wabe 0.6.9 → 0.6.10

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 (158) hide show
  1. package/README.md +138 -32
  2. package/bucket/b.txt +1 -0
  3. package/dev/index.ts +215 -0
  4. package/dist/authentication/Session.d.ts +4 -1
  5. package/dist/authentication/interface.d.ts +16 -0
  6. package/dist/email/interface.d.ts +1 -1
  7. package/dist/graphql/resolvers.d.ts +4 -2
  8. package/dist/hooks/index.d.ts +1 -0
  9. package/dist/index.d.ts +0 -1
  10. package/dist/index.js +8713 -8867
  11. package/dist/server/index.d.ts +4 -2
  12. package/dist/utils/crypto.d.ts +7 -0
  13. package/dist/utils/helper.d.ts +4 -1
  14. package/generated/schema.graphql +16 -14
  15. package/generated/wabe.ts +4 -4
  16. package/package.json +15 -15
  17. package/src/authentication/OTP.test.ts +69 -0
  18. package/src/authentication/OTP.ts +66 -0
  19. package/src/authentication/Session.test.ts +665 -0
  20. package/src/authentication/Session.ts +529 -0
  21. package/src/authentication/defaultAuthentication.ts +214 -0
  22. package/src/authentication/index.ts +3 -0
  23. package/src/authentication/interface.ts +157 -0
  24. package/src/authentication/oauth/GitHub.test.ts +105 -0
  25. package/src/authentication/oauth/GitHub.ts +133 -0
  26. package/src/authentication/oauth/Google.test.ts +105 -0
  27. package/src/authentication/oauth/Google.ts +110 -0
  28. package/src/authentication/oauth/Oauth2Client.test.ts +225 -0
  29. package/src/authentication/oauth/Oauth2Client.ts +140 -0
  30. package/src/authentication/oauth/index.ts +2 -0
  31. package/src/authentication/oauth/utils.test.ts +35 -0
  32. package/src/authentication/oauth/utils.ts +28 -0
  33. package/src/authentication/providers/EmailOTP.test.ts +138 -0
  34. package/src/authentication/providers/EmailOTP.ts +93 -0
  35. package/src/authentication/providers/EmailPassword.test.ts +187 -0
  36. package/src/authentication/providers/EmailPassword.ts +130 -0
  37. package/src/authentication/providers/EmailPasswordSRP.test.ts +206 -0
  38. package/src/authentication/providers/EmailPasswordSRP.ts +184 -0
  39. package/src/authentication/providers/GitHub.ts +30 -0
  40. package/src/authentication/providers/Google.ts +30 -0
  41. package/src/authentication/providers/OAuth.test.ts +185 -0
  42. package/src/authentication/providers/OAuth.ts +112 -0
  43. package/src/authentication/providers/PhonePassword.test.ts +187 -0
  44. package/src/authentication/providers/PhonePassword.ts +129 -0
  45. package/src/authentication/providers/QRCodeOTP.test.ts +79 -0
  46. package/src/authentication/providers/QRCodeOTP.ts +65 -0
  47. package/src/authentication/providers/index.ts +6 -0
  48. package/src/authentication/resolvers/refreshResolver.test.ts +37 -0
  49. package/src/authentication/resolvers/refreshResolver.ts +20 -0
  50. package/src/authentication/resolvers/signInWithResolver.inte.test.ts +59 -0
  51. package/src/authentication/resolvers/signInWithResolver.test.ts +307 -0
  52. package/src/authentication/resolvers/signInWithResolver.ts +102 -0
  53. package/src/authentication/resolvers/signOutResolver.test.ts +41 -0
  54. package/src/authentication/resolvers/signOutResolver.ts +22 -0
  55. package/src/authentication/resolvers/signUpWithResolver.test.ts +186 -0
  56. package/src/authentication/resolvers/signUpWithResolver.ts +69 -0
  57. package/src/authentication/resolvers/verifyChallenge.test.ts +136 -0
  58. package/src/authentication/resolvers/verifyChallenge.ts +69 -0
  59. package/src/authentication/roles.test.ts +59 -0
  60. package/src/authentication/roles.ts +40 -0
  61. package/src/authentication/utils.test.ts +99 -0
  62. package/src/authentication/utils.ts +43 -0
  63. package/src/cache/InMemoryCache.test.ts +62 -0
  64. package/src/cache/InMemoryCache.ts +45 -0
  65. package/src/cron/index.test.ts +17 -0
  66. package/src/cron/index.ts +46 -0
  67. package/src/database/DatabaseController.test.ts +625 -0
  68. package/src/database/DatabaseController.ts +983 -0
  69. package/src/database/index.test.ts +1230 -0
  70. package/src/database/index.ts +9 -0
  71. package/src/database/interface.ts +312 -0
  72. package/src/email/DevAdapter.ts +8 -0
  73. package/src/email/EmailController.test.ts +29 -0
  74. package/src/email/EmailController.ts +13 -0
  75. package/src/email/index.ts +2 -0
  76. package/src/email/interface.ts +36 -0
  77. package/src/email/templates/sendOtpCode.ts +120 -0
  78. package/src/file/FileController.ts +28 -0
  79. package/src/file/FileDevAdapter.ts +54 -0
  80. package/src/file/hookDeleteFile.ts +27 -0
  81. package/src/file/hookReadFile.ts +70 -0
  82. package/src/file/hookUploadFile.ts +53 -0
  83. package/src/file/index.test.ts +979 -0
  84. package/src/file/index.ts +2 -0
  85. package/src/file/interface.ts +42 -0
  86. package/src/graphql/GraphQLSchema.test.ts +4399 -0
  87. package/src/graphql/GraphQLSchema.ts +928 -0
  88. package/src/graphql/index.ts +2 -0
  89. package/src/graphql/parseGraphqlSchema.ts +94 -0
  90. package/src/graphql/parser.test.ts +217 -0
  91. package/src/graphql/parser.ts +566 -0
  92. package/src/graphql/pointerAndRelationFunction.ts +200 -0
  93. package/src/graphql/resolvers.ts +467 -0
  94. package/src/graphql/tests/aggregation.test.ts +1123 -0
  95. package/src/graphql/tests/e2e.test.ts +596 -0
  96. package/src/graphql/tests/scalars.test.ts +250 -0
  97. package/src/graphql/types.ts +219 -0
  98. package/src/hooks/HookObject.test.ts +122 -0
  99. package/src/hooks/HookObject.ts +168 -0
  100. package/src/hooks/authentication.ts +76 -0
  101. package/src/hooks/createUser.test.ts +77 -0
  102. package/src/hooks/createUser.ts +10 -0
  103. package/src/hooks/defaultFields.test.ts +187 -0
  104. package/src/hooks/defaultFields.ts +40 -0
  105. package/src/hooks/deleteSession.test.ts +181 -0
  106. package/src/hooks/deleteSession.ts +20 -0
  107. package/src/hooks/hashFieldHook.test.ts +163 -0
  108. package/src/hooks/hashFieldHook.ts +97 -0
  109. package/src/hooks/index.test.ts +207 -0
  110. package/src/hooks/index.ts +430 -0
  111. package/src/hooks/permissions.test.ts +424 -0
  112. package/src/hooks/permissions.ts +113 -0
  113. package/src/hooks/protected.test.ts +551 -0
  114. package/src/hooks/protected.ts +72 -0
  115. package/src/hooks/searchableFields.test.ts +166 -0
  116. package/src/hooks/searchableFields.ts +98 -0
  117. package/src/hooks/session.test.ts +138 -0
  118. package/src/hooks/session.ts +78 -0
  119. package/src/hooks/setEmail.test.ts +216 -0
  120. package/src/hooks/setEmail.ts +35 -0
  121. package/src/hooks/setupAcl.test.ts +589 -0
  122. package/src/hooks/setupAcl.ts +29 -0
  123. package/src/index.ts +9 -0
  124. package/src/schema/Schema.test.ts +484 -0
  125. package/src/schema/Schema.ts +795 -0
  126. package/src/schema/defaultResolvers.ts +94 -0
  127. package/src/schema/index.ts +1 -0
  128. package/src/schema/resolvers/meResolver.test.ts +62 -0
  129. package/src/schema/resolvers/meResolver.ts +14 -0
  130. package/src/schema/resolvers/newFile.ts +0 -0
  131. package/src/schema/resolvers/resetPassword.test.ts +345 -0
  132. package/src/schema/resolvers/resetPassword.ts +64 -0
  133. package/src/schema/resolvers/sendEmail.test.ts +118 -0
  134. package/src/schema/resolvers/sendEmail.ts +21 -0
  135. package/src/schema/resolvers/sendOtpCode.test.ts +153 -0
  136. package/src/schema/resolvers/sendOtpCode.ts +52 -0
  137. package/src/security.test.ts +3461 -0
  138. package/src/server/defaultSessionHandler.test.ts +66 -0
  139. package/src/server/defaultSessionHandler.ts +115 -0
  140. package/src/server/generateCodegen.ts +476 -0
  141. package/src/server/index.test.ts +552 -0
  142. package/src/server/index.ts +354 -0
  143. package/src/server/interface.ts +11 -0
  144. package/src/server/routes/authHandler.ts +187 -0
  145. package/src/server/routes/index.ts +40 -0
  146. package/src/utils/crypto.test.ts +41 -0
  147. package/src/utils/crypto.ts +121 -0
  148. package/src/utils/export.ts +13 -0
  149. package/src/utils/helper.ts +195 -0
  150. package/src/utils/index.test.ts +11 -0
  151. package/src/utils/index.ts +201 -0
  152. package/src/utils/preload.ts +8 -0
  153. package/src/utils/testHelper.ts +117 -0
  154. package/tsconfig.json +32 -0
  155. package/bunfig.toml +0 -4
  156. package/dist/ai/index.d.ts +0 -1
  157. package/dist/ai/interface.d.ts +0 -9
  158. /package/dist/server/{defaultHandlers.d.ts → defaultSessionHandler.d.ts} +0 -0
