@gjsify/cli 0.4.3 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.gjs.mjs +3 -3
- package/lib/commands/install.js +53 -0
- package/lib/commands/run.js +20 -3
- package/lib/utils/install-backend-native.js +16 -5
- package/lib/utils/install-backend.d.ts +12 -0
- package/package.json +15 -15
package/dist/cli.gjs.mjs
CHANGED
|
@@ -739,7 +739,7 @@ var S=Object.getOwnPropertySymbols,C=Object.prototype.hasOwnProperty,N=Object.pr
|
|
|
739
739
|
`+n,map:null}}}}}function expandEnvTemplate(n,a=process.env){return n.replace(/\$\{env:([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g,(n,S,C)=>{let N=a[S];return N!==void 0&&N!==``?N:C??``})}function resolveShebangLine(n){if(n===void 0||n===!1)return null;if(n===!0)return`#!/usr/bin/env -S gjs -m`;let a=expandEnvTemplate(n);return a.trim()?a.startsWith(`#!`)?a:`#!`+a:null}tn(),Wo();const CT=Io(fileURLToPath(import.meta.url));function resolveConsoleShim(){let n=Ao(CT,`../shims/console-gjs.js`),a=null;try{a=(Fs(),__toCommonJS(Ms))}catch{return n}if(a.existsSync(n))return n;try{return(wc(),__toCommonJS(bc)).createRequire(import.meta.url).resolve(`@gjsify/rolldown-plugin-gjsify/shims/console-gjs`)}catch{return n}}const setupForGjs=async n=>{let a=[`cairo`,`gettext`,`system`,...n.userExternal??[]],external=n=>!!(n.startsWith(`gi://`)||a.includes(n)),S=n.pluginOptions.format??`esm`,C=n.pluginOptions.exclude??[],N=await globToEntryPoints(n.input,C),F=Ao(CT,`../shims/unicorn-magic.js`),I={...getAliasesForGjs({external}),"unicorn-magic":F,...n.pluginOptions.aliases??{},...n.userAliases??{}},H=n.pluginOptions.consoleShim===!1?null:resolveConsoleShim(),W=[];n.pluginOptions.autoGlobalsInject&&W.push(n.pluginOptions.autoGlobalsInject);let K=wrapInputWithSideEffects(N,W),q={input:K.input,platform:`neutral`,external,resolve:{mainFields:S===`esm`?[`browser`,`module`,`main`]:[`browser`,`main`,`module`],conditionNames:S===`esm`?[`browser`,`import`]:[`browser`,`require`,`import`]},transform:{target:`firefox140`,define:{global:`globalThis`,window:`globalThis`,"process.env.READABLE_STREAM":`"disable"`},...H?{inject:{console:[H,`console`]}}:{}},output:{...n.output,format:S,sourcemap:!1,codeSplitting:!1},treeshake:!0},Y=getBundleDirFromOutput(n.output);return{options:q,plugins:[...K.plugin?[K.plugin]:[],inputShebangStripPlugin(),aliasPlugin({entries:{"random-access-file":`random-access-file/index.js`,...flattenAliases$3(I)}}),blueprintPlugin(),deepkitPlugin({reflection:n.pluginOptions.reflection}),cssAsStringPlugin({targets:{firefox:60<<16}}),nodeModulesPathRewritePlugin({bundleDir:Y}),processStubPlugin({userBanner:n.userBanner}),(()=>{let a=resolveShebangLine(n.shebang);return shebangPlugin({enabled:a!==null,line:a??void 0})})()]}};function wrapInputWithSideEffects(n,a){if(a.length===0||n===void 0)return{input:n,plugin:null};let S=new Map,C=`\0gjsify-entry:`;function wrap(n){let a=C+n;return S.set(a,n),a}let N;if(typeof n==`string`)N=wrap(n);else if(Array.isArray(n))N=n.map(wrap);else{let a={};for(let[S,C]of Object.entries(n))a[S]=wrap(C);N=a}let F=a.map(n=>`import ${JSON.stringify(n)};`).join(`
|
|
740
740
|
`);return{input:N,plugin:{name:`gjsify-virtual-entry`,async resolveId(n,a){return n.startsWith(C)?n:null},async load(n){if(!n.startsWith(C))return null;let a=S.get(n);if(!a)return null;let N=(await this.resolve(a,void 0,{skipSelf:!0}))?.id??a;return{code:`${F}\nexport * from ${JSON.stringify(N)};\n`,moduleSideEffects:!0}}}}}function flattenAliases$3(n){let a={};for(let[S,C]of Object.entries(n))C&&(a[S]=C);return a}__name$1(flattenAliases$3,`flattenAliases`);const setupForNode=async n=>{let a=n.userExternal??[],S=[...jh,`node-datachannel`,...a],external=n=>!!(n.startsWith(`gi://`)||n.startsWith(`@girs/`)||S.includes(n)),C=n.pluginOptions.format??`esm`,N=n.pluginOptions.exclude??[],F=await globToEntryPoints(n.input,N),I={...getAliasesForNode({external}),...n.pluginOptions.aliases??{},...n.userAliases??{}},H=getBundleDirFromOutput(n.output);return{options:{input:F,platform:`node`,external,resolve:{mainFields:C===`esm`?[`module`,`main`,`browser`]:[`main`,`module`,`browser`],conditionNames:C===`esm`?[`require`,`node`,`module`]:[`require`]},transform:{target:`node24`,define:{global:`globalThis`,window:`globalThis`}},output:{...n.output,format:C,sourcemap:!1,banner:void 0,codeSplitting:!1},treeshake:!0},plugins:[aliasPlugin({entries:flattenAliases$2(I)}),deepkitPlugin({reflection:n.pluginOptions.reflection}),cssAsStringPlugin(),nodeModulesPathRewritePlugin({bundleDir:H})]}};function flattenAliases$2(n){let a={};for(let[S,C]of Object.entries(n))C&&(a[S]=C);return a}__name$1(flattenAliases$2,`flattenAliases`);const wT=`\0gjsify-empty-gjs-import`;function gjsImportsEmptyPlugin(){return{name:`gjsify-gjs-imports-empty`,resolveId:{order:`pre`,filter:{id:/^(@girs\/|gi:\/\/)/},handler(n){return{id:wT}}},load(n){return n===wT?{code:`export {}; export default {};`,moduleSideEffects:!1}:null}}}const setupForBrowser=async n=>{let a=[...n.userExternal??[]],S=n.pluginOptions.exclude??[],C=await globToEntryPoints(n.input,S),N={process:`@gjsify/empty`,"node:process":`@gjsify/empty`,assert:`@gjsify/assert`,"node:assert":`@gjsify/assert`,...n.pluginOptions.aliases??{},...n.userAliases??{}};return{options:{input:C,platform:`browser`,external:a,resolve:{mainFields:[`browser`,`module`,`main`],conditionNames:[`import`,`browser`]},transform:{target:`esnext`,define:{global:`globalThis`,window:`globalThis`}},output:{...n.output,format:`esm`,sourcemap:!1,codeSplitting:!1},treeshake:!0},plugins:[gjsImportsEmptyPlugin(),aliasPlugin({entries:flattenAliases$1(N)}),blueprintPlugin(),deepkitPlugin({reflection:n.pluginOptions.reflection}),cssAsStringPlugin()]}};function flattenAliases$1(n){let a={};for(let[S,C]of Object.entries(n))C&&(a[S]=C);return a}__name$1(flattenAliases$1,`flattenAliases`);const setupLib=async n=>{let a=n.pluginOptions.format??n.pluginOptions.library??`esm`,S=n.pluginOptions.exclude??[],C=await globToEntryPoints(n.input,S),N=computeCommonRoot(C),F={...n.pluginOptions.aliases??{},...n.userAliases??{}},external=n=>!(n.startsWith(`./`)||n.startsWith(`../`)||n.startsWith(`/`));return{options:{input:C,platform:`neutral`,external,resolve:{mainFields:a===`esm`?[`module`,`main`]:[`main`],conditionNames:a===`esm`?[`module`,`import`]:[`require`]},transform:{target:`esnext`},output:{...n.output,format:a,preserveModules:!0,preserveModulesRoot:N,sourcemap:!1},treeshake:!1},plugins:[aliasPlugin({entries:flattenAliases(F)}),cssAsStringPlugin()]}};function computeCommonRoot(n){let a=n===void 0?[]:typeof n==`string`?[n]:Array.isArray(n)?n:Object.values(n);if(a.length===0)return`src`;let S=a.map(n=>n.split(`/`).filter(Boolean)),C=S[0],N=0;for(;N<C.length;N++){let n=C[N];if(!S.every(a=>a[N]===n))break}if(N===0)return`src`;let F=C.slice(0,N);return S.some(n=>n.length>N)?F.join(`/`):F.slice(0,-1).join(`/`)||`src`}function flattenAliases(n){let a={};for(let[S,C]of Object.entries(n))C&&(a[S]=C);return a}ps();function textLoaderPlugin(n={}){let a=Object.entries(n.loaders??{}).filter(([,n])=>n===`text`).map(([n])=>n);if(a.length===0)return null;let S=a.map(n=>n.replace(/^\./,``).replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)),C=RegExp(`\\.(?:${S.join(`|`)})$`);return{name:`gjsify-text-loader`,async load(n){if(!C.test(n))return null;let a=await readFile$1(n,`utf8`);return{code:`export default ${JSON.stringify(a)};`,moduleType:`js`}}}}const gjsifyPlugin=async(n,a={})=>{if(a.library)switch(a.library){case`esm`:case`cjs`:return await setupLib({input:n.input,output:n.output,userAliases:n.userAliases,pluginOptions:a});default:throw TypeError(`Unknown library type: `+a.library)}let S=a.app??`gjs`;switch(S){case`gjs`:return await setupForGjs({input:n.input,output:n.output,userExternal:n.userExternal,userBanner:n.userBanner,userAliases:n.userAliases,shebang:n.shebang,pluginOptions:a});case`node`:return await setupForNode({input:n.input,output:n.output,userExternal:n.userExternal,userAliases:n.userAliases,pluginOptions:a});case`browser`:return await setupForBrowser({input:n.input,output:n.output,userExternal:n.userExternal,userAliases:n.userAliases,pluginOptions:a});default:throw TypeError(`Unknown app platform: `+S)}};wc(),Wo(),tn();function isPluginByName(n){return typeof n==`object`&&!!n&&typeof n.name==`string`&&!(`apply`in n)&&!(`resolveId`in n)&&!(`load`in n)&&!(`transform`in n)&&!(`renderChunk`in n)&&!(`generateBundle`in n)}async function resolveUserPlugins(n,a){let S=createRequire(No(a,`package.json`)),C=[];for(let N of n){if(!isPluginByName(N)){C.push(N);continue}let n;try{n=S.resolve(N.name)}catch(n){throw Error(`gjsify config: failed to resolve plugin "${N.name}" from ${a}. Add it to your project's dependencies, or pass a Plugin object directly. (${n.message})`)}let F=await import(pathToFileURL(n).href),I=N.export??`default`,H=F[I];if(typeof H!=`function`){let n=Object.keys(F).filter(n=>typeof F[n]==`function`);throw Error(`gjsify config: plugin "${N.name}" has no function export "${I}". Available function exports: ${n.length?n.join(`, `):`(none)`}.`)}let W=await H(N.options);if(W==null)throw Error(`gjsify config: plugin "${N.name}" factory returned ${W}. Check the plugin's signature — it should return a Rolldown/Vite plugin object.`);C.push(W)}return C}Be();const defaultBundler=async({rolldownInput:n,format:a})=>{let S=await(await import(`rolldown`)).rolldown(n);try{let n=await S.generate({format:a,minify:!1,sourcemap:!1}),C=[];for(let a of n.output)a.type===`chunk`&&C.push(a.code);return C}finally{await S.close()}},TT=ey;function setsEqual(n,a){if(n.size!==a.size)return!1;for(let S of n)if(!a.has(S))return!1;return!0}async function applyExcludeGlobals(n,a,S,C){if(!C?.length)return{detected:n,injectPath:a};for(let a of C)n.delete(a);let N=detectedToRegisterPaths(n);for(let n of S)N.add(n);return{detected:n,injectPath:N.size>0?await writeRegisterInjectFile(N)??void 0:void 0}}function detectedToRegisterPaths(n){let a=new Set;for(let S of n){let n=TT[S];n&&a.add(n)}return a}async function detectAutoGlobals(n,a,S,C,N={},F=defaultBundler){let I=N.extraGlobalsList?resolveGlobalsList(N.extraGlobalsList):new Set,H=new Set(N.excludeGlobals??[]),W=new Set,K;I.size>0&&(K=await writeRegisterInjectFile(I)??void 0);let q=(n.plugins??[]).filter(n=>{let a=n&&typeof n==`object`&&`name`in n?n.name:void 0;return a!==`gjsify`&&a!==`gjsify-orchestrator`});for(let Y=1;Y<=5;Y++){let X=await S({...a,autoGlobalsInject:K}),te=await F({rolldownInput:{input:K?appendInjectAsEntry(n.input,K):n.input,external:n.external,resolve:n.resolve,transform:n.transform,plugins:[...q,X],logLevel:`silent`},format:n.format??`esm`});if(te.length===0)return{detected:new Set,injectPath:K};let ne=new Set;for(let n=0;n<te.length;n++){let a=te[n]??``;try{for(let n of detectFreeGlobals(a))ne.add(n)}catch(S){if(globalThis.process?.env?.GJSIFY_DEBUG_AUTO_GLOBALS){let S=`/tmp/gjsify-auto-globals-failed-chunk-${n}.mjs`;try{(await Promise.resolve().then(()=>(Fs(),Ms))).writeFileSync(S,a),ze.error(`[gjsify-auto-globals] parse failed on chunk #${n} — wrote ${S} for inspection`)}catch{}}throw S}}if(H.size>0)for(let n of H)ne.delete(n);if(setsEqual(W,ne)){if(C){let n=[...W].sort(),a=I.size>0?` (+ ${I.size} extra register module(s))`:``;ze.debug(`[gjsify] --globals auto: converged after ${Y-1} iteration(s), ${W.size} global(s)${n.length?`: `+n.join(`, `):``}${a}`)}return applyExcludeGlobals(W,K,I,N.excludeGlobals)}W=ne;let re=detectedToRegisterPaths(W);for(let n of I)re.add(n);if(re.size===0)return{detected:W,injectPath:void 0};if(K=await writeRegisterInjectFile(re)??void 0,C){let n=[...W].sort();ze.debug(`[gjsify] --globals auto: iteration ${Y}, ${W.size} global(s)${n.length?`: `+n.join(`, `):``}`)}}return C&&ze.debug(`[gjsify] --globals auto: hit max iterations (5), using last detected set`),applyExcludeGlobals(W,K,I,N.excludeGlobals)}function appendInjectAsEntry(n,a){return n===void 0?[a]:typeof n==`string`?[n,a]:Array.isArray(n)?[...n,a]:{...n,__gjsify_inject:a}}wc(),tn(),Wo(),Fs(),ps();function findPnpRoot(n){let a=n;for(;;){if(existsSync(No(a,`.pnp.cjs`)))return a;let n=Io(a);if(n===a)return null;a=n}}async function loadPnpApi(){try{let n=await import(`pnpapi`);return n.default??n}catch{return null}}async function pnpPlugin(n={}){let a=n.issuerUrl??import.meta.url;if(!findPnpRoot(process.cwd()))return null;let S=await loadPnpApi();if(S===null)return null;let C=fileURLToPath(a),N=createRequire(C),F=n.relayPackages??[`@gjsify/node-polyfills`,`@gjsify/web-polyfills`],I=[];for(let n of F)try{I.push(N.resolve(`${n}/package.json`))}catch{}return{name:`gjsify-pnp`,resolveId:{order:`pre`,async handler(n,a){if(n.startsWith(`.`)||n.startsWith(`/`))return null;if(n.startsWith(`gi://`))return{id:n,external:!0};if(!a)return null;let N=a.startsWith(`file://`)?fileURLToPath(a):a;try{let a=S.resolveRequest(n,N);return a===null?null:{id:a}}catch(a){if(!isUndeclaredDependency(a))throw a;try{let a=S.resolveRequest(n,C);if(a!==null)return{id:a}}catch(n){if(!isUndeclaredDependency(n))throw n}for(let a of I)try{let C=S.resolveRequest(n,a);if(C!==null)return{id:C}}catch(n){if(!isUndeclaredDependency(n))throw n}return null}}},async load(n){if(!n.includes(`/.yarn/`)&&!n.includes(`.zip/`))return null;try{return{code:await readFile$1(n,`utf8`)}}catch(a){let S=a instanceof Error?a.message:String(a);this.error(`gjsify-pnp: failed to read ${n}: ${S}`)}}}}function isUndeclaredDependency(n){return typeof n==`object`&&!!n&&`pnpCode`in n&&n.pnpCode===`UNDECLARED_DEPENDENCY`}Be();let ET=!1;function normalizeBundlerOptions(n){let a=n.bundler??{};if(!n.esbuild)return a;ET||(ET=!0,ze.warn(`[gjsify] DEPRECATION: the 'esbuild' config key is deprecated and will be removed in 0.5.0. Rename it to 'bundler' (typed as RolldownOptions). See the migration notes in the gjsify CHANGELOG.`));let S=legacyEsbuildToRolldown(n.esbuild),C={...S,...a};return(S.output||a.output)&&(C.output={...S.output??{},...a.output??{}}),(S.transform||a.transform)&&(C.transform={...S.transform??{},...a.transform??{}},(S.transform?.define||a.transform?.define)&&(C.transform.define={...S.transform?.define??{},...a.transform?.define??{}})),(S.resolve||a.resolve)&&(C.resolve={...S.resolve??{},...a.resolve??{}}),C}function legacyEsbuildToRolldown(n){let a={},S={},C={},N={};return n.outfile!==void 0&&(S.file=n.outfile),n.outdir!==void 0&&(S.dir=n.outdir),n.format!==void 0&&(S.format=n.format),n.minify!==void 0&&(S.minify=n.minify),n.sourcemap!==void 0&&(S.sourcemap=n.sourcemap===`inline`?`inline`:!!n.sourcemap),n.banner?.js!==void 0&&(S.banner=n.banner.js),n.target!==void 0&&(C.target=Array.isArray(n.target)?n.target.join(`,`):n.target),n.define!==void 0&&(C.define=n.define),n.mainFields!==void 0&&(N.mainFields=n.mainFields),n.conditions!==void 0&&(N.conditionNames=n.conditions),n.external!==void 0&&(a.external=n.external),n.platform!==void 0&&(a.platform=n.platform),Object.keys(S).length>0&&(a.output=S),Object.keys(C).length>0&&(a.transform=C),Object.keys(N).length>0&&(a.resolve=N),a}function mergeBundlerOptions(n,a){let{input:S,external:C,...N}=a,F={...n,...N};return(n.output||a.output)&&(F.output={...n.output??{},...a.output??{}}),(n.transform||a.transform)&&(F.transform={...n.transform??{},...a.transform??{}},(n.transform?.define||a.transform?.define)&&(F.transform.define={...n.transform?.define??{},...a.transform?.define??{}})),(n.resolve||a.resolve)&&(F.resolve={...n.resolve??{},...a.resolve??{}}),F}Be(),Wo(),ps();function isUnsafeDefaultOutput(n){if(/\.[cm]?tsx?$/i.test(n))return!0;let a=n.replace(/\\/g,`/`);return!!/(?:^|\/)src\//.test(a)}async function buildPnpPlugin(){return pnpPlugin({issuerUrl:import.meta.url})}var BuildAction=class{configData;constructor(n={}){this.configData=n}async buildLibrary(){let{verbose:n,library:a,typescript:S,exclude:C,aliases:N}=this.configData,F=a??{},I=normalizeBundlerOptions(this.configData),H=F.module?Io(F.module):void 0,W=F.main?Io(F.main):void 0,K=F.module?Ro(F.module):`.js`,q=F.main?Ro(F.main):`.js`,Y=H&&W&&H!==W,X=await buildPnpPlugin(),te=X?[X]:[],ne=[];if(Y){let a=H.includes(`/cjs`)||K===`.cjs`?`cjs`:`esm`;ne.push(await runOneLibraryBuild({pluginOpts:{debug:n,library:a,exclude:C,reflection:S?.reflection,jsExtension:K},userBundler:I,output:{dir:H},userAliases:N,pnpPlugins:te}));let F=W.includes(`/cjs`)||q===`.cjs`?`cjs`:`esm`;ne.push(await runOneLibraryBuild({pluginOpts:{debug:n,library:F,exclude:C,reflection:S?.reflection,jsExtension:q},userBundler:I,output:{dir:W},userAliases:N,pnpPlugins:te}))}else{let a=I.output?.file??F.module??F.main,H=a?Ro(a):`.js`,W=I.output?.dir??(a?Io(a):void 0),K=I.output?.format??(W?.includes(`/cjs`)||H===`.cjs`?`cjs`:`esm`);ne.push(await runOneLibraryBuild({pluginOpts:{debug:n,library:K,exclude:C,reflection:S?.reflection,jsExtension:H},userBundler:I,output:{dir:W},userAliases:N,pnpPlugins:te}))}return ne}parseGlobalsValue(n){if(n===void 0)return{autoMode:!0,extras:``};if(n===`none`||n===``)return{autoMode:!1,extras:``};let a=n.split(`,`).map(n=>n.trim()).filter(Boolean);return{autoMode:a.includes(`auto`),extras:a.filter(n=>n!==`auto`).join(`,`)}}async resolveGlobalsInject(n,a,S){if(n!==`gjs`||!a)return;let C=resolveGlobalsList(a);if(C.size===0)return;let N=await writeRegisterInjectFile(C,process.cwd());return S&&N&&ze.debug(`[gjsify] globals: injected ${C.size} register module(s) from --globals ${a}`),N??void 0}async applyShebang(n,a){if(!n){a&&ze.warn(`[gjsify] --shebang skipped: no single outfile (use --outfile for GJS executables)`);return}let S=resolveShebangLine(this.configData.shebang)??`#!/usr/bin/env -S gjs -m`,C=await readFile$1(n,`utf-8`);C.startsWith(`#!`)?a&&ze.debug(`[gjsify] --shebang skipped: ${n} already starts with a shebang`):await writeFile$1(n,S+`
|
|
741
741
|
`+C),await chmod$1(n,493),a&&ze.debug(`[gjsify] --shebang: wrote ${S} + chmod 0o755 to ${n}`)}async buildApp(n=`gjs`){let{verbose:a,typescript:S,exclude:C,library:N,aliases:F,excludeGlobals:I}=this.configData,H=normalizeBundlerOptions(this.configData),W=H.output?.format??(H.output?.file?.endsWith(`.cjs`)?`cjs`:`esm`),K=W===`iife`?`esm`:W,q=H.output?.file,Y=H.output?.dir;if(!q&&!Y&&(N?.main||N?.module)){let n=K===`cjs`?N.main??N.module:N.module??N.main;if(n&&isUnsafeDefaultOutput(n))throw Error(`gjsify build: refusing to default --outfile to ${n} (would overwrite a TypeScript source file). Pass --outfile/--outdir explicitly, or set "gjsify.bundler.output.file" in package.json.`);q=n}let{consoleShim:X,globals:te}=this.configData,ne=Array.isArray(H.external)?H.external:void 0,re=typeof H.output?.banner==`string`?H.output.banner:void 0,ie={debug:a,app:n,format:K,exclude:C,reflection:S?.reflection,consoleShim:X,...F?{aliases:F}:{}},{autoMode:ae,extras:oe}=this.parseGlobalsValue(te),Z=await buildPnpPlugin(),se=Z?[Z]:[],ce=textLoaderPlugin({loaders:this.configData.loaders}),le=ce?[ce]:[];if(H.plugins?.length){let n=await resolveUserPlugins(H.plugins,process.cwd());le.push(...n)}if(n===`gjs`&&ae){let gjsifyPluginFactory=async n=>(await gjsifyPlugin({input:H.input,output:{file:q,dir:Y},userExternal:ne,userBanner:re,userAliases:F,shebang:this.configData.shebang},n)).plugins,{injectPath:n}=await detectAutoGlobals({input:H.input,plugins:[...se,...le],external:H.external,transform:H.transform,format:K},ie,gjsifyPluginFactory,a,{extraGlobalsList:oe,excludeGlobals:I},bundleToChunks);ie.autoGlobalsInject=n}else oe&&(ie.autoGlobalsInject=await this.resolveGlobalsInject(n,oe,a));let ue=await gjsifyPlugin({input:H.input,output:{file:q,dir:Y},userExternal:ne,userBanner:re,userAliases:F,shebang:this.configData.shebang},ie),de=await runBundle({...mergeBundlerOptions(ue.options,H),plugins:[...se,...le,...ue.plugins]});return n===`gjs`&&this.configData.shebang&&await this.applyShebang(q,a),[de]}async start(n={app:`gjs`}){return n.library?await this.buildLibrary():await this.buildApp(n.app)}};async function runOneLibraryBuild(n){let a=await gjsifyPlugin({input:n.userBundler.input,output:n.output,userAliases:n.userAliases},n.pluginOpts);return await runBundle({...mergeBundlerOptions(a.options,n.userBundler),plugins:[...n.pnpPlugins,...a.plugins]})}const DT={command:`build [entryPoints..]`,description:`Build and bundle your Gjs project`,builder:n=>n.option(`entry-points`,{description:`The entry points you want to bundle. Defaults to bundler.input from package.json#gjsify or .gjsifyrc.js, falling back to src/index.ts when neither is set.`,array:!0,type:`string`,normalize:!0,defaultDescription:`src/index.ts (fallback)`,coerce:n=>[...new Set(n)]}).option(`exclude`,{description:`An array of glob patterns to exclude entry-points and aliases`,array:!0,type:`string`,normalize:!0,default:[]}).option(`verbose`,{description:`Switch on the verbose mode`,type:`boolean`,normalize:!0,default:!1}).option(`app`,{description:`Use this if you want to build an application, the platform node is usually only used for tests`,type:`string`,choices:[`gjs`,`node`,`browser`],normalize:!0,default:`gjs`}).option(`format`,{description:`Override the default output format`,type:`string`,choices:[`iife`,`esm`,`cjs`],normalize:!0}).option(`minify`,{description:`Minify the bundled output. Defaults to true; use --no-minify to emit pretty-printed code (e.g. for debugging or readable bundle review).`,type:`boolean`,normalize:!0,defaultDescription:`true`}).option(`library`,{description:`Use this if you want to build a library for Gjsify`,type:`boolean`,normalize:!0,default:!1}).option(`outfile`,{alias:`o`,description:`Sets the output file name for the build operation. If no outfile is specified, the outfile will be parsed from the package.json. Only used if application mode is active`,type:`string`,normalize:!0}).option(`outdir`,{alias:`d`,description:`Sets the output directory for the build operation. If no outdir is specified, the outdir will be parsed from the package.json. Only used if library mode is active`,type:`string`,normalize:!0}).option(`reflection`,{alias:`r`,description:`Enables TypeScript types on runtime using Deepkit's type compiler`,type:`boolean`,normalize:!0,default:!1}).option(`log-level`,{description:`The log level can be changed to prevent esbuild from printing warning and/or error messages to the terminal`,type:`string`,choices:[`silent`,`error`,`warning`,`info`,`debug`,`verbose`],normalize:!0,default:`warning`}).option(`console-shim`,{description:`Inject a console shim into GJS builds for clean output without the GLib prefix and with working ANSI colors. Use --no-console-shim to disable. Only applies to GJS app builds.`,type:`boolean`,normalize:!0,default:!0}).option(`globals`,{description:"Comma-separated list of global identifiers, 'auto' (default) to detect automatically from the bundled output, or 'none' to disable. The 'auto' token may be combined with explicit identifiers/groups (e.g. 'auto,dom') for cases where the detector cannot statically see a global because it's accessed via indirection. Each identifier is mapped to the corresponding `@gjsify/<pkg>/register` module and injected into the bundle. See the CLI Reference docs for the full list of known identifiers. Only applies to GJS app builds.",type:`string`,normalize:!0,default:`auto`}).option(`shebang`,{description:"Prepend a `#!/usr/bin/env -S gjs -m` shebang to the output and mark it executable (chmod 755). Only applies to GJS app builds with a single --outfile. Default: false (use --shebang to enable, or set `shebang: true` in `.gjsifyrc.js`).",type:`boolean`,normalize:!0}).option(`external`,{description:`Module names that should NOT be bundled. Repeat the flag or pass a comma-separated list (e.g. --external typedoc,prettier). Globs are forwarded to esbuild as-is. See https://esbuild.github.io/api/#external`,array:!0,type:`string`,default:[],coerce:n=>n.flatMap(n=>n.split(`,`).map(n=>n.trim()).filter(Boolean))}).option(`define`,{description:`Substitute compile-time constants. Each entry is KEY=VALUE where VALUE is a JS expression (string literals must be quoted: --define VERSION='"1.2.3"'). Repeat the flag or pass comma-separated. See https://esbuild.github.io/api/#define`,array:!0,type:`string`,default:[]}).option(`alias`,{description:`Map module specifiers at bundle time. Each entry is FROM=TO (e.g. --alias typedoc=@gjsify/empty). Layered on top of the built-in alias map. Useful for stubbing heavy deps the test scenario never executes.`,array:!0,type:`string`,default:[],coerce:n=>n.flatMap(n=>n.split(`,`).map(n=>n.trim()).filter(Boolean))}).option(`exclude-globals`,{description:`Comma-separated global identifiers to remove from auto-detection results. Use for false positives from dead browser-compat code whose polyfills require unavailable native libraries (e.g. --exclude-globals fetch,XMLHttpRequest).`,type:`string`,normalize:!0}),handler:async n=>{await new BuildAction(await new Config().forBuild(n)).start({library:n.library,app:n.app})}};Fs(),Wo();function nodeArchToLinuxArch(n){return{x64:`x86_64`,arm64:`aarch64`,arm:`armv7`,ia32:`i686`}[n]??n}function readPackageJson$3(n){try{return JSON.parse(readFileSync(n,`utf-8`))}catch{return null}}__name$1(readPackageJson$3,`readPackageJson`);function scanNodeModules(n,a){let S=[];if(!existsSync(n))return S;let C;try{C=readdirSync(n)}catch{return S}for(let N of C)if(!N.startsWith(`.`))if(N.startsWith(`@`)){let C=No(n,N),F;try{F=readdirSync(C)}catch{continue}for(let n of F){let F=checkPackage(No(C,n),`${N}/${n}`,a);F&&S.push(F)}}else{let C=checkPackage(No(n,N),N,a);C&&S.push(C)}return S}function checkPackage(n,a,S){let C=readPackageJson$3(No(n,`package.json`));if(!C)return null;let N=C.gjsify;if(!N||typeof N!=`object`)return null;let F=N.prebuilds;if(typeof F!=`string`)return null;let I=No(n,F,`linux-${S}`);return existsSync(I)?{name:a,prebuildsDir:I}:null}function detectNativePackages(n){let a=nodeArchToLinuxArch(process.arch),S=[],C=new Set,N=Ao(n);for(;;){let n=No(N,`node_modules`);if(existsSync(n))for(let N of scanNodeModules(n,a))C.has(N.name)||(C.add(N.name),S.push(N));let F=Ao(N,`..`);if(F===N)break;N=F}return S}function buildNativeEnv(n){let a=n.map(n=>n.prebuildsDir),S=process.env.LD_LIBRARY_PATH??``,C=process.env.GI_TYPELIB_PATH??``;return{LD_LIBRARY_PATH:[...a,...S?[S]:[]].join(`:`),GI_TYPELIB_PATH:[...a,...C?[C]:[]].join(`:`)}}Be(),px(),Wo();function computeNativeEnvForBundle(n,a=process.cwd()){let S=Ao(n),C=detectNativePackages(a),N=detectNativePackages(Io(S)),F=new Set(C.map(n=>n.name)),I=buildNativeEnv([...C,...N.filter(n=>!F.has(n.name))]);return{env:I,envPrefix:Object.entries(I).filter(([,n])=>n!==void 0&&n!==``).map(([n,a])=>`${n}=${a}`).join(` `)}}async function runGjsBundle(n,a=[]){let{env:S,envPrefix:C}=computeNativeEnvForBundle(n),N={...process.env,...S},F=[`-m`,n,...a],I=[`gjs`,...F.map(n=>n.includes(` `)?`"${n}"`:n)].join(` `);ze.log(`$ ${C?`${C} `:``}${I}`);let H=spawn(`gjs`,F,{env:N,stdio:`inherit`});await new Promise((n,a)=>{H.on(`close`,S=>{S===0?n():a(Error(`gjs exited with code ${S}`))}),H.on(`error`,a)}).catch(n=>{ze.error(n.message),process.exit(1)})}Fs();function readPackageJson$2(n){if(!existsSync(n))return null;let a=readFileSync(n,`utf-8`);try{return JSON.parse(a)}catch(a){throw Error(`gjsify install: ${n} is not valid JSON: ${a.message}`)}}__name$1(readPackageJson$2,`readPackageJson`);function writePackageJson(n,a){let S=sortKnownDepFields(a);writeFileSync(n,JSON.stringify(S,null,2)+`
|
|
742
|
-
`,`utf-8`)}function parseSpec$2(n){if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a===-1)return{name:n};let S=n.indexOf(`@`,a+1);return S===-1?{name:n}:{name:n.slice(0,S),range:n.slice(S+1)}}let a=n.indexOf(`@`);return a===-1?{name:n}:{name:n.slice(0,a),range:n.slice(a+1)}}__name$1(parseSpec$2,`parseSpec`);function projectSpecsFromPackageJson(n){let a=[];for(let S of[`dependencies`,`devDependencies`,`optionalDependencies`]){let C=n[S];if(C)for(let[n,S]of Object.entries(C))typeof S==`string`&&(/^(workspace|link|file|portal|git\+|https?):/.test(S)||a.push(`${n}@${S}`))}return a}function addDependencyEntry(n,a,S,C){n[C]===void 0&&(n[C]={}),n[C][a]=S}function defaultRangeFromVersion(n){return`^${n}`}function sortKnownDepFields(n){let a={...n};for(let n of[`dependencies`,`devDependencies`,`peerDependencies`,`optionalDependencies`]){let S=a[n];S&&(a[n]=Object.fromEntries(Object.entries(S).sort(([n],[a])=>n<a?-1:+(n>a))))}return a}Fs(),Wo();function discoverWorkspaces(n,a={}){let S=No(n,`package.json`);if(!existsSync(S))throw Error(`@gjsify/workspace: no package.json at ${n}`);let C=JSON.parse(readFileSync(S,`utf-8`)),N=a.patterns??extractWorkspacePatterns(C),F=[];a.includeRoot&&C.name&&F.push({location:n,relativeLocation:`.`,name:C.name,version:C.version??`0.0.0`,manifest:C,private:C.private===!0});for(let a of N)for(let S of expandPattern(n,a)){let a=No(S,`package.json`);if(!existsSync(a))continue;let C;try{C=JSON.parse(readFileSync(a,`utf-8`))}catch{continue}C.name&&F.push({location:S,relativeLocation:Po(n,S).split(Vo).join(`/`),name:C.name,version:C.version??`0.0.0`,manifest:C,private:C.private===!0})}return F.sort((n,a)=>n.relativeLocation.localeCompare(a.relativeLocation)),F}function buildDependencyGraph(n,a={}){let S=a.includeDev??!1,C=a.includePeer??!1,N=a.includeOptional??!0,F=indexByName(n),I=new Map;for(let a of n){let n=new Set,H=a.manifest;for(let a of[H.dependencies,S?H.devDependencies:void 0,C?H.peerDependencies:void 0,N?H.optionalDependencies:void 0])if(a)for(let[S,C]of Object.entries(a))typeof C==`string`&&C.startsWith(`workspace:`)&&F.has(S)&&n.add(S);I.set(a.name,n)}return{edges:I,byName:F}}function topologicalSort(n){let a=new Map;for(let S of n.edges.keys())a.set(S,0);for(let S of n.edges.values())for(let n of S)a.has(n)&&a.set(n,(a.get(n)??0)+1);let S=new Map,C=new Map;for(let a of n.edges.keys())S.set(a,new Set),C.set(a,0);for(let[a,N]of n.edges)for(let n of N)S.has(n)&&(S.get(n).add(a),C.set(a,(C.get(a)??0)+1));let N=[];for(let[n,a]of C)a===0&&N.push(n);N.sort();let F=[];for(;N.length>0;){let a=N.shift(),I=n.byName.get(a);I&&F.push(I);let H=S.get(a);if(H){let n=[];for(let a of H){let S=(C.get(a)??1)-1;C.set(a,S),S===0&&n.push(a)}n.sort(),N.push(...n)}}if(F.length!==C.size){let n=[...C.entries()].filter(([,n])=>n>0).map(([n])=>n);throw Error(`@gjsify/workspace: dependency cycle detected involving ${n.join(`, `)}`)}return F}function filterWorkspaces(n,a){let S=a.include?.map(globToRegex),C=a.exclude?.map(globToRegex);return n.filter(n=>!(a.noPrivate&&n.private||S&&S.length>0&&!S.some(a=>a.test(n.name))||C&&C.length>0&&C.some(a=>a.test(n.name))))}function extractWorkspacePatterns(n){let a=n.workspaces;return a?Array.isArray(a)?a:a.packages??[]:[]}function expandPattern(n,a){let S=a.split(`/`).filter(Boolean),C=[Ao(n)];for(let n of S){let a=[];for(let S of C)if(n===`*`){let n=[];try{n=readdirSync(S)}catch{continue}for(let C of n){if(C.startsWith(`.`))continue;let n=No(S,C);try{statSync(n).isDirectory()&&a.push(n)}catch{}}}else if(n.includes(`*`)){let C=globToRegex(n),N=[];try{N=readdirSync(S)}catch{continue}for(let n of N){if(n.startsWith(`.`)||!C.test(n))continue;let N=No(S,n);try{statSync(N).isDirectory()&&a.push(N)}catch{}}}else{let C=No(S,n);if(existsSync(C))try{statSync(C).isDirectory()&&a.push(C)}catch{}}C=a}return C}function globToRegex(n){let a=n.replace(/[.+?^${}()|[\]\\]/g,`\\$&`).replace(/\*/g,`[^/]*`);return RegExp(`^${a}$`)}function indexByName(n){let a=new Map;for(let S of n)a.set(S.name,S);return a}Fs(),Wo();function readPackageJson$1(n){try{return JSON.parse(readFileSync(n,`utf-8`))}catch{return null}}__name$1(readPackageJson$1,`readPackageJson`);function findWorkspaceRoot(n){let a=n;for(let S=0;S<12;S++){let S=No(a,`package.json`);if(existsSync(S)&&readPackageJson$1(S)?.workspaces!==void 0)try{let S=discoverWorkspaces(a);if(a===n||S.some(a=>a.location===n))return a}catch{}let C=Ao(a,`..`);if(C===a)break;a=C}return null}Be(),Fs(),Wo(),px();const OT={command:`run <target> [args..]`,description:"Run a script from package.json (yarn-run-style) or a GJS bundle file. If <target> resolves to a file on disk (or has a path-like prefix), it is launched via gjs with LD_LIBRARY_PATH + GI_TYPELIB_PATH set for native packages. Otherwise it is looked up in the current package.json `scripts`.",builder:n=>n.positional(`target`,{description:"Either a script name (looked up in package.json `scripts`) or a path to a GJS bundle (e.g. dist/gjs.js).",type:`string`,demandOption:!0}).positional(`args`,{description:`Extra arguments passed through to the script / gjs.`,type:`string`,array:!0,default:[]}),handler:async n=>{let a=n.target,S=n.args??[];if(looksLikeFile(a)){await runGjsBundle(Ao(a),S);return}await runScript(a,S)}};function looksLikeFile(n){
|
|
742
|
+
`,`utf-8`)}function parseSpec$2(n){if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a===-1)return{name:n};let S=n.indexOf(`@`,a+1);return S===-1?{name:n}:{name:n.slice(0,S),range:n.slice(S+1)}}let a=n.indexOf(`@`);return a===-1?{name:n}:{name:n.slice(0,a),range:n.slice(a+1)}}__name$1(parseSpec$2,`parseSpec`);function projectSpecsFromPackageJson(n){let a=[];for(let S of[`dependencies`,`devDependencies`,`optionalDependencies`]){let C=n[S];if(C)for(let[n,S]of Object.entries(C))typeof S==`string`&&(/^(workspace|link|file|portal|git\+|https?):/.test(S)||a.push(`${n}@${S}`))}return a}function addDependencyEntry(n,a,S,C){n[C]===void 0&&(n[C]={}),n[C][a]=S}function defaultRangeFromVersion(n){return`^${n}`}function sortKnownDepFields(n){let a={...n};for(let n of[`dependencies`,`devDependencies`,`peerDependencies`,`optionalDependencies`]){let S=a[n];S&&(a[n]=Object.fromEntries(Object.entries(S).sort(([n],[a])=>n<a?-1:+(n>a))))}return a}Fs(),Wo();function discoverWorkspaces(n,a={}){let S=No(n,`package.json`);if(!existsSync(S))throw Error(`@gjsify/workspace: no package.json at ${n}`);let C=JSON.parse(readFileSync(S,`utf-8`)),N=a.patterns??extractWorkspacePatterns(C),F=[];a.includeRoot&&C.name&&F.push({location:n,relativeLocation:`.`,name:C.name,version:C.version??`0.0.0`,manifest:C,private:C.private===!0});for(let a of N)for(let S of expandPattern(n,a)){let a=No(S,`package.json`);if(!existsSync(a))continue;let C;try{C=JSON.parse(readFileSync(a,`utf-8`))}catch{continue}C.name&&F.push({location:S,relativeLocation:Po(n,S).split(Vo).join(`/`),name:C.name,version:C.version??`0.0.0`,manifest:C,private:C.private===!0})}return F.sort((n,a)=>n.relativeLocation.localeCompare(a.relativeLocation)),F}function buildDependencyGraph(n,a={}){let S=a.includeDev??!1,C=a.includePeer??!1,N=a.includeOptional??!0,F=indexByName(n),I=new Map;for(let a of n){let n=new Set,H=a.manifest;for(let a of[H.dependencies,S?H.devDependencies:void 0,C?H.peerDependencies:void 0,N?H.optionalDependencies:void 0])if(a)for(let[S,C]of Object.entries(a))typeof C==`string`&&C.startsWith(`workspace:`)&&F.has(S)&&n.add(S);I.set(a.name,n)}return{edges:I,byName:F}}function topologicalSort(n){let a=new Map;for(let S of n.edges.keys())a.set(S,0);for(let S of n.edges.values())for(let n of S)a.has(n)&&a.set(n,(a.get(n)??0)+1);let S=new Map,C=new Map;for(let a of n.edges.keys())S.set(a,new Set),C.set(a,0);for(let[a,N]of n.edges)for(let n of N)S.has(n)&&(S.get(n).add(a),C.set(a,(C.get(a)??0)+1));let N=[];for(let[n,a]of C)a===0&&N.push(n);N.sort();let F=[];for(;N.length>0;){let a=N.shift(),I=n.byName.get(a);I&&F.push(I);let H=S.get(a);if(H){let n=[];for(let a of H){let S=(C.get(a)??1)-1;C.set(a,S),S===0&&n.push(a)}n.sort(),N.push(...n)}}if(F.length!==C.size){let n=[...C.entries()].filter(([,n])=>n>0).map(([n])=>n);throw Error(`@gjsify/workspace: dependency cycle detected involving ${n.join(`, `)}`)}return F}function filterWorkspaces(n,a){let S=a.include?.map(globToRegex),C=a.exclude?.map(globToRegex);return n.filter(n=>!(a.noPrivate&&n.private||S&&S.length>0&&!S.some(a=>a.test(n.name))||C&&C.length>0&&C.some(a=>a.test(n.name))))}function extractWorkspacePatterns(n){let a=n.workspaces;return a?Array.isArray(a)?a:a.packages??[]:[]}function expandPattern(n,a){let S=a.split(`/`).filter(Boolean),C=[Ao(n)];for(let n of S){let a=[];for(let S of C)if(n===`*`){let n=[];try{n=readdirSync(S)}catch{continue}for(let C of n){if(C.startsWith(`.`))continue;let n=No(S,C);try{statSync(n).isDirectory()&&a.push(n)}catch{}}}else if(n.includes(`*`)){let C=globToRegex(n),N=[];try{N=readdirSync(S)}catch{continue}for(let n of N){if(n.startsWith(`.`)||!C.test(n))continue;let N=No(S,n);try{statSync(N).isDirectory()&&a.push(N)}catch{}}}else{let C=No(S,n);if(existsSync(C))try{statSync(C).isDirectory()&&a.push(C)}catch{}}C=a}return C}function globToRegex(n){let a=n.replace(/[.+?^${}()|[\]\\]/g,`\\$&`).replace(/\*/g,`[^/]*`);return RegExp(`^${a}$`)}function indexByName(n){let a=new Map;for(let S of n)a.set(S.name,S);return a}Fs(),Wo();function readPackageJson$1(n){try{return JSON.parse(readFileSync(n,`utf-8`))}catch{return null}}__name$1(readPackageJson$1,`readPackageJson`);function findWorkspaceRoot(n){let a=n;for(let S=0;S<12;S++){let S=No(a,`package.json`);if(existsSync(S)&&readPackageJson$1(S)?.workspaces!==void 0)try{let S=discoverWorkspaces(a);if(a===n||S.some(a=>a.location===n))return a}catch{}let C=Ao(a,`..`);if(C===a)break;a=C}return null}Be(),Fs(),Wo(),px();const OT={command:`run <target> [args..]`,description:"Run a script from package.json (yarn-run-style) or a GJS bundle file. If <target> resolves to a file on disk (or has a path-like prefix), it is launched via gjs with LD_LIBRARY_PATH + GI_TYPELIB_PATH set for native packages. Otherwise it is looked up in the current package.json `scripts`.",builder:n=>n.positional(`target`,{description:"Either a script name (looked up in package.json `scripts`) or a path to a GJS bundle (e.g. dist/gjs.js).",type:`string`,demandOption:!0}).positional(`args`,{description:`Extra arguments passed through to the script / gjs.`,type:`string`,array:!0,default:[]}),handler:async n=>{let a=n.target,S=n.args??[],C=readPackageJson$2(No(process.cwd(),`package.json`));if(!(C?.scripts&&typeof C.scripts[a]==`string`)&&looksLikeFile(a)){await runGjsBundle(Ao(a),S);return}await runScript(a,S)}};function looksLikeFile(n){if(n.startsWith(`./`)||n.startsWith(`../`)||n.startsWith(`/`)||n.includes(`/`)||n.includes(`\\`)||/\.(c?js|mjs|cjs|gjs)$/.test(n))return!0;try{return statSync(n).isFile()}catch{return!1}}async function runScript(n,a){let S=process.cwd(),C=No(S,`package.json`),N=readPackageJson$2(C);N||(ze.error(`gjsify run: no package.json in ${S}`),process.exit(1));let F=N.scripts??{},I=F[n];if(typeof I!=`string`){let a=Object.keys(F).join(`, `)||`<none>`;ze.error(`gjsify run: no script "${n}" in ${C} (available: ${a})`),process.exit(1)}let H=findWorkspaceRoot(S),W=[No(S,`node_modules`,`.bin`)];H&&H!==S&&W.push(No(H,`node_modules`,`.bin`));let K={...process.env,PATH:[...W,process.env.PATH??``].filter(Boolean).join(Ho),npm_lifecycle_event:n,npm_package_name:N.name??``,npm_package_version:N.version??``},q=a.length>0?`${I} ${a.map(shellEscape).join(` `)}`:I;await new Promise((a,C)=>{let N=spawn(q,[],{cwd:S,env:K,stdio:`inherit`,shell:!0});N.on(`close`,S=>{S===0?a():C(Error(`script "${n}" exited with code ${S}`))}),N.on(`error`,C)}).catch(n=>{ze.error(n.message),process.exit(1)}),process.exit(0)}function shellEscape(n){return/^[a-zA-Z0-9_\-./=:@,]+$/.test(n)?n:`'${n.replace(/'/g,`'\\''`)}'`}Be(),Wo();const kT={command:`info [file]`,description:`Show native gjsify packages detected in node_modules and the env vars needed to run a GJS bundle directly with gjs.`,builder:n=>n.positional(`file`,{description:`Optional: the GJS bundle path to include in the example command (e.g. dist/gjs.js)`,type:`string`,normalize:!0}).option(`export`,{description:`Output only shell export statements suitable for eval (eval $(gjsify info --export))`,type:`boolean`,default:!1}),handler:async n=>{let a=process.cwd(),S=n.file?Ao(n.file):null,C=detectNativePackages(a),{LD_LIBRARY_PATH:N,GI_TYPELIB_PATH:F}=buildNativeEnv(C);if(n.export){ze.log(`export LD_LIBRARY_PATH="${N}"`),ze.log(`export GI_TYPELIB_PATH="${F}"`);return}if(C.length===0){ze.log(`No native gjsify packages detected in node_modules.`),ze.log(`Native packages declare "gjsify": { "prebuilds": "<dir>" } in their package.json.`);return}ze.log(`Native packages detected:`);for(let n of C)ze.log(` ${n.name} → ${n.prebuildsDir}`);ze.log(``),ze.log(`To run your app directly with gjs, set:`),ze.log(` export LD_LIBRARY_PATH="${N}"`),ze.log(` export GI_TYPELIB_PATH="${F}"`),S?ze.log(` gjs -m ${S}`):ze.log(` gjs -m <your-bundle.js>`),ze.log(``),ze.log(`Or use gjsify run to handle this automatically:`),S?ze.log(` gjsify run ${n.file}`):ze.log(` gjsify run <your-bundle.js>`)}};px(),Wo(),wc(),tn(),Fs();function tryExecFile(n,a){try{return execFileSync(n,a,{encoding:`utf-8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()}catch{return null}}function checkBinary(n,a,S,C,N,F,I){let H=tryExecFile(S,C);return H===null?{id:n,name:a,found:!1,severity:N,requiredBy:I}:{id:n,name:a,found:!0,version:F?F(H):H.split(`
|
|
743
743
|
`)[0]??H,severity:N,requiredBy:I}}function checkPkgConfig(n,a,S,C,N){let F=tryExecFile(`pkg-config`,[`--modversion`,S]);return F===null?{id:n,name:a,found:!1,severity:C,requiredBy:N}:{id:n,name:a,found:!0,version:F.split(`
|
|
744
744
|
`)[0],severity:C,requiredBy:N}}function checkNpmPackage(n,a,S,C,N,F){try{return createRequire(pathToFileURL(No(C,`_check_.js`)).href).resolve(S),{id:n,name:a,found:!0,severity:N,requiredBy:F}}catch{}try{return createRequire(import.meta.url).resolve(S),{id:n,name:a,found:!0,severity:N,requiredBy:F}}catch{return{id:n,name:a,found:!1,severity:N,requiredBy:F}}}function detectPackageManager$2(){for(let n of[`apt`,`dnf`,`pacman`,`zypper`,`apk`])if(tryExecFile(`which`,[n])!==null)return n;return`unknown`}__name$1(detectPackageManager$2,`detectPackageManager`);const AT={manette:{id:`manette`,name:`libmanette`,pkgName:`manette-0.2`},gstreamer:{id:`gstreamer`,name:`GStreamer`,pkgName:`gstreamer-1.0`},"gst-app":{id:`gst-app`,name:`GStreamer App`,pkgName:`gstreamer-app-1.0`},"gdk-pixbuf":{id:`gdk-pixbuf`,name:`GdkPixbuf`,pkgName:`gdk-pixbuf-2.0`},pango:{id:`pango`,name:`Pango`,pkgName:`pango`},pangocairo:{id:`pangocairo`,name:`PangoCairo`,pkgName:`pangocairo`},webkitgtk:{id:`webkitgtk`,name:`WebKitGTK`,pkgName:`webkitgtk-6.0`},cairo:{id:`cairo`,name:`Cairo`,pkgName:`cairo`}},jT={"@gjsify/gamepad":[`manette`],"@gjsify/webaudio":[`gstreamer`,`gst-app`],"@gjsify/iframe":[`webkitgtk`],"@gjsify/canvas2d":[`gdk-pixbuf`,`pango`,`pangocairo`,`cairo`],"@gjsify/canvas2d-core":[`gdk-pixbuf`,`pango`,`pangocairo`,`cairo`],"@gjsify/dom-elements":[`gdk-pixbuf`],"@gjsify/webgl":[`gwebgl`]};function findProjectRoot(n){let a=Ao(n);for(;;){if(existsSync(No(a,`package.json`)))return a;let n=Ao(a,`..`);if(n===a)return null;a=n}}function discoverGjsifyPackages(n){let a=findProjectRoot(n);if(!a)return null;let S=No(a,`node_modules`,`@gjsify`);if(!existsSync(S))return new Set;let C=No(a,`package.json`),N={};try{N=JSON.parse(readFileSync(C,`utf-8`))}catch{}let F={...N.dependencies,...N.devDependencies},I=new Set;try{for(let n of readdirSync(S,{withFileTypes:!0}))(n.isDirectory()||n.isSymbolicLink())&&I.add(`@gjsify/${n.name}`)}catch{}for(let n of Object.keys(F))n.startsWith(`@gjsify/`)&&I.add(n);return I}function computeNeededOptionalDeps(n){let a=discoverGjsifyPackages(n);if(a===null)return null;let S=new Set;for(let n of a){let a=jT[n];if(a)for(let n of a)S.add(n)}return S}function runAllChecks(n){let a=computeNeededOptionalDeps(n);return[...runMinimalChecks(),...runRequiredChecks(n),...runOptionalChecks(a,n)]}function runMinimalChecks(){let n=[];return n.push({id:`nodejs`,name:`Node.js`,found:!0,version:process.version,severity:`required`}),n.push(checkBinary(`gjs`,`GJS`,`gjs`,[`--version`],`required`,n=>n.replace(/^GJS\s+/i,``).split(`
|
|
745
745
|
`)[0]??n)),n}function checkGwebgl(n){return checkNpmPackage(`gwebgl`,`gwebgl (@gjsify/webgl)`,`@gjsify/webgl`,n,`optional`,[`@gjsify/webgl`])}function runRequiredChecks(n){let a=[];return a.push(checkBinary(`blueprint-compiler`,`Blueprint Compiler`,`blueprint-compiler`,[`--version`],`required`)),a.push(checkBinary(`pkg-config`,`pkg-config`,`pkg-config`,[`--version`],`required`)),a.push(checkBinary(`meson`,`Meson`,`meson`,[`--version`],`required`)),a.push(checkPkgConfig(`gtk4`,`GTK4`,`gtk4`,`required`)),a.push(checkPkgConfig(`libadwaita`,`libadwaita`,`libadwaita-1`,`required`)),a.push(checkPkgConfig(`libsoup3`,`libsoup3`,`libsoup-3.0`,`required`)),a.push(checkPkgConfig(`gobject-introspection`,`GObject Introspection`,`gobject-introspection-1.0`,`required`)),a}function runOptionalChecks(n,a){let S=[];for(let[a,C]of Object.entries(AT)){if(n!==null&&!n.has(a))continue;let N=Object.entries(jT).filter(([,n])=>n.includes(a)).map(([n])=>n);S.push(checkPkgConfig(C.id,C.name,C.pkgName,`optional`,N))}return(n===null||n.has(`gwebgl`))&&S.push(checkGwebgl(a)),S}const MT={apt:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkg-config`,meson:`meson`,gtk4:`libgtk-4-dev`,libadwaita:`libadwaita-1-dev`,libsoup3:`libsoup-3.0-dev`,webkitgtk:`libwebkit2gtk-6.0-dev`,"gobject-introspection":`gobject-introspection libgirepository1.0-dev`,manette:`libmanette-0.2-0 gir1.2-manette-0.2`,gstreamer:`libgstreamer1.0-dev`,"gst-app":`libgstreamer-plugins-base1.0-dev gir1.2-gst-plugins-base-1.0`,"gdk-pixbuf":`libgdk-pixbuf-2.0-dev`,pango:`libpango1.0-dev`,pangocairo:`libpango1.0-dev`,cairo:`libcairo2-dev`},dnf:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkgconf-pkg-config`,meson:`meson`,gtk4:`gtk4-devel`,libadwaita:`libadwaita-devel`,libsoup3:`libsoup3-devel`,webkitgtk:`webkitgtk6.0-devel`,"gobject-introspection":`gobject-introspection-devel`,manette:`libmanette-devel`,gstreamer:`gstreamer1-devel`,"gst-app":`gstreamer1-plugins-base-devel`,"gdk-pixbuf":`gdk-pixbuf2-devel`,pango:`pango-devel`,pangocairo:`pango-devel`,cairo:`cairo-devel`},pacman:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkgconf`,meson:`meson`,gtk4:`gtk4`,libadwaita:`libadwaita`,libsoup3:`libsoup3`,webkitgtk:`webkitgtk-6.0`,"gobject-introspection":`gobject-introspection`,manette:`libmanette`,gstreamer:`gstreamer`,"gst-app":`gst-plugins-base`,"gdk-pixbuf":`gdk-pixbuf2`,pango:`pango`,pangocairo:`pango`,cairo:`cairo`},zypper:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkg-config`,meson:`meson`,gtk4:`gtk4-devel`,libadwaita:`libadwaita-devel`,libsoup3:`libsoup-3_0-devel`,webkitgtk:`webkitgtk6_0-devel`,"gobject-introspection":`gobject-introspection-devel`,manette:`libmanette-0_2-0-devel`,gstreamer:`gstreamer-devel`,"gst-app":`gstreamer-plugins-base-devel`,"gdk-pixbuf":`gdk-pixbuf-devel`,pango:`pango-devel`,pangocairo:`pango-devel`,cairo:`cairo-devel`},apk:{gjs:`gjs`,"blueprint-compiler":`blueprint-compiler`,"pkg-config":`pkgconf`,meson:`meson`,gtk4:`gtk4.0-dev`,libadwaita:`libadwaita-dev`,libsoup3:`libsoup3-dev`,webkitgtk:`webkit2gtk-6.0-dev`,"gobject-introspection":`gobject-introspection-dev`,manette:`libmanette-dev`,gstreamer:`gstreamer-dev`,"gst-app":`gst-plugins-base-dev`,"gdk-pixbuf":`gdk-pixbuf-dev`,pango:`pango-dev`,pangocairo:`pango-dev`,cairo:`cairo-dev`},unknown:{}},NT={apt:`sudo apt install`,dnf:`sudo dnf install`,pacman:`sudo pacman -S`,zypper:`sudo zypper install`,apk:`sudo apk add`,unknown:``};function buildInstallCommand(n,a){if(n===`unknown`)return null;let S=MT[n],C=[],N=[];for(let n of a){if(n.id===`gwebgl`){N.push(`@gjsify/webgl`);continue}if(n.id===`nodejs`)continue;let a=S[n.id];a&&C.push(a)}let F=[];return C.length>0&&F.push(`${NT[n]} ${C.join(` `)}`),N.length>0&&F.push(`npm install ${N.join(` `)}`),F.length>0?F.join(`
|
|
@@ -779,12 +779,12 @@ jobs:
|
|
|
779
779
|
manifest-path: ${n.manifest}
|
|
780
780
|
bundle: ${n.bundle}
|
|
781
781
|
cache-key: ${n.cacheKey}
|
|
782
|
-
`}const $T={command:`flatpak <subcommand>`,description:`Flatpak toolchain: init/build/deps/ci subcommands for shipping GJS apps and CLIs as Flatpaks.`,builder:n=>n.command(YT.command,YT.description,YT.builder,YT.handler).command(XT.command,XT.description,XT.builder,XT.handler).command(ZT.command,ZT.description,ZT.builder,ZT.handler).command(QT.command,QT.description,QT.builder,QT.handler).demandCommand(1).strict()};Fs(),Wo();const eE=/^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;function parseSpec$1(n){if(!n)throw Error(`dlx: empty package spec`);if(n.startsWith(`./`)||n.startsWith(`../`)||Mo(n)||existsSync(n))return{kind:`local`,path:Ao(n)};let a=n,S,C=n.lastIndexOf(`@`);if(C>0&&(a=n.slice(0,C),S=n.slice(C+1)),!eE.test(a))throw Error(`dlx: invalid package name "${a}"`);return{kind:`registry`,name:a,version:S,spec:n}}__name$1(parseSpec$1,`parseSpec`),Fs(),Wo();function resolveGjsEntry(n,a){let S=No(n,`package.json`);if(!existsSync(S))throw Error(`dlx: no package.json found at ${n}`);let C=JSON.parse(readFileSync(S,`utf-8`)),N=C.gjsify?.bin,F=C.gjsify?.main,I=C.main,H,W=null,K=!1;if(a!==null){if(!N||!N[a]){let S=N?Object.keys(N).join(`, `):`(none)`;throw Error(`dlx: package "${C.name??n}" has no GJS bin named "${a}" — known: ${S}`)}H=N[a],W=a}else if(N&&Object.keys(N).length===1){let n=Object.keys(N)[0];H=N[n],W=n}else F?H=F:I&&(H=I,K=!0);if(N&&Object.keys(N).length>1&&a===null){let a=Object.keys(N).join(`, `);throw Error(`dlx: package "${C.name??n}" defines multiple GJS bins — pass one of: ${a}`)}if(!H)throw Error(`dlx: package "${C.name??n}" has no GJS entry — set \`gjsify.main\` (or \`gjsify.bin\`) in its package.json`);let q=Ao(n,H);if(!existsSync(q))throw Error(`dlx: GJS entry not found: ${q}`);return{bundlePath:q,binName:W,fromFallback:K}}ka(),Fs(),rp(),Wo();function lexCompare(n,a){return n<a?-1:+(n>a)}function createCacheKey(n){let a=[...n.packages].sort(lexCompare),S=Object.entries(n.registries??{}).sort(([n],[a])=>lexCompare(n,a)),C=JSON.stringify([a,S]);return createHash(`sha256`).update(C).digest(`hex`)}function dlxCacheRoot(){let n=process.env.XDG_CACHE_HOME,a=No(n&&n.length>0?n:No(homedir(),`.cache`),`gjsify`,`dlx`);return mkdirSync(a,{recursive:!0}),a}function cacheDirFor(n){let a=No(dlxCacheRoot(),n);return mkdirSync(a,{recursive:!0}),a}function makePrepareDir(n){let a=No(n,`${Date.now().toString(16)}-${process.pid.toString(16)}`);return mkdirSync(a,{recursive:!0}),a}function getValidCachedPkg(n,a=10080){let S=No(n,`pkg`),C;try{C=lstatSync(S)}catch(n){if(n.code===`ENOENT`)return;throw n}if(!C.isSymbolicLink())return;let N;try{N=realpathSync(S)}catch{return}return Date.now()-C.mtime.getTime()<=a*6e4?N:void 0}function symlinkSwap(n,a){let S=No(n,`pkg`),C=No(n,`pkg.tmp-${Date.now().toString(16)}-${process.pid.toString(16)}`);try{symlinkSync(a,C,`dir`)}catch(n){throw n}try{renameSync(C,S)}catch(n){let a=n.code;if(a===`EBUSY`||a===`EPERM`||a===`EEXIST`){try{rmSync(C)}catch{}return realpathSync(S)}throw n}return realpathSync(S)}function resolveInstalledPkgDir(n,a){return Ao(n,`node_modules`,a)}function parse(n){try{return new SemVer(n)}catch{return null}}function satisfies(n,a){let S=a instanceof rE?a:new rE(a),C=n instanceof SemVer?n:parse(String(n));return C?S.test(C):!1}function maxSatisfying(n,a){let S=a instanceof rE?a:new rE(a),C=null;for(let a of n){let n=parse(a);!n||!S.test(n)||(C===null||n.compare(C)>0)&&(C=n)}return C?C.version:null}function testComparator(n,a){if(n.semver===null)return!0;let S=a.compare(n.semver);switch(n.operator){case``:case`=`:return S===0;case`<`:return S<0;case`<=`:return S<=0;case`>`:return S>0;case`>=`:return S>=0}}function formatComparator(n){return n.semver===null?`*`:`${n.operator}${n.semver.version}`}function parseRangePart(n){let a=n.trim();if(a===``||a===`*`||a.toLowerCase()===`latest`)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];let S=a.match(/^\s*(\S+)\s+-\s+(\S+)\s*$/);if(S)return hyphenRange(S[1],S[2]);let C=a.replace(/(<=|>=|<|>|=)\s+(?=\S)/g,`$1`).split(/\s+/),N=[];for(let n of C)N.push(...parseSimple(n));return N}function parseSimple(n){if(n===`*`||n===``||n.toLowerCase()===`latest`)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];if(n.startsWith(`^`))return caretRange(n.slice(1));if(n.startsWith(`~`))return tildeRange(n.slice(1).replace(/^>/,``));let a=n.match(/^(<=|>=|<|>|=)\s*(.+)$/);if(a){let n=a[1];return primitiveRange(n,a[2])}return partialRange(n)}function parsePartial(n){let a=n.trim().replace(/^v/,``);if(a===``||a===`*`)return{major:null,minor:null,patch:null,pre:``,build:``};let S=``,C=``,N=a,F=N.indexOf(`+`);F>=0&&(C=N.slice(F+1),N=N.slice(0,F));let I=N.indexOf(`-`);I>=0&&(S=N.slice(I+1),N=N.slice(0,I));let H=N.split(`.`),xr=a=>{if(a===void 0||a===``||a===`x`||a===`X`||a===`*`)return null;if(!/^\d+$/.test(a))throw TypeError(`Invalid partial version: ${n}`);return Number(a)};return{major:xr(H[0]),minor:xr(H[1]),patch:xr(H[2]),pre:S,build:C}}function partialToVersion(n){return`${n.major??0}.${n.minor??0}.${n.patch??0}${n.pre?`-${n.pre}`:``}${n.build?`+${n.build}`:``}`}function partialRange(n){let a=parsePartial(n);return a.major===null?[{operator:`>=`,semver:new SemVer(`0.0.0`)}]:a.minor===null?[{operator:`>=`,semver:new SemVer(`${a.major}.0.0`)},{operator:`<`,semver:new SemVer(`${a.major+1}.0.0`)}]:a.patch===null?[{operator:`>=`,semver:new SemVer(`${a.major}.${a.minor}.0`)},{operator:`<`,semver:new SemVer(`${a.major}.${a.minor+1}.0`)}]:[{operator:`=`,semver:new SemVer(partialToVersion(a))}]}function caretRange(n){let a=parsePartial(n);if(a.major===null)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];let S=`${a.major}.${a.minor??0}.${a.patch??0}${a.pre?`-${a.pre}`:``}`,C;return C=a.major>0||a.minor===null?`${a.major+1}.0.0`:a.minor>0||a.patch===null?`0.${a.minor+1}.0`:`0.0.${a.patch+1}`,[{operator:`>=`,semver:new SemVer(S)},{operator:`<`,semver:new SemVer(C)}]}function tildeRange(n){let a=parsePartial(n);if(a.major===null)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];let S=`${a.major}.${a.minor??0}.${a.patch??0}${a.pre?`-${a.pre}`:``}`,C=a.minor===null?`${a.major+1}.0.0`:`${a.major}.${a.minor+1}.0`;return[{operator:`>=`,semver:new SemVer(S)},{operator:`<`,semver:new SemVer(C)}]}function primitiveRange(n,a){let S=parsePartial(a);return S.major===null?[{operator:`>=`,semver:new SemVer(`0.0.0`)}]:n===`=`||n===``?partialRange(a):n===`>`?S.minor===null?[{operator:`>=`,semver:new SemVer(`${S.major+1}.0.0`)}]:S.patch===null?[{operator:`>=`,semver:new SemVer(`${S.major}.${S.minor+1}.0`)}]:[{operator:`>`,semver:new SemVer(partialToVersion(S))}]:n===`<`?S.minor===null?[{operator:`<`,semver:new SemVer(`${S.major}.0.0`)}]:S.patch===null?[{operator:`<`,semver:new SemVer(`${S.major}.${S.minor}.0`)}]:[{operator:`<`,semver:new SemVer(partialToVersion(S))}]:n===`>=`?[{operator:`>=`,semver:new SemVer(partialToVersion(S))}]:S.minor===null?[{operator:`<`,semver:new SemVer(`${S.major+1}.0.0`)}]:S.patch===null?[{operator:`<`,semver:new SemVer(`${S.major}.${S.minor+1}.0`)}]:[{operator:`<=`,semver:new SemVer(partialToVersion(S))}]}function hyphenRange(n,a){let S=parsePartial(n),C=parsePartial(a),N=S.major===null?{operator:`>=`,semver:new SemVer(`0.0.0`)}:{operator:`>=`,semver:new SemVer(`${S.major}.${S.minor??0}.${S.patch??0}${S.pre?`-${S.pre}`:``}`)},F;return F=C.major===null?{operator:`>=`,semver:new SemVer(`0.0.0`)}:C.minor===null?{operator:`<`,semver:new SemVer(`${C.major+1}.0.0`)}:C.patch===null?{operator:`<`,semver:new SemVer(`${C.major}.${C.minor+1}.0`)}:{operator:`<=`,semver:new SemVer(`${C.major}.${C.minor}.${C.patch}${C.pre?`-${C.pre}`:``}`)},[N,F]}var tE,nE,SemVer,rE,iE=__esmMin(()=>{tE=/^(0|[1-9]\d*)$/,nE=/^(\d+)\.(\d+)\.(\d+)(?:-((?:[0-9A-Za-z-]+)(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/,SemVer=class{major;minor;patch;prerelease;build;version;constructor(n){let a=String(n).trim().replace(/^v/,``),S=nE.exec(a);if(!S)throw TypeError(`Invalid Version: ${n}`);this.major=Number(S[1]),this.minor=Number(S[2]),this.patch=Number(S[3]),this.prerelease=S[4]?S[4].split(`.`).map(n=>tE.test(n)?Number(n):n):[],this.build=S[5]?S[5].split(`.`):[],this.version=`${this.major}.${this.minor}.${this.patch}`+(this.prerelease.length?`-${this.prerelease.join(`.`)}`:``)+(this.build.length?`+${this.build.join(`.`)}`:``)}compare(n){return this.major===n.major?this.minor===n.minor?this.patch===n.patch?this.comparePre(n):this.patch<n.patch?-1:1:this.minor<n.minor?-1:1:this.major<n.major?-1:1}comparePre(n){let a=this.prerelease,S=n.prerelease;if(a.length===0&&S.length===0)return 0;if(a.length===0)return 1;if(S.length===0)return-1;for(let n=0;;n++){let C=a[n],N=S[n];if(C===void 0&&N===void 0)return 0;if(N===void 0)return 1;if(C===void 0)return-1;if(C===N)continue;let F=typeof C==`number`,I=typeof N==`number`;return F&&!I?-1:!F&&I?1:C<N?-1:1}}toString(){return this.version}},rE=class Range{raw;set;constructor(n){if(n instanceof Range){this.raw=n.raw,this.set=n.set;return}this.raw=String(n).trim();let a=this.raw.split(/\s*\|\|\s*/),S=[];for(let n of a){let a=parseRangePart(n);if(a.length===0)throw TypeError(`Invalid range: ${this.raw}`);S.push(a)}if(S.length===0)throw TypeError(`Invalid range: ${this.raw}`);this.set=S}test(n){let a=n instanceof SemVer?n:parse(String(n));if(!a)return!1;for(let n of this.set)if(n.every(n=>testComparator(n,a))){if(a.prerelease.length>0&&!n.some(n=>n.semver!==null&&n.semver.prerelease.length>0&&n.semver.major===a.major&&n.semver.minor===a.minor&&n.semver.patch===a.patch))continue;return!0}return!1}format(){return this.set.map(n=>n.map(formatComparator).join(` `)).join(` || `)}toString(){return this.format()}}});function assertPackument(n,a){if(!a||typeof a!=`object`)throw TypeError(`registry: ${n} packument is not an object`);let S=a;if(typeof S.name!=`string`)throw TypeError(`registry: ${n} packument missing string name`);if(!S.versions||typeof S.versions!=`object`)throw TypeError(`registry: ${n} packument missing versions map`)}function registryFor(n,a){if(a&&n.startsWith(`@`)){let S=n.slice(0,n.indexOf(`/`)),C=a.scopes[S];if(C)return ensureTrailingSlash(C)}return a?.registry?ensureTrailingSlash(a.registry):aE}function packumentUrl(n,a){let S=ensureTrailingSlash(a);if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a<0)throw TypeError(`Invalid scoped package name: ${n}`);let C=n.slice(0,a),N=n.slice(a+1);return`${S}${encodeURIComponent(C)}/${encodeURIComponent(N)}`}return`${S}${encodeURIComponent(n)}`}async function fetchPackument(n,a={}){let S=packumentUrl(n,a.registry??registryFor(n,a.npmrc)),C=buildHeaders(S,a);C.accept??=`application/vnd.npm.install-v1+json`;let N=a.fetch??globalThis.fetch;if(!N)throw Error(`@gjsify/npm-registry: globalThis.fetch is missing`);let F=await N(S,{headers:C,signal:a.signal});if(!F.ok)throw F.status===404?new PackageNotFoundError(n,S):Error(`registry GET ${S} -> ${F.status} ${F.statusText}`);let I=await F.json();return assertPackument(n,I),I}async function fetchTarball(n,a={}){let S=buildHeaders(n,a);S.accept??=`application/octet-stream`;let C=a.fetch??globalThis.fetch;if(!C)throw Error(`@gjsify/npm-registry: globalThis.fetch is missing`);let N=await C(n,{headers:S,signal:a.signal});if(!N.ok)throw Error(`tarball GET ${n} -> ${N.status} ${N.statusText}`);let F=new Uint8Array(await N.arrayBuffer());if(a.integrity&&!await verifyIntegrity(F,a.integrity))throw new IntegrityError(n,a.integrity);return F}async function verifyIntegrity(n,a){let S=a.trim().split(/\s+/);for(let a of S){let S=a.indexOf(`-`);if(S<0)continue;let C=a.slice(0,S).toLowerCase(),N=a.slice(S+1),F=globalThis.crypto?.subtle;if(!F)throw Error(`@gjsify/npm-registry: globalThis.crypto.subtle is missing`);let I=subriToWebCryptoAlgo(C);if(!I)continue;let H=await F.digest(I,dataAsArrayBuffer(n));if(bytesToBase64(new Uint8Array(H))===N)return!0}return!1}function subriToWebCryptoAlgo(n){switch(n){case`sha1`:return`SHA-1`;case`sha256`:return`SHA-256`;case`sha384`:return`SHA-384`;case`sha512`:return`SHA-512`;default:return null}}function dataAsArrayBuffer(n){if(n.byteOffset===0&&n.byteLength===n.buffer.byteLength)return n.buffer;let a=new Uint8Array(n.byteLength);return a.set(n),a.buffer}function bytesToBase64(n){let a=``;for(let S=0;S<n.length;S++)a+=String.fromCharCode(n[S]);return btoa(a)}function parseNpmrc(n){let a={registry:aE,scopes:{},authTokens:{},basicAuth:{}},S=n.split(/\r?\n/),C={};for(let n of S){let S=n.replace(/^\s+|\s+$/g,``);if(!S||S.startsWith(`#`)||S.startsWith(`;`))continue;let N=S.indexOf(`=`);if(N<0)continue;let F=S.slice(0,N).trim(),I=expandEnv(stripQuotes(S.slice(N+1).trim()));if(F===`registry`){a.registry=ensureTrailingSlash(I);continue}let H=F.match(/^(@[^:]+):registry$/);if(H){a.scopes[H[1]]=ensureTrailingSlash(I);continue}let W=F.match(/^\/\/(.+):_authToken$/);if(W){a.authTokens[normalizeAuthHost(W[1])]=I;continue}let K=F.match(/^\/\/(.+):username$/);if(K){(C[normalizeAuthHost(K[1])]??={}).user=I;continue}let q=F.match(/^\/\/(.+):_password$/);if(q){let n=base64Decode(I);(C[normalizeAuthHost(q[1])]??={}).pass=n;continue}}for(let[n,S]of Object.entries(C))S.user&&S.pass!==void 0&&(a.basicAuth[n]={username:S.user,password:S.pass});return a}function buildHeaders(n,a){let S={"user-agent":`gjsify-install/0.3.7`};if(a.npmrc){let C=resolveAuthForUrl(n,a.npmrc);C&&(S.authorization=C)}if(a.headers)for(let[n,C]of Object.entries(a.headers))S[n.toLowerCase()]=C;return S}function resolveAuthForUrl(n,a){let S=pathPrefixes(new URL(n));for(let n of S){let S=a.authTokens[n];if(S)return`Bearer ${S}`;let C=a.basicAuth[n];if(C)return`Basic ${btoa(`${C.username}:${C.password}`)}`}return null}function pathPrefixes(n){let a=n.pathname.split(`/`).filter(Boolean),S=[];for(let C=a.length;C>=0;C--){let N=a.slice(0,C).join(`/`);S.push(N?`//${n.host}/${N}`:`//${n.host}`)}return S}function normalizeAuthHost(n){return`//${n.replace(/\/+$/,``)}`}function ensureTrailingSlash(n){return n.endsWith(`/`)?n:n+`/`}function stripQuotes(n){return n.startsWith(`"`)&&n.endsWith(`"`)||n.startsWith(`'`)&&n.endsWith(`'`)?n.slice(1,-1):n}function expandEnv(n){return n.replace(/\$\{([A-Z0-9_]+)\}/gi,(n,a)=>globalThis.process?.env?.[a]??``)}function base64Decode(n){return atob(n)}var aE,PackageNotFoundError,IntegrityError,oE=__esmMin(()=>{aE=`https://registry.npmjs.org/`,PackageNotFoundError=class extends Error{name;url;constructor(n,a){super(`Package not found in registry: ${n} (${a})`),this.name=n,this.url=a,this.name=`PackageNotFoundError`}},IntegrityError=class extends Error{url;integrity;constructor(n,a){super(`Tarball integrity mismatch for ${n} (expected ${a})`),this.url=n,this.integrity=a,this.name=`IntegrityError`}}});function parseTar(n){let a=[],S=null,C=null,N=null,F=0;for(;F+512<=n.length;){let I=n.subarray(F,F+512);if(allZeros(I)){let a=n.subarray(F+512,F+2*512);if(a.length===512&&allZeros(a))break;F+=512;continue}if(!validateChecksum(I))throw new TarParseError(`Bad header checksum at offset ${F} — file is not a valid tar archive`);let H=readString(I,0,100),W=parseOctal(I,100,8),K=parseOctal(I,124,12),q=parseOctal(I,136,12),Y=String.fromCharCode(I[156]||0),X=readString(I,157,100),te=readString(I,257,6),ne=readString(I,345,155),re=readString(I,265,32),ie=readString(I,297,32);F+=512;let ae=n.subarray(F,F+K);if(F+=alignToBlock(K),Y===`x`){S=parsePaxRecords(ae);continue}if(Y===`g`)continue;if(Y===`L`){C=bytesToString(ae).replace(/\0+$/,``);continue}if(Y===`K`){N=bytesToString(ae).replace(/\0+$/,``);continue}let oe=H;te===`ustar`&&ne!==``&&(oe=`${ne}/${H}`),C!==null&&(oe=C,C=null);let Z=X;if(N!==null&&(Z=N,N=null),S!==null){let C=S.get(`path`);C!==void 0&&(oe=C);let N=S.get(`linkpath`);N!==void 0&&(Z=N);let I=S.get(`size`);if(I!==void 0){let C=Number(I);if(Number.isFinite(C)){let N=F-alignToBlock(K),I=n.subarray(N,N+C);F=N+alignToBlock(C),S=null,a.push(buildEntry(oe,Z,Y,W,q,re,ie,I));continue}}S=null}a.push(buildEntry(oe,Z,Y,W,q,re,ie,ae))}return a}function buildEntry(n,a,S,C,N,F,I,H){return{name:n,linkname:a,type:typeflagToType(S,n),mode:C,mtime:N,body:H,uname:F,gname:I}}function typeflagToType(n,a){switch(n){case`0`:case`\0`:case``:return a.endsWith(`/`)?`directory`:`file`;case`1`:return`hardlink`;case`2`:return`symlink`;case`5`:return`directory`;case`x`:return`pax-header`;case`g`:return`pax-global`;case`L`:return`gnu-longname`;case`K`:return`gnu-longlink`;default:return`unknown`}}function parsePaxRecords(n){let a=new Map,S=0;for(;S<n.length;){let C=S;for(;C<n.length&&n[C]!==32;)C++;if(C>=n.length)break;let N=bytesToString(n.subarray(S,C)),F=Number(N);if(!Number.isFinite(F)||F<=0)break;let I=S+F;if(I>n.length)break;let H=bytesToString(n.subarray(C+1,I-1)),W=H.indexOf(`=`);if(W>0){let n=H.slice(0,W),S=H.slice(W+1);a.set(n,S)}S=I}return a}function readString(n,a,S){let C=a,N=a+S;for(;C<N&&n[C]!==0;)C++;return bytesToString(n.subarray(a,C))}function bytesToString(n){return new TextDecoder(`utf-8`,{fatal:!1}).decode(n)}function parseOctal(n,a,S){if(S>0&&n[a]&128){let C=n[a]&127;for(let N=1;N<S;N++)C=C*256+n[a+N];return C}let C=``;for(let N=0;N<S;N++){let S=n[a+N];S===0||S===32||(C+=String.fromCharCode(S))}return C===``?0:parseInt(C,8)}function alignToBlock(n){return Math.ceil(n/512)*512}function allZeros(n){for(let a=0;a<n.length;a++)if(n[a]!==0)return!1;return!0}function validateChecksum(n){let a=parseOctal(n,148,8),S=0,C=0;for(let a=0;a<512;a++){let N=a>=148&&a<156?32:n[a];S+=N,C+=N>127?N-256:N}return a===S||a===C}var TarParseError,sE=__esmMin(()=>{TarParseError=class extends Error{constructor(n){super(n),this.name=`TarParseError`}}});async function extractTarball(n,a,S={}){let C=n instanceof Uint8Array?n:new Uint8Array(n),N=parseTar(S.gzip??(C.length>=2&&C[0]===31&&C[1]===139)?await gunzip(C):C);mkdirSync(a,{recursive:!0});let F=S.strip??1,I=S.preventEscape??!0,H={files:[],directories:[],symlinks:[],skipped:0};for(let n of N){let C=stripComponents(n.name,F);if(C===null||C===``){H.skipped++;continue}let N=Ao(a,C);if(I&&!isInside(N,a))throw Error(`tar: refusing to extract ${n.name} outside ${a} (resolved=${N})`);if(S.filter&&!S.filter(n,N)){H.skipped++;continue}if(n.type===`directory`){mkdirSync(N,{recursive:!0}),H.directories.push(N);continue}if(n.type===`file`){mkdirSync(Io(N),{recursive:!0}),writeFileSync(N,n.body);let a=S.chmod?.(n,N)??n.mode&511;if(a>0)try{chmodSync(N,a)}catch{}H.files.push(N);continue}if(n.type===`symlink`){mkdirSync(Io(N),{recursive:!0});try{symlinkSync(n.linkname,N),H.symlinks.push(N)}catch{writeFileSync(N,n.linkname),H.files.push(N)}continue}H.skipped++}return H}async function gunzip(n){let a=globalThis.DecompressionStream;if(typeof a!=`function`)throw Error(`@gjsify/tar: globalThis.DecompressionStream is not available — import '@gjsify/compression-streams/register' on GJS to register it`);let S=new Blob([new Uint8Array(n)]).stream().pipeThrough(new a(`gzip`)),C=[],N=0,F=S.getReader();for(;;){let{value:n,done:a}=await F.read();if(a)break;let S=n instanceof Uint8Array?n:new Uint8Array(n);C.push(S),N+=S.length}let I=new Uint8Array(N),H=0;for(let n of C)I.set(n,H),H+=n.length;return I}function stripComponents(n,a){if(a<=0)return n;let S=n.split(`/`).filter(n=>n!==``);return S.length<=a?null:S.slice(a).join(`/`)}function isInside(n,a){let S=Po(a,n);return S!==``&&!S.startsWith(`..`)&&!Mo(S)}var cE=__esmMin(()=>{sE(),Fs(),Wo()}),lE=__esmMin(()=>{cE()}),uE=__exportAll$3({installPackagesNative:()=>installPackagesNative});async function installPackagesNative(n){if(n.specs.length===0)throw Error(`installPackagesNative: empty specs list`);mkdirSync(n.prefix,{recursive:!0});let a=await loadNpmrc(n),S=makeLogger(n.verbose??!1),C=No(n.prefix,fE),N=readLockfile(C),F;if(n.frozen){if(!N)throw Error(`install: --immutable requires ${fE} at ${n.prefix} — none found. Run \`gjsify install\` (without --immutable) to generate one and commit it.`);let a=describeLockfileDrift(N,n.specs);if(a)throw Error(`install: --immutable but ${C} is stale.\n${a}\nRe-run \`gjsify install\` (without --immutable) to refresh the lockfile.`);S(`install: --immutable, using lockfile (%d package(s))`,Object.keys(N.packages).length),F=lockfileToNodes(N)}else N&&lockfileMatchesRequest(N,n.specs)?(S(`install: using lockfile (%d package(s))`,Object.keys(N.packages).length),F=lockfileToNodes(N)):(S(`install: resolving %d top-level spec(s) → %s`,n.specs.length,n.prefix),F=await resolveDeps(n.specs,a,S),n.lockfile&&(writeLockfile(C,n.specs,F),S(`install: wrote %s (%d entries)`,fE,F.length)));return S(`install: downloading %d tarball(s)`,F.length),await downloadAndExtractAll(F,n.prefix,a,S),await linkBins(F,n.prefix,S),S(`install: done`),topLevelResolutions(n.specs,F)}function topLevelResolutions(n,a){let S=new Map;for(let n of a)n.installPath===`node_modules/${n.name}`&&S.set(n.name,n);let C=[];for(let a of n){let n=parseSpecName(a),N=S.get(n);N&&C.push({name:N.name,version:N.version})}return C}function parseSpecName(n){if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a===-1)return n;let S=n.indexOf(`@`,a+1);return S===-1?n:n.slice(0,S)}let a=n.indexOf(`@`);return a===-1?n:n.slice(0,a)}async function resolveDeps(n,a,S){let C=new Map,fetchPkg=n=>{let S=C.get(n);if(S)return S;let N=fetchPackument(n,{npmrc:a});return C.set(n,N),N},N=new Map,F=new Map,I=n.map(parseSpec).map(n=>({from:null,name:n.name,range:n.range,required:!0}));for(;I.length>0;){let n=I.shift(),a=findVisible(n.from,n.name,N);if(a&&satisfiesRange(a.version,n.range))continue;let C=null;try{let a=await fetchPkg(n.name);if(C=pickVersion(a,n.range),!C){if(!n.required)continue;throw Error(`No version of ${n.name} satisfies ${n.range}`)}let H=a.versions[C];if(!H)throw Error(`Packument for ${n.name} promised ${C} but no entry exists`);let W=decidePlacement(n.from,n.name,C,F),K={name:n.name,version:C,tarballUrl:H.dist.tarball,integrity:H.dist.integrity,installPath:W,dependencies:H.dependencies??{},optionalDependencies:H.optionalDependencies??{},bin:H.bin};N.set(W,K),W===`node_modules/${n.name}`&&F.set(n.name,K),S(`resolve: %s@%s ← %s (at %s)`,n.name,C,n.range,W);for(let[n,a]of Object.entries(K.dependencies))I.push({from:W,name:n,range:a,required:!0});for(let[n,a]of Object.entries(K.optionalDependencies))I.push({from:W,name:n,range:a,required:!1})}catch(a){if(!n.required){S(`resolve: optional dep %s@%s skipped (%s)`,n.name,n.range,a.message);continue}throw a}}return Array.from(N.values())}function findVisible(n,a,S){let C=[];if(n!==null){C.push(`${n}/node_modules/${a}`);let S=n;for(;;){let n=S.lastIndexOf(`/node_modules/`);if(n<0||(S=S.slice(0,n),C.push(`${S}/node_modules/${a}`),S===``))break}}C.push(`node_modules/${a}`);for(let n of C){let a=S.get(n);if(a)return a}return null}function decidePlacement(n,a,S,C){let N=C.get(a);return!N||N.version===S||n===null?`node_modules/${a}`:`${n}/node_modules/${a}`}function satisfiesRange(n,a){try{return satisfies(n,new rE(a))}catch{return!1}}function readLockfile(n){if(!existsSync(n))return null;try{let a=JSON.parse(readFileSync(n,`utf-8`));return a.lockfileVersion!==pE||!a.packages||typeof a.packages!=`object`?null:a}catch{return null}}function writeLockfile(n,a,S){let C={},N=[...S].sort((n,a)=>n.installPath<a.installPath?-1:+(n.installPath>a.installPath));for(let n of N)C[n.installPath]={version:n.version,resolved:n.tarballUrl,integrity:n.integrity,dependencies:Object.keys(n.dependencies).length>0?n.dependencies:void 0,bin:n.bin};let F={lockfileVersion:pE,requested:[...a],packages:C};writeFileSync(n,JSON.stringify(F,null,2)+`
|
|
782
|
+
`}const $T={command:`flatpak <subcommand>`,description:`Flatpak toolchain: init/build/deps/ci subcommands for shipping GJS apps and CLIs as Flatpaks.`,builder:n=>n.command(YT.command,YT.description,YT.builder,YT.handler).command(XT.command,XT.description,XT.builder,XT.handler).command(ZT.command,ZT.description,ZT.builder,ZT.handler).command(QT.command,QT.description,QT.builder,QT.handler).demandCommand(1).strict()};Fs(),Wo();const eE=/^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;function parseSpec$1(n){if(!n)throw Error(`dlx: empty package spec`);if(n.startsWith(`./`)||n.startsWith(`../`)||Mo(n)||existsSync(n))return{kind:`local`,path:Ao(n)};let a=n,S,C=n.lastIndexOf(`@`);if(C>0&&(a=n.slice(0,C),S=n.slice(C+1)),!eE.test(a))throw Error(`dlx: invalid package name "${a}"`);return{kind:`registry`,name:a,version:S,spec:n}}__name$1(parseSpec$1,`parseSpec`),Fs(),Wo();function resolveGjsEntry(n,a){let S=No(n,`package.json`);if(!existsSync(S))throw Error(`dlx: no package.json found at ${n}`);let C=JSON.parse(readFileSync(S,`utf-8`)),N=C.gjsify?.bin,F=C.gjsify?.main,I=C.main,H,W=null,K=!1;if(a!==null){if(!N||!N[a]){let S=N?Object.keys(N).join(`, `):`(none)`;throw Error(`dlx: package "${C.name??n}" has no GJS bin named "${a}" — known: ${S}`)}H=N[a],W=a}else if(N&&Object.keys(N).length===1){let n=Object.keys(N)[0];H=N[n],W=n}else F?H=F:I&&(H=I,K=!0);if(N&&Object.keys(N).length>1&&a===null){let a=Object.keys(N).join(`, `);throw Error(`dlx: package "${C.name??n}" defines multiple GJS bins — pass one of: ${a}`)}if(!H)throw Error(`dlx: package "${C.name??n}" has no GJS entry — set \`gjsify.main\` (or \`gjsify.bin\`) in its package.json`);let q=Ao(n,H);if(!existsSync(q))throw Error(`dlx: GJS entry not found: ${q}`);return{bundlePath:q,binName:W,fromFallback:K}}ka(),Fs(),rp(),Wo();function lexCompare(n,a){return n<a?-1:+(n>a)}function createCacheKey(n){let a=[...n.packages].sort(lexCompare),S=Object.entries(n.registries??{}).sort(([n],[a])=>lexCompare(n,a)),C=JSON.stringify([a,S]);return createHash(`sha256`).update(C).digest(`hex`)}function dlxCacheRoot(){let n=process.env.XDG_CACHE_HOME,a=No(n&&n.length>0?n:No(homedir(),`.cache`),`gjsify`,`dlx`);return mkdirSync(a,{recursive:!0}),a}function cacheDirFor(n){let a=No(dlxCacheRoot(),n);return mkdirSync(a,{recursive:!0}),a}function makePrepareDir(n){let a=No(n,`${Date.now().toString(16)}-${process.pid.toString(16)}`);return mkdirSync(a,{recursive:!0}),a}function getValidCachedPkg(n,a=10080){let S=No(n,`pkg`),C;try{C=lstatSync(S)}catch(n){if(n.code===`ENOENT`)return;throw n}if(!C.isSymbolicLink())return;let N;try{N=realpathSync(S)}catch{return}return Date.now()-C.mtime.getTime()<=a*6e4?N:void 0}function symlinkSwap(n,a){let S=No(n,`pkg`),C=No(n,`pkg.tmp-${Date.now().toString(16)}-${process.pid.toString(16)}`);try{symlinkSync(a,C,`dir`)}catch(n){throw n}try{renameSync(C,S)}catch(n){let a=n.code;if(a===`EBUSY`||a===`EPERM`||a===`EEXIST`){try{rmSync(C)}catch{}return realpathSync(S)}throw n}return realpathSync(S)}function resolveInstalledPkgDir(n,a){return Ao(n,`node_modules`,a)}function parse(n){try{return new SemVer(n)}catch{return null}}function satisfies(n,a){let S=a instanceof rE?a:new rE(a),C=n instanceof SemVer?n:parse(String(n));return C?S.test(C):!1}function maxSatisfying(n,a){let S=a instanceof rE?a:new rE(a),C=null;for(let a of n){let n=parse(a);!n||!S.test(n)||(C===null||n.compare(C)>0)&&(C=n)}return C?C.version:null}function testComparator(n,a){if(n.semver===null)return!0;let S=a.compare(n.semver);switch(n.operator){case``:case`=`:return S===0;case`<`:return S<0;case`<=`:return S<=0;case`>`:return S>0;case`>=`:return S>=0}}function formatComparator(n){return n.semver===null?`*`:`${n.operator}${n.semver.version}`}function parseRangePart(n){let a=n.trim();if(a===``||a===`*`||a.toLowerCase()===`latest`)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];let S=a.match(/^\s*(\S+)\s+-\s+(\S+)\s*$/);if(S)return hyphenRange(S[1],S[2]);let C=a.replace(/(<=|>=|<|>|=)\s+(?=\S)/g,`$1`).split(/\s+/),N=[];for(let n of C)N.push(...parseSimple(n));return N}function parseSimple(n){if(n===`*`||n===``||n.toLowerCase()===`latest`)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];if(n.startsWith(`^`))return caretRange(n.slice(1));if(n.startsWith(`~`))return tildeRange(n.slice(1).replace(/^>/,``));let a=n.match(/^(<=|>=|<|>|=)\s*(.+)$/);if(a){let n=a[1];return primitiveRange(n,a[2])}return partialRange(n)}function parsePartial(n){let a=n.trim().replace(/^v/,``);if(a===``||a===`*`)return{major:null,minor:null,patch:null,pre:``,build:``};let S=``,C=``,N=a,F=N.indexOf(`+`);F>=0&&(C=N.slice(F+1),N=N.slice(0,F));let I=N.indexOf(`-`);I>=0&&(S=N.slice(I+1),N=N.slice(0,I));let H=N.split(`.`),xr=a=>{if(a===void 0||a===``||a===`x`||a===`X`||a===`*`)return null;if(!/^\d+$/.test(a))throw TypeError(`Invalid partial version: ${n}`);return Number(a)};return{major:xr(H[0]),minor:xr(H[1]),patch:xr(H[2]),pre:S,build:C}}function partialToVersion(n){return`${n.major??0}.${n.minor??0}.${n.patch??0}${n.pre?`-${n.pre}`:``}${n.build?`+${n.build}`:``}`}function partialRange(n){let a=parsePartial(n);return a.major===null?[{operator:`>=`,semver:new SemVer(`0.0.0`)}]:a.minor===null?[{operator:`>=`,semver:new SemVer(`${a.major}.0.0`)},{operator:`<`,semver:new SemVer(`${a.major+1}.0.0`)}]:a.patch===null?[{operator:`>=`,semver:new SemVer(`${a.major}.${a.minor}.0`)},{operator:`<`,semver:new SemVer(`${a.major}.${a.minor+1}.0`)}]:[{operator:`=`,semver:new SemVer(partialToVersion(a))}]}function caretRange(n){let a=parsePartial(n);if(a.major===null)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];let S=`${a.major}.${a.minor??0}.${a.patch??0}${a.pre?`-${a.pre}`:``}`,C;return C=a.major>0||a.minor===null?`${a.major+1}.0.0`:a.minor>0||a.patch===null?`0.${a.minor+1}.0`:`0.0.${a.patch+1}`,[{operator:`>=`,semver:new SemVer(S)},{operator:`<`,semver:new SemVer(C)}]}function tildeRange(n){let a=parsePartial(n);if(a.major===null)return[{operator:`>=`,semver:new SemVer(`0.0.0`)}];let S=`${a.major}.${a.minor??0}.${a.patch??0}${a.pre?`-${a.pre}`:``}`,C=a.minor===null?`${a.major+1}.0.0`:`${a.major}.${a.minor+1}.0`;return[{operator:`>=`,semver:new SemVer(S)},{operator:`<`,semver:new SemVer(C)}]}function primitiveRange(n,a){let S=parsePartial(a);return S.major===null?[{operator:`>=`,semver:new SemVer(`0.0.0`)}]:n===`=`||n===``?partialRange(a):n===`>`?S.minor===null?[{operator:`>=`,semver:new SemVer(`${S.major+1}.0.0`)}]:S.patch===null?[{operator:`>=`,semver:new SemVer(`${S.major}.${S.minor+1}.0`)}]:[{operator:`>`,semver:new SemVer(partialToVersion(S))}]:n===`<`?S.minor===null?[{operator:`<`,semver:new SemVer(`${S.major}.0.0`)}]:S.patch===null?[{operator:`<`,semver:new SemVer(`${S.major}.${S.minor}.0`)}]:[{operator:`<`,semver:new SemVer(partialToVersion(S))}]:n===`>=`?[{operator:`>=`,semver:new SemVer(partialToVersion(S))}]:S.minor===null?[{operator:`<`,semver:new SemVer(`${S.major+1}.0.0`)}]:S.patch===null?[{operator:`<`,semver:new SemVer(`${S.major}.${S.minor+1}.0`)}]:[{operator:`<=`,semver:new SemVer(partialToVersion(S))}]}function hyphenRange(n,a){let S=parsePartial(n),C=parsePartial(a),N=S.major===null?{operator:`>=`,semver:new SemVer(`0.0.0`)}:{operator:`>=`,semver:new SemVer(`${S.major}.${S.minor??0}.${S.patch??0}${S.pre?`-${S.pre}`:``}`)},F;return F=C.major===null?{operator:`>=`,semver:new SemVer(`0.0.0`)}:C.minor===null?{operator:`<`,semver:new SemVer(`${C.major+1}.0.0`)}:C.patch===null?{operator:`<`,semver:new SemVer(`${C.major}.${C.minor+1}.0`)}:{operator:`<=`,semver:new SemVer(`${C.major}.${C.minor}.${C.patch}${C.pre?`-${C.pre}`:``}`)},[N,F]}var tE,nE,SemVer,rE,iE=__esmMin(()=>{tE=/^(0|[1-9]\d*)$/,nE=/^(\d+)\.(\d+)\.(\d+)(?:-((?:[0-9A-Za-z-]+)(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/,SemVer=class{major;minor;patch;prerelease;build;version;constructor(n){let a=String(n).trim().replace(/^v/,``),S=nE.exec(a);if(!S)throw TypeError(`Invalid Version: ${n}`);this.major=Number(S[1]),this.minor=Number(S[2]),this.patch=Number(S[3]),this.prerelease=S[4]?S[4].split(`.`).map(n=>tE.test(n)?Number(n):n):[],this.build=S[5]?S[5].split(`.`):[],this.version=`${this.major}.${this.minor}.${this.patch}`+(this.prerelease.length?`-${this.prerelease.join(`.`)}`:``)+(this.build.length?`+${this.build.join(`.`)}`:``)}compare(n){return this.major===n.major?this.minor===n.minor?this.patch===n.patch?this.comparePre(n):this.patch<n.patch?-1:1:this.minor<n.minor?-1:1:this.major<n.major?-1:1}comparePre(n){let a=this.prerelease,S=n.prerelease;if(a.length===0&&S.length===0)return 0;if(a.length===0)return 1;if(S.length===0)return-1;for(let n=0;;n++){let C=a[n],N=S[n];if(C===void 0&&N===void 0)return 0;if(N===void 0)return 1;if(C===void 0)return-1;if(C===N)continue;let F=typeof C==`number`,I=typeof N==`number`;return F&&!I?-1:!F&&I?1:C<N?-1:1}}toString(){return this.version}},rE=class Range{raw;set;constructor(n){if(n instanceof Range){this.raw=n.raw,this.set=n.set;return}this.raw=String(n).trim();let a=this.raw.split(/\s*\|\|\s*/),S=[];for(let n of a){let a=parseRangePart(n);if(a.length===0)throw TypeError(`Invalid range: ${this.raw}`);S.push(a)}if(S.length===0)throw TypeError(`Invalid range: ${this.raw}`);this.set=S}test(n){let a=n instanceof SemVer?n:parse(String(n));if(!a)return!1;for(let n of this.set)if(n.every(n=>testComparator(n,a))){if(a.prerelease.length>0&&!n.some(n=>n.semver!==null&&n.semver.prerelease.length>0&&n.semver.major===a.major&&n.semver.minor===a.minor&&n.semver.patch===a.patch))continue;return!0}return!1}format(){return this.set.map(n=>n.map(formatComparator).join(` `)).join(` || `)}toString(){return this.format()}}});function assertPackument(n,a){if(!a||typeof a!=`object`)throw TypeError(`registry: ${n} packument is not an object`);let S=a;if(typeof S.name!=`string`)throw TypeError(`registry: ${n} packument missing string name`);if(!S.versions||typeof S.versions!=`object`)throw TypeError(`registry: ${n} packument missing versions map`)}function registryFor(n,a){if(a&&n.startsWith(`@`)){let S=n.slice(0,n.indexOf(`/`)),C=a.scopes[S];if(C)return ensureTrailingSlash(C)}return a?.registry?ensureTrailingSlash(a.registry):aE}function packumentUrl(n,a){let S=ensureTrailingSlash(a);if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a<0)throw TypeError(`Invalid scoped package name: ${n}`);let C=n.slice(0,a),N=n.slice(a+1);return`${S}${encodeURIComponent(C)}/${encodeURIComponent(N)}`}return`${S}${encodeURIComponent(n)}`}async function fetchPackument(n,a={}){let S=packumentUrl(n,a.registry??registryFor(n,a.npmrc)),C=buildHeaders(S,a);C.accept??=`application/vnd.npm.install-v1+json`;let N=a.fetch??globalThis.fetch;if(!N)throw Error(`@gjsify/npm-registry: globalThis.fetch is missing`);let F=await N(S,{headers:C,signal:a.signal});if(!F.ok)throw F.status===404?new PackageNotFoundError(n,S):Error(`registry GET ${S} -> ${F.status} ${F.statusText}`);let I=await F.json();return assertPackument(n,I),I}async function fetchTarball(n,a={}){let S=buildHeaders(n,a);S.accept??=`application/octet-stream`;let C=a.fetch??globalThis.fetch;if(!C)throw Error(`@gjsify/npm-registry: globalThis.fetch is missing`);let N=await C(n,{headers:S,signal:a.signal});if(!N.ok)throw Error(`tarball GET ${n} -> ${N.status} ${N.statusText}`);let F=new Uint8Array(await N.arrayBuffer());if(a.integrity&&!await verifyIntegrity(F,a.integrity))throw new IntegrityError(n,a.integrity);return F}async function verifyIntegrity(n,a){let S=a.trim().split(/\s+/);for(let a of S){let S=a.indexOf(`-`);if(S<0)continue;let C=a.slice(0,S).toLowerCase(),N=a.slice(S+1),F=globalThis.crypto?.subtle;if(!F)throw Error(`@gjsify/npm-registry: globalThis.crypto.subtle is missing`);let I=subriToWebCryptoAlgo(C);if(!I)continue;let H=await F.digest(I,dataAsArrayBuffer(n));if(bytesToBase64(new Uint8Array(H))===N)return!0}return!1}function subriToWebCryptoAlgo(n){switch(n){case`sha1`:return`SHA-1`;case`sha256`:return`SHA-256`;case`sha384`:return`SHA-384`;case`sha512`:return`SHA-512`;default:return null}}function dataAsArrayBuffer(n){if(n.byteOffset===0&&n.byteLength===n.buffer.byteLength)return n.buffer;let a=new Uint8Array(n.byteLength);return a.set(n),a.buffer}function bytesToBase64(n){let a=``;for(let S=0;S<n.length;S++)a+=String.fromCharCode(n[S]);return btoa(a)}function parseNpmrc(n){let a={registry:aE,scopes:{},authTokens:{},basicAuth:{}},S=n.split(/\r?\n/),C={};for(let n of S){let S=n.replace(/^\s+|\s+$/g,``);if(!S||S.startsWith(`#`)||S.startsWith(`;`))continue;let N=S.indexOf(`=`);if(N<0)continue;let F=S.slice(0,N).trim(),I=expandEnv(stripQuotes(S.slice(N+1).trim()));if(F===`registry`){a.registry=ensureTrailingSlash(I);continue}let H=F.match(/^(@[^:]+):registry$/);if(H){a.scopes[H[1]]=ensureTrailingSlash(I);continue}let W=F.match(/^\/\/(.+):_authToken$/);if(W){a.authTokens[normalizeAuthHost(W[1])]=I;continue}let K=F.match(/^\/\/(.+):username$/);if(K){(C[normalizeAuthHost(K[1])]??={}).user=I;continue}let q=F.match(/^\/\/(.+):_password$/);if(q){let n=base64Decode(I);(C[normalizeAuthHost(q[1])]??={}).pass=n;continue}}for(let[n,S]of Object.entries(C))S.user&&S.pass!==void 0&&(a.basicAuth[n]={username:S.user,password:S.pass});return a}function buildHeaders(n,a){let S={"user-agent":`gjsify-install/0.3.7`};if(a.npmrc){let C=resolveAuthForUrl(n,a.npmrc);C&&(S.authorization=C)}if(a.headers)for(let[n,C]of Object.entries(a.headers))S[n.toLowerCase()]=C;return S}function resolveAuthForUrl(n,a){let S=pathPrefixes(new URL(n));for(let n of S){let S=a.authTokens[n];if(S)return`Bearer ${S}`;let C=a.basicAuth[n];if(C)return`Basic ${btoa(`${C.username}:${C.password}`)}`}return null}function pathPrefixes(n){let a=n.pathname.split(`/`).filter(Boolean),S=[];for(let C=a.length;C>=0;C--){let N=a.slice(0,C).join(`/`);S.push(N?`//${n.host}/${N}`:`//${n.host}`)}return S}function normalizeAuthHost(n){return`//${n.replace(/\/+$/,``)}`}function ensureTrailingSlash(n){return n.endsWith(`/`)?n:n+`/`}function stripQuotes(n){return n.startsWith(`"`)&&n.endsWith(`"`)||n.startsWith(`'`)&&n.endsWith(`'`)?n.slice(1,-1):n}function expandEnv(n){return n.replace(/\$\{([A-Z0-9_]+)\}/gi,(n,a)=>globalThis.process?.env?.[a]??``)}function base64Decode(n){return atob(n)}var aE,PackageNotFoundError,IntegrityError,oE=__esmMin(()=>{aE=`https://registry.npmjs.org/`,PackageNotFoundError=class extends Error{name;url;constructor(n,a){super(`Package not found in registry: ${n} (${a})`),this.name=n,this.url=a,this.name=`PackageNotFoundError`}},IntegrityError=class extends Error{url;integrity;constructor(n,a){super(`Tarball integrity mismatch for ${n} (expected ${a})`),this.url=n,this.integrity=a,this.name=`IntegrityError`}}});function parseTar(n){let a=[],S=null,C=null,N=null,F=0;for(;F+512<=n.length;){let I=n.subarray(F,F+512);if(allZeros(I)){let a=n.subarray(F+512,F+2*512);if(a.length===512&&allZeros(a))break;F+=512;continue}if(!validateChecksum(I))throw new TarParseError(`Bad header checksum at offset ${F} — file is not a valid tar archive`);let H=readString(I,0,100),W=parseOctal(I,100,8),K=parseOctal(I,124,12),q=parseOctal(I,136,12),Y=String.fromCharCode(I[156]||0),X=readString(I,157,100),te=readString(I,257,6),ne=readString(I,345,155),re=readString(I,265,32),ie=readString(I,297,32);F+=512;let ae=n.subarray(F,F+K);if(F+=alignToBlock(K),Y===`x`){S=parsePaxRecords(ae);continue}if(Y===`g`)continue;if(Y===`L`){C=bytesToString(ae).replace(/\0+$/,``);continue}if(Y===`K`){N=bytesToString(ae).replace(/\0+$/,``);continue}let oe=H;te===`ustar`&&ne!==``&&(oe=`${ne}/${H}`),C!==null&&(oe=C,C=null);let Z=X;if(N!==null&&(Z=N,N=null),S!==null){let C=S.get(`path`);C!==void 0&&(oe=C);let N=S.get(`linkpath`);N!==void 0&&(Z=N);let I=S.get(`size`);if(I!==void 0){let C=Number(I);if(Number.isFinite(C)){let N=F-alignToBlock(K),I=n.subarray(N,N+C);F=N+alignToBlock(C),S=null,a.push(buildEntry(oe,Z,Y,W,q,re,ie,I));continue}}S=null}a.push(buildEntry(oe,Z,Y,W,q,re,ie,ae))}return a}function buildEntry(n,a,S,C,N,F,I,H){return{name:n,linkname:a,type:typeflagToType(S,n),mode:C,mtime:N,body:H,uname:F,gname:I}}function typeflagToType(n,a){switch(n){case`0`:case`\0`:case``:return a.endsWith(`/`)?`directory`:`file`;case`1`:return`hardlink`;case`2`:return`symlink`;case`5`:return`directory`;case`x`:return`pax-header`;case`g`:return`pax-global`;case`L`:return`gnu-longname`;case`K`:return`gnu-longlink`;default:return`unknown`}}function parsePaxRecords(n){let a=new Map,S=0;for(;S<n.length;){let C=S;for(;C<n.length&&n[C]!==32;)C++;if(C>=n.length)break;let N=bytesToString(n.subarray(S,C)),F=Number(N);if(!Number.isFinite(F)||F<=0)break;let I=S+F;if(I>n.length)break;let H=bytesToString(n.subarray(C+1,I-1)),W=H.indexOf(`=`);if(W>0){let n=H.slice(0,W),S=H.slice(W+1);a.set(n,S)}S=I}return a}function readString(n,a,S){let C=a,N=a+S;for(;C<N&&n[C]!==0;)C++;return bytesToString(n.subarray(a,C))}function bytesToString(n){return new TextDecoder(`utf-8`,{fatal:!1}).decode(n)}function parseOctal(n,a,S){if(S>0&&n[a]&128){let C=n[a]&127;for(let N=1;N<S;N++)C=C*256+n[a+N];return C}let C=``;for(let N=0;N<S;N++){let S=n[a+N];S===0||S===32||(C+=String.fromCharCode(S))}return C===``?0:parseInt(C,8)}function alignToBlock(n){return Math.ceil(n/512)*512}function allZeros(n){for(let a=0;a<n.length;a++)if(n[a]!==0)return!1;return!0}function validateChecksum(n){let a=parseOctal(n,148,8),S=0,C=0;for(let a=0;a<512;a++){let N=a>=148&&a<156?32:n[a];S+=N,C+=N>127?N-256:N}return a===S||a===C}var TarParseError,sE=__esmMin(()=>{TarParseError=class extends Error{constructor(n){super(n),this.name=`TarParseError`}}});async function extractTarball(n,a,S={}){let C=n instanceof Uint8Array?n:new Uint8Array(n),N=parseTar(S.gzip??(C.length>=2&&C[0]===31&&C[1]===139)?await gunzip(C):C);mkdirSync(a,{recursive:!0});let F=S.strip??1,I=S.preventEscape??!0,H={files:[],directories:[],symlinks:[],skipped:0};for(let n of N){let C=stripComponents(n.name,F);if(C===null||C===``){H.skipped++;continue}let N=Ao(a,C);if(I&&!isInside(N,a))throw Error(`tar: refusing to extract ${n.name} outside ${a} (resolved=${N})`);if(S.filter&&!S.filter(n,N)){H.skipped++;continue}if(n.type===`directory`){mkdirSync(N,{recursive:!0}),H.directories.push(N);continue}if(n.type===`file`){mkdirSync(Io(N),{recursive:!0}),writeFileSync(N,n.body);let a=S.chmod?.(n,N)??n.mode&511;if(a>0)try{chmodSync(N,a)}catch{}H.files.push(N);continue}if(n.type===`symlink`){mkdirSync(Io(N),{recursive:!0});try{symlinkSync(n.linkname,N),H.symlinks.push(N)}catch{writeFileSync(N,n.linkname),H.files.push(N)}continue}H.skipped++}return H}async function gunzip(n){let a=globalThis.DecompressionStream;if(typeof a!=`function`)throw Error(`@gjsify/tar: globalThis.DecompressionStream is not available — import '@gjsify/compression-streams/register' on GJS to register it`);let S=new Blob([new Uint8Array(n)]).stream().pipeThrough(new a(`gzip`)),C=[],N=0,F=S.getReader();for(;;){let{value:n,done:a}=await F.read();if(a)break;let S=n instanceof Uint8Array?n:new Uint8Array(n);C.push(S),N+=S.length}let I=new Uint8Array(N),H=0;for(let n of C)I.set(n,H),H+=n.length;return I}function stripComponents(n,a){if(a<=0)return n;let S=n.split(`/`).filter(n=>n!==``);return S.length<=a?null:S.slice(a).join(`/`)}function isInside(n,a){let S=Po(a,n);return S!==``&&!S.startsWith(`..`)&&!Mo(S)}var cE=__esmMin(()=>{sE(),Fs(),Wo()}),lE=__esmMin(()=>{cE()}),uE=__exportAll$3({installPackagesNative:()=>installPackagesNative});async function installPackagesNative(n){if(n.specs.length===0)throw Error(`installPackagesNative: empty specs list`);mkdirSync(n.prefix,{recursive:!0});let a=await loadNpmrc(n),S=makeLogger(n.verbose??!1),C=No(n.prefix,fE),N=readLockfile(C),F;if(n.frozen){if(!N)throw Error(`install: --immutable requires ${fE} at ${n.prefix} — none found. Run \`gjsify install\` (without --immutable) to generate one and commit it.`);let a=describeLockfileDrift(N,n.specs);if(a)throw Error(`install: --immutable but ${C} is stale.\n${a}\nRe-run \`gjsify install\` (without --immutable) to refresh the lockfile.`);S(`install: --immutable, using lockfile (%d package(s))`,Object.keys(N.packages).length),F=lockfileToNodes(N)}else N&&lockfileMatchesRequest(N,n.specs)?(S(`install: using lockfile (%d package(s))`,Object.keys(N.packages).length),F=lockfileToNodes(N)):(S(`install: resolving %d top-level spec(s) → %s`,n.specs.length,n.prefix),F=await resolveDeps(n.specs,a,S,n.overrides),n.lockfile&&(writeLockfile(C,n.specs,F),S(`install: wrote %s (%d entries)`,fE,F.length)));return S(`install: downloading %d tarball(s)`,F.length),await downloadAndExtractAll(F,n.prefix,a,S),await linkBins(F,n.prefix,S),S(`install: done`),topLevelResolutions(n.specs,F)}function topLevelResolutions(n,a){let S=new Map;for(let n of a)n.installPath===`node_modules/${n.name}`&&S.set(n.name,n);let C=[];for(let a of n){let n=parseSpecName(a),N=S.get(n);N&&C.push({name:N.name,version:N.version})}return C}function parseSpecName(n){if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a===-1)return n;let S=n.indexOf(`@`,a+1);return S===-1?n:n.slice(0,S)}let a=n.indexOf(`@`);return a===-1?n:n.slice(0,a)}async function resolveDeps(n,a,S,C){let applyOverride=(n,a)=>{if(!C)return a;let N=C[n];return typeof N!=`string`||N.length===0||N===a?a:(S(`install: override %s %s → %s`,n,a,N),N)},N=new Map,fetchPkg=n=>{let S=N.get(n);if(S)return S;let C=fetchPackument(n,{npmrc:a});return N.set(n,C),C},F=new Map,I=new Map,H=n.map(parseSpec).map(n=>({from:null,name:n.name,range:applyOverride(n.name,n.range),required:!0}));for(;H.length>0;){let n=H.shift(),a=findVisible(n.from,n.name,F);if(a&&satisfiesRange(a.version,n.range))continue;let C=null;try{let a=await fetchPkg(n.name);if(C=pickVersion(a,n.range),!C){if(!n.required)continue;throw Error(`No version of ${n.name} satisfies ${n.range}`)}let N=a.versions[C];if(!N)throw Error(`Packument for ${n.name} promised ${C} but no entry exists`);let W=decidePlacement(n.from,n.name,C,I),K={name:n.name,version:C,tarballUrl:N.dist.tarball,integrity:N.dist.integrity,installPath:W,dependencies:N.dependencies??{},optionalDependencies:N.optionalDependencies??{},bin:N.bin};F.set(W,K),W===`node_modules/${n.name}`&&I.set(n.name,K),S(`resolve: %s@%s ← %s (at %s)`,n.name,C,n.range,W);for(let[n,a]of Object.entries(K.dependencies))H.push({from:W,name:n,range:applyOverride(n,a),required:!0});for(let[n,a]of Object.entries(K.optionalDependencies))H.push({from:W,name:n,range:applyOverride(n,a),required:!1})}catch(a){if(!n.required){S(`resolve: optional dep %s@%s skipped (%s)`,n.name,n.range,a.message);continue}throw a}}return Array.from(F.values())}function findVisible(n,a,S){let C=[];if(n!==null){C.push(`${n}/node_modules/${a}`);let S=n;for(;;){let n=S.lastIndexOf(`/node_modules/`);if(n<0||(S=S.slice(0,n),C.push(`${S}/node_modules/${a}`),S===``))break}}C.push(`node_modules/${a}`);for(let n of C){let a=S.get(n);if(a)return a}return null}function decidePlacement(n,a,S,C){let N=C.get(a);return!N||N.version===S||n===null?`node_modules/${a}`:`${n}/node_modules/${a}`}function satisfiesRange(n,a){try{return satisfies(n,new rE(a))}catch{return!1}}function readLockfile(n){if(!existsSync(n))return null;try{let a=JSON.parse(readFileSync(n,`utf-8`));return a.lockfileVersion!==pE||!a.packages||typeof a.packages!=`object`?null:a}catch{return null}}function writeLockfile(n,a,S){let C={},N=[...S].sort((n,a)=>n.installPath<a.installPath?-1:+(n.installPath>a.installPath));for(let n of N)C[n.installPath]={version:n.version,resolved:n.tarballUrl,integrity:n.integrity,dependencies:Object.keys(n.dependencies).length>0?n.dependencies:void 0,bin:n.bin};let F={lockfileVersion:pE,requested:[...a],packages:C};writeFileSync(n,JSON.stringify(F,null,2)+`
|
|
783
783
|
`)}function lockfileToNodes(n){return Object.entries(n.packages).map(([n,a])=>({name:nameFromInstallPath(n),version:a.version,tarballUrl:a.resolved,integrity:a.integrity,installPath:n,dependencies:a.dependencies??{},optionalDependencies:{},bin:a.bin}))}function nameFromInstallPath(n){let a=n.lastIndexOf(`/node_modules/`);return a<0?n.replace(/^node_modules\//,``):n.slice(a+14)}function lockfileMatchesRequest(n,a){if(n.requested.length!==a.length)return!1;let S=[...n.requested].sort(),C=[...a].sort();return S.every((n,a)=>n===C[a])}function describeLockfileDrift(n,a){let S=new Set(n.requested),C=new Set(a),N=[],F=[];for(let n of C)S.has(n)||N.push(n);for(let n of S)C.has(n)||F.push(n);if(N.length===0&&F.length===0)return null;let I=[];return N.length>0&&I.push(` + ${N.sort().join(`
|
|
784
784
|
+ `)}`),F.length>0&&I.push(` - ${F.sort().join(`
|
|
785
785
|
- `)}`),I.join(`
|
|
786
786
|
`)}function parseSpec(n){if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a<0)throw Error(`Invalid spec (scoped name without slash): ${n}`);let S=n.indexOf(`@`,a);return S<0?{name:n,range:`*`}:{name:n.slice(0,S),range:n.slice(S+1)||`*`}}let a=n.indexOf(`@`);return a<0?{name:n,range:`*`}:{name:n.slice(0,a),range:n.slice(a+1)||`*`}}function pickVersion(n,a){if(n[`dist-tags`][a])return n[`dist-tags`][a];let S;try{S=new rE(a)}catch{throw Error(`Invalid version range for ${n.name}: ${a}`)}return maxSatisfying(Object.keys(n.versions).filter(n=>{try{return new SemVer(n),!0}catch{return!1}}),S)}async function downloadAndExtractAll(n,a,S,C){let N=[...n].sort((n,a)=>depth(n.installPath)-depth(a.installPath)||(n.installPath<a.installPath?-1:1)),F=[],I=Math.max(1,Math.min(dE,N.length)),H=0,W=N.findIndex(n=>depth(n.installPath)>1),K=W<0?N.length:W;for(;H<K;){let n=N[H++];if(!n)break;await extractOne(n,a,S,C)}for(let n=0;n<I;n++)F.push((async()=>{for(;;){let n=H++;if(n>=N.length)return;let F=N[n];if(!F)return;await extractOne(F,a,S,C)}})());await Promise.all(F)}async function extractOne(n,a,S,C){let N=No(a,n.installPath);C(`fetch: %s@%s ← %s (→ %s)`,n.name,n.version,n.tarballUrl,n.installPath);let F=await fetchTarball(n.tarballUrl,{npmrc:S,integrity:n.integrity});rmSync(N,{recursive:!0,force:!0}),mkdirSync(N,{recursive:!0}),await extractTarball(F,N)}function depth(n){return n.split(`/node_modules/`).length}async function linkBins(n,a,S){let C=No(a,`node_modules`,`.bin`),N=0;for(let S of n){if(!S.bin||depth(S.installPath)!==1)continue;let n=normalizeBin$1(S.name,S.bin);if(n.size!==0){mkdirSync(C,{recursive:!0});for(let[F,I]of n){let n=No(a,S.installPath,I);if(!existsSync(n))continue;try{chmodSync(n,493)}catch{}let H=No(C,F);rmSync(H,{force:!0});let W=Po(C,n);try{symlinkSync(W,H),N++}catch{copyFileSync(n,H),chmodSync(H,493),N++}}}}N>0&&S(`bin: linked %d entry(ies) under .bin/`,N)}function normalizeBin$1(n,a){let S=new Map;if(typeof a==`string`){let C=n.startsWith(`@`)?n.slice(n.indexOf(`/`)+1):n;return S.set(C,a),S}for(let[n,C]of Object.entries(a))S.set(n,C);return S}async function loadNpmrc(n){let a=homedir(),S={registry:n.registry??aE,scopes:{},authTokens:{},basicAuth:{}};for(let C of[No(a,`.npmrc`),No(n.prefix,`.npmrc`)])if(existsSync(C))try{let n=parseNpmrc(readFileSync(C,`utf-8`));S={...S,...n,scopes:{...S.scopes,...n.scopes}}}catch(n){ze.warn(`gjsify install: ignoring malformed ${C}: ${n.message}`)}let C=process.env.npm_config_registry;return C&&(S.registry=C),n.registry&&(S.registry=n.registry),S}function makeLogger(n){return n?(n,...a)=>{let S=n.replace(/%s|%d/g,()=>String(a.shift()));process.stderr.write(`gjsify install: ${S}\n`)}:()=>{}}var dE,fE,pE,mE=__esmMin(()=>{Be(),Fs(),Wo(),rp(),iE(),oE(),lE(),dE=Number(process.env.GJSIFY_INSTALL_CONCURRENCY??`8`)||8,fE=`gjsify-lock.json`,pE=2,__name$1(normalizeBin$1,`normalizeBin`)});px(),Fs(),Wo();const hE=process.env.GJSIFY_INSTALL_BACKEND??`native`;async function installPackages(n){if(hE===`npm`)return await installViaNpm(n),{installed:[]};let{installPackagesNative:a}=await Promise.resolve().then(()=>(mE(),uE));return{installed:await a(n)}}async function installViaNpm({prefix:n,specs:a,verbose:S,registry:C}){if(a.length===0)throw Error(`installPackages: empty specs list`);writeFileSync(No(n,`package.json`),JSON.stringify({name:`gjsify-dlx-cache`,version:`0.0.0`,private:!0},null,2)),C&&writeFileSync(No(n,`.npmrc`),`registry=${C}\n`);let N=[`install`,`--no-package-lock`,`--no-audit`,`--no-fund`,`--prefix`,n,...S?[`--loglevel`,`verbose`]:[`--loglevel`,`warn`],...a];await new Promise((n,a)=>{let S=spawn(`npm`,N,{stdio:`inherit`});S.on(`close`,S=>{S===0?n():a(Error(`npm install exited with code ${S}`))}),S.on(`error`,n=>{let S=n.code===`ENOENT`?`npm not found on PATH — install Node.js or set GJSIFY_INSTALL_BACKEND=native (not yet supported)`:`npm install failed: ${n.message}`;a(Error(S))})})}Be(),Fs(),Wo();const gE={command:`dlx <spec> [binOrArg] [extraArgs..]`,description:`Run the GJS bundle of an npm-published package without installing it locally.`,builder:n=>n.positional(`spec`,{description:"Package spec (`name`, `name@version`, `@scope/name@spec`, or local path).",type:`string`,demandOption:!0}).positional(`binOrArg`,{description:"Optional bin name when the package defines `gjsify.bin` with multiple entries; otherwise treated as the first argument forwarded to the bundle.",type:`string`}).positional(`extraArgs`,{description:"Extra args forwarded to `gjs -m <bundle>`.",type:`string`,array:!0}).option(`cache-max-age`,{description:`Cache TTL in minutes. Defaults to 7 days. Use 0 to bypass cache.`,type:`number`,default:1440*7}).option(`reinstall`,{description:`Bypass the cache for this run (alias for --cache-max-age=0).`,type:`boolean`,default:!1}).option(`frozen`,{description:`Use the project-local gjsify-lock.json verbatim — fail if missing or stale (no resolver pass).`,type:`boolean`,default:!1}).option(`verbose`,{description:`Verbose logging (passes --loglevel verbose to npm).`,type:`boolean`,default:!1}).option(`registry`,{description:`Registry URL override.`,type:`string`}),handler:async n=>{let a=parseSpec$1(n.spec),S=n.reinstall?0:n[`cache-max-age`],{pkgDir:C,cachedPkgName:N}=await ensurePkgDir(a,{verbose:n.verbose,registry:n.registry,cacheMaxAge:S,frozen:n.frozen}),{binName:F,extraArgs:I}=splitBinAndArgs(C,n.binOrArg,n.extraArgs??[]),H=resolveGjsEntry(C,F);H.fromFallback&&ze.warn(`[gjsify dlx] package "${N??a.kind}" has no \`gjsify\` field — falling back to package.json#main. Add \`gjsify.main\` to silence.`),await runGjsBundle(H.bundlePath,I)}};async function ensurePkgDir(n,a){if(n.kind===`local`)return{pkgDir:n.path,cachedPkgName:null};let S=cacheDirFor(createCacheKey({packages:[n.spec]})),C=a.cacheMaxAge>0?getValidCachedPkg(S,a.cacheMaxAge):void 0;if(C)return{pkgDir:resolveInstalledPkgDir(C,n.name),cachedPkgName:n.name};let N=makePrepareDir(S);return await installPackages({prefix:N,specs:[n.spec],verbose:a.verbose,registry:a.registry,lockfile:!0,frozen:a.frozen}),{pkgDir:resolveInstalledPkgDir(symlinkSwap(S,N),n.name),cachedPkgName:n.name}}function splitBinAndArgs(n,a,S){if(!a)return{binName:null,extraArgs:S};let C=No(n,`package.json`);if(existsSync(C))try{let n=JSON.parse(readFileSync(C,`utf-8`)).gjsify?.bin;if(n&&Object.prototype.hasOwnProperty.call(n,a))return{binName:a,extraArgs:S}}catch{}return{binName:null,extraArgs:[a,...S]}}Fs(),rp(),Wo();function defaultGlobalLayout(){let n=process.env.GJSIFY_GLOBAL_PREFIX,a=process.env.GJSIFY_GLOBAL_BIN_DIR,S=homedir(),C=process.env.XDG_DATA_HOME??No(S,`.local`,`share`);return{prefix:n??No(C,`gjsify`,`global`),binDir:a??No(S,`.local`,`bin`)}}function linkGlobalBins(n,a){mkdirSync(a.binDir,{recursive:!0});let S=[];for(let C of n){let n=No(a.prefix,`node_modules`,C),N=No(n,`package.json`);if(!existsSync(N))continue;let F=pickBinMap(C,readJson(N));if(!(!F||F.size===0))for(let[C,N]of F){let F=No(n,N);if(!existsSync(F))continue;try{chmodSync(F,493)}catch{}let I=No(a.binDir,C);rmSync(I,{force:!0}),writeFileSync(I,`#!/bin/sh\nexec ${shQuote(F)} "$@"\n`),chmodSync(I,493),S.push({name:C,target:F,link:I})}}return S}function shQuote(n){return`'${n.replace(/'/g,`'\\''`)}'`}function pickBinMap(n,a){let S=a.gjsify;if(S?.bin!==void 0)return normalizeBin(n,S.bin);let C=a.bin;return C===void 0?null:normalizeBin(n,C)}function normalizeBin(n,a){let S=new Map;if(typeof a==`string`){let C=n.startsWith(`@`)?n.slice(n.indexOf(`/`)+1):n;return S.set(C,a),S}for(let[n,C]of Object.entries(a))S.set(n,C);return S}function readJson(n){return JSON.parse(readFileSync(n,`utf-8`))}function binDirOnPath(n){let a=process.env.PATH??``,S=process.platform===`win32`?`;`:`:`,C=Ao(n);return a.split(S).some(n=>n&&Ao(n)===C)}function specToPackageName(n){if(n.startsWith(`@`)){let a=n.indexOf(`/`);if(a<0)return n;let S=n.indexOf(`@`,a);return S<0?n:n.slice(0,S)}let a=n.indexOf(`@`);return a<0?n:n.slice(0,a)}Be(),Fs(),Wo(),px();const _E={command:`install [packages..]`,description:`Install npm dependencies in the current project (or globally with -g), then run gjsify-aware post-checks.`,builder:n=>n.positional(`packages`,{description:`Optional package specs. With none, runs a full project install.`,type:`string`,array:!0}).option(`global`,{description:`Install into the user-global XDG location and symlink bins into ~/.local/bin.`,type:`boolean`,alias:`g`,default:!1}).option(`save-dev`,{type:`boolean`,alias:`D`}).option(`save-peer`,{type:`boolean`}).option(`save-optional`,{type:`boolean`,alias:`O`}).option(`immutable`,{description:`CI mode: install strictly from gjsify-lock.json, fail if the lockfile is missing or stale. Equivalent to yarn --immutable / npm ci --frozen-lockfile.`,type:`boolean`,default:!1}).option(`verbose`,{description:`Verbose install logging.`,type:`boolean`,default:!1}),handler:async n=>{if(n.immutable&&(n.packages&&n.packages.length>0&&(ze.error(`gjsify install --immutable does not accept package arguments. Remove the package names or drop --immutable.`),process.exit(1)),n.global&&(ze.error(`gjsify install --immutable is incompatible with --global.`),process.exit(1))),n.global){(!n.packages||n.packages.length===0)&&(ze.error(`gjsify install --global requires at least one <pkg> argument.`),process.exit(1));for(let a of[`save-dev`,`save-peer`,`save-optional`])n[a]&&ze.warn(`gjsify install --global ignores --${a}: global installs do not modify a project package.json.`);await installGlobalAndLink(n.packages,{verbose:n.verbose});return}if(process.env.GJSIFY_INSTALL_BACKEND===`npm`){await projectInstallViaNpm(n),await runPostInstallChecks();return}await projectInstallNative(n),await runPostInstallChecks()}};function isWorkspaceRoot(n){let a=readPackageJson$2(No(n,`package.json`));return a?a.workspaces!==void 0:!1}function depKindFromArgs(n){return n[`save-dev`]?`devDependencies`:n[`save-peer`]?`peerDependencies`:n[`save-optional`]?`optionalDependencies`:`dependencies`}async function projectInstallNative(n){let a=process.cwd(),S=No(a,`package.json`);if(existsSync(No(a,`.pnp.cjs`))||existsSync(No(a,`.pnp.loader.mjs`)))throw Error("gjsify install: detected Yarn PnP (.pnp.cjs) — native install is not PnP-aware yet. Use `yarn install` or set GJSIFY_INSTALL_BACKEND=npm.");if((!n.packages||n.packages.length===0)&&isWorkspaceRoot(a)){await workspaceInstall(a,n);return}let C,N=readPackageJson$2(S),F=N?projectSpecsFromPackageJson(N):[];if(n.packages&&n.packages.length>0){let a=new Set(n.packages.map(n=>parseSpec$2(n).name));C=[...F.filter(n=>!a.has(parseSpec$2(n).name)),...n.packages]}else{if(!N)throw Error(`gjsify install: no package.json in ${a}`);if(C=F,C.length===0){ze.log(`gjsify install: no dependencies declared in package.json — nothing to do.`);return}}mkdirSync(a,{recursive:!0});let I=await installPackages({prefix:a,specs:C,verbose:n.verbose,lockfile:!n.immutable,frozen:n.immutable});if(n.packages&&n.packages.length>0&&N){let C=depKindFromArgs(n);for(let a of n.packages){let{name:n,range:S}=parseSpec$2(a),F=I.installed.find(a=>a.name===n);addDependencyEntry(N,n,S??(F?defaultRangeFromVersion(F.version):`latest`),C)}writePackageJson(S,N),n.immutable||syncLockfileRequested(a,projectSpecsFromPackageJson(N))}}function syncLockfileRequested(n,a){let S=No(n,`gjsify-lock.json`);if(existsSync(S))try{let n=JSON.parse(readFileSync(S,`utf-8`)),C=[...a].sort(),N=[...n.requested??[]].sort();if(C.length===N.length&&C.every((n,a)=>n===N[a]))return;n.requested=a,writeFileSync(S,JSON.stringify(n,null,2)+`
|
|
787
|
-
`)}catch{}}async function workspaceInstall(n,a){let S=discoverWorkspaces(n,{includeRoot:!0});if(S.length===0)throw Error(`gjsify install: ${n} has a "workspaces" field but no workspaces were discovered`);let C=new Map(S.map(n=>[n.name,n])),N=new Set,F=[];for(let n of S){let a=n.manifest;for(let S of[`dependencies`,`devDependencies`,`optionalDependencies`]){let I=a[S];if(I){for(let[a,S]of Object.entries(I))if(typeof S==`string`){if(S.startsWith(`workspace:`)){let N=C.get(a);if(!N)throw Error(`gjsify install: ${n.name} declares "${a}: ${S}" but no workspace with that name exists`);F.push({fromWorkspaceName:n.name,depName:a,targetLocation:N.location});continue}/^(link|file|portal|git\+|https?):/.test(S)||N.add(`${a}@${S}`)}}}}ze.log(`gjsify install: ${S.length} workspace(s), ${N.size} external dep spec(s), ${F.length} workspace symlink(s)`),N.size>0?await installPackages({prefix:n,specs:[...N],verbose:a.verbose,lockfile:!a.immutable,frozen:a.immutable}):a.verbose&&ze.log(`gjsify install: no external deps to fetch`);for(let n of F){let a=C.get(n.fromWorkspaceName);if(!a)continue;let S=No(a.location,`node_modules`,n.depName);mkdirSync(Io(S),{recursive:!0});try{let n=lstatSync(S);n.isSymbolicLink()||n.isFile()?rmSync(S,{force:!0}):n.isDirectory()&&rmSync(S,{recursive:!0,force:!0})}catch{}symlinkSync(Po(Io(S),n.targetLocation),S)}F.length>0&&ze.log(`gjsify install: wired ${F.length} workspace symlink(s)`);let
|
|
787
|
+
`)}catch{}}async function workspaceInstall(n,a){let S=discoverWorkspaces(n,{includeRoot:!0});if(S.length===0)throw Error(`gjsify install: ${n} has a "workspaces" field but no workspaces were discovered`);let C=new Map(S.map(n=>[n.name,n])),N=new Set,F=[];for(let n of S){let a=n.manifest;for(let S of[`dependencies`,`devDependencies`,`optionalDependencies`]){let I=a[S];if(I){for(let[a,S]of Object.entries(I))if(typeof S==`string`){if(S.startsWith(`workspace:`)){let N=C.get(a);if(!N)throw Error(`gjsify install: ${n.name} declares "${a}: ${S}" but no workspace with that name exists`);F.push({fromWorkspaceName:n.name,depName:a,targetLocation:N.location});continue}/^(link|file|portal|git\+|https?):/.test(S)||N.add(`${a}@${S}`)}}}}ze.log(`gjsify install: ${S.length} workspace(s), ${N.size} external dep spec(s), ${F.length} workspace symlink(s)`);let I=S.find(a=>a.location===n)?.manifest,H=extractOverrides(I);N.size>0?await installPackages({prefix:n,specs:[...N],verbose:a.verbose,lockfile:!a.immutable,frozen:a.immutable,overrides:H}):a.verbose&&ze.log(`gjsify install: no external deps to fetch`);for(let n of F){let a=C.get(n.fromWorkspaceName);if(!a)continue;let S=No(a.location,`node_modules`,n.depName);mkdirSync(Io(S),{recursive:!0});try{let n=lstatSync(S);n.isSymbolicLink()||n.isFile()?rmSync(S,{force:!0}):n.isDirectory()&&rmSync(S,{recursive:!0,force:!0})}catch{}symlinkSync(Po(Io(S),n.targetLocation),S)}F.length>0&&ze.log(`gjsify install: wired ${F.length} workspace symlink(s)`);let W=No(n,`node_modules`),K=0;for(let a of S){if(a.location===n||!a.name)continue;let S=No(W,a.name),C=!1;try{lstatSync(S),C=!0}catch{}C||(mkdirSync(Io(S),{recursive:!0}),symlinkSync(Po(Io(S),a.location),S),K++)}K>0&&ze.log(`gjsify install: hoisted ${K} workspace(s) to root node_modules/`);let q=No(n,`node_modules`,`.bin`),Y=0;for(let n of S){let a=n.manifest,S=a.gjsify?.bin,C=a.bin,N=mergeWorkspaceBins(n.name,S,C);if(N.size!==0){mkdirSync(q,{recursive:!0});for(let[a,{nodeTarget:S,gjsTarget:C}]of N){let N=No(q,a);try{rmSync(N,{force:!0})}catch{}writeFileSync(N,buildBinShim(n.location,S,C),{mode:493}),chmodSync(N,493),Y++}}}Y>0&&ze.log(`gjsify install: linked ${Y} workspace bin(s) into node_modules/.bin/`)}function extractOverrides(n){if(!n)return;let a={},merge=(n,S)=>{if(n)for(let[C,N]of Object.entries(n)){if(C.startsWith(`_`))continue;if(typeof N!=`string`){ze.warn(`gjsify install: ${S}["${C}"] is not a string — nested override shape isn't supported yet, skipping`);continue}let n=C,F=C.startsWith(`@`)?C.indexOf(`@`,1):C.indexOf(`@`);F>0&&(n=C.slice(0,F)),a[n]=N}};return merge(n.overrides,`overrides`),merge(n.resolutions,`resolutions`),Object.keys(a).length>0?a:void 0}function buildBinShim(n,a,S){let C=a?No(n,a):null,N=S?No(n,S):null;if(C&&N)return`#!/bin/sh\nif [ -f "${C}" ]; then\n exec node "${C}" "$@"\nfi\nexec gjs -m "${N}" "$@"\n`;if(C)return`#!/bin/sh\nexec node "${C}" "$@"\n`;if(N)return`#!/bin/sh\nexec gjs -m "${N}" "$@"\n`;throw Error(`buildBinShim: either nodeTarget or gjsTarget must be provided`)}function mergeWorkspaceBins(n,a,S){let C=new Map,N=n.startsWith(`@`)?n.slice(n.indexOf(`/`)+1):n,get=n=>{let a=C.get(n);return a||(a={},C.set(n,a)),a};if(typeof S==`string`)get(N).nodeTarget=S;else if(S&&typeof S==`object`)for(let[n,a]of Object.entries(S))typeof a==`string`&&a.length>0&&(get(n).nodeTarget=a);if(typeof a==`string`)get(N).gjsTarget=a;else if(a&&typeof a==`object`)for(let[n,S]of Object.entries(a))typeof S==`string`&&S.length>0&&(get(n).gjsTarget=S);return C}async function projectInstallViaNpm(n){let a=[`install`];n[`save-dev`]&&a.push(`--save-dev`),n[`save-peer`]&&a.push(`--save-peer`),n[`save-optional`]&&a.push(`--save-optional`),n.verbose&&a.push(`--loglevel`,`verbose`),n.packages&&n.packages.length>0&&a.push(...n.packages),await spawnNpm(a)}async function spawnNpm(n){return new Promise((a,S)=>{let C=spawn(`npm`,n,{stdio:`inherit`});C.on(`close`,n=>{n===0?a():S(Error(`npm install exited with code ${n}`))}),C.on(`error`,n=>{let a=n.code===`ENOENT`?`npm not found on PATH — install Node.js first.`:`npm install failed: ${n.message}`;S(Error(a))})}).catch(n=>{ze.error(n.message),process.exit(1)})}async function installGlobalAndLink(n,a){let S=defaultGlobalLayout();mkdirSync(S.prefix,{recursive:!0}),ze.log(`gjsify install --global → ${S.prefix}`),ze.log(` bins → ${S.binDir}`),await installPackages({prefix:S.prefix,specs:n,verbose:a.verbose});let C=linkGlobalBins(n.map(specToPackageName),S);if(C.length===0)ze.warn("\nNo bins declared (neither `gjsify.bin` nor `bin` in package.json) — nothing was symlinked.");else{ze.log(`\nLinked ${C.length} bin(s):`);for(let n of C)ze.log(` • ${n.link} → ${n.target}`)}C.length>0&&!binDirOnPath(S.binDir)&&ze.warn(`\nNote: ${S.binDir} is not on your PATH.\nAdd it to your shell rc file:\n export PATH="${S.binDir}:$PATH"`)}async function runPostInstallChecks(){ze.log(`
|
|
788
788
|
--- gjsify post-install checks ---`);let n=runMinimalChecks().filter(n=>!n.found&&n.severity===`required`);if(n.length>0){ze.warn(`Missing required system dependencies:
|
|
789
789
|
`);for(let a of n)ze.warn(` ✗ ${a.name}`);let a=buildInstallCommand(detectPackageManager$2(),n);a&&ze.warn(`\nInstall with:\n ${a}`)}else ze.log(`System dependencies OK.`);let a=detectNativePackages(process.cwd());if(a.length>0){ze.log(`\nDetected ${a.length} @gjsify/* package(s) with native prebuilds:`);for(let n of a)ze.log(` • ${n.name}`);ze.log("\nUse `gjsify run <bundle>` to launch with LD_LIBRARY_PATH/GI_TYPELIB_PATH set.")}}Be(),px(),rp();const vE={command:`foreach [script] [args..]`,description:"Run a workspace script across all (or filtered) workspaces. Drop-in for `yarn workspaces foreach`: -A/--all, -p/--parallel, -t/--topological, --include, --exclude, --no-private. Pass --exec to run an arbitrary command instead of a script.",builder:n=>n.positional(`script`,{description:"Script name to run in each workspace (`run <name>`-equivalent). With --exec, the command to run instead.",type:`string`}).positional(`args`,{description:`Extra arguments forwarded to each child invocation.`,type:`string`,array:!0}).option(`all`,{description:"Include workspaces declared as `private: true`.",type:`boolean`,alias:`A`,default:!1}).option(`parallel`,{description:`Run workspaces in parallel (capped by --jobs).`,type:`boolean`,alias:`p`,default:!1}).option(`topological`,{description:`Wait for each workspace's deps to finish before starting it (production deps only).`,type:`boolean`,alias:`t`,default:!1}).option(`topological-dev`,{description:`Like --topological but also respects devDependencies (often cyclic — use sparingly).`,type:`boolean`,default:!1}).option(`include`,{description:`Glob pattern to include workspaces by name (repeatable).`,type:`string`,array:!0}).option(`exclude`,{description:`Glob pattern to exclude workspaces by name (repeatable).`,type:`string`,array:!0}).option(`private`,{description:`Include private workspaces (default true). Pass --no-private to skip them.`,type:`boolean`,default:!0}).option(`verbose`,{description:`Echo every spawned command before running it.`,type:`boolean`,alias:`v`,default:!1}).option(`jobs`,{description:`Maximum concurrent workspaces in --parallel mode (default: cpu count).`,type:`number`,alias:`j`}).option(`exec`,{description:"Treat <script> [args..] as an arbitrary command (yarn `workspaces foreach exec`-equivalent) instead of a package.json script lookup. Workspace filtering by script presence is skipped. Use `-- <cmd> <args...>` to pass flags to the command without yargs intercepting them.",type:`boolean`,default:!1}).parserConfiguration({"populate--":!0}),handler:async n=>{let a=discoverWorkspaces(findWorkspaceRoot(process.cwd())??process.cwd()),S=n.exec===!0,C=n.script,N=n.args??[];if(S){let a=(n[`--`]??[]).filter(n=>typeof n==`string`);a.length>0&&(C?N=[...N,...a]:(C=a[0],N=[...N,...a.slice(1)])),C||(ze.error("gjsify foreach --exec: missing command. Pass it after `--`, e.g. `gjsify foreach --exec -- npm publish --tag latest`."),process.exit(1))}let F=filterWorkspaces(a,{include:n.include,exclude:n.exclude,noPrivate:n.private===!1});if(!S){C||(ze.error(`gjsify foreach: missing <script> positional. Pass --exec to run an arbitrary command instead.`),process.exit(1));let n=C;F=F.filter(a=>typeof(a.manifest.scripts??{})[n]==`string`)}if(F.length===0){ze.log(`gjsify foreach: no workspaces match (${S?`exec`:`script`}="${C}", include=${JSON.stringify(n.include??[])}, exclude=${JSON.stringify(n.exclude??[])})`);return}(n.topological||n[`topological-dev`])&&(F=topologicalSort(buildDependencyGraph(F,{includeDev:n[`topological-dev`]===!0})));let I=n.verbose===!0,H=C;try{if(n.parallel&&!n.topological&&!n[`topological-dev`]){let a=n.jobs&&n.jobs>0?n.jobs:cpus().length;await runParallel(F,H,N,a,I,S)}else if(n.parallel){let a=n.jobs&&n.jobs>0?n.jobs:cpus().length;await runTopologicalParallel(F,H,N,a,I,n[`topological-dev`]===!0,S)}else await runSequential(F,H,N,I,S)}catch(n){ze.error(n.message),process.exit(1)}process.exit(0)}};async function runSequential(n,a,S,C,N){for(let F of n)await runOne(F,a,S,!1,C,N)}async function runParallel(n,a,S,C,N,F){let I=0,H=[];for(let W=0;W<C;W++)H.push((async()=>{for(;I<n.length;)await runOne(n[I++],a,S,!0,N,F)})());await Promise.all(H)}async function runTopologicalParallel(n,a,S,C,N,F,I){let H=new Set(n.map(n=>n.name)),W=new Map;for(let a of n){let n=new Set,S=a.manifest;for(let a of[S.dependencies,F?S.devDependencies:void 0,S.optionalDependencies])if(a)for(let[S,C]of Object.entries(a))typeof C==`string`&&C.startsWith(`workspace:`)&&H.has(S)&&n.add(S);W.set(a.name,n)}let K=new Map(n.map(n=>[n.name,n])),q=new Set,Y=0;return new Promise((n,F)=>{let H=null,pump=()=>{if(!H){for(;Y<C;){let C=[...W.entries()].filter(([,n])=>[...n].every(n=>q.has(n))).map(([n])=>n);if(C.length===0)break;let X=C.sort()[0];W.delete(X),Y++,runOne(K.get(X),a,S,!0,N,I).then(()=>{if(Y--,q.add(X),W.size===0&&Y===0){n();return}pump()}).catch(n=>{H=n instanceof Error?n:Error(String(n)),Y===0&&F(H)})}W.size>0&&Y===0&&!H&&F(Error(`gjsify foreach --topological: stuck — workspaces ${[...W.keys()].join(`, `)} have unsatisfied deps in the selected set`))}};pump()})}async function runOne(n,a,S,C,N,F){if(F){N&&ze.error(`[${n.name}] $ ${a} ${S.join(` `)}`),await spawnPrefixed(a,S,n.location,C?`[${n.name}] `:null);return}let I=detectPackageManager$1(),H=I===`gjsify`?[`run`,a,...S]:[`run`,a,...S.length>0?[`--`,...S]:[]];N&&ze.error(`[${n.name}] $ ${I} ${H.join(` `)}`),await spawnPrefixed(I,H,n.location,C?`[${n.name}] `:null)}function detectPackageManager$1(){let n=process.env.npm_config_user_agent??``;return n.startsWith(`yarn/`)?`yarn`:n.startsWith(`gjsify/`)?`gjsify`:`npm`}__name$1(detectPackageManager$1,`detectPackageManager`);function spawnPrefixed(n,a,S,C){return new Promise((N,F)=>{let I=spawn(n,a,{cwd:S,stdio:C?[`ignore`,`pipe`,`pipe`]:`inherit`,env:process.env});C&&I.stdout&&I.stderr&&(prefixLines(I.stdout,process.stdout,C),prefixLines(I.stderr,process.stderr,C)),I.on(`close`,S=>{S===0?N():F(Error(`${n} ${a.join(` `)} exited with code ${S}`))}),I.on(`error`,n=>F(n))})}function prefixLines(n,a,S){let C=``;n.setEncoding(`utf-8`),n.on(`data`,n=>{C+=n;let N;for(;(N=C.indexOf(`
|
|
790
790
|
`))!==-1;)a.write(S+C.slice(0,N+1)),C=C.slice(N+1)}),n.on(`end`,()=>{C.length>0&&a.write(S+C+`
|
package/lib/commands/install.js
CHANGED
|
@@ -248,6 +248,13 @@ async function workspaceInstall(cwd, args) {
|
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
250
|
console.log(`gjsify install: ${workspaces.length} workspace(s), ${externalSpecs.size} external dep spec(s), ${symlinks.length} workspace symlink(s)`);
|
|
251
|
+
// Read top-level package.json's `overrides` (npm-native) or `resolutions`
|
|
252
|
+
// (yarn-native, kept as the existing field name in pre-Phase-D.8 repos).
|
|
253
|
+
// Both are flattened to a name → version map and passed to the install
|
|
254
|
+
// backend. Pattern keys like `typescript@*` are normalised to bare names —
|
|
255
|
+
// we don't yet support per-parent scoping (npm's nested overrides shape).
|
|
256
|
+
const rootManifest = workspaces.find((w) => w.location === cwd)?.manifest;
|
|
257
|
+
const overrides = extractOverrides(rootManifest);
|
|
251
258
|
if (externalSpecs.size > 0) {
|
|
252
259
|
await installPackages({
|
|
253
260
|
prefix: cwd,
|
|
@@ -255,6 +262,7 @@ async function workspaceInstall(cwd, args) {
|
|
|
255
262
|
verbose: args.verbose,
|
|
256
263
|
lockfile: !args.immutable,
|
|
257
264
|
frozen: args.immutable,
|
|
265
|
+
overrides,
|
|
258
266
|
});
|
|
259
267
|
}
|
|
260
268
|
else if (args.verbose) {
|
|
@@ -386,6 +394,51 @@ async function workspaceInstall(cwd, args) {
|
|
|
386
394
|
* different cwds that consumers (`yarn run`, `npm run`, direct PATH
|
|
387
395
|
* invocation) call us from.
|
|
388
396
|
*/
|
|
397
|
+
/**
|
|
398
|
+
* Flatten npm `overrides` or yarn `resolutions` into a bare name → range map.
|
|
399
|
+
*
|
|
400
|
+
* Supports two input shapes:
|
|
401
|
+
*
|
|
402
|
+
* "overrides": { "typescript": "~5.9.2" } (npm)
|
|
403
|
+
* "resolutions": { "typescript@*": "~5.9.2" } (yarn pattern)
|
|
404
|
+
*
|
|
405
|
+
* Pattern keys with a version glob (`name@*`, `name@^x`) are normalised to the
|
|
406
|
+
* bare name — gjsify's resolver doesn't yet support per-incoming-range
|
|
407
|
+
* scoping. Object-valued nested overrides (npm's per-parent shape, e.g.
|
|
408
|
+
* `"foo": { ".": "1.0", "bar": "2.0" }`) are intentionally ignored; they would
|
|
409
|
+
* silently misbehave without per-parent support, so we surface a warning
|
|
410
|
+
* instead of half-applying them.
|
|
411
|
+
*
|
|
412
|
+
* Keys beginning with `_` are skipped (convention for documentation entries
|
|
413
|
+
* like `"_comment_typescript"` used in the wild).
|
|
414
|
+
*/
|
|
415
|
+
function extractOverrides(rootManifest) {
|
|
416
|
+
if (!rootManifest)
|
|
417
|
+
return undefined;
|
|
418
|
+
const out = {};
|
|
419
|
+
const merge = (source, fieldName) => {
|
|
420
|
+
if (!source)
|
|
421
|
+
return;
|
|
422
|
+
for (const [key, value] of Object.entries(source)) {
|
|
423
|
+
if (key.startsWith('_'))
|
|
424
|
+
continue;
|
|
425
|
+
if (typeof value !== 'string') {
|
|
426
|
+
console.warn(`gjsify install: ${fieldName}["${key}"] is not a string — nested override shape isn't supported yet, skipping`);
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
// Normalise pattern keys (`name@*`, `name@^range`) → bare name.
|
|
430
|
+
// For scoped packages preserve the leading `@`.
|
|
431
|
+
let name = key;
|
|
432
|
+
const atIdx = key.startsWith('@') ? key.indexOf('@', 1) : key.indexOf('@');
|
|
433
|
+
if (atIdx > 0)
|
|
434
|
+
name = key.slice(0, atIdx);
|
|
435
|
+
out[name] = value;
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
merge(rootManifest.overrides, 'overrides');
|
|
439
|
+
merge(rootManifest.resolutions, 'resolutions');
|
|
440
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
441
|
+
}
|
|
389
442
|
function buildBinShim(wsLocation, nodeTarget, gjsTarget) {
|
|
390
443
|
const nodeAbs = nodeTarget ? join(wsLocation, nodeTarget) : null;
|
|
391
444
|
const gjsAbs = gjsTarget ? join(wsLocation, gjsTarget) : null;
|
package/lib/commands/run.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// extension, or that resolves to an existing path on disk is treated
|
|
14
14
|
// as a bundle file. Everything else is a script name. Users who want
|
|
15
15
|
// to disambiguate can pass `./<file>` explicitly.
|
|
16
|
-
import {
|
|
16
|
+
import { statSync } from 'node:fs';
|
|
17
17
|
import { delimiter, join, resolve } from 'node:path';
|
|
18
18
|
import { spawn } from 'node:child_process';
|
|
19
19
|
import { runGjsBundle } from '../utils/run-gjs.js';
|
|
@@ -37,7 +37,15 @@ export const runCommand = {
|
|
|
37
37
|
handler: async (args) => {
|
|
38
38
|
const target = args.target;
|
|
39
39
|
const extraArgs = args.args ?? [];
|
|
40
|
-
|
|
40
|
+
// Script lookup wins over file detection. Without this, a bare
|
|
41
|
+
// `gjsify run build` would resolve to a file when a `./build`
|
|
42
|
+
// directory exists in cwd (e.g. meson's build dir from a Vala
|
|
43
|
+
// prebuild) — masking the package.json's `"build": "…"` script.
|
|
44
|
+
// File mode is still entered for explicit path-shaped targets
|
|
45
|
+
// (`./bundle.js`, `dist/x.mjs`, `/abs/path`).
|
|
46
|
+
const pkg = readPackageJson(join(process.cwd(), 'package.json'));
|
|
47
|
+
const hasScript = pkg?.scripts && typeof pkg.scripts[target] === 'string';
|
|
48
|
+
if (!hasScript && looksLikeFile(target)) {
|
|
41
49
|
const file = resolve(target);
|
|
42
50
|
await runGjsBundle(file, extraArgs);
|
|
43
51
|
return;
|
|
@@ -52,7 +60,16 @@ function looksLikeFile(target) {
|
|
|
52
60
|
return true;
|
|
53
61
|
if (/\.(c?js|mjs|cjs|gjs)$/.test(target))
|
|
54
62
|
return true;
|
|
55
|
-
|
|
63
|
+
// Bare names like "build" can collide with build/ directories from
|
|
64
|
+
// meson/vala prebuilds — only treat as a file if it's a regular file,
|
|
65
|
+
// not a directory.
|
|
66
|
+
try {
|
|
67
|
+
const st = statSync(target);
|
|
68
|
+
return st.isFile();
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
56
73
|
}
|
|
57
74
|
/**
|
|
58
75
|
* Run a script declared in the current workspace's `package.json#scripts`.
|
|
@@ -56,7 +56,7 @@ export async function installPackagesNative(opts) {
|
|
|
56
56
|
}
|
|
57
57
|
else {
|
|
58
58
|
log("install: resolving %d top-level spec(s) → %s", opts.specs.length, opts.prefix);
|
|
59
|
-
nodes = await resolveDeps(opts.specs, npmrc, log);
|
|
59
|
+
nodes = await resolveDeps(opts.specs, npmrc, log, opts.overrides);
|
|
60
60
|
if (opts.lockfile) {
|
|
61
61
|
writeLockfile(lockfilePath, opts.specs, nodes);
|
|
62
62
|
log("install: wrote %s (%d entries)", LOCKFILE_NAME, nodes.length);
|
|
@@ -114,7 +114,18 @@ function parseSpecName(spec) {
|
|
|
114
114
|
* the root. Each placement returns a `ResolvedNode` whose `installPath`
|
|
115
115
|
* captures where it lives in the tree.
|
|
116
116
|
*/
|
|
117
|
-
async function resolveDeps(specs, npmrc, log) {
|
|
117
|
+
async function resolveDeps(specs, npmrc, log, overrides) {
|
|
118
|
+
const applyOverride = (name, range) => {
|
|
119
|
+
if (!overrides)
|
|
120
|
+
return range;
|
|
121
|
+
const override = overrides[name];
|
|
122
|
+
if (typeof override !== 'string' || override.length === 0)
|
|
123
|
+
return range;
|
|
124
|
+
if (override === range)
|
|
125
|
+
return range;
|
|
126
|
+
log("install: override %s %s → %s", name, range, override);
|
|
127
|
+
return override;
|
|
128
|
+
};
|
|
118
129
|
const packumentCache = new Map();
|
|
119
130
|
const fetchPkg = (name) => {
|
|
120
131
|
const cached = packumentCache.get(name);
|
|
@@ -131,7 +142,7 @@ async function resolveDeps(specs, npmrc, log) {
|
|
|
131
142
|
const queue = specs.map(parseSpec).map((s) => ({
|
|
132
143
|
from: null,
|
|
133
144
|
name: s.name,
|
|
134
|
-
range: s.range,
|
|
145
|
+
range: applyOverride(s.name, s.range),
|
|
135
146
|
required: true,
|
|
136
147
|
}));
|
|
137
148
|
while (queue.length > 0) {
|
|
@@ -181,10 +192,10 @@ async function resolveDeps(specs, npmrc, log) {
|
|
|
181
192
|
}
|
|
182
193
|
log("resolve: %s@%s ← %s (at %s)", edge.name, version, edge.range, installPath);
|
|
183
194
|
for (const [depName, depRange] of Object.entries(node.dependencies)) {
|
|
184
|
-
queue.push({ from: installPath, name: depName, range: depRange, required: true });
|
|
195
|
+
queue.push({ from: installPath, name: depName, range: applyOverride(depName, depRange), required: true });
|
|
185
196
|
}
|
|
186
197
|
for (const [depName, depRange] of Object.entries(node.optionalDependencies)) {
|
|
187
|
-
queue.push({ from: installPath, name: depName, range: depRange, required: false });
|
|
198
|
+
queue.push({ from: installPath, name: depName, range: applyOverride(depName, depRange), required: false });
|
|
188
199
|
}
|
|
189
200
|
}
|
|
190
201
|
catch (e) {
|
|
@@ -15,6 +15,18 @@ export interface InstallOptions {
|
|
|
15
15
|
lockfile?: boolean;
|
|
16
16
|
/** Use `<prefix>/gjsify-lock.json` as the source of truth — fail if missing. */
|
|
17
17
|
frozen?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Per-package version overrides — `<name> → <range>`. Applied to every
|
|
20
|
+
* edge during dependency resolution, irrespective of the requester.
|
|
21
|
+
* Mirrors npm's top-level `overrides` field and yarn's `resolutions`
|
|
22
|
+
* (the simple, name-only flavour; pattern keys like `typescript@*` are
|
|
23
|
+
* normalised to bare `typescript` by the caller before passing in).
|
|
24
|
+
*
|
|
25
|
+
* Lets a workspace root pin a transitive dep version when the
|
|
26
|
+
* deduplicated tree would otherwise pick a different one — e.g. for
|
|
27
|
+
* forcing `typescript@~5.9` across every `typescript@*` devDep.
|
|
28
|
+
*/
|
|
29
|
+
overrides?: Record<string, string>;
|
|
18
30
|
}
|
|
19
31
|
export interface InstallResult {
|
|
20
32
|
/** Top-level packages that were requested, with the version each
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"description": "CLI for Gjsify",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -37,18 +37,18 @@
|
|
|
37
37
|
"cli"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@gjsify/buffer": "
|
|
41
|
-
"@gjsify/create-app": "
|
|
42
|
-
"@gjsify/node-globals": "
|
|
43
|
-
"@gjsify/node-polyfills": "
|
|
44
|
-
"@gjsify/npm-registry": "
|
|
45
|
-
"@gjsify/resolve-npm": "
|
|
46
|
-
"@gjsify/rolldown-plugin-gjsify": "
|
|
47
|
-
"@gjsify/rolldown-plugin-pnp": "
|
|
48
|
-
"@gjsify/semver": "
|
|
49
|
-
"@gjsify/tar": "
|
|
50
|
-
"@gjsify/web-polyfills": "
|
|
51
|
-
"@gjsify/workspace": "
|
|
40
|
+
"@gjsify/buffer": "^0.4.5",
|
|
41
|
+
"@gjsify/create-app": "^0.4.5",
|
|
42
|
+
"@gjsify/node-globals": "^0.4.5",
|
|
43
|
+
"@gjsify/node-polyfills": "^0.4.5",
|
|
44
|
+
"@gjsify/npm-registry": "^0.4.5",
|
|
45
|
+
"@gjsify/resolve-npm": "^0.4.5",
|
|
46
|
+
"@gjsify/rolldown-plugin-gjsify": "^0.4.5",
|
|
47
|
+
"@gjsify/rolldown-plugin-pnp": "^0.4.5",
|
|
48
|
+
"@gjsify/semver": "^0.4.5",
|
|
49
|
+
"@gjsify/tar": "^0.4.5",
|
|
50
|
+
"@gjsify/web-polyfills": "^0.4.5",
|
|
51
|
+
"@gjsify/workspace": "^0.4.5",
|
|
52
52
|
"cosmiconfig": "^9.0.1",
|
|
53
53
|
"get-tsconfig": "^4.14.0",
|
|
54
54
|
"pkg-types": "^2.3.1",
|
|
@@ -56,12 +56,12 @@
|
|
|
56
56
|
"yargs": "^18.0.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@gjsify/unit": "
|
|
59
|
+
"@gjsify/unit": "^0.4.5",
|
|
60
60
|
"@types/yargs": "^17.0.35",
|
|
61
61
|
"typescript": "^6.0.3"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
|
-
"@gjsify/rolldown-native": "
|
|
64
|
+
"@gjsify/rolldown-native": "^0.4.5"
|
|
65
65
|
},
|
|
66
66
|
"peerDependenciesMeta": {
|
|
67
67
|
"@gjsify/rolldown-native": {
|