@veryfront/ext-content-mdx 0.1.1186 → 0.1.1189
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/esm/_dnt.polyfills.d.ts +6 -6
- package/esm/_dnt.polyfills.d.ts.map +1 -1
- package/esm/deno.d.ts +18 -0
- package/esm/deno.js +30 -9
- package/esm/src/config/defaults.d.ts +31 -24
- package/esm/src/config/defaults.d.ts.map +1 -1
- package/esm/src/config/defaults.js +25 -18
- package/esm/src/errors/diagnostic-policy.d.ts +35 -0
- package/esm/src/errors/diagnostic-policy.d.ts.map +1 -0
- package/esm/src/errors/diagnostic-policy.js +100 -0
- package/esm/src/errors/error-registry/boundary.d.ts +2 -0
- package/esm/src/errors/error-registry/boundary.d.ts.map +1 -1
- package/esm/src/errors/error-registry/boundary.js +8 -0
- package/esm/src/errors/error-registry/config.d.ts.map +1 -1
- package/esm/src/errors/error-registry/config.js +3 -3
- package/esm/src/errors/error-registry/deploy.js +1 -1
- package/esm/src/errors/error-registry/server.d.ts +2 -0
- package/esm/src/errors/error-registry/server.d.ts.map +1 -1
- package/esm/src/errors/error-registry/server.js +8 -0
- package/esm/src/errors/error-registry-helpers.d.ts +11 -2
- package/esm/src/errors/error-registry-helpers.d.ts.map +1 -1
- package/esm/src/errors/error-registry-helpers.js +70 -1
- package/esm/src/errors/error-registry.d.ts +85 -73
- package/esm/src/errors/error-registry.d.ts.map +1 -1
- package/esm/src/errors/error-registry.js +2 -14
- package/esm/src/errors/types.d.ts +44 -5
- package/esm/src/errors/types.d.ts.map +1 -1
- package/esm/src/errors/types.js +148 -24
- package/esm/src/errors/veryfront-error.d.ts +25 -2
- package/esm/src/errors/veryfront-error.d.ts.map +1 -1
- package/esm/src/errors/veryfront-error.js +638 -28
- package/esm/src/observability/limits.d.ts +20 -0
- package/esm/src/observability/limits.d.ts.map +1 -0
- package/esm/src/observability/limits.js +19 -0
- package/esm/src/observability/telemetry-error.d.ts +22 -0
- package/esm/src/observability/telemetry-error.d.ts.map +1 -0
- package/esm/src/observability/telemetry-error.js +377 -0
- package/esm/src/observability/tracing/api-shim.d.ts +39 -0
- package/esm/src/observability/tracing/api-shim.d.ts.map +1 -1
- package/esm/src/observability/tracing/api-shim.js +196 -69
- package/esm/src/observability/tracing/context-callback.d.ts +14 -0
- package/esm/src/observability/tracing/context-callback.d.ts.map +1 -0
- package/esm/src/observability/tracing/context-callback.js +111 -0
- package/esm/src/observability/tracing/otlp-setup.d.ts.map +1 -1
- package/esm/src/observability/tracing/otlp-setup.js +190 -46
- package/esm/src/platform/adapters/base.d.ts +51 -7
- package/esm/src/platform/adapters/base.d.ts.map +1 -1
- package/esm/src/platform/adapters/base.js +4 -2
- package/esm/src/platform/adapters/bounded-file-read.d.ts +9 -0
- package/esm/src/platform/adapters/bounded-file-read.d.ts.map +1 -1
- package/esm/src/platform/adapters/bounded-file-read.js +11 -5
- package/esm/src/platform/adapters/file-snapshot-error.d.ts +2 -0
- package/esm/src/platform/adapters/file-snapshot-error.d.ts.map +1 -1
- package/esm/src/platform/adapters/file-snapshot-error.js +2 -0
- package/esm/src/platform/adapters/file-system-capabilities.d.ts +74 -0
- package/esm/src/platform/adapters/file-system-capabilities.d.ts.map +1 -0
- package/esm/src/platform/adapters/file-system-capabilities.js +508 -0
- package/esm/src/platform/adapters/native-file-system-provenance.d.ts +6 -0
- package/esm/src/platform/adapters/native-file-system-provenance.d.ts.map +1 -0
- package/esm/src/platform/adapters/native-file-system-provenance.js +15 -0
- package/esm/src/platform/adapters/runtime/deno/filesystem-adapter.d.ts +45 -0
- package/esm/src/platform/adapters/runtime/deno/filesystem-adapter.d.ts.map +1 -0
- package/esm/src/platform/adapters/runtime/deno/filesystem-adapter.js +291 -0
- package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.d.ts +71 -0
- package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.d.ts.map +1 -0
- package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.js +471 -0
- package/esm/src/platform/adapters/runtime/shared/shared-watcher.d.ts +16 -0
- package/esm/src/platform/adapters/runtime/shared/shared-watcher.d.ts.map +1 -0
- package/esm/src/platform/adapters/runtime/shared/shared-watcher.js +140 -0
- package/esm/src/platform/adapters/runtime/shared/temp-dir.d.ts +2 -0
- package/esm/src/platform/adapters/runtime/shared/temp-dir.d.ts.map +1 -0
- package/esm/src/platform/adapters/runtime/shared/temp-dir.js +10 -0
- package/esm/src/platform/adapters/runtime/shared/watcher-queue.d.ts +5 -0
- package/esm/src/platform/adapters/runtime/shared/watcher-queue.d.ts.map +1 -0
- package/esm/src/platform/adapters/runtime/shared/watcher-queue.js +75 -0
- package/esm/src/platform/compat/abort-signal.d.ts +20 -0
- package/esm/src/platform/compat/abort-signal.d.ts.map +1 -0
- package/esm/src/platform/compat/abort-signal.js +64 -0
- package/esm/src/platform/compat/constants.d.ts +2 -2
- package/esm/src/platform/compat/constants.d.ts.map +1 -1
- package/esm/src/platform/compat/constants.js +2 -2
- package/esm/src/platform/compat/error-introspection.d.ts +37 -0
- package/esm/src/platform/compat/error-introspection.d.ts.map +1 -0
- package/esm/src/platform/compat/error-introspection.js +258 -0
- package/esm/src/platform/compat/fs.d.ts +29 -8
- package/esm/src/platform/compat/fs.d.ts.map +1 -1
- package/esm/src/platform/compat/fs.js +123 -57
- package/esm/src/platform/compat/native-brand-checks.d.ts +14 -0
- package/esm/src/platform/compat/native-brand-checks.d.ts.map +1 -0
- package/esm/src/platform/compat/native-brand-checks.js +68 -0
- package/esm/src/platform/compat/not-found-error.d.ts +8 -3
- package/esm/src/platform/compat/not-found-error.d.ts.map +1 -1
- package/esm/src/platform/compat/not-found-error.js +164 -31
- package/esm/src/platform/compat/path/security.d.ts.map +1 -1
- package/esm/src/platform/compat/path/security.js +3 -5
- package/esm/src/platform/compat/process/command.d.ts +24 -1
- package/esm/src/platform/compat/process/command.d.ts.map +1 -1
- package/esm/src/platform/compat/process/command.js +393 -78
- package/esm/src/platform/compat/process/env.d.ts +11 -0
- package/esm/src/platform/compat/process/env.d.ts.map +1 -1
- package/esm/src/platform/compat/process/env.js +28 -38
- package/esm/src/platform/compat/process/global-error.d.ts +19 -0
- package/esm/src/platform/compat/process/global-error.d.ts.map +1 -0
- package/esm/src/platform/compat/process/global-error.js +57 -0
- package/esm/src/platform/compat/process/lifecycle.d.ts +10 -3
- package/esm/src/platform/compat/process/lifecycle.d.ts.map +1 -1
- package/esm/src/platform/compat/process/lifecycle.js +74 -23
- package/esm/src/platform/compat/process/project-env-contract.d.ts +19 -0
- package/esm/src/platform/compat/process/project-env-contract.d.ts.map +1 -0
- package/esm/src/platform/compat/process/project-env-contract.js +19 -0
- package/esm/src/platform/compat/runtime.d.ts +14 -5
- package/esm/src/platform/compat/runtime.d.ts.map +1 -1
- package/esm/src/platform/compat/runtime.js +34 -9
- package/esm/src/platform/compat/std/front-matter-yaml.d.ts +12 -0
- package/esm/src/platform/compat/std/front-matter-yaml.d.ts.map +1 -1
- package/esm/src/platform/compat/std/front-matter-yaml.js +35 -3
- package/esm/src/platform/compat/temp-directory-prefix.d.ts +8 -0
- package/esm/src/platform/compat/temp-directory-prefix.d.ts.map +1 -0
- package/esm/src/platform/compat/temp-directory-prefix.js +15 -0
- package/esm/src/utils/abort.d.ts +10 -0
- package/esm/src/utils/abort.d.ts.map +1 -0
- package/esm/src/utils/abort.js +35 -0
- package/esm/src/utils/constants/build.d.ts +3 -0
- package/esm/src/utils/constants/build.d.ts.map +1 -1
- package/esm/src/utils/constants/build.js +5 -1
- package/esm/src/utils/constants/cache.d.ts +21 -0
- package/esm/src/utils/constants/cache.d.ts.map +1 -1
- package/esm/src/utils/constants/cache.js +101 -39
- package/esm/src/utils/constants/css.d.ts +20 -0
- package/esm/src/utils/constants/css.d.ts.map +1 -0
- package/esm/src/utils/constants/css.js +19 -0
- package/esm/src/utils/constants/limits.d.ts +4 -0
- package/esm/src/utils/constants/limits.d.ts.map +1 -1
- package/esm/src/utils/constants/limits.js +4 -0
- package/esm/src/utils/constants/project-identity.d.ts +5 -0
- package/esm/src/utils/constants/project-identity.d.ts.map +1 -0
- package/esm/src/utils/constants/project-identity.js +4 -0
- package/esm/src/utils/constants/retry.d.ts +18 -0
- package/esm/src/utils/constants/retry.d.ts.map +1 -1
- package/esm/src/utils/constants/retry.js +18 -0
- package/esm/src/utils/constants/security.d.ts +4 -0
- package/esm/src/utils/constants/security.d.ts.map +1 -1
- package/esm/src/utils/constants/security.js +4 -0
- package/esm/src/utils/index.d.ts +3 -1
- package/esm/src/utils/index.d.ts.map +1 -1
- package/esm/src/utils/index.js +3 -1
- package/esm/src/utils/logger/core.d.ts +5 -0
- package/esm/src/utils/logger/core.d.ts.map +1 -1
- package/esm/src/utils/logger/core.js +67 -2
- package/esm/src/utils/logger/redact.d.ts +36 -13
- package/esm/src/utils/logger/redact.d.ts.map +1 -1
- package/esm/src/utils/logger/redact.js +573 -83
- package/esm/src/utils/parallel.d.ts.map +1 -1
- package/esm/src/utils/parallel.js +11 -1
- package/esm/src/utils/project-identity.d.ts +11 -0
- package/esm/src/utils/project-identity.d.ts.map +1 -0
- package/esm/src/utils/project-identity.js +69 -0
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +3 -3
- package/esm/src/platform/adapters/runtime/shared/native-file-capabilities.d.ts +0 -33
- package/esm/src/platform/adapters/runtime/shared/native-file-capabilities.d.ts.map +0 -1
- package/esm/src/platform/adapters/runtime/shared/native-file-capabilities.js +0 -205
|
@@ -3,6 +3,8 @@ export interface CommandResult {
|
|
|
3
3
|
code: number;
|
|
4
4
|
stdout?: string;
|
|
5
5
|
stderr?: string;
|
|
6
|
+
/** True when captured output exceeded the configured byte limit. */
|
|
7
|
+
outputTruncated?: boolean;
|
|
6
8
|
}
|
|
7
9
|
export interface CommandOptions {
|
|
8
10
|
args?: string[];
|
|
@@ -16,9 +18,30 @@ export interface CommandOptions {
|
|
|
16
18
|
inherit?: boolean;
|
|
17
19
|
/** Use shell to run the command (needed for .cmd files on Windows) */
|
|
18
20
|
shell?: boolean;
|
|
19
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Kill the command after this duration in milliseconds. Positive values are
|
|
23
|
+
* floored to whole milliseconds and clamped to the portable timer maximum;
|
|
24
|
+
* `undefined`, non-positive values, and NaN disable the timeout.
|
|
25
|
+
*/
|
|
20
26
|
timeoutMs?: number;
|
|
27
|
+
/** Terminate the command when the caller cancels. */
|
|
28
|
+
signal?: AbortSignal;
|
|
29
|
+
/**
|
|
30
|
+
* Best-effort process-tree cleanup after the managed command settles.
|
|
31
|
+
* Disabled by default so generic callers retain normal daemon/background
|
|
32
|
+
* process behavior. Sandboxed or otherwise lifecycle-owning callers can
|
|
33
|
+
* enable it to prevent ordinary descendants from outliving the command.
|
|
34
|
+
*/
|
|
35
|
+
terminateProcessTreeOnExit?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Maximum combined stdout and stderr bytes retained when `capture` is true.
|
|
38
|
+
*
|
|
39
|
+
* @default 16777216
|
|
40
|
+
*/
|
|
41
|
+
maxOutputBytes?: number;
|
|
21
42
|
}
|
|
43
|
+
/** @internal Exported so Windows tree-termination arguments can be tested on every host. */
|
|
44
|
+
export declare function buildWindowsTaskkillArgs(pid: number, force: boolean): string[];
|
|
22
45
|
/**
|
|
23
46
|
* Run a command and return the result.
|
|
24
47
|
* Works across Deno, Node.js, and Bun.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/compat/process/command.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/compat/process/command.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gDAAgD;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sEAAsE;IACtE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAuED,4FAA4F;AAC5F,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAK9E;AAoTD;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAmVxB"}
|
|
@@ -1,78 +1,299 @@
|
|
|
1
1
|
import * as dntShim from "../../../../_dnt.shims.js";
|
|
2
2
|
import { dynamicImport } from "../dynamic-import.js";
|
|
3
|
+
import { addAbortSignalListenerOnce, isAbortSignalAborted, isAbortSignalWithoutHooks, removeAbortSignalListener, } from "../abort-signal.js";
|
|
3
4
|
import { getDenoRuntime, isBun as IS_BUN, isDeno as IS_DENO } from "../runtime.js";
|
|
4
5
|
import { isWindowsPlatform, runtimeProcess } from "./runtime-process.js";
|
|
5
6
|
const COMMAND_TIMEOUT_EXIT_CODE = 124;
|
|
7
|
+
const COMMAND_OUTPUT_LIMIT_EXIT_CODE = 125;
|
|
8
|
+
const COMMAND_ABORT_EXIT_CODE = 130;
|
|
6
9
|
const FORCE_KILL_GRACE_MS = 250;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
10
|
+
const DEFAULT_MAX_OUTPUT_BYTES = 16 * 1024 * 1024;
|
|
11
|
+
const MAX_COMMAND_TIMEOUT_MS = 2_147_483_647;
|
|
12
|
+
const apply = Reflect.apply;
|
|
13
|
+
const uint8ArraySlice = Uint8Array.prototype.slice;
|
|
14
|
+
function createTerminationResult(reason, detail, stdout, stderr, outputTruncated = reason === "output-limit") {
|
|
15
|
+
const message = reason === "timeout"
|
|
16
|
+
? `Command timed out after ${detail}ms`
|
|
17
|
+
: reason === "output-limit"
|
|
18
|
+
? `Command output exceeded ${detail} bytes`
|
|
19
|
+
: "Command aborted";
|
|
17
20
|
return {
|
|
18
21
|
success: false,
|
|
19
|
-
code:
|
|
22
|
+
code: reason === "timeout"
|
|
23
|
+
? COMMAND_TIMEOUT_EXIT_CODE
|
|
24
|
+
: reason === "output-limit"
|
|
25
|
+
? COMMAND_OUTPUT_LIMIT_EXIT_CODE
|
|
26
|
+
: COMMAND_ABORT_EXIT_CODE,
|
|
20
27
|
stdout,
|
|
21
|
-
stderr: `${stderr ?? ""}\
|
|
28
|
+
stderr: `${stderr ?? ""}\n${message}`.trim(),
|
|
29
|
+
outputTruncated: outputTruncated || undefined,
|
|
22
30
|
};
|
|
23
31
|
}
|
|
24
|
-
function
|
|
25
|
-
|
|
32
|
+
function validateAbortSignal(signal) {
|
|
33
|
+
if (signal === undefined)
|
|
34
|
+
return;
|
|
35
|
+
if (!isAbortSignalWithoutHooks(signal)) {
|
|
36
|
+
throw new TypeError("signal must be an AbortSignal");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function resolveCommandTimeoutMs(timeoutMs) {
|
|
40
|
+
if (typeof timeoutMs !== "number" || !(timeoutMs > 0))
|
|
41
|
+
return undefined;
|
|
42
|
+
return Math.min(Math.floor(timeoutMs), MAX_COMMAND_TIMEOUT_MS);
|
|
43
|
+
}
|
|
44
|
+
/** @internal Exported so Windows tree-termination arguments can be tested on every host. */
|
|
45
|
+
export function buildWindowsTaskkillArgs(pid, force) {
|
|
46
|
+
if (!Number.isSafeInteger(pid) || pid <= 0) {
|
|
47
|
+
throw new RangeError("Windows taskkill pid must be a positive safe integer");
|
|
48
|
+
}
|
|
49
|
+
return ["/PID", String(pid), "/T", ...(force ? ["/F"] : [])];
|
|
50
|
+
}
|
|
51
|
+
function tryDirectSignal(signalDirect, signal) {
|
|
52
|
+
try {
|
|
53
|
+
signalDirect(signal);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// The target may have exited before taskkill failure became observable.
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function tryForceSettledProcessTree(signalTree) {
|
|
60
|
+
try {
|
|
61
|
+
signalTree("SIGKILL");
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// A settled command with no remaining descendants has no process group or
|
|
65
|
+
// live direct handle. Cleanup is intentionally idempotent in that case.
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function signalWindowsTreeWithDeno(deno, pid, force, signalDirect) {
|
|
69
|
+
const signal = force ? "SIGKILL" : "SIGTERM";
|
|
70
|
+
if (!Number.isSafeInteger(pid) || (pid ?? 0) <= 0) {
|
|
71
|
+
tryDirectSignal(signalDirect, signal);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const taskkill = new deno.Command("taskkill", {
|
|
76
|
+
args: buildWindowsTaskkillArgs(pid, force),
|
|
77
|
+
stdin: "null",
|
|
78
|
+
stdout: "null",
|
|
79
|
+
stderr: "null",
|
|
80
|
+
}).spawn();
|
|
81
|
+
void taskkill.status.then((status) => {
|
|
82
|
+
if (!status.success)
|
|
83
|
+
tryDirectSignal(signalDirect, signal);
|
|
84
|
+
}).catch(() => tryDirectSignal(signalDirect, signal));
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
tryDirectSignal(signalDirect, signal);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function signalWindowsTreeWithBun(bun, pid, force, signalDirect) {
|
|
91
|
+
const signal = force ? "SIGKILL" : "SIGTERM";
|
|
92
|
+
if (!Number.isSafeInteger(pid) || (pid ?? 0) <= 0) {
|
|
93
|
+
tryDirectSignal(signalDirect, signal);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const taskkill = bun.spawn({
|
|
98
|
+
cmd: ["taskkill", ...buildWindowsTaskkillArgs(pid, force)],
|
|
99
|
+
stdout: "ignore",
|
|
100
|
+
stderr: "ignore",
|
|
101
|
+
});
|
|
102
|
+
taskkill.unref?.();
|
|
103
|
+
void taskkill.exited.then((code) => {
|
|
104
|
+
if (code !== 0)
|
|
105
|
+
tryDirectSignal(signalDirect, signal);
|
|
106
|
+
}).catch(() => tryDirectSignal(signalDirect, signal));
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
tryDirectSignal(signalDirect, signal);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function signalWindowsTreeWithNode(spawn, pid, force, signalDirect) {
|
|
113
|
+
const signal = force ? "SIGKILL" : "SIGTERM";
|
|
114
|
+
if (!Number.isSafeInteger(pid) || (pid ?? 0) <= 0) {
|
|
115
|
+
tryDirectSignal(signalDirect, signal);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
const taskkill = spawn("taskkill", buildWindowsTaskkillArgs(pid, force), {
|
|
120
|
+
stdio: "ignore",
|
|
121
|
+
windowsHide: true,
|
|
122
|
+
});
|
|
123
|
+
taskkill.once("error", () => tryDirectSignal(signalDirect, signal));
|
|
124
|
+
taskkill.once("close", (code) => {
|
|
125
|
+
if (code !== 0)
|
|
126
|
+
tryDirectSignal(signalDirect, signal);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
tryDirectSignal(signalDirect, signal);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function signalProcessTree(pid, signal, detachedProcessGroup, signalGroup, signalDirect) {
|
|
134
|
+
if (detachedProcessGroup && Number.isSafeInteger(pid) && (pid ?? 0) > 0) {
|
|
135
|
+
try {
|
|
136
|
+
signalGroup(-pid, signal);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
catch (_) {
|
|
140
|
+
// The child may have exited before its process group became observable.
|
|
141
|
+
// Fall through to the direct handle so cancellation remains best effort.
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
signalDirect(signal);
|
|
145
|
+
}
|
|
146
|
+
function createProcessGuard(timeoutMs, signal, terminate, forceTerminate, releaseAfterForce) {
|
|
147
|
+
let terminationReason = null;
|
|
26
148
|
let timeoutId;
|
|
27
149
|
let forceKillId;
|
|
150
|
+
let forceTerminationCompleted = false;
|
|
151
|
+
const abortListener = () => stop("abort");
|
|
28
152
|
if (timeoutMs && timeoutMs > 0) {
|
|
29
153
|
timeoutId = dntShim.setTimeout(() => {
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
terminate();
|
|
33
|
-
}
|
|
34
|
-
catch (_) {
|
|
35
|
-
/* expected: best-effort terminate may fail if process already exited */
|
|
36
|
-
}
|
|
37
|
-
forceKillId = dntShim.setTimeout(() => {
|
|
38
|
-
try {
|
|
39
|
-
forceTerminate();
|
|
40
|
-
}
|
|
41
|
-
catch (_) {
|
|
42
|
-
/* expected: best-effort force terminate may fail if process already exited */
|
|
43
|
-
}
|
|
44
|
-
}, FORCE_KILL_GRACE_MS);
|
|
154
|
+
stop("timeout");
|
|
45
155
|
}, timeoutMs);
|
|
46
156
|
}
|
|
157
|
+
if (signal) {
|
|
158
|
+
addAbortSignalListenerOnce(signal, abortListener);
|
|
159
|
+
if (isAbortSignalAborted(signal))
|
|
160
|
+
stop("abort");
|
|
161
|
+
}
|
|
47
162
|
return {
|
|
48
|
-
|
|
163
|
+
stop,
|
|
164
|
+
reason: () => terminationReason,
|
|
49
165
|
clear: () => {
|
|
50
166
|
if (timeoutId)
|
|
51
167
|
clearTimeout(timeoutId);
|
|
52
|
-
if (
|
|
53
|
-
|
|
168
|
+
if (signal)
|
|
169
|
+
removeAbortSignalListener(signal, abortListener);
|
|
170
|
+
if (terminationReason === null) {
|
|
171
|
+
if (forceKillId)
|
|
172
|
+
clearTimeout(forceKillId);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
// The directly managed process may settle after SIGTERM while a child in
|
|
176
|
+
// its process group remains alive. Do not cancel escalation on that
|
|
177
|
+
// abnormal settlement; force it immediately before releasing lifecycle
|
|
178
|
+
// ownership.
|
|
179
|
+
forceTerminateOnce();
|
|
54
180
|
},
|
|
55
181
|
};
|
|
182
|
+
function stop(reason) {
|
|
183
|
+
if (terminationReason !== null)
|
|
184
|
+
return;
|
|
185
|
+
terminationReason = reason;
|
|
186
|
+
try {
|
|
187
|
+
terminate();
|
|
188
|
+
}
|
|
189
|
+
catch (_) {
|
|
190
|
+
/* expected: best-effort terminate may fail if process already exited */
|
|
191
|
+
}
|
|
192
|
+
forceKillId = dntShim.setTimeout(forceTerminateOnce, FORCE_KILL_GRACE_MS);
|
|
193
|
+
}
|
|
194
|
+
function forceTerminateOnce() {
|
|
195
|
+
if (forceTerminationCompleted)
|
|
196
|
+
return;
|
|
197
|
+
forceTerminationCompleted = true;
|
|
198
|
+
if (forceKillId) {
|
|
199
|
+
clearTimeout(forceKillId);
|
|
200
|
+
forceKillId = undefined;
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
forceTerminate();
|
|
204
|
+
}
|
|
205
|
+
catch (_) {
|
|
206
|
+
/* expected: best-effort force terminate may fail if process already exited */
|
|
207
|
+
}
|
|
208
|
+
finally {
|
|
209
|
+
releaseAfterForce();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function createCaptureBudget(maxOutputBytes, onExceeded) {
|
|
214
|
+
return {
|
|
215
|
+
remaining: maxOutputBytes,
|
|
216
|
+
exceeded: false,
|
|
217
|
+
onExceeded,
|
|
218
|
+
};
|
|
56
219
|
}
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
220
|
+
function captureChunk(chunks, chunk, budget) {
|
|
221
|
+
const available = budget.remaining;
|
|
222
|
+
if (available > 0) {
|
|
223
|
+
// Invoke the typed-array intrinsic directly: Buffer#slice() returns a view
|
|
224
|
+
// and can retain a much larger pooled backing allocation.
|
|
225
|
+
const retained = apply(uint8ArraySlice, chunk, [
|
|
226
|
+
0,
|
|
227
|
+
Math.min(chunk.byteLength, available),
|
|
228
|
+
]);
|
|
229
|
+
chunks.push(retained);
|
|
230
|
+
budget.remaining -= retained.byteLength;
|
|
231
|
+
}
|
|
232
|
+
if (chunk.byteLength > available && !budget.exceeded) {
|
|
233
|
+
budget.exceeded = true;
|
|
234
|
+
budget.onExceeded();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function decodeChunks(chunks) {
|
|
238
|
+
const total = chunks.reduce((acc, chunk) => acc + chunk.byteLength, 0);
|
|
68
239
|
const merged = new Uint8Array(total);
|
|
69
240
|
let offset = 0;
|
|
70
241
|
for (const chunk of chunks) {
|
|
71
242
|
merged.set(chunk, offset);
|
|
72
|
-
offset += chunk.
|
|
243
|
+
offset += chunk.byteLength;
|
|
73
244
|
}
|
|
74
245
|
return new TextDecoder().decode(merged);
|
|
75
246
|
}
|
|
247
|
+
function captureStreamToString(stream, budget) {
|
|
248
|
+
const reader = stream.getReader();
|
|
249
|
+
const chunks = [];
|
|
250
|
+
let cancelled = false;
|
|
251
|
+
return {
|
|
252
|
+
result: (async () => {
|
|
253
|
+
try {
|
|
254
|
+
while (true) {
|
|
255
|
+
const { done, value } = await reader.read();
|
|
256
|
+
if (done)
|
|
257
|
+
break;
|
|
258
|
+
if (value)
|
|
259
|
+
captureChunk(chunks, value, budget);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
if (!cancelled)
|
|
264
|
+
throw error;
|
|
265
|
+
}
|
|
266
|
+
finally {
|
|
267
|
+
reader.releaseLock();
|
|
268
|
+
}
|
|
269
|
+
return decodeChunks(chunks);
|
|
270
|
+
})(),
|
|
271
|
+
cancel: (reason) => {
|
|
272
|
+
if (cancelled)
|
|
273
|
+
return;
|
|
274
|
+
cancelled = true;
|
|
275
|
+
try {
|
|
276
|
+
const cancellation = reader.cancel(reason);
|
|
277
|
+
void cancellation.catch(() => { });
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
// The stream may already have closed between termination and release.
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
function resolveShellCommand(cmd, args) {
|
|
286
|
+
if (isWindowsPlatform()) {
|
|
287
|
+
return { cmd: "cmd.exe", args: ["/d", "/s", "/c", cmd, ...args] };
|
|
288
|
+
}
|
|
289
|
+
if (args.length === 0) {
|
|
290
|
+
return { cmd: "sh", args: ["-c", cmd] };
|
|
291
|
+
}
|
|
292
|
+
return {
|
|
293
|
+
cmd: "sh",
|
|
294
|
+
args: ["-c", 'exec "$@"', "sh", cmd, ...args],
|
|
295
|
+
};
|
|
296
|
+
}
|
|
76
297
|
/**
|
|
77
298
|
* Run a command and return the result.
|
|
78
299
|
* Works across Deno, Node.js, and Bun.
|
|
@@ -84,32 +305,67 @@ async function readStreamToString(stream) {
|
|
|
84
305
|
* @param options.shell - Use shell to run command (needed for .cmd on Windows)
|
|
85
306
|
*/
|
|
86
307
|
export async function runCommand(cmd, options = {}) {
|
|
87
|
-
const { args = [], cwd: cmdCwd, env: cmdEnv, clearEnv = false, capture = false, inherit = false, shell = false, timeoutMs, } = options;
|
|
88
|
-
|
|
308
|
+
const { args = [], cwd: cmdCwd, env: cmdEnv, clearEnv = false, capture = false, inherit = false, shell = false, timeoutMs, signal, terminateProcessTreeOnExit = false, maxOutputBytes = DEFAULT_MAX_OUTPUT_BYTES, } = options;
|
|
309
|
+
validateAbortSignal(signal);
|
|
310
|
+
if (typeof terminateProcessTreeOnExit !== "boolean") {
|
|
311
|
+
throw new TypeError("terminateProcessTreeOnExit must be a boolean");
|
|
312
|
+
}
|
|
313
|
+
const effectiveTimeoutMs = resolveCommandTimeoutMs(timeoutMs);
|
|
314
|
+
if (!Number.isSafeInteger(maxOutputBytes) || maxOutputBytes <= 0) {
|
|
315
|
+
throw new RangeError("maxOutputBytes must be a positive safe integer");
|
|
316
|
+
}
|
|
317
|
+
if (signal && isAbortSignalAborted(signal)) {
|
|
318
|
+
return createTerminationResult("abort", 0);
|
|
319
|
+
}
|
|
89
320
|
// Determine stdio mode: inherit > capture > null
|
|
90
|
-
const
|
|
321
|
+
const shouldCapture = capture && !inherit;
|
|
322
|
+
const stdioMode = inherit ? "inherit" : shouldCapture ? "piped" : "null";
|
|
323
|
+
const detachedProcessGroup = !isWindowsPlatform() &&
|
|
324
|
+
(effectiveTimeoutMs !== undefined ||
|
|
325
|
+
signal !== undefined ||
|
|
326
|
+
shouldCapture ||
|
|
327
|
+
terminateProcessTreeOnExit);
|
|
91
328
|
const deno = IS_DENO ? getDenoRuntime() : undefined;
|
|
92
329
|
if (deno) {
|
|
93
|
-
const denoCommand = shell ?
|
|
330
|
+
const denoCommand = shell ? resolveShellCommand(cmd, args) : { cmd, args };
|
|
94
331
|
const command = new deno.Command(denoCommand.cmd, {
|
|
95
|
-
args: denoCommand.args,
|
|
332
|
+
args: [...denoCommand.args],
|
|
96
333
|
cwd: cmdCwd,
|
|
97
334
|
env: cmdEnv,
|
|
98
335
|
clearEnv,
|
|
99
336
|
stdin: inherit ? "inherit" : "null",
|
|
100
337
|
stdout: stdioMode,
|
|
101
338
|
stderr: stdioMode,
|
|
339
|
+
detached: detachedProcessGroup,
|
|
102
340
|
});
|
|
103
341
|
const child = command.spawn();
|
|
104
|
-
const
|
|
342
|
+
const windowsPlatform = isWindowsPlatform();
|
|
343
|
+
const directSignal = (terminationSignal) => child.kill(terminationSignal);
|
|
344
|
+
const signalChild = (terminationSignal) => windowsPlatform
|
|
345
|
+
? signalWindowsTreeWithDeno(deno, child.pid, terminationSignal === "SIGKILL", directSignal)
|
|
346
|
+
: signalProcessTree(child.pid, terminationSignal, detachedProcessGroup, (processGroupId, groupSignal) => deno.kill(processGroupId, groupSignal), directSignal);
|
|
347
|
+
const captures = {};
|
|
348
|
+
const guard = createProcessGuard(effectiveTimeoutMs, signal, () => signalChild("SIGTERM"), () => signalChild("SIGKILL"), () => {
|
|
349
|
+
const reason = new Error("Command capture closed after forced termination");
|
|
350
|
+
captures.stdout?.cancel(reason);
|
|
351
|
+
captures.stderr?.cancel(reason);
|
|
352
|
+
});
|
|
353
|
+
const captureBudget = createCaptureBudget(maxOutputBytes, () => guard.stop("output-limit"));
|
|
354
|
+
captures.stdout = shouldCapture && child.stdout
|
|
355
|
+
? captureStreamToString(child.stdout, captureBudget)
|
|
356
|
+
: undefined;
|
|
357
|
+
captures.stderr = shouldCapture && child.stderr
|
|
358
|
+
? captureStreamToString(child.stderr, captureBudget)
|
|
359
|
+
: undefined;
|
|
105
360
|
try {
|
|
106
361
|
const [status, stdout, stderr] = await Promise.all([
|
|
107
362
|
child.status,
|
|
108
|
-
|
|
109
|
-
|
|
363
|
+
captures.stdout?.result ?? Promise.resolve(undefined),
|
|
364
|
+
captures.stderr?.result ?? Promise.resolve(undefined),
|
|
110
365
|
]);
|
|
111
|
-
|
|
112
|
-
|
|
366
|
+
const reason = guard.reason();
|
|
367
|
+
if (reason) {
|
|
368
|
+
return createTerminationResult(reason, reason === "timeout" ? effectiveTimeoutMs ?? 0 : maxOutputBytes, stdout, stderr, captureBudget.exceeded);
|
|
113
369
|
}
|
|
114
370
|
return {
|
|
115
371
|
success: status.success,
|
|
@@ -119,41 +375,73 @@ export async function runCommand(cmd, options = {}) {
|
|
|
119
375
|
};
|
|
120
376
|
}
|
|
121
377
|
finally {
|
|
122
|
-
|
|
378
|
+
if (terminateProcessTreeOnExit && guard.reason() === null) {
|
|
379
|
+
tryForceSettledProcessTree(signalChild);
|
|
380
|
+
}
|
|
381
|
+
guard.clear();
|
|
123
382
|
}
|
|
124
383
|
}
|
|
125
384
|
if (IS_BUN) {
|
|
126
385
|
const bunGlobal = dntShim.dntGlobalThis;
|
|
127
|
-
const bunStdio = inherit ? "inherit" :
|
|
128
|
-
const shellCommand = shell ?
|
|
386
|
+
const bunStdio = inherit ? "inherit" : shouldCapture ? "pipe" : "ignore";
|
|
387
|
+
const shellCommand = shell ? resolveShellCommand(cmd, args) : null;
|
|
129
388
|
const bunCmd = shellCommand ? [shellCommand.cmd, ...shellCommand.args] : [cmd, ...args];
|
|
130
389
|
const proc = bunGlobal.Bun.spawn({
|
|
131
390
|
cmd: bunCmd,
|
|
132
391
|
cwd: cmdCwd,
|
|
392
|
+
detached: detachedProcessGroup,
|
|
133
393
|
env: clearEnv ? cmdEnv ?? {} : cmdEnv,
|
|
134
394
|
stdout: bunStdio,
|
|
135
395
|
stderr: bunStdio,
|
|
136
396
|
});
|
|
137
|
-
const
|
|
397
|
+
const windowsPlatform = isWindowsPlatform();
|
|
398
|
+
const directSignal = (terminationSignal) => proc.kill?.(terminationSignal);
|
|
399
|
+
const signalChild = (terminationSignal) => windowsPlatform
|
|
400
|
+
? signalWindowsTreeWithBun(bunGlobal.Bun, proc.pid, terminationSignal === "SIGKILL", directSignal)
|
|
401
|
+
: signalProcessTree(proc.pid, terminationSignal, detachedProcessGroup, (processGroupId, groupSignal) => {
|
|
402
|
+
if (!runtimeProcess)
|
|
403
|
+
throw new Error("Runtime process unavailable");
|
|
404
|
+
runtimeProcess.kill(processGroupId, groupSignal);
|
|
405
|
+
}, directSignal);
|
|
406
|
+
const captures = {};
|
|
407
|
+
const guard = createProcessGuard(effectiveTimeoutMs, signal, () => signalChild("SIGTERM"), () => signalChild("SIGKILL"), () => {
|
|
408
|
+
const reason = new Error("Command capture closed after forced termination");
|
|
409
|
+
captures.stdout?.cancel(reason);
|
|
410
|
+
captures.stderr?.cancel(reason);
|
|
411
|
+
});
|
|
412
|
+
const captureBudget = createCaptureBudget(maxOutputBytes, () => guard.stop("output-limit"));
|
|
413
|
+
captures.stdout = shouldCapture && proc.stdout
|
|
414
|
+
? captureStreamToString(proc.stdout, captureBudget)
|
|
415
|
+
: undefined;
|
|
416
|
+
captures.stderr = shouldCapture && proc.stderr
|
|
417
|
+
? captureStreamToString(proc.stderr, captureBudget)
|
|
418
|
+
: undefined;
|
|
138
419
|
try {
|
|
139
420
|
const [code, stdout, stderr] = await Promise.all([
|
|
140
421
|
proc.exited,
|
|
141
|
-
|
|
142
|
-
|
|
422
|
+
captures.stdout?.result ?? Promise.resolve(undefined),
|
|
423
|
+
captures.stderr?.result ?? Promise.resolve(undefined),
|
|
143
424
|
]);
|
|
144
|
-
|
|
145
|
-
|
|
425
|
+
const reason = guard.reason();
|
|
426
|
+
if (reason) {
|
|
427
|
+
return createTerminationResult(reason, reason === "timeout" ? effectiveTimeoutMs ?? 0 : maxOutputBytes, stdout, stderr, captureBudget.exceeded);
|
|
146
428
|
}
|
|
147
429
|
return { success: code === 0, code, stdout, stderr };
|
|
148
430
|
}
|
|
149
431
|
finally {
|
|
150
|
-
|
|
432
|
+
if (terminateProcessTreeOnExit && guard.reason() === null) {
|
|
433
|
+
tryForceSettledProcessTree(signalChild);
|
|
434
|
+
}
|
|
435
|
+
guard.clear();
|
|
151
436
|
}
|
|
152
437
|
}
|
|
153
438
|
if (!runtimeProcess)
|
|
154
439
|
return { success: false, code: 1 };
|
|
155
440
|
const process = runtimeProcess;
|
|
156
441
|
const { spawn } = await dynamicImport("node:child_process");
|
|
442
|
+
if (signal && isAbortSignalAborted(signal)) {
|
|
443
|
+
return createTerminationResult("abort", 0);
|
|
444
|
+
}
|
|
157
445
|
const nodeStdio = inherit
|
|
158
446
|
? ["inherit", "inherit", "inherit"]
|
|
159
447
|
: capture
|
|
@@ -165,41 +453,68 @@ export async function runCommand(cmd, options = {}) {
|
|
|
165
453
|
env: clearEnv ? cmdEnv ?? {} : cmdEnv ? { ...process.env, ...cmdEnv } : undefined,
|
|
166
454
|
stdio: nodeStdio,
|
|
167
455
|
shell,
|
|
456
|
+
detached: detachedProcessGroup,
|
|
457
|
+
});
|
|
458
|
+
const stdoutChunks = [];
|
|
459
|
+
const stderrChunks = [];
|
|
460
|
+
const windowsPlatform = isWindowsPlatform();
|
|
461
|
+
const directSignal = (terminationSignal) => child.kill(terminationSignal);
|
|
462
|
+
const signalChild = (terminationSignal) => windowsPlatform
|
|
463
|
+
? signalWindowsTreeWithNode(spawn, child.pid, terminationSignal === "SIGKILL", directSignal)
|
|
464
|
+
: signalProcessTree(child.pid, terminationSignal, detachedProcessGroup, (processGroupId, groupSignal) => process.kill(processGroupId, groupSignal), directSignal);
|
|
465
|
+
const guard = createProcessGuard(effectiveTimeoutMs, signal, () => signalChild("SIGTERM"), () => signalChild("SIGKILL"), () => {
|
|
466
|
+
child.stdout?.destroy();
|
|
467
|
+
child.stderr?.destroy();
|
|
168
468
|
});
|
|
169
|
-
|
|
170
|
-
let
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
469
|
+
const captureBudget = createCaptureBudget(maxOutputBytes, () => guard.stop("output-limit"));
|
|
470
|
+
let resultSettled = false;
|
|
471
|
+
const settleProcessOwnership = () => {
|
|
472
|
+
if (resultSettled)
|
|
473
|
+
return false;
|
|
474
|
+
resultSettled = true;
|
|
475
|
+
if (terminateProcessTreeOnExit && guard.reason() === null) {
|
|
476
|
+
tryForceSettledProcessTree(signalChild);
|
|
477
|
+
}
|
|
478
|
+
guard.clear();
|
|
479
|
+
return true;
|
|
480
|
+
};
|
|
481
|
+
if (shouldCapture) {
|
|
174
482
|
child.stdout?.on("data", (data) => {
|
|
175
|
-
|
|
483
|
+
captureChunk(stdoutChunks, data, captureBudget);
|
|
176
484
|
});
|
|
177
485
|
child.stderr?.on("data", (data) => {
|
|
178
|
-
|
|
486
|
+
captureChunk(stderrChunks, data, captureBudget);
|
|
179
487
|
});
|
|
180
488
|
}
|
|
181
489
|
child.on("close", (code) => {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
490
|
+
if (!settleProcessOwnership())
|
|
491
|
+
return;
|
|
492
|
+
const stdout = shouldCapture ? decodeChunks(stdoutChunks) : undefined;
|
|
493
|
+
const stderr = shouldCapture ? decodeChunks(stderrChunks) : undefined;
|
|
494
|
+
const reason = guard.reason();
|
|
495
|
+
if (reason) {
|
|
496
|
+
resolve(createTerminationResult(reason, reason === "timeout" ? effectiveTimeoutMs ?? 0 : maxOutputBytes, stdout, stderr, captureBudget.exceeded));
|
|
185
497
|
return;
|
|
186
498
|
}
|
|
187
499
|
resolve({
|
|
188
500
|
success: code === 0,
|
|
189
501
|
code: code ?? 1,
|
|
190
|
-
stdout
|
|
191
|
-
stderr
|
|
502
|
+
stdout,
|
|
503
|
+
stderr,
|
|
192
504
|
});
|
|
193
505
|
});
|
|
194
506
|
child.on("error", (spawnError) => {
|
|
195
|
-
|
|
507
|
+
if (!settleProcessOwnership())
|
|
508
|
+
return;
|
|
509
|
+
const stdout = shouldCapture ? decodeChunks(stdoutChunks) : undefined;
|
|
510
|
+
const stderr = shouldCapture ? decodeChunks(stderrChunks) : undefined;
|
|
196
511
|
// Include the spawn error message so callers can distinguish ENOENT
|
|
197
512
|
// ("command not found"), EACCES ("permission denied"), etc.
|
|
198
513
|
resolve({
|
|
199
514
|
success: false,
|
|
200
515
|
code: 1,
|
|
201
|
-
stdout
|
|
202
|
-
stderr:
|
|
516
|
+
stdout,
|
|
517
|
+
stderr: shouldCapture
|
|
203
518
|
? (stderr
|
|
204
519
|
? `${stderr}\nSpawn error: ${spawnError.message}`
|
|
205
520
|
: `Spawn error: ${spawnError.message}`)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ProjectEnvSnapshot } from "./project-env-contract.js";
|
|
1
2
|
export type EnvOverlayStorage = {
|
|
2
3
|
getStore: () => unknown;
|
|
3
4
|
run?: <T>(store: unknown, fn: () => T) => T;
|
|
@@ -10,6 +11,16 @@ export declare function env(): Record<string, string>;
|
|
|
10
11
|
* Use this for framework-owned runtime configuration that should not be shadowed by tenant env.
|
|
11
12
|
*/
|
|
12
13
|
export declare function getHostEnv(key: string): string | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Register the server-owned project environment snapshot bridge.
|
|
16
|
+
*
|
|
17
|
+
* Kept out of the public process barrel so project code cannot replace the
|
|
18
|
+
* callback through a supported package export. Re-registering a different
|
|
19
|
+
* function is rejected rather than silently widening an isolation boundary.
|
|
20
|
+
*/
|
|
21
|
+
export declare function registerTrustedProjectEnvSnapshot(getter: () => ProjectEnvSnapshot | undefined): void;
|
|
22
|
+
/** Return the active server-owned project env snapshot, if registered. */
|
|
23
|
+
export declare function getTrustedProjectEnvSnapshot(): ProjectEnvSnapshot | undefined;
|
|
13
24
|
/** Read an environment variable from the active project scope. */
|
|
14
25
|
export declare function getEnv(key: string): string | undefined;
|
|
15
26
|
export interface EnvBooleanOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/compat/process/env.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/compat/process/env.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAKpE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,OAAO,CAAC;IACxB,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACtC,CAAC;AAoBF,oDAAoD;AACpD,wBAAgB,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAoB5C;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAqB1D;AAID;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,MAAM,kBAAkB,GAAG,SAAS,GAC3C,IAAI,CAKN;AAED,0EAA0E;AAC1E,wBAAgB,4BAA4B,IAAI,kBAAkB,GAAG,SAAS,CAE7E;AAED,kEAAkE;AAClE,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAWtD;AAKD,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAUD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAC9D,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;AAOpE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAC9D,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;AAapE,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,QAAQ,UAAQ,EAChB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAmBT;AAED,gBAAgB;AAChB,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAiBvD;AAED,6CAA6C;AAC7C,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAiB3C;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,iBAAiB,GAAG,IAAI,CAS/D"}
|