From 57e525482d6a575e152a4ee749ec9c5f06231c90 Mon Sep 17 00:00:00 2001 From: iphayao Date: Sat, 9 Jun 2018 23:16:45 +0700 Subject: [PATCH 1/8] gen: add web api template support --- bin/express-cli.js | 36 ++++++++++++++++++++++--------- templates/js/routes/api/values.js | 29 +++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 templates/js/routes/api/values.js diff --git a/bin/express-cli.js b/bin/express-cli.js index cfec11be..38d895db 100755 --- a/bin/express-cli.js +++ b/bin/express-cli.js @@ -54,6 +54,7 @@ program .option('-H, --hogan', 'add hogan.js engine support', renamedOption('--hogan', '--view=hogan')) .option('-v, --view ', 'add view support (dust|ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)') .option(' --no-view', 'use static html instead of view engine') + .option('-a, --api', 'use web api template') .option('-c, --css ', 'add stylesheet support (less|stylus|compass|sass) (defaults to plain css)') .option(' --git', 'add .gitignore') .option('-f, --force', 'force on non-empty directory') @@ -207,8 +208,13 @@ function createApplication (name, dir) { // copy route templates mkdir(dir, 'routes') - copyTemplateMulti('js/routes', dir + '/routes', '*.js') - + if(!program.api) { + copyTemplateMulti('js/routes', dir + '/routes', '*.js') + } + else { + copyTemplateMulti('js/routes/api', dir + '/routes', '*.js') + } + if (program.view) { // Copy view templates mkdir(dir, 'views') @@ -239,7 +245,7 @@ function createApplication (name, dir) { copyTemplateMulti('views', dir + '/views', '*.vash') break } - } else { + } else if (!program.api) { // Copy extra public files copyTemplate('js/index.html', path.join(dir, 'public/index.html')) } @@ -268,13 +274,20 @@ function createApplication (name, dir) { break } - // Index router mount - app.locals.localModules.indexRouter = './routes/index' - app.locals.mounts.push({ path: '/', code: 'indexRouter' }) + if(!program.api) { + // Index router mount + app.locals.localModules.indexRouter = './routes/index' + app.locals.mounts.push({ path: '/', code: 'indexRouter' }) - // User router mount - app.locals.localModules.usersRouter = './routes/users' - app.locals.mounts.push({ path: '/users', code: 'usersRouter' }) + // User router mount + app.locals.localModules.usersRouter = './routes/users' + app.locals.mounts.push({ path: '/users', code: 'usersRouter' }) + } + else { + // Value router mounte + app.locals.localModules.apiRouter = './routes/values' + app.locals.mounts.push({ path: '/api', code: 'apiRouter'}) + } // Template support switch (program.view) { @@ -460,11 +473,14 @@ function main () { } // Default view engine - if (program.view === true) { + if (program.view === true && !program.api) { warning('the default view engine will not be jade in future releases\n' + "use `--view=jade' or `--help' for additional options") program.view = 'jade' } + else if (program.api) { + program.view = false; + } // Generate application emptyDirectory(destinationPath, function (empty) { diff --git a/templates/js/routes/api/values.js b/templates/js/routes/api/values.js new file mode 100644 index 00000000..f3652e0e --- /dev/null +++ b/templates/js/routes/api/values.js @@ -0,0 +1,29 @@ +var express = require('express'); +var router = express.Router(); + +/* GET values */ +router.get('/values', function(req, res, next) { + res.json(['value1', 'value2']); +}); + +/* GET values/5 */ +router.get('/values/:id', function(req, res, next) { + res.send('value'); +}); + +/* POST values */ +router.post('/values', function(req, res, next) { + res.send(); +}); + +/* PUT values/5 */ +router.put('/values/:id', function(req, res, next) { + res.send(); +}); + +/* DELETE values/5 */ +router.delete('/values/:id', function(req, res, next) { + res.send(); +}); + +module.exports = router; \ No newline at end of file From 58cc8247688782128978fe38fb338b73bd253ecf Mon Sep 17 00:00:00 2001 From: iphayao Date: Sun, 10 Jun 2018 00:42:31 +0700 Subject: [PATCH 2/8] test/gen: add web api test and fixed response error as json --- bin/express-cli.js | 2 ++ templates/js/app.js.ejs | 9 +++-- test/cmd.js | 80 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 2 deletions(-) diff --git a/bin/express-cli.js b/bin/express-cli.js index 38d895db..a2f1f41a 100755 --- a/bin/express-cli.js +++ b/bin/express-cli.js @@ -332,6 +332,8 @@ function createApplication (name, dir) { break } + app.locals.api = program.api + // Static files app.locals.uses.push("express.static(path.join(__dirname, 'public'))") diff --git a/templates/js/app.js.ejs b/templates/js/app.js.ejs index 2ef75aec..27ef199d 100644 --- a/templates/js/app.js.ejs +++ b/templates/js/app.js.ejs @@ -1,4 +1,4 @@ -<% if (view) { -%> +<% if (view || api) { -%> var createError = require('http-errors'); <% } -%> var express = require('express'); @@ -30,7 +30,7 @@ app.use(<%- use %>); app.use(<%= mount.path %>, <%- mount.code %>); <% }); -%> -<% if (view) { -%> +<% if (view || api) { -%> // catch 404 and forward to error handler app.use(function(req, res, next) { next(createError(404)); @@ -44,7 +44,12 @@ app.use(function(err, req, res, next) { // render the error page res.status(err.status || 500); + <% if (view) { -%> res.render('error'); + <% } -%> + <% if (api) { -%> + res.json({ 'message' : err.message }); + <% } -%> }); <% } -%> diff --git a/test/cmd.js b/test/cmd.js index 1749afdd..15e9e149 100644 --- a/test/cmd.js +++ b/test/cmd.js @@ -578,6 +578,86 @@ describe('express(1)', function () { }) }) + describe('--api', function () { + var ctx = setupTestEnvironment(this.fullTitle()) + + it('should create web api app without view engine', function (done) { + run(ctx.dir, ['--api'], function (err, stdout) { + if (err) return done(err) + ctx.files = utils.parseCreatedFiles(stdout, ctx.dir) + assert.equal(ctx.files.length, 11) + done() + }) + }) + + it('should have basic files', function () { + assert.notEqual(ctx.files.indexOf('bin/www'), -1) + assert.notEqual(ctx.files.indexOf('app.js'), -1) + assert.notEqual(ctx.files.indexOf('package.json'), -1) + }) + + it('should not have views directory', function () { + assert.equal(ctx.files.indexOf('views'), -1) + }) + + it('should have installable dependencies', function (done) { + this.timeout(NPM_INSTALL_TIMEOUT) + npmInstall(ctx.dir, done) + }) + + describe('npm start', function () { + before('start app', function () { + this.app = new AppRunner(ctx.dir) + }) + + after('stop app', function (done) { + this.timeout(APP_START_STOP_TIMEOUT) + this.app.stop(done) + }) + + it('should start app', function (done) { + this.timeout(APP_START_STOP_TIMEOUT) + this.app.start(done) + }) + + it('should respond to HTTP GET request', function (done) { + request(this.app) + .get('/api/values') + .expect(200, ['value1', 'value2'], done) + }) + + it('should respond to HTTP GET request with id', function (done) { + request(this.app) + .get('/api/values/5') + .expect(200, 'value', done) + }) + + it('should respond to HTTP POST request', function (done) { + request(this.app) + .post('/api/values') + .expect(200, '', done) + }) + + it('should respond to HTTP PUT request with id', function (done) { + request(this.app) + .put('/api/values/5') + .expect(200, '', done) + }) + + it('should respond to HTTP DELETE request with id', function (done) { + request(this.app) + .delete('/api/values/5') + .expect(200, '', done) + }) + + it('should generate a 404', function (done) { + request(this.app) + .get('/api/does_not_exist') + .expect(404, {"message": "Not Found"}, done) + }) + }) + }) + describe('--pug', function () { var ctx = setupTestEnvironment(this.fullTitle()) From 922519df61da2362f1f0b1a5ff620c18655a7b92 Mon Sep 17 00:00:00 2001 From: iphayao Date: Sun, 10 Jun 2018 08:13:20 +0700 Subject: [PATCH 3/8] gen: fix http-errors dependency for web api --- bin/express-cli.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/express-cli.js b/bin/express-cli.js index a2f1f41a..2326d2d7 100755 --- a/bin/express-cli.js +++ b/bin/express-cli.js @@ -245,7 +245,10 @@ function createApplication (name, dir) { copyTemplateMulti('views', dir + '/views', '*.vash') break } - } else if (!program.api) { + } else if (program.api) { + // Add http-errors dependencies + pkg.dependencies['http-errors'] = '~1.6.2' + } else { // Copy extra public files copyTemplate('js/index.html', path.join(dir, 'public/index.html')) } From 89cac19b0d339294a199deb2ecef41bb067548b2 Mon Sep 17 00:00:00 2001 From: iphayao Date: Sun, 10 Jun 2018 08:51:46 +0700 Subject: [PATCH 4/8] lint: fixed lint from added web api --- bin/express-cli.js | 19 ++++++++----------- test/cmd.js | 2 +- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/bin/express-cli.js b/bin/express-cli.js index 2326d2d7..d6d7dbff 100755 --- a/bin/express-cli.js +++ b/bin/express-cli.js @@ -208,13 +208,12 @@ function createApplication (name, dir) { // copy route templates mkdir(dir, 'routes') - if(!program.api) { + if (!program.api) { copyTemplateMulti('js/routes', dir + '/routes', '*.js') - } - else { + } else { copyTemplateMulti('js/routes/api', dir + '/routes', '*.js') } - + if (program.view) { // Copy view templates mkdir(dir, 'views') @@ -277,7 +276,7 @@ function createApplication (name, dir) { break } - if(!program.api) { + if (!program.api) { // Index router mount app.locals.localModules.indexRouter = './routes/index' app.locals.mounts.push({ path: '/', code: 'indexRouter' }) @@ -285,11 +284,10 @@ function createApplication (name, dir) { // User router mount app.locals.localModules.usersRouter = './routes/users' app.locals.mounts.push({ path: '/users', code: 'usersRouter' }) - } - else { + } else { // Value router mounte app.locals.localModules.apiRouter = './routes/values' - app.locals.mounts.push({ path: '/api', code: 'apiRouter'}) + app.locals.mounts.push({ path: '/api', code: 'apiRouter' }) } // Template support @@ -482,9 +480,8 @@ function main () { warning('the default view engine will not be jade in future releases\n' + "use `--view=jade' or `--help' for additional options") program.view = 'jade' - } - else if (program.api) { - program.view = false; + } else if (program.api) { + program.view = false } // Generate application diff --git a/test/cmd.js b/test/cmd.js index 15e9e149..ee792ee2 100644 --- a/test/cmd.js +++ b/test/cmd.js @@ -653,7 +653,7 @@ describe('express(1)', function () { it('should generate a 404', function (done) { request(this.app) .get('/api/does_not_exist') - .expect(404, {"message": "Not Found"}, done) + .expect(404, {'message': 'Not Found'}, done) }) }) }) From 24c216877dd9ef55d3ce52e5fbec535e188ab169 Mon Sep 17 00:00:00 2001 From: iphayao Date: Sun, 10 Jun 2018 09:57:30 +0700 Subject: [PATCH 5/8] docs: update options in readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ca18976e..94f62926 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ This generator can also be further configured with the following command line fl -H, --hogan add hogan.js engine support -v, --view add view support (dust|ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade) --no-view use static html instead of view engine + -a, --api use web api template -c, --css add stylesheet support (less|stylus|compass|sass) (defaults to plain css) --git add .gitignore -f, --force force on non-empty directory From 2131f2d9819c5397dbac0a5b9ca3168d5d5c6636 Mon Sep 17 00:00:00 2001 From: iphayao Date: Sat, 18 Jan 2020 15:42:35 +0700 Subject: [PATCH 6/8] gen: fixed comment typo --- bin/express-cli.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/express-cli.js b/bin/express-cli.js index d6d7dbff..b66f2de0 100755 --- a/bin/express-cli.js +++ b/bin/express-cli.js @@ -285,7 +285,7 @@ function createApplication (name, dir) { app.locals.localModules.usersRouter = './routes/users' app.locals.mounts.push({ path: '/users', code: 'usersRouter' }) } else { - // Value router mounte + // Value router mount app.locals.localModules.apiRouter = './routes/values' app.locals.mounts.push({ path: '/api', code: 'apiRouter' }) } From bde2daec2a97014cfd8f224c65eb26b850d3bb97 Mon Sep 17 00:00:00 2001 From: iphayao Date: Sat, 18 Jan 2020 16:02:07 +0700 Subject: [PATCH 7/8] docs:update description of api option --- README.md | 2 +- bin/express-cli.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 94f62926..062b6ebf 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ This generator can also be further configured with the following command line fl -H, --hogan add hogan.js engine support -v, --view add view support (dust|ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade) --no-view use static html instead of view engine - -a, --api use web api template + -a, --api use web api template without view engine -c, --css add stylesheet support (less|stylus|compass|sass) (defaults to plain css) --git add .gitignore -f, --force force on non-empty directory diff --git a/bin/express-cli.js b/bin/express-cli.js index b66f2de0..b0b34c50 100755 --- a/bin/express-cli.js +++ b/bin/express-cli.js @@ -54,7 +54,7 @@ program .option('-H, --hogan', 'add hogan.js engine support', renamedOption('--hogan', '--view=hogan')) .option('-v, --view ', 'add view support (dust|ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)') .option(' --no-view', 'use static html instead of view engine') - .option('-a, --api', 'use web api template') + .option('-a, --api', 'use web api template without view engine') .option('-c, --css ', 'add stylesheet support (less|stylus|compass|sass) (defaults to plain css)') .option(' --git', 'add .gitignore') .option('-f, --force', 'force on non-empty directory') From 31a0cbfbc45856c30438e7584b61ad034658a298 Mon Sep 17 00:00:00 2001 From: iphayao Date: Sat, 18 Jan 2020 20:23:59 +0700 Subject: [PATCH 8/8] tests: fixed unit test --- test/cmd.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/cmd.js b/test/cmd.js index ccef18dc..a80776a3 100644 --- a/test/cmd.js +++ b/test/cmd.js @@ -640,19 +640,19 @@ describe('express(1)', function () { run(ctx.dir, ['--api'], function (err, stdout) { if (err) return done(err) ctx.files = utils.parseCreatedFiles(stdout, ctx.dir) - assert.equal(ctx.files.length, 11) + assert.strictEqual(ctx.files.length, 11) done() }) }) it('should have basic files', function () { - assert.notEqual(ctx.files.indexOf('bin/www'), -1) - assert.notEqual(ctx.files.indexOf('app.js'), -1) - assert.notEqual(ctx.files.indexOf('package.json'), -1) + assert.notStrictEqual(ctx.files.indexOf('bin/www'), -1) + assert.notStrictEqual(ctx.files.indexOf('app.js'), -1) + assert.notStrictEqual(ctx.files.indexOf('package.json'), -1) }) it('should not have views directory', function () { - assert.equal(ctx.files.indexOf('views'), -1) + assert.strictEqual(ctx.files.indexOf('views'), -1) }) it('should have installable dependencies', function (done) { @@ -708,7 +708,7 @@ describe('express(1)', function () { it('should generate a 404', function (done) { request(this.app) .get('/api/does_not_exist') - .expect(404, {'message': 'Not Found'}, done) + .expect(404, { 'message': 'Not Found' }, done) }) }) })