@housekit/orm 0.1.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.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +224 -0
  3. package/dist/builders/delete.d.ts +21 -0
  4. package/dist/builders/insert.d.ts +128 -0
  5. package/dist/builders/prepared.d.ts +11 -0
  6. package/dist/builders/select.d.ts +352 -0
  7. package/dist/builders/select.types.d.ts +76 -0
  8. package/dist/builders/update.d.ts +23 -0
  9. package/dist/client.d.ts +52 -0
  10. package/dist/codegen/zod.d.ts +4 -0
  11. package/dist/column.d.ts +76 -0
  12. package/dist/compiler.d.ts +27 -0
  13. package/dist/core.d.ts +6 -0
  14. package/dist/data-types.d.ts +150 -0
  15. package/dist/dictionary.d.ts +263 -0
  16. package/dist/engines.d.ts +558 -0
  17. package/dist/expressions.d.ts +72 -0
  18. package/dist/external.d.ts +177 -0
  19. package/dist/index.d.ts +187 -0
  20. package/dist/index.js +222 -0
  21. package/dist/logger.d.ts +8 -0
  22. package/dist/materialized-views.d.ts +271 -0
  23. package/dist/metadata.d.ts +33 -0
  24. package/dist/modules/aggregates.d.ts +205 -0
  25. package/dist/modules/array.d.ts +122 -0
  26. package/dist/modules/conditional.d.ts +110 -0
  27. package/dist/modules/conversion.d.ts +189 -0
  28. package/dist/modules/geo.d.ts +202 -0
  29. package/dist/modules/hash.d.ts +7 -0
  30. package/dist/modules/index.d.ts +12 -0
  31. package/dist/modules/json.d.ts +130 -0
  32. package/dist/modules/math.d.ts +28 -0
  33. package/dist/modules/string.d.ts +167 -0
  34. package/dist/modules/time.d.ts +154 -0
  35. package/dist/modules/types.d.ts +177 -0
  36. package/dist/modules/window.d.ts +27 -0
  37. package/dist/relational.d.ts +33 -0
  38. package/dist/relations.d.ts +15 -0
  39. package/dist/schema-builder.d.ts +172 -0
  40. package/dist/table.d.ts +172 -0
  41. package/dist/utils/background-batcher.d.ts +20 -0
  42. package/dist/utils/batch-transform.d.ts +20 -0
  43. package/dist/utils/binary-reader.d.ts +48 -0
  44. package/dist/utils/binary-serializer.d.ts +160 -0
  45. package/dist/utils/binary-worker-code.d.ts +1 -0
  46. package/dist/utils/binary-worker-pool.d.ts +76 -0
  47. package/dist/utils/binary-worker.d.ts +12 -0
  48. package/dist/utils/insert-processing.d.ts +23 -0
  49. package/dist/utils/lru-cache.d.ts +10 -0
  50. package/package.json +68 -0
