@wavehouse/chtypes 0.1.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.
Files changed (72) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/LICENSE +202 -0
  3. package/README.md +442 -0
  4. package/dist/cli.d.ts +43 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +303 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/discover.d.ts +134 -0
  9. package/dist/discover.d.ts.map +1 -0
  10. package/dist/discover.js +291 -0
  11. package/dist/discover.js.map +1 -0
  12. package/dist/errors.d.ts +204 -0
  13. package/dist/errors.d.ts.map +1 -0
  14. package/dist/errors.js +228 -0
  15. package/dist/errors.js.map +1 -0
  16. package/dist/fetch.d.ts +235 -0
  17. package/dist/fetch.d.ts.map +1 -0
  18. package/dist/fetch.js +842 -0
  19. package/dist/fetch.js.map +1 -0
  20. package/dist/ffi.d.ts +346 -0
  21. package/dist/ffi.d.ts.map +1 -0
  22. package/dist/ffi.js +913 -0
  23. package/dist/ffi.js.map +1 -0
  24. package/dist/format.d.ts +104 -0
  25. package/dist/format.d.ts.map +1 -0
  26. package/dist/format.js +108 -0
  27. package/dist/format.js.map +1 -0
  28. package/dist/index.d.ts +28 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +28 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/json.d.ts +127 -0
  33. package/dist/json.d.ts.map +1 -0
  34. package/dist/json.js +577 -0
  35. package/dist/json.js.map +1 -0
  36. package/dist/library.d.ts +225 -0
  37. package/dist/library.d.ts.map +1 -0
  38. package/dist/library.js +234 -0
  39. package/dist/library.js.map +1 -0
  40. package/dist/numeric.d.ts +20 -0
  41. package/dist/numeric.d.ts.map +1 -0
  42. package/dist/numeric.js +107 -0
  43. package/dist/numeric.js.map +1 -0
  44. package/dist/paths.d.ts +47 -0
  45. package/dist/paths.d.ts.map +1 -0
  46. package/dist/paths.js +78 -0
  47. package/dist/paths.js.map +1 -0
  48. package/dist/registry.d.ts +204 -0
  49. package/dist/registry.d.ts.map +1 -0
  50. package/dist/registry.js +409 -0
  51. package/dist/registry.js.map +1 -0
  52. package/dist/results.d.ts +326 -0
  53. package/dist/results.d.ts.map +1 -0
  54. package/dist/results.js +235 -0
  55. package/dist/results.js.map +1 -0
  56. package/dist/schema.d.ts +444 -0
  57. package/dist/schema.d.ts.map +1 -0
  58. package/dist/schema.js +448 -0
  59. package/dist/schema.js.map +1 -0
  60. package/dist/settings.d.ts +43 -0
  61. package/dist/settings.d.ts.map +1 -0
  62. package/dist/settings.js +33 -0
  63. package/dist/settings.js.map +1 -0
  64. package/dist/tar.d.ts +32 -0
  65. package/dist/tar.d.ts.map +1 -0
  66. package/dist/tar.js +310 -0
  67. package/dist/tar.js.map +1 -0
  68. package/dist/transform.d.ts +73 -0
  69. package/dist/transform.d.ts.map +1 -0
  70. package/dist/transform.js +527 -0
  71. package/dist/transform.js.map +1 -0
  72. package/package.json +62 -0
