@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 @@
1
+ {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../src/repositories/event.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,226 @@
1
+ var _a;
2
+ import { AbstractRepository } from "./abstract.js";
3
+ import { WEBDA_TEST } from "./repository.js";
4
+ /**
5
+ * Repository decorator that wraps another repository with event emission.
6
+ *
7
+ * Emits "before" events (Create, Update, Patch, Delete, PartialUpdate, Query)
8
+ * before delegating to the underlying repository, then emits "after" events
9
+ * (Created, Updated, Patched, Deleted, PartialUpdated, Queried) on success.
10
+ *
11
+ * @typeParam T - The ModelClass this repository manages
12
+ */
13
+ export class EventRepository extends AbstractRepository {
14
+ static { _a = WEBDA_TEST; }
15
+ /**
16
+ * @param model - The model class constructor
17
+ * @param pks - Array of primary key field names
18
+ * @param repository - The underlying repository to delegate storage operations to
19
+ */
20
+ constructor(model, pks, repository) {
21
+ super(model, pks, "_");
22
+ this.repository = repository;
23
+ /** Test utilities - clears events and delegates to underlying repository */
24
+ this[_a] = {
25
+ clear: async (excludeListeners) => {
26
+ if (!excludeListeners) {
27
+ this.events.clear();
28
+ }
29
+ // @ts-ignore
30
+ this.repository[WEBDA_TEST].clear();
31
+ }
32
+ };
33
+ }
34
+ /**
35
+ * Increment numeric attributes with event emission
36
+ * @override
37
+ */
38
+ async incrementAttributes(primaryKey, info, _conditionField, _condition) {
39
+ await this.emit("PartialUpdate", {
40
+ object_id: primaryKey,
41
+ partial_update: {
42
+ increments: info
43
+ }
44
+ });
45
+ await this.repository.incrementAttributes(primaryKey, info, _conditionField, _condition);
46
+ await this.emit("PartialUpdated", {
47
+ object_id: primaryKey,
48
+ partial_update: {
49
+ increments: info
50
+ }
51
+ });
52
+ }
53
+ /**
54
+ * Query with event emission
55
+ *
56
+ * Parameters are bound here, so the events carry the bound query and the underlying
57
+ * repository (often a store one) only ever receives a plain query.
58
+ * @param query - the query to execute
59
+ * @param params - values for the `?` or `:name` placeholders
60
+ * @returns the query results with optional continuation token
61
+ */
62
+ async query(query, params) {
63
+ if (params !== undefined) {
64
+ query = (await import("@webda/ql")).bind(query, params);
65
+ }
66
+ await this.emit("Query", { query });
67
+ const res = await this.repository.query(query);
68
+ await this.emit("Queried", { ...res, query });
69
+ return res;
70
+ }
71
+ /**
72
+ * Iterate through all objects
73
+ * @param query - the query filter
74
+ * @param params - values for the `?` or `:name` placeholders, bound before reaching the underlying repository
75
+ * @returns an async generator of objects
76
+ */
77
+ async *iterate(query, params) {
78
+ if (params !== undefined) {
79
+ query = (await import("@webda/ql")).bind(query, params);
80
+ }
81
+ yield* this.repository.iterate(query);
82
+ }
83
+ /**
84
+ * Delete an item from a collection
85
+ * @param uuid The UUID of the item
86
+ * @param collection The collection to delete from
87
+ * @param index The index of the item to delete
88
+ * @param itemWriteConditionField The field to use for the write condition
89
+ * @param itemWriteCondition The value to use for the write condition
90
+ */
91
+ async deleteItemFromCollection(uuid, collection, index, itemWriteConditionField, itemWriteCondition) {
92
+ await this.emit("PartialUpdate", {
93
+ object_id: uuid,
94
+ partial_update: {
95
+ delete_from_collection: {
96
+ collection,
97
+ index,
98
+ itemWriteConditionField,
99
+ itemWriteCondition
100
+ }
101
+ }
102
+ });
103
+ await this.repository.deleteItemFromCollection(uuid, collection, index, itemWriteConditionField, itemWriteCondition);
104
+ await this.emit("PartialUpdated", {
105
+ object_id: uuid,
106
+ partial_update: {
107
+ delete_from_collection: {
108
+ collection,
109
+ index,
110
+ itemWriteConditionField,
111
+ itemWriteCondition
112
+ }
113
+ }
114
+ });
115
+ }
116
+ /**
117
+ * Upsert item to collection with event emission
118
+ * @override
119
+ */
120
+ async upsertItemToCollection(uuid, collection, item, index, itemWriteConditionField, itemWriteCondition) {
121
+ await this.emit("PartialUpdate", {
122
+ object_id: uuid,
123
+ partial_update: {
124
+ upsert_in_collection: {
125
+ collection,
126
+ item,
127
+ index,
128
+ itemWriteConditionField,
129
+ itemWriteCondition
130
+ }
131
+ }
132
+ });
133
+ await this.repository.upsertItemToCollection(uuid, collection, item, index, itemWriteConditionField, itemWriteCondition);
134
+ await this.emit("PartialUpdated", {
135
+ object_id: uuid,
136
+ partial_update: {
137
+ upsert_in_collection: {
138
+ collection,
139
+ item,
140
+ index,
141
+ itemWriteConditionField,
142
+ itemWriteCondition
143
+ }
144
+ }
145
+ });
146
+ }
147
+ /**
148
+ * Remove attribute with event emission
149
+ * @override
150
+ */
151
+ async removeAttribute(uuid, attribute, conditionField, condition) {
152
+ await this.emit("PartialUpdate", {
153
+ object_id: uuid,
154
+ partial_update: {
155
+ remove_attribute: {
156
+ attribute,
157
+ conditionField,
158
+ condition
159
+ }
160
+ }
161
+ });
162
+ await this.repository.removeAttribute(uuid, attribute, conditionField, condition);
163
+ await this.emit("PartialUpdated", {
164
+ object_id: uuid,
165
+ partial_update: {
166
+ remove_attribute: {
167
+ attribute,
168
+ conditionField,
169
+ condition
170
+ }
171
+ }
172
+ });
173
+ }
174
+ /** @override */
175
+ async get(primaryKey) {
176
+ const res = await this.repository.get(primaryKey);
177
+ return res;
178
+ }
179
+ /**
180
+ * Create with event emission (emits Create before and Created after)
181
+ * @override
182
+ */
183
+ async create(data, save) {
184
+ // Build the instance once so a generated primary key is shared by the events
185
+ // and the underlying repository
186
+ const item = this.buildItem(data);
187
+ const object_id = this.getPrimaryKey(item);
188
+ await this.emit("Create", { object_id, object: item });
189
+ const res = await this.repository.create(item, save);
190
+ await this.emit("Created", { object_id, object: res });
191
+ return res;
192
+ }
193
+ /**
194
+ * Patch with event emission (emits Patch before and Patched after)
195
+ * @override
196
+ */
197
+ async patch(primaryKey, data, _conditionField, _condition) {
198
+ await this.emit("Patch", { object_id: primaryKey, object: data });
199
+ await this.repository.patch(primaryKey, data, _conditionField, _condition);
200
+ await this.emit("Patched", { object_id: primaryKey, object: data });
201
+ }
202
+ /**
203
+ * Update with event emission (emits Update before and Updated after)
204
+ * @override
205
+ */
206
+ async update(data, conditionField, condition) {
207
+ await this.emit("Update", { object_id: this.getPrimaryKey(data), object: data });
208
+ await this.repository.update(data, conditionField, condition);
209
+ await this.emit("Updated", { object_id: this.getPrimaryKey(data), object: data });
210
+ }
211
+ /**
212
+ * Delete with event emission (emits Delete before and Deleted after)
213
+ * @override
214
+ */
215
+ async delete(uuid, conditionField, condition) {
216
+ await this.emit("Delete", { object_id: uuid });
217
+ await this.repository.delete(uuid, conditionField, condition);
218
+ await this.emit("Deleted", { object_id: uuid });
219
+ }
220
+ /** @override */
221
+ async exists(uuid) {
222
+ const res = await this.repository.exists(uuid);
223
+ return res;
224
+ }
225
+ }
226
+ //# sourceMappingURL=event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.js","sourceRoot":"","sources":["../../src/repositories/event.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ import type { ModelRefWithCreate } from "../relations.js";
2
+ import { SettablePrimaryKey, type Storable, type ModelClass } from "../storable.js";
3
+ import { Helpers } from "../types.js";
4
+ import type { Repository } from "./repository.js";
5
+ import type { QueryParameters, WebdaQLString } from "@webda/ql";
6
+ /**
7
+ * Global registry mapping ModelClass constructors to their Repository instances.
8
+ *
9
+ * @internal — Populated by `Store.computeStores()`; not for app code. App code
10
+ * reaches a repository via `useRepository(Model)` or static model methods
11
+ * (`Model.create()`, `Model.query()`, `Model.ref()`).
12
+ */
13
+ export declare const Repositories: WeakMap<ModelClass<Storable<any, any>>, Repository<any>>;
14
+ /**
15
+ * Return a repository for a model
16
+ * @param arg - the model class to look up
17
+ * @returns the repository for the model
18
+ */
19
+ export declare function useRepository<T extends ModelClass>(arg: T): Repository<T>;
20
+ /**
21
+ * Register a repository
22
+ *
23
+ * @internal — Called by `Store.computeStores()`; not for app code.
24
+ * @param model - the model class to register for
25
+ * @param repository - the repository instance
26
+ */
27
+ export declare function registerRepository<T extends ModelClass>(model: T, repository: Repository<T>): void;
28
+ /**
29
+ * MixIn that adds static repository methods (create, query, iterate, ref, getRepository)
30
+ * to a base class, enabling Model classes to access their repository directly.
31
+ *
32
+ * @param Base - The base class to augment
33
+ * @returns the augmented class with repository methods
34
+ */
35
+ export declare function RepositoryStorageClassMixIn<TBase extends new (...args: any[]) => object>(Base: TBase): {
36
+ new (...args: any[]): {
37
+ /**
38
+ * Return the proxied version of this model (identity by default)
39
+ * @returns this instance
40
+ */
41
+ toProxy(): /*elided*/ any;
42
+ };
43
+ /**
44
+ * Get the repository registered for this model class.
45
+ * @returns the repository
46
+ */
47
+ getRepository<T extends ModelClass>(this: T): Repository<T>;
48
+ /**
49
+ * Create the object directly
50
+ * @param this - the model class constructor
51
+ * @param data - the initial data
52
+ * @param save - whether to persist immediately
53
+ * @returns the created model instance
54
+ */
55
+ create<T extends ModelClass>(this: T, data: Helpers<InstanceType<T>>, save?: boolean): Promise<InstanceType<T>>;
56
+ /**
57
+ * Query the object directly
58
+ *
59
+ * ```ts
60
+ * Task.query("owner = ? AND priority >= ?", [user, 2]);
61
+ * Task.query("owner = :owner", { owner: user });
62
+ * ```
63
+ * @param this - the model class constructor
64
+ * @param query - the query string, optionally with `?` or `:name` placeholders
65
+ * @param params - values for the placeholders: an array for `?`, an object for `:name`
66
+ * @returns the query results
67
+ */
68
+ query<T extends ModelClass>(this: T, query: WebdaQLString<InstanceType<T>>, params?: QueryParameters): Promise<{
69
+ results: InstanceType<T>[];
70
+ continuationToken?: string;
71
+ }>;
72
+ /**
73
+ * Iterate through all objects
74
+ * @param this - the model class constructor
75
+ * @param query - the query string, optionally with `?` or `:name` placeholders
76
+ * @param params - values for the placeholders: an array for `?`, an object for `:name`
77
+ * @returns an async generator of model instances
78
+ */
79
+ iterate<T extends ModelClass>(this: T, query: WebdaQLString<InstanceType<T>>, params?: QueryParameters): AsyncGenerator<InstanceType<T>, any, any>;
80
+ /**
81
+ * Get a reference to the model
82
+ * @param this - the model class constructor
83
+ * @param key - the primary key value
84
+ * @returns a model reference with create capability
85
+ */
86
+ ref<T extends ModelClass>(this: T, key: SettablePrimaryKey<InstanceType<T>>): ModelRefWithCreate<InstanceType<T>>;
87
+ } & TBase;
88
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/repositories/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAkB,kBAAkB,EAAqB,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACvH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAEhE;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,0DAA6C,CAAC;AAEvE;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,UAAU,EAAE,GAAG,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CASzE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAElG;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,SAAS,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK;kBAA7B,GAAG,EAAE;QA8EzE;;;WAGG;;;IA/EH;;;OAGG;kBACkB,CAAC,SAAS,UAAU,QAAQ,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;IAIlE;;;;;;OAMG;WACW,CAAC,SAAS,UAAU,QAC1B,CAAC,QACD,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SACxB,OAAO,GACZ,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAI3B;;;;;;;;;;;OAWG;UACU,CAAC,SAAS,UAAU,QACzB,CAAC,SACA,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,WAC5B,eAAe,GACvB,OAAO,CAAC;QACT,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;IAIF;;;;;;OAMG;YACmB,CAAC,SAAS,UAAU,QAClC,CAAC,SACA,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,WAC5B,eAAe,GACvB,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC;IAM5C;;;;;OAKG;QACQ,CAAC,SAAS,UAAU,QACvB,CAAC,OACF,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GACvC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;UAYzC"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Global registry mapping ModelClass constructors to their Repository instances.
3
+ *
4
+ * @internal — Populated by `Store.computeStores()`; not for app code. App code
5
+ * reaches a repository via `useRepository(Model)` or static model methods
6
+ * (`Model.create()`, `Model.query()`, `Model.ref()`).
7
+ */
8
+ export const Repositories = new WeakMap();
9
+ /**
10
+ * Return a repository for a model
11
+ * @param arg - the model class to look up
12
+ * @returns the repository for the model
13
+ */
14
+ export function useRepository(arg) {
15
+ let clazz = arg;
16
+ while (!Repositories.has(clazz)) {
17
+ clazz = Object.getPrototypeOf(clazz);
18
+ if (clazz === null || clazz === Object) {
19
+ throw new Error(`No repository found for ${arg.prototype.constructor.name}`);
20
+ }
21
+ }
22
+ return Repositories.get(clazz);
23
+ }
24
+ /**
25
+ * Register a repository
26
+ *
27
+ * @internal — Called by `Store.computeStores()`; not for app code.
28
+ * @param model - the model class to register for
29
+ * @param repository - the repository instance
30
+ */
31
+ export function registerRepository(model, repository) {
32
+ Repositories.set(model, repository);
33
+ }
34
+ /**
35
+ * MixIn that adds static repository methods (create, query, iterate, ref, getRepository)
36
+ * to a base class, enabling Model classes to access their repository directly.
37
+ *
38
+ * @param Base - The base class to augment
39
+ * @returns the augmented class with repository methods
40
+ */
41
+ export function RepositoryStorageClassMixIn(Base) {
42
+ return class extends Base {
43
+ /**
44
+ * Get the repository registered for this model class.
45
+ * @returns the repository
46
+ */
47
+ static getRepository() {
48
+ return useRepository(this);
49
+ }
50
+ /**
51
+ * Create the object directly
52
+ * @param this - the model class constructor
53
+ * @param data - the initial data
54
+ * @param save - whether to persist immediately
55
+ * @returns the created model instance
56
+ */
57
+ static create(data, save = true) {
58
+ return useRepository(this).create(data, save);
59
+ }
60
+ /**
61
+ * Query the object directly
62
+ *
63
+ * ```ts
64
+ * Task.query("owner = ? AND priority >= ?", [user, 2]);
65
+ * Task.query("owner = :owner", { owner: user });
66
+ * ```
67
+ * @param this - the model class constructor
68
+ * @param query - the query string, optionally with `?` or `:name` placeholders
69
+ * @param params - values for the placeholders: an array for `?`, an object for `:name`
70
+ * @returns the query results
71
+ */
72
+ static query(query, params) {
73
+ return useRepository(this).query(query, params);
74
+ }
75
+ /**
76
+ * Iterate through all objects
77
+ * @param this - the model class constructor
78
+ * @param query - the query string, optionally with `?` or `:name` placeholders
79
+ * @param params - values for the placeholders: an array for `?`, an object for `:name`
80
+ * @returns an async generator of model instances
81
+ */
82
+ static async *iterate(query, params) {
83
+ for await (const item of useRepository(this).iterate(query, params)) {
84
+ yield item;
85
+ }
86
+ }
87
+ /**
88
+ * Get a reference to the model
89
+ * @param this - the model class constructor
90
+ * @param key - the primary key value
91
+ * @returns a model reference with create capability
92
+ */
93
+ static ref(key) {
94
+ return useRepository(this).ref(key);
95
+ }
96
+ /**
97
+ * Return the proxied version of this model (identity by default)
98
+ * @returns this instance
99
+ */
100
+ toProxy() {
101
+ return this;
102
+ }
103
+ };
104
+ }
105
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/repositories/hooks.ts"],"names":[],"mappings":"AAMA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,EAA+B,CAAC;AAEvE;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAuB,GAAM;IACxD,IAAI,KAAK,GAAQ,GAAG,CAAC;IACrB,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,YAAY,CAAC,GAAG,CAAC,KAAK,CAAkB,CAAC;AAClD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAuB,KAAQ,EAAE,UAAyB;IAC1F,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CAA+C,IAAW;IACnG,OAAO,KAAM,SAAQ,IAAI;QACvB;;;WAGG;QACH,MAAM,CAAC,aAAa;YAClB,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAED;;;;;;WAMG;QACH,MAAM,CAAC,MAAM,CAEX,IAA8B,EAC9B,IAAI,GAAY,IAAI;YAEpB,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;QAED;;;;;;;;;;;WAWG;QACH,MAAM,CAAC,KAAK,CAEV,KAAqC,EACrC,MAAwB;YAKxB,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAClD,CAAC;QAED;;;;;;WAMG;QACH,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAEnB,KAAqC,EACrC,MAAwB;YAExB,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;gBACpE,MAAM,IAAuB,CAAC;YAChC,CAAC;QACH,CAAC;QAED;;;;;WAKG;QACH,MAAM,CAAC,GAAG,CAER,GAAwC;YAExC,OAAO,aAAa,CAAC,IAAI,CAAE,CAAC,GAAG,CAAC,GAAU,CAAC,CAAC;QAC9C,CAAC;QAED;;;WAGG;QACH,OAAO;YACL,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,208 @@
1
+ import type { ArrayElement } from "@webda/tsc-esm";
2
+ import type { QueryParameters } from "@webda/ql";
3
+ import type { PK, WEBDA_PRIMARY_KEY, ModelClass } from "../storable.js";
4
+ import type { Helpers, JSONed, PropertyPaths, NumericPropertyPaths } from "../types.js";
5
+ import { AbstractRepository } from "./abstract.js";
6
+ import { Repository, WEBDA_TEST } from "./repository.js";
7
+ /**
8
+ * Parsed query structure expected from the WebdaQL parser.
9
+ *
10
+ * Includes pagination (limit, continuationToken), ordering, and a filter
11
+ * with an `eval` function for in-memory evaluation.
12
+ */
13
+ export type Query = {
14
+ limit: number;
15
+ orderBy?: {
16
+ field: string;
17
+ direction: "ASC" | "DESC";
18
+ }[];
19
+ continuationToken?: string;
20
+ filter: {
21
+ eval: (item: any) => boolean;
22
+ };
23
+ };
24
+ /** Result of a simulated find operation, including whether filtering was applied. */
25
+ export type FindResult<T> = {
26
+ results: T[];
27
+ continuationToken?: string;
28
+ filter: boolean;
29
+ };
30
+ /**
31
+ * This is a simple in-memory repository implementation
32
+ * It is used for testing purposes only
33
+ */
34
+ export declare class MemoryRepository<T extends ModelClass, K extends Map<string, string> = Map<string, string>> extends AbstractRepository<T> {
35
+ protected storage: K;
36
+ /**
37
+ * @param model - The model class constructor
38
+ * @param pks - Primary key field names
39
+ * @param separator - Composite key separator (default: "_")
40
+ * @param map - Optional pre-existing Map to use as storage backend
41
+ */
42
+ constructor(model: T, pks: string[], separator?: string, map?: K);
43
+ /** @override */
44
+ get(primaryKey: PK<InstanceType<T>, InstanceType<T>[typeof WEBDA_PRIMARY_KEY][number]> | string): Promise<Helpers<InstanceType<T>>>;
45
+ /** @override */
46
+ create(data: Helpers<InstanceType<T>>, save?: boolean): Promise<InstanceType<T>>;
47
+ /** @override */
48
+ update<K extends PropertyPaths<InstanceType<T>>>(data: Helpers<InstanceType<T>>, conditionField?: K | null, condition?: any): Promise<void>;
49
+ /**
50
+ * Verify an optimistic locking condition on an item
51
+ * @param item - The item to check
52
+ * @param conditionField - Field to validate
53
+ * @param condition - Expected value
54
+ * @throws Error if the condition does not match
55
+ */
56
+ protected checkCondition<K extends PropertyPaths<InstanceType<T>>>(item: InstanceType<T>, conditionField?: K | null, condition?: any): void;
57
+ /** @override */
58
+ patch<K extends PropertyPaths<InstanceType<T>>>(primaryKey: PK<InstanceType<T>, InstanceType<T>[typeof WEBDA_PRIMARY_KEY][number]> | string, data: Partial<InstanceType<T>>, conditionField?: K | null, condition?: any): Promise<void>;
59
+ /**
60
+ * Serialize the object to a string
61
+ *
62
+ * This method is used to allow switching between different serialization methods
63
+ *
64
+ * The serialized payload is also stamped with a top-level `__type` field
65
+ * carrying the concrete model identifier when available
66
+ * (`item.constructor.Metadata?.Identifier`). This lets `query()` and external
67
+ * storage backends filter results by class without re-instantiating every
68
+ * item — important when a single underlying storage map is shared across a
69
+ * model and its subclasses (the common case in production where each
70
+ * registered model owns its own MemoryRepository pointing at the same Map).
71
+ *
72
+ * The stamp lives on the serializer envelope (sibling of `value` /
73
+ * `$serializer`), not inside `value`. `deserialize()` re-surfaces it on the
74
+ * reconstructed instance as a non-enumerable `__type` property so WebdaQL's
75
+ * filter eval can read it without it ever leaking into `JSON.stringify` or
76
+ * `Object.keys` output — keeping API responses and re-serialize cycles
77
+ * byte-identical for the model's own fields.
78
+ *
79
+ * Models that don't carry Metadata (plain unit-test classes that don't go
80
+ * through Application.setModelMetadata) simply skip the stamp; the resulting
81
+ * payload is byte-identical to the previous implementation.
82
+ *
83
+ * @param item to serialize
84
+ * @returns serialized object
85
+ */
86
+ serialize(item: InstanceType<T>): string;
87
+ /**
88
+ * Unserialize the object from a string
89
+ *
90
+ * Beyond restoring the concrete type via `@webda/serialize`'s
91
+ * `$serializer.type` typeKey, this also surfaces the storage envelope's
92
+ * `__type` stamp on the in-memory instance as a NON-ENUMERABLE property. The
93
+ * non-enumerable bit keeps `__type` invisible to `JSON.stringify` and
94
+ * `Object.keys` (so API responses and re-serialize cycles are byte-identical
95
+ * for the model's own fields), while still being readable via direct
96
+ * property access — which is exactly how WebdaQL's filter eval reads it
97
+ * (`ComparisonExpression.getAttributeValue` walks `obj[name]`).
98
+ *
99
+ * Backward-compat: legacy rows written before the envelope-stamping was
100
+ * introduced won't carry `__type`. In that case we backfill from the
101
+ * repository's own `model.Metadata.Identifier` so they look like records of
102
+ * the parent class — which is exactly what `query()`'s prepended class
103
+ * filter expects (parent + descendants). Plain unit-test classes without
104
+ * Metadata get no stamp at all; their repos opt out of class filtering on
105
+ * the query side too (see `query`).
106
+ *
107
+ * @param item - the serialized string
108
+ * @returns the deserialized model instance
109
+ */
110
+ deserialize(item: string): InstanceType<T>;
111
+ /**
112
+ * Collect the WebdaQL class-filter identifier list — `this.model`'s
113
+ * identifier and every transitive descendant carried in `Metadata.Subclasses`.
114
+ *
115
+ * Returns `undefined` when the model carries no `Metadata` (plain unit-test
116
+ * classes that didn't go through `Application.setModelMetadata`). In that
117
+ * case `query()` skips the prepend and returns everything in storage,
118
+ * preserving the pre-fix behavior for those bare classes.
119
+ *
120
+ * @returns the list of identifiers to match, or `undefined` when no Metadata
121
+ */
122
+ protected buildClassFilterIdentifiers(): string[] | undefined;
123
+ /**
124
+ * Build the WebdaQL class-filter clause `__type IN ['A', 'B', ...]` covering
125
+ * `this.model`'s identifier and every transitive descendant.
126
+ *
127
+ * Returns `undefined` when the model carries no `Metadata`.
128
+ *
129
+ * @returns the class-filter WebdaQL clause, or `undefined` when no Metadata
130
+ */
131
+ protected buildClassFilter(): string | undefined;
132
+ /**
133
+ * Add query support
134
+ *
135
+ * Class filtering: when several model classes share the same underlying
136
+ * storage Map (e.g. a model and its subclasses each registering their own
137
+ * repository pointing at the same `Map` via `MemoryStore.getRepository`),
138
+ * results are restricted to instances of `this.model` and its transitive
139
+ * descendants. The filter is applied as a real WebdaQL clause —
140
+ * `__type IN ['Webda/Post', 'Webda/BlogPost', ...]` — prepended to the
141
+ * caller's query via `WebdaQL.PrependCondition` (string path) or merged
142
+ * directly into the AST (parsed-Query path used by `iterate`). Each stored
143
+ * item carries its `__type` as a non-enumerable property courtesy of
144
+ * `deserialize`, so the WebdaQL filter eval reads it directly without
145
+ * leaking it to JSON serialization. There is no post-filter step.
146
+ *
147
+ * Models without `Metadata` (plain unit-test classes) opt out of the
148
+ * prepend — `buildClassFilterIdentifiers` returns `undefined` and the query
149
+ * runs as given. External storage backends that adopt the same `__type`
150
+ * stamping convention can use `buildClassFilter` to produce the equivalent
151
+ * server-side WHERE clause.
152
+ *
153
+ * @param query - the query string or parsed query
154
+ * @param params - values for the `?` or `:name` placeholders of a query string
155
+ * @returns the query results with optional continuation token
156
+ */
157
+ query(query: string | Query, params?: QueryParameters): Promise<{
158
+ results: InstanceType<T>[];
159
+ continuationToken?: string;
160
+ }>;
161
+ /**
162
+ * Allow to simulate a find on a list of uuids
163
+ * It is static to be reusable by other repository like FileRepository
164
+ * @param query - the parsed query
165
+ * @param uuids - the list of UIDs to search
166
+ * @param repository - the repository to fetch objects from
167
+ * @returns the query results with optional continuation token
168
+ */
169
+ static simulateFind<T extends ModelClass>(query: Query, uuids: any[], repository: Repository<T>): Promise<{
170
+ results: InstanceType<T>[];
171
+ continuationToken?: string;
172
+ }>;
173
+ /**
174
+ * Add iterator support
175
+ * @param query - the query string
176
+ * @param params - values for the `?` or `:name` placeholders
177
+ */
178
+ iterate(query: string, params?: QueryParameters): AsyncGenerator<InstanceType<T>, any, any>;
179
+ /** @override */
180
+ delete<K extends PropertyPaths<InstanceType<T>>>(primaryKey: PK<InstanceType<T>, InstanceType<T>[typeof WEBDA_PRIMARY_KEY][number]>, _conditionField?: K | null, _condition?: any): Promise<void>;
181
+ /** @override */
182
+ exists(primaryKey: PK<InstanceType<T>, InstanceType<T>[typeof WEBDA_PRIMARY_KEY][number]> | string): Promise<boolean>;
183
+ /** @override */
184
+ incrementAttributes<K extends PropertyPaths<InstanceType<T>>, L extends NumericPropertyPaths<InstanceType<T>>>(primaryKey: PK<InstanceType<T>, InstanceType<T>[typeof WEBDA_PRIMARY_KEY][number]> | string, info: (L | {
185
+ property: L;
186
+ value?: number;
187
+ })[] | Record<L, number>, _conditionField?: K | null, _condition?: any): Promise<void>;
188
+ /**
189
+ * Verify a write condition on a collection item
190
+ * @param item - The array to check
191
+ * @param index - Index of the item in the array
192
+ * @param itemWriteConditionField - Field name to check on the item
193
+ * @param itemWriteCondition - Expected value for the field
194
+ * @throws Error if the condition does not match
195
+ */
196
+ protected checkItemWriteCondition(item: any[], index: number, itemWriteConditionField: string, itemWriteCondition: any): void;
197
+ /** @override */
198
+ upsertItemToCollection<K extends Extract<PropertyPaths<InstanceType<T>, any[]>, keyof InstanceType<T>>, L extends keyof ArrayElement<InstanceType<T>[K]>>(primaryKey: PK<InstanceType<T>, InstanceType<T>[typeof WEBDA_PRIMARY_KEY][number]>, collection: K, item: ArrayElement<InstanceType<T>[K]> | JSONed<ArrayElement<InstanceType<T>[K]>>, index?: number, itemWriteConditionField?: any, itemWriteCondition?: any): Promise<void>;
199
+ /** @override */
200
+ deleteItemFromCollection<K extends Extract<PropertyPaths<InstanceType<T>, any[]>, keyof InstanceType<T>>, L extends keyof ArrayElement<InstanceType<T>[K]>>(primaryKey: PK<InstanceType<T>, InstanceType<T>[typeof WEBDA_PRIMARY_KEY][number]>, collection: K, index: number, itemWriteConditionField?: any, itemWriteCondition?: any): Promise<void>;
201
+ /** @override */
202
+ removeAttribute<L extends PropertyPaths<InstanceType<T>>, K extends PropertyPaths<InstanceType<T>>>(primaryKey: PK<InstanceType<T>, InstanceType<T>[typeof WEBDA_PRIMARY_KEY][number]>, attribute: K, _conditionField?: L | null, _condition?: any): Promise<void>;
203
+ /** Test utilities - clears all stored data */
204
+ [WEBDA_TEST]: {
205
+ clear: () => Promise<void>;
206
+ };
207
+ }
208
+ //# sourceMappingURL=memory.d.ts.map