remult 3.3.18 → 3.3.19-next.2

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 (38) hide show
  1. package/esm/index.js +7 -6
  2. package/esm/remult-d1.js +1 -0
  3. package/esm/remult-knex/index.js +112 -2
  4. package/esm/remult-mongo.js +17 -8
  5. package/esm/remult-sqlite-core.js +1 -0
  6. package/esm/src/data-interfaces.js +4 -4
  7. package/esm/src/data-providers/array-entity-data-provider.js +14 -2
  8. package/esm/src/data-providers/indexed-db-data-provider.js +811 -0
  9. package/esm/src/data-providers/json-data-provider.js +2 -2
  10. package/esm/src/data-providers/rest-data-provider.js +11 -12
  11. package/esm/src/data-providers/sql-database.js +110 -43
  12. package/esm/src/remult3/RepositoryImplementation.js +90 -60
  13. package/index.d.ts +31 -17
  14. package/index.js +5 -2
  15. package/package.json +1 -1
  16. package/remult-d1.d.ts +1 -0
  17. package/remult-d1.js +1 -0
  18. package/remult-knex/index.d.ts +2 -2
  19. package/remult-knex/index.js +329 -44
  20. package/remult-mongo.js +80 -36
  21. package/remult-sqlite-core.d.ts +1 -0
  22. package/remult-sqlite-core.js +1 -0
  23. package/src/column-interfaces.d.ts +4 -0
  24. package/src/data-interfaces.d.ts +2 -3
  25. package/src/data-interfaces.js +4 -4
  26. package/src/data-providers/array-entity-data-provider.d.ts +2 -2
  27. package/src/data-providers/array-entity-data-provider.js +92 -14
  28. package/src/data-providers/indexed-db-data-provider.d.ts +39 -0
  29. package/src/data-providers/indexed-db-data-provider.js +1387 -0
  30. package/src/data-providers/json-data-provider.js +2 -2
  31. package/src/data-providers/rest-data-provider.d.ts +2 -3
  32. package/src/data-providers/rest-data-provider.js +18 -17
  33. package/src/data-providers/sql-database.js +254 -105
  34. package/src/remult3/RepositoryImplementation.d.ts +1 -1
  35. package/src/remult3/RepositoryImplementation.js +384 -270
  36. package/src/remult3/remult3.d.ts +2 -2
  37. package/src/sql-command.d.ts +2 -0
  38. package/src/standard-schema/index.d.ts +1 -1
