@zerotal/orm 1.1.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,22 +1,25 @@
1
1
  // ── Model mixins ──────────────────────────────────────────────────────────────
2
2
  //
3
- // `BaseModelWith(...)` composes any number of model mixins on top of `BaseModel`,
4
- // so packages can ship reusable model behaviour (auth contract, roles, permissions,
5
- // soft deletes, …) that apps stack without "wrapper hell":
3
+ // Mixin composition machinery for the ORM. The entry point is `Model.using(...)`
4
+ // (see BaseModel.ts) this module owns the types it is built from, and the fold
5
+ // itself. Nothing here imports `BaseModel`: the fold seeds from its receiver, so
6
+ // this is a leaf module.
7
+ //
8
+ // `Model.using(...)` composes any number of model mixins, so packages can ship
9
+ // reusable model behaviour (auth contract, roles, permissions, soft deletes, …)
10
+ // that apps stack without "wrapper hell":
6
11
  //
7
12
  // // before — nested, base repeated, order reads inside-out
8
13
  // class User extends Roles(Permissions(AuthUser)) {}
9
14
  //
10
15
  // // after — flat, left-to-right, base baked in
11
- // class User extends BaseModelWith(Authenticatable, Permissions, Roles) {}
16
+ // class User extends Model.using(Authenticatable, Permissions, Roles) {}
12
17
  //
13
18
  // A mixin is the canonical generic form `(<T>(Base: T) => class extends Base { … })`.
14
- // Because each one returns `class extends Base`, BaseModel's full static surface
19
+ // Because each one returns `class extends Base`, the base's full static surface
15
20
  // (`User.query()`, `find()`, `create()`, scopes, …) and every mixin's instance
16
21
  // members flow through to the final class — fully type-checked.
17
22
 
18
- import { BaseModel } from "./BaseModel.ts";
19
-
20
23
  /** A concrete class constructor. */
21
24
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- generic mixin base bound
22
25
  export type Constructor<T = object> = new (...args: any[]) => T;
@@ -32,505 +35,127 @@ export type Mixin<TIn extends Constructor = Constructor, TOut extends Constructo
32
35
  Base: TIn,
33
36
  ) => TOut;
34
37
 
35
- type Base = typeof BaseModel;
36
-
37
- // Typed overloads (1–8 mixins) thread the accumulated type through each step so the
38
- // result is `BaseModel`'s statics + every mixin's members. Need more? Nest a
39
- // `BaseModelWith(...)` call or add another overload.
40
-
41
38
  /**
42
- * Compose any number of model {@link Mixin | mixins} on top of {@link BaseModel},
43
- * folding them left-to-right so the resulting class carries `BaseModel`'s full
44
- * static surface (`query()`, `find()`, `create()`, scopes, …) plus every mixin's
45
- * instance and static members — all fully type-checked.
46
- *
47
- * Prefer this over hand-nesting mixins (`Roles(Permissions(AuthUser))`), which
48
- * reads inside-out and repeats the base. Each overload (1–20 mixins) threads the
49
- * accumulated type through every step; for more, nest a second `BaseModelWith(...)`.
39
+ * The call signatures behind `Model.using(...)`.
50
40
  *
51
- * @param mixins - Mixin factories applied in order; each receives the class the
52
- * previous one produced.
53
- * @returns A model class extending `BaseModel` with every mixin applied.
41
+ * Each overload threads the accumulated type through every step, so the composed class carries
42
+ * the base's full static surface plus every mixin's instance and static members — fully
43
+ * type-checked. The `this: TBase` parameter is what makes the base polymorphic: `using` composes
44
+ * onto whatever class it is called on, not onto a hardcoded `BaseModel`.
54
45
  *
55
- * @example
56
- * ```ts
57
- * class User extends BaseModelWith(Authenticatable, Permissions, Roles) {}
58
- * ```
46
+ * Overloads cover 1–8 mixins. There is no ceiling: the composed class carries `using` too, so
47
+ * `Model.using(a, b).using(c, d)` chains.
59
48
  */
