clarity-pattern-parser 7.0.2 → 8.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.
package/biome.json ADDED
@@ -0,0 +1,257 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/1.8.1/schema.json",
3
+ "css": {
4
+ "parser": {
5
+ "cssModules": true
6
+ }
7
+ },
8
+ "files": {
9
+ "ignore": [
10
+ "package.json",
11
+ "**/*.yml",
12
+ "node_modules/",
13
+ "storybook-static/",
14
+ ".yarn/",
15
+ ".vscode/",
16
+ "coverage/",
17
+ "dist/",
18
+ "build/",
19
+ "**/*.d.ts",
20
+ "**/@types/",
21
+ "**/__mocks__/"
22
+ ]
23
+ },
24
+ "formatter": {
25
+ "enabled": true,
26
+ "formatWithErrors": false,
27
+ "indentStyle": "space",
28
+ "indentWidth": 2,
29
+ "lineEnding": "lf",
30
+ "lineWidth": 90,
31
+ "attributePosition": "auto"
32
+ },
33
+ "organizeImports": { "enabled": true },
34
+ "linter": {
35
+ "enabled": true,
36
+ "rules": {
37
+ "recommended": false,
38
+ "a11y": {
39
+ "noAccessKey": "warn",
40
+ "noAriaUnsupportedElements": "warn",
41
+ "noBlankTarget": "warn",
42
+ "noDistractingElements": "warn",
43
+ "noHeaderScope": "warn",
44
+ "noRedundantAlt": "warn",
45
+ "noRedundantRoles": "warn",
46
+ "useAltText": "warn",
47
+ "useAnchorContent": "warn",
48
+ "useAriaActivedescendantWithTabindex": "warn",
49
+ "useAriaPropsForRole": "warn",
50
+ "useHeadingContent": "warn",
51
+ "useIframeTitle": "warn",
52
+ "useValidAnchor": "warn",
53
+ "useValidAriaProps": "warn",
54
+ "useValidAriaRole": "warn",
55
+ "useValidAriaValues": "warn"
56
+ },
57
+ "complexity": {
58
+ "noMultipleSpacesInRegularExpressionLiterals": "warn",
59
+ "noUselessConstructor": "warn",
60
+ "noUselessLabel": "warn",
61
+ "noUselessLoneBlockStatements": "warn",
62
+ "noUselessRename": "warn",
63
+ "noWith": "warn"
64
+ },
65
+ "correctness": {
66
+ "noConstAssign": "warn",
67
+ "noEmptyCharacterClassInRegex": "warn",
68
+ "noEmptyPattern": "warn",
69
+ "noGlobalObjectCalls": "warn",
70
+ "noInvalidUseBeforeDeclaration": "warn",
71
+ "noNewSymbol": "warn",
72
+ "noSelfAssign": "warn",
73
+ "noUndeclaredVariables": "error",
74
+ "noUnreachable": "warn",
75
+ "noUnreachableSuper": "warn",
76
+ "noUnusedLabels": "warn",
77
+ "noUnusedVariables": "warn",
78
+ "useArrayLiterals": "warn",
79
+ "useExhaustiveDependencies": "error",
80
+ "useHookAtTopLevel": "error",
81
+ "useIsNan": "warn",
82
+ "useYield": "warn"
83
+ },
84
+ "security": {
85
+ "noDangerouslySetInnerHtmlWithChildren": "warn",
86
+ "noGlobalEval": "warn"
87
+ },
88
+ "style": {
89
+ "noCommaOperator": "warn",
90
+ "noRestrictedGlobals": {
91
+ "level": "error",
92
+ "options": {
93
+ "deniedGlobals": [
94
+ "addEventListener",
95
+ "blur",
96
+ "close",
97
+ "closed",
98
+ "confirm",
99
+ "defaultStatus",
100
+ "defaultstatus",
101
+ "event",
102
+ "external",
103
+ "find",
104
+ "focus",
105
+ "frameElement",
106
+ "frames",
107
+ "history",
108
+ "innerHeight",
109
+ "innerWidth",
110
+ "length",
111
+ "location",
112
+ "locationbar",
113
+ "menubar",
114
+ "moveBy",
115
+ "moveTo",
116
+ "name",
117
+ "onblur",
118
+ "onerror",
119
+ "onfocus",
120
+ "onload",
121
+ "onresize",
122
+ "onunload",
123
+ "open",
124
+ "opener",
125
+ "opera",
126
+ "outerHeight",
127
+ "outerWidth",
128
+ "pageXOffset",
129
+ "pageYOffset",
130
+ "parent",
131
+ "print",
132
+ "removeEventListener",
133
+ "resizeBy",
134
+ "resizeTo",
135
+ "screen",
136
+ "screenLeft",
137
+ "screenTop",
138
+ "screenX",
139
+ "screenY",
140
+ "scroll",
141
+ "scrollbars",
142
+ "scrollBy",
143
+ "scrollTo",
144
+ "scrollX",
145
+ "scrollY",
146
+ "self",
147
+ "status",
148
+ "statusbar",
149
+ "stop",
150
+ "toolbar",
151
+ "top",
152
+ "setInterval",
153
+ "setTimeout",
154
+ "clearInterval",
155
+ "clearTimeout"
156
+ ]
157
+ }
158
+ }
159
+ },
160
+ "suspicious": {
161
+ "noCatchAssign": "warn",
162
+ "noCommentText": "warn",
163
+ "noControlCharactersInRegex": "warn",
164
+ "noDoubleEquals": "warn",
165
+ "noDuplicateCase": "warn",
166
+ "noDuplicateClassMembers": "warn",
167
+ "noDuplicateJsxProps": "warn",
168
+ "noDuplicateObjectKeys": "warn",
169
+ "noDuplicateParameters": "warn",
170
+ "noFallthroughSwitchClause": "off",
171
+ "noFunctionAssign": "warn",
172
+ "noLabelVar": "warn",
173
+ "noRedeclare": "warn",
174
+ "noSelfCompare": "warn",
175
+ "noShadowRestrictedNames": "warn",
176
+ "useGetterReturn": "warn",
177
+ "useValidTypeof": "warn"
178
+ }
179
+ }
180
+ },
181
+ "javascript": {
182
+ "formatter": {
183
+ "jsxQuoteStyle": "double",
184
+ "quoteProperties": "asNeeded",
185
+ "trailingCommas": "es5",
186
+ "semicolons": "always",
187
+ "arrowParentheses": "asNeeded",
188
+ "bracketSpacing": true,
189
+ "bracketSameLine": false,
190
+ "quoteStyle": "single",
191
+ "attributePosition": "auto"
192
+ }
193
+ },
194
+ "overrides": [
195
+ {
196
+ "include": [
197
+ "*.test.ts",
198
+ "*.test.tsx",
199
+ "*.test.js",
200
+ "*.test.jsx",
201
+ "test.js",
202
+ "test.jsx",
203
+ "test.ts",
204
+ "test.tsx",
205
+ "testUtils.ts",
206
+ "testUtils.tsx"
207
+ ],
208
+ "linter": { "rules": {} }
209
+ },
210
+ {
211
+ "include": ["*.ts", "*.tsx"],
212
+ "linter": {
213
+ "rules": {
214
+ "complexity": {
215
+ "noBannedTypes": "warn",
216
+ "noUselessConstructor": "warn",
217
+ "noUselessTypeConstraint": "error"
218
+ },
219
+ "correctness": {
220
+ "noInvalidUseBeforeDeclaration": "off",
221
+ "noPrecisionLoss": "error",
222
+ "noUndeclaredVariables": "off",
223
+ "noUnusedVariables": "warn",
224
+ "useArrayLiterals": "off"
225
+ },
226
+ "style": {
227
+ "noInferrableTypes": "warn",
228
+ "noNamespace": "error",
229
+ "noNonNullAssertion": "warn",
230
+ "useAsConstAssertion": "error",
231
+ "useConsistentArrayType": "warn"
232
+ },
233
+ "suspicious": {
234
+ "noDuplicateClassMembers": "off",
235
+ "noEmptyBlockStatements": "off",
236
+ "noExplicitAny": "off",
237
+ "noExtraNonNullAssertion": "error",
238
+ "noMisleadingInstantiator": "error",
239
+ "noRedeclare": "off",
240
+ "useNamespaceKeyword": "error"
241
+ }
242
+ }
243
+ }
244
+ },
245
+ {
246
+ "include": [
247
+ "*.stories.@(ts|tsx|js|jsx|mjs|cjs)",
248
+ "*.story.@(ts|tsx|js|jsx|mjs|cjs)"
249
+ ],
250
+ "linter": { "rules": {} }
251
+ },
252
+ {
253
+ "include": [".storybook/main.@(js|cjs|mjs|ts)"],
254
+ "linter": { "rules": {} }
255
+ }
256
+ ]
257
+ }
@@ -183,8 +183,9 @@
183
183
  }
