@housekit/orm 0.1.18 → 0.1.21
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/README.md +19 -6
- package/dist/builders/delete.d.ts +2 -2
- package/dist/builders/insert.d.ts +9 -4
- package/dist/builders/select.d.ts +10 -7
- package/dist/builders/update.d.ts +2 -2
- package/dist/client.d.ts +7 -12
- package/dist/index.d.ts +32 -3
- package/dist/index.js +417 -261
- package/dist/relational.d.ts +35 -3
- package/dist/relations.d.ts +7 -4
- package/dist/schema-builder.d.ts +36 -6
- package/dist/table.d.ts +31 -20
- package/dist/utils/background-batcher.d.ts +2 -2
- package/dist/utils/insert-processing.d.ts +2 -2
- package/package.json +1 -1
package/dist/relational.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
import { type TableDefinition } from './core';
|
|
1
|
+
import { type RelationDefinition, type TableDefinition, type CleanSelect } from './core';
|
|
2
2
|
import type { SQLExpression } from './expressions';
|
|
3
|
+
type Simplify<T> = {
|
|
4
|
+
[K in keyof T]: T[K];
|
|
5
|
+
} & {};
|
|
6
|
+
type RelationsOf<TTable> = TTable extends {
|
|
7
|
+
$relations: infer R;
|
|
8
|
+
} ? R : {};
|
|
9
|
+
type NormalizedRelations<TTable> = RelationsOf<TTable> extends Record<string, RelationDefinition<any>> ? RelationsOf<TTable> : {};
|
|
10
|
+
type RelationTarget<T> = T extends RelationDefinition<infer TTarget> ? TTarget : never;
|
|
3
11
|
/**
|
|
4
12
|
* Join strategy for relational queries.
|
|
5
13
|
*
|
|
@@ -10,6 +18,23 @@ export type JoinStrategy = 'auto' | 'standard' | 'global' | 'any' | 'global_any'
|
|
|
10
18
|
/**
|
|
11
19
|
* Configuration options for the Relational Query API (`findMany`, `findFirst`).
|
|
12
20
|
*/
|
|
21
|
+
export type RelationalWith<TTable> = [
|
|
22
|
+
keyof NormalizedRelations<TTable>
|
|
23
|
+
] extends [never] ? Record<string, boolean | RelationalFindOptions<any>> : {
|
|
24
|
+
[K in keyof NormalizedRelations<TTable>]?: boolean | RelationalFindOptions<RelationTarget<NormalizedRelations<TTable>[K]>>;
|
|
25
|
+
};
|
|
26
|
+
type NestedWith<T> = T extends RelationalFindOptions<any> ? T['with'] : undefined;
|
|
27
|
+
type RelationValue<TRel, TWith> = TRel extends {
|
|
28
|
+
relation: 'one';
|
|
29
|
+
table: infer TRelTable;
|
|
30
|
+
} ? RelationalResult<TRelTable, TWith> | null : TRel extends {
|
|
31
|
+
relation: 'many';
|
|
32
|
+
table: infer TRelTable;
|
|
33
|
+
} ? Array<RelationalResult<TRelTable, TWith>> : never;
|
|
34
|
+
type RelationValueForKey<TTable, K, TWithValue> = K extends keyof NormalizedRelations<TTable> ? TWithValue extends boolean ? RelationValue<NormalizedRelations<TTable>[K], undefined> : TWithValue extends RelationalFindOptions<any> ? RelationValue<NormalizedRelations<TTable>[K], NestedWith<TWithValue>> : never : any;
|
|
35
|
+
export type RelationalResult<TTable, TWith = undefined> = Simplify<CleanSelect<TTable> & (TWith extends RelationalWith<TTable> ? {
|
|
36
|
+
[K in keyof TWith]: RelationValueForKey<TTable, K, TWith[K]>;
|
|
37
|
+
} : {})>;
|
|
13
38
|
export type RelationalFindOptions<TTable = any> = {
|
|
14
39
|
/**
|
|
15
40
|
* Filter conditions for the main query.
|
|
@@ -32,7 +57,7 @@ export type RelationalFindOptions<TTable = any> = {
|
|
|
32
57
|
*
|
|
33
58
|
* @example with: { posts: { limit: 5 }, profile: true }
|
|
34
59
|
*/
|
|
35
|
-
with?:
|
|
60
|
+
with?: RelationalWith<TTable>;
|
|
36
61
|
/**
|
|
37
62
|
* Join strategy for related data.
|
|
38
63
|
*
|
|
@@ -46,6 +71,12 @@ export type RelationalFindOptions<TTable = any> = {
|
|
|
46
71
|
*/
|
|
47
72
|
joinStrategy?: JoinStrategy;
|
|
48
73
|
};
|
|
74
|
+
export type RelationalAPI<TSchema extends Record<string, TableDefinition<any>>> = {
|
|
75
|
+
[K in keyof TSchema]: {
|
|
76
|
+
findMany: <TOpts extends RelationalFindOptions<TSchema[K]> | undefined>(opts?: TOpts) => Promise<Array<RelationalResult<TSchema[K], TOpts extends RelationalFindOptions<TSchema[K]> ? TOpts['with'] : undefined>>>;
|
|
77
|
+
findFirst: <TOpts extends RelationalFindOptions<TSchema[K]> | undefined>(opts?: TOpts) => Promise<RelationalResult<TSchema[K], TOpts extends RelationalFindOptions<TSchema[K]> ? TOpts['with'] : undefined> | null>;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
49
80
|
/**
|
|
50
81
|
* Build a modern relational API with ClickHouse-specific optimizations.
|
|
51
82
|
*
|
|
@@ -58,4 +89,5 @@ export type RelationalFindOptions<TTable = any> = {
|
|
|
58
89
|
* @param client - The ClickHouse client instance.
|
|
59
90
|
* @param schema - The shared schema definition containing all table and relation metadata.
|
|
60
91
|
*/
|
|
61
|
-
export declare function buildRelationalAPI(client: any, schema?:
|
|
92
|
+
export declare function buildRelationalAPI<TSchema extends Record<string, TableDefinition<any>>>(client: any, schema?: TSchema): RelationalAPI<TSchema> | undefined;
|
|
93
|
+
export {};
|
package/dist/relations.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ClickHouseColumn, RelationDefinition, TableDefinition } from './core';
|
|
1
|
+
import type { ClickHouseColumn, RelationDefinition, TableColumns, TableDefinition } from './core';
|
|
2
2
|
type OneConfig = {
|
|
3
3
|
fields: ClickHouseColumn[];
|
|
4
4
|
references: ClickHouseColumn[];
|
|
@@ -8,8 +8,11 @@ type ManyConfig = {
|
|
|
8
8
|
references?: ClickHouseColumn[];
|
|
9
9
|
};
|
|
10
10
|
type RelationBuilderHelpers = {
|
|
11
|
-
one: (table:
|
|
12
|
-
many: (table:
|
|
11
|
+
one: <TTarget extends TableDefinition<TableColumns>>(table: TTarget, config: OneConfig) => RelationDefinition<TTarget>;
|
|
12
|
+
many: <TTarget extends TableDefinition<TableColumns>>(table: TTarget, config?: ManyConfig) => RelationDefinition<TTarget>;
|
|
13
13
|
};
|
|
14
|
-
export declare function relations<TTable extends TableDefinition<
|
|
14
|
+
export declare function relations<TTable extends TableDefinition<TableColumns>, TRelations extends Record<string, RelationDefinition<any>>>(table: TTable, callback: (helpers: RelationBuilderHelpers) => TRelations): asserts table is TTable & {
|
|
15
|
+
$relations: TRelations;
|
|
16
|
+
};
|
|
17
|
+
export declare function relations<TTable extends TableDefinition<TableColumns>, TRelations extends Record<string, RelationDefinition<any>>>(table: TTable, callback: (helpers: RelationBuilderHelpers) => TRelations): TRelations;
|
|
15
18
|
export {};
|
package/dist/schema-builder.d.ts
CHANGED
|
@@ -132,6 +132,24 @@ export declare const t: {
|
|
|
132
132
|
polygon: (name: string) => ClickHouseColumn<[number, number][][], true, false>;
|
|
133
133
|
multiPolygon: (name: string) => ClickHouseColumn<[number, number][][][], true, false>;
|
|
134
134
|
enum: (name: string, values: readonly string[]) => ClickHouseColumn<string, false, false>;
|
|
135
|
+
/**
|
|
136
|
+
* Adds 'created_at' and 'updated_at' columns with default now().
|
|
137
|
+
*/
|
|
138
|
+
timestamps: () => {
|
|
139
|
+
created_at: ClickHouseColumn<string | Date, true, false>;
|
|
140
|
+
updated_at: ClickHouseColumn<string | Date, true, false>;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Adds a standard UUID primary key column (default: 'id').
|
|
144
|
+
*/
|
|
145
|
+
primaryUuid: <TName extends string = "id">(name?: TName) => { [K in TName]: ClickHouseColumn<string>; };
|
|
146
|
+
/**
|
|
147
|
+
* Adds 'is_deleted' and 'deleted_at' columns for soft deletes.
|
|
148
|
+
*/
|
|
149
|
+
softDeletes: () => {
|
|
150
|
+
is_deleted: ClickHouseColumn<boolean, true, false>;
|
|
151
|
+
deleted_at: ClickHouseColumn<string | Date, false, false>;
|
|
152
|
+
};
|
|
135
153
|
};
|
|
136
154
|
export type ColumnBuilder = typeof t;
|
|
137
155
|
/**
|
|
@@ -160,13 +178,25 @@ export { chProjection as defineProjection };
|
|
|
160
178
|
/**
|
|
161
179
|
* Define relations for a table using a callback pattern.
|
|
162
180
|
*/
|
|
163
|
-
export declare function relations<TTable extends TableDefinition<any
|
|
164
|
-
one:
|
|
181
|
+
export declare function relations<TTable extends TableDefinition<any>, TRelations extends Record<string, RelationDefinition<any>>>(table: TTable, relationsBuilder: (helpers: {
|
|
182
|
+
one: <TTarget extends TableDefinition<any>>(table: TTarget, config: {
|
|
183
|
+
fields: ClickHouseColumn<any, any, any>[];
|
|
184
|
+
references: ClickHouseColumn<any, any, any>[];
|
|
185
|
+
}) => RelationDefinition<TTarget>;
|
|
186
|
+
many: <TTarget extends TableDefinition<any>>(table: TTarget, config?: {
|
|
187
|
+
fields?: ClickHouseColumn<any, any, any>[];
|
|
188
|
+
references?: ClickHouseColumn<any, any, any>[];
|
|
189
|
+
}) => RelationDefinition<TTarget>;
|
|
190
|
+
}) => TRelations): asserts table is TTable & {
|
|
191
|
+
$relations: TRelations;
|
|
192
|
+
};
|
|
193
|
+
export declare function relations<TTable extends TableDefinition<any>, TRelations extends Record<string, RelationDefinition<any>>>(table: TTable, relationsBuilder: (helpers: {
|
|
194
|
+
one: <TTarget extends TableDefinition<any>>(table: TTarget, config: {
|
|
165
195
|
fields: ClickHouseColumn<any, any, any>[];
|
|
166
196
|
references: ClickHouseColumn<any, any, any>[];
|
|
167
|
-
}) => RelationDefinition
|
|
168
|
-
many:
|
|
197
|
+
}) => RelationDefinition<TTarget>;
|
|
198
|
+
many: <TTarget extends TableDefinition<any>>(table: TTarget, config?: {
|
|
169
199
|
fields?: ClickHouseColumn<any, any, any>[];
|
|
170
200
|
references?: ClickHouseColumn<any, any, any>[];
|
|
171
|
-
}) => RelationDefinition
|
|
172
|
-
}) =>
|
|
201
|
+
}) => RelationDefinition<TTarget>;
|
|
202
|
+
}) => TRelations): TRelations;
|
package/dist/table.d.ts
CHANGED
|
@@ -53,16 +53,16 @@ export declare const index: (name: string) => {
|
|
|
53
53
|
};
|
|
54
54
|
};
|
|
55
55
|
export declare const projection: (name: string, query: string) => ProjectionDefinition;
|
|
56
|
-
export type RelationDefinition = {
|
|
56
|
+
export type RelationDefinition<TTarget extends TableDefinition<any> = TableDefinition<any>> = {
|
|
57
57
|
relation: 'one';
|
|
58
58
|
name: string;
|
|
59
|
-
table:
|
|
59
|
+
table: TTarget;
|
|
60
60
|
fields: ClickHouseColumn[];
|
|
61
61
|
references: ClickHouseColumn[];
|
|
62
62
|
} | {
|
|
63
63
|
relation: 'many';
|
|
64
64
|
name: string;
|
|
65
|
-
table:
|
|
65
|
+
table: TTarget;
|
|
66
66
|
fields?: ClickHouseColumn[];
|
|
67
67
|
references?: ClickHouseColumn[];
|
|
68
68
|
};
|
|
@@ -81,21 +81,21 @@ export type InferSelectModel<T extends {
|
|
|
81
81
|
};
|
|
82
82
|
export type InferInsertModel<T extends {
|
|
83
83
|
$columns: TableColumns;
|
|
84
|
-
}> = TableInsert<T['$columns']
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
$inferSelect
|
|
98
|
-
} ? S :
|
|
84
|
+
}> = TableInsert<T['$columns']>;
|
|
85
|
+
type InferInsertFromColumns<T> = T extends {
|
|
86
|
+
$columns: infer TCols extends TableColumns;
|
|
87
|
+
} ? TableInsert<TCols> : never;
|
|
88
|
+
type InferSelectFromColumns<T> = T extends {
|
|
89
|
+
$columns: infer TCols extends TableColumns;
|
|
90
|
+
} ? InferSelectModel<{
|
|
91
|
+
$columns: TCols;
|
|
92
|
+
}> : never;
|
|
93
|
+
export type CleanInsert<T> = T extends {
|
|
94
|
+
$inferInsert: infer I;
|
|
95
|
+
} ? I : InferInsertFromColumns<T>;
|
|
96
|
+
export type CleanSelect<T> = T extends {
|
|
97
|
+
$inferSelect: infer S;
|
|
98
|
+
} ? S : InferSelectFromColumns<T>;
|
|
99
99
|
export type InferInsertValue<TCols extends TableColumns, K extends keyof TCols> = TCols[K] extends ClickHouseColumn<infer Type, infer NotNull, any> ? NotNull extends true ? Type : Type | undefined | null : never;
|
|
100
100
|
export type TableInsertArray<T extends TableDefinition<TableColumns>> = T['$inferInsert'][];
|
|
101
101
|
export type TableModel<T extends TableDefinition<TableColumns>> = PublicSelectModel<T>;
|
|
@@ -112,13 +112,24 @@ export type TableDefinition<TCols extends TableColumns, TOptions = TableOptions>
|
|
|
112
112
|
toSQL(): string;
|
|
113
113
|
toSQLs?(): string[];
|
|
114
114
|
as(alias: string): TableDefinition<TCols, TOptions>;
|
|
115
|
-
$inferSelect
|
|
115
|
+
$inferSelect: InferSelectModel<{
|
|
116
116
|
$columns: TCols;
|
|
117
117
|
}>;
|
|
118
|
-
$inferInsert
|
|
118
|
+
$inferInsert: InferInsertModel<{
|
|
119
119
|
$columns: TCols;
|
|
120
120
|
}>;
|
|
121
121
|
} & TCols;
|
|
122
|
+
export type TableRuntime<TInsert = any, TSelect = any, TOptions = TableOptions> = {
|
|
123
|
+
$table: string;
|
|
124
|
+
$columns: TableColumns;
|
|
125
|
+
$options: TOptions;
|
|
126
|
+
$relations?: Record<string, RelationDefinition>;
|
|
127
|
+
toSQL(): string;
|
|
128
|
+
toSQLs?(): string[];
|
|
129
|
+
as(alias: string): TableRuntime<TInsert, TSelect, TOptions>;
|
|
130
|
+
$inferSelect: TSelect;
|
|
131
|
+
$inferInsert: TInsert;
|
|
132
|
+
};
|
|
122
133
|
export interface VersionedMeta {
|
|
123
134
|
baseName: string;
|
|
124
135
|
version: string | number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ClickHouseClient } from '@clickhouse/client';
|
|
2
|
-
import type {
|
|
2
|
+
import type { TableRuntime } from '../core';
|
|
3
3
|
export interface BatchConfig {
|
|
4
4
|
maxRows: number;
|
|
5
5
|
flushIntervalMs: number;
|
|
@@ -12,7 +12,7 @@ declare class BackgroundBatcher {
|
|
|
12
12
|
private serializers;
|
|
13
13
|
constructor(client: ClickHouseClient);
|
|
14
14
|
private getSerializer;
|
|
15
|
-
add(table:
|
|
15
|
+
add(table: TableRuntime<any, any>, row: any, config: BatchConfig): Promise<void>;
|
|
16
16
|
flush(tableName: string): Promise<void>;
|
|
17
17
|
flushAll(): Promise<void>;
|
|
18
18
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ClickHouseColumn, type
|
|
1
|
+
import { ClickHouseColumn, type TableRuntime } from '../core';
|
|
2
2
|
type UUIDVersion = 1 | 3 | 4 | 5 | 6 | 7;
|
|
3
3
|
type PreparedInsertColumn = {
|
|
4
4
|
propKey: string;
|
|
@@ -17,7 +17,7 @@ export type InsertPlan = {
|
|
|
17
17
|
columnNames: string[];
|
|
18
18
|
useCompact: boolean;
|
|
19
19
|
};
|
|
20
|
-
export declare function buildInsertPlan(table:
|
|
20
|
+
export declare function buildInsertPlan(table: TableRuntime<any, any>): InsertPlan;
|
|
21
21
|
export declare function processRowWithPlan(row: Record<string, any>, plan: InsertPlan, mode?: 'compact' | 'json'): Record<string, any> | any[];
|
|
22
22
|
export declare function processRowsStream(rows: AsyncIterable<Record<string, any>> | Iterable<Record<string, any>>, plan: InsertPlan, mode?: 'compact' | 'json'): AsyncGenerator<any[] | Record<string, any>, void, unknown>;
|
|
23
23
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@housekit/orm",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
4
4
|
"description": "Type-safe ClickHouse ORM with modern DX and ClickHouse-specific optimizations. Features Turbo Mode (RowBinary), full engine support, and advanced query capabilities.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|