@attestry/sdk 0.6.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 +190 -0
- package/README.md +1269 -0
- package/dist/client.d.ts +58 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +74 -0
- package/dist/client.js.map +1 -0
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +43 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +41 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/lines-parser.d.ts +50 -0
- package/dist/lines-parser.d.ts.map +1 -0
- package/dist/lines-parser.js +211 -0
- package/dist/lines-parser.js.map +1 -0
- package/dist/ndjson-parser.d.ts +57 -0
- package/dist/ndjson-parser.d.ts.map +1 -0
- package/dist/ndjson-parser.js +245 -0
- package/dist/ndjson-parser.js.map +1 -0
- package/dist/resources/abac-policies.d.ts +1034 -0
- package/dist/resources/abac-policies.d.ts.map +1 -0
- package/dist/resources/abac-policies.js +1519 -0
- package/dist/resources/abac-policies.js.map +1 -0
- package/dist/resources/audit-log.d.ts +588 -0
- package/dist/resources/audit-log.d.ts.map +1 -0
- package/dist/resources/audit-log.js +629 -0
- package/dist/resources/audit-log.js.map +1 -0
- package/dist/resources/batch.d.ts +845 -0
- package/dist/resources/batch.d.ts.map +1 -0
- package/dist/resources/batch.js +1074 -0
- package/dist/resources/batch.js.map +1 -0
- package/dist/resources/chat.d.ts +151 -0
- package/dist/resources/chat.d.ts.map +1 -0
- package/dist/resources/chat.js +124 -0
- package/dist/resources/chat.js.map +1 -0
- package/dist/resources/check.d.ts +348 -0
- package/dist/resources/check.d.ts.map +1 -0
- package/dist/resources/check.js +543 -0
- package/dist/resources/check.js.map +1 -0
- package/dist/resources/compliance-check.d.ts +330 -0
- package/dist/resources/compliance-check.d.ts.map +1 -0
- package/dist/resources/compliance-check.js +402 -0
- package/dist/resources/compliance-check.js.map +1 -0
- package/dist/resources/decisions.d.ts +1208 -0
- package/dist/resources/decisions.d.ts.map +1 -0
- package/dist/resources/decisions.js +1362 -0
- package/dist/resources/decisions.js.map +1 -0
- package/dist/resources/evidence-pack.d.ts +1080 -0
- package/dist/resources/evidence-pack.d.ts.map +1 -0
- package/dist/resources/evidence-pack.js +1789 -0
- package/dist/resources/evidence-pack.js.map +1 -0
- package/dist/resources/gate.d.ts +613 -0
- package/dist/resources/gate.d.ts.map +1 -0
- package/dist/resources/gate.js +737 -0
- package/dist/resources/gate.js.map +1 -0
- package/dist/resources/incidents.d.ts +136 -0
- package/dist/resources/incidents.d.ts.map +1 -0
- package/dist/resources/incidents.js +229 -0
- package/dist/resources/incidents.js.map +1 -0
- package/dist/resources/regulatory-changes.d.ts +307 -0
- package/dist/resources/regulatory-changes.d.ts.map +1 -0
- package/dist/resources/regulatory-changes.js +365 -0
- package/dist/resources/regulatory-changes.js.map +1 -0
- package/dist/resources/safe-input-read.d.ts +21 -0
- package/dist/resources/safe-input-read.d.ts.map +1 -0
- package/dist/resources/safe-input-read.js +57 -0
- package/dist/resources/safe-input-read.js.map +1 -0
- package/dist/resources/ship-gate.d.ts +475 -0
- package/dist/resources/ship-gate.d.ts.map +1 -0
- package/dist/resources/ship-gate.js +727 -0
- package/dist/resources/ship-gate.js.map +1 -0
- package/dist/resources/vision.d.ts +540 -0
- package/dist/resources/vision.d.ts.map +1 -0
- package/dist/resources/vision.js +1036 -0
- package/dist/resources/vision.js.map +1 -0
- package/dist/retry.d.ts +103 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +224 -0
- package/dist/retry.js.map +1 -0
- package/dist/sse-parser.d.ts +64 -0
- package/dist/sse-parser.d.ts.map +1 -0
- package/dist/sse-parser.js +271 -0
- package/dist/sse-parser.js.map +1 -0
- package/dist/transport.d.ts +142 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +455 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +61 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Async generator: reads from a stream of UTF-8-encoded NDJSON bytes
|
|
3
|
+
* and yields each parsed JSON value. Ends when the underlying reader
|
|
4
|
+
* signals `done`. Defensive: a caller that breaks early out of the
|
|
5
|
+
* for-await loop leaves the reader open — call `reader.cancel()` from
|
|
6
|
+
* your finally block (or use `parseNDJSONResponse` below which handles
|
|
7
|
+
* cleanup automatically).
|
|
8
|
+
*
|
|
9
|
+
* Mid-stream read errors are wrapped as
|
|
10
|
+
* `AttestryError("network error during stream: <reason>")` with the
|
|
11
|
+
* original error chained as `cause`. AbortError-shaped rejects (caller
|
|
12
|
+
* cancelled the underlying signal) are wrapped as
|
|
13
|
+
* `AttestryError("request aborted by caller")` for symmetry with the
|
|
14
|
+
* pre-fetch abort surface. The resource layer can rely on these
|
|
15
|
+
* wrappings — `runDecisionsExport`'s catch passes any `AttestryError`
|
|
16
|
+
* through verbatim.
|
|
17
|
+
*
|
|
18
|
+
* @throws AttestryError if a JSON line fails to parse, OR the residual
|
|
19
|
+
* line buffer exceeds `maxLineBytes` (defense against unbounded-
|
|
20
|
+
* line DoS), OR the underlying reader rejects mid-iteration
|
|
21
|
+
* (network drop, abort).
|
|
22
|
+
*/
|
|
23
|
+
export declare function parseNDJSON(reader: ReadableStreamDefaultReader<Uint8Array>, options?: {
|
|
24
|
+
maxLineBytes?: number;
|
|
25
|
+
}): AsyncGenerator<unknown, void, unknown>;
|
|
26
|
+
/**
|
|
27
|
+
* Convenience wrapper around `parseNDJSON` that accepts a `Response`,
|
|
28
|
+
* derives the reader, and ALWAYS calls `reader.cancel()` in a `finally`
|
|
29
|
+
* block — including when a caller breaks out of the for-await loop
|
|
30
|
+
* early. Without this, an early `break` leaks the underlying connection.
|
|
31
|
+
*
|
|
32
|
+
* Resources should call this rather than `parseNDJSON` directly.
|
|
33
|
+
*
|
|
34
|
+
* Symmetric to `parseSSEResponse`.
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseNDJSONResponse(response: Response, options?: {
|
|
37
|
+
maxLineBytes?: number;
|
|
38
|
+
}): AsyncGenerator<unknown, void, unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* Trim a single trailing `\r` (CR). Defensive: NDJSON spec mandates LF
|
|
41
|
+
* only, but a Windows-tooling artifact could leave a CR before the LF.
|
|
42
|
+
* Trimming exactly one CR keeps the parser permissive without treating
|
|
43
|
+
* CR alone as a line separator.
|
|
44
|
+
*/
|
|
45
|
+
declare function stripTrailingCR(s: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Parse one trimmed line as JSON. Throws `AttestryError` (with the
|
|
48
|
+
* underlying error as `cause`) if the payload isn't valid JSON.
|
|
49
|
+
*/
|
|
50
|
+
declare function parseLine(line: string): unknown;
|
|
51
|
+
export declare const __test__: {
|
|
52
|
+
DEFAULT_MAX_LINE_BYTES: number;
|
|
53
|
+
parseLine: typeof parseLine;
|
|
54
|
+
stripTrailingCR: typeof stripTrailingCR;
|
|
55
|
+
};
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=ndjson-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ndjson-parser.d.ts","sourceRoot":"","sources":["../src/ndjson-parser.ts"],"names":[],"mappings":"AAmDA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAuB,WAAW,CAChC,MAAM,EAAE,2BAA2B,CAAC,UAAU,CAAC,EAC/C,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAO,GACtC,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAqGxC;AAED;;;;;;;;;GASG;AACH,wBAAuB,mBAAmB,CACxC,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAO,GACtC,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAmBxC;AAID;;;;;GAKG;AACH,iBAAS,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1C;AAmBD;;;GAGG;AACH,iBAAS,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAcxC;AAGD,eAAO,MAAM,QAAQ;;;;CAIpB,CAAC"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
// ─── NDJSON parser ──────────────────────────────────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// Parses application/x-ndjson (newline-delimited JSON) streams. One JSON
|
|
4
|
+
// value per `\n`-delimited line. Symmetric to `sse-parser.ts` but
|
|
5
|
+
// simpler — no event/id/data headers, no multi-line frame join, no
|
|
6
|
+
// optional retry: hint.
|
|
7
|
+
//
|
|
8
|
+
// Used by streaming endpoints whose payload is a sequence of opaque JSON
|
|
9
|
+
// frames (today: `decisions.export`; future: `audit-log/export`,
|
|
10
|
+
// `bundles/export`). The parser yields raw `unknown` values; the
|
|
11
|
+
// resource-level caller validates frame shape.
|
|
12
|
+
//
|
|
13
|
+
// Spec:
|
|
14
|
+
// https://github.com/ndjson/ndjson-spec
|
|
15
|
+
//
|
|
16
|
+
// Subset implemented:
|
|
17
|
+
// - One JSON value per line, separated by U+000A LINE FEED (`\n`).
|
|
18
|
+
// - UTF-8 decoded with `{stream: true}` so multibyte chars split
|
|
19
|
+
// across reads recombine correctly.
|
|
20
|
+
// - Leading BOM (U+FEFF) stripped once at stream start.
|
|
21
|
+
// - Blank lines silently skipped (lenient — kernel doesn't emit them
|
|
22
|
+
// but defensive parsers should tolerate whitespace).
|
|
23
|
+
// - Final unterminated line (no trailing `\n`) is emitted (lenient —
|
|
24
|
+
// handles HTTP/1.1 connection-close mid-line).
|
|
25
|
+
// - Buffer cap (1 MiB default) on the residual partial-line buffer,
|
|
26
|
+
// defending against an unbounded line attack.
|
|
27
|
+
//
|
|
28
|
+
// Subset deliberately NOT implemented:
|
|
29
|
+
// - `\r` / `\r\n` line endings — strict NDJSON spec mandates `\n`
|
|
30
|
+
// only. The parser trims trailing `\r` defensively before parsing
|
|
31
|
+
// (Windows-tooling artifact) but does NOT treat `\r` alone as a
|
|
32
|
+
// line separator.
|
|
33
|
+
// - Comment lines — ndjson has no comment syntax.
|
|
34
|
+
import { AttestryError } from "./errors.js";
|
|
35
|
+
/**
|
|
36
|
+
* Maximum residual buffer size before the parser bails. Defends against
|
|
37
|
+
* a server / proxy emitting an unbounded line (no `\n` boundary) — the
|
|
38
|
+
* parser would otherwise accumulate until OOM.
|
|
39
|
+
*
|
|
40
|
+
* 1 MiB is generous: the kernel's `decisions.export` per-record line is
|
|
41
|
+
* ~1 KB today (a record with empty jsonb arrays serialises near 500
|
|
42
|
+
* bytes; with claims/invocations populated, ~2 KB). 1 MiB is ~1000×
|
|
43
|
+
* headroom.
|
|
44
|
+
*
|
|
45
|
+
* Configurable via `parseNDJSON`'s `maxLineBytes` option for callers
|
|
46
|
+
* with legitimate large-line use cases (none today).
|
|
47
|
+
*/
|
|
48
|
+
const DEFAULT_MAX_LINE_BYTES = 1024 * 1024;
|
|
49
|
+
/**
|
|
50
|
+
* Async generator: reads from a stream of UTF-8-encoded NDJSON bytes
|
|
51
|
+
* and yields each parsed JSON value. Ends when the underlying reader
|
|
52
|
+
* signals `done`. Defensive: a caller that breaks early out of the
|
|
53
|
+
* for-await loop leaves the reader open — call `reader.cancel()` from
|
|
54
|
+
* your finally block (or use `parseNDJSONResponse` below which handles
|
|
55
|
+
* cleanup automatically).
|
|
56
|
+
*
|
|
57
|
+
* Mid-stream read errors are wrapped as
|
|
58
|
+
* `AttestryError("network error during stream: <reason>")` with the
|
|
59
|
+
* original error chained as `cause`. AbortError-shaped rejects (caller
|
|
60
|
+
* cancelled the underlying signal) are wrapped as
|
|
61
|
+
* `AttestryError("request aborted by caller")` for symmetry with the
|
|
62
|
+
* pre-fetch abort surface. The resource layer can rely on these
|
|
63
|
+
* wrappings — `runDecisionsExport`'s catch passes any `AttestryError`
|
|
64
|
+
* through verbatim.
|
|
65
|
+
*
|
|
66
|
+
* @throws AttestryError if a JSON line fails to parse, OR the residual
|
|
67
|
+
* line buffer exceeds `maxLineBytes` (defense against unbounded-
|
|
68
|
+
* line DoS), OR the underlying reader rejects mid-iteration
|
|
69
|
+
* (network drop, abort).
|
|
70
|
+
*/
|
|
71
|
+
export async function* parseNDJSON(reader, options = {}) {
|
|
72
|
+
const maxLineBytes = options.maxLineBytes ?? DEFAULT_MAX_LINE_BYTES;
|
|
73
|
+
const decoder = new TextDecoder("utf-8");
|
|
74
|
+
let buffer = "";
|
|
75
|
+
let bomStripped = false;
|
|
76
|
+
while (true) {
|
|
77
|
+
let result;
|
|
78
|
+
try {
|
|
79
|
+
result = await reader.read();
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
// Mid-stream reader rejects: TCP RST, proxy hang-up, signal-
|
|
83
|
+
// aborted fetch. Wrap with a clear AttestryError so consumers
|
|
84
|
+
// can branch uniformly via `instanceof AttestryError` rather
|
|
85
|
+
// than having to type-narrow on raw DOMException / TypeError.
|
|
86
|
+
// Resource-layer wrapper passes AttestryError through verbatim.
|
|
87
|
+
if (isAbortErrorShape(err)) {
|
|
88
|
+
throw new AttestryError("request aborted by caller", { cause: err });
|
|
89
|
+
}
|
|
90
|
+
throw new AttestryError(`network error during stream: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
91
|
+
}
|
|
92
|
+
const { value, done } = result;
|
|
93
|
+
if (done) {
|
|
94
|
+
// Flush any final bytes (no-op if value was always complete).
|
|
95
|
+
buffer += decoder.decode();
|
|
96
|
+
// Per NDJSON spec, the final newline is optional — emit any
|
|
97
|
+
// trailing partial line if non-empty after trimming. This handles
|
|
98
|
+
// HTTP/1.1 connection-close mid-line: better to surface the
|
|
99
|
+
// partial frame to the caller (who can then validate its shape)
|
|
100
|
+
// than silently drop it.
|
|
101
|
+
const trimmed = stripTrailingCR(buffer).trim();
|
|
102
|
+
if (trimmed.length > 0)
|
|
103
|
+
yield parseLine(trimmed);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (value === undefined)
|
|
107
|
+
continue;
|
|
108
|
+
// `{stream: true}` carries multi-byte UTF-8 boundaries across chunks.
|
|
109
|
+
buffer += decoder.decode(value, { stream: true });
|
|
110
|
+
// Strip a leading BOM (U+FEFF) if present. Kernel doesn't emit a
|
|
111
|
+
// BOM today, but a misconfigured proxy / charset transcoder could
|
|
112
|
+
// prepend one. Without this strip, the first frame's first char
|
|
113
|
+
// would be `{` and `JSON.parse` would throw with an
|
|
114
|
+
// unhelpful "unexpected character" error. One-shot: only at the
|
|
115
|
+
// very first decoded codepoint of the stream.
|
|
116
|
+
//
|
|
117
|
+
// Hostile-review fix: `bomStripped` is now only flipped once we've
|
|
118
|
+
// actually decoded at least one character. Otherwise an empty /
|
|
119
|
+
// partial-multibyte first read would set the flag prematurely; if
|
|
120
|
+
// the BOM bytes (or a continuation that the decoder treats as
|
|
121
|
+
// mid-stream-data BOM) arrived in a later read, the strip-attempt
|
|
122
|
+
// would be skipped. Defense-in-depth — `String.prototype.trim()`
|
|
123
|
+
// happens to treat U+FEFF as whitespace and the default
|
|
124
|
+
// `TextDecoder("utf-8")` strips a stream-start BOM internally, so
|
|
125
|
+
// the consumer-visible bug is masked today. Pinning the correct
|
|
126
|
+
// shape regardless so a future change (`ignoreBOM: true`, or a
|
|
127
|
+
// line that doesn't run through `.trim()`) doesn't reintroduce it.
|
|
128
|
+
if (!bomStripped && buffer.length > 0) {
|
|
129
|
+
bomStripped = true;
|
|
130
|
+
// Defense-in-depth dead path: in Node 18+ / browsers,
|
|
131
|
+
// `TextDecoder("utf-8")` defaults to `ignoreBOM: false` and
|
|
132
|
+
// strips a stream-start BOM internally — by the time the byte
|
|
133
|
+
// reaches our buffer, the BOM is already gone. The two lines
|
|
134
|
+
// below are reachable only if a future refactor passes
|
|
135
|
+
// `{ignoreBOM: true}` to TextDecoder OR processes the buffer
|
|
136
|
+
// through some path that bypasses TextDecoder's strip. Marked
|
|
137
|
+
// for v8 coverage to make the intentional defense visible.
|
|
138
|
+
/* v8 ignore next 3 */
|
|
139
|
+
if (buffer.charCodeAt(0) === 0xfeff) {
|
|
140
|
+
buffer = buffer.slice(1);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Yield each complete line. We split on `\n` rather than using
|
|
144
|
+
// String.split to keep the indexing explicit (and to make the
|
|
145
|
+
// residual-buffer accounting visible).
|
|
146
|
+
while (true) {
|
|
147
|
+
const newlineIdx = buffer.indexOf("\n");
|
|
148
|
+
if (newlineIdx === -1)
|
|
149
|
+
break;
|
|
150
|
+
const line = buffer.slice(0, newlineIdx);
|
|
151
|
+
buffer = buffer.slice(newlineIdx + 1);
|
|
152
|
+
const trimmed = stripTrailingCR(line).trim();
|
|
153
|
+
if (trimmed.length === 0)
|
|
154
|
+
continue; // blank line — skip silently
|
|
155
|
+
yield parseLine(trimmed);
|
|
156
|
+
}
|
|
157
|
+
// Defense in depth: after consuming all complete lines, the residual
|
|
158
|
+
// buffer holds at most a partial line. If THAT exceeds the cap, the
|
|
159
|
+
// server emitted an unbounded line (or omitted the delimiter) — bail
|
|
160
|
+
// before we OOM. Checking after the yield-loop avoids tripping on a
|
|
161
|
+
// single huge chunk that contains many small complete lines.
|
|
162
|
+
if (buffer.length > maxLineBytes) {
|
|
163
|
+
throw new AttestryError(`NDJSON line exceeded maximum buffer size (${maxLineBytes} bytes) — server emitted an unbounded line or omitted the line delimiter`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Convenience wrapper around `parseNDJSON` that accepts a `Response`,
|
|
169
|
+
* derives the reader, and ALWAYS calls `reader.cancel()` in a `finally`
|
|
170
|
+
* block — including when a caller breaks out of the for-await loop
|
|
171
|
+
* early. Without this, an early `break` leaks the underlying connection.
|
|
172
|
+
*
|
|
173
|
+
* Resources should call this rather than `parseNDJSON` directly.
|
|
174
|
+
*
|
|
175
|
+
* Symmetric to `parseSSEResponse`.
|
|
176
|
+
*/
|
|
177
|
+
export async function* parseNDJSONResponse(response, options = {}) {
|
|
178
|
+
if (response.body === null) {
|
|
179
|
+
// 204 No Content / empty body — iterator ends with zero frames.
|
|
180
|
+
// (Throwing would be over-strict; the server may legitimately close
|
|
181
|
+
// before any data — symmetric to parseSSEResponse.)
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const reader = response.body.getReader();
|
|
185
|
+
try {
|
|
186
|
+
yield* parseNDJSON(reader, options);
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
// Release the lock + signal cancellation upstream. Wrapped in
|
|
190
|
+
// try/catch because cancel() on an already-closed reader rejects.
|
|
191
|
+
try {
|
|
192
|
+
await reader.cancel();
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
// Already canceled / closed — nothing to do.
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// ─── Internals ──────────────────────────────────────────────────────────────
|
|
200
|
+
/**
|
|
201
|
+
* Trim a single trailing `\r` (CR). Defensive: NDJSON spec mandates LF
|
|
202
|
+
* only, but a Windows-tooling artifact could leave a CR before the LF.
|
|
203
|
+
* Trimming exactly one CR keeps the parser permissive without treating
|
|
204
|
+
* CR alone as a line separator.
|
|
205
|
+
*/
|
|
206
|
+
function stripTrailingCR(s) {
|
|
207
|
+
return s.length > 0 && s.charCodeAt(s.length - 1) === 0x0d ? s.slice(0, -1) : s;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* True if `err` is an AbortError-shaped exception (DOMException or
|
|
211
|
+
* Error with `name === "AbortError"`). Both browsers and Node 18+
|
|
212
|
+
* produce this shape when `fetch` / `reader.read()` is aborted via
|
|
213
|
+
* `AbortController.abort()`. Type-narrowing on DOMException alone is
|
|
214
|
+
* too broad (it includes other DOM error types); check by name. Same
|
|
215
|
+
* helper signature as `isAbortError` in `resources/decisions.ts`.
|
|
216
|
+
*/
|
|
217
|
+
function isAbortErrorShape(err) {
|
|
218
|
+
return (err !== null &&
|
|
219
|
+
typeof err === "object" &&
|
|
220
|
+
"name" in err &&
|
|
221
|
+
err.name === "AbortError");
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Parse one trimmed line as JSON. Throws `AttestryError` (with the
|
|
225
|
+
* underlying error as `cause`) if the payload isn't valid JSON.
|
|
226
|
+
*/
|
|
227
|
+
function parseLine(line) {
|
|
228
|
+
try {
|
|
229
|
+
return JSON.parse(line);
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
throw new AttestryError(`NDJSON line was not valid JSON: ${
|
|
233
|
+
// JSON.parse always throws SyntaxError (an Error subclass), so
|
|
234
|
+
// the String(err) branch is unreachable. Defense-in-depth.
|
|
235
|
+
/* v8 ignore next */
|
|
236
|
+
err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Test-only handles for direct pinning of internals.
|
|
240
|
+
export const __test__ = {
|
|
241
|
+
DEFAULT_MAX_LINE_BYTES,
|
|
242
|
+
parseLine,
|
|
243
|
+
stripTrailingCR,
|
|
244
|
+
};
|
|
245
|
+
//# sourceMappingURL=ndjson-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ndjson-parser.js","sourceRoot":"","sources":["../src/ndjson-parser.ts"],"names":[],"mappings":"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"}
|