@expo/entity-database-adapter-knex 0.35.0 → 0.36.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.
Files changed (35) hide show
  1. package/build/PostgresEntityDatabaseAdapter.d.ts +1 -1
  2. package/build/PostgresEntityDatabaseAdapter.js.map +1 -1
  3. package/build/PostgresEntityDatabaseAdapterProvider.d.ts +1 -1
  4. package/build/PostgresEntityQueryContextProvider.js +1 -0
  5. package/build/PostgresEntityQueryContextProvider.js.map +1 -1
  6. package/build/__integration-tests__/PostgresEntityIntegration-test.js +41 -28
  7. package/build/__integration-tests__/PostgresEntityIntegration-test.js.map +1 -1
  8. package/build/__integration-tests__/PostgresEntityQueryContextProvider-test.js.map +1 -1
  9. package/build/errors/__tests__/wrapNativePostgresCallAsync-test.js.map +1 -1
  10. package/build/errors/wrapNativePostgresCallAsync.js.map +1 -1
  11. package/build/testfixtures/ErrorsTestEntity.js +12 -15
  12. package/build/testfixtures/ErrorsTestEntity.js.map +1 -1
  13. package/build/testfixtures/InvalidTestEntity.js +12 -15
  14. package/build/testfixtures/InvalidTestEntity.js.map +1 -1
  15. package/build/testfixtures/PostgresTestEntity.js +12 -15
  16. package/build/testfixtures/PostgresTestEntity.js.map +1 -1
  17. package/build/testfixtures/PostgresTriggerTestEntity.js +16 -15
  18. package/build/testfixtures/PostgresTriggerTestEntity.js.map +1 -1
  19. package/build/testfixtures/PostgresUniqueTestEntity.js +12 -15
  20. package/build/testfixtures/PostgresUniqueTestEntity.js.map +1 -1
  21. package/build/testfixtures/PostgresValidatorTestEntity.js +14 -15
  22. package/build/testfixtures/PostgresValidatorTestEntity.js.map +1 -1
  23. package/package.json +5 -5
  24. package/src/PostgresEntityDatabaseAdapter.ts +15 -13
  25. package/src/PostgresEntityDatabaseAdapterProvider.ts +2 -2
  26. package/src/PostgresEntityQueryContextProvider.ts +5 -5
  27. package/src/__integration-tests__/PostgresEntityIntegration-test.ts +129 -106
  28. package/src/__integration-tests__/PostgresInvalidSetup-test.ts +8 -8
  29. package/src/__integration-tests__/errors-test.ts +11 -11
  30. package/src/__tests__/EntityFields-test.ts +3 -3
  31. package/src/errors/wrapNativePostgresCallAsync.ts +2 -2
  32. package/src/testfixtures/ErrorsTestEntity.ts +2 -2
  33. package/src/testfixtures/PostgresTriggerTestEntity.ts +10 -4
  34. package/src/testfixtures/PostgresValidatorTestEntity.ts +2 -2
  35. package/src/testfixtures/createKnexIntegrationTestEntityCompanionProvider.ts +2 -2
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  OrderByOrdering,
3
3
  createUnitTestEntityCompanionProvider,
4
- enforceResultsAsync,
5
4
  ViewerContext,
6
5
  TransactionIsolationLevel,
7
6
  } from '@expo/entity';
8
7
  import { enforceAsyncResult } from '@expo/results';
9
8
  import { knex, Knex } from 'knex';
10
9
  import nullthrows from 'nullthrows';
10
+ import { setTimeout } from 'timers/promises';
11
11
 
12
12
  import PostgresTestEntity from '../testfixtures/PostgresTestEntity';
13
13
  import PostgresTriggerTestEntity from '../testfixtures/PostgresTriggerTestEntity';
