From 1c8d652ef3b0ea079dc3590ba04429be9401a10e Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 8 Oct 2026 13:50:15 +0800 Subject: [PATCH 1/2] fix: verify installer scripts with bundled checksums --- CONTRIBUTING.md | 22 ++ README.md | 14 + dist/azure/index.mjs | 63 +++- dist/gitlab/index.mjs | 61 +++- dist/index.mjs | 61 +++- scripts/update-installer-checksums.mjs | 41 +++ src/azure/install-viteplus.test.ts | 35 +- src/ci/install-script-urls.test.ts | 77 ++-- src/ci/install-script-urls.ts | 98 ++--- src/ci/install-viteplus.ts | 31 +- src/ci/installer-checksums.json | 477 +++++++++++++++++++++++++ src/ci/installer-integrity.test.ts | 112 ++++++ src/ci/vp-dirs.test.ts | 78 ++-- src/ci/vp-dirs.ts | 108 ++++-- src/install-viteplus.test.ts | 91 ++--- src/install-viteplus.ts | 32 +- 16 files changed, 1117 insertions(+), 284 deletions(-) create mode 100644 scripts/update-installer-checksums.mjs create mode 100644 src/ci/installer-checksums.json create mode 100644 src/ci/installer-integrity.test.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8382772..30bac12 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -72,6 +72,28 @@ The PR's `rebuild-bundle.yml` must match the default branch before the publisher Renovate opens a PR when SocketDev publishes a new `sfw-free` release. The custom manager in [`.github/renovate.json`](.github/renovate.json) updates the shared `SFW_VERSION` pin in `src/ci/install-sfw.ts` for all three integrations. +### Installer Checksum Pins + +`src/ci/installer-checksums.json` is the trust source for installer downloads in +all three integrations. It records immutable upstream commits and SHA-256 +checksums. Historical pins keep older installer directory layouts available. +The default pin also serves dist-tags, unknown versions, and preview builds. + +To add a pin, review `packages/cli/install.sh` and `packages/cli/install.ps1` at +the intended commit in `voidzero-dev/vite-plus`. Review any scripts they execute, +including `install-legacy.sh` and `install-legacy.ps1`. Then run: + +```bash +node scripts/update-installer-checksums.mjs +``` + +Add `--default` to select the new default installer. The command fetches the +scripts without executing them and records their checksums, including the +legacy helpers when present. It does not run during installation or builds. +Review the manifest diff and rebuild all three bundles. Do not add a runtime +checksum lookup or an unverified download fallback. If upstream adds another +script dependency, extend verification before approving that installer. + ## Releasing Publish releases as Git tags, not as an npm package. Keep `package.json.version` aligned with the release tag. Consumers pin an exact tag such as `voidzero-dev/setup-vp@v1.21.1` or a commit SHA. Do not move the `v1` major tag, which is frozen at `v1.15.0`. diff --git a/README.md b/README.md index 79d3974..517d487 100644 --- a/README.md +++ b/README.md @@ -379,6 +379,20 @@ Separate package-manager modes require Vite+ 0.3.1+. Any explicit configuration, | `version` | The installed version of Vite+ | | `cache-hit` | Boolean indicating if cache was restored | +## Installer integrity + +GitHub Actions, GitLab, and Azure download installer scripts from immutable +upstream commits and check their SHA-256 checksums before execution. The expected +checksums ship with setup-vp. Both download mirrors use the same checksums, and +the installer's legacy helper is also verified before execution. + +Known versions use their matching installer. Dist-tags, preview builds, and +versions without a bundled checksum use the checksum-pinned default installer. +If all sources for a known version fail, setup-vp also tries that default. +The requested CLI version is unchanged. Update setup-vp when a newer CLI requires +an installer that its current checksum pins do not support. These checksums cover +installer scripts; the installer still downloads the requested CLI packages. + ## Caching ### Reuse an installed version diff --git a/dist/azure/index.mjs b/dist/azure/index.mjs index aaad74e..a99f81b 100644 --- a/dist/azure/index.mjs +++ b/dist/azure/index.mjs @@ -138,15 +138,15 @@ n?this.stack.push(n):(yield*this.pop(),yield*this.step())}else{let t=this.peek(2 `)+1;for(;e!==0;)this.onNewLine(this.offset+e),e=this.source.indexOf(` `,e)+1}return{type:e,offset:this.offset,indent:this.indent,source:this.source}}startBlockValue(e){switch(this.type){case`alias`:case`scalar`:case`single-quoted-scalar`:case`double-quoted-scalar`:return this.flowScalar(this.type);case`block-scalar-header`:return{type:`block-scalar`,offset:this.offset,indent:this.indent,props:[this.sourceToken],source:``};case`flow-map-start`:case`flow-seq-start`:return{type:`flow-collection`,offset:this.offset,indent:this.indent,start:this.sourceToken,items:[],end:[]};case`seq-item-ind`:return{type:`block-seq`,offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken]}]};case`explicit-key-ind`:{this.onKeyLine=!0;let t=getFirstKeyStartProps(getPrevProps(e));return t.push(this.sourceToken),{type:`block-map`,offset:this.offset,indent:this.indent,items:[{start:t,explicitKey:!0}]}}case`map-value-ind`:{this.onKeyLine=!0;let t=getFirstKeyStartProps(getPrevProps(e));return{type:`block-map`,offset:this.offset,indent:this.indent,items:[{start:t,key:null,sep:[this.sourceToken]}]}}}return null}atIndentedComment(e,t){return this.type!==`comment`||this.indent<=t?!1:e.every(e=>e.type===`newline`||e.type===`space`)}*documentEnd(e){this.type!==`doc-mode`&&(e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type===`newline`&&(yield*this.pop()))}*lineEnd(e){switch(this.type){case`comma`:case`doc-start`:case`doc-end`:case`flow-seq-end`:case`flow-map-end`:case`map-value-ind`:yield*this.pop(),yield*this.step();break;case`newline`:this.onKeyLine=!1;default:e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type===`newline`&&(yield*this.pop())}}}})),Qe=/* @__PURE__ */ __commonJSMin((e=>{var t=We(),n=G(),r=K(),i=le(),a=O(),o=Xe(),s=Ze();function parseOptions(e){let t=e.prettyErrors!==!1;return{lineCounter:e.lineCounter||t&&new o.LineCounter||null,prettyErrors:t}}function parseAllDocuments(e,n={}){let{lineCounter:i,prettyErrors:a}=parseOptions(n),o=new s.Parser(i?.addNewLine),c=new t.Composer(n),l=Array.from(c.compose(o.parse(e)));if(a&&i)for(let t of l)t.errors.forEach(r.prettifyError(e,i)),t.warnings.forEach(r.prettifyError(e,i));return l.length>0?l:Object.assign([],{empty:!0},c.streamInfo())}function parseDocument(e,n={}){let{lineCounter:i,prettyErrors:a}=parseOptions(n),o=new s.Parser(i?.addNewLine),c=new t.Composer(n),l=null;for(let t of c.compose(o.parse(e),!0,e.length))if(!l)l=t;else if(l.options.logLevel!==`silent`){l.errors.push(new r.YAMLParseError(t.range.slice(0,2),`MULTIPLE_DOCS`,`Source contains multiple documents; please use YAML.parseAllDocuments()`));break}return a&&i&&(l.errors.forEach(r.prettifyError(e,i)),l.warnings.forEach(r.prettifyError(e,i))),l}function parse(e,t,n){let r;typeof t==`function`?r=t:n===void 0&&t&&typeof t==`object`&&(n=t);let a=parseDocument(e,n);if(!a)return null;if(a.warnings.forEach(e=>i.warn(a.options.logLevel,e)),a.errors.length>0){if(a.options.logLevel!==`silent`)throw a.errors[0];a.errors=[]}return a.toJS(Object.assign({reviver:r},n))}function stringify(e,t,r){let i=null;if(typeof t==`function`||Array.isArray(t)?i=t:r===void 0&&t&&(r=t),typeof r==`string`&&(r=r.length),typeof r==`number`){let e=Math.round(r);r=e<1?void 0:e>8?{indent:8}:{indent:e}}if(e===void 0){let{keepUndefined:e}=r??t??{};if(!e)return}return a.isDocument(e)&&!i?e.toString(r):new n.Document(e,i,r).toString(r)}e.parse=parse,e.parseAllDocuments=parseAllDocuments,e.parseDocument=parseDocument,e.stringify=stringify})),Y=(/* @__PURE__ */ __commonJSMin((e=>{var t=We(),n=G(),r=ke(),i=K(),a=M(),o=O(),s=R(),c=N(),l=z(),u=V();Je();var d=Ye(),f=Xe(),p=Ze(),m=Qe(),h=k();e.Composer=t.Composer,e.Document=n.Document,e.Schema=r.Schema,e.YAMLError=i.YAMLError,e.YAMLParseError=i.YAMLParseError,e.YAMLWarning=i.YAMLWarning,e.Alias=a.Alias,e.isAlias=o.isAlias,e.isCollection=o.isCollection,e.isDocument=o.isDocument,e.isMap=o.isMap,e.isNode=o.isNode,e.isPair=o.isPair,e.isScalar=o.isScalar,e.isSeq=o.isSeq,e.Pair=s.Pair,e.Scalar=c.Scalar,e.YAMLMap=l.YAMLMap,e.YAMLSeq=u.YAMLSeq,e.Lexer=d.Lexer,e.LineCounter=f.LineCounter,e.Parser=p.Parser,e.parse=m.parse,e.parseAllDocuments=m.parseAllDocuments,e.parseDocument=m.parseDocument,e.stringify=m.stringify,e.visit=h.visit,e.visitAsync=h.visitAsync})))();function parseInstalledVpVersion(e){return(e.match(/^\s*vp\s+v?(\d[^\s]*)/im)??e.match(/Global:\s*v?(\d[^\s]*)/i))?.[1]??`unknown`}const $e=/* @__PURE__ */ new Set([`true`,`True`,`TRUE`]),et=/* @__PURE__ */ new Set([`false`,`False`,`FALSE`]);function parseNodeManager(e){if(e){if($e.has(e))return!0;if(et.has(e))return!1;throw Error(`Invalid node-manager input: "${e}". Expected "true", "false", or unset.`)}}function supportsScopedEnv(e){let t=parseInstalledVpVersion(e);if(t.startsWith(`0.0.0-commit.`))return!0;let n=t.match(/^(\d+)\.(\d+)\.(\d+)/);if(!n)throw Error(`Could not determine the installed Vite+ version for env configuration.`);let[,r,i,a]=n.map(Number);return r>0||i>3||i===3&&a>=1}function nodeManagerOffArgs(e){return parseInstalledVpVersion(e).startsWith(`0.0.0-commit.`)&&console.info("setup-vp: node-manager: false requires a preview build that supports `vp env off node`. If this command is unsupported, use a newer preview or a stable release. setup-vp will not fall back to disabling package-manager management."),supportsScopedEnv(e)?[`env`,`off`,`node`]:[`env`,`off`]}const tt=[`npm`,`pnpm`,`yarn`,`bun`];function parsePackageManager(e){if(!e?.trim())return;let t;try{t=(0,Y.parse)(e)}catch(e){throw Error(`Invalid package-manager input: ${String(e)}`)}if(t!==``){if(typeof t==`boolean`)return t;if(t&&typeof t==`object`&&!Array.isArray(t)){for(let[e,n]of Object.entries(t))if(!tt.includes(e)||typeof n!=`boolean`)throw Error(`Invalid package-manager input: ${e} must be npm, pnpm, yarn, or bun with a boolean value.`);return t}throw Error(`Invalid package-manager input: expected a boolean or a mapping of npm, pnpm, yarn, and bun to booleans.`)}}function packageManagerArgs(e,t){if(e===void 0)return[];if(!supportsScopedEnv(t))throw Error(`package-manager configuration requires Vite+ 0.3.1 or newer.`);return typeof e==`boolean`?e?[]:[[`env`,`off`,`pm`]]:tt.filter(t=>e[t]===!1).map(e=>[`env`,`off`,e])}const X=`Vite+`,Z=`vite-plus`;function resolvePath$1(e,t){return u.isAbsolute(e)?e:u.join(t,e)}function isWithin(e,t){let n=u.relative(t,e);return!u.isAbsolute(n)&&n!==`..`&&!n.startsWith(`..${u.sep}`)}function resolveProjectDirectory(e){let{workingDirectory:t,workspaceRoot:n}=e,r=u.isAbsolute(t)?t:u.join(n,t);try{if(!c(r).isDirectory())throw Error(`working-directory is not a directory: ${t} (resolved to ${r})`)}catch(e){throw e instanceof Error&&`code`in e&&e.code===`ENOENT`?Error(`working-directory not found: ${t} (resolved to ${r})`):e}return r}function isWindows(e=process.platform){return e===`win32`}function run(e,t,n={}){let r=y(e,t,{stdio:`inherit`,...n});if(r.error)throw r.error;if(r.status!==0)throw Error(`${e} ${t.join(` `)} exited with code ${r.status??1}`)}function runWithOutput(e,t,n={}){return new Promise((r,i)=>{let a=v(e,t,{...n,stdio:[`ignore`,`pipe`,`pipe`]}),o=``,s=``;a.stdout.on(`data`,e=>{process.stdout.write(e),o=(o+e.toString()).slice(-4e3)}),a.stderr.on(`data`,e=>{process.stderr.write(e),s=(s+e.toString()).slice(-4e3)}),a.on(`error`,i),a.on(`close`,e=>r({exitCode:e??1,stdout:o,stderr:s}))})}function commandPath(e){if(isWindows()){let t=y(`where`,[e],{encoding:`utf8`});return t.status===0&&t.stdout.trim().split(/\r?\n/)[0]?.trim()||void 0}let t=y(`sh`,[`-c`,`command -v "$1"`,`sh`,e],{encoding:`utf8`});if(t.status===0)return t.stdout.trim()}function getCommandOutput(e,t,n){let r=y(e,t,{cwd:n?.cwd,encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`]});if(r.status===0)return r.stdout.trim()}const nt=[{filename:`pnpm-lock.yaml`,type:`pnpm`},{filename:`bun.lockb`,type:`bun`},{filename:`bun.lock`,type:`bun`},{filename:`package-lock.json`,type:`npm`},{filename:`npm-shrinkwrap.json`,type:`npm`},{filename:`yarn.lock`,type:`yarn`}];function resolvePath(e,t){return p(e)?e:m(t,e)}function inferLockFileType(e,t){return t.includes(`pnpm`)?{type:`pnpm`,path:e,filename:t}:t.includes(`yarn`)?{type:`yarn`,path:e,filename:t}:t.startsWith(`bun.`)?{type:`bun`,path:e,filename:t}:{type:`npm`,path:e,filename:t}}function detectLockFile(e,t){if(e){let r=resolvePath(e,t);if(n(r)){let e=d(r),t=nt.find(t=>t.filename===e);return t?{type:t.type,path:r,filename:e}:inferLockFileType(r,e)}return}let r=o(t);for(let e of nt)if(r.includes(e.filename)){let n=m(t,e.filename);return{type:e.type,path:n,filename:e.filename}}}function prepareCacheMetadata(e){let{projectDir:t,cacheDependencyPath:n,logWarning:r}=e,i=detectLockFile(n||void 0,t);if(!i)return r?.(`setup-vp: cache is enabled but no supported lock file was found; skipping cache.`),{ready:!1};let a=getCommandOutput(`vp`,[`pm`,`cache`,`dir`],{cwd:u.dirname(i.path)});return a?{ready:!0,cachePath:a,lockFile:i.path,lockType:i.type}:(r?.(`setup-vp: could not resolve package-manager cache directory for ${i.filename}; skipping cache.`),{ready:!1})}function createLockfileResolver(e){let{getWorkspaceDir:t,info:r,debug:i}=e,o=/^\d+\.\d+\.\d+/;function tryResolveVitePlusVersionFromLockfile(e,t){let n=detectLockfileForProject(e,t);if(!n)return;let a=n.filename.endsWith(`.lockb`)?textBunLockBeside(n):n;if(!a){i(`Cannot read ${n.filename} (binary) to resolve the ${X} version; using "latest". Use the text bun.lock, or set the \`version\` input.`);return}let o=parseVitePlusVersionFromLockfile(a,workspaceSubPath(f(a.path),e));if(o)return r(`Resolved ${X} version '${o}' from ${a.filename}`),o;i(`No ${X} version found in ${a.path}`)}function detectLockfileForProject(e,n){if(n)return detectLockFile(n,e);let r=t(),i=e;for(;;){let e=detectLockFile(void 0,i);if(e)return e;let t=f(i);if(i===r||t===i||!isWithin(t,r))break;i=t}}function textBunLockBeside(e){let t=m(f(e.path),`bun.lock`);return n(t)?{type:`bun`,path:t,filename:`bun.lock`}:void 0}function workspaceSubPath(e,t){if(!isWithin(t,e))return``;let n=h(e,t);return n?n.split(g).join(`/`):``}function parseVitePlusVersionFromLockfile(e,t=``){if(e.filename.endsWith(`.lockb`))return;let n;try{n=a(e.path,`utf-8`)}catch{return}let r;switch(e.type){case`npm`:r=fromNpmLock(n,t);break;case`pnpm`:r=fromPnpmLock(n,t);break;case`yarn`:r=fromYarnLock(n);break;case`bun`:r=fromBunTextLock(n);break;default:return}return r&&o.test(r)?r:void 0}function fromNpmLock(e,t){let n;try{n=JSON.parse(e)}catch{return}let r=n.packages;if(t){let e=r?.[`${t}/node_modules/${Z}`]?.version;if(typeof e==`string`)return e;if(!npmPackageDeclaresVitePlus(r?.[t]))return}let i=r?.[`node_modules/${Z}`]?.version;if(typeof i==`string`)return i;let a=n.dependencies?.[Z]?.version;return typeof a==`string`?a:void 0}function npmPackageDeclaresVitePlus(e){if(!e)return!1;for(let t of[`dependencies`,`devDependencies`]){let n=e[t];if(n&&typeof n==`object`&&`vite-plus`in n)return!0}return!1}function fromPnpmLock(e,t){let n;try{n=(0,Y.parse)(e)}catch{return}if(!n||typeof n!=`object`)return;let r=n,i=r.importers;if(i&&typeof i==`object`){let e=t||`.`;return e in i?pnpmImporterVersion(i[e]):void 0}return pnpmImporterVersion(r)||e.match(/^\s*\/?vite-plus@(\d+\.\d+\.\d+[^\s():'"]*)/m)?.[1]}function pnpmImporterVersion(e){if(!e||typeof e!=`object`)return;let t=e;for(let e of[`dependencies`,`devDependencies`,`optionalDependencies`]){let n=t[e];if(n&&typeof n==`object`){let e=n[Z],t=typeof e==`string`?e:e?.version;if(typeof t==`string`){let e=t.replace(/\(.*$/,``).trim();if(o.test(e))return e}}}}function fromYarnLock(e){let t=/* @__PURE__ */ new Set,n=e.split(/\r?\n/);for(let e=0;ee,info:console.info,debug:()=>{},warning:console.warn}}const rt=`https://raw.githubusercontent.com/voidzero-dev/vite-plus`,it=`packages/cli`,at=/^0\.0\.0-commit\.([0-9a-f]{40})$/i,ot=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;function pkgPrNewCommitSha(e){return e.match(at)?.[1]}function getInstallScriptUrls(e,t=process.platform){let n=isWindows(t)?`install.ps1`:`install.sh`,r=installScriptRef(e);return{pinned:r?[`${rt}/${r}/${it}/${n}`,`https://cdn.jsdelivr.net/gh/voidzero-dev/vite-plus@${r}/${it}/${n}`]:[],latest:[`https://viteplus.dev/${n}`,`${rt}/main/${it}/${n}`]}}function installScriptRef(e){let t=pkgPrNewCommitSha(e);if(t)return t.toLowerCase();if(ot.test(e))return`v${e}`}function readNpmrc(e){try{return a(e,`utf8`)}catch(e){if(e.code===`ENOENT`)return``;throw e}}function analyzeProjectNpmrc(e){let t=/* @__PURE__ */ new Set;for(let n of e.split(/\r?\n/)){let e=n.trim();if(!e||e.startsWith(`;`)||e.startsWith(`#`))continue;let r=e.indexOf(`=`);if(r<0)continue;let i=e.slice(r+1).trim();for(let e of i.matchAll(/\$\{(\w+)\}/g))t.add(e[1])}return{envVarRefs:t}}function readUserConfigLines(e,t){let n=e.HOME||e.USERPROFILE,r=e.NPM_CONFIG_USERCONFIG||e.PNPM_CONFIG_USERCONFIG||n&&u.join(n,`.npmrc`);return(r?readNpmrc(r):``).split(/\r?\n/).filter(e=>!t.has(e.split(`=`)[0].trim().toLowerCase()))}function isReservedAuthVariable(e){return[`GITHUB_TOKEN`,`CI_JOB_TOKEN`,`SYSTEM_ACCESSTOKEN`].includes(e)?!1:/^(?:PATH|HOME|USERPROFILE|TMPDIR|CI)$/i.test(e)||/^(?:SETUP_VP_|RUNNER_|GITHUB_|CI_|SYSTEM_|AGENT_|BUILD_|RELEASE_)/i.test(e)}function writeUserConfig(e,t,n){let r=i(u.join(x(),`setup-vp-npmrc-`)),a=u.join(r,`.npmrc`);l(a,e,{encoding:`utf8`,mode:384});for(let e of[`NPM_CONFIG_USERCONFIG`,`PNPM_CONFIG_USERCONFIG`])t[e]=a,n?.(e,a);return a}function configureAuth(e,t,n,r,i){if(!e){if(!i)return;let{envVarRefs:e}=analyzeProjectNpmrc(readNpmrc(u.join(i,`.npmrc`)));for(let t of e)!isReservedAuthVariable(t)&&n[t]&&r?.(t,n[t]);return}let a;try{a=new URL(e)}catch{throw Error(`Invalid registry-url: "${e}". Must be a valid URL.`)}let o=a.href.endsWith(`/`)?a.href:`${a.href}/`,s=``;t&&(s=`${(t.startsWith(`@`)?t:`@${t}`).toLowerCase()}:`);let c=o.replace(/^\w+:/,``).toLowerCase(),l=readUserConfigLines(n,/* @__PURE__ */ new Set([`${s}registry`,`${c}:_authtoken`]));l.push(`${c}:_authToken=\${NODE_AUTH_TOKEN}`,`${s}registry=${o}`);let d=writeUserConfig(l.filter(Boolean).join(` +`)){let e=t.trim();if(!e||e.startsWith(`#`))continue;let[n,...r]=e.split(/\s+/);if(n===`nodejs`||n===`node`){for(let e of r)if(isAsdfInstallableVersion(e))return e}}}function isAsdfInstallableVersion(e){return!!e&&e!==`system`&&!e.startsWith(`ref:`)&&!e.startsWith(`path:`)}function parsePackageJson(e){let t;try{t=JSON.parse(e)}catch{throw Error(`Failed to parse package.json: invalid JSON`)}let n=t.devEngines;if(n?.runtime){let e=findNodeRuntime(n.runtime);if(e)return e}let r=t.engines;if(r?.node&&typeof r.node==`string`)return r.node}function findNodeRuntime(e){let t=Array.isArray(e)?e:[e];for(let e of t)if(e?.name===`node`&&typeof e.version==`string`)return e.version}return{resolveNodeVersionFile}}function resolutionContext(e){return{getWorkspaceDir:()=>e,info:console.info,debug:()=>{},warning:console.warn}}var rt=`1.1.0`,it={"1.1.0":{commit:`3aa366ee03ac162f5acfd8ee7c752a8245d904c6`,sh:`e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f`,ps1:`a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"1.0.0":{commit:`fc287d7b1c0dc008dbc65d1d2b2f51a44e2a5ea4`,sh:`e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f`,ps1:`a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"1.0.0-rc.1":{commit:`a9d81a4911190345408854b1c1f5cabdc8490a10`,sh:`e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f`,ps1:`a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"1.0.0-rc.0":{commit:`173e734826cdf79ef05ba91390c3508be5ebba3b`,sh:`e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f`,ps1:`a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"0.3.3":{commit:`45f9b9ac7128c2829f9130352ebcdc6462aca3d9`,sh:`6ed2d2847e5b7f3d67b6f91f2d28200bdffcffcd91ef2a336cf764d02776fcc3`,ps1:`bf909eed0675633eab5679fe1b40b1c313ee6e976a5ac732f2df3d35e39b0090`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"0.3.2":{commit:`9fd0d0ae6e775db361d3d5f9f3a18b47bc195420`,sh:`6ed2d2847e5b7f3d67b6f91f2d28200bdffcffcd91ef2a336cf764d02776fcc3`,ps1:`d202bcf693221f1b9732c73327dd4f3585614fadad647aebbf55b3eb453ab082`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"0.3.1":{commit:`13e1e5ab0d993d5a704d7bcb9419cee9aca79a7d`,sh:`d4a1ffa8245bdfcf39a786d545be6a43e231b771c32d7c02414bb96d4f5d9cdc`,ps1:`096c1948222a83b424f6b98417567ea4437414a85ed380fe74ec89c406e5cf86`},"0.3.0":{commit:`b2d15e3899dcc8adedfd45d98de9d30046a624f4`,sh:`3dd88cedb6d9b2665c305eda5413971417c8f183a819386148131b66a2cc6b2e`,ps1:`e803c4cdc20dce9a67eaa2f9780272336ef5bdaf40cc2d4366e8961cd11df572`},"0.2.9":{commit:`73bdd105c2b7c263b55f7e9b48a37a8933cc317a`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.8":{commit:`fc3f0e266d13f0ab288097e202edf4112534a1d2`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.7":{commit:`c17e1c3c7cf859a29dd32eb60e82dc8157449ac2`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.6":{commit:`cd064c68a45fb82badfc1853ff690b1b70511165`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.5":{commit:`93dc59a324f790603ce65e629c13617468d1027d`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.4":{commit:`1ca9f0fcef42bbfb9a5a559f3cc4553c49c80f8c`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.3":{commit:`7f70680f91ad51cc4f1dae3e6cceb194ae7dd0ea`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.2":{commit:`4f7fd0b66ebb5433acdb06f8660cf0f08c5a0d4b`,sh:`8b0a9835d871c4e67aee1c8d5b7e402d165cb55a3222743567a443028b33492e`,ps1:`7ecc798b6b749576215be5aee2b3f11e825115d48fe576cd5a0ecca7c039de71`},"0.2.1":{commit:`a0ed27069ea9eb65802def970ef554855993e0ac`,sh:`6f4fe3690a3f011b4b6cec3c71035e9c04a97dd45dd9e2623dc67f842268f0d2`,ps1:`60821b6f38a0eb984c5846722341f650e4d040c25e93add64aa134f199f86681`},"0.2.0":{commit:`6f97f097de8833b456e431270180b621b2309994`,sh:`6f4fe3690a3f011b4b6cec3c71035e9c04a97dd45dd9e2623dc67f842268f0d2`,ps1:`60821b6f38a0eb984c5846722341f650e4d040c25e93add64aa134f199f86681`},"0.1.24":{commit:`a1a2bbd6bf7e558277ab0f24f4e36243fc064043`,sh:`304d0267bea50d9f5400f3a826f0ae27884c22325b4d149d00a2ae4736c5a0cc`,ps1:`b54e90f2fd7749aa511248c34ac89afe868d7ac625a89074b1b3a7db03a1d02e`},"0.1.23":{commit:`2b3383748b576212ccb94dd2c647277e0bc4f5e2`,sh:`15242cab7c7832e2a3dc134e23059ce7726f7cca1467d78a79cd70760d3e3fb6`,ps1:`0611cb2777dc903ede063e303b84cc8193c49375b58eaba2db86c1c5c296719a`},"0.1.22":{commit:`12368dafa4a7b8c51fc1ef274c4cd5b60e6d3859`,sh:`15242cab7c7832e2a3dc134e23059ce7726f7cca1467d78a79cd70760d3e3fb6`,ps1:`0611cb2777dc903ede063e303b84cc8193c49375b58eaba2db86c1c5c296719a`},"0.1.21":{commit:`c61621ac610ad114746b98d7e457ca4e13171837`,sh:`8ca22990891df17cd808d7eedc3f8fcc722ad3a402191f6c125f36368af663f6`,ps1:`8a09b7b3ab975b134e1ec6d94daebe9cd531b2f3da9246fe8d9e38ee59df26c1`},"0.1.21-alpha.7":{commit:`c61621ac610ad114746b98d7e457ca4e13171837`,sh:`8ca22990891df17cd808d7eedc3f8fcc722ad3a402191f6c125f36368af663f6`,ps1:`8a09b7b3ab975b134e1ec6d94daebe9cd531b2f3da9246fe8d9e38ee59df26c1`},"0.1.21-alpha.6":{commit:`e134e4f84d7e3447d2fbd54fabf4efa928d6ce91`,sh:`8ca22990891df17cd808d7eedc3f8fcc722ad3a402191f6c125f36368af663f6`,ps1:`8a09b7b3ab975b134e1ec6d94daebe9cd531b2f3da9246fe8d9e38ee59df26c1`},"0.1.21-alpha.5":{commit:`634759714a507316148fd602a49dfceb87959b92`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.4":{commit:`dc41b711b8405fa42910fe186e8de2f58a51e14b`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.3":{commit:`7044ab9b003e42b5a5c9145dd7551da687d76989`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.2":{commit:`c4cdfc9666b5d0fd2fc2a9a4182ecb03afb5fa36`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.1":{commit:`cbd74649cf5d58dae8f309400f1754e418872f76`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.0":{commit:`7b9e6d6ce0cbc3bfef38b91034b493bc1739fc6e`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20":{commit:`bcc93a46abe94c543a0d36540dbd78aabfececfb`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.4":{commit:`bcc93a46abe94c543a0d36540dbd78aabfececfb`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.3":{commit:`210897e627ea27f2d7e0a7e5d2792aaf0e2775cc`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.2":{commit:`a5f36e08ef31ff9962b0b749652f57ab09fbdeb1`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.1":{commit:`fac1a20dd4f0f4990907ac67413c5c2b90a6ae42`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.0":{commit:`aeacdb0caacf2d7627c7b8df57011fb13bc040f5`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19":{commit:`41e78e2ba8ead352ca74aa32835489bfedfad63d`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19-alpha.3":{commit:`da5f14712472e185a825087f485cc4072b2ba8e7`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19-alpha.2":{commit:`4ac205f4434d6d362abc09e323991721da564f70`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19-alpha.1":{commit:`c5510b2f6de9976fde25c200aeed28b2f496a540`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19-alpha.0":{commit:`b9d218a6f9aa0c3b22fe85b6ad9229b0e135b31b`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.18":{commit:`6e06c175c71c725a46c409062c4c8d1fe1150449`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.18-alpha.0":{commit:`40a47e52cd596674a80203991013913555655f0d`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17":{commit:`e159b84a95199fc17a7ffddef14caeefc81c90f2`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.5":{commit:`48e49ca0c1c062989120c41bcce9ee1db8b172dd`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.4":{commit:`a5fca7ddca580725a3ba06efbd47ee573b60c50a`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.3":{commit:`a94deea2fc68b5a6a2e2f2868df32b6cc7bf7ec8`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.2":{commit:`2703014124101b30ec2470159d84d8f9a32dd285`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.1":{commit:`ba538e199ba23ca34f895af5b36564366990725b`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.0":{commit:`29f821e61f41e2068713676856d7363bf72e5896`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`c44111999449915902c9f0e0ddfa61ea1b3c3a0502ee4b1a3994a115abb4c5bc`},"0.1.16":{commit:`f64bb6c98c1ff577ba7e8ae4ddb43dcfcc3624b0`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`c44111999449915902c9f0e0ddfa61ea1b3c3a0502ee4b1a3994a115abb4c5bc`},"0.1.16-alpha.4":{commit:`556043129dc6a006cbdefd40b9c68ca306f086b5`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`c44111999449915902c9f0e0ddfa61ea1b3c3a0502ee4b1a3994a115abb4c5bc`},"0.1.16-alpha.3":{commit:`6153ccb787f9b35655c1702f3220e5c7a57ca997`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`53c0cfbb7e92719b18808611a977eb34312992c20cca8636d9f905c43184b860`},"0.1.16-alpha.2":{commit:`f72d8a1f86fde0945de6e362d1fd120043f635cd`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`53c0cfbb7e92719b18808611a977eb34312992c20cca8636d9f905c43184b860`},"0.1.16-alpha.1":{commit:`38aa60a7a087113364e5b80feceaa57d3100f766`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`53c0cfbb7e92719b18808611a977eb34312992c20cca8636d9f905c43184b860`},"0.1.16-alpha.0":{commit:`a015d7897617b7807ed0d825000fc1e7e9b18e67`,sh:`4057f586f65168077362203bcde2ea8ed07ec7ee3a560a35a20b974f4318c098`,ps1:`e9caf430aa09d14b82f5522aeb84b9321470d09512f2634e3d2dfda77d3645f6`},"0.1.15":{commit:`bf39b756ae038af3d34bbceeedc9ecf60afdd9a8`,sh:`437b3dbf8bed60740183083687801c037c318a48ba590ef5e2e06594ffd61530`,ps1:`299207f95a34b0e9a03df0bd7a77c80521b793740a5674aba80519ce7bd2c034`},"0.1.15-alpha.7":{commit:`f922d5fa560cae6f232cb1a74099c78587806ad3`,sh:`437b3dbf8bed60740183083687801c037c318a48ba590ef5e2e06594ffd61530`,ps1:`299207f95a34b0e9a03df0bd7a77c80521b793740a5674aba80519ce7bd2c034`},"0.1.15-alpha.6":{commit:`6cd75f480d9c10845d05d32be594c8cc6bce3c64`,sh:`437b3dbf8bed60740183083687801c037c318a48ba590ef5e2e06594ffd61530`,ps1:`299207f95a34b0e9a03df0bd7a77c80521b793740a5674aba80519ce7bd2c034`},"0.1.15-alpha.5":{commit:`dbe191ed95750571d9e02c33849c33c6789cfee4`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.4":{commit:`3af4839e659745492252020d78d519559e4a568d`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.3":{commit:`fd1b75e2ac170472017e3e601189fdfb3ed5f5d8`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.2":{commit:`3a85b2b65ba63d6706e58ca45d9b8ae1aa04d27a`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.1":{commit:`c267e06a0e254472983af686dd376efed5344d15`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.0":{commit:`94aecfa3edb591faf2b92835732090e41eba6dbb`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.14":{commit:`71b90b4eadd9795f354d3d5208decf904b92d927`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.14-alpha.3":{commit:`01693e3781bf854ff3fd1cd755f26ade1773ccc2`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.14-alpha.1":{commit:`0ff9227227bf58c48d46ea8814f21b1549f211cb`,sh:`cf9cfa219dce0fa7a9aba8f0804214af89d3321e0eec40ebc02371c7f08acba8`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.14-alpha.0":{commit:`fc9bf496ad50dba718a1544583d19eb47ff32534`,sh:`cf9cfa219dce0fa7a9aba8f0804214af89d3321e0eec40ebc02371c7f08acba8`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.13":{commit:`9861b670b32c53ea28dfb0b7e1189e533a13c5fd`,sh:`4f70075425f42ff90c304da5f74a586bd1bc4cfa79cdac2d5eff3dfd7176b845`,ps1:`7b6495786f059b2be584156884e68cb6da99f2ee6c0fddd6987c59fa604f794d`},"0.1.13-alpha.5":{commit:`2dfc0c3c81451233abe62ed49de1266ff5069a64`,sh:`4f70075425f42ff90c304da5f74a586bd1bc4cfa79cdac2d5eff3dfd7176b845`,ps1:`7b6495786f059b2be584156884e68cb6da99f2ee6c0fddd6987c59fa604f794d`},"0.1.13-alpha.4":{commit:`ffc1638a075632f9a1977f24467dcce5d31d00d1`,sh:`4f70075425f42ff90c304da5f74a586bd1bc4cfa79cdac2d5eff3dfd7176b845`,ps1:`7b6495786f059b2be584156884e68cb6da99f2ee6c0fddd6987c59fa604f794d`},"0.1.13-alpha.3":{commit:`d64cba8cda73af176453e0c25e7743d6ab25486f`,sh:`ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b`,ps1:`9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88`},"0.1.13-alpha.2":{commit:`9db93c21726781c7fe0d2d90b7373ad172af2dbc`,sh:`ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b`,ps1:`9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88`},"0.1.13-alpha.1":{commit:`849c1263bb9913dcd1a3fe0680b6cb8113639e06`,sh:`ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b`,ps1:`9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88`},"0.1.13-alpha.0":{commit:`b3d0e962b13118f3ff4097d224523833584326e6`,sh:`ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b`,ps1:`9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88`},"0.1.12":{commit:`8c6c1b23f1fe702f21ae72ff96979bfedb66364b`,sh:`43985e08bab995fba9c28923be6070d78f979c635c53ef7fd624a3103d9ce588`,ps1:`c40df7d8d632cd36d56b16e27006b0886dd51785e6033ca20bcbe3308901443c`},"0.1.12-alpha.2":{commit:`fe3189b64e0588ddae272ed6c4d49a8cbc23ce55`,sh:`2bc79f0370486d429783850b12e039672cc7f7236712c11a23d5b9405b05a597`,ps1:`c40df7d8d632cd36d56b16e27006b0886dd51785e6033ca20bcbe3308901443c`},"0.1.11":{commit:`ef77182006de701eb5260a68652f6dab6db7b760`,sh:`6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2`,ps1:`e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca`},"0.1.10":{commit:`1848576dcdb270611ce6e9c4b0b7ea7fdb223f32`,sh:`6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2`,ps1:`e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca`},"0.1.9":{commit:`b25efbd3c2a5ebdc18496e4ca2142f6449343952`,sh:`6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2`,ps1:`e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca`},"0.1.8":{commit:`0a1ec92c7b21d73317c9f3d796a35c8c9f14d0f1`,sh:`6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2`,ps1:`e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca`},"0.1.7":{commit:`a7dc6660a4e0f488a061d6350222adabdf763f5b`,sh:`a8378abdf90ce4a95352f1f9918d54bd666ec347ff9cad0c3bbfa2fef6db62cd`,ps1:`7462b3bb999b14f138d15df47a84dbdb3a7be96f56f77e9626e6624b6640eafc`},"0.1.6":{commit:`0c40c50cb395317ca3b35508e286018114b6372c`,sh:`a8378abdf90ce4a95352f1f9918d54bd666ec347ff9cad0c3bbfa2fef6db62cd`,ps1:`7462b3bb999b14f138d15df47a84dbdb3a7be96f56f77e9626e6624b6640eafc`},"0.1.5":{commit:`133340675e7eb9de8e0d8ffd8efb9de619ba6a39`,sh:`3316073e62247a9b8fc34f1be8b24047e3e3315749cc52d68eeccae2462f78d1`,ps1:`722de6e4ab17a6f853100055f522a2fec3a3255c394bc29be1d5fc3b6ed8f120`},"0.1.4":{commit:`12abba5def4cf4479f226188c0b24e04d15f3181`,sh:`3316073e62247a9b8fc34f1be8b24047e3e3315749cc52d68eeccae2462f78d1`,ps1:`722de6e4ab17a6f853100055f522a2fec3a3255c394bc29be1d5fc3b6ed8f120`},"0.1.3":{commit:`c0c8ebda74ac78bb70a73ebf4de67865079c9b38`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.2":{commit:`dfb9d4b258b11f6842c7b62f228617d4065f5a83`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.1":{commit:`8c5823fa0d19d7e186115963d1ff7ff58fa30576`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.1-alpha.0":{commit:`bdef013b286275979c9e593fe564c686b3d7130b`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.0":{commit:`cf4df93a8fd7f6b871f98766fb2c6a6578f2d8bc`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.0-alpha.0":{commit:`82f57fbb4d53b99d023d923979f2b2f08ff5e18f`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`}};const at=/^0\.0\.0-commit\.([0-9a-f]{40})$/i;function pkgPrNewCommitSha(e){return e.match(at)?.[1]}const ot=it;function getInstallScriptSources(e,t=process.platform){let n=isWindows(t)?`ps1`:`sh`;function sources(e){let t=`packages/cli/install.${n}`;return[`https://raw.githubusercontent.com/voidzero-dev/vite-plus/${e.commit}/${t}`,`https://cdn.jsdelivr.net/gh/voidzero-dev/vite-plus@${e.commit}/${t}`].map(t=>{let r=e[`legacy_${n}`];return{url:t,sha256:e[n],...r?{legacy:{url:t.replace(`install.${n}`,`install-legacy.${n}`),sha256:r}}:{}}})}let r=Object.hasOwn(ot,e)?ot[e]:void 0,i=ot[rt];return{pinned:r&&r.commit!==i.commit?sources(r):[],fallback:sources(i)}}function readNpmrc(e){try{return a(e,`utf8`)}catch(e){if(e.code===`ENOENT`)return``;throw e}}function analyzeProjectNpmrc(e){let t=/* @__PURE__ */ new Set;for(let n of e.split(/\r?\n/)){let e=n.trim();if(!e||e.startsWith(`;`)||e.startsWith(`#`))continue;let r=e.indexOf(`=`);if(r<0)continue;let i=e.slice(r+1).trim();for(let e of i.matchAll(/\$\{(\w+)\}/g))t.add(e[1])}return{envVarRefs:t}}function readUserConfigLines(e,t){let n=e.HOME||e.USERPROFILE,r=e.NPM_CONFIG_USERCONFIG||e.PNPM_CONFIG_USERCONFIG||n&&u.join(n,`.npmrc`);return(r?readNpmrc(r):``).split(/\r?\n/).filter(e=>!t.has(e.split(`=`)[0].trim().toLowerCase()))}function isReservedAuthVariable(e){return[`GITHUB_TOKEN`,`CI_JOB_TOKEN`,`SYSTEM_ACCESSTOKEN`].includes(e)?!1:/^(?:PATH|HOME|USERPROFILE|TMPDIR|CI)$/i.test(e)||/^(?:SETUP_VP_|RUNNER_|GITHUB_|CI_|SYSTEM_|AGENT_|BUILD_|RELEASE_)/i.test(e)}function writeUserConfig(e,t,n){let r=i(u.join(x(),`setup-vp-npmrc-`)),a=u.join(r,`.npmrc`);l(a,e,{encoding:`utf8`,mode:384});for(let e of[`NPM_CONFIG_USERCONFIG`,`PNPM_CONFIG_USERCONFIG`])t[e]=a,n?.(e,a);return a}function configureAuth(e,t,n,r,i){if(!e){if(!i)return;let{envVarRefs:e}=analyzeProjectNpmrc(readNpmrc(u.join(i,`.npmrc`)));for(let t of e)!isReservedAuthVariable(t)&&n[t]&&r?.(t,n[t]);return}let a;try{a=new URL(e)}catch{throw Error(`Invalid registry-url: "${e}". Must be a valid URL.`)}let o=a.href.endsWith(`/`)?a.href:`${a.href}/`,s=``;t&&(s=`${(t.startsWith(`@`)?t:`@${t}`).toLowerCase()}:`);let c=o.replace(/^\w+:/,``).toLowerCase(),l=readUserConfigLines(n,/* @__PURE__ */ new Set([`${s}registry`,`${c}:_authtoken`]));l.push(`${c}:_authToken=\${NODE_AUTH_TOKEN}`,`${s}registry=${o}`);let d=writeUserConfig(l.filter(Boolean).join(` `)+` `,n,r);return n.NODE_AUTH_TOKEN=n.NODE_AUTH_TOKEN||`XXXXX-XXXXX-XXXXX-XXXXX`,r?.(`NODE_AUTH_TOKEN`,n.NODE_AUTH_TOKEN),d}function resolveSfwEnabled(e,t,n){return e?!pkgPrNewCommitSha(t)||(n(`sfw was requested but is automatically disabled for Vite+ preview build ${t}; Socket Firewall Free will not be used.`),!1):!1}const Q=`v1.15.4`,st=`https://github.com/SocketDev/sfw-free/releases/download/${Q}`;function isMuslLinux(){if(process.platform!==`linux`)return!1;try{let e=process.report?.getReport();if(e?.header&&!e.header.glibcVersionRuntime)return!0}catch{}return n(`/etc/alpine-release`)}function getSfwAssetName(e,t,n){if(e===`darwin`){if(t===`arm64`)return`sfw-free-macos-arm64`;if(t===`x64`)return`sfw-free-macos-x86_64`}else if(e===`linux`){if(t===`arm64`)return n?`sfw-free-musl-linux-arm64`:`sfw-free-linux-arm64`;if(t===`x64`)return n?`sfw-free-musl-linux-x86_64`:`sfw-free-linux-x86_64`}else if(isWindows(e)){if(t===`arm64`)return`sfw-free-windows-arm64.exe`;if(t===`x64`)return`sfw-free-windows-x86_64.exe`}throw Error(`Unsupported platform/arch for sfw: ${e}/${t}${e===`linux`?` (${n?`musl`:`glibc`})`:``}`)}function downloadFileWithShell(e,t,n){let r=Math.max(1,Math.ceil(n/1e3)),i=commandPath(`curl`);if(i){let n=y(i,[`-fsSL`,`--connect-timeout`,`5`,`--max-time`,String(r),e,`-o`,t],{stdio:`ignore`});if(n.status===0)return;throw n.error||/* @__PURE__ */ Error(`curl failed while downloading ${e}`)}let a=commandPath(`wget`);if(a){let n=y(a,[`-q`,`-T`,String(r),`-t`,`2`,`-O`,t,e],{stdio:`ignore`});if(n.status===0)return;throw n.error||/* @__PURE__ */ Error(`wget failed while downloading ${e}`)}throw Error(`curl or wget is required to download sfw`)}function downloadFile(e,n,r=0,i=6e4,a){return r>5?Promise.reject(/* @__PURE__ */ Error(`too many redirects while downloading ${e}`)):a?new Promise((o,s)=>{let c=!1,finish=e=>{c||(c=!0,clearTimeout(u),e?s(e):o())},l=a(e,o=>{let s=o.statusCode??0,c=o.headers.location;if(s>=300&&s<400&&c){o.resume(),downloadFile(new URL(c,e).toString(),n,r+1,i,a).then(()=>finish(),finish);return}if(s!==200){o.resume(),finish(/* @__PURE__ */ Error(`download failed with HTTP ${s}: ${e}`));return}let l=t(n);o.pipe(l),l.on(`finish`,()=>l.close(()=>finish())),l.on(`error`,finish)}),u=setTimeout(()=>{l.destroy(/* @__PURE__ */ Error(`download timed out after ${i}ms: ${e}`))},i);l.on(`error`,finish)}):(downloadFileWithShell(e,n,i),Promise.resolve())}async function setupSfw(e,t={}){let n=t.env??process.env,r=t.sfwEnabled??n.SETUP_VP_SFW===`true`,i=t.platform??process.platform,a=t.arch??process.arch,o=t.isMusl??isMuslLinux(),s=t.download??downloadFile;if(!resolveSfwEnabled(r,t.vitePlusVersion??``,t.logWarning??console.warn))return`vp`;if(e.length===0)return console.log(`setup-vp: sfw was requested but run-install is disabled; sfw will not be invoked.`),`vp`;let c=commandPath(`sfw`);if(c)return console.log(`setup-vp: using existing sfw on PATH: ${c}`),`sfw`;let l;try{l=getSfwAssetName(i,a,o)}catch{return console.error(`setup-vp: sfw has no published binary for this runner's platform/architecture (process.platform=${i}, process.arch=${a}, musl=${o}) and none was found on PATH; falling back to plain vp install.`),`vp`}let d=t.cacheDirectory||n.SETUP_VP_SFW_CACHE_DIR,f=d?u.join(d,Q,l):await w(u.join(x(),`setup-vp-sfw-`));await C(f,{recursive:!0});let p=u.join(f,isWindows(i)?`sfw.exe`:`sfw`),m=`${st}/${l}`;function activate(){let e=isWindows(i)?`;`:`:`;return n.PATH=`${f}${e}${n.PATH||``}`,t.exportVariable?.(`PATH`,n.PATH),`sfw`}if(await ee(p).then(e=>e.isFile()&&e.size>0,()=>!1))return console.log(`setup-vp: using cached sfw ${Q}: ${p}`),activate();for(let e=1;e<=2;e+=1){let t=await w(u.join(f,`.download-`)),n=u.join(t,`sfw`);try{if(console.log(`setup-vp: installing sfw ${Q} from ${m}`),await s(m,n),(await ee(n)).size===0)throw Error(`Downloaded sfw binary is empty`);return await S(n,493),await T(n,p),activate()}catch(t){if(e===2)throw t;await new Promise(e=>setTimeout(e,2e3))}finally{await E(t,{recursive:!0,force:!0})}}throw Error(`failed to install sfw after retrying`)}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function validateRunInstallEntry(e){if(!isRecord(e))throw Error(`run-install entries must be objects`);for(let t of Object.keys(e))if(t!==`cwd`&&t!==`args`)throw Error(`unsupported run-install key: ${t}`);let t={};if(e.cwd!==void 0){if(typeof e.cwd!=`string`)throw Error(`run-install.cwd must be a string`);t.cwd=e.cwd}if(e.args!==void 0){if(!Array.isArray(e.args)||e.args.some(e=>typeof e!=`string`))throw Error(`run-install.args must be an array of strings`);t.args=e.args}return t}function validateRunInstallInput(e){return e===null||typeof e==`boolean`?e:Array.isArray(e)?e.map(validateRunInstallEntry):validateRunInstallEntry(e)}function parseRunInstall(e){let t=validateRunInstallInput((0,Y.parse)(e)??null);return t?t===!0?[{}]:Array.isArray(t)?t:[t]:[]}function isSfwVpNotFoundFlake(e,t){return/Command 'vp' not found in PATH/.test(e+` `+t)}async function runInstall(e,t,n,r=process.env,i={}){let a={...r};delete a.SETUP_VP_ENV_FILE;let o=i.execute??runWithOutput,s=[];for(let r of e){let e=r.cwd?u.resolve(t,r.cwd):t,c=[`install`,...r.args||[]],l=n===`sfw`?[`vp`,...c]:c,d=`${n} ${l.join(` `)} (cwd: ${e})`;console.log(`setup-vp: running ${d}`);try{let t=await o(n,l,{cwd:e,env:a});if(t.exitCode!==0&&n===`sfw`&&isSfwVpNotFoundFlake(t.stdout,t.stderr)){let r=isWindows(i.platform);if(console.warn(r?`setup-vp: sfw could not resolve vp; warming the PowerShell command cache and retrying once.`:`setup-vp: sfw could not resolve vp; retrying once.`),r)try{await o(`powershell.exe`,[`-NoProfile`,`-Command`,`Get-Command vp`],{cwd:e,env:a})}catch{}t=await o(n,l,{cwd:e,env:a})}t.exitCode!==0&&s.push(`${d} exited with code ${t.exitCode}\n${t.stderr.trim()||t.stdout.trim()}`)}catch(e){s.push(`${d}: ${String(e)}`)}}if(s.length)throw Error(s.join(` `))}function escapeLoggingCommandData(e){return e.replaceAll(`%`,`%AZP25`).replaceAll(`\r`,`%0D`).replaceAll(` -`,`%0A`).replaceAll(`;`,`%3B`).replaceAll(`]`,`%5D`)}function prependPath(e){process.stdout.write(`##vso[task.prependpath]${escapeLoggingCommandData(e)}\n`)}function setVariable(e,t,n={}){let r=[`variable=${e}`];n.isOutput&&r.push(`isOutput=true`),n.isReadonly&&r.push(`isReadonly=true`),n.isSecret&&r.push(`issecret=true`),process.stdout.write(`##vso[task.setvariable ${r.join(`;`)}]${escapeLoggingCommandData(t)}\n`)}function logWarning(e){process.stdout.write(`##vso[task.logissue type=warning]${escapeLoggingCommandData(e)}\n`)}function logInfo(e){console.log(e)}const $=`SETUP_VP_DIRS_FILE`;function getVitePlusBinDirs(e){let t=m(e.data,`fallback-bin`);return c(t,{throwIfNoEntry:!1})?.isDirectory()?{bin:e.bin,fallbackBin:t}:{bin:e.bin}}function appendFallbackBinToPath(e,t,n=process.platform){let r=isWindows(n)?`;`:`:`;return[...e?e.split(r).filter(e=>e!==t):[],t].join(r)}const ct=/^v?(\d+)\.(\d+)\.\d+(?:-[0-9A-Za-z.-]+)?$/;function supportsVitePlusDirs(e){if(pkgPrNewCommitSha(e))return!0;let t=e.match(ct);if(!t)return!0;let n=Number(t[1]),r=Number(t[2]);return n>0||r>=3}function createVitePlusDirsFile(){return m(x(),`setup-vp-dirs-${ne()}.txt`)}function removeVitePlusDirsFile(e){s(e,{force:!0})}function readVitePlusProbe(e){try{return a(e,`utf8`)}catch(e){if(e.code===`ENOENT`)return;throw e}}function resolveVitePlusBinDirs(e,t,n){if(!t){if(!supportsVitePlusDirs(e))return{bin:n};throw Error(`Vite+ was installed successfully, but setup-vp could not resolve its VpDirs.`)}let r=readVitePlusProbe(t),i=r===void 0?void 0:parseVitePlusDirs(r);if(i)return getVitePlusBinDirs(i);if(!(pkgPrNewCommitSha(e)!==void 0||ct.test(e))&&r!==void 0){let e=parseInstalledVpVersion(r);if(e!==`unknown`&&!supportsVitePlusDirs(e))return{bin:n}}throw Error(`Vite+ was installed successfully, but setup-vp could not resolve its VpDirs.`)}function parseVitePlusDirs(e){let t=/* @__PURE__ */ new Map;for(let n of e.split(/\r?\n/)){let e=n.indexOf(` `);if(e<1)continue;let r=n.slice(0,e).replace(/^\uFEFF/,``),i=n.slice(e+1).trim();i&&t.set(r,i)}let n=t.get(`data`),r=t.get(`bin`),i=t.get(`cache`),a=t.get(`config`),o=t.get(`state`);if(n&&r&&i&&a&&o)return{data:n,bin:r,cache:i,config:a,state:o}}function getInstallScriptCommand(e,t=process.platform,n=!0){if(isWindows(t))return n?{command:`pwsh`,args:[`-Command`,` +`,`%0A`).replaceAll(`;`,`%3B`).replaceAll(`]`,`%5D`)}function prependPath(e){process.stdout.write(`##vso[task.prependpath]${escapeLoggingCommandData(e)}\n`)}function setVariable(e,t,n={}){let r=[`variable=${e}`];n.isOutput&&r.push(`isOutput=true`),n.isReadonly&&r.push(`isReadonly=true`),n.isSecret&&r.push(`issecret=true`),process.stdout.write(`##vso[task.setvariable ${r.join(`;`)}]${escapeLoggingCommandData(t)}\n`)}function logWarning(e){process.stdout.write(`##vso[task.logissue type=warning]${escapeLoggingCommandData(e)}\n`)}function logInfo(e){console.log(e)}const $=`SETUP_VP_DIRS_FILE`;function getVitePlusBinDirs(e){let t=m(e.data,`fallback-bin`);return c(t,{throwIfNoEntry:!1})?.isDirectory()?{bin:e.bin,fallbackBin:t}:{bin:e.bin}}function appendFallbackBinToPath(e,t,n=process.platform){let r=isWindows(n)?`;`:`:`;return[...e?e.split(r).filter(e=>e!==t):[],t].join(r)}const ct=/^v?(\d+)\.(\d+)\.\d+(?:-[0-9A-Za-z.-]+)?$/;function supportsVitePlusDirs(e){if(pkgPrNewCommitSha(e))return!0;let t=e.match(ct);if(!t)return!0;let n=Number(t[1]),r=Number(t[2]);return n>0||r>=3}function createVitePlusDirsFile(){return m(x(),`setup-vp-dirs-${ne()}.txt`)}function removeVitePlusDirsFile(e){s(e,{force:!0})}function readVitePlusProbe(e){try{return a(e,`utf8`)}catch(e){if(e.code===`ENOENT`)return;throw e}}function resolveVitePlusBinDirs(e,t,n){if(!t){if(!supportsVitePlusDirs(e))return{bin:n};throw Error(`Vite+ was installed successfully, but setup-vp could not resolve its VpDirs.`)}let r=readVitePlusProbe(t),i=r===void 0?void 0:parseVitePlusDirs(r);if(i)return getVitePlusBinDirs(i);if(!(pkgPrNewCommitSha(e)!==void 0||ct.test(e))&&r!==void 0){let e=parseInstalledVpVersion(r);if(e!==`unknown`&&!supportsVitePlusDirs(e))return{bin:n}}throw Error(`Vite+ was installed successfully, but setup-vp could not resolve its VpDirs.`)}function parseVitePlusDirs(e){let t=/* @__PURE__ */ new Map;for(let n of e.split(/\r?\n/)){let e=n.indexOf(` `);if(e<1)continue;let r=n.slice(0,e).replace(/^\uFEFF/,``),i=n.slice(e+1).trim();i&&t.set(r,i)}let n=t.get(`data`),r=t.get(`bin`),i=t.get(`cache`),a=t.get(`config`),o=t.get(`state`);if(n&&r&&i&&a&&o)return{data:n,bin:r,cache:i,config:a,state:o}}function getInstallScriptCommand(e,t=process.platform,n=!0){let r=[{...e,name:isWindows(t)?`install.ps1`:`install.sh`}];e.legacy&&r.push({...e.legacy,name:isWindows(t)?`install-legacy.ps1`:`install-legacy.sh`});for(let e of r)if(!/^[a-f0-9]{64}$/.test(e.sha256))throw Error(`A trusted SHA-256 checksum is required for the Vite+ installer.`);if(isWindows(t)){let e=` $dirsFile = $env:${$} Set-Content -LiteralPath $dirsFile -Value '' -NoNewline -Encoding UTF8 -. ([scriptblock]::Create((irm -TimeoutSec 15 ${e}))) +. $installerFile $vpDir = if ($script:ShimDir) { $script:ShimDir } elseif ($InstallDir) { @@ -163,30 +163,55 @@ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } $env:VP_DUMP_DIRS = '1' & $vpPath | Add-Content -LiteralPath $dirsFile -Encoding UTF8 if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } -`.trim()]}:{command:`pwsh`,args:[`-Command`,`& ([scriptblock]::Create((irm -TimeoutSec 15 ${e})))`]};let r=` +`.trim();return{command:`pwsh`,args:[`-ExecutionPolicy`,`Bypass`,`-Command`,` +$ErrorActionPreference = 'Stop' +$installerDir = Join-Path ([System.IO.Path]::GetTempPath()) ('setup-vp-install-' + [guid]::NewGuid().ToString('N')) +$null = New-Item -ItemType Directory -Path $installerDir +$installerFile = Join-Path $installerDir 'install.ps1' +try { + ${r.map(({url:e,sha256:t,name:n})=>` + $downloadFile = Join-Path $installerDir '${n}' + Invoke-WebRequest -UseBasicParsing -TimeoutSec 15 -Uri '${e.replaceAll(`'`,`''`)}' -OutFile $downloadFile + if ((Get-FileHash -LiteralPath $downloadFile -Algorithm SHA256).Hash -ne '${t}') { + throw 'setup-vp: installer SHA-256 checksum mismatch; refusing to execute it.' + }`).join(` +`)} + $global:LASTEXITCODE = 0 + ${n?e:`& $installerFile +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }`} +} finally { + Remove-Item -LiteralPath $installerDir -Recurse -Force +} +`.trim()]}}let quote=e=>`'${e.replaceAll(`'`,`'\\''`)}'`;return{command:`bash`,args:[`-c`,` +set +u +set -eo pipefail +installer_dir="$(mktemp -d "\${TMPDIR:-/tmp}/setup-vp-install.XXXXXX")" +trap 'rm -rf "$installer_dir"' EXIT +installer_file="$installer_dir/install.sh" +${r.map(({url:e,sha256:t,name:n})=>` +download_file="$installer_dir/${n}" if command -v curl >/dev/null 2>&1; then - curl -fsSL --connect-timeout 5 --max-time 15 "${e}"${n?` -o "$installer_file"`:``} + curl -fsSL --connect-timeout 5 --max-time 15 ${quote(e)} -o "$download_file" elif command -v wget >/dev/null 2>&1; then - wget -q -T 15 -t 1 -O ${n?`"$installer_file"`:`-`} "${e}" + wget -q -T 15 -t 1 -O "$download_file" ${quote(e)} else echo "setup-vp: curl or wget is required to download the installer." >&2 exit 127 fi -`.trim();return n?{command:`bash`,args:[`-c`,` -set +u -set -eo pipefail -installer_file="$(mktemp "\${TMPDIR:-/tmp}/setup-vp-install.XXXXXX")" -trap 'rm -f "$installer_file"' EXIT -: > "$${$}" -${r} +${quote(process.execPath)} -e ${quote(`const fs = require("node:fs"); +const crypto = require("node:crypto"); +const actual = crypto.createHash("sha256").update(fs.readFileSync(process.argv[1])).digest("hex"); +if (actual !== process.argv[2]) { + console.error("setup-vp: installer SHA-256 checksum mismatch; refusing to execute it."); + process.exit(1); +}`)} "$download_file" '${t}' +`).join(` +`)} +${n?`: > "$${$}" source "$installer_file" vp_dir="\${SHIM_DIR:-\${INSTALL_DIR:-\${VP_HOME:-$HOME/.vite-plus}}/bin}" if [ -x "$vp_dir/vp" ]; then "$vp_dir/vp" --version > "$${$}" VP_DUMP_DIRS=1 "$vp_dir/vp" >> "$${$}" -fi -`.trim()]}:{command:`bash`,args:[`-c`,` -set +u -set -o pipefail -${r} | bash -`.trim()]}}const lt=2e3;function getVitePlusHome(e=process.platform,t=process.env){let n=isWindows(e)?t.USERPROFILE||b():t.HOME||b();return m(n,`.vite-plus`)}function runInstallCommand(e,t,n=process.platform){let{command:r,args:i}=getInstallScriptCommand(e,n,t.VP_VPDIRS_AWARE===`1`),a={env:{...process.env,...t},stdio:`inherit`},o=y(r,i,a);if(isWindows(n)&&o.error?.code===`ENOENT`&&(o=y(`powershell.exe`,i,a)),o.error)throw o.error;return o.status??1}async function installVitePlus(e,t={}){let n=t.platform??process.platform,r=t.env??process.env,i=t.prependPath,a=t.sleep??te,o=t.runInstall??runInstallCommand,s=t.logWarningFn??console.warn,c={...Object.fromEntries(Object.entries(r).filter(e=>e[1]!==void 0)),VP_VERSION:e,VITE_PLUS_VERSION:e},l=supportsVitePlusDirs(e)?createVitePlusDirsFile():void 0;l?(c.VP_VPDIRS_AWARE=`1`,c[$]=l):(delete c.VP_VPDIRS_AWARE,delete c[$]);let u=pkgPrNewCommitSha(e);u&&(c.VP_PR_VERSION=u);let{pinned:d,latest:f}=getInstallScriptUrls(e,n),p=d.length+f.length,h=2*p,g=``,_=0;async function tryUrls(e){for(let t=0;t<2;t+=1)for(let t of e){_+=1;try{let e=o(t,c,n);if(e===0)return!0;g=`exit code ${e}`}catch(e){g=e instanceof Error?e.message:String(e)}_0){if(await tryUrls(d)){ensureBinInPath();return}s(`setup-vp: could not fetch the install script pinned to Vite+ ${e}. Falling back to the latest install script. The latest script may not be compatible with ${e}.`)}if(await tryUrls(f)){ensureBinInPath();return}throw Error(`Failed to install Vite+ after ${h} attempts across ${p} URL(s): ${g}`)}finally{l&&removeVitePlusDirsFile(l)}}function parseBoolean(e){return e?.toLowerCase()===`true`}function parseAzureInputs(e){return{version:e.SETUP_VP_VERSION||``,versionFile:e.SETUP_VP_VERSION_FILE||void 0,nodeVersion:e.SETUP_VP_NODE_VERSION||void 0,nodeVersionFile:e.SETUP_VP_NODE_VERSION_FILE||void 0,workingDirectory:e.SETUP_VP_WORKING_DIRECTORY||`.`,runInstall:e.SETUP_VP_RUN_INSTALL??`true`,sfw:parseBoolean(e.SETUP_VP_SFW),nodeManager:parseNodeManager(e.SETUP_VP_NODE_MANAGER),packageManager:parsePackageManager(e.SETUP_VP_PACKAGE_MANAGER),registryUrl:e.SETUP_VP_REGISTRY_URL||``,scope:e.SETUP_VP_SCOPE||``,cache:parseBoolean(e.SETUP_VP_CACHE),cacheDependencyPath:e.SETUP_VP_CACHE_DEPENDENCY_PATH||``,workspaceRoot:e.SYSTEM_DEFAULTWORKINGDIRECTORY||process.cwd()}}function resolveProjectDirFromInputs(e){return resolveProjectDirectory({workingDirectory:e.workingDirectory,workspaceRoot:e.workspaceRoot})}const ut={installVitePlus,prepareCacheMetadata,configureAuth,setupSfw,parseRunInstall,runInstall,getCommandOutput,run,parseInstalledVpVersion,prependPath,setVariable,logWarning,logInfo};function fail(e){console.error(`setup-vp: ${e}`),process.exit(1)}async function runPrepare(e=process.env,t=ut){let n=parseAzureInputs(e),i=resolveProjectDirFromInputs(n);if(n.nodeManager===!1&&(n.nodeVersion||n.nodeVersionFile))throw Error(`node-version and node-version-file cannot be used with node-manager: false`);let a={...resolutionContext(n.workspaceRoot),info:t.logInfo,warning:t.logWarning},o=createVersionResolver(a).resolveVitePlusVersion(n,i),s=n.nodeVersion||(n.nodeVersionFile?createNodeVersionResolver(a).resolveNodeVersionFile(n.nodeVersionFile,i):void 0);t.setVariable(`SETUP_VP_CACHE_HIT`,`false`),t.setVariable(`SETUP_VP_CACHE_READY`,`false`),t.setVariable(`SETUP_VP_SFW_READY`,`false`),t.setVariable(`SETUP_VP_BOOTSTRAP_NODE`,process.execPath),await t.installVitePlus(o,{env:e,prependPath:e=>t.prependPath(e),exportPath:e=>t.setVariable(`PATH`,e),logWarningFn:t.logWarning}),t.setVariable(`SETUP_VP_RESOLVED_VERSION`,o);let c=(n.nodeManager===!1||n.packageManager!==void 0)&&t.getCommandOutput(`vp`,[`--version`])||``,l=packageManagerArgs(n.packageManager,c);n.nodeManager===!1?t.run(`vp`,nodeManagerOffArgs(c)):s&&t.run(`vp`,[`env`,`use`,s],{cwd:i});for(let e of l)t.run(`vp`,e);let d=u.resolve(process.argv[1]||``);if(t.setVariable(`SETUP_VP_RUNTIME_PATH`,d),n.sfw&&!pkgPrNewCommitSha(o)&&t.parseRunInstall(n.runInstall).length>0)try{let i=getSfwAssetName(process.platform,process.arch,isMuslLinux()),a=u.join(e.PIPELINE_WORKSPACE||n.workspaceRoot,`.setup-vp-sfw`);r(a,{recursive:!0}),t.setVariable(`SETUP_VP_SFW_CACHE_DIR`,a),t.setVariable(`SETUP_VP_SFW_CACHE_KEY`,`${Q}-${i}`),t.setVariable(`SETUP_VP_SFW_READY`,`true`)}catch(e){t.logWarning(String(e))}if(!n.cache)return;let f=t.prepareCacheMetadata({projectDir:i,cacheDependencyPath:n.cacheDependencyPath||void 0,logWarning:t.logWarning});if(!f.ready){t.setVariable(`SETUP_VP_CACHE_READY`,`false`);return}t.setVariable(`SETUP_VP_CACHE_READY`,`true`),f.cachePath&&t.setVariable(`SETUP_VP_CACHE_PATH`,f.cachePath),f.lockFile&&t.setVariable(`SETUP_VP_LOCK_FILE`,f.lockFile),f.lockType&&t.setVariable(`SETUP_VP_LOCK_TYPE`,f.lockType)}async function runFinalize(e=process.env,t=ut){let n=parseAzureInputs(e),r=resolveProjectDirFromInputs(n),i=analyzeProjectNpmrc(readNpmrc(u.join(r,`.npmrc`))).envVarRefs;i.add(`NODE_AUTH_TOKEN`);for(let t of i)!isReservedAuthVariable(t)&&/^\$\([^)]+\)$/.test(e[t]||``)&&delete e[t];t.configureAuth(n.registryUrl,n.scope,e,(e,n)=>{e!==`NODE_AUTH_TOKEN`&&n!==void 0&&t.setVariable(e,n,{isSecret:e!==`NPM_CONFIG_USERCONFIG`&&e!==`PNPM_CONFIG_USERCONFIG`})},r);let a=t.parseRunInstall(n.runInstall),o=await t.setupSfw(a,{env:e,sfwEnabled:n.sfw,vitePlusVersion:e.SETUP_VP_RESOLVED_VERSION||n.version,logWarning:t.logWarning,exportVariable:(e,n)=>{n!==void 0&&(e===`PATH`?t.prependPath(n.split(u.delimiter)[0]):t.setVariable(e,n))}});a.length>0&&await t.runInstall(a,r,o,e);let s=t.getCommandOutput(`vp`,[`--version`],{cwd:r});if(!s)throw Error(`Failed to verify Vite+ installation: vp --version failed or returned no output.`);t.logInfo(s);let c=t.parseInstalledVpVersion(s);t.setVariable(`SETUP_VP_INSTALLED_VERSION`,c),t.setVariable(`version`,c,{isOutput:!0}),t.setVariable(`cacheHit`,String(e.SETUP_VP_CACHE_HIT===`true`),{isOutput:!0})}async function main(e){if(e===`prepare`){await runPrepare();return}if(e===`finalize`){await runFinalize();return}fail(`invalid phase "${String(e)}"; expected "prepare" or "finalize"`)}function isEntrypoint(e=process.argv[1],t=import.meta.url){return!!(e&&t===_(u.resolve(e)).href)}if(isEntrypoint()){let e=process.argv[2];e||fail(`missing phase argument; expected "prepare" or "finalize"`);try{await main(e)}catch(e){fail(e instanceof Error?e.message:String(e))}}export{isEntrypoint,main,runFinalize,runPrepare}; \ No newline at end of file +fi`:`bash "$installer_file"`} +`.trim()]}}const lt=2e3;function getVitePlusHome(e=process.platform,t=process.env){let n=isWindows(e)?t.USERPROFILE||b():t.HOME||b();return m(n,`.vite-plus`)}function runInstallCommand(e,t,n){let{command:r,args:i}=getInstallScriptCommand(e,n,t.VP_VPDIRS_AWARE===`1`),a={env:{...process.env,...t},stdio:`inherit`},o=y(r,i,a);if(isWindows(n)&&o.error?.code===`ENOENT`&&(o=y(`powershell.exe`,i,a)),o.error)throw o.error;return o.status??1}async function installVitePlus(e,t={}){let n=t.platform??process.platform,r=t.env??process.env,i=t.prependPath,a=t.sleep??te,o=t.runInstall??runInstallCommand,s=t.logWarningFn??console.warn,c={...Object.fromEntries(Object.entries(r).filter(e=>e[1]!==void 0)),VP_VERSION:e,VITE_PLUS_VERSION:e},l=supportsVitePlusDirs(e)?createVitePlusDirsFile():void 0;l?(c.VP_VPDIRS_AWARE=`1`,c[$]=l):(delete c.VP_VPDIRS_AWARE,delete c[$]);let u=pkgPrNewCommitSha(e);u&&(c.VP_PR_VERSION=u);let{pinned:d,fallback:f}=getInstallScriptSources(e,n),p=d.length+f.length,h=2*p,g=``,_=0;async function tryUrls(e){for(let t=0;t<2;t+=1)for(let t of e){let{url:e}=t;_+=1;try{let e=o(t,c,n);if(e===0)return!0;g=`exit code ${e}`}catch(e){g=e instanceof Error?e.message:String(e)}_0){if(await tryUrls(d)){ensureBinInPath();return}s(`setup-vp: could not fetch the install script pinned to Vite+ ${e}. Falling back to the checksum-pinned default install script. The default script may not be compatible with ${e}.`)}if(await tryUrls(f)){ensureBinInPath();return}throw Error(`Failed to install Vite+ after ${h} attempts across ${p} URL(s): ${g}`)}finally{l&&removeVitePlusDirsFile(l)}}function parseBoolean(e){return e?.toLowerCase()===`true`}function parseAzureInputs(e){return{version:e.SETUP_VP_VERSION||``,versionFile:e.SETUP_VP_VERSION_FILE||void 0,nodeVersion:e.SETUP_VP_NODE_VERSION||void 0,nodeVersionFile:e.SETUP_VP_NODE_VERSION_FILE||void 0,workingDirectory:e.SETUP_VP_WORKING_DIRECTORY||`.`,runInstall:e.SETUP_VP_RUN_INSTALL??`true`,sfw:parseBoolean(e.SETUP_VP_SFW),nodeManager:parseNodeManager(e.SETUP_VP_NODE_MANAGER),packageManager:parsePackageManager(e.SETUP_VP_PACKAGE_MANAGER),registryUrl:e.SETUP_VP_REGISTRY_URL||``,scope:e.SETUP_VP_SCOPE||``,cache:parseBoolean(e.SETUP_VP_CACHE),cacheDependencyPath:e.SETUP_VP_CACHE_DEPENDENCY_PATH||``,workspaceRoot:e.SYSTEM_DEFAULTWORKINGDIRECTORY||process.cwd()}}function resolveProjectDirFromInputs(e){return resolveProjectDirectory({workingDirectory:e.workingDirectory,workspaceRoot:e.workspaceRoot})}const ut={installVitePlus,prepareCacheMetadata,configureAuth,setupSfw,parseRunInstall,runInstall,getCommandOutput,run,parseInstalledVpVersion,prependPath,setVariable,logWarning,logInfo};function fail(e){console.error(`setup-vp: ${e}`),process.exit(1)}async function runPrepare(e=process.env,t=ut){let n=parseAzureInputs(e),i=resolveProjectDirFromInputs(n);if(n.nodeManager===!1&&(n.nodeVersion||n.nodeVersionFile))throw Error(`node-version and node-version-file cannot be used with node-manager: false`);let a={...resolutionContext(n.workspaceRoot),info:t.logInfo,warning:t.logWarning},o=createVersionResolver(a).resolveVitePlusVersion(n,i),s=n.nodeVersion||(n.nodeVersionFile?createNodeVersionResolver(a).resolveNodeVersionFile(n.nodeVersionFile,i):void 0);t.setVariable(`SETUP_VP_CACHE_HIT`,`false`),t.setVariable(`SETUP_VP_CACHE_READY`,`false`),t.setVariable(`SETUP_VP_SFW_READY`,`false`),t.setVariable(`SETUP_VP_BOOTSTRAP_NODE`,process.execPath),await t.installVitePlus(o,{env:e,prependPath:e=>t.prependPath(e),exportPath:e=>t.setVariable(`PATH`,e),logWarningFn:t.logWarning}),t.setVariable(`SETUP_VP_RESOLVED_VERSION`,o);let c=(n.nodeManager===!1||n.packageManager!==void 0)&&t.getCommandOutput(`vp`,[`--version`])||``,l=packageManagerArgs(n.packageManager,c);n.nodeManager===!1?t.run(`vp`,nodeManagerOffArgs(c)):s&&t.run(`vp`,[`env`,`use`,s],{cwd:i});for(let e of l)t.run(`vp`,e);let d=u.resolve(process.argv[1]||``);if(t.setVariable(`SETUP_VP_RUNTIME_PATH`,d),n.sfw&&!pkgPrNewCommitSha(o)&&t.parseRunInstall(n.runInstall).length>0)try{let i=getSfwAssetName(process.platform,process.arch,isMuslLinux()),a=u.join(e.PIPELINE_WORKSPACE||n.workspaceRoot,`.setup-vp-sfw`);r(a,{recursive:!0}),t.setVariable(`SETUP_VP_SFW_CACHE_DIR`,a),t.setVariable(`SETUP_VP_SFW_CACHE_KEY`,`${Q}-${i}`),t.setVariable(`SETUP_VP_SFW_READY`,`true`)}catch(e){t.logWarning(String(e))}if(!n.cache)return;let f=t.prepareCacheMetadata({projectDir:i,cacheDependencyPath:n.cacheDependencyPath||void 0,logWarning:t.logWarning});if(!f.ready){t.setVariable(`SETUP_VP_CACHE_READY`,`false`);return}t.setVariable(`SETUP_VP_CACHE_READY`,`true`),f.cachePath&&t.setVariable(`SETUP_VP_CACHE_PATH`,f.cachePath),f.lockFile&&t.setVariable(`SETUP_VP_LOCK_FILE`,f.lockFile),f.lockType&&t.setVariable(`SETUP_VP_LOCK_TYPE`,f.lockType)}async function runFinalize(e=process.env,t=ut){let n=parseAzureInputs(e),r=resolveProjectDirFromInputs(n),i=analyzeProjectNpmrc(readNpmrc(u.join(r,`.npmrc`))).envVarRefs;i.add(`NODE_AUTH_TOKEN`);for(let t of i)!isReservedAuthVariable(t)&&/^\$\([^)]+\)$/.test(e[t]||``)&&delete e[t];t.configureAuth(n.registryUrl,n.scope,e,(e,n)=>{e!==`NODE_AUTH_TOKEN`&&n!==void 0&&t.setVariable(e,n,{isSecret:e!==`NPM_CONFIG_USERCONFIG`&&e!==`PNPM_CONFIG_USERCONFIG`})},r);let a=t.parseRunInstall(n.runInstall),o=await t.setupSfw(a,{env:e,sfwEnabled:n.sfw,vitePlusVersion:e.SETUP_VP_RESOLVED_VERSION||n.version,logWarning:t.logWarning,exportVariable:(e,n)=>{n!==void 0&&(e===`PATH`?t.prependPath(n.split(u.delimiter)[0]):t.setVariable(e,n))}});a.length>0&&await t.runInstall(a,r,o,e);let s=t.getCommandOutput(`vp`,[`--version`],{cwd:r});if(!s)throw Error(`Failed to verify Vite+ installation: vp --version failed or returned no output.`);t.logInfo(s);let c=t.parseInstalledVpVersion(s);t.setVariable(`SETUP_VP_INSTALLED_VERSION`,c),t.setVariable(`version`,c,{isOutput:!0}),t.setVariable(`cacheHit`,String(e.SETUP_VP_CACHE_HIT===`true`),{isOutput:!0})}async function main(e){if(e===`prepare`){await runPrepare();return}if(e===`finalize`){await runFinalize();return}fail(`invalid phase "${String(e)}"; expected "prepare" or "finalize"`)}function isEntrypoint(e=process.argv[1],t=import.meta.url){return!!(e&&t===_(u.resolve(e)).href)}if(isEntrypoint()){let e=process.argv[2];e||fail(`missing phase argument; expected "prepare" or "finalize"`);try{await main(e)}catch(e){fail(e instanceof Error?e.message:String(e))}}export{isEntrypoint,main,runFinalize,runPrepare}; \ No newline at end of file diff --git a/dist/gitlab/index.mjs b/dist/gitlab/index.mjs index 5785bd0..48e46bf 100644 --- a/dist/gitlab/index.mjs +++ b/dist/gitlab/index.mjs @@ -138,10 +138,10 @@ n?this.stack.push(n):(yield*this.pop(),yield*this.step())}else{let t=this.peek(2 `)+1;for(;e!==0;)this.onNewLine(this.offset+e),e=this.source.indexOf(` `,e)+1}return{type:e,offset:this.offset,indent:this.indent,source:this.source}}startBlockValue(e){switch(this.type){case`alias`:case`scalar`:case`single-quoted-scalar`:case`double-quoted-scalar`:return this.flowScalar(this.type);case`block-scalar-header`:return{type:`block-scalar`,offset:this.offset,indent:this.indent,props:[this.sourceToken],source:``};case`flow-map-start`:case`flow-seq-start`:return{type:`flow-collection`,offset:this.offset,indent:this.indent,start:this.sourceToken,items:[],end:[]};case`seq-item-ind`:return{type:`block-seq`,offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken]}]};case`explicit-key-ind`:{this.onKeyLine=!0;let t=getFirstKeyStartProps(getPrevProps(e));return t.push(this.sourceToken),{type:`block-map`,offset:this.offset,indent:this.indent,items:[{start:t,explicitKey:!0}]}}case`map-value-ind`:{this.onKeyLine=!0;let t=getFirstKeyStartProps(getPrevProps(e));return{type:`block-map`,offset:this.offset,indent:this.indent,items:[{start:t,key:null,sep:[this.sourceToken]}]}}}return null}atIndentedComment(e,t){return this.type!==`comment`||this.indent<=t?!1:e.every(e=>e.type===`newline`||e.type===`space`)}*documentEnd(e){this.type!==`doc-mode`&&(e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type===`newline`&&(yield*this.pop()))}*lineEnd(e){switch(this.type){case`comma`:case`doc-start`:case`doc-end`:case`flow-seq-end`:case`flow-map-end`:case`map-value-ind`:yield*this.pop(),yield*this.step();break;case`newline`:this.onKeyLine=!1;default:e.end?e.end.push(this.sourceToken):e.end=[this.sourceToken],this.type===`newline`&&(yield*this.pop())}}}})),it=/* @__PURE__ */ __commonJSMin((e=>{var t=Xe(),n=G(),r=K(),i=he(),a=O(),o=nt(),s=rt();function parseOptions(e){let t=e.prettyErrors!==!1;return{lineCounter:e.lineCounter||t&&new o.LineCounter||null,prettyErrors:t}}function parseAllDocuments(e,n={}){let{lineCounter:i,prettyErrors:a}=parseOptions(n),o=new s.Parser(i?.addNewLine),c=new t.Composer(n),l=Array.from(c.compose(o.parse(e)));if(a&&i)for(let t of l)t.errors.forEach(r.prettifyError(e,i)),t.warnings.forEach(r.prettifyError(e,i));return l.length>0?l:Object.assign([],{empty:!0},c.streamInfo())}function parseDocument(e,n={}){let{lineCounter:i,prettyErrors:a}=parseOptions(n),o=new s.Parser(i?.addNewLine),c=new t.Composer(n),l=null;for(let t of c.compose(o.parse(e),!0,e.length))if(!l)l=t;else if(l.options.logLevel!==`silent`){l.errors.push(new r.YAMLParseError(t.range.slice(0,2),`MULTIPLE_DOCS`,`Source contains multiple documents; please use YAML.parseAllDocuments()`));break}return a&&i&&(l.errors.forEach(r.prettifyError(e,i)),l.warnings.forEach(r.prettifyError(e,i))),l}function parse(e,t,n){let r;typeof t==`function`?r=t:n===void 0&&t&&typeof t==`object`&&(n=t);let a=parseDocument(e,n);if(!a)return null;if(a.warnings.forEach(e=>i.warn(a.options.logLevel,e)),a.errors.length>0){if(a.options.logLevel!==`silent`)throw a.errors[0];a.errors=[]}return a.toJS(Object.assign({reviver:r},n))}function stringify(e,t,r){let i=null;if(typeof t==`function`||Array.isArray(t)?i=t:r===void 0&&t&&(r=t),typeof r==`string`&&(r=r.length),typeof r==`number`){let e=Math.round(r);r=e<1?void 0:e>8?{indent:8}:{indent:e}}if(e===void 0){let{keepUndefined:e}=r??t??{};if(!e)return}return a.isDocument(e)&&!i?e.toString(r):new n.Document(e,i,r).toString(r)}e.parse=parse,e.parseAllDocuments=parseAllDocuments,e.parseDocument=parseDocument,e.stringify=stringify})),Y=(/* @__PURE__ */ __commonJSMin((e=>{var t=Xe(),n=G(),r=Fe(),i=K(),a=M(),o=O(),s=R(),c=N(),l=z(),u=V();et();var d=tt(),f=nt(),p=rt(),m=it(),h=k();e.Composer=t.Composer,e.Document=n.Document,e.Schema=r.Schema,e.YAMLError=i.YAMLError,e.YAMLParseError=i.YAMLParseError,e.YAMLWarning=i.YAMLWarning,e.Alias=a.Alias,e.isAlias=o.isAlias,e.isCollection=o.isCollection,e.isDocument=o.isDocument,e.isMap=o.isMap,e.isNode=o.isNode,e.isPair=o.isPair,e.isScalar=o.isScalar,e.isSeq=o.isSeq,e.Pair=s.Pair,e.Scalar=c.Scalar,e.YAMLMap=l.YAMLMap,e.YAMLSeq=u.YAMLSeq,e.Lexer=d.Lexer,e.LineCounter=f.LineCounter,e.Parser=p.Parser,e.parse=m.parse,e.parseAllDocuments=m.parseAllDocuments,e.parseDocument=m.parseDocument,e.stringify=m.stringify,e.visit=h.visit,e.visitAsync=h.visitAsync})))();const X=`Vite+`,Z=`vite-plus`;function resolvePath$1(e,t){return h.isAbsolute(e)?e:h.join(t,e)}function isWithin(e,t){let n=h.relative(t,e);return!h.isAbsolute(n)&&n!==`..`&&!n.startsWith(`..${h.sep}`)}function resolveProjectDirectory(e){let{workingDirectory:t,workspaceRoot:n}=e,r=h.isAbsolute(t)?t:h.join(n,t);try{if(!f(r).isDirectory())throw Error(`working-directory is not a directory: ${t} (resolved to ${r})`)}catch(e){throw e instanceof Error&&`code`in e&&e.code===`ENOENT`?Error(`working-directory not found: ${t} (resolved to ${r})`):e}return r}function isWindows(e=process.platform){return e===`win32`}function run(e,t,n={}){let r=w(e,t,{stdio:`inherit`,...n});if(r.error)throw r.error;if(r.status!==0)throw Error(`${e} ${t.join(` `)} exited with code ${r.status??1}`)}function runWithOutput(e,t,n={}){return new Promise((r,i)=>{let a=C(e,t,{...n,stdio:[`ignore`,`pipe`,`pipe`]}),o=``,s=``;a.stdout.on(`data`,e=>{process.stdout.write(e),o=(o+e.toString()).slice(-4e3)}),a.stderr.on(`data`,e=>{process.stderr.write(e),s=(s+e.toString()).slice(-4e3)}),a.on(`error`,i),a.on(`close`,e=>r({exitCode:e??1,stdout:o,stderr:s}))})}function commandPath(e){if(isWindows()){let t=w(`where`,[e],{encoding:`utf8`});return t.status===0&&t.stdout.trim().split(/\r?\n/)[0]?.trim()||void 0}let t=w(`sh`,[`-c`,`command -v "$1"`,`sh`,e],{encoding:`utf8`});if(t.status===0)return t.stdout.trim()}function getCommandOutput(e,t,n){let r=w(e,t,{cwd:n?.cwd,encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`]});if(r.status===0)return r.stdout.trim()}const at=[{filename:`pnpm-lock.yaml`,type:`pnpm`},{filename:`bun.lockb`,type:`bun`},{filename:`bun.lock`,type:`bun`},{filename:`package-lock.json`,type:`npm`},{filename:`npm-shrinkwrap.json`,type:`npm`},{filename:`yarn.lock`,type:`yarn`}];function resolvePath(e,t){return v(e)?e:y(t,e)}function inferLockFileType(e,t){return t.includes(`pnpm`)?{type:`pnpm`,path:e,filename:t}:t.includes(`yarn`)?{type:`yarn`,path:e,filename:t}:t.startsWith(`bun.`)?{type:`bun`,path:e,filename:t}:{type:`npm`,path:e,filename:t}}function detectLockFile(e,t){if(e){let n=resolvePath(e,t);if(i(n)){let e=g(n),t=at.find(t=>t.filename===e);return t?{type:t.type,path:n,filename:e}:inferLockFileType(n,e)}return}let n=l(t);for(let e of at)if(n.includes(e.filename)){let n=y(t,e.filename);return{type:e.type,path:n,filename:e.filename}}}function prepareCacheMetadata(e){let{projectDir:t,cacheDependencyPath:n,logWarning:r}=e,i=detectLockFile(n||void 0,t);if(!i)return r?.(`setup-vp: cache is enabled but no supported lock file was found; skipping cache.`),{ready:!1};let a=getCommandOutput(`vp`,[`pm`,`cache`,`dir`],{cwd:h.dirname(i.path)});return a?{ready:!0,cachePath:a,lockFile:i.path,lockType:i.type}:(r?.(`setup-vp: could not resolve package-manager cache directory for ${i.filename}; skipping cache.`),{ready:!1})}function createLockfileResolver(e){let{getWorkspaceDir:t,info:n,debug:r}=e,a=/^\d+\.\d+\.\d+/;function tryResolveVitePlusVersionFromLockfile(e,t){let i=detectLockfileForProject(e,t);if(!i)return;let a=i.filename.endsWith(`.lockb`)?textBunLockBeside(i):i;if(!a){r(`Cannot read ${i.filename} (binary) to resolve the ${X} version; using "latest". Use the text bun.lock, or set the \`version\` input.`);return}let o=parseVitePlusVersionFromLockfile(a,workspaceSubPath(_(a.path),e));if(o)return n(`Resolved ${X} version '${o}' from ${a.filename}`),o;r(`No ${X} version found in ${a.path}`)}function detectLockfileForProject(e,n){if(n)return detectLockFile(n,e);let r=t(),i=e;for(;;){let e=detectLockFile(void 0,i);if(e)return e;let t=_(i);if(i===r||t===i||!isWithin(t,r))break;i=t}}function textBunLockBeside(e){let t=y(_(e.path),`bun.lock`);return i(t)?{type:`bun`,path:t,filename:`bun.lock`}:void 0}function workspaceSubPath(e,t){if(!isWithin(t,e))return``;let n=b(e,t);return n?n.split(x).join(`/`):``}function parseVitePlusVersionFromLockfile(e,t=``){if(e.filename.endsWith(`.lockb`))return;let n;try{n=c(e.path,`utf-8`)}catch{return}let r;switch(e.type){case`npm`:r=fromNpmLock(n,t);break;case`pnpm`:r=fromPnpmLock(n,t);break;case`yarn`:r=fromYarnLock(n);break;case`bun`:r=fromBunTextLock(n);break;default:return}return r&&a.test(r)?r:void 0}function fromNpmLock(e,t){let n;try{n=JSON.parse(e)}catch{return}let r=n.packages;if(t){let e=r?.[`${t}/node_modules/${Z}`]?.version;if(typeof e==`string`)return e;if(!npmPackageDeclaresVitePlus(r?.[t]))return}let i=r?.[`node_modules/${Z}`]?.version;if(typeof i==`string`)return i;let a=n.dependencies?.[Z]?.version;return typeof a==`string`?a:void 0}function npmPackageDeclaresVitePlus(e){if(!e)return!1;for(let t of[`dependencies`,`devDependencies`]){let n=e[t];if(n&&typeof n==`object`&&`vite-plus`in n)return!0}return!1}function fromPnpmLock(e,t){let n;try{n=(0,Y.parse)(e)}catch{return}if(!n||typeof n!=`object`)return;let r=n,i=r.importers;if(i&&typeof i==`object`){let e=t||`.`;return e in i?pnpmImporterVersion(i[e]):void 0}return pnpmImporterVersion(r)||e.match(/^\s*\/?vite-plus@(\d+\.\d+\.\d+[^\s():'"]*)/m)?.[1]}function pnpmImporterVersion(e){if(!e||typeof e!=`object`)return;let t=e;for(let e of[`dependencies`,`devDependencies`,`optionalDependencies`]){let n=t[e];if(n&&typeof n==`object`){let e=n[Z],t=typeof e==`string`?e:e?.version;if(typeof t==`string`){let e=t.replace(/\(.*$/,``).trim();if(a.test(e))return e}}}}function fromYarnLock(e){let t=/* @__PURE__ */ new Set,n=e.split(/\r?\n/);for(let e=0;ee,info:console.info,debug:()=>{},warning:console.warn}}const ot=`https://raw.githubusercontent.com/voidzero-dev/vite-plus`,st=`packages/cli`,ct=/^0\.0\.0-commit\.([0-9a-f]{40})$/i,lt=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;function pkgPrNewCommitSha(e){return e.match(ct)?.[1]}function getInstallScriptUrls(e,t=process.platform){let n=isWindows(t)?`install.ps1`:`install.sh`,r=installScriptRef(e);return{pinned:r?[`${ot}/${r}/${st}/${n}`,`https://cdn.jsdelivr.net/gh/voidzero-dev/vite-plus@${r}/${st}/${n}`]:[],latest:[`https://viteplus.dev/${n}`,`${ot}/main/${st}/${n}`]}}function installScriptRef(e){let t=pkgPrNewCommitSha(e);if(t)return t.toLowerCase();if(lt.test(e))return`v${e}`}function parseInstalledVpVersion(e){return(e.match(/^\s*vp\s+v?(\d[^\s]*)/im)??e.match(/Global:\s*v?(\d[^\s]*)/i))?.[1]??`unknown`}const Q=`SETUP_VP_DIRS_FILE`;function getVitePlusBinDirs(e){let t=y(e.data,`fallback-bin`);return f(t,{throwIfNoEntry:!1})?.isDirectory()?{bin:e.bin,fallbackBin:t}:{bin:e.bin}}function appendFallbackBinToPath(e,t,n=process.platform){let r=isWindows(n)?`;`:`:`;return[...e?e.split(r).filter(e=>e!==t):[],t].join(r)}const ut=/^v?(\d+)\.(\d+)\.\d+(?:-[0-9A-Za-z.-]+)?$/;function supportsVitePlusDirs(e){if(pkgPrNewCommitSha(e))return!0;let t=e.match(ut);if(!t)return!0;let n=Number(t[1]),r=Number(t[2]);return n>0||r>=3}function createVitePlusDirsFile(){return y(E(),`setup-vp-dirs-${ne()}.txt`)}function removeVitePlusDirsFile(e){d(e,{force:!0})}function readVitePlusProbe(e){try{return c(e,`utf8`)}catch(e){if(e.code===`ENOENT`)return;throw e}}function resolveVitePlusBinDirs(e,t,n){if(!t){if(!supportsVitePlusDirs(e))return{bin:n};throw Error(`Vite+ was installed successfully, but setup-vp could not resolve its VpDirs.`)}let r=readVitePlusProbe(t),i=r===void 0?void 0:parseVitePlusDirs(r);if(i)return getVitePlusBinDirs(i);if(!(pkgPrNewCommitSha(e)!==void 0||ut.test(e))&&r!==void 0){let e=parseInstalledVpVersion(r);if(e!==`unknown`&&!supportsVitePlusDirs(e))return{bin:n}}throw Error(`Vite+ was installed successfully, but setup-vp could not resolve its VpDirs.`)}function parseVitePlusDirs(e){let t=/* @__PURE__ */ new Map;for(let n of e.split(/\r?\n/)){let e=n.indexOf(` `);if(e<1)continue;let r=n.slice(0,e).replace(/^\uFEFF/,``),i=n.slice(e+1).trim();i&&t.set(r,i)}let n=t.get(`data`),r=t.get(`bin`),i=t.get(`cache`),a=t.get(`config`),o=t.get(`state`);if(n&&r&&i&&a&&o)return{data:n,bin:r,cache:i,config:a,state:o}}function getInstallScriptCommand(e,t=process.platform,n=!0){if(isWindows(t))return n?{command:`pwsh`,args:[`-Command`,` +`)){let e=t.trim();if(!e||e.startsWith(`#`))continue;let[n,...r]=e.split(/\s+/);if(n===`nodejs`||n===`node`){for(let e of r)if(isAsdfInstallableVersion(e))return e}}}function isAsdfInstallableVersion(e){return!!e&&e!==`system`&&!e.startsWith(`ref:`)&&!e.startsWith(`path:`)}function parsePackageJson(e){let t;try{t=JSON.parse(e)}catch{throw Error(`Failed to parse package.json: invalid JSON`)}let n=t.devEngines;if(n?.runtime){let e=findNodeRuntime(n.runtime);if(e)return e}let r=t.engines;if(r?.node&&typeof r.node==`string`)return r.node}function findNodeRuntime(e){let t=Array.isArray(e)?e:[e];for(let e of t)if(e?.name===`node`&&typeof e.version==`string`)return e.version}return{resolveNodeVersionFile}}function resolutionContext(e){return{getWorkspaceDir:()=>e,info:console.info,debug:()=>{},warning:console.warn}}var ot=`1.1.0`,st={"1.1.0":{commit:`3aa366ee03ac162f5acfd8ee7c752a8245d904c6`,sh:`e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f`,ps1:`a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"1.0.0":{commit:`fc287d7b1c0dc008dbc65d1d2b2f51a44e2a5ea4`,sh:`e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f`,ps1:`a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"1.0.0-rc.1":{commit:`a9d81a4911190345408854b1c1f5cabdc8490a10`,sh:`e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f`,ps1:`a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"1.0.0-rc.0":{commit:`173e734826cdf79ef05ba91390c3508be5ebba3b`,sh:`e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f`,ps1:`a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"0.3.3":{commit:`45f9b9ac7128c2829f9130352ebcdc6462aca3d9`,sh:`6ed2d2847e5b7f3d67b6f91f2d28200bdffcffcd91ef2a336cf764d02776fcc3`,ps1:`bf909eed0675633eab5679fe1b40b1c313ee6e976a5ac732f2df3d35e39b0090`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"0.3.2":{commit:`9fd0d0ae6e775db361d3d5f9f3a18b47bc195420`,sh:`6ed2d2847e5b7f3d67b6f91f2d28200bdffcffcd91ef2a336cf764d02776fcc3`,ps1:`d202bcf693221f1b9732c73327dd4f3585614fadad647aebbf55b3eb453ab082`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"0.3.1":{commit:`13e1e5ab0d993d5a704d7bcb9419cee9aca79a7d`,sh:`d4a1ffa8245bdfcf39a786d545be6a43e231b771c32d7c02414bb96d4f5d9cdc`,ps1:`096c1948222a83b424f6b98417567ea4437414a85ed380fe74ec89c406e5cf86`},"0.3.0":{commit:`b2d15e3899dcc8adedfd45d98de9d30046a624f4`,sh:`3dd88cedb6d9b2665c305eda5413971417c8f183a819386148131b66a2cc6b2e`,ps1:`e803c4cdc20dce9a67eaa2f9780272336ef5bdaf40cc2d4366e8961cd11df572`},"0.2.9":{commit:`73bdd105c2b7c263b55f7e9b48a37a8933cc317a`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.8":{commit:`fc3f0e266d13f0ab288097e202edf4112534a1d2`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.7":{commit:`c17e1c3c7cf859a29dd32eb60e82dc8157449ac2`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.6":{commit:`cd064c68a45fb82badfc1853ff690b1b70511165`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.5":{commit:`93dc59a324f790603ce65e629c13617468d1027d`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.4":{commit:`1ca9f0fcef42bbfb9a5a559f3cc4553c49c80f8c`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.3":{commit:`7f70680f91ad51cc4f1dae3e6cceb194ae7dd0ea`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.2":{commit:`4f7fd0b66ebb5433acdb06f8660cf0f08c5a0d4b`,sh:`8b0a9835d871c4e67aee1c8d5b7e402d165cb55a3222743567a443028b33492e`,ps1:`7ecc798b6b749576215be5aee2b3f11e825115d48fe576cd5a0ecca7c039de71`},"0.2.1":{commit:`a0ed27069ea9eb65802def970ef554855993e0ac`,sh:`6f4fe3690a3f011b4b6cec3c71035e9c04a97dd45dd9e2623dc67f842268f0d2`,ps1:`60821b6f38a0eb984c5846722341f650e4d040c25e93add64aa134f199f86681`},"0.2.0":{commit:`6f97f097de8833b456e431270180b621b2309994`,sh:`6f4fe3690a3f011b4b6cec3c71035e9c04a97dd45dd9e2623dc67f842268f0d2`,ps1:`60821b6f38a0eb984c5846722341f650e4d040c25e93add64aa134f199f86681`},"0.1.24":{commit:`a1a2bbd6bf7e558277ab0f24f4e36243fc064043`,sh:`304d0267bea50d9f5400f3a826f0ae27884c22325b4d149d00a2ae4736c5a0cc`,ps1:`b54e90f2fd7749aa511248c34ac89afe868d7ac625a89074b1b3a7db03a1d02e`},"0.1.23":{commit:`2b3383748b576212ccb94dd2c647277e0bc4f5e2`,sh:`15242cab7c7832e2a3dc134e23059ce7726f7cca1467d78a79cd70760d3e3fb6`,ps1:`0611cb2777dc903ede063e303b84cc8193c49375b58eaba2db86c1c5c296719a`},"0.1.22":{commit:`12368dafa4a7b8c51fc1ef274c4cd5b60e6d3859`,sh:`15242cab7c7832e2a3dc134e23059ce7726f7cca1467d78a79cd70760d3e3fb6`,ps1:`0611cb2777dc903ede063e303b84cc8193c49375b58eaba2db86c1c5c296719a`},"0.1.21":{commit:`c61621ac610ad114746b98d7e457ca4e13171837`,sh:`8ca22990891df17cd808d7eedc3f8fcc722ad3a402191f6c125f36368af663f6`,ps1:`8a09b7b3ab975b134e1ec6d94daebe9cd531b2f3da9246fe8d9e38ee59df26c1`},"0.1.21-alpha.7":{commit:`c61621ac610ad114746b98d7e457ca4e13171837`,sh:`8ca22990891df17cd808d7eedc3f8fcc722ad3a402191f6c125f36368af663f6`,ps1:`8a09b7b3ab975b134e1ec6d94daebe9cd531b2f3da9246fe8d9e38ee59df26c1`},"0.1.21-alpha.6":{commit:`e134e4f84d7e3447d2fbd54fabf4efa928d6ce91`,sh:`8ca22990891df17cd808d7eedc3f8fcc722ad3a402191f6c125f36368af663f6`,ps1:`8a09b7b3ab975b134e1ec6d94daebe9cd531b2f3da9246fe8d9e38ee59df26c1`},"0.1.21-alpha.5":{commit:`634759714a507316148fd602a49dfceb87959b92`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.4":{commit:`dc41b711b8405fa42910fe186e8de2f58a51e14b`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.3":{commit:`7044ab9b003e42b5a5c9145dd7551da687d76989`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.2":{commit:`c4cdfc9666b5d0fd2fc2a9a4182ecb03afb5fa36`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.1":{commit:`cbd74649cf5d58dae8f309400f1754e418872f76`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.0":{commit:`7b9e6d6ce0cbc3bfef38b91034b493bc1739fc6e`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20":{commit:`bcc93a46abe94c543a0d36540dbd78aabfececfb`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.4":{commit:`bcc93a46abe94c543a0d36540dbd78aabfececfb`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.3":{commit:`210897e627ea27f2d7e0a7e5d2792aaf0e2775cc`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.2":{commit:`a5f36e08ef31ff9962b0b749652f57ab09fbdeb1`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.1":{commit:`fac1a20dd4f0f4990907ac67413c5c2b90a6ae42`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.0":{commit:`aeacdb0caacf2d7627c7b8df57011fb13bc040f5`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19":{commit:`41e78e2ba8ead352ca74aa32835489bfedfad63d`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19-alpha.3":{commit:`da5f14712472e185a825087f485cc4072b2ba8e7`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19-alpha.2":{commit:`4ac205f4434d6d362abc09e323991721da564f70`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19-alpha.1":{commit:`c5510b2f6de9976fde25c200aeed28b2f496a540`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19-alpha.0":{commit:`b9d218a6f9aa0c3b22fe85b6ad9229b0e135b31b`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.18":{commit:`6e06c175c71c725a46c409062c4c8d1fe1150449`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.18-alpha.0":{commit:`40a47e52cd596674a80203991013913555655f0d`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17":{commit:`e159b84a95199fc17a7ffddef14caeefc81c90f2`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.5":{commit:`48e49ca0c1c062989120c41bcce9ee1db8b172dd`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.4":{commit:`a5fca7ddca580725a3ba06efbd47ee573b60c50a`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.3":{commit:`a94deea2fc68b5a6a2e2f2868df32b6cc7bf7ec8`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.2":{commit:`2703014124101b30ec2470159d84d8f9a32dd285`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.1":{commit:`ba538e199ba23ca34f895af5b36564366990725b`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.0":{commit:`29f821e61f41e2068713676856d7363bf72e5896`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`c44111999449915902c9f0e0ddfa61ea1b3c3a0502ee4b1a3994a115abb4c5bc`},"0.1.16":{commit:`f64bb6c98c1ff577ba7e8ae4ddb43dcfcc3624b0`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`c44111999449915902c9f0e0ddfa61ea1b3c3a0502ee4b1a3994a115abb4c5bc`},"0.1.16-alpha.4":{commit:`556043129dc6a006cbdefd40b9c68ca306f086b5`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`c44111999449915902c9f0e0ddfa61ea1b3c3a0502ee4b1a3994a115abb4c5bc`},"0.1.16-alpha.3":{commit:`6153ccb787f9b35655c1702f3220e5c7a57ca997`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`53c0cfbb7e92719b18808611a977eb34312992c20cca8636d9f905c43184b860`},"0.1.16-alpha.2":{commit:`f72d8a1f86fde0945de6e362d1fd120043f635cd`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`53c0cfbb7e92719b18808611a977eb34312992c20cca8636d9f905c43184b860`},"0.1.16-alpha.1":{commit:`38aa60a7a087113364e5b80feceaa57d3100f766`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`53c0cfbb7e92719b18808611a977eb34312992c20cca8636d9f905c43184b860`},"0.1.16-alpha.0":{commit:`a015d7897617b7807ed0d825000fc1e7e9b18e67`,sh:`4057f586f65168077362203bcde2ea8ed07ec7ee3a560a35a20b974f4318c098`,ps1:`e9caf430aa09d14b82f5522aeb84b9321470d09512f2634e3d2dfda77d3645f6`},"0.1.15":{commit:`bf39b756ae038af3d34bbceeedc9ecf60afdd9a8`,sh:`437b3dbf8bed60740183083687801c037c318a48ba590ef5e2e06594ffd61530`,ps1:`299207f95a34b0e9a03df0bd7a77c80521b793740a5674aba80519ce7bd2c034`},"0.1.15-alpha.7":{commit:`f922d5fa560cae6f232cb1a74099c78587806ad3`,sh:`437b3dbf8bed60740183083687801c037c318a48ba590ef5e2e06594ffd61530`,ps1:`299207f95a34b0e9a03df0bd7a77c80521b793740a5674aba80519ce7bd2c034`},"0.1.15-alpha.6":{commit:`6cd75f480d9c10845d05d32be594c8cc6bce3c64`,sh:`437b3dbf8bed60740183083687801c037c318a48ba590ef5e2e06594ffd61530`,ps1:`299207f95a34b0e9a03df0bd7a77c80521b793740a5674aba80519ce7bd2c034`},"0.1.15-alpha.5":{commit:`dbe191ed95750571d9e02c33849c33c6789cfee4`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.4":{commit:`3af4839e659745492252020d78d519559e4a568d`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.3":{commit:`fd1b75e2ac170472017e3e601189fdfb3ed5f5d8`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.2":{commit:`3a85b2b65ba63d6706e58ca45d9b8ae1aa04d27a`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.1":{commit:`c267e06a0e254472983af686dd376efed5344d15`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.0":{commit:`94aecfa3edb591faf2b92835732090e41eba6dbb`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.14":{commit:`71b90b4eadd9795f354d3d5208decf904b92d927`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.14-alpha.3":{commit:`01693e3781bf854ff3fd1cd755f26ade1773ccc2`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.14-alpha.1":{commit:`0ff9227227bf58c48d46ea8814f21b1549f211cb`,sh:`cf9cfa219dce0fa7a9aba8f0804214af89d3321e0eec40ebc02371c7f08acba8`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.14-alpha.0":{commit:`fc9bf496ad50dba718a1544583d19eb47ff32534`,sh:`cf9cfa219dce0fa7a9aba8f0804214af89d3321e0eec40ebc02371c7f08acba8`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.13":{commit:`9861b670b32c53ea28dfb0b7e1189e533a13c5fd`,sh:`4f70075425f42ff90c304da5f74a586bd1bc4cfa79cdac2d5eff3dfd7176b845`,ps1:`7b6495786f059b2be584156884e68cb6da99f2ee6c0fddd6987c59fa604f794d`},"0.1.13-alpha.5":{commit:`2dfc0c3c81451233abe62ed49de1266ff5069a64`,sh:`4f70075425f42ff90c304da5f74a586bd1bc4cfa79cdac2d5eff3dfd7176b845`,ps1:`7b6495786f059b2be584156884e68cb6da99f2ee6c0fddd6987c59fa604f794d`},"0.1.13-alpha.4":{commit:`ffc1638a075632f9a1977f24467dcce5d31d00d1`,sh:`4f70075425f42ff90c304da5f74a586bd1bc4cfa79cdac2d5eff3dfd7176b845`,ps1:`7b6495786f059b2be584156884e68cb6da99f2ee6c0fddd6987c59fa604f794d`},"0.1.13-alpha.3":{commit:`d64cba8cda73af176453e0c25e7743d6ab25486f`,sh:`ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b`,ps1:`9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88`},"0.1.13-alpha.2":{commit:`9db93c21726781c7fe0d2d90b7373ad172af2dbc`,sh:`ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b`,ps1:`9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88`},"0.1.13-alpha.1":{commit:`849c1263bb9913dcd1a3fe0680b6cb8113639e06`,sh:`ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b`,ps1:`9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88`},"0.1.13-alpha.0":{commit:`b3d0e962b13118f3ff4097d224523833584326e6`,sh:`ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b`,ps1:`9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88`},"0.1.12":{commit:`8c6c1b23f1fe702f21ae72ff96979bfedb66364b`,sh:`43985e08bab995fba9c28923be6070d78f979c635c53ef7fd624a3103d9ce588`,ps1:`c40df7d8d632cd36d56b16e27006b0886dd51785e6033ca20bcbe3308901443c`},"0.1.12-alpha.2":{commit:`fe3189b64e0588ddae272ed6c4d49a8cbc23ce55`,sh:`2bc79f0370486d429783850b12e039672cc7f7236712c11a23d5b9405b05a597`,ps1:`c40df7d8d632cd36d56b16e27006b0886dd51785e6033ca20bcbe3308901443c`},"0.1.11":{commit:`ef77182006de701eb5260a68652f6dab6db7b760`,sh:`6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2`,ps1:`e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca`},"0.1.10":{commit:`1848576dcdb270611ce6e9c4b0b7ea7fdb223f32`,sh:`6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2`,ps1:`e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca`},"0.1.9":{commit:`b25efbd3c2a5ebdc18496e4ca2142f6449343952`,sh:`6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2`,ps1:`e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca`},"0.1.8":{commit:`0a1ec92c7b21d73317c9f3d796a35c8c9f14d0f1`,sh:`6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2`,ps1:`e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca`},"0.1.7":{commit:`a7dc6660a4e0f488a061d6350222adabdf763f5b`,sh:`a8378abdf90ce4a95352f1f9918d54bd666ec347ff9cad0c3bbfa2fef6db62cd`,ps1:`7462b3bb999b14f138d15df47a84dbdb3a7be96f56f77e9626e6624b6640eafc`},"0.1.6":{commit:`0c40c50cb395317ca3b35508e286018114b6372c`,sh:`a8378abdf90ce4a95352f1f9918d54bd666ec347ff9cad0c3bbfa2fef6db62cd`,ps1:`7462b3bb999b14f138d15df47a84dbdb3a7be96f56f77e9626e6624b6640eafc`},"0.1.5":{commit:`133340675e7eb9de8e0d8ffd8efb9de619ba6a39`,sh:`3316073e62247a9b8fc34f1be8b24047e3e3315749cc52d68eeccae2462f78d1`,ps1:`722de6e4ab17a6f853100055f522a2fec3a3255c394bc29be1d5fc3b6ed8f120`},"0.1.4":{commit:`12abba5def4cf4479f226188c0b24e04d15f3181`,sh:`3316073e62247a9b8fc34f1be8b24047e3e3315749cc52d68eeccae2462f78d1`,ps1:`722de6e4ab17a6f853100055f522a2fec3a3255c394bc29be1d5fc3b6ed8f120`},"0.1.3":{commit:`c0c8ebda74ac78bb70a73ebf4de67865079c9b38`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.2":{commit:`dfb9d4b258b11f6842c7b62f228617d4065f5a83`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.1":{commit:`8c5823fa0d19d7e186115963d1ff7ff58fa30576`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.1-alpha.0":{commit:`bdef013b286275979c9e593fe564c686b3d7130b`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.0":{commit:`cf4df93a8fd7f6b871f98766fb2c6a6578f2d8bc`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.0-alpha.0":{commit:`82f57fbb4d53b99d023d923979f2b2f08ff5e18f`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`}};const ct=/^0\.0\.0-commit\.([0-9a-f]{40})$/i;function pkgPrNewCommitSha(e){return e.match(ct)?.[1]}const lt=st;function getInstallScriptSources(e,t=process.platform){let n=isWindows(t)?`ps1`:`sh`;function sources(e){let t=`packages/cli/install.${n}`;return[`https://raw.githubusercontent.com/voidzero-dev/vite-plus/${e.commit}/${t}`,`https://cdn.jsdelivr.net/gh/voidzero-dev/vite-plus@${e.commit}/${t}`].map(t=>{let r=e[`legacy_${n}`];return{url:t,sha256:e[n],...r?{legacy:{url:t.replace(`install.${n}`,`install-legacy.${n}`),sha256:r}}:{}}})}let r=Object.hasOwn(lt,e)?lt[e]:void 0,i=lt[ot];return{pinned:r&&r.commit!==i.commit?sources(r):[],fallback:sources(i)}}function parseInstalledVpVersion(e){return(e.match(/^\s*vp\s+v?(\d[^\s]*)/im)??e.match(/Global:\s*v?(\d[^\s]*)/i))?.[1]??`unknown`}const Q=`SETUP_VP_DIRS_FILE`;function getVitePlusBinDirs(e){let t=y(e.data,`fallback-bin`);return f(t,{throwIfNoEntry:!1})?.isDirectory()?{bin:e.bin,fallbackBin:t}:{bin:e.bin}}function appendFallbackBinToPath(e,t,n=process.platform){let r=isWindows(n)?`;`:`:`;return[...e?e.split(r).filter(e=>e!==t):[],t].join(r)}const ut=/^v?(\d+)\.(\d+)\.\d+(?:-[0-9A-Za-z.-]+)?$/;function supportsVitePlusDirs(e){if(pkgPrNewCommitSha(e))return!0;let t=e.match(ut);if(!t)return!0;let n=Number(t[1]),r=Number(t[2]);return n>0||r>=3}function createVitePlusDirsFile(){return y(E(),`setup-vp-dirs-${ne()}.txt`)}function removeVitePlusDirsFile(e){d(e,{force:!0})}function readVitePlusProbe(e){try{return c(e,`utf8`)}catch(e){if(e.code===`ENOENT`)return;throw e}}function resolveVitePlusBinDirs(e,t,n){if(!t){if(!supportsVitePlusDirs(e))return{bin:n};throw Error(`Vite+ was installed successfully, but setup-vp could not resolve its VpDirs.`)}let r=readVitePlusProbe(t),i=r===void 0?void 0:parseVitePlusDirs(r);if(i)return getVitePlusBinDirs(i);if(!(pkgPrNewCommitSha(e)!==void 0||ut.test(e))&&r!==void 0){let e=parseInstalledVpVersion(r);if(e!==`unknown`&&!supportsVitePlusDirs(e))return{bin:n}}throw Error(`Vite+ was installed successfully, but setup-vp could not resolve its VpDirs.`)}function parseVitePlusDirs(e){let t=/* @__PURE__ */ new Map;for(let n of e.split(/\r?\n/)){let e=n.indexOf(` `);if(e<1)continue;let r=n.slice(0,e).replace(/^\uFEFF/,``),i=n.slice(e+1).trim();i&&t.set(r,i)}let n=t.get(`data`),r=t.get(`bin`),i=t.get(`cache`),a=t.get(`config`),o=t.get(`state`);if(n&&r&&i&&a&&o)return{data:n,bin:r,cache:i,config:a,state:o}}function getInstallScriptCommand(e,t=process.platform,n=!0){let r=[{...e,name:isWindows(t)?`install.ps1`:`install.sh`}];e.legacy&&r.push({...e.legacy,name:isWindows(t)?`install-legacy.ps1`:`install-legacy.sh`});for(let e of r)if(!/^[a-f0-9]{64}$/.test(e.sha256))throw Error(`A trusted SHA-256 checksum is required for the Vite+ installer.`);if(isWindows(t)){let e=` $dirsFile = $env:${Q} Set-Content -LiteralPath $dirsFile -Value '' -NoNewline -Encoding UTF8 -. ([scriptblock]::Create((irm -TimeoutSec 15 ${e}))) +. $installerFile $vpDir = if ($script:ShimDir) { $script:ShimDir } elseif ($InstallDir) { @@ -158,33 +158,58 @@ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } $env:VP_DUMP_DIRS = '1' & $vpPath | Add-Content -LiteralPath $dirsFile -Encoding UTF8 if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } -`.trim()]}:{command:`pwsh`,args:[`-Command`,`& ([scriptblock]::Create((irm -TimeoutSec 15 ${e})))`]};let r=` +`.trim();return{command:`pwsh`,args:[`-ExecutionPolicy`,`Bypass`,`-Command`,` +$ErrorActionPreference = 'Stop' +$installerDir = Join-Path ([System.IO.Path]::GetTempPath()) ('setup-vp-install-' + [guid]::NewGuid().ToString('N')) +$null = New-Item -ItemType Directory -Path $installerDir +$installerFile = Join-Path $installerDir 'install.ps1' +try { + ${r.map(({url:e,sha256:t,name:n})=>` + $downloadFile = Join-Path $installerDir '${n}' + Invoke-WebRequest -UseBasicParsing -TimeoutSec 15 -Uri '${e.replaceAll(`'`,`''`)}' -OutFile $downloadFile + if ((Get-FileHash -LiteralPath $downloadFile -Algorithm SHA256).Hash -ne '${t}') { + throw 'setup-vp: installer SHA-256 checksum mismatch; refusing to execute it.' + }`).join(` +`)} + $global:LASTEXITCODE = 0 + ${n?e:`& $installerFile +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }`} +} finally { + Remove-Item -LiteralPath $installerDir -Recurse -Force +} +`.trim()]}}let quote=e=>`'${e.replaceAll(`'`,`'\\''`)}'`;return{command:`bash`,args:[`-c`,` +set +u +set -eo pipefail +installer_dir="$(mktemp -d "\${TMPDIR:-/tmp}/setup-vp-install.XXXXXX")" +trap 'rm -rf "$installer_dir"' EXIT +installer_file="$installer_dir/install.sh" +${r.map(({url:e,sha256:t,name:n})=>` +download_file="$installer_dir/${n}" if command -v curl >/dev/null 2>&1; then - curl -fsSL --connect-timeout 5 --max-time 15 "${e}"${n?` -o "$installer_file"`:``} + curl -fsSL --connect-timeout 5 --max-time 15 ${quote(e)} -o "$download_file" elif command -v wget >/dev/null 2>&1; then - wget -q -T 15 -t 1 -O ${n?`"$installer_file"`:`-`} "${e}" + wget -q -T 15 -t 1 -O "$download_file" ${quote(e)} else echo "setup-vp: curl or wget is required to download the installer." >&2 exit 127 fi -`.trim();return n?{command:`bash`,args:[`-c`,` -set +u -set -eo pipefail -installer_file="$(mktemp "\${TMPDIR:-/tmp}/setup-vp-install.XXXXXX")" -trap 'rm -f "$installer_file"' EXIT -: > "$${Q}" -${r} +${quote(process.execPath)} -e ${quote(`const fs = require("node:fs"); +const crypto = require("node:crypto"); +const actual = crypto.createHash("sha256").update(fs.readFileSync(process.argv[1])).digest("hex"); +if (actual !== process.argv[2]) { + console.error("setup-vp: installer SHA-256 checksum mismatch; refusing to execute it."); + process.exit(1); +}`)} "$download_file" '${t}' +`).join(` +`)} +${n?`: > "$${Q}" source "$installer_file" vp_dir="\${SHIM_DIR:-\${INSTALL_DIR:-\${VP_HOME:-$HOME/.vite-plus}}/bin}" if [ -x "$vp_dir/vp" ]; then "$vp_dir/vp" --version > "$${Q}" VP_DUMP_DIRS=1 "$vp_dir/vp" >> "$${Q}" -fi -`.trim()]}:{command:`bash`,args:[`-c`,` -set +u -set -o pipefail -${r} | bash -`.trim()]}}const dt=2e3;function getVitePlusHome(e=process.platform,t=process.env){let n=isWindows(e)?t.USERPROFILE||T():t.HOME||T();return y(n,`.vite-plus`)}function runInstallCommand(e,t,n=process.platform){let{command:r,args:i}=getInstallScriptCommand(e,n,t.VP_VPDIRS_AWARE===`1`),a={env:{...process.env,...t},stdio:`inherit`},o=w(r,i,a);if(isWindows(n)&&o.error?.code===`ENOENT`&&(o=w(`powershell.exe`,i,a)),o.error)throw o.error;return o.status??1}async function installVitePlus(e,t={}){let n=t.platform??process.platform,r=t.env??process.env,i=t.prependPath,a=t.sleep??ee,o=t.runInstall??runInstallCommand,s=t.logWarningFn??console.warn,c={...Object.fromEntries(Object.entries(r).filter(e=>e[1]!==void 0)),VP_VERSION:e,VITE_PLUS_VERSION:e},l=supportsVitePlusDirs(e)?createVitePlusDirsFile():void 0;l?(c.VP_VPDIRS_AWARE=`1`,c[Q]=l):(delete c.VP_VPDIRS_AWARE,delete c[Q]);let u=pkgPrNewCommitSha(e);u&&(c.VP_PR_VERSION=u);let{pinned:d,latest:f}=getInstallScriptUrls(e,n),p=d.length+f.length,m=2*p,h=``,g=0;async function tryUrls(e){for(let t=0;t<2;t+=1)for(let t of e){g+=1;try{let e=o(t,c,n);if(e===0)return!0;h=`exit code ${e}`}catch(e){h=e instanceof Error?e.message:String(e)}g0){if(await tryUrls(d)){ensureBinInPath();return}s(`setup-vp: could not fetch the install script pinned to Vite+ ${e}. Falling back to the latest install script. The latest script may not be compatible with ${e}.`)}if(await tryUrls(f)){ensureBinInPath();return}throw Error(`Failed to install Vite+ after ${m} attempts across ${p} URL(s): ${h}`)}finally{l&&removeVitePlusDirsFile(l)}}function copyCacheDirectory(e,t,r){e=h.resolve(e),t=h.resolve(t),n(e,t,{recursive:!0,force:r,errorOnExist:!1,filter:(n,i)=>{let s=a(i,{throwIfNoEntry:!1}),c=a(n);if(s&&!r)return c.isDirectory()&&s.isDirectory();if(s&&(s.isSymbolicLink()||c.isSymbolicLink())&&d(i,{recursive:!0,force:!0}),c.isSymbolicLink()){let r=h.resolve(h.dirname(n),u(n)),a=r;if(isWithin(r,e)){let n=h.join(t,h.relative(e,r));a=h.relative(h.dirname(i),n)||`.`}return o(h.dirname(i),{recursive:!0}),p(a,i,f(r,{throwIfNoEntry:!1})?.isDirectory()?`dir`:`file`),!1}return!0}})}function restoreCacheSnapshot(e,t,n=console.warn,r=!0){if(!e.ready||!e.cachePath||!e.lockFile||!e.lockType)return{hit:!1,save:()=>{}};let a=e.cachePath;if(isWithin(h.resolve(a),h.resolve(t))||isWithin(h.resolve(t),h.resolve(a)))return n(`setup-vp: package-manager cache overlaps the snapshot directory; skipping cache.`),{hit:!1,save:()=>{}};let s=h.join(t,process.platform,process.arch,e.lockType),l=h.join(s,`packages`),u=h.join(s,`lock-hash`),d=e.lockFile;function hashLockFile(){return te(`sha256`).update(c(d)).digest(`hex`)}let f;try{f=hashLockFile()}catch(e){return n(`setup-vp: could not read cache lock file: ${String(e)}`),{hit:!1,save:()=>{}}}let p=!1;try{r&&i(l)&&(o(a,{recursive:!0}),copyCacheDirectory(l,a,!1),p=c(u,`utf8`)===f)}catch(e){n(`setup-vp: could not restore package-manager cache: ${String(e)}`)}return{hit:p,save:()=>{try{if(!i(a))return;let e=hashLockFile();o(s,{recursive:!0}),copyCacheDirectory(a,l,!0),m(u,e,`utf8`)}catch(e){n(`setup-vp: could not save package-manager cache: ${String(e)}`)}}}}const ft=/* @__PURE__ */ new Set([`true`,`True`,`TRUE`]),pt=/* @__PURE__ */ new Set([`false`,`False`,`FALSE`]);function parseNodeManager(e){if(e){if(ft.has(e))return!0;if(pt.has(e))return!1;throw Error(`Invalid node-manager input: "${e}". Expected "true", "false", or unset.`)}}function supportsScopedEnv(e){let t=parseInstalledVpVersion(e);if(t.startsWith(`0.0.0-commit.`))return!0;let n=t.match(/^(\d+)\.(\d+)\.(\d+)/);if(!n)throw Error(`Could not determine the installed Vite+ version for env configuration.`);let[,r,i,a]=n.map(Number);return r>0||i>3||i===3&&a>=1}function nodeManagerOffArgs(e){return parseInstalledVpVersion(e).startsWith(`0.0.0-commit.`)&&console.info("setup-vp: node-manager: false requires a preview build that supports `vp env off node`. If this command is unsupported, use a newer preview or a stable release. setup-vp will not fall back to disabling package-manager management."),supportsScopedEnv(e)?[`env`,`off`,`node`]:[`env`,`off`]}const mt=[`npm`,`pnpm`,`yarn`,`bun`];function parsePackageManager(e){if(!e?.trim())return;let t;try{t=(0,Y.parse)(e)}catch(e){throw Error(`Invalid package-manager input: ${String(e)}`)}if(t!==``){if(typeof t==`boolean`)return t;if(t&&typeof t==`object`&&!Array.isArray(t)){for(let[e,n]of Object.entries(t))if(!mt.includes(e)||typeof n!=`boolean`)throw Error(`Invalid package-manager input: ${e} must be npm, pnpm, yarn, or bun with a boolean value.`);return t}throw Error(`Invalid package-manager input: expected a boolean or a mapping of npm, pnpm, yarn, and bun to booleans.`)}}function packageManagerArgs(e,t){if(e===void 0)return[];if(!supportsScopedEnv(t))throw Error(`package-manager configuration requires Vite+ 0.3.1 or newer.`);return typeof e==`boolean`?e?[]:[[`env`,`off`,`pm`]]:mt.filter(t=>e[t]===!1).map(e=>[`env`,`off`,e])}function readNpmrc(e){try{return c(e,`utf8`)}catch(e){if(e.code===`ENOENT`)return``;throw e}}function analyzeProjectNpmrc(e){let t=/* @__PURE__ */ new Set;for(let n of e.split(/\r?\n/)){let e=n.trim();if(!e||e.startsWith(`;`)||e.startsWith(`#`))continue;let r=e.indexOf(`=`);if(r<0)continue;let i=e.slice(r+1).trim();for(let e of i.matchAll(/\$\{(\w+)\}/g))t.add(e[1])}return{envVarRefs:t}}function readUserConfigLines(e,t){let n=e.HOME||e.USERPROFILE,r=e.NPM_CONFIG_USERCONFIG||e.PNPM_CONFIG_USERCONFIG||n&&h.join(n,`.npmrc`);return(r?readNpmrc(r):``).split(/\r?\n/).filter(e=>!t.has(e.split(`=`)[0].trim().toLowerCase()))}function isReservedAuthVariable(e){return[`GITHUB_TOKEN`,`CI_JOB_TOKEN`,`SYSTEM_ACCESSTOKEN`].includes(e)?!1:/^(?:PATH|HOME|USERPROFILE|TMPDIR|CI)$/i.test(e)||/^(?:SETUP_VP_|RUNNER_|GITHUB_|CI_|SYSTEM_|AGENT_|BUILD_|RELEASE_)/i.test(e)}function writeUserConfig(e,t,n){let r=s(h.join(E(),`setup-vp-npmrc-`)),i=h.join(r,`.npmrc`);m(i,e,{encoding:`utf8`,mode:384});for(let e of[`NPM_CONFIG_USERCONFIG`,`PNPM_CONFIG_USERCONFIG`])t[e]=i,n?.(e,i);return i}function configureAuth$1(e,t,n,r,i){if(!e){if(!i)return;let{envVarRefs:e}=analyzeProjectNpmrc(readNpmrc(h.join(i,`.npmrc`)));for(let t of e)!isReservedAuthVariable(t)&&n[t]&&r?.(t,n[t]);return}let a;try{a=new URL(e)}catch{throw Error(`Invalid registry-url: "${e}". Must be a valid URL.`)}let o=a.href.endsWith(`/`)?a.href:`${a.href}/`,s=``;t&&(s=`${(t.startsWith(`@`)?t:`@${t}`).toLowerCase()}:`);let c=o.replace(/^\w+:/,``).toLowerCase(),l=readUserConfigLines(n,/* @__PURE__ */ new Set([`${s}registry`,`${c}:_authtoken`]));l.push(`${c}:_authToken=\${NODE_AUTH_TOKEN}`,`${s}registry=${o}`);let u=writeUserConfig(l.filter(Boolean).join(` +fi`:`bash "$installer_file"`} +`.trim()]}}const dt=2e3;function getVitePlusHome(e=process.platform,t=process.env){let n=isWindows(e)?t.USERPROFILE||T():t.HOME||T();return y(n,`.vite-plus`)}function runInstallCommand(e,t,n){let{command:r,args:i}=getInstallScriptCommand(e,n,t.VP_VPDIRS_AWARE===`1`),a={env:{...process.env,...t},stdio:`inherit`},o=w(r,i,a);if(isWindows(n)&&o.error?.code===`ENOENT`&&(o=w(`powershell.exe`,i,a)),o.error)throw o.error;return o.status??1}async function installVitePlus(e,t={}){let n=t.platform??process.platform,r=t.env??process.env,i=t.prependPath,a=t.sleep??ee,o=t.runInstall??runInstallCommand,s=t.logWarningFn??console.warn,c={...Object.fromEntries(Object.entries(r).filter(e=>e[1]!==void 0)),VP_VERSION:e,VITE_PLUS_VERSION:e},l=supportsVitePlusDirs(e)?createVitePlusDirsFile():void 0;l?(c.VP_VPDIRS_AWARE=`1`,c[Q]=l):(delete c.VP_VPDIRS_AWARE,delete c[Q]);let u=pkgPrNewCommitSha(e);u&&(c.VP_PR_VERSION=u);let{pinned:d,fallback:f}=getInstallScriptSources(e,n),p=d.length+f.length,m=2*p,h=``,g=0;async function tryUrls(e){for(let t=0;t<2;t+=1)for(let t of e){let{url:e}=t;g+=1;try{let e=o(t,c,n);if(e===0)return!0;h=`exit code ${e}`}catch(e){h=e instanceof Error?e.message:String(e)}g0){if(await tryUrls(d)){ensureBinInPath();return}s(`setup-vp: could not fetch the install script pinned to Vite+ ${e}. Falling back to the checksum-pinned default install script. The default script may not be compatible with ${e}.`)}if(await tryUrls(f)){ensureBinInPath();return}throw Error(`Failed to install Vite+ after ${m} attempts across ${p} URL(s): ${h}`)}finally{l&&removeVitePlusDirsFile(l)}}function copyCacheDirectory(e,t,r){e=h.resolve(e),t=h.resolve(t),n(e,t,{recursive:!0,force:r,errorOnExist:!1,filter:(n,i)=>{let s=a(i,{throwIfNoEntry:!1}),c=a(n);if(s&&!r)return c.isDirectory()&&s.isDirectory();if(s&&(s.isSymbolicLink()||c.isSymbolicLink())&&d(i,{recursive:!0,force:!0}),c.isSymbolicLink()){let r=h.resolve(h.dirname(n),u(n)),a=r;if(isWithin(r,e)){let n=h.join(t,h.relative(e,r));a=h.relative(h.dirname(i),n)||`.`}return o(h.dirname(i),{recursive:!0}),p(a,i,f(r,{throwIfNoEntry:!1})?.isDirectory()?`dir`:`file`),!1}return!0}})}function restoreCacheSnapshot(e,t,n=console.warn,r=!0){if(!e.ready||!e.cachePath||!e.lockFile||!e.lockType)return{hit:!1,save:()=>{}};let a=e.cachePath;if(isWithin(h.resolve(a),h.resolve(t))||isWithin(h.resolve(t),h.resolve(a)))return n(`setup-vp: package-manager cache overlaps the snapshot directory; skipping cache.`),{hit:!1,save:()=>{}};let s=h.join(t,process.platform,process.arch,e.lockType),l=h.join(s,`packages`),u=h.join(s,`lock-hash`),d=e.lockFile;function hashLockFile(){return te(`sha256`).update(c(d)).digest(`hex`)}let f;try{f=hashLockFile()}catch(e){return n(`setup-vp: could not read cache lock file: ${String(e)}`),{hit:!1,save:()=>{}}}let p=!1;try{r&&i(l)&&(o(a,{recursive:!0}),copyCacheDirectory(l,a,!1),p=c(u,`utf8`)===f)}catch(e){n(`setup-vp: could not restore package-manager cache: ${String(e)}`)}return{hit:p,save:()=>{try{if(!i(a))return;let e=hashLockFile();o(s,{recursive:!0}),copyCacheDirectory(a,l,!0),m(u,e,`utf8`)}catch(e){n(`setup-vp: could not save package-manager cache: ${String(e)}`)}}}}const ft=/* @__PURE__ */ new Set([`true`,`True`,`TRUE`]),pt=/* @__PURE__ */ new Set([`false`,`False`,`FALSE`]);function parseNodeManager(e){if(e){if(ft.has(e))return!0;if(pt.has(e))return!1;throw Error(`Invalid node-manager input: "${e}". Expected "true", "false", or unset.`)}}function supportsScopedEnv(e){let t=parseInstalledVpVersion(e);if(t.startsWith(`0.0.0-commit.`))return!0;let n=t.match(/^(\d+)\.(\d+)\.(\d+)/);if(!n)throw Error(`Could not determine the installed Vite+ version for env configuration.`);let[,r,i,a]=n.map(Number);return r>0||i>3||i===3&&a>=1}function nodeManagerOffArgs(e){return parseInstalledVpVersion(e).startsWith(`0.0.0-commit.`)&&console.info("setup-vp: node-manager: false requires a preview build that supports `vp env off node`. If this command is unsupported, use a newer preview or a stable release. setup-vp will not fall back to disabling package-manager management."),supportsScopedEnv(e)?[`env`,`off`,`node`]:[`env`,`off`]}const mt=[`npm`,`pnpm`,`yarn`,`bun`];function parsePackageManager(e){if(!e?.trim())return;let t;try{t=(0,Y.parse)(e)}catch(e){throw Error(`Invalid package-manager input: ${String(e)}`)}if(t!==``){if(typeof t==`boolean`)return t;if(t&&typeof t==`object`&&!Array.isArray(t)){for(let[e,n]of Object.entries(t))if(!mt.includes(e)||typeof n!=`boolean`)throw Error(`Invalid package-manager input: ${e} must be npm, pnpm, yarn, or bun with a boolean value.`);return t}throw Error(`Invalid package-manager input: expected a boolean or a mapping of npm, pnpm, yarn, and bun to booleans.`)}}function packageManagerArgs(e,t){if(e===void 0)return[];if(!supportsScopedEnv(t))throw Error(`package-manager configuration requires Vite+ 0.3.1 or newer.`);return typeof e==`boolean`?e?[]:[[`env`,`off`,`pm`]]:mt.filter(t=>e[t]===!1).map(e=>[`env`,`off`,e])}function readNpmrc(e){try{return c(e,`utf8`)}catch(e){if(e.code===`ENOENT`)return``;throw e}}function analyzeProjectNpmrc(e){let t=/* @__PURE__ */ new Set;for(let n of e.split(/\r?\n/)){let e=n.trim();if(!e||e.startsWith(`;`)||e.startsWith(`#`))continue;let r=e.indexOf(`=`);if(r<0)continue;let i=e.slice(r+1).trim();for(let e of i.matchAll(/\$\{(\w+)\}/g))t.add(e[1])}return{envVarRefs:t}}function readUserConfigLines(e,t){let n=e.HOME||e.USERPROFILE,r=e.NPM_CONFIG_USERCONFIG||e.PNPM_CONFIG_USERCONFIG||n&&h.join(n,`.npmrc`);return(r?readNpmrc(r):``).split(/\r?\n/).filter(e=>!t.has(e.split(`=`)[0].trim().toLowerCase()))}function isReservedAuthVariable(e){return[`GITHUB_TOKEN`,`CI_JOB_TOKEN`,`SYSTEM_ACCESSTOKEN`].includes(e)?!1:/^(?:PATH|HOME|USERPROFILE|TMPDIR|CI)$/i.test(e)||/^(?:SETUP_VP_|RUNNER_|GITHUB_|CI_|SYSTEM_|AGENT_|BUILD_|RELEASE_)/i.test(e)}function writeUserConfig(e,t,n){let r=s(h.join(E(),`setup-vp-npmrc-`)),i=h.join(r,`.npmrc`);m(i,e,{encoding:`utf8`,mode:384});for(let e of[`NPM_CONFIG_USERCONFIG`,`PNPM_CONFIG_USERCONFIG`])t[e]=i,n?.(e,i);return i}function configureAuth$1(e,t,n,r,i){if(!e){if(!i)return;let{envVarRefs:e}=analyzeProjectNpmrc(readNpmrc(h.join(i,`.npmrc`)));for(let t of e)!isReservedAuthVariable(t)&&n[t]&&r?.(t,n[t]);return}let a;try{a=new URL(e)}catch{throw Error(`Invalid registry-url: "${e}". Must be a valid URL.`)}let o=a.href.endsWith(`/`)?a.href:`${a.href}/`,s=``;t&&(s=`${(t.startsWith(`@`)?t:`@${t}`).toLowerCase()}:`);let c=o.replace(/^\w+:/,``).toLowerCase(),l=readUserConfigLines(n,/* @__PURE__ */ new Set([`${s}registry`,`${c}:_authtoken`]));l.push(`${c}:_authToken=\${NODE_AUTH_TOKEN}`,`${s}registry=${o}`);let u=writeUserConfig(l.filter(Boolean).join(` `)+` `,n,r);return n.NODE_AUTH_TOKEN=n.NODE_AUTH_TOKEN||`XXXXX-XXXXX-XXXXX-XXXXX`,r?.(`NODE_AUTH_TOKEN`,n.NODE_AUTH_TOKEN),u}function shellQuote(e){return`'${String(e).replaceAll(`'`,`'\\''`)}'`}function exportShellEnv(e,t,n=process.env){if(!n.SETUP_VP_ENV_FILE||t===void 0)return;if(!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(e))throw Error(`Invalid environment variable name`);let r=n.SETUP_VP_ENV_FORMAT===`powershell`?`$env:${e} = '${t.replaceAll(`'`,`''`)}'\n`:`export ${e}=${shellQuote(t)}\n`;m(n.SETUP_VP_ENV_FILE,r,{encoding:`utf8`,flag:`a`})}function configureAuth(e,t,n=process.env,r){return configureAuth$1(e,t,n,n===process.env?(e,t)=>exportShellEnv(e,t,n):void 0,r)}function resolveSfwEnabled(e,t,n){return e?!pkgPrNewCommitSha(t)||(n(`sfw was requested but is automatically disabled for Vite+ preview build ${t}; Socket Firewall Free will not be used.`),!1):!1}const $=`v1.15.4`,ht=`https://github.com/SocketDev/sfw-free/releases/download/${$}`;function isMuslLinux(){if(process.platform!==`linux`)return!1;try{let e=process.report?.getReport();if(e?.header&&!e.header.glibcVersionRuntime)return!0}catch{}return i(`/etc/alpine-release`)}function getSfwAssetName(e,t,n){if(e===`darwin`){if(t===`arm64`)return`sfw-free-macos-arm64`;if(t===`x64`)return`sfw-free-macos-x86_64`}else if(e===`linux`){if(t===`arm64`)return n?`sfw-free-musl-linux-arm64`:`sfw-free-linux-arm64`;if(t===`x64`)return n?`sfw-free-musl-linux-x86_64`:`sfw-free-linux-x86_64`}else if(isWindows(e)){if(t===`arm64`)return`sfw-free-windows-arm64.exe`;if(t===`x64`)return`sfw-free-windows-x86_64.exe`}throw Error(`Unsupported platform/arch for sfw: ${e}/${t}${e===`linux`?` (${n?`musl`:`glibc`})`:``}`)}function downloadFileWithShell(e,t,n){let r=Math.max(1,Math.ceil(n/1e3)),i=commandPath(`curl`);if(i){let n=w(i,[`-fsSL`,`--connect-timeout`,`5`,`--max-time`,String(r),e,`-o`,t],{stdio:`ignore`});if(n.status===0)return;throw n.error||/* @__PURE__ */ Error(`curl failed while downloading ${e}`)}let a=commandPath(`wget`);if(a){let n=w(a,[`-q`,`-T`,String(r),`-t`,`2`,`-O`,t,e],{stdio:`ignore`});if(n.status===0)return;throw n.error||/* @__PURE__ */ Error(`wget failed while downloading ${e}`)}throw Error(`curl or wget is required to download sfw`)}function downloadFile(e,t,n=0,i=6e4,a){return n>5?Promise.reject(/* @__PURE__ */ Error(`too many redirects while downloading ${e}`)):a?new Promise((o,s)=>{let c=!1,finish=e=>{c||(c=!0,clearTimeout(u),e?s(e):o())},l=a(e,o=>{let s=o.statusCode??0,c=o.headers.location;if(s>=300&&s<400&&c){o.resume(),downloadFile(new URL(c,e).toString(),t,n+1,i,a).then(()=>finish(),finish);return}if(s!==200){o.resume(),finish(/* @__PURE__ */ Error(`download failed with HTTP ${s}: ${e}`));return}let l=r(t);o.pipe(l),l.on(`finish`,()=>l.close(()=>finish())),l.on(`error`,finish)}),u=setTimeout(()=>{l.destroy(/* @__PURE__ */ Error(`download timed out after ${i}ms: ${e}`))},i);l.on(`error`,finish)}):(downloadFileWithShell(e,t,i),Promise.resolve())}async function setupSfw$1(e,t={}){let n=t.env??process.env,r=t.sfwEnabled??n.SETUP_VP_SFW===`true`,i=t.platform??process.platform,a=t.arch??process.arch,o=t.isMusl??isMuslLinux(),s=t.download??downloadFile;if(!resolveSfwEnabled(r,t.vitePlusVersion??``,t.logWarning??console.warn))return`vp`;if(e.length===0)return console.log(`setup-vp: sfw was requested but run-install is disabled; sfw will not be invoked.`),`vp`;let c=commandPath(`sfw`);if(c)return console.log(`setup-vp: using existing sfw on PATH: ${c}`),`sfw`;let l;try{l=getSfwAssetName(i,a,o)}catch{return console.error(`setup-vp: sfw has no published binary for this runner's platform/architecture (process.platform=${i}, process.arch=${a}, musl=${o}) and none was found on PATH; falling back to plain vp install.`),`vp`}let u=t.cacheDirectory||n.SETUP_VP_SFW_CACHE_DIR,d=u?h.join(u,$,l):await ae(h.join(E(),`setup-vp-sfw-`));await ie(d,{recursive:!0});let f=h.join(d,isWindows(i)?`sfw.exe`:`sfw`),p=`${ht}/${l}`;function activate(){let e=isWindows(i)?`;`:`:`;return n.PATH=`${d}${e}${n.PATH||``}`,t.exportVariable?.(`PATH`,n.PATH),`sfw`}if(await ce(f).then(e=>e.isFile()&&e.size>0,()=>!1))return console.log(`setup-vp: using cached sfw ${$}: ${f}`),activate();for(let e=1;e<=2;e+=1){let t=await ae(h.join(d,`.download-`)),n=h.join(t,`sfw`);try{if(console.log(`setup-vp: installing sfw ${$} from ${p}`),await s(p,n),(await ce(n)).size===0)throw Error(`Downloaded sfw binary is empty`);return await re(n,493),await oe(n,f),activate()}catch(t){if(e===2)throw t;await new Promise(e=>setTimeout(e,2e3))}finally{await se(t,{recursive:!0,force:!0})}}throw Error(`failed to install sfw after retrying`)}async function setupSfw(e,t=process.env,n=``){return setupSfw$1(e,{env:t,vitePlusVersion:n,exportVariable:(e,n)=>exportShellEnv(e,n,t)})}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function validateRunInstallEntry(e){if(!isRecord(e))throw Error(`run-install entries must be objects`);for(let t of Object.keys(e))if(t!==`cwd`&&t!==`args`)throw Error(`unsupported run-install key: ${t}`);let t={};if(e.cwd!==void 0){if(typeof e.cwd!=`string`)throw Error(`run-install.cwd must be a string`);t.cwd=e.cwd}if(e.args!==void 0){if(!Array.isArray(e.args)||e.args.some(e=>typeof e!=`string`))throw Error(`run-install.args must be an array of strings`);t.args=e.args}return t}function validateRunInstallInput(e){return e===null||typeof e==`boolean`?e:Array.isArray(e)?e.map(validateRunInstallEntry):validateRunInstallEntry(e)}function parseRunInstall(e){let t=validateRunInstallInput((0,Y.parse)(e)??null);return t?t===!0?[{}]:Array.isArray(t)?t:[t]:[]}function isSfwVpNotFoundFlake(e,t){return/Command 'vp' not found in PATH/.test(e+` `+t)}async function runInstall(e,t,n,r=process.env,i={}){let a={...r};delete a.SETUP_VP_ENV_FILE;let o=i.execute??runWithOutput,s=[];for(let r of e){let e=r.cwd?h.resolve(t,r.cwd):t,c=[`install`,...r.args||[]],l=n===`sfw`?[`vp`,...c]:c,u=`${n} ${l.join(` `)} (cwd: ${e})`;console.log(`setup-vp: running ${u}`);try{let t=await o(n,l,{cwd:e,env:a});if(t.exitCode!==0&&n===`sfw`&&isSfwVpNotFoundFlake(t.stdout,t.stderr)){let r=isWindows(i.platform);if(console.warn(r?`setup-vp: sfw could not resolve vp; warming the PowerShell command cache and retrying once.`:`setup-vp: sfw could not resolve vp; retrying once.`),r)try{await o(`powershell.exe`,[`-NoProfile`,`-Command`,`Get-Command vp`],{cwd:e,env:a})}catch{}t=await o(n,l,{cwd:e,env:a})}t.exitCode!==0&&s.push(`${u} exited with code ${t.exitCode}\n${t.stderr.trim()||t.stdout.trim()}`)}catch(e){s.push(`${u}: ${String(e)}`)}}if(s.length)throw Error(s.join(` diff --git a/dist/index.mjs b/dist/index.mjs index 3eea643..7a410bd 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -189,10 +189,10 @@ function _null(e){return/* @__PURE__ */ _null$1(ea,e)}const ta=/*@__PURE__*/ $co function array(e,t){return new ta({type:`array`,element:e,...normalizeParams(t)})}const na=/*@__PURE__*/ $constructor(`ZodMiniObject`,(e,t)=>{Ji.init(e,t),Zi.init(e,t),installLazyProp(e,`shape`,e=>e._zod.def.shape,!1)});// @__NO_SIDE_EFFECTS__ function object(e,t){let n={type:`object`,shape:e??{},...normalizeParams(t)};return new na(n)}const ra=/*@__PURE__*/ $constructor(`ZodMiniUnion`,(e,t)=>{Yi.init(e,t),Zi.init(e,t)});// @__NO_SIDE_EFFECTS__ function union(e,t){return new ra({type:`union`,options:e,...normalizeParams(t)})}const ia=/*@__PURE__*/ $constructor(`ZodMiniOptional`,(e,t)=>{Xi.init(e,t),Zi.init(e,t)});// @__NO_SIDE_EFFECTS__ -function optional(e){return new ia({type:`optional`,innerType:e})}const aa=`Vite+`,oa=`vite-plus`,sa=/* @__PURE__ */ object({cwd:/* @__PURE__ */ optional(/* @__PURE__ */ string()),args:/* @__PURE__ */ optional(/* @__PURE__ */ array(/* @__PURE__ */ string()))}),ca=/* @__PURE__ */ union([/* @__PURE__ */ _null(),/* @__PURE__ */ boolean(),sa,/* @__PURE__ */ array(sa)]),la=`Vite+`;function getInputs(){let e=getInput(`node-version`)||void 0,t=getInput(`node-version-file`)||void 0,n=parseNodeManager(getInput(`node-manager`));if(n===!1&&(e||t))throw Error(`node-manager: false cannot be combined with node-version or node-version-file: installing a Node.js version requires the Vite+ Node.js manager.`);return{version:getInput(`version`),versionFile:getInput(`version-file`)||void 0,nodeVersion:e,nodeVersionFile:t,nodeManager:n,packageManager:parsePackageManager(getInput(`package-manager`)),workingDirectory:getInput(`working-directory`)||void 0,runInstall:parseRunInstall(getInput(`run-install`)),sfw:getBooleanInput(`sfw`),cache:getBooleanInput(`cache`),cacheSave:getBooleanInput(`cache-save`),cacheDependencyPath:getInput(`cache-dependency-path`)||void 0,registryUrl:getInput(`registry-url`)||void 0,scope:getInput(`scope`)||void 0}}function parseRunInstall(e){if(!e||e===`false`||e===`null`)return[];if(e===`true`)return[{}];let t=(0,_i.parse)(e);try{let e=ca.parse(t);return e?e===!0?[{}]:Array.isArray(e)?e:[e]:[]}catch(e){throw e instanceof Mi?Error(`Invalid run-install input: ${e.issues.map(e=>e.message).join(`, `)}`):e}}function isWindows(e=process.platform){return e===`win32`}const ua=`https://raw.githubusercontent.com/voidzero-dev/vite-plus`,da=`packages/cli`,fa=/^0\.0\.0-commit\.([0-9a-f]{40})$/i,pa=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;function pkgPrNewCommitSha(e){return e.match(fa)?.[1]}function getInstallScriptUrls(e,t=process.platform){let n=isWindows(t)?`install.ps1`:`install.sh`,r=installScriptRef(e);return{pinned:r?[`${ua}/${r}/${da}/${n}`,`https://cdn.jsdelivr.net/gh/voidzero-dev/vite-plus@${r}/${da}/${n}`]:[],latest:[`https://viteplus.dev/${n}`,`${ua}/main/${da}/${n}`]}}function installScriptRef(e){let t=pkgPrNewCommitSha(e);if(t)return t.toLowerCase();if(pa.test(e))return`v${e}`}const ma=`SETUP_VP_DIRS_FILE`;function getVitePlusBinDirs(e){let t=P(e.data,`fallback-bin`);return ge(t,{throwIfNoEntry:!1})?.isDirectory()?{bin:e.bin,fallbackBin:t}:{bin:e.bin}}function appendFallbackBinToPath(e,t,n=process.platform){let r=isWindows(n)?`;`:`:`;return[...e?e.split(r).filter(e=>e!==t):[],t].join(r)}const ha=/^v?(\d+)\.(\d+)\.\d+(?:-[0-9A-Za-z.-]+)?$/;function supportsVitePlusDirs(e){if(pkgPrNewCommitSha(e))return!0;let t=e.match(ha);if(!t)return!0;let n=Number(t[1]),r=Number(t[2]);return n>0||r>=3}function createVitePlusDirsFile(){return P(Ce(),`setup-vp-dirs-${D()}.txt`)}function removeVitePlusDirsFile(e){he(e,{force:!0})}function readVitePlusProbe(e){try{return pe(e,`utf8`)}catch(e){if(e.code===`ENOENT`)return;throw e}}function resolveVitePlusBinDirs(e,t,n){if(!t){if(!supportsVitePlusDirs(e))return{bin:n};throw Error(`Vite+ was installed successfully, but setup-vp could not resolve its VpDirs.`)}let r=readVitePlusProbe(t),i=r===void 0?void 0:parseVitePlusDirs(r);if(i)return getVitePlusBinDirs(i);if(!(pkgPrNewCommitSha(e)!==void 0||ha.test(e))&&r!==void 0){let e=parseInstalledVpVersion$1(r);if(e!==`unknown`&&!supportsVitePlusDirs(e))return{bin:n}}throw Error(`Vite+ was installed successfully, but setup-vp could not resolve its VpDirs.`)}function parseVitePlusDirs(e){let t=/* @__PURE__ */ new Map;for(let n of e.split(/\r?\n/)){let e=n.indexOf(` `);if(e<1)continue;let r=n.slice(0,e).replace(/^\uFEFF/,``),i=n.slice(e+1).trim();i&&t.set(r,i)}let n=t.get(`data`),r=t.get(`bin`),i=t.get(`cache`),a=t.get(`config`),o=t.get(`state`);if(n&&r&&i&&a&&o)return{data:n,bin:r,cache:i,config:a,state:o}}function getInstallScriptCommand(e,t=process.platform,n=!0){if(isWindows(t))return n?{command:`pwsh`,args:[`-Command`,` +function optional(e){return new ia({type:`optional`,innerType:e})}const aa=`Vite+`,oa=`vite-plus`,sa=/* @__PURE__ */ object({cwd:/* @__PURE__ */ optional(/* @__PURE__ */ string()),args:/* @__PURE__ */ optional(/* @__PURE__ */ array(/* @__PURE__ */ string()))}),ca=/* @__PURE__ */ union([/* @__PURE__ */ _null(),/* @__PURE__ */ boolean(),sa,/* @__PURE__ */ array(sa)]),la=`Vite+`;function getInputs(){let e=getInput(`node-version`)||void 0,t=getInput(`node-version-file`)||void 0,n=parseNodeManager(getInput(`node-manager`));if(n===!1&&(e||t))throw Error(`node-manager: false cannot be combined with node-version or node-version-file: installing a Node.js version requires the Vite+ Node.js manager.`);return{version:getInput(`version`),versionFile:getInput(`version-file`)||void 0,nodeVersion:e,nodeVersionFile:t,nodeManager:n,packageManager:parsePackageManager(getInput(`package-manager`)),workingDirectory:getInput(`working-directory`)||void 0,runInstall:parseRunInstall(getInput(`run-install`)),sfw:getBooleanInput(`sfw`),cache:getBooleanInput(`cache`),cacheSave:getBooleanInput(`cache-save`),cacheDependencyPath:getInput(`cache-dependency-path`)||void 0,registryUrl:getInput(`registry-url`)||void 0,scope:getInput(`scope`)||void 0}}function parseRunInstall(e){if(!e||e===`false`||e===`null`)return[];if(e===`true`)return[{}];let t=(0,_i.parse)(e);try{let e=ca.parse(t);return e?e===!0?[{}]:Array.isArray(e)?e:[e]:[]}catch(e){throw e instanceof Mi?Error(`Invalid run-install input: ${e.issues.map(e=>e.message).join(`, `)}`):e}}function isWindows(e=process.platform){return e===`win32`}var ua=`1.1.0`,da={"1.1.0":{commit:`3aa366ee03ac162f5acfd8ee7c752a8245d904c6`,sh:`e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f`,ps1:`a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"1.0.0":{commit:`fc287d7b1c0dc008dbc65d1d2b2f51a44e2a5ea4`,sh:`e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f`,ps1:`a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"1.0.0-rc.1":{commit:`a9d81a4911190345408854b1c1f5cabdc8490a10`,sh:`e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f`,ps1:`a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"1.0.0-rc.0":{commit:`173e734826cdf79ef05ba91390c3508be5ebba3b`,sh:`e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f`,ps1:`a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"0.3.3":{commit:`45f9b9ac7128c2829f9130352ebcdc6462aca3d9`,sh:`6ed2d2847e5b7f3d67b6f91f2d28200bdffcffcd91ef2a336cf764d02776fcc3`,ps1:`bf909eed0675633eab5679fe1b40b1c313ee6e976a5ac732f2df3d35e39b0090`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"0.3.2":{commit:`9fd0d0ae6e775db361d3d5f9f3a18b47bc195420`,sh:`6ed2d2847e5b7f3d67b6f91f2d28200bdffcffcd91ef2a336cf764d02776fcc3`,ps1:`d202bcf693221f1b9732c73327dd4f3585614fadad647aebbf55b3eb453ab082`,legacy_sh:`a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514`,legacy_ps1:`98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07`},"0.3.1":{commit:`13e1e5ab0d993d5a704d7bcb9419cee9aca79a7d`,sh:`d4a1ffa8245bdfcf39a786d545be6a43e231b771c32d7c02414bb96d4f5d9cdc`,ps1:`096c1948222a83b424f6b98417567ea4437414a85ed380fe74ec89c406e5cf86`},"0.3.0":{commit:`b2d15e3899dcc8adedfd45d98de9d30046a624f4`,sh:`3dd88cedb6d9b2665c305eda5413971417c8f183a819386148131b66a2cc6b2e`,ps1:`e803c4cdc20dce9a67eaa2f9780272336ef5bdaf40cc2d4366e8961cd11df572`},"0.2.9":{commit:`73bdd105c2b7c263b55f7e9b48a37a8933cc317a`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.8":{commit:`fc3f0e266d13f0ab288097e202edf4112534a1d2`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.7":{commit:`c17e1c3c7cf859a29dd32eb60e82dc8157449ac2`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.6":{commit:`cd064c68a45fb82badfc1853ff690b1b70511165`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.5":{commit:`93dc59a324f790603ce65e629c13617468d1027d`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.4":{commit:`1ca9f0fcef42bbfb9a5a559f3cc4553c49c80f8c`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.3":{commit:`7f70680f91ad51cc4f1dae3e6cceb194ae7dd0ea`,sh:`58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54`,ps1:`4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906`},"0.2.2":{commit:`4f7fd0b66ebb5433acdb06f8660cf0f08c5a0d4b`,sh:`8b0a9835d871c4e67aee1c8d5b7e402d165cb55a3222743567a443028b33492e`,ps1:`7ecc798b6b749576215be5aee2b3f11e825115d48fe576cd5a0ecca7c039de71`},"0.2.1":{commit:`a0ed27069ea9eb65802def970ef554855993e0ac`,sh:`6f4fe3690a3f011b4b6cec3c71035e9c04a97dd45dd9e2623dc67f842268f0d2`,ps1:`60821b6f38a0eb984c5846722341f650e4d040c25e93add64aa134f199f86681`},"0.2.0":{commit:`6f97f097de8833b456e431270180b621b2309994`,sh:`6f4fe3690a3f011b4b6cec3c71035e9c04a97dd45dd9e2623dc67f842268f0d2`,ps1:`60821b6f38a0eb984c5846722341f650e4d040c25e93add64aa134f199f86681`},"0.1.24":{commit:`a1a2bbd6bf7e558277ab0f24f4e36243fc064043`,sh:`304d0267bea50d9f5400f3a826f0ae27884c22325b4d149d00a2ae4736c5a0cc`,ps1:`b54e90f2fd7749aa511248c34ac89afe868d7ac625a89074b1b3a7db03a1d02e`},"0.1.23":{commit:`2b3383748b576212ccb94dd2c647277e0bc4f5e2`,sh:`15242cab7c7832e2a3dc134e23059ce7726f7cca1467d78a79cd70760d3e3fb6`,ps1:`0611cb2777dc903ede063e303b84cc8193c49375b58eaba2db86c1c5c296719a`},"0.1.22":{commit:`12368dafa4a7b8c51fc1ef274c4cd5b60e6d3859`,sh:`15242cab7c7832e2a3dc134e23059ce7726f7cca1467d78a79cd70760d3e3fb6`,ps1:`0611cb2777dc903ede063e303b84cc8193c49375b58eaba2db86c1c5c296719a`},"0.1.21":{commit:`c61621ac610ad114746b98d7e457ca4e13171837`,sh:`8ca22990891df17cd808d7eedc3f8fcc722ad3a402191f6c125f36368af663f6`,ps1:`8a09b7b3ab975b134e1ec6d94daebe9cd531b2f3da9246fe8d9e38ee59df26c1`},"0.1.21-alpha.7":{commit:`c61621ac610ad114746b98d7e457ca4e13171837`,sh:`8ca22990891df17cd808d7eedc3f8fcc722ad3a402191f6c125f36368af663f6`,ps1:`8a09b7b3ab975b134e1ec6d94daebe9cd531b2f3da9246fe8d9e38ee59df26c1`},"0.1.21-alpha.6":{commit:`e134e4f84d7e3447d2fbd54fabf4efa928d6ce91`,sh:`8ca22990891df17cd808d7eedc3f8fcc722ad3a402191f6c125f36368af663f6`,ps1:`8a09b7b3ab975b134e1ec6d94daebe9cd531b2f3da9246fe8d9e38ee59df26c1`},"0.1.21-alpha.5":{commit:`634759714a507316148fd602a49dfceb87959b92`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.4":{commit:`dc41b711b8405fa42910fe186e8de2f58a51e14b`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.3":{commit:`7044ab9b003e42b5a5c9145dd7551da687d76989`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.2":{commit:`c4cdfc9666b5d0fd2fc2a9a4182ecb03afb5fa36`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.1":{commit:`cbd74649cf5d58dae8f309400f1754e418872f76`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.21-alpha.0":{commit:`7b9e6d6ce0cbc3bfef38b91034b493bc1739fc6e`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20":{commit:`bcc93a46abe94c543a0d36540dbd78aabfececfb`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.4":{commit:`bcc93a46abe94c543a0d36540dbd78aabfececfb`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.3":{commit:`210897e627ea27f2d7e0a7e5d2792aaf0e2775cc`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.2":{commit:`a5f36e08ef31ff9962b0b749652f57ab09fbdeb1`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.1":{commit:`fac1a20dd4f0f4990907ac67413c5c2b90a6ae42`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.20-alpha.0":{commit:`aeacdb0caacf2d7627c7b8df57011fb13bc040f5`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19":{commit:`41e78e2ba8ead352ca74aa32835489bfedfad63d`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19-alpha.3":{commit:`da5f14712472e185a825087f485cc4072b2ba8e7`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19-alpha.2":{commit:`4ac205f4434d6d362abc09e323991721da564f70`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19-alpha.1":{commit:`c5510b2f6de9976fde25c200aeed28b2f496a540`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.19-alpha.0":{commit:`b9d218a6f9aa0c3b22fe85b6ad9229b0e135b31b`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.18":{commit:`6e06c175c71c725a46c409062c4c8d1fe1150449`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.18-alpha.0":{commit:`40a47e52cd596674a80203991013913555655f0d`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17":{commit:`e159b84a95199fc17a7ffddef14caeefc81c90f2`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.5":{commit:`48e49ca0c1c062989120c41bcce9ee1db8b172dd`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.4":{commit:`a5fca7ddca580725a3ba06efbd47ee573b60c50a`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.3":{commit:`a94deea2fc68b5a6a2e2f2868df32b6cc7bf7ec8`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.2":{commit:`2703014124101b30ec2470159d84d8f9a32dd285`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.1":{commit:`ba538e199ba23ca34f895af5b36564366990725b`,sh:`f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e`,ps1:`56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88`},"0.1.17-alpha.0":{commit:`29f821e61f41e2068713676856d7363bf72e5896`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`c44111999449915902c9f0e0ddfa61ea1b3c3a0502ee4b1a3994a115abb4c5bc`},"0.1.16":{commit:`f64bb6c98c1ff577ba7e8ae4ddb43dcfcc3624b0`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`c44111999449915902c9f0e0ddfa61ea1b3c3a0502ee4b1a3994a115abb4c5bc`},"0.1.16-alpha.4":{commit:`556043129dc6a006cbdefd40b9c68ca306f086b5`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`c44111999449915902c9f0e0ddfa61ea1b3c3a0502ee4b1a3994a115abb4c5bc`},"0.1.16-alpha.3":{commit:`6153ccb787f9b35655c1702f3220e5c7a57ca997`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`53c0cfbb7e92719b18808611a977eb34312992c20cca8636d9f905c43184b860`},"0.1.16-alpha.2":{commit:`f72d8a1f86fde0945de6e362d1fd120043f635cd`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`53c0cfbb7e92719b18808611a977eb34312992c20cca8636d9f905c43184b860`},"0.1.16-alpha.1":{commit:`38aa60a7a087113364e5b80feceaa57d3100f766`,sh:`e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a`,ps1:`53c0cfbb7e92719b18808611a977eb34312992c20cca8636d9f905c43184b860`},"0.1.16-alpha.0":{commit:`a015d7897617b7807ed0d825000fc1e7e9b18e67`,sh:`4057f586f65168077362203bcde2ea8ed07ec7ee3a560a35a20b974f4318c098`,ps1:`e9caf430aa09d14b82f5522aeb84b9321470d09512f2634e3d2dfda77d3645f6`},"0.1.15":{commit:`bf39b756ae038af3d34bbceeedc9ecf60afdd9a8`,sh:`437b3dbf8bed60740183083687801c037c318a48ba590ef5e2e06594ffd61530`,ps1:`299207f95a34b0e9a03df0bd7a77c80521b793740a5674aba80519ce7bd2c034`},"0.1.15-alpha.7":{commit:`f922d5fa560cae6f232cb1a74099c78587806ad3`,sh:`437b3dbf8bed60740183083687801c037c318a48ba590ef5e2e06594ffd61530`,ps1:`299207f95a34b0e9a03df0bd7a77c80521b793740a5674aba80519ce7bd2c034`},"0.1.15-alpha.6":{commit:`6cd75f480d9c10845d05d32be594c8cc6bce3c64`,sh:`437b3dbf8bed60740183083687801c037c318a48ba590ef5e2e06594ffd61530`,ps1:`299207f95a34b0e9a03df0bd7a77c80521b793740a5674aba80519ce7bd2c034`},"0.1.15-alpha.5":{commit:`dbe191ed95750571d9e02c33849c33c6789cfee4`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.4":{commit:`3af4839e659745492252020d78d519559e4a568d`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.3":{commit:`fd1b75e2ac170472017e3e601189fdfb3ed5f5d8`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.2":{commit:`3a85b2b65ba63d6706e58ca45d9b8ae1aa04d27a`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.1":{commit:`c267e06a0e254472983af686dd376efed5344d15`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.15-alpha.0":{commit:`94aecfa3edb591faf2b92835732090e41eba6dbb`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.14":{commit:`71b90b4eadd9795f354d3d5208decf904b92d927`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.14-alpha.3":{commit:`01693e3781bf854ff3fd1cd755f26ade1773ccc2`,sh:`029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.14-alpha.1":{commit:`0ff9227227bf58c48d46ea8814f21b1549f211cb`,sh:`cf9cfa219dce0fa7a9aba8f0804214af89d3321e0eec40ebc02371c7f08acba8`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.14-alpha.0":{commit:`fc9bf496ad50dba718a1544583d19eb47ff32534`,sh:`cf9cfa219dce0fa7a9aba8f0804214af89d3321e0eec40ebc02371c7f08acba8`,ps1:`735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06`},"0.1.13":{commit:`9861b670b32c53ea28dfb0b7e1189e533a13c5fd`,sh:`4f70075425f42ff90c304da5f74a586bd1bc4cfa79cdac2d5eff3dfd7176b845`,ps1:`7b6495786f059b2be584156884e68cb6da99f2ee6c0fddd6987c59fa604f794d`},"0.1.13-alpha.5":{commit:`2dfc0c3c81451233abe62ed49de1266ff5069a64`,sh:`4f70075425f42ff90c304da5f74a586bd1bc4cfa79cdac2d5eff3dfd7176b845`,ps1:`7b6495786f059b2be584156884e68cb6da99f2ee6c0fddd6987c59fa604f794d`},"0.1.13-alpha.4":{commit:`ffc1638a075632f9a1977f24467dcce5d31d00d1`,sh:`4f70075425f42ff90c304da5f74a586bd1bc4cfa79cdac2d5eff3dfd7176b845`,ps1:`7b6495786f059b2be584156884e68cb6da99f2ee6c0fddd6987c59fa604f794d`},"0.1.13-alpha.3":{commit:`d64cba8cda73af176453e0c25e7743d6ab25486f`,sh:`ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b`,ps1:`9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88`},"0.1.13-alpha.2":{commit:`9db93c21726781c7fe0d2d90b7373ad172af2dbc`,sh:`ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b`,ps1:`9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88`},"0.1.13-alpha.1":{commit:`849c1263bb9913dcd1a3fe0680b6cb8113639e06`,sh:`ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b`,ps1:`9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88`},"0.1.13-alpha.0":{commit:`b3d0e962b13118f3ff4097d224523833584326e6`,sh:`ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b`,ps1:`9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88`},"0.1.12":{commit:`8c6c1b23f1fe702f21ae72ff96979bfedb66364b`,sh:`43985e08bab995fba9c28923be6070d78f979c635c53ef7fd624a3103d9ce588`,ps1:`c40df7d8d632cd36d56b16e27006b0886dd51785e6033ca20bcbe3308901443c`},"0.1.12-alpha.2":{commit:`fe3189b64e0588ddae272ed6c4d49a8cbc23ce55`,sh:`2bc79f0370486d429783850b12e039672cc7f7236712c11a23d5b9405b05a597`,ps1:`c40df7d8d632cd36d56b16e27006b0886dd51785e6033ca20bcbe3308901443c`},"0.1.11":{commit:`ef77182006de701eb5260a68652f6dab6db7b760`,sh:`6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2`,ps1:`e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca`},"0.1.10":{commit:`1848576dcdb270611ce6e9c4b0b7ea7fdb223f32`,sh:`6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2`,ps1:`e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca`},"0.1.9":{commit:`b25efbd3c2a5ebdc18496e4ca2142f6449343952`,sh:`6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2`,ps1:`e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca`},"0.1.8":{commit:`0a1ec92c7b21d73317c9f3d796a35c8c9f14d0f1`,sh:`6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2`,ps1:`e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca`},"0.1.7":{commit:`a7dc6660a4e0f488a061d6350222adabdf763f5b`,sh:`a8378abdf90ce4a95352f1f9918d54bd666ec347ff9cad0c3bbfa2fef6db62cd`,ps1:`7462b3bb999b14f138d15df47a84dbdb3a7be96f56f77e9626e6624b6640eafc`},"0.1.6":{commit:`0c40c50cb395317ca3b35508e286018114b6372c`,sh:`a8378abdf90ce4a95352f1f9918d54bd666ec347ff9cad0c3bbfa2fef6db62cd`,ps1:`7462b3bb999b14f138d15df47a84dbdb3a7be96f56f77e9626e6624b6640eafc`},"0.1.5":{commit:`133340675e7eb9de8e0d8ffd8efb9de619ba6a39`,sh:`3316073e62247a9b8fc34f1be8b24047e3e3315749cc52d68eeccae2462f78d1`,ps1:`722de6e4ab17a6f853100055f522a2fec3a3255c394bc29be1d5fc3b6ed8f120`},"0.1.4":{commit:`12abba5def4cf4479f226188c0b24e04d15f3181`,sh:`3316073e62247a9b8fc34f1be8b24047e3e3315749cc52d68eeccae2462f78d1`,ps1:`722de6e4ab17a6f853100055f522a2fec3a3255c394bc29be1d5fc3b6ed8f120`},"0.1.3":{commit:`c0c8ebda74ac78bb70a73ebf4de67865079c9b38`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.2":{commit:`dfb9d4b258b11f6842c7b62f228617d4065f5a83`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.1":{commit:`8c5823fa0d19d7e186115963d1ff7ff58fa30576`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.1-alpha.0":{commit:`bdef013b286275979c9e593fe564c686b3d7130b`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.0":{commit:`cf4df93a8fd7f6b871f98766fb2c6a6578f2d8bc`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`},"0.1.0-alpha.0":{commit:`82f57fbb4d53b99d023d923979f2b2f08ff5e18f`,sh:`f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1`,ps1:`c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22`}};const fa=/^0\.0\.0-commit\.([0-9a-f]{40})$/i;function pkgPrNewCommitSha(e){return e.match(fa)?.[1]}const pa=da;function getInstallScriptSources(e,t=process.platform){let n=isWindows(t)?`ps1`:`sh`;function sources(e){let t=`packages/cli/install.${n}`;return[`https://raw.githubusercontent.com/voidzero-dev/vite-plus/${e.commit}/${t}`,`https://cdn.jsdelivr.net/gh/voidzero-dev/vite-plus@${e.commit}/${t}`].map(t=>{let r=e[`legacy_${n}`];return{url:t,sha256:e[n],...r?{legacy:{url:t.replace(`install.${n}`,`install-legacy.${n}`),sha256:r}}:{}}})}let r=Object.hasOwn(pa,e)?pa[e]:void 0,i=pa[ua];return{pinned:r&&r.commit!==i.commit?sources(r):[],fallback:sources(i)}}const ma=`SETUP_VP_DIRS_FILE`;function getVitePlusBinDirs(e){let t=P(e.data,`fallback-bin`);return ge(t,{throwIfNoEntry:!1})?.isDirectory()?{bin:e.bin,fallbackBin:t}:{bin:e.bin}}function appendFallbackBinToPath(e,t,n=process.platform){let r=isWindows(n)?`;`:`:`;return[...e?e.split(r).filter(e=>e!==t):[],t].join(r)}const ha=/^v?(\d+)\.(\d+)\.\d+(?:-[0-9A-Za-z.-]+)?$/;function supportsVitePlusDirs(e){if(pkgPrNewCommitSha(e))return!0;let t=e.match(ha);if(!t)return!0;let n=Number(t[1]),r=Number(t[2]);return n>0||r>=3}function createVitePlusDirsFile(){return P(Ce(),`setup-vp-dirs-${D()}.txt`)}function removeVitePlusDirsFile(e){he(e,{force:!0})}function readVitePlusProbe(e){try{return pe(e,`utf8`)}catch(e){if(e.code===`ENOENT`)return;throw e}}function resolveVitePlusBinDirs(e,t,n){if(!t){if(!supportsVitePlusDirs(e))return{bin:n};throw Error(`Vite+ was installed successfully, but setup-vp could not resolve its VpDirs.`)}let r=readVitePlusProbe(t),i=r===void 0?void 0:parseVitePlusDirs(r);if(i)return getVitePlusBinDirs(i);if(!(pkgPrNewCommitSha(e)!==void 0||ha.test(e))&&r!==void 0){let e=parseInstalledVpVersion$1(r);if(e!==`unknown`&&!supportsVitePlusDirs(e))return{bin:n}}throw Error(`Vite+ was installed successfully, but setup-vp could not resolve its VpDirs.`)}function parseVitePlusDirs(e){let t=/* @__PURE__ */ new Map;for(let n of e.split(/\r?\n/)){let e=n.indexOf(` `);if(e<1)continue;let r=n.slice(0,e).replace(/^\uFEFF/,``),i=n.slice(e+1).trim();i&&t.set(r,i)}let n=t.get(`data`),r=t.get(`bin`),i=t.get(`cache`),a=t.get(`config`),o=t.get(`state`);if(n&&r&&i&&a&&o)return{data:n,bin:r,cache:i,config:a,state:o}}function getInstallScriptCommand(e,t=process.platform,n=!0){let r=[{...e,name:isWindows(t)?`install.ps1`:`install.sh`}];e.legacy&&r.push({...e.legacy,name:isWindows(t)?`install-legacy.ps1`:`install-legacy.sh`});for(let e of r)if(!/^[a-f0-9]{64}$/.test(e.sha256))throw Error(`A trusted SHA-256 checksum is required for the Vite+ installer.`);if(isWindows(t)){let e=` $dirsFile = $env:${ma} Set-Content -LiteralPath $dirsFile -Value '' -NoNewline -Encoding UTF8 -. ([scriptblock]::Create((irm -TimeoutSec 15 ${e}))) +. $installerFile $vpDir = if ($script:ShimDir) { $script:ShimDir } elseif ($InstallDir) { @@ -209,36 +209,61 @@ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } $env:VP_DUMP_DIRS = '1' & $vpPath | Add-Content -LiteralPath $dirsFile -Encoding UTF8 if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } -`.trim()]}:{command:`pwsh`,args:[`-Command`,`& ([scriptblock]::Create((irm -TimeoutSec 15 ${e})))`]};let r=` +`.trim();return{command:`pwsh`,args:[`-ExecutionPolicy`,`Bypass`,`-Command`,` +$ErrorActionPreference = 'Stop' +$installerDir = Join-Path ([System.IO.Path]::GetTempPath()) ('setup-vp-install-' + [guid]::NewGuid().ToString('N')) +$null = New-Item -ItemType Directory -Path $installerDir +$installerFile = Join-Path $installerDir 'install.ps1' +try { + ${r.map(({url:e,sha256:t,name:n})=>` + $downloadFile = Join-Path $installerDir '${n}' + Invoke-WebRequest -UseBasicParsing -TimeoutSec 15 -Uri '${e.replaceAll(`'`,`''`)}' -OutFile $downloadFile + if ((Get-FileHash -LiteralPath $downloadFile -Algorithm SHA256).Hash -ne '${t}') { + throw 'setup-vp: installer SHA-256 checksum mismatch; refusing to execute it.' + }`).join(` +`)} + $global:LASTEXITCODE = 0 + ${n?e:`& $installerFile +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }`} +} finally { + Remove-Item -LiteralPath $installerDir -Recurse -Force +} +`.trim()]}}let quote=e=>`'${e.replaceAll(`'`,`'\\''`)}'`;return{command:`bash`,args:[`-c`,` +set +u +set -eo pipefail +installer_dir="$(mktemp -d "\${TMPDIR:-/tmp}/setup-vp-install.XXXXXX")" +trap 'rm -rf "$installer_dir"' EXIT +installer_file="$installer_dir/install.sh" +${r.map(({url:e,sha256:t,name:n})=>` +download_file="$installer_dir/${n}" if command -v curl >/dev/null 2>&1; then - curl -fsSL --connect-timeout 5 --max-time 15 "${e}"${n?` -o "$installer_file"`:``} + curl -fsSL --connect-timeout 5 --max-time 15 ${quote(e)} -o "$download_file" elif command -v wget >/dev/null 2>&1; then - wget -q -T 15 -t 1 -O ${n?`"$installer_file"`:`-`} "${e}" + wget -q -T 15 -t 1 -O "$download_file" ${quote(e)} else echo "setup-vp: curl or wget is required to download the installer." >&2 exit 127 fi -`.trim();return n?{command:`bash`,args:[`-c`,` -set +u -set -eo pipefail -installer_file="$(mktemp "\${TMPDIR:-/tmp}/setup-vp-install.XXXXXX")" -trap 'rm -f "$installer_file"' EXIT -: > "$${ma}" -${r} +${quote(process.execPath)} -e ${quote(`const fs = require("node:fs"); +const crypto = require("node:crypto"); +const actual = crypto.createHash("sha256").update(fs.readFileSync(process.argv[1])).digest("hex"); +if (actual !== process.argv[2]) { + console.error("setup-vp: installer SHA-256 checksum mismatch; refusing to execute it."); + process.exit(1); +}`)} "$download_file" '${t}' +`).join(` +`)} +${n?`: > "$${ma}" source "$installer_file" vp_dir="\${SHIM_DIR:-\${INSTALL_DIR:-\${VP_HOME:-$HOME/.vite-plus}}/bin}" if [ -x "$vp_dir/vp" ]; then "$vp_dir/vp" --version > "$${ma}" VP_DUMP_DIRS=1 "$vp_dir/vp" >> "$${ma}" -fi -`.trim()]}:{command:`bash`,args:[`-c`,` -set +u -set -o pipefail -${r} | bash +fi`:`bash "$installer_file"`} `.trim()]}}function getVitePlusHome(){let e=isWindows()?process.env.USERPROFILE:process.env.HOME;return P(e||xe(),`.vite-plus`)}function parseInstalledVpVersion(e){return(e.match(/^\s*vp\s+v?(\d[^\s]*)/im)??e.match(/Global:\s*v?(\d[^\s]*)/i))?.[1]??`unknown`}function getWorkspaceDir(){return process.env.GITHUB_WORKSPACE||process.cwd()}function resolvePath$2(e,t){return re(e)?e:P(t,e)}function getConfiguredProjectDir(e){if(!e.workingDirectory)return getWorkspaceDir();let t=resolvePath$2(e.workingDirectory,getWorkspaceDir());if(!F(t))throw Error(`working-directory not found: ${e.workingDirectory} (resolved to ${t})`);if(!ge(t).isDirectory())throw Error(`working-directory is not a directory: ${e.workingDirectory} (resolved to ${t})`);return t}function getInstallCwd(e,t){return t?resolvePath$2(t,e):e}const ga=[{filename:`pnpm-lock.yaml`,type:`pnpm`},{filename:`bun.lockb`,type:`bun`},{filename:`bun.lock`,type:`bun`},{filename:`package-lock.json`,type:`npm`},{filename:`npm-shrinkwrap.json`,type:`npm`},{filename:`yarn.lock`,type:`yarn`}];function detectLockFile$1(e,t=getWorkspaceDir(),n=!1){if(e){let n=resolvePath$2(e,t);if(F(n)){let e=te(n),t=ga.find(t=>t.filename===e);return t?{type:t.type,path:n,filename:e}:inferLockFileType$1(n,e)}return}let r=me(t);for(let e of ga)if(r.includes(e.filename)){let r=P(t,e.filename);return n||info(`Auto-detected lock file: ${e.filename}`),{type:e.type,path:r,filename:e.filename}}}function inferLockFileType$1(e,t){return t.includes(`pnpm`)?{type:`pnpm`,path:e,filename:t}:t.includes(`yarn`)?{type:`yarn`,path:e,filename:t}:t.startsWith(`bun.`)?{type:`bun`,path:e,filename:t}:{type:`npm`,path:e,filename:t}}async function getCacheDirectories(e,t){switch(e){case`npm`:case`pnpm`:case`yarn`:case`bun`:return getViteCacheDir(t);default:return[]}}async function getCommandOutput(e,t,n){let r=`${e} ${t.join(` `)}`;try{let i=await getExecOutput(e,t,{cwd:n?.cwd,silent:!0,ignoreReturnCode:!0});if(i.exitCode===0)return i.stdout.trim();debug(`Command "${r}" exited with code ${i.exitCode}`);return}catch(e){warning(`Failed to run "${r}": ${String(e)}`);return}}async function getViteCacheDir(e){let t=await getCommandOutput(`vp`,[`pm`,`cache`,`dir`],{cwd:e});return t?[t]:[]}const _a=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/,va=[`vp`,`node`,`npm`,`npx`,`vpx`,`vpr`],ya=[`pnpm`,`pnpx`,`yarn`,`yarnpkg`,`bun`,`bunx`],ba=[`VP_NODE_MANAGER`,`VP_PM_MANAGER`,`VP_NPM_MANAGER`,`VP_PNPM_MANAGER`,`VP_YARN_MANAGER`,`VP_BUN_MANAGER`];function findReusableVitePlus(e,t=process.env,n=process.platform){if(!_a.test(e)||pkgPrNewCommitSha(e)||!supportsVitePlusDirs(e)||t.VP_PR_VERSION||t.VP_LOCAL_TGZ||t.VP_LOCAL_BINARY||t.VP_SKIP_DEPS_INSTALL||ba.some(e=>t[e]&&t[e]!==`yes`)||!hasValidDirOverrides(t))return;let r=isWindows(n)?`vp.exe`:`vp`;for(let i of candidateDataDirs(t,n)){let a=P(i,`current`,`bin`,r);if(F(a))try{let r=I(P(i,`current`));if(ne(r)!==I(i)||!hasDependencies(r,e))continue;let o={cwd:Ce(),env:t,encoding:`utf8`,timeout:5e3,maxBuffer:1048576,stdio:[`ignore`,`pipe`,`ignore`]},s=we(a,[],{...o,env:{...t,VP_DUMP_DIRS:`1`}}),c=parseVitePlusDirs(s),l=/^layout\t(single-root|split)\r?$/m.exec(s)?.[1];if(!c||!Object.values(c).every(re)||!l||I(c.data)!==I(i))continue;let u=we(a,[`--version`],o);if(parseInstalledVpVersion$1(u)!==e||!hasManagedEnvironment(c.config,n)||!hasValidShims(c,a,n,l,u)||!hasNativeBinding(r,o))continue;return getVitePlusBinDirs(c)}catch(e){debug(`Cannot reuse Vite+ at ${i}: ${String(e)}`)}}}function hasValidDirOverrides(e){if(e.VP_HOME&&!re(e.VP_HOME))return!1;let t=[e.VP_BIN_DIR,e.VP_DATA_DIR,e.VP_CACHE_DIR].filter(e=>!!e);return t.length===0||t.length===3&&t.every(re)}function candidateDataDirs(e,t){if(e.VP_HOME)return[e.VP_HOME];let n=(isWindows(t)?e.USERPROFILE:e.HOME)||xe(),r=[P(n,`.vite-plus`),e.VP_DATA_DIR];if(isWindows(t))r.push(P(e.LOCALAPPDATA||P(n,`AppData`,`Local`),`vite-plus`,`data`));else{let t=e.XDG_DATA_HOME;r.push(P(t&&re(t)?t:P(n,`.local`,`share`),`vite-plus`))}return[...new Set(r.filter(e=>!!e&&re(e)))]}function hasDependencies(t,n){let r=JSON.parse(pe(P(t,`package.json`),`utf8`));if(r.name!==`vp-global`||r.version!==n||r.dependencies?.[`vite-plus`]!==n)return!1;let i=I(P(t,`node_modules`,`vite-plus`,`package.json`));if(!isInside(t,i))return!1;let a=JSON.parse(pe(i,`utf8`));if(a.name!==`vite-plus`||a.version!==n||!a.dependencies)return!1;let o=e(i);return ge(P(ne(i),`dist`,`bin.js`)).isFile()?Object.keys(a.dependencies).every(e=>o.resolve.paths(e)?.some(n=>{let r=P(n,e,`package.json`);return F(r)&&isInside(t,I(r))})):!1}function isInside(e,t){let n=ie(e,t);return n!==`..`&&!n.startsWith(`..${oe}`)&&!re(n)}function hasNativeBinding(e,t){let n=I(P(e,`node_modules`,`vite-plus`,`binding`,`index.cjs`));if(!isInside(e,n)||!ge(n).isFile())return!1;let r=JSON.parse(we(process.execPath,[`--input-type=commonjs`,`--eval`,` require(process.argv[1]); process.stdout.write(JSON.stringify(Object.keys(require.cache).filter(file => file.endsWith('.node')))); -`,n],{...t,env:{...t.env,NAPI_RS_ENFORCE_VERSION_CHECK:`1`}}));return Array.isArray(r)&&r.length>0&&r.every(t=>typeof t==`string`&&re(t)&&isInside(e,I(t)))}function hasManagedEnvironment(e,t){let n=P(e,`config.json`),r=F(n)?JSON.parse(pe(n,`utf8`)):{};if([r.shimMode,r.nodeShimMode,...Object.values(r.packageManagerShimModes??{})].some(e=>e!==void 0&&e!==`managed`))return!1;let i=P(e,isWindows(t)?`env.ps1`:`env`);return ge(i).isFile()}function hasValidShims(e,t,n,r,i){let a=[...va,...supportsScopedEnv(i)?ya:[`corepack`]];if(isWindows(n)){let n=pe(P(ne(t),`vp-shim.exe`));return ge(P(e.bin,`vp-use.cmd`)).isFile()?a.every(t=>{let i=pe(P(e.bin,`${t}.exe`)),[a,...o]=pe(P(e.bin,`${t}.shim`),`utf8`).trim().split(/\r?\n/),s=new Map(o.map(e=>{let t=e.indexOf(`=`);return[e.slice(0,t),e.slice(t+1)]}));return i.equals(n)&&a===`vite-plus-shim-v1`&&s.get(`layout`)===r&&s.get(`data`)===e.data&&s.get(`cache`)===e.cache}):!1}let o=I(t);return a.every(t=>{let n=P(e.bin,t);return le(n,de.X_OK),I(n)===o})}const xa=2e3;async function installVitePlus(e){let{version:t}=e,n=findReusableVitePlus(t);if(n){ensureVitePlusBinsInPath(n,!0),info(`Reusing ${la}@${t} from ${n.bin}`);return}info(`Installing ${la}@${t}...`);let r={...process.env,VP_VERSION:t,VITE_PLUS_VERSION:t},i=supportsVitePlusDirs(t)?createVitePlusDirsFile():void 0;i?(r.VP_VPDIRS_AWARE=`1`,r[ma]=i):(delete r.VP_VPDIRS_AWARE,delete r[ma]);let a=pkgPrNewCommitSha(t);a&&(r.VP_PR_VERSION=a);let{pinned:o,latest:s}=getInstallScriptUrls(t),c=o.length+s.length,l=2*c,u=``,d=0,tryUrls=async e=>{for(let t=0;t<2;t++)for(let t of e){d++;try{let e=await runInstallCommand(t,r);if(e===0)return!0;u=`exit code ${e}`}catch(e){u=e instanceof Error?e.message:String(e)}d0){if(await tryUrls(o)){ensureVitePlusBinInPath(t,i);return}warning(`Could not fetch the install script pinned to ${la}@${t}. Falling back to the latest install script. The latest script may not be compatible with ${t}.`)}if(await tryUrls(s)){ensureVitePlusBinInPath(t,i);return}throw Error(`Failed to install ${la} after ${l} attempts across ${c} URL(s): ${u}`)}finally{i&&removeVitePlusDirsFile(i)}}async function runInstallCommand(e,t){let n={env:t,ignoreReturnCode:!0},{command:r,args:i}=getInstallScriptCommand(e,process.platform,t.VP_VPDIRS_AWARE===`1`);return exec(r,i,n)}function ensureVitePlusBinInPath(e,t){ensureVitePlusBinsInPath(resolveVitePlusBinDirs(e,t,P(getVitePlusHome(),`bin`)))}function ensureVitePlusBinsInPath({bin:e,fallbackBin:t},n=!1){(n||!process.env.PATH?.split(N).includes(e))&&addPath(e),t&&exportVariable(`PATH`,appendFallbackBinToPath(process.env.PATH,t))}function getOptions(e){let t={followSymbolicLinks:!0,implicitDescendants:!0,matchDirectories:!0,omitBrokenSymbolicLinks:!0,excludeHiddenFiles:!1};return e&&(typeof e.followSymbolicLinks==`boolean`&&(t.followSymbolicLinks=e.followSymbolicLinks,debug(`followSymbolicLinks '${t.followSymbolicLinks}'`)),typeof e.implicitDescendants==`boolean`&&(t.implicitDescendants=e.implicitDescendants,debug(`implicitDescendants '${t.implicitDescendants}'`)),typeof e.matchDirectories==`boolean`&&(t.matchDirectories=e.matchDirectories,debug(`matchDirectories '${t.matchDirectories}'`)),typeof e.omitBrokenSymbolicLinks==`boolean`&&(t.omitBrokenSymbolicLinks=e.omitBrokenSymbolicLinks,debug(`omitBrokenSymbolicLinks '${t.omitBrokenSymbolicLinks}'`)),typeof e.excludeHiddenFiles==`boolean`&&(t.excludeHiddenFiles=e.excludeHiddenFiles,debug(`excludeHiddenFiles '${t.excludeHiddenFiles}'`))),t}const Sa=process.platform===`win32`;function dirname$1(e){if(e=safeTrimTrailingSeparator(e),Sa&&/^\\\\[^\\]+(\\[^\\]+)?$/.test(e))return e;let t=u.dirname(e);return Sa&&/^\\\\[^\\]+\\[^\\]+\\$/.test(t)&&(t=safeTrimTrailingSeparator(t)),t}function ensureAbsoluteRoot(e,t){if(h(e,`ensureAbsoluteRoot parameter 'root' must not be empty`),h(t,`ensureAbsoluteRoot parameter 'itemPath' must not be empty`),hasAbsoluteRoot(t))return t;if(Sa){if(t.match(/^[A-Z]:[^\\/]|^[A-Z]:$/i)){let e=process.cwd();return h(e.match(/^[A-Z]:\\/i),`Expected current directory to start with an absolute drive root. Actual '${e}'`),t[0].toUpperCase()===e[0].toUpperCase()?t.length===2?`${t[0]}:\\${e.substr(3)}`:(e.endsWith(`\\`)||(e+=`\\`),`${t[0]}:\\${e.substr(3)}${t.substr(2)}`):`${t[0]}:\\${t.substr(2)}`}if(normalizeSeparators(t).match(/^\\$|^\\[^\\]/)){let e=process.cwd();return h(e.match(/^[A-Z]:\\/i),`Expected current directory to start with an absolute drive root. Actual '${e}'`),`${e[0]}:\\${t.substr(1)}`}}return h(hasAbsoluteRoot(e),`ensureAbsoluteRoot parameter 'root' must have an absolute root`),e.endsWith(`/`)||Sa&&e.endsWith(`\\`)||(e+=u.sep),e+t}function hasAbsoluteRoot(e){return h(e,`hasAbsoluteRoot parameter 'itemPath' must not be empty`),e=normalizeSeparators(e),Sa?e.startsWith(`\\\\`)||/^[A-Z]:\\/i.test(e):e.startsWith(`/`)}function hasRoot(e){return h(e,`isRooted parameter 'itemPath' must not be empty`),e=normalizeSeparators(e),Sa?e.startsWith(`\\`)||/^[A-Z]:/i.test(e):e.startsWith(`/`)}function normalizeSeparators(e){return e||=``,Sa?(e=e.replace(/\//g,`\\`),(/^\\\\+[^\\]/.test(e)?`\\`:``)+e.replace(/\\\\+/g,`\\`)):e.replace(/\/\/+/g,`/`)}function safeTrimTrailingSeparator(e){return e?(e=normalizeSeparators(e),!e.endsWith(u.sep)||e===u.sep||Sa&&/^[A-Z]:\\$/i.test(e)?e:e.substr(0,e.length-1)):``}var Ca;(function(e){e[e.None=0]=`None`,e[e.Directory=1]=`Directory`,e[e.File=2]=`File`,e[e.All=3]=`All`})(Ca||={});const wa=process.platform===`win32`;function getSearchPaths(e){e=e.filter(e=>!e.negate);let t={};for(let n of e){let e=wa?n.searchPath.toUpperCase():n.searchPath;t[e]=`candidate`}let n=[];for(let r of e){let e=wa?r.searchPath.toUpperCase():r.searchPath;if(t[e]===`included`)continue;let i=!1,a=e,o=dirname$1(a);for(;o!==a;){if(t[o]){i=!0;break}a=o,o=dirname$1(a)}i||(n.push(r.searchPath),t[e]=`included`)}return n}function match$1(e,t){let n=Ca.None;for(let r of e)r.negate?n&=~r.match(t):n|=r.match(t);return n}function partialMatch(e,t){return e.some(e=>!e.negate&&e.partialMatch(t))}const balanced=(e,t,n)=>{let r=e instanceof RegExp?maybeMatch(e,n):e,i=t instanceof RegExp?maybeMatch(t,n):t,a=r!==null&&i!=null&&range$1(r,i,n);return a&&{start:a[0],end:a[1],pre:n.slice(0,a[0]),body:n.slice(a[0]+r.length,a[1]),post:n.slice(a[1]+i.length)}},maybeMatch=(e,t)=>{let n=t.match(e);return n?n[0]:null},range$1=(e,t,n)=>{let r,i,a,o,s,c=n.indexOf(e),l=n.indexOf(t,c+1),u=c;if(c>=0&&l>0){if(e===t)return[c,l];for(r=[],a=n.length;u>=0&&!s;){if(u===c)r.push(u),c=n.indexOf(e,u+1);else if(r.length===1){let e=r.pop();e!==void 0&&(s=[e,l])}else i=r.pop(),i!==void 0&&i=0?c:l}r.length&&o!==void 0&&(s=[a,o])}return s},Ta=`\0SLASH`+Math.random()+`\0`,Ea=`\0OPEN`+Math.random()+`\0`,Da=`\0CLOSE`+Math.random()+`\0`,Oa=`\0COMMA`+Math.random()+`\0`,ka=`\0PERIOD`+Math.random()+`\0`,Aa=new RegExp(Ta,`g`),ja=new RegExp(Ea,`g`),Ma=new RegExp(Da,`g`),Na=new RegExp(Oa,`g`),Pa=new RegExp(ka,`g`),Fa=/\\\\/g,Ia=/\\{/g,La=/\\}/g,Ra=/\\,/g,za=/\\\./g;function numeric(e){return isNaN(e)?e.charCodeAt(0):parseInt(e,10)}function escapeBraces(e){return e.replace(Fa,Ta).replace(Ia,Ea).replace(La,Da).replace(Ra,Oa).replace(za,ka)}function unescapeBraces(e){return e.replace(Aa,`\\`).replace(ja,`{`).replace(Ma,`}`).replace(Na,`,`).replace(Pa,`.`)}function parseCommaParts(e){if(!e)return[``];let t=[],n=balanced(`{`,`}`,e);if(!n)return e.split(`,`);let{pre:r,body:i,post:a}=n,o=r.split(`,`);o[o.length-1]+=`{`+i+`}`;let s=parseCommaParts(a);return a.length&&(o[o.length-1]+=s.shift(),o.push.apply(o,s)),t.push.apply(t,o),t}function expand(e,t={}){if(!e)return[];let{max:n=1e5}=t;return e.slice(0,2)===`{}`&&(e=`\\{\\}`+e.slice(2)),expand_(escapeBraces(e),n,!0).map(unescapeBraces)}function embrace(e){return`{`+e+`}`}function isPadded(e){return/^-?0\d/.test(e)}function lte(e,t){return e<=t}function gte(e,t){return e>=t}function expand_(e,t,n){let r=[],i=balanced(`{`,`}`,e);if(!i)return[e];let a=i.pre,o=i.post.length?expand_(i.post,t,!1):[``];if(/\$$/.test(i.pre))for(let e=0;e=0;if(!l&&!u)return i.post.match(/,(?!,).*\}/)?(e=i.pre+`{`+i.body+Da+i.post,expand_(e,t,!0)):[e];let d;if(l)d=i.body.split(/\.\./);else if(d=parseCommaParts(i.body),d.length===1&&d[0]!==void 0&&(d=expand_(d[0],t,!1).map(embrace),d.length===1))return o.map(e=>i.pre+d[0]+e);let f;if(l&&d[0]!==void 0&&d[1]!==void 0){let e=numeric(d[0]),t=numeric(d[1]),n=Math.max(d[0].length,d[1].length),r=d.length===3&&d[2]!==void 0?Math.max(Math.abs(numeric(d[2])),1):1,i=lte;t0){let n=Array(t+1).join(`0`);e=o<0?`-`+n+e.slice(1):n+e}}f.push(e)}}else{f=[];for(let e=0;e{if(typeof e!=`string`)throw TypeError(`invalid pattern`);if(e.length>65536)throw TypeError(`pattern is too long`)},Ba={"[:alnum:]":[`\\p{L}\\p{Nl}\\p{Nd}`,!0],"[:alpha:]":[`\\p{L}\\p{Nl}`,!0],"[:ascii:]":[`\\x00-\\x7f`,!1],"[:blank:]":[`\\p{Zs}\\t`,!0],"[:cntrl:]":[`\\p{Cc}`,!0],"[:digit:]":[`\\p{Nd}`,!0],"[:graph:]":[`\\p{Z}\\p{C}`,!0,!0],"[:lower:]":[`\\p{Ll}`,!0],"[:print:]":[`\\p{C}`,!0],"[:punct:]":[`\\p{P}`,!0],"[:space:]":[`\\p{Z}\\t\\r\\n\\v\\f`,!0],"[:upper:]":[`\\p{Lu}`,!0],"[:word:]":[`\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}`,!0],"[:xdigit:]":[`A-Fa-f0-9`,!1]},braceEscape=e=>e.replace(/[[\]\\-]/g,`\\$&`),regexpEscape=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`),rangesToString=e=>e.join(``),parseClass=(e,t)=>{let n=t; +`,n],{...t,env:{...t.env,NAPI_RS_ENFORCE_VERSION_CHECK:`1`}}));return Array.isArray(r)&&r.length>0&&r.every(t=>typeof t==`string`&&re(t)&&isInside(e,I(t)))}function hasManagedEnvironment(e,t){let n=P(e,`config.json`),r=F(n)?JSON.parse(pe(n,`utf8`)):{};if([r.shimMode,r.nodeShimMode,...Object.values(r.packageManagerShimModes??{})].some(e=>e!==void 0&&e!==`managed`))return!1;let i=P(e,isWindows(t)?`env.ps1`:`env`);return ge(i).isFile()}function hasValidShims(e,t,n,r,i){let a=[...va,...supportsScopedEnv(i)?ya:[`corepack`]];if(isWindows(n)){let n=pe(P(ne(t),`vp-shim.exe`));return ge(P(e.bin,`vp-use.cmd`)).isFile()?a.every(t=>{let i=pe(P(e.bin,`${t}.exe`)),[a,...o]=pe(P(e.bin,`${t}.shim`),`utf8`).trim().split(/\r?\n/),s=new Map(o.map(e=>{let t=e.indexOf(`=`);return[e.slice(0,t),e.slice(t+1)]}));return i.equals(n)&&a===`vite-plus-shim-v1`&&s.get(`layout`)===r&&s.get(`data`)===e.data&&s.get(`cache`)===e.cache}):!1}let o=I(t);return a.every(t=>{let n=P(e.bin,t);return le(n,de.X_OK),I(n)===o})}const xa=2e3;async function installVitePlus(e){let{version:t}=e,n=findReusableVitePlus(t);if(n){ensureVitePlusBinsInPath(n,!0),info(`Reusing ${la}@${t} from ${n.bin}`);return}info(`Installing ${la}@${t}...`);let r={...process.env,VP_VERSION:t,VITE_PLUS_VERSION:t},i=supportsVitePlusDirs(t)?createVitePlusDirsFile():void 0;i?(r.VP_VPDIRS_AWARE=`1`,r[ma]=i):(delete r.VP_VPDIRS_AWARE,delete r[ma]);let a=pkgPrNewCommitSha(t);a&&(r.VP_PR_VERSION=a);let{pinned:o,fallback:s}=getInstallScriptSources(t),c=o.length+s.length,l=2*c,u=``,d=0,tryUrls=async e=>{for(let t=0;t<2;t++)for(let t of e){let{url:e}=t;d++;try{let e=await runInstallCommand(t,r);if(e===0)return!0;u=`exit code ${e}`}catch(e){u=e instanceof Error?e.message:String(e)}d0){if(await tryUrls(o)){ensureVitePlusBinInPath(t,i);return}warning(`Could not fetch the install script pinned to ${la}@${t}. Falling back to the checksum-pinned default install script. The default script may not be compatible with ${t}.`)}if(await tryUrls(s)){ensureVitePlusBinInPath(t,i);return}throw Error(`Failed to install ${la} after ${l} attempts across ${c} URL(s): ${u}`)}finally{i&&removeVitePlusDirsFile(i)}}async function runInstallCommand(e,t){let n={env:t,ignoreReturnCode:!0},{command:r,args:i}=getInstallScriptCommand(e,process.platform,t.VP_VPDIRS_AWARE===`1`);return exec(r,i,n)}function ensureVitePlusBinInPath(e,t){ensureVitePlusBinsInPath(resolveVitePlusBinDirs(e,t,P(getVitePlusHome(),`bin`)))}function ensureVitePlusBinsInPath({bin:e,fallbackBin:t},n=!1){(n||!process.env.PATH?.split(N).includes(e))&&addPath(e),t&&exportVariable(`PATH`,appendFallbackBinToPath(process.env.PATH,t))}function getOptions(e){let t={followSymbolicLinks:!0,implicitDescendants:!0,matchDirectories:!0,omitBrokenSymbolicLinks:!0,excludeHiddenFiles:!1};return e&&(typeof e.followSymbolicLinks==`boolean`&&(t.followSymbolicLinks=e.followSymbolicLinks,debug(`followSymbolicLinks '${t.followSymbolicLinks}'`)),typeof e.implicitDescendants==`boolean`&&(t.implicitDescendants=e.implicitDescendants,debug(`implicitDescendants '${t.implicitDescendants}'`)),typeof e.matchDirectories==`boolean`&&(t.matchDirectories=e.matchDirectories,debug(`matchDirectories '${t.matchDirectories}'`)),typeof e.omitBrokenSymbolicLinks==`boolean`&&(t.omitBrokenSymbolicLinks=e.omitBrokenSymbolicLinks,debug(`omitBrokenSymbolicLinks '${t.omitBrokenSymbolicLinks}'`)),typeof e.excludeHiddenFiles==`boolean`&&(t.excludeHiddenFiles=e.excludeHiddenFiles,debug(`excludeHiddenFiles '${t.excludeHiddenFiles}'`))),t}const Sa=process.platform===`win32`;function dirname$1(e){if(e=safeTrimTrailingSeparator(e),Sa&&/^\\\\[^\\]+(\\[^\\]+)?$/.test(e))return e;let t=u.dirname(e);return Sa&&/^\\\\[^\\]+\\[^\\]+\\$/.test(t)&&(t=safeTrimTrailingSeparator(t)),t}function ensureAbsoluteRoot(e,t){if(h(e,`ensureAbsoluteRoot parameter 'root' must not be empty`),h(t,`ensureAbsoluteRoot parameter 'itemPath' must not be empty`),hasAbsoluteRoot(t))return t;if(Sa){if(t.match(/^[A-Z]:[^\\/]|^[A-Z]:$/i)){let e=process.cwd();return h(e.match(/^[A-Z]:\\/i),`Expected current directory to start with an absolute drive root. Actual '${e}'`),t[0].toUpperCase()===e[0].toUpperCase()?t.length===2?`${t[0]}:\\${e.substr(3)}`:(e.endsWith(`\\`)||(e+=`\\`),`${t[0]}:\\${e.substr(3)}${t.substr(2)}`):`${t[0]}:\\${t.substr(2)}`}if(normalizeSeparators(t).match(/^\\$|^\\[^\\]/)){let e=process.cwd();return h(e.match(/^[A-Z]:\\/i),`Expected current directory to start with an absolute drive root. Actual '${e}'`),`${e[0]}:\\${t.substr(1)}`}}return h(hasAbsoluteRoot(e),`ensureAbsoluteRoot parameter 'root' must have an absolute root`),e.endsWith(`/`)||Sa&&e.endsWith(`\\`)||(e+=u.sep),e+t}function hasAbsoluteRoot(e){return h(e,`hasAbsoluteRoot parameter 'itemPath' must not be empty`),e=normalizeSeparators(e),Sa?e.startsWith(`\\\\`)||/^[A-Z]:\\/i.test(e):e.startsWith(`/`)}function hasRoot(e){return h(e,`isRooted parameter 'itemPath' must not be empty`),e=normalizeSeparators(e),Sa?e.startsWith(`\\`)||/^[A-Z]:/i.test(e):e.startsWith(`/`)}function normalizeSeparators(e){return e||=``,Sa?(e=e.replace(/\//g,`\\`),(/^\\\\+[^\\]/.test(e)?`\\`:``)+e.replace(/\\\\+/g,`\\`)):e.replace(/\/\/+/g,`/`)}function safeTrimTrailingSeparator(e){return e?(e=normalizeSeparators(e),!e.endsWith(u.sep)||e===u.sep||Sa&&/^[A-Z]:\\$/i.test(e)?e:e.substr(0,e.length-1)):``}var Ca;(function(e){e[e.None=0]=`None`,e[e.Directory=1]=`Directory`,e[e.File=2]=`File`,e[e.All=3]=`All`})(Ca||={});const wa=process.platform===`win32`;function getSearchPaths(e){e=e.filter(e=>!e.negate);let t={};for(let n of e){let e=wa?n.searchPath.toUpperCase():n.searchPath;t[e]=`candidate`}let n=[];for(let r of e){let e=wa?r.searchPath.toUpperCase():r.searchPath;if(t[e]===`included`)continue;let i=!1,a=e,o=dirname$1(a);for(;o!==a;){if(t[o]){i=!0;break}a=o,o=dirname$1(a)}i||(n.push(r.searchPath),t[e]=`included`)}return n}function match$1(e,t){let n=Ca.None;for(let r of e)r.negate?n&=~r.match(t):n|=r.match(t);return n}function partialMatch(e,t){return e.some(e=>!e.negate&&e.partialMatch(t))}const balanced=(e,t,n)=>{let r=e instanceof RegExp?maybeMatch(e,n):e,i=t instanceof RegExp?maybeMatch(t,n):t,a=r!==null&&i!=null&&range$1(r,i,n);return a&&{start:a[0],end:a[1],pre:n.slice(0,a[0]),body:n.slice(a[0]+r.length,a[1]),post:n.slice(a[1]+i.length)}},maybeMatch=(e,t)=>{let n=t.match(e);return n?n[0]:null},range$1=(e,t,n)=>{let r,i,a,o,s,c=n.indexOf(e),l=n.indexOf(t,c+1),u=c;if(c>=0&&l>0){if(e===t)return[c,l];for(r=[],a=n.length;u>=0&&!s;){if(u===c)r.push(u),c=n.indexOf(e,u+1);else if(r.length===1){let e=r.pop();e!==void 0&&(s=[e,l])}else i=r.pop(),i!==void 0&&i=0?c:l}r.length&&o!==void 0&&(s=[a,o])}return s},Ta=`\0SLASH`+Math.random()+`\0`,Ea=`\0OPEN`+Math.random()+`\0`,Da=`\0CLOSE`+Math.random()+`\0`,Oa=`\0COMMA`+Math.random()+`\0`,ka=`\0PERIOD`+Math.random()+`\0`,Aa=new RegExp(Ta,`g`),ja=new RegExp(Ea,`g`),Ma=new RegExp(Da,`g`),Na=new RegExp(Oa,`g`),Pa=new RegExp(ka,`g`),Fa=/\\\\/g,Ia=/\\{/g,La=/\\}/g,Ra=/\\,/g,za=/\\\./g;function numeric(e){return isNaN(e)?e.charCodeAt(0):parseInt(e,10)}function escapeBraces(e){return e.replace(Fa,Ta).replace(Ia,Ea).replace(La,Da).replace(Ra,Oa).replace(za,ka)}function unescapeBraces(e){return e.replace(Aa,`\\`).replace(ja,`{`).replace(Ma,`}`).replace(Na,`,`).replace(Pa,`.`)}function parseCommaParts(e){if(!e)return[``];let t=[],n=balanced(`{`,`}`,e);if(!n)return e.split(`,`);let{pre:r,body:i,post:a}=n,o=r.split(`,`);o[o.length-1]+=`{`+i+`}`;let s=parseCommaParts(a);return a.length&&(o[o.length-1]+=s.shift(),o.push.apply(o,s)),t.push.apply(t,o),t}function expand(e,t={}){if(!e)return[];let{max:n=1e5}=t;return e.slice(0,2)===`{}`&&(e=`\\{\\}`+e.slice(2)),expand_(escapeBraces(e),n,!0).map(unescapeBraces)}function embrace(e){return`{`+e+`}`}function isPadded(e){return/^-?0\d/.test(e)}function lte(e,t){return e<=t}function gte(e,t){return e>=t}function expand_(e,t,n){let r=[],i=balanced(`{`,`}`,e);if(!i)return[e];let a=i.pre,o=i.post.length?expand_(i.post,t,!1):[``];if(/\$$/.test(i.pre))for(let e=0;e=0;if(!l&&!u)return i.post.match(/,(?!,).*\}/)?(e=i.pre+`{`+i.body+Da+i.post,expand_(e,t,!0)):[e];let d;if(l)d=i.body.split(/\.\./);else if(d=parseCommaParts(i.body),d.length===1&&d[0]!==void 0&&(d=expand_(d[0],t,!1).map(embrace),d.length===1))return o.map(e=>i.pre+d[0]+e);let f;if(l&&d[0]!==void 0&&d[1]!==void 0){let e=numeric(d[0]),t=numeric(d[1]),n=Math.max(d[0].length,d[1].length),r=d.length===3&&d[2]!==void 0?Math.max(Math.abs(numeric(d[2])),1):1,i=lte;t0){let n=Array(t+1).join(`0`);e=o<0?`-`+n+e.slice(1):n+e}}f.push(e)}}else{f=[];for(let e=0;e{if(typeof e!=`string`)throw TypeError(`invalid pattern`);if(e.length>65536)throw TypeError(`pattern is too long`)},Ba={"[:alnum:]":[`\\p{L}\\p{Nl}\\p{Nd}`,!0],"[:alpha:]":[`\\p{L}\\p{Nl}`,!0],"[:ascii:]":[`\\x00-\\x7f`,!1],"[:blank:]":[`\\p{Zs}\\t`,!0],"[:cntrl:]":[`\\p{Cc}`,!0],"[:digit:]":[`\\p{Nd}`,!0],"[:graph:]":[`\\p{Z}\\p{C}`,!0,!0],"[:lower:]":[`\\p{Ll}`,!0],"[:print:]":[`\\p{C}`,!0],"[:punct:]":[`\\p{P}`,!0],"[:space:]":[`\\p{Z}\\t\\r\\n\\v\\f`,!0],"[:upper:]":[`\\p{Lu}`,!0],"[:word:]":[`\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}`,!0],"[:xdigit:]":[`A-Fa-f0-9`,!1]},braceEscape=e=>e.replace(/[[\]\\-]/g,`\\$&`),regexpEscape=e=>e.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,`\\$&`),rangesToString=e=>e.join(``),parseClass=(e,t)=>{let n=t; /* c8 ignore start */ if(e.charAt(n)!==`[`)throw Error(`not in a brace expression`); /* c8 ignore stop */ diff --git a/scripts/update-installer-checksums.mjs b/scripts/update-installer-checksums.mjs new file mode 100644 index 0000000..6e43fb1 --- /dev/null +++ b/scripts/update-installer-checksums.mjs @@ -0,0 +1,41 @@ +import { createHash } from "node:crypto"; +import { readFile, writeFile } from "node:fs/promises"; + +// Supply the reviewed upstream commit explicitly. Never resolve a moving ref +// while installing Vite+: these checksums are part of the setup-vp release. +const [version, commit, flag] = process.argv.slice(2); +if ( + !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(version ?? "") || + !/^[0-9a-f]{40}$/.test(commit ?? "") || + (flag !== undefined && flag !== "--default") +) { + throw new Error( + "Usage: node scripts/update-installer-checksums.mjs [--default]", + ); +} + +const manifestPath = new URL("../src/ci/installer-checksums.json", import.meta.url); +const manifest = JSON.parse(await readFile(manifestPath, "utf8")); +const checksums = {}; +for (const extension of ["sh", "ps1"]) { + const url = `https://raw.githubusercontent.com/voidzero-dev/vite-plus/${commit}/packages/cli/install.${extension}`; + const response = await fetch(url, { signal: AbortSignal.timeout(15_000), redirect: "error" }); + if (!response.ok) throw new Error(`Download failed (${response.status}): ${url}`); + const bytes = Buffer.from(await response.arrayBuffer()); + if (bytes.length === 0) throw new Error(`Empty installer: ${url}`); + checksums[extension] = createHash("sha256").update(bytes).digest("hex"); + if (bytes.includes(`install-legacy.${extension}`)) { + const legacyUrl = url.replace(`install.${extension}`, `install-legacy.${extension}`); + const legacy = await fetch(legacyUrl, { + signal: AbortSignal.timeout(15_000), + redirect: "error", + }); + if (!legacy.ok) throw new Error(`Download failed (${legacy.status}): ${legacyUrl}`); + const legacyBytes = Buffer.from(await legacy.arrayBuffer()); + if (legacyBytes.length === 0) throw new Error(`Empty installer: ${legacyUrl}`); + checksums[`legacy_${extension}`] = createHash("sha256").update(legacyBytes).digest("hex"); + } +} +manifest.releases[version] = { commit, ...checksums }; +if (flag === "--default") manifest.defaultVersion = version; +await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`); diff --git a/src/azure/install-viteplus.test.ts b/src/azure/install-viteplus.test.ts index c9ef7dd..e1d998f 100644 --- a/src/azure/install-viteplus.test.ts +++ b/src/azure/install-viteplus.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it, vi } from "vite-plus/test"; import { writeFileSync } from "node:fs"; import { join } from "node:path"; +import { getInstallScriptSources, type InstallScriptSource } from "../ci/install-script-urls.js"; import { installVitePlus } from "./install-viteplus.js"; function writeDirsFile(env: Record, bin: string): void { @@ -20,7 +21,11 @@ describe("installVitePlus", () => { it("uses PowerShell installers on Windows and bash installers on Unix", async () => { const calls: NodeJS.Platform[] = []; const runInstall = vi.fn( - (_url: string, env: Record, platform: NodeJS.Platform = process.platform) => { + ( + _source: InstallScriptSource, + env: Record, + platform: NodeJS.Platform = process.platform, + ) => { calls.push(platform); writeDirsFile(env, `/test/${platform}/bin`); return 0; @@ -48,13 +53,13 @@ describe("installVitePlus", () => { for (const [, installEnv] of runInstall.mock.calls) { expect(installEnv.VP_NODE_MANAGER).toBeUndefined(); } - expect(runInstall.mock.calls[0]?.[0]).toContain("install.ps1"); - expect(runInstall.mock.calls[1]?.[0]).toContain("install.sh"); + expect(runInstall.mock.calls[0]?.[0].url).toContain("install.ps1"); + expect(runInstall.mock.calls[1]?.[0].url).toContain("install.sh"); }); - it("installs exact versions with the release-tag script before the latest script", async () => { + it("tries the release-specific checksum pin before the default pin", async () => { // Fail every attempt so the full URL order is observable. - const runInstall = vi.fn((_url: string, _env: Record) => 1); + const runInstall = vi.fn((_source: InstallScriptSource, _env: Record) => 1); const warnings: string[] = []; await expect( @@ -72,18 +77,20 @@ describe("installVitePlus", () => { }), ).rejects.toThrow(/after 8 attempts across 4 URL\(s\)/); - const urls = runInstall.mock.calls.map((call) => call[0]); - expect(urls[0]).toContain("/v0.2.9/packages/cli/install.sh"); + const urls = runInstall.mock.calls.map((call) => call[0].url); + expect(urls[0]).toBe(getInstallScriptSources("0.2.9", "linux").pinned[0]!.url); expect(urls[1]).toContain("jsdelivr"); - expect(urls[4]).toBe("https://viteplus.dev/install.sh"); - expect(warnings.some((message) => message.includes("Falling back to the latest"))).toBe(true); + expect(urls[4]).toBe(getInstallScriptSources("latest", "linux").fallback[0]!.url); + expect( + warnings.some((message) => message.includes("Falling back to the checksum-pinned default")), + ).toBe(true); const installEnv = runInstall.mock.calls[0]?.[1] as Record; expect(installEnv.VP_VPDIRS_AWARE).toBeUndefined(); expect(installEnv.SETUP_VP_DIRS_FILE).toBeUndefined(); }); it("routes pkg.pr.new commit builds through VP_PR_VERSION", async () => { - const runInstall = vi.fn((_url: string, env: Record) => { + const runInstall = vi.fn((_source: InstallScriptSource, env: Record) => { writeDirsFile(env, "/test/data/bin"); return 0; }); @@ -99,7 +106,7 @@ describe("installVitePlus", () => { }); const installCalls = runInstall.mock.calls as unknown as Array< - [string, Record, NodeJS.Platform?] + [InstallScriptSource, Record, NodeJS.Platform?] >; expect(installCalls[0]?.[1]?.VP_PR_VERSION).toBe(sha); expect(installCalls[0]?.[1]?.VP_VPDIRS_AWARE).toBe("1"); @@ -109,7 +116,7 @@ describe("installVitePlus", () => { it("uses the installed version to resolve the latest dist-tag", async () => { const prependPath = vi.fn(); const env = { HOME: "/home/runner", PATH: "/usr/bin" }; - const runInstall = vi.fn((_url: string, installEnv: Record) => { + const runInstall = vi.fn((_source: InstallScriptSource, installEnv: Record) => { writeFileSync(installEnv.SETUP_VP_DIRS_FILE, "vp v0.2.9\n"); return 0; }); @@ -134,7 +141,7 @@ describe("installVitePlus", () => { { version: "latest", output: "vp v0.3.0\n" }, ])("fails when $version does not report valid VpDirs", async ({ version, output }) => { const prependPath = vi.fn(); - const runInstall = vi.fn((_url: string, env: Record) => { + const runInstall = vi.fn((_source: InstallScriptSource, env: Record) => { if (output !== undefined) writeFileSync(env.SETUP_VP_DIRS_FILE, output); return 0; }); @@ -159,7 +166,7 @@ describe("installVitePlus", () => { it("prepends the bin directory reported by the installed payload", async () => { const prependPath = vi.fn(); const env = { PATH: "/usr/bin" }; - const runInstall = vi.fn((_url: string, installEnv: Record) => { + const runInstall = vi.fn((_source: InstallScriptSource, installEnv: Record) => { writeDirsFile(installEnv, "/test/data/bin"); return 0; }); diff --git a/src/ci/install-script-urls.test.ts b/src/ci/install-script-urls.test.ts index db296d3..5381736 100644 --- a/src/ci/install-script-urls.test.ts +++ b/src/ci/install-script-urls.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from "vite-plus/test"; -import { getInstallScriptUrls, pkgPrNewCommitSha } from "./install-script-urls.js"; +import { getInstallScriptSources, pkgPrNewCommitSha } from "./install-script-urls.js"; const commitSha = "7d848b3da1987fa60b4cf18487fcc36a2a697e94"; @@ -14,45 +14,56 @@ describe("pkgPrNewCommitSha", () => { }); }); -describe("getInstallScriptUrls", () => { - it("pins an exact version to its release tag, with jsDelivr as mirror", () => { - const { pinned, latest } = getInstallScriptUrls("0.2.9", "linux"); - expect(pinned).toEqual([ - "https://raw.githubusercontent.com/voidzero-dev/vite-plus/v0.2.9/packages/cli/install.sh", - "https://cdn.jsdelivr.net/gh/voidzero-dev/vite-plus@v0.2.9/packages/cli/install.sh", - ]); - expect(latest).toEqual([ - "https://viteplus.dev/install.sh", - "https://raw.githubusercontent.com/voidzero-dev/vite-plus/main/packages/cli/install.sh", +describe("getInstallScriptSources", () => { + it("pins historical versions to a commit and the same checksum on both mirrors", () => { + const { pinned } = getInstallScriptSources("0.2.9", "linux"); + expect(pinned.map(({ url }) => url)).toEqual([ + "https://raw.githubusercontent.com/voidzero-dev/vite-plus/73bdd105c2b7c263b55f7e9b48a37a8933cc317a/packages/cli/install.sh", + "https://cdn.jsdelivr.net/gh/voidzero-dev/vite-plus@73bdd105c2b7c263b55f7e9b48a37a8933cc317a/packages/cli/install.sh", ]); + expect(pinned[0]!.sha256).toMatch(/^[a-f0-9]{64}$/); + expect(pinned[1]!.sha256).toBe(pinned[0]!.sha256); + expect(pinned[0]!.legacy).toBeUndefined(); }); - it("pins prerelease versions to their release tag", () => { - const { pinned } = getInstallScriptUrls("0.1.21-alpha.7", "linux"); - expect(pinned[0]).toContain("/v0.1.21-alpha.7/"); + it("keeps prerelease-specific pins", () => { + const { pinned } = getInstallScriptSources("0.1.21-alpha.7", "linux"); + expect(pinned[0]!.url).toContain("/c61621ac610ad114746b98d7e457ca4e13171837/"); }); - it("pins pkg.pr.new commit builds to the commit, lowercasing the SHA", () => { - const { pinned } = getInstallScriptUrls(`0.0.0-commit.${commitSha.toUpperCase()}`, "linux"); - expect(pinned).toEqual([ - `https://raw.githubusercontent.com/voidzero-dev/vite-plus/${commitSha}/packages/cli/install.sh`, - `https://cdn.jsdelivr.net/gh/voidzero-dev/vite-plus@${commitSha}/packages/cli/install.sh`, - ]); + it.each([ + "latest", + "next", + "99.0.0", + "^0.2.0", + "0.2", + "0.2.x", + "0.2.9+build.5", + "", + "__proto__", + `0.0.0-commit.${commitSha}`, + ])("uses only the bundled fallback pin for %j", (version) => { + const { pinned, fallback } = getInstallScriptSources(version, "linux"); + expect(pinned).toEqual([]); + expect(fallback).toEqual(getInstallScriptSources("latest", "linux").fallback); + expect(fallback).toHaveLength(2); }); - it.each(["latest", "next", "^0.2.0", "0.2", "0.2.x", "0.2.9+build.5", ""])( - "does not pin %j", - (version) => { - const { pinned, latest } = getInstallScriptUrls(version, "linux"); - expect(pinned).toEqual([]); - expect(latest).toHaveLength(2); + it.each(["linux", "win32"] as const)( + "pins all %s files, including legacy dependencies", + (platform) => { + const { fallback } = getInstallScriptSources("latest", platform); + const extension = platform === "win32" ? "ps1" : "sh"; + for (const source of fallback) { + expect(source.url).toMatch( + new RegExp(`[/@][a-f0-9]{40}/packages/cli/install\\.${extension}$`), + ); + expect(source.sha256).toMatch(/^[a-f0-9]{64}$/); + expect(source.legacy?.url).toBe( + source.url.replace(`install.${extension}`, `install-legacy.${extension}`), + ); + expect(source.legacy?.sha256).toMatch(/^[a-f0-9]{64}$/); + } }, ); - - it("uses install.ps1 on Windows for both pinned and latest URLs", () => { - const { pinned, latest } = getInstallScriptUrls("0.2.9", "win32"); - for (const url of [...pinned, ...latest]) { - expect(url).toMatch(/install\.ps1$/); - } - }); }); diff --git a/src/ci/install-script-urls.ts b/src/ci/install-script-urls.ts index fe6c25b..27a5f0e 100644 --- a/src/ci/install-script-urls.ts +++ b/src/ci/install-script-urls.ts @@ -1,16 +1,7 @@ import { isWindows } from "./platform.js"; +import manifest from "./installer-checksums.json" with { type: "json" }; -// The install script changes with the CLI: a script from main can install an -// older CLI incorrectly. Example: the XDG directory-layout switch in -// voidzero-dev/vite-plus#2346 changes where fresh installs land. When the -// requested version maps to a git ref in the vite-plus repo (the release tag -// for an exact version, the commit itself for a pkg.pr.new preview build), -// prefer the script from that ref: script and CLI then always match. -// Dist-tags ("latest", "next") keep the latest script, which matches whatever -// they resolve to. const REPO_RAW_BASE = "https://raw.githubusercontent.com/voidzero-dev/vite-plus"; -// jsDelivr mirrors GitHub refs on independent infrastructure, so the pinned -// script stays reachable through a raw.githubusercontent.com incident. const REPO_CDN_BASE = "https://cdn.jsdelivr.net/gh/voidzero-dev/vite-plus"; const SCRIPT_DIR = "packages/cli"; @@ -26,53 +17,62 @@ const SCRIPT_DIR = "packages/cli"; // build. const PKG_PR_NEW_COMMIT_RE = /^0\.0\.0-commit\.([0-9a-f]{40})$/i; -// An exact published version (`major.minor.patch` with an optional prerelease -// suffix, e.g. `0.1.21-alpha.7`) maps to its `v` release tag. The -// regex rejects build metadata (`+meta`): vite-plus never publishes it, and -// `+` would need URL-escaping. Nothing else maps to a ref (dist-tags, or -// ranges passed through the raw `version` input). -const EXACT_RELEASE_VERSION_RE = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/; - export function pkgPrNewCommitSha(version: string): string | undefined { return version.match(PKG_PR_NEW_COMMIT_RE)?.[1]; } -export interface InstallScriptUrls { - /** - * Script URLs pinned to the git ref matching the requested version; empty - * when the version cannot be mapped to a ref. - */ - pinned: string[]; - /** - * Latest-script URLs: the viteplus.dev CDN first, then the vite-plus repo - * main branch, so a CDN/edge incident doesn't fully block CI. - */ - latest: string[]; +export interface InstallerFile { + url: string; + sha256: string; +} + +export interface InstallScriptSource extends InstallerFile { + legacy?: InstallerFile; +} + +interface InstallerPin { + commit: string; + sh: string; + ps1: string; + legacy_sh?: string; + legacy_ps1?: string; } -export function getInstallScriptUrls( +const releases: Record = manifest.releases; + +export function getInstallScriptSources( version: string, platform: NodeJS.Platform = process.platform, -): InstallScriptUrls { - const script = isWindows(platform) ? "install.ps1" : "install.sh"; - const ref = installScriptRef(version); +): { pinned: InstallScriptSource[]; fallback: InstallScriptSource[] } { + const extension = isWindows(platform) ? "ps1" : "sh"; + function sources(pin: InstallerPin): InstallScriptSource[] { + const path = `${SCRIPT_DIR}/install.${extension}`; + return [`${REPO_RAW_BASE}/${pin.commit}/${path}`, `${REPO_CDN_BASE}@${pin.commit}/${path}`].map( + (url) => { + const legacySha256 = pin[`legacy_${extension}`]; + return { + url, + sha256: pin[extension], + ...(legacySha256 + ? { + legacy: { + url: url.replace(`install.${extension}`, `install-legacy.${extension}`), + sha256: legacySha256, + }, + } + : {}), + }; + }, + ); + } + + // Keep historical installer/layout compatibility without trusting moving tags + // or checksums fetched alongside the script. Unknown releases and previews + // use the fallback approved in this setup-vp release, never upstream main. + const pin = Object.hasOwn(releases, version) ? releases[version] : undefined; + const fallback = releases[manifest.defaultVersion]!; return { - pinned: ref - ? [ - `${REPO_RAW_BASE}/${ref}/${SCRIPT_DIR}/${script}`, - `${REPO_CDN_BASE}@${ref}/${SCRIPT_DIR}/${script}`, - ] - : [], - latest: [`https://viteplus.dev/${script}`, `${REPO_RAW_BASE}/main/${SCRIPT_DIR}/${script}`], + pinned: pin && pin.commit !== fallback.commit ? sources(pin) : [], + fallback: sources(fallback), }; } - -function installScriptRef(version: string): string | undefined { - // Git SHAs are lowercase, so lowercase the extracted SHA before it becomes - // the ref. Check the commit shape first: it also matches the exact-version - // regex but must resolve to the commit, not a `v0.0.0-commit.*` tag. - const sha = pkgPrNewCommitSha(version); - if (sha) return sha.toLowerCase(); - if (EXACT_RELEASE_VERSION_RE.test(version)) return `v${version}`; - return undefined; -} diff --git a/src/ci/install-viteplus.ts b/src/ci/install-viteplus.ts index 1c2a97c..0486618 100644 --- a/src/ci/install-viteplus.ts +++ b/src/ci/install-viteplus.ts @@ -2,7 +2,11 @@ import { homedir } from "node:os"; import { join } from "node:path"; import { setTimeout as sleep } from "node:timers/promises"; import { spawnSync } from "node:child_process"; -import { getInstallScriptUrls, pkgPrNewCommitSha } from "./install-script-urls.js"; +import { + getInstallScriptSources, + pkgPrNewCommitSha, + type InstallScriptSource, +} from "./install-script-urls.js"; import { isWindows } from "./platform.js"; import { appendFallbackBinToPath, @@ -26,11 +30,11 @@ export function getVitePlusHome( } function runInstallCommand( - url: string, + source: InstallScriptSource, env: Record, - platform: NodeJS.Platform = process.platform, + platform: NodeJS.Platform, ): number { - const { command, args } = getInstallScriptCommand(url, platform, env.VP_VPDIRS_AWARE === "1"); + const { command, args } = getInstallScriptCommand(source, platform, env.VP_VPDIRS_AWARE === "1"); const spawnOptions = { env: { ...process.env, ...env }, stdio: "inherit" as const, @@ -92,21 +96,22 @@ export async function installVitePlus( env.VP_PR_VERSION = prVersion; } - // Prefer the install script pinned to the requested version's git ref. Fall - // back to the latest script only after all pinned sources fail (see + // Prefer the bundled pin for the requested version. Try the default pin + // only after all version-specific sources fail (see // ../ci/install-script-urls.ts for the rationale). - const { pinned, latest } = getInstallScriptUrls(version, platform); - const totalUrls = pinned.length + latest.length; + const { pinned, fallback } = getInstallScriptSources(version, platform); + const totalUrls = pinned.length + fallback.length; const maxAttempts = INSTALL_MAX_ROUNDS * totalUrls; let failureReason = ""; let attempt = 0; - async function tryUrls(urls: string[]): Promise { + async function tryUrls(urls: InstallScriptSource[]): Promise { for (let round = 0; round < INSTALL_MAX_ROUNDS; round += 1) { - for (const url of urls) { + for (const source of urls) { + const { url } = source; attempt += 1; try { - const exitCode = runInstall(url, env, platform); + const exitCode = runInstall(source, env, platform); if (exitCode === 0) return true; failureReason = `exit code ${exitCode}`; } catch (error) { @@ -148,11 +153,11 @@ export async function installVitePlus( return; } warn( - `setup-vp: could not fetch the install script pinned to Vite+ ${version}. Falling back to the latest install script. The latest script may not be compatible with ${version}.`, + `setup-vp: could not fetch the install script pinned to Vite+ ${version}. Falling back to the checksum-pinned default install script. The default script may not be compatible with ${version}.`, ); } - if (await tryUrls(latest)) { + if (await tryUrls(fallback)) { ensureBinInPath(); return; } diff --git a/src/ci/installer-checksums.json b/src/ci/installer-checksums.json new file mode 100644 index 0000000..77a1e4c --- /dev/null +++ b/src/ci/installer-checksums.json @@ -0,0 +1,477 @@ +{ + "defaultVersion": "1.1.0", + "releases": { + "1.1.0": { + "commit": "3aa366ee03ac162f5acfd8ee7c752a8245d904c6", + "sh": "e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f", + "ps1": "a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe", + "legacy_sh": "a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514", + "legacy_ps1": "98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07" + }, + "1.0.0": { + "commit": "fc287d7b1c0dc008dbc65d1d2b2f51a44e2a5ea4", + "sh": "e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f", + "ps1": "a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe", + "legacy_sh": "a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514", + "legacy_ps1": "98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07" + }, + "1.0.0-rc.1": { + "commit": "a9d81a4911190345408854b1c1f5cabdc8490a10", + "sh": "e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f", + "ps1": "a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe", + "legacy_sh": "a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514", + "legacy_ps1": "98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07" + }, + "1.0.0-rc.0": { + "commit": "173e734826cdf79ef05ba91390c3508be5ebba3b", + "sh": "e79e48da3b2817c179f581c943e2e1ccf0c690d32d0ed11b8cbfbebd7196918f", + "ps1": "a3a5232c7a270426ef08197b0ffbdb51479a38c63f7f6399ad3217027ead2bfe", + "legacy_sh": "a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514", + "legacy_ps1": "98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07" + }, + "0.3.3": { + "commit": "45f9b9ac7128c2829f9130352ebcdc6462aca3d9", + "sh": "6ed2d2847e5b7f3d67b6f91f2d28200bdffcffcd91ef2a336cf764d02776fcc3", + "ps1": "bf909eed0675633eab5679fe1b40b1c313ee6e976a5ac732f2df3d35e39b0090", + "legacy_sh": "a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514", + "legacy_ps1": "98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07" + }, + "0.3.2": { + "commit": "9fd0d0ae6e775db361d3d5f9f3a18b47bc195420", + "sh": "6ed2d2847e5b7f3d67b6f91f2d28200bdffcffcd91ef2a336cf764d02776fcc3", + "ps1": "d202bcf693221f1b9732c73327dd4f3585614fadad647aebbf55b3eb453ab082", + "legacy_sh": "a3825f5a48d6ac5ac523d79a33ef3eff954013b8af7e4208231ac3de66030514", + "legacy_ps1": "98348a3b7000c35a20ce8e51b4c6fe2d77010edaa8ae2f9a92a2e461dbfa6b07" + }, + "0.3.1": { + "commit": "13e1e5ab0d993d5a704d7bcb9419cee9aca79a7d", + "sh": "d4a1ffa8245bdfcf39a786d545be6a43e231b771c32d7c02414bb96d4f5d9cdc", + "ps1": "096c1948222a83b424f6b98417567ea4437414a85ed380fe74ec89c406e5cf86" + }, + "0.3.0": { + "commit": "b2d15e3899dcc8adedfd45d98de9d30046a624f4", + "sh": "3dd88cedb6d9b2665c305eda5413971417c8f183a819386148131b66a2cc6b2e", + "ps1": "e803c4cdc20dce9a67eaa2f9780272336ef5bdaf40cc2d4366e8961cd11df572" + }, + "0.2.9": { + "commit": "73bdd105c2b7c263b55f7e9b48a37a8933cc317a", + "sh": "58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54", + "ps1": "4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906" + }, + "0.2.8": { + "commit": "fc3f0e266d13f0ab288097e202edf4112534a1d2", + "sh": "58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54", + "ps1": "4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906" + }, + "0.2.7": { + "commit": "c17e1c3c7cf859a29dd32eb60e82dc8157449ac2", + "sh": "58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54", + "ps1": "4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906" + }, + "0.2.6": { + "commit": "cd064c68a45fb82badfc1853ff690b1b70511165", + "sh": "58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54", + "ps1": "4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906" + }, + "0.2.5": { + "commit": "93dc59a324f790603ce65e629c13617468d1027d", + "sh": "58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54", + "ps1": "4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906" + }, + "0.2.4": { + "commit": "1ca9f0fcef42bbfb9a5a559f3cc4553c49c80f8c", + "sh": "58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54", + "ps1": "4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906" + }, + "0.2.3": { + "commit": "7f70680f91ad51cc4f1dae3e6cceb194ae7dd0ea", + "sh": "58bb052c6a007e662e99667d65686251b16d6b39aa21155487da6d51280b3d54", + "ps1": "4275b9aca4e6c5055fa8e20e6d0e241104a1bf6aa4c35fae03bb8db9d9bca906" + }, + "0.2.2": { + "commit": "4f7fd0b66ebb5433acdb06f8660cf0f08c5a0d4b", + "sh": "8b0a9835d871c4e67aee1c8d5b7e402d165cb55a3222743567a443028b33492e", + "ps1": "7ecc798b6b749576215be5aee2b3f11e825115d48fe576cd5a0ecca7c039de71" + }, + "0.2.1": { + "commit": "a0ed27069ea9eb65802def970ef554855993e0ac", + "sh": "6f4fe3690a3f011b4b6cec3c71035e9c04a97dd45dd9e2623dc67f842268f0d2", + "ps1": "60821b6f38a0eb984c5846722341f650e4d040c25e93add64aa134f199f86681" + }, + "0.2.0": { + "commit": "6f97f097de8833b456e431270180b621b2309994", + "sh": "6f4fe3690a3f011b4b6cec3c71035e9c04a97dd45dd9e2623dc67f842268f0d2", + "ps1": "60821b6f38a0eb984c5846722341f650e4d040c25e93add64aa134f199f86681" + }, + "0.1.24": { + "commit": "a1a2bbd6bf7e558277ab0f24f4e36243fc064043", + "sh": "304d0267bea50d9f5400f3a826f0ae27884c22325b4d149d00a2ae4736c5a0cc", + "ps1": "b54e90f2fd7749aa511248c34ac89afe868d7ac625a89074b1b3a7db03a1d02e" + }, + "0.1.23": { + "commit": "2b3383748b576212ccb94dd2c647277e0bc4f5e2", + "sh": "15242cab7c7832e2a3dc134e23059ce7726f7cca1467d78a79cd70760d3e3fb6", + "ps1": "0611cb2777dc903ede063e303b84cc8193c49375b58eaba2db86c1c5c296719a" + }, + "0.1.22": { + "commit": "12368dafa4a7b8c51fc1ef274c4cd5b60e6d3859", + "sh": "15242cab7c7832e2a3dc134e23059ce7726f7cca1467d78a79cd70760d3e3fb6", + "ps1": "0611cb2777dc903ede063e303b84cc8193c49375b58eaba2db86c1c5c296719a" + }, + "0.1.21": { + "commit": "c61621ac610ad114746b98d7e457ca4e13171837", + "sh": "8ca22990891df17cd808d7eedc3f8fcc722ad3a402191f6c125f36368af663f6", + "ps1": "8a09b7b3ab975b134e1ec6d94daebe9cd531b2f3da9246fe8d9e38ee59df26c1" + }, + "0.1.21-alpha.7": { + "commit": "c61621ac610ad114746b98d7e457ca4e13171837", + "sh": "8ca22990891df17cd808d7eedc3f8fcc722ad3a402191f6c125f36368af663f6", + "ps1": "8a09b7b3ab975b134e1ec6d94daebe9cd531b2f3da9246fe8d9e38ee59df26c1" + }, + "0.1.21-alpha.6": { + "commit": "e134e4f84d7e3447d2fbd54fabf4efa928d6ce91", + "sh": "8ca22990891df17cd808d7eedc3f8fcc722ad3a402191f6c125f36368af663f6", + "ps1": "8a09b7b3ab975b134e1ec6d94daebe9cd531b2f3da9246fe8d9e38ee59df26c1" + }, + "0.1.21-alpha.5": { + "commit": "634759714a507316148fd602a49dfceb87959b92", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.21-alpha.4": { + "commit": "dc41b711b8405fa42910fe186e8de2f58a51e14b", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.21-alpha.3": { + "commit": "7044ab9b003e42b5a5c9145dd7551da687d76989", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.21-alpha.2": { + "commit": "c4cdfc9666b5d0fd2fc2a9a4182ecb03afb5fa36", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.21-alpha.1": { + "commit": "cbd74649cf5d58dae8f309400f1754e418872f76", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.21-alpha.0": { + "commit": "7b9e6d6ce0cbc3bfef38b91034b493bc1739fc6e", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.20": { + "commit": "bcc93a46abe94c543a0d36540dbd78aabfececfb", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.20-alpha.4": { + "commit": "bcc93a46abe94c543a0d36540dbd78aabfececfb", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.20-alpha.3": { + "commit": "210897e627ea27f2d7e0a7e5d2792aaf0e2775cc", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.20-alpha.2": { + "commit": "a5f36e08ef31ff9962b0b749652f57ab09fbdeb1", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.20-alpha.1": { + "commit": "fac1a20dd4f0f4990907ac67413c5c2b90a6ae42", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.20-alpha.0": { + "commit": "aeacdb0caacf2d7627c7b8df57011fb13bc040f5", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.19": { + "commit": "41e78e2ba8ead352ca74aa32835489bfedfad63d", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.19-alpha.3": { + "commit": "da5f14712472e185a825087f485cc4072b2ba8e7", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.19-alpha.2": { + "commit": "4ac205f4434d6d362abc09e323991721da564f70", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.19-alpha.1": { + "commit": "c5510b2f6de9976fde25c200aeed28b2f496a540", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.19-alpha.0": { + "commit": "b9d218a6f9aa0c3b22fe85b6ad9229b0e135b31b", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.18": { + "commit": "6e06c175c71c725a46c409062c4c8d1fe1150449", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.18-alpha.0": { + "commit": "40a47e52cd596674a80203991013913555655f0d", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.17": { + "commit": "e159b84a95199fc17a7ffddef14caeefc81c90f2", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.17-alpha.5": { + "commit": "48e49ca0c1c062989120c41bcce9ee1db8b172dd", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.17-alpha.4": { + "commit": "a5fca7ddca580725a3ba06efbd47ee573b60c50a", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.17-alpha.3": { + "commit": "a94deea2fc68b5a6a2e2f2868df32b6cc7bf7ec8", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.17-alpha.2": { + "commit": "2703014124101b30ec2470159d84d8f9a32dd285", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.17-alpha.1": { + "commit": "ba538e199ba23ca34f895af5b36564366990725b", + "sh": "f9420c8a68f7ee62eee1bf37b7f500e5679723b786de2ba94ca365d61c4d5e8e", + "ps1": "56367e016077c5e8c5454fa36a00b8871811b664f9866f2da6951f2a95f70b88" + }, + "0.1.17-alpha.0": { + "commit": "29f821e61f41e2068713676856d7363bf72e5896", + "sh": "e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a", + "ps1": "c44111999449915902c9f0e0ddfa61ea1b3c3a0502ee4b1a3994a115abb4c5bc" + }, + "0.1.16": { + "commit": "f64bb6c98c1ff577ba7e8ae4ddb43dcfcc3624b0", + "sh": "e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a", + "ps1": "c44111999449915902c9f0e0ddfa61ea1b3c3a0502ee4b1a3994a115abb4c5bc" + }, + "0.1.16-alpha.4": { + "commit": "556043129dc6a006cbdefd40b9c68ca306f086b5", + "sh": "e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a", + "ps1": "c44111999449915902c9f0e0ddfa61ea1b3c3a0502ee4b1a3994a115abb4c5bc" + }, + "0.1.16-alpha.3": { + "commit": "6153ccb787f9b35655c1702f3220e5c7a57ca997", + "sh": "e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a", + "ps1": "53c0cfbb7e92719b18808611a977eb34312992c20cca8636d9f905c43184b860" + }, + "0.1.16-alpha.2": { + "commit": "f72d8a1f86fde0945de6e362d1fd120043f635cd", + "sh": "e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a", + "ps1": "53c0cfbb7e92719b18808611a977eb34312992c20cca8636d9f905c43184b860" + }, + "0.1.16-alpha.1": { + "commit": "38aa60a7a087113364e5b80feceaa57d3100f766", + "sh": "e07226efa02f5a0a4d09ad7997534333ca379b2b6dd3137d7184e0202ce76b5a", + "ps1": "53c0cfbb7e92719b18808611a977eb34312992c20cca8636d9f905c43184b860" + }, + "0.1.16-alpha.0": { + "commit": "a015d7897617b7807ed0d825000fc1e7e9b18e67", + "sh": "4057f586f65168077362203bcde2ea8ed07ec7ee3a560a35a20b974f4318c098", + "ps1": "e9caf430aa09d14b82f5522aeb84b9321470d09512f2634e3d2dfda77d3645f6" + }, + "0.1.15": { + "commit": "bf39b756ae038af3d34bbceeedc9ecf60afdd9a8", + "sh": "437b3dbf8bed60740183083687801c037c318a48ba590ef5e2e06594ffd61530", + "ps1": "299207f95a34b0e9a03df0bd7a77c80521b793740a5674aba80519ce7bd2c034" + }, + "0.1.15-alpha.7": { + "commit": "f922d5fa560cae6f232cb1a74099c78587806ad3", + "sh": "437b3dbf8bed60740183083687801c037c318a48ba590ef5e2e06594ffd61530", + "ps1": "299207f95a34b0e9a03df0bd7a77c80521b793740a5674aba80519ce7bd2c034" + }, + "0.1.15-alpha.6": { + "commit": "6cd75f480d9c10845d05d32be594c8cc6bce3c64", + "sh": "437b3dbf8bed60740183083687801c037c318a48ba590ef5e2e06594ffd61530", + "ps1": "299207f95a34b0e9a03df0bd7a77c80521b793740a5674aba80519ce7bd2c034" + }, + "0.1.15-alpha.5": { + "commit": "dbe191ed95750571d9e02c33849c33c6789cfee4", + "sh": "029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54", + "ps1": "735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06" + }, + "0.1.15-alpha.4": { + "commit": "3af4839e659745492252020d78d519559e4a568d", + "sh": "029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54", + "ps1": "735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06" + }, + "0.1.15-alpha.3": { + "commit": "fd1b75e2ac170472017e3e601189fdfb3ed5f5d8", + "sh": "029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54", + "ps1": "735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06" + }, + "0.1.15-alpha.2": { + "commit": "3a85b2b65ba63d6706e58ca45d9b8ae1aa04d27a", + "sh": "029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54", + "ps1": "735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06" + }, + "0.1.15-alpha.1": { + "commit": "c267e06a0e254472983af686dd376efed5344d15", + "sh": "029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54", + "ps1": "735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06" + }, + "0.1.15-alpha.0": { + "commit": "94aecfa3edb591faf2b92835732090e41eba6dbb", + "sh": "029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54", + "ps1": "735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06" + }, + "0.1.14": { + "commit": "71b90b4eadd9795f354d3d5208decf904b92d927", + "sh": "029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54", + "ps1": "735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06" + }, + "0.1.14-alpha.3": { + "commit": "01693e3781bf854ff3fd1cd755f26ade1773ccc2", + "sh": "029268628df6cedefe1d46bca277cf5d7b29723c482598163948c4d88d605f54", + "ps1": "735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06" + }, + "0.1.14-alpha.1": { + "commit": "0ff9227227bf58c48d46ea8814f21b1549f211cb", + "sh": "cf9cfa219dce0fa7a9aba8f0804214af89d3321e0eec40ebc02371c7f08acba8", + "ps1": "735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06" + }, + "0.1.14-alpha.0": { + "commit": "fc9bf496ad50dba718a1544583d19eb47ff32534", + "sh": "cf9cfa219dce0fa7a9aba8f0804214af89d3321e0eec40ebc02371c7f08acba8", + "ps1": "735aa98ada7f922862b353b6edc648af08842ec5a1d5504a1cbff511212bfc06" + }, + "0.1.13": { + "commit": "9861b670b32c53ea28dfb0b7e1189e533a13c5fd", + "sh": "4f70075425f42ff90c304da5f74a586bd1bc4cfa79cdac2d5eff3dfd7176b845", + "ps1": "7b6495786f059b2be584156884e68cb6da99f2ee6c0fddd6987c59fa604f794d" + }, + "0.1.13-alpha.5": { + "commit": "2dfc0c3c81451233abe62ed49de1266ff5069a64", + "sh": "4f70075425f42ff90c304da5f74a586bd1bc4cfa79cdac2d5eff3dfd7176b845", + "ps1": "7b6495786f059b2be584156884e68cb6da99f2ee6c0fddd6987c59fa604f794d" + }, + "0.1.13-alpha.4": { + "commit": "ffc1638a075632f9a1977f24467dcce5d31d00d1", + "sh": "4f70075425f42ff90c304da5f74a586bd1bc4cfa79cdac2d5eff3dfd7176b845", + "ps1": "7b6495786f059b2be584156884e68cb6da99f2ee6c0fddd6987c59fa604f794d" + }, + "0.1.13-alpha.3": { + "commit": "d64cba8cda73af176453e0c25e7743d6ab25486f", + "sh": "ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b", + "ps1": "9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88" + }, + "0.1.13-alpha.2": { + "commit": "9db93c21726781c7fe0d2d90b7373ad172af2dbc", + "sh": "ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b", + "ps1": "9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88" + }, + "0.1.13-alpha.1": { + "commit": "849c1263bb9913dcd1a3fe0680b6cb8113639e06", + "sh": "ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b", + "ps1": "9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88" + }, + "0.1.13-alpha.0": { + "commit": "b3d0e962b13118f3ff4097d224523833584326e6", + "sh": "ebd3e50bd66b28afb65ce54a18303086f250454745c9fb37f7bdd2e7d8f6fb1b", + "ps1": "9f15f9338edb75d094abc1cdf67a6fb54a695151f1d65fddf1d67487b1984e88" + }, + "0.1.12": { + "commit": "8c6c1b23f1fe702f21ae72ff96979bfedb66364b", + "sh": "43985e08bab995fba9c28923be6070d78f979c635c53ef7fd624a3103d9ce588", + "ps1": "c40df7d8d632cd36d56b16e27006b0886dd51785e6033ca20bcbe3308901443c" + }, + "0.1.12-alpha.2": { + "commit": "fe3189b64e0588ddae272ed6c4d49a8cbc23ce55", + "sh": "2bc79f0370486d429783850b12e039672cc7f7236712c11a23d5b9405b05a597", + "ps1": "c40df7d8d632cd36d56b16e27006b0886dd51785e6033ca20bcbe3308901443c" + }, + "0.1.11": { + "commit": "ef77182006de701eb5260a68652f6dab6db7b760", + "sh": "6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2", + "ps1": "e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca" + }, + "0.1.10": { + "commit": "1848576dcdb270611ce6e9c4b0b7ea7fdb223f32", + "sh": "6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2", + "ps1": "e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca" + }, + "0.1.9": { + "commit": "b25efbd3c2a5ebdc18496e4ca2142f6449343952", + "sh": "6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2", + "ps1": "e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca" + }, + "0.1.8": { + "commit": "0a1ec92c7b21d73317c9f3d796a35c8c9f14d0f1", + "sh": "6f1bb9867ce3aa016c69275ea18cff93a6ccb6930e54da9adc9e796f92b3b1c2", + "ps1": "e9d218df164332dcb79f7a64770e8a9b60e22eb0d7e8ce1d4df862e3e6d2cdca" + }, + "0.1.7": { + "commit": "a7dc6660a4e0f488a061d6350222adabdf763f5b", + "sh": "a8378abdf90ce4a95352f1f9918d54bd666ec347ff9cad0c3bbfa2fef6db62cd", + "ps1": "7462b3bb999b14f138d15df47a84dbdb3a7be96f56f77e9626e6624b6640eafc" + }, + "0.1.6": { + "commit": "0c40c50cb395317ca3b35508e286018114b6372c", + "sh": "a8378abdf90ce4a95352f1f9918d54bd666ec347ff9cad0c3bbfa2fef6db62cd", + "ps1": "7462b3bb999b14f138d15df47a84dbdb3a7be96f56f77e9626e6624b6640eafc" + }, + "0.1.5": { + "commit": "133340675e7eb9de8e0d8ffd8efb9de619ba6a39", + "sh": "3316073e62247a9b8fc34f1be8b24047e3e3315749cc52d68eeccae2462f78d1", + "ps1": "722de6e4ab17a6f853100055f522a2fec3a3255c394bc29be1d5fc3b6ed8f120" + }, + "0.1.4": { + "commit": "12abba5def4cf4479f226188c0b24e04d15f3181", + "sh": "3316073e62247a9b8fc34f1be8b24047e3e3315749cc52d68eeccae2462f78d1", + "ps1": "722de6e4ab17a6f853100055f522a2fec3a3255c394bc29be1d5fc3b6ed8f120" + }, + "0.1.3": { + "commit": "c0c8ebda74ac78bb70a73ebf4de67865079c9b38", + "sh": "f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1", + "ps1": "c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22" + }, + "0.1.2": { + "commit": "dfb9d4b258b11f6842c7b62f228617d4065f5a83", + "sh": "f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1", + "ps1": "c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22" + }, + "0.1.1": { + "commit": "8c5823fa0d19d7e186115963d1ff7ff58fa30576", + "sh": "f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1", + "ps1": "c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22" + }, + "0.1.1-alpha.0": { + "commit": "bdef013b286275979c9e593fe564c686b3d7130b", + "sh": "f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1", + "ps1": "c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22" + }, + "0.1.0": { + "commit": "cf4df93a8fd7f6b871f98766fb2c6a6578f2d8bc", + "sh": "f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1", + "ps1": "c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22" + }, + "0.1.0-alpha.0": { + "commit": "82f57fbb4d53b99d023d923979f2b2f08ff5e18f", + "sh": "f7e35474150665ea0c812d25e3ecf8643c7584aba6acd2c74f9a1af5b7b935c1", + "ps1": "c8e44334d26d9585efdf89878343628015a3600f7843f6b560d6a705ec9aaf22" + } + } +} diff --git a/src/ci/installer-integrity.test.ts b/src/ci/installer-integrity.test.ts new file mode 100644 index 0000000..cb1efbb --- /dev/null +++ b/src/ci/installer-integrity.test.ts @@ -0,0 +1,112 @@ +import { createHash } from "node:crypto"; +import { spawnSync } from "node:child_process"; +import { chmodSync, existsSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { describe, expect, it } from "vite-plus/test"; +import { getInstallScriptCommand } from "./vp-dirs.js"; + +const sha256 = (content: string) => createHash("sha256").update(content).digest("hex"); +const windows = process.platform === "win32"; +const shells = windows ? ["pwsh", "powershell.exe"] : ["bash"]; + +describe("installer integrity", () => { + it.each(["", "a".repeat(63), "g".repeat(64)])("rejects invalid checksum %j", (checksum) => { + expect(() => + getInstallScriptCommand({ url: "https://example.invalid/install.sh", sha256: checksum }), + ).toThrow("trusted SHA-256"); + }); + + it.each(shells.flatMap((shell) => [false, true].map((detectDirs) => ({ shell, detectDirs }))))( + "never runs tampered downloads ($shell, detectDirs: $detectDirs)", + ({ shell, detectDirs }) => { + const root = mkdtempSync(join(tmpdir(), "setup-vp-integrity-")); + const marker = join(root, "executed"); + const primary = join(root, "primary"); + const legacy = join(root, "legacy"); + const extension = windows ? "ps1" : "sh"; + const content = windows + ? "Set-Content -LiteralPath $env:TEST_MARKER -Value executed\n" + : 'printf executed > "$TEST_MARKER"\n'; + const source = { + url: `https://example.invalid/install.${extension}`, + sha256: sha256(content), + legacy: { + url: `https://example.invalid/install-legacy.${extension}`, + sha256: sha256(content), + }, + }; + const env = { + ...process.env, + PATH: `${root}${windows ? ";" : ":"}${process.env.PATH}`, + HOME: root, + USERPROFILE: root, + TMPDIR: root, + TEMP: root, + TMP: root, + TEST_PRIMARY: primary, + TEST_LEGACY: legacy, + TEST_MARKER: marker, + SETUP_VP_DIRS_FILE: join(root, "dirs"), + }; + if (!windows) { + writeFileSync( + join(root, "curl"), + `#!/bin/bash +if [[ "$6" == *install-legacy* ]]; then + cp "$TEST_LEGACY" "$8" +else + cp "$TEST_PRIMARY" "$8" +fi +`, + ); + chmodSync(join(root, "curl"), 0o755); + } + const command = getInstallScriptCommand(source, process.platform, detectDirs); + const prefix = windows + ? ` +function Invoke-WebRequest { + param([switch]$UseBasicParsing, $TimeoutSec, $Uri, $OutFile) + $fixture = if ($Uri -like '*install-legacy*') { $env:TEST_LEGACY } else { $env:TEST_PRIMARY } + Copy-Item -LiteralPath $fixture -Destination $OutFile +} +` + : ""; + const execute = () => + spawnSync(shell, [...command.args.slice(0, -1), prefix + command.args.at(-1)!], { + env, + encoding: "utf8", + }); + try { + for (const target of [primary, legacy]) { + for (const tampered of ["", `${content}# tampered\n`]) { + writeFileSync(primary, content); + writeFileSync(legacy, content); + writeFileSync(target, tampered); + const result = execute(); + expect(result.status, result.error?.message).not.toBe(0); + expect(result.stderr).toContain("checksum mismatch"); + expect(existsSync(marker)).toBe(false); + expect( + readdirSync(root).filter( + (name) => + name.startsWith("setup-vp-install.") || name.startsWith("setup-vp-install-"), + ), + ).toEqual([]); + } + } + // A matching file must still be executable, proving that failures above + // came from verification rather than a broken shell/download fixture. + if (!detectDirs || !windows) { + writeFileSync(primary, content); + writeFileSync(legacy, content); + const result = execute(); + expect(result.status, result.stderr).toBe(0); + expect(existsSync(marker)).toBe(true); + } + } finally { + rmSync(root, { recursive: true, force: true }); + } + }, + ); +}); diff --git a/src/ci/vp-dirs.test.ts b/src/ci/vp-dirs.test.ts index b547c24..0f14f75 100644 --- a/src/ci/vp-dirs.test.ts +++ b/src/ci/vp-dirs.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from "vite-plus/test"; +import { createHash } from "node:crypto"; import { spawnSync } from "node:child_process"; import { chmodSync, @@ -15,6 +16,11 @@ import { join } from "node:path"; import { isWindows } from "./platform.js"; import { getInstallScriptCommand, parseVitePlusDirs, supportsVitePlusDirs } from "./vp-dirs.js"; +const source = (url: string, content = "") => ({ + url, + sha256: createHash("sha256").update(content).digest("hex"), +}); + describe("Vite+ directory resolution", () => { it("parses the machine-readable VpDirs output", () => { expect( @@ -55,16 +61,16 @@ describe("Vite+ directory resolution", () => { }); it("dumps directories from the installer-resolved Unix shim", () => { - const command = getInstallScriptCommand("https://example.com/install.sh", "linux"); + const command = getInstallScriptCommand(source("https://example.com/install.sh"), "linux"); expect(command.command).toBe("bash"); - expect(command.args[1]).toContain('mktemp "${TMPDIR:-/tmp}/setup-vp-install.XXXXXX"'); - expect(command.args[1]).toContain('-o "$installer_file"'); - expect(command.args[1]).toContain('source "$installer_file"'); - expect(command.args[1]).not.toContain("source /dev/stdin"); - expect(command.args[1]).toContain('"$vp_dir/vp" --version'); - expect(command.args[1]).toContain('VP_DUMP_DIRS=1 "$vp_dir/vp"'); - expect(command.args[1]).toContain('>> "$SETUP_VP_DIRS_FILE"'); + expect(command.args.at(-1)!).toContain('mktemp -d "${TMPDIR:-/tmp}/setup-vp-install.XXXXXX"'); + expect(command.args.at(-1)!).toContain('-o "$download_file"'); + expect(command.args.at(-1)!).toContain('source "$installer_file"'); + expect(command.args.at(-1)!).not.toContain("source /dev/stdin"); + expect(command.args.at(-1)!).toContain('"$vp_dir/vp" --version'); + expect(command.args.at(-1)!).toContain('VP_DUMP_DIRS=1 "$vp_dir/vp"'); + expect(command.args.at(-1)!).toContain('>> "$SETUP_VP_DIRS_FILE"'); }); it.skipIf(isWindows()).each([true, false])( @@ -98,13 +104,13 @@ fi ); chmodSync(join(bin, "curl"), 0o755); chmodSync(join(bin, "vp"), 0o755); - const command = getInstallScriptCommand( - "https://example.com/install.sh", - "linux", - detectDirs, - ); - const runInstaller = () => - spawnSync(command.command, command.args, { + const runInstaller = () => { + const command = getInstallScriptCommand( + source("https://example.com/install.sh", readFileSync(installer, "utf8")), + "linux", + detectDirs, + ); + return spawnSync(command.command, command.args, { encoding: "utf8", env: { ...process.env, @@ -116,6 +122,7 @@ fi SETUP_VP_TEST_CONTINUED: continued, }, }); + }; try { writeFileSync( @@ -152,18 +159,21 @@ printf 'installer completed\\n' ); it("dumps directories from the installer-resolved Windows shim", () => { - const command = getInstallScriptCommand("https://example.com/install.ps1", "win32"); + const command = getInstallScriptCommand(source("https://example.com/install.ps1"), "win32"); expect(command.command).toBe("pwsh"); - expect(command.args[1]).toContain(". ([scriptblock]::Create"); - expect(command.args[1]).toContain("Join-Path $vpDir 'vp.exe'"); - expect(command.args[1]).not.toContain("vp.cmd"); - expect(command.args[1]).toContain("Test-Path -LiteralPath $vpPath -PathType Leaf"); - expect(command.args[1]).toContain("setup-vp requires vp.exe in the installed bin directory"); - expect(command.args[1]).toContain("& $vpPath --version"); - expect(command.args[1]).toContain("$env:VP_DUMP_DIRS = '1'"); - expect(command.args[1]).toContain("Set-Content -LiteralPath $dirsFile -Encoding UTF8"); - expect(command.args[1]).toContain("Add-Content -LiteralPath $dirsFile -Encoding UTF8"); + expect(command.args.slice(0, 3)).toEqual(["-ExecutionPolicy", "Bypass", "-Command"]); + expect(command.args.at(-1)!).toContain(". $installerFile"); + expect(command.args.at(-1)!).toContain("Join-Path $vpDir 'vp.exe'"); + expect(command.args.at(-1)!).not.toContain("vp.cmd"); + expect(command.args.at(-1)!).toContain("Test-Path -LiteralPath $vpPath -PathType Leaf"); + expect(command.args.at(-1)!).toContain( + "setup-vp requires vp.exe in the installed bin directory", + ); + expect(command.args.at(-1)!).toContain("& $vpPath --version"); + expect(command.args.at(-1)!).toContain("$env:VP_DUMP_DIRS = '1'"); + expect(command.args.at(-1)!).toContain("Set-Content -LiteralPath $dirsFile -Encoding UTF8"); + expect(command.args.at(-1)!).toContain("Add-Content -LiteralPath $dirsFile -Encoding UTF8"); }); it.skipIf(isWindows()).each([true, false])( @@ -193,7 +203,7 @@ if [ "$7" = '-' ]; then cat "$SETUP_VP_TEST_INSTALLER"; else cp "$SETUP_VP_TEST_ const marker = join(root, "installed"); writeFileSync(installer, 'printf installed > "$SETUP_VP_TEST_MARKER"\n'); const command = getInstallScriptCommand( - "https://example.invalid/install.sh", + source("https://example.invalid/install.sh", readFileSync(installer, "utf8")), "linux", detectDirs, ); @@ -228,16 +238,20 @@ if [ "$7" = '-' ]; then cat "$SETUP_VP_TEST_INSTALLER"; else cp "$SETUP_VP_TEST_ ); it.each([ - ["linux" as const, "install.sh", "| bash"], - ["win32" as const, "install.ps1", "& ([scriptblock]::Create"], + ["linux" as const, "install.sh", 'bash "$installer_file"'], + ["win32" as const, "install.ps1", "& $installerFile"], ])( "uses the legacy %s installer command when detection is disabled", (platform, name, marker) => { - const command = getInstallScriptCommand(`https://example.com/${name}`, platform, false); + const command = getInstallScriptCommand( + source(`https://example.com/${name}`), + platform, + false, + ); - expect(command.args[1]).toContain(marker); - expect(command.args[1]).not.toContain("VP_DUMP_DIRS"); - expect(command.args[1]).not.toContain("SETUP_VP_DIRS_FILE"); + expect(command.args.at(-1)!).toContain(marker); + expect(command.args.at(-1)!).not.toContain("VP_DUMP_DIRS"); + expect(command.args.at(-1)!).not.toContain("SETUP_VP_DIRS_FILE"); }, ); }); diff --git a/src/ci/vp-dirs.ts b/src/ci/vp-dirs.ts index 8309fcd..a3aea49 100644 --- a/src/ci/vp-dirs.ts +++ b/src/ci/vp-dirs.ts @@ -2,7 +2,7 @@ import { randomUUID } from "node:crypto"; import { readFileSync, rmSync, statSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; -import { pkgPrNewCommitSha } from "./install-script-urls.js"; +import { pkgPrNewCommitSha, type InstallScriptSource } from "./install-script-urls.js"; import { isWindows } from "./platform.js"; import { parseInstalledVpVersion } from "./version.js"; @@ -129,25 +129,28 @@ export function parseVitePlusDirs(output: string): VitePlusDirs | undefined { } export function getInstallScriptCommand( - url: string, + source: InstallScriptSource, platform: NodeJS.Platform = process.platform, detectDirs = true, ): { command: string; args: string[] } { - if (isWindows(platform)) { - if (!detectDirs) { - return { - command: "pwsh", - args: [ - "-Command", - `& ([scriptblock]::Create((irm -TimeoutSec ${PWSH_TIMEOUT_SEC} ${url})))`, - ], - }; + const files = [{ ...source, name: isWindows(platform) ? "install.ps1" : "install.sh" }]; + if (source.legacy) { + files.push({ + ...source.legacy, + name: isWindows(platform) ? "install-legacy.ps1" : "install-legacy.sh", + }); + } + for (const file of files) { + if (!/^[a-f0-9]{64}$/.test(file.sha256)) { + throw new Error("A trusted SHA-256 checksum is required for the Vite+ installer."); } + } - const script = ` + if (isWindows(platform)) { + const probe = ` $dirsFile = $env:${VP_DIRS_FILE_ENV} Set-Content -LiteralPath $dirsFile -Value '' -NoNewline -Encoding UTF8 -. ([scriptblock]::Create((irm -TimeoutSec ${PWSH_TIMEOUT_SEC} ${url}))) +. $installerFile $vpDir = if ($script:ShimDir) { $script:ShimDir } elseif ($InstallDir) { @@ -165,43 +168,78 @@ $env:VP_DUMP_DIRS = '1' & $vpPath | Add-Content -LiteralPath $dirsFile -Encoding UTF8 if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } `.trim(); - return { command: "pwsh", args: ["-Command", script] }; + const script = ` +$ErrorActionPreference = 'Stop' +$installerDir = Join-Path ([System.IO.Path]::GetTempPath()) ('setup-vp-install-' + [guid]::NewGuid().ToString('N')) +$null = New-Item -ItemType Directory -Path $installerDir +$installerFile = Join-Path $installerDir 'install.ps1' +try { + ${files + .map( + ({ url, sha256, name }) => ` + $downloadFile = Join-Path $installerDir '${name}' + Invoke-WebRequest -UseBasicParsing -TimeoutSec ${PWSH_TIMEOUT_SEC} -Uri '${url.replaceAll("'", "''")}' -OutFile $downloadFile + if ((Get-FileHash -LiteralPath $downloadFile -Algorithm SHA256).Hash -ne '${sha256}') { + throw 'setup-vp: installer SHA-256 checksum mismatch; refusing to execute it.' + }`, + ) + .join("\n")} + $global:LASTEXITCODE = 0 + ${detectDirs ? probe : "& $installerFile\nif ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }"} +} finally { + Remove-Item -LiteralPath $installerDir -Recurse -Force +} +`.trim(); + // The verified files replace the old in-memory script blocks. Permit them + // in this child session without changing the runner's persistent policy. + return { command: "pwsh", args: ["-ExecutionPolicy", "Bypass", "-Command", script] }; } + // Use the same Node executable as this runtime so minimal runners do not + // need sha256sum/shasum or a separate node command on PATH. + const verify = `const fs = require("node:fs"); +const crypto = require("node:crypto"); +const actual = crypto.createHash("sha256").update(fs.readFileSync(process.argv[1])).digest("hex"); +if (actual !== process.argv[2]) { + console.error("setup-vp: installer SHA-256 checksum mismatch; refusing to execute it."); + process.exit(1); +}`; + const quote = (value: string): string => `'${value.replaceAll("'", "'\\''")}'`; // Upstream installers read optional positional arguments without defaults. // Do not inherit nounset from a caller that exports SHELLOPTS. - const download = ` + const script = ` +set +u +set -eo pipefail +installer_dir="$(mktemp -d "\${TMPDIR:-/tmp}/setup-vp-install.XXXXXX")" +trap 'rm -rf "$installer_dir"' EXIT +installer_file="$installer_dir/install.sh" +${files + .map( + ({ url, sha256, name }) => ` +download_file="$installer_dir/${name}" if command -v curl >/dev/null 2>&1; then - curl -fsSL ${CURL_TIMEOUT_FLAGS} "${url}"${detectDirs ? ' -o "$installer_file"' : ""} + curl -fsSL ${CURL_TIMEOUT_FLAGS} ${quote(url)} -o "$download_file" elif command -v wget >/dev/null 2>&1; then - wget -q -T 15 -t 1 -O ${detectDirs ? '"$installer_file"' : "-"} "${url}" + wget -q -T 15 -t 1 -O "$download_file" ${quote(url)} else echo "setup-vp: curl or wget is required to download the installer." >&2 exit 127 fi -`.trim(); - if (!detectDirs) { - const script = ` -set +u -set -o pipefail -${download} | bash -`.trim(); - return { command: "bash", args: ["-c", script] }; - } - - const script = ` -set +u -set -eo pipefail -installer_file="$(mktemp "\${TMPDIR:-/tmp}/setup-vp-install.XXXXXX")" -trap 'rm -f "$installer_file"' EXIT -: > "$${VP_DIRS_FILE_ENV}" -${download} +${quote(process.execPath)} -e ${quote(verify)} "$download_file" '${sha256}' +`, + ) + .join("\n")} +${ + detectDirs + ? `: > "$${VP_DIRS_FILE_ENV}" source "$installer_file" vp_dir="\${SHIM_DIR:-\${INSTALL_DIR:-\${VP_HOME:-$HOME/.vite-plus}}/bin}" if [ -x "$vp_dir/vp" ]; then "$vp_dir/vp" --version > "$${VP_DIRS_FILE_ENV}" VP_DUMP_DIRS=1 "$vp_dir/vp" >> "$${VP_DIRS_FILE_ENV}" -fi +fi` + : 'bash "$installer_file"' +} `.trim(); return { command: "bash", args: ["-c", script] }; } diff --git a/src/install-viteplus.test.ts b/src/install-viteplus.test.ts index 3a0b933..ecd77b0 100644 --- a/src/install-viteplus.test.ts +++ b/src/install-viteplus.test.ts @@ -6,10 +6,14 @@ import { tmpdir } from "node:os"; import { delimiter, join } from "node:path"; import { installVitePlus } from "./install-viteplus.js"; import { findReusableVitePlus } from "./reuse-viteplus.js"; +import manifest from "./ci/installer-checksums.json" with { type: "json" }; import type { Inputs } from "./types.js"; const windows = process.platform === "win32"; const installerExtension = windows ? "ps1" : "sh"; +const defaultCommit = + manifest.releases[manifest.defaultVersion as keyof typeof manifest.releases].commit; +const releaseCommit = manifest.releases["0.2.9"].commit; vi.mock("@actions/core", () => ({ info: vi.fn(), @@ -159,8 +163,10 @@ describe("installVitePlus", () => { expect(addPath).toHaveBeenCalledWith(join("/home/runner", ".vite-plus", "bin")); const [_command, args, options] = vi.mocked(exec).mock.calls[0]; - expect((args as string[])[1]).toContain(windows ? "[scriptblock]::Create" : "| bash"); - expect((args as string[])[1]).not.toContain("VP_DUMP_DIRS"); + expect((args as string[]).at(-1)!).toContain( + windows ? "& $installerFile" : 'bash "$installer_file"', + ); + expect((args as string[]).at(-1)!).not.toContain("VP_DUMP_DIRS"); expect((options as { env: Record }).env.VP_VPDIRS_AWARE).toBeUndefined(); expect((options as { env: Record }).env.SETUP_VP_DIRS_FILE).toBeUndefined(); }); @@ -229,7 +235,7 @@ describe("installVitePlus", () => { expect(warning).toHaveBeenCalledTimes(1); }); - it("should fall back to the GitHub install URL after a single primary failure", async () => { + it("should fall back to the checksum-pinned mirror after a single primary failure", async () => { vi.mocked(exec).mockResolvedValueOnce(35); mockSuccessfulInstallOnce(); @@ -237,12 +243,14 @@ describe("installVitePlus", () => { expect(exec).toHaveBeenCalledTimes(2); - const primaryScript = (vi.mocked(exec).mock.calls[0][1] as string[])[1]; - expect(primaryScript).toContain(`https://viteplus.dev/install.${installerExtension}`); + const primaryScript = (vi.mocked(exec).mock.calls[0][1] as string[]).at(-1)!; + expect(primaryScript).toContain( + `https://raw.githubusercontent.com/voidzero-dev/vite-plus/${defaultCommit}/packages/cli/install.${installerExtension}`, + ); - const fallbackScript = (vi.mocked(exec).mock.calls[1][1] as string[])[1]; + const fallbackScript = (vi.mocked(exec).mock.calls[1][1] as string[]).at(-1)!; expect(fallbackScript).toContain( - `https://raw.githubusercontent.com/voidzero-dev/vite-plus/main/packages/cli/install.${installerExtension}`, + `https://cdn.jsdelivr.net/gh/voidzero-dev/vite-plus@${defaultCommit}/packages/cli/install.${installerExtension}`, ); }); @@ -251,32 +259,29 @@ describe("installVitePlus", () => { await expect(installVitePlus(baseInputs)).rejects.toThrow(); - const scripts = vi.mocked(exec).mock.calls.map((call) => (call[1] as string[])[1]); + const scripts = vi.mocked(exec).mock.calls.map((call) => (call[1] as string[]).at(-1)!); expect(scripts).toHaveLength(4); - expect(scripts[0]).toContain(`viteplus.dev/install.${installerExtension}`); - expect(scripts[1]).toContain("raw.githubusercontent.com"); - expect(scripts[2]).toContain(`viteplus.dev/install.${installerExtension}`); - expect(scripts[3]).toContain("raw.githubusercontent.com"); + expect(scripts[0]).toContain(`/${defaultCommit}/packages/cli/install.${installerExtension}`); + expect(scripts[1]).toContain("cdn.jsdelivr.net"); + expect(scripts[2]).toContain(`/${defaultCommit}/packages/cli/install.${installerExtension}`); + expect(scripts[3]).toContain("cdn.jsdelivr.net"); }); // ci/install-script-urls.test.ts tests the exact URL strings. These tests // verify that the version reaches the URL selection. it.each([ - { desc: "exact versions", version: "0.2.9", ref: "v0.2.9" }, - { desc: "pkg.pr.new commit builds", version: `0.0.0-commit.${commitSha}`, ref: commitSha }, - ])( - "should install $desc with the install script from their git ref", - async ({ version, ref }) => { - mockSuccessfulInstallOnce(); + { desc: "exact versions", version: "0.2.9", ref: releaseCommit }, + { desc: "pkg.pr.new commit builds", version: `0.0.0-commit.${commitSha}`, ref: defaultCommit }, + ])("should install $desc with a checksum-pinned install script", async ({ version, ref }) => { + mockSuccessfulInstallOnce(); - await installVitePlus({ ...baseInputs, version }); + await installVitePlus({ ...baseInputs, version }); - const script = (vi.mocked(exec).mock.calls[0][1] as string[])[1]; - expect(script).toContain( - `https://raw.githubusercontent.com/voidzero-dev/vite-plus/${ref}/packages/cli/install.${installerExtension}`, - ); - }, - ); + const script = (vi.mocked(exec).mock.calls[0][1] as string[]).at(-1)!; + expect(script).toContain( + `https://raw.githubusercontent.com/voidzero-dev/vite-plus/${ref}/packages/cli/install.${installerExtension}`, + ); + }); it("should fall back to the jsDelivr mirror of the pinned script on failure", async () => { vi.mocked(exec).mockResolvedValueOnce(35); @@ -284,17 +289,19 @@ describe("installVitePlus", () => { await installVitePlus({ ...baseInputs, version: "0.2.9" }); - const fallbackScript = (vi.mocked(exec).mock.calls[1][1] as string[])[1]; + const fallbackScript = (vi.mocked(exec).mock.calls[1][1] as string[]).at(-1)!; expect(fallbackScript).toContain( - `https://cdn.jsdelivr.net/gh/voidzero-dev/vite-plus@v0.2.9/packages/cli/install.${installerExtension}`, + `https://cdn.jsdelivr.net/gh/voidzero-dev/vite-plus@${releaseCommit}/packages/cli/install.${installerExtension}`, ); - // If both pinned attempts fail, the code warns before it uses the latest + // If both pinned attempts fail, the code warns before it uses the default // URLs. Success on the mirror must not trigger the compatibility fallback. - expect(warning).not.toHaveBeenCalledWith(expect.stringContaining("latest install script")); + expect(warning).not.toHaveBeenCalledWith( + expect.stringContaining("checksum-pinned default install script"), + ); }); - it("should fall back to the latest install script only after exhausting pinned URLs", async () => { - // 4 pinned attempts fail (2 rounds × 2 URLs), the 5th (latest CDN) succeeds. + it("should fall back to the checksum-pinned default install script only after exhausting pinned URLs", async () => { + // 4 pinned attempts fail (2 rounds × 2 URLs), the 5th (default primary) succeeds. vi.mocked(exec) .mockResolvedValueOnce(22) .mockResolvedValueOnce(22) @@ -304,24 +311,26 @@ describe("installVitePlus", () => { await installVitePlus({ ...baseInputs, version: "0.2.9" }); - const scripts = vi.mocked(exec).mock.calls.map((call) => (call[1] as string[])[1]); - expect(scripts[0]).toContain("/v0.2.9/"); + const scripts = vi.mocked(exec).mock.calls.map((call) => (call[1] as string[]).at(-1)!); + expect(scripts[0]).toContain(`/${releaseCommit}/`); expect(scripts[1]).toContain("jsdelivr"); - expect(scripts[2]).toContain("/v0.2.9/"); + expect(scripts[2]).toContain(`/${releaseCommit}/`); expect(scripts[3]).toContain("jsdelivr"); - expect(scripts[4]).toContain(`https://viteplus.dev/install.${installerExtension}`); + expect(scripts[4]).toContain( + `https://raw.githubusercontent.com/voidzero-dev/vite-plus/${defaultCommit}/packages/cli/install.${installerExtension}`, + ); expect(warning).toHaveBeenCalledWith( - expect.stringContaining("The latest script may not be compatible with 0.2.9"), + expect.stringContaining("The default script may not be compatible with 0.2.9"), ); }); - it("should count pinned and latest URLs in the exhaustion error for exact versions", async () => { + it("should count pinned and default URLs in the exhaustion error for exact versions", async () => { vi.mocked(exec).mockResolvedValue(6); await expect(installVitePlus({ ...baseInputs, version: "0.2.9" })).rejects.toThrow( /after 8 attempts across 4 URL\(s\)/, ); - // 2 rounds × 2 pinned URLs + 2 rounds × 2 latest URLs. + // 2 rounds × 2 pinned URLs + 2 rounds × 2 default URLs. expect(exec).toHaveBeenCalledTimes(8); }); @@ -332,9 +341,9 @@ describe("installVitePlus", () => { const [cmd, args] = vi.mocked(exec).mock.calls[0]; expect(cmd).toBe(windows ? "pwsh" : "bash"); - const script = (args as string[])[1]; + const script = (args as string[]).at(-1)!; if (windows) { - expect(script).toContain(". ([scriptblock]::Create((irm -TimeoutSec"); + expect(script).toContain(". $installerFile"); expect(script).toContain("Join-Path $vpDir 'vp.exe'"); expect(script).toContain("& $vpPath --version"); expect(script).toContain("$env:VP_DUMP_DIRS = '1'"); @@ -344,7 +353,7 @@ describe("installVitePlus", () => { expect(script).toMatch(/^set \+u\nset -eo pipefail\n/); expect(script).toContain("--connect-timeout"); expect(script).toContain("--max-time"); - expect(script).toContain('-o "$installer_file"'); + expect(script).toContain('-o "$download_file"'); expect(script).toContain('source "$installer_file"'); expect(script).not.toContain("source /dev/stdin"); expect(script).toContain('"$vp_dir/vp" --version'); diff --git a/src/install-viteplus.ts b/src/install-viteplus.ts index fcdd4e5..db4dfaa 100644 --- a/src/install-viteplus.ts +++ b/src/install-viteplus.ts @@ -2,7 +2,11 @@ import { info, warning, addPath, exportVariable } from "@actions/core"; import { exec } from "@actions/exec"; import { delimiter, join } from "node:path"; import { setTimeout as sleep } from "node:timers/promises"; -import { getInstallScriptUrls, pkgPrNewCommitSha } from "./ci/install-script-urls.js"; +import { + getInstallScriptSources, + pkgPrNewCommitSha, + type InstallScriptSource, +} from "./ci/install-script-urls.js"; import { appendFallbackBinToPath, createVitePlusDirsFile, @@ -63,21 +67,22 @@ export async function installVitePlus(inputs: Inputs): Promise { env.VP_PR_VERSION = prVersion; } - // Prefer the install script pinned to the requested version's git ref. Fall - // back to the latest script only after all pinned sources fail (see + // Prefer the bundled pin for the requested version. Try the default pin + // only after all version-specific sources fail (see // ci/install-script-urls.ts for the rationale). - const { pinned, latest } = getInstallScriptUrls(version); - const totalUrls = pinned.length + latest.length; + const { pinned, fallback } = getInstallScriptSources(version); + const totalUrls = pinned.length + fallback.length; const maxAttempts = INSTALL_MAX_ROUNDS * totalUrls; let failureReason = ""; let attempt = 0; - const tryUrls = async (urls: string[]): Promise => { + const tryUrls = async (urls: InstallScriptSource[]): Promise => { for (let round = 0; round < INSTALL_MAX_ROUNDS; round++) { - for (const url of urls) { + for (const source of urls) { + const { url } = source; attempt++; try { - const exitCode = await runInstallCommand(url, env); + const exitCode = await runInstallCommand(source, env); if (exitCode === 0) return true; failureReason = `exit code ${exitCode}`; } catch (error) { @@ -102,11 +107,11 @@ export async function installVitePlus(inputs: Inputs): Promise { return; } warning( - `Could not fetch the install script pinned to ${DISPLAY_NAME}@${version}. Falling back to the latest install script. The latest script may not be compatible with ${version}.`, + `Could not fetch the install script pinned to ${DISPLAY_NAME}@${version}. Falling back to the checksum-pinned default install script. The default script may not be compatible with ${version}.`, ); } - if (await tryUrls(latest)) { + if (await tryUrls(fallback)) { ensureVitePlusBinInPath(version, dirsFile); return; } @@ -119,10 +124,13 @@ export async function installVitePlus(inputs: Inputs): Promise { } } -async function runInstallCommand(url: string, env: { [key: string]: string }): Promise { +async function runInstallCommand( + source: InstallScriptSource, + env: { [key: string]: string }, +): Promise { const options = { env, ignoreReturnCode: true }; const { command, args } = getInstallScriptCommand( - url, + source, process.platform, env.VP_VPDIRS_AWARE === "1", ); From ba31e2e92db94128365b911b88b5918b2fe46254 Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 8 Oct 2026 14:07:35 +0800 Subject: [PATCH 2/2] fix: preserve Windows installer failures before probing --- dist/azure/index.mjs | 1 + dist/gitlab/index.mjs | 1 + dist/index.mjs | 1 + src/ci/installer-integrity.test.ts | 97 ++++++++++++++++++++++++++++-- src/ci/vp-dirs.ts | 1 + 5 files changed, 96 insertions(+), 5 deletions(-) diff --git a/dist/azure/index.mjs b/dist/azure/index.mjs index a99f81b..302fd3b 100644 --- a/dist/azure/index.mjs +++ b/dist/azure/index.mjs @@ -147,6 +147,7 @@ n?this.stack.push(n):(yield*this.pop(),yield*this.step())}else{let t=this.peek(2 $dirsFile = $env:${$} Set-Content -LiteralPath $dirsFile -Value '' -NoNewline -Encoding UTF8 . $installerFile +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } $vpDir = if ($script:ShimDir) { $script:ShimDir } elseif ($InstallDir) { diff --git a/dist/gitlab/index.mjs b/dist/gitlab/index.mjs index 48e46bf..2a0cc39 100644 --- a/dist/gitlab/index.mjs +++ b/dist/gitlab/index.mjs @@ -142,6 +142,7 @@ n?this.stack.push(n):(yield*this.pop(),yield*this.step())}else{let t=this.peek(2 $dirsFile = $env:${Q} Set-Content -LiteralPath $dirsFile -Value '' -NoNewline -Encoding UTF8 . $installerFile +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } $vpDir = if ($script:ShimDir) { $script:ShimDir } elseif ($InstallDir) { diff --git a/dist/index.mjs b/dist/index.mjs index 7a410bd..816d951 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -193,6 +193,7 @@ function optional(e){return new ia({type:`optional`,innerType:e})}const aa=`Vite $dirsFile = $env:${ma} Set-Content -LiteralPath $dirsFile -Value '' -NoNewline -Encoding UTF8 . $installerFile +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } $vpDir = if ($script:ShimDir) { $script:ShimDir } elseif ($InstallDir) { diff --git a/src/ci/installer-integrity.test.ts b/src/ci/installer-integrity.test.ts index cb1efbb..4d1188d 100644 --- a/src/ci/installer-integrity.test.ts +++ b/src/ci/installer-integrity.test.ts @@ -1,15 +1,35 @@ import { createHash } from "node:crypto"; import { spawnSync } from "node:child_process"; -import { chmodSync, existsSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from "node:fs"; +import { + chmodSync, + copyFileSync, + existsSync, + mkdirSync, + mkdtempSync, + readFileSync, + readdirSync, + rmSync, + writeFileSync, +} from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { describe, expect, it } from "vite-plus/test"; -import { getInstallScriptCommand } from "./vp-dirs.js"; +import { getInstallScriptCommand, parseVitePlusDirs } from "./vp-dirs.js"; const sha256 = (content: string) => createHash("sha256").update(content).digest("hex"); const windows = process.platform === "win32"; const shells = windows ? ["pwsh", "powershell.exe"] : ["bash"]; +function installerTestEnv(shell: string, overrides: NodeJS.ProcessEnv): NodeJS.ProcessEnv { + // Node inherits PowerShell 7's module paths from the CI shell. Let Desktop + // construct its own paths so built-in cmdlets such as Get-FileHash load. + return Object.fromEntries( + Object.entries({ ...process.env, ...overrides }).filter( + ([key]) => shell !== "powershell.exe" || key.toLowerCase() !== "psmodulepath", + ), + ); +} + describe("installer integrity", () => { it.each(["", "a".repeat(63), "g".repeat(64)])("rejects invalid checksum %j", (checksum) => { expect(() => @@ -36,8 +56,7 @@ describe("installer integrity", () => { sha256: sha256(content), }, }; - const env = { - ...process.env, + const env = installerTestEnv(shell, { PATH: `${root}${windows ? ";" : ":"}${process.env.PATH}`, HOME: root, USERPROFILE: root, @@ -48,7 +67,7 @@ describe("installer integrity", () => { TEST_LEGACY: legacy, TEST_MARKER: marker, SETUP_VP_DIRS_FILE: join(root, "dirs"), - }; + }); if (!windows) { writeFileSync( join(root, "curl"), @@ -109,4 +128,72 @@ function Invoke-WebRequest { } }, ); + + it.skipIf(!windows).each(["pwsh", "powershell.exe"])( + "preserves installer failures before probing an existing executable (%s)", + (shell) => { + const root = mkdtempSync(join(tmpdir(), "setup-vp-installer-exit-")); + const bin = join(root, "existing bin"); + const primary = join(root, "installer.ps1"); + const marker = join(root, "probed"); + const dirsFile = join(root, "dirs"); + const probe = join(root, "probe.cjs"); + try { + mkdirSync(bin); + // A native executable with a successful --version response must not + // hide the installer's failure. Its no-argument probe records usage. + copyFileSync(process.execPath, join(bin, "vp.exe")); + writeFileSync( + probe, + `const fs = require("node:fs"); +fs.writeFileSync(process.env.TEST_MARKER, "probed"); +for (const key of ["data", "bin", "cache", "config", "state"]) { + console.log(key + "\\t" + process.env.TEST_EXISTING_BIN); +} +process.exit(0); +`, + ); + const env = installerTestEnv(shell, { + TEST_PRIMARY: primary, + TEST_MARKER: marker, + TEST_EXISTING_BIN: bin, + SETUP_VP_DIRS_FILE: dirsFile, + NODE_OPTIONS: `--require="${probe.replaceAll("\\", "/")}"`, + // Also exercise case-insensitive removal in the Desktop harness. + PSMODULEPATH: join(root, "wrong-edition-modules"), + }); + function execute(exitCode: number) { + const content = `$script:ShimDir = $env:TEST_EXISTING_BIN\nexit ${exitCode}\n`; + writeFileSync(primary, content); + const command = getInstallScriptCommand( + { url: "https://example.invalid/install.ps1", sha256: sha256(content) }, + "win32", + ); + const download = ` +function Invoke-WebRequest { + param([switch]$UseBasicParsing, $TimeoutSec, $Uri, $OutFile) + Copy-Item -LiteralPath $env:TEST_PRIMARY -Destination $OutFile +} +`; + return spawnSync(shell, [...command.args.slice(0, -1), download + command.args.at(-1)!], { + env, + encoding: "utf8", + }); + } + + const failure = execute(23); + expect(failure.status, failure.stderr).toBe(23); + expect(existsSync(marker)).toBe(false); + expect(readFileSync(dirsFile, "utf8").trim()).toBe(""); + + // Prove that the existing executable and its directory probe work. + const success = execute(0); + expect(success.status, success.stderr).toBe(0); + expect(readFileSync(marker, "utf8")).toBe("probed"); + expect(parseVitePlusDirs(readFileSync(dirsFile, "utf8"))?.bin).toBe(bin); + } finally { + rmSync(root, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 }); + } + }, + ); }); diff --git a/src/ci/vp-dirs.ts b/src/ci/vp-dirs.ts index a3aea49..c3fcf35 100644 --- a/src/ci/vp-dirs.ts +++ b/src/ci/vp-dirs.ts @@ -151,6 +151,7 @@ export function getInstallScriptCommand( $dirsFile = $env:${VP_DIRS_FILE_ENV} Set-Content -LiteralPath $dirsFile -Value '' -NoNewline -Encoding UTF8 . $installerFile +if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } $vpDir = if ($script:ShimDir) { $script:ShimDir } elseif ($InstallDir) {