@poe-platform/safe-js 0.1.799 → 0.1.800
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 +3 -1
- package/dist/safe-js/chunks/{chunk-ULPZIHB5.js → chunk-5RLD4TVI.js} +174 -127
- package/dist/safe-js/chunks/{chunk-TBZILU4U.js → chunk-7THYP46K.js} +1 -1
- package/dist/safe-js/chunks/{chunk-UU4T2KIT.js → chunk-CK3YK2EC.js} +1 -1
- package/dist/safe-js/chunks/{chunk-3O7HA6WT.js → chunk-F6Y734YA.js} +2 -2
- package/dist/safe-js/chunks/{chunk-OPYN6N5M.js → chunk-HPHCQNFV.js} +154 -1
- package/dist/safe-js/chunks/{chunk-W6C3Q6U4.js → chunk-LWHXSNF6.js} +2 -2
- package/dist/safe-js/chunks/{chunk-ZKLJW27N.js → chunk-PMOXSLM5.js} +1 -1
- package/dist/safe-js/chunks/{chunk-M6S3F3WM.js → chunk-QEDOBN2G.js} +4 -4
- package/dist/safe-js/chunks/chunk-QRWRR6IA.js +78 -0
- package/dist/safe-js/chunks/{chunk-MCFRB5X3.js → chunk-SHMRT4QX.js} +76 -6
- package/dist/safe-js/chunks/{chunk-KULEMOAE.js → chunk-XAV2RKLO.js} +3 -154
- package/dist/safe-js/chunks/{chunk-MDJ7MJYI.js → chunk-XOMGWE37.js} +2 -2
- package/dist/safe-js/chunks/{chunk-QTCPJ7FN.js → chunk-XV5OYKND.js} +1 -1
- package/dist/safe-js/chunks/{chunk-OTVZWRYE.js → chunk-YAHDXC7P.js} +1 -1
- package/dist/safe-js/chunks/{cli-runtime-DYXJZCGV.js → cli-runtime-OCWFX4TM.js} +15 -15
- package/dist/safe-js/chunks/{dump-XDJEF2LG.js → dump-KUPBSXSL.js} +2 -2
- package/dist/safe-js/chunks/{harness-32OOFC5A.js → harness-3DDUS3RY.js} +2 -2
- package/dist/safe-js/chunks/{mcp-PTCA53MN.js → mcp-4D3WWY7U.js} +3 -3
- package/dist/safe-js/chunks/{migration-file-EEGIOHQB.js → migration-file-4CYSJ6LO.js} +3 -3
- package/dist/safe-js/chunks/{restore-U3CCH36B.js → restore-GDHBT5ZD.js} +3 -3
- package/dist/safe-js/chunks/{run-Q74MU3QQ.js → run-3X6J7FPV.js} +5 -5
- package/dist/safe-js/chunks/{runtime-modules-SL5D6LAJ.js → runtime-modules-MGSXY4BN.js} +2 -2
- package/dist/safe-js/cli.js +2 -2
- package/dist/safe-js/core.d.ts +6 -0
- package/dist/safe-js/core.js +33 -7
- package/dist/safe-js/index.js +24 -93
- package/dist/safe-js/interp/data-copy.d.ts +3 -2
- package/dist/safe-js/interp/host-bridge.d.ts +5 -4
- package/dist/safe-js/modules/fs.js +2 -2
- package/dist/safe-js/node-unavailable.d.ts +1 -0
- package/dist/safe-js/portable/chunks/chunk-H5X3T5VP.js +909 -0
- package/dist/safe-js/portable/chunks/chunk-KYJVK33V.js +58698 -0
- package/dist/safe-js/portable/chunks/chunk-XCTU25SU.js +111 -0
- package/dist/safe-js/portable/chunks/source-files-CVU252FB.js +7 -0
- package/dist/safe-js/portable/core.js +14757 -0
- package/dist/safe-js/portable/modules/fs.js +9 -0
- package/dist/safe-js/snapshot/arguments.d.ts +2 -0
- package/dist/safe-js/snapshot/property-descriptors.d.ts +2 -0
- package/dist/safe-js/snapshot/regexp-properties.d.ts +2 -0
- package/dist/safe-js/snapshot/symbols.d.ts +2 -0
- package/dist/safe-js/workerd.d.ts +3 -0
- package/dist/safe-js/workerd.js +74425 -0
- package/package.json +30 -6
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
validateMigrationReconciliation,
|
|
11
11
|
validateMigrationSemantics,
|
|
12
12
|
validateSnapshotMigration
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-PMOXSLM5.js";
|
|
14
14
|
import {
|
|
15
15
|
DUMP_FORMAT_VERSION,
|
|
16
16
|
EXECUTION_SEMANTICS,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
serializeSafeJSSnapshot,
|
|
21
21
|
validateDumpEnvelope,
|
|
22
22
|
validateSnapshotData
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-5RLD4TVI.js";
|
|
24
24
|
import {
|
|
25
25
|
parseModule
|
|
26
26
|
} from "./chunk-A3LXCGMJ.js";
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
collectComments,
|
|
6
6
|
formatParseError,
|
|
7
7
|
hoistedVarDeclarations,
|
|
8
|
+
hostErrorData,
|
|
8
9
|
numericTypedArrayConstructors,
|
|
9
10
|
parseModule,
|
|
10
11
|
tokenize
|
|
@@ -11174,6 +11175,158 @@ function hasOnlyRegexLiteralDiagnostics(diagnostics) {
|
|
|
11174
11175
|
);
|
|
11175
11176
|
}
|
|
11176
11177
|
|
|
11178
|
+
// packages/safe-js/src/modules/env.ts
|
|
11179
|
+
var EnvAccessError = class extends Error {
|
|
11180
|
+
code = "ENV_ACCESS_DENIED";
|
|
11181
|
+
variable;
|
|
11182
|
+
constructor(variable) {
|
|
11183
|
+
super(`Environment access denied for ${JSON.stringify(variable)}.`);
|
|
11184
|
+
this.name = "EnvAccessError";
|
|
11185
|
+
this.variable = variable;
|
|
11186
|
+
hostErrorData.set(this, { code: this.code, variable });
|
|
11187
|
+
}
|
|
11188
|
+
};
|
|
11189
|
+
function makeEnvModule(input) {
|
|
11190
|
+
const options = normalizeEnvOptions(Array.isArray(input) ? { allow: input } : input);
|
|
11191
|
+
const allowedNames = new Set(options.allow);
|
|
11192
|
+
const values = options.values;
|
|
11193
|
+
return {
|
|
11194
|
+
get(name) {
|
|
11195
|
+
const variable = readEnvName(name, "Environment variable name");
|
|
11196
|
+
if (!allowedNames.has(variable)) throw new EnvAccessError(variable);
|
|
11197
|
+
return readEnvValue(values ?? (typeof process !== "undefined" ? process.env ?? {} : {}), variable);
|
|
11198
|
+
}
|
|
11199
|
+
};
|
|
11200
|
+
}
|
|
11201
|
+
function parseEnvConfig(json) {
|
|
11202
|
+
return normalizeEnvOptions(JSON.parse(json));
|
|
11203
|
+
}
|
|
11204
|
+
function normalizeEnvOptions(input) {
|
|
11205
|
+
if (input === null || typeof input !== "object" || Array.isArray(input)) {
|
|
11206
|
+
throw new TypeError("Environment options must be an object.");
|
|
11207
|
+
}
|
|
11208
|
+
const fields = Object.getOwnPropertyDescriptors(input);
|
|
11209
|
+
for (const key of Reflect.ownKeys(fields)) {
|
|
11210
|
+
if (key !== "allow" && key !== "values") {
|
|
11211
|
+
throw new TypeError("Unknown environment option.");
|
|
11212
|
+
}
|
|
11213
|
+
if (!("value" in fields[key])) {
|
|
11214
|
+
throw new TypeError("Environment options must not contain accessors.");
|
|
11215
|
+
}
|
|
11216
|
+
}
|
|
11217
|
+
const inputAllow = Object.getOwnPropertyDescriptor(input, "allow")?.value;
|
|
11218
|
+
if (!Array.isArray(inputAllow)) {
|
|
11219
|
+
throw new TypeError("Environment allow list must be an array of non-empty strings.");
|
|
11220
|
+
}
|
|
11221
|
+
const allow = [];
|
|
11222
|
+
for (let index = 0; index < inputAllow.length; index += 1) {
|
|
11223
|
+
const descriptor = Object.getOwnPropertyDescriptor(inputAllow, index);
|
|
11224
|
+
if (descriptor === void 0 || !("value" in descriptor)) {
|
|
11225
|
+
throw new TypeError("Environment allow list must contain only own data entries.");
|
|
11226
|
+
}
|
|
11227
|
+
allow.push(readEnvName(descriptor.value, `Environment allow list[${index}]`));
|
|
11228
|
+
}
|
|
11229
|
+
const inputValues = Object.getOwnPropertyDescriptor(input, "values")?.value;
|
|
11230
|
+
if (inputValues === void 0) return { allow };
|
|
11231
|
+
if (inputValues === null || typeof inputValues !== "object" || Array.isArray(inputValues)) {
|
|
11232
|
+
throw new TypeError("Environment values must be an object.");
|
|
11233
|
+
}
|
|
11234
|
+
return {
|
|
11235
|
+
allow,
|
|
11236
|
+
values: Object.fromEntries(allow.map((name) => [name, readEnvValue(inputValues, name)]))
|
|
11237
|
+
};
|
|
11238
|
+
}
|
|
11239
|
+
function readEnvValue(values, name) {
|
|
11240
|
+
const descriptor = Object.getOwnPropertyDescriptor(values, name);
|
|
11241
|
+
if (descriptor === void 0) return void 0;
|
|
11242
|
+
if (!("value" in descriptor)) {
|
|
11243
|
+
throw new TypeError(`Environment value for ${JSON.stringify(name)} must not be an accessor.`);
|
|
11244
|
+
}
|
|
11245
|
+
if (descriptor.value !== void 0 && typeof descriptor.value !== "string") {
|
|
11246
|
+
throw new TypeError(
|
|
11247
|
+
`Environment value for ${JSON.stringify(name)} must be a string or undefined.`
|
|
11248
|
+
);
|
|
11249
|
+
}
|
|
11250
|
+
return descriptor.value;
|
|
11251
|
+
}
|
|
11252
|
+
function readEnvName(value, label) {
|
|
11253
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
11254
|
+
throw new TypeError(`${label} must be a non-empty string.`);
|
|
11255
|
+
}
|
|
11256
|
+
if (value.includes("\0") || value.includes("=")) {
|
|
11257
|
+
throw new TypeError(`${label} must not contain NUL or equals signs.`);
|
|
11258
|
+
}
|
|
11259
|
+
return value;
|
|
11260
|
+
}
|
|
11261
|
+
|
|
11262
|
+
// packages/safe-js/src/modules/fail.ts
|
|
11263
|
+
var HarnessFailure = class extends Error {
|
|
11264
|
+
constructor(message) {
|
|
11265
|
+
super(message);
|
|
11266
|
+
this.name = "HarnessFailure";
|
|
11267
|
+
}
|
|
11268
|
+
};
|
|
11269
|
+
function makeFailModule() {
|
|
11270
|
+
function fail(message) {
|
|
11271
|
+
throw new HarnessFailure(readNonEmptyString(message, "Harness failure message"));
|
|
11272
|
+
}
|
|
11273
|
+
return {
|
|
11274
|
+
default: fail
|
|
11275
|
+
};
|
|
11276
|
+
}
|
|
11277
|
+
function readNonEmptyString(value, label) {
|
|
11278
|
+
if (typeof value !== "string") {
|
|
11279
|
+
throw new Error(`${label} must be a non-empty string.`);
|
|
11280
|
+
}
|
|
11281
|
+
if (value.trim().length === 0) {
|
|
11282
|
+
throw new Error(`${label} must be a non-empty string.`);
|
|
11283
|
+
}
|
|
11284
|
+
return value;
|
|
11285
|
+
}
|
|
11286
|
+
|
|
11287
|
+
// packages/safe-js/src/modules/metric.ts
|
|
11288
|
+
function makeMetricModule(npmRunner) {
|
|
11289
|
+
return {
|
|
11290
|
+
async run(name) {
|
|
11291
|
+
const metricName = readNonEmptyString2(name, "Metric name");
|
|
11292
|
+
const scriptName = `metric:${metricName}`;
|
|
11293
|
+
const stdout = await npmRunner(scriptName);
|
|
11294
|
+
const score = parseMetricScore(stdout, scriptName);
|
|
11295
|
+
return score;
|
|
11296
|
+
}
|
|
11297
|
+
};
|
|
11298
|
+
}
|
|
11299
|
+
function parseMetricScore(stdout, scriptName) {
|
|
11300
|
+
if (typeof stdout !== "string") {
|
|
11301
|
+
throw new Error(`Metric runner for "${scriptName}" must resolve to a stdout string.`);
|
|
11302
|
+
}
|
|
11303
|
+
const scoreLine = stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).at(-1);
|
|
11304
|
+
if (scoreLine === void 0) {
|
|
11305
|
+
throw new Error(`Metric script "${scriptName}" must print a numeric score.`);
|
|
11306
|
+
}
|
|
11307
|
+
const score = Number(scoreLine);
|
|
11308
|
+
if (!Number.isFinite(score)) {
|
|
11309
|
+
throw new Error(`Metric script "${scriptName}" must print a numeric score.`);
|
|
11310
|
+
}
|
|
11311
|
+
return score;
|
|
11312
|
+
}
|
|
11313
|
+
function readNonEmptyString2(value, label) {
|
|
11314
|
+
if (typeof value !== "string") {
|
|
11315
|
+
throw new Error(`${label} must be a non-empty string.`);
|
|
11316
|
+
}
|
|
11317
|
+
const normalizedValue = value.trim();
|
|
11318
|
+
if (normalizedValue.length === 0) {
|
|
11319
|
+
throw new Error(`${label} must be a non-empty string.`);
|
|
11320
|
+
}
|
|
11321
|
+
return normalizedValue;
|
|
11322
|
+
}
|
|
11323
|
+
|
|
11177
11324
|
export {
|
|
11178
|
-
lint
|
|
11325
|
+
lint,
|
|
11326
|
+
EnvAccessError,
|
|
11327
|
+
makeEnvModule,
|
|
11328
|
+
parseEnvConfig,
|
|
11329
|
+
HarnessFailure,
|
|
11330
|
+
makeFailModule,
|
|
11331
|
+
makeMetricModule
|
|
11179
11332
|
};
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
McpError,
|
|
3
3
|
connectMcpTransport,
|
|
4
4
|
normalizeMcpOptions
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-SHMRT4QX.js";
|
|
6
6
|
import {
|
|
7
7
|
declareHostOperation,
|
|
8
8
|
runResources
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-5RLD4TVI.js";
|
|
10
10
|
import {
|
|
11
11
|
hostErrorData
|
|
12
12
|
} from "./chunk-A3LXCGMJ.js";
|
|
@@ -7,15 +7,15 @@ import {
|
|
|
7
7
|
} from "./chunk-ONWFPHUI.js";
|
|
8
8
|
import {
|
|
9
9
|
restore
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-XOMGWE37.js";
|
|
11
11
|
import {
|
|
12
12
|
hashParsedAst,
|
|
13
13
|
hashSource
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-PMOXSLM5.js";
|
|
15
15
|
import {
|
|
16
16
|
attachDumpController,
|
|
17
17
|
createDumpController
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-XV5OYKND.js";
|
|
19
19
|
import {
|
|
20
20
|
DUMP_FORMAT_VERSION,
|
|
21
21
|
EXECUTION_SEMANTICS,
|
|
@@ -107,7 +107,7 @@ import {
|
|
|
107
107
|
wrapCallerInjectedBindings,
|
|
108
108
|
wrapCancelableBindings,
|
|
109
109
|
wrapHostConstructor
|
|
110
|
-
} from "./chunk-
|
|
110
|
+
} from "./chunk-5RLD4TVI.js";
|
|
111
111
|
import {
|
|
112
112
|
Budget,
|
|
113
113
|
CompileScope,
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createSeededRandom
|
|
3
|
+
} from "./chunk-5RLD4TVI.js";
|
|
4
|
+
|
|
5
|
+
// packages/safe-js/src/modules/time.ts
|
|
6
|
+
function makeTimeModule(options = {}) {
|
|
7
|
+
const hasDeterministicRandom = options.random !== void 0 || options.seed !== void 0;
|
|
8
|
+
const random = options.random ?? (options.seed === void 0 ? () => Math.random() : createSeededRandom(options.seed).next);
|
|
9
|
+
const now = options.now ?? (() => Date.now());
|
|
10
|
+
const signal = options.signal;
|
|
11
|
+
async function sleep(ms) {
|
|
12
|
+
assertSleepDelay(ms);
|
|
13
|
+
return await new Promise((resolve, reject) => {
|
|
14
|
+
if (signal?.aborted === true) {
|
|
15
|
+
reject(createSleepAbortError());
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const start = performance.now();
|
|
19
|
+
let timeout = setTimeout(resolveSleep, ms);
|
|
20
|
+
function cleanup() {
|
|
21
|
+
clearTimeout(timeout);
|
|
22
|
+
signal?.removeEventListener("abort", rejectSleep);
|
|
23
|
+
}
|
|
24
|
+
function resolveSleep() {
|
|
25
|
+
const remainingMs = ms - (performance.now() - start);
|
|
26
|
+
if (remainingMs > 0) {
|
|
27
|
+
timeout = setTimeout(resolveSleep, remainingMs);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
cleanup();
|
|
31
|
+
resolve();
|
|
32
|
+
}
|
|
33
|
+
function rejectSleep() {
|
|
34
|
+
cleanup();
|
|
35
|
+
reject(createSleepAbortError());
|
|
36
|
+
}
|
|
37
|
+
signal?.addEventListener("abort", rejectSleep, { once: true });
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
random,
|
|
42
|
+
now,
|
|
43
|
+
sleep,
|
|
44
|
+
uuid: hasDeterministicRandom ? () => createRandomUuid(random) : () => globalThis.crypto.randomUUID()
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function createRandomUuid(random) {
|
|
48
|
+
const bytes = Array.from({ length: 16 }, () => Math.floor(readRandomUnit(random()) * 256));
|
|
49
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
50
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
51
|
+
const hex = bytes.map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
52
|
+
return [
|
|
53
|
+
hex.slice(0, 8),
|
|
54
|
+
hex.slice(8, 12),
|
|
55
|
+
hex.slice(12, 16),
|
|
56
|
+
hex.slice(16, 20),
|
|
57
|
+
hex.slice(20)
|
|
58
|
+
].join("-");
|
|
59
|
+
}
|
|
60
|
+
function readRandomUnit(value) {
|
|
61
|
+
if (Number.isFinite(value) && value >= 0 && value < 1) {
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
throw new RangeError("time.uuid() random source must return a number in [0, 1).");
|
|
65
|
+
}
|
|
66
|
+
function assertSleepDelay(ms) {
|
|
67
|
+
if (Number.isFinite(ms) && ms >= 0) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
throw new RangeError("time.sleep(ms) requires a non-negative finite millisecond delay.");
|
|
71
|
+
}
|
|
72
|
+
function createSleepAbortError() {
|
|
73
|
+
return new Error("time.sleep aborted.");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export {
|
|
77
|
+
makeTimeModule
|
|
78
|
+
};
|
|
@@ -3753,6 +3753,7 @@ function snapshotLoopbackAuthorizationOptions(options) {
|
|
|
3753
3753
|
...options,
|
|
3754
3754
|
openBrowser: options.openBrowser?.bind(options),
|
|
3755
3755
|
readLine: options.readLine?.bind(options),
|
|
3756
|
+
waitForCallback: options.waitForCallback?.bind(options),
|
|
3756
3757
|
createServer: options.createServer?.bind(options),
|
|
3757
3758
|
callbackPath: options.callbackPath,
|
|
3758
3759
|
redirectUri: options.redirectUri,
|
|
@@ -3767,6 +3768,7 @@ async function createLoopbackAuthorizationSession(options = {}) {
|
|
|
3767
3768
|
const timeoutMs = options.timeoutMs ?? 12e4;
|
|
3768
3769
|
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2147483647)
|
|
3769
3770
|
throw new Error("OAuth authorization timeoutMs must be a positive supported timer interval");
|
|
3771
|
+
if (options.waitForCallback !== void 0) return createHostedAuthorizationSession(options, timeoutMs);
|
|
3770
3772
|
const target = loopbackTarget(options);
|
|
3771
3773
|
const server = options.createServer ? options.createServer() : http.createServer();
|
|
3772
3774
|
const controller = new AbortController();
|
|
@@ -3829,6 +3831,72 @@ function loopbackTarget(options) {
|
|
|
3829
3831
|
throw new Error("Invalid OAuth loopback callback path");
|
|
3830
3832
|
return { port: 0, host: "127.0.0.1", callbackPath };
|
|
3831
3833
|
}
|
|
3834
|
+
function validateAuthorizationRedirect(options) {
|
|
3835
|
+
if (options.waitForCallback === void 0) {
|
|
3836
|
+
loopbackTarget(options);
|
|
3837
|
+
return;
|
|
3838
|
+
}
|
|
3839
|
+
if (typeof options.waitForCallback !== "function" || options.redirectUri === void 0)
|
|
3840
|
+
throw new Error("Hosted OAuth callbacks require redirectUri and waitForCallback");
|
|
3841
|
+
validateHostedOAuthRedirect(options.redirectUri, options.callbackPath);
|
|
3842
|
+
}
|
|
3843
|
+
function validateHostedOAuthRedirect(redirectUri, callbackPath) {
|
|
3844
|
+
const url = new URL(redirectUri);
|
|
3845
|
+
if (url.protocol !== "https:" || url.username || url.password || url.href.includes("#") || url.port === "0" || oauthCallbackParameters.some((name) => url.searchParams.has(name)) || [...redirectUri].some((char) => char.codePointAt(0) <= 32) || callbackPath !== void 0 && callbackPath !== url.pathname)
|
|
3846
|
+
throw new Error("Invalid hosted OAuth redirect URI");
|
|
3847
|
+
}
|
|
3848
|
+
function createHostedAuthorizationSession(options, timeoutMs) {
|
|
3849
|
+
validateAuthorizationRedirect(options);
|
|
3850
|
+
const redirectUri = options.redirectUri, controller = new AbortController();
|
|
3851
|
+
let used = false;
|
|
3852
|
+
const aborted = () => controller.abort(options.signal?.reason);
|
|
3853
|
+
const timer = setTimeout(() => controller.abort(new Error("OAuth authorization timed out")), timeoutMs);
|
|
3854
|
+
timer.unref?.();
|
|
3855
|
+
const cleanup = () => {
|
|
3856
|
+
clearTimeout(timer);
|
|
3857
|
+
options.signal?.removeEventListener("abort", aborted);
|
|
3858
|
+
};
|
|
3859
|
+
controller.signal.addEventListener("abort", cleanup, { once: true });
|
|
3860
|
+
options.signal?.addEventListener("abort", aborted, { once: true });
|
|
3861
|
+
if (options.signal?.aborted) aborted();
|
|
3862
|
+
return {
|
|
3863
|
+
redirectUri,
|
|
3864
|
+
async waitForCode(authorizationUrl) {
|
|
3865
|
+
controller.signal.throwIfAborted();
|
|
3866
|
+
if (used) throw new Error("OAuth authorization session has already been used");
|
|
3867
|
+
used = true;
|
|
3868
|
+
try {
|
|
3869
|
+
const authorization = new URL(authorizationUrl);
|
|
3870
|
+
if (authorization.searchParams.getAll("redirect_uri").length !== 1 || authorization.searchParams.get("redirect_uri") !== redirectUri)
|
|
3871
|
+
throw new Error("OAuth authorization redirect mismatch");
|
|
3872
|
+
const callback = await new Promise((resolve, reject) => {
|
|
3873
|
+
const onAbort = () => reject(controller.signal.reason);
|
|
3874
|
+
controller.signal.addEventListener("abort", onAbort, { once: true });
|
|
3875
|
+
void Promise.resolve().then(() => {
|
|
3876
|
+
controller.signal.throwIfAborted();
|
|
3877
|
+
return options.waitForCallback({ authorizationUrl, redirectUri, signal: controller.signal });
|
|
3878
|
+
}).then(resolve, reject).finally(() => controller.signal.removeEventListener("abort", onAbort));
|
|
3879
|
+
});
|
|
3880
|
+
controller.signal.throwIfAborted();
|
|
3881
|
+
const url = new URL(callback), base = new URL(redirectUri);
|
|
3882
|
+
if (url.origin !== base.origin || url.pathname !== base.pathname || url.username || url.password || url.href.includes("#") || [...callback].some((char) => char.codePointAt(0) <= 32)) throw new Error("OAuth callback redirect mismatch");
|
|
3883
|
+
const params = readAuthorizationCallbackParameters(url);
|
|
3884
|
+
for (const name of oauthCallbackParameters) url.searchParams.delete(name);
|
|
3885
|
+
if (url.searchParams.toString() !== base.searchParams.toString()) throw new Error("OAuth callback redirect mismatch");
|
|
3886
|
+
const expected = readExpectedAuthorizationCallback(authorizationUrl);
|
|
3887
|
+
if (expected.state === null) throw new Error("OAuth authorization missing state");
|
|
3888
|
+
validateAuthorizationCallbackBinding(params, expected);
|
|
3889
|
+
if (params.error !== null) throw new OAuthAuthorizationError(params.error, params.errorDescription ?? params.error);
|
|
3890
|
+
return validateAuthorizationCallbackParameters(params, expected);
|
|
3891
|
+
} finally {
|
|
3892
|
+
controller.abort(new Error("OAuth authorization session closed"));
|
|
3893
|
+
}
|
|
3894
|
+
},
|
|
3895
|
+
close() {
|
|
3896
|
+
controller.abort(new Error("OAuth authorization session closed"));
|
|
3897
|
+
}
|
|
3898
|
+
};
|
|
3899
|
+
}
|
|
3832
3900
|
async function startServer(server, port, host, signal) {
|
|
3833
3901
|
signal.throwIfAborted();
|
|
3834
3902
|
return new Promise((resolve, reject) => {
|
|
@@ -4076,7 +4144,9 @@ function normalizeStoredOAuthClient(value) {
|
|
|
4076
4144
|
if (requestedRedirectUri !== void 0) {
|
|
4077
4145
|
try {
|
|
4078
4146
|
if (typeof requestedRedirectUri !== "string") throw new Error("Invalid redirect identity");
|
|
4079
|
-
|
|
4147
|
+
if (new URL(requestedRedirectUri).protocol === "https:")
|
|
4148
|
+
validateHostedOAuthRedirect(requestedRedirectUri);
|
|
4149
|
+
else loopbackTarget({ redirectUri: requestedRedirectUri });
|
|
4080
4150
|
} catch {
|
|
4081
4151
|
throw new Error("Invalid stored OAuth registration redirect identity");
|
|
4082
4152
|
}
|
|
@@ -4968,7 +5038,7 @@ function isStoredOAuthTokensOrMissing(value) {
|
|
|
4968
5038
|
return false;
|
|
4969
5039
|
}
|
|
4970
5040
|
const scope = getOwnEntry4(value, "scope");
|
|
4971
|
-
return scope === void 0 || typeof scope === "string" && scope.trim().length > 0;
|
|
5041
|
+
return scope === void 0 || scope === "" || typeof scope === "string" && scope.trim().length > 0;
|
|
4972
5042
|
}
|
|
4973
5043
|
function isNonBlankOwnString(record2, key2) {
|
|
4974
5044
|
const value = getOwnString(record2, key2);
|
|
@@ -5368,7 +5438,7 @@ async function requestTokens(input) {
|
|
|
5368
5438
|
throw new Error("OAuth token response has invalid refresh_token");
|
|
5369
5439
|
const scope = getOwnEntry5(payload, "scope");
|
|
5370
5440
|
const normalizedRefreshToken = typeof refreshToken === "string" && refreshToken.trim().length > 0 ? refreshToken.trim() : void 0;
|
|
5371
|
-
const normalizedScope = normalizeOAuthScope(scope);
|
|
5441
|
+
const normalizedScope = scope === "" ? "" : normalizeOAuthScope(scope);
|
|
5372
5442
|
if (scope !== void 0 && normalizedScope === void 0)
|
|
5373
5443
|
throw new Error("Invalid OAuth scope syntax in token response");
|
|
5374
5444
|
return {
|
|
@@ -5494,7 +5564,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
5494
5564
|
const clientMode = options.client.mode;
|
|
5495
5565
|
const interactiveEnabled = options.allowInteractive !== false;
|
|
5496
5566
|
const sessionLockTimeoutMs = options.sessionLockTimeoutMs;
|
|
5497
|
-
|
|
5567
|
+
validateAuthorizationRedirect(browser);
|
|
5498
5568
|
assertPersistenceNamespace(options.persistenceNamespace);
|
|
5499
5569
|
const clientMetadata = getClientMetadata(options.client);
|
|
5500
5570
|
const requestedScope = clientMetadata?.scope;
|
|
@@ -6116,7 +6186,7 @@ function normalizeStoredTokens(value) {
|
|
|
6116
6186
|
const scope = getOwnEntry6(value, "scope");
|
|
6117
6187
|
const normalizedAccessToken = accessToken?.trim();
|
|
6118
6188
|
const normalizedRefreshToken = typeof refreshToken === "string" ? refreshToken.trim() : void 0;
|
|
6119
|
-
const normalizedScope = normalizeOAuthScope(scope);
|
|
6189
|
+
const normalizedScope = scope === "" ? "" : normalizeOAuthScope(scope);
|
|
6120
6190
|
if (accessToken === void 0 || normalizedAccessToken === void 0 || normalizedAccessToken.length === 0 || tokenType !== "Bearer" || !(expiresAt === null || typeof expiresAt === "number" && Number.isSafeInteger(expiresAt) && expiresAt <= MAX_JS_DATE_MS3 && Number.isFinite(new Date(expiresAt).getTime())) || refreshToken !== void 0 && (typeof refreshToken !== "string" || normalizedRefreshToken === void 0 || normalizedRefreshToken.length === 0)) {
|
|
6121
6191
|
return void 0;
|
|
6122
6192
|
}
|
|
@@ -6125,7 +6195,7 @@ function normalizeStoredTokens(value) {
|
|
|
6125
6195
|
tokenType,
|
|
6126
6196
|
expiresAt,
|
|
6127
6197
|
...normalizedRefreshToken === void 0 ? {} : { refreshToken: normalizedRefreshToken },
|
|
6128
|
-
...normalizedScope === void 0
|
|
6198
|
+
...normalizedScope === void 0 ? {} : { scope: normalizedScope }
|
|
6129
6199
|
};
|
|
6130
6200
|
}
|
|
6131
6201
|
function getClientMetadata(client) {
|
|
@@ -2524,115 +2524,6 @@ function isRecord2(value) {
|
|
|
2524
2524
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2525
2525
|
}
|
|
2526
2526
|
|
|
2527
|
-
// packages/safe-js/src/modules/env.ts
|
|
2528
|
-
var EnvAccessError = class extends Error {
|
|
2529
|
-
code = "ENV_ACCESS_DENIED";
|
|
2530
|
-
variable;
|
|
2531
|
-
constructor(variable) {
|
|
2532
|
-
super(`Environment access denied for ${JSON.stringify(variable)}.`);
|
|
2533
|
-
this.name = "EnvAccessError";
|
|
2534
|
-
this.variable = variable;
|
|
2535
|
-
hostErrorData.set(this, { code: this.code, variable });
|
|
2536
|
-
}
|
|
2537
|
-
};
|
|
2538
|
-
function makeEnvModule(input) {
|
|
2539
|
-
const options = normalizeEnvOptions(Array.isArray(input) ? { allow: input } : input);
|
|
2540
|
-
const allowedNames = new Set(options.allow);
|
|
2541
|
-
const values = options.values;
|
|
2542
|
-
return {
|
|
2543
|
-
get(name) {
|
|
2544
|
-
const variable = readEnvName(name, "Environment variable name");
|
|
2545
|
-
if (!allowedNames.has(variable)) throw new EnvAccessError(variable);
|
|
2546
|
-
return readEnvValue(values ?? (typeof process !== "undefined" ? process.env ?? {} : {}), variable);
|
|
2547
|
-
}
|
|
2548
|
-
};
|
|
2549
|
-
}
|
|
2550
|
-
function parseEnvConfig(json) {
|
|
2551
|
-
return normalizeEnvOptions(JSON.parse(json));
|
|
2552
|
-
}
|
|
2553
|
-
function normalizeEnvOptions(input) {
|
|
2554
|
-
if (input === null || typeof input !== "object" || Array.isArray(input)) {
|
|
2555
|
-
throw new TypeError("Environment options must be an object.");
|
|
2556
|
-
}
|
|
2557
|
-
const fields = Object.getOwnPropertyDescriptors(input);
|
|
2558
|
-
for (const key of Reflect.ownKeys(fields)) {
|
|
2559
|
-
if (key !== "allow" && key !== "values") {
|
|
2560
|
-
throw new TypeError("Unknown environment option.");
|
|
2561
|
-
}
|
|
2562
|
-
if (!("value" in fields[key])) {
|
|
2563
|
-
throw new TypeError("Environment options must not contain accessors.");
|
|
2564
|
-
}
|
|
2565
|
-
}
|
|
2566
|
-
const inputAllow = Object.getOwnPropertyDescriptor(input, "allow")?.value;
|
|
2567
|
-
if (!Array.isArray(inputAllow)) {
|
|
2568
|
-
throw new TypeError("Environment allow list must be an array of non-empty strings.");
|
|
2569
|
-
}
|
|
2570
|
-
const allow = [];
|
|
2571
|
-
for (let index = 0; index < inputAllow.length; index += 1) {
|
|
2572
|
-
const descriptor = Object.getOwnPropertyDescriptor(inputAllow, index);
|
|
2573
|
-
if (descriptor === void 0 || !("value" in descriptor)) {
|
|
2574
|
-
throw new TypeError("Environment allow list must contain only own data entries.");
|
|
2575
|
-
}
|
|
2576
|
-
allow.push(readEnvName(descriptor.value, `Environment allow list[${index}]`));
|
|
2577
|
-
}
|
|
2578
|
-
const inputValues = Object.getOwnPropertyDescriptor(input, "values")?.value;
|
|
2579
|
-
if (inputValues === void 0) return { allow };
|
|
2580
|
-
if (inputValues === null || typeof inputValues !== "object" || Array.isArray(inputValues)) {
|
|
2581
|
-
throw new TypeError("Environment values must be an object.");
|
|
2582
|
-
}
|
|
2583
|
-
return {
|
|
2584
|
-
allow,
|
|
2585
|
-
values: Object.fromEntries(allow.map((name) => [name, readEnvValue(inputValues, name)]))
|
|
2586
|
-
};
|
|
2587
|
-
}
|
|
2588
|
-
function readEnvValue(values, name) {
|
|
2589
|
-
const descriptor = Object.getOwnPropertyDescriptor(values, name);
|
|
2590
|
-
if (descriptor === void 0) return void 0;
|
|
2591
|
-
if (!("value" in descriptor)) {
|
|
2592
|
-
throw new TypeError(`Environment value for ${JSON.stringify(name)} must not be an accessor.`);
|
|
2593
|
-
}
|
|
2594
|
-
if (descriptor.value !== void 0 && typeof descriptor.value !== "string") {
|
|
2595
|
-
throw new TypeError(
|
|
2596
|
-
`Environment value for ${JSON.stringify(name)} must be a string or undefined.`
|
|
2597
|
-
);
|
|
2598
|
-
}
|
|
2599
|
-
return descriptor.value;
|
|
2600
|
-
}
|
|
2601
|
-
function readEnvName(value, label) {
|
|
2602
|
-
if (typeof value !== "string" || value.length === 0) {
|
|
2603
|
-
throw new TypeError(`${label} must be a non-empty string.`);
|
|
2604
|
-
}
|
|
2605
|
-
if (value.includes("\0") || value.includes("=")) {
|
|
2606
|
-
throw new TypeError(`${label} must not contain NUL or equals signs.`);
|
|
2607
|
-
}
|
|
2608
|
-
return value;
|
|
2609
|
-
}
|
|
2610
|
-
|
|
2611
|
-
// packages/safe-js/src/modules/fail.ts
|
|
2612
|
-
var HarnessFailure = class extends Error {
|
|
2613
|
-
constructor(message) {
|
|
2614
|
-
super(message);
|
|
2615
|
-
this.name = "HarnessFailure";
|
|
2616
|
-
}
|
|
2617
|
-
};
|
|
2618
|
-
function makeFailModule() {
|
|
2619
|
-
function fail(message) {
|
|
2620
|
-
throw new HarnessFailure(readNonEmptyString2(message, "Harness failure message"));
|
|
2621
|
-
}
|
|
2622
|
-
return {
|
|
2623
|
-
default: fail
|
|
2624
|
-
};
|
|
2625
|
-
}
|
|
2626
|
-
function readNonEmptyString2(value, label) {
|
|
2627
|
-
if (typeof value !== "string") {
|
|
2628
|
-
throw new Error(`${label} must be a non-empty string.`);
|
|
2629
|
-
}
|
|
2630
|
-
if (value.trim().length === 0) {
|
|
2631
|
-
throw new Error(`${label} must be a non-empty string.`);
|
|
2632
|
-
}
|
|
2633
|
-
return value;
|
|
2634
|
-
}
|
|
2635
|
-
|
|
2636
2527
|
// packages/safe-js/src/modules/fs-config.ts
|
|
2637
2528
|
import {
|
|
2638
2529
|
createFileSystem,
|
|
@@ -2701,7 +2592,7 @@ function makeLogModule(sink = createJsonlStdoutSink()) {
|
|
|
2701
2592
|
normalizedSink({
|
|
2702
2593
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2703
2594
|
type: "event",
|
|
2704
|
-
name:
|
|
2595
|
+
name: readNonEmptyString2(name, "Event name"),
|
|
2705
2596
|
payload
|
|
2706
2597
|
});
|
|
2707
2598
|
}
|
|
@@ -2724,7 +2615,7 @@ function createJsonlStdoutSink() {
|
|
|
2724
2615
|
stdoutSinks.set(stream, sink);
|
|
2725
2616
|
return sink;
|
|
2726
2617
|
}
|
|
2727
|
-
function
|
|
2618
|
+
function readNonEmptyString2(value, label) {
|
|
2728
2619
|
if (typeof value !== "string") {
|
|
2729
2620
|
throw new Error(`${label} must be a non-empty string.`);
|
|
2730
2621
|
}
|
|
@@ -2796,43 +2687,6 @@ function toJsonValue(value, seen) {
|
|
|
2796
2687
|
return String(value);
|
|
2797
2688
|
}
|
|
2798
2689
|
|
|
2799
|
-
// packages/safe-js/src/modules/metric.ts
|
|
2800
|
-
function makeMetricModule(npmRunner) {
|
|
2801
|
-
return {
|
|
2802
|
-
async run(name) {
|
|
2803
|
-
const metricName = readNonEmptyString4(name, "Metric name");
|
|
2804
|
-
const scriptName = `metric:${metricName}`;
|
|
2805
|
-
const stdout = await npmRunner(scriptName);
|
|
2806
|
-
const score = parseMetricScore(stdout, scriptName);
|
|
2807
|
-
return score;
|
|
2808
|
-
}
|
|
2809
|
-
};
|
|
2810
|
-
}
|
|
2811
|
-
function parseMetricScore(stdout, scriptName) {
|
|
2812
|
-
if (typeof stdout !== "string") {
|
|
2813
|
-
throw new Error(`Metric runner for "${scriptName}" must resolve to a stdout string.`);
|
|
2814
|
-
}
|
|
2815
|
-
const scoreLine = stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).at(-1);
|
|
2816
|
-
if (scoreLine === void 0) {
|
|
2817
|
-
throw new Error(`Metric script "${scriptName}" must print a numeric score.`);
|
|
2818
|
-
}
|
|
2819
|
-
const score = Number(scoreLine);
|
|
2820
|
-
if (!Number.isFinite(score)) {
|
|
2821
|
-
throw new Error(`Metric script "${scriptName}" must print a numeric score.`);
|
|
2822
|
-
}
|
|
2823
|
-
return score;
|
|
2824
|
-
}
|
|
2825
|
-
function readNonEmptyString4(value, label) {
|
|
2826
|
-
if (typeof value !== "string") {
|
|
2827
|
-
throw new Error(`${label} must be a non-empty string.`);
|
|
2828
|
-
}
|
|
2829
|
-
const normalizedValue = value.trim();
|
|
2830
|
-
if (normalizedValue.length === 0) {
|
|
2831
|
-
throw new Error(`${label} must be a non-empty string.`);
|
|
2832
|
-
}
|
|
2833
|
-
return normalizedValue;
|
|
2834
|
-
}
|
|
2835
|
-
|
|
2836
2690
|
export {
|
|
2837
2691
|
formatInterpreterError,
|
|
2838
2692
|
SPAWN_MODES,
|
|
@@ -2845,12 +2699,7 @@ export {
|
|
|
2845
2699
|
createSpawnUsageAccumulator,
|
|
2846
2700
|
runWithSpawnUsageAccumulator,
|
|
2847
2701
|
makeAgentModule,
|
|
2848
|
-
EnvAccessError,
|
|
2849
|
-
makeEnvModule,
|
|
2850
|
-
parseEnvConfig,
|
|
2851
|
-
makeFailModule,
|
|
2852
2702
|
parseFsConfig,
|
|
2853
2703
|
resolveFsConfig,
|
|
2854
|
-
makeLogModule
|
|
2855
|
-
makeMetricModule
|
|
2704
|
+
makeLogModule
|
|
2856
2705
|
};
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
hashParsedAst,
|
|
3
3
|
hashSource,
|
|
4
4
|
validateSnapshotMigration
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-PMOXSLM5.js";
|
|
6
6
|
import {
|
|
7
7
|
SnapshotValidationError,
|
|
8
8
|
assertSnapshotInactive,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
validateDumpEnvelope,
|
|
12
12
|
validateGuestHeapSource,
|
|
13
13
|
validateRuntimeSnapshotDescriptors
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-5RLD4TVI.js";
|
|
15
15
|
import {
|
|
16
16
|
SandboxError,
|
|
17
17
|
parseExecutableModule,
|