diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2c7a63eaf..bf3937671 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,19 @@
+
+# [4.2.0](https://github.com/angular-fullstack/generator-angular-fullstack/compare/4.1.4...v4.2.0) (2017-04-19)
+
+## Notable Changes
+
+* `node-inspector` has been taken out in favor of Node's integrated `--inspect` flag.
+* @benmarten has taken care of a lot of the lint issues we've seen pulluting the console
+* @benmarten also enabled the use of (Yarn)[https://yarnpkg.com] if you have it installed. Thanks Ben!
+* Various other fixes. See the [comparison](https://github.com/angular-fullstack/generator-angular-fullstack/compare/4.1.4...4.2.0) for the full list.
+
+### Bug Fixes
+
+* **angular-validation-match:** Integration with Babel & Typescript ([#2517](https://github.com/angular-fullstack/generator-angular-fullstack/issues/2517)) ([9db9918](https://github.com/angular-fullstack/generator-angular-fullstack/commit/9db9918))
+
+
+
## [4.1.4](https://github.com/angular-fullstack/generator-angular-fullstack/compare/4.1.2...v4.1.4) (2017-03-01)
diff --git a/angular-fullstack-deps b/angular-fullstack-deps
index 1fee2d68f..a654f8f36 160000
--- a/angular-fullstack-deps
+++ b/angular-fullstack-deps
@@ -1 +1 @@
-Subproject commit 1fee2d68ff55a8ad8a3ba0efd908b5c5e5d6571d
+Subproject commit a654f8f36cf6efb8947f12c867f7a63bbf93d3ad
diff --git a/gulpfile.js b/gulpfile.js
index 768e6d419..f9afc6d36 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -148,7 +148,16 @@ gulp.task('installFixtures', function() {
}, 1 * 1000);
shell.cd('test/fixtures');
- execAsync('npm install --quiet', {cwd: '../fixtures'}).then(() => {
+ let installCommand;
+ if(process.platform === 'win32') {
+ installCommand = 'yarn --version >nul 2>&1 && ( yarn install ) || ( npm install --quiet )';
+ } else {
+ installCommand = 'type yarn &> /dev/null | yarn install || npm install --quiet';
+ }
+
+ execAsync(installCommand, {
+ cwd: '../fixtures'
+ }).then(() => {
process.stdout.write('\n');
if(!process.env.SAUCE_USERNAME) {
gutil.log('running npm run-script update-webdriver');
diff --git a/package.json b/package.json
index 9cfe6592d..7fe2b2c04 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "generator-angular-fullstack",
- "version": "4.1.4",
+ "version": "4.2.0",
"description": "Yeoman generator for creating MEAN stack applications, using MongoDB, Express, AngularJS, and Node",
"keywords": [
"yeoman-generator",
diff --git a/readme.md b/readme.md
index 2a26f85da..6d24535ab 100644
--- a/readme.md
+++ b/readme.md
@@ -1,5 +1,5 @@
# AngularJS Full-Stack generator
-
+[](https://angular-fullstack.github.io/)

[](https://www.npmjs.com/package/generator-angular-fullstack)
@@ -79,27 +79,27 @@ yo angular-fullstack
Available generators:
* App
- - [angular-fullstack](/docs/generators/app.md) (aka [angular-fullstack:app](/docs/generators/app.md))
+ - [angular-fullstack](https://angular-fullstack.github.io/generators/app/) (aka [angular-fullstack:app](https://angular-fullstack.github.io/generators/app/))
* Server Side
- - [angular-fullstack:endpoint](/docs/generators/endpoint.md)
+ - [angular-fullstack:endpoint](https://angular-fullstack.github.io/generators/endpoint)
* Client Side (via [generator-ng-component](https://github.com/DaftMonk/generator-ng-component))
- - [angular-fullstack:route](/docs/generators/route.md)
- - [angular-fullstack:component](/docs/generators/component.md)
- - [angular-fullstack:controller](/docs/generators/controller.md)
- - [angular-fullstack:filter](/docs/generators/filter.md)
- - [angular-fullstack:directive](/docs/generators/directive.md)
- - [angular-fullstack:service](/docs/generators/service.md)
- - [angular-fullstack:provider](/docs/generators/service.md)
- - [angular-fullstack:factory](/docs/generators/service.md)
- - [angular-fullstack:decorator](/docs/generators/decorator.md)
+ - [angular-fullstack:route](https://angular-fullstack.github.io/generators/route)
+ - [angular-fullstack:component](https://angular-fullstack.github.io/generators/component)
+ - [angular-fullstack:controller](https://angular-fullstack.github.io/generators/controller)
+ - [angular-fullstack:filter](https://angular-fullstack.github.io/generators/filter)
+ - [angular-fullstack:directive](https://angular-fullstack.github.io/generators/directive)
+ - [angular-fullstack:service](https://angular-fullstack.github.io/generators/service)
+ - [angular-fullstack:provider](https://angular-fullstack.github.io/generators/service)
+ - [angular-fullstack:factory](https://angular-fullstack.github.io/generators/service)
+ - [angular-fullstack:decorator](https://angular-fullstack.github.io/generators/decorator)
* Deployment
- - [angular-fullstack:openshift](/docs/generators/openshift.md)
- - [angular-fullstack:heroku](/docs/generators/heroku.md)
+ - [angular-fullstack:openshift](https://angular-fullstack.github.io/generators/openshift)
+ - [angular-fullstack:heroku](https://angular-fullstack.github.io/generators/heroku)
## Documentation
-Check out our [documentation home page](http://angular-fullstack.github.io/generator-angular-fullstack).
+Check out our [documentation home page](http://angular-fullstack.github.io/).
## Contribute
@@ -166,4 +166,4 @@ Is your company using Angular-FullStack? Ask your boss to support the project. Y
-
+[](https://angular-fullstack.github.io/)
diff --git a/src/generators/app/index.js b/src/generators/app/index.js
index d66e6f9c6..9c169d0ce 100644
--- a/src/generators/app/index.js
+++ b/src/generators/app/index.js
@@ -96,6 +96,7 @@ export class Generator extends Base {
},
info: function () {
this.log(this.yoWelcome);
+ this.log('Angular Fullstack v' + this.rootGeneratorVersion() +'\n');
this.log('Out of the box I create an AngularJS app with an Express server.\n');
},
checkForConfig: function() {
@@ -546,7 +547,8 @@ export class Generator extends Base {
['ngRoute', 'angular-route'],
['uiBootstrap', 'angular-ui-bootstrap'],
['ngMessages', 'angular-messages'],
- ['io', 'socket.io-client']
+ ['io', 'socket.io-client'],
+ ['ngValidationMatch', 'angular-validation-match']
];
function replacer(contents) {
modulesToFix.forEach(([moduleName, importName]) => {
@@ -604,7 +606,15 @@ export class Generator extends Base {
install() {
if(!this.options['skip-install']) {
- this.spawnCommand('npm', ['install']);
+ let yarnCheckCommand;
+ if (process.platform === 'win32') {
+ yarnCheckCommand = 'yarn --version >nul 2>&1';
+ } else {
+ yarnCheckCommand = 'type yarn &> /dev/null';
+ }
+ exec(yarnCheckCommand, (error, stdout, stderr) => {
+ return this.spawnCommand((!error) ? 'yarn' : 'npm', ['install']);
+ });
}
}
diff --git a/templates/app/.eslintrc b/templates/app/.eslintrc
index 93dbcc287..28a8da424 100644
--- a/templates/app/.eslintrc
+++ b/templates/app/.eslintrc
@@ -82,7 +82,7 @@
"no-octal-escape": 0, //disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251";
"no-octal": 0, //disallow use of octal literals
"no-param-reassign": 0, //disallow reassignment of function parameters
- "no-process-env": 1, //disallow use of process.env
+ "no-process-env": 0, //disallow use of process.env
"no-proto": 2, //disallow usage of __proto__ property
"no-redeclare": 2, //disallow declaring the same variable more than once
"no-return-assign": 2, //disallow use of assignment in return statement
diff --git a/templates/app/_package.json b/templates/app/_package.json
index 7cb086235..6d6ff0091 100644
--- a/templates/app/_package.json
+++ b/templates/app/_package.json
@@ -22,7 +22,7 @@
<%# END CLIENT %>
"core-js": "^2.2.1",
"express": "^4.13.3",
- "morgan": "~1.7.0",
+ "morgan": "^1.8.0",
"body-parser": "^1.13.3",
"method-override": "^2.3.5",
"cookie-parser": "^1.3.5",
@@ -92,7 +92,6 @@
"gulp-istanbul-enforcer": "^1.0.3",
"gulp-load-plugins": "^1.0.0-rc.1",
"gulp-mocha": "^2.1.3",
- "gulp-node-inspector": "^0.1.0",
"gulp-plumber": "^1.0.1",
"gulp-protractor": "^3.0.0",
"gulp-rev": "^7.0.0",
diff --git a/templates/app/client/app/app.js b/templates/app/client/app/app.js
index 2937399dd..cda6907e9 100644
--- a/templates/app/client/app/app.js
+++ b/templates/app/client/app/app.js
@@ -4,6 +4,7 @@ import angular from 'angular';
import ngCookies from 'angular-cookies';
import ngResource from 'angular-resource';
import ngSanitize from 'angular-sanitize';
+
<%_ if(filters.socketio) { _%>
import 'angular-socket-io';<% } %>
<%_ if(filters.ngroute) { _%>
@@ -12,9 +13,9 @@ const ngRoute = require('angular-route');<% } %>
import uiRouter from 'angular-ui-router';<% } %>
<%_ if(filters.uibootstrap) { _%>
import uiBootstrap from 'angular-ui-bootstrap';<% } %>
-// import ngMessages from 'angular-messages';
<%_ if(filters.auth) { _%>
-// import ngValidationMatch from 'angular-validation-match';<% } %>
+import 'angular-validation-match';
+<% } %>
import {routeConfig} from './app.config';
@@ -49,7 +50,9 @@ angular.module('<%= scriptAppName %>', [
<%_ if(filters.auth) { %>
_Auth,
account,
- admin,<% } _%>
+ admin,
+ 'validation.match',
+ <% } _%>
navbar,
footer,
main,
diff --git a/templates/app/client/components/auth(auth)/auth.service.js b/templates/app/client/components/auth(auth)/auth.service.js
index e38a12632..b4fc54758 100644
--- a/templates/app/client/components/auth(auth)/auth.service.js
+++ b/templates/app/client/components/auth(auth)/auth.service.js
@@ -1,4 +1,7 @@
'use strict';
+
+import _ from 'lodash';
+
// @flow
class _User {
_id: string = '';
@@ -185,9 +188,8 @@ export function AuthService($location, $http, $cookies, $q, appConfig, Util, Use
* @param {Function|*} callback - optional, function(is)
* @return {Bool|Promise}
*/
- isAdmin() {
- return Auth.hasRole
- .apply(Auth, [].concat.apply(['admin'], arguments));
+ isAdmin(...args) {
+ return Auth.hasRole(...Reflect.apply([].concat, ['admin'], args));
},
/**
@@ -196,6 +198,7 @@ export function AuthService($location, $http, $cookies, $q, appConfig, Util, Use
* @return {Bool}
*/
isAdminSync() {
+ // eslint-disable-next-line no-sync
return Auth.hasRoleSync('admin');
},
diff --git a/templates/app/client/components/modal(uibootstrap)/modal.service.js b/templates/app/client/components/modal(uibootstrap)/modal.service.js
index 31de851db..5dff0da27 100644
--- a/templates/app/client/components/modal(uibootstrap)/modal.service.js
+++ b/templates/app/client/components/modal(uibootstrap)/modal.service.js
@@ -37,9 +37,9 @@ export function Modal($rootScope, $uibModal) {
* @param {String} name - name or info to show on modal
* @param {All} - any additional args are passed straight to del callback
*/
- return function() {
- var args = Array.prototype.slice.call(arguments);
- var name = args.shift();
+ return function(...args) {
+ var slicedArgs = Reflect.apply(Array.prototype.slice, args);
+ var name = slicedArgs.shift();
var deleteModal;
deleteModal = openModal({
@@ -64,7 +64,7 @@ export function Modal($rootScope, $uibModal) {
}, 'modal-danger');
deleteModal.result.then(function(event) {
- del.apply(event, args);
+ Reflect.apply(del, event, slicedArgs);
});
};
}
diff --git a/templates/app/gulpfile.babel.js b/templates/app/gulpfile.babel.js
index 4e6db6421..357ef8d35 100644
--- a/templates/app/gulpfile.babel.js
+++ b/templates/app/gulpfile.babel.js
@@ -331,17 +331,11 @@ gulp.task('start:server:prod', () => {
.on('log', onServerLog);
});
-gulp.task('start:inspector', () => {
- gulp.src([])
- .pipe(plugins.nodeInspector({
- debugPort: <%= debugPort %>
- }));
-});
-
gulp.task('start:server:debug', () => {
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
config = require(`./${serverPath}/config/environment`);
- nodemon(`-w ${serverPath} --debug=<%= debugPort %> --debug-brk ${serverPath}`)
+ // nodemon(`-w ${serverPath} --debug=<%= debugPort %> --debug-brk ${serverPath}`)
+ nodemon(`-w ${serverPath} --inspect --debug-brk ${serverPath}`)
.on('log', onServerLog);
});
@@ -385,7 +379,6 @@ gulp.task('serve:debug', cb => {
'typings'<% } %>
],
'webpack:dev',
- 'start:inspector',
['start:server:debug', 'start:client'],
'watch',
cb
diff --git a/templates/app/server/api/user(auth)/user.model(mongooseModels).js b/templates/app/server/api/user(auth)/user.model(mongooseModels).js
index b19e3ff36..c62104f0b 100644
--- a/templates/app/server/api/user(auth)/user.model(mongooseModels).js
+++ b/templates/app/server/api/user(auth)/user.model(mongooseModels).js
@@ -99,10 +99,10 @@ UserSchema
// Validate email is not taken
UserSchema
.path('email')
- .validate(function(value, respond) {
+ .validate(function(value) {
<%_ if(filters.oauth) { -%>
if(authTypes.indexOf(this.provider) !== -1) {
- return respond(true);
+ return true;
}
<%_ } -%>
@@ -110,11 +110,11 @@ UserSchema
.then(user => {
if(user) {
if(this.id === user.id) {
- return respond(true);
+ return true;
}
- return respond(false);
+ return false;
}
- return respond(true);
+ return true;
})
.catch(function(err) {
throw err;
@@ -197,14 +197,16 @@ UserSchema.methods = {
* @return {String}
* @api public
*/
- makeSalt(byteSize, callback) {
- var defaultByteSize = 16;
+ makeSalt(...args) {
+ let byteSize;
+ let callback;
+ let defaultByteSize = 16;
- if(typeof arguments[0] === 'function') {
- callback = arguments[0];
+ if(typeof args[0] === 'function') {
+ callback = args[0];
byteSize = defaultByteSize;
- } else if(typeof arguments[1] === 'function') {
- callback = arguments[1];
+ } else if(typeof args[1] === 'function') {
+ callback = args[1];
} else {
throw new Error('Missing Callback');
}
@@ -244,17 +246,20 @@ UserSchema.methods = {
var salt = new Buffer(this.salt, 'base64');
if(!callback) {
- return crypto.pbkdf2Sync(password, salt, defaultIterations, defaultKeyLength)
+ // eslint-disable-next-line no-sync
+ return crypto.pbkdf2Sync(password, salt, defaultIterations,
+ defaultKeyLength, 'sha1')
.toString('base64');
}
- return crypto.pbkdf2(password, salt, defaultIterations, defaultKeyLength, (err, key) => {
- if(err) {
- return callback(err);
- } else {
- return callback(null, key.toString('base64'));
- }
- });
+ return crypto.pbkdf2(password, salt, defaultIterations, defaultKeyLength,
+ 'sha1', (err, key) => {
+ if(err) {
+ return callback(err);
+ } else {
+ return callback(null, key.toString('base64'));
+ }
+ });
}
};
diff --git a/templates/app/server/api/user(auth)/user.model(sequelizeModels).js b/templates/app/server/api/user(auth)/user.model(sequelizeModels).js
index 58e8f5ae2..991bc9403 100644
--- a/templates/app/server/api/user(auth)/user.model(sequelizeModels).js
+++ b/templates/app/server/api/user(auth)/user.model(sequelizeModels).js
@@ -135,8 +135,10 @@ export default function(sequelize, DataTypes) {
* @return {String}
* @api public
*/
- makeSalt(byteSize, callback) {
- var defaultByteSize = 16;
+ makeSalt(...args) {
+ let byteSize;
+ let callback;
+ let defaultByteSize = 16;
if(typeof arguments[0] === 'function') {
callback = arguments[0];
@@ -177,6 +179,7 @@ export default function(sequelize, DataTypes) {
var salt = new Buffer(this.salt, 'base64');
if(!callback) {
+ // eslint-disable-next-line no-sync
return crypto.pbkdf2Sync(password, salt, defaultIterations, defaultKeyLength)
.toString('base64');
}
diff --git a/templates/app/server/config/seed(models).js b/templates/app/server/config/seed(models).js
index cd4f07d33..053b26c66 100644
--- a/templates/app/server/config/seed(models).js
+++ b/templates/app/server/config/seed(models).js
@@ -17,8 +17,8 @@ export default function seedDatabaseIfNeeded() {
<% if (filters.mongooseModels) { %>Thing.find({}).remove()<% }
if (filters.sequelizeModels) { %>return Thing.destroy({ where: {} })<% } %>
.then(() => {
- <% if (filters.mongooseModels) { %>Thing.create({<% }
- if (filters.sequelizeModels) { %>return Thing.bulkCreate([{<% } %>
+ <% if (filters.mongooseModels) { %>let thing = Thing.create({<% }
+ if (filters.sequelizeModels) { %>let thing = Thing.bulkCreate([{<% } %>
name: 'Development Tools',
info: 'Integration with popular tools such as Webpack, Gulp, Babel, TypeScript, Karma, '
+ 'Mocha, ESLint, Node Inspector, Livereload, Protractor, Pug, '
@@ -47,6 +47,7 @@ export default function seedDatabaseIfNeeded() {
+ 'and openshift subgenerators'
<% if (filters.mongooseModels) { %>});<% }
if (filters.sequelizeModels) { %>}]);<% } %>
+ return thing;
})
.then(() => console.log('finished populating things'))
.catch(err => console.log('error populating things', err));
diff --git a/templates/endpoint/basename.controller.js b/templates/endpoint/basename.controller.js
index a9b5fa74c..098f7d532 100644
--- a/templates/endpoint/basename.controller.js
+++ b/templates/endpoint/basename.controller.js
@@ -27,6 +27,7 @@ function respondWithResult(res, statusCode) {
function patchUpdates(patches) {
return function(entity) {
try {
+ // eslint-disable-next-line prefer-reflect
jsonpatch.apply(entity, patches, /*validate*/ true);
} catch(err) {
return Promise.reject(err);
@@ -98,7 +99,7 @@ export function create(req, res) {
// Upserts the given <%= classedName %> in the DB at the specified ID
export function upsert(req, res) {
if(req.body._id) {
- delete req.body._id;
+ Reflect.deleteProperty(req.body, '_id');
}
<%_ if(filters.mongooseModels) { -%>
return <%= classedName %>.findOneAndUpdate({_id: req.params.id}, req.body, {new: true, upsert: true, setDefaultsOnInsert: true, runValidators: true}).exec()<% } %>
@@ -115,7 +116,7 @@ export function upsert(req, res) {
// Updates an existing <%= classedName %> in the DB
export function patch(req, res) {
if(req.body._id) {
- delete req.body._id;
+ Reflect.deleteProperty(req.body, '_id');
}
<% if(filters.mongooseModels) { %>return <%= classedName %>.findById(req.params.id).exec()<% }
if(filters.sequelizeModels) { %>return <%= classedName %>.find({