@anthonylzq/simba.js 7.2.0 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -1,6 +1,20 @@
1
- const readLineSync = require('readline-sync')
1
+ const prompts = require('prompts')
2
2
  const yargs = require('yargs/yargs')
3
3
  const { hideBin } = require('yargs/helpers')
4
+ const {
5
+ constants: {
6
+ PACKAGE_MANAGERS,
7
+ ONE_CHARACTER_REGEX,
8
+ UNLICENSED,
9
+ LICENSES,
10
+ DATABASES,
11
+ YEAR_REGEX,
12
+ EMAIL_REGEX,
13
+ PROJECT_VERSION,
14
+ MAIN_FILE
15
+ }
16
+ } = require('./src/utils')
17
+ const POSSIBLE_LICENSES = Object.keys(LICENSES)
4
18
 
5
19
  const installation = require('./src')
6
20
 
@@ -9,7 +23,7 @@ const argv = yargs(hideBin(process.argv))
9
23
  .version(false)
10
24
  // Pending to test it using npx
11
25
  .usage(
12
- '"simba [options]" (if you it installed globally) or only "simba -q" if you want to be asked for the options one by one.'
26
+ 'Simba.js, the easiest way to create your TypeScript APIs\n\nUsage:\n\t"simba [options]" or only "simba -q" if you want to be asked for the options one by one.'
13
27
  )
