From d17bc71a0b522676157ff06ba6a7b99d9841cf80 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Thu, 25 Aug 2016 18:06:54 +0100 Subject: [PATCH] chore(lint): lint ts as well as js (#1823) --- addon/ng2/commands/build.ts | 17 +++-- addon/ng2/commands/doc.ts | 10 +-- addon/ng2/commands/e2e.ts | 2 +- addon/ng2/commands/generate.ts | 16 ++--- addon/ng2/commands/github-pages-deploy.ts | 40 ++++++----- addon/ng2/commands/lint.ts | 2 +- addon/ng2/commands/serve.ts | 62 ++++++++++------ addon/ng2/commands/test.ts | 2 +- addon/ng2/commands/version.ts | 14 ++-- addon/ng2/custom-typings.d.ts | 6 +- addon/ng2/models/config.ts | 14 ++-- addon/ng2/models/config/config.ts | 6 +- addon/ng2/models/find-lazy-modules.ts | 10 +-- .../json-schema/schema-class-factory.ts | 6 +- addon/ng2/models/json-schema/schema-tree.ts | 6 +- addon/ng2/models/json-schema/serializer.ts | 3 - addon/ng2/models/webpack-build-common.ts | 54 ++++++++++---- addon/ng2/models/webpack-build-development.ts | 4 +- addon/ng2/models/webpack-build-mobile.ts | 14 ++-- addon/ng2/models/webpack-build-production.ts | 12 ++-- addon/ng2/models/webpack-build-utils.ts | 8 +-- addon/ng2/models/webpack-config.ts | 41 ++++++----- addon/ng2/tasks/build-webpack-watch.ts | 17 +++-- addon/ng2/tasks/build-webpack.ts | 19 +++-- addon/ng2/tasks/create-github-repo.ts | 36 +++++++--- addon/ng2/tasks/doc.ts | 4 +- addon/ng2/tasks/e2e.ts | 27 +++---- addon/ng2/tasks/link-cli.ts | 2 +- addon/ng2/tasks/lint.ts | 2 +- addon/ng2/tasks/serve-webpack.ts | 46 ++++++------ addon/ng2/tasks/test.ts | 3 +- addon/ng2/tsconfig.json | 3 + .../ng2/utilities/prerender-webpack-plugin.ts | 4 +- package.json | 8 ++- packages/ast-tools/src/ast-utils.ts | 6 +- packages/ast-tools/src/change.ts | 2 +- packages/ast-tools/src/route-utils.spec.ts | 20 ++++-- packages/ast-tools/src/route-utils.ts | 71 ++++++++++++------- tests/acceptance/module-resolver.spec.ts | 3 +- tslint.json | 5 +- 40 files changed, 376 insertions(+), 251 deletions(-) diff --git a/addon/ng2/commands/build.ts b/addon/ng2/commands/build.ts index 935102fa8484..423788459318 100644 --- a/addon/ng2/commands/build.ts +++ b/addon/ng2/commands/build.ts @@ -17,7 +17,12 @@ module.exports = Command.extend({ aliases: ['b'], availableOptions: [ - { name: 'target', type: String, default: 'development', aliases: ['t', { 'dev': 'development' }, { 'prod': 'production' }] }, + { + name: 'target', + type: String, + default: 'development', + aliases: ['t', { 'dev': 'development' }, { 'prod': 'production' }] + }, { name: 'environment', type: String, default: '', aliases: ['e'] }, { name: 'output-path', type: 'Path', default: 'dist/', aliases: ['o'] }, { name: 'watch', type: Boolean, default: false, aliases: ['w'] }, @@ -26,18 +31,18 @@ module.exports = Command.extend({ ], run: function (commandOptions: BuildOptions) { - if (commandOptions.environment === ''){ + if (commandOptions.environment === '') { if (commandOptions.target === 'development') { commandOptions.environment = 'dev'; } if (commandOptions.target === 'production') { commandOptions.environment = 'prod'; - } + } } - var project = this.project; - var ui = this.ui; - var buildTask = commandOptions.watch ? + const project = this.project; + const ui = this.ui; + const buildTask = commandOptions.watch ? new WebpackBuildWatch({ cliProject: project, ui: ui, diff --git a/addon/ng2/commands/doc.ts b/addon/ng2/commands/doc.ts index 0551e8ddfdb4..040be66ee15f 100644 --- a/addon/ng2/commands/doc.ts +++ b/addon/ng2/commands/doc.ts @@ -10,10 +10,10 @@ const DocCommand = Command.extend({ '' ], - run: function(commandOptions, rawArgs:Array) { - var keyword = rawArgs[0]; - - var docTask = new DocTask({ + run: function(commandOptions, rawArgs: Array) { + const keyword = rawArgs[0]; + + const docTask = new DocTask({ ui: this.ui, analytics: this.analytics, project: this.project @@ -23,4 +23,4 @@ const DocCommand = Command.extend({ } }); -module.exports = DocCommand; \ No newline at end of file +module.exports = DocCommand; diff --git a/addon/ng2/commands/e2e.ts b/addon/ng2/commands/e2e.ts index 05fb0244477a..b4facd11c444 100644 --- a/addon/ng2/commands/e2e.ts +++ b/addon/ng2/commands/e2e.ts @@ -9,7 +9,7 @@ module.exports = Command.extend({ run: function () { this.project.ngConfig = this.project.ngConfig || CliConfig.fromProject(); - var e2eTask = new E2ETask({ + const e2eTask = new E2ETask({ ui: this.ui, analytics: this.analytics, project: this.project diff --git a/addon/ng2/commands/generate.ts b/addon/ng2/commands/generate.ts index a38f298b38f5..bc3dda446b64 100644 --- a/addon/ng2/commands/generate.ts +++ b/addon/ng2/commands/generate.ts @@ -2,9 +2,9 @@ import * as EmberGenerateCommand from 'ember-cli/lib/commands/generate'; import * as fs from 'fs'; import * as path from 'path'; import * as SilentError from 'silent-error'; -var chalk = require('chalk'); import * as Blueprint from 'ember-cli/lib/models/blueprint'; -var EOL = require('os').EOL; +const chalk = require('chalk'); +const EOL = require('os').EOL; const GenerateCommand = EmberGenerateCommand.extend({ name: 'generate', @@ -21,16 +21,16 @@ const GenerateCommand = EmberGenerateCommand.extend({ !fs.existsSync(path.join(__dirname, '..', 'blueprints', rawArgs[0]))) { SilentError.debugOrThrow('angular-cli/commands/generate', `Invalid blueprint: ${rawArgs[0]}`); } - + // Override default help to hide ember blueprints EmberGenerateCommand.prototype.printDetailedHelp = function (options) { - var blueprintList = fs.readdirSync(path.join(__dirname, '..', 'blueprints')); - var blueprints = blueprintList + const blueprintList = fs.readdirSync(path.join(__dirname, '..', 'blueprints')); + const blueprints = blueprintList .filter(bp => bp.indexOf('-test') === -1) .filter(bp => bp !== 'ng2') .map(bp => Blueprint.load(path.join(__dirname, '..', 'blueprints', bp))); - - var output = ''; + + let output = ''; blueprints .forEach(function (bp) { output += bp.printBasicHelp(false) + EOL; @@ -38,7 +38,7 @@ const GenerateCommand = EmberGenerateCommand.extend({ this.ui.writeLine(chalk.cyan(' Available blueprints')); this.ui.writeLine(output); }; - + return EmberGenerateCommand.prototype.beforeRun.apply(this, arguments); } }); diff --git a/addon/ng2/commands/github-pages-deploy.ts b/addon/ng2/commands/github-pages-deploy.ts index 8a967bff91cf..c0420298f83b 100644 --- a/addon/ng2/commands/github-pages-deploy.ts +++ b/addon/ng2/commands/github-pages-deploy.ts @@ -9,6 +9,7 @@ import * as path from 'path'; import * as WebpackBuild from '../tasks/build-webpack'; import * as CreateGithubRepo from '../tasks/create-github-repo'; import { CliConfig } from '../models/config'; +import { oneLine } from 'common-tags'; const fsReadFile = Promise.denodeify(fs.readFile); const fsWriteFile = Promise.denodeify(fs.writeFile); @@ -18,7 +19,10 @@ const fsCopy = Promise.denodeify(fse.copy); module.exports = Command.extend({ name: 'github-pages:deploy', aliases: ['gh-pages:deploy'], - description: 'Build the test app for production, commit it into a git branch, setup GitHub repo and push to it', + description: oneLine` + Build the test app for production, commit it into a git branch, + setup GitHub repo and push to it + `, works: 'insideProject', availableOptions: [ @@ -60,13 +64,13 @@ module.exports = Command.extend({ }], run: function(options, rawArgs) { - var ui = this.ui; - var root = this.project.root; - var execOptions = { + const ui = this.ui; + const root = this.project.root; + const execOptions = { cwd: root }; - if (options.environment === ''){ + if (options.environment === '') { if (options.target === 'development') { options.environment = 'dev'; } @@ -75,7 +79,7 @@ module.exports = Command.extend({ } } - var projectName = this.project.pkg.name; + const projectName = this.project.pkg.name; const outDir = CliConfig.fromProject().config.apps[0].outDir; @@ -86,7 +90,7 @@ module.exports = Command.extend({ // declared here so that tests can stub exec const execPromise = Promise.denodeify(exec); - var buildTask = new WebpackBuild({ + const buildTask = new WebpackBuild({ ui: this.ui, analytics: this.analytics, cliProject: this.project, @@ -95,19 +99,19 @@ module.exports = Command.extend({ outputPath: outDir }); - var buildOptions = { + const buildOptions = { target: options.target, environment: options.environment, outputPath: outDir }; - var createGithubRepoTask = new CreateGithubRepo({ + const createGithubRepoTask = new CreateGithubRepo({ ui: this.ui, analytics: this.analytics, project: this.project }); - var createGithubRepoOptions = { + const createGithubRepoOptions = { projectName, ghUsername: options.ghUsername, ghToken: options.ghToken @@ -137,7 +141,7 @@ module.exports = Command.extend({ } function build() { - if (options.skipBuild) return Promise.resolve(); + if (options.skipBuild) { return Promise.resolve(); } return buildTask.run(buildOptions); } @@ -165,7 +169,7 @@ module.exports = Command.extend({ function checkoutGhPages() { return execPromise(`git checkout ${ghPagesBranch}`) - .catch(createGhPagesBranch) + .catch(createGhPagesBranch); } function createGhPagesBranch() { @@ -179,16 +183,16 @@ module.exports = Command.extend({ function copyFiles() { return fsReadDir(outDir) .then((files) => Promise.all(files.map((file) => { - if (file === '.gitignore'){ + if (file === '.gitignore') { // don't overwrite the .gitignore file return Promise.resolve(); } - return fsCopy(path.join(outDir, file), path.join('.', file)) + return fsCopy(path.join(outDir, file), path.join('.', file)); }))); } function updateBaseHref() { - if (options.userPage) return Promise.resolve(); + if (options.userPage) { return Promise.resolve(); } let indexHtml = path.join(root, 'index.html'); return fsReadFile(indexHtml, 'utf8') .then((data) => data.replace(//g, ``)) @@ -215,7 +219,8 @@ module.exports = Command.extend({ function printProjectUrl() { return execPromise('git remote -v') .then((stdout) => { - let userName = stdout.match(/origin\s+(?:https:\/\/|git@)github\.com(?:\:|\/)([^\/]+)/m)[1].toLowerCase(); + let match = stdout.match(/origin\s+(?:https:\/\/|git@)github\.com(?:\:|\/)([^\/]+)/m); + let userName = match[1].toLowerCase(); let url = `https://${userName}.github.io/${options.userPage ? '' : (projectName + '/')}`; ui.writeLine(chalk.green(`Deployed! Visit ${url}`)); ui.writeLine('Github pages might take a few minutes to show the deployed site.'); @@ -225,7 +230,8 @@ module.exports = Command.extend({ function failGracefully(error) { if (error && (/git clean/.test(error.message) || /Permission denied/.test(error.message))) { ui.writeLine(error.message); - let msg = 'There was a permissions error during git file operations, please close any open project files/folders and try again.'; + let msg = 'There was a permissions error during git file operations, ' + + 'please close any open project files/folders and try again.'; msg += `\nYou might also need to return to the ${initialBranch} branch manually.`; return Promise.reject(new SilentError(msg)); } else { diff --git a/addon/ng2/commands/lint.ts b/addon/ng2/commands/lint.ts index 76b431975605..8e78bab3195a 100644 --- a/addon/ng2/commands/lint.ts +++ b/addon/ng2/commands/lint.ts @@ -6,7 +6,7 @@ module.exports = Command.extend({ description: 'Lints code in existing project', works: 'insideProject', run: function () { - var lintTask = new LintTask({ + const lintTask = new LintTask({ ui: this.ui, analytics: this.analytics, project: this.project diff --git a/addon/ng2/commands/serve.ts b/addon/ng2/commands/serve.ts index 2ae43e4631dd..668ae49d9803 100644 --- a/addon/ng2/commands/serve.ts +++ b/addon/ng2/commands/serve.ts @@ -3,7 +3,6 @@ import * as Command from 'ember-cli/lib/models/command'; import * as Promise from 'ember-cli/lib/ext/promise'; import * as SilentError from 'silent-error'; import * as PortFinder from 'portfinder'; -import * as EOL from 'os'; import * as ServeWebpackTask from '../tasks/serve-webpack.ts'; PortFinder.basePort = 49152; @@ -36,15 +35,46 @@ module.exports = Command.extend({ availableOptions: [ { name: 'port', type: Number, default: defaultPort, aliases: ['p'] }, - { name: 'host', type: String, default: 'localhost', aliases: ['H'], description: 'Listens on all interfaces by default' }, + { + name: 'host', + type: String, + default: 'localhost', + aliases: ['H'], + description: 'Listens on all interfaces by default' + }, { name: 'proxy-config', type: 'Path', aliases: ['pc'] }, { name: 'watcher', type: String, default: 'events', aliases: ['w'] }, { name: 'live-reload', type: Boolean, default: true, aliases: ['lr'] }, - { name: 'live-reload-host', type: String, aliases: ['lrh'], description: 'Defaults to host' }, - { name: 'live-reload-base-url', type: String, aliases: ['lrbu'], description: 'Defaults to baseURL' }, - { name: 'live-reload-port', type: Number, aliases: ['lrp'], description: '(Defaults to port number within [49152...65535])' }, - { name: 'live-reload-live-css', type: Boolean, default: true, description: 'Whether to live reload CSS (default true)' }, - { name: 'target', type: String, default: 'development', aliases: ['t', { 'dev': 'development' }, { 'prod': 'production' }] }, + { + name: 'live-reload-host', + type: String, + aliases: ['lrh'], + description: 'Defaults to host' + }, + { + name: 'live-reload-base-url', + type: String, + aliases: ['lrbu'], + description: 'Defaults to baseURL' + }, + { + name: 'live-reload-port', + type: Number, + aliases: ['lrp'], + description: '(Defaults to port number within [49152...65535])' + }, + { + name: 'live-reload-live-css', + type: Boolean, + default: true, + description: 'Whether to live reload CSS (default true)' + }, + { + name: 'target', + type: String, + default: 'development', + aliases: ['t', { 'dev': 'development' }, { 'prod': 'production' }] + }, { name: 'environment', type: String, default: '', aliases: ['e'] }, { name: 'ssl', type: Boolean, default: false }, { name: 'ssl-key', type: String, default: 'ssl/server.key' }, @@ -52,7 +82,7 @@ module.exports = Command.extend({ ], run: function(commandOptions: ServeTaskOptions) { - if (commandOptions.environment === ''){ + if (commandOptions.environment === '') { if (commandOptions.target === 'development') { commandOptions.environment = 'dev'; } @@ -65,20 +95,12 @@ module.exports = Command.extend({ return this._checkExpressPort(commandOptions) .then(this._autoFindLiveReloadPort.bind(this)) - .then((commandOptions: ServeTaskOptions) => { - commandOptions = assign({}, commandOptions, { + .then((opts: ServeTaskOptions) => { + commandOptions = assign({}, opts, { baseURL: this.project.config(commandOptions.target).baseURL || '/' }); - if (commandOptions.proxy) { - if (!commandOptions.proxy.match(/^(http:|https:)/)) { - var message = 'You need to include a protocol with the proxy URL.' + EOL + 'Try --proxy http://' + commandOptions.proxy; - - return Promise.reject(new SilentError(message)); - } - } - - var serve = new ServeWebpackTask({ + const serve = new ServeWebpackTask({ ui: this.ui, analytics: this.analytics, project: this.project, @@ -93,7 +115,7 @@ module.exports = Command.extend({ .then((foundPort: number) => { if (commandOptions.port !== foundPort && commandOptions.port !== 0) { - var message = 'Port ' + commandOptions.port + ' is already in use.'; + const message = 'Port ' + commandOptions.port + ' is already in use.'; return Promise.reject(new SilentError(message)); } diff --git a/addon/ng2/commands/test.ts b/addon/ng2/commands/test.ts index cb8bc7739edb..73db61af844b 100644 --- a/addon/ng2/commands/test.ts +++ b/addon/ng2/commands/test.ts @@ -16,7 +16,7 @@ module.exports = TestCommand.extend({ run: function (commandOptions) { this.project.ngConfig = this.project.ngConfig || CliConfig.fromProject(); - var testTask = new TestTask({ + const testTask = new TestTask({ ui: this.ui, analytics: this.analytics, project: this.project diff --git a/addon/ng2/commands/version.ts b/addon/ng2/commands/version.ts index 5c34b91af81c..86937c70d118 100644 --- a/addon/ng2/commands/version.ts +++ b/addon/ng2/commands/version.ts @@ -14,18 +14,18 @@ const VersionCommand = Command.extend({ }], run: function (options) { - var versions = process.versions; - var pkg = require(path.resolve(__dirname, '..', '..', '..', 'package.json')); + const versions = process.versions; + const pkg = require(path.resolve(__dirname, '..', '..', '..', 'package.json')); versions['os'] = process.platform + ' ' + process.arch; - var alwaysPrint = ['node', 'os']; + const alwaysPrint = ['node', 'os']; - var ngCliVersion = pkg.version; + let ngCliVersion = pkg.version; if (!__dirname.match(/node_modules/)) { - var gitBranch = '??'; + let gitBranch = '??'; try { - var gitRefName = '' + child_process.execSync('git symbolic-ref HEAD', {cwd: __dirname}); + const gitRefName = '' + child_process.execSync('git symbolic-ref HEAD', {cwd: __dirname}); gitBranch = path.basename(gitRefName.replace('\n', '')); } catch (e) { } @@ -35,7 +35,7 @@ const VersionCommand = Command.extend({ this.printVersion('angular-cli', ngCliVersion); - for (var module in versions) { + for (const module in versions) { if (options.verbose || alwaysPrint.indexOf(module) > -1) { this.printVersion(module, versions[module]); } diff --git a/addon/ng2/custom-typings.d.ts b/addon/ng2/custom-typings.d.ts index b70dd7e88df3..1fbb264de74a 100644 --- a/addon/ng2/custom-typings.d.ts +++ b/addon/ng2/custom-typings.d.ts @@ -3,7 +3,7 @@ interface IWebpackDevServerConfigurationOptions { hot?: boolean; historyApiFallback?: boolean; compress?: boolean; - proxy?: {[key: string] : string}; + proxy?: {[key: string]: string}; staticOptions?: any; quiet?: boolean; noInfo?: boolean; @@ -14,8 +14,8 @@ interface IWebpackDevServerConfigurationOptions { poll?: number; }; publicPath?: string; - headers?: { [key:string]: string }; - stats?: { [key:string]: boolean }; + headers?: { [key: string]: string }; + stats?: { [key: string]: boolean }; inline: boolean; } diff --git a/addon/ng2/models/config.ts b/addon/ng2/models/config.ts index 3998d1abab34..4e11ba9a6452 100644 --- a/addon/ng2/models/config.ts +++ b/addon/ng2/models/config.ts @@ -1,12 +1,10 @@ import {CliConfig as CliConfigBase} from './config/config'; import {CliConfig as ConfigInterface} from '../../../lib/config/schema'; +import { oneLine } from 'common-tags'; import * as chalk from 'chalk'; import * as fs from 'fs'; import * as path from 'path'; -const schemaPath = path.resolve(process.env.CLI_ROOT, 'lib/config/schema.json'); -const schema = require(schemaPath); - export const CLI_CONFIG_FILE_NAME = 'angular-cli.json'; @@ -51,11 +49,11 @@ export class CliConfig extends CliConfigBase { const cliConfig = CliConfigBase.fromConfigPath(CliConfig._configFilePath(), [globalConfigPath]); if (cliConfig.alias('apps.0.root', 'defaults.sourceDir') + cliConfig.alias('apps.0.prefix', 'defaults.prefix')) { - console.error(chalk.yellow( - 'The "defaults.prefix" and "defaults.sourceDir" properties of angular-cli.json\n' - + 'are deprecated in favor of "apps[0].root" and "apps[0].prefix".\n' - + 'Please update in order to avoid errors in future versions of angular-cli.' - )); + console.error(chalk.yellow(oneLine` + The "defaults.prefix" and "defaults.sourceDir" properties of angular-cli.json + are deprecated in favor of "apps[0].root" and "apps[0].prefix".\n + Please update in order to avoid errors in future versions of angular-cli. + `)); } return cliConfig as CliConfig; diff --git a/addon/ng2/models/config/config.ts b/addon/ng2/models/config/config.ts index a1869e50eb96..2c0161c28652 100644 --- a/addon/ng2/models/config/config.ts +++ b/addon/ng2/models/config/config.ts @@ -17,7 +17,7 @@ export class InvalidConfigError extends Error { export class CliConfig { private _config: SchemaClass; - private constructor(private _configPath: string, + constructor(private _configPath: string, schema: Object, configJson: Config, fallbacks: Config[] = []) { @@ -29,7 +29,7 @@ export class CliConfig { save(path: string = this._configPath) { return fs.writeFileSync(path, this.serialize(), 'utf-8'); } - serialize(mimetype: string = 'application/json'): string { + serialize(mimetype = 'application/json'): string { return this._config.$$serialize(mimetype); } @@ -73,7 +73,7 @@ export class CliConfig { try { content = JSON.parse(configContent); schema = JSON.parse(schemaContent); - others = otherContents.map(content => JSON.parse(content)); + others = otherContents.map(content => JSON.parse(otherContent)); } catch (err) { throw new InvalidConfigError(err); } diff --git a/addon/ng2/models/find-lazy-modules.ts b/addon/ng2/models/find-lazy-modules.ts index cc6f13c1dc8e..bad5aebe3d73 100644 --- a/addon/ng2/models/find-lazy-modules.ts +++ b/addon/ng2/models/find-lazy-modules.ts @@ -3,13 +3,9 @@ import * as glob from 'glob'; import * as path from 'path'; import * as ts from 'typescript'; -import {Observable} from 'rxjs/Observable'; import {getSource, findNodes, getContentOfKeyLiteral} from '../utilities/ast-utils'; -const loadChildrenRegex = /(\{[^{}]+?(loadChildren|['"]loadChildren['"])\s*:\s*)('[^']+'|"[^"]+")/gm; - - interface Array { flatMap: (mapFn: (item: T) => Array) => Array; } @@ -37,15 +33,15 @@ export function findLoadChildren(tsFilePath: string): string[] { // key is an expression, can't do anything. return false; } - return key == 'loadChildren' + return key == 'loadChildren'; }) // Remove initializers that are not files. .filter((node: ts.PropertyAssignment) => { return node.initializer.kind === ts.SyntaxKind.StringLiteral; }) - // Get the full text of the initiliazer. + // Get the full text of the initializer. .map((node: ts.PropertyAssignment) => { - return eval(node.initializer.getText(source)); + return eval(node.initializer.getText(source)); // tslint:disable-line }) .flatMap((value: string) => unique[value] ? undefined : unique[value] = value) .map((moduleName: string) => moduleName.split('#')[0]); diff --git a/addon/ng2/models/json-schema/schema-class-factory.ts b/addon/ng2/models/json-schema/schema-class-factory.ts index 0a18f3e2db8c..cdb57d4f8638 100644 --- a/addon/ng2/models/json-schema/schema-class-factory.ts +++ b/addon/ng2/models/json-schema/schema-class-factory.ts @@ -108,7 +108,7 @@ class SchemaClassBase implements SchemaClass { $$set(path: string, value: any) { const node = _getSchemaNodeForPath(this[kSchemaNode], path); if (node) { - node.set(value) + node.set(value); } else { // This might be inside an object that can have additionalProperties, so // a TreeNode would not exist. @@ -137,7 +137,7 @@ class SchemaClassBase implements SchemaClass { return node ? node.defined : false; } - $$delete(path: string){ + $$delete(path: string) { const node = _getSchemaNodeForPath(this[kSchemaNode], path); if (node) { node.destroy(); @@ -145,7 +145,7 @@ class SchemaClassBase implements SchemaClass { } /** Serialize into a string. */ - $$serialize(mimetype: string = 'application/json', ...options: any[]): string { + $$serialize(mimetype = 'application/json', ...options: any[]): string { let str = ''; const serializer = Serializer.fromMimetype(mimetype, (s) => str += s, ...options); diff --git a/addon/ng2/models/json-schema/schema-tree.ts b/addon/ng2/models/json-schema/schema-tree.ts index e8de8b1949b8..6f601c665c22 100644 --- a/addon/ng2/models/json-schema/schema-tree.ts +++ b/addon/ng2/models/json-schema/schema-tree.ts @@ -75,7 +75,7 @@ export abstract class SchemaTreeNode { get parent(): SchemaTreeNode { return this._parent; } get children(): { [key: string]: SchemaTreeNode} { return null; } - abstract get() : T; + abstract get(): T; set(v: T) { if (!this.readOnly) { throw new MissingImplementationError(); @@ -105,7 +105,7 @@ export abstract class SchemaTreeNode { /** Base Class used for Non-Leaves TreeNode. Meaning they can have children. */ abstract class NonLeafSchemaTreeNode extends SchemaTreeNode { dispose() { - for (const key of Object.keys(this.children) { + for (const key of Object.keys(this.children)) { this.children[key].dispose(); } super.dispose(); @@ -132,7 +132,7 @@ abstract class NonLeafSchemaTreeNode extends SchemaTreeNode { const type = schema['type']; let Klass: TreeNodeConstructor = null; - switch(type) { + switch (type) { case 'object': Klass = ObjectSchemaTreeNode; break; case 'array': Klass = ArraySchemaTreeNode; break; case 'string': Klass = StringSchemaTreeNode; break; diff --git a/addon/ng2/models/json-schema/serializer.ts b/addon/ng2/models/json-schema/serializer.ts index a5f8ac1a09a3..3112b8f7d9ef 100644 --- a/addon/ng2/models/json-schema/serializer.ts +++ b/addon/ng2/models/json-schema/serializer.ts @@ -60,9 +60,6 @@ class JsonSerializer implements Serializer { private _top() { return this._state[this._state.length - 1] || {}; } - private _topIsArray() { - return this._top().type == 'array'; - } private _indent(): string { if (this._indentDelta == 0) { diff --git a/addon/ng2/models/webpack-build-common.ts b/addon/ng2/models/webpack-build-common.ts index baeeb5359c27..7bc30b3eef3e 100644 --- a/addon/ng2/models/webpack-build-common.ts +++ b/addon/ng2/models/webpack-build-common.ts @@ -4,7 +4,7 @@ import * as HtmlWebpackPlugin from 'html-webpack-plugin'; import * as webpack from 'webpack'; import * as atl from 'awesome-typescript-loader'; -import {findLazyModules} from './find-lazy-modules'; +import { findLazyModules } from './find-lazy-modules'; export function getWebpackCommonConfig(projectRoot: string, environment: string, appConfig: any) { @@ -14,13 +14,13 @@ export function getWebpackCommonConfig(projectRoot: string, environment: string, const scripts = appConfig.scripts.map(script => path.resolve(appRoot, script)); const lazyModules = findLazyModules(appRoot); - let entry = { + let entry = { main: [appMain] }; // Only add styles/scripts if there's actually entries there - if (appConfig.styles.length > 0) entry.styles = styles; - if (appConfig.scripts.length > 0) entry.scripts = scripts; + if (appConfig.styles.length > 0) { entry['styles'] = styles; } + if (appConfig.scripts.length > 0) { entry['scripts'] = scripts; } return { devtool: 'source-map', @@ -62,16 +62,42 @@ export function getWebpackCommonConfig(projectRoot: string, environment: string, }, // in main, load css as raw text -        { exclude: styles, test: /\.css$/, loaders: ['raw-loader', 'postcss-loader'] }, -        { exclude: styles, test: /\.styl$/, loaders: ['raw-loader', 'postcss-loader', 'stylus-loader'] }, -        { exclude: styles, test: /\.less$/, loaders: ['raw-loader', 'postcss-loader', 'less-loader'] }, -        { exclude: styles, test: /\.scss$|\.sass$/, loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] }, +        { + exclude: styles, + test: /\.css/, + loaders: ['raw-loader', 'postcss-loader'] + }, { + exclude: styles, + test: /\.styl$/, + loaders: ['raw-loader', 'postcss-loader', 'stylus-loader'] }, +        { + exclude: styles, + test: /\.less$/, + loaders: ['raw-loader', 'postcss-loader', 'less-loader'] + }, { + exclude: styles, + test: /\.scss$|\.sass$/, + loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] + }, // outside of main, load it via style-loader -        { include: styles, test: /\.css$/, loaders: ['style-loader', 'css-loader', 'postcss-loader'] }, -        { include: styles, test: /\.styl$/, loaders: ['style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] }, -        { include: styles, test: /\.less$/, loaders: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'] }, -        { include: styles, test: /\.scss$|\.sass$/, loaders: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] }, +        { + include: styles, + test: /\.css$/, + loaders: ['style-loader', 'css-loader', 'postcss-loader'] + }, { + include: styles, + test: /\.styl$/, + loaders: ['style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] + }, { + include: styles, + test: /\.less$/, + loaders: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'] + }, { + include: styles, + test: /\.scss$|\.sass$/, + loaders: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] + }, // load global scripts using script-loader { include: scripts, test: /\.js$/, loader: 'script-loader' }, @@ -97,7 +123,7 @@ export function getWebpackCommonConfig(projectRoot: string, environment: string, // Since it takes a RegExp as first parameter, we need to escape the path. // See https://webpack.github.io/docs/list-of-plugins.html#normalmodulereplacementplugin new RegExp(path.resolve(appRoot, appConfig.environments['source']) - .replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")), + .replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&')), path.resolve(appRoot, appConfig.environments[environment]) ), new webpack.optimize.CommonsChunkPlugin({ @@ -124,5 +150,5 @@ export function getWebpackCommonConfig(projectRoot: string, environment: string, clearImmediate: false, setImmediate: false } - } + }; } diff --git a/addon/ng2/models/webpack-build-development.ts b/addon/ng2/models/webpack-build-development.ts index be24e1bb1cdf..50c5d9a55efc 100644 --- a/addon/ng2/models/webpack-build-development.ts +++ b/addon/ng2/models/webpack-build-development.ts @@ -1,4 +1,4 @@ -const path = require('path') +const path = require('path'); export const getWebpackDevConfigPartial = function(projectRoot: string, appConfig: any) { return { @@ -24,4 +24,4 @@ export const getWebpackDevConfigPartial = function(projectRoot: string, appConfi setImmediate: false } }; -} +}; diff --git a/addon/ng2/models/webpack-build-mobile.ts b/addon/ng2/models/webpack-build-mobile.ts index 3f30234f883b..34290c93cb6d 100644 --- a/addon/ng2/models/webpack-build-mobile.ts +++ b/addon/ng2/models/webpack-build-mobile.ts @@ -1,4 +1,3 @@ -import * as webpack from 'webpack'; import * as path from 'path'; import * as OfflinePlugin from 'offline-plugin'; import * as CopyWebpackPlugin from 'copy-webpack-plugin'; @@ -10,8 +9,13 @@ export const getWebpackMobileConfigPartial = function (projectRoot: string, appC return { plugins: [ new CopyWebpackPlugin([ - {from: path.resolve(projectRoot, appConfig.root, 'icons'), to: path.resolve(projectRoot, appConfig.outDir, 'icons')}, - {from: path.resolve(projectRoot, appConfig.root, 'manifest.webapp'), to: path.resolve(projectRoot, appConfig.outDir)} + { + from: path.resolve(projectRoot, appConfig.root, 'icons'), + to: path.resolve(projectRoot, appConfig.outDir, 'icons') + }, { + from: path.resolve(projectRoot, appConfig.root, 'manifest.webapp'), + to: path.resolve(projectRoot, appConfig.outDir) + } ]), new PrerenderWebpackPlugin({ templatePath: 'index.html', @@ -19,7 +23,7 @@ export const getWebpackMobileConfigPartial = function (projectRoot: string, appC appPath: path.resolve(projectRoot, appConfig.root) }) ] - } + }; }; export const getWebpackMobileProdConfigPartial = function (projectRoot: string, appConfig: any) { @@ -30,5 +34,5 @@ export const getWebpackMobileProdConfigPartial = function (projectRoot: string, plugins: [ new OfflinePlugin() ] - } + }; }; diff --git a/addon/ng2/models/webpack-build-production.ts b/addon/ng2/models/webpack-build-production.ts index d18e84442abb..656152db6cd4 100644 --- a/addon/ng2/models/webpack-build-production.ts +++ b/addon/ng2/models/webpack-build-production.ts @@ -1,5 +1,4 @@ import * as path from 'path'; -import * as webpackMerge from 'webpack-merge'; // used to merge webpack configs import * as WebpackMd5Hash from 'webpack-md5-hash'; import * as CompressionPlugin from 'compression-webpack-plugin'; import * as webpack from 'webpack'; @@ -17,12 +16,11 @@ export const getWebpackProdConfigPartial = function(projectRoot: string, appConf plugins: [ new WebpackMd5Hash(), new webpack.optimize.DedupePlugin(), - // ~107kb new webpack.optimize.UglifyJsPlugin({ - beautify: false, //prod - mangle: { screw_ie8 : true, keep_fnames: true }, //prod - compress: { screw_ie8: true }, //prod - comments: false //prod + beautify: false, + mangle: { screw_ie8 : true, keep_fnames: true }, + compress: { screw_ie8: true }, + comments: false }), new CompressionPlugin({ asset: '[path].gz[query]', @@ -57,5 +55,5 @@ export const getWebpackProdConfigPartial = function(projectRoot: string, appConf clearImmediate: false, setImmediate: false } - } + }; }; diff --git a/addon/ng2/models/webpack-build-utils.ts b/addon/ng2/models/webpack-build-utils.ts index dcaa15558593..b1853ea5ae00 100644 --- a/addon/ng2/models/webpack-build-utils.ts +++ b/addon/ng2/models/webpack-build-utils.ts @@ -2,15 +2,15 @@ import * as path from 'path'; export const ngAppResolve = (resolvePath: string): string => { return path.resolve(process.cwd(), resolvePath); -} +}; -export const webpackOutputOptions: WebpackProgressPluginOutputOptions = { +export const webpackOutputOptions = { colors: true, chunks: true, modules: false, reasons: false, chunkModules: false -} +}; export const webpackDevServerOutputOptions = { assets: true, @@ -20,4 +20,4 @@ export const webpackDevServerOutputOptions = { timings: true, chunks: false, chunkModules: false -} +}; diff --git a/addon/ng2/models/webpack-config.ts b/addon/ng2/models/webpack-config.ts index c0768d6f4d00..2da873f98df5 100644 --- a/addon/ng2/models/webpack-config.ts +++ b/addon/ng2/models/webpack-config.ts @@ -12,27 +12,31 @@ export class NgCliWebpackConfig { // TODO: When webpack2 types are finished lets replace all these any types // so this is more maintainable in the future for devs public config: any; - private webpackDevConfigPartial: any; - private webpackProdConfigPartial: any; - private webpackBaseConfig: any; - private webpackMobileConfigPartial: any; - private webpackMobileProdConfigPartial: any; + private devConfigPartial: any; + private prodConfigPartial: any; + private baseConfig: any; - constructor(public ngCliProject: any, public target: string, public environment: string, outputDir?: string) { + constructor( + public ngCliProject: any, + public target: string, + public environment: string, + outputDir?: string + ) { const config: CliConfig = CliConfig.fromProject(); const appConfig = config.config.apps[0]; appConfig.outDir = outputDir || appConfig.outDir; - this.webpackBaseConfig = getWebpackCommonConfig(this.ngCliProject.root, environment, appConfig); - this.webpackDevConfigPartial = getWebpackDevConfigPartial(this.ngCliProject.root, appConfig); - this.webpackProdConfigPartial = getWebpackProdConfigPartial(this.ngCliProject.root, appConfig); + this.baseConfig = getWebpackCommonConfig(this.ngCliProject.root, environment, appConfig); + this.devConfigPartial = getWebpackDevConfigPartial(this.ngCliProject.root, appConfig); + this.prodConfigPartial = getWebpackProdConfigPartial(this.ngCliProject.root, appConfig); - if (appConfig.mobile){ - this.webpackMobileConfigPartial = getWebpackMobileConfigPartial(this.ngCliProject.root, appConfig); - this.webpackMobileProdConfigPartial = getWebpackMobileProdConfigPartial(this.ngCliProject.root, appConfig); - this.webpackBaseConfig = webpackMerge(this.webpackBaseConfig, this.webpackMobileConfigPartial); - this.webpackProdConfigPartial = webpackMerge(this.webpackProdConfigPartial, this.webpackMobileProdConfigPartial); + if (appConfig.mobile) { + let mobileConfigPartial = getWebpackMobileConfigPartial(this.ngCliProject.root, appConfig); + let mobileProdConfigPartial = getWebpackMobileProdConfigPartial(this.ngCliProject.root, + appConfig); + this.baseConfig = webpackMerge(this.baseConfig, mobileConfigPartial); + this.prodConfigPartial = webpackMerge(this.prodConfigPartial, mobileProdConfigPartial); } this.generateConfig(); @@ -40,15 +44,14 @@ export class NgCliWebpackConfig { generateConfig(): void { switch (this.target) { - case "development": - this.config = webpackMerge(this.webpackBaseConfig, this.webpackDevConfigPartial); + case 'development': + this.config = webpackMerge(this.baseConfig, this.devConfigPartial); break; - case "production": - this.config = webpackMerge(this.webpackBaseConfig, this.webpackProdConfigPartial); + case 'production': + this.config = webpackMerge(this.baseConfig, this.prodConfigPartial); break; default: throw new Error("Invalid build target. Only 'development' and 'production' are available."); - break; } } } diff --git a/addon/ng2/tasks/build-webpack-watch.ts b/addon/ng2/tasks/build-webpack-watch.ts index 911b6f3b0936..af350d17e0ba 100644 --- a/addon/ng2/tasks/build-webpack-watch.ts +++ b/addon/ng2/tasks/build-webpack-watch.ts @@ -16,7 +16,12 @@ module.exports = Task.extend({ rimraf.sync(path.resolve(project.root, runTaskOptions.outputPath)); - const config = new NgCliWebpackConfig(project, runTaskOptions.target, runTaskOptions.environment, runTaskOptions.outputPath).config; + const config = new NgCliWebpackConfig( + project, + runTaskOptions.target, + runTaskOptions.environment, + runTaskOptions.outputPath + ).config; const webpackCompiler = webpack(config); webpackCompiler.apply(new ProgressPlugin({ @@ -28,15 +33,15 @@ module.exports = Task.extend({ if (err) { lastHash = null; console.error(err.stack || err); - if(err.details) console.error(err.details); + if (err.details) { console.error(err.details); } reject(err.details); } - if(stats.hash !== lastHash) { + if (stats.hash !== lastHash) { lastHash = stats.hash; - process.stdout.write(stats.toString(webpackOutputOptions) + "\n"); + process.stdout.write(stats.toString(webpackOutputOptions) + '\n'); } - }) - }) + }); + }); } }); diff --git a/addon/ng2/tasks/build-webpack.ts b/addon/ng2/tasks/build-webpack.ts index fe0ec60fe59f..e0a3316a5cd2 100644 --- a/addon/ng2/tasks/build-webpack.ts +++ b/addon/ng2/tasks/build-webpack.ts @@ -13,11 +13,16 @@ module.exports = Task.extend({ // Options: String outputPath run: function(runTaskOptions: ServeTaskOptions) { - var project = this.cliProject; + const project = this.cliProject; rimraf.sync(path.resolve(project.root, runTaskOptions.outputPath)); - var config = new NgCliWebpackConfig(project, runTaskOptions.target, runTaskOptions.environment, runTaskOptions.outputPath).config; - + const config = new NgCliWebpackConfig( + project, + runTaskOptions.target, + runTaskOptions.environment, + runTaskOptions.outputPath + ).config; + const webpackCompiler = webpack(config); const ProgressPlugin = require('webpack/lib/ProgressPlugin'); @@ -32,16 +37,16 @@ module.exports = Task.extend({ // TODO: Make conditional if using --watch webpackCompiler.purgeInputFileSystem(); - if(err) { + if (err) { lastHash = null; console.error(err.stack || err); - if(err.details) console.error(err.details); + if (err.details) { console.error(err.details); } reject(err.details); } - if(stats.hash !== lastHash) { + if (stats.hash !== lastHash) { lastHash = stats.hash; - process.stdout.write(stats.toString(webpackOutputOptions) + "\n"); + process.stdout.write(stats.toString(webpackOutputOptions) + '\n'); } resolve(); }); diff --git a/addon/ng2/tasks/create-github-repo.ts b/addon/ng2/tasks/create-github-repo.ts index 046c65694e88..a899f934ca9e 100644 --- a/addon/ng2/tasks/create-github-repo.ts +++ b/addon/ng2/tasks/create-github-repo.ts @@ -3,10 +3,11 @@ import * as Task from 'ember-cli/lib/models/task'; import * as SilentError from 'silent-error'; import { exec } from 'child_process'; import * as https from 'https'; +import { oneLine } from 'common-tags'; module.exports = Task.extend({ run: function(commandOptions) { - var ui = this.ui; + const ui = this.ui; let promise; // declared here so that tests can stub exec @@ -18,16 +19,24 @@ module.exports = Task.extend({ ghUsername: commandOptions.ghUsername }); } else { - ui.writeLine("\nIn order to deploy this project via GitHub Pages, we must first create a repository for it."); - ui.writeLine("It's safer to use a token than to use a password, so you will need to create one.\n"); - ui.writeLine("Go to the following page and click 'Generate new token'."); - ui.writeLine("https://github.com/settings/tokens\n"); - ui.writeLine("Choose 'public_repo' as scope and then click 'Generate token'.\n"); + ui.writeLine(); + ui.writeLine(oneLine` + In order to deploy this project via GitHub Pages, we must first create a repository for it. + `); + ui.writeLine(oneLine` + It\'s safer to use a token than to use a password so you will need to create one + `); + ui.writeLine('Go to the following page and click "Generate new token".'); + ui.writeLine('https://github.com/settings/tokens\n'); + ui.writeLine('Choose "public_repo" as scope and then click "Generate token".\n'); promise = ui.prompt([ { name: 'ghToken', type: 'input', - message: 'Please enter GitHub token you just created (used only once to create the repo):', + message: oneLine` + Please enter GitHub token you just created + (used only once to create the repo): + `, validate: function(token) { return /.+/.test(token); } @@ -44,11 +53,11 @@ module.exports = Task.extend({ return promise .then((answers) => { return new Promise(function(resolve, reject) { - var postData = JSON.stringify({ + const postData = JSON.stringify({ 'name': commandOptions.projectName }); - var req = https.request({ + const req = https.request({ hostname: 'api.github.com', port: 443, path: '/user/repos', @@ -63,9 +72,14 @@ module.exports = Task.extend({ req.on('response', function(response) { if (response.statusCode === 201) { - resolve(execPromise(`git remote add origin git@github.com:${answers.ghUsername}/${commandOptions.projectName}.git`)) + resolve(execPromise(oneLine` + git remote add origin + git@github.com:${answers.ghUsername}/${commandOptions.projectName}.git + `)); } else { - reject(new SilentError(`Failed to create GitHub repo. Error: ${response.statusCode} ${response.statusMessage}`)); + reject(new SilentError(oneLine` + Failed to create GitHub repo. Error: ${response.statusCode} ${response.statusMessage} + `)); } }); diff --git a/addon/ng2/tasks/doc.ts b/addon/ng2/tasks/doc.ts index 54161d47ebb6..687014def974 100644 --- a/addon/ng2/tasks/doc.ts +++ b/addon/ng2/tasks/doc.ts @@ -3,9 +3,9 @@ import * as opn from 'opn'; const DocTask = Task.extend({ run: function(keyword: string) { - var searchUrl = `https://angular.io/docs/ts/latest/api/#!?apiFilter=${keyword}`; + const searchUrl = `https://angular.io/docs/ts/latest/api/#!?apiFilter=${keyword}`; return opn(searchUrl, { wait: false }); } }); -module.exports = DocTask; \ No newline at end of file +module.exports = DocTask; diff --git a/addon/ng2/tasks/e2e.ts b/addon/ng2/tasks/e2e.ts index fcf0b850e501..2ecc8420e0f3 100644 --- a/addon/ng2/tasks/e2e.ts +++ b/addon/ng2/tasks/e2e.ts @@ -5,21 +5,22 @@ import {exec} from 'child_process'; module.exports = Task.extend({ run: function () { - var ui = this.ui; - var exitCode = 0; + const ui = this.ui; + let exitCode = 0; return new Promise((resolve) => { - exec(`npm run e2e -- ${this.project.ngConfig.config.e2e.protractor.config}`, (err, stdout, stderr) => { - ui.writeLine(stdout); - if (err) { - ui.writeLine(stderr); - ui.writeLine(chalk.red('Some end-to-end tests failed, see above.')); - exitCode = err.code; - } else { - ui.writeLine(chalk.green('All end-to-end tests pass.')); - } - resolve(exitCode); - }); + exec(`npm run e2e -- ${this.project.ngConfig.config.e2e.protractor.config}`, + (err, stdout, stderr) => { + ui.writeLine(stdout); + if (err) { + ui.writeLine(stderr); + ui.writeLine(chalk.red('Some end-to-end tests failed, see above.')); + exitCode = err.code; + } else { + ui.writeLine(chalk.green('All end-to-end tests pass.')); + } + resolve(exitCode); + }); }); } }); diff --git a/addon/ng2/tasks/link-cli.ts b/addon/ng2/tasks/link-cli.ts index 181993cac6b1..a1b29c5407c6 100644 --- a/addon/ng2/tasks/link-cli.ts +++ b/addon/ng2/tasks/link-cli.ts @@ -5,7 +5,7 @@ import {exec} from 'child_process'; module.exports = Task.extend({ run: function() { - var ui = this.ui; + const ui = this.ui; return new Promise(function(resolve, reject) { exec('npm link angular-cli', (err) => { diff --git a/addon/ng2/tasks/lint.ts b/addon/ng2/tasks/lint.ts index d407dc68df3c..46ff93b5ed71 100644 --- a/addon/ng2/tasks/lint.ts +++ b/addon/ng2/tasks/lint.ts @@ -5,7 +5,7 @@ import {exec} from 'child_process'; module.exports = Task.extend({ run: function () { - var ui = this.ui; + const ui = this.ui; return new Promise(function(resolve, reject) { exec('npm run lint', (err, stdout) => { diff --git a/addon/ng2/tasks/serve-webpack.ts b/addon/ng2/tasks/serve-webpack.ts index 8fe322e1a319..5862f64c2fc1 100644 --- a/addon/ng2/tasks/serve-webpack.ts +++ b/addon/ng2/tasks/serve-webpack.ts @@ -10,18 +10,24 @@ import { webpackDevServerOutputOptions } from '../models/'; import { NgCliWebpackConfig } from '../models/webpack-config'; import { ServeTaskOptions } from '../commands/serve'; import { CliConfig } from '../models/config'; +import { oneLine } from 'common-tags'; module.exports = Task.extend({ run: function(commandOptions: ServeTaskOptions) { + const ui = this.ui; - let lastHash = null; let webpackCompiler: any; - var config = new NgCliWebpackConfig(this.project, commandOptions.target, commandOptions.environment).config; + let config = new NgCliWebpackConfig( + this.project, commandOptions.target, + commandOptions.environment + ).config; // This allows for live reload of page when changes are made to repo. // https://webpack.github.io/docs/webpack-dev-server.html#inline-mode - config.entry.main.unshift(`webpack-dev-server/client?http://${commandOptions.host}:${commandOptions.port}/`); + config.entry.main.unshift( + `webpack-dev-server/client?http://${commandOptions.host}:${commandOptions.port}/` + ); webpackCompiler = webpack(config); webpackCompiler.apply(new ProgressPlugin({ @@ -35,39 +41,39 @@ module.exports = Task.extend({ if (fs.existsSync(proxyPath)) { proxyConfig = require(proxyPath); } else { - var message = 'Proxy config file ' + proxyPath + ' does not exist.'; - return Promise.reject(new SilentError(message)); + const message = 'Proxy config file ' + proxyPath + ' does not exist.'; + return Promise.reject(new SilentError(message)); } } const webpackDevServerConfiguration: IWebpackDevServerConfigurationOptions = { - contentBase: path.resolve(this.project.root, `./${CliConfig.fromProject().config.apps[0].root}`), + contentBase: path.resolve( + this.project.root, + `./${CliConfig.fromProject().config.apps[0].root}` + ), historyApiFallback: true, stats: webpackDevServerOutputOptions, inline: true, proxy: proxyConfig }; - const serveMessage:string = chalk.green(`\n*\n*\n NG Live Development Server is running on http://${commandOptions.host}:${commandOptions.port}.\n*\n*`); - const server = new WebpackDevServer(webpackCompiler, webpackDevServerConfiguration); + ui.writeLine(chalk.green(oneLine` + ** + NG Live Development Server is running on + http://${commandOptions.host}:${commandOptions.port}. + ** + `)); + const server = new WebpackDevServer(webpackCompiler, webpackDevServerConfiguration); return new Promise((resolve, reject) => { server.listen(commandOptions.port, `${commandOptions.host}`, function(err, stats) { - if(err) { - lastHash = null; + if (err) { console.error(err.stack || err); - if(err.details) console.error(err.details); - reject(err.details); + if (err.details) { console.error(err.details); } + reject(err.details); } - - if(stats && stats.hash && stats.hash !== lastHash) { - lastHash = stats.hash; - process.stdout.write(stats.toString(webpackOutputOptions) + '\n' + serveMessage + '\n'); - } - - process.stdout.write(serveMessage); }); - }) + }); } }); diff --git a/addon/ng2/tasks/test.ts b/addon/ng2/tasks/test.ts index 30802e0ea944..83076bd3dcae 100644 --- a/addon/ng2/tasks/test.ts +++ b/addon/ng2/tasks/test.ts @@ -1,7 +1,6 @@ import * as Promise from 'ember-cli/lib/ext/promise'; import * as Task from 'ember-cli/lib/models/task'; import * as path from 'path'; -import { getWebpackTestConfig } from '../models/webpack-build-test'; // require dependencies within the target project function requireDependency(root, moduleName) { @@ -10,7 +9,7 @@ function requireDependency(root, moduleName) { return require(path.join(root, 'node_modules', moduleName, main)); } -module.exports = Task.extend({ +module.exports = Task.extend({ run: function (options) { const projectRoot = this.project.root; return new Promise((resolve) => { diff --git a/addon/ng2/tsconfig.json b/addon/ng2/tsconfig.json index 37f40a514ae4..5ec19d74563c 100644 --- a/addon/ng2/tsconfig.json +++ b/addon/ng2/tsconfig.json @@ -14,6 +14,9 @@ "sourceRoot": "/", "target": "es5", "lib": ["es6"], + "typeRoots": [ + "../../node_modules/@types" + ], "paths": { "@angular-cli/ast-tools": [ "../../packages/ast-tools/src" ] } diff --git a/addon/ng2/utilities/prerender-webpack-plugin.ts b/addon/ng2/utilities/prerender-webpack-plugin.ts index 1ce3c042aff9..0b3f77b5f9d8 100644 --- a/addon/ng2/utilities/prerender-webpack-plugin.ts +++ b/addon/ng2/utilities/prerender-webpack-plugin.ts @@ -10,7 +10,7 @@ interface IWebpackPrerender { export class PrerenderWebpackPlugin { private bootloader: any; - private cachedTemplate: string + private cachedTemplate: string; constructor(private options: IWebpackPrerender) { // maintain your platform instance @@ -53,4 +53,4 @@ export class PrerenderWebpackPlugin { delete require.cache[key]; }); } -} \ No newline at end of file +}; diff --git a/package.json b/package.json index 58105b89bdbb..28023568c604 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,10 @@ "test:cli": "node tests/runner", "test:inspect": "node --inspect --debug-brk tests/runner", "test:packages": "node scripts/run-packages-spec.js", - "lint": "eslint .", - "build-config-interface": "dtsgen lib/config/schema.json --out lib/config/schema.d.ts" + "build-config-interface": "dtsgen lib/config/schema.json --out lib/config/schema.d.ts", + "eslint": "eslint .", + "tslint": "tslint \"**/*.ts\" -c tslint.json -e \"**/blueprints/*/files/**/*.ts\" -e \"node_modules/**\" -e \"tmp/**\"", + "lint": "npm-run-all -c eslint tslint" }, "repository": { "type": "git", @@ -41,6 +43,7 @@ "angular2-template-loader": "^0.5.0", "awesome-typescript-loader": "^2.2.1", "chalk": "^1.1.3", + "common-tags": "^1.3.1", "compression-webpack-plugin": "^0.3.1", "copy-webpack-plugin": "^3.0.1", "core-js": "^2.4.0", @@ -66,6 +69,7 @@ "lodash": "^4.11.1", "node-sass": "^3.7.0", "npm": "3.10.2", + "npm-run-all": "^3.0.0", "offline-plugin": "^3.4.1", "opn": "4.0.1", "parse5": "^2.1.5", diff --git a/packages/ast-tools/src/ast-utils.ts b/packages/ast-tools/src/ast-utils.ts index 89e022fb85c2..c95ec2dae6cc 100644 --- a/packages/ast-tools/src/ast-utils.ts +++ b/packages/ast-tools/src/ast-utils.ts @@ -42,7 +42,7 @@ export function getSourceNodes(sourceFile: ts.SourceFile): Observable { const subject = new ReplaySubject(); let nodes: ts.Node[] = [sourceFile]; - while(nodes.length > 0) { + while (nodes.length > 0) { const node = nodes.shift(); if (node) { @@ -82,7 +82,7 @@ function nodesByPosition(first: ts.Node, second: ts.Node): number { */ export function insertAfterLastOccurrence(nodes: ts.Node[], toInsert: string, file: string, fallbackPos?: number, syntaxKind?: ts.SyntaxKind): Change { - var lastItem = nodes.sort(nodesByPosition).pop(); + let lastItem = nodes.sort(nodesByPosition).pop(); if (syntaxKind) { lastItem = findNodes(lastItem, syntaxKind).sort(nodesByPosition).pop(); } @@ -99,7 +99,7 @@ export function getContentOfKeyLiteral(source: ts.SourceFile, node: ts.Node): st return (node).text; } else if (node.kind == ts.SyntaxKind.StringLiteral) { try { - return JSON.parse(node.getFullText(source)) + return JSON.parse(node.getFullText(source)); } catch (e) { return null; } diff --git a/packages/ast-tools/src/change.ts b/packages/ast-tools/src/change.ts index 174c0839cf15..dde0bc5523a4 100644 --- a/packages/ast-tools/src/change.ts +++ b/packages/ast-tools/src/change.ts @@ -65,7 +65,7 @@ export class MultiChange implements Change { return this._changes .sort((a: Change, b: Change) => b.order - a.order) .reduce((promise, change) => { - return promise.then(() => change.apply()) + return promise.then(() => change.apply()); }, Promise.resolve()); } } diff --git a/packages/ast-tools/src/route-utils.spec.ts b/packages/ast-tools/src/route-utils.spec.ts index c22a48fad995..c9d83b87ef21 100644 --- a/packages/ast-tools/src/route-utils.spec.ts +++ b/packages/ast-tools/src/route-utils.spec.ts @@ -168,7 +168,9 @@ describe('route utils', () => { }); }); it('does not add provideRouter to bootstrap if present', () => { - let editedFile = new InsertChange(mainFile, 124, ', [ HTTP_PROVIDERS, provideRouter(routes) ]'); + let editedFile = new InsertChange(mainFile, + 124, + ', [ HTTP_PROVIDERS, provideRouter(routes) ]'); return editedFile.apply() .then(() => nru.applyChanges(nru.bootstrapItem(mainFile, routes, toBootstrap))) .then(() => readFile(mainFile, 'utf8')) @@ -203,14 +205,14 @@ describe('route utils', () => { .then(() => readFile(mainFile, 'utf8')) .then(content => { expect(content).toEqual(prefix + routerImport + - 'bootstrap(AppComponent, [ provideRouter(routes) ]);\n if(e){bootstrap, provideRouter});'); + 'bootstrap(AppComponent, [ provideRouter(routes) ]);\n if(e){bootstrap, provideRouter});'); // tslint:disable-line }); }); }); describe('addPathToRoutes', () => { const routesFile = 'src/routes.ts'; - var options = {dir: 'src/app', appRoot: 'src/app', routesFile: routesFile, + let options = {dir: 'src/app', appRoot: 'src/app', routesFile: routesFile, component: 'NewRouteComponent', dasherizedName: 'new-route'}; const nestedRoutes = `\n { path: 'home', component: HomeComponent, children: [ @@ -235,7 +237,8 @@ describe('route utils', () => { }); it('adds import to new route component if absent', () => { - return nru.applyChanges(nru.addPathToRoutes(routesFile, _.merge({route: 'new-route'}, options))) + return nru.applyChanges(nru.addPathToRoutes(routesFile, + _.merge({route: 'new-route'}, options))) .then(() => readFile(routesFile, 'utf8')) .then(content => { expect(content).toEqual( @@ -289,6 +292,7 @@ export default [\n { path: 'new-route', component: NewRouteComponent }\n];`); nru.addPathToRoutes(routesFile, _.merge({route: 'home/about/details'}, options))); }) .then(() => readFile(routesFile, 'utf8')) .then(content => { + // tslint:disable-next-line let expected = `import { DetailsComponent } from './app/home/about/details/details.component'; export default [ { path: 'home', component: HomeComponent, @@ -310,9 +314,11 @@ export default [ options.dasherizedName = 'sections'; options.component = 'SectionsComponent'; return nru.applyChanges( - nru.addPathToRoutes(routesFile, _.merge({route: 'home/about/more/sections'}, options))); }) + nru.addPathToRoutes(routesFile, + _.merge({route: 'home/about/more/sections'}, options))); }) .then(() => readFile(routesFile, 'utf8')) .then(content => { + // tslint:disable-next-line let expected = `import { SectionsComponent } from './app/home/about/more/sections/sections.component'; export default [ { path: 'home', component: HomeComponent, @@ -347,6 +353,7 @@ export default [ nru.addPathToRoutes(routesFile, _.merge({route: 'home/about/:id'}, options))); }) .then(() => readFile(routesFile, 'utf8')) .then(content => { + // tslint:disable-next-line expect(content).toEqual(`import { AboutComponent_1 } from './app/home/about/about.component'; export default [ { path: 'main', component: MainComponent } @@ -435,6 +442,7 @@ export default [ }) .then(() => readFile(routesFile, 'utf8')) .then(content => { + // tslint:disable-next-line let expected = `import { TrapQueenComponent } from './app/home/trap-queen/trap-queen.component'; export default [ { path: 'home', component: HomeComponent, @@ -489,7 +497,7 @@ export default [ let editedFile = new InsertChange(routesFile, 0, `import { AboutComponent } from './app/about/about.component'; import { DetailsComponent } from './app/about/details/details.component'; -import { DetailsComponent as DetailsComponent_1 } from './app/about/description/details.component;\n`); +import { DetailsComponent as DetailsComponent_1 } from './app/about/description/details.component;\n`); // tslint:disable-line return editedFile.apply(); }).then(() => { options.dasherizedName = 'details'; diff --git a/packages/ast-tools/src/route-utils.ts b/packages/ast-tools/src/route-utils.ts index bc2c86fe5154..8fd750bf5e30 100644 --- a/packages/ast-tools/src/route-utils.ts +++ b/packages/ast-tools/src/route-utils.ts @@ -12,9 +12,13 @@ import {insertAfterLastOccurrence} from './ast-utils'; * @param imports Object { importedClass: ['path/to/import/from', defaultStyleImport?] } * @param toBootstrap */ -export function bootstrapItem(mainFile: string, imports: {[key: string]: (string | boolean)[]}, toBootstrap: string ) { +export function bootstrapItem( + mainFile: string, + imports: {[key: string]: (string | boolean)[]}, + toBootstrap: string +) { let changes = Object.keys(imports).map(importedClass => { - var defaultStyleImport = imports[importedClass].length === 2 && !!imports[importedClass][1]; + let defaultStyleImport = imports[importedClass].length === 2 && !!imports[importedClass][1]; return insertImport( mainFile, importedClass, @@ -43,8 +47,8 @@ export function bootstrapItem(mainFile: string, imports: {[key: string]: (string } // if bracket exitst already, add configuration template, // otherwise, insert into bootstrap parens - var fallBackPos: number, configurePathsTemplate: string, separator: string; - var syntaxListNodes: any; + let fallBackPos: number, configurePathsTemplate: string, separator: string; + let syntaxListNodes: any; let bootstrapProviders = bootstrapNode.getChildAt(2).getChildAt(2); // array of providers if ( bootstrapProviders ) { @@ -88,7 +92,7 @@ export function insertImport(fileToEdit: string, symbolName: string, if (relevantImports.length > 0) { - var importsAsterisk = false; + let importsAsterisk = false; // imports from import file let imports: ts.Node[] = []; relevantImports.forEach(n => { @@ -128,7 +132,13 @@ export function insertImport(fileToEdit: string, symbolName: string, let separator = insertAtBeginning ? '' : ';\n'; let toInsert = `${separator}import ${open}${symbolName}${close}` + ` from '${fileName}'${insertAtBeginning ? ';\n' : ''}`; - return insertAfterLastOccurrence(allImports, toInsert, fileToEdit, fallbackPos, ts.SyntaxKind.StringLiteral); + return insertAfterLastOccurrence( + allImports, + toInsert, + fileToEdit, + fallbackPos, + ts.SyntaxKind.StringLiteral + ); }; /** @@ -149,9 +159,13 @@ export function addPathToRoutes(routesFile: string, pathOptions: any): Change[] let routePath = route.replace(positionalRoutes, ''); routePath = `./app/${routePath}/${pathOptions.dasherizedName}.component`; let originalComponent = pathOptions.component; - pathOptions.component = resolveImportName(pathOptions.component, routePath, pathOptions.routesFile); + pathOptions.component = resolveImportName( + pathOptions.component, + routePath, + pathOptions.routesFile + ); - var content = `{ path: '${route}', component: ${pathOptions.component}${isDefault}${outlet} }`; + let content = `{ path: '${route}', component: ${pathOptions.component}${isDefault}${outlet} }`; let rootNode = getRootNode(routesFile); let routesNode = rootNode.getChildAt(0).getChildren().filter(n => { // get export statement @@ -162,7 +176,7 @@ export function addPathToRoutes(routesFile: string, pathOptions: any): Change[] throw new Error('Did not insert path in routes.ts because ' + `there were multiple or no 'export default' statements`); } - var pos = routesNode[0].getChildAt(2).getChildAt(0).end; // openBracketLiteral + let pos = routesNode[0].getChildAt(2).getChildAt(0).end; // openBracketLiteral // all routes in export route array let routesArray = routesNode[0].getChildAt(2).getChildAt(1) .getChildren() @@ -172,14 +186,16 @@ export function addPathToRoutes(routesFile: string, pathOptions: any): Change[] // don't duplicate routes throw new Error('Route was not added since it is a duplicate'); } - var isChild = false; + let isChild = false; // get parent to insert under let parent: ts.Node; if (pathOptions.parent) { // append '_' to route to find the actual parent (not parent of the parent) parent = getParent(routesArray, `${pathOptions.parent}/_`); if (!parent) { - throw new Error(`You specified parent '${pathOptions.parent}'' which was not found in routes.ts`); + throw new Error( + `You specified parent '${pathOptions.parent}'' which was not found in routes.ts` + ); } if (route.indexOf(pathOptions.parent) === 0) { route = route.substring(pathOptions.parent.length); @@ -296,8 +312,8 @@ function resolveImportName (importName: string, importPath: string, fileName: st return importName; } const baseName = importNames[index].split('_')[0]; - var newName = baseName; - var resolutionNumber = 1; + let newName = baseName; + let resolutionNumber = 1; while (importNames.indexOf(newName) !== -1) { newName = `${baseName}_${resolutionNumber}`; resolutionNumber++; @@ -328,8 +344,9 @@ export function resolveComponentPath(projectRoot: string, currentDir: string, fi // only component file name is given filePath = componentName; } - var directory = filePath[0] === path.sep ? - path.resolve(path.join(projectRoot, 'src', 'app', filePath)) : path.resolve(currentDir, filePath); + let directory = filePath[0] === path.sep ? + path.resolve(path.join(projectRoot, 'src', 'app', filePath)) : + path.resolve(currentDir, filePath); if (!fs.existsSync(directory)) { throw new Error(`path '${filePath}' must be relative to current directory` + @@ -364,13 +381,14 @@ function addChildPath (parentObject: ts.Node, pathOptions: any, route: string) { if (!parentObject) { return; } - var pos: number; - var newContent: string; + let pos: number; + let newContent: string; // get object with 'children' property let childrenNode = parentObject.getChildAt(1).getChildren() - .filter(n => n.kind === ts.SyntaxKind.PropertyAssignment - && ((n as ts.PropertyAssignment).name as ts.Identifier).text === 'children'); + .filter(n => + n.kind === ts.SyntaxKind.PropertyAssignment + && ((n as ts.PropertyAssignment).name as ts.Identifier).text === 'children'); // find number of spaces to pad nested paths let nestingLevel = 1; // for indenting route object in the `children` array let n = parentObject; @@ -417,7 +435,7 @@ function getParent(routesArray: ts.Node[], route: string, parent?: ts.Node): ts. if (route.length === 0) { return; // route has been completely matched } - var splitRoute = route.split('/'); + let splitRoute = route.split('/'); // don't treat positional parameters separately if (splitRoute.length > 1 && splitRoute[1].indexOf(':') !== -1) { let actualRoute = splitRoute.shift(); @@ -442,13 +460,18 @@ function getParent(routesArray: ts.Node[], route: string, parent?: ts.Node): ts. * Helper for addPathToRoutes. * @return whether path with same route and component exists */ -function pathExists(routesArray: ts.Node[], route: string, component: string, fullRoute?: string): boolean { +function pathExists( + routesArray: ts.Node[], + route: string, + component: string, + fullRoute?: string +): boolean { if (routesArray.length === 0) { return false; } fullRoute = fullRoute ? fullRoute : route; - var sameRoute = false; - var splitRoute = route.split('/'); + let sameRoute = false; + let splitRoute = route.split('/'); // don't treat positional parameters separately if (splitRoute.length > 1 && splitRoute[1].indexOf(':') !== -1) { let actualRoute = splitRoute.shift(); @@ -461,7 +484,7 @@ function pathExists(routesArray: ts.Node[], route: string, component: string, fu sameRoute = currentRoute === splitRoute[0]; // Confirm that it's parents are the same if (sameRoute && sameComponent) { - var path = currentRoute; + let path = currentRoute; let objExp = n.parent; while (objExp) { if (objExp.kind === ts.SyntaxKind.ObjectLiteralExpression) { diff --git a/tests/acceptance/module-resolver.spec.ts b/tests/acceptance/module-resolver.spec.ts index cff22f2a2787..cab4039f9808 100644 --- a/tests/acceptance/module-resolver.spec.ts +++ b/tests/acceptance/module-resolver.spec.ts @@ -130,7 +130,8 @@ describe('ModuleResolver', () => { .then((tsFile: ts.SourceFile) => { let contentsBaz = dependentFilesUtils.getImportClauses(tsFile); let barExpectedContent = path.normalize('../bar/bar.component'); - let fooBarExpectedContent = `.${path.sep}qux${path.sep}quux${path.sep}foobar${path.sep}foobar.component`; + let fooBarExpectedContent = + `.${path.sep}qux${path.sep}quux${path.sep}foobar${path.sep}foobar.component`; expect(contentsBaz[0].specifierText).to.equal(barExpectedContent); expect(contentsBaz[1].specifierText).to.equal(fooBarExpectedContent); }); diff --git a/tslint.json b/tslint.json index f5d2ac212a52..6cb5eba50936 100644 --- a/tslint.json +++ b/tslint.json @@ -18,9 +18,9 @@ "no-internal-module": true, "no-trailing-whitespace": true, "no-bitwise": true, - "no-shadowed-variable": true, "no-unused-expression": true, "no-unused-variable": true, + "no-var-keyword": true, "one-line": [ true, "check-catch", @@ -49,7 +49,8 @@ true, "ban-keywords", "check-format", - "allow-trailing-underscore" + "allow-leading-underscore", + "allow-pascal-case" ], "whitespace": [ true,