@invariant-ui/cli 0.0.0-stage → 0.2.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 (190) hide show
  1. package/LICENSE +105 -0
  2. package/README.md +250 -2
  3. package/dist/agent-kit/apply.js +232 -0
  4. package/dist/agent-kit/guidance.js +236 -0
  5. package/dist/agent-kit/index.js +5 -0
  6. package/dist/agent-kit/integrations.js +121 -0
  7. package/dist/agent-kit/plugin.js +115 -0
  8. package/dist/artifact-generator/index.js +75 -0
  9. package/dist/browser-verify/driver.js +2 -0
  10. package/dist/browser-verify/index.js +4 -0
  11. package/dist/browser-verify/playwright.js +82 -0
  12. package/dist/browser-verify/runner.js +175 -0
  13. package/dist/browser-verify/spec.js +103 -0
  14. package/dist/cli/args.js +77 -0
  15. package/dist/cli/baseline.js +64 -0
  16. package/dist/cli/cli.js +121 -0
  17. package/dist/cli/commands-browser.js +104 -0
  18. package/dist/cli/commands-discover.js +312 -0
  19. package/dist/cli/commands-enforcement.js +35 -0
  20. package/dist/cli/commands-governance.js +179 -0
  21. package/dist/cli/commands-hook.js +269 -0
  22. package/dist/cli/commands-patterns.js +324 -0
  23. package/dist/cli/commands-setup.js +485 -0
  24. package/dist/cli/commands-validate.js +157 -0
  25. package/dist/cli/commands.js +517 -0
  26. package/dist/cli/config.js +197 -0
  27. package/dist/cli/diff.js +66 -0
  28. package/dist/cli/enforcement-log.js +83 -0
  29. package/dist/cli/enforcement-report.js +96 -0
  30. package/dist/cli/errors.js +10 -0
  31. package/dist/cli/format.js +22 -0
  32. package/dist/cli/index.js +5 -0
  33. package/dist/cli/io.js +2 -0
  34. package/dist/cli/main.js +31 -0
  35. package/dist/cli/pipeline.js +262 -0
  36. package/dist/cli/publish.js +77 -0
  37. package/dist/cli/report.js +127 -0
  38. package/dist/cli/starter-rules.js +57 -0
  39. package/dist/cli/store.js +60 -0
  40. package/dist/cli/version.js +5 -0
  41. package/dist/cli/watch.js +68 -0
  42. package/dist/cli/workflow.js +52 -0
  43. package/dist/compiler-angular/adapter.js +115 -0
  44. package/dist/compiler-angular/analyze.js +222 -0
  45. package/dist/compiler-angular/classes.js +446 -0
  46. package/dist/compiler-angular/declared.js +285 -0
  47. package/dist/compiler-angular/emit.js +183 -0
  48. package/dist/compiler-angular/index.js +4 -0
  49. package/dist/compiler-angular/template.js +142 -0
  50. package/dist/compiler-core/adapter.js +2 -0
  51. package/dist/compiler-core/adapters/inventory.js +312 -0
  52. package/dist/compiler-core/compile.js +148 -0
  53. package/dist/compiler-core/component-facts.js +123 -0
  54. package/dist/compiler-core/discovery/docs.js +66 -0
  55. package/dist/compiler-core/discovery/entries.js +270 -0
  56. package/dist/compiler-core/discovery/exports.js +207 -0
  57. package/dist/compiler-core/discovery/graph.js +59 -0
  58. package/dist/compiler-core/discovery/index.js +103 -0
  59. package/dist/compiler-core/discovery/packages.js +148 -0
  60. package/dist/compiler-core/discovery/schema.js +144 -0
  61. package/dist/compiler-core/discovery/storybook.js +232 -0
  62. package/dist/compiler-core/discovery/support.js +82 -0
  63. package/dist/compiler-core/discovery/tokens.js +186 -0
  64. package/dist/compiler-core/discovery/tooling.js +146 -0
  65. package/dist/compiler-core/fs.js +89 -0
  66. package/dist/compiler-core/glob.js +3 -0
  67. package/dist/compiler-core/index.js +16 -0
  68. package/dist/compiler-core/ir-builder.js +68 -0
  69. package/dist/compiler-core/json-schema.js +11 -0
  70. package/dist/compiler-core/testing/index.js +81 -0
  71. package/dist/compiler-core/ts/ast.js +166 -0
  72. package/dist/compiler-core/ts/members.js +163 -0
  73. package/dist/compiler-core/ts/program.js +81 -0
  74. package/dist/compiler-core/ts/static-eval.js +145 -0
  75. package/dist/compiler-core/ts/tsconfig-paths.js +60 -0
  76. package/dist/compiler-core/walk.js +46 -0
  77. package/dist/compiler-ir/index.js +4 -0
  78. package/dist/compiler-ir/ir.js +67 -0
  79. package/dist/compiler-ir/json-schema.js +6 -0
  80. package/dist/compiler-ir/validate.js +116 -0
  81. package/dist/compiler-react/adapter.js +147 -0
  82. package/dist/compiler-react/analyze.js +199 -0
  83. package/dist/compiler-react/behavior.js +75 -0
  84. package/dist/compiler-react/detect.js +558 -0
  85. package/dist/compiler-react/emit.js +188 -0
  86. package/dist/compiler-react/index.js +2 -0
  87. package/dist/compiler-react/props.js +157 -0
  88. package/dist/compiler-react/styling.js +138 -0
  89. package/dist/compiler-react/usage.js +116 -0
  90. package/dist/compiler-react/variants.js +111 -0
  91. package/dist/compiler-storybook/adapter.js +253 -0
  92. package/dist/compiler-storybook/csf.js +521 -0
  93. package/dist/compiler-storybook/emit.js +202 -0
  94. package/dist/compiler-storybook/index-json.js +41 -0
  95. package/dist/compiler-storybook/index.js +5 -0
  96. package/dist/compiler-storybook/mdx.js +120 -0
  97. package/dist/compiler-tokens/adapter.js +158 -0
  98. package/dist/compiler-tokens/css.js +59 -0
  99. package/dist/compiler-tokens/index.js +5 -0
  100. package/dist/compiler-tokens/json-lines.js +106 -0
  101. package/dist/compiler-tokens/json-tokens.js +52 -0
  102. package/dist/compiler-vue/adapter.js +107 -0
  103. package/dist/compiler-vue/analyze.js +344 -0
  104. package/dist/compiler-vue/declared.js +343 -0
  105. package/dist/compiler-vue/emit.js +129 -0
  106. package/dist/compiler-vue/index.js +5 -0
  107. package/dist/compiler-vue/script.js +472 -0
  108. package/dist/compiler-vue/sfc.js +44 -0
  109. package/dist/compiler-vue/template.js +73 -0
  110. package/dist/contract/archetype-checks.js +153 -0
  111. package/dist/contract/components.js +102 -0
  112. package/dist/contract/conflicts.js +39 -0
  113. package/dist/contract/contract.js +46 -0
  114. package/dist/contract/evidence.js +84 -0
  115. package/dist/contract/fact-path.js +39 -0
  116. package/dist/contract/facts.js +62 -0
  117. package/dist/contract/index.js +16 -0
  118. package/dist/contract/integrity.js +21 -0
  119. package/dist/contract/json-schema.js +11 -0
  120. package/dist/contract/knowledge.js +95 -0
  121. package/dist/contract/pattern-checks.js +254 -0
  122. package/dist/contract/patterns.js +225 -0
  123. package/dist/contract/primitives.js +81 -0
  124. package/dist/contract/sources.js +30 -0
  125. package/dist/contract/tokens.js +41 -0
  126. package/dist/contract/validate.js +253 -0
  127. package/dist/contract-query/archetype.js +188 -0
  128. package/dist/contract-query/index.js +6 -0
  129. package/dist/contract-query/patterns.js +298 -0
  130. package/dist/contract-query/search.js +132 -0
  131. package/dist/contract-query/system.js +148 -0
  132. package/dist/contract-query/views.js +288 -0
  133. package/dist/governance/decisions.js +229 -0
  134. package/dist/governance/index.js +5 -0
  135. package/dist/governance/patterns-file.js +156 -0
  136. package/dist/governance/patterns.js +510 -0
  137. package/dist/governance/policies.js +148 -0
  138. package/dist/mcp/index.js +7 -0
  139. package/dist/mcp/loader.js +70 -0
  140. package/dist/mcp/protocol.js +27 -0
  141. package/dist/mcp/resources.js +138 -0
  142. package/dist/mcp/server.js +177 -0
  143. package/dist/mcp/stdio.js +28 -0
  144. package/dist/mcp/tools.js +267 -0
  145. package/dist/reconciliation/code.js +62 -0
  146. package/dist/reconciliation/components.js +401 -0
  147. package/dist/reconciliation/conflicts.js +126 -0
  148. package/dist/reconciliation/facts.js +41 -0
  149. package/dist/reconciliation/index.js +7 -0
  150. package/dist/reconciliation/reconcile.js +134 -0
  151. package/dist/reconciliation/resolve.js +158 -0
  152. package/dist/reconciliation/review.js +81 -0
  153. package/dist/reconciliation/storybook.js +370 -0
  154. package/dist/reconciliation/tokens.js +179 -0
  155. package/dist/reconciliation/util.js +55 -0
  156. package/dist/semantic-engine/additive.js +51 -0
  157. package/dist/semantic-engine/compounds.js +91 -0
  158. package/dist/semantic-engine/documents.js +157 -0
  159. package/dist/semantic-engine/enrich.js +42 -0
  160. package/dist/semantic-engine/index.js +7 -0
  161. package/dist/semantic-engine/infer.js +38 -0
  162. package/dist/semantic-engine/tokens.js +120 -0
  163. package/dist/shared/canonical.js +65 -0
  164. package/dist/shared/diagnostic.js +78 -0
  165. package/dist/shared/glob.js +98 -0
  166. package/dist/shared/index.js +4 -0
  167. package/dist/shared/json.js +2 -0
  168. package/dist/validation/card.js +50 -0
  169. package/dist/validation/discovery/arrangements.js +162 -0
  170. package/dist/validation/discovery/discover.js +70 -0
  171. package/dist/validation/discovery/index.js +8 -0
  172. package/dist/validation/discovery/model.js +127 -0
  173. package/dist/validation/discovery/promote.js +24 -0
  174. package/dist/validation/discovery/reviews.js +63 -0
  175. package/dist/validation/discovery/shapes.js +47 -0
  176. package/dist/validation/discovery/similar-files.js +146 -0
  177. package/dist/validation/discovery/util.js +47 -0
  178. package/dist/validation/index.js +11 -0
  179. package/dist/validation/interaction-facts.js +341 -0
  180. package/dist/validation/interaction-workflows.js +633 -0
  181. package/dist/validation/literals.js +251 -0
  182. package/dist/validation/pattern-rules.js +608 -0
  183. package/dist/validation/policy.js +241 -0
  184. package/dist/validation/report.js +163 -0
  185. package/dist/validation/rules.js +269 -0
  186. package/dist/validation/scan.js +295 -0
  187. package/dist/validation/text.js +34 -0
  188. package/dist/validation/validate-code.js +513 -0
  189. package/dist/validation/validate-usage.js +196 -0
  190. package/package.json +38 -4
