diff --git a/.gitattributes b/.gitattributes
index 176a458f9..fcadb2cf9 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1 +1 @@
-* text=auto
+* text eol=lf
diff --git a/.gitignore b/.gitignore
index 9e436b36f..78a6835b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,5 +5,5 @@ demo
.idea
.DS_Store
release.txt
-fixtures/bower.json
-fixtures/package.json
\ No newline at end of file
+test/fixtures/bower.json
+test/fixtures/package.json
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 5100940c2..814f378a3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,15 +1,26 @@
+sudo: false
language: node_js
node_js:
- '0.12'
+env:
+ global:
+ - SAUCE_USERNAME=fullstack_ci
+ - SAUCE_ACCESS_KEY=1a527ca6-4aa5-4618-86ce-0278bf158cbf
before_install:
+ - ./scripts/sauce_connect_setup.sh
- gem update --system
- gem install sass --version "=3.3.7"
- npm install -g bower grunt-cli
services: mongodb
+cache:
+ directories:
+ - node_modules
+ - test/fixtures/node_modules
+ - test/fixtures/bower_components
notifications:
webhooks:
urls:
- - https://webhooks.gitter.im/e/911ed472ef19bcb27858
+ - secure: "DhPNqHXuUIeIGE9Ek3+63qhco+4MozXqMZL6dAKoq1MHQ2RAPO6SYIkUYZqDnuWYlwWao2EnTYcDREivIV/m/RnkP9bKlpX/n/RNJe+X4bwFaCU55fVKgkAFn3takSBC5SVoeTWHdWu3WhhqSdioWjT7mlE1wtt/RanSMb5Id8M="
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: false # default: false
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ced95fa81..9d265082f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -582,4 +582,4 @@ Closes #18, #17
#### Features
-* **gen:** include MongoDB as an option When selected, sets up database with Mongoose. Repl ([280cc84d](http://github.com/DaftMonk/generator-angular-fullstack/commit/280cc84d735c60b1c261540dceda34dd7f91c93c), closes [#2](http://github.com/DaftMonk/generator-angular-fullstack/issues/2))
\ No newline at end of file
+* **gen:** include MongoDB as an option When selected, sets up database with Mongoose. Repl ([280cc84d](http://github.com/DaftMonk/generator-angular-fullstack/commit/280cc84d735c60b1c261540dceda34dd7f91c93c), closes [#2](http://github.com/DaftMonk/generator-angular-fullstack/issues/2))
diff --git a/Gruntfile.js b/Gruntfile.js
index 9819a4041..38fc08efc 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,16 +1,19 @@
'use strict';
-var markdown = require('marked');
+
var semver = require('semver');
-var _s = require('underscore.string');
var shell = require('shelljs');
-var process = require('child_process');
+var child_process = require('child_process');
var Q = require('q');
var helpers = require('yeoman-generator').test;
-var fs = require('fs-extra');
+var fs = require('fs');
var path = require('path');
module.exports = function (grunt) {
- require('load-grunt-tasks')(grunt);
+ // Load grunt tasks automatically, when needed
+ require('jit-grunt')(grunt, {
+ buildcontrol: 'grunt-build-control',
+ changelog: 'grunt-conventional-changelog'
+ });
grunt.initConfig({
config: {
@@ -58,6 +61,11 @@ module.exports = function (grunt) {
},
all: ['Gruntfile.js', '*/index.js']
},
+ env: {
+ fast: {
+ SKIP_E2E: true
+ }
+ },
mochaTest: {
test: {
src: [
@@ -82,6 +90,16 @@ module.exports = function (grunt) {
]
}]
}
+ },
+ david: {
+ gen: {
+ options: {}
+ },
+ app: {
+ options: {
+ package: 'test/fixtures/package.json'
+ }
+ }
}
});
@@ -139,6 +157,7 @@ module.exports = function (grunt) {
bootstrap: true,
uibootstrap: true,
mongoose: true,
+ testing: 'jasmine',
auth: true,
oauth: ['googleAuth', 'twitterAuth'],
socketio: true
@@ -202,7 +221,6 @@ module.exports = function (grunt) {
});
grunt.registerTask('updateFixtures', 'updates package and bower fixtures', function() {
- var done = this.async();
var packageJson = fs.readFileSync(path.resolve('app/templates/_package.json'), 'utf8');
var bowerJson = fs.readFileSync(path.resolve('app/templates/_bower.json'), 'utf8');
@@ -215,11 +233,8 @@ module.exports = function (grunt) {
bowerJson = bowerJson.replace(/<%(.*)%>/g, '');
// save files
- fs.writeFile(path.resolve(__dirname + '/test/fixtures/package.json'), packageJson, function() {
- fs.writeFile(path.resolve(__dirname + '/test/fixtures/bower.json'), bowerJson, function() {
- done();
- });
- });
+ fs.writeFileSync(path.resolve(__dirname + '/test/fixtures/package.json'), packageJson);
+ fs.writeFileSync(path.resolve(__dirname + '/test/fixtures/bower.json'), bowerJson);
});
grunt.registerTask('installFixtures', 'install package and bower fixtures', function() {
@@ -227,12 +242,21 @@ module.exports = function (grunt) {
shell.cd('test/fixtures');
grunt.log.ok('installing npm dependencies for generated app');
- process.exec('npm install --quiet', {cwd: '../fixtures'}, function (error, stdout, stderr) {
+ child_process.exec('npm install --quiet', {cwd: '../fixtures'}, function (error, stdout, stderr) {
grunt.log.ok('installing bower dependencies for generated app');
- process.exec('bower install', {cwd: '../fixtures'}, function (error, stdout, stderr) {
- shell.cd('../../');
- done();
+ child_process.exec('bower install', {cwd: '../fixtures'}, function (error, stdout, stderr) {
+
+ if(!process.env.SAUCE_USERNAME) {
+ grunt.log.ok('running npm run update-webdriver');
+ child_process.exec('npm run update-webdriver', function() {
+ shell.cd('../../');
+ done();
+ });
+ } else {
+ shell.cd('../../');
+ done();
+ }
})
});
});
@@ -242,6 +266,24 @@ module.exports = function (grunt) {
'installFixtures',
'mochaTest'
]);
+ grunt.registerTask('test', function(target, option) {
+ if (target === 'fast') {
+ grunt.task.run([
+ 'env:fast'
+ ]);
+ }
+
+ return grunt.task.run([
+ 'updateFixtures',
+ 'installFixtures',
+ 'mochaTest'
+ ])
+ });
+
+ grunt.registerTask('deps', function(target) {
+ if (!target || target === 'app') grunt.task.run(['updateFixtures']);
+ grunt.task.run(['david:' + (target || '')]);
+ });
grunt.registerTask('demo', [
'clean:demo',
diff --git a/app/index.js b/app/index.js
index 194b337a6..ec954aa46 100644
--- a/app/index.js
+++ b/app/index.js
@@ -5,274 +5,415 @@ var util = require('util');
var genUtils = require('../util.js');
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
-var wiredep = require('wiredep');
var AngularFullstackGenerator = yeoman.generators.Base.extend({
- init: function () {
- this.argument('name', { type: String, required: false });
- this.appname = this.name || path.basename(process.cwd());
- this.appname = this._.camelize(this._.slugify(this._.humanize(this.appname)));
-
- this.option('app-suffix', {
- desc: 'Allow a custom suffix to be added to the module name',
- type: String,
- required: 'false'
- });
- this.scriptAppName = this.appname + genUtils.appName(this);
- this.appPath = this.env.options.appPath;
- this.pkg = require('../package.json');
-
- this.filters = {};
- },
+ initializing: {
- info: function () {
- this.log(this.yeoman);
- this.log('Out of the box I create an AngularJS app with an Express server.\n');
- },
+ init: function () {
+ this.argument('name', { type: String, required: false });
+ this.appname = this.name || path.basename(process.cwd());
+ this.appname = this._.camelize(this._.slugify(this._.humanize(this.appname)));
- checkForConfig: function() {
- var cb = this.async();
+ this.option('app-suffix', {
+ desc: 'Allow a custom suffix to be added to the module name',
+ type: String,
+ required: 'false'
+ });
+ this.scriptAppName = this.appname + genUtils.appName(this);
+ this.appPath = this.env.options.appPath;
+ this.pkg = require('../package.json');
- if(this.config.get('filters')) {
- this.prompt([{
- type: "confirm",
- name: "skipConfig",
- message: "Existing .yo-rc configuration found, would you like to use it?",
- default: true,
- }], function (answers) {
- this.skipConfig = answers.skipConfig;
+ this.filters = {};
+
+ // dynamic assertion statement
+ this.does = this.is = function(foo) {
+ foo = this.engine(foo.replace(/\(;>%%<;\)/g, '<%')
+ .replace(/\(;>%<;\)/g, '%>'), this);
+ if (this.filters.should) {
+ return foo + '.should';
+ } else {
+ return 'expect(' + foo + ').to';
+ }
+ }.bind(this);
+ },
- // NOTE: temp(?) fix for #403
- if(typeof this.oauth==='undefined') {
- var strategies = Object.keys(this.filters).filter(function(key) {
- return key.match(/Auth$/) && key;
+ info: function () {
+ this.log(this.welcome);
+ this.log('Out of the box I create an AngularJS app with an Express server.\n');
+ },
+
+ checkForConfig: function() {
+ var cb = this.async();
+
+ if(this.config.get('filters')) {
+ this.prompt([{
+ type: 'confirm',
+ name: 'skipConfig',
+ message: 'Existing .yo-rc configuration found, would you like to use it?',
+ default: true,
+ }], function (answers) {
+ this.skipConfig = answers.skipConfig;
+
+ this.filters = this._.defaults(this.config.get('filters'), {
+ bootstrap: true,
+ uibootstrap: true,
+ jasmine: true
});
- if(strategies.length) this.config.set('oauth', true);
- }
+ this.config.set('filters', this.filters);
+ this.config.forceSave();
+ cb();
+ }.bind(this));
+ } else {
cb();
- }.bind(this));
- } else {
- cb();
+ }
}
+
},
- clientPrompts: function() {
- if(this.skipConfig) return;
- var cb = this.async();
+ prompting: {
- this.log('# Client\n');
+ clientPrompts: function() {
+ if(this.skipConfig) return;
+ var cb = this.async();
- this.prompt([{
- type: "list",
- name: "script",
- message: "What would you like to write scripts with?",
- choices: [ "JavaScript", "CoffeeScript"],
- filter: function( val ) {
- var filterMap = {
- 'JavaScript': 'js',
- 'CoffeeScript': 'coffee'
- };
+ this.log('# Client\n');
- return filterMap[val];
+ this.prompt([{
+ type: 'list',
+ name: 'script',
+ message: 'What would you like to write scripts with?',
+ choices: [ 'JavaScript', 'JavaScript + Babel', 'CoffeeScript'],
+ filter: function( val ) {
+ return {
+ 'JavaScript': 'js',
+ 'JavaScript + Babel': 'babel',
+ 'CoffeeScript': 'coffee'
+ }[val];
+ }
+ }, {
+ type: 'list',
+ name: 'markup',
+ message: 'What would you like to write markup with?',
+ choices: ['HTML', 'Jade'],
+ filter: function( val ) { return val.toLowerCase(); }
+ }, {
+ type: 'list',
+ name: 'stylesheet',
+ default: 1,
+ message: 'What would you like to write stylesheets with?',
+ choices: [ 'CSS', 'Sass', 'Stylus', 'Less'],
+ filter: function( val ) { return val.toLowerCase(); }
+ }, {
+ type: 'list',
+ name: 'router',
+ default: 1,
+ message: 'What Angular router would you like to use?',
+ choices: [ 'ngRoute', 'uiRouter'],
+ filter: function( val ) { return val.toLowerCase(); }
+ }, {
+ type: 'confirm',
+ name: 'bootstrap',
+ message: 'Would you like to include Bootstrap?'
+ }, {
+ type: 'confirm',
+ name: 'uibootstrap',
+ message: 'Would you like to include UI Bootstrap?',
+ when: function (answers) {
+ return answers.bootstrap;
+ }
+ }], function (answers) {
+
+ // also set 'js' to true if using babel
+ if(answers.script === 'babel') { this.filters.js = true; }
+ this.filters[answers.script] = true;
+ this.filters[answers.markup] = true;
+ this.filters[answers.stylesheet] = true;
+ this.filters[answers.router] = true;
+ this.filters.bootstrap = !!answers.bootstrap;
+ this.filters.uibootstrap = !!answers.uibootstrap;
+ cb();
+ }.bind(this));
+ },
+
+ serverPrompts: function() {
+ if(this.skipConfig) return;
+ var cb = this.async();
+ var self = this;
+
+ this.log('\n# Server\n');
+
+ this.prompt([{
+ type: 'checkbox',
+ name: 'odms',
+ message: 'What would you like to use for data modeling?',
+ choices: [
+ {
+ value: 'mongoose',
+ name: 'Mongoose (MongoDB)',
+ checked: true
+ },
+ {
+ value: 'sequelize',
+ name: 'Sequelize (MySQL, SQLite, MariaDB, PostgreSQL)',
+ checked: false
+ }
+ ]
+ }, {
+ type: 'list',
+ name: 'models',
+ message: 'What would you like to use for the default models?',
+ choices: [ 'Mongoose', 'Sequelize' ],
+ filter: function( val ) {
+ return val.toLowerCase();
+ },
+ when: function(answers) {
+ return answers.odms && answers.odms.length > 1;
}
}, {
- type: "confirm",
- name: "babel",
- message: "Would you like to use Javascript ES6 in your client by preprocessing it with Babel?",
+ type: 'confirm',
+ name: 'auth',
+ message: 'Would you scaffold out an authentication boilerplate?',
when: function (answers) {
- return answers.script === 'js';
+ return answers.odms && answers.odms.length !== 0;
}
}, {
- type: "list",
- name: "markup",
- message: "What would you like to write markup with?",
- choices: [ "HTML", "Jade"],
- filter: function( val ) { return val.toLowerCase(); }
- }, {
- type: "list",
- name: "stylesheet",
- default: 1,
- message: "What would you like to write stylesheets with?",
- choices: [ "CSS", "Sass", "Stylus", "Less"],
- filter: function( val ) { return val.toLowerCase(); }
- }, {
- type: "list",
- name: "router",
- default: 1,
- message: "What Angular router would you like to use?",
- choices: [ "ngRoute", "uiRouter"],
- filter: function( val ) { return val.toLowerCase(); }
- }, {
- type: "confirm",
- name: "bootstrap",
- message: "Would you like to include Bootstrap?"
+ type: 'checkbox',
+ name: 'oauth',
+ message: 'Would you like to include additional oAuth strategies?',
+ when: function (answers) {
+ return answers.auth;
+ },
+ choices: [
+ {
+ value: 'googleAuth',
+ name: 'Google',
+ checked: false
+ },
+ {
+ value: 'facebookAuth',
+ name: 'Facebook',
+ checked: false
+ },
+ {
+ value: 'twitterAuth',
+ name: 'Twitter',
+ checked: false
+ }
+ ]
}, {
- type: "confirm",
- name: "uibootstrap",
- message: "Would you like to include UI Bootstrap?",
+ type: 'confirm',
+ name: 'socketio',
+ message: 'Would you like to use socket.io?',
+ // to-do: should not be dependent on ODMs
when: function (answers) {
- return answers.bootstrap;
- }
+ return answers.odms && answers.odms.length !== 0;
+ },
+ default: true
}], 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;
- this.filters[answers.router] = true;
- this.filters.bootstrap = !!answers.bootstrap;
- this.filters.uibootstrap = !!answers.uibootstrap;
- cb();
+ if(answers.socketio) this.filters.socketio = true;
+ if(answers.auth) this.filters.auth = true;
+ if(answers.odms && answers.odms.length > 0) {
+ var models;
+ if(!answers.models) {
+ models = answers.odms[0];
+ } else {
+ models = answers.models;
+ }
+ this.filters.models = true;
+ this.filters[models + 'Models'] = true;
+ answers.odms.forEach(function(odm) {
+ this.filters[odm] = true;
+ }.bind(this));
+ } else {
+ this.filters.noModels = true;
+ }
+ if(answers.oauth) {
+ if(answers.oauth.length) this.filters.oauth = true;
+ answers.oauth.forEach(function(oauthStrategy) {
+ this.filters[oauthStrategy] = true;
+ }.bind(this));
+ }
+
+ cb();
}.bind(this));
- },
+ },
- serverPrompts: function() {
- if(this.skipConfig) return;
- var cb = this.async();
- var self = this;
-
- this.log('\n# Server\n');
-
- this.prompt([{
- type: "confirm",
- name: "mongoose",
- message: "Would you like to use mongoDB with Mongoose for data modeling?"
- }, {
- type: "confirm",
- name: "auth",
- message: "Would you scaffold out an authentication boilerplate?",
- when: function (answers) {
- return answers.mongoose;
- }
- }, {
- type: 'checkbox',
- name: 'oauth',
- message: 'Would you like to include additional oAuth strategies?',
- when: function (answers) {
- return answers.auth;
- },
- choices: [
- {
- value: 'googleAuth',
- name: 'Google',
- checked: false
- },
- {
- value: 'facebookAuth',
- name: 'Facebook',
- checked: false
+ projectPrompts: function() {
+ if(this.skipConfig) return;
+ var cb = this.async();
+ var self = this;
+
+ this.log('\n# Project\n');
+
+ this.prompt([{
+ type: 'list',
+ name: 'testing',
+ message: 'What would you like to write tests with?',
+ choices: [ 'Jasmine', 'Mocha + Chai + Sinon'],
+ filter: function( val ) {
+ var filterMap = {
+ 'Jasmine': 'jasmine',
+ 'Mocha + Chai + Sinon': 'mocha'
+ };
+
+ return filterMap[val];
+ }
+ }, {
+ type: 'list',
+ name: 'chai',
+ message: 'What would you like to write Chai assertions with?',
+ choices: ['Expect', 'Should'],
+ filter: function( val ) {
+ return val.toLowerCase();
},
- {
- value: 'twitterAuth',
- name: 'Twitter',
- checked: false
+ when: function( answers ) {
+ return answers.testing === 'mocha';
}
- ]
- }, {
- type: "confirm",
- name: "socketio",
- message: "Would you like to use socket.io?",
- // to-do: should not be dependent on mongoose
- when: function (answers) {
- return answers.mongoose;
- },
- default: true
- }], function (answers) {
- if(answers.socketio) this.filters.socketio = true;
- if(answers.mongoose) this.filters.mongoose = true;
- if(answers.auth) this.filters.auth = true;
- if(answers.oauth) {
- if(answers.oauth.length) this.filters.oauth = true;
- answers.oauth.forEach(function(oauthStrategy) {
- this.filters[oauthStrategy] = true;
- }.bind(this));
- }
+ }], function (answers) {
+ /**
+ * Default to grunt until gulp support is implemented
+ */
+ this.filters.grunt = true;
+
+ this.filters[answers.testing] = true;
+ if (answers.testing === 'mocha') {
+ this.filters.jasmine = false;
+ this.filters.should = false;
+ this.filters.expect = false;
+ this.filters[answers.chai] = true;
+ }
+ if (answers.testing === 'jasmine') {
+ this.filters.mocha = false;
+ this.filters.should = false;
+ this.filters.expect = false;
+ }
+
+ cb();
+ }.bind(this));
+ }
- cb();
- }.bind(this));
},
- saveSettings: function() {
- if(this.skipConfig) return;
- this.config.set('insertRoutes', true);
- this.config.set('registerRoutesFile', 'server/routes.js');
- this.config.set('routesNeedle', '// Insert routes below');
+ configuring: {
- this.config.set('routesBase', '/api/');
- this.config.set('pluralizeRoutes', true);
+ saveSettings: function() {
+ if(this.skipConfig) return;
+ this.config.set('endpointDirectory', 'server/api/');
+ this.config.set('insertRoutes', true);
+ this.config.set('registerRoutesFile', 'server/routes.js');
+ this.config.set('routesNeedle', '// Insert routes below');
- this.config.set('insertSockets', true);
- this.config.set('registerSocketsFile', 'server/config/socketio.js');
- this.config.set('socketsNeedle', '// Insert sockets below');
+ this.config.set('routesBase', '/api/');
+ this.config.set('pluralizeRoutes', true);
+
+ this.config.set('insertSockets', true);
+ this.config.set('registerSocketsFile', 'server/config/socketio.js');
+ this.config.set('socketsNeedle', '// Insert sockets below');
+
+ this.config.set('insertModels', true);
+ this.config.set('registerModelsFile', 'server/sqldb/index.js');
+ this.config.set('modelsNeedle', '// Insert models below');
+
+ this.config.set('filters', this.filters);
+ this.config.forceSave();
+ },
+
+ ngComponent: function() {
+ if(this.skipConfig) return;
+ var appPath = 'client/app/';
+ var extensions = [];
+ var filters = [
+ 'ngroute',
+ 'uirouter',
+ 'jasmine',
+ 'mocha',
+ 'expect',
+ 'should'
+ ].filter(function(v) {return this.filters[v];}, this);
+
+ 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');
+ if(this.filters.jade) extensions.push('jade');
+ if(this.filters.css) extensions.push('css');
+ if(this.filters.stylus) extensions.push('styl');
+ if(this.filters.sass) extensions.push('scss');
+ if(this.filters.less) extensions.push('less');
+
+ this.composeWith('ng-component', {
+ options: {
+ 'routeDirectory': appPath,
+ 'directiveDirectory': appPath,
+ 'filterDirectory': appPath,
+ 'serviceDirectory': appPath,
+ 'filters': filters,
+ 'extensions': extensions,
+ 'basePath': 'client'
+ }
+ }, { local: require.resolve('generator-ng-component/app/index.js') });
+ },
+
+ ngModules: function() {
+ var angModules = [
+ "'ngCookies'",
+ "'ngResource'",
+ "'ngSanitize'"
+ ];
+ if(this.filters.ngroute) angModules.push("'ngRoute'");
+ if(this.filters.socketio) angModules.push("'btford.socket-io'");
+ if(this.filters.uirouter) angModules.push("'ui.router'");
+ if(this.filters.uibootstrap) angModules.push("'ui.bootstrap'");
+
+ this.angularModules = '\n ' + angModules.join(',\n ') +'\n';
+ }
- this.config.set('filters', this.filters);
- this.config.forceSave();
},
- compose: function() {
- if(this.skipConfig) return;
- var appPath = 'client/app/';
- var extensions = [];
- var filters = [];
-
- 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');
- if(this.filters.jade) extensions.push('jade');
- if(this.filters.css) extensions.push('css');
- if(this.filters.stylus) extensions.push('styl');
- if(this.filters.sass) extensions.push('scss');
- if(this.filters.less) extensions.push('less');
-
- this.composeWith('ng-component', {
- options: {
- 'routeDirectory': appPath,
- 'directiveDirectory': appPath,
- 'filterDirectory': appPath,
- 'serviceDirectory': appPath,
- 'filters': filters,
- 'extensions': extensions,
- 'basePath': 'client'
+ default: {},
+
+ writing: {
+
+ generateProject: function() {
+ this.sourceRoot(path.join(__dirname, './templates'));
+ genUtils.processDirectory(this, '.', '.');
+ },
+
+ generateEndpoint: function() {
+ var models;
+ if (this.filters.mongooseModels) {
+ models = 'mongoose';
+ } else if (this.filters.sequelizeModels) {
+ models = 'sequelize';
}
- }, { local: require.resolve('generator-ng-component/app/index.js') });
- },
+ this.composeWith('angular-fullstack:endpoint', {
+ options: {
+ route: '/api/things',
+ models: models
+ },
+ args: ['thing']
+ });
+ }
- ngModules: function() {
- this.filters = this._.defaults(this.config.get('filters'), {
- bootstrap: true,
- uibootstrap: true
- });
-
- var angModules = [
- "'ngCookies'",
- "'ngResource'",
- "'ngSanitize'"
- ];
- if(this.filters.ngroute) angModules.push("'ngRoute'");
- if(this.filters.socketio) angModules.push("'btford.socket-io'");
- if(this.filters.uirouter) angModules.push("'ui.router'");
- if(this.filters.uibootstrap) angModules.push("'ui.bootstrap'");
-
- this.angularModules = "\n " + angModules.join(",\n ") +"\n";
},
- generate: function() {
- this.sourceRoot(path.join(__dirname, './templates'));
- genUtils.processDirectory(this, '.', '.');
+ install: {
+
+ installDeps: function() {
+ this.installDependencies({
+ skipInstall: this.options['skip-install']
+ });
+ }
+
},
- end: function() {
- this.installDependencies({
- skipInstall: this.options['skip-install']
- });
- }
+ end: {}
+
});
module.exports = AngularFullstackGenerator;
diff --git a/app/templates/.buildignore b/app/templates/.buildignore
index fc98b8eb5..3ae6d06a2 100644
--- a/app/templates/.buildignore
+++ b/app/templates/.buildignore
@@ -1 +1 @@
-*.coffee
\ No newline at end of file
+*.coffee
diff --git a/app/templates/.jscs.json b/app/templates/.jscs.json
new file mode 100644
index 000000000..99393d5f6
--- /dev/null
+++ b/app/templates/.jscs.json
@@ -0,0 +1,44 @@
+{
+ "maximumLineLength": {
+ "value": 100,
+ "allowComments": true,
+ "allowRegex": true
+ },
+ "disallowMixedSpacesAndTabs": true,
+ "disallowMultipleLineStrings": true,
+ "disallowNewlineBeforeBlockStatements": true,
+ "disallowSpaceAfterObjectKeys": true,
+ "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
+ "disallowSpaceBeforeBinaryOperators": [","],
+ "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
+ "disallowSpacesInAnonymousFunctionExpression": {
+ "beforeOpeningRoundBrace": true
+ },
+ "disallowSpacesInFunctionDeclaration": {
+ "beforeOpeningRoundBrace": true
+ },
+ "disallowSpacesInNamedFunctionExpression": {
+ "beforeOpeningRoundBrace": true
+ },
+ "disallowSpacesInsideArrayBrackets": true,
+ "disallowSpacesInsideParentheses": true,
+ "disallowTrailingComma": true,
+ "disallowTrailingWhitespace": true,
+ "requireCommaBeforeLineBreak": true,
+ "requireLineFeedAtFileEnd": true,
+ "requireSpaceAfterBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"],
+ "requireSpaceBeforeBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"],
+ "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
+ "requireSpaceBeforeBlockStatements": true,
+ "requireSpacesInConditionalExpression": {
+ "afterTest": true,
+ "beforeConsequent": true,
+ "afterConsequent": true,
+ "beforeAlternate": true
+ },
+ "requireSpacesInFunction": {
+ "beforeOpeningCurlyBrace": true
+ },
+ "validateLineBreaks": "LF",
+ "validateParameterSeparator": ", "
+}
diff --git a/app/templates/.travis.yml b/app/templates/.travis.yml
index 5112a8e88..c12f57edb 100644
--- a/app/templates/.travis.yml
+++ b/app/templates/.travis.yml
@@ -1,9 +1,8 @@
language: node_js
node_js:
- - '0.10'
- - '0.11'
+ - '0.12'
before_script:
- npm install -g bower grunt-cli<% if (filters.sass) { %>
- gem install sass<% } %>
- bower install
-services: mongodb
\ No newline at end of file
+services: mongodb
diff --git a/app/templates/Gruntfile.js b/app/templates/Gruntfile.js
index 6685f5108..666681a89 100644
--- a/app/templates/Gruntfile.js
+++ b/app/templates/Gruntfile.js
@@ -16,7 +16,8 @@ module.exports = function (grunt) {
ngtemplates: 'grunt-angular-templates',
cdnify: 'grunt-google-cdn',
protractor: 'grunt-protractor-runner',
- buildcontrol: 'grunt-build-control'
+ buildcontrol: 'grunt-build-control',
+ istanbul_check_coverage: 'grunt-mocha-istanbul'
});
// Time how long tasks take. Can help when optimizing build times
@@ -38,13 +39,13 @@ module.exports = function (grunt) {
},
dev: {
options: {
- script: 'server/app.js',
+ script: 'server',
debug: true
}
},
prod: {
options: {
- script: 'dist/server/app.js'
+ script: 'dist/server'
}
}
},
@@ -53,102 +54,73 @@ module.exports = function (grunt) {
url: 'http://localhost:<%%= express.options.port %>'
}
},
- watch: {
+ watch: {<% if(filters.babel) { %>
+ babel: {
+ files: ['<%%= yeoman.client %>/{app,components}/**/!(*.spec|*.mock).js'],
+ tasks: ['newer:babel:client']
+ },<% } %>
injectJS: {
files: [
- '<%%= yeoman.client %>/{app,components}/**/*.js',
- '!<%%= yeoman.client %>/{app,components}/**/*.spec.js',
- '!<%%= yeoman.client %>/{app,components}/**/*.mock.js',
- '!<%%= yeoman.client %>/app/app.js'],
+ '<%%= yeoman.client %>/{app,components}/**/!(*.spec|*.mock).js',
+ '!<%%= yeoman.client %>/app/app.js'
+ ],
tasks: ['injector:scripts']
},
injectCss: {
- files: [
- '<%%= yeoman.client %>/{app,components}/**/*.css'
- ],
+ files: ['<%%= yeoman.client %>/{app,components}/**/*.css'],
tasks: ['injector:css']
},
mochaTest: {
- files: ['server/**/*.spec.js'],
+ files: ['server/**/*.{spec,integration}.js'],
tasks: ['env:test', 'mochaTest']
},
jsTest: {
- files: [
- '<%%= yeoman.client %>/{app,components}/**/*.spec.js',
- '<%%= yeoman.client %>/{app,components}/**/*.mock.js'
- ],
- tasks: ['newer:jshint:all', 'karma']
- },<% if(filters.stylus) { %>
+ files: ['<%%= yeoman.client %>/{app,components}/**/*.{spec,mock}.js'],
+ tasks: ['newer:jshint:all', 'wiredep:test', 'karma']
+ },<% if (filters.stylus) { %>
injectStylus: {
- files: [
- '<%%= yeoman.client %>/{app,components}/**/*.styl'],
+ files: ['<%%= yeoman.client %>/{app,components}/**/*.styl'],
tasks: ['injector:stylus']
},
stylus: {
- files: [
- '<%%= yeoman.client %>/{app,components}/**/*.styl'],
- tasks: ['stylus', 'autoprefixer']
- },<% } %><% if(filters.sass) { %>
+ files: ['<%%= yeoman.client %>/{app,components}/**/*.styl'],
+ tasks: ['stylus', 'postcss']
+ },<% } if (filters.sass) { %>
injectSass: {
- files: [
- '<%%= yeoman.client %>/{app,components}/**/*.{scss,sass}'],
+ files: ['<%%= yeoman.client %>/{app,components}/**/*.{scss,sass}'],
tasks: ['injector:sass']
},
sass: {
- files: [
- '<%%= yeoman.client %>/{app,components}/**/*.{scss,sass}'],
- tasks: ['sass', 'autoprefixer']
- },<% } %><% if(filters.less) { %>
+ files: ['<%%= yeoman.client %>/{app,components}/**/*.{scss,sass}'],
+ tasks: ['sass', 'postcss']
+ },<% } if (filters.less) { %>
injectLess: {
- files: [
- '<%%= yeoman.client %>/{app,components}/**/*.less'],
+ files: ['<%%= yeoman.client %>/{app,components}/**/*.less'],
tasks: ['injector:less']
},
less: {
- files: [
- '<%%= yeoman.client %>/{app,components}/**/*.less'],
- tasks: ['less', 'autoprefixer']
- },<% } %><% if(filters.jade) { %>
+ files: ['<%%= yeoman.client %>/{app,components}/**/*.less'],
+ tasks: ['less', 'postcss']
+ },<% } if (filters.jade) { %>
jade: {
- files: [
- '<%%= yeoman.client %>/{app,components}/*',
- '<%%= yeoman.client %>/{app,components}/**/*.jade'],
+ files: ['<%%= yeoman.client %>/{app,components}/**/*.jade'],
tasks: ['jade']
- },<% } %><% if(filters.coffee) { %>
+ },<% } if (filters.coffee) { %>
coffee: {
- files: [
- '<%%= yeoman.client %>/{app,components}/**/*.{coffee,litcoffee,coffee.md}',
- '!<%%= yeoman.client %>/{app,components}/**/*.spec.{coffee,litcoffee,coffee.md}'
- ],
+ files: ['<%%= yeoman.client %>/{app,components}/**/!(*.spec).{coffee,litcoffee,coffee.md}'],
tasks: ['newer:coffee', 'injector:scripts']
},
coffeeTest: {
- files: [
- '<%%= yeoman.client %>/{app,components}/**/*.spec.{coffee,litcoffee,coffee.md}'
- ],
+ files: ['<%%= 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']
},
livereload: {
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',
+ '{.tmp,<%%= yeoman.client %>}/{app,components}/**/*.{css,html}',
+ '{.tmp,<%%= yeoman.client %>}/{app,components}/**/!(*.spec|*.mock).js',
'<%%= yeoman.client %>/assets/images/{,*//*}*.{png,jpg,jpeg,gif,webp,svg}'
],
options: {
@@ -156,15 +128,17 @@ module.exports = function (grunt) {
}
},
express: {
- files: [
- 'server/**/*.{js,json}'
- ],
+ files: ['server/**/*.{js,json}'],
tasks: ['express:dev', 'wait'],
options: {
livereload: true,
- nospawn: true //Without this option specified express won't be reloaded
+ spawn: false //Without this option specified express won't be reloaded
}
- }
+ },
+ bower: {
+ files: ['bower.json'],
+ tasks: ['wiredep']
+ },
},
// Make sure code styles are up to par and there are no obvious mistakes
@@ -177,27 +151,31 @@ module.exports = function (grunt) {
options: {
jshintrc: 'server/.jshintrc'
},
- src: [
- 'server/**/*.js',
- '!server/**/*.spec.js'
- ]
+ src: ['server/**/!(*.spec|*.integration).js']
},
serverTest: {
options: {
jshintrc: 'server/.jshintrc-spec'
},
- src: ['server/**/*.spec.js']
+ src: ['server/**/*.{spec,integration}.js']
},
- all: [
- '<%%= yeoman.client %>/{app,components}/**/*.js',
- '!<%%= yeoman.client %>/{app,components}/**/*.spec.js',
- '!<%%= yeoman.client %>/{app,components}/**/*.mock.js'
- ],
+ all: ['<%%= yeoman.client %>/{app,components}/**/!(*.spec|*.mock).js'],
test: {
- src: [
- '<%%= yeoman.client %>/{app,components}/**/*.spec.js',
- '<%%= yeoman.client %>/{app,components}/**/*.mock.js'
- ]
+ src: ['<%%= yeoman.client %>/{app,components}/**/*.{spec,mock}.js']
+ }
+ },
+
+ jscs: {
+ options: {
+ config: ".jscs.json"
+ },
+ main: {
+ files: {
+ src: [
+ '<%%= yeoman.client %>/app/**/*.js',
+ 'server/**/*.js'
+ ]
+ }
}
},
@@ -208,10 +186,7 @@ module.exports = function (grunt) {
dot: true,
src: [
'.tmp',
- '<%%= yeoman.dist %>/*',
- '!<%%= yeoman.dist %>/.git*',
- '!<%%= yeoman.dist %>/.openshift',
- '!<%%= yeoman.dist %>/Procfile'
+ '<%%= yeoman.dist %>/!(.git*|.openshift|Procfile)**'
]
}]
},
@@ -219,9 +194,12 @@ module.exports = function (grunt) {
},
// Add vendor prefixed styles
- autoprefixer: {
+ postcss: {
options: {
- browsers: ['last 1 version']
+ map: true,
+ processors: [
+ require('autoprefixer-core')({browsers: ['last 1 version']})
+ ]
},
dist: {
files: [{
@@ -245,7 +223,7 @@ module.exports = function (grunt) {
// Use nodemon to run server in debug mode with an initial breakpoint
nodemon: {
debug: {
- script: 'server/app.js',
+ script: 'server',
options: {
nodeArgs: ['--debug-brk'],
env: {
@@ -267,26 +245,36 @@ module.exports = function (grunt) {
}
},
- // Automatically inject Bower components into the app
+ // Automatically inject Bower components into the app and karma.conf.js
wiredep: {
- target: {
+ options: {
+ exclude: [
+ /bootstrap.js/,
+ '/json3/',
+ '/es5-shim/'<% if(!filters.css) { %>,
+ /font-awesome\.css/<% if(filters.bootstrap) { %>,
+ /bootstrap\.css/<% if(filters.sass) { %>,
+ /bootstrap-sass-official/<% }}} %>
+ ]
+ },
+ client: {
src: '<%%= yeoman.client %>/index.html',
ignorePath: '<%%= yeoman.client %>/',
- exclude: [/bootstrap-sass-official/, /bootstrap.js/, '/json3/', '/es5-shim/'<% if(!filters.css) { %>, /bootstrap.css/, /font-awesome.css/ <% } %>]
+ },
+ test: {
+ src: './karma.conf.js',
+ devDependencies: true
}
},
// Renames files for browser caching purposes
- rev: {
+ filerev: {
dist: {
- files: {
- src: [
- '<%%= yeoman.dist %>/public/{,*/}*.js',
- '<%%= yeoman.dist %>/public/{,*/}*.css',
- '<%%= yeoman.dist %>/public/assets/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
- '<%%= yeoman.dist %>/public/assets/fonts/*'
- ]
- }
+ src: [
+ '<%%= yeoman.dist %>/client/!(bower_components){,*/}*.{js,css}',
+ '<%%= yeoman.dist %>/client/assets/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
+ '<%%= yeoman.dist %>/client/assets/fonts/*'
+ ]
}
},
@@ -296,19 +284,19 @@ module.exports = function (grunt) {
useminPrepare: {
html: ['<%%= yeoman.client %>/index.html'],
options: {
- dest: '<%%= yeoman.dist %>/public'
+ dest: '<%%= yeoman.dist %>/client'
}
},
// Performs rewrites based on rev and the useminPrepare configuration
usemin: {
- html: ['<%%= yeoman.dist %>/public/{,*/}*.html'],
- css: ['<%%= yeoman.dist %>/public/{,*/}*.css'],
- js: ['<%%= yeoman.dist %>/public/{,*/}*.js'],
+ html: ['<%%= yeoman.dist %>/client/!(bower_components){,*/}*.html'],
+ css: ['<%%= yeoman.dist %>/client/!(bower_components){,*/}*.css'],
+ js: ['<%%= yeoman.dist %>/client/!(bower_components){,*/}*.js'],
options: {
assetsDirs: [
- '<%%= yeoman.dist %>/public',
- '<%%= yeoman.dist %>/public/assets/images'
+ '<%%= yeoman.dist %>/client',
+ '<%%= yeoman.dist %>/client/assets/images'
],
// This is so we update image references in our ng-templates
patterns: {
@@ -325,19 +313,8 @@ module.exports = function (grunt) {
files: [{
expand: true,
cwd: '<%%= yeoman.client %>/assets/images',
- src: '{,*/}*.{png,jpg,jpeg,gif}',
- dest: '<%%= yeoman.dist %>/public/assets/images'
- }]
- }
- },
-
- svgmin: {
- dist: {
- files: [{
- expand: true,
- cwd: '<%%= yeoman.client %>/assets/images',
- src: '{,*/}*.svg',
- dest: '<%%= yeoman.dist %>/public/assets/images'
+ src: '{,*/}*.{png,jpg,jpeg,gif,svg}',
+ dest: '<%%= yeoman.dist %>/client/assets/images'
}]
}
},
@@ -386,7 +363,7 @@ module.exports = function (grunt) {
// Replace Google CDN references
cdnify: {
dist: {
- html: ['<%%= yeoman.dist %>/public/*.html']
+ html: ['<%%= yeoman.dist %>/client/*.html']
}
},
@@ -397,7 +374,7 @@ module.exports = function (grunt) {
expand: true,
dot: true,
cwd: '<%%= yeoman.client %>',
- dest: '<%%= yeoman.dist %>/public',
+ dest: '<%%= yeoman.dist %>/client',
src: [
'*.{ico,png,txt}',
'.htaccess',
@@ -409,7 +386,7 @@ module.exports = function (grunt) {
}, {
expand: true,
cwd: '.tmp/images',
- dest: '<%%= yeoman.dist %>/public/assets/images',
+ dest: '<%%= yeoman.dist %>/client/assets/images',
src: ['generated/*']
}, {
expand: true,
@@ -453,19 +430,19 @@ module.exports = function (grunt) {
// Run some tasks in parallel to speed up the build process
concurrent: {
server: [<% if(filters.coffee) { %>
- 'coffee',<% } %><% if(filters.babel) { %>
- 'babel',<% } %><% if(filters.jade) { %>
- 'jade',<% } %><% if(filters.stylus) { %>
- 'stylus',<% } %><% if(filters.sass) { %>
- 'sass',<% } %><% if(filters.less) { %>
+ 'coffee',<% } if(filters.babel) { %>
+ 'newer:babel:client',<% } if(filters.jade) { %>
+ 'jade',<% } if(filters.stylus) { %>
+ 'stylus',<% } if(filters.sass) { %>
+ 'sass',<% } if(filters.less) { %>
'less',<% } %>
],
test: [<% if(filters.coffee) { %>
- 'coffee',<% } %><% if(filters.babel) { %>
- 'babel',<% } %><% if(filters.jade) { %>
- 'jade',<% } %><% if(filters.stylus) { %>
- 'stylus',<% } %><% if(filters.sass) { %>
- 'sass',<% } %><% if(filters.less) { %>
+ 'coffee',<% } if(filters.babel) { %>
+ 'newer:babel:client',<% } if(filters.jade) { %>
+ 'jade',<% } if(filters.stylus) { %>
+ 'stylus',<% } if(filters.sass) { %>
+ 'sass',<% } if(filters.less) { %>
'less',<% } %>
],
debug: {
@@ -478,14 +455,13 @@ module.exports = function (grunt) {
}
},
dist: [<% if(filters.coffee) { %>
- 'coffee',<% } %><% if(filters.babel) { %>
- 'babel',<% } %><% if(filters.jade) { %>
- 'jade',<% } %><% if(filters.stylus) { %>
- 'stylus',<% } %><% if(filters.sass) { %>
- 'sass',<% } %><% if(filters.less) { %>
+ 'coffee',<% } if(filters.babel) { %>
+ 'newer:babel:client',<% } if(filters.jade) { %>
+ 'jade',<% } if(filters.stylus) { %>
+ 'stylus',<% } if(filters.sass) { %>
+ 'sass',<% } if(filters.less) { %>
'less',<% } %>
- 'imagemin',
- 'svgmin'
+ 'imagemin'
]
},
@@ -499,9 +475,53 @@ module.exports = function (grunt) {
mochaTest: {
options: {
- reporter: 'spec'
+ reporter: 'spec',
+ require: 'mocha.conf.js',
+ timeout: 5000 // set default mocha spec timeout
+ },
+ unit: {
+ src: ['server/**/*.spec.js']
},
- src: ['server/**/*.spec.js']
+ integration: {
+ src: ['server/**/*.integration.js']
+ }
+ },
+
+ mocha_istanbul: {
+ unit: {
+ options: {
+ excludes: ['**/*.{spec,mock,integration}.js'],
+ reporter: 'spec',
+ require: ['mocha.conf.js'],
+ mask: '**/*.spec.js',
+ coverageFolder: 'coverage/server/unit'
+ },
+ src: 'server'
+ },
+ integration: {
+ options: {
+ excludes: ['**/*.{spec,mock,integration}.js'],
+ reporter: 'spec',
+ require: ['mocha.conf.js'],
+ mask: '**/*.integration.js',
+ coverageFolder: 'coverage/server/integration'
+ },
+ src: 'server'
+ }
+ },
+
+ istanbul_check_coverage: {
+ default: {
+ options: {
+ coverageFolder: 'coverage/**',
+ check: {
+ lines: 80,
+ statements: 80,
+ branches: 80,
+ functions: 80
+ }
+ }
+ }
},
protractor: {
@@ -525,7 +545,7 @@ module.exports = function (grunt) {
NODE_ENV: 'production'
},
all: localConfig
- },<% if(filters.jade) { %>
+ },<% if (filters.jade) { %>
// Compiles Jade to html
jade: {
@@ -538,14 +558,12 @@ module.exports = function (grunt) {
files: [{
expand: true,
cwd: '<%%= yeoman.client %>',
- src: [
- '{app,components}/**/*.jade'
- ],
+ src: ['{app,components}/**/*.jade'],
dest: '.tmp',
ext: '.html'
}]
}
- },<% } %><% if(filters.coffee) { %>
+ },<% } if (filters.coffee) { %>
// Compiles CoffeeScript to JavaScript
coffee: {
@@ -557,82 +575,59 @@ module.exports = function (grunt) {
files: [{
expand: true,
cwd: 'client',
- src: [
- '{app,components}/**/*.coffee',
- '!{app,components}/**/*.spec.coffee'
- ],
+ src: ['{app,components}/**/!(*.spec).coffee'],
dest: '.tmp',
ext: '.js'
}]
}
- },<% } %><% if(filters.babel) { %>
+ },<% } if(filters.babel) { %>
// Compiles ES6 to JavaScript using Babel
babel: {
- options: {
+ options: {
sourceMap: true
},
- server: {
+ client: {
files: [{
expand: true,
- cwd: 'client',
- src: [
- '{app,components}/**/*.js',
- '!{app,components}/**/*.spec.js'
- ],
+ cwd: '<%%= yeoman.client %>',
+ src: ['{app,components}/**/!(*.spec).js'],
dest: '.tmp'
}]
}
- },<% } %><% if(filters.stylus) { %>
+ },<% } if(filters.stylus) { %>
// Compiles Stylus to CSS
stylus: {
server: {
options: {
- paths: [
- '<%%= yeoman.client %>/bower_components',
- '<%%= yeoman.client %>/app',
- '<%%= yeoman.client %>/components'
- ],
"include css": true
},
files: {
'.tmp/app/app.css' : '<%%= yeoman.client %>/app/app.styl'
}
}
- },<% } %><% if(filters.sass) { %>
+ },<% } if (filters.sass) { %>
// Compiles Sass to CSS
sass: {
server: {
options: {
- loadPath: [
- '<%%= yeoman.client %>/bower_components',
- '<%%= yeoman.client %>/app',
- '<%%= yeoman.client %>/components'
- ],
compass: false
},
files: {
'.tmp/app/app.css' : '<%%= yeoman.client %>/app/app.scss'
}
}
- },<% } %><% if(filters.less) { %>
+ },<% } if (filters.less) { %>
// Compiles Less to CSS
less: {
- options: {
- paths: [
- '<%%= yeoman.client %>/bower_components',
- '<%%= yeoman.client %>/app',
- '<%%= yeoman.client %>/components'
- ]
- },
server: {
files: {
'.tmp/app/app.css' : '<%%= yeoman.client %>/app/app.less'
}
- },
+ }
},<% } %>
injector: {
@@ -652,26 +647,21 @@ module.exports = function (grunt) {
},
files: {
'<%%= yeoman.client %>/index.html': [
- [
- <% 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.babel) { %>
+ '.tmp/{app,components}/**/!(*.spec|*.mock).js',<% } else { %>
+ '{.tmp,<%%= yeoman.client %>}/{app,components}/**/!(*.spec|*.mock).js',<% } %>
+ '!{.tmp,<%%= yeoman.client %>}/app/app.js'
]
]
}
- },<% if(filters.stylus) { %>
+ },<% if (filters.stylus) { %>
// Inject component styl into app.styl
stylus: {
options: {
transform: function(filePath) {
filePath = filePath.replace('/client/app/', '');
- filePath = filePath.replace('/client/components/', '');
+ filePath = filePath.replace('/client/components/', '../components/');
return '@import \'' + filePath + '\';';
},
starttag: '// injector',
@@ -683,14 +673,14 @@ module.exports = function (grunt) {
'!<%%= yeoman.client %>/app/app.styl'
]
}
- },<% } %><% if(filters.sass) { %>
+ },<% } if (filters.sass) { %>
// Inject component scss into app.scss
sass: {
options: {
transform: function(filePath) {
filePath = filePath.replace('/client/app/', '');
- filePath = filePath.replace('/client/components/', '');
+ filePath = filePath.replace('/client/components/', '../components/');
return '@import \'' + filePath + '\';';
},
starttag: '// injector',
@@ -702,14 +692,14 @@ module.exports = function (grunt) {
'!<%%= yeoman.client %>/app/app.{scss,sass}'
]
}
- },<% } %><% if(filters.less) { %>
+ },<% } if (filters.less) { %>
// Inject component less into app.less
less: {
options: {
transform: function(filePath) {
filePath = filePath.replace('/client/app/', '');
- filePath = filePath.replace('/client/components/', '');
+ filePath = filePath.replace('/client/components/', '../components/');
return '@import \'' + filePath + '\';';
},
starttag: '// injector',
@@ -767,28 +757,28 @@ module.exports = function (grunt) {
if (target === 'debug') {
return grunt.task.run([
'clean:server',
- 'env:all',<% if(filters.stylus) { %>
- 'injector:stylus', <% } %><% if(filters.less) { %>
- 'injector:less', <% } %><% if(filters.sass) { %>
- 'injector:sass', <% } %>
+ 'env:all',<% if (filters.stylus) { %>
+ 'injector:stylus',<% } if (filters.less) { %>
+ 'injector:less',<% } if (filters.sass) { %>
+ 'injector:sass',<% } %>
'concurrent:server',
'injector',
- 'wiredep',
- 'autoprefixer',
+ 'wiredep:client',
+ 'postcss',
'concurrent:debug'
]);
}
grunt.task.run([
'clean:server',
- 'env:all',<% if(filters.stylus) { %>
- 'injector:stylus', <% } %><% if(filters.less) { %>
- 'injector:less', <% } %><% if(filters.sass) { %>
- 'injector:sass', <% } %>
+ 'env:all',<% if (filters.stylus) { %>
+ 'injector:stylus',<% } if (filters.less) { %>
+ 'injector:less',<% } if (filters.sass) { %>
+ 'injector:sass',<% } %>
'concurrent:server',
'injector',
- 'wiredep',
- 'autoprefixer',
+ 'wiredep:client',
+ 'postcss',
'express:dev',
'wait',
'open',
@@ -801,44 +791,94 @@ module.exports = function (grunt) {
grunt.task.run(['serve']);
});
- grunt.registerTask('test', function(target) {
+ grunt.registerTask('test', function(target, option) {
if (target === 'server') {
return grunt.task.run([
'env:all',
'env:test',
- 'mochaTest'
+ 'mochaTest:unit',
+ 'mochaTest:integration'
]);
}
else if (target === 'client') {
return grunt.task.run([
'clean:server',
- 'env:all',<% if(filters.stylus) { %>
- 'injector:stylus', <% } %><% if(filters.less) { %>
- 'injector:less', <% } %><% if(filters.sass) { %>
- 'injector:sass', <% } %>
+ 'env:all',<% if (filters.stylus) { %>
+ 'injector:stylus',<% } if (filters.less) { %>
+ 'injector:less',<% } if (filters.sass) { %>
+ 'injector:sass',<% } %>
'concurrent:test',
'injector',
- 'autoprefixer',
+ 'postcss',
+ 'wiredep:test',
'karma'
]);
}
else if (target === 'e2e') {
- return grunt.task.run([
- 'clean:server',
- 'env:all',
- 'env:test',<% if(filters.stylus) { %>
- 'injector:stylus', <% } %><% if(filters.less) { %>
- 'injector:less', <% } %><% if(filters.sass) { %>
- 'injector:sass', <% } %>
- 'concurrent:test',
- 'injector',
- 'wiredep',
- 'autoprefixer',
- 'express:dev',
- 'protractor'
- ]);
+
+ if (option === 'prod') {
+ return grunt.task.run([
+ 'build',
+ 'env:all',
+ 'env:prod',
+ 'express:prod',
+ 'protractor'
+ ]);
+ }
+
+ else {
+ return grunt.task.run([
+ 'clean:server',
+ 'env:all',
+ 'env:test',<% if (filters.stylus) { %>
+ 'injector:stylus',<% } if (filters.less) { %>
+ 'injector:less',<% } if (filters.sass) { %>
+ 'injector:sass',<% } %>
+ 'concurrent:test',
+ 'injector',
+ 'wiredep:client',
+ 'postcss',
+ 'express:dev',
+ 'protractor'
+ ]);
+ }
+ }
+
+ else if (target === 'coverage') {
+
+ if (option === 'unit') {
+ return grunt.task.run([
+ 'env:all',
+ 'env:test',
+ 'mocha_istanbul:unit'
+ ]);
+ }
+
+ else if (option === 'integration') {
+ return grunt.task.run([
+ 'env:all',
+ 'env:test',
+ 'mocha_istanbul:integration'
+ ]);
+ }
+
+ else if (option === 'check') {
+ return grunt.task.run([
+ 'istanbul_check_coverage'
+ ]);
+ }
+
+ else {
+ return grunt.task.run([
+ 'env:all',
+ 'env:test',
+ 'mocha_istanbul',
+ 'istanbul_check_coverage'
+ ]);
+ }
+
}
else grunt.task.run([
@@ -848,15 +888,15 @@ module.exports = function (grunt) {
});
grunt.registerTask('build', [
- 'clean:dist',<% if(filters.stylus) { %>
- 'injector:stylus', <% } %><% if(filters.less) { %>
- 'injector:less', <% } %><% if(filters.sass) { %>
- 'injector:sass', <% } %>
+ 'clean:dist',<% if (filters.stylus) { %>
+ 'injector:stylus',<% } if (filters.less) { %>
+ 'injector:less',<% } if (filters.sass) { %>
+ 'injector:sass',<% } %>
'concurrent:dist',
'injector',
- 'wiredep',
+ 'wiredep:client',
'useminPrepare',
- 'autoprefixer',
+ 'postcss',
'ngtemplates',
'concat',
'ngAnnotate',
@@ -864,7 +904,7 @@ module.exports = function (grunt) {
'cdnify',
'cssmin',
'uglify',
- 'rev',
+ 'filerev',
'usemin'
]);
diff --git a/app/templates/README.md b/app/templates/README.md
new file mode 100644
index 000000000..958834120
--- /dev/null
+++ b/app/templates/README.md
@@ -0,0 +1,34 @@
+# <%= _.slugify(_.humanize(appname)) %>
+
+This project was generated with the [Angular Full-Stack Generator](https://github.com/DaftMonk/generator-angular-fullstack) version <%= pkg.version %>.
+
+## Getting Started
+
+### Prerequisites
+
+- [Git](https://git-scm.com/)
+- [Node.js and NPM](nodejs.org) >= v0.12.0
+- [Bower](bower.io) (`npm install --global bower`)<% if(filters.sass) { %>
+- [Ruby](https://www.ruby-lang.org) and then `gem install sass`<% } if(filters.grunt) { %>
+- [Grunt](http://gruntjs.com/) (`npm install --global grunt-cli`)<% } if(filters.gulp) { %>
+- [Gulp](http://gulpjs.com/) (`npm install --global gulp`)<% } if(filters.mongoose) { %>
+- [MongoDB](https://www.mongodb.org/) - Keep a running daemon with `mongod`<% } if(filters.sequelize) { %>
+- [SQLite](https://www.sqlite.org/quickstart.html)<% } %>
+
+### Developing<% var i = 1; %>
+
+<%= i++ %>. Run `npm install` to install server dependencies.
+
+<%= i++ %>. Run `bower install` to install front-end dependencies.<% if(filters.mongoose) { %>
+
+<%= i++ %>. Run `mongod` in a separate shell to keep an instance of the MongoDB Daemon running<% } %>
+
+<%= i++ %>. Run <% if(filters.grunt) { %>`grunt serve`<% } if(filters.grunt && filters.gulp) { %> or <% } if(filters.gulp) { %>`gulp serve`<% } %> to start the development server. It should automatically open the client in your browser when ready.
+
+## Build & development
+
+Run `grunt build` for building and `grunt serve` for preview.
+
+## Testing
+
+Running `npm test` will run the unit tests with karma.
diff --git a/app/templates/_.gitignore b/app/templates/_.gitignore
index a5f8174b5..d5ae65fb7 100644
--- a/app/templates/_.gitignore
+++ b/app/templates/_.gitignore
@@ -1,6 +1,6 @@
node_modules
public
-.tmp<% if(filters.sass) { %>
+.tmp<% if (filters.sass) { %>
.sass-cache<% } %>
.idea
client/bower_components
diff --git a/app/templates/_bower.json b/app/templates/_bower.json
index 156d04b32..1d41b39d1 100644
--- a/app/templates/_bower.json
+++ b/app/templates/_bower.json
@@ -2,23 +2,22 @@
"name": "<%= _.slugify(_.humanize(appname)) %>",
"version": "0.0.0",
"dependencies": {
- "angular": ">=1.2.*",
+ "angular": "~1.4.0",
"json3": "~3.3.1",
"es5-shim": "~3.0.1",<% if(filters.bootstrap) { %><% if (filters.sass) { %>
"bootstrap-sass-official": "~3.1.1",<% } %>
"bootstrap": "~3.1.1",<% } %>
- "angular-resource": ">=1.2.*",
- "angular-cookies": ">=1.2.*",
- "angular-sanitize": ">=1.2.*",<% if(filters.ngroute) { %>
- "angular-route": ">=1.2.*",<% } %><% if(filters.uibootstrap) { %>
- "angular-bootstrap": "~0.11.0",<% } %>
+ "angular-resource": "~1.4.0",
+ "angular-cookies": "~1.4.0",
+ "angular-sanitize": "~1.4.0",<% if (filters.ngroute) { %>
+ "angular-route": "~1.4.0",<% } %><% if (filters.uibootstrap) { %>
+ "angular-bootstrap": "~0.13.0",<% } %>
"font-awesome": ">=4.1.0",
"lodash": "~2.4.1"<% if(filters.socketio) { %>,
- "angular-socket-io": "~0.6.0"<% } %><% if(filters.uirouter) { %>,
+ "angular-socket-io": "~0.7.0"<% } %><% if(filters.uirouter) { %>,
"angular-ui-router": "~0.2.15"<% } %>
},
"devDependencies": {
- "angular-mocks": ">=1.2.*",
- "angular-scenario": ">=1.2.*"
+ "angular-mocks": "~1.4.0"
}
}
diff --git a/app/templates/_package.json b/app/templates/_package.json
index 88541b924..53b4e9824 100644
--- a/app/templates/_package.json
+++ b/app/templates/_package.json
@@ -7,94 +7,110 @@
"morgan": "~1.0.0",
"body-parser": "~1.5.0",
"method-override": "~1.0.0",
- "serve-favicon": "~2.0.1",
"cookie-parser": "~1.0.1",
"express-session": "~1.0.2",
"errorhandler": "~1.0.0",
"compression": "~1.0.1",
- "lodash": "~2.4.1",<% if(filters.jade) { %>
- "jade": "~1.2.0",<% } %><% if(filters.html) { %>
- "ejs": "~0.8.4",<% } %><% if(filters.mongoose) { %>
- "mongoose": "~4.0.3",<% } %><% if(filters.auth) { %>
+ "composable-middleware": "^0.3.0",
+ "lodash": "~2.4.1",
+ "babel-core": "^5.6.4",<% if (filters.jade) { %>
+ "jade": "~1.2.0",<% } %><% if (filters.html) { %>
+ "ejs": "~0.8.4",<% } %><% if (filters.mongoose) { %>
+ "mongoose": "^4.1.2",
+ "bluebird": "^2.9.34",
+ "connect-mongo": "^0.8.1",<% } %><% if (filters.sequelize) { %>
+ "sequelize": "^3.5.1",
+ "sqlite3": "~3.0.2",
+ "express-sequelize-session": "0.4.0",<% } %><% if (filters.auth) { %>
"jsonwebtoken": "^5.0.0",
"express-jwt": "^3.0.0",
"passport": "~0.2.0",
- "passport-local": "~0.1.6",<% } %><% if(filters.facebookAuth) { %>
- "passport-facebook": "latest",<% } %><% if(filters.twitterAuth) { %>
- "passport-twitter": "latest",<% } %><% if(filters.googleAuth) { %>
- "passport-google-oauth": "latest",<% } %>
- "composable-middleware": "^0.3.0",
- "connect-mongo": "^0.8.1"<% if(filters.socketio) { %>,
- "socket.io": "^1.0.6",
- "socket.io-client": "^1.0.6",
- "socketio-jwt": "^3.0.0"<% } %>
+ "passport-local": "~0.1.6",<% } %><% if (filters.facebookAuth) { %>
+ "passport-facebook": "latest",<% } %><% if (filters.twitterAuth) { %>
+ "passport-twitter": "latest",<% } %><% if (filters.googleAuth) { %>
+ "passport-google-oauth": "latest",<% } %><% if (filters.socketio) { %>
+ "socket.io": "^1.3.5",
+ "socket.io-client": "^1.3.5",
+ "socketio-jwt": "^4.2.0",<% } %>
+ "serve-favicon": "~2.0.1"
},
"devDependencies": {
- "grunt": "~0.4.4",
- "grunt-autoprefixer": "~0.7.2",
- "grunt-wiredep": "~1.8.0",
- "grunt-concurrent": "~0.5.0",
- "grunt-contrib-clean": "~0.5.0",
- "grunt-contrib-concat": "~0.4.0",
- "grunt-contrib-copy": "~0.5.0",
- "grunt-contrib-cssmin": "~0.9.0",
- "grunt-contrib-htmlmin": "~0.2.0",
- "grunt-contrib-imagemin": "~0.7.1",
- "grunt-contrib-jshint": "~0.10.0",
- "grunt-contrib-uglify": "~0.4.0",
- "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",<% } %><% if(filters.babel) { %>
+ "autoprefixer-core": "^5.2.1",
+ "grunt": "~0.4.5",
+ "grunt-wiredep": "^2.0.0",
+ "grunt-concurrent": "^2.0.1",
+ "grunt-contrib-clean": "^0.6.0",
+ "grunt-contrib-concat": "^0.5.1",
+ "grunt-contrib-copy": "^0.8.0",
+ "grunt-contrib-cssmin": "^0.13.0",
+ "grunt-contrib-imagemin": "^0.9.4",
+ "grunt-contrib-jshint": "~0.11.2",
+ "grunt-contrib-uglify": "^0.9.1",
+ "grunt-contrib-watch": "~0.6.1",<% if (filters.coffee) { %>
+ "grunt-contrib-coffee": "^0.13.0",<% } %><% if (filters.jade) { %>
+ "grunt-contrib-jade": "^0.15.0",<% } %><% if (filters.less) { %>
+ "grunt-contrib-less": "^1.0.0",<% } %><% if(filters.babel) { %>
"karma-babel-preprocessor": "^5.2.1",
"grunt-babel": "~5.0.0",<% } %>
"grunt-google-cdn": "~0.4.0",
- "grunt-newer": "~0.7.0",
- "grunt-ng-annotate": "^0.2.3",
- "grunt-rev": "~0.1.0",
- "grunt-svgmin": "~0.4.0",
- "grunt-usemin": "~2.1.1",
+ "grunt-jscs": "^2.0.0",
+ "grunt-newer": "^1.1.1",
+ "grunt-ng-annotate": "^1.0.1",
+ "grunt-filerev": "^2.3.1",
+ "grunt-usemin": "^3.0.0",
"grunt-env": "~0.4.1",
- "grunt-node-inspector": "~0.1.5",
- "grunt-nodemon": "~0.2.0",
+ "grunt-node-inspector": "^0.2.0",
+ "grunt-nodemon": "^0.4.0",
"grunt-angular-templates": "^0.5.4",
"grunt-dom-munger": "^3.4.0",
- "grunt-protractor-runner": "^1.1.0",
- "grunt-injector": "~0.5.4",
- "grunt-karma": "~0.8.2",
- "grunt-build-control": "~0.4.0",
- "grunt-mocha-test": "~0.10.2",<% if(filters.sass) { %>
- "grunt-contrib-sass": "^0.7.3",<% } %><% if(filters.stylus) { %>
+ "grunt-protractor-runner": "^2.0.0",
+ "grunt-injector": "^0.6.0",
+ "grunt-karma": "~0.12.0",
+ "grunt-build-control": "^0.5.0",<% if(filters.sass) { %>
+ "grunt-contrib-sass": "^0.9.0",<% } %><% if(filters.stylus) { %>
"grunt-contrib-stylus": "latest",<% } %>
- "jit-grunt": "^0.5.0",
- "time-grunt": "~0.3.1",
- "grunt-express-server": "~0.4.17",
+ "jit-grunt": "^0.9.1",
+ "time-grunt": "^1.2.1",
+ "grunt-express-server": "^0.5.1",
+ "grunt-postcss": "^0.5.5",
"grunt-open": "~0.2.3",
"open": "~0.0.4",
- "jshint-stylish": "~0.1.5",
- "connect-livereload": "~0.4.0",
+ "jshint-stylish": "~2.0.1",
+ "connect-livereload": "^0.5.3",
+ "mocha": "^2.2.5",
+ "grunt-mocha-test": "~0.12.7",
+ "grunt-mocha-istanbul": "^3.0.1",
+ "istanbul": "^0.3.17",
+ "chai-as-promised": "^5.1.0",
+ "chai-things": "^0.2.0",
+ "sinon-chai": "^2.8.0",<% if (filters.mocha) { %>
+ "karma-mocha": "^0.2.0",
+ "karma-chai-plugins": "^0.6.0",<% } if (filters.jasmine) { %>
+ "jasmine-core": "^2.3.4",
+ "karma-jasmine": "~0.3.0",
+ "jasmine-spec-reporter": "^2.4.0",<% } %>
"karma-ng-scenario": "~0.1.0",
- "karma-firefox-launcher": "~0.1.3",
+ "karma-firefox-launcher": "~0.1.6",
"karma-script-launcher": "~0.1.0",
"karma-html2js-preprocessor": "~0.1.0",
- "karma-ng-jade2js-preprocessor": "^0.1.2",
- "karma-jasmine": "~0.1.5",
- "karma-chrome-launcher": "~0.1.3",
+ "karma-ng-jade2js-preprocessor": "^0.2.0",
+ "karma-chrome-launcher": "~0.2.0",
"requirejs": "~2.1.11",
- "karma-requirejs": "~0.2.1",
- "karma-coffee-preprocessor": "~0.2.1",
+ "karma-requirejs": "~0.2.2",
+ "karma-coffee-preprocessor": "~0.3.0",
"karma-jade-preprocessor": "0.0.11",
- "karma-phantomjs-launcher": "~0.1.4",
- "karma": "~0.12.9",
- "karma-ng-html2js-preprocessor": "~0.1.0",
- "supertest": "~0.11.0",
- "should": "~3.3.1"
+ "karma-phantomjs-launcher": "~0.2.0",
+ "karma": "~0.13.3",
+ "karma-ng-html2js-preprocessor": "~0.1.2",
+ "karma-spec-reporter": "~0.0.20",
+ "proxyquire": "^1.0.1",
+ "supertest": "~0.11.0"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=0.12.0"
},
"scripts": {
- "start": "node server/app.js",
+ "start": "node server",
"test": "grunt test",
"update-webdriver": "node node_modules/grunt-protractor-runner/node_modules/protractor/bin/webdriver-manager update"
},
diff --git a/app/templates/client/app/account(auth)/account(coffee).coffee b/app/templates/client/app/account(auth)/account(coffee).coffee
index 2b7b8b23b..c794d7f04 100644
--- a/app/templates/client/app/account(auth)/account(coffee).coffee
+++ b/app/templates/client/app/account(auth)/account(coffee).coffee
@@ -1,12 +1,20 @@
'use strict'
angular.module '<%= scriptAppName %>'
-<% if(filters.ngroute) { %>.config ($routeProvider) ->
+<% if (filters.ngroute) { %>.config ($routeProvider) ->
$routeProvider
.when '/login',
templateUrl: 'app/account/login/login.html'
controller: 'LoginCtrl'
+ .when '/logout',
+ name: 'logout'
+ referrer: '/'
+ controller: ($location, $route, Auth) ->
+ referrer = $route.current.params.referrer or $route.current.referrer or "/"
+ Auth.logout()
+ $location.path referrer
+
.when '/signup',
templateUrl: 'app/account/signup/signup.html'
controller: 'SignupCtrl'
@@ -15,13 +23,25 @@ angular.module '<%= scriptAppName %>'
templateUrl: 'app/account/settings/settings.html'
controller: 'SettingsCtrl'
authenticate: true
-<% } %><% if(filters.uirouter) { %>.config ($stateProvider) ->
+
+.run ($rootScope) ->
+ $rootScope.$on '$routeChangeStart', (event, next, current) ->
+ next.referrer = current.originalPath if next.name is "logout" and current and current.originalPath and not current.authenticate
+<% } %><% if (filters.uirouter) { %>.config ($stateProvider) ->
$stateProvider
.state 'login',
url: '/login'
templateUrl: 'app/account/login/login.html'
controller: 'LoginCtrl'
+ .state 'logout',
+ url: '/logout?referrer'
+ referrer: 'main'
+ controller: ($state, Auth) ->
+ referrer = $state.params.referrer or $state.current.referrer or "main"
+ Auth.logout()
+ $state.go referrer
+
.state 'signup',
url: '/signup'
templateUrl: 'app/account/signup/signup.html'
@@ -32,4 +52,8 @@ angular.module '<%= scriptAppName %>'
templateUrl: 'app/account/settings/settings.html'
controller: 'SettingsCtrl'
authenticate: true
-<% } %>
\ No newline at end of file
+
+.run ($rootScope) ->
+ $rootScope.$on '$stateChangeStart', (event, next, nextParams, current) ->
+ next.referrer = current.name if next.name is "logout" and current and current.name and not current.authenticate
+<% } %>
diff --git a/app/templates/client/app/account(auth)/account(js).js b/app/templates/client/app/account(auth)/account(js).js
index 0e30543a5..d60fd72fe 100644
--- a/app/templates/client/app/account(auth)/account(js).js
+++ b/app/templates/client/app/account(auth)/account(js).js
@@ -1,12 +1,24 @@
'use strict';
angular.module('<%= scriptAppName %>')
- <% if(filters.ngroute) { %>.config(function ($routeProvider) {
+ <% if (filters.ngroute) { %>.config(function($routeProvider) {
$routeProvider
.when('/login', {
templateUrl: 'app/account/login/login.html',
controller: 'LoginCtrl'
})
+ .when('/logout', {
+ name: 'logout',
+ referrer: '/',
+ template: '',
+ controller: function($location, $route, Auth) {
+ var referrer = $route.current.params.referrer ||
+ $route.current.referrer ||
+ '/';
+ Auth.logout();
+ $location.path(referrer);
+ }
+ })
.when('/signup', {
templateUrl: 'app/account/signup/signup.html',
controller: 'SignupCtrl'
@@ -16,13 +28,32 @@ angular.module('<%= scriptAppName %>')
controller: 'SettingsCtrl',
authenticate: true
});
- });<% } %><% if(filters.uirouter) { %>.config(function ($stateProvider) {
+ })
+ .run(function($rootScope) {
+ $rootScope.$on('$routeChangeStart', function(event, next, current) {
+ if (next.name === 'logout' && current && current.originalPath && !current.authenticate) {
+ next.referrer = current.originalPath;
+ }
+ });
+ });<% } %><% if (filters.uirouter) { %>.config(function($stateProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'app/account/login/login.html',
controller: 'LoginCtrl'
})
+ .state('logout', {
+ url: '/logout?referrer',
+ referrer: 'main',
+ template: '',
+ controller: function($state, Auth) {
+ var referrer = $state.params.referrer ||
+ $state.current.referrer ||
+ 'main';
+ Auth.logout();
+ $state.go(referrer);
+ }
+ })
.state('signup', {
url: '/signup',
templateUrl: 'app/account/signup/signup.html',
@@ -34,4 +65,11 @@ angular.module('<%= scriptAppName %>')
controller: 'SettingsCtrl',
authenticate: true
});
- });<% } %>
\ No newline at end of file
+ })
+ .run(function($rootScope) {
+ $rootScope.$on('$stateChangeStart', function(event, next, nextParams, current) {
+ if (next.name === 'logout' && current && current.name && !current.authenticate) {
+ next.referrer = current.name;
+ }
+ });
+ });<% } %>
diff --git a/app/templates/client/app/account(auth)/login/login(html).html b/app/templates/client/app/account(auth)/login/login(html).html
index 572f2e144..667ecdd0e 100644
--- a/app/templates/client/app/account(auth)/login/login(html).html
+++ b/app/templates/client/app/account(auth)/login/login(html).html
@@ -1,4 +1,4 @@
-
+
-<% if(filters.oauth) {%>
+<% if (filters.oauth) {%>
-
<% if(filters.facebookAuth) {%>
+
<% if (filters.facebookAuth) {%>
Connect with Facebook
- <% } %><% if(filters.googleAuth) {%>
+ <% } %><% if (filters.googleAuth) {%>
Connect with Google+
- <% } %><% if(filters.twitterAuth) {%>
+ <% } %><% if (filters.twitterAuth) {%>
<% } %>
diff --git a/app/templates/client/app/account(auth)/login/login(jade).jade b/app/templates/client/app/account(auth)/login/login(jade).jade
index 4b13c0b13..e7ce91916 100644
--- a/app/templates/client/app/account(auth)/login/login(jade).jade
+++ b/app/templates/client/app/account(auth)/login/login(jade).jade
@@ -1,4 +1,4 @@
-div(ng-include='"components/navbar/navbar.html"')
+navbar
.container
.row
.col-sm-12
@@ -20,7 +20,7 @@ div(ng-include='"components/navbar/navbar.html"')
form.form(name='form', ng-submit='login(form)', novalidate='')
.form-group
label Email
- input.form-control(type='text', name='email', ng-model='user.email')
+ input.form-control(type='email', name='email', ng-model='user.email')
.form-group
label Password
input.form-control(type='password', name='password', ng-model='user.password')
@@ -34,20 +34,20 @@ div(ng-include='"components/navbar/navbar.html"')
button.btn.btn-inverse.btn-lg.btn-login(type='submit')
| Login
= ' '
- a.btn.btn-default.btn-lg.btn-register(href='/signup')
+ a.btn.btn-default.btn-lg.btn-register(<% if (filters.uirouter) { %>ui-sref='signup'<% } else { %>href='/signup'<% } %>)
| Register
-<% if(filters.oauth) {%>
+<% if (filters.oauth) {%>
hr
- div<% if(filters.facebookAuth) {%>
+ div<% if (filters.facebookAuth) {%>
a.btn.btn-facebook(href='', ng-click='loginOauth("facebook")')
i.fa.fa-facebook
| Connect with Facebook
- = ' '<% } %><% if(filters.googleAuth) {%>
+ = ' '<% } %><% if (filters.googleAuth) {%>
a.btn.btn-google-plus(href='', ng-click='loginOauth("google")')
i.fa.fa-google-plus
| Connect with Google+
- = ' '<% } %><% if(filters.twitterAuth) {%>
+ = ' '<% } %><% if (filters.twitterAuth) {%>
a.btn.btn-twitter(href='', ng-click='loginOauth("twitter")')
i.fa.fa-twitter
| Connect with Twitter<% } %><% } %>
diff --git a/app/templates/client/app/account(auth)/login/login(less).less b/app/templates/client/app/account(auth)/login/login(less).less
index bd01a056e..6eaecd90c 100644
--- a/app/templates/client/app/account(auth)/login/login(less).less
+++ b/app/templates/client/app/account(auth)/login/login(less).less
@@ -1,4 +1,4 @@
-<% if(filters.bootstrap) { %>// Colors
+<% if (filters.bootstrap) { %>// Colors
// --------------------------------------------------
@btnText: #fff;
diff --git a/app/templates/client/app/account(auth)/login/login(sass).scss b/app/templates/client/app/account(auth)/login/login(sass).scss
index eb214a8ca..5b6956124 100644
--- a/app/templates/client/app/account(auth)/login/login(sass).scss
+++ b/app/templates/client/app/account(auth)/login/login(sass).scss
@@ -1,4 +1,4 @@
-<% if(filters.bootstrap) { %>// Colors
+<% if (filters.bootstrap) { %>// Colors
// --------------------------------------------------
$btnText: #fff;
diff --git a/app/templates/client/app/account(auth)/login/login.controller(coffee).coffee b/app/templates/client/app/account(auth)/login/login.controller(coffee).coffee
index 3f90c25d7..7bcb69969 100644
--- a/app/templates/client/app/account(auth)/login/login.controller(coffee).coffee
+++ b/app/templates/client/app/account(auth)/login/login.controller(coffee).coffee
@@ -1,7 +1,7 @@
'use strict'
angular.module '<%= scriptAppName %>'
-.controller 'LoginCtrl', ($scope, Auth, $location<% if(filters.oauth) {%>, $window<% } %>) ->
+.controller 'LoginCtrl', ($scope, Auth<% if (filters.ngroute) { %>, $location<% } %><% if (filters.uirouter) { %>, $state<% } %><% if (filters.oauth) {%>, $window<% } %>) ->
$scope.user = {}
$scope.errors = {}
$scope.login = (form) ->
@@ -14,10 +14,10 @@ angular.module '<%= scriptAppName %>'
password: $scope.user.password
.then ->
- $location.path '/'
+ <% if (filters.ngroute) { %>$location.path '/'<% } %><% if (filters.uirouter) { %>$state.go 'main'<% } %>
.catch (err) ->
$scope.errors.other = err.message
-<% if(filters.oauth) {%>
+<% if (filters.oauth) {%>
$scope.loginOauth = (provider) ->
$window.location.href = '/auth/' + provider<% } %>
diff --git a/app/templates/client/app/account(auth)/login/login.controller(js).js b/app/templates/client/app/account(auth)/login/login.controller(js).js
index 7b13da384..2417e62f4 100644
--- a/app/templates/client/app/account(auth)/login/login.controller(js).js
+++ b/app/templates/client/app/account(auth)/login/login.controller(js).js
@@ -1,28 +1,28 @@
'use strict';
angular.module('<%= scriptAppName %>')
- .controller('LoginCtrl', function ($scope, Auth, $location<% if (filters.oauth) { %>, $window<% } %>) {
+ .controller('LoginCtrl', function($scope, Auth<% if (filters.ngroute) { %>, $location<% } %><% if (filters.uirouter) { %>, $state<% } %><% if (filters.oauth) { %>, $window<% } %>) {
$scope.user = {};
$scope.errors = {};
$scope.login = function(form) {
$scope.submitted = true;
- if(form.$valid) {
+ if (form.$valid) {
Auth.login({
email: $scope.user.email,
password: $scope.user.password
})
- .then( function() {
+ .then(function() {
// Logged in, redirect to home
- $location.path('/');
+ <% if (filters.ngroute) { %>$location.path('/');<% } %><% if (filters.uirouter) { %>$state.go('main');<% } %>
})
- .catch( function(err) {
+ .catch(function(err) {
$scope.errors.other = err.message;
});
}
};
-<% if(filters.oauth) {%>
+<% if (filters.oauth) {%>
$scope.loginOauth = function(provider) {
$window.location.href = '/auth/' + provider;
};<% } %>
diff --git a/app/templates/client/app/account(auth)/settings/settings(html).html b/app/templates/client/app/account(auth)/settings/settings(html).html
index bb5d8ded0..ec4e2d820 100644
--- a/app/templates/client/app/account(auth)/settings/settings(html).html
+++ b/app/templates/client/app/account(auth)/settings/settings(html).html
@@ -1,4 +1,4 @@
-
+
@@ -36,4 +36,4 @@
Change Password
-
\ No newline at end of file
+
diff --git a/app/templates/client/app/account(auth)/settings/settings(jade).jade b/app/templates/client/app/account(auth)/settings/settings(jade).jade
index 2dc55d402..96340b522 100644
--- a/app/templates/client/app/account(auth)/settings/settings(jade).jade
+++ b/app/templates/client/app/account(auth)/settings/settings(jade).jade
@@ -1,4 +1,4 @@
-div(ng-include='"components/navbar/navbar.html"')
+navbar
.container
.row
.col-sm-12
diff --git a/app/templates/client/app/account(auth)/settings/settings.controller(js).js b/app/templates/client/app/account(auth)/settings/settings.controller(js).js
index 829bd8248..eeb1219cf 100644
--- a/app/templates/client/app/account(auth)/settings/settings.controller(js).js
+++ b/app/templates/client/app/account(auth)/settings/settings.controller(js).js
@@ -1,21 +1,21 @@
'use strict';
angular.module('<%= scriptAppName %>')
- .controller('SettingsCtrl', function ($scope, User, Auth) {
+ .controller('SettingsCtrl', function($scope, User, Auth) {
$scope.errors = {};
$scope.changePassword = function(form) {
$scope.submitted = true;
- if(form.$valid) {
- Auth.changePassword( $scope.user.oldPassword, $scope.user.newPassword )
- .then( function() {
- $scope.message = 'Password successfully changed.';
- })
- .catch( function() {
- form.password.$setValidity('mongoose', false);
- $scope.errors.other = 'Incorrect password';
- $scope.message = '';
- });
+ if (form.$valid) {
+ Auth.changePassword($scope.user.oldPassword, $scope.user.newPassword)
+ .then(function() {
+ $scope.message = 'Password successfully changed.';
+ })
+ .catch(function() {
+ form.password.$setValidity('mongoose', false);
+ $scope.errors.other = 'Incorrect password';
+ $scope.message = '';
+ });
}
- };
+ };
});
diff --git a/app/templates/client/app/account(auth)/signup/signup(html).html b/app/templates/client/app/account(auth)/signup/signup(html).html
index 59faed568..5052a02ee 100644
--- a/app/templates/client/app/account(auth)/signup/signup(html).html
+++ b/app/templates/client/app/account(auth)/signup/signup(html).html
@@ -1,4 +1,4 @@
-
+
@@ -55,22 +55,22 @@
Sign up
-<% if(filters.oauth) {%>
+<% if (filters.oauth) {%>
-
<% if(filters.facebookAuth) {%>
+
<% if (filters.facebookAuth) {%>
Connect with Facebook
- <% } %><% if(filters.googleAuth) {%>
+ <% } %><% if (filters.googleAuth) {%>
Connect with Google+
- <% } %><% if(filters.twitterAuth) {%>
+ <% } %><% if (filters.twitterAuth) {%>
<% } %>
diff --git a/app/templates/client/app/account(auth)/signup/signup(jade).jade b/app/templates/client/app/account(auth)/signup/signup(jade).jade
index 43815a21c..cca29a28e 100644
--- a/app/templates/client/app/account(auth)/signup/signup(jade).jade
+++ b/app/templates/client/app/account(auth)/signup/signup(jade).jade
@@ -1,4 +1,4 @@
-div(ng-include='"components/navbar/navbar.html"')
+navbar
.container
.row
.col-sm-12
@@ -33,24 +33,24 @@ div(ng-include='"components/navbar/navbar.html"')
| {{ errors.password }}
div
- button.btn.btn-inverse.btn-lg.btn-login(type='submit')
+ button.btn.btn-inverse.btn-lg.btn-register(type='submit')
| Sign up
= ' '
- a.btn.btn-default.btn-lg.btn-register(href='/login')
+ a.btn.btn-default.btn-lg.btn-login(<% if (filters.uirouter) { %>ui-sref='login'<% } else { %>href='/login'<% } %>)
| Login
-<% if(filters.oauth) {%>
+<% if (filters.oauth) {%>
hr
- div<% if(filters.facebookAuth) {%>
+ div<% if (filters.facebookAuth) {%>
a.btn.btn-facebook(href='', ng-click='loginOauth("facebook")')
i.fa.fa-facebook
| Connect with Facebook
- = ' '<% } %><% if(filters.googleAuth) {%>
+ = ' '<% } %><% if (filters.googleAuth) {%>
a.btn.btn-google-plus(href='', ng-click='loginOauth("google")')
i.fa.fa-google-plus
| Connect with Google+
- = ' '<% } %><% if(filters.twitterAuth) {%>
+ = ' '<% } %><% if (filters.twitterAuth) {%>
a.btn.btn-twitter(href='', ng-click='loginOauth("twitter")')
i.fa.fa-twitter
| Connect with Twitter<% } %><% } %>
diff --git a/app/templates/client/app/account(auth)/signup/signup.controller(coffee).coffee b/app/templates/client/app/account(auth)/signup/signup.controller(coffee).coffee
index 1b9c9696f..d167b7e30 100644
--- a/app/templates/client/app/account(auth)/signup/signup.controller(coffee).coffee
+++ b/app/templates/client/app/account(auth)/signup/signup.controller(coffee).coffee
@@ -1,7 +1,7 @@
'use strict'
angular.module '<%= scriptAppName %>'
-.controller 'SignupCtrl', ($scope, Auth, $location<% if(filters.oauth) {%>, $window<% } %>) ->
+.controller 'SignupCtrl', ($scope, Auth<% if (filters.ngroute) { %>, $location<% } %><% if (filters.uirouter) { %>, $state<% } %><% if (filters.oauth) {%>, $window<% } %>) ->
$scope.user = {}
$scope.errors = {}
$scope.register = (form) ->
@@ -15,16 +15,22 @@ angular.module '<%= scriptAppName %>'
password: $scope.user.password
.then ->
- $location.path '/'
+ <% if (filters.ngroute) { %>$location.path '/'<% } %><% if (filters.uirouter) { %>$state.go 'main'<% } %>
.catch (err) ->
err = err.data
$scope.errors = {}
-
+<% if (filters.mongooseModels) { %>
# Update validity of form fields that match the mongoose errors
angular.forEach err.errors, (error, field) ->
form[field].$setValidity 'mongoose', false
- $scope.errors[field] = error.message
-<% if(filters.oauth) {%>
+ $scope.errors[field] = error.message<% }
+ if (filters.sequelizeModels) { %>
+ # Update validity of form fields that match the sequelize errors
+ if err.name
+ angular.forEach err.fields, (field) ->
+ form[field].$setValidity 'mongoose', false
+ $scope.errors[field] = err.message<% } %>
+<% if (filters.oauth) {%>
$scope.loginOauth = (provider) ->
$window.location.href = '/auth/' + provider<% } %>
diff --git a/app/templates/client/app/account(auth)/signup/signup.controller(js).js b/app/templates/client/app/account(auth)/signup/signup.controller(js).js
index 7d6ba3d38..346eb7ea7 100644
--- a/app/templates/client/app/account(auth)/signup/signup.controller(js).js
+++ b/app/templates/client/app/account(auth)/signup/signup.controller(js).js
@@ -1,36 +1,44 @@
'use strict';
angular.module('<%= scriptAppName %>')
- .controller('SignupCtrl', function ($scope, Auth, $location<% if (filters.oauth) { %>, $window<% } %>) {
+ .controller('SignupCtrl', function($scope, Auth<% if (filters.ngroute) { %>, $location<% } %><% if (filters.uirouter) { %>, $state<% } %><% if (filters.oauth) { %>, $window<% } %>) {
$scope.user = {};
$scope.errors = {};
$scope.register = function(form) {
$scope.submitted = true;
- if(form.$valid) {
+ if (form.$valid) {
Auth.createUser({
name: $scope.user.name,
email: $scope.user.email,
password: $scope.user.password
})
- .then( function() {
+ .then(function() {
// Account created, redirect to home
- $location.path('/');
+ <% if (filters.ngroute) { %>$location.path('/');<% } %><% if (filters.uirouter) { %>$state.go('main');<% } %>
})
- .catch( function(err) {
+ .catch(function(err) {
err = err.data;
$scope.errors = {};
-
+<% if (filters.mongooseModels) { %>
// Update validity of form fields that match the mongoose errors
angular.forEach(err.errors, function(error, field) {
form[field].$setValidity('mongoose', false);
$scope.errors[field] = error.message;
- });
+ });<% }
+ if (filters.sequelizeModels) { %>
+ // Update validity of form fields that match the sequelize errors
+ if (err.name) {
+ angular.forEach(err.fields, function(field) {
+ form[field].$setValidity('mongoose', false);
+ $scope.errors[field] = err.message;
+ });
+ }<% } %>
});
}
};
-<% if(filters.oauth) {%>
+<% if (filters.oauth) {%>
$scope.loginOauth = function(provider) {
$window.location.href = '/auth/' + provider;
};<% } %>
diff --git a/app/templates/client/app/admin(auth)/admin(coffee).coffee b/app/templates/client/app/admin(auth)/admin(coffee).coffee
index a0497445e..99b49177f 100644
--- a/app/templates/client/app/admin(auth)/admin(coffee).coffee
+++ b/app/templates/client/app/admin(auth)/admin(coffee).coffee
@@ -1,15 +1,15 @@
'use strict'
angular.module '<%= scriptAppName %>'
-<% if(filters.ngroute) { %>.config ($routeProvider) ->
+<% if (filters.ngroute) { %>.config ($routeProvider) ->
$routeProvider
.when '/admin',
templateUrl: 'app/admin/admin.html'
controller: 'AdminCtrl'
-<% } %><% if(filters.uirouter) { %>.config ($stateProvider) ->
+<% } %><% if (filters.uirouter) { %>.config ($stateProvider) ->
$stateProvider
.state 'admin',
url: '/admin'
templateUrl: 'app/admin/admin.html'
controller: 'AdminCtrl'
-<% } %>
\ No newline at end of file
+<% } %>
diff --git a/app/templates/client/app/admin(auth)/admin(html).html b/app/templates/client/app/admin(auth)/admin(html).html
index 5c27c7af2..7688c9b47 100644
--- a/app/templates/client/app/admin(auth)/admin(html).html
+++ b/app/templates/client/app/admin(auth)/admin(html).html
@@ -1,4 +1,4 @@
-
+
The delete user and user index api routes are restricted to users with the 'admin' role.
@@ -9,4 +9,4 @@
-
\ No newline at end of file
+
diff --git a/app/templates/client/app/admin(auth)/admin(jade).jade b/app/templates/client/app/admin(auth)/admin(jade).jade
index fd80a0bb6..bcef64773 100644
--- a/app/templates/client/app/admin(auth)/admin(jade).jade
+++ b/app/templates/client/app/admin(auth)/admin(jade).jade
@@ -1,4 +1,4 @@
-div(ng-include='"components/navbar/navbar.html"')
+navbar
.container
p
| The delete user and user index api routes are restricted to users with the 'admin' role.
@@ -8,4 +8,4 @@ div(ng-include='"components/navbar/navbar.html"')
br
span.text-muted {{user.email}}
a.trash(ng-click='delete(user)')
- span.glyphicon.glyphicon-trash.pull-right
\ No newline at end of file
+ span.glyphicon.glyphicon-trash.pull-right
diff --git a/app/templates/client/app/admin(auth)/admin(js).js b/app/templates/client/app/admin(auth)/admin(js).js
index 270e8a974..f37ba9fcc 100644
--- a/app/templates/client/app/admin(auth)/admin(js).js
+++ b/app/templates/client/app/admin(auth)/admin(js).js
@@ -1,17 +1,17 @@
'use strict';
angular.module('<%= scriptAppName %>')
- <% if(filters.ngroute) { %>.config(function ($routeProvider) {
+ <% if (filters.ngroute) { %>.config(function($routeProvider) {
$routeProvider
.when('/admin', {
templateUrl: 'app/admin/admin.html',
controller: 'AdminCtrl'
});
- });<% } %><% if(filters.uirouter) { %>.config(function ($stateProvider) {
+ });<% } %><% if (filters.uirouter) { %>.config(function($stateProvider) {
$stateProvider
.state('admin', {
url: '/admin',
templateUrl: 'app/admin/admin.html',
controller: 'AdminCtrl'
});
- });<% } %>
\ No newline at end of file
+ });<% } %>
diff --git a/app/templates/client/app/admin(auth)/admin(less).less b/app/templates/client/app/admin(auth)/admin(less).less
index ad8202750..a6f536dc5 100644
--- a/app/templates/client/app/admin(auth)/admin(less).less
+++ b/app/templates/client/app/admin(auth)/admin(less).less
@@ -1 +1 @@
-.trash { color:rgb(209, 91, 71); }
\ No newline at end of file
+.trash { color:rgb(209, 91, 71); }
diff --git a/app/templates/client/app/admin(auth)/admin(stylus).styl b/app/templates/client/app/admin(auth)/admin(stylus).styl
index d57e50db5..d7d50a172 100644
--- a/app/templates/client/app/admin(auth)/admin(stylus).styl
+++ b/app/templates/client/app/admin(auth)/admin(stylus).styl
@@ -1,2 +1,2 @@
.trash
- color rgb(209, 91, 71)
\ No newline at end of file
+ color rgb(209, 91, 71)
diff --git a/app/templates/client/app/admin(auth)/admin.controller(coffee).coffee b/app/templates/client/app/admin(auth)/admin.controller(coffee).coffee
index 7a16032da..5183df059 100644
--- a/app/templates/client/app/admin(auth)/admin.controller(coffee).coffee
+++ b/app/templates/client/app/admin(auth)/admin.controller(coffee).coffee
@@ -9,4 +9,4 @@ angular.module '<%= scriptAppName %>'
$scope.delete = (user) ->
User.remove id: user._id
- _.remove $scope.users, user
\ No newline at end of file
+ $scope.users.splice @$index, 1
diff --git a/app/templates/client/app/admin(auth)/admin.controller(js).js b/app/templates/client/app/admin(auth)/admin.controller(js).js
index dd6b09405..3cbfd4b7f 100644
--- a/app/templates/client/app/admin(auth)/admin.controller(js).js
+++ b/app/templates/client/app/admin(auth)/admin.controller(js).js
@@ -1,17 +1,13 @@
'use strict';
angular.module('<%= scriptAppName %>')
- .controller('AdminCtrl', function ($scope, $http, Auth, User) {
+ .controller('AdminCtrl', function($scope, $http, Auth, User) {
// Use the User $resource to fetch all users
$scope.users = User.query();
$scope.delete = function(user) {
User.remove({ id: user._id });
- angular.forEach($scope.users, function(u, i) {
- if (u === user) {
- $scope.users.splice(i, 1);
- }
- });
+ $scope.users.splice(this.$index, 1);
};
});
diff --git a/app/templates/client/app/app(coffee).coffee b/app/templates/client/app/app(coffee).coffee
index ea9ae3c95..f0c1bd129 100644
--- a/app/templates/client/app/app(coffee).coffee
+++ b/app/templates/client/app/app(coffee).coffee
@@ -1,39 +1,42 @@
'use strict'
angular.module '<%= scriptAppName %>', [<%= angularModules %>]
-<% if(filters.ngroute) { %>.config ($routeProvider, $locationProvider<% if(filters.auth) { %>, $httpProvider<% } %>) ->
+<% if (filters.ngroute) { %>.config ($routeProvider, $locationProvider<% if (filters.auth) { %>, $httpProvider<% } %>) ->
$routeProvider
.otherwise
redirectTo: '/'
- $locationProvider.html5Mode true<% if(filters.auth) { %>
+ $locationProvider.html5Mode true<% if (filters.auth) { %>
$httpProvider.interceptors.push 'authInterceptor'<% } %>
-<% } %><% if(filters.uirouter) { %>.config ($stateProvider, $urlRouterProvider, $locationProvider<% if(filters.auth) { %>, $httpProvider<% } %>) ->
+<% } %><% if (filters.uirouter) { %>.config ($stateProvider, $urlRouterProvider, $locationProvider<% if (filters.auth) { %>, $httpProvider<% } %>) ->
$urlRouterProvider
.otherwise '/'
- $locationProvider.html5Mode true<% if(filters.auth) { %>
+ $locationProvider.html5Mode true<% if (filters.auth) { %>
$httpProvider.interceptors.push 'authInterceptor'<% } %>
-<% } %><% if(filters.auth) { %>
-.factory 'authInterceptor', ($rootScope, $q, $cookieStore, $location) ->
- # Add authorization token to headers
+<% } %><% if (filters.auth) { %>
+.factory 'authInterceptor', ($rootScope, $q, $cookies<% if (filters.ngroute) { %>, $location<% } if (filters.uirouter) { %>, $injector<% } %>) ->
+ <% if (filters.uirouter) { %>state = null
+ <% } %># Add authorization token to headers
request: (config) ->
config.headers = config.headers or {}
- config.headers.Authorization = 'Bearer ' + $cookieStore.get 'token' if $cookieStore.get 'token'
+ config.headers.Authorization = 'Bearer ' + $cookies.get 'token' if $cookies.get 'token'
config
# Intercept 401s and redirect you to login
responseError: (response) ->
if response.status is 401
- $location.path '/login'
+ <% if (filters.ngroute) { %>$location.path '/login'<% } if (filters.uirouter) { %>(state || state = $injector.get '$state').go 'login'<% } %>
# remove any stale tokens
- $cookieStore.remove 'token'
+ $cookies.remove 'token'
$q.reject response
-.run ($rootScope, $location, Auth) ->
- # Redirect to login if route requires auth and you're not logged in
- $rootScope.$on <% if(filters.ngroute) { %>'$routeChangeStart'<% } %><% if(filters.uirouter) { %>'$stateChangeStart'<% } %>, (event, next) ->
- Auth.isLoggedInAsync (loggedIn) ->
- $location.path "/login" if next.authenticate and not loggedIn
-<% } %>
\ No newline at end of file
+.run ($rootScope<% if (filters.ngroute) { %>, $location<% } %><% if (filters.uirouter) { %>, $state<% } %>, Auth) ->
+ # Redirect to login if route requires auth and the user is not logged in
+ $rootScope.$on <% if (filters.ngroute) { %>'$routeChangeStart'<% } %><% if (filters.uirouter) { %>'$stateChangeStart'<% } %>, (event, next) ->
+ if next.authenticate
+ Auth.isLoggedIn (loggedIn) ->
+ if !loggedIn
+ event.preventDefault()
+ <% if (filters.ngroute) { %>$location.path '/login'<% } %><% if (filters.uirouter) { %>$state.go 'login'<% }} %>
diff --git a/app/templates/client/app/app(css).css b/app/templates/client/app/app(css).css
index f1a61a918..2dbd1e8c5 100644
--- a/app/templates/client/app/app(css).css
+++ b/app/templates/client/app/app(css).css
@@ -1,15 +1,15 @@
-<% if(filters.bootstrap) { %>
+<% if (filters.bootstrap) { %>
/**
* Bootstrap Fonts
*/
@font-face {
- font-family: 'Glyphicons Halflings';
- src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot');
- src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),
- url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'),
- url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'),
- url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+ font-family: 'Glyphicons Halflings';
+ src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot');
+ src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),
+ url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'),
+ url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'),
+ url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}<% } %>
/**
@@ -17,30 +17,30 @@
*/
@font-face {
- font-family: 'FontAwesome';
- src: url('../bower_components/font-awesome/fonts/fontawesome-webfont.eot?v=4.1.0');
- src: url('../bower_components/font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'),
- url('../bower_components/font-awesome/fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'),
- url('../bower_components/font-awesome/fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'),
- url('../bower_components/font-awesome/fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');
- font-weight: normal;
- font-style: normal;
+ font-family: 'FontAwesome';
+ src: url('../bower_components/font-awesome/fonts/fontawesome-webfont.eot?v=4.1.0');
+ src: url('../bower_components/font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'),
+ url('../bower_components/font-awesome/fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'),
+ url('../bower_components/font-awesome/fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'),
+ url('../bower_components/font-awesome/fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');
+ font-weight: normal;
+ font-style: normal;
}
/**
* App-wide Styles
*/
-.browsehappy {
- margin: 0.2em 0;
- background: #ccc;
- color: #000;
- padding: 0.2em 0;
+.browserupgrade {
+ margin: 0.2em 0;
+ background: #ccc;
+ color: #000;
+ padding: 0.2em 0;
}
-<% if (!filters.bootstrap) { %>
+<% if(!filters.bootstrap) { %>
/* Responsive: Portrait tablets and up */
@media screen and (min-width: 768px) {
- .container {
- max-width: 730px;
- }
-}<% } %>
\ No newline at end of file
+ .container {
+ max-width: 730px;
+ }
+}<% } %>
diff --git a/app/templates/client/app/app(js).js b/app/templates/client/app/app(js).js
index c8850ed07..27410af8a 100644
--- a/app/templates/client/app/app(js).js
+++ b/app/templates/client/app/app(js).js
@@ -1,39 +1,40 @@
'use strict';
angular.module('<%= scriptAppName %>', [<%= angularModules %>])
- <% if(filters.ngroute) { %>.config(function ($routeProvider, $locationProvider<% if(filters.auth) { %>, $httpProvider<% } %>) {
+ <% if (filters.ngroute) { %>.config(function($routeProvider, $locationProvider<% if (filters.auth) { %>, $httpProvider<% } %>) {
$routeProvider
.otherwise({
redirectTo: '/'
});
- $locationProvider.html5Mode(true);<% if(filters.auth) { %>
+ $locationProvider.html5Mode(true);<% if (filters.auth) { %>
$httpProvider.interceptors.push('authInterceptor');<% } %>
- })<% } %><% if(filters.uirouter) { %>.config(function ($stateProvider, $urlRouterProvider, $locationProvider<% if(filters.auth) { %>, $httpProvider<% } %>) {
+ })<% } if (filters.uirouter) { %>.config(function($stateProvider, $urlRouterProvider, $locationProvider<% if (filters.auth) { %>, $httpProvider<% } %>) {
$urlRouterProvider
.otherwise('/');
- $locationProvider.html5Mode(true);<% if(filters.auth) { %>
+ $locationProvider.html5Mode(true);<% if (filters.auth) { %>
$httpProvider.interceptors.push('authInterceptor');<% } %>
- })<% } %><% if(filters.auth) { %>
+ })<% } if (filters.auth) { %>
- .factory('authInterceptor', function ($rootScope, $q, $cookieStore, $location) {
- return {
+ .factory('authInterceptor', function($rootScope, $q, $cookies<% if (filters.ngroute) { %>, $location<% } if (filters.uirouter) { %>, $injector<% } %>) {
+ <% if (filters.uirouter) { %>var state;
+ <% } %>return {
// Add authorization token to headers
- request: function (config) {
+ request: function(config) {
config.headers = config.headers || {};
- if ($cookieStore.get('token')) {
- config.headers.Authorization = 'Bearer ' + $cookieStore.get('token');
+ if ($cookies.get('token')) {
+ config.headers.Authorization = 'Bearer ' + $cookies.get('token');
}
return config;
},
// Intercept 401s and redirect you to login
responseError: function(response) {
- if(response.status === 401) {
- $location.path('/login');
+ if (response.status === 401) {
+ <% if (filters.ngroute) { %>$location.path('/login');<% } if (filters.uirouter) { %>(state || (state = $injector.get('$state'))).go('login');<% } %>
// remove any stale tokens
- $cookieStore.remove('token');
+ $cookies.remove('token');
return $q.reject(response);
}
else {
@@ -43,14 +44,16 @@ angular.module('<%= scriptAppName %>', [<%= angularModules %>])
};
})
- .run(function ($rootScope, $location, Auth) {
- // Redirect to login if route requires auth and you're not logged in
- $rootScope.$on(<% if(filters.ngroute) { %>'$routeChangeStart'<% } %><% if(filters.uirouter) { %>'$stateChangeStart'<% } %>, function (event, next) {
- Auth.isLoggedInAsync(function(loggedIn) {
- if (next.authenticate && !loggedIn) {
- event.preventDefault();
- $location.path('/login');
- }
- });
+ .run(function($rootScope<% if (filters.ngroute) { %>, $location<% } if (filters.uirouter) { %>, $state<% } %>, Auth) {
+ // Redirect to login if route requires auth and the user is not logged in
+ $rootScope.$on(<% if (filters.ngroute) { %>'$routeChangeStart'<% } %><% if (filters.uirouter) { %>'$stateChangeStart'<% } %>, function(event, next) {
+ if (next.authenticate) {
+ Auth.isLoggedIn(function(loggedIn) {
+ if (!loggedIn) {
+ event.preventDefault();
+ <% if (filters.ngroute) { %>$location.path('/login');<% } if (filters.uirouter) { %>$state.go('login');<% } %>
+ }
+ });
+ }
});
})<% } %>;
diff --git a/app/templates/client/app/app(less).less b/app/templates/client/app/app(less).less
index 30639f539..cbfffbe88 100644
--- a/app/templates/client/app/app(less).less
+++ b/app/templates/client/app/app(less).less
@@ -1,29 +1,29 @@
-<% if(filters.bootstrap) { %>@import 'bootstrap/less/bootstrap.less';<% } %>
-@import 'font-awesome/less/font-awesome.less';
+<% if (filters.bootstrap) { %>@import '../bower_components/bootstrap/less/bootstrap.less';<% } %>
+@import '../bower_components/font-awesome/less/font-awesome.less';
-<% if(filters.bootstrap) { %>@icon-font-path: '/bower_components/bootstrap/fonts/';<% } %>
-@fa-font-path: '/bower_components/font-awesome/fonts';
+<% if (filters.bootstrap) { %>@icon-font-path: '../bower_components/bootstrap/fonts/';<% } %>
+@fa-font-path: '../bower_components/font-awesome/fonts';
/**
* App-wide Styles
*/
-.browsehappy {
- margin: 0.2em 0;
- background: #ccc;
- color: #000;
- padding: 0.2em 0;
+.browserupgrade {
+ margin: 0.2em 0;
+ background: #ccc;
+ color: #000;
+ padding: 0.2em 0;
}
-<% if (!filters.bootstrap) { %>
+<% if(!filters.bootstrap) { %>
/* Responsive: Portrait tablets and up */
@media screen and (min-width: 768px) {
- .container {
- max-width: 730px;
- }
+ .container {
+ max-width: 730px;
+ }
}
<% } %>
// injector
@import 'account/login/login.less';
@import 'admin/admin.less';
@import 'main/main.less';
-// endinjector
\ No newline at end of file
+// endinjector
diff --git a/app/templates/client/app/app(sass).scss b/app/templates/client/app/app(sass).scss
index 4b8ae7a04..889878aee 100644
--- a/app/templates/client/app/app(sass).scss
+++ b/app/templates/client/app/app(sass).scss
@@ -1,25 +1,25 @@
-<% if(filters.bootstrap) { %>$icon-font-path: "/bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/";<% } %>
-$fa-font-path: "/bower_components/font-awesome/fonts";
-<% if(filters.bootstrap) { %>
-@import 'bootstrap-sass-official/vendor/assets/stylesheets/bootstrap';<% } %>
-@import 'font-awesome/scss/font-awesome';
+<% if (filters.bootstrap) { %>$icon-font-path: "../bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/";<% } %>
+$fa-font-path: "../bower_components/font-awesome/fonts";
+<% if (filters.bootstrap) { %>
+@import '../bower_components/bootstrap-sass-official/vendor/assets/stylesheets/bootstrap';<% } %>
+@import '../bower_components/font-awesome/scss/font-awesome';
/**
* App-wide Styles
*/
-.browsehappy {
- margin: 0.2em 0;
- background: #ccc;
- color: #000;
- padding: 0.2em 0;
+.browserupgrade {
+ margin: 0.2em 0;
+ background: #ccc;
+ color: #000;
+ padding: 0.2em 0;
}
-<% if (!filters.bootstrap) { %>
+<% if(!filters.bootstrap) { %>
/* Responsive: Portrait tablets and up */
@media screen and (min-width: 768px) {
- .container {
- max-width: 730px;
- }
+ .container {
+ max-width: 730px;
+ }
}
<% } %>
// Component styles are injected through grunt
@@ -27,4 +27,4 @@ $fa-font-path: "/bower_components/font-awesome/fonts";
@import 'account/login/login.scss';
@import 'admin/admin.scss';
@import 'main/main.scss';
-// endinjector
\ No newline at end of file
+// endinjector
diff --git a/app/templates/client/app/app(stylus).styl b/app/templates/client/app/app(stylus).styl
index b7e4bb9c1..d25cdfc59 100644
--- a/app/templates/client/app/app(stylus).styl
+++ b/app/templates/client/app/app(stylus).styl
@@ -1,17 +1,17 @@
-@import "font-awesome/css/font-awesome.css"
-<% if(filters.bootstrap) { %>@import "bootstrap/dist/css/bootstrap.css"
+@import "../bower_components/font-awesome/css/font-awesome.css"
+<% if (filters.bootstrap) { %>@import "../bower_components/bootstrap/dist/css/bootstrap.css"
//
// Bootstrap Fonts
//
@font-face
- font-family: 'Glyphicons Halflings'
- src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot')
- src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),
- url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'),
- url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'),
- url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+ font-family: 'Glyphicons Halflings'
+ src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot')
+ src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),
+ url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'),
+ url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'),
+ url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
<% } %>
//
// Font Awesome Fonts
@@ -31,20 +31,20 @@
// App-wide Styles
//
-.browsehappy
- background #ccc
- color #000
- margin 0.2em 0
- padding 0.2em 0
-<% if (!filters.bootstrap) { %>
+.browserupgrade
+ background #ccc
+ color #000
+ margin 0.2em 0
+ padding 0.2em 0
+<% if(!filters.bootstrap) { %>
// Responsive: Portrait tablets and up
@media screen and (min-width: 768px)
- .container
- max-width 730px
+ .container
+ max-width 730px
<% } %>
// Component styles are injected through grunt
// injector
@import "account/login/login"
@import "admin/admin"
@import "main/main"
-// endinjector
\ No newline at end of file
+// endinjector
diff --git a/app/templates/client/app/main/main(coffee).coffee b/app/templates/client/app/main/main(coffee).coffee
index 6d84bdc1e..04cd367bb 100644
--- a/app/templates/client/app/main/main(coffee).coffee
+++ b/app/templates/client/app/main/main(coffee).coffee
@@ -1,15 +1,15 @@
'use strict'
angular.module '<%= scriptAppName %>'
-<% if(filters.ngroute) { %>.config ($routeProvider) ->
+<% if (filters.ngroute) { %>.config ($routeProvider) ->
$routeProvider
.when '/',
templateUrl: 'app/main/main.html'
controller: 'MainCtrl'
-<% } %><% if(filters.uirouter) { %>.config ($stateProvider) ->
+<% } %><% if (filters.uirouter) { %>.config ($stateProvider) ->
$stateProvider
.state 'main',
url: '/'
templateUrl: 'app/main/main.html'
controller: 'MainCtrl'
-<% } %>
\ No newline at end of file
+<% } %>
diff --git a/app/templates/client/app/main/main(css).css b/app/templates/client/app/main/main(css).css
index c396852d6..b49092ec1 100644
--- a/app/templates/client/app/main/main(css).css
+++ b/app/templates/client/app/main/main(css).css
@@ -1,34 +1,27 @@
.thing-form {
- margin: 20px 0;
+ margin: 20px 0;
}
#banner {
- border-bottom: none;
- margin-top: -20px;
+ border-bottom: none;
+ margin-top: -20px;
}
#banner h1 {
- font-size: 60px;
- line-height: 1;
- letter-spacing: -1px;
+ font-size: 60px;
+ line-height: 1;
+ letter-spacing: -1px;
}
.hero-unit {
- position: relative;
- padding: 30px 15px;
- color: #F5F5F5;
- text-align: center;
- text-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
- background: #4393B9;
-}
-
-.footer {
- text-align: center;
- padding: 30px 0;
- margin-top: 70px;
- border-top: 1px solid #E5E5E5;
+ position: relative;
+ padding: 30px 15px;
+ color: #F5F5F5;
+ text-align: center;
+ text-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
+ background: #4393B9;
}
.navbar-text {
- margin-left: 15px;
-}
\ No newline at end of file
+ margin-left: 15px;
+}
diff --git a/app/templates/client/app/main/main(html).html b/app/templates/client/app/main/main(html).html
index cd0f185b2..0d745d9a8 100644
--- a/app/templates/client/app/main/main(html).html
+++ b/app/templates/client/app/main/main(html).html
@@ -1,4 +1,4 @@
-
+
@@ -13,10 +13,10 @@
'Allo, 'Allo!
-
<% if(filters.socketio) { %>
+ <% if (filters.socketio) { %>
<% } %>
-
+
diff --git a/app/templates/client/app/main/main(jade).jade b/app/templates/client/app/main/main(jade).jade
index 76784c855..3277e7b05 100644
--- a/app/templates/client/app/main/main(jade).jade
+++ b/app/templates/client/app/main/main(jade).jade
@@ -1,4 +1,4 @@
-div(ng-include='"components/navbar/navbar.html"')
+navbar
header#banner.hero-unit
.container
@@ -13,8 +13,8 @@ header#banner.hero-unit
ul.nav.nav-tabs.nav-stacked.col-md-4.col-lg-4.col-sm-6(ng-repeat='thing in awesomeThings')
li
a(href='#', tooltip='{{thing.info}}')
- | {{thing.name}}<% if(filters.socketio) { %>
- button.close(type='button', ng-click='deleteThing(thing)') ×<% } %><% if(filters.socketio) { %>
+ | {{thing.name}}<% if (filters.socketio) { %>
+ button.close(type='button', ng-click='deleteThing(thing)') ×<% } %><% if (filters.socketio) { %>
form.thing-form
label Syncs in realtime across clients
@@ -23,11 +23,4 @@ header#banner.hero-unit
span.input-group-btn
button.btn.btn-primary(type='submit', ng-click='addThing()') Add New<% } %>
-footer.footer
- .container
- p
- | Angular Fullstack v<%= pkg.version %>
- = ' | '
- a(href='https://twitter.com/tyhenkel') @tyhenkel
- = ' | '
- a(href='https://github.com/DaftMonk/generator-angular-fullstack/issues?state=open') Issues
\ No newline at end of file
+footer
diff --git a/app/templates/client/app/main/main(js).js b/app/templates/client/app/main/main(js).js
index 1d3bc318a..165181ffe 100644
--- a/app/templates/client/app/main/main(js).js
+++ b/app/templates/client/app/main/main(js).js
@@ -1,17 +1,17 @@
'use strict';
angular.module('<%= scriptAppName %>')
- <% if(filters.ngroute) { %>.config(function ($routeProvider) {
+ <% if (filters.ngroute) { %>.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'app/main/main.html',
controller: 'MainCtrl'
});
- });<% } %><% if(filters.uirouter) { %>.config(function ($stateProvider) {
+ });<% } %><% if (filters.uirouter) { %>.config(function($stateProvider) {
$stateProvider
.state('main', {
url: '/',
templateUrl: 'app/main/main.html',
controller: 'MainCtrl'
});
- });<% } %>
\ No newline at end of file
+ });<% } %>
diff --git a/app/templates/client/app/main/main(less).less b/app/templates/client/app/main/main(less).less
index 39636ab2d..b49092ec1 100644
--- a/app/templates/client/app/main/main(less).less
+++ b/app/templates/client/app/main/main(less).less
@@ -3,32 +3,25 @@
}
#banner {
- border-bottom: none;
- margin-top: -20px;
+ border-bottom: none;
+ margin-top: -20px;
}
#banner h1 {
- font-size: 60px;
- line-height: 1;
- letter-spacing: -1px;
+ font-size: 60px;
+ line-height: 1;
+ letter-spacing: -1px;
}
.hero-unit {
- position: relative;
- padding: 30px 15px;
- color: #F5F5F5;
- text-align: center;
- text-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
- background: #4393B9;
-}
-
-.footer {
- text-align: center;
- padding: 30px 0;
- margin-top: 70px;
- border-top: 1px solid #E5E5E5;
+ position: relative;
+ padding: 30px 15px;
+ color: #F5F5F5;
+ text-align: center;
+ text-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
+ background: #4393B9;
}
.navbar-text {
- margin-left: 15px;
-}
\ No newline at end of file
+ margin-left: 15px;
+}
diff --git a/app/templates/client/app/main/main(sass).scss b/app/templates/client/app/main/main(sass).scss
index aa19c3649..b49092ec1 100644
--- a/app/templates/client/app/main/main(sass).scss
+++ b/app/templates/client/app/main/main(sass).scss
@@ -1,34 +1,27 @@
.thing-form {
- margin: 20px 0;
+ margin: 20px 0;
}
#banner {
- border-bottom: none;
- margin-top: -20px;
+ border-bottom: none;
+ margin-top: -20px;
}
#banner h1 {
- font-size: 60px;
- line-height: 1;
- letter-spacing: -1px;
+ font-size: 60px;
+ line-height: 1;
+ letter-spacing: -1px;
}
.hero-unit {
- position: relative;
- padding: 30px 15px;
- color: #F5F5F5;
- text-align: center;
- text-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
- background: #4393B9;
-}
-
-.footer {
- text-align: center;
- padding: 30px 0;
- margin-top: 70px;
- border-top: 1px solid #E5E5E5;
+ position: relative;
+ padding: 30px 15px;
+ color: #F5F5F5;
+ text-align: center;
+ text-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
+ background: #4393B9;
}
.navbar-text {
margin-left: 15px;
-}
\ No newline at end of file
+}
diff --git a/app/templates/client/app/main/main(stylus).styl b/app/templates/client/app/main/main(stylus).styl
index 9ba91c3a3..c3915218c 100644
--- a/app/templates/client/app/main/main(stylus).styl
+++ b/app/templates/client/app/main/main(stylus).styl
@@ -1,28 +1,22 @@
.thing-form
- margin 20px 0
+ margin 20px 0
#banner
- border-bottom none
- margin-top -20px
+ border-bottom none
+ margin-top -20px
#banner h1
- font-size 60px
- letter-spacing -1px
- line-height 1
+ font-size 60px
+ letter-spacing -1px
+ line-height 1
.hero-unit
- background #4393B9
- color #F5F5F5
- padding 30px 15px
- position relative
- text-align center
- text-shadow 0 1px 0 rgba(0, 0, 0, 0.1)
-
-.footer
- border-top 1px solid #E5E5E5
- margin-top 70px
- padding 30px 0
- text-align center
+ background #4393B9
+ color #F5F5F5
+ padding 30px 15px
+ position relative
+ text-align center
+ text-shadow 0 1px 0 rgba(0, 0, 0, 0.1)
.navbar-text
- margin-left 15px
\ No newline at end of file
+ margin-left 15px
diff --git a/app/templates/client/app/main/main.controller(coffee).coffee b/app/templates/client/app/main/main.controller(coffee).coffee
index 143e7f387..4b04a951b 100644
--- a/app/templates/client/app/main/main.controller(coffee).coffee
+++ b/app/templates/client/app/main/main.controller(coffee).coffee
@@ -1,13 +1,13 @@
'use strict'
angular.module '<%= scriptAppName %>'
-.controller 'MainCtrl', ($scope, $http<% if(filters.socketio) { %>, socket<% } %>) ->
+.controller 'MainCtrl', ($scope, $http<% if (filters.socketio) { %>, socket<% } %>) ->
$scope.awesomeThings = []
$http.get('/api/things').success (awesomeThings) ->
$scope.awesomeThings = awesomeThings
- <% if(filters.socketio) { %>socket.syncUpdates 'thing', $scope.awesomeThings<% } %>
-<% if(filters.mongoose) { %>
+ <% if (filters.socketio) { %>socket.syncUpdates 'thing', $scope.awesomeThings<% } %>
+<% if (filters.models) { %>
$scope.addThing = ->
return if $scope.newThing is ''
$http.post '/api/things',
@@ -16,7 +16,7 @@ angular.module '<%= scriptAppName %>'
$scope.newThing = ''
$scope.deleteThing = (thing) ->
- $http.delete '/api/things/' + thing._id<% } %><% if(filters.socketio) { %>
+ $http.delete '/api/things/' + thing._id<% } %><% if (filters.socketio) { %>
$scope.$on '$destroy', ->
socket.unsyncUpdates 'thing'<% } %>
diff --git a/app/templates/client/app/main/main.controller(js).js b/app/templates/client/app/main/main.controller(js).js
index 433a10fe4..345d9909d 100644
--- a/app/templates/client/app/main/main.controller(js).js
+++ b/app/templates/client/app/main/main.controller(js).js
@@ -1,16 +1,16 @@
'use strict';
angular.module('<%= scriptAppName %>')
- .controller('MainCtrl', function ($scope, $http<% if(filters.socketio) { %>, socket<% } %>) {
+ .controller('MainCtrl', function($scope, $http<% if (filters.socketio) { %>, socket<% } %>) {
$scope.awesomeThings = [];
$http.get('/api/things').success(function(awesomeThings) {
- $scope.awesomeThings = awesomeThings;<% if(filters.socketio) { %>
+ $scope.awesomeThings = awesomeThings;<% if (filters.socketio) { %>
socket.syncUpdates('thing', $scope.awesomeThings);<% } %>
});
-<% if(filters.mongoose) { %>
+<% if (filters.models) { %>
$scope.addThing = function() {
- if($scope.newThing === '') {
+ if ($scope.newThing === '') {
return;
}
$http.post('/api/things', { name: $scope.newThing });
@@ -19,9 +19,9 @@ angular.module('<%= scriptAppName %>')
$scope.deleteThing = function(thing) {
$http.delete('/api/things/' + thing._id);
- };<% } %><% if(filters.socketio) { %>
+ };<% } %><% if (filters.socketio) { %>
- $scope.$on('$destroy', function () {
+ $scope.$on('$destroy', function() {
socket.unsyncUpdates('thing');
});<% } %>
});
diff --git a/app/templates/client/app/main/main.controller.spec(coffee).coffee b/app/templates/client/app/main/main.controller.spec(coffee).coffee
index efe9b39a6..a72ae8695 100644
--- a/app/templates/client/app/main/main.controller.spec(coffee).coffee
+++ b/app/templates/client/app/main/main.controller.spec(coffee).coffee
@@ -3,15 +3,17 @@
describe 'Controller: MainCtrl', ->
# load the controller's module
- beforeEach module '<%= scriptAppName %>' <% if(filters.socketio) {%>
+ beforeEach module '<%= scriptAppName %>' <% if (filters.uirouter) {%>
+ beforeEach module 'stateMock' <% } %><% if (filters.socketio) {%>
beforeEach module 'socketMock' <% } %>
MainCtrl = undefined
- scope = undefined
+ scope = undefined<% if (filters.uirouter) {%>
+ state = undefined<% } %>
$httpBackend = undefined
# Initialize the controller and a mock scope
- beforeEach inject (_$httpBackend_, $controller, $rootScope) ->
+ beforeEach inject (_$httpBackend_, $controller, $rootScope<% if (filters.uirouter) {%>, $state<% } %>) ->
$httpBackend = _$httpBackend_
$httpBackend.expectGET('/api/things').respond [
'HTML5 Boilerplate'
@@ -19,10 +21,12 @@ describe 'Controller: MainCtrl', ->
'Karma'
'Express'
]
- scope = $rootScope.$new()
+ scope = $rootScope.$new()<% if (filters.uirouter) {%>
+ state = $state<% } %>
MainCtrl = $controller 'MainCtrl',
$scope: scope
it 'should attach a list of things to the scope', ->
- $httpBackend.flush()
- expect(scope.awesomeThings.length).toBe 4
\ No newline at end of file
+ $httpBackend.flush()<% if (filters.jasmine) { %>
+ expect(scope.awesomeThings.length).toBe 4 <% } if (filters.mocha) { %>
+ <%= does("scope.awesomeThings.length") %>.equal 4<% } %>
diff --git a/app/templates/client/app/main/main.controller.spec(js).js b/app/templates/client/app/main/main.controller.spec(js).js
index 373e9db08..71fd2a783 100644
--- a/app/templates/client/app/main/main.controller.spec(js).js
+++ b/app/templates/client/app/main/main.controller.spec(js).js
@@ -1,29 +1,33 @@
'use strict';
-describe('Controller: MainCtrl', function () {
+describe('Controller: MainCtrl', function() {
// load the controller's module
- beforeEach(module('<%= scriptAppName %>'));<% if(filters.socketio) {%>
+ beforeEach(module('<%= scriptAppName %>'));<% if (filters.uirouter) {%>
+ beforeEach(module('stateMock'));<% } %><% if (filters.socketio) {%>
beforeEach(module('socketMock'));<% } %>
- var MainCtrl,
- scope,
- $httpBackend;
+ var MainCtrl;
+ var scope;<% if (filters.uirouter) {%>
+ var state;<% } %>
+ var $httpBackend;
// Initialize the controller and a mock scope
- beforeEach(inject(function (_$httpBackend_, $controller, $rootScope) {
+ beforeEach(inject(function(_$httpBackend_, $controller, $rootScope<% if (filters.uirouter) {%>, $state<% } %>) {
$httpBackend = _$httpBackend_;
$httpBackend.expectGET('/api/things')
.respond(['HTML5 Boilerplate', 'AngularJS', 'Karma', 'Express']);
- scope = $rootScope.$new();
+ scope = $rootScope.$new();<% if (filters.uirouter) {%>
+ state = $state;<% } %>
MainCtrl = $controller('MainCtrl', {
$scope: scope
});
}));
- it('should attach a list of things to the scope', function () {
- $httpBackend.flush();
- expect(scope.awesomeThings.length).toBe(4);
+ it('should attach a list of things to the scope', function() {
+ $httpBackend.flush();<% if (filters.jasmine) { %>
+ expect(scope.awesomeThings.length).toBe(4);<% } if (filters.mocha) { %>
+ <%= does("scope.awesomeThings.length") %>.equal(4);<% } %>
});
});
diff --git a/app/templates/client/components/auth(auth)/auth.service(coffee).coffee b/app/templates/client/components/auth(auth)/auth.service(coffee).coffee
index ac503ed0b..2892d04ed 100644
--- a/app/templates/client/components/auth(auth)/auth.service(coffee).coffee
+++ b/app/templates/client/components/auth(auth)/auth.service(coffee).coffee
@@ -1,43 +1,41 @@
'use strict'
angular.module '<%= scriptAppName %>'
-.factory 'Auth', ($location, $rootScope, $http, User, $cookieStore, $q) ->
- currentUser = if $cookieStore.get 'token' then User.get() else {}
+.factory 'Auth', ($http, User, $cookies, $q) ->
+ currentUser = if $cookies.get 'token' then User.get() else {}
###
Authenticate user and save token
@param {Object} user - login info
- @param {Function} callback - optional
+ @param {Function} callback - optional, function(error, user)
@return {Promise}
###
login: (user, callback) ->
- deferred = $q.defer()
$http.post '/auth/local',
email: user.email
password: user.password
- .success (data) ->
- $cookieStore.put 'token', data.token
+ .then (res) ->
+ $cookies.put 'token', res.data.token
currentUser = User.get()
- deferred.resolve data
- callback?()
+ currentUser.$promise
- .error (err) =>
- @logout()
- deferred.reject err
- callback? err
+ .then (user) ->
+ callback? null, user
+ user
- deferred.promise
+ .catch (err) =>
+ @logout()
+ callback? err.data
+ $q.reject err.data
###
Delete access token and user info
-
- @param {Function}
###
logout: ->
- $cookieStore.remove 'token'
+ $cookies.remove 'token'
currentUser = {}
return
@@ -46,15 +44,15 @@ angular.module '<%= scriptAppName %>'
Create a new user
@param {Object} user - user info
- @param {Function} callback - optional
+ @param {Function} callback - optional, function(error, user)
@return {Promise}
###
createUser: (user, callback) ->
User.save user,
(data) ->
- $cookieStore.put 'token', data.token
+ $cookies.put 'token', data.token
currentUser = User.get()
- callback? user
+ callback? null, user
, (err) =>
@logout()
@@ -68,7 +66,7 @@ angular.module '<%= scriptAppName %>'
@param {String} oldPassword
@param {String} newPassword
- @param {Function} callback - optional
+ @param {Function} callback - optional, function(error, user)
@return {Promise}
###
changePassword: (oldPassword, newPassword, callback) ->
@@ -78,8 +76,8 @@ angular.module '<%= scriptAppName %>'
oldPassword: oldPassword
newPassword: newPassword
- , (user) ->
- callback? user
+ , () ->
+ callback? null
, (err) ->
callback? err
@@ -88,49 +86,65 @@ angular.module '<%= scriptAppName %>'
###
- Gets all available info on authenticated user
+ Gets all available info on a user
+ (synchronous|asynchronous)
- @return {Object} user
+ @param {Function|*} callback - optional, funciton(user)
+ @return {Object|Promise}
###
- getCurrentUser: ->
- currentUser
+ getCurrentUser: (callback) ->
+ return currentUser if arguments.length is 0
+ value = if (currentUser.hasOwnProperty("$promise")) then currentUser.$promise else currentUser
+ $q.when value
- ###
- Check if a user is logged in synchronously
+ .then (user) ->
+ callback? user
+ user
- @return {Boolean}
- ###
- isLoggedIn: ->
- currentUser.hasOwnProperty 'role'
+ , ->
+ callback? {}
+ {}
###
- Waits for currentUser to resolve before checking if user is logged in
+ Check if a user is logged in
+ (synchronous|asynchronous)
+
+ @param {Function|*} callback - optional, function(is)
+ @return {Bool|Promise}
###
- isLoggedInAsync: (callback) ->
- if currentUser.hasOwnProperty '$promise'
- currentUser.$promise.then ->
- callback? true
- return
- .catch ->
- callback? false
- return
+ isLoggedIn: (callback) ->
+ return currentUser.hasOwnProperty("role") if arguments.length is 0
+
+ @getCurrentUser null
+
+ .then (user) ->
+ is_ = user.hasOwnProperty("role")
+ callback? is_
+ is_
- else
- callback? currentUser.hasOwnProperty 'role'
###
Check if a user is an admin
+ (synchronous|asynchronous)
- @return {Boolean}
+ @param {Function|*} callback - optional, function(is)
+ @return {Bool|Promise}
###
- isAdmin: ->
- currentUser.role is 'admin'
+ isAdmin: (callback) ->
+ return currentUser.role is "admin" if arguments.length is 0
+
+ @getCurrentUser null
+
+ .then (user) ->
+ is_ = user.role is "admin"
+ callback? is_
+ is_
###
Get auth token
###
getToken: ->
- $cookieStore.get 'token'
+ $cookies.get 'token'
diff --git a/app/templates/client/components/auth(auth)/auth.service(js).js b/app/templates/client/components/auth(auth)/auth.service(js).js
index 9afb12da9..2a1fcb480 100644
--- a/app/templates/client/components/auth(auth)/auth.service(js).js
+++ b/app/templates/client/components/auth(auth)/auth.service(js).js
@@ -1,9 +1,20 @@
'use strict';
angular.module('<%= scriptAppName %>')
- .factory('Auth', function Auth($location, $rootScope, $http, User, $cookieStore, $q) {
- var currentUser = {};
- if($cookieStore.get('token')) {
+ .factory('Auth', function Auth($http, User, $cookies, $q) {
+ /**
+ * Return a callback or noop function
+ *
+ * @param {Function|*} cb - a 'potential' function
+ * @return {Function}
+ */
+ var safeCb = function(cb) {
+ return (angular.isFunction(cb)) ? cb : angular.noop;
+ },
+
+ currentUser = {};
+
+ if ($cookies.get('token')) {
currentUser = User.get();
}
@@ -13,39 +24,35 @@ angular.module('<%= scriptAppName %>')
* Authenticate user and save token
*
* @param {Object} user - login info
- * @param {Function} callback - optional
+ * @param {Function} callback - optional, function(error, user)
* @return {Promise}
*/
login: function(user, callback) {
- var cb = callback || angular.noop;
- var deferred = $q.defer();
-
- $http.post('/auth/local', {
+ return $http.post('/auth/local', {
email: user.email,
password: user.password
- }).
- success(function(data) {
- $cookieStore.put('token', data.token);
+ })
+ .then(function(res) {
+ $cookies.put('token', res.data.token);
currentUser = User.get();
- deferred.resolve(data);
- return cb();
- }).
- error(function(err) {
+ return currentUser.$promise;
+ })
+ .then(function(user) {
+ safeCb(callback)(null, user);
+ return user;
+ })
+ .catch(function(err) {
this.logout();
- deferred.reject(err);
- return cb(err);
+ safeCb(callback)(err.data);
+ return $q.reject(err.data);
}.bind(this));
-
- return deferred.promise;
},
/**
* Delete access token and user info
- *
- * @param {Function}
*/
logout: function() {
- $cookieStore.remove('token');
+ $cookies.remove('token');
currentUser = {};
},
@@ -53,21 +60,19 @@ angular.module('<%= scriptAppName %>')
* Create a new user
*
* @param {Object} user - user info
- * @param {Function} callback - optional
+ * @param {Function} callback - optional, function(error, user)
* @return {Promise}
*/
createUser: function(user, callback) {
- var cb = callback || angular.noop;
-
return User.save(user,
function(data) {
- $cookieStore.put('token', data.token);
+ $cookies.put('token', data.token);
currentUser = User.get();
- return cb(user);
+ return safeCb(callback)(null, user);
},
function(err) {
this.logout();
- return cb(err);
+ return safeCb(callback)(err);
}.bind(this)).$promise;
},
@@ -76,71 +81,90 @@ angular.module('<%= scriptAppName %>')
*
* @param {String} oldPassword
* @param {String} newPassword
- * @param {Function} callback - optional
+ * @param {Function} callback - optional, function(error, user)
* @return {Promise}
*/
changePassword: function(oldPassword, newPassword, callback) {
- var cb = callback || angular.noop;
-
return User.changePassword({ id: currentUser._id }, {
oldPassword: oldPassword,
newPassword: newPassword
- }, function(user) {
- return cb(user);
+ }, function() {
+ return safeCb(callback)(null);
}, function(err) {
- return cb(err);
+ return safeCb(callback)(err);
}).$promise;
},
/**
- * Gets all available info on authenticated user
+ * Gets all available info on a user
+ * (synchronous|asynchronous)
*
- * @return {Object} user
+ * @param {Function|*} callback - optional, funciton(user)
+ * @return {Object|Promise}
*/
- getCurrentUser: function() {
- return currentUser;
+ getCurrentUser: function(callback) {
+ if (arguments.length === 0) {
+ return currentUser;
+ }
+
+ var value = (currentUser.hasOwnProperty('$promise')) ? currentUser.$promise : currentUser;
+ return $q.when(value)
+ .then(function(user) {
+ safeCb(callback)(user);
+ return user;
+ }, function() {
+ safeCb(callback)({});
+ return {};
+ });
},
/**
* Check if a user is logged in
+ * (synchronous|asynchronous)
*
- * @return {Boolean}
+ * @param {Function|*} callback - optional, function(is)
+ * @return {Bool|Promise}
*/
- isLoggedIn: function() {
- return currentUser.hasOwnProperty('role');
- },
+ isLoggedIn: function(callback) {
+ if (arguments.length === 0) {
+ return currentUser.hasOwnProperty('role');
+ }
- /**
- * Waits for currentUser to resolve before checking if user is logged in
- */
- isLoggedInAsync: function(cb) {
- if(currentUser.hasOwnProperty('$promise')) {
- currentUser.$promise.then(function() {
- cb(true);
- }).catch(function() {
- cb(false);
+ return this.getCurrentUser(null)
+ .then(function(user) {
+ var is = user.hasOwnProperty('role');
+ safeCb(callback)(is);
+ return is;
});
- } else if(currentUser.hasOwnProperty('role')) {
- cb(true);
- } else {
- cb(false);
- }
},
- /**
- * Check if a user is an admin
- *
- * @return {Boolean}
- */
- isAdmin: function() {
- return currentUser.role === 'admin';
+ /**
+ * Check if a user is an admin
+ * (synchronous|asynchronous)
+ *
+ * @param {Function|*} callback - optional, function(is)
+ * @return {Bool|Promise}
+ */
+ isAdmin: function(callback) {
+ if (arguments.length === 0) {
+ return currentUser.role === 'admin';
+ }
+
+ return this.getCurrentUser(null)
+ .then(function(user) {
+ var is = user.role === 'admin';
+ safeCb(callback)(is);
+ return is;
+ });
},
/**
* Get auth token
+ *
+ * @return {String} - a token string used for authenticating
*/
getToken: function() {
- return $cookieStore.get('token');
+ return $cookies.get('token');
}
};
});
diff --git a/app/templates/client/components/footer/footer(css).css b/app/templates/client/components/footer/footer(css).css
new file mode 100644
index 000000000..cd1753eed
--- /dev/null
+++ b/app/templates/client/components/footer/footer(css).css
@@ -0,0 +1,6 @@
+footer.footer {
+ text-align: center;
+ padding: 30px 0;
+ margin-top: 70px;
+ border-top: 1px solid #E5E5E5;
+}
diff --git a/app/templates/client/components/footer/footer(html).html b/app/templates/client/components/footer/footer(html).html
new file mode 100644
index 000000000..3f9f7ffb9
--- /dev/null
+++ b/app/templates/client/components/footer/footer(html).html
@@ -0,0 +1,6 @@
+
diff --git a/app/templates/client/components/footer/footer(jade).jade b/app/templates/client/components/footer/footer(jade).jade
new file mode 100644
index 000000000..a0bd84a1d
--- /dev/null
+++ b/app/templates/client/components/footer/footer(jade).jade
@@ -0,0 +1,7 @@
+.container
+ p
+ | Angular Fullstack v<%= pkg.version %>
+ = ' | '
+ a(href='https://twitter.com/tyhenkel') @tyhenkel
+ = ' | '
+ a(href='https://github.com/DaftMonk/generator-angular-fullstack/issues?state=open') Issues
diff --git a/app/templates/client/components/footer/footer(less).less b/app/templates/client/components/footer/footer(less).less
new file mode 100644
index 000000000..cd1753eed
--- /dev/null
+++ b/app/templates/client/components/footer/footer(less).less
@@ -0,0 +1,6 @@
+footer.footer {
+ text-align: center;
+ padding: 30px 0;
+ margin-top: 70px;
+ border-top: 1px solid #E5E5E5;
+}
diff --git a/app/templates/client/components/footer/footer(sass).scss b/app/templates/client/components/footer/footer(sass).scss
new file mode 100644
index 000000000..cd1753eed
--- /dev/null
+++ b/app/templates/client/components/footer/footer(sass).scss
@@ -0,0 +1,6 @@
+footer.footer {
+ text-align: center;
+ padding: 30px 0;
+ margin-top: 70px;
+ border-top: 1px solid #E5E5E5;
+}
diff --git a/app/templates/client/components/footer/footer(stylus).styl b/app/templates/client/components/footer/footer(stylus).styl
new file mode 100644
index 000000000..ad725136b
--- /dev/null
+++ b/app/templates/client/components/footer/footer(stylus).styl
@@ -0,0 +1,5 @@
+footer.footer
+ border-top 1px solid #E5E5E5
+ margin-top 70px
+ padding 30px 0
+ text-align center
diff --git a/app/templates/client/components/footer/footer.directive(coffee).coffee b/app/templates/client/components/footer/footer.directive(coffee).coffee
new file mode 100644
index 000000000..467006759
--- /dev/null
+++ b/app/templates/client/components/footer/footer.directive(coffee).coffee
@@ -0,0 +1,8 @@
+'use strict'
+
+angular.module '<%= scriptAppName %>'
+.directive 'footer', ->
+ templateUrl: 'components/footer/footer.html'
+ restrict: 'E',
+ link: (scope, element) ->
+ element.addClass('footer')
diff --git a/app/templates/client/components/footer/footer.directive(js).js b/app/templates/client/components/footer/footer.directive(js).js
new file mode 100644
index 000000000..a640e2289
--- /dev/null
+++ b/app/templates/client/components/footer/footer.directive(js).js
@@ -0,0 +1,12 @@
+'use strict';
+
+angular.module('<%= scriptAppName %>')
+ .directive('footer', function () {
+ return {
+ templateUrl: 'components/footer/footer.html',
+ restrict: 'E',
+ link: function (scope, element) {
+ element.addClass('footer');
+ }
+ };
+ });
diff --git a/app/templates/client/components/modal(uibootstrap)/modal(css).css b/app/templates/client/components/modal(uibootstrap)/modal(css).css
index f5cc0d9e7..ae0406856 100644
--- a/app/templates/client/components/modal(uibootstrap)/modal(css).css
+++ b/app/templates/client/components/modal(uibootstrap)/modal(css).css
@@ -20,4 +20,4 @@
}
.modal-danger .modal-header {
background: #d9534f;
-}
\ No newline at end of file
+}
diff --git a/app/templates/client/components/modal(uibootstrap)/modal(html).html b/app/templates/client/components/modal(uibootstrap)/modal(html).html
index 4580254ff..f04d0db03 100644
--- a/app/templates/client/components/modal(uibootstrap)/modal(html).html
+++ b/app/templates/client/components/modal(uibootstrap)/modal(html).html
@@ -8,4 +8,4 @@
\ No newline at end of file
+
diff --git a/app/templates/client/components/mongoose-error(auth)/mongoose-error.directive(coffee).coffee b/app/templates/client/components/mongoose-error(auth)/mongoose-error.directive(coffee).coffee
index d255f614d..cf0e1ccf0 100644
--- a/app/templates/client/components/mongoose-error(auth)/mongoose-error.directive(coffee).coffee
+++ b/app/templates/client/components/mongoose-error(auth)/mongoose-error.directive(coffee).coffee
@@ -9,4 +9,4 @@ angular.module '<%= scriptAppName %>'
require: 'ngModel'
link: (scope, element, attrs, ngModel) ->
element.on 'keydown', ->
- ngModel.$setValidity 'mongoose', true
\ No newline at end of file
+ ngModel.$setValidity 'mongoose', true
diff --git a/app/templates/client/components/mongoose-error(auth)/mongoose-error.directive(js).js b/app/templates/client/components/mongoose-error(auth)/mongoose-error.directive(js).js
index 8a331009b..a71cb03cf 100644
--- a/app/templates/client/components/mongoose-error(auth)/mongoose-error.directive(js).js
+++ b/app/templates/client/components/mongoose-error(auth)/mongoose-error.directive(js).js
@@ -14,4 +14,4 @@ angular.module('<%= scriptAppName %>')
});
}
};
- });
\ No newline at end of file
+ });
diff --git a/app/templates/client/components/navbar/navbar(html).html b/app/templates/client/components/navbar/navbar(html).html
index 71f8606dd..ec9e4682d 100644
--- a/app/templates/client/components/navbar/navbar(html).html
+++ b/app/templates/client/components/navbar/navbar(html).html
@@ -11,18 +11,18 @@
<% if(filters.auth) { %>
+
ui-sref-active="active"<% } else { %>ng-class="{active: isActive(item.link)}"<% } %>>
+ ui-sref="{{item.state}}"<% } else { %>ng-href="{{item.link}}"<% } %>>{{item.title}}
+ <% if (filters.auth) { %>
+
ui-sref-active="active"<% } else { %>ng-class="{active: isActive('/admin')}"<% } %>>ui-sref="admin"<% } else { %>href="/admin"<% } %>>Admin<% } %>
+ <% if (filters.auth) { %>
<% } %>
diff --git a/app/templates/client/components/navbar/navbar(jade).jade b/app/templates/client/components/navbar/navbar(jade).jade
index 2b17f29c3..e20a8fffa 100644
--- a/app/templates/client/components/navbar/navbar(jade).jade
+++ b/app/templates/client/components/navbar/navbar(jade).jade
@@ -10,25 +10,25 @@ div.navbar.navbar-default.navbar-static-top(ng-controller='NavbarCtrl')
div#navbar-main.navbar-collapse.collapse(collapse='isCollapsed')
ul.nav.navbar-nav
- li(ng-repeat='item in menu', ng-class='{active: isActive(item.link)}')
- a(ng-href='{{item.link}}') {{item.title}}<% if(filters.auth) { %>
+ li(ng-repeat='item in menu', <% if (filters.uirouter) { %>ui-sref-active='active'<% } else { %>ng-class='{active: isActive(item.link)}'<% } %>)
+ a(<% if (filters.uirouter) { %>ui-sref='{{item.state}}'<% } else { %>ng-href='{{item.link}}'<% } %>) {{item.title}}<% if (filters.auth) { %>
- li(ng-show='isAdmin()', ng-class='{active: isActive("/admin")}')
- a(href='/admin') Admin<% } %><% if(filters.auth) { %>
+ li(ng-show='isAdmin()', <% if (filters.uirouter) { %>ui-sref-active='active'<% } else { %>ng-class='{active: isActive("/admin")}'<% } %>)
+ a(<% if (filters.uirouter) { %>ui-sref='admin'<% } else { %>href='/admin'<% } %>) Admin
ul.nav.navbar-nav.navbar-right
- li(ng-hide='isLoggedIn()', ng-class='{active: isActive("/signup")}')
- a(href='/signup') Sign up
+ li(ng-hide='isLoggedIn()', <% if (filters.uirouter) { %>ui-sref-active='active'<% } else { %>ng-class='{active: isActive("/signup")}'<% } %>)
+ a(<% if (filters.uirouter) { %>ui-sref='signup'<% } else { %>href='/signup'<% } %>) Sign up
- li(ng-hide='isLoggedIn()', ng-class='{active: isActive("/login")}')
- a(href='/login') Login
+ li(ng-hide='isLoggedIn()', <% if (filters.uirouter) { %>ui-sref-active='active'<% } else { %>ng-class='{active: isActive("/login")}'<% } %>)
+ a(<% if (filters.uirouter) { %>ui-sref='login'<% } else { %>href='/login'<% } %>) Login
li(ng-show='isLoggedIn()')
p.navbar-text Hello {{ getCurrentUser().name }}
- li(ng-show='isLoggedIn()', ng-class='{active: isActive("/settings")}')
- a(href='/settings')
+ li(ng-show='isLoggedIn()', <% if (filters.uirouter) { %>ui-sref-active='active'<% } else { %>ng-class='{active: isActive("/settings")}'<% } %>)
+ a(<% if (filters.uirouter) { %>ui-sref='settings'<% } else { %>href='/settings'<% } %>)
span.glyphicon.glyphicon-cog
- li(ng-show='isLoggedIn()', ng-class='{active: isActive("/logout")}')
- a(href='', ng-click='logout()') Logout<% } %>
\ No newline at end of file
+ li(ng-show='isLoggedIn()')
+ a(<% if (filters.uirouter) { %>ui-sref='logout'<% } else { %>href='/logout'<% } %>) Logout<% } %>
diff --git a/app/templates/client/components/navbar/navbar.controller(coffee).coffee b/app/templates/client/components/navbar/navbar.controller(coffee).coffee
index d3804c5eb..98eaf2213 100644
--- a/app/templates/client/components/navbar/navbar.controller(coffee).coffee
+++ b/app/templates/client/components/navbar/navbar.controller(coffee).coffee
@@ -1,19 +1,15 @@
'use strict'
angular.module '<%= scriptAppName %>'
-.controller 'NavbarCtrl', ($scope, $location<% if(filters.auth) {%>, Auth<% } %>) ->
+.controller 'NavbarCtrl', ($scope<% if(!filters.uirouter) { %>, $location<% } %><% if (filters.auth) {%>, Auth<% } %>) ->
$scope.menu = [
title: 'Home'
- link: '/'
+ <% if (filters.uirouter) { %>state: 'main'<% } else { %>link: '/'<% } %>
]
- $scope.isCollapsed = true<% if(filters.auth) {%>
+ $scope.isCollapsed = true<% if (filters.auth) {%>
$scope.isLoggedIn = Auth.isLoggedIn
$scope.isAdmin = Auth.isAdmin
- $scope.getCurrentUser = Auth.getCurrentUser
-
- $scope.logout = ->
- Auth.logout()
- $location.path '/login'<% } %>
+ $scope.getCurrentUser = Auth.getCurrentUser<% } %><% if(!filters.uirouter) { %>
$scope.isActive = (route) ->
- route is $location.path()
\ No newline at end of file
+ route is $location.path()<% } %>
diff --git a/app/templates/client/components/navbar/navbar.controller(js).js b/app/templates/client/components/navbar/navbar.controller(js).js
index 4ce9dbcb5..b3eef7cf6 100644
--- a/app/templates/client/components/navbar/navbar.controller(js).js
+++ b/app/templates/client/components/navbar/navbar.controller(js).js
@@ -1,23 +1,18 @@
'use strict';
angular.module('<%= scriptAppName %>')
- .controller('NavbarCtrl', function ($scope, $location<% if(filters.auth) {%>, Auth<% } %>) {
+ .controller('NavbarCtrl', function ($scope<% if(!filters.uirouter) { %>, $location<% } %><% if (filters.auth) {%>, Auth<% } %>) {
$scope.menu = [{
'title': 'Home',
- 'link': '/'
+ <% if (filters.uirouter) { %>'state': 'main'<% } else { %>'link': '/'<% } %>
}];
- $scope.isCollapsed = true;<% if(filters.auth) {%>
+ $scope.isCollapsed = true;<% if (filters.auth) {%>
$scope.isLoggedIn = Auth.isLoggedIn;
$scope.isAdmin = Auth.isAdmin;
- $scope.getCurrentUser = Auth.getCurrentUser;
-
- $scope.logout = function() {
- Auth.logout();
- $location.path('/login');
- };<% } %>
+ $scope.getCurrentUser = Auth.getCurrentUser;<% } %><% if(!filters.uirouter) { %>
$scope.isActive = function(route) {
return route === $location.path();
- };
- });
\ No newline at end of file
+ };<% } %>
+ });
diff --git a/app/templates/client/components/navbar/navbar.directive(coffee).coffee b/app/templates/client/components/navbar/navbar.directive(coffee).coffee
new file mode 100644
index 000000000..bea476822
--- /dev/null
+++ b/app/templates/client/components/navbar/navbar.directive(coffee).coffee
@@ -0,0 +1,7 @@
+'use strict'
+
+angular.module '<%= scriptAppName %>'
+.directive 'navbar', ->
+ templateUrl: 'components/navbar/navbar.html'
+ restrict: 'E'
+ controller: 'NavbarCtrl'
diff --git a/app/templates/client/components/navbar/navbar.directive(js).js b/app/templates/client/components/navbar/navbar.directive(js).js
new file mode 100644
index 000000000..9153e6489
--- /dev/null
+++ b/app/templates/client/components/navbar/navbar.directive(js).js
@@ -0,0 +1,10 @@
+'use strict';
+
+angular.module('<%= scriptAppName %>')
+ .directive('navbar', function () {
+ return {
+ templateUrl: 'components/navbar/navbar.html',
+ restrict: 'E',
+ controller: 'NavbarCtrl'
+ };
+ });
diff --git a/app/templates/client/components/socket(socketio)/socket.mock.js b/app/templates/client/components/socket(socketio)/socket.mock(js).js
similarity index 98%
rename from app/templates/client/components/socket(socketio)/socket.mock.js
rename to app/templates/client/components/socket(socketio)/socket.mock(js).js
index 84a2e0c36..ba09c1d35 100644
--- a/app/templates/client/components/socket(socketio)/socket.mock.js
+++ b/app/templates/client/components/socket(socketio)/socket.mock(js).js
@@ -13,4 +13,4 @@ angular.module('socketMock', [])
syncUpdates: function() {},
unsyncUpdates: function() {}
};
- });
\ No newline at end of file
+ });
diff --git a/app/templates/client/components/socket(socketio)/socket.service.js b/app/templates/client/components/socket(socketio)/socket.service(js).js
similarity index 100%
rename from app/templates/client/components/socket(socketio)/socket.service.js
rename to app/templates/client/components/socket(socketio)/socket.service(js).js
diff --git a/app/templates/client/components/ui-router(uirouter)/ui-router.mock(coffee).coffee b/app/templates/client/components/ui-router(uirouter)/ui-router.mock(coffee).coffee
new file mode 100644
index 000000000..ff3937c35
--- /dev/null
+++ b/app/templates/client/components/ui-router(uirouter)/ui-router.mock(coffee).coffee
@@ -0,0 +1,26 @@
+'use strict'
+
+angular.module 'stateMock', []
+angular.module('stateMock').service '$state', ($q) ->
+ @expectedTransitions = []
+
+ @transitionTo = (stateName) ->
+ if @expectedTransitions.length > 0
+ expectedState = @expectedTransitions.shift()
+ throw Error('Expected transition to state: ' + expectedState + ' but transitioned to ' + stateName) if expectedState isnt stateName
+ else
+ throw Error('No more transitions were expected! Tried to transition to ' + stateName)
+ console.log 'Mock transition to: ' + stateName
+ deferred = $q.defer()
+ promise = deferred.promise
+ deferred.resolve()
+ promise
+
+ @go = @transitionTo
+
+ @expectTransitionTo = (stateName) ->
+ @expectedTransitions.push stateName
+
+ @ensureAllTransitionsHappened = ->
+ throw Error('Not all transitions happened!') if @expectedTransitions.length > 0
+ @
diff --git a/app/templates/client/components/ui-router(uirouter)/ui-router.mock(js).js b/app/templates/client/components/ui-router(uirouter)/ui-router.mock(js).js
new file mode 100644
index 000000000..a5a1bf413
--- /dev/null
+++ b/app/templates/client/components/ui-router(uirouter)/ui-router.mock(js).js
@@ -0,0 +1,34 @@
+'use strict';
+
+angular.module('stateMock', []);
+angular.module('stateMock').service('$state', function($q) {
+ this.expectedTransitions = [];
+
+ this.transitionTo = function(stateName) {
+ if (this.expectedTransitions.length > 0) {
+ var expectedState = this.expectedTransitions.shift();
+ if (expectedState !== stateName) {
+ throw Error('Expected transition to state: ' + expectedState + ' but transitioned to ' + stateName);
+ }
+ } else {
+ throw Error('No more transitions were expected! Tried to transition to ' + stateName);
+ }
+ console.log('Mock transition to: ' + stateName);
+ var deferred = $q.defer();
+ var promise = deferred.promise;
+ deferred.resolve();
+ return promise;
+ };
+
+ this.go = this.transitionTo;
+
+ this.expectTransitionTo = function(stateName) {
+ this.expectedTransitions.push(stateName);
+ };
+
+ this.ensureAllTransitionsHappened = function() {
+ if (this.expectedTransitions.length > 0) {
+ throw Error('Not all transitions happened!');
+ }
+ };
+});
diff --git a/app/templates/client/index.html b/app/templates/client/index.html
index e9dcd5729..1c8d00d8e 100644
--- a/app/templates/client/index.html
+++ b/app/templates/client/index.html
@@ -5,7 +5,7 @@
-
+
@@ -16,25 +16,25 @@
-
+
- <% if(filters.ngroute) { %><% } %><% if(filters.uirouter) { %><% } %>
+ <% if (filters.ngroute) { %><% } %><% if (filters.uirouter) { %><% } %>
<% } %>
-
- <% if(filters.babel) { %>
-
- <% } else { %>
-
- <% } %>
-
-
-
-
-
+
+
+
+
+
+