regex-partial-match 1.3.0 → 2.0.0

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.
Files changed (137) hide show
  1. package/README.md +120 -267
  2. package/lib/core/corePartialMatchRegExp.d.ts +24 -0
  3. package/lib/core/corePartialMatchRegExp.js +22 -0
  4. package/lib/core/index.d.ts +4 -0
  5. package/lib/core/index.js +2 -0
  6. package/lib/extend/index.d.ts +6 -7
  7. package/lib/extend/index.js +1 -1
  8. package/lib/features/index.d.ts +20 -0
  9. package/lib/features/index.js +23 -0
  10. package/lib/hitEnd/index.d.ts +45 -0
  11. package/lib/hitEnd/index.js +57 -0
  12. package/lib/hitEnd/matchHitEnd.d.ts +4 -0
  13. package/lib/hitEnd/matchHitEnd.js +51 -0
  14. package/lib/{partialMatchRegExp/isComplete → hitEnd}/partRole.d.ts +1 -1
  15. package/lib/hitEnd/partRole.js +17 -0
  16. package/lib/hitEnd/truncationProbe.d.ts +8 -0
  17. package/lib/hitEnd/truncationProbe.js +187 -0
  18. package/lib/hitEnd/truncationProbeCache.d.ts +14 -0
  19. package/lib/index.d.ts +4 -0
  20. package/lib/index.js +4 -0
  21. package/lib/modules/backreferences/asNativeAtom.d.ts +2 -0
  22. package/lib/{partialMatchRegExp/compilePartial → modules/backreferences}/asNativeAtom.js +2 -2
  23. package/lib/modules/backreferences/asPreScanPart.d.ts +2 -0
  24. package/lib/{partialMatchRegExp/compilePartial → modules/backreferences}/asPreScanPart.js +2 -2
  25. package/lib/modules/backreferences/backreferenceRecorder.d.ts +2 -0
  26. package/lib/modules/backreferences/backreferenceRecorder.js +38 -0
  27. package/lib/modules/backreferences/compileDynamic.d.ts +4 -0
  28. package/lib/modules/backreferences/compileDynamic.js +53 -0
  29. package/lib/modules/backreferences/compiledBackreferences.d.ts +9 -0
  30. package/lib/modules/backreferences/compiledBackreferences.js +9 -0
  31. package/lib/modules/backreferences/constants.d.ts +2 -0
  32. package/lib/modules/backreferences/constants.js +2 -0
  33. package/lib/modules/backreferences/execDynamic.d.ts +2 -0
  34. package/lib/modules/backreferences/execDynamic.js +43 -0
  35. package/lib/{partialMatchRegExp/compilePartial → modules/backreferences}/flagsAtBackreference.d.ts +1 -1
  36. package/lib/{partialMatchRegExp → modules/backreferences}/groupName.js +1 -1
  37. package/lib/modules/backreferences/index.d.ts +10 -0
  38. package/lib/modules/backreferences/index.js +20 -0
  39. package/lib/modules/backreferences/longestBakedPrefixEndingInput.js +46 -0
  40. package/lib/{partialMatchRegExp/compilePartial → modules/backreferences}/renderParts.d.ts +1 -1
  41. package/lib/{partialMatchRegExp/compilePartial → modules/backreferences}/renderParts.js +1 -1
  42. package/lib/{partialMatchRegExp/compilePartial → modules/backreferences}/resolvedFromScan.d.ts +1 -1
  43. package/lib/{partialMatchRegExp/compilePartial → modules/backreferences}/resolvedFromScan.js +2 -2
  44. package/lib/{partialMatchRegExp/compilePartial → modules/backreferences}/startsWithUnderFlags.js +1 -1
  45. package/lib/modules/carets/appendMultilineCaret.d.ts +7 -0
  46. package/lib/modules/carets/appendMultilineCaret.js +181 -0
  47. package/lib/modules/carets/caretRecorder.d.ts +2 -0
  48. package/lib/modules/carets/caretRecorder.js +164 -0
  49. package/lib/modules/carets/caretSyntax.d.ts +3 -0
  50. package/lib/modules/carets/caretSyntax.js +11 -0
  51. package/lib/modules/carets/index.d.ts +9 -0
  52. package/lib/modules/carets/index.js +18 -0
  53. package/lib/modules/carets/lineTerminator.d.ts +1 -0
  54. package/lib/modules/carets/lineTerminator.js +31 -0
  55. package/lib/modules/carets/needsCaretRules.d.ts +1 -0
  56. package/lib/modules/carets/needsCaretRules.js +15 -0
  57. package/lib/modules/carets/quantifierBounds.d.ts +3 -0
  58. package/lib/modules/carets/quantifierBounds.js +18 -0
  59. package/lib/modules/index.d.ts +3 -0
  60. package/lib/modules/index.js +2 -0
  61. package/lib/partialMatchRegExp/atomSyntax.d.ts +14 -1
  62. package/lib/partialMatchRegExp/atomSyntax.js +24 -1
  63. package/lib/partialMatchRegExp/backreferenceExpansion.d.ts +1 -6
  64. package/lib/partialMatchRegExp/backreferenceHook.d.ts +11 -0
  65. package/lib/partialMatchRegExp/backreferenceHook.js +1 -0
  66. package/lib/partialMatchRegExp/caretHook.d.ts +17 -0
  67. package/lib/partialMatchRegExp/caretHook.js +5 -0
  68. package/lib/partialMatchRegExp/compilePartial/compileWith.d.ts +3 -0
  69. package/lib/partialMatchRegExp/compilePartial/compileWith.js +36 -0
  70. package/lib/partialMatchRegExp/compilePartial/compiled.d.ts +17 -17
  71. package/lib/partialMatchRegExp/compilePartial/compiled.js +8 -21
  72. package/lib/partialMatchRegExp/compilePartial/constants.d.ts +4 -0
  73. package/lib/partialMatchRegExp/compilePartial/constants.js +4 -0
  74. package/lib/partialMatchRegExp/compilePartial/groupShape.d.ts +4 -0
  75. package/lib/partialMatchRegExp/compilePartial/groupShape.js +9 -0
  76. package/lib/partialMatchRegExp/compilePartial/toStatic.d.ts +2 -2
  77. package/lib/partialMatchRegExp/compilePartial/toStatic.js +2 -2
  78. package/lib/partialMatchRegExp/constants.d.ts +5 -0
  79. package/lib/partialMatchRegExp/constants.js +5 -0
  80. package/lib/partialMatchRegExp/createPartialMatchRegExp.d.ts +3 -0
  81. package/lib/partialMatchRegExp/createPartialMatchRegExp.js +21 -0
  82. package/lib/partialMatchRegExp/execFrom.d.ts +1 -0
  83. package/lib/partialMatchRegExp/execFrom.js +4 -0
  84. package/lib/partialMatchRegExp/index.d.ts +49 -3
  85. package/lib/partialMatchRegExp/index.js +31 -3
  86. package/lib/partialMatchRegExp/moduleHooks.d.ts +14 -0
  87. package/lib/partialMatchRegExp/moduleHooks.js +15 -0
  88. package/lib/partialMatchRegExp/opaqueModule.d.ts +9 -0
  89. package/lib/partialMatchRegExp/opaqueModule.js +1 -0
  90. package/lib/partialMatchRegExp/part.d.ts +2 -11
  91. package/lib/partialMatchRegExp/partialMatchInternals.d.ts +2 -1
  92. package/lib/partialMatchRegExp/partialMatchInternals.js +3 -1
  93. package/lib/partialMatchRegExp/quantifier.d.ts +6 -0
  94. package/lib/partialMatchRegExp/quantifier.js +9 -0
  95. package/lib/partialMatchRegExp/rawLookaroundInfo.d.ts +11 -0
  96. package/lib/partialMatchRegExp/rawLookaroundInfo.js +1 -0
  97. package/lib/partialMatchRegExp/regexFeatures.d.ts +1 -5
  98. package/lib/partialMatchRegExp/regexFeatures.js +2 -8
  99. package/lib/partialMatchRegExp/scope.d.ts +12 -0
  100. package/lib/partialMatchRegExp/scope.js +45 -0
  101. package/lib/partialMatchRegExp/walk.d.ts +13 -5
  102. package/lib/partialMatchRegExp/walk.js +211 -165
  103. package/lib/partialMatchRegExp/withModules.d.ts +13 -0
  104. package/lib/partialMatchRegExp/withModules.js +27 -0
  105. package/package.json +39 -56
  106. package/lib/partialMatchRegExp/compilePartial/asNativeAtom.d.ts +0 -2
  107. package/lib/partialMatchRegExp/compilePartial/asOptionalAtom.d.ts +0 -1
  108. package/lib/partialMatchRegExp/compilePartial/asOptionalAtom.js +0 -4
  109. package/lib/partialMatchRegExp/compilePartial/asPreScanPart.d.ts +0 -2
  110. package/lib/partialMatchRegExp/compilePartial/index.d.ts +0 -2
  111. package/lib/partialMatchRegExp/compilePartial/index.js +0 -79
  112. package/lib/partialMatchRegExp/compilePartial/longestBakedPrefixEndingInput.js +0 -50
  113. package/lib/partialMatchRegExp/compilePartial/reclassifyLegacyEscapes.d.ts +0 -2
  114. package/lib/partialMatchRegExp/compilePartial/reclassifyLegacyEscapes.js +0 -17
  115. package/lib/partialMatchRegExp/compilePartial/spliceOriginalSource.d.ts +0 -2
  116. package/lib/partialMatchRegExp/compilePartial/spliceOriginalSource.js +0 -12
  117. package/lib/partialMatchRegExp/isComplete/index.d.ts +0 -38
  118. package/lib/partialMatchRegExp/isComplete/index.js +0 -41
  119. package/lib/partialMatchRegExp/isComplete/isMatchComplete.d.ts +0 -3
  120. package/lib/partialMatchRegExp/isComplete/isMatchComplete.js +0 -14
  121. package/lib/partialMatchRegExp/isComplete/partRole.js +0 -28
  122. package/lib/partialMatchRegExp/isComplete/truncationProbe.d.ts +0 -8
  123. package/lib/partialMatchRegExp/isComplete/truncationProbe.js +0 -105
  124. package/lib/partialMatchRegExp/isComplete/truncationProbeCache.d.ts +0 -4
  125. package/lib/partialMatchRegExp/partialMatchRegExp.d.ts +0 -55
  126. package/lib/partialMatchRegExp/partialMatchRegExp.js +0 -114
  127. package/lib/partialMatchRegExp/preferLongerCaptures.d.ts +0 -1
  128. package/lib/partialMatchRegExp/preferLongerCaptures.js +0 -30
  129. /package/lib/{partialMatchRegExp/isComplete → hitEnd}/truncationProbeCache.js +0 -0
  130. /package/lib/{partialMatchRegExp/compilePartial → modules/backreferences}/caseFoldFlags.d.ts +0 -0
  131. /package/lib/{partialMatchRegExp/compilePartial → modules/backreferences}/caseFoldFlags.js +0 -0
  132. /package/lib/{partialMatchRegExp → modules/backreferences}/escapeAtom.d.ts +0 -0
  133. /package/lib/{partialMatchRegExp → modules/backreferences}/escapeAtom.js +0 -0
  134. /package/lib/{partialMatchRegExp/compilePartial → modules/backreferences}/flagsAtBackreference.js +0 -0
  135. /package/lib/{partialMatchRegExp → modules/backreferences}/groupName.d.ts +0 -0
  136. /package/lib/{partialMatchRegExp/compilePartial → modules/backreferences}/longestBakedPrefixEndingInput.d.ts +0 -0
  137. /package/lib/{partialMatchRegExp/compilePartial → modules/backreferences}/startsWithUnderFlags.d.ts +0 -0