@@ -0,0 +1,295 @@
1
+ import ts from "typescript";
2
+ const dyn = (text) => ({ expression: text.replace(/\s+/g, " ").trim().slice(0, 80) });
3
+ function jsxValue(init, sf) {
4
+ if (!init)
5
+ return true;
6
+ if (ts.isStringLiteral(init))
7
+ return init.text;
8
+ if (ts.isJsxExpression(init) && init.expression) {
9
+ const e = init.expression;
10
+ if (ts.isStringLiteralLike(e))
11
+ return e.text;
12
+ if (ts.isNumericLiteral(e))
13
+ return Number(e.text);
14
+ if (e.kind === ts.SyntaxKind.TrueKeyword)
15
+ return true;
16
+ if (e.kind === ts.SyntaxKind.FalseKeyword)
17
+ return false;
18
+ if (e.kind === ts.SyntaxKind.NullKeyword)
19
+ return null;
20
+ return dyn(e.getText(sf));
21
+ }
22
+ return dyn(init.getText(sf));
23
+ }
24
+ /** JSX elements and import bindings in a TypeScript/JavaScript snippet, by syntax only. Nothing is evaluated. */
25
+ export function scanJsx(code, filename = "snippet.tsx") {
26
+ const kind = /\.jsx?$/i.test(filename) ? ts.ScriptKind.JSX : ts.ScriptKind.TSX;
27
+ const sf = ts.createSourceFile(filename, code, ts.ScriptTarget.Latest, true, kind);
28
+ const uses = [];
29
+ const imports = new Map();
30
+ for (const stmt of sf.statements) {
31
+ if (!ts.isImportDeclaration(stmt) || !ts.isStringLiteral(stmt.moduleSpecifier))
32
+ continue;
33
+ const module = stmt.moduleSpecifier.text;
34
+ const clause = stmt.importClause;
35
+ if (!clause)
36
+ continue;
37
+ if (clause.name)
38
+ imports.set(clause.name.text, { module, imported: "default" });
39
+ const bindings = clause.namedBindings;
40
+ if (bindings && ts.isNamespaceImport(bindings))
41
+ imports.set(bindings.name.text, { module, imported: "*" });
42
+ else if (bindings)
43
+ for (const el of bindings.elements)
44
+ imports.set(el.name.text, { module, imported: (el.propertyName ?? el.name).text });
45
+ }
46
+ const unwrap = (node) => {
47
+ let n = node;
48
+ while (ts.isParenthesizedExpression(n) || ts.isAsExpression(n) || ts.isNonNullExpression(n))
49
+ n = n.expression;
50
+ return n;
51
+ };
52
+ const isJsx = (n) => ts.isJsxElement(n) || ts.isJsxSelfClosingElement(n) || ts.isJsxFragment(n);
53
+ const containsJsx = (n) => {
54
+ let found = false;
55
+ const look = (c) => {
56
+ if (found)
57
+ return;
58
+ if (isJsx(c))
59
+ found = true;
60
+ else
61
+ ts.forEachChild(c, look);
62
+ };
63
+ look(n);
64
+ return found;
65
+ };
66
+ /** True when this element is what a component returns (directly or through a conditional), not a value stored elsewhere. */
67
+ const isRendered = (node) => {
68
+ let child = node;
69
+ for (let p = node.parent; p; child = p, p = p.parent) {
70
+ if (ts.isParenthesizedExpression(p) || ts.isAsExpression(p) || ts.isNonNullExpression(p))
71
+ continue;
72
+ if (ts.isReturnStatement(p))
73
+ return true;
74
+ if (ts.isArrowFunction(p))
75
+ return p.body === child;
76
+ if (ts.isConditionalExpression(p)) {
77
+ if (p.condition === child)
78
+ return false;
79
+ continue;
80
+ }
81
+ if (ts.isBinaryExpression(p) &&
82
+ [
83
+ ts.SyntaxKind.AmpersandAmpersandToken,
84
+ ts.SyntaxKind.BarBarToken,
85
+ ts.SyntaxKind.QuestionQuestionToken
86
+ ].includes(p.operatorToken.kind))
87
+ continue;
88
+ return false;
89
+ }
90
+ return false;
91
+ };
92
+ const isOpaqueChild = (child) => {
93
+ if (!ts.isJsxExpression(child) || !child.expression)
94
+ return false;
95
+ const e = unwrap(child.expression);
96
+ if (ts.isStringLiteralLike(e) || ts.isNumericLiteral(e))
97
+ return false;
98
+ return !containsJsx(e);
99
+ };
100
+ const visit = (node, parent, depth, loop) => {
101
+ let next = parent;
102
+ let nextDepth = depth;
103
+ let nextLoop = loop;
104
+ if (ts.isJsxElement(node) || ts.isJsxSelfClosingElement(node)) {
105
+ const opening = ts.isJsxElement(node) ? node.openingElement : node;
106
+ const attrs = {};
107
+ let spread = false;
108
+ for (const a of opening.attributes.properties) {
109
+ if (ts.isJsxSpreadAttribute(a))
110
+ spread = true;
111
+ else
112
+ attrs[a.name.getText(sf)] = jsxValue(a.initializer, sf);
113
+ }
114
+ const hasChildren = ts.isJsxElement(node)
115
+ ? node.children.some((c) => !(ts.isJsxText(c) && c.containsOnlyTriviaWhiteSpaces))
116
+ : false;
117
+ const opaque = spread ||
118
+ "children" in attrs ||
119
+ "dangerouslySetInnerHTML" in attrs ||
120
+ (ts.isJsxElement(node) && node.children.some(isOpaqueChild));
121
+ const pos = sf.getLineAndCharacterOfPosition(node.getStart(sf));
122
+ // A root element that is not returned (a variable, an argument) is not placed in the tree here.
123
+ const level = parent === undefined && !isRendered(node) ? depth + 1 : depth;
124
+ uses.push({
125
+ tag: opening.tagName.getText(sf),
126
+ line: pos.line + 1,
127
+ column: pos.character + 1,
128
+ attrs,
129
+ hasChildren,
130
+ hasSpread: spread,
131
+ parent,
132
+ exprDepth: level,
133
+ loopDepth: loop,
134
+ opaque
135
+ });
136
+ next = uses.length - 1;
137
+ nextDepth = level;
138
+ }
139
+ else if (ts.isJsxExpression(node)) {
140
+ // `icon={<Icon />}` is an element handed to its parent as a prop, not a condition or a loop.
141
+ const direct = ts.isJsxAttribute(node.parent) && node.expression !== undefined && isJsx(unwrap(node.expression));
142
+ if (!direct)
143
+ nextDepth = depth + 1;
144
+ }
145
+ else if ((ts.isArrowFunction(node) || ts.isFunctionExpression(node)) && depth > 0) {
146
+ nextLoop = loop + 1;
147
+ }
148
+ ts.forEachChild(node, (child) => visit(child, next, nextDepth, nextLoop));
149
+ };
150
+ visit(sf, undefined, 0, 0);
151
+ return { uses, imports };
152
+ }
153
+ const RAW_TEXT = new Set(["script", "style"]);
154
+ const VOID = new Set([
155
+ "area",
156
+ "base",
157
+ "br",
158
+ "col",
159
+ "embed",
160
+ "hr",
161
+ "img",
162
+ "input",
163
+ "link",
164
+ "meta",
165
+ "source",
166
+ "track",
167
+ "wbr"
168
+ ]);
169
+ const camel = (n) => /^(data|aria)-/.test(n) ? n : n.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
170
+ /**
171
+ * Element start tags in an HTML-like template (Vue, Angular, HTML), with their nesting. A single linear pass:
172
+ * no DOM, no expression evaluation. Event handlers, structural directives and references are skipped;
173
+ * bindings are kept as dynamic values.
174
+ */
175
+ export function scanMarkup(code) {
176
+ const uses = [];
177
+ const stack = [];
178
+ let i = 0;
179
+ let line = 1;
180
+ let lineStart = 0;
181
+ const n = code.length;
182
+ const advance = (to) => {
183
+ for (; i < to && i < n; i++)
184
+ if (code[i] === "\n") {
185
+ line++;
186
+ lineStart = i + 1;
187
+ }
188
+ };
189
+ while (i < n) {
190
+ const lt = code.indexOf("<", i);
191
+ if (lt < 0)
192
+ break;
193
+ advance(lt);
194
+ if (code.startsWith("<!--", i)) {
195
+ const end = code.indexOf("-->", i + 4);
196
+ advance(end < 0 ? n : end + 3);
197
+ continue;
198
+ }
199
+ if (code.startsWith("</", i)) {
200
+ const close = /^<\/([A-Za-z][A-Za-z0-9_.:-]*)/.exec(code.slice(i, i + 130));
201
+ if (close) {
202
+ const at = stack.map((s) => s.tag).lastIndexOf(close[1]);
203
+ if (at >= 0)
204
+ stack.length = at;
205
+ }
206
+ advance(i + 2);
207
+ continue;
208
+ }
209
+ const m = /^<([A-Za-z][A-Za-z0-9_.:-]*)/.exec(code.slice(i, i + 130));
210
+ if (!m) {
211
+ advance(i + 1);
212
+ continue;
213
+ }
214
+ const tag = m[1];
215
+ const startLine = line;
216
+ const startColumn = i - lineStart + 1;
217
+ let j = i + m[0].length;
218
+ const attrs = {};
219
+ let spread = false;
220
+ let selfClosing = false;
221
+ while (j < n) {
222
+ while (j < n && /\s/.test(code[j]))
223
+ j++;
224
+ const c = code[j];
225
+ if (c === undefined)
226
+ break;
227
+ if (c === ">") {
228
+ j++;
229
+ break;
230
+ }
231
+ if (c === "/" && code[j + 1] === ">") {
232
+ selfClosing = true;
233
+ j += 2;
234
+ break;
235
+ }
236
+ const nm = /^[^\s=>/"']+/.exec(code.slice(j, j + 200));
237
+ if (!nm) {
238
+ j++;
239
+ continue;
240
+ }
241
+ const raw = nm[0];
242
+ j += raw.length;
243
+ let value;
244
+ let k = j;
245
+ while (k < n && /\s/.test(code[k]))
246
+ k++;
247
+ if (code[k] === "=") {
248
+ k++;
249
+ while (k < n && /\s/.test(code[k]))
250
+ k++;
251
+ const q = code[k];
252
+ if (q === '"' || q === "'") {
253
+ const end = code.indexOf(q, k + 1);
254
+ value = code.slice(k + 1, end < 0 ? n : end);
255
+ j = end < 0 ? n : end + 1;
256
+ }
257
+ else {
258
+ const um = /^[^\s>]+/.exec(code.slice(k, k + 200));
259
+ value = um?.[0] ?? "";
260
+ j = k + value.length;
261
+ }
262
+ }
263
+ if (/^(@|\(|v-on:|v-on$|#|\*|v-if|v-else|v-for|v-show|v-model|v-slot|ng)/.test(raw) &&
264
+ !/^\[/.test(raw)) {
265
+ if (raw === "v-bind" || raw.startsWith("v-bind="))
266
+ spread = true;
267
+ continue;
268
+ }
269
+ const bound = /^(:|v-bind:|\[)/.test(raw);
270
+ const name = camel(raw
271
+ .replace(/^(:|v-bind:)/, "")
272
+ .replace(/^\[|\]$/g, "")
273
+ .replace(/^attr\./, ""));
274
+ attrs[name] = bound ? dyn(value ?? "") : value === undefined ? true : value;
275
+ }
276
+ uses.push({
277
+ tag,
278
+ line: startLine,
279
+ column: startColumn,
280
+ attrs,
281
+ hasChildren: selfClosing ? false : undefined,
282
+ hasSpread: spread,
283
+ parent: stack[stack.length - 1]?.index
284
+ });
285
+ if (!selfClosing && !VOID.has(tag.toLowerCase()) && !RAW_TEXT.has(tag.toLowerCase()))
286
+ stack.push({ tag, index: uses.length - 1 });
287
+ advance(j);
288
+ if (RAW_TEXT.has(tag.toLowerCase()) && !selfClosing) {
289
+ const close = code.toLowerCase().indexOf(`</${tag.toLowerCase()}`, i);
290
+ advance(close < 0 ? n : close);
291
+ }
292
+ }
293
+ return uses;
294
+ }
295
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1,34 @@
1
+ /** Edit distance, capped: returns `limit + 1` as soon as the distance must exceed `limit`. */
2
+ export function distance(a, b, limit) {
3
+ if (Math.abs(a.length - b.length) > limit)
4
+ return limit + 1;
5
+ let prev = Array.from({ length: b.length + 1 }, (_, i) => i);
6
+ for (let i = 1; i <= a.length; i++) {
7
+ const cur = [i];
8
+ let best = i;
9
+ for (let j = 1; j <= b.length; j++) {
10
+ const v = Math.min(prev[j] + 1, cur[j - 1] + 1, prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
11
+ cur.push(v);
12
+ if (v < best)
13
+ best = v;
14
+ }
15
+ if (best > limit)
16
+ return limit + 1;
17
+ prev = cur;
18
+ }
19
+ return prev[b.length];
20
+ }
21
+ /** Up to `max` candidates close to `name`, nearest first. Case-insensitive; never suggests the name itself. */
22
+ export function nearest(name, candidates, max = 3) {
23
+ const n = name.toLowerCase();
24
+ const limit = Math.max(2, Math.floor(n.length / 3));
25
+ return [...new Set(candidates)]
26
+ .filter((c) => c.toLowerCase() !== n)
27
+ .map((c) => ({ c, d: distance(n, c.toLowerCase(), limit) }))
28
+ .filter((x) => x.d <= limit)
29
+ .sort((a, b) => a.d - b.d || (a.c < b.c ? -1 : 1))
30
+ .slice(0, max)
31
+ .map((x) => x.c);
32
+ }
33
+ export const quoteList = (values) => values.map((v) => JSON.stringify(v)).join(", ");
34
+ //# sourceMappingURL=text.js.map