wabe 0.6.9 → 0.6.11

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 (162) hide show
  1. package/README.md +156 -50
  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/cron/index.d.ts +0 -1
  7. package/dist/database/DatabaseController.d.ts +41 -13
  8. package/dist/database/interface.d.ts +1 -0
  9. package/dist/email/DevAdapter.d.ts +0 -1
  10. package/dist/email/interface.d.ts +1 -1
  11. package/dist/graphql/resolvers.d.ts +4 -2
  12. package/dist/hooks/index.d.ts +8 -2
  13. package/dist/index.d.ts +0 -1
  14. package/dist/index.js +32144 -32058
  15. package/dist/schema/Schema.d.ts +2 -1
  16. package/dist/server/index.d.ts +4 -2
  17. package/dist/utils/crypto.d.ts +7 -0
  18. package/dist/utils/helper.d.ts +5 -1
  19. package/generated/schema.graphql +22 -14
  20. package/generated/wabe.ts +4 -4
  21. package/package.json +23 -23
  22. package/src/authentication/OTP.test.ts +69 -0
  23. package/src/authentication/OTP.ts +64 -0
  24. package/src/authentication/Session.test.ts +629 -0
  25. package/src/authentication/Session.ts +493 -0
  26. package/src/authentication/defaultAuthentication.ts +209 -0
  27. package/src/authentication/index.ts +3 -0
  28. package/src/authentication/interface.ts +155 -0
  29. package/src/authentication/oauth/GitHub.test.ts +91 -0
  30. package/src/authentication/oauth/GitHub.ts +121 -0
  31. package/src/authentication/oauth/Google.test.ts +91 -0
  32. package/src/authentication/oauth/Google.ts +101 -0
  33. package/src/authentication/oauth/Oauth2Client.test.ts +219 -0
  34. package/src/authentication/oauth/Oauth2Client.ts +135 -0
  35. package/src/authentication/oauth/index.ts +2 -0
  36. package/src/authentication/oauth/utils.test.ts +33 -0
  37. package/src/authentication/oauth/utils.ts +27 -0
  38. package/src/authentication/providers/EmailOTP.test.ts +127 -0
  39. package/src/authentication/providers/EmailOTP.ts +84 -0
  40. package/src/authentication/providers/EmailPassword.test.ts +176 -0
  41. package/src/authentication/providers/EmailPassword.ts +116 -0
  42. package/src/authentication/providers/EmailPasswordSRP.test.ts +208 -0
  43. package/src/authentication/providers/EmailPasswordSRP.ts +179 -0
  44. package/src/authentication/providers/GitHub.ts +24 -0
  45. package/src/authentication/providers/Google.ts +24 -0
  46. package/src/authentication/providers/OAuth.test.ts +185 -0
  47. package/src/authentication/providers/OAuth.ts +106 -0
  48. package/src/authentication/providers/PhonePassword.test.ts +176 -0
  49. package/src/authentication/providers/PhonePassword.ts +115 -0
  50. package/src/authentication/providers/QRCodeOTP.test.ts +77 -0
  51. package/src/authentication/providers/QRCodeOTP.ts +58 -0
  52. package/src/authentication/providers/index.ts +6 -0
  53. package/src/authentication/resolvers/refreshResolver.test.ts +30 -0
  54. package/src/authentication/resolvers/refreshResolver.ts +19 -0
  55. package/src/authentication/resolvers/signInWithResolver.inte.test.ts +59 -0
  56. package/src/authentication/resolvers/signInWithResolver.test.ts +293 -0
  57. package/src/authentication/resolvers/signInWithResolver.ts +92 -0
  58. package/src/authentication/resolvers/signOutResolver.test.ts +38 -0
  59. package/src/authentication/resolvers/signOutResolver.ts +18 -0
  60. package/src/authentication/resolvers/signUpWithResolver.test.ts +180 -0
  61. package/src/authentication/resolvers/signUpWithResolver.ts +65 -0
  62. package/src/authentication/resolvers/verifyChallenge.test.ts +133 -0
  63. package/src/authentication/resolvers/verifyChallenge.ts +62 -0
  64. package/src/authentication/roles.test.ts +49 -0
  65. package/src/authentication/roles.ts +40 -0
  66. package/src/authentication/utils.test.ts +97 -0
  67. package/src/authentication/utils.ts +39 -0
  68. package/src/cache/InMemoryCache.test.ts +62 -0
  69. package/src/cache/InMemoryCache.ts +45 -0
  70. package/src/cron/index.test.ts +17 -0
  71. package/src/cron/index.ts +43 -0
  72. package/src/database/DatabaseController.test.ts +613 -0
  73. package/src/database/DatabaseController.ts +1007 -0
  74. package/src/database/index.test.ts +1372 -0
  75. package/src/database/index.ts +9 -0
  76. package/src/database/interface.ts +302 -0
  77. package/src/email/DevAdapter.ts +7 -0
  78. package/src/email/EmailController.test.ts +29 -0
  79. package/src/email/EmailController.ts +13 -0
  80. package/src/email/index.ts +2 -0
  81. package/src/email/interface.ts +36 -0
  82. package/src/email/templates/sendOtpCode.ts +120 -0
  83. package/src/file/FileController.ts +28 -0
  84. package/src/file/FileDevAdapter.ts +51 -0
  85. package/src/file/hookDeleteFile.ts +25 -0
  86. package/src/file/hookReadFile.ts +66 -0
  87. package/src/file/hookUploadFile.ts +50 -0
  88. package/src/file/index.test.ts +932 -0
  89. package/src/file/index.ts +2 -0
  90. package/src/file/interface.ts +39 -0
  91. package/src/graphql/GraphQLSchema.test.ts +4408 -0
  92. package/src/graphql/GraphQLSchema.ts +880 -0
  93. package/src/graphql/index.ts +2 -0
  94. package/src/graphql/parseGraphqlSchema.ts +85 -0
  95. package/src/graphql/parser.test.ts +203 -0
  96. package/src/graphql/parser.ts +542 -0
  97. package/src/graphql/pointerAndRelationFunction.ts +191 -0
  98. package/src/graphql/resolvers.ts +442 -0
  99. package/src/graphql/tests/aggregation.test.ts +1115 -0
  100. package/src/graphql/tests/e2e.test.ts +590 -0
  101. package/src/graphql/tests/scalars.test.ts +250 -0
  102. package/src/graphql/types.ts +227 -0
  103. package/src/hooks/HookObject.test.ts +122 -0
  104. package/src/hooks/HookObject.ts +165 -0
  105. package/src/hooks/authentication.ts +67 -0
  106. package/src/hooks/createUser.test.ts +77 -0
  107. package/src/hooks/createUser.ts +10 -0
  108. package/src/hooks/defaultFields.test.ts +176 -0
  109. package/src/hooks/defaultFields.ts +32 -0
  110. package/src/hooks/deleteSession.test.ts +181 -0
  111. package/src/hooks/deleteSession.ts +20 -0
  112. package/src/hooks/hashFieldHook.test.ts +152 -0
  113. package/src/hooks/hashFieldHook.ts +89 -0
  114. package/src/hooks/index.test.ts +258 -0
  115. package/src/hooks/index.ts +414 -0
  116. package/src/hooks/permissions.test.ts +412 -0
  117. package/src/hooks/permissions.ts +93 -0
  118. package/src/hooks/protected.test.ts +551 -0
  119. package/src/hooks/protected.ts +60 -0
  120. package/src/hooks/searchableFields.test.ts +147 -0
  121. package/src/hooks/searchableFields.ts +86 -0
  122. package/src/hooks/session.test.ts +134 -0
  123. package/src/hooks/session.ts +76 -0
  124. package/src/hooks/setEmail.test.ts +216 -0
  125. package/src/hooks/setEmail.ts +33 -0
  126. package/src/hooks/setupAcl.test.ts +618 -0
  127. package/src/hooks/setupAcl.ts +25 -0
  128. package/src/index.ts +9 -0
  129. package/src/schema/Schema.test.ts +482 -0
  130. package/src/schema/Schema.ts +757 -0
  131. package/src/schema/defaultResolvers.ts +93 -0
  132. package/src/schema/index.ts +1 -0
  133. package/src/schema/resolvers/meResolver.test.ts +62 -0
  134. package/src/schema/resolvers/meResolver.ts +10 -0
  135. package/src/schema/resolvers/resetPassword.test.ts +341 -0
  136. package/src/schema/resolvers/resetPassword.ts +63 -0
  137. package/src/schema/resolvers/sendEmail.test.ts +118 -0
  138. package/src/schema/resolvers/sendEmail.ts +21 -0
  139. package/src/schema/resolvers/sendOtpCode.test.ts +141 -0
  140. package/src/schema/resolvers/sendOtpCode.ts +52 -0
  141. package/src/security.test.ts +3434 -0
  142. package/src/server/defaultSessionHandler.test.ts +62 -0
  143. package/src/server/defaultSessionHandler.ts +105 -0
  144. package/src/server/generateCodegen.ts +433 -0
  145. package/src/server/index.test.ts +532 -0
  146. package/src/server/index.ts +334 -0
  147. package/src/server/interface.ts +11 -0
  148. package/src/server/routes/authHandler.ts +169 -0
  149. package/src/server/routes/index.ts +39 -0
  150. package/src/utils/crypto.test.ts +41 -0
  151. package/src/utils/crypto.ts +105 -0
  152. package/src/utils/export.ts +11 -0
  153. package/src/utils/helper.ts +204 -0
  154. package/src/utils/index.test.ts +11 -0
  155. package/src/utils/index.ts +189 -0
  156. package/src/utils/preload.ts +8 -0
  157. package/src/utils/testHelper.ts +116 -0
  158. package/tsconfig.json +32 -0
  159. package/bunfig.toml +0 -4
  160. package/dist/ai/index.d.ts +0 -1
  161. package/dist/ai/interface.d.ts +0 -9
  162. /package/dist/server/{defaultHandlers.d.ts → defaultSessionHandler.d.ts} +0 -0
