clarity-pattern-parser 7.0.1 → 7.0.3

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
+ }
@@ -13,5 +13,6 @@ export declare class Grammar {
13
13
  private _getPattern;
14
14
  private _buildAnd;
15
15
  private _buildRepeat;
16
+ private _buildAlias;
16
17
  static parse(expression: string): Map<string, Pattern>;
17
18
  }
@@ -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.
@@ -1711,6 +1721,7 @@
1711
1721
  orLiteral,
1712
1722
  andLiteral,
1713
1723
  repeatLiteral,
1724
+ name.clone("alias-literal"),
1714
1725
  ]);
1715
1726
  const statement = new And("statement", [
1716
1727
  optionalSpaces,
@@ -1784,7 +1795,7 @@
1784
1795
  else {
1785
1796
  cursor.moveTo(firstIndex);
1786
1797
  cursor.resolveError();
1787
- cursor.recordErrorAt(firstIndex, this);
1798
+ cursor.recordErrorAt(firstIndex, firstIndex, this);
1788
1799
  }
1789
1800
  return null;
1790
1801
  }
@@ -1852,12 +1863,13 @@
1852
1863
  }
1853
1864
  this._text = text;
1854
1865
  this._cursor = new Cursor(text);
1866
+ this._cursor.startRecording();
1855
1867
  let errorAtIndex = null;
1856
1868
  const ast = this._pattern.parse(this._cursor);
1857
1869
  const isComplete = (ast === null || ast === void 0 ? void 0 : ast.value) === text;
1858
1870
  const options = this._getAllOptions();
1859
1871
  if (this._cursor.hasError && this._cursor.furthestError != null) {
1860
- errorAtIndex = this._cursor.furthestError.index;
1872
+ errorAtIndex = this._cursor.furthestError.endIndex;
1861
1873
  errorAtIndex = options.reduce((errorAtIndex, option) => Math.max(errorAtIndex, option.startIndex), errorAtIndex);
1862
1874
  }
1863
1875
  return {
@@ -1869,7 +1881,20 @@
1869
1881
  };
1870
1882
  }
1871
1883
  _getAllOptions() {
1872
- 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();
1873
1898
  }
1874
1899
  _createSuggestionsFromRoot() {
1875
1900
  const suggestions = [];
@@ -1880,7 +1905,7 @@
1880
1905
  return suggestions;
1881
1906
  }
1882
1907
  _createSuggestionsFromMatch(match) {
1883
- if (!match.pattern) {
1908
+ if (match.pattern == null) {
1884
1909
  return this._createSuggestions(-1, this._getTokensForPattern(this._pattern));
1885
1910
  }
1886
1911
  const leafPattern = match.pattern;
@@ -2057,6 +2082,10 @@
2057
2082
  this._buildRepeat(n);
2058
2083
  break;
2059
2084
  }
2085
+ case "alias-literal": {
2086
+ this._buildAlias(n);
2087
+ break;
2088
+ }
2060
2089
  }
2061
2090
  });
2062
2091
  }
@@ -2162,6 +2191,15 @@
2162
2191
  const repeat = new Repeat(name, pattern.clone(pattern.name, isPatternOptional), options);
2163
2192
  this._parseContext.patternsByName.set(name, repeat);
2164
2193
  }
2194
+ _buildAlias(statementNode) {
2195
+ const nameNode = statementNode.find(n => n.name === "name");
2196
+ const aliasNode = statementNode.find(n => n.name === "alias-literal");
2197
+ const aliasName = aliasNode.value;
2198
+ const name = nameNode.value;
2199
+ const pattern = this._getPattern(aliasName);
2200
+ const alias = pattern.clone(name);
2201
+ this._parseContext.patternsByName.set(name, alias);
2202
+ }
2165
2203
  static parse(expression) {
2166
2204
  const grammar = new Grammar();
2167
2205
  return grammar.parse(expression);