@tikoci/rosetta 0.5.0 → 0.5.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/README.md +64 -147
- package/package.json +1 -1
- package/src/browse.ts +116 -40
- package/src/db.ts +16 -0
- package/src/extract-devices.ts +5 -1
- package/src/extract-html.test.ts +67 -0
- package/src/extract-html.ts +239 -112
- package/src/mcp.ts +8 -4
- package/src/query.test.ts +36 -5
- package/src/query.ts +32 -20
package/src/query.ts
CHANGED
|
@@ -458,6 +458,7 @@ export function searchProperties(
|
|
|
458
458
|
default_val: string | null;
|
|
459
459
|
description: string;
|
|
460
460
|
section: string | null;
|
|
461
|
+
page_id: number;
|
|
461
462
|
page_title: string;
|
|
462
463
|
page_url: string;
|
|
463
464
|
excerpt: string;
|
|
@@ -486,6 +487,7 @@ function runPropertiesFtsQuery(
|
|
|
486
487
|
default_val: string | null;
|
|
487
488
|
description: string;
|
|
488
489
|
section: string | null;
|
|
490
|
+
page_id: number;
|
|
489
491
|
page_title: string;
|
|
490
492
|
page_url: string;
|
|
491
493
|
excerpt: string;
|
|
@@ -495,7 +497,7 @@ function runPropertiesFtsQuery(
|
|
|
495
497
|
return db
|
|
496
498
|
.prepare(
|
|
497
499
|
`SELECT p.name, p.type, p.default_val, p.description, p.section,
|
|
498
|
-
pg.title as page_title, pg.url as page_url,
|
|
500
|
+
pg.id as page_id, pg.title as page_title, pg.url as page_url,
|
|
499
501
|
snippet(properties_fts, 1, '**', '**', '...', 20) as excerpt
|
|
500
502
|
FROM properties_fts fts
|
|
501
503
|
JOIN properties p ON p.id = fts.rowid
|
|
@@ -509,6 +511,7 @@ function runPropertiesFtsQuery(
|
|
|
509
511
|
default_val: string | null;
|
|
510
512
|
description: string;
|
|
511
513
|
section: string | null;
|
|
514
|
+
page_id: number;
|
|
512
515
|
page_title: string;
|
|
513
516
|
page_url: string;
|
|
514
517
|
excerpt: string;
|
|
@@ -518,7 +521,7 @@ function runPropertiesFtsQuery(
|
|
|
518
521
|
}
|
|
519
522
|
}
|
|
520
523
|
|
|
521
|
-
type CalloutResult = {
|
|
524
|
+
export type CalloutResult = {
|
|
522
525
|
type: string;
|
|
523
526
|
content: string;
|
|
524
527
|
page_title: string;
|
|
@@ -1088,6 +1091,7 @@ export type DeviceTestRow = {
|
|
|
1088
1091
|
};
|
|
1089
1092
|
|
|
1090
1093
|
type DeviceTestFilters = {
|
|
1094
|
+
device?: string;
|
|
1091
1095
|
test_type?: string;
|
|
1092
1096
|
mode?: string;
|
|
1093
1097
|
configuration?: string;
|
|
@@ -1099,6 +1103,10 @@ function buildTestWhereClause(filters: DeviceTestFilters): { whereClause: string
|
|
|
1099
1103
|
const where: string[] = [];
|
|
1100
1104
|
const params: (string | number)[] = [];
|
|
1101
1105
|
|
|
1106
|
+
if (filters.device) {
|
|
1107
|
+
where.push("d.product_name LIKE ?");
|
|
1108
|
+
params.push(`%${filters.device}%`);
|
|
1109
|
+
}
|
|
1102
1110
|
if (filters.test_type) {
|
|
1103
1111
|
where.push("t.test_type = ?");
|
|
1104
1112
|
params.push(filters.test_type);
|
|
@@ -1485,27 +1493,31 @@ function runVideosFtsQuery(ftsQuery: string, limit: number): VideoSearchResult[]
|
|
|
1485
1493
|
const VERSION_BASE_URL = "https://upgrade.mikrotik.com/routeros/NEWESTa7";
|
|
1486
1494
|
|
|
1487
1495
|
/** Fetch current RouterOS versions from MikroTik's upgrade server. */
|
|
1496
|
+
const WINBOX_URL = "https://upgrade.mikrotik.com/routeros/winbox/LATEST.4";
|
|
1497
|
+
|
|
1488
1498
|
export async function fetchCurrentVersions(): Promise<{
|
|
1489
1499
|
channels: Record<string, string | null>;
|
|
1500
|
+
winbox: string | null;
|
|
1490
1501
|
fetched_at: string;
|
|
1491
1502
|
}> {
|
|
1492
1503
|
const channels: Record<string, string | null> = {};
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
channels[channel] =
|
|
1507
|
-
}
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1504
|
+
const fetchOne = async (url: string): Promise<string | null> => {
|
|
1505
|
+
try {
|
|
1506
|
+
const resp = await fetch(url, { signal: AbortSignal.timeout(10_000) });
|
|
1507
|
+
if (!resp.ok) return null;
|
|
1508
|
+
const text = await resp.text();
|
|
1509
|
+
return text.trim().split(/\s+/)[0] || null;
|
|
1510
|
+
} catch {
|
|
1511
|
+
return null;
|
|
1512
|
+
}
|
|
1513
|
+
};
|
|
1514
|
+
const [, winbox] = await Promise.all([
|
|
1515
|
+
Promise.all(
|
|
1516
|
+
VERSION_CHANNELS.map(async (channel) => {
|
|
1517
|
+
channels[channel] = await fetchOne(`${VERSION_BASE_URL}.${channel}`);
|
|
1518
|
+
}),
|
|
1519
|
+
),
|
|
1520
|
+
fetchOne(WINBOX_URL),
|
|
1521
|
+
]);
|
|
1522
|
+
return { channels, winbox, fetched_at: new Date().toISOString() };
|
|
1511
1523
|
}
|