@anthonylzq/simba.js 3.2.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -13
- package/lib/index.js +0 -2
- package/lib/src/functions/api.js +377 -344
- package/lib/src/functions/tsconfig.js +1 -1
- package/lib/src/index.js +4 -4
- package/lib/src/utils/titleCase.js +1 -1
- package/package.json +8 -6
package/lib/src/functions/api.js
CHANGED
|
@@ -121,23 +121,13 @@ export {}
|
|
|
121
121
|
file: `${projectName}/src/@types/index.d.ts`
|
|
122
122
|
}
|
|
123
123
|
},
|
|
124
|
-
'@types/dto': {
|
|
125
|
-
user: {
|
|
126
|
-
content: `interface DtoUser {
|
|
127
|
-
id: string
|
|
128
|
-
lastName: string
|
|
129
|
-
name: string
|
|
130
|
-
}
|
|
131
|
-
`,
|
|
132
|
-
file: `${projectName}/src/@types/dto/user.d.ts`
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
124
|
'@types/models': {
|
|
136
125
|
user: {
|
|
137
|
-
content: `interface
|
|
126
|
+
content: `interface UserDBO {
|
|
138
127
|
id: string
|
|
139
128
|
name: string
|
|
140
129
|
lastName: string
|
|
130
|
+
createdAt: Date
|
|
141
131
|
updatedAt: Date
|
|
142
132
|
}
|
|
143
133
|
`,
|
|
@@ -166,7 +156,7 @@ export * from './queries'
|
|
|
166
156
|
user: {
|
|
167
157
|
content: `import { model, Schema } from 'mongoose'
|
|
168
158
|
|
|
169
|
-
const
|
|
159
|
+
const UserSchema = new Schema<UserDBO>(
|
|
170
160
|
{
|
|
171
161
|
lastName: {
|
|
172
162
|
required: true,
|
|
@@ -178,24 +168,18 @@ const User = new Schema<IUser>(
|
|
|
178
168
|
}
|
|
179
169
|
},
|
|
180
170
|
{
|
|
181
|
-
timestamps:
|
|
182
|
-
createdAt: false,
|
|
183
|
-
updatedAt: true
|
|
184
|
-
},
|
|
171
|
+
timestamps: true,
|
|
185
172
|
versionKey: false,
|
|
186
|
-
|
|
187
|
-
transform(_, ret) {
|
|
173
|
+
toObject: {
|
|
174
|
+
transform: (_, ret) => {
|
|
188
175
|
ret.id = ret._id.toString()
|
|
189
|
-
ret.updatedAt = ret.updatedAt.toISOString()
|
|
190
176
|
delete ret._id
|
|
191
|
-
|
|
192
|
-
},
|
|
193
|
-
virtuals: true
|
|
177
|
+
}
|
|
194
178
|
}
|
|
195
179
|
}
|
|
196
180
|
)
|
|
197
181
|
|
|
198
|
-
const UserModel = model<
|
|
182
|
+
const UserModel = model<UserDBO>('users', UserSchema)
|
|
199
183
|
|
|
200
184
|
export { UserModel }
|
|
201
185
|
`,
|
|
@@ -208,42 +192,63 @@ export { UserModel }
|
|
|
208
192
|
file: `${projectName}/src/database/mongo/queries/index.ts`
|
|
209
193
|
},
|
|
210
194
|
user: {
|
|
211
|
-
content: `import {
|
|
195
|
+
content: `import { Document, Types } from 'mongoose'
|
|
196
|
+
|
|
197
|
+
import { UserModel } from '..'
|
|
198
|
+
import { UserDTO } from 'schemas'
|
|
199
|
+
|
|
200
|
+
const userDBOtoDTO = (
|
|
201
|
+
userDBO: Document<unknown, unknown, UserDBO> &
|
|
202
|
+
UserDBO & {
|
|
203
|
+
_id: Types.ObjectId
|
|
204
|
+
}
|
|
205
|
+
): UserDTO => ({
|
|
206
|
+
...userDBO.toObject(),
|
|
207
|
+
createdAt: userDBO.createdAt.toISOString(),
|
|
208
|
+
updatedAt: userDBO.updatedAt.toISOString()
|
|
209
|
+
})
|
|
212
210
|
|
|
213
|
-
const store = async (userData:
|
|
211
|
+
const store = async (userData: UserDTO): Promise<UserDTO> => {
|
|
214
212
|
const user = new UserModel(userData)
|
|
213
|
+
|
|
215
214
|
await user.save()
|
|
216
215
|
|
|
217
|
-
return user
|
|
216
|
+
return userDBOtoDTO(user)
|
|
218
217
|
}
|
|
219
218
|
|
|
220
219
|
const remove = async (
|
|
221
220
|
id: string | null = null
|
|
222
|
-
): Promise<
|
|
223
|
-
if (id)
|
|
221
|
+
): Promise<UserDTO | number | null> => {
|
|
222
|
+
if (id) {
|
|
223
|
+
const removedUser = await UserModel.findByIdAndRemove(id)
|
|
224
|
+
|
|
225
|
+
if (!removedUser) return null
|
|
226
|
+
|
|
227
|
+
return userDBOtoDTO(removedUser)
|
|
228
|
+
}
|
|
224
229
|
|
|
225
230
|
return (await UserModel.deleteMany({})).deletedCount
|
|
226
231
|
}
|
|
227
232
|
|
|
228
233
|
const get = async (
|
|
229
234
|
id: string | null = null
|
|
230
|
-
): Promise<
|
|
235
|
+
): Promise<UserDTO[] | UserDTO | null> => {
|
|
231
236
|
if (id) {
|
|
232
237
|
const user = await UserModel.findById(id)
|
|
233
238
|
|
|
234
|
-
return user ? user
|
|
239
|
+
return user ? userDBOtoDTO(user) : null
|
|
235
240
|
}
|
|
236
241
|
|
|
237
242
|
const users = await UserModel.find({})
|
|
238
243
|
|
|
239
|
-
return users.map(u => u
|
|
244
|
+
return users.map(u => userDBOtoDTO(u))
|
|
240
245
|
}
|
|
241
246
|
|
|
242
|
-
const update = async (userData:
|
|
247
|
+
const update = async (userData: UserDTO): Promise<UserDTO | null> => {
|
|
243
248
|
const { id, ...rest } = userData
|
|
244
249
|
const user = await UserModel.findByIdAndUpdate(id, rest, { new: true })
|
|
245
250
|
|
|
246
|
-
return user ? user
|
|
251
|
+
return user ? userDBOtoDTO(user) : null
|
|
247
252
|
}
|
|
248
253
|
|
|
249
254
|
export { store, remove, get, update }
|
|
@@ -259,6 +264,58 @@ export * from './server'
|
|
|
259
264
|
file: `${projectName}/src/network/index.ts`
|
|
260
265
|
}
|
|
261
266
|
},
|
|
267
|
+
schemas: {
|
|
268
|
+
index: {
|
|
269
|
+
content: `import { Static, Type } from '@sinclair/typebox'
|
|
270
|
+
|
|
271
|
+
const id = Type.String({
|
|
272
|
+
pattern: '^[a-zA-Z0-9]{24,}$'
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
type Id = Static<typeof id>
|
|
276
|
+
|
|
277
|
+
const idSchema = Type.Object({ id })
|
|
278
|
+
|
|
279
|
+
type IdSchema = Static<typeof idSchema>
|
|
280
|
+
|
|
281
|
+
export { id, Id, idSchema, IdSchema }
|
|
282
|
+
export * from './user'
|
|
283
|
+
`,
|
|
284
|
+
file: `${projectName}/src/schemas/index.ts`
|
|
285
|
+
},
|
|
286
|
+
user: {
|
|
287
|
+
content: `import { Static, Type } from '@sinclair/typebox'
|
|
288
|
+
|
|
289
|
+
import { id } from '.'
|
|
290
|
+
|
|
291
|
+
const user = Type.Object({
|
|
292
|
+
lastName: Type.String(),
|
|
293
|
+
name: Type.String()
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
type User = Static<typeof user>
|
|
297
|
+
|
|
298
|
+
const userDto = Type.Object({
|
|
299
|
+
id: Type.Optional(id),
|
|
300
|
+
lastName: Type.String(),
|
|
301
|
+
name: Type.String(),
|
|
302
|
+
createdAt: Type.Optional(Type.String()),
|
|
303
|
+
updatedAt: Type.Optional(Type.String())
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
type UserDTO = Static<typeof userDto>
|
|
307
|
+
|
|
308
|
+
const storeUserSchema = Type.Object({
|
|
309
|
+
args: user
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
type StoreUser = Static<typeof storeUserSchema>
|
|
313
|
+
|
|
314
|
+
export { userDto, UserDTO, user, User, storeUserSchema, StoreUser }
|
|
315
|
+
`,
|
|
316
|
+
file: `${projectName}/src/schemas/user.ts`
|
|
317
|
+
}
|
|
318
|
+
},
|
|
262
319
|
services: {
|
|
263
320
|
index: {
|
|
264
321
|
content: "export * from './user'\n",
|
|
@@ -268,41 +325,53 @@ export * from './server'
|
|
|
268
325
|
content: `import httpErrors from 'http-errors'
|
|
269
326
|
|
|
270
327
|
import { store, remove, get, update } from 'database'
|
|
328
|
+
import { UserDTO } from 'schemas'
|
|
271
329
|
import { EFU, MFU, GE, errorHandling } from './utils'
|
|
272
330
|
|
|
273
331
|
type Process = {
|
|
274
332
|
type: 'store' | 'getAll' | 'deleteAll' | 'getOne' | 'update' | 'delete'
|
|
275
333
|
}
|
|
276
334
|
|
|
335
|
+
type Arguments = {
|
|
336
|
+
id?: string
|
|
337
|
+
userDto?: UserDTO
|
|
338
|
+
userDtoWithoutId?: Omit<UserDTO, 'id'>
|
|
339
|
+
}
|
|
340
|
+
|
|
277
341
|
class UserService {
|
|
278
|
-
|
|
342
|
+
#args: Arguments
|
|
279
343
|
|
|
280
|
-
constructor(args:
|
|
281
|
-
this
|
|
344
|
+
constructor(args: Arguments = {}) {
|
|
345
|
+
this.#args = args
|
|
282
346
|
}
|
|
283
347
|
|
|
284
|
-
public process({ type }: Process): Promise<string |
|
|
348
|
+
public process({ type }: Process): Promise<string | UserDTO | UserDTO[]> {
|
|
285
349
|
switch (type) {
|
|
286
350
|
case 'store':
|
|
287
|
-
return this
|
|
351
|
+
return this.#store()
|
|
288
352
|
case 'getAll':
|
|
289
|
-
return this
|
|
353
|
+
return this.#getAll()
|
|
290
354
|
case 'deleteAll':
|
|
291
|
-
return this
|
|
355
|
+
return this.#deleteAll()
|
|
292
356
|
case 'getOne':
|
|
293
|
-
return this
|
|
357
|
+
return this.#getOne()
|
|
294
358
|
case 'update':
|
|
295
|
-
return this
|
|
359
|
+
return this.#update()
|
|
296
360
|
case 'delete':
|
|
297
|
-
return this
|
|
361
|
+
return this.#delete()
|
|
298
362
|
default:
|
|
299
363
|
throw new httpErrors.InternalServerError(GE.INTERNAL_SERVER_ERROR)
|
|
300
364
|
}
|
|
301
365
|
}
|
|
302
366
|
|
|
303
|
-
|
|
367
|
+
async #store(): Promise<UserDTO> {
|
|
304
368
|
try {
|
|
305
|
-
|
|
369
|
+
if (!this.#args.userDtoWithoutId)
|
|
370
|
+
throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
|
|
371
|
+
|
|
372
|
+
const result = await store({
|
|
373
|
+
...this.#args.userDtoWithoutId
|
|
374
|
+
})
|
|
306
375
|
|
|
307
376
|
return result
|
|
308
377
|
} catch (e) {
|
|
@@ -310,9 +379,9 @@ class UserService {
|
|
|
310
379
|
}
|
|
311
380
|
}
|
|
312
381
|
|
|
313
|
-
|
|
382
|
+
async #getAll(): Promise<UserDTO[]> {
|
|
314
383
|
try {
|
|
315
|
-
const users = (await get()) as
|
|
384
|
+
const users = (await get()) as UserDTO[]
|
|
316
385
|
|
|
317
386
|
return users
|
|
318
387
|
} catch (e) {
|
|
@@ -320,7 +389,7 @@ class UserService {
|
|
|
320
389
|
}
|
|
321
390
|
}
|
|
322
391
|
|
|
323
|
-
|
|
392
|
+
async #deleteAll(): Promise<string> {
|
|
324
393
|
try {
|
|
325
394
|
const usersDeleted = (await remove()) as number
|
|
326
395
|
|
|
@@ -335,11 +404,13 @@ class UserService {
|
|
|
335
404
|
}
|
|
336
405
|
}
|
|
337
406
|
|
|
338
|
-
|
|
339
|
-
const { id } = this._args as DtoUser
|
|
340
|
-
|
|
407
|
+
async #getOne(): Promise<UserDTO> {
|
|
341
408
|
try {
|
|
342
|
-
|
|
409
|
+
if (!this.#args.id)
|
|
410
|
+
throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
|
|
411
|
+
|
|
412
|
+
const { id } = this.#args
|
|
413
|
+
const user = (await get(id)) as UserDTO | null
|
|
343
414
|
|
|
344
415
|
if (!user) throw new httpErrors.NotFound(EFU.NOT_FOUND)
|
|
345
416
|
|
|
@@ -349,9 +420,12 @@ class UserService {
|
|
|
349
420
|
}
|
|
350
421
|
}
|
|
351
422
|
|
|
352
|
-
|
|
423
|
+
async #update(): Promise<UserDTO> {
|
|
353
424
|
try {
|
|
354
|
-
|
|
425
|
+
if (!this.#args.userDto || !this.#args.userDto.id)
|
|
426
|
+
throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
|
|
427
|
+
|
|
428
|
+
const updatedUser = await update(this.#args.userDto)
|
|
355
429
|
|
|
356
430
|
if (!updatedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
|
|
357
431
|
|
|
@@ -361,10 +435,12 @@ class UserService {
|
|
|
361
435
|
}
|
|
362
436
|
}
|
|
363
437
|
|
|
364
|
-
|
|
365
|
-
const { id } = this._args as DtoUser
|
|
366
|
-
|
|
438
|
+
async #delete(): Promise<string> {
|
|
367
439
|
try {
|
|
440
|
+
if (!this.#args.id)
|
|
441
|
+
throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
|
|
442
|
+
|
|
443
|
+
const { id } = this.#args
|
|
368
444
|
const deletedUser = await remove(id)
|
|
369
445
|
|
|
370
446
|
if (!deletedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
|
|
@@ -484,6 +560,33 @@ Server.start()
|
|
|
484
560
|
}
|
|
485
561
|
|
|
486
562
|
const expressData = {
|
|
563
|
+
'@types/custom': {
|
|
564
|
+
request: {
|
|
565
|
+
content: `type ExpressRequest = import('express').Request
|
|
566
|
+
|
|
567
|
+
interface CustomRequest extends ExpressRequest {
|
|
568
|
+
body: {
|
|
569
|
+
args?: import('schemas').UserDTO
|
|
570
|
+
}
|
|
571
|
+
// We can add custom headers via intersection, remember that for some reason
|
|
572
|
+
// headers must be in Snake-Pascal-Case
|
|
573
|
+
headers: import('http').IncomingHttpHeaders & {
|
|
574
|
+
'Custom-Header'?: string
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
`,
|
|
578
|
+
file: `${projectName}/src/@types/custom/request.d.ts`
|
|
579
|
+
},
|
|
580
|
+
response: {
|
|
581
|
+
content: `type ExpressResponse = import('express').Response
|
|
582
|
+
|
|
583
|
+
interface CustomResponse extends ExpressResponse {
|
|
584
|
+
newValue?: string
|
|
585
|
+
}
|
|
586
|
+
`,
|
|
587
|
+
file: `${projectName}/src/@types/custom/response.d.ts`
|
|
588
|
+
}
|
|
589
|
+
},
|
|
487
590
|
network: {
|
|
488
591
|
response: {
|
|
489
592
|
content: `interface ResponseProps {
|
|
@@ -547,26 +650,27 @@ export { applyRoutes }
|
|
|
547
650
|
content: `import express from 'express'
|
|
548
651
|
import mongoose from 'mongoose'
|
|
549
652
|
import morgan from 'morgan'
|
|
653
|
+
import cors from 'cors'
|
|
550
654
|
|
|
551
655
|
import { applyRoutes } from './router'
|
|
552
656
|
|
|
553
657
|
const PORT = (process.env.PORT as string) || '1996'
|
|
554
658
|
|
|
555
659
|
class Server {
|
|
556
|
-
|
|
557
|
-
|
|
660
|
+
#app: express.Application
|
|
661
|
+
#connection: mongoose.Connection | undefined
|
|
558
662
|
|
|
559
663
|
constructor() {
|
|
560
|
-
this
|
|
561
|
-
this
|
|
664
|
+
this.#app = express()
|
|
665
|
+
this.#config()
|
|
562
666
|
}
|
|
563
667
|
|
|
564
|
-
|
|
565
|
-
this.
|
|
566
|
-
this.
|
|
567
|
-
this.
|
|
568
|
-
this.
|
|
569
|
-
this.
|
|
668
|
+
#config() {
|
|
669
|
+
this.#app.use(cors())
|
|
670
|
+
this.#app.use(morgan('dev'))
|
|
671
|
+
this.#app.use(express.json())
|
|
672
|
+
this.#app.use(express.urlencoded({ extended: false }))
|
|
673
|
+
this.#app.use(
|
|
570
674
|
(
|
|
571
675
|
req: express.Request,
|
|
572
676
|
res: express.Response,
|
|
@@ -582,23 +686,23 @@ class Server {
|
|
|
582
686
|
}
|
|
583
687
|
)
|
|
584
688
|
|
|
585
|
-
applyRoutes(this
|
|
689
|
+
applyRoutes(this.#app)
|
|
586
690
|
}
|
|
587
691
|
|
|
588
|
-
|
|
589
|
-
this
|
|
692
|
+
async #mongo(): Promise<void> {
|
|
693
|
+
this.#connection = mongoose.connection
|
|
590
694
|
const connection = {
|
|
591
695
|
keepAlive: true,
|
|
592
696
|
useNewUrlParser: true,
|
|
593
697
|
useUnifiedTopology: true
|
|
594
698
|
}
|
|
595
|
-
this.
|
|
699
|
+
this.#connection.on('connected', () => {
|
|
596
700
|
console.log('Mongo connection established.')
|
|
597
701
|
})
|
|
598
|
-
this.
|
|
702
|
+
this.#connection.on('reconnected', () => {
|
|
599
703
|
console.log('Mongo connection reestablished')
|
|
600
704
|
})
|
|
601
|
-
this.
|
|
705
|
+
this.#connection.on('disconnected', () => {
|
|
602
706
|
console.log('Mongo connection disconnected')
|
|
603
707
|
console.log('Trying to reconnected to Mongo...')
|
|
604
708
|
setTimeout(() => {
|
|
@@ -609,10 +713,10 @@ class Server {
|
|
|
609
713
|
})
|
|
610
714
|
}, 3000)
|
|
611
715
|
})
|
|
612
|
-
this.
|
|
716
|
+
this.#connection.on('close', () => {
|
|
613
717
|
console.log('Mongo connection closed')
|
|
614
718
|
})
|
|
615
|
-
this.
|
|
719
|
+
this.#connection.on('error', (e: Error) => {
|
|
616
720
|
console.log('Mongo connection error:')
|
|
617
721
|
console.error(e)
|
|
618
722
|
})
|
|
@@ -620,12 +724,12 @@ class Server {
|
|
|
620
724
|
}
|
|
621
725
|
|
|
622
726
|
public start(): void {
|
|
623
|
-
this.
|
|
727
|
+
this.#app.listen(PORT, () => {
|
|
624
728
|
console.log(\`Server running at port \${PORT}\`)
|
|
625
729
|
})
|
|
626
730
|
|
|
627
731
|
try {
|
|
628
|
-
this
|
|
732
|
+
this.#mongo()
|
|
629
733
|
} catch (e) {
|
|
630
734
|
console.error(e)
|
|
631
735
|
}
|
|
@@ -639,33 +743,6 @@ export { server as Server }
|
|
|
639
743
|
file: `${projectName}/src/network/server.ts`
|
|
640
744
|
}
|
|
641
745
|
},
|
|
642
|
-
'@types/custom': {
|
|
643
|
-
request: {
|
|
644
|
-
content: `type ExpressRequest = import('express').Request
|
|
645
|
-
|
|
646
|
-
interface CustomRequest extends ExpressRequest {
|
|
647
|
-
body: {
|
|
648
|
-
args?: DtoUser
|
|
649
|
-
}
|
|
650
|
-
// We can add custom headers via intersection, remember that for some reason
|
|
651
|
-
// headers must be in Snake-Pascal-Case
|
|
652
|
-
headers: import('http').IncomingHttpHeaders & {
|
|
653
|
-
'Custom-Header'?: string
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
`,
|
|
657
|
-
file: `${projectName}/src/@types/custom/request.d.ts`
|
|
658
|
-
},
|
|
659
|
-
response: {
|
|
660
|
-
content: `type ExpressResponse = import('express').Response
|
|
661
|
-
|
|
662
|
-
interface CustomResponse extends ExpressResponse {
|
|
663
|
-
newValue?: string
|
|
664
|
-
}
|
|
665
|
-
`,
|
|
666
|
-
file: `${projectName}/src/@types/custom/response.d.ts`
|
|
667
|
-
}
|
|
668
|
-
},
|
|
669
746
|
'network/routes': {
|
|
670
747
|
home: {
|
|
671
748
|
content: `import { Response, Request, Router } from 'express'
|
|
@@ -694,146 +771,82 @@ export * from './user'
|
|
|
694
771
|
file: `${projectName}/src/network/routes/index.ts`
|
|
695
772
|
},
|
|
696
773
|
user: {
|
|
697
|
-
content: `import { Router
|
|
698
|
-
import httpErrors from 'http-errors'
|
|
699
|
-
import { ValidationError } from 'joi'
|
|
774
|
+
content: `import { Router } from 'express'
|
|
700
775
|
|
|
701
776
|
import { response } from 'network/response'
|
|
702
|
-
import { UserService } from 'services
|
|
703
|
-
import { idSchema,
|
|
777
|
+
import { UserService } from 'services'
|
|
778
|
+
import { idSchema, storeUserSchema, UserDTO } from 'schemas'
|
|
779
|
+
import { validatorCompiler } from './utils'
|
|
704
780
|
|
|
705
781
|
const User = Router()
|
|
706
782
|
|
|
707
783
|
User.route('/users')
|
|
708
784
|
.post(
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
res: CustomResponse,
|
|
712
|
-
next: NextFunction
|
|
713
|
-
): Promise<void> => {
|
|
785
|
+
validatorCompiler(storeUserSchema, 'body'),
|
|
786
|
+
async (req: CustomRequest, res: CustomResponse): Promise<void> => {
|
|
714
787
|
const {
|
|
715
788
|
body: { args }
|
|
716
789
|
} = req
|
|
790
|
+
const us = new UserService({ userDtoWithoutId: args })
|
|
791
|
+
const result = await us.process({ type: 'store' })
|
|
717
792
|
|
|
718
|
-
|
|
719
|
-
await storeUserSchema.validateAsync(args)
|
|
720
|
-
const us = new UserService(args)
|
|
721
|
-
const result = await us.process({ type: 'store' })
|
|
722
|
-
response({ error: false, message: result, res, status: 201 })
|
|
723
|
-
} catch (e) {
|
|
724
|
-
if (e instanceof ValidationError)
|
|
725
|
-
return next(new httpErrors.UnprocessableEntity(e.message))
|
|
726
|
-
|
|
727
|
-
next(e)
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
)
|
|
731
|
-
.get(
|
|
732
|
-
async (
|
|
733
|
-
req: CustomRequest,
|
|
734
|
-
res: CustomResponse,
|
|
735
|
-
next: NextFunction
|
|
736
|
-
): Promise<void> => {
|
|
737
|
-
const us = new UserService()
|
|
738
|
-
|
|
739
|
-
try {
|
|
740
|
-
const result = await us.process({ type: 'getAll' })
|
|
741
|
-
response({ error: false, message: result, res, status: 200 })
|
|
742
|
-
} catch (e) {
|
|
743
|
-
next(e)
|
|
744
|
-
}
|
|
793
|
+
response({ error: false, message: result, res, status: 201 })
|
|
745
794
|
}
|
|
746
795
|
)
|
|
747
|
-
.
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
res: CustomResponse,
|
|
751
|
-
next: NextFunction
|
|
752
|
-
): Promise<void> => {
|
|
753
|
-
const us = new UserService()
|
|
796
|
+
.get(async (req: CustomRequest, res: CustomResponse): Promise<void> => {
|
|
797
|
+
const us = new UserService()
|
|
798
|
+
const result = await us.process({ type: 'getAll' })
|
|
754
799
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
}
|
|
762
|
-
)
|
|
800
|
+
response({ error: false, message: result, res, status: 200 })
|
|
801
|
+
})
|
|
802
|
+
.delete(async (req: CustomRequest, res: CustomResponse): Promise<void> => {
|
|
803
|
+
const us = new UserService()
|
|
804
|
+
const result = await us.process({ type: 'deleteAll' })
|
|
805
|
+
|
|
806
|
+
response({ error: false, message: result, res, status: 200 })
|
|
807
|
+
})
|
|
763
808
|
|
|
764
809
|
User.route('/user/:id')
|
|
765
810
|
.get(
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
res: CustomResponse,
|
|
769
|
-
next: NextFunction
|
|
770
|
-
): Promise<void> => {
|
|
811
|
+
validatorCompiler(idSchema, 'params'),
|
|
812
|
+
async (req: CustomRequest, res: CustomResponse): Promise<void> => {
|
|
771
813
|
const {
|
|
772
814
|
params: { id }
|
|
773
815
|
} = req
|
|
816
|
+
const us = new UserService({ id })
|
|
817
|
+
const result = await us.process({ type: 'getOne' })
|
|
774
818
|
|
|
775
|
-
|
|
776
|
-
await idSchema.validateAsync(id)
|
|
777
|
-
const us = new UserService({ id })
|
|
778
|
-
const result = await us.process({ type: 'getOne' })
|
|
779
|
-
response({ error: false, message: result, res, status: 200 })
|
|
780
|
-
} catch (e) {
|
|
781
|
-
if (e instanceof ValidationError)
|
|
782
|
-
return next(new httpErrors.UnprocessableEntity(e.message))
|
|
783
|
-
|
|
784
|
-
next(e)
|
|
785
|
-
}
|
|
819
|
+
response({ error: false, message: result, res, status: 200 })
|
|
786
820
|
}
|
|
787
821
|
)
|
|
788
822
|
.patch(
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
next: NextFunction
|
|
793
|
-
): Promise<void> => {
|
|
823
|
+
validatorCompiler(idSchema, 'params'),
|
|
824
|
+
validatorCompiler(storeUserSchema, 'body'),
|
|
825
|
+
async (req: CustomRequest, res: CustomResponse): Promise<void> => {
|
|
794
826
|
const {
|
|
795
827
|
body: { args },
|
|
796
828
|
params: { id }
|
|
797
829
|
} = req
|
|
798
|
-
const
|
|
830
|
+
const userDto = {
|
|
799
831
|
id,
|
|
800
832
|
...args
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
await userSchema.validateAsync(user)
|
|
805
|
-
const us = new UserService(user)
|
|
806
|
-
const result = await us.process({ type: 'update' })
|
|
807
|
-
response({ error: false, message: result, res, status: 200 })
|
|
808
|
-
} catch (e) {
|
|
809
|
-
if (e instanceof ValidationError)
|
|
810
|
-
return next(new httpErrors.UnprocessableEntity(e.message))
|
|
833
|
+
} as UserDTO
|
|
834
|
+
const us = new UserService({ userDto })
|
|
835
|
+
const result = await us.process({ type: 'update' })
|
|
811
836
|
|
|
812
|
-
|
|
813
|
-
}
|
|
837
|
+
response({ error: false, message: result, res, status: 200 })
|
|
814
838
|
}
|
|
815
839
|
)
|
|
816
840
|
.delete(
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
res: CustomResponse,
|
|
820
|
-
next: NextFunction
|
|
821
|
-
): Promise<void> => {
|
|
841
|
+
validatorCompiler(idSchema, 'params'),
|
|
842
|
+
async (req: CustomRequest, res: CustomResponse): Promise<void> => {
|
|
822
843
|
const {
|
|
823
844
|
params: { id }
|
|
824
845
|
} = req
|
|
846
|
+
const us = new UserService({ id })
|
|
847
|
+
const result = await us.process({ type: 'delete' })
|
|
825
848
|
|
|
826
|
-
|
|
827
|
-
await idSchema.validateAsync(id)
|
|
828
|
-
const us = new UserService({ id })
|
|
829
|
-
const result = await us.process({ type: 'delete' })
|
|
830
|
-
response({ error: false, message: result, res, status: 200 })
|
|
831
|
-
} catch (e) {
|
|
832
|
-
if (e instanceof ValidationError)
|
|
833
|
-
return next(new httpErrors.UnprocessableEntity(e.message))
|
|
834
|
-
|
|
835
|
-
next(e)
|
|
836
|
-
}
|
|
849
|
+
response({ error: false, message: result, res, status: 200 })
|
|
837
850
|
}
|
|
838
851
|
)
|
|
839
852
|
|
|
@@ -842,34 +855,48 @@ export { User }
|
|
|
842
855
|
file: `${projectName}/src/network/routes/user.ts`
|
|
843
856
|
}
|
|
844
857
|
},
|
|
845
|
-
'network/routes/
|
|
858
|
+
'network/routes/utils': {
|
|
846
859
|
index: {
|
|
847
|
-
content: `import
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
content: `import Joi from 'joi'
|
|
858
|
-
|
|
859
|
-
const userSchema = Joi.object().keys({
|
|
860
|
-
id: Joi.string().length(24).required(),
|
|
861
|
-
lastName: Joi.string().required(),
|
|
862
|
-
name: Joi.string().required()
|
|
860
|
+
content: `import { NextFunction } from 'express'
|
|
861
|
+
import httpErrors from 'http-errors'
|
|
862
|
+
import { TObject, TProperties } from '@sinclair/typebox'
|
|
863
|
+
import Ajv from 'ajv'
|
|
864
|
+
|
|
865
|
+
const ajv = new Ajv({
|
|
866
|
+
removeAdditional: true,
|
|
867
|
+
useDefaults: true,
|
|
868
|
+
coerceTypes: true,
|
|
869
|
+
nullable: true
|
|
863
870
|
})
|
|
864
871
|
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
872
|
+
type Middleware = (
|
|
873
|
+
req: CustomRequest,
|
|
874
|
+
res: CustomResponse,
|
|
875
|
+
next: NextFunction
|
|
876
|
+
) => void
|
|
877
|
+
|
|
878
|
+
const validatorCompiler = <T extends TProperties>(
|
|
879
|
+
schema: TObject<T>,
|
|
880
|
+
value: 'body' | 'params'
|
|
881
|
+
): Middleware => {
|
|
882
|
+
return (req: CustomRequest, res: CustomResponse, next: NextFunction) => {
|
|
883
|
+
const validate = ajv.compile(schema)
|
|
884
|
+
const ok = validate(req[value])
|
|
885
|
+
|
|
886
|
+
if (!ok && validate.errors) {
|
|
887
|
+
const [error] = validate.errors
|
|
888
|
+
const errorMessage = \`\${error.dataPath.replace('.', '')} \${error.message}\`
|
|
889
|
+
|
|
890
|
+
return next(new httpErrors.UnprocessableEntity(errorMessage))
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
next()
|
|
894
|
+
}
|
|
895
|
+
}
|
|
869
896
|
|
|
870
|
-
export {
|
|
897
|
+
export { validatorCompiler }
|
|
871
898
|
`,
|
|
872
|
-
file: `${projectName}/src/network/routes/
|
|
899
|
+
file: `${projectName}/src/network/routes/utils/index.ts`
|
|
873
900
|
}
|
|
874
901
|
},
|
|
875
902
|
utils: {
|
|
@@ -909,7 +936,7 @@ export { userSchema, storeUserSchema }
|
|
|
909
936
|
"summary": "Save a user in the database",
|
|
910
937
|
"operationId": "store",
|
|
911
938
|
"requestBody": {
|
|
912
|
-
"$ref": "#/components/requestBodies/
|
|
939
|
+
"$ref": "#/components/requestBodies/UserDTO"
|
|
913
940
|
},
|
|
914
941
|
"responses": {
|
|
915
942
|
"201": {
|
|
@@ -1103,7 +1130,7 @@ export { userSchema, storeUserSchema }
|
|
|
1103
1130
|
}
|
|
1104
1131
|
],
|
|
1105
1132
|
"requestBody": {
|
|
1106
|
-
"$ref": "#/components/requestBodies/
|
|
1133
|
+
"$ref": "#/components/requestBodies/UserDTO"
|
|
1107
1134
|
},
|
|
1108
1135
|
"responses": {
|
|
1109
1136
|
"200": {
|
|
@@ -1264,7 +1291,7 @@ export { userSchema, storeUserSchema }
|
|
|
1264
1291
|
}
|
|
1265
1292
|
},
|
|
1266
1293
|
"requestBodies": {
|
|
1267
|
-
"
|
|
1294
|
+
"UserDTO": {
|
|
1268
1295
|
"description": "User name and last name",
|
|
1269
1296
|
"content": {
|
|
1270
1297
|
"application/json": {
|
|
@@ -1360,24 +1387,26 @@ export { applyRoutes }
|
|
|
1360
1387
|
file: `${projectName}/src/network/router.ts`
|
|
1361
1388
|
},
|
|
1362
1389
|
server: {
|
|
1363
|
-
content: `import
|
|
1390
|
+
content: `import fastify, { FastifyInstance } from 'fastify'
|
|
1364
1391
|
import mongoose from 'mongoose'
|
|
1365
1392
|
|
|
1366
1393
|
import { applyRoutes } from './router'
|
|
1394
|
+
import { validatorCompiler } from './utils'
|
|
1367
1395
|
|
|
1368
1396
|
const PORT = process.env.PORT ?? '1996'
|
|
1369
1397
|
|
|
1370
1398
|
class Server {
|
|
1371
|
-
|
|
1372
|
-
|
|
1399
|
+
#app: FastifyInstance
|
|
1400
|
+
#connection: mongoose.Connection | undefined
|
|
1373
1401
|
|
|
1374
1402
|
constructor() {
|
|
1375
|
-
this
|
|
1376
|
-
this
|
|
1403
|
+
this.#app = fastify({ logger: { prettyPrint: true } })
|
|
1404
|
+
this.#config()
|
|
1377
1405
|
}
|
|
1378
1406
|
|
|
1379
|
-
|
|
1380
|
-
this.
|
|
1407
|
+
#config() {
|
|
1408
|
+
this.#app.register(require('fastify-cors'), {})
|
|
1409
|
+
this.#app.addHook('preHandler', (req, reply, done) => {
|
|
1381
1410
|
reply.header('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE')
|
|
1382
1411
|
reply.header('Access-Control-Allow-Origin', '*')
|
|
1383
1412
|
reply.header(
|
|
@@ -1386,25 +1415,26 @@ class Server {
|
|
|
1386
1415
|
)
|
|
1387
1416
|
done()
|
|
1388
1417
|
})
|
|
1389
|
-
|
|
1418
|
+
this.#app.setValidatorCompiler(validatorCompiler)
|
|
1419
|
+
applyRoutes(this.#app)
|
|
1390
1420
|
}
|
|
1391
1421
|
|
|
1392
|
-
|
|
1393
|
-
this
|
|
1422
|
+
async #mongo(): Promise<void> {
|
|
1423
|
+
this.#connection = mongoose.connection
|
|
1394
1424
|
const connection = {
|
|
1395
1425
|
keepAlive: true,
|
|
1396
1426
|
useNewUrlParser: true,
|
|
1397
1427
|
useUnifiedTopology: true
|
|
1398
1428
|
}
|
|
1399
|
-
this.
|
|
1400
|
-
this.
|
|
1429
|
+
this.#connection.on('connected', () => {
|
|
1430
|
+
this.#app.log.info('Mongo connection established.')
|
|
1401
1431
|
})
|
|
1402
|
-
this.
|
|
1403
|
-
this.
|
|
1432
|
+
this.#connection.on('reconnected', () => {
|
|
1433
|
+
this.#app.log.info('Mongo connection reestablished')
|
|
1404
1434
|
})
|
|
1405
|
-
this.
|
|
1406
|
-
this.
|
|
1407
|
-
this.
|
|
1435
|
+
this.#connection.on('disconnected', () => {
|
|
1436
|
+
this.#app.log.info('Mongo connection disconnected')
|
|
1437
|
+
this.#app.log.info('Trying to reconnected to Mongo...')
|
|
1408
1438
|
setTimeout(() => {
|
|
1409
1439
|
mongoose.connect(process.env.MONGO_URI as string, {
|
|
1410
1440
|
...connection,
|
|
@@ -1413,20 +1443,20 @@ class Server {
|
|
|
1413
1443
|
})
|
|
1414
1444
|
}, 3000)
|
|
1415
1445
|
})
|
|
1416
|
-
this.
|
|
1417
|
-
this.
|
|
1446
|
+
this.#connection.on('close', () => {
|
|
1447
|
+
this.#app.log.info('Mongo connection closed')
|
|
1418
1448
|
})
|
|
1419
|
-
this.
|
|
1420
|
-
this.
|
|
1421
|
-
this.
|
|
1449
|
+
this.#connection.on('error', (e: Error) => {
|
|
1450
|
+
this.#app.log.info('Mongo connection error:')
|
|
1451
|
+
this.#app.log.error(e)
|
|
1422
1452
|
})
|
|
1423
1453
|
await mongoose.connect(process.env.MONGO_URI as string, connection)
|
|
1424
1454
|
}
|
|
1425
1455
|
|
|
1426
1456
|
public async start(): Promise<void> {
|
|
1427
1457
|
try {
|
|
1428
|
-
await this.
|
|
1429
|
-
this
|
|
1458
|
+
await this.#app.listen(PORT)
|
|
1459
|
+
this.#mongo()
|
|
1430
1460
|
} catch (e) {
|
|
1431
1461
|
console.error(e)
|
|
1432
1462
|
}
|
|
@@ -1510,26 +1540,31 @@ export * from './docs'
|
|
|
1510
1540
|
},
|
|
1511
1541
|
user: {
|
|
1512
1542
|
content: `import { FastifyInstance } from 'fastify'
|
|
1543
|
+
import { Type } from '@sinclair/typebox'
|
|
1513
1544
|
|
|
1514
1545
|
import { response } from 'network/response'
|
|
1515
|
-
import {
|
|
1546
|
+
import {
|
|
1547
|
+
userDto,
|
|
1548
|
+
idSchema,
|
|
1549
|
+
IdSchema,
|
|
1550
|
+
storeUserSchema,
|
|
1551
|
+
StoreUser
|
|
1552
|
+
} from 'schemas'
|
|
1516
1553
|
import { UserService } from 'services'
|
|
1517
1554
|
|
|
1518
1555
|
const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
1519
1556
|
app
|
|
1520
|
-
.post<{ Body:
|
|
1557
|
+
.post<{ Body: StoreUser }>(
|
|
1521
1558
|
\`\${prefix}/users\`,
|
|
1522
1559
|
{
|
|
1523
1560
|
schema: {
|
|
1524
|
-
body:
|
|
1525
|
-
args: storeUserSchema
|
|
1526
|
-
},
|
|
1561
|
+
body: storeUserSchema,
|
|
1527
1562
|
response: {
|
|
1528
1563
|
200: {
|
|
1529
1564
|
error: {
|
|
1530
1565
|
type: 'boolean'
|
|
1531
1566
|
},
|
|
1532
|
-
message:
|
|
1567
|
+
message: userDto
|
|
1533
1568
|
}
|
|
1534
1569
|
},
|
|
1535
1570
|
tags: ['user']
|
|
@@ -1541,14 +1576,16 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1541
1576
|
args: { lastName, name }
|
|
1542
1577
|
}
|
|
1543
1578
|
} = request
|
|
1544
|
-
const us = new UserService({
|
|
1579
|
+
const us = new UserService({
|
|
1580
|
+
userDtoWithoutId: { lastName, name }
|
|
1581
|
+
})
|
|
1545
1582
|
const user = await us.process({ type: 'store' })
|
|
1546
1583
|
|
|
1547
1584
|
response({
|
|
1548
1585
|
error: false,
|
|
1549
1586
|
message: user,
|
|
1550
1587
|
reply,
|
|
1551
|
-
status:
|
|
1588
|
+
status: 201
|
|
1552
1589
|
})
|
|
1553
1590
|
}
|
|
1554
1591
|
)
|
|
@@ -1561,10 +1598,7 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1561
1598
|
error: {
|
|
1562
1599
|
type: 'boolean'
|
|
1563
1600
|
},
|
|
1564
|
-
message:
|
|
1565
|
-
type: 'array',
|
|
1566
|
-
items: userSchema
|
|
1567
|
-
}
|
|
1601
|
+
message: Type.Array(userDto)
|
|
1568
1602
|
}
|
|
1569
1603
|
},
|
|
1570
1604
|
tags: ['user']
|
|
@@ -1611,19 +1645,17 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1611
1645
|
})
|
|
1612
1646
|
}
|
|
1613
1647
|
)
|
|
1614
|
-
.get<{ Params:
|
|
1648
|
+
.get<{ Params: IdSchema }>(
|
|
1615
1649
|
\`\${prefix}/user/:id\`,
|
|
1616
1650
|
{
|
|
1617
1651
|
schema: {
|
|
1618
|
-
params:
|
|
1619
|
-
id: idSchema
|
|
1620
|
-
},
|
|
1652
|
+
params: idSchema,
|
|
1621
1653
|
response: {
|
|
1622
1654
|
200: {
|
|
1623
1655
|
error: {
|
|
1624
1656
|
type: 'boolean'
|
|
1625
1657
|
},
|
|
1626
|
-
message:
|
|
1658
|
+
message: userDto
|
|
1627
1659
|
}
|
|
1628
1660
|
},
|
|
1629
1661
|
tags: ['user']
|
|
@@ -1644,22 +1676,18 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1644
1676
|
})
|
|
1645
1677
|
}
|
|
1646
1678
|
)
|
|
1647
|
-
.patch<{ Body:
|
|
1679
|
+
.patch<{ Body: StoreUser; Params: IdSchema }>(
|
|
1648
1680
|
\`\${prefix}/user/:id\`,
|
|
1649
1681
|
{
|
|
1650
1682
|
schema: {
|
|
1651
|
-
body:
|
|
1652
|
-
|
|
1653
|
-
},
|
|
1654
|
-
params: {
|
|
1655
|
-
id: idSchema
|
|
1656
|
-
},
|
|
1683
|
+
body: storeUserSchema,
|
|
1684
|
+
params: idSchema,
|
|
1657
1685
|
response: {
|
|
1658
1686
|
200: {
|
|
1659
1687
|
error: {
|
|
1660
1688
|
type: 'boolean'
|
|
1661
1689
|
},
|
|
1662
|
-
message:
|
|
1690
|
+
message: userDto
|
|
1663
1691
|
}
|
|
1664
1692
|
},
|
|
1665
1693
|
tags: ['user']
|
|
@@ -1672,7 +1700,9 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1672
1700
|
},
|
|
1673
1701
|
params: { id }
|
|
1674
1702
|
} = request
|
|
1675
|
-
const us = new UserService({
|
|
1703
|
+
const us = new UserService({
|
|
1704
|
+
userDto: { name, lastName, id }
|
|
1705
|
+
})
|
|
1676
1706
|
const user = await us.process({ type: 'update' })
|
|
1677
1707
|
|
|
1678
1708
|
response({
|
|
@@ -1683,13 +1713,11 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1683
1713
|
})
|
|
1684
1714
|
}
|
|
1685
1715
|
)
|
|
1686
|
-
.delete<{ Params:
|
|
1716
|
+
.delete<{ Params: IdSchema }>(
|
|
1687
1717
|
\`\${prefix}/user/:id\`,
|
|
1688
1718
|
{
|
|
1689
1719
|
schema: {
|
|
1690
|
-
params:
|
|
1691
|
-
id: idSchema
|
|
1692
|
-
},
|
|
1720
|
+
params: idSchema,
|
|
1693
1721
|
response: {
|
|
1694
1722
|
200: {
|
|
1695
1723
|
error: {
|
|
@@ -1725,45 +1753,57 @@ export { User }
|
|
|
1725
1753
|
file: `${projectName}/src/network/routes/user.ts`
|
|
1726
1754
|
}
|
|
1727
1755
|
},
|
|
1728
|
-
'network/
|
|
1756
|
+
'network/utils': {
|
|
1729
1757
|
index: {
|
|
1730
|
-
content:
|
|
1758
|
+
content: `/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1759
|
+
import {
|
|
1760
|
+
FastifyRouteSchemaDef,
|
|
1761
|
+
FastifyValidationResult
|
|
1762
|
+
} from 'fastify/types/schema'
|
|
1763
|
+
import httpErrors from 'http-errors'
|
|
1764
|
+
import Ajv from 'ajv'
|
|
1731
1765
|
|
|
1732
|
-
const
|
|
1766
|
+
const ajv = new Ajv({
|
|
1767
|
+
removeAdditional: true,
|
|
1768
|
+
useDefaults: true,
|
|
1769
|
+
coerceTypes: true,
|
|
1770
|
+
nullable: true
|
|
1771
|
+
})
|
|
1733
1772
|
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
},
|
|
1739
|
-
user: {
|
|
1740
|
-
content: `import { Type } from '@sinclair/typebox'
|
|
1773
|
+
const validatorCompiler = ({
|
|
1774
|
+
schema
|
|
1775
|
+
}: FastifyRouteSchemaDef<any>): FastifyValidationResult => {
|
|
1776
|
+
const validate = ajv.compile(schema)
|
|
1741
1777
|
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
lastName: Type.Optional(Type.String()),
|
|
1745
|
-
name: Type.Optional(Type.String()),
|
|
1746
|
-
updatedAt: Type.Optional(Type.String())
|
|
1747
|
-
})
|
|
1778
|
+
return (data: unknown): boolean => {
|
|
1779
|
+
const ok = validate(data)
|
|
1748
1780
|
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1781
|
+
if (!ok && validate.errors) {
|
|
1782
|
+
const [error] = validate.errors
|
|
1783
|
+
const errorMessage = \`\${error.dataPath.replace('.', '')} \${error.message}\`
|
|
1784
|
+
|
|
1785
|
+
throw new httpErrors.UnprocessableEntity(errorMessage)
|
|
1786
|
+
}
|
|
1753
1787
|
|
|
1754
|
-
|
|
1788
|
+
return true
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
export { validatorCompiler }
|
|
1755
1793
|
`,
|
|
1756
|
-
file: `${projectName}/src/network/
|
|
1794
|
+
file: `${projectName}/src/network/utils/index.ts`
|
|
1757
1795
|
}
|
|
1758
1796
|
}
|
|
1759
1797
|
}
|
|
1760
1798
|
|
|
1761
|
-
const expressFolders = `${projectName}/src/utils
|
|
1799
|
+
const expressFolders = `${projectName}/src/utils \
|
|
1800
|
+
${projectName}/src/@types/custom \
|
|
1801
|
+
${projectName}/src/network/routes/utils`
|
|
1802
|
+
|
|
1803
|
+
const fastifyFolders = `${projectName}/src/network/utils`
|
|
1762
1804
|
|
|
1763
1805
|
const createFoldersCommands = `mkdir ${projectName}/src \
|
|
1764
1806
|
${projectName}/src/@types \
|
|
1765
|
-
${projectName}/src/@types/dto \
|
|
1766
|
-
${projectName}/src/@types/custom \
|
|
1767
1807
|
${projectName}/src/@types/models \
|
|
1768
1808
|
${projectName}/src/database \
|
|
1769
1809
|
${projectName}/src/database/mongo \
|
|
@@ -1771,11 +1811,11 @@ ${projectName}/src/database/mongo/models \
|
|
|
1771
1811
|
${projectName}/src/database/mongo/queries \
|
|
1772
1812
|
${projectName}/src/network \
|
|
1773
1813
|
${projectName}/src/network/routes \
|
|
1774
|
-
${projectName}/src/
|
|
1814
|
+
${projectName}/src/schemas \
|
|
1775
1815
|
${projectName}/src/services \
|
|
1776
1816
|
${projectName}/src/services/utils \
|
|
1777
1817
|
${projectName}/src/services/utils/messages \
|
|
1778
|
-
${fastify ?
|
|
1818
|
+
${fastify ? `${fastifyFolders}` : `${expressFolders}`}
|
|
1779
1819
|
`
|
|
1780
1820
|
|
|
1781
1821
|
if (os.platform() === 'win32')
|
|
@@ -1785,19 +1825,12 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1785
1825
|
// /@types
|
|
1786
1826
|
await writeFile(data['@types'].index.file, data['@types'].index.content)
|
|
1787
1827
|
|
|
1788
|
-
// /@types/dto
|
|
1789
|
-
await writeFile(data['@types/dto'].user.file, data['@types/dto'].user.content)
|
|
1790
|
-
|
|
1791
1828
|
// /@types/models
|
|
1792
1829
|
await writeFile(
|
|
1793
1830
|
data['@types/models'].user.file,
|
|
1794
1831
|
data['@types/models'].user.content
|
|
1795
1832
|
)
|
|
1796
1833
|
|
|
1797
|
-
// /services
|
|
1798
|
-
await writeFile(data.services.user.file, data.services.user.content)
|
|
1799
|
-
await writeFile(data.services.index.file, data.services.index.content)
|
|
1800
|
-
|
|
1801
1834
|
// /database
|
|
1802
1835
|
await writeFile(data.database.index.file, data.database.index.content)
|
|
1803
1836
|
await writeFile(
|
|
@@ -1821,6 +1854,14 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1821
1854
|
data['database/mongo/queries'].user.content
|
|
1822
1855
|
)
|
|
1823
1856
|
|
|
1857
|
+
// /schemas
|
|
1858
|
+
await writeFile(data.schemas.user.file, data.schemas.user.content)
|
|
1859
|
+
await writeFile(data.schemas.index.file, data.schemas.index.content)
|
|
1860
|
+
|
|
1861
|
+
// /services
|
|
1862
|
+
await writeFile(data.services.user.file, data.services.user.content)
|
|
1863
|
+
await writeFile(data.services.index.file, data.services.index.content)
|
|
1864
|
+
|
|
1824
1865
|
// /services/utils
|
|
1825
1866
|
await writeFile(
|
|
1826
1867
|
data['services/utils'].index.file,
|
|
@@ -1882,16 +1923,22 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1882
1923
|
fastifyData['network/routes'].index.content
|
|
1883
1924
|
)
|
|
1884
1925
|
|
|
1885
|
-
// /network/routes/
|
|
1926
|
+
// /network/routes/utils
|
|
1927
|
+
await writeFile(
|
|
1928
|
+
fastifyData['network/utils'].index.file,
|
|
1929
|
+
fastifyData['network/utils'].index.content
|
|
1930
|
+
)
|
|
1931
|
+
} else {
|
|
1932
|
+
// /@types/custom
|
|
1886
1933
|
await writeFile(
|
|
1887
|
-
|
|
1888
|
-
|
|
1934
|
+
expressData['@types/custom'].request.file,
|
|
1935
|
+
expressData['@types/custom'].request.content
|
|
1889
1936
|
)
|
|
1890
1937
|
await writeFile(
|
|
1891
|
-
|
|
1892
|
-
|
|
1938
|
+
expressData['@types/custom'].response.file,
|
|
1939
|
+
expressData['@types/custom'].response.content
|
|
1893
1940
|
)
|
|
1894
|
-
|
|
1941
|
+
|
|
1895
1942
|
// /network
|
|
1896
1943
|
await writeFile(
|
|
1897
1944
|
expressData.network.response.file,
|
|
@@ -1920,14 +1967,10 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1920
1967
|
expressData['network/routes'].index.content
|
|
1921
1968
|
)
|
|
1922
1969
|
|
|
1923
|
-
// /network/routes/
|
|
1924
|
-
await writeFile(
|
|
1925
|
-
expressData['network/routes/schemas'].index.file,
|
|
1926
|
-
expressData['network/routes/schemas'].index.content
|
|
1927
|
-
)
|
|
1970
|
+
// /network/routes/utils
|
|
1928
1971
|
await writeFile(
|
|
1929
|
-
expressData['network/routes/
|
|
1930
|
-
expressData['network/routes/
|
|
1972
|
+
expressData['network/routes/utils'].index.file,
|
|
1973
|
+
expressData['network/routes/utils'].index.content
|
|
1931
1974
|
)
|
|
1932
1975
|
|
|
1933
1976
|
// /utils
|
|
@@ -1936,15 +1979,5 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1936
1979
|
expressData.utils.index.file,
|
|
1937
1980
|
expressData.utils.index.content
|
|
1938
1981
|
)
|
|
1939
|
-
|
|
1940
|
-
// /@types/custom
|
|
1941
|
-
await writeFile(
|
|
1942
|
-
expressData['@types/custom'].request.file,
|
|
1943
|
-
expressData['@types/custom'].request.content
|
|
1944
|
-
)
|
|
1945
|
-
await writeFile(
|
|
1946
|
-
expressData['@types/custom'].response.file,
|
|
1947
|
-
expressData['@types/custom'].response.content
|
|
1948
|
-
)
|
|
1949
1982
|
}
|
|
1950
1983
|
}
|