token-goat 2.9.14 → 2.9.16
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 +15 -1
- package/dist/{token-goat-chunk-2ESBO4IN.mjs → token-goat-chunk-2IEIBVVD.mjs} +16 -9
- package/dist/{token-goat-chunk-RUDOKYPJ.mjs → token-goat-chunk-2PCFAQAS.mjs} +6582 -6194
- package/dist/{token-goat-chunk-AMYCQJX4.mjs → token-goat-chunk-3H6FQT62.mjs} +49 -256
- package/dist/{token-goat-chunk-PRJVGIC5.mjs → token-goat-chunk-4DC6DDIB.mjs} +7 -5
- package/dist/token-goat-chunk-4EXFN2AW.mjs +29 -0
- package/dist/{token-goat-chunk-VZYD4OZB.mjs → token-goat-chunk-5USHO7B6.mjs} +416 -4168
- package/dist/token-goat-chunk-63QWJ6UM.mjs +277 -0
- package/dist/token-goat-chunk-BFNTLGVA.mjs +4547 -0
- package/dist/token-goat-chunk-BGHSSJUA.mjs +102 -0
- package/dist/{token-goat-chunk-T2IWWTHB.mjs → token-goat-chunk-DMQ32ZSR.mjs} +35 -1142
- package/dist/{token-goat-chunk-DBNY4RLN.mjs → token-goat-chunk-EJCY6KHO.mjs} +5 -3
- package/dist/token-goat-chunk-ERTXEKB6.mjs +228 -0
- package/dist/{token-goat-chunk-Z6UXPYJA.mjs → token-goat-chunk-F2ARFHLJ.mjs} +1 -1
- package/dist/{token-goat-chunk-EG3663UT.mjs → token-goat-chunk-GIMGT34T.mjs} +4 -2
- package/dist/{token-goat-chunk-XVZ4MNQC.mjs → token-goat-chunk-GMXBQS6O.mjs} +360 -116
- package/dist/{token-goat-chunk-SAQ5PG4L.mjs → token-goat-chunk-H3DXI6VD.mjs} +8 -4
- package/dist/token-goat-chunk-LJL6FGDS.mjs +35 -0
- package/dist/{token-goat-chunk-NEI4NC54.mjs → token-goat-chunk-LKSXAMJB.mjs} +7 -2
- package/dist/token-goat-chunk-LMFO66YD.mjs +331 -0
- package/dist/{token-goat-chunk-7OGKZ7AP.mjs → token-goat-chunk-M2R4UQ3B.mjs} +5 -3
- package/dist/{token-goat-chunk-YHGTGG6K.mjs → token-goat-chunk-MA5BZ2KI.mjs} +68 -7
- package/dist/{token-goat-chunk-ASVVF4JV.mjs → token-goat-chunk-MIL62GMN.mjs} +171 -23
- package/dist/{token-goat-chunk-ZFM4PWXL.mjs → token-goat-chunk-NAMH252H.mjs} +10 -7
- package/dist/{token-goat-chunk-YTQHZJXW.mjs → token-goat-chunk-NOBZV7PM.mjs} +96 -22
- package/dist/{token-goat-chunk-4SDX3QP3.mjs → token-goat-chunk-NQZCSVN2.mjs} +13 -5
- package/dist/{token-goat-chunk-XEH6KBWW.mjs → token-goat-chunk-OCI25AXY.mjs} +4 -3
- package/dist/token-goat-chunk-OSUFN2FV.mjs +326 -0
- package/dist/{token-goat-chunk-O5WAMISC.mjs → token-goat-chunk-QMZMHQRR.mjs} +29 -18
- package/dist/{token-goat-chunk-POBYR64E.mjs → token-goat-chunk-R3X5TCPB.mjs} +801 -3
- package/dist/token-goat-chunk-RRNZMM3A.mjs +3364 -0
- package/dist/{token-goat-chunk-PGGDW7DZ.mjs → token-goat-chunk-ULA4WCED.mjs} +9 -6
- package/dist/token-goat-chunk-UMXD2M7O.mjs +975 -0
- package/dist/{token-goat-chunk-3XQPEJMV.mjs → token-goat-chunk-UXHDBVUR.mjs} +1 -1
- package/dist/{token-goat-chunk-EZNVAIR3.mjs → token-goat-chunk-VVIYEFBI.mjs} +4 -3
- package/dist/token-goat-chunk-XOHTFRDH.mjs +10760 -0
- package/dist/{token-goat-chunk-HF6H7RNK.mjs → token-goat-chunk-YPS64ACE.mjs} +13 -3
- package/dist/{token-goat-chunk-DAMXYVIW.mjs → token-goat-chunk-Z5VPAXTC.mjs} +2560 -820
- package/dist/{token-goat-chunk-XQF5J25J.mjs → token-goat-chunk-ZEHFYJ7Z.mjs} +5 -4
- package/dist/token-goat-hook.mjs +15 -10
- package/dist/token-goat.core.mjs +24 -18
- package/docs/cli.md +8 -6
- package/package.json +1 -1
- package/dist/token-goat-chunk-IT6O3PNN.mjs +0 -15463
- package/dist/token-goat-chunk-ZD4EM4LR.mjs +0 -30
- package/dist/token-goat-chunk-ZYNNQ36L.mjs +0 -479
|
@@ -11,10 +11,12 @@ import {
|
|
|
11
11
|
decodeSource,
|
|
12
12
|
extractErrorMessage,
|
|
13
13
|
foldPath,
|
|
14
|
-
normalizeDarwinSystemAlias,
|
|
15
14
|
projectConfigPath,
|
|
16
15
|
runGit
|
|
17
|
-
} from "./token-goat-chunk-
|
|
16
|
+
} from "./token-goat-chunk-3H6FQT62.mjs";
|
|
17
|
+
import {
|
|
18
|
+
normalizeDarwinSystemAlias
|
|
19
|
+
} from "./token-goat-chunk-ERTXEKB6.mjs";
|
|
18
20
|
import {
|
|
19
21
|
init_define_import_meta_env
|
|
20
22
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
@@ -1419,7 +1421,8 @@ var CONFIG_DEFAULTS = {
|
|
|
1419
1421
|
image_shrink: {
|
|
1420
1422
|
enabled: true,
|
|
1421
1423
|
jpeg_quality: 75,
|
|
1422
|
-
|
|
1424
|
+
// 16,000,000 used to reject a routine 24MP DSLR/phone photo outright -- the exact input this feature exists to shrink -- while the engine's own decode ceiling (MAX_DECODED_BYTES in image_engine.ts, 256MB at 4 bytes/pixel for a single frame) sits at 67,108,864px. 64,000,000 covers cameras well past 24MP (including 48MP phone sensors) with ~4.9% margin below that hard ceiling, which assertDecodableSize enforces independently of this value on every decode regardless of what this header check allows through. Measured on this engine (2026-09-17): a 24MP PNG decodes+shrinks in ~370ms, 60,000,516px in ~920ms, and 67,108,864px (the ceiling itself) in ~760ms -- all comfortably fast, so the new value is chosen for coverage headroom under the ceiling, not for decode-time cost. Decode time is not the cost that binds, though: memory is. This value is read off a header before anything is decoded, so what it really sets is how large a buffer a file's own declared dimensions may talk this hook into allocating -- at 4 bytes per pixel, raising it from 16,000,000 raised that peak from ~64MB to ~256MB, which is why it now sits flush against MAX_DECODED_BYTES rather than comfortably below it. And on the JPEG path there is no assertDecodableSize call at all: decodeJpeg hands the buffer to jpeg-js, so a JPEG decode is bounded by whatever maxResolutionInMP/maxMemoryUsageInMB that call passes -- a bound this codebase states only because decodeJpeg passes both explicitly rather than inheriting jpeg-js's own 100MP default, which is looser than the 67.1MP MAX_DECODED_BYTES allows.
|
|
1425
|
+
max_image_pixels: 64e6,
|
|
1423
1426
|
screenshot_redirect: true,
|
|
1424
1427
|
ocr_enabled: true,
|
|
1425
1428
|
// Confidence is Tesseract's own 0-100 mean-word-confidence score. 65 is a deliberately
|
|
@@ -1564,7 +1567,7 @@ var CONFIG_DEFAULTS = {
|
|
|
1564
1567
|
offline: false
|
|
1565
1568
|
},
|
|
1566
1569
|
mcp: {
|
|
1567
|
-
confine_reads_to_project_root:
|
|
1570
|
+
confine_reads_to_project_root: false,
|
|
1568
1571
|
allowed_roots: []
|
|
1569
1572
|
},
|
|
1570
1573
|
hint_stats: {
|
|
@@ -1953,6 +1956,7 @@ function invalidateConfigCache() {
|
|
|
1953
1956
|
_cached2 = null;
|
|
1954
1957
|
resetLastProjectConfigLockedKeys();
|
|
1955
1958
|
}
|
|
1959
|
+
registerReset(invalidateConfigCache);
|
|
1956
1960
|
function withoutConfigEnv(fn) {
|
|
1957
1961
|
const keys = allEnvKeys();
|
|
1958
1962
|
const saved = {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
buildEvent,
|
|
5
|
+
relay,
|
|
6
|
+
relayInProcess
|
|
7
|
+
} from "./token-goat-chunk-GMXBQS6O.mjs";
|
|
8
|
+
import "./token-goat-chunk-UXHDBVUR.mjs";
|
|
9
|
+
import {
|
|
10
|
+
MAX_STDIN_BYTES,
|
|
11
|
+
readStdinJson
|
|
12
|
+
} from "./token-goat-chunk-UMXD2M7O.mjs";
|
|
13
|
+
import "./token-goat-chunk-XOHTFRDH.mjs";
|
|
14
|
+
import "./token-goat-chunk-5USHO7B6.mjs";
|
|
15
|
+
import "./token-goat-chunk-DMQ32ZSR.mjs";
|
|
16
|
+
import "./token-goat-chunk-3BTK54F3.mjs";
|
|
17
|
+
import "./token-goat-chunk-BFNTLGVA.mjs";
|
|
18
|
+
import "./token-goat-chunk-63QWJ6UM.mjs";
|
|
19
|
+
import "./token-goat-chunk-R3X5TCPB.mjs";
|
|
20
|
+
import "./token-goat-chunk-H3DXI6VD.mjs";
|
|
21
|
+
import "./token-goat-chunk-EEIDFMEM.mjs";
|
|
22
|
+
import "./token-goat-chunk-OSUFN2FV.mjs";
|
|
23
|
+
import "./token-goat-chunk-3H6FQT62.mjs";
|
|
24
|
+
import "./token-goat-chunk-ERTXEKB6.mjs";
|
|
25
|
+
import "./token-goat-chunk-Y4AFKTHK.mjs";
|
|
26
|
+
import "./token-goat-chunk-GMOUBOX4.mjs";
|
|
27
|
+
import "./token-goat-chunk-RRNZMM3A.mjs";
|
|
28
|
+
import "./token-goat-chunk-A37V4PBF.mjs";
|
|
29
|
+
export {
|
|
30
|
+
MAX_STDIN_BYTES,
|
|
31
|
+
buildEvent,
|
|
32
|
+
readStdinJson,
|
|
33
|
+
relay,
|
|
34
|
+
relayInProcess
|
|
35
|
+
};
|
|
@@ -280,7 +280,7 @@ async function extractPdfText(data, pagesSpec, layout = false) {
|
|
|
280
280
|
for (let i = start; i <= end; i++) {
|
|
281
281
|
const page = await getPageWithinDeadline(doc, i, deadline);
|
|
282
282
|
const textItems = await readPageTextItems(page, MAX_PDF_TEXT_BYTES - spent, deadline);
|
|
283
|
-
const pageText = layout ? reconstructLayout(textItems, deadline) : textItems
|
|
283
|
+
const pageText = layout ? reconstructLayout(textItems, deadline) : joinTextItems(textItems, "\n");
|
|
284
284
|
spent += pageText.length;
|
|
285
285
|
pages.push(pageText.trim());
|
|
286
286
|
}
|
|
@@ -306,7 +306,7 @@ async function locatePdfPages(data, pattern, opts) {
|
|
|
306
306
|
for (; i <= end && matches.length < maxMatches; i++) {
|
|
307
307
|
const page = await getPageWithinDeadline(doc, i, deadline);
|
|
308
308
|
const textItems = await readPageTextItems(page, MAX_PDF_TEXT_BYTES, deadline);
|
|
309
|
-
const pageText = textItems
|
|
309
|
+
const pageText = joinTextItems(textItems, " ");
|
|
310
310
|
const m = re.exec(pageText);
|
|
311
311
|
if (m === null) continue;
|
|
312
312
|
matches.push({ page: i, snippet: locateSnippet(pageText, m.index, m[0].length, context) });
|
|
@@ -315,6 +315,11 @@ async function locatePdfPages(data, pattern, opts) {
|
|
|
315
315
|
return { matches, truncated };
|
|
316
316
|
});
|
|
317
317
|
}
|
|
318
|
+
function joinTextItems(items, eol) {
|
|
319
|
+
let out = "";
|
|
320
|
+
for (const item of items) out += item.str + (item.hasEOL ? eol : "");
|
|
321
|
+
return out;
|
|
322
|
+
}
|
|
318
323
|
function locateSnippet(text, index, matchLen, context) {
|
|
319
324
|
const kept = Math.min(matchLen, context);
|
|
320
325
|
const pad = Math.max(0, context - kept);
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
Database
|
|
5
|
+
} from "./token-goat-chunk-OSUFN2FV.mjs";
|
|
6
|
+
import {
|
|
7
|
+
displaySafeText
|
|
8
|
+
} from "./token-goat-chunk-ERTXEKB6.mjs";
|
|
9
|
+
import {
|
|
10
|
+
init_define_import_meta_env
|
|
11
|
+
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
12
|
+
|
|
13
|
+
// src/sqlite_query.ts
|
|
14
|
+
init_define_import_meta_env();
|
|
15
|
+
import * as fs from "node:fs";
|
|
16
|
+
var SQLITE_QUERY_ROW_CAP = 5e3;
|
|
17
|
+
var SQLITE_MAGIC = Buffer.from([83, 81, 76, 105, 116, 101, 32, 102, 111, 114, 109, 97, 116, 32, 51, 0]);
|
|
18
|
+
function readMagicBytes(filePath) {
|
|
19
|
+
let fd;
|
|
20
|
+
try {
|
|
21
|
+
fd = fs.openSync(filePath, "r");
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const buf = Buffer.alloc(SQLITE_MAGIC.length);
|
|
27
|
+
const bytesRead = fs.readSync(fd, buf, 0, buf.length, 0);
|
|
28
|
+
return bytesRead === buf.length ? buf : null;
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
} finally {
|
|
32
|
+
fs.closeSync(fd);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function isSqliteFile(filePath) {
|
|
36
|
+
const magic = readMagicBytes(filePath);
|
|
37
|
+
return magic !== null && magic.equals(SQLITE_MAGIC);
|
|
38
|
+
}
|
|
39
|
+
function openReadonlySqlite(filePath) {
|
|
40
|
+
if (!fs.existsSync(filePath)) {
|
|
41
|
+
throw new Error(`file not found: ${displaySafeText(filePath)}`);
|
|
42
|
+
}
|
|
43
|
+
if (!isSqliteFile(filePath)) {
|
|
44
|
+
throw new Error(`not a valid SQLite database (bad file header): ${displaySafeText(filePath)}`);
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
return new Database(filePath, { readonly: true, fileMustExist: true });
|
|
48
|
+
} catch (e) {
|
|
49
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
50
|
+
throw new Error(`failed to open SQLite database: ${msg}`, { cause: e });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function quoteIdent(name) {
|
|
54
|
+
return `"${name.replace(/"/g, '""')}"`;
|
|
55
|
+
}
|
|
56
|
+
function getSqliteSchema(filePath) {
|
|
57
|
+
const db = openReadonlySqlite(filePath);
|
|
58
|
+
try {
|
|
59
|
+
const objects = db.prepare("SELECT name, type FROM sqlite_master WHERE type IN ('table','view') AND name NOT LIKE 'sqlite\\_%' ESCAPE '\\' ORDER BY name").all();
|
|
60
|
+
const tables = objects.map((o) => {
|
|
61
|
+
const columns = db.prepare(`PRAGMA table_info(${quoteIdent(o.name)})`).all().map(
|
|
62
|
+
(c) => ({
|
|
63
|
+
name: c.name,
|
|
64
|
+
type: c.type || "",
|
|
65
|
+
notNull: c.notnull === 1,
|
|
66
|
+
primaryKey: c.pk > 0,
|
|
67
|
+
defaultValue: c.dflt_value === null || c.dflt_value === void 0 ? null : String(c.dflt_value)
|
|
68
|
+
})
|
|
69
|
+
);
|
|
70
|
+
const indexes = db.prepare(`PRAGMA index_list(${quoteIdent(o.name)})`).all().map(
|
|
71
|
+
(idx) => {
|
|
72
|
+
const idxColumns = db.prepare(`PRAGMA index_info(${quoteIdent(idx.name)})`).all().map((c) => c.name);
|
|
73
|
+
return { name: idx.name, unique: idx.unique === 1, columns: idxColumns };
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
const foreignKeys = db.prepare(`PRAGMA foreign_key_list(${quoteIdent(o.name)})`).all().map((fk) => ({ table: fk.table, from: fk.from, to: fk.to }));
|
|
77
|
+
let rowCount;
|
|
78
|
+
try {
|
|
79
|
+
const row = db.prepare(`SELECT COUNT(*) AS c FROM ${quoteIdent(o.name)}`).get();
|
|
80
|
+
rowCount = row.c;
|
|
81
|
+
} catch {
|
|
82
|
+
rowCount = null;
|
|
83
|
+
}
|
|
84
|
+
return { name: o.name, kind: o.type === "view" ? "view" : "table", columns, indexes, foreignKeys, rowCount };
|
|
85
|
+
});
|
|
86
|
+
return { tables };
|
|
87
|
+
} finally {
|
|
88
|
+
db.close();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function formatSqliteSchema(result) {
|
|
92
|
+
if (result.tables.length === 0) return "(no tables or views found)";
|
|
93
|
+
return result.tables.map((t) => {
|
|
94
|
+
const lines = [`${t.name} (${t.kind}${t.rowCount !== null ? `, ${t.rowCount} row${t.rowCount === 1 ? "" : "s"}` : ""})`];
|
|
95
|
+
for (const c of t.columns) {
|
|
96
|
+
const flags = [c.primaryKey ? "PK" : null, c.notNull ? "NOT NULL" : null, c.defaultValue !== null ? `DEFAULT ${c.defaultValue}` : null].filter((f) => f !== null).join(" ");
|
|
97
|
+
lines.push(` ${displaySafeText(c.name)} ${displaySafeText(c.type || "(untyped)")}${flags ? ` ${flags}` : ""}`);
|
|
98
|
+
}
|
|
99
|
+
if (t.indexes.length > 0) {
|
|
100
|
+
lines.push(" indexes:");
|
|
101
|
+
for (const idx of t.indexes) {
|
|
102
|
+
lines.push(` ${displaySafeText(idx.name)}${idx.unique ? " (unique)" : ""}: ${displaySafeText(idx.columns.join(", "))}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (t.foreignKeys.length > 0) {
|
|
106
|
+
lines.push(" foreign keys:");
|
|
107
|
+
for (const fk of t.foreignKeys) {
|
|
108
|
+
lines.push(` ${fk.from} -> ${fk.table}.${fk.to}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return lines.join("\n");
|
|
112
|
+
}).join("\n\n");
|
|
113
|
+
}
|
|
114
|
+
function getSqliteTables(filePath) {
|
|
115
|
+
const db = openReadonlySqlite(filePath);
|
|
116
|
+
try {
|
|
117
|
+
const objects = db.prepare(
|
|
118
|
+
// ESCAPE makes every `_` literal; see getSqliteSchema above. Here it costs three tables rather than one, since `%_fts_%` and `%_vec0_%` exist to hide the shadow tables FTS5 and sqlite-vec create beside a virtual table, and unescaped they also hide anything of the shape `my_ftsx_cache`.
|
|
119
|
+
"SELECT name, type FROM sqlite_master WHERE type IN ('table','view') AND name NOT LIKE 'sqlite\\_%' ESCAPE '\\' AND name NOT LIKE '%\\_fts\\_%' ESCAPE '\\' AND name NOT LIKE '%\\_vec0\\_%' ESCAPE '\\' ORDER BY name"
|
|
120
|
+
).all();
|
|
121
|
+
return objects.map((o) => {
|
|
122
|
+
let columnCount;
|
|
123
|
+
try {
|
|
124
|
+
const cols = db.prepare(`PRAGMA table_info(${quoteIdent(o.name)})`).all();
|
|
125
|
+
columnCount = cols.length;
|
|
126
|
+
} catch {
|
|
127
|
+
columnCount = 0;
|
|
128
|
+
}
|
|
129
|
+
let rowCount;
|
|
130
|
+
try {
|
|
131
|
+
const row = db.prepare(`SELECT COUNT(*) AS c FROM ${quoteIdent(o.name)}`).get();
|
|
132
|
+
rowCount = row.c;
|
|
133
|
+
} catch {
|
|
134
|
+
rowCount = null;
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
name: o.name,
|
|
138
|
+
kind: o.type === "view" ? "view" : "table",
|
|
139
|
+
rowCount,
|
|
140
|
+
columnCount
|
|
141
|
+
};
|
|
142
|
+
});
|
|
143
|
+
} finally {
|
|
144
|
+
db.close();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function formatSqliteTables(tables) {
|
|
148
|
+
if (tables.length === 0) return "(no tables or views found)";
|
|
149
|
+
return tables.map((t) => {
|
|
150
|
+
const parts = [t.kind];
|
|
151
|
+
if (t.rowCount !== null) {
|
|
152
|
+
parts.push(`${t.rowCount.toLocaleString()} row${t.rowCount === 1 ? "" : "s"}`);
|
|
153
|
+
}
|
|
154
|
+
parts.push(`${t.columnCount} col${t.columnCount === 1 ? "" : "s"}`);
|
|
155
|
+
return `${displaySafeText(t.name)} (${parts.join(", ")})`;
|
|
156
|
+
}).join("\n");
|
|
157
|
+
}
|
|
158
|
+
var FORBIDDEN_KEYWORDS = [
|
|
159
|
+
"INSERT",
|
|
160
|
+
"UPDATE",
|
|
161
|
+
"DELETE",
|
|
162
|
+
"DROP",
|
|
163
|
+
"ALTER",
|
|
164
|
+
"CREATE",
|
|
165
|
+
"ATTACH",
|
|
166
|
+
"DETACH",
|
|
167
|
+
"TRUNCATE",
|
|
168
|
+
"VACUUM",
|
|
169
|
+
"REINDEX",
|
|
170
|
+
"PRAGMA",
|
|
171
|
+
"BEGIN",
|
|
172
|
+
"COMMIT",
|
|
173
|
+
"ROLLBACK",
|
|
174
|
+
"SAVEPOINT",
|
|
175
|
+
"RELEASE",
|
|
176
|
+
"GRANT",
|
|
177
|
+
"REVOKE"
|
|
178
|
+
];
|
|
179
|
+
function stripSqlLiteralsAndComments(sql) {
|
|
180
|
+
let out = "";
|
|
181
|
+
let i = 0;
|
|
182
|
+
const n = sql.length;
|
|
183
|
+
while (i < n) {
|
|
184
|
+
const c = sql[i];
|
|
185
|
+
if (c === "'" || c === '"' || c === "`") {
|
|
186
|
+
const quote = c;
|
|
187
|
+
out += " ";
|
|
188
|
+
i++;
|
|
189
|
+
while (i < n) {
|
|
190
|
+
if (sql[i] === quote) {
|
|
191
|
+
if (sql[i + 1] === quote) {
|
|
192
|
+
i += 2;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
i++;
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
i++;
|
|
199
|
+
}
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (c === "[") {
|
|
203
|
+
out += " ";
|
|
204
|
+
i++;
|
|
205
|
+
while (i < n && sql[i] !== "]") i++;
|
|
206
|
+
if (i < n) i++;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (c === "-" && sql[i + 1] === "-") {
|
|
210
|
+
while (i < n && sql[i] !== "\n") i++;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (c === "/" && sql[i + 1] === "*") {
|
|
214
|
+
i += 2;
|
|
215
|
+
while (i < n && !(sql[i] === "*" && sql[i + 1] === "/")) i++;
|
|
216
|
+
i += 2;
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
out += c;
|
|
220
|
+
i++;
|
|
221
|
+
}
|
|
222
|
+
return out;
|
|
223
|
+
}
|
|
224
|
+
function validateReadOnlySelect(sql) {
|
|
225
|
+
const stripped = stripSqlLiteralsAndComments(sql);
|
|
226
|
+
const trimmed = stripped.trim();
|
|
227
|
+
if (trimmed === "") {
|
|
228
|
+
throw new Error("empty query");
|
|
229
|
+
}
|
|
230
|
+
const withoutTrailingSemicolons = trimmed.replace(/;+\s*$/, "");
|
|
231
|
+
if (withoutTrailingSemicolons.includes(";")) {
|
|
232
|
+
throw new Error("multiple statements are not allowed (sqlite-query accepts exactly one read-only SELECT statement)");
|
|
233
|
+
}
|
|
234
|
+
const upper = withoutTrailingSemicolons.toUpperCase();
|
|
235
|
+
if (!/^(SELECT|WITH)\b/.test(upper.trimStart())) {
|
|
236
|
+
throw new Error("only SELECT statements are allowed (sqlite-query is read-only)");
|
|
237
|
+
}
|
|
238
|
+
for (const kw of FORBIDDEN_KEYWORDS) {
|
|
239
|
+
if (new RegExp(`\\b${kw}\\b`).test(upper)) {
|
|
240
|
+
throw new Error(`statement contains forbidden keyword '${kw}' (sqlite-query only allows read-only SELECT queries)`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (/\bREPLACE\b(?!\s*\()/.test(upper)) {
|
|
244
|
+
throw new Error("statement contains forbidden keyword 'REPLACE' (sqlite-query only allows read-only SELECT queries)");
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function normalizeSqliteScalar(value) {
|
|
248
|
+
if (typeof value === "bigint") {
|
|
249
|
+
return Number.isSafeInteger(Number(value)) ? Number(value) : value.toString();
|
|
250
|
+
}
|
|
251
|
+
return value;
|
|
252
|
+
}
|
|
253
|
+
function normalizeSqliteRow(row) {
|
|
254
|
+
const out = {};
|
|
255
|
+
for (const [k, v] of Object.entries(row)) out[k] = normalizeSqliteScalar(v);
|
|
256
|
+
return out;
|
|
257
|
+
}
|
|
258
|
+
function runReadOnlySqliteQuery(filePath, sql, opts = {}) {
|
|
259
|
+
validateReadOnlySelect(sql);
|
|
260
|
+
const rowCap = opts.rowCap ?? SQLITE_QUERY_ROW_CAP;
|
|
261
|
+
const db = openReadonlySqlite(filePath);
|
|
262
|
+
try {
|
|
263
|
+
let stmt;
|
|
264
|
+
try {
|
|
265
|
+
stmt = db.prepare(sql);
|
|
266
|
+
} catch (e) {
|
|
267
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
268
|
+
throw new Error(`invalid SQL: ${msg}`, { cause: e });
|
|
269
|
+
}
|
|
270
|
+
if (!stmt.reader) {
|
|
271
|
+
throw new Error("only read-only SELECT statements are allowed (sqlite-query is read-only)");
|
|
272
|
+
}
|
|
273
|
+
stmt.safeIntegers(true);
|
|
274
|
+
let columns = [];
|
|
275
|
+
try {
|
|
276
|
+
columns = stmt.columns().map((c) => c.name);
|
|
277
|
+
} catch {
|
|
278
|
+
columns = [];
|
|
279
|
+
}
|
|
280
|
+
const rows = [];
|
|
281
|
+
let rowCapped = false;
|
|
282
|
+
for (const row of stmt.iterate()) {
|
|
283
|
+
if (rows.length >= rowCap) {
|
|
284
|
+
rowCapped = true;
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
rows.push(normalizeSqliteRow(row));
|
|
288
|
+
}
|
|
289
|
+
return { columns, rows, rowCapped };
|
|
290
|
+
} finally {
|
|
291
|
+
db.close();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function formatSqliteCell(value) {
|
|
295
|
+
if (value === null || value === void 0) return "";
|
|
296
|
+
if (value instanceof Uint8Array) return `<blob ${value.length} bytes>`;
|
|
297
|
+
return String(value);
|
|
298
|
+
}
|
|
299
|
+
function formatSqliteQueryTable(result, opts = {}) {
|
|
300
|
+
if (result.columns.length === 0 && result.rows.length === 0) return "(no rows)";
|
|
301
|
+
const lines = [
|
|
302
|
+
result.columns.map(quoteCsvCellLocal).join(","),
|
|
303
|
+
...result.rows.map((r) => result.columns.map((c) => quoteCsvCellLocal(formatSqliteCell(r[c]))).join(","))
|
|
304
|
+
];
|
|
305
|
+
if (opts.headTruncated === true) {
|
|
306
|
+
lines.push("...(more rows elided; use --head to see more)");
|
|
307
|
+
}
|
|
308
|
+
if (result.rowCapped) {
|
|
309
|
+
lines.push(`...(result truncated at the ${SQLITE_QUERY_ROW_CAP}-row safety cap; narrow the query with WHERE/LIMIT for a complete result)`);
|
|
310
|
+
}
|
|
311
|
+
return lines.join("\n");
|
|
312
|
+
}
|
|
313
|
+
function quoteCsvCellLocal(cell) {
|
|
314
|
+
if (cell.includes(",") || cell.includes('"') || cell.includes("\n") || cell.includes("\r")) {
|
|
315
|
+
return `"${cell.replace(/"/g, '""')}"`;
|
|
316
|
+
}
|
|
317
|
+
return cell;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export {
|
|
321
|
+
SQLITE_QUERY_ROW_CAP,
|
|
322
|
+
isSqliteFile,
|
|
323
|
+
openReadonlySqlite,
|
|
324
|
+
getSqliteSchema,
|
|
325
|
+
formatSqliteSchema,
|
|
326
|
+
getSqliteTables,
|
|
327
|
+
formatSqliteTables,
|
|
328
|
+
validateReadOnlySelect,
|
|
329
|
+
runReadOnlySqliteQuery,
|
|
330
|
+
formatSqliteQueryTable
|
|
331
|
+
};
|
|
@@ -2,12 +2,14 @@ import { createRequire as __cjsRequire } from 'node:module';
|
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
loadConfig
|
|
5
|
-
} from "./token-goat-chunk-
|
|
5
|
+
} from "./token-goat-chunk-H3DXI6VD.mjs";
|
|
6
6
|
import "./token-goat-chunk-EEIDFMEM.mjs";
|
|
7
7
|
import {
|
|
8
|
-
VERSION
|
|
8
|
+
VERSION
|
|
9
|
+
} from "./token-goat-chunk-3H6FQT62.mjs";
|
|
10
|
+
import {
|
|
9
11
|
displaySafeJson
|
|
10
|
-
} from "./token-goat-chunk-
|
|
12
|
+
} from "./token-goat-chunk-ERTXEKB6.mjs";
|
|
11
13
|
import "./token-goat-chunk-GMOUBOX4.mjs";
|
|
12
14
|
import {
|
|
13
15
|
init_define_import_meta_env
|
|
@@ -10,13 +10,13 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
createLazyModuleLoader
|
|
12
12
|
} from "./token-goat-chunk-AH6QILZM.mjs";
|
|
13
|
+
import {
|
|
14
|
+
pushAll
|
|
15
|
+
} from "./token-goat-chunk-3H6FQT62.mjs";
|
|
13
16
|
import {
|
|
14
17
|
DocumentRefusedError,
|
|
15
18
|
MAX_DOCUMENT_WORK_MILLIS
|
|
16
19
|
} from "./token-goat-chunk-Y4AFKTHK.mjs";
|
|
17
|
-
import {
|
|
18
|
-
pushAll
|
|
19
|
-
} from "./token-goat-chunk-AMYCQJX4.mjs";
|
|
20
20
|
import {
|
|
21
21
|
init_define_import_meta_env
|
|
22
22
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
@@ -332,7 +332,27 @@ function pushTextValue(runs, val) {
|
|
|
332
332
|
runs.push(String(val["#text"]));
|
|
333
333
|
}
|
|
334
334
|
}
|
|
335
|
-
|
|
335
|
+
var MATH_PARA_RE = /<m:oMathPara(?:\s[^>]*)?>([\s\S]*?)<\/m:oMathPara>/g;
|
|
336
|
+
var MATH_RE = /<m:oMath(?:\s[^>]*)?>([\s\S]*?)<\/m:oMath>/g;
|
|
337
|
+
var MATH_TEXT_RE = /<m:t(?:\s[^>]*)?>([^<]*)<\/m:t>/g;
|
|
338
|
+
function mathRunText(fragment) {
|
|
339
|
+
let out = "";
|
|
340
|
+
for (const m of fragment.matchAll(MATH_TEXT_RE)) out += m[1];
|
|
341
|
+
return out;
|
|
342
|
+
}
|
|
343
|
+
function inlineMathRuns(xml, openRun, closeRun) {
|
|
344
|
+
const asRun = (text) => text.length > 0 ? `${openRun}${text}${closeRun}` : "";
|
|
345
|
+
const withParas = xml.replace(MATH_PARA_RE, (_whole, inner) => {
|
|
346
|
+
const lines = [];
|
|
347
|
+
for (const m of inner.matchAll(MATH_RE)) {
|
|
348
|
+
const text = mathRunText(m[1]);
|
|
349
|
+
if (text.length > 0) lines.push(text);
|
|
350
|
+
}
|
|
351
|
+
return asRun(lines.length > 0 ? lines.join(" ") : mathRunText(inner));
|
|
352
|
+
});
|
|
353
|
+
return withParas.replace(MATH_RE, (_whole, inner) => asRun(mathRunText(inner)));
|
|
354
|
+
}
|
|
355
|
+
function collectTextRuns(node, tag, skipInside = []) {
|
|
336
356
|
const runs = [];
|
|
337
357
|
function walk(n) {
|
|
338
358
|
if (Array.isArray(n)) {
|
|
@@ -342,6 +362,7 @@ function collectTextRuns(node, tag) {
|
|
|
342
362
|
if (n !== null && typeof n === "object") {
|
|
343
363
|
const obj = n;
|
|
344
364
|
for (const [key, val] of Object.entries(obj)) {
|
|
365
|
+
if (skipInside.includes(key)) continue;
|
|
345
366
|
if (key === tag) {
|
|
346
367
|
pushTextValue(runs, val);
|
|
347
368
|
} else if (val !== null && typeof val === "object") {
|
|
@@ -353,7 +374,23 @@ function collectTextRuns(node, tag) {
|
|
|
353
374
|
walk(node);
|
|
354
375
|
return runs;
|
|
355
376
|
}
|
|
356
|
-
function
|
|
377
|
+
function dropAlternateContentFallbacks(node) {
|
|
378
|
+
if (Array.isArray(node)) {
|
|
379
|
+
node.forEach(dropAlternateContentFallbacks);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
if (node === null || typeof node !== "object") return;
|
|
383
|
+
for (const [key, val] of Object.entries(node)) {
|
|
384
|
+
if (key === "mc:AlternateContent") {
|
|
385
|
+
for (const alt of Array.isArray(val) ? val : [val]) {
|
|
386
|
+
if (alt !== null && typeof alt === "object" && "mc:Choice" in alt && "mc:Fallback" in alt) delete alt["mc:Fallback"];
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
if (val !== null && typeof val === "object") dropAlternateContentFallbacks(val);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
function collectElements(node, tag, opts = {}) {
|
|
393
|
+
const skip = opts.skipInside;
|
|
357
394
|
const out = [];
|
|
358
395
|
function walk(n) {
|
|
359
396
|
if (Array.isArray(n)) {
|
|
@@ -363,9 +400,17 @@ function collectElements(node, tag) {
|
|
|
363
400
|
if (n !== null && typeof n === "object") {
|
|
364
401
|
const obj = n;
|
|
365
402
|
for (const [key, val] of Object.entries(obj)) {
|
|
403
|
+
if (skip !== void 0 && skip.includes(key)) continue;
|
|
366
404
|
if (key === tag) {
|
|
367
|
-
if (
|
|
368
|
-
|
|
405
|
+
if (opts.includeNested !== true) {
|
|
406
|
+
if (Array.isArray(val)) pushAll(out, val);
|
|
407
|
+
else out.push(val);
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
for (const item of Array.isArray(val) ? val : [val]) {
|
|
411
|
+
out.push(item);
|
|
412
|
+
if (item !== null && typeof item === "object") walk(item);
|
|
413
|
+
}
|
|
369
414
|
} else if (val !== null && typeof val === "object") {
|
|
370
415
|
walk(val);
|
|
371
416
|
}
|
|
@@ -375,6 +420,19 @@ function collectElements(node, tag) {
|
|
|
375
420
|
walk(node);
|
|
376
421
|
return out;
|
|
377
422
|
}
|
|
423
|
+
function collectParagraphTexts(node, paragraphTag, runTag, skipInside = [], breakTag) {
|
|
424
|
+
const paragraphs = collectElements(node, paragraphTag, { skipInside });
|
|
425
|
+
if (paragraphs.length === 0) {
|
|
426
|
+
const whole = joinParagraphRuns(node, runTag, skipInside, breakTag);
|
|
427
|
+
return whole.length > 0 ? [whole] : [];
|
|
428
|
+
}
|
|
429
|
+
return paragraphs.map((p) => joinParagraphRuns(p, runTag, skipInside, breakTag));
|
|
430
|
+
}
|
|
431
|
+
function joinParagraphRuns(node, runTag, skipInside, breakTag) {
|
|
432
|
+
const runs = collectTextRuns(node, runTag, skipInside);
|
|
433
|
+
const broken = breakTag !== void 0 && collectElements(node, breakTag, { skipInside }).length > 0;
|
|
434
|
+
return runs.join(broken ? " " : "");
|
|
435
|
+
}
|
|
378
436
|
function sortNumberedParts(paths, pattern) {
|
|
379
437
|
return paths.map((p) => {
|
|
380
438
|
const m = pattern.exec(p);
|
|
@@ -390,7 +448,10 @@ export {
|
|
|
390
448
|
ooxmlPartBudget,
|
|
391
449
|
decodeZipEntry,
|
|
392
450
|
parseOoxmlPart,
|
|
451
|
+
inlineMathRuns,
|
|
393
452
|
collectTextRuns,
|
|
453
|
+
dropAlternateContentFallbacks,
|
|
394
454
|
collectElements,
|
|
455
|
+
collectParagraphTexts,
|
|
395
456
|
sortNumberedParts
|
|
396
457
|
};
|