@anthonylzq/simba.js 2.0.3 → 2.1.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 CHANGED
@@ -138,8 +138,6 @@ Regardless of the option chosen, a new folder will be generated with the name of
138
138
  ┃ ┃ ┗ 📜index.ts
139
139
  ┃ ┣ 📜index.ts
140
140
  ┃ ┗ 📜user.ts
141
- ┣ 📂test
142
- ┃ ┗ 📜test.http
143
141
  ┣ 📂utils
144
142
  ┃ ┣ 📜docs.json
145
143
  ┃ ┗ 📜index.ts
@@ -155,6 +153,7 @@ Regardless of the option chosen, a new folder will be generated with the name of
155
153
  📜nodemon.json
156
154
  📜package.json
157
155
  📜README.md
156
+ 📜index.http
158
157
  📜tsconfig.base.json
159
158
  📜tsconfig.json
160
159
  📜webpack.config.js
@@ -41,13 +41,12 @@ const writeFile = require('../utils/writeFile')
41
41
  * | | |- index: content, file
42
42
  * | |- user: content, file
43
43
  * | |- index: content, file
44
- * |- test:
45
- * | |- index.http: content, file
46
44
  * |- utils:
47
45
  * | |- docs.json: content, file
48
46
  * | |- index: content, file
49
47
  * |- .env: content, file
50
48
  * |- index: content, file
49
+ * index.http: content, file
51
50
  */
52
51
 
