@gtkx/cli 2.0.0-beta.1 → 2.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builder.d.ts +1 -0
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +17 -5
- package/dist/builder.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +9 -1
- package/dist/cli.js.map +1 -1
- package/dist/codegen/reference.d.ts.map +1 -1
- package/dist/codegen/reference.js +1 -0
- package/dist/codegen/reference.js.map +1 -1
- package/dist/codegen/run-codegen.d.ts +4 -2
- package/dist/codegen/run-codegen.d.ts.map +1 -1
- package/dist/codegen/run-codegen.js +15 -16
- package/dist/codegen/run-codegen.js.map +1 -1
- package/dist/codegen/store-resolver.d.ts +2 -1
- package/dist/codegen/store-resolver.d.ts.map +1 -1
- package/dist/codegen/store-resolver.js +4 -3
- package/dist/codegen/store-resolver.js.map +1 -1
- package/dist/commands/build.d.ts +5 -0
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +83 -10
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/codegen.d.ts +1 -0
- package/dist/commands/codegen.d.ts.map +1 -1
- package/dist/commands/codegen.js +6 -5
- package/dist/commands/codegen.js.map +1 -1
- package/dist/commands/deploy.d.ts +1 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +4 -2
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +9 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +29 -4
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +1 -0
- package/dist/commands/docs.js.map +1 -1
- package/dist/deploy/freedesktop/metainfo.d.ts.map +1 -1
- package/dist/deploy/freedesktop/metainfo.js +41 -2
- package/dist/deploy/freedesktop/metainfo.js.map +1 -1
- package/dist/deploy/freedesktop/validate.d.ts.map +1 -1
- package/dist/deploy/freedesktop/validate.js +10 -4
- package/dist/deploy/freedesktop/validate.js.map +1 -1
- package/dist/deploy/nfpm/config.d.ts +3 -2
- package/dist/deploy/nfpm/config.d.ts.map +1 -1
- package/dist/deploy/nfpm/config.js +7 -4
- package/dist/deploy/nfpm/config.js.map +1 -1
- package/dist/deploy/nfpm/contents.d.ts.map +1 -1
- package/dist/deploy/nfpm/contents.js +8 -0
- package/dist/deploy/nfpm/contents.js.map +1 -1
- package/dist/deploy/node-runtime/elf.d.ts +2 -1
- package/dist/deploy/node-runtime/elf.d.ts.map +1 -1
- package/dist/deploy/node-runtime/elf.js +32 -5
- package/dist/deploy/node-runtime/elf.js.map +1 -1
- package/dist/deploy/node-runtime/index.d.ts +2 -1
- package/dist/deploy/node-runtime/index.d.ts.map +1 -1
- package/dist/deploy/node-runtime/index.js +75 -5
- package/dist/deploy/node-runtime/index.js.map +1 -1
- package/dist/deploy/notices/node-runtime.js +2 -2
- package/dist/deploy/notices/node-runtime.js.map +1 -1
- package/dist/deploy/payload/launcher.d.ts.map +1 -1
- package/dist/deploy/payload/launcher.js +14 -1
- package/dist/deploy/payload/launcher.js.map +1 -1
- package/dist/deploy/payload/stage.js +1 -1
- package/dist/deploy/payload/stage.js.map +1 -1
- package/dist/deploy/run-deploy.d.ts +1 -0
- package/dist/deploy/run-deploy.d.ts.map +1 -1
- package/dist/deploy/run-deploy.js +100 -14
- package/dist/deploy/run-deploy.js.map +1 -1
- package/dist/deploy/settings/build-manifest.d.ts +6 -1
- package/dist/deploy/settings/build-manifest.d.ts.map +1 -1
- package/dist/deploy/settings/build-manifest.js +15 -4
- package/dist/deploy/settings/build-manifest.js.map +1 -1
- package/dist/deploy/settings/extra-files.d.ts +1 -1
- package/dist/deploy/settings/extra-files.d.ts.map +1 -1
- package/dist/deploy/settings/extra-files.js +22 -1
- package/dist/deploy/settings/extra-files.js.map +1 -1
- package/dist/deploy/settings/index.d.ts +1 -0
- package/dist/deploy/settings/index.d.ts.map +1 -1
- package/dist/deploy/settings/index.js +2 -1
- package/dist/deploy/settings/index.js.map +1 -1
- package/dist/deploy/settings/paths.d.ts +2 -1
- package/dist/deploy/settings/paths.d.ts.map +1 -1
- package/dist/deploy/settings/paths.js +113 -5
- package/dist/deploy/settings/paths.js.map +1 -1
- package/dist/deploy/targets/flatpak-source.d.ts.map +1 -1
- package/dist/deploy/targets/flatpak-source.js +11 -2
- package/dist/deploy/targets/flatpak-source.js.map +1 -1
- package/dist/deploy/targets/nfpm-target.d.ts.map +1 -1
- package/dist/deploy/targets/nfpm-target.js +12 -7
- package/dist/deploy/targets/nfpm-target.js.map +1 -1
- package/dist/deploy/types.d.ts +1 -0
- package/dist/deploy/types.d.ts.map +1 -1
- package/dist/deploy/types.js.map +1 -1
- package/dist/dev/entry-env.d.ts +2 -1
- package/dist/dev/entry-env.d.ts.map +1 -1
- package/dist/dev/entry-env.js +2 -1
- package/dist/dev/entry-env.js.map +1 -1
- package/dist/dev/headless.d.ts +3 -0
- package/dist/dev/headless.d.ts.map +1 -0
- package/dist/dev/headless.js +35 -0
- package/dist/dev/headless.js.map +1 -0
- package/dist/dev/runner-deps.d.ts +1 -1
- package/dist/dev/runner-deps.d.ts.map +1 -1
- package/dist/dev/runner-deps.js +3 -3
- package/dist/dev/runner-deps.js.map +1 -1
- package/dist/dev/runner-main.d.ts.map +1 -1
- package/dist/dev/runner-main.js +8 -3
- package/dist/dev/runner-main.js.map +1 -1
- package/dist/dev/supervisor.d.ts +1 -0
- package/dist/dev/supervisor.d.ts.map +1 -1
- package/dist/dev/supervisor.js +4 -3
- package/dist/dev/supervisor.js.map +1 -1
- package/dist/i18n/catalogs.d.ts.map +1 -1
- package/dist/i18n/catalogs.js +1 -0
- package/dist/i18n/catalogs.js.map +1 -1
- package/dist/i18n/source-messages.d.ts.map +1 -1
- package/dist/i18n/source-messages.js +960 -8
- package/dist/i18n/source-messages.js.map +1 -1
- package/dist/internal/build-manifest.d.ts +5 -2
- package/dist/internal/build-manifest.d.ts.map +1 -1
- package/dist/internal/build-manifest.js +15 -2
- package/dist/internal/build-manifest.js.map +1 -1
- package/dist/internal/build-output.d.ts +8 -0
- package/dist/internal/build-output.d.ts.map +1 -0
- package/dist/internal/build-output.js +79 -0
- package/dist/internal/build-output.js.map +1 -0
- package/dist/internal/docs-elements.d.ts +1 -0
- package/dist/internal/docs-elements.d.ts.map +1 -1
- package/dist/internal/docs-elements.js +5 -4
- package/dist/internal/docs-elements.js.map +1 -1
- package/dist/internal/entry-arg.d.ts +4 -1
- package/dist/internal/entry-arg.d.ts.map +1 -1
- package/dist/internal/entry-arg.js +7 -1
- package/dist/internal/entry-arg.js.map +1 -1
- package/dist/internal/errors.d.ts +2 -1
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +1 -1
- package/dist/internal/errors.js.map +1 -1
- package/dist/internal/output-directory.d.ts +15 -0
- package/dist/internal/output-directory.d.ts.map +1 -0
- package/dist/internal/output-directory.js +490 -0
- package/dist/internal/output-directory.js.map +1 -0
- package/dist/internal/parent-process.d.ts +12 -0
- package/dist/internal/parent-process.d.ts.map +1 -0
- package/dist/internal/parent-process.js +74 -0
- package/dist/internal/parent-process.js.map +1 -0
- package/dist/internal/prepare-project.d.ts +2 -0
- package/dist/internal/prepare-project.d.ts.map +1 -1
- package/dist/internal/prepare-project.js +3 -3
- package/dist/internal/prepare-project.js.map +1 -1
- package/dist/internal/source-imports.js +1 -1
- package/dist/internal/source-imports.js.map +1 -1
- package/dist/mcp/client.js +2 -2
- package/dist/mcp/client.js.map +1 -1
- package/dist/vite-plugins/build-manifest.d.ts +5 -1
- package/dist/vite-plugins/build-manifest.d.ts.map +1 -1
- package/dist/vite-plugins/build-manifest.js +2 -1
- package/dist/vite-plugins/build-manifest.js.map +1 -1
- package/dist/vite-plugins/ensure-store.d.ts +1 -1
- package/dist/vite-plugins/ensure-store.d.ts.map +1 -1
- package/dist/vite-plugins/ensure-store.js +2 -2
- package/dist/vite-plugins/ensure-store.js.map +1 -1
- package/dist/vite-plugins/i18n.d.ts.map +1 -1
- package/dist/vite-plugins/i18n.js +58 -6
- package/dist/vite-plugins/i18n.js.map +1 -1
- package/dist/vite-plugins/index.d.ts +8 -1
- package/dist/vite-plugins/index.d.ts.map +1 -1
- package/dist/vite-plugins/index.js +6 -2
- package/dist/vite-plugins/index.js.map +1 -1
- package/dist/vite-plugins/native.d.ts.map +1 -1
- package/dist/vite-plugins/native.js +0 -4
- package/dist/vite-plugins/native.js.map +1 -1
- package/dist/vite-plugins/self-contained.d.ts.map +1 -1
- package/dist/vite-plugins/self-contained.js +159 -158
- package/dist/vite-plugins/self-contained.js.map +1 -1
- package/dist/vite-plugins/settings-worker-env.d.ts +1 -1
- package/dist/vite-plugins/settings-worker-env.d.ts.map +1 -1
- package/dist/vite-plugins/settings-worker-env.js +2 -2
- package/dist/vite-plugins/settings-worker-env.js.map +1 -1
- package/dist/vitest-plugin.d.ts +2 -1
- package/dist/vitest-plugin.d.ts.map +1 -1
- package/dist/vitest-plugin.js +6 -6
- package/dist/vitest-plugin.js.map +1 -1
- package/package.json +10 -9
- package/src/builder.ts +18 -5
- package/src/cli.ts +9 -1
- package/src/codegen/reference.ts +1 -0
- package/src/codegen/run-codegen.ts +17 -19
- package/src/codegen/store-resolver.ts +5 -3
- package/src/commands/build.ts +13 -2
- package/src/commands/codegen.ts +6 -5
- package/src/commands/deploy.ts +4 -2
- package/src/commands/dev.ts +38 -4
- package/src/commands/docs.ts +1 -0
- package/src/deploy/freedesktop/metainfo.ts +73 -21
- package/src/deploy/freedesktop/validate.ts +12 -4
- package/src/deploy/nfpm/config.ts +13 -4
- package/src/deploy/nfpm/contents.ts +8 -0
- package/src/deploy/node-runtime/elf.ts +43 -5
- package/src/deploy/node-runtime/index.ts +107 -6
- package/src/deploy/notices/node-runtime.ts +2 -2
- package/src/deploy/payload/launcher.ts +20 -1
- package/src/deploy/payload/stage.ts +1 -1
- package/src/deploy/run-deploy.ts +56 -16
- package/src/deploy/settings/build-manifest.ts +28 -3
- package/src/deploy/settings/extra-files.ts +26 -2
- package/src/deploy/settings/index.ts +3 -1
- package/src/deploy/settings/paths.ts +70 -5
- package/src/deploy/targets/flatpak-source.ts +13 -2
- package/src/deploy/targets/nfpm-target.ts +13 -6
- package/src/deploy/types.ts +1 -0
- package/src/dev/entry-env.ts +2 -1
- package/src/dev/headless.ts +40 -0
- package/src/dev/runner-deps.ts +3 -3
- package/src/dev/runner-main.ts +10 -3
- package/src/dev/supervisor.ts +6 -3
- package/src/i18n/catalogs.ts +1 -0
- package/src/i18n/source-messages.ts +1429 -28
- package/src/internal/build-manifest.ts +25 -1
- package/src/internal/build-output.ts +113 -0
- package/src/internal/docs-elements.ts +10 -4
- package/src/internal/entry-arg.ts +8 -1
- package/src/internal/errors.ts +1 -1
- package/src/internal/output-directory.ts +699 -0
- package/src/internal/parent-process.ts +110 -0
- package/src/internal/prepare-project.ts +5 -5
- package/src/internal/source-imports.ts +1 -1
- package/src/mcp/client.ts +2 -2
- package/src/vite-plugins/build-manifest.ts +7 -1
- package/src/vite-plugins/ensure-store.ts +2 -2
- package/src/vite-plugins/i18n.ts +83 -5
- package/src/vite-plugins/index.ts +14 -7
- package/src/vite-plugins/native.ts +0 -5
- package/src/vite-plugins/self-contained.ts +184 -185
- package/src/vite-plugins/settings-worker-env.ts +2 -2
- package/src/vitest-plugin.ts +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry-arg.d.ts","sourceRoot":"","sources":["../../src/internal/entry-arg.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAS5D,QAAA,MAAM,MAAM,EAAE;IAAE,GAAG,EAAE,YAAY,CAAA;CAKhC,CAAC;AAEF,QAAA,MAAM,QAAQ,EAAE;IAAE,KAAK,EAAE,gBAAgB,CAAC;IAAC,GAAG,EAAE,YAAY,CAAA;CAO3D,CAAC;AAEF,QAAA,MAAM,UAAU,GAAI,MAAM;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,KAAG,MAAwD,CAAC;AA+BtG,QAAA,MAAM,YAAY,GAAI,KAAK,MAAM,EAAE,OAAO,MAAM,GAAG,SAAS,KAAG,MACK,CAAC;AAErE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"entry-arg.d.ts","sourceRoot":"","sources":["../../src/internal/entry-arg.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAS5D,QAAA,MAAM,MAAM,EAAE;IAAE,GAAG,EAAE,YAAY,CAAA;CAKhC,CAAC;AAEF,QAAA,MAAM,SAAS,EAAE;IAAE,MAAM,EAAE,YAAY,CAAA;CAKtC,CAAC;AAEF,QAAA,MAAM,QAAQ,EAAE;IAAE,KAAK,EAAE,gBAAgB,CAAC;IAAC,GAAG,EAAE,YAAY,CAAA;CAO3D,CAAC;AAEF,QAAA,MAAM,UAAU,GAAI,MAAM;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,KAAG,MAAwD,CAAC;AA+BtG,QAAA,MAAM,YAAY,GAAI,KAAK,MAAM,EAAE,OAAO,MAAM,GAAG,SAAS,KAAG,MACK,CAAC;AAErE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -10,6 +10,12 @@ const cwdArg = {
|
|
|
10
10
|
description: "Project root (default: current working directory)",
|
|
11
11
|
},
|
|
12
12
|
};
|
|
13
|
+
const configArg = {
|
|
14
|
+
config: {
|
|
15
|
+
type: "string",
|
|
16
|
+
description: "Project-relative configuration file (default: gtkx.config.*)",
|
|
17
|
+
},
|
|
18
|
+
};
|
|
13
19
|
const entryArg = {
|
|
14
20
|
entry: {
|
|
15
21
|
type: "positional",
|
|
@@ -39,5 +45,5 @@ const resolveGivenEntry = (cwd, entry) => {
|
|
|
39
45
|
return path;
|
|
40
46
|
};
|
|
41
47
|
const resolveEntry = (cwd, entry) => entry ? resolveGivenEntry(cwd, entry) : resolveDefaultEntry(cwd);
|
|
42
|
-
export { cwdArg, entryArg, resolveCwd, resolveEntry };
|
|
48
|
+
export { configArg, cwdArg, entryArg, resolveCwd, resolveEntry };
|
|
43
49
|
//# sourceMappingURL=entry-arg.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry-arg.js","sourceRoot":"","sources":["../../src/internal/entry-arg.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,kBAAkB,GAAG,WAAW,CAAC;AACvC,MAAM,wBAAwB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAChE,MAAM,wBAAwB,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,kBAAkB,GAAG,SAAS,EAAE,CAAC,CAAC;AAClH,MAAM,aAAa,GAAG,GAAG,kBAAkB,IAAI,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAErF,MAAM,MAAM,GAA0B;IAClC,GAAG,EAAE;QACD,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,mDAAmD;KACnE;CACJ,CAAC;AAEF,MAAM,QAAQ,GAAmD;IAC7D,KAAK,EAAE;QACH,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,wBAAwB,aAAa,GAAG;QACrD,QAAQ,EAAE,KAAK;KAClB;IACD,GAAG,MAAM;CACZ,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,IAAsB,EAAU,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AACtG,MAAM,MAAM,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAEvG,MAAM,wBAAwB,GAAG,CAAC,GAAW,EAAS,EAAE,CACpD,IAAI,KAAK,CACL,0BAA0B,GAAG,gBAAgB,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;IACpF,qCAAqC,CACxC,CAAC;AAEN,MAAM,mBAAmB,GAAG,CAAC,GAAW,EAAU,EAAE;IAChD,KAAK,MAAM,SAAS,IAAI,wBAAwB,EAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAErC,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED,MAAM,wBAAwB,CAAC,GAAG,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,GAAW,EAAE,KAAa,EAAU,EAAE;IAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAEjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,GAAG,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,KAAyB,EAAU,EAAE,CACpE,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;AAErE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC","sourcesContent":["import type { PositionalArgDef, StringArgDef } from \"citty\";\nimport { statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nconst DEFAULT_ENTRY_BASE = \"src/index\";\nconst DEFAULT_ENTRY_EXTENSIONS = [\".tsx\", \".jsx\", \".ts\", \".js\"];\nconst DEFAULT_ENTRY_CANDIDATES = DEFAULT_ENTRY_EXTENSIONS.map((extension) => `${DEFAULT_ENTRY_BASE}${extension}`);\nconst DEFAULT_ENTRY = `${DEFAULT_ENTRY_BASE}{${DEFAULT_ENTRY_EXTENSIONS.join(\",\")}}`;\n\nconst cwdArg: { cwd: StringArgDef } = {\n cwd: {\n type: \"string\",\n description: \"Project root (default: current working directory)\",\n },\n};\n\nconst entryArg: { entry: PositionalArgDef; cwd: StringArgDef } = {\n entry: {\n type: \"positional\",\n description: `Entry file (default: ${DEFAULT_ENTRY})`,\n required: false,\n },\n ...cwdArg,\n};\n\nconst resolveCwd = (args: { cwd?: string }): string => (args.cwd ? resolve(args.cwd) : process.cwd());\nconst isFile = (path: string): boolean => statSync(path, { throwIfNoEntry: false })?.isFile() === true;\n\nconst missingDefaultEntryError = (cwd: string): Error =>\n new Error(\n `No entry file found in ${cwd}. Looked for ${DEFAULT_ENTRY_CANDIDATES.join(\", \")}; ` +\n \"pass the entry file as an argument.\",\n );\n\nconst resolveDefaultEntry = (cwd: string): string => {\n for (const candidate of DEFAULT_ENTRY_CANDIDATES) {\n const path = resolve(cwd, candidate);\n\n if (isFile(path)) {\n return path;\n }\n }\n\n throw missingDefaultEntryError(cwd);\n};\n\nconst resolveGivenEntry = (cwd: string, entry: string): string => {\n const path = resolve(cwd, entry);\n\n if (!isFile(path)) {\n throw new Error(`No entry file at ${path}.`);\n }\n\n return path;\n};\n\nconst resolveEntry = (cwd: string, entry: string | undefined): string =>\n entry ? resolveGivenEntry(cwd, entry) : resolveDefaultEntry(cwd);\n\nexport { cwdArg, entryArg, resolveCwd, resolveEntry };\n"]}
|
|
1
|
+
{"version":3,"file":"entry-arg.js","sourceRoot":"","sources":["../../src/internal/entry-arg.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,kBAAkB,GAAG,WAAW,CAAC;AACvC,MAAM,wBAAwB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAChE,MAAM,wBAAwB,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,kBAAkB,GAAG,SAAS,EAAE,CAAC,CAAC;AAClH,MAAM,aAAa,GAAG,GAAG,kBAAkB,IAAI,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAErF,MAAM,MAAM,GAA0B;IAClC,GAAG,EAAE;QACD,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,mDAAmD;KACnE;CACJ,CAAC;AAEF,MAAM,SAAS,GAA6B;IACxC,MAAM,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,8DAA8D;KAC9E;CACJ,CAAC;AAEF,MAAM,QAAQ,GAAmD;IAC7D,KAAK,EAAE;QACH,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,wBAAwB,aAAa,GAAG;QACrD,QAAQ,EAAE,KAAK;KAClB;IACD,GAAG,MAAM;CACZ,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,IAAsB,EAAU,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AACtG,MAAM,MAAM,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAEvG,MAAM,wBAAwB,GAAG,CAAC,GAAW,EAAS,EAAE,CACpD,IAAI,KAAK,CACL,0BAA0B,GAAG,gBAAgB,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;IACpF,qCAAqC,CACxC,CAAC;AAEN,MAAM,mBAAmB,GAAG,CAAC,GAAW,EAAU,EAAE;IAChD,KAAK,MAAM,SAAS,IAAI,wBAAwB,EAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAErC,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED,MAAM,wBAAwB,CAAC,GAAG,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,GAAW,EAAE,KAAa,EAAU,EAAE;IAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAEjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,GAAG,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,KAAyB,EAAU,EAAE,CACpE,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;AAErE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC","sourcesContent":["import type { PositionalArgDef, StringArgDef } from \"citty\";\nimport { statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nconst DEFAULT_ENTRY_BASE = \"src/index\";\nconst DEFAULT_ENTRY_EXTENSIONS = [\".tsx\", \".jsx\", \".ts\", \".js\"];\nconst DEFAULT_ENTRY_CANDIDATES = DEFAULT_ENTRY_EXTENSIONS.map((extension) => `${DEFAULT_ENTRY_BASE}${extension}`);\nconst DEFAULT_ENTRY = `${DEFAULT_ENTRY_BASE}{${DEFAULT_ENTRY_EXTENSIONS.join(\",\")}}`;\n\nconst cwdArg: { cwd: StringArgDef } = {\n cwd: {\n type: \"string\",\n description: \"Project root (default: current working directory)\",\n },\n};\n\nconst configArg: { config: StringArgDef } = {\n config: {\n type: \"string\",\n description: \"Project-relative configuration file (default: gtkx.config.*)\",\n },\n};\n\nconst entryArg: { entry: PositionalArgDef; cwd: StringArgDef } = {\n entry: {\n type: \"positional\",\n description: `Entry file (default: ${DEFAULT_ENTRY})`,\n required: false,\n },\n ...cwdArg,\n};\n\nconst resolveCwd = (args: { cwd?: string }): string => (args.cwd ? resolve(args.cwd) : process.cwd());\nconst isFile = (path: string): boolean => statSync(path, { throwIfNoEntry: false })?.isFile() === true;\n\nconst missingDefaultEntryError = (cwd: string): Error =>\n new Error(\n `No entry file found in ${cwd}. Looked for ${DEFAULT_ENTRY_CANDIDATES.join(\", \")}; ` +\n \"pass the entry file as an argument.\",\n );\n\nconst resolveDefaultEntry = (cwd: string): string => {\n for (const candidate of DEFAULT_ENTRY_CANDIDATES) {\n const path = resolve(cwd, candidate);\n\n if (isFile(path)) {\n return path;\n }\n }\n\n throw missingDefaultEntryError(cwd);\n};\n\nconst resolveGivenEntry = (cwd: string, entry: string): string => {\n const path = resolve(cwd, entry);\n\n if (!isFile(path)) {\n throw new Error(`No entry file at ${path}.`);\n }\n\n return path;\n};\n\nconst resolveEntry = (cwd: string, entry: string | undefined): string =>\n entry ? resolveGivenEntry(cwd, entry) : resolveDefaultEntry(cwd);\n\nexport { configArg, cwdArg, entryArg, resolveCwd, resolveEntry };\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ArgsDef, CommandDef } from "citty";
|
|
2
|
+
declare const printError: (cause: unknown) => never;
|
|
2
3
|
declare const withErrorBoundary: <T extends ArgsDef>(command: CommandDef<T>) => CommandDef<T>;
|
|
3
|
-
export { withErrorBoundary };
|
|
4
|
+
export { printError, withErrorBoundary };
|
|
4
5
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/internal/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/internal/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAKjD,QAAA,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,KASpC,CAAC;AAEF,QAAA,MAAM,iBAAiB,GAAI,CAAC,SAAS,OAAO,EAAE,SAAS,UAAU,CAAC,CAAC,CAAC,KAAG,UAAU,CAAC,CAAC,CAiBlF,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC"}
|
package/dist/internal/errors.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/internal/errors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,MAAM,UAAU,GAAG,CAAC,KAAc,EAAS,EAAE;IACzC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAEtB,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACtD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAoB,OAAsB,EAAiB,EAAE;IACnF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAExB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACpB,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,OAAO;QACH,GAAG,OAAO;QACV,GAAG,EAAE,KAAK,EAAE,OAAO,EAAoB,EAAE;YACrC,IAAI,CAAC;gBACD,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC;QACL,CAAC;KACJ,CAAC;AACN,CAAC,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,CAAC","sourcesContent":["import type { ArgsDef, CommandDef } from \"citty\";\nimport { logger } from \"@gtkx/utils\";\n\nconst ERROR_EXIT_CODE = 1;\n\nconst printError = (cause: unknown): never => {\n const message = cause instanceof Error ? cause.message : String(cause);\n logger.error(message);\n\n if (cause instanceof Error && cause.stack !== undefined) {\n logger.debug(cause.stack);\n }\n\n process.exit(ERROR_EXIT_CODE);\n};\n\nconst withErrorBoundary = <T extends ArgsDef>(command: CommandDef<T>): CommandDef<T> => {\n const run = command.run;\n\n if (run === undefined) {\n return command;\n }\n\n return {\n ...command,\n run: async (context): Promise<unknown> => {\n try {\n return await run(context);\n } catch (error) {\n return printError(error);\n }\n },\n };\n};\n\nexport { withErrorBoundary };\n"]}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/internal/errors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,MAAM,UAAU,GAAG,CAAC,KAAc,EAAS,EAAE;IACzC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAEtB,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACtD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAoB,OAAsB,EAAiB,EAAE;IACnF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAExB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACpB,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,OAAO;QACH,GAAG,OAAO;QACV,GAAG,EAAE,KAAK,EAAE,OAAO,EAAoB,EAAE;YACrC,IAAI,CAAC;gBACD,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC;QACL,CAAC;KACJ,CAAC;AACN,CAAC,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC","sourcesContent":["import type { ArgsDef, CommandDef } from \"citty\";\nimport { logger } from \"@gtkx/utils\";\n\nconst ERROR_EXIT_CODE = 1;\n\nconst printError = (cause: unknown): never => {\n const message = cause instanceof Error ? cause.message : String(cause);\n logger.error(message);\n\n if (cause instanceof Error && cause.stack !== undefined) {\n logger.debug(cause.stack);\n }\n\n process.exit(ERROR_EXIT_CODE);\n};\n\nconst withErrorBoundary = <T extends ArgsDef>(command: CommandDef<T>): CommandDef<T> => {\n const run = command.run;\n\n if (run === undefined) {\n return command;\n }\n\n return {\n ...command,\n run: async (context): Promise<unknown> => {\n try {\n return await run(context);\n } catch (error) {\n return printError(error);\n }\n },\n };\n};\n\nexport { printError, withErrorBoundary };\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type DirectoryValidator = (path: string) => boolean;
|
|
2
|
+
type OutputDirectoryTransaction = Disposable & {
|
|
3
|
+
commit: (preservedNames?: ReadonlySet<string>, isFresh?: DirectoryValidator) => void;
|
|
4
|
+
path: string;
|
|
5
|
+
};
|
|
6
|
+
type PreparedOutputDirectory = {
|
|
7
|
+
status: "prepared";
|
|
8
|
+
transaction: OutputDirectoryTransaction;
|
|
9
|
+
} | {
|
|
10
|
+
status: "unsafe";
|
|
11
|
+
};
|
|
12
|
+
declare const readRegularFile: (path: string) => string | null;
|
|
13
|
+
declare const prepareOutputDirectory: (rootPath: string, path: string, isReusable: DirectoryValidator) => PreparedOutputDirectory;
|
|
14
|
+
export { type OutputDirectoryTransaction, prepareOutputDirectory, readRegularFile, };
|
|
15
|
+
//# sourceMappingURL=output-directory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-directory.d.ts","sourceRoot":"","sources":["../../src/internal/output-directory.ts"],"names":[],"mappings":"AAmBA,KAAK,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;AAoBpD,KAAK,0BAA0B,GAAG,UAAU,GAAG;IAC3C,MAAM,EAAE,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACrF,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AACF,KAAK,uBAAuB,GAAG;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,WAAW,EAAE,0BAA0B,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,CAAC;AAiBtH,QAAA,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,MAAM,GAAG,IAkBhD,CAAC;AAklBF,QAAA,MAAM,sBAAsB,GACxB,UAAU,MAAM,EAChB,MAAM,MAAM,EACZ,YAAY,kBAAkB,KAC/B,uBAgBF,CAAC;AAEF,OAAO,EACH,KAAK,0BAA0B,EAC/B,sBAAsB,EACtB,eAAe,GAClB,CAAC"}
|
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
import { closeSync, constants, fstatSync, lstatSync, mkdirSync, mkdtempSync, openSync, readdirSync, readFileSync, realpathSync, renameSync, rmdirSync, rmSync, } from "node:fs";
|
|
2
|
+
import { basename, dirname, isAbsolute, join, relative, sep } from "node:path";
|
|
3
|
+
const hasErrorCode = (value, code) => typeof value === "object" && value !== null && "code" in value && value.code === code;
|
|
4
|
+
const readRegularFile = (path) => {
|
|
5
|
+
let descriptor = null;
|
|
6
|
+
try {
|
|
7
|
+
descriptor = openSync(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
8
|
+
if (!fstatSync(descriptor).isFile()) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return readFileSync(descriptor, "utf8");
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
finally {
|
|
17
|
+
if (descriptor !== null) {
|
|
18
|
+
closeSync(descriptor);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const openDirectoryLease = (path) => {
|
|
23
|
+
let descriptor = null;
|
|
24
|
+
try {
|
|
25
|
+
descriptor = openSync(path, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
26
|
+
const stats = fstatSync(descriptor, { bigint: true });
|
|
27
|
+
let retainedDescriptor = descriptor;
|
|
28
|
+
return {
|
|
29
|
+
identity: { device: stats.dev, inode: stats.ino },
|
|
30
|
+
path: join("/proc/self/fd", String(descriptor)),
|
|
31
|
+
release: () => {
|
|
32
|
+
if (retainedDescriptor === null) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const releasedDescriptor = retainedDescriptor;
|
|
36
|
+
retainedDescriptor = null;
|
|
37
|
+
closeSync(releasedDescriptor);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
if (descriptor !== null) {
|
|
43
|
+
closeSync(descriptor);
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const readDirectoryIdentity = (path) => {
|
|
49
|
+
const lease = openDirectoryLease(path);
|
|
50
|
+
if (lease === null) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
lease.release();
|
|
54
|
+
return lease.identity;
|
|
55
|
+
};
|
|
56
|
+
const hasDirectoryIdentity = (path, expected) => {
|
|
57
|
+
const actual = readDirectoryIdentity(path);
|
|
58
|
+
return actual !== null && actual.device === expected.device && actual.inode === expected.inode;
|
|
59
|
+
};
|
|
60
|
+
const hasResolvedDirectoryIdentity = (path, expected) => {
|
|
61
|
+
try {
|
|
62
|
+
return hasDirectoryIdentity(realpathSync(path), expected);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const capturePath = (source, destination) => {
|
|
69
|
+
try {
|
|
70
|
+
renameSync(source, destination);
|
|
71
|
+
return "captured";
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
if (hasErrorCode(error, "ENOENT")) {
|
|
75
|
+
return "missing";
|
|
76
|
+
}
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const createQuarantineDirectory = (parent, displayParent) => {
|
|
81
|
+
const created = mkdtempSync(join(parent.path, ".gtkx-output-"));
|
|
82
|
+
const name = basename(created);
|
|
83
|
+
const entry = join(parent.path, name);
|
|
84
|
+
const lease = openDirectoryLease(entry);
|
|
85
|
+
if (lease === null) {
|
|
86
|
+
rmdirSync(entry);
|
|
87
|
+
throw new Error("Could not secure the output quarantine directory");
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
displayPath: join(displayParent, name),
|
|
91
|
+
path: lease.path,
|
|
92
|
+
release: lease.release,
|
|
93
|
+
remove: () => {
|
|
94
|
+
if (!hasDirectoryIdentity(entry, lease.identity)) {
|
|
95
|
+
throw new Error(`The output quarantine changed; retained files are in ${join(displayParent, name)}`);
|
|
96
|
+
}
|
|
97
|
+
rmdirSync(entry);
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
const releaseTransactionLeases = (fresh, quarantine, parent, root) => {
|
|
102
|
+
try {
|
|
103
|
+
fresh.release();
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
try {
|
|
107
|
+
quarantine.release();
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
try {
|
|
111
|
+
parent.release();
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
root.release();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const releasePreparationLeases = (quarantine, parent, root) => {
|
|
120
|
+
try {
|
|
121
|
+
quarantine.release();
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
try {
|
|
125
|
+
parent.release();
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
root.release();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
const movePath = (source, destination, operations) => {
|
|
133
|
+
renameSync(source, destination);
|
|
134
|
+
operations.push({ source, destination });
|
|
135
|
+
};
|
|
136
|
+
const moveNames = (source, destination, names, operations) => {
|
|
137
|
+
for (const name of names) {
|
|
138
|
+
movePath(join(source, name), join(destination, name), operations);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
const reverseOperations = (operations) => {
|
|
142
|
+
for (const operation of operations.toReversed()) {
|
|
143
|
+
renameSync(operation.destination, operation.source);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const overlayDirectory = (source, destination, backup, operations) => {
|
|
147
|
+
for (const name of readdirSync(source)) {
|
|
148
|
+
overlayEntry({
|
|
149
|
+
source: join(source, name),
|
|
150
|
+
destination: join(destination, name),
|
|
151
|
+
backup: join(backup, name),
|
|
152
|
+
operations,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
const overlayEntry = (request) => {
|
|
157
|
+
const destinationStats = lstatSync(request.destination, { throwIfNoEntry: false });
|
|
158
|
+
if (destinationStats === undefined) {
|
|
159
|
+
movePath(request.source, request.destination, request.operations);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const sourceStats = lstatSync(request.source);
|
|
163
|
+
if (sourceStats.isDirectory() && destinationStats.isDirectory()) {
|
|
164
|
+
overlayDirectory(request.source, request.destination, request.backup, request.operations);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (!sourceStats.isFile() || !destinationStats.isFile()) {
|
|
168
|
+
throw new Error("Cannot merge conflicting preserved output entries");
|
|
169
|
+
}
|
|
170
|
+
mkdirSync(dirname(request.backup), { recursive: true });
|
|
171
|
+
movePath(request.destination, request.backup, request.operations);
|
|
172
|
+
movePath(request.source, request.destination, request.operations);
|
|
173
|
+
};
|
|
174
|
+
const restoreUnexpectedOutput = (unexpected, target, quarantine, previous) => {
|
|
175
|
+
try {
|
|
176
|
+
renameSync(unexpected, target);
|
|
177
|
+
if (previous === null) {
|
|
178
|
+
quarantine.remove();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
throw new Error(`Output recovery failed; retained files are in ${quarantine.displayPath}`, { cause: error });
|
|
183
|
+
}
|
|
184
|
+
throw new Error(`Output changed during the operation; the previous output is retained in ${quarantine.displayPath}`);
|
|
185
|
+
};
|
|
186
|
+
const recoverUnsecuredPublicPath = (target, quarantine, previous, error) => {
|
|
187
|
+
const unsecured = join(quarantine.path, "unsecured");
|
|
188
|
+
const publicCapture = capturePath(target, unsecured);
|
|
189
|
+
try {
|
|
190
|
+
if (previous !== null) {
|
|
191
|
+
renameSync(previous, target);
|
|
192
|
+
}
|
|
193
|
+
else if (publicCapture === "captured") {
|
|
194
|
+
renameSync(unsecured, target);
|
|
195
|
+
}
|
|
196
|
+
if (previous === null || publicCapture === "missing") {
|
|
197
|
+
quarantine.remove();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch (recoveryError) {
|
|
201
|
+
throw new AggregateError([error, recoveryError], `Could not recover the output directory; retained files are in ${quarantine.displayPath}`, { cause: recoveryError });
|
|
202
|
+
}
|
|
203
|
+
throw new Error(`Could not secure the output directory; retained files are in ${quarantine.displayPath}`, {
|
|
204
|
+
cause: error,
|
|
205
|
+
});
|
|
206
|
+
};
|
|
207
|
+
const recoverFailedCapture = (quarantine, error) => {
|
|
208
|
+
try {
|
|
209
|
+
quarantine.remove();
|
|
210
|
+
}
|
|
211
|
+
catch (recoveryError) {
|
|
212
|
+
throw new AggregateError([error, recoveryError], `Could not clean the output quarantine; retained files are in ${quarantine.displayPath}`, { cause: recoveryError });
|
|
213
|
+
}
|
|
214
|
+
throw error;
|
|
215
|
+
};
|
|
216
|
+
const rollbackOutputDirectory = (target, quarantine, previous, freshIdentity) => {
|
|
217
|
+
const failed = join(quarantine.path, "failed");
|
|
218
|
+
const freshCapture = capturePath(target, failed);
|
|
219
|
+
if (freshCapture === "captured" && !hasDirectoryIdentity(failed, freshIdentity)) {
|
|
220
|
+
restoreUnexpectedOutput(failed, target, quarantine, previous);
|
|
221
|
+
}
|
|
222
|
+
if (previous !== null) {
|
|
223
|
+
renameSync(previous, target);
|
|
224
|
+
}
|
|
225
|
+
if (freshCapture === "captured") {
|
|
226
|
+
rmSync(failed, { recursive: true, force: true, maxRetries: 5 });
|
|
227
|
+
}
|
|
228
|
+
quarantine.remove();
|
|
229
|
+
};
|
|
230
|
+
const restoreMissingFreshOutput = (target, quarantine, previous) => {
|
|
231
|
+
try {
|
|
232
|
+
if (previous !== null) {
|
|
233
|
+
renameSync(previous, target);
|
|
234
|
+
}
|
|
235
|
+
quarantine.remove();
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
throw new Error(`The fresh output disappeared; retained files are in ${quarantine.displayPath}`, {
|
|
239
|
+
cause: error,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
throw new Error("The fresh output directory disappeared before it could be committed");
|
|
243
|
+
};
|
|
244
|
+
const captureVerifiedFreshOutput = (target, quarantine, previous, freshIdentity) => {
|
|
245
|
+
const fresh = join(quarantine.path, "fresh");
|
|
246
|
+
if (capturePath(target, fresh) === "missing") {
|
|
247
|
+
restoreMissingFreshOutput(target, quarantine, previous);
|
|
248
|
+
}
|
|
249
|
+
if (!hasDirectoryIdentity(fresh, freshIdentity)) {
|
|
250
|
+
restoreUnexpectedOutput(fresh, target, quarantine, previous);
|
|
251
|
+
}
|
|
252
|
+
return fresh;
|
|
253
|
+
};
|
|
254
|
+
const recoverCommit = (request) => {
|
|
255
|
+
const { backup, error, fresh, operations, previous, quarantine, target } = request;
|
|
256
|
+
try {
|
|
257
|
+
reverseOperations(operations);
|
|
258
|
+
renameSync(previous, target);
|
|
259
|
+
rmSync(fresh, { recursive: true, force: true, maxRetries: 5 });
|
|
260
|
+
rmSync(backup, { recursive: true, force: true, maxRetries: 5 });
|
|
261
|
+
quarantine.remove();
|
|
262
|
+
}
|
|
263
|
+
catch (recoveryError) {
|
|
264
|
+
throw new AggregateError([error, recoveryError], `Could not restore the previous output; retained files are in ${quarantine.displayPath}`, { cause: recoveryError });
|
|
265
|
+
}
|
|
266
|
+
throw error;
|
|
267
|
+
};
|
|
268
|
+
const installFreshOutput = (request) => {
|
|
269
|
+
const { fresh, preservedNames, previous, quarantine, target } = request;
|
|
270
|
+
const backup = join(quarantine.path, "backup");
|
|
271
|
+
const operations = [];
|
|
272
|
+
try {
|
|
273
|
+
const oldNames = readdirSync(previous).filter((name) => !preservedNames.has(name));
|
|
274
|
+
const freshNames = readdirSync(fresh);
|
|
275
|
+
const ordinaryFreshNames = freshNames.filter((name) => !preservedNames.has(name));
|
|
276
|
+
const preservedFreshNames = freshNames.filter((name) => preservedNames.has(name));
|
|
277
|
+
mkdirSync(backup);
|
|
278
|
+
moveNames(previous, backup, oldNames, operations);
|
|
279
|
+
moveNames(fresh, previous, ordinaryFreshNames, operations);
|
|
280
|
+
for (const name of preservedFreshNames) {
|
|
281
|
+
overlayEntry({
|
|
282
|
+
source: join(fresh, name),
|
|
283
|
+
destination: join(previous, name),
|
|
284
|
+
backup: join(backup, name),
|
|
285
|
+
operations,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
renameSync(previous, target);
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
recoverCommit({ ...request, backup, operations, error });
|
|
292
|
+
}
|
|
293
|
+
rmSync(fresh, { recursive: true, force: true, maxRetries: 5 });
|
|
294
|
+
rmSync(backup, { recursive: true, force: true, maxRetries: 5 });
|
|
295
|
+
quarantine.remove();
|
|
296
|
+
};
|
|
297
|
+
const commitOutputDirectory = (request) => {
|
|
298
|
+
const { freshIdentity, preservedNames, previous, quarantine, target } = request;
|
|
299
|
+
const fresh = captureVerifiedFreshOutput(target, quarantine, previous, freshIdentity);
|
|
300
|
+
if (previous === null) {
|
|
301
|
+
renameSync(fresh, target);
|
|
302
|
+
quarantine.remove();
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
installFreshOutput({ target, quarantine, previous, fresh, preservedNames });
|
|
306
|
+
};
|
|
307
|
+
const assertFreshOutput = (path, isFresh) => {
|
|
308
|
+
if (isFresh !== undefined && !isFresh(path)) {
|
|
309
|
+
throw new Error("The build did not write to the secured output directory");
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
const createOutputDirectoryTransaction = (request) => {
|
|
313
|
+
const { fresh, parent, previous, publicParent, publicPath, publicRoot, quarantine, root, target } = request;
|
|
314
|
+
let state = "prepared";
|
|
315
|
+
const commit = (preservedNames = new Set(), isFresh) => {
|
|
316
|
+
if (state !== "prepared") {
|
|
317
|
+
throw new Error("The output directory transaction has already finished");
|
|
318
|
+
}
|
|
319
|
+
if (!hasResolvedDirectoryIdentity(publicRoot, root.identity) ||
|
|
320
|
+
!hasResolvedDirectoryIdentity(publicParent, parent.identity)) {
|
|
321
|
+
throw new Error(`The output parent changed; previous output is retained in ${quarantine.displayPath}`);
|
|
322
|
+
}
|
|
323
|
+
assertFreshOutput(target, isFresh);
|
|
324
|
+
state = "retained";
|
|
325
|
+
try {
|
|
326
|
+
commitOutputDirectory({
|
|
327
|
+
target,
|
|
328
|
+
quarantine,
|
|
329
|
+
previous,
|
|
330
|
+
freshIdentity: fresh.identity,
|
|
331
|
+
preservedNames,
|
|
332
|
+
});
|
|
333
|
+
state = "committed";
|
|
334
|
+
}
|
|
335
|
+
finally {
|
|
336
|
+
releaseTransactionLeases(fresh, quarantine, parent, root);
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
const rollback = () => {
|
|
340
|
+
if (state !== "prepared") {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
state = "retained";
|
|
344
|
+
try {
|
|
345
|
+
rollbackOutputDirectory(target, quarantine, previous, fresh.identity);
|
|
346
|
+
state = "rolled-back";
|
|
347
|
+
}
|
|
348
|
+
finally {
|
|
349
|
+
releaseTransactionLeases(fresh, quarantine, parent, root);
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
return { path: publicPath, commit, [Symbol.dispose]: rollback };
|
|
353
|
+
};
|
|
354
|
+
const rollbackAfterError = (transaction, error) => {
|
|
355
|
+
try {
|
|
356
|
+
transaction[Symbol.dispose]();
|
|
357
|
+
}
|
|
358
|
+
catch (rollbackError) {
|
|
359
|
+
throw new AggregateError([error, rollbackError], "Could not roll back the output directory transaction", { cause: rollbackError });
|
|
360
|
+
}
|
|
361
|
+
throw error;
|
|
362
|
+
};
|
|
363
|
+
const requireFreshDirectoryLease = (resources) => {
|
|
364
|
+
const { parent, previous, quarantine, root, target } = resources;
|
|
365
|
+
const lease = openDirectoryLease(target);
|
|
366
|
+
if (lease !== null) {
|
|
367
|
+
return lease;
|
|
368
|
+
}
|
|
369
|
+
try {
|
|
370
|
+
return recoverUnsecuredPublicPath(target, quarantine, previous, new Error("Could not record the fresh output directory identity"));
|
|
371
|
+
}
|
|
372
|
+
finally {
|
|
373
|
+
releasePreparationLeases(quarantine, parent, root);
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
const requireDirectoryLease = (path, message) => {
|
|
377
|
+
const lease = openDirectoryLease(path);
|
|
378
|
+
if (lease === null) {
|
|
379
|
+
throw new Error(message);
|
|
380
|
+
}
|
|
381
|
+
return lease;
|
|
382
|
+
};
|
|
383
|
+
const createChildDirectoryLease = (parent, name) => {
|
|
384
|
+
const path = join(parent.path, name);
|
|
385
|
+
try {
|
|
386
|
+
mkdirSync(path);
|
|
387
|
+
}
|
|
388
|
+
catch (error) {
|
|
389
|
+
if (!hasErrorCode(error, "EEXIST")) {
|
|
390
|
+
throw error;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return requireDirectoryLease(path, "Could not secure the output parent directory");
|
|
394
|
+
};
|
|
395
|
+
const openOutputParent = (root, rootPath, outputPath) => {
|
|
396
|
+
const relativeParent = relative(rootPath, dirname(outputPath));
|
|
397
|
+
if (relativeParent === ".." || isAbsolute(relativeParent) || relativeParent.startsWith(`..${sep}`)) {
|
|
398
|
+
throw new Error("The output directory must be below the project root");
|
|
399
|
+
}
|
|
400
|
+
let parent = requireDirectoryLease(`${root.path}/.`, "Could not secure the project root directory");
|
|
401
|
+
const segments = relativeParent.split(sep);
|
|
402
|
+
try {
|
|
403
|
+
for (const segment of segments) {
|
|
404
|
+
if (segment.length === 0) {
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
const child = createChildDirectoryLease(parent, segment);
|
|
408
|
+
parent.release();
|
|
409
|
+
parent = child;
|
|
410
|
+
}
|
|
411
|
+
return parent;
|
|
412
|
+
}
|
|
413
|
+
catch (error) {
|
|
414
|
+
parent.release();
|
|
415
|
+
throw error;
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
const createPreparationResources = (rootPath, path) => {
|
|
419
|
+
const canonicalRoot = realpathSync(rootPath);
|
|
420
|
+
const root = requireDirectoryLease(canonicalRoot, "Could not secure the project root directory");
|
|
421
|
+
let parent;
|
|
422
|
+
try {
|
|
423
|
+
parent = openOutputParent(root, rootPath, path);
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
root.release();
|
|
427
|
+
throw error;
|
|
428
|
+
}
|
|
429
|
+
let quarantine;
|
|
430
|
+
try {
|
|
431
|
+
quarantine = createQuarantineDirectory(root, canonicalRoot);
|
|
432
|
+
}
|
|
433
|
+
catch (error) {
|
|
434
|
+
parent.release();
|
|
435
|
+
root.release();
|
|
436
|
+
throw error;
|
|
437
|
+
}
|
|
438
|
+
const target = join(parent.path, basename(path));
|
|
439
|
+
const captured = join(quarantine.path, "previous");
|
|
440
|
+
let previous = null;
|
|
441
|
+
try {
|
|
442
|
+
previous = capturePath(target, captured) === "captured" ? captured : null;
|
|
443
|
+
}
|
|
444
|
+
catch (error) {
|
|
445
|
+
try {
|
|
446
|
+
recoverFailedCapture(quarantine, error);
|
|
447
|
+
}
|
|
448
|
+
finally {
|
|
449
|
+
releasePreparationLeases(quarantine, parent, root);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
try {
|
|
453
|
+
mkdirSync(target);
|
|
454
|
+
}
|
|
455
|
+
catch (error) {
|
|
456
|
+
try {
|
|
457
|
+
recoverUnsecuredPublicPath(target, quarantine, previous, error);
|
|
458
|
+
}
|
|
459
|
+
finally {
|
|
460
|
+
releasePreparationLeases(quarantine, parent, root);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return {
|
|
464
|
+
target,
|
|
465
|
+
publicPath: path,
|
|
466
|
+
publicRoot: rootPath,
|
|
467
|
+
publicParent: dirname(path),
|
|
468
|
+
parent,
|
|
469
|
+
quarantine,
|
|
470
|
+
previous,
|
|
471
|
+
root,
|
|
472
|
+
};
|
|
473
|
+
};
|
|
474
|
+
const prepareOutputDirectory = (rootPath, path, isReusable) => {
|
|
475
|
+
const resources = createPreparationResources(rootPath, path);
|
|
476
|
+
const fresh = requireFreshDirectoryLease(resources);
|
|
477
|
+
const transaction = createOutputDirectoryTransaction({ ...resources, fresh });
|
|
478
|
+
try {
|
|
479
|
+
if (resources.previous === null || isReusable(resources.previous)) {
|
|
480
|
+
return { status: "prepared", transaction };
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
catch (error) {
|
|
484
|
+
rollbackAfterError(transaction, error);
|
|
485
|
+
}
|
|
486
|
+
transaction[Symbol.dispose]();
|
|
487
|
+
return { status: "unsafe" };
|
|
488
|
+
};
|
|
489
|
+
export { prepareOutputDirectory, readRegularFile, };
|
|
490
|
+
//# sourceMappingURL=output-directory.js.map
|