@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.
Files changed (44) hide show
  1. package/README.md +3 -1
  2. package/dist/safe-js/chunks/{chunk-ULPZIHB5.js → chunk-5RLD4TVI.js} +174 -127
  3. package/dist/safe-js/chunks/{chunk-TBZILU4U.js → chunk-7THYP46K.js} +1 -1
  4. package/dist/safe-js/chunks/{chunk-UU4T2KIT.js → chunk-CK3YK2EC.js} +1 -1
  5. package/dist/safe-js/chunks/{chunk-3O7HA6WT.js → chunk-F6Y734YA.js} +2 -2
  6. package/dist/safe-js/chunks/{chunk-OPYN6N5M.js → chunk-HPHCQNFV.js} +154 -1
  7. package/dist/safe-js/chunks/{chunk-W6C3Q6U4.js → chunk-LWHXSNF6.js} +2 -2
  8. package/dist/safe-js/chunks/{chunk-ZKLJW27N.js → chunk-PMOXSLM5.js} +1 -1
  9. package/dist/safe-js/chunks/{chunk-M6S3F3WM.js → chunk-QEDOBN2G.js} +4 -4
  10. package/dist/safe-js/chunks/chunk-QRWRR6IA.js +78 -0
  11. package/dist/safe-js/chunks/{chunk-MCFRB5X3.js → chunk-SHMRT4QX.js} +76 -6
  12. package/dist/safe-js/chunks/{chunk-KULEMOAE.js → chunk-XAV2RKLO.js} +3 -154
  13. package/dist/safe-js/chunks/{chunk-MDJ7MJYI.js → chunk-XOMGWE37.js} +2 -2
  14. package/dist/safe-js/chunks/{chunk-QTCPJ7FN.js → chunk-XV5OYKND.js} +1 -1
  15. package/dist/safe-js/chunks/{chunk-OTVZWRYE.js → chunk-YAHDXC7P.js} +1 -1
  16. package/dist/safe-js/chunks/{cli-runtime-DYXJZCGV.js → cli-runtime-OCWFX4TM.js} +15 -15
  17. package/dist/safe-js/chunks/{dump-XDJEF2LG.js → dump-KUPBSXSL.js} +2 -2
  18. package/dist/safe-js/chunks/{harness-32OOFC5A.js → harness-3DDUS3RY.js} +2 -2
  19. package/dist/safe-js/chunks/{mcp-PTCA53MN.js → mcp-4D3WWY7U.js} +3 -3
  20. package/dist/safe-js/chunks/{migration-file-EEGIOHQB.js → migration-file-4CYSJ6LO.js} +3 -3
  21. package/dist/safe-js/chunks/{restore-U3CCH36B.js → restore-GDHBT5ZD.js} +3 -3
  22. package/dist/safe-js/chunks/{run-Q74MU3QQ.js → run-3X6J7FPV.js} +5 -5
  23. package/dist/safe-js/chunks/{runtime-modules-SL5D6LAJ.js → runtime-modules-MGSXY4BN.js} +2 -2
  24. package/dist/safe-js/cli.js +2 -2
  25. package/dist/safe-js/core.d.ts +6 -0
  26. package/dist/safe-js/core.js +33 -7
  27. package/dist/safe-js/index.js +24 -93
  28. package/dist/safe-js/interp/data-copy.d.ts +3 -2
  29. package/dist/safe-js/interp/host-bridge.d.ts +5 -4
  30. package/dist/safe-js/modules/fs.js +2 -2
  31. package/dist/safe-js/node-unavailable.d.ts +1 -0
  32. package/dist/safe-js/portable/chunks/chunk-H5X3T5VP.js +909 -0
  33. package/dist/safe-js/portable/chunks/chunk-KYJVK33V.js +58698 -0
  34. package/dist/safe-js/portable/chunks/chunk-XCTU25SU.js +111 -0
  35. package/dist/safe-js/portable/chunks/source-files-CVU252FB.js +7 -0
  36. package/dist/safe-js/portable/core.js +14757 -0
  37. package/dist/safe-js/portable/modules/fs.js +9 -0
  38. package/dist/safe-js/snapshot/arguments.d.ts +2 -0
  39. package/dist/safe-js/snapshot/property-descriptors.d.ts +2 -0
  40. package/dist/safe-js/snapshot/regexp-properties.d.ts +2 -0
  41. package/dist/safe-js/snapshot/symbols.d.ts +2 -0
  42. package/dist/safe-js/workerd.d.ts +3 -0
  43. package/dist/safe-js/workerd.js +74425 -0
  44. package/package.json +30 -6
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isSandboxClosure
3
- } from "./chunk-ULPZIHB5.js";
3
+ } from "./chunk-5RLD4TVI.js";
4
4
 
5
5
  // packages/safe-js/src/lint/runtime-modules.ts
6
6
  var AsyncFunction = (async () => void 0).constructor;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  deepCopyToSandbox
3
- } from "./chunk-ULPZIHB5.js";
3
+ } from "./chunk-5RLD4TVI.js";
4
4
 
5
5
  // packages/safe-js/src/modules/harness.ts
6
6
  function makeHarnessModule(frontmatter, meta) {
@@ -10,7 +10,7 @@ import {
10
10
  validateMigrationReconciliation,
11
11
  validateMigrationSemantics,
12
12
  validateSnapshotMigration
13
- } from "./chunk-ZKLJW27N.js";
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-ULPZIHB5.js";
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-MCFRB5X3.js";
5
+ } from "./chunk-SHMRT4QX.js";
6
6
  import {
7
7
  declareHostOperation,
8
8
  runResources
9
- } from "./chunk-ULPZIHB5.js";
9
+ } from "./chunk-5RLD4TVI.js";
10
10
  import {
11
11
  hostErrorData
12
12
  } from "./chunk-A3LXCGMJ.js";
@@ -2,7 +2,7 @@ import {
2
2
  HostCallJournal,
3
3
  decodeReplayData,
4
4
  validateSnapshotData
5
- } from "./chunk-ULPZIHB5.js";
5
+ } from "./chunk-5RLD4TVI.js";
6
6
  import {
7
7
  CompileScope,
8
8
  SandboxError,
@@ -7,15 +7,15 @@ import {
7
7
  } from "./chunk-ONWFPHUI.js";
8
8
  import {
9
9
  restore
10
- } from "./chunk-MDJ7MJYI.js";
10
+ } from "./chunk-XOMGWE37.js";
11
11
  import {
12
12
  hashParsedAst,
13
13
  hashSource
14
- } from "./chunk-ZKLJW27N.js";
14
+ } from "./chunk-PMOXSLM5.js";
15
15
  import {
16
16
  attachDumpController,
17
17
  createDumpController
18
- } from "./chunk-QTCPJ7FN.js";
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-ULPZIHB5.js";
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
- loopbackTarget({ redirectUri: requestedRedirectUri });
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
- loopbackTarget(browser);
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 || normalizedScope.length === 0 ? {} : { scope: normalizedScope }
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: readNonEmptyString3(name, "Event 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 readNonEmptyString3(value, label) {
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-ZKLJW27N.js";
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-ULPZIHB5.js";
14
+ } from "./chunk-5RLD4TVI.js";
15
15
  import {
16
16
  SandboxError,
17
17
  parseExecutableModule,