wabe 0.6.12 → 0.6.14

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 (156) hide show
  1. package/dist/database/DatabaseController.d.ts +2 -0
  2. package/dist/file/FileDevAdapter.d.ts +1 -0
  3. package/dist/graphql/pointerAndRelationFunction.d.ts +6 -0
  4. package/dist/index.js +3827 -3541
  5. package/dist/schema/Schema.d.ts +2 -2
  6. package/dist/server/generateCodegen.d.ts +10 -0
  7. package/dist/server/index.d.ts +2 -1
  8. package/dist/utils/objectKeys.d.ts +1 -0
  9. package/package.json +7 -4
  10. package/dev/index.ts +0 -215
  11. package/dist/schema/resolvers/sendEmail.d.ts +0 -1
  12. package/generated/schema.graphql +0 -1945
  13. package/generated/wabe.ts +0 -448
  14. package/src/authentication/OTP.test.ts +0 -69
  15. package/src/authentication/OTP.ts +0 -64
  16. package/src/authentication/Session.test.ts +0 -629
  17. package/src/authentication/Session.ts +0 -517
  18. package/src/authentication/cookies.ts +0 -10
  19. package/src/authentication/defaultAuthentication.ts +0 -209
  20. package/src/authentication/index.ts +0 -4
  21. package/src/authentication/interface.ts +0 -177
  22. package/src/authentication/oauth/GitHub.test.ts +0 -91
  23. package/src/authentication/oauth/GitHub.ts +0 -121
  24. package/src/authentication/oauth/Google.test.ts +0 -91
  25. package/src/authentication/oauth/Google.ts +0 -101
  26. package/src/authentication/oauth/Oauth2Client.test.ts +0 -219
  27. package/src/authentication/oauth/Oauth2Client.ts +0 -135
  28. package/src/authentication/oauth/index.ts +0 -2
  29. package/src/authentication/oauth/utils.test.ts +0 -33
  30. package/src/authentication/oauth/utils.ts +0 -27
  31. package/src/authentication/providers/EmailOTP.test.ts +0 -127
  32. package/src/authentication/providers/EmailOTP.ts +0 -95
  33. package/src/authentication/providers/EmailPassword.test.ts +0 -263
  34. package/src/authentication/providers/EmailPassword.ts +0 -138
  35. package/src/authentication/providers/EmailPasswordSRP.test.ts +0 -208
  36. package/src/authentication/providers/EmailPasswordSRP.ts +0 -191
  37. package/src/authentication/providers/GitHub.ts +0 -24
  38. package/src/authentication/providers/Google.ts +0 -24
  39. package/src/authentication/providers/OAuth.test.ts +0 -185
  40. package/src/authentication/providers/OAuth.ts +0 -106
  41. package/src/authentication/providers/PhonePassword.test.ts +0 -221
  42. package/src/authentication/providers/PhonePassword.ts +0 -136
  43. package/src/authentication/providers/QRCodeOTP.test.ts +0 -77
  44. package/src/authentication/providers/QRCodeOTP.ts +0 -69
  45. package/src/authentication/providers/index.ts +0 -6
  46. package/src/authentication/resolvers/refreshResolver.test.ts +0 -30
  47. package/src/authentication/resolvers/refreshResolver.ts +0 -19
  48. package/src/authentication/resolvers/signInWithResolver.inte.test.ts +0 -59
  49. package/src/authentication/resolvers/signInWithResolver.test.ts +0 -306
  50. package/src/authentication/resolvers/signInWithResolver.ts +0 -106
  51. package/src/authentication/resolvers/signOutResolver.test.ts +0 -38
  52. package/src/authentication/resolvers/signOutResolver.ts +0 -18
  53. package/src/authentication/resolvers/signUpWithResolver.test.ts +0 -180
  54. package/src/authentication/resolvers/signUpWithResolver.ts +0 -68
  55. package/src/authentication/resolvers/verifyChallenge.test.ts +0 -230
  56. package/src/authentication/resolvers/verifyChallenge.ts +0 -78
  57. package/src/authentication/roles.test.ts +0 -49
  58. package/src/authentication/roles.ts +0 -40
  59. package/src/authentication/security.ts +0 -278
  60. package/src/authentication/utils.test.ts +0 -97
  61. package/src/authentication/utils.ts +0 -39
  62. package/src/cache/InMemoryCache.test.ts +0 -62
  63. package/src/cache/InMemoryCache.ts +0 -45
  64. package/src/cron/index.test.ts +0 -17
  65. package/src/cron/index.ts +0 -43
  66. package/src/database/DatabaseController.test.ts +0 -613
  67. package/src/database/DatabaseController.ts +0 -1415
  68. package/src/database/index.test.ts +0 -1551
  69. package/src/database/index.ts +0 -9
  70. package/src/database/interface.ts +0 -308
  71. package/src/email/DevAdapter.ts +0 -7
  72. package/src/email/EmailController.test.ts +0 -29
  73. package/src/email/EmailController.ts +0 -13
  74. package/src/email/index.ts +0 -2
  75. package/src/email/interface.ts +0 -36
  76. package/src/email/templates/sendOtpCode.ts +0 -120
  77. package/src/file/FileController.ts +0 -28
  78. package/src/file/FileDevAdapter.ts +0 -51
  79. package/src/file/hookDeleteFile.ts +0 -25
  80. package/src/file/hookReadFile.ts +0 -66
  81. package/src/file/hookUploadFile.ts +0 -52
  82. package/src/file/index.test.ts +0 -1031
  83. package/src/file/index.ts +0 -2
  84. package/src/file/interface.ts +0 -63
  85. package/src/file/security.ts +0 -156
  86. package/src/graphql/GraphQLSchema.test.ts +0 -5099
  87. package/src/graphql/GraphQLSchema.ts +0 -886
  88. package/src/graphql/index.ts +0 -2
  89. package/src/graphql/parseGraphqlSchema.ts +0 -85
  90. package/src/graphql/parser.test.ts +0 -203
  91. package/src/graphql/parser.ts +0 -707
  92. package/src/graphql/pointerAndRelationFunction.ts +0 -191
  93. package/src/graphql/resolvers.ts +0 -464
  94. package/src/graphql/tests/aggregation.test.ts +0 -1115
  95. package/src/graphql/tests/e2e.test.ts +0 -590
  96. package/src/graphql/tests/scalars.test.ts +0 -250
  97. package/src/graphql/types.ts +0 -227
  98. package/src/hooks/HookObject.test.ts +0 -122
  99. package/src/hooks/HookObject.ts +0 -165
  100. package/src/hooks/authentication.ts +0 -67
  101. package/src/hooks/createUser.test.ts +0 -77
  102. package/src/hooks/createUser.ts +0 -10
  103. package/src/hooks/defaultFields.test.ts +0 -176
  104. package/src/hooks/defaultFields.ts +0 -32
  105. package/src/hooks/deleteSession.test.ts +0 -181
  106. package/src/hooks/deleteSession.ts +0 -20
  107. package/src/hooks/hashFieldHook.test.ts +0 -152
  108. package/src/hooks/hashFieldHook.ts +0 -89
  109. package/src/hooks/index.test.ts +0 -258
  110. package/src/hooks/index.ts +0 -420
  111. package/src/hooks/permissions.test.ts +0 -412
  112. package/src/hooks/permissions.ts +0 -93
  113. package/src/hooks/protected.test.ts +0 -551
  114. package/src/hooks/protected.ts +0 -74
  115. package/src/hooks/searchableFields.test.ts +0 -147
  116. package/src/hooks/searchableFields.ts +0 -86
  117. package/src/hooks/session.test.ts +0 -134
  118. package/src/hooks/session.ts +0 -76
  119. package/src/hooks/setEmail.test.ts +0 -216
  120. package/src/hooks/setEmail.ts +0 -33
  121. package/src/hooks/setupAcl.test.ts +0 -618
  122. package/src/hooks/setupAcl.ts +0 -25
  123. package/src/hooks/virtualFields.test.ts +0 -228
  124. package/src/hooks/virtualFields.ts +0 -48
  125. package/src/index.ts +0 -9
  126. package/src/schema/Schema.test.ts +0 -482
  127. package/src/schema/Schema.ts +0 -839
  128. package/src/schema/defaultResolvers.ts +0 -93
  129. package/src/schema/index.ts +0 -1
  130. package/src/schema/resolvers/meResolver.test.ts +0 -62
  131. package/src/schema/resolvers/meResolver.ts +0 -10
  132. package/src/schema/resolvers/resetPassword.test.ts +0 -341
  133. package/src/schema/resolvers/resetPassword.ts +0 -63
  134. package/src/schema/resolvers/sendEmail.test.ts +0 -118
  135. package/src/schema/resolvers/sendEmail.ts +0 -21
  136. package/src/schema/resolvers/sendOtpCode.test.ts +0 -141
  137. package/src/schema/resolvers/sendOtpCode.ts +0 -52
  138. package/src/security.test.ts +0 -4136
  139. package/src/server/defaultSessionHandler.test.ts +0 -62
  140. package/src/server/defaultSessionHandler.ts +0 -104
  141. package/src/server/generateCodegen.ts +0 -433
  142. package/src/server/index.test.ts +0 -843
  143. package/src/server/index.ts +0 -336
  144. package/src/server/interface.ts +0 -11
  145. package/src/server/routes/authHandler.ts +0 -171
  146. package/src/server/routes/index.ts +0 -48
  147. package/src/utils/crypto.test.ts +0 -41
  148. package/src/utils/crypto.ts +0 -105
  149. package/src/utils/database.ts +0 -8
  150. package/src/utils/export.ts +0 -12
  151. package/src/utils/helper.ts +0 -204
  152. package/src/utils/index.test.ts +0 -11
  153. package/src/utils/index.ts +0 -196
  154. package/src/utils/preload.ts +0 -8
  155. package/src/utils/testHelper.ts +0 -124
  156. package/tsconfig.json +0 -32