@@ -0,0 +1,1387 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IndexedDbDataProvider = exports.IndexedDbIndexBuilder = void 0;
4
+ exports.idbPrefetchFromFilter = idbPrefetchFromFilter;
5
+ var tslib_1 = require("tslib");
6
+ var filter_consumer_bridge_to_sql_request_js_1 = require("../filter/filter-consumer-bridge-to-sql-request.js");
7
+ var RepositoryImplementation_js_1 = require("../remult3/RepositoryImplementation.js");
8
+ var array_entity_data_provider_js_1 = require("./array-entity-data-provider.js");
9
+ var IndexedDbIndexBuilder = /** @class */ (function () {
10
+ function IndexedDbIndexBuilder() {
11
+ //@internal
12
+ this.entries = [];
13
+ }
14
+ IndexedDbIndexBuilder.prototype.ensureIndexes = function (entity, indexes) {
15
+ this.entries.push({ entity: entity, indexes: tslib_1.__spreadArray([], tslib_1.__read(indexes), false) });
16
+ return this;
17
+ };
18
+ return IndexedDbIndexBuilder;
19
+ }());
20
+ exports.IndexedDbIndexBuilder = IndexedDbIndexBuilder;
21
+ var IDB_KEYS_STORE = '__remult_keys';
22
+ var IDB_DEK_ID = 'dek';
23
+ var IDB_ENC = '_enc';
24
+ var IDB_IV = '_iv';
25
+ var IndexedDbDataProvider = /** @class */ (function () {
26
+ function IndexedDbDataProvider(dbName, options) {
27
+ if (dbName === void 0) { dbName = 'remult'; }
28
+ this.dbName = dbName;
29
+ //@internal
30
+ this.declaredIndexes = [];
31
+ //@internal
32
+ this.tail = Promise.resolve();
33
+ this.encrypt = (options === null || options === void 0 ? void 0 : options.encrypt) === true;
34
+ this.customGetKey = options === null || options === void 0 ? void 0 : options.getEncryptionKey;
35
+ if (this.encrypt && !(typeof crypto !== 'undefined' && crypto.subtle)) {
36
+ throw new Error('Web Crypto API is required when IndexedDB encryption is enabled');
37
+ }
38
+ if (options === null || options === void 0 ? void 0 : options.indexes) {
39
+ var builder = new IndexedDbIndexBuilder();
40
+ options.indexes(builder);
41
+ this.declaredIndexes = builder.entries;
42
+ }
43
+ }
44
+ IndexedDbDataProvider.prototype.getEntityDataProvider = function (entity) {
45
+ return new IndexedDbEntityDataProvider(this, entity);
46
+ };
47
+ IndexedDbDataProvider.prototype.transaction = function (action) {
48
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
49
+ return tslib_1.__generator(this, function (_a) {
50
+ switch (_a.label) {
51
+ case 0: return [4 /*yield*/, action(this)];
52
+ case 1:
53
+ _a.sent();
54
+ return [2 /*return*/];
55
+ }
56
+ });
57
+ });
58
+ };
59
+ IndexedDbDataProvider.prototype.ensureSchema = function (entities) {
60
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
61
+ var _this = this;
62
+ return tslib_1.__generator(this, function (_a) {
63
+ switch (_a.label) {
64
+ case 0: return [4 /*yield*/, this.enqueue(function () { return _this.ensureStores(entities); })];
65
+ case 1:
66
+ _a.sent();
67
+ return [2 /*return*/];
68
+ }
69
+ });
70
+ });
71
+ };
72
+ IndexedDbDataProvider.prototype.close = function () {
73
+ var _a;
74
+ (_a = this.db) === null || _a === void 0 ? void 0 : _a.close();
75
+ this.db = undefined;
76
+ };
77
+ //@internal
78
+ IndexedDbDataProvider.prototype.enqueue = function (fn) {
79
+ var run = this.tail.then(fn, fn);
80
+ this.tail = run.then(function () { }, function () { });
81
+ return run;
82
+ };
83
+ //@internal
84
+ IndexedDbDataProvider.prototype.runWithRows = function (entity, where, what) {
85
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
86
+ var _this = this;
87
+ return tslib_1.__generator(this, function (_a) {
88
+ return [2 /*return*/, this.enqueue(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
89
+ var rows;
90
+ return tslib_1.__generator(this, function (_a) {
91
+ switch (_a.label) {
92
+ case 0: return [4 /*yield*/, this.ensureStores([entity])];
93
+ case 1:
94
+ _a.sent();
95
+ return [4 /*yield*/, this.loadRows(entity, where)];
96
+ case 2:
97
+ rows = _a.sent();
98
+ return [2 /*return*/, what(new array_entity_data_provider_js_1.ArrayEntityDataProvider(entity, function () { return rows; }))];
99
+ }
100
+ });
101
+ }); })];
102
+ });
103
+ });
104
+ };
105
+ //@internal
106
+ IndexedDbDataProvider.prototype.fetchRows = function (entity, where) {
107
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
108
+ var _this = this;
109
+ return tslib_1.__generator(this, function (_a) {
110
+ return [2 /*return*/, this.enqueue(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
111
+ return tslib_1.__generator(this, function (_a) {
112
+ switch (_a.label) {
113
+ case 0: return [4 /*yield*/, this.ensureStores([entity])];
114
+ case 1:
115
+ _a.sent();
116
+ return [2 /*return*/, this.loadRows(entity, where)];
117
+ }
118
+ });
119
+ }); })];
120
+ });
121
+ });
122
+ };
123
+ //@internal
124
+ IndexedDbDataProvider.prototype.loadRows = function (entity, where) {
125
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
126
+ var storeName, prefetch, rows, _a, dek, names;
127
+ return tslib_1.__generator(this, function (_b) {
128
+ switch (_b.label) {
129
+ case 0:
130
+ storeName = storeNameOf(entity);
131
+ return [4 /*yield*/, idbPrefetchFromFilter(entity, where, this.storeIndexes(storeName))];
132
+ case 1:
133
+ prefetch = _b.sent();
134
+ this.lastFetch = prefetch;
135
+ if (!(prefetch.type === 'all')) return [3 /*break*/, 3];
136
+ return [4 /*yield*/, this.getAll(storeName)];
137
+ case 2:
138
+ _a = _b.sent();
139
+ return [3 /*break*/, 5];
140
+ case 3: return [4 /*yield*/, this.fetchOps(storeName, entity, prefetch.type === 'or' ? prefetch.parts : [prefetch])];
141
+ case 4:
142
+ _a = _b.sent();
143
+ _b.label = 5;
144
+ case 5:
145
+ rows = _a;
146
+ if (!this.encrypt)
147
+ return [2 /*return*/, rows];
148
+ return [4 /*yield*/, this.loadDek()];
149
+ case 6:
150
+ dek = _b.sent();
151
+ return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(entity, function (x) { return x; })];
152
+ case 7:
153
+ names = _b.sent();
154
+ return [2 /*return*/, Promise.all(rows.map(function (row) { return decryptJson(storeName, row, entity, names, dek); }))];
155
+ }
156
+ });
157
+ });
158
+ };
159
+ //@internal
160
+ IndexedDbDataProvider.prototype.storeIndexes = function (storeName) {
161
+ var db = this.db;
162
+ if (!(db === null || db === void 0 ? void 0 : db.objectStoreNames.contains(storeName)))
163
+ return [];
164
+ var store = db.transaction(storeName).objectStore(storeName);
165
+ var names = store.indexNames;
166
+ var result = [];
167
+ for (var i = 0; i < names.length; i++) {
168
+ var name_1 = names[i];
169
+ result.push({
170
+ name: name_1,
171
+ keyPath: store.index(name_1).keyPath,
172
+ });
173
+ }
174
+ return result;
175
+ };
176
+ //@internal
177
+ IndexedDbDataProvider.prototype.indexesFor = function (entity) {
178
+ return this.declaredIndexes
179
+ .filter(function (e) { return e.entity === entity.entityType; })
180
+ .flatMap(function (e) { return e.indexes; });
181
+ };
182
+ //@internal
183
+ IndexedDbDataProvider.prototype.ensureStores = function (entities) {
184
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
185
+ var wanted, db, needsKeyStore, needsUpgrade, nextVersion;
186
+ var _this = this;
187
+ return tslib_1.__generator(this, function (_a) {
188
+ switch (_a.label) {
189
+ case 0: return [4 /*yield*/, Promise.all(entities.map(function (entity) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
190
+ var keyPath;
191
+ var _a;
192
+ return tslib_1.__generator(this, function (_b) {
193
+ switch (_b.label) {
194
+ case 0: return [4 /*yield*/, keyPathOf(entity)];
195
+ case 1:
196
+ keyPath = _b.sent();
197
+ _a = {
198
+ name: storeNameOf(entity),
199
+ keyPath: keyPath,
200
+ autoIncrement: (0, RepositoryImplementation_js_1.isAutoIncrement)(entity.idMetadata.field)
201
+ };
202
+ return [4 /*yield*/, resolveIndexDefs(entity, this.indexesFor(entity), keyPath)];
203
+ case 2: return [2 /*return*/, (_a.indexes = _b.sent(),
204
+ _a)];
205
+ }
206
+ });
207
+ }); }))];
208
+ case 1:
209
+ wanted = _a.sent();
210
+ return [4 /*yield*/, this.open()];
211
+ case 2:
212
+ db = _a.sent();
213
+ needsKeyStore = this.usesKeyStore() && !db.objectStoreNames.contains(IDB_KEYS_STORE);
214
+ needsUpgrade = needsKeyStore ||
215
+ wanted.some(function (w) {
216
+ if (!db.objectStoreNames.contains(w.name))
217
+ return true;
218
+ var existing = _this.storeIndexes(w.name).map(function (i) { return i.name; });
219
+ return w.indexes.some(function (idx) { return !existing.includes(idx.name); });
220
+ });
221
+ if (!needsUpgrade)
222
+ return [2 /*return*/];
223
+ nextVersion = db.version + 1;
224
+ this.forget(db);
225
+ db.close();
226
+ return [4 /*yield*/, this.open(nextVersion, function (upgradeDb, tx) {
227
+ var e_1, _a, e_2, _b;
228
+ if (_this.usesKeyStore() &&
229
+ !upgradeDb.objectStoreNames.contains(IDB_KEYS_STORE)) {
230
+ upgradeDb.createObjectStore(IDB_KEYS_STORE, { keyPath: 'id' });
231
+ }
232
+ try {
233
+ for (var wanted_1 = tslib_1.__values(wanted), wanted_1_1 = wanted_1.next(); !wanted_1_1.done; wanted_1_1 = wanted_1.next()) {
234
+ var _c = wanted_1_1.value, name_2 = _c.name, keyPath = _c.keyPath, autoIncrement = _c.autoIncrement, indexes = _c.indexes;
235
+ var store = upgradeDb.objectStoreNames.contains(name_2)
236
+ ? tx.objectStore(name_2)
237
+ : upgradeDb.createObjectStore(name_2, { keyPath: keyPath, autoIncrement: autoIncrement });
238
+ try {
239
+ for (var indexes_1 = (e_2 = void 0, tslib_1.__values(indexes)), indexes_1_1 = indexes_1.next(); !indexes_1_1.done; indexes_1_1 = indexes_1.next()) {
240
+ var idx = indexes_1_1.value;
241
+ if (!store.indexNames.contains(idx.name)) {
242
+ store.createIndex(idx.name, idx.keyPath);
243
+ }
244
+ }
245
+ }
246
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
247
+ finally {
248
+ try {
249
+ if (indexes_1_1 && !indexes_1_1.done && (_b = indexes_1.return)) _b.call(indexes_1);
250
+ }
251
+ finally { if (e_2) throw e_2.error; }
252
+ }
253
+ }
254
+ }
255
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
256
+ finally {
257
+ try {
258
+ if (wanted_1_1 && !wanted_1_1.done && (_a = wanted_1.return)) _a.call(wanted_1);
259
+ }
260
+ finally { if (e_1) throw e_1.error; }
261
+ }
262
+ })];
263
+ case 3:
264
+ _a.sent();
265
+ return [2 /*return*/];
266
+ }
267
+ });
268
+ });
269
+ };
270
+ //@internal
271
+ IndexedDbDataProvider.prototype.usesKeyStore = function () {
272
+ return this.encrypt && !this.customGetKey;
273
+ };
274
+ //@internal
275
+ IndexedDbDataProvider.prototype.loadDek = function () {
276
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
277
+ var key_1, existing, generated, key;
278
+ var _this = this;
279
+ return tslib_1.__generator(this, function (_a) {
280
+ switch (_a.label) {
281
+ case 0:
282
+ if (this.dek)
283
+ return [2 /*return*/, this.dek];
284
+ if (!this.customGetKey) return [3 /*break*/, 2];
285
+ return [4 /*yield*/, this.customGetKey()];
286
+ case 1:
287
+ key_1 = _a.sent();
288
+ this.dek = key_1;
289
+ return [2 /*return*/, key_1];
290
+ case 2: return [4 /*yield*/, this.withStore(IDB_KEYS_STORE, 'readonly', function (s) {
291
+ return idbReq(s.get(IDB_DEK_ID));
292
+ })];
293
+ case 3:
294
+ existing = _a.sent();
295
+ if (existing === null || existing === void 0 ? void 0 : existing.key) {
296
+ this.dek = existing.key;
297
+ return [2 /*return*/, existing.key];
298
+ }
299
+ return [4 /*yield*/, crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt'])];
300
+ case 4:
301
+ generated = _a.sent();
302
+ return [4 /*yield*/, this.withStore(IDB_KEYS_STORE, 'readwrite', function (s) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
303
+ var rec, e_3, again;
304
+ return tslib_1.__generator(this, function (_a) {
305
+ switch (_a.label) {
306
+ case 0: return [4 /*yield*/, idbReq(s.get(IDB_DEK_ID))];
307
+ case 1:
308
+ rec = _a.sent();
309
+ if (rec === null || rec === void 0 ? void 0 : rec.key)
310
+ return [2 /*return*/, rec.key];
311
+ _a.label = 2;
312
+ case 2:
313
+ _a.trys.push([2, 4, , 7]);
314
+ return [4 /*yield*/, idbReq(s.add({ id: IDB_DEK_ID, key: generated }))];
315
+ case 3:
316
+ _a.sent();
317
+ return [2 /*return*/, generated];
318
+ case 4:
319
+ e_3 = _a.sent();
320
+ if (!((e_3 === null || e_3 === void 0 ? void 0 : e_3.name) === 'ConstraintError')) return [3 /*break*/, 6];
321
+ return [4 /*yield*/, idbReq(s.get(IDB_DEK_ID))];
322
+ case 5:
323
+ again = _a.sent();
324
+ if (!(again === null || again === void 0 ? void 0 : again.key))
325
+ throw new Error('Failed to load IndexedDB encryption key');
326
+ return [2 /*return*/, again.key];
327
+ case 6: throw e_3;
328
+ case 7: return [2 /*return*/];
329
+ }
330
+ });
331
+ }); })];
332
+ case 5:
333
+ key = _a.sent();
334
+ this.dek = key;
335
+ return [2 /*return*/, key];
336
+ }
337
+ });
338
+ });
339
+ };
340
+ //@internal
341
+ IndexedDbDataProvider.prototype.plaintextDbNames = function (entity) {
342
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
343
+ var names, set, _a, _b, f, _c, _d, def, keys, _loop_1, keys_1, keys_1_1, key;
344
+ var e_4, _e, e_5, _f, e_6, _g;
345
+ return tslib_1.__generator(this, function (_h) {
346
+ switch (_h.label) {
347
+ case 0: return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(entity, function (x) { return x; })];
348
+ case 1:
349
+ names = _h.sent();
350
+ set = new Set();
351
+ try {
352
+ for (_a = tslib_1.__values(entity.idMetadata.fields), _b = _a.next(); !_b.done; _b = _a.next()) {
353
+ f = _b.value;
354
+ set.add(names.$dbNameOf(f));
355
+ }
356
+ }
357
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
358
+ finally {
359
+ try {
360
+ if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
361
+ }
362
+ finally { if (e_4) throw e_4.error; }
363
+ }
364
+ try {
365
+ for (_c = tslib_1.__values(this.indexesFor(entity)), _d = _c.next(); !_d.done; _d = _c.next()) {
366
+ def = _d.value;
367
+ keys = Array.isArray(def) ? tslib_1.__spreadArray([], tslib_1.__read(def), false) : [def];
368
+ _loop_1 = function (key) {
369
+ var field = tslib_1.__spreadArray([], tslib_1.__read(entity.fields), false).find(function (f) { return f.key === key; });
370
+ if (field)
371
+ set.add(names.$dbNameOf(field));
372
+ };
373
+ try {
374
+ for (keys_1 = (e_6 = void 0, tslib_1.__values(keys)), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
375
+ key = keys_1_1.value;
376
+ _loop_1(key);
377
+ }
378
+ }
379
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
380
+ finally {
381
+ try {
382
+ if (keys_1_1 && !keys_1_1.done && (_g = keys_1.return)) _g.call(keys_1);
383
+ }
384
+ finally { if (e_6) throw e_6.error; }
385
+ }
386
+ }
387
+ }
388
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
389
+ finally {
390
+ try {
391
+ if (_d && !_d.done && (_f = _c.return)) _f.call(_c);
392
+ }
393
+ finally { if (e_5) throw e_5.error; }
394
+ }
395
+ return [2 /*return*/, set];
396
+ }
397
+ });
398
+ });
399
+ };
400
+ //@internal
401
+ IndexedDbDataProvider.prototype.forget = function (db) {
402
+ if (this.db === db)
403
+ this.db = undefined;
404
+ };
405
+ //@internal
406
+ IndexedDbDataProvider.prototype.open = function (version, upgrade) {
407
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
408
+ var _a;
409
+ var _this = this;
410
+ return tslib_1.__generator(this, function (_b) {
411
+ switch (_b.label) {
412
+ case 0:
413
+ if (this.db && version == null)
414
+ return [2 /*return*/, this.db];
415
+ _a = this;
416
+ return [4 /*yield*/, new Promise(function (resolve, reject) {
417
+ var request = version == null
418
+ ? indexedDB.open(_this.dbName)
419
+ : indexedDB.open(_this.dbName, version);
420
+ request.onerror = function () { return reject(request.error); };
421
+ request.onupgradeneeded = function () {
422
+ return upgrade === null || upgrade === void 0 ? void 0 : upgrade(request.result, request.transaction);
423
+ };
424
+ request.onsuccess = function () {
425
+ var db = request.result;
426
+ var forget = function () { return _this.forget(db); };
427
+ db.onclose = forget;
428
+ db.onversionchange = function () {
429
+ db.close();
430
+ forget();
431
+ };
432
+ resolve(db);
433
+ };
434
+ })];
435
+ case 1:
436
+ _a.db = _b.sent();
437
+ return [2 /*return*/, this.db];
438
+ }
439
+ });
440
+ });
441
+ };
442
+ //@internal
443
+ IndexedDbDataProvider.prototype.getAll = function (storeName, range) {
444
+ return this.withStore(storeName, 'readonly', function (store) {
445
+ return idbReq(range ? store.getAll(range) : store.getAll());
446
+ });
447
+ };
448
+ //@internal
449
+ IndexedDbDataProvider.prototype.fetchOps = function (storeName, entity, ops) {
450
+ var _this = this;
451
+ return this.withStore(storeName, 'readonly', function (store) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
452
+ var idKey, seen, rows, _loop_2, ops_1, ops_1_1, op, e_7_1;
453
+ var e_7, _a;
454
+ return tslib_1.__generator(this, function (_b) {
455
+ switch (_b.label) {
456
+ case 0:
457
+ idKey = entity.idMetadata.fields[0].key;
458
+ seen = new Set();
459
+ rows = [];
460
+ _loop_2 = function (op) {
461
+ var source, chunk, _c, _d, chunk_1, chunk_1_1, row, k;
462
+ var e_8, _e;
463
+ return tslib_1.__generator(this, function (_f) {
464
+ switch (_f.label) {
465
+ case 0:
466
+ source = op.index ? store.index(op.index) : store;
467
+ if (!(op.type === 'keys')) return [3 /*break*/, 5];
468
+ if (!op.index) return [3 /*break*/, 2];
469
+ return [4 /*yield*/, Promise.all(op.keys.map(function (key) { return idbReq(source.getAll(key)); }))];
470
+ case 1:
471
+ _d = (_f.sent()).flat();
472
+ return [3 /*break*/, 4];
473
+ case 2: return [4 /*yield*/, Promise.all(op.keys.map(function (key) { return idbReq(store.get(key)); }))];
474
+ case 3:
475
+ _d = _f.sent();
476
+ _f.label = 4;
477
+ case 4:
478
+ _c = _d;
479
+ return [3 /*break*/, 7];
480
+ case 5: return [4 /*yield*/, idbReq(source.getAll(op.range))];
481
+ case 6:
482
+ _c = _f.sent();
483
+ _f.label = 7;
484
+ case 7:
485
+ chunk = _c;
486
+ try {
487
+ for (chunk_1 = (e_8 = void 0, tslib_1.__values(chunk)), chunk_1_1 = chunk_1.next(); !chunk_1_1.done; chunk_1_1 = chunk_1.next()) {
488
+ row = chunk_1_1.value;
489
+ if (row == null)
490
+ continue;
491
+ k = JSON.stringify(row[idKey]);
492
+ if (seen.has(k))
493
+ continue;
494
+ seen.add(k);
495
+ rows.push(row);
496
+ }
497
+ }
498
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
499
+ finally {
500
+ try {
501
+ if (chunk_1_1 && !chunk_1_1.done && (_e = chunk_1.return)) _e.call(chunk_1);
502
+ }
503
+ finally { if (e_8) throw e_8.error; }
504
+ }
505
+ return [2 /*return*/];
506
+ }
507
+ });
508
+ };
509
+ _b.label = 1;
510
+ case 1:
511
+ _b.trys.push([1, 6, 7, 8]);
512
+ ops_1 = tslib_1.__values(ops), ops_1_1 = ops_1.next();
513
+ _b.label = 2;
514
+ case 2:
515
+ if (!!ops_1_1.done) return [3 /*break*/, 5];
516
+ op = ops_1_1.value;
517
+ return [5 /*yield**/, _loop_2(op)];
518
+ case 3:
519
+ _b.sent();
520
+ _b.label = 4;
521
+ case 4:
522
+ ops_1_1 = ops_1.next();
523
+ return [3 /*break*/, 2];
524
+ case 5: return [3 /*break*/, 8];
525
+ case 6:
526
+ e_7_1 = _b.sent();
527
+ e_7 = { error: e_7_1 };
528
+ return [3 /*break*/, 8];
529
+ case 7:
530
+ try {
531
+ if (ops_1_1 && !ops_1_1.done && (_a = ops_1.return)) _a.call(ops_1);
532
+ }
533
+ finally { if (e_7) throw e_7.error; }
534
+ return [7 /*endfinally*/];
535
+ case 8: return [2 /*return*/, rows];
536
+ }
537
+ });
538
+ }); });
539
+ };
540
+ //@internal
541
+ IndexedDbDataProvider.prototype.withStore = function (storeName, mode, op) {
542
+ var _this = this;
543
+ return new Promise(function (resolve, reject) {
544
+ var tx = _this.db.transaction(storeName, mode);
545
+ var result;
546
+ var opErr;
547
+ tx.oncomplete = function () {
548
+ if (opErr)
549
+ reject(opErr);
550
+ else
551
+ resolve(result);
552
+ };
553
+ tx.onabort = function () { return reject(opErr !== null && opErr !== void 0 ? opErr : tx.error); };
554
+ tx.onerror = function () { return reject(opErr !== null && opErr !== void 0 ? opErr : tx.error); };
555
+ Promise.resolve(op(tx.objectStore(storeName))).then(function (r) {
556
+ result = r;
557
+ }, function (e) {
558
+ opErr = e;
559
+ try {
560
+ tx.abort();
561
+ }
562
+ catch (_a) {
563
+ /* already aborted */
564
+ }
565
+ });
566
+ });
567
+ };
568
+ return IndexedDbDataProvider;
569
+ }());
570
+ exports.IndexedDbDataProvider = IndexedDbDataProvider;
571
+ var IndexedDbEntityDataProvider = /** @class */ (function () {
572
+ function IndexedDbEntityDataProvider(provider, entity) {
573
+ this.provider = provider;
574
+ this.entity = entity;
575
+ }
576
+ IndexedDbEntityDataProvider.prototype.find = function (options) {
577
+ return this.provider.runWithRows(this.entity, options === null || options === void 0 ? void 0 : options.where, function (dp) {
578
+ return dp.find(options);
579
+ });
580
+ };
581
+ IndexedDbEntityDataProvider.prototype.count = function (where) {
582
+ return this.provider.runWithRows(this.entity, where, function (dp) { return dp.count(where); });
583
+ };
584
+ IndexedDbEntityDataProvider.prototype.groupBy = function (options) {
585
+ return this.provider.runWithRows(this.entity, options === null || options === void 0 ? void 0 : options.where, function (dp) {
586
+ return dp.groupBy(options);
587
+ });
588
+ };
589
+ IndexedDbEntityDataProvider.prototype.insert = function (data) {
590
+ var _this = this;
591
+ return this.provider.enqueue(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
592
+ var helper, names, auto, idName, rows, storeName, dek, _a, keep, _b, keys, i, toWrite, _c;
593
+ var _this = this;
594
+ return tslib_1.__generator(this, function (_d) {
595
+ switch (_d.label) {
596
+ case 0: return [4 /*yield*/, this.provider.ensureStores([this.entity])];
597
+ case 1:
598
+ _d.sent();
599
+ helper = new array_entity_data_provider_js_1.ArrayEntityDataProvider(this.entity, function () { return []; });
600
+ return [4 /*yield*/, helper.init()];
601
+ case 2:
602
+ names = _d.sent();
603
+ auto = (0, RepositoryImplementation_js_1.isAutoIncrement)(this.entity.idMetadata.field);
604
+ idName = names.$dbNameOf(this.entity.idMetadata.field);
605
+ rows = data.map(function (row) {
606
+ var json = helper.translateToJson(row, names);
607
+ helper.verifyThatRowHasAllNotNullColumns(json, names);
608
+ if (auto)
609
+ delete json[idName];
610
+ return json;
611
+ });
612
+ storeName = storeNameOf(this.entity);
613
+ if (!this.provider.encrypt) return [3 /*break*/, 4];
614
+ return [4 /*yield*/, this.provider.loadDek()];
615
+ case 3:
616
+ _a = _d.sent();
617
+ return [3 /*break*/, 5];
618
+ case 4:
619
+ _a = undefined;
620
+ _d.label = 5;
621
+ case 5:
622
+ dek = _a;
623
+ if (!dek) return [3 /*break*/, 7];
624
+ return [4 /*yield*/, this.provider.plaintextDbNames(this.entity)];
625
+ case 6:
626
+ _b = _d.sent();
627
+ return [3 /*break*/, 8];
628
+ case 7:
629
+ _b = undefined;
630
+ _d.label = 8;
631
+ case 8:
632
+ keep = _b;
633
+ if (!(dek && auto)) return [3 /*break*/, 10];
634
+ return [4 /*yield*/, this.provider.withStore(storeName, 'readwrite', function (store) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
635
+ var allocated, i, _a, _b;
636
+ return tslib_1.__generator(this, function (_c) {
637
+ switch (_c.label) {
638
+ case 0:
639
+ allocated = [];
640
+ i = 0;
641
+ _c.label = 1;
642
+ case 1:
643
+ if (!(i < rows.length)) return [3 /*break*/, 4];
644
+ _b = (_a = allocated).push;
645
+ return [4 /*yield*/, idbReq(store.add({}))];
646
+ case 2:
647
+ _b.apply(_a, [_c.sent()]);
648
+ _c.label = 3;
649
+ case 3:
650
+ i++;
651
+ return [3 /*break*/, 1];
652
+ case 4: return [2 /*return*/, allocated];
653
+ }
654
+ });
655
+ }); })];
656
+ case 9:
657
+ keys = _d.sent();
658
+ for (i = 0; i < rows.length; i++) {
659
+ rows[i][idName] = keys[i];
660
+ }
661
+ _d.label = 10;
662
+ case 10:
663
+ if (!dek) return [3 /*break*/, 12];
664
+ return [4 /*yield*/, Promise.all(rows.map(function (json) {
665
+ return encryptJson(storeName, json, keep, keyFromRow(_this.entity, names, json), dek);
666
+ }))];
667
+ case 11:
668
+ _c = _d.sent();
669
+ return [3 /*break*/, 13];
670
+ case 12:
671
+ _c = rows;
672
+ _d.label = 13;
673
+ case 13:
674
+ toWrite = _c;
675
+ return [4 /*yield*/, this.provider.withStore(storeName, 'readwrite', function (store) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
676
+ var i, key, e_9;
677
+ var _a;
678
+ return tslib_1.__generator(this, function (_b) {
679
+ switch (_b.label) {
680
+ case 0:
681
+ i = 0;
682
+ _b.label = 1;
683
+ case 1:
684
+ if (!(i < toWrite.length)) return [3 /*break*/, 9];
685
+ _b.label = 2;
686
+ case 2:
687
+ _b.trys.push([2, 7, , 8]);
688
+ if (!(dek && auto)) return [3 /*break*/, 4];
689
+ return [4 /*yield*/, idbReq(store.put(toWrite[i]))];
690
+ case 3:
691
+ _b.sent();
692
+ return [3 /*break*/, 6];
693
+ case 4: return [4 /*yield*/, idbReq(store.add(toWrite[i]))];
694
+ case 5:
695
+ key = _b.sent();
696
+ if (auto)
697
+ rows[i][idName] = (_a = rows[i][idName]) !== null && _a !== void 0 ? _a : key;
698
+ _b.label = 6;
699
+ case 6: return [3 /*break*/, 8];
700
+ case 7:
701
+ e_9 = _b.sent();
702
+ if ((e_9 === null || e_9 === void 0 ? void 0 : e_9.name) === 'ConstraintError')
703
+ throw Error('id already exists');
704
+ throw e_9;
705
+ case 8:
706
+ i++;
707
+ return [3 /*break*/, 1];
708
+ case 9: return [2 /*return*/];
709
+ }
710
+ });
711
+ }); })];
712
+ case 14:
713
+ _d.sent();
714
+ return [2 /*return*/, rows.map(function (json) { return helper.translateFromJson(json, names); })];
715
+ }
716
+ });
717
+ }); });
718
+ };
719
+ IndexedDbEntityDataProvider.prototype.update = function (id, data) {
720
+ var _this = this;
721
+ return this.provider.enqueue(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
722
+ var helper, names, key, storeName, existingRaw, dek, _a, existing, _b, json, keys, _c, _d, f, newKey, toWrite, _e, _f, _g;
723
+ var e_10, _h;
724
+ var _this = this;
725
+ return tslib_1.__generator(this, function (_j) {
726
+ switch (_j.label) {
727
+ case 0: return [4 /*yield*/, this.provider.ensureStores([this.entity])];
728
+ case 1:
729
+ _j.sent();
730
+ helper = new array_entity_data_provider_js_1.ArrayEntityDataProvider(this.entity, function () { return []; });
731
+ return [4 /*yield*/, helper.init()];
732
+ case 2:
733
+ names = _j.sent();
734
+ key = toIdbKey(this.entity, id);
735
+ storeName = storeNameOf(this.entity);
736
+ return [4 /*yield*/, this.provider.withStore(storeName, 'readonly', function (store) { return idbReq(store.get(key)); })];
737
+ case 3:
738
+ existingRaw = _j.sent();
739
+ if (existingRaw == null)
740
+ throw new Error("Couldn't find row with id \"".concat(id, "\" in entity \"").concat(this.entity.key, "\" to update"));
741
+ if (!this.provider.encrypt) return [3 /*break*/, 5];
742
+ return [4 /*yield*/, this.provider.loadDek()];
743
+ case 4:
744
+ _a = _j.sent();
745
+ return [3 /*break*/, 6];
746
+ case 5:
747
+ _a = undefined;
748
+ _j.label = 6;
749
+ case 6:
750
+ dek = _a;
751
+ if (!dek) return [3 /*break*/, 8];
752
+ return [4 /*yield*/, decryptJson(storeName, existingRaw, this.entity, names, dek)];
753
+ case 7:
754
+ _b = _j.sent();
755
+ return [3 /*break*/, 9];
756
+ case 8:
757
+ _b = existingRaw;
758
+ _j.label = 9;
759
+ case 9:
760
+ existing = _b;
761
+ json = tslib_1.__assign({}, existing);
762
+ keys = Object.keys(data);
763
+ try {
764
+ for (_c = tslib_1.__values(this.entity.fields), _d = _c.next(); !_d.done; _d = _c.next()) {
765
+ f = _d.value;
766
+ if (!(0, filter_consumer_bridge_to_sql_request_js_1.isDbReadonly)(f, names) && keys.includes(f.key)) {
767
+ json[names.$dbNameOf(f)] = f.valueConverter.toJson(data[f.key]);
768
+ }
769
+ }
770
+ }
771
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
772
+ finally {
773
+ try {
774
+ if (_d && !_d.done && (_h = _c.return)) _h.call(_c);
775
+ }
776
+ finally { if (e_10) throw e_10.error; }
777
+ }
778
+ helper.verifyThatRowHasAllNotNullColumns(json, names);
779
+ newKey = keyFromRow(this.entity, names, json);
780
+ if (!dek) return [3 /*break*/, 12];
781
+ _f = encryptJson;
782
+ _g = [storeName,
783
+ json];
784
+ return [4 /*yield*/, this.provider.plaintextDbNames(this.entity)];
785
+ case 10: return [4 /*yield*/, _f.apply(void 0, _g.concat([_j.sent(), newKey,
786
+ dek]))];
787
+ case 11:
788
+ _e = _j.sent();
789
+ return [3 /*break*/, 13];
790
+ case 12:
791
+ _e = json;
792
+ _j.label = 13;
793
+ case 13:
794
+ toWrite = _e;
795
+ return [4 /*yield*/, this.provider.withStore(storeName, 'readwrite', function (store) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
796
+ var conflict;
797
+ return tslib_1.__generator(this, function (_a) {
798
+ switch (_a.label) {
799
+ case 0:
800
+ if (!!idbKeysEqual(key, newKey)) return [3 /*break*/, 3];
801
+ return [4 /*yield*/, idbReq(store.get(newKey))];
802
+ case 1:
803
+ conflict = _a.sent();
804
+ if (conflict != null)
805
+ throw Error('id already exists');
806
+ return [4 /*yield*/, idbReq(store.delete(key))];
807
+ case 2:
808
+ _a.sent();
809
+ _a.label = 3;
810
+ case 3: return [4 /*yield*/, idbReq(store.put(toWrite))];
811
+ case 4:
812
+ _a.sent();
813
+ return [2 /*return*/];
814
+ }
815
+ });
816
+ }); })];
817
+ case 14:
818
+ _j.sent();
819
+ return [2 /*return*/, helper.translateFromJson(json, names)];
820
+ }
821
+ });
822
+ }); });
823
+ };
824
+ IndexedDbEntityDataProvider.prototype.delete = function (ids) {
825
+ var _this = this;
826
+ if (ids.length === 0)
827
+ return Promise.resolve();
828
+ return this.provider.enqueue(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
829
+ var _this = this;
830
+ return tslib_1.__generator(this, function (_a) {
831
+ switch (_a.label) {
832
+ case 0: return [4 /*yield*/, this.provider.ensureStores([this.entity])];
833
+ case 1:
834
+ _a.sent();
835
+ return [2 /*return*/, this.provider.withStore(storeNameOf(this.entity), 'readwrite', function (store) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
836
+ var ids_1, ids_1_1, id, key, existing, e_11_1;
837
+ var e_11, _a;
838
+ return tslib_1.__generator(this, function (_b) {
839
+ switch (_b.label) {
840
+ case 0:
841
+ _b.trys.push([0, 6, 7, 8]);
842
+ ids_1 = tslib_1.__values(ids), ids_1_1 = ids_1.next();
843
+ _b.label = 1;
844
+ case 1:
845
+ if (!!ids_1_1.done) return [3 /*break*/, 5];
846
+ id = ids_1_1.value;
847
+ key = toIdbKey(this.entity, id);
848
+ return [4 /*yield*/, idbReq(store.get(key))];
849
+ case 2:
850
+ existing = _b.sent();
851
+ if (existing == null)
852
+ throw new Error("Couldn't find row with id \"".concat(id, "\" in entity \"").concat(this.entity.key, "\" to delete"));
853
+ return [4 /*yield*/, idbReq(store.delete(key))];
854
+ case 3:
855
+ _b.sent();
856
+ _b.label = 4;
857
+ case 4:
858
+ ids_1_1 = ids_1.next();
859
+ return [3 /*break*/, 1];
860
+ case 5: return [3 /*break*/, 8];
861
+ case 6:
862
+ e_11_1 = _b.sent();
863
+ e_11 = { error: e_11_1 };
864
+ return [3 /*break*/, 8];
865
+ case 7:
866
+ try {
867
+ if (ids_1_1 && !ids_1_1.done && (_a = ids_1.return)) _a.call(ids_1);
868
+ }
869
+ finally { if (e_11) throw e_11.error; }
870
+ return [7 /*endfinally*/];
871
+ case 8: return [2 /*return*/];
872
+ }
873
+ });
874
+ }); })];
875
+ }
876
+ });
877
+ }); });
878
+ };
879
+ return IndexedDbEntityDataProvider;
880
+ }());
881
+ function storeNameOf(entity) {
882
+ return entity.dbName;
883
+ }
884
+ //@internal
885
+ function idbPrefetchFromFilter(entity_1, where_1) {
886
+ return tslib_1.__awaiter(this, arguments, void 0, function (entity, where, indexes) {
887
+ var names, c, r, ordered, ordered_1, ordered_1_1, idx, r;
888
+ var e_12, _a;
889
+ if (indexes === void 0) { indexes = []; }
890
+ return tslib_1.__generator(this, function (_b) {
891
+ switch (_b.label) {
892
+ case 0:
893
+ if (!where)
894
+ return [2 /*return*/, { type: 'all' }];
895
+ return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(entity, function (x) { return x; })];
896
+ case 1:
897
+ names = _b.sent();
898
+ if (entity.idMetadata.fields.length === 1) {
899
+ c = new IdbPrefetchCollector(entity.idMetadata.fields[0]);
900
+ where.__applyToConsumer(c);
901
+ r = c.result();
902
+ if (r.type !== 'all')
903
+ return [2 /*return*/, r];
904
+ }
905
+ ordered = tslib_1.__spreadArray([], tslib_1.__read(indexes), false).sort(function (a, b) { return pathLen(b.keyPath) - pathLen(a.keyPath); });
906
+ try {
907
+ for (ordered_1 = tslib_1.__values(ordered), ordered_1_1 = ordered_1.next(); !ordered_1_1.done; ordered_1_1 = ordered_1.next()) {
908
+ idx = ordered_1_1.value;
909
+ r = prefetchForIndex(entity, names, where, idx);
910
+ if (r.type !== 'all')
911
+ return [2 /*return*/, withIndex(r, idx.name)];
912
+ }
913
+ }
914
+ catch (e_12_1) { e_12 = { error: e_12_1 }; }
915
+ finally {
916
+ try {
917
+ if (ordered_1_1 && !ordered_1_1.done && (_a = ordered_1.return)) _a.call(ordered_1);
918
+ }
919
+ finally { if (e_12) throw e_12.error; }
920
+ }
921
+ return [2 /*return*/, { type: 'all' }];
922
+ }
923
+ });
924
+ });
925
+ }
926
+ function prefetchForIndex(entity, names, where, idx) {
927
+ var path = Array.isArray(idx.keyPath) ? idx.keyPath : [idx.keyPath];
928
+ if (path.length === 1) {
929
+ var field = fieldByDbName(entity, names, path[0]);
930
+ if (!field)
931
+ return { type: 'all' };
932
+ var c = new IdbPrefetchCollector(field);
933
+ where.__applyToConsumer(c);
934
+ return c.result();
935
+ }
936
+ var parts = path.map(function (dbName) {
937
+ var field = fieldByDbName(entity, names, dbName);
938
+ if (!field)
939
+ return { type: 'all' };
940
+ var c = new IdbPrefetchCollector(field);
941
+ where.__applyToConsumer(c);
942
+ return c.result();
943
+ });
944
+ if (parts.every(function (p) { return p.type === 'keys'; })) {
945
+ return {
946
+ type: 'keys',
947
+ keys: cartesian(parts.map(function (p) { return p.keys; })),
948
+ };
949
+ }
950
+ var last = parts[parts.length - 1];
951
+ var prefix = parts.slice(0, -1);
952
+ if (last.type === 'range' &&
953
+ prefix.every(function (p) { return p.type === 'keys' && p.keys.length === 1; })) {
954
+ var pre = prefix.map(function (p) { return p.keys[0]; });
955
+ var r = last.range;
956
+ try {
957
+ if (r.lower !== undefined && r.upper !== undefined)
958
+ return {
959
+ type: 'range',
960
+ range: IDBKeyRange.bound(tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(pre), false), [r.lower], false), tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(pre), false), [r.upper], false), r.lowerOpen, r.upperOpen),
961
+ };
962
+ if (r.lower !== undefined)
963
+ return {
964
+ type: 'range',
965
+ range: IDBKeyRange.lowerBound(tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(pre), false), [r.lower], false), r.lowerOpen),
966
+ };
967
+ if (r.upper !== undefined)
968
+ return {
969
+ type: 'range',
970
+ range: IDBKeyRange.upperBound(tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(pre), false), [r.upper], false), r.upperOpen),
971
+ };
972
+ }
973
+ catch (_a) {
974
+ return { type: 'keys', keys: [] };
975
+ }
976
+ }
977
+ return { type: 'all' };
978
+ }
979
+ function withIndex(prefetch, index) {
980
+ if (prefetch.type === 'all')
981
+ return prefetch;
982
+ if (prefetch.type === 'or')
983
+ return { type: 'or', parts: prefetch.parts.map(function (p) { return (tslib_1.__assign(tslib_1.__assign({}, p), { index: index })); }) };
984
+ return tslib_1.__assign(tslib_1.__assign({}, prefetch), { index: index });
985
+ }
986
+ function pathLen(keyPath) {
987
+ return Array.isArray(keyPath) ? keyPath.length : 1;
988
+ }
989
+ function fieldByDbName(entity, names, dbName) {
990
+ var e_13, _a;
991
+ try {
992
+ for (var _b = tslib_1.__values(entity.fields), _c = _b.next(); !_c.done; _c = _b.next()) {
993
+ var f = _c.value;
994
+ if (names.$dbNameOf(f) === dbName)
995
+ return f;
996
+ }
997
+ }
998
+ catch (e_13_1) { e_13 = { error: e_13_1 }; }
999
+ finally {
1000
+ try {
1001
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1002
+ }
1003
+ finally { if (e_13) throw e_13.error; }
1004
+ }
1005
+ }
1006
+ function cartesian(lists) {
1007
+ var e_14, _a;
1008
+ var acc = [[]];
1009
+ var _loop_3 = function (list) {
1010
+ acc = acc.flatMap(function (prefix) { return list.map(function (v) { return tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(prefix), false), [v], false); }); });
1011
+ };
1012
+ try {
1013
+ for (var lists_1 = tslib_1.__values(lists), lists_1_1 = lists_1.next(); !lists_1_1.done; lists_1_1 = lists_1.next()) {
1014
+ var list = lists_1_1.value;
1015
+ _loop_3(list);
1016
+ }
1017
+ }
1018
+ catch (e_14_1) { e_14 = { error: e_14_1 }; }
1019
+ finally {
1020
+ try {
1021
+ if (lists_1_1 && !lists_1_1.done && (_a = lists_1.return)) _a.call(lists_1);
1022
+ }
1023
+ finally { if (e_14) throw e_14.error; }
1024
+ }
1025
+ return acc;
1026
+ }
1027
+ var IdbPrefetchCollector = /** @class */ (function () {
1028
+ function IdbPrefetchCollector(idField) {
1029
+ this.idField = idField;
1030
+ this.cannotNarrow = false;
1031
+ }
1032
+ IdbPrefetchCollector.prototype.result = function () {
1033
+ if (this.cannotNarrow)
1034
+ return { type: 'all' };
1035
+ var andOp = this.andOp();
1036
+ if (this.keys && andOp)
1037
+ return andOp;
1038
+ if (this.orOps)
1039
+ return mergeOps(this.orOps);
1040
+ return andOp !== null && andOp !== void 0 ? andOp : { type: 'all' };
1041
+ };
1042
+ IdbPrefetchCollector.prototype.hasIdConstraint = function () {
1043
+ return this.keys != null || this.hasBounds || this.orOps != null;
1044
+ };
1045
+ Object.defineProperty(IdbPrefetchCollector.prototype, "hasBounds", {
1046
+ get: function () {
1047
+ return this.lower != null || this.upper != null;
1048
+ },
1049
+ enumerable: false,
1050
+ configurable: true
1051
+ });
1052
+ IdbPrefetchCollector.prototype.andOp = function () {
1053
+ if (this.keys) {
1054
+ if (!this.hasBounds)
1055
+ return { type: 'keys', keys: this.keys };
1056
+ try {
1057
+ var range_1 = this.toKeyRange();
1058
+ return {
1059
+ type: 'keys',
1060
+ keys: this.keys.filter(function (k) { return range_1.includes(k); }),
1061
+ };
1062
+ }
1063
+ catch (_a) {
1064
+ return { type: 'keys', keys: [] };
1065
+ }
1066
+ }
1067
+ if (!this.hasBounds)
1068
+ return undefined;
1069
+ try {
1070
+ return { type: 'range', range: this.toKeyRange() };
1071
+ }
1072
+ catch (_b) {
1073
+ return { type: 'keys', keys: [] };
1074
+ }
1075
+ };
1076
+ IdbPrefetchCollector.prototype.toKeyRange = function () {
1077
+ if (this.lower && this.upper)
1078
+ return IDBKeyRange.bound(this.lower.value, this.upper.value, this.lower.open, this.upper.open);
1079
+ if (this.lower)
1080
+ return IDBKeyRange.lowerBound(this.lower.value, this.lower.open);
1081
+ return IDBKeyRange.upperBound(this.upper.value, this.upper.open);
1082
+ };
1083
+ IdbPrefetchCollector.prototype.isId = function (col) {
1084
+ return col.key === this.idField.key;
1085
+ };
1086
+ IdbPrefetchCollector.prototype.toKey = function (col, val) {
1087
+ return col.valueConverter.toJson(val);
1088
+ };
1089
+ IdbPrefetchCollector.prototype.intersectKeys = function (vals) {
1090
+ if (!this.keys)
1091
+ this.keys = tslib_1.__spreadArray([], tslib_1.__read(vals), false);
1092
+ else
1093
+ this.keys = this.keys.filter(function (k) {
1094
+ return vals.some(function (v) { return idbKeysEqual(k, v); });
1095
+ });
1096
+ };
1097
+ IdbPrefetchCollector.prototype.addLower = function (value, open) {
1098
+ if (!this.lower)
1099
+ this.lower = { value: value, open: open };
1100
+ else if (value > this.lower.value)
1101
+ this.lower = { value: value, open: open };
1102
+ else if (value === this.lower.value)
1103
+ this.lower = { value: value, open: this.lower.open || open };
1104
+ };
1105
+ IdbPrefetchCollector.prototype.addUpper = function (value, open) {
1106
+ if (!this.upper)
1107
+ this.upper = { value: value, open: open };
1108
+ else if (value < this.upper.value)
1109
+ this.upper = { value: value, open: open };
1110
+ else if (value === this.upper.value)
1111
+ this.upper = { value: value, open: this.upper.open || open };
1112
+ };
1113
+ IdbPrefetchCollector.prototype.isEqualTo = function (col, val) {
1114
+ if (this.isId(col))
1115
+ this.intersectKeys([this.toKey(col, val)]);
1116
+ };
1117
+ IdbPrefetchCollector.prototype.isIn = function (col, val) {
1118
+ var _this = this;
1119
+ if (this.isId(col))
1120
+ this.intersectKeys(val.map(function (v) { return _this.toKey(col, v); }));
1121
+ };
1122
+ IdbPrefetchCollector.prototype.isGreaterThan = function (col, val) {
1123
+ if (this.isId(col))
1124
+ this.addLower(this.toKey(col, val), true);
1125
+ };
1126
+ IdbPrefetchCollector.prototype.isGreaterOrEqualTo = function (col, val) {
1127
+ if (this.isId(col))
1128
+ this.addLower(this.toKey(col, val), false);
1129
+ };
1130
+ IdbPrefetchCollector.prototype.isLessThan = function (col, val) {
1131
+ if (this.isId(col))
1132
+ this.addUpper(this.toKey(col, val), true);
1133
+ };
1134
+ IdbPrefetchCollector.prototype.isLessOrEqualTo = function (col, val) {
1135
+ if (this.isId(col))
1136
+ this.addUpper(this.toKey(col, val), false);
1137
+ };
1138
+ IdbPrefetchCollector.prototype.or = function (orElements) {
1139
+ var _this = this;
1140
+ var results = orElements.map(function (el) {
1141
+ var c = new IdbPrefetchCollector(_this.idField);
1142
+ el.__applyToConsumer(c);
1143
+ return c.result();
1144
+ });
1145
+ if (results.some(function (r) { return r.type === 'all'; }))
1146
+ return;
1147
+ var ops = results.flatMap(function (r) {
1148
+ return r.type === 'or' ? r.parts : r.type === 'all' ? [] : [r];
1149
+ });
1150
+ this.orOps = this.orOps ? tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(this.orOps), false), tslib_1.__read(ops), false) : ops;
1151
+ };
1152
+ IdbPrefetchCollector.prototype.not = function (filter) {
1153
+ var c = new IdbPrefetchCollector(this.idField);
1154
+ filter.__applyToConsumer(c);
1155
+ if (c.cannotNarrow || c.hasIdConstraint())
1156
+ this.cannotNarrow = true;
1157
+ };
1158
+ IdbPrefetchCollector.prototype.isNull = function (col) {
1159
+ if (this.isId(col))
1160
+ this.cannotNarrow = true;
1161
+ };
1162
+ IdbPrefetchCollector.prototype.isNotNull = function (col) {
1163
+ if (this.isId(col))
1164
+ this.cannotNarrow = true;
1165
+ };
1166
+ IdbPrefetchCollector.prototype.isDifferentFrom = function (_col, _val) { };
1167
+ IdbPrefetchCollector.prototype.containsCaseInsensitive = function (_col, _val) { };
1168
+ IdbPrefetchCollector.prototype.notContainsCaseInsensitive = function (_col, _val) { };
1169
+ IdbPrefetchCollector.prototype.startsWithCaseInsensitive = function (_col, _val) { };
1170
+ IdbPrefetchCollector.prototype.endsWithCaseInsensitive = function (_col, _val) { };
1171
+ IdbPrefetchCollector.prototype.custom = function (_key, _customItem) {
1172
+ this.cannotNarrow = true;
1173
+ };
1174
+ IdbPrefetchCollector.prototype.databaseCustom = function (_databaseCustom) {
1175
+ this.cannotNarrow = true;
1176
+ };
1177
+ return IdbPrefetchCollector;
1178
+ }());
1179
+ function mergeOps(ops) {
1180
+ var e_15, _a;
1181
+ var _b, _c;
1182
+ var keyGroups = new Map();
1183
+ var ranges = [];
1184
+ try {
1185
+ for (var ops_2 = tslib_1.__values(ops), ops_2_1 = ops_2.next(); !ops_2_1.done; ops_2_1 = ops_2.next()) {
1186
+ var op = ops_2_1.value;
1187
+ if (op.type === 'keys') {
1188
+ var k = (_b = op.index) !== null && _b !== void 0 ? _b : '';
1189
+ keyGroups.set(k, tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(((_c = keyGroups.get(k)) !== null && _c !== void 0 ? _c : [])), false), tslib_1.__read(op.keys), false));
1190
+ }
1191
+ else
1192
+ ranges.push(op);
1193
+ }
1194
+ }
1195
+ catch (e_15_1) { e_15 = { error: e_15_1 }; }
1196
+ finally {
1197
+ try {
1198
+ if (ops_2_1 && !ops_2_1.done && (_a = ops_2.return)) _a.call(ops_2);
1199
+ }
1200
+ finally { if (e_15) throw e_15.error; }
1201
+ }
1202
+ var parts = tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(tslib_1.__spreadArray([], tslib_1.__read(keyGroups.entries()), false).map(function (_a) {
1203
+ var _b = tslib_1.__read(_a, 2), index = _b[0], keys = _b[1];
1204
+ return (tslib_1.__assign({ type: 'keys', keys: keys.filter(function (k, i) { return keys.findIndex(function (x) { return idbKeysEqual(x, k); }) === i; }) }, (index ? { index: index } : {})));
1205
+ })), false), tslib_1.__read(ranges), false);
1206
+ if (parts.length === 1)
1207
+ return parts[0];
1208
+ return { type: 'or', parts: parts };
1209
+ }
1210
+ function resolveIndexDefs(entity, defs, storeKeyPath) {
1211
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
1212
+ var names, result, seen, pk, defs_1, defs_1_1, def, keys, keyPath, path, name_3;
1213
+ var e_16, _a;
1214
+ return tslib_1.__generator(this, function (_b) {
1215
+ switch (_b.label) {
1216
+ case 0:
1217
+ if (defs.length === 0)
1218
+ return [2 /*return*/, []];
1219
+ return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(entity, function (x) { return x; })];
1220
+ case 1:
1221
+ names = _b.sent();
1222
+ result = [];
1223
+ seen = new Set();
1224
+ pk = JSON.stringify(storeKeyPath);
1225
+ try {
1226
+ for (defs_1 = tslib_1.__values(defs), defs_1_1 = defs_1.next(); !defs_1_1.done; defs_1_1 = defs_1.next()) {
1227
+ def = defs_1_1.value;
1228
+ keys = Array.isArray(def) ? tslib_1.__spreadArray([], tslib_1.__read(def), false) : [def];
1229
+ keyPath = keys.map(function (key) {
1230
+ var field = tslib_1.__spreadArray([], tslib_1.__read(entity.fields), false).find(function (f) { return f.key === key; });
1231
+ if (!field)
1232
+ throw new Error("IndexedDB index field \"".concat(key, "\" not found on entity \"").concat(entity.key, "\""));
1233
+ return names.$dbNameOf(field);
1234
+ });
1235
+ path = keyPath.length === 1 ? keyPath[0] : keyPath;
1236
+ if (JSON.stringify(path) === pk)
1237
+ continue;
1238
+ name_3 = keyPath.join('_');
1239
+ if (seen.has(name_3))
1240
+ continue;
1241
+ seen.add(name_3);
1242
+ result.push({ name: name_3, keyPath: path });
1243
+ }
1244
+ }
1245
+ catch (e_16_1) { e_16 = { error: e_16_1 }; }
1246
+ finally {
1247
+ try {
1248
+ if (defs_1_1 && !defs_1_1.done && (_a = defs_1.return)) _a.call(defs_1);
1249
+ }
1250
+ finally { if (e_16) throw e_16.error; }
1251
+ }
1252
+ return [2 /*return*/, result];
1253
+ }
1254
+ });
1255
+ });
1256
+ }
1257
+ function keyPathOf(entity) {
1258
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
1259
+ var names, fields;
1260
+ return tslib_1.__generator(this, function (_a) {
1261
+ switch (_a.label) {
1262
+ case 0: return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(entity, function (x) { return x; })];
1263
+ case 1:
1264
+ names = _a.sent();
1265
+ fields = entity.idMetadata.fields;
1266
+ if (fields.length === 1)
1267
+ return [2 /*return*/, names.$dbNameOf(fields[0])];
1268
+ return [2 /*return*/, fields.map(function (f) { return names.$dbNameOf(f); })];
1269
+ }
1270
+ });
1271
+ });
1272
+ }
1273
+ function toIdbKey(entity, id) {
1274
+ var fields = entity.idMetadata.fields;
1275
+ if (fields.length === 1)
1276
+ return fields[0].valueConverter.toJson(id);
1277
+ var values = typeof id === 'object' && id !== null
1278
+ ? id
1279
+ : Object.fromEntries(String(id)
1280
+ .split(',')
1281
+ .map(function (part, i) { return [
1282
+ fields[i].key,
1283
+ fields[i].valueConverter.fromJson(part),
1284
+ ]; }));
1285
+ return fields.map(function (f) { return f.valueConverter.toJson(values[f.key]); });
1286
+ }
1287
+ function keyFromRow(entity, names, row) {
1288
+ var fields = entity.idMetadata.fields;
1289
+ if (fields.length === 1)
1290
+ return row[names.$dbNameOf(fields[0])];
1291
+ return fields.map(function (f) { return row[names.$dbNameOf(f)]; });
1292
+ }
1293
+ function idbKeysEqual(a, b) {
1294
+ return JSON.stringify(a) === JSON.stringify(b);
1295
+ }
1296
+ function idbReq(request) {
1297
+ return new Promise(function (resolve, reject) {
1298
+ request.onsuccess = function () { return resolve(request.result); };
1299
+ request.onerror = function () { return reject(request.error); };
1300
+ });
1301
+ }
1302
+ function encAad(storeName, id) {
1303
+ return new TextEncoder().encode(storeName + '\0' + JSON.stringify(id));
1304
+ }
1305
+ function asBufferSource(value, label) {
1306
+ if (value instanceof Uint8Array || value instanceof ArrayBuffer)
1307
+ return value;
1308
+ throw new Error("Failed to decrypt IndexedDB row: missing ".concat(label));
1309
+ }
1310
+ function encryptJson(storeName, json, plaintext, idbKey, dek) {
1311
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
1312
+ var stored, payload, _a, _b, k, iv, _c, _d;
1313
+ var e_17, _e;
1314
+ return tslib_1.__generator(this, function (_f) {
1315
+ switch (_f.label) {
1316
+ case 0:
1317
+ stored = {};
1318
+ payload = {};
1319
+ try {
1320
+ for (_a = tslib_1.__values(Object.keys(json)), _b = _a.next(); !_b.done; _b = _a.next()) {
1321
+ k = _b.value;
1322
+ if (k === IDB_ENC || k === IDB_IV)
1323
+ continue;
1324
+ if (plaintext.has(k))
1325
+ stored[k] = json[k];
1326
+ else
1327
+ payload[k] = json[k];
1328
+ }
1329
+ }
1330
+ catch (e_17_1) { e_17 = { error: e_17_1 }; }
1331
+ finally {
1332
+ try {
1333
+ if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
1334
+ }
1335
+ finally { if (e_17) throw e_17.error; }
1336
+ }
1337
+ iv = crypto.getRandomValues(new Uint8Array(12));
1338
+ _c = stored;
1339
+ _d = IDB_ENC;
1340
+ return [4 /*yield*/, crypto.subtle.encrypt({
1341
+ name: 'AES-GCM',
1342
+ iv: iv,
1343
+ additionalData: encAad(storeName, idbKey),
1344
+ }, dek, new TextEncoder().encode(JSON.stringify(payload)))];
1345
+ case 1:
1346
+ _c[_d] = _f.sent();
1347
+ stored[IDB_IV] = iv;
1348
+ return [2 /*return*/, stored];
1349
+ }
1350
+ });
1351
+ });
1352
+ }
1353
+ function decryptJson(storeName, row, entity, names, dek) {
1354
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
1355
+ var idbKey, plain, payload, result, e_18;
1356
+ var _a;
1357
+ return tslib_1.__generator(this, function (_b) {
1358
+ switch (_b.label) {
1359
+ case 0:
1360
+ if (row == null || row[IDB_ENC] == null)
1361
+ return [2 /*return*/, row];
1362
+ idbKey = keyFromRow(entity, names, row);
1363
+ _b.label = 1;
1364
+ case 1:
1365
+ _b.trys.push([1, 3, , 4]);
1366
+ return [4 /*yield*/, crypto.subtle.decrypt({
1367
+ name: 'AES-GCM',
1368
+ iv: asBufferSource(row[IDB_IV], IDB_IV),
1369
+ additionalData: encAad(storeName, idbKey),
1370
+ }, dek, asBufferSource(row[IDB_ENC], IDB_ENC))];
1371
+ case 2:
1372
+ plain = _b.sent();
1373
+ payload = JSON.parse(new TextDecoder().decode(plain));
1374
+ result = tslib_1.__assign(tslib_1.__assign({}, row), payload);
1375
+ delete result[IDB_ENC];
1376
+ delete result[IDB_IV];
1377
+ return [2 /*return*/, result];
1378
+ case 3:
1379
+ e_18 = _b.sent();
1380
+ if ((_a = e_18 === null || e_18 === void 0 ? void 0 : e_18.message) === null || _a === void 0 ? void 0 : _a.startsWith('Failed to decrypt IndexedDB row'))
1381
+ throw e_18;
1382
+ throw new Error("Failed to decrypt IndexedDB row in \"".concat(storeName, "\""));
1383
+ case 4: return [2 /*return*/];
1384
+ }
1385
+ });
1386
+ });
1387
+ }