@@ -0,0 +1,352 @@
1
+ import type { ClickHouseClient } from '@clickhouse/client';
2
+ import { ClickHouseColumn, type TableDefinition, type TableOptions } from '../core';
3
+ import { type SQLExpression } from '../expressions';
4
+ import { type QueryBuilderState, type SelectionShape, type SelectResult, type ResultWithArrayJoin, type InferQueryResult } from './select.types';
5
+ export type { QueryBuilderState, SelectionShape, SelectResult } from './select.types';
6
+ export type InferQueryResultFromBuilder<TBuilder extends ClickHouseQueryBuilder<any, any, any>> = TBuilder extends ClickHouseQueryBuilder<any, any, infer TResult> ? TResult : never;
7
+ type StandardJoinType = 'INNER' | 'LEFT' | 'RIGHT' | 'FULL' | 'CROSS';
8
+ export declare class ClickHouseQueryBuilder<TTable extends TableDefinition<any> | null = null, TSelection extends SelectionShape | null = null, TResult = InferQueryResult<TTable, TSelection>> {
9
+ private client;
10
+ private _select;
11
+ private _table;
12
+ private _prewhere;
13
+ private _sample;
14
+ private _settings;
15
+ private _distinct;
16
+ private _joins;
17
+ private _arrayJoins;
18
+ private _ctes;
19
+ private _where;
20
+ private _limit;
21
+ private _offset;
22
+ private _orderBy;
23
+ private _groupBy;
24
+ private _having;
25
+ private _final;
26
+ private _windows;
27
+ private _suggestions;
28
+ constructor(client: ClickHouseClient);
29
+ select<TNewSelection extends SelectionShape>(fields: TNewSelection): ClickHouseQueryBuilder<TTable, TNewSelection, InferQueryResult<TTable, TNewSelection>>;
30
+ select(): ClickHouseQueryBuilder<TTable, null, InferQueryResult<TTable, null>>;
31
+ from<TNewTable extends TableDefinition<any>>(table: TNewTable): ClickHouseQueryBuilder<TNewTable, TSelection, InferQueryResult<TNewTable, TSelection>>;
32
+ from<TSubQuery extends ClickHouseQueryBuilder<any, any, any>>(subquery: TSubQuery, alias?: string): ClickHouseQueryBuilder<any, TSelection, any>;
33
+ private fromSubquery;
34
+ where(expression: SQLExpression | undefined | null): this;
35
+ orderBy(col: ClickHouseColumn | SQLExpression | {
36
+ col: ClickHouseColumn | SQLExpression;
37
+ dir: 'ASC' | 'DESC';
38
+ }, dir?: 'ASC' | 'DESC'): this;
39
+ groupBy(...cols: (ClickHouseColumn | SQLExpression)[]): this;
40
+ having(expression: SQLExpression): this;
41
+ limit(val: number): this;
42
+ offset(val: number): this;
43
+ distinct(): this;
44
+ innerJoin(table: {
45
+ $table: string;
46
+ }, on: SQLExpression): this;
47
+ leftJoin(table: {
48
+ $table: string;
49
+ }, on: SQLExpression): this;
50
+ rightJoin(table: {
51
+ $table: string;
52
+ }, on: SQLExpression): this;
53
+ fullJoin(table: {
54
+ $table: string;
55
+ }, on: SQLExpression): this;
56
+ /**
57
+ * CROSS JOIN - Cartesian product of two tables
58
+ * Use with caution on large tables!
59
+ */
60
+ crossJoin(table: {
61
+ $table: string;
62
+ }): this;
63
+ /**
64
+ * GLOBAL JOIN - Essential for distributed ClickHouse clusters.
65
+ *
66
+ * In a cluster, the right table is sent to all nodes where the left table exists.
67
+ * Without GLOBAL, each node only sees its local data, leading to incomplete results.
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * // For distributed tables, use GLOBAL to ensure complete results
72
+ * db.select().from(events).globalJoin('LEFT', users, eq(events.user_id, users.id))
73
+ * ```
74
+ */
75
+ globalJoin(type: StandardJoinType, table: {
76
+ $table: string;
77
+ }, on: SQLExpression): this;
78
+ /**
79
+ * Global INNER JOIN shorthand
80
+ */
81
+ globalInnerJoin(table: {
82
+ $table: string;
83
+ }, on: SQLExpression): this;
84
+ /**
85
+ * Global LEFT JOIN shorthand
86
+ */
87
+ globalLeftJoin(table: {
88
+ $table: string;
89
+ }, on: SQLExpression): this;
90
+ /**
91
+ * ANY JOIN - Returns first matching row from right table.
92
+ *
93
+ * Faster than ALL JOIN but may be non-deterministic if multiple rows match.
94
+ * Excellent for lookup tables where you know there's only one match.
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * // When user_id is unique in users table, ANY is faster
99
+ * db.select().from(events).anyJoin('LEFT', users, eq(events.user_id, users.id))
100
+ * ```
101
+ */
102
+ anyJoin(type: StandardJoinType, table: {
103
+ $table: string;
104
+ }, on: SQLExpression): this;
105
+ /**
106
+ * ANY INNER JOIN shorthand
107
+ */
108
+ anyInnerJoin(table: {
109
+ $table: string;
110
+ }, on: SQLExpression): this;
111
+ /**
112
+ * ANY LEFT JOIN shorthand
113
+ */
114
+ anyLeftJoin(table: {
115
+ $table: string;
116
+ }, on: SQLExpression): this;
117
+ /**
118
+ * ALL JOIN - Returns all matching rows (default SQL behavior).
119
+ * Explicitly stating ALL can be useful for clarity.
120
+ */
121
+ allJoin(type: StandardJoinType, table: {
122
+ $table: string;
123
+ }, on: SQLExpression): this;
124
+ /**
125
+ * ASOF JOIN - Time-series join that finds closest match.
126
+ *
127
+ * Essential for financial data, IoT, and logs where exact timestamp matches are rare.
128
+ * Finds the row with the closest (less-than-or-equal) value in the ordered column.
129
+ *
130
+ * The ON condition should include an inequality on an ordered column.
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * // Find the closest price quote for each trade
135
+ * db.select()
136
+ * .from(trades)
137
+ * .asofJoin(quotes, sql`${trades.symbol} = ${quotes.symbol} AND ${trades.timestamp} >= ${quotes.timestamp}`)
138
+ * ```
139
+ */
140
+ asofJoin(table: {
141
+ $table: string;
142
+ }, on: SQLExpression): this;
143
+ /**
144
+ * ASOF INNER JOIN - Same as ASOF but only returns matching rows
145
+ */
146
+ asofInnerJoin(table: {
147
+ $table: string;
148
+ }, on: SQLExpression): this;
149
+ /**
150
+ * SEMI JOIN - Returns rows from left table that have at least one match in right.
151
+ *
152
+ * Unlike regular JOIN, doesn't duplicate rows and doesn't include right table columns.
153
+ * More efficient than EXISTS subquery.
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * // Get all users who have at least one order
158
+ * db.select().from(users).semiJoin(orders, eq(users.id, orders.user_id))
159
+ * ```
160
+ */
161
+ semiJoin(table: {
162
+ $table: string;
163
+ }, on: SQLExpression): this;
164
+ /**
165
+ * ANTI JOIN - Returns rows from left table that have NO matches in right.
166
+ *
167
+ * More efficient than NOT EXISTS subquery.
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * // Get all users who have never placed an order
172
+ * db.select().from(users).antiJoin(orders, eq(users.id, orders.user_id))
173
+ * ```
174
+ */
175
+ antiJoin(table: {
176
+ $table: string;
177
+ }, on: SQLExpression): this;
178
+ /**
179
+ * GLOBAL ASOF JOIN - For time-series joins across distributed clusters
180
+ */
181
+ globalAsofJoin(table: {
182
+ $table: string;
183
+ }, on: SQLExpression): this;
184
+ /**
185
+ * GLOBAL ANY JOIN - Combines GLOBAL (for clusters) with ANY (for performance)
186
+ */
187
+ globalAnyJoin(type: StandardJoinType, table: {
188
+ $table: string;
189
+ }, on: SQLExpression): this;
190
+ arrayJoin<TCol extends ClickHouseColumn, TColName extends keyof TResult>(column: TCol & {
191
+ name: TColName;
192
+ }, ...additionalColumns: (ClickHouseColumn | SQLExpression)[]): ClickHouseQueryBuilder<TTable, TSelection, ResultWithArrayJoin<TResult, TColName>>;
193
+ arrayJoinMultiple<TColumns extends (ClickHouseColumn | SQLExpression)[]>(...columns: TColumns): ClickHouseQueryBuilder<TTable, TSelection, TResult>;
194
+ arrayJoinAs(column: ClickHouseColumn | SQLExpression, alias: string): ClickHouseQueryBuilder<TTable, TSelection, any>;
195
+ with(name: string, query: ClickHouseQueryBuilder<any>): this;
196
+ prewhere(expression: SQLExpression): this;
197
+ sample(ratio: number, offset?: number): this;
198
+ /**
199
+ * Define a typed CTE and get a virtual table for use in FROM/JOIN with autocomplete.
200
+ * Also registers the CTE on this builder; use register() to attach to another builder if needed.
201
+ */
202
+ $with<TAlias extends string, TSelection extends SelectionShape | null>(alias: TAlias, queryBuilder: ClickHouseQueryBuilder<any, TSelection>): {
203
+ cteTable: {
204
+ $table: string;
205
+ $columns: TSelection extends SelectionShape ? { [K in keyof (TSelection extends infer T ? T extends TSelection ? T extends SelectionShape ? SelectResult<T> : Record<string, any> : never : never)]: ClickHouseColumn<(TSelection extends infer T_1 ? T_1 extends TSelection ? T_1 extends SelectionShape ? SelectResult<T_1> : Record<string, any> : never : never)[K], true, false>; } : Record<string, ClickHouseColumn<any, true, false>>;
206
+ $options: TableOptions & {
207
+ kind: "cte";
208
+ query?: string;
209
+ };
210
+ $relations?: Record<string, import("../table").RelationDefinition>;
211
+ toSQL(): string;
212
+ toSQLs?(): string[];
213
+ as(alias: string): TableDefinition<TSelection extends SelectionShape ? { [K in keyof (TSelection extends infer T_1 ? T_1 extends TSelection ? T_1 extends SelectionShape ? SelectResult<T_1> : Record<string, any> : never : never)]: ClickHouseColumn<(TSelection extends infer T_2 ? T_2 extends TSelection ? T_2 extends SelectionShape ? SelectResult<T_2> : Record<string, any> : never : never)[K], true, false>; } : Record<string, ClickHouseColumn<any, true, false>>, TableOptions & {
214
+ kind: "cte";
215
+ query?: string;
216
+ }>;
217
+ $inferSelect?: import("../table").InferSelectModel<{
218
+ $columns: TSelection extends SelectionShape ? { [K in keyof (TSelection extends infer T_1 ? T_1 extends TSelection ? T_1 extends SelectionShape ? SelectResult<T_1> : Record<string, any> : never : never)]: ClickHouseColumn<(TSelection extends infer T_2 ? T_2 extends TSelection ? T_2 extends SelectionShape ? SelectResult<T_2> : Record<string, any> : never : never)[K], true, false>; } : Record<string, ClickHouseColumn<any, true, false>>;
219
+ }> | undefined;
220
+ $inferInsert?: import("../table").InferInsertModel<{
221
+ $columns: TSelection extends SelectionShape ? { [K in keyof (TSelection extends infer T_2 ? T_2 extends TSelection ? T_2 extends SelectionShape ? SelectResult<T_2> : Record<string, any> : never : never)]: ClickHouseColumn<(TSelection extends infer T_3 ? T_3 extends TSelection ? T_3 extends SelectionShape ? SelectResult<T_3> : Record<string, any> : never : never)[K], true, false>; } : Record<string, ClickHouseColumn<any, true, false>>;
222
+ }> | undefined;
223
+ } & (TSelection extends SelectionShape ? { [K in keyof (TSelection extends infer T_3 ? T_3 extends TSelection ? T_3 extends SelectionShape ? SelectResult<T_3> : Record<string, any> : never : never)]: ClickHouseColumn<(TSelection extends infer T_4 ? T_4 extends TSelection ? T_4 extends SelectionShape ? SelectResult<T_4> : Record<string, any> : never : never)[K], true, false>; } : Record<string, ClickHouseColumn<any, true, false>>);
224
+ register: (mainQuery: ClickHouseQueryBuilder<any, any, any>) => ClickHouseQueryBuilder<any, any, any>;
225
+ };
226
+ final(): this;
227
+ window(name: string, definition: string): this;
228
+ settings(settings: Record<string, string | number | boolean>): this;
229
+ private createSubqueryTable;
230
+ getState(): QueryBuilderState<ClickHouseQueryBuilder<any>>;
231
+ toSQL(): {
232
+ query: string;
233
+ params: Record<string, unknown>;
234
+ suggestions: string[];
235
+ };
236
+ then<TResult1 = TResult[], TResult2 = never>(onfulfilled?: ((value: TResult[]) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
237
+ /**
238
+ * Native streaming support.
239
+ * Iterate over results row-by-row without loading everything into memory.
240
+ * Prevents OOM on large datasets.
241
+ *
242
+ * @example
243
+ * for await (const row of db.select().from(logs)) {
244
+ * process(row);
245
+ * }
246
+ */
247
+ [Symbol.asyncIterator](): AsyncIterableIterator<TResult>;
248
+ /**
249
+ * Explicit alias for streaming
250
+ */
251
+ stream(): AsyncIterableIterator<TResult>;
252
+ /**
253
+ * Native binary mode for high-performance data retrieval.
254
+ * Reads data using ClickHouse 'RowBinary' format and parses it directly in Node.js.
255
+ * Up to 10x faster than standard JSON select for large datasets.
256
+ *
257
+ * Requirements: All selected columns must be strictly typed (ClickHouseColumn instances).
258
+ */
259
+ native(): Promise<TResult[]>;
260
+ /**
261
+ * Vector mode for columnar data retrieval.
262
+ * Returns data in Columnar format (TypedArrays) instead of Row-based objects.
263
+ * Ideal for analytical processing, charting, or passing to libraries like Apache Arrow.
264
+ *
265
+ * @example
266
+ * const { prices } = await db.select({ prices: trades.price }).vector();
267
+ * // prices is a Float64Array
268
+ */
269
+ vector(): Promise<{
270
+ [K in keyof TResult]: TResult[K] extends number ? (TResult[K] extends number ? Float64Array | Int32Array : Array<TResult[K]>) : Array<TResult[K]>;
271
+ }>;
272
+ private executeBinary;
273
+ explain(): Promise<any>;
274
+ explainPipeline(): Promise<any>;
275
+ /**
276
+ * Find first record (limit 1)
277
+ * @returns First record or null if no records found
278
+ */
279
+ findFirst(): Promise<TResult | null>;
280
+ /**
281
+ * Find unique record (limit 1, expects exactly one record)
282
+ * @returns Record if found, null if no records found
283
+ * @throws If multiple records found (shouldn't happen with limit 1)
284
+ */
285
+ findUnique(): Promise<TResult | null>;
286
+ /**
287
+ * Find many records with pagination
288
+ * @param options - Pagination options
289
+ */
290
+ findMany(options?: {
291
+ limit?: number;
292
+ offset?: number;
293
+ }): Promise<TResult[]>;
294
+ /**
295
+ * Find many records with cursor-based pagination
296
+ * @param options - Cursor pagination options
297
+ */
298
+ findManyCursor(options?: {
299
+ limit?: number;
300
+ cursor?: {
301
+ column: ClickHouseColumn | SQLExpression;
302
+ value: any;
303
+ direction?: 'ASC' | 'DESC';
304
+ };
305
+ }): Promise<TResult[]>;
306
+ /**
307
+ * Count records with optional where clause
308
+ * @param table - Table to count from (optional if already set)
309
+ * @param options - Count options
310
+ */
311
+ count(table?: TableDefinition<any>, options?: {
312
+ where?: SQLExpression;
313
+ }): Promise<number>;
314
+ /**
315
+ * Check if any records exist
316
+ * @param options - Existence check options
317
+ */
318
+ exists(options?: {
319
+ where?: SQLExpression;
320
+ }): Promise<boolean>;
321
+ /**
322
+ * Get paginated results with metadata
323
+ * @param options - Pagination options
324
+ */
325
+ findManyWithMeta(options?: {
326
+ limit?: number;
327
+ offset?: number;
328
+ includeTotal?: boolean;
329
+ }): Promise<{
330
+ data: TResult[];
331
+ total?: number;
332
+ hasMore?: boolean;
333
+ }>;
334
+ /**
335
+ * Find records and return as a Map keyed by specified column
336
+ * @param keyColumn - Column to use as key
337
+ * @param options - Query options
338
+ */
339
+ findAsMap<K extends string | number>(keyColumn: ClickHouseColumn | SQLExpression, options?: {
340
+ limit?: number;
341
+ offset?: number;
342
+ }): Promise<Map<K, TResult>>;
343
+ /**
344
+ * Find records and return as a grouped object
345
+ * @param groupColumn - Column to group by
346
+ * @param options - Query options
347
+ */
348
+ findGrouped<G extends string | number>(groupColumn: ClickHouseColumn | SQLExpression, options?: {
349
+ limit?: number;
350
+ offset?: number;
351
+ }): Promise<Record<G, TResult[]>>;
352
+ }
@@ -0,0 +1,76 @@
1
+ import type { ClickHouseColumn, TableDefinition, TableRow } from '../core';
2
+ import type { SQLExpression } from '../expressions';
3
+ export type SelectionShape = Record<string, ClickHouseColumn | SQLExpression>;
4
+ type AliasKey<TValue, TFallback extends PropertyKey> = TValue extends {
5
+ _alias: infer TAlias extends string;
6
+ } ? TAlias : TFallback;
7
+ export type SelectResult<TSelection extends SelectionShape> = {
8
+ [K in keyof TSelection as AliasKey<TSelection[K], K & string>]: TSelection[K] extends ClickHouseColumn<infer V, infer NotNull, any> ? NotNull extends true ? V : V | null : TSelection[K] extends SQLExpression<infer TExpr> ? TExpr : never;
9
+ };
10
+ export type Prettify<T> = {
11
+ [K in keyof T]: T[K];
12
+ } & {};
13
+ export type InferQueryResult<TTable, TSelection> = [
14
+ TSelection
15
+ ] extends [null] | [undefined] ? TTable extends {
16
+ $columns: infer TCols extends Record<string, any>;
17
+ } ? TableRow<TCols> : any : TSelection extends SelectionShape ? Prettify<SelectResult<TSelection>> : TTable extends {
18
+ $columns: infer TCols extends Record<string, any>;
19
+ } ? TableRow<TCols> : any;
20
+ export type NextResultForSelection<TTable, TSelection, TResult, TNextSelection> = [
21
+ TResult
22
+ ] extends [InferQueryResult<TTable, TSelection>] ? InferQueryResult<TTable, TNextSelection> : TResult;
23
+ export type NextResultForTable<TTable, TSelection, TResult, TNextTable> = [
24
+ TResult
25
+ ] extends [InferQueryResult<TTable, TSelection>] ? InferQueryResult<TNextTable, TSelection> : TResult;
26
+ export type QueryBuilderState<TCte = any> = {
27
+ select: SelectionShape | null;
28
+ table: TableDefinition<any> | null;
29
+ prewhere: SQLExpression | null;
30
+ sample: {
31
+ ratio: number;
32
+ offset?: number;
33
+ } | null;
34
+ settings: Record<string, string | number | boolean> | null;
35
+ distinct: boolean;
36
+ joins: Array<{
37
+ type: string;
38
+ table: string;
39
+ on: SQLExpression | null;
40
+ }>;
41
+ arrayJoins: Array<{
42
+ column: ClickHouseColumn | SQLExpression;
43
+ alias?: string;
44
+ }>;
45
+ ctes: Array<{
46
+ name: string;
47
+ query: TCte;
48
+ }>;
49
+ where: SQLExpression | null;
50
+ limit: number | null;
51
+ offset: number | null;
52
+ orderBy: {
53
+ col: ClickHouseColumn | SQLExpression;
54
+ dir: 'ASC' | 'DESC';
55
+ }[];
56
+ groupBy: (ClickHouseColumn | SQLExpression)[];
57
+ having: SQLExpression | null;
58
+ final: boolean;
59
+ windows: Record<string, string>;
60
+ suggestions: string[];
61
+ };
62
+ export type ArrayElementType<T> = T extends Array<infer U> ? U : T;
63
+ export type ArrayJoinResult<TResult, TArrayJoinColumns extends (keyof TResult)[]> = {
64
+ [K in keyof TResult]: K extends TArrayJoinColumns[number] ? ArrayElementType<TResult[K]> : TResult[K];
65
+ };
66
+ export type UnwrapArray<T> = T extends Array<infer U> ? U : T;
67
+ export type ResultWithArrayJoin<TResult, TColumnName extends keyof TResult> = {
68
+ [K in keyof TResult]: K extends TColumnName ? UnwrapArray<TResult[K]> : TResult[K];
69
+ };
70
+ export type ResultWithMultipleArrayJoins<TResult, TColumnNames extends (keyof TResult)[]> = {
71
+ [K in keyof TResult]: K extends TColumnNames[number] ? UnwrapArray<TResult[K]> : TResult[K];
72
+ };
73
+ export type SubqueryToTable<TResult> = TableDefinition<{
74
+ [K in keyof TResult & string]: ClickHouseColumn<TResult[K]>;
75
+ }>;
76
+ export {};
@@ -0,0 +1,23 @@
1
+ import type { ClickHouseClient } from '@clickhouse/client';
2
+ import type { SQLExpression } from '../expressions';
3
+ import { type TableDefinition, type TableColumns } from '../core';
4
+ export declare class ClickHouseUpdateBuilder<TTable extends TableDefinition<TableColumns>> {
5
+ private client;
6
+ private table;
7
+ private _set;
8
+ private _where;
9
+ private _lastMutationId;
10
+ constructor(client: ClickHouseClient, table: TTable);
11
+ set(values: Record<string, any>): this;
12
+ where(expression: SQLExpression): this;
13
+ toSQL(): {
14
+ query: string;
15
+ params: Record<string, unknown>;
16
+ };
17
+ execute(): Promise<void>;
18
+ wait(options?: {
19
+ pollIntervalMs?: number;
20
+ timeoutMs?: number;
21
+ }): Promise<void>;
22
+ then<TResult1 = void, TResult2 = never>(onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
23
+ }
@@ -0,0 +1,52 @@
1
+ import type { ClickHouseClient, ClickHouseClientConfigOptions } from '@clickhouse/client';
2
+ import { ClickHouseQueryBuilder } from './builders/select';
3
+ import { ClickHouseInsertBuilder } from './builders/insert';
4
+ import { ClickHouseDeleteBuilder } from './builders/delete';
5
+ import { ClickHouseUpdateBuilder } from './builders/update';
6
+ import { type TableDefinition, type TableColumns, type TableInsert } from './core';
7
+ import { type HousekitLogger } from './logger';
8
+ import { type RelationalFindOptions } from './relational';
9
+ export type HousekitClientConfig = ClickHouseClientConfigOptions & {
10
+ schema?: Record<string, TableDefinition<any>>;
11
+ logger?: HousekitLogger;
12
+ };
13
+ export type ClientConfigWithSchema = HousekitClientConfig;
14
+ export interface HousekitClient<TSchema extends Record<string, TableDefinition<any>> | undefined = any> {
15
+ rawClient: ClickHouseClient;
16
+ select: <T extends Record<string, any> | TableDefinition<any>>(fieldsOrTable?: T) => any;
17
+ with: (name: string, query: ClickHouseQueryBuilder<any>) => ClickHouseQueryBuilder<any>;
18
+ insert: <TCols extends TableColumns>(table: TableDefinition<TCols>) => ClickHouseInsertBuilder<any>;
19
+ insertMany: <TCols extends TableColumns>(table: TableDefinition<TCols>, values: Array<TableInsert<TCols>> | Iterable<TableInsert<TCols>> | AsyncIterable<TableInsert<TCols>>, opts?: {
20
+ maxBlockSize?: number;
21
+ asyncInsertWait?: boolean;
22
+ }) => Promise<void>;
23
+ update: <TCols extends TableColumns>(table: TableDefinition<TCols>) => ClickHouseUpdateBuilder<any>;
24
+ delete: <TCols extends TableColumns>(table: TableDefinition<TCols>) => ClickHouseDeleteBuilder<any>;
25
+ command: (params: {
26
+ query: string;
27
+ query_params?: Record<string, unknown>;
28
+ format?: string;
29
+ }) => Promise<any>;
30
+ raw: (query: string, params?: Record<string, unknown>) => Promise<any>;
31
+ tableExists: (tableName: string) => Promise<boolean>;
32
+ ensureTable: (table: {
33
+ $table: string;
34
+ toSQL: () => string;
35
+ }) => Promise<void>;
36
+ dropTable: (tableName: string, options?: {
37
+ ifExists?: boolean;
38
+ }) => Promise<void>;
39
+ close: () => Promise<void>;
40
+ schema: TSchema;
41
+ _config: HousekitClientConfig;
42
+ query: TSchema extends Record<string, TableDefinition<any>> ? {
43
+ [K in keyof TSchema]: {
44
+ findMany: (opts?: RelationalFindOptions) => Promise<any[]>;
45
+ findFirst: (opts?: RelationalFindOptions) => Promise<any | null>;
46
+ };
47
+ } : undefined;
48
+ }
49
+ export declare function createHousekitClient<TSchema extends Record<string, TableDefinition<any>> | undefined = any>(config: HousekitClientConfig & {
50
+ schema?: TSchema;
51
+ }): HousekitClient<TSchema>;
52
+ export declare const createClientFromConfigObject: typeof createHousekitClient;
@@ -0,0 +1,4 @@
1
+ import { z } from 'zod';
2
+ import { TableDefinition, TableColumns } from '../table';
3
+ export declare function generateSelectSchema<TCols extends TableColumns>(table: TableDefinition<TCols>): z.ZodObject<any>;
4
+ export declare function generateInsertSchema<TCols extends TableColumns>(table: TableDefinition<TCols>): z.ZodObject<any>;
@@ -0,0 +1,76 @@
1
+ export type ColumnMeta = {
2
+ isJson?: boolean;
3
+ enumValues?: readonly string[];
4
+ autoGenerate?: {
5
+ type: 'uuid';
6
+ version?: 1 | 3 | 4 | 5 | 6 | 7;
7
+ };
8
+ isPrimaryKey?: boolean;
9
+ default?: any;
10
+ defaultFn?: (row: Record<string, any>) => any;
11
+ references?: {
12
+ table: string;
13
+ column: string;
14
+ onDelete?: 'cascade' | 'set null' | 'restrict' | 'no action';
15
+ onUpdate?: 'cascade' | 'set null' | 'restrict' | 'no action';
16
+ };
17
+ codec?: string;
18
+ materialized?: string;
19
+ alias?: string;
20
+ defaultExpr?: string;
21
+ comment?: string;
22
+ };
23
+ export declare class ClickHouseColumn<TType = any, TNotNull extends boolean = true, TAutoGenerated extends boolean = false> {
24
+ name: string;
25
+ type: string;
26
+ isNull: boolean;
27
+ meta?: ColumnMeta | undefined;
28
+ tableName?: string;
29
+ constructor(name: string, type: string, isNull?: boolean, // Columns are NOT NULL by default (isNull = false)
30
+ meta?: ColumnMeta | undefined);
31
+ clone<NTNotNull extends boolean = TNotNull, NAutoGenerated extends boolean = TAutoGenerated>(overrides?: {
32
+ name?: string;
33
+ type?: string;
34
+ isNull?: boolean;
35
+ meta?: ColumnMeta;
36
+ }): ClickHouseColumn<TType, NTNotNull, NAutoGenerated>;
37
+ notNull(): ClickHouseColumn<TType, true, TAutoGenerated>;
38
+ nullable(): ClickHouseColumn<TType, false, TAutoGenerated>;
39
+ autoGenerate(options?: {
40
+ version?: 1 | 3 | 4 | 5 | 6 | 7;
41
+ }): ClickHouseColumn<TType, TNotNull, true>;
42
+ primaryKey(): ClickHouseColumn<TType, true, TAutoGenerated>;
43
+ /**
44
+ * Define a default value for the column.
45
+ * Can be a static value or a SQL expression like 'now()'.
46
+ */
47
+ default(value: any): ClickHouseColumn<TType, TNotNull, TAutoGenerated>;
48
+ references(getColumn: () => ClickHouseColumn, options?: {
49
+ onDelete?: 'cascade' | 'set null' | 'restrict' | 'no action';
50
+ onUpdate?: 'cascade' | 'set null' | 'restrict' | 'no action';
51
+ }): ClickHouseColumn<TType, TNotNull, TAutoGenerated>;
52
+ /**
53
+ * Add a comment to the column in the database.
54
+ */
55
+ comment(text: string): ClickHouseColumn<TType, TNotNull, TAutoGenerated>;
56
+ alias(expression: string): ClickHouseColumn<TType, TNotNull, TAutoGenerated>;
57
+ /**
58
+ * Apply a compression codec to this column.
59
+ * Can be chained to apply multiple codecs (e.g., Delta then ZSTD).
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * // Optimize for time-series
64
+ * timestamp.codec('DoubleDelta').codec('ZSTD', 3)
65
+ * // Optimize for metrics
66
+ * value.codec('Gorilla')
67
+ * ```
68
+ */
69
+ codec(type: 'ZSTD' | 'LZ4' | 'Delta' | 'DoubleDelta' | 'Gorilla' | 'None', level?: number): ClickHouseColumn<TType, TNotNull, TAutoGenerated>;
70
+ /**
71
+ * Calculates the column value on the client side before insertion.
72
+ * Useful for UUIDs, hashes, or computations based on other fields.
73
+ */
74
+ $defaultFn(fn: (row: Record<string, any>) => any): ClickHouseColumn<TType, TNotNull, TAutoGenerated>;
75
+ toSQL(): string;
76
+ }
@@ -0,0 +1,27 @@
1
+ import type { QueryBuilderState } from './builders/select.types';
2
+ import { PreparedQuery } from './builders/prepared';
3
+ export declare class QueryCompiler {
4
+ private paramCounter;
5
+ reset(): void;
6
+ private getNextParamName;
7
+ /**
8
+ * Compile with caching support.
9
+ * Returns a PreparedQuery ready for execution and the values to bind.
10
+ */
11
+ compileWithCache(state: QueryBuilderState, client: any): {
12
+ cachedQuery: PreparedQuery<any>;
13
+ values: any[];
14
+ };
15
+ /**
16
+ * Legacy/Internal method for getting SQL + Params directly (used by toSQL)
17
+ */
18
+ compileSelect(state: QueryBuilderState): {
19
+ sql: string;
20
+ params: Record<string, unknown>;
21
+ suggestions: string[];
22
+ };
23
+ private generateFingerprint;
24
+ private performFullCompilation;
25
+ private formatColumn;
26
+ private resolveColumn;
27
+ }
package/dist/core.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from './column';
2
+ export * from './table';
3
+ export * from './engines';
4
+ export * from './materialized-views';
5
+ export * from './dictionary';
6
+ export * from './external';