@zhin.js/database 1.0.4 → 1.0.6

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 (115) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1360 -34
  3. package/lib/base/database.d.ts +71 -13
  4. package/lib/base/database.d.ts.map +1 -1
  5. package/lib/base/database.js +128 -4
  6. package/lib/base/database.js.map +1 -1
  7. package/lib/base/dialect.d.ts +27 -10
  8. package/lib/base/dialect.d.ts.map +1 -1
  9. package/lib/base/dialect.js +32 -0
  10. package/lib/base/dialect.js.map +1 -1
  11. package/lib/base/index.d.ts +1 -0
  12. package/lib/base/index.d.ts.map +1 -1
  13. package/lib/base/index.js +1 -0
  14. package/lib/base/index.js.map +1 -1
  15. package/lib/base/model.d.ts +105 -12
  16. package/lib/base/model.d.ts.map +1 -1
  17. package/lib/base/model.js +224 -3
  18. package/lib/base/model.js.map +1 -1
  19. package/lib/base/query-classes.d.ts +204 -33
  20. package/lib/base/query-classes.d.ts.map +1 -1
  21. package/lib/base/query-classes.js +276 -0
  22. package/lib/base/query-classes.js.map +1 -1
  23. package/lib/base/thenable.d.ts +7 -7
  24. package/lib/base/thenable.d.ts.map +1 -1
  25. package/lib/base/thenable.js +5 -4
  26. package/lib/base/thenable.js.map +1 -1
  27. package/lib/base/transaction.d.ts +46 -0
  28. package/lib/base/transaction.d.ts.map +1 -0
  29. package/lib/base/transaction.js +186 -0
  30. package/lib/base/transaction.js.map +1 -0
  31. package/lib/dialects/memory.d.ts +12 -7
  32. package/lib/dialects/memory.d.ts.map +1 -1
  33. package/lib/dialects/memory.js +7 -4
  34. package/lib/dialects/memory.js.map +1 -1
  35. package/lib/dialects/mongodb.d.ts +11 -7
  36. package/lib/dialects/mongodb.d.ts.map +1 -1
  37. package/lib/dialects/mongodb.js +18 -15
  38. package/lib/dialects/mongodb.js.map +1 -1
  39. package/lib/dialects/mysql.d.ts +35 -6
  40. package/lib/dialects/mysql.d.ts.map +1 -1
  41. package/lib/dialects/mysql.js +137 -18
  42. package/lib/dialects/mysql.js.map +1 -1
  43. package/lib/dialects/pg.d.ts +35 -6
  44. package/lib/dialects/pg.d.ts.map +1 -1
  45. package/lib/dialects/pg.js +137 -18
  46. package/lib/dialects/pg.js.map +1 -1
  47. package/lib/dialects/redis.d.ts +11 -6
  48. package/lib/dialects/redis.d.ts.map +1 -1
  49. package/lib/dialects/redis.js +11 -8
  50. package/lib/dialects/redis.js.map +1 -1
  51. package/lib/dialects/sqlite.d.ts +19 -6
  52. package/lib/dialects/sqlite.d.ts.map +1 -1
  53. package/lib/dialects/sqlite.js +63 -10
  54. package/lib/dialects/sqlite.js.map +1 -1
  55. package/lib/index.d.ts +1 -0
  56. package/lib/index.d.ts.map +1 -1
  57. package/lib/index.js +1 -0
  58. package/lib/index.js.map +1 -1
  59. package/lib/migration.d.ts +132 -0
  60. package/lib/migration.d.ts.map +1 -0
  61. package/lib/migration.js +475 -0
  62. package/lib/migration.js.map +1 -0
  63. package/lib/registry.d.ts +26 -23
  64. package/lib/registry.d.ts.map +1 -1
  65. package/lib/registry.js +1 -5
  66. package/lib/registry.js.map +1 -1
  67. package/lib/type/document/database.d.ts +11 -11
  68. package/lib/type/document/database.d.ts.map +1 -1
  69. package/lib/type/document/database.js.map +1 -1
  70. package/lib/type/document/model.d.ts +7 -7
  71. package/lib/type/document/model.d.ts.map +1 -1
  72. package/lib/type/document/model.js.map +1 -1
  73. package/lib/type/keyvalue/database.d.ts +11 -11
  74. package/lib/type/keyvalue/database.d.ts.map +1 -1
  75. package/lib/type/keyvalue/database.js.map +1 -1
  76. package/lib/type/keyvalue/model.d.ts +2 -2
  77. package/lib/type/keyvalue/model.d.ts.map +1 -1
  78. package/lib/type/keyvalue/model.js.map +1 -1
  79. package/lib/type/related/database.d.ts +48 -13
  80. package/lib/type/related/database.d.ts.map +1 -1
  81. package/lib/type/related/database.js +258 -27
  82. package/lib/type/related/database.js.map +1 -1
  83. package/lib/type/related/model.d.ts +251 -15
  84. package/lib/type/related/model.d.ts.map +1 -1
  85. package/lib/type/related/model.js +647 -22
  86. package/lib/type/related/model.js.map +1 -1
  87. package/lib/types.d.ts +475 -37
  88. package/lib/types.d.ts.map +1 -1
  89. package/lib/types.js +6 -0
  90. package/lib/types.js.map +1 -1
  91. package/package.json +14 -5
  92. package/src/base/database.ts +168 -24
  93. package/src/base/dialect.ts +49 -10
  94. package/src/base/index.ts +2 -1
  95. package/src/base/model.ts +258 -18
  96. package/src/base/query-classes.ts +471 -63
  97. package/src/base/thenable.ts +12 -11
  98. package/src/base/transaction.ts +213 -0
  99. package/src/dialects/memory.ts +14 -13
  100. package/src/dialects/mongodb.ts +40 -38
  101. package/src/dialects/mysql.ts +151 -22
  102. package/src/dialects/pg.ts +148 -21
  103. package/src/dialects/redis.ts +40 -38
  104. package/src/dialects/sqlite.ts +73 -15
  105. package/src/index.ts +1 -2
  106. package/src/migration.ts +544 -0
  107. package/src/registry.ts +33 -33
  108. package/src/type/document/database.ts +32 -32
  109. package/src/type/document/model.ts +14 -14
  110. package/src/type/keyvalue/database.ts +32 -32
  111. package/src/type/keyvalue/model.ts +18 -18
  112. package/src/type/related/database.ts +309 -34
  113. package/src/type/related/model.ts +800 -33
  114. package/src/types.ts +559 -44
  115. package/tests/database.test.ts +1738 -0
