@gtkx/cli 2.0.0-beta.7 → 2.0.0-beta.8
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/commands/deploy.d.ts +4 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +6 -0
- package/dist/commands/deploy.js.map +1 -1
- package/dist/deploy/download.d.ts +7 -3
- package/dist/deploy/download.d.ts.map +1 -1
- package/dist/deploy/download.js +19 -15
- package/dist/deploy/download.js.map +1 -1
- package/dist/deploy/native-addon.d.ts +5 -0
- package/dist/deploy/native-addon.d.ts.map +1 -0
- package/dist/deploy/native-addon.js +134 -0
- package/dist/deploy/native-addon.js.map +1 -0
- package/dist/deploy/node-runtime/download.js +2 -2
- package/dist/deploy/node-runtime/download.js.map +1 -1
- package/dist/deploy/node-runtime/elf.d.ts +3 -1
- package/dist/deploy/node-runtime/elf.d.ts.map +1 -1
- package/dist/deploy/node-runtime/elf.js +3 -1
- package/dist/deploy/node-runtime/elf.js.map +1 -1
- package/dist/deploy/node-runtime/index.d.ts.map +1 -1
- package/dist/deploy/node-runtime/index.js +14 -2
- package/dist/deploy/node-runtime/index.js.map +1 -1
- package/dist/deploy/payload/stage.d.ts +2 -1
- package/dist/deploy/payload/stage.d.ts.map +1 -1
- package/dist/deploy/payload/stage.js +22 -2
- 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 +135 -79
- package/dist/deploy/run-deploy.js.map +1 -1
- package/dist/deploy/settings/arch.d.ts +9 -3
- package/dist/deploy/settings/arch.d.ts.map +1 -1
- package/dist/deploy/settings/arch.js +27 -6
- package/dist/deploy/settings/arch.js.map +1 -1
- package/dist/deploy/settings/index.d.ts +2 -1
- 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 +6 -5
- package/dist/deploy/settings/paths.js.map +1 -1
- package/dist/deploy/targets/appimage.d.ts.map +1 -1
- package/dist/deploy/targets/appimage.js +1 -0
- package/dist/deploy/targets/appimage.js.map +1 -1
- package/dist/deploy/targets/flatpak-pnpm.js +4 -4
- package/dist/deploy/targets/flatpak-pnpm.js.map +1 -1
- package/dist/deploy/targets/flatpak.d.ts.map +1 -1
- package/dist/deploy/targets/flatpak.js +1 -0
- package/dist/deploy/targets/flatpak.js.map +1 -1
- package/dist/deploy/targets/nfpm-target.d.ts.map +1 -1
- package/dist/deploy/targets/nfpm-target.js +1 -0
- package/dist/deploy/targets/nfpm-target.js.map +1 -1
- package/dist/deploy/types.d.ts +4 -2
- package/dist/deploy/types.d.ts.map +1 -1
- package/dist/deploy/types.js.map +1 -1
- package/dist/deploy/vendored/appimagetool.js +2 -2
- package/dist/deploy/vendored/appimagetool.js.map +1 -1
- package/dist/deploy/vendored/nfpm.js +1 -1
- package/dist/deploy/vendored/nfpm.js.map +1 -1
- package/dist/dev/font-dir.d.ts +1 -1
- package/dist/dev/font-dir.d.ts.map +1 -1
- package/dist/dev/font-dir.js +0 -3
- package/dist/dev/font-dir.js.map +1 -1
- package/dist/dev/runner.d.ts.map +1 -1
- package/dist/dev/runner.js +19 -6
- package/dist/dev/runner.js.map +1 -1
- package/dist/internal/font-staging.d.ts +5 -2
- package/dist/internal/font-staging.d.ts.map +1 -1
- package/dist/internal/font-staging.js +76 -27
- package/dist/internal/font-staging.js.map +1 -1
- package/dist/internal/source-imports.js +1 -1
- package/dist/internal/source-imports.js.map +1 -1
- package/dist/vite-plugins/font-worker-env.d.ts.map +1 -1
- package/dist/vite-plugins/font-worker-env.js +2 -5
- package/dist/vite-plugins/font-worker-env.js.map +1 -1
- package/dist/vite-plugins/font.d.ts.map +1 -1
- package/dist/vite-plugins/font.js +16 -4
- package/dist/vite-plugins/font.js.map +1 -1
- package/dist/vite-plugins/icons.js +2 -2
- package/dist/vite-plugins/icons.js.map +1 -1
- package/dist/vite-plugins/react-compiler.js +2 -2
- package/dist/vite-plugins/react-compiler.js.map +1 -1
- package/dist/vite-plugins/resources.js +2 -2
- package/dist/vite-plugins/resources.js.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/vite-plugins/store-links.d.ts.map +1 -1
- package/dist/vite-plugins/store-links.js +2 -1
- package/dist/vite-plugins/store-links.js.map +1 -1
- package/dist/vite-plugins/undeclared-library.js +2 -2
- package/dist/vite-plugins/undeclared-library.js.map +1 -1
- package/package.json +13 -13
- package/src/commands/deploy.ts +6 -0
- package/src/deploy/download.ts +33 -17
- package/src/deploy/native-addon.ts +183 -0
- package/src/deploy/node-runtime/download.ts +2 -2
- package/src/deploy/node-runtime/elf.ts +4 -1
- package/src/deploy/node-runtime/index.ts +24 -4
- package/src/deploy/payload/stage.ts +34 -2
- package/src/deploy/run-deploy.ts +203 -93
- package/src/deploy/settings/arch.ts +40 -8
- package/src/deploy/settings/index.ts +4 -1
- package/src/deploy/settings/paths.ts +8 -6
- package/src/deploy/targets/appimage.ts +1 -0
- package/src/deploy/targets/flatpak-pnpm.ts +4 -4
- package/src/deploy/targets/flatpak.ts +1 -0
- package/src/deploy/targets/nfpm-target.ts +1 -0
- package/src/deploy/types.ts +4 -1
- package/src/deploy/vendored/appimagetool.ts +2 -2
- package/src/deploy/vendored/nfpm.ts +1 -1
- package/src/dev/font-dir.ts +1 -6
- package/src/dev/runner.ts +24 -6
- package/src/internal/font-staging.ts +99 -27
- package/src/internal/source-imports.ts +1 -1
- package/src/vite-plugins/font-worker-env.ts +2 -6
- package/src/vite-plugins/font.ts +21 -3
- package/src/vite-plugins/icons.ts +2 -2
- package/src/vite-plugins/react-compiler.ts +2 -2
- package/src/vite-plugins/resources.ts +2 -2
- package/src/vite-plugins/settings-worker-env.ts +2 -2
- package/src/vite-plugins/store-links.ts +2 -1
- package/src/vite-plugins/undeclared-library.ts +2 -2
|
@@ -3,6 +3,10 @@ declare const deploy: import("citty").CommandDef<{
|
|
|
3
3
|
readonly type: "string";
|
|
4
4
|
readonly description: `Comma-separated package formats to build (${string})`;
|
|
5
5
|
};
|
|
6
|
+
readonly arch: {
|
|
7
|
+
readonly type: "string";
|
|
8
|
+
readonly description: `Comma-separated architectures to build (${string}; default: the host)`;
|
|
9
|
+
};
|
|
6
10
|
readonly out: {
|
|
7
11
|
readonly type: "string";
|
|
8
12
|
readonly description: "Output directory relative to the project root (default: build)";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AASA,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;EA2CV,CAAC;AAEH,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
package/dist/commands/deploy.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { defineCommand } from "citty";
|
|
2
2
|
import { KNOWN_NAMES } from "../deploy/registry.js";
|
|
3
3
|
import { runDeploy } from "../deploy/run-deploy.js";
|
|
4
|
+
import { KNOWN_ARCH_NAMES } from "../deploy/settings/arch.js";
|
|
4
5
|
import { configArg, entryArg } from "../internal/entry-arg.js";
|
|
5
6
|
import { resolveProject } from "../internal/prepare-project.js";
|
|
6
7
|
const DEPLOY_MODE = "production";
|
|
@@ -16,6 +17,10 @@ const deploy = defineCommand({
|
|
|
16
17
|
type: "string",
|
|
17
18
|
description: `Comma-separated package formats to build (${KNOWN_NAMES})`,
|
|
18
19
|
},
|
|
20
|
+
arch: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: `Comma-separated architectures to build (${KNOWN_ARCH_NAMES}; default: the host)`,
|
|
23
|
+
},
|
|
19
24
|
out: {
|
|
20
25
|
type: "string",
|
|
21
26
|
description: "Output directory relative to the project root (default: build)",
|
|
@@ -36,6 +41,7 @@ const deploy = defineCommand({
|
|
|
36
41
|
cwd,
|
|
37
42
|
configFile,
|
|
38
43
|
targets: args.target,
|
|
44
|
+
arches: args.arch,
|
|
39
45
|
outDir: args.out,
|
|
40
46
|
shouldPrintManifests: args["print-manifests"] === true,
|
|
41
47
|
shouldSkipBuild: args["skip-build"] === true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEhE,MAAM,WAAW,GAAG,YAAY,CAAC;AAEjC,MAAM,MAAM,GAAG,aAAa,CAAC;IACzB,IAAI,EAAE;QACF,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,0CAA0C;KAC1D;IACD,IAAI,EAAE;QACF,GAAG,QAAQ;QACX,GAAG,SAAS;QACZ,MAAM,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,6CAA6C,WAAW,GAAG;SAC3E;QACD,GAAG,EAAE;YACD,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,gEAAgE;SAChF;QACD,iBAAiB,EAAE;YACf,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,yEAAyE;SACzF;QACD,YAAY,EAAE;YACV,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,wDAAwD;SACxE;KACJ;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACd,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAE3E,MAAM,SAAS,CAAC;YACZ,KAAK;YACL,GAAG;YACH,UAAU;YACV,OAAO,EAAE,IAAI,CAAC,MAAM;YACpB,MAAM,EAAE,IAAI,CAAC,GAAG;YAChB,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC,KAAK,IAAI;YACtD,eAAe,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI;SAC/C,CAAC,CAAC;IACP,CAAC;CACJ,CAAC,CAAC;AAEH,OAAO,EAAE,MAAM,EAAE,CAAC","sourcesContent":["import { defineCommand } from \"citty\";\nimport { KNOWN_NAMES } from \"../deploy/registry.js\";\nimport { runDeploy } from \"../deploy/run-deploy.js\";\nimport { configArg, entryArg } from \"../internal/entry-arg.js\";\nimport { resolveProject } from \"../internal/prepare-project.js\";\n\nconst DEPLOY_MODE = \"production\";\n\nconst deploy = defineCommand({\n meta: {\n name: \"deploy\",\n description: \"Package the application for distribution\",\n },\n args: {\n ...entryArg,\n ...configArg,\n target: {\n type: \"string\",\n description: `Comma-separated package formats to build (${KNOWN_NAMES})`,\n },\n out: {\n type: \"string\",\n description: \"Output directory relative to the project root (default: build)\",\n },\n \"print-manifests\": {\n type: \"boolean\",\n description: \"Write the generated manifests and metadata, then stop without packaging\",\n },\n \"skip-build\": {\n type: \"boolean\",\n description: \"Package what is already in dist/ instead of rebuilding\",\n },\n },\n async run({ args }) {\n const { cwd, entry, configFile } = await resolveProject(args, DEPLOY_MODE);\n\n await runDeploy({\n entry,\n cwd,\n configFile,\n targets: args.target,\n outDir: args.out,\n shouldPrintManifests: args[\"print-manifests\"] === true,\n shouldSkipBuild: args[\"skip-build\"] === true,\n });\n },\n});\n\nexport { deploy };\n"]}
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEhE,MAAM,WAAW,GAAG,YAAY,CAAC;AAEjC,MAAM,MAAM,GAAG,aAAa,CAAC;IACzB,IAAI,EAAE;QACF,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,0CAA0C;KAC1D;IACD,IAAI,EAAE;QACF,GAAG,QAAQ;QACX,GAAG,SAAS;QACZ,MAAM,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,6CAA6C,WAAW,GAAG;SAC3E;QACD,IAAI,EAAE;YACF,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,2CAA2C,gBAAgB,sBAAsB;SACjG;QACD,GAAG,EAAE;YACD,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,gEAAgE;SAChF;QACD,iBAAiB,EAAE;YACf,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,yEAAyE;SACzF;QACD,YAAY,EAAE;YACV,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,wDAAwD;SACxE;KACJ;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACd,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAE3E,MAAM,SAAS,CAAC;YACZ,KAAK;YACL,GAAG;YACH,UAAU;YACV,OAAO,EAAE,IAAI,CAAC,MAAM;YACpB,MAAM,EAAE,IAAI,CAAC,IAAI;YACjB,MAAM,EAAE,IAAI,CAAC,GAAG;YAChB,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC,KAAK,IAAI;YACtD,eAAe,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI;SAC/C,CAAC,CAAC;IACP,CAAC;CACJ,CAAC,CAAC;AAEH,OAAO,EAAE,MAAM,EAAE,CAAC","sourcesContent":["import { defineCommand } from \"citty\";\nimport { KNOWN_NAMES } from \"../deploy/registry.js\";\nimport { runDeploy } from \"../deploy/run-deploy.js\";\nimport { KNOWN_ARCH_NAMES } from \"../deploy/settings/arch.js\";\nimport { configArg, entryArg } from \"../internal/entry-arg.js\";\nimport { resolveProject } from \"../internal/prepare-project.js\";\n\nconst DEPLOY_MODE = \"production\";\n\nconst deploy = defineCommand({\n meta: {\n name: \"deploy\",\n description: \"Package the application for distribution\",\n },\n args: {\n ...entryArg,\n ...configArg,\n target: {\n type: \"string\",\n description: `Comma-separated package formats to build (${KNOWN_NAMES})`,\n },\n arch: {\n type: \"string\",\n description: `Comma-separated architectures to build (${KNOWN_ARCH_NAMES}; default: the host)`,\n },\n out: {\n type: \"string\",\n description: \"Output directory relative to the project root (default: build)\",\n },\n \"print-manifests\": {\n type: \"boolean\",\n description: \"Write the generated manifests and metadata, then stop without packaging\",\n },\n \"skip-build\": {\n type: \"boolean\",\n description: \"Package what is already in dist/ instead of rebuilding\",\n },\n },\n async run({ args }) {\n const { cwd, entry, configFile } = await resolveProject(args, DEPLOY_MODE);\n\n await runDeploy({\n entry,\n cwd,\n configFile,\n targets: args.target,\n arches: args.arch,\n outDir: args.out,\n shouldPrintManifests: args[\"print-manifests\"] === true,\n shouldSkipBuild: args[\"skip-build\"] === true,\n });\n },\n});\n\nexport { deploy };\n"]}
|
|
@@ -4,17 +4,21 @@ type DigestRequest = {
|
|
|
4
4
|
assetName: string;
|
|
5
5
|
subject: string;
|
|
6
6
|
};
|
|
7
|
+
type DigestAlgorithm = "sha256" | "sha512";
|
|
7
8
|
type DownloadRequest = {
|
|
8
9
|
url: string;
|
|
9
10
|
dest: string;
|
|
10
11
|
label: string;
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
digest: string;
|
|
13
|
+
algorithm?: DigestAlgorithm | undefined;
|
|
14
|
+
freshDigest?: (() => Promise<string>) | undefined;
|
|
13
15
|
mode?: number | undefined;
|
|
14
16
|
};
|
|
15
17
|
declare const cacheDir: (segments: string[]) => string;
|
|
18
|
+
declare const readCachedDigest: (dest: string, algorithm: DigestAlgorithm) => string | undefined;
|
|
19
|
+
declare const writeAtomically: (dest: string, contents: string) => void;
|
|
16
20
|
declare const publishedDigest: (request: DigestRequest) => Promise<string>;
|
|
17
21
|
declare const cachedDigest: (request: DigestRequest) => Promise<string>;
|
|
18
22
|
declare const downloadFile: (request: DownloadRequest) => Promise<string>;
|
|
19
|
-
export { cacheDir, cachedDigest, type DigestRequest, downloadFile, publishedDigest };
|
|
23
|
+
export { cacheDir, cachedDigest, type DigestRequest, downloadFile, publishedDigest, readCachedDigest, writeAtomically, };
|
|
20
24
|
//# sourceMappingURL=download.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/deploy/download.ts"],"names":[],"mappings":"AAMA,KAAK,aAAa,GAAG;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,eAAe,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;IAClD,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,CAAC;
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/deploy/download.ts"],"names":[],"mappings":"AAMA,KAAK,aAAa,GAAG;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE3C,KAAK,eAAe,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IACxC,WAAW,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;IAClD,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,CAAC;AAcF,QAAA,MAAM,QAAQ,GAAI,UAAU,MAAM,EAAE,KAAG,MAKtC,CAAC;AA6BF,QAAA,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,WAAW,eAAe,KAAG,MAAM,GAAG,SAQ7E,CAAC;AAEF,QAAA,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,UAAU,MAAM,KAAG,IAIzD,CAAC;AAEF,QAAA,MAAM,eAAe,GAAU,SAAS,aAAa,KAAG,OAAO,CAAC,MAAM,CAWrE,CAAC;AAEF,QAAA,MAAM,YAAY,GAAU,SAAS,aAAa,KAAG,OAAO,CAAC,MAAM,CAIlE,CAAC;AAgBF,QAAA,MAAM,YAAY,GAAU,SAAS,eAAe,KAAG,OAAO,CAAC,MAAM,CAsBpE,CAAC;AAaF,OAAO,EACH,QAAQ,EACR,YAAY,EACZ,KAAK,aAAa,EAClB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,eAAe,GAClB,CAAC"}
|
package/dist/deploy/download.js
CHANGED
|
@@ -4,7 +4,10 @@ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSy
|
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
const CACHE_NAMESPACE = "gtkx";
|
|
7
|
-
const DIGEST_PATTERN =
|
|
7
|
+
const DIGEST_PATTERN = {
|
|
8
|
+
sha256: /^[\da-f]{64}$/,
|
|
9
|
+
sha512: /^[\da-f]{128}$/,
|
|
10
|
+
};
|
|
8
11
|
const cacheRoot = () => {
|
|
9
12
|
const base = process.env.XDG_CACHE_HOME;
|
|
10
13
|
return join(base !== undefined && base.length > 0 ? base : join(homedir(), ".cache"), CACHE_NAMESPACE);
|
|
@@ -14,9 +17,9 @@ const cacheDir = (segments) => {
|
|
|
14
17
|
mkdirSync(dir, { recursive: true });
|
|
15
18
|
return dir;
|
|
16
19
|
};
|
|
17
|
-
const getDigest = (contents) => createHash(
|
|
18
|
-
const assertDigest = (url, contents, expected) => {
|
|
19
|
-
const actual = getDigest(contents);
|
|
20
|
+
const getDigest = (contents, algorithm) => createHash(algorithm).update(contents).digest("hex");
|
|
21
|
+
const assertDigest = (url, contents, expected, algorithm) => {
|
|
22
|
+
const actual = getDigest(contents, algorithm);
|
|
20
23
|
if (actual !== expected) {
|
|
21
24
|
throw new Error(`Checksum mismatch for ${url}\n expected ${expected}\n received ${actual}`);
|
|
22
25
|
}
|
|
@@ -32,10 +35,10 @@ const fetchText = async (url) => {
|
|
|
32
35
|
const bytes = await fetchBytes(url);
|
|
33
36
|
return bytes.toString("utf8");
|
|
34
37
|
};
|
|
35
|
-
const readCachedDigest = (dest) => {
|
|
38
|
+
const readCachedDigest = (dest, algorithm) => {
|
|
36
39
|
try {
|
|
37
40
|
const cached = readFileSync(dest, "utf8").trim();
|
|
38
|
-
return DIGEST_PATTERN.test(cached) ? cached : undefined;
|
|
41
|
+
return DIGEST_PATTERN[algorithm].test(cached) ? cached : undefined;
|
|
39
42
|
}
|
|
40
43
|
catch {
|
|
41
44
|
return undefined;
|
|
@@ -49,35 +52,36 @@ const writeAtomically = (dest, contents) => {
|
|
|
49
52
|
const publishedDigest = async (request) => {
|
|
50
53
|
const checksums = await fetchText(request.url);
|
|
51
54
|
const digest = digestFromChecksums(checksums, request.assetName, request.subject);
|
|
52
|
-
if (!DIGEST_PATTERN.test(digest)) {
|
|
55
|
+
if (!DIGEST_PATTERN.sha256.test(digest)) {
|
|
53
56
|
throw new Error(`${request.subject} published a malformed checksum for ${request.assetName}: "${digest}"`);
|
|
54
57
|
}
|
|
55
58
|
writeAtomically(request.dest, digest);
|
|
56
59
|
return digest;
|
|
57
60
|
};
|
|
58
61
|
const cachedDigest = async (request) => {
|
|
59
|
-
const cached = readCachedDigest(request.dest);
|
|
62
|
+
const cached = readCachedDigest(request.dest, "sha256");
|
|
60
63
|
return cached ?? publishedDigest(request);
|
|
61
64
|
};
|
|
62
|
-
const isCacheUsable = (dest,
|
|
65
|
+
const isCacheUsable = (dest, digest, algorithm) => {
|
|
63
66
|
if (!existsSync(dest)) {
|
|
64
67
|
return false;
|
|
65
68
|
}
|
|
66
|
-
if (getDigest(readFileSync(dest)) ===
|
|
69
|
+
if (getDigest(readFileSync(dest), algorithm) === digest) {
|
|
67
70
|
return true;
|
|
68
71
|
}
|
|
69
72
|
warn(`Discarding the cached ${dest}: its checksum no longer matches`);
|
|
70
73
|
return false;
|
|
71
74
|
};
|
|
72
75
|
const downloadFile = async (request) => {
|
|
73
|
-
const { url, dest, label,
|
|
74
|
-
|
|
76
|
+
const { url, dest, label, digest, mode } = request;
|
|
77
|
+
const algorithm = request.algorithm ?? "sha256";
|
|
78
|
+
if (isCacheUsable(dest, digest, algorithm)) {
|
|
75
79
|
return dest;
|
|
76
80
|
}
|
|
77
81
|
info(`Downloading ${label}`);
|
|
78
|
-
const expected = request.
|
|
82
|
+
const expected = request.freshDigest === undefined ? digest : await request.freshDigest();
|
|
79
83
|
const contents = await fetchBytes(url);
|
|
80
|
-
assertDigest(url, contents, expected);
|
|
84
|
+
assertDigest(url, contents, expected, algorithm);
|
|
81
85
|
const staging = `${dest}.partial`;
|
|
82
86
|
writeFileSync(staging, contents);
|
|
83
87
|
if (mode !== undefined) {
|
|
@@ -94,5 +98,5 @@ const digestFromChecksums = (checksums, assetName, subject) => {
|
|
|
94
98
|
}
|
|
95
99
|
return digest;
|
|
96
100
|
};
|
|
97
|
-
export { cacheDir, cachedDigest, downloadFile, publishedDigest };
|
|
101
|
+
export { cacheDir, cachedDigest, downloadFile, publishedDigest, readCachedDigest, writeAtomically, };
|
|
98
102
|
//# sourceMappingURL=download.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/deploy/download.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpG,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/deploy/download.ts"],"names":[],"mappings":"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","sourcesContent":["import { info, warn } from \"@gtkx/utils\";\nimport { createHash } from \"node:crypto\";\nimport { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\ntype DigestRequest = {\n url: string;\n dest: string;\n assetName: string;\n subject: string;\n};\n\ntype DigestAlgorithm = \"sha256\" | \"sha512\";\n\ntype DownloadRequest = {\n url: string;\n dest: string;\n label: string;\n digest: string;\n algorithm?: DigestAlgorithm | undefined;\n freshDigest?: (() => Promise<string>) | undefined;\n mode?: number | undefined;\n};\n\nconst CACHE_NAMESPACE = \"gtkx\";\nconst DIGEST_PATTERN: Record<DigestAlgorithm, RegExp> = {\n sha256: /^[\\da-f]{64}$/,\n sha512: /^[\\da-f]{128}$/,\n};\n\nconst cacheRoot = (): string => {\n const base = process.env.XDG_CACHE_HOME;\n\n return join(base !== undefined && base.length > 0 ? base : join(homedir(), \".cache\"), CACHE_NAMESPACE);\n};\n\nconst cacheDir = (segments: string[]): string => {\n const dir = join(cacheRoot(), ...segments);\n mkdirSync(dir, { recursive: true });\n\n return dir;\n};\n\nconst getDigest = (contents: Buffer, algorithm: DigestAlgorithm): string =>\n createHash(algorithm).update(contents).digest(\"hex\");\n\nconst assertDigest = (url: string, contents: Buffer, expected: string, algorithm: DigestAlgorithm): void => {\n const actual = getDigest(contents, algorithm);\n\n if (actual !== expected) {\n throw new Error(`Checksum mismatch for ${url}\\n expected ${expected}\\n received ${actual}`);\n }\n};\n\nconst fetchBytes = async (url: string): Promise<Buffer> => {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Cannot download ${url}: HTTP ${String(response.status)} ${response.statusText}`);\n }\n\n return Buffer.from(await response.arrayBuffer());\n};\n\nconst fetchText = async (url: string): Promise<string> => {\n const bytes = await fetchBytes(url);\n\n return bytes.toString(\"utf8\");\n};\n\nconst readCachedDigest = (dest: string, algorithm: DigestAlgorithm): string | undefined => {\n try {\n const cached = readFileSync(dest, \"utf8\").trim();\n\n return DIGEST_PATTERN[algorithm].test(cached) ? cached : undefined;\n } catch {\n return undefined;\n }\n};\n\nconst writeAtomically = (dest: string, contents: string): void => {\n const staging = `${dest}.partial`;\n writeFileSync(staging, contents);\n renameSync(staging, dest);\n};\n\nconst publishedDigest = async (request: DigestRequest): Promise<string> => {\n const checksums = await fetchText(request.url);\n const digest = digestFromChecksums(checksums, request.assetName, request.subject);\n\n if (!DIGEST_PATTERN.sha256.test(digest)) {\n throw new Error(`${request.subject} published a malformed checksum for ${request.assetName}: \"${digest}\"`);\n }\n\n writeAtomically(request.dest, digest);\n\n return digest;\n};\n\nconst cachedDigest = async (request: DigestRequest): Promise<string> => {\n const cached = readCachedDigest(request.dest, \"sha256\");\n\n return cached ?? publishedDigest(request);\n};\n\nconst isCacheUsable = (dest: string, digest: string, algorithm: DigestAlgorithm): boolean => {\n if (!existsSync(dest)) {\n return false;\n }\n\n if (getDigest(readFileSync(dest), algorithm) === digest) {\n return true;\n }\n\n warn(`Discarding the cached ${dest}: its checksum no longer matches`);\n\n return false;\n};\n\nconst downloadFile = async (request: DownloadRequest): Promise<string> => {\n const { url, dest, label, digest, mode } = request;\n const algorithm = request.algorithm ?? \"sha256\";\n\n if (isCacheUsable(dest, digest, algorithm)) {\n return dest;\n }\n\n info(`Downloading ${label}`);\n const expected = request.freshDigest === undefined ? digest : await request.freshDigest();\n const contents = await fetchBytes(url);\n assertDigest(url, contents, expected, algorithm);\n const staging = `${dest}.partial`;\n writeFileSync(staging, contents);\n\n if (mode !== undefined) {\n chmodSync(staging, mode);\n }\n\n renameSync(staging, dest);\n\n return dest;\n};\n\nconst digestFromChecksums = (checksums: string, assetName: string, subject: string): string => {\n const line = checksums.split(\"\\n\").find((entry) => entry.trim().endsWith(` ${assetName}`));\n const digest = line?.trim().split(/\\s+/, 1)[0];\n\n if (digest === undefined) {\n throw new Error(`${subject} publishes no checksum for ${assetName}`);\n }\n\n return digest;\n};\n\nexport {\n cacheDir,\n cachedDigest,\n type DigestRequest,\n downloadFile,\n publishedDigest,\n readCachedDigest,\n writeAtomically,\n};\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DeploySettings } from "./types.js";
|
|
2
|
+
declare const BINDING_FILENAME = "gtkx.node";
|
|
3
|
+
declare const resolveStagedAddon: (settings: DeploySettings) => Promise<string | null>;
|
|
4
|
+
export { BINDING_FILENAME, resolveStagedAddon };
|
|
5
|
+
//# sourceMappingURL=native-addon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-addon.d.ts","sourceRoot":"","sources":["../../src/deploy/native-addon.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,YAAY,CAAC;AAQjE,QAAA,MAAM,gBAAgB,cAAc,CAAC;AA8JrC,QAAA,MAAM,kBAAkB,GAAU,UAAU,cAAc,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAWjF,CAAC;AAEF,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { runCliTool } from "../internal/run-cli-tool.js";
|
|
5
|
+
import { cacheDir, downloadFile, readCachedDigest, writeAtomically } from "./download.js";
|
|
6
|
+
import { isHostArch } from "./settings/arch.js";
|
|
7
|
+
const BINDING_FILENAME = "gtkx.node";
|
|
8
|
+
const DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
|
9
|
+
const NATIVE_MANIFEST = "@gtkx/native/package.json";
|
|
10
|
+
const PACKAGE_ROOT = "package";
|
|
11
|
+
const REQUEST_TIMEOUT = 30_000;
|
|
12
|
+
const SRI_PREFIX = "sha512-";
|
|
13
|
+
const STRIP_COMPONENTS = "1";
|
|
14
|
+
const VERSION_PATTERN = /^[\w.+-]+$/;
|
|
15
|
+
const binaryFilename = (arch) => `native.linux-${arch}-gnu.node`;
|
|
16
|
+
const platformStem = (arch) => `native-linux-${arch}-gnu`;
|
|
17
|
+
const platformPackage = (arch) => `@gtkx/${platformStem(arch)}`;
|
|
18
|
+
const withoutTrailingSlash = (value) => {
|
|
19
|
+
let end = value.length;
|
|
20
|
+
while (end > 0 && value[end - 1] === "/") {
|
|
21
|
+
end -= 1;
|
|
22
|
+
}
|
|
23
|
+
return value.slice(0, end);
|
|
24
|
+
};
|
|
25
|
+
const registryUrl = () => {
|
|
26
|
+
const configured = process.env.npm_config_registry;
|
|
27
|
+
return withoutTrailingSlash(configured !== undefined && configured.length > 0 ? configured : DEFAULT_REGISTRY);
|
|
28
|
+
};
|
|
29
|
+
const projectRequireFor = (root) => createRequire(join(root, "package.json"));
|
|
30
|
+
const localBinary = (projectRequire, arch) => {
|
|
31
|
+
const nativeRoot = dirname(projectRequire.resolve(NATIVE_MANIFEST));
|
|
32
|
+
const candidate = join(nativeRoot, binaryFilename(arch));
|
|
33
|
+
return existsSync(candidate) ? candidate : null;
|
|
34
|
+
};
|
|
35
|
+
const installedBinary = (projectRequire, arch) => {
|
|
36
|
+
try {
|
|
37
|
+
return projectRequire.resolve(platformPackage(arch));
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const manifestVersion = (manifest) => {
|
|
44
|
+
if (typeof manifest !== "object" || manifest === null || !("version" in manifest)) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const version = manifest.version;
|
|
48
|
+
return typeof version === "string" && VERSION_PATTERN.test(version) ? version : null;
|
|
49
|
+
};
|
|
50
|
+
const nativeVersion = (projectRequire) => {
|
|
51
|
+
const parsed = JSON.parse(readFileSync(projectRequire.resolve(NATIVE_MANIFEST), "utf8"));
|
|
52
|
+
const version = manifestVersion(parsed);
|
|
53
|
+
if (version === null) {
|
|
54
|
+
throw new Error("Cannot read a usable version from @gtkx/native; is it installed?");
|
|
55
|
+
}
|
|
56
|
+
return version;
|
|
57
|
+
};
|
|
58
|
+
const hexFromIntegrity = (integrity, subject) => {
|
|
59
|
+
if (typeof integrity !== "string" || !integrity.startsWith(SRI_PREFIX)) {
|
|
60
|
+
throw new Error(`The npm registry publishes no sha512 integrity for ${subject}`);
|
|
61
|
+
}
|
|
62
|
+
return Buffer.from(integrity.slice(SRI_PREFIX.length), "base64").toString("hex");
|
|
63
|
+
};
|
|
64
|
+
const fetchVersionDocument = async (url, subject) => {
|
|
65
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(REQUEST_TIMEOUT) });
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
throw new Error(`Cannot fetch ${subject}: HTTP ${String(response.status)} ${response.statusText}. ` +
|
|
68
|
+
`Install ${subject} directly, or drop that architecture from --arch.`);
|
|
69
|
+
}
|
|
70
|
+
const document = await response.json();
|
|
71
|
+
if (typeof document !== "object" || document === null) {
|
|
72
|
+
throw new Error(`The npm registry returned no metadata for ${subject}`);
|
|
73
|
+
}
|
|
74
|
+
return document;
|
|
75
|
+
};
|
|
76
|
+
const publishedTarball = async (arch, version) => {
|
|
77
|
+
const registry = registryUrl();
|
|
78
|
+
const subject = `${platformPackage(arch)}@${version}`;
|
|
79
|
+
const url = `${registry}/${encodeURIComponent(platformPackage(arch))}/${version}`;
|
|
80
|
+
const document = await fetchVersionDocument(url, subject);
|
|
81
|
+
const dist = document.dist;
|
|
82
|
+
if (typeof dist !== "object" || dist === null) {
|
|
83
|
+
throw new Error(`The npm registry returned no tarball for ${subject}`);
|
|
84
|
+
}
|
|
85
|
+
const entry = dist;
|
|
86
|
+
const tarball = entry.tarball;
|
|
87
|
+
if (typeof tarball !== "string" || new URL(tarball).origin !== new URL(registry).origin) {
|
|
88
|
+
throw new Error(`The npm registry returned an unusable tarball URL for ${subject}`);
|
|
89
|
+
}
|
|
90
|
+
return { url: tarball, digest: hexFromIntegrity(entry.integrity, subject) };
|
|
91
|
+
};
|
|
92
|
+
const extractAddon = (archive, dir, arch) => {
|
|
93
|
+
runCliTool({
|
|
94
|
+
tool: "tar",
|
|
95
|
+
args: ["-xzf", archive, "-C", dir, "--strip-components", STRIP_COMPONENTS,
|
|
96
|
+
`${PACKAGE_ROOT}/${binaryFilename(arch)}`],
|
|
97
|
+
target: platformPackage(arch),
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
const cachedTarballUrl = (arch, version) => `${registryUrl()}/${platformPackage(arch)}/-/${platformStem(arch)}-${version}.tgz`;
|
|
101
|
+
const tarballFor = async (arch, version, sidecar) => {
|
|
102
|
+
const cached = readCachedDigest(sidecar, "sha512");
|
|
103
|
+
if (cached !== undefined) {
|
|
104
|
+
return { url: cachedTarballUrl(arch, version), digest: cached };
|
|
105
|
+
}
|
|
106
|
+
const published = await publishedTarball(arch, version);
|
|
107
|
+
writeAtomically(sidecar, published.digest);
|
|
108
|
+
return published;
|
|
109
|
+
};
|
|
110
|
+
const downloadedBinary = async (arch, version) => {
|
|
111
|
+
const dir = cacheDir(["native", `${version}-linux-${arch}`]);
|
|
112
|
+
const archive = join(dir, `${platformStem(arch)}-${version}.tgz`);
|
|
113
|
+
const tarball = await tarballFor(arch, version, `${archive}.sha512`);
|
|
114
|
+
await downloadFile({
|
|
115
|
+
url: tarball.url,
|
|
116
|
+
dest: archive,
|
|
117
|
+
label: `${platformPackage(arch)} ${version}`,
|
|
118
|
+
digest: tarball.digest,
|
|
119
|
+
algorithm: "sha512",
|
|
120
|
+
});
|
|
121
|
+
extractAddon(archive, dir, arch);
|
|
122
|
+
return join(dir, binaryFilename(arch));
|
|
123
|
+
};
|
|
124
|
+
const resolveStagedAddon = async (settings) => {
|
|
125
|
+
const arch = settings.arch.node;
|
|
126
|
+
if (isHostArch(arch)) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
const projectRequire = projectRequireFor(settings.paths.root);
|
|
130
|
+
const resolved = localBinary(projectRequire, arch) ?? installedBinary(projectRequire, arch);
|
|
131
|
+
return resolved ?? await downloadedBinary(arch, nativeVersion(projectRequire));
|
|
132
|
+
};
|
|
133
|
+
export { BINDING_FILENAME, resolveStagedAddon };
|
|
134
|
+
//# sourceMappingURL=native-addon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-addon.js","sourceRoot":"","sources":["../../src/deploy/native-addon.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\nimport type { DeployArchName, DeploySettings } from \"./types.js\";\nimport { runCliTool } from \"../internal/run-cli-tool.js\";\nimport { cacheDir, downloadFile, readCachedDigest, writeAtomically } from \"./download.js\";\nimport { isHostArch } from \"./settings/arch.js\";\n\ntype ProjectRequire = ReturnType<typeof createRequire>;\ntype Tarball = { url: string; digest: string };\n\nconst BINDING_FILENAME = \"gtkx.node\";\nconst DEFAULT_REGISTRY = \"https://registry.npmjs.org\";\nconst NATIVE_MANIFEST = \"@gtkx/native/package.json\";\nconst PACKAGE_ROOT = \"package\";\nconst REQUEST_TIMEOUT = 30_000;\nconst SRI_PREFIX = \"sha512-\";\nconst STRIP_COMPONENTS = \"1\";\nconst VERSION_PATTERN = /^[\\w.+-]+$/;\n\nconst binaryFilename = (arch: DeployArchName): string => `native.linux-${arch}-gnu.node`;\nconst platformStem = (arch: DeployArchName): string => `native-linux-${arch}-gnu`;\nconst platformPackage = (arch: DeployArchName): string => `@gtkx/${platformStem(arch)}`;\n\nconst withoutTrailingSlash = (value: string): string => {\n let end = value.length;\n\n while (end > 0 && value[end - 1] === \"/\") {\n end -= 1;\n }\n\n return value.slice(0, end);\n};\n\nconst registryUrl = (): string => {\n const configured = process.env.npm_config_registry;\n\n return withoutTrailingSlash(configured !== undefined && configured.length > 0 ? configured : DEFAULT_REGISTRY);\n};\n\nconst projectRequireFor = (root: string): ProjectRequire => createRequire(join(root, \"package.json\"));\n\nconst localBinary = (projectRequire: ProjectRequire, arch: DeployArchName): string | null => {\n const nativeRoot = dirname(projectRequire.resolve(NATIVE_MANIFEST));\n const candidate = join(nativeRoot, binaryFilename(arch));\n\n return existsSync(candidate) ? candidate : null;\n};\n\nconst installedBinary = (projectRequire: ProjectRequire, arch: DeployArchName): string | null => {\n try {\n return projectRequire.resolve(platformPackage(arch));\n } catch {\n return null;\n }\n};\n\nconst manifestVersion = (manifest: unknown): string | null => {\n if (typeof manifest !== \"object\" || manifest === null || !(\"version\" in manifest)) {\n return null;\n }\n\n const version = manifest.version;\n\n return typeof version === \"string\" && VERSION_PATTERN.test(version) ? version : null;\n};\n\nconst nativeVersion = (projectRequire: ProjectRequire): string => {\n const parsed: unknown = JSON.parse(readFileSync(projectRequire.resolve(NATIVE_MANIFEST), \"utf8\"));\n const version = manifestVersion(parsed);\n\n if (version === null) {\n throw new Error(\"Cannot read a usable version from @gtkx/native; is it installed?\");\n }\n\n return version;\n};\n\nconst hexFromIntegrity = (integrity: unknown, subject: string): string => {\n if (typeof integrity !== \"string\" || !integrity.startsWith(SRI_PREFIX)) {\n throw new Error(`The npm registry publishes no sha512 integrity for ${subject}`);\n }\n\n return Buffer.from(integrity.slice(SRI_PREFIX.length), \"base64\").toString(\"hex\");\n};\n\nconst fetchVersionDocument = async (url: string, subject: string): Promise<Record<string, unknown>> => {\n const response = await fetch(url, { signal: AbortSignal.timeout(REQUEST_TIMEOUT) });\n\n if (!response.ok) {\n throw new Error(\n `Cannot fetch ${subject}: HTTP ${String(response.status)} ${response.statusText}. ` +\n `Install ${subject} directly, or drop that architecture from --arch.`,\n );\n }\n\n const document: unknown = await response.json();\n\n if (typeof document !== \"object\" || document === null) {\n throw new Error(`The npm registry returned no metadata for ${subject}`);\n }\n\n return document as Record<string, unknown>;\n};\n\nconst publishedTarball = async (arch: DeployArchName, version: string): Promise<Tarball> => {\n const registry = registryUrl();\n const subject = `${platformPackage(arch)}@${version}`;\n const url = `${registry}/${encodeURIComponent(platformPackage(arch))}/${version}`;\n const document = await fetchVersionDocument(url, subject);\n const dist: unknown = document.dist;\n\n if (typeof dist !== \"object\" || dist === null) {\n throw new Error(`The npm registry returned no tarball for ${subject}`);\n }\n\n const entry = dist as Record<string, unknown>;\n const tarball = entry.tarball;\n\n if (typeof tarball !== \"string\" || new URL(tarball).origin !== new URL(registry).origin) {\n throw new Error(`The npm registry returned an unusable tarball URL for ${subject}`);\n }\n\n return { url: tarball, digest: hexFromIntegrity(entry.integrity, subject) };\n};\n\nconst extractAddon = (archive: string, dir: string, arch: DeployArchName): void => {\n runCliTool({\n tool: \"tar\",\n args: [\"-xzf\", archive, \"-C\", dir, \"--strip-components\", STRIP_COMPONENTS,\n `${PACKAGE_ROOT}/${binaryFilename(arch)}`],\n target: platformPackage(arch),\n });\n};\n\nconst cachedTarballUrl = (arch: DeployArchName, version: string): string =>\n `${registryUrl()}/${platformPackage(arch)}/-/${platformStem(arch)}-${version}.tgz`;\n\nconst tarballFor = async (arch: DeployArchName, version: string, sidecar: string): Promise<Tarball> => {\n const cached = readCachedDigest(sidecar, \"sha512\");\n\n if (cached !== undefined) {\n return { url: cachedTarballUrl(arch, version), digest: cached };\n }\n\n const published = await publishedTarball(arch, version);\n writeAtomically(sidecar, published.digest);\n\n return published;\n};\n\nconst downloadedBinary = async (arch: DeployArchName, version: string): Promise<string> => {\n const dir = cacheDir([\"native\", `${version}-linux-${arch}`]);\n const archive = join(dir, `${platformStem(arch)}-${version}.tgz`);\n const tarball = await tarballFor(arch, version, `${archive}.sha512`);\n\n await downloadFile({\n url: tarball.url,\n dest: archive,\n label: `${platformPackage(arch)} ${version}`,\n digest: tarball.digest,\n algorithm: \"sha512\",\n });\n\n extractAddon(archive, dir, arch);\n\n return join(dir, binaryFilename(arch));\n};\n\nconst resolveStagedAddon = async (settings: DeploySettings): Promise<string | null> => {\n const arch = settings.arch.node;\n\n if (isHostArch(arch)) {\n return null;\n }\n\n const projectRequire = projectRequireFor(settings.paths.root);\n const resolved = localBinary(projectRequire, arch) ?? installedBinary(projectRequire, arch);\n\n return resolved ?? await downloadedBinary(arch, nativeVersion(projectRequire));\n};\n\nexport { BINDING_FILENAME, resolveStagedAddon };\n"]}
|
|
@@ -31,8 +31,8 @@ const downloadNode = async (version, arch, destDir) => {
|
|
|
31
31
|
url: `${DIST_BASE_URL}/v${version}/${assetName}`,
|
|
32
32
|
dest: join(dir, assetName),
|
|
33
33
|
label: `Node.js ${version} for linux-${arch}`,
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
digest: await cachedDigest(request),
|
|
35
|
+
freshDigest: () => publishedDigest(request),
|
|
36
36
|
});
|
|
37
37
|
mkdirSync(destDir, { recursive: true });
|
|
38
38
|
extractNode(archive, destDir, version, arch);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../../src/deploy/node-runtime/download.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAOhD,MAAM,aAAa,GAAG,yBAAyB,CAAC;AAChD,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,MAAM,cAAc,GAAG,gBAAgB,CAAC;AACxC,MAAM,SAAS,GAAG,UAAU,CAAC;AAE7B,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,IAAY,EAAU,EAAE,CAAC,SAAS,OAAO,UAAU,IAAI,EAAE,CAAC;AAEhG,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,SAAiB,EAAE,GAAW,EAAiB,EAAE,CAAC,CAAC;IACvF,GAAG,EAAE,GAAG,aAAa,KAAK,OAAO,IAAI,cAAc,EAAE;IACrD,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,SAAS,CAAC;IACtC,SAAS;IACT,OAAO,EAAE,WAAW,OAAO,EAAE;CAChC,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,GAAW,EAAE,OAAe,EAAE,IAAY,EAAQ,EAAE;IACtF,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAE3C,UAAU,CAAC;QACP,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,oBAAoB,EAAE,gBAAgB;YACrE,GAAG,OAAO,IAAI,SAAS,EAAE,EAAE,GAAG,OAAO,IAAI,gBAAgB,EAAE,CAAC;QAChE,MAAM,EAAE,WAAW,OAAO,EAAE;KAC/B,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,KAAK,EAAE,OAAe,EAAE,IAAY,EAAE,OAAe,EAA2B,EAAE;IACnG,MAAM,SAAS,GAAG,GAAG,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC;IACzD,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,MAAM,EAAE,GAAG,OAAO,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;IAEvD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC;QAC/B,GAAG,EAAE,GAAG,aAAa,KAAK,OAAO,IAAI,SAAS,EAAE;QAChD,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC;QAC1B,KAAK,EAAE,WAAW,OAAO,cAAc,IAAI,EAAE;QAC7C,MAAM,EAAE,MAAM,YAAY,CAAC,OAAO,CAAC;QACnC,WAAW,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC;KAC9C,CAAC,CAAC;IAEH,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAE7C,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAE,CAAC;AAC5F,CAAC,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC","sourcesContent":["import { mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { DigestRequest } from \"../download.js\";\nimport { runCliTool } from \"../../internal/run-cli-tool.js\";\nimport { cachedDigest, cacheDir, downloadFile, publishedDigest } from \"../download.js\";\nimport { LICENSE_FILENAME } from \"./license.js\";\n\ntype DownloadedNode = {\n path: string;\n licenseFile: string;\n};\n\nconst DIST_BASE_URL = \"https://nodejs.org/dist\";\nconst STRIP_COMPONENTS = \"1\";\nconst CHECKSUMS_FILE = \"SHASUMS256.txt\";\nconst NODE_PATH = \"bin/node\";\n\nconst releaseName = (version: string, arch: string): string => `node-v${version}-linux-${arch}`;\n\nconst digestRequest = (version: string, assetName: string, dir: string): DigestRequest => ({\n url: `${DIST_BASE_URL}/v${version}/${CHECKSUMS_FILE}`,\n dest: join(dir, `${assetName}.sha256`),\n assetName,\n subject: `Node.js ${version}`,\n});\n\nconst extractNode = (archive: string, dir: string, version: string, arch: string): void => {\n const release = releaseName(version, arch);\n\n runCliTool({\n tool: \"tar\",\n args: [\"-xJf\", archive, \"-C\", dir, \"--strip-components\", STRIP_COMPONENTS,\n `${release}/${NODE_PATH}`, `${release}/${LICENSE_FILENAME}`],\n target: `Node.js ${version}`,\n });\n};\n\nconst downloadNode = async (version: string, arch: string, destDir: string): Promise<DownloadedNode> => {\n const assetName = `${releaseName(version, arch)}.tar.xz`;\n const dir = cacheDir([\"node\", `${version}-linux-${arch}`]);\n const request = digestRequest(version, assetName, dir);\n\n const archive = await downloadFile({\n url: `${DIST_BASE_URL}/v${version}/${assetName}`,\n dest: join(dir, assetName),\n label: `Node.js ${version} for linux-${arch}`,\n
|
|
1
|
+
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../../src/deploy/node-runtime/download.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAOhD,MAAM,aAAa,GAAG,yBAAyB,CAAC;AAChD,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,MAAM,cAAc,GAAG,gBAAgB,CAAC;AACxC,MAAM,SAAS,GAAG,UAAU,CAAC;AAE7B,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,IAAY,EAAU,EAAE,CAAC,SAAS,OAAO,UAAU,IAAI,EAAE,CAAC;AAEhG,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,SAAiB,EAAE,GAAW,EAAiB,EAAE,CAAC,CAAC;IACvF,GAAG,EAAE,GAAG,aAAa,KAAK,OAAO,IAAI,cAAc,EAAE;IACrD,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,SAAS,CAAC;IACtC,SAAS;IACT,OAAO,EAAE,WAAW,OAAO,EAAE;CAChC,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,GAAW,EAAE,OAAe,EAAE,IAAY,EAAQ,EAAE;IACtF,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAE3C,UAAU,CAAC;QACP,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,oBAAoB,EAAE,gBAAgB;YACrE,GAAG,OAAO,IAAI,SAAS,EAAE,EAAE,GAAG,OAAO,IAAI,gBAAgB,EAAE,CAAC;QAChE,MAAM,EAAE,WAAW,OAAO,EAAE;KAC/B,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,KAAK,EAAE,OAAe,EAAE,IAAY,EAAE,OAAe,EAA2B,EAAE;IACnG,MAAM,SAAS,GAAG,GAAG,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC;IACzD,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,MAAM,EAAE,GAAG,OAAO,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;IAEvD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC;QAC/B,GAAG,EAAE,GAAG,aAAa,KAAK,OAAO,IAAI,SAAS,EAAE;QAChD,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC;QAC1B,KAAK,EAAE,WAAW,OAAO,cAAc,IAAI,EAAE;QAC7C,MAAM,EAAE,MAAM,YAAY,CAAC,OAAO,CAAC;QACnC,WAAW,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC;KAC9C,CAAC,CAAC;IAEH,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAE7C,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAE,CAAC;AAC5F,CAAC,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC","sourcesContent":["import { mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { DigestRequest } from \"../download.js\";\nimport { runCliTool } from \"../../internal/run-cli-tool.js\";\nimport { cachedDigest, cacheDir, downloadFile, publishedDigest } from \"../download.js\";\nimport { LICENSE_FILENAME } from \"./license.js\";\n\ntype DownloadedNode = {\n path: string;\n licenseFile: string;\n};\n\nconst DIST_BASE_URL = \"https://nodejs.org/dist\";\nconst STRIP_COMPONENTS = \"1\";\nconst CHECKSUMS_FILE = \"SHASUMS256.txt\";\nconst NODE_PATH = \"bin/node\";\n\nconst releaseName = (version: string, arch: string): string => `node-v${version}-linux-${arch}`;\n\nconst digestRequest = (version: string, assetName: string, dir: string): DigestRequest => ({\n url: `${DIST_BASE_URL}/v${version}/${CHECKSUMS_FILE}`,\n dest: join(dir, `${assetName}.sha256`),\n assetName,\n subject: `Node.js ${version}`,\n});\n\nconst extractNode = (archive: string, dir: string, version: string, arch: string): void => {\n const release = releaseName(version, arch);\n\n runCliTool({\n tool: \"tar\",\n args: [\"-xJf\", archive, \"-C\", dir, \"--strip-components\", STRIP_COMPONENTS,\n `${release}/${NODE_PATH}`, `${release}/${LICENSE_FILENAME}`],\n target: `Node.js ${version}`,\n });\n};\n\nconst downloadNode = async (version: string, arch: string, destDir: string): Promise<DownloadedNode> => {\n const assetName = `${releaseName(version, arch)}.tar.xz`;\n const dir = cacheDir([\"node\", `${version}-linux-${arch}`]);\n const request = digestRequest(version, assetName, dir);\n\n const archive = await downloadFile({\n url: `${DIST_BASE_URL}/v${version}/${assetName}`,\n dest: join(dir, assetName),\n label: `Node.js ${version} for linux-${arch}`,\n digest: await cachedDigest(request),\n freshDigest: () => publishedDigest(request),\n });\n\n mkdirSync(destDir, { recursive: true });\n extractNode(archive, destDir, version, arch);\n\n return { path: join(destDir, NODE_PATH), licenseFile: join(destDir, LICENSE_FILENAME) };\n};\n\nexport { downloadNode };\n"]}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
type ElfInfo = {
|
|
2
|
+
machine: number;
|
|
2
3
|
needed: string[];
|
|
3
4
|
glibcMinimum: string | null;
|
|
4
5
|
};
|
|
5
6
|
declare const readElfInfo: (path: string) => ElfInfo;
|
|
7
|
+
declare const readOptionalElfInfo: (path: string) => ElfInfo | null;
|
|
6
8
|
declare const glibcMinimumForFiles: (paths: Iterable<string>) => string | null;
|
|
7
|
-
export { type ElfInfo, glibcMinimumForFiles, readElfInfo };
|
|
9
|
+
export { type ElfInfo, glibcMinimumForFiles, readElfInfo, readOptionalElfInfo };
|
|
8
10
|
//# sourceMappingURL=elf.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elf.d.ts","sourceRoot":"","sources":["../../../src/deploy/node-runtime/elf.ts"],"names":[],"mappings":"AAQA,KAAK,OAAO,GAAG;IACX,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;
|
|
1
|
+
{"version":3,"file":"elf.d.ts","sourceRoot":"","sources":["../../../src/deploy/node-runtime/elf.ts"],"names":[],"mappings":"AAQA,KAAK,OAAO,GAAG;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AA0IF,QAAA,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,OAAkD,CAAC;AASvF,QAAA,MAAM,mBAAmB,GAAI,MAAM,MAAM,KAAG,OAAO,GAAG,IAUrD,CAAC;AAEF,QAAA,MAAM,oBAAoB,GAAI,OAAO,QAAQ,CAAC,MAAM,CAAC,KAAG,MAAM,GAAG,IAYhE,CAAC;AAEF,OAAO,EAAE,KAAK,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC"}
|
|
@@ -5,6 +5,7 @@ const CLASS_64 = 2;
|
|
|
5
5
|
const LITTLE_ENDIAN = 1;
|
|
6
6
|
const OFFSET_CLASS = 4;
|
|
7
7
|
const OFFSET_DATA = 5;
|
|
8
|
+
const OFFSET_MACHINE = 0x12;
|
|
8
9
|
const OFFSET_SECTION_HEADERS = 0x28;
|
|
9
10
|
const OFFSET_SECTION_ENTRY_SIZE = 0x3A;
|
|
10
11
|
const OFFSET_SECTION_COUNT = 0x3C;
|
|
@@ -93,6 +94,7 @@ const readElfBuffer = (buffer, path) => {
|
|
|
93
94
|
const sections = readSections(buffer);
|
|
94
95
|
const strings = stringTable(buffer, sectionFor(sections, ".dynstr"));
|
|
95
96
|
return {
|
|
97
|
+
machine: buffer.readUInt16LE(OFFSET_MACHINE),
|
|
96
98
|
needed: readNeeded(buffer, sectionFor(sections, ".dynamic"), strings),
|
|
97
99
|
glibcMinimum: readGlibcMinimum(strings),
|
|
98
100
|
};
|
|
@@ -123,5 +125,5 @@ const glibcMinimumForFiles = (paths) => {
|
|
|
123
125
|
}
|
|
124
126
|
return formatVersion(highestVersion(versions));
|
|
125
127
|
};
|
|
126
|
-
export { glibcMinimumForFiles, readElfInfo };
|
|
128
|
+
export { glibcMinimumForFiles, readElfInfo, readOptionalElfInfo };
|
|
127
129
|
//# sourceMappingURL=elf.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elf.js","sourceRoot":"","sources":["../../../src/deploy/node-runtime/elf.ts"],"names":[],"mappings":"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","sourcesContent":["import { closeSync, openSync, readFileSync, readSync } from \"node:fs\";\n\ntype ElfSection = {\n name: string;\n offset: number;\n size: number;\n};\n\ntype ElfInfo = {\n needed: string[];\n glibcMinimum: string | null;\n};\n\ntype DynamicEntry = {\n tag: number;\n value: number;\n};\n\nconst ELF_MAGIC = \"ELF\";\nconst ELF_MAGIC_SIZE = 4;\nconst CLASS_64 = 2;\nconst LITTLE_ENDIAN = 1;\nconst OFFSET_CLASS = 4;\nconst OFFSET_DATA = 5;\nconst OFFSET_SECTION_HEADERS = 0x28;\nconst OFFSET_SECTION_ENTRY_SIZE = 0x3A;\nconst OFFSET_SECTION_COUNT = 0x3C;\nconst OFFSET_SECTION_NAME_INDEX = 0x3E;\nconst SECTION_NAME = 0;\nconst SECTION_OFFSET = 24;\nconst SECTION_SIZE = 32;\nconst DYNAMIC_ENTRY_SIZE = 16;\nconst DT_NULL = 0;\nconst DT_NEEDED = 1;\nconst DYNAMIC_VALUE_OFFSET = 8;\nconst GLIBC_VERSION = /GLIBC_(\\d+)\\.(\\d+)/g;\nconst VERSION_RADIX = 1000;\n\nconst hasElfMagic = (buffer: Buffer): boolean =>\n buffer.length >= OFFSET_CLASS && buffer.subarray(0, 4).toString(\"latin1\") === ELF_MAGIC;\n\nconst assertElf64 = (buffer: Buffer, path: string): void => {\n if (buffer.length < OFFSET_SECTION_NAME_INDEX || !hasElfMagic(buffer)) {\n throw new Error(`Cannot read ${path}: it is not an ELF binary`);\n }\n\n if (buffer.readUInt8(OFFSET_CLASS) !== CLASS_64 || buffer.readUInt8(OFFSET_DATA) !== LITTLE_ENDIAN) {\n throw new Error(`Cannot read ${path}: only little-endian 64-bit ELF binaries are supported`);\n }\n};\n\nconst readCString = (buffer: Buffer, start: number): string => {\n const end = buffer.indexOf(0, start);\n\n return buffer.subarray(start, end === -1 ? buffer.length : end).toString(\"latin1\");\n};\n\nconst readSection = (buffer: Buffer, base: number, names: Buffer): ElfSection => ({\n name: readCString(names, buffer.readUInt32LE(base + SECTION_NAME)),\n offset: Number(buffer.readBigUInt64LE(base + SECTION_OFFSET)),\n size: Number(buffer.readBigUInt64LE(base + SECTION_SIZE)),\n});\n\nconst readSections = (buffer: Buffer): ElfSection[] => {\n const headers = Number(buffer.readBigUInt64LE(OFFSET_SECTION_HEADERS));\n const entrySize = buffer.readUInt16LE(OFFSET_SECTION_ENTRY_SIZE);\n const count = buffer.readUInt16LE(OFFSET_SECTION_COUNT);\n const nameIndex = buffer.readUInt16LE(OFFSET_SECTION_NAME_INDEX);\n const nameBase = headers + nameIndex * entrySize;\n const nameOffset = Number(buffer.readBigUInt64LE(nameBase + SECTION_OFFSET));\n const nameSize = Number(buffer.readBigUInt64LE(nameBase + SECTION_SIZE));\n const names = buffer.subarray(nameOffset, nameOffset + nameSize);\n\n return Array.from({ length: count }, (_, index) => readSection(buffer, headers + index * entrySize, names));\n};\n\nconst sectionFor = (sections: ElfSection[], name: string): ElfSection | undefined =>\n sections.find((section) => section.name === name);\n\nconst readDynamicEntries = (buffer: Buffer, dynamic: ElfSection): DynamicEntry[] => {\n const entries: DynamicEntry[] = [];\n\n for (let cursor = 0; cursor + DYNAMIC_ENTRY_SIZE <= dynamic.size; cursor += DYNAMIC_ENTRY_SIZE) {\n const base = dynamic.offset + cursor;\n const tag = Number(buffer.readBigUInt64LE(base));\n\n if (tag === DT_NULL) {\n break;\n }\n\n entries.push({ tag, value: Number(buffer.readBigUInt64LE(base + DYNAMIC_VALUE_OFFSET)) });\n }\n\n return entries;\n};\n\nconst readNeeded = (buffer: Buffer, dynamic: ElfSection | undefined, strings: Buffer): string[] => {\n if (dynamic === undefined) {\n return [];\n }\n\n return readDynamicEntries(buffer, dynamic)\n .filter((entry) => entry.tag === DT_NEEDED)\n .map((entry) => readCString(strings, entry.value));\n};\n\nconst getRank = (version: number[]): number => (version[0] ?? 0) * VERSION_RADIX + (version[1] ?? 0);\n\nconst highestVersion = (versions: number[][]): number[] | null => {\n let highest: number[] | null = null;\n\n for (const version of versions) {\n if (highest === null || getRank(version) > getRank(highest)) {\n highest = version;\n }\n }\n\n return highest;\n};\n\nconst formatVersion = (version: number[] | null): string | null =>\n version === null ? null : `${String(version[0] ?? 0)}.${String(version[1] ?? 0)}`;\n\nconst readGlibcMinimum = (strings: Buffer): string | null => {\n const found = strings\n .toString(\"latin1\")\n .matchAll(GLIBC_VERSION)\n .map((match) => [Number(match[1]), Number(match[2])])\n .toArray();\n\n return formatVersion(highestVersion(found));\n};\n\nconst stringTable = (buffer: Buffer, dynstr: ElfSection | undefined): Buffer =>\n dynstr === undefined ? Buffer.alloc(0) : buffer.subarray(dynstr.offset, dynstr.offset + dynstr.size);\n\nconst readElfBuffer = (buffer: Buffer, path: string): ElfInfo => {\n assertElf64(buffer, path);\n const sections = readSections(buffer);\n const strings = stringTable(buffer, sectionFor(sections, \".dynstr\"));\n\n return {\n needed: readNeeded(buffer, sectionFor(sections, \".dynamic\"), strings),\n glibcMinimum: readGlibcMinimum(strings),\n };\n};\n\nconst readElfInfo = (path: string): ElfInfo => readElfBuffer(readFileSync(path), path);\n\nconst readFilePrefix = (descriptor: number, size: number): Buffer => {\n const buffer = Buffer.alloc(size);\n const bytesRead = readSync(descriptor, buffer, 0, size, 0);\n\n return buffer.subarray(0, bytesRead);\n};\n\nconst readOptionalElfInfo = (path: string): ElfInfo | null => {\n const descriptor = openSync(path, \"r\");\n\n try {\n const prefix = readFilePrefix(descriptor, ELF_MAGIC_SIZE);\n\n return hasElfMagic(prefix) ? readElfBuffer(readFileSync(descriptor), path) : null;\n } finally {\n closeSync(descriptor);\n }\n};\n\nconst glibcMinimumForFiles = (paths: Iterable<string>): string | null => {\n const versions: number[][] = [];\n\n for (const path of paths) {\n const minimum = readOptionalElfInfo(path)?.glibcMinimum;\n\n if (minimum !== undefined && minimum !== null) {\n versions.push(minimum.split(\".\").map(Number));\n }\n }\n\n return formatVersion(highestVersion(versions));\n};\n\nexport { type ElfInfo, glibcMinimumForFiles, readElfInfo };\n"]}
|
|
1
|
+
{"version":3,"file":"elf.js","sourceRoot":"","sources":["../../../src/deploy/node-runtime/elf.ts"],"names":[],"mappings":"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","sourcesContent":["import { closeSync, openSync, readFileSync, readSync } from \"node:fs\";\n\ntype ElfSection = {\n name: string;\n offset: number;\n size: number;\n};\n\ntype ElfInfo = {\n machine: number;\n needed: string[];\n glibcMinimum: string | null;\n};\n\ntype DynamicEntry = {\n tag: number;\n value: number;\n};\n\nconst ELF_MAGIC = \"ELF\";\nconst ELF_MAGIC_SIZE = 4;\nconst CLASS_64 = 2;\nconst LITTLE_ENDIAN = 1;\nconst OFFSET_CLASS = 4;\nconst OFFSET_DATA = 5;\nconst OFFSET_MACHINE = 0x12;\nconst OFFSET_SECTION_HEADERS = 0x28;\nconst OFFSET_SECTION_ENTRY_SIZE = 0x3A;\nconst OFFSET_SECTION_COUNT = 0x3C;\nconst OFFSET_SECTION_NAME_INDEX = 0x3E;\nconst SECTION_NAME = 0;\nconst SECTION_OFFSET = 24;\nconst SECTION_SIZE = 32;\nconst DYNAMIC_ENTRY_SIZE = 16;\nconst DT_NULL = 0;\nconst DT_NEEDED = 1;\nconst DYNAMIC_VALUE_OFFSET = 8;\nconst GLIBC_VERSION = /GLIBC_(\\d+)\\.(\\d+)/g;\nconst VERSION_RADIX = 1000;\n\nconst hasElfMagic = (buffer: Buffer): boolean =>\n buffer.length >= OFFSET_CLASS && buffer.subarray(0, 4).toString(\"latin1\") === ELF_MAGIC;\n\nconst assertElf64 = (buffer: Buffer, path: string): void => {\n if (buffer.length < OFFSET_SECTION_NAME_INDEX || !hasElfMagic(buffer)) {\n throw new Error(`Cannot read ${path}: it is not an ELF binary`);\n }\n\n if (buffer.readUInt8(OFFSET_CLASS) !== CLASS_64 || buffer.readUInt8(OFFSET_DATA) !== LITTLE_ENDIAN) {\n throw new Error(`Cannot read ${path}: only little-endian 64-bit ELF binaries are supported`);\n }\n};\n\nconst readCString = (buffer: Buffer, start: number): string => {\n const end = buffer.indexOf(0, start);\n\n return buffer.subarray(start, end === -1 ? buffer.length : end).toString(\"latin1\");\n};\n\nconst readSection = (buffer: Buffer, base: number, names: Buffer): ElfSection => ({\n name: readCString(names, buffer.readUInt32LE(base + SECTION_NAME)),\n offset: Number(buffer.readBigUInt64LE(base + SECTION_OFFSET)),\n size: Number(buffer.readBigUInt64LE(base + SECTION_SIZE)),\n});\n\nconst readSections = (buffer: Buffer): ElfSection[] => {\n const headers = Number(buffer.readBigUInt64LE(OFFSET_SECTION_HEADERS));\n const entrySize = buffer.readUInt16LE(OFFSET_SECTION_ENTRY_SIZE);\n const count = buffer.readUInt16LE(OFFSET_SECTION_COUNT);\n const nameIndex = buffer.readUInt16LE(OFFSET_SECTION_NAME_INDEX);\n const nameBase = headers + nameIndex * entrySize;\n const nameOffset = Number(buffer.readBigUInt64LE(nameBase + SECTION_OFFSET));\n const nameSize = Number(buffer.readBigUInt64LE(nameBase + SECTION_SIZE));\n const names = buffer.subarray(nameOffset, nameOffset + nameSize);\n\n return Array.from({ length: count }, (_, index) => readSection(buffer, headers + index * entrySize, names));\n};\n\nconst sectionFor = (sections: ElfSection[], name: string): ElfSection | undefined =>\n sections.find((section) => section.name === name);\n\nconst readDynamicEntries = (buffer: Buffer, dynamic: ElfSection): DynamicEntry[] => {\n const entries: DynamicEntry[] = [];\n\n for (let cursor = 0; cursor + DYNAMIC_ENTRY_SIZE <= dynamic.size; cursor += DYNAMIC_ENTRY_SIZE) {\n const base = dynamic.offset + cursor;\n const tag = Number(buffer.readBigUInt64LE(base));\n\n if (tag === DT_NULL) {\n break;\n }\n\n entries.push({ tag, value: Number(buffer.readBigUInt64LE(base + DYNAMIC_VALUE_OFFSET)) });\n }\n\n return entries;\n};\n\nconst readNeeded = (buffer: Buffer, dynamic: ElfSection | undefined, strings: Buffer): string[] => {\n if (dynamic === undefined) {\n return [];\n }\n\n return readDynamicEntries(buffer, dynamic)\n .filter((entry) => entry.tag === DT_NEEDED)\n .map((entry) => readCString(strings, entry.value));\n};\n\nconst getRank = (version: number[]): number => (version[0] ?? 0) * VERSION_RADIX + (version[1] ?? 0);\n\nconst highestVersion = (versions: number[][]): number[] | null => {\n let highest: number[] | null = null;\n\n for (const version of versions) {\n if (highest === null || getRank(version) > getRank(highest)) {\n highest = version;\n }\n }\n\n return highest;\n};\n\nconst formatVersion = (version: number[] | null): string | null =>\n version === null ? null : `${String(version[0] ?? 0)}.${String(version[1] ?? 0)}`;\n\nconst readGlibcMinimum = (strings: Buffer): string | null => {\n const found = strings\n .toString(\"latin1\")\n .matchAll(GLIBC_VERSION)\n .map((match) => [Number(match[1]), Number(match[2])])\n .toArray();\n\n return formatVersion(highestVersion(found));\n};\n\nconst stringTable = (buffer: Buffer, dynstr: ElfSection | undefined): Buffer =>\n dynstr === undefined ? Buffer.alloc(0) : buffer.subarray(dynstr.offset, dynstr.offset + dynstr.size);\n\nconst readElfBuffer = (buffer: Buffer, path: string): ElfInfo => {\n assertElf64(buffer, path);\n const sections = readSections(buffer);\n const strings = stringTable(buffer, sectionFor(sections, \".dynstr\"));\n\n return {\n machine: buffer.readUInt16LE(OFFSET_MACHINE),\n needed: readNeeded(buffer, sectionFor(sections, \".dynamic\"), strings),\n glibcMinimum: readGlibcMinimum(strings),\n };\n};\n\nconst readElfInfo = (path: string): ElfInfo => readElfBuffer(readFileSync(path), path);\n\nconst readFilePrefix = (descriptor: number, size: number): Buffer => {\n const buffer = Buffer.alloc(size);\n const bytesRead = readSync(descriptor, buffer, 0, size, 0);\n\n return buffer.subarray(0, bytesRead);\n};\n\nconst readOptionalElfInfo = (path: string): ElfInfo | null => {\n const descriptor = openSync(path, \"r\");\n\n try {\n const prefix = readFilePrefix(descriptor, ELF_MAGIC_SIZE);\n\n return hasElfMagic(prefix) ? readElfBuffer(readFileSync(descriptor), path) : null;\n } finally {\n closeSync(descriptor);\n }\n};\n\nconst glibcMinimumForFiles = (paths: Iterable<string>): string | null => {\n const versions: number[][] = [];\n\n for (const path of paths) {\n const minimum = readOptionalElfInfo(path)?.glibcMinimum;\n\n if (minimum !== undefined && minimum !== null) {\n versions.push(minimum.split(\".\").map(Number));\n }\n }\n\n return formatVersion(highestVersion(versions));\n};\n\nexport { type ElfInfo, glibcMinimumForFiles, readElfInfo, readOptionalElfInfo };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/deploy/node-runtime/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/deploy/node-runtime/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAgB,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAgG7E,QAAA,MAAM,aAAa,GAAI,UAAU,cAAc,KAAG,MAajD,CAAC;AAEF,QAAA,MAAM,kBAAkB,GAAI,UAAU,cAAc,KAAG,MAatD,CAAC;AAgEF,QAAA,MAAM,kBAAkB,GAAU,UAAU,cAAc,KAAG,OAAO,CAAC,WAAW,CAW/E,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { MINIMUM_NODE_VERSION } from "@gtkx/config/internal";
|
|
2
|
-
import { info, tryResolveExecutable } from "@gtkx/utils";
|
|
2
|
+
import { info, tryResolveExecutable, warn } from "@gtkx/utils";
|
|
3
3
|
import { execFileSync } from "node:child_process";
|
|
4
4
|
import { chmodSync, copyFileSync, mkdirSync, statSync } from "node:fs";
|
|
5
5
|
import { join, resolve } from "node:path";
|
|
6
6
|
import { runCliTool } from "../../internal/run-cli-tool.js";
|
|
7
|
+
import { elfMachineFor, hostArchName } from "../settings/arch.js";
|
|
7
8
|
import { downloadNode } from "./download.js";
|
|
8
9
|
import { readElfInfo } from "./elf.js";
|
|
9
10
|
import { assertPortableNode } from "./guard.js";
|
|
@@ -117,13 +118,24 @@ const stageFromSource = async (settings, version, source) => {
|
|
|
117
118
|
assertPortableNode(readElfInfo(sourcePath), source);
|
|
118
119
|
return { path: stageNode(settings, sourcePath), licenseFile: licenseBesideNode(sourcePath) };
|
|
119
120
|
};
|
|
121
|
+
const shouldStripRuntime = (settings, node, elf) => {
|
|
122
|
+
if (node.shouldStrip === false) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
if (elf.machine === elfMachineFor(hostArchName())) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
warn(`Skipping \`strip\` on the bundled Node.js: it was built for ${settings.arch.node} and \`strip\` reads ` +
|
|
129
|
+
`only ${hostArchName()}. The ${settings.arch.node} packages carry an unstripped runtime.`);
|
|
130
|
+
return false;
|
|
131
|
+
};
|
|
120
132
|
const resolveNodeRuntime = async (settings) => {
|
|
121
133
|
const node = settings.deploy.node ?? {};
|
|
122
134
|
const source = nodeSourceFor(settings);
|
|
123
135
|
const version = resolveNodeVersion(settings);
|
|
124
136
|
const staged = await stageFromSource(settings, version, source);
|
|
125
|
-
const isStripped = node.shouldStrip === false ? false : didStripBinary(staged.path);
|
|
126
137
|
const elf = readElfInfo(staged.path);
|
|
138
|
+
const isStripped = shouldStripRuntime(settings, node, elf) && didStripBinary(staged.path);
|
|
127
139
|
const glibcMinimum = elf.glibcMinimum ?? "unknown";
|
|
128
140
|
info(`Bundled Node.js v${version} (${megabytes(staged.path)} MiB, runtime glibc >= ${glibcMinimum})`);
|
|
129
141
|
return { ...staged, version, glibcMinimum: elf.glibcMinimum, isStripped };
|