@anthonylzq/simba.js 4.3.0 → 5.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 +197 -20
- package/lib/index.js +17 -11
- package/lib/src/functions/api/database.js +177 -0
- package/lib/src/functions/api/index.js +230 -0
- package/lib/src/functions/api/network.js +2536 -0
- package/lib/src/functions/api/schemas.js +122 -0
- package/lib/src/functions/api/services.js +220 -0
- package/lib/src/functions/api/types.js +110 -0
- package/lib/src/functions/api/utils.js +466 -0
- package/lib/src/index.js +21 -7
- package/lib/src/utils/writeFile.js +2 -2
- package/package.json +19 -4
- package/lib/src/functions/api.js +0 -1983
package/README.md
CHANGED
|
@@ -34,6 +34,7 @@ By doing this your prompt will ask you the following questions:
|
|
|
34
34
|
- `Project version (0.1.0):` the initial version of the project, `0.1.0` as default.
|
|
35
35
|
- `Select your license [1...7]:`, the license you have chosen for the project.
|
|
36
36
|
- `License year (current year):`, the year where your license starts, current year as default.
|
|
37
|
+
- `Will this project use GraphQL? [y/n]:`, yes or no question, only **y** or **n** is accepted. This is not case sensitive.
|
|
37
38
|
- `Will this project be deployed with Heroku? [y/n]:`, yes or no question, only **y** or **n** is accepted. This is not case sensitive.
|
|
38
39
|
|
|
39
40
|
The second option you have is by passing flags in one single command. If you need help, please run:
|
|
@@ -69,6 +70,8 @@ Options:
|
|
|
69
70
|
[boolean] [default: false]
|
|
70
71
|
-F, --fastify Whether or not you want to use Fastify for your
|
|
71
72
|
project [boolean] [default: false]
|
|
73
|
+
-g, --graphql Whether or not you want to use GraphQL for your
|
|
74
|
+
project [boolean] [default: false]
|
|
72
75
|
-h, --help Show help [boolean]
|
|
73
76
|
|
|
74
77
|
Examples:
|
|
@@ -94,18 +97,28 @@ As default, `yarn` is selected as package manager, but if you don't want to use
|
|
|
94
97
|
simba -N myProject -D 'This is a test' -l mit -a myName -e myEmail@email.com -H -n
|
|
95
98
|
```
|
|
96
99
|
|
|
97
|
-
|
|
100
|
+
What if I want to use Fastify instead Express? Well, you only have to pass the `-F` flag:
|
|
98
101
|
|
|
99
102
|
```bash
|
|
100
103
|
simba -N myProject -D 'This is a test' -l mit -a myName -e myEmail@email.com -H -F
|
|
101
104
|
```
|
|
102
105
|
|
|
106
|
+
And how can I use GraphQL? Well, you only have to pass the `-g` flag:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
simba -N myProject -D 'This is a test' -l mit -a myName -e myEmail@email.com -H -F -g
|
|
110
|
+
```
|
|
111
|
+
|
|
103
112
|
Finally, you may not want to use a license or one of the available licenses, don't worry, just don't pass the flag `-l` neither `--license` as follows:
|
|
104
113
|
|
|
105
114
|
```bash
|
|
106
115
|
simba -N myProject -D 'This is a test' -a myName -e myEmail@email.com -H
|
|
107
116
|
```
|
|
108
117
|
|
|
118
|
+
#### Why didn't you use [`TypeGraphQL`](https://typegraphql.com/)?
|
|
119
|
+
|
|
120
|
+
[They don't support GraphQL v16.x.x](https://github.com/MichalLytek/type-graphql/issues/1100), until then.
|
|
121
|
+
|
|
109
122
|
## <a name="project-structure"></a>Project structure
|
|
110
123
|
|
|
111
124
|
Regardless of the option chosen, a new folder will be generated with the name of the project, it will contain the following structure, depending if you have chosen Express or Fastify:
|
|
@@ -119,8 +132,6 @@ Regardless of the option chosen, a new folder will be generated with the name of
|
|
|
119
132
|
┃ ┣ 📂custom
|
|
120
133
|
┃ ┃ ┣ 📜request.d.ts
|
|
121
134
|
┃ ┃ ┗ 📜response.d.ts
|
|
122
|
-
┃ ┣ 📂dto
|
|
123
|
-
┃ ┃ ┗ 📜user.d.ts
|
|
124
135
|
┃ ┣ 📂models
|
|
125
136
|
┃ ┃ ┗ 📜user.d.ts
|
|
126
137
|
┃ ┗ 📜index.d.ts
|
|
@@ -137,7 +148,7 @@ Regardless of the option chosen, a new folder will be generated with the name of
|
|
|
137
148
|
┣ 📂network
|
|
138
149
|
┃ ┣ 📂routes
|
|
139
150
|
┃ ┃ ┣ 📂utils
|
|
140
|
-
┃ ┃ ┃ ┗ 📜
|
|
151
|
+
┃ ┃ ┃ ┗ 📜index.ts
|
|
141
152
|
┃ ┃ ┣ 📜home.ts
|
|
142
153
|
┃ ┃ ┣ 📜index.ts
|
|
143
154
|
┃ ┃ ┗ 📜user.ts
|
|
@@ -179,6 +190,81 @@ Regardless of the option chosen, a new folder will be generated with the name of
|
|
|
179
190
|
📜yarn.lock (or package-lock.json)
|
|
180
191
|
```
|
|
181
192
|
|
|
193
|
+
### Express-GraphQL case
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
📂node_modules
|
|
197
|
+
📂src
|
|
198
|
+
┣ 📂@types
|
|
199
|
+
┃ ┣ 📂custom
|
|
200
|
+
┃ ┃ ┣ 📜request.d.ts
|
|
201
|
+
┃ ┃ ┗ 📜response.d.ts
|
|
202
|
+
┃ ┣ 📂graphQL
|
|
203
|
+
┃ ┃ ┗ 📜context.d.ts
|
|
204
|
+
┃ ┣ 📂models
|
|
205
|
+
┃ ┃ ┗ 📜user.d.ts
|
|
206
|
+
┃ ┗ 📜index.d.ts
|
|
207
|
+
┣ 📂database
|
|
208
|
+
┃ ┣ 📂mongo
|
|
209
|
+
┃ ┃ ┣ 📂models
|
|
210
|
+
┃ ┃ ┃ ┣ 📜index.ts
|
|
211
|
+
┃ ┃ ┃ ┗ 📜user.ts
|
|
212
|
+
┃ ┃ ┣ 📂queries
|
|
213
|
+
┃ ┃ ┃ ┣ 📜index.ts
|
|
214
|
+
┃ ┃ ┃ ┗ 📜user.ts
|
|
215
|
+
┃ ┃ ┗ 📜index.ts
|
|
216
|
+
┃ ┗ 📜index.ts
|
|
217
|
+
┣ 📂graphQL
|
|
218
|
+
┃ ┣ 📂models
|
|
219
|
+
┃ ┃ ┣ 📂User
|
|
220
|
+
┃ ┃ ┃ ┣ 📜index.ts
|
|
221
|
+
┃ ┃ ┃ ┣ 📜mutations.ts
|
|
222
|
+
┃ ┃ ┃ ┣ 📜mutationsResolver.ts
|
|
223
|
+
┃ ┃ ┃ ┣ 📜queries.ts
|
|
224
|
+
┃ ┃ ┃ ┣ 📜queriesResolver.ts
|
|
225
|
+
┃ ┃ ┃ ┣ 📜schemas.ts
|
|
226
|
+
┃ ┃ ┃ ┗ 📜typeDefs.ts
|
|
227
|
+
┃ ┃ ┣ 📂utils
|
|
228
|
+
┃ ┃ ┃ ┣ 📂messages
|
|
229
|
+
┃ ┃ ┃ ┃ ┣ 📜index.ts
|
|
230
|
+
┃ ┃ ┃ ┃ ┗ 📜user.ts
|
|
231
|
+
┃ ┃ ┃ ┗ 📜index.ts
|
|
232
|
+
┃ ┃ ┗ 📜index.ts
|
|
233
|
+
┃ ┗ 📜index.ts
|
|
234
|
+
┣ 📂network
|
|
235
|
+
┃ ┣ 📂routes
|
|
236
|
+
┃ ┃ ┣ 📂utils
|
|
237
|
+
┃ ┃ ┃ ┗ 📜index.ts
|
|
238
|
+
┃ ┃ ┣ 📜home.ts
|
|
239
|
+
┃ ┃ ┣ 📜index.ts
|
|
240
|
+
┃ ┣ 📜index.ts
|
|
241
|
+
┃ ┣ 📜response.ts
|
|
242
|
+
┃ ┣ 📜routes.ts
|
|
243
|
+
┃ ┗ 📜server.ts
|
|
244
|
+
┣ 📂schemas
|
|
245
|
+
┃ ┣ 📜index.ts
|
|
246
|
+
┃ ┗ 📜user.ts
|
|
247
|
+
┣ 📂utils
|
|
248
|
+
┃ ┣ 📜docs.json
|
|
249
|
+
┃ ┗ 📜index.ts
|
|
250
|
+
┗ 📜index.ts
|
|
251
|
+
📜.env
|
|
252
|
+
📜.eslintignore
|
|
253
|
+
📜.eslintrc
|
|
254
|
+
📜.gitignore
|
|
255
|
+
📜CHANGELOG.md
|
|
256
|
+
📜Dockerfile
|
|
257
|
+
📜heroku.yml
|
|
258
|
+
📜LICENSE
|
|
259
|
+
📜nodemon.json
|
|
260
|
+
📜package.json
|
|
261
|
+
📜README.md
|
|
262
|
+
📜tsconfig.base.json
|
|
263
|
+
📜tsconfig.json
|
|
264
|
+
📜webpack.config.js
|
|
265
|
+
📜yarn.lock (or package-lock.json)
|
|
266
|
+
```
|
|
267
|
+
|
|
182
268
|
### Fastify case
|
|
183
269
|
|
|
184
270
|
```
|
|
@@ -241,12 +327,82 @@ Regardless of the option chosen, a new folder will be generated with the name of
|
|
|
241
327
|
📜yarn.lock (or package-lock.json)
|
|
242
328
|
```
|
|
243
329
|
|
|
330
|
+
### Fastify-GraphQL case
|
|
331
|
+
|
|
332
|
+
```
|
|
333
|
+
📂node_modules
|
|
334
|
+
📂src
|
|
335
|
+
┣ 📂@types
|
|
336
|
+
┃ ┣ 📂graphQL
|
|
337
|
+
┃ ┃ ┗ 📜context.d.ts
|
|
338
|
+
┃ ┣ 📂dto
|
|
339
|
+
┃ ┃ ┗ 📜user.d.ts
|
|
340
|
+
┃ ┣ 📂models
|
|
341
|
+
┃ ┃ ┗ 📜user.d.ts
|
|
342
|
+
┃ ┗ 📜index.d.ts
|
|
343
|
+
┣ 📂database
|
|
344
|
+
┃ ┣ 📂mongo
|
|
345
|
+
┃ ┃ ┣ 📂models
|
|
346
|
+
┃ ┃ ┃ ┣ 📜index.ts
|
|
347
|
+
┃ ┃ ┃ ┗ 📜user.ts
|
|
348
|
+
┃ ┃ ┣ 📂queries
|
|
349
|
+
┃ ┃ ┃ ┣ 📜index.ts
|
|
350
|
+
┃ ┃ ┃ ┗ 📜user.ts
|
|
351
|
+
┃ ┃ ┗ 📜index.ts
|
|
352
|
+
┃ ┗ 📜index.ts
|
|
353
|
+
┣ 📂graphQL
|
|
354
|
+
┃ ┣ 📂models
|
|
355
|
+
┃ ┃ ┣ 📂User
|
|
356
|
+
┃ ┃ ┃ ┣ 📜index.ts
|
|
357
|
+
┃ ┃ ┃ ┣ 📜mutations.ts
|
|
358
|
+
┃ ┃ ┃ ┣ 📜mutationsResolver.ts
|
|
359
|
+
┃ ┃ ┃ ┣ 📜queries.ts
|
|
360
|
+
┃ ┃ ┃ ┣ 📜queriesResolver.ts
|
|
361
|
+
┃ ┃ ┃ ┣ 📜schemas.ts
|
|
362
|
+
┃ ┃ ┃ ┗ 📜typeDefs.ts
|
|
363
|
+
┃ ┃ ┣ 📂utils
|
|
364
|
+
┃ ┃ ┃ ┣ 📂messages
|
|
365
|
+
┃ ┃ ┃ ┃ ┣ 📜index.ts
|
|
366
|
+
┃ ┃ ┃ ┃ ┗ 📜user.ts
|
|
367
|
+
┃ ┃ ┃ ┗ 📜index.ts
|
|
368
|
+
┃ ┃ ┗ 📜index.ts
|
|
369
|
+
┃ ┗ 📜index.ts
|
|
370
|
+
┣ 📂network
|
|
371
|
+
┃ ┣ 📂routes
|
|
372
|
+
┃ ┃ ┣ 📜docs.ts
|
|
373
|
+
┃ ┃ ┣ 📜home.ts
|
|
374
|
+
┃ ┃ ┣ 📜index.ts
|
|
375
|
+
┃ ┣ 📜index.ts
|
|
376
|
+
┃ ┣ 📜response.ts
|
|
377
|
+
┃ ┣ 📜routes.ts
|
|
378
|
+
┃ ┗ 📜server.ts
|
|
379
|
+
┣ 📂schemas
|
|
380
|
+
┃ ┣ 📜index.ts
|
|
381
|
+
┃ ┗ 📜user.ts
|
|
382
|
+
┗ 📜index.ts
|
|
383
|
+
📜.env
|
|
384
|
+
📜.eslintignore
|
|
385
|
+
📜.eslintrc
|
|
386
|
+
📜.gitignore
|
|
387
|
+
📜CHANGELOG.md
|
|
388
|
+
📜Dockerfile
|
|
389
|
+
📜heroku.yml
|
|
390
|
+
📜LICENSE
|
|
391
|
+
📜nodemon.json
|
|
392
|
+
📜package.json
|
|
393
|
+
📜README.md
|
|
394
|
+
📜tsconfig.base.json
|
|
395
|
+
📜tsconfig.json
|
|
396
|
+
📜webpack.config.js
|
|
397
|
+
📜yarn.lock (or package-lock.json)
|
|
398
|
+
```
|
|
399
|
+
|
|
244
400
|
If you want to check the content of the files, please check the [example](https://github.com/AnthonyLzq/simba.js/tree/master/example) folder, there you will an example for both, Express and Fastify.
|
|
245
401
|
|
|
246
402
|
### Some considerations
|
|
247
403
|
|
|
248
|
-
-
|
|
249
|
-
-
|
|
404
|
+
- You are able to run a server that has one main route, `home` (`/`), `user` (`api/user` or `api/user/:id`) and `docs` (`api/docs`), in case you are not using GraphQL.
|
|
405
|
+
- In case you are using GraphQL, there are 4 mutations (`storeUser`, `updateUser`, `deleteAllUsers` and `deleteUser`) and 2 queries available (`getUsers` and `getUser`), you can find them in the playground under the route `/api`.
|
|
250
406
|
- To connect your server with your `MongoDB` database, you need to provide your `uri` in the `.env`. By default, Simba will try to connect to a local database. The content of the `.env` file is:
|
|
251
407
|
|
|
252
408
|
```bash
|
|
@@ -288,16 +444,24 @@ If you want to check the content of the files, please check the [example](https:
|
|
|
288
444
|
|
|
289
445
|
Please check the [`changelog.md`](https://github.com/AnthonyLzq/simba.js/blob/master/CHANGELOG.md) file. Also, if you want to check what is coming, check the [road map](https://simbajs.notion.site/simbajs/783092dc7d444067b4c56a25d671f658?v=31060f3d17524ca58870e86c2960a6df).
|
|
290
446
|
|
|
291
|
-
### Version
|
|
447
|
+
### Version 5.x.x
|
|
292
448
|
|
|
293
449
|
In this major version I would be focusing on adding new possible configurations according to the road map. The major changes of this version will be described here:
|
|
294
450
|
|
|
295
|
-
-
|
|
296
|
-
-
|
|
451
|
+
- API creation logic was split to improve scalability.
|
|
452
|
+
- Added support for GraphQL in both, Express and Fastify.
|
|
297
453
|
|
|
298
454
|
## <a name="notes"></a>Notes
|
|
299
455
|
|
|
300
|
-
Here is the list of the packages that are being installed, as `
|
|
456
|
+
Here is the list of the packages that are being installed, as `dependencies`:
|
|
457
|
+
|
|
458
|
+
- [`@sinclair/typebox`](https://www.npmjs.com/package/@sinclair/typebox)
|
|
459
|
+
- [`ajv`](https://www.npmjs.com/package/ajv)
|
|
460
|
+
- [`http-errors`](https://www.npmjs.com/package/http-errors)
|
|
461
|
+
- [`mongoose`](https://mongoosejs.com/)
|
|
462
|
+
- [`pino-pretty`](https://www.npmjs.com/package/pino-pretty)
|
|
463
|
+
|
|
464
|
+
As `devDependencies`:
|
|
301
465
|
|
|
302
466
|
- [`@types/http-errors`](https://www.npmjs.com/package/@types/http-errors)
|
|
303
467
|
- [`@types/node`](https://www.npmjs.com/package/@types/node)
|
|
@@ -321,28 +485,35 @@ Here is the list of the packages that are being installed, as `devDependencies`:
|
|
|
321
485
|
- [`webpack-cli`](https://www.npmjs.com/package/webpack-cli)
|
|
322
486
|
- [`webpack-node-externals`](https://www.npmjs.com/package/webpack-node-externals)
|
|
323
487
|
|
|
324
|
-
|
|
488
|
+
### In case you are using GraphQL
|
|
325
489
|
|
|
326
|
-
|
|
490
|
+
As `dependencies`:
|
|
491
|
+
- [`@graphql-tools/schema`](https://www.npmjs.com/package/@graphql-tools/schema)
|
|
327
492
|
- [`ajv`](https://www.npmjs.com/package/ajv)
|
|
328
|
-
- [`
|
|
329
|
-
- [`
|
|
493
|
+
- [`ajv-formats`](https://www.npmjs.com/package/ajv-formats)
|
|
494
|
+
- [`apollo-server-core`](https://www.npmjs.com/package/apollo-server-core)
|
|
495
|
+
- [`graphql`](https://www.npmjs.com/package/graphql)
|
|
330
496
|
|
|
331
497
|
### Express case
|
|
332
498
|
|
|
499
|
+
As `dependencies`:
|
|
500
|
+
|
|
501
|
+
- [`cors`](https://www.npmjs.com/package/cors)
|
|
502
|
+
- [`express`](https://www.npmjs.com/package/express)
|
|
503
|
+
- [`express-pino-logger`](https://www.npmjs.com/package/express-pino-logger)
|
|
504
|
+
- [`swagger-ui-express`](https://www.npmjs.com/package/swagger-ui-express)
|
|
505
|
+
|
|
333
506
|
As `devDependencies`:
|
|
334
507
|
|
|
335
508
|
- [`@types/express`](https://www.npmjs.com/package/@types/express)
|
|
336
509
|
- [`@types/cors`](https://www.npmjs.com/package/@types/cors)
|
|
337
|
-
- [`@types/
|
|
510
|
+
- [`@types/express-pino-logger`](https://www.npmjs.com/package/@types/express-pino-logger)
|
|
338
511
|
- [`@types/swagger-ui-express`](https://www.npmjs.com/package/@types/swagger-ui-express)
|
|
339
512
|
|
|
340
|
-
|
|
513
|
+
#### In case you are using GraphQL
|
|
341
514
|
|
|
342
|
-
|
|
343
|
-
- [`express`](https://www.npmjs.com/package/express)
|
|
344
|
-
- [`morgan`](https://www.npmjs.com/package/morgan)
|
|
345
|
-
- [`swagger-ui-express`](https://www.npmjs.com/package/swagger-ui-express)
|
|
515
|
+
As `dependencies`:
|
|
516
|
+
- [`apollo-server-express`](https://www.npmjs.com/package/apollo-server-express)
|
|
346
517
|
|
|
347
518
|
### Fastify case
|
|
348
519
|
|
|
@@ -352,6 +523,12 @@ As `dependencies`:
|
|
|
352
523
|
- [`fastify-cors`](https://www.npmjs.com/package/fastify-cors)
|
|
353
524
|
- [`fastify-swagger`](https://www.npmjs.com/package/fastify-swagger)
|
|
354
525
|
|
|
526
|
+
#### In case you are using GraphQL
|
|
527
|
+
|
|
528
|
+
As `dependencies`:
|
|
529
|
+
- [`apollo-server-fastify`](https://www.npmjs.com/package/apollo-server-fastify)
|
|
530
|
+
- [`apollo-server-plugin-base`](https://www.npmjs.com/package/apollo-server-plugin-base)
|
|
531
|
+
|
|
355
532
|
Feel free to contribute to this project. Every contribution will be appreciated.
|
|
356
533
|
|
|
357
534
|
## Author
|
package/lib/index.js
CHANGED
|
@@ -52,6 +52,8 @@ const argv = yargs(hideBin(process.argv))
|
|
|
52
52
|
)
|
|
53
53
|
.alias('F', 'fastify')
|
|
54
54
|
.describe('F', 'Whether or not you want to use Fastify for your project')
|
|
55
|
+
.alias('g', 'graphql')
|
|
56
|
+
.describe('g', 'Whether or not you want to use GraphQL for your project')
|
|
55
57
|
.default({
|
|
56
58
|
H: false,
|
|
57
59
|
n: false,
|
|
@@ -60,9 +62,10 @@ const argv = yargs(hideBin(process.argv))
|
|
|
60
62
|
v: '0.1.0',
|
|
61
63
|
f: 'src/index.ts',
|
|
62
64
|
q: false,
|
|
63
|
-
F: false
|
|
65
|
+
F: false,
|
|
66
|
+
g: false
|
|
64
67
|
})
|
|
65
|
-
.boolean(['H', 'n', 'q', 'F'])
|
|
68
|
+
.boolean(['H', 'n', 'q', 'F', 'g'])
|
|
66
69
|
.help('h')
|
|
67
70
|
.alias('h', 'help')
|
|
68
71
|
.epilog('Developed by AnthonyLzq').argv
|
|
@@ -80,7 +83,8 @@ const config = {
|
|
|
80
83
|
npm: false,
|
|
81
84
|
manager: 'yarn add',
|
|
82
85
|
mainFile: 'src/index.ts',
|
|
83
|
-
fastify: false
|
|
86
|
+
fastify: false,
|
|
87
|
+
graphql: false
|
|
84
88
|
}
|
|
85
89
|
const UNLICENSED = 'unlicensed'
|
|
86
90
|
const LICENSES = [
|
|
@@ -132,7 +136,6 @@ const main = async () => {
|
|
|
132
136
|
prompt: '> Express or Fastify? '
|
|
133
137
|
}
|
|
134
138
|
)
|
|
135
|
-
|
|
136
139
|
readLineSync.promptLoop(
|
|
137
140
|
input => {
|
|
138
141
|
config.projectName = input.toLowerCase()
|
|
@@ -145,7 +148,6 @@ const main = async () => {
|
|
|
145
148
|
prompt: '> Project name: '
|
|
146
149
|
}
|
|
147
150
|
)
|
|
148
|
-
|
|
149
151
|
readLineSync.promptLoop(
|
|
150
152
|
input => {
|
|
151
153
|
config.projectDescription = input
|
|
@@ -158,7 +160,6 @@ const main = async () => {
|
|
|
158
160
|
prompt: '> Project description: '
|
|
159
161
|
}
|
|
160
162
|
)
|
|
161
|
-
|
|
162
163
|
readLineSync.promptLoop(
|
|
163
164
|
input => {
|
|
164
165
|
config.author = input
|
|
@@ -171,12 +172,10 @@ const main = async () => {
|
|
|
171
172
|
prompt: '> Author: '
|
|
172
173
|
}
|
|
173
174
|
)
|
|
174
|
-
|
|
175
175
|
config.email = readLineSync.questionEMail('> Email: ', {
|
|
176
176
|
limit: EMAIL_REGEXP,
|
|
177
177
|
limitMessage: 'That is not a valid email!'
|
|
178
178
|
})
|
|
179
|
-
|
|
180
179
|
config.version = readLineSync.question('> Project version (0.1.0): ')
|
|
181
180
|
config.version = config.version === '' ? '0.1.0' : config.version
|
|
182
181
|
|
|
@@ -192,7 +191,6 @@ const main = async () => {
|
|
|
192
191
|
.toLowerCase()
|
|
193
192
|
.replace(/ /g, '-')
|
|
194
193
|
.replace('d', '')
|
|
195
|
-
|
|
196
194
|
readLineSync.promptLoop(
|
|
197
195
|
input => {
|
|
198
196
|
if (input !== '') config.licenseYear = input
|
|
@@ -205,14 +203,18 @@ const main = async () => {
|
|
|
205
203
|
prompt: `> License year (${config.licenseYear}): `
|
|
206
204
|
}
|
|
207
205
|
)
|
|
208
|
-
|
|
206
|
+
config.graphql = readLineSync.keyInYNStrict(
|
|
207
|
+
'> Will this project use GraphQL? ',
|
|
208
|
+
{
|
|
209
|
+
caseSensitive: false
|
|
210
|
+
}
|
|
211
|
+
)
|
|
209
212
|
config.heroku = readLineSync.keyInYNStrict(
|
|
210
213
|
'> Will this project be deployed with Heroku? ',
|
|
211
214
|
{
|
|
212
215
|
caseSensitive: false
|
|
213
216
|
}
|
|
214
217
|
)
|
|
215
|
-
|
|
216
218
|
config.mainFile = readLineSync.question('> Main file (src/index.ts): ')
|
|
217
219
|
} else {
|
|
218
220
|
if (!argv.author) return console.log('Error! An author is required!')
|
|
@@ -283,6 +285,8 @@ const main = async () => {
|
|
|
283
285
|
config.manager = 'npm i'
|
|
284
286
|
}
|
|
285
287
|
|
|
288
|
+
if (argv.graphql) config.graphql = true
|
|
289
|
+
|
|
286
290
|
if (!argv.mainFile) console.log('Using src/index.ts as default main file')
|
|
287
291
|
else config.mainFile = argv.mainFile
|
|
288
292
|
}
|
|
@@ -305,4 +309,6 @@ module.exports = main
|
|
|
305
309
|
* @property {Boolean} npm true means that the package manager will be npm, otherwise yarn
|
|
306
310
|
* @property {'yarn add'|'npm i'} manager command that will be used to install packages
|
|
307
311
|
* @property {String} mainFile main file of the project
|
|
312
|
+
* @property {Boolean} fastify true means that the project will be using Fastify
|
|
313
|
+
* @property {Boolean} graphql true means that the project will be using GraphQL
|
|
308
314
|
*/
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
const { platform } = require('os')
|
|
2
|
+
const { promisify } = require('util')
|
|
3
|
+
const exec = promisify(require('child_process').exec)
|
|
4
|
+
const writeFile = require('../../utils/writeFile')
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {Object} args
|
|
8
|
+
* @param {String} projectName
|
|
9
|
+
*/
|
|
10
|
+
const mongoF = async ({ projectName }) => {
|
|
11
|
+
const createFoldersCommand = `mkdir ${projectName}/src/database/mongo \
|
|
12
|
+
${projectName}/src/database/mongo/models \
|
|
13
|
+
${projectName}/src/database/mongo/queries`
|
|
14
|
+
|
|
15
|
+
if (platform() === 'win32')
|
|
16
|
+
await exec(createFoldersCommand.replaceAll('/', '\\'))
|
|
17
|
+
else await exec(createFoldersCommand)
|
|
18
|
+
|
|
19
|
+
const database = {
|
|
20
|
+
index: {
|
|
21
|
+
content: "export * from './mongo'\n",
|
|
22
|
+
file: `${projectName}/src/database/index.ts`
|
|
23
|
+
},
|
|
24
|
+
mongo: {
|
|
25
|
+
index: {
|
|
26
|
+
content: `export * from './models'
|
|
27
|
+
export * from './queries'
|
|
28
|
+
`,
|
|
29
|
+
file: `${projectName}/src/database/mongo/index.ts`
|
|
30
|
+
},
|
|
31
|
+
models: {
|
|
32
|
+
index: {
|
|
33
|
+
content: "export * from './user'\n",
|
|
34
|
+
file: `${projectName}/src/database/mongo/models/index.ts`
|
|
35
|
+
},
|
|
36
|
+
user: {
|
|
37
|
+
content: `import { model, Schema } from 'mongoose'
|
|
38
|
+
|
|
39
|
+
const UserSchema = new Schema<UserDBO>(
|
|
40
|
+
{
|
|
41
|
+
lastName: {
|
|
42
|
+
required: true,
|
|
43
|
+
type: String
|
|
44
|
+
},
|
|
45
|
+
name: {
|
|
46
|
+
required: true,
|
|
47
|
+
type: String
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
timestamps: true,
|
|
52
|
+
versionKey: false,
|
|
53
|
+
toObject: {
|
|
54
|
+
transform: (_, ret) => {
|
|
55
|
+
ret.id = ret._id.toString()
|
|
56
|
+
delete ret._id
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
const UserModel = model<UserDBO>('users', UserSchema)
|
|
63
|
+
|
|
64
|
+
export { UserModel }
|
|
65
|
+
`,
|
|
66
|
+
file: `${projectName}/src/database/mongo/models/user.ts`
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
queries: {
|
|
70
|
+
index: {
|
|
71
|
+
content: "export * from './user'\n",
|
|
72
|
+
file: `${projectName}/src/database/mongo/queries/index.ts`
|
|
73
|
+
},
|
|
74
|
+
user: {
|
|
75
|
+
content: `import { Document, Types } from 'mongoose'
|
|
76
|
+
|
|
77
|
+
import { UserModel } from '..'
|
|
78
|
+
import { UserDTO } from 'schemas'
|
|
79
|
+
|
|
80
|
+
const userDBOtoDTO = (
|
|
81
|
+
userDBO: Document<unknown, unknown, UserDBO> &
|
|
82
|
+
UserDBO & {
|
|
83
|
+
_id: Types.ObjectId
|
|
84
|
+
}
|
|
85
|
+
): UserDTO => ({
|
|
86
|
+
...userDBO.toObject(),
|
|
87
|
+
createdAt: userDBO.createdAt.toISOString(),
|
|
88
|
+
updatedAt: userDBO.updatedAt.toISOString()
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
const store = async (userData: UserDTO): Promise<UserDTO> => {
|
|
92
|
+
const user = new UserModel(userData)
|
|
93
|
+
|
|
94
|
+
await user.save()
|
|
95
|
+
|
|
96
|
+
return userDBOtoDTO(user)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const remove = async (
|
|
100
|
+
id: string | null = null
|
|
101
|
+
): Promise<UserDTO | number | null> => {
|
|
102
|
+
if (id) {
|
|
103
|
+
const removedUser = await UserModel.findByIdAndRemove(id)
|
|
104
|
+
|
|
105
|
+
if (!removedUser) return null
|
|
106
|
+
|
|
107
|
+
return userDBOtoDTO(removedUser)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return (await UserModel.deleteMany({})).deletedCount
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const get = async (
|
|
114
|
+
id: string | null = null
|
|
115
|
+
): Promise<UserDTO[] | UserDTO | null> => {
|
|
116
|
+
if (id) {
|
|
117
|
+
const user = await UserModel.findById(id)
|
|
118
|
+
|
|
119
|
+
return user ? userDBOtoDTO(user) : null
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const users = await UserModel.find({})
|
|
123
|
+
|
|
124
|
+
return users.map(u => userDBOtoDTO(u))
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const update = async (userData: UserDTO): Promise<UserDTO | null> => {
|
|
128
|
+
const { id, ...rest } = userData
|
|
129
|
+
const user = await UserModel.findByIdAndUpdate(id, rest, { new: true })
|
|
130
|
+
|
|
131
|
+
return user ? userDBOtoDTO(user) : null
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export { store, remove, get, update }
|
|
135
|
+
`,
|
|
136
|
+
file: `${projectName}/src/database/mongo/queries/user.ts`
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
await Promise.all([
|
|
143
|
+
await writeFile(database.index.file, database.index.content),
|
|
144
|
+
await writeFile(database.mongo.index.file, database.mongo.index.content),
|
|
145
|
+
await writeFile(
|
|
146
|
+
database.mongo.models.index.file,
|
|
147
|
+
database.mongo.models.index.content
|
|
148
|
+
),
|
|
149
|
+
await writeFile(
|
|
150
|
+
database.mongo.models.user.file,
|
|
151
|
+
database.mongo.models.user.content
|
|
152
|
+
),
|
|
153
|
+
await writeFile(
|
|
154
|
+
database.mongo.queries.index.file,
|
|
155
|
+
database.mongo.queries.index.content
|
|
156
|
+
),
|
|
157
|
+
await writeFile(
|
|
158
|
+
database.mongo.queries.user.file,
|
|
159
|
+
database.mongo.queries.user.content
|
|
160
|
+
)
|
|
161
|
+
])
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @param {Object} args
|
|
166
|
+
* @param {Boolean|undefined} args.mongo
|
|
167
|
+
* @param {String} args.projectName
|
|
168
|
+
*/
|
|
169
|
+
module.exports = async ({ mongo = true, projectName }) => {
|
|
170
|
+
const createFoldersCommand = `mkdir ${projectName}/src/database`
|
|
171
|
+
|
|
172
|
+
if (platform() === 'win32')
|
|
173
|
+
await exec(createFoldersCommand.replaceAll('/', '\\'))
|
|
174
|
+
else await exec(createFoldersCommand)
|
|
175
|
+
|
|
176
|
+
if (mongo) await mongoF({ projectName })
|
|
177
|
+
}
|