60
- export function BaseModelWith<A extends Constructor>(a: (base: Base) => A): A;
61
- export function BaseModelWith<A extends Constructor, B extends Constructor>(
62
- a: (base: Base) => A,
63
- b: (base: A) => B,
64
- ): B;
65
- export function BaseModelWith<A extends Constructor, B extends Constructor, C extends Constructor>(
66
- a: (base: Base) => A,
67
- b: (base: A) => B,
68
- c: (base: B) => C,
69
- ): C;
70
- export function BaseModelWith<
71
- A extends Constructor,
72
- B extends Constructor,
73
- C extends Constructor,
74
- D extends Constructor,
75
- >(a: (base: Base) => A, b: (base: A) => B, c: (base: B) => C, d: (base: C) => D): D;
76
- export function BaseModelWith<
77
- A extends Constructor,
78
- B extends Constructor,
79
- C extends Constructor,
80
- D extends Constructor,
81
- E extends Constructor,
82
- >(
83
- a: (base: Base) => A,
84
- b: (base: A) => B,
85
- c: (base: B) => C,
86
- d: (base: C) => D,
87
- e: (base: D) => E,
88
- ): E;
89
- export function BaseModelWith<
90
- A extends Constructor,
91
- B extends Constructor,
92
- C extends Constructor,
93
- D extends Constructor,
94
- E extends Constructor,
95
- F extends Constructor,
96
- >(
97
- a: (base: Base) => A,
98
- b: (base: A) => B,
99
- c: (base: B) => C,
100
- d: (base: C) => D,
101
- e: (base: D) => E,
102
- f: (base: E) => F,
103
- ): F;
104
- export function BaseModelWith<
105
- A extends Constructor,
106
- B extends Constructor,
107
- C extends Constructor,
108
- D extends Constructor,
109
- E extends Constructor,
110
- F extends Constructor,
111
- G extends Constructor,
112
- >(
113
- a: (base: Base) => A,
114
- b: (base: A) => B,
115
- c: (base: B) => C,
116
- d: (base: C) => D,
117
- e: (base: D) => E,
118
- f: (base: E) => F,
119
- g: (base: F) => G,
120
- ): G;
121
- export function BaseModelWith<
122
- A extends Constructor,
123
- B extends Constructor,
124
- C extends Constructor,
125
- D extends Constructor,
126
- E extends Constructor,
127
- F extends Constructor,
128
- G extends Constructor,
129
- H extends Constructor,
130
- >(
131
- a: (base: Base) => A,
132
- b: (base: A) => B,
133
- c: (base: B) => C,
134
- d: (base: C) => D,
135
- e: (base: D) => E,
136
- f: (base: E) => F,
137
- g: (base: F) => G,
138
- h: (base: G) => H,
139
- ): H;
140
- export function BaseModelWith<
141
- A extends Constructor,
142
- B extends Constructor,
143
- C extends Constructor,
144
- D extends Constructor,
145
- E extends Constructor,
146
- F extends Constructor,
147
- G extends Constructor,
148
- H extends Constructor,
149
- I extends Constructor,
150
- >(
151
- a: (base: Base) => A,
152
- b: (base: A) => B,
153
- c: (base: B) => C,
154
- d: (base: C) => D,
155
- e: (base: D) => E,
156
- f: (base: E) => F,
157
- g: (base: F) => G,
158
- h: (base: G) => H,
159
- i: (base: H) => I,
160
- ): I;
161
- export function BaseModelWith<
162
- A extends Constructor,
163
- B extends Constructor,
164
- C extends Constructor,
165
- D extends Constructor,
166
- E extends Constructor,
167
- F extends Constructor,
168
- G extends Constructor,
169
- H extends Constructor,
170
- I extends Constructor,
171
- J extends Constructor,
172
- >(
173
- a: (base: Base) => A,
174
- b: (base: A) => B,
175
- c: (base: B) => C,
176
- d: (base: C) => D,
177
- e: (base: D) => E,
178
- f: (base: E) => F,
179
- g: (base: F) => G,
180
- h: (base: G) => H,
181
- i: (base: H) => I,
182
- j: (base: I) => J,
183
- ): J;
184
- export function BaseModelWith<
185
- A extends Constructor,
186
- B extends Constructor,
187
- C extends Constructor,
188
- D extends Constructor,
189
- E extends Constructor,
190
- F extends Constructor,
191
- G extends Constructor,
192
- H extends Constructor,
193
- I extends Constructor,
194
- J extends Constructor,
195
- K extends Constructor,
196
- >(
197
- a: (base: Base) => A,
198
- b: (base: A) => B,
199
- c: (base: B) => C,
200
- d: (base: C) => D,
201
- e: (base: D) => E,
202
- f: (base: E) => F,
203
- g: (base: F) => G,
204
- h: (base: G) => H,
205
- i: (base: H) => I,
206
- j: (base: I) => J,
207
- k: (base: J) => K,
208
- ): K;
209
- export function BaseModelWith<
210
- A extends Constructor,
211
- B extends Constructor,
212
- C extends Constructor,
213
- D extends Constructor,
214
- E extends Constructor,
215
- F extends Constructor,
216
- G extends Constructor,
217
- H extends Constructor,
218
- I extends Constructor,
219
- J extends Constructor,
220
- K extends Constructor,
221
- L extends Constructor,
222
- >(
223
- a: (base: Base) => A,
224
- b: (base: A) => B,
225
- c: (base: B) => C,
226
- d: (base: C) => D,
227
- e: (base: D) => E,
228
- f: (base: E) => F,
229
- g: (base: F) => G,
230
- h: (base: G) => H,
231
- i: (base: H) => I,
232
- j: (base: I) => J,
233
- k: (base: J) => K,
234
- l: (base: K) => L,
235
- ): L;
236
- export function BaseModelWith<
237
- A extends Constructor,
238
- B extends Constructor,
239
- C extends Constructor,
240
- D extends Constructor,
241
- E extends Constructor,
242
- F extends Constructor,
243
- G extends Constructor,
244
- H extends Constructor,
245
- I extends Constructor,
246
- J extends Constructor,
247
- K extends Constructor,
248
- L extends Constructor,
249
- M extends Constructor,
250
- >(
251
- a: (base: Base) => A,
252
- b: (base: A) => B,
253
- c: (base: B) => C,
254
- d: (base: C) => D,
255
- e: (base: D) => E,
256
- f: (base: E) => F,
257
- g: (base: F) => G,
258
- h: (base: G) => H,
259
- i: (base: H) => I,
260
- j: (base: I) => J,
261
- k: (base: J) => K,
262
- l: (base: K) => L,
263
- m: (base: L) => M,
264
- ): M;
265
- export function BaseModelWith<
266
- A extends Constructor,
267
- B extends Constructor,
268
- C extends Constructor,
269
- D extends Constructor,
270
- E extends Constructor,
271
- F extends Constructor,
272
- G extends Constructor,
273
- H extends Constructor,
274
- I extends Constructor,
275
- J extends Constructor,
276
- K extends Constructor,
277
- L extends Constructor,
278
- M extends Constructor,
279
- N extends Constructor,
280
- >(
281
- a: (base: Base) => A,
282
- b: (base: A) => B,
283
- c: (base: B) => C,
284
- d: (base: C) => D,
285
- e: (base: D) => E,
286
- f: (base: E) => F,
287
- g: (base: F) => G,
288
- h: (base: G) => H,
289
- i: (base: H) => I,
290
- j: (base: I) => J,
291
- k: (base: J) => K,
292
- l: (base: K) => L,
293
- m: (base: L) => M,
294
- n: (base: M) => N,
295
- ): N;
296
- export function BaseModelWith<
297
- A extends Constructor,
298
- B extends Constructor,
299
- C extends Constructor,
300
- D extends Constructor,
301
- E extends Constructor,
302
- F extends Constructor,
303
- G extends Constructor,
304
- H extends Constructor,
305
- I extends Constructor,
306
- J extends Constructor,
307
- K extends Constructor,
308
- L extends Constructor,
309
- M extends Constructor,
310
- N extends Constructor,
311
- O extends Constructor,
312
- >(
313
- a: (base: Base) => A,
314
- b: (base: A) => B,
315
- c: (base: B) => C,
316
- d: (base: C) => D,
317
- e: (base: D) => E,
318
- f: (base: E) => F,
319
- g: (base: F) => G,
320
- h: (base: G) => H,
321
- i: (base: H) => I,
322
- j: (base: I) => J,
323
- k: (base: J) => K,
324
- l: (base: K) => L,
325
- m: (base: L) => M,
326
- n: (base: M) => N,
327
- o: (base: N) => O,
328
- ): O;
329
- export function BaseModelWith<
330
- A extends Constructor,
331
- B extends Constructor,
332
- C extends Constructor,
333
- D extends Constructor,
334
- E extends Constructor,
335
- F extends Constructor,
336
- G extends Constructor,
337
- H extends Constructor,
338
- I extends Constructor,
339
- J extends Constructor,
340
- K extends Constructor,
341
- L extends Constructor,
342
- M extends Constructor,
343
- N extends Constructor,
344
- O extends Constructor,
345
- P extends Constructor,
346
- >(
347
- a: (base: Base) => A,
348
- b: (base: A) => B,
349
- c: (base: B) => C,
350
- d: (base: C) => D,
351
- e: (base: D) => E,
352
- f: (base: E) => F,
353
- g: (base: F) => G,
354
- h: (base: G) => H,
355
- i: (base: H) => I,
356
- j: (base: I) => J,
357
- k: (base: J) => K,
358
- l: (base: K) => L,
359
- m: (base: L) => M,
360
- n: (base: M) => N,
361
- o: (base: N) => O,
362
- p: (base: O) => P,
363
- ): P;
364
- export function BaseModelWith<
365
- A extends Constructor,
366
- B extends Constructor,
367
- C extends Constructor,
368
- D extends Constructor,
369
- E extends Constructor,
370
- F extends Constructor,
371
- G extends Constructor,
372
- H extends Constructor,
373
- I extends Constructor,
374
- J extends Constructor,
375
- K extends Constructor,
376
- L extends Constructor,
377
- M extends Constructor,
378
- N extends Constructor,
379
- O extends Constructor,
380
- P extends Constructor,
381
- Q extends Constructor,
382
- >(
383
- a: (base: Base) => A,
384
- b: (base: A) => B,
385
- c: (base: B) => C,
386
- d: (base: C) => D,
387
- e: (base: D) => E,
388
- f: (base: E) => F,
389
- g: (base: F) => G,
390
- h: (base: G) => H,
391
- i: (base: H) => I,
392
- j: (base: I) => J,
393
- k: (base: J) => K,
394
- l: (base: K) => L,
395
- m: (base: L) => M,
396
- n: (base: M) => N,
397
- o: (base: N) => O,
398
- p: (base: O) => P,
399
- q: (base: P) => Q,
400
- ): Q;
401
- export function BaseModelWith<
402
- A extends Constructor,
403
- B extends Constructor,
404
- C extends Constructor,
405
- D extends Constructor,
406
- E extends Constructor,
407
- F extends Constructor,
408
- G extends Constructor,
409
- H extends Constructor,
410
- I extends Constructor,
411
- J extends Constructor,
412
- K extends Constructor,
413
- L extends Constructor,
414
- M extends Constructor,
415
- N extends Constructor,
416
- O extends Constructor,
417
- P extends Constructor,
418
- Q extends Constructor,
419
- R extends Constructor,
420
- >(
421
- a: (base: Base) => A,
422
- b: (base: A) => B,
423
- c: (base: B) => C,
424
- d: (base: C) => D,
425
- e: (base: D) => E,
426
- f: (base: E) => F,
427
- g: (base: F) => G,
428
- h: (base: G) => H,
429
- i: (base: H) => I,
430
- j: (base: I) => J,
431
- k: (base: J) => K,
432
- l: (base: K) => L,
433
- m: (base: L) => M,
434
- n: (base: M) => N,
435
- o: (base: N) => O,
436
- p: (base: O) => P,
437
- q: (base: P) => Q,
438
- r: (base: Q) => R,
439
- ): R;
440
- export function BaseModelWith<
441
- A extends Constructor,
442
- B extends Constructor,
443
- C extends Constructor,
444
- D extends Constructor,
445
- E extends Constructor,
446
- F extends Constructor,
447
- G extends Constructor,
448
- H extends Constructor,
449
- I extends Constructor,
450
- J extends Constructor,
451
- K extends Constructor,
452
- L extends Constructor,
453
- M extends Constructor,
454
- N extends Constructor,
455
- O extends Constructor,
456
- P extends Constructor,
457
- Q extends Constructor,
458
- R extends Constructor,
459
- S extends Constructor,
460
- >(
461
- a: (base: Base) => A,
462
- b: (base: A) => B,
463
- c: (base: B) => C,
464
- d: (base: C) => D,
465
- e: (base: D) => E,
466
- f: (base: E) => F,
467
- g: (base: F) => G,
468
- h: (base: G) => H,
469
- i: (base: H) => I,
470
- j: (base: I) => J,
471
- k: (base: J) => K,
472
- l: (base: K) => L,
473
- m: (base: L) => M,
474
- n: (base: M) => N,
475
- o: (base: N) => O,
476
- p: (base: O) => P,
477
- q: (base: P) => Q,
478
- r: (base: Q) => R,
479
- s: (base: R) => S,
480
- ): S;
481
- export function BaseModelWith<
482
- A extends Constructor,
483
- B extends Constructor,
484
- C extends Constructor,
485
- D extends Constructor,
486
- E extends Constructor,
487
- F extends Constructor,
488
- G extends Constructor,
489
- H extends Constructor,
490
- I extends Constructor,
491
- J extends Constructor,
492
- K extends Constructor,
493
- L extends Constructor,
494
- M extends Constructor,
495
- N extends Constructor,
496
- O extends Constructor,
497
- P extends Constructor,
498
- Q extends Constructor,
499
- R extends Constructor,
500
- S extends Constructor,
501
- T extends Constructor,
502
- >(
503
- a: (base: Base) => A,
504
- b: (base: A) => B,
505
- c: (base: B) => C,
506
- d: (base: C) => D,
507
- e: (base: D) => E,
508
- f: (base: E) => F,
509
- g: (base: F) => G,
510
- h: (base: G) => H,
511
- i: (base: H) => I,
512
- j: (base: I) => J,
513
- k: (base: J) => K,
514
- l: (base: K) => L,
515
- m: (base: L) => M,
516
- n: (base: M) => N,
517
- o: (base: N) => O,
518
- p: (base: O) => P,
519
- q: (base: P) => Q,
520
- r: (base: Q) => R,
521
- s: (base: R) => S,
522
- t: (base: S) => T,
523
- ): T;
49
+ export interface Compose {
50
+ <TBase extends Constructor, A extends Constructor>(this: TBase, a: (base: TBase) => A): A;
51
+ <TBase extends Constructor, A extends Constructor, B extends Constructor>(
52
+ this: TBase,
53
+ a: (base: TBase) => A,
54
+ b: (base: A) => B,
55
+ ): B;
56
+ <TBase extends Constructor, A extends Constructor, B extends Constructor, C extends Constructor>(
57
+ this: TBase,
58
+ a: (base: TBase) => A,
59
+ b: (base: A) => B,
60
+ c: (base: B) => C,
61
+ ): C;
62
+ <
63
+ TBase extends Constructor,
64
+ A extends Constructor,
65
+ B extends Constructor,
66
+ C extends Constructor,
67
+ D extends Constructor,
68
+ >(
69
+ this: TBase,
70
+ a: (base: TBase) => A,
71
+ b: (base: A) => B,
72
+ c: (base: B) => C,
73
+ d: (base: C) => D,
74
+ ): D;
75
+ <
76
+ TBase extends Constructor,
77
+ A extends Constructor,
78
+ B extends Constructor,
79
+ C extends Constructor,
80
+ D extends Constructor,
81
+ E extends Constructor,
82
+ >(
83
+ this: TBase,
84
+ a: (base: TBase) => A,
85
+ b: (base: A) => B,
86
+ c: (base: B) => C,
87
+ d: (base: C) => D,
88
+ e: (base: D) => E,
89
+ ): E;
90
+ <
91
+ TBase extends Constructor,
92
+ A extends Constructor,
93
+ B extends Constructor,
94
+ C extends Constructor,
95
+ D extends Constructor,
96
+ E extends Constructor,
97
+ F extends Constructor,
98
+ >(
99
+ this: TBase,
100
+ a: (base: TBase) => A,
101
+ b: (base: A) => B,
102
+ c: (base: B) => C,
103
+ d: (base: C) => D,
104
+ e: (base: D) => E,
105
+ f: (base: E) => F,
106
+ ): F;
107
+ <
108
+ TBase extends Constructor,
109
+ A extends Constructor,
110
+ B extends Constructor,
111
+ C extends Constructor,
112
+ D extends Constructor,
113
+ E extends Constructor,
114
+ F extends Constructor,
115
+ G extends Constructor,
116
+ >(
117
+ this: TBase,
118
+ a: (base: TBase) => A,
119
+ b: (base: A) => B,
120
+ c: (base: B) => C,
121
+ d: (base: C) => D,
122
+ e: (base: D) => E,
123
+ f: (base: E) => F,
124
+ g: (base: F) => G,
125
+ ): G;
126
+ <
127
+ TBase extends Constructor,
128
+ A extends Constructor,
129
+ B extends Constructor,
130
+ C extends Constructor,
131
+ D extends Constructor,
132
+ E extends Constructor,
133
+ F extends Constructor,
134
+ G extends Constructor,
135
+ H extends Constructor,
136
+ >(
137
+ this: TBase,
138
+ a: (base: TBase) => A,
139
+ b: (base: A) => B,
140
+ c: (base: B) => C,
141
+ d: (base: C) => D,
142
+ e: (base: D) => E,
143
+ f: (base: E) => F,
144
+ g: (base: F) => G,
145
+ h: (base: G) => H,
146
+ ): H;
147
+ }
524
148
 
525
- // Implementation: fold the mixins over BaseModel, left to right. The base param is
526
- // `any` so each typed overload above (whose base is the narrower `typeof BaseModel`
527
- // or a prior mixin's result) stays assignable to this implementation signature.
528
- export function BaseModelWith(
149
+ /**
150
+ * The fold behind {@link Compose}: apply each mixin left-to-right, seeding from `this` (the
151
+ * class `using` was called on). Assigned to `BaseModel.using` not exported publicly.
152
+ *
153
+ * @internal
154
+ */
155
+ export const _compose = function (
156
+ this: Constructor,
529
157
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- variadic mixin folder
530
158
  ...mixins: Array<(base: any) => Constructor>
531
159
  ): Constructor {
532
- return mixins.reduce<Constructor>(
533
- (acc, mixin) => mixin(acc),
534
- BaseModel as unknown as Constructor,
535
- );
536
- }
160
+ return mixins.reduce<Constructor>((acc, mixin) => mixin(acc), this);
161
+ } as Compose;