@acodeninja/persist 2.3.1 → 2.4.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/package.json +1 -1
- package/src/Persist.js +1 -1
- package/src/engine/Engine.js +156 -5
- package/src/engine/FileEngine.js +21 -4
- package/src/engine/HTTPEngine.js +41 -17
- package/src/engine/S3Engine.js +34 -12
- package/src/type/Model.js +1 -1
- package/src/type/resolved/SlugType.js +2 -0
package/package.json
CHANGED
package/src/Persist.js
CHANGED
package/src/engine/Engine.js
CHANGED
@@ -24,6 +24,18 @@ class Engine {
|
|
24
24
|
return Promise.reject(new NotImplementedError(`${this.name} must implement .getById()`));
|
25
25
|
}
|
26
26
|
|
27
|
+
/**
|
28
|
+
* Deletes a model by its ID. This method must be implemented by subclasses.
|
29
|
+
*
|
30
|
+
* @param {string} _id - The ID of the model to retrieve.
|
31
|
+
* @throws {NotImplementedError} Throws if the method is not implemented.
|
32
|
+
* @returns {Promise<void>} - Returns a promise resolving when the model has been deleted.
|
33
|
+
* @abstract
|
34
|
+
*/
|
35
|
+
static deleteById(_id) {
|
36
|
+
return Promise.reject(new NotImplementedError(`${this.name} must implement .deleteById()`));
|
37
|
+
}
|
38
|
+
|
27
39
|
/**
|
28
40
|
* Saves a model to the data store. This method must be implemented by subclasses.
|
29
41
|
*
|
@@ -181,7 +193,10 @@ class Engine {
|
|
181
193
|
await this.putModel(m);
|
182
194
|
|
183
195
|
uploadedModels.push(m.id);
|
184
|
-
indexUpdates[m.constructor.name] =
|
196
|
+
indexUpdates[m.constructor.name] = {
|
197
|
+
...indexUpdates[m.constructor.name] || {},
|
198
|
+
[m.id]: m,
|
199
|
+
};
|
185
200
|
|
186
201
|
if (m.constructor.searchProperties().length > 0) {
|
187
202
|
const rawSearchIndex = {
|
@@ -243,6 +258,127 @@ class Engine {
|
|
243
258
|
}
|
244
259
|
}
|
245
260
|
|
261
|
+
/**
|
262
|
+
* Deletes a model
|
263
|
+
*
|
264
|
+
* @param {Model} model
|
265
|
+
* @return {Promise<void>}
|
266
|
+
* @throws {NotFoundEngineError} Throws if the model is not found.
|
267
|
+
*/
|
268
|
+
static async delete(model) {
|
269
|
+
this.checkConfiguration();
|
270
|
+
|
271
|
+
const modelUpdates = [];
|
272
|
+
const processedModels = [];
|
273
|
+
const indexUpdates = {};
|
274
|
+
const additionalDeletions = [];
|
275
|
+
const deletedModels = [];
|
276
|
+
|
277
|
+
/**
|
278
|
+
* Delete the given model, updating search indexes as required.
|
279
|
+
* @param {Model} m - The model to be deleted.
|
280
|
+
* @return {Promise<void>}
|
281
|
+
*/
|
282
|
+
const deleteModel = async (m) => {
|
283
|
+
if (deletedModels.includes(m.id)) return;
|
284
|
+
if (m.constructor.searchProperties().length > 0) {
|
285
|
+
const rawSearchIndex = await this.getSearchIndexRaw(m.constructor);
|
286
|
+
|
287
|
+
delete rawSearchIndex[m.id];
|
288
|
+
|
289
|
+
await this.putSearchIndexRaw(m.constructor, rawSearchIndex);
|
290
|
+
|
291
|
+
const compiledIndex = lunr(function () {
|
292
|
+
this.ref('id');
|
293
|
+
|
294
|
+
for (const field of m.constructor.searchProperties()) {
|
295
|
+
this.field(field);
|
296
|
+
}
|
297
|
+
|
298
|
+
Object.values(rawSearchIndex).forEach(function (doc) {
|
299
|
+
this.add(doc);
|
300
|
+
}, this);
|
301
|
+
});
|
302
|
+
|
303
|
+
await this.putSearchIndexCompiled(m.constructor, compiledIndex);
|
304
|
+
}
|
305
|
+
|
306
|
+
if (m.constructor.indexedProperties().length > 0) {
|
307
|
+
indexUpdates[m.constructor.name] = {
|
308
|
+
...indexUpdates[m.constructor.name] || {},
|
309
|
+
[m.id]: undefined,
|
310
|
+
};
|
311
|
+
}
|
312
|
+
|
313
|
+
await this.deleteById(m.id);
|
314
|
+
deletedModels.push(m.id);
|
315
|
+
};
|
316
|
+
|
317
|
+
/**
|
318
|
+
* Process updates to all sub-models of the given model.
|
319
|
+
* @param {Model} m - The model to process for updates.
|
320
|
+
* @return {Promise<void>}
|
321
|
+
*/
|
322
|
+
const processModelUpdates = async (m) => {
|
323
|
+
if (!processedModels.includes(m.id)) {
|
324
|
+
processedModels.push(m.id);
|
325
|
+
|
326
|
+
for (const [key, property] of Object.entries(m)) {
|
327
|
+
if (Type.Model.isModel(property)) {
|
328
|
+
if (property.id === model.id) {
|
329
|
+
m[key] = undefined;
|
330
|
+
indexUpdates[m.constructor.name] = {
|
331
|
+
...indexUpdates[m.constructor.name] || {},
|
332
|
+
[m.id]: m,
|
333
|
+
};
|
334
|
+
modelUpdates.push(m);
|
335
|
+
}
|
336
|
+
|
337
|
+
if (m.id !== model.id && (Type.Model.isModel(m.constructor[key]) ? m.constructor[key] : m.constructor[key]())._required) {
|
338
|
+
additionalDeletions.push(m);
|
339
|
+
}
|
340
|
+
|
341
|
+
await processModelUpdates(property);
|
342
|
+
}
|
343
|
+
if (Array.isArray(property) && Type.Model.isModel(property[0])) {
|
344
|
+
for (const [index, subModel] of property.entries()) {
|
345
|
+
if (subModel.id === model.id) {
|
346
|
+
m[key].splice(index, 1);
|
347
|
+
indexUpdates[m.constructor.name] = {
|
348
|
+
...indexUpdates[m.constructor.name] || {},
|
349
|
+
[m.id]: m,
|
350
|
+
};
|
351
|
+
modelUpdates.push(m);
|
352
|
+
}
|
353
|
+
await processModelUpdates(subModel);
|
354
|
+
}
|
355
|
+
}
|
356
|
+
}
|
357
|
+
}
|
358
|
+
};
|
359
|
+
|
360
|
+
try {
|
361
|
+
const hydrated = await this.hydrate(model);
|
362
|
+
await processModelUpdates(hydrated);
|
363
|
+
await deleteModel(hydrated);
|
364
|
+
|
365
|
+
for (const updatedModel of modelUpdates) {
|
366
|
+
if (!additionalDeletions.map(m => m.id).includes(updatedModel.id)) {
|
367
|
+
await this.put(updatedModel);
|
368
|
+
}
|
369
|
+
}
|
370
|
+
|
371
|
+
for (const modelToBeDeleted of additionalDeletions) {
|
372
|
+
await deleteModel(modelToBeDeleted);
|
373
|
+
}
|
374
|
+
|
375
|
+
await this.putIndex(indexUpdates);
|
376
|
+
} catch (error) {
|
377
|
+
if (error.constructor === NotImplementedError) throw error;
|
378
|
+
throw new CannotDeleteEngineError(`${this.name}.delete(${model.id}) model cannot be deleted`, error);
|
379
|
+
}
|
380
|
+
}
|
381
|
+
|
246
382
|
/**
|
247
383
|
* Hydrates a model by populating its related properties (e.g., submodels) from stored data.
|
248
384
|
*
|
@@ -258,8 +394,10 @@ class Engine {
|
|
258
394
|
|
259
395
|
for (const [name, property] of Object.entries(modelToProcess)) {
|
260
396
|
if (Type.Model.isDryModel(property)) {
|
397
|
+
// skipcq: JS-0129
|
261
398
|
modelToProcess[name] = await hydrateSubModel(property, modelToProcess, name);
|
262
399
|
} else if (Array.isArray(property) && Type.Model.isDryModel(property[0])) {
|
400
|
+
// skipcq: JS-0129
|
263
401
|
modelToProcess[name] = await hydrateModelList(property, modelToProcess, name);
|
264
402
|
}
|
265
403
|
}
|
@@ -283,15 +421,15 @@ class Engine {
|
|
283
421
|
const hydrateModelList = async (property, modelToProcess, name) => {
|
284
422
|
const subModelClass = getSubModelClass(modelToProcess, name, true);
|
285
423
|
|
286
|
-
const newModelList = await Promise.all(property.map(
|
424
|
+
const newModelList = await Promise.all(property.map(subModel => {
|
287
425
|
if (hydratedModels[subModel.id]) {
|
288
426
|
return hydratedModels[subModel.id];
|
289
427
|
}
|
290
428
|
|
291
|
-
return
|
429
|
+
return this.get(subModelClass, subModel.id);
|
292
430
|
}));
|
293
431
|
|
294
|
-
return
|
432
|
+
return Promise.all(newModelList.map(async subModel => {
|
295
433
|
if (hydratedModels[subModel.id]) {
|
296
434
|
return hydratedModels[subModel.id];
|
297
435
|
}
|
@@ -312,7 +450,7 @@ class Engine {
|
|
312
450
|
return isArray ? constructorField._items : constructorField;
|
313
451
|
}
|
314
452
|
|
315
|
-
return
|
453
|
+
return hydrateModel(await this.get(model.constructor, model.id));
|
316
454
|
}
|
317
455
|
|
318
456
|
/**
|
@@ -387,6 +525,19 @@ export class NotFoundEngineError extends EngineError {
|
|
387
525
|
*/
|
388
526
|
}
|
389
527
|
|
528
|
+
/**
|
529
|
+
* Represents an error that occurs when a requested resource or item cannot be deleted by the engine.
|
530
|
+
* Extends the `EngineError` class.
|
531
|
+
*/
|
532
|
+
export class CannotDeleteEngineError extends EngineError {
|
533
|
+
/**
|
534
|
+
* Creates an instance of `CannotDeleteEngineError`.
|
535
|
+
*
|
536
|
+
* @param {string} message - The error message.
|
537
|
+
* @param {Error} [error] - An optional underlying error that caused this error.
|
538
|
+
*/
|
539
|
+
}
|
540
|
+
|
390
541
|
/**
|
391
542
|
* Represents an error indicating that a certain method or functionality is not implemented in the engine.
|
392
543
|
* Extends the `EngineError` class.
|
package/src/engine/FileEngine.js
CHANGED
@@ -64,6 +64,17 @@ class FileEngine extends Engine {
|
|
64
64
|
.then(JSON.parse);
|
65
65
|
}
|
66
66
|
|
67
|
+
/**
|
68
|
+
* Deletes a model by its ID from the file system.
|
69
|
+
*
|
70
|
+
* @param {string} id - The ID of the model to delete.
|
71
|
+
* @returns {Promise<void>} Resolves when the model has been deleted.
|
72
|
+
* @throws {Error} Throws if the file cannot be deleted.
|
73
|
+
*/
|
74
|
+
static deleteById(id) {
|
75
|
+
return this.configuration.filesystem.rm(join(this.configuration.path, `${id}.json`));
|
76
|
+
}
|
77
|
+
|
67
78
|
/**
|
68
79
|
* Retrieves the index for a given model from the file system.
|
69
80
|
*
|
@@ -98,19 +109,20 @@ class FileEngine extends Engine {
|
|
98
109
|
/**
|
99
110
|
* Saves the index for multiple models to the file system.
|
100
111
|
*
|
101
|
-
* @param {Object} index - An object where keys are locations and values are
|
112
|
+
* @param {Object} index - An object where keys are locations and values are key value pairs of models and their ids.
|
102
113
|
* @throws {FailedWriteFileEngineError} Throws if the index cannot be written to the file system.
|
103
114
|
*/
|
104
115
|
static async putIndex(index) {
|
105
116
|
const processIndex = async (location, models) => {
|
106
|
-
const modelIndex = Object.fromEntries(models.map((m) => [m.id, m.toIndexData()]));
|
107
117
|
const filePath = join(this.configuration.path, location, '_index.json');
|
108
118
|
const currentIndex = JSON.parse((await this.configuration.filesystem.readFile(filePath).catch(() => '{}')).toString());
|
109
119
|
|
110
120
|
try {
|
111
121
|
await this.configuration.filesystem.writeFile(filePath, JSON.stringify({
|
112
122
|
...currentIndex,
|
113
|
-
...
|
123
|
+
...Object.fromEntries(
|
124
|
+
Object.entries(models).map(([k, v]) => [k, v?.toIndexData?.() || v]),
|
125
|
+
),
|
114
126
|
}));
|
115
127
|
} catch (error) {
|
116
128
|
throw new FailedWriteFileEngineError(`Failed to put file://${filePath}`, error);
|
@@ -121,7 +133,12 @@ class FileEngine extends Engine {
|
|
121
133
|
await processIndex(location, models);
|
122
134
|
}
|
123
135
|
|
124
|
-
await processIndex('', Object.values(index).
|
136
|
+
await processIndex('', Object.values(index).reduce((accumulator, currentValue) => {
|
137
|
+
Object.keys(currentValue).forEach(key => {
|
138
|
+
accumulator[key] = currentValue[key];
|
139
|
+
});
|
140
|
+
return accumulator;
|
141
|
+
}, {}));
|
125
142
|
}
|
126
143
|
|
127
144
|
/**
|
package/src/engine/HTTPEngine.js
CHANGED
@@ -126,7 +126,7 @@ class HTTPEngine extends Engine {
|
|
126
126
|
*
|
127
127
|
* @throws {HTTPRequestFailedError} Thrown if the fetch request fails.
|
128
128
|
*/
|
129
|
-
static
|
129
|
+
static getById(id) {
|
130
130
|
this.checkConfiguration();
|
131
131
|
|
132
132
|
const url = new URL([
|
@@ -135,7 +135,26 @@ class HTTPEngine extends Engine {
|
|
135
135
|
`${id}.json`,
|
136
136
|
].filter(e => Boolean(e)).join('/'));
|
137
137
|
|
138
|
-
return
|
138
|
+
return this._processFetch(url, this._getReadOptions());
|
139
|
+
}
|
140
|
+
|
141
|
+
/**
|
142
|
+
* Deletes a model by its ID from an HTTP server.
|
143
|
+
*
|
144
|
+
* @param {string} id - The ID of the model to delete.
|
145
|
+
* @returns {Promise<void>} Resolves when the model has been deleted.
|
146
|
+
* @throws {Error} Throws if the file cannot be deleted.
|
147
|
+
*/
|
148
|
+
static deleteById(id) {
|
149
|
+
this.checkConfiguration();
|
150
|
+
|
151
|
+
const url = new URL([
|
152
|
+
this.configuration.host,
|
153
|
+
this.configuration.prefix,
|
154
|
+
`${id}.json`,
|
155
|
+
].filter(e => Boolean(e)).join('/'));
|
156
|
+
|
157
|
+
return this._processFetch(url, {...this._getReadOptions(), method: 'DELETE'});
|
139
158
|
}
|
140
159
|
|
141
160
|
/**
|
@@ -162,14 +181,12 @@ class HTTPEngine extends Engine {
|
|
162
181
|
/**
|
163
182
|
* Uploads (puts) an index object to the server.
|
164
183
|
*
|
165
|
-
* @param {Object} index -
|
184
|
+
* @param {Object} index - An object where keys are locations and values are key value pairs of models and their ids.
|
166
185
|
* @returns {Promise<void>}
|
167
|
-
*
|
168
186
|
* @throws {HTTPRequestFailedError} Thrown if the PUT request fails.
|
169
187
|
*/
|
170
188
|
static async putIndex(index) {
|
171
189
|
const processIndex = async (location, models) => {
|
172
|
-
const modelIndex = Object.fromEntries(models.map(m => [m.id, m.toIndexData()]));
|
173
190
|
const url = new URL([
|
174
191
|
this.configuration.host,
|
175
192
|
this.configuration.prefix,
|
@@ -177,11 +194,13 @@ class HTTPEngine extends Engine {
|
|
177
194
|
'_index.json',
|
178
195
|
].filter(e => Boolean(e)).join('/'));
|
179
196
|
|
180
|
-
return
|
197
|
+
return this._processFetch(url, {
|
181
198
|
...this._getWriteOptions(),
|
182
199
|
body: JSON.stringify({
|
183
200
|
...await this.getIndex(location),
|
184
|
-
...
|
201
|
+
...Object.fromEntries(
|
202
|
+
Object.entries(models).map(([k, v]) => [k, v?.toIndexData?.() || v]),
|
203
|
+
),
|
185
204
|
}),
|
186
205
|
});
|
187
206
|
};
|
@@ -190,7 +209,12 @@ class HTTPEngine extends Engine {
|
|
190
209
|
await processIndex(location, models);
|
191
210
|
}
|
192
211
|
|
193
|
-
await processIndex(null, Object.values(index).
|
212
|
+
await processIndex(null, Object.values(index).reduce((accumulator, currentValue) => {
|
213
|
+
Object.keys(currentValue).forEach(key => {
|
214
|
+
accumulator[key] = currentValue[key];
|
215
|
+
});
|
216
|
+
return accumulator;
|
217
|
+
}, {}));
|
194
218
|
}
|
195
219
|
|
196
220
|
/**
|
@@ -199,7 +223,7 @@ class HTTPEngine extends Engine {
|
|
199
223
|
* @param {Model.constructor?} model - The model in the host where the index is stored.
|
200
224
|
* @returns {Promise<Object>} The index data in JSON format.
|
201
225
|
*/
|
202
|
-
static
|
226
|
+
static getIndex(model) {
|
203
227
|
const url = new URL([
|
204
228
|
this.configuration.host,
|
205
229
|
this.configuration.prefix,
|
@@ -207,7 +231,7 @@ class HTTPEngine extends Engine {
|
|
207
231
|
'_index.json',
|
208
232
|
].filter(e => Boolean(e)).join('/'));
|
209
233
|
|
210
|
-
return
|
234
|
+
return this._processFetch(url, this._getReadOptions(), {});
|
211
235
|
}
|
212
236
|
|
213
237
|
/**
|
@@ -216,7 +240,7 @@ class HTTPEngine extends Engine {
|
|
216
240
|
* @param {Model.constructor} model - The model whose compiled search index to retrieve.
|
217
241
|
* @returns {Promise<Object>} The compiled search index in JSON format.
|
218
242
|
*/
|
219
|
-
static
|
243
|
+
static getSearchIndexCompiled(model) {
|
220
244
|
const url = new URL([
|
221
245
|
this.configuration.host,
|
222
246
|
this.configuration.prefix,
|
@@ -224,7 +248,7 @@ class HTTPEngine extends Engine {
|
|
224
248
|
'_search_index.json',
|
225
249
|
].join('/'));
|
226
250
|
|
227
|
-
return
|
251
|
+
return this._processFetch(url, this._getReadOptions());
|
228
252
|
}
|
229
253
|
|
230
254
|
/**
|
@@ -233,7 +257,7 @@ class HTTPEngine extends Engine {
|
|
233
257
|
* @param {Model.constructor} model - The model whose raw search index to retrieve.
|
234
258
|
* @returns {Promise<Object>} The raw search index in JSON format, or an empty object if not found.
|
235
259
|
*/
|
236
|
-
static
|
260
|
+
static getSearchIndexRaw(model) {
|
237
261
|
const url = new URL([
|
238
262
|
this.configuration.host,
|
239
263
|
this.configuration.prefix,
|
@@ -241,7 +265,7 @@ class HTTPEngine extends Engine {
|
|
241
265
|
'_search_index_raw.json',
|
242
266
|
].join('/'));
|
243
267
|
|
244
|
-
return
|
268
|
+
return this._processFetch(url, this._getReadOptions()).catch(() => ({}));
|
245
269
|
}
|
246
270
|
|
247
271
|
/**
|
@@ -253,7 +277,7 @@ class HTTPEngine extends Engine {
|
|
253
277
|
*
|
254
278
|
* @throws {HTTPRequestFailedError} Thrown if the PUT request fails.
|
255
279
|
*/
|
256
|
-
static
|
280
|
+
static putSearchIndexCompiled(model, compiledIndex) {
|
257
281
|
const url = new URL([
|
258
282
|
this.configuration.host,
|
259
283
|
this.configuration.prefix,
|
@@ -276,7 +300,7 @@ class HTTPEngine extends Engine {
|
|
276
300
|
*
|
277
301
|
* @throws {HTTPRequestFailedError} Thrown if the PUT request fails.
|
278
302
|
*/
|
279
|
-
static
|
303
|
+
static putSearchIndexRaw(model, rawIndex) {
|
280
304
|
const url = new URL([
|
281
305
|
this.configuration.host,
|
282
306
|
this.configuration.prefix,
|
@@ -284,7 +308,7 @@ class HTTPEngine extends Engine {
|
|
284
308
|
'_search_index_raw.json',
|
285
309
|
].filter(e => Boolean(e)).join('/'));
|
286
310
|
|
287
|
-
return
|
311
|
+
return this._processFetch(url, {
|
288
312
|
...this._getWriteOptions(),
|
289
313
|
body: JSON.stringify(rawIndex),
|
290
314
|
});
|
package/src/engine/S3Engine.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
+
import {DeleteObjectCommand, GetObjectCommand, PutObjectCommand} from '@aws-sdk/client-s3';
|
1
2
|
import Engine, {EngineError, MissConfiguredError} from './Engine.js';
|
2
|
-
import {GetObjectCommand, PutObjectCommand} from '@aws-sdk/client-s3';
|
3
3
|
|
4
4
|
/**
|
5
5
|
* Represents an error specific to the S3 engine operations.
|
@@ -68,6 +68,24 @@ class S3Engine extends Engine {
|
|
68
68
|
return JSON.parse(await data.Body.transformToString());
|
69
69
|
}
|
70
70
|
|
71
|
+
/**
|
72
|
+
* Deletes a model by its ID from theS3 bucket.
|
73
|
+
*
|
74
|
+
* @param {string} id - The ID of the model to delete.
|
75
|
+
* @returns {Promise<void>} Resolves when the model has been deleted.
|
76
|
+
* @throws {Error} Throws if the model cannot be deleted.
|
77
|
+
*/
|
78
|
+
static async deleteById(id) {
|
79
|
+
const objectPath = [this.configuration.prefix, `${id}.json`].join('/');
|
80
|
+
|
81
|
+
await this.configuration.client.send(new DeleteObjectCommand({
|
82
|
+
Bucket: this.configuration.bucket,
|
83
|
+
Key: objectPath,
|
84
|
+
}));
|
85
|
+
|
86
|
+
return undefined;
|
87
|
+
}
|
88
|
+
|
71
89
|
/**
|
72
90
|
* Puts (uploads) a model object to S3.
|
73
91
|
*
|
@@ -113,16 +131,13 @@ class S3Engine extends Engine {
|
|
113
131
|
/**
|
114
132
|
* Puts (uploads) an index object to S3.
|
115
133
|
*
|
116
|
-
* @param {Object} index -
|
134
|
+
* @param {Object} index - An object where keys are locations and values are key value pairs of models and their ids.
|
117
135
|
* @returns {Promise<void>}
|
118
|
-
*
|
119
136
|
* @throws {FailedPutS3EngineError} Thrown if there is an error during the S3 PutObject operation.
|
120
137
|
*/
|
121
138
|
static async putIndex(index) {
|
122
139
|
const processIndex = async (location, models) => {
|
123
|
-
const modelIndex = Object.fromEntries(models.map(m => [m.id, m.toIndexData()]));
|
124
140
|
const Key = [this.configuration.prefix, location, '_index.json'].filter(e => Boolean(e)).join('/');
|
125
|
-
|
126
141
|
const currentIndex = await this.getIndex(location);
|
127
142
|
|
128
143
|
try {
|
@@ -132,7 +147,9 @@ class S3Engine extends Engine {
|
|
132
147
|
ContentType: 'application/json',
|
133
148
|
Body: JSON.stringify({
|
134
149
|
...currentIndex,
|
135
|
-
...
|
150
|
+
...Object.fromEntries(
|
151
|
+
Object.entries(models).map(([k, v]) => [k, v?.toIndexData?.() || v]),
|
152
|
+
),
|
136
153
|
}),
|
137
154
|
}));
|
138
155
|
} catch (error) {
|
@@ -144,7 +161,12 @@ class S3Engine extends Engine {
|
|
144
161
|
await processIndex(location, models);
|
145
162
|
}
|
146
163
|
|
147
|
-
await processIndex(null, Object.values(index).
|
164
|
+
await processIndex(null, Object.values(index).reduce((accumulator, currentValue) => {
|
165
|
+
Object.keys(currentValue).forEach(key => {
|
166
|
+
accumulator[key] = currentValue[key];
|
167
|
+
});
|
168
|
+
return accumulator;
|
169
|
+
}, {}));
|
148
170
|
}
|
149
171
|
|
150
172
|
/**
|
@@ -153,9 +175,9 @@ class S3Engine extends Engine {
|
|
153
175
|
* @param {Model.constructor} model - The model whose search index to retrieve.
|
154
176
|
* @returns {Promise<Object>} The compiled search index.
|
155
177
|
*/
|
156
|
-
static
|
157
|
-
return
|
158
|
-
Key: [this.configuration.prefix, model.
|
178
|
+
static getSearchIndexCompiled(model) {
|
179
|
+
return this.configuration.client.send(new GetObjectCommand({
|
180
|
+
Key: [this.configuration.prefix, model.toString(), '_search_index.json'].join('/'),
|
159
181
|
Bucket: this.configuration.bucket,
|
160
182
|
})).then(data => data.Body.transformToString())
|
161
183
|
.then(JSON.parse);
|
@@ -167,8 +189,8 @@ class S3Engine extends Engine {
|
|
167
189
|
* @param {Model.constructor} model - The model whose raw search index to retrieve.
|
168
190
|
* @returns {Promise<Object>} The raw search index, or an empty object if not found.
|
169
191
|
*/
|
170
|
-
static
|
171
|
-
return
|
192
|
+
static getSearchIndexRaw(model) {
|
193
|
+
return this.configuration.client.send(new GetObjectCommand({
|
172
194
|
Key: [this.configuration.prefix, model.toString(), '_search_index_raw.json'].join('/'),
|
173
195
|
Bucket: this.configuration.bucket,
|
174
196
|
})).then(data => data.Body.transformToString())
|
package/src/type/Model.js
CHANGED