mailwoman 4.4.0 → 4.5.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.
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autocomplete.d.ts","sourceRoot":"","sources":["../../commands/autocomplete.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAErD,OAAO,EAAE,eAAe,IAAI,IAAI,EAAE,wBAAwB,IAAI,OAAO,EAAE,CAAA;AAEvE,QAAA,MAAM,eAAe,6BAAgE,CAAA;AAErF,eAAO,MAAM,wBAAwB;;;;qBAiBnC,CAAA;AAEF,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACpC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA0C9B;AAaD,QAAA,MAAM,mBAAmB,EAAE,gBAAgB,CAAC,OAAO,wBAAwB,EAAE,OAAO,eAAe,CA2ClG,CAAA;AAED,eAAe,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* @copyright Sister Software
|
|
4
|
+
* @license AGPL-3.0
|
|
5
|
+
* @author Teffen Ellis, et al.
|
|
6
|
+
*
|
|
7
|
+
* `mailwoman autocomplete <prefix>`
|
|
8
|
+
*
|
|
9
|
+
* One-shot prefix completion against the FST gazetteer. Returns the top-N place suggestions (name,
|
|
10
|
+
* placetype, WOF id, importance) that match the given prefix, ranked by importance.
|
|
11
|
+
*
|
|
12
|
+
* The prefix normalizer is `normalizeTokens` from `fst-matcher` — the SAME function used at FST
|
|
13
|
+
* build time — so the symmetry contract from #190 is honoured. No third normalizer.
|
|
14
|
+
*
|
|
15
|
+
* Default FST path: $MAILWOMAN_FST_BIN, else /tmp/v440-stage/en-us/v4.4.0/fst-en-US.bin. Pass --fst
|
|
16
|
+
* <path> to override.
|
|
17
|
+
*/
|
|
18
|
+
import { Text } from "ink";
|
|
19
|
+
import { readFileSync } from "node:fs";
|
|
20
|
+
import { useEffect, useState } from "react";
|
|
21
|
+
import zod from "zod";
|
|
22
|
+
export { ArgumentsSchema as args, AutocompleteConfigSchema as options };
|
|
23
|
+
const ArgumentsSchema = zod.array(zod.string().describe("Prefix string to complete"));
|
|
24
|
+
export const AutocompleteConfigSchema = zod.object({
|
|
25
|
+
limit: zod.coerce
|
|
26
|
+
.number()
|
|
27
|
+
.int()
|
|
28
|
+
.min(1)
|
|
29
|
+
.max(100)
|
|
30
|
+
.optional()
|
|
31
|
+
.default(10)
|
|
32
|
+
.describe("Maximum number of completions to return (default 10)"),
|
|
33
|
+
fst: zod
|
|
34
|
+
.string()
|
|
35
|
+
.optional()
|
|
36
|
+
.describe("Path to the FST binary (fst-en-US.bin). Defaults to $MAILWOMAN_FST_BIN or " +
|
|
37
|
+
"/tmp/v440-stage/en-us/v4.4.0/fst-en-US.bin."),
|
|
38
|
+
json: zod.boolean().optional().default(false).describe("Emit results as a JSON array instead of formatted text"),
|
|
39
|
+
});
|
|
40
|
+
/** Resolve the FST binary path from explicit flag, env var, or the staged default. */
|
|
41
|
+
export function resolveFstPath(explicitPath) {
|
|
42
|
+
return explicitPath ?? process.env["MAILWOMAN_FST_BIN"] ?? "/tmp/v440-stage/en-us/v4.4.0/fst-en-US.bin";
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Load the FST from `fstPath` and run prefix autocomplete. Throws with a human-readable message on
|
|
46
|
+
* any IO or format error so callers can surface it cleanly.
|
|
47
|
+
*/
|
|
48
|
+
export async function runAutocomplete(prefix, opts) {
|
|
49
|
+
const { existsSync } = await import("node:fs");
|
|
50
|
+
const fstPath = opts.fstPath;
|
|
51
|
+
if (!existsSync(fstPath)) {
|
|
52
|
+
throw new Error(`FST binary not found at ${fstPath}.\n` +
|
|
53
|
+
`Pass --fst <path>, set $MAILWOMAN_FST_BIN, or build the FST with:\n` +
|
|
54
|
+
` mailwoman fst build --db /path/to/wof-admin.db --output fst-en-US.bin`);
|
|
55
|
+
}
|
|
56
|
+
let buf;
|
|
57
|
+
try {
|
|
58
|
+
buf = readFileSync(fstPath);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
62
|
+
throw new Error(`Failed to read FST binary at ${fstPath}: ${msg}`);
|
|
63
|
+
}
|
|
64
|
+
// Dynamic import keeps @mailwoman/resolver-wof-sqlite a true optional peer dep — only loaded
|
|
65
|
+
// when the autocomplete command is invoked.
|
|
66
|
+
const { deserializeFst } = await import("@mailwoman/resolver-wof-sqlite/fst-serialize");
|
|
67
|
+
const { autocomplete } = await import("@mailwoman/resolver-wof-sqlite/fst-autocomplete");
|
|
68
|
+
let matcher;
|
|
69
|
+
try {
|
|
70
|
+
matcher = deserializeFst(buf);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
74
|
+
throw new Error(`Malformed FST binary at ${fstPath}: ${msg}`);
|
|
75
|
+
}
|
|
76
|
+
const result = autocomplete(matcher, prefix, { maxSuggestions: opts.limit ?? 10 });
|
|
77
|
+
return result.suggestions.map((s) => ({
|
|
78
|
+
name: s.name,
|
|
79
|
+
placetype: s.placetype,
|
|
80
|
+
wofID: s.wofID,
|
|
81
|
+
importance: s.importance,
|
|
82
|
+
completionTokens: s.completionTokens,
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
function formatSuggestions(entries) {
|
|
86
|
+
if (entries.length === 0)
|
|
87
|
+
return "(no completions)";
|
|
88
|
+
return entries
|
|
89
|
+
.map((e, i) => {
|
|
90
|
+
const completion = e.completionTokens.length > 0 ? ` [+${e.completionTokens.join(" ")}]` : "";
|
|
91
|
+
const imp = e.importance.toFixed(4);
|
|
92
|
+
return `${String(i + 1).padStart(2)}. ${e.name}${completion} (${e.placetype}, wof:${e.wofID}, imp:${imp})`;
|
|
93
|
+
})
|
|
94
|
+
.join("\n");
|
|
95
|
+
}
|
|
96
|
+
const AutocompleteCommand = ({ options, args, }) => {
|
|
97
|
+
const [output, setOutput] = useState();
|
|
98
|
+
const [error, setError] = useState();
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
const prefix = args[0];
|
|
101
|
+
if (!prefix) {
|
|
102
|
+
// Intentional: surface the usage error through the same render-then-exit pattern as parse.tsx.
|
|
103
|
+
// The "cascading renders" the rule warns about are not a real cost here — the effect
|
|
104
|
+
// short-circuits with `return`.
|
|
105
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect
|
|
106
|
+
setError("Usage: mailwoman autocomplete <prefix> [--limit N] [--fst <path>]");
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const fstPath = resolveFstPath(options.fst);
|
|
110
|
+
runAutocomplete(prefix, { fstPath, limit: options.limit })
|
|
111
|
+
.then((entries) => {
|
|
112
|
+
if (options.json) {
|
|
113
|
+
setOutput(JSON.stringify(entries, null, 2));
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
setOutput(formatSuggestions(entries));
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
.catch((err) => {
|
|
120
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
121
|
+
setError(msg);
|
|
122
|
+
});
|
|
123
|
+
}, [args, options]);
|
|
124
|
+
if (error) {
|
|
125
|
+
return _jsx(Text, { color: "red", children: error });
|
|
126
|
+
}
|
|
127
|
+
if (!output) {
|
|
128
|
+
return _jsx(Text, { dimColor: true, children: "Searching..." });
|
|
129
|
+
}
|
|
130
|
+
return _jsx(Text, { children: output });
|
|
131
|
+
};
|
|
132
|
+
export default AutocompleteCommand;
|
|
133
|
+
//# sourceMappingURL=autocomplete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autocomplete.js","sourceRoot":"","sources":["../../commands/autocomplete.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mailwoman",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.0",
|
|
4
4
|
"description": "Utilities for working with contacts for email, phone, and postal addresses.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"contributors": [
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@fragaria/address-formatter": "^6.7.1",
|
|
35
35
|
"@inkjs/ui": "^2.0.0",
|
|
36
|
-
"@mailwoman/classifiers": "4.
|
|
37
|
-
"@mailwoman/core": "4.
|
|
38
|
-
"@mailwoman/kind-classifier": "4.
|
|
39
|
-
"@mailwoman/locale-gate": "4.
|
|
40
|
-
"@mailwoman/normalize": "4.
|
|
41
|
-
"@mailwoman/phrase-grouper": "4.
|
|
42
|
-
"@mailwoman/query-shape": "4.
|
|
36
|
+
"@mailwoman/classifiers": "4.5.0",
|
|
37
|
+
"@mailwoman/core": "4.5.0",
|
|
38
|
+
"@mailwoman/kind-classifier": "4.5.0",
|
|
39
|
+
"@mailwoman/locale-gate": "4.5.0",
|
|
40
|
+
"@mailwoman/normalize": "4.5.0",
|
|
41
|
+
"@mailwoman/phrase-grouper": "4.5.0",
|
|
42
|
+
"@mailwoman/query-shape": "4.5.0",
|
|
43
43
|
"change-case": "^5.4.4",
|
|
44
44
|
"express": "^5.2.1",
|
|
45
45
|
"geojson": "^0.5.0",
|