package/src/types.ts CHANGED
@@ -6,8 +6,22 @@ export type QueryType =
6
6
  | 'drop_index'
7
7
  | 'select'
8
8
  | 'insert'
9
+ | 'insert_many'
9
10
  | 'update'
10
- | 'delete';
11
+ | 'delete'
12
+ | 'aggregate';
13
+
14
+ // ============================================================================
15
+ // Aggregation Types
16
+ // ============================================================================
17
+
18
+ export type AggregateFunction = 'count' | 'sum' | 'avg' | 'min' | 'max';
19
+
20
+ export interface AggregateField<T extends object> {
21
+ fn: AggregateFunction;
22
+ field: keyof T | '*';
23
+ alias?: string;
24
+ }
11
25
 
12
26
  // ============================================================================
13
27
  // Column Type Definitions
@@ -35,6 +49,70 @@ export type Definition<T extends object=object> = {
35
49
  [P in keyof T]: Column<T[P]>;
36
50
  }
37
51
 
52
+ // ============================================================================
53
+ // Model Options
54
+ // ============================================================================
55
+
56
+ export interface ModelOptions {
57
+ /** 启用软删除(需要表中有 deletedAt 字段) */
58
+ softDelete?: boolean;
59
+ /** 软删除字段名,默认 'deletedAt' */
60
+ deletedAtField?: string;
61
+ /** 启用自动时间戳(createdAt, updatedAt) */
62
+ timestamps?: boolean;
63
+ /** createdAt 字段名,默认 'createdAt' */
64
+ createdAtField?: string;
65
+ /** updatedAt 字段名,默认 'updatedAt' */
66
+ updatedAtField?: string;
67
+ }
68
+
69
+ // ============================================================================
70
+ // Lifecycle Hooks Types
71
+ // ============================================================================
72
+
73
+ /**
74
+ * 生命周期钩子上下文
75
+ * 包含当前操作的相关信息
76
+ */
77
+ export interface HookContext<T extends object = object> {
78
+ /** 模型名称 */
79
+ modelName: string;
80
+ /** 当前操作的数据(create/update 时) */
81
+ data?: Partial<T>;
82
+ /** 查询条件(find/update/delete 时) */
83
+ where?: Condition<T>;
84
+ /** 操作结果(after 钩子时) */
85
+ result?: T | T[] | number;
86
+ }
87
+
88
+ /**
89
+ * 钩子函数类型
90
+ * 返回 false 可以取消操作(仅 before 钩子)
91
+ */
92
+ export type HookFn<T extends object = object> = (
93
+ context: HookContext<T>
94
+ ) => void | boolean | Promise<void | boolean>;
95
+
96
+ /**
97
+ * 生命周期钩子名称
98
+ */
99
+ export type HookName =
100
+ | 'beforeCreate'
101
+ | 'afterCreate'
102
+ | 'beforeUpdate'
103
+ | 'afterUpdate'
104
+ | 'beforeDelete'
105
+ | 'afterDelete'
106
+ | 'beforeFind'
107
+ | 'afterFind';
108
+
109
+ /**
110
+ * 钩子配置
111
+ */
112
+ export type HooksConfig<T extends object = object> = {
113
+ [K in HookName]?: HookFn<T> | HookFn<T>[];
114
+ };
115
+
38
116
  // ============================================================================
