From 4d572b097826e6d0edb26009f873ba06149e5376 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 28 Jun 2026 17:27:42 +0000 Subject: [PATCH 1/9] fix: support ESM app entrypoints in the universal shim When the x64 and arm64 app.asar (or app dir) contents diverge, the generated entry shim used `require()` to load the per-arch archive. If the inner app's entrypoint is an ES module this throws ERR_REQUIRE_ESM at launch. Detect each arch's entrypoint module format from its package.json and, only when both arches agree on ESM, ship an ESM shim that uses dynamic import. If the two arches disagree on module system, fail the build with a clear error instead of producing a broken bundle. - Add detectEntrypointModule / resolveShimModule to asar-utils - Add ESM shim sources entry-asar/esm/{has,no}-asar.mts compiled to .mjs - Wire both the HAS_ASAR and NO_ASAR shim sites in makeUniversalApp - Add unit tests for the detection logic and ESM integration tests Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01EPgSb3xj4vdi1mUNSzpVUD --- .gitignore | 1 + entry-asar/esm/has-asar.mts | 30 ++++++++++++ entry-asar/esm/no-asar.mts | 30 ++++++++++++ entry-asar/esm/tsconfig.json | 19 ++++++++ package.json | 5 +- src/asar-utils.ts | 39 ++++++++++++++++ src/index.ts | 72 +++++++++++++++++++++++----- test/detect-entrypoint.spec.ts | 85 ++++++++++++++++++++++++++++++++++ test/globalSetup.ts | 58 +++++++++++++++++++++++ test/index.spec.ts | 28 +++++++++++ tsconfig.entry-asar.json | 4 +- 11 files changed, 357 insertions(+), 14 deletions(-) create mode 100644 entry-asar/esm/has-asar.mts create mode 100644 entry-asar/esm/no-asar.mts create mode 100644 entry-asar/esm/tsconfig.json create mode 100644 test/detect-entrypoint.spec.ts diff --git a/.gitignore b/.gitignore index d0ed1a2..738e767 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ node_modules dist entry-asar/*.js* entry-asar/*.ts +entry-asar/esm/*.mjs* *.app test/fixtures/apps coverage diff --git a/entry-asar/esm/has-asar.mts b/entry-asar/esm/has-asar.mts new file mode 100644 index 0000000..956f554 --- /dev/null +++ b/entry-asar/esm/has-asar.mts @@ -0,0 +1,30 @@ +import { app } from 'electron'; +import { createRequire } from 'node:module'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; + +const require = createRequire(import.meta.url); + +if (process.arch === 'arm64') { + await setPaths('arm64'); +} else { + await setPaths('x64'); +} + +async function setPaths(platform: string) { + // This should return the full path, ending in something like + // Notion.app/Contents/Resources/app.asar + const appPath = app.getAppPath(); + const asarFile = `app-${platform}.asar`; + + // Maybe we'll handle this in Electron one day + if (path.basename(appPath) === 'app.asar') { + const platformAppPath = path.join(path.dirname(appPath), asarFile); + + // This is an undocumented API. It exists. + app.setAppPath(platformAppPath); + } + + process._archPath = require.resolve(`../${asarFile}`); + await import(pathToFileURL(process._archPath).href); +} diff --git a/entry-asar/esm/no-asar.mts b/entry-asar/esm/no-asar.mts new file mode 100644 index 0000000..66a0bac --- /dev/null +++ b/entry-asar/esm/no-asar.mts @@ -0,0 +1,30 @@ +import { app } from 'electron'; +import { createRequire } from 'node:module'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; + +const require = createRequire(import.meta.url); + +if (process.arch === 'arm64') { + await setPaths('arm64'); +} else { + await setPaths('x64'); +} + +async function setPaths(platform: string) { + // This should return the full path, ending in something like + // Notion.app/Contents/Resources/app + const appPath = app.getAppPath(); + const appFolder = `app-${platform}`; + + // Maybe we'll handle this in Electron one day + if (path.basename(appPath) === 'app') { + const platformAppPath = path.join(path.dirname(appPath), appFolder); + + // This is an undocumented private API. It exists. + app.setAppPath(platformAppPath); + } + + process._archPath = require.resolve(`../${appFolder}`); + await import(pathToFileURL(process._archPath).href); +} diff --git a/entry-asar/esm/tsconfig.json b/entry-asar/esm/tsconfig.json new file mode 100644 index 0000000..5dc7d68 --- /dev/null +++ b/entry-asar/esm/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "module": "nodenext", + "moduleResolution": "nodenext", + "target": "es2022", + "lib": ["es2022"], + "sourceMap": true, + "strict": true, + "rootDir": ".", + "outDir": ".", + "types": ["node"], + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "declaration": false, + "ignoreDeprecations": "6.0" + }, + "include": ["*.mts", "../ambient.d.ts"], + "exclude": [] +} diff --git a/package.json b/package.json index 991a421..ad901fc 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,10 @@ "files": [ "dist/*", "entry-asar/*", + "entry-asar/esm/*", "!entry-asar/**/*.ts", + "!entry-asar/**/*.mts", + "!entry-asar/**/tsconfig.json", "README.md" ], "author": "Samuel Attard", @@ -28,7 +31,7 @@ "provenance": true }, "scripts": { - "build": "tsc -p tsconfig.json && tsc -p tsconfig.entry-asar.json", + "build": "tsc -p tsconfig.json && tsc -p tsconfig.entry-asar.json && tsc -p entry-asar/esm/tsconfig.json", "build:docs": "typedoc", "lint": "oxfmt --check . && oxlint", "lint:fix": "oxfmt --write . && oxlint --fix", diff --git a/src/asar-utils.ts b/src/asar-utils.ts index bbdcc14..0c0bc43 100644 --- a/src/asar-utils.ts +++ b/src/asar-utils.ts @@ -15,6 +15,11 @@ export enum AsarMode { HAS_ASAR, } +export enum EntrypointModule { + ESM = 'esm', + CJS = 'cjs', +} + export type MergeASARsOptions = { x64AsarPath: string; arm64AsarPath: string; @@ -36,6 +41,40 @@ export const detectAsarMode = async (appPath: string) => { return AsarMode.HAS_ASAR; }; +/** + * Determine an app entrypoint's module format from its package.json using + * Node's own resolution rules. Anything we cannot positively identify as ESM + * is treated as CJS, so we never ship an ESM shim on a guess. + */ +export const detectEntrypointModule = (packageJson: unknown): EntrypointModule => { + if (typeof packageJson !== 'object' || packageJson === null) { + return EntrypointModule.CJS; + } + const pj = packageJson as { main?: unknown; type?: unknown }; + const main = typeof pj.main === 'string' && pj.main.length > 0 ? pj.main : 'index.js'; + if (main.endsWith('.mjs')) return EntrypointModule.ESM; + if (main.endsWith('.cjs')) return EntrypointModule.CJS; + // .js / .json / .node / extensionless -> governed by the package "type" field + return pj.type === 'module' ? EntrypointModule.ESM : EntrypointModule.CJS; +}; + +/** + * Given the detected module format of each architecture's entrypoint, decide + * which shim to ship. Refuses to build a universal app when the two + * architectures disagree, since a single shim cannot satisfy both. + */ +export const resolveShimModule = ( + x64: EntrypointModule, + arm64: EntrypointModule, +): EntrypointModule => { + if (x64 !== arm64) { + throw new Error( + `Can't create universal binary: the x64 app entrypoint is ${x64.toUpperCase()} but the arm64 app entrypoint is ${arm64.toUpperCase()}. Both architectures must use the same module system (CommonJS or ESM).`, + ); + } + return x64; +}; + export const generateAsarIntegrity = (asarPath: string) => { return { algorithm: 'SHA256' as const, diff --git a/src/index.ts b/src/index.ts index 1fb179c..8ee8329 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,7 +7,15 @@ import { promisify } from 'node:util'; import * as asar from '@electron/asar'; import plist from 'plist'; -import { AsarMode, detectAsarMode, isUniversalMachO, mergeASARs } from './asar-utils.js'; +import { + AsarMode, + detectAsarMode, + detectEntrypointModule, + EntrypointModule, + isUniversalMachO, + mergeASARs, + resolveShimModule, +} from './asar-utils.js'; import { AppFile, AppFileType, @@ -270,17 +278,37 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise = const entryAsar = path.resolve(tmpDir, 'entry-asar'); await fs.promises.mkdir(entryAsar, { recursive: true }); - await fs.promises.cp( - path.resolve(import.meta.dirname, '..', 'entry-asar', 'no-asar.js'), - path.resolve(entryAsar, 'index.js'), - ); + let pj = JSON.parse( await fs.promises.readFile( path.resolve(opts.x64AppPath, 'Contents', 'Resources', 'app', 'package.json'), 'utf8', ), ); - pj.main = 'index.js'; + const arm64Pj = JSON.parse( + await fs.promises.readFile( + path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app', 'package.json'), + 'utf8', + ), + ); + const shimModule = resolveShimModule( + detectEntrypointModule(pj), + detectEntrypointModule(arm64Pj), + ); + + if (shimModule === EntrypointModule.ESM) { + await fs.promises.cp( + path.resolve(import.meta.dirname, '..', 'entry-asar', 'esm', 'no-asar.mjs'), + path.resolve(entryAsar, 'index.mjs'), + ); + pj.main = 'index.mjs'; + } else { + await fs.promises.cp( + path.resolve(import.meta.dirname, '..', 'entry-asar', 'no-asar.js'), + path.resolve(entryAsar, 'index.js'), + ); + pj.main = 'index.js'; + } await fs.promises.writeFile( path.resolve(entryAsar, 'package.json'), JSON.stringify(pj) + '\n', @@ -353,10 +381,7 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise = const entryAsar = path.resolve(tmpDir, 'entry-asar'); await fs.promises.mkdir(entryAsar, { recursive: true }); - await fs.promises.cp( - path.resolve(import.meta.dirname, '..', 'entry-asar', 'has-asar.js'), - path.resolve(entryAsar, 'index.js'), - ); + let pj = JSON.parse( ( await asar.extractFile( @@ -365,7 +390,32 @@ export const makeUniversalApp = async (opts: MakeUniversalOpts): Promise = ) ).toString('utf8'), ); - pj.main = 'index.js'; + const arm64Pj = JSON.parse( + asar + .extractFile( + path.resolve(opts.arm64AppPath, 'Contents', 'Resources', 'app.asar'), + 'package.json', + ) + .toString('utf8'), + ); + const shimModule = resolveShimModule( + detectEntrypointModule(pj), + detectEntrypointModule(arm64Pj), + ); + + if (shimModule === EntrypointModule.ESM) { + await fs.promises.cp( + path.resolve(import.meta.dirname, '..', 'entry-asar', 'esm', 'has-asar.mjs'), + path.resolve(entryAsar, 'index.mjs'), + ); + pj.main = 'index.mjs'; + } else { + await fs.promises.cp( + path.resolve(import.meta.dirname, '..', 'entry-asar', 'has-asar.js'), + path.resolve(entryAsar, 'index.js'), + ); + pj.main = 'index.js'; + } await fs.promises.writeFile( path.resolve(entryAsar, 'package.json'), JSON.stringify(pj) + '\n', diff --git a/test/detect-entrypoint.spec.ts b/test/detect-entrypoint.spec.ts new file mode 100644 index 0000000..06eac9b --- /dev/null +++ b/test/detect-entrypoint.spec.ts @@ -0,0 +1,85 @@ +import { describe, expect, it } from 'vitest'; + +import { detectEntrypointModule, EntrypointModule, resolveShimModule } from '../dist/asar-utils.js'; + +describe('detectEntrypointModule', () => { + it('detects ESM when main has a .mjs extension', () => { + expect(detectEntrypointModule({ main: 'index.mjs' })).toBe(EntrypointModule.ESM); + }); + + it('detects ESM for a nested .mjs main', () => { + expect(detectEntrypointModule({ main: 'src/app.mjs' })).toBe(EntrypointModule.ESM); + }); + + it('detects CJS when main has a .cjs extension', () => { + expect(detectEntrypointModule({ main: 'index.cjs' })).toBe(EntrypointModule.CJS); + }); + + it('lets the .cjs extension win over a "module" type', () => { + expect(detectEntrypointModule({ main: 'index.cjs', type: 'module' })).toBe( + EntrypointModule.CJS, + ); + }); + + it('lets the .mjs extension win over a "commonjs" type', () => { + expect(detectEntrypointModule({ main: 'index.mjs', type: 'commonjs' })).toBe( + EntrypointModule.ESM, + ); + }); + + it('detects ESM for a .js main when type is "module"', () => { + expect(detectEntrypointModule({ main: 'index.js', type: 'module' })).toBe(EntrypointModule.ESM); + }); + + it('detects CJS for a .js main when type is "commonjs"', () => { + expect(detectEntrypointModule({ main: 'index.js', type: 'commonjs' })).toBe( + EntrypointModule.CJS, + ); + }); + + it('defaults a .js main with no type to CJS', () => { + expect(detectEntrypointModule({ main: 'index.js' })).toBe(EntrypointModule.CJS); + }); + + it('detects ESM when type is "module" and there is no main', () => { + expect(detectEntrypointModule({ type: 'module' })).toBe(EntrypointModule.ESM); + }); + + it('defaults an empty package.json to CJS', () => { + expect(detectEntrypointModule({})).toBe(EntrypointModule.CJS); + }); + + it('treats null as CJS', () => { + expect(detectEntrypointModule(null)).toBe(EntrypointModule.CJS); + }); + + it('treats a non-object as CJS', () => { + expect(detectEntrypointModule(42)).toBe(EntrypointModule.CJS); + }); +}); + +describe('resolveShimModule', () => { + it('returns CJS when both arches are CJS', () => { + expect(resolveShimModule(EntrypointModule.CJS, EntrypointModule.CJS)).toBe( + EntrypointModule.CJS, + ); + }); + + it('returns ESM when both arches are ESM', () => { + expect(resolveShimModule(EntrypointModule.ESM, EntrypointModule.ESM)).toBe( + EntrypointModule.ESM, + ); + }); + + it('throws when x64 is ESM but arm64 is CJS', () => { + expect(() => resolveShimModule(EntrypointModule.ESM, EntrypointModule.CJS)).toThrow( + /ESM[\s\S]*CJS/, + ); + }); + + it('throws when x64 is CJS but arm64 is ESM', () => { + expect(() => resolveShimModule(EntrypointModule.CJS, EntrypointModule.ESM)).toThrow( + /CJS[\s\S]*ESM/, + ); + }); +}); diff --git a/test/globalSetup.ts b/test/globalSetup.ts index baf0693..28b38bf 100644 --- a/test/globalSetup.ts +++ b/test/globalSetup.ts @@ -1,9 +1,29 @@ import { execFileSync } from 'node:child_process'; import fs from 'node:fs'; +import os from 'node:os'; import path from 'node:path'; +import { createPackage } from '@electron/asar'; + import { appsDir, asarsDir, downloadElectronZip, fixtureDir, templateApp } from './util.js'; +// Build an app source directory whose entrypoint is an ES module. The `suffix` +// lets two arches diverge so that `makeUniversalApp` is forced to create a shim. +const createEsmAppDir = async (name: string, suffix: string) => { + const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), `${name}-`)); + await fs.promises.writeFile( + path.join(dir, 'package.json'), + JSON.stringify({ name: 'app', type: 'module', main: 'index.mjs' }) + '\n', + 'utf8', + ); + await fs.promises.writeFile( + path.join(dir, 'index.mjs'), + `console.log('I am an ESM app${suffix}', process.arch);\nprocess.exit(0);\n`, + 'utf8', + ); + return dir; +}; + // generates binaries from hello-world.c // hello-world-universal, hello-world-x86_64, hello-world-arm64 const generateMachO = () => { @@ -87,4 +107,42 @@ export default async () => { ); }), ]); + + // ESM entrypoint fixtures (regression coverage for ERR_REQUIRE_ESM when the + // x64/arm64 asars diverge). The two arches differ so a shim is generated. + const x64EsmAsarDir = await createEsmAppDir('X64AsarEsm', ''); + const arm64EsmAsarDir = await createEsmAppDir('Arm64AsarEsmExtraFile', ' (extra)'); + const x64EsmNoAsarDir = await createEsmAppDir('X64NoAsarEsm', ''); + const arm64EsmNoAsarDir = await createEsmAppDir('Arm64NoAsarEsmExtraFile', ' (extra)'); + + await Promise.all([ + templateApp('X64AsarEsm.app', 'x64', async (appPath) => { + await createPackage( + x64EsmAsarDir, + path.resolve(appPath, 'Contents', 'Resources', 'app.asar'), + ); + }), + + templateApp('Arm64AsarEsmExtraFile.app', 'arm64', async (appPath) => { + await createPackage( + arm64EsmAsarDir, + path.resolve(appPath, 'Contents', 'Resources', 'app.asar'), + ); + }), + + templateApp('X64NoAsarEsm.app', 'x64', async (appPath) => { + await fs.promises.cp(x64EsmNoAsarDir, path.resolve(appPath, 'Contents', 'Resources', 'app'), { + recursive: true, + verbatimSymlinks: true, + }); + }), + + templateApp('Arm64NoAsarEsmExtraFile.app', 'arm64', async (appPath) => { + await fs.promises.cp( + arm64EsmNoAsarDir, + path.resolve(appPath, 'Contents', 'Resources', 'app'), + { recursive: true, verbatimSymlinks: true }, + ); + }), + ]); }; diff --git a/test/index.spec.ts b/test/index.spec.ts index 0ce3fcc..43a52e0 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -121,6 +121,20 @@ describe.concurrent('makeUniversalApp', () => { }, ); + it( + 'should create a shim for ESM entrypoints if asars are different between architectures', + { timeout: VERIFY_APP_TIMEOUT }, + async ({ expect }) => { + const out = path.resolve(await mkOutDir(), 'ShimmedAsarEsm.app'); + await makeUniversalApp({ + x64AppPath: path.resolve(appsPath, 'X64AsarEsm.app'), + arm64AppPath: path.resolve(appsPath, 'Arm64AsarEsmExtraFile.app'), + outAppPath: out, + }); + await verifyApp(expect, out); + }, + ); + it( 'should merge two different asars when `mergeASARs` is enabled', { timeout: VERIFY_APP_TIMEOUT }, @@ -376,6 +390,20 @@ describe.concurrent('makeUniversalApp', () => { }, ); + it( + 'should shim two different app folders with ESM entrypoints', + { timeout: VERIFY_APP_TIMEOUT }, + async ({ expect }) => { + const out = path.resolve(await mkOutDir(), 'ShimNoAsarEsm.app'); + await makeUniversalApp({ + x64AppPath: path.resolve(appsPath, 'X64NoAsarEsm.app'), + arm64AppPath: path.resolve(appsPath, 'Arm64NoAsarEsmExtraFile.app'), + outAppPath: out, + }); + await verifyApp(expect, out); + }, + ); + it( 'different app dirs with different macho files (shim and lipo)', { timeout: VERIFY_APP_TIMEOUT }, diff --git a/tsconfig.entry-asar.json b/tsconfig.entry-asar.json index d6df746..b798ead 100644 --- a/tsconfig.entry-asar.json +++ b/tsconfig.entry-asar.json @@ -14,6 +14,6 @@ "declaration": false, "ignoreDeprecations": "6.0" }, - "include": ["entry-asar"], - "exclude": [] + "include": ["entry-asar/*.ts"], + "exclude": ["entry-asar/esm"] } From 6482e33ed76b62ca508c1ae01b59dc6fad4aaf4c Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 28 Jun 2026 17:43:45 +0000 Subject: [PATCH 2/9] test: fix ESM fixtures to diverge via a unique file, not shared entrypoint content --- test/globalSetup.ts | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/test/globalSetup.ts b/test/globalSetup.ts index 28b38bf..9af58ca 100644 --- a/test/globalSetup.ts +++ b/test/globalSetup.ts @@ -7,9 +7,12 @@ import { createPackage } from '@electron/asar'; import { appsDir, asarsDir, downloadElectronZip, fixtureDir, templateApp } from './util.js'; -// Build an app source directory whose entrypoint is an ES module. The `suffix` -// lets two arches diverge so that `makeUniversalApp` is forced to create a shim. -const createEsmAppDir = async (name: string, suffix: string) => { +// Build an app source directory whose entrypoint is an ES module. The +// `package.json` and `index.mjs` are byte-identical across arches (so +// `makeUniversalApp`'s identical-SHA check for plain files passes); divergence +// is introduced via a uniquely-named `extraFile`, which forces a shim to be +// created the same way the non-ESM fixtures do. +const createEsmAppDir = async (name: string, extraFile?: string) => { const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), `${name}-`)); await fs.promises.writeFile( path.join(dir, 'package.json'), @@ -18,9 +21,12 @@ const createEsmAppDir = async (name: string, suffix: string) => { ); await fs.promises.writeFile( path.join(dir, 'index.mjs'), - `console.log('I am an ESM app${suffix}', process.arch);\nprocess.exit(0);\n`, + `console.log('I am an ESM app', process.arch);\nprocess.exit(0);\n`, 'utf8', ); + if (extraFile) { + await fs.promises.writeFile(path.join(dir, extraFile), 'extra\n', 'utf8'); + } return dir; }; @@ -110,10 +116,10 @@ export default async () => { // ESM entrypoint fixtures (regression coverage for ERR_REQUIRE_ESM when the // x64/arm64 asars diverge). The two arches differ so a shim is generated. - const x64EsmAsarDir = await createEsmAppDir('X64AsarEsm', ''); - const arm64EsmAsarDir = await createEsmAppDir('Arm64AsarEsmExtraFile', ' (extra)'); - const x64EsmNoAsarDir = await createEsmAppDir('X64NoAsarEsm', ''); - const arm64EsmNoAsarDir = await createEsmAppDir('Arm64NoAsarEsmExtraFile', ' (extra)'); + const x64EsmAsarDir = await createEsmAppDir('X64AsarEsm'); + const arm64EsmAsarDir = await createEsmAppDir('Arm64AsarEsmExtraFile', 'extra-file.txt'); + const x64EsmNoAsarDir = await createEsmAppDir('X64NoAsarEsm'); + const arm64EsmNoAsarDir = await createEsmAppDir('Arm64NoAsarEsmExtraFile', 'extra-file.txt'); await Promise.all([ templateApp('X64AsarEsm.app', 'x64', async (appPath) => { From c40874f73e4fae32efa0b1036d36c7b6e3d2d63d Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 28 Jun 2026 17:55:21 +0000 Subject: [PATCH 3/9] test: mirror existing no-asar fixture divergence for ESM The no-asar ESM fixtures are copied straight into the bundle tree, so diverging via a loose plain `extra-file.txt` was classified as a unique PLAIN file and tripped makeUniversalApp's mach-o parity guard. Diverge via uniquely-named `.bin` files instead (classified as V8 snapshots and excluded from the parity check), exactly the way the existing non-ESM `should shim two different app folders` test does. --- test/globalSetup.ts | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/test/globalSetup.ts b/test/globalSetup.ts index 9af58ca..b668cc6 100644 --- a/test/globalSetup.ts +++ b/test/globalSetup.ts @@ -10,8 +10,16 @@ import { appsDir, asarsDir, downloadElectronZip, fixtureDir, templateApp } from // Build an app source directory whose entrypoint is an ES module. The // `package.json` and `index.mjs` are byte-identical across arches (so // `makeUniversalApp`'s identical-SHA check for plain files passes); divergence -// is introduced via a uniquely-named `extraFile`, which forces a shim to be -// created the same way the non-ESM fixtures do. +// is introduced via a uniquely-named `.bin` file. +// +// For the no-asar case the source directory is copied straight into +// `Contents/Resources/app`, which sits in the bundle tree that +// `makeUniversalApp` scans for mach-o parity. A `.bin` file is classified as a +// V8 snapshot (SNAPSHOT) and so is excluded from that parity check, exactly the +// way the existing non-ESM no-asar shim fixtures diverge (see the +// `should shim two different app folders` test, which uses `hello-world.bin` / +// `i-aint-got-no-rhythm.bin`). A loose plain file (e.g. a `.txt`) would instead +// be treated as a unique PLAIN file and trip the parity guard, so we avoid it. const createEsmAppDir = async (name: string, extraFile?: string) => { const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), `${name}-`)); await fs.promises.writeFile( @@ -118,8 +126,15 @@ export default async () => { // x64/arm64 asars diverge). The two arches differ so a shim is generated. const x64EsmAsarDir = await createEsmAppDir('X64AsarEsm'); const arm64EsmAsarDir = await createEsmAppDir('Arm64AsarEsmExtraFile', 'extra-file.txt'); - const x64EsmNoAsarDir = await createEsmAppDir('X64NoAsarEsm'); - const arm64EsmNoAsarDir = await createEsmAppDir('Arm64NoAsarEsmExtraFile', 'extra-file.txt'); + // The no-asar fixtures are copied straight into the bundle tree, so they must + // diverge via uniquely-named `.bin` files (excluded from the mach-o parity + // guard as V8 snapshots) rather than a plain file. This mirrors the existing + // non-ESM `should shim two different app folders` test exactly. + const x64EsmNoAsarDir = await createEsmAppDir('X64NoAsarEsm', 'hello-world.bin'); + const arm64EsmNoAsarDir = await createEsmAppDir( + 'Arm64NoAsarEsmExtraFile', + 'i-aint-got-no-rhythm.bin', + ); await Promise.all([ templateApp('X64AsarEsm.app', 'x64', async (appPath) => { From d09b403abd80259c654d0478a88f0e21704c5e85 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 28 Jun 2026 17:56:03 +0000 Subject: [PATCH 4/9] test: raise verifyApp timeout for heavy integration tests The heavy verifyApp integration tests run ~60s each on their own and the suite is contended under maxConcurrency, so 80s left too little margin and one test timed out at ~140s. Raise VERIFY_APP_TIMEOUT to 180s. --- test/util.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/util.ts b/test/util.ts index bedb1fa..9492c8e 100644 --- a/test/util.ts +++ b/test/util.ts @@ -17,7 +17,9 @@ import * as fileUtils from '../dist/file-utils.js'; // We do a LOT of verifications in `verifyApp` 😅 // exec universal binary -> verify ALL asars -> verify ALL app dirs -> verify ALL asar integrity entries // plus some tests create fixtures at runtime -export const VERIFY_APP_TIMEOUT = 80 * 1000; +// The heavy verifyApp integration tests run ~60s each on their own and the suite +// is contended under `maxConcurrency`, so give them plenty of headroom in CI. +export const VERIFY_APP_TIMEOUT = 180 * 1000; export const fixtureDir = path.resolve(import.meta.dirname, 'fixtures'); export const asarsDir = path.resolve(fixtureDir, 'asars'); From 12f102f17b6e389b414b2b874b8f6655a26b5377 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 28 Jun 2026 18:11:42 +0000 Subject: [PATCH 5/9] fix: use raw path for ESM shim dynamic import and exit on failure --- entry-asar/esm/has-asar.mts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/entry-asar/esm/has-asar.mts b/entry-asar/esm/has-asar.mts index 956f554..a4fd8ba 100644 --- a/entry-asar/esm/has-asar.mts +++ b/entry-asar/esm/has-asar.mts @@ -1,7 +1,6 @@ import { app } from 'electron'; import { createRequire } from 'node:module'; import path from 'node:path'; -import { pathToFileURL } from 'node:url'; const require = createRequire(import.meta.url); @@ -26,5 +25,10 @@ async function setPaths(platform: string) { } process._archPath = require.resolve(`../${asarFile}`); - await import(pathToFileURL(process._archPath).href); + try { + await import(process._archPath); + } catch (err) { + console.error(err); + process.exit(1); + } } From d11d8b0e5769b1c5a5a1075729933ea3b76feb07 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 28 Jun 2026 18:11:52 +0000 Subject: [PATCH 6/9] fix: use raw path for ESM shim dynamic import and exit on failure --- entry-asar/esm/no-asar.mts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/entry-asar/esm/no-asar.mts b/entry-asar/esm/no-asar.mts index 66a0bac..82bed04 100644 --- a/entry-asar/esm/no-asar.mts +++ b/entry-asar/esm/no-asar.mts @@ -1,7 +1,6 @@ import { app } from 'electron'; import { createRequire } from 'node:module'; import path from 'node:path'; -import { pathToFileURL } from 'node:url'; const require = createRequire(import.meta.url); @@ -26,5 +25,10 @@ async function setPaths(platform: string) { } process._archPath = require.resolve(`../${appFolder}`); - await import(pathToFileURL(process._archPath).href); + try { + await import(process._archPath); + } catch (err) { + console.error(err); + process.exit(1); + } } From af30e17f95a2973d79081bb47a9b7b1a7c3dc6a0 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 28 Jun 2026 18:30:28 +0000 Subject: [PATCH 7/9] test: add electron28 dependency and run ESM fixtures on Electron 28 --- package.json | 1 + test/globalSetup.ts | 93 ++++--- test/util.ts | 18 +- yarn.lock | 583 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 662 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index ad901fc..055f318 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@types/node": "~22.10.7", "@types/plist": "^3.0.4", "cross-zip": "^4.0.0", + "electron28": "npm:electron@^28.0.0", "husky": "^9.1.7", "lint-staged": "^16.1.0", "oxfmt": "^0.44.0", diff --git a/test/globalSetup.ts b/test/globalSetup.ts index b668cc6..57438fd 100644 --- a/test/globalSetup.ts +++ b/test/globalSetup.ts @@ -5,7 +5,14 @@ import path from 'node:path'; import { createPackage } from '@electron/asar'; -import { appsDir, asarsDir, downloadElectronZip, fixtureDir, templateApp } from './util.js'; +import { + appsDir, + asarsDir, + downloadElectronZip, + ELECTRON_28_VERSION, + fixtureDir, + templateApp, +} from './util.js'; // Build an app source directory whose entrypoint is an ES module. The // `package.json` and `index.mjs` are byte-identical across arches (so @@ -69,6 +76,10 @@ export default async () => { // the concurrent test suite) so they all hit the cached zip. await downloadElectronZip('arm64'); await downloadElectronZip('x64'); + // The ESM fixtures below run on Electron 28, so warm that version's cache for + // both arches too before the parallel `templateApp` calls race on it. + await downloadElectronZip('arm64', ELECTRON_28_VERSION); + await downloadElectronZip('x64', ELECTRON_28_VERSION); await Promise.all([ templateApp('Arm64Asar.app', 'arm64', async (appPath) => { @@ -137,33 +148,57 @@ export default async () => { ); await Promise.all([ - templateApp('X64AsarEsm.app', 'x64', async (appPath) => { - await createPackage( - x64EsmAsarDir, - path.resolve(appPath, 'Contents', 'Resources', 'app.asar'), - ); - }), - - templateApp('Arm64AsarEsmExtraFile.app', 'arm64', async (appPath) => { - await createPackage( - arm64EsmAsarDir, - path.resolve(appPath, 'Contents', 'Resources', 'app.asar'), - ); - }), - - templateApp('X64NoAsarEsm.app', 'x64', async (appPath) => { - await fs.promises.cp(x64EsmNoAsarDir, path.resolve(appPath, 'Contents', 'Resources', 'app'), { - recursive: true, - verbatimSymlinks: true, - }); - }), - - templateApp('Arm64NoAsarEsmExtraFile.app', 'arm64', async (appPath) => { - await fs.promises.cp( - arm64EsmNoAsarDir, - path.resolve(appPath, 'Contents', 'Resources', 'app'), - { recursive: true, verbatimSymlinks: true }, - ); - }), + templateApp( + 'X64AsarEsm.app', + 'x64', + async (appPath) => { + await createPackage( + x64EsmAsarDir, + path.resolve(appPath, 'Contents', 'Resources', 'app.asar'), + ); + }, + ELECTRON_28_VERSION, + ), + + templateApp( + 'Arm64AsarEsmExtraFile.app', + 'arm64', + async (appPath) => { + await createPackage( + arm64EsmAsarDir, + path.resolve(appPath, 'Contents', 'Resources', 'app.asar'), + ); + }, + ELECTRON_28_VERSION, + ), + + templateApp( + 'X64NoAsarEsm.app', + 'x64', + async (appPath) => { + await fs.promises.cp( + x64EsmNoAsarDir, + path.resolve(appPath, 'Contents', 'Resources', 'app'), + { + recursive: true, + verbatimSymlinks: true, + }, + ); + }, + ELECTRON_28_VERSION, + ), + + templateApp( + 'Arm64NoAsarEsmExtraFile.app', + 'arm64', + async (appPath) => { + await fs.promises.cp( + arm64EsmNoAsarDir, + path.resolve(appPath, 'Contents', 'Resources', 'app'), + { recursive: true, verbatimSymlinks: true }, + ); + }, + ELECTRON_28_VERSION, + ), ]); }; diff --git a/test/util.ts b/test/util.ts index 9492c8e..c074614 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,5 +1,6 @@ import { execFile as execFileCb } from 'node:child_process'; import fs from 'node:fs'; +import { createRequire } from 'node:module'; import os from 'node:os'; import path from 'node:path'; import { promisify } from 'node:util'; @@ -12,8 +13,18 @@ import type { ExpectStatic } from 'vitest'; const execFile = promisify(execFileCb); +const require = createRequire(import.meta.url); + import * as fileUtils from '../dist/file-utils.js'; +// The default Electron version used by the fixtures. The ESM integration +// fixtures override this with `ELECTRON_28_VERSION` below. +export const DEFAULT_ELECTRON_VERSION = '27.0.0'; + +// Resolved from the separately-declared `electron28` dev dependency so it tracks +// whatever `electron@^28` resolves to in the lockfile. +export const ELECTRON_28_VERSION = require('electron28/package.json').version as string; + // We do a LOT of verifications in `verifyApp` 😅 // exec universal binary -> verify ALL asars -> verify ALL app dirs -> verify ALL asar integrity entries // plus some tests create fixtures at runtime @@ -206,10 +217,10 @@ export const createStagingAppDir = async ( }; }; -export const downloadElectronZip = (arch: string) => +export const downloadElectronZip = (arch: string, version: string = DEFAULT_ELECTRON_VERSION) => downloadArtifact({ artifactName: 'electron', - version: '27.0.0', + version, platform: 'darwin', arch, }); @@ -218,8 +229,9 @@ export const templateApp = async ( name: string, arch: string, modify: (appPath: string) => Promise, + version: string = DEFAULT_ELECTRON_VERSION, ) => { - const electronZip = await downloadElectronZip(arch); + const electronZip = await downloadElectronZip(arch, version); // unzip to a unique tmpdir so concurrent calls don't race on the intermediate // Electron.app path const extractDir = await fs.promises.mkdtemp(path.join(appsDir, '.extract-')); diff --git a/yarn.lock b/yarn.lock index 16dce8b..3782fd1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,6 +18,25 @@ __metadata: languageName: node linkType: hard +"@electron/get@npm:^2.0.0": + version: 2.0.3 + resolution: "@electron/get@npm:2.0.3" + dependencies: + debug: "npm:^4.1.1" + env-paths: "npm:^2.2.0" + fs-extra: "npm:^8.1.0" + global-agent: "npm:^3.0.0" + got: "npm:^11.8.5" + progress: "npm:^2.0.3" + semver: "npm:^6.2.0" + sumchecker: "npm:^3.0.1" + dependenciesMeta: + global-agent: + optional: true + checksum: 10c0/148957d531bac50c29541515f2483c3e5c9c6ba9f0269a5d536540d2b8d849188a89588f18901f3a84c2b4fd376d1e0c5ea2159eb2d17bda68558f57df19015e + languageName: node + linkType: hard + "@electron/get@npm:^5.0.0": version: 5.0.0 resolution: "@electron/get@npm:5.0.0" @@ -49,6 +68,7 @@ __metadata: "@types/plist": "npm:^3.0.4" cross-zip: "npm:^4.0.0" debug: "npm:^4.3.1" + electron28: "npm:electron@^28.0.0" husky: "npm:^9.1.7" lint-staged: "npm:^16.1.0" oxfmt: "npm:^0.44.0" @@ -618,6 +638,13 @@ __metadata: languageName: node linkType: hard +"@sindresorhus/is@npm:^4.0.0": + version: 4.6.0 + resolution: "@sindresorhus/is@npm:4.6.0" + checksum: 10c0/33b6fb1d0834ec8dd7689ddc0e2781c2bfd8b9c4e4bacbcb14111e0ae00621f2c264b8a7d36541799d74888b5dccdf422a891a5cb5a709ace26325eedc81e22e + languageName: node + linkType: hard + "@standard-schema/spec@npm:^1.1.0": version: 1.1.0 resolution: "@standard-schema/spec@npm:1.1.0" @@ -625,6 +652,15 @@ __metadata: languageName: node linkType: hard +"@szmarczak/http-timer@npm:^4.0.5": + version: 4.0.6 + resolution: "@szmarczak/http-timer@npm:4.0.6" + dependencies: + defer-to-connect: "npm:^2.0.0" + checksum: 10c0/73946918c025339db68b09abd91fa3001e87fc749c619d2e9c2003a663039d4c3cb89836c98a96598b3d47dec2481284ba85355392644911f5ecd2336536697f + languageName: node + linkType: hard + "@tsconfig/node22@npm:^22.0.1": version: 22.0.1 resolution: "@tsconfig/node22@npm:22.0.1" @@ -641,6 +677,18 @@ __metadata: languageName: node linkType: hard +"@types/cacheable-request@npm:^6.0.1": + version: 6.0.3 + resolution: "@types/cacheable-request@npm:6.0.3" + dependencies: + "@types/http-cache-semantics": "npm:*" + "@types/keyv": "npm:^3.1.4" + "@types/node": "npm:*" + "@types/responselike": "npm:^1.0.0" + checksum: 10c0/10816a88e4e5b144d43c1d15a81003f86d649776c7f410c9b5e6579d0ad9d4ca71c541962fb403077388b446e41af7ae38d313e46692144985f006ac5e11fa03 + languageName: node + linkType: hard + "@types/chai@npm:^5.2.2": version: 5.2.3 resolution: "@types/chai@npm:5.2.3" @@ -690,6 +738,22 @@ __metadata: languageName: node linkType: hard +"@types/http-cache-semantics@npm:*": + version: 4.2.0 + resolution: "@types/http-cache-semantics@npm:4.2.0" + checksum: 10c0/82dd33cbe7d4843f1e884a251c6a12d385b62274353b9db167462e7fbffdbb3a83606f9952203017c5b8cabbd7b9eef0cf240a3a9dedd20f69875c9701939415 + languageName: node + linkType: hard + +"@types/keyv@npm:^3.1.4": + version: 3.1.4 + resolution: "@types/keyv@npm:3.1.4" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/ff8f54fc49621210291f815fe5b15d809fd7d032941b3180743440bd507ecdf08b9e844625fa346af568c84bf34114eb378dcdc3e921a08ba1e2a08d7e3c809c + languageName: node + linkType: hard + "@types/ms@npm:*": version: 0.7.33 resolution: "@types/ms@npm:0.7.33" @@ -706,6 +770,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^18.11.18": + version: 18.19.130 + resolution: "@types/node@npm:18.19.130" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 10c0/22ba2bc9f8863101a7e90a56aaeba1eb3ebdc51e847cef4a6d188967ab1acbce9b4f92251372fd0329ecb924bbf610509e122c3dfe346c04dbad04013d4ad7d0 + languageName: node + linkType: hard + "@types/node@npm:~22.10.7": version: 22.10.10 resolution: "@types/node@npm:22.10.10" @@ -725,6 +798,15 @@ __metadata: languageName: node linkType: hard +"@types/responselike@npm:^1.0.0": + version: 1.0.3 + resolution: "@types/responselike@npm:1.0.3" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/a58ba341cb9e7d74f71810a88862da7b2a6fa42e2a1fc0ce40498f6ea1d44382f0640117057da779f74c47039f7166bf48fad02dc876f94e005c7afa50f5e129 + languageName: node + linkType: hard + "@types/unist@npm:*": version: 3.0.3 resolution: "@types/unist@npm:3.0.3" @@ -732,6 +814,15 @@ __metadata: languageName: node linkType: hard +"@types/yauzl@npm:^2.9.1": + version: 2.10.3 + resolution: "@types/yauzl@npm:2.10.3" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/f1b7c1b99fef9f2fe7f1985ef7426d0cebe48cd031f1780fcdc7451eec7e31ac97028f16f50121a59bcf53086a1fc8c856fd5b7d3e00970e43d92ae27d6b43dc + languageName: node + linkType: hard + "@vitest/expect@npm:4.1.2": version: 4.1.2 resolution: "@vitest/expect@npm:4.1.2" @@ -890,6 +981,13 @@ __metadata: languageName: node linkType: hard +"boolean@npm:^3.0.1": + version: 3.2.0 + resolution: "boolean@npm:3.2.0" + checksum: 10c0/6a0dc9668f6f3dda42a53c181fcbdad223169c8d87b6c4011b87a8b14a21770efb2934a778f063d7ece17280f8c06d313c87f7b834bb1dd526a867ffcd00febf + languageName: node + linkType: hard + "brace-expansion@npm:^5.0.2, brace-expansion@npm:^5.0.5": version: 5.0.6 resolution: "brace-expansion@npm:5.0.6" @@ -908,6 +1006,35 @@ __metadata: languageName: node linkType: hard +"buffer-crc32@npm:~0.2.3": + version: 0.2.13 + resolution: "buffer-crc32@npm:0.2.13" + checksum: 10c0/cb0a8ddf5cf4f766466db63279e47761eb825693eeba6a5a95ee4ec8cb8f81ede70aa7f9d8aeec083e781d47154290eb5d4d26b3f7a465ec57fb9e7d59c47150 + languageName: node + linkType: hard + +"cacheable-lookup@npm:^5.0.3": + version: 5.0.4 + resolution: "cacheable-lookup@npm:5.0.4" + checksum: 10c0/a6547fb4954b318aa831cbdd2f7b376824bc784fb1fa67610e4147099e3074726072d9af89f12efb69121415a0e1f2918a8ddd4aafcbcf4e91fbeef4a59cd42c + languageName: node + linkType: hard + +"cacheable-request@npm:^7.0.2": + version: 7.0.4 + resolution: "cacheable-request@npm:7.0.4" + dependencies: + clone-response: "npm:^1.0.2" + get-stream: "npm:^5.1.0" + http-cache-semantics: "npm:^4.0.0" + keyv: "npm:^4.0.0" + lowercase-keys: "npm:^2.0.0" + normalize-url: "npm:^6.0.1" + responselike: "npm:^2.0.0" + checksum: 10c0/0834a7d17ae71a177bc34eab06de112a43f9b5ad05ebe929bec983d890a7d9f2bc5f1aa8bb67ea2b65e07a3bc74bea35fa62dd36dbac52876afe36fdcf83da41 + languageName: node + linkType: hard + "chai@npm:^6.2.2": version: 6.2.2 resolution: "chai@npm:6.2.2" @@ -941,6 +1068,15 @@ __metadata: languageName: node linkType: hard +"clone-response@npm:^1.0.2": + version: 1.0.3 + resolution: "clone-response@npm:1.0.3" + dependencies: + mimic-response: "npm:^1.0.0" + checksum: 10c0/06a2b611824efb128810708baee3bd169ec9a1bf5976a5258cd7eb3f7db25f00166c6eee5961f075c7e38e194f373d4fdf86b8166ad5b9c7e82bbd2e333a6087 + languageName: node + linkType: hard + "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -1027,6 +1163,44 @@ __metadata: languageName: node linkType: hard +"decompress-response@npm:^6.0.0": + version: 6.0.0 + resolution: "decompress-response@npm:6.0.0" + dependencies: + mimic-response: "npm:^3.1.0" + checksum: 10c0/bd89d23141b96d80577e70c54fb226b2f40e74a6817652b80a116d7befb8758261ad073a8895648a29cc0a5947021ab66705cb542fa9c143c82022b27c5b175e + languageName: node + linkType: hard + +"defer-to-connect@npm:^2.0.0": + version: 2.0.1 + resolution: "defer-to-connect@npm:2.0.1" + checksum: 10c0/625ce28e1b5ad10cf77057b9a6a727bf84780c17660f6644dab61dd34c23de3001f03cedc401f7d30a4ed9965c2e8a7336e220a329146f2cf85d4eddea429782 + languageName: node + linkType: hard + +"define-data-property@npm:^1.0.1": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.0.1" + checksum: 10c0/dea0606d1483eb9db8d930d4eac62ca0fa16738b0b3e07046cddfacf7d8c868bbe13fa0cb263eb91c7d0d527960dc3f2f2471a69ed7816210307f6744fe62e37 + languageName: node + linkType: hard + +"define-properties@npm:^1.2.1": + version: 1.2.1 + resolution: "define-properties@npm:1.2.1" + dependencies: + define-data-property: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.0" + object-keys: "npm:^1.1.1" + checksum: 10c0/88a152319ffe1396ccc6ded510a3896e77efac7a1bfbaa174a7b00414a1747377e0bb525d303794a47cf30e805c2ec84e575758512c6e44a993076d29fd4e6c3 + languageName: node + linkType: hard + "detect-libc@npm:^2.0.3": version: 2.1.2 resolution: "detect-libc@npm:2.1.2" @@ -1034,6 +1208,13 @@ __metadata: languageName: node linkType: hard +"detect-node@npm:^2.0.4": + version: 2.1.0 + resolution: "detect-node@npm:2.1.0" + checksum: 10c0/f039f601790f2e9d4654e499913259a798b1f5246ae24f86ab5e8bd4aaf3bce50484234c494f11fb00aecb0c6e2733aa7b1cf3f530865640b65fbbd65b2c4e09 + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -1041,6 +1222,19 @@ __metadata: languageName: node linkType: hard +"electron28@npm:electron@^28.0.0": + version: 28.3.3 + resolution: "electron@npm:28.3.3" + dependencies: + "@electron/get": "npm:^2.0.0" + "@types/node": "npm:^18.11.18" + extract-zip: "npm:^2.0.1" + bin: + electron: cli.js + checksum: 10c0/e9ff47ed18379f9bdefc49e34f676eb83dde118de83d27e9e98760d02d41dd118b90d854d983831ccf7b8b4fe311966d8c95e43f52b4fb7089a84863e4373e10 + languageName: node + linkType: hard + "emoji-regex@npm:^10.3.0": version: 10.4.0 resolution: "emoji-regex@npm:10.4.0" @@ -1062,6 +1256,15 @@ __metadata: languageName: node linkType: hard +"end-of-stream@npm:^1.1.0": + version: 1.4.5 + resolution: "end-of-stream@npm:1.4.5" + dependencies: + once: "npm:^1.4.0" + checksum: 10c0/b0701c92a10b89afb1cb45bf54a5292c6f008d744eb4382fa559d54775ff31617d1d7bc3ef617575f552e24fad2c7c1a1835948c66b3f3a4be0a6c1f35c883d8 + languageName: node + linkType: hard + "entities@npm:^4.4.0": version: 4.5.0 resolution: "entities@npm:4.5.0" @@ -1069,6 +1272,13 @@ __metadata: languageName: node linkType: hard +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 + languageName: node + linkType: hard + "env-paths@npm:^3.0.0": version: 3.0.0 resolution: "env-paths@npm:3.0.0" @@ -1083,6 +1293,20 @@ __metadata: languageName: node linkType: hard +"es-define-property@npm:^1.0.0": + version: 1.0.1 + resolution: "es-define-property@npm:1.0.1" + checksum: 10c0/3f54eb49c16c18707949ff25a1456728c883e81259f045003499efba399c08bad00deebf65cccde8c0e07908c1a225c9d472b7107e558f2a48e28d530e34527c + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85 + languageName: node + linkType: hard + "es-module-lexer@npm:^2.0.0": version: 2.0.0 resolution: "es-module-lexer@npm:2.0.0" @@ -1090,6 +1314,20 @@ __metadata: languageName: node linkType: hard +"es6-error@npm:^4.1.1": + version: 4.1.1 + resolution: "es6-error@npm:4.1.1" + checksum: 10c0/357663fb1e845c047d548c3d30f86e005db71e122678f4184ced0693f634688c3f3ef2d7de7d4af732f734de01f528b05954e270f06aa7d133679fb9fe6600ef + languageName: node + linkType: hard + +"escape-string-regexp@npm:^4.0.0": + version: 4.0.0 + resolution: "escape-string-regexp@npm:4.0.0" + checksum: 10c0/9497d4dd307d845bd7f75180d8188bb17ea8c151c1edbf6b6717c100e104d629dc2dfb687686181b0f4b7d732c7dfdc4d5e7a8ff72de1b0ca283a75bbb3a9cd9 + languageName: node + linkType: hard + "estree-walker@npm:^3.0.3": version: 3.0.3 resolution: "estree-walker@npm:3.0.3" @@ -1113,6 +1351,32 @@ __metadata: languageName: node linkType: hard +"extract-zip@npm:^2.0.1": + version: 2.0.1 + resolution: "extract-zip@npm:2.0.1" + dependencies: + "@types/yauzl": "npm:^2.9.1" + debug: "npm:^4.1.1" + get-stream: "npm:^5.1.0" + yauzl: "npm:^2.10.0" + dependenciesMeta: + "@types/yauzl": + optional: true + bin: + extract-zip: cli.js + checksum: 10c0/9afbd46854aa15a857ae0341a63a92743a7b89c8779102c3b4ffc207516b2019337353962309f85c66ee3d9092202a83cdc26dbf449a11981272038443974aee + languageName: node + linkType: hard + +"fd-slicer@npm:~1.1.0": + version: 1.1.0 + resolution: "fd-slicer@npm:1.1.0" + dependencies: + pend: "npm:~1.2.0" + checksum: 10c0/304dd70270298e3ffe3bcc05e6f7ade2511acc278bc52d025f8918b48b6aa3b77f10361bddfadfe2a28163f7af7adbdce96f4d22c31b2f648ba2901f0c5fc20e + languageName: node + linkType: hard + "fdir@npm:^6.5.0": version: 6.5.0 resolution: "fdir@npm:6.5.0" @@ -1144,6 +1408,17 @@ __metadata: languageName: node linkType: hard +"fs-extra@npm:^8.1.0": + version: 8.1.0 + resolution: "fs-extra@npm:8.1.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^4.0.0" + universalify: "npm:^0.1.0" + checksum: 10c0/259f7b814d9e50d686899550c4f9ded85c46c643f7fe19be69504888e007fcbc08f306fae8ec495b8b998635e997c9e3e175ff2eeed230524ef1c1684cc96423 + languageName: node + linkType: hard + "fsevents@npm:@electron/fsevents@2.3.3-fork": version: 2.3.3-fork resolution: "@electron/fsevents@npm:2.3.3-fork" @@ -1166,6 +1441,15 @@ __metadata: languageName: node linkType: hard +"get-stream@npm:^5.1.0": + version: 5.2.0 + resolution: "get-stream@npm:5.2.0" + dependencies: + pump: "npm:^3.0.0" + checksum: 10c0/43797ffd815fbb26685bf188c8cfebecb8af87b3925091dd7b9a9c915993293d78e3c9e1bce125928ff92f2d0796f3889b92b5ec6d58d1041b574682132e0a80 + languageName: node + linkType: hard + "glob@npm:^11.0.1": version: 11.1.0 resolution: "glob@npm:11.1.0" @@ -1182,13 +1466,89 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.2.11": +"global-agent@npm:^3.0.0": + version: 3.0.0 + resolution: "global-agent@npm:3.0.0" + dependencies: + boolean: "npm:^3.0.1" + es6-error: "npm:^4.1.1" + matcher: "npm:^3.0.0" + roarr: "npm:^2.15.3" + semver: "npm:^7.3.2" + serialize-error: "npm:^7.0.1" + checksum: 10c0/bb8750d026b25da437072762fd739098bad92ff72f66483c3929db4579e072f5523960f7e7fd70ee0d75db48898067b5dc1c9c1d17888128cff008fcc34d1bd3 + languageName: node + linkType: hard + +"globalthis@npm:^1.0.1": + version: 1.0.4 + resolution: "globalthis@npm:1.0.4" + dependencies: + define-properties: "npm:^1.2.1" + gopd: "npm:^1.0.1" + checksum: 10c0/9d156f313af79d80b1566b93e19285f481c591ad6d0d319b4be5e03750d004dde40a39a0f26f7e635f9007a3600802f53ecd85a759b86f109e80a5f705e01846 + languageName: node + linkType: hard + +"gopd@npm:^1.0.1": + version: 1.2.0 + resolution: "gopd@npm:1.2.0" + checksum: 10c0/50fff1e04ba2b7737c097358534eacadad1e68d24cccee3272e04e007bed008e68d2614f3987788428fd192a5ae3889d08fb2331417e4fc4a9ab366b2043cead + languageName: node + linkType: hard + +"got@npm:^11.8.5": + version: 11.8.6 + resolution: "got@npm:11.8.6" + dependencies: + "@sindresorhus/is": "npm:^4.0.0" + "@szmarczak/http-timer": "npm:^4.0.5" + "@types/cacheable-request": "npm:^6.0.1" + "@types/responselike": "npm:^1.0.0" + cacheable-lookup: "npm:^5.0.3" + cacheable-request: "npm:^7.0.2" + decompress-response: "npm:^6.0.0" + http2-wrapper: "npm:^1.0.0-beta.5.2" + lowercase-keys: "npm:^2.0.0" + p-cancelable: "npm:^2.0.0" + responselike: "npm:^2.0.0" + checksum: 10c0/754dd44877e5cf6183f1e989ff01c648d9a4719e357457bd4c78943911168881f1cfb7b2cb15d885e2105b3ad313adb8f017a67265dd7ade771afdb261ee8cb1 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 languageName: node linkType: hard +"has-property-descriptors@npm:^1.0.0": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: "npm:^1.0.0" + checksum: 10c0/253c1f59e80bb476cf0dde8ff5284505d90c3bdb762983c3514d36414290475fe3fd6f574929d84de2a8eec00d35cf07cb6776205ff32efd7c50719125f00236 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.0.0": + version: 4.2.0 + resolution: "http-cache-semantics@npm:4.2.0" + checksum: 10c0/45b66a945cf13ec2d1f29432277201313babf4a01d9e52f44b31ca923434083afeca03f18417f599c9ab3d0e7b618ceb21257542338b57c54b710463b4a53e37 + languageName: node + linkType: hard + +"http2-wrapper@npm:^1.0.0-beta.5.2": + version: 1.0.3 + resolution: "http2-wrapper@npm:1.0.3" + dependencies: + quick-lru: "npm:^5.1.1" + resolve-alpn: "npm:^1.0.0" + checksum: 10c0/6a9b72a033e9812e1476b9d776ce2f387bc94bc46c88aea0d5dab6bd47d0a539b8178830e77054dd26d1142c866d515a28a4dc7c3ff4232c88ff2ebe4f5d12d1 + languageName: node + linkType: hard + "husky@npm:^9.1.7": version: 9.1.7 resolution: "husky@npm:9.1.7" @@ -1253,6 +1613,41 @@ __metadata: languageName: node linkType: hard +"json-buffer@npm:3.0.1": + version: 3.0.1 + resolution: "json-buffer@npm:3.0.1" + checksum: 10c0/0d1c91569d9588e7eef2b49b59851f297f3ab93c7b35c7c221e288099322be6b562767d11e4821da500f3219542b9afd2e54c5dc573107c1126ed1080f8e96d7 + languageName: node + linkType: hard + +"json-stringify-safe@npm:^5.0.1": + version: 5.0.1 + resolution: "json-stringify-safe@npm:5.0.1" + checksum: 10c0/7dbf35cd0411d1d648dceb6d59ce5857ec939e52e4afc37601aa3da611f0987d5cee5b38d58329ceddf3ed48bd7215229c8d52059ab01f2444a338bf24ed0f37 + languageName: node + linkType: hard + +"jsonfile@npm:^4.0.0": + version: 4.0.0 + resolution: "jsonfile@npm:4.0.0" + dependencies: + graceful-fs: "npm:^4.1.6" + dependenciesMeta: + graceful-fs: + optional: true + checksum: 10c0/7dc94b628d57a66b71fb1b79510d460d662eb975b5f876d723f81549c2e9cd316d58a2ddf742b2b93a4fa6b17b2accaf1a738a0e2ea114bdfb13a32e5377e480 + languageName: node + linkType: hard + +"keyv@npm:^4.0.0": + version: 4.5.4 + resolution: "keyv@npm:4.5.4" + dependencies: + json-buffer: "npm:3.0.1" + checksum: 10c0/aa52f3c5e18e16bb6324876bb8b59dd02acf782a4b789c7b2ae21107fab95fab3890ed448d4f8dba80ce05391eeac4bfabb4f02a20221342982f806fa2cf271e + languageName: node + linkType: hard + "lightningcss-android-arm64@npm:1.32.0": version: 1.32.0 resolution: "lightningcss-android-arm64@npm:1.32.0" @@ -1436,6 +1831,13 @@ __metadata: languageName: node linkType: hard +"lowercase-keys@npm:^2.0.0": + version: 2.0.0 + resolution: "lowercase-keys@npm:2.0.0" + checksum: 10c0/f82a2b3568910509da4b7906362efa40f5b54ea14c2584778ddb313226f9cbf21020a5db35f9b9a0e95847a9b781d548601f31793d736b22a2b8ae8eb9ab1082 + languageName: node + linkType: hard + "lru-cache@npm:^11.0.0": version: 11.1.0 resolution: "lru-cache@npm:11.1.0" @@ -1475,6 +1877,15 @@ __metadata: languageName: node linkType: hard +"matcher@npm:^3.0.0": + version: 3.0.0 + resolution: "matcher@npm:3.0.0" + dependencies: + escape-string-regexp: "npm:^4.0.0" + checksum: 10c0/2edf24194a2879690bcdb29985fc6bc0d003df44e04df21ebcac721fa6ce2f6201c579866bb92f9380bffe946f11ecd8cd31f34117fb67ebf8aca604918e127e + languageName: node + linkType: hard + "mdurl@npm:^2.0.0": version: 2.0.0 resolution: "mdurl@npm:2.0.0" @@ -1499,6 +1910,20 @@ __metadata: languageName: node linkType: hard +"mimic-response@npm:^1.0.0": + version: 1.0.1 + resolution: "mimic-response@npm:1.0.1" + checksum: 10c0/c5381a5eae997f1c3b5e90ca7f209ed58c3615caeee850e85329c598f0c000ae7bec40196580eef1781c60c709f47258131dab237cad8786f8f56750594f27fa + languageName: node + linkType: hard + +"mimic-response@npm:^3.1.0": + version: 3.1.0 + resolution: "mimic-response@npm:3.1.0" + checksum: 10c0/0d6f07ce6e03e9e4445bee655202153bdb8a98d67ee8dc965ac140900d7a2688343e6b4c9a72cfc9ef2f7944dfd76eef4ab2482eb7b293a68b84916bac735362 + languageName: node + linkType: hard + "minimatch@npm:^10.0.1, minimatch@npm:^10.1.1": version: 10.2.4 resolution: "minimatch@npm:10.2.4" @@ -1554,6 +1979,20 @@ __metadata: languageName: node linkType: hard +"normalize-url@npm:^6.0.1": + version: 6.1.0 + resolution: "normalize-url@npm:6.1.0" + checksum: 10c0/95d948f9bdd2cfde91aa786d1816ae40f8262946e13700bf6628105994fe0ff361662c20af3961161c38a119dc977adeb41fc0b41b1745eb77edaaf9cb22db23 + languageName: node + linkType: hard + +"object-keys@npm:^1.1.1": + version: 1.1.1 + resolution: "object-keys@npm:1.1.1" + checksum: 10c0/b11f7ccdbc6d406d1f186cdadb9d54738e347b2692a14439ca5ac70c225fa6db46db809711b78589866d47b25fc3e8dee0b4c722ac751e11180f9380e3d8601d + languageName: node + linkType: hard + "obug@npm:^2.1.1": version: 2.1.1 resolution: "obug@npm:2.1.1" @@ -1561,6 +2000,15 @@ __metadata: languageName: node linkType: hard +"once@npm:^1.3.1, once@npm:^1.4.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0 + languageName: node + linkType: hard + "onetime@npm:^7.0.0": version: 7.0.0 resolution: "onetime@npm:7.0.0" @@ -1741,6 +2189,13 @@ __metadata: languageName: node linkType: hard +"p-cancelable@npm:^2.0.0": + version: 2.1.1 + resolution: "p-cancelable@npm:2.1.1" + checksum: 10c0/8c6dc1f8dd4154fd8b96a10e55a3a832684c4365fb9108056d89e79fbf21a2465027c04a59d0d797b5ffe10b54a61a32043af287d5c4860f1e996cbdbc847f01 + languageName: node + linkType: hard + "package-json-from-dist@npm:^1.0.0": version: 1.0.1 resolution: "package-json-from-dist@npm:1.0.1" @@ -1772,6 +2227,13 @@ __metadata: languageName: node linkType: hard +"pend@npm:~1.2.0": + version: 1.2.0 + resolution: "pend@npm:1.2.0" + checksum: 10c0/8a87e63f7a4afcfb0f9f77b39bb92374afc723418b9cb716ee4257689224171002e07768eeade4ecd0e86f1fa3d8f022994219fb45634f2dbd78c6803e452458 + languageName: node + linkType: hard + "picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" @@ -1831,6 +2293,16 @@ __metadata: languageName: node linkType: hard +"pump@npm:^3.0.0": + version: 3.0.4 + resolution: "pump@npm:3.0.4" + dependencies: + end-of-stream: "npm:^1.1.0" + once: "npm:^1.3.1" + checksum: 10c0/2780e66b5471c19e3e3e1063b84f3f6a3a08367f24c5ed552f98cd5901e6ada27c7ad6495d4244f553fd03b01884a4561933064f053f47c8994d84fd352768ea + languageName: node + linkType: hard + "punycode.js@npm:^2.3.1": version: 2.3.1 resolution: "punycode.js@npm:2.3.1" @@ -1838,6 +2310,29 @@ __metadata: languageName: node linkType: hard +"quick-lru@npm:^5.1.1": + version: 5.1.1 + resolution: "quick-lru@npm:5.1.1" + checksum: 10c0/a24cba5da8cec30d70d2484be37622580f64765fb6390a928b17f60cd69e8dbd32a954b3ff9176fa1b86d86ff2ba05252fae55dc4d40d0291c60412b0ad096da + languageName: node + linkType: hard + +"resolve-alpn@npm:^1.0.0": + version: 1.2.1 + resolution: "resolve-alpn@npm:1.2.1" + checksum: 10c0/b70b29c1843bc39781ef946c8cd4482e6d425976599c0f9c138cec8209e4e0736161bf39319b01676a847000085dfdaf63583c6fb4427bf751a10635bd2aa0c4 + languageName: node + linkType: hard + +"responselike@npm:^2.0.0": + version: 2.0.1 + resolution: "responselike@npm:2.0.1" + dependencies: + lowercase-keys: "npm:^2.0.0" + checksum: 10c0/360b6deb5f101a9f8a4174f7837c523c3ec78b7ca8a7c1d45a1062b303659308a23757e318b1e91ed8684ad1205721142dd664d94771cd63499353fd4ee732b5 + languageName: node + linkType: hard + "restore-cursor@npm:^5.0.0": version: 5.1.0 resolution: "restore-cursor@npm:5.1.0" @@ -1855,6 +2350,20 @@ __metadata: languageName: node linkType: hard +"roarr@npm:^2.15.3": + version: 2.15.4 + resolution: "roarr@npm:2.15.4" + dependencies: + boolean: "npm:^3.0.1" + detect-node: "npm:^2.0.4" + globalthis: "npm:^1.0.1" + json-stringify-safe: "npm:^5.0.1" + semver-compare: "npm:^1.0.0" + sprintf-js: "npm:^1.1.2" + checksum: 10c0/7d01d4c14513c461778dd673a8f9e53255221f8d04173aafeb8e11b23d8b659bb83f1c90cfe81af7f9c213b8084b404b918108fd792bda76678f555340cc64ec + languageName: node + linkType: hard + "rolldown@npm:1.0.3": version: 1.0.3 resolution: "rolldown@npm:1.0.3" @@ -1913,6 +2422,31 @@ __metadata: languageName: node linkType: hard +"semver-compare@npm:^1.0.0": + version: 1.0.0 + resolution: "semver-compare@npm:1.0.0" + checksum: 10c0/9ef4d8b81847556f0865f46ddc4d276bace118c7cb46811867af82e837b7fc473911981d5a0abc561fa2db487065572217e5b06e18701c4281bcdd2a1affaff1 + languageName: node + linkType: hard + +"semver@npm:^6.2.0": + version: 6.3.1 + resolution: "semver@npm:6.3.1" + bin: + semver: bin/semver.js + checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d + languageName: node + linkType: hard + +"semver@npm:^7.3.2": + version: 7.8.5 + resolution: "semver@npm:7.8.5" + bin: + semver: bin/semver.js + checksum: 10c0/b1f3127a5be8125a94f37188b361c212466c292c6910adce3ec106cff5dc211ccaedc4739c11bb70fda59d6fc1f040a9bca289f4e093451521a2372e5231fe0c + languageName: node + linkType: hard + "semver@npm:^7.6.3": version: 7.7.2 resolution: "semver@npm:7.7.2" @@ -1922,6 +2456,15 @@ __metadata: languageName: node linkType: hard +"serialize-error@npm:^7.0.1": + version: 7.0.1 + resolution: "serialize-error@npm:7.0.1" + dependencies: + type-fest: "npm:^0.13.1" + checksum: 10c0/7982937d578cd901276c8ab3e2c6ed8a4c174137730f1fb0402d005af209a0e84d04acc874e317c936724c7b5b26c7a96ff7e4b8d11a469f4924a4b0ea814c05 + languageName: node + linkType: hard + "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -1979,6 +2522,13 @@ __metadata: languageName: node linkType: hard +"sprintf-js@npm:^1.1.2": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: 10c0/09270dc4f30d479e666aee820eacd9e464215cdff53848b443964202bf4051490538e5dd1b42e1a65cf7296916ca17640aebf63dae9812749c7542ee5f288dec + languageName: node + linkType: hard + "stackback@npm:0.0.2": version: 0.0.2 resolution: "stackback@npm:0.0.2" @@ -2124,6 +2674,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^0.13.1": + version: 0.13.1 + resolution: "type-fest@npm:0.13.1" + checksum: 10c0/0c0fa07ae53d4e776cf4dac30d25ad799443e9eef9226f9fddbb69242db86b08584084a99885cfa5a9dfe4c063ebdc9aa7b69da348e735baede8d43f1aeae93b + languageName: node + linkType: hard + "typedoc@npm:~0.28.0": version: 0.28.18 resolution: "typedoc@npm:0.28.18" @@ -2189,6 +2746,13 @@ __metadata: languageName: node linkType: hard +"universalify@npm:^0.1.0": + version: 0.1.2 + resolution: "universalify@npm:0.1.2" + checksum: 10c0/e70e0339f6b36f34c9816f6bf9662372bd241714dc77508d231d08386d94f2c4aa1ba1318614f92015f40d45aae1b9075cd30bd490efbe39387b60a76ca3f045 + languageName: node + linkType: hard + "vite@npm:^6.0.0 || ^7.0.0 || ^8.0.0": version: 8.0.16 resolution: "vite@npm:8.0.16" @@ -2364,6 +2928,13 @@ __metadata: languageName: node linkType: hard +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0 + languageName: node + linkType: hard + "xmlbuilder@npm:>=11.0.1, xmlbuilder@npm:^15.1.1": version: 15.1.1 resolution: "xmlbuilder@npm:15.1.1" @@ -2379,3 +2950,13 @@ __metadata: checksum: 10c0/ddff0e11c1b467728d7eb4633db61c5f5de3d8e9373cf84d08fb0cdee03e1f58f02b9f1c51a4a8a865751695addbd465a77f73f1079be91fe5493b29c305fd77 languageName: node linkType: hard + +"yauzl@npm:^2.10.0": + version: 2.10.0 + resolution: "yauzl@npm:2.10.0" + dependencies: + buffer-crc32: "npm:~0.2.3" + fd-slicer: "npm:~1.1.0" + checksum: 10c0/f265002af7541b9ec3589a27f5fb8f11cf348b53cc15e2751272e3c062cd73f3e715bc72d43257de71bbaecae446c3f1b14af7559e8ab0261625375541816422 + languageName: node + linkType: hard From 9008a2f61cad2895b3159d4afce0b0de52cbd33f Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 28 Jun 2026 18:45:15 +0000 Subject: [PATCH 8/9] test: assert ESM universal app boots and emits index.mjs instead of snapshotting --- test/index.spec.ts | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/test/index.spec.ts b/test/index.spec.ts index 43a52e0..7e06f15 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -8,12 +8,13 @@ import { makeUniversalApp } from '../dist/index.js'; import { fsMove } from '../src/file-utils.js'; import { createStagingAppDir, + ensureUniversal, generateNativeApp, templateApp, VERIFY_APP_TIMEOUT, verifyApp, } from './util.js'; -import { createPackage, createPackageWithOptions } from '@electron/asar'; +import { createPackage, createPackageWithOptions, extractFile } from '@electron/asar'; const appsPath = path.resolve(import.meta.dirname, 'fixtures', 'apps'); @@ -131,7 +132,16 @@ describe.concurrent('makeUniversalApp', () => { arm64AppPath: path.resolve(appsPath, 'Arm64AsarEsmExtraFile.app'), outAppPath: out, }); - await verifyApp(expect, out); + // Launches both arches; asserts each prints its arch, proving the ESM + // shim loads the per-arch entrypoint. We can't snapshot the file tree + // here because no baseline is committed (it can only be generated on + // macOS), so assert the emitted shim + `main` directly instead. + await ensureUniversal(expect, out); + const appAsar = path.resolve(out, 'Contents', 'Resources', 'app.asar'); + const pj = JSON.parse(extractFile(appAsar, 'package.json').toString('utf8')); + expect(pj.main).toBe('index.mjs'); + const shim = extractFile(appAsar, 'index.mjs').toString('utf8'); + expect(shim).toContain('await import'); }, ); @@ -400,7 +410,17 @@ describe.concurrent('makeUniversalApp', () => { arm64AppPath: path.resolve(appsPath, 'Arm64NoAsarEsmExtraFile.app'), outAppPath: out, }); - await verifyApp(expect, out); + // Launches both arches; asserts each prints its arch, proving the ESM + // shim loads the per-arch entrypoint. We can't snapshot the file tree + // here because no baseline is committed (it can only be generated on + // macOS), so assert the emitted shim + `main` directly instead. The + // no-asar path also packages the shim folder into `app.asar`. + await ensureUniversal(expect, out); + const appAsar = path.resolve(out, 'Contents', 'Resources', 'app.asar'); + const pj = JSON.parse(extractFile(appAsar, 'package.json').toString('utf8')); + expect(pj.main).toBe('index.mjs'); + const shim = extractFile(appAsar, 'index.mjs').toString('utf8'); + expect(shim).toContain('await import'); }, ); From f9eabd8288642717087cf25a5412d9b9a776addc Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 2 Jul 2026 20:39:21 +0000 Subject: [PATCH 9/9] build: update electron devDependencies Bump the aliased electron dev dependency used by the ESM fixtures from electron@^28.0.0 to the latest stable electron@^43.0.0 and rename the alias/constant accordingly (electron28 -> electron43, ELECTRON_28_VERSION -> ELECTRON_43_VERSION). --- package.json | 2 +- test/globalSetup.ts | 16 +- test/util.ts | 8 +- yarn.lock | 601 +++----------------------------------------- 4 files changed, 42 insertions(+), 585 deletions(-) diff --git a/package.json b/package.json index 055f318..01aee06 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@types/node": "~22.10.7", "@types/plist": "^3.0.4", "cross-zip": "^4.0.0", - "electron28": "npm:electron@^28.0.0", + "electron43": "npm:electron@^43.0.0", "husky": "^9.1.7", "lint-staged": "^16.1.0", "oxfmt": "^0.44.0", diff --git a/test/globalSetup.ts b/test/globalSetup.ts index 57438fd..e113403 100644 --- a/test/globalSetup.ts +++ b/test/globalSetup.ts @@ -9,7 +9,7 @@ import { appsDir, asarsDir, downloadElectronZip, - ELECTRON_28_VERSION, + ELECTRON_43_VERSION, fixtureDir, templateApp, } from './util.js'; @@ -76,10 +76,10 @@ export default async () => { // the concurrent test suite) so they all hit the cached zip. await downloadElectronZip('arm64'); await downloadElectronZip('x64'); - // The ESM fixtures below run on Electron 28, so warm that version's cache for + // The ESM fixtures below run on Electron 43, so warm that version's cache for // both arches too before the parallel `templateApp` calls race on it. - await downloadElectronZip('arm64', ELECTRON_28_VERSION); - await downloadElectronZip('x64', ELECTRON_28_VERSION); + await downloadElectronZip('arm64', ELECTRON_43_VERSION); + await downloadElectronZip('x64', ELECTRON_43_VERSION); await Promise.all([ templateApp('Arm64Asar.app', 'arm64', async (appPath) => { @@ -157,7 +157,7 @@ export default async () => { path.resolve(appPath, 'Contents', 'Resources', 'app.asar'), ); }, - ELECTRON_28_VERSION, + ELECTRON_43_VERSION, ), templateApp( @@ -169,7 +169,7 @@ export default async () => { path.resolve(appPath, 'Contents', 'Resources', 'app.asar'), ); }, - ELECTRON_28_VERSION, + ELECTRON_43_VERSION, ), templateApp( @@ -185,7 +185,7 @@ export default async () => { }, ); }, - ELECTRON_28_VERSION, + ELECTRON_43_VERSION, ), templateApp( @@ -198,7 +198,7 @@ export default async () => { { recursive: true, verbatimSymlinks: true }, ); }, - ELECTRON_28_VERSION, + ELECTRON_43_VERSION, ), ]); }; diff --git a/test/util.ts b/test/util.ts index c074614..d1e5af3 100644 --- a/test/util.ts +++ b/test/util.ts @@ -18,12 +18,12 @@ const require = createRequire(import.meta.url); import * as fileUtils from '../dist/file-utils.js'; // The default Electron version used by the fixtures. The ESM integration -// fixtures override this with `ELECTRON_28_VERSION` below. +// fixtures override this with `ELECTRON_43_VERSION` below. export const DEFAULT_ELECTRON_VERSION = '27.0.0'; -// Resolved from the separately-declared `electron28` dev dependency so it tracks -// whatever `electron@^28` resolves to in the lockfile. -export const ELECTRON_28_VERSION = require('electron28/package.json').version as string; +// Resolved from the separately-declared `electron43` dev dependency so it tracks +// whatever `electron@^43` resolves to in the lockfile. +export const ELECTRON_43_VERSION = require('electron43/package.json').version as string; // We do a LOT of verifications in `verifyApp` 😅 // exec universal binary -> verify ALL asars -> verify ALL app dirs -> verify ALL asar integrity entries diff --git a/yarn.lock b/yarn.lock index 3782fd1..cfcd15e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,13 @@ __metadata: version: 8 cacheKey: 10c0 +"@electron-internal/extract-zip@npm:^1.0.1": + version: 1.0.4 + resolution: "@electron-internal/extract-zip@npm:1.0.4" + checksum: 10c0/e841b38b08317ff5345e3454d0417c406d2258f0de5e654b55b49b28c46d3c0666febc5e14044a4ce110b8a9dd5d4d2b6d7e546a658d073094b3e335ca6db252 + languageName: node + linkType: hard + "@electron/asar@npm:^4.0.0": version: 4.0.0 resolution: "@electron/asar@npm:4.0.0" @@ -18,25 +25,6 @@ __metadata: languageName: node linkType: hard -"@electron/get@npm:^2.0.0": - version: 2.0.3 - resolution: "@electron/get@npm:2.0.3" - dependencies: - debug: "npm:^4.1.1" - env-paths: "npm:^2.2.0" - fs-extra: "npm:^8.1.0" - global-agent: "npm:^3.0.0" - got: "npm:^11.8.5" - progress: "npm:^2.0.3" - semver: "npm:^6.2.0" - sumchecker: "npm:^3.0.1" - dependenciesMeta: - global-agent: - optional: true - checksum: 10c0/148957d531bac50c29541515f2483c3e5c9c6ba9f0269a5d536540d2b8d849188a89588f18901f3a84c2b4fd376d1e0c5ea2159eb2d17bda68558f57df19015e - languageName: node - linkType: hard - "@electron/get@npm:^5.0.0": version: 5.0.0 resolution: "@electron/get@npm:5.0.0" @@ -68,7 +56,7 @@ __metadata: "@types/plist": "npm:^3.0.4" cross-zip: "npm:^4.0.0" debug: "npm:^4.3.1" - electron28: "npm:electron@^28.0.0" + electron43: "npm:electron@^43.0.0" husky: "npm:^9.1.7" lint-staged: "npm:^16.1.0" oxfmt: "npm:^0.44.0" @@ -638,13 +626,6 @@ __metadata: languageName: node linkType: hard -"@sindresorhus/is@npm:^4.0.0": - version: 4.6.0 - resolution: "@sindresorhus/is@npm:4.6.0" - checksum: 10c0/33b6fb1d0834ec8dd7689ddc0e2781c2bfd8b9c4e4bacbcb14111e0ae00621f2c264b8a7d36541799d74888b5dccdf422a891a5cb5a709ace26325eedc81e22e - languageName: node - linkType: hard - "@standard-schema/spec@npm:^1.1.0": version: 1.1.0 resolution: "@standard-schema/spec@npm:1.1.0" @@ -652,15 +633,6 @@ __metadata: languageName: node linkType: hard -"@szmarczak/http-timer@npm:^4.0.5": - version: 4.0.6 - resolution: "@szmarczak/http-timer@npm:4.0.6" - dependencies: - defer-to-connect: "npm:^2.0.0" - checksum: 10c0/73946918c025339db68b09abd91fa3001e87fc749c619d2e9c2003a663039d4c3cb89836c98a96598b3d47dec2481284ba85355392644911f5ecd2336536697f - languageName: node - linkType: hard - "@tsconfig/node22@npm:^22.0.1": version: 22.0.1 resolution: "@tsconfig/node22@npm:22.0.1" @@ -677,18 +649,6 @@ __metadata: languageName: node linkType: hard -"@types/cacheable-request@npm:^6.0.1": - version: 6.0.3 - resolution: "@types/cacheable-request@npm:6.0.3" - dependencies: - "@types/http-cache-semantics": "npm:*" - "@types/keyv": "npm:^3.1.4" - "@types/node": "npm:*" - "@types/responselike": "npm:^1.0.0" - checksum: 10c0/10816a88e4e5b144d43c1d15a81003f86d649776c7f410c9b5e6579d0ad9d4ca71c541962fb403077388b446e41af7ae38d313e46692144985f006ac5e11fa03 - languageName: node - linkType: hard - "@types/chai@npm:^5.2.2": version: 5.2.3 resolution: "@types/chai@npm:5.2.3" @@ -738,22 +698,6 @@ __metadata: languageName: node linkType: hard -"@types/http-cache-semantics@npm:*": - version: 4.2.0 - resolution: "@types/http-cache-semantics@npm:4.2.0" - checksum: 10c0/82dd33cbe7d4843f1e884a251c6a12d385b62274353b9db167462e7fbffdbb3a83606f9952203017c5b8cabbd7b9eef0cf240a3a9dedd20f69875c9701939415 - languageName: node - linkType: hard - -"@types/keyv@npm:^3.1.4": - version: 3.1.4 - resolution: "@types/keyv@npm:3.1.4" - dependencies: - "@types/node": "npm:*" - checksum: 10c0/ff8f54fc49621210291f815fe5b15d809fd7d032941b3180743440bd507ecdf08b9e844625fa346af568c84bf34114eb378dcdc3e921a08ba1e2a08d7e3c809c - languageName: node - linkType: hard - "@types/ms@npm:*": version: 0.7.33 resolution: "@types/ms@npm:0.7.33" @@ -770,12 +714,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^18.11.18": - version: 18.19.130 - resolution: "@types/node@npm:18.19.130" +"@types/node@npm:^24.9.0": + version: 24.13.2 + resolution: "@types/node@npm:24.13.2" dependencies: - undici-types: "npm:~5.26.4" - checksum: 10c0/22ba2bc9f8863101a7e90a56aaeba1eb3ebdc51e847cef4a6d188967ab1acbce9b4f92251372fd0329ecb924bbf610509e122c3dfe346c04dbad04013d4ad7d0 + undici-types: "npm:~7.18.0" + checksum: 10c0/d7d48a88a4feb0a6aac3cbfaf9ef3b12752b4b09447f88dd0b4c77c03b281e3d4330fe6982a99aedcd63fc16c7540a0c248b91eb2abb0b3edd884d7fe684e9ea languageName: node linkType: hard @@ -798,15 +742,6 @@ __metadata: languageName: node linkType: hard -"@types/responselike@npm:^1.0.0": - version: 1.0.3 - resolution: "@types/responselike@npm:1.0.3" - dependencies: - "@types/node": "npm:*" - checksum: 10c0/a58ba341cb9e7d74f71810a88862da7b2a6fa42e2a1fc0ce40498f6ea1d44382f0640117057da779f74c47039f7166bf48fad02dc876f94e005c7afa50f5e129 - languageName: node - linkType: hard - "@types/unist@npm:*": version: 3.0.3 resolution: "@types/unist@npm:3.0.3" @@ -814,15 +749,6 @@ __metadata: languageName: node linkType: hard -"@types/yauzl@npm:^2.9.1": - version: 2.10.3 - resolution: "@types/yauzl@npm:2.10.3" - dependencies: - "@types/node": "npm:*" - checksum: 10c0/f1b7c1b99fef9f2fe7f1985ef7426d0cebe48cd031f1780fcdc7451eec7e31ac97028f16f50121a59bcf53086a1fc8c856fd5b7d3e00970e43d92ae27d6b43dc - languageName: node - linkType: hard - "@vitest/expect@npm:4.1.2": version: 4.1.2 resolution: "@vitest/expect@npm:4.1.2" @@ -981,13 +907,6 @@ __metadata: languageName: node linkType: hard -"boolean@npm:^3.0.1": - version: 3.2.0 - resolution: "boolean@npm:3.2.0" - checksum: 10c0/6a0dc9668f6f3dda42a53c181fcbdad223169c8d87b6c4011b87a8b14a21770efb2934a778f063d7ece17280f8c06d313c87f7b834bb1dd526a867ffcd00febf - languageName: node - linkType: hard - "brace-expansion@npm:^5.0.2, brace-expansion@npm:^5.0.5": version: 5.0.6 resolution: "brace-expansion@npm:5.0.6" @@ -1006,35 +925,6 @@ __metadata: languageName: node linkType: hard -"buffer-crc32@npm:~0.2.3": - version: 0.2.13 - resolution: "buffer-crc32@npm:0.2.13" - checksum: 10c0/cb0a8ddf5cf4f766466db63279e47761eb825693eeba6a5a95ee4ec8cb8f81ede70aa7f9d8aeec083e781d47154290eb5d4d26b3f7a465ec57fb9e7d59c47150 - languageName: node - linkType: hard - -"cacheable-lookup@npm:^5.0.3": - version: 5.0.4 - resolution: "cacheable-lookup@npm:5.0.4" - checksum: 10c0/a6547fb4954b318aa831cbdd2f7b376824bc784fb1fa67610e4147099e3074726072d9af89f12efb69121415a0e1f2918a8ddd4aafcbcf4e91fbeef4a59cd42c - languageName: node - linkType: hard - -"cacheable-request@npm:^7.0.2": - version: 7.0.4 - resolution: "cacheable-request@npm:7.0.4" - dependencies: - clone-response: "npm:^1.0.2" - get-stream: "npm:^5.1.0" - http-cache-semantics: "npm:^4.0.0" - keyv: "npm:^4.0.0" - lowercase-keys: "npm:^2.0.0" - normalize-url: "npm:^6.0.1" - responselike: "npm:^2.0.0" - checksum: 10c0/0834a7d17ae71a177bc34eab06de112a43f9b5ad05ebe929bec983d890a7d9f2bc5f1aa8bb67ea2b65e07a3bc74bea35fa62dd36dbac52876afe36fdcf83da41 - languageName: node - linkType: hard - "chai@npm:^6.2.2": version: 6.2.2 resolution: "chai@npm:6.2.2" @@ -1068,15 +958,6 @@ __metadata: languageName: node linkType: hard -"clone-response@npm:^1.0.2": - version: 1.0.3 - resolution: "clone-response@npm:1.0.3" - dependencies: - mimic-response: "npm:^1.0.0" - checksum: 10c0/06a2b611824efb128810708baee3bd169ec9a1bf5976a5258cd7eb3f7db25f00166c6eee5961f075c7e38e194f373d4fdf86b8166ad5b9c7e82bbd2e333a6087 - languageName: node - linkType: hard - "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -1163,44 +1044,6 @@ __metadata: languageName: node linkType: hard -"decompress-response@npm:^6.0.0": - version: 6.0.0 - resolution: "decompress-response@npm:6.0.0" - dependencies: - mimic-response: "npm:^3.1.0" - checksum: 10c0/bd89d23141b96d80577e70c54fb226b2f40e74a6817652b80a116d7befb8758261ad073a8895648a29cc0a5947021ab66705cb542fa9c143c82022b27c5b175e - languageName: node - linkType: hard - -"defer-to-connect@npm:^2.0.0": - version: 2.0.1 - resolution: "defer-to-connect@npm:2.0.1" - checksum: 10c0/625ce28e1b5ad10cf77057b9a6a727bf84780c17660f6644dab61dd34c23de3001f03cedc401f7d30a4ed9965c2e8a7336e220a329146f2cf85d4eddea429782 - languageName: node - linkType: hard - -"define-data-property@npm:^1.0.1": - version: 1.1.4 - resolution: "define-data-property@npm:1.1.4" - dependencies: - es-define-property: "npm:^1.0.0" - es-errors: "npm:^1.3.0" - gopd: "npm:^1.0.1" - checksum: 10c0/dea0606d1483eb9db8d930d4eac62ca0fa16738b0b3e07046cddfacf7d8c868bbe13fa0cb263eb91c7d0d527960dc3f2f2471a69ed7816210307f6744fe62e37 - languageName: node - linkType: hard - -"define-properties@npm:^1.2.1": - version: 1.2.1 - resolution: "define-properties@npm:1.2.1" - dependencies: - define-data-property: "npm:^1.0.1" - has-property-descriptors: "npm:^1.0.0" - object-keys: "npm:^1.1.1" - checksum: 10c0/88a152319ffe1396ccc6ded510a3896e77efac7a1bfbaa174a7b00414a1747377e0bb525d303794a47cf30e805c2ec84e575758512c6e44a993076d29fd4e6c3 - languageName: node - linkType: hard - "detect-libc@npm:^2.0.3": version: 2.1.2 resolution: "detect-libc@npm:2.1.2" @@ -1208,13 +1051,6 @@ __metadata: languageName: node linkType: hard -"detect-node@npm:^2.0.4": - version: 2.1.0 - resolution: "detect-node@npm:2.1.0" - checksum: 10c0/f039f601790f2e9d4654e499913259a798b1f5246ae24f86ab5e8bd4aaf3bce50484234c494f11fb00aecb0c6e2733aa7b1cf3f530865640b65fbbd65b2c4e09 - languageName: node - linkType: hard - "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -1222,16 +1058,17 @@ __metadata: languageName: node linkType: hard -"electron28@npm:electron@^28.0.0": - version: 28.3.3 - resolution: "electron@npm:28.3.3" +"electron43@npm:electron@^43.0.0": + version: 43.0.0 + resolution: "electron@npm:43.0.0" dependencies: - "@electron/get": "npm:^2.0.0" - "@types/node": "npm:^18.11.18" - extract-zip: "npm:^2.0.1" + "@electron-internal/extract-zip": "npm:^1.0.1" + "@electron/get": "npm:^5.0.0" + "@types/node": "npm:^24.9.0" bin: electron: cli.js - checksum: 10c0/e9ff47ed18379f9bdefc49e34f676eb83dde118de83d27e9e98760d02d41dd118b90d854d983831ccf7b8b4fe311966d8c95e43f52b4fb7089a84863e4373e10 + install-electron: install.js + checksum: 10c0/9f0bfb4e55dd97102941d009ce44ea1c5aa82325e877733284d75be8880ead11305ff45198d059e5127b441c94391ed159136cee23f2474e2416e2bbab2e9940 languageName: node linkType: hard @@ -1256,15 +1093,6 @@ __metadata: languageName: node linkType: hard -"end-of-stream@npm:^1.1.0": - version: 1.4.5 - resolution: "end-of-stream@npm:1.4.5" - dependencies: - once: "npm:^1.4.0" - checksum: 10c0/b0701c92a10b89afb1cb45bf54a5292c6f008d744eb4382fa559d54775ff31617d1d7bc3ef617575f552e24fad2c7c1a1835948c66b3f3a4be0a6c1f35c883d8 - languageName: node - linkType: hard - "entities@npm:^4.4.0": version: 4.5.0 resolution: "entities@npm:4.5.0" @@ -1272,13 +1100,6 @@ __metadata: languageName: node linkType: hard -"env-paths@npm:^2.2.0": - version: 2.2.1 - resolution: "env-paths@npm:2.2.1" - checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 - languageName: node - linkType: hard - "env-paths@npm:^3.0.0": version: 3.0.0 resolution: "env-paths@npm:3.0.0" @@ -1293,20 +1114,6 @@ __metadata: languageName: node linkType: hard -"es-define-property@npm:^1.0.0": - version: 1.0.1 - resolution: "es-define-property@npm:1.0.1" - checksum: 10c0/3f54eb49c16c18707949ff25a1456728c883e81259f045003499efba399c08bad00deebf65cccde8c0e07908c1a225c9d472b7107e558f2a48e28d530e34527c - languageName: node - linkType: hard - -"es-errors@npm:^1.3.0": - version: 1.3.0 - resolution: "es-errors@npm:1.3.0" - checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85 - languageName: node - linkType: hard - "es-module-lexer@npm:^2.0.0": version: 2.0.0 resolution: "es-module-lexer@npm:2.0.0" @@ -1314,20 +1121,6 @@ __metadata: languageName: node linkType: hard -"es6-error@npm:^4.1.1": - version: 4.1.1 - resolution: "es6-error@npm:4.1.1" - checksum: 10c0/357663fb1e845c047d548c3d30f86e005db71e122678f4184ced0693f634688c3f3ef2d7de7d4af732f734de01f528b05954e270f06aa7d133679fb9fe6600ef - languageName: node - linkType: hard - -"escape-string-regexp@npm:^4.0.0": - version: 4.0.0 - resolution: "escape-string-regexp@npm:4.0.0" - checksum: 10c0/9497d4dd307d845bd7f75180d8188bb17ea8c151c1edbf6b6717c100e104d629dc2dfb687686181b0f4b7d732c7dfdc4d5e7a8ff72de1b0ca283a75bbb3a9cd9 - languageName: node - linkType: hard - "estree-walker@npm:^3.0.3": version: 3.0.3 resolution: "estree-walker@npm:3.0.3" @@ -1351,32 +1144,6 @@ __metadata: languageName: node linkType: hard -"extract-zip@npm:^2.0.1": - version: 2.0.1 - resolution: "extract-zip@npm:2.0.1" - dependencies: - "@types/yauzl": "npm:^2.9.1" - debug: "npm:^4.1.1" - get-stream: "npm:^5.1.0" - yauzl: "npm:^2.10.0" - dependenciesMeta: - "@types/yauzl": - optional: true - bin: - extract-zip: cli.js - checksum: 10c0/9afbd46854aa15a857ae0341a63a92743a7b89c8779102c3b4ffc207516b2019337353962309f85c66ee3d9092202a83cdc26dbf449a11981272038443974aee - languageName: node - linkType: hard - -"fd-slicer@npm:~1.1.0": - version: 1.1.0 - resolution: "fd-slicer@npm:1.1.0" - dependencies: - pend: "npm:~1.2.0" - checksum: 10c0/304dd70270298e3ffe3bcc05e6f7ade2511acc278bc52d025f8918b48b6aa3b77f10361bddfadfe2a28163f7af7adbdce96f4d22c31b2f648ba2901f0c5fc20e - languageName: node - linkType: hard - "fdir@npm:^6.5.0": version: 6.5.0 resolution: "fdir@npm:6.5.0" @@ -1408,17 +1175,6 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^8.1.0": - version: 8.1.0 - resolution: "fs-extra@npm:8.1.0" - dependencies: - graceful-fs: "npm:^4.2.0" - jsonfile: "npm:^4.0.0" - universalify: "npm:^0.1.0" - checksum: 10c0/259f7b814d9e50d686899550c4f9ded85c46c643f7fe19be69504888e007fcbc08f306fae8ec495b8b998635e997c9e3e175ff2eeed230524ef1c1684cc96423 - languageName: node - linkType: hard - "fsevents@npm:@electron/fsevents@2.3.3-fork": version: 2.3.3-fork resolution: "@electron/fsevents@npm:2.3.3-fork" @@ -1441,15 +1197,6 @@ __metadata: languageName: node linkType: hard -"get-stream@npm:^5.1.0": - version: 5.2.0 - resolution: "get-stream@npm:5.2.0" - dependencies: - pump: "npm:^3.0.0" - checksum: 10c0/43797ffd815fbb26685bf188c8cfebecb8af87b3925091dd7b9a9c915993293d78e3c9e1bce125928ff92f2d0796f3889b92b5ec6d58d1041b574682132e0a80 - languageName: node - linkType: hard - "glob@npm:^11.0.1": version: 11.1.0 resolution: "glob@npm:11.1.0" @@ -1466,89 +1213,13 @@ __metadata: languageName: node linkType: hard -"global-agent@npm:^3.0.0": - version: 3.0.0 - resolution: "global-agent@npm:3.0.0" - dependencies: - boolean: "npm:^3.0.1" - es6-error: "npm:^4.1.1" - matcher: "npm:^3.0.0" - roarr: "npm:^2.15.3" - semver: "npm:^7.3.2" - serialize-error: "npm:^7.0.1" - checksum: 10c0/bb8750d026b25da437072762fd739098bad92ff72f66483c3929db4579e072f5523960f7e7fd70ee0d75db48898067b5dc1c9c1d17888128cff008fcc34d1bd3 - languageName: node - linkType: hard - -"globalthis@npm:^1.0.1": - version: 1.0.4 - resolution: "globalthis@npm:1.0.4" - dependencies: - define-properties: "npm:^1.2.1" - gopd: "npm:^1.0.1" - checksum: 10c0/9d156f313af79d80b1566b93e19285f481c591ad6d0d319b4be5e03750d004dde40a39a0f26f7e635f9007a3600802f53ecd85a759b86f109e80a5f705e01846 - languageName: node - linkType: hard - -"gopd@npm:^1.0.1": - version: 1.2.0 - resolution: "gopd@npm:1.2.0" - checksum: 10c0/50fff1e04ba2b7737c097358534eacadad1e68d24cccee3272e04e007bed008e68d2614f3987788428fd192a5ae3889d08fb2331417e4fc4a9ab366b2043cead - languageName: node - linkType: hard - -"got@npm:^11.8.5": - version: 11.8.6 - resolution: "got@npm:11.8.6" - dependencies: - "@sindresorhus/is": "npm:^4.0.0" - "@szmarczak/http-timer": "npm:^4.0.5" - "@types/cacheable-request": "npm:^6.0.1" - "@types/responselike": "npm:^1.0.0" - cacheable-lookup: "npm:^5.0.3" - cacheable-request: "npm:^7.0.2" - decompress-response: "npm:^6.0.0" - http2-wrapper: "npm:^1.0.0-beta.5.2" - lowercase-keys: "npm:^2.0.0" - p-cancelable: "npm:^2.0.0" - responselike: "npm:^2.0.0" - checksum: 10c0/754dd44877e5cf6183f1e989ff01c648d9a4719e357457bd4c78943911168881f1cfb7b2cb15d885e2105b3ad313adb8f017a67265dd7ade771afdb261ee8cb1 - languageName: node - linkType: hard - -"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11": +"graceful-fs@npm:^4.2.11": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 languageName: node linkType: hard -"has-property-descriptors@npm:^1.0.0": - version: 1.0.2 - resolution: "has-property-descriptors@npm:1.0.2" - dependencies: - es-define-property: "npm:^1.0.0" - checksum: 10c0/253c1f59e80bb476cf0dde8ff5284505d90c3bdb762983c3514d36414290475fe3fd6f574929d84de2a8eec00d35cf07cb6776205ff32efd7c50719125f00236 - languageName: node - linkType: hard - -"http-cache-semantics@npm:^4.0.0": - version: 4.2.0 - resolution: "http-cache-semantics@npm:4.2.0" - checksum: 10c0/45b66a945cf13ec2d1f29432277201313babf4a01d9e52f44b31ca923434083afeca03f18417f599c9ab3d0e7b618ceb21257542338b57c54b710463b4a53e37 - languageName: node - linkType: hard - -"http2-wrapper@npm:^1.0.0-beta.5.2": - version: 1.0.3 - resolution: "http2-wrapper@npm:1.0.3" - dependencies: - quick-lru: "npm:^5.1.1" - resolve-alpn: "npm:^1.0.0" - checksum: 10c0/6a9b72a033e9812e1476b9d776ce2f387bc94bc46c88aea0d5dab6bd47d0a539b8178830e77054dd26d1142c866d515a28a4dc7c3ff4232c88ff2ebe4f5d12d1 - languageName: node - linkType: hard - "husky@npm:^9.1.7": version: 9.1.7 resolution: "husky@npm:9.1.7" @@ -1613,41 +1284,6 @@ __metadata: languageName: node linkType: hard -"json-buffer@npm:3.0.1": - version: 3.0.1 - resolution: "json-buffer@npm:3.0.1" - checksum: 10c0/0d1c91569d9588e7eef2b49b59851f297f3ab93c7b35c7c221e288099322be6b562767d11e4821da500f3219542b9afd2e54c5dc573107c1126ed1080f8e96d7 - languageName: node - linkType: hard - -"json-stringify-safe@npm:^5.0.1": - version: 5.0.1 - resolution: "json-stringify-safe@npm:5.0.1" - checksum: 10c0/7dbf35cd0411d1d648dceb6d59ce5857ec939e52e4afc37601aa3da611f0987d5cee5b38d58329ceddf3ed48bd7215229c8d52059ab01f2444a338bf24ed0f37 - languageName: node - linkType: hard - -"jsonfile@npm:^4.0.0": - version: 4.0.0 - resolution: "jsonfile@npm:4.0.0" - dependencies: - graceful-fs: "npm:^4.1.6" - dependenciesMeta: - graceful-fs: - optional: true - checksum: 10c0/7dc94b628d57a66b71fb1b79510d460d662eb975b5f876d723f81549c2e9cd316d58a2ddf742b2b93a4fa6b17b2accaf1a738a0e2ea114bdfb13a32e5377e480 - languageName: node - linkType: hard - -"keyv@npm:^4.0.0": - version: 4.5.4 - resolution: "keyv@npm:4.5.4" - dependencies: - json-buffer: "npm:3.0.1" - checksum: 10c0/aa52f3c5e18e16bb6324876bb8b59dd02acf782a4b789c7b2ae21107fab95fab3890ed448d4f8dba80ce05391eeac4bfabb4f02a20221342982f806fa2cf271e - languageName: node - linkType: hard - "lightningcss-android-arm64@npm:1.32.0": version: 1.32.0 resolution: "lightningcss-android-arm64@npm:1.32.0" @@ -1831,13 +1467,6 @@ __metadata: languageName: node linkType: hard -"lowercase-keys@npm:^2.0.0": - version: 2.0.0 - resolution: "lowercase-keys@npm:2.0.0" - checksum: 10c0/f82a2b3568910509da4b7906362efa40f5b54ea14c2584778ddb313226f9cbf21020a5db35f9b9a0e95847a9b781d548601f31793d736b22a2b8ae8eb9ab1082 - languageName: node - linkType: hard - "lru-cache@npm:^11.0.0": version: 11.1.0 resolution: "lru-cache@npm:11.1.0" @@ -1877,15 +1506,6 @@ __metadata: languageName: node linkType: hard -"matcher@npm:^3.0.0": - version: 3.0.0 - resolution: "matcher@npm:3.0.0" - dependencies: - escape-string-regexp: "npm:^4.0.0" - checksum: 10c0/2edf24194a2879690bcdb29985fc6bc0d003df44e04df21ebcac721fa6ce2f6201c579866bb92f9380bffe946f11ecd8cd31f34117fb67ebf8aca604918e127e - languageName: node - linkType: hard - "mdurl@npm:^2.0.0": version: 2.0.0 resolution: "mdurl@npm:2.0.0" @@ -1910,20 +1530,6 @@ __metadata: languageName: node linkType: hard -"mimic-response@npm:^1.0.0": - version: 1.0.1 - resolution: "mimic-response@npm:1.0.1" - checksum: 10c0/c5381a5eae997f1c3b5e90ca7f209ed58c3615caeee850e85329c598f0c000ae7bec40196580eef1781c60c709f47258131dab237cad8786f8f56750594f27fa - languageName: node - linkType: hard - -"mimic-response@npm:^3.1.0": - version: 3.1.0 - resolution: "mimic-response@npm:3.1.0" - checksum: 10c0/0d6f07ce6e03e9e4445bee655202153bdb8a98d67ee8dc965ac140900d7a2688343e6b4c9a72cfc9ef2f7944dfd76eef4ab2482eb7b293a68b84916bac735362 - languageName: node - linkType: hard - "minimatch@npm:^10.0.1, minimatch@npm:^10.1.1": version: 10.2.4 resolution: "minimatch@npm:10.2.4" @@ -1979,20 +1585,6 @@ __metadata: languageName: node linkType: hard -"normalize-url@npm:^6.0.1": - version: 6.1.0 - resolution: "normalize-url@npm:6.1.0" - checksum: 10c0/95d948f9bdd2cfde91aa786d1816ae40f8262946e13700bf6628105994fe0ff361662c20af3961161c38a119dc977adeb41fc0b41b1745eb77edaaf9cb22db23 - languageName: node - linkType: hard - -"object-keys@npm:^1.1.1": - version: 1.1.1 - resolution: "object-keys@npm:1.1.1" - checksum: 10c0/b11f7ccdbc6d406d1f186cdadb9d54738e347b2692a14439ca5ac70c225fa6db46db809711b78589866d47b25fc3e8dee0b4c722ac751e11180f9380e3d8601d - languageName: node - linkType: hard - "obug@npm:^2.1.1": version: 2.1.1 resolution: "obug@npm:2.1.1" @@ -2000,15 +1592,6 @@ __metadata: languageName: node linkType: hard -"once@npm:^1.3.1, once@npm:^1.4.0": - version: 1.4.0 - resolution: "once@npm:1.4.0" - dependencies: - wrappy: "npm:1" - checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0 - languageName: node - linkType: hard - "onetime@npm:^7.0.0": version: 7.0.0 resolution: "onetime@npm:7.0.0" @@ -2189,13 +1772,6 @@ __metadata: languageName: node linkType: hard -"p-cancelable@npm:^2.0.0": - version: 2.1.1 - resolution: "p-cancelable@npm:2.1.1" - checksum: 10c0/8c6dc1f8dd4154fd8b96a10e55a3a832684c4365fb9108056d89e79fbf21a2465027c04a59d0d797b5ffe10b54a61a32043af287d5c4860f1e996cbdbc847f01 - languageName: node - linkType: hard - "package-json-from-dist@npm:^1.0.0": version: 1.0.1 resolution: "package-json-from-dist@npm:1.0.1" @@ -2227,13 +1803,6 @@ __metadata: languageName: node linkType: hard -"pend@npm:~1.2.0": - version: 1.2.0 - resolution: "pend@npm:1.2.0" - checksum: 10c0/8a87e63f7a4afcfb0f9f77b39bb92374afc723418b9cb716ee4257689224171002e07768eeade4ecd0e86f1fa3d8f022994219fb45634f2dbd78c6803e452458 - languageName: node - linkType: hard - "picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" @@ -2293,16 +1862,6 @@ __metadata: languageName: node linkType: hard -"pump@npm:^3.0.0": - version: 3.0.4 - resolution: "pump@npm:3.0.4" - dependencies: - end-of-stream: "npm:^1.1.0" - once: "npm:^1.3.1" - checksum: 10c0/2780e66b5471c19e3e3e1063b84f3f6a3a08367f24c5ed552f98cd5901e6ada27c7ad6495d4244f553fd03b01884a4561933064f053f47c8994d84fd352768ea - languageName: node - linkType: hard - "punycode.js@npm:^2.3.1": version: 2.3.1 resolution: "punycode.js@npm:2.3.1" @@ -2310,29 +1869,6 @@ __metadata: languageName: node linkType: hard -"quick-lru@npm:^5.1.1": - version: 5.1.1 - resolution: "quick-lru@npm:5.1.1" - checksum: 10c0/a24cba5da8cec30d70d2484be37622580f64765fb6390a928b17f60cd69e8dbd32a954b3ff9176fa1b86d86ff2ba05252fae55dc4d40d0291c60412b0ad096da - languageName: node - linkType: hard - -"resolve-alpn@npm:^1.0.0": - version: 1.2.1 - resolution: "resolve-alpn@npm:1.2.1" - checksum: 10c0/b70b29c1843bc39781ef946c8cd4482e6d425976599c0f9c138cec8209e4e0736161bf39319b01676a847000085dfdaf63583c6fb4427bf751a10635bd2aa0c4 - languageName: node - linkType: hard - -"responselike@npm:^2.0.0": - version: 2.0.1 - resolution: "responselike@npm:2.0.1" - dependencies: - lowercase-keys: "npm:^2.0.0" - checksum: 10c0/360b6deb5f101a9f8a4174f7837c523c3ec78b7ca8a7c1d45a1062b303659308a23757e318b1e91ed8684ad1205721142dd664d94771cd63499353fd4ee732b5 - languageName: node - linkType: hard - "restore-cursor@npm:^5.0.0": version: 5.1.0 resolution: "restore-cursor@npm:5.1.0" @@ -2350,20 +1886,6 @@ __metadata: languageName: node linkType: hard -"roarr@npm:^2.15.3": - version: 2.15.4 - resolution: "roarr@npm:2.15.4" - dependencies: - boolean: "npm:^3.0.1" - detect-node: "npm:^2.0.4" - globalthis: "npm:^1.0.1" - json-stringify-safe: "npm:^5.0.1" - semver-compare: "npm:^1.0.0" - sprintf-js: "npm:^1.1.2" - checksum: 10c0/7d01d4c14513c461778dd673a8f9e53255221f8d04173aafeb8e11b23d8b659bb83f1c90cfe81af7f9c213b8084b404b918108fd792bda76678f555340cc64ec - languageName: node - linkType: hard - "rolldown@npm:1.0.3": version: 1.0.3 resolution: "rolldown@npm:1.0.3" @@ -2422,31 +1944,6 @@ __metadata: languageName: node linkType: hard -"semver-compare@npm:^1.0.0": - version: 1.0.0 - resolution: "semver-compare@npm:1.0.0" - checksum: 10c0/9ef4d8b81847556f0865f46ddc4d276bace118c7cb46811867af82e837b7fc473911981d5a0abc561fa2db487065572217e5b06e18701c4281bcdd2a1affaff1 - languageName: node - linkType: hard - -"semver@npm:^6.2.0": - version: 6.3.1 - resolution: "semver@npm:6.3.1" - bin: - semver: bin/semver.js - checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d - languageName: node - linkType: hard - -"semver@npm:^7.3.2": - version: 7.8.5 - resolution: "semver@npm:7.8.5" - bin: - semver: bin/semver.js - checksum: 10c0/b1f3127a5be8125a94f37188b361c212466c292c6910adce3ec106cff5dc211ccaedc4739c11bb70fda59d6fc1f040a9bca289f4e093451521a2372e5231fe0c - languageName: node - linkType: hard - "semver@npm:^7.6.3": version: 7.7.2 resolution: "semver@npm:7.7.2" @@ -2456,15 +1953,6 @@ __metadata: languageName: node linkType: hard -"serialize-error@npm:^7.0.1": - version: 7.0.1 - resolution: "serialize-error@npm:7.0.1" - dependencies: - type-fest: "npm:^0.13.1" - checksum: 10c0/7982937d578cd901276c8ab3e2c6ed8a4c174137730f1fb0402d005af209a0e84d04acc874e317c936724c7b5b26c7a96ff7e4b8d11a469f4924a4b0ea814c05 - languageName: node - linkType: hard - "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -2522,13 +2010,6 @@ __metadata: languageName: node linkType: hard -"sprintf-js@npm:^1.1.2": - version: 1.1.3 - resolution: "sprintf-js@npm:1.1.3" - checksum: 10c0/09270dc4f30d479e666aee820eacd9e464215cdff53848b443964202bf4051490538e5dd1b42e1a65cf7296916ca17640aebf63dae9812749c7542ee5f288dec - languageName: node - linkType: hard - "stackback@npm:0.0.2": version: 0.0.2 resolution: "stackback@npm:0.0.2" @@ -2674,13 +2155,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.13.1": - version: 0.13.1 - resolution: "type-fest@npm:0.13.1" - checksum: 10c0/0c0fa07ae53d4e776cf4dac30d25ad799443e9eef9226f9fddbb69242db86b08584084a99885cfa5a9dfe4c063ebdc9aa7b69da348e735baede8d43f1aeae93b - languageName: node - linkType: hard - "typedoc@npm:~0.28.0": version: 0.28.18 resolution: "typedoc@npm:0.28.18" @@ -2739,6 +2213,13 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:~7.18.0": + version: 7.18.2 + resolution: "undici-types@npm:7.18.2" + checksum: 10c0/85a79189113a238959d7a647368e4f7c5559c3a404ebdb8fc4488145ce9426fcd82252a844a302798dfc0e37e6fb178ff481ed03bc4caf634c5757d9ef43521d + languageName: node + linkType: hard + "undici@npm:^7.24.4": version: 7.28.0 resolution: "undici@npm:7.28.0" @@ -2746,13 +2227,6 @@ __metadata: languageName: node linkType: hard -"universalify@npm:^0.1.0": - version: 0.1.2 - resolution: "universalify@npm:0.1.2" - checksum: 10c0/e70e0339f6b36f34c9816f6bf9662372bd241714dc77508d231d08386d94f2c4aa1ba1318614f92015f40d45aae1b9075cd30bd490efbe39387b60a76ca3f045 - languageName: node - linkType: hard - "vite@npm:^6.0.0 || ^7.0.0 || ^8.0.0": version: 8.0.16 resolution: "vite@npm:8.0.16" @@ -2928,13 +2402,6 @@ __metadata: languageName: node linkType: hard -"wrappy@npm:1": - version: 1.0.2 - resolution: "wrappy@npm:1.0.2" - checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0 - languageName: node - linkType: hard - "xmlbuilder@npm:>=11.0.1, xmlbuilder@npm:^15.1.1": version: 15.1.1 resolution: "xmlbuilder@npm:15.1.1" @@ -2950,13 +2417,3 @@ __metadata: checksum: 10c0/ddff0e11c1b467728d7eb4633db61c5f5de3d8e9373cf84d08fb0cdee03e1f58f02b9f1c51a4a8a865751695addbd465a77f73f1079be91fe5493b29c305fd77 languageName: node linkType: hard - -"yauzl@npm:^2.10.0": - version: 2.10.0 - resolution: "yauzl@npm:2.10.0" - dependencies: - buffer-crc32: "npm:~0.2.3" - fd-slicer: "npm:~1.1.0" - checksum: 10c0/f265002af7541b9ec3589a27f5fb8f11cf348b53cc15e2751272e3c062cd73f3e715bc72d43257de71bbaecae446c3f1b14af7559e8ab0261625375541816422 - languageName: node - linkType: hard