@@ -42,7 +42,7 @@ describe('postgres entity integration', () => {
42
42
  it('supports parallel partial updates', async () => {
43
43
  const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
44
44
  const entity = await enforceAsyncResult(
45
- PostgresTestEntity.creator(vc).setField('name', 'hello').createAsync()
45
+ PostgresTestEntity.creator(vc).setField('name', 'hello').createAsync(),
46
46
  );
47
47
 
48
48
  // update two different fields at the same time (from the same entity)
@@ -69,7 +69,7 @@ describe('postgres entity integration', () => {
69
69
  it('throws knex error upon empty update', async () => {
70
70
  const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
71
71
  const entity = await enforceAsyncResult(
72
- PostgresTestEntity.creator(vc).setField('name', 'hello').createAsync()
72
+ PostgresTestEntity.creator(vc).setField('name', 'hello').createAsync(),
73
73
  );
74
74
  await expect(PostgresTestEntity.updater(entity).updateAsync()).rejects.toThrow();
75
75
  });
@@ -77,7 +77,7 @@ describe('postgres entity integration', () => {
77
77
  it('throws error upon empty update for stub database adapter to match behavior', async () => {
78
78
  const vc = new ViewerContext(createUnitTestEntityCompanionProvider());
79
79
  const entity = await enforceAsyncResult(
80
- PostgresTestEntity.creator(vc).setField('name', 'hello').createAsync()
80
+ PostgresTestEntity.creator(vc).setField('name', 'hello').createAsync(),
81
81
  );
82
82
  await expect(PostgresTestEntity.updater(entity).updateAsync()).rejects.toThrow();
83
83
  });
@@ -88,66 +88,89 @@ describe('postgres entity integration', () => {
88
88
 
89
89
  // put one in the DB
90
90
  const firstEntity = await enforceAsyncResult(
91
- PostgresTestEntity.creator(vc1).setField('name', 'hello').createAsync()
91
+ PostgresTestEntity.creator(vc1).setField('name', 'hello').createAsync(),
92
92
  );
93
93
 
94
- await enforceAsyncResult(PostgresTestEntity.loader(vc1).loadByIDAsync(firstEntity.getID()));
94
+ await PostgresTestEntity.loader(vc1).enforcing().loadByIDAsync(firstEntity.getID());
95
95
 
96
96
  const errorToThrow = new Error('Intentional error');
97
97
 
98
98
  await expect(
99
- vc1.runInTransactionForDatabaseAdaptorFlavorAsync('postgres', async (queryContext) => {
100
- // put another in the DB that will be rolled back due to error thrown
101
- await enforceAsyncResult(
102
- PostgresTestEntity.creator(vc1, queryContext).setField('name', 'hello').createAsync()
103
- );
99
+ vc1.runInTransactionForDatabaseAdaptorFlavorAsync(
100
+ 'postgres',
101
+ async (queryContext) => {
102
+ // put another in the DB that will be rolled back due to error thrown
103
+ await enforceAsyncResult(
104
+ PostgresTestEntity.creator(vc1, queryContext).setField('name', 'hello').createAsync(),
105
+ );
104
106
 
105
- throw errorToThrow;
106
- })
107
+ throw errorToThrow;
108
+ },
109
+ {}, // test empty transaction config
110
+ ),
107
111
  ).rejects.toEqual(errorToThrow);
108
112
 
109
- const entities = await enforceResultsAsync(
110
- PostgresTestEntity.loader(vc1).loadManyByFieldEqualingAsync('name', 'hello')
111
- );
113
+ const entities = await PostgresTestEntity.loader(vc1)
114
+ .enforcing()
115
+ .loadManyByFieldEqualingAsync('name', 'hello');
112
116
  expect(entities).toHaveLength(1);
113
117
  });
114
118
 
115
- it('passes transaction config into transactions', async () => {
116
- const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
117
-
118
- const firstEntity = await enforceAsyncResult(
119
- PostgresTestEntity.creator(vc1).setField('name', 'hello').createAsync()
120
- );
119
+ describe('isolation levels', () => {
120
+ test.each(Object.values(TransactionIsolationLevel))(
121
+ 'isolation level: %p',
122
+ async (isolationLevel: TransactionIsolationLevel) => {
123
+ const vc1 = new ViewerContext(
124
+ createKnexIntegrationTestEntityCompanionProvider(knexInstance),
125
+ );
121
126
 
122
- const loadAndUpdateAsync = async (newName: string): Promise<{ error?: Error }> => {
123
- try {
124
- await vc1.runInTransactionForDatabaseAdaptorFlavorAsync(
125
- 'postgres',
126
- async (queryContext) => {
127
- const entity = await PostgresTestEntity.loader(vc1, queryContext)
128
- .enforcing()
129
- .loadByIDAsync(firstEntity.getID());
130
- await PostgresTestEntity.updater(entity, queryContext)
131
- .setField('name', newName)
132
- .enforceUpdateAsync();
133
- },
134
- { isolationLevel: TransactionIsolationLevel.SERIALIZABLE }
127
+ const firstEntity = await enforceAsyncResult(
128
+ PostgresTestEntity.creator(vc1).setField('name', 'hello').createAsync(),
135
129
  );
136
- return {};
137
- } catch (e) {
138
- return { error: e as Error };
139
- }
140
- };
141
-
142
- // do some parallel updates to trigger serializable error in at least some of them
143
- const results = await Promise.all([
144
- loadAndUpdateAsync('hello2'),
145
- loadAndUpdateAsync('hello3'),
146
- loadAndUpdateAsync('hello4'),
147
- loadAndUpdateAsync('hello5'),
148
- ]);
149
130
 
150
- expect(results.filter((r) => (r.error as any)?.cause?.code === '40001').length > 0).toBe(true);
131
+ const loadAndUpdateAsync = async (
132
+ newName: string,
133
+ delay: number,
134
+ ): Promise<{ error?: Error }> => {
135
+ try {
136
+ await vc1.runInTransactionForDatabaseAdaptorFlavorAsync(
137
+ 'postgres',
138
+ async (queryContext) => {
139
+ const entity = await PostgresTestEntity.loader(vc1, queryContext)
140
+ .enforcing()
141
+ .loadByIDAsync(firstEntity.getID());
142
+ await setTimeout(delay);
143
+ await PostgresTestEntity.updater(entity, queryContext)
144
+ .setField('name', entity.getField('name') + ',' + newName)
145
+ .enforceUpdateAsync();
146
+ },
147
+ { isolationLevel },
148
+ );
149
+ return {};
150
+ } catch (e) {
151
+ return { error: e as Error };
152
+ }
153
+ };
154
+
155
+ // do some parallel updates to trigger serializable error in at least some of them
156
+ const results = await Promise.all([
157
+ loadAndUpdateAsync('hello2', 0),
158
+ loadAndUpdateAsync('hello3', 100),
159
+ loadAndUpdateAsync('hello4', 200),
160
+ loadAndUpdateAsync('hello5', 300),
161
+ ]);
162
+
163
+ if (isolationLevel === TransactionIsolationLevel.READ_COMMITTED) {
164
+ // read committed seems executes the transactions and doesn't produce a consistent result, but doesn't throw
165
+ expect(results.filter((r) => !!r.error).length > 0).toBe(false);
166
+ } else {
167
+ // all other isolation levels throw since they're doing nonrepeatable reads
168
+ expect(results.filter((r) => (r.error as any)?.cause?.code === '40001').length > 0).toBe(
169
+ true,
170
+ );
171
+ }
172
+ },
173
+ );
151
174
  });
152
175
 
153
176
  describe('JSON fields', () => {
@@ -158,7 +181,7 @@ describe('postgres entity integration', () => {
158
181
  PostgresTestEntity.creator(vc1)
159
182
  .setField('stringArray', ['hello', 'world'])
160
183
  .setField('jsonArrayField', ['hello', 'world'])
161
- .createAsync()
184
+ .createAsync(),
162
185
  );
163
186
 
164
187
  expect(entity.getField('stringArray')).toEqual(['hello', 'world']);
@@ -171,7 +194,7 @@ describe('postgres entity integration', () => {
171
194
  const entity = await enforceAsyncResult(
172
195
  PostgresTestEntity.creator(vc1)
173
196
  .setField('jsonObjectField', { hello: 'world' })
174
- .createAsync()
197
+ .createAsync(),
175
198
  );
176
199
 
177
200
  expect(entity.getField('jsonObjectField')).toEqual({ hello: 'world' });
@@ -183,12 +206,12 @@ describe('postgres entity integration', () => {
183
206
  const entity1 = await enforceAsyncResult(
184
207
  PostgresTestEntity.creator(vc1)
185
208
  .setField('maybeJsonArrayField', ['hello', 'world'])
186
- .createAsync()
209
+ .createAsync(),
187
210
  );
188
211
  const entity2 = await enforceAsyncResult(
189
212
  PostgresTestEntity.creator(vc1)
190
213
  .setField('maybeJsonArrayField', { hello: 'world' })
191
- .createAsync()
214
+ .createAsync(),
192
215
  );
193
216
 
194
217
  expect(entity1.getField('maybeJsonArrayField')).toEqual(['hello', 'world']);
@@ -201,17 +224,17 @@ describe('postgres entity integration', () => {
201
224
  const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
202
225
 
203
226
  let entity = await enforceAsyncResult(
204
- PostgresTestEntity.creator(vc1).setField('bigintField', '72057594037928038').createAsync()
227
+ PostgresTestEntity.creator(vc1).setField('bigintField', '72057594037928038').createAsync(),
205
228
  );
206
229
  expect(entity.getField('bigintField')).toEqual('72057594037928038');
207
230
 
208
231
  entity = await enforceAsyncResult(
209
- PostgresTestEntity.updater(entity).setField('bigintField', '10').updateAsync()
232
+ PostgresTestEntity.updater(entity).setField('bigintField', '10').updateAsync(),
210
233
  );
211
234
  expect(entity.getField('bigintField')).toEqual('10');
212
235
 
213
236
  entity = await enforceAsyncResult(
214
- PostgresTestEntity.updater(entity).setField('bigintField', '-10').updateAsync()
237
+ PostgresTestEntity.updater(entity).setField('bigintField', '-10').updateAsync(),
215
238
  );
216
239
  expect(entity.getField('bigintField')).toEqual('-10');
217
240
  });
@@ -226,7 +249,7 @@ describe('postgres entity integration', () => {
226
249
  .setField('name', 'hello')
227
250
  .setField('hasACat', false)
228
251
  .setField('hasADog', true)
229
- .createAsync()
252
+ .createAsync(),
230
253
  );
231
254
 
232
255
  await enforceAsyncResult(
@@ -234,7 +257,7 @@ describe('postgres entity integration', () => {
234
257
  .setField('name', 'world')
235
258
  .setField('hasACat', false)
236
259
  .setField('hasADog', true)
237
- .createAsync()
260
+ .createAsync(),
238
261
  );
239
262
 
240
263
  await enforceAsyncResult(
@@ -242,7 +265,7 @@ describe('postgres entity integration', () => {
242
265
  .setField('name', 'wat')
243
266
  .setField('hasACat', false)
244
267
  .setField('hasADog', false)
245
- .createAsync()
268
+ .createAsync(),
246
269
  );
247
270
 
248
271
  const results = await PostgresTestEntity.loader(vc1)
@@ -299,25 +322,25 @@ describe('postgres entity integration', () => {
299
322
  PostgresTestEntity.creator(vc1)
300
323
  .setField('name', 'a')
301
324
  .setField('hasADog', true)
302
- .createAsync()
325
+ .createAsync(),
303
326
  );
304
327
  await enforceAsyncResult(
305
328
  PostgresTestEntity.creator(vc1)
306
329
  .setField('name', 'b')
307
330
  .setField('hasADog', true)
308
- .createAsync()
331
+ .createAsync(),
309
332
  );
310
333
  await enforceAsyncResult(
311
334
  PostgresTestEntity.creator(vc1)
312
335
  .setField('name', null)
313
336
  .setField('hasADog', true)
314
- .createAsync()
337
+ .createAsync(),
315
338
  );
316
339
  await enforceAsyncResult(
317
340
  PostgresTestEntity.creator(vc1)
318
341
  .setField('name', null)
319
342
  .setField('hasADog', false)
320
- .createAsync()
343
+ .createAsync(),
321
344
  );
322
345
 
323
346
  const results = await PostgresTestEntity.loader(vc1)
@@ -340,7 +363,7 @@ describe('postgres entity integration', () => {
340
363
  order: OrderByOrdering.DESCENDING,
341
364
  },
342
365
  ],
343
- }
366
+ },
344
367
  );
345
368
  expect(results2).toHaveLength(2);
346
369
  expect(results2.map((e) => e.getField('name'))).toEqual([null, 'a']);
@@ -355,7 +378,7 @@ describe('postgres entity integration', () => {
355
378
  .setField('name', 'hello')
356
379
  .setField('hasACat', false)
357
380
  .setField('hasADog', true)
358
- .createAsync()
381
+ .createAsync(),
359
382
  );
360
383
 
361
384
  const results = await PostgresTestEntity.loader(vc1)
@@ -372,13 +395,13 @@ describe('postgres entity integration', () => {
372
395
  .setField('name', 'hello')
373
396
  .setField('hasACat', false)
374
397
  .setField('hasADog', true)
375
- .createAsync()
398
+ .createAsync(),
376
399
  );
377
400
 
378
401
  await expect(
379
402
  PostgresTestEntity.loader(vc1)
380
403
  .enforcing()
381
- .loadManyByRawWhereClauseAsync('invalid_column = ?', ['hello'])
404
+ .loadManyByRawWhereClauseAsync('invalid_column = ?', ['hello']),
382
405
  ).rejects.toThrow();
383
406
  });
384
407
 
@@ -389,21 +412,21 @@ describe('postgres entity integration', () => {
389
412
  PostgresTestEntity.creator(vc1)
390
413
  .setField('name', 'a')
391
414
  .setField('hasADog', true)
392
- .createAsync()
415
+ .createAsync(),
393
416
  );
394
417
 
395
418
  await enforceAsyncResult(
396
419
  PostgresTestEntity.creator(vc1)
397
420
  .setField('name', 'b')
398
421
  .setField('hasADog', true)
399
- .createAsync()
422
+ .createAsync(),
400
423
  );
401
424
 
402
425
  await enforceAsyncResult(
403
426
  PostgresTestEntity.creator(vc1)
404
427
  .setField('name', 'c')
405
428
  .setField('hasADog', true)
406
- .createAsync()
429
+ .createAsync(),
407
430
  );
408
431
 
409
432
  const results = await PostgresTestEntity.loader(vc1)
@@ -455,58 +478,58 @@ describe('postgres entity integration', () => {
455
478
  describe('create', () => {
456
479
  it('rolls back transaction when trigger throws except afterCommit', async () => {
457
480
  const vc1 = new ViewerContext(
458
- createKnexIntegrationTestEntityCompanionProvider(knexInstance)
481
+ createKnexIntegrationTestEntityCompanionProvider(knexInstance),
459
482
  );
460
483
 
461
484
  await expect(
462
485
  PostgresTriggerTestEntity.creator(vc1)
463
486
  .setField('name', 'beforeCreate')
464
- .enforceCreateAsync()
487
+ .enforceCreateAsync(),
465
488
  ).rejects.toThrowError('name cannot have value beforeCreate');
466
489
  await expect(
467
490
  PostgresTriggerTestEntity.loader(vc1)
468
491
  .enforcing()
469
- .loadByFieldEqualingAsync('name', 'beforeCreate')
492
+ .loadByFieldEqualingAsync('name', 'beforeCreate'),
470
493
  ).resolves.toBeNull();
471
494
 
472
495
  await expect(
473
496
  PostgresTriggerTestEntity.creator(vc1)
474
497
  .setField('name', 'afterCreate')
475
- .enforceCreateAsync()
498
+ .enforceCreateAsync(),
476
499
  ).rejects.toThrowError('name cannot have value afterCreate');
477
500
  await expect(
478
501
  PostgresTriggerTestEntity.loader(vc1)
479
502
  .enforcing()
480
- .loadByFieldEqualingAsync('name', 'afterCreate')
503
+ .loadByFieldEqualingAsync('name', 'afterCreate'),
481
504
  ).resolves.toBeNull();
482
505
 
483
506
  await expect(
484
- PostgresTriggerTestEntity.creator(vc1).setField('name', 'beforeAll').enforceCreateAsync()
507
+ PostgresTriggerTestEntity.creator(vc1).setField('name', 'beforeAll').enforceCreateAsync(),
485
508
  ).rejects.toThrowError('name cannot have value beforeAll');
486
509
  await expect(
487
510
  PostgresTriggerTestEntity.loader(vc1)
488
511
  .enforcing()
489
- .loadByFieldEqualingAsync('name', 'beforeAll')
512
+ .loadByFieldEqualingAsync('name', 'beforeAll'),
490
513
  ).resolves.toBeNull();
491
514
 
492
515
  await expect(
493
- PostgresTriggerTestEntity.creator(vc1).setField('name', 'afterAll').enforceCreateAsync()
516
+ PostgresTriggerTestEntity.creator(vc1).setField('name', 'afterAll').enforceCreateAsync(),
494
517
  ).rejects.toThrowError('name cannot have value afterAll');
495
518
  await expect(
496
519
  PostgresTriggerTestEntity.loader(vc1)
497
520
  .enforcing()
498
- .loadByFieldEqualingAsync('name', 'afterAll')
521
+ .loadByFieldEqualingAsync('name', 'afterAll'),
499
522
  ).resolves.toBeNull();
500
523
 
501
524
  await expect(
502
525
  PostgresTriggerTestEntity.creator(vc1)
503
526
  .setField('name', 'afterCommit')
504
- .enforceCreateAsync()
527
+ .enforceCreateAsync(),
505
528
  ).rejects.toThrowError('name cannot have value afterCommit');
506
529
  await expect(
507
530
  PostgresTriggerTestEntity.loader(vc1)
508
531
  .enforcing()
509
- .loadByFieldEqualingAsync('name', 'afterCommit')
532
+ .loadByFieldEqualingAsync('name', 'afterCommit'),
510
533
  ).resolves.not.toBeNull();
511
534
  });
512
535
  });
@@ -514,7 +537,7 @@ describe('postgres entity integration', () => {
514
537
  describe('update', () => {
515
538
  it('rolls back transaction when trigger throws except afterCommit', async () => {
516
539
  const vc1 = new ViewerContext(
517
- createKnexIntegrationTestEntityCompanionProvider(knexInstance)
540
+ createKnexIntegrationTestEntityCompanionProvider(knexInstance),
518
541
  );
519
542
 
520
543
  const entity = await PostgresTriggerTestEntity.creator(vc1)
@@ -524,56 +547,56 @@ describe('postgres entity integration', () => {
524
547
  await expect(
525
548
  PostgresTriggerTestEntity.updater(entity)
526
549
  .setField('name', 'beforeUpdate')
527
- .enforceUpdateAsync()
550
+ .enforceUpdateAsync(),
528
551
  ).rejects.toThrowError('name cannot have value beforeUpdate');
529
552
  await expect(
530
553
  PostgresTriggerTestEntity.loader(vc1)
531
554
  .enforcing()
532
- .loadByFieldEqualingAsync('name', 'beforeUpdate')
555
+ .loadByFieldEqualingAsync('name', 'beforeUpdate'),
533
556
  ).resolves.toBeNull();
534
557
 
535
558
  await expect(
536
559
  PostgresTriggerTestEntity.updater(entity)
537
560
  .setField('name', 'afterUpdate')
538
- .enforceUpdateAsync()
561
+ .enforceUpdateAsync(),
539
562
  ).rejects.toThrowError('name cannot have value afterUpdate');
540
563
  await expect(
541
564
  PostgresTriggerTestEntity.loader(vc1)
542
565
  .enforcing()
543
- .loadByFieldEqualingAsync('name', 'afterUpdate')
566
+ .loadByFieldEqualingAsync('name', 'afterUpdate'),
544
567
  ).resolves.toBeNull();
545
568
 
546
569
  await expect(
547
570
  PostgresTriggerTestEntity.updater(entity)
548
571
  .setField('name', 'beforeAll')
549
- .enforceUpdateAsync()
572
+ .enforceUpdateAsync(),
550
573
  ).rejects.toThrowError('name cannot have value beforeAll');
551
574
  await expect(
552
575
  PostgresTriggerTestEntity.loader(vc1)
553
576
  .enforcing()
554
- .loadByFieldEqualingAsync('name', 'beforeAll')
577
+ .loadByFieldEqualingAsync('name', 'beforeAll'),
555
578
  ).resolves.toBeNull();
556
579
 
557
580
  await expect(
558
581
  PostgresTriggerTestEntity.updater(entity)
559
582
  .setField('name', 'afterAll')
560
- .enforceUpdateAsync()
583
+ .enforceUpdateAsync(),
561
584
  ).rejects.toThrowError('name cannot have value afterAll');
562
585
  await expect(
563
586
  PostgresTriggerTestEntity.loader(vc1)
564
587
  .enforcing()
565
- .loadByFieldEqualingAsync('name', 'afterAll')
588
+ .loadByFieldEqualingAsync('name', 'afterAll'),
566
589
  ).resolves.toBeNull();
567
590
 
568
591
  await expect(
569
592
  PostgresTriggerTestEntity.updater(entity)
570
593
  .setField('name', 'afterCommit')
571
- .enforceUpdateAsync()
594
+ .enforceUpdateAsync(),
572
595
  ).rejects.toThrowError('name cannot have value afterCommit');
573
596
  await expect(
574
597
  PostgresTriggerTestEntity.loader(vc1)
575
598
  .enforcing()
576
- .loadByFieldEqualingAsync('name', 'afterCommit')
599
+ .loadByFieldEqualingAsync('name', 'afterCommit'),
577
600
  ).resolves.not.toBeNull();
578
601
  });
579
602
  });
@@ -581,31 +604,31 @@ describe('postgres entity integration', () => {
581
604
  describe('delete', () => {
582
605
  it('rolls back transaction when trigger throws except afterCommit', async () => {
583
606
  const vc1 = new ViewerContext(
584
- createKnexIntegrationTestEntityCompanionProvider(knexInstance)
607
+ createKnexIntegrationTestEntityCompanionProvider(knexInstance),
585
608
  );
586
609
 
587
610
  const entityBeforeDelete = await PostgresTriggerTestEntity.creator(vc1)
588
611
  .setField('name', 'beforeDelete')
589
612
  .enforceCreateAsync();
590
613
  await expect(
591
- PostgresTriggerTestEntity.enforceDeleteAsync(entityBeforeDelete)
614
+ PostgresTriggerTestEntity.enforceDeleteAsync(entityBeforeDelete),
592
615
  ).rejects.toThrowError('name cannot have value beforeDelete');
593
616
  await expect(
594
617
  PostgresTriggerTestEntity.loader(vc1)
595
618
  .enforcing()
596
- .loadByFieldEqualingAsync('name', 'beforeDelete')
619
+ .loadByFieldEqualingAsync('name', 'beforeDelete'),
597
620
  ).resolves.not.toBeNull();
598
621
 
599
622
  const entityAfterDelete = await PostgresTriggerTestEntity.creator(vc1)
600
623
  .setField('name', 'afterDelete')
601
624
  .enforceCreateAsync();
602
625
  await expect(
603
- PostgresTriggerTestEntity.enforceDeleteAsync(entityAfterDelete)
626
+ PostgresTriggerTestEntity.enforceDeleteAsync(entityAfterDelete),
604
627
  ).rejects.toThrowError('name cannot have value afterDelete');
605
628
  await expect(
606
629
  PostgresTriggerTestEntity.loader(vc1)
607
630
  .enforcing()
608
- .loadByFieldEqualingAsync('name', 'afterDelete')
631
+ .loadByFieldEqualingAsync('name', 'afterDelete'),
609
632
  ).resolves.not.toBeNull();
610
633
  });
611
634
  });
@@ -613,25 +636,25 @@ describe('postgres entity integration', () => {
613
636
  describe('create', () => {
614
637
  it('rolls back transaction when trigger throws ', async () => {
615
638
  const vc1 = new ViewerContext(
616
- createKnexIntegrationTestEntityCompanionProvider(knexInstance)
639
+ createKnexIntegrationTestEntityCompanionProvider(knexInstance),
617
640
  );
618
641
 
619
642
  await expect(
620
643
  PostgresValidatorTestEntity.creator(vc1)
621
644
  .setField('name', 'beforeCreateAndBeforeUpdate')
622
- .enforceCreateAsync()
645
+ .enforceCreateAsync(),
623
646
  ).rejects.toThrowError('name cannot have value beforeCreateAndBeforeUpdate');
624
647
  await expect(
625
648
  PostgresValidatorTestEntity.loader(vc1)
626
649
  .enforcing()
627
- .loadByFieldEqualingAsync('name', 'beforeCreateAndBeforeUpdate')
650
+ .loadByFieldEqualingAsync('name', 'beforeCreateAndBeforeUpdate'),
628
651
  ).resolves.toBeNull();
629
652
  });
630
653
  });
631
654
  describe('update', () => {
632
655
  it('rolls back transaction when trigger throws ', async () => {
633
656
  const vc1 = new ViewerContext(
634
- createKnexIntegrationTestEntityCompanionProvider(knexInstance)
657
+ createKnexIntegrationTestEntityCompanionProvider(knexInstance),
635
658
  );
636
659
 
637
660
  const entity = await PostgresValidatorTestEntity.creator(vc1)
@@ -641,19 +664,19 @@ describe('postgres entity integration', () => {
641
664
  await expect(
642
665
  PostgresValidatorTestEntity.updater(entity)
643
666
  .setField('name', 'beforeCreateAndBeforeUpdate')
644
- .enforceUpdateAsync()
667
+ .enforceUpdateAsync(),
645
668
  ).rejects.toThrowError('name cannot have value beforeCreateAndBeforeUpdate');
646
669
  await expect(
647
670
  PostgresValidatorTestEntity.loader(vc1)
648
671
  .enforcing()
649
- .loadByFieldEqualingAsync('name', 'beforeCreateAndBeforeUpdate')
672
+ .loadByFieldEqualingAsync('name', 'beforeCreateAndBeforeUpdate'),
650
673
  ).resolves.toBeNull();
651
674
  });
652
675
  });
653
676
  describe('delete', () => {
654
677
  it('validation should not run on a delete mutation', async () => {
655
678
  const vc1 = new ViewerContext(
656
- createKnexIntegrationTestEntityCompanionProvider(knexInstance)
679
+ createKnexIntegrationTestEntityCompanionProvider(knexInstance),
657
680
  );
658
681
 
659
682
  const entityToDelete = await PostgresValidatorTestEntity.creator(vc1)
@@ -663,7 +686,7 @@ describe('postgres entity integration', () => {
663
686
  await expect(
664
687
  PostgresValidatorTestEntity.loader(vc1)
665
688
  .enforcing()
666
- .loadByFieldEqualingAsync('name', 'shouldBeDeleted')
689
+ .loadByFieldEqualingAsync('name', 'shouldBeDeleted'),
667
690
  ).resolves.toBeNull();
668
691
  });
669
692
  });
@@ -718,7 +741,7 @@ describe('postgres entity integration', () => {
718
741
  preCommitCallCount++;
719
742
  throw Error('wat');
720
743
  }, 0);
721
- })
744
+ }),
722
745
  ).rejects.toThrowError('wat');
723
746
 
724
747
  expect(preCommitCallCount).toBe(2);
@@ -35,40 +35,40 @@ describe('postgres entity integration', () => {
35
35
  it('throws after deletion of multiple rows or no rows', async () => {
36
36
  const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
37
37
  const entity1 = await enforceAsyncResult(
38
- InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'hello').createAsync()
38
+ InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'hello').createAsync(),
39
39
  );
40
40
  await enforceAsyncResult(
41
- InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'world').createAsync()
41
+ InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'world').createAsync(),
42
42
  );
43
43
 
44
44
  await expect(InvalidTestEntity.deleteAsync(entity1)).rejects.toThrowError(
45
- 'Excessive deletions from database adapter delete'
45
+ 'Excessive deletions from database adapter delete',
46
46
  );
47
47
  });
48
48
 
49
49
  it('throws after update of multiple rows', async () => {
50
50
  const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
51
51
  const entity1 = await enforceAsyncResult(
52
- InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'hello').createAsync()
52
+ InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'hello').createAsync(),
53
53
  );
54
54
  await enforceAsyncResult(
55
- InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'world').createAsync()
55
+ InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'world').createAsync(),
56
56
  );
57
57
 
58
58
  await expect(
59
- InvalidTestEntity.updater(entity1).setField('name', 'blah').enforceUpdateAsync()
59
+ InvalidTestEntity.updater(entity1).setField('name', 'blah').enforceUpdateAsync(),
60
60
  ).rejects.toThrowError('Excessive results from database adapter update');
61
61
  });
62
62
 
63
63
  it('throws after update of no rows', async () => {
64
64
  const vc = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
65
65
  const entity1 = await enforceAsyncResult(
66
- InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'hello').createAsync()
66
+ InvalidTestEntity.creator(vc).setField('id', 1).setField('name', 'hello').createAsync(),
67
67
  );
68
68
  await InvalidTestEntity.deleteAsync(entity1);
69
69
 
70
70
  await expect(
71
- InvalidTestEntity.updater(entity1).setField('name', 'blah').enforceUpdateAsync()
71
+ InvalidTestEntity.updater(entity1).setField('name', 'blah').enforceUpdateAsync(),
72
72
  ).rejects.toThrowError('Empty results from database adapter update');
73
73
  });
74
74
  });