clwy-express-generator 5.1.4 → 5.2.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 CHANGED
@@ -10,6 +10,7 @@
10
10
 
11
11
  - **🚀 ES6 支持**:代码更现代简洁。
12
12
  - **🔀 路由拆分**:独立文件,便于管理维护。
13
+ - **🗄️ ORM 支持**:支持 Prisma 或 Sequelize ORM。
13
14
  - **📁 中间件模块化**:新增文件夹存放中间件。
14
15
  - **🔧 增加环境变量配置**:多环境管理更便捷。
15
16
  - **🔄 集成 nodemon**:开发时自动重启服务。
@@ -19,12 +20,15 @@
19
20
 
20
21
  ## 快速开始
21
22
 
23
+ ### 基础使用
24
+
22
25
  使用express最快的方式是利用可执行文件`express(1)`来生成一个应用,如下所示:
23
26
 
24
27
  创建应用:
25
28
 
26
29
  ```bash
27
- $ npx clwy-express-generator --view=ejs --es6 es6-demo && cd es6-demo
30
+ $ npx clwy-express-generator --view=ejs --es6 es6-demo
31
+ $ cd es6-demo
28
32
  ```
29
33
 
30
34
  安装依赖:
@@ -39,6 +43,51 @@ $ npm install
39
43
  $ npm start
40
44
  ```
41
45
 
46
+ ## 使用 ORM
47
+
48
+ ### 使用数据库
49
+
50
+ 安装好 Docker 并启动后:
51
+
52
+ ```bash
53
+ $ docker-compose up -d
54
+ ```
55
+
56
+ 默认将启动 MySQL 数据库,PostgreSQL 和 Redis 配置已在 `docker-compose.yml` 中,请根据需求调整。
57
+
58
+ ### 使用 Prisma
59
+
60
+ 创建应用:
61
+
62
+ ```bash
63
+ $ npx clwy-express-generator --view=ejs --orm=prisma --es6 es6-prisma-demo
64
+ $ cd es6-prisma-demo
65
+ $ npm i
66
+ ```
67
+
68
+ 初始化数据库客户端:
69
+
70
+ ```bash
71
+ $ npx prisma generate
72
+ ```
73
+
74
+ ### 使用 Sequelize
75
+
76
+ 创建应用:
77
+
78
+ ```bash
79
+ $ npx clwy-express-generator --view=ejs --orm=sequelize --es6 es6-sequelize-demo
80
+ $ cd es6-sequelize-demo
81
+ $ npm i
82
+ ```
83
+
84
+ 根据需求安装数据库引擎:
85
+
86
+ ```bash
87
+ $ npm install --save mysql2 # MySQL
88
+ $ npm install --save pg pg-hstore # Postgres
89
+ ```
90
+
42
91
  ## 命令行选项
43
92
 
44
93
  此生成器还可以通过以下命令行标志进行进一步配置。
@@ -46,6 +95,7 @@ $ npm start
46
95
  --version 输出版本号
47
96
  -v, --view <engine> 添加视图引擎 <engine> 支持 (dust|ejs|hbs|hjs|pug|twig|vash|api)(默认为 ejs)
48
97
  --no-view 使用静态html而不是视图引擎
98
+ -o, --orm <orm> 添加 ORM <orm> 支持 (prisma|sequelize)
49
99
  -c, --css <engine> 添加样式表引擎 <engine> 支持 (less|stylus|compass|sass)(默认为纯 css)
50
100
  --git 添加 .gitignore 文件
51
101
  --es6 生成 ES6 代码和模块类型项目(需要Node 22.x或更高版本)
@@ -54,31 +104,35 @@ $ npm start
54
104
 
55
105
  ------------
56
106
 
57
- # clwy-express-generator: [Express'](https://www.npmjs.com/package/express) application generator
107
+ # clwy-express-generator: [Express](https://www.npmjs.com/package/express) Application Generator
58
108
 
59
- **This project is a fork of [express-generator](https://github.com/expressjs/generator), enhanced with new features.**
109
+ **This project is forked from [express-generator](https://github.com/expressjs/generator) with additional features.**
60
110
 
61
- **The ES6 support was adapted and improved from [Dr Jeff Jackson](https://github.com/drjeffjackson)'s [Pull Request](https://github.com/expressjs/generator/pull/316).**
111
+ **ES6 support is implemented based on the [Pull Request](https://github.com/expressjs/generator/pull/316) submitted by [Dr. Jeff Jackson](https://github.com/drjeffjackson), with further optimizations and adjustments.**
62
112
 
63
113
  ## Features
64
114
 
65
- - **🚀 ES6 Support**: Modern and cleaner code.
66
- - **🔀 Split Routes**: Separate files for easier management and maintenance.
67
- - **📁 Modular Middleware**: Dedicated folder for middleware.
68
- - **🔧 Environment Variables**: Easier multi-environment configuration.
69
- - **🔄 Nodemon Integration**: Auto-restart during development.
70
- - **🌐 CORS Integration**: Allows cross-origin requests.
71
- - **📄 Added basic README.md**: Describes the project as a simple Express app with static file serving and basic routing.
72
- - **📦 Built-in Configs**: Includes `.prettierrc` (code formatting) and `.gitignore` (file exclusion) by default.
115
+ - **🚀 ES6 Support**: More modern and concise code.
116
+ - **🔀 Route Splitting**: Independent files for easier management and maintenance.
117
+ - **🗄️ ORM Support**: Supports Prisma or Sequelize ORM.
118
+ - **📁 Modular Middleware**: New folder for storing middleware.
119
+ - **🔧 Enhanced Environment Variable Configuration**: More convenient multi-environment management.
120
+ - **🔄 Integrated Nodemon**: Automatic service restart during development.
121
+ - **🌐 Integrated CORS**: Allows cross-origin requests.
122
+ - **📄 Added README.md**: Contains project introduction and basic feature descriptions.
123
+ - **📦 Built-in Configuration**: Includes `.prettierrc` (code formatting) and `.gitignore` (file ignore) by default.
73
124
 
74
125
  ## Quick Start
75
126
 
76
- The quickest way to get started with express is to utilize the executable `express(1)` to generate an application as shown below:
127
+ ### Basic Usage
77
128
 
78
- Create the app:
129
+ The fastest way to create an Express application is by using the executable `express(1)` to generate an app, as shown below:
130
+
131
+ Create the application:
79
132
 
80
133
  ```bash
