convex-ents 0.2.0 → 0.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/dist/functions.js CHANGED
@@ -23,138 +23,127 @@ __export(functions_exports, {
23
23
  addEntRules: () => addEntRules,
24
24
  entWrapper: () => entWrapper,
25
25
  entsTableFactory: () => entsTableFactory,
26
+ getDeletionConfig: () => getDeletionConfig,
27
+ getEdgeDefinitions: () => getEdgeDefinitions,
26
28
  getReadRule: () => getReadRule,
27
29
  getWriteRule: () => getWriteRule
28
30
  });
29
31
  module.exports = __toCommonJS(functions_exports);
30
32
 
31
33
  // src/writer.ts
34
+ var import_server = require("convex/server");
32
35
  var WriterImplBase = class _WriterImplBase {
33
- constructor(db, entDefinitions, table) {
34
- this.db = db;
36
+ constructor(ctx, entDefinitions, table) {
37
+ this.ctx = ctx;
35
38
  this.entDefinitions = entDefinitions;
36
39
  this.table = table;
37
40
  }
38
- async deleteId(id) {
41
+ async deleteId(id, behavior) {
39
42
  await this.checkReadAndWriteRule("delete", id, void 0);
40
- let memoized = void 0;
41
- const oldDoc = async () => {
42
- if (memoized !== void 0) {
43
- return memoized;
44
- }
45
- return memoized = await this.db.get(id);
46
- };
43
+ const deletionConfig = getDeletionConfig(this.entDefinitions, this.table);
44
+ const isDeletingSoftly = behavior !== "hard" && deletionConfig !== void 0 && (deletionConfig.type === "soft" || deletionConfig.type === "scheduled");
45
+ if (behavior === "soft" && !isDeletingSoftly) {
46
+ throw new Error(
47
+ `Cannot soft delete document with ID "${id}" in table "${this.table}" because it does not have an "allowSoft", "soft" or "scheduled" deletion behavior configured.`
48
+ );
49
+ }
47
50
  const edges = {};
48
51
  await Promise.all(
49
- Object.values(
50
- this.entDefinitions[this.table].edges
51
- ).map(async (edgeDefinition) => {
52
- const key = edgeDefinition.name;
53
- if (edgeDefinition.cardinality === "single") {
54
- if (edgeDefinition.type === "ref") {
55
- edges[key] = {
56
- remove: (await oldDoc())[key]
57
- };
58
- }
59
- } else {
60
- if (edgeDefinition.type === "field") {
61
- const existing = (await this.db.query(edgeDefinition.to).withIndex(
62
- edgeDefinition.ref,
63
- (q) => q.eq(edgeDefinition.ref, id)
64
- ).collect()).map((doc) => doc._id);
65
- edges[key] = { remove: existing };
66
- } else {
67
- const existing = (await this.db.query(edgeDefinition.table).withIndex(
68
- edgeDefinition.field,
69
- (q) => q.eq(edgeDefinition.field, id)
70
- ).collect()).concat(
71
- edgeDefinition.symmetric ? await this.db.query(edgeDefinition.table).withIndex(
52
+ Object.values(getEdgeDefinitions(this.entDefinitions, this.table)).map(
53
+ async (edgeDefinition) => {
54
+ const key = edgeDefinition.name;
55
+ if (edgeDefinition.cardinality === "single" && edgeDefinition.type === "ref" || edgeDefinition.cardinality === "multiple" && edgeDefinition.type === "field") {
56
+ if (!isDeletingSoftly || edgeDefinition.deletion === "soft") {
57
+ const remove = (await this.ctx.db.query(edgeDefinition.to).withIndex(
72
58
  edgeDefinition.ref,
73
59
  (q) => q.eq(edgeDefinition.ref, id)
74
- ).collect() : []
75
- ).map((doc) => doc._id);
76
- edges[key] = { removeEdges: existing };
60
+ ).collect()).map((doc) => doc._id);
61
+ edges[key] = { remove };
62
+ }
63
+ } else if (edgeDefinition.cardinality === "multiple") {
64
+ if (!isDeletingSoftly) {
65
+ const removeEdges = (await this.ctx.db.query(edgeDefinition.table).withIndex(
66
+ edgeDefinition.field,
67
+ (q) => q.eq(edgeDefinition.field, id)
68
+ ).collect()).concat(
69
+ edgeDefinition.symmetric ? await this.ctx.db.query(edgeDefinition.table).withIndex(
70
+ edgeDefinition.ref,
71
+ (q) => q.eq(edgeDefinition.ref, id)
72
+ ).collect() : []
73
+ ).map((doc) => doc._id);
74
+ edges[key] = { removeEdges };
75
+ }
77
76
  }
78
77
  }
79
- })
78
+ )
80
79
  );
81
- await this.db.delete(id);
82
- await this.writeEdges(id, edges);
80
+ const deletionTime = +/* @__PURE__ */ new Date();
81
+ if (isDeletingSoftly) {
82
+ await this.ctx.db.patch(id, { deletionTime });
83
+ } else {
84
+ try {
85
+ await this.ctx.db.delete(id);
86
+ } catch (e) {
87
+ }
88
+ }
89
+ await this.writeEdges(id, edges, isDeletingSoftly);
90
+ if (deletionConfig !== void 0 && deletionConfig.type === "scheduled") {
91
+ const fnRef = this.ctx.scheduledDelete ?? (0, import_server.makeFunctionReference)(
92
+ "functions:scheduledDelete"
93
+ );
94
+ await this.ctx.scheduler.runAfter(deletionConfig.delayMs ?? 0, fnRef, {
95
+ origin: {
96
+ id,
97
+ table: this.table,
98
+ deletionTime
99
+ },
100
+ inProgress: false,
101
+ stack: []
102
+ });
103
+ }
83
104
  return id;
84
105
  }
85
- async deletedIdIn(id, table) {
86
- await new _WriterImplBase(this.db, this.entDefinitions, table).deleteId(id);
106
+ async deletedIdIn(id, table, cascadingSoft) {
107
+ await new _WriterImplBase(this.ctx, this.entDefinitions, table).deleteId(
108
+ id,
109
+ cascadingSoft ? "soft" : "hard"
110
+ );
87
111
  }
88
- async writeEdges(docId, changes) {
112
+ async writeEdges(docId, changes, deleteSoftly) {
89
113
  await Promise.all(
90
- Object.values(
91
- this.entDefinitions[this.table].edges
92
- ).map(async (edgeDefinition) => {
93
- const idOrIds = changes[edgeDefinition.name];
94
- if (idOrIds === void 0) {
95
- return;
96
- }
97
- if (edgeDefinition.cardinality === "single") {
98
- if (edgeDefinition.type === "ref") {
99
- if (idOrIds.remove !== void 0) {
100
- await this.deletedIdIn(
101
- idOrIds.remove,
102
- edgeDefinition.to
103
- );
104
- }
105
- if (idOrIds.add !== void 0) {
106
- await this.db.patch(
107
- idOrIds.add,
108
- { [edgeDefinition.ref]: docId }
109
- );
110
- }
114
+ Object.values(getEdgeDefinitions(this.entDefinitions, this.table)).map(
115
+ async (edgeDefinition) => {
116
+ const idOrIds = changes[edgeDefinition.name];
117
+ if (idOrIds === void 0) {
118
+ return;
111
119
  }
112
- } else {
113
- if (edgeDefinition.type === "field") {
114
- if (idOrIds.remove !== void 0) {
120
+ if (edgeDefinition.cardinality === "single" && edgeDefinition.type === "ref" || edgeDefinition.cardinality === "multiple" && edgeDefinition.type === "field") {
121
+ if (idOrIds.remove !== void 0 && idOrIds.remove.length > 0) {
115
122
  await Promise.all(
116
123
  idOrIds.remove.map(
117
- (id) => this.deletedIdIn(id, edgeDefinition.to)
124
+ (id) => this.deletedIdIn(
125
+ id,
126
+ edgeDefinition.to,
127
+ (deleteSoftly ?? false) && edgeDefinition.deletion === "soft"
128
+ )
118
129
  )
119
130
  );
120
131
  }
121
- if (idOrIds.add !== void 0) {
132
+ if (idOrIds.add !== void 0 && idOrIds.add.length > 0) {
122
133
  await Promise.all(
123
134
  idOrIds.add.map(
124
- async (id) => this.db.patch(id, {
135
+ async (id) => this.ctx.db.patch(id, {
125
136
  [edgeDefinition.ref]: docId
126
137
  })
127
138
  )
128
139
  );
129
140
  }
130
- } else {
131
- let removeEdges = [];
132
- if (idOrIds.remove !== void 0) {
133
- removeEdges = (await Promise.all(
134
- idOrIds.remove.map(
135
- async (id) => (await this.db.query(edgeDefinition.table).withIndex(
136
- edgeDefinition.field,
137
- (q) => q.eq(edgeDefinition.field, docId).eq(
138
- edgeDefinition.ref,
139
- id
140
- )
141
- ).collect()).concat(
142
- edgeDefinition.symmetric ? await this.db.query(edgeDefinition.table).withIndex(
143
- edgeDefinition.ref,
144
- (q) => q.eq(edgeDefinition.ref, docId).eq(edgeDefinition.field, id)
145
- ).collect() : []
146
- )
147
- )
148
- )).map((doc) => doc._id);
149
- }
150
- if (idOrIds.removeEdges !== void 0) {
151
- removeEdges = idOrIds.removeEdges;
152
- }
153
- if (removeEdges.length > 0) {
141
+ } else if (edgeDefinition.cardinality === "multiple") {
142
+ if ((idOrIds.removeEdges ?? []).length > 0) {
154
143
  await Promise.all(
155
- removeEdges.map(async (id) => {
144
+ idOrIds.removeEdges.map(async (id) => {
156
145
  try {
157
- await this.db.delete(id);
146
+ await this.ctx.db.delete(id);
158
147
  } catch (e) {
159
148
  }
160
149
  })
@@ -163,12 +152,12 @@ var WriterImplBase = class _WriterImplBase {
163
152
  if (idOrIds.add !== void 0) {
164
153
  await Promise.all(
165
154
  idOrIds.add.map(async (id) => {
166
- await this.db.insert(edgeDefinition.table, {
155
+ await this.ctx.db.insert(edgeDefinition.table, {
167
156
  [edgeDefinition.field]: docId,
168
157
  [edgeDefinition.ref]: id
169
158
  });
170
159
  if (edgeDefinition.symmetric) {
171
- await this.db.insert(edgeDefinition.table, {
160
+ await this.ctx.db.insert(edgeDefinition.table, {
172
161
  [edgeDefinition.field]: id,
173
162
  [edgeDefinition.ref]: docId
174
163
  });
@@ -178,7 +167,7 @@ var WriterImplBase = class _WriterImplBase {
178
167
  }
179
168
  }
180
169
  }
181
- })
170
+ )
182
171
  );
183
172
  }
184
173
  async checkUniqueness(value, id) {
@@ -189,7 +178,7 @@ var WriterImplBase = class _WriterImplBase {
189
178
  if (fieldDefinition.unique) {
190
179
  const key = fieldDefinition.name;
191
180
  const fieldValue = value[key];
192
- const existing = await this.db.query(this.table).withIndex(key, (q) => q.eq(key, value[key])).unique();
181
+ const existing = await this.ctx.db.query(this.table).withIndex(key, (q) => q.eq(key, value[key])).unique();
193
182
  if (existing !== null && (id === void 0 || existing._id !== id)) {
194
183
  throw new Error(
195
184
  `In table "${this.table}" cannot create a duplicate document with field "${key}" of value \`${fieldValue}\`, existing document with ID "${existing._id}" already has it.`
@@ -199,28 +188,31 @@ var WriterImplBase = class _WriterImplBase {
199
188
  })
200
189
  );
201
190
  await Promise.all(
202
- Object.values(
203
- this.entDefinitions[this.table].edges
204
- ).map(async (edgeDefinition) => {
205
- if (edgeDefinition.cardinality === "single" && edgeDefinition.type === "field" && edgeDefinition.unique) {
206
- const key = edgeDefinition.field;
207
- if (value[key] === void 0) {
208
- return;
209
- }
210
- const existing = await this.db.query(this.table).withIndex(key, (q) => q.eq(key, value[key])).unique();
211
- if (existing !== null && (id === void 0 || existing._id !== id)) {
212
- throw new Error(
213
- `In table "${this.table}" cannot create a duplicate 1:1 edge "${edgeDefinition.name}" to ID "${value[key]}", existing document with ID "${existing._id}" already has it.`
214
- );
191
+ Object.values(getEdgeDefinitions(this.entDefinitions, this.table)).map(
192
+ async (edgeDefinition) => {
193
+ if (edgeDefinition.cardinality === "single" && edgeDefinition.type === "field" && edgeDefinition.unique) {
194
+ const key = edgeDefinition.field;
195
+ if (value[key] === void 0) {
196
+ return;
197
+ }
198
+ const existing = await this.ctx.db.query(this.table).withIndex(key, (q) => q.eq(key, value[key])).unique();
199
+ if (existing !== null && (id === void 0 || existing._id !== id)) {
200
+ throw new Error(
201
+ `In table "${this.table}" cannot create a duplicate 1:1 edge "${edgeDefinition.name}" to ID "${value[key]}", existing document with ID "${existing._id}" already has it.`
202
+ );
203
+ }
215
204
  }
216
205
  }
217
- })
206
+ )
218
207
  );
219
208
  }
220
209
  fieldsOnly(value) {
221
210
  const fields = {};
222
211
  Object.keys(value).forEach((key) => {
223
- const edgeDefinition = this.entDefinitions[this.table].edges[key];
212
+ const edgeDefinition = getEdgeDefinitions(
213
+ this.entDefinitions,
214
+ this.table
215
+ )[key];
224
216
  if (edgeDefinition === void 0) {
225
217
  fields[key] = value[key];
226
218
  }
@@ -231,7 +223,7 @@ var WriterImplBase = class _WriterImplBase {
231
223
  if (id !== void 0) {
232
224
  const readPolicy = getReadRule(this.entDefinitions, this.table);
233
225
  if (readPolicy !== void 0) {
234
- const doc = await this.db.get(id);
226
+ const doc = await this.ctx.db.get(id);
235
227
  if (doc === null) {
236
228
  throw new Error(
237
229
  `Cannot update document with ID "${id}" in table "${this.table} because it does not exist"`
@@ -250,8 +242,8 @@ var WriterImplBase = class _WriterImplBase {
250
242
  return;
251
243
  }
252
244
  const ent = id === void 0 ? void 0 : entWrapper(
253
- await this.db.get(id),
254
- this.db,
245
+ await this.ctx.db.get(id),
246
+ this.ctx,
255
247
  this.entDefinitions,
256
248
  this.table
257
249
  );
@@ -283,17 +275,17 @@ var WriterImplBase = class _WriterImplBase {
283
275
 
284
276
  // src/functions.ts
285
277
  var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
286
- constructor(db, entDefinitions, table, retrieve) {
278
+ constructor(ctx, entDefinitions, table, retrieve) {
287
279
  super(() => {
288
280
  });
289
- this.db = db;
281
+ this.ctx = ctx;
290
282
  this.entDefinitions = entDefinitions;
291
283
  this.table = table;
292
284
  this.retrieve = retrieve;
293
285
  }
294
286
  filter(predicate) {
295
287
  return new _PromiseQueryOrNullImpl(
296
- this.db,
288
+ this.ctx,
297
289
  this.entDefinitions,
298
290
  this.table,
299
291
  async () => {
@@ -305,16 +297,18 @@ var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
305
297
  }
306
298
  );
307
299
  }
308
- async map(callbackFn) {
309
- const array = await this;
310
- if (array === null) {
311
- return [];
312
- }
313
- return await Promise.all(array.map(callbackFn));
300
+ map(callbackFn) {
301
+ return new PromiseArrayImpl(async () => {
302
+ const array = await this;
303
+ if (array === null) {
304
+ return null;
305
+ }
306
+ return await Promise.all(array.map(callbackFn));
307
+ });
314
308
  }
315
309
  order(order, indexName) {
316
310
  return new _PromiseQueryOrNullImpl(
317
- this.db,
311
+ this.ctx,
318
312
  this.entDefinitions,
319
313
  this.table,
320
314
  async () => {
@@ -331,7 +325,7 @@ var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
331
325
  }
332
326
  paginate(paginationOpts) {
333
327
  return new PromisePaginationResultOrNullImpl(
334
- this.db,
328
+ this.ctx,
335
329
  this.entDefinitions,
336
330
  this.table,
337
331
  this.retrieve,
@@ -340,7 +334,7 @@ var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
340
334
  }
341
335
  take(n) {
342
336
  return new PromiseEntsOrNullImpl(
343
- this.db,
337
+ this.ctx,
344
338
  this.entDefinitions,
345
339
  this.table,
346
340
  async () => {
@@ -351,7 +345,7 @@ var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
351
345
  }
352
346
  first() {
353
347
  return new PromiseEntOrNullImpl(
354
- this.db,
348
+ this.ctx,
355
349
  this.entDefinitions,
356
350
  this.table,
357
351
  async () => {
@@ -367,7 +361,7 @@ var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
367
361
  }
368
362
  firstX() {
369
363
  return new PromiseEntWriterImpl(
370
- this.db,
364
+ this.ctx,
371
365
  this.entDefinitions,
372
366
  this.table,
373
367
  async () => {
@@ -386,7 +380,7 @@ var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
386
380
  }
387
381
  unique() {
388
382
  return new PromiseEntOrNullImpl(
389
- this.db,
383
+ this.ctx,
390
384
  this.entDefinitions,
391
385
  this.table,
392
386
  async () => {
@@ -408,7 +402,7 @@ var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
408
402
  }
409
403
  uniqueX() {
410
404
  return new PromiseEntWriterImpl(
411
- this.db,
405
+ this.ctx,
412
406
  this.entDefinitions,
413
407
  this.table,
414
408
  async () => {
@@ -435,7 +429,7 @@ var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
435
429
  }
436
430
  const docs = await query.collect();
437
431
  return filterByReadRule(
438
- this.db,
432
+ this.ctx,
439
433
  this.entDefinitions,
440
434
  this.table,
441
435
  docs,
@@ -445,7 +439,7 @@ var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
445
439
  then(onfulfilled, onrejected) {
446
440
  return this.docs().then(
447
441
  (documents) => documents === null ? null : documents.map(
448
- (doc) => entWrapper(doc, this.db, this.entDefinitions, this.table)
442
+ (doc) => entWrapper(doc, this.ctx, this.entDefinitions, this.table)
449
443
  )
450
444
  ).then(onfulfilled, onrejected);
451
445
  }
@@ -474,7 +468,7 @@ var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
474
468
  }
475
469
  docs.push(
476
470
  ...(await filterByReadRule(
477
- this.db,
471
+ this.ctx,
478
472
  this.entDefinitions,
479
473
  this.table,
480
474
  page,
@@ -487,10 +481,10 @@ var PromiseQueryOrNullImpl = class _PromiseQueryOrNullImpl extends Promise {
487
481
  }
488
482
  };
489
483
  var PromisePaginationResultOrNullImpl = class extends Promise {
490
- constructor(db, entDefinitions, table, retrieve, paginationOpts) {
484
+ constructor(ctx, entDefinitions, table, retrieve, paginationOpts) {
491
485
  super(() => {
492
486
  });
493
- this.db = db;
487
+ this.ctx = ctx;
494
488
  this.entDefinitions = entDefinitions;
495
489
  this.table = table;
496
490
  this.retrieve = retrieve;
@@ -515,7 +509,7 @@ var PromisePaginationResultOrNullImpl = class extends Promise {
515
509
  return {
516
510
  ...result,
517
511
  page: await filterByReadRule(
518
- this.db,
512
+ this.ctx,
519
513
  this.entDefinitions,
520
514
  this.table,
521
515
  result.page,
@@ -528,15 +522,15 @@ var PromisePaginationResultOrNullImpl = class extends Promise {
528
522
  (result) => result === null ? null : {
529
523
  ...result,
530
524
  page: result.page.map(
531
- (doc) => entWrapper(doc, this.db, this.entDefinitions, this.table)
525
+ (doc) => entWrapper(doc, this.ctx, this.entDefinitions, this.table)
532
526
  )
533
527
  }
534
528
  ).then(onfulfilled, onrejected);
535
529
  }
536
530
  };
537
531
  var PromiseTableImpl = class extends PromiseQueryOrNullImpl {
538
- constructor(db, entDefinitions, table) {
539
- super(db, entDefinitions, table, async () => db.query(table));
532
+ constructor(ctx, entDefinitions, table) {
533
+ super(ctx, entDefinitions, table, async () => ctx.db.query(table));
540
534
  }
541
535
  get(...args) {
542
536
  return this.getImpl(args);
@@ -552,18 +546,18 @@ var PromiseTableImpl = class extends PromiseQueryOrNullImpl {
552
546
  }
553
547
  getImpl(args, throwIfNull = false) {
554
548
  return new PromiseEntWriterImpl(
555
- this.db,
549
+ this.ctx,
556
550
  this.entDefinitions,
557
551
  this.table,
558
552
  args.length === 1 ? async () => {
559
553
  const id = args[0];
560
- if (this.db.normalizeId(this.table, id) === null) {
554
+ if (this.ctx.db.normalizeId(this.table, id) === null) {
561
555
  throw new Error(`Invalid id \`${id}\` for table "${this.table}"`);
562
556
  }
563
557
  return {
564
558
  id,
565
559
  doc: async () => {
566
- const doc = await this.db.get(id);
560
+ const doc = await this.ctx.db.get(id);
567
561
  if (throwIfNull && doc === null) {
568
562
  throw new Error(
569
563
  `Document not found with id \`${id}\` in table "${this.table}"`
@@ -574,7 +568,7 @@ var PromiseTableImpl = class extends PromiseQueryOrNullImpl {
574
568
  };
575
569
  } : async () => {
576
570
  const [indexName, value] = args;
577
- const doc = await this.db.query(this.table).withIndex(indexName, (q) => q.eq(indexName, value)).unique();
571
+ const doc = await this.ctx.db.query(this.table).withIndex(indexName, (q) => q.eq(indexName, value)).unique();
578
572
  if (throwIfNull && doc === null) {
579
573
  throw new Error(
580
574
  `Table "${this.table}" does not contain document with field "${indexName}" = \`${value}\``
@@ -587,13 +581,13 @@ var PromiseTableImpl = class extends PromiseQueryOrNullImpl {
587
581
  }
588
582
  getManyImpl(args, throwIfNull = false) {
589
583
  return new PromiseEntsOrNullImpl(
590
- this.db,
584
+ this.ctx,
591
585
  this.entDefinitions,
592
586
  this.table,
593
587
  args.length === 1 ? async () => {
594
588
  const ids = args[0];
595
589
  ids.forEach((id) => {
596
- if (this.db.normalizeId(this.table, id) === null) {
590
+ if (this.ctx.db.normalizeId(this.table, id) === null) {
597
591
  throw new Error(
598
592
  `Invalid id \`${id}\` for table "${this.table}"`
599
593
  );
@@ -601,7 +595,7 @@ var PromiseTableImpl = class extends PromiseQueryOrNullImpl {
601
595
  });
602
596
  return await Promise.all(
603
597
  ids.map(async (id) => {
604
- const doc = await this.db.get(id);
598
+ const doc = await this.ctx.db.get(id);
605
599
  if (doc === null) {
606
600
  throw new Error(
607
601
  `Document not found with id \`${id}\` in table "${this.table}"`
@@ -614,7 +608,7 @@ var PromiseTableImpl = class extends PromiseQueryOrNullImpl {
614
608
  const [indexName, values] = args;
615
609
  return await Promise.all(
616
610
  values.map(async (value) => {
617
- const doc = await this.db.query(this.table).withIndex(indexName, (q) => q.eq(indexName, value)).unique();
611
+ const doc = await this.ctx.db.query(this.table).withIndex(indexName, (q) => q.eq(indexName, value)).unique();
618
612
  if (throwIfNull && doc === null) {
619
613
  throw new Error(
620
614
  `Table "${this.table}" does not contain document with field "${indexName}" = \`${value}\``
@@ -628,7 +622,7 @@ var PromiseTableImpl = class extends PromiseQueryOrNullImpl {
628
622
  );
629
623
  }
630
624
  normalizeId(id) {
631
- return this.db.normalizeId(this.table, id);
625
+ return this.ctx.db.normalizeId(this.table, id);
632
626
  }
633
627
  // normalizeId or throw
634
628
  normalizeIdX(id) {
@@ -640,7 +634,7 @@ var PromiseTableImpl = class extends PromiseQueryOrNullImpl {
640
634
  }
641
635
  withIndex(indexName, indexRange) {
642
636
  return new PromiseQueryOrNullImpl(
643
- this.db,
637
+ this.ctx,
644
638
  this.entDefinitions,
645
639
  this.table,
646
640
  async () => {
@@ -651,7 +645,7 @@ var PromiseTableImpl = class extends PromiseQueryOrNullImpl {
651
645
  }
652
646
  search(indexName, searchFilter) {
653
647
  return new PromiseQueryOrNullImpl(
654
- this.db,
648
+ this.ctx,
655
649
  this.entDefinitions,
656
650
  this.table,
657
651
  async () => {
@@ -662,25 +656,27 @@ var PromiseTableImpl = class extends PromiseQueryOrNullImpl {
662
656
  }
663
657
  };
664
658
  var PromiseEntsOrNullImpl = class extends Promise {
665
- constructor(db, entDefinitions, table, retrieve, throwIfNull) {
659
+ constructor(ctx, entDefinitions, table, retrieve, throwIfNull) {
666
660
  super(() => {
667
661
  });
668
- this.db = db;
662
+ this.ctx = ctx;
669
663
  this.entDefinitions = entDefinitions;
670
664
  this.table = table;
671
665
  this.retrieve = retrieve;
672
666
  this.throwIfNull = throwIfNull;
673
667
  }
674
- async map(callbackFn) {
675
- const array = await this;
676
- if (array === null) {
677
- return [];
678
- }
679
- return await Promise.all(array.map(callbackFn));
668
+ map(callbackFn) {
669
+ return new PromiseArrayImpl(async () => {
670
+ const array = await this;
671
+ if (array === null) {
672
+ return null;
673
+ }
674
+ return await Promise.all(array.map(callbackFn));
675
+ });
680
676
  }
681
677
  first() {
682
678
  return new PromiseEntOrNullImpl(
683
- this.db,
679
+ this.ctx,
684
680
  this.entDefinitions,
685
681
  this.table,
686
682
  async () => {
@@ -695,7 +691,7 @@ var PromiseEntsOrNullImpl = class extends Promise {
695
691
  }
696
692
  firstX() {
697
693
  return new PromiseEntOrNullImpl(
698
- this.db,
694
+ this.ctx,
699
695
  this.entDefinitions,
700
696
  this.table,
701
697
  async () => {
@@ -714,7 +710,7 @@ var PromiseEntsOrNullImpl = class extends Promise {
714
710
  }
715
711
  unique() {
716
712
  return new PromiseEntOrNullImpl(
717
- this.db,
713
+ this.ctx,
718
714
  this.entDefinitions,
719
715
  this.table,
720
716
  async () => {
@@ -732,7 +728,7 @@ var PromiseEntsOrNullImpl = class extends Promise {
732
728
  }
733
729
  uniqueX() {
734
730
  return new PromiseEntOrNullImpl(
735
- this.db,
731
+ this.ctx,
736
732
  this.entDefinitions,
737
733
  this.table,
738
734
  async () => {
@@ -754,7 +750,7 @@ var PromiseEntsOrNullImpl = class extends Promise {
754
750
  async docs() {
755
751
  const docs = await this.retrieve();
756
752
  return filterByReadRule(
757
- this.db,
753
+ this.ctx,
758
754
  this.entDefinitions,
759
755
  this.table,
760
756
  docs,
@@ -764,14 +760,14 @@ var PromiseEntsOrNullImpl = class extends Promise {
764
760
  then(onfulfilled, onrejected) {
765
761
  return this.docs().then(
766
762
  (docs) => docs === null ? null : docs.map(
767
- (doc) => entWrapper(doc, this.db, this.entDefinitions, this.table)
763
+ (doc) => entWrapper(doc, this.ctx, this.entDefinitions, this.table)
768
764
  )
769
765
  ).then(onfulfilled, onrejected);
770
766
  }
771
767
  };
772
768
  var PromiseEdgeOrNullImpl = class extends PromiseEntsOrNullImpl {
773
- constructor(db, entDefinitions, table, field, retrieveRange) {
774
- super(db, entDefinitions, table, () => retrieveRange((q) => q), false);
769
+ constructor(ctx, entDefinitions, table, field, retrieveRange) {
770
+ super(ctx, entDefinitions, table, () => retrieveRange((q) => q), false);
775
771
  this.field = field;
776
772
  this.retrieveRange = retrieveRange;
777
773
  }
@@ -781,10 +777,10 @@ var PromiseEdgeOrNullImpl = class extends PromiseEntsOrNullImpl {
781
777
  }
782
778
  };
783
779
  var PromiseEntOrNullImpl = class _PromiseEntOrNullImpl extends Promise {
784
- constructor(db, entDefinitions, table, retrieve, throwIfNull) {
780
+ constructor(ctx, entDefinitions, table, retrieve, throwIfNull) {
785
781
  super(() => {
786
782
  });
787
- this.db = db;
783
+ this.ctx = ctx;
788
784
  this.entDefinitions = entDefinitions;
789
785
  this.table = table;
790
786
  this.retrieve = retrieve;
@@ -802,7 +798,7 @@ var PromiseEntOrNullImpl = class _PromiseEntOrNullImpl extends Promise {
802
798
  const readPolicy = getReadRule(this.entDefinitions, this.table);
803
799
  if (readPolicy !== void 0) {
804
800
  const decision = await readPolicy(
805
- entWrapper(doc, this.db, this.entDefinitions, this.table)
801
+ entWrapper(doc, this.ctx, this.entDefinitions, this.table)
806
802
  );
807
803
  if (this.throwIfNull && !decision) {
808
804
  throw new Error(
@@ -815,7 +811,7 @@ var PromiseEntOrNullImpl = class _PromiseEntOrNullImpl extends Promise {
815
811
  }
816
812
  then(onfulfilled, onrejected) {
817
813
  return this.doc().then(
818
- (doc) => doc === null ? null : entWrapper(doc, this.db, this.entDefinitions, this.table)
814
+ (doc) => doc === null ? null : entWrapper(doc, this.ctx, this.entDefinitions, this.table)
819
815
  ).then(onfulfilled, onrejected);
820
816
  }
821
817
  edge(edge) {
@@ -825,11 +821,11 @@ var PromiseEntOrNullImpl = class _PromiseEntOrNullImpl extends Promise {
825
821
  return this.edgeImpl(edge, true);
826
822
  }
827
823
  edgeImpl(edge, throwIfNull = false) {
828
- const edgeDefinition = this.entDefinitions[this.table].edges[edge];
824
+ const edgeDefinition = getEdgeDefinitions(this.entDefinitions, this.table)[edge];
829
825
  if (edgeDefinition.cardinality === "multiple") {
830
826
  if (edgeDefinition.type === "ref") {
831
827
  return new PromiseEdgeOrNullImpl(
832
- this.db,
828
+ this.ctx,
833
829
  this.entDefinitions,
834
830
  edgeDefinition.to,
835
831
  edgeDefinition.ref,
@@ -838,13 +834,13 @@ var PromiseEntOrNullImpl = class _PromiseEntOrNullImpl extends Promise {
838
834
  if (id === null) {
839
835
  return null;
840
836
  }
841
- const edgeDocs = await this.db.query(edgeDefinition.table).withIndex(
837
+ const edgeDocs = await this.ctx.db.query(edgeDefinition.table).withIndex(
842
838
  edgeDefinition.field,
843
839
  (q) => indexRange(q.eq(edgeDefinition.field, id))
844
840
  ).collect();
845
841
  return (await Promise.all(
846
842
  edgeDocs.map(
847
- (edgeDoc) => this.db.get(edgeDoc[edgeDefinition.ref])
843
+ (edgeDoc) => this.ctx.db.get(edgeDoc[edgeDefinition.ref])
848
844
  )
849
845
  )).filter((doc, i) => {
850
846
  if (doc === null) {
@@ -858,7 +854,7 @@ var PromiseEntOrNullImpl = class _PromiseEntOrNullImpl extends Promise {
858
854
  );
859
855
  }
860
856
  return new PromiseQueryOrNullImpl(
861
- this.db,
857
+ this.ctx,
862
858
  this.entDefinitions,
863
859
  edgeDefinition.to,
864
860
  async () => {
@@ -866,7 +862,7 @@ var PromiseEntOrNullImpl = class _PromiseEntOrNullImpl extends Promise {
866
862
  if (id === null) {
867
863
  return null;
868
864
  }
869
- return this.db.query(edgeDefinition.to).withIndex(
865
+ return this.ctx.db.query(edgeDefinition.to).withIndex(
870
866
  edgeDefinition.ref,
871
867
  (q) => q.eq(edgeDefinition.ref, id)
872
868
  );
@@ -874,7 +870,7 @@ var PromiseEntOrNullImpl = class _PromiseEntOrNullImpl extends Promise {
874
870
  );
875
871
  }
876
872
  return new _PromiseEntOrNullImpl(
877
- this.db,
873
+ this.ctx,
878
874
  this.entDefinitions,
879
875
  edgeDefinition.to,
880
876
  async () => {
@@ -883,7 +879,7 @@ var PromiseEntOrNullImpl = class _PromiseEntOrNullImpl extends Promise {
883
879
  return nullRetriever;
884
880
  }
885
881
  if (edgeDefinition.type === "ref") {
886
- const otherDoc = await this.db.query(edgeDefinition.to).withIndex(
882
+ const otherDoc = await this.ctx.db.query(edgeDefinition.to).withIndex(
887
883
  edgeDefinition.ref,
888
884
  (q) => q.eq(edgeDefinition.ref, id)
889
885
  ).unique();
@@ -899,7 +895,7 @@ var PromiseEntOrNullImpl = class _PromiseEntOrNullImpl extends Promise {
899
895
  return {
900
896
  id: otherId,
901
897
  doc: async () => {
902
- const otherDoc = await this.db.get(otherId);
898
+ const otherDoc = await this.ctx.db.get(otherId);
903
899
  if (otherDoc === null) {
904
900
  throw new Error(
905
901
  `Dangling reference for edge "${edgeDefinition.name}" in table "${this.table}" for document with ID "${id}": Could not find a document with ID "${otherId}" in table "${edgeDefinition.to}".`
@@ -913,10 +909,27 @@ var PromiseEntOrNullImpl = class _PromiseEntOrNullImpl extends Promise {
913
909
  );
914
910
  }
915
911
  };
916
- function entWrapper(fields, db, entDefinitions, table) {
912
+ var PromiseArrayImpl = class extends Promise {
913
+ constructor(retrieve) {
914
+ super(() => {
915
+ });
916
+ this.retrieve = retrieve;
917
+ }
918
+ async filter(predicate) {
919
+ const array = await this.retrieve();
920
+ if (array === null) {
921
+ return null;
922
+ }
923
+ return array.filter(predicate);
924
+ }
925
+ then(onfulfilled, onrejected) {
926
+ return this.retrieve().then(onfulfilled, onrejected);
927
+ }
928
+ };
929
+ function entWrapper(fields, ctx, entDefinitions, table) {
917
930
  const doc = { ...fields };
918
931
  const queryInterface = new PromiseEntWriterImpl(
919
- db,
932
+ ctx,
920
933
  entDefinitions,
921
934
  table,
922
935
  async () => ({ id: doc._id, doc: async () => doc }),
@@ -939,6 +952,14 @@ function entWrapper(fields, db, entDefinitions, table) {
939
952
  writable: false,
940
953
  configurable: false
941
954
  });
955
+ Object.defineProperty(doc, "doc", {
956
+ value: () => {
957
+ return doc;
958
+ },
959
+ enumerable: false,
960
+ writable: false,
961
+ configurable: false
962
+ });
942
963
  Object.defineProperty(doc, "patch", {
943
964
  value: (value) => {
944
965
  return queryInterface.patch(value);
@@ -972,54 +993,58 @@ function entWrapper(fields, db, entDefinitions, table) {
972
993
  );
973
994
  return doc;
974
995
  }
975
- function entsTableFactory(db, entDefinitions) {
996
+ function entsTableFactory(ctx, entDefinitions, options) {
997
+ const enrichedCtx = options !== void 0 ? { ...ctx, ...options } : ctx;
976
998
  return (table, indexName, indexRange) => {
977
999
  if (typeof table !== "string") {
978
1000
  throw new Error(`Expected table name, got \`${table}\``);
979
1001
  }
980
1002
  if (indexName !== void 0) {
981
- return new PromiseTableImpl(db, entDefinitions, table).withIndex(
982
- indexName,
983
- indexRange
984
- );
1003
+ return new PromiseTableImpl(
1004
+ enrichedCtx,
1005
+ entDefinitions,
1006
+ table
1007
+ ).withIndex(indexName, indexRange);
985
1008
  }
986
- if (db.insert !== void 0) {
1009
+ if (ctx.db.insert !== void 0) {
987
1010
  return new PromiseTableWriterImpl(
988
- db,
1011
+ enrichedCtx,
989
1012
  entDefinitions,
990
1013
  table
991
1014
  );
992
1015
  }
993
- return new PromiseTableImpl(db, entDefinitions, table);
1016
+ return new PromiseTableImpl(enrichedCtx, entDefinitions, table);
994
1017
  };
995
1018
  }
996
1019
  var PromiseTableWriterImpl = class extends PromiseTableImpl {
997
- constructor(db, entDefinitions, table) {
998
- super(db, entDefinitions, table);
999
- this.db = db;
1000
- this.base = new WriterImplBase(db, entDefinitions, table);
1020
+ constructor(ctx, entDefinitions, table) {
1021
+ super(ctx, entDefinitions, table);
1022
+ this.ctx = ctx;
1023
+ this.base = new WriterImplBase(ctx, entDefinitions, table);
1001
1024
  }
1002
1025
  base;
1003
1026
  insert(value) {
1004
1027
  return new PromiseEntIdImpl(
1005
- this.db,
1028
+ this.ctx,
1006
1029
  this.entDefinitions,
1007
1030
  this.table,
1008
1031
  async () => {
1009
1032
  await this.base.checkReadAndWriteRule("create", void 0, value);
1010
1033
  await this.base.checkUniqueness(value);
1011
1034
  const fields = this.base.fieldsOnly(value);
1012
- const docId = await this.db.insert(this.table, fields);
1035
+ const docId = await this.ctx.db.insert(this.table, fields);
1013
1036
  const edges = {};
1014
1037
  Object.keys(value).forEach((key) => {
1015
- const edgeDefinition = this.entDefinitions[this.table].edges[key];
1038
+ const edgeDefinition = getEdgeDefinitions(
1039
+ this.entDefinitions,
1040
+ this.table
1041
+ )[key];
1016
1042
  if (edgeDefinition === void 0 || edgeDefinition.cardinality === "single" && edgeDefinition.type === "field") {
1017
1043
  return;
1018
1044
  }
1019
- if (edgeDefinition.cardinality === "single") {
1020
- throw new Error("Cannot set 1:1 edge from optional end.");
1021
- }
1022
- edges[key] = { add: value[key] };
1045
+ edges[key] = {
1046
+ add: edgeDefinition.cardinality === "single" ? [value[key]] : value[key]
1047
+ };
1023
1048
  });
1024
1049
  await this.base.writeEdges(docId, edges);
1025
1050
  return docId;
@@ -1032,19 +1057,19 @@ var PromiseTableWriterImpl = class extends PromiseTableImpl {
1032
1057
  }
1033
1058
  };
1034
1059
  var PromiseEntWriterImpl = class extends PromiseEntOrNullImpl {
1035
- constructor(db, entDefinitions, table, retrieve, throwIfNull) {
1036
- super(db, entDefinitions, table, retrieve, throwIfNull);
1037
- this.db = db;
1060
+ constructor(ctx, entDefinitions, table, retrieve, throwIfNull) {
1061
+ super(ctx, entDefinitions, table, retrieve, throwIfNull);
1062
+ this.ctx = ctx;
1038
1063
  this.entDefinitions = entDefinitions;
1039
1064
  this.table = table;
1040
1065
  this.retrieve = retrieve;
1041
1066
  this.throwIfNull = throwIfNull;
1042
- this.base = new WriterImplBase(db, entDefinitions, table);
1067
+ this.base = new WriterImplBase(ctx, entDefinitions, table);
1043
1068
  }
1044
1069
  base;
1045
1070
  patch(value) {
1046
1071
  return new PromiseEntIdImpl(
1047
- this.db,
1072
+ this.ctx,
1048
1073
  this.entDefinitions,
1049
1074
  this.table,
1050
1075
  async () => {
@@ -1053,18 +1078,52 @@ var PromiseEntWriterImpl = class extends PromiseEntOrNullImpl {
1053
1078
  await this.base.checkReadAndWriteRule("update", id, value);
1054
1079
  await this.base.checkUniqueness(value, id);
1055
1080
  const fields = this.base.fieldsOnly(value);
1056
- await this.db.patch(id, fields);
1081
+ await this.ctx.db.patch(id, fields);
1057
1082
  const edges = {};
1058
1083
  await Promise.all(
1059
1084
  Object.keys(value).map(async (key) => {
1060
- const edgeDefinition = this.entDefinitions[this.table].edges[key];
1085
+ const edgeDefinition = getEdgeDefinitions(
1086
+ this.entDefinitions,
1087
+ this.table
1088
+ )[key];
1061
1089
  if (edgeDefinition === void 0 || edgeDefinition.cardinality === "single" && edgeDefinition.type === "field") {
1062
1090
  return;
1063
1091
  }
1064
1092
  if (edgeDefinition.cardinality === "single") {
1065
- throw new Error("Cannot set 1:1 edge from optional end.");
1093
+ throw new Error(
1094
+ `Cannot set 1:1 edge "${edgeDefinition.name}" on ent in table "${this.table}", update the ent in "${edgeDefinition.to}" table instead.`
1095
+ );
1066
1096
  } else {
1067
- edges[key] = value[key];
1097
+ if (edgeDefinition.type === "field") {
1098
+ throw new Error(
1099
+ `Cannot set 1:many edges "${edgeDefinition.name}" on ent in table "${this.table}", update the ents in "${edgeDefinition.to}" table instead.`
1100
+ );
1101
+ } else {
1102
+ const { add, remove } = value[key];
1103
+ const removeEdges = (await Promise.all(
1104
+ (remove ?? []).map(
1105
+ async (edgeId) => (await this.ctx.db.query(edgeDefinition.table).withIndex(
1106
+ edgeDefinition.field,
1107
+ (q) => q.eq(edgeDefinition.field, id).eq(
1108
+ edgeDefinition.ref,
1109
+ edgeId
1110
+ )
1111
+ ).collect()).concat(
1112
+ edgeDefinition.symmetric ? await this.ctx.db.query(edgeDefinition.table).withIndex(
1113
+ edgeDefinition.ref,
1114
+ (q) => q.eq(edgeDefinition.ref, id).eq(
1115
+ edgeDefinition.field,
1116
+ edgeId
1117
+ )
1118
+ ).collect() : []
1119
+ )
1120
+ )
1121
+ )).map((edgeDoc) => edgeDoc._id);
1122
+ edges[key] = {
1123
+ add,
1124
+ removeEdges
1125
+ };
1126
+ }
1068
1127
  }
1069
1128
  })
1070
1129
  );
@@ -1075,7 +1134,7 @@ var PromiseEntWriterImpl = class extends PromiseEntOrNullImpl {
1075
1134
  }
1076
1135
  replace(value) {
1077
1136
  return new PromiseEntIdImpl(
1078
- this.db,
1137
+ this.ctx,
1079
1138
  this.entDefinitions,
1080
1139
  this.table,
1081
1140
  async () => {
@@ -1084,38 +1143,33 @@ var PromiseEntWriterImpl = class extends PromiseEntOrNullImpl {
1084
1143
  await this.base.checkReadAndWriteRule("update", docId, value);
1085
1144
  await this.base.checkUniqueness(value, docId);
1086
1145
  const fields = this.base.fieldsOnly(value);
1087
- await this.db.replace(docId, fields);
1146
+ await this.ctx.db.replace(docId, fields);
1088
1147
  const edges = {};
1089
1148
  await Promise.all(
1090
1149
  Object.values(
1091
- this.entDefinitions[this.table].edges
1150
+ getEdgeDefinitions(this.entDefinitions, this.table)
1092
1151
  ).map(async (edgeDefinition) => {
1093
1152
  const key = edgeDefinition.name;
1094
1153
  const idOrIds = value[key];
1095
1154
  if (edgeDefinition.cardinality === "single") {
1096
1155
  if (edgeDefinition.type === "ref") {
1097
- const oldDoc = await this.db.get(docId);
1156
+ const oldDoc = await this.ctx.db.get(docId);
1098
1157
  if (oldDoc[key] !== void 0 && oldDoc[key] !== idOrIds) {
1099
1158
  throw new Error("Cannot set 1:1 edge from optional end.");
1100
1159
  }
1101
1160
  }
1102
1161
  } else {
1103
1162
  if (edgeDefinition.type === "field") {
1104
- const existing = (await this.db.query(edgeDefinition.to).withIndex(
1105
- edgeDefinition.ref,
1106
- (q) => q.eq(edgeDefinition.ref, docId)
1107
- ).collect()).map((doc) => doc._id);
1108
- edges[key] = {
1109
- add: idOrIds,
1110
- remove: existing
1111
- };
1163
+ if (idOrIds !== void 0) {
1164
+ throw new Error("Cannot set 1:many edge from many end.");
1165
+ }
1112
1166
  } else {
1113
1167
  const requested = new Set(idOrIds ?? []);
1114
- const remove = (await this.db.query(edgeDefinition.table).withIndex(
1168
+ const removeEdges = (await this.ctx.db.query(edgeDefinition.table).withIndex(
1115
1169
  edgeDefinition.field,
1116
1170
  (q) => q.eq(edgeDefinition.field, docId)
1117
1171
  ).collect()).map((doc) => [doc._id, doc[edgeDefinition.ref]]).concat(
1118
- edgeDefinition.symmetric ? (await this.db.query(edgeDefinition.table).withIndex(
1172
+ edgeDefinition.symmetric ? (await this.ctx.db.query(edgeDefinition.table).withIndex(
1119
1173
  edgeDefinition.ref,
1120
1174
  (q) => q.eq(edgeDefinition.ref, docId)
1121
1175
  ).collect()).map(
@@ -1129,8 +1183,8 @@ var PromiseEntWriterImpl = class extends PromiseEntOrNullImpl {
1129
1183
  return true;
1130
1184
  }).map(([edgeId]) => edgeId);
1131
1185
  edges[key] = {
1132
- add: Array.from(requested),
1133
- removeEdges: remove
1186
+ add: idOrIds ?? [],
1187
+ removeEdges
1134
1188
  };
1135
1189
  }
1136
1190
  }
@@ -1144,26 +1198,26 @@ var PromiseEntWriterImpl = class extends PromiseEntOrNullImpl {
1144
1198
  async delete() {
1145
1199
  const { id: docId } = await this.retrieve();
1146
1200
  const id = docId;
1147
- return this.base.deleteId(id);
1201
+ return this.base.deleteId(id, "default");
1148
1202
  }
1149
1203
  };
1150
1204
  var PromiseEntIdImpl = class extends Promise {
1151
- constructor(db, entDefinitions, table, retrieve) {
1205
+ constructor(ctx, entDefinitions, table, retrieve) {
1152
1206
  super(() => {
1153
1207
  });
1154
- this.db = db;
1208
+ this.ctx = ctx;
1155
1209
  this.entDefinitions = entDefinitions;
1156
1210
  this.table = table;
1157
1211
  this.retrieve = retrieve;
1158
1212
  }
1159
1213
  get() {
1160
1214
  return new PromiseEntOrNullImpl(
1161
- this.db,
1215
+ this.ctx,
1162
1216
  this.entDefinitions,
1163
1217
  this.table,
1164
1218
  async () => {
1165
1219
  const id = await this.retrieve();
1166
- return { id, doc: async () => this.db.get(id) };
1220
+ return { id, doc: async () => this.ctx.db.get(id) };
1167
1221
  },
1168
1222
  true
1169
1223
  );
@@ -1185,7 +1239,7 @@ function loadedRetriever(doc) {
1185
1239
  function addEntRules(entDefinitions, rules) {
1186
1240
  return { ...entDefinitions, rules };
1187
1241
  }
1188
- async function filterByReadRule(db, entDefinitions, table, docs, throwIfNull) {
1242
+ async function filterByReadRule(ctx, entDefinitions, table, docs, throwIfNull) {
1189
1243
  if (docs === null) {
1190
1244
  return null;
1191
1245
  }
@@ -1196,7 +1250,7 @@ async function filterByReadRule(db, entDefinitions, table, docs, throwIfNull) {
1196
1250
  const decisions = await Promise.all(
1197
1251
  docs.map(async (doc) => {
1198
1252
  const decision = await readPolicy(
1199
- entWrapper(doc, db, entDefinitions, table)
1253
+ entWrapper(doc, ctx, entDefinitions, table)
1200
1254
  );
1201
1255
  if (throwIfNull && !decision) {
1202
1256
  throw new Error(
@@ -1214,11 +1268,19 @@ function getReadRule(entDefinitions, table) {
1214
1268
  function getWriteRule(entDefinitions, table) {
1215
1269
  return entDefinitions.rules?.[table]?.write;
1216
1270
  }
1271
+ function getEdgeDefinitions(entDefinitions, table) {
1272
+ return entDefinitions[table].edges;
1273
+ }
1274
+ function getDeletionConfig(entDefinitions, table) {
1275
+ return entDefinitions[table].deletionConfig;
1276
+ }
1217
1277
  // Annotate the CommonJS export names for ESM import in node:
1218
1278
  0 && (module.exports = {
1219
1279
  addEntRules,
1220
1280
  entWrapper,
1221
1281
  entsTableFactory,
1282
+ getDeletionConfig,
1283
+ getEdgeDefinitions,
1222
1284
  getReadRule,
1223
1285
  getWriteRule
1224
1286
  });