@@ -0,0 +1,13 @@
1
+ import type { Module } from "./opaqueModule.ts";
2
+ import type { PartialMatchRegExpConstructor } from "./index.ts";
3
+ /**
4
+ * The `PartialMatchRegExp` class that applies the rules the given modules
5
+ * supply.
6
+ *
7
+ * The same set of modules, in any order, returns the same class.
8
+ *
9
+ * @param modules - The modules to bind, from `regex-partial-match/modules`
10
+ * @returns The `PartialMatchRegExp` class that binds `modules`
11
+ * @throws `TypeError` if any argument is not a module
12
+ */
13
+ export default function withModules(...modules: Module[]): PartialMatchRegExpConstructor;
@@ -0,0 +1,27 @@
1
+ import createPartialMatchRegExp from "./createPartialMatchRegExp.js";
2
+ import { definedModuleHooks, moduleHooks } from "./moduleHooks.js";
3
+ const boundByModuleMask = [];
4
+ const isDefinedHooks = (value) => definedModuleHooks.has(value);
5
+ /**
6
+ * The `PartialMatchRegExp` class that applies the rules the given modules
7
+ * supply.
8
+ *
9
+ * The same set of modules, in any order, returns the same class.
10
+ *
11
+ * @param modules - The modules to bind, from `regex-partial-match/modules`
12
+ * @returns The `PartialMatchRegExp` class that binds `modules`
13
+ * @throws `TypeError` if any argument is not a module
14
+ */
15
+ export default function withModules(...modules) {
16
+ const hooks = {};
17
+ let moduleMask = 0;
18
+ for (const module of modules) {
19
+ const bound = Reflect.get(Object(module), moduleHooks);
20
+ if (!isDefinedHooks(bound))
21
+ throw new TypeError("Not a module");
22
+ moduleMask |= bound.bit;
23
+ Object.assign(hooks, bound);
24
+ }
25
+ return (boundByModuleMask[moduleMask] ||
26
+ (boundByModuleMask[moduleMask] = createPartialMatchRegExp(Object.freeze(hooks))));
27
+ }
package/package.json CHANGED
@@ -1,17 +1,7 @@
1
1
  {
2
2
  "name": "regex-partial-match",
3
- "version": "1.3.0",
3
+ "version": "2.0.0",
4
4
  "description": "A regular expression transform for partial matching",
5
- "devEngines": {
6
- "runtime": {
7
- "name": "node",
8
- "version": ">=24.12"
9
- },
10
- "packageManager": {
11
- "name": "npm",
12
- "version": "11.19.0+sha512.48377f8478372aa1c4e47b763475b135836da82436a5700f2e5e8eb5084fc840f93c7b117eb3ad3b5f7d3194c81b6710a10d59448f6ddbcb21ac3fb672bdc003"
13
- }
14
- },
15
5
  "keywords": [
16
6
  "regexp",
17
7
  "regular expressions",
@@ -33,12 +23,12 @@
33
23
  }
34
24
  ],