@@ -0,0 +1,542 @@
1
+ import {
2
+ GraphQLBoolean,
3
+ type GraphQLEnumType,
4
+ type GraphQLFieldConfig,
5
+ GraphQLFloat,
6
+ GraphQLInputObjectType,
7
+ GraphQLInt,
8
+ GraphQLList,
9
+ GraphQLNonNull,
10
+ GraphQLObjectType,
11
+ type GraphQLScalarType,
12
+ GraphQLString,
13
+ } from 'graphql'
14
+ import {
15
+ type AllObjects,
16
+ AnyWhereInput,
17
+ ArrayWhereInput,
18
+ BooleanWhereInput,
19
+ DateScalarType,
20
+ DateWhereInput,
21
+ EmailScalarType,
22
+ EmailWhereInput,
23
+ FileScalarType,
24
+ FileWhereInput,
25
+ FloatWhereInput,
26
+ IntWhereInput,
27
+ PhoneScalarType,
28
+ PhoneWhereInput,
29
+ StringWhereInput,
30
+ } from '../graphql'
31
+ import type { ClassInterface, SchemaFields, WabePrimaryTypes } from '../schema'
32
+ import type { WabeTypes } from '../server'
33
+ import type { DevWabeTypes } from '../utils/helper'
34
+
35
+ type GraphqlObjectType =
36
+ | 'Object'
37
+ | 'InputObject'
38
+ | 'CreateFieldsInput'
39
+ | 'UpdateFieldsInput'
40
+ | 'WhereInputObject'
41
+
42
+ type ParseObjectOptions = {
43
+ required?: boolean
44
+ description?: string
45
+ objectToParse: ClassInterface<any>
46
+ nameOfTheObject: string
47
+ }
48
+
49
+ type ParseObjectCallback = (options: ParseObjectOptions) => any
50
+
51
+ export const templateScalarType: Record<WabePrimaryTypes, GraphQLScalarType> = {
52
+ String: GraphQLString,
53
+ Int: GraphQLInt,
54
+ Float: GraphQLFloat,
55
+ Boolean: GraphQLBoolean,
56
+ Date: DateScalarType,
57
+ Email: EmailScalarType,
58
+ File: FileScalarType,
59
+ Phone: PhoneScalarType,
60
+ Hash: GraphQLString,
61
+ }
62
+
63
+ export const templateWhereInput: Record<WabePrimaryTypes | 'Array', GraphQLInputObjectType> = {
64
+ String: StringWhereInput,
65
+ Int: IntWhereInput,
66
+ Float: FloatWhereInput,
67
+ Boolean: BooleanWhereInput,
68
+ Date: DateWhereInput,
69
+ Email: EmailWhereInput,
70
+ Phone: PhoneWhereInput,
71
+ Array: ArrayWhereInput,
72
+ File: FileWhereInput,
73
+ Hash: StringWhereInput,
74
+ }
75
+
76
+ interface GraphqlParserFactoryOptions {
77
+ graphqlObjectType: GraphqlObjectType
78
+ allObjects: AllObjects
79
+ schemaFields: SchemaFields<DevWabeTypes>
80
+ }
81
+
82
+ interface GraphqlParserConstructorOptions {
83
+ scalars: GraphQLScalarType[]
84
+ enums: GraphQLEnumType[]
85
+ }
86
+
87
+ export type GraphqlParserFactory<T extends WabeTypes> = (options: GraphqlParserFactoryOptions) => {
88
+ _parseWabeObject(options: ParseObjectOptions): any
89
+ _parseWabeWhereInputObject(options: ParseObjectOptions): any
90
+ _parseWabeInputObject(options: ParseObjectOptions): any
91
+ _parseWabeUpdateInputObject(options: ParseObjectOptions): any
92
+ getGraphqlType(options: {
93
+ type: WabePrimaryTypes | 'Array' | T['enums'] | T['scalars']
94
+ typeValue?: WabePrimaryTypes
95
+ isWhereType?: boolean
96
+ }): any
97
+ getGraphqlFields(nameOfTheObject: string): any
98
+ }
99
+
100
+ export type GraphqlParserConstructor = <T extends WabeTypes>(
101
+ options: GraphqlParserConstructorOptions,
102
+ ) => GraphqlParserFactory<T>
103
+
104
+ export const GraphqlParser: GraphqlParserConstructor =
105
+ ({ scalars, enums }: GraphqlParserConstructorOptions) =>
106
+ ({ graphqlObjectType, schemaFields, allObjects }: GraphqlParserFactoryOptions) => {
107
+ // Get graphql fields from a wabe object
108
+ const _getGraphqlFieldsFromAnObject = ({
109
+ objectToParse,
110
+ callBackForObjectType,
111
+ forceRequiredToFalse = false,
112
+ isWhereType = false,
113
+ nameOfTheObject,
114
+ }: {
115
+ objectToParse: ClassInterface<DevWabeTypes>
116
+ forceRequiredToFalse?: boolean
117
+ isWhereType?: boolean
118
+ callBackForObjectType: ParseObjectCallback
119
+ nameOfTheObject: string
120
+ }) => {
121
+ const fields = objectToParse.fields
122
+
123
+ const graphqlFields = Object.keys(fields).reduce(
124
+ (acc, key) => {
125
+ const currentField = fields[key]
126
+
127
+ const keyWithFirstLetterUppercase = `${key.charAt(0).toUpperCase()}${key.slice(1)}`
128
+
129
+ if (currentField?.type === 'Object') {
130
+ acc[key] = {
131
+ type: callBackForObjectType({
132
+ required: currentField.object.required,
133
+ description: currentField.description,
134
+ objectToParse: currentField.object,
135
+ nameOfTheObject: `${nameOfTheObject}${keyWithFirstLetterUppercase}`,
136
+ }),
137
+ }
138
+
139
+ return acc
140
+ }
141
+
142
+ if (currentField?.type === 'Array') {
143
+ if (currentField?.typeValue === 'Object') {
144
+ const objectList = new GraphQLList(
145
+ callBackForObjectType({
146
+ required: currentField.object.required,
147
+ description: currentField.description,
148
+ objectToParse: currentField.object,
149
+ nameOfTheObject: `${nameOfTheObject}${currentField.object.name}`,
150
+ }),
151
+ )
152
+
153
+ acc[key] = {
154
+ type: currentField.required ? new GraphQLNonNull(objectList) : objectList,
155
+ }
156
+ }
157
+
158
+ if (
159
+ currentField.typeValue &&
160
+ // @ts-expect-error
161
+ templateScalarType[currentField.typeValue]
162
+ ) {
163
+ const graphqlType = getGraphqlType({
164
+ type: currentField.type,
165
+ // @ts-expect-error
166
+ typeValue: currentField.typeValue,
167
+ isWhereType,
168
+ requiredValue: currentField.requiredValue,
169
+ })
170
+
171
+ acc[key] = {
172
+ type:
173
+ currentField.required && !forceRequiredToFalse
174
+ ? new GraphQLNonNull(graphqlType)
175
+ : graphqlType,
176
+ }
177
+ }
178
+
179
+ return acc
180
+ }
181
+
182
+ const graphqlType = getGraphqlType({
183
+ ...currentField,
184
+ // We never come here, complicated to good type this
185
+ type: currentField?.type as WabePrimaryTypes,
186
+ isWhereType,
187
+ })
188
+
189
+ acc[key] = {
190
+ type:
191
+ currentField?.required && !forceRequiredToFalse
192
+ ? new GraphQLNonNull(graphqlType)
193
+ : graphqlType,
194
+ }
195
+
196
+ return acc
197
+ },
198
+ {} as Record<string, any>,
199
+ )
200
+
201
+ return graphqlFields
202
+ }
203
+
204
+ // ------------------ Parsers ------------------
205
+
206
+ // Parse simple object
207
+ const _parseWabeObject = ({
208
+ required,
209
+ description,
210
+ objectToParse,
211
+ nameOfTheObject,
212
+ }: ParseObjectOptions) => {
213
+ const graphqlFields = _getGraphqlFieldsFromAnObject({
214
+ objectToParse,
215
+ callBackForObjectType: _parseWabeObject,
216
+ nameOfTheObject,
217
+ })
218
+
219
+ const graphqlObject = new GraphQLObjectType({
220
+ name: nameOfTheObject,
221
+ description: description,
222
+ fields: graphqlFields,
223
+ })
224
+
225
+ return required ? new GraphQLNonNull(graphqlObject) : graphqlObject
226
+ }
227
+
228
+ // Parse input object
229
+ const _parseWabeInputObject = ({
230
+ required,
231
+ description,
232
+ objectToParse,
233
+ nameOfTheObject,
234
+ }: ParseObjectOptions) => {
235
+ const graphqlFields = _getGraphqlFieldsFromAnObject({
236
+ objectToParse,
237
+ callBackForObjectType: _parseWabeInputObject,
238
+ nameOfTheObject,
239
+ })
240
+
241
+ const graphqlObject = new GraphQLInputObjectType({
242
+ name: `${nameOfTheObject}Input`,
243
+ description: description,
244
+ fields: graphqlFields,
245
+ })
246
+
247
+ return required ? new GraphQLNonNull(graphqlObject) : graphqlObject
248
+ }
249
+
250
+ // Parse create input object
251
+ const _parseWabeCreateInputObject = ({
252
+ required,
253
+ description,
254
+ objectToParse,
255
+ nameOfTheObject,
256
+ }: ParseObjectOptions) => {
257
+ const graphqlFields = _getGraphqlFieldsFromAnObject({
258
+ objectToParse,
259
+ callBackForObjectType: _parseWabeCreateInputObject,
260
+ forceRequiredToFalse: true,
261
+ nameOfTheObject,
262
+ })
263
+
264
+ const graphqlObject = new GraphQLInputObjectType({
265
+ name: `${nameOfTheObject}CreateFieldsInput`,
266
+ description: description,
267
+ fields: graphqlFields,
268
+ })
269
+
270
+ return required ? new GraphQLNonNull(graphqlObject) : graphqlObject
271
+ }
272
+
273
+ // Parse update input object
274
+ const _parseWabeUpdateInputObject = ({
275
+ required,
276
+ description,
277
+ objectToParse,
278
+ nameOfTheObject,
279
+ }: ParseObjectOptions) => {
280
+ const graphqlFields = _getGraphqlFieldsFromAnObject({
281
+ objectToParse,
282
+ callBackForObjectType: _parseWabeUpdateInputObject,
283
+ forceRequiredToFalse: true,
284
+ nameOfTheObject,
285
+ })
286
+
287
+ const graphqlObject = new GraphQLInputObjectType({
288
+ name: `${nameOfTheObject}UpdateFieldsInput`,
289
+ description: description,
290
+ fields: graphqlFields,
291
+ })
292
+
293
+ return required ? new GraphQLNonNull(graphqlObject) : graphqlObject
294
+ }
295
+
296
+ // Parse where input object
297
+ const _parseWabeWhereInputObject = ({
298
+ required,
299
+ description,
300
+ objectToParse,
301
+ nameOfTheObject,
302
+ }: ParseObjectOptions) => {
303
+ const graphqlFields = _getGraphqlFieldsFromAnObject({
304
+ objectToParse,
305
+ callBackForObjectType: _parseWabeWhereInputObject,
306
+ forceRequiredToFalse: true,
307
+ isWhereType: true,
308
+ nameOfTheObject,
309
+ })
310
+
311
+ const graphqlObject = new GraphQLInputObjectType({
312
+ name: `${nameOfTheObject}WhereInput`,
313
+ description: description,
314
+ fields: (): any => ({
315
+ ...graphqlFields,
316
+ OR: {
317
+ type: new GraphQLList(graphqlObject),
318
+ },
319
+ AND: {
320
+ type: new GraphQLList(graphqlObject),
321
+ },
322
+ }),
323
+ })
324
+
325
+ return required ? new GraphQLNonNull(graphqlObject) : graphqlObject
326
+ }
327
+
328
+ const _graphqlObjectFactory: Record<
329
+ GraphqlObjectType,
330
+ {
331
+ callback: ParseObjectCallback
332
+ isWhereType: boolean
333
+ forceRequiredToFalse: boolean
334
+ }
335
+ > = {
336
+ Object: {
337
+ callback: _parseWabeObject,
338
+ isWhereType: false,
339
+ forceRequiredToFalse: false,
340
+ },
341
+ InputObject: {
342
+ callback: _parseWabeInputObject,
343
+ isWhereType: false,
344
+ forceRequiredToFalse: false,
345
+ },
346
+ CreateFieldsInput: {
347
+ callback: _parseWabeCreateInputObject,
348
+ isWhereType: false,
349
+ forceRequiredToFalse: true,
350
+ },
351
+ UpdateFieldsInput: {
352
+ callback: _parseWabeUpdateInputObject,
353
+ isWhereType: false,
354
+ forceRequiredToFalse: true,
355
+ },
356
+ WhereInputObject: {
357
+ callback: _parseWabeWhereInputObject,
358
+ isWhereType: true,
359
+ forceRequiredToFalse: true,
360
+ },
361
+ }
362
+
363
+ // Get the good graphql type for a field
364
+ const getGraphqlType = ({
365
+ type,
366
+ typeValue,
367
+ requiredValue,
368
+ isWhereType = false,
369
+ }: {
370
+ type: WabePrimaryTypes | 'Array' | keyof WabeTypes['enums'] | WabeTypes['scalars']
371
+ typeValue?: WabePrimaryTypes
372
+ requiredValue?: boolean
373
+ isWhereType?: boolean
374
+ }) => {
375
+ const scalarExist = scalars.find((scalar) => scalar.name === type)
376
+
377
+ const enumExist = enums.find((e) => e.name === type)
378
+
379
+ if (isWhereType) {
380
+ if (!Object.keys(templateWhereInput).includes(type)) return AnyWhereInput
381
+
382
+ return templateWhereInput[type as WabePrimaryTypes]
383
+ }
384
+
385
+ if (scalarExist) return scalarExist
386
+ if (enumExist) return enumExist
387
+
388
+ const graphqlType =
389
+ type === 'Array' && typeValue
390
+ ? new GraphQLList(
391
+ requiredValue
392
+ ? new GraphQLNonNull(templateScalarType[typeValue])
393
+ : templateScalarType[typeValue],
394
+ )
395
+ : // @ts-expect-error
396
+ templateScalarType[type]
397
+
398
+ if (!graphqlType) throw new Error(`${type} not exist in schema`)
399
+
400
+ return graphqlType
401
+ }
402
+
403
+ // Get Graphql object from a schema fields passed in WabeGraphqlParser
404
+ const getGraphqlFields = (nameOfTheObject: string) => {
405
+ const { callback, forceRequiredToFalse, isWhereType } =
406
+ _graphqlObjectFactory[graphqlObjectType]
407
+
408
+ const keysOfObject = Object.keys(schemaFields)
409
+
410
+ const rawFields = keysOfObject.reduce(
411
+ (acc, key) => {
412
+ const currentField = schemaFields[key]
413
+
414
+ const isRelation = currentField?.type === 'Relation'
415
+ const isPointer = currentField?.type === 'Pointer'
416
+
417
+ if (isRelation || isPointer) {
418
+ const graphqlObject = allObjects[currentField.class]
419
+
420
+ switch (graphqlObjectType) {
421
+ case 'Object': {
422
+ acc[key] = {
423
+ type: isRelation ? graphqlObject?.connectionObject : graphqlObject?.object,
424
+ }
425
+
426
+ break
427
+ }
428
+ case 'UpdateFieldsInput':
429
+ case 'CreateFieldsInput':
430
+ case 'InputObject': {
431
+ acc[key] = {
432
+ type: isRelation
433
+ ? graphqlObject?.relationInputObject
434
+ : graphqlObject?.pointerInputObject,
435
+ }
436
+
437
+ break
438
+ }
439
+ case 'WhereInputObject': {
440
+ acc[key] = {
441
+ type: allObjects[currentField.class]?.whereInputObject,
442
+ }
443
+
444
+ break
445
+ }
446
+ }
447
+
448
+ return acc
449
+ }
450
+
451
+ if (currentField?.type === 'File') {
452
+ if (graphqlObjectType === 'Object')
453
+ acc[key] = {
454
+ type: currentField.required
455
+ ? new GraphQLNonNull(allObjects.FileInfo?.object)
456
+ : allObjects.FileInfo?.object,
457
+ }
458
+
459
+ if (
460
+ graphqlObjectType === 'CreateFieldsInput' ||
461
+ graphqlObjectType === 'UpdateFieldsInput'
462
+ ) {
463
+ acc[key] = {
464
+ type: currentField.required
465
+ ? new GraphQLNonNull(allObjects.FileInfo?.inputObject)
466
+ : allObjects.FileInfo?.inputObject,
467
+ }
468
+ }
469
+
470
+ return acc
471
+ }
472
+
473
+ if (currentField?.type === 'Object') {
474
+ acc[key] = {
475
+ type: callback({
476
+ ...currentField,
477
+ objectToParse: currentField.object,
478
+ nameOfTheObject: `${nameOfTheObject}${currentField.object.name}`,
479
+ }),
480
+ }
481
+
482
+ return acc
483
+ }
484
+
485
+ if (currentField?.type === 'Array') {
486
+ if (currentField.typeValue === 'Object') {
487
+ const objectList = new GraphQLList(
488
+ callback({
489
+ ...currentField,
490
+ required: currentField.object.required,
491
+ objectToParse: currentField.object,
492
+ nameOfTheObject: `${nameOfTheObject}${currentField.object.name}`,
493
+ }),
494
+ )
495
+
496
+ acc[key] = {
497
+ type: currentField.required ? new GraphQLNonNull(objectList) : objectList,
498
+ }
499
+
500
+ return acc
501
+ }
502
+ }
503
+
504
+ const graphqlType = getGraphqlType({
505
+ ...currentField,
506
+ type: currentField?.type,
507
+ isWhereType,
508
+ })
509
+
510
+ acc[key] = {
511
+ type:
512
+ currentField?.required && !forceRequiredToFalse
513
+ ? new GraphQLNonNull(graphqlType)
514
+ : graphqlType,
515
+ }
516
+
517
+ return acc
518
+ },
519
+ {} as Record<string, any>,
520
+ )
521
+
522
+ return Object.keys(rawFields).reduce(
523
+ (acc, key) => {
524
+ const field = rawFields[key]
525
+
526
+ acc[key] = field
527
+
528
+ return acc
529
+ },
530
+ {} as Record<string, GraphQLFieldConfig<any, any, any>>,
531
+ )
532
+ }
533
+
534
+ return {
535
+ getGraphqlType,
536
+ getGraphqlFields,
537
+ _parseWabeObject,
538
+ _parseWabeInputObject,
539
+ _parseWabeUpdateInputObject,
540
+ _parseWabeWhereInputObject,
541
+ }
542
+ }
@@ -0,0 +1,191 @@
1
+ import { getClassFromClassName } from '../utils'
2
+ import type { WabeContext } from '../server/interface'
3
+ import { notEmpty } from '../utils/export'
4
+
5
+ type CreateAndLink = any
6
+ type Link = string
7
+ type Unlink = boolean
8
+ type Add = Array<string>
9
+ type Remove = Array<string>
10
+ type CreateAndAdd = Array<any>
11
+
12
+ export type TypeOfExecution = 'create' | 'update' | 'updateMany'
13
+
14
+ export type InputFields = Record<
15
+ string,
16
+ | {
17
+ createAndLink?: CreateAndLink
18
+ link?: Link
19
+ unlink?: Unlink
20
+ add?: Add
21
+ remove?: Remove
22
+ createAndAdd?: CreateAndAdd
23
+ }
24
+ | string
25
+ >
26
+
27
+ export const createAndLink = async ({
28
+ createAndLink,
29
+ context,
30
+ fieldName,
31
+ className,
32
+ }: {
33
+ createAndLink: CreateAndLink
34
+ fieldName: string
35
+ context: WabeContext<any>
36
+ className: string
37
+ }) => {
38
+ const classInSchema = getClassFromClassName(className, context.wabe.config)
39
+
40
+ const res = await context.wabe.controllers.database.createObject({
41
+ // @ts-expect-error
42
+ className: classInSchema.fields[fieldName].class,
43
+ data: createAndLink,
44
+ select: { id: true },
45
+ context,
46
+ })
47
+
48
+ return res?.id
49
+ }
50
+
51
+ export const createAndAdd = async ({
52
+ createAndAdd,
53
+ context,
54
+ fieldName,
55
+ className,
56
+ }: {
57
+ createAndAdd: CreateAndAdd
58
+ fieldName: string
59
+ context: WabeContext<any>
60
+ className: string
61
+ }) => {
62
+ const classInSchema = getClassFromClassName(className, context.wabe.config)
63
+
64
+ const result = await context.wabe.controllers.database.createObjects({
65
+ // @ts-expect-error
66
+ className: classInSchema.fields[fieldName].class,
67
+ data: createAndAdd,
68
+ select: { id: true },
69
+ context,
70
+ })
71
+
72
+ return result.map((object: any) => object.id)
73
+ }
74
+
75
+ export const add = async ({
76
+ add,
77
+ context,
78
+ fieldName,
79
+ typeOfExecution,
80
+ id,
81
+ className,
82
+ where,
83
+ }: {
84
+ add: Add
85
+ fieldName: string
86
+ context: WabeContext<any>
87
+ typeOfExecution: TypeOfExecution
88
+ id?: string
89
+ className: string
90
+ where: any
91
+ }) => {
92
+ if (typeOfExecution === 'create') return add
93
+
94
+ if (typeOfExecution === 'update' && id) {
95
+ const currentValue = await context.wabe.controllers.database.getObject({
96
+ className,
97
+ id,
98
+ select: { [fieldName]: true },
99
+ context,
100
+ })
101
+
102
+ const currentValueIds = currentValue?.[fieldName]?.map((object: any) => object.id) || []
103
+
104
+ return [...currentValueIds, ...add].filter(notEmpty)
105
+ }
106
+
107
+ // For update many we need to get all objects that match the where and add the new value
108
+ // So we doesn't update the field for updateMany
109
+ if (typeOfExecution === 'updateMany' && where) {
110
+ const allObjectsMatchedWithWhere = await context.wabe.controllers.database.getObjects({
111
+ className,
112
+ where,
113
+ select: { [fieldName]: true },
114
+ context,
115
+ })
116
+
117
+ return Promise.all(
118
+ allObjectsMatchedWithWhere.flatMap((object: any) => {
119
+ const currentValueIds = object[fieldName]?.map((object: any) => object.id) || []
120
+
121
+ return [...currentValueIds, ...add]
122
+ }),
123
+ )
124
+ }
125
+ }
126
+
127
+ export const remove = async ({
128
+ remove,
129
+ context,
130
+ fieldName,
131
+ typeOfExecution,
132
+ id,
133
+ className,
134
+ where,
135
+ }: {
136
+ remove: Remove
137
+ fieldName: string
138
+ context: WabeContext<any>
139
+ typeOfExecution: TypeOfExecution
140
+ id?: string
141
+ className: string
142
+ where: any
143
+ }) => {
144
+ if (typeOfExecution === 'create') return []
145
+
146
+ const classInSchema = getClassFromClassName(className, context.wabe.config)
147
+
148
+ if (typeOfExecution === 'update' && id) {
149
+ const currentValue = await context.wabe.controllers.database.getObject({
150
+ className,
151
+ id,
152
+ select: { [fieldName]: true },
153
+ context,
154
+ })
155
+
156
+ const olderValuesIds = currentValue?.[fieldName]?.map((object: any) => object.id) || []
157
+
158
+ await context.wabe.controllers.database.deleteObjects({
159
+ // @ts-expect-error
160
+ className: classInSchema.fields[fieldName].class,
161
+ where: { id: { in: remove } },
162
+ context,
163
+ select: {},
164
+ })
165
+
166
+ return olderValuesIds.filter((olderValue: any) => !remove.includes(olderValue))
167
+ }
168
+
169
+ if (typeOfExecution === 'updateMany' && where) {
170
+ const allObjectsMatchedWithWhere = await context.wabe.controllers.database.getObjects({
171
+ className,
172
+ where,
173
+ select: { [fieldName]: true },
174
+ context,
175
+ })
176
+
177
+ const olderValuesIds = allObjectsMatchedWithWhere.flatMap(
178
+ (object: any) => object[fieldName]?.map((object: any) => object.id) || [],
179
+ )
180
+
181
+ await context.wabe.controllers.database.deleteObjects({
182
+ // @ts-expect-error
183
+ className: classInSchema.fields[fieldName].class,
184
+ where: { id: { in: remove } },
185
+ context,
186
+ select: {},
187
+ })
188
+
189
+ return olderValuesIds.filter((olderValue: any) => !remove.includes(olderValue))
190
+ }
191
+ }