81
- $ npx clwy-express-generator --view=ejs --es6 es6-demo && cd es6-demo
134
+ $ npx clwy-express-generator --view=ejs --es6 es6-demo
135
+ $ cd es6-demo
82
136
  ```
83
137
 
84
138
  Install dependencies:
@@ -93,18 +147,64 @@ Start your Express.js app at `http://localhost:3000/`:
93
147
  $ npm start
94
148
  ```
95
149
 
96
- ## Command Line Options
150
+ ## Using ORM
151
+
152
+ ### Using a Database
153
+
154
+ After installing and starting Docker:
155
+
156
+ ```bash
157
+ $ docker-compose up -d
158
+ ```
159
+
160
+ This will start a MySQL database by default. PostgreSQL and Redis configurations are already in `docker-compose.yml`; adjust them according to your needs.
161
+
162
+ ### Using Prisma
163
+
164
+ Create the application:
165
+
166
+ ```bash
167
+ $ npx clwy-express-generator --view=ejs --orm=prisma --es6 es6-prisma-demo
168
+ $ cd es6-prisma-demo
169
+ $ npm i
170
+ ```
171
+
172
+ Initialize the database client:
97
173
 
98
- This generator can also be further configured with the following command line flags.
174
+ ```bash
175
+ $ npx prisma generate
176
+ ```
177
+
178
+ ### Using Sequelize
179
+
180
+ Create the application:
181
+
182
+ ```bash
183
+ $ npx clwy-express-generator --view=ejs --orm=sequelize --es6 es6-sequelize-demo
184
+ $ cd es6-sequelize-demo
185
+ $ npm i
186
+ ```
187
+
188
+ Install the database engine as needed:
189
+
190
+ ```bash
191
+ $ npm install --save mysql2 # MySQL
192
+ $ npm install --save pg pg-hstore # Postgres
193
+ ```
194
+
195
+ ## Command Line Options
99
196
 
100
- --version output the version number
101
- -v, --view <engine> add view <engine> support (dust|ejs|hbs|hjs|pug|twig|vash|api) (defaults to ejs)
102
- --no-view use static html instead of view engine
103
- -c, --css <engine> add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
104
- --git add .gitignore
105
- --es6 generate ES6 code and module-type project (requires Node 22.x or higher)
106
- -f, --force force on non-empty directory
107
- -h, --help output usage information
197
+ This generator can be further configured with the following command line flags.
198
+
199
+ --version Output the version number
200
+ -v, --view <engine> Add view engine <engine> support (dust|ejs|hbs|hjs|pug|twig|vash|api) (defaults to ejs)
201
+ --no-view Use static HTML instead of a view engine
202
+ -o, --orm <orm> Add ORM <orm> support (prisma|sequelize)
203
+ -c, --css <engine> Add stylesheet engine <engine> support (less|stylus|compass|sass) (defaults to plain css)
204
+ --git Add .gitignore file
205
+ --es6 Generate ES6 code and module type project (requires Node 22.x or higher)
206
+ -f, --force Force operation on non-empty directory
207
+ -h, --help Output usage information
108
208
 
109
209
  ------------
110
210
 
@@ -14,7 +14,7 @@ const MODE_0666 = parseInt('0666', 8)
14
14
  const MODE_0755 = parseInt('0755', 8)
15
15
  const TEMPLATE_DIR = path.join(__dirname, '..', 'templates')
16
16
  const VERSION = require('../package').version
17
- const MIN_ES6_VERSION = 14
17
+ const MIN_ES6_VERSION = 22
18
18
 
19
19
  // parse args
20
20
  const unknown = []
@@ -25,16 +25,17 @@ const args = parseArgs(process.argv.slice(2), {
25
25
  f: 'force',
26
26
  h: 'help',
27
27
  H: 'hogan',
28
- v: 'view'
28
+ v: 'view',
29
+ o: 'orm',
29
30
  },
30
31
  boolean: ['ejs', 'es6', 'force', 'git', 'hbs', 'help', 'hogan', 'pug', 'version'],
31
- default: { css: true, view: true },
32
+ default: { css: true, view: true, orm: false },
32
33
  string: ['css', 'view'],
33
34
  unknown: function (s) {
34
35
  if (s.charAt(0) === '-') {
35
36
  unknown.push(s)
36
37
  }
37
- }
38
+ },
38
39
  })
39
40
 
40
41
  args['!'] = unknown
@@ -46,10 +47,10 @@ main(args, exit)
46
47
  * Prompt for confirmation on STDOUT/STDIN
47
48
  */
48
49
 
49
- function confirm (msg, callback) {
50
+ function confirm(msg, callback) {
50
51
  const rl = readline.createInterface({
51
52
  input: process.stdin,
52
- output: process.stdout
53
+ output: process.stdout,
53
54
  })
54
55
 
55
56
  rl.question(msg, function (input) {
@@ -62,7 +63,7 @@ function confirm (msg, callback) {
62
63
  * Copy file from template directory.
63
64
  */
64
65
 
65
- function copyTemplate (from, to) {
66
+ function copyTemplate(from, to) {
66
67
  write(to, fs.readFileSync(path.join(TEMPLATE_DIR, from), 'utf-8'))
67
68
  }
68
69
 
@@ -70,7 +71,7 @@ function copyTemplate (from, to) {
70
71
  * Copy multiple files from template directory.
71
72
  */
72
73
 
73
- function copyTemplateMulti (fromDir, toDir, nameGlob) {
74
+ function copyTemplateMulti(fromDir, toDir, nameGlob) {
74
75
  fs.readdirSync(path.join(TEMPLATE_DIR, fromDir))
75
76
  .filter(minimatch.filter(nameGlob, { matchBase: true }))
76
77
  .forEach(function (name) {
@@ -87,7 +88,7 @@ function copyTemplateMulti (fromDir, toDir, nameGlob) {
87
88
  * @param {function} done
88
89
  */
89
90
 
90
- function createApplication (name, dir, options, done) {
91
+ function createApplication(name, dir, options, done) {
91
92
  console.log()
92
93
 
93
94
  // Package
@@ -98,18 +99,18 @@ function createApplication (name, dir, options, done) {
98
99
  type: options.es6 ? 'module' : 'commonjs',
99
100
  scripts: {
100
101
  start: 'nodemon ./bin/www',
101
- format: 'prettier --write "**/*.{js,json,md}"'
102
+ format: 'prettier --write "**/*.{js,json,md}"',
102
103
  },
103
104
  dependencies: {
104
105
  cors: '^2.8.5',
105
- debug: '~4.4.0',
106
- dotenv: '^16.5.0',
107
- express: '~5.1.0'
106
+ debug: '~4.4.3',
107
+ dotenv: '^17.2.3',
108
+ express: '~5.2.1',
108
109
  },
109
110
  devDependencies: {
110
- nodemon: '^3.1.9',
111
- prettier: '^3.5.3'
112
- }
111
+ nodemon: '^3.1.11',
112
+ prettier: '^3.7.4',
113
+ },
113
114
  }
114
115
 
115
116
  // JavaScript
@@ -127,7 +128,7 @@ function createApplication (name, dir, options, done) {
127
128
  // Request logger
128
129
  app.locals.modules.logger = 'morgan'
129
130
  app.locals.uses.push("logger('dev')")
130
- pkg.dependencies.morgan = '~1.10.0'
131
+ pkg.dependencies.morgan = '~1.10.1'
131
132
 
132
133
  // Body parsers
133
134
  app.locals.uses.push('express.json()')
@@ -153,6 +154,9 @@ function createApplication (name, dir, options, done) {
153
154
  mkdir(dir, 'middlewares')
154
155
  mkdir(dir, 'utils')
155
156
 
157
+ // copy docker-compose.yml
158
+ copyTemplate('docker-compose.yml', path.join(dir, 'docker-compose.yml'))
159
+
156
160
  // copy css templates
157
161
  switch (options.css) {
158
162
  case 'less':
@@ -173,28 +177,27 @@ function createApplication (name, dir, options, done) {
173
177
  }
174
178
 
175
179
  // copy Prettier templates
176
- copyTemplate(options.es6 ? 'mjs/prettierrc.json' : 'js/prettierrc.json', path.join(dir, '.prettierrc.json'))
180
+ copyTemplate(
181
+ options.es6 ? 'mjs/prettierrc.json' : 'js/prettierrc.json',
182
+ path.join(dir, '.prettierrc.json'),
183
+ )
177
184
 
178
185
  // copy config templates
179
186
  mkdir(dir, 'config')
180
- copyTemplateMulti(
181
- options.es6 ? 'mjs/config' : 'js/config',
182
- dir + '/config', '*.js'
183
- )
187
+ copyTemplateMulti(options.es6 ? 'mjs/config' : 'js/config', dir + '/config', '*.js')
184
188
 
185
189
  // copy route templates
186
190
  mkdir(dir, 'routes')
187
- copyTemplateMulti(
188
- options.es6 ? 'mjs/routes' : 'js/routes',
189
- dir + '/routes', '*.js')
191
+ copyTemplateMulti(options.es6 ? 'mjs/routes' : 'js/routes', dir + '/routes', '*.js')
190
192
 
191
193
  if (options.view) {
192
194
  // Copy view templates
193
195
  mkdir(dir, 'views')
194
- pkg.dependencies['http-errors'] = '~2.0.0'
196
+ pkg.dependencies['http-errors'] = '~2.0.1'
195
197
  copyTemplateMulti(
196
198
  options.es6 ? 'mjs/middlewares' : 'js/middlewares',
197
- dir + '/middlewares', '*.js'
199
+ dir + '/middlewares',
200
+ '*.js',
198
201
  )
199
202
 
200
203
  switch (options.view) {
@@ -239,7 +242,9 @@ function createApplication (name, dir, options, done) {
239
242
  break
240
243
  case 'sass':
241
244
  app.locals.modules.sassMiddleware = 'node-sass-middleware'
242
- app.locals.uses.push("sassMiddleware({\n src: path.join(__dirname, 'public'),\n dest: path.join(__dirname, 'public'),\n indentedSyntax: true, // true = .sass and false = .scss\n sourceMap: true\n})")
245
+ app.locals.uses.push(
246
+ "sassMiddleware({\n src: path.join(__dirname, 'public'),\n dest: path.join(__dirname, 'public'),\n indentedSyntax: true, // true = .sass and false = .scss\n sourceMap: true\n})",
247
+ )
243
248
  pkg.dependencies['node-sass-middleware'] = '~1.1.0'
244
249
  break
245
250
  case 'stylus':
@@ -255,7 +260,7 @@ function createApplication (name, dir, options, done) {
255
260
  app.locals.modules.adaro = 'adaro'
256
261
  app.locals.view = {
257
262
  engine: 'dust',
258
- render: 'adaro.dust()'
263
+ render: 'adaro.dust()',
259
264
  }
260
265
  pkg.dependencies.adaro = '~1.0.4'
261
266
  break
@@ -288,6 +293,34 @@ function createApplication (name, dir, options, done) {
288
293
  break
289
294
  }
290
295
 
296
+ // ORM
297
+ env.locals.orm = false
298
+ if (options.orm) {
299
+ env.locals.orm = options.orm
300
+
301
+ switch (options.orm) {
302
+ case 'prisma':
303
+ // copy Prisma templates
304
+ pkg.dependencies.prisma = '^7.2.0'
305
+ pkg.dependencies['@prisma/client'] = '^7.2.0'
306
+
307
+ mkdir(dir, 'prisma')
308
+ copyTemplateMulti('prisma', dir, 'prisma.config.js')
309
+ copyTemplateMulti('prisma/prisma', dir + '/prisma', 'schema.prisma')
310
+ break
311
+ case 'sequelize':
312
+ // copy Sequelize templates
313
+ pkg.dependencies.sequelize = '^6.37.7'
314
+
315
+ mkdir(dir, 'migrations')
316
+ mkdir(dir, 'seeders')
317
+ mkdir(dir, 'models')
318
+ copyTemplateMulti('sequelize/models', dir + '/models', 'index.js')
319
+ copyTemplateMulti('sequelize/config', dir + '/config', 'config.json')
320
+ break
321
+ }
322
+ }
323
+
291
324
  // Static files
292
325
  app.locals.uses.push("express.static(path.join(__dirname, 'public'))")
293
326
 
@@ -338,8 +371,9 @@ function createApplication (name, dir, options, done) {
338
371
  * @param {String} pathName
339
372
  */
340
373
 
341
- function createAppName (pathName) {
342
- return path.basename(pathName)
374
+ function createAppName(pathName) {
375
+ return path
376
+ .basename(pathName)
343
377
  .replace(/[^A-Za-z0-9.-]+/g, '-')
344
378
  .replace(/^[-_.]+|-+$/g, '')
345
379
  .toLowerCase()
@@ -352,7 +386,7 @@ function createAppName (pathName) {
352
386
  * @param {Function} fn
353
387
  */
354
388
 
355
- function emptyDirectory (dir, fn) {
389
+ function emptyDirectory(dir, fn) {
356
390
  fs.readdir(dir, function (err, files) {
357
391
  if (err && err.code !== 'ENOENT') throw err
358
392
  fn(!files || !files.length)
@@ -365,7 +399,7 @@ function emptyDirectory (dir, fn) {
365
399
  * @param {String} message
366
400
  */
367
401
 
368
- function error (message) {
402
+ function error(message) {
369
403
  console.error()
370
404
  message.split('\n').forEach(function (line) {
371
405
  console.error(' error: %s', line)
@@ -377,12 +411,12 @@ function error (message) {
377
411
  * Graceful exit for async STDIO
378
412
  */
379
413
 
380
- function exit (code) {
414
+ function exit(code) {
381
415
  // flush output for Node.js Windows pipe bug
382
416
  // https://github.com/joyent/node/issues/6247 is just one bug example
383
417
  // https://github.com/visionmedia/mocha/issues/333 has a good discussion
384
- function done () {
385
- if (!(draining--)) process.exit(code)
418
+ function done() {
419
+ if (!draining--) process.exit(code)
386
420
  }
387
421
 
388
422
  let draining = 0
@@ -403,28 +437,27 @@ function exit (code) {
403
437
  * Determine if launched from cmd.exe
404
438
  */
405
439
 
406
- function launchedFromCmd () {
407
- return process.platform === 'win32' &&
408
- process.env._ === undefined
440
+ function launchedFromCmd() {
441
+ return process.platform === 'win32' && process.env._ === undefined
409
442
  }
410
443
 
411
444
  /**
412
445
  * Load template file.
413
446
  */
414
447
 
415
- function loadTemplate (name) {
416
- const contents = fs.readFileSync(path.join(__dirname, '..', 'templates', (name + '.ejs')), 'utf-8')
448
+ function loadTemplate(name) {
449
+ const contents = fs.readFileSync(path.join(__dirname, '..', 'templates', name + '.ejs'), 'utf-8')
417
450
  const locals = Object.create(null)
418
451
 
419
- function render () {
452
+ function render() {
420
453
  return ejs.render(contents, locals, {
421
- escape: util.inspect
454
+ escape: util.inspect,
422
455
  })
423
456
  }
424
457
 
425
458
  return {
426
459
  locals: locals,
427
- render: render
460
+ render: render,
428
461
  }
429
462
  }
430
463
 
@@ -432,7 +465,7 @@ function loadTemplate (name) {
432
465
  * Main program.
433
466
  */
434
467
 
435
- function main (options, done) {
468
+ function main(options, done) {
436
469
  // top-level argument direction
437
470
  if (options['!'].length > 0) {
438
471
  usage()
@@ -446,15 +479,19 @@ function main (options, done) {
446
479
  done(0)
447
480
  } else if (options.css === '') {
448
481
  usage()
449
- error('option `-c, --css <engine>\' argument missing')
482
+ error("option `-c, --css <engine>' argument missing")
450
483
  done(1)