39
117
  // Column Alteration Types
40
118
  // ============================================================================
@@ -64,6 +142,21 @@ export type AlterDefinition<T extends object> = {
64
142
  [P in keyof T]?: AddDefinition<T[P]> | ModifyDefinition<T[P]> | DropDefinition
65
143
  };
66
144
 
145
+ // ============================================================================
146
+ // Subquery Types
147
+ // ============================================================================
148
+
149
+ /**
150
+ * 子查询标识接口
151
+ * @template T 子查询返回的字段类型
152
+ */
153
+ export interface Subquery<T = any> {
154
+ readonly __isSubquery: true;
155
+ /** 子查询返回值类型标记(仅用于类型推断,运行时不存在) */
156
+ readonly __returnType?: T;
157
+ toSQL(): { sql: string; params: any[] };
158
+ }
159
+
67
160
  // ============================================================================
68
161
  // Condition Types
69
162
  // ============================================================================
@@ -75,8 +168,10 @@ export interface ComparisonOperators<T> {
75
168
  $gte?: T;
76
169
  $lt?: T;
77
170
  $lte?: T;
78
- $in?: T[];
79
- $nin?: T[];
171
+ /** 值在数组中或子查询结果中 */
172
+ $in?: T[] | Subquery<T>;
173
+ /** 值不在数组中或子查询结果中 */
174
+ $nin?: T[] | Subquery<T>;
80
175
  $like?: string;
81
176
  $nlike?: string;
82
177
  }
@@ -102,70 +197,116 @@ export interface Ordering<T extends object> {
102
197
  direction: SortDirection;
103
198
  }
104
199
 
200
+ // ============================================================================
201
+ // JOIN Types
202
+ // ============================================================================
203
+
204
+ export type JoinType = 'INNER' | 'LEFT' | 'RIGHT' | 'FULL';
205
+
206
+ /**
207
+ * JOIN 子句定义
208
+ * @template S Schema 类型
209
+ * @template T 主表
210
+ * @template J 关联表
211
+ */
212
+ export interface JoinClause<
213
+ S extends Record<string, object>,
214
+ T extends keyof S,
215
+ J extends keyof S
216
+ > {
217
+ /** JOIN 类型 */
218
+ type: JoinType;
219
+ /** 关联表名 */
220
+ table: J;
221
+ /** 主表字段 */
222
+ leftField: keyof S[T];
223
+ /** 关联表字段 */
224
+ rightField: keyof S[J];
225
+ /** 表别名(可选) */
226
+ alias?: string;
227
+ }
228
+
105
229
  // ============================================================================
106
230
  // Query Parameter Types (Discriminated Union)
107
231
  // ============================================================================
108
232
 
