@webda/models 0.0.0-stage → 4.0.0-beta.3

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 (51) hide show
  1. package/LICENSE +166 -0
  2. package/README.md +146 -2
  3. package/lib/index.d.ts +11 -0
  4. package/lib/index.d.ts.map +1 -0
  5. package/lib/index.js +11 -0
  6. package/lib/index.js.map +1 -0
  7. package/lib/mock.d.ts +72 -0
  8. package/lib/mock.d.ts.map +1 -0
  9. package/lib/mock.js +83 -0
  10. package/lib/mock.js.map +1 -0
  11. package/lib/model.model.d.ts +247 -0
  12. package/lib/model.model.d.ts.map +1 -0
  13. package/lib/model.model.js +277 -0
  14. package/lib/model.model.js.map +1 -0
  15. package/lib/relations.d.ts +705 -0
  16. package/lib/relations.d.ts.map +1 -0
  17. package/lib/relations.js +938 -0
  18. package/lib/relations.js.map +1 -0
  19. package/lib/repositories/abstract.d.ts +124 -0
  20. package/lib/repositories/abstract.d.ts.map +1 -0
  21. package/lib/repositories/abstract.js +249 -0
  22. package/lib/repositories/abstract.js.map +1 -0
  23. package/lib/repositories/conformance.d.ts +40 -0
  24. package/lib/repositories/conformance.d.ts.map +1 -0
  25. package/lib/repositories/conformance.js +38 -0
  26. package/lib/repositories/conformance.js.map +1 -0
  27. package/lib/repositories/event.d.ts +100 -0
  28. package/lib/repositories/event.d.ts.map +1 -0
  29. package/lib/repositories/event.js +226 -0
  30. package/lib/repositories/event.js.map +1 -0
  31. package/lib/repositories/hooks.d.ts +88 -0
  32. package/lib/repositories/hooks.d.ts.map +1 -0
  33. package/lib/repositories/hooks.js +105 -0
  34. package/lib/repositories/hooks.js.map +1 -0
  35. package/lib/repositories/memory.d.ts +208 -0
  36. package/lib/repositories/memory.d.ts.map +1 -0
  37. package/lib/repositories/memory.js +446 -0
  38. package/lib/repositories/memory.js.map +1 -0
  39. package/lib/repositories/repository.d.ts +238 -0
  40. package/lib/repositories/repository.d.ts.map +1 -0
  41. package/lib/repositories/repository.js +19 -0
  42. package/lib/repositories/repository.js.map +1 -0
  43. package/lib/storable.d.ts +200 -0
  44. package/lib/storable.d.ts.map +1 -0
  45. package/lib/storable.js +66 -0
  46. package/lib/storable.js.map +1 -0
  47. package/lib/types.d.ts +230 -0
  48. package/lib/types.d.ts.map +1 -0
  49. package/lib/types.js +12 -0
  50. package/lib/types.js.map +1 -0
  51. package/package.json +60 -3
