@poe-platform/safe-js 0.1.194 → 0.1.196

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.
@@ -739,6 +739,7 @@ function measureNode(node) {
739
739
  return 3 + node.value.length;
740
740
  case "anchor":
741
741
  case "wordBoundary":
742
+ case "backreference":
742
743
  return 3;
743
744
  case "characterClass": {
744
745
  let usage = 5 + node.items.length;
@@ -757,6 +758,7 @@ function measureNode(node) {
757
758
  case "group":
758
759
  return 5 + measureNode(node.body);
759
760
  case "lookahead":
761
+ case "lookbehind":
760
762
  return 4 + measureNode(node.body);
761
763
  case "quantifier":
762
764
  return (Object.hasOwn(node, "max") ? 6 : 5) + measureNode(node.body);
@@ -2073,6 +2075,7 @@ var RegexParser = class {
2073
2075
  guard;
2074
2076
  captureCount = 0;
2075
2077
  cursor = 0;
2078
+ totalCaptureCount;
2076
2079
  get position() {
2077
2080
  return this.cursor;
2078
2081
  }
@@ -2129,7 +2132,7 @@ var RegexParser = class {
2129
2132
  if (quantifier === void 0) {
2130
2133
  return body;
2131
2134
  }
2132
- if (body.type === "anchor" || body.type === "wordBoundary") {
2135
+ if (body.type === "anchor" || body.type === "wordBoundary" || body.type === "lookbehind") {
2133
2136
  this.fail("Invalid quantifier target", quantifierStart);
2134
2137
  }
2135
2138
  const greedy = this.peek() !== "?";
@@ -2164,7 +2167,8 @@ var RegexParser = class {
2164
2167
  }
2165
2168
  parseGroup(start) {
2166
2169
  let capturing = true;
2167
- let lookahead;
2170
+ let assertionNegated;
2171
+ let lookbehind = false;
2168
2172
  if (this.peek() === "?") {
2169
2173
  this.guard.allocate(Math.min(3, this.source.length - this.position));
2170
2174
  this.guard.work(Math.min(3, this.source.length - this.position));
@@ -2174,10 +2178,13 @@ var RegexParser = class {
2174
2178
  this.position += 2;
2175
2179
  } else if (extension.startsWith("?=") || extension.startsWith("?!")) {
2176
2180
  capturing = false;
2177
- lookahead = extension.startsWith("?!");
2181
+ assertionNegated = extension.startsWith("?!");
2178
2182
  this.position += 2;
2179
2183
  } else if (extension.startsWith("?<=") || extension.startsWith("?<!")) {
2180
- this.fail("Lookbehind is not supported", start);
2184
+ capturing = false;
2185
+ assertionNegated = extension.startsWith("?<!");
2186
+ lookbehind = true;
2187
+ this.position += 3;
2181
2188
  } else if (extension.startsWith("?<")) {
2182
2189
  this.fail("Named groups are not supported", start);
2183
2190
  } else {
@@ -2197,9 +2204,9 @@ var RegexParser = class {
2197
2204
  this.fail("Unterminated group", start);
2198
2205
  }
2199
2206
  this.position += 1;
2200
- if (lookahead !== void 0) {
2207
+ if (assertionNegated !== void 0) {
2201
2208
  this.guard.allocate(4);
2202
- return { type: "lookahead", negated: lookahead, body };
2209
+ return { type: lookbehind ? "lookbehind" : "lookahead", negated: assertionNegated, body };
2203
2210
  }
2204
2211
  this.guard.allocate(5);
2205
2212
  return { type: "group", capturing, index, body };
@@ -2262,8 +2269,29 @@ var RegexParser = class {
2262
2269
  this.fail("Trailing escape", start);
2263
2270
  }
2264
2271
  const escaped = this.take();
2265
- if (escaped >= "1" && escaped <= "9") {
2266
- this.fail("Backreferences are not supported", start);
2272
+ if (isDecimalDigit2(escaped)) {
2273
+ if (!inCharacterClass && escaped !== "0") {
2274
+ let end = this.position;
2275
+ let index = Number(escaped);
2276
+ while (isDecimalDigit2(this.source[end] ?? "")) {
2277
+ this.guard.work(1);
2278
+ index = index * 10 + Number(this.source[end++]);
2279
+ }
2280
+ this.totalCaptureCount ??= this.countAllCaptures();
2281
+ if (index <= this.totalCaptureCount) {
2282
+ this.position = end;
2283
+ this.guard.allocate(3);
2284
+ return { type: "backreference", index };
2285
+ }
2286
+ }
2287
+ this.guard.allocate(4);
2288
+ if (escaped === "8" || escaped === "9") return { type: "literal", value: escaped };
2289
+ let code = Number(escaped);
2290
+ const maximum = escaped <= "3" ? 3 : 2;
2291
+ for (let digits = 1; digits < maximum && this.peek() >= "0" && this.peek() <= "7"; digits++) {
2292
+ code = code * 8 + Number(this.take());
2293
+ }
2294
+ return { type: "literal", value: String.fromCharCode(code) };
2267
2295
  }
2268
2296
  if (escaped === "p" || escaped === "P") {
2269
2297
  this.fail("Unicode property escapes are not supported", start);
@@ -2319,6 +2347,21 @@ var RegexParser = class {
2319
2347
  this.position = end;
2320
2348
  return String.fromCharCode(Number.parseInt(digits, 16));
2321
2349
  }
2350
+ countAllCaptures() {
2351
+ let count = 0;
2352
+ let escaped = false;
2353
+ let characterClass = false;
2354
+ for (let index = 0; index < this.source.length; index++) {
2355
+ this.guard.work(1);
2356
+ const character = this.source[index];
2357
+ if (escaped) escaped = false;
2358
+ else if (character === "\\") escaped = true;
2359
+ else if (character === "[") characterClass = true;
2360
+ else if (character === "]") characterClass = false;
2361
+ else if (!characterClass && character === "(" && this.source[index + 1] !== "?") count++;
2362
+ }
2363
+ return count;
2364
+ }
2322
2365
  parseQuantifier() {
2323
2366
  const character = this.peek();
2324
2367
  if (character === "*") {
@@ -9320,7 +9363,7 @@ function matchRegexFrom(pattern, input, startIndex) {
9320
9363
  return null;
9321
9364
  }
9322
9365
  for (let attempt = startIndex; attempt <= input.length; attempt += 1) {
9323
- const context = { input, flags: pattern.flags, steps: 0 };
9366
+ const context = { input, flags: pattern.flags, direction: 1, work: { steps: 0 } };
9324
9367
  charge(context);
9325
9368
  const initialState = {
9326
9369
  position: attempt,
@@ -9336,18 +9379,35 @@ function matchRegexFrom(pattern, input, startIndex) {
9336
9379
  }
9337
9380
  function* matchNode(node, state, context) {
9338
9381
  charge(context);
9382
+ const characterIndex = context.direction === 1 ? state.position : state.position - 1;
9339
9383
  switch (node.type) {
9340
9384
  case "empty":
9341
9385
  yield state;
9342
9386
  return;
9343
9387
  case "literal":
9344
- if (charactersEqual(context.input[state.position], node.value, context.flags.ignoreCase)) {
9345
- yield { ...state, position: state.position + 1 };
9388
+ if (charactersEqual(context.input[characterIndex], node.value, context.flags.ignoreCase)) {
9389
+ yield { ...state, position: state.position + context.direction };
9346
9390
  }
9347
9391
  return;
9392
+ case "backreference": {
9393
+ const capture = state.captures[node.index - 1];
9394
+ if (capture === void 0) {
9395
+ yield state;
9396
+ return;
9397
+ }
9398
+ const length = capture.end - capture.start;
9399
+ const start = context.direction === 1 ? state.position : state.position - length;
9400
+ if (start < 0 || start + length > context.input.length) return;
9401
+ for (let offset = 0; offset < length; offset++) {
9402
+ charge(context);
9403
+ if (!charactersEqual(context.input[start + offset], context.input[capture.start + offset], context.flags.ignoreCase)) return;
9404
+ }
9405
+ yield { ...state, position: state.position + context.direction * length };
9406
+ return;
9407
+ }
9348
9408
  case "dot":
9349
- if (state.position < context.input.length && (context.flags.dotAll || !isLineTerminator(context.input[state.position]))) {
9350
- yield { ...state, position: state.position + 1 };
9409
+ if (characterIndex >= 0 && characterIndex < context.input.length && (context.flags.dotAll || !isLineTerminator(context.input[characterIndex]))) {
9410
+ yield { ...state, position: state.position + context.direction };
9351
9411
  }
9352
9412
  return;
9353
9413
  case "anchor":
@@ -9364,9 +9424,9 @@ function* matchNode(node, state, context) {
9364
9424
  return;
9365
9425
  }
9366
9426
  case "characterClass": {
9367
- const character = context.input[state.position];
9427
+ const character = context.input[characterIndex];
9368
9428
  if (character !== void 0 && matchesCharacterClass(character, node.items, node.negated, context.flags.ignoreCase)) {
9369
- yield { ...state, position: state.position + 1 };
9429
+ yield { ...state, position: state.position + context.direction };
9370
9430
  }
9371
9431
  return;
9372
9432
  }
@@ -9378,8 +9438,12 @@ function* matchNode(node, state, context) {
9378
9438
  yield* matchNode(alternative, cloneState(state), context);
9379
9439
  }
9380
9440
  return;
9381
- case "lookahead": {
9382
- const result = matchNode(node.body, cloneState(state), context).next();
9441
+ case "lookahead":
9442
+ case "lookbehind": {
9443
+ const result = matchNode(node.body, cloneState(state), {
9444
+ ...context,
9445
+ direction: node.type === "lookbehind" ? -1 : 1
9446
+ }).next();
9383
9447
  if (node.negated) {
9384
9448
  if (result.done) yield state;
9385
9449
  } else if (!result.done) {
@@ -9394,7 +9458,7 @@ function* matchNode(node, state, context) {
9394
9458
  continue;
9395
9459
  }
9396
9460
  const captures = result.captures.slice();
9397
- captures[node.index - 1] = { start: state.position, end: result.position };
9461
+ captures[node.index - 1] = { start: Math.min(state.position, result.position), end: Math.max(state.position, result.position) };
9398
9462
  yield { position: result.position, captures };
9399
9463
  }
9400
9464
  return;
@@ -9408,7 +9472,8 @@ function* matchSequence(elements, index, state, context) {
9408
9472
  yield state;
9409
9473
  return;
9410
9474
  }
9411
- for (const result of matchNode(elements[index], state, context)) {
9475
+ const element = elements[context.direction === 1 ? index : elements.length - 1 - index];
9476
+ for (const result of matchNode(element, state, context)) {
9412
9477
  yield* matchSequence(elements, index + 1, result, context);
9413
9478
  }
9414
9479
  }
@@ -9511,13 +9576,13 @@ function clearNodeCaptures(node, captures) {
9511
9576
  }
9512
9577
  return;
9513
9578
  }
9514
- if (node.type === "quantifier" || node.type === "lookahead") {
9579
+ if (node.type === "quantifier" || node.type === "lookahead" || node.type === "lookbehind") {
9515
9580
  clearNodeCaptures(node.body, captures);
9516
9581
  }
9517
9582
  }
9518
9583
  function charge(context) {
9519
- context.steps += 1;
9520
- allocateRegexSteps(context.steps);
9584
+ context.work.steps += 1;
9585
+ allocateRegexSteps(context.work.steps);
9521
9586
  }
9522
9587
  function normalizeLastIndex(lastIndex) {
9523
9588
  if (Number.isNaN(lastIndex) || lastIndex <= 0) {
@@ -37101,4 +37166,4 @@ export {
37101
37166
  FileSnapshotBackend,
37102
37167
  run
37103
37168
  };
37104
- //# sourceMappingURL=chunk-WRASETAY.js.map
37169
+ //# sourceMappingURL=chunk-KMQUDIYF.js.map