@@ -0,0 +1,291 @@
1
+ /**
2
+ * The discovery kit.
3
+ *
4
+ * This library NEVER talks to ClickHouse; it ships the queries. At connect
5
+ * time a caller (a gateway, WaveHouse) runs these three queries against the
6
+ * deployment's own server with whatever client it already has, feeds the
7
+ * results to the typed parsers below, and then declares what it learned:
8
+ *
9
+ * profile.version -> Registry#for / the artifact to load
10
+ * profile.settings -> compileDdl({ settings }) (compile-time) and per-call settings
11
+ * columns -> reconstructDdl -> compileDdl
12
+ *
13
+ * The pattern, in full (spec/bindings.md §Discovery):
14
+ *
15
+ * 1. run QUERY_SERVER_VERSION, QUERY_CHANGED_SETTINGS once per connection
16
+ * 2. cache the ServerProfile per deployment/tenant
17
+ * 3. const lib = registry.for(profile.version)
18
+ * 4. const schema = lib.compileDdl(ddl, { settings: profile.settings, mode: 0 })
19
+ * 5. per call: pass profile.settings (plus any per-INSERT overrides) to rows()
20
+ *
21
+ * Never ask the customer for their settings — ask their server. The queries
22
+ * return exactly what the server believes, spelled the way the server spells
23
+ * it, which is what the settings gate (spec/c-abi.md, Settings rule 2)
24
+ * validates against.
25
+ *
26
+ * The parsers read JSONEachRow bytes through this package's own byte-exact
27
+ * JSON reader, so a numeric field (`position`) is taken from its literal
28
+ * digits — quoted or bare, ClickHouse's stock HTTP output quotes 64-bit
29
+ * integers — and never routed through a float.
30
+ */
31
+ import { ChtypesError } from './errors.js';
32
+ import { asString, parseJsonValue, rawText } from './json.js';
33
+ // The canonical discovery queries. Each carries its FORMAT clause so the
34
+ // bytes an HTTP client gets back are exactly what the matching parse*
35
+ // function consumes. A native-protocol client that returns typed rows
36
+ // instead can ignore the parsers and fill the structs directly.
37
+ /**
38
+ * Names the deployment's exact release — the string `Registry#for` resolves
39
+ * (minor line or exact patch both work). One row: `{"version":"25.8.28.1"}`.
40
+ */
41
+ export const QUERY_SERVER_VERSION = 'SELECT version() AS version FORMAT JSONEachRow';
42
+ /**
43
+ * Lists every query setting the deployment runs at a NON-default value — the
44
+ * whole declared profile, from the server itself. One row per setting:
45
+ * `{"name":"flatten_nested","value":"0"}`. `system.settings.value` is already
46
+ * a String; the map feeds `compileDdl({ settings })` and per-call settings
47
+ * verbatim.
48
+ */
49
+ export const QUERY_CHANGED_SETTINGS = 'SELECT name, value FROM system.settings WHERE changed FORMAT JSONEachRow';
50
+ /**
51
+ * Describes one existing table, in declaration order, with everything a
52
+ * column-declaration list needs — INCLUDING `default_kind` and
53
+ * `default_expression`, without which a reconstructed schema silently loses
54
+ * its DEFAULT/MATERIALIZED semantics. Uses ClickHouse's own query parameters:
55
+ * send `param_db` / `param_table` (HTTP) or bind `{db}`/`{table}` (native).
56
+ */
57
+ export const QUERY_TABLE_COLUMNS = 'SELECT name, type, default_kind, default_expression, position ' +
58
+ 'FROM system.columns WHERE database = {db:String} AND table = {table:String} ' +
59
+ 'ORDER BY position FORMAT JSONEachRow';
60
+ const asBuffer = (body) => typeof body === 'string'
61
+ ? Buffer.from(body, 'utf8')
62
+ : Buffer.isBuffer(body)
63
+ ? body
64
+ : Buffer.from(body.buffer, body.byteOffset, body.byteLength);
65
+ /** Split a JSONEachRow body into one parsed object per line. */
66
+ function jsonEachRowDocs(body) {
67
+ const out = [];
68
+ for (const line of splitLines(asBuffer(body))) {
69
+ if (line[0] !== 0x7b /* { */) {
70
+ throw new ChtypesError(`chtypes: not a JSONEachRow line: ${line.toString('utf8').slice(0, 60)}`);
71
+ }
72
+ const doc = parseJsonValue(line);
73
+ if (doc === null || doc.kind !== 'object') {
74
+ throw new ChtypesError(`chtypes: not a JSONEachRow line: ${line.toString('utf8').slice(0, 60)}`);
75
+ }
76
+ out.push(doc);
77
+ }
78
+ return out;
79
+ }
80
+ function splitLines(body) {
81
+ const out = [];
82
+ let start = 0;
83
+ for (let i = 0; i <= body.length; i++) {
84
+ if (i === body.length || body[i] === 0x0a) {
85
+ const line = trimSpace(body.subarray(start, i));
86
+ if (line.length > 0)
87
+ out.push(line);
88
+ start = i + 1;
89
+ }
90
+ }
91
+ return out;
92
+ }
93
+ /** ASCII whitespace trim over bytes, so no decode happens before the parse. */
94
+ function trimSpace(line) {
95
+ let a = 0;
96
+ let b = line.length;
97
+ const ws = (c) => c === 0x20 || c === 0x09 || c === 0x0a || c === 0x0d;
98
+ while (a < b && ws(line[a]))
99
+ a++;
100
+ while (b > a && ws(line[b - 1]))
101
+ b--;
102
+ return line.subarray(a, b);
103
+ }
104
+ /** A field of a discovery row, by key — the reference's `row[k]`, last wins. */
105
+ function member(doc, key) {
106
+ let found;
107
+ for (let i = 0; i < doc.keys.length; i++) {
108
+ if (doc.keys[i].toString('utf8') === key)
109
+ found = doc.items[i];
110
+ }
111
+ return found;
112
+ }
113
+ /**
114
+ * A field's value that may arrive quoted or bare (ClickHouse quotes 64-bit
115
+ * integers in JSON output by default), digits preserved exactly — never
116
+ * through a float. Mirrors the reference's `jsonString`.
117
+ */
118
+ function jsonString(value) {
119
+ if (value === undefined)
120
+ return '';
121
+ // A parsed value's raw slice carries no surrounding whitespace, so the
122
+ // reference's TrimSpace has nothing to do here — and JS's own `trim()` is
123
+ // deliberately avoided in this package (its WhiteSpace set includes U+FEFF).
124
+ return value.kind === 'string' ? asString(value) : rawText(value);
125
+ }
126
+ /**
127
+ * Read `QUERY_SERVER_VERSION`'s JSONEachRow body.
128
+ *
129
+ * @param body - the query result bytes (or text) as the server sent them.
130
+ * @returns the version string, e.g. `"25.8.28.1"` — feed `Registry#for`.
131
+ * @throws {ChtypesError} when the body is not exactly one JSONEachRow row with
132
+ * a non-empty `version` field.
133
+ */
134
+ export function parseVersionResult(body) {
135
+ const docs = jsonEachRowDocs(body);
136
+ if (docs.length !== 1) {
137
+ throw new ChtypesError(`chtypes: version query returned ${docs.length} rows, want 1`);
138
+ }
139
+ const v = member(docs[0], 'version');
140
+ if (v === undefined) {
141
+ throw new ChtypesError('chtypes: version query row has no `version` field');
142
+ }
143
+ const out = jsonString(v);
144
+ if (out === '') {
145
+ throw new ChtypesError('chtypes: version query returned an empty version');
146
+ }
147
+ return out;
148
+ }
149
+ /**
150
+ * Read `QUERY_CHANGED_SETTINGS`' JSONEachRow body. An empty body is a stock
151
+ * server: an empty map, not an error.
152
+ *
153
+ * @param body - the query result bytes (or text) as the server sent them.
154
+ * @returns setting name → value, ready for `ServerProfile#settings`,
155
+ * `compileDdl({ settings })` and per-call settings.
156
+ * @throws {ChtypesError} when a row is not JSONEachRow or lacks `name`/`value`.
157
+ */
158
+ export function parseChangedSettingsResult(body) {
159
+ const out = {};
160
+ for (const doc of jsonEachRowDocs(body)) {
161
+ const name = member(doc, 'name');
162
+ if (name === undefined) {
163
+ throw new ChtypesError(`chtypes: settings row has no \`name\` field: ${rawText(doc).slice(0, 60)}`);
164
+ }
165
+ const value = member(doc, 'value');
166
+ if (value === undefined) {
167
+ throw new ChtypesError(`chtypes: settings row has no \`value\` field: ${rawText(doc).slice(0, 60)}`);
168
+ }
169
+ out[jsonString(name)] = jsonString(value);
170
+ }
171
+ return out;
172
+ }
173
+ /**
174
+ * Read `QUERY_TABLE_COLUMNS`' JSONEachRow body, in the query's ORDER BY
175
+ * position order. `position` survives both spellings — quoted on stock HTTP
176
+ * output (`output_format_json_quote_64bit_integers=1`) and bare when a client
177
+ * unsets that — parsed from its literal digits, never through `JSON.parse`'s
178
+ * double. A position is small, so it fits a JS number once those digits are
179
+ * in hand; a malformed one is left 0, as the reference leaves it.
180
+ *
181
+ * @param body - the query result bytes (or text) as the server sent them.
182
+ * @returns one `DiscoveredColumn` per row, in the query's position order —
183
+ * feed `reconstructDdl`.
184
+ * @throws {ChtypesError} when a row is malformed, lacks `name`/`type`, or the
185
+ * body holds no rows at all (wrong database/table, or no access).
186
+ */
187
+ export function parseColumnsResult(body) {
188
+ const out = [];
189
+ for (const doc of jsonEachRowDocs(body)) {
190
+ const name = jsonString(member(doc, 'name'));
191
+ const type = jsonString(member(doc, 'type'));
192
+ if (name === '' || type === '') {
193
+ throw new ChtypesError(`chtypes: columns row missing name/type: ${rawText(doc).slice(0, 80)}`);
194
+ }
195
+ let position = 0;
196
+ const raw = member(doc, 'position');
197
+ if (raw !== undefined) {
198
+ const digits = jsonString(raw);
199
+ const n = Number(digits);
200
+ if (/^\d+$/.test(digits) && Number.isSafeInteger(n))
201
+ position = n;
202
+ }
203
+ out.push({
204
+ name,
205
+ type,
206
+ defaultKind: jsonString(member(doc, 'default_kind')),
207
+ defaultExpression: jsonString(member(doc, 'default_expression')),
208
+ position,
209
+ });
210
+ }
211
+ if (out.length === 0) {
212
+ throw new ChtypesError('chtypes: columns query returned no rows — wrong database/table, or no access');
213
+ }
214
+ return out;
215
+ }
216
+ /**
217
+ * Quote an identifier the way ClickHouse DDL requires: plain
218
+ * `[A-Za-z_][A-Za-z0-9_]*` stays bare, anything else is backticked with
219
+ * backticks doubled. `system.columns` can return anything — the flattened
220
+ * Nested idiom (`n.a`), spaces, keywords.
221
+ */
222
+ function backquoteIfNeeded(name) {
223
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
224
+ return name;
225
+ return '`' + name.replaceAll('`', '``') + '`';
226
+ }
227
+ /**
228
+ * Turn `QUERY_TABLE_COLUMNS`' rows back into the column-declaration list
229
+ * `compileDdl` takes. It is a spelling exercise, not a semantic one: types
230
+ * and expressions are the server's own text, passed through verbatim, and the
231
+ * library's own compile is the judge of the result.
232
+ *
233
+ * Two facts a caller must know, both properties of the server rather than of
234
+ * this function:
235
+ *
236
+ * - `system.columns` reports the table AS STORED. Under the default
237
+ * `flatten_nested=1` a `Nested(a,b)` column appears as its flattened
238
+ * `n.a`/`n.b` Array columns and reconstructs to exactly those — which is
239
+ * the same table. Under `flatten_nested=0` it appears as one column of
240
+ * type `Nested(...)`, which also reconstructs directly. Reconstruction is
241
+ * therefore shape-faithful either way, PROVIDED the same `flatten_nested`
242
+ * value is declared to `compileDdl({ settings })` that the table was
243
+ * created under — which is what the discovered `ServerProfile.settings`
244
+ * carries.
245
+ * - a MATERIALIZED/ALIAS column reconstructs with its expression; an
246
+ * EPHEMERAL column may legitimately have an empty `default_expression`.
247
+ *
248
+ * @param cols - the discovered columns, e.g. from `parseColumnsResult`.
249
+ * @returns the column-declaration list for `Library#compileDdl`.
250
+ * @throws {ChtypesError} when a column is inconsistent: no name/type, a
251
+ * `default_expression` with no kind, a DEFAULT/MATERIALIZED/ALIAS kind with
252
+ * no expression, an unknown kind, or no columns at all.
253
+ */
254
+ export function reconstructDdl(cols) {
255
+ if (cols.length === 0) {
256
+ throw new ChtypesError('chtypes: no columns to reconstruct');
257
+ }
258
+ const parts = [];
259
+ for (let i = 0; i < cols.length; i++) {
260
+ const c = cols[i];
261
+ if (c.name === '' || c.type === '') {
262
+ throw new ChtypesError(`chtypes: column ${i} has no name/type`);
263
+ }
264
+ let decl = `${backquoteIfNeeded(c.name)} ${c.type}`;
265
+ switch (c.defaultKind) {
266
+ case '':
267
+ if (c.defaultExpression !== '') {
268
+ throw new ChtypesError(`chtypes: column ${c.name} has a default_expression but no default_kind`);
269
+ }
270
+ break;
271
+ case 'DEFAULT':
272
+ case 'MATERIALIZED':
273
+ case 'ALIAS':
274
+ if (c.defaultExpression === '') {
275
+ throw new ChtypesError(`chtypes: column ${c.name} is ${c.defaultKind} but has no default_expression`);
276
+ }
277
+ decl += ` ${c.defaultKind} ${c.defaultExpression}`;
278
+ break;
279
+ case 'EPHEMERAL':
280
+ decl += ' EPHEMERAL';
281
+ if (c.defaultExpression !== '')
282
+ decl += ` ${c.defaultExpression}`;
283
+ break;
284
+ default:
285
+ throw new ChtypesError(`chtypes: column ${c.name} has unknown default_kind ${JSON.stringify(c.defaultKind)}`);
286
+ }
287
+ parts.push(decl);
288
+ }
289
+ return parts.join(', ');
290
+ }
291
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * The error model, which is three outcomes that must never be conflated
3
+ * (spec/c-abi.md §Error model):
4
+ *
5
+ * - ClickHouse rejects -> a real ClickHouse error code
6
+ * - this build refuses -> CODE_UNSUPPORTED (-2), never a ClickHouse code
7
+ * - ClickHouse accepts but the value cannot be read back -> code 691, and it
8
+ * is an ACCEPTED insert, surfaced through the row outcome rather than here.
9
+ *
10
+ * Mapping `unsupported` onto a rejection manufactures an over-reject the product
11
+ * never made; mapping it onto an acceptance manufactures an over-accept, which
12
+ * is the cardinal sin. So it gets its own sentinel on the wire and, since
13
+ * 2026-08-26, its own ERROR CLASS here — `UnsupportedError`, a peer of
14
+ * `SchemaError` rather than a subclass, so that a `catch` which handles only
15
+ * `SchemaError` cannot silently swallow a decline as a rejection.
16
+ */
17
+ /** "This build refuses to answer." Never a real ClickHouse error code. */
18
+ export declare const CODE_UNSUPPORTED = -2;
19
+ /**
20
+ * The chs_* ABI revision this binding was written against — `CHS_ABI_REVISION`
21
+ * in `include/chtypes.h`.
22
+ *
23
+ * This package dlopens artifacts rather than compiling against the header, so
24
+ * this is a hand-kept mirror and MUST be bumped in the same cycle the header
25
+ * is. A `Registry` refuses an artifact reporting a different nonzero revision;
26
+ * 0 means the artifact predates the probe, which is ignorance rather than
27
+ * incompatibility (spec/artifact.md §Loading).
28
+ *
29
+ * Revision 3 (2026-08-31): `chs_rows` gained `export_format` / `doc_flags` /
30
+ * `out_bytes`, and the `chs_filter_compile` / `chs_filter_free` /
31
+ * `chs_filter_rows` trio joined the surface.
32
+ *
33
+ * Revision 4 (2026-08-31, the filter phase-2 cycle): `chs_filter_compile`
34
+ * gained `params_json` (`{name:Type}` query parameters), and the block twin
35
+ * joined — `chs_block_parse` / `chs_block_free` / `chs_filter_eval`. This
36
+ * binding therefore speaks 4 and refuses revision-3 artifacts — calling the
37
+ * 5-argument `chs_filter_compile` through the 4-argument revision-3 artifact
38
+ * is undefined behaviour, which is exactly what the gate exists to prevent.
39
+ */
40
+ export declare const ABI_REVISION = 4;
41
+ /** Base class for everything this package throws. */
42
+ export declare class ChtypesError extends Error {
43
+ constructor(message: string, options?: {
44
+ cause?: unknown;
45
+ });
46
+ }
47
+ /** A registry could not be loaded, or a version could not be resolved. */
48
+ export declare class RegistryError extends ChtypesError {
49
+ }
50
+ /**
51
+ * A REFUSAL: ClickHouse itself refused a type, a column list, an engine or a
52
+ * TTL.
53
+ *
54
+ * `code` is ALWAYS a real ClickHouse error code. "This build declines to
55
+ * answer" is a DIFFERENT CLASS — `UnsupportedError` — never this one carrying
56
+ * a sentinel, so no `SchemaError` ever holds `CODE_UNSUPPORTED`
57
+ * (spec/bindings.md rule 12).
58
+ */
59
+ export declare class SchemaError extends ChtypesError {
60
+ readonly code: number;
61
+ readonly detail: string;
62
+ readonly column: string | undefined;
63
+ constructor(code: number, detail: string, column?: string);
64
+ }
65
+ /**
66
+ * A DECLINE: "a real server might well have accepted this; I will not guess."
67
+ * Never ClickHouse rejecting anything, so it carries no `code` property at all
68
+ * — there is no code to carry.
69
+ *
70
+ * It is a PEER of `SchemaError`, deliberately NOT a subclass and deliberately
71
+ * NOT matched by `err instanceof SchemaError`. A decline that still satisfied
72
+ * "is a SchemaError" would be the sentinel problem wearing a class hierarchy:
73
+ * every `catch` that forgot the predicate would keep silently turning declines
74
+ * into rejections, which is a manufactured over-reject — data loss the product
75
+ * never made, budgeted at zero. As a peer, forgetting throws on past the
76
+ * handler, which is loud.
77
+ *
78
+ * ```ts
79
+ * try {
80
+ * schema.setEngine(engine, orderBy);
81
+ * } catch (err) {
82
+ * // validate cautiously; do NOT blame the tenant
83
+ * if (err instanceof UnsupportedError) return degradeToCarefulPath(err);
84
+ * // ClickHouse refused: err.code is its own code
85
+ * if (err instanceof SchemaError) return rejectWith(err.code, err.detail);
86
+ * throw err;
87
+ * }
88
+ * ```
89
+ *
90
+ * The MESSAGE still renders the ABI's `CODE_UNSUPPORTED` sentinel in the shape
91
+ * `SchemaError` renders its code. The sentinel is not a property of this class
92
+ * — it is the wire value the C ABI returned — but the rendering is frozen: the
93
+ * conformance driver puts this exact string on the protocol wire as an
94
+ * `unsupported` scope, and Python's `UnsupportedError` already spells it this
95
+ * way. Changing the text would move rig records without changing a verdict.
96
+ */
97
+ export declare class UnsupportedError extends ChtypesError {
98
+ readonly detail: string;
99
+ readonly column: string | undefined;
100
+ constructor(detail: string, column?: string);
101
+ }
102
+ /**
103
+ * The ONE place an ABI error code becomes an error object, so the
104
+ * refusal/decline split cannot be decided differently in two files.
105
+ *
106
+ * The SIGN decides (spec/bindings.md rule 12, spec/c-abi.md §Error model): a
107
+ * positive code is the server's own refusal and rides through verbatim; any
108
+ * negative code is this library declining (`-2` "I will not guess", `-1` a
109
+ * guarded exception, and a binding's own missing-symbol sentinel) and becomes
110
+ * an `UnsupportedError`. Keying on the sign rather than on `=== CODE_UNSUPPORTED`
111
+ * means a negative sentinel a later era adds can never become "a SchemaError
112
+ * with a negative code", which the class's own contract forbids.
113
+ *
114
+ * Internal: not re-exported from the package index.
115
+ */
116
+ export declare function schemaErrorFor(code: number, detail: string, column?: string): SchemaError | UnsupportedError;
117
+ /** The codes docs/fetch.md §7 shares across every SDK. */
118
+ export type ArtifactErrorCode = 'CHTYPES_ARTIFACT_MISSING' | 'CHTYPES_ARTIFACT_UNTRUSTED' | 'CHTYPES_ARTIFACT_CORRUPT' | 'CHTYPES_ARTIFACT_PINNED' | 'CHTYPES_ARTIFACT_UNPUBLISHED' | 'CHTYPES_SOURCE_UNREACHABLE';
119
+ /** The command this SDK's §7 message tells a user to run. */
120
+ export declare const FETCH_COMMAND = "npx @wavehouse/chtypes fetch";
121
+ /**
122
+ * The §7 message, verbatim apart from the bracketed parts:
123
+ *
124
+ * chtypes: no artifact for ClickHouse <line> (<os>-<arch>). Looked in: <dir1>, <dir2>, ….
125
+ * Install it: npx @wavehouse/chtypes fetch <line>
126
+ * or set CHTYPES_AUTOFETCH=1 to fetch on first use.
127
+ */
128
+ export declare function artifactMissingMessage(line: string, platform: string, lookedIn: readonly string[]): string;
129
+ /**
130
+ * The one identifiable error for a missing artifact (docs/fetch.md §7):
131
+ * a `Registry` was asked for a line that no directory on its search path
132
+ * holds. `code` is `'CHTYPES_ARTIFACT_MISSING'`; the message is the
133
+ * contract's, and names every directory that was looked in and the command
134
+ * that installs the line.
135
+ *
136
+ * A subclass of `RegistryError`, so a `catch` written against `for()`'s
137
+ * documented error keeps working; the `code` is what a caller matches on.
138
+ */
139
+ export declare class ArtifactMissingError extends RegistryError {
140
+ readonly code: 'CHTYPES_ARTIFACT_MISSING';
141
+ /** The minor line that was asked for, e.g. `25.8`. */
142
+ readonly line: string;
143
+ /** The platform key the registry serves, e.g. `darwin-arm64`. */
144
+ readonly platform: string;
145
+ /** Every directory of the search path, in order. */
146
+ readonly lookedIn: readonly string[];
147
+ constructor(line: string, platform: string, lookedIn: readonly string[]);
148
+ }
149
+ /**
150
+ * Base of the fetch-time verdicts (docs/fetch.md §3–§7). `code` is one of the
151
+ * shared codes; the subclasses exist so `instanceof` reads as well as `code`.
152
+ */
153
+ export declare class FetchError extends ChtypesError {
154
+ readonly code: Exclude<ArtifactErrorCode, 'CHTYPES_ARTIFACT_MISSING'>;
155
+ constructor(code: Exclude<ArtifactErrorCode, 'CHTYPES_ARTIFACT_MISSING'>, message: string, options?: {
156
+ cause?: unknown;
157
+ });
158
+ }
159
+ /**
160
+ * `CHTYPES_ARTIFACT_UNTRUSTED`: the release's `SHA256SUMS.sig` is absent,
161
+ * malformed, or does not verify with any trusted key. Nothing is downloaded
162
+ * around it (§3 step 0).
163
+ */
164
+ export declare class ArtifactUntrustedError extends FetchError {
165
+ constructor(message: string, options?: {
166
+ cause?: unknown;
167
+ });
168
+ }
169
+ /**
170
+ * `CHTYPES_ARTIFACT_CORRUPT`: any hash mismatch along the chain, a release
171
+ * that disagrees with itself (`index.json` vs `SHA256SUMS`, manifest vs
172
+ * index), or an archive that cannot be read safely.
173
+ */
174
+ export declare class ArtifactCorruptError extends FetchError {
175
+ constructor(message: string, options?: {
176
+ cause?: unknown;
177
+ });
178
+ }
179
+ /**
180
+ * `CHTYPES_ARTIFACT_PINNED`: a `--frozen` lock file names a different asset
181
+ * or sha256 for this line — or none at all — and the fetch refused it (§5).
182
+ */
183
+ export declare class ArtifactPinnedError extends FetchError {
184
+ constructor(message: string, options?: {
185
+ cause?: unknown;
186
+ });
187
+ }
188
+ /** `CHTYPES_ARTIFACT_UNPUBLISHED`: the release has nothing for this platform, line or exact patch. */
189
+ export declare class ArtifactUnpublishedError extends FetchError {
190
+ constructor(message: string, options?: {
191
+ cause?: unknown;
192
+ });
193
+ }
194
+ /**
195
+ * `CHTYPES_SOURCE_UNREACHABLE`: the source could not be reached or does not
196
+ * serve the release files — or `offline` forbade reaching it and the line is
197
+ * not installed and verified.
198
+ */
199
+ export declare class SourceUnreachableError extends FetchError {
200
+ constructor(message: string, options?: {
201
+ cause?: unknown;
202
+ });
203
+ }
204
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}