diff --git a/.eslintignore b/.eslintignore index a2fb72657257..38e09e42e1ca 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,5 @@ # /node_modules and /bower_components ignored by default +dist/ .git/ tmp/ typings/ diff --git a/addon/ng2/commands/build.ts b/addon/ng2/commands/build.ts index a976372531ff..1072ed950d9e 100644 --- a/addon/ng2/commands/build.ts +++ b/addon/ng2/commands/build.ts @@ -1,6 +1,6 @@ -import * as Command from 'ember-cli/lib/models/command'; -import * as WebpackBuild from '../tasks/build-webpack'; -import * as WebpackBuildWatch from '../tasks/build-webpack-watch'; +const Command = require('ember-cli/lib/models/command'); +import WebpackBuild from '../tasks/build-webpack'; +import WebpackBuildWatch from '../tasks/build-webpack-watch'; export interface BuildOptions { target?: string; @@ -12,7 +12,7 @@ export interface BuildOptions { baseHref?: string; } -module.exports = Command.extend({ +const BuildCommand = Command.extend({ name: 'build', description: 'Builds your app and places it into the output path (dist/ by default).', aliases: ['b'], @@ -64,4 +64,6 @@ module.exports = Command.extend({ } }); -module.exports.overrideCore = true; + +BuildCommand.overrideCore = true; +export default BuildCommand; diff --git a/addon/ng2/commands/doc.ts b/addon/ng2/commands/doc.ts index 040be66ee15f..f69ecec5b748 100644 --- a/addon/ng2/commands/doc.ts +++ b/addon/ng2/commands/doc.ts @@ -1,5 +1,5 @@ -import * as Command from 'ember-cli/lib/models/command'; -import * as DocTask from '../tasks/doc'; +const Command = require('ember-cli/lib/models/command'); +import { DocTask } from '../tasks/doc'; const DocCommand = Command.extend({ name: 'doc', @@ -10,7 +10,7 @@ const DocCommand = Command.extend({ '' ], - run: function(commandOptions, rawArgs: Array) { + run: function(commandOptions: any, rawArgs: Array) { const keyword = rawArgs[0]; const docTask = new DocTask({ @@ -23,4 +23,4 @@ const DocCommand = Command.extend({ } }); -module.exports = DocCommand; +export default DocCommand; diff --git a/addon/ng2/commands/e2e.ts b/addon/ng2/commands/e2e.ts index b4facd11c444..0f423e159c24 100644 --- a/addon/ng2/commands/e2e.ts +++ b/addon/ng2/commands/e2e.ts @@ -1,15 +1,15 @@ -import * as Command from 'ember-cli/lib/models/command'; -import * as E2ETask from '../tasks/e2e'; +const Command = require('ember-cli/lib/models/command'); +import {E2eTask} from '../tasks/e2e'; import {CliConfig} from '../models/config'; -module.exports = Command.extend({ +const E2eCommand = Command.extend({ name: 'e2e', description: 'Run e2e tests in existing project', works: 'insideProject', run: function () { this.project.ngConfig = this.project.ngConfig || CliConfig.fromProject(); - const e2eTask = new E2ETask({ + const e2eTask = new E2eTask({ ui: this.ui, analytics: this.analytics, project: this.project @@ -18,3 +18,6 @@ module.exports = Command.extend({ return e2eTask.run(); } }); + + +export default E2eCommand; diff --git a/addon/ng2/commands/easter-egg.ts b/addon/ng2/commands/easter-egg.ts index 48079e668c34..59c1522f0e63 100644 --- a/addon/ng2/commands/easter-egg.ts +++ b/addon/ng2/commands/easter-egg.ts @@ -1,6 +1,5 @@ -import * as Command from 'ember-cli/lib/models/command'; -import * as Promise from 'ember-cli/lib/ext/promise'; -import * as stringUtils from 'ember-cli-string-utils'; +const Command = require('ember-cli/lib/models/command'); +const stringUtils = require('ember-cli-string-utils'); import * as chalk from 'chalk'; @@ -9,13 +8,13 @@ function pickOne(of: string[]): string { } -module.exports = function(name) { +export default function(name: string) { return Command.extend({ name: name, works: 'insideProject', - run: function (commandOptions, rawArgs): Promise { - this[stringUtils.camelize(this.name)](commandOptions, rawArgs); + run: function (commandOptions: any, rawArgs: string[]): Promise { + (this as any)[stringUtils.camelize(this.name)](commandOptions, rawArgs); return Promise.resolve(); }, diff --git a/addon/ng2/commands/generate.ts b/addon/ng2/commands/generate.ts index bc3dda446b64..789c15a89e9a 100644 --- a/addon/ng2/commands/generate.ts +++ b/addon/ng2/commands/generate.ts @@ -1,15 +1,17 @@ -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'; -import * as Blueprint from 'ember-cli/lib/models/blueprint'; +import * as os from 'os'; + const chalk = require('chalk'); -const EOL = require('os').EOL; +const EmberGenerateCommand = require('ember-cli/lib/commands/generate'); +const Blueprint = require('ember-cli/lib/models/blueprint'); +const SilentError = require('silent-error'); + const GenerateCommand = EmberGenerateCommand.extend({ name: 'generate', - beforeRun: function(rawArgs) { + beforeRun: function(rawArgs: string[]) { if (!rawArgs.length) { return; } @@ -23,7 +25,7 @@ const GenerateCommand = EmberGenerateCommand.extend({ } // Override default help to hide ember blueprints - EmberGenerateCommand.prototype.printDetailedHelp = function (options) { + EmberGenerateCommand.prototype.printDetailedHelp = function() { const blueprintList = fs.readdirSync(path.join(__dirname, '..', 'blueprints')); const blueprints = blueprintList .filter(bp => bp.indexOf('-test') === -1) @@ -33,7 +35,7 @@ const GenerateCommand = EmberGenerateCommand.extend({ let output = ''; blueprints .forEach(function (bp) { - output += bp.printBasicHelp(false) + EOL; + output += bp.printBasicHelp(false) + os.EOL; }); this.ui.writeLine(chalk.cyan(' Available blueprints')); this.ui.writeLine(output); @@ -43,12 +45,12 @@ const GenerateCommand = EmberGenerateCommand.extend({ } }); -function mapBlueprintName(name) { - let mappedName = aliasMap[name]; +function mapBlueprintName(name: string): string { + let mappedName: string = aliasMap[name]; return mappedName ? mappedName : name; } -const aliasMap = { +const aliasMap: { [alias: string]: string } = { 'cl': 'class', 'c': 'component', 'd': 'directive', @@ -59,5 +61,5 @@ const aliasMap = { 's': 'service' }; -module.exports = GenerateCommand; -module.exports.overrideCore = true; +export default GenerateCommand; +GenerateCommand.overrideCore = true; diff --git a/addon/ng2/commands/get.ts b/addon/ng2/commands/get.ts index 88fcffb7380d..9b605b4d6028 100644 --- a/addon/ng2/commands/get.ts +++ b/addon/ng2/commands/get.ts @@ -1,7 +1,7 @@ import * as chalk from 'chalk'; -import * as Command from 'ember-cli/lib/models/command'; import {CliConfig} from '../models/config'; +const Command = require('ember-cli/lib/models/command'); const GetCommand = Command.extend({ name: 'get', @@ -10,7 +10,7 @@ const GetCommand = Command.extend({ availableOptions: [], - run: function (commandOptions, rawArgs): Promise { + run: function (commandOptions: any, rawArgs: string[]): Promise { return new Promise(resolve => { const config = CliConfig.fromProject(); const value = config.get(rawArgs[0]); @@ -27,4 +27,4 @@ const GetCommand = Command.extend({ } }); -module.exports = GetCommand; +export default GetCommand; diff --git a/addon/ng2/commands/github-pages-deploy.ts b/addon/ng2/commands/github-pages-deploy.ts index c8c3ec400038..631c882b3949 100644 --- a/addon/ng2/commands/github-pages-deploy.ts +++ b/addon/ng2/commands/github-pages-deploy.ts @@ -1,18 +1,19 @@ -import * as Command from 'ember-cli/lib/models/command'; -import * as SilentError from 'silent-error'; +const Command = require('ember-cli/lib/models/command'); +const SilentError = require('silent-error'); +import denodeify = require('denodeify'); + import { exec } from 'child_process'; -import * as Promise from 'ember-cli/lib/ext/promise'; import * as chalk from 'chalk'; import * as fs from 'fs'; import * as fse from 'fs-extra'; import * as path from 'path'; -import * as WebpackBuild from '../tasks/build-webpack'; -import * as CreateGithubRepo from '../tasks/create-github-repo'; +import WebpackBuild from '../tasks/build-webpack'; +import CreateGithubRepo from '../tasks/create-github-repo'; import { CliConfig } from '../models/config'; import { oneLine } from 'common-tags'; -const fsReadDir = Promise.denodeify(fs.readdir); -const fsCopy = Promise.denodeify(fse.copy); +const fsReadDir = denodeify(fs.readdir); +const fsCopy = denodeify(fse.copy); interface GithubPagesDeployOptions { message?: string; @@ -25,7 +26,7 @@ interface GithubPagesDeployOptions { baseHref?: string; } -module.exports = Command.extend({ +const githubPagesDeployCommand = Command.extend({ name: 'github-pages:deploy', aliases: ['gh-pages:deploy'], description: oneLine` @@ -77,7 +78,7 @@ module.exports = Command.extend({ aliases: ['bh'] }], - run: function(options: GithubPagesDeployOptions, rawArgs) { + run: function(options: GithubPagesDeployOptions, rawArgs: string[]) { const ui = this.ui; const root = this.project.root; const execOptions = { @@ -99,10 +100,10 @@ module.exports = Command.extend({ let ghPagesBranch = 'gh-pages'; let destinationBranch = options.userPage ? 'master' : ghPagesBranch; - let initialBranch; + let initialBranch: string; // declared here so that tests can stub exec - const execPromise = Promise.denodeify(exec); + const execPromise = <(cmd: string, options?: any) => Promise>denodeify(exec); const buildTask = new WebpackBuild({ ui: this.ui, @@ -155,7 +156,7 @@ module.exports = Command.extend({ function checkForPendingChanges() { return execPromise('git status --porcelain') - .then(stdout => { + .then((stdout: string) => { if (/\w+/m.test(stdout)) { let msg = 'Uncommitted file changes found! Please commit all changes before deploying.'; return Promise.reject(new SilentError(msg)); @@ -170,7 +171,7 @@ module.exports = Command.extend({ function saveStartingBranchName() { return execPromise('git rev-parse --abbrev-ref HEAD') - .then((stdout) => initialBranch = stdout.replace(/\s/g, '')); + .then((stdout: string) => initialBranch = stdout.replace(/\s/g, '')); } function createGitHubRepoIfNeeded() { @@ -205,7 +206,7 @@ module.exports = Command.extend({ function copyFiles() { return fsReadDir(outDir) - .then((files) => Promise.all(files.map((file) => { + .then((files: string[]) => Promise.all(files.map((file) => { if (file === '.gitignore') { // don't overwrite the .gitignore file return Promise.resolve(); @@ -245,7 +246,7 @@ module.exports = Command.extend({ }); } - function failGracefully(error) { + function failGracefully(error: 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, ' + @@ -258,3 +259,6 @@ module.exports = Command.extend({ } } }); + + +export default githubPagesDeployCommand; diff --git a/addon/ng2/commands/init.js b/addon/ng2/commands/init.ts similarity index 75% rename from addon/ng2/commands/init.js rename to addon/ng2/commands/init.ts index 7c7fff8aa460..a3252a73d984 100644 --- a/addon/ng2/commands/init.js +++ b/addon/ng2/commands/init.ts @@ -1,15 +1,17 @@ 'use strict'; -var Command = require('ember-cli/lib/models/command'); -var Promise = require('ember-cli/lib/ext/promise'); -var SilentError = require('silent-error'); -var validProjectName = require('ember-cli/lib/utilities/valid-project-name'); -var normalizeBlueprint = require('ember-cli/lib/utilities/normalize-blueprint-option'); -var GitInit = require('../tasks/git-init'); -var LinkCli = require('../tasks/link-cli'); -var NpmInstall = require('../tasks/npm-install'); - -module.exports = Command.extend({ +import LinkCli from '../tasks/link-cli'; + +const Command = require('ember-cli/lib/models/command'); +const Promise = require('ember-cli/lib/ext/promise'); +const SilentError = require('silent-error'); +const validProjectName = require('ember-cli/lib/utilities/valid-project-name'); +const normalizeBlueprint = require('ember-cli/lib/utilities/normalize-blueprint-option'); +const GitInit = require('../tasks/git-init'); +const NpmInstall = require('../tasks/npm-install'); + + +const InitCommand: any = Command.extend({ name: 'init', description: 'Creates a new angular-cli project in the current folder.', aliases: ['i'], @@ -39,13 +41,13 @@ module.exports = Command.extend({ } }, - run: function (commandOptions, rawArgs) { + run: function (commandOptions: any, rawArgs: string[]) { if (commandOptions.dryRun) { commandOptions.skipNpm = true; commandOptions.skipBower = true; } - var installBlueprint = new this.tasks.InstallBlueprint({ + const installBlueprint = new this.tasks.InstallBlueprint({ ui: this.ui, analytics: this.analytics, project: this.project @@ -53,49 +55,53 @@ module.exports = Command.extend({ // needs an explicit check in case it's just 'undefined' // due to passing of options from 'new' and 'addon' + let gitInit; if (commandOptions.skipGit === false) { - var gitInit = new GitInit({ + gitInit = new GitInit({ ui: this.ui, project: this.project }); } + let linkCli; if (commandOptions.linkCli) { - var linkCli = new LinkCli({ + linkCli = new LinkCli({ ui: this.ui, analytics: this.analytics, project: this.project }); } + let npmInstall; if (!commandOptions.skipNpm) { - var npmInstall = new NpmInstall({ + npmInstall = new NpmInstall({ ui: this.ui, analytics: this.analytics, project: this.project }); } + let bowerInstall; if (!commandOptions.skipBower) { - var bowerInstall = new this.tasks.BowerInstall({ + bowerInstall = new this.tasks.BowerInstall({ ui: this.ui, analytics: this.analytics, project: this.project }); } - var project = this.project; - var packageName = commandOptions.name !== '.' && commandOptions.name || project.name(); + const project = this.project; + const packageName = commandOptions.name !== '.' && commandOptions.name || project.name(); if (!packageName) { - var message = 'The `ng ' + this.name + '` command requires a ' + + const message = 'The `ng ' + this.name + '` command requires a ' + 'package.json in current folder with name attribute or a specified name via arguments. ' + 'For more details, use `ng help`.'; return Promise.reject(new SilentError(message)); } - - var blueprintOpts = { + + const blueprintOpts = { dryRun: commandOptions.dryRun, blueprint: commandOptions.blueprint || this._defaultBlueprint(), rawName: packageName, @@ -146,4 +152,5 @@ module.exports = Command.extend({ } }); -module.exports.overrideCore = true; +InitCommand.overrideCore = true; +export default InitCommand; diff --git a/addon/ng2/commands/lint.ts b/addon/ng2/commands/lint.ts index 8e78bab3195a..18e313c251d3 100644 --- a/addon/ng2/commands/lint.ts +++ b/addon/ng2/commands/lint.ts @@ -1,7 +1,7 @@ -import * as Command from 'ember-cli/lib/models/command'; -import * as LintTask from '../tasks/lint'; +const Command = require('ember-cli/lib/models/command'); +import LintTask from '../tasks/lint'; -module.exports = Command.extend({ +export default Command.extend({ name: 'lint', description: 'Lints code in existing project', works: 'insideProject', diff --git a/addon/ng2/commands/new.ts b/addon/ng2/commands/new.ts index d0f0d520908e..0c0d518744c7 100644 --- a/addon/ng2/commands/new.ts +++ b/addon/ng2/commands/new.ts @@ -1,11 +1,11 @@ import * as chalk from 'chalk'; -import * as Command from 'ember-cli/lib/models/command'; -import * as Project from 'ember-cli/lib/models/project'; -import * as SilentError from 'silent-error'; -import * as validProjectName from 'ember-cli/lib/utilities/valid-project-name'; +const Command = require('ember-cli/lib/models/command'); +const Project = require('ember-cli/lib/models/project'); +const SilentError = require('silent-error'); +const validProjectName = require('ember-cli/lib/utilities/valid-project-name'); const normalizeBlueprint = require('ember-cli/lib/utilities/normalize-blueprint-option'); -const InitCommand = require('./init'); +import InitCommand from './init'; const NewCommand = Command.extend({ name: 'new', @@ -27,7 +27,7 @@ const NewCommand = Command.extend({ { name: 'mobile', type: Boolean, default: false } ], - run: function (commandOptions, rawArgs) { + run: function (commandOptions: any, rawArgs: string[]) { const packageName = rawArgs.shift(); if (!packageName) { @@ -84,5 +84,6 @@ const NewCommand = Command.extend({ } }); -module.exports = NewCommand; -module.exports.overrideCore = true; + +NewCommand.overrideCore = true; +export default NewCommand; diff --git a/addon/ng2/commands/serve.ts b/addon/ng2/commands/serve.ts index 668ae49d9803..0567bd9c257a 100644 --- a/addon/ng2/commands/serve.ts +++ b/addon/ng2/commands/serve.ts @@ -1,13 +1,13 @@ import * as assign from 'lodash/assign'; -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 ServeWebpackTask from '../tasks/serve-webpack.ts'; +import * as denodeify from 'denodeify'; +const Command = require('ember-cli/lib/models/command'); +const SilentError = require('silent-error'); +const PortFinder = require('portfinder'); +import ServeWebpackTask from '../tasks/serve-webpack.ts'; PortFinder.basePort = 49152; -const getPort = Promise.denodeify(PortFinder.getPort); +const getPort = denodeify(PortFinder.getPort); const defaultPort = process.env.PORT || 4200; export interface ServeTaskOptions { @@ -28,7 +28,7 @@ export interface ServeTaskOptions { sslCert?: string; } -module.exports = Command.extend({ +const ServeCommand = Command.extend({ name: 'serve', description: 'Builds and serves your app, rebuilding on file changes.', aliases: ['server', 's'], @@ -115,8 +115,7 @@ module.exports = Command.extend({ .then((foundPort: number) => { if (commandOptions.port !== foundPort && commandOptions.port !== 0) { - const message = 'Port ' + commandOptions.port + ' is already in use.'; - return Promise.reject(new SilentError(message)); + throw new SilentError(`Port ${commandOptions.port} is already in use.`); } // otherwise, our found port is good @@ -149,4 +148,5 @@ module.exports = Command.extend({ } }); -module.exports.overrideCore = true; +ServeCommand.overrideCore = true; +export default ServeCommand; diff --git a/addon/ng2/commands/set.ts b/addon/ng2/commands/set.ts index b45e60fa5eee..a1c2733cca03 100644 --- a/addon/ng2/commands/set.ts +++ b/addon/ng2/commands/set.ts @@ -1,5 +1,5 @@ -import * as SilentError from 'silent-error'; -import * as Command from 'ember-cli/lib/models/command'; +const SilentError = require('silent-error'); +const Command = require('ember-cli/lib/models/command'); import {CliConfig} from '../models/config'; @@ -28,7 +28,7 @@ const SetCommand = Command.extend({ return +raw; }, - run: function (commandOptions, rawArgs): Promise { + run: function (commandOptions: any, rawArgs: string[]): Promise { return new Promise(resolve => { const [jsonPath, rawValue] = rawArgs; const config = CliConfig.fromProject(); @@ -50,4 +50,4 @@ const SetCommand = Command.extend({ } }); -module.exports = SetCommand; +export default SetCommand; diff --git a/addon/ng2/commands/test.ts b/addon/ng2/commands/test.ts index 73db61af844b..74049b943c1c 100644 --- a/addon/ng2/commands/test.ts +++ b/addon/ng2/commands/test.ts @@ -1,8 +1,8 @@ -import * as TestCommand from 'ember-cli/lib/commands/test'; -import * as TestTask from '../tasks/test'; +const TestCommand = require('ember-cli/lib/commands/test'); +import TestTask from '../tasks/test'; import {CliConfig} from '../models/config'; -module.exports = TestCommand.extend({ +const NgCliTestCommand = TestCommand.extend({ availableOptions: [ { name: 'watch', type: Boolean, default: true, aliases: ['w'] }, { name: 'browsers', type: String }, @@ -13,7 +13,7 @@ module.exports = TestCommand.extend({ { name: 'build', type: Boolean, default: true } ], - run: function (commandOptions) { + run: function(commandOptions: any) { this.project.ngConfig = this.project.ngConfig || CliConfig.fromProject(); const testTask = new TestTask({ @@ -30,4 +30,5 @@ module.exports = TestCommand.extend({ } }); -module.exports.overrideCore = true; +NgCliTestCommand.overrideCore = true; +export default NgCliTestCommand; diff --git a/addon/ng2/commands/version.ts b/addon/ng2/commands/version.ts index 86937c70d118..13aadcfdaf38 100644 --- a/addon/ng2/commands/version.ts +++ b/addon/ng2/commands/version.ts @@ -1,4 +1,4 @@ -import * as Command from 'ember-cli/lib/models/command'; +const Command = require('ember-cli/lib/models/command'); import * as path from 'path'; import * as child_process from 'child_process'; @@ -13,8 +13,8 @@ const VersionCommand = Command.extend({ type: Boolean, 'default': false }], - run: function (options) { - const versions = process.versions; + run: function (options: any) { + const versions: any = process.versions; const pkg = require(path.resolve(__dirname, '..', '..', '..', 'package.json')); versions['os'] = process.platform + ' ' + process.arch; @@ -35,18 +35,18 @@ const VersionCommand = Command.extend({ this.printVersion('angular-cli', ngCliVersion); - for (const module in versions) { + for (const module of Object.keys(versions)) { if (options.verbose || alwaysPrint.indexOf(module) > -1) { this.printVersion(module, versions[module]); } } }, - printVersion: function (module, version) { + printVersion: function (module: string, version: string) { this.ui.writeLine(module + ': ' + version); } }); -module.exports = VersionCommand; -module.exports.overrideCore = true; +VersionCommand.overrideCore = true; +export default VersionCommand; diff --git a/addon/ng2/index.js b/addon/ng2/index.js index 7ffc78e4a482..58c02dc47fa7 100644 --- a/addon/ng2/index.js +++ b/addon/ng2/index.js @@ -12,25 +12,25 @@ module.exports = { includedCommands: function () { return { - 'build': require('./commands/build'), - 'serve': require('./commands/serve'), - 'new': require('./commands/new'), - 'generate': require('./commands/generate'), - 'init': require('./commands/init'), - 'test': require('./commands/test'), - 'e2e': require('./commands/e2e'), - 'lint': require('./commands/lint'), - 'version': require('./commands/version'), - 'completion': require('./commands/completion'), - 'doc': require('./commands/doc'), - 'github-pages-deploy': require('./commands/github-pages-deploy'), + 'build': require('./commands/build').default, + 'serve': require('./commands/serve').default, + 'new': require('./commands/new').default, + 'generate': require('./commands/generate').default, + 'init': require('./commands/init').default, + 'test': require('./commands/test').default, + 'e2e': require('./commands/e2e').default, + 'lint': require('./commands/lint').default, + 'version': require('./commands/version').default, + 'completion': require('./commands/completion').default, + 'doc': require('./commands/doc').default, + 'github-pages-deploy': require('./commands/github-pages-deploy').default, // Easter eggs. - 'make-this-awesome': require('./commands/easter-egg')('make-this-awesome'), + 'make-this-awesome': require('./commands/easter-egg').default, // Configuration. - 'set': require('./commands/set'), - 'get': require('./commands/get') + 'set': require('./commands/set').default, + 'get': require('./commands/get').default }; } }; diff --git a/addon/ng2/models/config.ts b/addon/ng2/models/config.ts index 4e11ba9a6452..dfb5c436d273 100644 --- a/addon/ng2/models/config.ts +++ b/addon/ng2/models/config.ts @@ -43,12 +43,19 @@ export class CliConfig extends CliConfigBase { const globalConfigPath = path.join(getUserHome(), CLI_CONFIG_FILE_NAME); if (!configPath) { - return {}; + return CliConfigBase.fromJson({}); } - const cliConfig = CliConfigBase.fromConfigPath(CliConfig._configFilePath(), [globalConfigPath]); - if (cliConfig.alias('apps.0.root', 'defaults.sourceDir') - + cliConfig.alias('apps.0.prefix', 'defaults.prefix')) { + const cliConfig = CliConfigBase.fromConfigPath( + CliConfig._configFilePath(), [globalConfigPath]); + + const aliases = [ + cliConfig.alias('apps.0.root', 'defaults.sourceDir'), + cliConfig.alias('apps.0.prefix', 'defaults.prefix') + ]; + + // If any of them returned true, output a deprecation warning. + if (aliases.some(x => !!x)) { 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 diff --git a/addon/ng2/models/config/config.ts b/addon/ng2/models/config/config.ts index 5ca4945b0bde..f67bde1a2e9c 100644 --- a/addon/ng2/models/config/config.ts +++ b/addon/ng2/models/config/config.ts @@ -14,17 +14,17 @@ export class InvalidConfigError extends Error { } -export class CliConfig { - private _config: SchemaClass; +export class CliConfig { + private _config: SchemaClass; constructor(private _configPath: string, schema: Object, - configJson: Config, - fallbacks: Config[] = []) { - this._config = new (SchemaClassFactory(schema))(configJson, ...fallbacks); + configJson: JsonType, + fallbacks: JsonType[] = []) { + this._config = new (SchemaClassFactory(schema))(configJson, ...fallbacks); } - get config(): Config { return this._config; } + get config(): JsonType { return this._config; } save(path: string = this._configPath) { return fs.writeFileSync(path, this.serialize(), 'utf-8'); @@ -55,20 +55,28 @@ export class CliConfig { this._config.$$set(jsonPath, value); } - static fromJson(schema: Object, content: Config, ...global: Config[]) { - return new CliConfig(null, schema, content, global); + static fromJson(content: ConfigType, ...global: ConfigType[]) { + const schemaContent = fs.readFileSync(DEFAULT_CONFIG_SCHEMA_PATH, 'utf-8'); + let schema: Object; + try { + schema = JSON.parse(schemaContent); + } catch (err) { + throw new InvalidConfigError(err); + } + + return new CliConfig(null, schema, content, global); } - static fromConfigPath(configPath: string, otherPath: string[] = []): CliConfig { + static fromConfigPath(configPath: string, otherPath: string[] = []): CliConfig { const configContent = fs.readFileSync(configPath, 'utf-8'); const schemaContent = fs.readFileSync(DEFAULT_CONFIG_SCHEMA_PATH, 'utf-8'); const otherContents = otherPath .map(path => fs.existsSync(path) && fs.readFileSync(path, 'utf-8')) .filter(content => !!content); - let content; - let schema; - let others; + let content: T; + let schema: Object; + let others: T[]; try { content = JSON.parse(configContent); @@ -78,6 +86,6 @@ export class CliConfig { throw new InvalidConfigError(err); } - return new CliConfig(configPath, schema, content, others); + return new CliConfig(configPath, schema, content, others); } } diff --git a/addon/ng2/models/find-lazy-modules.ts b/addon/ng2/models/find-lazy-modules.ts index bad5aebe3d73..9b98a9079ec2 100644 --- a/addon/ng2/models/find-lazy-modules.ts +++ b/addon/ng2/models/find-lazy-modules.ts @@ -6,59 +6,61 @@ import * as ts from 'typescript'; import {getSource, findNodes, getContentOfKeyLiteral} from '../utilities/ast-utils'; -interface Array { - flatMap: (mapFn: (item: T) => Array) => Array; -} -Array.prototype.flatMap = function(mapFn: (item: T) => Array): Array { - if (!mapFn) { - return []; - } - - return this.reduce((arr, current) => { +function flatMap(obj: Array, mapFn: (item: T) => R | R[]): Array { + return obj.reduce((arr: R[], current: T) => { const result = mapFn.call(null, current); return result !== undefined ? arr.concat(result) : arr; - }, []); -}; + }, []); +} export function findLoadChildren(tsFilePath: string): string[] { const source = getSource(tsFilePath); - const unique = {}; + const unique: { [path: string]: boolean } = {}; + + let nodes = flatMap( + findNodes(source, ts.SyntaxKind.ObjectLiteralExpression), + node => findNodes(node, ts.SyntaxKind.PropertyAssignment)) + .filter((node: ts.PropertyAssignment) => { + const key = getContentOfKeyLiteral(source, node.name); + if (!key) { + // key is an expression, can't do anything. + return false; + } + 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 initializer. + .map((node: ts.PropertyAssignment) => { + return JSON.parse(node.initializer.getText(source)); // tslint:disable-line + }); - return findNodes(source, ts.SyntaxKind.ObjectLiteralExpression) - .flatMap(node => findNodes(node, ts.SyntaxKind.PropertyAssignment)) - .filter((node: ts.PropertyAssignment) => { - const key = getContentOfKeyLiteral(source, node.name); - if (!key) { - // key is an expression, can't do anything. + return nodes + .filter((value: string) => { + if (unique[value]) { return false; + } else { + unique[value] = true; + return true; } - 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 initializer. - .map((node: ts.PropertyAssignment) => { - return eval(node.initializer.getText(source)); // tslint:disable-line }) - .flatMap((value: string) => unique[value] ? undefined : unique[value] = value) .map((moduleName: string) => moduleName.split('#')[0]); } export function findLazyModules(projectRoot: any): string[] { - const allTs = glob.sync(path.join(projectRoot, '/**/*.ts')); - const result = {}; - allTs - .flatMap(tsPath => { + const result: {[key: string]: boolean} = {}; + glob.sync(path.join(projectRoot, '/**/*.ts')) + .forEach(tsPath => { findLoadChildren(tsPath).forEach(moduleName => { const fileName = path.resolve(path.dirname(tsPath), moduleName) + '.ts'; if (fs.existsSync(fileName)) { - result[moduleName] = fileName; + result[moduleName] = true; } }); }); - return result; + return Object.keys(result); } diff --git a/addon/ng2/models/index.ts b/addon/ng2/models/index.ts index f01dfadc6be5..b4205cf32e91 100644 --- a/addon/ng2/models/index.ts +++ b/addon/ng2/models/index.ts @@ -1,5 +1,4 @@ export * from './webpack-build-common'; -export * from './webpack-build-test'; export * from './webpack-build-production'; export * from './webpack-build-development'; export * from './webpack-build-mobile'; diff --git a/addon/ng2/models/json-schema/schema-class-factory.ts b/addon/ng2/models/json-schema/schema-class-factory.ts index cdb57d4f8638..c6b0734bc8e0 100644 --- a/addon/ng2/models/json-schema/schema-class-factory.ts +++ b/addon/ng2/models/json-schema/schema-class-factory.ts @@ -21,7 +21,7 @@ const kOriginalRoot = Symbol('schema-value'); */ function _parseJsonPath(path: string): string[] { const fragments = (path || '').split(/\./g); - const result = []; + const result: string[] = []; while (fragments.length > 0) { const fragment = fragments.shift(); @@ -53,9 +53,8 @@ function _getSchemaNodeForPath(rootMetaData: SchemaTreeNode, /** The interface the SchemaClassFactory returned class implements. */ -export interface SchemaClass extends ConfigType { - new (config: ConfigType): SchemaClass; - +export interface SchemaClass extends Object { + $$root(): JsonType; $$get(path: string): any; $$set(path: string, value: any): void; $$alias(source: string, destination: string): boolean; @@ -64,27 +63,37 @@ export interface SchemaClass extends ConfigType { // Metadata of the schema. $$typeOf(path: string): string; $$defined(path: string): boolean; - $$delete(path: string); + $$delete(path: string): void; $$serialize(mimetype?: string): string; } class SchemaClassBase implements SchemaClass { - private [kSchemaNode]: SchemaTreeNode; - - constructor(value: T) { - this[kOriginalRoot] = value; + constructor(schema: Object, value: T, ...fallbacks: T[]) { + (this as any)[kOriginalRoot] = value; + const forward = fallbacks.length > 0 + ? (new SchemaClassBase(schema, fallbacks.pop(), ...fallbacks).$$schema()) + : null; + (this as any)[kSchemaNode] = new RootSchemaTreeNode(this, { + forward, + value, + schema + }); } + $$root(): T { return this as any; } + $$schema(): RootSchemaTreeNode { return (this as any)[kSchemaNode] as RootSchemaTreeNode; } + $$originalRoot(): T { return (this as any)[kOriginalRoot] as T; } + /** Sets the value of a destination if the value is currently undefined. */ $$alias(source: string, destination: string) { - let sourceSchemaTreeNode = _getSchemaNodeForPath(this[kSchemaNode], source); + let sourceSchemaTreeNode = _getSchemaNodeForPath(this.$$schema(), source); const fragments = _parseJsonPath(destination); const maybeValue = fragments.reduce((value: any, current: string) => { return value && value[current]; - }, this[kOriginalRoot]); + }, this.$$originalRoot()); if (maybeValue !== undefined) { sourceSchemaTreeNode.set(maybeValue); @@ -95,18 +104,18 @@ class SchemaClassBase implements SchemaClass { /** Destroy all links between schemas to allow for GC. */ $$dispose() { - this[kSchemaNode].dispose(); + this.$$schema().dispose(); } /** Get a value from a JSON path. */ $$get(path: string): any { - const node = _getSchemaNodeForPath(this[kSchemaNode], path); + const node = _getSchemaNodeForPath(this.$$schema(), path); return node ? node.get() : undefined; } /** Set a value from a JSON path. */ - $$set(path: string, value: any) { - const node = _getSchemaNodeForPath(this[kSchemaNode], path); + $$set(path: string, value: any): void { + const node = _getSchemaNodeForPath(this.$$schema(), path); if (node) { node.set(value); } else { @@ -116,9 +125,9 @@ class SchemaClassBase implements SchemaClass { if (!splitPath) { return undefined; } - const parent = splitPath + const parent: any = splitPath .slice(0, -1) - .reduce((parent, curr) => parent && parent[curr], this); + .reduce((parent: any, curr: string) => parent && parent[curr], this); if (parent) { parent[splitPath[splitPath.length - 1]] = value; @@ -128,17 +137,17 @@ class SchemaClassBase implements SchemaClass { /** Get the Schema associated with a path. */ $$typeOf(path: string): string { - const node = _getSchemaNodeForPath(this[kSchemaNode], path); + const node = _getSchemaNodeForPath(this.$$schema(), path); return node ? node.type : null; } $$defined(path: string): boolean { - const node = _getSchemaNodeForPath(this[kSchemaNode], path); + const node = _getSchemaNodeForPath(this.$$schema(), path); return node ? node.defined : false; } $$delete(path: string) { - const node = _getSchemaNodeForPath(this[kSchemaNode], path); + const node = _getSchemaNodeForPath(this.$$schema(), path); if (node) { node.destroy(); } @@ -150,13 +159,15 @@ class SchemaClassBase implements SchemaClass { const serializer = Serializer.fromMimetype(mimetype, (s) => str += s, ...options); serializer.start(); - this[kSchemaNode].serialize(serializer); + this.$$schema().serialize(serializer); serializer.end(); return str; } } - +export interface SchemaClassFactoryReturn { + new (value: T, ...fallbacks: T[]): SchemaClass; +} /** * Create a class from a JSON SCHEMA object. Instanciating that class with an object @@ -166,16 +177,10 @@ class SchemaClassBase implements SchemaClass { * @returns {GeneratedSchemaClass} * @constructor */ -export function SchemaClassFactory(schema: Object): SchemaClassBase { +export function SchemaClassFactory(schema: Object): SchemaClassFactoryReturn { class GeneratedSchemaClass extends SchemaClassBase { constructor(value: T, ...fallbacks: T[]) { - super(value); - - this[kSchemaNode] = new RootSchemaTreeNode(this, { - forward: fallbacks.length > 0 ? (new this.constructor(...fallbacks)[kSchemaNode]) : null, - value, - schema - }); + super(schema, value, ...fallbacks); } } diff --git a/addon/ng2/models/json-schema/schema-tree.ts b/addon/ng2/models/json-schema/schema-tree.ts index 6f601c665c22..68a46dee9394 100644 --- a/addon/ng2/models/json-schema/schema-tree.ts +++ b/addon/ng2/models/json-schema/schema-tree.ts @@ -8,19 +8,18 @@ export class MissingImplementationError extends NgToolkitError {} export class SettingReadOnlyPropertyError extends NgToolkitError {} +export interface Schema { + [key: string]: any; +} + + /** This interface is defined to simplify the arguments passed in to the SchemaTreeNode. */ -interface TreeNodeConstructorArgument { +export type TreeNodeConstructorArgument = { parent?: SchemaTreeNode; name?: string; value: T; forward: SchemaTreeNode; - schema: Object; -} - - -/** A constructor for a SchemaTreeNode. */ -interface TreeNodeConstructor { - new (x: TreeNodeConstructorArgument): SchemaTreeNode; + schema: Schema; } @@ -34,7 +33,7 @@ export abstract class SchemaTreeNode { protected _defined: boolean = false; protected _dirty: boolean = false; - protected _schema: Object; + protected _schema: Schema; protected _name: string; protected _value: T; @@ -72,8 +71,8 @@ export abstract class SchemaTreeNode { abstract destroy(): void; get name() { return this._name; } get readOnly(): boolean { return this._schema['readOnly']; } - get parent(): SchemaTreeNode { return this._parent; } - get children(): { [key: string]: SchemaTreeNode} { return null; } + get parent(): SchemaTreeNode { return this._parent; } + get children(): { [key: string]: SchemaTreeNode} { return null; } abstract get(): T; set(v: T) { @@ -83,7 +82,7 @@ export abstract class SchemaTreeNode { throw new SettingReadOnlyPropertyError(); }; - abstract serialize(serializer: Serializer, value?: T = this.get()); + abstract serialize(serializer: Serializer, value?: T): void; protected static _defineProperty(proto: any, treeNode: SchemaTreeNode): void { if (treeNode.readOnly) { @@ -103,7 +102,7 @@ export abstract class SchemaTreeNode { /** Base Class used for Non-Leaves TreeNode. Meaning they can have children. */ -abstract class NonLeafSchemaTreeNode extends SchemaTreeNode { +export abstract class NonLeafSchemaTreeNode extends SchemaTreeNode { dispose() { for (const key of Object.keys(this.children)) { this.children[key].dispose(); @@ -128,9 +127,9 @@ abstract class NonLeafSchemaTreeNode extends SchemaTreeNode { // Helper function to create a child based on its schema. protected _createChildProperty(name: string, value: T, forward: SchemaTreeNode, - schema: Object, define = true): SchemaTreeNode { + schema: Schema, define = true): SchemaTreeNode { const type = schema['type']; - let Klass: TreeNodeConstructor = null; + let Klass: any = null; switch (type) { case 'object': Klass = ObjectSchemaTreeNode; break; @@ -155,11 +154,11 @@ abstract class NonLeafSchemaTreeNode extends SchemaTreeNode { /** A Schema Tree Node that represents an object. */ -class ObjectSchemaTreeNode extends NonLeafSchemaTreeNode { +export class ObjectSchemaTreeNode extends NonLeafSchemaTreeNode<{[key: string]: any}> { // The map of all children metadata. protected _children: { [key: string]: SchemaTreeNode }; - constructor(metaData: TreeNodeConstructorArgument) { + constructor(metaData: TreeNodeConstructorArgument) { super(metaData); let { value, forward, schema } = metaData; @@ -174,8 +173,8 @@ class ObjectSchemaTreeNode extends NonLeafSchemaTreeNode { const propertySchema = schema['properties'][name]; this._children[name] = this._createChildProperty( name, - value && value[name], - forward && (forward as NonLeafSchemaTreeNode).children[name], + value ? value[name] : null, + forward ? (forward as ObjectSchemaTreeNode).children[name] : null, propertySchema); } } else if (!schema['additionalProperties']) { @@ -216,11 +215,11 @@ class ObjectSchemaTreeNode extends NonLeafSchemaTreeNode { /** A Schema Tree Node that represents an array. */ -class ArraySchemaTreeNode extends NonLeafSchemaTreeNode { +export class ArraySchemaTreeNode extends NonLeafSchemaTreeNode> { // The map of all items metadata. protected _items: SchemaTreeNode[]; - constructor(metaData: TreeNodeConstructorArgument) { + constructor(metaData: TreeNodeConstructorArgument>) { super(metaData); let { value, forward, schema } = metaData; @@ -236,7 +235,7 @@ class ArraySchemaTreeNode extends NonLeafSchemaTreeNode { this._items[index] = this._createChildProperty( '' + index, value && value[index], - forward && (forward as NonLeafSchemaTreeNode).children[index], + forward && (forward as ArraySchemaTreeNode).children[index], schema['items'] ); } @@ -246,7 +245,7 @@ class ArraySchemaTreeNode extends NonLeafSchemaTreeNode { } } - get children() { return this._items; } + get children() { return this._items as {[key: string]: any}; } get type() { return 'array'; } serialize(serializer: Serializer, value = this._value) { @@ -264,7 +263,7 @@ class ArraySchemaTreeNode extends NonLeafSchemaTreeNode { * properties of the Schema root. */ export class RootSchemaTreeNode extends ObjectSchemaTreeNode { - constructor(proto: SchemaClassBase, metaData: TreeNodeConstructorArgument) { + constructor(proto: any, metaData: TreeNodeConstructorArgument) { super(metaData); for (const key of Object.keys(this._children)) { @@ -277,10 +276,10 @@ export class RootSchemaTreeNode extends ObjectSchemaTreeNode { /** A leaf in the schema tree. Must contain a single primitive value. */ -abstract class LeafSchemaTreeNode extends SchemaTreeNode { +export abstract class LeafSchemaTreeNode extends SchemaTreeNode { private _default: T; - constructor(metaData: TreeNodeConstructorArgument) { + constructor(metaData: TreeNodeConstructorArgument) { super(metaData); this._defined = metaData.value !== undefined; if ('default' in metaData.schema) { @@ -297,7 +296,7 @@ abstract class LeafSchemaTreeNode extends SchemaTreeNode { } return this._value === undefined ? undefined : this.convert(this._value); } - set(v) { this.dirty = true; this._value = this.convert(v); } + set(v: T) { this.dirty = true; this._value = this.convert(v); } destroy() { this._defined = false; @@ -306,7 +305,7 @@ abstract class LeafSchemaTreeNode extends SchemaTreeNode { abstract convert(v: any): T; - serialize(serializer: Serializer, value?: T = this.get()) { + serialize(serializer: Serializer, value: T = this.get()) { if (this.defined) { serializer.outputValue(value); } @@ -316,7 +315,7 @@ abstract class LeafSchemaTreeNode extends SchemaTreeNode { /** Basic primitives for JSON Schema. */ class StringSchemaTreeNode extends LeafSchemaTreeNode { - serialize(serializer: Serializer, value?: string = this.get()) { + serialize(serializer: Serializer, value: string = this.get()) { if (this.defined) { serializer.outputString(value); } @@ -328,7 +327,7 @@ class StringSchemaTreeNode extends LeafSchemaTreeNode { class BooleanSchemaTreeNode extends LeafSchemaTreeNode { - serialize(serializer: Serializer, value?: boolean = this.get()) { + serialize(serializer: Serializer, value: boolean = this.get()) { if (this.defined) { serializer.outputBoolean(value); } @@ -340,7 +339,7 @@ class BooleanSchemaTreeNode extends LeafSchemaTreeNode { class NumberSchemaTreeNode extends LeafSchemaTreeNode { - serialize(serializer: Serializer, value?: number = this.get()) { + serialize(serializer: Serializer, value: number = this.get()) { if (this.defined) { serializer.outputNumber(value); } diff --git a/addon/ng2/models/json-schema/serializer.ts b/addon/ng2/models/json-schema/serializer.ts index 3112b8f7d9ef..bee8c9645cf3 100644 --- a/addon/ng2/models/json-schema/serializer.ts +++ b/addon/ng2/models/json-schema/serializer.ts @@ -8,23 +8,23 @@ export interface WriterFn { } export abstract class Serializer { - abstract start(); - abstract end(); + abstract start(): void; + abstract end(): void; - abstract object(callback: () => void); - abstract property(name: string, callback: () => void); - abstract array(callback: () => void); + abstract object(callback: () => void): void; + abstract property(name: string, callback: () => void): void; + abstract array(callback: () => void): void; - abstract outputString(value: string); - abstract outputNumber(value: number); - abstract outputBoolean(value: boolean); + abstract outputString(value: string): void; + abstract outputNumber(value: number): void; + abstract outputBoolean(value: boolean): void; // Fallback when the value does not have metadata. - abstract outputValue(value: any); + abstract outputValue(value: any): void; - static fromMimetype(mimetype: string, writer: WriterFn, ...opts: any[]) { - let Klass = null; + static fromMimetype(mimetype: string, writer: WriterFn, ...opts: any[]): Serializer { + let Klass: { new(writer: WriterFn, ...args: any[]): Serializer } = null; switch (mimetype) { case 'application/json': Klass = JsonSerializer; break; @@ -36,8 +36,14 @@ export abstract class Serializer { } +interface JsonSerializerState { + empty?: boolean; + type?: string; + property?: boolean; +} + class JsonSerializer implements Serializer { - private _state: { empty: boolean, type: string, property: boolean }[] = []; + private _state: JsonSerializerState[] = []; constructor(private _writer: WriterFn, private _indentDelta = 2) {} @@ -57,7 +63,7 @@ class JsonSerializer implements Serializer { } } - private _top() { + private _top(): JsonSerializerState { return this._state[this._state.length - 1] || {}; } diff --git a/addon/ng2/models/webpack-build-common.ts b/addon/ng2/models/webpack-build-common.ts index d8f599992fe1..cbe92ef13711 100644 --- a/addon/ng2/models/webpack-build-common.ts +++ b/addon/ng2/models/webpack-build-common.ts @@ -1,12 +1,15 @@ import * as path from 'path'; -import * as CopyWebpackPlugin from 'copy-webpack-plugin'; -import * as HtmlWebpackPlugin from 'html-webpack-plugin'; +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); import * as webpack from 'webpack'; -import * as atl from 'awesome-typescript-loader'; +const atl = require('awesome-typescript-loader'); import { findLazyModules } from './find-lazy-modules'; + + import { BaseHrefWebpackPlugin } from '../utilities/base-href-webpack-plugin'; + export function getWebpackCommonConfig( projectRoot: string, environment: string, @@ -16,11 +19,15 @@ export function getWebpackCommonConfig( const appRoot = path.resolve(projectRoot, appConfig.root); const appMain = path.resolve(appRoot, appConfig.main); - const styles = appConfig.styles.map(style => path.resolve(appRoot, style)); - const scripts = appConfig.scripts.map(script => path.resolve(appRoot, script)); + const styles = appConfig.styles + ? appConfig.styles.map((style: string) => path.resolve(appRoot, style)) + : []; + const scripts = appConfig.scripts + ? appConfig.scripts.map((script: string) => path.resolve(appRoot, script)) + : []; const lazyModules = findLazyModules(appRoot); - let entry = { + let entry: { [key: string]: string[] } = { main: [appMain] }; diff --git a/addon/ng2/models/webpack-build-mobile.ts b/addon/ng2/models/webpack-build-mobile.ts index 34290c93cb6d..2b5a280fc3cf 100644 --- a/addon/ng2/models/webpack-build-mobile.ts +++ b/addon/ng2/models/webpack-build-mobile.ts @@ -1,6 +1,6 @@ import * as path from 'path'; -import * as OfflinePlugin from 'offline-plugin'; -import * as CopyWebpackPlugin from 'copy-webpack-plugin'; +const OfflinePlugin = require('offline-plugin'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); import { PrerenderWebpackPlugin } from '../utilities/prerender-webpack-plugin.ts'; export const getWebpackMobileConfigPartial = function (projectRoot: string, appConfig: any) { diff --git a/addon/ng2/models/webpack-build-production.ts b/addon/ng2/models/webpack-build-production.ts index 656152db6cd4..4b41cefee76e 100644 --- a/addon/ng2/models/webpack-build-production.ts +++ b/addon/ng2/models/webpack-build-production.ts @@ -1,6 +1,6 @@ import * as path from 'path'; -import * as WebpackMd5Hash from 'webpack-md5-hash'; -import * as CompressionPlugin from 'compression-webpack-plugin'; +const WebpackMd5Hash = require('webpack-md5-hash'); +const CompressionPlugin = require('compression-webpack-plugin'); import * as webpack from 'webpack'; export const getWebpackProdConfigPartial = function(projectRoot: string, appConfig: any) { @@ -16,11 +16,9 @@ export const getWebpackProdConfigPartial = function(projectRoot: string, appConf plugins: [ new WebpackMd5Hash(), new webpack.optimize.DedupePlugin(), - new webpack.optimize.UglifyJsPlugin({ - beautify: false, + new webpack.optimize.UglifyJsPlugin({ mangle: { screw_ie8 : true, keep_fnames: true }, - compress: { screw_ie8: true }, - comments: false + compress: { screw_ie8: true } }), new CompressionPlugin({ asset: '[path].gz[query]', diff --git a/addon/ng2/models/webpack-config.ts b/addon/ng2/models/webpack-config.ts index fd292f9aaeaa..85c8c90fea54 100644 --- a/addon/ng2/models/webpack-config.ts +++ b/addon/ng2/models/webpack-config.ts @@ -1,4 +1,4 @@ -import * as webpackMerge from 'webpack-merge'; +const webpackMerge = require('webpack-merge'); import { CliConfig } from './config'; import { getWebpackCommonConfig, diff --git a/addon/ng2/tasks/build-webpack-watch.ts b/addon/ng2/tasks/build-webpack-watch.ts index c25f8a7d80a5..a85d4f1112c5 100644 --- a/addon/ng2/tasks/build-webpack-watch.ts +++ b/addon/ng2/tasks/build-webpack-watch.ts @@ -1,15 +1,15 @@ import * as rimraf from 'rimraf'; import * as path from 'path'; -import * as Task from 'ember-cli/lib/models/task'; +const Task = require('ember-cli/lib/models/task'); import * as webpack from 'webpack'; -import * as ProgressPlugin from 'webpack/lib/ProgressPlugin'; +const ProgressPlugin = require('webpack/lib/ProgressPlugin'); import { NgCliWebpackConfig } from '../models/webpack-config'; import { webpackOutputOptions } from '../models/'; import { BuildOptions } from '../commands/build'; let lastHash: any = null; -module.exports = Task.extend({ +export default Task.extend({ run: function(runTaskOptions: BuildOptions) { const project = this.cliProject; @@ -23,14 +23,14 @@ module.exports = Task.extend({ runTaskOptions.outputPath, runTaskOptions.baseHref ).config; - const webpackCompiler = webpack(config); + const webpackCompiler: any = webpack(config); webpackCompiler.apply(new ProgressPlugin({ profile: true })); - return new Promise( (resolve, reject) => { - webpackCompiler.watch({}, (err, stats) => { + return new Promise((resolve, reject) => { + webpackCompiler.watch({}, (err: any, stats: any) => { if (err) { lastHash = null; console.error(err.stack || err); diff --git a/addon/ng2/tasks/build-webpack.ts b/addon/ng2/tasks/build-webpack.ts index b8cf8fa83d7c..49abc0687b57 100644 --- a/addon/ng2/tasks/build-webpack.ts +++ b/addon/ng2/tasks/build-webpack.ts @@ -1,6 +1,6 @@ import * as rimraf from 'rimraf'; import * as path from 'path'; -import * as Task from 'ember-cli/lib/models/task'; +const Task = require('ember-cli/lib/models/task'); import * as webpack from 'webpack'; import { BuildOptions } from '../commands/build'; import { NgCliWebpackConfig } from '../models/webpack-config'; @@ -9,7 +9,7 @@ import { webpackOutputOptions } from '../models/'; // Configure build and output; let lastHash: any = null; -module.exports = Task.extend({ +export default Task.extend({ // Options: String outputPath run: function (runTaskOptions: BuildOptions) { @@ -24,7 +24,7 @@ module.exports = Task.extend({ runTaskOptions.baseHref ).config; - const webpackCompiler = webpack(config); + const webpackCompiler: any = webpack(config); const ProgressPlugin = require('webpack/lib/ProgressPlugin'); @@ -33,7 +33,7 @@ module.exports = Task.extend({ })); return new Promise((resolve, reject) => { - webpackCompiler.run((err, stats) => { + webpackCompiler.run((err: any, stats: any) => { // Don't keep cache // TODO: Make conditional if using --watch webpackCompiler.purgeInputFileSystem(); @@ -41,8 +41,10 @@ module.exports = Task.extend({ if (err) { lastHash = null; 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.hash !== lastHash) { diff --git a/addon/ng2/tasks/create-github-repo.ts b/addon/ng2/tasks/create-github-repo.ts index a899f934ca9e..ecf008bf4373 100644 --- a/addon/ng2/tasks/create-github-repo.ts +++ b/addon/ng2/tasks/create-github-repo.ts @@ -1,17 +1,18 @@ -import * as Promise from 'ember-cli/lib/ext/promise'; -import * as Task from 'ember-cli/lib/models/task'; -import * as SilentError from 'silent-error'; +import * as denodeify from 'denodeify'; +const Task = require('ember-cli/lib/models/task'); +const SilentError = require('silent-error'); import { exec } from 'child_process'; import * as https from 'https'; import { oneLine } from 'common-tags'; -module.exports = Task.extend({ - run: function(commandOptions) { + +export default Task.extend({ + run: function(commandOptions: any) { const ui = this.ui; - let promise; + let promise: Promise; // declared here so that tests can stub exec - const execPromise = Promise.denodeify(exec); + const execPromise = denodeify(exec); if (/.+/.test(commandOptions.ghToken) && /\w+/.test(commandOptions.ghUsername)) { promise = Promise.resolve({ @@ -37,14 +38,14 @@ module.exports = Task.extend({ Please enter GitHub token you just created (used only once to create the repo): `, - validate: function(token) { + validate: function(token: string) { return /.+/.test(token); } }, { name: 'ghUsername', type: 'input', message: 'and your GitHub user name:', - validate: function(userName) { + validate: function(userName: string) { return /\w+/.test(userName); } }]); @@ -70,7 +71,7 @@ module.exports = Task.extend({ } }); - req.on('response', function(response) { + req.on('response', function(response: any) { if (response.statusCode === 201) { resolve(execPromise(oneLine` git remote add origin diff --git a/addon/ng2/tasks/doc.ts b/addon/ng2/tasks/doc.ts index 687014def974..05b8b2cb4183 100644 --- a/addon/ng2/tasks/doc.ts +++ b/addon/ng2/tasks/doc.ts @@ -1,11 +1,9 @@ -import * as Task from 'ember-cli/lib/models/task'; -import * as opn from 'opn'; +const Task = require('ember-cli/lib/models/task'); +const opn = require('opn'); -const DocTask = Task.extend({ +export const DocTask: any = Task.extend({ run: function(keyword: string) { const searchUrl = `https://angular.io/docs/ts/latest/api/#!?apiFilter=${keyword}`; return opn(searchUrl, { wait: false }); } }); - -module.exports = DocTask; diff --git a/addon/ng2/tasks/e2e.ts b/addon/ng2/tasks/e2e.ts index 2ecc8420e0f3..778856424d7f 100644 --- a/addon/ng2/tasks/e2e.ts +++ b/addon/ng2/tasks/e2e.ts @@ -1,21 +1,21 @@ -import * as Promise from 'ember-cli/lib/ext/promise'; -import * as Task from 'ember-cli/lib/models/task'; +const Task = require('ember-cli/lib/models/task'); import * as chalk from 'chalk'; import {exec} from 'child_process'; -module.exports = Task.extend({ + +export const E2eTask = Task.extend({ run: function () { 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) => { + (err: NodeJS.ErrnoException, stdout: string, stderr: string) => { ui.writeLine(stdout); if (err) { ui.writeLine(stderr); ui.writeLine(chalk.red('Some end-to-end tests failed, see above.')); - exitCode = err.code; + exitCode = 1; } else { ui.writeLine(chalk.green('All end-to-end tests pass.')); } diff --git a/addon/ng2/tasks/link-cli.ts b/addon/ng2/tasks/link-cli.ts index a1b29c5407c6..bddf702fc965 100644 --- a/addon/ng2/tasks/link-cli.ts +++ b/addon/ng2/tasks/link-cli.ts @@ -1,9 +1,8 @@ -import * as Promise from 'ember-cli/lib/ext/promise'; -import * as Task from 'ember-cli/lib/models/task'; +const Task = require('ember-cli/lib/models/task'); import * as chalk from 'chalk'; import {exec} from 'child_process'; -module.exports = Task.extend({ +export default Task.extend({ run: function() { const ui = this.ui; diff --git a/addon/ng2/tasks/lint.ts b/addon/ng2/tasks/lint.ts index 46ff93b5ed71..0277bb20b404 100644 --- a/addon/ng2/tasks/lint.ts +++ b/addon/ng2/tasks/lint.ts @@ -1,9 +1,8 @@ -import * as Promise from 'ember-cli/lib/ext/promise'; -import * as Task from 'ember-cli/lib/models/task'; +const Task = require('ember-cli/lib/models/task'); import * as chalk from 'chalk'; import {exec} from 'child_process'; -module.exports = Task.extend({ +export default Task.extend({ run: function () { const ui = this.ui; diff --git a/addon/ng2/tasks/serve-webpack.ts b/addon/ng2/tasks/serve-webpack.ts index 5862f64c2fc1..4dfb1dffff1f 100644 --- a/addon/ng2/tasks/serve-webpack.ts +++ b/addon/ng2/tasks/serve-webpack.ts @@ -1,18 +1,18 @@ import * as fs from 'fs'; import * as path from 'path'; import * as chalk from 'chalk'; -import * as SilentError from 'silent-error'; -import * as Task from 'ember-cli/lib/models/task'; +const SilentError = require('silent-error'); +const Task = require('ember-cli/lib/models/task'); import * as webpack from 'webpack'; -import * as WebpackDevServer from 'webpack-dev-server'; -import * as ProgressPlugin from 'webpack/lib/ProgressPlugin'; +const WebpackDevServer = require('webpack-dev-server'); +const ProgressPlugin = require('webpack/lib/ProgressPlugin'); 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({ +export default Task.extend({ run: function(commandOptions: ServeTaskOptions) { const ui = this.ui; @@ -66,7 +66,7 @@ module.exports = Task.extend({ const server = new WebpackDevServer(webpackCompiler, webpackDevServerConfiguration); return new Promise((resolve, reject) => { - server.listen(commandOptions.port, `${commandOptions.host}`, function(err, stats) { + server.listen(commandOptions.port, `${commandOptions.host}`, function(err: any, stats: any) { if (err) { console.error(err.stack || err); if (err.details) { console.error(err.details); } @@ -76,7 +76,3 @@ module.exports = Task.extend({ }); } }); - - - - diff --git a/addon/ng2/tasks/test.ts b/addon/ng2/tasks/test.ts index 83076bd3dcae..d406df43e0c3 100644 --- a/addon/ng2/tasks/test.ts +++ b/addon/ng2/tasks/test.ts @@ -1,16 +1,15 @@ -import * as Promise from 'ember-cli/lib/ext/promise'; -import * as Task from 'ember-cli/lib/models/task'; +const Task = require('ember-cli/lib/models/task'); import * as path from 'path'; // require dependencies within the target project -function requireDependency(root, moduleName) { +function requireDependency(root: string, moduleName: string) { const packageJson = require(path.join(root, 'node_modules', moduleName, 'package.json')); const main = path.normalize(packageJson.main); return require(path.join(root, 'node_modules', moduleName, main)); } -module.exports = Task.extend({ - run: function (options) { +export default Task.extend({ + run: function (options: any) { const projectRoot = this.project.root; return new Promise((resolve) => { const karma = requireDependency(projectRoot, 'karma'); diff --git a/addon/ng2/tsconfig.json b/addon/ng2/tsconfig.json index 5ec19d74563c..116aa140dbe1 100644 --- a/addon/ng2/tsconfig.json +++ b/addon/ng2/tsconfig.json @@ -8,8 +8,8 @@ "moduleResolution": "node", "noEmitOnError": true, "noImplicitAny": true, - "outDir": "../dist/", - "rootDir": ".", + "outDir": "../../dist/", + "rootDir": "../..", "sourceMap": true, "sourceRoot": "/", "target": "es5", @@ -17,10 +17,15 @@ "typeRoots": [ "../../node_modules/@types" ], + "baseUrl": "", "paths": { - "@angular-cli/ast-tools": [ "../../packages/ast-tools/src" ] + "@angular-cli/ast-tools": [ "../../packages/ast-tools/src" ], + "@angular-cli/webpack": [ "../../packages/webpack/src" ] } }, + "exclude": [ + "blueprints/*/files/**/*" + ], "includes": [ "./custom-typings.d.ts" ] diff --git a/addon/ng2/utilities/base-href-webpack-plugin.ts b/addon/ng2/utilities/base-href-webpack-plugin.ts index 8466882adc53..c4b857b87022 100644 --- a/addon/ng2/utilities/base-href-webpack-plugin.ts +++ b/addon/ng2/utilities/base-href-webpack-plugin.ts @@ -1,20 +1,20 @@ -interface BaseHrefWebpackPluginOptions { +export interface BaseHrefWebpackPluginOptions { baseHref: string; } export class BaseHrefWebpackPlugin { constructor(private options: BaseHrefWebpackPluginOptions) { } - apply(compiler): void { + apply(compiler: any): void { // Ignore if baseHref is not passed if (!this.options.baseHref) { return; } - compiler.plugin('compilation', (compilation) => { + compiler.plugin('compilation', (compilation: any) => { compilation.plugin( 'html-webpack-plugin-before-html-processing', - (htmlPluginData, callback) => { + (htmlPluginData: any, callback: Function) => { // Check if base tag already exists const baseTagRegex = //i; const baseTagMatches = htmlPluginData.html.match(baseTagRegex); diff --git a/addon/ng2/utilities/get-dependent-files.ts b/addon/ng2/utilities/get-dependent-files.ts index bcc978486d04..c34aac816b18 100644 --- a/addon/ng2/utilities/get-dependent-files.ts +++ b/addon/ng2/utilities/get-dependent-files.ts @@ -1,12 +1,13 @@ -'use strict'; - import * as fs from 'fs'; import * as ts from 'typescript'; import * as glob from 'glob'; import * as path from 'path'; import * as denodeify from 'denodeify'; -import { Promise } from 'es6-promise'; + +const readFile = denodeify(fs.readFile); +const globSearch = denodeify(glob); + /** * Interface that represents a module specifier and its position in the source file. @@ -16,7 +17,7 @@ export interface ModuleImport { specifierText: string; pos: number; end: number; -}; +} export interface ModuleMap { [key: string]: ModuleImport[]; @@ -25,11 +26,10 @@ export interface ModuleMap { /** * Create a SourceFile as defined by Typescript Compiler API. * Generate a AST structure from a source file. - * + * * @param fileName source file for which AST is to be extracted */ export function createTsSourceFile(fileName: string): Promise { - const readFile = denodeify(fs.readFile); return readFile(fileName, 'utf8') .then((contents: string) => { return ts.createSourceFile(fileName, contents, ts.ScriptTarget.ES6, true); @@ -38,11 +38,11 @@ export function createTsSourceFile(fileName: string): Promise { /** * Traverses through AST of a given file of kind 'ts.SourceFile', filters out child - * nodes of the kind 'ts.SyntaxKind.ImportDeclaration' and returns import clauses as + * nodes of the kind 'ts.SyntaxKind.ImportDeclaration' and returns import clauses as * ModuleImport[] - * + * * @param {ts.SourceFile} node: Typescript Node of whose AST is being traversed - * + * * @return {ModuleImport[]} traverses through ts.Node and returns an array of moduleSpecifiers. */ export function getImportClauses(node: ts.SourceFile): ModuleImport[] { @@ -58,16 +58,15 @@ export function getImportClauses(node: ts.SourceFile): ModuleImport[] { }); } -/** +/** * Find the file, 'index.ts' given the directory name and return boolean value * based on its findings. - * + * * @param dirPath - * + * * @return a boolean value after it searches for a barrel (index.ts by convention) in a given path */ export function hasIndexFile(dirPath: string): Promise { - const globSearch = denodeify(glob); return globSearch(path.join(dirPath, 'index.ts'), { nodir: true }) .then((indexFile: string[]) => { return indexFile.length > 0; @@ -80,20 +79,19 @@ export function hasIndexFile(dirPath: string): Promise { * creating associated files with the name of the generated unit. So, there are two * assumptions made: * a. the function only returns associated files that have names matching to the given unit. - * b. the function only looks for the associated files in the directory where the given unit + * b. the function only looks for the associated files in the directory where the given unit * exists. - * + * * @todo read the metadata to look for the associated files of a given file. - * - * @param fileName - * + * + * @param fileName + * * @return absolute paths of '.html/.css/.sass/.spec.ts' files associated with the given file. * */ export function getAllAssociatedFiles(fileName: string): Promise { let fileDirName = path.dirname(fileName); let componentName = path.basename(fileName, '.ts'); - const globSearch = denodeify(glob); return globSearch(path.join(fileDirName, `${componentName}.*`), { nodir: true }) .then((files: string[]) => { return files.filter((file) => { @@ -105,15 +103,14 @@ export function getAllAssociatedFiles(fileName: string): Promise { /** * Returns a map of all dependent file/s' path with their moduleSpecifier object * (specifierText, pos, end). - * - * @param fileName file upon which other files depend + * + * @param fileName file upon which other files depend * @param rootPath root of the project - * + * * @return {Promise} ModuleMap of all dependent file/s (specifierText, pos, end) - * + * */ export function getDependentFiles(fileName: string, rootPath: string): Promise { - const globSearch = denodeify(glob); return globSearch(path.join(rootPath, '**/*.ts'), { nodir: true }) .then((files: string[]) => Promise.all(files.map(file => createTsSourceFile(file))) .then((tsFiles: ts.SourceFile[]) => tsFiles.map(file => getImportClauses(file))) diff --git a/addon/ng2/utilities/module-resolver.ts b/addon/ng2/utilities/module-resolver.ts index d02c97d54404..3b889116b53d 100644 --- a/addon/ng2/utilities/module-resolver.ts +++ b/addon/ng2/utilities/module-resolver.ts @@ -4,11 +4,11 @@ import * as path from 'path'; import * as ts from 'typescript'; import * as dependentFilesUtils from './get-dependent-files'; -import { Promise } from 'es6-promise'; + import { Change, ReplaceChange } from './change'; -/** - * Rewrites import module of dependent files when the file is moved. +/** + * Rewrites import module of dependent files when the file is moved. * Also, rewrites export module of related index file of the given file. */ export class ModuleResolver { @@ -17,11 +17,11 @@ export class ModuleResolver { /** * Changes are applied from the bottom of a file to the top. - * An array of Change instances are sorted based upon the order, + * An array of Change instances are sorted based upon the order, * then apply() method is called sequentially. - * - * @param changes {Change []} - * @return Promise after all apply() method of Change class is called + * + * @param changes {Change []} + * @return Promise after all apply() method of Change class is called * to all Change instances sequentially. */ applySortedChangePromise(changes: Change[]): Promise { @@ -30,9 +30,9 @@ export class ModuleResolver { .reduce((newChange, change) => newChange.then(() => change.apply()), Promise.resolve()); } - /** + /** * Assesses the import specifier and determines if it is a relative import. - * + * * @return {boolean} boolean value if the import specifier is a relative import. */ isRelativeImport(importClause: dependentFilesUtils.ModuleImport): boolean { @@ -42,13 +42,13 @@ export class ModuleResolver { return singleSlash || currentDirSyntax || parentDirSyntax; } - /** + /** * Rewrites the import specifiers of all the dependent files (cases for no index file). - * + * * @todo Implement the logic for rewriting imports of the dependent files when the file * being moved has index file in its old path and/or in its new path. - * - * @return {Promise} + * + * @return {Promise} */ resolveDependentFiles(): Promise { return dependentFilesUtils.getDependentFiles(this.oldFilePath, this.rootPath) @@ -83,7 +83,7 @@ export class ModuleResolver { /** * Rewrites the file's own relative imports after it has been moved to new path. - * + * * @return {Promise} */ resolveOwnImports(): Promise { diff --git a/addon/ng2/utilities/prerender-webpack-plugin.ts b/addon/ng2/utilities/prerender-webpack-plugin.ts index 0b3f77b5f9d8..95eb34cecea1 100644 --- a/addon/ng2/utilities/prerender-webpack-plugin.ts +++ b/addon/ng2/utilities/prerender-webpack-plugin.ts @@ -1,7 +1,7 @@ // replace with the real thing when PR is merged // https://github.com/angular/universal/pull/464 -interface IWebpackPrerender { +export interface IWebpackPrerender { templatePath: string; configPath: string; appPath: string; @@ -17,8 +17,8 @@ export class PrerenderWebpackPlugin { this.bootloader = require(this.options.configPath).getBootloader(); } - apply(compiler) { - compiler.plugin('emit', (compilation, callback) => { + apply(compiler: any) { + compiler.plugin('emit', (compilation: any, callback: Function) => { if (compilation.assets.hasOwnProperty(this.options.templatePath)) { // we need to cache the template file to be able to re-serialize it // even when it is not being emitted @@ -28,7 +28,7 @@ export class PrerenderWebpackPlugin { if (this.cachedTemplate) { this.decacheAppFiles(); require(this.options.configPath).serialize(this.bootloader, this.cachedTemplate) - .then((html) => { + .then((html: string) => { compilation.assets[this.options.templatePath] = { source: () => html, size: () => html.length diff --git a/lib/bootstrap-local.js b/lib/bootstrap-local.js index 773cca8930ce..80e219cbce88 100644 --- a/lib/bootstrap-local.js +++ b/lib/bootstrap-local.js @@ -2,9 +2,12 @@ 'use strict'; const fs = require('fs'); +const path = require('path'); const ts = require('typescript'); +const compilerOptions = JSON.parse(fs.readFileSync(path.join(__dirname, '../tsconfig.json'))); + const oldRequireTs = require.extensions['.ts']; require.extensions['.ts'] = function(m, filename) { // If we're in node module, either call the old hook or simply compile the @@ -21,10 +24,7 @@ require.extensions['.ts'] = function(m, filename) { const source = fs.readFileSync(filename).toString(); try { - const result = ts.transpile(source, { - target: ts.ScriptTarget.ES5, - module: ts.ModuleKind.CommonJs - }); + const result = ts.transpile(source, compilerOptions); // Send it to node to execute. return m._compile(result, filename); @@ -35,7 +35,11 @@ require.extensions['.ts'] = function(m, filename) { } }; - +// +// require('ts-node').register({ +// project: path.dirname(__dirname), +// lazy: true +// }); // If we're running locally, meaning npm linked. This is basically "developer mode". if (!__dirname.match(/\/node_modules\//)) { diff --git a/package.json b/package.json index 28023568c604..efca8c867d16 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,9 @@ }, "keywords": [], "scripts": { - "build": "for PKG in packages/*; do echo Building $PKG...; tsc -P $PKG; done", + "build": "npm-run-all -c build:main build:packages", + "build:main": "tsc -p addon/ng2", + "build:packages": "for PKG in packages/*; do echo Building $PKG...; tsc -P $PKG; done", "test": "npm run test:packages && npm run test:cli", "mobile_test": "mocha tests/e2e/e2e_workflow.spec.js", "test:cli": "node tests/runner", @@ -17,7 +19,7 @@ "test:packages": "node scripts/run-packages-spec.js", "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/**\"", + "tslint": "tslint \"**/*.ts\" -c tslint.json -e \"**/blueprints/*/files/**/*.ts\" -e \"node_modules/**\" -e \"tmp/**\" -e \"dist/**\"", "lint": "npm-run-all -c eslint tslint" }, "repository": { @@ -38,6 +40,8 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { + "@angular/compiler": "^2.0.0-rc.5", + "@angular/compiler-cli": "^0.5.0", "@angular/core": "^2.0.0-rc.5", "@angular/tsc-wrapped": "^0.2.2", "angular2-template-loader": "^0.5.0", @@ -109,7 +113,11 @@ ] }, "devDependencies": { + "@types/chalk": "^0.4.28", + "@types/common-tags": "^1.2.3", "@types/denodeify": "^1.2.29", + "@types/fs-extra": "^0.0.31", + "@types/glob": "^5.0.29", "@types/jasmine": "^2.2.32", "@types/lodash": "^4.0.25-alpha", "@types/mock-fs": "3.6.28", @@ -132,6 +140,7 @@ "sinon": "^1.17.3", "through": "^2.3.8", "tree-kill": "^1.0.0", + "ts-node": "^1.3.0", "tslint": "^3.11.0", "walk-sync": "^0.2.6" } diff --git a/packages/ast-tools/src/ast-utils.ts b/packages/ast-tools/src/ast-utils.ts index c95ec2dae6cc..0ffe4c6d8580 100644 --- a/packages/ast-tools/src/ast-utils.ts +++ b/packages/ast-tools/src/ast-utils.ts @@ -204,6 +204,7 @@ function _addSymbolToNgModuleMetadata(ngModulePath: string, metadataField: strin }) .then((node: ts.Node) => { if (!node) { + /* eslint-disable no-console */ console.log('No app module found. Please add your new class to your component.'); return new NoopChange(); } diff --git a/packages/ast-tools/src/index.ts b/packages/ast-tools/src/index.ts index 8c2b89852e23..d76151999687 100644 --- a/packages/ast-tools/src/index.ts +++ b/packages/ast-tools/src/index.ts @@ -1,3 +1,4 @@ export * from './ast-utils'; export * from './change'; export * from './node'; +export * from './route-utils'; diff --git a/tests/models/config.spec.ts b/tests/models/config.spec.ts index f99cbda1e744..706a4467f1bd 100644 --- a/tests/models/config.spec.ts +++ b/tests/models/config.spec.ts @@ -10,7 +10,7 @@ describe('Config', () => { let schema = JSON.parse(fs.readFileSync(path.join(__dirname, 'spec-schema.json'), 'utf-8')); it('works', () => { - const cliConfig = CliConfig.fromJson(schema, { + const cliConfig = new CliConfig(null, schema, { requiredKey: 1, stringKey: 'stringValue' }); @@ -31,7 +31,7 @@ describe('Config', () => { describe('Get', () => { it('works', () => { - const config = CliConfig.fromJson(schema, { + const config = new CliConfig(null, schema, { requiredKey: 1, stringKey: 'stringValue' }); @@ -42,7 +42,7 @@ describe('Config', () => { }); it('will never throw', () => { - const config = CliConfig.fromJson(schema, { + const config = new CliConfig(null, schema, { requiredKey: 1 }); @@ -54,10 +54,12 @@ describe('Config', () => { }); it('handles fallback values', () => { - const cliConfig = CliConfig.fromJson(schema, + const cliConfig = new CliConfig(null, schema, { requiredKey: 1 }, - { requiredKey: 1, stringKey: 'stringValue' }, - { requiredKey: 1, numberKey: 1 } + [ + { requiredKey: 1, stringKey: 'stringValue' }, + { requiredKey: 1, numberKey: 1 } + ] ); // Check on string. @@ -91,10 +93,11 @@ describe('Config', () => { arrayKey2: [{ stringKey: 'value1' }, { stringKey: 'value2' }] }; - const cliConfig = CliConfig.fromJson(schema, - jsonObject, - { requiredKey: 1, stringKey: 'stringValue' }, - { requiredKey: 1, numberKey: 1 } + const cliConfig = new CliConfig(null, schema, + jsonObject, [ + { requiredKey: 1, stringKey: 'stringValue' }, + { requiredKey: 1, numberKey: 1 } + ] ); expect(cliConfig.config.arrayKey2[0].stringKey).to.equal('value1'); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000000..7d2ae56c1324 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "experimentalDecorators": true, + "mapRoot": "", + "module": "commonjs", + "moduleResolution": "node", + "noEmitOnError": true, + "noImplicitAny": true, + "outDir": "./dist/", + "rootDir": ".", + "sourceMap": true, + "sourceRoot": "", + "target": "es5", + "lib": ["es6"], + "baseUrl": "", + "typeRoots": [ + "./node_modules/@types" + ], + "types": [ + "jasmine", + "node" + ], + "paths": { + "@angular-cli/ast-tools": [ "./packages/ast-tools/src" ], + "@angular-cli/webpack": [ "./packages/webpack/src" ] + } + }, + "exclude": [ + "dist/**/*", + "tmp/**/*" + ] +}