35
25
  "type": "module",
36
- "main": "lib/partialMatchRegExp/index.js",
26
+ "main": "lib/index.js",
37
27
  "exports": {
38
28
  ".": {
39
- "types": "./lib/partialMatchRegExp/index.d.ts",
40
- "import": "./lib/partialMatchRegExp/index.js",
41
- "default": "./lib/partialMatchRegExp/index.js"
29
+ "types": "./lib/index.d.ts",
30
+ "import": "./lib/index.js",
31
+ "default": "./lib/index.js"
42
32
  },
43
33
  "./extend": {
44
34
  "types": "./lib/extend/index.d.ts",
@@ -46,9 +36,39 @@
46
36
  "default": "./lib/extend/index.js"
47
37
  },
48
38
  "./partialMatchRegExp": {
49
- "types": "./lib/partialMatchRegExp/partialMatchRegExp.d.ts",
50
- "import": "./lib/partialMatchRegExp/partialMatchRegExp.js",
51
- "default": "./lib/partialMatchRegExp/partialMatchRegExp.js"
39
+ "types": "./lib/partialMatchRegExp/index.d.ts",
40
+ "import": "./lib/partialMatchRegExp/index.js",
41
+ "default": "./lib/partialMatchRegExp/index.js"
42
+ },
43
+ "./hitEnd": {
44
+ "types": "./lib/hitEnd/index.d.ts",
45
+ "import": "./lib/hitEnd/index.js",
46
+ "default": "./lib/hitEnd/index.js"
47
+ },
48
+ "./features": {
49
+ "types": "./lib/features/index.d.ts",
50
+ "import": "./lib/features/index.js",
51
+ "default": "./lib/features/index.js"
52
+ },
53
+ "./core": {
54
+ "types": "./lib/core/index.d.ts",
55
+ "import": "./lib/core/index.js",
56
+ "default": "./lib/core/index.js"
57
+ },
58
+ "./modules": {
59
+ "types": "./lib/modules/index.d.ts",
60
+ "import": "./lib/modules/index.js",
61
+ "default": "./lib/modules/index.js"
62
+ },
63
+ "./modules/carets": {
64
+ "types": "./lib/modules/carets/index.d.ts",
65
+ "import": "./lib/modules/carets/index.js",
66
+ "default": "./lib/modules/carets/index.js"
67
+ },
68
+ "./modules/backreferences": {
69
+ "types": "./lib/modules/backreferences/index.d.ts",
70
+ "import": "./lib/modules/backreferences/index.js",
71
+ "default": "./lib/modules/backreferences/index.js"
52
72
  }
53
73
  },
