@bunyad/orm 0.2.0-beta.1 → 0.2.0-beta.2
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 +1 -1
- package/dist/casts.d.ts +16 -3
- package/dist/casts.js +150 -4
- package/dist/eager.js +130 -11
- package/dist/factory.d.ts +20 -1
- package/dist/factory.js +143 -37
- package/dist/index.d.ts +21 -1
- package/dist/index.js +3 -1
- package/dist/model-events.d.ts +8 -2
- package/dist/model-events.js +27 -4
- package/dist/model-query.d.ts +75 -29
- package/dist/model-query.js +252 -133
- package/dist/model.d.ts +164 -34
- package/dist/model.js +708 -44
- package/dist/relations.d.ts +187 -11
- package/dist/relations.js +815 -89
- package/dist/schema-types.d.ts +27 -0
- package/dist/schema-types.js +145 -0
- package/dist/test-drivers.d.ts +10 -0
- package/dist/test-drivers.js +40 -0
- package/dist/typed-names.d.ts +53 -0
- package/dist/typed-names.js +4 -0
- package/package.json +3 -3
package/dist/relations.d.ts
CHANGED
|
@@ -12,12 +12,34 @@ type RelationWriteKey = (typeof RELATION_QUERY_WRITE)[number];
|
|
|
12
12
|
/** Types for the methods `installRelationQueryForwarders` adds to every relation. */
|
|
13
13
|
type RelationQuery<T extends Model> = Pick<ModelQuery<T>, RelationQueryKey>;
|
|
14
14
|
type RelationWrite<T extends Model> = Pick<ModelQuery<T>, RelationWriteKey>;
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Strip `__pivot_*` columns onto `model.pivot` (or the `as()` accessor). With
|
|
17
|
+
* `using(PivotModel)` the pivot is an instance of that model, so its casts and
|
|
18
|
+
* methods apply.
|
|
19
|
+
*/
|
|
20
|
+
export declare function applyPivotAttributes(model: Model, attrs: Record<string, unknown>, pivotKeys: string[], options?: {
|
|
21
|
+
accessor?: string;
|
|
22
|
+
pivotClass?: ModelClass;
|
|
23
|
+
}): Model;
|
|
24
|
+
export declare function registerMorphClass(model: ModelClass): void;
|
|
25
|
+
/**
|
|
26
|
+
* `Relation::morphMap` — register aliases, or read the current map when called
|
|
27
|
+
* with no arguments. Pass `merge = false` to replace the existing map.
|
|
28
|
+
*/
|
|
29
|
+
export declare function morphMap(): Record<string, ModelClass>;
|
|
30
|
+
export declare function morphMap(map: Record<string, ModelClass>, merge?: boolean): Record<string, ModelClass>;
|
|
31
|
+
/** `Relation::enforceMorphMap` — register the map and refuse unmapped classes. */
|
|
32
|
+
export declare function enforceMorphMap(map: Record<string, ModelClass>, merge?: boolean): Record<string, ModelClass>;
|
|
33
|
+
/** `Relation::requireMorphMap` — throw when a model without an alias is used polymorphically. */
|
|
34
|
+
export declare function requireMorphMap(required?: boolean): void;
|
|
35
|
+
export declare function requiresMorphMap(): boolean;
|
|
18
36
|
export declare function clearMorphMap(): void;
|
|
19
37
|
export declare function morphTypeFor(model: ModelClass): string;
|
|
38
|
+
/** `Relation::getMorphedModel` — class for an alias, or undefined. */
|
|
39
|
+
export declare function getMorphedModel(type: string): ModelClass | undefined;
|
|
20
40
|
export declare function resolveMorphType(type: string): ModelClass;
|
|
41
|
+
/** `withDefault` support shared by the single-result relations (belongsTo, hasOne, morphOne). */
|
|
42
|
+
export type DefaultSpec<T extends Model> = true | Record<string, unknown> | ((model: T, parent: Model) => void);
|
|
21
43
|
/** MorphMany relation. */
|
|
22
44
|
export declare class MorphMany<T extends Model = Model> {
|
|
23
45
|
#private;
|
|
@@ -34,6 +56,13 @@ export declare class MorphMany<T extends Model = Model> {
|
|
|
34
56
|
getMorphType(): string;
|
|
35
57
|
getLocalKeyName(): string;
|
|
36
58
|
/** Constrained related query (`morphMany().where(…).get()`). */
|
|
59
|
+
/**
|
|
60
|
+
* `chaperone($inverse)` — set the parent on every loaded child (`post.user` without a query).
|
|
61
|
+
* The inverse name defaults to the parent class name in camelCase.
|
|
62
|
+
*/
|
|
63
|
+
chaperone(inverse?: string): this;
|
|
64
|
+
/** Property the parent is set on, or `undefined` when `chaperone()` was not called. */
|
|
65
|
+
getInverse(): string | undefined;
|
|
37
66
|
getQuery(): ModelQuery<T>;
|
|
38
67
|
get(): Promise<OrmCollection<T>>;
|
|
39
68
|
first(): Promise<T | null>;
|
|
@@ -60,6 +89,11 @@ export declare class MorphOne<T extends Model = Model> {
|
|
|
60
89
|
latestOfMany(column?: string): this;
|
|
61
90
|
oldestOfMany(column?: string): this;
|
|
62
91
|
ofMany(column: string, aggregate: "min" | "max"): this;
|
|
92
|
+
/** `withDefault` — return an empty related model instead of `null` when nothing matches. */
|
|
93
|
+
withDefault(spec?: DefaultSpec<T>): this;
|
|
94
|
+
hasDefault(): boolean;
|
|
95
|
+
/** The default model for the owner this relation was built from. */
|
|
96
|
+
makeDefault(): T;
|
|
63
97
|
getQuery(): ModelQuery<T>;
|
|
64
98
|
get(): Promise<T | null>;
|
|
65
99
|
first(): Promise<T | null>;
|
|
@@ -94,6 +128,13 @@ export declare class HasMany<T extends Model = Model> {
|
|
|
94
128
|
getForeignKeyName(): string;
|
|
95
129
|
getLocalKeyName(): string;
|
|
96
130
|
/** Constrained related query (`hasMany().where(…).orderBy(…).get()`). */
|
|
131
|
+
/**
|
|
132
|
+
* `chaperone($inverse)` — set the parent on every loaded child (`post.user` without a query).
|
|
133
|
+
* The inverse name defaults to the parent class name in camelCase.
|
|
134
|
+
*/
|
|
135
|
+
chaperone(inverse?: string): this;
|
|
136
|
+
/** Property the parent is set on, or `undefined` when `chaperone()` was not called. */
|
|
137
|
+
getInverse(): string | undefined;
|
|
97
138
|
getQuery(): ModelQuery<T>;
|
|
98
139
|
get(): Promise<OrmCollection<T>>;
|
|
99
140
|
first(): Promise<T | null>;
|
|
@@ -121,6 +162,18 @@ export declare class HasOne<T extends Model = Model> {
|
|
|
121
162
|
oldestOfMany(column?: string): this;
|
|
122
163
|
/** Constrain to the related row with min/max of `column`. */
|
|
123
164
|
ofMany(column: string, aggregate: "min" | "max"): this;
|
|
165
|
+
/** `withDefault` — return an empty related model instead of `null` when nothing matches. */
|
|
166
|
+
withDefault(spec?: DefaultSpec<T>): this;
|
|
167
|
+
hasDefault(): boolean;
|
|
168
|
+
/** The default model for the owner this relation was built from. */
|
|
169
|
+
makeDefault(): T;
|
|
170
|
+
/**
|
|
171
|
+
* `chaperone($inverse)` — set the parent on every loaded child (`post.user` without a query).
|
|
172
|
+
* The inverse name defaults to the parent class name in camelCase.
|
|
173
|
+
*/
|
|
174
|
+
chaperone(inverse?: string): this;
|
|
175
|
+
/** Property the parent is set on, or `undefined` when `chaperone()` was not called. */
|
|
176
|
+
getInverse(): string | undefined;
|
|
124
177
|
getQuery(): ModelQuery<T>;
|
|
125
178
|
get(): Promise<T | null>;
|
|
126
179
|
first(): Promise<T | null>;
|
|
@@ -178,6 +231,11 @@ export declare class BelongsTo<T extends Model = Model> {
|
|
|
178
231
|
getRelated(): ModelClass;
|
|
179
232
|
getForeignKeyName(): string;
|
|
180
233
|
getOwnerKeyName(): string;
|
|
234
|
+
/** `withDefault` — return an empty related model instead of `null` when nothing matches. */
|
|
235
|
+
withDefault(spec?: DefaultSpec<T>): this;
|
|
236
|
+
hasDefault(): boolean;
|
|
237
|
+
/** The default model for the owner this relation was built from. */
|
|
238
|
+
makeDefault(): T;
|
|
181
239
|
getQuery(): ModelQuery<T>;
|
|
182
240
|
get(): Promise<T | null>;
|
|
183
241
|
first(): Promise<T | null>;
|
|
@@ -194,6 +252,38 @@ export declare class BelongsTo<T extends Model = Model> {
|
|
|
194
252
|
touchSync(): boolean;
|
|
195
253
|
}
|
|
196
254
|
/** BelongsToMany relation. */
|
|
255
|
+
/**
|
|
256
|
+
* Point `child[inverse]` at its parent without making it enumerable: a back-reference
|
|
257
|
+
* must not be serialized (`toJSON`) or treated as an attribute, or parent → child → parent recurses.
|
|
258
|
+
*/
|
|
259
|
+
export declare function setInverse(child: unknown, inverse: string, parent: Model): void;
|
|
260
|
+
/** `wherePivot*` constraints on a many-to-many pivot table (AND only). */
|
|
261
|
+
export type PivotWhere = {
|
|
262
|
+
kind: "basic";
|
|
263
|
+
column: string;
|
|
264
|
+
op: string;
|
|
265
|
+
value: unknown;
|
|
266
|
+
} | {
|
|
267
|
+
kind: "in";
|
|
268
|
+
column: string;
|
|
269
|
+
values: unknown[];
|
|
270
|
+
not: boolean;
|
|
271
|
+
} | {
|
|
272
|
+
kind: "null";
|
|
273
|
+
column: string;
|
|
274
|
+
not: boolean;
|
|
275
|
+
} | {
|
|
276
|
+
kind: "between";
|
|
277
|
+
column: string;
|
|
278
|
+
values: [unknown, unknown];
|
|
279
|
+
not: boolean;
|
|
280
|
+
};
|
|
281
|
+
export type PivotOrder = {
|
|
282
|
+
column: string;
|
|
283
|
+
direction: "asc" | "desc";
|
|
284
|
+
};
|
|
285
|
+
/** Apply pivot wheres to a ModelQuery / QueryBuilder, qualified with the pivot table. */
|
|
286
|
+
export declare function applyPivotWheres(q: unknown, pivotTable: string, wheres: readonly PivotWhere[]): void;
|
|
197
287
|
export declare class BelongsToMany<T extends Model = Model> {
|
|
198
288
|
#private;
|
|
199
289
|
private parent;
|
|
@@ -212,13 +302,58 @@ export declare class BelongsToMany<T extends Model = Model> {
|
|
|
212
302
|
getQuery(): ModelQuery<T>;
|
|
213
303
|
get(): Promise<OrmCollection<T>>;
|
|
214
304
|
first(): Promise<T | null>;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
305
|
+
/** `withTimestamps` — stamp `created_at` / `updated_at` on pivot writes. */
|
|
306
|
+
withTimestamps(): this;
|
|
307
|
+
/** `as('membership')` — expose the pivot under another property name than `pivot`. */
|
|
308
|
+
as(accessor: string): this;
|
|
309
|
+
/**
|
|
310
|
+
* `using(MembershipPivot)` — hydrate the pivot as a model (casts and methods apply)
|
|
311
|
+
* and run pivot writes (`attach`, `sync`, `updateExistingPivot`) through its "set" casts.
|
|
312
|
+
*/
|
|
313
|
+
using(pivotClass: ModelClass): this;
|
|
314
|
+
getPivotAccessor(): string;
|
|
315
|
+
getPivotClass(): ModelClass | undefined;
|
|
316
|
+
getPivotWheres(): PivotWhere[];
|
|
317
|
+
getPivotOrders(): PivotOrder[];
|
|
318
|
+
/**
|
|
319
|
+
* `wherePivot` — constrain the pivot row. Also scopes `attach` defaults, `sync`,
|
|
320
|
+
* `detach` and `updateExistingPivot`, so two relations on one pivot table with
|
|
321
|
+
* different `wherePivot` values stay independent.
|
|
322
|
+
*/
|
|
323
|
+
wherePivot(column: string, value: unknown): this;
|
|
324
|
+
wherePivot(column: string, op: string, value: unknown): this;
|
|
325
|
+
wherePivotIn(column: string, values: unknown[]): this;
|
|
326
|
+
wherePivotNotIn(column: string, values: unknown[]): this;
|
|
327
|
+
wherePivotNull(column: string): this;
|
|
328
|
+
wherePivotNotNull(column: string): this;
|
|
329
|
+
wherePivotBetween(column: string, values: [unknown, unknown]): this;
|
|
330
|
+
wherePivotNotBetween(column: string, values: [unknown, unknown]): this;
|
|
331
|
+
/** `orderByPivot` — order related rows by a pivot column. */
|
|
332
|
+
orderByPivot(column: string, direction?: "asc" | "desc"): this;
|
|
333
|
+
/** `attach` — one multi-row INSERT per chunk; optional pivot attributes. */
|
|
334
|
+
attach(ids: PivotIds, attributes?: Record<string, unknown>): Promise<void>;
|
|
335
|
+
/** `detach` — returns the number of deleted pivot rows. */
|
|
336
|
+
detach(ids?: PivotIds): Promise<number>;
|
|
337
|
+
/** `updateExistingPivot` — update pivot columns for one related id. Returns affected rows. */
|
|
338
|
+
updateExistingPivot(id: string | number | Model, attributes: Record<string, unknown>): Promise<number>;
|
|
339
|
+
/**
|
|
340
|
+
* `sync` — diff against existing rows: attach new, detach removed, and update
|
|
341
|
+
* pivot attributes of kept rows when the map form supplies them.
|
|
342
|
+
*/
|
|
343
|
+
sync(ids: PivotIds, detaching?: boolean): Promise<PivotSyncResult>;
|
|
344
|
+
/** `syncWithoutDetaching`. */
|
|
345
|
+
syncWithoutDetaching(ids: PivotIds): Promise<PivotSyncResult>;
|
|
346
|
+
/** `toggle` — attach missing, detach present. */
|
|
347
|
+
toggle(ids: PivotIds): Promise<{
|
|
348
|
+
attached: Array<string | number>;
|
|
349
|
+
detached: Array<string | number>;
|
|
350
|
+
}>;
|
|
351
|
+
}
|
|
352
|
+
export type PivotIds = string | number | Model | Array<string | number | Model> | Record<string | number, Record<string, unknown>>;
|
|
353
|
+
export interface PivotSyncResult {
|
|
354
|
+
attached: Array<string | number>;
|
|
355
|
+
detached: Array<string | number>;
|
|
356
|
+
updated: Array<string | number>;
|
|
222
357
|
}
|
|
223
358
|
/** Options for `morphToMany` beyond the positional args. */
|
|
224
359
|
export type MorphToManyOptions = {
|
|
@@ -260,8 +395,42 @@ export declare class MorphToMany<T extends Model = Model> {
|
|
|
260
395
|
/** Primary morph type written on attach (first configured type). */
|
|
261
396
|
getMorphType(): string;
|
|
262
397
|
get(): Promise<OrmCollection<T>>;
|
|
398
|
+
/** One multi-row INSERT per chunk (was one INSERT per id). */
|
|
399
|
+
attach(ids: Array<string | number> | string | number): Promise<void>;
|
|
400
|
+
/** Returns the number of deleted pivot rows. */
|
|
401
|
+
detach(ids?: Array<string | number> | string | number): Promise<number>;
|
|
402
|
+
/** Diff-based: keeps existing rows, attaches new ids, detaches removed ones. */
|
|
403
|
+
sync(ids: Array<string | number>): Promise<PivotSyncResult>;
|
|
404
|
+
syncWithoutDetaching(ids: Array<string | number>): Promise<PivotSyncResult>;
|
|
405
|
+
toggle(ids: Array<string | number> | string | number): Promise<{
|
|
406
|
+
attached: Array<string | number>;
|
|
407
|
+
detached: Array<string | number>;
|
|
408
|
+
}>;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* `morphedByMany` — inverse of a `morphToMany` (`taggables` pivot).
|
|
412
|
+
* Parent is the "tag" side; the pivot stores the related model's id and morph type.
|
|
413
|
+
*/
|
|
414
|
+
export declare class MorphedByMany<T extends Model = Model> {
|
|
415
|
+
#private;
|
|
416
|
+
private parent;
|
|
417
|
+
private related;
|
|
418
|
+
private pivotTable;
|
|
419
|
+
private foreignPivotKey;
|
|
420
|
+
private relatedPivotKey;
|
|
421
|
+
private morphTypeColumn;
|
|
422
|
+
private morphType;
|
|
423
|
+
constructor(parent: Model, related: ModelClass, pivotTable: string, foreignPivotKey: string, relatedPivotKey: string, morphTypeColumn: string, morphType: string);
|
|
424
|
+
getRelated(): ModelClass;
|
|
425
|
+
getPivotTable(): string;
|
|
426
|
+
getForeignPivotKeyName(): string;
|
|
427
|
+
getRelatedPivotKeyName(): string;
|
|
428
|
+
getMorphTypeColumn(): string;
|
|
429
|
+
getMorphType(): string;
|
|
430
|
+
get(): Promise<OrmCollection<T>>;
|
|
263
431
|
attach(ids: Array<string | number> | string | number): Promise<void>;
|
|
264
|
-
detach(ids?: Array<string | number> | string | number): Promise<
|
|
432
|
+
detach(ids?: Array<string | number> | string | number): Promise<number>;
|
|
433
|
+
/** Detach missing ids, attach new ones; keeps rows that stay */
|
|
265
434
|
sync(ids: Array<string | number>): Promise<void>;
|
|
266
435
|
syncWithoutDetaching(ids: Array<string | number>): Promise<void>;
|
|
267
436
|
toggle(ids: Array<string | number> | string | number): Promise<void>;
|
|
@@ -271,6 +440,9 @@ export type RelationMeta = {
|
|
|
271
440
|
related: ModelClass;
|
|
272
441
|
foreignKey: string;
|
|
273
442
|
localKey: string;
|
|
443
|
+
/** morphOne / morphMany: the related rows must also carry this morph type. */
|
|
444
|
+
typeColumn?: string;
|
|
445
|
+
morphType?: string;
|
|
274
446
|
} | {
|
|
275
447
|
kind: "belongsTo";
|
|
276
448
|
related: ModelClass;
|
|
@@ -284,6 +456,7 @@ export type RelationMeta = {
|
|
|
284
456
|
relatedPivotKey: string;
|
|
285
457
|
localKey: string;
|
|
286
458
|
pivotColumns: string[];
|
|
459
|
+
pivotWheres: PivotWhere[];
|
|
287
460
|
} | {
|
|
288
461
|
kind: "morphToMany";
|
|
289
462
|
related: ModelClass;
|
|
@@ -313,6 +486,9 @@ export type RelationMeta = {
|
|
|
313
486
|
secondLocalKey: string;
|
|
314
487
|
};
|
|
315
488
|
export declare function resolveRelation(model: ModelClass, relation: string): RelationMeta | null;
|
|
489
|
+
/** Relation metadata for aggregate subqueries (morphOne / morphMany resolve as `has` + morph type). */
|
|
490
|
+
export type AggregateRelationMeta = RelationMeta;
|
|
491
|
+
export declare function resolveAggregateRelation(model: ModelClass, relation: string): AggregateRelationMeta | null;
|
|
316
492
|
export declare function countRelation(model: Model, relation: string): Promise<number>;
|
|
317
493
|
/** Run COUNT/SUM/AVG/MIN/MAX/EXISTS for a relation on one model instance. */
|
|
318
494
|
export declare function aggregateRelation(model: Model, relation: string, fn: "count" | "sum" | "avg" | "min" | "max" | "exists", column?: string): Promise<unknown>;
|