@webda/models 0.0.0-stage → 4.0.0-beta.4
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 +166 -0
- package/README.md +146 -2
- package/lib/index.d.ts +11 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +11 -0
- package/lib/index.js.map +1 -0
- package/lib/mock.d.ts +72 -0
- package/lib/mock.d.ts.map +1 -0
- package/lib/mock.js +83 -0
- package/lib/mock.js.map +1 -0
- package/lib/model.model.d.ts +286 -0
- package/lib/model.model.d.ts.map +1 -0
- package/lib/model.model.js +336 -0
- package/lib/model.model.js.map +1 -0
- package/lib/relations.d.ts +705 -0
- package/lib/relations.d.ts.map +1 -0
- package/lib/relations.js +938 -0
- package/lib/relations.js.map +1 -0
- package/lib/repositories/abstract.d.ts +138 -0
- package/lib/repositories/abstract.d.ts.map +1 -0
- package/lib/repositories/abstract.js +280 -0
- package/lib/repositories/abstract.js.map +1 -0
- package/lib/repositories/conformance.d.ts +40 -0
- package/lib/repositories/conformance.d.ts.map +1 -0
- package/lib/repositories/conformance.js +38 -0
- package/lib/repositories/conformance.js.map +1 -0
- package/lib/repositories/event.d.ts +101 -0
- package/lib/repositories/event.d.ts.map +1 -0
- package/lib/repositories/event.js +228 -0
- package/lib/repositories/event.js.map +1 -0
- package/lib/repositories/hooks.d.ts +88 -0
- package/lib/repositories/hooks.d.ts.map +1 -0
- package/lib/repositories/hooks.js +105 -0
- package/lib/repositories/hooks.js.map +1 -0
- package/lib/repositories/memory.d.ts +262 -0
- package/lib/repositories/memory.d.ts.map +1 -0
- package/lib/repositories/memory.js +574 -0
- package/lib/repositories/memory.js.map +1 -0
- package/lib/repositories/repository.d.ts +238 -0
- package/lib/repositories/repository.d.ts.map +1 -0
- package/lib/repositories/repository.js +19 -0
- package/lib/repositories/repository.js.map +1 -0
- package/lib/storable.d.ts +210 -0
- package/lib/storable.d.ts.map +1 -0
- package/lib/storable.js +76 -0
- package/lib/storable.js.map +1 -0
- package/lib/types.d.ts +230 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +12 -0
- package/lib/types.js.map +1 -0
- package/package.json +60 -3
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
var _a;
|
|
2
|
+
import { deserialize, serialize, serializeRaw } from "@webda/serialize";
|
|
3
|
+
import { AbstractRepository } from "./abstract.js";
|
|
4
|
+
import { WEBDA_TEST } from "./repository.js";
|
|
5
|
+
/** Lazily-loaded WebdaQL module for query parsing */
|
|
6
|
+
let WebdaQL = null;
|
|
7
|
+
/**
|
|
8
|
+
* This is a simple in-memory repository implementation
|
|
9
|
+
* It is used for testing purposes only
|
|
10
|
+
*/
|
|
11
|
+
export class MemoryRepository extends AbstractRepository {
|
|
12
|
+
static { _a = WEBDA_TEST; }
|
|
13
|
+
/**
|
|
14
|
+
* @param model - The model class constructor
|
|
15
|
+
* @param pks - Primary key field names
|
|
16
|
+
* @param separator - Composite key separator (default: "_")
|
|
17
|
+
* @param map - Optional pre-existing Map to use as storage backend
|
|
18
|
+
*/
|
|
19
|
+
constructor(model, pks, separator, map) {
|
|
20
|
+
super(model, pks, separator);
|
|
21
|
+
/** Test utilities - clears all stored data */
|
|
22
|
+
this[_a] = {
|
|
23
|
+
clear: async () => {
|
|
24
|
+
this.storage.clear();
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
this.storage = map || new Map();
|
|
28
|
+
}
|
|
29
|
+
/** @override */
|
|
30
|
+
async get(primaryKey) {
|
|
31
|
+
const key = this.getPrimaryKey(primaryKey).toString();
|
|
32
|
+
const item = this.storage.get(key);
|
|
33
|
+
if (!item)
|
|
34
|
+
throw new Error(`Not found: ${key}`);
|
|
35
|
+
return this.deserialize(item);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Synchronous read used by conditional writes to keep check-and-set atomic
|
|
39
|
+
* @param primaryKey - key of the item
|
|
40
|
+
* @returns the deserialized item
|
|
41
|
+
*/
|
|
42
|
+
getSync(primaryKey) {
|
|
43
|
+
const key = this.getPrimaryKey(primaryKey).toString();
|
|
44
|
+
const item = this.storage.get(key);
|
|
45
|
+
if (!item)
|
|
46
|
+
throw new Error(`Not found: ${key}`);
|
|
47
|
+
return this.deserialize(item);
|
|
48
|
+
}
|
|
49
|
+
/** @override */
|
|
50
|
+
async create(data, save = true) {
|
|
51
|
+
const item = this.buildItem(data);
|
|
52
|
+
// The key is read from the built item: a primary key generated by the model
|
|
53
|
+
// (e.g. UuidModel) must be the one used for storage
|
|
54
|
+
const key = this.getPrimaryKey(item).toString();
|
|
55
|
+
if (this.storage.has(key)) {
|
|
56
|
+
throw new Error(`Already exists: ${key}`);
|
|
57
|
+
}
|
|
58
|
+
if (save !== false) {
|
|
59
|
+
this.storage.set(key, this.serialize(item));
|
|
60
|
+
}
|
|
61
|
+
return item;
|
|
62
|
+
}
|
|
63
|
+
/** @override */
|
|
64
|
+
async update(data, conditionField, condition) {
|
|
65
|
+
const item = this.getSync(this.getPrimaryKey(data));
|
|
66
|
+
this.checkCondition(item, conditionField, condition);
|
|
67
|
+
this.storage.set(this.getPrimaryKey(data).toString(), this.serialize(new this.model(data)));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Verify an optimistic locking condition on an item
|
|
71
|
+
* @param item - The item to check
|
|
72
|
+
* @param conditionField - Field to validate
|
|
73
|
+
* @param condition - Expected value
|
|
74
|
+
* @throws Error if the condition does not match
|
|
75
|
+
*/
|
|
76
|
+
checkCondition(item, conditionField, condition) {
|
|
77
|
+
if (conditionField) {
|
|
78
|
+
if (item[conditionField] !== condition) {
|
|
79
|
+
throw new Error(`Condition failed: ${conditionField} !== ${condition}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** @override */
|
|
84
|
+
async patch(primaryKey, data, conditionField, condition) {
|
|
85
|
+
// Read, check and write without yielding so the condition acts as an atomic compare-and-set
|
|
86
|
+
const item = this.getSync(primaryKey);
|
|
87
|
+
this.checkCondition(item, conditionField, condition);
|
|
88
|
+
item.load(data);
|
|
89
|
+
this.storage.set(item.getPrimaryKey().toString(), this.serialize(item));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Serialize the object to a string
|
|
93
|
+
*
|
|
94
|
+
* This method is used to allow switching between different serialization methods
|
|
95
|
+
*
|
|
96
|
+
* The serialized payload is also stamped with a top-level `__type` field
|
|
97
|
+
* carrying the concrete model identifier when available
|
|
98
|
+
* (`item.constructor.Metadata?.Identifier`). This lets `query()` and external
|
|
99
|
+
* storage backends filter results by class without re-instantiating every
|
|
100
|
+
* item — important when a single underlying storage map is shared across a
|
|
101
|
+
* model and its subclasses (the common case in production where each
|
|
102
|
+
* registered model owns its own MemoryRepository pointing at the same Map).
|
|
103
|
+
*
|
|
104
|
+
* The stamp lives on the serializer envelope (sibling of `value` /
|
|
105
|
+
* `$serializer`), not inside `value`. `deserialize()` re-surfaces it on the
|
|
106
|
+
* reconstructed instance as a non-enumerable `__type` property so WebdaQL's
|
|
107
|
+
* filter eval can read it without it ever leaking into `JSON.stringify` or
|
|
108
|
+
* `Object.keys` output — keeping API responses and re-serialize cycles
|
|
109
|
+
* byte-identical for the model's own fields.
|
|
110
|
+
*
|
|
111
|
+
* Models that don't carry Metadata (plain unit-test classes that don't go
|
|
112
|
+
* through Application.setModelMetadata) simply skip the stamp; the resulting
|
|
113
|
+
* payload is byte-identical to the previous implementation.
|
|
114
|
+
*
|
|
115
|
+
* @param item to serialize
|
|
116
|
+
* @returns serialized object
|
|
117
|
+
*/
|
|
118
|
+
serialize(item) {
|
|
119
|
+
const typeIdentifier = item?.constructor?.Metadata?.Identifier;
|
|
120
|
+
if (!typeIdentifier) {
|
|
121
|
+
return serialize(item);
|
|
122
|
+
}
|
|
123
|
+
const raw = serializeRaw(item);
|
|
124
|
+
// serializeRaw returns either { value, $serializer } for objects with
|
|
125
|
+
// metadata, or just the raw value for primitives. Models always come back
|
|
126
|
+
// in the former shape; stamp __type at the envelope level (sibling of
|
|
127
|
+
// value/$serializer) so the deserializer never copies it onto the model.
|
|
128
|
+
if (raw && typeof raw === "object" && raw.value !== undefined) {
|
|
129
|
+
if (raw.__type === undefined) {
|
|
130
|
+
raw.__type = typeIdentifier;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return JSON.stringify(raw);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Unserialize the object from a string
|
|
137
|
+
*
|
|
138
|
+
* Beyond restoring the concrete type via `@webda/serialize`'s
|
|
139
|
+
* `$serializer.type` typeKey, this also surfaces the storage envelope's
|
|
140
|
+
* `__type` stamp on the in-memory instance as a NON-ENUMERABLE property. The
|
|
141
|
+
* non-enumerable bit keeps `__type` invisible to `JSON.stringify` and
|
|
142
|
+
* `Object.keys` (so API responses and re-serialize cycles are byte-identical
|
|
143
|
+
* for the model's own fields), while still being readable via direct
|
|
144
|
+
* property access — which is exactly how WebdaQL's filter eval reads it
|
|
145
|
+
* (`ComparisonExpression.getAttributeValue` walks `obj[name]`).
|
|
146
|
+
*
|
|
147
|
+
* Backward-compat: legacy rows written before the envelope-stamping was
|
|
148
|
+
* introduced won't carry `__type`. In that case we backfill from the
|
|
149
|
+
* repository's own `model.Metadata.Identifier` so they look like records of
|
|
150
|
+
* the parent class — which is exactly what `query()`'s prepended class
|
|
151
|
+
* filter expects (parent + descendants). Plain unit-test classes without
|
|
152
|
+
* Metadata get no stamp at all; their repos opt out of class filtering on
|
|
153
|
+
* the query side too (see `query`).
|
|
154
|
+
*
|
|
155
|
+
* @param item - the serialized string
|
|
156
|
+
* @returns the deserialized model instance
|
|
157
|
+
*/
|
|
158
|
+
deserialize(item) {
|
|
159
|
+
// Re-parse the envelope to read `__type` (the serializer's deserialize
|
|
160
|
+
// path strips it because it's not in `value`). This is cheap relative to
|
|
161
|
+
// deserialize itself.
|
|
162
|
+
let typeFromEnvelope;
|
|
163
|
+
let raw;
|
|
164
|
+
try {
|
|
165
|
+
raw = JSON.parse(item);
|
|
166
|
+
if (raw && typeof raw === "object") {
|
|
167
|
+
typeFromEnvelope = raw.__type;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// Non-JSON or malformed; skip the stamp — instance is still usable.
|
|
172
|
+
}
|
|
173
|
+
const instance = (this.isPlainRow(raw) ? this.hydratePlainRow(raw) : deserialize(item));
|
|
174
|
+
const stamped = typeFromEnvelope ?? this.model?.Metadata?.Identifier;
|
|
175
|
+
if (stamped) {
|
|
176
|
+
Object.defineProperty(instance, "__type", {
|
|
177
|
+
value: stamped,
|
|
178
|
+
enumerable: false,
|
|
179
|
+
configurable: true,
|
|
180
|
+
writable: true
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
return instance;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Whether a stored row is a plain JSON object without a serializer envelope
|
|
187
|
+
*
|
|
188
|
+
* Rows written by earlier versions (e.g. a v3 FileStore folder or MemoryStore persistence file) store the
|
|
189
|
+
* object itself, its type in a top-level `__type`.
|
|
190
|
+
* @param raw - the parsed row
|
|
191
|
+
* @returns true for a plain object row
|
|
192
|
+
*/
|
|
193
|
+
isPlainRow(raw) {
|
|
194
|
+
return (raw !== null &&
|
|
195
|
+
typeof raw === "object" &&
|
|
196
|
+
!Array.isArray(raw) &&
|
|
197
|
+
raw.$serializer === undefined &&
|
|
198
|
+
typeof this.model === "function");
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Find the class to hydrate a row typed `identifier`: the repository model, one of its transitive subclasses,
|
|
202
|
+
* or the repository model for one of its ancestors
|
|
203
|
+
* @param identifier - model identifier
|
|
204
|
+
* @returns the class, `this.model` when it carries no Metadata, or undefined when unrelated
|
|
205
|
+
*/
|
|
206
|
+
findModelClass(identifier) {
|
|
207
|
+
const root = this.model;
|
|
208
|
+
if (!root?.Metadata?.Identifier) {
|
|
209
|
+
return root;
|
|
210
|
+
}
|
|
211
|
+
const seen = new Set();
|
|
212
|
+
const queue = [root];
|
|
213
|
+
while (queue.length) {
|
|
214
|
+
const clazz = queue.shift();
|
|
215
|
+
if (!clazz || seen.has(clazz))
|
|
216
|
+
continue;
|
|
217
|
+
seen.add(clazz);
|
|
218
|
+
if (clazz.Metadata?.Identifier === identifier)
|
|
219
|
+
return clazz;
|
|
220
|
+
queue.push(...(clazz.Metadata?.Subclasses ?? []));
|
|
221
|
+
}
|
|
222
|
+
// An ancestor-typed row (e.g. written before an application subclassed the model) is read as this model
|
|
223
|
+
for (let parent = Object.getPrototypeOf(root); parent && parent !== Function.prototype;) {
|
|
224
|
+
if (parent.Metadata?.Identifier === identifier)
|
|
225
|
+
return root;
|
|
226
|
+
parent = Object.getPrototypeOf(parent);
|
|
227
|
+
}
|
|
228
|
+
return undefined;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Hydrate a plain JSON row as an instance of the repository model (or of the transitive subclass named by its
|
|
232
|
+
* `__type`; an ancestor type hydrates as the repository model), the same way document stores hydrate their rows;
|
|
233
|
+
* a row typed as an unrelated model is refused
|
|
234
|
+
* @param raw - the parsed row
|
|
235
|
+
* @returns the model instance
|
|
236
|
+
*/
|
|
237
|
+
hydratePlainRow(raw) {
|
|
238
|
+
const { __type, ...data } = raw;
|
|
239
|
+
const clazz = __type === undefined ? this.model : this.findModelClass(__type);
|
|
240
|
+
if (!clazz) {
|
|
241
|
+
throw new Error(`Row of type '${__type}' does not belong to ${this.model?.Metadata?.Identifier}`);
|
|
242
|
+
}
|
|
243
|
+
const instance = new clazz(data);
|
|
244
|
+
if (typeof instance.load === "function") {
|
|
245
|
+
instance.load(data);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
Object.assign(instance, data);
|
|
249
|
+
}
|
|
250
|
+
return instance;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Collect the WebdaQL class-filter identifier list — `this.model`'s
|
|
254
|
+
* identifier and every transitive descendant carried in `Metadata.Subclasses`.
|
|
255
|
+
*
|
|
256
|
+
* Returns `undefined` when the model carries no `Metadata` (plain unit-test
|
|
257
|
+
* classes that didn't go through `Application.setModelMetadata`). In that
|
|
258
|
+
* case `query()` skips the prepend and returns everything in storage,
|
|
259
|
+
* preserving the pre-fix behavior for those bare classes.
|
|
260
|
+
*
|
|
261
|
+
* @returns the list of identifiers to match, or `undefined` when no Metadata
|
|
262
|
+
*/
|
|
263
|
+
buildClassFilterIdentifiers() {
|
|
264
|
+
const meta = this.model?.Metadata;
|
|
265
|
+
if (!meta?.Identifier)
|
|
266
|
+
return undefined;
|
|
267
|
+
const ids = [meta.Identifier];
|
|
268
|
+
const subclasses = Array.isArray(meta.Subclasses) ? meta.Subclasses : [];
|
|
269
|
+
for (const sub of subclasses) {
|
|
270
|
+
const id = sub?.Metadata?.Identifier;
|
|
271
|
+
if (typeof id === "string" && !ids.includes(id))
|
|
272
|
+
ids.push(id);
|
|
273
|
+
}
|
|
274
|
+
return ids;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Build the WebdaQL class-filter clause `__type IN ['A', 'B', ...]` covering
|
|
278
|
+
* `this.model`'s identifier and every transitive descendant.
|
|
279
|
+
*
|
|
280
|
+
* Returns `undefined` when the model carries no `Metadata`.
|
|
281
|
+
*
|
|
282
|
+
* @returns the class-filter WebdaQL clause, or `undefined` when no Metadata
|
|
283
|
+
*/
|
|
284
|
+
buildClassFilter() {
|
|
285
|
+
const ids = this.buildClassFilterIdentifiers();
|
|
286
|
+
if (!ids)
|
|
287
|
+
return undefined;
|
|
288
|
+
// Single-quote each id; escape embedded single quotes by doubling them.
|
|
289
|
+
const literals = ids.map(id => `'${id.replace(/'/g, "''")}'`).join(", ");
|
|
290
|
+
return `__type IN [${literals}]`;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Add query support
|
|
294
|
+
*
|
|
295
|
+
* Class filtering: when several model classes share the same underlying
|
|
296
|
+
* storage Map (e.g. a model and its subclasses each registering their own
|
|
297
|
+
* repository pointing at the same `Map` via `MemoryStore.getRepository`),
|
|
298
|
+
* results are restricted to instances of `this.model` and its transitive
|
|
299
|
+
* descendants. The filter is applied as a real WebdaQL clause —
|
|
300
|
+
* `__type IN ['Webda/Post', 'Webda/BlogPost', ...]` — prepended to the
|
|
301
|
+
* caller's query via `WebdaQL.PrependCondition` (string path) or merged
|
|
302
|
+
* directly into the AST (parsed-Query path used by `iterate`). Each stored
|
|
303
|
+
* item carries its `__type` as a non-enumerable property courtesy of
|
|
304
|
+
* `deserialize`, so the WebdaQL filter eval reads it directly without
|
|
305
|
+
* leaking it to JSON serialization. There is no post-filter step.
|
|
306
|
+
*
|
|
307
|
+
* Models without `Metadata` (plain unit-test classes) opt out of the
|
|
308
|
+
* prepend — `buildClassFilterIdentifiers` returns `undefined` and the query
|
|
309
|
+
* runs as given. External storage backends that adopt the same `__type`
|
|
310
|
+
* stamping convention can use `buildClassFilter` to produce the equivalent
|
|
311
|
+
* server-side WHERE clause.
|
|
312
|
+
*
|
|
313
|
+
* @param query - the query string or parsed query
|
|
314
|
+
* @param params - values for the `?` or `:name` placeholders of a query string
|
|
315
|
+
* @returns the query results with optional continuation token
|
|
316
|
+
*/
|
|
317
|
+
async query(query, params) {
|
|
318
|
+
WebdaQL ??= await import("@webda/ql");
|
|
319
|
+
if (typeof query === "string" && params !== undefined) {
|
|
320
|
+
query = WebdaQL.bind(query, params);
|
|
321
|
+
}
|
|
322
|
+
const ids = this.buildClassFilterIdentifiers();
|
|
323
|
+
let parsed;
|
|
324
|
+
if (typeof query === "string") {
|
|
325
|
+
const merged = ids ? WebdaQL.PrependCondition(query, this.buildClassFilter()) : query;
|
|
326
|
+
parsed = WebdaQL.parse(merged);
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
parsed = query;
|
|
330
|
+
if (ids) {
|
|
331
|
+
// Merge the class filter directly into the AST so callers like
|
|
332
|
+
// `iterate()` keep their per-page mutations on the parsed Query
|
|
333
|
+
// (notably `continuationToken`) — re-stringifying via toString() loses
|
|
334
|
+
// those because parse-tree-backed toString reflects the original
|
|
335
|
+
// source, not later runtime mutations.
|
|
336
|
+
const classClause = new WebdaQL.ComparisonExpression("IN", "__type", ids);
|
|
337
|
+
const current = parsed.filter;
|
|
338
|
+
if (current instanceof WebdaQL.AndExpression) {
|
|
339
|
+
// Avoid double-prepend across pages of `iterate()`.
|
|
340
|
+
const already = current.children.some((c) => c instanceof WebdaQL.ComparisonExpression && c.operator === "IN" && c.attribute?.[0] === "__type");
|
|
341
|
+
if (!already) {
|
|
342
|
+
current.children.unshift(classClause);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
parsed.filter = new WebdaQL.AndExpression([classClause, current]);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return MemoryRepository.simulateFind(parsed, this.listKeysOfModel(ids), this);
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* List the storage keys that may belong to this model
|
|
354
|
+
*
|
|
355
|
+
* A storage shared by several models holds foreign entries whose key shape can be invalid for this
|
|
356
|
+
* repository: they are skipped from the stored envelope `__type` before any parsing. Entries without a
|
|
357
|
+
* readable stamp (legacy rows, corrupted payloads) are kept so any error on them still surfaces.
|
|
358
|
+
* @param ids - class identifiers (model and subclasses), undefined to keep everything
|
|
359
|
+
* @returns the keys to evaluate
|
|
360
|
+
*/
|
|
361
|
+
listKeysOfModel(ids) {
|
|
362
|
+
const keys = [...this.storage.keys()];
|
|
363
|
+
if (!ids)
|
|
364
|
+
return keys;
|
|
365
|
+
return keys.filter(key => {
|
|
366
|
+
const raw = this.storage.get(key);
|
|
367
|
+
if (typeof raw !== "string")
|
|
368
|
+
return true;
|
|
369
|
+
try {
|
|
370
|
+
const type = JSON.parse(raw)?.__type;
|
|
371
|
+
return typeof type !== "string" || ids.includes(type);
|
|
372
|
+
}
|
|
373
|
+
catch {
|
|
374
|
+
return true;
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Allow to simulate a find on a list of uuids
|
|
380
|
+
* It is static to be reusable by other repository like FileRepository
|
|
381
|
+
* @param query - the parsed query
|
|
382
|
+
* @param uuids - the list of UIDs to search
|
|
383
|
+
* @param repository - the repository to fetch objects from
|
|
384
|
+
* @returns the query results with optional continuation token
|
|
385
|
+
*/
|
|
386
|
+
static async simulateFind(query, uuids, repository) {
|
|
387
|
+
const result = {
|
|
388
|
+
results: [],
|
|
389
|
+
continuationToken: undefined,
|
|
390
|
+
filter: true
|
|
391
|
+
};
|
|
392
|
+
let count = 0;
|
|
393
|
+
let limit = query.limit;
|
|
394
|
+
let offset = parseInt(query.continuationToken || "0");
|
|
395
|
+
const originalOffset = offset;
|
|
396
|
+
if (query.orderBy && query.orderBy.length) {
|
|
397
|
+
offset = 0;
|
|
398
|
+
// We need to retrieve everything to orderBy after
|
|
399
|
+
limit = Number.MAX_SAFE_INTEGER;
|
|
400
|
+
}
|
|
401
|
+
// Need to transfert to Array
|
|
402
|
+
for (const uuid of uuids) {
|
|
403
|
+
count++;
|
|
404
|
+
// Offset start
|
|
405
|
+
if (offset >= count) {
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
408
|
+
const obj = (await repository.get(uuid));
|
|
409
|
+
if (obj && query.filter.eval(obj)) {
|
|
410
|
+
result.results.push(obj);
|
|
411
|
+
if (result.results.length >= limit) {
|
|
412
|
+
result.continuationToken = count.toString();
|
|
413
|
+
return result;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
// Order by
|
|
418
|
+
if (query.orderBy && query.orderBy.length) {
|
|
419
|
+
// Sorting the results
|
|
420
|
+
result.results.sort((a, b) => {
|
|
421
|
+
let valA, valB;
|
|
422
|
+
for (const orderBy of query.orderBy) {
|
|
423
|
+
const invert = orderBy.direction === "ASC" ? 1 : -1;
|
|
424
|
+
valA = WebdaQL.ComparisonExpression.getAttributeValue(a, orderBy.field.split("."));
|
|
425
|
+
valB = WebdaQL.ComparisonExpression.getAttributeValue(b, orderBy.field.split("."));
|
|
426
|
+
if (valA === valB) {
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
if (typeof valA === "string") {
|
|
430
|
+
return valA.localeCompare(valB) * invert;
|
|
431
|
+
}
|
|
432
|
+
return (valA < valB ? -1 : 1) * invert;
|
|
433
|
+
}
|
|
434
|
+
return -1;
|
|
435
|
+
});
|
|
436
|
+
result.results = result.results.slice(originalOffset, query.limit + originalOffset);
|
|
437
|
+
if (result.results.length >= query.limit) {
|
|
438
|
+
result.continuationToken = (query.limit + originalOffset).toString();
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return result;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Add iterator support
|
|
445
|
+
* @param query - the query string
|
|
446
|
+
* @param params - values for the `?` or `:name` placeholders
|
|
447
|
+
*/
|
|
448
|
+
async *iterate(query, params) {
|
|
449
|
+
WebdaQL ??= await import("@webda/ql");
|
|
450
|
+
if (params !== undefined) {
|
|
451
|
+
query = WebdaQL.bind(query, params);
|
|
452
|
+
}
|
|
453
|
+
/* c8 ignore next */
|
|
454
|
+
const q = WebdaQL.parse(query); // Ensure it is valid
|
|
455
|
+
if (!q.limit) {
|
|
456
|
+
q.limit = 100; // Default pagination size
|
|
457
|
+
}
|
|
458
|
+
do {
|
|
459
|
+
const res = await this.query(q);
|
|
460
|
+
for (const i of res.results) {
|
|
461
|
+
yield i;
|
|
462
|
+
}
|
|
463
|
+
q.continuationToken = res.continuationToken;
|
|
464
|
+
} while (q.continuationToken);
|
|
465
|
+
}
|
|
466
|
+
/** @override */
|
|
467
|
+
async delete(primaryKey, _conditionField, _condition) {
|
|
468
|
+
this.storage.delete(this.getPrimaryKey(primaryKey).toString());
|
|
469
|
+
}
|
|
470
|
+
/** @override */
|
|
471
|
+
async exists(primaryKey) {
|
|
472
|
+
return this.storage.has(this.getPrimaryKey(primaryKey).toString());
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Resolve the parent object and last key of a dotted path, creating intermediate objects
|
|
476
|
+
* @param item - root object
|
|
477
|
+
* @param path - dotted path
|
|
478
|
+
* @returns the holder and the last key
|
|
479
|
+
*/
|
|
480
|
+
resolvePath(item, path) {
|
|
481
|
+
const parts = path.split(".");
|
|
482
|
+
for (const part of parts) {
|
|
483
|
+
if (part === "__proto__" || part === "constructor" || part === "prototype") {
|
|
484
|
+
throw new Error(`Invalid path segment '${part}' in '${path}'`);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
let holder = item;
|
|
488
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
489
|
+
const part = parts[i];
|
|
490
|
+
// Only ever descend into own properties, so the walk can never reach a prototype
|
|
491
|
+
if (!Object.prototype.hasOwnProperty.call(holder, part) || holder[part] === null || holder[part] === undefined) {
|
|
492
|
+
Object.defineProperty(holder, part, { value: {}, writable: true, enumerable: true, configurable: true });
|
|
493
|
+
}
|
|
494
|
+
holder = holder[part];
|
|
495
|
+
}
|
|
496
|
+
return { holder, key: parts[parts.length - 1] };
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Increment attributes atomically: the read-modify-write never yields, so concurrent calls all count
|
|
500
|
+
* @override
|
|
501
|
+
* @returns the new value of each incremented attribute, by path
|
|
502
|
+
*/
|
|
503
|
+
async incrementAttributes(primaryKey, info, _conditionField, _condition) {
|
|
504
|
+
const item = this.getSync(primaryKey);
|
|
505
|
+
const entries = Array.isArray(info)
|
|
506
|
+
? info.map(entry => typeof entry === "string"
|
|
507
|
+
? [entry, 1]
|
|
508
|
+
: [entry.property, entry.value ?? 1])
|
|
509
|
+
: Object.entries(info).map(([prop, value]) => [prop, value]);
|
|
510
|
+
const updated = {};
|
|
511
|
+
for (const [prop, inc] of entries) {
|
|
512
|
+
const { holder, key } = this.resolvePath(item, prop);
|
|
513
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype" || holder === Object.prototype) {
|
|
514
|
+
throw new Error(`Invalid path segment in '${prop}'`);
|
|
515
|
+
}
|
|
516
|
+
const current = Object.prototype.hasOwnProperty.call(holder, key) ? holder[key] : 0;
|
|
517
|
+
Object.defineProperty(holder, key, {
|
|
518
|
+
value: (current || 0) + inc,
|
|
519
|
+
writable: true,
|
|
520
|
+
enumerable: true,
|
|
521
|
+
configurable: true
|
|
522
|
+
});
|
|
523
|
+
updated[prop] = holder[key];
|
|
524
|
+
}
|
|
525
|
+
this.storage.set(this.getPrimaryKey(primaryKey).toString(), this.serialize(item));
|
|
526
|
+
return updated;
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Verify a write condition on a collection item
|
|
530
|
+
* @param item - The array to check
|
|
531
|
+
* @param index - Index of the item in the array
|
|
532
|
+
* @param itemWriteConditionField - Field name to check on the item
|
|
533
|
+
* @param itemWriteCondition - Expected value for the field
|
|
534
|
+
* @throws Error if the condition does not match
|
|
535
|
+
*/
|
|
536
|
+
checkItemWriteCondition(item, index, itemWriteConditionField, itemWriteCondition) {
|
|
537
|
+
if ((Array.isArray(item) && index < item.length && item[index][itemWriteConditionField] === itemWriteCondition) ||
|
|
538
|
+
!itemWriteCondition) {
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
throw new Error("Item write condition failed");
|
|
542
|
+
}
|
|
543
|
+
/** @override */
|
|
544
|
+
async upsertItemToCollection(primaryKey, collection, item, index, itemWriteConditionField, itemWriteCondition) {
|
|
545
|
+
const obj = (await this.get(primaryKey));
|
|
546
|
+
obj[collection] ??= [];
|
|
547
|
+
this.checkItemWriteCondition(obj[collection], index, itemWriteConditionField, itemWriteCondition);
|
|
548
|
+
const arr = obj[collection];
|
|
549
|
+
if (typeof index === "number") {
|
|
550
|
+
arr[index] = item;
|
|
551
|
+
}
|
|
552
|
+
else {
|
|
553
|
+
arr.push(item);
|
|
554
|
+
}
|
|
555
|
+
this.storage.set(this.getPrimaryKey(primaryKey).toString(), this.serialize(obj));
|
|
556
|
+
}
|
|
557
|
+
/** @override */
|
|
558
|
+
async deleteItemFromCollection(primaryKey, collection, index, itemWriteConditionField, itemWriteCondition) {
|
|
559
|
+
const obj = (await this.get(primaryKey));
|
|
560
|
+
const arr = obj[collection];
|
|
561
|
+
this.checkItemWriteCondition(obj[collection], index, itemWriteConditionField, itemWriteCondition);
|
|
562
|
+
if (Array.isArray(arr) && index >= 0 && index < arr.length) {
|
|
563
|
+
arr.splice(index, 1);
|
|
564
|
+
this.storage.set(this.getPrimaryKey(primaryKey).toString(), this.serialize(obj));
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
/** @override */
|
|
568
|
+
async removeAttribute(primaryKey, attribute, _conditionField, _condition) {
|
|
569
|
+
const obj = (await this.get(primaryKey));
|
|
570
|
+
delete obj[attribute];
|
|
571
|
+
this.storage.set(this.getPrimaryKey(primaryKey).toString(), this.serialize(obj));
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/repositories/memory.ts"],"names":[],"mappings":"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"}
|