@anthonylzq/simba.js 2.0.4 → 2.1.1
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
|
@@ -30,12 +30,6 @@ npm i -g @anthonylzq/simba.js
|
|
|
30
30
|
|
|
31
31
|
## Usage
|
|
32
32
|
|
|
33
|
-
<!-- Also, if you don't want to install it globally, you can use npx as follows:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
npx simba.js
|
|
37
|
-
``` -->
|
|
38
|
-
|
|
39
33
|
As developer you have two main options to create your new project, one is by running:
|
|
40
34
|
|
|
41
35
|
```bash
|
package/lib/index.js
CHANGED
|
@@ -9,7 +9,7 @@ const argv = yargs(hideBin(process.argv))
|
|
|
9
9
|
.version(false)
|
|
10
10
|
// Pending to test it using npx
|
|
11
11
|
.usage(
|
|
12
|
-
'simba [options] (if you it installed globally) or only simba if you want to be asked for the options one by one'
|
|
12
|
+
'"simba [options]" (if you it installed globally) or only "simba -q" if you want to be asked for the options one by one'
|
|
13
13
|
)
|
|
14
14
|
.example(
|
|
15
15
|
"simba -N 'Project Name' -D 'Project description' -a Anthony -e sluzquinosa@uni.pe"
|
|
@@ -46,7 +46,6 @@ const argv = yargs(hideBin(process.argv))
|
|
|
46
46
|
.nargs('f', 1)
|
|
47
47
|
.describe('f', 'Main file of the project')
|
|
48
48
|
.alias('q', 'questions')
|
|
49
|
-
.nargs('q', 1)
|
|
50
49
|
.describe(
|
|
51
50
|
'q',
|
|
52
51
|
'Whether or not you want to be asked to answer the questions related to the project one by one'
|
|
@@ -69,45 +69,18 @@ export {}
|
|
|
69
69
|
'@types/dto': {
|
|
70
70
|
user: {
|
|
71
71
|
content: `interface DtoUser {
|
|
72
|
-
id
|
|
73
|
-
lastName
|
|
74
|
-
name
|
|
72
|
+
id: string
|
|
73
|
+
lastName: string
|
|
74
|
+
name: string
|
|
75
75
|
}
|
|
76
76
|
`,
|
|
77
77
|
file: `${projectName}/src/@types/dto/user.d.ts`
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
|
-
'@types/custom': {
|
|
81
|
-
request: {
|
|
82
|
-
content: `type ExpressRequest = import('express').Request
|
|
83
|
-
|
|
84
|
-
interface CustomRequest extends ExpressRequest {
|
|
85
|
-
body: {
|
|
86
|
-
args?: DtoUser
|
|
87
|
-
}
|
|
88
|
-
// We can add custom headers via intersection, remember that for some reason
|
|
89
|
-
// headers must be in Snake-Pascal-Case
|
|
90
|
-
headers: import('http').IncomingHttpHeaders & {
|
|
91
|
-
'Custom-Header'?: string
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
`,
|
|
95
|
-
file: `${projectName}/src/@types/custom/request.d.ts`
|
|
96
|
-
},
|
|
97
|
-
response: {
|
|
98
|
-
content: `type ExpressResponse = import('express').Response
|
|
99
|
-
|
|
100
|
-
interface CustomResponse extends ExpressResponse {
|
|
101
|
-
newValue?: string
|
|
102
|
-
}
|
|
103
|
-
`,
|
|
104
|
-
file: `${projectName}/src/@types/custom/response.d.ts`
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
80
|
'@types/models': {
|
|
108
81
|
user: {
|
|
109
82
|
content: `interface IUser {
|
|
110
|
-
|
|
83
|
+
id: string
|
|
111
84
|
name: string
|
|
112
85
|
lastName: string
|
|
113
86
|
updatedAt: Date
|
|
@@ -154,14 +127,14 @@ const User = new Schema<IUser>(
|
|
|
154
127
|
createdAt: false,
|
|
155
128
|
updatedAt: true
|
|
156
129
|
},
|
|
130
|
+
versionKey: false,
|
|
157
131
|
toJSON: {
|
|
158
132
|
transform(_, ret) {
|
|
159
|
-
ret.id = ret._id
|
|
133
|
+
ret.id = ret._id.toString()
|
|
134
|
+
ret.updatedAt = ret.updatedAt.toISOString()
|
|
160
135
|
delete ret._id
|
|
161
136
|
delete ret.__v
|
|
162
|
-
delete ret.updatedAt
|
|
163
137
|
},
|
|
164
|
-
versionKey: false,
|
|
165
138
|
virtuals: true
|
|
166
139
|
}
|
|
167
140
|
}
|
|
@@ -180,12 +153,13 @@ export { UserModel }
|
|
|
180
153
|
file: `${projectName}/src/database/mongo/queries/index.ts`
|
|
181
154
|
},
|
|
182
155
|
user: {
|
|
183
|
-
content: `import { UserModel } from '
|
|
156
|
+
content: `import { UserModel } from '..'
|
|
184
157
|
|
|
185
158
|
const store = async (userData: DtoUser): Promise<IUser> => {
|
|
186
159
|
const user = new UserModel(userData)
|
|
160
|
+
await user.save()
|
|
187
161
|
|
|
188
|
-
return
|
|
162
|
+
return user.toJSON()
|
|
189
163
|
}
|
|
190
164
|
|
|
191
165
|
const remove = async (
|
|
@@ -199,15 +173,22 @@ const remove = async (
|
|
|
199
173
|
const get = async (
|
|
200
174
|
id: string | null = null
|
|
201
175
|
): Promise<IUser[] | IUser | null> => {
|
|
202
|
-
if (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({})
|
|
203
183
|
|
|
204
|
-
return
|
|
184
|
+
return users.map(u => u.toJSON())
|
|
205
185
|
}
|
|
206
186
|
|
|
207
187
|
const update = async (userData: DtoUser): Promise<IUser | null> => {
|
|
208
188
|
const { id, ...rest } = userData
|
|
189
|
+
const user = await UserModel.findByIdAndUpdate(id, rest, { new: true })
|
|
209
190
|
|
|
210
|
-
return
|
|
191
|
+
return user ? user.toJSON() : null
|
|
211
192
|
}
|
|
212
193
|
|
|
213
194
|
export { store, remove, get, update }
|
|
@@ -221,7 +202,234 @@ export { store, remove, get, update }
|
|
|
221
202
|
export * from './server'
|
|
222
203
|
`,
|
|
223
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`
|
|
224
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`
|
|
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: {
|
|
225
433
|
response: {
|
|
226
434
|
content: `interface ResponseProps {
|
|
227
435
|
error: boolean
|
|
@@ -369,11 +577,38 @@ class Server {
|
|
|
369
577
|
}
|
|
370
578
|
}
|
|
371
579
|
|
|
372
|
-
const server = new Server()
|
|
373
|
-
|
|
374
|
-
export { server as Server }
|
|
580
|
+
const server = new Server()
|
|
581
|
+
|
|
582
|
+
export { server as Server }
|
|
583
|
+
`,
|
|
584
|
+
file: `${projectName}/src/network/server.ts`
|
|
585
|
+
}
|
|
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
|
+
}
|
|
375
610
|
`,
|
|
376
|
-
file: `${projectName}/src/
|
|
611
|
+
file: `${projectName}/src/@types/custom/response.d.ts`
|
|
377
612
|
}
|
|
378
613
|
},
|
|
379
614
|
'network/routes': {
|
|
@@ -410,7 +645,7 @@ import { ValidationError } from 'joi'
|
|
|
410
645
|
|
|
411
646
|
import { response } from 'network/response'
|
|
412
647
|
import { UserService } from 'services/user'
|
|
413
|
-
import { idSchema, userSchema } from './schemas'
|
|
648
|
+
import { idSchema, userSchema, storeUserSchema } from './schemas'
|
|
414
649
|
|
|
415
650
|
const User = Router()
|
|
416
651
|
|
|
@@ -424,12 +659,16 @@ User.route('/users')
|
|
|
424
659
|
const {
|
|
425
660
|
body: { args }
|
|
426
661
|
} = req
|
|
427
|
-
const us = new UserService(args as DtoUser)
|
|
428
662
|
|
|
429
663
|
try {
|
|
664
|
+
await storeUserSchema.validateAsync(args)
|
|
665
|
+
const us = new UserService(args)
|
|
430
666
|
const result = await us.process({ type: 'store' })
|
|
431
667
|
response({ error: false, message: result, res, status: 201 })
|
|
432
668
|
} catch (e) {
|
|
669
|
+
if (e instanceof ValidationError)
|
|
670
|
+
return next(new httpErrors.UnprocessableEntity(e.message))
|
|
671
|
+
|
|
433
672
|
next(e)
|
|
434
673
|
}
|
|
435
674
|
}
|
|
@@ -480,7 +719,7 @@ User.route('/user/:id')
|
|
|
480
719
|
|
|
481
720
|
try {
|
|
482
721
|
await idSchema.validateAsync(id)
|
|
483
|
-
const us = new UserService({ id }
|
|
722
|
+
const us = new UserService({ id })
|
|
484
723
|
const result = await us.process({ type: 'getOne' })
|
|
485
724
|
response({ error: false, message: result, res, status: 200 })
|
|
486
725
|
} catch (e) {
|
|
@@ -501,7 +740,7 @@ User.route('/user/:id')
|
|
|
501
740
|
body: { args },
|
|
502
741
|
params: { id }
|
|
503
742
|
} = req
|
|
504
|
-
const user
|
|
743
|
+
const user = {
|
|
505
744
|
id,
|
|
506
745
|
...args
|
|
507
746
|
}
|
|
@@ -531,7 +770,7 @@ User.route('/user/:id')
|
|
|
531
770
|
|
|
532
771
|
try {
|
|
533
772
|
await idSchema.validateAsync(id)
|
|
534
|
-
const us = new UserService({ id }
|
|
773
|
+
const us = new UserService({ id })
|
|
535
774
|
const result = await us.process({ type: 'delete' })
|
|
536
775
|
response({ error: false, message: result, res, status: 200 })
|
|
537
776
|
} catch (e) {
|
|
@@ -568,216 +807,14 @@ const userSchema = Joi.object().keys({
|
|
|
568
807
|
name: Joi.string().required()
|
|
569
808
|
})
|
|
570
809
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
},
|
|
576
|
-
services: {
|
|
577
|
-
index: {
|
|
578
|
-
content: "export * from './user'\n",
|
|
579
|
-
file: `${projectName}/src/services/index.ts`
|
|
580
|
-
},
|
|
581
|
-
user: {
|
|
582
|
-
content: `import httpErrors from 'http-errors'
|
|
583
|
-
|
|
584
|
-
import { store, remove, get, update } from 'database'
|
|
585
|
-
import { EFU, MFU, GE, errorHandling } from './utils'
|
|
586
|
-
|
|
587
|
-
type Process = {
|
|
588
|
-
type: 'store' | 'getAll' | 'deleteAll' | 'getOne' | 'update' | 'delete'
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
class UserService {
|
|
592
|
-
private _args: DtoUser | null
|
|
593
|
-
|
|
594
|
-
constructor(args: DtoUser | null = null) {
|
|
595
|
-
this._args = args
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
public process({ type }: Process): Promise<string | IUser[] | IUser> {
|
|
599
|
-
switch (type) {
|
|
600
|
-
case 'store':
|
|
601
|
-
return this._store()
|
|
602
|
-
case 'getAll':
|
|
603
|
-
return this._getAll()
|
|
604
|
-
case 'deleteAll':
|
|
605
|
-
return this._deleteAll()
|
|
606
|
-
case 'getOne':
|
|
607
|
-
return this._getOne()
|
|
608
|
-
case 'update':
|
|
609
|
-
return this._update()
|
|
610
|
-
case 'delete':
|
|
611
|
-
return this._delete()
|
|
612
|
-
default:
|
|
613
|
-
throw new httpErrors.InternalServerError(GE.INTERNAL_SERVER_ERROR)
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
private async _store(): Promise<IUser> {
|
|
618
|
-
try {
|
|
619
|
-
const result = await store(this._args as DtoUser)
|
|
620
|
-
|
|
621
|
-
return result
|
|
622
|
-
} catch (e) {
|
|
623
|
-
return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
private async _getAll(): Promise<IUser[]> {
|
|
628
|
-
try {
|
|
629
|
-
const users = (await get()) as IUser[]
|
|
630
|
-
|
|
631
|
-
return users
|
|
632
|
-
} catch (e) {
|
|
633
|
-
return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
private async _deleteAll(): Promise<string> {
|
|
638
|
-
try {
|
|
639
|
-
const usersDeleted = (await remove()) as number
|
|
640
|
-
|
|
641
|
-
if (usersDeleted >= 1) return MFU.ALL_USERS_DELETED
|
|
642
|
-
|
|
643
|
-
if (usersDeleted === 0)
|
|
644
|
-
throw new httpErrors.Conflict(EFU.NOTHING_TO_DELETE)
|
|
645
|
-
|
|
646
|
-
throw new httpErrors.InternalServerError(GE.INTERNAL_SERVER_ERROR)
|
|
647
|
-
} catch (e) {
|
|
648
|
-
return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
private async _getOne(): Promise<IUser> {
|
|
653
|
-
const { id } = this._args as DtoUser
|
|
654
|
-
|
|
655
|
-
try {
|
|
656
|
-
const user = (await get(id as string)) as IUser | null
|
|
657
|
-
|
|
658
|
-
if (!user) throw new httpErrors.NotFound(EFU.NOT_FOUND)
|
|
659
|
-
|
|
660
|
-
return user
|
|
661
|
-
} catch (e) {
|
|
662
|
-
return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
private async _update(): Promise<IUser> {
|
|
667
|
-
try {
|
|
668
|
-
const updatedUser = await update(this._args as DtoUser)
|
|
669
|
-
|
|
670
|
-
if (!updatedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
|
|
671
|
-
|
|
672
|
-
return updatedUser
|
|
673
|
-
} catch (e) {
|
|
674
|
-
return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
private async _delete(): Promise<string> {
|
|
679
|
-
const { id } = this._args as DtoUser
|
|
680
|
-
|
|
681
|
-
try {
|
|
682
|
-
const deletedUser = await remove(id)
|
|
683
|
-
|
|
684
|
-
if (!deletedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
|
|
685
|
-
|
|
686
|
-
return MFU.USER_DELETED
|
|
687
|
-
} catch (e) {
|
|
688
|
-
return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
export { UserService }
|
|
694
|
-
`,
|
|
695
|
-
file: `${projectName}/src/services/user.ts`
|
|
696
|
-
}
|
|
697
|
-
},
|
|
698
|
-
'services/utils': {
|
|
699
|
-
index: {
|
|
700
|
-
content: `import httpErrors from 'http-errors'
|
|
701
|
-
|
|
702
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
703
|
-
const errorHandling = (e: any, message?: string): never => {
|
|
704
|
-
console.error(e)
|
|
705
|
-
|
|
706
|
-
if (e instanceof httpErrors.HttpError) throw e
|
|
707
|
-
|
|
708
|
-
throw new httpErrors.InternalServerError(message ?? e.message)
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
export { errorHandling }
|
|
712
|
-
export * from './messages'
|
|
713
|
-
`,
|
|
714
|
-
file: `${projectName}/src/services/utils/index.ts`
|
|
715
|
-
}
|
|
716
|
-
},
|
|
717
|
-
'services/utils/messages': {
|
|
718
|
-
index: {
|
|
719
|
-
content: `enum GenericErrors {
|
|
720
|
-
INTERNAL_SERVER_ERROR = 'Something went wrong'
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
export { GenericErrors as GE }
|
|
724
|
-
export * from './user'
|
|
725
|
-
`,
|
|
726
|
-
file: `${projectName}/src/services/utils/messages/index.ts`
|
|
727
|
-
},
|
|
728
|
-
user: {
|
|
729
|
-
content: `enum ErrorForUser {
|
|
730
|
-
NOT_FOUND = 'The requested user does not exists',
|
|
731
|
-
NOTHING_TO_DELETE = 'There is no user to be deleted'
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
enum MessageForUser {
|
|
735
|
-
ALL_USERS_DELETED = 'All the users were deleted successfully',
|
|
736
|
-
USER_DELETED = 'The requested user was successfully deleted'
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
export { ErrorForUser as EFU, MessageForUser as MFU }
|
|
740
|
-
`,
|
|
741
|
-
file: `${projectName}/src/services/utils/messages/user.ts`
|
|
742
|
-
}
|
|
743
|
-
},
|
|
744
|
-
test: {
|
|
745
|
-
index: {
|
|
746
|
-
content: `### Testing store a user
|
|
747
|
-
POST http://localhost:1996/api/users
|
|
748
|
-
Content-Type: application/json
|
|
749
|
-
|
|
750
|
-
{
|
|
751
|
-
"args": {
|
|
752
|
-
"lastName": "Lzq",
|
|
753
|
-
"name": "Anthony"
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
### Testing getAll users
|
|
758
|
-
GET http://localhost:1996/api/users
|
|
759
|
-
|
|
760
|
-
### Testing deleteAll users
|
|
761
|
-
DELETE http://localhost:1996/api/users
|
|
762
|
-
|
|
763
|
-
### Testing getOne user
|
|
764
|
-
GET http://localhost:1996/api/user/60e7e3b93b01c1a7aa74cd6b
|
|
765
|
-
|
|
766
|
-
### Testing update user
|
|
767
|
-
PATCH http://localhost:1996/api/user/60e7e3b93b01c1a7aa74cd6b
|
|
768
|
-
Content-Type: application/json
|
|
769
|
-
|
|
770
|
-
{
|
|
771
|
-
"args": {
|
|
772
|
-
"name": "Anthony",
|
|
773
|
-
"lastName": "Luzquiños"
|
|
774
|
-
}
|
|
775
|
-
}
|
|
810
|
+
const storeUserSchema = Joi.object().keys({
|
|
811
|
+
lastName: Joi.string().required(),
|
|
812
|
+
name: Joi.string().required()
|
|
813
|
+
})
|
|
776
814
|
|
|
777
|
-
|
|
778
|
-
DELETE http://localhost:1996/api/user/60e7e3b93b01c1a7aa74cd6b
|
|
815
|
+
export { userSchema, storeUserSchema }
|
|
779
816
|
`,
|
|
780
|
-
file: `${projectName}/
|
|
817
|
+
file: `${projectName}/src/network/routes/schemas/user.ts`
|
|
781
818
|
}
|
|
782
819
|
},
|
|
783
820
|
utils: {
|
|
@@ -1205,28 +1242,16 @@ DELETE http://localhost:1996/api/user/60e7e3b93b01c1a7aa74cd6b
|
|
|
1205
1242
|
content: "export { default as docs } from './docs.json'\n",
|
|
1206
1243
|
file: `${projectName}/src/utils/index.ts`
|
|
1207
1244
|
}
|
|
1208
|
-
},
|
|
1209
|
-
'.env': {
|
|
1210
|
-
content: `MONGO_URI = mongodb://mongo:mongo@mongo:27017/${projectName}`,
|
|
1211
|
-
file: `${projectName}/.env`
|
|
1212
|
-
},
|
|
1213
|
-
index: {
|
|
1214
|
-
content: `import { Server } from './network'
|
|
1215
|
-
|
|
1216
|
-
Server.start()
|
|
1217
|
-
`,
|
|
1218
|
-
file: `${projectName}/src/index.ts`
|
|
1219
1245
|
}
|
|
1220
1246
|
}
|
|
1221
1247
|
|
|
1248
|
+
const expressFolders = `${projectName}/src/utils`
|
|
1249
|
+
|
|
1222
1250
|
const createFoldersCommands = `mkdir ${projectName}/src \
|
|
1223
1251
|
${projectName}/src/@types \
|
|
1224
1252
|
${projectName}/src/@types/dto \
|
|
1225
1253
|
${projectName}/src/@types/custom \
|
|
1226
1254
|
${projectName}/src/@types/models \
|
|
1227
|
-
${projectName}/src/services \
|
|
1228
|
-
${projectName}/src/services/utils \
|
|
1229
|
-
${projectName}/src/services/utils/messages \
|
|
1230
1255
|
${projectName}/src/database \
|
|
1231
1256
|
${projectName}/src/database/mongo \
|
|
1232
1257
|
${projectName}/src/database/mongo/models \
|
|
@@ -1234,8 +1259,10 @@ ${projectName}/src/database/mongo/queries \
|
|
|
1234
1259
|
${projectName}/src/network \
|
|
1235
1260
|
${projectName}/src/network/routes \
|
|
1236
1261
|
${projectName}/src/network/routes/schemas \
|
|
1237
|
-
${projectName}/src/
|
|
1238
|
-
${projectName}/src/utils
|
|
1262
|
+
${projectName}/src/services \
|
|
1263
|
+
${projectName}/src/services/utils \
|
|
1264
|
+
${projectName}/src/services/utils/messages \
|
|
1265
|
+
${expressFolders}
|
|
1239
1266
|
`
|
|
1240
1267
|
|
|
1241
1268
|
if (os.platform() === 'win32')
|
|
@@ -1247,12 +1274,12 @@ ${projectName}/src/utils
|
|
|
1247
1274
|
|
|
1248
1275
|
// /@types/custom
|
|
1249
1276
|
await writeFile(
|
|
1250
|
-
|
|
1251
|
-
|
|
1277
|
+
expressData['@types/custom'].request.file,
|
|
1278
|
+
expressData['@types/custom'].request.content
|
|
1252
1279
|
)
|
|
1253
1280
|
await writeFile(
|
|
1254
|
-
|
|
1255
|
-
|
|
1281
|
+
expressData['@types/custom'].response.file,
|
|
1282
|
+
expressData['@types/custom'].response.content
|
|
1256
1283
|
)
|
|
1257
1284
|
|
|
1258
1285
|
// /@types/dto
|
|
@@ -1309,40 +1336,49 @@ ${projectName}/src/utils
|
|
|
1309
1336
|
|
|
1310
1337
|
// /network
|
|
1311
1338
|
await writeFile(data.network.index.file, data.network.index.content)
|
|
1312
|
-
await writeFile(
|
|
1313
|
-
|
|
1314
|
-
|
|
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
|
+
)
|
|
1315
1351
|
|
|
1316
1352
|
// /network/routes
|
|
1317
1353
|
await writeFile(
|
|
1318
|
-
|
|
1319
|
-
|
|
1354
|
+
expressData['network/routes'].home.file,
|
|
1355
|
+
expressData['network/routes'].home.content
|
|
1320
1356
|
)
|
|
1321
1357
|
await writeFile(
|
|
1322
|
-
|
|
1323
|
-
|
|
1358
|
+
expressData['network/routes'].user.file,
|
|
1359
|
+
expressData['network/routes'].user.content
|
|
1324
1360
|
)
|
|
1325
1361
|
await writeFile(
|
|
1326
|
-
|
|
1327
|
-
|
|
1362
|
+
expressData['network/routes'].index.file,
|
|
1363
|
+
expressData['network/routes'].index.content
|
|
1328
1364
|
)
|
|
1329
1365
|
|
|
1330
1366
|
// /network/routes/schemas
|
|
1331
1367
|
await writeFile(
|
|
1332
|
-
|
|
1333
|
-
|
|
1368
|
+
expressData['network/routes/schemas'].index.file,
|
|
1369
|
+
expressData['network/routes/schemas'].index.content
|
|
1334
1370
|
)
|
|
1335
1371
|
await writeFile(
|
|
1336
|
-
|
|
1337
|
-
|
|
1372
|
+
expressData['network/routes/schemas'].user.file,
|
|
1373
|
+
expressData['network/routes/schemas'].user.content
|
|
1338
1374
|
)
|
|
1339
1375
|
|
|
1340
1376
|
// /test
|
|
1341
1377
|
await writeFile(data.test.index.file, data.test.index.content)
|
|
1342
1378
|
|
|
1343
1379
|
// /utils
|
|
1344
|
-
await writeFile(
|
|
1345
|
-
await writeFile(
|
|
1380
|
+
await writeFile(expressData.utils.docs.file, expressData.utils.docs.content)
|
|
1381
|
+
await writeFile(expressData.utils.index.file, expressData.utils.index.content)
|
|
1346
1382
|
|
|
1347
1383
|
// .env
|
|
1348
1384
|
await writeFile(data['.env'].file, data['.env'].content)
|
|
@@ -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/
|
|
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
|
|
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.
|
|
3
|
+
"version": "2.1.1",
|
|
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"
|
|
@@ -30,17 +31,18 @@
|
|
|
30
31
|
"author": "AnthonyLzq",
|
|
31
32
|
"license": "MIT",
|
|
32
33
|
"dependencies": {
|
|
33
|
-
"cli-progress": "^3.
|
|
34
|
+
"cli-progress": "^3.10.0",
|
|
34
35
|
"colors": "^1.4.0",
|
|
35
36
|
"readline-sync": "^1.4.10",
|
|
36
37
|
"underscore": "^1.13.2",
|
|
37
|
-
"yargs": "^17.3.
|
|
38
|
+
"yargs": "^17.3.1"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
|
-
"
|
|
41
|
+
"dotenv": "^14.3.2",
|
|
42
|
+
"eslint": "^8.7.0",
|
|
41
43
|
"eslint-config-prettier": "^8.3.0",
|
|
42
44
|
"eslint-config-standard": "^16.0.3",
|
|
43
|
-
"eslint-plugin-import": "^2.25.
|
|
45
|
+
"eslint-plugin-import": "^2.25.4",
|
|
44
46
|
"eslint-plugin-node": "^11.1.0",
|
|
45
47
|
"eslint-plugin-prettier": "^4.0.0",
|
|
46
48
|
"standard-version": "^9.3.2"
|