@poe-platform/safe-js 0.1.89 → 0.1.90

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.
@@ -6997,26 +6997,8 @@ function getSandboxPrototype(value, budget) {
6997
6997
  if (prototypes.has(value)) return prototypes.get(value) ?? null;
6998
6998
  return budget !== void 0 && isPrototypeRecord(value) ? intrinsicPrototypes.get(budget) ?? null : null;
6999
6999
  }
7000
- function getSandboxDataProperty(value, key, budget) {
7001
- let current = value;
7002
- let depth = 0;
7003
- while (typeof current === "object" && current !== null) {
7004
- if (isGuestHostObject(current)) return getHostObjectMember(current, String(key));
7005
- if (isGuestClosure(current)) return getGuestFunctionProperty(current, String(key));
7006
- if (isSandboxClosure(current)) {
7007
- const properties = current.properties;
7008
- return properties !== void 0 && Object.hasOwn(properties, String(key)) ? properties[String(key)] : void 0;
7009
- }
7010
- if (isSandboxMap(current) || isSandboxSet(current) || isSandboxPromise(current) || isSandboxRegex(current) || isSandboxGenerator(current))
7011
- return void 0;
7012
- if (Object.hasOwn(current, String(key))) return current[String(key)];
7013
- current = getSandboxPrototype(current, budget);
7014
- if (current !== null) {
7015
- budget?.visitNode();
7016
- assertSandboxDataDepth(++depth);
7017
- }
7018
- }
7019
- return void 0;
7000
+ function hasExplicitSandboxPrototype(value) {
7001
+ return prototypes.has(value);
7020
7002
  }
7021
7003
  function setSandboxPrototype(value, prototype, budget) {
7022
7004
  if (budget !== void 0 && intrinsicPrototypes.get(budget) === value && prototype !== null) {
@@ -8178,609 +8160,930 @@ function isCounter(value) {
8178
8160
  // packages/safe-js/src/interp/cancel.ts
8179
8161
  import { AsyncLocalStorage as AsyncLocalStorage4 } from "node:async_hooks";
8180
8162
 
8181
- // packages/safe-js/src/interp/string-coercion.ts
8182
- function sandboxString(value, budget, context, joining = /* @__PURE__ */ new Set()) {
8183
- if (value === null || typeof value !== "object") {
8184
- if (typeof value === "function") throw new TypeError("Expected a sandbox value.");
8185
- return budget.allocateString(String(value));
8186
- }
8187
- return stringifyObject(value, budget, context, joining);
8163
+ // packages/safe-js/src/interp/regex/engine.ts
8164
+ function matchRegex(pattern, input, lastIndex = 0) {
8165
+ const startIndex = pattern.flags.global ? normalizeLastIndex(lastIndex) : 0;
8166
+ return matchRegexFrom(pattern, input, startIndex);
8188
8167
  }
8189
- async function stringifyObject(value, budget, context, joining) {
8190
- const leaveCall = budget.enterCall();
8191
- try {
8192
- budget.visitNode();
8193
- for (const name of ["toString", "valueOf"]) {
8194
- const descriptor = Object.getOwnPropertyDescriptor(value, name);
8195
- let result;
8196
- if (descriptor === void 0) {
8197
- if (name === "valueOf") continue;
8198
- result = await defaultToString(value, budget, context, joining);
8199
- } else {
8200
- const hook = ownDataValue(value, name);
8201
- if (!isSandboxClosure(hook)) continue;
8202
- if (context?.invokeClosure === void 0) {
8203
- throw new TypeError("String hooks require a sandbox call context.");
8204
- }
8205
- result = await context.invokeClosure(hook, [], value);
8206
- }
8207
- if (result === null || typeof result !== "object") {
8208
- return sandboxString(result, budget, context, joining);
8209
- }
8168
+ function matchRegexFrom(pattern, input, startIndex) {
8169
+ if (startIndex > input.length) {
8170
+ return null;
8171
+ }
8172
+ for (let attempt = startIndex; attempt <= input.length; attempt += 1) {
8173
+ const context = { input, flags: pattern.flags, steps: 0 };
8174
+ charge(context);
8175
+ const initialState = {
8176
+ position: attempt,
8177
+ captures: new Array(pattern.captureCount)
8178
+ };
8179
+ const result = matchNode(pattern.body, initialState, context).next();
8180
+ if (!result.done) {
8181
+ return toRegexMatch(input, attempt, result.value);
8210
8182
  }
8211
- throw new TypeError("Cannot convert object to primitive value");
8212
- } finally {
8213
- leaveCall();
8214
8183
  }
8184
+ return null;
8215
8185
  }
8216
- async function defaultToString(value, budget, context, joining) {
8217
- if (isSandboxDate(value)) return budget.allocateString(dateString(value));
8218
- if (Array.isArray(value) || isFloat32Array(value)) {
8219
- if (Object.hasOwn(value, "join")) {
8220
- const join = ownDataValue(value, "join");
8221
- if (!isSandboxClosure(join))
8222
- return isFloat32Array(value) ? "[object Float32Array]" : "[object Array]";
8223
- if (context?.invokeClosure === void 0) {
8224
- throw new TypeError("String hooks require a sandbox call context.");
8186
+ function* matchNode(node, state, context) {
8187
+ charge(context);
8188
+ switch (node.type) {
8189
+ case "empty":
8190
+ yield state;
8191
+ return;
8192
+ case "literal":
8193
+ if (charactersEqual(context.input[state.position], node.value, context.flags.ignoreCase)) {
8194
+ yield { ...state, position: state.position + 1 };
8225
8195
  }
8226
- return context.invokeClosure(join, [], value);
8196
+ return;
8197
+ case "dot":
8198
+ if (state.position < context.input.length && (context.flags.dotAll || !isLineTerminator(context.input[state.position]))) {
8199
+ yield { ...state, position: state.position + 1 };
8200
+ }
8201
+ return;
8202
+ case "anchor":
8203
+ if (matchesAnchor(node.kind, state.position, context)) {
8204
+ yield state;
8205
+ }
8206
+ return;
8207
+ case "wordBoundary": {
8208
+ const previousWord = state.position > 0 && isWordCharacter(context.input[state.position - 1]);
8209
+ const nextWord = state.position < context.input.length && isWordCharacter(context.input[state.position]);
8210
+ if (previousWord !== nextWord !== node.negated) {
8211
+ yield state;
8212
+ }
8213
+ return;
8227
8214
  }
8228
- if (joining.has(value)) return "";
8229
- joining.add(value);
8230
- try {
8231
- const length = isFloat32Array(value) ? float32Storage(value).length : value.length;
8232
- let text = "";
8233
- for (let index = 0; index < length; index++) {
8234
- budget.visitNode();
8235
- const element = ownDataValue(value, String(index));
8236
- const part = element === null || element === void 0 ? "" : await sandboxString(element, budget, context, joining);
8237
- text = budget.allocateString(text + (index === 0 ? "" : ",") + part);
8215
+ case "characterClass": {
8216
+ const character = context.input[state.position];
8217
+ if (character !== void 0 && matchesCharacterClass(character, node.items, node.negated, context.flags.ignoreCase)) {
8218
+ yield { ...state, position: state.position + 1 };
8238
8219
  }
8239
- return text;
8240
- } finally {
8241
- joining.delete(value);
8220
+ return;
8242
8221
  }
8222
+ case "sequence":
8223
+ yield* matchSequence(node.elements, 0, state, context);
8224
+ return;
8225
+ case "alternation":
8226
+ for (const alternative of node.alternatives) {
8227
+ yield* matchNode(alternative, cloneState(state), context);
8228
+ }
8229
+ return;
8230
+ case "group":
8231
+ for (const result of matchNode(node.body, cloneState(state), context)) {
8232
+ if (!node.capturing || node.index === void 0) {
8233
+ yield result;
8234
+ continue;
8235
+ }
8236
+ const captures = result.captures.slice();
8237
+ captures[node.index - 1] = { start: state.position, end: result.position };
8238
+ yield { position: result.position, captures };
8239
+ }
8240
+ return;
8241
+ case "quantifier":
8242
+ yield* matchQuantifier(node, state, context, 0);
8243
8243
  }
8244
- if (sandboxErrorTypes.has(value)) {
8245
- const nameValue = ownDataValue(value, "name");
8246
- const name = nameValue === void 0 ? "Error" : await sandboxString(nameValue, budget, context, joining);
8247
- const messageValue = ownDataValue(value, "message");
8248
- const message = messageValue === void 0 ? "" : await sandboxString(messageValue, budget, context, joining);
8249
- return name === "" ? message : message === "" ? name : `${name}: ${message}`;
8250
- }
8251
- return isSandboxPromise(value) ? "[object Promise]" : "[object Object]";
8252
8244
  }
8253
- function ownDataValue(value, name) {
8254
- const descriptor = Object.getOwnPropertyDescriptor(value, name);
8255
- if (descriptor !== void 0 && !Object.hasOwn(descriptor, "value")) {
8256
- throw new TypeError("String conversion requires sandbox data properties.");
8245
+ function* matchSequence(elements, index, state, context) {
8246
+ charge(context);
8247
+ if (index === elements.length) {
8248
+ yield state;
8249
+ return;
8250
+ }
8251
+ for (const result of matchNode(elements[index], state, context)) {
8252
+ yield* matchSequence(elements, index + 1, result, context);
8257
8253
  }
8258
- return descriptor?.value;
8259
8254
  }
8260
-
8261
- // packages/safe-js/src/interp/property-key.ts
8262
- async function toPropertyKey(value, budget, context) {
8263
- if (typeof value === "string") return value;
8264
- const invocation = context.invokeClosure === void 0 ? {
8265
- ...context,
8266
- invokeClosure: async (closure, args, thisValue) => {
8267
- const leaveCall = budget.enterCall();
8268
- try {
8269
- const result = closure.call(args, { ...invocation, thisValue });
8270
- if (isSandboxPromise(result)) {
8271
- await result.synchronousPrefix;
8272
- return result;
8255
+ function* matchQuantifier(node, state, context, count) {
8256
+ charge(context);
8257
+ const canRepeat = node.max === void 0 || count < node.max;
8258
+ if (!node.greedy && count >= node.min) {
8259
+ yield state;
8260
+ }
8261
+ if (canRepeat) {
8262
+ for (const result of matchNode(node.body, clearCaptures(node.body, state), context)) {
8263
+ if (result.position === state.position) {
8264
+ if (count >= node.min) {
8265
+ continue;
8273
8266
  }
8274
- return await result;
8275
- } finally {
8276
- leaveCall();
8277
- }
8278
- }
8279
- } : context;
8280
- if (typeof value === "object" && value !== null && !Array.isArray(value) && !isSandboxClosure(value) && !isSandboxMap(value) && !isSandboxSet(value) && !isSandboxPromise(value) && !isSandboxRegex(value) && !isSandboxDate(value) && !isFloat32Array(value) && !isSandboxGenerator(value) && !isGuestHostObject(value)) {
8281
- for (const name of ["toString", "valueOf"]) {
8282
- const method = getSandboxDataProperty(value, name, budget);
8283
- if (!isSandboxClosure(method)) continue;
8284
- const primitive = await invocation.invokeClosure(method, [], value);
8285
- if (primitive === null || typeof primitive !== "object") {
8286
- return budget.allocateString(String(primitive));
8267
+ if (count + 1 >= node.min) {
8268
+ yield result;
8269
+ } else {
8270
+ yield* matchQuantifier(node, result, context, count + 1);
8271
+ }
8272
+ continue;
8287
8273
  }
8274
+ yield* matchQuantifier(node, result, context, count + 1);
8288
8275
  }
8289
- throw new TypeError("Cannot convert object to primitive value.");
8290
8276
  }
8291
- return sandboxString(value, budget, invocation);
8292
- }
8293
-
8294
- // packages/safe-js/src/interp/exceptions.ts
8295
- var capturedExceptionBrand = /* @__PURE__ */ Symbol("CapturedException");
8296
- async function evaluateThrowStatement(node, context, evaluateNode2) {
8297
- const argument = await evaluateNode2(node.argument, context);
8298
- if (argument.kind !== "normal") {
8299
- return argument;
8277
+ if (node.greedy && count >= node.min) {
8278
+ yield state;
8300
8279
  }
8301
- return {
8302
- kind: "throw",
8303
- hasValue: true,
8304
- span: node.span,
8305
- stackFrames: context.callStack,
8306
- value: argument.value
8307
- };
8308
8280
  }
8309
- async function evaluateTryStatement(node, context, evaluateNode2) {
8310
- let fatalBudgetError;
8311
- let tryResult;
8312
- try {
8313
- tryResult = await evaluateBlockCompletion(node.block, context, evaluateNode2);
8314
- } catch (error) {
8315
- if (!isBudgetExceeded(error) || node.finalizer === void 0) {
8316
- throw error;
8317
- }
8318
- fatalBudgetError = error;
8319
- tryResult = {
8320
- kind: "throw",
8321
- hasValue: true,
8322
- value: void 0
8323
- };
8324
- }
8325
- const tryOrCatchResult = fatalBudgetError === void 0 && tryResult.kind === "throw" && node.handler !== void 0 ? await evaluateCatchClause(node.handler, tryResult.value, context, evaluateNode2) : tryResult;
8326
- if (node.finalizer === void 0 || tryOrCatchResult.kind === "error") {
8327
- return tryOrCatchResult;
8328
- }
8329
- const evaluateFinalizer = () => fatalBudgetError?.budget === "deadline" ? evaluateWithoutDeadlineChecks(
8330
- context,
8331
- () => evaluateBlockCompletion(node.finalizer, context, evaluateNode2)
8332
- ) : evaluateBlockCompletion(node.finalizer, context, evaluateNode2);
8333
- const finalizerResult = await (fatalBudgetError === void 0 ? evaluateFinalizer() : withFatalPromiseCleanup(evaluateFinalizer));
8334
- if (fatalBudgetError !== void 0) {
8335
- throw fatalBudgetError;
8336
- }
8337
- if (finalizerResult.kind === "normal") {
8338
- return tryOrCatchResult;
8281
+ function matchesAnchor(kind, position, context) {
8282
+ if (kind === "start") {
8283
+ return position === 0 || context.flags.multiline && position > 0 && isLineTerminator(context.input[position - 1]);
8339
8284
  }
8340
- return finalizerResult;
8341
- }
8342
- function createCapturedException(reason, stackFrames, sandbox = false) {
8343
- return {
8344
- reason,
8345
- sandbox,
8346
- stackFrames,
8347
- [capturedExceptionBrand]: true
8348
- };
8285
+ return position === context.input.length || context.flags.multiline && position < context.input.length && isLineTerminator(context.input[position]);
8349
8286
  }
8350
- function isCapturedException(value) {
8351
- return typeof value === "object" && value !== null && capturedExceptionBrand in value;
8287
+ function matchesCharacterClass(character, items, negated, ignoreCase) {
8288
+ const matched = items.some((item) => matchesCharacterClassItem(character, item, ignoreCase));
8289
+ return negated ? !matched : matched;
8352
8290
  }
8353
- function coerceThrownValue(reason, budget, stackFrames, span, sandbox = false) {
8354
- if (reason instanceof HostCallResumabilityError) {
8355
- throw reason;
8356
- }
8357
- if (isSubsetErrorValue(reason)) {
8358
- attachErrorSpan(reason, readErrorSpan(reason) ?? span);
8359
- return reason;
8360
- }
8361
- if (reason instanceof Error) {
8362
- return createSubsetErrorValue(reason.name || "Error", reason.message, stackFrames, budget, {
8363
- chargeBudget: false,
8364
- cause: readErrorCause(reason),
8365
- span
8366
- });
8367
- }
8368
- if (sandbox) {
8369
- return reason;
8291
+ function matchesCharacterClassItem(character, item, ignoreCase) {
8292
+ if (item.type === "character") {
8293
+ return charactersEqual(character, item.value, ignoreCase);
8370
8294
  }
8371
- if (isErrorLikeValue(reason)) {
8372
- return createSubsetErrorValue(reason.name || "Error", reason.message, stackFrames, budget, {
8373
- chargeBudget: false,
8374
- cause: readErrorCause(reason),
8375
- span
8376
- });
8295
+ if (item.type === "range") {
8296
+ const candidate = character.charCodeAt(0);
8297
+ const from = item.from.charCodeAt(0);
8298
+ const to = item.to.charCodeAt(0);
8299
+ if (candidate >= from && candidate <= to) {
8300
+ return true;
8301
+ }
8302
+ if (!ignoreCase) {
8303
+ return false;
8304
+ }
8305
+ const foldedCandidate = foldCharacter(character, true).charCodeAt(0);
8306
+ const foldedFrom = foldCharacter(item.from, true).charCodeAt(0);
8307
+ const foldedTo = foldCharacter(item.to, true).charCodeAt(0);
8308
+ return foldedCandidate >= foldedFrom && foldedCandidate <= foldedTo;
8377
8309
  }
8378
- return deepCopyToSandbox(reason);
8310
+ const matched = item.kind === "digit" ? isDigit(character) : item.kind === "word" ? isWordCharacter(character) : isSpaceCharacter(character);
8311
+ return item.negated ? !matched : matched;
8379
8312
  }
8380
- function surfaceThrownValue(reason, budget, stackFrames = [], span) {
8381
- if (reason instanceof HostCallResumabilityError) {
8382
- throw reason;
8313
+ function toRegexMatch(input, start, state) {
8314
+ return {
8315
+ index: start,
8316
+ text: input.slice(start, state.position),
8317
+ captures: state.captures.map(
8318
+ (capture) => capture === void 0 ? void 0 : input.slice(capture.start, capture.end)
8319
+ )
8320
+ };
8321
+ }
8322
+ function cloneState(state) {
8323
+ return { position: state.position, captures: state.captures.slice() };
8324
+ }
8325
+ function clearCaptures(node, state) {
8326
+ const captures = state.captures.slice();
8327
+ clearNodeCaptures(node, captures);
8328
+ return { position: state.position, captures };
8329
+ }
8330
+ function clearNodeCaptures(node, captures) {
8331
+ if (node.type === "group") {
8332
+ if (node.capturing && node.index !== void 0) {
8333
+ captures[node.index - 1] = void 0;
8334
+ }
8335
+ clearNodeCaptures(node.body, captures);
8336
+ return;
8383
8337
  }
8384
- if (isSubsetErrorValue(reason)) {
8385
- normalizeSurfacedSubsetError(reason, budget, stackFrames, span);
8386
- return reason;
8338
+ if (node.type === "sequence") {
8339
+ for (const element of node.elements) {
8340
+ clearNodeCaptures(element, captures);
8341
+ }
8342
+ return;
8387
8343
  }
8388
- if (reason instanceof Error) {
8389
- const error = createSubsetErrorValue(
8390
- reason.name || "Error",
8391
- reason.message,
8392
- stackFrames,
8393
- budget,
8394
- {
8395
- cause: reason,
8396
- chargeBudget: false,
8397
- span
8398
- }
8399
- );
8400
- normalizeSurfacedSubsetError(error, budget, stackFrames, span);
8401
- return error;
8344
+ if (node.type === "alternation") {
8345
+ for (const alternative of node.alternatives) {
8346
+ clearNodeCaptures(alternative, captures);
8347
+ }
8348
+ return;
8402
8349
  }
8403
- if (isErrorLikeValue(reason)) {
8404
- const error = createSubsetErrorValue(
8405
- reason.name || "Error",
8406
- reason.message,
8407
- stackFrames,
8408
- budget,
8409
- {
8410
- cause: readErrorCause(reason),
8411
- chargeBudget: false,
8412
- span
8413
- }
8414
- );
8415
- normalizeSurfacedSubsetError(error, budget, stackFrames, span);
8416
- return error;
8350
+ if (node.type === "quantifier") {
8351
+ clearNodeCaptures(node.body, captures);
8417
8352
  }
8418
- return createSubsetErrorValue("Error", describeThrownValue(reason), stackFrames, budget, {
8419
- chargeBudget: false,
8420
- span
8421
- });
8422
8353
  }
8423
- function createSubsetErrorValue(name, message, stackFrames, budget, options = {}) {
8424
- const resumeChecks = options.chargeBudget === false ? budget.suspendChecks() : void 0;
8425
- try {
8426
- const errorName = budget.allocateString(name === "" ? "Error" : name);
8427
- const errorMessage = budget.allocateString(coerceErrorMessage(message));
8428
- const header = errorMessage === "" ? errorName : `${errorName}: ${errorMessage}`;
8429
- const stack = budget.allocateString([header, ...[...stackFrames].reverse()].join("\n"));
8430
- const error = {
8431
- name: errorName,
8432
- message: errorMessage,
8433
- stack
8434
- };
8435
- sandboxErrorTypes.set(error, toSandboxErrorName(errorName));
8436
- attachErrorSpan(error, options.span);
8437
- attachWrappedErrorCause(error, options.cause);
8438
- return error;
8439
- } finally {
8440
- resumeChecks?.();
8441
- }
8354
+ function charge(context) {
8355
+ context.steps += 1;
8356
+ allocateRegexSteps(context.steps);
8442
8357
  }
8443
- function isSandboxErrorConstructorInstance(value, name) {
8444
- if (typeof value !== "object" || value === null) return false;
8445
- const errorType = sandboxErrorTypes.get(value);
8446
- return errorType !== void 0 && (name === "Error" || name === errorType);
8358
+ function normalizeLastIndex(lastIndex) {
8359
+ if (!Number.isFinite(lastIndex) || lastIndex <= 0) {
8360
+ return 0;
8361
+ }
8362
+ return Math.floor(lastIndex);
8447
8363
  }
8448
- function toSandboxErrorName(name) {
8449
- return sandboxErrorNames.includes(name) ? name : "Error";
8364
+ function charactersEqual(left, right, ignoreCase) {
8365
+ return left !== void 0 && foldCharacter(left, ignoreCase) === foldCharacter(right, ignoreCase);
8450
8366
  }
8451
- function isSubsetErrorValue(value) {
8452
- if (typeof value !== "object" || value === null) {
8453
- return false;
8367
+ function foldCharacter(character, ignoreCase) {
8368
+ if (!ignoreCase) {
8369
+ return character;
8454
8370
  }
8455
- const prototype = Object.getPrototypeOf(value);
8456
- return (prototype === Object.prototype || prototype === null) && typeof value.name === "string" && typeof value.message === "string" && typeof value.stack === "string";
8457
- }
8458
- function normalizeSurfacedSubsetError(error, budget, stackFrames, span) {
8459
- const resumeChecks = budget.suspendChecks();
8460
- try {
8461
- const name = budget.allocateString(toSandboxErrorName(readErrorName(error)));
8462
- const message = budget.allocateString(readSurfacedErrorMessage(error, name));
8463
- const frames = readSandboxStackFrames(error.stack);
8464
- error.name = name;
8465
- error.message = message;
8466
- error.stack = budget.allocateString(
8467
- formatErrorStack(name, message, frames.length > 0 ? frames : [...stackFrames].reverse())
8468
- );
8469
- attachErrorSpan(error, readErrorSpan(error) ?? span);
8470
- } finally {
8471
- resumeChecks();
8371
+ const folded = character.toUpperCase();
8372
+ if (folded.length !== 1) {
8373
+ return character;
8374
+ }
8375
+ if (character.charCodeAt(0) >= 128 && folded.charCodeAt(0) < 128) {
8376
+ return character;
8472
8377
  }
8378
+ return folded;
8473
8379
  }
8474
- function readErrorName(error) {
8475
- return typeof error.name === "string" && error.name.length > 0 ? error.name : "Error";
8380
+ function isDigit(character) {
8381
+ return character >= "0" && character <= "9";
8476
8382
  }
8477
- function readSurfacedErrorMessage(error, name) {
8478
- const message = typeof error.message === "string" ? error.message : "";
8479
- if (message === "") {
8480
- return `${name} thrown`;
8481
- }
8482
- if (message === "[object Object]") {
8483
- return `${name} thrown with non-string message`;
8484
- }
8485
- return message;
8383
+ function isWordCharacter(character) {
8384
+ return isDigit(character) || character >= "A" && character <= "Z" || character >= "a" && character <= "z" || character === "_";
8486
8385
  }
8487
- function readSandboxStackFrames(stack) {
8488
- if (typeof stack !== "string") {
8489
- return [];
8490
- }
8491
- const [, ...frames] = stack.split("\n");
8492
- return frames;
8386
+ function isSpaceCharacter(character) {
8387
+ return character === " " || character === "\f" || character === "\n" || character === "\r" || character === " " || character === "\v" || character === "\xA0" || character === "\u1680" || character >= "\u2000" && character <= "\u200A" || character === "\u2028" || character === "\u2029" || character === "\u202F" || character === "\u205F" || character === "\u3000" || character === "\uFEFF";
8493
8388
  }
8494
- function isErrorLikeValue(value) {
8495
- return typeof value === "object" && value !== null && typeof value.name === "string" && typeof value.message === "string";
8389
+ function isLineTerminator(character) {
8390
+ return character === "\n" || character === "\r" || character === "\u2028" || character === "\u2029";
8496
8391
  }
8497
- function coerceErrorMessage(message) {
8498
- if (message === void 0) {
8499
- return "";
8392
+
8393
+ // packages/safe-js/src/interp/methods/regex.ts
8394
+ var regexMethodNames = /* @__PURE__ */ new Set(["exec", "test"]);
8395
+ function isRegexMethodName(property) {
8396
+ return typeof property === "string" && regexMethodNames.has(property);
8397
+ }
8398
+ function getRegexMember(target, property, budget) {
8399
+ if (property === "source") return escapeRegexSource(target.source, budget);
8400
+ if (property === "flags") {
8401
+ const flags = [..."gims"].filter((flag) => target.flags.includes(flag)).join("");
8402
+ return budget === void 0 ? flags : budget.allocateString(flags);
8500
8403
  }
8501
- if (Array.isArray(message)) {
8502
- return message.map((value) => value === null || value === void 0 ? "" : String(value)).join(",");
8404
+ if (property === "lastIndex") return target.lastIndex;
8405
+ if (!isRegexMethodName(property)) {
8406
+ return void 0;
8503
8407
  }
8504
- if (typeof message === "object" && message !== null) {
8505
- return "[object Object]";
8408
+ return createSandboxClosure({
8409
+ sandbox: true,
8410
+ name: `RegExp#${property}`,
8411
+ call: (args) => callRegexMethod(target, property, args)
8412
+ });
8413
+ }
8414
+ function escapeRegexSource(source, budget) {
8415
+ let text = "";
8416
+ let escaped = false;
8417
+ let inClass = false;
8418
+ for (const character of source) {
8419
+ budget?.visitNode();
8420
+ if (character === "\n" || character === "\r" || character === "\u2028" || character === "\u2029") {
8421
+ if (escaped) text = text.slice(0, -1);
8422
+ text += character === "\n" ? "\\n" : character === "\r" ? "\\r" : character === "\u2028" ? "\\u2028" : "\\u2029";
8423
+ escaped = false;
8424
+ } else {
8425
+ if (!escaped && character === "[") inClass = true;
8426
+ if (!escaped && character === "]") inClass = false;
8427
+ text += character === "/" && !escaped && !inClass ? "\\/" : character;
8428
+ escaped = character === "\\" && !escaped;
8429
+ }
8430
+ budget?.allocateString(text);
8506
8431
  }
8507
- return String(message);
8432
+ text = text === "" ? "(?:)" : text;
8433
+ return budget === void 0 ? text : budget.allocateString(text);
8508
8434
  }
8509
- async function evaluateWithoutDeadlineChecks(context, evaluate) {
8510
- const resumeDeadlineChecks = context.budget.suspendDeadlineChecks();
8511
- try {
8512
- return await evaluate();
8513
- } finally {
8514
- resumeDeadlineChecks();
8435
+ function setRegexMember(target, property, value) {
8436
+ if (property !== "lastIndex") {
8437
+ throw new TypeError(`RegExp#${String(property)} is not writable.`);
8515
8438
  }
8439
+ target.lastIndex = Number(value);
8516
8440
  }
8517
- function isBudgetExceeded(error) {
8518
- return error instanceof SandboxError && error.code === "budgetExceeded";
8441
+ function callRegexMethod(target, methodName, args) {
8442
+ const match = executeRegex(target, String(args[0]));
8443
+ return methodName === "test" ? match !== null : toMatchArray(match, String(args[0]));
8519
8444
  }
8520
- async function evaluateCatchClause(node, thrownValue, context, evaluateNode2) {
8521
- const scope = context.scope.child();
8522
- const catchContext = {
8523
- ...context,
8524
- scope
8525
- };
8526
- if (node.param !== void 0) {
8527
- const binding = await bindPattern(node.param, thrownValue, catchContext, evaluateNode2);
8528
- if (!binding.ok) {
8529
- return binding.result;
8530
- }
8445
+ function executeRegex(target, input) {
8446
+ const pattern = getSandboxRegexPattern(target);
8447
+ const match = matchRegex(pattern, input, target.lastIndex);
8448
+ if (pattern.flags.global) {
8449
+ target.lastIndex = match === null ? 0 : match.index + match.text.length;
8531
8450
  }
8532
- return evaluateBlockCompletion(node.body, catchContext, evaluateNode2);
8451
+ return match;
8533
8452
  }
8534
- async function evaluateBlockCompletion(node, context, evaluateNode2) {
8535
- const blockContext = {
8536
- ...context,
8537
- scope: context.scope.child()
8538
- };
8539
- predeclareBlockBindings(node, blockContext.scope);
8540
- let result = {
8541
- kind: "normal",
8542
- hasValue: false,
8543
- value: void 0
8544
- };
8545
- for (const statement of node.body) {
8546
- result = await evaluateNode2(statement, blockContext);
8547
- if (result.kind !== "normal") {
8548
- return result;
8549
- }
8453
+ function toMatchArray(match, input) {
8454
+ if (match === null) {
8455
+ return null;
8550
8456
  }
8457
+ const result = [match.text, ...match.captures];
8458
+ Object.assign(result, { index: match.index, input, groups: void 0 });
8551
8459
  return result;
8552
8460
  }
8553
- function predeclareBlockBindings(node, scope) {
8554
- const names = /* @__PURE__ */ new Set();
8555
- for (const statement of node.body) {
8556
- if (statement.type !== "VariableDeclaration" || statement.kind === "var") {
8557
- continue;
8558
- }
8559
- for (const name of getDeclarationBindingNames(statement)) {
8560
- if (names.has(name) || scope.hasOwnBinding(name)) {
8561
- throw new Error(`Cannot redeclare binding '${name}' in the same scope.`);
8461
+
8462
+ // packages/safe-js/src/interp/string-coercion.ts
8463
+ var defaultStringHook = /* @__PURE__ */ Symbol("defaultStringHook");
8464
+ function sandboxString(value, budget, context, joining = /* @__PURE__ */ new Set()) {
8465
+ if (value === null || typeof value !== "object") {
8466
+ if (typeof value === "function") throw new TypeError("Expected a sandbox value.");
8467
+ return budget.allocateString(String(value));
8468
+ }
8469
+ const invocation = context?.invokeClosure !== void 0 ? context : {
8470
+ ...context,
8471
+ stack: context?.stack ?? [],
8472
+ thisValue: context?.thisValue,
8473
+ invokeClosure: async (closure, args, thisValue) => {
8474
+ const leaveCall = budget.enterCall();
8475
+ try {
8476
+ const result = closure.call(args, { ...invocation, thisValue });
8477
+ if (isSandboxPromise(result)) {
8478
+ await result.synchronousPrefix;
8479
+ return result;
8480
+ }
8481
+ return await result;
8482
+ } finally {
8483
+ leaveCall();
8562
8484
  }
8563
- names.add(name);
8564
- scope.predeclare(name, statement.kind);
8565
8485
  }
8566
- }
8567
- }
8568
- function getDeclarationBindingNames(node) {
8569
- return node.declarations.flatMap((declarator) => getPatternBindingNames(declarator.id));
8570
- }
8571
- function getPatternBindingNames(pattern) {
8572
- switch (pattern.type) {
8573
- case "Identifier":
8574
- return [pattern.name];
8575
- case "MemberExpression":
8576
- return [];
8577
- case "AssignmentPattern":
8578
- return getPatternBindingNames(pattern.left);
8579
- case "ArrayPattern":
8580
- return pattern.elements.flatMap(
8581
- (element) => element === null ? [] : getPatternBindingNames(element)
8582
- );
8583
- case "ObjectPattern":
8584
- return pattern.properties.flatMap(
8585
- (property) => property.type === "RestElement" ? getPatternBindingNames(property) : getPatternBindingNames(property.value)
8586
- );
8587
- case "RestElement":
8588
- return getPatternBindingNames(pattern.argument);
8589
- }
8590
- }
8591
- async function bindPattern(pattern, value, context, evaluateNode2) {
8592
- switch (pattern.type) {
8593
- case "Identifier":
8594
- context.scope.declare(pattern.name, "let", value);
8595
- return { ok: true };
8596
- case "MemberExpression":
8597
- throw new TypeError("Catch bindings do not support member expressions.");
8598
- case "AssignmentPattern":
8599
- return bindAssignmentPattern(pattern, value, context, evaluateNode2);
8600
- case "ArrayPattern":
8601
- return bindArrayPattern(pattern, value, context, evaluateNode2);
8602
- case "ObjectPattern":
8603
- return bindObjectPattern(pattern, value, context, evaluateNode2);
8604
- case "RestElement":
8605
- return bindPattern(pattern.argument, value, context, evaluateNode2);
8606
- }
8486
+ };
8487
+ return stringifyObject(value, budget, invocation, joining);
8607
8488
  }
8608
- async function bindAssignmentPattern(pattern, value, context, evaluateNode2) {
8609
- let nextValue = value;
8610
- if (nextValue === void 0) {
8611
- const defaultValue = await evaluateNode2(pattern.right, context);
8612
- if (defaultValue.kind !== "normal") {
8613
- return {
8614
- ok: false,
8615
- result: defaultValue
8616
- };
8489
+ async function stringifyObject(value, budget, context, joining) {
8490
+ const leaveCall = budget.enterCall();
8491
+ try {
8492
+ budget.visitNode();
8493
+ for (const name of ["toString", "valueOf"]) {
8494
+ const hook = conversionHook(value, name, budget);
8495
+ let result;
8496
+ if (hook === defaultStringHook) {
8497
+ result = await defaultToString(value, budget, context, joining);
8498
+ } else {
8499
+ if (!isSandboxClosure(hook)) continue;
8500
+ if (context?.invokeClosure === void 0) {
8501
+ throw new TypeError("String hooks require a sandbox call context.");
8502
+ }
8503
+ result = await context.invokeClosure(hook, [], value);
8504
+ }
8505
+ if (result === null || typeof result !== "object") {
8506
+ return sandboxString(result, budget, context, joining);
8507
+ }
8617
8508
  }
8618
- nextValue = defaultValue.value;
8509
+ throw new TypeError("Cannot convert object to primitive value");
8510
+ } finally {
8511
+ leaveCall();
8619
8512
  }
8620
- return bindPattern(pattern.left, nextValue, context, evaluateNode2);
8621
8513
  }
8622
- async function bindArrayPattern(pattern, value, context, evaluateNode2) {
8623
- if (!Array.isArray(value)) {
8624
- throw new TypeError("Array catch bindings require an array value.");
8625
- }
8626
- for (let index = 0; index < pattern.elements.length; index += 1) {
8627
- const element = pattern.elements[index];
8628
- if (element === null) {
8629
- continue;
8630
- }
8631
- const elementValue = element.type === "RestElement" ? value.slice(index) : value[index];
8632
- const binding = await bindPattern(element, elementValue, context, evaluateNode2);
8633
- if (!binding.ok) {
8634
- return binding;
8514
+ function conversionHook(value, name, budget) {
8515
+ const implicitBuiltin = !hasExplicitSandboxPrototype(value) && (Array.isArray(value) || isSandboxDate(value) || isFloat32Array(value) || sandboxErrorTypes.has(value) || isSandboxClosure(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxRegex(value) || isSandboxGenerator(value) || isGuestHostObject(value));
8516
+ let current = value;
8517
+ let depth = 0;
8518
+ while (current !== null) {
8519
+ const properties = isGuestClosure(current) ? getGuestFunctionProperties(current) : current;
8520
+ const descriptor = properties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(properties, name);
8521
+ if (descriptor !== void 0) {
8522
+ if (!Object.hasOwn(descriptor, "value"))
8523
+ throw new TypeError("String conversion requires sandbox data properties.");
8524
+ return descriptor.value;
8525
+ }
8526
+ const parent = getSandboxPrototype(current, budget);
8527
+ if (current === value && (implicitBuiltin || parent === null && !hasExplicitSandboxPrototype(value))) {
8528
+ return name === "toString" ? defaultStringHook : void 0;
8529
+ }
8530
+ current = parent;
8531
+ if (current !== null) {
8532
+ budget.visitNode();
8533
+ assertSandboxDataDepth(++depth);
8635
8534
  }
8636
8535
  }
8637
- return { ok: true };
8536
+ return void 0;
8638
8537
  }
8639
- async function bindObjectPattern(pattern, value, context, evaluateNode2) {
8640
- if (typeof value !== "object" && !Array.isArray(value) || value === null) {
8641
- throw new TypeError("Object catch bindings require a non-null object value.");
8538
+ async function defaultToString(value, budget, context, joining) {
8539
+ if (isSandboxMap(value)) return "[object Map]";
8540
+ if (isSandboxSet(value)) return "[object Set]";
8541
+ if (isSandboxGenerator(value)) return "[object Generator]";
8542
+ if (isSandboxRegex(value)) {
8543
+ return budget.allocateString(
8544
+ `/${getRegexMember(value, "source", budget)}/${getRegexMember(value, "flags", budget)}`
8545
+ );
8642
8546
  }
8643
- const excludedKeys = /* @__PURE__ */ new Set();
8644
- for (const property of pattern.properties) {
8645
- if (property.type === "RestElement") {
8646
- const restValue = copyObjectRest(value, excludedKeys);
8647
- const binding2 = await bindPattern(property, restValue, context, evaluateNode2);
8648
- if (!binding2.ok) {
8649
- return binding2;
8547
+ if (isSandboxDate(value)) return budget.allocateString(dateString(value));
8548
+ if (Array.isArray(value) || isFloat32Array(value)) {
8549
+ if (Object.hasOwn(value, "join")) {
8550
+ const join = ownDataValue(value, "join");
8551
+ if (!isSandboxClosure(join))
8552
+ return isFloat32Array(value) ? "[object Float32Array]" : "[object Array]";
8553
+ if (context?.invokeClosure === void 0) {
8554
+ throw new TypeError("String hooks require a sandbox call context.");
8650
8555
  }
8651
- continue;
8652
- }
8653
- const key = await resolvePatternPropertyKey(property, context, evaluateNode2);
8654
- if (!key.ok) {
8655
- return key;
8556
+ return context.invokeClosure(join, [], value);
8656
8557
  }
8657
- excludedKeys.add(String(key.value));
8658
- const binding = await bindPattern(
8659
- property.value,
8660
- getObjectPatternValue(value, key.value),
8661
- context,
8662
- evaluateNode2
8663
- );
8664
- if (!binding.ok) {
8665
- return binding;
8558
+ if (joining.has(value)) return "";
8559
+ joining.add(value);
8560
+ try {
8561
+ const length = isFloat32Array(value) ? float32Storage(value).length : value.length;
8562
+ let text = "";
8563
+ for (let index = 0; index < length; index++) {
8564
+ budget.visitNode();
8565
+ const element = ownDataValue(value, String(index));
8566
+ const part = element === null || element === void 0 ? "" : await sandboxString(element, budget, context, joining);
8567
+ text = budget.allocateString(text + (index === 0 ? "" : ",") + part);
8568
+ }
8569
+ return text;
8570
+ } finally {
8571
+ joining.delete(value);
8666
8572
  }
8667
8573
  }
8668
- return { ok: true };
8574
+ if (sandboxErrorTypes.has(value)) {
8575
+ const nameValue = ownDataValue(value, "name");
8576
+ const name = nameValue === void 0 ? "Error" : await sandboxString(nameValue, budget, context, joining);
8577
+ const messageValue = ownDataValue(value, "message");
8578
+ const message = messageValue === void 0 ? "" : await sandboxString(messageValue, budget, context, joining);
8579
+ return name === "" ? message : message === "" ? name : `${name}: ${message}`;
8580
+ }
8581
+ return isSandboxPromise(value) ? "[object Promise]" : "[object Object]";
8669
8582
  }
8670
- async function resolvePatternPropertyKey(property, context, evaluateNode2) {
8671
- if (!property.computed) {
8672
- return {
8673
- ok: true,
8674
- value: getStaticPropertyKey(property.key)
8675
- };
8583
+ function ownDataValue(value, name) {
8584
+ const descriptor = Object.getOwnPropertyDescriptor(value, name);
8585
+ if (descriptor !== void 0 && !Object.hasOwn(descriptor, "value")) {
8586
+ throw new TypeError("String conversion requires sandbox data properties.");
8676
8587
  }
8677
- const computedKey = await evaluateNode2(property.key, context);
8678
- if (computedKey.kind !== "normal") {
8679
- return {
8680
- ok: false,
8681
- result: computedKey
8682
- };
8588
+ return descriptor?.value;
8589
+ }
8590
+
8591
+ // packages/safe-js/src/interp/property-key.ts
8592
+ async function toPropertyKey(value, budget, context) {
8593
+ if (typeof value === "string") return value;
8594
+ return sandboxString(value, budget, context);
8595
+ }
8596
+
8597
+ // packages/safe-js/src/interp/exceptions.ts
8598
+ var capturedExceptionBrand = /* @__PURE__ */ Symbol("CapturedException");
8599
+ async function evaluateThrowStatement(node, context, evaluateNode2) {
8600
+ const argument = await evaluateNode2(node.argument, context);
8601
+ if (argument.kind !== "normal") {
8602
+ return argument;
8683
8603
  }
8684
8604
  return {
8685
- ok: true,
8686
- value: await (context.toPropertyKey?.(computedKey.value) ?? toPropertyKey(
8687
- computedKey.value,
8688
- context.budget,
8689
- { stack: context.callStack, thisValue: void 0 }
8690
- ))
8605
+ kind: "throw",
8606
+ hasValue: true,
8607
+ span: node.span,
8608
+ stackFrames: context.callStack,
8609
+ value: argument.value
8691
8610
  };
8692
8611
  }
8693
- function getStaticPropertyKey(property) {
8694
- switch (property.type) {
8695
- case "Identifier":
8696
- return property.name;
8697
- case "StringLiteral":
8698
- case "NumericLiteral":
8699
- return property.value;
8700
- default:
8701
- throw new TypeError(`Unsupported catch binding property key '${property.type}'.`);
8612
+ async function evaluateTryStatement(node, context, evaluateNode2) {
8613
+ let fatalBudgetError;
8614
+ let tryResult;
8615
+ try {
8616
+ tryResult = await evaluateBlockCompletion(node.block, context, evaluateNode2);
8617
+ } catch (error) {
8618
+ if (!isBudgetExceeded(error) || node.finalizer === void 0) {
8619
+ throw error;
8620
+ }
8621
+ fatalBudgetError = error;
8622
+ tryResult = {
8623
+ kind: "throw",
8624
+ hasValue: true,
8625
+ value: void 0
8626
+ };
8627
+ }
8628
+ const tryOrCatchResult = fatalBudgetError === void 0 && tryResult.kind === "throw" && node.handler !== void 0 ? await evaluateCatchClause(node.handler, tryResult.value, context, evaluateNode2) : tryResult;
8629
+ if (node.finalizer === void 0 || tryOrCatchResult.kind === "error") {
8630
+ return tryOrCatchResult;
8631
+ }
8632
+ const evaluateFinalizer = () => fatalBudgetError?.budget === "deadline" ? evaluateWithoutDeadlineChecks(
8633
+ context,
8634
+ () => evaluateBlockCompletion(node.finalizer, context, evaluateNode2)
8635
+ ) : evaluateBlockCompletion(node.finalizer, context, evaluateNode2);
8636
+ const finalizerResult = await (fatalBudgetError === void 0 ? evaluateFinalizer() : withFatalPromiseCleanup(evaluateFinalizer));
8637
+ if (fatalBudgetError !== void 0) {
8638
+ throw fatalBudgetError;
8639
+ }
8640
+ if (finalizerResult.kind === "normal") {
8641
+ return tryOrCatchResult;
8702
8642
  }
8643
+ return finalizerResult;
8703
8644
  }
8704
- function getObjectPatternValue(value, key) {
8705
- return value[key];
8645
+ function createCapturedException(reason, stackFrames, sandbox = false) {
8646
+ return {
8647
+ reason,
8648
+ sandbox,
8649
+ stackFrames,
8650
+ [capturedExceptionBrand]: true
8651
+ };
8706
8652
  }
8707
- function copyObjectRest(value, excludedKeys) {
8708
- const rest = /* @__PURE__ */ Object.create(null);
8709
- for (const [key, entryValue] of Object.entries(value)) {
8710
- if (excludedKeys.has(key)) {
8711
- continue;
8712
- }
8713
- rest[key] = entryValue;
8653
+ function isCapturedException(value) {
8654
+ return typeof value === "object" && value !== null && capturedExceptionBrand in value;
8655
+ }
8656
+ function coerceThrownValue(reason, budget, stackFrames, span, sandbox = false) {
8657
+ if (reason instanceof HostCallResumabilityError) {
8658
+ throw reason;
8714
8659
  }
8715
- return rest;
8660
+ if (isSubsetErrorValue(reason)) {
8661
+ attachErrorSpan(reason, readErrorSpan(reason) ?? span);
8662
+ return reason;
8663
+ }
8664
+ if (reason instanceof Error) {
8665
+ return createSubsetErrorValue(reason.name || "Error", reason.message, stackFrames, budget, {
8666
+ chargeBudget: false,
8667
+ cause: readErrorCause(reason),
8668
+ span
8669
+ });
8670
+ }
8671
+ if (sandbox) {
8672
+ return reason;
8673
+ }
8674
+ if (isErrorLikeValue(reason)) {
8675
+ return createSubsetErrorValue(reason.name || "Error", reason.message, stackFrames, budget, {
8676
+ chargeBudget: false,
8677
+ cause: readErrorCause(reason),
8678
+ span
8679
+ });
8680
+ }
8681
+ return deepCopyToSandbox(reason);
8716
8682
  }
8717
-
8718
- // packages/safe-js/src/interp/running-state.ts
8719
- var runningObjects = /* @__PURE__ */ new WeakSet();
8720
- var lockedCollections = /* @__PURE__ */ new WeakSet();
8721
- var activeSnapshots = /* @__PURE__ */ new WeakSet();
8722
- function enterRunningState(object) {
8723
- if (runningObjects.has(object)) {
8724
- throw new SandboxError("reentry");
8683
+ function surfaceThrownValue(reason, budget, stackFrames = [], span) {
8684
+ if (reason instanceof HostCallResumabilityError) {
8685
+ throw reason;
8725
8686
  }
8726
- runningObjects.add(object);
8727
- let active = true;
8728
- return () => {
8729
- if (!active) return;
8730
- active = false;
8731
- runningObjects.delete(object);
8732
- };
8687
+ if (isSubsetErrorValue(reason)) {
8688
+ normalizeSurfacedSubsetError(reason, budget, stackFrames, span);
8689
+ return reason;
8690
+ }
8691
+ if (reason instanceof Error) {
8692
+ const error = createSubsetErrorValue(
8693
+ reason.name || "Error",
8694
+ reason.message,
8695
+ stackFrames,
8696
+ budget,
8697
+ {
8698
+ cause: reason,
8699
+ chargeBudget: false,
8700
+ span
8701
+ }
8702
+ );
8703
+ normalizeSurfacedSubsetError(error, budget, stackFrames, span);
8704
+ return error;
8705
+ }
8706
+ if (isErrorLikeValue(reason)) {
8707
+ const error = createSubsetErrorValue(
8708
+ reason.name || "Error",
8709
+ reason.message,
8710
+ stackFrames,
8711
+ budget,
8712
+ {
8713
+ cause: readErrorCause(reason),
8714
+ chargeBudget: false,
8715
+ span
8716
+ }
8717
+ );
8718
+ normalizeSurfacedSubsetError(error, budget, stackFrames, span);
8719
+ return error;
8720
+ }
8721
+ return createSubsetErrorValue("Error", describeThrownValue(reason), stackFrames, budget, {
8722
+ chargeBudget: false,
8723
+ span
8724
+ });
8733
8725
  }
8734
- function assertCollectionMutable(object) {
8735
- if (lockedCollections.has(object)) {
8736
- throw new SandboxError("reentry");
8726
+ function createSubsetErrorValue(name, message, stackFrames, budget, options = {}) {
8727
+ const resumeChecks = options.chargeBudget === false ? budget.suspendChecks() : void 0;
8728
+ try {
8729
+ const errorName = budget.allocateString(name === "" ? "Error" : name);
8730
+ const errorMessage = budget.allocateString(coerceErrorMessage(message));
8731
+ const header = errorMessage === "" ? errorName : `${errorName}: ${errorMessage}`;
8732
+ const stack = budget.allocateString([header, ...[...stackFrames].reverse()].join("\n"));
8733
+ const error = {
8734
+ name: errorName,
8735
+ message: errorMessage,
8736
+ stack
8737
+ };
8738
+ sandboxErrorTypes.set(error, toSandboxErrorName(errorName));
8739
+ attachErrorSpan(error, options.span);
8740
+ attachWrappedErrorCause(error, options.cause);
8741
+ return error;
8742
+ } finally {
8743
+ resumeChecks?.();
8737
8744
  }
8738
8745
  }
8739
- function enterSnapshotRun(snapshot) {
8740
- if (activeSnapshots.has(snapshot)) {
8741
- throw new SandboxError("reentry");
8746
+ function isSandboxErrorConstructorInstance(value, name) {
8747
+ if (typeof value !== "object" || value === null) return false;
8748
+ const errorType = sandboxErrorTypes.get(value);
8749
+ return errorType !== void 0 && (name === "Error" || name === errorType);
8750
+ }
8751
+ function toSandboxErrorName(name) {
8752
+ return sandboxErrorNames.includes(name) ? name : "Error";
8753
+ }
8754
+ function isSubsetErrorValue(value) {
8755
+ if (typeof value !== "object" || value === null) {
8756
+ return false;
8742
8757
  }
8743
- activeSnapshots.add(snapshot);
8744
- return () => activeSnapshots.delete(snapshot);
8758
+ const prototype = Object.getPrototypeOf(value);
8759
+ return (prototype === Object.prototype || prototype === null) && typeof value.name === "string" && typeof value.message === "string" && typeof value.stack === "string";
8745
8760
  }
8746
- function assertSnapshotInactive(snapshot) {
8747
- if (activeSnapshots.has(snapshot)) {
8748
- throw new SandboxError("reentry");
8761
+ function normalizeSurfacedSubsetError(error, budget, stackFrames, span) {
8762
+ const resumeChecks = budget.suspendChecks();
8763
+ try {
8764
+ const name = budget.allocateString(toSandboxErrorName(readErrorName(error)));
8765
+ const message = budget.allocateString(readSurfacedErrorMessage(error, name));
8766
+ const frames = readSandboxStackFrames(error.stack);
8767
+ error.name = name;
8768
+ error.message = message;
8769
+ error.stack = budget.allocateString(
8770
+ formatErrorStack(name, message, frames.length > 0 ? frames : [...stackFrames].reverse())
8771
+ );
8772
+ attachErrorSpan(error, readErrorSpan(error) ?? span);
8773
+ } finally {
8774
+ resumeChecks();
8749
8775
  }
8750
8776
  }
8751
-
8752
- // packages/safe-js/src/interp/iteration.ts
8753
- function getSandboxIterator(value) {
8754
- if (isGuestHostObject(value)) return getHostObjectIterator(value);
8755
- if (isFloat32Array(value)) {
8756
- return syncIterator(Float32Array.prototype.values.call(value));
8777
+ function readErrorName(error) {
8778
+ return typeof error.name === "string" && error.name.length > 0 ? error.name : "Error";
8779
+ }
8780
+ function readSurfacedErrorMessage(error, name) {
8781
+ const message = typeof error.message === "string" ? error.message : "";
8782
+ if (message === "") {
8783
+ return `${name} thrown`;
8757
8784
  }
8758
- if (isSandboxGenerator(value)) {
8759
- return generatorIterator(value);
8785
+ if (message === "[object Object]") {
8786
+ return `${name} thrown with non-string message`;
8760
8787
  }
8761
- if (typeof value === "string") {
8762
- return syncIterator(value[Symbol.iterator]());
8788
+ return message;
8789
+ }
8790
+ function readSandboxStackFrames(stack) {
8791
+ if (typeof stack !== "string") {
8792
+ return [];
8763
8793
  }
8764
- if (isSandboxMap(value)) {
8765
- return collectionIterator(value.entries);
8794
+ const [, ...frames] = stack.split("\n");
8795
+ return frames;
8796
+ }
8797
+ function isErrorLikeValue(value) {
8798
+ return typeof value === "object" && value !== null && typeof value.name === "string" && typeof value.message === "string";
8799
+ }
8800
+ function coerceErrorMessage(message) {
8801
+ if (message === void 0) {
8802
+ return "";
8766
8803
  }
8767
- if (isSandboxSet(value)) {
8768
- return collectionIterator(value.values);
8804
+ if (Array.isArray(message)) {
8805
+ return message.map((value) => value === null || value === void 0 ? "" : String(value)).join(",");
8769
8806
  }
8770
- if (typeof value !== "object" && typeof value !== "function" || value === null) {
8771
- return void 0;
8807
+ if (typeof message === "object" && message !== null) {
8808
+ return "[object Object]";
8772
8809
  }
8773
- const iteratorMethod = value[Symbol.iterator];
8774
- if (typeof iteratorMethod !== "function") {
8775
- return void 0;
8810
+ return String(message);
8811
+ }
8812
+ async function evaluateWithoutDeadlineChecks(context, evaluate) {
8813
+ const resumeDeadlineChecks = context.budget.suspendDeadlineChecks();
8814
+ try {
8815
+ return await evaluate();
8816
+ } finally {
8817
+ resumeDeadlineChecks();
8776
8818
  }
8777
- return syncIterator(Reflect.apply(iteratorMethod, value, []));
8778
8819
  }
8779
- function collectionIterator(collection) {
8780
- let iterator = collection[Symbol.iterator]();
8781
- let exhausted = false;
8782
- return {
8783
- ...syncIterator({
8820
+ function isBudgetExceeded(error) {
8821
+ return error instanceof SandboxError && error.code === "budgetExceeded";
8822
+ }
8823
+ async function evaluateCatchClause(node, thrownValue, context, evaluateNode2) {
8824
+ const scope = context.scope.child();
8825
+ const catchContext = {
8826
+ ...context,
8827
+ scope
8828
+ };
8829
+ if (node.param !== void 0) {
8830
+ const binding = await bindPattern(node.param, thrownValue, catchContext, evaluateNode2);
8831
+ if (!binding.ok) {
8832
+ return binding.result;
8833
+ }
8834
+ }
8835
+ return evaluateBlockCompletion(node.body, catchContext, evaluateNode2);
8836
+ }
8837
+ async function evaluateBlockCompletion(node, context, evaluateNode2) {
8838
+ const blockContext = {
8839
+ ...context,
8840
+ scope: context.scope.child()
8841
+ };
8842
+ predeclareBlockBindings(node, blockContext.scope);
8843
+ let result = {
8844
+ kind: "normal",
8845
+ hasValue: false,
8846
+ value: void 0
8847
+ };
8848
+ for (const statement of node.body) {
8849
+ result = await evaluateNode2(statement, blockContext);
8850
+ if (result.kind !== "normal") {
8851
+ return result;
8852
+ }
8853
+ }
8854
+ return result;
8855
+ }
8856
+ function predeclareBlockBindings(node, scope) {
8857
+ const names = /* @__PURE__ */ new Set();
8858
+ for (const statement of node.body) {
8859
+ if (statement.type !== "VariableDeclaration" || statement.kind === "var") {
8860
+ continue;
8861
+ }
8862
+ for (const name of getDeclarationBindingNames(statement)) {
8863
+ if (names.has(name) || scope.hasOwnBinding(name)) {
8864
+ throw new Error(`Cannot redeclare binding '${name}' in the same scope.`);
8865
+ }
8866
+ names.add(name);
8867
+ scope.predeclare(name, statement.kind);
8868
+ }
8869
+ }
8870
+ }
8871
+ function getDeclarationBindingNames(node) {
8872
+ return node.declarations.flatMap((declarator) => getPatternBindingNames(declarator.id));
8873
+ }
8874
+ function getPatternBindingNames(pattern) {
8875
+ switch (pattern.type) {
8876
+ case "Identifier":
8877
+ return [pattern.name];
8878
+ case "MemberExpression":
8879
+ return [];
8880
+ case "AssignmentPattern":
8881
+ return getPatternBindingNames(pattern.left);
8882
+ case "ArrayPattern":
8883
+ return pattern.elements.flatMap(
8884
+ (element) => element === null ? [] : getPatternBindingNames(element)
8885
+ );
8886
+ case "ObjectPattern":
8887
+ return pattern.properties.flatMap(
8888
+ (property) => property.type === "RestElement" ? getPatternBindingNames(property) : getPatternBindingNames(property.value)
8889
+ );
8890
+ case "RestElement":
8891
+ return getPatternBindingNames(pattern.argument);
8892
+ }
8893
+ }
8894
+ async function bindPattern(pattern, value, context, evaluateNode2) {
8895
+ switch (pattern.type) {
8896
+ case "Identifier":
8897
+ context.scope.declare(pattern.name, "let", value);
8898
+ return { ok: true };
8899
+ case "MemberExpression":
8900
+ throw new TypeError("Catch bindings do not support member expressions.");
8901
+ case "AssignmentPattern":
8902
+ return bindAssignmentPattern(pattern, value, context, evaluateNode2);
8903
+ case "ArrayPattern":
8904
+ return bindArrayPattern(pattern, value, context, evaluateNode2);
8905
+ case "ObjectPattern":
8906
+ return bindObjectPattern(pattern, value, context, evaluateNode2);
8907
+ case "RestElement":
8908
+ return bindPattern(pattern.argument, value, context, evaluateNode2);
8909
+ }
8910
+ }
8911
+ async function bindAssignmentPattern(pattern, value, context, evaluateNode2) {
8912
+ let nextValue = value;
8913
+ if (nextValue === void 0) {
8914
+ const defaultValue = await evaluateNode2(pattern.right, context);
8915
+ if (defaultValue.kind !== "normal") {
8916
+ return {
8917
+ ok: false,
8918
+ result: defaultValue
8919
+ };
8920
+ }
8921
+ nextValue = defaultValue.value;
8922
+ }
8923
+ return bindPattern(pattern.left, nextValue, context, evaluateNode2);
8924
+ }
8925
+ async function bindArrayPattern(pattern, value, context, evaluateNode2) {
8926
+ if (!Array.isArray(value)) {
8927
+ throw new TypeError("Array catch bindings require an array value.");
8928
+ }
8929
+ for (let index = 0; index < pattern.elements.length; index += 1) {
8930
+ const element = pattern.elements[index];
8931
+ if (element === null) {
8932
+ continue;
8933
+ }
8934
+ const elementValue = element.type === "RestElement" ? value.slice(index) : value[index];
8935
+ const binding = await bindPattern(element, elementValue, context, evaluateNode2);
8936
+ if (!binding.ok) {
8937
+ return binding;
8938
+ }
8939
+ }
8940
+ return { ok: true };
8941
+ }
8942
+ async function bindObjectPattern(pattern, value, context, evaluateNode2) {
8943
+ if (typeof value !== "object" && !Array.isArray(value) || value === null) {
8944
+ throw new TypeError("Object catch bindings require a non-null object value.");
8945
+ }
8946
+ const excludedKeys = /* @__PURE__ */ new Set();
8947
+ for (const property of pattern.properties) {
8948
+ if (property.type === "RestElement") {
8949
+ const restValue = copyObjectRest(value, excludedKeys);
8950
+ const binding2 = await bindPattern(property, restValue, context, evaluateNode2);
8951
+ if (!binding2.ok) {
8952
+ return binding2;
8953
+ }
8954
+ continue;
8955
+ }
8956
+ const key = await resolvePatternPropertyKey(property, context, evaluateNode2);
8957
+ if (!key.ok) {
8958
+ return key;
8959
+ }
8960
+ excludedKeys.add(String(key.value));
8961
+ const binding = await bindPattern(
8962
+ property.value,
8963
+ getObjectPatternValue(value, key.value),
8964
+ context,
8965
+ evaluateNode2
8966
+ );
8967
+ if (!binding.ok) {
8968
+ return binding;
8969
+ }
8970
+ }
8971
+ return { ok: true };
8972
+ }
8973
+ async function resolvePatternPropertyKey(property, context, evaluateNode2) {
8974
+ if (!property.computed) {
8975
+ return {
8976
+ ok: true,
8977
+ value: getStaticPropertyKey(property.key)
8978
+ };
8979
+ }
8980
+ const computedKey = await evaluateNode2(property.key, context);
8981
+ if (computedKey.kind !== "normal") {
8982
+ return {
8983
+ ok: false,
8984
+ result: computedKey
8985
+ };
8986
+ }
8987
+ return {
8988
+ ok: true,
8989
+ value: await (context.toPropertyKey?.(computedKey.value) ?? toPropertyKey(
8990
+ computedKey.value,
8991
+ context.budget,
8992
+ { stack: context.callStack, thisValue: void 0 }
8993
+ ))
8994
+ };
8995
+ }
8996
+ function getStaticPropertyKey(property) {
8997
+ switch (property.type) {
8998
+ case "Identifier":
8999
+ return property.name;
9000
+ case "StringLiteral":
9001
+ case "NumericLiteral":
9002
+ return property.value;
9003
+ default:
9004
+ throw new TypeError(`Unsupported catch binding property key '${property.type}'.`);
9005
+ }
9006
+ }
9007
+ function getObjectPatternValue(value, key) {
9008
+ return value[key];
9009
+ }
9010
+ function copyObjectRest(value, excludedKeys) {
9011
+ const rest = /* @__PURE__ */ Object.create(null);
9012
+ for (const [key, entryValue] of Object.entries(value)) {
9013
+ if (excludedKeys.has(key)) {
9014
+ continue;
9015
+ }
9016
+ rest[key] = entryValue;
9017
+ }
9018
+ return rest;
9019
+ }
9020
+
9021
+ // packages/safe-js/src/interp/running-state.ts
9022
+ var runningObjects = /* @__PURE__ */ new WeakSet();
9023
+ var lockedCollections = /* @__PURE__ */ new WeakSet();
9024
+ var activeSnapshots = /* @__PURE__ */ new WeakSet();
9025
+ function enterRunningState(object) {
9026
+ if (runningObjects.has(object)) {
9027
+ throw new SandboxError("reentry");
9028
+ }
9029
+ runningObjects.add(object);
9030
+ let active = true;
9031
+ return () => {
9032
+ if (!active) return;
9033
+ active = false;
9034
+ runningObjects.delete(object);
9035
+ };
9036
+ }
9037
+ function assertCollectionMutable(object) {
9038
+ if (lockedCollections.has(object)) {
9039
+ throw new SandboxError("reentry");
9040
+ }
9041
+ }
9042
+ function enterSnapshotRun(snapshot) {
9043
+ if (activeSnapshots.has(snapshot)) {
9044
+ throw new SandboxError("reentry");
9045
+ }
9046
+ activeSnapshots.add(snapshot);
9047
+ return () => activeSnapshots.delete(snapshot);
9048
+ }
9049
+ function assertSnapshotInactive(snapshot) {
9050
+ if (activeSnapshots.has(snapshot)) {
9051
+ throw new SandboxError("reentry");
9052
+ }
9053
+ }
9054
+
9055
+ // packages/safe-js/src/interp/iteration.ts
9056
+ function getSandboxIterator(value) {
9057
+ if (isGuestHostObject(value)) return getHostObjectIterator(value);
9058
+ if (isFloat32Array(value)) {
9059
+ return syncIterator(Float32Array.prototype.values.call(value));
9060
+ }
9061
+ if (isSandboxGenerator(value)) {
9062
+ return generatorIterator(value);
9063
+ }
9064
+ if (typeof value === "string") {
9065
+ return syncIterator(value[Symbol.iterator]());
9066
+ }
9067
+ if (isSandboxMap(value)) {
9068
+ return collectionIterator(value.entries);
9069
+ }
9070
+ if (isSandboxSet(value)) {
9071
+ return collectionIterator(value.values);
9072
+ }
9073
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
9074
+ return void 0;
9075
+ }
9076
+ const iteratorMethod = value[Symbol.iterator];
9077
+ if (typeof iteratorMethod !== "function") {
9078
+ return void 0;
9079
+ }
9080
+ return syncIterator(Reflect.apply(iteratorMethod, value, []));
9081
+ }
9082
+ function collectionIterator(collection) {
9083
+ let iterator = collection[Symbol.iterator]();
9084
+ let exhausted = false;
9085
+ return {
9086
+ ...syncIterator({
8784
9087
  next: () => {
8785
9088
  if (exhausted) return { done: true, value: void 0 };
8786
9089
  const result = iterator.next();
@@ -23715,565 +24018,288 @@ async function findLastInArray(value, callback, options, stack, thisValue) {
23715
24018
  const length = value.length;
23716
24019
  for (let index = length - 1; index >= 0; index -= 1) {
23717
24020
  options.budget.visitNode();
23718
- const entry = index in value ? value[index] : void 0;
23719
- if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
23720
- return entry;
23721
- }
23722
- }
23723
- return void 0;
23724
- }
23725
- async function findLastIndexInArray(value, callback, options, stack, thisValue) {
23726
- const length = value.length;
23727
- for (let index = length - 1; index >= 0; index -= 1) {
23728
- options.budget.visitNode();
23729
- const entry = index in value ? value[index] : void 0;
23730
- if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
23731
- return index;
23732
- }
23733
- }
23734
- return -1;
23735
- }
23736
- async function someInArray(value, callback, options, stack, thisValue) {
23737
- const length = value.length;
23738
- for (let index = 0; index < length; index += 1) {
23739
- options.budget.visitNode();
23740
- if (!(index in value)) {
23741
- continue;
23742
- }
23743
- if (await callArrayCallback(callback, value[index], index, value, options, stack, thisValue)) {
23744
- return true;
23745
- }
23746
- }
23747
- return false;
23748
- }
23749
- async function everyInArray(value, callback, options, stack, thisValue) {
23750
- const length = value.length;
23751
- for (let index = 0; index < length; index += 1) {
23752
- options.budget.visitNode();
23753
- if (!(index in value)) {
23754
- continue;
23755
- }
23756
- if (!await callArrayCallback(callback, value[index], index, value, options, stack, thisValue)) {
23757
- return false;
23758
- }
23759
- }
23760
- return true;
23761
- }
23762
- async function reduceArray(value, callback, hasInitialValue, initialValue, options, stack) {
23763
- const length = value.length;
23764
- if (hasInitialValue) {
23765
- return reduceFromLeft(value, callback, initialValue, 0, length, options, stack);
23766
- }
23767
- const start = findNextDefinedIndex(value, 0, 1, length, options.budget);
23768
- if (start < 0) {
23769
- throw new TypeError("Reduce of empty array with no initial value.");
23770
- }
23771
- return reduceFromLeft(value, callback, value[start], start + 1, length, options, stack);
23772
- }
23773
- async function reduceRightArray(value, callback, hasInitialValue, initialValue, options, stack) {
23774
- const length = value.length;
23775
- if (hasInitialValue) {
23776
- return reduceFromRight(value, callback, initialValue, length - 1, length, options, stack);
23777
- }
23778
- const start = findNextDefinedIndex(value, length - 1, -1, length, options.budget);
23779
- if (start < 0) {
23780
- throw new TypeError("Reduce of empty array with no initial value.");
23781
- }
23782
- return reduceFromRight(value, callback, value[start], start - 1, length, options, stack);
23783
- }
23784
- async function reduceFromLeft(value, callback, accumulator, startIndex, length, options, stack) {
23785
- let current = accumulator;
23786
- const retainedAccumulator = {};
23787
- options.budget.setRetainedValues(retainedAccumulator, () => [current]);
23788
- try {
23789
- for (let index = startIndex; index < length; index += 1) {
23790
- options.budget.visitNode();
23791
- if (!(index in value)) {
23792
- continue;
23793
- }
23794
- current = await options.callClosure(callback, [current, value[index], index, value], stack);
23795
- }
23796
- return current;
23797
- } finally {
23798
- options.budget.setRetainedValues(retainedAccumulator, void 0);
23799
- }
23800
- }
23801
- async function reduceFromRight(value, callback, accumulator, startIndex, length, options, stack) {
23802
- let current = accumulator;
23803
- const retainedAccumulator = {};
23804
- options.budget.setRetainedValues(retainedAccumulator, () => [current]);
23805
- try {
23806
- for (let index = Math.min(startIndex, length - 1); index >= 0; index -= 1) {
23807
- options.budget.visitNode();
23808
- if (!(index in value)) {
23809
- continue;
23810
- }
23811
- current = await options.callClosure(callback, [current, value[index], index, value], stack);
23812
- }
23813
- return current;
23814
- } finally {
23815
- options.budget.setRetainedValues(retainedAccumulator, void 0);
23816
- }
23817
- }
23818
- async function forEachArray(value, callback, options, stack, thisValue) {
23819
- const length = value.length;
23820
- for (let index = 0; index < length; index += 1) {
23821
- options.budget.visitNode();
23822
- if (!(index in value)) {
23823
- continue;
23824
- }
23825
- await callArrayCallback(callback, value[index], index, value, options, stack, thisValue);
23826
- }
23827
- }
23828
- async function flatMapArray(value, callback, options, stack, thisValue) {
23829
- const length = value.length;
23830
- const result = [];
23831
- options.budget.setRetainedValues(result, () => [result]);
23832
- try {
23833
- for (let index = 0; index < length; index += 1) {
23834
- options.budget.visitNode();
23835
- if (!(index in value)) {
23836
- continue;
23837
- }
23838
- const mapped = await callArrayCallback(
23839
- callback,
23840
- value[index],
23841
- index,
23842
- value,
23843
- options,
23844
- stack,
23845
- thisValue
23846
- );
23847
- if (Array.isArray(mapped)) {
23848
- for (let mappedIndex = 0; mappedIndex < mapped.length; mappedIndex += 1) {
23849
- options.budget.visitNode();
23850
- if (!(mappedIndex in mapped)) {
23851
- continue;
23852
- }
23853
- result.push(mapped[mappedIndex]);
23854
- options.budget.allocateArrayLength(result.length);
23855
- }
23856
- continue;
23857
- }
23858
- result.push(mapped);
23859
- options.budget.allocateArrayLength(result.length);
23860
- }
23861
- return result;
23862
- } finally {
23863
- options.budget.setRetainedValues(result, void 0);
23864
- }
23865
- }
23866
- function flattenArray(value, depth, budget) {
23867
- const result = [];
23868
- appendFlattenedEntries(value, depth, result, budget);
23869
- return result;
23870
- }
23871
- function appendFlattenedEntries(value, depth, result, budget) {
23872
- for (let index = 0; index < value.length; index += 1) {
23873
- if (!(index in value)) {
23874
- continue;
23875
- }
23876
- const entry = value[index];
23877
- if (depth > 0 && Array.isArray(entry)) {
23878
- appendFlattenedEntries(entry, depth - 1, result, budget);
23879
- continue;
23880
- }
23881
- result.push(entry);
23882
- budget.allocateArrayLength(result.length);
23883
- }
23884
- }
23885
- async function sortArray(value, comparator, options, stack) {
23886
- const length = value.length;
23887
- const definedValues = [];
23888
- let undefinedCount = 0;
23889
- let currentEntry;
23890
- options.budget.setRetainedValues(definedValues, () => [definedValues, currentEntry]);
23891
- try {
23892
- for (let index = 0; index < length; index += 1) {
23893
- options.budget.visitNode();
23894
- if (!(index in value)) {
23895
- continue;
23896
- }
23897
- const entry = value[index];
23898
- if (entry === void 0) {
23899
- undefinedCount += 1;
23900
- continue;
23901
- }
23902
- definedValues.push(entry);
23903
- }
23904
- for (let index = 1; index < definedValues.length; index += 1) {
23905
- currentEntry = definedValues[index];
23906
- let cursor = index - 1;
23907
- while (cursor >= 0 && await compareEntries(definedValues[cursor], currentEntry, comparator, options, stack) > 0) {
23908
- definedValues[cursor + 1] = definedValues[cursor];
23909
- cursor -= 1;
23910
- }
23911
- definedValues[cursor + 1] = currentEntry;
23912
- }
23913
- currentEntry = void 0;
23914
- for (let index = 0; index < definedValues.length; index += 1) {
23915
- value[index] = definedValues[index];
23916
- }
23917
- for (let index = 0; index < undefinedCount; index += 1) {
23918
- value[definedValues.length + index] = void 0;
23919
- }
23920
- for (let index = definedValues.length + undefinedCount; index < length; index += 1) {
23921
- options.budget.visitNode();
23922
- delete value[index];
23923
- }
23924
- } finally {
23925
- options.budget.setRetainedValues(definedValues, void 0);
23926
- }
23927
- }
23928
- async function compareEntries(left, right, comparator, options, stack) {
23929
- options.budget.visitNode();
23930
- const result = Number(await options.callClosure(comparator, [left, right], stack));
23931
- return Number.isNaN(result) ? 0 : result;
23932
- }
23933
- async function callArrayCallback(callback, value, index, array, options, stack, thisValue) {
23934
- return options.callClosure(callback, [value, index, array], stack, thisValue);
23935
- }
23936
- function findNextDefinedIndex(value, startIndex, direction, length, budget) {
23937
- for (let index = startIndex; direction > 0 ? index < length : index >= 0; index += direction) {
23938
- budget.visitNode();
23939
- if (index in value) {
23940
- return index;
23941
- }
23942
- }
23943
- return -1;
23944
- }
23945
- function budgetProducedValue(value, budget) {
23946
- allocateProducedValue(value, budget, /* @__PURE__ */ new WeakSet());
23947
- return value;
23948
- }
23949
- function allocateProducedValue(value, budget, seen) {
23950
- if (typeof value === "string") {
23951
- budget.allocateString(value);
23952
- return;
23953
- }
23954
- if (Array.isArray(value)) {
23955
- budget.allocateArrayLength(value.length);
23956
- if (seen.has(value)) {
23957
- return;
23958
- }
23959
- seen.add(value);
23960
- for (const entry of value) {
23961
- allocateProducedValue(entry, budget, seen);
24021
+ const entry = index in value ? value[index] : void 0;
24022
+ if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
24023
+ return entry;
23962
24024
  }
23963
- return;
23964
24025
  }
23965
- if (isSandboxMap(value)) {
23966
- budget.allocateCollectionEntries(value.entries.size);
23967
- if (seen.has(value)) {
23968
- return;
23969
- }
23970
- seen.add(value);
23971
- for (const [key, entry] of value.entries) {
23972
- allocateProducedValue(key, budget, seen);
23973
- allocateProducedValue(entry, budget, seen);
24026
+ return void 0;
24027
+ }
24028
+ async function findLastIndexInArray(value, callback, options, stack, thisValue) {
24029
+ const length = value.length;
24030
+ for (let index = length - 1; index >= 0; index -= 1) {
24031
+ options.budget.visitNode();
24032
+ const entry = index in value ? value[index] : void 0;
24033
+ if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
24034
+ return index;
23974
24035
  }
23975
- return;
23976
24036
  }
23977
- if (isSandboxSet(value)) {
23978
- budget.allocateCollectionEntries(value.values.size);
23979
- if (seen.has(value)) {
23980
- return;
24037
+ return -1;
24038
+ }
24039
+ async function someInArray(value, callback, options, stack, thisValue) {
24040
+ const length = value.length;
24041
+ for (let index = 0; index < length; index += 1) {
24042
+ options.budget.visitNode();
24043
+ if (!(index in value)) {
24044
+ continue;
23981
24045
  }
23982
- seen.add(value);
23983
- for (const entry of value.values) {
23984
- allocateProducedValue(entry, budget, seen);
24046
+ if (await callArrayCallback(callback, value[index], index, value, options, stack, thisValue)) {
24047
+ return true;
23985
24048
  }
23986
- return;
23987
- }
23988
- if (typeof value !== "object" || value === null || isSandboxClosure(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value)) {
23989
- return;
23990
- }
23991
- if (seen.has(value)) {
23992
- return;
23993
- }
23994
- seen.add(value);
23995
- for (const entry of Object.values(value)) {
23996
- allocateProducedValue(entry, budget, seen);
23997
24049
  }
24050
+ return false;
23998
24051
  }
23999
- function toIntegerOrInfinity(value) {
24000
- const number = Number(value);
24001
- if (Number.isNaN(number) || Object.is(number, 0) || Object.is(number, -0)) {
24002
- return 0;
24003
- }
24004
- if (!Number.isFinite(number)) {
24005
- return number;
24052
+ async function everyInArray(value, callback, options, stack, thisValue) {
24053
+ const length = value.length;
24054
+ for (let index = 0; index < length; index += 1) {
24055
+ options.budget.visitNode();
24056
+ if (!(index in value)) {
24057
+ continue;
24058
+ }
24059
+ if (!await callArrayCallback(callback, value[index], index, value, options, stack, thisValue)) {
24060
+ return false;
24061
+ }
24006
24062
  }
24007
- return Math.trunc(number);
24063
+ return true;
24008
24064
  }
24009
-
24010
- // packages/safe-js/src/interp/methods/function.ts
24011
- var functionMethodNames = /* @__PURE__ */ new Set(["apply", "bind", "call"]);
24012
- function getFunctionMember(target, property, options) {
24013
- if (isGuestClosure(target)) {
24014
- const value = getGuestFunctionProperty(target, String(property));
24015
- if (value !== void 0 || Object.hasOwn(target.properties ?? {}, String(property))) return value;
24016
- if (!isFunctionMethodName(property)) return void 0;
24017
- }
24018
- const properties = target.properties;
24019
- if (properties !== void 0 && Object.hasOwn(properties, String(property))) {
24020
- return properties[String(property)];
24021
- }
24022
- if (property === "length") {
24023
- return target.length;
24065
+ async function reduceArray(value, callback, hasInitialValue, initialValue, options, stack) {
24066
+ const length = value.length;
24067
+ if (hasInitialValue) {
24068
+ return reduceFromLeft(value, callback, initialValue, 0, length, options, stack);
24024
24069
  }
24025
- if (!isFunctionMethodName(property)) {
24026
- return void 0;
24070
+ const start = findNextDefinedIndex(value, 0, 1, length, options.budget);
24071
+ if (start < 0) {
24072
+ throw new TypeError("Reduce of empty array with no initial value.");
24027
24073
  }
24028
- return createSandboxClosure({
24029
- sandbox: true,
24030
- name: `Function#${property}`,
24031
- call: (args, context) => callFunctionMethod(target, property, args, options, context?.stack ?? [])
24032
- });
24033
- }
24034
- function isFunctionMethodName(property) {
24035
- return typeof property === "string" && functionMethodNames.has(property);
24074
+ return reduceFromLeft(value, callback, value[start], start + 1, length, options, stack);
24036
24075
  }
24037
- function callFunctionMethod(target, methodName, args, options, stack) {
24038
- const thisValue = args[0];
24039
- if (methodName === "bind") {
24040
- const boundArgs = args.slice(1);
24041
- return createSandboxClosure({
24042
- guest: true,
24043
- sandbox: true,
24044
- name: `bound ${target.name ?? ""}`,
24045
- length: target.length === void 0 ? void 0 : Math.max(0, target.length - boundArgs.length),
24046
- boundTarget: target,
24047
- retainedValues: () => [target, thisValue, ...boundArgs],
24048
- call: (callArgs, context) => options.callClosure(target, [...boundArgs, ...callArgs], context?.stack ?? [], thisValue),
24049
- ...target.construct === void 0 ? {} : {
24050
- construct: (callArgs, context) => options.callClosure(
24051
- target,
24052
- [...boundArgs, ...callArgs],
24053
- context?.stack ?? [],
24054
- void 0,
24055
- true
24056
- )
24057
- }
24058
- });
24059
- }
24060
- if (methodName === "call") {
24061
- return options.callClosure(target, args.slice(1), stack, thisValue);
24062
- }
24063
- const applyArgs = args[1];
24064
- if (applyArgs === null || applyArgs === void 0) {
24065
- return options.callClosure(target, [], stack, thisValue);
24076
+ async function reduceRightArray(value, callback, hasInitialValue, initialValue, options, stack) {
24077
+ const length = value.length;
24078
+ if (hasInitialValue) {
24079
+ return reduceFromRight(value, callback, initialValue, length - 1, length, options, stack);
24066
24080
  }
24067
- if (!Array.isArray(applyArgs)) {
24068
- throw new TypeError("Function#apply requires an array or nullish arguments value.");
24081
+ const start = findNextDefinedIndex(value, length - 1, -1, length, options.budget);
24082
+ if (start < 0) {
24083
+ throw new TypeError("Reduce of empty array with no initial value.");
24069
24084
  }
24070
- return options.callClosure(target, applyArgs, stack, thisValue);
24085
+ return reduceFromRight(value, callback, value[start], start - 1, length, options, stack);
24071
24086
  }
24072
-
24073
- // packages/safe-js/src/interp/methods/collection-callback.ts
24074
- var activeCallbacks = /* @__PURE__ */ new WeakMap();
24075
- function enterKeyedCollectionCallback(target, keys, budget) {
24076
- let state = activeCallbacks.get(target);
24077
- if (state === void 0) {
24078
- state = { cursors: /* @__PURE__ */ new Set(), leaveRunning: enterRunningState(target) };
24079
- activeCallbacks.set(target, state);
24080
- }
24081
- const cursor = { budget, pending: /* @__PURE__ */ new Set() };
24082
- state.cursors.add(cursor);
24083
- const leave = () => {
24084
- if (!state.cursors.delete(cursor)) return;
24085
- cursor.pending.clear();
24086
- budget.setRetainedDataUsage(cursor, 0);
24087
- budget.setRetainedValues(cursor, void 0);
24088
- if (state.cursors.size === 0) {
24089
- activeCallbacks.delete(target);
24090
- state.leaveRunning();
24091
- }
24092
- };
24087
+ async function reduceFromLeft(value, callback, accumulator, startIndex, length, options, stack) {
24088
+ let current = accumulator;
24089
+ const retainedAccumulator = {};
24090
+ options.budget.setRetainedValues(retainedAccumulator, () => [current]);
24093
24091
  try {
24094
- budget.setRetainedDataUsage(cursor, 1);
24095
- budget.setRetainedValues(cursor, () => cursor.pending);
24096
- for (const key of keys) updatePendingKeys(cursor, "add", key);
24097
- } catch (error) {
24098
- leave();
24099
- throw error;
24100
- }
24101
- return {
24102
- next: () => {
24103
- budget.visitNode();
24104
- for (const key of cursor.pending) {
24105
- cursor.pending.delete(key);
24106
- budget.setRetainedDataUsage(cursor, 1 + cursor.pending.size);
24107
- return { done: false, value: key };
24092
+ for (let index = startIndex; index < length; index += 1) {
24093
+ options.budget.visitNode();
24094
+ if (!(index in value)) {
24095
+ continue;
24108
24096
  }
24109
- return { done: true, value: void 0 };
24110
- },
24111
- leave
24112
- };
24113
- }
24114
- function updateKeyedCollectionCallbacks(target, mutation, key) {
24115
- const state = activeCallbacks.get(target);
24116
- if (state === void 0) return;
24117
- for (const cursor of state.cursors) updatePendingKeys(cursor, mutation, key);
24118
- }
24119
- function updatePendingKeys(cursor, mutation, key) {
24120
- const { budget, pending } = cursor;
24121
- budget.visitNode();
24122
- if (mutation === "add") {
24123
- const nextSize = pending.has(key) ? pending.size : pending.size + 1;
24124
- budget.allocateCollectionEntries(nextSize);
24125
- budget.setRetainedDataUsage(cursor, 1 + nextSize);
24126
- pending.add(key);
24127
- } else {
24128
- if (mutation === "delete") pending.delete(key);
24129
- else pending.clear();
24130
- budget.setRetainedDataUsage(cursor, 1 + pending.size);
24131
- }
24132
- }
24133
-
24134
- // packages/safe-js/src/interp/methods/map.ts
24135
- var mapMethodNames = /* @__PURE__ */ new Set([
24136
- "get",
24137
- "set",
24138
- "has",
24139
- "delete",
24140
- "clear",
24141
- "forEach",
24142
- "keys",
24143
- "values",
24144
- "entries"
24145
- ]);
24146
- function isMapMethodName(value) {
24147
- return typeof value === "string" && mapMethodNames.has(value);
24148
- }
24149
- function getMapMember(target, property, options) {
24150
- if (property === "size") {
24151
- return target.entries.size;
24152
- }
24153
- if (!isMapMethodName(property)) {
24154
- return void 0;
24097
+ current = await options.callClosure(callback, [current, value[index], index, value], stack);
24098
+ }
24099
+ return current;
24100
+ } finally {
24101
+ options.budget.setRetainedValues(retainedAccumulator, void 0);
24155
24102
  }
24156
- return createSandboxClosure({
24157
- sandbox: true,
24158
- call: (args, context) => callMapMethod(target, property, args, options, context?.stack ?? []),
24159
- name: property
24160
- });
24161
- }
24162
- async function callMapMethod(target, methodName, args, options, stack = []) {
24163
- switch (methodName) {
24164
- case "get":
24165
- return target.entries.get(args[0]);
24166
- case "set": {
24167
- assertCollectionMutable(target);
24168
- const exists = target.entries.has(args[0]);
24169
- const nextSize = exists ? target.entries.size : target.entries.size + 1;
24170
- options.budget.allocateCollectionEntries(nextSize);
24171
- if (!exists) updateKeyedCollectionCallbacks(target, "add", args[0]);
24172
- target.entries.set(args[0], args[1]);
24173
- return target;
24103
+ }
24104
+ async function reduceFromRight(value, callback, accumulator, startIndex, length, options, stack) {
24105
+ let current = accumulator;
24106
+ const retainedAccumulator = {};
24107
+ options.budget.setRetainedValues(retainedAccumulator, () => [current]);
24108
+ try {
24109
+ for (let index = Math.min(startIndex, length - 1); index >= 0; index -= 1) {
24110
+ options.budget.visitNode();
24111
+ if (!(index in value)) {
24112
+ continue;
24113
+ }
24114
+ current = await options.callClosure(callback, [current, value[index], index, value], stack);
24174
24115
  }
24175
- case "has":
24176
- return target.entries.has(args[0]);
24177
- case "delete": {
24178
- assertCollectionMutable(target);
24179
- const deleted = target.entries.delete(args[0]);
24180
- if (deleted) updateKeyedCollectionCallbacks(target, "delete", args[0]);
24181
- return deleted;
24116
+ return current;
24117
+ } finally {
24118
+ options.budget.setRetainedValues(retainedAccumulator, void 0);
24119
+ }
24120
+ }
24121
+ async function forEachArray(value, callback, options, stack, thisValue) {
24122
+ const length = value.length;
24123
+ for (let index = 0; index < length; index += 1) {
24124
+ options.budget.visitNode();
24125
+ if (!(index in value)) {
24126
+ continue;
24182
24127
  }
24183
- case "clear":
24184
- assertCollectionMutable(target);
24185
- target.entries.clear();
24186
- updateKeyedCollectionCallbacks(target, "clear");
24187
- return void 0;
24188
- case "forEach": {
24189
- const callback = args[0];
24190
- if (!isSandboxClosure(callback)) {
24191
- throw new TypeError("Map.prototype.forEach requires a callback function.");
24128
+ await callArrayCallback(callback, value[index], index, value, options, stack, thisValue);
24129
+ }
24130
+ }
24131
+ async function flatMapArray(value, callback, options, stack, thisValue) {
24132
+ const length = value.length;
24133
+ const result = [];
24134
+ options.budget.setRetainedValues(result, () => [result]);
24135
+ try {
24136
+ for (let index = 0; index < length; index += 1) {
24137
+ options.budget.visitNode();
24138
+ if (!(index in value)) {
24139
+ continue;
24192
24140
  }
24193
- const cursor = enterKeyedCollectionCallback(target, target.entries.keys(), options.budget);
24194
- try {
24195
- for (let entry = cursor.next(); !entry.done; entry = cursor.next()) {
24196
- const key = entry.value;
24197
- const value = target.entries.get(key);
24198
- await options.callClosure(callback, [value, key, target], stack, args[1]);
24141
+ const mapped = await callArrayCallback(
24142
+ callback,
24143
+ value[index],
24144
+ index,
24145
+ value,
24146
+ options,
24147
+ stack,
24148
+ thisValue
24149
+ );
24150
+ if (Array.isArray(mapped)) {
24151
+ for (let mappedIndex = 0; mappedIndex < mapped.length; mappedIndex += 1) {
24152
+ options.budget.visitNode();
24153
+ if (!(mappedIndex in mapped)) {
24154
+ continue;
24155
+ }
24156
+ result.push(mapped[mappedIndex]);
24157
+ options.budget.allocateArrayLength(result.length);
24199
24158
  }
24200
- } finally {
24201
- cursor.leave();
24159
+ continue;
24202
24160
  }
24203
- return void 0;
24161
+ result.push(mapped);
24162
+ options.budget.allocateArrayLength(result.length);
24204
24163
  }
24205
- case "keys":
24206
- return allocateProducedSandboxValue([...target.entries.keys()], options.budget);
24207
- case "values":
24208
- return allocateProducedSandboxValue([...target.entries.values()], options.budget);
24209
- case "entries":
24210
- return allocateProducedSandboxValue(
24211
- [...target.entries].map(([key, value]) => [key, value]),
24212
- options.budget
24213
- );
24164
+ return result;
24165
+ } finally {
24166
+ options.budget.setRetainedValues(result, void 0);
24214
24167
  }
24215
24168
  }
24216
-
24217
- // packages/safe-js/src/interp/methods/number.ts
24218
- var numberMethodNames = /* @__PURE__ */ new Set([
24219
- "toExponential",
24220
- "toFixed",
24221
- "toPrecision",
24222
- "toString"
24223
- ]);
24224
- function getNumberMember(value, property, budget) {
24225
- if (!isNumberMethodName(property)) {
24226
- return void 0;
24169
+ function flattenArray(value, depth, budget) {
24170
+ const result = [];
24171
+ appendFlattenedEntries(value, depth, result, budget);
24172
+ return result;
24173
+ }
24174
+ function appendFlattenedEntries(value, depth, result, budget) {
24175
+ for (let index = 0; index < value.length; index += 1) {
24176
+ if (!(index in value)) {
24177
+ continue;
24178
+ }
24179
+ const entry = value[index];
24180
+ if (depth > 0 && Array.isArray(entry)) {
24181
+ appendFlattenedEntries(entry, depth - 1, result, budget);
24182
+ continue;
24183
+ }
24184
+ result.push(entry);
24185
+ budget.allocateArrayLength(result.length);
24227
24186
  }
24228
- return createSandboxClosure({
24229
- sandbox: true,
24230
- name: `Number#${property}`,
24231
- call: (args) => callNumberMethod(value, property, args, budget)
24232
- });
24233
24187
  }
24234
- function isNumberMethodName(property) {
24235
- return typeof property === "string" && numberMethodNames.has(property);
24188
+ async function sortArray(value, comparator, options, stack) {
24189
+ const length = value.length;
24190
+ const definedValues = [];
24191
+ let undefinedCount = 0;
24192
+ let currentEntry;
24193
+ options.budget.setRetainedValues(definedValues, () => [definedValues, currentEntry]);
24194
+ try {
24195
+ for (let index = 0; index < length; index += 1) {
24196
+ options.budget.visitNode();
24197
+ if (!(index in value)) {
24198
+ continue;
24199
+ }
24200
+ const entry = value[index];
24201
+ if (entry === void 0) {
24202
+ undefinedCount += 1;
24203
+ continue;
24204
+ }
24205
+ definedValues.push(entry);
24206
+ }
24207
+ for (let index = 1; index < definedValues.length; index += 1) {
24208
+ currentEntry = definedValues[index];
24209
+ let cursor = index - 1;
24210
+ while (cursor >= 0 && await compareEntries(definedValues[cursor], currentEntry, comparator, options, stack) > 0) {
24211
+ definedValues[cursor + 1] = definedValues[cursor];
24212
+ cursor -= 1;
24213
+ }
24214
+ definedValues[cursor + 1] = currentEntry;
24215
+ }
24216
+ currentEntry = void 0;
24217
+ for (let index = 0; index < definedValues.length; index += 1) {
24218
+ value[index] = definedValues[index];
24219
+ }
24220
+ for (let index = 0; index < undefinedCount; index += 1) {
24221
+ value[definedValues.length + index] = void 0;
24222
+ }
24223
+ for (let index = definedValues.length + undefinedCount; index < length; index += 1) {
24224
+ options.budget.visitNode();
24225
+ delete value[index];
24226
+ }
24227
+ } finally {
24228
+ options.budget.setRetainedValues(definedValues, void 0);
24229
+ }
24236
24230
  }
24237
- function callNumberMethod(value, methodName, args, budget) {
24238
- return budget.allocateString(callNativeNumberMethod(value, methodName, args));
24231
+ async function compareEntries(left, right, comparator, options, stack) {
24232
+ options.budget.visitNode();
24233
+ const result = Number(await options.callClosure(comparator, [left, right], stack));
24234
+ return Number.isNaN(result) ? 0 : result;
24239
24235
  }
24240
- function callNativeNumberMethod(value, methodName, args) {
24241
- switch (methodName) {
24242
- case "toString":
24243
- return value.toString(asValidatedRadix(args[0]));
24244
- case "toExponential":
24245
- return args[0] === void 0 ? value.toExponential() : value.toExponential(asValidatedFractionDigits(args[0], methodName));
24246
- case "toFixed":
24247
- return value.toFixed(asValidatedFractionDigits(args[0], methodName));
24248
- case "toPrecision":
24249
- return args[0] === void 0 ? value.toPrecision() : value.toPrecision(asValidatedPrecision(args[0]));
24236
+ async function callArrayCallback(callback, value, index, array, options, stack, thisValue) {
24237
+ return options.callClosure(callback, [value, index, array], stack, thisValue);
24238
+ }
24239
+ function findNextDefinedIndex(value, startIndex, direction, length, budget) {
24240
+ for (let index = startIndex; direction > 0 ? index < length : index >= 0; index += direction) {
24241
+ budget.visitNode();
24242
+ if (index in value) {
24243
+ return index;
24244
+ }
24250
24245
  }
24246
+ return -1;
24251
24247
  }
24252
- function asValidatedRadix(value) {
24253
- if (value === void 0) {
24254
- return void 0;
24248
+ function budgetProducedValue(value, budget) {
24249
+ allocateProducedValue(value, budget, /* @__PURE__ */ new WeakSet());
24250
+ return value;
24251
+ }
24252
+ function allocateProducedValue(value, budget, seen) {
24253
+ if (typeof value === "string") {
24254
+ budget.allocateString(value);
24255
+ return;
24255
24256
  }
24256
- const radix = toIntegerOrInfinity2(value);
24257
- if (radix < 2 || radix > 36) {
24258
- throw new RangeError("Number#toString radix must be between 2 and 36.");
24257
+ if (Array.isArray(value)) {
24258
+ budget.allocateArrayLength(value.length);
24259
+ if (seen.has(value)) {
24260
+ return;
24261
+ }
24262
+ seen.add(value);
24263
+ for (const entry of value) {
24264
+ allocateProducedValue(entry, budget, seen);
24265
+ }
24266
+ return;
24259
24267
  }
24260
- return radix;
24261
- }
24262
- function asValidatedFractionDigits(value, methodName) {
24263
- const digits = toIntegerOrInfinity2(value);
24264
- if (digits < 0 || digits > 100) {
24265
- throw new RangeError(`Number#${methodName} digits must be between 0 and 100.`);
24268
+ if (isSandboxMap(value)) {
24269
+ budget.allocateCollectionEntries(value.entries.size);
24270
+ if (seen.has(value)) {
24271
+ return;
24272
+ }
24273
+ seen.add(value);
24274
+ for (const [key, entry] of value.entries) {
24275
+ allocateProducedValue(key, budget, seen);
24276
+ allocateProducedValue(entry, budget, seen);
24277
+ }
24278
+ return;
24266
24279
  }
24267
- return digits;
24268
- }
24269
- function asValidatedPrecision(value) {
24270
- const precision = toIntegerOrInfinity2(value);
24271
- if (precision < 1 || precision > 100) {
24272
- throw new RangeError("Number#toPrecision precision must be between 1 and 100.");
24280
+ if (isSandboxSet(value)) {
24281
+ budget.allocateCollectionEntries(value.values.size);
24282
+ if (seen.has(value)) {
24283
+ return;
24284
+ }
24285
+ seen.add(value);
24286
+ for (const entry of value.values) {
24287
+ allocateProducedValue(entry, budget, seen);
24288
+ }
24289
+ return;
24290
+ }
24291
+ if (typeof value !== "object" || value === null || isSandboxClosure(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value)) {
24292
+ return;
24293
+ }
24294
+ if (seen.has(value)) {
24295
+ return;
24296
+ }
24297
+ seen.add(value);
24298
+ for (const entry of Object.values(value)) {
24299
+ allocateProducedValue(entry, budget, seen);
24273
24300
  }
24274
- return precision;
24275
24301
  }
24276
- function toIntegerOrInfinity2(value) {
24302
+ function toIntegerOrInfinity(value) {
24277
24303
  const number = Number(value);
24278
24304
  if (Number.isNaN(number) || Object.is(number, 0) || Object.is(number, -0)) {
24279
24305
  return 0;
@@ -24284,300 +24310,302 @@ function toIntegerOrInfinity2(value) {
24284
24310
  return Math.trunc(number);
24285
24311
  }
24286
24312
 
24287
- // packages/safe-js/src/interp/methods/generator.ts
24288
- var generatorMethodNames = /* @__PURE__ */ new Set(["next", "return", "throw"]);
24289
- function getGeneratorMember(target, property, budget) {
24290
- if (typeof property !== "string" || !generatorMethodNames.has(property)) {
24313
+ // packages/safe-js/src/interp/methods/function.ts
24314
+ var functionMethodNames = /* @__PURE__ */ new Set(["apply", "bind", "call"]);
24315
+ function getFunctionMember(target, property, options) {
24316
+ if (isGuestClosure(target)) {
24317
+ const value = getGuestFunctionProperty(target, String(property));
24318
+ if (value !== void 0 || Object.hasOwn(target.properties ?? {}, String(property))) return value;
24319
+ if (!isFunctionMethodName(property)) return void 0;
24320
+ }
24321
+ const properties = target.properties;
24322
+ if (properties !== void 0 && Object.hasOwn(properties, String(property))) {
24323
+ return properties[String(property)];
24324
+ }
24325
+ if (property === "length") {
24326
+ return target.length;
24327
+ }
24328
+ if (!isFunctionMethodName(property)) {
24291
24329
  return void 0;
24292
24330
  }
24293
24331
  return createSandboxClosure({
24294
24332
  sandbox: true,
24295
- name: property,
24296
- call: async ([value]) => {
24297
- const iterator = getSandboxIterator(target);
24298
- const result = await iterator[property](value);
24299
- return allocateProducedSandboxValue(
24300
- { value: result.value, done: result.done === true },
24301
- budget
24302
- );
24303
- }
24333
+ name: `Function#${property}`,
24334
+ call: (args, context) => callFunctionMethod(target, property, args, options, context?.stack ?? [])
24304
24335
  });
24305
24336
  }
24306
-
24307
- // packages/safe-js/src/interp/regex/engine.ts
24308
- function matchRegex(pattern, input, lastIndex = 0) {
24309
- const startIndex = pattern.flags.global ? normalizeLastIndex(lastIndex) : 0;
24310
- return matchRegexFrom(pattern, input, startIndex);
24311
- }
24312
- function matchRegexFrom(pattern, input, startIndex) {
24313
- if (startIndex > input.length) {
24314
- return null;
24315
- }
24316
- for (let attempt = startIndex; attempt <= input.length; attempt += 1) {
24317
- const context = { input, flags: pattern.flags, steps: 0 };
24318
- charge(context);
24319
- const initialState = {
24320
- position: attempt,
24321
- captures: new Array(pattern.captureCount)
24322
- };
24323
- const result = matchNode(pattern.body, initialState, context).next();
24324
- if (!result.done) {
24325
- return toRegexMatch(input, attempt, result.value);
24326
- }
24327
- }
24328
- return null;
24337
+ function isFunctionMethodName(property) {
24338
+ return typeof property === "string" && functionMethodNames.has(property);
24329
24339
  }
24330
- function* matchNode(node, state, context) {
24331
- charge(context);
24332
- switch (node.type) {
24333
- case "empty":
24334
- yield state;
24335
- return;
24336
- case "literal":
24337
- if (charactersEqual(context.input[state.position], node.value, context.flags.ignoreCase)) {
24338
- yield { ...state, position: state.position + 1 };
24339
- }
24340
- return;
24341
- case "dot":
24342
- if (state.position < context.input.length && (context.flags.dotAll || !isLineTerminator(context.input[state.position]))) {
24343
- yield { ...state, position: state.position + 1 };
24344
- }
24345
- return;
24346
- case "anchor":
24347
- if (matchesAnchor(node.kind, state.position, context)) {
24348
- yield state;
24349
- }
24350
- return;
24351
- case "wordBoundary": {
24352
- const previousWord = state.position > 0 && isWordCharacter(context.input[state.position - 1]);
24353
- const nextWord = state.position < context.input.length && isWordCharacter(context.input[state.position]);
24354
- if (previousWord !== nextWord !== node.negated) {
24355
- yield state;
24356
- }
24357
- return;
24358
- }
24359
- case "characterClass": {
24360
- const character = context.input[state.position];
24361
- if (character !== void 0 && matchesCharacterClass(character, node.items, node.negated, context.flags.ignoreCase)) {
24362
- yield { ...state, position: state.position + 1 };
24363
- }
24364
- return;
24365
- }
24366
- case "sequence":
24367
- yield* matchSequence(node.elements, 0, state, context);
24368
- return;
24369
- case "alternation":
24370
- for (const alternative of node.alternatives) {
24371
- yield* matchNode(alternative, cloneState(state), context);
24372
- }
24373
- return;
24374
- case "group":
24375
- for (const result of matchNode(node.body, cloneState(state), context)) {
24376
- if (!node.capturing || node.index === void 0) {
24377
- yield result;
24378
- continue;
24379
- }
24380
- const captures = result.captures.slice();
24381
- captures[node.index - 1] = { start: state.position, end: result.position };
24382
- yield { position: result.position, captures };
24340
+ function callFunctionMethod(target, methodName, args, options, stack) {
24341
+ const thisValue = args[0];
24342
+ if (methodName === "bind") {
24343
+ const boundArgs = args.slice(1);
24344
+ return createSandboxClosure({
24345
+ guest: true,
24346
+ sandbox: true,
24347
+ name: `bound ${target.name ?? ""}`,
24348
+ length: target.length === void 0 ? void 0 : Math.max(0, target.length - boundArgs.length),
24349
+ boundTarget: target,
24350
+ retainedValues: () => [target, thisValue, ...boundArgs],
24351
+ call: (callArgs, context) => options.callClosure(target, [...boundArgs, ...callArgs], context?.stack ?? [], thisValue),
24352
+ ...target.construct === void 0 ? {} : {
24353
+ construct: (callArgs, context) => options.callClosure(
24354
+ target,
24355
+ [...boundArgs, ...callArgs],
24356
+ context?.stack ?? [],
24357
+ void 0,
24358
+ true
24359
+ )
24383
24360
  }
24384
- return;
24385
- case "quantifier":
24386
- yield* matchQuantifier(node, state, context, 0);
24361
+ });
24387
24362
  }
24388
- }
24389
- function* matchSequence(elements, index, state, context) {
24390
- charge(context);
24391
- if (index === elements.length) {
24392
- yield state;
24393
- return;
24363
+ if (methodName === "call") {
24364
+ return options.callClosure(target, args.slice(1), stack, thisValue);
24394
24365
  }
24395
- for (const result of matchNode(elements[index], state, context)) {
24396
- yield* matchSequence(elements, index + 1, result, context);
24366
+ const applyArgs = args[1];
24367
+ if (applyArgs === null || applyArgs === void 0) {
24368
+ return options.callClosure(target, [], stack, thisValue);
24369
+ }
24370
+ if (!Array.isArray(applyArgs)) {
24371
+ throw new TypeError("Function#apply requires an array or nullish arguments value.");
24397
24372
  }
24373
+ return options.callClosure(target, applyArgs, stack, thisValue);
24398
24374
  }
24399
- function* matchQuantifier(node, state, context, count) {
24400
- charge(context);
24401
- const canRepeat = node.max === void 0 || count < node.max;
24402
- if (!node.greedy && count >= node.min) {
24403
- yield state;
24375
+
24376
+ // packages/safe-js/src/interp/methods/collection-callback.ts
24377
+ var activeCallbacks = /* @__PURE__ */ new WeakMap();
24378
+ function enterKeyedCollectionCallback(target, keys, budget) {
24379
+ let state = activeCallbacks.get(target);
24380
+ if (state === void 0) {
24381
+ state = { cursors: /* @__PURE__ */ new Set(), leaveRunning: enterRunningState(target) };
24382
+ activeCallbacks.set(target, state);
24404
24383
  }
24405
- if (canRepeat) {
24406
- for (const result of matchNode(node.body, clearCaptures(node.body, state), context)) {
24407
- if (result.position === state.position) {
24408
- if (count >= node.min) {
24409
- continue;
24410
- }
24411
- if (count + 1 >= node.min) {
24412
- yield result;
24413
- } else {
24414
- yield* matchQuantifier(node, result, context, count + 1);
24415
- }
24416
- continue;
24417
- }
24418
- yield* matchQuantifier(node, result, context, count + 1);
24384
+ const cursor = { budget, pending: /* @__PURE__ */ new Set() };
24385
+ state.cursors.add(cursor);
24386
+ const leave = () => {
24387
+ if (!state.cursors.delete(cursor)) return;
24388
+ cursor.pending.clear();
24389
+ budget.setRetainedDataUsage(cursor, 0);
24390
+ budget.setRetainedValues(cursor, void 0);
24391
+ if (state.cursors.size === 0) {
24392
+ activeCallbacks.delete(target);
24393
+ state.leaveRunning();
24419
24394
  }
24395
+ };
24396
+ try {
24397
+ budget.setRetainedDataUsage(cursor, 1);
24398
+ budget.setRetainedValues(cursor, () => cursor.pending);
24399
+ for (const key of keys) updatePendingKeys(cursor, "add", key);
24400
+ } catch (error) {
24401
+ leave();
24402
+ throw error;
24420
24403
  }
24421
- if (node.greedy && count >= node.min) {
24422
- yield state;
24404
+ return {
24405
+ next: () => {
24406
+ budget.visitNode();
24407
+ for (const key of cursor.pending) {
24408
+ cursor.pending.delete(key);
24409
+ budget.setRetainedDataUsage(cursor, 1 + cursor.pending.size);
24410
+ return { done: false, value: key };
24411
+ }
24412
+ return { done: true, value: void 0 };
24413
+ },
24414
+ leave
24415
+ };
24416
+ }
24417
+ function updateKeyedCollectionCallbacks(target, mutation, key) {
24418
+ const state = activeCallbacks.get(target);
24419
+ if (state === void 0) return;
24420
+ for (const cursor of state.cursors) updatePendingKeys(cursor, mutation, key);
24421
+ }
24422
+ function updatePendingKeys(cursor, mutation, key) {
24423
+ const { budget, pending } = cursor;
24424
+ budget.visitNode();
24425
+ if (mutation === "add") {
24426
+ const nextSize = pending.has(key) ? pending.size : pending.size + 1;
24427
+ budget.allocateCollectionEntries(nextSize);
24428
+ budget.setRetainedDataUsage(cursor, 1 + nextSize);
24429
+ pending.add(key);
24430
+ } else {
24431
+ if (mutation === "delete") pending.delete(key);
24432
+ else pending.clear();
24433
+ budget.setRetainedDataUsage(cursor, 1 + pending.size);
24434
+ }
24435
+ }
24436
+
24437
+ // packages/safe-js/src/interp/methods/map.ts
24438
+ var mapMethodNames = /* @__PURE__ */ new Set([
24439
+ "get",
24440
+ "set",
24441
+ "has",
24442
+ "delete",
24443
+ "clear",
24444
+ "forEach",
24445
+ "keys",
24446
+ "values",
24447
+ "entries"
24448
+ ]);
24449
+ function isMapMethodName(value) {
24450
+ return typeof value === "string" && mapMethodNames.has(value);
24451
+ }
24452
+ function getMapMember(target, property, options) {
24453
+ if (property === "size") {
24454
+ return target.entries.size;
24423
24455
  }
24424
- }
24425
- function matchesAnchor(kind, position, context) {
24426
- if (kind === "start") {
24427
- return position === 0 || context.flags.multiline && position > 0 && isLineTerminator(context.input[position - 1]);
24456
+ if (!isMapMethodName(property)) {
24457
+ return void 0;
24428
24458
  }
24429
- return position === context.input.length || context.flags.multiline && position < context.input.length && isLineTerminator(context.input[position]);
24430
- }
24431
- function matchesCharacterClass(character, items, negated, ignoreCase) {
24432
- const matched = items.some((item) => matchesCharacterClassItem(character, item, ignoreCase));
24433
- return negated ? !matched : matched;
24459
+ return createSandboxClosure({
24460
+ sandbox: true,
24461
+ call: (args, context) => callMapMethod(target, property, args, options, context?.stack ?? []),
24462
+ name: property
24463
+ });
24434
24464
  }
24435
- function matchesCharacterClassItem(character, item, ignoreCase) {
24436
- if (item.type === "character") {
24437
- return charactersEqual(character, item.value, ignoreCase);
24438
- }
24439
- if (item.type === "range") {
24440
- const candidate = character.charCodeAt(0);
24441
- const from = item.from.charCodeAt(0);
24442
- const to = item.to.charCodeAt(0);
24443
- if (candidate >= from && candidate <= to) {
24444
- return true;
24465
+ async function callMapMethod(target, methodName, args, options, stack = []) {
24466
+ switch (methodName) {
24467
+ case "get":
24468
+ return target.entries.get(args[0]);
24469
+ case "set": {
24470
+ assertCollectionMutable(target);
24471
+ const exists = target.entries.has(args[0]);
24472
+ const nextSize = exists ? target.entries.size : target.entries.size + 1;
24473
+ options.budget.allocateCollectionEntries(nextSize);
24474
+ if (!exists) updateKeyedCollectionCallbacks(target, "add", args[0]);
24475
+ target.entries.set(args[0], args[1]);
24476
+ return target;
24445
24477
  }
24446
- if (!ignoreCase) {
24447
- return false;
24478
+ case "has":
24479
+ return target.entries.has(args[0]);
24480
+ case "delete": {
24481
+ assertCollectionMutable(target);
24482
+ const deleted = target.entries.delete(args[0]);
24483
+ if (deleted) updateKeyedCollectionCallbacks(target, "delete", args[0]);
24484
+ return deleted;
24448
24485
  }
24449
- const foldedCandidate = foldCharacter(character, true).charCodeAt(0);
24450
- const foldedFrom = foldCharacter(item.from, true).charCodeAt(0);
24451
- const foldedTo = foldCharacter(item.to, true).charCodeAt(0);
24452
- return foldedCandidate >= foldedFrom && foldedCandidate <= foldedTo;
24486
+ case "clear":
24487
+ assertCollectionMutable(target);
24488
+ target.entries.clear();
24489
+ updateKeyedCollectionCallbacks(target, "clear");
24490
+ return void 0;
24491
+ case "forEach": {
24492
+ const callback = args[0];
24493
+ if (!isSandboxClosure(callback)) {
24494
+ throw new TypeError("Map.prototype.forEach requires a callback function.");
24495
+ }
24496
+ const cursor = enterKeyedCollectionCallback(target, target.entries.keys(), options.budget);
24497
+ try {
24498
+ for (let entry = cursor.next(); !entry.done; entry = cursor.next()) {
24499
+ const key = entry.value;
24500
+ const value = target.entries.get(key);
24501
+ await options.callClosure(callback, [value, key, target], stack, args[1]);
24502
+ }
24503
+ } finally {
24504
+ cursor.leave();
24505
+ }
24506
+ return void 0;
24507
+ }
24508
+ case "keys":
24509
+ return allocateProducedSandboxValue([...target.entries.keys()], options.budget);
24510
+ case "values":
24511
+ return allocateProducedSandboxValue([...target.entries.values()], options.budget);
24512
+ case "entries":
24513
+ return allocateProducedSandboxValue(
24514
+ [...target.entries].map(([key, value]) => [key, value]),
24515
+ options.budget
24516
+ );
24453
24517
  }
24454
- const matched = item.kind === "digit" ? isDigit(character) : item.kind === "word" ? isWordCharacter(character) : isSpaceCharacter(character);
24455
- return item.negated ? !matched : matched;
24456
24518
  }
24457
- function toRegexMatch(input, start, state) {
24458
- return {
24459
- index: start,
24460
- text: input.slice(start, state.position),
24461
- captures: state.captures.map(
24462
- (capture) => capture === void 0 ? void 0 : input.slice(capture.start, capture.end)
24463
- )
24464
- };
24519
+
24520
+ // packages/safe-js/src/interp/methods/number.ts
24521
+ var numberMethodNames = /* @__PURE__ */ new Set([
24522
+ "toExponential",
24523
+ "toFixed",
24524
+ "toPrecision",
24525
+ "toString"
24526
+ ]);
24527
+ function getNumberMember(value, property, budget) {
24528
+ if (!isNumberMethodName(property)) {
24529
+ return void 0;
24530
+ }
24531
+ return createSandboxClosure({
24532
+ sandbox: true,
24533
+ name: `Number#${property}`,
24534
+ call: (args) => callNumberMethod(value, property, args, budget)
24535
+ });
24465
24536
  }
24466
- function cloneState(state) {
24467
- return { position: state.position, captures: state.captures.slice() };
24537
+ function isNumberMethodName(property) {
24538
+ return typeof property === "string" && numberMethodNames.has(property);
24468
24539
  }
24469
- function clearCaptures(node, state) {
24470
- const captures = state.captures.slice();
24471
- clearNodeCaptures(node, captures);
24472
- return { position: state.position, captures };
24540
+ function callNumberMethod(value, methodName, args, budget) {
24541
+ return budget.allocateString(callNativeNumberMethod(value, methodName, args));
24473
24542
  }
24474
- function clearNodeCaptures(node, captures) {
24475
- if (node.type === "group") {
24476
- if (node.capturing && node.index !== void 0) {
24477
- captures[node.index - 1] = void 0;
24478
- }
24479
- clearNodeCaptures(node.body, captures);
24480
- return;
24481
- }
24482
- if (node.type === "sequence") {
24483
- for (const element of node.elements) {
24484
- clearNodeCaptures(element, captures);
24485
- }
24486
- return;
24543
+ function callNativeNumberMethod(value, methodName, args) {
24544
+ switch (methodName) {
24545
+ case "toString":
24546
+ return value.toString(asValidatedRadix(args[0]));
24547
+ case "toExponential":
24548
+ return args[0] === void 0 ? value.toExponential() : value.toExponential(asValidatedFractionDigits(args[0], methodName));
24549
+ case "toFixed":
24550
+ return value.toFixed(asValidatedFractionDigits(args[0], methodName));
24551
+ case "toPrecision":
24552
+ return args[0] === void 0 ? value.toPrecision() : value.toPrecision(asValidatedPrecision(args[0]));
24487
24553
  }
24488
- if (node.type === "alternation") {
24489
- for (const alternative of node.alternatives) {
24490
- clearNodeCaptures(alternative, captures);
24491
- }
24492
- return;
24554
+ }
24555
+ function asValidatedRadix(value) {
24556
+ if (value === void 0) {
24557
+ return void 0;
24493
24558
  }
24494
- if (node.type === "quantifier") {
24495
- clearNodeCaptures(node.body, captures);
24559
+ const radix = toIntegerOrInfinity2(value);
24560
+ if (radix < 2 || radix > 36) {
24561
+ throw new RangeError("Number#toString radix must be between 2 and 36.");
24496
24562
  }
24563
+ return radix;
24497
24564
  }
24498
- function charge(context) {
24499
- context.steps += 1;
24500
- allocateRegexSteps(context.steps);
24501
- }
24502
- function normalizeLastIndex(lastIndex) {
24503
- if (!Number.isFinite(lastIndex) || lastIndex <= 0) {
24504
- return 0;
24565
+ function asValidatedFractionDigits(value, methodName) {
24566
+ const digits = toIntegerOrInfinity2(value);
24567
+ if (digits < 0 || digits > 100) {
24568
+ throw new RangeError(`Number#${methodName} digits must be between 0 and 100.`);
24505
24569
  }
24506
- return Math.floor(lastIndex);
24507
- }
24508
- function charactersEqual(left, right, ignoreCase) {
24509
- return left !== void 0 && foldCharacter(left, ignoreCase) === foldCharacter(right, ignoreCase);
24570
+ return digits;
24510
24571
  }
24511
- function foldCharacter(character, ignoreCase) {
24512
- if (!ignoreCase) {
24513
- return character;
24572
+ function asValidatedPrecision(value) {
24573
+ const precision = toIntegerOrInfinity2(value);
24574
+ if (precision < 1 || precision > 100) {
24575
+ throw new RangeError("Number#toPrecision precision must be between 1 and 100.");
24514
24576
  }
24515
- const folded = character.toUpperCase();
24516
- if (folded.length !== 1) {
24517
- return character;
24577
+ return precision;
24578
+ }
24579
+ function toIntegerOrInfinity2(value) {
24580
+ const number = Number(value);
24581
+ if (Number.isNaN(number) || Object.is(number, 0) || Object.is(number, -0)) {
24582
+ return 0;
24518
24583
  }
24519
- if (character.charCodeAt(0) >= 128 && folded.charCodeAt(0) < 128) {
24520
- return character;
24584
+ if (!Number.isFinite(number)) {
24585
+ return number;
24521
24586
  }
24522
- return folded;
24523
- }
24524
- function isDigit(character) {
24525
- return character >= "0" && character <= "9";
24526
- }
24527
- function isWordCharacter(character) {
24528
- return isDigit(character) || character >= "A" && character <= "Z" || character >= "a" && character <= "z" || character === "_";
24529
- }
24530
- function isSpaceCharacter(character) {
24531
- return character === " " || character === "\f" || character === "\n" || character === "\r" || character === " " || character === "\v" || character === "\xA0" || character === "\u1680" || character >= "\u2000" && character <= "\u200A" || character === "\u2028" || character === "\u2029" || character === "\u202F" || character === "\u205F" || character === "\u3000" || character === "\uFEFF";
24532
- }
24533
- function isLineTerminator(character) {
24534
- return character === "\n" || character === "\r" || character === "\u2028" || character === "\u2029";
24587
+ return Math.trunc(number);
24535
24588
  }
24536
24589
 
24537
- // packages/safe-js/src/interp/methods/regex.ts
24538
- var regexMethodNames = /* @__PURE__ */ new Set(["exec", "test"]);
24539
- function isRegexMethodName(property) {
24540
- return typeof property === "string" && regexMethodNames.has(property);
24541
- }
24542
- function getRegexMember(target, property) {
24543
- if (property === "source" || property === "flags" || property === "lastIndex") {
24544
- return target[property];
24545
- }
24546
- if (!isRegexMethodName(property)) {
24590
+ // packages/safe-js/src/interp/methods/generator.ts
24591
+ var generatorMethodNames = /* @__PURE__ */ new Set(["next", "return", "throw"]);
24592
+ function getGeneratorMember(target, property, budget) {
24593
+ if (typeof property !== "string" || !generatorMethodNames.has(property)) {
24547
24594
  return void 0;
24548
24595
  }
24549
24596
  return createSandboxClosure({
24550
24597
  sandbox: true,
24551
- name: `RegExp#${property}`,
24552
- call: (args) => callRegexMethod(target, property, args)
24598
+ name: property,
24599
+ call: async ([value]) => {
24600
+ const iterator = getSandboxIterator(target);
24601
+ const result = await iterator[property](value);
24602
+ return allocateProducedSandboxValue(
24603
+ { value: result.value, done: result.done === true },
24604
+ budget
24605
+ );
24606
+ }
24553
24607
  });
24554
24608
  }
24555
- function setRegexMember(target, property, value) {
24556
- if (property !== "lastIndex") {
24557
- throw new TypeError(`RegExp#${String(property)} is not writable.`);
24558
- }
24559
- target.lastIndex = Number(value);
24560
- }
24561
- function callRegexMethod(target, methodName, args) {
24562
- const match = executeRegex(target, String(args[0]));
24563
- return methodName === "test" ? match !== null : toMatchArray(match, String(args[0]));
24564
- }
24565
- function executeRegex(target, input) {
24566
- const pattern = getSandboxRegexPattern(target);
24567
- const match = matchRegex(pattern, input, target.lastIndex);
24568
- if (pattern.flags.global) {
24569
- target.lastIndex = match === null ? 0 : match.index + match.text.length;
24570
- }
24571
- return match;
24572
- }
24573
- function toMatchArray(match, input) {
24574
- if (match === null) {
24575
- return null;
24576
- }
24577
- const result = [match.text, ...match.captures];
24578
- Object.assign(result, { index: match.index, input, groups: void 0 });
24579
- return result;
24580
- }
24581
24609
 
24582
24610
  // packages/safe-js/src/interp/methods/string.ts
24583
24611
  var SPLIT_STRING_MESSAGE = "String#split only supports string separator values.";
@@ -27488,7 +27516,7 @@ function getPropertyValue(target, property, context) {
27488
27516
  if (isSandboxGenerator(target)) return getGeneratorMember(target, property, context.budget);
27489
27517
  if (isSandboxClosure(target)) return getClosureMemberValue(target, property, context);
27490
27518
  if (isSandboxPromise(target)) return getPromiseMember(property, context.budget);
27491
- if (isSandboxRegex(target)) return getRegexMember(target, property);
27519
+ if (isSandboxRegex(target)) return getRegexMember(target, property, context.budget);
27492
27520
  if (!isIndexableSandboxValue(target)) {
27493
27521
  throw new TypeError("Attempted to read a property from a non-object value.");
27494
27522
  }
@@ -27753,7 +27781,7 @@ async function evaluateMemberCallExpression(node, context) {
27753
27781
  if (isSandboxRegex(member.object) && isRegexMethodName(member.property)) {
27754
27782
  return evaluateResolvedCallExpression(
27755
27783
  node,
27756
- getRegexMember(member.object, member.property),
27784
+ getRegexMember(member.object, member.property, context.budget),
27757
27785
  context,
27758
27786
  member.object
27759
27787
  );
@@ -32866,4 +32894,4 @@ export {
32866
32894
  FileSnapshotBackend,
32867
32895
  run
32868
32896
  };
32869
- //# sourceMappingURL=chunk-M4M56OCI.js.map
32897
+ //# sourceMappingURL=chunk-774EXZKX.js.map