54
74
  "files": [
@@ -58,47 +78,10 @@
58
78
  "type": "git",
59
79
  "url": "git+https://github.com/TomStrepsil/regex-partial-match.git"
60
80
  },
61
- "workspaces": [
62
- "test/benchmarking"
63
- ],
64
81
  "sideEffects": [
65
82
  "./lib/extend/index.js"
66
83
  ],
67
- "scripts": {
68
- "lint": "eslint .",
69
- "lint:fix": "eslint . --fix",
70
- "prepare": "simple-git-hooks",
71
- "prepublishOnly": "tsc -p tsconfig.build.json",
72
- "ci:smoke-test-built-package": "node .github/scripts/smoke-test-built-package.ts",
73
- "test": "vitest run --config ./test/vitest.config.ts",
74
- "test:watch": "vitest --config ./test/vitest.config.ts",
75
- "test:coverage": "vitest run --config ./test/vitest.config.ts --coverage"
76
- },
77
- "simple-git-hooks": {
78
- "pre-commit": "node_modules/.bin/lint-staged"
79
- },
80
- "lint-staged": {
81
- "*.{ts,js}": [
82
- "eslint --fix"
83
- ]
84
- },
85
84
  "publishConfig": {
86
85
  "registry": "https://registry.npmjs.org"
87
- },
88
- "devDependencies": {
89
- "@eslint/js": "^9.17.0",
90
- "@eslint/markdown": "^7.5.1",
91
- "@types/node": "^25.9.3",
92
- "@typescript/lib-es2018": "file:types/lib-es2018",
93
- "@typescript/lib-es2022": "file:types/lib-es2022",
94
- "@vitest/coverage-v8": "^4.1.11",
95
- "esbuild": "^0.28.1",
96
- "eslint": "^9.17.0",
97
- "jiti": "^2.6.1",
98
- "lint-staged": "^15.2.11",
99
- "simple-git-hooks": "^2.12.1",
100
- "typescript": "^6.0.3",
101
- "typescript-eslint": "^8.18.1",
102
- "vitest": "^4.0.15"
103
86
  }