@@ -0,0 +1,247 @@
1
+ import { WEBDA_EVENTS, WEBDA_PRIMARY_KEY, type PK, type PrimaryKeyType, type Storable, WEBDA_PRIMARY_KEY_SEPARATOR, WEBDA_STORAGE, ModelClass } from "./storable.js";
2
+ import { WEBDA_DIRTY } from "@webda/utils";
3
+ import type { SelfJSONed } from "./types.js";
4
+ import type { ModelRef } from "./relations.js";
5
+ import type { Repository } from "./repositories/repository.js";
6
+ import { LoadParameters } from "./types.js";
7
+ /**
8
+ * Make all properties optional except those in K.
9
+ */
10
+ export type PartialExcept<T, K extends keyof T> = Partial<T> & Pick<T, K>;
11
+ /**
12
+ * Make only the properties in K optional, keeping the rest required.
13
+ */
14
+ export type ExceptPartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
15
+ /**
16
+ * Allow simulated delete
17
+ */
18
+ export declare const WEBDA_DELETED = "__deleted";
19
+ /**
20
+ * Event sent by models
21
+ *
22
+ * Events are sent by the model to notify of changes
23
+ * after the changes are done
24
+ *
25
+ * If you need to prevent the change, you should extend the object
26
+ */
27
+ export type ModelEvents<T = any> = {
28
+ Create: {
29
+ object_id: string;
30
+ object: T;
31
+ };
32
+ PartialUpdate: any;
33
+ Delete: {
34
+ object_id: string;
35
+ };
36
+ Update: {
37
+ object_id: string;
38
+ object: T;
39
+ previous: T;
40
+ };
41
+ Patch: {
42
+ object_id: string;
43
+ object: T;
44
+ previous: T;
45
+ };
46
+ Query: {
47
+ query: string;
48
+ };
49
+ Created: {
50
+ object_id: string;
51
+ object: T;
52
+ };
53
+ PartialUpdated: any;
54
+ Deleted: {
55
+ object_id: string;
56
+ };
57
+ Patched: {
58
+ object_id: string;
59
+ object: T;
60
+ previous: T;
61
+ };
62
+ Updated: {
63
+ object_id: string;
64
+ object: T;
65
+ previous: T;
66
+ };
67
+ Queried: {
68
+ query: string;
69
+ results: T[];
70
+ continuationToken?: string;
71
+ };
72
+ };
73
+ declare const Model_base: {
74
+ new (...args: any[]): {
75
+ toProxy(): /*elided*/ any;
76
+ };
77
+ getRepository<T extends ModelClass>(this: T): Repository<T>;
78
+ create<T extends ModelClass>(this: T, data: InstanceType<T> extends infer T_1 ? { [K in keyof T_1 as K extends symbol ? never : InstanceType<T>[K] extends (...args: any[]) => any ? never : K]: T_1[K]; } : never, save?: boolean): Promise<InstanceType<T>>;
79
+ query<T extends ModelClass>(this: T, query: import("@webda/ql").WebdaQLString<InstanceType<T>>, params?: import("@webda/ql").QueryParameters): Promise<{
80
+ results: InstanceType<T>[];
81
+ continuationToken?: string;
82
+ }>;
83
+ iterate<T extends ModelClass>(this: T, query: import("@webda/ql").WebdaQLString<InstanceType<T>>, params?: import("@webda/ql").QueryParameters): AsyncGenerator<InstanceType<T>, any, any>;
84
+ ref<T extends ModelClass>(this: T, key: import("./storable.js").SettablePrimaryKey<InstanceType<T>>): import("./relations.js").ModelRefWithCreate<InstanceType<T>>;
85
+ } & ObjectConstructor;
86
+ /**
87
+ * Model object definition
88
+ *
89
+ * This is the core of many application
90
+ */
91
+ export declare abstract class Model extends Model_base implements Storable {
92
+ /**
93
+ * Model events
94
+ */
95
+ [WEBDA_EVENTS]?: ModelEvents<this>;
96
+ /**
97
+ * Internal backing store for morpher-generated accessor properties.
98
+ * Populated automatically when getter/setter pairs are generated at build time.
99
+ */
100
+ protected [WEBDA_STORAGE]: Record<string, any>;
101
+ /**
102
+ * Properties that are dirty and need to be saved
103
+ * @private
104
+ */
105
+ [WEBDA_DIRTY]?: Set<string>;
106
+ /** Non-abstract class need to define their PrimaryKey */
107
+ abstract [WEBDA_PRIMARY_KEY]: readonly (keyof this)[];
108
+ /**
109
+ * K is inferred as the literal tuple type of `this.keyFields`,
110
+ * so K[number] is the exact union of keys you wrote.
111
+ * @returns the primary key value
112
+ */
113
+ getPrimaryKey<K extends readonly (keyof this)[]>(this: this & {
114
+ [WEBDA_PRIMARY_KEY]: K;
115
+ [WEBDA_PRIMARY_KEY_SEPARATOR]?: string;
116
+ }): PrimaryKeyType<this>;
117
+ /**
118
+ * Return the string representation of the primary key
119
+ * @returns the string UID
120
+ */
121
+ getUUID(): string;
122
+ /**
123
+ * Get a reference to this model instance in its repository
124
+ * @returns a model reference
125
+ */
126
+ ref(): ModelRef<this>;
127
+ /**
128
+ * Set the primary key of the model
129
+ * @param this - the model instance
130
+ * @param value - the primary key value to set
131
+ * @returns the model instance
132
+ */
133
+ setPrimaryKey<K extends readonly (keyof this)[]>(this: this & {
134
+ [WEBDA_PRIMARY_KEY]: K;
135
+ }, value: PK<this, K[number]>): this;
136
+ /**
137
+ * Get the repository associated with this model class
138
+ * @returns the repository
139
+ */
140
+ getRepository(): Repository<ModelClass<this>>;
141
+ /**
142
+ * Register Model custom serializer
143
+ * @param this - the model class constructor
144
+ * @param overwrite - whether to overwrite an existing serializer
145
+ * @param identifier - fully-qualified model identifier (e.g. `WebdaSample/User`)
146
+ * used to namespace the serializer key when multiple classes share the same
147
+ * JS constructor name. Defaults to the constructor's own name.
148
+ *
149
+ * TODO Might want to move to deserialize static function
150
+ */
151
+ static registerSerializer<T extends ModelClass>(this: T & {
152
+ fromJSON?: (data: any) => InstanceType<T>;
153
+ getStaticProperties?: () => any;
154
+ }, overwrite?: boolean, identifier?: string): void;
155
+ /**
156
+ * Serialize the model to JSON.
157
+ *
158
+ * Uses `for...in` to include both own enumerable properties (regular class fields)
159
+ * and inherited enumerable prototype getters generated by the morpher for coercible
160
+ * fields (e.g. Date). Symbol-keyed internals and methods are excluded automatically.
161
+ * @returns the model instance
162
+ */
163
+ toJSON(): this;
164
+ /**
165
+ * Reload the model from the repository, updating all properties in-place
166
+ * @returns the refreshed model instance
167
+ */
168
+ refresh(): Promise<this>;
169
+ /**
170
+ * Save the model to the repository
171
+ * @returns the saved model instance
172
+ */
173
+ save(): Promise<this>;
174
+ /**
175
+ * Helper to emit events from the class
176
+ * @param event - the event name to emit
177
+ * @param payload - the event data
178
+ */
179
+ protected emit<T extends keyof this[typeof WEBDA_EVENTS]>(event: T, payload: this[typeof WEBDA_EVENTS][T]): Promise<void>;
180
+ /**
181
+ * Custom deserializers for the model
182
+ * @returns a map of field deserializers, or undefined
183
+ */
184
+ static getDeserializers<T extends ModelClass>(this: T): Partial<Record<keyof InstanceType<T>, (value: any) => any>> | undefined;
185
+ /** Built-in deserializer helpers for common types */
186
+ static DefaultDeserializer: {
187
+ Date: (value: string | number | Date | undefined) => Date;
188
+ };
189
+ /**
190
+ * Deserialize the model
191
+ * @param this - the model class constructor
192
+ * @param data - the raw data to deserialize
193
+ * @param instance - optional existing instance to populate
194
+ * @returns the deserialized model instance
195
+ */
196
+ static deserialize<T extends ModelClass, K extends object = InstanceType<T>>(this: T, data: any, instance?: K): K;
197
+ /**
198
+ * Allow to load from Storage, Dto and helper formats
199
+ * @param params - the data to load
200
+ * @returns the model instance
201
+ */
202
+ load(params: LoadParameters<this>): this;
203
+ /**
204
+ * Check whether this model instance has been soft-deleted
205
+ * @returns true if soft-deleted
206
+ */
207
+ isDeleted(): any;
208
+ /**
209
+ * Delete a model
210
+ * @returns a promise resolving when deleted (void)
211
+ */
212
+ delete(): Promise<void>;
213
+ /**
214
+ * Patch the object
215
+ * @param data - the partial data to patch with
216
+ * @returns the patched model instance
217
+ */
218
+ patch(data: Partial<SelfJSONed<this>>): Promise<this>;
219
+ }
220
+ /**
221
+ * Simple model with a UUID
222
+ */
223
+ export declare class UuidModel extends Model {
224
+ /**
225
+ * Definition of the primary key
226
+ */
227
+ [WEBDA_PRIMARY_KEY]: readonly ["uuid"];
228
+ /**
229
+ * UUID of the model
230
+ * @format uuid
231
+ */
232
+ uuid: string;
233
+ /**
234
+ * Constructor
235
+ * @param data - optional initial data
236
+ */
237
+ constructor(data?: Partial<UuidModel>);
238
+ /**
239
+ * Generate a new UUID for this model.
240
+ * Override to provide custom ID generation logic.
241
+ * @param data - Optional partial data used during construction
242
+ * @returns the generated UUID string
243
+ */
244
+ generateUUID(data?: any): string;
245
+ }
246
+ export {};
247
+ //# sourceMappingURL=model.model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.model.d.ts","sourceRoot":"","sources":["../src/model.model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,277 @@
1
+ var _a, _b;
2
+ import { WEBDA_EVENTS, WEBDA_PRIMARY_KEY, WEBDA_PRIMARY_KEY_SEPARATOR, WEBDA_STORAGE } from "./storable.js";
3
+ import { WEBDA_DIRTY } from "@webda/utils";
4
+ import { randomUUID } from "crypto";
5
+ import { ObjectSerializer, registerSerializer } from "@webda/serialize";
6
+ import { RepositoryStorageClassMixIn } from "./repositories/hooks.js";
7
+ /**
8
+ * Allow simulated delete
9
+ */
10
+ export const WEBDA_DELETED = "__deleted";
11
+ /**
12
+ * Model object definition
13
+ *
14
+ * This is the core of many application
15
+ */
16
+ export class Model extends RepositoryStorageClassMixIn(Object) {
17
+ constructor() {
18
+ super(...arguments);
19
+ /**
20
+ * Internal backing store for morpher-generated accessor properties.
21
+ * Populated automatically when getter/setter pairs are generated at build time.
22
+ */
23
+ this[_a] = {};
24
+ }
25
+ static { _a = WEBDA_STORAGE; }
26
+ /**
27
+ * K is inferred as the literal tuple type of `this.keyFields`,
28
+ * so K[number] is the exact union of keys you wrote.
29
+ * @returns the primary key value
30
+ */
31
+ getPrimaryKey() {
32
+ const result = {};
33
+ if (this[WEBDA_PRIMARY_KEY].length === 1) {
34
+ return this[this[WEBDA_PRIMARY_KEY][0]];
35
+ }
36
+ for (const k of this[WEBDA_PRIMARY_KEY]) {
37
+ result[k] = this[k];
38
+ }
39
+ result.toString = () => {
40
+ return this[WEBDA_PRIMARY_KEY].map(k => `${this[k]}`).join(this[WEBDA_PRIMARY_KEY_SEPARATOR] || "_");
41
+ };
42
+ return result;
43
+ }
44
+ /**
45
+ * Return the string representation of the primary key
46
+ * @returns the string UID
47
+ */
48
+ getUUID() {
49
+ return this.getRepository().getUID(this);
50
+ }
51
+ /**
52
+ * Get a reference to this model instance in its repository
53
+ * @returns a model reference
54
+ */
55
+ ref() {
56
+ return this.getRepository().ref(this.getPrimaryKey());
57
+ }
58
+ /**
59
+ * Set the primary key of the model
60
+ * @param this - the model instance
61
+ * @param value - the primary key value to set
62
+ * @returns the model instance
63
+ */
64
+ setPrimaryKey(value) {
65
+ if (this[WEBDA_PRIMARY_KEY].length === 1) {
66
+ this[this[WEBDA_PRIMARY_KEY][0]] = value;
67
+ }
68
+ else {
69
+ for (const k of this[WEBDA_PRIMARY_KEY]) {
70
+ this[k] = value[k];
71
+ }
72
+ }
73
+ return this;
74
+ }
75
+ /**
76
+ * Get the repository associated with this model class
77
+ * @returns the repository
78
+ */
79
+ getRepository() {
80
+ return this.constructor.getRepository();
81
+ }
82
+ /**
83
+ * Register Model custom serializer
84
+ * @param this - the model class constructor
85
+ * @param overwrite - whether to overwrite an existing serializer
86
+ * @param identifier - fully-qualified model identifier (e.g. `WebdaSample/User`)
87
+ * used to namespace the serializer key when multiple classes share the same
88
+ * JS constructor name. Defaults to the constructor's own name.
89
+ *
90
+ * TODO Might want to move to deserialize static function
91
+ */
92
+ static registerSerializer(overwrite = true, identifier) {
93
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
94
+ const clazz = this;
95
+ if (!clazz.getStaticProperties) {
96
+ clazz.getStaticProperties = () => ({});
97
+ }
98
+ // Use the fully-qualified model identifier (e.g. "WebdaSample/User") when
99
+ // available so two classes that share a JS constructor name — like an app
100
+ // override shadowing a framework-provided model — don't collide on the
101
+ // same serializer key.
102
+ const typeKey = identifier
103
+ ? `@webda/models/${identifier}`
104
+ : `@webda/models/${this.prototype.constructor.name}`;
105
+ // The base ObjectSerializer.deserializer is responsible for invoking the
106
+ // model's compile-time-emitted `__hydrateBehaviors(rawData)` method (when
107
+ // present), so a model loaded from a store ends up with the same wired
108
+ // Behavior instances as one populated via `model.load(...)`.
109
+ registerSerializer(typeKey, new ObjectSerializer(clazz, clazz.getStaticProperties()), overwrite);
110
+ }
111
+ /**
112
+ * Serialize the model to JSON.
113
+ *
114
+ * Uses `for...in` to include both own enumerable properties (regular class fields)
115
+ * and inherited enumerable prototype getters generated by the morpher for coercible
116
+ * fields (e.g. Date). Symbol-keyed internals and methods are excluded automatically.
117
+ * @returns the model instance
118
+ */
119
+ toJSON() {
120
+ return this;
121
+ }
122
+ /**
123
+ * Reload the model from the repository, updating all properties in-place
124
+ * @returns the refreshed model instance
125
+ */
126
+ async refresh() {
127
+ const repo = this.getRepository();
128
+ const data = await repo.get(this.getPrimaryKey());
129
+ Object.assign(this, data);
130
+ return this;
131
+ }
132
+ /**
133
+ * Save the model to the repository
134
+ * @returns the saved model instance
135
+ */
136
+ async save() {
137
+ const repo = this.getRepository();
138
+ const concreteThis = this;
139
+ if (!concreteThis["dirty"]?.valueOf()) {
140
+ await repo.upsert(concreteThis);
141
+ }
142
+ else {
143
+ const patch = concreteThis["dirty"].getPatch();
144
+ await repo.patch(this.getPrimaryKey(), patch);
145
+ concreteThis["dirty"].clear();
146
+ }
147
+ return this;
148
+ }
149
+ /**
150
+ * Helper to emit events from the class
151
+ * @param event - the event name to emit
152
+ * @param payload - the event data
153
+ */
154
+ async emit(event, payload) {
155
+ await this.getRepository().emit(event, payload);
156
+ }
157
+ /**
158
+ * Custom deserializers for the model
159
+ * @returns a map of field deserializers, or undefined
160
+ */
161
+ static getDeserializers() {
162
+ return undefined;
163
+ }
164
+ /** Built-in deserializer helpers for common types */
165
+ static { this.DefaultDeserializer = {
166
+ Date: (value) => (value ? new Date(value) : new Date())
167
+ }; }
168
+ /**
169
+ * Deserialize the model
170
+ * @param this - the model class constructor
171
+ * @param data - the raw data to deserialize
172
+ * @param instance - optional existing instance to populate
173
+ * @returns the deserialized model instance
174
+ */
175
+ static deserialize(data, instance) {
176
+ if (!instance) {
177
+ instance = new this(data);
178
+ return instance;
179
+ }
180
+ // Deserialize with custom deserializers if any
181
+ const deserializers = this.getDeserializers ? this.getDeserializers() : undefined;
182
+ let info = deserializers ? {} : data;
183
+ if (deserializers) {
184
+ for (const key in data) {
185
+ if (deserializers[key]) {
186
+ info[key] = deserializers[key](data[key]);
187
+ }
188
+ else {
189
+ info[key] = data[key];
190
+ }
191
+ }
192
+ }
193
+ else {
194
+ info = data;
195
+ }
196
+ Object.assign(instance, info);
197
+ // Hydrate Behavior-typed attributes by delegating to the per-model
198
+ // `__hydrateBehaviors(rawData)` method generated by `@webda/content-mapper`
199
+ // transformer for any model that declares Behavior-typed properties.
200
+ // Models without such properties simply lack the method, so the optional
201
+ // chain makes this a no-op for them. The same call sits inside the base
202
+ // ObjectSerializer.deserializer so both load paths share the contract.
203
+ instance.__hydrateBehaviors?.(data);
204
+ return instance;
205
+ }
206
+ /**
207
+ * Allow to load from Storage, Dto and helper formats
208
+ * @param params - the data to load
209
+ * @returns the model instance
210
+ */
211
+ load(params) {
212
+ // @ts-ignore
213
+ this.constructor.deserialize(params, this);
214
+ return this;
215
+ }
216
+ /**
217
+ * Check whether this model instance has been soft-deleted
218
+ * @returns true if soft-deleted
219
+ */
220
+ isDeleted() {
221
+ return this[WEBDA_DELETED];
222
+ }
223
+ /**
224
+ * Delete a model
225
+ * @returns a promise resolving when deleted (void)
226
+ */
227
+ async delete() {
228
+ // Mark the model as deleted
229
+ // return this.ref().setAttribute(WEBDA_DELETED, Date.now());
230
+ // or delete for real
231
+ return this.ref().delete();
232
+ }
233
+ /**
234
+ * Patch the object
235
+ * @param data - the partial data to patch with
236
+ * @returns the patched model instance
237
+ */
238
+ async patch(data) {
239
+ this.load(data);
240
+ const repo = this.getRepository();
241
+ await repo.patch(this.getPrimaryKey(), Object.keys(data).reduce((acc, key) => {
242
+ acc[key] = this[key];
243
+ return acc;
244
+ }, {}));
245
+ return this;
246
+ }
247
+ }
248
+ /**
249
+ * Simple model with a UUID
250
+ */
251
+ export class UuidModel extends Model {
252
+ static { _b = WEBDA_PRIMARY_KEY; }
253
+ /**
254
+ * Constructor
255
+ * @param data - optional initial data
256
+ */
257
+ constructor(data) {
258
+ super();
259
+ /**
260
+ * Definition of the primary key
261
+ */
262
+ this[_b] = ["uuid"];
263
+ this.uuid = data?.uuid || this.generateUUID(data);
264
+ }
265
+ /**
266
+ * Generate a new UUID for this model.
267
+ * Override to provide custom ID generation logic.
268
+ * @param data - Optional partial data used during construction
269
+ * @returns the generated UUID string
270
+ */
271
+ generateUUID(data) {
272
+ return randomUUID();
273
+ }
274
+ }
275
+ // Register serializer for UuidModel
276
+ UuidModel.registerSerializer();
277
+ //# sourceMappingURL=model.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.model.js","sourceRoot":"","sources":["../src/model.model.ts"],"names":[],"mappings":"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"}