diff --git a/app/index.js b/app/index.js index 6e4724801..194b337a6 100644 --- a/app/index.js +++ b/app/index.js @@ -78,6 +78,13 @@ var AngularFullstackGenerator = yeoman.generators.Base.extend({ return filterMap[val]; } + }, { + type: "confirm", + name: "babel", + message: "Would you like to use Javascript ES6 in your client by preprocessing it with Babel?", + when: function (answers) { + return answers.script === 'js'; + } }, { type: "list", name: "markup", @@ -110,6 +117,9 @@ var AngularFullstackGenerator = yeoman.generators.Base.extend({ return answers.bootstrap; } }], function (answers) { + + this.filters.babel = !!answers.babel; + if(this.filters.babel){ this.filters.js = true; } this.filters[answers.script] = true; this.filters[answers.markup] = true; this.filters[answers.stylesheet] = true; @@ -211,6 +221,7 @@ var AngularFullstackGenerator = yeoman.generators.Base.extend({ if(this.filters.ngroute) filters.push('ngroute'); if(this.filters.uirouter) filters.push('uirouter'); + if(this.filters.babel) extensions.push('babel'); if(this.filters.coffee) extensions.push('coffee'); if(this.filters.js) extensions.push('js'); if(this.filters.html) extensions.push('html'); diff --git a/app/templates/Gruntfile.js b/app/templates/Gruntfile.js index a0267aaa4..96a662066 100644 --- a/app/templates/Gruntfile.js +++ b/app/templates/Gruntfile.js @@ -127,6 +127,13 @@ module.exports = function (grunt) { '<%%= yeoman.client %>/{app,components}/**/*.spec.{coffee,litcoffee,coffee.md}' ], tasks: ['karma'] + },<% } %><% if(filters.babel) { %> + babel: { + files: [ + '<%%= yeoman.client %>/{app,components}/**/*.js', + '!<%%= yeoman.client %>/{app,components}/**/*.spec.js' + ], + tasks: ['babel'] },<% } %> gruntfile: { files: ['Gruntfile.js'] @@ -135,7 +142,11 @@ module.exports = function (grunt) { files: [ '{.tmp,<%%= yeoman.client %>}/{app,components}/**/*.css', '{.tmp,<%%= yeoman.client %>}/{app,components}/**/*.html', + <% if(filters.babel) { %> + '.tmp/{app,components}/**/*.js', + <% } else { %> '{.tmp,<%%= yeoman.client %>}/{app,components}/**/*.js', + <% } %> '!{.tmp,<%%= yeoman.client %>}{app,components}/**/*.spec.js', '!{.tmp,<%%= yeoman.client %>}/{app,components}/**/*.mock.js', '<%%= yeoman.client %>/assets/images/{,*//*}*.{png,jpg,jpeg,gif,webp,svg}' @@ -442,14 +453,16 @@ module.exports = function (grunt) { // Run some tasks in parallel to speed up the build process concurrent: { server: [<% if(filters.coffee) { %> - 'coffee',<% } %><% if(filters.jade) { %> + 'coffee',<% } %><% if(filters.babel) { %> + 'babel',<% } %><% if(filters.jade) { %> 'jade',<% } %><% if(filters.stylus) { %> 'stylus',<% } %><% if(filters.sass) { %> 'sass',<% } %><% if(filters.less) { %> 'less',<% } %> ], test: [<% if(filters.coffee) { %> - 'coffee',<% } %><% if(filters.jade) { %> + 'coffee',<% } %><% if(filters.babel) { %> + 'babel',<% } %><% if(filters.jade) { %> 'jade',<% } %><% if(filters.stylus) { %> 'stylus',<% } %><% if(filters.sass) { %> 'sass',<% } %><% if(filters.less) { %> @@ -465,7 +478,8 @@ module.exports = function (grunt) { } }, dist: [<% if(filters.coffee) { %> - 'coffee',<% } %><% if(filters.jade) { %> + 'coffee',<% } %><% if(filters.babel) { %> + 'babel',<% } %><% if(filters.jade) { %> 'jade',<% } %><% if(filters.stylus) { %> 'stylus',<% } %><% if(filters.sass) { %> 'sass',<% } %><% if(filters.less) { %> @@ -551,6 +565,24 @@ module.exports = function (grunt) { ext: '.js' }] } + },<% } %><% if(filters.babel) { %> + + // Compiles ES6 to JavaScript using Babel + babel: { + options: { + sourceMap: true + }, + server: { + files: [{ + expand: true, + cwd: 'client', + src: [ + '{app,components}/**/*.js', + '!{app,components}/**/*.spec.js' + ], + dest: '.tmp' + }] + } },<% } %><% if(filters.stylus) { %> // Compiles Stylus to CSS @@ -620,10 +652,16 @@ module.exports = function (grunt) { }, files: { '<%%= yeoman.client %>/index.html': [ - ['{.tmp,<%%= yeoman.client %>}/{app,components}/**/*.js', - '!{.tmp,<%%= yeoman.client %>}/app/app.js', - '!{.tmp,<%%= yeoman.client %>}/{app,components}/**/*.spec.js', - '!{.tmp,<%%= yeoman.client %>}/{app,components}/**/*.mock.js'] + [ + <% if(filters.babel) { %> + '.tmp/{app,components}/**/*.js', + <% } else { %> + '{.tmp,<%%= yeoman.client %>}/{app,components}/**/*.js', + <% } %> + '!{.tmp,<%%= yeoman.client %>}/app/app.js', + '!{.tmp,<%%= yeoman.client %>}/{app,components}/**/*.spec.js', + '!{.tmp,<%%= yeoman.client %>}/{app,components}/**/*.mock.js' + ] ] } },<% if(filters.stylus) { %> diff --git a/app/templates/_.gitignore b/app/templates/_.gitignore index 6b4afbb0f..a5f8174b5 100644 --- a/app/templates/_.gitignore +++ b/app/templates/_.gitignore @@ -5,4 +5,5 @@ public .idea client/bower_components dist -/server/config/local.env.js \ No newline at end of file +/server/config/local.env.js +npm-debug.log diff --git a/app/templates/_package.json b/app/templates/_package.json index b19b58813..207100bff 100644 --- a/app/templates/_package.json +++ b/app/templates/_package.json @@ -45,7 +45,8 @@ "grunt-contrib-watch": "~0.6.1",<% if(filters.coffee) { %> "grunt-contrib-coffee": "^0.10.1",<% } %><% if(filters.jade) { %> "grunt-contrib-jade": "^0.11.0",<% } %><% if(filters.less) { %> - "grunt-contrib-less": "^0.11.0",<% } %> + "grunt-contrib-less": "^0.11.0",<% } %><% if(filters.babel) { %> + "grunt-babel": "~5.0.0",<% } %> "grunt-google-cdn": "~0.4.0", "grunt-newer": "~0.7.0", "grunt-ng-annotate": "^0.2.3", diff --git a/app/templates/client/index.html b/app/templates/client/index.html index e823e372d..e9dcd5729 100644 --- a/app/templates/client/index.html +++ b/app/templates/client/index.html @@ -50,7 +50,11 @@ <% } %> + <% if(filters.babel) { %> + + <% } else { %> + <% } %> diff --git a/app/templates/server/api/thing/thing.controller.js b/app/templates/server/api/thing/thing.controller.js index ba84d6fc9..0adc6211c 100644 --- a/app/templates/server/api/thing/thing.controller.js +++ b/app/templates/server/api/thing/thing.controller.js @@ -37,7 +37,7 @@ exports.index = function(req, res) {<% if (!filters.mongoose) { %> ]);<% } %><% if (filters.mongoose) { %> Thing.find(function (err, things) { if(err) { return handleError(res, err); } - return res.json(200, things); + return res.status(200).json(things); });<% } %> };<% if (filters.mongoose) { %> @@ -45,7 +45,7 @@ exports.index = function(req, res) {<% if (!filters.mongoose) { %> exports.show = function(req, res) { Thing.findById(req.params.id, function (err, thing) { if(err) { return handleError(res, err); } - if(!thing) { return res.send(404); } + if(!thing) { return res.status(404).send('Not Found'); } return res.json(thing); }); }; @@ -54,7 +54,7 @@ exports.show = function(req, res) { exports.create = function(req, res) { Thing.create(req.body, function(err, thing) { if(err) { return handleError(res, err); } - return res.json(201, thing); + return res.status(201).json(thing); }); }; @@ -63,11 +63,11 @@ exports.update = function(req, res) { if(req.body._id) { delete req.body._id; } Thing.findById(req.params.id, function (err, thing) { if (err) { return handleError(res, err); } - if(!thing) { return res.send(404); } + if(!thing) { return res.status(404).send('Not Found'); } var updated = _.merge(thing, req.body); updated.save(function (err) { if (err) { return handleError(res, err); } - return res.json(200, thing); + return res.status(200).json(thing); }); }); }; @@ -76,14 +76,14 @@ exports.update = function(req, res) { exports.destroy = function(req, res) { Thing.findById(req.params.id, function (err, thing) { if(err) { return handleError(res, err); } - if(!thing) { return res.send(404); } + if(!thing) { return res.status(404).send('Not Found'); } thing.remove(function(err) { if(err) { return handleError(res, err); } - return res.send(204); + return res.status(204).send('No Content'); }); }); }; function handleError(res, err) { - return res.send(500, err); + return res.status(500).send(err); }<% } %> \ No newline at end of file diff --git a/app/templates/server/api/user(auth)/user.controller.js b/app/templates/server/api/user(auth)/user.controller.js index f4cd10c29..585e47b67 100644 --- a/app/templates/server/api/user(auth)/user.controller.js +++ b/app/templates/server/api/user(auth)/user.controller.js @@ -6,7 +6,7 @@ var config = require('../../config/environment'); var jwt = require('jsonwebtoken'); var validationError = function(res, err) { - return res.json(422, err); + return res.status(422).json(err); }; /** @@ -15,8 +15,8 @@ var validationError = function(res, err) { */ exports.index = function(req, res) { User.find({}, '-salt -hashedPassword', function (err, users) { - if(err) return res.send(500, err); - res.json(200, users); + if(err) return res.status(500).send(err); + res.status(200).json(users); }); }; @@ -42,7 +42,7 @@ exports.show = function (req, res, next) { User.findById(userId, function (err, user) { if (err) return next(err); - if (!user) return res.send(401); + if (!user) return res.status(401).send('Unauthorized'); res.json(user.profile); }); }; @@ -53,8 +53,8 @@ exports.show = function (req, res, next) { */ exports.destroy = function(req, res) { User.findByIdAndRemove(req.params.id, function(err, user) { - if(err) return res.send(500, err); - return res.send(204); + if(err) return res.status(500).send(err); + return res.status(204).send('No Content'); }); }; @@ -71,10 +71,10 @@ exports.changePassword = function(req, res, next) { user.password = newPass; user.save(function(err) { if (err) return validationError(res, err); - res.send(200); + res.status(200).send('OK'); }); } else { - res.send(403); + res.status(403).send('Forbidden'); } }); }; @@ -88,7 +88,7 @@ exports.me = function(req, res, next) { _id: userId }, '-salt -hashedPassword', function(err, user) { // don't ever give out the password or salt if (err) return next(err); - if (!user) return res.json(401); + if (!user) return res.status(401).send('Unauthorized'); res.json(user); }); }; diff --git a/app/templates/server/app.js b/app/templates/server/app.js index 08b942f43..f677d7a43 100644 --- a/app/templates/server/app.js +++ b/app/templates/server/app.js @@ -13,7 +13,11 @@ var config = require('./config/environment'); <% if (filters.mongoose) { %> // Connect to database mongoose.connect(config.mongo.uri, config.mongo.options); - +mongoose.connection.on('error', function(err) { + console.error('MongoDB connection error: ' + err); + process.exit(-1); + } +); // Populate DB with sample data if(config.seedDB) { require('./config/seed'); } @@ -21,7 +25,7 @@ if(config.seedDB) { require('./config/seed'); } var app = express(); var server = require('http').createServer(app);<% if (filters.socketio) { %> var socketio = require('socket.io')(server, { - serveClient: (config.env === 'production') ? false : true, + serveClient: config.env !== 'production', path: '/socket.io-client' }); require('./config/socketio')(socketio);<% } %> @@ -34,4 +38,4 @@ server.listen(config.port, config.ip, function () { }); // Expose app -exports = module.exports = app; \ No newline at end of file +exports = module.exports = app; diff --git a/app/templates/server/auth(auth)/auth.service.js b/app/templates/server/auth(auth)/auth.service.js index 38ec34302..370dac51e 100644 --- a/app/templates/server/auth(auth)/auth.service.js +++ b/app/templates/server/auth(auth)/auth.service.js @@ -27,7 +27,7 @@ function isAuthenticated() { .use(function(req, res, next) { User.findById(req.user._id, function (err, user) { if (err) return next(err); - if (!user) return res.send(401); + if (!user) return res.status(401).send('Unauthorized'); req.user = user; next(); @@ -48,7 +48,7 @@ function hasRole(roleRequired) { next(); } else { - res.send(403); + res.status(403).send('Forbidden'); } }); } @@ -64,7 +64,7 @@ function signToken(id) { * Set token cookie directly for oAuth strategies */ function setTokenCookie(req, res) { - if (!req.user) return res.json(404, { message: 'Something went wrong, please try again.'}); + if (!req.user) return res.status(404).json({ message: 'Something went wrong, please try again.'}); var token = signToken(req.user._id, req.user.role); res.cookie('token', JSON.stringify(token)); res.redirect('/'); diff --git a/app/templates/server/auth(auth)/facebook(facebookAuth)/passport.js b/app/templates/server/auth(auth)/facebook(facebookAuth)/passport.js index 90ae48939..54574efb6 100644 --- a/app/templates/server/auth(auth)/facebook(facebookAuth)/passport.js +++ b/app/templates/server/auth(auth)/facebook(facebookAuth)/passport.js @@ -25,8 +25,8 @@ exports.setup = function (User, config) { facebook: profile._json }); user.save(function(err) { - if (err) done(err); - return done(err, user); + if (err) return done(err); + done(err, user); }); } else { return done(err, user); @@ -34,4 +34,4 @@ exports.setup = function (User, config) { }) } )); -}; \ No newline at end of file +}; diff --git a/app/templates/server/auth(auth)/google(googleAuth)/passport.js b/app/templates/server/auth(auth)/google(googleAuth)/passport.js index d304e8ac9..c9754c83a 100644 --- a/app/templates/server/auth(auth)/google(googleAuth)/passport.js +++ b/app/templates/server/auth(auth)/google(googleAuth)/passport.js @@ -21,8 +21,8 @@ exports.setup = function (User, config) { google: profile._json }); user.save(function(err) { - if (err) done(err); - return done(err, user); + if (err) return done(err); + done(err, user); }); } else { return done(err, user); diff --git a/app/templates/server/auth(auth)/local/index.js b/app/templates/server/auth(auth)/local/index.js index 8bf88a046..2e761a52d 100644 --- a/app/templates/server/auth(auth)/local/index.js +++ b/app/templates/server/auth(auth)/local/index.js @@ -9,8 +9,8 @@ var router = express.Router(); router.post('/', function(req, res, next) { passport.authenticate('local', function (err, user, info) { var error = err || info; - if (error) return res.json(401, error); - if (!user) return res.json(404, {message: 'Something went wrong, please try again.'}); + if (error) return res.status(401).json(error); + if (!user) return res.status(404).json({message: 'Something went wrong, please try again.'}); var token = auth.signToken(user._id, user.role); res.json({token: token}); diff --git a/app/templates/server/auth(auth)/twitter(twitterAuth)/passport.js b/app/templates/server/auth(auth)/twitter(twitterAuth)/passport.js index a2eb4a537..4544ce186 100644 --- a/app/templates/server/auth(auth)/twitter(twitterAuth)/passport.js +++ b/app/templates/server/auth(auth)/twitter(twitterAuth)/passport.js @@ -24,7 +24,7 @@ exports.setup = function (User, config) { }); user.save(function(err) { if (err) return done(err); - return done(err, user); + done(err, user); }); } else { return done(err, user); @@ -32,4 +32,4 @@ exports.setup = function (User, config) { }); } )); -}; \ No newline at end of file +}; diff --git a/endpoint/index.js b/endpoint/index.js index d67f78e51..2b3d7eb22 100644 --- a/endpoint/index.js +++ b/endpoint/index.js @@ -28,7 +28,7 @@ Generator.prototype.askFor = function askFor() { var prompts = [ { name: 'route', - message: 'What will the url of your endpoint to be?', + message: 'What will the url of your endpoint be?', default: base + name } ]; diff --git a/endpoint/templates/name.controller.js b/endpoint/templates/name.controller.js index 1d9da544e..3d46b2ad4 100644 --- a/endpoint/templates/name.controller.js +++ b/endpoint/templates/name.controller.js @@ -8,7 +8,7 @@ exports.index = function(req, res) {<% if (!filters.mongoose) { %> res.json([]);<% } %><% if (filters.mongoose) { %> <%= classedName %>.find(function (err, <%= name %>s) { if(err) { return handleError(res, err); } - return res.json(200, <%= name %>s); + return res.status(200).json(<%= name %>s); });<% } %> };<% if (filters.mongoose) { %> @@ -16,7 +16,7 @@ exports.index = function(req, res) {<% if (!filters.mongoose) { %> exports.show = function(req, res) { <%= classedName %>.findById(req.params.id, function (err, <%= name %>) { if(err) { return handleError(res, err); } - if(!<%= name %>) { return res.send(404); } + if(!<%= name %>) { return res.status(404).send('Not Found'); } return res.json(<%= name %>); }); }; @@ -25,7 +25,7 @@ exports.show = function(req, res) { exports.create = function(req, res) { <%= classedName %>.create(req.body, function(err, <%= name %>) { if(err) { return handleError(res, err); } - return res.json(201, <%= name %>); + return res.status(201).json(<%= name %>); }); }; @@ -34,11 +34,11 @@ exports.update = function(req, res) { if(req.body._id) { delete req.body._id; } <%= classedName %>.findById(req.params.id, function (err, <%= name %>) { if (err) { return handleError(res, err); } - if(!<%= name %>) { return res.send(404); } + if(!<%= name %>) { return res.status(404).send('Not Found'); } var updated = _.merge(<%= name %>, req.body); updated.save(function (err) { if (err) { return handleError(res, err); } - return res.json(200, <%= name %>); + return res.status(200).json(<%= name %>); }); }); }; @@ -47,14 +47,14 @@ exports.update = function(req, res) { exports.destroy = function(req, res) { <%= classedName %>.findById(req.params.id, function (err, <%= name %>) { if(err) { return handleError(res, err); } - if(!<%= name %>) { return res.send(404); } + if(!<%= name %>) { return res.status(404).send('Not Found'); } <%= name %>.remove(function(err) { if(err) { return handleError(res, err); } - return res.send(204); + return res.status(204).send('No Content'); }); }); }; function handleError(res, err) { - return res.send(500, err); + return res.status(500).send(err); }<% } %> \ No newline at end of file diff --git a/readme.md b/readme.md index 31836c2a2..209a6356b 100644 --- a/readme.md +++ b/readme.md @@ -94,7 +94,7 @@ Generates a new API endpoint. Example: ```bash yo angular-fullstack:endpoint message -[?] What will the url of your endpoint to be? /api/messages +[?] What will the url of your endpoint be? /api/messages ``` Produces: diff --git a/test/test-file-creation.js b/test/test-file-creation.js index 774a6f658..beb8b14b8 100644 --- a/test/test-file-creation.js +++ b/test/test-file-creation.js @@ -145,6 +145,49 @@ describe('angular-fullstack generator', function () { // }); }); + describe('with Babel ES6 preprocessor', function() { + beforeEach(function() { + helpers.mockPrompt(gen, { + script: 'js', + babel: true, + markup: 'jade', + stylesheet: 'less', + router: 'uirouter' + }); + }); + + it('should run client tests successfully', function(done) { + this.timeout(60000); + gen.run({}, function () { + exec('grunt test:client', function (error, stdout, stderr) { + expect(stdout, 'Client tests failed \n' + stdout ).to.contain('Executed 1 of 1\u001b[32m SUCCESS\u001b'); + done(); + }); + }); + }); + + it('should pass jshint', function(done) { + this.timeout(60000); + gen.run({}, function () { + exec('grunt jshint', function (error, stdout, stderr) { + expect(stdout).to.contain('Done, without errors.'); + done(); + }); + }); + }); + + it('should run server tests successfully', function(done) { + this.timeout(60000); + gen.run({}, function () { + exec('grunt test:server', function (error, stdout, stderr) { + expect(stdout, 'Server tests failed (do you have mongoDB running?) \n' + stdout).to.contain('Done, without errors.'); + done(); + }); + }); + }); + }); + + describe('with other preprocessors and oauth', function() { beforeEach(function() { helpers.mockPrompt(gen, {