@relations-dil/relations 0.1.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.
- package/LICENSE +21 -0
- package/README.md +824 -0
- package/dist/dynamic.d.ts +122 -0
- package/dist/dynamic.js +164 -0
- package/dist/errors.d.ts +31 -0
- package/dist/errors.js +50 -0
- package/dist/field.d.ts +157 -0
- package/dist/field.js +660 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.js +75 -0
- package/dist/kinds.d.ts +99 -0
- package/dist/kinds.js +169 -0
- package/dist/migrations.d.ts +62 -0
- package/dist/migrations.js +293 -0
- package/dist/mock.d.ts +88 -0
- package/dist/mock.js +511 -0
- package/dist/model.d.ts +277 -0
- package/dist/model.js +1159 -0
- package/dist/overscore.d.ts +66 -0
- package/dist/overscore.js +226 -0
- package/dist/record.d.ts +58 -0
- package/dist/record.js +246 -0
- package/dist/registry.d.ts +24 -0
- package/dist/registry.js +27 -0
- package/dist/relation.d.ts +114 -0
- package/dist/relation.js +145 -0
- package/dist/source.d.ts +147 -0
- package/dist/source.js +409 -0
- package/dist/titles.d.ts +43 -0
- package/dist/titles.js +115 -0
- package/dist/typed.d.ts +99 -0
- package/dist/typed.js +44 -0
- package/dist/util.d.ts +16 -0
- package/dist/util.js +117 -0
- package/package.json +68 -0
package/dist/model.d.ts
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Models: what you actually write, and the only thing that knows about relations.
|
|
3
|
+
*/
|
|
4
|
+
import { Field, type FieldOptions } from './field.js';
|
|
5
|
+
import { Record } from './record.js';
|
|
6
|
+
import { type FieldKind, type Kind } from './kinds.js';
|
|
7
|
+
import type { ManyToMany, OneTo } from './relation.js';
|
|
8
|
+
/** What a model is currently doing. */
|
|
9
|
+
export type ModelAction = 'create' | 'retrieve' | 'update';
|
|
10
|
+
/** Whether a model holds one record or many. */
|
|
11
|
+
export type ModelMode = 'one' | 'many';
|
|
12
|
+
/** What a model is to whatever reached it. */
|
|
13
|
+
export type ModelRole = 'model' | 'parent' | 'child';
|
|
14
|
+
/** Everything accepted as a field declaration in `static fields`. */
|
|
15
|
+
export type FieldSpec = Kind | Field | Set<any> | any[] | (() => any) | ({
|
|
16
|
+
kind: FieldKind;
|
|
17
|
+
} & FieldOptions);
|
|
18
|
+
/** Options relations passes to itself when building related or loaded models. */
|
|
19
|
+
interface Internals {
|
|
20
|
+
read?: globalThis.Record<string, any>;
|
|
21
|
+
child?: globalThis.Record<string, any>;
|
|
22
|
+
parent?: globalThis.Record<string, any>;
|
|
23
|
+
sibling?: globalThis.Record<string, any>;
|
|
24
|
+
action?: ModelAction;
|
|
25
|
+
mode?: ModelMode;
|
|
26
|
+
chunk?: number;
|
|
27
|
+
bulk?: boolean;
|
|
28
|
+
size?: number;
|
|
29
|
+
related?: globalThis.Record<string, any>;
|
|
30
|
+
args?: any[];
|
|
31
|
+
}
|
|
32
|
+
/** Turn a `static fields` entry into an actual Field. */
|
|
33
|
+
export declare function toField(spec: FieldSpec): Field;
|
|
34
|
+
/**
|
|
35
|
+
* What's knowable about a model without having an instance of it: its name, its fields,
|
|
36
|
+
* its indexes, its relations. Sources and migrations work against this.
|
|
37
|
+
*/
|
|
38
|
+
export declare class ModelIdentity {
|
|
39
|
+
/** Anything else the model class hung off itself in uppercase. */
|
|
40
|
+
[attribute: string]: any;
|
|
41
|
+
/** Name of the source this model lives in. */
|
|
42
|
+
SOURCE: string | null;
|
|
43
|
+
/** Human-facing title of the model. */
|
|
44
|
+
TITLE: string | null;
|
|
45
|
+
/** Name of the model in the source. */
|
|
46
|
+
NAME: string | null;
|
|
47
|
+
/** Whether this model is a many-to-many tie table. */
|
|
48
|
+
TIE: boolean | null;
|
|
49
|
+
/** Parent relations, keyed by the attribute on this model. */
|
|
50
|
+
PARENTS: globalThis.Record<string, OneTo>;
|
|
51
|
+
/** Child relations, keyed by the attribute on this model. */
|
|
52
|
+
CHILDREN: globalThis.Record<string, OneTo>;
|
|
53
|
+
/** Sister relations, keyed by the attribute on this model. */
|
|
54
|
+
SISTERS: globalThis.Record<string, ManyToMany>;
|
|
55
|
+
/** Brother relations, keyed by the attribute on this model. */
|
|
56
|
+
BROTHERS: globalThis.Record<string, ManyToMany>;
|
|
57
|
+
/** Default chunk size for related lookups and bulk creates. */
|
|
58
|
+
CHUNK: number;
|
|
59
|
+
/** The model's fields, in order. Records are built from these. */
|
|
60
|
+
_fields: Record;
|
|
61
|
+
/** Name of the id field, if there is one. */
|
|
62
|
+
_id: string | null;
|
|
63
|
+
/** Fields that make up a title. */
|
|
64
|
+
_titles: string[];
|
|
65
|
+
/** Fields to show in a listing. */
|
|
66
|
+
_list: string[];
|
|
67
|
+
/** Unique indexes, keyed by index name. */
|
|
68
|
+
_unique: globalThis.Record<string, string[]>;
|
|
69
|
+
/** Regular indexes, keyed by index name. */
|
|
70
|
+
_index: globalThis.Record<string, string[]>;
|
|
71
|
+
/** Default sort order, as signed field names. */
|
|
72
|
+
_order: string[];
|
|
73
|
+
/** The name of a field, whether given by name or position. */
|
|
74
|
+
_fieldName(field: string | number): string;
|
|
75
|
+
/** Turn a sort spec into signed field names, checking each one exists. */
|
|
76
|
+
_ordering(sort: string | string[]): string[];
|
|
77
|
+
/** The parent relation a field points at, if any. */
|
|
78
|
+
_ancestor(field: string): OneTo | null;
|
|
79
|
+
/** The full definition of this model, for schemas and migrations. */
|
|
80
|
+
define(): globalThis.Record<string, any>;
|
|
81
|
+
/** How to get from a previous definition of this model to this one. */
|
|
82
|
+
migrate(previous: globalThis.Record<string, any>, definition?: globalThis.Record<string, any>): globalThis.Record<string, any>;
|
|
83
|
+
}
|
|
84
|
+
export declare const MigrationsRef: {
|
|
85
|
+
model: (current: any, define: any) => any;
|
|
86
|
+
};
|
|
87
|
+
/** The static shape of a model class. */
|
|
88
|
+
export interface ModelClass<M extends Model = Model> {
|
|
89
|
+
new (...args: any[]): M;
|
|
90
|
+
source?: string;
|
|
91
|
+
fields?: globalThis.Record<string, FieldSpec>;
|
|
92
|
+
store?: string;
|
|
93
|
+
title?: string;
|
|
94
|
+
id?: string | number | null;
|
|
95
|
+
titles?: string | string[];
|
|
96
|
+
list?: string | string[];
|
|
97
|
+
unique?: string | string[] | globalThis.Record<string, string[]> | false;
|
|
98
|
+
index?: string | string[] | globalThis.Record<string, string[]>;
|
|
99
|
+
order?: string | string[];
|
|
100
|
+
chunk?: number;
|
|
101
|
+
thy(target?: ModelIdentity): ModelIdentity;
|
|
102
|
+
[member: string]: any;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* A model. Extend it, declare `static source` and `static fields`, and you have
|
|
106
|
+
* something you can create, retrieve, update and delete against any source.
|
|
107
|
+
*
|
|
108
|
+
* ```ts
|
|
109
|
+
* class Unit extends Model {
|
|
110
|
+
* static source = 'example'
|
|
111
|
+
* static fields = { id: int, name: str }
|
|
112
|
+
* }
|
|
113
|
+
*
|
|
114
|
+
* await new Unit('yep').create()
|
|
115
|
+
* const unit = await Unit.one({ name: 'yep' }).retrieve()
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
export declare class Model extends ModelIdentity {
|
|
119
|
+
/** The single loaded record, in one mode. */
|
|
120
|
+
_record: Record | null;
|
|
121
|
+
/** The loaded models, in many mode. */
|
|
122
|
+
_models: Model[] | null;
|
|
123
|
+
/** Loaded parent models, keyed by attribute. */
|
|
124
|
+
_parents: globalThis.Record<string, Model | null>;
|
|
125
|
+
/** Loaded child models, keyed by attribute. */
|
|
126
|
+
_children: globalThis.Record<string, Model | null>;
|
|
127
|
+
/** Loaded sister models, keyed by attribute. */
|
|
128
|
+
_sisters: globalThis.Record<string, Model | null>;
|
|
129
|
+
/** Loaded brother models, keyed by attribute. */
|
|
130
|
+
_brothers: globalThis.Record<string, Model | null>;
|
|
131
|
+
/** Pending sibling-attribute criteria, keyed by relation attribute. */
|
|
132
|
+
_ties: globalThis.Record<string, globalThis.Record<string, any>>;
|
|
133
|
+
/** What this model is to whatever reached it. */
|
|
134
|
+
_role: ModelRole;
|
|
135
|
+
/** Whether this model holds one record or many. */
|
|
136
|
+
_mode: ModelMode | null;
|
|
137
|
+
/** Whether this is a bulk insert. */
|
|
138
|
+
_bulk: boolean;
|
|
139
|
+
/** Chunk size for this model. */
|
|
140
|
+
_chunk: number;
|
|
141
|
+
/** How many to accumulate before a bulk insert flushes. */
|
|
142
|
+
_size: number;
|
|
143
|
+
/** The current fuzzy match. */
|
|
144
|
+
_like: any;
|
|
145
|
+
/** Sorting to apply on retrieve. */
|
|
146
|
+
_sort: string[] | null;
|
|
147
|
+
/** How many records to retrieve. */
|
|
148
|
+
_limit: number | null;
|
|
149
|
+
/** Where to start retrieving from. */
|
|
150
|
+
_offset: number;
|
|
151
|
+
/** What this model is doing. */
|
|
152
|
+
_action: ModelAction;
|
|
153
|
+
/** Fields set automatically because of a relation. */
|
|
154
|
+
_related: globalThis.Record<string, any>;
|
|
155
|
+
/** Whether a limit was reached, so there may be more records than were returned. */
|
|
156
|
+
overflow: boolean;
|
|
157
|
+
constructor(...args: any[]);
|
|
158
|
+
/**
|
|
159
|
+
* Work out everything knowable about this model class. Called for you on every
|
|
160
|
+
* instance; call it directly when you need a model's shape without an instance.
|
|
161
|
+
*/
|
|
162
|
+
static thy(target?: ModelIdentity): ModelIdentity;
|
|
163
|
+
/** Register a parent relation on this class. */
|
|
164
|
+
static _parent(relation: OneTo): void;
|
|
165
|
+
/** Register a child relation on this class. */
|
|
166
|
+
static _child(relation: OneTo): void;
|
|
167
|
+
/** Register a sister relation on this class. */
|
|
168
|
+
static _sister(relation: ManyToMany): void;
|
|
169
|
+
/** Register a brother relation on this class. */
|
|
170
|
+
static _brother(relation: ManyToMany): void;
|
|
171
|
+
/** Whether a name is one of this model's relation attributes. */
|
|
172
|
+
_isRelation(name: string): boolean;
|
|
173
|
+
/** The related model behind a relation attribute. */
|
|
174
|
+
_relate(name: string): Model | null;
|
|
175
|
+
/** Hold on to a sibling-attribute filter until the source can resolve it. */
|
|
176
|
+
_tie(name: string, remainder: string, value: any): void;
|
|
177
|
+
/**
|
|
178
|
+
* Fold criteria gathered on related models into this model's own criteria. Retrieving
|
|
179
|
+
* the relatives is what makes this async: `Test.many({unit__name: 'x'})` has to find
|
|
180
|
+
* the matching units before it can filter tests by their ids.
|
|
181
|
+
*/
|
|
182
|
+
_collate(): Promise<void>;
|
|
183
|
+
/** Keep relations honest when the field they hang off changes. */
|
|
184
|
+
_propagate(field: string | number, value: any): void;
|
|
185
|
+
/** Fill a record in from positional and named values. */
|
|
186
|
+
_input(record: Record, positional: any[], named: globalThis.Record<string, any>): void;
|
|
187
|
+
/** Build a fresh record for an action. */
|
|
188
|
+
_build(action: 'create' | 'retrieve' | 'update', options?: {
|
|
189
|
+
defaults?: boolean;
|
|
190
|
+
read?: globalThis.Record<string, any>;
|
|
191
|
+
positional?: any[];
|
|
192
|
+
named?: globalThis.Record<string, any>;
|
|
193
|
+
}): Record;
|
|
194
|
+
/**
|
|
195
|
+
* Guard synchronous access. A model that still has to hit the source can't fill
|
|
196
|
+
* itself in from a property getter, so say so plainly instead of returning nothing.
|
|
197
|
+
*/
|
|
198
|
+
_ensureSync(): void;
|
|
199
|
+
/** Retrieve if this model still needs to, then carry on. */
|
|
200
|
+
_ensure(): Promise<void>;
|
|
201
|
+
/** Every model this one stands for: itself in one mode, its models in many. */
|
|
202
|
+
_each(action?: ModelAction): Model[];
|
|
203
|
+
/** Read a value the way `model[key]` does. */
|
|
204
|
+
_item(key: string | number): any;
|
|
205
|
+
/** Write a value the way `model[key] = value` does. */
|
|
206
|
+
_setItem(key: string | number, value: any): void;
|
|
207
|
+
/** Whether a field is reachable right now, the way `key in model` asks in Python. */
|
|
208
|
+
_contains(key: string | number): boolean;
|
|
209
|
+
/** Walk a double-underscored path that starts at a relation. */
|
|
210
|
+
_path(name: string): any;
|
|
211
|
+
/** The proxy wrapping this model, so internals hand back the same object callers hold. */
|
|
212
|
+
_proxy: Model | null;
|
|
213
|
+
/** Add criteria. Positional values match fields in order, named ones by `field__operator`. */
|
|
214
|
+
filter(...args: any[]): this;
|
|
215
|
+
/** A model set up to insert many records without reading their ids back. */
|
|
216
|
+
static bulk<M extends Model>(this: ModelClass<M>, size?: number): M;
|
|
217
|
+
/** A model that will retrieve exactly one record. */
|
|
218
|
+
static one<M extends Model>(this: ModelClass<M>, ...args: any[]): M;
|
|
219
|
+
/** A model that will retrieve any number of records. */
|
|
220
|
+
static many<M extends Model>(this: ModelClass<M>, ...args: any[]): M;
|
|
221
|
+
/** Sort: on a retrieve it's added to the query, otherwise the loaded models are sorted. */
|
|
222
|
+
sort(...args: string[]): this;
|
|
223
|
+
/** How many records to retrieve, and where to start. */
|
|
224
|
+
limit(limit?: number | {
|
|
225
|
+
limit?: number;
|
|
226
|
+
start?: number;
|
|
227
|
+
page?: number;
|
|
228
|
+
perPage?: number;
|
|
229
|
+
}): this;
|
|
230
|
+
/** Set values on the loaded record, or stage a mass update across many. */
|
|
231
|
+
set(...args: any[]): this;
|
|
232
|
+
/**
|
|
233
|
+
* Add a record. In many mode you can add as many as you like.
|
|
234
|
+
*
|
|
235
|
+
* On a relation that hasn't been read yet, adding starts a fresh set to create rather
|
|
236
|
+
* than quietly going to the source - `await model.relation.retrieve()` first when you
|
|
237
|
+
* want the existing records loaded alongside the new ones.
|
|
238
|
+
*/
|
|
239
|
+
add(...args: any[]): this;
|
|
240
|
+
/** Add a record, flushing to the source when a bulk model fills up. */
|
|
241
|
+
queue(...args: any[]): Promise<this>;
|
|
242
|
+
/** Number of records in many mode, or fields in one mode. */
|
|
243
|
+
get size(): number;
|
|
244
|
+
/** The loaded models, in many mode. */
|
|
245
|
+
get models(): Model[];
|
|
246
|
+
/** Models in many mode, field names in one mode. */
|
|
247
|
+
[Symbol.iterator](): IterableIterator<any>;
|
|
248
|
+
/** Field names of the loaded record. */
|
|
249
|
+
keys(): string[];
|
|
250
|
+
/** Every value, keyed by field name - or an array of those in many mode. */
|
|
251
|
+
export(): any;
|
|
252
|
+
/** So `JSON.stringify(model)` does what you'd hope. */
|
|
253
|
+
toJSON(): any;
|
|
254
|
+
/** The definition of this model, for schemas and migrations. */
|
|
255
|
+
static define(...args: any[]): any;
|
|
256
|
+
/** Write this model's records to the source. */
|
|
257
|
+
create(...args: any[]): Promise<this>;
|
|
258
|
+
/** How many records match. */
|
|
259
|
+
count(...args: any[]): Promise<number>;
|
|
260
|
+
/**
|
|
261
|
+
* Read this model's records out of the source. Pass `false` to get `null` instead of
|
|
262
|
+
* an error when a one-mode retrieve finds nothing.
|
|
263
|
+
*/
|
|
264
|
+
retrieve(verify?: boolean, ...args: any[]): Promise<this | null>;
|
|
265
|
+
/** Titles for the matching records, keyed by id. */
|
|
266
|
+
titles(...args: any[]): Promise<any>;
|
|
267
|
+
/** Write changes back to the source. Resolves to how many records changed. */
|
|
268
|
+
update(...args: any[]): Promise<number>;
|
|
269
|
+
/** Remove records from the source. Resolves to how many were removed. */
|
|
270
|
+
delete(...args: any[]): Promise<number>;
|
|
271
|
+
/** The query a source would run for an action, without running it. */
|
|
272
|
+
query(action?: 'create' | 'retrieve' | 'count' | 'titles' | 'update' | 'delete', ...args: any[]): any;
|
|
273
|
+
}
|
|
274
|
+
/** Build a model the way relations does internally, bypassing the public constructor. */
|
|
275
|
+
export declare function construct<M extends Model>(cls: ModelClass<M>, internal: Internals): M;
|
|
276
|
+
export {};
|
|
277
|
+
//# sourceMappingURL=model.d.ts.map
|