@@ -1,9 +0,0 @@
1
- import type { WabeTypes } from '../server'
2
- import type { DatabaseAdapter } from './interface'
3
-
4
- export interface DatabaseConfig<T extends WabeTypes> {
5
- adapter: DatabaseAdapter<T>
6
- }
7
-
8
- export * from './DatabaseController'
9
- export * from './interface'
@@ -1,308 +0,0 @@
1
- import type { WabeContext } from '../server/interface'
2
- import type { WabeTypes } from '../server'
3
- import type { SchemaInterface } from '../schema'
4
-
5
- type IsScalar<T> = T extends string | number | boolean | Date ? true : false
6
-
7
- type IsArray<T> = T extends Array<any> ? true : false
8
-
9
- type IsObject<T, K extends WabeTypes> = T extends object
10
- ? T extends K['types'][keyof K['types']]
11
- ? false
12
- : true
13
- : false
14
-
15
- type ExtractType<
16
- T extends WabeTypes,
17
- ClassName extends keyof T['types'],
18
- FieldName extends keyof T['types'][ClassName],
19
- > = T['types'][ClassName][FieldName]
20
-
21
- type ExtractWhereType<
22
- T extends WabeTypes,
23
- ClassName extends keyof T['where'],
24
- FieldName extends keyof T['where'][ClassName],
25
- > = T['where'][ClassName][FieldName]
26
-
27
- type WhereScalar<T> = {
28
- equalTo?: T
29
- notEqualTo?: T
30
- greaterThan?: T
31
- lessThan?: T
32
- greaterThanOrEqualTo?: T
33
- lessThanOrEqualTo?: T
34
- in?: T[]
35
- notIn?: T[]
36
- contains?: T
37
- notContains?: T
38
- exists?: boolean
39
- }
40
-
41
- type WhereObject<T> = {
42
- [P in keyof T]: IsScalar<T[P]> extends false ? WhereObject<Partial<T[P]>> : WhereScalar<T[P]>
43
- }
44
-
45
- type WhereAggregation<T extends WabeTypes, K = keyof T['where']> = {
46
- [P in keyof T['where'][K]]: IsScalar<ExtractWhereType<T, K, P>> extends false
47
- ? WhereObject<Partial<ExtractWhereType<T, K, P>>>
48
- : WhereScalar<ExtractWhereType<T, K, P>>
49
- }
50
-
51
- type WhereConditional<T extends WabeTypes, K = keyof T['where']> = {
52
- OR?: Array<WhereType<T, K>>
53
- AND?: Array<WhereType<T, K>>
54
- }
55
-
56
- export type WhereType<T extends WabeTypes, K = keyof T['where']> = Partial<WhereAggregation<T, K>> &
57
- WhereConditional<T, K>
58
-
59
- /** Structure for relation where input (have / isEmpty) */
60
- export type RelationWhereInput<THave = unknown> = {
61
- have?: THave
62
- isEmpty?: boolean
63
- }
64
-
65
- type SelectObject<T, K extends WabeTypes, Depth extends number = 3> = {
66
- [P in keyof T]: IsScalar<T[P]> extends true
67
- ? boolean
68
- : IsArray<T[P]> extends true
69
- ? T[P] extends Array<infer Item>
70
- ? (Depth extends 0 ? boolean : SelectObject<Partial<Item>, K, Decrement<Depth>>) | boolean
71
- : boolean
72
- : IsObject<[P], K> extends true
73
- ? (Depth extends 0 ? boolean : SelectObject<Partial<T[P]>, K, Decrement<Depth>>) | boolean
74
- : boolean
75
- }
76
-
77
- type Decrement<N extends number> = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10][N]
78
-
79
- export type SelectType<
80
- T extends WabeTypes,
81
- K extends keyof T['types'],
82
- U extends keyof T['types'][K],
83
- Depth extends number = 3,
84
- > = Partial<{
85
- [P in U]: IsScalar<ExtractType<T, K, P>> extends true
86
- ? boolean
87
- : IsArray<ExtractType<T, K, P>> extends true
88
- ? ExtractType<T, K, P> extends Array<infer Item>
89
- ? (Depth extends 0 ? boolean : SelectObject<Partial<Item>, T, Decrement<Depth>>) | boolean
90
- : boolean
91
- : ExtractType<T, K, P> extends object
92
- ?
93
- | (Depth extends 0
94
- ? boolean
95
- : SelectObject<Partial<ExtractType<T, K, P>>, T, Decrement<Depth>>)
96
- | boolean
97
- : boolean
98
- }>
99
-
100
- export type OrderType<
101
- T extends WabeTypes,
102
- K extends keyof T['types'],
103
- U extends keyof T['types'][K],
104
- > = Record<U, 'ASC' | 'DESC'>
105
-
106
- export type OutputType<
107
- T extends WabeTypes,
108
- K extends keyof T['types'],
109
- U extends keyof T['types'][K],
110
- > = (Pick<T['types'][K], U> & { id: string }) | null
111
-
112
- export interface AdapterOptions {
113
- databaseUrl: string
114
- databaseName: string
115
- }
116
-
117
- export type MutationData<
118
- T extends WabeTypes,
119
- K extends keyof T['types'],
120
- U extends keyof T['types'][K],
121
- > = Record<U, any>
122
-
123
- export interface CountOptions<T extends WabeTypes, K extends keyof T['types']> {
124
- className: K
125
- where?: WhereType<T, K>
126
- context: WabeContext<T>
127
- }
128
-
129
- export interface GetObjectOptions<
130
- T extends WabeTypes,
131
- K extends keyof T['types'],
132
- U extends keyof T['types'][K],
133
- > {
134
- className: K
135
- id: string
136
- where?: WhereType<T, K>
137
- context: WabeContext<T>
138
- _skipHooks?: boolean
139
- select?: SelectType<T, K, U>
140
- }
141
-
142
- export interface GetObjectsOptions<
143
- T extends WabeTypes,
144
- K extends keyof T['types'],
145
- U extends keyof T['types'][K],
146
- W extends keyof T['types'][K],
147
- > {
148
- className: K
149
- where?: WhereType<T, K>
150
- order?: OrderType<T, K, U>
151
- offset?: number
152
- first?: number
153
- context: WabeContext<T>
154
- _skipHooks?: boolean
155
- select?: SelectType<T, K, W>
156
- }
157
-
158
- export interface CreateObjectOptions<
159
- T extends WabeTypes,
160
- K extends keyof T['types'],
161
- U extends keyof T['types'][K],
162
- W extends keyof T['types'][K],
163
- > {
164
- className: K
165
- data: MutationData<T, K, U>
166
- context: WabeContext<T>
167
- select?: SelectType<T, K, W>
168
- }
169
- export interface CreateObjectsOptions<
170
- T extends WabeTypes,
171
- K extends keyof T['types'],
172
- U extends keyof T['types'][K],
173
- W extends keyof T['types'][K],
174
- X extends keyof T['types'][K],
175
- > {
176
- className: K
177
- data: Array<MutationData<T, K, U>>
178
- offset?: number
179
- first?: number
180
- order?: OrderType<T, U, X>
181
- context: WabeContext<T>
182
- select?: SelectType<T, K, W>
183
- }
184
-
185
- export interface UpdateObjectOptions<
186
- T extends WabeTypes,
187
- K extends keyof T['types'],
188
- U extends keyof T['types'][K],
189
- W extends keyof T['types'][K],
190
- > {
191
- className: K
192
- id: string
193
- where?: WhereType<T, K>
194
- data: MutationData<T, K, U>
195
- context: WabeContext<T>
196
- _skipHooks?: boolean
197
- select?: SelectType<T, K, W>
198
- }
199
-
200
- export interface UpdateObjectsOptions<
201
- T extends WabeTypes,
202
- K extends keyof T['types'],
203
- U extends keyof T['types'][K],
204
- W extends keyof T['types'][K],
205
- X extends keyof T['types'][K],
206
- > {
207
- className: K
208
- where: WhereType<T, K>
209
- order?: OrderType<T, K, X>
210
- data: MutationData<T, K, U>
211
- offset?: number
212
- first?: number
213
- context: WabeContext<T>
214
- _skipHooks?: boolean
215
- select?: SelectType<T, K, W>
216
- }
217
-
218
- export interface DeleteObjectOptions<
219
- T extends WabeTypes,
220
- K extends keyof T['types'],
221
- U extends keyof T['types'][K],
222
- > {
223
- className: K
224
- id: string
225
- where?: WhereType<T, K>
226
- context: WabeContext<T>
227
- select?: SelectType<T, K, U>
228
- }
229
-
230
- export interface DeleteObjectsOptions<
231
- T extends WabeTypes,
232
- K extends keyof T['types'],
233
- U extends keyof T['types'][K],
234
- W extends keyof T['types'][K],
235
- > {
236
- className: K
237
- where: WhereType<T, K>
238
- order?: OrderType<T, K, U>
239
- offset?: number
240
- first?: number
241
- context: WabeContext<T>
242
- select?: SelectType<T, K, W>
243
- }
244
-
245
- export interface DatabaseAdapter<T extends WabeTypes> {
246
- close(): Promise<void>
247
-
248
- createClassIfNotExist(className: string, schema: SchemaInterface<T>): Promise<any> | any
249
-
250
- initializeDatabase(schema: SchemaInterface<T>): Promise<void>
251
- clearDatabase(): Promise<void>
252
-
253
- count<K extends keyof T['types']>(params: CountOptions<T, K>): Promise<number>
254
-
255
- getObject<K extends keyof T['types'], U extends keyof T['types'][K]>(
256
- params: GetObjectOptions<T, K, U>,
257
- ): Promise<OutputType<T, K, U>>
258
- getObjects<
259
- K extends keyof T['types'],
260
- U extends keyof T['types'][K],
261
- W extends keyof T['types'][K],
262
- >(
263
- params: GetObjectsOptions<T, K, U, W>,
264
- ): Promise<OutputType<T, K, W>[]>
265
-
266
- createObject<
267
- K extends keyof T['types'],
268
- U extends keyof T['types'][K],
269
- W extends keyof T['types'][K],
270
- >(
271
- params: CreateObjectOptions<T, K, U, W>,
272
- ): Promise<{ id: string }>
273
- createObjects<
274
- K extends keyof T['types'],
275
- U extends keyof T['types'][K],
276
- W extends keyof T['types'][K],
277
- X extends keyof T['types'][K],
278
- >(
279
- params: CreateObjectsOptions<T, K, U, W, X>,
280
- ): Promise<Array<{ id: string }>>
281
-
282
- updateObject<
283
- K extends keyof T['types'],
284
- U extends keyof T['types'][K],
285
- W extends keyof T['types'][K],
286
- >(
287
- params: UpdateObjectOptions<T, K, U, W>,
288
- ): Promise<{ id: string }>
289
- updateObjects<
290
- K extends keyof T['types'],
291
- U extends keyof T['types'][K],
292
- W extends keyof T['types'][K],
293
- X extends keyof T['types'][K],
294
- >(
295
- params: UpdateObjectsOptions<T, K, U, W, X>,
296
- ): Promise<Array<{ id: string }>>
297
-
298
- deleteObject<K extends keyof T['types'], U extends keyof T['types'][K]>(
299
- params: DeleteObjectOptions<T, K, U>,
300
- ): Promise<void>
301
- deleteObjects<
302
- K extends keyof T['types'],
303
- U extends keyof T['types'][K],
304
- W extends keyof T['types'][K],
305
- >(
306
- params: DeleteObjectsOptions<T, K, U, W>,
307
- ): Promise<void>
308
- }
@@ -1,7 +0,0 @@
1
- import type { EmailAdapter } from './interface'
2
-
3
- export class EmailDevAdapter implements EmailAdapter {
4
- async send() {
5
- return '123456'
6
- }
7
- }
@@ -1,29 +0,0 @@
1
- import { describe, expect, it, mock } from 'bun:test'
2
- import { EmailController } from './EmailController'
3
-
4
- describe('EmailController', () => {
5
- it('should send email using correct adapter', async () => {
6
- const mockSend = mock(() => {})
7
- const dummyAdapter = {
8
- send: mockSend,
9
- }
10
-
11
- // @ts-expect-error
12
- const controller = new EmailController(dummyAdapter)
13
-
14
- await controller.send({
15
- from: 'from',
16
- to: ['to'],
17
- subject: 'subject',
18
- text: 'text',
19
- })
20
-
21
- expect(mockSend).toHaveBeenCalledTimes(1)
22
- expect(mockSend).toHaveBeenCalledWith({
23
- from: 'from',
24
- to: ['to'],
25
- subject: 'subject',
26
- text: 'text',
27
- })
28
- })
29
- })
@@ -1,13 +0,0 @@
1
- import type { EmailAdapter, EmailSendOptions } from './interface'
2
-
3
- export class EmailController implements EmailAdapter {
4
- public adapter: EmailAdapter
5
-
6
- constructor(adapter: EmailAdapter) {
7
- this.adapter = adapter
8
- }
9
-
10
- send(options: EmailSendOptions) {
11
- return this.adapter.send(options)
12
- }
13
- }
@@ -1,2 +0,0 @@
1
- export * from './interface'
2
- export * from './DevAdapter'
@@ -1,36 +0,0 @@
1
- export type HtmlTemplates = {
2
- sendOTPCode: {
3
- fn: (options: { otp: string }) => string | Promise<string>
4
- subject: string
5
- }
6
- }
7
-
8
- export interface EmailSendOptions {
9
- from: string
10
- to: Array<string>
11
- subject: string
12
- node?: any
13
- html?: string
14
- text?: string
15
- }
16
-
17
- export interface EmailAdapter {
18
- /**
19
- * Send an email using the provided adapter
20
- * @param options Mail options (expeditor, recipient, subject ...)
21
- * @return The id of the email sended, throw an error if something wrong
22
- */
23
- send(options: EmailSendOptions): Promise<string>
24
- }
25
-
26
- /**
27
- * Configuration for the email in Wabe
28
- * @property adapter The adapter to use to send emails
29
- * @property mainEmail The email to use as sender for emails sent by Wabe
30
- * @property templates The html templates to use for a specific email. If not provided, Wabe will use the default templates
31
- */
32
- export interface EmailConfig {
33
- adapter: EmailAdapter
34
- mainEmail?: string
35
- htmlTemplates?: HtmlTemplates
36
- }
@@ -1,120 +0,0 @@
1
- export const sendOtpCodeTemplate = (otp: string) => `
2
- <!DOCTYPE html>
3
- <html lang="en">
4
-
5
- <head>
6
- <meta charset="UTF-8">
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
9
- <title>Password Reset</title>
10
- <style>
11
- body {
12
- font-family: 'Arial', sans-serif;
13
- margin: 0;
14
- padding: 0;
15
- background-color: #f4f4f4;
16
- }
17
-
18
- .email-container {
19
- max-width: 600px;
20
- margin: 0 auto;
21
- background-color: #ffffff;
22
- border-radius: 8px;
23
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
24
- overflow: hidden;
25
- }
26
-
27
- .header {
28
- background-color: #4CAF50;
29
- padding: 20px;
30
- text-align: center;
31
- color: white;
32
- }
33
-
34
- .header h1 {
35
- margin: 0;
36
- font-size: 24px;
37
- }
38
-
39
- .content {
40
- padding: 20px;
41
- font-size: 16px;
42
- line-height: 1.6;
43
- color: #333333;
44
- }
45
-
46
- .content p {
47
- margin-bottom: 20px;
48
- }
49
-
50
- .otp-code {
51
- display: inline-block;
52
- padding: 10px 20px;
53
- background-color: #4CAF50;
54
- color: white;
55
- font-size: 18px;
56
- font-weight: bold;
57
- border-radius: 5px;
58
- letter-spacing: 2px;
59
- text-align: center;
60
- }
61
-
62
- .footer {
63
- background-color: #f4f4f4;
64
- text-align: center;
65
- padding: 10px;
66
- font-size: 14px;
67
- color: #888888;
68
- }
69
-
70
- .footer p {
71
- margin: 0;
72
- }
73
-
74
- /* Responsive Design */
75
- @media screen and (max-width: 600px) {
76
- .email-container {
77
- width: 100%;
78
- }
79
-
80
- .header h1 {
81
- font-size: 20px;
82
- }
83
-
84
- .content {
85
- padding: 15px;
86
- }
87
-
88
- .otp-code {
89
- font-size: 16px;
90
- padding: 8px 16px;
91
- }
92
- }
93
- </style>
94
- </head>
95
-
96
- <body>
97
- <div class="email-container">
98
- <!-- Email Header -->
99
- <div class="header">
100
- <h1>Confirmation code</h1>
101
- </div>
102
-
103
- <!-- Email Content -->
104
- <div class="content">
105
- <p>Hello,</p>
106
- <p>Here is your confirmation code. Please use the OTP code (valid for 5 minutes) below to proceed the action:</p>
107
- <p class="otp-code">${otp}</p>
108
- <p>If you did not request this code, please ignore this email.</p>
109
- <p>Thank you</p>
110
- </div>
111
-
112
- <!-- Email Footer -->
113
- <div class="footer">
114
- <p>Powered by Wabe</p>
115
- </div>
116
- </div>
117
- </body>
118
-
119
- </html>
120
- `
@@ -1,28 +0,0 @@
1
- import type { Wabe } from '../server'
2
- import type { DevWabeTypes } from '../utils/helper'
3
- import type { FileAdapter, ReadFileOptions } from './interface'
4
-
5
- export class FileController implements FileAdapter {
6
- public adapter: FileAdapter
7
- private wabe: Wabe<DevWabeTypes>
8
-
9
- constructor(adapter: FileAdapter, wabe: Wabe<any>) {
10
- this.adapter = adapter
11
- this.wabe = wabe
12
- }
13
-
14
- uploadFile(file: File) {
15
- return this.adapter.uploadFile(file)
16
- }
17
-
18
- readFile(fileName: string, options?: ReadFileOptions) {
19
- return this.adapter.readFile(fileName, {
20
- ...options,
21
- port: this.wabe.config.port,
22
- })
23
- }
24
-
25
- deleteFile(fileName: string) {
26
- return this.adapter.deleteFile(fileName)
27
- }
28
- }
@@ -1,51 +0,0 @@
1
- import { writeFile, mkdir, rm, access, constants } from 'node:fs/promises'
2
- import path from 'node:path'
3
- import type { FileAdapter, ReadFileOptions } from '.'
4
-
5
- export class FileDevAdapter implements FileAdapter {
6
- private basePath = 'bucket'
7
- private rootPath = process.cwd()
8
-
9
- async uploadFile(file: File): Promise<void> {
10
- const fullPath = path.join(this.rootPath, this.basePath)
11
-
12
- await mkdir(fullPath, { recursive: true })
13
-
14
- const fileType = file.type
15
-
16
- let fileContent: Buffer
17
-
18
- if (fileType.startsWith('text') || fileType.includes('json')) {
19
- const textContent = await file.text()
20
- fileContent = Buffer.from(textContent, 'utf-8')
21
- } else {
22
- const arrayBuffer = await file.arrayBuffer()
23
- fileContent = Buffer.from(arrayBuffer)
24
- }
25
-
26
- await writeFile(path.join(fullPath, file.name), fileContent)
27
- }
28
-
29
- async readFile(fileName: string, options?: ReadFileOptions): Promise<string | null> {
30
- const filePath = path.join(this.rootPath, this.basePath, fileName)
31
-
32
- try {
33
- await access(filePath, constants.F_OK)
34
- return `http://127.0.0.1:${options?.port || 3001}/${this.basePath}/${fileName}`
35
- } catch {
36
- return null
37
- }
38
- }
39
-
40
- async deleteFile(fileName: string): Promise<void> {
41
- const filePath = path.join(this.rootPath, this.basePath, fileName)
42
-
43
- try {
44
- await access(filePath, constants.F_OK)
45
-
46
- await rm(filePath)
47
- } catch {
48
- // Do nothing
49
- }
50
- }
51
- }
@@ -1,25 +0,0 @@
1
- import type { HookObject } from '../hooks/HookObject'
2
-
3
- const deleteFile = async (hookObject: HookObject<any, any>) => {
4
- const schema = hookObject.context.wabe.config.schema?.classes?.find(
5
- (currentClass) => currentClass.name === hookObject.className,
6
- )
7
-
8
- if (!schema) return
9
-
10
- await Promise.all(
11
- Object.entries(schema.fields)
12
- .filter(([_, value]) => value.type === 'File')
13
- .map(([fieldName]) => {
14
- const fileName = hookObject.originalObject?.[fieldName]?.name as string
15
-
16
- if (!fileName) return Promise.resolve()
17
-
18
- if (!hookObject.context.wabe.controllers.file) throw new Error('No file adapter found')
19
-
20
- return hookObject.context.wabe.controllers.file?.deleteFile(fileName)
21
- }),
22
- )
23
- }
24
-
25
- export const defaultAfterDeleteFile = (hookObject: HookObject<any, any>) => deleteFile(hookObject)
@@ -1,66 +0,0 @@
1
- import type { HookObject } from '../hooks/HookObject'
2
-
3
- const getFile = async (hookObject: HookObject<any, any>) => {
4
- const schema = hookObject.context.wabe.config.schema?.classes?.find(
5
- (currentClass) => currentClass.name === hookObject.className,
6
- )
7
-
8
- if (!schema) return
9
-
10
- const urlCacheInSeconds = hookObject.context.wabe.config.file?.urlCacheInSeconds || 3600 * 24
11
-
12
- // After read we get the file URL and we update the field url with an URL.
13
- // For security purpose we recommend to use a presigned URL
14
- await Promise.all(
15
- Object.entries(schema.fields)
16
- .filter(([_, value]) => value.type === 'File')
17
- .map(async ([fieldName]) => {
18
- const fileInfo = hookObject.object?.[fieldName]
19
-
20
- if (!fileInfo) return
21
-
22
- const fileName = fileInfo.name as string
23
-
24
- if (!fileName && fileInfo.url) return fileInfo.url
25
-
26
- const fileUrlGeneratedAt = new Date(fileInfo.urlGeneratedAt)
27
-
28
- if (
29
- fileUrlGeneratedAt &&
30
- fileUrlGeneratedAt.getTime() + urlCacheInSeconds * 1000 > Date.now()
31
- )
32
- return
33
-
34
- if (!hookObject.context.wabe.controllers.file) throw new Error('No file adapter found')
35
-
36
- const fileUrlFromBucket = await hookObject.context.wabe.controllers.file?.readFile(fileName)
37
-
38
- const newUrl = fileUrlFromBucket || fileInfo.url
39
- const newUrlGeneratedAt = new Date()
40
-
41
- // Mutate the object returned to the caller so AfterRead effects are visible immediately
42
- // @ts-expect-error
43
- hookObject.object[fieldName] = {
44
- ...fileInfo,
45
- urlGeneratedAt: newUrlGeneratedAt,
46
- url: newUrl,
47
- }
48
-
49
- return hookObject.context.wabe.controllers.database.updateObject({
50
- className: hookObject.className,
51
- context: hookObject.context,
52
- id: hookObject.object?.id || '',
53
- data: {
54
- [fieldName]: {
55
- ...fileInfo,
56
- urlGeneratedAt: newUrlGeneratedAt,
57
- url: newUrl,
58
- },
59
- },
60
- _skipHooks: true,
61
- })
62
- }),
63
- )
64
- }
65
-
66
- export const defaultAfterReadFile = (hookObject: HookObject<any, any>) => getFile(hookObject)