53
52
  /**
@@ -70,45 +69,18 @@ export {}
70
69
  '@types/dto': {
71
70
  user: {
72
71
  content: `interface DtoUser {
73
- id?: string
74
- lastName?: string
75
- name?: string
72
+ id: string
73
+ lastName: string
74
+ name: string
76
75
  }
77
76
  `,
78
77
  file: `${projectName}/src/@types/dto/user.d.ts`
79
78
  }
80
79
  },
81
- '@types/custom': {
82
- request: {
83
- content: `type ExpressRequest = import('express').Request
84
-
85
- interface CustomRequest extends ExpressRequest {
86
- body: {
87
- args?: DtoUser
88
- }
89
- // We can add custom headers via intersection, remember that for some reason
90
- // headers must be in Snake-Pascal-Case
91
- headers: import('http').IncomingHttpHeaders & {
92
- 'Custom-Header'?: string
93
- }
94
- }
95
- `,
96
- file: `${projectName}/src/@types/custom/request.d.ts`
97
- },
98
- response: {
99
- content: `type ExpressResponse = import('express').Response
100
-
101
- interface CustomResponse extends ExpressResponse {
102
- newValue?: string
103
- }
104
- `,
105
- file: `${projectName}/src/@types/custom/response.d.ts`
106
- }
107
- },
108
80
  '@types/models': {
109
81
  user: {
110
82
  content: `interface IUser {
111
- _id: import('mongoose').Types.ObjectId
83
+ id: string
112
84
  name: string
113
85
  lastName: string
114
86
  updatedAt: Date
@@ -155,14 +127,14 @@ const User = new Schema<IUser>(
155
127
  createdAt: false,
156
128
  updatedAt: true
157
129
  },
130
+ versionKey: false,
158
131
  toJSON: {
159
132
  transform(_, ret) {
160
- ret.id = ret._id
133
+ ret.id = ret._id.toString()
134
+ ret.updatedAt = ret.updatedAt.toISOString()
161
135
  delete ret._id
162
136
  delete ret.__v
163
- delete ret.updatedAt
164
137
  },
165
- versionKey: false,
166
138
  virtuals: true
167
139
  }
168
140
  }
@@ -181,12 +153,13 @@ export { UserModel }
181
153
  file: `${projectName}/src/database/mongo/queries/index.ts`
182
154
  },
183
155
  user: {
184
- content: `import { UserModel } from '../models'
156
+ content: `import { UserModel } from '..'
185
157
 
186
158
  const store = async (userData: DtoUser): Promise<IUser> => {
187
159
  const user = new UserModel(userData)
160
+ await user.save()
188
161
 
189
- return await user.save()
162
+ return user.toJSON()
190
163
  }
191
164
 
192
165
  const remove = async (
@@ -200,15 +173,22 @@ const remove = async (
200
173
  const get = async (
201
174
  id: string | null = null
202
175
  ): Promise<IUser[] | IUser | null> => {
203
- if (id) return await UserModel.findById(id)
176
+ if (id) {
177
+ const user = await UserModel.findById(id)
178
+
179
+ return user ? user.toJSON() : null
180
+ }
181
+
182
+ const users = await UserModel.find({})
204
183
 
205
- return await UserModel.find({})
184
+ return users.map(u => u.toJSON())
206
185
  }
207
186
 
208
187
  const update = async (userData: DtoUser): Promise<IUser | null> => {
209
188
  const { id, ...rest } = userData
189
+ const user = await UserModel.findByIdAndUpdate(id, rest, { new: true })
210
190
 
211
- return await UserModel.findByIdAndUpdate(id, rest, { new: true })
191
+ return user ? user.toJSON() : null
212
192
  }
213
193
 
214
194
  export { store, remove, get, update }
@@ -222,7 +202,234 @@ export { store, remove, get, update }
222
202
  export * from './server'
223
203
  `,
224
204
  file: `${projectName}/src/network/index.ts`
205
+ }
206
+ },
207
+ services: {
208
+ index: {
209
+ content: "export * from './user'\n",
210
+ file: `${projectName}/src/services/index.ts`
211
+ },
212
+ user: {
213
+ content: `import httpErrors from 'http-errors'
214
+
215
+ import { store, remove, get, update } from 'database'
216
+ import { EFU, MFU, GE, errorHandling } from './utils'
217
+
218
+ type Process = {
219
+ type: 'store' | 'getAll' | 'deleteAll' | 'getOne' | 'update' | 'delete'
220
+ }
221
+
222
+ class UserService {
223
+ private _args: Partial<DtoUser> | null
224
+
225
+ constructor(args: Partial<DtoUser> | null = null) {
226
+ this._args = args
227
+ }
228
+
229
+ public process({ type }: Process): Promise<string | IUser[] | IUser> {
230
+ switch (type) {
231
+ case 'store':
232
+ return this._store()
233
+ case 'getAll':
234
+ return this._getAll()
235
+ case 'deleteAll':
236
+ return this._deleteAll()
237
+ case 'getOne':
238
+ return this._getOne()
239
+ case 'update':
240
+ return this._update()
241
+ case 'delete':
242
+ return this._delete()
243
+ default:
244
+ throw new httpErrors.InternalServerError(GE.INTERNAL_SERVER_ERROR)
245
+ }
246
+ }
247
+
248
+ private async _store(): Promise<IUser> {
249
+ try {
250
+ const result = await store(this._args as DtoUser)
251
+
252
+ return result
253
+ } catch (e) {
254
+ return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
255
+ }
256
+ }
257
+
258
+ private async _getAll(): Promise<IUser[]> {
259
+ try {
260
+ const users = (await get()) as IUser[]
261
+
262
+ return users
263
+ } catch (e) {
264
+ return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
265
+ }
266
+ }
267
+
268
+ private async _deleteAll(): Promise<string> {
269
+ try {
270
+ const usersDeleted = (await remove()) as number
271
+
272
+ if (usersDeleted >= 1) return MFU.ALL_USERS_DELETED
273
+
274
+ if (usersDeleted === 0)
275
+ throw new httpErrors.Conflict(EFU.NOTHING_TO_DELETE)
276
+
277
+ throw new httpErrors.InternalServerError(GE.INTERNAL_SERVER_ERROR)
278
+ } catch (e) {
279
+ return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
280
+ }
281
+ }
282
+
283
+ private async _getOne(): Promise<IUser> {
284
+ const { id } = this._args as DtoUser
285
+
286
+ try {
287
+ const user = (await get(id as string)) as IUser | null
288
+
289
+ if (!user) throw new httpErrors.NotFound(EFU.NOT_FOUND)
290
+
291
+ return user
292
+ } catch (e) {
293
+ return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
294
+ }
295
+ }
296
+
297
+ private async _update(): Promise<IUser> {
298
+ try {
299
+ const updatedUser = await update(this._args as DtoUser)
300
+
301
+ if (!updatedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
302
+
303
+ return updatedUser
304
+ } catch (e) {
305
+ return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
306
+ }
307
+ }
308
+
309
+ private async _delete(): Promise<string> {
310
+ const { id } = this._args as DtoUser
311
+
312
+ try {
313
+ const deletedUser = await remove(id)
314
+
315
+ if (!deletedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
316
+
317
+ return MFU.USER_DELETED
318
+ } catch (e) {
319
+ return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
320
+ }
321
+ }
322
+ }
323
+
324
+ export { UserService }
325
+ `,
326
+ file: `${projectName}/src/services/user.ts`
327
+ }
328
+ },
329
+ 'services/utils': {
330
+ index: {
331
+ content: `import httpErrors from 'http-errors'
332
+
333
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
334
+ const errorHandling = (e: any, message?: string): never => {
335
+ console.error(e)
336
+
337
+ if (e instanceof httpErrors.HttpError) throw e
338
+
339
+ throw new httpErrors.InternalServerError(message ?? e.message)
340
+ }
341
+
342
+ export { errorHandling }
343
+ export * from './messages'
344
+ `,
345
+ file: `${projectName}/src/services/utils/index.ts`
346
+ }
347
+ },
348
+ 'services/utils/messages': {
349
+ index: {
350
+ content: `enum GenericErrors {
351
+ INTERNAL_SERVER_ERROR = 'Something went wrong'
352
+ }
353
+
354
+ export { GenericErrors as GE }
355
+ export * from './user'
356
+ `,
357
+ file: `${projectName}/src/services/utils/messages/index.ts`
225
358
  },
359
+ user: {
360
+ content: `enum ErrorForUser {
361
+ NOT_FOUND = 'The requested user does not exists',
362
+ NOTHING_TO_DELETE = 'There is no user to be deleted'
363
+ }
364
+
365
+ enum MessageForUser {
366
+ ALL_USERS_DELETED = 'All the users were deleted successfully',
367
+ USER_DELETED = 'The requested user was successfully deleted'
368
+ }
369
+
370
+ export { ErrorForUser as EFU, MessageForUser as MFU }
371
+ `,
372
+ file: `${projectName}/src/services/utils/messages/user.ts`
373
+ }
374
+ },
375
+ test: {
376
+ index: {
377
+ content: `### Testing store a user
378
+ POST http://localhost:1996/api/users
379
+ Content-Type: application/json
380
+
381
+ {
382
+ "args": {
383
+ "lastName": "Lzq",
384
+ "name": "Anthony"
385
+ }
386
+ }
387
+
388
+ ### Testing getAll users
389
+ GET http://localhost:1996/api/users
390
+
391
+ ### Testing deleteAll users
392
+ DELETE http://localhost:1996/api/users
393
+
394
+ ### Testing getOne user
395
+ GET http://localhost:1996/api/user/60e7e3b93b01c1a7aa74cd6b
396
+
397
+ ### Testing update user
398
+ PATCH http://localhost:1996/api/user/60e7e3b93b01c1a7aa74cd6b
399
+ Content-Type: application/json
400
+
401
+ {
402
+ "args": {
403
+ "name": "Anthony",
404
+ "lastName": "Luzquiños"
405
+ }
406
+ }
407
+
408
+ ### Testing delete user
409
+ DELETE http://localhost:1996/api/user/60e7e3b93b01c1a7aa74cd6b
410
+ `,
411
+ file: `${projectName}/index.http`
412
+ }
413
+ },
414
+ '.env': {
415
+ content: `MONGO_URI = ${
416
+ process.env.LOCAL
417
+ ? process.env.MONGO_URI
418
+ : `mongodb://mongo:mongo@mongo:27017/${projectName}`
419
+ }`,
420
+ file: `${projectName}/.env`
421
+ },
422
+ index: {
423
+ content: `import { Server } from './network'
424
+
425
+ Server.start()
426
+ `,
427
+ file: `${projectName}/src/index.ts`
428
+ }
429
+ }
430
+
431
+ const expressData = {
432
+ network: {
226
433
  response: {
227
434
  content: `interface ResponseProps {
228
435
  error: boolean
@@ -377,6 +584,33 @@ export { server as Server }
377
584
  file: `${projectName}/src/network/server.ts`
378
585
  }
379
586
  },
587
+ '@types/custom': {
588
+ request: {
589
+ content: `type ExpressRequest = import('express').Request
590
+
591
+ interface CustomRequest extends ExpressRequest {
592
+ body: {
593
+ args?: DtoUser
594
+ }
595
+ // We can add custom headers via intersection, remember that for some reason
596
+ // headers must be in Snake-Pascal-Case
597
+ headers: import('http').IncomingHttpHeaders & {
598
+ 'Custom-Header'?: string
599
+ }
600
+ }
601
+ `,
602
+ file: `${projectName}/src/@types/custom/request.d.ts`
603
+ },
604
+ response: {
605
+ content: `type ExpressResponse = import('express').Response
606
+
607
+ interface CustomResponse extends ExpressResponse {
608
+ newValue?: string
609
+ }
610
+ `,
611
+ file: `${projectName}/src/@types/custom/response.d.ts`
612
+ }
613
+ },
380
614
  'network/routes': {
381
615
  home: {
382
616
  content: `import { Response, Request, Router } from 'express'
@@ -411,7 +645,7 @@ import { ValidationError } from 'joi'
411
645
 
412
646
  import { response } from 'network/response'
413
647
  import { UserService } from 'services/user'
414
- import { idSchema, userSchema } from './schemas'
648
+ import { idSchema, userSchema, storeUserSchema } from './schemas'
415
649
 
416
650
  const User = Router()
417
651
 
@@ -425,12 +659,16 @@ User.route('/users')
425
659
  const {
426
660
  body: { args }
427
661
  } = req
428
- const us = new UserService(args as DtoUser)
429
662
 
430
663
  try {
664
+ await storeUserSchema.validateAsync(args)
665
+ const us = new UserService(args)
431
666
  const result = await us.process({ type: 'store' })
432
667
  response({ error: false, message: result, res, status: 201 })
433
668
  } catch (e) {
669
+ if (e instanceof ValidationError)
670
+ return next(new httpErrors.UnprocessableEntity(e.message))
671
+
434
672
  next(e)
435
673
  }
436
674
  }
@@ -481,7 +719,7 @@ User.route('/user/:id')
481
719
 
482
720
  try {
483
721
  await idSchema.validateAsync(id)
484
- const us = new UserService({ id } as DtoUser)
722
+ const us = new UserService({ id })
485
723
  const result = await us.process({ type: 'getOne' })
486
724
  response({ error: false, message: result, res, status: 200 })
487
725
  } catch (e) {
@@ -502,7 +740,7 @@ User.route('/user/:id')
502
740
  body: { args },
503
741
  params: { id }
504
742
  } = req
505
- const user: DtoUser = {
743
+ const user = {
506
744
  id,
507
745
  ...args
508
746
  }
@@ -532,7 +770,7 @@ User.route('/user/:id')
532
770
 
533
771
  try {
534
772
  await idSchema.validateAsync(id)
535
- const us = new UserService({ id } as DtoUser)
773
+ const us = new UserService({ id })
536
774
  const result = await us.process({ type: 'delete' })
537
775
  response({ error: false, message: result, res, status: 200 })
538
776
  } catch (e) {
@@ -569,216 +807,14 @@ const userSchema = Joi.object().keys({
569
807
  name: Joi.string().required()
570
808
  })
571
809
 
572
- export { userSchema }
573
- `,
574
- file: `${projectName}/src/network/routes/schemas/user.ts`
575
- }
576
- },
577
- services: {
578
- index: {
579
- content: "export * from './user'\n",
580
- file: `${projectName}/src/services/index.ts`
581
- },
582
- user: {
583
- content: `import httpErrors from 'http-errors'
584
-
585
- import { store, remove, get, update } from 'database'
586
- import { EFU, MFU, GE, errorHandling } from './utils'
587
-
588
- type Process = {
589
- type: 'store' | 'getAll' | 'deleteAll' | 'getOne' | 'update' | 'delete'
590
- }
591
-
592
- class UserService {
593
- private _args: DtoUser | null
594
-
595
- constructor(args: DtoUser | null = null) {
596
- this._args = args
597
- }
598
-
599
- public process({ type }: Process): Promise<string | IUser[] | IUser> {
600
- switch (type) {
601
- case 'store':
602
- return this._store()
603
- case 'getAll':
604
- return this._getAll()
605
- case 'deleteAll':
606
- return this._deleteAll()
607
- case 'getOne':
608
- return this._getOne()
609
- case 'update':
610
- return this._update()
611
- case 'delete':
612
- return this._delete()
613
- default:
614
- throw new httpErrors.InternalServerError(GE.INTERNAL_SERVER_ERROR)
615
- }
616
- }
617
-
618
- private async _store(): Promise<IUser> {
619
- try {
620
- const result = await store(this._args as DtoUser)
621
-
622
- return result
623
- } catch (e) {
624
- return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
625
- }
626
- }
627
-
628
- private async _getAll(): Promise<IUser[]> {
629
- try {
630
- const users = (await get()) as IUser[]
631
-
632
- return users
633
- } catch (e) {
634
- return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
635
- }
636
- }
637
-
638
- private async _deleteAll(): Promise<string> {
639
- try {
640
- const usersDeleted = (await remove()) as number
641
-
642
- if (usersDeleted >= 1) return MFU.ALL_USERS_DELETED
643
-
644
- if (usersDeleted === 0)
645
- throw new httpErrors.Conflict(EFU.NOTHING_TO_DELETE)
646
-
647
- throw new httpErrors.InternalServerError(GE.INTERNAL_SERVER_ERROR)
648
- } catch (e) {
649
- return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
650
- }
651
- }
652
-
653
- private async _getOne(): Promise<IUser> {
654
- const { id } = this._args as DtoUser
655
-
656
- try {
657
- const user = (await get(id as string)) as IUser | null
658
-
659
- if (!user) throw new httpErrors.NotFound(EFU.NOT_FOUND)
660
-
661
- return user
662
- } catch (e) {
663
- return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
664
- }
665
- }
666
-
667
- private async _update(): Promise<IUser> {
668
- try {
669
- const updatedUser = await update(this._args as DtoUser)
670
-
671
- if (!updatedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
672
-
673
- return updatedUser
674
- } catch (e) {
675
- return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
676
- }
677
- }
678
-
679
- private async _delete(): Promise<string> {
680
- const { id } = this._args as DtoUser
681
-
682
- try {
683
- const deletedUser = await remove(id)
684
-
685
- if (!deletedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
686
-
687
- return MFU.USER_DELETED
688
- } catch (e) {
689
- return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
690
- }
691
- }
692
- }
693
-
694
- export { UserService }
695
- `,
696
- file: `${projectName}/src/services/user.ts`
697
- }
698
- },
699
- 'services/utils': {
700
- index: {
701
- content: `import httpErrors from 'http-errors'
702
-
703
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
704
- const errorHandling = (e: any, message?: string): never => {
705
- console.error(e)
706
-
707
- if (e instanceof httpErrors.HttpError) throw e
708
-
709
- throw new httpErrors.InternalServerError(message ?? e.message)
710
- }
711
-
712
- export { errorHandling }
713
- export * from './messages'
714
- `,
715
- file: `${projectName}/src/services/utils/index.ts`
716
- }
717
- },
718
- 'services/utils/messages': {
719
- index: {
720
- content: `enum GenericErrors {
721
- INTERNAL_SERVER_ERROR = 'Something went wrong'
722
- }
723
-
724
- export { GenericErrors as GE }
725
- export * from './user'
726
- `,
727
- file: `${projectName}/src/services/utils/messages/index.ts`
728
- },
729
- user: {
730
- content: `enum ErrorForUser {
731
- NOT_FOUND = 'The requested user does not exists',
732
- NOTHING_TO_DELETE = 'There is no user to be deleted'
733
- }
734
-
735
- enum MessageForUser {
736
- ALL_USERS_DELETED = 'All the users were deleted successfully',
737
- USER_DELETED = 'The requested user was successfully deleted'
738
- }
739
-
740
- export { ErrorForUser as EFU, MessageForUser as MFU }
741
- `,
742
- file: `${projectName}/src/services/utils/messages/user.ts`
743
- }
744
- },
745
- test: {
746
- index: {
747
- content: `### Testing store a user
748
- POST http://localhost:1996/api/users
749
- Content-Type: application/json
750
-
751
- {
752
- "args": {
753
- "lastName": "Lzq",
754
- "name": "Anthony"
755
- }
756
- }
757
-
758
- ### Testing getAll users
759
- GET http://localhost:1996/api/users
760
-
761
- ### Testing deleteAll users
762
- DELETE http://localhost:1996/api/users
763
-
764
- ### Testing getOne user
765
- GET http://localhost:1996/api/user/60e7e3b93b01c1a7aa74cd6b
766
-
767
- ### Testing update user
768
- PATCH http://localhost:1996/api/user/60e7e3b93b01c1a7aa74cd6b
769
- Content-Type: application/json
770
-
771
- {
772
- "args": {
773
- "name": "Anthony",
774
- "lastName": "Luzquiños"
775
- }
776
- }
810
+ const storeUserSchema = Joi.object().keys({
811
+ lastName: Joi.string().required(),
812
+ name: Joi.string().required()
813
+ })
777
814
 
778
- ### Testing delete user
779
- DELETE http://localhost:1996/api/user/60e7e3b93b01c1a7aa74cd6b
815
+ export { userSchema, storeUserSchema }
780
816
  `,
781
- file: `${projectName}/src/test/index.http`
817
+ file: `${projectName}/src/network/routes/schemas/user.ts`
782
818
  }
783
819
  },
784
820
  utils: {
@@ -1206,28 +1242,16 @@ DELETE http://localhost:1996/api/user/60e7e3b93b01c1a7aa74cd6b
1206
1242
  content: "export { default as docs } from './docs.json'\n",
1207
1243
  file: `${projectName}/src/utils/index.ts`
1208
1244
  }
1209
- },
1210
- '.env': {
1211
- content: `MONGO_URI = mongodb://mongo:mongo@mongo:27017/${projectName}`,
1212
- file: `${projectName}/.env`
1213
- },
1214
- index: {
1215
- content: `import { Server } from './network'
1216
-
1217
- Server.start()
1218
- `,
1219
- file: `${projectName}/src/index.ts`
1220
1245
  }
1221
1246
  }
1222
1247
 
1248
+ const expressFolders = `${projectName}/src/utils`
1249
+
1223
1250
  const createFoldersCommands = `mkdir ${projectName}/src \
1224
1251
  ${projectName}/src/@types \
1225
1252
  ${projectName}/src/@types/dto \
1226
1253
  ${projectName}/src/@types/custom \
1227
1254
  ${projectName}/src/@types/models \
1228
- ${projectName}/src/services \
1229
- ${projectName}/src/services/utils \
1230
- ${projectName}/src/services/utils/messages \
1231
1255
  ${projectName}/src/database \
1232
1256
  ${projectName}/src/database/mongo \
1233
1257
  ${projectName}/src/database/mongo/models \
@@ -1235,8 +1259,10 @@ ${projectName}/src/database/mongo/queries \
1235
1259
  ${projectName}/src/network \
1236
1260
  ${projectName}/src/network/routes \
1237
1261
  ${projectName}/src/network/routes/schemas \
1238
- ${projectName}/src/test \
1239
- ${projectName}/src/utils
1262
+ ${projectName}/src/services \
1263
+ ${projectName}/src/services/utils \
1264
+ ${projectName}/src/services/utils/messages \
1265
+ ${expressFolders}
1240
1266
  `
1241
1267
 
1242
1268
  if (os.platform() === 'win32')
@@ -1248,12 +1274,12 @@ ${projectName}/src/utils
1248
1274
 
1249
1275
  // /@types/custom
1250
1276
  await writeFile(
1251
- data['@types/custom'].request.file,
1252
- data['@types/custom'].request.content
1277
+ expressData['@types/custom'].request.file,
1278
+ expressData['@types/custom'].request.content
1253
1279
  )
1254
1280
  await writeFile(
1255
- data['@types/custom'].response.file,
1256
- data['@types/custom'].response.content
1281
+ expressData['@types/custom'].response.file,
1282
+ expressData['@types/custom'].response.content
1257
1283
  )
1258
1284
 
1259
1285
  // /@types/dto
@@ -1310,40 +1336,49 @@ ${projectName}/src/utils
1310
1336
 
1311
1337
  // /network
1312
1338
  await writeFile(data.network.index.file, data.network.index.content)
1313
- await writeFile(data.network.response.file, data.network.response.content)
1314
- await writeFile(data.network.router.file, data.network.router.content)
1315
- await writeFile(data.network.server.file, data.network.server.content)
1339
+ await writeFile(
1340
+ expressData.network.response.file,
1341
+ expressData.network.response.content
1342
+ )
1343
+ await writeFile(
1344
+ expressData.network.router.file,
1345
+ expressData.network.router.content
1346
+ )
1347
+ await writeFile(
1348
+ expressData.network.server.file,
1349
+ expressData.network.server.content
1350
+ )
1316
1351
 
1317
1352
  // /network/routes
1318
1353
  await writeFile(
1319
- data['network/routes'].home.file,
1320
- data['network/routes'].home.content
1354
+ expressData['network/routes'].home.file,
1355
+ expressData['network/routes'].home.content
1321
1356
  )
1322
1357
  await writeFile(
1323
- data['network/routes'].user.file,
1324
- data['network/routes'].user.content
1358
+ expressData['network/routes'].user.file,
1359
+ expressData['network/routes'].user.content
1325
1360
  )
1326
1361
  await writeFile(
1327
- data['network/routes'].index.file,
1328
- data['network/routes'].index.content
1362
+ expressData['network/routes'].index.file,
1363
+ expressData['network/routes'].index.content
1329
1364
  )
1330
1365
 
1331
1366
  // /network/routes/schemas
1332
1367
  await writeFile(
1333
- data['network/routes/schemas'].index.file,
1334
- data['network/routes/schemas'].index.content
1368
+ expressData['network/routes/schemas'].index.file,
1369
+ expressData['network/routes/schemas'].index.content
1335
1370
  )
1336
1371
  await writeFile(
1337
- data['network/routes/schemas'].user.file,
1338
- data['network/routes/schemas'].user.content
1372
+ expressData['network/routes/schemas'].user.file,
1373
+ expressData['network/routes/schemas'].user.content
1339
1374
  )
1340
1375
 
1341
1376
  // /test
1342
1377
  await writeFile(data.test.index.file, data.test.index.content)
1343
1378
 
1344
1379
  // /utils
1345
- await writeFile(data.utils.docs.file, data.utils.docs.content)
1346
- await writeFile(data.utils.index.file, data.utils.index.content)
1380
+ await writeFile(expressData.utils.docs.file, expressData.utils.docs.content)
1381
+ await writeFile(expressData.utils.index.file, expressData.utils.index.content)
1347
1382
 
1348
1383
  // .env
1349
1384
  await writeFile(data['.env'].file, data['.env'].content)
@@ -6,71 +6,71 @@ const writeFile = require('../utils/writeFile')
6
6
  */
