@poe-platform/safe-js 0.1.199 → 0.1.200

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-X5VIB5JV.js";
30
+ } from "./chunk-OX7524JW.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-YWBUORD7.js.map
8252
+ //# sourceMappingURL=chunk-6HCV5BAA.js.map
@@ -753,8 +753,10 @@ function measureNode(node) {
753
753
  return 3;
754
754
  case "characterClass": {
755
755
  let usage = 5 + node.items.length;
756
+ if (node.operation !== void 0) usage += 1 + node.operation.length;
757
+ if (node.strings !== void 0) usage += 1;
756
758
  for (const item of node.items) {
757
- usage += item.type === "character" ? 3 + item.value.length : item.type === "range" ? 4 + item.from.length + item.to.length : item.type === "property" ? 4 + item.value.length : 4;
759
+ usage += item.type === "character" ? 3 + item.value.length : item.type === "range" ? 4 + item.from.length + item.to.length : item.type === "property" ? 4 + item.value.length + (item.strings === void 0 ? 0 : 1) : item.type === "set" ? 3 + measureNode({ type: "characterClass", ...item.value }) : item.type === "strings" ? 4 + item.values.reduce((total, value) => total + 1 + value.length, 0) : 4;
758
760
  }
759
761
  return usage;
760
762
  }
@@ -2068,7 +2070,7 @@ function parseRegex(source, flags = "", compilation, valueUnits = 0) {
2068
2070
  guard.checkLength(flags.length, true);
2069
2071
  guard.allocate(5 + valueUnits);
2070
2072
  const parsedFlags = parseFlags(flags, guard);
2071
- const parser = new RegexParser(source, guard, parsedFlags.unicode);
2073
+ const parser = new RegexParser(source, guard, parsedFlags.unicode || parsedFlags.unicodeSets, parsedFlags.unicodeSets);
2072
2074
  const body = parser.parse();
2073
2075
  guard.allocate(5 + source.length);
2074
2076
  const pattern = { source, flags: parsedFlags, captureCount: parser.captureCount, body };
@@ -2080,14 +2082,16 @@ function parseRegex(source, flags = "", compilation, valueUnits = 0) {
2080
2082
  }
2081
2083
  }
2082
2084
  var RegexParser = class {
2083
- constructor(source, guard, unicode) {
2085
+ constructor(source, guard, unicode, unicodeSets) {
2084
2086
  this.source = source;
2085
2087
  this.guard = guard;
2086
2088
  this.unicode = unicode;
2089
+ this.unicodeSets = unicodeSets;
2087
2090
  }
2088
2091
  source;
2089
2092
  guard;
2090
2093
  unicode;
2094
+ unicodeSets;
2091
2095
  captureCount = 0;
2092
2096
  cursor = 0;
2093
2097
  totalCaptureCount;
@@ -2239,6 +2243,7 @@ var RegexParser = class {
2239
2243
  return { type: "group", capturing, index, body, ...name === void 0 ? {} : { name } };
2240
2244
  }
2241
2245
  parseCharacterClass(start) {
2246
+ if (this.unicodeSets) return { type: "characterClass", ...this.parseUnicodeSet(start) };
2242
2247
  const negated = this.peek() === "^";
2243
2248
  if (negated) {
2244
2249
  this.position += 1;
@@ -2291,6 +2296,95 @@ var RegexParser = class {
2291
2296
  this.guard.allocate(4);
2292
2297
  return { type: "character", value: this.takeCharacter() };
2293
2298
  }
2299
+ parseUnicodeSet(start) {
2300
+ this.guard.enterGroup();
2301
+ try {
2302
+ const negated = this.peek() === "^";
2303
+ if (negated) this.position++;
2304
+ this.guard.allocate(5);
2305
+ const items = [];
2306
+ let operation;
2307
+ while (!this.atEnd() && this.peek() !== "]") {
2308
+ this.guard.array(items.length + 1);
2309
+ let item = this.parseUnicodeSetItem(start);
2310
+ if (this.peek() === "-" && this.source[this.position + 1] !== "-") {
2311
+ this.position++;
2312
+ const right = this.parseUnicodeSetItem(start);
2313
+ if (item.type !== "character" || right.type !== "character") this.fail("Invalid set range", start);
2314
+ if (item.value.codePointAt(0) > right.value.codePointAt(0)) this.fail("Set range is out of order", start);
2315
+ this.guard.allocate(4 + item.value.length + right.value.length);
2316
+ item = { type: "range", from: item.value, to: right.value };
2317
+ }
2318
+ if (operation !== void 0 && item.type === "range") this.fail("Set operations require nested ranges", start);
2319
+ items.push(item);
2320
+ const operator = this.source.slice(this.position, this.position + 2);
2321
+ if (operator === "&&" || operator === "--") {
2322
+ const next = operator === "&&" ? "intersection" : "subtraction";
2323
+ if (operation === void 0 && (items.length !== 1 || item.type === "range") || operation !== void 0 && operation !== next) this.fail("Mixed set operations", start);
2324
+ if (operation === void 0) this.guard.allocate(1 + next.length);
2325
+ operation = next;
2326
+ this.position += 2;
2327
+ if (this.peek() === "]" || this.atEnd()) this.fail("Missing set operand", start);
2328
+ } else if (operation !== void 0 && this.peek() !== "]") this.fail("Missing set operator", start);
2329
+ }
2330
+ if (this.take() !== "]") this.fail("Unterminated character set", start);
2331
+ const mayContainStrings = (item) => {
2332
+ if (item.type === "set") return item.value.strings === true;
2333
+ if (item.type === "property") return item.strings === true;
2334
+ if (item.type === "strings") return item.values.some((value) => value.length !== ((value.codePointAt(0) ?? 0) > 65535 ? 2 : 1));
2335
+ return false;
2336
+ };
2337
+ const strings = operation === "intersection" ? items.every(mayContainStrings) : operation === "subtraction" ? mayContainStrings(items[0]) : items.some(mayContainStrings);
2338
+ if (negated && strings) this.fail("Cannot complement a set containing strings", start);
2339
+ if (strings) this.guard.allocate(1);
2340
+ return { negated, items, ...operation === void 0 ? {} : { operation }, ...strings ? { strings: true } : {} };
2341
+ } finally {
2342
+ this.guard.leaveGroup();
2343
+ }
2344
+ }
2345
+ parseUnicodeSetItem(start) {
2346
+ if (this.peek() === "[") {
2347
+ this.position++;
2348
+ this.guard.allocate(3);
2349
+ return { type: "set", value: this.parseUnicodeSet(start) };
2350
+ }
2351
+ if (this.source.startsWith("\\q{", this.position)) {
2352
+ this.position += 3;
2353
+ this.guard.allocate(4);
2354
+ const values = [];
2355
+ let value2 = "";
2356
+ while (!this.atEnd()) {
2357
+ if (this.peek() === "|" || this.peek() === "}") {
2358
+ this.guard.array(values.length + 1);
2359
+ this.guard.allocate(1);
2360
+ values.push(value2);
2361
+ value2 = "";
2362
+ if (this.take() === "}") return { type: "strings", values };
2363
+ } else {
2364
+ const item = this.parseSetCharacter(start);
2365
+ this.guard.allocate(item.length);
2366
+ value2 += item;
2367
+ }
2368
+ }
2369
+ this.fail("Unterminated class string", start);
2370
+ }
2371
+ if (this.peek() === "\\") return this.parseClassItem(start);
2372
+ const value = this.parseSetCharacter(start);
2373
+ this.guard.allocate(3 + value.length);
2374
+ return { type: "character", value };
2375
+ }
2376
+ parseSetCharacter(start) {
2377
+ if (this.peek() === "\\") {
2378
+ this.position++;
2379
+ const node = this.parseEscape(true, start);
2380
+ if (node.type !== "literal") this.fail("Class strings require literal characters", start);
2381
+ return node.value;
2382
+ }
2383
+ const character = this.takeCharacter();
2384
+ if (!character || "()[]{}/-|".includes(character) || "!#$%&*+,.:;<=>?@^`~".includes(character) && this.peek() === character)
2385
+ this.fail("Invalid character in Unicode set", start);
2386
+ return character;
2387
+ }
2294
2388
  parseEscape(inCharacterClass, start) {
2295
2389
  if (this.atEnd()) {
2296
2390
  this.fail("Trailing escape", start);
@@ -2344,12 +2438,20 @@ var RegexParser = class {
2344
2438
  const value = this.source.slice(begin, this.position);
2345
2439
  if (this.take() !== "}") this.fail("Unterminated Unicode property escape", start);
2346
2440
  try {
2347
- new RegExp(`\\p{${value}}`, "u");
2441
+ new RegExp(`\\${escaped}{${value}}`, this.unicodeSets ? "v" : "u");
2348
2442
  } catch {
2349
2443
  this.fail("Unknown Unicode property", start);
2350
2444
  }
2445
+ let strings = false;
2446
+ if (this.unicodeSets) {
2447
+ try {
2448
+ new RegExp(`\\p{${value}}`, "u");
2449
+ } catch {
2450
+ strings = true;
2451
+ }
2452
+ }
2351
2453
  this.guard.array(1);
2352
- return { type: "characterClass", negated: false, items: [{ type: "property", value, negated: escaped === "P" }] };
2454
+ return { type: "characterClass", negated: false, items: [{ type: "property", value, negated: escaped === "P", ...strings ? { strings: true } : {} }] };
2353
2455
  }
2354
2456
  if (escaped === "x") {
2355
2457
  this.guard.allocate(4);
@@ -2417,7 +2519,7 @@ var RegexParser = class {
2417
2519
  this.guard.allocate(4);
2418
2520
  return { type: "literal", value: String.fromCharCode(letter.charCodeAt(0) % 32) };
2419
2521
  }
2420
- if (this.unicode && controls[escaped] === void 0 && !"^$\\.*+?()[]{}|/".includes(escaped) && !(inCharacterClass && escaped === "-"))
2522
+ if (this.unicode && controls[escaped] === void 0 && !"^$\\.*+?()[]{}|/".includes(escaped) && !(inCharacterClass && (escaped === "-" || this.unicodeSets && "!#$%&+,.:;<=>?@`~".includes(escaped))))
2421
2523
  this.fail("Invalid identity escape", start);
2422
2524
  this.guard.allocate(4);
2423
2525
  return { type: "literal", value: controls[escaped] ?? escaped };
@@ -2591,6 +2693,7 @@ function parseFlags(flags, guard) {
2591
2693
  global: false,
2592
2694
  sticky: false,
2593
2695
  unicode: false,
2696
+ unicodeSets: false,
2594
2697
  ignoreCase: false,
2595
2698
  multiline: false,
2596
2699
  dotAll: false
@@ -2602,7 +2705,8 @@ function parseFlags(flags, guard) {
2602
2705
  m: "multiline",
2603
2706
  s: "dotAll",
2604
2707
  y: "sticky",
2605
- u: "unicode"
2708
+ u: "unicode",
2709
+ v: "unicodeSets"
2606
2710
  };
2607
2711
  for (let position = 0; position < flags.length; position += 1) {
2608
2712
  guard.work(1);
@@ -2616,6 +2720,7 @@ function parseFlags(flags, guard) {
2616
2720
  }
2617
2721
  parsed[name] = true;
2618
2722
  }
2723
+ if (parsed.unicode && parsed.unicodeSets) throw new SyntaxError("Unicode flags u and v cannot be combined");
2619
2724
  return parsed;
2620
2725
  }
2621
2726
  function isDecimalDigit2(character) {
@@ -9518,8 +9623,9 @@ function matchRegexFrom(pattern, input, startIndex) {
9518
9623
  if (startIndex > input.length) {
9519
9624
  return null;
9520
9625
  }
9521
- if (pattern.flags.unicode && startIndex > 0 && startIndex < input.length && input.charCodeAt(startIndex) >= 56320 && input.charCodeAt(startIndex) <= 57343 && input.charCodeAt(startIndex - 1) >= 55296 && input.charCodeAt(startIndex - 1) <= 56319) startIndex--;
9522
- for (let attempt = startIndex; attempt <= input.length; attempt = advanceStringIndex(input, attempt, pattern.flags.unicode)) {
9626
+ const unicode = pattern.flags.unicode || pattern.flags.unicodeSets;
9627
+ if (unicode && startIndex > 0 && startIndex < input.length && input.charCodeAt(startIndex) >= 56320 && input.charCodeAt(startIndex) <= 57343 && input.charCodeAt(startIndex - 1) >= 55296 && input.charCodeAt(startIndex - 1) <= 56319) startIndex--;
9628
+ for (let attempt = startIndex; attempt <= input.length; attempt = advanceStringIndex(input, attempt, unicode)) {
9523
9629
  const context = { input, flags: pattern.flags, groups: pattern.groups, direction: 1, work: { steps: 0 } };
9524
9630
  charge(context);
9525
9631
  const initialState = {
@@ -9536,13 +9642,14 @@ function matchRegexFrom(pattern, input, startIndex) {
9536
9642
  }
9537
9643
  function* matchNode(node, state, context) {
9538
9644
  charge(context);
9539
- const character = readCharacter(context.input, state.position, context.direction, context.flags.unicode);
9645
+ const unicode = context.flags.unicode || context.flags.unicodeSets;
9646
+ const character = readCharacter(context.input, state.position, context.direction, unicode);
9540
9647
  switch (node.type) {
9541
9648
  case "empty":
9542
9649
  yield state;
9543
9650
  return;
9544
9651
  case "literal":
9545
- if (charactersEqual(character, node.value, context.flags.ignoreCase, context.flags.unicode)) {
9652
+ if (charactersEqual(character, node.value, context.flags.ignoreCase, unicode)) {
9546
9653
  yield { ...state, position: state.position + context.direction * character.length };
9547
9654
  }
9548
9655
  return;
@@ -9568,9 +9675,9 @@ function* matchNode(node, state, context) {
9568
9675
  const end = context.direction === 1 ? capture.end : capture.start;
9569
9676
  while (reference !== end) {
9570
9677
  charge(context);
9571
- const expected = readCharacter(context.input, reference, context.direction, context.flags.unicode);
9572
- const actual = readCharacter(context.input, position, context.direction, context.flags.unicode);
9573
- if (!charactersEqual(actual, expected, context.flags.ignoreCase, context.flags.unicode)) return;
9678
+ const expected = readCharacter(context.input, reference, context.direction, unicode);
9679
+ const actual = readCharacter(context.input, position, context.direction, unicode);
9680
+ if (!charactersEqual(actual, expected, context.flags.ignoreCase, unicode)) return;
9574
9681
  reference += context.direction * expected.length;
9575
9682
  position += context.direction * actual.length;
9576
9683
  }
@@ -9588,14 +9695,22 @@ function* matchNode(node, state, context) {
9588
9695
  }
9589
9696
  return;
9590
9697
  case "wordBoundary": {
9591
- const previousWord = state.position > 0 && matchesCharacterClassItem(context.input[state.position - 1], { type: "kind", kind: "word", negated: false }, context.flags.ignoreCase, context.flags.unicode);
9592
- const nextWord = state.position < context.input.length && matchesCharacterClassItem(context.input[state.position], { type: "kind", kind: "word", negated: false }, context.flags.ignoreCase, context.flags.unicode);
9698
+ const previousWord = state.position > 0 && matchesCharacterClassItem(context.input[state.position - 1], { type: "kind", kind: "word", negated: false }, context.flags.ignoreCase, unicode);
9699
+ const nextWord = state.position < context.input.length && matchesCharacterClassItem(context.input[state.position], { type: "kind", kind: "word", negated: false }, context.flags.ignoreCase, unicode);
9593
9700
  if (previousWord !== nextWord !== node.negated) {
9594
9701
  yield state;
9595
9702
  }
9596
9703
  return;
9597
9704
  }
9598
9705
  case "characterClass": {
9706
+ if (context.flags.unicodeSets) {
9707
+ const lengths = [...matchUnicodeSet(node, state.position, context)].sort((a, b) => b - a);
9708
+ for (const length of lengths) {
9709
+ charge(context);
9710
+ yield { ...state, position: state.position + context.direction * length };
9711
+ }
9712
+ return;
9713
+ }
9599
9714
  if (character !== void 0 && matchesCharacterClass(character, node.items, node.negated, context)) {
9600
9715
  yield { ...state, position: state.position + context.direction * character.length };
9601
9716
  }
@@ -9687,7 +9802,8 @@ function matchesCharacterClass(character, items, negated, context) {
9687
9802
  });
9688
9803
  return negated ? !matched : matched;
9689
9804
  }
9690
- function matchesCharacterClassItem(character, item, ignoreCase, unicode) {
9805
+ function matchesCharacterClassItem(character, item, ignoreCase, unicode, unicodeSets = false) {
9806
+ if (item.type === "strings" || item.type === "set") return false;
9691
9807
  if (unicode) {
9692
9808
  const hex = (value) => `\\u{${value.codePointAt(0).toString(16)}}`;
9693
9809
  let atom;
@@ -9698,7 +9814,7 @@ function matchesCharacterClassItem(character, item, ignoreCase, unicode) {
9698
9814
  const kind = item.kind === "digit" ? "d" : item.kind === "word" ? "w" : "s";
9699
9815
  atom = `\\${item.negated ? kind.toUpperCase() : kind}`;
9700
9816
  }
9701
- return new RegExp(`^(?:${atom})$`, ignoreCase ? "iu" : "u").test(character);
9817
+ return new RegExp(`^(?:${atom})$`, (ignoreCase ? "i" : "") + (unicodeSets ? "v" : "u")).test(character);
9702
9818
  }
9703
9819
  if (item.type === "property") return false;
9704
9820
  if (item.type === "character") {
@@ -9722,6 +9838,76 @@ function matchesCharacterClassItem(character, item, ignoreCase, unicode) {
9722
9838
  const matched = item.kind === "digit" ? isDigit(character) : item.kind === "word" ? isWordCharacter(character) : isSpaceCharacter(character);
9723
9839
  return item.negated ? !matched : matched;
9724
9840
  }
9841
+ function matchUnicodeSet(set, position, context) {
9842
+ charge(context);
9843
+ let lengths = /* @__PURE__ */ new Set();
9844
+ for (let index = 0; index < set.items.length; index++) {
9845
+ const next = matchUnicodeSetItem(set.items[index], position, context);
9846
+ if (index === 0) lengths = next;
9847
+ else if (set.operation === void 0) {
9848
+ for (const length of next) {
9849
+ charge(context);
9850
+ lengths.add(length);
9851
+ }
9852
+ } else {
9853
+ for (const length of lengths) {
9854
+ charge(context);
9855
+ if (set.operation === "intersection" ? !next.has(length) : next.has(length)) lengths.delete(length);
9856
+ }
9857
+ }
9858
+ }
9859
+ if (set.negated) {
9860
+ const character = readCharacter(context.input, position, context.direction, true);
9861
+ return new Set(character !== void 0 && !lengths.has(character.length) ? [character.length] : []);
9862
+ }
9863
+ return lengths;
9864
+ }
9865
+ function matchUnicodeSetItem(item, position, context) {
9866
+ charge(context);
9867
+ if (item.type === "set") return matchUnicodeSet(item.value, position, context);
9868
+ const lengths = /* @__PURE__ */ new Set();
9869
+ if (item.type === "strings") {
9870
+ for (const value of item.values) {
9871
+ charge(context);
9872
+ let reference = context.direction === 1 ? 0 : value.length;
9873
+ let cursor = position;
9874
+ const end = context.direction === 1 ? value.length : 0;
9875
+ while (reference !== end) {
9876
+ charge(context);
9877
+ const expected = readCharacter(value, reference, context.direction, true);
9878
+ const actual = readCharacter(context.input, cursor, context.direction, true);
9879
+ if (!charactersEqual(actual, expected, context.flags.ignoreCase, true)) break;
9880
+ reference += context.direction * expected.length;
9881
+ cursor += context.direction * actual.length;
9882
+ }
9883
+ if (reference === end) lengths.add(Math.abs(cursor - position));
9884
+ }
9885
+ return lengths;
9886
+ }
9887
+ if (item.type === "property" && item.strings) {
9888
+ const atom = `\\p{${item.value}}`;
9889
+ const flags = (context.flags.ignoreCase ? "i" : "") + "v";
9890
+ const matcher = new RegExp(context.direction === 1 ? atom : `(?<=(${atom}))`, flags + "y");
9891
+ matcher.lastIndex = position;
9892
+ const match = matcher.exec(context.input);
9893
+ if (match === null) return lengths;
9894
+ const longest = context.direction === 1 ? match[0] : match[1];
9895
+ const member = new RegExp(`^(?:${atom})$`, flags);
9896
+ let consumed = 0;
9897
+ while (consumed < longest.length) {
9898
+ charge(context);
9899
+ const cursor = context.direction === 1 ? consumed : longest.length - consumed;
9900
+ consumed += readCharacter(longest, cursor, context.direction, true).length;
9901
+ const candidate = context.direction === 1 ? longest.slice(0, consumed) : longest.slice(longest.length - consumed);
9902
+ if (member.test(candidate)) lengths.add(consumed);
9903
+ }
9904
+ return lengths;
9905
+ }
9906
+ const character = readCharacter(context.input, position, context.direction, true);
9907
+ if (character !== void 0 && matchesCharacterClassItem(character, item, context.flags.ignoreCase, true, true))
9908
+ lengths.add(character.length);
9909
+ return lengths;
9910
+ }
9725
9911
  function toRegexMatch(input, start, state, hasIndices, groups) {
9726
9912
  const match = {
9727
9913
  index: start,
@@ -10640,7 +10826,7 @@ function splitNormalized(value, separator, limit, budget, parent) {
10640
10826
  while (result2.length < limit) {
10641
10827
  const match = executeRegex(splitter, value, Number(splitter.lastIndex));
10642
10828
  if (match === null) break;
10643
- if (match.text.length === 0) splitter.lastIndex = advanceStringIndex(value, match.index, splitter.flags.includes("u"));
10829
+ if (match.text.length === 0) splitter.lastIndex = advanceStringIndex(value, match.index, splitter.flags.includes("u") || splitter.flags.includes("v"));
10644
10830
  endedWithZeroWidthMatch = match.text.length === 0 && match.index === value.length;
10645
10831
  if (match.text.length === 0 && (match.index === copiedThrough || match.index === value.length))
10646
10832
  continue;
@@ -10815,7 +11001,7 @@ function collectRegexMatches(regex, value, all, budget, lastIndex = 0) {
10815
11001
  budget?.allocateArrayLength(matches.length + 1);
10816
11002
  matches.push(match);
10817
11003
  lastIndex = match.index + match.text.length;
10818
- if (all && match.text.length === 0) regex.lastIndex = lastIndex = advanceStringIndex(value, lastIndex, regex.flags.includes("u"));
11004
+ if (all && match.text.length === 0) regex.lastIndex = lastIndex = advanceStringIndex(value, lastIndex, regex.flags.includes("u") || regex.flags.includes("v"));
10819
11005
  } while (all);
10820
11006
  return matches;
10821
11007
  }
@@ -37381,4 +37567,4 @@ export {
37381
37567
  FileSnapshotBackend,
37382
37568
  run
37383
37569
  };
37384
- //# sourceMappingURL=chunk-X5VIB5JV.js.map
37570
+ //# sourceMappingURL=chunk-OX7524JW.js.map