@hagicode/hagiscript 0.1.0-dev.9.1.ba06982
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/README.md +251 -0
- package/README_cn.md +251 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +50 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/node-runtime-commands.d.ts +2 -0
- package/dist/commands/node-runtime-commands.js +88 -0
- package/dist/commands/node-runtime-commands.js.map +1 -0
- package/dist/commands/npm-sync-commands.d.ts +2 -0
- package/dist/commands/npm-sync-commands.js +155 -0
- package/dist/commands/npm-sync-commands.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/node-download.d.ts +13 -0
- package/dist/runtime/node-download.js +78 -0
- package/dist/runtime/node-download.js.map +1 -0
- package/dist/runtime/node-extract.d.ts +6 -0
- package/dist/runtime/node-extract.js +155 -0
- package/dist/runtime/node-extract.js.map +1 -0
- package/dist/runtime/node-installer.d.ts +39 -0
- package/dist/runtime/node-installer.js +85 -0
- package/dist/runtime/node-installer.js.map +1 -0
- package/dist/runtime/node-platform.d.ts +14 -0
- package/dist/runtime/node-platform.js +41 -0
- package/dist/runtime/node-platform.js.map +1 -0
- package/dist/runtime/node-release.d.ts +28 -0
- package/dist/runtime/node-release.js +146 -0
- package/dist/runtime/node-release.js.map +1 -0
- package/dist/runtime/node-verify.d.ts +20 -0
- package/dist/runtime/node-verify.js +66 -0
- package/dist/runtime/node-verify.js.map +1 -0
- package/dist/runtime/npm-global.d.ts +20 -0
- package/dist/runtime/npm-global.js +53 -0
- package/dist/runtime/npm-global.js.map +1 -0
- package/dist/runtime/npm-sync.d.ts +114 -0
- package/dist/runtime/npm-sync.js +398 -0
- package/dist/runtime/npm-sync.js.map +1 -0
- package/dist/runtime/tool-sync-catalog.config.json +59 -0
- package/dist/runtime/tool-sync-catalog.d.ts +48 -0
- package/dist/runtime/tool-sync-catalog.js +189 -0
- package/dist/runtime/tool-sync-catalog.js.map +1 -0
- package/dist/version.d.ts +7 -0
- package/dist/version.js +9 -0
- package/dist/version.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { InvalidArgumentError } from "commander";
|
|
2
|
+
import { mkdtemp, writeFile } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { getDefaultManagedNodeRuntimeDirectory, resolveManagedNodeRuntime } from "../runtime/node-installer.js";
|
|
6
|
+
import { NpmManifestValidationError, NpmSyncCommandError, syncNpmGlobals } from "../runtime/npm-sync.js";
|
|
7
|
+
export function registerNpmSyncCommand(program) {
|
|
8
|
+
program
|
|
9
|
+
.command("npm-sync")
|
|
10
|
+
.description("sync managed npm tools using HagiScript's Node.js runtime, or an explicit runtime for compatibility")
|
|
11
|
+
.option("--runtime <path>", "explicit Node.js runtime directory")
|
|
12
|
+
.option("--managed-runtime <path>", "HagiScript-managed runtime directory to verify or install before sync")
|
|
13
|
+
.option("--manifest <path>", "npm-sync manifest JSON file")
|
|
14
|
+
.option("--selected-agent-cli <id>", "selected optional agent CLI ID for product-managed tool sync", collectValues, [])
|
|
15
|
+
.option("--custom-agent-cli <package[@version]>", "custom npm-installable agent CLI for product-managed tool sync", collectValues, [])
|
|
16
|
+
.action(async (options, command) => {
|
|
17
|
+
const explicitRuntime = options.runtime
|
|
18
|
+
? validatePathOption(options.runtime, "--runtime")
|
|
19
|
+
: undefined;
|
|
20
|
+
const selectedAgentCliIds = options.selectedAgentCli ?? [];
|
|
21
|
+
const customAgentCliSelectors = options.customAgentCli ?? [];
|
|
22
|
+
const hasInlineToolSelection = selectedAgentCliIds.length > 0 || customAgentCliSelectors.length > 0;
|
|
23
|
+
const manifestPath = options.manifest
|
|
24
|
+
? validatePathOption(options.manifest, "--manifest")
|
|
25
|
+
: hasInlineToolSelection
|
|
26
|
+
? await writeInlineToolManifest(selectedAgentCliIds, customAgentCliSelectors)
|
|
27
|
+
: undefined;
|
|
28
|
+
if (!manifestPath) {
|
|
29
|
+
throw new InvalidArgumentError("--manifest is required unless --selected-agent-cli or --custom-agent-cli is provided.");
|
|
30
|
+
}
|
|
31
|
+
const managedRuntimePath = options.managedRuntime
|
|
32
|
+
? validatePathOption(options.managedRuntime, "--managed-runtime")
|
|
33
|
+
: getDefaultManagedNodeRuntimeDirectory();
|
|
34
|
+
try {
|
|
35
|
+
const runtimePath = explicitRuntime ?? (await resolveManagedNodeRuntime({
|
|
36
|
+
targetDirectory: managedRuntimePath
|
|
37
|
+
})).targetDirectory;
|
|
38
|
+
await syncNpmGlobals({
|
|
39
|
+
runtimePath,
|
|
40
|
+
manifestPath,
|
|
41
|
+
onLog: printNpmSyncLog
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
command.error(formatNpmSyncError(error), { exitCode: 1 });
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function collectValues(value, previous) {
|
|
50
|
+
return [...previous, value];
|
|
51
|
+
}
|
|
52
|
+
async function writeInlineToolManifest(selectedAgentCliIds, customAgentCliSelectors) {
|
|
53
|
+
const directory = await mkdtemp(join(tmpdir(), "hagiscript-tool-sync-"));
|
|
54
|
+
const manifestPath = join(directory, "manifest.json");
|
|
55
|
+
await writeFile(manifestPath, JSON.stringify({
|
|
56
|
+
tools: {
|
|
57
|
+
optionalAgentCliSyncEnabled: true,
|
|
58
|
+
selectedOptionalAgentCliIds: selectedAgentCliIds,
|
|
59
|
+
customAgentClis: customAgentCliSelectors.map(parseCustomAgentCli)
|
|
60
|
+
}
|
|
61
|
+
}, null, 2));
|
|
62
|
+
return manifestPath;
|
|
63
|
+
}
|
|
64
|
+
function parseCustomAgentCli(selector) {
|
|
65
|
+
const trimmed = selector.trim();
|
|
66
|
+
const versionSeparator = trimmed.startsWith("@")
|
|
67
|
+
? trimmed.indexOf("@", 1)
|
|
68
|
+
: trimmed.indexOf("@");
|
|
69
|
+
if (versionSeparator <= 0) {
|
|
70
|
+
return { packageName: trimmed };
|
|
71
|
+
}
|
|
72
|
+
const packageName = trimmed.slice(0, versionSeparator);
|
|
73
|
+
const version = trimmed.slice(versionSeparator + 1);
|
|
74
|
+
return {
|
|
75
|
+
packageName,
|
|
76
|
+
version,
|
|
77
|
+
target: version
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function validatePathOption(value, optionName) {
|
|
81
|
+
const normalized = value?.trim();
|
|
82
|
+
if (!normalized) {
|
|
83
|
+
throw new InvalidArgumentError(`${optionName} must be a non-empty path.`);
|
|
84
|
+
}
|
|
85
|
+
if (normalized.includes("\0")) {
|
|
86
|
+
throw new InvalidArgumentError(`${optionName} contains an invalid null byte.`);
|
|
87
|
+
}
|
|
88
|
+
return normalized;
|
|
89
|
+
}
|
|
90
|
+
function printNpmSyncLog(event) {
|
|
91
|
+
switch (event.type) {
|
|
92
|
+
case "manifest-loaded":
|
|
93
|
+
process.stdout.write(`Manifest validated: ${event.manifestPath} (${event.packageCount} packages, mode=${event.syncMode})\n`);
|
|
94
|
+
break;
|
|
95
|
+
case "runtime-valid":
|
|
96
|
+
process.stdout.write(`Runtime validated: ${event.runtime.targetDirectory}\n`);
|
|
97
|
+
process.stdout.write(`node: ${event.runtime.nodePath} (${event.runtime.nodeVersion})\n`);
|
|
98
|
+
process.stdout.write(`npm: ${event.runtime.npmPath} (${event.runtime.npmVersion})\n`);
|
|
99
|
+
break;
|
|
100
|
+
case "inventory":
|
|
101
|
+
process.stdout.write(`Detected global packages: ${Object.keys(event.packages).sort().length}\n`);
|
|
102
|
+
break;
|
|
103
|
+
case "planned-action":
|
|
104
|
+
process.stdout.write(`Plan: ${event.action.packageName} ${event.action.action} installed=${event.action.installedVersion ?? "missing"} required=${event.action.requiredRange} selector=${event.action.selectedInstallSelector}${formatToolMetadata(event.action)}\n`);
|
|
105
|
+
break;
|
|
106
|
+
case "skip":
|
|
107
|
+
process.stdout.write(`Skip: ${event.action.packageName} already satisfies range\n`);
|
|
108
|
+
break;
|
|
109
|
+
case "install-start":
|
|
110
|
+
process.stdout.write(`Install: ${event.action.packageName} using ${event.action.selectedInstallSelector}\n`);
|
|
111
|
+
break;
|
|
112
|
+
case "install-complete":
|
|
113
|
+
process.stdout.write(`Synced: ${event.action.packageName} (${event.action.action})\n`);
|
|
114
|
+
break;
|
|
115
|
+
case "summary":
|
|
116
|
+
printSummary(event.summary);
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function printSummary(summary) {
|
|
121
|
+
process.stdout.write(`npm-sync complete.\n`);
|
|
122
|
+
process.stdout.write(`Runtime: ${summary.runtime.targetDirectory}\n`);
|
|
123
|
+
process.stdout.write(`Manifest: ${summary.manifestPath}\n`);
|
|
124
|
+
process.stdout.write(`Mode: ${summary.syncMode}\n`);
|
|
125
|
+
process.stdout.write(`Packages: ${summary.packageCount}\n`);
|
|
126
|
+
process.stdout.write(`No-op: ${summary.noopCount}\n`);
|
|
127
|
+
process.stdout.write(`Changed: ${summary.changedCount}\n`);
|
|
128
|
+
}
|
|
129
|
+
function formatToolMetadata(action) {
|
|
130
|
+
if (!action.toolId) {
|
|
131
|
+
return "";
|
|
132
|
+
}
|
|
133
|
+
return ` tool=${action.toolId} group=${action.toolGroup ?? "unknown"}`;
|
|
134
|
+
}
|
|
135
|
+
function formatNpmSyncError(error) {
|
|
136
|
+
if (error instanceof NpmManifestValidationError) {
|
|
137
|
+
return error.message;
|
|
138
|
+
}
|
|
139
|
+
if (error instanceof NpmSyncCommandError) {
|
|
140
|
+
const lines = [error.message];
|
|
141
|
+
if (error.packageName) {
|
|
142
|
+
lines.push(`Package: ${error.packageName}`);
|
|
143
|
+
}
|
|
144
|
+
lines.push(`Command: ${error.command} ${error.args.join(" ")}`);
|
|
145
|
+
if (error.stderr.trim().length > 0) {
|
|
146
|
+
lines.push(`stderr: ${error.stderr.trim()}`);
|
|
147
|
+
}
|
|
148
|
+
if (error.stdout.trim().length > 0) {
|
|
149
|
+
lines.push(`stdout: ${error.stdout.trim()}`);
|
|
150
|
+
}
|
|
151
|
+
return lines.join("\n");
|
|
152
|
+
}
|
|
153
|
+
return error instanceof Error ? error.message : String(error);
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=npm-sync-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm-sync-commands.js","sourceRoot":"","sources":["../../src/commands/npm-sync-commands.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { getPackageMetadata, packageName, packageVersion, type PackageMetadata } from "./version.js";
|
|
2
|
+
export interface HagiscriptRuntimeInfo {
|
|
3
|
+
packageName: string;
|
|
4
|
+
version: string;
|
|
5
|
+
status: "foundation";
|
|
6
|
+
}
|
|
7
|
+
export declare function createRuntimeInfo(): HagiscriptRuntimeInfo;
|
|
8
|
+
export { getDefaultManagedNodeRuntimeDirectory, installNodeRuntime, resolveManagedNodeRuntime, type InstallNodeRuntimeResult, type ResolveManagedNodeRuntimeResult } from "./runtime/node-installer.js";
|
|
9
|
+
export { verifyNodeRuntime, type NodeRuntimeVerificationResult } from "./runtime/node-verify.js";
|
|
10
|
+
export { createNpmSyncPlan, loadNpmSyncManifest, normalizeGlobalInventory, syncNpmGlobals, validateNpmSyncManifest, type InstalledGlobalPackages, type NpmSyncActionKind, type NpmSyncActionResult, type NpmSyncManifest, type NpmSyncManifestEntry, type NpmSyncPlannedAction, type NpmSyncRuntimeMetadata, type NpmSyncSummary } from "./runtime/npm-sync.js";
|
|
11
|
+
export { buildToolSyncPackageSet, builtInToolSyncCatalog, normalizeToolSyncEntry, validateToolSyncCatalog, type CustomAgentCliToolInput, type ToolSyncCatalogEntry, type ToolSyncGroupId, type ToolSyncPackageConstraint, type ToolSyncRequirement, type ToolSyncSelection } from "./runtime/tool-sync-catalog.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { packageName, packageVersion } from "./version.js";
|
|
2
|
+
export { getPackageMetadata, packageName, packageVersion } from "./version.js";
|
|
3
|
+
export function createRuntimeInfo() {
|
|
4
|
+
return {
|
|
5
|
+
packageName,
|
|
6
|
+
version: packageVersion,
|
|
7
|
+
status: "foundation"
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export { getDefaultManagedNodeRuntimeDirectory, installNodeRuntime, resolveManagedNodeRuntime } from "./runtime/node-installer.js";
|
|
11
|
+
export { verifyNodeRuntime } from "./runtime/node-verify.js";
|
|
12
|
+
export { createNpmSyncPlan, loadNpmSyncManifest, normalizeGlobalInventory, syncNpmGlobals, validateNpmSyncManifest } from "./runtime/npm-sync.js";
|
|
13
|
+
export { buildToolSyncPackageSet, builtInToolSyncCatalog, normalizeToolSyncEntry, validateToolSyncCatalog } from "./runtime/tool-sync-catalog.js";
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,cAAc,EAEf,MAAM,cAAc,CAAC;AAQtB,MAAM,UAAU,iBAAiB;IAC/B,OAAO;QACL,WAAW;QACX,OAAO,EAAE,cAAc;QACvB,MAAM,EAAE,YAAY;KACrB,CAAC;AACJ,CAAC;AAED,OAAO,EACL,qCAAqC,EACrC,kBAAkB,EAClB,yBAAyB,EAG1B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,iBAAiB,EAElB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,cAAc,EACd,uBAAuB,EASxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EAOxB,MAAM,gCAAgC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface DownloadProgress {
|
|
2
|
+
receivedBytes: number;
|
|
3
|
+
totalBytes?: number;
|
|
4
|
+
}
|
|
5
|
+
export interface DownloadOptions {
|
|
6
|
+
fetchImpl?: typeof fetch;
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
onProgress?: (progress: DownloadProgress) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare class NodeRuntimeNetworkError extends Error {
|
|
11
|
+
constructor(message: string, options?: ErrorOptions);
|
|
12
|
+
}
|
|
13
|
+
export declare function downloadNodeArchive(url: string, destinationPath: string, options?: DownloadOptions): Promise<void>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { createWriteStream } from "node:fs";
|
|
2
|
+
import { mkdir } from "node:fs/promises";
|
|
3
|
+
import { dirname } from "node:path";
|
|
4
|
+
export class NodeRuntimeNetworkError extends Error {
|
|
5
|
+
constructor(message, options) {
|
|
6
|
+
super(message, options);
|
|
7
|
+
this.name = "NodeRuntimeNetworkError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export async function downloadNodeArchive(url, destinationPath, options = {}) {
|
|
11
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
12
|
+
const timeoutMs = options.timeoutMs ?? 120_000;
|
|
13
|
+
const abortController = new AbortController();
|
|
14
|
+
const timeout = setTimeout(() => abortController.abort(), timeoutMs);
|
|
15
|
+
try {
|
|
16
|
+
const response = await fetchImpl(url, { signal: abortController.signal });
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
throw new NodeRuntimeNetworkError(`Failed to download Node.js archive: HTTP ${response.status}`);
|
|
19
|
+
}
|
|
20
|
+
if (!response.body) {
|
|
21
|
+
throw new NodeRuntimeNetworkError("Failed to download Node.js archive: response body was empty.");
|
|
22
|
+
}
|
|
23
|
+
await mkdir(dirname(destinationPath), { recursive: true });
|
|
24
|
+
const totalBytes = parseContentLength(response.headers.get("content-length"));
|
|
25
|
+
let receivedBytes = 0;
|
|
26
|
+
await writeResponseBody(response.body, destinationPath, (chunkLength) => {
|
|
27
|
+
receivedBytes += chunkLength;
|
|
28
|
+
options.onProgress?.({ receivedBytes, totalBytes });
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (error instanceof NodeRuntimeNetworkError) {
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
36
|
+
throw new NodeRuntimeNetworkError(`Failed to download Node.js archive: ${reason}`, error instanceof Error ? { cause: error } : undefined);
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
clearTimeout(timeout);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function writeResponseBody(body, destinationPath, onChunk) {
|
|
43
|
+
const reader = body.getReader();
|
|
44
|
+
const file = createWriteStream(destinationPath);
|
|
45
|
+
try {
|
|
46
|
+
while (true) {
|
|
47
|
+
const { done, value } = await reader.read();
|
|
48
|
+
if (done) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
onChunk(value.byteLength);
|
|
52
|
+
if (!file.write(value)) {
|
|
53
|
+
await new Promise((resolve) => file.once("drain", resolve));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
await new Promise((resolve, reject) => {
|
|
57
|
+
file.end((error) => {
|
|
58
|
+
if (error) {
|
|
59
|
+
reject(error);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
resolve();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
reader.releaseLock();
|
|
68
|
+
file.close();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function parseContentLength(value) {
|
|
72
|
+
if (!value) {
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
const parsed = Number(value);
|
|
76
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : undefined;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=node-download.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-download.js","sourceRoot":"","sources":["../../src/runtime/node-download.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare class NodeRuntimeExtractionError extends Error {
|
|
2
|
+
constructor(message: string, options?: ErrorOptions);
|
|
3
|
+
}
|
|
4
|
+
export declare function extractNodeArchive(archivePath: string, stagingDirectory: string, archiveExtension: "zip" | "tar.xz"): Promise<string>;
|
|
5
|
+
export declare function moveExtractedRootToTarget(extractedRoot: string, targetDirectory: string): Promise<void>;
|
|
6
|
+
export declare function assertTargetIsEmptyOrMissing(targetDirectory: string): Promise<void>;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { createWriteStream } from "node:fs";
|
|
2
|
+
import { mkdir, readdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, join, relative, sep } from "node:path";
|
|
4
|
+
import { spawn } from "node:child_process";
|
|
5
|
+
import { createGunzip, gunzipSync } from "node:zlib";
|
|
6
|
+
import { pipeline } from "node:stream/promises";
|
|
7
|
+
import { createReadStream } from "node:fs";
|
|
8
|
+
export class NodeRuntimeExtractionError extends Error {
|
|
9
|
+
constructor(message, options) {
|
|
10
|
+
super(message, options);
|
|
11
|
+
this.name = "NodeRuntimeExtractionError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function extractNodeArchive(archivePath, stagingDirectory, archiveExtension) {
|
|
15
|
+
await mkdir(stagingDirectory, { recursive: true });
|
|
16
|
+
if (archiveExtension === "zip") {
|
|
17
|
+
await extractZip(archivePath, stagingDirectory);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
await extractTar(archivePath, stagingDirectory);
|
|
21
|
+
}
|
|
22
|
+
return findExtractedRoot(stagingDirectory);
|
|
23
|
+
}
|
|
24
|
+
export async function moveExtractedRootToTarget(extractedRoot, targetDirectory) {
|
|
25
|
+
await assertTargetIsEmptyOrMissing(targetDirectory);
|
|
26
|
+
await mkdir(dirname(targetDirectory), { recursive: true });
|
|
27
|
+
await rm(targetDirectory, { recursive: true, force: true });
|
|
28
|
+
await rename(extractedRoot, targetDirectory);
|
|
29
|
+
}
|
|
30
|
+
export async function assertTargetIsEmptyOrMissing(targetDirectory) {
|
|
31
|
+
try {
|
|
32
|
+
const entries = await readdir(targetDirectory);
|
|
33
|
+
if (entries.length > 0) {
|
|
34
|
+
throw new NodeRuntimeExtractionError(`Target directory is not empty: ${targetDirectory}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (error.code === "ENOENT") {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (error instanceof NodeRuntimeExtractionError) {
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
const stats = await stat(targetDirectory).catch(() => undefined);
|
|
45
|
+
if (stats && !stats.isDirectory()) {
|
|
46
|
+
throw new NodeRuntimeExtractionError(`Target path exists but is not a directory: ${targetDirectory}`);
|
|
47
|
+
}
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async function extractZip(archivePath, destination) {
|
|
52
|
+
const extractors = ["unzip", "bsdtar"];
|
|
53
|
+
let lastError;
|
|
54
|
+
for (const extractor of extractors) {
|
|
55
|
+
try {
|
|
56
|
+
const args = extractor === "unzip"
|
|
57
|
+
? ["-q", archivePath, "-d", destination]
|
|
58
|
+
: ["-xf", archivePath, "-C", destination];
|
|
59
|
+
await runExtractor(extractor, args);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
throw new NodeRuntimeExtractionError("Failed to extract zip archive. Install unzip or bsdtar, or provide a valid Node.js archive.", lastError ? { cause: lastError } : undefined);
|
|
67
|
+
}
|
|
68
|
+
async function extractTar(archivePath, destination) {
|
|
69
|
+
try {
|
|
70
|
+
await runExtractor("tar", ["-xJf", archivePath, "-C", destination]);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
const directError = error instanceof Error ? error : new Error(String(error));
|
|
74
|
+
try {
|
|
75
|
+
await extractTarWithNode(archivePath, destination);
|
|
76
|
+
}
|
|
77
|
+
catch (fallbackError) {
|
|
78
|
+
throw new NodeRuntimeExtractionError(`Failed to extract tar archive: ${directError.message}`, fallbackError instanceof Error ? { cause: fallbackError } : undefined);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function runExtractor(command, args) {
|
|
83
|
+
await new Promise((resolve, reject) => {
|
|
84
|
+
const child = spawn(command, args, { stdio: ["ignore", "ignore", "pipe"] });
|
|
85
|
+
const stderr = [];
|
|
86
|
+
child.stderr.on("data", (chunk) => stderr.push(chunk));
|
|
87
|
+
child.on("error", reject);
|
|
88
|
+
child.on("close", (code) => {
|
|
89
|
+
if (code === 0) {
|
|
90
|
+
resolve();
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
reject(new Error(`${command} exited with code ${code ?? "unknown"}: ${Buffer.concat(stderr).toString("utf8").trim()}`));
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
async function findExtractedRoot(stagingDirectory) {
|
|
98
|
+
const entries = await readdir(stagingDirectory, { withFileTypes: true });
|
|
99
|
+
const directories = entries.filter((entry) => entry.isDirectory());
|
|
100
|
+
if (directories.length !== 1) {
|
|
101
|
+
throw new NodeRuntimeExtractionError(`Expected exactly one extracted Node.js root in staging directory, found ${directories.length}.`);
|
|
102
|
+
}
|
|
103
|
+
return join(stagingDirectory, directories[0].name);
|
|
104
|
+
}
|
|
105
|
+
async function extractTarWithNode(archivePath, destination) {
|
|
106
|
+
const tarPath = archivePath.endsWith(".gz")
|
|
107
|
+
? `${archivePath}.tar`
|
|
108
|
+
: `${archivePath}.decompressed.tar`;
|
|
109
|
+
try {
|
|
110
|
+
if (archivePath.endsWith(".gz")) {
|
|
111
|
+
await pipeline(createReadStream(archivePath), createGunzip(), createWriteStream(tarPath));
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
await writeFile(tarPath, gunzipSync(await readFile(archivePath)));
|
|
115
|
+
}
|
|
116
|
+
await extractTarBuffer(await readFile(tarPath), destination);
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
await rm(tarPath, { force: true }).catch(() => undefined);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async function extractTarBuffer(buffer, destination) {
|
|
123
|
+
let offset = 0;
|
|
124
|
+
while (offset + 512 <= buffer.length) {
|
|
125
|
+
const header = buffer.subarray(offset, offset + 512);
|
|
126
|
+
if (header.every((byte) => byte === 0)) {
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
const name = header.toString("utf8", 0, 100).replace(/\0.*$/, "");
|
|
130
|
+
const sizeText = header
|
|
131
|
+
.toString("utf8", 124, 136)
|
|
132
|
+
.replace(/\0.*$/, "")
|
|
133
|
+
.trim();
|
|
134
|
+
const typeFlag = header.toString("utf8", 156, 157);
|
|
135
|
+
const size = parseInt(sizeText || "0", 8);
|
|
136
|
+
const outputPath = safeJoin(destination, name);
|
|
137
|
+
if (typeFlag === "5") {
|
|
138
|
+
await mkdir(outputPath, { recursive: true });
|
|
139
|
+
}
|
|
140
|
+
else if (typeFlag === "0" || typeFlag === "") {
|
|
141
|
+
await mkdir(dirname(outputPath), { recursive: true });
|
|
142
|
+
await writeFile(outputPath, buffer.subarray(offset + 512, offset + 512 + size));
|
|
143
|
+
}
|
|
144
|
+
offset += 512 + Math.ceil(size / 512) * 512;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function safeJoin(root, entryName) {
|
|
148
|
+
const normalized = join(root, entryName);
|
|
149
|
+
const rel = relative(root, normalized);
|
|
150
|
+
if (rel.startsWith("..") || rel.includes(`..${sep}`)) {
|
|
151
|
+
throw new NodeRuntimeExtractionError(`Archive entry escapes extraction directory: ${basename(entryName)}`);
|
|
152
|
+
}
|
|
153
|
+
return normalized;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=node-extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-extract.js","sourceRoot":"","sources":["../../src/runtime/node-extract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type DownloadProgress } from "./node-download.js";
|
|
2
|
+
import { verifyNodeRuntime } from "./node-verify.js";
|
|
3
|
+
export interface InstallNodeRuntimeOptions {
|
|
4
|
+
targetDirectory: string;
|
|
5
|
+
versionSelector?: string;
|
|
6
|
+
fetchImpl?: typeof fetch;
|
|
7
|
+
downloadTimeoutMs?: number;
|
|
8
|
+
verifyTimeoutMs?: number;
|
|
9
|
+
onProgress?: (progress: DownloadProgress) => void;
|
|
10
|
+
}
|
|
11
|
+
export interface ResolveManagedNodeRuntimeOptions {
|
|
12
|
+
targetDirectory?: string;
|
|
13
|
+
versionSelector?: string;
|
|
14
|
+
fetchImpl?: typeof fetch;
|
|
15
|
+
downloadTimeoutMs?: number;
|
|
16
|
+
verifyTimeoutMs?: number;
|
|
17
|
+
verifyRuntime?: typeof verifyNodeRuntime;
|
|
18
|
+
installRuntime?: typeof installNodeRuntime;
|
|
19
|
+
onProgress?: (progress: DownloadProgress) => void;
|
|
20
|
+
}
|
|
21
|
+
export interface InstallNodeRuntimeResult {
|
|
22
|
+
version: string;
|
|
23
|
+
npmVersion: string;
|
|
24
|
+
targetDirectory: string;
|
|
25
|
+
nodePath: string;
|
|
26
|
+
npmPath: string;
|
|
27
|
+
archiveUrl: string;
|
|
28
|
+
}
|
|
29
|
+
export interface ResolveManagedNodeRuntimeResult {
|
|
30
|
+
targetDirectory: string;
|
|
31
|
+
nodePath: string;
|
|
32
|
+
npmPath: string;
|
|
33
|
+
nodeVersion: string;
|
|
34
|
+
npmVersion: string;
|
|
35
|
+
installed: boolean;
|
|
36
|
+
}
|
|
37
|
+
export declare function getDefaultManagedNodeRuntimeDirectory(): string;
|
|
38
|
+
export declare function resolveManagedNodeRuntime(options?: ResolveManagedNodeRuntimeOptions): Promise<ResolveManagedNodeRuntimeResult>;
|
|
39
|
+
export declare function installNodeRuntime(options: InstallNodeRuntimeOptions): Promise<InstallNodeRuntimeResult>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { assertTargetIsEmptyOrMissing, extractNodeArchive, moveExtractedRootToTarget } from "./node-extract.js";
|
|
5
|
+
import { downloadNodeArchive } from "./node-download.js";
|
|
6
|
+
import { fetchNodeReleaseMetadata, selectNodeArchive } from "./node-release.js";
|
|
7
|
+
import { mapNodePlatform } from "./node-platform.js";
|
|
8
|
+
import { getRuntimeExecutablePaths, verifyNodeRuntime } from "./node-verify.js";
|
|
9
|
+
export function getDefaultManagedNodeRuntimeDirectory() {
|
|
10
|
+
return join(homedir(), ".hagiscript", "node-runtime");
|
|
11
|
+
}
|
|
12
|
+
export async function resolveManagedNodeRuntime(options = {}) {
|
|
13
|
+
const targetDirectory = resolve(options.targetDirectory ?? getDefaultManagedNodeRuntimeDirectory());
|
|
14
|
+
const verifyRuntime = options.verifyRuntime ?? verifyNodeRuntime;
|
|
15
|
+
const initialVerification = await verifyRuntime(targetDirectory, {
|
|
16
|
+
timeoutMs: options.verifyTimeoutMs
|
|
17
|
+
});
|
|
18
|
+
if (initialVerification.valid) {
|
|
19
|
+
return toResolvedRuntime(initialVerification, false);
|
|
20
|
+
}
|
|
21
|
+
const installRuntime = options.installRuntime ?? installNodeRuntime;
|
|
22
|
+
await installRuntime({
|
|
23
|
+
targetDirectory,
|
|
24
|
+
versionSelector: options.versionSelector,
|
|
25
|
+
fetchImpl: options.fetchImpl,
|
|
26
|
+
downloadTimeoutMs: options.downloadTimeoutMs,
|
|
27
|
+
verifyTimeoutMs: options.verifyTimeoutMs,
|
|
28
|
+
onProgress: options.onProgress
|
|
29
|
+
});
|
|
30
|
+
const finalVerification = await verifyRuntime(targetDirectory, {
|
|
31
|
+
timeoutMs: options.verifyTimeoutMs
|
|
32
|
+
});
|
|
33
|
+
assertValidVerification(finalVerification);
|
|
34
|
+
return toResolvedRuntime(finalVerification, true);
|
|
35
|
+
}
|
|
36
|
+
export async function installNodeRuntime(options) {
|
|
37
|
+
const targetDirectory = resolve(options.targetDirectory);
|
|
38
|
+
await assertTargetIsEmptyOrMissing(targetDirectory);
|
|
39
|
+
const releases = await fetchNodeReleaseMetadata(options.fetchImpl);
|
|
40
|
+
const archive = selectNodeArchive(releases, options.versionSelector, mapNodePlatform());
|
|
41
|
+
const stagingRoot = await mkdtemp(join(dirname(targetDirectory), ".hagiscript-node-"));
|
|
42
|
+
const archivePath = join(stagingRoot, archive.fileName);
|
|
43
|
+
try {
|
|
44
|
+
await downloadNodeArchive(archive.url, archivePath, {
|
|
45
|
+
fetchImpl: options.fetchImpl,
|
|
46
|
+
timeoutMs: options.downloadTimeoutMs,
|
|
47
|
+
onProgress: options.onProgress
|
|
48
|
+
});
|
|
49
|
+
const extractedRoot = await extractNodeArchive(archivePath, join(stagingRoot, "extract"), archive.platform.archiveExtension);
|
|
50
|
+
const verification = await verifyNodeRuntime(extractedRoot, {
|
|
51
|
+
timeoutMs: options.verifyTimeoutMs
|
|
52
|
+
});
|
|
53
|
+
assertValidVerification(verification);
|
|
54
|
+
await moveExtractedRootToTarget(extractedRoot, targetDirectory);
|
|
55
|
+
const finalPaths = getRuntimeExecutablePaths(targetDirectory);
|
|
56
|
+
return {
|
|
57
|
+
version: verification.nodeVersion ?? archive.version,
|
|
58
|
+
npmVersion: verification.npmVersion ?? "unknown",
|
|
59
|
+
targetDirectory,
|
|
60
|
+
nodePath: finalPaths.nodePath,
|
|
61
|
+
npmPath: finalPaths.npmPath,
|
|
62
|
+
archiveUrl: archive.url
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
await rm(stagingRoot, { recursive: true, force: true }).catch(() => undefined);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function assertValidVerification(verification) {
|
|
70
|
+
if (!verification.valid) {
|
|
71
|
+
throw new Error(`Installed Node.js runtime failed verification: ${verification.failureReason ?? "unknown failure"}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function toResolvedRuntime(verification, installed) {
|
|
75
|
+
assertValidVerification(verification);
|
|
76
|
+
return {
|
|
77
|
+
targetDirectory: verification.targetDirectory,
|
|
78
|
+
nodePath: verification.nodePath,
|
|
79
|
+
npmPath: verification.npmPath,
|
|
80
|
+
nodeVersion: verification.nodeVersion,
|
|
81
|
+
npmVersion: verification.npmVersion,
|
|
82
|
+
installed
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=node-installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-installer.js","sourceRoot":"","sources":["../../src/runtime/node-installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type NodeOperatingSystem = "win" | "linux" | "darwin";
|
|
2
|
+
export type NodeArchitecture = "x64" | "arm64";
|
|
3
|
+
export interface NodePlatformTarget {
|
|
4
|
+
os: NodeOperatingSystem;
|
|
5
|
+
arch: NodeArchitecture;
|
|
6
|
+
nodeFileKey: `${NodeOperatingSystem}-${NodeArchitecture}`;
|
|
7
|
+
archiveExtension: "zip" | "tar.xz";
|
|
8
|
+
executableName: "node.exe" | "node";
|
|
9
|
+
npmExecutableName: "npm.cmd" | "npm";
|
|
10
|
+
}
|
|
11
|
+
export declare class UnsupportedNodePlatformError extends Error {
|
|
12
|
+
constructor(message: string);
|
|
13
|
+
}
|
|
14
|
+
export declare function mapNodePlatform(platform?: NodeJS.Platform, arch?: NodeJS.Architecture): NodePlatformTarget;
|