@poe-platform/safe-js 0.1.114 → 0.1.116

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-DVWTNFTV.js";
30
+ } from "./chunk-VDFW3EKS.js";
31
31
 
32
32
  // packages/safe-js/src/migrate.ts
33
33
  import { createHash } from "node:crypto";
@@ -8245,4 +8245,4 @@ export {
8245
8245
  parseMcpConfig,
8246
8246
  makeMcpModule
8247
8247
  };
8248
- //# sourceMappingURL=chunk-7Z6HCXET.js.map
8248
+ //# sourceMappingURL=chunk-3R3FX4C5.js.map
@@ -23827,6 +23827,7 @@ function hoistVarDeclarations(node, scope) {
23827
23827
  }
23828
23828
 
23829
23829
  // packages/safe-js/src/interp/methods/array.ts
23830
+ var arrayLikeSources = /* @__PURE__ */ new WeakMap();
23830
23831
  var activeArrayCallbacks = /* @__PURE__ */ new WeakMap();
23831
23832
  var arrayMethodNames = /* @__PURE__ */ new Set([
23832
23833
  "map",
@@ -23878,7 +23879,7 @@ function getArrayMember(value, property, options) {
23878
23879
  return createSandboxClosure({
23879
23880
  sandbox: true,
23880
23881
  name: `Array#${property}`,
23881
- call: (args, context) => callArrayMethod(value, property, args, options, context?.stack ?? [])
23882
+ call: (args, context) => callArrayMethod(context?.thisValue, property, args, { ...options, context }, context?.stack ?? [])
23882
23883
  });
23883
23884
  }
23884
23885
  return void 0;
@@ -23893,28 +23894,75 @@ function getArrayIndex(property) {
23893
23894
  function isArrayMethodName(property) {
23894
23895
  return typeof property === "string" && arrayMethodNames.has(property);
23895
23896
  }
23896
- async function callArrayMethod(value, methodName, args, options, stack = []) {
23897
- if (isMutatingArrayMethod(methodName)) {
23898
- assertCollectionMutable(value);
23899
- }
23900
- if (isCallbackArrayMethod(methodName)) {
23901
- let callbackState = activeArrayCallbacks.get(value);
23902
- if (callbackState === void 0) {
23903
- callbackState = { depth: 0, leave: enterRunningState(value) };
23904
- activeArrayCallbacks.set(value, callbackState);
23897
+ async function callArrayMethod(receiver, methodName, args, options, stack = []) {
23898
+ if (receiver === null || receiver === void 0) throw new TypeError("Array method requires a receiver.");
23899
+ if (typeof receiver !== "object") throw new TypeError("Object primitive boxing is not supported.");
23900
+ const retainedReceiver = {};
23901
+ options.budget.setRetainedValues(retainedReceiver, () => [receiver]);
23902
+ try {
23903
+ const value = Array.isArray(receiver) || methodName === "concat" ? receiver : await arrayLikeView(receiver, options);
23904
+ if (isMutatingArrayMethod(methodName)) {
23905
+ assertCollectionMutable(receiver);
23905
23906
  }
23906
- callbackState.depth += 1;
23907
- try {
23908
- return await callArrayMethodUnlocked(value, methodName, args, options, stack);
23909
- } finally {
23910
- callbackState.depth -= 1;
23911
- if (callbackState.depth === 0) {
23912
- activeArrayCallbacks.delete(value);
23913
- callbackState.leave();
23907
+ if (isCallbackArrayMethod(methodName)) {
23908
+ let callbackState = activeArrayCallbacks.get(receiver);
23909
+ if (callbackState === void 0) {
23910
+ callbackState = { depth: 0, leave: enterRunningState(receiver) };
23911
+ activeArrayCallbacks.set(receiver, callbackState);
23912
+ }
23913
+ callbackState.depth += 1;
23914
+ try {
23915
+ const result2 = await callArrayMethodUnlocked(value, methodName, args, options, stack);
23916
+ return result2 === value ? receiver : result2;
23917
+ } finally {
23918
+ callbackState.depth -= 1;
23919
+ if (callbackState.depth === 0) {
23920
+ activeArrayCallbacks.delete(receiver);
23921
+ callbackState.leave();
23922
+ }
23914
23923
  }
23915
23924
  }
23925
+ const result = await callArrayMethodUnlocked(value, methodName, args, options, stack);
23926
+ return result === value ? receiver : result;
23927
+ } finally {
23928
+ options.budget.setRetainedValues(retainedReceiver, void 0);
23916
23929
  }
23917
- return callArrayMethodUnlocked(value, methodName, args, options, stack);
23930
+ }
23931
+ async function arrayLikeView(receiver, options) {
23932
+ const rawLength = options.context?.getProperty !== void 0 ? options.context.getProperty(receiver, "length") : getSandboxDataProperty(receiver, "length", options.budget);
23933
+ const number = await sandboxNumber(rawLength, options.budget, options.context);
23934
+ const length = Number.isNaN(number) || number <= 0 ? 0 : Math.min(Math.trunc(number), Number.MAX_SAFE_INTEGER);
23935
+ const view = new Proxy(/* @__PURE__ */ Object.create(null), {
23936
+ get: (_target, key) => {
23937
+ options.budget.visitNode();
23938
+ if (key === "length") return length;
23939
+ if (typeof key !== "string") return void 0;
23940
+ return options.context?.getProperty !== void 0 ? options.context.getProperty(receiver, key) : getSandboxDataProperty(receiver, key, options.budget);
23941
+ },
23942
+ has: (_target, key) => {
23943
+ options.budget.visitNode();
23944
+ if (typeof key === "string" && options.hasProperty !== void 0) return options.hasProperty(receiver, key);
23945
+ for (let current = receiver; current !== null; current = getSandboxPrototype(current, options.budget)) {
23946
+ options.budget.visitNode();
23947
+ if (Object.hasOwn(current, key)) return true;
23948
+ }
23949
+ return false;
23950
+ },
23951
+ set: (_target, key, entry) => {
23952
+ options.budget.visitNode();
23953
+ if (typeof key !== "string") throw new TypeError("Array indices must be string keys.");
23954
+ if (options.setProperty !== void 0) options.setProperty(receiver, key, entry);
23955
+ else if (!Reflect.set(receiver, key, entry)) throw new TypeError(`Cannot assign property '${key}'.`);
23956
+ return true;
23957
+ },
23958
+ deleteProperty: (_target, key) => {
23959
+ options.budget.visitNode();
23960
+ if (typeof key === "string" && options.deleteProperty !== void 0) return options.deleteProperty(receiver, key);
23961
+ return Reflect.deleteProperty(receiver, key);
23962
+ }
23963
+ });
23964
+ arrayLikeSources.set(view, receiver);
23965
+ return view;
23918
23966
  }
23919
23967
  async function callArrayMethodUnlocked(value, methodName, args, options, stack) {
23920
23968
  switch (methodName) {
@@ -24027,11 +24075,21 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
24027
24075
  return Reflect.apply(Array.prototype.lastIndexOf, value, [...args]);
24028
24076
  case "join":
24029
24077
  return options.budget.allocateString(Reflect.apply(Array.prototype.join, value, [...args]));
24030
- case "slice":
24031
- return budgetProducedValue(
24032
- Reflect.apply(Array.prototype.slice, value, [...args]),
24033
- options.budget
24034
- );
24078
+ case "slice": {
24079
+ const length = value.length;
24080
+ const start = toIntegerOrInfinity(await sandboxNumber(args[0], options.budget, options.context));
24081
+ const end = args[1] === void 0 ? length : toIntegerOrInfinity(await sandboxNumber(args[1], options.budget, options.context));
24082
+ const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
24083
+ const final = end < 0 ? Math.max(length + end, 0) : Math.min(end, length);
24084
+ const count = Math.max(final - first, 0);
24085
+ options.budget.allocateArrayLength(count);
24086
+ const result = new Array(count);
24087
+ for (let index = 0; index < count; index += 1) {
24088
+ options.budget.visitNode();
24089
+ if (first + index in value) result[index] = value[first + index];
24090
+ }
24091
+ return budgetProducedValue(result, options.budget);
24092
+ }
24035
24093
  case "concat":
24036
24094
  return budgetProducedValue(
24037
24095
  Reflect.apply(Array.prototype.concat, value, [...args]),
@@ -24058,7 +24116,7 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
24058
24116
  );
24059
24117
  case "sort":
24060
24118
  if (args[0] === void 0) {
24061
- value.sort();
24119
+ Reflect.apply(Array.prototype.sort, value, []);
24062
24120
  budgetProducedValue(value, options.budget);
24063
24121
  return value;
24064
24122
  }
@@ -24066,11 +24124,17 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
24066
24124
  budgetProducedValue(value, options.budget);
24067
24125
  return value;
24068
24126
  case "reverse":
24069
- value.reverse();
24127
+ Reflect.apply(Array.prototype.reverse, value, []);
24070
24128
  budgetProducedValue(value, options.budget);
24071
24129
  return value;
24072
24130
  case "toSorted": {
24073
- const result = Array.from(value);
24131
+ const length = value.length;
24132
+ options.budget.allocateArrayLength(length);
24133
+ const result = new Array(length);
24134
+ for (let index = 0; index < length; index += 1) {
24135
+ options.budget.visitNode();
24136
+ result[index] = value[index];
24137
+ }
24074
24138
  if (args[0] === void 0) {
24075
24139
  result.sort();
24076
24140
  } else {
@@ -24079,13 +24143,29 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
24079
24143
  return budgetProducedValue(result, options.budget);
24080
24144
  }
24081
24145
  case "toReversed": {
24082
- const result = Array.from(value);
24083
- result.reverse();
24146
+ const length = value.length;
24147
+ options.budget.allocateArrayLength(length);
24148
+ const result = new Array(length);
24149
+ for (let index = 0; index < length; index += 1) {
24150
+ options.budget.visitNode();
24151
+ result[index] = value[length - index - 1];
24152
+ }
24084
24153
  return budgetProducedValue(result, options.budget);
24085
24154
  }
24086
24155
  case "toSpliced": {
24087
- const result = Array.from(value);
24088
- Reflect.apply(Array.prototype.splice, result, [...args]);
24156
+ const length = value.length;
24157
+ const start = toIntegerOrInfinity(await sandboxNumber(args[0], options.budget, options.context));
24158
+ const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
24159
+ const inserted = Math.max(args.length - 2, 0);
24160
+ const deleted = args.length === 0 ? 0 : args.length === 1 ? length - first : Math.min(Math.max(toIntegerOrInfinity(await sandboxNumber(args[1], options.budget, options.context)), 0), length - first);
24161
+ const resultLength = length + inserted - deleted;
24162
+ if (resultLength > Number.MAX_SAFE_INTEGER) throw new TypeError("Array-like length exceeds the safe integer limit.");
24163
+ options.budget.allocateArrayLength(resultLength);
24164
+ const result = new Array(resultLength);
24165
+ for (let index = 0; index < resultLength; index += 1) {
24166
+ options.budget.visitNode();
24167
+ result[index] = index < first ? value[index] : index < first + inserted ? args[index - first + 2] : value[index - inserted + deleted];
24168
+ }
24089
24169
  return budgetProducedValue(result, options.budget);
24090
24170
  }
24091
24171
  case "with": {
@@ -24099,39 +24179,42 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
24099
24179
  const result = [];
24100
24180
  for (let position = 0; position < length; position += 1) {
24101
24181
  options.budget.visitNode();
24102
- result[position] = position === actualIndex ? args[1] : Object.hasOwn(value, position) ? value[position] : void 0;
24182
+ result[position] = position === actualIndex ? args[1] : Array.isArray(value) && !Object.hasOwn(value, position) ? void 0 : value[position];
24103
24183
  }
24104
24184
  return budgetProducedValue(result, options.budget);
24105
24185
  }
24106
24186
  case "push": {
24107
- appendArrayValues(value, args);
24108
- const nextLength = value.length;
24187
+ const nextLength = appendArrayValues(value, args);
24109
24188
  budgetProducedValue(value, options.budget);
24110
24189
  return nextLength;
24111
24190
  }
24112
24191
  case "pop":
24113
- return budgetProducedValue(value.pop(), options.budget);
24192
+ return budgetProducedValue(Reflect.apply(Array.prototype.pop, value, []), options.budget);
24114
24193
  case "shift":
24115
- return budgetProducedValue(value.shift(), options.budget);
24194
+ return budgetProducedValue(Reflect.apply(Array.prototype.shift, value, []), options.budget);
24116
24195
  case "unshift": {
24117
- prependArrayValues(value, args);
24118
- const nextLength = value.length;
24196
+ const nextLength = prependArrayValues(value, args);
24119
24197
  budgetProducedValue(value, options.budget);
24120
24198
  return nextLength;
24121
24199
  }
24122
24200
  }
24123
24201
  }
24124
24202
  function appendArrayValues(target, values) {
24203
+ let length = target.length;
24204
+ if (length + values.length > Number.MAX_SAFE_INTEGER) throw new TypeError("Array-like length exceeds the safe integer limit.");
24125
24205
  for (const value of values) {
24126
- target.push(value);
24206
+ target[length++] = value;
24127
24207
  }
24208
+ target.length = length;
24209
+ return length;
24128
24210
  }
24129
24211
  function prependArrayValues(target, values) {
24130
24212
  const originalLength = target.length;
24131
- target.length = originalLength + values.length;
24132
- for (let index = originalLength - 1; index >= 0; index -= 1) {
24213
+ const length = originalLength + values.length;
24214
+ if (length > Number.MAX_SAFE_INTEGER) throw new TypeError("Array-like length exceeds the safe integer limit.");
24215
+ for (let index = values.length === 0 ? -1 : originalLength - 1; index >= 0; index -= 1) {
24133
24216
  const targetIndex = index + values.length;
24134
- if (Object.hasOwn(target, index)) {
24217
+ if (index in target) {
24135
24218
  target[targetIndex] = target[index];
24136
24219
  } else {
24137
24220
  delete target[targetIndex];
@@ -24140,6 +24223,8 @@ function prependArrayValues(target, values) {
24140
24223
  for (let index = 0; index < values.length; index += 1) {
24141
24224
  target[index] = values[index];
24142
24225
  }
24226
+ target.length = length;
24227
+ return length;
24143
24228
  }
24144
24229
  function isCallbackArrayMethod(methodName) {
24145
24230
  return methodName === "map" || methodName === "filter" || methodName === "find" || methodName === "findIndex" || methodName === "findLast" || methodName === "findLastIndex" || methodName === "some" || methodName === "every" || methodName === "reduce" || methodName === "reduceRight" || methodName === "forEach" || methodName === "flatMap" || methodName === "sort";
@@ -24155,6 +24240,7 @@ function getRequiredCallback(methodName, value) {
24155
24240
  }
24156
24241
  async function mapArray(value, callback, options, stack, thisValue) {
24157
24242
  const length = value.length;
24243
+ options.budget.allocateArrayLength(length);
24158
24244
  const result = new Array(length);
24159
24245
  options.budget.setRetainedValues(result, () => [result]);
24160
24246
  try {
@@ -24300,7 +24386,7 @@ async function reduceFromLeft(value, callback, accumulator, startIndex, length,
24300
24386
  if (!(index in value)) {
24301
24387
  continue;
24302
24388
  }
24303
- current = await options.callClosure(callback, [current, value[index], index, value], stack);
24389
+ current = await options.callClosure(callback, [current, value[index], index, arrayLikeSources.get(value) ?? value], stack);
24304
24390
  }
24305
24391
  return current;
24306
24392
  } finally {
@@ -24317,7 +24403,7 @@ async function reduceFromRight(value, callback, accumulator, startIndex, length,
24317
24403
  if (!(index in value)) {
24318
24404
  continue;
24319
24405
  }
24320
- current = await options.callClosure(callback, [current, value[index], index, value], stack);
24406
+ current = await options.callClosure(callback, [current, value[index], index, arrayLikeSources.get(value) ?? value], stack);
24321
24407
  }
24322
24408
  return current;
24323
24409
  } finally {
@@ -24440,7 +24526,7 @@ async function compareEntries(left, right, comparator, options, stack) {
24440
24526
  return Number.isNaN(result) ? 0 : result;
24441
24527
  }
24442
24528
  async function callArrayCallback(callback, value, index, array, options, stack, thisValue) {
24443
- return options.callClosure(callback, [value, index, array], stack, thisValue);
24529
+ return options.callClosure(callback, [value, index, arrayLikeSources.get(array) ?? array], stack, thisValue);
24444
24530
  }
24445
24531
  function findNextDefinedIndex(value, startIndex, direction, length, budget) {
24446
24532
  for (let index = startIndex; direction > 0 ? index < length : index >= 0; index += direction) {
@@ -24452,6 +24538,7 @@ function findNextDefinedIndex(value, startIndex, direction, length, budget) {
24452
24538
  return -1;
24453
24539
  }
24454
24540
  function budgetProducedValue(value, budget) {
24541
+ if (typeof value === "object" && value !== null) value = arrayLikeSources.get(value) ?? value;
24455
24542
  allocateProducedValue(value, budget, /* @__PURE__ */ new WeakSet());
24456
24543
  return value;
24457
24544
  }
@@ -24739,63 +24826,42 @@ function getNumberMember(property, budget) {
24739
24826
  return createSandboxClosure({
24740
24827
  sandbox: true,
24741
24828
  name: `Number#${property}`,
24742
- call: (args, context) => callNumberMethod(context?.thisValue, property, args, budget)
24829
+ call: (args, context) => callNumberMethod(context?.thisValue, property, args, budget, context)
24743
24830
  });
24744
24831
  }
24745
24832
  function isNumberMethodName(property) {
24746
24833
  return typeof property === "string" && numberMethodNames.has(property);
24747
24834
  }
24748
- function callNumberMethod(value, methodName, args, budget) {
24835
+ function callNumberMethod(value, methodName, args, budget, context) {
24749
24836
  if (typeof value !== "number") {
24750
24837
  throw new TypeError(`Number#${methodName} requires a number receiver.`);
24751
24838
  }
24752
- return budget.allocateString(callNativeNumberMethod(value, methodName, args));
24753
- }
24754
- function callNativeNumberMethod(value, methodName, args) {
24755
- switch (methodName) {
24756
- case "toString":
24757
- return value.toString(asValidatedRadix(args[0]));
24758
- case "toExponential":
24759
- return args[0] === void 0 ? value.toExponential() : value.toExponential(asValidatedFractionDigits(args[0], methodName));
24760
- case "toFixed":
24761
- return value.toFixed(asValidatedFractionDigits(args[0], methodName));
24762
- case "toPrecision":
24763
- return args[0] === void 0 ? value.toPrecision() : value.toPrecision(asValidatedPrecision(args[0]));
24839
+ const argument = args[0];
24840
+ if (argument !== null && typeof argument === "object") {
24841
+ return formatObjectArgument(value, methodName, argument, budget, context);
24764
24842
  }
24843
+ return formatNumber(value, methodName, argument === void 0 ? void 0 : Number(argument), budget);
24765
24844
  }
24766
- function asValidatedRadix(value) {
24767
- if (value === void 0) {
24768
- return void 0;
24769
- }
24770
- const radix = toIntegerOrInfinity2(value);
24771
- if (radix < 2 || radix > 36) {
24772
- throw new RangeError("Number#toString radix must be between 2 and 36.");
24773
- }
24774
- return radix;
24775
- }
24776
- function asValidatedFractionDigits(value, methodName) {
24777
- const digits = toIntegerOrInfinity2(value);
24778
- if (digits < 0 || digits > 100) {
24779
- throw new RangeError(`Number#${methodName} digits must be between 0 and 100.`);
24780
- }
24781
- return digits;
24782
- }
24783
- function asValidatedPrecision(value) {
24784
- const precision = toIntegerOrInfinity2(value);
24785
- if (precision < 1 || precision > 100) {
24786
- throw new RangeError("Number#toPrecision precision must be between 1 and 100.");
24845
+ async function formatObjectArgument(value, methodName, argument, budget, context) {
24846
+ const retainedArgument = {};
24847
+ budget.setRetainedValues(retainedArgument, () => [argument]);
24848
+ try {
24849
+ const number = await sandboxNumber(argument, budget, context);
24850
+ return formatNumber(value, methodName, number, budget);
24851
+ } finally {
24852
+ budget.setRetainedValues(retainedArgument, void 0);
24787
24853
  }
24788
- return precision;
24789
24854
  }
24790
- function toIntegerOrInfinity2(value) {
24791
- const number = Number(value);
24792
- if (Number.isNaN(number) || Object.is(number, 0) || Object.is(number, -0)) {
24793
- return 0;
24794
- }
24795
- if (!Number.isFinite(number)) {
24796
- return number;
24855
+ function formatNumber(value, methodName, argument, budget) {
24856
+ let result;
24857
+ try {
24858
+ result = value[methodName](argument);
24859
+ } catch (error) {
24860
+ if (!(error instanceof RangeError)) throw error;
24861
+ const detail = methodName === "toString" ? "radix must be between 2 and 36." : methodName === "toPrecision" ? "precision must be between 1 and 100." : "digits must be between 0 and 100.";
24862
+ throw new RangeError(`Number#${methodName} ${detail}`);
24797
24863
  }
24798
- return Math.trunc(number);
24864
+ return budget.allocateString(result);
24799
24865
  }
24800
24866
 
24801
24867
  // packages/safe-js/src/interp/methods/generator.ts
@@ -28620,7 +28686,7 @@ async function evaluateNumberMethodCall(node, target, methodName, context) {
28620
28686
  return {
28621
28687
  kind: "normal",
28622
28688
  hasValue: true,
28623
- value: callNumberMethod(target, methodName, args.value, context.budget)
28689
+ value: await callNumberMethod(target, methodName, args.value, context.budget, createCoercionContext(context))
28624
28690
  };
28625
28691
  } catch (error) {
28626
28692
  if (isFatalSandboxError(error)) {
@@ -28632,6 +28698,10 @@ async function evaluateNumberMethodCall(node, target, methodName, context) {
28632
28698
  function createArrayMethodOptions(context) {
28633
28699
  return {
28634
28700
  budget: context.budget,
28701
+ context: createCoercionContext(context),
28702
+ hasProperty: (value, property) => hasSandboxProperty(value, property, context),
28703
+ setProperty: (value, property, entry) => setSandboxProperty(value, property, entry, context.budget),
28704
+ deleteProperty: deleteSandboxProperty,
28635
28705
  callClosure: (closure, args, stack, thisValue) => invokeSandboxClosure(closure, args, context, stack, void 0, thisValue)
28636
28706
  };
28637
28707
  }
@@ -33213,4 +33283,4 @@ export {
33213
33283
  FileSnapshotBackend,
33214
33284
  run
33215
33285
  };
33216
- //# sourceMappingURL=chunk-DVWTNFTV.js.map
33286
+ //# sourceMappingURL=chunk-VDFW3EKS.js.map