@anthonylzq/simba.js 7.2.0 → 8.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 +94 -104
- package/bin/index.js +4 -0
- package/lib/index.js +155 -194
- package/lib/src/functions/api/database.js +194 -233
- package/lib/src/functions/api/express.js +270 -1572
- package/lib/src/functions/api/fastify.js +250 -1579
- package/lib/src/functions/api/index.js +34 -24
- package/lib/src/functions/api/schemas.js +40 -58
- package/lib/src/functions/api/services.js +147 -135
- package/lib/src/functions/api/utils.js +78 -102
- package/lib/src/functions/docker.js +32 -23
- package/lib/src/functions/eslint.js +9 -7
- package/lib/src/functions/ghat.js +35 -26
- package/lib/src/functions/index.js +1 -3
- package/lib/src/functions/packageJson.js +10 -21
- package/lib/src/functions/tests.js +88 -375
- package/lib/src/functions/tsconfig.js +9 -9
- package/lib/src/index.js +31 -50
- package/lib/src/utils/constants.js +36 -1
- package/lib/src/utils/index.js +5 -0
- package/package.json +66 -59
- package/lib/src/functions/heroku.js +0 -16
- package/lib/src/functions/webpack.js +0 -51
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
const { platform } = require('os')
|
|
2
2
|
const { promisify } = require('util')
|
|
3
3
|
const exec = promisify(require('child_process').exec)
|
|
4
|
+
|
|
5
|
+
const db = require('./database')
|
|
6
|
+
const schemas = require('./schemas')
|
|
7
|
+
const services = require('./services')
|
|
8
|
+
const utils = require('./utils')
|
|
4
9
|
const writeFile = require('../../utils/writeFile')
|
|
5
10
|
|
|
6
11
|
/**
|
|
@@ -66,500 +71,6 @@ export {}
|
|
|
66
71
|
await Promise.all(processes)
|
|
67
72
|
}
|
|
68
73
|
|
|
69
|
-
/**
|
|
70
|
-
* @param {Object} args
|
|
71
|
-
* @param {String} args.projectName
|
|
72
|
-
*/
|
|
73
|
-
const mongo = async ({ projectName }) => {
|
|
74
|
-
const createFoldersCommand = `mkdir ${projectName}/src/database \
|
|
75
|
-
${projectName}/src/database/mongo ${projectName}/src/database/mongo/models \
|
|
76
|
-
${projectName}/src/database/mongo/queries`
|
|
77
|
-
|
|
78
|
-
if (platform() === 'win32')
|
|
79
|
-
await exec(createFoldersCommand.replaceAll('/', '\\'))
|
|
80
|
-
else await exec(createFoldersCommand)
|
|
81
|
-
|
|
82
|
-
const database = {
|
|
83
|
-
index: {
|
|
84
|
-
content: "export * from './mongo'\n",
|
|
85
|
-
file: `${projectName}/src/database/index.ts`
|
|
86
|
-
},
|
|
87
|
-
mongo: {
|
|
88
|
-
connection: {
|
|
89
|
-
content: `import { connect, connection } from 'mongoose'
|
|
90
|
-
import { FastifyLoggerInstance } from 'fastify'
|
|
91
|
-
|
|
92
|
-
const ENVIRONMENTS_WITHOUT_RECONNECTION = ['ci', 'local']
|
|
93
|
-
const dbConnection = async (
|
|
94
|
-
logger?: FastifyLoggerInstance
|
|
95
|
-
): Promise<{
|
|
96
|
-
connect: () => Promise<typeof import('mongoose')>
|
|
97
|
-
disconnect: () => Promise<void>
|
|
98
|
-
}> => {
|
|
99
|
-
const connectionConfig = {
|
|
100
|
-
keepAlive: true,
|
|
101
|
-
useNewUrlParser: true,
|
|
102
|
-
useUnifiedTopology: true
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
connection.on('connected', () => {
|
|
106
|
-
logger?.info('Mongo connection established.')
|
|
107
|
-
})
|
|
108
|
-
connection.on('reconnected', () => {
|
|
109
|
-
logger?.info('Mongo connection reestablished')
|
|
110
|
-
})
|
|
111
|
-
connection.on('disconnected', () => {
|
|
112
|
-
if (
|
|
113
|
-
!ENVIRONMENTS_WITHOUT_RECONNECTION.includes(
|
|
114
|
-
process.env.NODE_ENV as string
|
|
115
|
-
)
|
|
116
|
-
) {
|
|
117
|
-
logger?.info(
|
|
118
|
-
'Mongo connection disconnected. Trying to reconnected to Mongo...'
|
|
119
|
-
)
|
|
120
|
-
setTimeout(() => {
|
|
121
|
-
connect(process.env.DB_URI as string, {
|
|
122
|
-
...connection,
|
|
123
|
-
connectTimeoutMS: 3000,
|
|
124
|
-
socketTimeoutMS: 3000
|
|
125
|
-
})
|
|
126
|
-
}, 3000)
|
|
127
|
-
}
|
|
128
|
-
})
|
|
129
|
-
connection.on('close', () => {
|
|
130
|
-
logger?.info('Mongo connection closed')
|
|
131
|
-
})
|
|
132
|
-
connection.on('error', (e: Error) => {
|
|
133
|
-
logger?.info('Mongo connection error:')
|
|
134
|
-
logger?.error(e)
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
return {
|
|
138
|
-
connect: () => connect(process.env.DB_URI as string, connectionConfig),
|
|
139
|
-
disconnect: () => connection.close()
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
export { dbConnection }
|
|
144
|
-
`,
|
|
145
|
-
file: `${projectName}/src/database/mongo/connection.ts`
|
|
146
|
-
},
|
|
147
|
-
index: {
|
|
148
|
-
content: `export * from './models'
|
|
149
|
-
export * from './queries'
|
|
150
|
-
export * from './connection'
|
|
151
|
-
`,
|
|
152
|
-
file: `${projectName}/src/database/mongo/index.ts`
|
|
153
|
-
},
|
|
154
|
-
models: {
|
|
155
|
-
index: {
|
|
156
|
-
content: "export * from './user'\n",
|
|
157
|
-
file: `${projectName}/src/database/mongo/models/index.ts`
|
|
158
|
-
},
|
|
159
|
-
user: {
|
|
160
|
-
content: `import { model, Schema } from 'mongoose'
|
|
161
|
-
|
|
162
|
-
const UserSchema = new Schema<UserDBO>(
|
|
163
|
-
{
|
|
164
|
-
lastName: {
|
|
165
|
-
required: true,
|
|
166
|
-
type: String
|
|
167
|
-
},
|
|
168
|
-
name: {
|
|
169
|
-
required: true,
|
|
170
|
-
type: String
|
|
171
|
-
}
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
timestamps: true,
|
|
175
|
-
versionKey: false,
|
|
176
|
-
toObject: {
|
|
177
|
-
transform: (_, ret) => {
|
|
178
|
-
ret.id = ret._id.toString()
|
|
179
|
-
delete ret._id
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
const UserModel = model<UserDBO>('users', UserSchema)
|
|
186
|
-
|
|
187
|
-
export { UserModel }
|
|
188
|
-
`,
|
|
189
|
-
file: `${projectName}/src/database/mongo/models/user.ts`
|
|
190
|
-
}
|
|
191
|
-
},
|
|
192
|
-
queries: {
|
|
193
|
-
index: {
|
|
194
|
-
content: "export * from './user'\n",
|
|
195
|
-
file: `${projectName}/src/database/mongo/queries/index.ts`
|
|
196
|
-
},
|
|
197
|
-
user: {
|
|
198
|
-
content: `import { Document, MergeType, Types } from 'mongoose'
|
|
199
|
-
|
|
200
|
-
import { UserModel } from '..'
|
|
201
|
-
import { User, UserDTO, UserWithId } from 'schemas'
|
|
202
|
-
|
|
203
|
-
const userDBOtoDTO = (
|
|
204
|
-
userDBO: Document<unknown, unknown, MergeType<UserDBO, UserDBO>> &
|
|
205
|
-
Omit<UserDBO, keyof UserDBO> &
|
|
206
|
-
UserDBO & {
|
|
207
|
-
_id: Types.ObjectId
|
|
208
|
-
}
|
|
209
|
-
): UserDTO => ({
|
|
210
|
-
...userDBO.toObject(),
|
|
211
|
-
createdAt: userDBO.createdAt.toISOString(),
|
|
212
|
-
updatedAt: userDBO.updatedAt.toISOString()
|
|
213
|
-
})
|
|
214
|
-
|
|
215
|
-
const store = async (userData: User): Promise<UserDTO> => {
|
|
216
|
-
const user = new UserModel(userData)
|
|
217
|
-
|
|
218
|
-
await user.save()
|
|
219
|
-
|
|
220
|
-
return userDBOtoDTO(user)
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const remove = async (
|
|
224
|
-
id: string | null = null
|
|
225
|
-
): Promise<UserDTO | number | null> => {
|
|
226
|
-
if (id) {
|
|
227
|
-
const removedUser = await UserModel.findByIdAndRemove(id)
|
|
228
|
-
|
|
229
|
-
if (!removedUser) return null
|
|
230
|
-
|
|
231
|
-
return userDBOtoDTO(removedUser)
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return (await UserModel.deleteMany({})).deletedCount
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const get = async (
|
|
238
|
-
id: string | null = null
|
|
239
|
-
): Promise<UserDTO[] | UserDTO | null> => {
|
|
240
|
-
if (id) {
|
|
241
|
-
const user = await UserModel.findById(id)
|
|
242
|
-
|
|
243
|
-
return user ? userDBOtoDTO(user) : null
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const users = await UserModel.find({})
|
|
247
|
-
|
|
248
|
-
return users.map(u => userDBOtoDTO(u))
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const update = async (userData: UserWithId): Promise<UserDTO | null> => {
|
|
252
|
-
const { id, ...rest } = userData
|
|
253
|
-
const user = await UserModel.findByIdAndUpdate(id, rest, { new: true })
|
|
254
|
-
|
|
255
|
-
return user ? userDBOtoDTO(user) : null
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
export { store, remove, get, update }
|
|
259
|
-
`,
|
|
260
|
-
file: `${projectName}/src/database/mongo/queries/user.ts`
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
await Promise.all([
|
|
267
|
-
writeFile(database.index.file, database.index.content),
|
|
268
|
-
writeFile(
|
|
269
|
-
database.mongo.connection.file,
|
|
270
|
-
database.mongo.connection.content
|
|
271
|
-
),
|
|
272
|
-
writeFile(database.mongo.index.file, database.mongo.index.content),
|
|
273
|
-
writeFile(
|
|
274
|
-
database.mongo.models.index.file,
|
|
275
|
-
database.mongo.models.index.content
|
|
276
|
-
),
|
|
277
|
-
writeFile(
|
|
278
|
-
database.mongo.models.user.file,
|
|
279
|
-
database.mongo.models.user.content
|
|
280
|
-
),
|
|
281
|
-
writeFile(
|
|
282
|
-
database.mongo.queries.index.file,
|
|
283
|
-
database.mongo.queries.index.content
|
|
284
|
-
),
|
|
285
|
-
writeFile(
|
|
286
|
-
database.mongo.queries.user.file,
|
|
287
|
-
database.mongo.queries.user.content
|
|
288
|
-
)
|
|
289
|
-
])
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* @param {Object} args
|
|
294
|
-
* @param {String} args.projectName
|
|
295
|
-
* @param {import('../../../../').Config['database']} args.db
|
|
296
|
-
*/
|
|
297
|
-
const sql = async ({ projectName, db }) => {
|
|
298
|
-
const createFoldersCommand = `mkdir ${projectName}/src/scripts \
|
|
299
|
-
${projectName}/src/database ${projectName}/src/database/${db} \
|
|
300
|
-
${projectName}/src/database/${db}/models ${projectName}/src/database/${db}/queries \
|
|
301
|
-
${projectName}/src/database/${db}/migrations`
|
|
302
|
-
|
|
303
|
-
if (platform() === 'win32')
|
|
304
|
-
await exec(createFoldersCommand.replaceAll('/', '\\'))
|
|
305
|
-
else await exec(createFoldersCommand)
|
|
306
|
-
|
|
307
|
-
const database = {
|
|
308
|
-
index: {
|
|
309
|
-
content: `export * from './${db}'\n`,
|
|
310
|
-
file: `${projectName}/src/database/index.ts`
|
|
311
|
-
},
|
|
312
|
-
[db]: {
|
|
313
|
-
config: {
|
|
314
|
-
content: `require('dotenv').config()
|
|
315
|
-
|
|
316
|
-
module.exports = {
|
|
317
|
-
development: {
|
|
318
|
-
url: process.env.DB_URI,
|
|
319
|
-
dialect: 'postgres'
|
|
320
|
-
},
|
|
321
|
-
production: {
|
|
322
|
-
url: process.env.DB_URI,
|
|
323
|
-
dialect: 'postgres'
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
`,
|
|
327
|
-
file: `${projectName}/src/database/${db}/config.js`
|
|
328
|
-
},
|
|
329
|
-
connection: {
|
|
330
|
-
content: `import { join } from 'path'
|
|
331
|
-
import { Sequelize } from 'sequelize-typescript'
|
|
332
|
-
import { FastifyLoggerInstance } from 'fastify'
|
|
333
|
-
|
|
334
|
-
import * as models from './models'
|
|
335
|
-
|
|
336
|
-
let sequelize: Sequelize
|
|
337
|
-
|
|
338
|
-
const dbConnection = async (
|
|
339
|
-
logger?: FastifyLoggerInstance
|
|
340
|
-
): Promise<{
|
|
341
|
-
connect: () => Promise<Sequelize>
|
|
342
|
-
disconnect: () => Promise<void>
|
|
343
|
-
createMigration: (migrationName: string) => Promise<void>
|
|
344
|
-
}> => {
|
|
345
|
-
return {
|
|
346
|
-
connect: async () => {
|
|
347
|
-
if (!sequelize) {
|
|
348
|
-
sequelize = new Sequelize(process.env.DB_URI as string, {
|
|
349
|
-
models: Object.values(models)
|
|
350
|
-
})
|
|
351
|
-
logger?.info('Postgres connection established.')
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
return sequelize
|
|
355
|
-
},
|
|
356
|
-
disconnect: () => {
|
|
357
|
-
logger?.info('Postgres connection closed.')
|
|
358
|
-
|
|
359
|
-
return sequelize?.close()
|
|
360
|
-
},
|
|
361
|
-
createMigration: async (migrationName: string) => {
|
|
362
|
-
const { SequelizeTypescriptMigration } = await import(
|
|
363
|
-
'sequelize-typescript-migration-lts'
|
|
364
|
-
)
|
|
365
|
-
|
|
366
|
-
await SequelizeTypescriptMigration.makeMigration(sequelize, {
|
|
367
|
-
outDir: join(__dirname, './migrations'),
|
|
368
|
-
migrationName,
|
|
369
|
-
preview: false
|
|
370
|
-
})
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
export { dbConnection }
|
|
376
|
-
`,
|
|
377
|
-
file: `${projectName}/src/database/${db}/connection.ts`
|
|
378
|
-
},
|
|
379
|
-
index: {
|
|
380
|
-
content: `export * from './connection'
|
|
381
|
-
export * from './models'
|
|
382
|
-
export * from './queries'
|
|
383
|
-
`,
|
|
384
|
-
file: `${projectName}/src/database/${db}/index.ts`
|
|
385
|
-
},
|
|
386
|
-
models: {
|
|
387
|
-
index: {
|
|
388
|
-
content: "export * from './user'\n",
|
|
389
|
-
file: `${projectName}/src/database/${db}/models/index.ts`
|
|
390
|
-
},
|
|
391
|
-
user: {
|
|
392
|
-
content: `import { Model, Column, Table, DataType } from 'sequelize-typescript'
|
|
393
|
-
|
|
394
|
-
@Table({
|
|
395
|
-
paranoid: true,
|
|
396
|
-
tableName: 'users'
|
|
397
|
-
})
|
|
398
|
-
class User extends Model {
|
|
399
|
-
@Column({
|
|
400
|
-
type: DataType.STRING
|
|
401
|
-
})
|
|
402
|
-
name!: string
|
|
403
|
-
|
|
404
|
-
@Column({
|
|
405
|
-
type: DataType.STRING
|
|
406
|
-
})
|
|
407
|
-
lastName!: string
|
|
408
|
-
|
|
409
|
-
@Column({
|
|
410
|
-
type: DataType.STRING
|
|
411
|
-
})
|
|
412
|
-
email!: string
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
export { User }
|
|
416
|
-
`,
|
|
417
|
-
file: `${projectName}/src/database/${db}/models/user.ts`
|
|
418
|
-
}
|
|
419
|
-
},
|
|
420
|
-
queries: {
|
|
421
|
-
index: {
|
|
422
|
-
content: "export * from './user'\n",
|
|
423
|
-
file: `${projectName}/src/database/${db}/queries/index.ts`
|
|
424
|
-
},
|
|
425
|
-
user: {
|
|
426
|
-
content: `import { User } from '..'
|
|
427
|
-
import { User as UserSchema, UserDTO, UserWithId } from 'schemas'
|
|
428
|
-
import { Transaction } from 'sequelize/types'
|
|
429
|
-
|
|
430
|
-
const userDBOtoDTO = (userDBO: User): UserDTO => ({
|
|
431
|
-
...userDBO.get(),
|
|
432
|
-
createdAt: userDBO.createdAt.toISOString(),
|
|
433
|
-
updatedAt: userDBO.updatedAt.toISOString()
|
|
434
|
-
})
|
|
435
|
-
|
|
436
|
-
const store = async (
|
|
437
|
-
userData: UserSchema,
|
|
438
|
-
transaction: Transaction | null = null
|
|
439
|
-
): Promise<UserDTO> => {
|
|
440
|
-
const user = await User.create(userData, {
|
|
441
|
-
transaction
|
|
442
|
-
})
|
|
443
|
-
|
|
444
|
-
return userDBOtoDTO(user)
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
const remove = async (
|
|
448
|
-
id: number | null = null,
|
|
449
|
-
transaction: Transaction | null = null
|
|
450
|
-
): Promise<number | null> => {
|
|
451
|
-
if (id) {
|
|
452
|
-
const removedUser = await User.destroy({
|
|
453
|
-
where: { id },
|
|
454
|
-
transaction
|
|
455
|
-
})
|
|
456
|
-
|
|
457
|
-
return removedUser
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
const w = await User.destroy({ truncate: true, transaction })
|
|
461
|
-
|
|
462
|
-
return w
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
const get = async (
|
|
466
|
-
id: number | null = null
|
|
467
|
-
): Promise<UserDTO[] | UserDTO | null> => {
|
|
468
|
-
if (id) {
|
|
469
|
-
const user = await User.findByPk(id)
|
|
470
|
-
|
|
471
|
-
return user ? userDBOtoDTO(user) : null
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
const { rows: users } = await User.findAndCountAll()
|
|
475
|
-
|
|
476
|
-
return users.map(u => userDBOtoDTO(u))
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
const update = async (userData: UserWithId): Promise<UserDTO | null> => {
|
|
480
|
-
const { id, ...rest } = userData
|
|
481
|
-
const [, user] = await User.update(rest, {
|
|
482
|
-
where: { id },
|
|
483
|
-
returning: true,
|
|
484
|
-
limit: 1
|
|
485
|
-
})
|
|
486
|
-
|
|
487
|
-
return user[0] ? userDBOtoDTO(user[0]) : null
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
export { store, remove, get, update }
|
|
491
|
-
`,
|
|
492
|
-
file: `${projectName}/src/database/${db}/queries/user.ts`
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
},
|
|
496
|
-
scripts: {
|
|
497
|
-
migration: {
|
|
498
|
-
content: `import { dbConnection } from 'database'
|
|
499
|
-
import { promisify } from 'util'
|
|
500
|
-
|
|
501
|
-
const exec = promisify(require('child_process').exec)
|
|
502
|
-
|
|
503
|
-
const migration = async () => {
|
|
504
|
-
const connection = await dbConnection()
|
|
505
|
-
|
|
506
|
-
await connection.connect()
|
|
507
|
-
|
|
508
|
-
console.log('Creating migration')
|
|
509
|
-
|
|
510
|
-
if (process.env.MIGRATION)
|
|
511
|
-
await connection.createMigration(process.env.MIGRATION)
|
|
512
|
-
|
|
513
|
-
console.log('Executing migration')
|
|
514
|
-
|
|
515
|
-
await exec(
|
|
516
|
-
'yarn migrations:run:last && eslint src/database/* --ext .js --fix'
|
|
517
|
-
)
|
|
518
|
-
|
|
519
|
-
console.log('Migration complete')
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
migration()
|
|
523
|
-
`,
|
|
524
|
-
file: `${projectName}/src/scripts/migration.ts`
|
|
525
|
-
}
|
|
526
|
-
},
|
|
527
|
-
sequelizerc: {
|
|
528
|
-
content: `module.exports = {
|
|
529
|
-
config: './src/database/postgres/config.js',
|
|
530
|
-
'migrations-path': './src/database/postgres/migrations/'
|
|
531
|
-
}
|
|
532
|
-
`,
|
|
533
|
-
file: `${projectName}/.sequelizerc`
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
await Promise.all([
|
|
538
|
-
writeFile(database.index.file, database.index.content),
|
|
539
|
-
writeFile(database[db].config.file, database[db].config.content),
|
|
540
|
-
writeFile(database[db].connection.file, database[db].connection.content),
|
|
541
|
-
writeFile(database[db].index.file, database[db].index.content),
|
|
542
|
-
writeFile(
|
|
543
|
-
database[db].models.index.file,
|
|
544
|
-
database[db].models.index.content
|
|
545
|
-
),
|
|
546
|
-
writeFile(database[db].models.user.file, database[db].models.user.content),
|
|
547
|
-
writeFile(
|
|
548
|
-
database[db].queries.index.file,
|
|
549
|
-
database[db].queries.index.content
|
|
550
|
-
),
|
|
551
|
-
writeFile(
|
|
552
|
-
database[db].queries.user.file,
|
|
553
|
-
database[db].queries.user.content
|
|
554
|
-
),
|
|
555
|
-
writeFile(
|
|
556
|
-
database.scripts.migration.file,
|
|
557
|
-
database.scripts.migration.content
|
|
558
|
-
),
|
|
559
|
-
writeFile(database.sequelizerc.file, database.sequelizerc.content)
|
|
560
|
-
])
|
|
561
|
-
}
|
|
562
|
-
|
|
563
74
|
/**
|
|
564
75
|
* @param {Object} args
|
|
565
76
|
* @param {String} args.projectName
|
|
@@ -568,11 +79,9 @@ migration()
|
|
|
568
79
|
*/
|
|
569
80
|
const network = async ({ projectName, graphQL, dbIsSQL }) => {
|
|
570
81
|
const createFoldersCommand = `mkdir ${projectName}/src/network \
|
|
571
|
-
${projectName}/src/network/routes ${
|
|
82
|
+
${projectName}/src/network/routes ${
|
|
572
83
|
graphQL
|
|
573
|
-
? `${projectName}/src/
|
|
574
|
-
${projectName}/src/graphQL/models/User ${projectName}/src/graphQL/models/utils \
|
|
575
|
-
${projectName}/src/graphQL/models/utils/messages`
|
|
84
|
+
? `${projectName}/src/network/models ${projectName}/src/network/resolvers`
|
|
576
85
|
: ''
|
|
577
86
|
}`
|
|
578
87
|
|
|
@@ -619,10 +128,10 @@ ${
|
|
|
619
128
|
: "import { Home, User, Docs } from './routes'"
|
|
620
129
|
}
|
|
621
130
|
|
|
622
|
-
|
|
623
|
-
const applyRoutes = (app: FastifyInstance)
|
|
624
|
-
Home(app)
|
|
131
|
+
const routers = [Home${graphQL ? '' : ', User'}]
|
|
132
|
+
const applyRoutes = async (app: FastifyInstance) => {
|
|
625
133
|
routers.forEach(router => router(app))
|
|
134
|
+
await Docs(app)
|
|
626
135
|
|
|
627
136
|
// Handling 404 error
|
|
628
137
|
app.setNotFoundHandler((request, reply) => {
|
|
@@ -643,44 +152,43 @@ const applyRoutes = (app: FastifyInstance): void => {
|
|
|
643
152
|
})
|
|
644
153
|
}
|
|
645
154
|
|
|
646
|
-
export { applyRoutes }
|
|
647
|
-
`,
|
|
155
|
+
export { applyRoutes }\n`,
|
|
648
156
|
file: `${projectName}/src/network/router.ts`
|
|
649
157
|
},
|
|
650
158
|
server: {
|
|
651
159
|
content: graphQL
|
|
652
160
|
? `import fastify, { FastifyInstance } from 'fastify'
|
|
653
|
-
import
|
|
161
|
+
import debug from 'debug'
|
|
654
162
|
import {
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
} from 'apollo
|
|
659
|
-
import {
|
|
660
|
-
|
|
163
|
+
serializerCompiler,
|
|
164
|
+
validatorCompiler
|
|
165
|
+
} from 'fastify-type-provider-zod'
|
|
166
|
+
import { ApolloServer } from '@apollo/server'
|
|
167
|
+
import fastifyApollo, {
|
|
168
|
+
fastifyApolloDrainPlugin
|
|
169
|
+
} from '@as-integrations/fastify'
|
|
661
170
|
|
|
662
|
-
import {
|
|
171
|
+
import { dbConnection } from 'database'
|
|
663
172
|
import { applyRoutes } from './router'
|
|
173
|
+
import { buildSchemas } from './resolvers'
|
|
174
|
+
import { Log } from 'utils'
|
|
664
175
|
|
|
665
|
-
const
|
|
666
|
-
const
|
|
176
|
+
const d = debug('App:Network:Server')
|
|
177
|
+
const PORT = process.env.PORT ? parseInt(process.env.PORT) : 1996
|
|
667
178
|
|
|
668
|
-
class Server {
|
|
179
|
+
class Server implements Log {
|
|
669
180
|
#app: FastifyInstance
|
|
670
|
-
#connection: Awaited<ReturnType<typeof dbConnection>>
|
|
181
|
+
#connection: Awaited<ReturnType<typeof dbConnection>>
|
|
182
|
+
#apolloServer: ApolloServer | undefined
|
|
671
183
|
|
|
672
184
|
constructor() {
|
|
673
|
-
this.#app = fastify(
|
|
674
|
-
|
|
675
|
-
prettyPrint: !ENVIRONMENTS_WITHOUT_PRETTY_PRINT.includes(
|
|
676
|
-
process.env.NODE_ENV as string
|
|
677
|
-
)
|
|
678
|
-
}
|
|
679
|
-
})
|
|
680
|
-
this.#config()
|
|
185
|
+
this.#app = fastify()
|
|
186
|
+
this.#connection = dbConnection(d)
|
|
681
187
|
}
|
|
682
188
|
|
|
683
|
-
#config() {
|
|
189
|
+
async #config() {
|
|
190
|
+
await this.#apolloConfig()
|
|
191
|
+
this.#app.register(require('@fastify/cors'), {})
|
|
684
192
|
this.#app.addHook('preHandler', (req, reply, done) => {
|
|
685
193
|
reply.header('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE')
|
|
686
194
|
reply.header('Access-Control-Allow-Origin', '*')
|
|
@@ -691,99 +199,95 @@ class Server {
|
|
|
691
199
|
reply.header('x-powered-by', 'Simba.js')
|
|
692
200
|
done()
|
|
693
201
|
})
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
async #dbConnection() {
|
|
698
|
-
this.#connection = await dbConnection(this.#app.log)
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
#fastifyAppClosePlugin(): ApolloServerPlugin {
|
|
702
|
-
const app = this.#app
|
|
703
|
-
|
|
704
|
-
return {
|
|
705
|
-
async serverWillStart() {
|
|
706
|
-
return {
|
|
707
|
-
async drainServer() {
|
|
708
|
-
await app.close()
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
}
|
|
202
|
+
this.#app.setValidatorCompiler(validatorCompiler)
|
|
203
|
+
this.#app.setSerializerCompiler(serializerCompiler)
|
|
204
|
+
await applyRoutes(this.#app)
|
|
713
205
|
}
|
|
714
206
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
schema,
|
|
718
|
-
plugins: [
|
|
719
|
-
this.#fastifyAppClosePlugin(),
|
|
720
|
-
ApolloServerPluginDrainHttpServer({ httpServer: this.#app.server }),
|
|
721
|
-
process.env.NODE_ENV === 'production'
|
|
722
|
-
? ApolloServerPluginLandingPageDisabled()
|
|
723
|
-
: ApolloServerPluginLandingPageGraphQLPlayground()
|
|
724
|
-
],
|
|
725
|
-
context: (): Context => ({
|
|
726
|
-
log: this.#app.log
|
|
727
|
-
})
|
|
207
|
+
async #apolloConfig() {
|
|
208
|
+
this.#apolloServer = new ApolloServer({
|
|
209
|
+
schema: await buildSchemas(),
|
|
210
|
+
plugins: [fastifyApolloDrainPlugin(this.#app)]
|
|
728
211
|
})
|
|
212
|
+
await this.#apolloServer.start()
|
|
213
|
+
await this.#app.register(fastifyApollo(this.#apolloServer))
|
|
214
|
+
}
|
|
729
215
|
|
|
216
|
+
async start() {
|
|
730
217
|
try {
|
|
731
|
-
await
|
|
732
|
-
this.#
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
)
|
|
737
|
-
|
|
738
|
-
await this.#connection?.connect()
|
|
739
|
-
await this.#app.listen(PORT)
|
|
740
|
-
this.#app.log.info(
|
|
741
|
-
\`GraphQL server listening at: http://localhost:\${PORT}\${server.graphqlPath}\`
|
|
742
|
-
)
|
|
218
|
+
await this.#config()
|
|
219
|
+
await this.#connection.connect()
|
|
220
|
+
await this.#app.listen({
|
|
221
|
+
port: PORT,
|
|
222
|
+
host: '::'
|
|
223
|
+
})
|
|
224
|
+
d(\`HTTP server listening on port \${PORT}.\`)
|
|
743
225
|
} catch (e) {
|
|
744
|
-
|
|
226
|
+
this.log({
|
|
227
|
+
method: this.start.name,
|
|
228
|
+
value: 'error',
|
|
229
|
+
content: e
|
|
230
|
+
})
|
|
745
231
|
}
|
|
746
232
|
}
|
|
747
233
|
|
|
748
|
-
|
|
234
|
+
async stop() {
|
|
749
235
|
try {
|
|
750
236
|
await this.#connection?.disconnect()
|
|
751
237
|
await this.#app.close()
|
|
238
|
+
await this.#apolloServer?.stop()
|
|
239
|
+
d('HTTP server stopped.')
|
|
752
240
|
} catch (e) {
|
|
753
|
-
|
|
241
|
+
this.log({
|
|
242
|
+
method: this.stop.name,
|
|
243
|
+
value: 'error',
|
|
244
|
+
content: e
|
|
245
|
+
})
|
|
754
246
|
}
|
|
755
247
|
}
|
|
248
|
+
|
|
249
|
+
log({
|
|
250
|
+
method,
|
|
251
|
+
value,
|
|
252
|
+
content
|
|
253
|
+
}: {
|
|
254
|
+
method: string
|
|
255
|
+
value: string
|
|
256
|
+
content: unknown
|
|
257
|
+
}) {
|
|
258
|
+
d(
|
|
259
|
+
\`Server invoked -> \${this.constructor.name} ~ \${method} ~ value: \${value} ~ content: \${content}\`
|
|
260
|
+
)
|
|
261
|
+
}
|
|
756
262
|
}
|
|
757
263
|
|
|
758
264
|
const server = new Server()
|
|
759
265
|
|
|
760
|
-
export { server as Server }
|
|
761
|
-
`
|
|
266
|
+
export { server as Server }\n`
|
|
762
267
|
: `import fastify, { FastifyInstance } from 'fastify'
|
|
268
|
+
import debug from 'debug'
|
|
269
|
+
import {
|
|
270
|
+
serializerCompiler,
|
|
271
|
+
validatorCompiler
|
|
272
|
+
} from 'fastify-type-provider-zod'
|
|
763
273
|
|
|
764
274
|
import { dbConnection } from 'database'
|
|
275
|
+
import { Log } from 'utils'
|
|
765
276
|
import { applyRoutes } from './router'
|
|
766
|
-
import { validatorCompiler } from './utils'
|
|
767
277
|
|
|
768
|
-
const
|
|
769
|
-
const
|
|
278
|
+
const d = debug('App:Network:Server')
|
|
279
|
+
const PORT = process.env.PORT ? parseInt(process.env.PORT) : 1996
|
|
770
280
|
|
|
771
|
-
class Server {
|
|
281
|
+
class Server implements Log {
|
|
772
282
|
#app: FastifyInstance
|
|
773
|
-
#connection: Awaited<ReturnType<typeof dbConnection>>
|
|
283
|
+
#connection: Awaited<ReturnType<typeof dbConnection>>
|
|
774
284
|
|
|
775
285
|
constructor() {
|
|
776
|
-
this.#app = fastify(
|
|
777
|
-
|
|
778
|
-
prettyPrint: !ENVIRONMENTS_WITHOUT_PRETTY_PRINT.includes(
|
|
779
|
-
process.env.NODE_ENV as string
|
|
780
|
-
)
|
|
781
|
-
}
|
|
782
|
-
})
|
|
783
|
-
this.#config()
|
|
286
|
+
this.#app = fastify()
|
|
287
|
+
this.#connection = dbConnection(d)
|
|
784
288
|
}
|
|
785
289
|
|
|
786
|
-
#config() {
|
|
290
|
+
async #config() {
|
|
787
291
|
this.#app.register(require('@fastify/cors'), {})
|
|
788
292
|
this.#app.addHook('preHandler', (req, reply, done) => {
|
|
789
293
|
reply.header('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE')
|
|
@@ -796,47 +300,71 @@ class Server {
|
|
|
796
300
|
done()
|
|
797
301
|
})
|
|
798
302
|
this.#app.setValidatorCompiler(validatorCompiler)
|
|
799
|
-
|
|
303
|
+
this.#app.setSerializerCompiler(serializerCompiler)
|
|
304
|
+
await applyRoutes(this.#app)
|
|
800
305
|
}
|
|
801
306
|
|
|
802
|
-
async
|
|
803
|
-
this.#connection = await dbConnection(this.#app.log)
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
public async start(): Promise<void> {
|
|
307
|
+
async start(): Promise<void> {
|
|
807
308
|
try {
|
|
808
|
-
await this.#
|
|
809
|
-
await this.#connection
|
|
810
|
-
await this.#app.listen(
|
|
309
|
+
await this.#config()
|
|
310
|
+
await this.#connection.connect()
|
|
311
|
+
await this.#app.listen({
|
|
312
|
+
port: PORT,
|
|
313
|
+
host: '::'
|
|
314
|
+
})
|
|
315
|
+
d(\`HTTP server listening on port \${PORT}.\`)
|
|
811
316
|
} catch (e) {
|
|
812
|
-
|
|
317
|
+
this.log({
|
|
318
|
+
method: this.start.name,
|
|
319
|
+
value: 'error',
|
|
320
|
+
content: e
|
|
321
|
+
})
|
|
813
322
|
}
|
|
814
323
|
}
|
|
815
324
|
|
|
816
|
-
|
|
325
|
+
async stop(): Promise<void> {
|
|
817
326
|
try {
|
|
818
327
|
await this.#connection?.disconnect()
|
|
819
328
|
await this.#app.close()
|
|
329
|
+
d('HTTP server stopped.')
|
|
820
330
|
} catch (e) {
|
|
821
|
-
|
|
331
|
+
this.log({
|
|
332
|
+
method: this.stop.name,
|
|
333
|
+
value: 'error',
|
|
334
|
+
content: e
|
|
335
|
+
})
|
|
822
336
|
}
|
|
823
337
|
}
|
|
338
|
+
|
|
339
|
+
log({
|
|
340
|
+
method,
|
|
341
|
+
value,
|
|
342
|
+
content
|
|
343
|
+
}: {
|
|
344
|
+
method: string
|
|
345
|
+
value: string
|
|
346
|
+
content: unknown
|
|
347
|
+
}) {
|
|
348
|
+
d(
|
|
349
|
+
\`Server invoked -> \${this.constructor.name} ~ \${method} ~ value: \${value} ~ content: \${content}\`
|
|
350
|
+
)
|
|
351
|
+
}
|
|
824
352
|
}
|
|
825
353
|
|
|
826
354
|
const server = new Server()
|
|
827
355
|
|
|
828
|
-
export { server as Server }
|
|
829
|
-
`,
|
|
356
|
+
export { server as Server }\n`,
|
|
830
357
|
file: `${projectName}/src/network/server.ts`
|
|
831
358
|
},
|
|
832
359
|
routes: {
|
|
833
360
|
docs: {
|
|
834
361
|
content: `import { FastifyInstance } from 'fastify'
|
|
835
362
|
import fastifySwagger from '@fastify/swagger'
|
|
363
|
+
import fastifySwaggerUi from '@fastify/swagger-ui'
|
|
364
|
+
import { jsonSchemaTransform } from 'fastify-type-provider-zod'
|
|
836
365
|
|
|
837
|
-
const Docs = (app: FastifyInstance, prefix = '/api')
|
|
838
|
-
app.register(fastifySwagger, {
|
|
839
|
-
routePrefix: \`\${prefix}/docs\`,
|
|
366
|
+
const Docs = async (app: FastifyInstance, prefix = '/api') => {
|
|
367
|
+
await app.register(fastifySwagger, {
|
|
840
368
|
openapi: {
|
|
841
369
|
info: {
|
|
842
370
|
title: 'Test swagger',
|
|
@@ -863,19 +391,19 @@ const Docs = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
863
391
|
}
|
|
864
392
|
]
|
|
865
393
|
},
|
|
866
|
-
|
|
394
|
+
transform: jsonSchemaTransform
|
|
867
395
|
})
|
|
396
|
+
await app.register(fastifySwaggerUi, { routePrefix: \`\${prefix}/docs\` })
|
|
868
397
|
}
|
|
869
398
|
|
|
870
|
-
export { Docs }
|
|
871
|
-
`,
|
|
399
|
+
export { Docs }\n`,
|
|
872
400
|
file: `${projectName}/src/network/routes/docs.ts`
|
|
873
401
|
},
|
|
874
402
|
home: {
|
|
875
403
|
content: `import { FastifyInstance } from 'fastify'
|
|
876
404
|
import { response } from 'network/response'
|
|
877
405
|
|
|
878
|
-
const Home = (app: FastifyInstance, prefix = '/')
|
|
406
|
+
const Home = (app: FastifyInstance, prefix = '/') => {
|
|
879
407
|
app.get(\`\${prefix}\`, (request, reply) => {
|
|
880
408
|
response({
|
|
881
409
|
error: false,
|
|
@@ -900,7 +428,8 @@ ${graphQL ? '' : "export * from './user'\n"}`,
|
|
|
900
428
|
...(!graphQL && {
|
|
901
429
|
user: {
|
|
902
430
|
content: `import { FastifyInstance } from 'fastify'
|
|
903
|
-
import {
|
|
431
|
+
import { ZodTypeProvider } from 'fastify-type-provider-zod'
|
|
432
|
+
import z from 'zod'
|
|
904
433
|
|
|
905
434
|
import { response } from 'network/response'
|
|
906
435
|
import {
|
|
@@ -914,18 +443,17 @@ import { UserService } from 'services'
|
|
|
914
443
|
|
|
915
444
|
const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
916
445
|
app
|
|
446
|
+
.withTypeProvider<ZodTypeProvider>()
|
|
917
447
|
.post<{ Body: StoreUserDTO }>(
|
|
918
448
|
\`\${prefix}/users\`,
|
|
919
449
|
{
|
|
920
450
|
schema: {
|
|
921
451
|
body: storeUserDto,
|
|
922
452
|
response: {
|
|
923
|
-
|
|
924
|
-
error:
|
|
925
|
-
type: 'boolean'
|
|
926
|
-
},
|
|
453
|
+
201: z.object({
|
|
454
|
+
error: z.boolean(),
|
|
927
455
|
message: userDto
|
|
928
|
-
}
|
|
456
|
+
})
|
|
929
457
|
},
|
|
930
458
|
tags: ['user']
|
|
931
459
|
}
|
|
@@ -936,73 +464,10 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
936
464
|
args: { lastName, name }
|
|
937
465
|
}
|
|
938
466
|
} = request
|
|
939
|
-
const us = new UserService({
|
|
940
|
-
user: { lastName, name }
|
|
941
|
-
})
|
|
942
|
-
const user = await us.process({ type: 'store' })
|
|
943
|
-
|
|
944
|
-
response({
|
|
945
|
-
error: false,
|
|
946
|
-
message: user,
|
|
947
|
-
reply,
|
|
948
|
-
status: 201
|
|
949
|
-
})
|
|
950
|
-
}
|
|
951
|
-
)
|
|
952
|
-
.get(
|
|
953
|
-
\`\${prefix}/users\`,
|
|
954
|
-
{
|
|
955
|
-
schema: {
|
|
956
|
-
response: {
|
|
957
|
-
200: {
|
|
958
|
-
error: {
|
|
959
|
-
type: 'boolean'
|
|
960
|
-
},
|
|
961
|
-
message: Type.Array(userDto)
|
|
962
|
-
}
|
|
963
|
-
},
|
|
964
|
-
tags: ['user']
|
|
965
|
-
}
|
|
966
|
-
},
|
|
967
|
-
async (request, reply) => {
|
|
968
467
|
const us = new UserService()
|
|
969
|
-
const
|
|
970
|
-
|
|
971
|
-
response({
|
|
972
|
-
error: false,
|
|
973
|
-
message: users,
|
|
974
|
-
reply,
|
|
975
|
-
status: 200
|
|
976
|
-
})
|
|
977
|
-
}
|
|
978
|
-
)
|
|
979
|
-
.delete(
|
|
980
|
-
\`\${prefix}/users\`,
|
|
981
|
-
{
|
|
982
|
-
schema: {
|
|
983
|
-
response: {
|
|
984
|
-
200: {
|
|
985
|
-
error: {
|
|
986
|
-
type: 'boolean'
|
|
987
|
-
},
|
|
988
|
-
message: {
|
|
989
|
-
type: 'string'
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
},
|
|
993
|
-
tags: ['user']
|
|
994
|
-
}
|
|
995
|
-
},
|
|
996
|
-
async (request, reply) => {
|
|
997
|
-
const us = new UserService()
|
|
998
|
-
const result = await us.process({ type: 'deleteAll' })
|
|
999
|
-
|
|
1000
|
-
response({
|
|
1001
|
-
error: false,
|
|
1002
|
-
message: result,
|
|
1003
|
-
reply,
|
|
1004
|
-
status: 200
|
|
1005
|
-
})
|
|
468
|
+
const user = await us.store({ lastName, name })
|
|
469
|
+
|
|
470
|
+
response({ error: false, message: user, reply, status: 201 })
|
|
1006
471
|
}
|
|
1007
472
|
)
|
|
1008
473
|
.get<{ Params: IdSchema }>(
|
|
@@ -1011,12 +476,10 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1011
476
|
schema: {
|
|
1012
477
|
params: idSchema,
|
|
1013
478
|
response: {
|
|
1014
|
-
200: {
|
|
1015
|
-
error:
|
|
1016
|
-
type: 'boolean'
|
|
1017
|
-
},
|
|
479
|
+
200: z.object({
|
|
480
|
+
error: z.boolean(),
|
|
1018
481
|
message: userDto
|
|
1019
|
-
}
|
|
482
|
+
})
|
|
1020
483
|
},
|
|
1021
484
|
tags: ['user']
|
|
1022
485
|
}
|
|
@@ -1025,15 +488,10 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1025
488
|
const {
|
|
1026
489
|
params: { id }
|
|
1027
490
|
} = request
|
|
1028
|
-
const us = new UserService(
|
|
1029
|
-
const user = await us.
|
|
1030
|
-
|
|
1031
|
-
response({
|
|
1032
|
-
error: false,
|
|
1033
|
-
message: user,
|
|
1034
|
-
reply,
|
|
1035
|
-
status: 200
|
|
1036
|
-
})
|
|
491
|
+
const us = new UserService()
|
|
492
|
+
const user = await us.getById(id)
|
|
493
|
+
|
|
494
|
+
response({ error: false, message: user, reply, status: 200 })
|
|
1037
495
|
}
|
|
1038
496
|
)
|
|
1039
497
|
.patch<{ Body: StoreUserDTO; Params: IdSchema }>(
|
|
@@ -1043,12 +501,10 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1043
501
|
body: storeUserDto,
|
|
1044
502
|
params: idSchema,
|
|
1045
503
|
response: {
|
|
1046
|
-
200: {
|
|
1047
|
-
error:
|
|
1048
|
-
type: 'boolean'
|
|
1049
|
-
},
|
|
504
|
+
200: z.object({
|
|
505
|
+
error: z.boolean(),
|
|
1050
506
|
message: userDto
|
|
1051
|
-
}
|
|
507
|
+
})
|
|
1052
508
|
},
|
|
1053
509
|
tags: ['user']
|
|
1054
510
|
}
|
|
@@ -1060,17 +516,10 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1060
516
|
},
|
|
1061
517
|
params: { id }
|
|
1062
518
|
} = request
|
|
1063
|
-
const us = new UserService(
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
response({
|
|
1069
|
-
error: false,
|
|
1070
|
-
message: user,
|
|
1071
|
-
reply,
|
|
1072
|
-
status: 200
|
|
1073
|
-
})
|
|
519
|
+
const us = new UserService()
|
|
520
|
+
const user = await us.update(id, { name, lastName })
|
|
521
|
+
|
|
522
|
+
response({ error: false, message: user, reply, status: 200 })
|
|
1074
523
|
}
|
|
1075
524
|
)
|
|
1076
525
|
.delete<{ Params: IdSchema }>(
|
|
@@ -1079,14 +528,10 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1079
528
|
schema: {
|
|
1080
529
|
params: idSchema,
|
|
1081
530
|
response: {
|
|
1082
|
-
200: {
|
|
1083
|
-
error:
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
message: {
|
|
1087
|
-
type: 'string'
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
531
|
+
200: z.object({
|
|
532
|
+
error: z.boolean(),
|
|
533
|
+
message: z.string()
|
|
534
|
+
})
|
|
1090
535
|
},
|
|
1091
536
|
tags: ['user']
|
|
1092
537
|
}
|
|
@@ -1095,526 +540,113 @@ const User = (app: FastifyInstance, prefix = '/api'): void => {
|
|
|
1095
540
|
const {
|
|
1096
541
|
params: { id }
|
|
1097
542
|
} = request
|
|
1098
|
-
const us = new UserService(
|
|
1099
|
-
const result = await us.
|
|
1100
|
-
|
|
1101
|
-
response({
|
|
1102
|
-
error: false,
|
|
1103
|
-
message: result,
|
|
1104
|
-
reply,
|
|
1105
|
-
status: 200
|
|
1106
|
-
})
|
|
543
|
+
const us = new UserService()
|
|
544
|
+
const result = await us.deleteById(id)
|
|
545
|
+
|
|
546
|
+
response({ error: false, message: result, reply, status: 200 })
|
|
1107
547
|
}
|
|
1108
548
|
)
|
|
1109
549
|
}
|
|
1110
550
|
|
|
1111
|
-
export { User }
|
|
1112
|
-
`,
|
|
551
|
+
export { User }\n`,
|
|
1113
552
|
file: `${projectName}/src/network/routes/user.ts`
|
|
1114
553
|
}
|
|
1115
554
|
})
|
|
1116
555
|
},
|
|
1117
|
-
utils: {
|
|
1118
|
-
index: {
|
|
1119
|
-
content: `/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1120
|
-
import {
|
|
1121
|
-
FastifyRouteSchemaDef,
|
|
1122
|
-
FastifyValidationResult
|
|
1123
|
-
} from 'fastify/types/schema'
|
|
1124
|
-
import httpErrors from 'http-errors'
|
|
1125
|
-
import Ajv from 'ajv'
|
|
1126
|
-
|
|
1127
|
-
const ajv = new Ajv({
|
|
1128
|
-
removeAdditional: true,
|
|
1129
|
-
useDefaults: true,
|
|
1130
|
-
coerceTypes: true,
|
|
1131
|
-
nullable: true
|
|
1132
|
-
})
|
|
1133
|
-
|
|
1134
|
-
const validatorCompiler = ({
|
|
1135
|
-
schema
|
|
1136
|
-
}: FastifyRouteSchemaDef<any>): FastifyValidationResult => {
|
|
1137
|
-
const validate = ajv.compile(schema)
|
|
1138
|
-
|
|
1139
|
-
return (data: unknown): boolean => {
|
|
1140
|
-
const ok = validate(data)
|
|
1141
|
-
|
|
1142
|
-
if (!ok && validate.errors) {
|
|
1143
|
-
const [error] = validate.errors
|
|
1144
|
-
const errorMessage = \`\${error.dataPath.replace('.', '')} \${error.message}\`
|
|
1145
|
-
|
|
1146
|
-
throw new httpErrors.UnprocessableEntity(errorMessage)
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
return true
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
|
-
export { validatorCompiler }
|
|
1154
|
-
`,
|
|
1155
|
-
file: `${projectName}/src/network/utils/index.ts`
|
|
1156
|
-
}
|
|
1157
|
-
},
|
|
1158
556
|
...(graphQL && {
|
|
1159
|
-
|
|
557
|
+
models: {
|
|
1160
558
|
index: {
|
|
1161
|
-
content: "export * from './
|
|
1162
|
-
file: `${projectName}/src/
|
|
559
|
+
content: "export * from './User'\n",
|
|
560
|
+
file: `${projectName}/src/network/models/index.ts`
|
|
1163
561
|
},
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
content: `import { makeExecutableSchema } from '@graphql-tools/schema'
|
|
1168
|
-
|
|
1169
|
-
import { User as UserTD } from './typeDefs'
|
|
1170
|
-
import { Query } from './queriesResolver'
|
|
1171
|
-
import { Mutation } from './mutationsResolver'
|
|
1172
|
-
|
|
1173
|
-
const resolvers = {
|
|
1174
|
-
Query,
|
|
1175
|
-
Mutation
|
|
1176
|
-
}
|
|
1177
|
-
|
|
1178
|
-
const User = makeExecutableSchema({
|
|
1179
|
-
typeDefs: UserTD,
|
|
1180
|
-
resolvers
|
|
1181
|
-
})
|
|
1182
|
-
|
|
1183
|
-
export { User }
|
|
1184
|
-
`,
|
|
1185
|
-
file: `${projectName}/src/graphQL/models/User/index.ts`
|
|
1186
|
-
},
|
|
1187
|
-
mutations: {
|
|
1188
|
-
content: `import { ApolloError } from 'apollo-server-core'
|
|
1189
|
-
|
|
1190
|
-
import { store, remove, update } from 'database'
|
|
1191
|
-
import { User, UserDTO, UserWithId } from 'schemas'
|
|
1192
|
-
import { EFU, MFU, GE, errorHandling } from '../utils'
|
|
1193
|
-
|
|
1194
|
-
const storeUser = async (
|
|
1195
|
-
{ user }: { user: User },
|
|
1196
|
-
{ log }: Context
|
|
1197
|
-
): Promise<UserDTO> => {
|
|
1198
|
-
try {
|
|
1199
|
-
const result = await store(user)
|
|
1200
|
-
|
|
1201
|
-
return result
|
|
1202
|
-
} catch (e) {
|
|
1203
|
-
return errorHandling({
|
|
1204
|
-
e,
|
|
1205
|
-
message: GE.INTERNAL_SERVER_ERROR,
|
|
1206
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
1207
|
-
log
|
|
1208
|
-
})
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
562
|
+
User: {
|
|
563
|
+
content: `import 'reflect-metadata'
|
|
564
|
+
import { Field, ${dbIsSQL ? 'Int' : 'ID'}, ObjectType } from 'type-graphql'
|
|
1211
565
|
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
566
|
+
@ObjectType()
|
|
567
|
+
class User {
|
|
568
|
+
@Field(() => ${dbIsSQL ? 'Int' : 'ID'})
|
|
569
|
+
id!: number
|
|
1215
570
|
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
if (usersDeleted === 0)
|
|
1219
|
-
throw new ApolloError(EFU.NOTHING_TO_DELETE, 'NOTHING_TO_DELETE')
|
|
571
|
+
@Field()
|
|
572
|
+
lastName!: string
|
|
1220
573
|
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
return errorHandling({
|
|
1224
|
-
e,
|
|
1225
|
-
message: GE.INTERNAL_SERVER_ERROR,
|
|
1226
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
1227
|
-
log
|
|
1228
|
-
})
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
574
|
+
@Field()
|
|
575
|
+
name!: string
|
|
1231
576
|
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
{ log }: Context
|
|
1235
|
-
): Promise<UserDTO> => {
|
|
1236
|
-
try {
|
|
1237
|
-
const updatedUser = await update(user)
|
|
1238
|
-
|
|
1239
|
-
if (!updatedUser) throw new ApolloError(EFU.NOT_FOUND, 'NOT_FOUND')
|
|
1240
|
-
|
|
1241
|
-
return updatedUser
|
|
1242
|
-
} catch (e) {
|
|
1243
|
-
return errorHandling({
|
|
1244
|
-
e,
|
|
1245
|
-
message: GE.INTERNAL_SERVER_ERROR,
|
|
1246
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
1247
|
-
log
|
|
1248
|
-
})
|
|
1249
|
-
}
|
|
1250
|
-
}
|
|
577
|
+
@Field({ nullable: true })
|
|
578
|
+
createdAt?: string
|
|
1251
579
|
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
{ log }: Context
|
|
1255
|
-
): Promise<string> => {
|
|
1256
|
-
try {
|
|
1257
|
-
const deletedUser = await remove(id)
|
|
1258
|
-
|
|
1259
|
-
if (!deletedUser) throw new ApolloError(EFU.NOT_FOUND, 'NOT_FOUND')
|
|
1260
|
-
|
|
1261
|
-
return MFU.USER_DELETED
|
|
1262
|
-
} catch (e) {
|
|
1263
|
-
return errorHandling({
|
|
1264
|
-
e,
|
|
1265
|
-
message: GE.INTERNAL_SERVER_ERROR,
|
|
1266
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
1267
|
-
log
|
|
1268
|
-
})
|
|
1269
|
-
}
|
|
580
|
+
@Field({ nullable: true })
|
|
581
|
+
updatedAt?: string
|
|
1270
582
|
}
|
|
1271
583
|
|
|
1272
|
-
export {
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
import {
|
|
1279
|
-
|
|
1280
|
-
import {
|
|
1281
|
-
ajv,
|
|
1282
|
-
idSchema,
|
|
1283
|
-
User,
|
|
1284
|
-
user as storeUserSchema,
|
|
1285
|
-
UserDTO,
|
|
1286
|
-
UserWithId,
|
|
1287
|
-
userWithId as updateUserSchema
|
|
1288
|
-
} from 'schemas'
|
|
1289
|
-
import { storeUser, updateUser, deleteUser, deleteAllUsers } from './mutations'
|
|
1290
|
-
import { errorHandling, GE } from '../utils'
|
|
1291
|
-
|
|
1292
|
-
const Mutation = {
|
|
1293
|
-
storeUser: async (
|
|
1294
|
-
parent: unknown,
|
|
1295
|
-
{ user }: { user: User },
|
|
1296
|
-
context: Context
|
|
1297
|
-
): Promise<UserDTO> => {
|
|
1298
|
-
const { log } = context
|
|
1299
|
-
const validate = ajv.compile(storeUserSchema)
|
|
1300
|
-
|
|
1301
|
-
try {
|
|
1302
|
-
const ok = validate(user)
|
|
1303
|
-
|
|
1304
|
-
if (!ok)
|
|
1305
|
-
throw new ApolloError(
|
|
1306
|
-
\`\${(validate.errors as DefinedError[])[0].instancePath.replace(
|
|
1307
|
-
'/',
|
|
1308
|
-
''
|
|
1309
|
-
)} \${(validate.errors as DefinedError[])[0].message as string}\`,
|
|
1310
|
-
'UNPROCESSABLE_ENTITY'
|
|
1311
|
-
)
|
|
1312
|
-
|
|
1313
|
-
return await storeUser({ user }, context)
|
|
1314
|
-
} catch (e) {
|
|
1315
|
-
log.error(validate.errors)
|
|
1316
|
-
|
|
1317
|
-
return errorHandling({
|
|
1318
|
-
e,
|
|
1319
|
-
message: GE.INTERNAL_SERVER_ERROR,
|
|
1320
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
1321
|
-
log
|
|
1322
|
-
})
|
|
1323
|
-
}
|
|
1324
|
-
},
|
|
1325
|
-
updateUser: async (
|
|
1326
|
-
parent: unknown,
|
|
1327
|
-
{ user }: { user: UserWithId },
|
|
1328
|
-
context: Context
|
|
1329
|
-
): Promise<UserDTO> => {
|
|
1330
|
-
const validate = ajv.compile(updateUserSchema)
|
|
1331
|
-
const { log } = context
|
|
1332
|
-
|
|
1333
|
-
try {
|
|
1334
|
-
const ok = validate(user)
|
|
1335
|
-
|
|
1336
|
-
if (!ok)
|
|
1337
|
-
throw new ApolloError(
|
|
1338
|
-
\`\${(validate.errors as DefinedError[])[0].instancePath.replace(
|
|
1339
|
-
'/',
|
|
1340
|
-
''
|
|
1341
|
-
)} \${(validate.errors as DefinedError[])[0].message as string}\`,
|
|
1342
|
-
'UNPROCESSABLE_ENTITY'
|
|
1343
|
-
)
|
|
1344
|
-
|
|
1345
|
-
return await updateUser({ user }, context)
|
|
1346
|
-
} catch (e) {
|
|
1347
|
-
log.error(validate.errors)
|
|
1348
|
-
|
|
1349
|
-
return errorHandling({
|
|
1350
|
-
e,
|
|
1351
|
-
message: GE.INTERNAL_SERVER_ERROR,
|
|
1352
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
1353
|
-
log
|
|
1354
|
-
})
|
|
1355
|
-
}
|
|
1356
|
-
},
|
|
1357
|
-
deleteUser: async (
|
|
1358
|
-
parent: unknown,
|
|
1359
|
-
{ id }: { id: ${dbIsSQL ? 'number' : 'string'} },
|
|
1360
|
-
context: Context
|
|
1361
|
-
): Promise<string> => {
|
|
1362
|
-
const validate = ajv.compile(idSchema)
|
|
1363
|
-
const { log } = context
|
|
1364
|
-
|
|
1365
|
-
try {
|
|
1366
|
-
const ok = validate({ id })
|
|
1367
|
-
|
|
1368
|
-
if (!ok)
|
|
1369
|
-
throw new ApolloError(
|
|
1370
|
-
\`\${(validate.errors as DefinedError[])[0].instancePath.replace(
|
|
1371
|
-
'/',
|
|
1372
|
-
''
|
|
1373
|
-
)} \${(validate.errors as DefinedError[])[0].message as string}\`,
|
|
1374
|
-
'UNPROCESSABLE_ENTITY'
|
|
1375
|
-
)
|
|
1376
|
-
|
|
1377
|
-
return await deleteUser({ id }, context)
|
|
1378
|
-
} catch (e) {
|
|
1379
|
-
log.error(validate.errors)
|
|
1380
|
-
|
|
1381
|
-
return errorHandling({
|
|
1382
|
-
e,
|
|
1383
|
-
message: GE.INTERNAL_SERVER_ERROR,
|
|
1384
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
1385
|
-
log
|
|
1386
|
-
})
|
|
1387
|
-
}
|
|
1388
|
-
},
|
|
1389
|
-
deleteAllUsers: async (
|
|
1390
|
-
parent: unknown,
|
|
1391
|
-
args: unknown,
|
|
1392
|
-
context: Context
|
|
1393
|
-
): Promise<string> => {
|
|
1394
|
-
const { log } = context
|
|
1395
|
-
try {
|
|
1396
|
-
return await deleteAllUsers(context)
|
|
1397
|
-
} catch (e) {
|
|
1398
|
-
return errorHandling({
|
|
1399
|
-
e,
|
|
1400
|
-
message: GE.INTERNAL_SERVER_ERROR,
|
|
1401
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
1402
|
-
log
|
|
1403
|
-
})
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
584
|
+
export { User }\n`,
|
|
585
|
+
file: `${projectName}/src/network/models/User.ts`
|
|
586
|
+
}
|
|
587
|
+
},
|
|
588
|
+
resolvers: {
|
|
589
|
+
index: {
|
|
590
|
+
content: `import { buildSchema } from 'type-graphql'
|
|
591
|
+
import { UserResolver } from './User'
|
|
1407
592
|
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
content: `import { ApolloError } from 'apollo-server-core'
|
|
1414
|
-
|
|
1415
|
-
import { get } from 'database'
|
|
1416
|
-
import { UserDTO } from 'schemas'
|
|
1417
|
-
import { EFU, GE, errorHandling } from '../utils'
|
|
1418
|
-
|
|
1419
|
-
const getUsers = async (
|
|
1420
|
-
parent: unknown,
|
|
1421
|
-
args: unknown,
|
|
1422
|
-
{ log }: Context
|
|
1423
|
-
): Promise<UserDTO[]> => {
|
|
1424
|
-
try {
|
|
1425
|
-
const users = (await get()) as UserDTO[]
|
|
1426
|
-
|
|
1427
|
-
return users
|
|
1428
|
-
} catch (e) {
|
|
1429
|
-
return errorHandling({
|
|
1430
|
-
e,
|
|
1431
|
-
message: GE.INTERNAL_SERVER_ERROR,
|
|
1432
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
1433
|
-
log
|
|
1434
|
-
})
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
593
|
+
const buildSchemas = async () => {
|
|
594
|
+
const schema = await buildSchema({
|
|
595
|
+
resolvers: [UserResolver],
|
|
596
|
+
validate: { forbidUnknownValues: false }
|
|
597
|
+
})
|
|
1437
598
|
|
|
1438
|
-
|
|
1439
|
-
{ id }: { id: ${dbIsSQL ? 'number' : 'string'} },
|
|
1440
|
-
{ log }: Context
|
|
1441
|
-
): Promise<UserDTO> => {
|
|
1442
|
-
try {
|
|
1443
|
-
const user = (await get(id${dbIsSQL ? '' : ' as string'})) as UserDTO | null
|
|
1444
|
-
|
|
1445
|
-
if (!user) throw new ApolloError(EFU.NOT_FOUND, 'NOT_FOUND')
|
|
1446
|
-
|
|
1447
|
-
return user
|
|
1448
|
-
} catch (e) {
|
|
1449
|
-
return errorHandling({
|
|
1450
|
-
e,
|
|
1451
|
-
message: GE.INTERNAL_SERVER_ERROR,
|
|
1452
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
1453
|
-
log
|
|
1454
|
-
})
|
|
1455
|
-
}
|
|
599
|
+
return schema
|
|
1456
600
|
}
|
|
1457
601
|
|
|
1458
|
-
export {
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
import { ApolloError } from 'apollo-server-core'
|
|
1465
|
-
|
|
1466
|
-
import { ajv, idSchema, UserDTO } from 'schemas'
|
|
1467
|
-
import { getUser, getUsers } from './queries'
|
|
1468
|
-
import { errorHandling, GE } from '../utils'
|
|
1469
|
-
|
|
1470
|
-
const Query = {
|
|
1471
|
-
getUser: async (
|
|
1472
|
-
parent: unknown,
|
|
1473
|
-
{ id }: { id: ${dbIsSQL ? 'number' : 'string'} },
|
|
1474
|
-
context: Context
|
|
1475
|
-
): Promise<UserDTO> => {
|
|
1476
|
-
const { log } = context
|
|
1477
|
-
const validate = ajv.compile(idSchema)
|
|
1478
|
-
|
|
1479
|
-
try {
|
|
1480
|
-
const ok = validate({ id })
|
|
602
|
+
export { buildSchemas }\n`,
|
|
603
|
+
file: `${projectName}/src/network/resolvers/index.ts`
|
|
604
|
+
},
|
|
605
|
+
User: {
|
|
606
|
+
content: `import 'reflect-metadata'
|
|
607
|
+
import { Arg, Field, InputType, Mutation, Query, Resolver } from 'type-graphql'
|
|
1481
608
|
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
\`id \${(validate.errors as DefinedError[])[0].message as string}\`,
|
|
1485
|
-
'UNPROCESSABLE_ENTITY'
|
|
1486
|
-
)
|
|
609
|
+
import { User } from 'network/models'
|
|
610
|
+
import { UserService } from 'services'
|
|
1487
611
|
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
612
|
+
@InputType()
|
|
613
|
+
class UserInput {
|
|
614
|
+
@Field()
|
|
615
|
+
name!: string
|
|
1491
616
|
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
message: GE.INTERNAL_SERVER_ERROR,
|
|
1495
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
1496
|
-
log
|
|
1497
|
-
})
|
|
1498
|
-
}
|
|
1499
|
-
},
|
|
1500
|
-
getUsers
|
|
617
|
+
@Field()
|
|
618
|
+
lastName!: string
|
|
1501
619
|
}
|
|
1502
620
|
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
},
|
|
1507
|
-
typeDefs: {
|
|
1508
|
-
content: `import { gql } from 'apollo-server-core'
|
|
1509
|
-
|
|
1510
|
-
const User = gql\`
|
|
1511
|
-
type User {
|
|
1512
|
-
id: ${dbIsSQL ? 'Int' : 'ID'}!
|
|
1513
|
-
name: String!
|
|
1514
|
-
lastName: String!
|
|
1515
|
-
createdAt: String!
|
|
1516
|
-
updatedAt: String!
|
|
1517
|
-
}
|
|
621
|
+
@Resolver(User)
|
|
622
|
+
class UserResolver {
|
|
623
|
+
readonly #userService = new UserService()
|
|
1518
624
|
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
625
|
+
@Query(() => User)
|
|
626
|
+
async getById(@Arg('id') id: ${dbIsSQL ? 'number' : 'string'}) {
|
|
627
|
+
return this.#userService.getById(id)
|
|
1522
628
|
}
|
|
1523
629
|
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
630
|
+
@Mutation(() => User)
|
|
631
|
+
async store(@Arg('user') user: UserInput) {
|
|
632
|
+
return this.#userService.store(user)
|
|
1527
633
|
}
|
|
1528
634
|
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
635
|
+
@Mutation(() => User)
|
|
636
|
+
async update(@Arg('id') id: ${
|
|
637
|
+
dbIsSQL ? 'number' : 'string'
|
|
638
|
+
}, @Arg('user') user: UserInput) {
|
|
639
|
+
return this.#userService.update(id, user)
|
|
1533
640
|
}
|
|
1534
641
|
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
updateUser(user: UpdateUserInput!): User!
|
|
1539
|
-
deleteUser(id: ${dbIsSQL ? 'Int' : 'ID'}!): String
|
|
642
|
+
@Mutation(() => String)
|
|
643
|
+
async deleteById(@Arg('id') id: ${dbIsSQL ? 'number' : 'string'}) {
|
|
644
|
+
return this.#userService.deleteById(id)
|
|
1540
645
|
}
|
|
1541
|
-
\`
|
|
1542
|
-
|
|
1543
|
-
export { User }
|
|
1544
|
-
`,
|
|
1545
|
-
file: `${projectName}/src/graphQL/models/User/typeDefs.ts`
|
|
1546
|
-
}
|
|
1547
|
-
},
|
|
1548
|
-
utils: {
|
|
1549
|
-
messages: {
|
|
1550
|
-
index: {
|
|
1551
|
-
content: `enum GenericErrors {
|
|
1552
|
-
INTERNAL_SERVER_ERROR = 'Something went wrong'
|
|
1553
|
-
}
|
|
1554
|
-
|
|
1555
|
-
export { GenericErrors as GE }
|
|
1556
|
-
export * from './user'
|
|
1557
|
-
`,
|
|
1558
|
-
file: `${projectName}/src/graphQL/models/utils/messages/index.ts`
|
|
1559
|
-
},
|
|
1560
|
-
user: {
|
|
1561
|
-
content: `enum ErrorForUser {
|
|
1562
|
-
NOT_FOUND = 'The requested user does not exists',
|
|
1563
|
-
NOTHING_TO_DELETE = 'There is no user to be deleted'
|
|
1564
|
-
}
|
|
1565
|
-
|
|
1566
|
-
enum MessageForUser {
|
|
1567
|
-
ALL_USERS_DELETED = 'All the users were deleted successfully',
|
|
1568
|
-
USER_DELETED = 'The requested user was successfully deleted'
|
|
1569
|
-
}
|
|
1570
|
-
|
|
1571
|
-
export { ErrorForUser as EFU, MessageForUser as MFU }
|
|
1572
|
-
`,
|
|
1573
|
-
file: `${projectName}/src/graphQL/models/utils/messages/user.ts`
|
|
1574
|
-
}
|
|
1575
|
-
},
|
|
1576
|
-
index: {
|
|
1577
|
-
content: `import { ApolloError } from 'apollo-server-core'
|
|
1578
|
-
import { FastifyLoggerInstance } from 'fastify'
|
|
1579
|
-
|
|
1580
|
-
const errorHandling = ({
|
|
1581
|
-
e,
|
|
1582
|
-
message,
|
|
1583
|
-
code,
|
|
1584
|
-
log
|
|
1585
|
-
}: {
|
|
1586
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1587
|
-
e: any
|
|
1588
|
-
message: string
|
|
1589
|
-
code: string
|
|
1590
|
-
log: FastifyLoggerInstance
|
|
1591
|
-
}): never => {
|
|
1592
|
-
log.error(e)
|
|
1593
|
-
|
|
1594
|
-
if (e instanceof ApolloError) throw e
|
|
1595
|
-
|
|
1596
|
-
throw new ApolloError(message ?? e.message, code)
|
|
1597
646
|
}
|
|
1598
647
|
|
|
1599
|
-
export {
|
|
1600
|
-
|
|
1601
|
-
`,
|
|
1602
|
-
file: `${projectName}/src/graphQL/models/utils/index.ts`
|
|
1603
|
-
}
|
|
1604
|
-
},
|
|
1605
|
-
index: {
|
|
1606
|
-
content: `import { mergeSchemas } from '@graphql-tools/schema'
|
|
1607
|
-
|
|
1608
|
-
import { User } from './User'
|
|
1609
|
-
|
|
1610
|
-
const mergedSchema = mergeSchemas({
|
|
1611
|
-
schemas: [User]
|
|
1612
|
-
})
|
|
1613
|
-
|
|
1614
|
-
export { mergedSchema }
|
|
1615
|
-
`,
|
|
1616
|
-
file: `${projectName}/src/graphQL/models/index.ts`
|
|
1617
|
-
}
|
|
648
|
+
export { UserResolver }\n`,
|
|
649
|
+
file: `${projectName}/src/network/resolvers/User.ts`
|
|
1618
650
|
}
|
|
1619
651
|
}
|
|
1620
652
|
})
|
|
@@ -1626,53 +658,15 @@ export { mergedSchema }
|
|
|
1626
658
|
writeFile(network.server.file, network.server.content),
|
|
1627
659
|
writeFile(network.routes.docs.file, network.routes.docs.content),
|
|
1628
660
|
writeFile(network.routes.home.file, network.routes.home.content),
|
|
1629
|
-
writeFile(network.routes.index.file, network.routes.index.content)
|
|
1630
|
-
writeFile(network.utils.index.file, network.utils.index.content)
|
|
661
|
+
writeFile(network.routes.index.file, network.routes.index.content)
|
|
1631
662
|
]
|
|
1632
663
|
|
|
1633
664
|
if (graphQL)
|
|
1634
665
|
processes.concat([
|
|
1635
|
-
writeFile(network.
|
|
1636
|
-
writeFile(
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
),
|
|
1640
|
-
writeFile(
|
|
1641
|
-
network.graphQL?.models.User.mutations.file,
|
|
1642
|
-
network.graphQL?.models.User.mutations.content
|
|
1643
|
-
),
|
|
1644
|
-
writeFile(
|
|
1645
|
-
network.graphQL?.models.User.mutationsResolver.file,
|
|
1646
|
-
network.graphQL?.models.User.mutationsResolver.content
|
|
1647
|
-
),
|
|
1648
|
-
writeFile(
|
|
1649
|
-
network.graphQL?.models.User.queries.file,
|
|
1650
|
-
network.graphQL?.models.User.queries.content
|
|
1651
|
-
),
|
|
1652
|
-
writeFile(
|
|
1653
|
-
network.graphQL?.models.User.queriesResolver.file,
|
|
1654
|
-
network.graphQL?.models.User.queriesResolver.content
|
|
1655
|
-
),
|
|
1656
|
-
writeFile(
|
|
1657
|
-
network.graphQL?.models.User.typeDefs.file,
|
|
1658
|
-
network.graphQL?.models.User.typeDefs.content
|
|
1659
|
-
),
|
|
1660
|
-
writeFile(
|
|
1661
|
-
network.graphQL?.models.utils.messages.index.file,
|
|
1662
|
-
network.graphQL?.models.utils.messages.index.content
|
|
1663
|
-
),
|
|
1664
|
-
writeFile(
|
|
1665
|
-
network.graphQL?.models.utils.messages.user.file,
|
|
1666
|
-
network.graphQL?.models.utils.messages.user.content
|
|
1667
|
-
),
|
|
1668
|
-
writeFile(
|
|
1669
|
-
network.graphQL?.models.utils.index.file,
|
|
1670
|
-
network.graphQL?.models.utils.index.content
|
|
1671
|
-
),
|
|
1672
|
-
writeFile(
|
|
1673
|
-
network.graphQL?.models.index.file,
|
|
1674
|
-
network.graphQL?.models.index.content
|
|
1675
|
-
)
|
|
666
|
+
writeFile(network.models.index.file, network.models.index.content),
|
|
667
|
+
writeFile(network.models.User.file, network.models.User.content),
|
|
668
|
+
writeFile(network.resolvers.index.file, network.resolvers.index.content),
|
|
669
|
+
writeFile(network.resolvers.User.file, network.resolvers.User.content)
|
|
1676
670
|
])
|
|
1677
671
|
else
|
|
1678
672
|
processes.push(
|
|
@@ -1685,349 +679,26 @@ export { mergedSchema }
|
|
|
1685
679
|
/**
|
|
1686
680
|
* @param {Object} args
|
|
1687
681
|
* @param {String} args.projectName
|
|
1688
|
-
* @param {
|
|
1689
|
-
* @param {
|
|
1690
|
-
*/
|
|
1691
|
-
const schemas = async ({ projectName, dbIsSQL, graphQL }) => {
|
|
1692
|
-
const createFoldersCommand = `mkdir ${projectName}/src/schemas`
|
|
1693
|
-
|
|
1694
|
-
if (platform() === 'win32')
|
|
1695
|
-
await exec(createFoldersCommand.replaceAll('/', '\\'))
|
|
1696
|
-
else await exec(createFoldersCommand)
|
|
1697
|
-
|
|
1698
|
-
const schemas = {
|
|
1699
|
-
index: {
|
|
1700
|
-
content: graphQL
|
|
1701
|
-
? `import { Static, Type } from '@sinclair/typebox'
|
|
1702
|
-
import Ajv from 'ajv/dist/2019.js'
|
|
1703
|
-
import addFormats from 'ajv-formats'
|
|
1704
|
-
|
|
1705
|
-
const id = ${
|
|
1706
|
-
dbIsSQL
|
|
1707
|
-
? `Type.Number()`
|
|
1708
|
-
: `Type.String({ pattern: '^[a-zA-Z0-9]{24,}$' })`
|
|
1709
|
-
}
|
|
1710
|
-
type ID = Static<typeof id>
|
|
1711
|
-
|
|
1712
|
-
const idSchema = Type.Object({ id })
|
|
1713
|
-
|
|
1714
|
-
type IDSchema = Static<typeof idSchema>
|
|
1715
|
-
|
|
1716
|
-
const ajv = addFormats(new Ajv(), ['email'])
|
|
1717
|
-
.addKeyword('kind')
|
|
1718
|
-
.addKeyword('modifier')
|
|
1719
|
-
|
|
1720
|
-
export { id, ID, idSchema, IDSchema, ajv }
|
|
1721
|
-
export * from './user'
|
|
1722
|
-
`
|
|
1723
|
-
: `import { Static, Type } from '@sinclair/typebox'
|
|
1724
|
-
|
|
1725
|
-
const id = ${
|
|
1726
|
-
dbIsSQL
|
|
1727
|
-
? `Type.Number()`
|
|
1728
|
-
: `Type.String({ pattern: '^[a-zA-Z0-9]{24,}$' })`
|
|
1729
|
-
}
|
|
1730
|
-
|
|
1731
|
-
type Id = Static<typeof id>
|
|
1732
|
-
|
|
1733
|
-
const idSchema = Type.Object({ id })
|
|
1734
|
-
|
|
1735
|
-
type IdSchema = Static<typeof idSchema>
|
|
1736
|
-
|
|
1737
|
-
export { id, Id, idSchema, IdSchema }
|
|
1738
|
-
export * from './user'
|
|
1739
|
-
`,
|
|
1740
|
-
file: `${projectName}/src/schemas/index.ts`
|
|
1741
|
-
},
|
|
1742
|
-
user: {
|
|
1743
|
-
content: `import { Static, Type } from '@sinclair/typebox'
|
|
1744
|
-
|
|
1745
|
-
import { id } from '.'
|
|
1746
|
-
|
|
1747
|
-
const user = Type.Object({
|
|
1748
|
-
lastName: Type.String(),
|
|
1749
|
-
name: Type.String()
|
|
1750
|
-
})
|
|
1751
|
-
|
|
1752
|
-
type User = Static<typeof user>
|
|
1753
|
-
|
|
1754
|
-
const userWithId = Type.Intersect([user, Type.Object({ id })])
|
|
1755
|
-
|
|
1756
|
-
type UserWithId = Static<typeof userWithId>
|
|
1757
|
-
|
|
1758
|
-
const userDto = Type.Object({
|
|
1759
|
-
id: Type.Optional(id),
|
|
1760
|
-
lastName: Type.String(),
|
|
1761
|
-
name: Type.String(),
|
|
1762
|
-
createdAt: Type.Optional(Type.String()),
|
|
1763
|
-
updatedAt: Type.Optional(Type.String())
|
|
1764
|
-
})
|
|
1765
|
-
|
|
1766
|
-
type UserDTO = Static<typeof userDto>
|
|
1767
|
-
|
|
1768
|
-
const storeUserDto = Type.Object({
|
|
1769
|
-
args: user
|
|
1770
|
-
})
|
|
1771
|
-
|
|
1772
|
-
type StoreUserDTO = Static<typeof storeUserDto>
|
|
1773
|
-
|
|
1774
|
-
export {
|
|
1775
|
-
userDto,
|
|
1776
|
-
UserDTO,
|
|
1777
|
-
userWithId,
|
|
1778
|
-
UserWithId,
|
|
1779
|
-
user,
|
|
1780
|
-
User,
|
|
1781
|
-
storeUserDto,
|
|
1782
|
-
StoreUserDTO
|
|
1783
|
-
}
|
|
1784
|
-
`,
|
|
1785
|
-
file: `${projectName}/src/schemas/user.ts`
|
|
1786
|
-
}
|
|
1787
|
-
}
|
|
1788
|
-
|
|
1789
|
-
await Promise.all([
|
|
1790
|
-
writeFile(schemas.index.file, schemas.index.content),
|
|
1791
|
-
writeFile(schemas.user.file, schemas.user.content)
|
|
1792
|
-
])
|
|
1793
|
-
}
|
|
1794
|
-
|
|
1795
|
-
/**
|
|
1796
|
-
* @param {Object} args
|
|
1797
|
-
* @param {String} args.projectName
|
|
1798
|
-
* @param {Boolean} args.dbIsSQL
|
|
1799
|
-
*/
|
|
1800
|
-
const services = async ({ projectName, dbIsSQL }) => {
|
|
1801
|
-
const createFoldersCommand = `mkdir ${projectName}/src/services \
|
|
1802
|
-
${projectName}/src/services/utils \
|
|
1803
|
-
${projectName}/src/services/utils/messages`
|
|
1804
|
-
|
|
1805
|
-
if (platform() === 'win32')
|
|
1806
|
-
await exec(createFoldersCommand.replaceAll('/', '\\'))
|
|
1807
|
-
else await exec(createFoldersCommand)
|
|
1808
|
-
|
|
1809
|
-
const services = {
|
|
1810
|
-
index: {
|
|
1811
|
-
content: "export * from './user'\n",
|
|
1812
|
-
file: `${projectName}/src/services/index.ts`
|
|
1813
|
-
},
|
|
1814
|
-
user: {
|
|
1815
|
-
content: `import httpErrors from 'http-errors'
|
|
1816
|
-
|
|
1817
|
-
import { store, remove, get, update } from 'database'
|
|
1818
|
-
import { User, UserDTO, UserWithId } from 'schemas'
|
|
1819
|
-
import { EFU, MFU, GE, errorHandling } from './utils'
|
|
1820
|
-
|
|
1821
|
-
type Process = {
|
|
1822
|
-
type: 'store' | 'getAll' | 'deleteAll' | 'getOne' | 'update' | 'delete'
|
|
1823
|
-
}
|
|
1824
|
-
|
|
1825
|
-
type Arguments = {
|
|
1826
|
-
id?: ${dbIsSQL ? 'number' : 'string'}
|
|
1827
|
-
user?: User
|
|
1828
|
-
userWithId?: UserWithId
|
|
1829
|
-
}
|
|
1830
|
-
|
|
1831
|
-
class UserService {
|
|
1832
|
-
#args: Arguments
|
|
1833
|
-
|
|
1834
|
-
constructor(args: Arguments = {}) {
|
|
1835
|
-
this.#args = args
|
|
1836
|
-
}
|
|
1837
|
-
|
|
1838
|
-
public process({ type }: Process): Promise<string | UserDTO | UserDTO[]> {
|
|
1839
|
-
switch (type) {
|
|
1840
|
-
case 'store':
|
|
1841
|
-
return this.#store()
|
|
1842
|
-
case 'getAll':
|
|
1843
|
-
return this.#getAll()
|
|
1844
|
-
case 'deleteAll':
|
|
1845
|
-
return this.#deleteAll()
|
|
1846
|
-
case 'getOne':
|
|
1847
|
-
return this.#getOne()
|
|
1848
|
-
case 'update':
|
|
1849
|
-
return this.#update()
|
|
1850
|
-
case 'delete':
|
|
1851
|
-
return this.#delete()
|
|
1852
|
-
default:
|
|
1853
|
-
throw new httpErrors.InternalServerError(GE.INTERNAL_SERVER_ERROR)
|
|
1854
|
-
}
|
|
1855
|
-
}
|
|
1856
|
-
|
|
1857
|
-
async #store(): Promise<UserDTO> {
|
|
1858
|
-
try {
|
|
1859
|
-
if (!this.#args.user)
|
|
1860
|
-
throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
|
|
1861
|
-
|
|
1862
|
-
const result = await store(this.#args.user)
|
|
1863
|
-
|
|
1864
|
-
return result
|
|
1865
|
-
} catch (e) {
|
|
1866
|
-
return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
|
|
1867
|
-
}
|
|
1868
|
-
}
|
|
1869
|
-
|
|
1870
|
-
async #getAll(): Promise<UserDTO[]> {
|
|
1871
|
-
try {
|
|
1872
|
-
const users = (await get()) as UserDTO[]
|
|
1873
|
-
|
|
1874
|
-
return users
|
|
1875
|
-
} catch (e) {
|
|
1876
|
-
return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
|
|
1880
|
-
async #deleteAll(): Promise<string> {
|
|
1881
|
-
try {
|
|
1882
|
-
const usersDeleted = (await remove()) as number
|
|
1883
|
-
|
|
1884
|
-
${
|
|
1885
|
-
dbIsSQL
|
|
1886
|
-
? 'if (usersDeleted !== 0) return MFU.ALL_USERS_DELETED'
|
|
1887
|
-
: `if (usersDeleted >= 1) return MFU.ALL_USERS_DELETED
|
|
1888
|
-
|
|
1889
|
-
if (usersDeleted === 0)
|
|
1890
|
-
throw new httpErrors.Conflict(EFU.NOTHING_TO_DELETE)`
|
|
1891
|
-
}
|
|
1892
|
-
|
|
1893
|
-
throw new httpErrors.InternalServerError(GE.INTERNAL_SERVER_ERROR)
|
|
1894
|
-
} catch (e) {
|
|
1895
|
-
return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
|
|
1896
|
-
}
|
|
1897
|
-
}
|
|
1898
|
-
|
|
1899
|
-
async #getOne(): Promise<UserDTO> {
|
|
1900
|
-
try {
|
|
1901
|
-
if (!this.#args.id)
|
|
1902
|
-
throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
|
|
1903
|
-
|
|
1904
|
-
const { id } = this.#args
|
|
1905
|
-
const user = (await get(id)) as UserDTO | null
|
|
1906
|
-
|
|
1907
|
-
if (!user) throw new httpErrors.NotFound(EFU.NOT_FOUND)
|
|
1908
|
-
|
|
1909
|
-
return user
|
|
1910
|
-
} catch (e) {
|
|
1911
|
-
return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
|
|
1912
|
-
}
|
|
1913
|
-
}
|
|
1914
|
-
|
|
1915
|
-
async #update(): Promise<UserDTO> {
|
|
1916
|
-
try {
|
|
1917
|
-
if (!this.#args.userWithId || !this.#args.userWithId.id)
|
|
1918
|
-
throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
|
|
1919
|
-
|
|
1920
|
-
const updatedUser = await update(this.#args.userWithId)
|
|
1921
|
-
|
|
1922
|
-
if (!updatedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
|
|
1923
|
-
|
|
1924
|
-
return updatedUser
|
|
1925
|
-
} catch (e) {
|
|
1926
|
-
return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
|
|
1927
|
-
}
|
|
1928
|
-
}
|
|
1929
|
-
|
|
1930
|
-
async #delete(): Promise<string> {
|
|
1931
|
-
try {
|
|
1932
|
-
if (!this.#args.id)
|
|
1933
|
-
throw new httpErrors.UnprocessableEntity(GE.INTERNAL_SERVER_ERROR)
|
|
1934
|
-
|
|
1935
|
-
const { id } = this.#args
|
|
1936
|
-
const deletedUser = await remove(id)
|
|
1937
|
-
|
|
1938
|
-
if (!deletedUser) throw new httpErrors.NotFound(EFU.NOT_FOUND)
|
|
1939
|
-
|
|
1940
|
-
return MFU.USER_DELETED
|
|
1941
|
-
} catch (e) {
|
|
1942
|
-
return errorHandling(e, GE.INTERNAL_SERVER_ERROR)
|
|
1943
|
-
}
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1946
|
-
|
|
1947
|
-
export { UserService }
|
|
1948
|
-
`,
|
|
1949
|
-
file: `${projectName}/src/services/user.ts`
|
|
1950
|
-
},
|
|
1951
|
-
utils: {
|
|
1952
|
-
index: {
|
|
1953
|
-
content: `import httpErrors from 'http-errors'
|
|
1954
|
-
|
|
1955
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1956
|
-
const errorHandling = (e: any, message?: string): never => {
|
|
1957
|
-
console.error(e)
|
|
1958
|
-
|
|
1959
|
-
if (e instanceof httpErrors.HttpError) throw e
|
|
1960
|
-
|
|
1961
|
-
throw new httpErrors.InternalServerError(message ?? e.message)
|
|
1962
|
-
}
|
|
1963
|
-
|
|
1964
|
-
export { errorHandling }
|
|
1965
|
-
export * from './messages'
|
|
1966
|
-
`,
|
|
1967
|
-
file: `${projectName}/src/services/utils/index.ts`
|
|
1968
|
-
}
|
|
1969
|
-
},
|
|
1970
|
-
'utils/messages': {
|
|
1971
|
-
index: {
|
|
1972
|
-
content: `enum GenericErrors {
|
|
1973
|
-
INTERNAL_SERVER_ERROR = 'Something went wrong'
|
|
1974
|
-
}
|
|
1975
|
-
|
|
1976
|
-
export { GenericErrors as GE }
|
|
1977
|
-
export * from './user'
|
|
1978
|
-
`,
|
|
1979
|
-
file: `${projectName}/src/services/utils/messages/index.ts`
|
|
1980
|
-
},
|
|
1981
|
-
user: {
|
|
1982
|
-
content: `enum ErrorForUser {
|
|
1983
|
-
NOT_FOUND = 'The requested user does not exists',
|
|
1984
|
-
NOTHING_TO_DELETE = 'There is no user to be deleted'
|
|
1985
|
-
}
|
|
1986
|
-
|
|
1987
|
-
enum MessageForUser {
|
|
1988
|
-
ALL_USERS_DELETED = 'All the users were deleted successfully',
|
|
1989
|
-
USER_DELETED = 'The requested user was successfully deleted'
|
|
1990
|
-
}
|
|
1991
|
-
|
|
1992
|
-
export { ErrorForUser as EFU, MessageForUser as MFU }
|
|
1993
|
-
`,
|
|
1994
|
-
file: `${projectName}/src/services/utils/messages/user.ts`
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
1997
|
-
}
|
|
1998
|
-
|
|
1999
|
-
await Promise.all([
|
|
2000
|
-
writeFile(services.index.file, services.index.content),
|
|
2001
|
-
writeFile(services.user.file, services.user.content),
|
|
2002
|
-
writeFile(services.utils.index.file, services.utils.index.content),
|
|
2003
|
-
writeFile(
|
|
2004
|
-
services['utils/messages'].index.file,
|
|
2005
|
-
services['utils/messages'].index.content
|
|
2006
|
-
),
|
|
2007
|
-
writeFile(
|
|
2008
|
-
services['utils/messages'].user.file,
|
|
2009
|
-
services['utils/messages'].user.content
|
|
2010
|
-
)
|
|
2011
|
-
])
|
|
2012
|
-
}
|
|
2013
|
-
|
|
2014
|
-
/**
|
|
2015
|
-
* @param {Object} args
|
|
2016
|
-
* @param {String} args.projectName
|
|
682
|
+
* @param {String} args.email
|
|
683
|
+
* @param {String} args.projectVersion
|
|
2017
684
|
* @param {Boolean} args.graphQL
|
|
2018
685
|
* @param {import('../../../../').Config['database']} args.database
|
|
2019
686
|
*/
|
|
2020
|
-
const main = async ({
|
|
687
|
+
const main = async ({
|
|
688
|
+
projectName,
|
|
689
|
+
email,
|
|
690
|
+
projectVersion,
|
|
691
|
+
graphQL,
|
|
692
|
+
database
|
|
693
|
+
}) => {
|
|
2021
694
|
const dbIsSQL = database !== 'mongo'
|
|
2022
695
|
|
|
696
|
+
await utils({ fastify: true, projectName, email, projectVersion })
|
|
2023
697
|
await types({ projectName, graphQL, dbIsSQL })
|
|
2024
698
|
await network({ projectName, graphQL, dbIsSQL })
|
|
2025
699
|
await schemas({ projectName, graphQL, dbIsSQL })
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
if (dbIsSQL) await sql({ projectName, db: database })
|
|
2030
|
-
else await mongo({ projectName })
|
|
700
|
+
await services({ projectName, dbIsSQL })
|
|
701
|
+
await db({ projectName, database, fastify: true })
|
|
2031
702
|
}
|
|
2032
703
|
|
|
2033
704
|
module.exports = main
|