451
484
  } else if (options.view === '') {
452
485
  usage()
453
- error('option `-v, --view <engine>\' argument missing')
486
+ error("option `-v, --view <engine>' argument missing")
487
+ done(1)
488
+ } else if (options.orm === '') {
489
+ usage()
490
+ error("option `-o, --orm <engine>' argument missing")
454
491
  done(1)
455
492
  } else if (options.es6 && process.versions.node.split('.')[0] < MIN_ES6_VERSION) {
456
493
  usage()
457
- error('option `--es6\' requires Node version ' + MIN_ES6_VERSION + '.x or higher')
494
+ error("option `--es6' requires Node version " + MIN_ES6_VERSION + '.x or higher')
458
495
  done(1)
459
496
  } else {
460
497
  console.log(options.view)
@@ -489,8 +526,10 @@ function main (options, done) {
489
526
 
490
527
  // Default view engine
491
528
  if (options.view === true) {
492
- warning('the default view engine will not be ejs in future releases\n' +
493
- "use `--view=ejs' or `--help' for additional options")
529
+ warning(
530
+ 'the default view engine is ejs\n' +
531
+ "use `--view=ejs' or `--help' for additional options",
532
+ )
494
533
  options.view = 'ejs'
495
534
  }
496
535
 
@@ -520,7 +559,7 @@ function main (options, done) {
520
559
  * @param {string} dir
521
560
  */
522
561
 
523
- function mkdir (base, dir) {
562
+ function mkdir(base, dir) {
524
563
  const loc = path.join(base, dir)
525
564
 
526
565
  console.log(' \x1b[36mcreate\x1b[0m : ' + loc + path.sep)
@@ -531,7 +570,7 @@ function mkdir (base, dir) {
531
570
  * Display the usage.
532
571
  */
533
572
 
534
- function usage () {
573
+ function usage() {
535
574
  console.log('')
536
575
  console.log(' Usage: express [options] [dir]')
537
576
  console.log('')
@@ -541,11 +580,20 @@ function usage () {
541
580
  console.log(' --pug add pug engine support')
542
581
  console.log(' --hbs add handlebars engine support')
543
582
  console.log(' -H, --hogan add hogan.js engine support')
544
- console.log(' -v, --view <engine> add view <engine> support (dust|ejs|hbs|hjs|pug|twig|vash) (defaults to ejs)')
583
+ console.log(
584
+ ' -v, --view <engine> add view <engine> support (dust|ejs|hbs|hjs|pug|twig|vash) (defaults to ejs)',
585
+ )
545
586
  console.log(' --no-view use static html instead of view engine')
546
- console.log(' -c, --css <engine> add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)')
587
+ console.log(
588
+ ' -c, --css <engine> add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)',
589
+ )
547
590
  console.log(' --git add .gitignore')
548
- console.log(' --es6 generate ES6 code and module-type project (requires Node 14.x or higher)')
591
+ console.log(
592
+ ' --es6 generate ES6 code and module-type project (requires Node 22.x or higher)',
593
+ )
594
+ console.log(
595
+ ' -o, --orm <orm> add ORM <orm> support (prisma|sequelize)',
596
+ )
549
597
  console.log(' -f, --force force on non-empty directory')
550
598
  console.log(' --version output the version number')
551
599
  console.log(' -h, --help output usage information')
@@ -555,7 +603,7 @@ function usage () {
555
603
  * Display the version.
556
604
  */
557
605
 
558
- function version () {
606
+ function version() {
559
607
  console.log(VERSION)
560
608
  }
561
609
 
@@ -565,7 +613,7 @@ function version () {
565
613
  * @param {String} message
566
614
  */
567
615
 
568
- function warning (message) {
616
+ function warning(message) {
569
617
  console.error()
570
618
  message.split('\n').forEach(function (line) {
571
619
  console.error(' warning: %s', line)
@@ -580,7 +628,7 @@ function warning (message) {
580
628
  * @param {String} str
581
629
  */
582
630
 
583
- function write (file, str, mode) {
631
+ function write(file, str, mode) {
584
632
  fs.writeFileSync(file, str, { mode: mode || MODE_0666 })
585
633
  console.log(' \x1b[36mcreate\x1b[0m : ' + file)
586
634
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "clwy-express-generator",
3
3
  "description": "Express' application generator",
4
4
  "homepage": "https://github.com/clwy-cn/clwy-express-generator",
5
- "version": "5.1.4",
5
+ "version": "5.2.0",
6
6
  "author": "TJ Holowaychuk <tj@vision-media.ca>",
7
7
  "contributors": [
8
8
  "Aaron Heckmann <aaron.heckmann+github@gmail.com>",
@@ -40,13 +40,8 @@
40
40
  "clwy-express": "./bin/express-cli.js"
41
41
  },
42
42
  "devDependencies": {
43
- "eslint": "7.32.0",
44
- "eslint-config-standard": "14.1.1",
45
- "eslint-plugin-import": "2.25.4",
46
- "eslint-plugin-node": "11.1.0",
47
- "eslint-plugin-promise": "5.2.0",
48
- "eslint-plugin-standard": "4.1.0",
49
43
  "mocha": "9.1.3",
44
+ "prettier": "^3.7.4",
50
45
  "rimraf": "3.0.2",
51
46
  "supertest": "6.1.4",
52
47
  "tree-kill": "1.2.2",
@@ -64,6 +59,7 @@
64
59
  "scripts": {
65
60
  "lint": "eslint .",
66
61
  "test": "mocha --reporter spec --bail --check-leaks test/",
67
- "test-ci": "mocha --reporter spec --check-leaks test/"
62
+ "test-ci": "mocha --reporter spec --check-leaks test/",
63
+ "format": "prettier --write \"bin/*.{js,json,md,ts,jsx,tsx}\""
68
64
  }
69
65
  }
@@ -0,0 +1,26 @@
1
+ services:
2
+ mysql:
3
+ image: mysql:latest
4
+ command:
5
+ --character-set-server=utf8mb4
6
+ --collation-server=utf8mb4_general_ci
7
+ environment:
8
+ - MYSQL_ROOT_PASSWORD=root
9
+ ports:
10
+ - "3306:3306"
11
+ volumes:
12
+ - ./data/mysql:/var/lib/mysql
13
+ # postgresql:
14
+ # image: postgres:latest
15
+ # ports:
16
+ # - "5432:5432"
17
+ # environment:
18
+ # POSTGRES_PASSWORD: postgres
19
+ # volumes:
20
+ # - ./data/postgresql:/var/lib/postgresql/data
21
+ # redis:
22
+ # image: redis:latest
23
+ # ports:
24
+ # - "6379:6379"
25
+ # volumes:
26
+ # - ./data/redis:/data
package/templates/env.ejs CHANGED
@@ -1,3 +1,10 @@
1
1
  # your environment variables
2
2
  NODE_ENV=development
3
3
  PORT=3000
4
+
5
+ <% if (orm === 'prisma') { -%>
6
+ # If you want to use PostgresSQL or SQLite, change the provider and uncomment the following line
7
+ # DATABASE_URL="postgresql://postgres:postgres@localhost:5432/mydb?schema=public"
8
+ # DATABASE_URL="file:./dev.db"
9
+ DATABASE_URL="mysql://root:root@localhost:3306/mydb"
10
+ <% } -%>
@@ -0,0 +1,18 @@
1
+ // This is your Prisma schema file,
2
+ // learn more about it in the docs: https://pris.ly/d/prisma-schema
3
+
4
+ // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
5
+ // Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
6
+
7
+ generator client {
8
+ provider = "prisma-client"
9
+ output = "../generated/prisma"
10
+ }
11
+
12
+ datasource db {
13
+ provider = "mysql"
14
+
15
+ // If you want to use PostgresSQL or SQLite, change the provider and uncomment the following line
16
+ // provider = "postgresql"
17
+ // provider = "sqlite"
18
+ }
@@ -0,0 +1,13 @@
1
+ // This file was generated by Prisma:
2
+ import 'dotenv/config'
3
+ import { defineConfig } from 'prisma/config'
4
+
5
+ export default defineConfig({
6
+ schema: 'prisma/schema.prisma',
7
+ migrations: {
8
+ path: 'prisma/migrations',
9
+ },
10
+ datasource: {
11
+ url: process.env['DATABASE_URL'],
12
+ },
13
+ })
@@ -0,0 +1,27 @@
1
+ {
2
+ "development": {
3
+ "username": "root",
4
+ "password": "root",
5
+ "database": "database_development",
6
+ "host": "127.0.0.1",
7
+ "dialect": "mysql",
8
+ "timezone": "+08:00",
9
+ "logQueryParameters": true
10
+ },
11
+ "test": {
12
+ "username": "root",
13
+ "password": null,
14
+ "database": "database_test",
15
+ "host": "127.0.0.1",
16
+ "dialect": "mysql",
17
+ "timezone": "+08:00"
18
+ },
19
+ "production": {
20
+ "username": "root",
21
+ "password": null,
22
+ "database": "database_production",
23
+ "host": "127.0.0.1",
24
+ "dialect": "mysql",
25
+ "timezone": "+08:00"
26
+ }
27
+ }
@@ -0,0 +1,47 @@
1
+ import fs from 'fs'
2
+ import path from 'path'
3
+ import { fileURLToPath } from 'url'
4
+ import Sequelize from 'sequelize'
5
+ import process from 'process'
6
+
7
+ const __filename = fileURLToPath(import.meta.url)
8
+ const basename = path.basename(__filename)
9
+ const env = process.env.NODE_ENV || 'development'
10
+ const configPath = path.join(path.dirname(__filename), '../config/config.json')
11
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'))[env]
12
+ const db = {}
13
+
14
+ let sequelize
15
+ if (config.use_env_variable) {
16
+ sequelize = new Sequelize(process.env[config.use_env_variable], config)
17
+ } else {
18
+ sequelize = new Sequelize(config.database, config.username, config.password, config)
19
+ }
20
+
21
+ const files = fs.readdirSync(path.dirname(__filename)).filter((file) => {
22
+ return (
23
+ file.indexOf('.') !== 0 &&
24
+ file !== basename &&
25
+ file.slice(-3) === '.js' &&
26
+ file.indexOf('.test.js') === -1
27
+ )
28
+ })
29
+
30
+ for (const file of files) {
31
+ const model = (await import(`./${file}`)).default(
32
+ sequelize,
33
+ Sequelize.DataTypes,
34
+ )
35
+ db[model.name] = model
36
+ }
37
+
38
+ Object.keys(db).forEach((modelName) => {
39
+ if (db[modelName].associate) {
40
+ db[modelName].associate(db)
41
+ }
42
+ })
43
+
44
+ db.sequelize = sequelize
45
+ db.Sequelize = Sequelize
46
+
47
+ export default db