diff --git a/package.json b/package.json index 0a4406273..ae05dd55d 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,6 @@ "gulp-plumber": "^1.1.0", "gulp-util": "^3.0.7", "jit-grunt": "~0.10.0", - "jscs": "^3.0.3", "lazypipe": "^1.0.1", "merge-stream": "^1.0.0", "minimatch": "^3.0.0", diff --git a/src/generators/app/index.js b/src/generators/app/index.js index 8cb2566d7..a0a90125b 100644 --- a/src/generators/app/index.js +++ b/src/generators/app/index.js @@ -19,9 +19,6 @@ export class Generator extends Base { constructor(...args) { super(...args); - this.env.alias('angular-fullstack', 'afs'); - this.env.alias('afs', 'angular-fullstack'); - this.argument('name', { type: String, required: false }); this.option('skip-install', { @@ -30,6 +27,12 @@ export class Generator extends Base { defaults: false }); + this.option('skip-config', { + desc: 'Always use existing .yo-rc.json', + type: Boolean, + defaults: false + }); + this.option('app-suffix', { desc: 'Allow a custom suffix to be added to the module name', type: String, @@ -79,34 +82,38 @@ export class Generator extends Base { checkForConfig: function() { var existingFilters = this.config.get('filters'); - if(existingFilters) { - return this.prompt([{ - type: 'confirm', - name: 'skipConfig', - message: 'Existing .yo-rc configuration found, would you like to use it?', - default: true, - }]).then(answers => { - this.skipConfig = answers.skipConfig; - - if(this.skipConfig) { - insight.track('skipConfig', 'true'); - this.filters = existingFilters; - - this.scriptExt = this.filters.ts ? 'ts' : 'js'; - this.templateExt = this.filters.jade ? 'jade' : 'html'; - this.styleExt = this.filters.sass ? 'scss' : - this.filters.less ? 'less' : - this.filters.stylus ? 'styl' : - 'css'; - } else { - insight.track('skipConfig', 'false'); - this.filters = {}; - this.forceConfig = true; - this.config.set('filters', this.filters); - this.config.forceSave(); - } - }); - } + if(!existingFilters) return; + + let promise = this.options['skip-config'] + ? Promise.resolve({skipConfig: true}) + : this.prompt([{ + type: 'confirm', + name: 'skipConfig', + message: 'Existing .yo-rc configuration found, would you like to use it?', + default: true, + }]); + + promise.then(answers => { + this.skipConfig = answers.skipConfig; + + if(this.skipConfig) { + insight.track('skipConfig', 'true'); + this.filters = existingFilters; + + this.scriptExt = this.filters.ts ? 'ts' : 'js'; + this.templateExt = this.filters.jade ? 'jade' : 'html'; + this.styleExt = this.filters.sass ? 'scss' : + this.filters.less ? 'less' : + this.filters.stylus ? 'styl' : + 'css'; + } else { + insight.track('skipConfig', 'false'); + this.filters = {}; + this.forceConfig = true; + this.config.set('filters', this.filters); + this.config.forceSave(); + } + }); } }; } diff --git a/src/test/endpoint.test.js b/src/test/endpoint.test.js index 1c901e8f1..212776ec9 100644 --- a/src/test/endpoint.test.js +++ b/src/test/endpoint.test.js @@ -6,9 +6,6 @@ import Promise from 'bluebird'; import helpers from 'yeoman-test'; import assert from 'yeoman-assert'; import minimatch from 'minimatch'; -import Checker from 'jscs'; -const jscs = new Checker(); -jscs.registerDefaultRules(); import * as getExpectedFiles from './get-expected-files'; import { copyAsync, @@ -71,7 +68,7 @@ function runEndpointGen(name, opt={}) { }); } -let jshintCmd = path.join(TEST_DIR, '/fixtures/node_modules/.bin/jshint'); +let eslintCmd = path.join(TEST_DIR, '/fixtures/node_modules/.bin/eslint'); function testFile(command, _path) { _path = path.normalize(_path); return fs.accessAsync(_path, fs.R_OK).then(() => { @@ -79,42 +76,20 @@ function testFile(command, _path) { }); } -function jshintDir(dir, name, folder) { +function eslintDir(dir, name, folder) { if(!folder) folder = name; let endpointDir = path.join(dir, 'server/api', folder); let regFiles = fs.readdirAsync(endpointDir) .then(files => files.filter(file => minimatch(file, '**/!(*.spec|*.mock|*.integration).js', {dot: true}))) - .map(file => testFile(jshintCmd, path.join('./server/api/', folder, file))); + .map(file => testFile(eslintCmd, path.join('./server/api/', folder, file))); let specFiles = fs.readdirAsync(endpointDir) .then(files => files.filter(file => minimatch(file, '**/+(*.spec|*.mock|*.integration).js', {dot: true}))) - .map(file => testFile(`${jshintCmd} --config server/.jshintrc-spec`, path.join('./server/api/', folder, file))); + .map(file => testFile(`${eslintCmd} --env node,es6,mocha --global sinon,expect`, path.join('./server/api/', folder, file))); return Promise.all([regFiles, specFiles]); } -function jscsDir(dir, name, folder) { - if(!folder) folder = name; - let endpointDir = path.join(dir, 'server/api', folder); - - return fs.readdirAsync(endpointDir).then(files => { - return Promise.map(files, file => { - return fs.readFileAsync(path.join('server/api', folder, file), 'utf8').then(data => { - let results = jscs.checkString(data) - let errors = results.getErrorList(); - if(errors.length === 0) { - return Promise.resolve(); - } else { - errors.forEach(error => { - var colorizeOutput = true; - console.log(results.explainError(error, colorizeOutput) + '\n'); - }); - return Promise.reject(); - } - }); - }); - }); -} var config; var genDir; @@ -124,10 +99,6 @@ describe('angular-fullstack:endpoint', function() { return Promise.all([ runGen(defaultOptions).then(_dir => { genDir = _dir; - - return fs.readFileAsync(path.join(genDir, '.jscsrc'), 'utf8').then(data => { - jscs.configure(JSON.parse(data)); - }); }), readJSON(path.join(TEST_DIR, 'fixtures/.yo-rc.json')).then(_config => { _config['generator-angular-fullstack'].insertRoutes = false; @@ -146,9 +117,8 @@ describe('angular-fullstack:endpoint', function() { dir = _dir; return Promise.all([ - copyAsync(path.join(genDir, '/server/.jshintrc'), './server/.jshintrc'), - copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec'), - copyAsync(path.join(genDir, '/.jscsrc'), './.jscsrc') + copyAsync(path.join(genDir, '/.eslintrc'), './.eslintrc'), + copyAsync(path.join(genDir, '/server/.eslintrc'), './server/.eslintrc') ]); }); }); @@ -157,12 +127,8 @@ describe('angular-fullstack:endpoint', function() { assert.file(getExpectedFiles.endpoint('foo')); }); - it('should pass jscs', function() { - return jscsDir(dir, 'foo').should.be.fulfilled(); - }); - it('should pass lint', function() { - return jshintDir(dir, 'foo').should.be.fulfilled(); + return eslintDir(dir, 'foo').should.be.fulfilled(); }); }); @@ -173,9 +139,8 @@ describe('angular-fullstack:endpoint', function() { dir = _dir; return Promise.all([ - copyAsync(path.join(genDir, '/server/.jshintrc'), './server/.jshintrc'), - copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec'), - copyAsync(path.join(genDir, '/.jscsrc'), './.jscsrc') + copyAsync(path.join(genDir, '/.eslintrc'), './.eslintrc'), + copyAsync(path.join(genDir, '/server/.eslintrc'), './server/.eslintrc') ]); }); }); @@ -184,12 +149,8 @@ describe('angular-fullstack:endpoint', function() { assert.file(getExpectedFiles.endpoint('Foo')); }); - it('should pass jscs', function() { - return jscsDir(dir, 'Foo').should.be.fulfilled(); - }); - it('should pass lint', function() { - return jshintDir(dir, 'Foo').should.be.fulfilled(); + return eslintDir(dir, 'Foo').should.be.fulfilled(); }); }); @@ -200,9 +161,8 @@ describe('angular-fullstack:endpoint', function() { dir = _dir; return Promise.all([ - copyAsync(path.join(genDir, '/server/.jshintrc'), './server/.jshintrc'), - copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec'), - copyAsync(path.join(genDir, '/.jscsrc'), './.jscsrc') + copyAsync(path.join(genDir, '/.eslintrc'), './.eslintrc'), + copyAsync(path.join(genDir, '/server/.eslintrc'), './server/.eslintrc') ]); }); }); @@ -211,12 +171,8 @@ describe('angular-fullstack:endpoint', function() { assert.file(getExpectedFiles.endpoint('bar', 'foo/bar')); }); - it('should pass jscs', function() { - return jscsDir(dir, 'foo', 'foo/bar').should.be.fulfilled(); - }); - it('should pass lint', function() { - return jshintDir(dir, 'foo', 'foo/bar').should.be.fulfilled(); + return eslintDir(dir, 'foo', 'foo/bar').should.be.fulfilled(); }); }); @@ -227,9 +183,8 @@ describe('angular-fullstack:endpoint', function() { dir = _dir; return Promise.all([ - copyAsync(path.join(genDir, '/server/.jshintrc'), './server/.jshintrc'), - copyAsync(path.join(genDir, '/server/.jshintrc-spec'), './server/.jshintrc-spec'), - copyAsync(path.join(genDir, '/.jscsrc'), './.jscsrc') + copyAsync(path.join(genDir, '/.eslintrc'), './.eslintrc'), + copyAsync(path.join(genDir, '/server/.eslintrc'), './server/.eslintrc') ]); }); }); @@ -238,12 +193,8 @@ describe('angular-fullstack:endpoint', function() { assert.file(getExpectedFiles.endpoint('foo-bar')); }); - it('should pass jscs', function() { - return jscsDir(dir, 'foo-bar').should.be.fulfilled(); - }); - it('should pass lint', function() { - return jshintDir(dir, 'foo-bar').should.be.fulfilled(); + return eslintDir(dir, 'foo-bar').should.be.fulfilled(); }); }); }); diff --git a/src/test/get-expected-files.js b/src/test/get-expected-files.js index 8a3665c16..fc577510c 100644 --- a/src/test/get-expected-files.js +++ b/src/test/get-expected-files.js @@ -67,8 +67,7 @@ export function app(options) { 'client/components/navbar/navbar.component.' + script, 'client/components/util/util.module.' + script, 'client/components/util/util.service.' + script, - 'server/.jshintrc', - 'server/.jshintrc-spec', + 'server/.eslintrc', 'server/app.js', 'server/index.js', 'server/routes.js', @@ -92,10 +91,10 @@ export function app(options) { '.babelrc', '.buildignore', '.editorconfig', + '.eslintrc', '.gitattributes', '.gitignore', '.travis.yml', - '.jscsrc', '.yo-rc.json', 'gulpfile.babel.js', 'package.json', @@ -121,7 +120,7 @@ export function app(options) { ]); } else { files = files.concat([ - 'client/.jshintrc' + 'client/.eslintrc' ]); } diff --git a/src/test/main.test.js b/src/test/main.test.js index 93cf4eecc..e54f1fdbd 100644 --- a/src/test/main.test.js +++ b/src/test/main.test.js @@ -70,10 +70,6 @@ describe('angular-fullstack:app', function() { return assertOnlyFiles(expectedFiles, path.normalize(dir)).should.be.fulfilled(); }); - it('passes JSCS', function() { - return runCmd('gulp jscs').should.be.fulfilled(); - }); - it('passes lint', function() { return runCmd('gulp lint:scripts').should.be.fulfilled(); }); @@ -149,7 +145,6 @@ describe('angular-fullstack:app', function() { describe('default settings using existing `.yo-rc.json`', function() { var dir; - var jscsResult; var lintResult; var clientTestResult; var serverTestResult; @@ -163,7 +158,6 @@ describe('angular-fullstack:app', function() { } }).then(_dir => { dir = _dir; - jscsResult = runCmd('gulp jscs'); lintResult = runCmd('gulp lint:scripts'); clientTestResult = runCmd('gulp test:client'); serverTestResult = runCmd('gulp test:server'); @@ -176,10 +170,6 @@ describe('angular-fullstack:app', function() { return assertOnlyFiles(expectedFiles, path.normalize(dir)).should.be.fulfilled(); }); - it('passes JSCS', function() { - return jscsResult.should.be.fulfilled(); - }); - it('passes lint', function() { return lintResult.should.be.fulfilled(); }); @@ -195,7 +185,6 @@ describe('angular-fullstack:app', function() { describe('with TypeScript, Jade, Jasmine, LESS, & OAuth', function() { var dir; - var jscsResult; var lintResult; var clientTestResult; var serverTestResult; @@ -217,7 +206,6 @@ describe('angular-fullstack:app', function() { before(function() { return runGen(testOptions).then(_dir => { dir = _dir; - jscsResult = runCmd('gulp jscs'); lintResult = runCmd('gulp lint:scripts'); clientTestResult = runCmd('gulp test:client'); serverTestResult = runCmd('gulp test:server'); @@ -230,10 +218,6 @@ describe('angular-fullstack:app', function() { return assertOnlyFiles(expectedFiles, path.normalize(dir)).should.be.fulfilled(); }); - it('passes JSCS', function() { - return jscsResult.should.be.fulfilled(); - }); - it('passes lint', function() { return lintResult.should.be.fulfilled(); }); @@ -273,7 +257,6 @@ describe('angular-fullstack:app', function() { describe('with sequelize models, auth', function() { var dir; - var jscsResult; var lintResult; var clientTestResult; var serverTestResult; @@ -296,7 +279,6 @@ describe('angular-fullstack:app', function() { beforeEach(function() { return runGen(testOptions).then(_dir => { dir = _dir; - jscsResult = runCmd('gulp jscs'); lintResult = runCmd('gulp lint:scripts'); clientTestResult = runCmd('gulp test:client'); serverTestResult = runCmd('gulp test:server'); @@ -309,10 +291,6 @@ describe('angular-fullstack:app', function() { return assertOnlyFiles(expectedFiles, path.normalize(dir)).should.be.fulfilled(); }); - it('passes JSCS', function() { - return jscsResult.should.be.fulfilled(); - }); - it('passes lint', function() { return lintResult.should.be.fulfilled(); }); @@ -352,7 +330,6 @@ describe('angular-fullstack:app', function() { describe('with TypeScript, Mocha + Chai (should) and no server options', function() { var dir; - var jscsResult; var lintResult; var clientTestResult; var serverTestResult; @@ -375,7 +352,6 @@ describe('angular-fullstack:app', function() { beforeEach(function() { return runGen(testOptions).then(_dir => { dir = _dir; - jscsResult = runCmd('gulp jscs'); lintResult = runCmd('gulp lint:scripts'); clientTestResult = runCmd('gulp test:client'); serverTestResult = runCmd('gulp test:server'); @@ -388,10 +364,6 @@ describe('angular-fullstack:app', function() { return assertOnlyFiles(expectedFiles, path.normalize(dir)).should.be.fulfilled(); }); - it('passes JSCS', function() { - return jscsResult.should.be.fulfilled(); - }); - it('passes lint', function() { return lintResult.should.be.fulfilled(); }); diff --git a/templates/app/.eslintrc b/templates/app/.eslintrc new file mode 100644 index 000000000..ef5d7de07 --- /dev/null +++ b/templates/app/.eslintrc @@ -0,0 +1,251 @@ +{ + "parser": "babel-eslint", + "env": { + "es6": true + }, + "globals": {}, + "plugins": [], + "rules": { + //Possible Errors + "comma-dangle": 0, //disallow or enforce trailing commas + "no-cond-assign": 2, //disallow assignment in conditional expressions + "no-console": 0, //disallow use of console in the node environment + "no-constant-condition": 1, //disallow use of constant expressions in conditions + "no-control-regex": 2, //disallow control characters in regular expressions + "no-debugger": 2, //disallow use of debugger + "no-dupe-args": 2, //disallow duplicate arguments in functions + "no-dupe-keys": 2, //disallow duplicate keys when creating object literals + "no-duplicate-case": 0, //disallow a duplicate case label. + "no-empty-character-class": 2, //disallow the use of empty character classes in regular expressions + "no-empty": 2, //disallow empty statements + "no-ex-assign": 2, //disallow assigning to the exception in a catch block + "no-extra-boolean-cast": 2, //disallow double-negation boolean casts in a boolean context + "no-extra-parens": 1, //disallow unnecessary parentheses + "no-extra-semi": 2, //disallow unnecessary semicolons + "no-func-assign": 2, //disallow overwriting functions written as function declarations + "no-inner-declarations": 1, //disallow function or variable declarations in nested blocks + "no-invalid-regexp": 2, //disallow invalid regular expression strings in the RegExp constructor + "no-irregular-whitespace": 2, //disallow irregular whitespace outside of strings and comments + "no-negated-in-lhs": 2, //disallow negation of the left operand of an in expression + "no-obj-calls": 2, //disallow the use of object properties of the global object (Math and JSON) as functions + "no-prototype-builtins": 0, //Disallow use of Object.prototypes builtins directly + "no-regex-spaces": 2, //disallow multiple spaces in a regular expression literal + "no-sparse-arrays": 1, //disallow sparse arrays + "no-unexpected-multiline": 2, //Avoid code that looks like two expressions but is actually one + "no-unreachable": 2, //disallow unreachable statements after a return, throw, continue, or break statement + "no-unsafe-finally": 2, //disallow control flow statements in finally blocks + "use-isnan": 2, //disallow comparisons with the value NaN + "valid-jsdoc": 0, //Ensure JSDoc comments are valid + "valid-typeof": 2, //Ensure that the results of typeof are compared against a valid string + + //Best Practices + "accessor-pairs": 0, //Enforces getter/setter pairs in objects + "array-callback-return": 2, //Enforces return statements in callbacks of array's methods + "block-scoped-var": 0, //treat var statements as if they were block scoped + "complexity": 0, //specify the maximum cyclomatic complexity allowed in a program + "consistent-return": 0, //require return statements to either always or never specify values + "curly": [2, "multi-line"], //specify curly brace conventions for all control statements + "default-case": 0, //require default case in switch statements + "dot-location": [2, "property"], //enforces consistent newlines before or after dots + "dot-notation": 2, //encourages use of dot notation whenever possible + "eqeqeq": 0, //require the use of === and !== + "guard-for-in": 0, //make sure for-in loops have an if statement + "no-alert": 2, //disallow the use of alert, confirm, and prompt + "no-caller": 0, //disallow use of arguments.caller or arguments.callee + "no-case-declarations": 0, //disallow lexical declarations in case clauses + "no-div-regex": 2, //disallow division operators explicitly at beginning of regular expression + "no-else-return": 0, //disallow else after a return in an if + "no-empty-function": 0, //disallow use of empty functions + "no-empty-pattern": 2, //disallow use of empty destructuring patterns + "no-eq-null": 2, //disallow comparisons to null without a type-checking operator + "no-eval": 2, //disallow use of eval() + "no-extend-native": 0, //disallow adding to native types + "no-extra-bind": 1, //disallow unnecessary function binding + "no-extra-label": 2, //disallow unnecessary labels + "no-fallthrough": 0, //disallow fallthrough of case statements + "no-floating-decimal": 0, //disallow the use of leading or trailing decimal points in numeric literals + "no-implicit-coercion": 0, //disallow the type conversions with shorter notations + "no-implicit-globals": 0, //disallow var and named functions in global scope + "no-implied-eval": 2, //disallow use of eval()-like methods + "no-invalid-this": 1, //disallow this keywords outside of classes or class-like objects + "no-iterator": 2, //disallow usage of __iterator__ property + "no-labels": 2, //disallow use of labeled statements + "no-lone-blocks": 2, //disallow unnecessary nested blocks + "no-loop-func": 2, //disallow creation of functions within loops + "no-magic-numbers": 0, //disallow the use of magic numbers + "no-multi-spaces": 2, //disallow use of multiple spaces + "no-multi-str": 0, //disallow use of multiline strings + "no-native-reassign": 2, //disallow reassignments of native objects + "no-new-func": 1, //disallow use of new operator for Function object + "no-new-wrappers": 2, //disallows creating new instances of String,Number, and Boolean + "no-new": 2, //disallow use of the new operator when not part of an assignment or comparison + "no-octal-escape": 0, //disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251"; + "no-octal": 0, //disallow use of octal literals + "no-param-reassign": 0, //disallow reassignment of function parameters + "no-process-env": 1, //disallow use of process.env + "no-proto": 2, //disallow usage of __proto__ property + "no-redeclare": 2, //disallow declaring the same variable more than once + "no-return-assign": 2, //disallow use of assignment in return statement + "no-script-url": 2, //disallow use of javascript: urls. + "no-self-assign": 2, //disallow assignments where both sides are exactly the same + "no-self-compare": 2, //disallow comparisons where both sides are exactly the same + "no-sequences": 2, //disallow use of the comma operator + "no-throw-literal": 2, //restrict what can be thrown as an exception + "no-unmodified-loop-condition": 0, //disallow unmodified conditions of loops + "no-unused-expressions": 0, //disallow usage of expressions in statement position + "no-unused-labels": 2, //disallow unused labels + "no-useless-call": 2, //disallow unnecessary .call() and .apply() + "no-useless-concat": 2, //disallow unnecessary concatenation of literals or template literals + "no-useless-escape": 2, //disallow unnecessary escape characters + "no-void": 0, //disallow use of the void operator + "no-warning-comments": 1, //disallow usage of configurable warning terms in comments (e.g. TODO or FIXME) + "no-with": 2, //disallow use of the with statement + "radix": 2, //require use of the second argument for parseInt() + "vars-on-top": 0, //require declaration of all vars at the top of their containing scope + "wrap-iife": 2, //require immediate function invocation to be wrapped in parentheses + "yoda": 2, //require or disallow Yoda conditions + + //Strict Mode + "strict": 0, //controls location of Use Strict Directives + + //Variables + "init-declarations": 0, //enforce or disallow variable initializations at definition + "no-catch-shadow": 2, //disallow the catch clause parameter name being the same as a variable in the outer scope + "no-delete-var": 2, //disallow deletion of variables + "no-label-var": 2, //disallow labels that share a name with a variable + "no-restricted-globals": 0, //restrict usage of specified global variables + "no-shadow-restricted-names": 2, //disallow shadowing of names such as arguments + "no-shadow": [2, {"allow": ["err"]}], //disallow declaration of variables already declared in the outer scope + "no-undef-init": 2, //disallow use of undefined when initializing variables + "no-undef": 2, //disallow use of undeclared variables unless mentioned in a /*global */ block + "no-undefined": 0, //disallow use of undefined variable + "no-unused-vars": 2, //disallow declaration of variables that are not used in the code + "no-use-before-define": 0, //disallow use of variables before they are defined + + //Node.js and CommonJS + "callback-return": 2, //enforce return after a callback + "global-require": 0, //enforce require() on top-level module scope + "handle-callback-err": 2, //enforce error handling in callbacks + "no-mixed-requires": 2, //disallow mixing regular variable and require declarations + "no-new-require": 2, //disallow use of new operator with the require function + "no-path-concat": 2, //disallow string concatenation with __dirname and __filename + "no-process-exit": 2, //disallow process.exit() + "no-restricted-imports": 0, //restrict usage of specified node imports + "no-restricted-modules": 0, //restrict usage of specified node modules + "no-sync": 1, //disallow use of synchronous methods + + //Stylistic Issues + "array-bracket-spacing": [2, "never"], //enforce spacing inside array brackets + "block-spacing": 0, //disallow or enforce spaces inside of single line blocks + "brace-style": 2, //enforce one true brace style + "camelcase": 1, //require camel case names + "comma-spacing": [2, {"before": false, "after": true}], //enforce spacing before and after comma + "comma-style": 2, //enforce one true comma style + "computed-property-spacing": 2, //require or disallow padding inside computed properties + "consistent-this": 2, //enforce consistent naming when capturing the current execution context + "eol-last": 2, //enforce newline at the end of file, with no multiple empty lines + "func-names": 0, //require function expressions to have a name + "func-style": 0, //enforce use of function declarations or expressions + "id-blacklist": 0, //blacklist certain identifiers to prevent them being used + "id-length": 0, //this option enforces minimum and maximum identifier lengths (variable names, property names etc.) + "id-match": 0, //require identifiers to match the provided regular expression + "indent": ["error", 2], //specify tab or space width for your code + "jsx-quotes": 0, //specify whether double or single quotes should be used in JSX attributes + "key-spacing": 2, //enforce spacing between keys and values in object literal properties + "keyword-spacing": [2, { + "before": true, + "after": true, + "overrides": { + "if": {"after": false}, + "for": {"after": false}, + "while": {"after": false}, + "catch": {"after": false} + } + }], //enforce spacing before and after keywords + "linebreak-style": 2, //disallow mixed 'LF' and 'CRLF' as linebreaks + "lines-around-comment": 0, //enforce empty lines around comments + "max-depth": 1, //specify the maximum depth that blocks can be nested + "max-len": [1, 200], //specify the maximum length of a line in your program + "max-lines": 0, //enforce a maximum file length + "max-nested-callbacks": 2, //specify the maximum depth callbacks can be nested + "max-params": 0, //limits the number of parameters that can be used in the function declaration. + "max-statements": 0, //specify the maximum number of statement allowed in a function + "max-statements-per-line": 0, //enforce a maximum number of statements allowed per line + "new-cap": 0, //require a capital letter for constructors + "new-parens": 2, //disallow the omission of parentheses when invoking a constructor with no arguments + "newline-after-var": 0, //require or disallow an empty newline after variable declarations + "newline-before-return": 0, //require newline before return statement + "newline-per-chained-call": 0, //enforce newline after each call when chaining the calls + "no-array-constructor": 2, //disallow use of the Array constructor + "no-bitwise": 0, //disallow use of bitwise operators + "no-continue": 0, //disallow use of the continue statement + "no-inline-comments": 0, //disallow comments inline after code + "no-lonely-if": 2, //disallow if as the only statement in an else block + "no-mixed-operators": 0, //disallow mixes of different operators + "no-mixed-spaces-and-tabs": 2, //disallow mixed spaces and tabs for indentation + "no-multiple-empty-lines": 2, //disallow multiple empty lines + "no-negated-condition": 0, //disallow negated conditions + "no-nested-ternary": 0, //disallow nested ternary expressions + "no-new-object": 2, //disallow the use of the Object constructor + "no-plusplus": 0, //disallow use of unary operators, ++ and -- + "no-restricted-syntax": 0, //disallow use of certain syntax in code + "no-spaced-func": 2, //disallow space between function identifier and application + "no-ternary": 0, //disallow the use of ternary operators + "no-trailing-spaces": 2, //disallow trailing whitespace at the end of lines + "no-underscore-dangle": 0, //disallow dangling underscores in identifiers + "no-unneeded-ternary": 2, //disallow the use of ternary operators when a simpler alternative exists + "no-whitespace-before-property": 2, //disallow whitespace before properties + "object-curly-newline": 0, //enforce consistent line breaks inside braces + "object-curly-spacing": 0, //require or disallow padding inside curly braces + "object-property-newline": 0, //enforce placing object properties on separate lines + "one-var": [2, "never"], //require or disallow one variable declaration per function + "one-var-declaration-per-line": 2, //require or disallow an newline around variable declarations + "operator-assignment": 0, //require assignment operator shorthand where possible or prohibit it entirely + "operator-linebreak": [1, "before"], //enforce operators to be placed before or after line breaks + "padded-blocks": [2, "never"], //enforce padding within blocks + "quote-props": [2, "as-needed"], //require quotes around object literal property names + "quotes": [2, "single"], //specify whether backticks, double or single quotes should be used + "require-jsdoc": 0, //Require JSDoc comment + "semi-spacing": 2, //enforce spacing before and after semicolons + "sort-imports": 0, //sort import declarations within module + "semi": 2, //require or disallow use of semicolons instead of ASI + "sort-vars": 0, //sort variables within the same declaration block + "space-before-blocks": 2, //require or disallow a space before blocks + "space-before-function-paren": [2, "never"], //require or disallow a space before function opening parenthesis + "space-in-parens": 2, //require or disallow spaces inside parentheses + "space-infix-ops": 2, //require spaces around operators + "space-unary-ops": 2, //require or disallow spaces before/after unary operators + "spaced-comment": 0, //require or disallow a space immediately following the // or /* in a comment + "unicode-bom": 0, //require or disallow the Unicode BOM + "wrap-regex": 0, //require regex literals to be wrapped in parentheses + + //ECMAScript 6 + "arrow-body-style": [2, "as-needed"], //require braces in arrow function body + "arrow-parens": [2, "as-needed"], //require parens in arrow function arguments + "arrow-spacing": 2, //require space before/after arrow function's arrow + "constructor-super": 2, //verify calls of super() in constructors + "generator-star-spacing": 0, //enforce spacing around the * in generator functions + "no-class-assign": 2, //disallow modifying variables of class declarations + "no-confusing-arrow": 2, //disallow arrow functions where they could be confused with comparisons + "no-const-assign": 2, //disallow modifying variables that are declared using const + "no-dupe-class-members": 2, //disallow duplicate name in class members + "no-duplicate-imports": 2, //disallow duplicate module imports + "no-new-symbol": 2, //disallow use of the new operator with the Symbol object + "no-this-before-super": 2, //disallow use of this/super before calling super() in constructors. + "no-useless-computed-key": 2, //disallow unnecessary computed property keys in object literals + "no-useless-constructor": 2, //disallow unnecessary constructor + "no-useless-rename": 2, //disallow renaming import, export, and destructured assignments to the same name + "no-var": 0, //require let or const instead of var + "object-shorthand": 1, //require method and property shorthand syntax for object literals + "prefer-arrow-callback": 0, //suggest using arrow functions as callbacks + "prefer-const": 0, //suggest using const declaration for variables that are never modified after declared + "prefer-reflect": 1, //suggest using Reflect methods where applicable + "prefer-rest-params": 1, //suggest using the rest parameters instead of arguments + "prefer-spread": 1, //suggest using the spread operator instead of .apply(). + "prefer-template": 1, //suggest using template literals instead of strings concatenation + "require-yield": 2, //disallow generator functions that do not have yield + "rest-spread-spacing": ["error", "never"], //enforce spacing between rest and spread operators and their expressions + "template-curly-spacing": 2, //enforce spacing around embedded expressions of template strings + "yield-star-spacing": [2, "after"] //enforce spacing around the * in yield* expressions + } +} diff --git a/templates/app/.jscsrc b/templates/app/.jscsrc deleted file mode 100644 index 2560db00f..000000000 --- a/templates/app/.jscsrc +++ /dev/null @@ -1,46 +0,0 @@ -{ - "excludeFiles": [ - "client/app/app.constant.js" - ], - "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": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"], - "requireSpaceBeforeBlockStatements": true, - "requireSpacesInConditionalExpression": { - "afterTest": true, - "beforeConsequent": true, - "afterConsequent": true, - "beforeAlternate": true - }, - "requireSpacesInFunction": { - "beforeOpeningCurlyBrace": true - }, - "validateLineBreaks": "LF", - "validateParameterSeparator": ", " -} diff --git a/templates/app/_package.json b/templates/app/_package.json index 219ef0a74..e33abbd69 100644 --- a/templates/app/_package.json +++ b/templates/app/_package.json @@ -63,6 +63,7 @@ <%_ /* END CLIENT */ _%> "autoprefixer": "^6.0.0", "babel-core": "^6.6.5", + "babel-eslint": "^6.0.4", "babel-register": "^6.6.5", <%_ if(filters.flow) { -%> "flow-bin": "^0.27.0", @@ -70,7 +71,8 @@ "babel-plugin-transform-flow-comments": "^6.8.0",<% } %> "babel-plugin-transform-class-properties": "^6.6.0", "babel-plugin-transform-runtime": "^6.6.0", - "babel-preset-es2015": "^6.6.0",<% if(filters.gulp) { %> + "babel-preset-es2015": "^6.6.0", + "eslint": "^2.12.0",<% if(filters.gulp) { %> "del": "^2.0.2", "gulp": "^3.9.1", "gulp-add-src": "^0.2.0", @@ -84,14 +86,12 @@ "gulp-cache": "^0.4.2", "gulp-concat": "^2.6.0", "gulp-env": "^0.4.0", + "gulp-eslint": "^2.0.0", "gulp-filter": "^4.0.0", "gulp-imagemin": "^2.2.1", "gulp-inject": "^4.0.0", "gulp-istanbul": "~0.10.3", "gulp-istanbul-enforcer": "^1.0.3", - "gulp-jscs": "^3.0.2", - "gulp-jshint": "^2.0.0", - "jshint": "2.9.2", "gulp-livereload": "^3.8.0", "gulp-load-plugins": "^1.0.0-rc.1", "gulp-clean-css": "^2.0.6", @@ -133,7 +133,6 @@ "grunt-contrib-copy": "^1.0.0", "grunt-contrib-cssmin": "^1.0.0", "grunt-contrib-imagemin": "^1.0.0", - "grunt-contrib-jshint": "^1.0.0", "grunt-contrib-uglify": "^1.0.0", "grunt-contrib-watch": "^1.0.0",<% if(filters.jade) { %> "grunt-contrib-jade": "^1.0.0",<% } %><% if(filters.less) { %> @@ -143,7 +142,6 @@ "grunt-typings": "~0.1.4", "grunt-tslint": "~3.1.0",<% } %> "grunt-google-cdn": "~0.4.0", - "grunt-jscs": "^2.1.0", "grunt-newer": "^1.1.1", "grunt-ng-annotate": "^2.0.1", "grunt-ng-constant": "^2.0.1", @@ -201,7 +199,6 @@ <%_ /* END WEBPACK */ _%> "through2": "^2.0.1", "open": "~0.0.4", - "jshint-stylish": "^2.2.0", "connect-livereload": "^0.5.3", "istanbul": "~0.4.1", "chai": "^3.2.0", diff --git a/templates/app/client/.eslintrc(babel) b/templates/app/client/.eslintrc(babel) new file mode 100644 index 000000000..b12322f67 --- /dev/null +++ b/templates/app/client/.eslintrc(babel) @@ -0,0 +1,7 @@ +{ + "extends": "../.eslintrc", + "env": { + "browser": true, + "commonjs": true + } +} diff --git a/templates/app/client/.jshintrc(babel) b/templates/app/client/.jshintrc(babel) deleted file mode 100644 index 9d0d57476..000000000 --- a/templates/app/client/.jshintrc(babel) +++ /dev/null @@ -1,40 +0,0 @@ -{ - "node": true, - "browser": true, - "esnext": true, - "bitwise": true, - "camelcase": true, - "curly": true, - "eqeqeq": true, - "immed": true, - "latedef": true, - "newcap": true, - "noarg": true, - "quotmark": "single", - "undef": true, - "unused": true, - "strict": true, - "trailing": true, - "smarttabs": true, - "ignoreDelimiters": [ - { "start": "start-non-standard", "end": "end-non-standard" } - ], - "globals": { - "jQuery": true, - "angular": true, - "console": true, - "$": true, - "_": true, - "moment": true,<% if (filters.jasmine) { %> - "jasmine": true,<% } %> - "describe": true, - "beforeEach": true, - "module": true, - "inject": true, - "it": true, - "expect": true, - "browser": true, - "element": true, - "by": true - } -} diff --git a/templates/app/gulpfile.babel(gulp).js b/templates/app/gulpfile.babel(gulp).js index 0cc25c44c..8a808b21f 100644 --- a/templates/app/gulpfile.babel(gulp).js +++ b/templates/app/gulpfile.babel(gulp).js @@ -102,18 +102,42 @@ function whenServerReady(cb) { ********************/ let lintClientScripts = lazypipe()<% if(filters.babel) { %> - .pipe(plugins.jshint, `${clientPath}/.jshintrc`) - .pipe(plugins.jshint.reporter, 'jshint-stylish');<% } %><% if(filters.ts) { %> + .pipe(plugins.eslint, `${clientPath}/.eslintrc`) + .pipe(plugins.eslint.format);<% } %><% if(filters.ts) { %> .pipe(plugins.tslint, require(`./${clientPath}/tslint.json`)) .pipe(plugins.tslint.report, 'verbose', {emitError: false});<% } %> +const lintClientTestScripts = lazypipe() + <%_ if(filters.babel) { -%> + .pipe(plugins.eslint, { + configFile: `${clientPath}/.eslintrc`, + envs: [ + 'browser', + 'es6', + 'mocha' + ] + }) + .pipe(plugins.eslint.format); + <%_ } -%> + <%_ if(filters.ts) { -%> + .pipe(plugins.tslint, require(`./${clientPath}/tslint.json`)) + .pipe(plugins.tslint.report, 'verbose', {emitError: false}); + <%_ } -%> + let lintServerScripts = lazypipe() - .pipe(plugins.jshint, `${serverPath}/.jshintrc`) - .pipe(plugins.jshint.reporter, 'jshint-stylish'); + .pipe(plugins.eslint, `${serverPath}/.eslintrc`) + .pipe(plugins.eslint.format); let lintServerTestScripts = lazypipe() - .pipe(plugins.jshint, `${serverPath}/.jshintrc-spec`) - .pipe(plugins.jshint.reporter, 'jshint-stylish'); + .pipe(plugins.eslint, { + configFile: `${serverPath}/.eslintrc`, + envs: [ + 'node', + 'es6', + 'mocha' + ] + }) + .pipe(plugins.eslint.format); let transpileServer = lazypipe() .pipe(plugins.sourcemaps.init) diff --git a/templates/app/server/.eslintrc b/templates/app/server/.eslintrc new file mode 100644 index 000000000..849296d61 --- /dev/null +++ b/templates/app/server/.eslintrc @@ -0,0 +1,6 @@ +{ + "extends": "../.eslintrc", + "env": { + "node": true + } +} diff --git a/templates/app/server/.jshintrc b/templates/app/server/.jshintrc deleted file mode 100644 index 69f3b00e3..000000000 --- a/templates/app/server/.jshintrc +++ /dev/null @@ -1,15 +0,0 @@ -{ - "expr": true, - "node": true, - "esnext": true, - "bitwise": true, - "eqeqeq": true, - "immed": true, - "latedef": "nofunc", - "newcap": true, - "noarg": true, - "undef": true, - "smarttabs": true, - "asi": true, - "debug": true -} diff --git a/templates/app/server/.jshintrc-spec b/templates/app/server/.jshintrc-spec deleted file mode 100644 index 8c9871ce0..000000000 --- a/templates/app/server/.jshintrc-spec +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": ".jshintrc", - "globals": {<% if (filters.jasmine) { %> - "jasmine": true,<% } %> - "describe": true, - "it": true, - "before": true, - "beforeEach": true, - "after": true, - "afterEach": true, - "expect": true, - "assert": true, - "sinon": true - } -} diff --git a/templates/app/server/api/user(auth)/user.model(mongooseModels).js b/templates/app/server/api/user(auth)/user.model(mongooseModels).js index 5394bad3c..c67632162 100644 --- a/templates/app/server/api/user(auth)/user.model(mongooseModels).js +++ b/templates/app/server/api/user(auth)/user.model(mongooseModels).js @@ -1,9 +1,8 @@ 'use strict'; - +/*eslint no-invalid-this:0*/ import crypto from 'crypto'; -import mongoose from 'mongoose'; mongoose.Promise = require('bluebird'); -import {Schema} from 'mongoose';<% if (filters.oauth) { %> +import mongoose, {Schema} from 'mongoose';<% if(filters.oauth) { %> const authTypes = ['github', 'twitter', 'facebook', 'google'];<% } %> @@ -12,13 +11,17 @@ var UserSchema = new Schema({ email: { type: String, lowercase: true, - required: <% if(filters.oauth) { %>function() { - if (authTypes.indexOf(this.provider) === -1) { + <%_ if(filters.oauth) { -%> + required() { + if(authTypes.indexOf(this.provider) === -1) { return true; } else { return false; } - }<% } else { %>true<% } %> + } + <%_ } else { -%> + required: true + <%_ } -%> }, role: { type: String, @@ -27,7 +30,7 @@ var UserSchema = new Schema({ password: { type: String, required: <% if(filters.oauth) { %>function() { - if (authTypes.indexOf(this.provider) === -1) { + if(authTypes.indexOf(this.provider) === -1) { return true; } else { return false; @@ -35,9 +38,9 @@ var UserSchema = new Schema({ }<% } else { %>true<% } %> }, provider: String, - salt: String<% if (filters.oauth) { %>,<% if (filters.facebookAuth) { %> - facebook: {},<% } %><% if (filters.twitterAuth) { %> - twitter: {},<% } %><% if (filters.googleAuth) { %> + salt: String<% if(filters.oauth) { %>,<% if(filters.facebookAuth) { %> + facebook: {},<% } %><% if(filters.twitterAuth) { %> + twitter: {},<% } %><% if(filters.googleAuth) { %> google: {},<% } %> github: {}<% } %> }); @@ -51,8 +54,8 @@ UserSchema .virtual('profile') .get(function() { return { - 'name': this.name, - 'role': this.role + name: this.name, + role: this.role }; }); @@ -61,8 +64,8 @@ UserSchema .virtual('token') .get(function() { return { - '_id': this._id, - 'role': this.role + _id: this._id, + role: this.role }; }); @@ -73,18 +76,20 @@ UserSchema // Validate empty email UserSchema .path('email') - .validate(function(email) {<% if (filters.oauth) { %> - if (authTypes.indexOf(this.provider) !== -1) { + .validate(function(email) { + <%_ if(filters.oauth) { -%> + if(authTypes.indexOf(this.provider) !== -1) { return true; - }<% } %> + } + <%_ } -%> return email.length; }, 'Email cannot be blank'); // Validate empty password UserSchema .path('password') - .validate(function(password) {<% if (filters.oauth) { %> - if (authTypes.indexOf(this.provider) !== -1) { + .validate(function(password) {<% if(filters.oauth) { %> + if(authTypes.indexOf(this.provider) !== -1) { return true; }<% } %> return password.length; @@ -94,15 +99,16 @@ UserSchema UserSchema .path('email') .validate(function(value, respond) { - var self = this; - <%_ if(filters.oauth) { _%> - if (authTypes.indexOf(this.provider) !== -1) { + <%_ if(filters.oauth) { -%> + if(authTypes.indexOf(this.provider) !== -1) { return respond(true); - }<% } %> + } + + <%_ } -%> return this.constructor.findOne({ email: value }).exec() - .then(function(user) { - if (user) { - if (self.id === user.id) { + .then(user => { + if(user) { + if(this.id === user.id) { return respond(true); } return respond(false); @@ -124,13 +130,13 @@ var validatePresenceOf = function(value) { UserSchema .pre('save', function(next) { // Handle new/update passwords - if (!this.isModified('password')) { + if(!this.isModified('password')) { return next(); } - if (!validatePresenceOf(this.password)) { - <% if (filters.oauth) { %>if (authTypes.indexOf(this.provider) === -1) { - <% } %>return next(new Error('Invalid password'));<% if (filters.oauth) { %> + if(!validatePresenceOf(this.password)) { + <% if(filters.oauth) { %>if(authTypes.indexOf(this.provider) === -1) { + <% } %>return next(new Error('Invalid password'));<% if(filters.oauth) { %> } else { return next(); }<% } %> @@ -138,16 +144,16 @@ UserSchema // Make salt with a callback this.makeSalt((saltErr, salt) => { - if (saltErr) { + if(saltErr) { return next(saltErr); } this.salt = salt; this.encryptPassword(this.password, (encryptErr, hashedPassword) => { - if (encryptErr) { + if(encryptErr) { return next(encryptErr); } this.password = hashedPassword; - next(); + return next(); }); }); }); @@ -165,19 +171,19 @@ UserSchema.methods = { * @api public */ authenticate(password, callback) { - if (!callback) { + if(!callback) { return this.password === this.encryptPassword(password); } this.encryptPassword(password, (err, pwdGen) => { - if (err) { + if(err) { return callback(err); } - if (this.password === pwdGen) { - callback(null, true); + if(this.password === pwdGen) { + return callback(null, true); } else { - callback(null, false); + return callback(null, false); } }); }, @@ -185,7 +191,7 @@ UserSchema.methods = { /** * Make salt * - * @param {Number} byteSize Optional salt byte size, default to 16 + * @param {Number} [byteSize] - Optional salt byte size, default to 16 * @param {Function} callback * @return {String} * @api public @@ -193,26 +199,24 @@ UserSchema.methods = { makeSalt(byteSize, callback) { var defaultByteSize = 16; - if (typeof arguments[0] === 'function') { + if(typeof arguments[0] === 'function') { callback = arguments[0]; byteSize = defaultByteSize; - } else if (typeof arguments[1] === 'function') { + } else if(typeof arguments[1] === 'function') { callback = arguments[1]; + } else { + throw new Error('Missing Callback'); } - if (!byteSize) { + if(!byteSize) { byteSize = defaultByteSize; } - if (!callback) { - return crypto.randomBytes(byteSize).toString('base64'); - } - return crypto.randomBytes(byteSize, (err, salt) => { - if (err) { - callback(err); + if(err) { + return callback(err); } else { - callback(null, salt.toString('base64')); + return callback(null, salt.toString('base64')); } }); }, @@ -226,8 +230,8 @@ UserSchema.methods = { * @api public */ encryptPassword(password, callback) { - if (!password || !this.salt) { - if (!callback) { + if(!password || !this.salt) { + if(!callback) { return null; } else { return callback('Missing password or salt'); @@ -238,13 +242,13 @@ UserSchema.methods = { var defaultKeyLength = 64; var salt = new Buffer(this.salt, 'base64'); - if (!callback) { + if(!callback) { return crypto.pbkdf2Sync(password, salt, defaultIterations, defaultKeyLength) .toString('base64'); } return crypto.pbkdf2(password, salt, defaultIterations, defaultKeyLength, (err, key) => { - if (err) { + if(err) { callback(err); } else { callback(null, key.toString('base64')); diff --git a/templates/app/server/api/user(auth)/user.model(sequelizeModels).js b/templates/app/server/api/user(auth)/user.model(sequelizeModels).js index e2c625378..58e8f5ae2 100644 --- a/templates/app/server/api/user(auth)/user.model(sequelizeModels).js +++ b/templates/app/server/api/user(auth)/user.model(sequelizeModels).js @@ -1,13 +1,13 @@ 'use strict'; -import crypto from 'crypto';<% if (filters.oauth) { %> +import crypto from 'crypto';<% if(filters.oauth) { %> var authTypes = ['github', 'twitter', 'facebook', 'google'];<% } %> var validatePresenceOf = function(value) { return value && value.length; }; -module.exports = function(sequelize, DataTypes) { +export default function(sequelize, DataTypes) { var User = sequelize.define('User', { _id: { @@ -37,9 +37,9 @@ module.exports = function(sequelize, DataTypes) { } }, provider: DataTypes.STRING, - salt: DataTypes.STRING<% if (filters.oauth) { %>,<% if (filters.facebookAuth) { %> - facebook: DataTypes.JSON,<% } %><% if (filters.twitterAuth) { %> - twitter: DataTypes.JSON,<% } %><% if (filters.googleAuth) { %> + salt: DataTypes.STRING<% if(filters.oauth) { %>,<% if(filters.facebookAuth) { %> + facebook: DataTypes.JSON,<% } %><% if(filters.twitterAuth) { %> + twitter: DataTypes.JSON,<% } %><% if(filters.googleAuth) { %> google: DataTypes.JSON,<% } %> github: DataTypes.JSON<% } %> @@ -52,16 +52,16 @@ module.exports = function(sequelize, DataTypes) { // Public profile information profile: function() { return { - 'name': this.name, - 'role': this.role + name: this.name, + role: this.role }; }, // Non-sensitive info we'll be putting in the token token: function() { return { - '_id': this._id, - 'role': this.role + _id: this._id, + role: this.role }; } }, @@ -70,25 +70,25 @@ module.exports = function(sequelize, DataTypes) { * Pre-save hooks */ hooks: { - beforeBulkCreate: function(users, fields, fn) { + beforeBulkCreate(users, fields, fn) { var totalUpdated = 0; - users.forEach(function(user) { - user.updatePassword(function(err) { - if (err) { + users.forEach(user => { + user.updatePassword(err => { + if(err) { return fn(err); } totalUpdated += 1; - if (totalUpdated === users.length) { + if(totalUpdated === users.length) { return fn(); } }); }); }, - beforeCreate: function(user, fields, fn) { + beforeCreate(user, fields, fn) { user.updatePassword(fn); }, - beforeUpdate: function(user, fields, fn) { - if (user.changed('password')) { + beforeUpdate(user, fields, fn) { + if(user.changed('password')) { return user.updatePassword(fn); } fn(); @@ -107,18 +107,18 @@ module.exports = function(sequelize, DataTypes) { * @return {Boolean} * @api public */ - authenticate: function(password, callback) { - if (!callback) { + authenticate(password, callback) { + if(!callback) { return this.password === this.encryptPassword(password); } var _this = this; this.encryptPassword(password, function(err, pwdGen) { - if (err) { + if(err) { callback(err); } - if (_this.password === pwdGen) { + if(_this.password === pwdGen) { callback(null, true); } else { @@ -130,32 +130,29 @@ module.exports = function(sequelize, DataTypes) { /** * Make salt * - * @param {Number} byteSize Optional salt byte size, default to 16 + * @param {Number} [byteSize] - Optional salt byte size, default to 16 * @param {Function} callback * @return {String} * @api public */ - makeSalt: function(byteSize, callback) { + makeSalt(byteSize, callback) { var defaultByteSize = 16; - if (typeof arguments[0] === 'function') { + if(typeof arguments[0] === 'function') { callback = arguments[0]; byteSize = defaultByteSize; - } - else if (typeof arguments[1] === 'function') { + } else if(typeof arguments[1] === 'function') { callback = arguments[1]; + } else { + throw new Error('Missing Callback'); } - if (!byteSize) { + if(!byteSize) { byteSize = defaultByteSize; } - if (!callback) { - return crypto.randomBytes(byteSize).toString('base64'); - } - return crypto.randomBytes(byteSize, function(err, salt) { - if (err) { + if(err) { callback(err); } return callback(null, salt.toString('base64')); @@ -170,26 +167,23 @@ module.exports = function(sequelize, DataTypes) { * @return {String} * @api public */ - encryptPassword: function(password, callback) { - if (!password || !this.salt) { - if (!callback) { - return null; - } - return callback(null); + encryptPassword(password, callback) { + if(!password || !this.salt) { + return callback ? callback(null) : null; } var defaultIterations = 10000; var defaultKeyLength = 64; var salt = new Buffer(this.salt, 'base64'); - if (!callback) { + if(!callback) { return crypto.pbkdf2Sync(password, salt, defaultIterations, defaultKeyLength) .toString('base64'); } return crypto.pbkdf2(password, salt, defaultIterations, defaultKeyLength, function(err, key) { - if (err) { + if(err) { callback(err); } return callback(null, key.toString('base64')); @@ -203,31 +197,28 @@ module.exports = function(sequelize, DataTypes) { * @return {String} * @api public */ - updatePassword: function(fn) { + updatePassword(fn) { // Handle new/update passwords - if (this.password) { - if (!validatePresenceOf(this.password)<% if (filters.oauth) { %> && authTypes.indexOf(this.provider) === -1<% } %>) { - fn(new Error('Invalid password')); - } + if(!this.password) return fn(null); - // Make salt with a callback - var _this = this; - this.makeSalt(function(saltErr, salt) { - if (saltErr) { - fn(saltErr); + if(!validatePresenceOf(this.password)<% if(filters.oauth) { %> && authTypes.indexOf(this.provider) === -1<% } %>) { + fn(new Error('Invalid password')); + } + + // Make salt with a callback + this.makeSalt((saltErr, salt) => { + if(saltErr) { + return fn(saltErr); + } + this.salt = salt; + this.encryptPassword(this.password, (encryptErr, hashedPassword) => { + if(encryptErr) { + fn(encryptErr); } - _this.salt = salt; - _this.encryptPassword(_this.password, function(encryptErr, hashedPassword) { - if (encryptErr) { - fn(encryptErr); - } - _this.password = hashedPassword; - fn(null); - }); + this.password = hashedPassword; + fn(null); }); - } else { - fn(null); - } + }); } } }); diff --git a/templates/app/server/auth(auth)/facebook(facebookAuth)/passport.js b/templates/app/server/auth(auth)/facebook(facebookAuth)/passport.js index e8c9f9d9d..2573c2454 100644 --- a/templates/app/server/auth(auth)/facebook(facebookAuth)/passport.js +++ b/templates/app/server/auth(auth)/facebook(facebookAuth)/passport.js @@ -12,15 +12,15 @@ export function setup(User, config) { ] }, function(accessToken, refreshToken, profile, done) { - <% if (filters.mongooseModels) { %>User.findOne({'facebook.id': profile.id}).exec()<% } - if (filters.sequelizeModels) { %>User.find({where:{'facebook.id': profile.id}})<% } %> + <% if(filters.mongooseModels) { %>User.findOne({'facebook.id': profile.id}).exec()<% } + if(filters.sequelizeModels) { %>User.find({where:{'facebook.id': profile.id}})<% } %> .then(user => { - if (user) { + if(user) { return done(null, user); } - <% if (filters.mongooseModels) { %>user = new User({<% } - if (filters.sequelizeModels) { %>user = User.build({<% } %> + <% if(filters.mongooseModels) { %>user = new User({<% } + if(filters.sequelizeModels) { %>user = User.build({<% } %> name: profile.displayName, email: profile.emails[0].value, role: 'user', @@ -28,7 +28,7 @@ export function setup(User, config) { facebook: profile._json }); user.save() - .then(user => done(null, user)) + .then(savedUser => done(null, savedUser)) .catch(err => done(err)); }) .catch(err => done(err)); diff --git a/templates/app/server/auth(auth)/google(googleAuth)/passport.js b/templates/app/server/auth(auth)/google(googleAuth)/passport.js index 9d6d2193d..4e8f71e66 100644 --- a/templates/app/server/auth(auth)/google(googleAuth)/passport.js +++ b/templates/app/server/auth(auth)/google(googleAuth)/passport.js @@ -8,15 +8,15 @@ export function setup(User, config) { callbackURL: config.google.callbackURL }, function(accessToken, refreshToken, profile, done) { - <% if (filters.mongooseModels) { %>User.findOne({'google.id': profile.id}).exec()<% } - if (filters.sequelizeModels) { %>User.find({where:{'google.id': profile.id}})<% } %> + <% if(filters.mongooseModels) { %>User.findOne({'google.id': profile.id}).exec()<% } + if(filters.sequelizeModels) { %>User.find({where:{'google.id': profile.id}})<% } %> .then(user => { - if (user) { + if(user) { return done(null, user); } - <% if (filters.mongooseModels) { %>user = new User({<% } - if (filters.sequelizeModels) { %>user = User.build({<% } %> + <% if(filters.mongooseModels) { %>user = new User({<% } + if(filters.sequelizeModels) { %>user = User.build({<% } %> name: profile.displayName, email: profile.emails[0].value, role: 'user', @@ -24,9 +24,9 @@ export function setup(User, config) { provider: 'google', google: profile._json }); - <% if (filters.mongooseModels) { %>user.save()<% } - if (filters.sequelizeModels) { %>user.save()<% } %> - .then(user => done(null, user)) + <% if(filters.mongooseModels) { %>user.save()<% } + if(filters.sequelizeModels) { %>user.save()<% } %> + .then(savedUser => done(null, savedUser)) .catch(err => done(err)); }) .catch(err => done(err)); diff --git a/templates/app/server/auth(auth)/local/index.js b/templates/app/server/auth(auth)/local/index.js index 8002a8442..08ebf69b2 100644 --- a/templates/app/server/auth(auth)/local/index.js +++ b/templates/app/server/auth(auth)/local/index.js @@ -9,16 +9,16 @@ var router = express.Router(); router.post('/', function(req, res, next) { passport.authenticate('local', function(err, user, info) { var error = err || info; - if (error) { + if(error) { return res.status(401).json(error); } - if (!user) { + if(!user) { return res.status(404).json({message: 'Something went wrong, please try again.'}); } var token = signToken(user._id, user.role); res.json({ token }); - })(req, res, next) + })(req, res, next); }); export default router; diff --git a/templates/app/server/auth(auth)/local/passport.js b/templates/app/server/auth(auth)/local/passport.js index 430bbec38..125f482bc 100644 --- a/templates/app/server/auth(auth)/local/passport.js +++ b/templates/app/server/auth(auth)/local/passport.js @@ -2,25 +2,25 @@ import passport from 'passport'; import {Strategy as LocalStrategy} from 'passport-local'; function localAuthenticate(User, email, password, done) { - <% if (filters.mongooseModels) { %>User.findOne({ + <% if(filters.mongooseModels) { %>User.findOne({ email: email.toLowerCase() }).exec()<% } - if (filters.sequelizeModels) { %>User.find({ + if(filters.sequelizeModels) { %>User.find({ where: { email: email.toLowerCase() } })<% } %> .then(user => { - if (!user) { + if(!user) { return done(null, false, { message: 'This email is not registered.' }); } user.authenticate(password, function(authError, authenticated) { - if (authError) { + if(authError) { return done(authError); } - if (!authenticated) { + if(!authenticated) { return done(null, false, { message: 'This password is not correct.' }); } else { return done(null, user); @@ -30,11 +30,11 @@ function localAuthenticate(User, email, password, done) { .catch(err => done(err)); } -export function setup(User, config) { +export function setup(User/*, config*/) { passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' // this is the virtual field on the model - }, function(email, password, done) {<% if (filters.models) { %> + }, function(email, password, done) {<% if(filters.models) { %> return localAuthenticate(User, email, password, done); <% } %> })); } diff --git a/templates/app/server/auth(auth)/twitter(twitterAuth)/passport.js b/templates/app/server/auth(auth)/twitter(twitterAuth)/passport.js index 16c34339c..f13b4cfe7 100644 --- a/templates/app/server/auth(auth)/twitter(twitterAuth)/passport.js +++ b/templates/app/server/auth(auth)/twitter(twitterAuth)/passport.js @@ -8,24 +8,24 @@ export function setup(User, config) { callbackURL: config.twitter.callbackURL }, function(token, tokenSecret, profile, done) { - <% if (filters.mongooseModels) { %>User.findOne({'twitter.id': profile.id}).exec()<% } - if (filters.sequelizeModels) { %>User.find({where:{'twitter.id': profile.id}})<% } %> + <% if(filters.mongooseModels) { %>User.findOne({'twitter.id': profile.id}).exec()<% } + if(filters.sequelizeModels) { %>User.find({where:{'twitter.id': profile.id}})<% } %> .then(user => { - if (user) { + if(user) { return done(null, user); } - <% if (filters.mongooseModels) { %>user = new User({<% } - if (filters.sequelizeModels) { %>user = User.build({<% } %> + <% if(filters.mongooseModels) { %>user = new User({<% } + if(filters.sequelizeModels) { %>user = User.build({<% } %> name: profile.displayName, username: profile.username, role: 'user', provider: 'twitter', twitter: profile._json }); - <% if (filters.mongooseModels) { %>user.save()<% } - if (filters.sequelizeModels) { %>user.save()<% } %> - .then(user => done(null, user)) + <% if(filters.mongooseModels) { %>user.save()<% } + if(filters.sequelizeModels) { %>user.save()<% } %> + .then(savedUser => done(null, savedUser)) .catch(err => done(err)); }) .catch(err => done(err)); diff --git a/templates/app/server/components/errors/index.js b/templates/app/server/components/errors/index.js index 598698175..f1d7e3d44 100644 --- a/templates/app/server/components/errors/index.js +++ b/templates/app/server/components/errors/index.js @@ -13,7 +13,7 @@ module.exports[404] = function pageNotFound(req, res) { res.status(result.status); res.render(viewFilePath, {}, function(err, html) { - if (err) { + if(err) { return res.status(result.status).json(result); } diff --git a/templates/app/server/config/environment/development.js b/templates/app/server/config/environment/development.js index 472ad5050..fde4920c9 100644 --- a/templates/app/server/config/environment/development.js +++ b/templates/app/server/config/environment/development.js @@ -1,4 +1,5 @@ 'use strict'; +/*eslint no-process-env:0*/ // Development specific configuration // ================================== diff --git a/templates/app/server/config/environment/index.js b/templates/app/server/config/environment/index.js index c6115a06d..a543ced11 100644 --- a/templates/app/server/config/environment/index.js +++ b/templates/app/server/config/environment/index.js @@ -1,14 +1,15 @@ 'use strict'; +/*eslint no-process-env:0*/ -var path = require('path'); -var _ = require('lodash'); +import path from 'path'; +import _ from 'lodash'; -function requiredProcessEnv(name) { - if (!process.env[name]) { +/*function requiredProcessEnv(name) { + if(!process.env[name]) { throw new Error('You must set the ' + name + ' environment variable'); } return process.env[name]; -} +}*/ // All configurations will extend these options // ============================================ @@ -16,7 +17,7 @@ var all = { env: process.env.NODE_ENV, // Root path of server - root: path.normalize(__dirname + '/../../..'), + root: path.normalize(`${__dirname}/../../..`), // Server port port: process.env.PORT || 9000, @@ -39,24 +40,24 @@ var all = { safe: true } } - }<% if (filters.facebookAuth) { %>, + }<% if(filters.facebookAuth) { %>, facebook: { - clientID: process.env.FACEBOOK_ID || 'id', + clientID: process.env.FACEBOOK_ID || 'id', clientSecret: process.env.FACEBOOK_SECRET || 'secret', - callbackURL: (process.env.DOMAIN || '') + '/auth/facebook/callback' - }<% } %><% if (filters.twitterAuth) { %>, + callbackURL: `${process.env.DOMAIN || ''}/auth/facebook/callback` + }<% } %><% if(filters.twitterAuth) { %>, twitter: { - clientID: process.env.TWITTER_ID || 'id', + clientID: process.env.TWITTER_ID || 'id', clientSecret: process.env.TWITTER_SECRET || 'secret', - callbackURL: (process.env.DOMAIN || '') + '/auth/twitter/callback' - }<% } %><% if (filters.googleAuth) { %>, + callbackURL: `${process.env.DOMAIN || ''}/auth/twitter/callback` + }<% } %><% if(filters.googleAuth) { %>, google: { - clientID: process.env.GOOGLE_ID || 'id', + clientID: process.env.GOOGLE_ID || 'id', clientSecret: process.env.GOOGLE_SECRET || 'secret', - callbackURL: (process.env.DOMAIN || '') + '/auth/google/callback' + callbackURL: `${process.env.DOMAIN || ''}/auth/google/callback` }<% } %> }; @@ -65,4 +66,4 @@ var all = { module.exports = _.merge( all, require('./shared'), - require('./' + process.env.NODE_ENV + '.js') || {}); + require(`./${process.env.NODE_ENV}.js`) || {}); diff --git a/templates/app/server/config/environment/production.js b/templates/app/server/config/environment/production.js index 791dfb4a1..91221b2b0 100644 --- a/templates/app/server/config/environment/production.js +++ b/templates/app/server/config/environment/production.js @@ -1,30 +1,30 @@ 'use strict'; +/*eslint no-process-env:0*/ // Production specific configuration // ================================= module.exports = { // Server IP - ip: process.env.OPENSHIFT_NODEJS_IP || - process.env.IP || - undefined, + ip: process.env.OPENSHIFT_NODEJS_IP + || process.env.ip + || undefined, // Server port - port: process.env.OPENSHIFT_NODEJS_PORT || - process.env.PORT || - 8080<% if (filters.mongoose) { %>, + port: process.env.OPENSHIFT_NODEJS_PORT + || process.env.port + || 8080<% if (filters.mongoose) { %>, // MongoDB connection options mongo: { - uri: process.env.MONGODB_URI || - process.env.MONGOHQ_URL || - process.env.OPENSHIFT_MONGODB_DB_URL + - process.env.OPENSHIFT_APP_NAME || - 'mongodb://localhost/<%= lodash.slugify(appname) %>' + uri: process.env.MONGODB_URI + || process.env.MONGOHQ_URL + || process.env.OPENSHIFT_MONGODB_DB_URL + process.env.OPENSHIFT_APP_NAME + || 'mongodb://localhost/<%= lodash.slugify(appname) %>' }<% } if (filters.sequelize) { %>, sequelize: { - uri: process.env.SEQUELIZE_URI || - 'sqlite://', + uri: process.env.SEQUELIZE_URI + || 'sqlite://', options: { logging: false, storage: 'dist.sqlite', diff --git a/templates/app/server/config/environment/test.js b/templates/app/server/config/environment/test.js index ea7d65096..e336d4347 100644 --- a/templates/app/server/config/environment/test.js +++ b/templates/app/server/config/environment/test.js @@ -1,4 +1,5 @@ 'use strict'; +/*eslint no-process-env:0*/ // Test specific configuration // =========================== diff --git a/templates/endpoint/basename.controller.js b/templates/endpoint/basename.controller.js index f4f43d962..24c3946c3 100644 --- a/templates/endpoint/basename.controller.js +++ b/templates/endpoint/basename.controller.js @@ -1,22 +1,22 @@ /** * Using Rails-like standard naming convention for endpoints. - * GET <%= route %> -> index<% if (filters.models) { %> + * GET <%= route %> -> index<% if(filters.models) { %> * POST <%= route %> -> create * GET <%= route %>/:id -> show * PUT <%= route %>/:id -> update * DELETE <%= route %>/:id -> destroy<% } %> */ -'use strict';<% if (filters.models) { %> +'use strict';<% if(filters.models) { %> -import _ from 'lodash';<% if (filters.mongooseModels) { %> -import <%= classedName %> from './<%= basename %>.model';<% } if (filters.sequelizeModels) { %> +import _ from 'lodash';<% if(filters.mongooseModels) { %> +import <%= classedName %> from './<%= basename %>.model';<% } if(filters.sequelizeModels) { %> import {<%= classedName %>} from '<%= relativeRequire(config.get('registerModelsFile')) %>';<% } %> function respondWithResult(res, statusCode) { statusCode = statusCode || 200; return function(entity) { - if (entity) { + if(entity) { res.status(statusCode).json(entity); } }; @@ -24,21 +24,21 @@ function respondWithResult(res, statusCode) { function saveUpdates(updates) { return function(entity) { - <% if (filters.mongooseModels) { %>var updated = _.merge(entity, updates); - return updated.save() - .then(updated => {<% } - if (filters.sequelizeModels) { %>return entity.updateAttributes(updates) - .then(updated => {<% } %> - return updated; - }); + <%_ if(filters.mongooseModels) { -%> + var updated = _.merge(entity, updates); + return updated.save(); + <%_ } -%> + <%_ if(filters.sequelizeModels) { -%> + return entity.updateAttributes(updates); + <%_ } -%> }; } function removeEntity(res) { return function(entity) { - if (entity) { - <% if (filters.mongooseModels) { %>return entity.remove()<% } - if (filters.sequelizeModels) { %>return entity.destroy()<% } %> + if(entity) { + <% if(filters.mongooseModels) { %>return entity.remove()<% } + if(filters.sequelizeModels) { %>return entity.destroy()<% } %> .then(() => { res.status(204).end(); }); @@ -48,7 +48,7 @@ function removeEntity(res) { function handleEntityNotFound(res) { return function(entity) { - if (!entity) { + if(!entity) { res.status(404).end(); return null; } @@ -64,18 +64,18 @@ function handleError(res, statusCode) { }<% } %> // Gets a list of <%= classedName %>s -export function index(req, res) {<% if (!filters.models) { %> +export function index(req, res) {<% if(!filters.models) { %> res.json([]);<% } else { %> - <% if (filters.mongooseModels) { %>return <%= classedName %>.find().exec()<% } - if (filters.sequelizeModels) { %>return <%= classedName %>.findAll()<% } %> + <% if(filters.mongooseModels) { %>return <%= classedName %>.find().exec()<% } + if(filters.sequelizeModels) { %>return <%= classedName %>.findAll()<% } %> .then(respondWithResult(res)) .catch(handleError(res));<% } %> -}<% if (filters.models) { %> +}<% if(filters.models) { %> // Gets a single <%= classedName %> from the DB export function show(req, res) { - <% if (filters.mongooseModels) { %>return <%= classedName %>.findById(req.params.id).exec()<% } - if (filters.sequelizeModels) { %>return <%= classedName %>.find({ + <% if(filters.mongooseModels) { %>return <%= classedName %>.findById(req.params.id).exec()<% } + if(filters.sequelizeModels) { %>return <%= classedName %>.find({ where: { _id: req.params.id } @@ -87,19 +87,19 @@ export function show(req, res) { // Creates a new <%= classedName %> in the DB export function create(req, res) { - <% if (filters.mongooseModels) { %>return <%= classedName %>.create(req.body)<% } - if (filters.sequelizeModels) { %>return <%= classedName %>.create(req.body)<% } %> + <% if(filters.mongooseModels) { %>return <%= classedName %>.create(req.body)<% } + if(filters.sequelizeModels) { %>return <%= classedName %>.create(req.body)<% } %> .then(respondWithResult(res, 201)) .catch(handleError(res)); } // Updates an existing <%= classedName %> in the DB export function update(req, res) { - if (req.body._id) { + if(req.body._id) { delete req.body._id; } - <% if (filters.mongooseModels) { %>return <%= classedName %>.findById(req.params.id).exec()<% } - if (filters.sequelizeModels) { %>return <%= classedName %>.find({ + <% if(filters.mongooseModels) { %>return <%= classedName %>.findById(req.params.id).exec()<% } + if(filters.sequelizeModels) { %>return <%= classedName %>.find({ where: { _id: req.params.id } @@ -112,8 +112,8 @@ export function update(req, res) { // Deletes a <%= classedName %> from the DB export function destroy(req, res) { - <% if (filters.mongooseModels) { %>return <%= classedName %>.findById(req.params.id).exec()<% } - if (filters.sequelizeModels) { %>return <%= classedName %>.find({ + <% if(filters.mongooseModels) { %>return <%= classedName %>.findById(req.params.id).exec()<% } + if(filters.sequelizeModels) { %>return <%= classedName %>.find({ where: { _id: req.params.id } diff --git a/templates/endpoint/basename.events(models).js b/templates/endpoint/basename.events(models).js index f50f8c931..374c8108f 100644 --- a/templates/endpoint/basename.events(models).js +++ b/templates/endpoint/basename.events(models).js @@ -4,38 +4,41 @@ 'use strict'; -import {EventEmitter} from 'events';<% if (filters.mongooseModels) { %> -import <%= classedName %> from './<%= basename %>.model';<% } if (filters.sequelizeModels) { %> +import {EventEmitter} from 'events';<% if(filters.mongooseModels) { %> +import <%= classedName %> from './<%= basename %>.model';<% } if(filters.sequelizeModels) { %> var <%= classedName %> = require('<%= relativeRequire(config.get('registerModelsFile')) %>').<%= classedName %>;<% } %> var <%= classedName %>Events = new EventEmitter(); // Set max event listeners (0 == unlimited) <%= classedName %>Events.setMaxListeners(0); -// Model events<% if (filters.mongooseModels) { %> +// Model events +<%_ if(filters.mongooseModels) { -%> var events = { - 'save': 'save', - 'remove': 'remove' -};<% } if (filters.sequelizeModels) { %> + save: 'save', + remove: 'remove' +}; +<%_ } if(filters.sequelizeModels) { -%> var events = { - 'afterCreate': 'save', - 'afterUpdate': 'save', - 'afterDestroy': 'remove' -};<% } %> + afterCreate: 'save', + afterUpdate: 'save', + afterDestroy: 'remove' +}; +<%_ } -%> // Register the event emitter to the model events -for (var e in events) { - var event = events[e];<% if (filters.mongooseModels) { %> - <%= classedName %>.schema.post(e, emitEvent(event));<% } if (filters.sequelizeModels) { %> +for(var e in events) { + let event = events[e];<% if(filters.mongooseModels) { %> + <%= classedName %>.schema.post(e, emitEvent(event));<% } if(filters.sequelizeModels) { %> <%= classedName %>.hook(e, emitEvent(event));<% } %> } function emitEvent(event) { - return function(doc<% if (filters.sequelizeModels) { %>, options, done<% } %>) { + return function(doc<% if(filters.sequelizeModels) { %>, options, done<% } %>) { <%= classedName %>Events.emit(event + ':' + doc._id, doc); - <%= classedName %>Events.emit(event, doc);<% if (filters.sequelizeModels) { %> + <%= classedName %>Events.emit(event, doc);<% if(filters.sequelizeModels) { %> done(null);<% } %> - } + }; } export default <%= classedName %>Events; diff --git a/templates/endpoint/basename.integration.js b/templates/endpoint/basename.integration.js index f805e2397..c651766d1 100644 --- a/templates/endpoint/basename.integration.js +++ b/templates/endpoint/basename.integration.js @@ -6,7 +6,6 @@ import request from 'supertest';<% if(filters.models) { %> var new<%= classedName %>;<% } %> describe('<%= classedName %> API:', function() { - describe('GET <%= route %>', function() { var <%= cameledName %>s; @@ -16,7 +15,7 @@ describe('<%= classedName %> API:', function() { .expect(200) .expect('Content-Type', /json/) .end((err, res) => { - if (err) { + if(err) { return done(err); } <%= cameledName %>s = res.body; @@ -27,7 +26,6 @@ describe('<%= classedName %> API:', function() { it('should respond with JSON array', function() { <%= expect() %><%= cameledName %>s<%= to() %>.be.instanceOf(Array); }); - });<% if(filters.models) { %> describe('POST <%= route %>', function() { @@ -41,7 +39,7 @@ describe('<%= classedName %> API:', function() { .expect(201) .expect('Content-Type', /json/) .end((err, res) => { - if (err) { + if(err) { return done(err); } new<%= classedName %> = res.body; @@ -53,7 +51,6 @@ describe('<%= classedName %> API:', function() { <%= expect() %>new<%= classedName %>.name<%= to() %>.equal('New <%= classedName %>'); <%= expect() %>new<%= classedName %>.info<%= to() %>.equal('This is the brand new <%= cameledName %>!!!'); }); - }); describe('GET <%= route %>/:id', function() { @@ -65,7 +62,7 @@ describe('<%= classedName %> API:', function() { .expect(200) .expect('Content-Type', /json/) .end((err, res) => { - if (err) { + if(err) { return done(err); } <%= cameledName %> = res.body; @@ -81,7 +78,6 @@ describe('<%= classedName %> API:', function() { <%= expect() %><%= cameledName %>.name<%= to() %>.equal('New <%= classedName %>'); <%= expect() %><%= cameledName %>.info<%= to() %>.equal('This is the brand new <%= cameledName %>!!!'); }); - }); describe('PUT <%= route %>/:id', function() { @@ -97,7 +93,7 @@ describe('<%= classedName %> API:', function() { .expect(200) .expect('Content-Type', /json/) .end(function(err, res) { - if (err) { + if(err) { return done(err); } updated<%= classedName %> = res.body; @@ -113,17 +109,15 @@ describe('<%= classedName %> API:', function() { <%= expect() %>updated<%= classedName %>.name<%= to() %>.equal('Updated <%= classedName %>'); <%= expect() %>updated<%= classedName %>.info<%= to() %>.equal('This is the updated <%= cameledName %>!!!'); }); - }); describe('DELETE <%= route %>/:id', function() { - it('should respond with 204 on successful removal', function(done) { request(app) .delete('<%= route %>/' + new<%= classedName %>._id) .expect(204) - .end((err, res) => { - if (err) { + .end(err => { + if(err) { return done(err); } done(); @@ -134,14 +128,12 @@ describe('<%= classedName %> API:', function() { request(app) .delete('<%= route %>/' + new<%= classedName %>._id) .expect(404) - .end((err, res) => { - if (err) { + .end(err => { + if(err) { return done(err); } done(); }); }); - });<% } %> - }); diff --git a/templates/endpoint/basename.socket(socketio).js b/templates/endpoint/basename.socket(socketio).js index b9ee3ab56..0662cb886 100644 --- a/templates/endpoint/basename.socket(socketio).js +++ b/templates/endpoint/basename.socket(socketio).js @@ -11,9 +11,9 @@ var events = ['save', 'remove']; export function register(socket) { // Bind model events to socket events - for (var i = 0, eventsLength = events.length; i < eventsLength; i++) { + for(var i = 0, eventsLength = events.length; i < eventsLength; i++) { var event = events[i]; - var listener = createListener('<%= cameledName %>:' + event, socket); + var listener = createListener(`<%= cameledName %>:${event}`, socket); <%= classedName %>Events.on(event, listener); socket.on('disconnect', removeListener(event, listener)); diff --git a/templates/endpoint/index.spec.js b/templates/endpoint/index.spec.js index 81b6ec54a..adfc84b0f 100644 --- a/templates/endpoint/index.spec.js +++ b/templates/endpoint/index.spec.js @@ -20,8 +20,8 @@ var routerStub = { // require the index with our stubbed out modules var <%= cameledName %>Index = proxyquire('./index.js', { - 'express': { - Router: function() { + express: { + Router() { return routerStub; } }, @@ -29,69 +29,55 @@ var <%= cameledName %>Index = proxyquire('./index.js', { }); describe('<%= classedName %> API Router:', function() { - it('should return an express router instance', function() { <%= expect() %><%= cameledName %>Index<%= to() %>.equal(routerStub); }); describe('GET <%= route %>', function() { - it('should route to <%= cameledName %>.controller.index', function() { <%= expect() %>routerStub.get .withArgs('/', '<%= cameledName %>Ctrl.index') <%= to() %>.have.been.calledOnce; }); - });<% if(filters.models) { %> describe('GET <%= route %>/:id', function() { - it('should route to <%= cameledName %>.controller.show', function() { <%= expect() %>routerStub.get .withArgs('/:id', '<%= cameledName %>Ctrl.show') <%= to() %>.have.been.calledOnce; }); - }); describe('POST <%= route %>', function() { - it('should route to <%= cameledName %>.controller.create', function() { <%= expect() %>routerStub.post .withArgs('/', '<%= cameledName %>Ctrl.create') <%= to() %>.have.been.calledOnce; }); - }); describe('PUT <%= route %>/:id', function() { - it('should route to <%= cameledName %>.controller.update', function() { <%= expect() %>routerStub.put .withArgs('/:id', '<%= cameledName %>Ctrl.update') <%= to() %>.have.been.calledOnce; }); - }); describe('PATCH <%= route %>/:id', function() { - it('should route to <%= cameledName %>.controller.update', function() { <%= expect() %>routerStub.patch .withArgs('/:id', '<%= cameledName %>Ctrl.update') <%= to() %>.have.been.calledOnce; }); - }); describe('DELETE <%= route %>/:id', function() { - it('should route to <%= cameledName %>.controller.destroy', function() { <%= expect() %>routerStub.delete .withArgs('/:id', '<%= cameledName %>Ctrl.destroy') <%= to() %>.have.been.calledOnce; }); - });<% } %> - });