184
184
 
185
185
  class ParseError {
186
- constructor(index, pattern) {
187
- this.index = index;
186
+ constructor(startIndex, endIndex, pattern) {
187
+ this.startIndex = startIndex;
188
+ this.endIndex = endIndex;
188
189
  this.pattern = pattern;
189
190
  }
190
191
  }
@@ -250,7 +251,7 @@
250
251
  var _a;
251
252
  let parent = (_a = m.pattern) === null || _a === void 0 ? void 0 : _a.parent;
252
253
  while (parent != null) {
253
- if (parent == pattern.parent) {
254
+ if (parent === pattern.parent) {
254
255
  return true;
255
256
  }
256
257
  parent = parent.parent;
@@ -262,10 +263,10 @@
262
263
  }
263
264
  }
264
265
  }
265
- recordErrorAt(index, pattern) {
266
- const error = new ParseError(index, pattern);
266
+ recordErrorAt(firstIndex, lastIndex, pattern) {
267
+ const error = new ParseError(firstIndex, lastIndex, pattern);
267
268
  this._currentError = error;
268
- if (this._furthestError === null || index > this._furthestError.index) {
269
+ if (this._furthestError === null || lastIndex > this._furthestError.endIndex) {
269
270
  this._furthestError = error;
270
271
  }
271
272
  if (this._isRecording) {
@@ -320,6 +321,9 @@
320
321
  get error() {
321
322
  return this._history.error;
322
323
  }
324
+ get errors() {
325
+ return this._history.errors;
326
+ }
323
327
  get index() {
324
328
  return this._index;
325
329
  }
@@ -368,8 +372,8 @@
368
372
  recordMatch(pattern, node) {
369
373
  this._history.recordMatch(pattern, node);
370
374
  }
371
- recordErrorAt(index, onPattern) {
372
- this._history.recordErrorAt(index, onPattern);
375
+ recordErrorAt(firstIndex, lastIndex, onPattern) {
376
+ this._history.recordErrorAt(firstIndex, lastIndex, onPattern);
373
377
  }
374
378
  resolveError() {
375
379
  this._history.resolveError();
@@ -395,6 +399,7 @@
395
399
  this._parent = null;
396
400
  this._firstIndex = 0;
397
401
  this._lastIndex = 0;
402
+ this._endIndex = 0;
398
403
  }
399
404
  get type() {
400
405
  return this._type;
@@ -437,7 +442,7 @@
437
442
  return node;
438
443
  }
439
444
  if (!this._isOptional) {
440
- cursor.recordErrorAt(cursor.index, this);
445
+ cursor.recordErrorAt(this._firstIndex, this._endIndex, this);
441
446
  return null;
442
447
  }
443
448
  cursor.resolveError();
@@ -451,6 +456,7 @@
451
456
  const literalRune = this._runes[i];
452
457
  const cursorRune = cursor.currentChar;
453
458
  if (literalRune !== cursorRune) {
459
+ this._endIndex = cursor.index;
454
460
  break;
455
461
  }
456
462
  if (i + 1 === literalRuneLength) {
@@ -459,6 +465,7 @@
459
465
  break;
460
466
  }
461
467
  if (!cursor.hasNext()) {
468
+ this._endIndex = cursor.index + 1;
462
469
  break;
463
470
  }
464
471
  cursor.next();
@@ -505,6 +512,7 @@
505
512
  constructor(name, regex, isOptional = false) {
506
513
  this._node = null;
507
514
  this._cursor = null;
515
+ this._firstIndex = -1;
508
516
  this._substring = "";
509
517
  this._tokens = [];
510
518
  this._type = "regex";
@@ -558,6 +566,7 @@
558
566
  };
559
567
  }
560
568
  parse(cursor) {
569
+ this._firstIndex = cursor.index;
561
570
  this.resetState(cursor);
562
571
  this.tryToParse(cursor);
563
572
  return this._node;
@@ -586,7 +595,7 @@
586
595
  }
587
596
  processError(cursor) {
588
597
  if (!this._isOptional) {
589
- cursor.recordErrorAt(cursor.index, this);
598
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
590
599
  }
591
600
  this._node = null;
592
601
  }
@@ -824,7 +833,7 @@
824
833
  return node;
825
834
  }
826
835
  if (!this._isOptional) {
827
- cursor.recordErrorAt(this._firstIndex, this);
836
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
828
837
  return null;
829
838
  }
830
839
  cursor.resolveError();
@@ -963,7 +972,7 @@
963
972
  }
964
973
  if (matchCount < this._min) {
965
974
  cursor.moveTo(startIndex);
966
- cursor.recordErrorAt(startIndex, this);
975
+ cursor.recordErrorAt(startIndex, startIndex, this);
967
976
  return null;
968
977
  }
969
978
  else if (nodes.length === 0) {
@@ -1026,7 +1035,7 @@
1026
1035
  getPatternsAfter(childReference) {
1027
1036
  const childIndex = this._children.indexOf(childReference);
1028
1037
  // If Reference Pattern isn't a child.
1029
- if (childIndex == -1) {
1038
+ if (childIndex === -1) {
1030
1039
  return [];
1031
1040
  }
1032
1041
  // If Reference Pattern is the last pattern. Ask for the parents next patterns
@@ -1141,6 +1150,7 @@
1141
1150
  return this._nodes.length >= this._min;
1142
1151
  }
1143
1152
  _tryToParse(cursor) {
1153
+ const firstIndex = cursor.index;
1144
1154
  let passed = false;
1145
1155
  while (true) {
1146
1156
  const runningCursorIndex = cursor.index;
@@ -1152,7 +1162,7 @@
1152
1162
  }
1153
1163
  else {
1154
1164
  cursor.moveTo(runningCursorIndex);
1155
- cursor.recordErrorAt(runningCursorIndex, this._pattern);
1165
+ cursor.recordErrorAt(firstIndex, runningCursorIndex, this._pattern);
1156
1166
  passed = false;
1157
1167
  }
1158
1168
  break;
@@ -1188,7 +1198,7 @@
1188
1198
  return passed;
1189
1199
  }
1190
1200
  else if (!hasMinimum && passed) {
1191
- cursor.recordErrorAt(cursor.index, this);
1201
+ cursor.recordErrorAt(firstIndex, cursor.index, this);
1192
1202
  cursor.moveTo(this._firstIndex);
1193
1203
  return false;
1194
1204
  }
@@ -1293,7 +1303,7 @@
1293
1303
  this._pattern = pattern;
1294
1304
  this._parent = null;
1295
1305
  this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
1296
- if (this._options.max != Infinity) {
1306
+ if (this._options.max !== Infinity) {
1297
1307
  this._repeatPattern = new FiniteRepeat(name, pattern, this._options.max, this._options);
1298
1308
  }
1299
1309
  else {
@@ -1481,7 +1491,7 @@
1481
1491
  break;
1482
1492
  }
1483
1493
  // We didn't finish the parsing sequence.
1484
- cursor.recordErrorAt(cursor.index + 1, this);
1494
+ cursor.recordErrorAt(this._firstIndex, cursor.index + 1, this);
1485
1495
  break;
1486
1496
  }
1487
1497
  }
@@ -1496,7 +1506,7 @@
1496
1506
  // If we don't have any results from what we parsed then record error.
1497
1507
  const lastNode = this.getLastValidNode();
1498
1508
  if (lastNode === null) {
1499
- cursor.recordErrorAt(cursor.index, this);
1509
+ cursor.recordErrorAt(this._firstIndex, cursor.index, this);
1500
1510
  break;
1501
1511
  }
1502
1512
  // The sequence was parsed fully.
@@ -1785,7 +1795,7 @@
1785
1795
  else {
1786
1796
  cursor.moveTo(firstIndex);
1787
1797
  cursor.resolveError();
1788
- cursor.recordErrorAt(firstIndex, this);
1798
+ cursor.recordErrorAt(firstIndex, firstIndex, this);
1789
1799
  }
1790
1800
  return null;
1791
1801
  }
@@ -1853,12 +1863,13 @@
1853
1863
  }
1854
1864
  this._text = text;
1855
1865
  this._cursor = new Cursor(text);
1866
+ this._cursor.startRecording();
1856
1867
  let errorAtIndex = null;
1857
1868
  const ast = this._pattern.parse(this._cursor);
1858
1869
  const isComplete = (ast === null || ast === void 0 ? void 0 : ast.value) === text;
1859
1870
  const options = this._getAllOptions();
1860
1871
  if (this._cursor.hasError && this._cursor.furthestError != null) {
1861
- errorAtIndex = this._cursor.furthestError.index;
1872
+ errorAtIndex = this._cursor.furthestError.endIndex;
1862
1873
  errorAtIndex = options.reduce((errorAtIndex, option) => Math.max(errorAtIndex, option.startIndex), errorAtIndex);
1863
1874
  }
1864
1875
  return {
@@ -1870,7 +1881,20 @@
1870
1881
  };
1871
1882
  }