7
7
  module.exports = async projectName => {
8
8
  const data = {
9
- eslintContent: `module.exports = {
10
- env: {
11
- node: true
9
+ eslintContent: `{
10
+ "env": {
11
+ "node": true
12
12
  },
13
- root: true,
14
- parser: '@typescript-eslint/parser',
15
- plugins: ['@typescript-eslint', 'import', 'prettier'],
16
- extends: [
17
- 'standard',
18
- 'eslint:recommended',
19
- 'plugin:@typescript-eslint/eslint-recommended',
20
- 'plugin:@typescript-eslint/recommended',
21
- 'prettier'
13
+ "root": true,
14
+ "parser": "@typescript-eslint/parser",
15
+ "plugins": ["@typescript-eslint", "import", "prettier"],
16
+ "extends": [
17
+ "standard",
18
+ "eslint:recommended",
19
+ "plugin:@typescript-eslint/eslint-recommended",
20
+ "plugin:@typescript-eslint/recommended",
21
+ "prettier"
22
22
  ],
23
- rules: {
24
- '@typescript-eslint/no-var-requires': 'off',
25
- '@typescript-eslint/no-empty-interface': 'off',
26
- 'arrow-parens': ['error', 'as-needed'],
27
- 'import/extensions': [
23
+ "rules": {
24
+ "@typescript-eslint/no-var-requires": "off",
25
+ "@typescript-eslint/no-empty-interface": "off",
26
+ "arrow-parens": ["error", "as-needed"],
27
+ "import/extensions": [
28
28
  2,
29
29
  {
30
- ts: 'never',
31
- js: 'always',
32
- json: 'always'
30
+ "ts": "never",
31
+ "js": "always",
32
+ "json": "always"
33
33
  }
34
34
  ],
35
- 'import/no-extraneous-dependencies': [
36
- 'error',
35
+ "import/no-extraneous-dependencies": [
36
+ "error",
37
37
  {
38
- devDependencies: ['**/*.test.js', 'webpack.config.js'],
39
- optionalDependencies: ['**/*.test.js'],
40
- peerDependencies: ['**/*.test.js']
38
+ "devDependencies": ["**/*.test.js", "webpack.config.js"],
39
+ "optionalDependencies": ["**/*.test.js"],
40
+ "peerDependencies": ["**/*.test.js"]
41
41
  }
42
42
  ],
43
- 'max-len': [
44
- 'error',
43
+ "max-len": [
44
+ "error",
45
45
  {
46
- code: 80,
47
- ignoreComments: true,
48
- ignoreRegExpLiterals: true,
49
- ignoreTemplateLiterals: true,
50
- ignoreTrailingComments: true,
51
- ignoreStrings: true,
52
- ignoreUrls: true
46
+ "code": 80,
47
+ "ignoreComments": true,
48
+ "ignoreRegExpLiterals": true,
49
+ "ignoreTemplateLiterals": true,
50
+ "ignoreTrailingComments": true,
51
+ "ignoreStrings": true,
52
+ "ignoreUrls": true
53
53
  }
54
54
  ],
55
- 'newline-before-return': 'error',
56
- 'object-curly-spacing': ['error', 'always'],
55
+ "newline-before-return": "error",
56
+ "object-curly-spacing": ["error", "always"],
57
57
  "object-shorthand": ["error", "always"],
58
- 'prefer-const': 'error',
59
- 'prettier/prettier': [
60
- 'error',
58
+ "prefer-const": "error",
59
+ "prettier/prettier": [
60
+ "error",
61
61
  {
62
- arrowParens: 'avoid',
63
- bracketSpacing: true,
64
- printWidth: 80,
65
- quoteProps: 'as-needed',
66
- semi: false,
67
- singleQuote: true,
68
- tabWidth: 2,
69
- trailingComma: 'none'
62
+ "arrowParens": "avoid",
63
+ "bracketSpacing": true,
64
+ "printWidth": 80,
65
+ "quoteProps": "as-needed",
66
+ "semi": false,
67
+ "singleQuote": true,
68
+ "tabWidth": 2,
69
+ "trailingComma": "none"
70
70
  }
71
71
  ],
72
- radix: ['error', 'as-needed'],
73
- 'spaced-comment': ['error', 'always']
72
+ "radix": ["error", "as-needed"],
73
+ "spaced-comment": ["error", "always"]
74
74
  }
75
75
  }
76
76
  `,
@@ -15,7 +15,7 @@ module.exports = async projectName => {
15
15
  "ignore": [
16
16
  "src/**/*.test.ts"
17
17
  ],
18
- "exec": "ts-node -r dotenv/config ./src/index"
18
+ "exec": "npx ts-node -r dotenv/config ./src/index"
19
19
  }
20
20
  `,
21
21
  nodemonFile: 'nodemon.json'
@@ -14,7 +14,7 @@ const eslint = require('./functions/eslint')
14
14
  const webpack = require('./functions/webpack')
15
15
  const docker = require('./functions/docker')
16
16
  const herokuF = require('./functions/heroku')
17
- const express = require('./functions/express')
17
+ const express = require('./functions/api')
18
18
 
19
19
  /**
20
20
  * @param {Number} process number of process
@@ -56,13 +56,13 @@ module.exports = async ({
56
56
  cliProgress.Presets.shades_classic
57
57
  )
58
58
 
59
- const prodPackages = `${manager} express http-errors joi mongoose morgan swagger-ui-express`
59
+ const expressProdPackages = 'express joi morgan swagger-ui-express'
60
+ const prodPackages = `${manager} http-errors mongoose ${expressProdPackages}`
61
+
62
+ const expressDevPackages = `@types/express @types/morgan @types/swagger-ui-express`
60
63
  const devPackages = `${manager} -D \
61
- @types/express \
62
64
  @types/http-errors \
63
- @types/morgan \
64
65
  @types/node \
65
- @types/swagger-ui-express \
66
66
  @typescript-eslint/eslint-plugin \
67
67
  @typescript-eslint/parser \
68
68
  dotenv \
@@ -70,7 +70,9 @@ eslint \
70
70
  eslint-config-prettier \
71
71
  eslint-config-standard \
72
72
  eslint-plugin-import \
73
+ eslint-plugin-node \
73
74
  eslint-plugin-prettier \
75
+ eslint-plugin-promise \
74
76
  nodemon \
75
77
  prettier \
76
78
  standard-version \
@@ -81,7 +83,8 @@ tsconfig-paths-webpack-plugin \
81
83
  typescript \
82
84
  webpack \
83
85
  webpack-cli \
84
- webpack-node-externals`
86
+ webpack-node-externals \
87
+ ${expressDevPackages}`
85
88
 
86
89
  bar.start(process, i)
87
90
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anthonylzq/simba.js",
3
- "version": "2.0.3",
3
+ "version": "2.1.0",
4
4
  "description": "set up a modern backend app by running one command",
5
5
  "main": "lib/index.js",
6
6
  "directories": {
@@ -10,9 +10,10 @@
10
10
  "scripts": {
11
11
  "service": "node ./bin",
12
12
  "release": "standard-version",
13
- "test": "npm run rm && node ./bin -N example -D 'This is a test' -a AnthonyLzq -e sluzquinosa@uni.pe -l mit -H",
13
+ "test": "npm run rm && node -r dotenv/config ./bin -N example -D 'This is a test' -a AnthonyLzq -e sluzquinosa@uni.pe -l mit -H && npm run rm-git-example",
14
14
  "lint": "eslint --ext js lib/ --fix",
15
- "rm": "if [ -d \"example\" ]; then rm -rf example; fi"
15
+ "rm": "if [ -d \"example\" ]; then rm -rf example; fi",
16
+ "rm-git-example": "if [ -d \"example/.git\" ]; then rm -rf example/.git; fi"
16
17
  },
17
18
  "bin": {
18
19
  "simba": "./bin/index.js"
@@ -34,9 +35,10 @@
34
35
  "colors": "^1.4.0",
35
36
  "readline-sync": "^1.4.10",
36
37
  "underscore": "^1.13.2",
37
- "yargs": "^17.3.0"
38
+ "yargs": "^17.3.1"
38
39
  },
39
40
  "devDependencies": {
41
+ "dotenv": "^14.3.2",
40
42
  "eslint": "^8.5.0",
41
43
  "eslint-config-prettier": "^8.3.0",
42
44
  "eslint-config-standard": "^16.0.3",