bantamkit-mcp 0.26.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.
- package/LICENSE +21 -0
- package/README.md +398 -0
- package/assets/contracts/default.yaml +90 -0
- package/assets/evals/devteam/manifest.yaml +351 -0
- package/assets/evals/devteam/repo/HISTORY.md +18 -0
- package/assets/evals/devteam/repo/README.md +12 -0
- package/assets/evals/devteam/repo/docs/architecture.md +17 -0
- package/assets/evals/devteam/repo/docs/runbook.md +10 -0
- package/assets/evals/devteam/repo/issues/142-settlement-timeout.md +23 -0
- package/assets/evals/devteam/repo/patches/0009-retry-budget.patch +38 -0
- package/assets/evals/devteam/repo/src/ledger/__init__.py +3 -0
- package/assets/evals/devteam/repo/src/ledger/config.py +35 -0
- package/assets/evals/devteam/repo/src/ledger/errors.py +13 -0
- package/assets/evals/devteam/repo/src/ledger/posting.py +12 -0
- package/assets/evals/devteam/repo/src/ledger/registry.py +7 -0
- package/assets/evals/devteam/repo/src/ledger/report.py +9 -0
- package/assets/evals/devteam/repo/src/ledger/retry.py +17 -0
- package/assets/evals/devteam/repo/src/ledger/settle.py +16 -0
- package/assets/evals/devteam/repo/src/ledger/validate.py +14 -0
- package/assets/evals/devteam/repo/tests/test_posting.py +13 -0
- package/assets/evals/devteam/repo/tests/test_settle.py +9 -0
- package/assets/evals/devteam/tasks/dt-error-contract.yaml +186 -0
- package/assets/evals/devteam/tasks/dt-handler-map.yaml +183 -0
- package/assets/evals/devteam/tasks/dt-patch-before-after.yaml +182 -0
- package/assets/evals/devteam/tasks/dt-retry-attempts.yaml +181 -0
- package/assets/evals/devteam/tasks/dt-settlement-config.yaml +185 -0
- package/assets/evals/devteam/tasks/dt-symbol-home.yaml +181 -0
- package/assets/evals/devteam/tasks/dt-trace-blame.yaml +182 -0
- package/assets/evals/devteam/tasks/dt-unread-key.yaml +180 -0
- package/assets/evals/document/tasks/doc-large-in-137.yaml +38 -0
- package/assets/evals/document/tasks/doc-large-in-359.yaml +44 -0
- package/assets/evals/document/tasks/doc-large-in-372.yaml +38 -0
- package/assets/evals/document/tasks/doc-large-out-11764.yaml +37 -0
- package/assets/evals/document/tasks/doc-large-out-4137.yaml +37 -0
- package/assets/evals/document/tasks/doc-large-out-8022.yaml +37 -0
- package/assets/evals/document/tasks/doc-small-137.yaml +37 -0
- package/assets/evals/document/tasks/doc-small-261.yaml +37 -0
- package/assets/evals/document/tasks/doc-small-388.yaml +37 -0
- package/assets/evals/fixtures/.gitkeep +0 -0
- package/assets/evals/fixtures/catalog.json +6 -0
- package/assets/evals/perturbations/task-completion.yaml +576 -0
- package/assets/evals/tasks/.gitkeep +0 -0
- package/assets/evals/tasks/extract-contact.yaml +14 -0
- package/assets/evals/tasks/extract-invoice.yaml +14 -0
- package/assets/evals/tasks/extract-order.yaml +15 -0
- package/assets/evals/tasks/extract-schedule.yaml +14 -0
- package/assets/evals/tasks/extract-versions.yaml +17 -0
- package/assets/evals/tasks/nav-prod-port.yaml +84 -0
- package/assets/evals/tasks/nav-release-bundle.yaml +87 -0
- package/assets/evals/tasks/recall-audit-retention.yaml +17 -0
- package/assets/evals/tasks/recall-cache-ttl.yaml +13 -0
- package/assets/evals/tasks/recall-db-port.yaml +17 -0
- package/assets/evals/tasks/recall-deploy.yaml +13 -0
- package/assets/evals/tasks/recall-env-endpoint.yaml +18 -0
- package/assets/evals/tasks/recall-oncall-rotation.yaml +21 -0
- package/assets/evals/tasks/recall-oncall.yaml +13 -0
- package/assets/evals/tasks/recall-org-quota.yaml +18 -0
- package/assets/evals/tasks/recall-owner.yaml +13 -0
- package/assets/evals/tasks/shop-basket-total.yaml +10 -0
- package/assets/evals/tasks/shop-cheapest.yaml +9 -0
- package/assets/evals/tasks/shop-compare.yaml +9 -0
- package/assets/evals/tasks/shop-gadget-value.yaml +9 -0
- package/assets/evals/tasks/shop-stock-total.yaml +9 -0
- package/assets/evals/tasks/shop-total.yaml +9 -0
- package/assets/profiles/default.yaml +31 -0
- package/assets/profiles/patient.yaml +31 -0
- package/assets/rubrics/.gitkeep +0 -0
- package/assets/rubrics/code-quality.yaml +20 -0
- package/assets/rubrics/grounded-completion.yaml +37 -0
- package/assets/rubrics/task-completion.yaml +28 -0
- package/assets/schemas/shiftwork-checkpoint.json +188 -0
- package/assets/skills/.gitkeep +0 -0
- package/assets/skills/file-graph.md +7 -0
- package/assets/skills/memory.md +35 -0
- package/assets/tools/.gitkeep +0 -0
- package/assets/tools/bantamkit_read.json +48 -0
- package/assets/tools/bantamkit_status.json +25 -0
- package/assets/tools/build_identity.json +17 -0
- package/assets/tools/document_list.json +12 -0
- package/assets/tools/document_read.json +31 -0
- package/assets/tools/file_graph.json +12 -0
- package/assets/tools/memory_compact.json +31 -0
- package/assets/tools/memory_recall.json +38 -0
- package/assets/tools/memory_save.json +61 -0
- package/assets/tools/shiftwork_clock_in.json +25 -0
- package/assets/tools/shiftwork_clock_out.json +60 -0
- package/assets/tools/shiftwork_status.json +25 -0
- package/assets/tools/skill_audit.json +70 -0
- package/assets/tools/validate_json.json +31 -0
- package/dist/assets.d.ts +48 -0
- package/dist/assets.js +109 -0
- package/dist/charsets.d.ts +17 -0
- package/dist/charsets.js +580 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.js +280 -0
- package/dist/contract.d.ts +145 -0
- package/dist/contract.js +608 -0
- package/dist/docread.d.ts +357 -0
- package/dist/docread.js +3315 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.js +14 -0
- package/dist/eventlog.d.ts +137 -0
- package/dist/eventlog.js +294 -0
- package/dist/htmlentities.d.ts +2 -0
- package/dist/htmlentities.js +16 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +13 -0
- package/dist/mcp/identity.d.ts +25 -0
- package/dist/mcp/identity.js +275 -0
- package/dist/mcp/pyargs.d.ts +80 -0
- package/dist/mcp/pyargs.js +362 -0
- package/dist/mcp/sdkjson.d.ts +56 -0
- package/dist/mcp/sdkjson.js +91 -0
- package/dist/mcp/server.d.ts +45 -0
- package/dist/mcp/server.js +740 -0
- package/dist/mcp/status.d.ts +210 -0
- package/dist/mcp/status.js +357 -0
- package/dist/mcp/transport.d.ts +68 -0
- package/dist/mcp/transport.js +111 -0
- package/dist/mcpreport.d.ts +214 -0
- package/dist/mcpreport.js +758 -0
- package/dist/memory/cli.d.ts +2 -0
- package/dist/memory/cli.js +396 -0
- package/dist/memory/component.d.ts +256 -0
- package/dist/memory/component.js +497 -0
- package/dist/memory/factfile.d.ts +120 -0
- package/dist/memory/factfile.js +406 -0
- package/dist/memory/layers.d.ts +92 -0
- package/dist/memory/layers.js +410 -0
- package/dist/memory/pyfs.d.ts +521 -0
- package/dist/memory/pyfs.js +1608 -0
- package/dist/memory/pyyaml.d.ts +155 -0
- package/dist/memory/pyyaml.js +868 -0
- package/dist/memory/store.d.ts +478 -0
- package/dist/memory/store.js +1034 -0
- package/dist/pyargparse.d.ts +141 -0
- package/dist/pyargparse.js +813 -0
- package/dist/pyjson.d.ts +110 -0
- package/dist/pyjson.js +524 -0
- package/dist/pyjsonschema.d.ts +50 -0
- package/dist/pyjsonschema.js +951 -0
- package/dist/shiftwork.d.ts +60 -0
- package/dist/shiftwork.js +324 -0
- package/dist/skillaudit.d.ts +172 -0
- package/dist/skillaudit.js +914 -0
- package/dist/statusline.d.ts +106 -0
- package/dist/statusline.js +281 -0
- package/package.json +45 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Node half of `runtime-py/src/bantamkit/docread.py`: deterministic text extraction,
|
|
3
|
+
* addressable by part and row, dispatched on what a file IS.
|
|
4
|
+
*
|
|
5
|
+
* The Python module is the reference and this file COPIES it — its rows, its omission
|
|
6
|
+
* records and its sentences, byte for byte, for the kinds it reads: `text`, `xlsx`,
|
|
7
|
+
* `docx`, `html` and `mhtml`. Every constant, token and sentence below is the Python
|
|
8
|
+
* one; where the reference reads something this half does not (`pdf` through
|
|
9
|
+
* `pdfread`, `doc`/`rtf` through `/usr/bin/textutil`), `sniff` still IDENTIFIES the
|
|
10
|
+
* container so the refusal names it, and `extract` refuses with a sentence that is a
|
|
11
|
+
* DELIBERATE divergence recorded in `docs/porting.md`.
|
|
12
|
+
*
|
|
13
|
+
* No third-party dependency. The reference leans on four standard-library modules that
|
|
14
|
+
* Node does not ship, and each is replaced by the smallest hand-written reader that
|
|
15
|
+
* reproduces the reference's answers on the reference's own fixtures:
|
|
16
|
+
*
|
|
17
|
+
* - `zipfile` -> `ZipReader`: central-directory walk, stored + deflate (`node:zlib`
|
|
18
|
+
* `inflateRawSync`), CRC-32 checked the way `ZipFile.read` checks it.
|
|
19
|
+
* - `xml.etree` -> `parseXml`: a namespace-expanding element tree with `.text`,
|
|
20
|
+
* `iter(tag)`, `find(tag)` and direct-child iteration — the four ET
|
|
21
|
+
* operations `docread.py` actually calls.
|
|
22
|
+
* - `html.parser` + `html.unescape` -> `HtmlText` over a line-for-line port of
|
|
23
|
+
* `HTMLParser.goahead` (CPython 3.12.13, `convert_charrefs=True`), so
|
|
24
|
+
* the DATA CHUNKS arrive in the same pieces — the chunking is visible in
|
|
25
|
+
* the rows because `_HtmlText` joins chunks with a space.
|
|
26
|
+
* - `email` -> `parseMime`: multipart boundaries, header unfolding, Content-Type
|
|
27
|
+
* parameters, quoted-printable (`binascii.a2b_qp`) and base64.
|
|
28
|
+
*
|
|
29
|
+
* Python string semantics that JavaScript does not share are ported explicitly rather
|
|
30
|
+
* than approximated: `str.strip()`/`split()`/`splitlines()` use Python's whitespace and
|
|
31
|
+
* line-boundary sets (`PY_WS`, `pySplitlines`), `repr()` of a `str` and of `bytes` is
|
|
32
|
+
* `pyRepr`/`bytesRepr`, `sorted()` compares by code point (`cmpCodepoint`), and a UTF-8
|
|
33
|
+
* decode error reports the same `start` offset and `reason` CPython's decoder does
|
|
34
|
+
* (`utf8Scan`).
|
|
35
|
+
*/
|
|
36
|
+
import { BantamError } from './errors.js';
|
|
37
|
+
export declare const NS_S = "{http://schemas.openxmlformats.org/spreadsheetml/2006/main}";
|
|
38
|
+
export declare const NS_W = "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}";
|
|
39
|
+
export declare const NS_R = "{http://schemas.openxmlformats.org/officeDocument/2006/relationships}";
|
|
40
|
+
export declare const SUPPORTED: readonly ["text", "xlsx", "docx", "pdf", "html", "mhtml"];
|
|
41
|
+
export declare const TEXTUTIL_SUPPORTED: readonly ["doc", "rtf"];
|
|
42
|
+
export declare const TEXTUTIL = "/usr/bin/textutil";
|
|
43
|
+
export declare const DEFAULT_ROW_LIMIT = 50;
|
|
44
|
+
export declare const PAGE_MAX_ROWS = 200;
|
|
45
|
+
export declare const PAGE_MAX_BYTES = 3072;
|
|
46
|
+
export declare const TEXT_MAX_BYTES: number;
|
|
47
|
+
export declare const OMIT_MEDIA = "media";
|
|
48
|
+
export declare const OMIT_BLANK_ROWS = "blank-rows";
|
|
49
|
+
export declare const OMIT_NUMBER_FORMAT = "number-format";
|
|
50
|
+
export declare const OMIT_UNREAD_PAGE = "unread-page";
|
|
51
|
+
export declare const OMIT_UNMAPPED = "unmapped-text";
|
|
52
|
+
export declare const OMIT_UNREAD_TAIL = "unread-tail";
|
|
53
|
+
export declare const OMIT_SIZE_CAP = "size-cap";
|
|
54
|
+
export declare const OMIT_UNPLACED_CELL = "unplaced-cell";
|
|
55
|
+
/** Extraction failed. The message names what was seen, never just the format's own error. */
|
|
56
|
+
export declare class DocumentReadError extends BantamError {
|
|
57
|
+
}
|
|
58
|
+
/** `str.strip()` with no argument. */
|
|
59
|
+
export declare function pyStrip(s: string): string;
|
|
60
|
+
/** `str.split()` with no argument: runs of whitespace, no empty fields. */
|
|
61
|
+
export declare function pySplit(s: string): string[];
|
|
62
|
+
/** `str.splitlines()`: Python's line boundaries, terminators dropped. */
|
|
63
|
+
export declare function pySplitlines(s: string): string[];
|
|
64
|
+
/** `sorted()` on strings: by code point, which is not what `Array.sort` does above U+FFFF. */
|
|
65
|
+
export declare function cmpCodepoint(a: string, b: string): number;
|
|
66
|
+
/** `repr(str)`. */
|
|
67
|
+
export declare function pyRepr(s: string): string;
|
|
68
|
+
/** `repr(bytes)`. */
|
|
69
|
+
export declare function bytesRepr(buf: Uint8Array): string;
|
|
70
|
+
export interface Utf8Scan {
|
|
71
|
+
/** Bytes `[0, end)` decode cleanly. */
|
|
72
|
+
end: number;
|
|
73
|
+
/** Where the first sequence no continuation could complete begins, or -1. */
|
|
74
|
+
invalidAt: number;
|
|
75
|
+
/** CPython's `UnicodeDecodeError.reason` for that sequence. */
|
|
76
|
+
reason: string;
|
|
77
|
+
/** With `final` false: the bytes past `end` are an incomplete trailing character. */
|
|
78
|
+
incomplete: boolean;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* CPython's UTF-8 decoder, as a validator: the same `start` and `reason` its
|
|
82
|
+
* `UnicodeDecodeError` carries, and the same tolerance an incremental decoder has for a
|
|
83
|
+
* final character the read cut in half when `final` is false.
|
|
84
|
+
*/
|
|
85
|
+
export declare function utf8Scan(buf: Uint8Array, final: boolean): Utf8Scan;
|
|
86
|
+
/**
|
|
87
|
+
* `encodings.normalize_encoding` after `codecs.lookup`'s own lower-casing: runs of anything
|
|
88
|
+
* that is not an ASCII letter, digit or `.` collapse to one `_`, and none leads or trails.
|
|
89
|
+
* `ISO 8859-1`, `ISO--8859--1` and `iso-8859-1;` are all `iso_8859_1`.
|
|
90
|
+
*/
|
|
91
|
+
export declare function pyNormalizeEncoding(encoding: string): string;
|
|
92
|
+
/**
|
|
93
|
+
* `encodings.search_function`: the module `codecs.lookup(name)` would import, or `null`
|
|
94
|
+
* where it raises `LookupError`. The alias table is consulted on the normalized name and on
|
|
95
|
+
* the name with `.` as `_`; the module name itself is the fallback, and a name that is not
|
|
96
|
+
* a module — `cp-437` (`cp_437`), `x-mac-roman`, `latin.1` — is the `LookupError`.
|
|
97
|
+
*/
|
|
98
|
+
export declare function pyCodecModule(name: string): string | null;
|
|
99
|
+
/**
|
|
100
|
+
* `bytes.decode(charset, errors="replace")`, falling back to UTF-8 on `LookupError`
|
|
101
|
+
* (`docread.py`, `_decoded_body`).
|
|
102
|
+
*
|
|
103
|
+
* Until H2 this was `TextDecoder(charset)` with the WHATWG label table, and review round 3
|
|
104
|
+
* measured that table against the codec registry on bytes `80 D0 E9 A4 FF`
|
|
105
|
+
* (`runtime-py/tests/data/docread/charset-table.json`): cp437, mac_roman and iso-8859-16
|
|
106
|
+
* are labels WHATWG does not have; iso-8859-9's 0x80–0x9F are C1 controls to Python and
|
|
107
|
+
* windows-1254's punctuation to WHATWG; Node 25.2.1's ICU decoder maps windows-1252's
|
|
108
|
+
* 0x80 to U+0080 and prints nothing for a trailing 0xFF under latin-1; us-ascii is
|
|
109
|
+
* windows-1252 there. The single-byte codecs are now `charsets.ts`, 256 characters per
|
|
110
|
+
* module written by the registry itself (79 codecs, 20 of them measured over all 256 bytes
|
|
111
|
+
* against the old path: 13 differed); the CJK codecs go through `TextDecoder` with
|
|
112
|
+
* CPython's replacement policy (`decodeMultiByte`, where the residual is quantified); a
|
|
113
|
+
* module this port has no decoder for (`utf_7`, `hz`, `iso2022_kr`, `johab`, the JIS X
|
|
114
|
+
* 0213 variants) decodes as UTF-8, which is the other remaining divergence.
|
|
115
|
+
*
|
|
116
|
+
* AMENDED at review round 4 (H1). This paragraph used to name `iso2022_*` among the modules
|
|
117
|
+
* with no decoder, and for seven of that family the code did something else and worse: the
|
|
118
|
+
* generator had written them a single-byte table, so they were decoded one byte at a time and
|
|
119
|
+
* their escape sequences became U+FFFD. The six `iso2022_jp*` modules now go through ICU's
|
|
120
|
+
* real decoder (`ESCAPE_LABELS`, where the three arms are scored); `hz`, `iso2022_kr` and
|
|
121
|
+
* `utf_7` are what is left of the no-decoder set, and for them this paragraph is now true.
|
|
122
|
+
*/
|
|
123
|
+
export declare function decodeCharset(buf: Uint8Array, charset: string): string;
|
|
124
|
+
export interface OmissionDict {
|
|
125
|
+
subject: string;
|
|
126
|
+
count: number;
|
|
127
|
+
size: number;
|
|
128
|
+
where: string[];
|
|
129
|
+
what: string;
|
|
130
|
+
facts: Record<string, number>;
|
|
131
|
+
}
|
|
132
|
+
/** Something the file holds that the rows do not carry, as a COUNT and the fact behind it. */
|
|
133
|
+
export declare class Omission {
|
|
134
|
+
readonly subject: string;
|
|
135
|
+
readonly count: number;
|
|
136
|
+
readonly size: number;
|
|
137
|
+
readonly where: readonly string[];
|
|
138
|
+
readonly what: string;
|
|
139
|
+
readonly facts: readonly (readonly [string, number])[];
|
|
140
|
+
constructor(subject: string, count: number, size?: number, where?: readonly string[], what?: string, facts?: readonly (readonly [string, number])[]);
|
|
141
|
+
/** The primitive form the contract layer takes, keys in the reference's order. */
|
|
142
|
+
asDict(): OmissionDict;
|
|
143
|
+
}
|
|
144
|
+
/** One addressable unit: a worksheet, or a `.docx` body. `rows` are rendered lines. */
|
|
145
|
+
export declare class Part {
|
|
146
|
+
readonly name: string;
|
|
147
|
+
readonly index: number;
|
|
148
|
+
readonly rows: readonly string[];
|
|
149
|
+
readonly omissions: readonly Omission[];
|
|
150
|
+
constructor(name: string, index: number, rows: readonly string[], omissions?: readonly Omission[]);
|
|
151
|
+
get rowCount(): number;
|
|
152
|
+
/** UTF-8 bytes of this part's full rendering. EXTRACTED size, not file size. */
|
|
153
|
+
get textBytes(): number;
|
|
154
|
+
}
|
|
155
|
+
export declare class Document {
|
|
156
|
+
readonly kind: string;
|
|
157
|
+
readonly parts: readonly Part[];
|
|
158
|
+
readonly omissions: readonly Omission[];
|
|
159
|
+
constructor(kind: string, parts: readonly Part[], omissions?: readonly Omission[]);
|
|
160
|
+
get textBytes(): number;
|
|
161
|
+
/** Resolve by exact sheet name, else by 0-based index. Names win over numeric keys. */
|
|
162
|
+
part(key: string | number): Part;
|
|
163
|
+
}
|
|
164
|
+
/** A row slice of one part. `nextOffset` is null exactly when the part is exhausted. */
|
|
165
|
+
export declare class Page {
|
|
166
|
+
readonly part: string;
|
|
167
|
+
readonly offset: number;
|
|
168
|
+
readonly rows: readonly string[];
|
|
169
|
+
readonly totalRows: number;
|
|
170
|
+
readonly nextOffset: number | null;
|
|
171
|
+
readonly truncatedBytes: number;
|
|
172
|
+
constructor(part: string, offset: number, rows: readonly string[], totalRows: number, nextOffset: number | null, truncatedBytes?: number);
|
|
173
|
+
get text(): string;
|
|
174
|
+
}
|
|
175
|
+
/** The container a file's own bytes declare it to be. `kind` decides; `what` explains. */
|
|
176
|
+
export declare class Container {
|
|
177
|
+
readonly kind: string;
|
|
178
|
+
readonly what: string;
|
|
179
|
+
readonly named: string;
|
|
180
|
+
constructor(kind: string, what: string, named: string);
|
|
181
|
+
/** True when the name promises a container the bytes do not deliver. */
|
|
182
|
+
get suffixLies(): boolean;
|
|
183
|
+
}
|
|
184
|
+
export declare const SUFFIX_KINDS: Readonly<Record<string, string>>;
|
|
185
|
+
export declare const HEAD_BYTES = 4096;
|
|
186
|
+
/** What `path` IS. Magic bytes, then a zip's member list. The suffix is never consulted. */
|
|
187
|
+
export declare function sniff(path: string): Container;
|
|
188
|
+
/** `zipfile.BadZipFile`. Not a `DocumentReadError`: the reference lets it through too. */
|
|
189
|
+
export declare class BadZipFile extends Error {
|
|
190
|
+
constructor(message: string);
|
|
191
|
+
}
|
|
192
|
+
export declare function crc32(buf: Uint8Array): number;
|
|
193
|
+
/** `zipfile.ZipFile` read-only: the central directory, and `read(name)` with a CRC check. */
|
|
194
|
+
export declare class ZipReader {
|
|
195
|
+
private readonly data;
|
|
196
|
+
private readonly entries;
|
|
197
|
+
private readonly concat;
|
|
198
|
+
/** `Path(p).name`, for the one sentence `read` composes itself (the bzip2/lzma ruling). */
|
|
199
|
+
private readonly pathName;
|
|
200
|
+
private readonly byName;
|
|
201
|
+
private constructor();
|
|
202
|
+
static open(path: string): ZipReader;
|
|
203
|
+
static from(data: Buffer, pathName?: string): ZipReader;
|
|
204
|
+
namelist(): string[];
|
|
205
|
+
/** `infolist()` reduced to what `_media_index` reads: name, size, and whether it is a directory. */
|
|
206
|
+
infolist(): {
|
|
207
|
+
filename: string;
|
|
208
|
+
fileSize: number;
|
|
209
|
+
isDir: boolean;
|
|
210
|
+
}[];
|
|
211
|
+
has(name: string): boolean;
|
|
212
|
+
/** `ZipFile.read(name)`; a missing member is a `KeyError` — here `RangeError`, see `readMember`. */
|
|
213
|
+
read(name: string): Buffer;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* The ruled bzip2/lzma refusal, as its own class — review round 4 (M1).
|
|
217
|
+
*
|
|
218
|
+
* It IS a `DocumentReadError` and its sentence is unchanged, so `docs/porting.md`'s ruling
|
|
219
|
+
* and every case that pins the wording still hold. What the subclass buys is that
|
|
220
|
+
* `isUnreadableOptional` can name exactly this refusal: on the reference the same members are
|
|
221
|
+
* a `NotImplementedError`, which `_UNREADABLE_OPTIONAL` catches through `RuntimeError`, so a
|
|
222
|
+
* TOLERANT read swallows it there and must swallow it here. Without the class the only way to
|
|
223
|
+
* recognise it would be `instanceof DocumentReadError`, which would also swallow the
|
|
224
|
+
* encrypted-member and shared-string refusals that the same call can raise.
|
|
225
|
+
*/
|
|
226
|
+
export declare class ZipMethodUnsupported extends DocumentReadError {
|
|
227
|
+
constructor(message: string);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* `ZipFile.read`'s `RuntimeError` family: the member is encrypted (`method` undefined), or
|
|
231
|
+
* (its subclass `NotImplementedError`) compressed by a method zipfile has no decompressor
|
|
232
|
+
* for (`method` is the number). Not a `DocumentReadError` itself, because the reference's
|
|
233
|
+
* `_read` is what words it, and the parts `_rel_targets`/`_date_formats` read swallow it
|
|
234
|
+
* silently instead.
|
|
235
|
+
*/
|
|
236
|
+
export declare class ZipMemberUnreadable extends Error {
|
|
237
|
+
readonly member: string;
|
|
238
|
+
readonly method?: number | undefined;
|
|
239
|
+
constructor(member: string, method?: number | undefined);
|
|
240
|
+
}
|
|
241
|
+
/** `xml.etree.ElementTree.ParseError`. Not a `DocumentReadError`: the reference lets it through. */
|
|
242
|
+
export declare class XmlParseError extends Error {
|
|
243
|
+
constructor(message: string);
|
|
244
|
+
}
|
|
245
|
+
/** An element the way ET exposes one: expanded `{ns}tag`, attributes, `.text`, children. */
|
|
246
|
+
export declare class XmlElement {
|
|
247
|
+
readonly tag: string;
|
|
248
|
+
readonly attrs: Map<string, string>;
|
|
249
|
+
text: string;
|
|
250
|
+
readonly children: XmlElement[];
|
|
251
|
+
constructor(tag: string, attrs: Map<string, string>);
|
|
252
|
+
get(name: string): string | undefined;
|
|
253
|
+
/** `Element.find(tag)`: the first DIRECT child with that tag. */
|
|
254
|
+
find(tag: string): XmlElement | undefined;
|
|
255
|
+
/** `Element.iter(tag)`: this element and every descendant, document order. */
|
|
256
|
+
iter(tag?: string): IterableIterator<XmlElement>;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* A declared encoding expat has no decoder for. `LookupError("unknown encoding: x")` on the
|
|
260
|
+
* reference — NOT an `ET.ParseError`, so `_parse` does not word it and it escapes to the
|
|
261
|
+
* wire as a raised exception; the same class of thing here, deliberately not `XmlParseError`.
|
|
262
|
+
*/
|
|
263
|
+
export declare class XmlEncodingError extends Error {
|
|
264
|
+
constructor(encoding: string);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* A strict-enough XML reader: one root, matched tags, declared prefixes, the five
|
|
268
|
+
* predefined entities and the internal subset's own, comments and PIs dropped, CDATA kept,
|
|
269
|
+
* line ends normalised, and attribute values whitespace-normalised — what expat gives ET
|
|
270
|
+
* for an OOXML part.
|
|
271
|
+
*
|
|
272
|
+
* A declared entity is expanded the way expat expands it: in a text run its replacement
|
|
273
|
+
* text is PARSED in place, so `<!ENTITY e "<x>in</x>y">` yields an element, and a
|
|
274
|
+
* replacement that opens what it does not close is "asynchronous entity"; in an attribute
|
|
275
|
+
* value it is expanded as text and may not contain `<`; a reference to the entity being
|
|
276
|
+
* expanded is "recursive entity reference". Measured against `ET.fromstring` (job43 G2).
|
|
277
|
+
*/
|
|
278
|
+
export declare function parseXml(data: Uint8Array): XmlElement;
|
|
279
|
+
export declare function isDateFormat(code: string): boolean;
|
|
280
|
+
/** 0 -> `A`. */
|
|
281
|
+
export declare function columnLetter(index: number): string;
|
|
282
|
+
/**
|
|
283
|
+
* ECMA-376 gives a worksheet 16,384 columns, the last of them `XFD`. A reference past that
|
|
284
|
+
* does not name a column of any workbook, so this reader will not build a row wide enough to
|
|
285
|
+
* reach one. THE FORMAT'S NUMBER, not a limit invented here, which is why it is spelled as
|
|
286
|
+
* the last column's name rather than as a round figure someone liked.
|
|
287
|
+
*/
|
|
288
|
+
export declare const XLSX_MAX_COLUMNS = 16384;
|
|
289
|
+
/**
|
|
290
|
+
* Why a cell's own reference could not place it. Fixed strings, never the reference itself:
|
|
291
|
+
* `r` is whatever the file says, and an omission that echoed it would carry the file's bytes
|
|
292
|
+
* into the manifest with no bound at all.
|
|
293
|
+
*/
|
|
294
|
+
export declare const UNPLACED_SHAPE = "the column of a cell whose reference is not letters then digits";
|
|
295
|
+
export declare const UNPLACED_RANGE = "the column of a cell past XFD, the last column the format has";
|
|
296
|
+
/**
|
|
297
|
+
* `B7` -> `[1, '']`. The cell's own reference decides its column; XML order is a fallback.
|
|
298
|
+
*
|
|
299
|
+
* A reference is ASCII letters then ASCII digits naming a column the format has, or this
|
|
300
|
+
* reader cannot place it and says WHY. The match is on the reference AS WRITTEN and never on
|
|
301
|
+
* its uppercase (`_column`, review round 3): `r="ß1"` was a `TypeError` on the Python side
|
|
302
|
+
* and column 486 (`SS1`, after `toUpperCase`) here, and a column number that depends on a
|
|
303
|
+
* Unicode case table is not a fact about the workbook.
|
|
304
|
+
*
|
|
305
|
+
* AN ANSWER AND NOT A THROW, which is review round 4 (M2), mirroring `runtime-py` `a1acfa7`.
|
|
306
|
+
* Round 3 spelled the refusal as a `DocumentReadError` out of a function `sheetRows` does not
|
|
307
|
+
* catch, so ONE cell the reader could not place refused the entire workbook — measured on a
|
|
308
|
+
* two-sheet fixture where sheet `Good` is clean and sheet `Bad` holds one cell `r="1"`: no
|
|
309
|
+
* manifest, no parts, the clean sheet unreachable. `r="1"`, `r="A"` and `r="B7 "` all read
|
|
310
|
+
* before round 3. The strictness was right and its price was not: the cell keeps its text and
|
|
311
|
+
* takes its XML position, which is where it sat before round 3 and is the same position on
|
|
312
|
+
* both runtimes, and the column it did not get is disclosed as an `Omission` rather than
|
|
313
|
+
* charged to the whole document. The sentence "cell reference {r!r} is not a column-and-row
|
|
314
|
+
* reference like B7, so this reader cannot place it" NO LONGER EXISTS on either runtime.
|
|
315
|
+
*
|
|
316
|
+
* THE CEILING is review round 4 (M5). Round 3 made this function stricter about the SHAPE of
|
|
317
|
+
* a reference and left the resulting index unbounded: measured on the reference, a 1,755-byte
|
|
318
|
+
* xlsx whose one cell is `r="ZZZZZ1"` produced a 12,356,630-byte row, 7,041x the file. Row
|
|
319
|
+
* width is now bounded by the format at `XLSX_MAX_COLUMNS` fields however many bytes the file
|
|
320
|
+
* spends asking for more.
|
|
321
|
+
*/
|
|
322
|
+
export declare function columnIndex(ref: string | undefined, fallback: number): [number, string];
|
|
323
|
+
export declare function extractXlsx(path: string): Document;
|
|
324
|
+
export declare function extractDocx(path: string): Document;
|
|
325
|
+
/** `html.unescape`. */
|
|
326
|
+
export declare function unescape(s: string): string;
|
|
327
|
+
/** Rendered rows of one HTML fragment. A pure function of the string: no I/O, no host. */
|
|
328
|
+
export declare function htmlRows(markup: string): string[];
|
|
329
|
+
/** `binascii.a2b_qp(data, header=False)`, i.e. `quopri.decodestring`. */
|
|
330
|
+
export declare function decodeQuotedPrintable(data: Uint8Array): Buffer;
|
|
331
|
+
/**
|
|
332
|
+
* `binascii.a2b_uu(line)`: one uuencoded line to its bytes, in the C module's own steps.
|
|
333
|
+
*
|
|
334
|
+
* The first character is the byte count; each following character carries six bits, a line
|
|
335
|
+
* end or a line that ran out counts as zero ("some spaces got eaten at end-of-line"); a
|
|
336
|
+
* character outside `' '..'\x60'` is "Illegal char"; and whatever is left after the count
|
|
337
|
+
* is satisfied must be space, backtick or a line end, or it is "Trailing garbage".
|
|
338
|
+
*/
|
|
339
|
+
export declare function a2bUu(line: Uint8Array): Buffer;
|
|
340
|
+
/**
|
|
341
|
+
* `email.message._decode_uu`: the lines between `begin <octal mode> ...` and `end`, or
|
|
342
|
+
* `ValueError` — which `get_payload` answers with the payload UNDECODED.
|
|
343
|
+
*
|
|
344
|
+
* `begin` must start the line and its mode must parse in base 8; a blank line before `end`
|
|
345
|
+
* is "Truncated input"; `end` is recognised stripped of ` \t\r\n\f`; and a line
|
|
346
|
+
* `a2b_uu` rejects is retried cut to the length its count character implies (the workaround
|
|
347
|
+
* for broken encoders that the stdlib carries by name). Measured against the reference
|
|
348
|
+
* (job43 G2) on seventeen payload shapes, including the Truncated and no-`begin` ones.
|
|
349
|
+
*/
|
|
350
|
+
export declare function decodeUu(encoded: Buffer): Buffer;
|
|
351
|
+
export declare function extractMhtml(path: string): Document;
|
|
352
|
+
export declare function extractHtml(path: string): Document;
|
|
353
|
+
export declare function extractText(path: string): Document;
|
|
354
|
+
/** Dispatch on what the file IS. Anything unreadable raises, naming the container. */
|
|
355
|
+
export declare function extract(path: string): Document;
|
|
356
|
+
/** Slice `limit` rows from `part` starting at `offset`, optionally under a byte ceiling. */
|
|
357
|
+
export declare function page(doc: Document, part?: string | number, offset?: number, limit?: number, maxBytes?: number | null): Page;
|