14
28
  .example(
15
29
  "simba -N 'Project Name' -D 'Project description' -a Anthony -e sluzquinosa@uni.pe -l mit -F -t -d mongo --ghat"
@@ -26,8 +40,6 @@ const argv = yargs(hideBin(process.argv))
26
40
  .alias('e', 'email')
27
41
  .nargs('e', 1)
28
42
  .describe('e', 'Email of the author.')
29
- .alias('H', 'heroku')
30
- .describe('H', 'Whether or not the project will be deployed using Heroku.')
31
43
  .alias('l', 'license')
32
44
  .nargs('l', 1)
33
45
  .describe(
@@ -40,10 +52,10 @@ const argv = yargs(hideBin(process.argv))
40
52
  .alias('y', 'licenseYear')
41
53
  .nargs('y', 1)
42
54
  .describe('y', 'Year when the license starts.')
43
- .alias('n', 'npm')
55
+ .alias('m', 'manager')
44
56
  .describe(
45
- 'n',
46
- 'Whether or not the project should use npm as package manager.'
57
+ 'm',
58
+ 'Which package manager you want to use, available package managers are: npm, yarn and pnpm.'
47
59
  )
48
60
  .alias('f', 'mainFile')
49
61
  .nargs('f', 1)
@@ -57,11 +69,6 @@ const argv = yargs(hideBin(process.argv))
57
69
  .describe('F', 'Whether or not you want to use Fastify for your project.')
58
70
  .alias('g', 'graphql')
59
71
  .describe('g', 'Whether or not you want to use GraphQL for your project.')
60
- .alias('t', 'tests')
61
- .describe(
62
- 't',
63
- 'Whether or not you want to have a basic suit of unit tests with Jest.'
64
- )
65
72
  .alias('ghat', 'gh-action-tests')
66
73
  .describe(
67
74
  'ghat',
@@ -69,13 +76,11 @@ const argv = yargs(hideBin(process.argv))
69
76
  )
70
77
  .describe(
71
78
  'd',
72
- 'Which database you want to use, available databases are: MongoDB, PostgreSQL, MySQL, MariaDB, Sqlite and Microsoft SQL Server.'
79
+ 'Which database you want to use, available databases are: MongoDB (mongo), PostgreSQL (postgres), MySQL (mysql), MariaDB (mariadb), Sqlite (sqlite) and Microsoft SQL Server (sqlServer).'
73
80
  )
74
81
  .alias('d', 'database')
75
82
  .nargs('d', 1)
76
83
  .default({
77
- H: false,
78
- n: false,
79
84
  y: CURRENT_YEAR,
80
85
  l: 'unlicensed',
81
86
  v: '0.1.0',
@@ -83,29 +88,25 @@ const argv = yargs(hideBin(process.argv))
83
88
  q: false,
84
89
  F: false,
85
90
  g: false,
86
- t: false,
87
91
  ghat: false,
88
- d: 'mongo'
92
+ d: 'mongo',
93
+ m: 'pnpm'
89
94
  })
90
- .boolean(['H', 'n', 'q', 'F', 'g', 't'])
95
+ .boolean(['q', 'F', 'g'])
91
96
  .help('h')
92
97
  .alias('h', 'help')
93
98
  .epilog('Developed by AnthonyLzq').argv
94
99
 
95
- const PROJECT_VERSION = '0.1.0'
96
- const MAIN_FILE = 'src/index.ts'
97
100
  /** @type {Config} */
98
101
  const config = {
99
102
  author: '',
100
103
  email: '',
101
104
  projectName: '',
102
105
  projectDescription: '',
103
- heroku: false,
104
106
  license: 'unlicensed',
105
107
  version: PROJECT_VERSION,
106
108
  licenseYear: CURRENT_YEAR,
107
- npm: false,
108
- manager: 'yarn add',
109
+ manager: 'pnpm i',
109
110
  mainFile: MAIN_FILE,
110
111
  fastify: false,
111
112
  graphql: false,
@@ -113,175 +114,146 @@ const config = {
113
114
  ghat: true,
114
115
  database: 'mongo'
115
116
  }
116
- const UNLICENSED = 'unlicensed'
117
- const LICENSES = [
118
- 'MIT',
119
- 'Apache 2.0',
120
- 'MPL 2.0',
121
- 'LGPL 3.0',
122
- 'GPL 3.0',
123
- 'AGPL 3.0'
124
- ]
125
- const DATABASES = {
126
- MongoDB: 'mongo',
127
- PostgreSQL: 'postgres',
128
- MySQL: 'mysql',
129
- MariaDB: 'mariadb',
130
- Sqlite: 'sqlite',
131
- 'Microsoft SQL Server': 'sqlServer'
132
- }
133
- const POSSIBLE_LICENSES = ['mit', 'apache', 'mpl', 'lgpl', 'gpl', 'agpl']
134
- const ONE_CHARACTER_REGEXP = /^\w/
135
- const YEAR_REGEXP = /^\d{4}$/
136
- const EMAIL_REGEXP =
137
- /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i
138
117
 
139
118
  const main = async () => {
140
119
  if (argv.q) {
141
- readLineSync.promptCLLoop(
142
- {
143
- npm: () => {
144
- config.npm = true
145
-
146
- return true
120
+ const responses = await prompts(
121
+ [
122
+ {
123
+ type: 'text',
124
+ name: 'projectName',
125
+ message: 'Project name:',
126
+ validate: value =>
127
+ !ONE_CHARACTER_REGEX.test(value)
128
+ ? 'The project must have a name!'
129
+ : true,
130
+ format: value => value.toLowerCase()
147
131
  },
148
- yarn: () => true
149
- },
150
- {
151
- caseSensitive: false,
152
- limitMessage: 'That is not a valid option',
153
- prompt: '> Yarn or npm? '
154
- }
155
- )
156
-
157
- if (config.npm) config.manager = 'npm i'
158
-
159
- readLineSync.promptCLLoop(
160
- {
161
- express: () => true,
162
- fastify: () => {
163
- config.fastify = true
164
-
165
- return true
132
+ {
133
+ type: 'text',
134
+ name: 'projectDescription',
135
+ message: 'Project description:',
136
+ validate: value =>
137
+ !ONE_CHARACTER_REGEX.test(value)
138
+ ? 'The project must have a description!'
139
+ : true
140
+ },
141
+ {
142
+ type: 'select',
143
+ name: 'manager',
144
+ message: 'Select your package manager:',
145
+ choices: PACKAGE_MANAGERS.map(pm => ({
146
+ title: pm,
147
+ value: pm === 'yarn' ? `${pm} add` : `${pm} i`
148
+ }))
149
+ },
150
+ {
151
+ type: 'text',
152
+ name: 'author',
153
+ message: 'Author:',
154
+ validate: value =>
155
+ !ONE_CHARACTER_REGEX.test(value)
156
+ ? 'The project must have an author!'
157
+ : true
158
+ },
159
+ {
160
+ type: 'text',
161
+ name: 'email',
162
+ message: 'Email:',
163
+ validate: value =>
164
+ !EMAIL_REGEX.test(value) ? 'Please, give us a valid email.' : true
165
+ },
166
+ {
167
+ type: 'text',
168
+ name: 'version',
169
+ message: 'Project version:',
170
+ initial: '0.1.0'
171
+ },
172
+ {
173
+ type: 'select',
174
+ name: 'license',
175
+ message: 'License:',
176
+ choices: Object.entries(LICENSES).map(([key, value]) => ({
177
+ title: value,
178
+ value: key
179
+ }))
180
+ },
181
+ {
182
+ type: 'text',
183
+ name: 'licenseYear',
184
+ message: 'License year:',
185
+ initial: `${new Date().getFullYear()}`,
186
+ validate: value =>
187
+ !YEAR_REGEX.test(value) ? 'Please, give us a valid year.' : true
188
+ },
189
+ {
190
+ type: 'toggle',
191
+ name: 'ghat',
192
+ message:
193
+ 'Would you want to have a basic GitHub Action for the suit of tests and linting?',
194
+ active: 'yes',
195
+ inactive: 'no'
196
+ },
197
+ {
198
+ type: 'text',
199
+ name: 'mainFile',
200
+ message: 'Main file:',
201
+ initial: 'src/index.ts'
202
+ },
203
+ {
204
+ type: 'select',
205
+ name: 'framework',
206
+ message: 'Express or Fastify?',
207
+ choices: [
208
+ { title: 'Express', value: 'express' },
209
+ { title: 'Fastify', value: 'fastify' }
210
+ ]
211
+ },
212
+ {
213
+ type: 'toggle',
214
+ name: 'graphql',
215
+ message: 'Will this project use GraphQL?',
216
+ active: 'yes',
217
+ inactive: 'no'
218
+ },
219
+ {
220
+ type: 'select',
221
+ name: 'database',
222
+ message: 'Which database do you want to use?',
223
+ choices: Object.entries(DATABASES).map(([key, value]) => ({
224
+ title: value,
225
+ value: key
226
+ }))
166
227
  }
167
- },
168
- {
169
- caseSensitive: false,
170
- limitMessage: 'That is not a valid option',
171
- prompt: '> Express or Fastify? '
172
- }
173
- )
174
- readLineSync.promptLoop(
175
- input => {
176
- config.projectName = input.toLowerCase()
177
-
178
- return config.projectName !== ''
179
- },
180
- {
181
- limit: ONE_CHARACTER_REGEXP,
182
- limitMessage: 'The project must have a name!',
183
- prompt: '> Project name: '
184
- }
185
- )
186
- readLineSync.promptLoop(
187
- input => {
188
- config.projectDescription = input
189
-
190
- return config.projectDescription !== ''
191
- },
192
- {
193
- limit: ONE_CHARACTER_REGEXP,
194
- limitMessage: 'The project must have a description!',
195
- prompt: '> Project description: '
196
- }
197
- )
198
- readLineSync.promptLoop(
199
- input => {
200
- config.author = input
201
-
202
- return config.author !== ''
203
- },
204
- {
205
- limit: ONE_CHARACTER_REGEXP,
206
- limitMessage: 'The project must have an author!',
207
- prompt: '> Author: '
208
- }
209
- )
210
- config.email = readLineSync.questionEMail('> Email: ', {
211
- limit: EMAIL_REGEXP,
212
- limitMessage: 'That is not a valid email!'
213
- })
214
- config.version = readLineSync.question('> Project version (0.1.0): ')
215
- config.version = config.version === '' ? PROJECT_VERSION : config.version
216
- config.license = LICENSES[
217
- readLineSync.keyInSelect(LICENSES, '> Select your license: ', {
218
- cancel: false
219
- })
220
- ]
221
- .toLowerCase()
222
- .replace(/ /g, '-')
223
- .replace('d', '')
224
- readLineSync.promptLoop(
225
- input => {
226
- if (input !== '') config.licenseYear = input
227
-
228
- return YEAR_REGEXP.test(config.licenseYear)
229
- },
230
- {
231
- limit: [YEAR_REGEXP, ''],
232
- limitMessage: 'That is not a valid license year!',
233
- prompt: `> License year (${config.licenseYear}): `
234
- }
235
- )
236
- config.graphql = readLineSync.keyInYNStrict(
237
- '> Will this project use GraphQL? ',
238
- {
239
- caseSensitive: false
240
- }
241
- )
242
- config.heroku = readLineSync.keyInYNStrict(
243
- '> Will this project be deployed with Heroku? ',
228
+ ],
244
229
  {
245
- caseSensitive: false
246
- }
247
- )
248
- config.mainFile = readLineSync.question('> Main file (src/index.ts): ')
249
- config.mainFile = config.mainFile === '' ? MAIN_FILE : config.mainFile
250
- config.tests = readLineSync.keyInYNStrict(
251
- '> Would you want to have a basic suit of tests with Jest? ',
252
- {
253
- caseSensitive: false
230
+ onCancel: () => {
231
+ console.log('\nSimba.js process cancelled\n')
232
+ process.exit()
233
+ }
254
234
  }
255
235
  )
256
236
 
257
- if (config.tests)
258
- config.ghat = readLineSync.keyInYNStrict(
259
- '> Would you want to have a basic GitHub Action for the suit of tests and linting?',
260
- {
261
- caseSensitive: false
262
- }
263
- )
264
- else config.ghat = false
265
-
266
- config.database =
267
- DATABASES[
268
- Object.keys(DATABASES)[
269
- readLineSync.keyInSelect(
270
- Object.keys(DATABASES),
271
- '> Select your database: ',
272
- {
273
- cancel: false
274
- }
275
- )
276
- ]
277
- ]
237
+ config.author = responses.author
238
+ config.email = responses.email
239
+ config.projectName = responses.projectName
240
+ config.projectDescription = responses.projectDescription
241
+ config.license = responses.license
242
+ config.version = responses.version
243
+ config.licenseYear = responses.licenseYear
244
+ config.manager = responses.manager
245
+ config.mainFile = responses.mainFile
246
+ config.fastify = responses.framework === 'fastify'
247
+ config.graphql = responses.graphql
248
+ config.database = responses.database
249
+ config.ghat = responses.ghat
278
250
  } else {
279
251
  if (!argv.author) return console.log('Error! An author is required!')
280
252
  else config.author = argv.author
281
253
 
282
254
  if (!argv.email) return console.log('Error! An email is required!')
283
255
  else {
284
- if (!EMAIL_REGEXP.test(argv.email))
256
+ if (!EMAIL_REGEX.test(argv.email))
285
257
  return console.log('That is not a valid email!')
286
258
 
287
259
  config.email = argv.email
@@ -297,8 +269,6 @@ const main = async () => {
297
269
  return console.log('Error! A project description is required')
298
270
  else config.projectDescription = argv.projectDescription
299
271
 
300
- if (argv.heroku) config.heroku = true
301
-
302
272
  if (argv.fastify) config.fastify = true
303
273
 
304
274
  if (!argv.license || argv.license === UNLICENSED)
@@ -329,7 +299,7 @@ const main = async () => {
329
299
  console.log(
330
300
  `Year license was not provided, using ${config.licenseYear} as default`
331
301
  )
332
- else if (!YEAR_REGEXP.test(config.licenseYear))
302
+ else if (!YEAR_REGEX.test(config.licenseYear))
333
303
  return console.log(
334
304
  'Year license format was wrong, please provide a YYYY format'
335
305
  )
@@ -338,10 +308,11 @@ const main = async () => {
338
308
  console.log('Initial version wa not provided, using 0.1.0 as default')
339
309
  else config.version = argv.version
340
310
 
341
- if (!argv.npm) console.log('Using yarn as default package manager')
311
+ if (!argv.manager) console.log('Using pnpm as default package manager')
342
312
  else {
343
- config.npm = true
344
- config.manager = 'npm i'
313
+ argv.manager = argv.manager.toLowerCase()
314
+ config.manager =
315
+ argv.manager === 'yarn' ? `${argv.manager} add` : `${argv.manager} i`
345
316
  }
346
317
 
347
318
  if (argv.graphql) config.graphql = true
@@ -349,15 +320,8 @@ const main = async () => {
349
320
  if (!argv.mainFile) console.log('Using src/index.ts as default main file')
350
321
  else config.mainFile = argv.mainFile
351
322
 
352
- if (argv.tests) config.tests = true
353
-
354
323
  if (argv.ghat) config.ghat = true
355
324
 
356
- if (!config.tests && argv.ghat)
357
- return console.log(
358
- 'GitHub Action for tests can not be set to true if the tests flag is set to false'
359
- )
360
-
361
325
  if (argv.database) config.database = argv.database
362
326
  }
363
327
 
@@ -372,15 +336,12 @@ module.exports = main
372
336
  * @property {String} email email of the project author
373
337
  * @property {String} projectName project name
374
338
  * @property {String} projectDescription project description
375
- * @property {Boolean} heroku true if the project will be deployed in heroku
376
339
  * @property {'unlicensed'|'mit'|'apache-2.0'|'mpl-2.0'|'lgpl-3.0'|'gpl-3.0'|'agpl-3.0'} license project license
377
340
  * @property {String} version project initial version
378
341
  * @property {String} licenseYear year when the license starts in format YYYY
379
- * @property {Boolean} npm true means that the package manager will be npm, otherwise yarn
380
- * @property {'yarn add'|'npm i'} manager command that will be used to install packages
342
+ * @property {'yarn add'|'npm i'|'pnpm i'} manager command that will be used to install packages
381
343
  * @property {String} mainFile main file of the project
382
344
  * @property {Boolean} fastify true means that the project will be using Fastify
383
345
  * @property {Boolean} graphql true means that the project will be using GraphQL
384
346
  * @property {'mongo'|'postgres'|'mysql'|'mariadb'|'sqlite'|'sqlServer'} database project database
385
- * @property {Boolean} tests true means that the project will have tests
386
347
  */