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