@@ -0,0 +1,625 @@
1
+ import {
2
+ describe,
3
+ it,
4
+ expect,
5
+ mock,
6
+ afterEach,
7
+ spyOn,
8
+ afterAll,
9
+ } from 'bun:test'
10
+ import type { WhereType } from '.'
11
+ import * as hooks from '../hooks/index'
12
+ import type { WabeContext } from '../server/interface'
13
+ import type { DevWabeTypes } from '../utils/helper'
14
+ import { DatabaseController } from './DatabaseController'
15
+
16
+ describe('DatabaseController', () => {
17
+ const mockGetObject = mock(() => {})
18
+ const mockGetObjects = mock(() => {})
19
+ const mockCreateObject = mock(() => {})
20
+ const mockCreateObjects = mock(() => {})
21
+ const mockUpdateObject = mock(() => {})
22
+ const mockUpdateObjects = mock(() => {})
23
+ const mockDeleteObject = mock(() => {})
24
+ const mockDeleteObjects = mock(() => {})
25
+ const mockClearDatabase = mock(() => {})
26
+ const mockCount = mock(() => {})
27
+
28
+ const mockRunOnSingleObject = mock(() => ({ newData: {} }) as never)
29
+ const mockRunOnMultipleObject = mock(() => {})
30
+
31
+ const mockInitializeHook = spyOn(hooks, 'initializeHook').mockReturnValue({
32
+ runOnSingleObject: mockRunOnSingleObject,
33
+ runOnMultipleObjects: mockRunOnMultipleObject,
34
+ } as never)
35
+
36
+ const mockAdapter = mock(() => ({
37
+ getObject: mockGetObject,
38
+ getObjects: mockGetObjects,
39
+ createObject: mockCreateObject,
40
+ createObjects: mockCreateObjects,
41
+ updateObject: mockUpdateObject,
42
+ updateObjects: mockUpdateObjects,
43
+ deleteObject: mockDeleteObject,
44
+ deleteObjects: mockDeleteObjects,
45
+ clearDatabase: mockClearDatabase,
46
+ count: mockCount,
47
+ }))
48
+
49
+ const config = {
50
+ schema: {
51
+ classes: [
52
+ {
53
+ name: 'TestClass',
54
+ fields: {
55
+ fieldX: {
56
+ type: 'String',
57
+ },
58
+ pointerToAnotherClass: {
59
+ type: 'Pointer',
60
+ class: 'AnotherClass',
61
+ },
62
+ pointerToAnotherClass2: {
63
+ type: 'Pointer',
64
+ class: 'AnotherClass2',
65
+ },
66
+ },
67
+ },
68
+ {
69
+ name: 'AnotherClass',
70
+ fields: {
71
+ field1: {
72
+ type: 'String',
73
+ },
74
+ },
75
+ },
76
+ {
77
+ name: 'AnotherClass2',
78
+ fields: {
79
+ field3: {
80
+ type: 'String',
81
+ },
82
+ },
83
+ },
84
+ {
85
+ name: 'AnotherClass3',
86
+ fields: {
87
+ field4: {
88
+ type: 'String',
89
+ },
90
+ },
91
+ },
92
+ {
93
+ name: 'AnotherClass4',
94
+ fields: {
95
+ relationToAnotherClass3: {
96
+ type: 'Relation',
97
+ class: 'AnotherClass3',
98
+ },
99
+ },
100
+ },
101
+ {
102
+ name: 'ClassWithObject',
103
+ fields: {
104
+ object: {
105
+ type: 'Object',
106
+ object: {
107
+ name: 'ObjectName',
108
+ fields: {
109
+ objectField: {
110
+ type: 'String',
111
+ },
112
+ },
113
+ },
114
+ },
115
+ },
116
+ },
117
+ ],
118
+ },
119
+ } as any
120
+
121
+ const context = {
122
+ isRoot: true,
123
+ wabe: { config },
124
+ sessionId: 'sessionId',
125
+ } as any
126
+
127
+ afterAll(() => {
128
+ mockInitializeHook.mockRestore()
129
+ mockRunOnSingleObject.mockRestore()
130
+ mockRunOnMultipleObject.mockRestore()
131
+ })
132
+
133
+ afterEach(() => {
134
+ mockGetObject.mockClear()
135
+ mockGetObjects.mockClear()
136
+ mockInitializeHook.mockClear()
137
+ mockRunOnSingleObject.mockClear()
138
+ mockRunOnMultipleObject.mockClear()
139
+ mockClearDatabase.mockClear()
140
+ mockCount.mockClear()
141
+ })
142
+
143
+ it('should call adapter count', async () => {
144
+ const databaseController = new DatabaseController(mockAdapter() as any)
145
+
146
+ await databaseController.count({
147
+ className: 'User',
148
+ context,
149
+ where: { age: { equalTo: 20 } },
150
+ })
151
+
152
+ expect(mockCount).toHaveBeenCalledTimes(1)
153
+ expect(mockCount).toHaveBeenCalledWith({
154
+ className: 'User',
155
+ context,
156
+ where: { age: { equalTo: 20 } },
157
+ })
158
+ })
159
+
160
+ it('should call adapter clearDatabase', async () => {
161
+ const databaseController = new DatabaseController(mockAdapter() as any)
162
+
163
+ await databaseController.clearDatabase()
164
+
165
+ expect(mockClearDatabase).toHaveBeenCalledTimes(1)
166
+ })
167
+
168
+ it('should create new where include the ACL from context when isRoot = true', () => {
169
+ const databaseController = new DatabaseController(mockAdapter() as any)
170
+
171
+ const where: WhereType<any, any> = {
172
+ id: { equalTo: 'id' },
173
+ }
174
+
175
+ const context: WabeContext<any> = {
176
+ isRoot: true,
177
+ wabe: {} as any,
178
+ user: {
179
+ id: 'userId',
180
+ role: {
181
+ id: 'roleId',
182
+ } as any,
183
+ } as any,
184
+ }
185
+
186
+ const newWhere = databaseController._buildWhereWithACL(
187
+ where,
188
+ context,
189
+ 'read',
190
+ )
191
+
192
+ expect(newWhere).toEqual(where)
193
+ })
194
+
195
+ it('should create new where include the ACL from context on read operation', () => {
196
+ const databaseController = new DatabaseController(mockAdapter() as any)
197
+
198
+ const where: WhereType<DevWabeTypes, any> = {
199
+ id: { equalTo: 'id' },
200
+ }
201
+
202
+ const context: WabeContext<any> = {
203
+ isRoot: false,
204
+ wabe: {} as any,
205
+ user: {
206
+ id: 'userId',
207
+ role: {
208
+ id: 'roleId',
209
+ } as any,
210
+ } as any,
211
+ }
212
+
213
+ const newWhere = databaseController._buildWhereWithACL(
214
+ where,
215
+ context,
216
+ 'read',
217
+ )
218
+
219
+ // Soit user y est donc read doit etre à true soit user y est pas et donc role read doit etre à true
220
+
221
+ expect(newWhere).toEqual({
222
+ AND: [
223
+ { id: { equalTo: 'id' } },
224
+ {
225
+ OR: [
226
+ {
227
+ acl: { equalTo: null },
228
+ },
229
+ {
230
+ acl: {
231
+ users: { contains: { userId: 'userId', read: true } },
232
+ },
233
+ },
234
+ {
235
+ AND: [
236
+ {
237
+ acl: {
238
+ users: {
239
+ notContains: { userId: 'userId' },
240
+ },
241
+ },
242
+ },
243
+ {
244
+ acl: {
245
+ roles: { contains: { roleId: 'roleId', read: true } },
246
+ },
247
+ },
248
+ ],
249
+ },
250
+ ],
251
+ },
252
+ ],
253
+ } as any)
254
+ })
255
+
256
+ it('should create new where include the ACL from context with undefined roleId', () => {
257
+ const databaseController = new DatabaseController(mockAdapter() as any)
258
+
259
+ const where: WhereType<any, any> = {
260
+ id: { equalTo: 'id' },
261
+ }
262
+
263
+ const context: WabeContext<any> = {
264
+ isRoot: false,
265
+ wabe: {} as any,
266
+ user: {
267
+ id: 'userId',
268
+ } as any,
269
+ }
270
+
271
+ const newWhere = databaseController._buildWhereWithACL(
272
+ where,
273
+ context,
274
+ 'write',
275
+ )
276
+
277
+ expect(newWhere).toEqual({
278
+ AND: [
279
+ { id: { equalTo: 'id' } },
280
+ {
281
+ OR: [
282
+ {
283
+ acl: { equalTo: null },
284
+ },
285
+ {
286
+ acl: {
287
+ users: { contains: { userId: 'userId', write: true } },
288
+ },
289
+ },
290
+ ],
291
+ },
292
+ ],
293
+ } as any)
294
+ })
295
+
296
+ it('should create new where include the ACL from context with undefined userId and roleId', () => {
297
+ const databaseController = new DatabaseController(mockAdapter() as any)
298
+
299
+ const where: WhereType<any, any> = {
300
+ id: { equalTo: 'id' },
301
+ }
302
+
303
+ const context: WabeContext<any> = {
304
+ isRoot: false,
305
+ wabe: {} as any,
306
+ user: {} as any,
307
+ }
308
+
309
+ const newWhere = databaseController._buildWhereWithACL(
310
+ where,
311
+ context,
312
+ 'read',
313
+ )
314
+
315
+ expect(newWhere).toEqual({
316
+ AND: [{ id: { equalTo: 'id' } }, { acl: { equalTo: null } }],
317
+ } as any)
318
+ })
319
+
320
+ it('should not call createObjects adapter when the data array is empty', async () => {
321
+ const databaseController = new DatabaseController(mockAdapter() as any)
322
+
323
+ await databaseController.createObjects({
324
+ className: 'TestClass',
325
+ context,
326
+ data: [],
327
+ })
328
+
329
+ expect(mockCreateObjects).toHaveBeenCalledTimes(0)
330
+ })
331
+
332
+ it('should call hooks on getObject', async () => {
333
+ mockGetObject.mockResolvedValue({} as never)
334
+ const databaseController = new DatabaseController(mockAdapter() as any)
335
+
336
+ await databaseController.getObject({
337
+ className: 'TestClass',
338
+ context,
339
+ id: 'id',
340
+ select: { id: true },
341
+ })
342
+
343
+ expect(mockInitializeHook).toHaveBeenCalledTimes(1)
344
+ expect(mockInitializeHook).toHaveBeenCalledWith({
345
+ className: 'TestClass',
346
+ context: {
347
+ sessionId: 'sessionId',
348
+ wabe: { config },
349
+ isRoot: true,
350
+ },
351
+ select: { id: true },
352
+ })
353
+
354
+ expect(mockRunOnSingleObject).toHaveBeenCalledTimes(2)
355
+ expect(mockRunOnSingleObject).toHaveBeenNthCalledWith(1, {
356
+ operationType: hooks.OperationType.BeforeRead,
357
+ id: 'id',
358
+ })
359
+ expect(mockRunOnSingleObject).toHaveBeenNthCalledWith(2, {
360
+ operationType: hooks.OperationType.AfterRead,
361
+ id: 'id',
362
+ object: {},
363
+ })
364
+ })
365
+
366
+ it('should call hooks on getObjects', async () => {
367
+ mockGetObjects.mockResolvedValue([] as never)
368
+
369
+ const databaseController = new DatabaseController(mockAdapter() as any)
370
+
371
+ await databaseController.getObjects({
372
+ className: 'TestClass',
373
+ context,
374
+ where: { id: { equalTo: 'id' } },
375
+ select: { id: true },
376
+ })
377
+
378
+ expect(mockInitializeHook).toHaveBeenCalledTimes(1)
379
+ expect(mockInitializeHook).toHaveBeenCalledWith({
380
+ className: 'TestClass',
381
+ context: {
382
+ sessionId: 'sessionId',
383
+ wabe: { config },
384
+ isRoot: true,
385
+ },
386
+ select: { id: true },
387
+ })
388
+
389
+ expect(mockRunOnMultipleObject).toHaveBeenCalledTimes(2)
390
+ expect(mockRunOnMultipleObject).toHaveBeenNthCalledWith(1, {
391
+ operationType: hooks.OperationType.BeforeRead,
392
+ where: { id: { equalTo: 'id' } },
393
+ })
394
+ expect(mockRunOnMultipleObject).toHaveBeenNthCalledWith(2, {
395
+ operationType: hooks.OperationType.AfterRead,
396
+ objects: [],
397
+ })
398
+ })
399
+
400
+ it('should call hooks on updateObject', async () => {
401
+ mockRunOnSingleObject.mockResolvedValue({
402
+ object: undefined,
403
+ } as never)
404
+ mockUpdateObject.mockResolvedValue({ id: 'id' } as never)
405
+ mockGetObject.mockResolvedValue({ id: 'id' } as never)
406
+
407
+ const databaseController = new DatabaseController(mockAdapter() as any)
408
+
409
+ await databaseController.updateObject({
410
+ className: 'TestClass',
411
+ context,
412
+ id: 'id',
413
+ data: { name: 'test' },
414
+ select: { id: true },
415
+ })
416
+
417
+ expect(mockInitializeHook).toHaveBeenCalledTimes(2)
418
+ expect(mockInitializeHook).toHaveBeenCalledWith({
419
+ className: 'TestClass',
420
+ context: {
421
+ sessionId: 'sessionId',
422
+ wabe: { config },
423
+ isRoot: true,
424
+ },
425
+ newData: { name: 'test' },
426
+ select: { id: true },
427
+ })
428
+
429
+ expect(mockRunOnSingleObject).toHaveBeenCalledTimes(4)
430
+ expect(mockRunOnSingleObject).toHaveBeenNthCalledWith(1, {
431
+ operationType: hooks.OperationType.BeforeUpdate,
432
+ id: 'id',
433
+ })
434
+ expect(mockRunOnSingleObject).toHaveBeenNthCalledWith(2, {
435
+ operationType: hooks.OperationType.AfterUpdate,
436
+ id: 'id',
437
+ })
438
+ })
439
+
440
+ it('should call hooks on updateObjects', async () => {
441
+ mockRunOnMultipleObject.mockResolvedValue({
442
+ newData: {},
443
+ objects: [],
444
+ } as never)
445
+ mockUpdateObjects.mockResolvedValue([] as never)
446
+
447
+ const databaseController = new DatabaseController(mockAdapter() as any)
448
+
449
+ await databaseController.updateObjects({
450
+ className: 'TestClass',
451
+ context,
452
+ where: { id: { equalTo: 'id' } },
453
+ data: { name: 'test' },
454
+ select: { id: true },
455
+ })
456
+
457
+ expect(mockInitializeHook).toHaveBeenCalledTimes(2)
458
+ expect(mockInitializeHook).toHaveBeenCalledWith({
459
+ className: 'TestClass',
460
+ context: {
461
+ sessionId: 'sessionId',
462
+ wabe: { config },
463
+ isRoot: true,
464
+ },
465
+ newData: { name: 'test' },
466
+ select: { id: true },
467
+ })
468
+
469
+ expect(mockRunOnMultipleObject).toHaveBeenCalledTimes(4)
470
+ expect(mockRunOnMultipleObject).toHaveBeenNthCalledWith(1, {
471
+ operationType: hooks.OperationType.BeforeUpdate,
472
+ where: { id: { equalTo: 'id' } },
473
+ })
474
+ expect(mockRunOnMultipleObject).toHaveBeenNthCalledWith(2, {
475
+ operationType: hooks.OperationType.AfterUpdate,
476
+ ids: [],
477
+ originalObjects: [],
478
+ })
479
+ })
480
+
481
+ it('should call hooks on createObject', async () => {
482
+ mockCreateObject.mockResolvedValue({ id: 'id' } as never)
483
+
484
+ const databaseController = new DatabaseController(mockAdapter() as any)
485
+
486
+ await databaseController.createObject({
487
+ className: 'TestClass',
488
+ context,
489
+ data: { name: 'test' },
490
+ select: { id: true },
491
+ })
492
+
493
+ expect(mockInitializeHook).toHaveBeenCalledTimes(2)
494
+ expect(mockInitializeHook).toHaveBeenCalledWith({
495
+ className: 'TestClass',
496
+ context: {
497
+ sessionId: 'sessionId',
498
+ wabe: { config },
499
+ isRoot: true,
500
+ },
501
+ newData: { name: 'test' },
502
+ select: { id: true },
503
+ })
504
+
505
+ expect(mockRunOnSingleObject).toHaveBeenCalledTimes(4)
506
+ expect(mockRunOnSingleObject).toHaveBeenNthCalledWith(1, {
507
+ operationType: hooks.OperationType.BeforeCreate,
508
+ })
509
+ expect(mockRunOnSingleObject).toHaveBeenNthCalledWith(2, {
510
+ operationType: hooks.OperationType.AfterCreate,
511
+ id: 'id',
512
+ })
513
+ })
514
+
515
+ it('should call hooks on createObjects', async () => {
516
+ mockGetObjects.mockResolvedValue([{ id: 'id' }] as never)
517
+ mockCreateObjects.mockResolvedValue([{ id: 'id' }] as never)
518
+ mockRunOnMultipleObject.mockResolvedValue({
519
+ objects: [],
520
+ newData: [{ name: 'test' }],
521
+ } as never)
522
+
523
+ const databaseController = new DatabaseController(mockAdapter() as any)
524
+
525
+ await databaseController.createObjects({
526
+ className: 'TestClass',
527
+ context,
528
+ data: [{ name: 'test' }],
529
+ select: { id: true },
530
+ })
531
+
532
+ expect(mockInitializeHook).toHaveBeenCalledTimes(2)
533
+ expect(mockInitializeHook).toHaveBeenCalledWith({
534
+ className: 'TestClass',
535
+ context: {
536
+ sessionId: 'sessionId',
537
+ wabe: { config },
538
+ isRoot: true,
539
+ },
540
+ newData: { name: 'test' },
541
+ select: { id: true },
542
+ })
543
+
544
+ expect(mockRunOnMultipleObject).toHaveBeenCalledTimes(4)
545
+ expect(mockRunOnMultipleObject).toHaveBeenNthCalledWith(1, {
546
+ operationType: hooks.OperationType.BeforeCreate,
547
+ })
548
+ expect(mockRunOnMultipleObject).toHaveBeenNthCalledWith(2, {
549
+ operationType: hooks.OperationType.AfterCreate,
550
+ ids: ['id'],
551
+ })
552
+
553
+ mockRunOnMultipleObject.mockClear()
554
+ })
555
+
556
+ it('should call hooks on deleteObject', async () => {
557
+ const databaseController = new DatabaseController(mockAdapter() as any)
558
+
559
+ await databaseController.deleteObject({
560
+ className: 'TestClass',
561
+ context,
562
+ select: { id: true },
563
+ id: 'id',
564
+ })
565
+
566
+ expect(mockInitializeHook).toHaveBeenCalledTimes(2)
567
+ expect(mockInitializeHook).toHaveBeenCalledWith({
568
+ className: 'TestClass',
569
+ context: {
570
+ sessionId: 'sessionId',
571
+ wabe: { config },
572
+ isRoot: true,
573
+ },
574
+ select: { id: true },
575
+ })
576
+
577
+ // 4 because we have a getObject before the delete
578
+ expect(mockRunOnSingleObject).toHaveBeenCalledTimes(4)
579
+ expect(mockRunOnSingleObject).toHaveBeenNthCalledWith(3, {
580
+ operationType: hooks.OperationType.BeforeDelete,
581
+ id: 'id',
582
+ })
583
+ expect(mockRunOnSingleObject).toHaveBeenNthCalledWith(4, {
584
+ operationType: hooks.OperationType.AfterDelete,
585
+ object: undefined, // Because we don't mock deleteObject in databaseController
586
+ })
587
+ })
588
+
589
+ it('should call hooks on deleteObjects', async () => {
590
+ mockGetObjects.mockResolvedValue([{ id: 'id' }] as never)
591
+ mockRunOnMultipleObject.mockResolvedValue({} as never)
592
+
593
+ const databaseController = new DatabaseController(mockAdapter() as any)
594
+
595
+ await databaseController.deleteObjects({
596
+ className: 'TestClass',
597
+ context,
598
+ where: { id: { equalTo: 'id' } },
599
+ select: { id: true },
600
+ })
601
+
602
+ expect(mockInitializeHook).toHaveBeenCalledTimes(2)
603
+ expect(mockInitializeHook).toHaveBeenCalledWith({
604
+ className: 'TestClass',
605
+ context: {
606
+ sessionId: 'sessionId',
607
+ wabe: { config },
608
+ isRoot: true,
609
+ },
610
+ select: { id: true },
611
+ })
612
+
613
+ // 4 because we have a getObject before the delete
614
+ expect(mockRunOnMultipleObject).toHaveBeenCalledTimes(4)
615
+ expect(mockRunOnMultipleObject).toHaveBeenNthCalledWith(3, {
616
+ operationType: hooks.OperationType.BeforeDelete,
617
+ where: { id: { equalTo: 'id' } },
618
+ })
619
+ expect(mockRunOnMultipleObject).toHaveBeenNthCalledWith(4, {
620
+ operationType: hooks.OperationType.AfterDelete,
621
+ })
622
+
623
+ mockRunOnMultipleObject.mockClear()
624
+ })
625
+ })