@gjsify/cli 0.21.0 → 0.22.0
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
CHANGED
|
@@ -759,7 +759,7 @@ Optional:`);for(let n of H){let a=n.found?`✓`:`⚠`,S=n.version?` (${n.versio
|
|
|
759
759
|
All dependencies found.`);return}C.length>0&&ke.log(`\nMissing required: ${C.map(n=>n.name).join(`, `)}`),N.length>0&&ke.log(`Missing optional: ${N.map(n=>n.name).join(`, `)}`);let W=buildInstallCommand(S,F);W?ke.log(`\nTo install:\n ${W}`):ke.log(`
|
|
760
760
|
No install command available for your package manager. Install manually.`),process.exit(+(C.length>0))}}});function prefixLines(n,a,S,C){let N=``,F=``,emit=n=>{C?F+=n:a.write(n)};return n.setEncoding(`utf-8`),n.on(`data`,n=>{N+=n;let a;for(;(a=N.indexOf(`
|
|
761
761
|
`))!==-1;)emit(S+N.slice(0,a+1)),N=N.slice(a+1)}),n.on(`end`,()=>{N.length>0&&emit(S+N+`
|
|
762
|
-
`)}),()=>{F.length>0&&(a.write(F),F=``)}}var zj=__esmMin(()=>{});function runCheck(n,a){return new Promise(S=>{let C=spawn(`npm`,[`run`,`check`,`--if-present`],{cwd:n.location,stdio:a===null?`inherit`:[`ignore`,`pipe`,`pipe`]}),N=!process.stdout.isTTY,F=[];if(a!==null&&C.stdout&&C.stderr){let n=`[${a}] `;F.push(prefixLines(C.stdout,process.stdout,n,N)),F.push(prefixLines(C.stderr,process.stderr,n,N))}C.on(`close`,n=>{for(let n of F)n();S(n??1)}),C.on(`error`,()=>{for(let n of F)n();S(1)})})}var Bj,Vj=__esmMin(()=>{Ae(),dm(),zj(),Gg(),ms(),Gp(),Wg(),Kg(),Bj={command:`check`,description:"Run `npm run check` (TypeScript type-check) across the current workspace. In a workspace root: walks every package with a `check` script (excludes @girs/*; honours --include/--exclude). In a single package: runs the local `check` script directly. Symmetric peer of `gjsify format` / `lint` / `fix`. (Legacy system-dep `gjsify check` is now `gjsify system-check` — see #254.)",builder:n=>n.option(`include`,{description:`Only run in workspaces matching these glob patterns (repeatable).`,type:`string`,array:!0}).option(`exclude`,{description:`Skip workspaces matching these glob patterns (repeatable). Always excludes @girs/*.`,type:`string`,array:!0}).option(`parallel`,{description:`Run workspace checks in parallel (default). Use --no-parallel to run them sequentially with full per-workspace output.`,type:`boolean`,alias:`p`,default:!0}).option(`jobs`,{description:`Max parallel workers (when --parallel). Default: os.cpus().length.`,type:`number`,alias:`j`}).option(`verbose`,{description:`Log the per-workspace command before spawning.`,type:`boolean`,default:!1}),handler:async n=>{let a=process.cwd(),S=findWorkspaceRoot(a);if(S&&a!==S&&readPackageJson$2(rs(a,`package.json`))?.scripts?.check){n.verbose&&ke.log(`[check] cwd=${a} → npm run check`);let S=spawnSync(`npm`,[`run`,`check`],{cwd:a,stdio:`inherit`});process.exit(S.status??1)}S||(ke.error("gjsify check: no workspace root found from cwd. Run inside a workspace (or a package within one) with `npm run check` defined."),process.exit(1));let C=discoverWorkspaces(S),N=[`@girs/*`,...n.exclude??[]],F=filterWorkspaces(C,{include:n.include,exclude:N}).filter(n=>n.manifest.scripts?.check!==void 0);if(F.length===0&&(ke.error("gjsify check: no workspaces with a `check` script found."),process.exit(1)),n.verbose&&ke.log(`[check] root=${S} workspaces=${F.length} parallel=${n.parallel?`yes`:`no`}`),!n.parallel){let a=0;for(let S of F){n.verbose&&ke.log(`[check] → ${S.name}`);let C=await runCheck(S,null);C!==0&&a===0&&(a=C)}a!==0&&ke.error(`gjsify check: failures in ${F.filter(async n=>await runCheck(n,null)!==0).length}+ workspaces`),process.exit(a)}let I=n.jobs??Math.max(1,cpus().length),H=[],W=0,K=[];for(let n=0;n<I;n++)K.push((async()=>{for(;;){let n=W++;if(n>=F.length)return;let a=F[n],S=await runCheck(a,a.name);S!==0&&H.push({name:a.name,code:S})}})());if(await Promise.all(K),H.length>0){ke.error(`\ngjsify check: ${H.length} of ${F.length} workspace(s) failed:`);for(let n of H)ke.error(` ✗ ${n.name} (exit ${n.code})`);process.exit(1)}n.verbose&&ke.log(`\ngjsify check: ${F.length} workspace(s) green.`),process.exit(0)}}});function manifestPath(){let n=os(fileURLToPath(import.meta.url)),a=[rs(n,`..`,`..`,`showcases.json`),rs(n,`..`,`showcases.json`)];return a.find(n=>existsSync(n))??a[0]}function discoverShowcases(){let n=manifestPath();if(!existsSync(n))return[];let a;try{a=JSON.parse(readFileSync(n,`utf-8`))}catch{return[]}if(!Array.isArray(a.showcases))return[];let S=a.showcases.map(n=>({name:n.name,packageName:n.package,category:n.category,description:n.description??``,needsWebgl:!!n.needsWebgl}));return S.sort((n,a)=>n.category.localeCompare(a.category)||n.name.localeCompare(a.name)),S}function findShowcase(n){return discoverShowcases().find(a=>a.name===n)}var Hj=__esmMin(()=>{Qc(),ms(),mn()});function parseSpec$1(n){if(!n)throw Error(`dlx: empty package spec`);if(n.startsWith(`./`)||n.startsWith(`../`)||ns(n)||existsSync(n))return{kind:`local`,path:es(n)};let a=n,S,C=n.lastIndexOf(`@`);if(C>0&&(a=n.slice(0,C),S=n.slice(C+1)),!Uj.test(a))throw Error(`dlx: invalid package name "${a}"`);return{kind:`registry`,name:a,version:S,spec:n}}var Uj,Wj=__esmMin(()=>{Qc(),ms(),Uj=/^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,__name$1(parseSpec$1,`parseSpec`)});function resolveGjsEntry(n,a){let S=rs(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=es(n,H);if(!existsSync(q))throw Error(`dlx: GJS entry not found: ${q}`);return{bundlePath:q,binName:W,fromFallback:K}}function resolveNodeEntry(n){let a=rs(n,`package.json`);if(!existsSync(a))throw Error(`no package.json found at ${n}`);let S=JSON.parse(readFileSync(a,`utf-8`)),C=S.gjsify?.example?.node;if(C){let a=es(n,C);if(!existsSync(a))throw Error(`declared node entry not found: ${a} (gjsify.example.node)`);return a}let N=S.gjsify?.main??(S.gjsify?.bin?Object.values(S.gjsify.bin)[0]:void 0)??S.main;if(!N)throw Error(`package "${S.name??n}" has no entry to derive a node bundle from — set \`gjsify.example.node\` to its \`--app node\` bundle path.`);let F=N.replace(/\.gjs\.(js|mjs|cjs)$/,``).replace(/\.(js|mjs|cjs)$/,``),I=[`${F}.node.mjs`,`${F}.node.js`,`${F}.node.cjs`];for(let a of I){let S=es(n,a);if(existsSync(S))return S}throw Error(`package "${S.name??n}" has no \`--app node\` bundle — looked for ${I.join(`, `)}.\n Build one (e.g. \`gjsify build src/app.ts --app node --outfile dist/app.node.mjs\`) or set \`gjsify.example.node\` to its path.`)}var Gj=__esmMin(()=>{Qc(),ms()});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=rs(n&&n.length>0?n:rs(homedir(),`.cache`),`gjsify`,`dlx`);return mkdirSync(a,{recursive:!0}),a}function cacheDirFor(n){let a=rs(dlxCacheRoot(),n);return mkdirSync(a,{recursive:!0}),a}function makePrepareDir(n){let a=rs(n,`${Date.now().toString(16)}-${process.pid.toString(16)}`);return mkdirSync(a,{recursive:!0}),a}function getValidCachedPkg(n,a=qj){let S=rs(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*Kj?N:void 0}function symlinkSwap(n,a){let S=rs(n,`pkg`),C=rs(n,`pkg.tmp-${Date.now().toString(16)}-${process.pid.toString(16)}`);symlinkSync(a,C,`dir`);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 es(n,`node_modules`,a)}var Kj,qj,Jj=__esmMin(()=>{oo(),Qc(),Gp(),ms(),Kj=6e4,qj=1440*7});function makeProgressReporter(n={}){if(n.enabled===!1)return Xj;let a=n.stream??process.stderr,S=!!a.isTTY;return n.enabled??!0?S?makeTtyReporter(a):makePlainReporter(a):Xj}function makeTtyReporter(n){let a=0,S=``;function render(C,N=!1){let F=Date.now();!N&&F-a<33&&C===S||(a=F,S=C,n.write(`\r\x1B[2K`+C))}function clearLine(){n.write(`\r\x1B[2K`),S=``}return{beginPhase(a,S){render(formatBar(a,0,S,void 0,n.columns??80),!0)},update(a){render(formatBar(a.phase,a.current,a.total,a.name,n.columns??80))},endPhase(a){let S=Yj[a];clearLine(),n.write(`gjsify install: ${S} done\n`)}}}function makePlainReporter(n){let a=0,S=0;return{beginPhase(C,N){a=Date.now(),S=0,n.write(`gjsify install: ${Yj[C]} ${N} package(s)\n`)},update(C){let N=Date.now();if(N-a<Zj||C.current<=S)return;a=N,S=C.current;let F=C.total>0?Math.round(C.current/C.total*100):0;n.write(`gjsify install: ${Yj[C.phase]} ${C.current}/${C.total} (${F}%)\n`)},endPhase(a){n.write(`gjsify install: ${Yj[a]} done\n`)}}}function formatBar(n,a,S,C,N){let F=Yj[n],I=S>0?Math.min(1,a/S):0,H=`${a}/${S}`,W=`gjsify install: ${F} `,K=` ${H}`+(C?` ${C}`:``),q=Math.max(8,Math.min(40,N-W.length-K.length-4)),Y=Math.round(I*q),X=`█`.repeat(Y)+`░`.repeat(q-Y),te=`${W}[${X}]${K}`;if(te.length>N){let n=te.length-N+1,a=C&&C.length>n?C.slice(0,C.length-n-1)+`…`:``;te=`${W}[${X}] ${H}${a?` `+a:``}`}return te}var Yj,Xj,Zj,Qj=__esmMin(()=>{Yj={resolve:`resolving`,download:`downloading`,extract:`extracting`,link:`linking bins`},Xj={update(){},beginPhase(){},endPhase(){}},Zj=5e3});function parse(n){try{return new SemVer(n)}catch{return null}}function compare(n,a){let S=n instanceof SemVer?n:new SemVer(n),C=a instanceof SemVer?a:new SemVer(a);return S.compare(C)}function satisfies(n,a){let S=a instanceof tM?a:new tM(a),C=n instanceof SemVer?n:parse(String(n));return C?S.test(C):!1}function maxSatisfying(n,a){let S=a instanceof tM?a:new tM(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 $j,eM,SemVer,tM,nM=__esmMin(()=>{$j=/^(0|[1-9]\d*)$/,eM=/^(\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=eM.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=>$j.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}},tM=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$1(C)}return a?.registry?ensureTrailingSlash$1(a.registry):rM}function packumentUrl(n,a){let S=ensureTrailingSlash$1(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 fetchPackumentConditional(n,a={}){let S=packumentUrl(n,a.registry??registryFor(n,a.npmrc)),C=buildHeaders(S,{...a,acceptEncoding:`gzip`});C.accept??=`application/vnd.npm.install-v1+json`,a.ifNoneMatch&&(C[`if-none-match`]=a.ifNoneMatch);let N=await fetchWithRetry(S,{headers:C,signal:a.signal},{fetch:a.fetch,retries:a.retries,retryDelayMs:a.retryDelayMs,timeoutMs:a.timeoutMs,onRetry:a.onRetry});if(N.status===304){try{await N.arrayBuffer()}catch{}return{status:`not-modified`,etag:a.ifNoneMatch}}if(!N.ok)throw N.status===404||N.status===406?new PackageNotFoundError(n,S):Error(`registry GET ${S} -> ${N.status} ${N.statusText}`);let F=N.headers.get(`etag`)??void 0,I=await decodeJsonBody(N);return assertPackument(n,I),{status:`fresh`,packument:I,etag:F}}async function decodeJsonBody(n){return n.json()}async function fetchPackument(n,a={}){let S=await fetchPackumentConditional(n,a);if(!S.packument)throw Error(`registry: ${n} returned 304 Not Modified to an unconditional request`);return S.packument}async function fetchTarball(n,a={}){let S=buildHeaders(n,{...a,acceptEncoding:`identity`});S.accept??=`application/octet-stream`;let C=await fetchWithRetry(n,{headers:S,signal:a.signal},{fetch:a.fetch,retries:a.retries,retryDelayMs:a.retryDelayMs,timeoutMs:a.timeoutMs,onRetry:a.onRetry,retryNotFound:a.retryNotFound??!0});if(!C.ok)throw Error(`tarball GET ${n} -> ${C.status} ${C.statusText}`);let N=new Uint8Array(await C.arrayBuffer());if(a.integrity&&!await verifyIntegrity(N,a.integrity))throw new IntegrityError(n,a.integrity);return N}async function fetchWithRetry(n,a,S){let C=S.fetch??globalThis.fetch;if(!C)throw Error(`@gjsify/npm-registry: globalThis.fetch is missing`);let N=Math.max(0,S.retries??3),F=Math.max(0,S.retryDelayMs??250),I=Math.max(0,S.timeoutMs??3e4),H=S.retryNotFound??!1,W=0,K,q=0;for(;;){if(a.signal?.aborted)throw signalAbortError(a.signal);let Y=I>0?new AbortController:null,X=Y===null?null:setTimeout(()=>Y.abort(Error(`@gjsify/npm-registry: per-request timeout ${I}ms`)),I),te=composeSignals(a.signal,Y?.signal);try{let S=await C(n,{...a,signal:te}),F=isRetryableStatus(S.status)||H&&S.status===404;if(S.ok||!F||W>=N)return S;try{await S.arrayBuffer()}catch{}K=Error(`HTTP ${S.status} ${S.statusText}`)}catch(S){let C=Y!==null&&Y.signal.aborted,F=a.signal?.aborted===!0;if(C&&!F){if(q++,W>=N)throw new RegistryTimeoutError(n,I,q);K=S}else if(F)throw signalAbortError(a.signal);else{if(!isRetryableError(S)||W>=N)throw S;K=S}}finally{X!==null&&clearTimeout(X)}let ne=Math.min(F*2**W,8e3);S.onRetry?.({attempt:W+1,error:K,delayMs:ne}),await delay$1(ne,a.signal),W++}}function composeSignals(n,a){return n?a?AbortSignal.any([n,a]):n:a}function isRetryableStatus(n){return n===408||n===425||n===429||n===500||n===502||n===503||n===504||n===521||n===522||n===524||n===525}function isRetryableError(n){if(n&&typeof n==`object`&&`name`in n&&n.name===`AbortError`)return!1;if(n instanceof TypeError)return!0;if(n&&typeof n==`object`&&`name`in n){let a=n.name;if(a===`FetchError`)return!0;if(a===`AbortError`)return!1}let a=n?.cause;if(a&&typeof a==`object`&&`code`in a){let n=a.code;if(typeof n==`string`)return n===`ECONNRESET`||n===`ECONNREFUSED`||n===`ENETUNREACH`||n===`ENOTFOUND`||n===`ETIMEDOUT`||n===`EAI_AGAIN`||n===`UND_ERR_SOCKET`||n===`UND_ERR_CONNECT_TIMEOUT`}return!1}function delay$1(n,a){return n<=0?Promise.resolve():new Promise((S,C)=>{let N=setTimeout(()=>{a?.removeEventListener?.(`abort`,onAbort),S()},n),onAbort=()=>{clearTimeout(N),C(signalAbortError(a))};if(a?.aborted){clearTimeout(N),C(signalAbortError(a));return}a?.addEventListener?.(`abort`,onAbort,{once:!0})})}function signalAbortError(n){let a=n&&`reason`in n?n.reason:void 0;if(a instanceof Error)return a;let S=Error(`Aborted`);return S.name=`AbortError`,S}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:rM,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$1(I);continue}let H=F.match(/^(@[^:]+):registry$/);if(H){a.scopes[H[1]]=ensureTrailingSlash$1(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`,"accept-encoding":a.acceptEncoding??`identity`};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$1(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)}async function whoami(n,a){let S=`${ensureTrailingSlash$1(n)}-/whoami`,C=buildHeaders(S,{npmrc:a});C.accept=`application/json`;let N=globalThis.fetch;if(!N)throw Error(`@gjsify/npm-registry: globalThis.fetch is missing`);let F=await N(S,{method:`GET`,headers:C});if(!F.ok)throw Error(`whoami GET ${S} -> ${F.status} ${F.statusText}`);let I=await F.json();if(I&&typeof I==`object`&&`username`in I){let n=I.username;if(typeof n==`string`&&n.length>0)return{username:n}}return{}}var rM,PackageNotFoundError,IntegrityError,RegistryTimeoutError,iM=__esmMin(()=>{rM=`https://registry.npmjs.org/`,__name$1(delay$1,`delay`),__name$1(ensureTrailingSlash$1,`ensureTrailingSlash`),PackageNotFoundError=class extends Error{constructor(n,a){super(`Package not found in registry: ${n} (${a})`),this.name=n,this.url=a,this.name=`PackageNotFoundError`}},IntegrityError=class extends Error{constructor(n,a){super(`Tarball integrity mismatch for ${n} (expected ${a})`),this.url=n,this.integrity=a,this.name=`IntegrityError`}},RegistryTimeoutError=class extends Error{constructor(n,a,S){let C=Math.round(a/100)/10,N=Math.round(a*S/100)/10;super(`@gjsify/npm-registry: GET ${n} timed out after ${C}s × ${S} attempt(s) (total ~${N}s). This usually means the registry CDN is slow or unreachable.`),this.url=n,this.timeoutMs=a,this.attempts=S,this.name=`RegistryTimeoutError`}}});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,aM=__esmMin(()=>{TarParseError=class extends Error{constructor(n){super(n),this.name=`TarParseError`}}});function createTarball(n){let a=[];for(let S of n){if(`directory`in S&&S.directory===!0){a.push(buildHeader(ensureTrailingSlash(S.name),0,`5`,S.mode??493,S.mtime??0));continue}let n=S,C=typeof n.body==`string`?new TextEncoder().encode(n.body):n.body,N=n.mode??defaultFileMode(C);a.push(buildHeader(n.name,C.byteLength,`0`,N,n.mtime??0)),a.push(C);let F=padTo512(C.byteLength);F>0&&a.push(new Uint8Array(F))}return a.push(new Uint8Array(512*2)),concatChunks(a)}function buildHeader(n,a,S,C,N){let{prefix:F,basename:I}=splitPathForUstar(n),H=new Uint8Array(512);writeAscii(H,I,0,100),writeOctal(H,C&4095,100,7),H[107]=0,writeOctal(H,0,108,7),H[115]=0,writeOctal(H,0,116,7),H[123]=0,writeOctal(H,a,124,11),H[135]=0,writeOctal(H,N,136,11),H[147]=0;for(let n=148;n<156;n++)H[n]=32;H[156]=S.charCodeAt(0),writeAscii(H,`ustar\0`,257,6),writeAscii(H,`00`,263,2),F&&writeAscii(H,F,345,155);let W=0;for(let n=0;n<512;n++)W+=H[n];return writeAscii(H,W.toString(8).padStart(6,`0`),148,6),H[154]=0,H[155]=32,H}function splitPathForUstar(n){if(n.length<=100)return{prefix:``,basename:n};if(n.length>255)throw Error(`createTarball: path too long (${n.length} > 255 chars): ${n}`);for(let a=Math.min(n.length-1,155);a>0;a--)if(n[a]===`/`&&n.length-a-1<=100)return{prefix:n.slice(0,a),basename:n.slice(a+1)};throw Error(`createTarball: cannot split path into ustar prefix+basename (basename slot is 100 chars): ${n}`)}function writeAscii(n,a,S,C){let N=new TextEncoder().encode(a);if(N.length>C)throw Error(`createTarball: field too long (${N.length} > ${C}): "${a}"`);n.set(N,S)}function writeOctal(n,a,S,C){writeAscii(n,a.toString(8).padStart(C,`0`),S,C)}function padTo512(n){let a=n%512;return a===0?0:512-a}function ensureTrailingSlash(n){return n.endsWith(`/`)?n:`${n}/`}function defaultFileMode(n){return n.length>=2&&n[0]===35&&n[1]===33?493:420}function concatChunks(n){let a=0;for(let S of n)a+=S.byteLength;let S=new Uint8Array(a),C=0;for(let a of n)S.set(a,C),C+=a.byteLength;return S}var oM=__esmMin(()=>{});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=es(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(os(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(os(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`);return drainStream(new Blob([new Uint8Array(n)]).stream().pipeThrough(new a(`gzip`)))}async function gzip(n){let a=globalThis.CompressionStream;if(typeof a!=`function`)throw Error(`@gjsify/tar: globalThis.CompressionStream is not available — import '@gjsify/compression-streams/register' on GJS to register it`);return drainStream(new Blob([new Uint8Array(n)]).stream().pipeThrough(new a(`gzip`)))}async function drainStream(n){let a=[],S=0,C=n.getReader();for(;;){let{value:n,done:N}=await C.read();if(N)break;let F=n instanceof Uint8Array?n:new Uint8Array(n);a.push(F),S+=F.length}let N=new Uint8Array(S),F=0;for(let n of a)N.set(n,F),F+=n.length;return N}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=is(a,n);return S!==``&&!S.startsWith(`..`)&&!ns(S)}var sM=__esmMin(()=>{aM(),Qc(),ms()}),cM=__exportAll$3({BLOCK_SIZE:()=>512,TarParseError:()=>TarParseError,createTarball:()=>createTarball,extractTarball:()=>extractTarball,gunzip:()=>gunzip,gzip:()=>gzip,parseTar:()=>parseTar}),lM=__esmMin(()=>{aM(),oM(),sM()});function gjsifyCacheRoot(n,a){let S=process.env.XDG_CACHE_HOME;return rs(S&&S.length>0?S:rs(homedir(),`.cache`),`gjsify`,n,a)}function atomicWrite(n,a){try{atomicWriteStrict(n,a)}catch{}}function atomicWriteStrict(n,a){mkdirSync(rs(n,`..`),{recursive:!0});let S=`${n}.tmp.${process.pid}`;writeFileSync(S,a),renameSync(S,n)}function readCacheFile(n){if(!existsSync(n))return null;try{let a=readFileSync(n);return a.length===0?null:a}catch{return null}}var uM=__esmMin(()=>{Qc(),Gp(),ms()});function staleMs(){let n=process.env.GJSIFY_INSTALL_LOCK_STALE_MS;if(n!==void 0){let a=Number(n);if(Number.isFinite(a)&&a>0)return a}return pM}function lockingDisabled(){let n=process.env.GJSIFY_INSTALL_LOCK;if(n===void 0)return!1;let a=n.trim();return a===`0`||a===`false`}function isPidAlive(n){try{if(existsSync(`/proc/self`))return existsSync(`/proc/${n}`)}catch{}try{return process.kill(n,0),!0}catch(n){return n.code===`EPERM`}}function mtimeMs(n){try{return statSync(n).mtimeMs}catch{return null}}function assessLock(n){let a=rs(n,fM),S=null;try{S=JSON.parse(readFileSync(a,`utf-8`))}catch{S=null}let C=Date.now();if(S&&typeof S.pid==`number`){if(!isPidAlive(S.pid))return{stale:!0,reason:`owner pid ${S.pid} is gone`,ownerPid:S.pid};let n=typeof S.startedAt==`number`?S.startedAt:mtimeMs(a);return n!==null&&C-n>staleMs()?{stale:!0,reason:`owner pid ${S.pid} exceeded the ${staleMs()}ms staleness budget`,ownerPid:S.pid}:{stale:!1,ownerPid:S.pid}}let N=mtimeMs(n);return N===null?{stale:!1}:C-N>mM?{stale:!0,reason:`no owner recorded within the acquire grace period`}:{stale:!1}}function stealStaleLock(n){let a=`${n}.stale-${process.pid}-${++vM}`;try{renameSync(n,a)}catch{return!1}try{rmSync(a,{recursive:!0,force:!0})}catch{}return!0}function abortErr(n){let a=n&&`reason`in n?n.reason:void 0;if(a instanceof Error)return a;let S=Error(`Aborted`);return S.name=`AbortError`,S}function delay(n,a){return n<=0?Promise.resolve():new Promise((S,C)=>{let onAbort=()=>{clearTimeout(N),C(abortErr(a))},N=setTimeout(()=>{a?.removeEventListener?.(`abort`,onAbort),S()},n);if(a?.aborted){clearTimeout(N),C(abortErr(a));return}a?.addEventListener?.(`abort`,onAbort,{once:!0})})}function makeHandle(n){let a=!1;return{release(){if(a)return;a=!0;let S=_M.get(n);if(S&&(S.count--,!(S.count>0))){_M.delete(n);try{let a=JSON.parse(readFileSync(rs(n,fM),`utf-8`));if(a.nonce!==void 0&&a.nonce!==S.nonce)return}catch{}try{rmSync(n,{recursive:!0,force:!0})}catch{}}}}}async function acquireInstallLock(n,a={}){if(lockingDisabled())return{release(){}};let S;try{S=realpathSync(n)}catch{S=es(n)}let C=rs(S,`node_modules`,dM),N=_M.get(C);if(N)return N.count++,makeHandle(C);mkdirSync(os(C),{recursive:!0});let F=`${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`,I=hM,H=!1;for(;;){if(a.signal?.aborted)throw abortErr(a.signal);try{return mkdirSync(C),writeFileSync(rs(C,fM),JSON.stringify({pid:process.pid,nonce:F,startedAt:Date.now()})),_M.set(C,{count:1,nonce:F}),makeHandle(C)}catch(n){if(n.code!==`EEXIST`)throw n}let n=assessLock(C);if(n.stale){stealStaleLock(C)&&ke.warn(`gjsify install: removed stale install lock (${n.reason}) — ${C}`);continue}if(!H){H=!0;let a=n.ownerPid===void 0?``:` (pid ${n.ownerPid})`;ke.warn(`gjsify install: waiting for a concurrent install${a} to release ${C} …`)}await delay(I,a.signal),I=Math.min(Math.round(I*1.6),gM)}}var dM,fM,pM,mM,hM,gM,_M,vM,yM=__esmMin(()=>{Ae(),Qc(),ms(),dM=`.gjsify-install-lock`,fM=`owner.json`,pM=35*6e4,mM=15e3,hM=150,gM=1e3,_M=new Map,vM=0});function cacheRoot$1(){return gjsifyCacheRoot(`tarballs`,bM)}function parseSri$1(n){if(!n)return null;let a=n.indexOf(`-`);if(a<=0||a===n.length-1)return null;let S=n.slice(0,a),C=n.slice(a+1).replace(/=+$/,``),N;try{N=Buffer.from(C,`base64`).toString(`hex`)}catch{return null}return N.length<4?null:{algorithm:S,hex:N}}function pathFor$1(n){let a=parseSri$1(n);if(!a)return null;let S=a.hex.slice(0,2);return rs(cacheRoot$1(),a.algorithm,S,`${a.hex}.tgz`)}function getCachedTarball(n){let a=pathFor$1(n);return a?readCacheFile(a):null}function putCachedTarball(n,a){let S=pathFor$1(n);S&&(existsSync(S)||atomicWrite(S,a))}function npmCacacheContentDir(){let n=process.env.GJSIFY_NPM_CACHE;if(n!==void 0){let a=n.trim();return a===``||a===`0`||a===`false`?null:rs(a.endsWith(`_cacache`)?a:rs(a,`_cacache`),`content-v2`)}let a=process.env.npm_config_cache;return rs(a&&a.length>0?a:rs(homedir(),`.npm`),`_cacache`,`content-v2`)}function npmCachePathFor(n){let a=npmCacacheContentDir();if(!a)return null;let S=parseSri$1(n);return S?rs(a,S.algorithm,S.hex.slice(0,2),S.hex.slice(2,4),S.hex.slice(4)):null}function getForeignCachedTarball(n){let a=npmCachePathFor(n);return a?readCacheFile(a):null}var bM,xM=__esmMin(()=>{Qc(),Gp(),ms(),uM(),bM=`v1`,__name$1(cacheRoot$1,`cacheRoot`),__name$1(parseSri$1,`parseSri`),__name$1(pathFor$1,`pathFor`)});function isEnabled(){let n=process.env.GJSIFY_PACKUMENT_CACHE;if(n===void 0)return!0;let a=n.trim();return!(a===`0`||a===`false`||a===``)}function cacheRoot(){return gjsifyCacheRoot(`metadata`,SM)}function shardFor(n){let a=2166136261;for(let S=0;S<n.length;S++)a^=n.charCodeAt(S),a=Math.imul(a,16777619);return(a>>>0&255).toString(16).padStart(2,`0`)}function pathFor(n,a){if(!isEnabled())return null;let S=`${n}|${a}`,C=`${encodeURIComponent(n)}|${encodeURIComponent(a)}.json`;return rs(cacheRoot(),shardFor(S),C)}function getCachedPackument(n,a){let S=pathFor(n,a);if(!S)return null;let C=readCacheFile(S);if(!C)return null;try{let n=JSON.parse(C.toString(`utf-8`));return typeof n.etag!=`string`||!n.etag||!n.packument||typeof n.packument!=`object`?null:{etag:n.etag,packument:n.packument}}catch{return null}}function putCachedPackument(n,a,S,C){if(!S)return;let N=pathFor(n,a);N&&atomicWrite(N,JSON.stringify({etag:S,packument:C}))}var SM,CM=__esmMin(()=>{ms(),uM(),SM=`v1`});function parseNodeMajor(n){return Number.parseInt(String(n).split(`.`,1)[0]??``,10)}function nativeBackendNodeError(n,a){if(!a)return null;let S=parseNodeMajor(n);return!Number.isFinite(S)||S>=24?null:`gjsify install (native backend) requires Node ≥ 24, but this is Node ${n}. Its prebuilt native modules are ABI-locked to Node 24 and crash on older majors. Use Node 24 (nvm/asdf locally, actions/setup-node in CI), or run with --backend npm.`}function onRealNode(){return gjsSystemVersion()===void 0?isNode():!1}function assertNativeBackendNodeVersion(){let n=nativeBackendNodeError(process.versions.node,onRealNode());if(n)throw Error(n)}var wM=__esmMin(()=>{sm()}),TM=__exportAll$3({installPackagesNative:()=>installPackagesNative,parseSpec:()=>parseSpec,pickVersion:()=>pickVersion});async function installPackagesNative(n){if(assertNativeBackendNodeVersion(),n.specs.length===0)throw Error(`installPackagesNative: empty specs list`);mkdirSync(n.prefix,{recursive:!0});let a=await loadNpmrc$1(n),S=makeLogger(n.verbose??!1),C=await acquireInstallLock(n.prefix,{signal:n.signal});try{return await installPackagesNativeLocked(n,a,S)}finally{C.release()}}async function installPackagesNativeLocked(n,a,S){let C=n.progress,N=rs(n.prefix,DM),F=readLockfile(N),I;if(n.frozen){if(!F)throw Error(`install: --immutable requires ${DM} at ${n.prefix} — none found. Run \`gjsify install\` (without --immutable) to generate one and commit it.`);let a=describeLockfileDrift(F,n.specs);if(a)throw Error(`install: --immutable but ${N} is stale.\n${a}\nRe-run \`gjsify install\` (without --immutable) to refresh the lockfile.`);S(`install: --immutable, using lockfile (%d package(s))`,Object.keys(F.packages).length),I=lockfileToNodes(F)}else if(!n.refreshLockfile&&F&&lockfileMatchesRequest(F,n.specs))S(`install: using lockfile (%d package(s))`,Object.keys(F.packages).length),I=lockfileToNodes(F);else{let H=!n.refreshLockfile&&F?buildPreferredVersions(F):void 0;S(`install: resolving %d top-level spec(s) → %s%s`,n.specs.length,n.prefix,H?` (preserving ${H.size} locked name(s))`:``),I=await resolveDeps(n.specs,a,S,n.overrides,n.skipDeps,n.signal,C,H,n.workspaceNames,n.specOrigins),n.lockfile&&(writeLockfile(N,n.specs,I),S(`install: wrote %s (%d entries)`,DM,I.length))}if(n.workspaceNames&&n.workspaceNames.size>0){let a=I.length;I=I.filter(a=>!n.workspaceNames.has(a.name));let C=a-I.length;C>0&&S(`install: %d workspace-provided package(s) symlinked, not fetched`,C)}return S(`install: downloading %d tarball(s)`,I.length),await downloadAndExtractAll(I,n.prefix,a,S,n.signal,C),await linkBins(I,n.prefix,S),S(`install: done`),topLevelResolutions(n.specs,I)}function errMsg(n){return n instanceof Error?n.message:String(n)}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,N,F,I,H,W,K){I?.beginPhase(`resolve`,n.length);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)},q=new Map,fetchPkg=n=>{let C=q.get(n);if(C)return C;let N=fetchPackumentWithDiskCache(n,a,S,F);return q.set(n,N),N},Y=new Map,X=new Map,te=new Map,ne=n.map(parseSpec).map(n=>{let a=applyOverride(n.name,n.range),S=te.get(n.name);S||(S=new Map,te.set(n.name,S));let C=S.get(a);C||(C=new Set,S.set(a,C));for(let a of K?.get(`${n.name}@${n.range}`)??[])C.add(a);return{from:null,name:n.name,range:a,required:!0}});for(;ne.length>0;){let n=ne.splice(0,ne.length),a=[],C=new Set;for(let S of n)q.has(S.name)||C.has(S.name)||(C.add(S.name),a.push(S.name));await prefetchPackuments(a,fetchPkg,F);for(let a=0;a<n.length;a++){let C=n[a];if(W?.has(C.name))continue;let F=findVisible(C.from,C.name,Y);if(F&&satisfiesRange(F.version,C.range))continue;let K=null;try{let F=await fetchPkg(C.name),W=preferredVersionFor(H?.get(C.name),C.range);if(K=pickVersion(F,C.range,W),!K){if(!C.required)continue;throw Error(`No version of ${C.name} satisfies ${C.range}`)}let q=F.versions[K];if(!q)throw Error(`Packument for ${C.name} promised ${K} but no entry exists`);let te=decidePlacement(C.from,C.name,K,X),re={name:C.name,version:K,tarballUrl:q.dist.tarball,integrity:q.dist.integrity,installPath:te,dependencies:q.dependencies??{},optionalDependencies:q.optionalDependencies??{},bin:q.bin};if(Y.set(te,re),te===`node_modules/${C.name}`&&X.set(C.name,re),S(`resolve: %s@%s ← %s (at %s)`,C.name,K,C.range,te),I?.update({phase:`resolve`,current:Y.size,total:Y.size+(n.length-a-1)+ne.length,name:`${C.name}@${K}`}),!N){for(let[n,a]of Object.entries(re.dependencies))ne.push({from:te,name:n,range:applyOverride(n,a),required:!0});for(let[n,a]of Object.entries(re.optionalDependencies))ne.push({from:te,name:n,range:applyOverride(n,a),required:!1})}}catch(n){if(!C.required){S(`resolve: optional dep %s@%s skipped (%s)`,C.name,C.range,n.message);continue}throw n}}}return I?.endPhase(`resolve`),emitTopLevelConflictWarnings(te,X),Array.from(Y.values())}function emitTopLevelConflictWarnings(n,a){for(let[S,C]of n){if(C.size<2)continue;let n=a.get(S);if(!n)continue;let describe=(n,a)=>a.size>0?`${n} (requested by ${[...a].join(`, `)})`:n,N=[],F=[];for(let[a,S]of C){let C;try{C=satisfies(n.version,new tM(a))}catch{continue}(C?N:F).push(describe(a,S))}F.length!==0&&ke.warn(`[gjsify] warning: version conflict for ${S}: installed ${n.version} at ${n.installPath} — does NOT satisfy ${F.join(`, `)}`+(N.length>0?`; satisfies ${N.join(`, `)}`:``)+`. One hoisted copy serves all requesters until the per-workspace dedup pass lands (Phase D.8).`)}}async function fetchPackumentWithDiskCache(n,a,S,C){let N=registryFor(n,a),F=getCachedPackument(N,n),onRetry=({attempt:a,error:C,delayMs:N})=>{S(`packument %s: retry %d after %dms (%s)`,n,a,N,errMsg(C))},I=await fetchPackumentConditional(n,{npmrc:a,signal:C,ifNoneMatch:F?.etag,onRetry});return I.status===`not-modified`&&F?(S(`packument-cache-hit: %s (304, etag %s)`,n,F.etag),F.packument):I.status===`fresh`&&I.packument?(I.etag&&putCachedPackument(N,n,I.etag,I.packument),I.packument):fetchPackument(n,{npmrc:a,signal:C,onRetry})}async function prefetchPackuments(n,a,S){if(n.length===0)return;let C=0,N=Math.max(1,Math.min(EM,n.length)),worker=async()=>{for(;C<n.length;){if(S?.aborted)return;let N=n[C++];try{await a(N)}catch{}}};await Promise.all(Array.from({length:N},()=>worker()))}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 tM(a))}catch{return!1}}function readLockfile(n){if(!existsSync(n))return null;try{let a=JSON.parse(readFileSync(n,`utf-8`));return a.lockfileVersion!==OM||!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:OM,requested:[...a],packages:C};atomicWriteStrict(n,JSON.stringify(F,null,2)+`
|
|
762
|
+
`)}),()=>{F.length>0&&(a.write(F),F=``)}}var zj=__esmMin(()=>{});function runCheck(n,a){return new Promise(S=>{let C=spawn(`npm`,[`run`,`check`,`--if-present`],{cwd:n.location,stdio:a===null?`inherit`:[`ignore`,`pipe`,`pipe`]}),N=!process.stdout.isTTY,F=[];if(a!==null&&C.stdout&&C.stderr){let n=`[${a}] `;F.push(prefixLines(C.stdout,process.stdout,n,N)),F.push(prefixLines(C.stderr,process.stderr,n,N))}C.on(`close`,n=>{for(let n of F)n();S(n??1)}),C.on(`error`,()=>{for(let n of F)n();S(1)})})}var Bj,Vj=__esmMin(()=>{Ae(),dm(),zj(),Gg(),ms(),Gp(),Wg(),Kg(),Bj={command:`check`,description:"Run `npm run check` (TypeScript type-check) across the current workspace. In a workspace root: walks every package with a `check` script (excludes @girs/*; honours --include/--exclude). In a single package: runs the local `check` script directly. Symmetric peer of `gjsify format` / `lint` / `fix`. (Legacy system-dep `gjsify check` is now `gjsify system-check` — see #254.)",builder:n=>n.option(`include`,{description:`Only run in workspaces matching these glob patterns (repeatable).`,type:`string`,array:!0}).option(`exclude`,{description:`Skip workspaces matching these glob patterns (repeatable). Always excludes @girs/*.`,type:`string`,array:!0}).option(`parallel`,{description:`Run workspace checks in parallel (default). Use --no-parallel to run them sequentially with full per-workspace output.`,type:`boolean`,alias:`p`,default:!0}).option(`jobs`,{description:`Max parallel workers (when --parallel). Default: os.cpus().length.`,type:`number`,alias:`j`}).option(`verbose`,{description:`Log the per-workspace command before spawning.`,type:`boolean`,default:!1}),handler:async n=>{let a=process.cwd(),S=findWorkspaceRoot(a);if(S&&a!==S&&readPackageJson$2(rs(a,`package.json`))?.scripts?.check){n.verbose&&ke.log(`[check] cwd=${a} → npm run check`);let S=spawnSync(`npm`,[`run`,`check`],{cwd:a,stdio:`inherit`});process.exit(S.status??1)}S||(ke.error("gjsify check: no workspace root found from cwd. Run inside a workspace (or a package within one) with `npm run check` defined."),process.exit(1));let C=discoverWorkspaces(S),N=[`@girs/*`,...n.exclude??[]],F=filterWorkspaces(C,{include:n.include,exclude:N}).filter(n=>n.manifest.scripts?.check!==void 0);if(F.length===0&&(ke.error("gjsify check: no workspaces with a `check` script found."),process.exit(1)),n.verbose&&ke.log(`[check] root=${S} workspaces=${F.length} parallel=${n.parallel?`yes`:`no`}`),!n.parallel){let a=0;for(let S of F){n.verbose&&ke.log(`[check] → ${S.name}`);let C=await runCheck(S,null);C!==0&&a===0&&(a=C)}a!==0&&ke.error(`gjsify check: failures in ${F.filter(async n=>await runCheck(n,null)!==0).length}+ workspaces`),process.exit(a)}let I=n.jobs??Math.max(1,cpus().length),H=[],W=0,K=[];for(let n=0;n<I;n++)K.push((async()=>{for(;;){let n=W++;if(n>=F.length)return;let a=F[n],S=await runCheck(a,a.name);S!==0&&H.push({name:a.name,code:S})}})());if(await Promise.all(K),H.length>0){ke.error(`\ngjsify check: ${H.length} of ${F.length} workspace(s) failed:`);for(let n of H)ke.error(` ✗ ${n.name} (exit ${n.code})`);process.exit(1)}n.verbose&&ke.log(`\ngjsify check: ${F.length} workspace(s) green.`),process.exit(0)}}});function manifestPath(){let n=os(fileURLToPath(import.meta.url)),a=[rs(n,`..`,`..`,`showcases.json`),rs(n,`..`,`showcases.json`)];return a.find(n=>existsSync(n))??a[0]}function discoverShowcases(){let n=manifestPath();if(!existsSync(n))return[];let a;try{a=JSON.parse(readFileSync(n,`utf-8`))}catch{return[]}if(!Array.isArray(a.showcases))return[];let S=a.showcases.map(n=>({name:n.name,packageName:n.package,category:n.category,description:n.description??``,needsWebgl:!!n.needsWebgl}));return S.sort((n,a)=>n.category.localeCompare(a.category)||n.name.localeCompare(a.name)),S}function findShowcase(n){return discoverShowcases().find(a=>a.name===n)}var Hj=__esmMin(()=>{Qc(),ms(),mn()});function parseSpec$1(n){if(!n)throw Error(`dlx: empty package spec`);if(n.startsWith(`./`)||n.startsWith(`../`)||ns(n)||existsSync(n))return{kind:`local`,path:es(n)};let a=n,S,C=n.lastIndexOf(`@`);if(C>0&&(a=n.slice(0,C),S=n.slice(C+1)),!Uj.test(a))throw Error(`dlx: invalid package name "${a}"`);return{kind:`registry`,name:a,version:S,spec:n}}var Uj,Wj=__esmMin(()=>{Qc(),ms(),Uj=/^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,__name$1(parseSpec$1,`parseSpec`)});function resolveGjsEntry(n,a){let S=rs(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=es(n,H);if(!existsSync(q))throw Error(`dlx: GJS entry not found: ${q}`);return{bundlePath:q,binName:W,fromFallback:K}}function resolveNodeEntry(n){let a=rs(n,`package.json`);if(!existsSync(a))throw Error(`no package.json found at ${n}`);let S=JSON.parse(readFileSync(a,`utf-8`)),C=S.gjsify?.example?.node;if(C){let a=es(n,C);if(!existsSync(a))throw Error(`declared node entry not found: ${a} (gjsify.example.node)`);return a}let N=S.gjsify?.main??(S.gjsify?.bin?Object.values(S.gjsify.bin)[0]:void 0)??S.main;if(!N)throw Error(`package "${S.name??n}" has no entry to derive a node bundle from — set \`gjsify.example.node\` to its \`--app node\` bundle path.`);let F=N.replace(/\.gjs\.(js|mjs|cjs)$/,``).replace(/\.(js|mjs|cjs)$/,``),I=[`${F}.node.mjs`,`${F}.node.js`,`${F}.node.cjs`];for(let a of I){let S=es(n,a);if(existsSync(S))return S}throw Error(`package "${S.name??n}" has no \`--app node\` bundle — looked for ${I.join(`, `)}.\n Build one (e.g. \`gjsify build src/app.ts --app node --outfile dist/app.node.mjs\`) or set \`gjsify.example.node\` to its path.`)}var Gj=__esmMin(()=>{Qc(),ms()});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=rs(n&&n.length>0?n:rs(homedir(),`.cache`),`gjsify`,`dlx`);return mkdirSync(a,{recursive:!0}),a}function cacheDirFor(n){let a=rs(dlxCacheRoot(),n);return mkdirSync(a,{recursive:!0}),a}function makePrepareDir(n){let a=rs(n,`${Date.now().toString(16)}-${process.pid.toString(16)}`);return mkdirSync(a,{recursive:!0}),a}function getValidCachedPkg(n,a=qj){let S=rs(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*Kj?N:void 0}function symlinkSwap(n,a){let S=rs(n,`pkg`),C=rs(n,`pkg.tmp-${Date.now().toString(16)}-${process.pid.toString(16)}`);symlinkSync(a,C,`dir`);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 es(n,`node_modules`,a)}var Kj,qj,Jj=__esmMin(()=>{oo(),Qc(),Gp(),ms(),Kj=6e4,qj=1440*7});function makeProgressReporter(n={}){if(n.enabled===!1)return Xj;let a=n.stream??process.stderr,S=!!a.isTTY;return n.enabled??!0?S?makeTtyReporter(a):makePlainReporter(a):Xj}function makeTtyReporter(n){let a=0,S=``;function render(C,N=!1){let F=Date.now();!N&&F-a<33&&C===S||(a=F,S=C,n.write(`\r\x1B[2K`+C))}function clearLine(){n.write(`\r\x1B[2K`),S=``}return{beginPhase(a,S){render(formatBar(a,0,S,void 0,n.columns??80),!0)},update(a){render(formatBar(a.phase,a.current,a.total,a.name,n.columns??80))},endPhase(a){let S=Yj[a];clearLine(),n.write(`gjsify install: ${S} done\n`)}}}function makePlainReporter(n){let a=0,S=0;return{beginPhase(C,N){a=Date.now(),S=0,n.write(`gjsify install: ${Yj[C]} ${N} package(s)\n`)},update(C){let N=Date.now();if(N-a<Zj||C.current<=S)return;a=N,S=C.current;let F=C.total>0?Math.round(C.current/C.total*100):0;n.write(`gjsify install: ${Yj[C.phase]} ${C.current}/${C.total} (${F}%)\n`)},endPhase(a){n.write(`gjsify install: ${Yj[a]} done\n`)}}}function formatBar(n,a,S,C,N){let F=Yj[n],I=S>0?Math.min(1,a/S):0,H=`${a}/${S}`,W=`gjsify install: ${F} `,K=` ${H}`+(C?` ${C}`:``),q=Math.max(8,Math.min(40,N-W.length-K.length-4)),Y=Math.round(I*q),X=`█`.repeat(Y)+`░`.repeat(q-Y),te=`${W}[${X}]${K}`;if(te.length>N){let n=te.length-N+1,a=C&&C.length>n?C.slice(0,C.length-n-1)+`…`:``;te=`${W}[${X}] ${H}${a?` `+a:``}`}return te}var Yj,Xj,Zj,Qj=__esmMin(()=>{Yj={resolve:`resolving`,download:`downloading`,extract:`extracting`,link:`linking bins`},Xj={update(){},beginPhase(){},endPhase(){}},Zj=5e3});function parse(n){try{return new SemVer(n)}catch{return null}}function compare(n,a){let S=n instanceof SemVer?n:new SemVer(n),C=a instanceof SemVer?a:new SemVer(a);return S.compare(C)}function satisfies(n,a){let S=a instanceof tM?a:new tM(a),C=n instanceof SemVer?n:parse(String(n));return C?S.test(C):!1}function maxSatisfying(n,a){let S=a instanceof tM?a:new tM(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 $j,eM,SemVer,tM,nM=__esmMin(()=>{$j=/^(0|[1-9]\d*)$/,eM=/^(\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=eM.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=>$j.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}},tM=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$1(C)}return a?.registry?ensureTrailingSlash$1(a.registry):rM}function packumentUrl(n,a){let S=ensureTrailingSlash$1(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 fetchPackumentConditional(n,a={}){let S=packumentUrl(n,a.registry??registryFor(n,a.npmrc)),C=buildHeaders(S,{...a,acceptEncoding:`gzip`});C.accept??=`application/vnd.npm.install-v1+json`,a.ifNoneMatch&&(C[`if-none-match`]=a.ifNoneMatch);let N=await fetchWithRetry(S,{headers:C,signal:a.signal},{fetch:a.fetch,retries:a.retries,retryDelayMs:a.retryDelayMs,timeoutMs:a.timeoutMs,onRetry:a.onRetry});if(N.status===304){try{await N.arrayBuffer()}catch{}return{status:`not-modified`,etag:a.ifNoneMatch}}if(!N.ok)throw N.status===404||N.status===406?new PackageNotFoundError(n,S):Error(`registry GET ${S} -> ${N.status} ${N.statusText}`);let F=N.headers.get(`etag`)??void 0,I=await decodeJsonBody(N);return assertPackument(n,I),{status:`fresh`,packument:I,etag:F}}async function decodeJsonBody(n){return n.json()}async function fetchPackument(n,a={}){let S=await fetchPackumentConditional(n,a);if(!S.packument)throw Error(`registry: ${n} returned 304 Not Modified to an unconditional request`);return S.packument}async function fetchTarball(n,a={}){let S=buildHeaders(n,{...a,acceptEncoding:`identity`});S.accept??=`application/octet-stream`;let C=await fetchWithRetry(n,{headers:S,signal:a.signal},{fetch:a.fetch,retries:a.retries,retryDelayMs:a.retryDelayMs,timeoutMs:a.timeoutMs,onRetry:a.onRetry,retryNotFound:a.retryNotFound??!0});if(!C.ok)throw Error(`tarball GET ${n} -> ${C.status} ${C.statusText}`);let N=new Uint8Array(await C.arrayBuffer());if(a.integrity&&!await verifyIntegrity(N,a.integrity))throw new IntegrityError(n,a.integrity);return N}async function fetchWithRetry(n,a,S){let C=S.fetch??globalThis.fetch;if(!C)throw Error(`@gjsify/npm-registry: globalThis.fetch is missing`);let N=Math.max(0,S.retries??3),F=Math.max(0,S.retryDelayMs??250),I=Math.max(0,S.timeoutMs??3e4),H=S.retryNotFound??!1,W=0,K,q=0;for(;;){if(a.signal?.aborted)throw signalAbortError(a.signal);let Y=I>0?new AbortController:null,X=Y===null?null:setTimeout(()=>Y.abort(Error(`@gjsify/npm-registry: per-request timeout ${I}ms`)),I),te=composeSignals(a.signal,Y?.signal);try{let S=await C(n,{...a,signal:te}),F=isRetryableStatus(S.status)||H&&S.status===404;if(S.ok||!F||W>=N)return S;try{await S.arrayBuffer()}catch{}K=Error(`HTTP ${S.status} ${S.statusText}`)}catch(S){let C=Y!==null&&Y.signal.aborted,F=a.signal?.aborted===!0;if(C&&!F){if(q++,W>=N)throw new RegistryTimeoutError(n,I,q);K=S}else if(F)throw signalAbortError(a.signal);else{if(!isRetryableError(S)||W>=N)throw S;K=S}}finally{X!==null&&clearTimeout(X)}let ne=Math.min(F*2**W,8e3);S.onRetry?.({attempt:W+1,error:K,delayMs:ne}),await delay$1(ne,a.signal),W++}}function composeSignals(n,a){return n?a?AbortSignal.any([n,a]):n:a}function isRetryableStatus(n){return n===408||n===425||n===429||n===500||n===502||n===503||n===504||n===521||n===522||n===524||n===525}function isRetryableError(n){if(n&&typeof n==`object`&&`name`in n&&n.name===`AbortError`)return!1;if(n instanceof TypeError)return!0;if(n&&typeof n==`object`&&`name`in n){let a=n.name;if(a===`FetchError`)return!0;if(a===`AbortError`)return!1}let a=n?.cause;if(a&&typeof a==`object`&&`code`in a){let n=a.code;if(typeof n==`string`)return n===`ECONNRESET`||n===`ECONNREFUSED`||n===`ENETUNREACH`||n===`ENOTFOUND`||n===`ETIMEDOUT`||n===`EAI_AGAIN`||n===`UND_ERR_SOCKET`||n===`UND_ERR_CONNECT_TIMEOUT`}return!1}function delay$1(n,a){return n<=0?Promise.resolve():new Promise((S,C)=>{let N=setTimeout(()=>{a?.removeEventListener?.(`abort`,onAbort),S()},n),onAbort=()=>{clearTimeout(N),C(signalAbortError(a))};if(a?.aborted){clearTimeout(N),C(signalAbortError(a));return}a?.addEventListener?.(`abort`,onAbort,{once:!0})})}function signalAbortError(n){let a=n&&`reason`in n?n.reason:void 0;if(a instanceof Error)return a;let S=Error(`Aborted`);return S.name=`AbortError`,S}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:rM,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$1(I);continue}let H=F.match(/^(@[^:]+):registry$/);if(H){a.scopes[H[1]]=ensureTrailingSlash$1(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`,"accept-encoding":a.acceptEncoding??`identity`};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$1(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)}async function whoami(n,a){let S=`${ensureTrailingSlash$1(n)}-/whoami`,C=buildHeaders(S,{npmrc:a});C.accept=`application/json`;let N=globalThis.fetch;if(!N)throw Error(`@gjsify/npm-registry: globalThis.fetch is missing`);let F=await N(S,{method:`GET`,headers:C});if(!F.ok)throw Error(`whoami GET ${S} -> ${F.status} ${F.statusText}`);let I=await F.json();if(I&&typeof I==`object`&&`username`in I){let n=I.username;if(typeof n==`string`&&n.length>0)return{username:n}}return{}}var rM,PackageNotFoundError,IntegrityError,RegistryTimeoutError,iM=__esmMin(()=>{rM=`https://registry.npmjs.org/`,__name$1(delay$1,`delay`),__name$1(ensureTrailingSlash$1,`ensureTrailingSlash`),PackageNotFoundError=class extends Error{constructor(n,a){super(`Package not found in registry: ${n} (${a})`),this.name=n,this.url=a,this.name=`PackageNotFoundError`}},IntegrityError=class extends Error{constructor(n,a){super(`Tarball integrity mismatch for ${n} (expected ${a})`),this.url=n,this.integrity=a,this.name=`IntegrityError`}},RegistryTimeoutError=class extends Error{constructor(n,a,S){let C=Math.round(a/100)/10,N=Math.round(a*S/100)/10;super(`@gjsify/npm-registry: GET ${n} timed out after ${C}s × ${S} attempt(s) (total ~${N}s). This usually means the registry CDN is slow or unreachable.`),this.url=n,this.timeoutMs=a,this.attempts=S,this.name=`RegistryTimeoutError`}}});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,aM=__esmMin(()=>{TarParseError=class extends Error{constructor(n){super(n),this.name=`TarParseError`}}});function createTarball(n){let a=[];for(let S of n){if(`directory`in S&&S.directory===!0){a.push(buildHeader(ensureTrailingSlash(S.name),0,`5`,S.mode??493,S.mtime??0));continue}let n=S,C=typeof n.body==`string`?new TextEncoder().encode(n.body):n.body,N=n.mode??defaultFileMode(C);a.push(buildHeader(n.name,C.byteLength,`0`,N,n.mtime??0)),a.push(C);let F=padTo512(C.byteLength);F>0&&a.push(new Uint8Array(F))}return a.push(new Uint8Array(512*2)),concatChunks(a)}function buildHeader(n,a,S,C,N){let{prefix:F,basename:I}=splitPathForUstar(n),H=new Uint8Array(512);writeAscii(H,I,0,100),writeOctal(H,C&4095,100,7),H[107]=0,writeOctal(H,0,108,7),H[115]=0,writeOctal(H,0,116,7),H[123]=0,writeOctal(H,a,124,11),H[135]=0,writeOctal(H,N,136,11),H[147]=0;for(let n=148;n<156;n++)H[n]=32;H[156]=S.charCodeAt(0),writeAscii(H,`ustar\0`,257,6),writeAscii(H,`00`,263,2),F&&writeAscii(H,F,345,155);let W=0;for(let n=0;n<512;n++)W+=H[n];return writeAscii(H,W.toString(8).padStart(6,`0`),148,6),H[154]=0,H[155]=32,H}function splitPathForUstar(n){if(n.length<=100)return{prefix:``,basename:n};if(n.length>255)throw Error(`createTarball: path too long (${n.length} > 255 chars): ${n}`);for(let a=Math.min(n.length-1,155);a>0;a--)if(n[a]===`/`&&n.length-a-1<=100)return{prefix:n.slice(0,a),basename:n.slice(a+1)};throw Error(`createTarball: cannot split path into ustar prefix+basename (basename slot is 100 chars): ${n}`)}function writeAscii(n,a,S,C){let N=new TextEncoder().encode(a);if(N.length>C)throw Error(`createTarball: field too long (${N.length} > ${C}): "${a}"`);n.set(N,S)}function writeOctal(n,a,S,C){writeAscii(n,a.toString(8).padStart(C,`0`),S,C)}function padTo512(n){let a=n%512;return a===0?0:512-a}function ensureTrailingSlash(n){return n.endsWith(`/`)?n:`${n}/`}function defaultFileMode(n){return n.length>=2&&n[0]===35&&n[1]===33?493:420}function concatChunks(n){let a=0;for(let S of n)a+=S.byteLength;let S=new Uint8Array(a),C=0;for(let a of n)S.set(a,C),C+=a.byteLength;return S}var oM=__esmMin(()=>{});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=es(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(os(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(os(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`);return drainStream(new Blob([new Uint8Array(n)]).stream().pipeThrough(new a(`gzip`)))}async function gzip(n){let a=globalThis.CompressionStream;if(typeof a!=`function`)throw Error(`@gjsify/tar: globalThis.CompressionStream is not available — import '@gjsify/compression-streams/register' on GJS to register it`);return drainStream(new Blob([new Uint8Array(n)]).stream().pipeThrough(new a(`gzip`)))}async function drainStream(n){let a=[],S=0,C=n.getReader();for(;;){let{value:n,done:N}=await C.read();if(N)break;let F=n instanceof Uint8Array?n:new Uint8Array(n);a.push(F),S+=F.length}let N=new Uint8Array(S),F=0;for(let n of a)N.set(n,F),F+=n.length;return N}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=is(a,n);return S!==``&&!S.startsWith(`..`)&&!ns(S)}var sM=__esmMin(()=>{aM(),Qc(),ms()}),cM=__exportAll$3({BLOCK_SIZE:()=>512,TarParseError:()=>TarParseError,createTarball:()=>createTarball,extractTarball:()=>extractTarball,gunzip:()=>gunzip,gzip:()=>gzip,parseTar:()=>parseTar}),lM=__esmMin(()=>{aM(),oM(),sM()});function gjsifyCacheRoot(n,a){let S=process.env.XDG_CACHE_HOME;return rs(S&&S.length>0?S:rs(homedir(),`.cache`),`gjsify`,n,a)}function atomicWrite(n,a){try{atomicWriteStrict(n,a)}catch{}}function atomicWriteStrict(n,a){mkdirSync(rs(n,`..`),{recursive:!0});let S=`${n}.tmp.${process.pid}`;writeFileSync(S,a),renameSync(S,n)}function readCacheFile(n){if(!existsSync(n))return null;try{let a=readFileSync(n);return a.length===0?null:a}catch{return null}}var uM=__esmMin(()=>{Qc(),Gp(),ms()});function staleMs(){let n=process.env.GJSIFY_INSTALL_LOCK_STALE_MS;if(n!==void 0){let a=Number(n);if(Number.isFinite(a)&&a>0)return a}return pM}function lockingDisabled(){let n=process.env.GJSIFY_INSTALL_LOCK;if(n===void 0)return!1;let a=n.trim();return a===`0`||a===`false`}function isPidAlive(n){try{if(existsSync(`/proc/self`))return existsSync(`/proc/${n}`)}catch{}try{return process.kill(n,0),!0}catch(n){return n.code===`EPERM`}}function mtimeMs(n){try{return statSync(n).mtimeMs}catch{return null}}function assessLock(n){let a=rs(n,fM),S=null;try{S=JSON.parse(readFileSync(a,`utf-8`))}catch{S=null}let C=Date.now();if(S&&typeof S.pid==`number`){if(!isPidAlive(S.pid))return{stale:!0,reason:`owner pid ${S.pid} is gone`,ownerPid:S.pid};let n=typeof S.startedAt==`number`?S.startedAt:mtimeMs(a);return n!==null&&C-n>staleMs()?{stale:!0,reason:`owner pid ${S.pid} exceeded the ${staleMs()}ms staleness budget`,ownerPid:S.pid}:{stale:!1,ownerPid:S.pid}}let N=mtimeMs(n);return N===null?{stale:!1}:C-N>mM?{stale:!0,reason:`no owner recorded within the acquire grace period`}:{stale:!1}}function stealStaleLock(n){let a=`${n}.stale-${process.pid}-${++vM}`;try{renameSync(n,a)}catch{return!1}try{rmSync(a,{recursive:!0,force:!0})}catch{}return!0}function abortErr(n){let a=n&&`reason`in n?n.reason:void 0;if(a instanceof Error)return a;let S=Error(`Aborted`);return S.name=`AbortError`,S}function delay(n,a){return n<=0?Promise.resolve():new Promise((S,C)=>{let onAbort=()=>{clearTimeout(N),C(abortErr(a))},N=setTimeout(()=>{a?.removeEventListener?.(`abort`,onAbort),S()},n);if(a?.aborted){clearTimeout(N),C(abortErr(a));return}a?.addEventListener?.(`abort`,onAbort,{once:!0})})}function makeHandle(n){let a=!1;return{release(){if(a)return;a=!0;let S=_M.get(n);if(S&&(S.count--,!(S.count>0))){_M.delete(n);try{let a=JSON.parse(readFileSync(rs(n,fM),`utf-8`));if(a.nonce!==void 0&&a.nonce!==S.nonce)return}catch{}try{rmSync(n,{recursive:!0,force:!0})}catch{}}}}}async function acquireInstallLock(n,a={}){if(lockingDisabled())return{release(){}};let S;try{S=realpathSync(n)}catch{S=es(n)}let C=rs(S,`node_modules`,dM),N=_M.get(C);if(N)return N.count++,makeHandle(C);mkdirSync(os(C),{recursive:!0});let F=`${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`,I=hM,H=!1;for(;;){if(a.signal?.aborted)throw abortErr(a.signal);try{return mkdirSync(C),writeFileSync(rs(C,fM),JSON.stringify({pid:process.pid,nonce:F,startedAt:Date.now()})),_M.set(C,{count:1,nonce:F}),makeHandle(C)}catch(n){if(n.code!==`EEXIST`)throw n}let n=assessLock(C);if(n.stale){stealStaleLock(C)&&ke.warn(`gjsify install: removed stale install lock (${n.reason}) — ${C}`);continue}if(!H){H=!0;let a=n.ownerPid===void 0?``:` (pid ${n.ownerPid})`;ke.warn(`gjsify install: waiting for a concurrent install${a} to release ${C} …`)}await delay(I,a.signal),I=Math.min(Math.round(I*1.6),gM)}}var dM,fM,pM,mM,hM,gM,_M,vM,yM=__esmMin(()=>{Ae(),Qc(),ms(),dM=`.gjsify-install-lock`,fM=`owner.json`,pM=35*6e4,mM=15e3,hM=150,gM=1e3,_M=new Map,vM=0});function cacheRoot$1(){return gjsifyCacheRoot(`tarballs`,bM)}function parseSri$1(n){if(!n)return null;let a=n.indexOf(`-`);if(a<=0||a===n.length-1)return null;let S=n.slice(0,a),C=n.slice(a+1).replace(/=+$/,``),N;try{N=Buffer.from(C,`base64`).toString(`hex`)}catch{return null}return N.length<4?null:{algorithm:S,hex:N}}function pathFor$1(n){let a=parseSri$1(n);if(!a)return null;let S=a.hex.slice(0,2);return rs(cacheRoot$1(),a.algorithm,S,`${a.hex}.tgz`)}function getCachedTarball(n){let a=pathFor$1(n);return a?readCacheFile(a):null}function putCachedTarball(n,a){let S=pathFor$1(n);S&&(existsSync(S)||atomicWrite(S,a))}function npmCacacheContentDir(){let n=process.env.GJSIFY_NPM_CACHE;if(n!==void 0){let a=n.trim();return a===``||a===`0`||a===`false`?null:rs(a.endsWith(`_cacache`)?a:rs(a,`_cacache`),`content-v2`)}let a=process.env.npm_config_cache;return rs(a&&a.length>0?a:rs(homedir(),`.npm`),`_cacache`,`content-v2`)}function npmCachePathFor(n){let a=npmCacacheContentDir();if(!a)return null;let S=parseSri$1(n);return S?rs(a,S.algorithm,S.hex.slice(0,2),S.hex.slice(2,4),S.hex.slice(4)):null}function getForeignCachedTarball(n){let a=npmCachePathFor(n);return a?readCacheFile(a):null}var bM,xM=__esmMin(()=>{Qc(),Gp(),ms(),uM(),bM=`v1`,__name$1(cacheRoot$1,`cacheRoot`),__name$1(parseSri$1,`parseSri`),__name$1(pathFor$1,`pathFor`)});function isEnabled(){let n=process.env.GJSIFY_PACKUMENT_CACHE;if(n===void 0)return!0;let a=n.trim();return!(a===`0`||a===`false`||a===``)}function cacheRoot(){return gjsifyCacheRoot(`metadata`,SM)}function shardFor(n){let a=2166136261;for(let S=0;S<n.length;S++)a^=n.charCodeAt(S),a=Math.imul(a,16777619);return(a>>>0&255).toString(16).padStart(2,`0`)}function pathFor(n,a){if(!isEnabled())return null;let S=`${n}|${a}`,C=`${encodeURIComponent(n)}|${encodeURIComponent(a)}.json`;return rs(cacheRoot(),shardFor(S),C)}function getCachedPackument(n,a){let S=pathFor(n,a);if(!S)return null;let C=readCacheFile(S);if(!C)return null;try{let n=JSON.parse(C.toString(`utf-8`));return typeof n.etag!=`string`||!n.etag||!n.packument||typeof n.packument!=`object`?null:{etag:n.etag,packument:n.packument}}catch{return null}}function putCachedPackument(n,a,S,C){if(!S)return;let N=pathFor(n,a);N&&atomicWrite(N,JSON.stringify({etag:S,packument:C}))}var SM,CM=__esmMin(()=>{ms(),uM(),SM=`v1`});function parseNodeMajor(n){return Number.parseInt(String(n).split(`.`,1)[0]??``,10)}function nativeBackendNodeError(n,a){if(!a)return null;let S=parseNodeMajor(n);return!Number.isFinite(S)||S>=24?null:`gjsify install (native backend) requires Node ≥ 24, but this is Node ${n}. Its prebuilt native modules are ABI-locked to Node 24 and crash on older majors. Use Node 24 (nvm/asdf locally, actions/setup-node in CI), or run with --backend npm.`}function onRealNode(){return gjsSystemVersion()===void 0?isNode():!1}function assertNativeBackendNodeVersion(){let n=nativeBackendNodeError(process.versions.node,onRealNode());if(n)throw Error(n)}var wM=__esmMin(()=>{sm()}),TM=__exportAll$3({installPackagesNative:()=>installPackagesNative,parseSpec:()=>parseSpec,pickVersion:()=>pickVersion,warnMissingNativeBuilds:()=>warnMissingNativeBuilds});async function installPackagesNative(n){if(assertNativeBackendNodeVersion(),n.specs.length===0)throw Error(`installPackagesNative: empty specs list`);mkdirSync(n.prefix,{recursive:!0});let a=await loadNpmrc$1(n),S=makeLogger(n.verbose??!1),C=await acquireInstallLock(n.prefix,{signal:n.signal});try{return await installPackagesNativeLocked(n,a,S)}finally{C.release()}}async function installPackagesNativeLocked(n,a,S){let C=n.progress,N=rs(n.prefix,DM),F=readLockfile(N),I;if(n.frozen){if(!F)throw Error(`install: --immutable requires ${DM} at ${n.prefix} — none found. Run \`gjsify install\` (without --immutable) to generate one and commit it.`);let a=describeLockfileDrift(F,n.specs);if(a)throw Error(`install: --immutable but ${N} is stale.\n${a}\nRe-run \`gjsify install\` (without --immutable) to refresh the lockfile.`);S(`install: --immutable, using lockfile (%d package(s))`,Object.keys(F.packages).length),I=lockfileToNodes(F)}else if(!n.refreshLockfile&&F&&lockfileMatchesRequest(F,n.specs))S(`install: using lockfile (%d package(s))`,Object.keys(F.packages).length),I=lockfileToNodes(F);else{let H=!n.refreshLockfile&&F?buildPreferredVersions(F):void 0;S(`install: resolving %d top-level spec(s) → %s%s`,n.specs.length,n.prefix,H?` (preserving ${H.size} locked name(s))`:``),I=await resolveDeps(n.specs,a,S,n.overrides,n.skipDeps,n.signal,C,H,n.workspaceNames,n.specOrigins),n.lockfile&&(writeLockfile(N,n.specs,I),S(`install: wrote %s (%d entries)`,DM,I.length))}if(n.workspaceNames&&n.workspaceNames.size>0){let a=I.length;I=I.filter(a=>!n.workspaceNames.has(a.name));let C=a-I.length;C>0&&S(`install: %d workspace-provided package(s) symlinked, not fetched`,C)}return S(`install: downloading %d tarball(s)`,I.length),await downloadAndExtractAll(I,n.prefix,a,S,n.signal,C),await linkBins(I,n.prefix,S),warnMissingNativeBuilds(I,n.prefix,S),S(`install: done`),topLevelResolutions(n.specs,I)}function errMsg(n){return n instanceof Error?n.message:String(n)}function warnMissingNativeBuilds(n,a,S){let C=process.platform,N=process.arch,F=[`preinstall`,`install`,`postinstall`];for(let I of n){let n=rs(a,I.installPath),H;try{H=JSON.parse(readFileSync(rs(n,`package.json`),`utf8`))?.scripts}catch{continue}if(!H||typeof H!=`object`)continue;let W=F.find(n=>typeof H[n]==`string`);if(W===void 0)continue;let K=!1;try{let a=rs(n,`prebuilds`);for(let n of readdirSync(a))if(n.startsWith(`${C}-`)&&readdirSync(rs(a,n)).length>0){K=!0;break}}catch{}if(!K)try{K=readdirSync(rs(n,`build`,`Release`)).some(n=>n.endsWith(`.node`)||n.endsWith(`.so`))}catch{}K||S("install: WARNING — %s declares a native `%s` build script but ships no %s-%s prebuild, and gjsify install does not run build scripts (node-free). It will not load until built: run `node-gyp rebuild` in %s, or use a version that ships a %s-%s prebuild.",I.name,W,C,N,I.installPath,C,N)}}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,N,F,I,H,W,K){I?.beginPhase(`resolve`,n.length);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)},q=new Map,fetchPkg=n=>{let C=q.get(n);if(C)return C;let N=fetchPackumentWithDiskCache(n,a,S,F);return q.set(n,N),N},Y=new Map,X=new Map,te=new Map,ne=n.map(parseSpec).map(n=>{let a=applyOverride(n.name,n.range),S=te.get(n.name);S||(S=new Map,te.set(n.name,S));let C=S.get(a);C||(C=new Set,S.set(a,C));for(let a of K?.get(`${n.name}@${n.range}`)??[])C.add(a);return{from:null,name:n.name,range:a,required:!0}});for(;ne.length>0;){let n=ne.splice(0,ne.length),a=[],C=new Set;for(let S of n)q.has(S.name)||C.has(S.name)||(C.add(S.name),a.push(S.name));await prefetchPackuments(a,fetchPkg,F);for(let a=0;a<n.length;a++){let C=n[a];if(W?.has(C.name))continue;let F=findVisible(C.from,C.name,Y);if(F&&satisfiesRange(F.version,C.range))continue;let K=null;try{let F=await fetchPkg(C.name),W=preferredVersionFor(H?.get(C.name),C.range);if(K=pickVersion(F,C.range,W),!K){if(!C.required)continue;throw Error(`No version of ${C.name} satisfies ${C.range}`)}let q=F.versions[K];if(!q)throw Error(`Packument for ${C.name} promised ${K} but no entry exists`);let te=decidePlacement(C.from,C.name,K,X),re={name:C.name,version:K,tarballUrl:q.dist.tarball,integrity:q.dist.integrity,installPath:te,dependencies:q.dependencies??{},optionalDependencies:q.optionalDependencies??{},bin:q.bin};if(Y.set(te,re),te===`node_modules/${C.name}`&&X.set(C.name,re),S(`resolve: %s@%s ← %s (at %s)`,C.name,K,C.range,te),I?.update({phase:`resolve`,current:Y.size,total:Y.size+(n.length-a-1)+ne.length,name:`${C.name}@${K}`}),!N){for(let[n,a]of Object.entries(re.dependencies))ne.push({from:te,name:n,range:applyOverride(n,a),required:!0});for(let[n,a]of Object.entries(re.optionalDependencies))ne.push({from:te,name:n,range:applyOverride(n,a),required:!1})}}catch(n){if(!C.required){S(`resolve: optional dep %s@%s skipped (%s)`,C.name,C.range,n.message);continue}throw n}}}return I?.endPhase(`resolve`),emitTopLevelConflictWarnings(te,X),Array.from(Y.values())}function emitTopLevelConflictWarnings(n,a){for(let[S,C]of n){if(C.size<2)continue;let n=a.get(S);if(!n)continue;let describe=(n,a)=>a.size>0?`${n} (requested by ${[...a].join(`, `)})`:n,N=[],F=[];for(let[a,S]of C){let C;try{C=satisfies(n.version,new tM(a))}catch{continue}(C?N:F).push(describe(a,S))}F.length!==0&&ke.warn(`[gjsify] warning: version conflict for ${S}: installed ${n.version} at ${n.installPath} — does NOT satisfy ${F.join(`, `)}`+(N.length>0?`; satisfies ${N.join(`, `)}`:``)+`. One hoisted copy serves all requesters until the per-workspace dedup pass lands (Phase D.8).`)}}async function fetchPackumentWithDiskCache(n,a,S,C){let N=registryFor(n,a),F=getCachedPackument(N,n),onRetry=({attempt:a,error:C,delayMs:N})=>{S(`packument %s: retry %d after %dms (%s)`,n,a,N,errMsg(C))},I=await fetchPackumentConditional(n,{npmrc:a,signal:C,ifNoneMatch:F?.etag,onRetry});return I.status===`not-modified`&&F?(S(`packument-cache-hit: %s (304, etag %s)`,n,F.etag),F.packument):I.status===`fresh`&&I.packument?(I.etag&&putCachedPackument(N,n,I.etag,I.packument),I.packument):fetchPackument(n,{npmrc:a,signal:C,onRetry})}async function prefetchPackuments(n,a,S){if(n.length===0)return;let C=0,N=Math.max(1,Math.min(EM,n.length)),worker=async()=>{for(;C<n.length;){if(S?.aborted)return;let N=n[C++];try{await a(N)}catch{}}};await Promise.all(Array.from({length:N},()=>worker()))}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 tM(a))}catch{return!1}}function readLockfile(n){if(!existsSync(n))return null;try{let a=JSON.parse(readFileSync(n,`utf-8`));return a.lockfileVersion!==OM||!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:OM,requested:[...a],packages:C};atomicWriteStrict(n,JSON.stringify(F,null,2)+`
|
|
763
763
|
`)}function buildPreferredVersions(n){let a=new Map;for(let[S,C]of Object.entries(n.packages)){let n=nameFromInstallPath(S),N=a.get(n);N||(N=new Set,a.set(n,N)),N.add(C.version)}return a}function preferredVersionFor(n,a){if(!n||n.size===0)return;let S;for(let C of n)satisfiesRange(C,a)&&(S===void 0||new SemVer(C).compare(new SemVer(S))>0)&&(S=C);return S}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(`
|
|
764
764
|
+ `)}`),F.length>0&&I.push(` - ${F.sort().join(`
|
|
765
765
|
- `)}`),I.join(`
|
|
@@ -4,11 +4,42 @@ interface ParsedSpec {
|
|
|
4
4
|
name: string;
|
|
5
5
|
range: string;
|
|
6
6
|
}
|
|
7
|
+
interface ResolvedNode {
|
|
8
|
+
/** Package name (e.g. `@gjsify/cli`, `lodash`). */
|
|
9
|
+
name: string;
|
|
10
|
+
version: string;
|
|
11
|
+
tarballUrl: string;
|
|
12
|
+
integrity?: string;
|
|
13
|
+
/** Where this node lives relative to the install prefix. Always
|
|
14
|
+
* starts with `node_modules/`; nested entries look like
|
|
15
|
+
* `node_modules/<parent>/node_modules/<dep>`. */
|
|
16
|
+
installPath: string;
|
|
17
|
+
/** `dependencies` field from the packument (range strings keyed by name). */
|
|
18
|
+
dependencies: Record<string, string>;
|
|
19
|
+
/** `optionalDependencies` field from the packument. */
|
|
20
|
+
optionalDependencies: Record<string, string>;
|
|
21
|
+
bin?: string | Record<string, string>;
|
|
22
|
+
}
|
|
7
23
|
export interface InstalledTopLevel {
|
|
8
24
|
name: string;
|
|
9
25
|
version: string;
|
|
10
26
|
}
|
|
11
27
|
export declare function installPackagesNative(opts: InstallOptions): Promise<InstalledTopLevel[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Warn about a native package that installed WITHOUT a usable binary.
|
|
30
|
+
*
|
|
31
|
+
* gjsify install is node-free (it runs under GJS) and does NOT run a package's
|
|
32
|
+
* `install`/`postinstall` lifecycle script — running e.g. `node-gyp rebuild` would
|
|
33
|
+
* need Node + a C++ toolchain, breaking that property (see the header's "out of
|
|
34
|
+
* scope"). Such a package works only if it SHIPS a prebuild for the platform (the
|
|
35
|
+
* sanctioned path — `prebuilds/<platform>-<arch>/…`) or is later built by hand. When
|
|
36
|
+
* neither is present the package silently loads no binary (the `@gjsify/node-gi
|
|
37
|
+
* 0.21.0` case: installed, but `node_gi.node` absent → the consumer hit a runtime
|
|
38
|
+
* failure with no hint). Surface it at install time with an actionable line. Pure
|
|
39
|
+
* detection — no script is run, so node-free-ness is preserved.
|
|
40
|
+
*/
|
|
41
|
+
export declare function warnMissingNativeBuilds(nodes: ResolvedNode[], prefix: string, log: Logger): void;
|
|
12
42
|
export declare function parseSpec(raw: string): ParsedSpec;
|
|
13
43
|
export declare function pickVersion(packument: Packument, range: string, preferred?: string): string | null;
|
|
44
|
+
type Logger = (fmt: string, ...args: unknown[]) => void;
|
|
14
45
|
export {};
|
|
@@ -121,6 +121,7 @@ async function installPackagesNativeLocked(opts, npmrc, log) {
|
|
|
121
121
|
log('install: downloading %d tarball(s)', nodes.length);
|
|
122
122
|
await downloadAndExtractAll(nodes, opts.prefix, npmrc, log, opts.signal, progress);
|
|
123
123
|
await linkBins(nodes, opts.prefix, log);
|
|
124
|
+
warnMissingNativeBuilds(nodes, opts.prefix, log);
|
|
124
125
|
log('install: done');
|
|
125
126
|
// Surface the top-level requested packages so callers can update
|
|
126
127
|
// package.json with the resolved version (mirrors `npm install --save`
|
|
@@ -132,6 +133,71 @@ function errMsg(err) {
|
|
|
132
133
|
return err.message;
|
|
133
134
|
return String(err);
|
|
134
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Warn about a native package that installed WITHOUT a usable binary.
|
|
138
|
+
*
|
|
139
|
+
* gjsify install is node-free (it runs under GJS) and does NOT run a package's
|
|
140
|
+
* `install`/`postinstall` lifecycle script — running e.g. `node-gyp rebuild` would
|
|
141
|
+
* need Node + a C++ toolchain, breaking that property (see the header's "out of
|
|
142
|
+
* scope"). Such a package works only if it SHIPS a prebuild for the platform (the
|
|
143
|
+
* sanctioned path — `prebuilds/<platform>-<arch>/…`) or is later built by hand. When
|
|
144
|
+
* neither is present the package silently loads no binary (the `@gjsify/node-gi
|
|
145
|
+
* 0.21.0` case: installed, but `node_gi.node` absent → the consumer hit a runtime
|
|
146
|
+
* failure with no hint). Surface it at install time with an actionable line. Pure
|
|
147
|
+
* detection — no script is run, so node-free-ness is preserved.
|
|
148
|
+
*/
|
|
149
|
+
export function warnMissingNativeBuilds(nodes, prefix, log) {
|
|
150
|
+
const plat = process.platform;
|
|
151
|
+
const arch = process.arch;
|
|
152
|
+
const buildScriptKeys = ['preinstall', 'install', 'postinstall'];
|
|
153
|
+
for (const n of nodes) {
|
|
154
|
+
const pkgDir = path.join(prefix, n.installPath);
|
|
155
|
+
let scripts;
|
|
156
|
+
try {
|
|
157
|
+
const manifest = JSON.parse(fs.readFileSync(path.join(pkgDir, 'package.json'), 'utf8'));
|
|
158
|
+
scripts = manifest?.scripts;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
continue; // no/unreadable manifest — nothing to assess
|
|
162
|
+
}
|
|
163
|
+
if (!scripts || typeof scripts !== 'object')
|
|
164
|
+
continue;
|
|
165
|
+
const scriptKey = buildScriptKeys.find((k) => typeof scripts[k] === 'string');
|
|
166
|
+
if (scriptKey === undefined)
|
|
167
|
+
continue; // no native build lifecycle script
|
|
168
|
+
// Does it ship a prebuild for THIS platform (any prebuilds/<plat>-…/ with a
|
|
169
|
+
// file), or carry a locally-built build/Release binary?
|
|
170
|
+
let hasBinary = false;
|
|
171
|
+
try {
|
|
172
|
+
const prebuildsDir = path.join(pkgDir, 'prebuilds');
|
|
173
|
+
for (const entry of fs.readdirSync(prebuildsDir)) {
|
|
174
|
+
if (entry.startsWith(`${plat}-`) && fs.readdirSync(path.join(prebuildsDir, entry)).length > 0) {
|
|
175
|
+
hasBinary = true;
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
/* no prebuilds dir */
|
|
182
|
+
}
|
|
183
|
+
if (!hasBinary) {
|
|
184
|
+
try {
|
|
185
|
+
const releaseDir = path.join(pkgDir, 'build', 'Release');
|
|
186
|
+
hasBinary = fs
|
|
187
|
+
.readdirSync(releaseDir)
|
|
188
|
+
.some((f) => f.endsWith('.node') || f.endsWith('.so'));
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
/* no build/Release */
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (!hasBinary) {
|
|
195
|
+
log('install: WARNING — %s declares a native `%s` build script but ships no %s-%s prebuild, ' +
|
|
196
|
+
'and gjsify install does not run build scripts (node-free). It will not load until built: ' +
|
|
197
|
+
'run `node-gyp rebuild` in %s, or use a version that ships a %s-%s prebuild.', n.name, scriptKey, plat, arch, n.installPath, plat, arch);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
135
201
|
function topLevelResolutions(specs, nodes) {
|
|
136
202
|
// Top-level installs live at `node_modules/<name>` (no nesting). Build
|
|
137
203
|
// a name → root-node lookup limited to the top-level set.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "CLI for Gjsify",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -125,19 +125,19 @@
|
|
|
125
125
|
"cli"
|
|
126
126
|
],
|
|
127
127
|
"dependencies": {
|
|
128
|
-
"@gjsify/buffer": "^0.
|
|
129
|
-
"@gjsify/create-app": "^0.
|
|
130
|
-
"@gjsify/node-globals": "^0.
|
|
131
|
-
"@gjsify/node-polyfills": "^0.
|
|
132
|
-
"@gjsify/npm-registry": "^0.
|
|
133
|
-
"@gjsify/resolve-npm": "^0.
|
|
134
|
-
"@gjsify/rolldown-plugin-gjsify": "^0.
|
|
135
|
-
"@gjsify/rolldown-plugin-pnp": "^0.
|
|
136
|
-
"@gjsify/semver": "^0.
|
|
137
|
-
"@gjsify/tar": "^0.
|
|
138
|
-
"@gjsify/tsc": "^0.
|
|
139
|
-
"@gjsify/web-polyfills": "^0.
|
|
140
|
-
"@gjsify/workspace": "^0.
|
|
128
|
+
"@gjsify/buffer": "^0.22.0",
|
|
129
|
+
"@gjsify/create-app": "^0.22.0",
|
|
130
|
+
"@gjsify/node-globals": "^0.22.0",
|
|
131
|
+
"@gjsify/node-polyfills": "^0.22.0",
|
|
132
|
+
"@gjsify/npm-registry": "^0.22.0",
|
|
133
|
+
"@gjsify/resolve-npm": "^0.22.0",
|
|
134
|
+
"@gjsify/rolldown-plugin-gjsify": "^0.22.0",
|
|
135
|
+
"@gjsify/rolldown-plugin-pnp": "^0.22.0",
|
|
136
|
+
"@gjsify/semver": "^0.22.0",
|
|
137
|
+
"@gjsify/tar": "^0.22.0",
|
|
138
|
+
"@gjsify/tsc": "^0.22.0",
|
|
139
|
+
"@gjsify/web-polyfills": "^0.22.0",
|
|
140
|
+
"@gjsify/workspace": "^0.22.0",
|
|
141
141
|
"cosmiconfig": "^9.0.2",
|
|
142
142
|
"get-tsconfig": "^4.14.0",
|
|
143
143
|
"pkg-types": "^2.3.1",
|
|
@@ -145,13 +145,13 @@
|
|
|
145
145
|
"yargs": "^18.0.0"
|
|
146
146
|
},
|
|
147
147
|
"devDependencies": {
|
|
148
|
-
"@gjsify/unit": "^0.
|
|
148
|
+
"@gjsify/unit": "^0.22.0",
|
|
149
149
|
"@types/yargs": "^17.0.35",
|
|
150
150
|
"typescript": "^6.0.3"
|
|
151
151
|
},
|
|
152
152
|
"peerDependencies": {
|
|
153
|
-
"@gjsify/oxfmt-native": "^0.
|
|
154
|
-
"@gjsify/rolldown-native": "^0.
|
|
153
|
+
"@gjsify/oxfmt-native": "^0.22.0",
|
|
154
|
+
"@gjsify/rolldown-native": "^0.22.0"
|
|
155
155
|
},
|
|
156
156
|
"peerDependenciesMeta": {
|
|
157
157
|
"@gjsify/oxfmt-native": {
|