109
- export interface BaseQueryParams {
110
- tableName: string;
233
+ export interface BaseQueryParams<S extends Record<string, object> = Record<string, object>, T extends keyof S = keyof S> {
234
+ tableName: T;
111
235
  }
112
236
 
113
- export interface CreateQueryParams<T extends object = any> extends BaseQueryParams {
237
+ export interface CreateQueryParams<S extends Record<string, object>, T extends keyof S> extends BaseQueryParams<S,T> {
114
238
  type: 'create';
115
- definition: Definition<T>;
239
+ definition: Definition<S[T]>;
116
240
  }
117
241
 
118
- export interface AlterQueryParams<T extends object = any> extends BaseQueryParams {
242
+ export interface AlterQueryParams<S extends Record<string, object>, T extends keyof S> extends BaseQueryParams<S,T> {
119
243
  type: 'alter';
120
- alterations: AlterDefinition<T>;
244
+ alterations: AlterDefinition<S[T]>;
121
245
  }
122
246
 
123
- export interface DropTableQueryParams<T extends object = any> extends BaseQueryParams {
247
+ export interface DropTableQueryParams<S extends Record<string, object>, T extends keyof S> extends BaseQueryParams<S,T> {
124
248
  type: 'drop_table';
125
- conditions?: Condition<T>;
249
+ conditions?: Condition<S[T]>;
126
250
  }
127
251
 
128
- export interface DropIndexQueryParams extends BaseQueryParams {
252
+ export interface DropIndexQueryParams<S extends Record<string, object>, T extends keyof S> extends BaseQueryParams<S,T> {
129
253
  type: 'drop_index';
130
254
  indexName: string;
131
255
  conditions?: Condition<any>;
132
256
  }
133
257
 
134
- export interface SelectQueryParams<T extends object = any> extends BaseQueryParams {
258
+ export interface SelectQueryParams<S extends Record<string, object>, T extends keyof S> extends BaseQueryParams<S,T> {
135
259
  type: 'select';
136
- fields?: (keyof T)[];
137
- conditions?: Condition<T>;
138
- groupings?: (keyof T)[];
139
- orderings?: Ordering<T>[];
260
+ fields?: (keyof S[T])[];
261
+ conditions?: Condition<S[T]>;
262
+ groupings?: (keyof S[T])[];
263
+ orderings?: Ordering<S[T]>[];
140
264
  limitCount?: number;
141
265
  offsetCount?: number;
266
+ /** JOIN 子句列表 */
267
+ joins?: JoinClause<S, T, keyof S>[];
142
268
  }
143
269
 
144
- export interface InsertQueryParams<T extends object = any> extends BaseQueryParams {
270
+ export interface InsertQueryParams<S extends Record<string, object>, T extends keyof S> extends BaseQueryParams<S,T> {
145
271
  type: 'insert';
146
- data: T;
272
+ data: S[T];
273
+ }
274
+
275
+ export interface InsertManyQueryParams<S extends Record<string, object>, T extends keyof S> extends BaseQueryParams<S,T> {
276
+ type: 'insert_many';
277
+ data: S[T][];
147
278
  }
148
279
 
149
- export interface UpdateQueryParams<T extends object = any> extends BaseQueryParams {
280
+ export interface UpdateQueryParams<S extends Record<string, object>, T extends keyof S> extends BaseQueryParams<S,T> {
150
281
  type: 'update';
151
- update: Partial<T>;
152
- conditions?: Condition<T>;
282
+ update: Partial<S[T]>;
283
+ conditions?: Condition<S[T]>;
153
284
  }
154
285
 
155
- export interface DeleteQueryParams<T extends object = any> extends BaseQueryParams {
286
+ export interface DeleteQueryParams<S extends Record<string, object>, T extends keyof S> extends BaseQueryParams<S,T> {
156
287
  type: 'delete';
157
- conditions?: Condition<T>;
288
+ conditions?: Condition<S[T]>;
158
289
  }
159
290
 
160
- export type QueryParams<T extends object = any> =
161
- | CreateQueryParams<T>
162
- | AlterQueryParams<T>
163
- | DropTableQueryParams<T>
164
- | DropIndexQueryParams
165
- | SelectQueryParams<T>
166
- | InsertQueryParams<T>
167
- | UpdateQueryParams<T>
168
- | DeleteQueryParams<T>;
291
+ export interface AggregateQueryParams<S extends Record<string, object>, T extends keyof S> extends BaseQueryParams<S,T> {
292
+ type: 'aggregate';
293
+ aggregates: AggregateField<S[T]>[];
294
+ conditions?: Condition<S[T]>;
295
+ groupings?: (keyof S[T])[];
296
+ havingConditions?: Condition<S[T]>;
297
+ }
298
+
299
+ export type QueryParams<S extends Record<string, object>,T extends keyof S> =
300
+ | CreateQueryParams<S,T>
301
+ | AlterQueryParams<S,T>
302
+ | DropTableQueryParams<S,T>
303
+ | DropIndexQueryParams<S,T>
304
+ | SelectQueryParams<S,T>
305
+ | InsertQueryParams<S,T>
306
+ | InsertManyQueryParams<S,T>
307
+ | UpdateQueryParams<S,T>
308
+ | DeleteQueryParams<S,T>
309
+ | AggregateQueryParams<S,T>;
169
310
 
170
311
  // ============================================================================
171
312
  // Query Result Types
@@ -271,8 +412,6 @@ export interface BaseDriverConfig {
271
412
  }
272
413
 
273
414
 
274
- export interface MemoryConfig{
275
- }
276
415
 
277
416
 
278
417
  // ============================================================================
@@ -286,6 +425,91 @@ export interface DriverConnection {
286
425
  healthCheck(): Promise<boolean>;
287
426
  }
288
427
 
428
+ // ============================================================================
429
+ // Transaction Types
430
+ // ============================================================================
431
+
432
+ export type IsolationLevel = 'READ_UNCOMMITTED' | 'READ_COMMITTED' | 'REPEATABLE_READ' | 'SERIALIZABLE';
433
+
434
+ export interface TransactionOptions {
435
+ isolationLevel?: IsolationLevel;
436
+ timeout?: number;
437
+ }
438
+
439
+ export interface Transaction {
440
+ commit(): Promise<void>;
441
+ rollback(): Promise<void>;
442
+ query<T = any>(sql: string, params?: any[]): Promise<T>;
443
+ }
444
+
445
+ /**
446
+ * 增强的事务接口,支持链式调用
447
+ */
448
+ export interface TransactionContext<S extends Record<string, object> = Record<string, object>> extends Transaction {
449
+ /**
450
+ * 插入单条数据
451
+ */
452
+ insert<T extends keyof S>(tableName: T, data: S[T]): Promise<S[T]>;
453
+
454
+ /**
455
+ * 批量插入数据
456
+ */
457
+ insertMany<T extends keyof S>(tableName: T, data: S[T][]): Promise<{ affectedRows: number }>;
458
+
459
+ /**
460
+ * 查询数据
461
+ */
462
+ select<T extends keyof S>(tableName: T, fields?: (keyof S[T])[]): TransactionSelection<S, T>;
463
+
464
+ /**
465
+ * 更新数据
466
+ */
467
+ update<T extends keyof S>(tableName: T, data: Partial<S[T]>): TransactionUpdation<S, T>;
468
+
469
+ /**
470
+ * 删除数据
471
+ */
472
+ delete<T extends keyof S>(tableName: T): TransactionDeletion<S, T>;
473
+ }
474
+
475
+ /**
476
+ * 事务查询选择器
477
+ */
478
+ export interface TransactionSelection<S extends Record<string, object>, T extends keyof S> {
479
+ where(condition: Condition<S[T]>): this;
480
+ orderBy(field: keyof S[T], direction?: 'ASC' | 'DESC'): this;
481
+ limit(count: number): this;
482
+ offset(count: number): this;
483
+ then<R>(onfulfilled?: (value: S[T][]) => R | PromiseLike<R>): Promise<R>;
484
+ }
485
+
486
+ /**
487
+ * 事务更新器
488
+ */
489
+ export interface TransactionUpdation<S extends Record<string, object>, T extends keyof S> {
490
+ where(condition: Condition<S[T]>): this;
491
+ then<R>(onfulfilled?: (value: number) => R | PromiseLike<R>): Promise<R>;
492
+ }
493
+
494
+ /**
495
+ * 事务删除器
496
+ */
497
+ export interface TransactionDeletion<S extends Record<string, object>, T extends keyof S> {
498
+ where(condition: Condition<S[T]>): this;
499
+ then<R>(onfulfilled?: (value: number) => R | PromiseLike<R>): Promise<R>;
500
+ }
501
+
502
+ // ============================================================================
503
+ // Connection Pool Types
504
+ // ============================================================================
505
+
506
+ export interface PoolConfig {
507
+ min?: number;
508
+ max?: number;
509
+ acquireTimeoutMillis?: number;
510
+ idleTimeoutMillis?: number;
511
+ }
512
+
289
513
  export interface DriverQuery {
290
514
  query<T = any>(sql: string, params?: any[]): Promise<T>;
291
515
  }
@@ -296,7 +520,7 @@ export interface DriverSchema {
296
520
  }
297
521
 
298
522
  export interface DriverQueryBuilder<R> {
299
- buildQuery<T extends object = any>(params: QueryParams<T>): BuildQueryResult<R>;
523
+ buildQuery<S extends Record<string, object>, T extends keyof S>(params: QueryParams<S, T>): BuildQueryResult<R>;
300
524
  }
301
525
 
302
526
  export interface DriverLifecycle {
@@ -370,34 +594,325 @@ export type DeepRequired<T> = {
370
594
  // Type Guards
371
595
  // ============================================================================
372
596
 
373
- export function isCreateQuery<T extends object>(params: QueryParams<T>): params is CreateQueryParams<T> {
597
+ export function isCreateQuery<S extends Record<string, object>, T extends keyof S>(params: QueryParams<S, T>): params is CreateQueryParams<S, T> {
374
598
  return params.type === 'create';
375
599
  }
376
600
 
377
- export function isAlterQuery<T extends object>(params: QueryParams<T>): params is AlterQueryParams<T> {
601
+ export function isAlterQuery<S extends Record<string, object>, T extends keyof S>(params: QueryParams<S, T>): params is AlterQueryParams<S, T> {
378
602
  return params.type === 'alter';
379
603
  }
380
604
 
381
- export function isSelectQuery<T extends object>(params: QueryParams<T>): params is SelectQueryParams<T> {
605
+ export function isSelectQuery<S extends Record<string, object>, T extends keyof S>(params: QueryParams<S, T>): params is SelectQueryParams<S, T> {
382
606
  return params.type === 'select';
383
607
  }
384
608
 
385
- export function isInsertQuery<T extends object>(params: QueryParams<T>): params is InsertQueryParams<T> {
609
+ export function isInsertQuery<S extends Record<string, object>, T extends keyof S>(params: QueryParams<S, T>): params is InsertQueryParams<S, T> {
386
610
  return params.type === 'insert';
387
611
  }
388
612
 
389
- export function isUpdateQuery<T extends object>(params: QueryParams<T>): params is UpdateQueryParams<T> {
613
+ export function isUpdateQuery<S extends Record<string, object>, T extends keyof S>(params: QueryParams<S, T>): params is UpdateQueryParams<S, T> {
390
614
  return params.type === 'update';
391
615
  }
392
616
 
393
- export function isDeleteQuery<T extends object>(params: QueryParams<T>): params is DeleteQueryParams<T> {
617
+ export function isDeleteQuery<S extends Record<string, object>, T extends keyof S>(params: QueryParams<S, T>): params is DeleteQueryParams<S, T> {
394
618
  return params.type === 'delete';
395
619
  }
396
620
 
397
- export function isDropTableQuery<T extends object>(params: QueryParams<T>): params is DropTableQueryParams<T> {
621
+ export function isDropTableQuery<S extends Record<string, object>, T extends keyof S>(params: QueryParams<S, T>): params is DropTableQueryParams<S, T> {
398
622
  return params.type === 'drop_table';
399
623
  }
400
624
 
401
- export function isDropIndexQuery(params: QueryParams): params is DropIndexQueryParams {
625
+ export function isDropIndexQuery<S extends Record<string, object>, T extends keyof S>(params: QueryParams<S, T>): params is DropIndexQueryParams<S,T> {
402
626
  return params.type === 'drop_index';
403
627
  }
628
+
629
+ export function isInsertManyQuery<S extends Record<string, object>, T extends keyof S>(params: QueryParams<S, T>): params is InsertManyQueryParams<S, T> {
630
+ return params.type === 'insert_many';
631
+ }
632
+
633
+ export function isAggregateQuery<S extends Record<string, object>, T extends keyof S>(params: QueryParams<S, T>): params is AggregateQueryParams<S, T> {
634
+ return params.type === 'aggregate';
635
+ }
636
+
637
+ // ============================================================================
638
+ // Relations Types
639
+ // ============================================================================
640
+
641
+ /**
642
+ * 关联关系类型
643
+ */
644
+ export type RelationType = 'hasOne' | 'hasMany' | 'belongsTo' | 'belongsToMany';
645
+
646
+ /**
647
+ * Schema 中的关系声明
648
+ *
649
+ * @example
650
+ * ```ts
651
+ * interface MySchema {
652
+ * users: {
653
+ * id: number;
654
+ * name: string;
655
+ * $hasMany: { orders: 'userId' };
656
+ * $hasOne: { profile: 'userId' };
657
+ * };
658
+ * orders: {
659
+ * id: number;
660
+ * userId: number;
661
+ * $belongsTo: { users: 'userId' };
662
+ * };
663
+ * }
664
+ * ```
665
+ */
666
+ export interface SchemaRelations<S extends Record<string, object>> {
667
+ /** 一对多关系: { 目标表名: '外键字段' } */
668
+ $hasMany?: { [K in keyof S]?: string };
669
+ /** 一对一关系: { 目标表名: '外键字段' } */
670
+ $hasOne?: { [K in keyof S]?: string };
671
+ /** 多对一关系: { 目标表名: '本表外键字段' } */
672
+ $belongsTo?: { [K in keyof S]?: string };
673
+ }
674
+
675
+ /**
676
+ * 从 Schema 表定义中提取纯数据字段(排除关系声明)
677
+ */
678
+ export type SchemaFields<T> = Omit<T, '$hasMany' | '$hasOne' | '$belongsTo'>;
679
+
680
+ /**
681
+ * 关联关系定义
682
+ */
683
+ export interface RelationDefinition<
684
+ S extends Record<string, object>,
685
+ From extends keyof S,
686
+ To extends keyof S
687
+ > {
688
+ /** 关联类型 */
689
+ type: RelationType;
690
+ /** 目标表名 */
691
+ target: To;
692
+ /** 本表外键字段 */
693
+ foreignKey: keyof S[From] | keyof S[To];
694
+ /** 目标表主键字段(默认 'id') */
695
+ targetKey?: keyof S[To];
696
+ /** 本表主键字段(默认 'id') */
697
+ localKey?: keyof S[From];
698
+ /** 中间表配置(仅 belongsToMany) */
699
+ pivot?: PivotConfig;
700
+ }
701
+
702
+ /**
703
+ * 中间表(Pivot Table)配置
704
+ * 用于多对多关系
705
+ */
706
+ export interface PivotConfig {
707
+ /** 中间表名 */
708
+ table: string;
709
+ /** 中间表中指向源表的外键 */
710
+ foreignPivotKey: string;
711
+ /** 中间表中指向目标表的外键 */
712
+ relatedPivotKey: string;
713
+ /** 中间表额外字段(可选) */
714
+ pivotFields?: string[];
715
+ /** 是否包含时间戳 */
716
+ timestamps?: boolean;
717
+ }
718
+
719
+ /**
720
+ * 带关联数据的结果类型
721
+ */
722
+ export type WithRelation<
723
+ T extends object,
724
+ RelName extends string,
725
+ RelType extends 'hasOne' | 'belongsTo' | 'hasMany' | 'belongsToMany',
726
+ RelData extends object
727
+ > = T & {
728
+ [K in RelName]: RelType extends ('hasMany' | 'belongsToMany') ? RelData[] : RelData | null;
729
+ };
730
+
731
+ /**
732
+ * 带中间表数据的关联结果
733
+ */
734
+ export type WithPivot<T extends object, PivotData extends object = Record<string, any>> = T & {
735
+ pivot: PivotData;
736
+ };
737
+
738
+ /**
739
+ * 关联查询选项
740
+ */
741
+ export interface RelationQueryOptions<S extends Record<string, object>, T extends keyof S> {
742
+ /** 要加载的关联名称 */
743
+ relations?: string[];
744
+ /** 关联数据的筛选条件 */
745
+ where?: Condition<S[T]>;
746
+ }
747
+
748
+ /**
749
+ * 关系配置中的外键字段类型
750
+ * 表名是强类型的,字段名是 string(运行时验证)
751
+ */
752
+ export type RelationForeignKey = string;
753
+
754
+ /**
755
+ * hasMany 关系配置:{ 目标表名: 外键字段名 }
756
+ */
757
+ export type HasManyConfig<S extends Record<string, object>> = {
758
+ [K in Extract<keyof S, string>]?: RelationForeignKey;
759
+ };
760
+
761
+ /**
762
+ * hasOne 关系配置:{ 目标表名: 外键字段名 }
763
+ */
764
+ export type HasOneConfig<S extends Record<string, object>> = {
765
+ [K in Extract<keyof S, string>]?: RelationForeignKey;
766
+ };
767
+
768
+ /**
769
+ * belongsTo 关系配置:{ 目标表名: 本表外键字段名 }
770
+ */
771
+ export type BelongsToConfig<S extends Record<string, object>> = {
772
+ [K in Extract<keyof S, string>]?: RelationForeignKey;
773
+ };
774
+
775
+ /**
776
+ * belongsToMany 关系配置
777
+ * { 目标表名: { pivot: 中间表名, foreignKey: 源外键, relatedKey: 目标外键, pivotFields?: 额外字段 } }
778
+ */
779
+ export interface BelongsToManyRelationConfig {
780
+ /** 中间表名 */
781
+ pivot: string;
782
+ /** 中间表中指向源表的外键 */
783
+ foreignKey: string;
784
+ /** 中间表中指向目标表的外键 */
785
+ relatedKey: string;
786
+ /** 要获取的中间表额外字段 */
787
+ pivotFields?: string[];
788
+ }
789
+
790
+ export type BelongsToManyConfig<S extends Record<string, object>> = {
791
+ [K in Extract<keyof S, string>]?: BelongsToManyRelationConfig;
792
+ };
793
+
794
+ /**
795
+ * 单个表的关系配置
796
+ */
797
+ export interface TableRelationsConfig<S extends Record<string, object>> {
798
+ hasMany?: HasManyConfig<S>;
799
+ hasOne?: HasOneConfig<S>;
800
+ belongsTo?: BelongsToConfig<S>;
801
+ belongsToMany?: BelongsToManyConfig<S>;
802
+ }
803
+
804
+ /**
805
+ * 关系配置对象(用于 Database 构造)
806
+ *
807
+ * 表名是强类型的(必须是 Schema 中定义的表),
808
+ * 字段名是字符串(在运行时通过模型方法验证)
809
+ *
810
+ * @example
811
+ * ```ts
812
+ * interface Schema {
813
+ * users: { id: number; name: string };
814
+ * orders: { id: number; userId: number };
815
+ * }
816
+ *
817
+ * db.defineRelations({
818
+ * users: {
819
+ * hasMany: { orders: 'userId' } // ✅ 'orders' 是有效表名
820
+ * },
821
+ * orders: {
822
+ * belongsTo: { users: 'userId' } // ✅ 'users' 是有效表名
823
+ * },
824
+ * // wrongTable: {} // ❌ 类型错误:'wrongTable' 不在 Schema 中
825
+ * });
826
+ * ```
827
+ */
828
+ export type RelationsConfig<S extends Record<string, object>> = {
829
+ [T in Extract<keyof S, string>]?: TableRelationsConfig<S>;
830
+ };
831
+
832
+ // ============================================================================
833
+ // Migration Types
834
+ // ============================================================================
835
+
836
+ /**
837
+ * 迁移上下文 - 提供迁移操作所需的数据库方法
838
+ */
839
+ export interface MigrationContext {
840
+ /** 创建表 */
841
+ createTable(tableName: string, columns: Record<string, Column>): Promise<void>;
842
+ /** 删除表 */
843
+ dropTable(tableName: string): Promise<void>;
844
+ /** 添加列 */
845
+ addColumn(tableName: string, columnName: string, column: Column): Promise<void>;
846
+ /** 删除列 */
847
+ dropColumn(tableName: string, columnName: string): Promise<void>;
848
+ /** 修改列 */
849
+ modifyColumn(tableName: string, columnName: string, column: Column): Promise<void>;
850
+ /** 重命名列 */
851
+ renameColumn(tableName: string, oldName: string, newName: string): Promise<void>;
852
+ /** 添加索引 */
853
+ addIndex(tableName: string, indexName: string, columns: string[], unique?: boolean): Promise<void>;
854
+ /** 删除索引 */
855
+ dropIndex(tableName: string, indexName: string): Promise<void>;
856
+ /** 执行原生 SQL */
857
+ query<T = any>(sql: string, params?: any[]): Promise<T>;
858
+ }
859
+
860
+ /**
861
+ * 迁移定义
862
+ */
863
+ /**
864
+ * 迁移操作记录(用于自动生成 down)
865
+ */
866
+ export type MigrationOperation =
867
+ | { type: 'createTable'; tableName: string; columns: Record<string, Column> }
868
+ | { type: 'dropTable'; tableName: string }
869
+ | { type: 'addColumn'; tableName: string; columnName: string; column: Column }
870
+ | { type: 'dropColumn'; tableName: string; columnName: string }
871
+ | { type: 'addIndex'; tableName: string; indexName: string; columns: string[]; unique?: boolean }
872
+ | { type: 'dropIndex'; tableName: string; indexName: string }
873
+ | { type: 'renameColumn'; tableName: string; oldName: string; newName: string }
874
+ | { type: 'query'; sql: string; params?: any[] };
875
+
876
+ export interface Migration {
877
+ /** 迁移名称(唯一标识) */
878
+ name: string;
879
+ /** 迁移版本(时间戳或序号) */
880
+ version?: string | number;
881
+ /** 升级操作 */
882
+ up(context: MigrationContext): Promise<void>;
883
+ /**
884
+ * 降级操作(可选)
885
+ * 如果不提供,将自动根据 up 操作生成反向操作
886
+ */
887
+ down?(context: MigrationContext): Promise<void>;
888
+ }
889
+
890
+ /**
891
+ * 迁移记录(存储在数据库中)
892
+ */
893
+ export interface MigrationRecord {
894
+ id: number;
895
+ name: string;
896
+ batch: number;
897
+ executedAt: Date;
898
+ }
899
+
900
+ /**
901
+ * 迁移状态
902
+ */
903
+ export interface MigrationStatus {
904
+ name: string;
905
+ status: 'pending' | 'executed';
906
+ batch?: number;
907
+ executedAt?: Date;
908
+ }
909
+
910
+ /**
911
+ * 迁移运行器配置
912
+ */
913
+ export interface MigrationRunnerConfig {
914
+ /** 迁移记录表名 */
915
+ tableName?: string;
916
+ /** 迁移文件目录 */
917
+ migrationsPath?: string;
918
+ }