mailwoman 4.16.0 → 4.16.2
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/out/commands/gazetteer/build.d.ts.map +1 -0
- package/out/commands/gazetteer/build.js +95 -0
- package/out/commands/gazetteer/build.js.map +1 -0
- package/out/commands/gazetteer/promote.d.ts.map +1 -0
- package/out/commands/gazetteer/promote.js +47 -0
- package/out/commands/gazetteer/promote.js.map +1 -0
- package/out/commands/gazetteer/publish.d.ts.map +1 -0
- package/out/commands/gazetteer/publish.js +83 -0
- package/out/commands/gazetteer/publish.js.map +1 -0
- package/out/commands/gazetteer/release.d.ts.map +1 -0
- package/out/commands/gazetteer/release.js +113 -0
- package/out/commands/gazetteer/release.js.map +1 -0
- package/out/gazetteer-pipeline.d.ts.map +1 -0
- package/out/gazetteer-pipeline.js +182 -0
- package/out/gazetteer-pipeline.js.map +1 -0
- package/package.json +14 -14
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../commands/gazetteer/build.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,GAAG,MAAM,KAAK,CAAA;AAWrB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD,QAAA,MAAM,aAAa;;;;;;qBAejB,CAAA;AAEF,OAAO,EAAE,aAAa,IAAI,OAAO,EAAE,CAAA;AAEnC,QAAA,MAAM,cAAc,EAAE,gBAAgB,CAAC,OAAO,aAAa,CA2E1D,CAAA;AAED,eAAe,cAAc,CAAA"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { jsxs as _jsxs, 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 gazetteer build` — the durable GeoNames-alias upstream fold + the byte-range candidate
|
|
8
|
+
* build (FTS5-trigram fuzzy index baked in), in one command. Every decision the 2026-06-27 manual
|
|
9
|
+
* rebuild needed (which countries fold, which postcode shards, FTS) is a default here. Progress
|
|
10
|
+
* streams to stderr; the final summary is on stdout. See RELEASING.md Step 5.
|
|
11
|
+
*/
|
|
12
|
+
import { mailwomanDataRoot } from "@mailwoman/core/utils";
|
|
13
|
+
import { Box, Text } from "ink";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
import { useEffect, useState } from "react";
|
|
16
|
+
import zod from "zod";
|
|
17
|
+
import { buildCandidate, DEFAULT_ADMIN_DB, DEFAULT_CANDIDATE_OUT, DEFAULT_FOLD_COUNTRIES, foldGeonamesIntoAdmin, resolvePostcodeShards, wofDir, } from "../../gazetteer-pipeline.js";
|
|
18
|
+
const OptionsSchema = zod.object({
|
|
19
|
+
admin: zod
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("Admin (unified-WOF) source DB. Default <data-root>/wof/admin-global-priority.db"),
|
|
23
|
+
out: zod.string().optional().describe("Candidate-DB output path. Default <data-root>/wof/candidate-global.db"),
|
|
24
|
+
fold: zod
|
|
25
|
+
.boolean()
|
|
26
|
+
.default(true)
|
|
27
|
+
.describe("Run the durable GeoNames-alias upstream fold before building (default on)"),
|
|
28
|
+
countries: zod
|
|
29
|
+
.string()
|
|
30
|
+
.optional()
|
|
31
|
+
.describe(`Comma-separated ISO codes for the fold. Default: ${DEFAULT_FOLD_COUNTRIES.join(",")}`),
|
|
32
|
+
foldOut: zod.string().optional().describe("Folded admin-DB path. Default <admin>-geonames.db"),
|
|
33
|
+
});
|
|
34
|
+
export { OptionsSchema as options };
|
|
35
|
+
const GazetteerBuild = ({ options }) => {
|
|
36
|
+
const [error, setError] = useState();
|
|
37
|
+
const [summary, setSummary] = useState();
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
void (async () => {
|
|
40
|
+
try {
|
|
41
|
+
const root = mailwomanDataRoot();
|
|
42
|
+
const adminIn = options.admin ?? join(wofDir(root), DEFAULT_ADMIN_DB);
|
|
43
|
+
const out = options.out ?? join(wofDir(root), DEFAULT_CANDIDATE_OUT);
|
|
44
|
+
const countries = options.countries
|
|
45
|
+
? options.countries
|
|
46
|
+
.split(",")
|
|
47
|
+
.map((s) => s.trim().toUpperCase())
|
|
48
|
+
.filter(Boolean)
|
|
49
|
+
: DEFAULT_FOLD_COUNTRIES;
|
|
50
|
+
let adminDb = adminIn;
|
|
51
|
+
if (options.fold) {
|
|
52
|
+
const foldOut = options.foldOut ?? adminIn.replace(/\.db$/, "-geonames.db");
|
|
53
|
+
console.error(`▸ GeoNames upstream fold (${countries.join(",")}) → ${foldOut}`);
|
|
54
|
+
const f = await foldGeonamesIntoAdmin({
|
|
55
|
+
adminIn,
|
|
56
|
+
adminOut: foldOut,
|
|
57
|
+
countries,
|
|
58
|
+
onCountry: (e) => console.error(` ${e.country}: ${e.skipped ? "(dump missing — skipped)" : `${e.places.toLocaleString()} places`}`),
|
|
59
|
+
onPhase: (p, d) => console.error(` [${p}]${d ? ` ${d}` : ""}`),
|
|
60
|
+
});
|
|
61
|
+
console.error(` folded ${f.ingested.toLocaleString()} places; place_search ${f.placeSearchRows.toLocaleString()} rows`);
|
|
62
|
+
adminDb = foldOut;
|
|
63
|
+
}
|
|
64
|
+
const shards = resolvePostcodeShards(undefined, root);
|
|
65
|
+
console.error(`▸ candidate build ← ${adminDb} (${shards.length} postcode shards; FTS baked in)`);
|
|
66
|
+
const r = await buildCandidate({
|
|
67
|
+
adminDb,
|
|
68
|
+
out,
|
|
69
|
+
postcodeShards: shards,
|
|
70
|
+
onProgress: (phase, msg) => console.error(` [${phase}] ${msg}`),
|
|
71
|
+
});
|
|
72
|
+
setSummary([
|
|
73
|
+
`gazetteer: ${out}`,
|
|
74
|
+
`${r.rows.toLocaleString()} rows — ${r.primaries.toLocaleString()} primary, ${r.aliases.toLocaleString()} alias, ${r.postcodes.toLocaleString()} postcode (from ${r.places.toLocaleString()} places)`,
|
|
75
|
+
`next: mailwoman gazetteer promote (then publish, or run gazetteer release for all of it)`,
|
|
76
|
+
]);
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
80
|
+
}
|
|
81
|
+
})();
|
|
82
|
+
}, [options]);
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (summary || error)
|
|
85
|
+
setImmediate(() => process.exit(error ? 1 : 0));
|
|
86
|
+
}, [summary, error]);
|
|
87
|
+
if (error)
|
|
88
|
+
return _jsxs(Text, { color: "red", children: ["\u2717 ", error] });
|
|
89
|
+
if (summary) {
|
|
90
|
+
return (_jsx(Box, { flexDirection: "column", children: summary.map((line, i) => (_jsxs(Text, { color: i === 0 ? "green" : undefined, children: [i === 0 ? "✓ " : " ", line] }, i))) }));
|
|
91
|
+
}
|
|
92
|
+
return null; // progress streams to stderr until the summary lands
|
|
93
|
+
};
|
|
94
|
+
export default GazetteerBuild;
|
|
95
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../../commands/gazetteer/build.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promote.d.ts","sourceRoot":"","sources":["../../../commands/gazetteer/promote.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,GAAG,MAAM,KAAK,CAAA;AAGrB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD,QAAA,MAAM,eAAe,6BAEpB,CAAA;AACD,QAAA,MAAM,aAAa,sCAAiB,CAAA;AAEpC,OAAO,EAAE,eAAe,IAAI,IAAI,EAAE,aAAa,IAAI,OAAO,EAAE,CAAA;AAE5D,QAAA,MAAM,gBAAgB,EAAE,gBAAgB,CAAC,OAAO,aAAa,EAAE,OAAO,eAAe,CA+BpF,CAAA;AAED,eAAe,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsxs as _jsxs, 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 gazetteer promote [<candidate-db>]` — point the drop-in convention path
|
|
8
|
+
* `<data-root>/wof/candidate.db` at a candidate build (a symlink — a POINTER swap, never a DB
|
|
9
|
+
* mutation). The nominatim/photon CLIs auto-use this path for worldwide resolution. Defaults to
|
|
10
|
+
* the canonical `candidate-global.db`.
|
|
11
|
+
*/
|
|
12
|
+
import { mailwomanDataRoot } from "@mailwoman/core/utils";
|
|
13
|
+
import { Box, Text } from "ink";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
import { useEffect, useState } from "react";
|
|
16
|
+
import zod from "zod";
|
|
17
|
+
import { DEFAULT_CANDIDATE_OUT, promoteCandidate, wofDir } from "../../gazetteer-pipeline.js";
|
|
18
|
+
const ArgumentsSchema = zod.array(zod.string().describe(`Candidate DB to promote. Default <data-root>/wof/${DEFAULT_CANDIDATE_OUT}`));
|
|
19
|
+
const OptionsSchema = zod.object({});
|
|
20
|
+
export { ArgumentsSchema as args, OptionsSchema as options };
|
|
21
|
+
const GazetteerPromote = ({ args }) => {
|
|
22
|
+
const [error, setError] = useState();
|
|
23
|
+
const [link, setLink] = useState();
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
try {
|
|
26
|
+
const root = mailwomanDataRoot();
|
|
27
|
+
const candidateDb = args[0] ?? join(wofDir(root), DEFAULT_CANDIDATE_OUT);
|
|
28
|
+
const linkPath = promoteCandidate(candidateDb, root);
|
|
29
|
+
setLink({ from: linkPath, to: candidateDb });
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
33
|
+
}
|
|
34
|
+
}, [args]);
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (link || error)
|
|
37
|
+
setImmediate(() => process.exit(error ? 1 : 0));
|
|
38
|
+
}, [link, error]);
|
|
39
|
+
if (error)
|
|
40
|
+
return _jsxs(Text, { color: "red", children: ["\u2717 ", error] });
|
|
41
|
+
if (link) {
|
|
42
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "green", children: ["\u2713 promoted: ", link.from, " \u2192 ", link.to] }), _jsx(Text, { children: " drop-ins (nominatim/photon) now auto-use this gazetteer worldwide \u2014 no --candidate-db needed" })] }));
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
};
|
|
46
|
+
export default GazetteerPromote;
|
|
47
|
+
//# sourceMappingURL=promote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promote.js","sourceRoot":"","sources":["../../../commands/gazetteer/promote.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,GAAG,MAAM,KAAK,CAAA;AAErB,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAA;AAG7F,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,CAChC,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oDAAoD,qBAAqB,EAAE,CAAC,CAClG,CAAA;AACD,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAEpC,OAAO,EAAE,eAAe,IAAI,IAAI,EAAE,aAAa,IAAI,OAAO,EAAE,CAAA;AAE5D,MAAM,gBAAgB,GAAmE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;IACrG,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,EAAU,CAAA;IAC5C,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,EAAgC,CAAA;IAEhE,SAAS,CAAC,GAAG,EAAE;QACd,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAA;YAChC,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,qBAAqB,CAAC,CAAA;YACxE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;YACpD,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAA;QAC7C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,QAAQ,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;QACrD,CAAC;IACF,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,SAAS,CAAC,GAAG,EAAE;QACd,IAAI,IAAI,IAAI,KAAK;YAAE,YAAY,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACnE,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;IAEjB,IAAI,KAAK;QAAE,OAAO,MAAC,IAAI,IAAC,KAAK,EAAC,KAAK,wBAAI,KAAK,IAAQ,CAAA;IACpD,IAAI,IAAI,EAAE,CAAC;QACV,OAAO,CACN,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aAC1B,MAAC,IAAI,IAAC,KAAK,EAAC,OAAO,kCACL,IAAI,CAAC,IAAI,cAAK,IAAI,CAAC,EAAE,IAC5B,EACP,KAAC,IAAI,qHAAqG,IACrG,CACN,CAAA;IACF,CAAC;IACD,OAAO,IAAI,CAAA;AACZ,CAAC,CAAA;AAED,eAAe,gBAAgB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../../commands/gazetteer/publish.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,OAAO,GAAG,MAAM,KAAK,CAAA;AAGrB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD,QAAA,MAAM,eAAe,6BAEpB,CAAA;AACD,QAAA,MAAM,aAAa;;;;;;qBASjB,CAAA;AAEF,OAAO,EAAE,eAAe,IAAI,IAAI,EAAE,aAAa,IAAI,OAAO,EAAE,CAAA;AAE5D,QAAA,MAAM,gBAAgB,EAAE,gBAAgB,CAAC,OAAO,aAAa,EAAE,OAAO,eAAe,CAwDpF,CAAA;AAED,eAAe,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { jsxs as _jsxs, 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 gazetteer publish [<candidate-db>]` — upload the candidate gazetteer to R2 (the demo's
|
|
8
|
+
* byte-range source) and bump the demo's `ADMIN_GAZETTEER_VERSION`. Shells out to the proven
|
|
9
|
+
* `scripts/publish-demo-assets-to-r2.py` (boto3 + the R2 cache-control gotchas). The version
|
|
10
|
+
* defaults to today's date + `a` (e.g. `2026-06-27a`), the immutable convention.
|
|
11
|
+
*
|
|
12
|
+
* Creds: `RCLONE_S3_PUBLIC_*` must be in the process env — `set -a; . ./.env; set +a` first. This
|
|
13
|
+
* is an in-repo operator command (it needs the upload script + the demo's resources file).
|
|
14
|
+
*/
|
|
15
|
+
import { mailwomanDataRoot, repoRootPathBuilder } from "@mailwoman/core/utils";
|
|
16
|
+
import { Box, Text } from "ink";
|
|
17
|
+
import { mkdtempSync } from "node:fs";
|
|
18
|
+
import { tmpdir } from "node:os";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
import { useEffect, useState } from "react";
|
|
21
|
+
import zod from "zod";
|
|
22
|
+
import { DEFAULT_CANDIDATE_OUT, defaultGazetteerVersion, publishGazetteer, wofDir } from "../../gazetteer-pipeline.js";
|
|
23
|
+
const ArgumentsSchema = zod.array(zod.string().describe(`Candidate DB to publish. Default <data-root>/wof/${DEFAULT_CANDIDATE_OUT}`));
|
|
24
|
+
const OptionsSchema = zod.object({
|
|
25
|
+
gazetteerVersion: zod
|
|
26
|
+
.string()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("Immutable gazetteer version. Default today's date + 'a' (e.g. 2026-06-27a)"),
|
|
29
|
+
bucket: zod.string().optional().describe("R2 bucket (default nexus-public, per the upload script)"),
|
|
30
|
+
prefix: zod.string().default("mailwoman").describe("R2 key prefix"),
|
|
31
|
+
dryRun: zod.boolean().default(false).describe("Show what would upload; don't push or bump the demo"),
|
|
32
|
+
bumpDemo: zod.boolean().default(true).describe("Bump ADMIN_GAZETTEER_VERSION in the demo resources (default on)"),
|
|
33
|
+
});
|
|
34
|
+
export { ArgumentsSchema as args, OptionsSchema as options };
|
|
35
|
+
const GazetteerPublish = ({ options, args }) => {
|
|
36
|
+
const [error, setError] = useState();
|
|
37
|
+
const [done, setDone] = useState();
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
try {
|
|
40
|
+
const root = mailwomanDataRoot();
|
|
41
|
+
const candidateDb = args[0] ?? join(wofDir(root), DEFAULT_CANDIDATE_OUT);
|
|
42
|
+
const version = options.gazetteerVersion ?? defaultGazetteerVersion(new Date());
|
|
43
|
+
const uploadScript = String(repoRootPathBuilder("scripts", "publish-demo-assets-to-r2.py"));
|
|
44
|
+
const resourcesFile = options.bumpDemo
|
|
45
|
+
? String(repoRootPathBuilder("docs", "src", "shared", "resources.tsx"))
|
|
46
|
+
: undefined;
|
|
47
|
+
const stageDir = mkdtempSync(join(tmpdir(), "mailwoman-gazetteer-"));
|
|
48
|
+
console.error(`▸ publish ${candidateDb} → R2 gazetteer/${version}/candidate.db${options.dryRun ? " (dry-run)" : ""}`);
|
|
49
|
+
const r = publishGazetteer({
|
|
50
|
+
candidateDb,
|
|
51
|
+
version,
|
|
52
|
+
uploadScript,
|
|
53
|
+
resourcesFile,
|
|
54
|
+
stageDir,
|
|
55
|
+
bucket: options.bucket,
|
|
56
|
+
prefix: options.prefix,
|
|
57
|
+
dryRun: options.dryRun,
|
|
58
|
+
onPhase: (p, d) => console.error(` [${p}]${d ? ` ${d}` : ""}`),
|
|
59
|
+
});
|
|
60
|
+
setDone([
|
|
61
|
+
`R2: ${r.key}`,
|
|
62
|
+
r.bumped
|
|
63
|
+
? `demo: ADMIN_GAZETTEER_VERSION → ${version} (commit docs/src/shared/resources.tsx)`
|
|
64
|
+
: "demo: not bumped",
|
|
65
|
+
]);
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
69
|
+
}
|
|
70
|
+
}, [options, args]);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (done || error)
|
|
73
|
+
setImmediate(() => process.exit(error ? 1 : 0));
|
|
74
|
+
}, [done, error]);
|
|
75
|
+
if (error)
|
|
76
|
+
return _jsxs(Text, { color: "red", children: ["\u2717 ", error] });
|
|
77
|
+
if (done) {
|
|
78
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "green", children: "\u2713 published" }), done.map((line, i) => (_jsxs(Text, { children: [" ", line] }, i)))] }));
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
};
|
|
82
|
+
export default GazetteerPublish;
|
|
83
|
+
//# sourceMappingURL=publish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../../commands/gazetteer/publish.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../../../commands/gazetteer/release.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,OAAO,GAAG,MAAM,KAAK,CAAA;AAcrB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD,QAAA,MAAM,aAAa;;;;;;;;;qBAYjB,CAAA;AAEF,OAAO,EAAE,aAAa,IAAI,OAAO,EAAE,CAAA;AAEnC,QAAA,MAAM,gBAAgB,EAAE,gBAAgB,CAAC,OAAO,aAAa,CAyF5D,CAAA;AAED,eAAe,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { jsxs as _jsxs, 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 gazetteer release` — the whole gazetteer pipeline, turnkey: durable GeoNames fold →
|
|
8
|
+
* candidate build (FTS baked in) → promote the convention path → publish to R2 + bump the demo.
|
|
9
|
+
* The codified 2026-06-27 rebuild, no questions. `--no-publish` stops after promote (build local
|
|
10
|
+
* only); `--dry-run` previews the R2 upload. Creds: `RCLONE_S3_PUBLIC_*` in the env (source
|
|
11
|
+
* `.env`) for the publish step.
|
|
12
|
+
*/
|
|
13
|
+
import { mailwomanDataRoot, repoRootPathBuilder } from "@mailwoman/core/utils";
|
|
14
|
+
import { Box, Text } from "ink";
|
|
15
|
+
import { mkdtempSync } from "node:fs";
|
|
16
|
+
import { tmpdir } from "node:os";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
import { useEffect, useState } from "react";
|
|
19
|
+
import zod from "zod";
|
|
20
|
+
import { buildCandidate, DEFAULT_ADMIN_DB, DEFAULT_CANDIDATE_OUT, DEFAULT_FOLD_COUNTRIES, defaultGazetteerVersion, foldGeonamesIntoAdmin, promoteCandidate, publishGazetteer, resolvePostcodeShards, wofDir, } from "../../gazetteer-pipeline.js";
|
|
21
|
+
const OptionsSchema = zod.object({
|
|
22
|
+
admin: zod.string().optional().describe("Admin source DB. Default <data-root>/wof/admin-global-priority.db"),
|
|
23
|
+
out: zod.string().optional().describe("Candidate-DB output. Default <data-root>/wof/candidate-global.db"),
|
|
24
|
+
countries: zod
|
|
25
|
+
.string()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe(`Fold countries (comma-separated). Default: ${DEFAULT_FOLD_COUNTRIES.join(",")}`),
|
|
28
|
+
fold: zod.boolean().default(true).describe("Run the GeoNames fold (default on)"),
|
|
29
|
+
promote: zod.boolean().default(true).describe("Promote the convention path after building (default on)"),
|
|
30
|
+
publish: zod.boolean().default(true).describe("Publish to R2 + bump the demo after promoting (default on)"),
|
|
31
|
+
gazetteerVersion: zod.string().optional().describe("Gazetteer version. Default today's date + 'a'"),
|
|
32
|
+
dryRun: zod.boolean().default(false).describe("Preview the R2 upload; don't push or bump the demo"),
|
|
33
|
+
});
|
|
34
|
+
export { OptionsSchema as options };
|
|
35
|
+
const GazetteerRelease = ({ options }) => {
|
|
36
|
+
const [error, setError] = useState();
|
|
37
|
+
const [summary, setSummary] = useState();
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
void (async () => {
|
|
40
|
+
try {
|
|
41
|
+
const root = mailwomanDataRoot();
|
|
42
|
+
const adminIn = options.admin ?? join(wofDir(root), DEFAULT_ADMIN_DB);
|
|
43
|
+
const out = options.out ?? join(wofDir(root), DEFAULT_CANDIDATE_OUT);
|
|
44
|
+
const countries = options.countries
|
|
45
|
+
? options.countries
|
|
46
|
+
.split(",")
|
|
47
|
+
.map((s) => s.trim().toUpperCase())
|
|
48
|
+
.filter(Boolean)
|
|
49
|
+
: DEFAULT_FOLD_COUNTRIES;
|
|
50
|
+
const lines = [];
|
|
51
|
+
let adminDb = adminIn;
|
|
52
|
+
if (options.fold) {
|
|
53
|
+
const foldOut = adminIn.replace(/\.db$/, "-geonames.db");
|
|
54
|
+
console.error(`▸ fold (${countries.join(",")}) → ${foldOut}`);
|
|
55
|
+
const f = await foldGeonamesIntoAdmin({
|
|
56
|
+
adminIn,
|
|
57
|
+
adminOut: foldOut,
|
|
58
|
+
countries,
|
|
59
|
+
onCountry: (e) => console.error(` ${e.country}: ${e.skipped ? "(skipped)" : `${e.places.toLocaleString()} places`}`),
|
|
60
|
+
onPhase: (p, d) => console.error(` [${p}]${d ? ` ${d}` : ""}`),
|
|
61
|
+
});
|
|
62
|
+
lines.push(`folded ${f.ingested.toLocaleString()} GeoNames places`);
|
|
63
|
+
adminDb = foldOut;
|
|
64
|
+
}
|
|
65
|
+
const shards = resolvePostcodeShards(undefined, root);
|
|
66
|
+
console.error(`▸ build ← ${adminDb} (${shards.length} postcode shards; FTS baked in)`);
|
|
67
|
+
const r = await buildCandidate({
|
|
68
|
+
adminDb,
|
|
69
|
+
out,
|
|
70
|
+
postcodeShards: shards,
|
|
71
|
+
onProgress: (phase, msg) => console.error(` [${phase}] ${msg}`),
|
|
72
|
+
});
|
|
73
|
+
lines.push(`built ${out} — ${r.rows.toLocaleString()} rows, ${r.postcodes.toLocaleString()} postcodes`);
|
|
74
|
+
if (options.promote) {
|
|
75
|
+
const linkPath = promoteCandidate(out, root);
|
|
76
|
+
lines.push(`promoted ${linkPath} → ${out}`);
|
|
77
|
+
}
|
|
78
|
+
if (options.publish) {
|
|
79
|
+
const version = options.gazetteerVersion ?? defaultGazetteerVersion(new Date());
|
|
80
|
+
const stageDir = mkdtempSync(join(tmpdir(), "mailwoman-gazetteer-"));
|
|
81
|
+
console.error(`▸ publish → R2 gazetteer/${version}/candidate.db${options.dryRun ? " (dry-run)" : ""}`);
|
|
82
|
+
const p = publishGazetteer({
|
|
83
|
+
candidateDb: out,
|
|
84
|
+
version,
|
|
85
|
+
uploadScript: String(repoRootPathBuilder("scripts", "publish-demo-assets-to-r2.py")),
|
|
86
|
+
resourcesFile: String(repoRootPathBuilder("docs", "src", "shared", "resources.tsx")),
|
|
87
|
+
stageDir,
|
|
88
|
+
prefix: "mailwoman",
|
|
89
|
+
dryRun: options.dryRun,
|
|
90
|
+
onPhase: (ph, d) => console.error(` [${ph}]${d ? ` ${d}` : ""}`),
|
|
91
|
+
});
|
|
92
|
+
lines.push(`published R2 ${p.key}${p.bumped ? ` + demo → ${version} (commit resources.tsx)` : ""}`);
|
|
93
|
+
}
|
|
94
|
+
setSummary(lines);
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
98
|
+
}
|
|
99
|
+
})();
|
|
100
|
+
}, [options]);
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
if (summary || error)
|
|
103
|
+
setImmediate(() => process.exit(error ? 1 : 0));
|
|
104
|
+
}, [summary, error]);
|
|
105
|
+
if (error)
|
|
106
|
+
return _jsxs(Text, { color: "red", children: ["\u2717 ", error] });
|
|
107
|
+
if (summary) {
|
|
108
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "green", children: "\u2713 gazetteer release complete" }), summary.map((line, i) => (_jsxs(Text, { children: [" \u2022 ", line] }, i)))] }));
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
};
|
|
112
|
+
export default GazetteerRelease;
|
|
113
|
+
//# sourceMappingURL=release.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release.js","sourceRoot":"","sources":["../../../commands/gazetteer/release.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gazetteer-pipeline.d.ts","sourceRoot":"","sources":["../gazetteer-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* The candidate-gazetteer build → promote → publish pipeline, as reusable functions the `mailwoman
|
|
7
|
+
* gazetteer` commands compose. This is the codified version of the 2026-06-27 manual rebuild
|
|
8
|
+
* (RELEASING.md Step 5): the durable GeoNames-alias upstream fold, the candidate build with the
|
|
9
|
+
* FTS5-trigram fuzzy index baked in, the local convention-path promotion, and the R2 + demo
|
|
10
|
+
* publish — every decision that needed a question last time is a default here.
|
|
11
|
+
*
|
|
12
|
+
* `fold` and `build` reuse the CANONICAL package functions (`ingestGeonamesAliases`,
|
|
13
|
+
* `buildPlaceSearchFts`, `buildCandidateTable`) so the CLI, the standalone scripts, and a future
|
|
14
|
+
* `build-unified-wof --geonames-countries` all share ONE implementation. `publish` shells out to
|
|
15
|
+
* the proven `scripts/publish-demo-assets-to-r2.py` (boto3 + the R2 cache-control gotchas) and
|
|
16
|
+
* bumps the demo's `ADMIN_GAZETTEER_VERSION` — the only repo-coupled step, so its repo paths are
|
|
17
|
+
* passed in.
|
|
18
|
+
*/
|
|
19
|
+
import { execFileSync } from "node:child_process";
|
|
20
|
+
import { copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, rmSync, symlinkSync, writeFileSync, } from "node:fs";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
import { DatabaseSync } from "node:sqlite";
|
|
23
|
+
import { mailwomanDataRoot } from "./resolver-backend.js";
|
|
24
|
+
/**
|
|
25
|
+
* The bilingual / alt-name EU set the GeoNames fold lifts (FI hard-resolve 69.5 → 85.8 %). GeoNames
|
|
26
|
+
* `<CC>.txt` dumps from download.geonames.org/export/dump must be present under the geonames dir.
|
|
27
|
+
*/
|
|
28
|
+
export const DEFAULT_FOLD_COUNTRIES = [
|
|
29
|
+
"FI",
|
|
30
|
+
"PL",
|
|
31
|
+
"NO",
|
|
32
|
+
"CZ",
|
|
33
|
+
"AT",
|
|
34
|
+
"LT",
|
|
35
|
+
"LV",
|
|
36
|
+
"SI",
|
|
37
|
+
"SK",
|
|
38
|
+
"HR",
|
|
39
|
+
"DK",
|
|
40
|
+
"BE",
|
|
41
|
+
"CH",
|
|
42
|
+
"LU",
|
|
43
|
+
];
|
|
44
|
+
/**
|
|
45
|
+
* The canonical postcode-shard set (filenames under `<data-root>/wof/`) that reproduces the shipped
|
|
46
|
+
* gazetteer's ~1.79 M postcode coverage: US + the WOF intl shard (NL/FR/DE/ES/IT) + the GeoNames
|
|
47
|
+
* intl shard (PT/AU) + Overture postcode centroids (CA + the EU-coverage locales). GB (2.6 M) and
|
|
48
|
+
* JP are left out for size. Missing shards are skipped, not fatal.
|
|
49
|
+
*/
|
|
50
|
+
export const DEFAULT_POSTCODE_SHARDS = [
|
|
51
|
+
"postalcode-us.db",
|
|
52
|
+
"postalcode-intl.db",
|
|
53
|
+
"postalcode-geonames-intl.db",
|
|
54
|
+
"postcode-ca-overture.db",
|
|
55
|
+
...["at", "be", "ch", "cz", "dk", "es", "fi", "hr", "lt", "lu", "lv", "no", "pl", "pt", "si", "sk"].map((cc) => `postcode-${cc}-overture.db`),
|
|
56
|
+
];
|
|
57
|
+
/** The conventional admin source the fold copies from. */
|
|
58
|
+
export const DEFAULT_ADMIN_DB = "admin-global-priority.db";
|
|
59
|
+
/** The conventional candidate-build output. */
|
|
60
|
+
export const DEFAULT_CANDIDATE_OUT = "candidate-global.db";
|
|
61
|
+
/**
|
|
62
|
+
* `<data-root>/wof`, where the admin DB, candidate DB, postcode shards, and the convention symlink
|
|
63
|
+
* live.
|
|
64
|
+
*/
|
|
65
|
+
export function wofDir(dataRoot = mailwomanDataRoot()) {
|
|
66
|
+
return join(dataRoot, "wof");
|
|
67
|
+
}
|
|
68
|
+
/** `<data-root>/geonames`, the per-country GeoNames dump dir. */
|
|
69
|
+
export function geonamesDir(dataRoot = mailwomanDataRoot()) {
|
|
70
|
+
return join(dataRoot, "geonames");
|
|
71
|
+
}
|
|
72
|
+
/** Resolve the canonical postcode-shard filenames to absolute paths, keeping only those present. */
|
|
73
|
+
export function resolvePostcodeShards(shards = DEFAULT_POSTCODE_SHARDS, dataRoot = mailwomanDataRoot()) {
|
|
74
|
+
return shards.map((s) => join(wofDir(dataRoot), s)).filter((p) => existsSync(p));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Durable GeoNames upstream fold: copy the admin DB, fold the GeoNames places + Latin alt-names
|
|
78
|
+
* into its canonical `spr`/`names`/`place_population`, then rebuild `place_search`/`place_bbox` so
|
|
79
|
+
* the candidate build carries them. Build-on-copy — `adminIn` is never touched.
|
|
80
|
+
*/
|
|
81
|
+
export async function foldGeonamesIntoAdmin(opts) {
|
|
82
|
+
if (opts.adminIn === opts.adminOut) {
|
|
83
|
+
throw new Error("fold must write a distinct adminOut (build-on-copy, never in place)");
|
|
84
|
+
}
|
|
85
|
+
if (!existsSync(opts.adminIn))
|
|
86
|
+
throw new Error(`admin DB not found: ${opts.adminIn}`);
|
|
87
|
+
const { ingestGeonamesAliases, buildPlaceSearchFts } = await import("@mailwoman/resolver-wof-sqlite");
|
|
88
|
+
opts.onPhase?.("copy", `copying admin DB → ${opts.adminOut}`);
|
|
89
|
+
copyFileSync(opts.adminIn, opts.adminOut);
|
|
90
|
+
const db = new DatabaseSync(opts.adminOut);
|
|
91
|
+
const ingested = ingestGeonamesAliases(db, [...(opts.countries ?? DEFAULT_FOLD_COUNTRIES)], opts.geonamesDir ?? geonamesDir(), opts.onCountry);
|
|
92
|
+
opts.onPhase?.("place_search", "rebuilding place_search + place_bbox from the updated names");
|
|
93
|
+
const res = buildPlaceSearchFts(db, { drop: true, onProgress: (phase, detail) => opts.onPhase?.(phase, detail) });
|
|
94
|
+
db.exec("ANALYZE");
|
|
95
|
+
db.close();
|
|
96
|
+
return { ingested, placeSearchRows: res.indexedRows, bboxRows: res.bboxIndexedRows };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Build the byte-range candidate gazetteer from an admin DB + postcode shards. The FTS5-trigram
|
|
100
|
+
* fuzzy index is baked in by `buildCandidateTable`. Pure pass-through to the canonical builder.
|
|
101
|
+
*/
|
|
102
|
+
export async function buildCandidate(opts) {
|
|
103
|
+
const { buildCandidateTable } = await import("@mailwoman/resolver-wof-sqlite/build-candidate");
|
|
104
|
+
return buildCandidateTable({
|
|
105
|
+
input: opts.adminDb,
|
|
106
|
+
output: opts.out,
|
|
107
|
+
postcodes: [...(opts.postcodeShards ?? resolvePostcodeShards())],
|
|
108
|
+
onProgress: opts.onProgress,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Point the drop-in convention path `<data-root>/wof/candidate.db` at `candidateDb` (a symlink — a
|
|
113
|
+
* POINTER swap, never a DB mutation). The nominatim/photon CLIs auto-use this path. Returns the
|
|
114
|
+
* link.
|
|
115
|
+
*/
|
|
116
|
+
export function promoteCandidate(candidateDb, dataRoot = mailwomanDataRoot()) {
|
|
117
|
+
if (!existsSync(candidateDb))
|
|
118
|
+
throw new Error(`candidate DB not found: ${candidateDb}`);
|
|
119
|
+
const linkPath = join(wofDir(dataRoot), "candidate.db");
|
|
120
|
+
// Replace any existing pointer (symlink or stray file) — never the build it points at.
|
|
121
|
+
try {
|
|
122
|
+
if (lstatSync(linkPath))
|
|
123
|
+
rmSync(linkPath);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// nothing there yet
|
|
127
|
+
}
|
|
128
|
+
symlinkSync(candidateDb, linkPath);
|
|
129
|
+
return linkPath;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Publish the candidate gazetteer to R2 (the demo's byte-range source) and bump the demo's
|
|
133
|
+
* `ADMIN_GAZETTEER_VERSION`. Shells out to the proven `publish-demo-assets-to-r2.py` (boto3 + R2
|
|
134
|
+
* cache-control); RCLONE_S3_PUBLIC_* creds must be in the process env (source `.env` first).
|
|
135
|
+
*/
|
|
136
|
+
export function publishGazetteer(opts) {
|
|
137
|
+
if (!existsSync(opts.candidateDb))
|
|
138
|
+
throw new Error(`candidate DB not found: ${opts.candidateDb}`);
|
|
139
|
+
if (!existsSync(opts.uploadScript))
|
|
140
|
+
throw new Error(`upload script not found: ${opts.uploadScript}`);
|
|
141
|
+
const prefix = opts.prefix ?? "mailwoman";
|
|
142
|
+
const versionDir = join(opts.stageDir, "gazetteer", opts.version);
|
|
143
|
+
mkdirSync(versionDir, { recursive: true });
|
|
144
|
+
const staged = join(versionDir, "candidate.db");
|
|
145
|
+
try {
|
|
146
|
+
rmSync(staged);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// fresh
|
|
150
|
+
}
|
|
151
|
+
symlinkSync(opts.candidateDb, staged);
|
|
152
|
+
const key = `${prefix}/gazetteer/${opts.version}/candidate.db`;
|
|
153
|
+
opts.onPhase?.("upload", `R2 ${key}${opts.dryRun ? " (dry-run)" : ""}`);
|
|
154
|
+
const args = [opts.uploadScript, "--src", opts.stageDir, "--prefix", prefix];
|
|
155
|
+
if (opts.bucket)
|
|
156
|
+
args.push("--bucket", opts.bucket);
|
|
157
|
+
if (opts.dryRun)
|
|
158
|
+
args.push("--dry-run");
|
|
159
|
+
execFileSync("python3", args, { stdio: "inherit" });
|
|
160
|
+
let bumped = false;
|
|
161
|
+
if (opts.resourcesFile && !opts.dryRun && existsSync(opts.resourcesFile)) {
|
|
162
|
+
opts.onPhase?.("demo", `ADMIN_GAZETTEER_VERSION → ${opts.version}`);
|
|
163
|
+
const src = readFileSync(opts.resourcesFile, "utf8");
|
|
164
|
+
const next = src.replace(/(ADMIN_GAZETTEER_VERSION = ")[^"]+(")/, `$1${opts.version}$2`);
|
|
165
|
+
if (next !== src) {
|
|
166
|
+
writeFileSync(opts.resourcesFile, next);
|
|
167
|
+
bumped = true;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return { key, bumped };
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* A dated, immutable gazetteer version: `YYYY-MM-DD` + a lowercase suffix letter, e.g.
|
|
174
|
+
* `2026-06-27a`. Pass a `Date` (the CLI does; the module never reads the clock implicitly).
|
|
175
|
+
*/
|
|
176
|
+
export function defaultGazetteerVersion(now, suffix = "a") {
|
|
177
|
+
const y = now.getUTCFullYear();
|
|
178
|
+
const m = String(now.getUTCMonth() + 1).padStart(2, "0");
|
|
179
|
+
const d = String(now.getUTCDate()).padStart(2, "0");
|
|
180
|
+
return `${y}-${m}-${d}${suffix}`;
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=gazetteer-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gazetteer-pipeline.js","sourceRoot":"","sources":["../gazetteer-pipeline.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mailwoman",
|
|
3
|
-
"version": "4.16.
|
|
3
|
+
"version": "4.16.2",
|
|
4
4
|
"description": "A calibrated, retrieval-augmented postal-address parser — CLI + library.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"contributors": [
|
|
@@ -35,17 +35,17 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@fragaria/address-formatter": "^6.7.1",
|
|
37
37
|
"@inkjs/ui": "^2.0.0",
|
|
38
|
-
"@mailwoman/classifiers": "4.16.
|
|
39
|
-
"@mailwoman/core": "4.16.
|
|
40
|
-
"@mailwoman/corpus": "4.16.
|
|
41
|
-
"@mailwoman/kind-classifier": "4.16.
|
|
42
|
-
"@mailwoman/locale-gate": "4.16.
|
|
43
|
-
"@mailwoman/neural": "4.16.
|
|
44
|
-
"@mailwoman/normalize": "4.16.
|
|
45
|
-
"@mailwoman/phrase-grouper": "4.16.
|
|
46
|
-
"@mailwoman/query-shape": "4.16.
|
|
47
|
-
"@mailwoman/registry": "4.16.
|
|
48
|
-
"@mailwoman/resolver": "4.16.
|
|
38
|
+
"@mailwoman/classifiers": "4.16.2",
|
|
39
|
+
"@mailwoman/core": "4.16.2",
|
|
40
|
+
"@mailwoman/corpus": "4.16.2",
|
|
41
|
+
"@mailwoman/kind-classifier": "4.16.2",
|
|
42
|
+
"@mailwoman/locale-gate": "4.16.2",
|
|
43
|
+
"@mailwoman/neural": "4.16.2",
|
|
44
|
+
"@mailwoman/normalize": "4.16.2",
|
|
45
|
+
"@mailwoman/phrase-grouper": "4.16.2",
|
|
46
|
+
"@mailwoman/query-shape": "4.16.2",
|
|
47
|
+
"@mailwoman/registry": "4.16.2",
|
|
48
|
+
"@mailwoman/resolver": "4.16.2",
|
|
49
49
|
"chalk": "^5.6.2",
|
|
50
50
|
"change-case": "^5.4.4",
|
|
51
51
|
"d3-scale-chromatic": "^3.1.0",
|
|
@@ -66,10 +66,10 @@
|
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
68
|
"@duckdb/node-api": "1.5.3-r.3",
|
|
69
|
-
"@mailwoman/resolver-wof-sqlite": "4.16.
|
|
69
|
+
"@mailwoman/resolver-wof-sqlite": "4.16.2"
|
|
70
70
|
},
|
|
71
71
|
"optionalDependencies": {
|
|
72
|
-
"@mailwoman/tiger": "4.16.
|
|
72
|
+
"@mailwoman/tiger": "4.16.2"
|
|
73
73
|
},
|
|
74
74
|
"files": [
|
|
75
75
|
"!out/test/**/*",
|