@anthonylzq/simba.js 3.1.0 → 4.2.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 +27 -13
- package/lib/index.js +0 -2
- package/lib/src/functions/api.js +377 -345
- package/lib/src/functions/tsconfig.js +1 -1
- package/lib/src/index.js +4 -4
- package/package.json +4 -4
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
|
-
}
|
|
833
|
+
} as UserDTO
|
|
834
|
+
const us = new UserService({ userDto })
|
|
835
|
+
const result = await us.process({ type: 'update' })
|
|
802
836
|
|
|
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))
|
|
811
|
-
|
|
812
|
-
next(e)
|
|
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
|
+
}
|
|
869
892
|
|
|
870
|
-
|
|
893
|
+
next()
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
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": {
|
|
@@ -1368,16 +1395,17 @@ import { applyRoutes } from './router'
|
|
|
1368
1395
|
const PORT = process.env.PORT ?? '1996'
|
|
1369
1396
|
|
|
1370
1397
|
class Server {
|
|
1371
|
-
|
|
1372
|
-
|
|
1398
|
+
#app: FastifyInstance
|
|
1399
|
+
#connection: mongoose.Connection | undefined
|
|
1373
1400
|
|
|
1374
1401
|
constructor() {
|
|
1375
|
-
this
|
|
1376
|
-
this
|
|
1402
|
+
this.#app = Fastify({ logger: true })
|
|
1403
|
+
this.#config()
|
|
1377
1404
|
}
|
|
1378
1405
|
|
|
1379
|
-
|
|
1380
|
-
this.
|
|
1406
|
+
#config() {
|
|
1407
|
+
this.#app.register(require('fastify-cors'), {})
|
|
1408
|
+
this.#app.addHook('preHandler', (req, reply, done) => {
|
|
1381
1409
|
reply.header('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE')
|
|
1382
1410
|
reply.header('Access-Control-Allow-Origin', '*')
|
|
1383
1411
|
reply.header(
|
|
@@ -1386,25 +1414,25 @@ class Server {
|
|
|
1386
1414
|
)
|
|
1387
1415
|
done()
|
|
1388
1416
|
})
|
|
1389
|
-
applyRoutes(this
|
|
1417
|
+
applyRoutes(this.#app)
|
|
1390
1418
|
}
|
|
1391
1419
|
|
|
1392
|
-
|
|
1393
|
-
this
|
|
1420
|
+
async #mongo(): Promise<void> {
|
|
1421
|
+
this.#connection = mongoose.connection
|
|
1394
1422
|
const connection = {
|
|
1395
1423
|
keepAlive: true,
|
|
1396
1424
|
useNewUrlParser: true,
|
|
1397
1425
|
useUnifiedTopology: true
|
|
1398
1426
|
}
|
|
1399
|
-
this.
|
|
1400
|
-
this.
|
|
1427
|
+
this.#connection.on('connected', () => {
|
|
1428
|
+
this.#app.log.info('Mongo connection established.')
|
|
1401
1429
|
})
|
|
1402
|
-
this.
|
|
1403
|
-
this.
|
|
1430
|
+
this.#connection.on('reconnected', () => {
|
|
1431
|
+
this.#app.log.info('Mongo connection reestablished')
|
|
1404
1432
|
})
|
|
1405
|
-
this.
|
|
1406
|
-
this.
|
|
1407
|
-
this.
|
|
1433
|
+
this.#connection.on('disconnected', () => {
|
|
1434
|
+
this.#app.log.info('Mongo connection disconnected')
|
|
1435
|
+
this.#app.log.info('Trying to reconnected to Mongo...')
|
|
1408
1436
|
setTimeout(() => {
|
|
1409
1437
|
mongoose.connect(process.env.MONGO_URI as string, {
|
|
1410
1438
|
...connection,
|
|
@@ -1413,20 +1441,20 @@ class Server {
|
|
|
1413
1441
|
})
|
|
1414
1442
|
}, 3000)
|
|
1415
1443
|
})
|
|
1416
|
-
this.
|
|
1417
|
-
this.
|
|
1444
|
+
this.#connection.on('close', () => {
|
|
1445
|
+
this.#app.log.info('Mongo connection closed')
|
|
1418
1446
|
})
|
|
1419
|
-
this.
|
|
1420
|
-
this.
|
|
1421
|
-
this.
|
|
1447
|
+
this.#connection.on('error', (e: Error) => {
|
|
1448
|
+
this.#app.log.info('Mongo connection error:')
|
|
1449
|
+
this.#app.log.error(e)
|
|
1422
1450
|
})
|
|
1423
1451
|
await mongoose.connect(process.env.MONGO_URI as string, connection)
|
|
1424
1452
|
}
|
|
1425
1453
|
|
|
1426
1454
|
public async start(): Promise<void> {
|
|
1427
1455
|
try {
|
|
1428
|
-
await this.
|
|
1429
|
-
this
|
|
1456
|
+
await this.#app.listen(PORT)
|
|
1457
|
+
this.#mongo()
|
|
1430
1458
|
} catch (e) {
|
|
1431
1459
|
console.error(e)
|
|
1432
1460
|
}
|
|
@@ -1479,7 +1507,7 @@ const Docs = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1479
1507
|
}
|
|
1480
1508
|
|
|
1481
1509
|
export { Docs }
|
|
1482
|
-
|
|
1510
|
+
`,
|
|
1483
1511
|
file: `${projectName}/src/network/routes/docs.ts`
|
|
1484
1512
|
},
|
|
1485
1513
|
home: {
|
|
@@ -1510,30 +1538,37 @@ export * from './docs'
|
|
|
1510
1538
|
},
|
|
1511
1539
|
user: {
|
|
1512
1540
|
content: `import { FastifyInstance } from 'fastify'
|
|
1541
|
+
import { Type } from '@sinclair/typebox'
|
|
1513
1542
|
|
|
1514
1543
|
import { response } from 'network/response'
|
|
1515
|
-
import {
|
|
1544
|
+
import {
|
|
1545
|
+
userDto,
|
|
1546
|
+
idSchema,
|
|
1547
|
+
IdSchema,
|
|
1548
|
+
storeUserSchema,
|
|
1549
|
+
StoreUser
|
|
1550
|
+
} from 'schemas'
|
|
1516
1551
|
import { UserService } from 'services'
|
|
1552
|
+
import { validatorCompiler } from './utils'
|
|
1517
1553
|
|
|
1518
1554
|
const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
1519
1555
|
app
|
|
1520
|
-
.post<{ Body:
|
|
1556
|
+
.post<{ Body: StoreUser }>(
|
|
1521
1557
|
\`\${prefix}/users\`,
|
|
1522
1558
|
{
|
|
1523
1559
|
schema: {
|
|
1524
|
-
body:
|
|
1525
|
-
args: storeUserSchema
|
|
1526
|
-
},
|
|
1560
|
+
body: storeUserSchema,
|
|
1527
1561
|
response: {
|
|
1528
1562
|
200: {
|
|
1529
1563
|
error: {
|
|
1530
1564
|
type: 'boolean'
|
|
1531
1565
|
},
|
|
1532
|
-
message:
|
|
1566
|
+
message: userDto
|
|
1533
1567
|
}
|
|
1534
1568
|
},
|
|
1535
1569
|
tags: ['user']
|
|
1536
|
-
}
|
|
1570
|
+
},
|
|
1571
|
+
validatorCompiler
|
|
1537
1572
|
},
|
|
1538
1573
|
async (request, reply) => {
|
|
1539
1574
|
const {
|
|
@@ -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,23 +1645,22 @@ 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']
|
|
1630
|
-
}
|
|
1662
|
+
},
|
|
1663
|
+
validatorCompiler
|
|
1631
1664
|
},
|
|
1632
1665
|
async (request, reply) => {
|
|
1633
1666
|
const {
|
|
@@ -1644,22 +1677,18 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1644
1677
|
})
|
|
1645
1678
|
}
|
|
1646
1679
|
)
|
|
1647
|
-
.patch<{ Body:
|
|
1680
|
+
.patch<{ Body: StoreUser; Params: IdSchema }>(
|
|
1648
1681
|
\`\${prefix}/user/:id\`,
|
|
1649
1682
|
{
|
|
1650
1683
|
schema: {
|
|
1651
|
-
body:
|
|
1652
|
-
|
|
1653
|
-
},
|
|
1654
|
-
params: {
|
|
1655
|
-
id: idSchema
|
|
1656
|
-
},
|
|
1684
|
+
body: storeUserSchema,
|
|
1685
|
+
params: idSchema,
|
|
1657
1686
|
response: {
|
|
1658
1687
|
200: {
|
|
1659
1688
|
error: {
|
|
1660
1689
|
type: 'boolean'
|
|
1661
1690
|
},
|
|
1662
|
-
message:
|
|
1691
|
+
message: userDto
|
|
1663
1692
|
}
|
|
1664
1693
|
},
|
|
1665
1694
|
tags: ['user']
|
|
@@ -1672,7 +1701,9 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1672
1701
|
},
|
|
1673
1702
|
params: { id }
|
|
1674
1703
|
} = request
|
|
1675
|
-
const us = new UserService({
|
|
1704
|
+
const us = new UserService({
|
|
1705
|
+
userDto: { name, lastName, id }
|
|
1706
|
+
})
|
|
1676
1707
|
const user = await us.process({ type: 'update' })
|
|
1677
1708
|
|
|
1678
1709
|
response({
|
|
@@ -1683,13 +1714,11 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1683
1714
|
})
|
|
1684
1715
|
}
|
|
1685
1716
|
)
|
|
1686
|
-
.delete<{ Params:
|
|
1717
|
+
.delete<{ Params: IdSchema }>(
|
|
1687
1718
|
\`\${prefix}/user/:id\`,
|
|
1688
1719
|
{
|
|
1689
1720
|
schema: {
|
|
1690
|
-
params:
|
|
1691
|
-
id: idSchema
|
|
1692
|
-
},
|
|
1721
|
+
params: idSchema,
|
|
1693
1722
|
response: {
|
|
1694
1723
|
200: {
|
|
1695
1724
|
error: {
|
|
@@ -1725,45 +1754,54 @@ export { User }
|
|
|
1725
1754
|
file: `${projectName}/src/network/routes/user.ts`
|
|
1726
1755
|
}
|
|
1727
1756
|
},
|
|
1728
|
-
'network/routes/
|
|
1757
|
+
'network/routes/utils': {
|
|
1729
1758
|
index: {
|
|
1730
|
-
content:
|
|
1759
|
+
content: `/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1760
|
+
import {
|
|
1761
|
+
FastifyRouteSchemaDef,
|
|
1762
|
+
FastifyValidationResult
|
|
1763
|
+
} from 'fastify/types/schema'
|
|
1764
|
+
import httpErrors from 'http-errors'
|
|
1765
|
+
import Ajv from 'ajv'
|
|
1731
1766
|
|
|
1732
|
-
const
|
|
1767
|
+
const ajv = new Ajv({
|
|
1768
|
+
removeAdditional: true,
|
|
1769
|
+
useDefaults: true,
|
|
1770
|
+
coerceTypes: true,
|
|
1771
|
+
nullable: true
|
|
1772
|
+
})
|
|
1733
1773
|
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
},
|
|
1739
|
-
user: {
|
|
1740
|
-
content: `import { Type } from '@sinclair/typebox'
|
|
1774
|
+
const validatorCompiler = ({
|
|
1775
|
+
schema
|
|
1776
|
+
}: FastifyRouteSchemaDef<any>): FastifyValidationResult => {
|
|
1777
|
+
const validate = ajv.compile(schema)
|
|
1741
1778
|
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
lastName: Type.Optional(Type.String()),
|
|
1745
|
-
name: Type.Optional(Type.String()),
|
|
1746
|
-
updatedAt: Type.Optional(Type.String())
|
|
1747
|
-
})
|
|
1779
|
+
return (data: unknown): boolean => {
|
|
1780
|
+
const ok = validate(data)
|
|
1748
1781
|
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1782
|
+
if (!ok && validate.errors) {
|
|
1783
|
+
const [error] = validate.errors
|
|
1784
|
+
const errorMessage = \`\${error.dataPath.replace('.', '')} \${error.message}\`
|
|
1785
|
+
|
|
1786
|
+
throw new httpErrors.UnprocessableEntity(errorMessage)
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
return true
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1753
1792
|
|
|
1754
|
-
export {
|
|
1793
|
+
export { validatorCompiler }
|
|
1755
1794
|
`,
|
|
1756
|
-
file: `${projectName}/src/network/routes/
|
|
1795
|
+
file: `${projectName}/src/network/routes/utils/index.ts`
|
|
1757
1796
|
}
|
|
1758
1797
|
}
|
|
1759
1798
|
}
|
|
1760
1799
|
|
|
1761
|
-
const expressFolders = `${projectName}/src/utils
|
|
1800
|
+
const expressFolders = `${projectName}/src/utils \
|
|
1801
|
+
${projectName}/src/@types/custom`
|
|
1762
1802
|
|
|
1763
1803
|
const createFoldersCommands = `mkdir ${projectName}/src \
|
|
1764
1804
|
${projectName}/src/@types \
|
|
1765
|
-
${projectName}/src/@types/dto \
|
|
1766
|
-
${projectName}/src/@types/custom \
|
|
1767
1805
|
${projectName}/src/@types/models \
|
|
1768
1806
|
${projectName}/src/database \
|
|
1769
1807
|
${projectName}/src/database/mongo \
|
|
@@ -1771,7 +1809,8 @@ ${projectName}/src/database/mongo/models \
|
|
|
1771
1809
|
${projectName}/src/database/mongo/queries \
|
|
1772
1810
|
${projectName}/src/network \
|
|
1773
1811
|
${projectName}/src/network/routes \
|
|
1774
|
-
${projectName}/src/network/routes/
|
|
1812
|
+
${projectName}/src/network/routes/utils \
|
|
1813
|
+
${projectName}/src/schemas \
|
|
1775
1814
|
${projectName}/src/services \
|
|
1776
1815
|
${projectName}/src/services/utils \
|
|
1777
1816
|
${projectName}/src/services/utils/messages \
|
|
@@ -1785,19 +1824,12 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1785
1824
|
// /@types
|
|
1786
1825
|
await writeFile(data['@types'].index.file, data['@types'].index.content)
|
|
1787
1826
|
|
|
1788
|
-
// /@types/dto
|
|
1789
|
-
await writeFile(data['@types/dto'].user.file, data['@types/dto'].user.content)
|
|
1790
|
-
|
|
1791
1827
|
// /@types/models
|
|
1792
1828
|
await writeFile(
|
|
1793
1829
|
data['@types/models'].user.file,
|
|
1794
1830
|
data['@types/models'].user.content
|
|
1795
1831
|
)
|
|
1796
1832
|
|
|
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
1833
|
// /database
|
|
1802
1834
|
await writeFile(data.database.index.file, data.database.index.content)
|
|
1803
1835
|
await writeFile(
|
|
@@ -1821,6 +1853,14 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1821
1853
|
data['database/mongo/queries'].user.content
|
|
1822
1854
|
)
|
|
1823
1855
|
|
|
1856
|
+
// /schemas
|
|
1857
|
+
await writeFile(data.schemas.user.file, data.schemas.user.content)
|
|
1858
|
+
await writeFile(data.schemas.index.file, data.schemas.index.content)
|
|
1859
|
+
|
|
1860
|
+
// /services
|
|
1861
|
+
await writeFile(data.services.user.file, data.services.user.content)
|
|
1862
|
+
await writeFile(data.services.index.file, data.services.index.content)
|
|
1863
|
+
|
|
1824
1864
|
// /services/utils
|
|
1825
1865
|
await writeFile(
|
|
1826
1866
|
data['services/utils'].index.file,
|
|
@@ -1882,16 +1922,22 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1882
1922
|
fastifyData['network/routes'].index.content
|
|
1883
1923
|
)
|
|
1884
1924
|
|
|
1885
|
-
// /network/routes/
|
|
1925
|
+
// /network/routes/utils
|
|
1926
|
+
await writeFile(
|
|
1927
|
+
fastifyData['network/routes/utils'].index.file,
|
|
1928
|
+
fastifyData['network/routes/utils'].index.content
|
|
1929
|
+
)
|
|
1930
|
+
} else {
|
|
1931
|
+
// /@types/custom
|
|
1886
1932
|
await writeFile(
|
|
1887
|
-
|
|
1888
|
-
|
|
1933
|
+
expressData['@types/custom'].request.file,
|
|
1934
|
+
expressData['@types/custom'].request.content
|
|
1889
1935
|
)
|
|
1890
1936
|
await writeFile(
|
|
1891
|
-
|
|
1892
|
-
|
|
1937
|
+
expressData['@types/custom'].response.file,
|
|
1938
|
+
expressData['@types/custom'].response.content
|
|
1893
1939
|
)
|
|
1894
|
-
|
|
1940
|
+
|
|
1895
1941
|
// /network
|
|
1896
1942
|
await writeFile(
|
|
1897
1943
|
expressData.network.response.file,
|
|
@@ -1920,14 +1966,10 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1920
1966
|
expressData['network/routes'].index.content
|
|
1921
1967
|
)
|
|
1922
1968
|
|
|
1923
|
-
// /network/routes/
|
|
1924
|
-
await writeFile(
|
|
1925
|
-
expressData['network/routes/schemas'].index.file,
|
|
1926
|
-
expressData['network/routes/schemas'].index.content
|
|
1927
|
-
)
|
|
1969
|
+
// /network/routes/utils
|
|
1928
1970
|
await writeFile(
|
|
1929
|
-
expressData['network/routes/
|
|
1930
|
-
expressData['network/routes/
|
|
1971
|
+
expressData['network/routes/utils'].index.file,
|
|
1972
|
+
expressData['network/routes/utils'].index.content
|
|
1931
1973
|
)
|
|
1932
1974
|
|
|
1933
1975
|
// /utils
|
|
@@ -1936,15 +1978,5 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1936
1978
|
expressData.utils.index.file,
|
|
1937
1979
|
expressData.utils.index.content
|
|
1938
1980
|
)
|
|
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
1981
|
}
|
|
1950
1982
|
}
|