@hypequery/clickhouse 2.10.1 → 2.11.1
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/dist/core/cte-scope.d.ts +91 -0
- package/dist/core/cte-scope.d.ts.map +1 -0
- package/dist/core/cte-scope.js +52 -0
- package/dist/core/dialects/clickhouse-dialect.d.ts.map +1 -1
- package/dist/core/dialects/clickhouse-dialect.js +4 -1
- package/dist/core/features/analytics.d.ts +13 -2
- package/dist/core/features/analytics.d.ts.map +1 -1
- package/dist/core/features/analytics.js +49 -3
- package/dist/core/features/joins.d.ts +5 -1
- package/dist/core/features/joins.d.ts.map +1 -1
- package/dist/core/features/joins.js +5 -1
- package/dist/core/formatters/sql-formatter.d.ts +1 -0
- package/dist/core/formatters/sql-formatter.d.ts.map +1 -1
- package/dist/core/formatters/sql-formatter.js +10 -3
- package/dist/core/query-builder.d.ts +89 -12
- package/dist/core/query-builder.d.ts.map +1 -1
- package/dist/core/query-builder.js +56 -4
- package/dist/core/query-node.d.ts.map +1 -1
- package/dist/core/query-node.js +7 -1
- package/dist/core/tests/integration/setup.d.ts +9 -0
- package/dist/core/tests/integration/setup.d.ts.map +1 -1
- package/dist/core/tests/test-utils.d.ts +23 -1
- package/dist/core/tests/test-utils.d.ts.map +1 -1
- package/dist/core/tests/test-utils.js +12 -3
- package/dist/core/types/builder-state.d.ts +68 -9
- package/dist/core/types/builder-state.d.ts.map +1 -1
- package/dist/core/types/builder-state.js +1 -0
- package/dist/core/types/select-types.d.ts +4 -2
- package/dist/core/types/select-types.d.ts.map +1 -1
- package/dist/core/utils/compound-parameter.d.ts +6 -0
- package/dist/core/utils/compound-parameter.d.ts.map +1 -0
- package/dist/core/utils/compound-parameter.js +70 -0
- package/dist/core/utils/cte-fragments.d.ts +17 -0
- package/dist/core/utils/cte-fragments.d.ts.map +1 -0
- package/dist/core/utils/cte-fragments.js +20 -0
- package/dist/core/utils/cte-scope-state.d.ts +5 -0
- package/dist/core/utils/cte-scope-state.d.ts.map +1 -0
- package/dist/core/utils/cte-scope-state.js +16 -0
- package/dist/core/utils/named-parameters.d.ts +30 -0
- package/dist/core/utils/named-parameters.d.ts.map +1 -0
- package/dist/core/utils/named-parameters.js +108 -0
- package/dist/core/utils/parameter-type.d.ts +10 -0
- package/dist/core/utils/parameter-type.d.ts.map +1 -0
- package/dist/core/utils/parameter-type.js +46 -0
- package/dist/core/utils/record-guards.d.ts +3 -0
- package/dist/core/utils/record-guards.d.ts.map +1 -0
- package/dist/core/utils/record-guards.js +7 -0
- package/dist/core/utils/sql-parens.d.ts +6 -0
- package/dist/core/utils/sql-parens.d.ts.map +1 -1
- package/dist/core/utils/sql-parens.js +6 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -5
- package/dist/types/base.d.ts +39 -0
- package/dist/types/base.d.ts.map +1 -1
- package/package.json +3 -4
- package/dist/core/compiled/compile.d.ts +0 -25
- package/dist/core/compiled/compile.d.ts.map +0 -1
- package/dist/core/compiled/compile.js +0 -134
- package/dist/core/compiled/debug.d.ts +0 -7
- package/dist/core/compiled/debug.d.ts.map +0 -1
- package/dist/core/compiled/debug.js +0 -25
- package/dist/core/compiled/errors.d.ts +0 -38
- package/dist/core/compiled/errors.d.ts.map +0 -1
- package/dist/core/compiled/errors.js +0 -91
- package/dist/core/compiled/index.d.ts +0 -15
- package/dist/core/compiled/index.d.ts.map +0 -1
- package/dist/core/compiled/index.js +0 -14
- package/dist/core/compiled/parameters.d.ts +0 -28
- package/dist/core/compiled/parameters.d.ts.map +0 -1
- package/dist/core/compiled/parameters.js +0 -282
- package/dist/core/compiled/settings.d.ts +0 -49
- package/dist/core/compiled/settings.d.ts.map +0 -1
- package/dist/core/compiled/settings.js +0 -65
- package/dist/core/compiled/types.d.ts +0 -115
- package/dist/core/compiled/types.d.ts.map +0 -1
- package/dist/core/compiled/types.js +0 -13
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"named-parameters.d.ts","sourceRoot":"","sources":["../../../src/core/utils/named-parameters.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,UAAU,EAAE,OAAO,EAAE,CAAC;CACvB;AAoDD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,OAAO,SAAQ,GACd,qBAAqB,CAgDvB"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { escapeValue } from '../utils.js';
|
|
2
|
+
import { skipNonCode } from './sql-parens.js';
|
|
3
|
+
import { serializeCompoundParameter } from './compound-parameter.js';
|
|
4
|
+
const IDENTIFIER_START = /[A-Za-z_]/;
|
|
5
|
+
const IDENTIFIER_CHAR = /[A-Za-z0-9_]/;
|
|
6
|
+
function readIdentifier(sql, start) {
|
|
7
|
+
if (!IDENTIFIER_START.test(sql[start] ?? ''))
|
|
8
|
+
return undefined;
|
|
9
|
+
let i = start + 1;
|
|
10
|
+
while (i < sql.length && IDENTIFIER_CHAR.test(sql[i]))
|
|
11
|
+
i += 1;
|
|
12
|
+
return sql.slice(start, i);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Reads a `{name:Type}` placeholder starting at the `{`. The type is consumed
|
|
16
|
+
* with paren nesting so `{ids:Array(UInt64)}` matches, and anything that is not
|
|
17
|
+
* shaped like a placeholder — a `{shard}` macro, a brace in an expression —
|
|
18
|
+
* returns undefined so it is left untouched.
|
|
19
|
+
*/
|
|
20
|
+
function matchPlaceholder(sql, start) {
|
|
21
|
+
const name = readIdentifier(sql, start + 1);
|
|
22
|
+
if (name === undefined)
|
|
23
|
+
return undefined;
|
|
24
|
+
let i = start + 1 + name.length;
|
|
25
|
+
if (sql[i] !== ':')
|
|
26
|
+
return undefined;
|
|
27
|
+
i += 1;
|
|
28
|
+
const typeStart = i;
|
|
29
|
+
let depth = 0;
|
|
30
|
+
while (i < sql.length) {
|
|
31
|
+
const skippedTo = skipNonCode(sql, i);
|
|
32
|
+
if (skippedTo !== undefined) {
|
|
33
|
+
i = skippedTo;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const ch = sql[i];
|
|
37
|
+
if (ch === '{')
|
|
38
|
+
return undefined;
|
|
39
|
+
if (ch === '(')
|
|
40
|
+
depth += 1;
|
|
41
|
+
else if (ch === ')')
|
|
42
|
+
depth -= 1;
|
|
43
|
+
else if (ch === '}' && depth === 0) {
|
|
44
|
+
const type = sql.slice(typeStart, i).trim();
|
|
45
|
+
return type ? { name, type, end: i + 1 } : undefined;
|
|
46
|
+
}
|
|
47
|
+
i += 1;
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Rewrites ClickHouse-style `{name:Type}` placeholders to the positional `?`
|
|
53
|
+
* markers the builder binds against, pairing each with its value.
|
|
54
|
+
*
|
|
55
|
+
* TODO: Remove this client-side rewrite and its CAST/compound serialization
|
|
56
|
+
* once native server-side query_params binding replaces positional parameters.
|
|
57
|
+
* The public {name:Type} placeholder API can stay unchanged.
|
|
58
|
+
*
|
|
59
|
+
* Each marker is wrapped in a `CAST` to the declared type, which is what the
|
|
60
|
+
* server's own `{name:Type}` substitution does. Without it the value arrives as
|
|
61
|
+
* a String and any expression that depends on the real type fails to compile.
|
|
62
|
+
*
|
|
63
|
+
* Placeholders inside string literals, quoted identifiers, heredocs, and
|
|
64
|
+
* comments are data and are left alone, so a body can talk about braces without
|
|
65
|
+
* having them bound.
|
|
66
|
+
*
|
|
67
|
+
* Values that no placeholder references are ignored: a caller may pass one
|
|
68
|
+
* context object to several fragments.
|
|
69
|
+
*/
|
|
70
|
+
export function bindNamedParameters(sql, values = {}, context = 'SQL') {
|
|
71
|
+
const parameters = [];
|
|
72
|
+
let bound = '';
|
|
73
|
+
let copiedTo = 0;
|
|
74
|
+
let i = 0;
|
|
75
|
+
while (i < sql.length) {
|
|
76
|
+
const skippedTo = skipNonCode(sql, i);
|
|
77
|
+
if (skippedTo !== undefined) {
|
|
78
|
+
i = skippedTo;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (sql[i] !== '{') {
|
|
82
|
+
i += 1;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const placeholder = matchPlaceholder(sql, i);
|
|
86
|
+
if (!placeholder) {
|
|
87
|
+
const name = readIdentifier(sql, i + 1);
|
|
88
|
+
const afterName = name === undefined ? undefined : sql[i + 1 + name.length];
|
|
89
|
+
if (name !== undefined && (afterName === '}' || afterName === ':') && name in values) {
|
|
90
|
+
throw new Error(`${context} placeholder "{${name}}" is missing a type. Write it as {${name}:Type}, for example {${name}:UUID}.`);
|
|
91
|
+
}
|
|
92
|
+
i += 1;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (!(placeholder.name in values)) {
|
|
96
|
+
throw new Error(`${context} references parameter "${placeholder.name}", but no value was provided for it.`);
|
|
97
|
+
}
|
|
98
|
+
// The declared type has to survive substitution: a bare escaped literal
|
|
99
|
+
// reaches the server as a String, which breaks any expression that needs
|
|
100
|
+
// the real type — a UUID join key, for instance.
|
|
101
|
+
bound += `${sql.slice(copiedTo, i)}CAST(?, ${escapeValue(placeholder.type)})`;
|
|
102
|
+
const value = values[placeholder.name];
|
|
103
|
+
parameters.push(serializeCompoundParameter(value, placeholder.type));
|
|
104
|
+
copiedTo = placeholder.end;
|
|
105
|
+
i = placeholder.end;
|
|
106
|
+
}
|
|
107
|
+
return { sql: bound + sql.slice(copiedTo), parameters };
|
|
108
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function parseParameterType(type: string): {
|
|
2
|
+
name: string;
|
|
3
|
+
args: string[];
|
|
4
|
+
};
|
|
5
|
+
/** Named tuple fields can still be supplied positionally as JavaScript arrays. */
|
|
6
|
+
export declare function parseTupleField(field: string): {
|
|
7
|
+
name?: string;
|
|
8
|
+
type: string;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=parameter-type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parameter-type.d.ts","sourceRoot":"","sources":["../../../src/core/utils/parameter-type.ts"],"names":[],"mappings":"AA0BA,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAIjF;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAW9E"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { skipNonCode } from './sql-parens.js';
|
|
2
|
+
/** Split type arguments without treating quoted or nested commas as separators. */
|
|
3
|
+
function splitTypeArguments(input) {
|
|
4
|
+
const parts = [];
|
|
5
|
+
let depth = 0;
|
|
6
|
+
let start = 0;
|
|
7
|
+
let i = 0;
|
|
8
|
+
while (i < input.length) {
|
|
9
|
+
const end = skipNonCode(input, i);
|
|
10
|
+
if (end !== undefined) {
|
|
11
|
+
i = end;
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
if (input[i] === '(')
|
|
15
|
+
depth += 1;
|
|
16
|
+
if (input[i] === ')')
|
|
17
|
+
depth -= 1;
|
|
18
|
+
if (input[i] === ',' && depth === 0) {
|
|
19
|
+
parts.push(input.slice(start, i).trim());
|
|
20
|
+
start = i + 1;
|
|
21
|
+
}
|
|
22
|
+
i += 1;
|
|
23
|
+
}
|
|
24
|
+
if (input.slice(start).trim())
|
|
25
|
+
parts.push(input.slice(start).trim());
|
|
26
|
+
return parts;
|
|
27
|
+
}
|
|
28
|
+
export function parseParameterType(type) {
|
|
29
|
+
const match = /^([A-Za-z][A-Za-z0-9]*)\s*(?:\(([\s\S]*)\))?$/.exec(type.trim());
|
|
30
|
+
if (!match)
|
|
31
|
+
throw new Error(`Cannot serialize parameter with type ${type}`);
|
|
32
|
+
return { name: match[1], args: match[2] === undefined ? [] : splitTypeArguments(match[2]) };
|
|
33
|
+
}
|
|
34
|
+
/** Named tuple fields can still be supplied positionally as JavaScript arrays. */
|
|
35
|
+
export function parseTupleField(field) {
|
|
36
|
+
if (field[0] === '`' || field[0] === '"') {
|
|
37
|
+
const end = skipNonCode(field, 0);
|
|
38
|
+
const quote = field[0];
|
|
39
|
+
const name = field.slice(1, end - 1)
|
|
40
|
+
.replace(new RegExp(`${quote}${quote}`, 'g'), quote)
|
|
41
|
+
.replace(/\\(.)/gs, (_, char) => ({ n: '\n', r: '\r', t: '\t', '0': '\0', b: '\b', f: '\f' }[char] ?? char));
|
|
42
|
+
return { name, type: field.slice(end).trim() };
|
|
43
|
+
}
|
|
44
|
+
const named = /^([A-Za-z_][A-Za-z0-9_]*)\s+([A-Za-z][\s\S]*)$/.exec(field);
|
|
45
|
+
return named ? { name: named[1], type: named[2] } : { type: field };
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-guards.d.ts","sourceRoot":"","sources":["../../../src/core/utils/record-guards.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAI9E"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Accept plain objects and null-prototype records, excluding class instances. */
|
|
2
|
+
export function isPlainRecord(value) {
|
|
3
|
+
if (value === null || typeof value !== 'object')
|
|
4
|
+
return false;
|
|
5
|
+
const prototype = Object.getPrototypeOf(value);
|
|
6
|
+
return prototype === Object.prototype || prototype === null;
|
|
7
|
+
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When `start` opens a region that is not SQL code — a literal, a quoted
|
|
3
|
+
* identifier, a heredoc, or a comment — returns the index just past it.
|
|
4
|
+
* Scanners use it so markers inside such a region stay data.
|
|
5
|
+
*/
|
|
6
|
+
export declare function skipNonCode(sql: string, start: number): number | undefined;
|
|
1
7
|
/**
|
|
2
8
|
* Split on positional parameter markers that occur in SQL code. Question marks
|
|
3
9
|
* inside literals, quoted identifiers, heredocs, or comments are data, not
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-parens.d.ts","sourceRoot":"","sources":["../../../src/core/utils/sql-parens.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sql-parens.d.ts","sourceRoot":"","sources":["../../../src/core/utils/sql-parens.ts"],"names":[],"mappings":"AAuEA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAqB1E;AASD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAqB1D;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAchE;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CA8B/D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAuBzD"}
|
|
@@ -65,7 +65,12 @@ function isLineCommentStart(sql, start) {
|
|
|
65
65
|
return true;
|
|
66
66
|
return sql[start] === '#' && (sql[start + 1] === ' ' || sql[start + 1] === '!');
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
/**
|
|
69
|
+
* When `start` opens a region that is not SQL code — a literal, a quoted
|
|
70
|
+
* identifier, a heredoc, or a comment — returns the index just past it.
|
|
71
|
+
* Scanners use it so markers inside such a region stay data.
|
|
72
|
+
*/
|
|
73
|
+
export function skipNonCode(sql, start) {
|
|
69
74
|
const ch = sql[start];
|
|
70
75
|
if (ch === "'" || ch === '"' || ch === '`') {
|
|
71
76
|
return skipQuoted(sql, start, ch);
|
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,6 @@ export type { SqlDialect } from './core/dialects/sql-dialect.js';
|
|
|
12
12
|
export type { ClickHouseConfig, ClickHouseAdapterConfig, ClickHouseAdapterOptions, ClickHouseClientConfig, CreateQueryBuilderConfig, ExecuteOptions, IntegerJsonEncoding, StreamOptions } from './core/query-builder.js';
|
|
13
13
|
export { isClientConfig } from './core/query-builder.js';
|
|
14
14
|
export { substituteParameters, escapeValue } from './core/utils.js';
|
|
15
|
-
export * from './core/compiled/index.js';
|
|
16
15
|
export type { CacheOptions, CacheConfig, CacheProvider, CacheEntry, CacheStatus } from './core/cache/types.js';
|
|
17
16
|
export { CacheController } from './core/cache/controller.js';
|
|
18
17
|
export { MemoryCacheProvider } from './core/cache/providers/memory-lru.js';
|
|
@@ -20,7 +19,10 @@ export { MemoryCacheProvider as MemoryLRUCacheProvider } from './core/cache/prov
|
|
|
20
19
|
export { NoopCacheProvider } from './core/cache/providers/noop.js';
|
|
21
20
|
export type { ColumnType, TableColumn, TableSchema, TableRecord, DatabaseSchema, InferColumnType, } from './types/schema.js';
|
|
22
21
|
export type { InsertRow, InsertRowForColumns, InsertValue, InsertJsonValue, } from './types/insert.js';
|
|
23
|
-
export type { OrderDirection, QueryConfig, AggregationType } from './types/base.js';
|
|
22
|
+
export type { OrderDirection, QueryConfig, AggregationType, RawCteBody } from './types/base.js';
|
|
23
|
+
export { CteScope } from './core/cte-scope.js';
|
|
24
|
+
export type { CteScopeDeps } from './core/cte-scope.js';
|
|
25
|
+
export type { CteBody } from './core/features/analytics.js';
|
|
24
26
|
export type { FilterOperator, OperatorValueMap, FilterConditionInput } from './types/filters.js';
|
|
25
27
|
export type { JoinPath, JoinPathOptions } from './core/join-relationships.js';
|
|
26
28
|
export { CrossFilter } from './core/cross-filter.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,YAAY,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,YAAY,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,YAAY,EACV,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,qCAAqC,CAAC;AAC7C,YAAY,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAGjE,YAAY,EACV,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,cAAc,EACd,mBAAmB,EACnB,aAAa,EACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAIzD,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -9,15 +9,11 @@ export { isClientConfig } from './core/query-builder.js';
|
|
|
9
9
|
// SQL rendering used by the built-in adapter; exported so third-party DatabaseAdapter
|
|
10
10
|
// implementations (e.g. embedded engines) reproduce identical ?-param rendering.
|
|
11
11
|
export { substituteParameters, escapeValue } from './core/utils.js';
|
|
12
|
-
// CompiledQuery v1 (RFC 0010) — versioned execution-request contract with named typed
|
|
13
|
-
// parameters, closed operations/settings, authoritative ids, deadlines, a redacted debug
|
|
14
|
-
// form, and the public error envelope. Introduced beside the legacy ?-param path (CH-01);
|
|
15
|
-
// the built-in adapter transport is wired in a later change.
|
|
16
|
-
export * from './core/compiled/index.js';
|
|
17
12
|
export { CacheController } from './core/cache/controller.js';
|
|
18
13
|
export { MemoryCacheProvider } from './core/cache/providers/memory-lru.js';
|
|
19
14
|
export { MemoryCacheProvider as MemoryLRUCacheProvider } from './core/cache/providers/memory-lru.js';
|
|
20
15
|
export { NoopCacheProvider } from './core/cache/providers/noop.js';
|
|
16
|
+
export { CteScope } from './core/cte-scope.js';
|
|
21
17
|
export { CrossFilter } from './core/cross-filter.js';
|
|
22
18
|
export { logger } from './core/utils/logger.js';
|
|
23
19
|
// Re-export SQL expression utilities
|
package/dist/types/base.d.ts
CHANGED
|
@@ -16,6 +16,12 @@ export interface QueryConfig<_T, _Schema> {
|
|
|
16
16
|
orderBy?: OrderByItemNode[];
|
|
17
17
|
joins?: JoinNode[];
|
|
18
18
|
ctes?: CteNode[];
|
|
19
|
+
/**
|
|
20
|
+
* Renders the `WITH` clause as `WITH RECURSIVE`. `RECURSIVE` is a property of
|
|
21
|
+
* the clause rather than of a single entry, so one recursive CTE marks the
|
|
22
|
+
* whole list — the same rule SQL itself uses.
|
|
23
|
+
*/
|
|
24
|
+
recursiveCtes?: boolean;
|
|
19
25
|
unionQueries?: string[];
|
|
20
26
|
settings?: ClickHouseSettings;
|
|
21
27
|
}
|
|
@@ -69,6 +75,12 @@ export interface TableSourceNode {
|
|
|
69
75
|
kind: 'table';
|
|
70
76
|
name: string;
|
|
71
77
|
final?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* The name resolves to a CTE declared on this query rather than to a table.
|
|
80
|
+
* It renders identically, but table-only modifiers (`FINAL`, `PREWHERE`) do
|
|
81
|
+
* not apply to it.
|
|
82
|
+
*/
|
|
83
|
+
cte?: boolean;
|
|
72
84
|
}
|
|
73
85
|
export interface SubquerySourceNode {
|
|
74
86
|
kind: 'subquery';
|
|
@@ -117,7 +129,34 @@ export interface LimitByNode {
|
|
|
117
129
|
}
|
|
118
130
|
export interface CteNode {
|
|
119
131
|
kind: 'cte';
|
|
132
|
+
/**
|
|
133
|
+
* The entry as a single rendered fragment, with any parameter values already
|
|
134
|
+
* substituted. Kept as the canonical field so consumers reading it keep
|
|
135
|
+
* working; compilation prefers `name`/`body` when they are present.
|
|
136
|
+
*/
|
|
120
137
|
expression: string;
|
|
138
|
+
/** CTE alias. Present for named CTEs, absent for `withScalar` entries. */
|
|
139
|
+
name?: string;
|
|
140
|
+
/**
|
|
141
|
+
* The CTE body with `?` placeholders left in place, so its values can stay
|
|
142
|
+
* bound instead of being escaped into `expression`.
|
|
143
|
+
*/
|
|
144
|
+
body?: string;
|
|
145
|
+
/** Values for the placeholders in `body`, in order. */
|
|
146
|
+
parameters?: unknown[];
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* A raw CTE body with its values kept out of the SQL text. Placeholders use
|
|
150
|
+
* ClickHouse's `{name:Type}` form and are matched by name against `parameters`.
|
|
151
|
+
*
|
|
152
|
+
* Required for a recursive CTE, whose recursive term references an alias that
|
|
153
|
+
* no builder can express; ordinary CTEs are better written as a builder.
|
|
154
|
+
*/
|
|
155
|
+
export interface RawCteBody {
|
|
156
|
+
/** The CTE body, with `{name:Type}` placeholders for its values. */
|
|
157
|
+
sql: string;
|
|
158
|
+
/** Values for those placeholders, keyed by placeholder name. */
|
|
159
|
+
parameters?: Record<string, unknown>;
|
|
121
160
|
}
|
|
122
161
|
export interface SelectQueryNode<T, Schema> extends QueryConfig<T, Schema> {
|
|
123
162
|
kind: 'select-query';
|
package/dist/types/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/types/base.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/types/base.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hypequery/clickhouse",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.1",
|
|
4
4
|
"description": "Type-safe ClickHouse query builder and schema generator for TypeScript analytics",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"clickhouse",
|
|
@@ -47,8 +47,7 @@
|
|
|
47
47
|
],
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@clickhouse/client": "^1.18.3",
|
|
50
|
-
"dotenv": "^16.0.0"
|
|
51
|
-
"@hypequery/protocol": "0.13.0"
|
|
50
|
+
"dotenv": "^16.0.0"
|
|
52
51
|
},
|
|
53
52
|
"peerDependencies": {
|
|
54
53
|
"@clickhouse/client-web": "^0.2.0 || ^1.0.0",
|
|
@@ -74,7 +73,7 @@
|
|
|
74
73
|
"typescript": "^5.7.3",
|
|
75
74
|
"@vitest/coverage-v8": "^3.2.6",
|
|
76
75
|
"vitest": "^3.2.6",
|
|
77
|
-
"@hypequery/datasets": "0.
|
|
76
|
+
"@hypequery/datasets": "0.17.0"
|
|
78
77
|
},
|
|
79
78
|
"ts-node": {
|
|
80
79
|
"esm": true,
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { type CompiledIdentifiers, type CompiledOperation, type CompiledParameterDeclaration, type CompiledParameterValue, type CompiledQueryV1, type CompiledSensitivity, type CompiledSettings } from './types.js';
|
|
2
|
-
export interface CompileQueryInput {
|
|
3
|
-
readonly operation: CompiledOperation;
|
|
4
|
-
/** Trusted build/server output. Callers never author this. */
|
|
5
|
-
readonly sql: string;
|
|
6
|
-
readonly parameters?: readonly CompiledParameterDeclaration[];
|
|
7
|
-
/** Values supplied for declared parameter names. */
|
|
8
|
-
readonly values?: Readonly<Record<string, CompiledParameterValue>>;
|
|
9
|
-
readonly settings?: CompiledSettings;
|
|
10
|
-
readonly sensitivity?: CompiledSensitivity;
|
|
11
|
-
/** Server-generated authoritative identifier; the caller may add a correlation id. */
|
|
12
|
-
readonly identifiers: CompiledIdentifiers;
|
|
13
|
-
readonly deadline?: {
|
|
14
|
-
readonly callerAtEpochMs?: number;
|
|
15
|
-
readonly policyMaxMs?: number;
|
|
16
|
-
readonly nowEpochMs: number;
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Assemble and validate a `CompiledQueryV1` (RFC 0010). This constructs the execution
|
|
21
|
-
* request beside the legacy positional path; it performs every fail-closed check before an
|
|
22
|
-
* adapter is ever handed the query, but performs no I/O.
|
|
23
|
-
*/
|
|
24
|
-
export declare function compileQueryV1(input: CompileQueryInput): CompiledQueryV1;
|
|
25
|
-
//# sourceMappingURL=compile.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/core/compiled/compile.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,4BAA4B,EACjC,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACtB,MAAM,YAAY,CAAC;AAmBpB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC,8DAA8D;IAC9D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,4BAA4B,EAAE,CAAC;IAC9D,oDAAoD;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC;IACnE,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAC3C,sFAAsF;IACtF,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAClB,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;QAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;KAC7B,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,eAAe,CAqCxE"}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { buildDebugForm } from './debug.js';
|
|
2
|
-
import { CompiledQueryError } from './errors.js';
|
|
3
|
-
import { assertNoValuesInSql, buildParameterBindings, validateParameterReferences, } from './parameters.js';
|
|
4
|
-
import { resolveCompiledDeadline, resolveCompiledSettings } from './settings.js';
|
|
5
|
-
import { COMPILED_QUERY_VERSION, } from './types.js';
|
|
6
|
-
const MAX_CORRELATION_ID_BYTES = 1024;
|
|
7
|
-
const MAX_QUERY_ID_BYTES = 200;
|
|
8
|
-
const MAX_SQL_BYTES = 1_048_576;
|
|
9
|
-
const MAX_PARAMETERS = 256;
|
|
10
|
-
const MAX_CLICKHOUSE_TYPE_BYTES = 256;
|
|
11
|
-
const MAX_SENSITIVITY_LABELS = 32;
|
|
12
|
-
const MAX_SENSITIVITY_LABEL_BYTES = 64;
|
|
13
|
-
// eslint-disable-next-line no-control-regex -- control chars are exactly what we reject
|
|
14
|
-
const CONTROL_CHAR_PATTERN = /[\u0000-\u001F\u007F-\u009F]/;
|
|
15
|
-
const QUERY_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]*$/;
|
|
16
|
-
const SENSITIVITY_LABEL_PATTERN = /^[a-z][a-z0-9._-]*$/;
|
|
17
|
-
const LOGICAL_TYPES = new Set([
|
|
18
|
-
'array', 'boolean', 'bytes', 'date', 'datetime', 'decimal', 'enum', 'float',
|
|
19
|
-
'integer', 'map', 'null', 'string', 'tuple', 'uuid',
|
|
20
|
-
]);
|
|
21
|
-
const utf8 = new TextEncoder();
|
|
22
|
-
/**
|
|
23
|
-
* Assemble and validate a `CompiledQueryV1` (RFC 0010). This constructs the execution
|
|
24
|
-
* request beside the legacy positional path; it performs every fail-closed check before an
|
|
25
|
-
* adapter is ever handed the query, but performs no I/O.
|
|
26
|
-
*/
|
|
27
|
-
export function compileQueryV1(input) {
|
|
28
|
-
validateOperation(input.operation);
|
|
29
|
-
validateSql(input.sql);
|
|
30
|
-
const parameters = snapshotParameters(input.parameters ?? []);
|
|
31
|
-
const values = input.values ?? {};
|
|
32
|
-
validateParameterReferences(input.sql, parameters);
|
|
33
|
-
const bindings = buildParameterBindings(parameters, values);
|
|
34
|
-
assertNoValuesInSql(input.sql, bindings);
|
|
35
|
-
const settings = resolveCompiledSettings(input.settings ?? {});
|
|
36
|
-
const identifiers = validateIdentifiers(input.identifiers);
|
|
37
|
-
const deadlineInputs = input.deadline
|
|
38
|
-
? {
|
|
39
|
-
...input.deadline,
|
|
40
|
-
policyMaxMs: minimumDefined(input.deadline.policyMaxMs, settings.maxExecutionMs),
|
|
41
|
-
}
|
|
42
|
-
: undefined;
|
|
43
|
-
const deadline = deadlineInputs
|
|
44
|
-
? resolveCompiledDeadline(deadlineInputs)
|
|
45
|
-
: undefined;
|
|
46
|
-
const sensitivity = snapshotSensitivity(input.sensitivity);
|
|
47
|
-
const debug = buildDebugForm(input.sql, parameters, settings);
|
|
48
|
-
return Object.freeze({
|
|
49
|
-
version: COMPILED_QUERY_VERSION,
|
|
50
|
-
operation: input.operation,
|
|
51
|
-
sql: input.sql,
|
|
52
|
-
parameters,
|
|
53
|
-
bindings,
|
|
54
|
-
settings,
|
|
55
|
-
identifiers,
|
|
56
|
-
deadline,
|
|
57
|
-
sensitivity,
|
|
58
|
-
debug,
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
function minimumDefined(left, right) {
|
|
62
|
-
if (left === undefined)
|
|
63
|
-
return right;
|
|
64
|
-
if (right === undefined)
|
|
65
|
-
return left;
|
|
66
|
-
return Math.min(left, right);
|
|
67
|
-
}
|
|
68
|
-
function validateOperation(operation) {
|
|
69
|
-
if (operation !== 'query' && operation !== 'command' && operation !== 'insert') {
|
|
70
|
-
throw new CompiledQueryError('input-invalid', 'The compiled operation is invalid.');
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
function validateSql(sql) {
|
|
74
|
-
if (typeof sql !== 'string' || sql.length === 0 || utf8.encode(sql).length > MAX_SQL_BYTES) {
|
|
75
|
-
throw new CompiledQueryError('input-invalid', 'The compiled SQL is empty or too large.');
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
function snapshotParameters(input) {
|
|
79
|
-
if (!Array.isArray(input) || input.length > MAX_PARAMETERS) {
|
|
80
|
-
throw new CompiledQueryError('too-large', 'The compiled query has too many parameters.');
|
|
81
|
-
}
|
|
82
|
-
return Object.freeze(input.map((declaration) => {
|
|
83
|
-
const logical = declaration?.type?.logical;
|
|
84
|
-
const clickHouseType = declaration?.type?.clickHouseType;
|
|
85
|
-
if (!LOGICAL_TYPES.has(logical)
|
|
86
|
-
|| typeof clickHouseType !== 'string'
|
|
87
|
-
|| clickHouseType.length === 0
|
|
88
|
-
|| CONTROL_CHAR_PATTERN.test(clickHouseType)
|
|
89
|
-
|| utf8.encode(clickHouseType).length > MAX_CLICKHOUSE_TYPE_BYTES
|
|
90
|
-
|| typeof declaration.optional !== 'boolean') {
|
|
91
|
-
throw new CompiledQueryError('input-invalid', 'A parameter declaration is invalid.');
|
|
92
|
-
}
|
|
93
|
-
return Object.freeze({
|
|
94
|
-
name: declaration.name,
|
|
95
|
-
type: Object.freeze({ logical, clickHouseType }),
|
|
96
|
-
optional: declaration.optional,
|
|
97
|
-
});
|
|
98
|
-
}));
|
|
99
|
-
}
|
|
100
|
-
function snapshotSensitivity(input) {
|
|
101
|
-
const tenantScoped = input?.tenantScoped ?? false;
|
|
102
|
-
const labels = input?.labels ?? [];
|
|
103
|
-
if (typeof tenantScoped !== 'boolean' || !Array.isArray(labels) || labels.length > MAX_SENSITIVITY_LABELS) {
|
|
104
|
-
throw new CompiledQueryError('input-invalid', 'Sensitivity metadata is invalid.');
|
|
105
|
-
}
|
|
106
|
-
const snapshot = labels.map((label) => {
|
|
107
|
-
if (typeof label !== 'string'
|
|
108
|
-
|| !SENSITIVITY_LABEL_PATTERN.test(label)
|
|
109
|
-
|| utf8.encode(label).length > MAX_SENSITIVITY_LABEL_BYTES) {
|
|
110
|
-
throw new CompiledQueryError('input-invalid', 'A sensitivity label is invalid.');
|
|
111
|
-
}
|
|
112
|
-
return label;
|
|
113
|
-
});
|
|
114
|
-
return Object.freeze({ tenantScoped, labels: Object.freeze(snapshot) });
|
|
115
|
-
}
|
|
116
|
-
function validateIdentifiers(identifiers) {
|
|
117
|
-
if (typeof identifiers.queryId !== 'string'
|
|
118
|
-
|| !QUERY_ID_PATTERN.test(identifiers.queryId)
|
|
119
|
-
|| utf8.encode(identifiers.queryId).length > MAX_QUERY_ID_BYTES) {
|
|
120
|
-
throw new CompiledQueryError('internal', 'A server-generated query id is required.');
|
|
121
|
-
}
|
|
122
|
-
const { correlationId } = identifiers;
|
|
123
|
-
if (correlationId !== undefined) {
|
|
124
|
-
if (CONTROL_CHAR_PATTERN.test(correlationId)) {
|
|
125
|
-
throw new CompiledQueryError('input-invalid', 'The correlation id contains control characters.');
|
|
126
|
-
}
|
|
127
|
-
if (utf8.encode(correlationId).length > MAX_CORRELATION_ID_BYTES) {
|
|
128
|
-
throw new CompiledQueryError('too-large', 'The correlation id exceeds the allowed size.');
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return Object.freeze(correlationId === undefined
|
|
132
|
-
? { queryId: identifiers.queryId }
|
|
133
|
-
: { queryId: identifiers.queryId, correlationId });
|
|
134
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { CompiledDebugForm, CompiledParameterDeclaration, CompiledSettings } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Build the redacted, non-executable debug form. It carries no parameter values, tenant
|
|
4
|
-
* values, credentials, or setting values — only names, declared types, and structure.
|
|
5
|
-
*/
|
|
6
|
-
export declare function buildDebugForm(sql: string, parameters: readonly CompiledParameterDeclaration[], settings: CompiledSettings): CompiledDebugForm;
|
|
7
|
-
//# sourceMappingURL=debug.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../../src/core/compiled/debug.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,4BAA4B,EAC5B,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAWpB;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,SAAS,4BAA4B,EAAE,EACnD,QAAQ,EAAE,gBAAgB,GACzB,iBAAiB,CAkBnB"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { replaceParameterPlaceholders } from './parameters.js';
|
|
2
|
-
/**
|
|
3
|
-
* Marker wrapping placeholders in the debug form. The guillemets make the rendered SQL
|
|
4
|
-
* deliberately invalid as database SQL — it cannot be pasted into a client and run — while
|
|
5
|
-
* still showing structure and declared types (RFC 0010 §Debug form).
|
|
6
|
-
*/
|
|
7
|
-
const DEBUG_OPEN = '«param ';
|
|
8
|
-
const DEBUG_CLOSE = '»';
|
|
9
|
-
/**
|
|
10
|
-
* Build the redacted, non-executable debug form. It carries no parameter values, tenant
|
|
11
|
-
* values, credentials, or setting values — only names, declared types, and structure.
|
|
12
|
-
*/
|
|
13
|
-
export function buildDebugForm(sql, parameters, settings) {
|
|
14
|
-
const redactedSql = replaceParameterPlaceholders(sql, (name, type) => `${DEBUG_OPEN}${name}: ${type}${DEBUG_CLOSE}`);
|
|
15
|
-
return Object.freeze({
|
|
16
|
-
sql: redactedSql,
|
|
17
|
-
parameters: Object.freeze(parameters.map((p) => Object.freeze({
|
|
18
|
-
name: p.name,
|
|
19
|
-
type: p.type.clickHouseType,
|
|
20
|
-
optional: p.optional,
|
|
21
|
-
}))),
|
|
22
|
-
// Setting names only; values are policy and never appear in diagnostics.
|
|
23
|
-
settings: Object.freeze(Object.keys(settings).filter((key) => settings[key] !== undefined)),
|
|
24
|
-
});
|
|
25
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Public execution-failure envelope from RFC 0010 §Error envelope.
|
|
3
|
-
*
|
|
4
|
-
* The category set is closed and stable within version 1. It matches the frozen set in
|
|
5
|
-
* `@hypequery/protocol` (`events` module) so runtime failures and emitted diagnostics
|
|
6
|
-
* speak the same vocabulary. New categories require a new contract version.
|
|
7
|
-
*/
|
|
8
|
-
export declare const COMPILED_ERROR_CATEGORIES: readonly ["input-invalid", "unauthenticated", "forbidden", "tenant-required", "not-found", "too-large", "aborted", "deadline-exceeded", "unavailable", "internal"];
|
|
9
|
-
export type CompiledErrorCategory = (typeof COMPILED_ERROR_CATEGORIES)[number];
|
|
10
|
-
export declare function isCompiledErrorCategory(value: unknown): value is CompiledErrorCategory;
|
|
11
|
-
export declare function isClientFaultCategory(category: CompiledErrorCategory): boolean;
|
|
12
|
-
/** The stable, serializable error object surfaced to callers. */
|
|
13
|
-
export interface CompiledErrorEnvelope {
|
|
14
|
-
readonly category: CompiledErrorCategory;
|
|
15
|
-
readonly message: string;
|
|
16
|
-
/** Authoritative query identifier; safe for logs. Absent only before one is assigned. */
|
|
17
|
-
readonly queryId?: string;
|
|
18
|
-
}
|
|
19
|
-
export interface CompiledQueryErrorOptions {
|
|
20
|
-
readonly queryId?: string;
|
|
21
|
-
/** Non-public cause retained for local logging; never serialized into the envelope. */
|
|
22
|
-
readonly cause?: unknown;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* The only execution-failure shape a runtime may surface for a compiled query. For
|
|
26
|
-
* server-fault categories the caller-facing message is fixed to a generic string so no
|
|
27
|
-
* adapter text, SQL, value, or tenant identifier can leak.
|
|
28
|
-
*/
|
|
29
|
-
export declare class CompiledQueryError extends Error {
|
|
30
|
-
readonly category: CompiledErrorCategory;
|
|
31
|
-
readonly queryId?: string;
|
|
32
|
-
readonly cause?: unknown;
|
|
33
|
-
constructor(category: CompiledErrorCategory, message: string, options?: CompiledQueryErrorOptions);
|
|
34
|
-
private static resolveMessage;
|
|
35
|
-
/** The redacted, serializable envelope. Only closed fields; no `cause`, no stack. */
|
|
36
|
-
toEnvelope(): CompiledErrorEnvelope;
|
|
37
|
-
}
|
|
38
|
-
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/core/compiled/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,oKAW5B,CAAC;AAEX,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AAoB/E,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAKtF;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,OAAO,CAE9E;AAED,iEAAiE;AACjE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yFAAyF;IACzF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,uFAAuF;IACvF,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAkB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAGhC,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,yBAA8B;IAUzC,OAAO,CAAC,MAAM,CAAC,cAAc;IAY7B,qFAAqF;IACrF,UAAU,IAAI,qBAAqB;CAKpC"}
|