104
- }
87
+ }
@@ -1,2 +0,0 @@
1
- import { type Backreference } from "../part.ts";
2
- export default function asNativeAtom(backref: Backreference): string;
@@ -1 +0,0 @@
1
- export default function asOptionalAtom(text: string): string;
@@ -1,4 +0,0 @@
1
- import { DISJUNCTION_TO_END_OF_INPUT } from "../atomSyntax.js";
2
- export default function asOptionalAtom(text) {
3
- return "(?:" + text + DISJUNCTION_TO_END_OF_INPUT;
4
- }
@@ -1,2 +0,0 @@
1
- import { type Part } from "../part.ts";
2
- export default function asPreScanPart(part: Part): string;
@@ -1,2 +0,0 @@
1
- import { type CompiledPartial } from "./compiled.ts";
2
- export default function compilePartial(regex: RegExp): CompiledPartial;
@@ -1,79 +0,0 @@
1
- import escapeAtom from "../escapeAtom.js";
2
- import { walk } from "../walk.js";
3
- import { OPTIONAL_ATOM_OPENING } from "../atomSyntax.js";
4
- import { isBackreference } from "../part.js";
5
- import { hasFeature } from "../regexFeatures.js";
6
- import asOptionalAtom from "./asOptionalAtom.js";
7
- import asPreScanPart from "./asPreScanPart.js";
8
- import resolvedFromScan from "./resolvedFromScan.js";
9
- import startsWithUnderFlags from "./startsWithUnderFlags.js";
10
- import longestBakedPrefixEndingInput from "./longestBakedPrefixEndingInput.js";
11
- import flagsAtBackreference from "./flagsAtBackreference.js";
12
- import reclassifyLegacyEscapes from "./reclassifyLegacyEscapes.js";
13
- import spliceOriginalSource from "./spliceOriginalSource.js";
14
- import toStatic from "./toStatic.js";
15
- import { CompiledDynamic } from "./compiled.js";
16
- const MAYBE_HAS_BACKREFERENCE_REGEX = /\\[0-9]|\\k</;
17
- const NEVER = "(?!)";
18
- const GROUP_CLOSING = ")";
19
- const ALTERNATION = "|";
20
- const ONLY_AT_END_OF_INPUT = asOptionalAtom(NEVER);
21
- export default function compilePartial(regex) {
22
- const flags = regex.flags;
23
- let walked = walk(regex, true);
24
- if (hasFeature(walked.featureMask, "namedBackreference") &&
25
- !hasFeature(walked.featureMask, "namedGroup")) {
26
- walked = walk(regex, false);
27
- }
28
- const { parts, groupCount, featureMask, rawLookarounds, namedGroupOpenings } = walked;
29
- if (!MAYBE_HAS_BACKREFERENCE_REGEX.test(regex.source)) {
30
- return toStatic(parts, flags, rawLookarounds, namedGroupOpenings, featureMask);
31
- }
32
- const isUnicode = regex.unicode || regex.unicodeSets;
33
- const sanitisedParts = isUnicode
34
- ? parts
35
- : reclassifyLegacyEscapes(parts, regex.source, groupCount);
36
- const backreferences = sanitisedParts.filter(isBackreference);
37
- if (backreferences.length === 0) {
38
- return toStatic(sanitisedParts, flags, rawLookarounds, namedGroupOpenings, featureMask);
39
- }
40
- return new CompiledDynamic({
41
- originalCaptureScan: new RegExp(spliceOriginalSource(regex.source, backreferences), flags),
42
- preScan: new RegExp(sanitisedParts.map(asPreScanPart).join(""), flags),
43
- expansionFitsCaptures: (expandedFrom, match, input) => {
44
- var _a;
45
- for (const backref of backreferences) {
46
- const baked = resolvedFromScan(backref, expandedFrom);
47
- if (baked === undefined)
48
- continue;
49
- const resolved = (_a = resolvedFromScan(backref, match)) !== null && _a !== void 0 ? _a : "";
50
- const backrefFlags = flagsAtBackreference(backref, flags);
51
- const consumed = longestBakedPrefixEndingInput(baked, input, backrefFlags);
52
- if (!startsWithUnderFlags(resolved, consumed, backrefFlags))
53
- return false;
54
- }
55
- return true;
56
- },
57
- expand: (capture) => {
58
- const expanded = [];
59
- for (const part of sanitisedParts) {
60
- if (!isBackreference(part)) {
61
- expanded.push(part);
62
- continue;
63
- }
64
- const captured = resolvedFromScan(part, capture);
65
- if (captured === undefined || captured === "") {
66
- expanded.push(part);
67
- continue;
68
- }
69
- const atoms = isUnicode ? Array.from(captured) : captured.split("");
70
- expanded.push(OPTIONAL_ATOM_OPENING, part, ALTERNATION);
71
- for (const atom of atoms) {
72
- expanded.push(asOptionalAtom(escapeAtom(atom)));
73
- }
74
- expanded.push(ONLY_AT_END_OF_INPUT, GROUP_CLOSING);
75
- }
76
- return expanded;
77
- }
78
- }, rawLookarounds, namedGroupOpenings, featureMask);
79
- }
@@ -1,50 +0,0 @@
1
- import escapeAtom from "../escapeAtom.js";
2
- import caseFoldFlags from "./caseFoldFlags.js";
3
- const SENTINEL = null;
4
- function foldMatchersFor(atoms, flags) {
5
- const matchers = Object.create(null);
6
- if (!flags.includes("i"))
7
- return matchers;
8
- const foldFlags = caseFoldFlags(flags);
9
- for (const atom of atoms) {
10
- if (!(atom in matchers)) {
11
- matchers[atom] = new RegExp("^" + escapeAtom(atom), foldFlags);
12
- }
13
- }
14
- return matchers;
15
- }
16
- function atomsAgree(a, b, foldMatchers) {
17
- var _a, _b;
18
- if (a === SENTINEL || b === SENTINEL)
19
- return false;
20
- if (a === b)
21
- return true;
22
- return (_b = (_a = foldMatchers[a]) === null || _a === void 0 ? void 0 : _a.test(b)) !== null && _b !== void 0 ? _b : false;
23
- }
24
- export default function longestBakedPrefixEndingInput(baked, input, flags) {
25
- if (baked === "")
26
- return "";
27
- const isUnicode = flags.includes("u") || flags.includes("v");
28
- const bakedAtoms = isUnicode ? Array.from(baked) : baked.split("");
29
- const inputAtoms = isUnicode ? Array.from(input) : input.split("");
30
- const foldMatchers = foldMatchersFor(bakedAtoms, flags);
31
- const sentinelIndex = bakedAtoms.length;
32
- const totalLength = bakedAtoms.length + 1 + inputAtoms.length;
33
- const atIndex = (index) => index < sentinelIndex
34
- ? bakedAtoms[index]
35
- : index === sentinelIndex
36
- ? SENTINEL
37
- : inputAtoms[index - sentinelIndex - 1];
38
- const longestBorder = [0];
39
- for (let index = 1; index < totalLength; index++) {
40
- let matched = longestBorder[index - 1];
41
- while (matched > 0 &&
42
- !atomsAgree(atIndex(matched), atIndex(index), foldMatchers)) {
43
- matched = longestBorder[matched - 1];
44
- }
45
- if (atomsAgree(atIndex(matched), atIndex(index), foldMatchers))
46
- matched++;
47
- longestBorder.push(matched);
48
- }
49
- return bakedAtoms.slice(0, longestBorder[totalLength - 1]).join("");
50
- }
@@ -1,2 +0,0 @@
1
- import { type Part } from "../part.ts";
2
- export default function reclassifyLegacyEscapes(parts: Part[], source: string, groupCount: number): Part[];
@@ -1,17 +0,0 @@
1
- import { legacyEscapeAtoms } from "../legacyEscape.js";
2
- import { isNumericBackreference } from "../part.js";
3
- import asOptionalAtom from "./asOptionalAtom.js";
4
- export default function reclassifyLegacyEscapes(parts, source, groupCount) {
5
- const reclassified = [];
6
- for (const part of parts) {
7
- if (isNumericBackreference(part) && (part.ref < 1 || part.ref > groupCount)) {
8
- for (const atom of legacyEscapeAtoms(source.slice(part.start + 1, part.end))) {
9
- reclassified.push(asOptionalAtom(atom));
10
- }
11
- }
12
- else {
13
- reclassified.push(part);
14
- }
15
- }
16
- return reclassified;
17
- }
@@ -1,2 +0,0 @@
1
- import type { Backreference } from "../part.ts";
2
- export default function spliceOriginalSource(source: string, backrefs: Backreference[]): string;
@@ -1,12 +0,0 @@
1
- import { ANY_CAPTURED_TEXT } from "../atomSyntax.js";
2
- export default function spliceOriginalSource(source, backrefs) {
3
- let result = "";
4
- let cursor = 0;
5
- for (const { start, end, forward } of backrefs) {
6
- if (forward)
7
- continue;
8
- result += source.slice(cursor, start) + ANY_CAPTURED_TEXT;
9
- cursor = end;
10
- }
11
- return result + source.slice(cursor);
12
- }
@@ -1,38 +0,0 @@
1
- import type PartialMatchRegExp from "../partialMatchRegExp.ts";
2
- /**
3
- * Whether `match` — a match `partial` produced — is a match of the original
4
- * pattern, or merely a prefix of it.
5
- *
6
- * `true` means every atom matched literally, so the path the match took is
7
- * one the original pattern could have taken itself. `false` means the match
8
- * depended on the input running out: it took a `|$(?![\s\S])` truncation
9
- * branch, so more input is needed and its captures are provisional.
10
- *
11
- * Complete is not the same as final: `/hello \w+/` matches `"hello world"`
12
- * completely, and would match more of `"hello worldly"`.
13
- *
14
- * The implication runs one way only. The original pattern may also match at
15
- * this index by some *other* path — yielding the same text, and even the
16
- * same captures — so re-testing the original answers "does anything match
17
- * here?", not "did this result depend on truncation?", and cannot recover
18
- * this answer.
19
- *
20
- * @param partial - The `PartialMatchRegExp` instance that produced `match`
21
- * @param match - A match returned by `partial.exec()`
22
- * @returns `true` when the match is complete, `false` when it is a prefix
23
- *
24
- * @remarks
25
- * Requires ES2018+ regardless of the pattern — the probe this builds uses
26
- * named capturing groups internally, unlike `exec()` and `test()`.
27
- *
28
- * @example
29
- * ```typescript
30
- * import PartialMatchRegExp, { isComplete } from "regex-partial-match";
31
- *
32
- * const partial = new PartialMatchRegExp(/^\d{4}-\d{2}-\d{2}/);
33
- * const match = partial.exec('2024-06');
34
- *
35
- * match !== null && isComplete(partial, match); // false - keep typing
36
- * ```
37
- */
38
- export default function isComplete(partial: PartialMatchRegExp, match: RegExpExecArray): boolean;
@@ -1,41 +0,0 @@
1
- import { compiledPartial, truncationProbeCache } from "../partialMatchInternals.js";
2
- import isMatchComplete from "./isMatchComplete.js";
3
- /**
4
- * Whether `match` — a match `partial` produced — is a match of the original
5
- * pattern, or merely a prefix of it.
6
- *
7
- * `true` means every atom matched literally, so the path the match took is
8
- * one the original pattern could have taken itself. `false` means the match
9
- * depended on the input running out: it took a `|$(?![\s\S])` truncation
10
- * branch, so more input is needed and its captures are provisional.
11
- *
12
- * Complete is not the same as final: `/hello \w+/` matches `"hello world"`
13
- * completely, and would match more of `"hello worldly"`.
14
- *
15
- * The implication runs one way only. The original pattern may also match at
16
- * this index by some *other* path — yielding the same text, and even the
17
- * same captures — so re-testing the original answers "does anything match
18
- * here?", not "did this result depend on truncation?", and cannot recover
19
- * this answer.
20
- *
21
- * @param partial - The `PartialMatchRegExp` instance that produced `match`
22
- * @param match - A match returned by `partial.exec()`
23
- * @returns `true` when the match is complete, `false` when it is a prefix
24
- *
25
- * @remarks
26
- * Requires ES2018+ regardless of the pattern — the probe this builds uses
27
- * named capturing groups internally, unlike `exec()` and `test()`.
28
- *
29
- * @example
30
- * ```typescript
31
- * import PartialMatchRegExp, { isComplete } from "regex-partial-match";
32
- *
33
- * const partial = new PartialMatchRegExp(/^\d{4}-\d{2}-\d{2}/);
34
- * const match = partial.exec('2024-06');
35
- *
36
- * match !== null && isComplete(partial, match); // false - keep typing
37
- * ```
38
- */
39
- export default function isComplete(partial, match) {
40
- return isMatchComplete(partial[compiledPartial], match, partial.flags, partial[truncationProbeCache]);
41
- }
@@ -1,3 +0,0 @@
1
- import type { CompiledPartial } from "../compilePartial/compiled.ts";
2
- import type { TruncationProbeCache } from "./truncationProbeCache.ts";
3
- export default function isMatchComplete(compiled: CompiledPartial, match: RegExpExecArray, flags: string, cache: TruncationProbeCache): boolean;
@@ -1,14 +0,0 @@
1
- import { buildTruncationProbe, tookTruncationBranch } from "./truncationProbe.js";
2
- import { backreferenceExpansion } from "../backreferenceExpansion.js";
3
- export default function isMatchComplete(compiled, match, flags, cache) {
4
- var _a, _b;
5
- if (compiled.kind === "dynamic") {
6
- const expansion = match[backreferenceExpansion];
7
- if (expansion === undefined)
8
- return true;
9
- (_a = expansion.probe) !== null && _a !== void 0 ? _a : (expansion.probe = buildTruncationProbe(expansion.parts, compiled.rawLookarounds, compiled.namedGroupOpenings, flags));
10
- return !tookTruncationBranch(expansion.probe, match.input, match.index);
11
- }
12
- (_b = cache.probe) !== null && _b !== void 0 ? _b : (cache.probe = buildTruncationProbe(compiled.parts, compiled.rawLookarounds, compiled.namedGroupOpenings, flags));
13
- return !tookTruncationBranch(cache.probe, match.input, match.index);
14
- }
@@ -1,28 +0,0 @@
1
- import { DISJUNCTION_TO_END_OF_INPUT, OPTIONAL_ATOM_OPENING, NAMED_GROUP_OPENING } from "../atomSyntax.js";
2
- import { isBackreference } from "../part.js";
3
- function isGroupOpen(part) {
4
- return (part === "(" ||
5
- (part.startsWith(NAMED_GROUP_OPENING) &&
6
- !"=!".includes(part[NAMED_GROUP_OPENING.length])));
7
- }
8
- function isRawLookaroundOpen(part) {
9
- return (part.startsWith("(?!") ||
10
- part.startsWith(NAMED_GROUP_OPENING + "=") ||
11
- part.startsWith(NAMED_GROUP_OPENING + "!"));
12
- }
13
- function endsAtTruncationBranch(part) {
14
- return (part === DISJUNCTION_TO_END_OF_INPUT ||
15
- (part.startsWith(OPTIONAL_ATOM_OPENING) &&
16
- part.endsWith(DISJUNCTION_TO_END_OF_INPUT)));
17
- }
18
- export function roleOf(part) {
19
- if (isBackreference(part))
20
- return "backreference";
21
- if (isRawLookaroundOpen(part))
22
- return "rawLookaround";
23
- if (isGroupOpen(part))
24
- return "groupOpen";
25
- if (endsAtTruncationBranch(part))
26
- return "truncationEnd";
27
- return "plain";
28
- }
@@ -1,8 +0,0 @@
1
- import { type Part, type RawLookaroundInfo } from "../part.ts";
2
- export interface TruncationProbe {
3
- regex: RegExp;
4
- markerName: string;
5
- markerCount: number;
6
- }
7
- export declare const buildTruncationProbe: (parts: readonly Part[], rawLookarounds: readonly RawLookaroundInfo[], namedGroupOpenings: readonly string[], flags: string) => TruncationProbe;
8
- export declare const tookTruncationBranch: (probe: TruncationProbe, input: string, index: number) => boolean;
@@ -1,105 +0,0 @@
1
- import { legacyEscapeAsLiteral } from "../legacyEscape.js";
2
- import { DISJUNCTION_TO_END_OF_INPUT, OPTIONAL_ATOM_OPENING } from "../atomSyntax.js";
3
- import { groupNameOf, decodeGroupName } from "../groupName.js";
4
- import { isBackreference, isNumericBackreference } from "../part.js";
5
- import { roleOf } from "./partRole.js";
6
- const TRUNCATION_MARKER_NAME = "truncation";
7
- const FLAGS_INCOMPATIBLE_WITH_PROBING = /[dgy]/g;
8
- function groupShiftTable(rawLookarounds, roles) {
9
- const shiftForGroup = [0];
10
- let markerCount = 0;
11
- let rawLookaroundIndex = 0;
12
- for (const role of roles) {
13
- switch (role) {
14
- case "backreference":
15
- case "truncationEnd":
16
- markerCount++;
17
- break;
18
- case "groupOpen":
19
- shiftForGroup.push(markerCount);
20
- break;
21
- case "rawLookaround": {
22
- const { capturingGroupsOpened } = rawLookarounds[rawLookaroundIndex++];
23
- for (let i = 0; i < capturingGroupsOpened; i++) {
24
- shiftForGroup.push(markerCount);
25
- }
26
- break;
27
- }
28
- case "plain":
29
- break;
30
- }
31
- }
32
- return shiftForGroup;
33
- }
34
- function renumberedToken(backreference, shiftForGroup) {
35
- return isNumericBackreference(backreference)
36
- ? "\\" + String(backreference.ref + shiftForGroup[backreference.ref])
37
- : "\\k<" + backreference.ref + ">";
38
- }
39
- function renumberRawBackreferences(part, info, shiftForGroup, declaresNamedGroup) {
40
- let renumbered = "";
41
- let cursor = 0;
42
- for (const backreference of info.backreferences) {
43
- const relativeStart = backreference.start - info.sourceStart;
44
- const relativeEnd = backreference.end - info.sourceStart;
45
- renumbered +=
46
- part.slice(cursor, relativeStart) +
47
- rawReferenceReplacement(part.slice(relativeStart, relativeEnd), backreference, shiftForGroup, declaresNamedGroup);
48
- cursor = relativeEnd;
49
- }
50
- return renumbered + part.slice(cursor);
51
- }
52
- function rawReferenceReplacement(spelling, backreference, shiftForGroup, declaresNamedGroup) {
53
- if (isNumericBackreference(backreference)) {
54
- return backreference.ref >= 1 && backreference.ref < shiftForGroup.length
55
- ? "\\" + String(backreference.ref + shiftForGroup[backreference.ref])
56
- : legacyEscapeAsLiteral(spelling.slice(1));
57
- }
58
- return declaresNamedGroup ? spelling : "k" + spelling.slice(2);
59
- }
60
- export const buildTruncationProbe = (parts, rawLookarounds, namedGroupOpenings, flags) => {
61
- const declaresNamedGroup = namedGroupOpenings.length > 0;
62
- const declaredNames = namedGroupOpenings.map((opening) => decodeGroupName(groupNameOf(opening)));
63
- let markerName = TRUNCATION_MARKER_NAME;
64
- while (declaredNames.some((name) => name.startsWith(markerName))) {
65
- markerName += "_";
66
- }
67
- const roles = parts.map(roleOf);
68
- const shiftForGroup = groupShiftTable(rawLookarounds, roles);
69
- let markerCount = 0;
70
- let rawLookaroundIndex = 0;
71
- const probed = parts.map((part, index) => {
72
- if (isBackreference(part)) {
73
- const marker = "|(?<" + markerName + String(markerCount++) + ">)";
74
- return (OPTIONAL_ATOM_OPENING +
75
- renumberedToken(part, shiftForGroup) +
76
- marker +
77
- DISJUNCTION_TO_END_OF_INPUT.slice(1));
78
- }
79
- if (roles[index] === "rawLookaround") {
80
- return renumberRawBackreferences(part, rawLookarounds[rawLookaroundIndex++], shiftForGroup, declaresNamedGroup);
81
- }
82
- if (roles[index] !== "truncationEnd")
83
- return part;
84
- const marker = "|(?<" + markerName + String(markerCount++) + ">)";
85
- return (part.slice(0, -DISJUNCTION_TO_END_OF_INPUT.length) +
86
- marker +
87
- DISJUNCTION_TO_END_OF_INPUT.slice(1));
88
- });
89
- return {
90
- regex: new RegExp(probed.join(""), flags.replace(FLAGS_INCOMPATIBLE_WITH_PROBING, "") + "y"),
91
- markerName,
92
- markerCount
93
- };
94
- };
95
- export const tookTruncationBranch = (probe, input, index) => {
96
- var _a, _b;
97
- const { regex, markerName, markerCount } = probe;
98
- regex.lastIndex = index;
99
- const markers = (_b = (_a = regex.exec(input)) === null || _a === void 0 ? void 0 : _a.groups) !== null && _b !== void 0 ? _b : {};
100
- for (let marker = 0; marker < markerCount; marker++) {
101
- if (markers[markerName + String(marker)] !== undefined)
102
- return true;
103
- }
104
- return false;
105
- };
@@ -1,4 +0,0 @@
1
- import type { TruncationProbe } from "./truncationProbe.ts";
2
- export interface TruncationProbeCache {
3
- probe: TruncationProbe | undefined;
4
- }