@poe-platform/safe-js 0.1.170 → 0.1.171

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.
@@ -27,7 +27,7 @@ import {
27
27
  validateMigrationSemantics,
28
28
  validateSnapshotData,
29
29
  validateSnapshotMigration
30
- } from "./chunk-WPI4GGVU.js";
30
+ } from "./chunk-XKCTB5FR.js";
31
31
 
32
32
  // packages/safe-js/src/migrate.ts
33
33
  import { createHash } from "node:crypto";
@@ -8249,4 +8249,4 @@ export {
8249
8249
  parseMcpConfig,
8250
8250
  makeMcpModule
8251
8251
  };
8252
- //# sourceMappingURL=chunk-MZW43CYT.js.map
8252
+ //# sourceMappingURL=chunk-OUFC6W7G.js.map
@@ -9955,6 +9955,9 @@ function formatNumber(value, methodName, argument, budget) {
9955
9955
  return budget.allocateString(result);
9956
9956
  }
9957
9957
 
9958
+ // packages/safe-js/src/interp/methods/string.ts
9959
+ import { types as types6 } from "node:util";
9960
+
9958
9961
  // packages/safe-js/src/interp/regex/engine.ts
9959
9962
  function matchRegex(pattern, input, lastIndex = 0) {
9960
9963
  const startIndex = pattern.flags.global ? normalizeLastIndex(lastIndex) : 0;
@@ -10382,15 +10385,39 @@ function callStringMethod(value, methodName, args, budget, callClosure = async (
10382
10385
  if (value === null || value === void 0)
10383
10386
  throw new TypeError(`String#${methodName} requires a non-null receiver.`);
10384
10387
  const fallback = () => typeof value === "string" ? callStringMethodBody(value, methodName, args, budget, callClosure, parent, context) : Promise.resolve(sandboxString(value, budget, context)).then((string) => callStringMethodBody(string, methodName, args, budget, callClosure, parent, context));
10385
- const symbol = methodName === "match" ? Symbol.match : methodName === "search" ? Symbol.search : methodName === "split" ? Symbol.split : void 0;
10388
+ const symbol = methodName === "match" ? Symbol.match : methodName === "search" ? Symbol.search : methodName === "matchAll" ? Symbol.matchAll : methodName === "replace" || methodName === "replaceAll" ? Symbol.replace : methodName === "split" ? Symbol.split : void 0;
10386
10389
  const pattern = args[0];
10390
+ if (symbol !== void 0 && types6.isRegExp(pattern))
10391
+ throw new TypeError(`String#${methodName} does not accept unbranded host RegExp values.`);
10387
10392
  if (symbol === void 0 || pattern === null || pattern === void 0) return fallback();
10388
10393
  const applyHook = (hook) => {
10389
10394
  if (hook === null || hook === void 0) return fallback();
10390
10395
  if (!isSandboxClosure(hook)) throw new TypeError(`String#${methodName} symbol hook must be callable.`);
10391
- return invokeBuiltinClosure(hook, methodName === "split" ? [value, args[1]] : [value], budget, context, pattern);
10396
+ return invokeBuiltinClosure(hook, symbol === Symbol.split || symbol === Symbol.replace ? [value, args[1]] : [value], budget, context, pattern);
10392
10397
  };
10393
- return context?.getProperty !== void 0 ? Promise.resolve(context.getProperty(pattern, symbol)).then(applyHook) : applyHook(getSandboxDataProperty(pattern, symbol, budget));
10398
+ const readProperty = (key) => context?.getProperty !== void 0 ? context.getProperty(pattern, key) : key === "flags" && isSandboxRegex(pattern) && getSandboxPropertyDescriptor(pattern, key, budget) === void 0 ? pattern.flags : getSandboxDataProperty(pattern, key, budget);
10399
+ const dispatch = () => {
10400
+ const hook = readProperty(symbol);
10401
+ return hook instanceof Promise ? hook.then(applyHook) : applyHook(hook);
10402
+ };
10403
+ if ((methodName === "replaceAll" || methodName === "matchAll") && (typeof pattern === "object" || typeof pattern === "function")) {
10404
+ const checkFlags = (flags) => {
10405
+ const checkText = (text2) => {
10406
+ if (!text2.includes("g")) throw new TypeError(`String#${methodName} requires a global regex.`);
10407
+ return dispatch();
10408
+ };
10409
+ const text = sandboxString(flags, budget, context);
10410
+ return typeof text === "string" ? checkText(text) : text.then(checkText);
10411
+ };
10412
+ const checkMatch = (match2) => {
10413
+ if (!(match2 === void 0 ? isSandboxRegex(pattern) : Boolean(match2))) return dispatch();
10414
+ const flags = readProperty("flags");
10415
+ return flags instanceof Promise ? flags.then(checkFlags) : checkFlags(flags);
10416
+ };
10417
+ const match = readProperty(Symbol.match);
10418
+ return match instanceof Promise ? match.then(checkMatch) : checkMatch(match);
10419
+ }
10420
+ return dispatch();
10394
10421
  }
10395
10422
  function callStringMethodBody(value, methodName, args, budget, callClosure = async (closure, closureArgs) => await closure.call(closureArgs), parent, context) {
10396
10423
  if (methodName === "concat" && args.some((argument) => argument !== null && typeof argument === "object")) {
@@ -10435,7 +10462,7 @@ function callStringMethodBody(value, methodName, args, budget, callClosure = asy
10435
10462
  return callReplaceLikeMethod(value, methodName, args, budget, callClosure, context);
10436
10463
  }
10437
10464
  const regex = args[0];
10438
- if (isSandboxRegex(regex) && regex.lastIndex !== null && typeof regex.lastIndex === "object" && (methodName === "match" && !regex.flags.includes("g") || methodName === "matchAll" && regex.flags.includes("g"))) {
10465
+ if (isSandboxRegex(regex) && regex.lastIndex !== null && typeof regex.lastIndex === "object" && (methodName === "match" && !regex.flags.includes("g") || methodName === "matchAll")) {
10439
10466
  return callStringRegexCursor(value, methodName, regex, budget, parent, context);
10440
10467
  }
10441
10468
  if ((methodName === "match" || methodName === "matchAll" || methodName === "search") && !isSandboxRegex(args[0])) {
@@ -10567,20 +10594,26 @@ async function callConcat(value, args, budget, context) {
10567
10594
  function callReplaceLikeMethod(value, methodName, args, budget, callClosure, context) {
10568
10595
  const search = args[0];
10569
10596
  const replacement = args[1];
10570
- if (!isSandboxRegex(search) && typeof search !== "string" || typeof replacement !== "string" && !isSandboxClosure(replacement)) {
10571
- throw new TypeError(
10572
- `String#${methodName} only supports string or regex search values and string or function replacements.`
10573
- );
10597
+ const useRegex = isSandboxRegex(search) && getSandboxPropertyDescriptor(search, Symbol.replace, budget) === void 0;
10598
+ if (!useRegex && typeof search !== "string" || typeof replacement !== "string" && !isSandboxClosure(replacement)) {
10599
+ return (async () => {
10600
+ let normalizedSearch;
10601
+ let normalizedReplacement;
10602
+ const release = retainValues(budget, () => [normalizedSearch, normalizedReplacement]);
10603
+ try {
10604
+ normalizedSearch = useRegex ? search : await sandboxString(search, budget, context);
10605
+ normalizedReplacement = isSandboxClosure(replacement) ? replacement : await sandboxString(replacement, budget, context);
10606
+ return await callReplaceLikeMethod(value, methodName, [normalizedSearch, normalizedReplacement], budget, callClosure, context);
10607
+ } finally {
10608
+ release();
10609
+ }
10610
+ })();
10574
10611
  }
10575
10612
  if (isSandboxRegex(search)) {
10576
- if (methodName === "replaceAll" && !search.flags.includes("g")) {
10577
- throw new TypeError("String#replaceAll requires a global regex.");
10578
- }
10579
10613
  return replaceRegex(
10580
10614
  value,
10581
10615
  search,
10582
10616
  replacement,
10583
- methodName === "replaceAll",
10584
10617
  budget,
10585
10618
  callClosure,
10586
10619
  context
@@ -10600,14 +10633,14 @@ function callReplaceLikeMethod(value, methodName, args, budget, callClosure, con
10600
10633
  callClosure
10601
10634
  );
10602
10635
  }
10603
- async function replaceRegex(value, regex, replacement, replaceAll, budget, callClosure, context) {
10636
+ async function replaceRegex(value, regex, replacement, budget, callClosure, context) {
10604
10637
  if (regex.flags.includes("g")) regex.lastIndex = 0;
10605
10638
  const cursor = regex.lastIndex;
10606
10639
  const retained = {};
10607
10640
  budget.setRetainedValues(retained, () => [value, regex, cursor, replacement]);
10608
10641
  try {
10609
10642
  const lastIndex = await sandboxNumber(cursor, budget, context);
10610
- const matches = collectRegexMatches(regex, value, replaceAll || regex.flags.includes("g"), void 0, lastIndex);
10643
+ const matches = collectRegexMatches(regex, value, regex.flags.includes("g"), void 0, lastIndex);
10611
10644
  let result = "";
10612
10645
  let copiedThrough = 0;
10613
10646
  for (const match of matches) {
@@ -10774,13 +10807,11 @@ function callMatchLikeMethod(value, methodName, args, compilation, lastIndex) {
10774
10807
  if (!Object.is(regex.lastIndex, lastIndex2)) regex.lastIndex = lastIndex2;
10775
10808
  return match?.index ?? -1;
10776
10809
  }
10777
- if (methodName === "matchAll" && !regex.flags.includes("g"))
10778
- throw new TypeError("String#matchAll requires a global regex.");
10779
10810
  if (methodName === "match" && !regex.flags.includes("g"))
10780
10811
  return toMatchArray(executeRegex(regex, value, lastIndex ?? Number(regex.lastIndex)), value);
10781
10812
  if (methodName === "match") regex.lastIndex = 0;
10782
10813
  const matcher = methodName === "matchAll" ? createSandboxRegex(regex.source, regex.flags, normalizeLastIndex(lastIndex ?? Number(regex.lastIndex)), compilation) : regex;
10783
- const matches = collectRegexMatches(matcher, value, true, compilation.owner?.budget, Number(matcher.lastIndex));
10814
+ const matches = collectRegexMatches(matcher, value, matcher.flags.includes("g"), compilation.owner?.budget, Number(matcher.lastIndex));
10784
10815
  if (methodName === "match" && matches.length === 0) return null;
10785
10816
  return methodName === "match" ? matches.map((match) => match.text) : matches.map((match) => toMatchArray(match, value));
10786
10817
  }
@@ -33500,7 +33531,7 @@ function createReplayableRandom(options = {}) {
33500
33531
 
33501
33532
  // packages/safe-js/src/realm.ts
33502
33533
  import { AsyncLocalStorage as AsyncLocalStorage6 } from "node:async_hooks";
33503
- import { types as types6 } from "node:util";
33534
+ import { types as types7 } from "node:util";
33504
33535
 
33505
33536
  // packages/safe-js/src/interp/globals/console-json.ts
33506
33537
  function createConsoleJsonGlobals(options) {
@@ -34179,7 +34210,7 @@ var RealmState = class {
34179
34210
  throw new TypeError("Realm limits must be positive safe integers with supported names.");
34180
34211
  this.limits[name] = Number(value);
34181
34212
  }
34182
- if (options.extensions !== void 0 && (!Array.isArray(options.extensions) || types6.isProxy(options.extensions)))
34213
+ if (options.extensions !== void 0 && (!Array.isArray(options.extensions) || types7.isProxy(options.extensions)))
34183
34214
  throw new TypeError("Extensions must be a registration array.");
34184
34215
  const registrations = options.extensions ?? [];
34185
34216
  const extensions = [];
@@ -34414,7 +34445,7 @@ var RealmState = class {
34414
34445
  return this.phase.run(phase, () => {
34415
34446
  try {
34416
34447
  const result = call();
34417
- if (types6.isPromise(result) || phase.pending.size > 0 || phase.failure !== void 0) {
34448
+ if (types7.isPromise(result) || phase.pending.size > 0 || phase.failure !== void 0) {
34418
34449
  return Promise.resolve(result).then(
34419
34450
  async (value) => {
34420
34451
  await Promise.allSettled(phase.pending);
@@ -34483,7 +34514,7 @@ var RealmState = class {
34483
34514
  },
34484
34515
  read: (operation, validate) => {
34485
34516
  const value = this.invokeHost(operation, operation);
34486
- if (types6.isPromise(value)) {
34517
+ if (types7.isPromise(value)) {
34487
34518
  void Promise.resolve(value).catch(() => void 0);
34488
34519
  throw new TypeError("Live property operations must be synchronous.");
34489
34520
  }
@@ -34491,7 +34522,7 @@ var RealmState = class {
34491
34522
  },
34492
34523
  write: (operation, value) => {
34493
34524
  const result = this.invokeHost(operation, () => operation(this.exportValue(value)));
34494
- if (types6.isPromise(result)) {
34525
+ if (types7.isPromise(result)) {
34495
34526
  void Promise.resolve(result).catch(() => void 0);
34496
34527
  throw new TypeError("Live property setters must be synchronous.");
34497
34528
  }
@@ -34700,7 +34731,7 @@ var RealmState = class {
34700
34731
  }
34701
34732
  });
34702
34733
  const output = getExtensionSetup(extension)(context);
34703
- if (types6.isPromise(output)) {
34734
+ if (types7.isPromise(output)) {
34704
34735
  void Promise.resolve(output).catch(() => void 0);
34705
34736
  throw new TypeError("Extension setup must be synchronous.");
34706
34737
  }
@@ -34892,7 +34923,7 @@ var RealmState = class {
34892
34923
  };
34893
34924
  function readModules(input) {
34894
34925
  const entries = (value, label) => {
34895
- if (types6.isMap(value) && !types6.isProxy(value)) {
34926
+ if (types7.isMap(value) && !types7.isProxy(value)) {
34896
34927
  const result = [...Map.prototype.entries.call(value)];
34897
34928
  if (result.length > 4096 || result.some(([key]) => typeof key !== "string" || key.length === 0))
34898
34929
  throw new TypeError(`${label} requires bounded string keys.`);
@@ -36148,4 +36179,4 @@ export {
36148
36179
  FileSnapshotBackend,
36149
36180
  run
36150
36181
  };
36151
- //# sourceMappingURL=chunk-WPI4GGVU.js.map
36182
+ //# sourceMappingURL=chunk-XKCTB5FR.js.map