@wirecat/cli-base 0.48.0 → 0.49.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/CHANGELOG.md +10 -0
- package/dist/query/parser.d.ts +3 -1
- package/dist/query/parser.js +8 -1
- package/dist/query/types.d.ts +2 -0
- package/dist/query/types.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,16 @@ Versions before 0.8.0 are in the [git tags](https://github.com/WireCatLabs/cli-b
|
|
|
8
8
|
Every entry says what changed as a caller sees it, why, and what to watch for — the rules are
|
|
9
9
|
[`docs/dev/CONVENTIONS.md`](docs/dev/CONVENTIONS.md#the-changelog).
|
|
10
10
|
|
|
11
|
+
## 0.49.0 — 21.10.2026
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`parseLucene` can read a phrase's distance.** With `{ proximity: true }`, `"a b"~3` parses as a phrase predicate
|
|
16
|
+
with `slop: 3`, and `queryNodeSchema` accepts `slop`. Meeting search needs it for words spread over neighbouring
|
|
17
|
+
transcript lines, and a caller that turns it on says what the number counts. Without the option `~` is still
|
|
18
|
+
`query.unsupported-operator`, so messages and lists see no change. A distance that is not a whole number is
|
|
19
|
+
`query.invalid-syntax`; `word~2` (fuzzy) stays unsupported either way.
|
|
20
|
+
|
|
11
21
|
## 0.48.0 — 21.10.2026
|
|
12
22
|
|
|
13
23
|
### Changed — may break callers
|
package/dist/query/parser.d.ts
CHANGED
|
@@ -2,7 +2,9 @@ import { type QueryAst, type QueryContext } from "./types.js";
|
|
|
2
2
|
export interface ParseOptions extends QueryContext {
|
|
3
3
|
/** The field a bare word searches; `none` for a list, where a bare word is `query.bare-word`. */
|
|
4
4
|
defaultField?: string;
|
|
5
|
+
/** Read `"a b"~N` as a phrase with `slop: N`; a caller that turns it on says what N counts. */
|
|
6
|
+
proximity?: boolean;
|
|
5
7
|
}
|
|
6
|
-
export declare const parseLucene: (text: string, { defaultField, ...context }?: ParseOptions) => QueryAst;
|
|
8
|
+
export declare const parseLucene: (text: string, { defaultField, proximity, ...context }?: ParseOptions) => QueryAst;
|
|
7
9
|
/** Bare terms eligible for forgiving retrieval; explicit syntax keeps strict semantics. */
|
|
8
10
|
export declare const implicitTextTerms: (text: string) => Set<number>;
|
package/dist/query/parser.js
CHANGED
|
@@ -141,7 +141,7 @@ const regexHint = (text, at) => {
|
|
|
141
141
|
const word = `${/[^\s()"]*$/u.exec(text.slice(0, at))?.[0] ?? ""}${/^[^\s()"]*/u.exec(text.slice(at))?.[0] ?? ""}`;
|
|
142
142
|
return quoteHint(text, at) ?? `/ starts a regular expression; put the value in quotes: "${word}"`;
|
|
143
143
|
};
|
|
144
|
-
export const parseLucene = (text, { defaultField = "text", ...context } = {}) => {
|
|
144
|
+
export const parseLucene = (text, { defaultField = "text", proximity = false, ...context } = {}) => {
|
|
145
145
|
const fail = (reason, span, alternative) => queryError(reason, span, alternative ?? quoteHint(text, span.start), context);
|
|
146
146
|
if (text.length > QUERY_LIMITS.bytes || new TextEncoder().encode(text).length > QUERY_LIMITS.bytes)
|
|
147
147
|
fail("query.too-large", { start: 0, end: text.length });
|
|
@@ -290,6 +290,13 @@ export const parseLucene = (text, { defaultField = "text", ...context } = {}) =>
|
|
|
290
290
|
...(implicit ? { implicit: true } : {}),
|
|
291
291
|
});
|
|
292
292
|
}
|
|
293
|
+
if (proximity && peek().kind === "~" && node.kind === "predicate" && node.operator === "phrase") {
|
|
294
|
+
take();
|
|
295
|
+
const distance = take();
|
|
296
|
+
if (distance.kind !== "number" || !/^\d+$/u.test(distance.raw))
|
|
297
|
+
fail("query.invalid-syntax", distance.span, 'write the distance as a whole number: "a b"~3');
|
|
298
|
+
node = { ...node, slop: Number(distance.raw), span: { start: node.span.start, end: distance.span.end } };
|
|
299
|
+
}
|
|
293
300
|
if (peek().kind === "~")
|
|
294
301
|
fail("query.unsupported-operator", peek().span, node.kind === "predicate" && node.operator === "phrase"
|
|
295
302
|
? "proximity (~) is not supported — drop the ~ for the exact phrase, or join the words with AND"
|
package/dist/query/types.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export interface Predicate {
|
|
|
21
21
|
span: Span;
|
|
22
22
|
/** A bare word, under no field. */
|
|
23
23
|
implicit?: true;
|
|
24
|
+
/** `"a b"~N`, read only when the parser is asked to: how far apart the phrase's words may be. */
|
|
25
|
+
slop?: number;
|
|
24
26
|
}
|
|
25
27
|
export type QueryNode = Predicate | {
|
|
26
28
|
kind: "boolean";
|
package/dist/query/types.js
CHANGED
|
@@ -16,6 +16,7 @@ const predicateSchema = v.object({
|
|
|
16
16
|
upper_inclusive: v.optional(v.boolean()),
|
|
17
17
|
span: spanSchema,
|
|
18
18
|
implicit: v.optional(v.literal(true)),
|
|
19
|
+
slop: v.optional(v.pipe(v.number(), v.integer(), v.minValue(0))),
|
|
19
20
|
});
|
|
20
21
|
export const queryNodeSchema = v.variant("kind", [
|
|
21
22
|
predicateSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirecat/cli-base",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.49.0",
|
|
4
4
|
"description": "The parts every command line tool needs: output modes, terminal rendering, error model, exit codes, credentials, clocks",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Viacheslav Ptsarev",
|