@orz/query 0.0.0-stage → 0.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/LICENSE +29 -0
- package/README.md +103 -2
- package/dist/braces.d.ts +32 -0
- package/dist/braces.d.ts.map +1 -0
- package/dist/braces.js +127 -0
- package/dist/braces.js.map +1 -0
- package/dist/commands.d.ts +109 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +260 -0
- package/dist/commands.js.map +1 -0
- package/dist/completion.d.ts +166 -0
- package/dist/completion.d.ts.map +1 -0
- package/dist/completion.js +400 -0
- package/dist/completion.js.map +1 -0
- package/dist/diagnostics.d.ts +20 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +63 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/query.d.ts +119 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +449 -0
- package/dist/query.js.map +1 -0
- package/dist/shell-words.d.ts +38 -0
- package/dist/shell-words.d.ts.map +1 -0
- package/dist/shell-words.js +136 -0
- package/dist/shell-words.js.map +1 -0
- package/dist/suggest.d.ts +7 -0
- package/dist/suggest.d.ts.map +1 -0
- package/dist/suggest.js +44 -0
- package/dist/suggest.js.map +1 -0
- package/dist/values.d.ts +70 -0
- package/dist/values.d.ts.map +1 -0
- package/dist/values.js +91 -0
- package/dist/values.js.map +1 -0
- package/package.json +32 -3
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Completion at the caret, the pure half: what is being typed, where it
|
|
3
|
+
* starts and ends, and which values fit. Fetching and rendering stay with
|
|
4
|
+
* the editor that asks — a search box and a CodeMirror panel read the same
|
|
5
|
+
* slot.
|
|
6
|
+
*/
|
|
7
|
+
import { rawWord } from "./commands.js";
|
|
8
|
+
import { quoteQueryValue, } from "./query.js";
|
|
9
|
+
import { quoteShellWord, segmentValue, shellWords, } from "./shell-words.js";
|
|
10
|
+
const EMPTY = { matched: false, rows: [] };
|
|
11
|
+
function unitsOf(word, from) {
|
|
12
|
+
const units = [];
|
|
13
|
+
for (const segment of word.segments) {
|
|
14
|
+
if (segment.end <= from)
|
|
15
|
+
continue;
|
|
16
|
+
if (segment.quoted !== "none") {
|
|
17
|
+
units.push({
|
|
18
|
+
start: segment.start,
|
|
19
|
+
end: segment.end,
|
|
20
|
+
bare: null,
|
|
21
|
+
text: segmentValue(word, segment),
|
|
22
|
+
});
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
for (let i = Math.max(segment.start, from); i < segment.end; i += 1) {
|
|
26
|
+
const ch = word.raw[i - word.start] ?? "";
|
|
27
|
+
units.push({ start: i, end: i + 1, bare: ch, text: ch });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return units;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Where the current alternative of the innermost brace group still open at
|
|
34
|
+
* the end of `units` starts, or null when no group is open: then a brace is
|
|
35
|
+
* an ordinary character of the value being typed.
|
|
36
|
+
*/
|
|
37
|
+
function openAlternative(units) {
|
|
38
|
+
const stack = [];
|
|
39
|
+
for (const unit of units) {
|
|
40
|
+
if (unit.bare === "{")
|
|
41
|
+
stack.push(unit.end);
|
|
42
|
+
else if (unit.bare === "}")
|
|
43
|
+
stack.pop();
|
|
44
|
+
else if (unit.bare === "," && stack.length > 0) {
|
|
45
|
+
stack[stack.length - 1] = unit.end;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return stack.at(-1) ?? null;
|
|
49
|
+
}
|
|
50
|
+
const decode = (units, from) => units
|
|
51
|
+
.filter((u) => u.start >= from)
|
|
52
|
+
.map((u) => u.text)
|
|
53
|
+
.join("");
|
|
54
|
+
/**
|
|
55
|
+
* The rest of an alternative past the caret, so accepting `ui` in
|
|
56
|
+
* `{web,u|i}` replaces `ui` rather than leaving an `i` behind. Only bare
|
|
57
|
+
* characters count; a quote or a separator ends it.
|
|
58
|
+
*/
|
|
59
|
+
function alternativeTail(text, caret) {
|
|
60
|
+
const match = /^[^\s,{}'"\\]*/.exec(text.slice(caret));
|
|
61
|
+
return caret + (match?.[0].length ?? 0);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Plain mode: the units of a filter's values up to the caret. A quoted run
|
|
65
|
+
* only opens where a value (or an alternative) starts, which is the only
|
|
66
|
+
* place plain mode reads one; null when the caret is inside it.
|
|
67
|
+
*/
|
|
68
|
+
function plainUnits(query, from, caret) {
|
|
69
|
+
const units = [];
|
|
70
|
+
let i = from;
|
|
71
|
+
let valueStart = from;
|
|
72
|
+
const stack = [];
|
|
73
|
+
while (i < caret) {
|
|
74
|
+
const ch = query[i];
|
|
75
|
+
if (ch === '"' && (i === valueStart || i === stack.at(-1))) {
|
|
76
|
+
const close = query.indexOf('"', i + 1);
|
|
77
|
+
if (close === -1 || close >= caret)
|
|
78
|
+
return null;
|
|
79
|
+
units.push({
|
|
80
|
+
start: i,
|
|
81
|
+
end: close + 1,
|
|
82
|
+
bare: null,
|
|
83
|
+
text: query.slice(i + 1, close),
|
|
84
|
+
});
|
|
85
|
+
i = close + 1;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
units.push({ start: i, end: i + 1, bare: ch, text: ch });
|
|
89
|
+
if (ch === "{")
|
|
90
|
+
stack.push(i + 1);
|
|
91
|
+
else if (ch === "}")
|
|
92
|
+
stack.pop();
|
|
93
|
+
else if (ch === ",") {
|
|
94
|
+
if (stack.length > 0)
|
|
95
|
+
stack[stack.length - 1] = i + 1;
|
|
96
|
+
else
|
|
97
|
+
valueStart = i + 1;
|
|
98
|
+
}
|
|
99
|
+
i += 1;
|
|
100
|
+
}
|
|
101
|
+
return units;
|
|
102
|
+
}
|
|
103
|
+
function queryAlternative(schema, query, part, caret) {
|
|
104
|
+
const valuesFrom = part.keyEnd + 1;
|
|
105
|
+
let units;
|
|
106
|
+
let open = false;
|
|
107
|
+
if (schema.escapes === "shell") {
|
|
108
|
+
const word = shellWords(query.slice(part.start, caret), part.start)[0];
|
|
109
|
+
if (word === undefined)
|
|
110
|
+
return null;
|
|
111
|
+
units = unitsOf(word, valuesFrom);
|
|
112
|
+
open = word.unclosed === true;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
units = plainUnits(query, valuesFrom, caret);
|
|
116
|
+
}
|
|
117
|
+
if (units === null)
|
|
118
|
+
return null;
|
|
119
|
+
const from = openAlternative(units);
|
|
120
|
+
if (from === null)
|
|
121
|
+
return null;
|
|
122
|
+
const to = open ? caret : alternativeTail(query, caret);
|
|
123
|
+
return { from, to, typed: decode(units, from) + query.slice(caret, to) };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* The slot under the caret in a query: a value where the caret stands after
|
|
127
|
+
* a known key's colon, else the bare word the caret stands in (or an empty
|
|
128
|
+
* one where it stands) as a key. Null where a key cannot go at all: inside a
|
|
129
|
+
* filter's key, and inside quotes, which is how one asks for a literal.
|
|
130
|
+
*/
|
|
131
|
+
export function queryCompletionSlot(schema, parts, query, caret) {
|
|
132
|
+
for (const part of parts) {
|
|
133
|
+
if (caret < part.start || caret > part.end)
|
|
134
|
+
continue;
|
|
135
|
+
if (part.kind === "filter") {
|
|
136
|
+
const valuesFrom = part.keyEnd + 1;
|
|
137
|
+
if (caret < valuesFrom)
|
|
138
|
+
return null;
|
|
139
|
+
const spec = schema.qualifiers[part.key]?.value;
|
|
140
|
+
if (spec === undefined)
|
|
141
|
+
return null;
|
|
142
|
+
const group = schema.braces
|
|
143
|
+
? queryAlternative(schema, query, part, caret)
|
|
144
|
+
: null;
|
|
145
|
+
if (group !== null) {
|
|
146
|
+
return { kind: "value", ...group, spec, key: part.key, inBraces: true };
|
|
147
|
+
}
|
|
148
|
+
// The value the caret is inside, or the empty one it is sitting at.
|
|
149
|
+
const on = part.values.find((v) => caret >= v.start && caret <= v.end);
|
|
150
|
+
return {
|
|
151
|
+
kind: "value",
|
|
152
|
+
from: on?.start ?? caret,
|
|
153
|
+
to: on?.end ?? caret,
|
|
154
|
+
typed: on?.value ?? "",
|
|
155
|
+
spec,
|
|
156
|
+
key: part.key,
|
|
157
|
+
inBraces: false,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (part.kind === "text") {
|
|
161
|
+
if (part.raw.startsWith('"'))
|
|
162
|
+
return null;
|
|
163
|
+
if (schema.escapes === "shell" && part.raw.startsWith("'"))
|
|
164
|
+
return null;
|
|
165
|
+
const text = query.slice(part.start, caret);
|
|
166
|
+
const negated = text.startsWith("-");
|
|
167
|
+
return {
|
|
168
|
+
kind: "key",
|
|
169
|
+
from: part.start,
|
|
170
|
+
to: caret,
|
|
171
|
+
typed: negated ? text.slice(1) : text,
|
|
172
|
+
negated,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return { kind: "key", from: caret, to: caret, typed: "", negated: false };
|
|
177
|
+
}
|
|
178
|
+
const FIRST_LEVEL = /^\/([a-z0-9-]*)$/;
|
|
179
|
+
const ARGUMENT_LEVEL = /^\/([a-z0-9-]+)[ \t]/;
|
|
180
|
+
/**
|
|
181
|
+
* The slot at the end of `lineBeforeCaret`: the command word itself, or the
|
|
182
|
+
* argument the caret is in. Null where the line cannot be a command, past
|
|
183
|
+
* the last argument, and for a command that takes none.
|
|
184
|
+
*/
|
|
185
|
+
export function commandCompletionSlot(registry, lineBeforeCaret) {
|
|
186
|
+
const line = lineBeforeCaret;
|
|
187
|
+
const first = FIRST_LEVEL.exec(line);
|
|
188
|
+
if (first !== null) {
|
|
189
|
+
return {
|
|
190
|
+
kind: "command",
|
|
191
|
+
from: 0,
|
|
192
|
+
to: line.length,
|
|
193
|
+
typed: first[1],
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
const head = ARGUMENT_LEVEL.exec(line);
|
|
197
|
+
if (head === null)
|
|
198
|
+
return null;
|
|
199
|
+
const command = registry.byName.get(head[1]);
|
|
200
|
+
if (command === undefined || command.args.length === 0)
|
|
201
|
+
return null;
|
|
202
|
+
const nameEnd = head[1].length + 1;
|
|
203
|
+
const caret = line.length;
|
|
204
|
+
const words = shellWords(line.slice(nameEnd), nameEnd);
|
|
205
|
+
// A word that ends before the caret is finished; the caret starts the next.
|
|
206
|
+
if (words.length > 0 && words.at(-1).end < caret) {
|
|
207
|
+
words.push(rawWord(line, caret));
|
|
208
|
+
}
|
|
209
|
+
else if (words.length === 0) {
|
|
210
|
+
words.push(rawWord(line, caret));
|
|
211
|
+
}
|
|
212
|
+
const last = command.args.length - 1;
|
|
213
|
+
let rest = false;
|
|
214
|
+
const restHead = words[last];
|
|
215
|
+
if (command.args[last]?.rest &&
|
|
216
|
+
restHead !== undefined &&
|
|
217
|
+
!/^['"]/.test(restHead.raw)) {
|
|
218
|
+
words.splice(last, words.length - last, rawWord(line, restHead.start));
|
|
219
|
+
rest = true;
|
|
220
|
+
}
|
|
221
|
+
const index = words.length - 1;
|
|
222
|
+
const spec = command.args[index];
|
|
223
|
+
if (spec === undefined)
|
|
224
|
+
return null;
|
|
225
|
+
const word = words[index];
|
|
226
|
+
let from = word.start;
|
|
227
|
+
let typed = word.value;
|
|
228
|
+
let inBraces = false;
|
|
229
|
+
if (spec.multiple) {
|
|
230
|
+
const units = unitsOf(word, word.start);
|
|
231
|
+
const alternative = openAlternative(units);
|
|
232
|
+
if (alternative !== null) {
|
|
233
|
+
from = alternative;
|
|
234
|
+
typed = decode(units, alternative);
|
|
235
|
+
inBraces = true;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
kind: "argument",
|
|
240
|
+
from,
|
|
241
|
+
to: caret,
|
|
242
|
+
typed,
|
|
243
|
+
spec: spec.value,
|
|
244
|
+
command: command.name,
|
|
245
|
+
index,
|
|
246
|
+
last: index === last,
|
|
247
|
+
optional: spec.optional === true,
|
|
248
|
+
rest,
|
|
249
|
+
inBraces,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* The values a slot can take: the enum's set, the specials, and the
|
|
254
|
+
* provider's snapshot, in that order. `"fetch"` tells the caller to ask a
|
|
255
|
+
* `search` provider for `slot.typed` and call again with what it answered.
|
|
256
|
+
*/
|
|
257
|
+
export function slotValues(slot, provider, fetched) {
|
|
258
|
+
const spec = slot.spec;
|
|
259
|
+
const builtins = [
|
|
260
|
+
...(spec.kind === "enum" ? spec.values : []),
|
|
261
|
+
...(spec.special ?? []),
|
|
262
|
+
].map((value) => ({ value }));
|
|
263
|
+
if (provider === undefined)
|
|
264
|
+
return builtins;
|
|
265
|
+
if ("search" in provider) {
|
|
266
|
+
return fetched === undefined ? "fetch" : [...builtins, ...fetched];
|
|
267
|
+
}
|
|
268
|
+
return [...builtins, ...(provider.options ?? [])];
|
|
269
|
+
}
|
|
270
|
+
/** Options that `typed` prefixes, case-insensitively. */
|
|
271
|
+
export function filterOptions(options, typed) {
|
|
272
|
+
const lower = typed.toLowerCase();
|
|
273
|
+
return options.filter((o) => o.value.toLowerCase().startsWith(lower));
|
|
274
|
+
}
|
|
275
|
+
/** Splice `text` over `[start, end)` and put the caret after it. */
|
|
276
|
+
export function splice(query, start, end, text) {
|
|
277
|
+
return {
|
|
278
|
+
value: query.slice(0, start) + text + query.slice(end),
|
|
279
|
+
caret: start + text.length,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Splice, and leave the caret past a space, so that taking an offer ends a
|
|
284
|
+
* word rather than parking the caret against the next one.
|
|
285
|
+
*
|
|
286
|
+
* Only values do this. A key is completed to its colon and the value comes
|
|
287
|
+
* next with nothing in between, so a space there would have to be deleted
|
|
288
|
+
* again.
|
|
289
|
+
*
|
|
290
|
+
* The cost, taken deliberately: a value can be a comma-separated list, and
|
|
291
|
+
* closing it after one value means a second one needs a backspace. That is
|
|
292
|
+
* the rare path; ending a word is every time.
|
|
293
|
+
*/
|
|
294
|
+
export function spliceThenSpace(query, start, end, text) {
|
|
295
|
+
const spliced = splice(query, start, end, text);
|
|
296
|
+
const after = spliced.value.slice(spliced.caret);
|
|
297
|
+
return {
|
|
298
|
+
value: /^\s/.test(after)
|
|
299
|
+
? spliced.value
|
|
300
|
+
: `${spliced.value.slice(0, spliced.caret)} ${after}`,
|
|
301
|
+
caret: spliced.caret + 1,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* How a value is spelled into a command argument: as one shell word, except
|
|
306
|
+
* in a rest argument's raw remainder, where quotes would be read literally.
|
|
307
|
+
*/
|
|
308
|
+
export function quoteArgument(slot, value) {
|
|
309
|
+
return slot.rest ? value : quoteShellWord(value);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Keys, offered against the word the caret is in. Only a non-empty prefix of
|
|
313
|
+
* a real key counts as a match; a bare space lists them all, below submit.
|
|
314
|
+
*/
|
|
315
|
+
export function keyRows(schema, query, slot) {
|
|
316
|
+
if (slot?.kind !== "key")
|
|
317
|
+
return EMPTY;
|
|
318
|
+
const typed = slot.typed.toLowerCase();
|
|
319
|
+
if (typed.includes(":"))
|
|
320
|
+
return EMPTY;
|
|
321
|
+
const keys = schema.keys.filter((k) => k.toLowerCase().startsWith(typed));
|
|
322
|
+
const minus = slot.negated ? "-" : "";
|
|
323
|
+
return {
|
|
324
|
+
matched: typed !== "" && keys.length > 0,
|
|
325
|
+
rows: keys.map((key) => {
|
|
326
|
+
const hint = schema.qualifiers[key]?.hint;
|
|
327
|
+
return {
|
|
328
|
+
id: `key:${key}`,
|
|
329
|
+
text: `${minus}${key}:`,
|
|
330
|
+
...(hint === undefined ? {} : { hint }),
|
|
331
|
+
icon: "key",
|
|
332
|
+
apply: splice(query, slot.from, slot.to, `${minus}${key}:`),
|
|
333
|
+
};
|
|
334
|
+
}),
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Values, offered whenever the caret stands where one goes. The colon is
|
|
339
|
+
* already typed by then, so the intent is not in doubt and this always counts
|
|
340
|
+
* as a match — including on an empty value, where the whole list is what the
|
|
341
|
+
* reader is asking for. `options` are offered as given; narrow them with
|
|
342
|
+
* `filterOptions` first. Inside a brace group no space follows, since the
|
|
343
|
+
* group is still open.
|
|
344
|
+
*/
|
|
345
|
+
export function valueRows(schema, query, slot, options) {
|
|
346
|
+
if (slot?.kind !== "value")
|
|
347
|
+
return EMPTY;
|
|
348
|
+
return {
|
|
349
|
+
matched: true,
|
|
350
|
+
rows: options.map((o) => {
|
|
351
|
+
const text = quoteQueryValue(schema, o.value);
|
|
352
|
+
return {
|
|
353
|
+
id: `value:${slot.key}:${o.value}`,
|
|
354
|
+
text,
|
|
355
|
+
...(o.hint === undefined ? {} : { hint: o.hint }),
|
|
356
|
+
icon: "value",
|
|
357
|
+
apply: slot.inBraces
|
|
358
|
+
? splice(query, slot.from, slot.to, text)
|
|
359
|
+
: spliceThenSpace(query, slot.from, slot.to, text),
|
|
360
|
+
};
|
|
361
|
+
}),
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* The offered rows, in order: **the submit row is first** unless something
|
|
366
|
+
* is genuinely being completed.
|
|
367
|
+
*
|
|
368
|
+
* The reader is typing a query, not filling in a form. Putting a completion
|
|
369
|
+
* above the submit row means Enter submits something they did not ask for,
|
|
370
|
+
* and the only evidence that they wanted one is that what they typed
|
|
371
|
+
* actually prefixes something. Everything else — the full list of keys after
|
|
372
|
+
* a space, say — is still shown, because that is how the syntax is
|
|
373
|
+
* discovered, but it waits below.
|
|
374
|
+
*
|
|
375
|
+
* `limit` is spent here rather than inside each source, so that a source
|
|
376
|
+
* added later lands in the same budget without having to remember one. The
|
|
377
|
+
* matched rows spend it first — they are what the reader is completing — the
|
|
378
|
+
* submit row is never spent, and whatever is left goes to the rest.
|
|
379
|
+
*
|
|
380
|
+
* A source marked `yields` waits for both of those to be served and takes
|
|
381
|
+
* only the remainder. History is the one that does in todou (T-270): a
|
|
382
|
+
* completion or a jump answers the string being typed right now, history
|
|
383
|
+
* answers what was searched before, and the keys are the only place the
|
|
384
|
+
* syntax can be discovered — so history is what gives way when the panel is
|
|
385
|
+
* full.
|
|
386
|
+
*/
|
|
387
|
+
export function orderRows(results, submit, limit = 20) {
|
|
388
|
+
const band = (yields, matched) => results
|
|
389
|
+
.filter((r) => (r.yields ?? false) === yields && r.matched === matched)
|
|
390
|
+
.flatMap((r) => r.rows);
|
|
391
|
+
const firmMatched = band(false, true);
|
|
392
|
+
const firmRest = band(false, false);
|
|
393
|
+
const room = Math.max(0, limit - firmMatched.length - firmRest.length);
|
|
394
|
+
const softMatched = band(true, true).slice(0, room);
|
|
395
|
+
const softRest = band(true, false).slice(0, room - softMatched.length);
|
|
396
|
+
const matched = [...firmMatched, ...softMatched].slice(0, limit);
|
|
397
|
+
const rest = [...firmRest, ...softRest].slice(0, limit - matched.length);
|
|
398
|
+
return [...matched, submit, ...rest];
|
|
399
|
+
}
|
|
400
|
+
//# sourceMappingURL=completion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CompiledQuerySchema, QueryPart } from "./query.ts";
|
|
2
|
+
import { type ValueProviders } from "./values.ts";
|
|
3
|
+
export type QueryDiagnostic = {
|
|
4
|
+
key: string;
|
|
5
|
+
value: string;
|
|
6
|
+
start: number;
|
|
7
|
+
end: number;
|
|
8
|
+
/** `"opne" is not a state (open, closed)` */
|
|
9
|
+
message: string;
|
|
10
|
+
suggestion: string | null;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* What a query gets wrong that this package can tell without the app:
|
|
14
|
+
* enum values outside their set, `named` values an `options` provider does
|
|
15
|
+
* not hold, failed brace expansions and too many qualifiers. A value whose
|
|
16
|
+
* verdict is `unknown` is never reported; the app's server, which can see
|
|
17
|
+
* its own rows, stays the authority for those.
|
|
18
|
+
*/
|
|
19
|
+
export declare function diagnoseQuery(schema: CompiledQuerySchema, parts: readonly QueryPart[], providers?: ValueProviders): QueryDiagnostic[];
|
|
20
|
+
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,EAGL,KAAK,cAAc,EAEpB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAKF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,mBAAmB,EAC3B,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,SAAS,CAAC,EAAE,cAAc,GACzB,eAAe,EAAE,CAgDnB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { didYouMean } from "./suggest.js";
|
|
2
|
+
import { providerOf, suggestionCandidates, valueVerdict, } from "./values.js";
|
|
3
|
+
const article = (word) => /^[aeiou]/i.test(word) ? `an ${word}` : `a ${word}`;
|
|
4
|
+
/**
|
|
5
|
+
* What a query gets wrong that this package can tell without the app:
|
|
6
|
+
* enum values outside their set, `named` values an `options` provider does
|
|
7
|
+
* not hold, failed brace expansions and too many qualifiers. A value whose
|
|
8
|
+
* verdict is `unknown` is never reported; the app's server, which can see
|
|
9
|
+
* its own rows, stays the authority for those.
|
|
10
|
+
*/
|
|
11
|
+
export function diagnoseQuery(schema, parts, providers) {
|
|
12
|
+
const diagnostics = [];
|
|
13
|
+
let filters = 0;
|
|
14
|
+
for (const part of parts) {
|
|
15
|
+
if (part.kind !== "filter")
|
|
16
|
+
continue;
|
|
17
|
+
filters += 1;
|
|
18
|
+
if (schema.maxFilters !== undefined && filters === schema.maxFilters + 1) {
|
|
19
|
+
const count = parts.filter((p) => p.kind === "filter").length;
|
|
20
|
+
diagnostics.push({
|
|
21
|
+
key: part.key,
|
|
22
|
+
value: part.raw,
|
|
23
|
+
start: part.start,
|
|
24
|
+
end: part.end,
|
|
25
|
+
message: `${count} qualifiers (at most ${schema.maxFilters})`,
|
|
26
|
+
suggestion: null,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
const spec = schema.qualifiers[part.key]?.value;
|
|
30
|
+
if (spec === undefined)
|
|
31
|
+
continue;
|
|
32
|
+
const provider = providerOf(spec, providers);
|
|
33
|
+
for (const value of part.values) {
|
|
34
|
+
const where = { key: part.key, start: value.start, end: value.end };
|
|
35
|
+
if (value.error !== undefined) {
|
|
36
|
+
diagnostics.push({
|
|
37
|
+
...where,
|
|
38
|
+
value: value.value,
|
|
39
|
+
message: `"${value.value}" ${value.error}`,
|
|
40
|
+
suggestion: null,
|
|
41
|
+
});
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
for (const each of value.expanded) {
|
|
45
|
+
if (each === "")
|
|
46
|
+
continue;
|
|
47
|
+
if (valueVerdict(spec, each, provider) !== "invalid")
|
|
48
|
+
continue;
|
|
49
|
+
const message = spec.kind === "enum"
|
|
50
|
+
? `"${each}" is not ${article(part.key)} (${spec.values.join(", ")})`
|
|
51
|
+
: `no ${part.key} named "${each}"`;
|
|
52
|
+
diagnostics.push({
|
|
53
|
+
...where,
|
|
54
|
+
value: each,
|
|
55
|
+
message,
|
|
56
|
+
suggestion: didYouMean(each, suggestionCandidates(spec, provider)),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return diagnostics;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EACL,UAAU,EACV,oBAAoB,EAEpB,YAAY,GACb,MAAM,aAAa,CAAC;AAYrB,MAAM,OAAO,GAAG,CAAC,IAAY,EAAU,EAAE,CACvC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;AAEtD;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,MAA2B,EAC3B,KAA2B,EAC3B,SAA0B;IAE1B,MAAM,WAAW,GAAsB,EAAE,CAAC;IAC1C,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;YAAE,SAAS;QACrC,OAAO,IAAI,CAAC,CAAC;QACb,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,IAAI,OAAO,KAAK,MAAM,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;YACzE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;YAC9D,WAAW,CAAC,IAAI,CAAC;gBACf,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,KAAK,EAAE,IAAI,CAAC,GAAG;gBACf,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,OAAO,EAAE,GAAG,KAAK,wBAAwB,MAAM,CAAC,UAAU,GAAG;gBAC7D,UAAU,EAAE,IAAI;aACjB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;QAChD,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS;QACjC,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC7C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC;YACpE,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC9B,WAAW,CAAC,IAAI,CAAC;oBACf,GAAG,KAAK;oBACR,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,OAAO,EAAE,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE;oBAC1C,UAAU,EAAE,IAAI;iBACjB,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAClC,IAAI,IAAI,KAAK,EAAE;oBAAE,SAAS;gBAC1B,IAAI,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,SAAS;oBAAE,SAAS;gBAC/D,MAAM,OAAO,GACX,IAAI,CAAC,IAAI,KAAK,MAAM;oBAClB,CAAC,CAAC,IAAI,IAAI,YAAY,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;oBACrE,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,WAAW,IAAI,GAAG,CAAC;gBACvC,WAAW,CAAC,IAAI,CAAC;oBACf,GAAG,KAAK;oBACR,KAAK,EAAE,IAAI;oBACX,OAAO;oBACP,UAAU,EAAE,UAAU,CAAC,IAAI,EAAE,oBAAoB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;iBACnE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { BRACE_LIMIT, type BraceExpansion, expandBraces, } from "./braces.ts";
|
|
2
|
+
export { type ArgSpec, type ArgValue, type CommandDef, type CommandRegistry, commandLinesOf, createCommandRegistry, type ParsedDraft, parseCommandLines, type RecognizedLine, recognizeCommandLine, slugifyCommandName, summarizeCommands, } from "./commands.ts";
|
|
3
|
+
export { type CompletionRow, type CompletionSlot, commandCompletionSlot, filterOptions, keyRows, orderRows, queryCompletionSlot, quoteArgument, type SourceResult, slotValues, splice, spliceThenSpace, type ValueSlot, valueRows, } from "./completion.ts";
|
|
4
|
+
export { diagnoseQuery, type QueryDiagnostic } from "./diagnostics.ts";
|
|
5
|
+
export { type CompiledQuerySchema, defineQuerySchema, parseQuery, type QualifierSpec, type QueryFilter, type QueryPart, type QuerySchema, type QueryValue, queryFilters, queryTerms, quoteQueryValue, } from "./query.ts";
|
|
6
|
+
export { quoteShellWord, type ShellSegment, type ShellWord, segmentValue, shellWords, } from "./shell-words.ts";
|
|
7
|
+
export { didYouMean } from "./suggest.ts";
|
|
8
|
+
export { canonicalValue, providerOf, specialValue, type ValueOption, type ValueProvider, type ValueProviders, type ValueSpec, type ValueVerdict, valueVerdict, worstVerdict, } from "./values.ts";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,KAAK,cAAc,EACnB,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,cAAc,EACd,qBAAqB,EACrB,KAAK,WAAW,EAChB,iBAAiB,EACjB,KAAK,cAAc,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,qBAAqB,EACrB,aAAa,EACb,OAAO,EACP,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,KAAK,YAAY,EACjB,UAAU,EACV,MAAM,EACN,eAAe,EACf,KAAK,SAAS,EACd,SAAS,GACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EACL,KAAK,mBAAmB,EACxB,iBAAiB,EACjB,UAAU,EACV,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,YAAY,EACZ,UAAU,EACV,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,YAAY,EACZ,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EACL,cAAc,EACd,UAAU,EACV,YAAY,EACZ,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,YAAY,EACZ,YAAY,GACb,MAAM,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { BRACE_LIMIT, expandBraces, } from "./braces.js";
|
|
2
|
+
export { commandLinesOf, createCommandRegistry, parseCommandLines, recognizeCommandLine, slugifyCommandName, summarizeCommands, } from "./commands.js";
|
|
3
|
+
export { commandCompletionSlot, filterOptions, keyRows, orderRows, queryCompletionSlot, quoteArgument, slotValues, splice, spliceThenSpace, valueRows, } from "./completion.js";
|
|
4
|
+
export { diagnoseQuery } from "./diagnostics.js";
|
|
5
|
+
export { defineQuerySchema, parseQuery, queryFilters, queryTerms, quoteQueryValue, } from "./query.js";
|
|
6
|
+
export { quoteShellWord, segmentValue, shellWords, } from "./shell-words.js";
|
|
7
|
+
export { didYouMean } from "./suggest.js";
|
|
8
|
+
export { canonicalValue, providerOf, specialValue, valueVerdict, worstVerdict, } from "./values.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAEX,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAKL,cAAc,EACd,qBAAqB,EAErB,iBAAiB,EAEjB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,OAAO,EAGL,qBAAqB,EACrB,aAAa,EACb,OAAO,EACP,SAAS,EACT,mBAAmB,EACnB,aAAa,EAEb,UAAU,EACV,MAAM,EACN,eAAe,EAEf,SAAS,GACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAwB,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAEL,iBAAiB,EACjB,UAAU,EAMV,YAAY,EACZ,UAAU,EACV,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,EAGd,YAAY,EACZ,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EACL,cAAc,EACd,UAAU,EACV,YAAY,EAMZ,YAAY,EACZ,YAAY,GACb,MAAM,aAAa,CAAC"}
|
package/dist/query.d.ts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A search query grammar over a schema the app supplies. The app's server
|
|
3
|
+
* parses `q` and executes it (authoritative); its web box parses the same
|
|
4
|
+
* string to colour it and to place completions; a CLI parses it to re-quote
|
|
5
|
+
* the values that carry spaces. One string carries the whole query, so "the
|
|
6
|
+
* same query gives the same results in the CLI and on the web" holds
|
|
7
|
+
* structurally instead of being a discipline two implementations have to
|
|
8
|
+
* keep.
|
|
9
|
+
*
|
|
10
|
+
* Nothing here decides whether a `named` value exists: `label:kind:bug`
|
|
11
|
+
* parses the same in a project that has that label and in one that does
|
|
12
|
+
* not. Names are resolved by the caller, which keeps this module a pure
|
|
13
|
+
* function on either side of the wire.
|
|
14
|
+
*/
|
|
15
|
+
import type { ValueSpec } from "./values.ts";
|
|
16
|
+
export type QualifierSpec = {
|
|
17
|
+
value: ValueSpec;
|
|
18
|
+
/** Other spellings of the key itself: `meta` for `metadata`. */
|
|
19
|
+
keyAliases?: readonly string[];
|
|
20
|
+
/** One-line inline reminder in the completion row: "open or closed". */
|
|
21
|
+
hint?: string;
|
|
22
|
+
};
|
|
23
|
+
export type QuerySchema<K extends string = string> = {
|
|
24
|
+
qualifiers: Readonly<Record<K, QualifierSpec>>;
|
|
25
|
+
/** How quotes and backslashes read. `"plain"` unless set. */
|
|
26
|
+
escapes?: "plain" | "shell";
|
|
27
|
+
/** Brace expansion inside qualifier values. Off unless set. */
|
|
28
|
+
braces?: boolean;
|
|
29
|
+
/** More qualifier expressions than this is a diagnostic. */
|
|
30
|
+
maxFilters?: number;
|
|
31
|
+
};
|
|
32
|
+
export type CompiledQuerySchema<K extends string = string> = {
|
|
33
|
+
readonly qualifiers: Readonly<Record<K, QualifierSpec>>;
|
|
34
|
+
/** Canonical keys, in declaration order. */
|
|
35
|
+
readonly keys: readonly K[];
|
|
36
|
+
/**
|
|
37
|
+
* Every spelling of a key, lowercase, canonical ones included, mapping to
|
|
38
|
+
* the canonical one. Completion offers only `keys`, so an alias is offered
|
|
39
|
+
* under its canonical spelling and still parses when typed.
|
|
40
|
+
*/
|
|
41
|
+
readonly spellings: ReadonlyMap<string, K>;
|
|
42
|
+
readonly escapes: "plain" | "shell";
|
|
43
|
+
readonly braces: boolean;
|
|
44
|
+
readonly maxFilters: number | undefined;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Throws on a malformed table: these are programmer errors in static data,
|
|
48
|
+
* caught at module load rather than on some reader's query.
|
|
49
|
+
*/
|
|
50
|
+
export declare function defineQuerySchema<K extends string>(schema: QuerySchema<K>): CompiledQuerySchema<K>;
|
|
51
|
+
export type QueryValue = {
|
|
52
|
+
start: number;
|
|
53
|
+
end: number;
|
|
54
|
+
/** The source slice, quotes included. */
|
|
55
|
+
raw: string;
|
|
56
|
+
/** What the value means, quotes removed. */
|
|
57
|
+
value: string;
|
|
58
|
+
/** `[value]` unless braces expanded it. */
|
|
59
|
+
expanded: string[];
|
|
60
|
+
/** Why brace expansion failed (over the limit). */
|
|
61
|
+
error?: string;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* A span of the query string. Offsets are UTF-16 indices into the original
|
|
65
|
+
* `q`, so the colouring layer, the diagnostics and the completions all point
|
|
66
|
+
* at the same characters without re-scanning.
|
|
67
|
+
*/
|
|
68
|
+
export type QueryPart<K extends string = string> = {
|
|
69
|
+
kind: "space";
|
|
70
|
+
start: number;
|
|
71
|
+
end: number;
|
|
72
|
+
} | {
|
|
73
|
+
kind: "text";
|
|
74
|
+
start: number;
|
|
75
|
+
end: number;
|
|
76
|
+
raw: string;
|
|
77
|
+
term: string;
|
|
78
|
+
} | {
|
|
79
|
+
kind: "filter";
|
|
80
|
+
start: number;
|
|
81
|
+
end: number;
|
|
82
|
+
raw: string;
|
|
83
|
+
/** Canonical. */
|
|
84
|
+
key: K;
|
|
85
|
+
negated: boolean;
|
|
86
|
+
/** The key as typed, `-` and `:` excluded. */
|
|
87
|
+
keyStart: number;
|
|
88
|
+
keyEnd: number;
|
|
89
|
+
values: QueryValue[];
|
|
90
|
+
};
|
|
91
|
+
export type QueryFilter<K extends string = string> = {
|
|
92
|
+
key: K;
|
|
93
|
+
negated: boolean;
|
|
94
|
+
/** Unquoted, expanded and in source order; empty values never reach here. */
|
|
95
|
+
values: string[];
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* `q` split into spans that tile it completely — every character of the input
|
|
99
|
+
* belongs to exactly one part, which is what lets a mirror layer render the
|
|
100
|
+
* string by walking this list.
|
|
101
|
+
*
|
|
102
|
+
* Never throws: a half-typed query is the normal case for a search box, and
|
|
103
|
+
* every shape of input has a reading.
|
|
104
|
+
*/
|
|
105
|
+
export declare function parseQuery<K extends string>(schema: CompiledQuerySchema<K>, q: string): QueryPart<K>[];
|
|
106
|
+
/** The free-text terms, in source order; an empty `""` contributes nothing. */
|
|
107
|
+
export declare function queryTerms(parts: readonly QueryPart[]): string[];
|
|
108
|
+
/**
|
|
109
|
+
* Brace expansions are flattened, so `label:area:{web,ui}` reaches a server
|
|
110
|
+
* as `label:area:web,area:ui`, which it already reads as an OR.
|
|
111
|
+
*/
|
|
112
|
+
export declare function queryFilters<K extends string>(parts: readonly QueryPart<K>[]): QueryFilter<K>[];
|
|
113
|
+
/**
|
|
114
|
+
* A value spelled so it reads back as one value. Plain mode has no way to
|
|
115
|
+
* spell a quote inside a value — a bare one ends the value — so inner quotes
|
|
116
|
+
* are dropped rather than preserved.
|
|
117
|
+
*/
|
|
118
|
+
export declare function quoteQueryValue(schema: CompiledQuerySchema, value: string): string;
|
|
119
|
+
//# sourceMappingURL=query.d.ts.map
|