11import { spawn } from "node:child_process" ;
2- import { existsSync } from "node:fs" ;
2+ import { existsSync , readFileSync } from "node:fs" ;
33import { chmod , cp , mkdir , rename , rm , writeFile } from "node:fs/promises" ;
44import { createRequire } from "node:module" ;
55import { dirname , join , resolve } from "node:path" ;
@@ -23,6 +23,12 @@ export type DistributionPackageArtifact = {
2323 resourcesDir : string ;
2424} ;
2525
26+ type BundledDependency = {
27+ name : string ;
28+ version : string ;
29+ packageDir : string ;
30+ } ;
31+
2632type CommandInput = {
2733 command : string ;
2834 args : ReadonlyArray < string > ;
@@ -90,6 +96,56 @@ const resolveQuickJsWasmPath = (): string => {
9096 return wasmPath ;
9197} ;
9298
99+ const resolveInstalledPackage = ( input : {
100+ packageName : string ;
101+ fromPackageJsonPath : string ;
102+ } ) : BundledDependency => {
103+ const requireFromPackage = createRequire ( input . fromPackageJsonPath ) ;
104+ const packageEntrypointPath = requireFromPackage . resolve ( input . packageName ) ;
105+ let packageDir = dirname ( packageEntrypointPath ) ;
106+ let packageJsonPath = join ( packageDir , "package.json" ) ;
107+
108+ while ( ! existsSync ( packageJsonPath ) ) {
109+ const parentDir = dirname ( packageDir ) ;
110+ if ( parentDir === packageDir ) {
111+ throw new Error ( `Unable to locate package.json for ${ input . packageName } from ${ packageEntrypointPath } ` ) ;
112+ }
113+ packageDir = parentDir ;
114+ packageJsonPath = join ( packageDir , "package.json" ) ;
115+ }
116+
117+ const packageJson = JSON . parse ( readFileSync ( packageJsonPath , "utf8" ) ) as {
118+ name ?: string ;
119+ version ?: string ;
120+ } ;
121+
122+ if ( ! packageJson . name || ! packageJson . version ) {
123+ throw new Error ( `Invalid package metadata at ${ packageJsonPath } ` ) ;
124+ }
125+
126+ return {
127+ name : packageJson . name ,
128+ version : packageJson . version ,
129+ packageDir,
130+ } ;
131+ } ;
132+
133+ const resolveBundledDependencies = ( ) : ReadonlyArray < BundledDependency > => {
134+ const onePasswordSdk = resolveInstalledPackage ( {
135+ packageName : "@1password/sdk" ,
136+ fromPackageJsonPath : join ( repoRoot , "plugins/onepassword/sdk/package.json" ) ,
137+ } ) ;
138+ const onePasswordSdkCore = resolveInstalledPackage ( {
139+ packageName : "@1password/sdk-core" ,
140+ fromPackageJsonPath : join ( onePasswordSdk . packageDir , "package.json" ) ,
141+ } ) ;
142+
143+ return [
144+ onePasswordSdk ,
145+ onePasswordSdkCore ,
146+ ] ;
147+ } ;
148+
93149
94150const createPackageJson = ( input : {
95151 packageName : string ;
@@ -105,6 +161,8 @@ const createPackageJson = (input: {
105161 url ?: string ;
106162 } ;
107163 license ?: string ;
164+ dependencies ?: Readonly < Record < string , string > > ;
165+ bundleDependencies ?: ReadonlyArray < string > ;
108166} ) => {
109167 const packageJson = {
110168 name : input . packageName ,
@@ -122,13 +180,16 @@ const createPackageJson = (input: {
122180 } ,
123181 files : [
124182 "bin" ,
183+ "node_modules" ,
125184 "resources" ,
126185 "README.md" ,
127186 "package.json" ,
128187 ] ,
129188 engines : {
130189 node : ">=20" ,
131190 } ,
191+ dependencies : input . dependencies ,
192+ bundleDependencies : input . bundleDependencies ,
132193 } ;
133194
134195 return JSON . stringify ( packageJson , null , 2 ) + "\n" ;
@@ -195,6 +256,7 @@ const buildCliBundle = async (input: {
195256 "node" ,
196257 "--outdir" ,
197258 input . binDir ,
259+ "--external=@1password/sdk" ,
198260 ] ,
199261 cwd : repoRoot ,
200262 } ) ;
@@ -217,14 +279,17 @@ export const buildDistributionPackage = async (
217279 const webDir = join ( resourcesDir , "web" ) ;
218280 const bundlePath = join ( binDir , "executor.mjs" ) ;
219281 const launcherPath = join ( binDir , "executor.js" ) ;
282+ const nodeModulesDir = join ( packageDir , "node_modules" ) ;
220283 const quickJsWasmPath = resolveQuickJsWasmPath ( ) ;
284+ const bundledDependencies = resolveBundledDependencies ( ) ;
221285
222286 const webDistDir = join ( repoRoot , "apps/web/dist" ) ;
223287 const readmePath = join ( repoRoot , "README.md" ) ;
224288 const packageName = options . packageName ?? defaults . name ;
225289 const packageVersion = options . packageVersion ?? defaults . version ;
226290 await rm ( packageDir , { recursive : true , force : true } ) ;
227291 await mkdir ( binDir , { recursive : true } ) ;
292+ await mkdir ( nodeModulesDir , { recursive : true } ) ;
228293 await mkdir ( resourcesDir , { recursive : true } ) ;
229294
230295 if ( ( options . buildWeb ?? true ) || ! existsSync ( webDistDir ) ) {
@@ -245,6 +310,11 @@ export const buildDistributionPackage = async (
245310 } ) ;
246311
247312 await cp ( webDistDir , webDir , { recursive : true } ) ;
313+ for ( const dependency of bundledDependencies ) {
314+ const destinationDir = join ( nodeModulesDir , ...dependency . name . split ( "/" ) ) ;
315+ await mkdir ( dirname ( destinationDir ) , { recursive : true } ) ;
316+ await cp ( dependency . packageDir , destinationDir , { recursive : true } ) ;
317+ }
248318 await cp ( quickJsWasmPath , join ( binDir , "emscripten-module.wasm" ) ) ;
249319 await cp (
250320 join ( repoRoot , "packages/kernel/runtime-deno-subprocess/src/deno-subprocess-worker.mjs" ) ,
@@ -271,6 +341,10 @@ export const buildDistributionPackage = async (
271341 bugs : defaults . bugs ,
272342 repository : defaults . repository ,
273343 license : defaults . license ,
344+ dependencies : Object . fromEntries (
345+ bundledDependencies . map ( ( dependency ) => [ dependency . name , dependency . version ] ) ,
346+ ) ,
347+ bundleDependencies : bundledDependencies . map ( ( dependency ) => dependency . name ) ,
274348 } ) ) ;
275349 await cp ( readmePath , join ( packageDir , "README.md" ) ) ;
276350 await writeFile ( launcherPath , createLauncherSource ( ) ) ;
0 commit comments