@tikoci/rosetta 0.7.6 → 0.7.7
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/package.json +1 -1
- package/src/classify.ts +43 -1
- package/src/extract-dude.test.ts +10 -1
- package/src/extract-html.ts +10 -0
- package/src/query.test.ts +13 -1
- package/src/query.ts +3 -40
- package/src/release.test.ts +20 -0
package/package.json
CHANGED
package/src/classify.ts
CHANGED
|
@@ -14,7 +14,49 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { canonicalize } from "./canonicalize.ts";
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Known RouterOS topics — extracted from changelog categories, top-level
|
|
20
|
+
* command tree names, and common subsystem tokens. Used by the classifier
|
|
21
|
+
* to recognize domain-specific terms before FTS search.
|
|
22
|
+
*
|
|
23
|
+
* Source: `SELECT DISTINCT category FROM changelogs` (153 values) plus
|
|
24
|
+
* top-level commands (app, interface, ip, system) and common synonyms.
|
|
25
|
+
*
|
|
26
|
+
* Defined here (not in query.ts) so classify.ts stays pure (no DB imports)
|
|
27
|
+
* and classify.test.ts cannot transitively load db.ts before test setup.
|
|
28
|
+
*/
|
|
29
|
+
export const KNOWN_TOPICS = new Set([
|
|
30
|
+
// --- From changelog categories (high-frequency subsystems) ---
|
|
31
|
+
"api", "backup", "bgp", "bluetooth", "bonding", "bridge", "capsman",
|
|
32
|
+
"certificate", "chr", "cloud", "conntrack", "console", "container",
|
|
33
|
+
"defconf", "discovery", "disk", "dns", "dot1x", "dude",
|
|
34
|
+
"ethernet", "export", "fetch", "filesystem", "firewall",
|
|
35
|
+
"gps", "graphing", "hardware", "health", "hotspot",
|
|
36
|
+
"ike1", "ike2", "interface", "ipsec", "ipv6",
|
|
37
|
+
"l2tp", "l3hw", "ldp", "led", "log", "lora", "lte",
|
|
38
|
+
"macsec", "mlag", "modem", "mpls", "mqtt",
|
|
39
|
+
"netinstall", "netwatch", "ntp",
|
|
40
|
+
"ospf", "ovpn",
|
|
41
|
+
"poe", "ppp", "pppoe", "pptp", "ptp",
|
|
42
|
+
"queue", "quickset",
|
|
43
|
+
"radius", "resource", "rip", "romon", "route", "routing",
|
|
44
|
+
"serial", "sfp", "smb", "sms", "sniffer", "snmp", "socks", "ssh", "ssl", "sstp",
|
|
45
|
+
"switch", "system",
|
|
46
|
+
"traceroute", "tunnels", "upgrade", "upnp", "ups", "usb", "user",
|
|
47
|
+
"vlan", "vpls", "vrf", "vrrp", "vxlan",
|
|
48
|
+
"webfig", "wifi", "wifiwave2", "winbox", "wireguard", "wireless",
|
|
49
|
+
"zerotier",
|
|
50
|
+
// --- From changelog (DHCP variants, routing sub-protocols) ---
|
|
51
|
+
"dhcp", "dhcpv4", "dhcpv6", "rpki", "pimsm",
|
|
52
|
+
// --- Top-level command paths ---
|
|
53
|
+
"app", "ip",
|
|
54
|
+
// --- Common subsystem shorthand / synonyms ---
|
|
55
|
+
"nat", "mangle", "raw", "filter",
|
|
56
|
+
"bgp-vpn", "user-manager", "traffic-flow", "traffic-generator",
|
|
57
|
+
"route-filter", "routing-filter", "mac-telnet",
|
|
58
|
+
"w60g", "tr069",
|
|
59
|
+
]);
|
|
18
60
|
|
|
19
61
|
export type CommandFragment = {
|
|
20
62
|
/** `key=value` pairs extracted from the input (e.g. `chain=forward`). */
|
package/src/extract-dude.test.ts
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
// Force in-memory DB BEFORE importing extract-dude.ts (which transitively imports
|
|
2
|
+
// db.ts). Without this, db.ts evaluates against the project's real ros-help.db
|
|
3
|
+
// and any later test file (e.g. query.test.ts) that calls DELETE in beforeAll
|
|
4
|
+
// will wipe the CI-built database — exactly the bug that shipped 3-page DBs in
|
|
5
|
+
// release v0.7.6. See BACKLOG.md "Test DB-leak guards".
|
|
6
|
+
process.env.DB_PATH = ":memory:";
|
|
7
|
+
|
|
1
8
|
import { describe, expect, test } from "bun:test";
|
|
2
9
|
import { readFileSync } from "node:fs";
|
|
3
10
|
import { join } from "node:path";
|
|
4
|
-
|
|
11
|
+
|
|
12
|
+
// Dynamic import so the DB_PATH assignment above wins over module hoisting.
|
|
13
|
+
const { parseDudePage } = await import("./extract-dude.ts");
|
|
5
14
|
|
|
6
15
|
const probesHtml = readFileSync(join(import.meta.dirname, "..", "dude", "pages", "Probes.html"), "utf-8");
|
|
7
16
|
|
package/src/extract-html.ts
CHANGED
|
@@ -558,6 +558,16 @@ function main() {
|
|
|
558
558
|
console.log(` Total sections: ${totalSections} (across ${pagesWithSections} pages)`);
|
|
559
559
|
console.log(` FTS index rows: ${ftsCount}`);
|
|
560
560
|
|
|
561
|
+
// Hard fail if no pages were extracted — silent zero-page runs were the
|
|
562
|
+
// root cause of release v0.7.6 shipping a near-empty DB. CI must fail loud.
|
|
563
|
+
if (extracted === 0) {
|
|
564
|
+
console.error(
|
|
565
|
+
`\n::error::extract-html: 0 pages extracted from ${process.argv[2] ?? "(default dir)"}. ` +
|
|
566
|
+
`Check the HTML export download/unzip step.`,
|
|
567
|
+
);
|
|
568
|
+
process.exit(1);
|
|
569
|
+
}
|
|
570
|
+
|
|
561
571
|
// Quick search test
|
|
562
572
|
const testResults = db
|
|
563
573
|
.prepare(
|
package/src/query.test.ts
CHANGED
|
@@ -13,7 +13,19 @@ import { beforeAll, describe, expect, test } from "bun:test";
|
|
|
13
13
|
process.env.DB_PATH = ":memory:";
|
|
14
14
|
|
|
15
15
|
// Dynamic imports so the env-var assignment above is visible to db.ts
|
|
16
|
-
const { db, initDb, getDbStats, checkSchemaVersion, SCHEMA_VERSION } = await import("./db.ts");
|
|
16
|
+
const { db, initDb, getDbStats, checkSchemaVersion, SCHEMA_VERSION, DB_PATH } = await import("./db.ts");
|
|
17
|
+
|
|
18
|
+
// Hard guard: if some other test file imported db.ts before us with a real
|
|
19
|
+
// path, the singleton will be pointing at the project's ros-help.db and the
|
|
20
|
+
// DELETEs in beforeAll() below would wipe it. Fail fast with a clear message
|
|
21
|
+
// so this can never silently ship an empty DB again (release v0.7.6 regression).
|
|
22
|
+
if (DB_PATH !== ":memory:") {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`query.test.ts: DB singleton is at "${DB_PATH}" — expected ":memory:". ` +
|
|
25
|
+
`Another test file imported db.ts before this one without setting DB_PATH=:memory:. ` +
|
|
26
|
+
`Refusing to run because beforeAll() would DELETE FROM real tables.`,
|
|
27
|
+
);
|
|
28
|
+
}
|
|
17
29
|
const {
|
|
18
30
|
extractTerms,
|
|
19
31
|
buildFtsQuery,
|
package/src/query.ts
CHANGED
|
@@ -90,46 +90,9 @@ const COMPOUND_TERMS: [string, string][] = [
|
|
|
90
90
|
["address", "list"],
|
|
91
91
|
];
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
* (future) and glossary lookup to recognize domain-specific terms before
|
|
97
|
-
* FTS search. Maintained as a static Set for O(1) lookup.
|
|
98
|
-
*
|
|
99
|
-
* Source: `SELECT DISTINCT category FROM changelogs` (153 values) plus
|
|
100
|
-
* top-level commands (app, interface, ip, system) and common synonyms.
|
|
101
|
-
*/
|
|
102
|
-
export const KNOWN_TOPICS = new Set([
|
|
103
|
-
// --- From changelog categories (high-frequency subsystems) ---
|
|
104
|
-
"api", "backup", "bgp", "bluetooth", "bonding", "bridge", "capsman",
|
|
105
|
-
"certificate", "chr", "cloud", "conntrack", "console", "container",
|
|
106
|
-
"defconf", "discovery", "disk", "dns", "dot1x", "dude",
|
|
107
|
-
"ethernet", "export", "fetch", "filesystem", "firewall",
|
|
108
|
-
"gps", "graphing", "hardware", "health", "hotspot",
|
|
109
|
-
"ike1", "ike2", "interface", "ipsec", "ipv6",
|
|
110
|
-
"l2tp", "l3hw", "ldp", "led", "log", "lora", "lte",
|
|
111
|
-
"macsec", "mlag", "modem", "mpls", "mqtt",
|
|
112
|
-
"netinstall", "netwatch", "ntp",
|
|
113
|
-
"ospf", "ovpn",
|
|
114
|
-
"poe", "ppp", "pppoe", "pptp", "ptp",
|
|
115
|
-
"queue", "quickset",
|
|
116
|
-
"radius", "resource", "rip", "romon", "route", "routing",
|
|
117
|
-
"serial", "sfp", "smb", "sms", "sniffer", "snmp", "socks", "ssh", "ssl", "sstp",
|
|
118
|
-
"switch", "system",
|
|
119
|
-
"traceroute", "tunnels", "upgrade", "upnp", "ups", "usb", "user",
|
|
120
|
-
"vlan", "vpls", "vrf", "vrrp", "vxlan",
|
|
121
|
-
"webfig", "wifi", "wifiwave2", "winbox", "wireguard", "wireless",
|
|
122
|
-
"zerotier",
|
|
123
|
-
// --- From changelog (DHCP variants, routing sub-protocols) ---
|
|
124
|
-
"dhcp", "dhcpv4", "dhcpv6", "rpki", "pimsm",
|
|
125
|
-
// --- Top-level command paths ---
|
|
126
|
-
"app", "ip",
|
|
127
|
-
// --- Common subsystem shorthand / synonyms ---
|
|
128
|
-
"nat", "mangle", "raw", "filter",
|
|
129
|
-
"bgp-vpn", "user-manager", "traffic-flow", "traffic-generator",
|
|
130
|
-
"route-filter", "routing-filter", "mac-telnet",
|
|
131
|
-
"w60g", "tr069",
|
|
132
|
-
]);
|
|
93
|
+
// KNOWN_TOPICS is defined in classify.ts (pure module, no DB) and re-exported
|
|
94
|
+
// from here for backward compatibility. See classify.ts for the canonical definition.
|
|
95
|
+
export { KNOWN_TOPICS } from "./classify.ts";
|
|
133
96
|
|
|
134
97
|
function getSpecialSearchHint(question: string): string | undefined {
|
|
135
98
|
const normalized = question.toLowerCase();
|
package/src/release.test.ts
CHANGED
|
@@ -387,6 +387,26 @@ describe("release.yml", () => {
|
|
|
387
387
|
expect(src).toContain("npm publish");
|
|
388
388
|
expect(src).toContain("NPM_TOKEN");
|
|
389
389
|
});
|
|
390
|
+
|
|
391
|
+
test("validates DB content before publishing (regression: v0.7.6 shipped 3 pages)", () => {
|
|
392
|
+
const src = readText(".github/workflows/release.yml");
|
|
393
|
+
// Hard guard step that hard-fails the workflow if the built DB is degenerate.
|
|
394
|
+
expect(src).toContain("Validate DB has expected content");
|
|
395
|
+
// Must run BEFORE the artifact build, container push, GH Release, and npm publish.
|
|
396
|
+
const validateIdx = src.indexOf("Validate DB has expected content");
|
|
397
|
+
const buildIdx = src.indexOf("Build release artifacts");
|
|
398
|
+
const releaseIdx = src.indexOf("gh release create");
|
|
399
|
+
const npmIdx = src.indexOf("npm publish");
|
|
400
|
+
expect(validateIdx).toBeGreaterThan(0);
|
|
401
|
+
expect(validateIdx).toBeLessThan(buildIdx);
|
|
402
|
+
expect(validateIdx).toBeLessThan(releaseIdx);
|
|
403
|
+
expect(validateIdx).toBeLessThan(npmIdx);
|
|
404
|
+
// Must check minimum thresholds for the four critical tables.
|
|
405
|
+
expect(src).toMatch(/PAGES.*-lt 200/);
|
|
406
|
+
expect(src).toMatch(/COMMANDS.*-lt 1000/);
|
|
407
|
+
expect(src).toMatch(/DEVICES.*-lt 100/);
|
|
408
|
+
expect(src).toMatch(/PROPERTIES.*-lt 1000/);
|
|
409
|
+
});
|
|
390
410
|
});
|
|
391
411
|
|
|
392
412
|
// ---------------------------------------------------------------------------
|