@anthonylzq/simba.js 3.2.0 → 4.0.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 +11 -4
- package/lib/index.js +0 -2
- package/lib/src/functions/api.js +332 -287
- package/lib/src/functions/tsconfig.js +1 -1
- package/lib/src/index.js +3 -3
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -271,7 +271,7 @@ If you want to check the content of the files, please check the [example](https:
|
|
|
271
271
|
|
|
272
272
|
- The provided project structure is inspired in my personal experience as [`Node.js`](https://nodejs.org/en/) developer and the [`Nest`](https://nestjs.com/) framework. It follows a layered architecture:
|
|
273
273
|
|
|
274
|
-
1. Presentation layer (network layer): it is represented by the network
|
|
274
|
+
1. Presentation layer (network layer): it is represented by the network and schemas folders, which contains the routes and the schemas necessary for each route.
|
|
275
275
|
2. Business layer (services layer): it is represented by the services folder, which contains all the code related to the business logic of your application.
|
|
276
276
|
3. Persistance layer (database layer): it is represented by the database folder, which contains the database connection, models and queries (that will be used by the services). Multiple database connection are possible and should be implemented here.
|
|
277
277
|
|
|
@@ -284,7 +284,14 @@ If you want to check the content of the files, please check the [example](https:
|
|
|
284
284
|
|
|
285
285
|
## What is new?
|
|
286
286
|
|
|
287
|
-
Please check the [`changelog.md`](https://github.com/AnthonyLzq/simba.js/blob/master/CHANGELOG.md) file. Also, if you want to check what is coming, check the [road map](https://simbajs.notion.site/simbajs/783092dc7d444067b4c56a25d671f658?v=31060f3d17524ca58870e86c2960a6df).
|
|
287
|
+
Please check the [`changelog.md`](https://github.com/AnthonyLzq/simba.js/blob/master/CHANGELOG.md) file. Also, if you want to check what is coming, check the [road map](https://simbajs.notion.site/simbajs/783092dc7d444067b4c56a25d671f658?v=31060f3d17524ca58870e86c2960a6df).
|
|
288
|
+
|
|
289
|
+
### Version 4.x.x
|
|
290
|
+
|
|
291
|
+
In this major version I would be focusing on adding new possible configurations according to the road map. The major changes of this version will be described here:
|
|
292
|
+
|
|
293
|
+
- Replaced [`joi`](https://www.npmjs.com/package/joi) in favor of [`ajv`](https://www.npmjs.com/package/ajv) + [`@sinclair/typebox`](https://www.npmjs.com/package/@sinclair/typebox) in the Express case. [Why did I do this?](https://simbajs.notion.site/TypeBox-support-for-Express-f4e3cf8dd06f4c7ba4d8e4051a52688c)
|
|
294
|
+
- Using more descriptive nouns, now every database object is represented with a DBO at the end, like: _UserDBO_. Also the objects that are sent and received will have a DTO at the end, like: _UserDTO_.
|
|
288
295
|
|
|
289
296
|
## <a name="notes"></a>Notes
|
|
290
297
|
|
|
@@ -314,6 +321,8 @@ Here is the list of the packages that are being installed, as `devDependencies`:
|
|
|
314
321
|
|
|
315
322
|
As `dependencies`:
|
|
316
323
|
|
|
324
|
+
- [`@sinclair/typebox`](https://www.npmjs.com/package/@sinclair/typebox)
|
|
325
|
+
- [`ajv`](https://www.npmjs.com/package/ajv)
|
|
317
326
|
- [`http-errors`](https://www.npmjs.com/package/http-errors)
|
|
318
327
|
- [`mongoose`](https://mongoosejs.com/)
|
|
319
328
|
|
|
@@ -328,7 +337,6 @@ As `devDependencies`:
|
|
|
328
337
|
As `dependencies`:
|
|
329
338
|
|
|
330
339
|
- [`express`](https://expressjs.com/)
|
|
331
|
-
- [`joi`](https://joi.dev/api/?v=17.4.2)
|
|
332
340
|
- [`morgan`](https://www.npmjs.com/package/morgan)
|
|
333
341
|
- [`swagger-ui-express`](https://www.npmjs.com/package/swagger-ui-express)
|
|
334
342
|
|
|
@@ -336,7 +344,6 @@ As `dependencies`:
|
|
|
336
344
|
|
|
337
345
|
As `dependencies`:
|
|
338
346
|
|
|
339
|
-
- [`@sinclair/typebox`](https://www.npmjs.com/package/@sinclair/typebox)
|
|
340
347
|
- [`fastify`](https://www.npmjs.com/package/fastify)
|
|
341
348
|
- [`fastify-swagger`](https://www.npmjs.com/package/fastify-swagger)
|
|
342
349
|
|
package/lib/index.js
CHANGED
package/lib/src/functions/api.js
CHANGED
|
@@ -123,7 +123,7 @@ export {}
|
|
|
123
123
|
},
|
|
124
124
|
'@types/dto': {
|
|
125
125
|
user: {
|
|
126
|
-
content: `interface
|
|
126
|
+
content: `interface UserDTO {
|
|
127
127
|
id: string
|
|
128
128
|
lastName: string
|
|
129
129
|
name: string
|
|
@@ -134,10 +134,11 @@ export {}
|
|
|
134
134
|
},
|
|
135
135
|
'@types/models': {
|
|
136
136
|
user: {
|
|
137
|
-
content: `interface
|
|
137
|
+
content: `interface UserDBO {
|
|
138
138
|
id: string
|
|
139
139
|
name: string
|
|
140
140
|
lastName: string
|
|
141
|
+
createdAt: Date
|
|
141
142
|
updatedAt: Date
|
|
142
143
|
}
|
|
143
144
|
`,
|
|
@@ -166,7 +167,7 @@ export * from './queries'
|
|
|
166
167
|
user: {
|
|
167
168
|
content: `import { model, Schema } from 'mongoose'
|
|
168
169
|
|
|
169
|
-
const
|
|
170
|
+
const UserSchema = new Schema<UserDBO>(
|
|
170
171
|
{
|
|
171
172
|
lastName: {
|
|
172
173
|
required: true,
|
|
@@ -178,24 +179,18 @@ const User = new Schema<IUser>(
|
|
|
178
179
|
}
|
|
179
180
|
},
|
|
180
181
|
{
|
|
181
|
-
timestamps:
|
|
182
|
-
createdAt: false,
|
|
183
|
-
updatedAt: true
|
|
184
|
-
},
|
|
182
|
+
timestamps: true,
|
|
185
183
|
versionKey: false,
|
|
186
|
-
|
|
187
|
-
transform(_, ret) {
|
|
184
|
+
toObject: {
|
|
185
|
+
transform: (_, ret) => {
|
|
188
186
|
ret.id = ret._id.toString()
|
|
189
|
-
ret.updatedAt = ret.updatedAt.toISOString()
|
|
190
187
|
delete ret._id
|
|
191
|
-
|
|
192
|
-
},
|
|
193
|
-
virtuals: true
|
|
188
|
+
}
|
|
194
189
|
}
|
|
195
190
|
}
|
|
196
191
|
)
|
|
197
192
|
|
|
198
|
-
const UserModel = model<
|
|
193
|
+
const UserModel = model<UserDBO>('users', UserSchema)
|
|
199
194
|
|
|
200
195
|
export { UserModel }
|
|
201
196
|
`,
|
|
@@ -208,42 +203,63 @@ export { UserModel }
|
|
|
208
203
|
file: `${projectName}/src/database/mongo/queries/index.ts`
|
|
209
204
|
},
|
|
210
205
|
user: {
|
|
211
|
-
content: `import {
|
|
206
|
+
content: `import { Document, Types } from 'mongoose'
|
|
207
|
+
|
|
208
|
+
import { UserModel } from '..'
|
|
209
|
+
import { UserDTO } from 'schemas'
|
|
210
|
+
|
|
211
|
+
const userDBOtoDTO = (
|
|
212
|
+
userDBO: Document<unknown, unknown, UserDBO> &
|
|
213
|
+
UserDBO & {
|
|
214
|
+
_id: Types.ObjectId
|
|
215
|
+
}
|
|
216
|
+
): UserDTO => ({
|
|
217
|
+
...userDBO.toObject(),
|
|
218
|
+
createdAt: userDBO.createdAt.toISOString(),
|
|
219
|
+
updatedAt: userDBO.updatedAt.toISOString()
|
|
220
|
+
})
|
|
212
221
|
|
|
213
|
-
const store = async (userData:
|
|
222
|
+
const store = async (userData: UserDTO): Promise<UserDTO> => {
|
|
214
223
|
const user = new UserModel(userData)
|
|
224
|
+
|
|
215
225
|
await user.save()
|
|
216
226
|
|
|
217
|
-
return user
|
|
227
|
+
return userDBOtoDTO(user)
|
|
218
228
|
}
|
|
219
229
|
|
|
220
230
|
const remove = async (
|
|
221
231
|
id: string | null = null
|
|
222
|
-
): Promise<
|
|
223
|
-
if (id)
|
|
232
|
+
): Promise<UserDTO | number | null> => {
|
|
233
|
+
if (id) {
|
|
234
|
+
const removedUser = await UserModel.findByIdAndRemove(id)
|
|
235
|
+
|
|
236
|
+
if (!removedUser) return null
|
|
237
|
+
|
|
238
|
+
return userDBOtoDTO(removedUser)
|
|
239
|
+
}
|
|
224
240
|
|
|
225
241
|
return (await UserModel.deleteMany({})).deletedCount
|
|
226
242
|
}
|
|
227
243
|
|
|
228
244
|
const get = async (
|
|
229
245
|
id: string | null = null
|
|
230
|
-
): Promise<
|
|
246
|
+
): Promise<UserDTO[] | UserDTO | null> => {
|
|
231
247
|
if (id) {
|
|
232
248
|
const user = await UserModel.findById(id)
|
|
233
249
|
|
|
234
|
-
return user ? user
|
|
250
|
+
return user ? userDBOtoDTO(user) : null
|
|
235
251
|
}
|
|
236
252
|
|
|
237
253
|
const users = await UserModel.find({})
|
|
238
254
|
|
|
239
|
-
return users.map(u => u
|
|
255
|
+
return users.map(u => userDBOtoDTO(u))
|
|
240
256
|
}
|
|
241
257
|
|
|
242
|
-
const update = async (userData:
|
|
258
|
+
const update = async (userData: UserDTO): Promise<UserDTO | null> => {
|
|
243
259
|
const { id, ...rest } = userData
|
|
244
260
|
const user = await UserModel.findByIdAndUpdate(id, rest, { new: true })
|
|
245
261
|
|
|
246
|
-
return user ? user
|
|
262
|
+
return user ? userDBOtoDTO(user) : null
|
|
247
263
|
}
|
|
248
264
|
|
|
249
265
|
export { store, remove, get, update }
|
|
@@ -259,6 +275,58 @@ export * from './server'
|
|
|
259
275
|
file: `${projectName}/src/network/index.ts`
|
|
260
276
|
}
|
|
261
277
|
},
|
|
278
|
+
schemas: {
|
|
279
|
+
index: {
|
|
280
|
+
content: `import { Static, Type } from '@sinclair/typebox'
|
|
281
|
+
|
|
282
|
+
const id = Type.String({
|
|
283
|
+
pattern: '^[a-zA-Z0-9]{24,}$'
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
type Id = Static<typeof id>
|
|
287
|
+
|
|
288
|
+
const idSchema = Type.Object({ id })
|
|
289
|
+
|
|
290
|
+
type IdSchema = Static<typeof idSchema>
|
|
291
|
+
|
|
292
|
+
export { id, Id, idSchema, IdSchema }
|
|
293
|
+
export * from './user'
|
|
294
|
+
`,
|
|
295
|
+
file: `${projectName}/src/schemas/index.ts`
|
|
296
|
+
},
|
|
297
|
+
user: {
|
|
298
|
+
content: `import { Static, Type } from '@sinclair/typebox'
|
|
299
|
+
|
|
300
|
+
import { id } from '.'
|
|
301
|
+
|
|
302
|
+
const user = Type.Object({
|
|
303
|
+
lastName: Type.String(),
|
|
304
|
+
name: Type.String()
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
type User = Static<typeof user>
|
|
308
|
+
|
|
309
|
+
const userDto = Type.Object({
|
|
310
|
+
id: Type.Optional(id),
|
|
311
|
+
lastName: Type.String(),
|
|
312
|
+
name: Type.String(),
|
|
313
|
+
createdAt: Type.Optional(Type.String()),
|
|
314
|
+
updatedAt: Type.Optional(Type.String())
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
type UserDTO = Static<typeof userDto>
|
|
318
|
+
|
|
319
|
+
const storeUserSchema = Type.Object({
|
|
320
|
+
args: user
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
type StoreUser = Static<typeof storeUserSchema>
|
|
324
|
+
|
|
325
|
+
export { userDto, UserDTO, user, User, storeUserSchema, StoreUser }
|
|
326
|
+
`,
|
|
327
|
+
file: `${projectName}/src/schemas/user.ts`
|
|
328
|
+
}
|
|
329
|
+
},
|
|
262
330
|
services: {
|
|
263
331
|
index: {
|
|
264
332
|
content: "export * from './user'\n",
|
|
@@ -268,41 +336,53 @@ export * from './server'
|
|
|
268
336
|
content: `import httpErrors from 'http-errors'
|
|
269
337
|
|
|
270
338
|
import { store, remove, get, update } from 'database'
|
|
339
|
+
import { UserDTO } from 'schemas'
|
|
271
340
|
import { EFU, MFU, GE, errorHandling } from './utils'
|
|
272
341
|
|
|
273
342
|
type Process = {
|
|
274
343
|
type: 'store' | 'getAll' | 'deleteAll' | 'getOne' | 'update' | 'delete'
|
|
275
344
|
}
|
|
276
345
|
|
|
346
|
+
type Arguments = {
|
|
347
|
+
id?: string
|
|
348
|
+
userDto?: UserDTO
|
|
349
|
+
userDtoWithoutId?: Omit<UserDTO, 'id'>
|
|
350
|
+
}
|
|
351
|
+
|
|
277
352
|
class UserService {
|
|
278
|
-
|
|
353
|
+
#args: Arguments
|
|
279
354
|
|
|
280
|
-
constructor(args:
|
|
281
|
-
this
|
|
355
|
+
constructor(args: Arguments = {}) {
|
|
356
|
+
this.#args = args
|
|
282
357
|
}
|
|
283
358
|
|
|
284
|
-
public process({ type }: Process): Promise<string |
|
|
359
|
+
public process({ type }: Process): Promise<string | UserDTO | UserDTO[]> {
|
|
285
360
|
switch (type) {
|
|
286
361
|
case 'store':
|
|
287
|
-
return this
|
|
362
|
+
return this.#store()
|
|
288
363
|
case 'getAll':
|
|
289
|
-
return this
|
|
364
|
+
return this.#getAll()
|
|
290
365
|
case 'deleteAll':
|
|
291
|
-
return this
|
|
366
|
+
return this.#deleteAll()
|
|
292
367
|
case 'getOne':
|
|
293
|
-
return this
|
|
368
|
+
return this.#getOne()
|
|
294
369
|
case 'update':
|
|
295
|
-
return this
|
|
370
|
+
return this.#update()
|
|
296
371
|
case 'delete':
|
|
297
|
-
return this
|
|
372
|
+
return this.#delete()
|
|
298
373
|
default:
|
|
299
374
|
throw new httpErrors.InternalServerError(GE.INTERNAL_SERVER_ERROR)
|
|
300
375
|
}
|
|
301
376
|
}
|
|
302
377
|
|
|
303
|
-
|
|
378
|
+
async #store(): Promise<UserDTO> {
|
|
304
379
|
try {
|
|
305
|
-
|
|
380
|
+
if (!this.#args.userDtoWithoutId)
|
|
381
|
+
throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
|
|
382
|
+
|
|
383
|
+
const result = await store({
|
|
384
|
+
...this.#args.userDtoWithoutId
|
|
385
|
+
})
|
|
306
386
|
|
|
307
387
|
return result
|
|
308
388
|
} catch (e) {
|
|
@@ -310,9 +390,9 @@ class UserService {
|
|
|
310
390
|
}
|
|
311
391
|
}
|
|
312
392
|
|
|
313
|
-
|
|
393
|
+
async #getAll(): Promise<UserDTO[]> {
|
|
314
394
|
try {
|
|
315
|
-
const users = (await get()) as
|
|
395
|
+
const users = (await get()) as UserDTO[]
|
|
316
396
|
|
|
317
397
|
return users
|
|
318
398
|
} catch (e) {
|
|
@@ -320,7 +400,7 @@ class UserService {
|
|
|
320
400
|
}
|
|
321
401
|
}
|
|
322
402
|
|
|
323
|
-
|
|
403
|
+
async #deleteAll(): Promise<string> {
|
|
324
404
|
try {
|
|
325
405
|
const usersDeleted = (await remove()) as number
|
|
326
406
|
|
|
@@ -335,11 +415,13 @@ class UserService {
|
|
|
335
415
|
}
|
|
336
416
|
}
|
|
337
417
|
|
|
338
|
-
|
|
339
|
-
const { id } = this._args as DtoUser
|
|
340
|
-
|
|
418
|
+
async #getOne(): Promise<UserDTO> {
|
|
341
419
|
try {
|
|
342
|
-
|
|
420
|
+
if (!this.#args.id)
|
|
421
|
+
throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
|
|
422
|
+
|
|
423
|
+
const { id } = this.#args
|
|
424
|
+
const user = (await get(id)) as UserDTO | null
|
|
343
425
|
|
|
344
426
|
if (!user) throw new httpErrors.NotFound(EFU.NOT_FOUND)
|
|
345
427
|
|
|
@@ -349,9 +431,12 @@ class UserService {
|
|
|
349
431
|
}
|
|
350
432
|
}
|
|
351
433
|
|
|
352
|
-
|
|
434
|
+
async #update(): Promise<UserDTO> {
|
|
353
435
|
try {
|
|
354
|
-
|
|
436
|
+
if (!this.#args.userDto || !this.#args.userDto.id)
|
|
437
|
+
throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
|
|
438
|
+
|
|
439
|
+
const updatedUser = await update(this.#args.userDto)
|
|
355
440
|
|
|
356
441
|
if (!updatedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
|
|
357
442
|
|
|
@@ -361,10 +446,12 @@ class UserService {
|
|
|
361
446
|
}
|
|
362
447
|
}
|
|
363
448
|
|
|
364
|
-
|
|
365
|
-
const { id } = this._args as DtoUser
|
|
366
|
-
|
|
449
|
+
async #delete(): Promise<string> {
|
|
367
450
|
try {
|
|
451
|
+
if (!this.#args.id)
|
|
452
|
+
throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
|
|
453
|
+
|
|
454
|
+
const { id } = this.#args
|
|
368
455
|
const deletedUser = await remove(id)
|
|
369
456
|
|
|
370
457
|
if (!deletedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
|
|
@@ -484,6 +571,33 @@ Server.start()
|
|
|
484
571
|
}
|
|
485
572
|
|
|
486
573
|
const expressData = {
|
|
574
|
+
'@types/custom': {
|
|
575
|
+
request: {
|
|
576
|
+
content: `type ExpressRequest = import('express').Request
|
|
577
|
+
|
|
578
|
+
interface CustomRequest extends ExpressRequest {
|
|
579
|
+
body: {
|
|
580
|
+
args?: import('schemas').UserDTO
|
|
581
|
+
}
|
|
582
|
+
// We can add custom headers via intersection, remember that for some reason
|
|
583
|
+
// headers must be in Snake-Pascal-Case
|
|
584
|
+
headers: import('http').IncomingHttpHeaders & {
|
|
585
|
+
'Custom-Header'?: string
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
`,
|
|
589
|
+
file: `${projectName}/src/@types/custom/request.d.ts`
|
|
590
|
+
},
|
|
591
|
+
response: {
|
|
592
|
+
content: `type ExpressResponse = import('express').Response
|
|
593
|
+
|
|
594
|
+
interface CustomResponse extends ExpressResponse {
|
|
595
|
+
newValue?: string
|
|
596
|
+
}
|
|
597
|
+
`,
|
|
598
|
+
file: `${projectName}/src/@types/custom/response.d.ts`
|
|
599
|
+
}
|
|
600
|
+
},
|
|
487
601
|
network: {
|
|
488
602
|
response: {
|
|
489
603
|
content: `interface ResponseProps {
|
|
@@ -639,33 +753,6 @@ export { server as Server }
|
|
|
639
753
|
file: `${projectName}/src/network/server.ts`
|
|
640
754
|
}
|
|
641
755
|
},
|
|
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
756
|
'network/routes': {
|
|
670
757
|
home: {
|
|
671
758
|
content: `import { Response, Request, Router } from 'express'
|
|
@@ -694,146 +781,82 @@ export * from './user'
|
|
|
694
781
|
file: `${projectName}/src/network/routes/index.ts`
|
|
695
782
|
},
|
|
696
783
|
user: {
|
|
697
|
-
content: `import { Router
|
|
698
|
-
import httpErrors from 'http-errors'
|
|
699
|
-
import { ValidationError } from 'joi'
|
|
784
|
+
content: `import { Router } from 'express'
|
|
700
785
|
|
|
701
786
|
import { response } from 'network/response'
|
|
702
|
-
import { UserService } from 'services
|
|
703
|
-
import { idSchema,
|
|
787
|
+
import { UserService } from 'services'
|
|
788
|
+
import { idSchema, storeUserSchema, UserDTO } from 'schemas'
|
|
789
|
+
import { validatorCompiler } from './utils'
|
|
704
790
|
|
|
705
791
|
const User = Router()
|
|
706
792
|
|
|
707
793
|
User.route('/users')
|
|
708
794
|
.post(
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
res: CustomResponse,
|
|
712
|
-
next: NextFunction
|
|
713
|
-
): Promise<void> => {
|
|
795
|
+
validatorCompiler(storeUserSchema, 'body'),
|
|
796
|
+
async (req: CustomRequest, res: CustomResponse): Promise<void> => {
|
|
714
797
|
const {
|
|
715
798
|
body: { args }
|
|
716
799
|
} = req
|
|
800
|
+
const us = new UserService({ userDtoWithoutId: args })
|
|
801
|
+
const result = await us.process({ type: 'store' })
|
|
717
802
|
|
|
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
|
-
}
|
|
803
|
+
response({ error: false, message: result, res, status: 201 })
|
|
745
804
|
}
|
|
746
805
|
)
|
|
747
|
-
.
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
res: CustomResponse,
|
|
751
|
-
next: NextFunction
|
|
752
|
-
): Promise<void> => {
|
|
753
|
-
const us = new UserService()
|
|
806
|
+
.get(async (req: CustomRequest, res: CustomResponse): Promise<void> => {
|
|
807
|
+
const us = new UserService()
|
|
808
|
+
const result = await us.process({ type: 'getAll' })
|
|
754
809
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
}
|
|
762
|
-
)
|
|
810
|
+
response({ error: false, message: result, res, status: 200 })
|
|
811
|
+
})
|
|
812
|
+
.delete(async (req: CustomRequest, res: CustomResponse): Promise<void> => {
|
|
813
|
+
const us = new UserService()
|
|
814
|
+
const result = await us.process({ type: 'deleteAll' })
|
|
815
|
+
|
|
816
|
+
response({ error: false, message: result, res, status: 200 })
|
|
817
|
+
})
|
|
763
818
|
|
|
764
819
|
User.route('/user/:id')
|
|
765
820
|
.get(
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
res: CustomResponse,
|
|
769
|
-
next: NextFunction
|
|
770
|
-
): Promise<void> => {
|
|
821
|
+
validatorCompiler(idSchema, 'params'),
|
|
822
|
+
async (req: CustomRequest, res: CustomResponse): Promise<void> => {
|
|
771
823
|
const {
|
|
772
824
|
params: { id }
|
|
773
825
|
} = req
|
|
826
|
+
const us = new UserService({ id })
|
|
827
|
+
const result = await us.process({ type: 'getOne' })
|
|
774
828
|
|
|
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
|
-
}
|
|
829
|
+
response({ error: false, message: result, res, status: 200 })
|
|
786
830
|
}
|
|
787
831
|
)
|
|
788
832
|
.patch(
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
next: NextFunction
|
|
793
|
-
): Promise<void> => {
|
|
833
|
+
validatorCompiler(idSchema, 'params'),
|
|
834
|
+
validatorCompiler(storeUserSchema, 'body'),
|
|
835
|
+
async (req: CustomRequest, res: CustomResponse): Promise<void> => {
|
|
794
836
|
const {
|
|
795
837
|
body: { args },
|
|
796
838
|
params: { id }
|
|
797
839
|
} = req
|
|
798
|
-
const
|
|
840
|
+
const userDto = {
|
|
799
841
|
id,
|
|
800
842
|
...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))
|
|
843
|
+
} as UserDTO
|
|
844
|
+
const us = new UserService({ userDto })
|
|
845
|
+
const result = await us.process({ type: 'update' })
|
|
811
846
|
|
|
812
|
-
|
|
813
|
-
}
|
|
847
|
+
response({ error: false, message: result, res, status: 200 })
|
|
814
848
|
}
|
|
815
849
|
)
|
|
816
850
|
.delete(
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
res: CustomResponse,
|
|
820
|
-
next: NextFunction
|
|
821
|
-
): Promise<void> => {
|
|
851
|
+
validatorCompiler(idSchema, 'params'),
|
|
852
|
+
async (req: CustomRequest, res: CustomResponse): Promise<void> => {
|
|
822
853
|
const {
|
|
823
854
|
params: { id }
|
|
824
855
|
} = req
|
|
856
|
+
const us = new UserService({ id })
|
|
857
|
+
const result = await us.process({ type: 'delete' })
|
|
825
858
|
|
|
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
|
-
}
|
|
859
|
+
response({ error: false, message: result, res, status: 200 })
|
|
837
860
|
}
|
|
838
861
|
)
|
|
839
862
|
|
|
@@ -842,34 +865,48 @@ export { User }
|
|
|
842
865
|
file: `${projectName}/src/network/routes/user.ts`
|
|
843
866
|
}
|
|
844
867
|
},
|
|
845
|
-
'network/routes/
|
|
868
|
+
'network/routes/utils': {
|
|
846
869
|
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()
|
|
870
|
+
content: `import { NextFunction } from 'express'
|
|
871
|
+
import httpErrors from 'http-errors'
|
|
872
|
+
import { TObject, TProperties } from '@sinclair/typebox'
|
|
873
|
+
import Ajv from 'ajv'
|
|
874
|
+
|
|
875
|
+
const ajv = new Ajv({
|
|
876
|
+
removeAdditional: true,
|
|
877
|
+
useDefaults: true,
|
|
878
|
+
coerceTypes: true,
|
|
879
|
+
nullable: true
|
|
863
880
|
})
|
|
864
881
|
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
882
|
+
type Middleware = (
|
|
883
|
+
req: CustomRequest,
|
|
884
|
+
res: CustomResponse,
|
|
885
|
+
next: NextFunction
|
|
886
|
+
) => void
|
|
887
|
+
|
|
888
|
+
const validatorCompiler = <T extends TProperties>(
|
|
889
|
+
schema: TObject<T>,
|
|
890
|
+
value: 'body' | 'params'
|
|
891
|
+
): Middleware => {
|
|
892
|
+
return (req: CustomRequest, res: CustomResponse, next: NextFunction) => {
|
|
893
|
+
const validate = ajv.compile(schema)
|
|
894
|
+
const ok = validate(req[value])
|
|
895
|
+
|
|
896
|
+
if (!ok && validate.errors) {
|
|
897
|
+
const [error] = validate.errors
|
|
898
|
+
const errorMessage = \`\${error.dataPath.replace('.', '')} \${error.message}\`
|
|
899
|
+
|
|
900
|
+
return next(new httpErrors.UnprocessableEntity(errorMessage))
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
next()
|
|
904
|
+
}
|
|
905
|
+
}
|
|
869
906
|
|
|
870
|
-
export {
|
|
907
|
+
export { validatorCompiler }
|
|
871
908
|
`,
|
|
872
|
-
file: `${projectName}/src/network/routes/
|
|
909
|
+
file: `${projectName}/src/network/routes/utils/index.ts`
|
|
873
910
|
}
|
|
874
911
|
},
|
|
875
912
|
utils: {
|
|
@@ -909,7 +946,7 @@ export { userSchema, storeUserSchema }
|
|
|
909
946
|
"summary": "Save a user in the database",
|
|
910
947
|
"operationId": "store",
|
|
911
948
|
"requestBody": {
|
|
912
|
-
"$ref": "#/components/requestBodies/
|
|
949
|
+
"$ref": "#/components/requestBodies/UserDTO"
|
|
913
950
|
},
|
|
914
951
|
"responses": {
|
|
915
952
|
"201": {
|
|
@@ -1103,7 +1140,7 @@ export { userSchema, storeUserSchema }
|
|
|
1103
1140
|
}
|
|
1104
1141
|
],
|
|
1105
1142
|
"requestBody": {
|
|
1106
|
-
"$ref": "#/components/requestBodies/
|
|
1143
|
+
"$ref": "#/components/requestBodies/UserDTO"
|
|
1107
1144
|
},
|
|
1108
1145
|
"responses": {
|
|
1109
1146
|
"200": {
|
|
@@ -1264,7 +1301,7 @@ export { userSchema, storeUserSchema }
|
|
|
1264
1301
|
}
|
|
1265
1302
|
},
|
|
1266
1303
|
"requestBodies": {
|
|
1267
|
-
"
|
|
1304
|
+
"UserDTO": {
|
|
1268
1305
|
"description": "User name and last name",
|
|
1269
1306
|
"content": {
|
|
1270
1307
|
"application/json": {
|
|
@@ -1510,30 +1547,37 @@ export * from './docs'
|
|
|
1510
1547
|
},
|
|
1511
1548
|
user: {
|
|
1512
1549
|
content: `import { FastifyInstance } from 'fastify'
|
|
1550
|
+
import { Type } from '@sinclair/typebox'
|
|
1513
1551
|
|
|
1514
1552
|
import { response } from 'network/response'
|
|
1515
|
-
import {
|
|
1553
|
+
import {
|
|
1554
|
+
userDto,
|
|
1555
|
+
idSchema,
|
|
1556
|
+
IdSchema,
|
|
1557
|
+
storeUserSchema,
|
|
1558
|
+
StoreUser
|
|
1559
|
+
} from 'schemas'
|
|
1516
1560
|
import { UserService } from 'services'
|
|
1561
|
+
import { validatorCompiler } from './utils'
|
|
1517
1562
|
|
|
1518
1563
|
const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
1519
1564
|
app
|
|
1520
|
-
.post<{ Body:
|
|
1565
|
+
.post<{ Body: StoreUser }>(
|
|
1521
1566
|
\`\${prefix}/users\`,
|
|
1522
1567
|
{
|
|
1523
1568
|
schema: {
|
|
1524
|
-
body:
|
|
1525
|
-
args: storeUserSchema
|
|
1526
|
-
},
|
|
1569
|
+
body: storeUserSchema,
|
|
1527
1570
|
response: {
|
|
1528
1571
|
200: {
|
|
1529
1572
|
error: {
|
|
1530
1573
|
type: 'boolean'
|
|
1531
1574
|
},
|
|
1532
|
-
message:
|
|
1575
|
+
message: userDto
|
|
1533
1576
|
}
|
|
1534
1577
|
},
|
|
1535
1578
|
tags: ['user']
|
|
1536
|
-
}
|
|
1579
|
+
},
|
|
1580
|
+
validatorCompiler
|
|
1537
1581
|
},
|
|
1538
1582
|
async (request, reply) => {
|
|
1539
1583
|
const {
|
|
@@ -1541,14 +1585,16 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1541
1585
|
args: { lastName, name }
|
|
1542
1586
|
}
|
|
1543
1587
|
} = request
|
|
1544
|
-
const us = new UserService({
|
|
1588
|
+
const us = new UserService({
|
|
1589
|
+
userDtoWithoutId: { lastName, name }
|
|
1590
|
+
})
|
|
1545
1591
|
const user = await us.process({ type: 'store' })
|
|
1546
1592
|
|
|
1547
1593
|
response({
|
|
1548
1594
|
error: false,
|
|
1549
1595
|
message: user,
|
|
1550
1596
|
reply,
|
|
1551
|
-
status:
|
|
1597
|
+
status: 201
|
|
1552
1598
|
})
|
|
1553
1599
|
}
|
|
1554
1600
|
)
|
|
@@ -1561,10 +1607,7 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1561
1607
|
error: {
|
|
1562
1608
|
type: 'boolean'
|
|
1563
1609
|
},
|
|
1564
|
-
message:
|
|
1565
|
-
type: 'array',
|
|
1566
|
-
items: userSchema
|
|
1567
|
-
}
|
|
1610
|
+
message: Type.Array(userDto)
|
|
1568
1611
|
}
|
|
1569
1612
|
},
|
|
1570
1613
|
tags: ['user']
|
|
@@ -1611,23 +1654,22 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1611
1654
|
})
|
|
1612
1655
|
}
|
|
1613
1656
|
)
|
|
1614
|
-
.get<{ Params:
|
|
1657
|
+
.get<{ Params: IdSchema }>(
|
|
1615
1658
|
\`\${prefix}/user/:id\`,
|
|
1616
1659
|
{
|
|
1617
1660
|
schema: {
|
|
1618
|
-
params:
|
|
1619
|
-
id: idSchema
|
|
1620
|
-
},
|
|
1661
|
+
params: idSchema,
|
|
1621
1662
|
response: {
|
|
1622
1663
|
200: {
|
|
1623
1664
|
error: {
|
|
1624
1665
|
type: 'boolean'
|
|
1625
1666
|
},
|
|
1626
|
-
message:
|
|
1667
|
+
message: userDto
|
|
1627
1668
|
}
|
|
1628
1669
|
},
|
|
1629
1670
|
tags: ['user']
|
|
1630
|
-
}
|
|
1671
|
+
},
|
|
1672
|
+
validatorCompiler
|
|
1631
1673
|
},
|
|
1632
1674
|
async (request, reply) => {
|
|
1633
1675
|
const {
|
|
@@ -1644,22 +1686,18 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1644
1686
|
})
|
|
1645
1687
|
}
|
|
1646
1688
|
)
|
|
1647
|
-
.patch<{ Body:
|
|
1689
|
+
.patch<{ Body: StoreUser; Params: IdSchema }>(
|
|
1648
1690
|
\`\${prefix}/user/:id\`,
|
|
1649
1691
|
{
|
|
1650
1692
|
schema: {
|
|
1651
|
-
body:
|
|
1652
|
-
|
|
1653
|
-
},
|
|
1654
|
-
params: {
|
|
1655
|
-
id: idSchema
|
|
1656
|
-
},
|
|
1693
|
+
body: storeUserSchema,
|
|
1694
|
+
params: idSchema,
|
|
1657
1695
|
response: {
|
|
1658
1696
|
200: {
|
|
1659
1697
|
error: {
|
|
1660
1698
|
type: 'boolean'
|
|
1661
1699
|
},
|
|
1662
|
-
message:
|
|
1700
|
+
message: userDto
|
|
1663
1701
|
}
|
|
1664
1702
|
},
|
|
1665
1703
|
tags: ['user']
|
|
@@ -1672,7 +1710,9 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1672
1710
|
},
|
|
1673
1711
|
params: { id }
|
|
1674
1712
|
} = request
|
|
1675
|
-
const us = new UserService({
|
|
1713
|
+
const us = new UserService({
|
|
1714
|
+
userDto: { name, lastName, id }
|
|
1715
|
+
})
|
|
1676
1716
|
const user = await us.process({ type: 'update' })
|
|
1677
1717
|
|
|
1678
1718
|
response({
|
|
@@ -1683,13 +1723,11 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1683
1723
|
})
|
|
1684
1724
|
}
|
|
1685
1725
|
)
|
|
1686
|
-
.delete<{ Params:
|
|
1726
|
+
.delete<{ Params: IdSchema }>(
|
|
1687
1727
|
\`\${prefix}/user/:id\`,
|
|
1688
1728
|
{
|
|
1689
1729
|
schema: {
|
|
1690
|
-
params:
|
|
1691
|
-
id: idSchema
|
|
1692
|
-
},
|
|
1730
|
+
params: idSchema,
|
|
1693
1731
|
response: {
|
|
1694
1732
|
200: {
|
|
1695
1733
|
error: {
|
|
@@ -1725,45 +1763,55 @@ export { User }
|
|
|
1725
1763
|
file: `${projectName}/src/network/routes/user.ts`
|
|
1726
1764
|
}
|
|
1727
1765
|
},
|
|
1728
|
-
'network/routes/
|
|
1766
|
+
'network/routes/utils': {
|
|
1729
1767
|
index: {
|
|
1730
|
-
content:
|
|
1768
|
+
content: `/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1769
|
+
import {
|
|
1770
|
+
FastifyRouteSchemaDef,
|
|
1771
|
+
FastifyValidationResult
|
|
1772
|
+
} from 'fastify/types/schema'
|
|
1773
|
+
import httpErrors from 'http-errors'
|
|
1774
|
+
import Ajv from 'ajv'
|
|
1731
1775
|
|
|
1732
|
-
const
|
|
1776
|
+
const ajv = new Ajv({
|
|
1777
|
+
removeAdditional: true,
|
|
1778
|
+
useDefaults: true,
|
|
1779
|
+
coerceTypes: true,
|
|
1780
|
+
nullable: true
|
|
1781
|
+
})
|
|
1733
1782
|
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
},
|
|
1739
|
-
user: {
|
|
1740
|
-
content: `import { Type } from '@sinclair/typebox'
|
|
1783
|
+
const validatorCompiler = ({
|
|
1784
|
+
schema
|
|
1785
|
+
}: FastifyRouteSchemaDef<any>): FastifyValidationResult => {
|
|
1786
|
+
const validate = ajv.compile(schema)
|
|
1741
1787
|
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
lastName: Type.Optional(Type.String()),
|
|
1745
|
-
name: Type.Optional(Type.String()),
|
|
1746
|
-
updatedAt: Type.Optional(Type.String())
|
|
1747
|
-
})
|
|
1788
|
+
return (data: unknown): boolean => {
|
|
1789
|
+
const ok = validate(data)
|
|
1748
1790
|
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
})
|
|
1791
|
+
if (!ok && validate.errors) {
|
|
1792
|
+
const [error] = validate.errors
|
|
1793
|
+
const errorMessage = \`\${error.dataPath.replace('.', '')} \${error.message}\`
|
|
1753
1794
|
|
|
1754
|
-
|
|
1795
|
+
throw new httpErrors.UnprocessableEntity(errorMessage)
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1798
|
+
return true
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
export { validatorCompiler }
|
|
1755
1803
|
`,
|
|
1756
|
-
file: `${projectName}/src/network/routes/
|
|
1804
|
+
file: `${projectName}/src/network/routes/utils/index.ts`
|
|
1757
1805
|
}
|
|
1758
1806
|
}
|
|
1759
1807
|
}
|
|
1760
1808
|
|
|
1761
|
-
const expressFolders = `${projectName}/src/utils
|
|
1809
|
+
const expressFolders = `${projectName}/src/utils \
|
|
1810
|
+
${projectName}/src/@types/custom`
|
|
1762
1811
|
|
|
1763
1812
|
const createFoldersCommands = `mkdir ${projectName}/src \
|
|
1764
1813
|
${projectName}/src/@types \
|
|
1765
1814
|
${projectName}/src/@types/dto \
|
|
1766
|
-
${projectName}/src/@types/custom \
|
|
1767
1815
|
${projectName}/src/@types/models \
|
|
1768
1816
|
${projectName}/src/database \
|
|
1769
1817
|
${projectName}/src/database/mongo \
|
|
@@ -1771,7 +1819,8 @@ ${projectName}/src/database/mongo/models \
|
|
|
1771
1819
|
${projectName}/src/database/mongo/queries \
|
|
1772
1820
|
${projectName}/src/network \
|
|
1773
1821
|
${projectName}/src/network/routes \
|
|
1774
|
-
${projectName}/src/network/routes/
|
|
1822
|
+
${projectName}/src/network/routes/utils \
|
|
1823
|
+
${projectName}/src/schemas \
|
|
1775
1824
|
${projectName}/src/services \
|
|
1776
1825
|
${projectName}/src/services/utils \
|
|
1777
1826
|
${projectName}/src/services/utils/messages \
|
|
@@ -1794,10 +1843,6 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1794
1843
|
data['@types/models'].user.content
|
|
1795
1844
|
)
|
|
1796
1845
|
|
|
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
1846
|
// /database
|
|
1802
1847
|
await writeFile(data.database.index.file, data.database.index.content)
|
|
1803
1848
|
await writeFile(
|
|
@@ -1821,6 +1866,14 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1821
1866
|
data['database/mongo/queries'].user.content
|
|
1822
1867
|
)
|
|
1823
1868
|
|
|
1869
|
+
// /schemas
|
|
1870
|
+
await writeFile(data.schemas.user.file, data.schemas.user.content)
|
|
1871
|
+
await writeFile(data.schemas.index.file, data.schemas.index.content)
|
|
1872
|
+
|
|
1873
|
+
// /services
|
|
1874
|
+
await writeFile(data.services.user.file, data.services.user.content)
|
|
1875
|
+
await writeFile(data.services.index.file, data.services.index.content)
|
|
1876
|
+
|
|
1824
1877
|
// /services/utils
|
|
1825
1878
|
await writeFile(
|
|
1826
1879
|
data['services/utils'].index.file,
|
|
@@ -1882,16 +1935,22 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1882
1935
|
fastifyData['network/routes'].index.content
|
|
1883
1936
|
)
|
|
1884
1937
|
|
|
1885
|
-
// /network/routes/
|
|
1938
|
+
// /network/routes/utils
|
|
1886
1939
|
await writeFile(
|
|
1887
|
-
fastifyData['network/routes/
|
|
1888
|
-
fastifyData['network/routes/
|
|
1940
|
+
fastifyData['network/routes/utils'].index.file,
|
|
1941
|
+
fastifyData['network/routes/utils'].index.content
|
|
1889
1942
|
)
|
|
1943
|
+
} else {
|
|
1944
|
+
// /@types/custom
|
|
1890
1945
|
await writeFile(
|
|
1891
|
-
|
|
1892
|
-
|
|
1946
|
+
expressData['@types/custom'].request.file,
|
|
1947
|
+
expressData['@types/custom'].request.content
|
|
1893
1948
|
)
|
|
1894
|
-
|
|
1949
|
+
await writeFile(
|
|
1950
|
+
expressData['@types/custom'].response.file,
|
|
1951
|
+
expressData['@types/custom'].response.content
|
|
1952
|
+
)
|
|
1953
|
+
|
|
1895
1954
|
// /network
|
|
1896
1955
|
await writeFile(
|
|
1897
1956
|
expressData.network.response.file,
|
|
@@ -1920,14 +1979,10 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1920
1979
|
expressData['network/routes'].index.content
|
|
1921
1980
|
)
|
|
1922
1981
|
|
|
1923
|
-
// /network/routes/
|
|
1924
|
-
await writeFile(
|
|
1925
|
-
expressData['network/routes/schemas'].index.file,
|
|
1926
|
-
expressData['network/routes/schemas'].index.content
|
|
1927
|
-
)
|
|
1982
|
+
// /network/routes/utils
|
|
1928
1983
|
await writeFile(
|
|
1929
|
-
expressData['network/routes/
|
|
1930
|
-
expressData['network/routes/
|
|
1984
|
+
expressData['network/routes/utils'].index.file,
|
|
1985
|
+
expressData['network/routes/utils'].index.content
|
|
1931
1986
|
)
|
|
1932
1987
|
|
|
1933
1988
|
// /utils
|
|
@@ -1936,15 +1991,5 @@ ${fastify ? '' : `${expressFolders}`}
|
|
|
1936
1991
|
expressData.utils.index.file,
|
|
1937
1992
|
expressData.utils.index.content
|
|
1938
1993
|
)
|
|
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
1994
|
}
|
|
1950
1995
|
}
|
|
@@ -17,7 +17,7 @@ module.exports = async projectName => {
|
|
|
17
17
|
|
|
18
18
|
/* Basic Options */
|
|
19
19
|
// "incremental": true, /* Enable incremental compilation */
|
|
20
|
-
"target": "
|
|
20
|
+
"target": "ES2015" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
|
|
21
21
|
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
|
22
22
|
// "lib": [], /* Specify library files to be included in the compilation. */
|
|
23
23
|
"allowJs": true /* Allow javascript files to be compiled. */,
|
package/lib/src/index.js
CHANGED
|
@@ -57,9 +57,9 @@ module.exports = async ({
|
|
|
57
57
|
cliProgress.Presets.shades_classic
|
|
58
58
|
)
|
|
59
59
|
|
|
60
|
-
const expressProdPackages = 'express
|
|
61
|
-
const fastifyProdPackages = '
|
|
62
|
-
const prodPackages = `${manager} http-errors mongoose ${
|
|
60
|
+
const expressProdPackages = 'express morgan swagger-ui-express'
|
|
61
|
+
const fastifyProdPackages = 'fastify fastify-swagger'
|
|
62
|
+
const prodPackages = `${manager} http-errors mongoose @sinclair/typebox ajv@^6 ${
|
|
63
63
|
fastify ? fastifyProdPackages : expressProdPackages
|
|
64
64
|
}`
|
|
65
65
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anthonylzq/simba.js",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "set up a modern backend app by running one command",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"directories": {
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
"yargs": "^17.3.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"dotenv": "^
|
|
48
|
-
"eslint": "^8.
|
|
49
|
-
"eslint-config-prettier": "^8.
|
|
47
|
+
"dotenv": "^16.0.0",
|
|
48
|
+
"eslint": "^8.10.0",
|
|
49
|
+
"eslint-config-prettier": "^8.5.0",
|
|
50
50
|
"eslint-config-standard": "^16.0.3",
|
|
51
51
|
"eslint-plugin-import": "^2.25.4",
|
|
52
52
|
"eslint-plugin-node": "^11.1.0",
|