1872
1883
  _getAllOptions() {
1873
- return this._cursor.leafMatches.map((m) => this._createSuggestionsFromMatch(m)).flat();
1884
+ const errorMatches = this._getOptionsFromErrors();
1885
+ const leafMatches = this._cursor.leafMatches.map((m) => this._createSuggestionsFromMatch(m)).flat();
1886
+ const finalResults = errorMatches.filter(m => leafMatches.findIndex(l => l.text === m.text) === -1);
1887
+ return [...leafMatches, ...finalResults];
1888
+ }
1889
+ _getOptionsFromErrors() {
1890
+ // These errored because the length of the string.
1891
+ const errors = this._cursor.errors.filter(e => e.endIndex === this._cursor.length);
1892
+ const suggestions = errors.map(e => {
1893
+ const tokens = this._getTokensForPattern(e.pattern);
1894
+ const adjustedTokens = tokens.map(t => t.slice(e.endIndex - e.startIndex));
1895
+ return this._createSuggestions(e.endIndex, adjustedTokens);
1896
+ });
1897
+ return suggestions.flat();
1874
1898
  }
1875
1899
  _createSuggestionsFromRoot() {
1876
1900
  const suggestions = [];
@@ -1881,7 +1905,7 @@
1881
1905
  return suggestions;
1882
1906
  }
1883
1907
  _createSuggestionsFromMatch(match) {
1884
- if (!match.pattern) {
1908
+ if (match.pattern == null) {
1885
1909
  return this._createSuggestions(-1, this._getTokensForPattern(this._pattern));
1886
1910
  }
1887
1911
  const leafPattern = match.pattern;