From cf04a93fe9003539d06c9c694d719ae717fd92da Mon Sep 17 00:00:00 2001 From: Larkin Family Date: Thu, 14 Jul 2016 16:02:19 -0700 Subject: [PATCH 01/38] build: use webpack for building apps. This pull request replaces the underlying broccoli build system and then replaces it with webpack as the build and bundler. This will affect the following commands (however the user-level) functionality should go unchanged (besides unimplemented flags which will come after this PR.): ng build (with --env flag and --watch flag supported) ng serve (with --port flag supported) ng test / ng e2e The webpack configuration is blackboxed, and therefore users will not see a webpack.config.js file in their repository. Also this PR will bump the typescript version to 2.0 (beta). Fixes #909 #1155 #882 --- .../mobile/files/__path__/main-app-shell.ts | 49 +- .../mobile/files/__path__/system-import.js | 2 - .../blueprints/ng2/files/__path__/index.html | 51 +- .../ng2/files/__path__/polyfills.ts | 4 + .../ng2/blueprints/ng2/files/__path__/test.ts | 41 + .../ng2/files/__path__/tsconfig.json | 27 +- .../ng2/files/__path__/typings.d.ts | 14 +- .../blueprints/ng2/files/__path__/vendor.ts | 17 + .../blueprints/ng2/files/angular-cli-build.js | 21 - .../blueprints/ng2/files/config/karma.conf.js | 18 +- .../blueprints/ng2/files/e2e/tsconfig.json | 2 - .../ng2/blueprints/ng2/files/e2e/typings.d.ts | 2 +- addon/ng2/blueprints/ng2/files/package.json | 18 +- addon/ng2/blueprints/ng2/files/typings.json | 7 +- addon/ng2/commands/build.ts | 57 + addon/ng2/commands/init.js | 3 +- addon/ng2/commands/serve.ts | 129 + addon/ng2/commands/test.js | 68 +- addon/ng2/index.js | 2 + addon/ng2/models/builder.ts | 161 + addon/ng2/models/index.ts | 9 + addon/ng2/models/save-for-later.ts | 272 + addon/ng2/models/webpack-build-common.ts | 92 + addon/ng2/models/webpack-build-development.ts | 27 + addon/ng2/models/webpack-build-material2.ts | 224 + addon/ng2/models/webpack-build-mobile.ts | 27 + addon/ng2/models/webpack-build-production.ts | 69 + addon/ng2/models/webpack-build-test.ts | 92 + addon/ng2/models/webpack-build-utils.ts | 23 + addon/ng2/models/webpack-config.ts | 82 + addon/ng2/models/webpack-karma-config.ts | 30 + addon/ng2/tasks/build-watch.ts | 30 + addon/ng2/tasks/build-webpack-watch.ts | 44 + addon/ng2/tasks/build-webpack.ts | 50 + addon/ng2/tasks/build.ts | 55 + addon/ng2/tasks/serve-webpack.ts | 64 + addon/ng2/tasks/serve.ts | 64 + addon/ng2/tasks/test.js | 40 +- .../ng2/utilities/prerender-webpack-plugin.ts | 56 + addon/ng2/utilities/sw-install.js | 1 + .../ts-path-mappings-webpack-plugin.ts | 255 + custom-typings.d.ts | 31 + npm-shrinkwrap.json | 6026 ----------------- package.json | 67 +- tests/e2e/e2e_workflow.spec.js | 35 +- tsconfig.json | 3 +- 46 files changed, 2240 insertions(+), 6221 deletions(-) delete mode 100644 addon/ng2/blueprints/mobile/files/__path__/system-import.js create mode 100644 addon/ng2/blueprints/ng2/files/__path__/polyfills.ts create mode 100644 addon/ng2/blueprints/ng2/files/__path__/test.ts create mode 100644 addon/ng2/blueprints/ng2/files/__path__/vendor.ts delete mode 100644 addon/ng2/blueprints/ng2/files/angular-cli-build.js create mode 100644 addon/ng2/commands/build.ts create mode 100644 addon/ng2/commands/serve.ts create mode 100644 addon/ng2/models/builder.ts create mode 100644 addon/ng2/models/index.ts create mode 100644 addon/ng2/models/save-for-later.ts create mode 100644 addon/ng2/models/webpack-build-common.ts create mode 100644 addon/ng2/models/webpack-build-development.ts create mode 100644 addon/ng2/models/webpack-build-material2.ts create mode 100644 addon/ng2/models/webpack-build-mobile.ts create mode 100644 addon/ng2/models/webpack-build-production.ts create mode 100644 addon/ng2/models/webpack-build-test.ts create mode 100644 addon/ng2/models/webpack-build-utils.ts create mode 100644 addon/ng2/models/webpack-config.ts create mode 100644 addon/ng2/models/webpack-karma-config.ts create mode 100644 addon/ng2/tasks/build-watch.ts create mode 100644 addon/ng2/tasks/build-webpack-watch.ts create mode 100644 addon/ng2/tasks/build-webpack.ts create mode 100644 addon/ng2/tasks/build.ts create mode 100644 addon/ng2/tasks/serve-webpack.ts create mode 100644 addon/ng2/tasks/serve.ts create mode 100644 addon/ng2/utilities/prerender-webpack-plugin.ts create mode 100644 addon/ng2/utilities/sw-install.js create mode 100644 addon/ng2/utilities/ts-path-mappings-webpack-plugin.ts create mode 100644 custom-typings.d.ts delete mode 100644 npm-shrinkwrap.json diff --git a/addon/ng2/blueprints/mobile/files/__path__/main-app-shell.ts b/addon/ng2/blueprints/mobile/files/__path__/main-app-shell.ts index 999059f8aa07..7d266b8426a4 100644 --- a/addon/ng2/blueprints/mobile/files/__path__/main-app-shell.ts +++ b/addon/ng2/blueprints/mobile/files/__path__/main-app-shell.ts @@ -1,29 +1,44 @@ +import 'angular2-universal-polyfills'; import { provide } from '@angular/core'; import { APP_BASE_HREF } from '@angular/common'; import { APP_SHELL_BUILD_PROVIDERS } from '@angular/app-shell'; -import { AppComponent } from './app/'; -import { - REQUEST_URL, - ORIGIN_URL +import { + REQUEST_URL, + ORIGIN_URL, + Bootloader, + BootloaderConfig, + AppConfig } from 'angular2-universal'; +import { AppComponent } from './app/'; -export const options = { - directives: [ - // The component that will become the main App Shell - AppComponent - ], +const bootloaderConfig: BootloaderConfig = { platformProviders: [ APP_SHELL_BUILD_PROVIDERS, provide(ORIGIN_URL, { - useValue: '' - }) + useValue: 'http://localhost:4200' // full urls are needed for node xhr + }), + provide(APP_BASE_HREF, { useValue: '/' }), + ], + async: true, + preboot: false +} + +const appConfig: AppConfig = { + directives: [ + // The component that will become the main App Shell + AppComponent ], providers: [ // What URL should Angular be treating the app as if navigating - provide(APP_BASE_HREF, {useValue: '/'}), - provide(REQUEST_URL, {useValue: '/'}) - ], - async: false, - preboot: false -}; + provide(REQUEST_URL, { useValue: '/' }) + ] +} + +export function getBootloader() : Bootloader { + return new Bootloader(bootloaderConfig); +} +export function serialize(bootloader: Bootloader, template: string) : string { + appConfig.template = template; + return bootloader.serializeApplication(appConfig); +} \ No newline at end of file diff --git a/addon/ng2/blueprints/mobile/files/__path__/system-import.js b/addon/ng2/blueprints/mobile/files/__path__/system-import.js deleted file mode 100644 index 40fb651c0954..000000000000 --- a/addon/ng2/blueprints/mobile/files/__path__/system-import.js +++ /dev/null @@ -1,2 +0,0 @@ -System.import('main') - .catch(console.error.bind(console)); diff --git a/addon/ng2/blueprints/ng2/files/__path__/index.html b/addon/ng2/blueprints/ng2/files/__path__/index.html index c800d403bd81..250c1d86e223 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/index.html +++ b/addon/ng2/blueprints/ng2/files/__path__/index.html @@ -5,53 +5,26 @@ <%= jsComponentName %> - {{#unless environment.production}} - - {{/unless}} <% if (isMobile) { %> - {{#each mobile.icons}} - - {{/each}} - - {{#if environment.production}} - - {{/if}} + + + + + + + + + + + <% } %> + <<%= prefix %>-root>Loading...-root> - <% if (isMobile) { %> - {{#if environment.production}} - - {{else}} - {{#each scripts.polyfills}} - - {{/each}} - - {{/if}} - <% } else { %> - {{#each scripts.polyfills}} - - {{/each}} - - <% } %> diff --git a/addon/ng2/blueprints/ng2/files/__path__/polyfills.ts b/addon/ng2/blueprints/ng2/files/__path__/polyfills.ts new file mode 100644 index 000000000000..492efbe2f5cf --- /dev/null +++ b/addon/ng2/blueprints/ng2/files/__path__/polyfills.ts @@ -0,0 +1,4 @@ +// Prefer CoreJS over the polyfills above +import 'core-js/es6'; +import 'core-js/es7/reflect'; +import 'zone.js/dist/zone'; diff --git a/addon/ng2/blueprints/ng2/files/__path__/test.ts b/addon/ng2/blueprints/ng2/files/__path__/test.ts new file mode 100644 index 000000000000..a5a378a83e22 --- /dev/null +++ b/addon/ng2/blueprints/ng2/files/__path__/test.ts @@ -0,0 +1,41 @@ + +/*global jasmine, __karma__, window*/ +require('core-js/es6'); +require('core-js/es7/reflect'); + +// Typescript emit helpers polyfill +require('ts-helpers'); + +require('zone.js/dist/zone'); +require('zone.js/dist/long-stack-trace-zone'); +require('zone.js/dist/jasmine-patch'); +require('zone.js/dist/async-test'); +require('zone.js/dist/fake-async-test'); +require('zone.js/dist/sync-test'); + +// RxJS +require('rxjs/Rx'); + +Promise.all([ + System.import('@angular/core/testing'), + System.import('@angular/platform-browser-dynamic/testing') + ]).then(function (providers) { + let testing = providers[0]; + let testingBrowser = providers[1]; + + testing.setBaseTestProviders(testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, + testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS); +}); + +let testContext = require.context('../src', true, /\.spec\.ts/); + +/* + * get all the files, for each file, call the context function + * that will require the file and load it up here. Context will + * loop and require those spec files here + */ +function requireAll(requireContext) { + return requireContext.keys().map(requireContext); +} + +requireAll(testContext); diff --git a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json index 8ae99db810ac..165a050f79b0 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json @@ -1,24 +1,23 @@ { - "compileOnSave": false, "compilerOptions": { + "baseUrl":"./src", "declaration": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "mapRoot": "/", - "module": "commonjs", + "module": "es6", + "target": "es5", "moduleResolution": "node", - "noEmitOnError": true, - "noImplicitAny": false, - "outDir": "../dist/", + "outDir": "./dist/", "rootDir": ".", - "sourceMap": true, - "target": "es5", - "inlineSources": true + "sourceMap": true }, - - "files": [ - "main.ts",<% if (isMobile) { %> - "main-app-shell.ts",<% } %> - "typings.d.ts" + "compileOnSave": false, + "buildOnSave": false, + "exclude": [ + "node_modules", + "bower_components" + ], + "includes": [ + "**.d.ts" ] } diff --git a/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts b/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts index a58a428505dd..41fe0885ed8b 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts @@ -1,6 +1,16 @@ + // Typings reference file, see links for more information // https://github.com/typings/typings // https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html -/// -<% if(!isMobile) { %>declare var module: { id: string };<% } %> +/// +/// +/// +/// + +<% if(!isMobile) { %> +declare var System: any; +declare var module: { id: string }; +declare var require: any; +<% } %> + diff --git a/addon/ng2/blueprints/ng2/files/__path__/vendor.ts b/addon/ng2/blueprints/ng2/files/__path__/vendor.ts new file mode 100644 index 000000000000..a74ebfcb3957 --- /dev/null +++ b/addon/ng2/blueprints/ng2/files/__path__/vendor.ts @@ -0,0 +1,17 @@ +// Typescript emit helpers polyfill +import 'ts-helpers'; + +import '@angular/core'; +import '@angular/common'; +import '@angular/compiler'; +import '@angular/http'; +import '@angular/router'; +import '@angular/platform-browser'; +import '@angular/platform-browser-dynamic'; + +<% if(isMobile) { %> + import '@angular/app-shell'; +<% } %> + +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/mergeMap'; diff --git a/addon/ng2/blueprints/ng2/files/angular-cli-build.js b/addon/ng2/blueprints/ng2/files/angular-cli-build.js deleted file mode 100644 index bd905df03188..000000000000 --- a/addon/ng2/blueprints/ng2/files/angular-cli-build.js +++ /dev/null @@ -1,21 +0,0 @@ -// Angular-CLI build configuration -// This file lists all the node_modules files that will be used in a build -// Also see https://github.com/angular/angular-cli/wiki/3rd-party-libs - -/* global require, module */ - -var Angular2App = require('angular-cli/lib/broccoli/angular2-app'); - -module.exports = function(defaults) { - return new Angular2App(defaults, { - vendorNpmFiles: [ - 'systemjs/dist/system-polyfills.js', - 'systemjs/dist/system.src.js', - 'zone.js/dist/**/*.+(js|js.map)', - 'es6-shim/es6-shim.js', - 'reflect-metadata/**/*.+(ts|js|js.map)', - 'rxjs/**/*.+(js|js.map)', - '@angular/**/*.+(js|js.map)' - ] - }); -}; diff --git a/addon/ng2/blueprints/ng2/files/config/karma.conf.js b/addon/ng2/blueprints/ng2/files/config/karma.conf.js index ef294ceea32f..cff5f0a204d5 100644 --- a/addon/ng2/blueprints/ng2/files/config/karma.conf.js +++ b/addon/ng2/blueprints/ng2/files/config/karma.conf.js @@ -1,6 +1,3 @@ -// Karma configuration file, see link for more information -// https://karma-runner.github.io/0.13/config/configuration-file.html - module.exports = function (config) { config.set({ basePath: '..', @@ -16,20 +13,7 @@ module.exports = function (config) { flags: ['--no-sandbox'] } }, - files: [ - { pattern: 'dist/vendor/es6-shim/es6-shim.js', included: true, watched: false }, - { pattern: 'dist/vendor/zone.js/dist/zone.js', included: true, watched: false }, - { pattern: 'dist/vendor/reflect-metadata/Reflect.js', included: true, watched: false }, - { pattern: 'dist/vendor/systemjs/dist/system-polyfills.js', included: true, watched: false }, - { pattern: 'dist/vendor/systemjs/dist/system.src.js', included: true, watched: false }, - { pattern: 'dist/vendor/zone.js/dist/async-test.js', included: true, watched: false }, - { pattern: 'dist/vendor/zone.js/dist/fake-async-test.js', included: true, watched: false }, - - { pattern: 'config/karma-test-shim.js', included: true, watched: true }, - - // Distribution folder. - { pattern: 'dist/**/*', included: false, watched: true } - ], + files: [], exclude: [ // Vendor packages might include spec files. We don't want to use those. 'dist/vendor/**/*.spec.js' diff --git a/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json b/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json index 29de61073fac..93a6038f60b4 100644 --- a/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json @@ -4,14 +4,12 @@ "declaration": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "mapRoot": "", "module": "commonjs", "moduleResolution": "node", "noEmitOnError": true, "noImplicitAny": false, "rootDir": ".", "sourceMap": true, - "sourceRoot": "/", "target": "es5" } } diff --git a/addon/ng2/blueprints/ng2/files/e2e/typings.d.ts b/addon/ng2/blueprints/ng2/files/e2e/typings.d.ts index 9c2f2d0252ef..eebc2728b868 100644 --- a/addon/ng2/blueprints/ng2/files/e2e/typings.d.ts +++ b/addon/ng2/blueprints/ng2/files/e2e/typings.d.ts @@ -1 +1 @@ -/// +/// diff --git a/addon/ng2/blueprints/ng2/files/package.json b/addon/ng2/blueprints/ng2/files/package.json index 9c58713a4b9f..4583454e51d0 100644 --- a/addon/ng2/blueprints/ng2/files/package.json +++ b/addon/ng2/blueprints/ng2/files/package.json @@ -21,21 +21,21 @@ "@angular/platform-browser": "2.0.0-rc.4", "@angular/platform-browser-dynamic": "2.0.0-rc.4", "@angular/router": "3.0.0-beta.2", - "es6-shim": "0.35.1", - "reflect-metadata": "0.1.3", + "ts-helpers": "^1.1.1", "rxjs": "5.0.0-beta.6", "systemjs": "0.19.26", - "zone.js": "0.6.12" + "zone.js": "0.6.12", + "core-js": "^2.4.0" }, "devDependencies": {<% if(isMobile) { %> "@angular/platform-server": "2.0.0-rc.4", "@angular/service-worker": "0.2.0", "@angular/app-shell": "0.0.0", - "angular2-broccoli-prerender": "0.11.5", "angular2-universal":"0.104.5", "angular2-universal-polyfills": "0.4.1", - "preboot": "2.0.10",<% } %> - "angular-cli": "<%= version %>", + "preboot": "2.1.2", + "parse5": "1.5.1",<% } %> + "angular-cli": "^<%= version %>", "codelyzer": "0.0.20", "ember-cli-inject-live-reload": "1.4.0", "jasmine-core": "2.4.1", @@ -44,9 +44,9 @@ "karma-chrome-launcher": "0.2.3", "karma-jasmine": "0.3.8", "protractor": "3.3.0", - "ts-node": "0.5.5", + "ts-node": "0.9.1", "tslint": "3.11.0", - "typescript": "1.8.10", - "typings": "0.8.1"<%= stylePackage %> + "typescript": "^1.9.0-dev.20160627-1.0", + "typings": "^1.3.1"<%= stylePackage %> } } diff --git a/addon/ng2/blueprints/ng2/files/typings.json b/addon/ng2/blueprints/ng2/files/typings.json index 21f9888ab067..6d8375bdd9a0 100644 --- a/addon/ng2/blueprints/ng2/files/typings.json +++ b/addon/ng2/blueprints/ng2/files/typings.json @@ -1,11 +1,10 @@ { - "ambientDevDependencies": { + "globalDevDependencies": { "angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459", "jasmine": "registry:dt/jasmine#2.2.0+20160412134438", "selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654" }, - "ambientDependencies": { - "es6-shim": "registry:dt/es6-shim#0.31.2+20160317120654"<% if (isMobile) {%>, - "node": "registry:dt/node#4.0.0+20160509154515" <% } %> + "globalDependencies": { + <% if (isMobile) {%>"node": "registry:dt/node#6.0.0+20160621231320" <% } %> } } diff --git a/addon/ng2/commands/build.ts b/addon/ng2/commands/build.ts new file mode 100644 index 000000000000..afb23572b315 --- /dev/null +++ b/addon/ng2/commands/build.ts @@ -0,0 +1,57 @@ +const Command = require('ember-cli/lib/models/command'); +const win = require('ember-cli/lib/utilities/windows-admin'); + +// const Build = require('../tasks/build'); +// const BuildWatch = require('../tasks/build-watch'); + +var WebpackBuild = require('../tasks/build-webpack'); +var WebpackBuildWatch = require('../tasks/build-webpack-watch'); + +interface BuildOptions { + environment?: string; + outputPath?: string; + watch?: boolean; + watcher?: string; + supressSizes: boolean; +} + +module.exports = Command.extend({ + name: 'build', + description: 'Builds your app and places it into the output path (dist/ by default).', + aliases: ['b'], + + availableOptions: [ + { name: 'environment', type: String, default: 'development', aliases: ['e', { 'dev': 'development' }, { 'prod': 'production' }] }, + { name: 'output-path', type: 'Path', default: 'dist/', aliases: ['o'] }, + { name: 'watch', type: Boolean, default: false, aliases: ['w'] }, + { name: 'watcher', type: String }, + { name: 'suppress-sizes', type: Boolean, default: false }, + + // Experimental webpack build for material team + { name: 'm2', type: Boolean, default: false} + ], + + run: function (commandOptions: BuildOptions) { + var project = this.project; + var ui = this.ui; + var buildTask = commandOptions.watch ? + new WebpackBuildWatch({ + cliProject: project, + ui: ui, + outputPath: commandOptions.outputPath, + environment: commandOptions.environment + }) : + new WebpackBuild({ + cliProject: project, + ui: ui, + outputPath: commandOptions.outputPath, + environment: commandOptions.environment + }); + + console.log(buildTask); + + return buildTask.run(commandOptions); + } +}); + +module.exports.overrideCore = true; diff --git a/addon/ng2/commands/init.js b/addon/ng2/commands/init.js index 7c7fff8aa460..3244bf94e2c0 100644 --- a/addon/ng2/commands/init.js +++ b/addon/ng2/commands/init.js @@ -9,6 +9,7 @@ var GitInit = require('../tasks/git-init'); var LinkCli = require('../tasks/link-cli'); var NpmInstall = require('../tasks/npm-install'); + module.exports = Command.extend({ name: 'init', description: 'Creates a new angular-cli project in the current folder.', @@ -94,7 +95,7 @@ module.exports = Command.extend({ return Promise.reject(new SilentError(message)); } - + var blueprintOpts = { dryRun: commandOptions.dryRun, blueprint: commandOptions.blueprint || this._defaultBlueprint(), diff --git a/addon/ng2/commands/serve.ts b/addon/ng2/commands/serve.ts new file mode 100644 index 000000000000..0537c2ad29a4 --- /dev/null +++ b/addon/ng2/commands/serve.ts @@ -0,0 +1,129 @@ +const assign = require('lodash/assign'); +const Command = require('ember-cli/lib/models/command'); +const Promise = require('ember-cli/lib/ext/promise'); +const SilentError = require('silent-error'); +const PortFinder = require('portfinder'); +const win = require('ember-cli/lib/utilities/windows-admin'); +const EOL = require('os').EOL; + + +PortFinder.basePort = 49152; + +const getPort = Promise.denodeify(PortFinder.getPort); +const defaultPort = process.env.PORT || 4200; + +export interface ServeTaskOptions { + port?: number; + host?: string; + proxy?: string; + insecureProxy?: boolean; + watcher?: string; + liveReload?: boolean; + liveReloadHost?: string; + liveReloadPort?: number; + liveReloadBaseUrl?: string; + liveReloadLiveCss?: boolean; + environment?: string; + outputPath?: string; + ssl?: boolean; + sslKey?: string; + sslCert?: string; +} + +module.exports = Command.extend({ + name: 'serve', + description: 'Builds and serves your app, rebuilding on file changes.', + aliases: ['server', 's'], + + availableOptions: [ + { name: 'port', type: Number, default: defaultPort, aliases: ['p'] }, + { name: 'host', type: String, aliases: ['H'], description: 'Listens on all interfaces by default' }, + { name: 'proxy', type: String, aliases: ['pr', 'pxy'] }, + { name: 'insecure-proxy', type: Boolean, default: false, aliases: ['inspr'], description: 'Set false to proxy self-signed SSL certificates' }, + { 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: 'environment', type: String, default: 'development', aliases: ['e', { 'dev': 'development' }, { 'mat': 'material'}, { 'prod': 'production' }] }, + { name: 'output-path', type: 'Path', default: 'dist/', aliases: ['op', 'out'] }, + { name: 'ssl', type: Boolean, default: false }, + { name: 'ssl-key', type: String, default: 'ssl/server.key' }, + { name: 'ssl-cert', type: String, default: 'ssl/server.crt' } + ], + + run: function(commandOptions: ServeTaskOptions) { + + + commandOptions.liveReloadHost = commandOptions.liveReloadHost || commandOptions.host; + + return this._checkExpressPort(commandOptions) + .then(this._autoFindLiveReloadPort.bind(this)) + .then(function(commandOptions: ServeTaskOptions) { + commandOptions = assign({}, commandOptions, { + baseURL: this.project.config(commandOptions.environment).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)); + } + } + + const ServeWebpackTask = (require('../tasks/serve-webpack.ts')) + + var serve = new ServeWebpackTask({ + ui: this.ui, + analytics: this.analytics, + project: this.project, + }); + + return win.checkWindowsElevation(this.ui).then(function() { + return serve.run(commandOptions); + }); + }.bind(this)); + }, + + _checkExpressPort: function(commandOptions: ServeTaskOptions) { + return getPort({ port: commandOptions.port, host: commandOptions.host }) + .then(function(foundPort: number) { + + if (commandOptions.port !== foundPort && commandOptions.port !== 0) { + var message = 'Port ' + commandOptions.port + ' is already in use.'; + return Promise.reject(new SilentError(message)); + } + + // otherwise, our found port is good + commandOptions.port = foundPort; + return commandOptions; + + }.bind(this)); + }, + + _autoFindLiveReloadPort: function(commandOptions: ServeTaskOptions) { + return getPort({ port: commandOptions.liveReloadPort, host: commandOptions.liveReloadHost }) + .then(function(foundPort: number) { + + // if live reload port matches express port, try one higher + if (foundPort === commandOptions.port) { + commandOptions.liveReloadPort = foundPort + 1; + return this._autoFindLiveReloadPort(commandOptions); + } + + // port was already open + if (foundPort === commandOptions.liveReloadPort) { + return commandOptions; + } + + // use found port as live reload port + commandOptions.liveReloadPort = foundPort; + return commandOptions; + + }.bind(this)); + } +}); + +module.exports.overrideCore = true; diff --git a/addon/ng2/commands/test.js b/addon/ng2/commands/test.js index a171d0399722..aab5451ace50 100644 --- a/addon/ng2/commands/test.js +++ b/addon/ng2/commands/test.js @@ -3,10 +3,12 @@ var Promise = require('ember-cli/lib/ext/promise'); var TestCommand = require('ember-cli/lib/commands/test'); var win = require('ember-cli/lib/utilities/windows-admin'); -var BuildTask = require('ember-cli/lib/tasks/build'); -var BuildWatchTask = require('ember-cli/lib/tasks/build-watch'); +// var BuildTask = require('ember-cli/lib/tasks/build'); +// var BuildWatchTask = require('ember-cli/lib/tasks/build-watch'); +const BuildWebpack = require('../tasks/build-webpack'); +const BuildWebpackWatch = require('../tasks/build-webpack-watch'); const config = require('../models/config'); -var TestTask = require('../tasks/test'); +const TestTask = require('../tasks/test'); module.exports = TestCommand.extend({ @@ -23,58 +25,58 @@ module.exports = TestCommand.extend({ run: function (commandOptions) { this.project.ngConfig = this.project.ngConfig || config.CliConfig.fromProject(); - var buildWatchTask = - new BuildWatchTask({ - ui: this.ui, - analytics: this.analytics, - project: this.project - }); - var buildTask = new BuildTask({ - ui: this.ui, - analytics: this.analytics, - project: this.project - }); + // var buildWatchTask = + // new BuildWebpackWatch({ + // ui: this.ui, + // analytics: this.analytics, + // project: this.project + // }); + // var buildTask = new BuildWebpack({ + // ui: this.ui, + // analytics: this.analytics, + // project: this.project + // }); var testTask = new TestTask({ ui: this.ui, analytics: this.analytics, project: this.project }); - var buildOptions = { - environment: 'development', - outputPath: 'dist/' - }; - + // var buildOptions = { + // environment: 'development', + // outputPath: 'dist/' + // }; + // If not building, mock/suppress build tasks. - if (!commandOptions.build) { - buildTask = { - run: () => { - return; - } - }; - buildWatchTask = buildTask; - } - + // if (!commandOptions.build) { + // buildTask = { + // run: () => { + // return; + // } + // }; + // buildWatchTask = buildTask; + // } + if (commandOptions.watch) { return win.checkWindowsElevation(this.ui) .then( () => { // perform initial build to avoid race condition - return buildTask.run(buildOptions); + // return buildTask.run(buildOptions); }, () => { /* handle build error to allow watch mode to start */ }) .then(() => { - return Promise.all([buildWatchTask.run(buildOptions), testTask.run(commandOptions)]); + return Promise.all([testTask.run(commandOptions)]); }); } else { // if not watching ensure karma is doing a single run commandOptions.singleRun = true; return win.checkWindowsElevation(this.ui) - .then(() => { - return buildTask.run(buildOptions); - }) + // .then(() => { + // return buildTask.run(buildOptions); + // }) .then(() => { return testTask.run(commandOptions); }); diff --git a/addon/ng2/index.js b/addon/ng2/index.js index cb5a3b548acc..1d6248f0c179 100644 --- a/addon/ng2/index.js +++ b/addon/ng2/index.js @@ -12,6 +12,8 @@ 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'), diff --git a/addon/ng2/models/builder.ts b/addon/ng2/models/builder.ts new file mode 100644 index 000000000000..62b16304c71d --- /dev/null +++ b/addon/ng2/models/builder.ts @@ -0,0 +1,161 @@ +const fs = require('fs-extra'); +const existsSync = require('exists-sync'); +const path = require('path'); +const Promise = require('ember-cli/lib/ext/promise'); +const Task = require('ember-cli/lib/models/task'); +const SilentError = require('silent-error'); +const chalk = require('chalk'); +const attemptNeverIndex = require('ember-cli/lib/utilities/attempt-never-index'); +const findBuildFile = require('ember-cli/lib/utilities/find-build-file'); +const viz = require('broccoli-viz'); +const FSMonitor = require('fs-monitor-stack'); +const Sync = require('tree-sync'); +const mkdirp = require('mkdirp'); + +let resolve = null; +let promise = new Promise((r) => resolve = r); + + + + +var signalsTrapped = false; +var buildCount = 0; + +function outputViz(count, result, monitor) { + var processed = viz.process(result.graph); + + processed.forEach(function(node) { + node.stats.fs = monitor.statsFor(node); + }); + + fs.writeFileSync('graph.' + count + '.dot', viz.dot(processed)); + fs.writeFileSync('graph.' + count + '.json', JSON.stringify({ + summary: { + buildCount: count, + output: result.directory, + totalTime: result.totalTime, + totalNodes: processed.length, + stats: { + fs: monitor.totalStats() + } + }, + nodes: processed + })); +} + +module.exports = Task.extend({ + setupBuilder: function() { + this.environment = this.environment || 'development'; + process.env.ANGULAR_ENV = process.env.ANGULAR_ENV || process.env.EMBER_CLI || this.environment; + process.env.EMBER_ENV = process.env.ANGULAR_ENV; + + var buildFile = findBuildFile('angular-cli-build.js'); + this.tree = buildFile({ project: this.project }); + + if (webpack) { + console.log('webpack'); + } else { + var broccoli = require('ember-cli-broccoli'); + this.builder = new broccoli.Builder(this.tree); + } + }, + + trapSignals: function() { + if (!signalsTrapped) { + process.on('SIGINT', this.onSIGINT.bind(this)); + process.on('SIGTERM', this.onSIGTERM.bind(this)); + process.on('message', this.onMessage.bind(this)); + signalsTrapped = true; + } + }, + + init: function() { + this.setupBuilder(); + this.trapSignals(); + }, + + /** + Determine whether the output path is safe to delete. If the outputPath + appears anywhere in the parents of the project root, the build would + delete the project directory. In this case return `false`, otherwise + return `true`. + */ + canDeleteOutputPath: function(outputPath) { + var rootPathParents = [this.project.root]; + var dir = path.dirname(this.project.root); + rootPathParents.push(dir); + while (dir !== path.dirname(dir)) { + dir = path.dirname(dir); + rootPathParents.push(dir); + } + return rootPathParents.indexOf(outputPath) === -1; + }, + + copyToOutputPath: function(inputPath) { + var outputPath = this.outputPath; + + mkdirp.sync(outputPath); + + if (!this.canDeleteOutputPath(outputPath)) { + throw new SilentError('Using a build destination path of `' + outputPath + '` is not supported.'); + } + + var sync = this._sync; + if (sync === undefined) { + this._sync = sync = new Sync(inputPath, path.resolve(this.outputPath)); + } + + sync.sync(); + }, + + build: function(...args: any[]) { + attemptNeverIndex('tmp'); + return promise; + // return Promise.resolve(); + // if (this.webpack) { + // console.log(1, process.cwd()); + // return new Promise((resolve, reject) => { + // this.webpack.run((err, stats) => { + // console.log(!!err, stats); + // if (err) { + // reject(err); + // } + // resolve(); + // }); + // }); + // } + // return this.builder.build(...args); + }, + + cleanup: function() { + var ui = this.ui; + + // if (this.webpack) { + // this.webpack.cleanupAndExit(); + return Promise.resolve(); + // } else { + // return this.builder.cleanup().catch(function (err) { + // ui.writeLine(chalk.red('Cleanup error.')); + // ui.writeError(err); + // }); + // } + }, + + cleanupAndExit: function() { + this.cleanup().finally(function() { + process.exit(1); + }); + }, + + onSIGINT: function() { + this.cleanupAndExit(); + }, + onSIGTERM: function() { + this.cleanupAndExit(); + }, + onMessage: function(message) { + if (message.kill) { + this.cleanupAndExit(); + } + } +}); diff --git a/addon/ng2/models/index.ts b/addon/ng2/models/index.ts new file mode 100644 index 000000000000..7ad3809dced4 --- /dev/null +++ b/addon/ng2/models/index.ts @@ -0,0 +1,9 @@ +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'; +export * from './webpack-build-utils'; +export {getWebpackMaterialConfig, getWebpackMaterialE2EConfig} from './webpack-build-material2.ts'; + +export * from './webpack-karma-config'; diff --git a/addon/ng2/models/save-for-later.ts b/addon/ng2/models/save-for-later.ts new file mode 100644 index 000000000000..643ff92cfaf9 --- /dev/null +++ b/addon/ng2/models/save-for-later.ts @@ -0,0 +1,272 @@ + +// new webpack.LoaderOptionsPlugin({ +// minimize: true +// }), +// new webpack.LoaderOptionsPlugin({ +// test: /\.js$/, +// jsfile: true +// }) +// new ClosureCompilerPlugin({ +// compiler: { +// language_in: 'ECMASCRIPT5', +// language_out: 'ECMASCRIPT5', +// compilation_level: 'SIMPLE' +// }, +// concurrency: 3, +// }) + + + + +// ts: { +// configFileName: ngAppResolve('./src/tsconfig.json'), +// silent: true +// }, +// output: { +// path: './dist/', +// filename: '[name].[chunkhash].js', +// sourceMapFilename: '[name].[chunkhash].map', +// chunkFilename: '[chunkhash].js' +// }, +// recordsPath: path.join(__dirname, "records.json"), +// +// +// +// +// new webpack.optimize.CommonsChunkPlugin({ +// names: ['main', 'vendors', 'polyfills'] +// }), +// new webpack.optimize.CommonsChunkPlugin({ +// minChunks: Infinity, +// name: 'inline', +// filename: 'inline.js', +// sourceMapFilename: 'inline.map' +// }), +// new HtmlWebpackPlugin({ +// template:'./src/index.html', +// chunksSortMode: "dependency" +// }) +// +// +// export const materialEntryConfig: {[key: string]: any} = { +// demoMain: [ngAppResolve('./src/demo-app/main.ts')], +// e2eMain: [ngAppResolve('./src/e2e-app/main.ts')], +// core: [ngAppResolve('./src/core/core.ts')], +// vendor: [ +// "@angular/common", +// "@angular/compiler", +// "@angular/core", +// "@angular/http", +// "@angular/platform-browser", +// "@angular/platform-browser-dynamic", +// "@angular/router", +// ], +// polyfills: [ +// "core-js", +// "hammerjs", +// "rxjs", +// "systemjs", +// "zone.js" +// ] +// } + +// export const materialPluginsConfig: any[] = [ +// new webpack.optimize.CommonsChunkPlugin({ +// name: ['polyfills', 'vendor'].reverse() +// }), +// new HtmlWebpackPlugin({ +// template: ngAppResolve('./demo-app/index.html'), +// chunksSortMode: 'dependency' +// }) +// ]; +// +// +// +// +// +// const webpack = require('webpack'); +// const HtmlWebpackPlugin = require('html-webpack-plugin'); +// const CopyWebpackPlugin = require('copy-webpack-plugin'); +// const path = require('path'); +// const ClosureCompilerPlugin = require('webpack-closure-compiler'); +// const autoprefixer = require('autoprefixer'); +// const cssnano = require('cssnano'); +// const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin; +// // Resolve to the generated applications + + + + +// let baseHtmlTemplateConfig = { +// template: ngAppResolve('./src/index.html'), +// chunksSortMode: 'dependency' +// }; +// // These are the output +// const webpackTestPartial = { +// module: { +// plugins: [ +// new ForkCheckerPlugin(), +// new HtmlWebpackPlugin(baseHtmlTemplateConfig), +// ], +// preLoaders: [ +// { +// test: /\.ts$/, +// loader: 'tslint-loader', +// exclude: ['node_modules'] +// }, +// { +// test: /\.js$/, +// loader: 'source-map-loader', +// exclude: [ +// // these packages have problems with their sourcemaps +// ngAppResolve('node_modules/rxjs'), +// ngAppResolve('node_modules/@angular') +// ]} +// ], +// loaders: [ +// { +// test: /\.ts$/, +// loaders: [ +// { +// loader: 'awesome-typescript-loader', +// query: { +// useWebpackText: true, +// tsconfig: ngAppResolve('./src/tsconfig.json'), +// resolveGlobs: false, +// module: "es2015", +// target: "es5", +// library: 'es6', +// useForkChecker: true, +// removeComments: true +// } +// }, +// { +// loader: 'angular2-template-loader' +// } +// ], +// exclude: [/\.(spec|e2e)\.ts$/] +// }, +// { test: /\.json$/, loader: 'json-loader', exclude: [ngAppResolve('src/index.html')] }, +// { test: /\.css$/, loader: 'raw-loader', exclude: [ngAppResolve('src/index.html')] }, +// { test: /\.html$/, loader: 'raw-loader', exclude: [ngAppResolve('src/index.html')] } +// ] +// }, +// tslint: { +// emitErrors: false, +// failOnHint: false, +// resourcePath: 'src' +// }, +// node: { +// global: 'window', +// process: false, +// crypto: 'empty', +// module: false, +// clearImmediate: false, +// setImmediate: false +// } +// }; + +// Webpack Configuration Object +// Used in build.ts + +// var webpack = require('webpack'); +// var path = require('path'); + + +// // Webpack Config +// var webpackConfig = { +// devtool: "#source-map", +// entry: { +// 'angular2polyfills': [ +// // 'ie-shim', +// 'core-js/es6/symbol', +// 'core-js/es6/object', +// 'core-js/es6/function', +// 'core-js/es6/parse-int', +// 'core-js/es6/parse-float', +// 'core-js/es6/number', +// 'core-js/es6/math', +// 'core-js/es6/string', +// 'core-js/es6/date', +// 'core-js/es6/array', +// 'core-js/es6/regexp', +// 'core-js/es6/map', +// 'core-js/es6/set', +// 'core-js/es6/weak-map', +// 'core-js/es6/weak-set', +// 'core-js/es6/typed', +// 'core-js/es6/reflect', +// // 'core-js/es6/promise', // problem with firefox +// 'core-js/es7/reflect', +// 'zone.js/dist/zone', +// 'zone.js/dist/long-stack-trace-zone', +// ], +// 'angular2vendor': [ +// '@angular/platform-browser', +// '@angular/platform-browser-dynamic', +// '@angular/core', +// '@angular/common', +// '@angular/forms', +// '@angular/http', +// '@angular/router', +// ] +// }, + +// output: { +// path: './dist', +// filename: 'dll.[name].[hash].bundle.js', +// sourceMapFilename: '[name].map', +// chunkFilename: '[id].chunk.js', +// library: '__DLL_[name]', +// }, + + +// plugins: [ +// new webpack.DllPlugin({ +// name: '[vendor]', +// path: 'dist/vendor-manifest.json', +// }), +// new webpack.DllPlugin({ +// name: 'polyfills', +// path: 'dist/polyfills-manifest.json', +// }), +// ], + +// module: { +// preLoaders: [ +// { +// test: /\.js$/, +// loader: 'source-map-loader', +// exclude: [ +// // these packages have problems with their sourcemaps +// path.resolve(__dirname, 'node_modules', 'rxjs'), +// path.resolve(__dirname, 'node_modules', '@angular'), +// path.resolve(__dirname, 'node_modules', '@ngrx'), +// path.resolve(__dirname, 'node_modules', '@angular2-material'), +// ] +// } + +// ], +// loaders: [ +// ] +// }, + +// node: { +// global: 'window', +// crypto: 'empty', +// module: false, +// clearImmediate: false, +// setImmediate: false +// } + +// }; + + + + + + + + + + diff --git a/addon/ng2/models/webpack-build-common.ts b/addon/ng2/models/webpack-build-common.ts new file mode 100644 index 000000000000..7d07ff0be416 --- /dev/null +++ b/addon/ng2/models/webpack-build-common.ts @@ -0,0 +1,92 @@ +import * as webpack from 'webpack'; +import {LoaderConfig} from '../utilities/ts-path-mappings-webpack-plugin'; + +const path = require('path'); +const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin; +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); + +export const getWebpackCommonConfig = function(projectRoot: string) { + const awesomeTypescriptLoaderConfig: LoaderConfig | any = { + useWebpackText: true, + useForkChecker: true, + tsconfig: path.resolve(projectRoot, './src/tsconfig.json') + } + + return { + devtool: 'inline-source-map', + resolve: { + extensions: ['', '.ts', '.js'], + root: path.resolve(projectRoot, './src'), + moduleDirectories: ['node_modules'] + }, + context: path.resolve(__dirname, './'), + entry: { + main: [path.resolve(projectRoot, './src/main.ts')], + vendor: path.resolve(projectRoot, './src/vendor.ts'), + polyfills: path.resolve(projectRoot, './src/polyfills.ts') + }, + output: { + path: path.resolve(projectRoot, './dist'), + filename: '[name].bundle.js' + }, + module: { + preLoaders: [ + { + test: /\.js$/, + loader: 'source-map-loader', + exclude: [ + path.resolve(projectRoot, 'node_modules/rxjs'), + path.resolve(projectRoot, 'node_modules/@angular'), + ] + } + ], + loaders: [ + { + test: /\.ts$/, + loaders: [ + { + loader: 'awesome-typescript-loader', + query: awesomeTypescriptLoaderConfig + }, + { + loader: 'angular2-template-loader' + } + ], + exclude: [/\.(spec|e2e)\.ts$/] + }, + { test: /\.json$/, loader: 'json-loader'}, + { test: /\.css$/, loaders: ['raw-loader', 'postcss-loader'] }, + { test: /\.styl$/, loaders: ['raw-loader', 'postcss-loader', 'stylus-loader'] }, + { test: /\.less$/, loaders: ['raw-loader', 'postcss-loader', 'less-loader'] }, + { test: /\.scss$/, loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] }, + { test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000'}, + { test: /\.html$/, loader: 'raw-loader' } + ] + }, + plugins: [ + new ForkCheckerPlugin(), + new HtmlWebpackPlugin({ + template: path.resolve(projectRoot, 'src/index.html'), + chunksSortMode: 'dependency' + }), + new webpack.optimize.CommonsChunkPlugin({ + name: ['polyfills', 'vendor'].reverse() + }), + new webpack.optimize.CommonsChunkPlugin({ + minChunks: Infinity, + name: 'inline', + filename: 'inline.js', + sourceMapFilename: 'inline.map' + }), + new CopyWebpackPlugin([{from: path.resolve(projectRoot, './public'), to: path.resolve(projectRoot, './dist')}]) + ], + node: { + global: 'window', + crypto: 'empty', + module: false, + clearImmediate: false, + setImmediate: false + } + } +}; diff --git a/addon/ng2/models/webpack-build-development.ts b/addon/ng2/models/webpack-build-development.ts new file mode 100644 index 000000000000..fc37a5d92b45 --- /dev/null +++ b/addon/ng2/models/webpack-build-development.ts @@ -0,0 +1,27 @@ +const path = require('path') + +export const getWebpackDevConfigPartial = function(projectRoot: string) { + return { + debug: true, + devtool: 'cheap-module-source-map', + output: { + path: path.resolve(projectRoot, './dist'), + filename: '[name].bundle.js', + sourceMapFilename: '[name].map', + chunkFilename: '[id].chunk.js' + }, + tslint: { + emitErrors: false, + failOnHint: false, + resourcePath: path.resolve(projectRoot, './src') + }, + node: { + global: 'window', + crypto: 'empty', + process: true, + module: false, + clearImmediate: false, + setImmediate: false + } + }; +} diff --git a/addon/ng2/models/webpack-build-material2.ts b/addon/ng2/models/webpack-build-material2.ts new file mode 100644 index 000000000000..e7629a217bd9 --- /dev/null +++ b/addon/ng2/models/webpack-build-material2.ts @@ -0,0 +1,224 @@ +// Angular Material2 Custom CLI Webpack Plugin: This allows for the following: +// To build, serve, and watchmode the angular2-material repo. +// +// Requirements: +// +// Do a find and replace on the src directory +// .css'] => .scss'] +// This allows for angular2-template-loader to transpile the sass correctly. +import * as webpack from 'webpack'; +import {LoaderConfig} from '../utilities/ts-path-mappings-webpack-plugin'; + +const path = require('path'); +const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin; +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); + + +// var components = [ +// 'button', +// 'card', +// 'checkbox', +// 'grid-list', +// 'icon', +// 'input', +// 'list', +// 'progress-bar', +// 'progress-circle', +// 'radio', +// 'sidenav', +// 'slide-toggle', +// 'button-toggle', +// 'tabs', +// 'toolbar' +// ]; + +export const getWebpackMaterialConfig = function(projectRoot: string) { + const awesomeTypescriptLoaderConfig: LoaderConfig | any = { + useWebpackText: true, + useForkChecker: true, + tsconfig: path.resolve(projectRoot, './src/demo-app/tsconfig.json') + } + /** Map relative paths to URLs. */ + // var aliasMap: any = { + // '@angular2-material/core': path.resolve(projectRoot, './src/core'), + // }; + + // components.forEach(function (name) { + // aliasMap[("@angular2-material/" + name)] = path.resolve(projectRoot, "./src/components/" + name); + // return aliasMap[("@angular2-material/" + name)] = path.resolve(projectRoot, "./src/components/" + name); + // }); + + return { + devtool: 'inline-source-map', + resolve: { + extensions: ['', '.webpack.js', '.web.js', '.ts', '.tsx', '.js', '.css', '.scss'], + plugins: [ + ] + // alias: aliasMap + }, + sassLoader: { + includePaths: [ + // This allows for automatic resolving of @import's for sass for variables. + path.resolve(projectRoot, './src/core/style') + ] + }, + context: path.resolve(__dirname, './'), + entry: { + main: [path.resolve(projectRoot, './src/demo-app/main.ts')], + vendor: path.resolve(projectRoot, './src/demo-app/vendor.ts') + }, + output: { + path: './dist', + filename: '[name].bundle.js' + }, + module: { + preLoaders: [ + { + test: /\.js$/, + loader: 'source-map-loader', + exclude: [ + path.resolve(projectRoot, 'node_modules/rxjs'), + path.resolve(projectRoot, 'node_modules/@angular'), + ] + } + ], + // ts: { + // configFileName: path.resolve(projectRoot, './src/demo-app/tsconfig.json') + // }, + loaders: [ + { + test: /\.ts$/, + loaders: [ + { + loader: 'awesome-typescript-loader', + query: awesomeTypescriptLoaderConfig + }, + { + loader: 'angular2-template-loader' + } + ], + exclude: [/\.(spec|e2e)\.ts$/] + }, + { test: /\.json$/, loader: 'json-loader'}, + { test: /\.css$/, loaders: ['raw-loader', 'postcss-loader'] }, + { test: /\.styl$/, loaders: ['raw-loader', 'postcss-loader', 'stylus-loader'] }, + { test: /\.less$/, loaders: ['raw-loader', 'less-loader'] }, + { test: /\.s?css$/, loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] }, + { test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000'}, + { test: /\.html$/, loader: 'raw-loader' } + ] + }, + plugins: [ + new webpack.optimize.CommonsChunkPlugin({name: 'vendor'}), + new ForkCheckerPlugin(), + new HtmlWebpackPlugin({ + template: path.resolve(projectRoot, './src/demo-app/index.html'), + chunksSortMode: 'dependency' + }), + ], + node: { + global: 'window', + crypto: 'empty', + module: false, + clearImmediate: false, + setImmediate: false + } + }; +} + +export const getWebpackMaterialE2EConfig = function(projectRoot: string) { + const awesomeTypescriptLoaderConfig: LoaderConfig | any = { + useWebpackText: true, + useForkChecker: true, + tsconfig: path.resolve(projectRoot, './src/e2e-app/tsconfig.json') + } + /** Map relative paths to URLs. */ + // var aliasMap: any = { + // '@angular2-material/core': path.resolve(projectRoot, './src/core'), + // }; + + // components.forEach(function (name) { + // aliasMap[("@angular2-material/" + name)] = path.resolve(projectRoot, "./src/components/" + name); + // return aliasMap[("@angular2-material/" + name)] = path.resolve(projectRoot, "./src/components/" + name); + // }); + + return { + devtool: 'inline-source-map', + resolve: { + extensions: ['', '.webpack.js', '.web.js', '.ts', '.tsx', '.js', '.css', '.scss'], + + plugins: [ + ] + // alias: aliasMap + }, + sassLoader: { + includePaths: [ + // This allows for automatic resolving of @import's for sass for variables. + path.resolve(projectRoot, './src/core/style') + ] + }, + debug: true, + context: path.resolve(__dirname, './'), + entry: { + main: [path.resolve(projectRoot, './src/e2e-app/main.ts')], + vendor: path.resolve(projectRoot, './src/e2e-app/vendor.ts') + }, + output: { + path: './dist', + filename: '[name].bundle.js' + }, + module: { + preLoaders: [ + { + test: /\.js$/, + loader: 'source-map-loader', + exclude: [ + path.resolve(projectRoot, 'node_modules/rxjs'), + path.resolve(projectRoot, 'node_modules/@angular'), + ] + } + ], + // ts: { + // configFileName: path.resolve(projectRoot, './src/e2e-app/tsconfig.json') + // }, + loaders: [ + { + test: /\.ts$/, + loaders: [ + { + loader: 'awesome-typescript-loader', + query: awesomeTypescriptLoaderConfig + }, + { + loader: 'angular2-template-loader' + } + ], + exclude: [/\.(spec|e2e)\.ts$/] + }, + { test: /\.json$/, loader: 'json-loader'}, + { test: /\.css$/, loaders: ['raw-loader', 'postcss-loader'] }, + { test: /\.styl$/, loaders: ['raw-loader', 'postcss-loader', 'stylus-loader'] }, + { test: /\.less$/, loaders: ['raw-loader', 'less-loader'] }, + { test: /\.s?css$/, loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] }, + { test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000'}, + { test: /\.html$/, loader: 'raw-loader' } + ] + }, + plugins: [ + new webpack.optimize.CommonsChunkPlugin({name: 'vendor'}), + new ForkCheckerPlugin(), + new HtmlWebpackPlugin({ + template: path.resolve(projectRoot, './src/e2e-app/index.html'), + chunksSortMode: 'dependency' + }), + ], + node: { + global: 'window', + crypto: 'empty', + module: false, + clearImmediate: false, + setImmediate: false + } + }; +} diff --git a/addon/ng2/models/webpack-build-mobile.ts b/addon/ng2/models/webpack-build-mobile.ts new file mode 100644 index 000000000000..59257ae435c8 --- /dev/null +++ b/addon/ng2/models/webpack-build-mobile.ts @@ -0,0 +1,27 @@ +import * as webpack from 'webpack'; +import * as path from 'path'; +import * as OfflinePlugin from 'offline-plugin'; +import { PrerenderWebpackPlugin } from '../utilities/prerender-webpack-plugin.ts' + +export const getWebpackMobileConfigPartial = function (projectRoot: string) { + return { + plugins: [ + new PrerenderWebpackPlugin({ + templatePath: 'index.html', + configPath: path.resolve(projectRoot, './src/main-app-shell.ts'), + appPath: path.resolve(projectRoot, './src') + }) + ] + } +}; + +export const getWebpackMobileProdConfigPartial = function (projectRoot: string) { + return { + entry: { + 'sw-install': path.resolve(__dirname, '../utilities/sw-install.js') + }, + plugins: [ + new OfflinePlugin() + ] + } +}; diff --git a/addon/ng2/models/webpack-build-production.ts b/addon/ng2/models/webpack-build-production.ts new file mode 100644 index 000000000000..9b144ac2da39 --- /dev/null +++ b/addon/ng2/models/webpack-build-production.ts @@ -0,0 +1,69 @@ +import * as webpack from 'webpack'; + +const path = require('path'); +const webpackMerge = require('webpack-merge'); // used to merge webpack configs +const WebpackMd5Hash = require('webpack-md5-hash'); +const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin'); //TODO WP2 Typings +const CompressionPlugin = require("compression-webpack-plugin"); + +export const getWebpackProdConfigPartial = function(projectRoot: string) { + return { + debug: false, + devtool: 'source-map', + output: { + path: path.resolve(projectRoot, './dist'), + filename: '[name].[chunkhash].bundle.js', + sourceMapFilename: '[name].[chunkhash].bundle.map', + chunkFilename: '[id].[chunkhash].chunk.js' + }, + plugins: [ + new WebpackMd5Hash(), + new webpack.optimize.DedupePlugin() + // ~400kb (Doesn't do anything different (yet?)) + // new LoaderOptionsPlugin({ + // test: /\.js/, + // minimize: true, + // optimize: true, + // debug: false + // }), + // ~107kb + new webpack.optimize.UglifyJsPlugin({ + beautify: false, //prod + mangle: { screw_ie8 : true }, //prod + compress: { screw_ie8: true }, //prod + comments: false //prod + }), + new CompressionPlugin({ + asset: "[path].gz[query]", + algorithm: "gzip", + test: /\.js$|\.html$/, + threshold: 10240, + minRatio: 0.8 + }) + ], + tslint: { + emitErrors: true, + failOnHint: true, + resourcePath: path.resolve(projectRoot, './src') + }, + htmlLoader: { + minimize: true, + removeAttributeQuotes: false, + caseSensitive: true, + customAttrSurround: [ + [/#/, /(?:)/], + [/\*/, /(?:)/], + [/\[?\(?/, /(?:)/] + ], + customAttrAssign: [/\)?\]?=/] + }, + node: { + global: 'window', + crypto: 'empty', + process: false, + module: false, + clearImmediate: false, + setImmediate: false + } + } +}; diff --git a/addon/ng2/models/webpack-build-test.ts b/addon/ng2/models/webpack-build-test.ts new file mode 100644 index 000000000000..6a1d15bf4410 --- /dev/null +++ b/addon/ng2/models/webpack-build-test.ts @@ -0,0 +1,92 @@ +import * as webpack from 'webpack'; + +const path = require('path'); + +export const getWebpackTestConfig = function(projectRoot: string) { + return { + devtool: 'inline-source-map', + context: path.resolve(__dirname, './'), + resolve: { + extensions: ['', '.ts', '.js'], + root: path.resolve(projectRoot, './src') + }, + entry: { + test: path.resolve(projectRoot, './src/test.ts') + }, + output: { + path: './dist.test', + filename: '[name].bundle.js' + }, + module: { + preLoaders: [ + { + test: /\.ts$/, + loader: 'tslint-loader', + exclude: [ + path.resolve(projectRoot, 'node_modules') + ] + }, + { + test: /\.js$/, + loader: 'source-map-loader', + exclude: [ + path.resolve(projectRoot, 'node_modules/rxjs'), + path.resolve(projectRoot, 'node_modules/@angular') + ] + } + ], + loaders: [ + { + test: /\.ts$/, + loaders: [ + { + loader: 'awesome-typescript-loader', + query: { + useWebpackText: true, + tsconfig: path.resolve(projectRoot, './src/tsconfig.json'), + // resolveGlobs: false, + module: "commonjs", + target: "es5", + useForkChecker: true, + removeComments: true + } + }, + { + loader: 'angular2-template-loader' + } + ], + exclude: [/\.e2e\.ts$/] + }, + { test: /\.json$/, loader: 'json-loader'}, + { test: /\.css$/, loaders: ['raw-loader', 'postcss-loader'] }, + { test: /\.styl$/, loaders: ['raw-loader', 'postcss-loader', 'stylus-loader'] }, + { test: /\.less$/, loaders: ['raw-loader', 'postcss-loader', 'less-loader'] }, + { test: /\.scss$/, loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] }, + { test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000'}, + { test: /\.html$/, loader: 'raw-loader', exclude: [path.resolve(projectRoot, 'src/index.html')] } + ], + postLoaders: [ + { + test: /\.(js|ts)$/, loader: 'istanbul-instrumenter-loader', + exclude: [ + /\.(e2e|spec)\.ts$/, + /node_modules/ + ] + } + ] + }, + tslint: { + emitErrors: false, + failOnHint: false, + resourcePath: 'src' + }, + node: { + global: 'window', + process: false, + crypto: 'empty', + module: false, + clearImmediate: false, + setImmediate: false + } + }; +} diff --git a/addon/ng2/models/webpack-build-utils.ts b/addon/ng2/models/webpack-build-utils.ts new file mode 100644 index 000000000000..572567d1e638 --- /dev/null +++ b/addon/ng2/models/webpack-build-utils.ts @@ -0,0 +1,23 @@ +const path = require('path'); + +export const ngAppResolve = (resolvePath: string): string => { + return path.resolve(process.cwd(), resolvePath); +} + +export const webpackOutputOptions: WebpackProgressPluginOutputOptions = { + colors: true, + chunks: true, + modules: false, + reasons: false, + chunkModules: false +} + +export const webpackDevServerOutputOptions = { + assets: true, + colors: true, + version: true, + hash: true, + timings: true, + chunks: false, + chunkModules: false +} diff --git a/addon/ng2/models/webpack-config.ts b/addon/ng2/models/webpack-config.ts new file mode 100644 index 000000000000..7245c830e118 --- /dev/null +++ b/addon/ng2/models/webpack-config.ts @@ -0,0 +1,82 @@ +import { CliConfig } from './config'; +import { + getWebpackCommonConfig, + getWebpackDevConfigPartial, + getWebpackProdConfigPartial, + getWebpackMaterialConfig, + getWebpackMaterialE2EConfig, + getWebpackMobileConfigPartial, + getWebpackMobileProdConfigPartial +} from './'; + +const webpackMerge = require('webpack-merge'); +const path = require('path'); + +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 webpackMaterialConfig: any; + private webpackMaterialE2EConfig: any; + private webpackMobileConfigPartial: any; + private webpackMobileProdConfigPartial: any; + + constructor(public ngCliProject: any, public environment: string) { + if (ngCliProject.pkg.name === 'material2') { + this.webpackMaterialConfig = getWebpackMaterialConfig(this.ngCliProject.root); + this.webpackMaterialE2EConfig = getWebpackMaterialE2EConfig(this.ngCliProject.root); + } else { + this.webpackBaseConfig = getWebpackCommonConfig(this.ngCliProject.root); + } + + this.webpackDevConfigPartial = getWebpackDevConfigPartial(this.ngCliProject.root); + this.webpackProdConfigPartial = getWebpackProdConfigPartial(this.ngCliProject.root); + + if (CliConfig.fromProject().apps[0].mobile){ + this.webpackMobileConfigPartial = getWebpackMobileConfigPartial(this.ngCliProject.root); + this.webpackMobileProdConfigPartial = getWebpackMobileProdConfigPartial(this.ngCliProject.root); + this.webpackDevConfigPartial = webpackMerge(this.webpackDevConfigPartial, this.webpackMobileConfigPartial); + this.webpackProdConfigPartial = webpackMerge(this.webpackProdConfigPartial, this.webpackMobileProdConfigPartial); + } + + this.generateConfig(); + } + + generateConfig(): void { + switch (this.environment) { + case "d": + case "dev": + case "development": + case "develop": + this.config = webpackMerge(this.webpackBaseConfig, this.webpackDevConfigPartial); + break; + case "p": + case "prod": + case "production": + this.config = webpackMerge(this.webpackBaseConfig, this.webpackProdConfigPartial); + break; + case "d:m": + case "dev:mat": + case "dev:material": + case "development:mat": + case "development:material": + this.config = webpackMerge(this.webpackMaterialConfig, this.webpackDevConfigPartial); + break; + case "p:m": + case "prod:mat": + case "prod:material": + case "production:mat": + case "production:material": + this.config = webpackMerge(this.webpackMaterialConfig, this.webpackProdConfigPartial); + break; + default: + //TODO: Not sure what to put here. We have a default env passed anyways. + this.ngCliProject.ui.writeLine("Envrionment could not be determined while configuring your build system.", 3) + break; + } + } +} + diff --git a/addon/ng2/models/webpack-karma-config.ts b/addon/ng2/models/webpack-karma-config.ts new file mode 100644 index 000000000000..1640043fd31f --- /dev/null +++ b/addon/ng2/models/webpack-karma-config.ts @@ -0,0 +1,30 @@ +export default function(config) { + var testWebpackConfig = require('./webpack.test.js'); + config.set({ + basePath: '', + frameworks: ['jasmine'], + exclude: [ ], + files: [ { pattern: './config/spec-bundle.js', watched: false } ], + coverageReporter: { + dir : 'coverage/', + reporters: [ + { type: 'text-summary' }, + { type: 'json' }, + { type: 'html' } + ] + }, + preprocessors: { './config/spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] }, + webpack: testWebpackConfig, + webpackServer: { noInfo: true }, + reporters: ['progress', 'mocha', 'coverage' ], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: false, + browsers: [ + // 'Chrome', + 'PhantomJS' + ], + singleRun: true + }); +}; diff --git a/addon/ng2/tasks/build-watch.ts b/addon/ng2/tasks/build-watch.ts new file mode 100644 index 000000000000..d816d47a3fe2 --- /dev/null +++ b/addon/ng2/tasks/build-watch.ts @@ -0,0 +1,30 @@ +const chalk = require('chalk'); +const Task = require('ember-cli/lib/models/task'); +const Watcher = require('ember-cli/lib/models/watcher'); +const Promise = require('ember-cli/lib/ext/promise'); + +const Builder = require('../models/builder'); + + +module.exports = Task.extend({ + run: function(options) { + console.log(2); + this.ui.startProgress( + chalk.green('Building'), chalk.green('.') + ); + + return new Watcher({ + ui: this.ui, + builder: new Builder({ + ui: this.ui, + outputPath: options.outputPath, + environment: options.environment, + project: this.project + }), + analytics: this.analytics, + options: options + }).then(function() { + return new Promise(function () {}); // Run until failure or signal to exit + }); + } +}); diff --git a/addon/ng2/tasks/build-webpack-watch.ts b/addon/ng2/tasks/build-webpack-watch.ts new file mode 100644 index 000000000000..2db928c9b8d6 --- /dev/null +++ b/addon/ng2/tasks/build-webpack-watch.ts @@ -0,0 +1,44 @@ +import {NgCliWebpackConfig} from '../models/webpack-config' +import {webpackOutputOptions} from '../models/'; +import {ServeTaskOptions} from '../commands/serve'; +import * as rimraf from 'rimraf'; +import * as path from 'path'; + +var Task = require('ember-cli/lib/models/task'); +const webpack = require('webpack'); +const ProgressPlugin = require('webpack/lib/ProgressPlugin'); + + +let lastHash: any = null; + +module.exports = Task.extend({ + run: function(runTaskOptions: ServeTaskOptions) { + + var project = this.cliProject; + + rimraf.sync(path.resolve(project.root, runTaskOptions.outputPath)); + + const config = new NgCliWebpackConfig(project, runTaskOptions.environment).config; + const webpackCompiler = webpack(config); + + webpackCompiler.apply(new ProgressPlugin({ + profile: true + })); + + return new Promise( (resolve, reject) => { + webpackCompiler.watch({}, (err, stats) => { + if (err) { + lastHash = null; + console.error(err.stack || err); + if(err.details) console.error(err.details); + reject(err.details); + } + + if(stats.hash !== lastHash) { + lastHash = stats.hash; + process.stdout.write(stats.toString(webpackOutputOptions) + "\n"); + } + }) + }) + } +}); diff --git a/addon/ng2/tasks/build-webpack.ts b/addon/ng2/tasks/build-webpack.ts new file mode 100644 index 000000000000..c7ebed1998bd --- /dev/null +++ b/addon/ng2/tasks/build-webpack.ts @@ -0,0 +1,50 @@ +import {ServeTaskOptions} from '../commands/serve'; +import {NgCliWebpackConfig} from '../models/webpack-config' +import {webpackOutputOptions} from '../models/' +import * as rimraf from 'rimraf'; +import * as path from 'path'; + +// Configure build and output; +var Task = require('ember-cli/lib/models/task'); +const webpack = require('webpack'); + +let lastHash: any = null; + +module.exports = Task.extend({ + // Options: String outputPath + run: function(runTaskOptions: ServeTaskOptions) { + + var project = this.cliProject; + + rimraf.sync(path.resolve(project.root, runTaskOptions.outputPath)); + var config = new NgCliWebpackConfig(project, runTaskOptions.environment).config; + const webpackCompiler = webpack(config); + + const ProgressPlugin = require('webpack/lib/ProgressPlugin'); + + webpackCompiler.apply(new ProgressPlugin({ + profile: true + })); + + return new Promise((resolve, reject) => { + webpackCompiler.run((err, stats) => { + // Don't keep cache + // TODO: Make conditional if using --watch + webpackCompiler.purgeInputFileSystem(); + + if(err) { + lastHash = null; + console.error(err.stack || err); + if(err.details) console.error(err.details); + reject(err.details); + } + + if(stats.hash !== lastHash) { + lastHash = stats.hash; + process.stdout.write(stats.toString(webpackOutputOptions) + "\n"); + } + resolve(); + }); + }); + } +}); diff --git a/addon/ng2/tasks/build.ts b/addon/ng2/tasks/build.ts new file mode 100644 index 000000000000..8af2961d35b3 --- /dev/null +++ b/addon/ng2/tasks/build.ts @@ -0,0 +1,55 @@ +const chalk = require('chalk'); +const Task = require('ember-cli/lib/models/task'); + +const Builder = require('../models/builder'); + + +module.exports = Task.extend({ + // Options: String outputPath + run: function(options) { + var ui = this.ui; + var analytics = this.analytics; + + ui.startProgress(chalk.green('Building'), chalk.green('.')); + + var builder = new Builder({ + ui: ui, + outputPath: options.outputPath, + environment: options.environment, + project: this.project + }); + + return builder.build() + .then(function(results) { + if (!results) { + return; + } + var totalTime = results.totalTime / 1e6; + + analytics.track({ + name: 'ember build', + message: totalTime + 'ms' + }); + + analytics.trackTiming({ + category: 'rebuild', + variable: 'build time', + label: 'broccoli build time', + value: parseInt(totalTime, 10) + }); + }) + .finally(function() { + ui.stopProgress(); + return builder.cleanup(); + }) + .then(function() { + ui.writeLine(chalk.green('Built project successfully. Stored in "' + + options.outputPath + '".')); + }) + .catch(function(err) { + ui.writeLine(chalk.red('Build failed.')); + + throw err; + }); + } +}); diff --git a/addon/ng2/tasks/serve-webpack.ts b/addon/ng2/tasks/serve-webpack.ts new file mode 100644 index 000000000000..1e79cab8ed21 --- /dev/null +++ b/addon/ng2/tasks/serve-webpack.ts @@ -0,0 +1,64 @@ +import {webpackDevServerOutputOptions} from '../models/'; +import {NgCliWebpackConfig} from '../models/webpack-config'; +import {ServeTaskOptions} from '../commands/serve'; + +const path = require('path'); +const chalk = require('chalk'); + + +const Task = require('ember-cli/lib/models/task'); +const webpack = require('webpack'); +const WebpackDevServer = require('webpack-dev-server'); +const ProgressPlugin = require('webpack/lib/ProgressPlugin'); + + + +let lastHash = null; + +module.exports = Task.extend({ + run: function(commandOptions: ServeTaskOptions) { + + let webpackCompiler: any; + + var config: NgCliWebpackConfig = new NgCliWebpackConfig(this.project, commandOptions.environment).config; + webpackCompiler = webpack(config); + + + webpackCompiler.apply(new ProgressPlugin({ + profile: true, + colors: true + })); + + const webpackDevServerConfiguration: IWebpackDevServerConfigurationOptions = { + contentBase: path.resolve(this.project.root, './src'), + historyApiFallback: true, + stats: webpackDevServerOutputOptions, + inline: true + }; + + const serveMessage:string = chalk.green(`\n*\n*\n NG Live Development Server is running on http://localhost:${commandOptions.port}.\n*\n*`); + const server = new WebpackDevServer(webpackCompiler, webpackDevServerConfiguration); + + return new Promise((resolve, reject) => { + server.listen(commandOptions.port, "localhost", function(err, stats) { + if(err) { + lastHash = null; + console.error(err.stack || err); + 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/serve.ts b/addon/ng2/tasks/serve.ts new file mode 100644 index 000000000000..b283942396fc --- /dev/null +++ b/addon/ng2/tasks/serve.ts @@ -0,0 +1,64 @@ +'use strict'; + +var existsSync = require('exists-sync'); +var path = require('path'); +var LiveReloadServer = require('ember-cli/lib/tasks/server/livereload-server'); +var ExpressServer = require('ember-cli/lib/tasks/server/express-server'); +var Promise = require('ember-cli/lib/ext/promise'); +var Task = require('ember-cli/lib/models/task'); +var Watcher = require('ember-cli/lib/models/watcher'); +var Builder = require('../models/builder'); +var ServerWatcher = require('ember-cli/lib/models/server-watcher'); + +module.exports = Task.extend({ + run: function(options) { + var builder = new Builder({ + ui: this.ui, + outputPath: options.outputPath, + project: this.project, + environment: options.environment + }); + + var watcher = new Watcher({ + ui: this.ui, + builder: builder, + analytics: this.analytics, + options: options + }); + + var serverRoot = './server'; + var serverWatcher = null; + if (existsSync(serverRoot)) { + serverWatcher = new ServerWatcher({ + ui: this.ui, + analytics: this.analytics, + watchedDir: path.resolve(serverRoot) + }); + } + + var expressServer = new ExpressServer({ + ui: this.ui, + project: this.project, + watcher: watcher, + serverRoot: serverRoot, + serverWatcher: serverWatcher + }); + + var liveReloadServer = new LiveReloadServer({ + ui: this.ui, + analytics: this.analytics, + project: this.project, + watcher: watcher, + expressServer: expressServer + }); + + return Promise.all([ + liveReloadServer.start(options), + expressServer.start(options) + ]).then(function() { + return new Promise(function() { + // hang until the user exits. + }); + }); + } +}); diff --git a/addon/ng2/tasks/test.js b/addon/ng2/tasks/test.js index c284c79b4e55..79fec18489ca 100644 --- a/addon/ng2/tasks/test.js +++ b/addon/ng2/tasks/test.js @@ -4,6 +4,9 @@ var Promise = require('ember-cli/lib/ext/promise'); var Task = require('ember-cli/lib/models/task'); var path = require('path'); +var ngAppResolve = require('../models').ngAppResolve; +var webpackTestConfig = require('../models/webpack-build-test').getWebpackTestConfig; +var displayOptions = require('../models/webpack-build-utils').webpackOutputOptions; // require dependencies within the target project function requireDependency(root, moduleName) { @@ -13,20 +16,53 @@ function requireDependency(root, moduleName) { } module.exports = Task.extend({ - run: function (options) { var projectRoot = this.project.root; return new Promise((resolve) => { + var karma = requireDependency(projectRoot, 'karma'); var karmaConfig = path.join(projectRoot, this.project.ngConfig.test.karma.config); + options.plugins = [ + require("karma-webpack"), + require("karma-jasmine"), + require("karma-chrome-launcher"), + require("karma-coverage"), + require("karma-mocha-reporter"), + require("karma-sourcemap-loader"), + ]; + options.reporters = ['coverage', 'mocha', 'progress']; + + // Abstract the webpack concepts from the local karma config. + // Add those details here. + + // Single test entry file. Will run the test.ts bundle and track it. + options.files = [{ pattern: './src/test.ts', watched: false }]; + options.preprocessors = { './src/test.ts': ['coverage','webpack','sourcemap'] }; + options.webpack = webpackTestConfig(projectRoot); + options.webpackMiddleware = { + noInfo: true, // Hide webpack output because its noisy. + stats: { // Also prevent chunk and module display output, cleaner look. Only emit errors. + assets: false, + colors: true, + version: false, + hash: false, + timings: false, + chunks: false, + chunkModules: false + } + }; + // Convert browsers from a string to an array if (options.browsers) { options.browsers = options.browsers.split(','); } + + // Assign additional karmaConfig options to the local ngapp config options.configFile = karmaConfig; - var karmaServer = new karma.Server(options, resolve); + // :shipit: + var karmaServer = new karma.Server(options, resolve); karmaServer.start(); }); } diff --git a/addon/ng2/utilities/prerender-webpack-plugin.ts b/addon/ng2/utilities/prerender-webpack-plugin.ts new file mode 100644 index 000000000000..1ce3c042aff9 --- /dev/null +++ b/addon/ng2/utilities/prerender-webpack-plugin.ts @@ -0,0 +1,56 @@ +// replace with the real thing when PR is merged +// https://github.com/angular/universal/pull/464 + +interface IWebpackPrerender { + templatePath: string; + configPath: string; + appPath: string; +} + +export class PrerenderWebpackPlugin { + + private bootloader: any; + private cachedTemplate: string + + constructor(private options: IWebpackPrerender) { + // maintain your platform instance + this.bootloader = require(this.options.configPath).getBootloader(); + } + + apply(compiler) { + compiler.plugin('emit', (compilation, callback) => { + 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 + this.cachedTemplate = compilation.assets[this.options.templatePath].source(); + } + + if (this.cachedTemplate) { + this.decacheAppFiles(); + require(this.options.configPath).serialize(this.bootloader, this.cachedTemplate) + .then((html) => { + compilation.assets[this.options.templatePath] = { + source: () => html, + size: () => html.length + }; + callback(); + }); + } else { + callback(); + } + }); + } + + decacheAppFiles() { + // delete all app files from cache, but keep libs + // this is needed so that the config file can reimport up to date + // versions of the app files + delete require.cache[this.options.configPath]; + Object.keys(require.cache) + .filter(key => key.startsWith(this.options.appPath)) + .forEach(function (key) { + // console.log('===', key); + delete require.cache[key]; + }); + } +} \ No newline at end of file diff --git a/addon/ng2/utilities/sw-install.js b/addon/ng2/utilities/sw-install.js new file mode 100644 index 000000000000..d2e341852813 --- /dev/null +++ b/addon/ng2/utilities/sw-install.js @@ -0,0 +1 @@ +require('offline-plugin/runtime').install(); \ No newline at end of file diff --git a/addon/ng2/utilities/ts-path-mappings-webpack-plugin.ts b/addon/ng2/utilities/ts-path-mappings-webpack-plugin.ts new file mode 100644 index 000000000000..13bdeb057703 --- /dev/null +++ b/addon/ng2/utilities/ts-path-mappings-webpack-plugin.ts @@ -0,0 +1,255 @@ +import * as path from 'path'; +import * as ts from 'typescript'; +import * as _ from 'lodash'; + +const ModulesInRootPlugin: new (a: string, b: string, c: string) => ResolverPlugin = require('enhanced-resolve/lib/ModulesInRootPlugin'); + +const createInnerCallback: CreateInnerCallback = require('enhanced-resolve/lib/createInnerCallback'); +const getInnerRequest: getInnerRequest = require('enhanced-resolve/lib/getInnerRequest'); + +export type ResolverCallback = (request: Request, callback: Callback) => void; +export type QueryOptions = LoaderConfig & ts.CompilerOptions; +export type TsConfig = ts.ParsedCommandLine; + +export type CreateInnerCallback = (callback: Callback, options: Callback, message?: string, messageOptional?: string) => Callback; +type getInnerRequest = (resolver: Resolver, request: Request) => string; + +export interface TSCompilerInfo { + compilerPath: string; + tsImpl: typeof ts; +} + +export interface Request { + request?: Request; + relativePath: string; +} + +export interface Callback { + (err?: Error, result?: any): void; + + log?: any; + stack?: any; + missing?: any; +} + +export interface Configs { + configFilePath: string; + compilerConfig: TsConfig; + loaderConfig: LoaderConfig; +} + +export interface LoaderConfig { + instanceName?: string; + showRecompileReason?: boolean; + compiler?: string; + emitRequireType?: boolean; + reEmitDependentFiles?: boolean; + tsconfig?: string; + useWebpackText?: boolean; + externals?: string[]; + doTypeCheck?: boolean; + ignoreDiagnostics?: number[]; + forkChecker?: boolean; + forkCheckerSilent?: boolean; + useBabel?: boolean; + babelCore?: string; + babelOptions?: any; + usePrecompiledFiles?: boolean; + skipDeclarationFilesCheck?: boolean; + useCache?: boolean; + cacheDirectory?: string; + resolveGlobs?: boolean; + library: string; +} + +export interface ResolverPlugin { + apply(resolver: Resolver): void; +} + +export interface Resolver { + apply(plugin: ResolverPlugin): void; + plugin(source: string, cb: ResolverCallback): void; + doResolve(target: string, req: Request, desc: string, Callback: any): void; + join(relativePath: string, innerRequest: Request): Request; +} + +export interface Mapping { + onlyModule: boolean; + alias: string; + aliasPattern: RegExp; + target: string; +} + +export function readConfigFile(baseDir: string, query: QueryOptions, tsImpl: typeof ts): Configs { + let configFilePath: string; + if (query.tsconfig && query.tsconfig.match(/\.json$/)) { + configFilePath = path.dirname(path.resolve(process.cwd(),query.tsconfig)); + } else { + configFilePath = tsImpl.findConfigFile(process.cwd(), tsImpl.sys.fileExists); + } + + let existingOptions = tsImpl.convertCompilerOptionsFromJson(query, process.cwd(), 'atl.query'); + + if (!configFilePath) { + return { + configFilePath: process.cwd(), + compilerConfig: tsImpl.parseJsonConfigFileContent( + {}, + tsImpl.sys, + process.cwd(), + _.extend({}, ts.getDefaultCompilerOptions(), existingOptions.options) as ts.CompilerOptions, + process.cwd() + ), + loaderConfig: query as LoaderConfig + }; + } + + debugger; + + let jsonConfigFile = tsImpl.readConfigFile(configFilePath, tsImpl.sys.readFile); + + let compilerConfig = tsImpl.parseJsonConfigFileContent( + jsonConfigFile.config, + tsImpl.sys, + process.cwd(), + existingOptions.options, + configFilePath + ); + + return { + jsonConfigFile, + configFilePath, + compilerConfig, + loaderConfig: _.defaults( + query, + jsonConfigFile.config.awesomeTypescriptLoaderOptions) + }; +} + + + +export function setupTs(compiler: string): TSCompilerInfo { + let compilerPath = compiler || 'typescript'; + + let tsImpl: typeof ts; + let tsImplPath: string; + try { + tsImplPath = require.resolve(compilerPath); + tsImpl = require(tsImplPath); + } catch (e) { + console.error(e); + process.exit(1); + } + + let compilerInfo: TSCompilerInfo = { + compilerPath, + tsImpl, + }; + + return compilerInfo; +} + + +function escapeRegExp(str: string) { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); +} + +export class PathsPlugin implements ResolverPlugin { + source: string; + target: string; + ts: typeof ts; + configFilePath: string; + options: ts.CompilerOptions; + + baseUrl: string; + mappings: Mapping[]; + absoluteBaseUrl: string; + + + constructor(config: LoaderConfig & ts.CompilerOptions = {} as any) { + this.source = 'described-resolve'; + this.target = 'resolve'; + + this.ts = setupTs(config.compiler).tsImpl; + + let { configFilePath, compilerConfig, jsonConfigFile } = readConfigFile(process.cwd(), config, this.ts); + this.options = compilerConfig.options; + this.configFilePath = configFilePath; + + this.baseUrl = this.options.configFilePath ? this.options.configFilePath : './'; + + this.absoluteBaseUrl = path.resolve( + path.dirname(this.configFilePath), + this.baseUrl + ); + + console.log("CONFIG FILE AND BASE URL"); + console.log(this.configFilePath, this.absoluteBaseUrl); + + this.mappings = []; + let paths = this.options.paths || {}; + Object.keys(paths).forEach(alias => { + let onlyModule = alias.indexOf('*') === -1; + let excapedAlias = escapeRegExp(alias); + let targets = paths[alias]; + targets.forEach(target => { + let aliasPattern: RegExp; + if (onlyModule) { + aliasPattern = new RegExp(`^${excapedAlias}$`); + } else { + let withStarCapturing = excapedAlias.replace('\\*', '(.*)'); + aliasPattern = new RegExp(`^${withStarCapturing}`); + } + + this.mappings.push({ + onlyModule, + alias, + aliasPattern, + target: target + }); + }); + }); + } + + apply(resolver: Resolver) { + let { baseUrl, mappings, absoluteBaseUrl } = this; + + if (baseUrl) { + resolver.apply(new ModulesInRootPlugin("module", absoluteBaseUrl, "resolve")); + } + + mappings.forEach(mapping => { + // resolver.plugin(this.source, this.createPlugin(resolver, mapping)); + resolver.plugin(this.source, function(request, callback) { + var innerRequest = getInnerRequest(resolver, request); + if(!innerRequest) return callback(); + + var newRequestStr = mapping.target; + var match = innerRequest.match(mapping.aliasPattern); + if (!match) { + return callback(); + } + if (!mapping.onlyModule) { + newRequestStr = newRequestStr.replace('*', match[1]); + } + if (newRequestStr[0] === '.') { + newRequestStr = path.resolve(absoluteBaseUrl, newRequestStr); + } + var obj: Request = Object.assign({}, request, { + request: newRequestStr + }); + + console.log("aliased'" + innerRequest + "': '" + mapping.alias + "' to '" + newRequestStr + "'", newRequest); + + return resolver.doResolve(this.target, obj,"aliased with mapping '" + innerRequest + "': '" + mapping.alias + "' to '" + newRequestStr + "'", createInnerCallback(function(err, result) { + if(arguments.length > 0) return callback(err, result); + + // don't allow other aliasing or raw request + callback(null, null); + }, callback)); + + return callback(); + }); + }); + } +} diff --git a/custom-typings.d.ts b/custom-typings.d.ts new file mode 100644 index 000000000000..b70dd7e88df3 --- /dev/null +++ b/custom-typings.d.ts @@ -0,0 +1,31 @@ +interface IWebpackDevServerConfigurationOptions { + contentBase?: string; + hot?: boolean; + historyApiFallback?: boolean; + compress?: boolean; + proxy?: {[key: string] : string}; + staticOptions?: any; + quiet?: boolean; + noInfo?: boolean; + lazy?: boolean; + filename?: string; + watchOptions?: { + aggregateTimeout?: number; + poll?: number; + }; + publicPath?: string; + headers?: { [key:string]: string }; + stats?: { [key:string]: boolean }; + inline: boolean; +} + +interface WebpackProgressPluginOutputOptions { + colors?: boolean; + chunks?: boolean; + modules?: boolean; + reasons?: boolean; + chunkModules?: boolean; +} + +declare var HtmlWebpackPlugin: any; +declare var LoaderOptionsPlugin: any; diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json deleted file mode 100644 index 5fc2d093f6fb..000000000000 --- a/npm-shrinkwrap.json +++ /dev/null @@ -1,6026 +0,0 @@ -{ - "name": "angular-cli", - "version": "1.0.0-beta.9", - "dependencies": { - "abbrev": { - "version": "1.0.9", - "from": "abbrev@1.0.9" - }, - "accepts": { - "version": "1.3.3", - "from": "accepts@1.3.3" - }, - "acorn": { - "version": "1.2.2", - "from": "acorn@1.2.2" - }, - "acorn-jsx": { - "version": "3.0.1", - "from": "acorn-jsx@3.0.1", - "dependencies": { - "acorn": { - "version": "3.2.0", - "from": "acorn@3.2.0" - } - } - }, - "after": { - "version": "0.8.1", - "from": "after@0.8.1" - }, - "agent-base": { - "version": "2.0.1", - "from": "agent-base@2.0.1", - "dependencies": { - "semver": { - "version": "5.0.3", - "from": "semver@5.0.3" - } - } - }, - "align-text": { - "version": "0.1.4", - "from": "align-text@0.1.4" - }, - "alter": { - "version": "0.2.0", - "from": "alter@0.2.0" - }, - "amd-name-resolver": { - "version": "0.0.5", - "from": "amd-name-resolver@0.0.5" - }, - "amdefine": { - "version": "1.0.0", - "from": "amdefine@1.0.0" - }, - "ansi": { - "version": "0.3.1", - "from": "ansi@0.3.1" - }, - "ansi-escapes": { - "version": "1.4.0", - "from": "ansi-escapes@1.4.0" - }, - "ansi-regex": { - "version": "0.2.1", - "from": "ansi-regex@0.2.1" - }, - "ansi-styles": { - "version": "1.1.0", - "from": "ansi-styles@1.1.0" - }, - "ansicolors": { - "version": "0.2.1", - "from": "ansicolors@0.2.1" - }, - "any-promise": { - "version": "1.3.0", - "from": "any-promise@1.3.0" - }, - "archy": { - "version": "1.0.0", - "from": "archy@1.0.0" - }, - "are-we-there-yet": { - "version": "1.1.2", - "from": "are-we-there-yet@1.1.2", - "dependencies": { - "isarray": { - "version": "1.0.0", - "from": "isarray@1.0.0" - }, - "readable-stream": { - "version": "2.1.4", - "from": "readable-stream@2.1.4" - } - } - }, - "argparse": { - "version": "1.0.7", - "from": "argparse@1.0.7" - }, - "array-equal": { - "version": "1.0.0", - "from": "array-equal@1.0.0" - }, - "array-find-index": { - "version": "1.0.1", - "from": "array-find-index@1.0.1" - }, - "array-flatten": { - "version": "1.1.1", - "from": "array-flatten@1.1.1" - }, - "array-ify": { - "version": "1.0.0", - "from": "array-ify@1.0.0" - }, - "array-to-error": { - "version": "1.1.1", - "from": "array-to-error@1.1.1" - }, - "array-to-sentence": { - "version": "1.1.0", - "from": "array-to-sentence@1.1.0" - }, - "array-union": { - "version": "1.0.2", - "from": "array-union@1.0.2" - }, - "array-uniq": { - "version": "1.0.3", - "from": "array-uniq@1.0.3" - }, - "arraybuffer.slice": { - "version": "0.0.6", - "from": "arraybuffer.slice@0.0.6" - }, - "arrify": { - "version": "1.0.1", - "from": "arrify@1.0.1" - }, - "asn1": { - "version": "0.2.3", - "from": "asn1@0.2.3" - }, - "assert-plus": { - "version": "0.2.0", - "from": "assert-plus@0.2.0" - }, - "assertion-error": { - "version": "1.0.2", - "from": "assertion-error@1.0.2" - }, - "ast-traverse": { - "version": "0.1.1", - "from": "ast-traverse@0.1.1" - }, - "ast-types": { - "version": "0.8.12", - "from": "ast-types@0.8.12" - }, - "async": { - "version": "1.5.2", - "from": "async@1.5.2" - }, - "async-disk-cache": { - "version": "1.0.7", - "from": "async-disk-cache@1.0.7" - }, - "aws-sign2": { - "version": "0.6.0", - "from": "aws-sign2@0.6.0" - }, - "aws4": { - "version": "1.4.1", - "from": "aws4@1.4.1" - }, - "babel-code-frame": { - "version": "6.11.0", - "from": "babel-code-frame@6.11.0", - "dependencies": { - "js-tokens": { - "version": "2.0.0", - "from": "js-tokens@2.0.0" - } - } - }, - "babel-core": { - "version": "5.8.38", - "from": "babel-core@5.8.38", - "dependencies": { - "lodash": { - "version": "3.10.1", - "from": "lodash@3.10.1" - }, - "minimatch": { - "version": "2.0.10", - "from": "minimatch@2.0.10" - }, - "source-map": { - "version": "0.5.6", - "from": "source-map@0.5.6" - } - } - }, - "babel-generator": { - "version": "6.11.3", - "from": "babel-generator@6.11.3", - "dependencies": { - "source-map": { - "version": "0.5.6", - "from": "source-map@0.5.6" - } - } - }, - "babel-helper-hoist-variables": { - "version": "6.8.0", - "from": "babel-helper-hoist-variables@6.8.0" - }, - "babel-helpers": { - "version": "6.8.0", - "from": "babel-helpers@6.8.0" - }, - "babel-messages": { - "version": "6.8.0", - "from": "babel-messages@6.8.0" - }, - "babel-plugin-constant-folding": { - "version": "1.0.1", - "from": "babel-plugin-constant-folding@1.0.1" - }, - "babel-plugin-dead-code-elimination": { - "version": "1.0.2", - "from": "babel-plugin-dead-code-elimination@1.0.2" - }, - "babel-plugin-eval": { - "version": "1.0.1", - "from": "babel-plugin-eval@1.0.1" - }, - "babel-plugin-inline-environment-variables": { - "version": "1.0.1", - "from": "babel-plugin-inline-environment-variables@1.0.1" - }, - "babel-plugin-jscript": { - "version": "1.0.4", - "from": "babel-plugin-jscript@1.0.4" - }, - "babel-plugin-member-expression-literals": { - "version": "1.0.1", - "from": "babel-plugin-member-expression-literals@1.0.1" - }, - "babel-plugin-property-literals": { - "version": "1.0.1", - "from": "babel-plugin-property-literals@1.0.1" - }, - "babel-plugin-proto-to-assign": { - "version": "1.0.4", - "from": "babel-plugin-proto-to-assign@1.0.4", - "dependencies": { - "lodash": { - "version": "3.10.1", - "from": "lodash@3.10.1" - } - } - }, - "babel-plugin-react-constant-elements": { - "version": "1.0.3", - "from": "babel-plugin-react-constant-elements@1.0.3" - }, - "babel-plugin-react-display-name": { - "version": "1.0.3", - "from": "babel-plugin-react-display-name@1.0.3" - }, - "babel-plugin-remove-console": { - "version": "1.0.1", - "from": "babel-plugin-remove-console@1.0.1" - }, - "babel-plugin-remove-debugger": { - "version": "1.0.1", - "from": "babel-plugin-remove-debugger@1.0.1" - }, - "babel-plugin-runtime": { - "version": "1.0.7", - "from": "babel-plugin-runtime@1.0.7" - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.9.0", - "from": "babel-plugin-transform-es2015-modules-systemjs@6.9.0" - }, - "babel-plugin-undeclared-variables-check": { - "version": "1.0.2", - "from": "babel-plugin-undeclared-variables-check@1.0.2" - }, - "babel-plugin-undefined-to-void": { - "version": "1.1.6", - "from": "babel-plugin-undefined-to-void@1.1.6" - }, - "babel-register": { - "version": "6.9.0", - "from": "babel-register@6.9.0", - "dependencies": { - "babel-core": { - "version": "6.10.4", - "from": "babel-core@6.10.4" - }, - "babylon": { - "version": "6.8.4", - "from": "babylon@6.8.4" - }, - "core-js": { - "version": "2.4.0", - "from": "core-js@2.4.0" - }, - "source-map": { - "version": "0.5.6", - "from": "source-map@0.5.6" - } - } - }, - "babel-runtime": { - "version": "6.9.2", - "from": "babel-runtime@6.9.2", - "dependencies": { - "core-js": { - "version": "2.4.0", - "from": "core-js@2.4.0" - } - } - }, - "babel-template": { - "version": "6.9.0", - "from": "babel-template@6.9.0", - "dependencies": { - "babylon": { - "version": "6.8.4", - "from": "babylon@6.8.4" - } - } - }, - "babel-traverse": { - "version": "6.10.4", - "from": "babel-traverse@6.10.4", - "dependencies": { - "babylon": { - "version": "6.8.4", - "from": "babylon@6.8.4" - }, - "globals": { - "version": "8.18.0", - "from": "globals@8.18.0" - } - } - }, - "babel-types": { - "version": "6.11.1", - "from": "babel-types@6.11.1" - }, - "babylon": { - "version": "5.8.38", - "from": "babylon@5.8.38" - }, - "backbone": { - "version": "1.3.3", - "from": "backbone@1.3.3" - }, - "backo2": { - "version": "1.0.2", - "from": "backo2@1.0.2" - }, - "balanced-match": { - "version": "0.4.1", - "from": "balanced-match@0.4.1" - }, - "base64-arraybuffer": { - "version": "0.1.2", - "from": "base64-arraybuffer@0.1.2" - }, - "base64id": { - "version": "0.1.0", - "from": "base64id@0.1.0" - }, - "basic-auth": { - "version": "1.0.4", - "from": "basic-auth@1.0.4" - }, - "benchmark": { - "version": "1.0.0", - "from": "benchmark@1.0.0" - }, - "better-assert": { - "version": "1.0.2", - "from": "better-assert@1.0.2" - }, - "binaryextensions": { - "version": "2.0.0", - "from": "binaryextensions@2.0.0" - }, - "bl": { - "version": "1.1.2", - "from": "bl@1.1.2", - "dependencies": { - "isarray": { - "version": "1.0.0", - "from": "isarray@1.0.0" - }, - "readable-stream": { - "version": "2.0.6", - "from": "readable-stream@2.0.6" - } - } - }, - "blank-object": { - "version": "1.0.1", - "from": "blank-object@1.0.1" - }, - "blob": { - "version": "0.0.4", - "from": "blob@0.0.4" - }, - "bluebird": { - "version": "2.10.2", - "from": "bluebird@2.10.2" - }, - "body-parser": { - "version": "1.14.2", - "from": "body-parser@1.14.2", - "dependencies": { - "bytes": { - "version": "2.2.0", - "from": "bytes@2.2.0" - }, - "http-errors": { - "version": "1.3.1", - "from": "http-errors@1.3.1" - }, - "qs": { - "version": "5.2.0", - "from": "qs@5.2.0" - } - } - }, - "boom": { - "version": "2.10.1", - "from": "boom@2.10.1" - }, - "bower": { - "version": "1.7.9", - "from": "bower@1.7.9" - }, - "bower-config": { - "version": "1.4.0", - "from": "bower-config@1.4.0" - }, - "bower-endpoint-parser": { - "version": "0.2.2", - "from": "bower-endpoint-parser@0.2.2" - }, - "boxen": { - "version": "0.3.1", - "from": "boxen@0.3.1", - "dependencies": { - "repeating": { - "version": "2.0.1", - "from": "repeating@2.0.1" - } - } - }, - "brace-expansion": { - "version": "1.1.5", - "from": "brace-expansion@1.1.5" - }, - "breakable": { - "version": "1.0.0", - "from": "breakable@1.0.0" - }, - "broccoli": { - "version": "1.0.0-beta.7", - "from": "broccoli@1.0.0-beta.7" - }, - "broccoli-babel-transpiler": { - "version": "5.5.0", - "from": "broccoli-babel-transpiler@5.5.0" - }, - "broccoli-caching-writer": { - "version": "2.2.1", - "from": "broccoli-caching-writer@2.2.1", - "dependencies": { - "broccoli-kitchen-sink-helpers": { - "version": "0.2.9", - "from": "broccoli-kitchen-sink-helpers@0.2.9" - }, - "glob": { - "version": "5.0.15", - "from": "glob@5.0.15" - } - } - }, - "broccoli-clean-css": { - "version": "1.1.0", - "from": "broccoli-clean-css@1.1.0" - }, - "broccoli-concat": { - "version": "2.2.1", - "from": "broccoli-concat@2.2.1" - }, - "broccoli-config-loader": { - "version": "1.0.0", - "from": "broccoli-config-loader@1.0.0" - }, - "broccoli-config-replace": { - "version": "1.1.2", - "from": "broccoli-config-replace@1.1.2", - "dependencies": { - "broccoli-plugin": { - "version": "1.2.1", - "from": "broccoli-plugin@1.2.1" - }, - "fs-extra": { - "version": "0.24.0", - "from": "fs-extra@0.24.0" - } - } - }, - "broccoli-filter": { - "version": "0.1.14", - "from": "broccoli-filter@0.1.14", - "dependencies": { - "broccoli-kitchen-sink-helpers": { - "version": "0.2.9", - "from": "broccoli-kitchen-sink-helpers@0.2.9", - "dependencies": { - "mkdirp": { - "version": "0.5.1", - "from": "mkdirp@0.5.1" - } - } - }, - "glob": { - "version": "5.0.15", - "from": "glob@5.0.15" - }, - "mkdirp": { - "version": "0.3.5", - "from": "mkdirp@0.3.5" - }, - "walk-sync": { - "version": "0.1.3", - "from": "walk-sync@0.1.3" - } - } - }, - "broccoli-funnel": { - "version": "1.0.3", - "from": "broccoli-funnel@1.0.3" - }, - "broccoli-funnel-reducer": { - "version": "1.0.0", - "from": "broccoli-funnel-reducer@1.0.0" - }, - "broccoli-kitchen-sink-helpers": { - "version": "0.3.1", - "from": "broccoli-kitchen-sink-helpers@0.3.1", - "dependencies": { - "glob": { - "version": "5.0.15", - "from": "glob@5.0.15" - } - } - }, - "broccoli-merge-trees": { - "version": "1.1.2", - "from": "broccoli-merge-trees@1.1.2" - }, - "broccoli-persistent-filter": { - "version": "1.2.6", - "from": "broccoli-persistent-filter@1.2.6" - }, - "broccoli-plugin": { - "version": "1.1.0", - "from": "broccoli-plugin@1.1.0" - }, - "broccoli-sane-watcher": { - "version": "1.1.4", - "from": "broccoli-sane-watcher@1.1.4", - "dependencies": { - "broccoli-slow-trees": { - "version": "1.1.0", - "from": "broccoli-slow-trees@1.1.0" - } - } - }, - "broccoli-slow-trees": { - "version": "2.0.0", - "from": "broccoli-slow-trees@2.0.0" - }, - "broccoli-source": { - "version": "1.1.0", - "from": "broccoli-source@1.1.0" - }, - "broccoli-uglify-js": { - "version": "0.1.3", - "from": "broccoli-uglify-js@0.1.3", - "dependencies": { - "async": { - "version": "0.2.10", - "from": "async@0.2.10" - }, - "source-map": { - "version": "0.1.34", - "from": "source-map@0.1.34" - }, - "uglify-js": { - "version": "2.4.24", - "from": "uglify-js@2.4.24" - }, - "wordwrap": { - "version": "0.0.2", - "from": "wordwrap@0.0.2" - }, - "yargs": { - "version": "3.5.4", - "from": "yargs@3.5.4" - } - } - }, - "broccoli-viz": { - "version": "2.0.1", - "from": "broccoli-viz@2.0.1" - }, - "broccoli-writer": { - "version": "0.1.1", - "from": "broccoli-writer@0.1.1" - }, - "bser": { - "version": "1.0.2", - "from": "bser@1.0.2" - }, - "buffer-shims": { - "version": "1.0.0", - "from": "buffer-shims@1.0.0" - }, - "builtin-modules": { - "version": "1.1.1", - "from": "builtin-modules@1.1.1" - }, - "bytes": { - "version": "2.3.0", - "from": "bytes@2.3.0" - }, - "caller-path": { - "version": "0.1.0", - "from": "caller-path@0.1.0" - }, - "callsite": { - "version": "1.0.0", - "from": "callsite@1.0.0" - }, - "callsites": { - "version": "0.2.0", - "from": "callsites@0.2.0" - }, - "camelcase": { - "version": "1.2.1", - "from": "camelcase@1.2.1" - }, - "camelcase-keys": { - "version": "2.1.0", - "from": "camelcase-keys@2.1.0", - "dependencies": { - "camelcase": { - "version": "2.1.1", - "from": "camelcase@2.1.1" - } - } - }, - "can-symlink": { - "version": "1.0.0", - "from": "can-symlink@1.0.0" - }, - "capture-stack-trace": { - "version": "1.0.0", - "from": "capture-stack-trace@1.0.0" - }, - "cardinal": { - "version": "0.5.0", - "from": "cardinal@0.5.0" - }, - "caseless": { - "version": "0.11.0", - "from": "caseless@0.11.0" - }, - "center-align": { - "version": "0.1.3", - "from": "center-align@0.1.3" - }, - "chalk": { - "version": "1.1.3", - "from": "chalk@1.1.3", - "dependencies": { - "ansi-regex": { - "version": "2.0.0", - "from": "ansi-regex@2.0.0" - }, - "ansi-styles": { - "version": "2.2.1", - "from": "ansi-styles@2.2.1" - }, - "has-ansi": { - "version": "2.0.0", - "from": "has-ansi@2.0.0" - }, - "strip-ansi": { - "version": "3.0.1", - "from": "strip-ansi@3.0.1" - }, - "supports-color": { - "version": "2.0.0", - "from": "supports-color@2.0.0" - } - } - }, - "charm": { - "version": "1.0.1", - "from": "charm@1.0.1" - }, - "clean-base-url": { - "version": "1.0.0", - "from": "clean-base-url@1.0.0" - }, - "clean-css": { - "version": "3.4.18", - "from": "clean-css@3.4.18", - "dependencies": { - "commander": { - "version": "2.8.1", - "from": "commander@2.8.1" - } - } - }, - "clean-css-promise": { - "version": "0.1.1", - "from": "clean-css-promise@0.1.1" - }, - "cli-cursor": { - "version": "1.0.2", - "from": "cli-cursor@1.0.2" - }, - "cli-spinners": { - "version": "0.1.2", - "from": "cli-spinners@0.1.2" - }, - "cli-table": { - "version": "0.3.1", - "from": "cli-table@0.3.1", - "dependencies": { - "colors": { - "version": "1.0.3", - "from": "colors@1.0.3" - } - } - }, - "cli-usage": { - "version": "0.1.2", - "from": "cli-usage@0.1.2", - "dependencies": { - "minimist": { - "version": "0.2.0", - "from": "minimist@0.2.0" - } - } - }, - "cli-width": { - "version": "2.1.0", - "from": "cli-width@2.1.0" - }, - "cliui": { - "version": "2.1.0", - "from": "cliui@2.1.0", - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "from": "wordwrap@0.0.2" - } - } - }, - "clone": { - "version": "0.2.0", - "from": "clone@0.2.0" - }, - "code-point-at": { - "version": "1.0.0", - "from": "code-point-at@1.0.0" - }, - "colors": { - "version": "0.6.2", - "from": "colors@0.6.2" - }, - "columnify": { - "version": "1.5.4", - "from": "columnify@1.5.4", - "dependencies": { - "ansi-regex": { - "version": "2.0.0", - "from": "ansi-regex@2.0.0" - }, - "strip-ansi": { - "version": "3.0.1", - "from": "strip-ansi@3.0.1" - } - } - }, - "combined-stream": { - "version": "1.0.5", - "from": "combined-stream@1.0.5" - }, - "commander": { - "version": "2.9.0", - "from": "commander@2.9.0" - }, - "commoner": { - "version": "0.10.4", - "from": "commoner@0.10.4", - "dependencies": { - "glob": { - "version": "5.0.15", - "from": "glob@5.0.15" - } - } - }, - "compare-func": { - "version": "1.3.2", - "from": "compare-func@1.3.2", - "dependencies": { - "dot-prop": { - "version": "3.0.0", - "from": "dot-prop@3.0.0" - } - } - }, - "component-bind": { - "version": "1.0.0", - "from": "component-bind@1.0.0" - }, - "component-emitter": { - "version": "1.1.2", - "from": "component-emitter@1.1.2" - }, - "component-inherit": { - "version": "0.0.3", - "from": "component-inherit@0.0.3" - }, - "compressible": { - "version": "2.0.8", - "from": "compressible@2.0.8" - }, - "compression": { - "version": "1.6.2", - "from": "compression@1.6.2" - }, - "concat-map": { - "version": "0.0.1", - "from": "concat-map@0.0.1" - }, - "concat-stream": { - "version": "1.5.1", - "from": "concat-stream@1.5.1", - "dependencies": { - "isarray": { - "version": "1.0.0", - "from": "isarray@1.0.0" - }, - "readable-stream": { - "version": "2.0.6", - "from": "readable-stream@2.0.6" - } - } - }, - "configstore": { - "version": "2.0.0", - "from": "configstore@2.0.0" - }, - "connect": { - "version": "3.4.1", - "from": "connect@3.4.1" - }, - "consolidate": { - "version": "0.14.1", - "from": "consolidate@0.14.1", - "dependencies": { - "bluebird": { - "version": "3.4.1", - "from": "bluebird@3.4.1" - } - } - }, - "content-disposition": { - "version": "0.5.1", - "from": "content-disposition@0.5.1" - }, - "content-type": { - "version": "1.0.2", - "from": "content-type@1.0.2" - }, - "conventional-changelog-angular": { - "version": "1.2.0", - "from": "conventional-changelog-angular@1.2.0" - }, - "conventional-changelog-atom": { - "version": "0.1.0", - "from": "conventional-changelog-atom@0.1.0" - }, - "conventional-changelog-codemirror": { - "version": "0.1.0", - "from": "conventional-changelog-codemirror@0.1.0" - }, - "conventional-changelog-core": { - "version": "1.5.0", - "from": "conventional-changelog-core@1.5.0" - }, - "conventional-changelog-ember": { - "version": "0.2.2", - "from": "conventional-changelog-ember@0.2.2" - }, - "conventional-changelog-eslint": { - "version": "0.1.0", - "from": "conventional-changelog-eslint@0.1.0" - }, - "conventional-changelog-express": { - "version": "0.1.0", - "from": "conventional-changelog-express@0.1.0" - }, - "conventional-changelog-jquery": { - "version": "0.1.0", - "from": "conventional-changelog-jquery@0.1.0" - }, - "conventional-changelog-jscs": { - "version": "0.1.0", - "from": "conventional-changelog-jscs@0.1.0" - }, - "conventional-changelog-jshint": { - "version": "0.1.0", - "from": "conventional-changelog-jshint@0.1.0" - }, - "conventional-changelog-writer": { - "version": "1.4.1", - "from": "conventional-changelog-writer@1.4.1" - }, - "conventional-commits-filter": { - "version": "1.0.0", - "from": "conventional-commits-filter@1.0.0" - }, - "conventional-commits-parser": { - "version": "1.2.2", - "from": "conventional-commits-parser@1.2.2" - }, - "convert-source-map": { - "version": "1.2.0", - "from": "convert-source-map@1.2.0" - }, - "cookie": { - "version": "0.3.1", - "from": "cookie@0.3.1" - }, - "cookie-signature": { - "version": "1.0.6", - "from": "cookie-signature@1.0.6" - }, - "copy-dereference": { - "version": "1.0.0", - "from": "copy-dereference@1.0.0" - }, - "core-js": { - "version": "1.2.6", - "from": "core-js@1.2.6" - }, - "core-object": { - "version": "0.0.2", - "from": "core-object@0.0.2" - }, - "core-util-is": { - "version": "1.0.2", - "from": "core-util-is@1.0.2" - }, - "cpr": { - "version": "0.4.2", - "from": "cpr@0.4.2", - "dependencies": { - "glob": { - "version": "6.0.4", - "from": "glob@6.0.4" - }, - "rimraf": { - "version": "2.4.5", - "from": "rimraf@2.4.5" - } - } - }, - "create-error-class": { - "version": "3.0.2", - "from": "create-error-class@3.0.2" - }, - "cross-spawn": { - "version": "4.0.0", - "from": "cross-spawn@4.0.0" - }, - "cryptiles": { - "version": "2.0.5", - "from": "cryptiles@2.0.5" - }, - "currently-unhandled": { - "version": "0.4.1", - "from": "currently-unhandled@0.4.1" - }, - "d": { - "version": "0.1.1", - "from": "d@0.1.1" - }, - "dargs": { - "version": "4.1.0", - "from": "dargs@4.1.0" - }, - "dashdash": { - "version": "1.14.0", - "from": "dashdash@1.14.0", - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "from": "assert-plus@1.0.0" - } - } - }, - "data-uri-to-buffer": { - "version": "0.0.4", - "from": "data-uri-to-buffer@0.0.4" - }, - "dateformat": { - "version": "1.0.12", - "from": "dateformat@1.0.12" - }, - "debug": { - "version": "2.2.0", - "from": "debug@2.2.0" - }, - "decamelize": { - "version": "1.2.0", - "from": "decamelize@1.2.0" - }, - "deep-eql": { - "version": "0.1.3", - "from": "deep-eql@0.1.3", - "dependencies": { - "type-detect": { - "version": "0.1.1", - "from": "type-detect@0.1.1" - } - } - }, - "deep-extend": { - "version": "0.4.1", - "from": "deep-extend@0.4.1" - }, - "deep-is": { - "version": "0.1.3", - "from": "deep-is@0.1.3" - }, - "defaults": { - "version": "1.0.3", - "from": "defaults@1.0.3", - "dependencies": { - "clone": { - "version": "1.0.2", - "from": "clone@1.0.2" - } - } - }, - "defined": { - "version": "1.0.0", - "from": "defined@1.0.0" - }, - "defs": { - "version": "1.1.1", - "from": "defs@1.1.1", - "dependencies": { - "window-size": { - "version": "0.1.4", - "from": "window-size@0.1.4" - }, - "yargs": { - "version": "3.27.0", - "from": "yargs@3.27.0" - } - } - }, - "del": { - "version": "2.2.1", - "from": "del@2.2.1" - }, - "delayed-stream": { - "version": "1.0.0", - "from": "delayed-stream@1.0.0" - }, - "delegates": { - "version": "1.0.0", - "from": "delegates@1.0.0" - }, - "depd": { - "version": "1.1.0", - "from": "depd@1.1.0" - }, - "destroy": { - "version": "1.0.4", - "from": "destroy@1.0.4" - }, - "detect-indent": { - "version": "3.0.1", - "from": "detect-indent@3.0.1", - "dependencies": { - "minimist": { - "version": "1.2.0", - "from": "minimist@1.2.0" - } - } - }, - "detective": { - "version": "4.3.1", - "from": "detective@4.3.1" - }, - "did_it_work": { - "version": "0.0.6", - "from": "did_it_work@0.0.6" - }, - "diff": { - "version": "2.2.3", - "from": "diff@2.2.3" - }, - "doctrine": { - "version": "1.2.2", - "from": "doctrine@1.2.2", - "dependencies": { - "esutils": { - "version": "1.1.6", - "from": "esutils@1.1.6" - }, - "isarray": { - "version": "1.0.0", - "from": "isarray@1.0.0" - } - } - }, - "dot-prop": { - "version": "2.4.0", - "from": "dot-prop@2.4.0" - }, - "duplexer2": { - "version": "0.1.4", - "from": "duplexer2@0.1.4", - "dependencies": { - "isarray": { - "version": "1.0.0", - "from": "isarray@1.0.0" - }, - "readable-stream": { - "version": "2.1.4", - "from": "readable-stream@2.1.4" - } - } - }, - "ecc-jsbn": { - "version": "0.1.1", - "from": "ecc-jsbn@0.1.1" - }, - "editions": { - "version": "1.1.2", - "from": "editions@1.1.2" - }, - "ee-first": { - "version": "1.1.1", - "from": "ee-first@1.1.1" - }, - "ember-cli": { - "version": "2.5.0", - "from": "ember-cli@2.5.0", - "dependencies": { - "broccoli-plugin": { - "version": "1.2.1", - "from": "broccoli-plugin@1.2.1" - }, - "fs-extra": { - "version": "0.26.7", - "from": "fs-extra@0.26.7" - }, - "fs-tree-diff": { - "version": "0.4.4", - "from": "fs-tree-diff@0.4.4" - }, - "glob": { - "version": "7.0.3", - "from": "glob@7.0.3" - }, - "npm": { - "version": "2.14.21", - "from": "npm@2.14.21", - "dependencies": { - "abbrev": { - "version": "1.0.7", - "from": "abbrev@>=1.0.7 <1.1.0" - }, - "ansi": { - "version": "0.3.1", - "from": "ansi@latest" - }, - "ansi-regex": { - "version": "2.0.0", - "from": "ansi-regex@2.0.0" - }, - "ansicolors": { - "version": "0.3.2", - "from": "ansicolors@latest" - }, - "ansistyles": { - "version": "0.1.3", - "from": "ansistyles@0.1.3" - }, - "archy": { - "version": "1.0.0", - "from": "archy@>=1.0.0 <2.0.0" - }, - "async-some": { - "version": "1.0.2", - "from": "async-some@>=1.0.2 <1.1.0" - }, - "block-stream": { - "version": "0.0.8", - "from": "block-stream@0.0.8" - }, - "char-spinner": { - "version": "1.0.1", - "from": "char-spinner@latest" - }, - "chmodr": { - "version": "1.0.2", - "from": "chmodr@>=1.0.2 <1.1.0" - }, - "chownr": { - "version": "1.0.1", - "from": "chownr@1.0.1" - }, - "cmd-shim": { - "version": "2.0.2", - "from": "cmd-shim@2.0.2" - }, - "columnify": { - "version": "1.5.4", - "from": "columnify@latest", - "dependencies": { - "wcwidth": { - "version": "1.0.0", - "from": "wcwidth@>=1.0.0 <2.0.0", - "dependencies": { - "defaults": { - "version": "1.0.3", - "from": "defaults@>=1.0.0 <2.0.0", - "dependencies": { - "clone": { - "version": "1.0.2", - "from": "clone@>=1.0.2 <2.0.0" - } - } - } - } - } - } - }, - "config-chain": { - "version": "1.1.10", - "from": "config-chain@latest", - "dependencies": { - "proto-list": { - "version": "1.2.4", - "from": "proto-list@>=1.2.1 <1.3.0" - } - } - }, - "dezalgo": { - "version": "1.0.3", - "from": "dezalgo@>=1.0.3 <1.1.0", - "dependencies": { - "asap": { - "version": "2.0.3", - "from": "asap@>=2.0.0 <3.0.0" - } - } - }, - "editor": { - "version": "1.0.0", - "from": "editor@>=1.0.0 <1.1.0" - }, - "fs-vacuum": { - "version": "1.2.7", - "from": "fs-vacuum@1.2.7" - }, - "fs-write-stream-atomic": { - "version": "1.0.8", - "from": "fs-write-stream-atomic@>=1.0.5 <1.1.0", - "dependencies": { - "iferr": { - "version": "0.1.5", - "from": "iferr@>=0.1.5 <0.2.0" - } - } - }, - "fstream": { - "version": "1.0.8", - "from": "fstream@1.0.8" - }, - "fstream-npm": { - "version": "1.0.7", - "from": "fstream-npm@>=1.0.7 <1.1.0", - "dependencies": { - "fstream-ignore": { - "version": "1.0.3", - "from": "fstream-ignore@>=1.0.0 <2.0.0" - } - } - }, - "github-url-from-git": { - "version": "1.4.0", - "from": "github-url-from-git@>=1.4.0-0 <2.0.0-0" - }, - "github-url-from-username-repo": { - "version": "1.0.2", - "from": "github-url-from-username-repo@>=1.0.2-0 <2.0.0-0" - }, - "glob": { - "version": "5.0.15", - "from": "glob@5.0.15", - "dependencies": { - "path-is-absolute": { - "version": "1.0.0", - "from": "path-is-absolute@>=1.0.0 <2.0.0" - } - } - }, - "graceful-fs": { - "version": "4.1.3", - "from": "graceful-fs@latest" - }, - "hosted-git-info": { - "version": "2.1.4", - "from": "hosted-git-info@>=2.1.2 <2.2.0" - }, - "imurmurhash": { - "version": "0.1.4", - "from": "imurmurhash@0.1.4" - }, - "inflight": { - "version": "1.0.4", - "from": "inflight@>=1.0.4 <1.1.0" - }, - "inherits": { - "version": "2.0.1", - "from": "inherits@latest" - }, - "ini": { - "version": "1.3.4", - "from": "ini@latest" - }, - "init-package-json": { - "version": "1.9.3", - "from": "init-package-json@1.9.3", - "dependencies": { - "glob": { - "version": "6.0.4", - "from": "glob@>=6.0.0 <7.0.0", - "dependencies": { - "path-is-absolute": { - "version": "1.0.0", - "from": "path-is-absolute@>=1.0.0 <2.0.0" - } - } - }, - "promzard": { - "version": "0.3.0", - "from": "promzard@>=0.3.0 <0.4.0" - } - } - }, - "lockfile": { - "version": "1.0.1", - "from": "lockfile@>=1.0.0 <1.1.0" - }, - "lru-cache": { - "version": "3.2.0", - "from": "lru-cache@>=3.2.0 <3.3.0", - "dependencies": { - "pseudomap": { - "version": "1.0.1", - "from": "pseudomap@>=1.0.1 <2.0.0" - } - } - }, - "minimatch": { - "version": "3.0.0", - "from": "minimatch@>=3.0.0 <3.1.0", - "dependencies": { - "brace-expansion": { - "version": "1.1.1", - "from": "brace-expansion@>=1.0.0 <2.0.0", - "dependencies": { - "balanced-match": { - "version": "0.2.1", - "from": "balanced-match@>=0.2.0 <0.3.0" - }, - "concat-map": { - "version": "0.0.1", - "from": "concat-map@0.0.1" - } - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "from": "mkdirp@>=0.5.1 <0.6.0", - "dependencies": { - "minimist": { - "version": "0.0.8", - "from": "minimist@0.0.8" - } - } - }, - "node-gyp": { - "version": "3.3.0", - "from": "node-gyp@3.3.0", - "dependencies": { - "glob": { - "version": "4.5.3", - "from": "glob@>=3.0.0 <4.0.0||>=4.0.0 <5.0.0", - "dependencies": { - "minimatch": { - "version": "2.0.10", - "from": "minimatch@>=2.0.1 <3.0.0", - "dependencies": { - "brace-expansion": { - "version": "1.1.3", - "from": "brace-expansion@>=1.0.0 <2.0.0", - "dependencies": { - "balanced-match": { - "version": "0.3.0", - "from": "balanced-match@>=0.3.0 <0.4.0" - }, - "concat-map": { - "version": "0.0.1", - "from": "concat-map@0.0.1" - } - } - } - } - } - } - }, - "minimatch": { - "version": "1.0.0", - "from": "minimatch@>=1.0.0 <2.0.0", - "dependencies": { - "lru-cache": { - "version": "2.7.3", - "from": "lru-cache@>=2.0.0 <3.0.0" - }, - "sigmund": { - "version": "1.0.1", - "from": "sigmund@>=1.0.0 <1.1.0" - } - } - }, - "path-array": { - "version": "1.0.1", - "from": "path-array@>=1.0.0 <2.0.0", - "dependencies": { - "array-index": { - "version": "1.0.0", - "from": "array-index@>=1.0.0 <2.0.0", - "dependencies": { - "debug": { - "version": "2.2.0", - "from": "debug@>=2.2.0 <3.0.0", - "dependencies": { - "ms": { - "version": "0.7.1", - "from": "ms@0.7.1" - } - } - }, - "es6-symbol": { - "version": "3.0.2", - "from": "es6-symbol@>=3.0.2 <4.0.0", - "dependencies": { - "d": { - "version": "0.1.1", - "from": "d@>=0.1.1 <0.2.0" - }, - "es5-ext": { - "version": "0.10.11", - "from": "es5-ext@>=0.10.10 <0.11.0", - "dependencies": { - "es6-iterator": { - "version": "2.0.0", - "from": "es6-iterator@>=2.0.0 <3.0.0" - } - } - } - } - } - } - } - } - } - } - }, - "nopt": { - "version": "3.0.6", - "from": "nopt@>=3.0.6 <3.1.0" - }, - "normalize-git-url": { - "version": "3.0.1", - "from": "normalize-git-url@latest" - }, - "normalize-package-data": { - "version": "2.3.5", - "from": "normalize-package-data@>=2.3.5 <2.4.0", - "dependencies": { - "is-builtin-module": { - "version": "1.0.0", - "from": "is-builtin-module@>=1.0.0 <2.0.0", - "dependencies": { - "builtin-modules": { - "version": "1.1.0", - "from": "builtin-modules@>=1.0.0 <2.0.0" - } - } - } - } - }, - "npm-cache-filename": { - "version": "1.0.2", - "from": "npm-cache-filename@1.0.2" - }, - "npm-install-checks": { - "version": "1.0.7", - "from": "npm-install-checks@1.0.7" - }, - "npm-package-arg": { - "version": "4.1.0", - "from": "npm-package-arg@>=4.1.0 <4.2.0" - }, - "npm-registry-client": { - "version": "7.0.9", - "from": "npm-registry-client@>=7.0.9 <7.1.0", - "dependencies": { - "concat-stream": { - "version": "1.5.1", - "from": "concat-stream@>=1.4.6 <2.0.0", - "dependencies": { - "readable-stream": { - "version": "2.0.4", - "from": "readable-stream@>=2.0.0 <2.1.0", - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "from": "core-util-is@>=1.0.0 <1.1.0" - }, - "isarray": { - "version": "0.0.1", - "from": "isarray@0.0.1" - }, - "process-nextick-args": { - "version": "1.0.6", - "from": "process-nextick-args@>=1.0.0 <1.1.0" - }, - "string_decoder": { - "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0" - }, - "util-deprecate": { - "version": "1.0.2", - "from": "util-deprecate@>=1.0.1 <1.1.0" - } - } - }, - "typedarray": { - "version": "0.0.6", - "from": "typedarray@>=0.0.5 <0.1.0" - } - } - }, - "retry": { - "version": "0.8.0", - "from": "retry@>=0.8.0 <0.9.0" - } - } - }, - "npm-user-validate": { - "version": "0.1.2", - "from": "npm-user-validate@>=0.1.1 <0.2.0" - }, - "npmlog": { - "version": "2.0.2", - "from": "npmlog@2.0.2", - "dependencies": { - "are-we-there-yet": { - "version": "1.0.6", - "from": "are-we-there-yet@>=1.0.6 <1.1.0", - "dependencies": { - "delegates": { - "version": "1.0.0", - "from": "delegates@>=1.0.0 <2.0.0" - } - } - }, - "gauge": { - "version": "1.2.5", - "from": "gauge@>=1.2.5 <1.3.0", - "dependencies": { - "has-unicode": { - "version": "2.0.0", - "from": "has-unicode@>=2.0.0 <3.0.0" - }, - "lodash._basetostring": { - "version": "3.0.1", - "from": "lodash._basetostring@3.0.1" - }, - "lodash._createpadding": { - "version": "3.6.1", - "from": "lodash._createpadding@3.6.1" - }, - "lodash.pad": { - "version": "3.2.2", - "from": "lodash.pad@>=3.0.0 <4.0.0" - }, - "lodash.padleft": { - "version": "3.1.1", - "from": "lodash.padleft@>=3.0.0 <4.0.0" - }, - "lodash.padright": { - "version": "3.1.1", - "from": "lodash.padright@>=3.0.0 <4.0.0" - }, - "lodash.repeat": { - "version": "3.2.0", - "from": "lodash.repeat@3.2.0", - "dependencies": { - "lodash._root": { - "version": "3.0.1", - "from": "lodash._root@>=3.0.0 <4.0.0" - } - } - } - } - } - } - }, - "once": { - "version": "1.3.3", - "from": "once@>=1.3.3 <1.4.0" - }, - "opener": { - "version": "1.4.1", - "from": "opener@>=1.4.1 <1.5.0" - }, - "osenv": { - "version": "0.1.3", - "from": "osenv@0.1.3", - "dependencies": { - "os-homedir": { - "version": "1.0.0", - "from": "os-homedir@>=1.0.0 <2.0.0" - }, - "os-tmpdir": { - "version": "1.0.1", - "from": "os-tmpdir@>=1.0.0 <2.0.0" - } - } - }, - "path-is-inside": { - "version": "1.0.1", - "from": "path-is-inside@1.0.1" - }, - "read": { - "version": "1.0.7", - "from": "read@1.0.7", - "dependencies": { - "mute-stream": { - "version": "0.0.5", - "from": "mute-stream@>=0.0.4 <0.1.0" - } - } - }, - "read-installed": { - "version": "4.0.3", - "from": "read-installed@4.0.3", - "dependencies": { - "debuglog": { - "version": "1.0.1", - "from": "debuglog@>=1.0.1 <2.0.0" - }, - "readdir-scoped-modules": { - "version": "1.0.2", - "from": "readdir-scoped-modules@>=1.0.0 <2.0.0" - }, - "util-extend": { - "version": "1.0.1", - "from": "util-extend@>=1.0.1 <2.0.0" - } - } - }, - "read-package-json": { - "version": "2.0.3", - "from": "read-package-json@2.0.3", - "dependencies": { - "glob": { - "version": "6.0.4", - "from": "glob@>=6.0.0 <7.0.0", - "dependencies": { - "path-is-absolute": { - "version": "1.0.0", - "from": "path-is-absolute@>=1.0.0 <2.0.0" - } - } - }, - "json-parse-helpfulerror": { - "version": "1.0.3", - "from": "json-parse-helpfulerror@>=1.0.2 <2.0.0", - "dependencies": { - "jju": { - "version": "1.2.1", - "from": "jju@>=1.1.0 <2.0.0" - } - } - } - } - }, - "readable-stream": { - "version": "1.1.13", - "from": "readable-stream@>=1.1.13 <1.2.0", - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "from": "core-util-is@>=1.0.0 <1.1.0" - }, - "isarray": { - "version": "0.0.1", - "from": "isarray@0.0.1" - }, - "string_decoder": { - "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0" - } - } - }, - "realize-package-specifier": { - "version": "3.0.1", - "from": "realize-package-specifier@>=3.0.0 <3.1.0" - }, - "request": { - "version": "2.69.0", - "from": "request@2.69.0", - "dependencies": { - "aws-sign2": { - "version": "0.6.0", - "from": "aws-sign2@>=0.6.0 <0.7.0" - }, - "aws4": { - "version": "1.2.1", - "from": "aws4@>=1.2.1 <2.0.0", - "dependencies": { - "lru-cache": { - "version": "2.7.3", - "from": "lru-cache@>=2.6.5 <3.0.0" - } - } - }, - "bl": { - "version": "1.0.2", - "from": "bl@>=1.0.0 <1.1.0", - "dependencies": { - "readable-stream": { - "version": "2.0.5", - "from": "readable-stream@>=2.0.5 <2.1.0", - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "from": "core-util-is@>=1.0.0 <1.1.0" - }, - "isarray": { - "version": "0.0.1", - "from": "isarray@0.0.1" - }, - "process-nextick-args": { - "version": "1.0.6", - "from": "process-nextick-args@>=1.0.6 <1.1.0" - }, - "string_decoder": { - "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0" - }, - "util-deprecate": { - "version": "1.0.2", - "from": "util-deprecate@>=1.0.1 <1.1.0" - } - } - } - } - }, - "caseless": { - "version": "0.11.0", - "from": "caseless@>=0.11.0 <0.12.0" - }, - "combined-stream": { - "version": "1.0.5", - "from": "combined-stream@>=1.0.5 <1.1.0", - "dependencies": { - "delayed-stream": { - "version": "1.0.0", - "from": "delayed-stream@>=1.0.0 <1.1.0" - } - } - }, - "extend": { - "version": "3.0.0", - "from": "extend@>=3.0.0 <3.1.0" - }, - "forever-agent": { - "version": "0.6.1", - "from": "forever-agent@>=0.6.1 <0.7.0" - }, - "form-data": { - "version": "1.0.0-rc3", - "from": "form-data@>=1.0.0-rc3 <1.1.0", - "dependencies": { - "async": { - "version": "1.5.2", - "from": "async@>=1.4.0 <2.0.0" - } - } - }, - "har-validator": { - "version": "2.0.6", - "from": "har-validator@>=2.0.6 <2.1.0", - "dependencies": { - "chalk": { - "version": "1.1.1", - "from": "chalk@>=1.1.1 <2.0.0", - "dependencies": { - "ansi-styles": { - "version": "2.1.0", - "from": "ansi-styles@>=2.1.0 <3.0.0" - }, - "escape-string-regexp": { - "version": "1.0.4", - "from": "escape-string-regexp@>=1.0.2 <2.0.0" - }, - "has-ansi": { - "version": "2.0.0", - "from": "has-ansi@>=2.0.0 <3.0.0" - }, - "supports-color": { - "version": "2.0.0", - "from": "supports-color@>=2.0.0 <3.0.0" - } - } - }, - "commander": { - "version": "2.9.0", - "from": "commander@>=2.9.0 <3.0.0", - "dependencies": { - "graceful-readlink": { - "version": "1.0.1", - "from": "graceful-readlink@>=1.0.0" - } - } - }, - "is-my-json-valid": { - "version": "2.12.4", - "from": "is-my-json-valid@>=2.12.4 <3.0.0", - "dependencies": { - "generate-function": { - "version": "2.0.0", - "from": "generate-function@>=2.0.0 <3.0.0" - }, - "generate-object-property": { - "version": "1.2.0", - "from": "generate-object-property@>=1.1.0 <2.0.0", - "dependencies": { - "is-property": { - "version": "1.0.2", - "from": "is-property@>=1.0.0 <2.0.0" - } - } - }, - "jsonpointer": { - "version": "2.0.0", - "from": "jsonpointer@2.0.0" - }, - "xtend": { - "version": "4.0.1", - "from": "xtend@>=4.0.0 <5.0.0" - } - } - }, - "pinkie-promise": { - "version": "2.0.0", - "from": "pinkie-promise@>=2.0.0 <3.0.0", - "dependencies": { - "pinkie": { - "version": "2.0.4", - "from": "pinkie@>=2.0.0 <3.0.0" - } - } - } - } - }, - "hawk": { - "version": "3.1.3", - "from": "hawk@>=3.1.0 <3.2.0", - "dependencies": { - "boom": { - "version": "2.10.1", - "from": "boom@>=2.0.0 <3.0.0" - }, - "cryptiles": { - "version": "2.0.5", - "from": "cryptiles@>=2.0.0 <3.0.0" - }, - "hoek": { - "version": "2.16.3", - "from": "hoek@>=2.0.0 <3.0.0" - }, - "sntp": { - "version": "1.0.9", - "from": "sntp@>=1.0.0 <2.0.0" - } - } - }, - "http-signature": { - "version": "1.1.1", - "from": "http-signature@>=1.1.0 <1.2.0", - "dependencies": { - "assert-plus": { - "version": "0.2.0", - "from": "assert-plus@>=0.2.0 <0.3.0" - }, - "jsprim": { - "version": "1.2.2", - "from": "jsprim@>=1.2.2 <2.0.0", - "dependencies": { - "extsprintf": { - "version": "1.0.2", - "from": "extsprintf@1.0.2" - }, - "json-schema": { - "version": "0.2.2", - "from": "json-schema@0.2.2" - }, - "verror": { - "version": "1.3.6", - "from": "verror@1.3.6" - } - } - }, - "sshpk": { - "version": "1.7.3", - "from": "sshpk@>=1.7.0 <2.0.0", - "dependencies": { - "asn1": { - "version": "0.2.3", - "from": "asn1@>=0.2.3 <0.3.0" - }, - "dashdash": { - "version": "1.12.2", - "from": "dashdash@>=1.10.1 <2.0.0" - }, - "ecc-jsbn": { - "version": "0.1.1", - "from": "ecc-jsbn@>=0.0.1 <1.0.0" - }, - "jodid25519": { - "version": "1.0.2", - "from": "jodid25519@>=1.0.0 <2.0.0" - }, - "jsbn": { - "version": "0.1.0", - "from": "jsbn@>=0.1.0 <0.2.0" - }, - "tweetnacl": { - "version": "0.13.3", - "from": "tweetnacl@>=0.13.0 <1.0.0" - } - } - } - } - }, - "is-typedarray": { - "version": "1.0.0", - "from": "is-typedarray@>=1.0.0 <1.1.0" - }, - "isstream": { - "version": "0.1.2", - "from": "isstream@>=0.1.2 <0.2.0" - }, - "json-stringify-safe": { - "version": "5.0.1", - "from": "json-stringify-safe@>=5.0.1 <5.1.0" - }, - "mime-types": { - "version": "2.1.9", - "from": "mime-types@>=2.1.7 <2.2.0", - "dependencies": { - "mime-db": { - "version": "1.21.0", - "from": "mime-db@>=1.21.0 <1.22.0" - } - } - }, - "node-uuid": { - "version": "1.4.7", - "from": "node-uuid@>=1.4.7 <1.5.0" - }, - "oauth-sign": { - "version": "0.8.1", - "from": "oauth-sign@>=0.8.0 <0.9.0" - }, - "qs": { - "version": "6.0.2", - "from": "qs@>=6.0.2 <6.1.0" - }, - "stringstream": { - "version": "0.0.5", - "from": "stringstream@>=0.0.4 <0.1.0" - }, - "tough-cookie": { - "version": "2.2.1", - "from": "tough-cookie@>=2.2.0 <2.3.0" - }, - "tunnel-agent": { - "version": "0.4.2", - "from": "tunnel-agent@>=0.4.1 <0.5.0" - } - } - }, - "retry": { - "version": "0.9.0", - "from": "retry@0.9.0" - }, - "rimraf": { - "version": "2.5.2", - "from": "rimraf@2.5.2", - "dependencies": { - "glob": { - "version": "7.0.0", - "from": "glob@>=7.0.0 <8.0.0", - "dependencies": { - "path-is-absolute": { - "version": "1.0.0", - "from": "path-is-absolute@>=1.0.0 <2.0.0" - } - } - } - } - }, - "semver": { - "version": "5.1.0", - "from": "semver@>=5.1.0 <5.2.0" - }, - "sha": { - "version": "2.0.1", - "from": "sha@2.0.1", - "dependencies": { - "readable-stream": { - "version": "2.0.2", - "from": "readable-stream@>=2.0.2 <3.0.0", - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "from": "core-util-is@>=1.0.0 <1.1.0" - }, - "isarray": { - "version": "0.0.1", - "from": "isarray@0.0.1" - }, - "process-nextick-args": { - "version": "1.0.3", - "from": "process-nextick-args@>=1.0.0 <1.1.0" - }, - "string_decoder": { - "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0" - }, - "util-deprecate": { - "version": "1.0.1", - "from": "util-deprecate@>=1.0.1 <1.1.0" - } - } - } - } - }, - "slide": { - "version": "1.1.6", - "from": "slide@>=1.1.6 <1.2.0" - }, - "sorted-object": { - "version": "1.0.0", - "from": "sorted-object@" - }, - "spdx-license-ids": { - "version": "1.2.0", - "from": "spdx-license-ids@1.2.0" - }, - "strip-ansi": { - "version": "3.0.0", - "from": "strip-ansi@3.0.0" - }, - "tar": { - "version": "2.2.1", - "from": "tar@2.2.1" - }, - "text-table": { - "version": "0.2.0", - "from": "text-table@~0.2.0" - }, - "uid-number": { - "version": "0.0.6", - "from": "uid-number@>=0.0.6 <0.1.0" - }, - "umask": { - "version": "1.1.0", - "from": "umask@>=1.1.0 <1.2.0" - }, - "validate-npm-package-license": { - "version": "3.0.1", - "from": "validate-npm-package-license@>=3.0.1 <3.1.0", - "dependencies": { - "spdx-correct": { - "version": "1.0.2", - "from": "spdx-correct@>=1.0.0 <1.1.0" - }, - "spdx-expression-parse": { - "version": "1.0.2", - "from": "spdx-expression-parse@>=1.0.0 <1.1.0", - "dependencies": { - "spdx-exceptions": { - "version": "1.0.4", - "from": "spdx-exceptions@>=1.0.4 <2.0.0" - } - } - } - } - }, - "validate-npm-package-name": { - "version": "2.2.2", - "from": "validate-npm-package-name@2.2.2", - "dependencies": { - "builtins": { - "version": "0.0.7", - "from": "builtins@0.0.7" - } - } - }, - "which": { - "version": "1.2.4", - "from": "which@1.2.4", - "dependencies": { - "is-absolute": { - "version": "0.1.7", - "from": "is-absolute@>=0.1.7 <0.2.0", - "dependencies": { - "is-relative": { - "version": "0.1.3", - "from": "is-relative@>=0.1.0 <0.2.0" - } - } - }, - "isexe": { - "version": "1.1.1", - "from": "isexe@>=1.1.1 <2.0.0" - } - } - }, - "wrappy": { - "version": "1.0.1", - "from": "wrappy@1.0.1" - }, - "write-file-atomic": { - "version": "1.1.4", - "from": "write-file-atomic@>=1.1.4 <1.2.0" - } - } - } - } - }, - "ember-cli-broccoli": { - "version": "0.16.9", - "from": "ember-cli-broccoli@0.16.9", - "dependencies": { - "broccoli-kitchen-sink-helpers": { - "version": "0.2.9", - "from": "broccoli-kitchen-sink-helpers@0.2.9" - }, - "broccoli-slow-trees": { - "version": "1.1.0", - "from": "broccoli-slow-trees@1.1.0" - }, - "glob": { - "version": "5.0.15", - "from": "glob@5.0.15" - } - } - }, - "ember-cli-get-component-path-option": { - "version": "1.0.0", - "from": "ember-cli-get-component-path-option@1.0.0" - }, - "ember-cli-is-package-missing": { - "version": "1.0.0", - "from": "ember-cli-is-package-missing@1.0.0" - }, - "ember-cli-normalize-entity-name": { - "version": "1.0.0", - "from": "ember-cli-normalize-entity-name@1.0.0" - }, - "ember-cli-path-utils": { - "version": "1.0.0", - "from": "ember-cli-path-utils@1.0.0" - }, - "ember-cli-preprocess-registry": { - "version": "2.0.0", - "from": "ember-cli-preprocess-registry@2.0.0", - "dependencies": { - "lodash": { - "version": "3.10.1", - "from": "lodash@3.10.1" - } - } - }, - "ember-cli-string-utils": { - "version": "1.0.0", - "from": "ember-cli-string-utils@1.0.0" - }, - "ember-cli-test-info": { - "version": "1.0.0", - "from": "ember-cli-test-info@1.0.0" - }, - "ember-cli-valid-component-name": { - "version": "1.0.0", - "from": "ember-cli-valid-component-name@1.0.0" - }, - "ember-router-generator": { - "version": "1.2.1", - "from": "ember-router-generator@1.2.1", - "dependencies": { - "ast-types": { - "version": "0.8.17", - "from": "ast-types@0.8.17" - }, - "esprima": { - "version": "2.7.2", - "from": "esprima@2.7.2" - }, - "recast": { - "version": "0.11.10", - "from": "recast@0.11.10" - }, - "source-map": { - "version": "0.5.6", - "from": "source-map@0.5.6" - } - } - }, - "encodeurl": { - "version": "1.0.1", - "from": "encodeurl@1.0.1" - }, - "engine.io": { - "version": "1.6.11", - "from": "engine.io@1.6.11", - "dependencies": { - "accepts": { - "version": "1.1.4", - "from": "accepts@1.1.4" - }, - "mime-db": { - "version": "1.12.0", - "from": "mime-db@1.12.0" - }, - "mime-types": { - "version": "2.0.14", - "from": "mime-types@2.0.14" - }, - "negotiator": { - "version": "0.4.9", - "from": "negotiator@0.4.9" - } - } - }, - "engine.io-client": { - "version": "1.6.11", - "from": "engine.io-client@1.6.11", - "dependencies": { - "ws": { - "version": "1.0.1", - "from": "ws@1.0.1" - } - } - }, - "engine.io-parser": { - "version": "1.2.4", - "from": "engine.io-parser@1.2.4", - "dependencies": { - "has-binary": { - "version": "0.1.6", - "from": "has-binary@0.1.6" - } - } - }, - "ensure-posix-path": { - "version": "1.0.1", - "from": "ensure-posix-path@1.0.1" - }, - "entities": { - "version": "1.1.1", - "from": "entities@1.1.1" - }, - "error-ex": { - "version": "1.3.0", - "from": "error-ex@1.3.0" - }, - "es5-ext": { - "version": "0.10.12", - "from": "es5-ext@0.10.12" - }, - "es6-iterator": { - "version": "2.0.0", - "from": "es6-iterator@2.0.0" - }, - "es6-map": { - "version": "0.1.4", - "from": "es6-map@0.1.4" - }, - "es6-set": { - "version": "0.1.4", - "from": "es6-set@0.1.4" - }, - "es6-symbol": { - "version": "3.1.0", - "from": "es6-symbol@3.1.0" - }, - "es6-template-strings": { - "version": "2.0.0", - "from": "es6-template-strings@2.0.0" - }, - "es6-weak-map": { - "version": "2.0.1", - "from": "es6-weak-map@2.0.1" - }, - "escape-html": { - "version": "1.0.3", - "from": "escape-html@1.0.3" - }, - "escape-string-regexp": { - "version": "1.0.5", - "from": "escape-string-regexp@1.0.5" - }, - "escope": { - "version": "3.6.0", - "from": "escope@3.6.0" - }, - "esniff": { - "version": "1.0.0", - "from": "esniff@1.0.0" - }, - "espree": { - "version": "3.1.6", - "from": "espree@3.1.6", - "dependencies": { - "acorn": { - "version": "3.2.0", - "from": "acorn@3.2.0" - } - } - }, - "esprima-fb": { - "version": "15001.1001.0-dev-harmony-fb", - "from": "esprima-fb@15001.1001.0-dev-harmony-fb" - }, - "esrecurse": { - "version": "4.1.0", - "from": "esrecurse@4.1.0", - "dependencies": { - "estraverse": { - "version": "4.1.1", - "from": "estraverse@4.1.1" - } - } - }, - "estraverse": { - "version": "4.2.0", - "from": "estraverse@4.2.0" - }, - "esutils": { - "version": "2.0.2", - "from": "esutils@2.0.2" - }, - "etag": { - "version": "1.7.0", - "from": "etag@1.7.0" - }, - "event-emitter": { - "version": "0.3.4", - "from": "event-emitter@0.3.4" - }, - "eventemitter3": { - "version": "1.2.0", - "from": "eventemitter3@1.2.0" - }, - "events-to-array": { - "version": "1.0.2", - "from": "events-to-array@1.0.2" - }, - "exec-sh": { - "version": "0.2.0", - "from": "exec-sh@0.2.0" - }, - "exists-sync": { - "version": "0.0.3", - "from": "exists-sync@0.0.3" - }, - "exit": { - "version": "0.1.2", - "from": "exit@0.1.2" - }, - "exit-hook": { - "version": "1.1.1", - "from": "exit-hook@1.1.1" - }, - "express": { - "version": "4.14.0", - "from": "express@4.14.0", - "dependencies": { - "finalhandler": { - "version": "0.5.0", - "from": "finalhandler@0.5.0" - } - } - }, - "extend": { - "version": "3.0.0", - "from": "extend@3.0.0" - }, - "extsprintf": { - "version": "1.0.2", - "from": "extsprintf@1.0.2" - }, - "fast-levenshtein": { - "version": "1.1.3", - "from": "fast-levenshtein@1.1.3" - }, - "fast-ordered-set": { - "version": "1.0.2", - "from": "fast-ordered-set@1.0.2" - }, - "fast-sourcemap-concat": { - "version": "1.0.0", - "from": "fast-sourcemap-concat@1.0.0", - "dependencies": { - "chalk": { - "version": "0.5.1", - "from": "chalk@0.5.1" - } - } - }, - "faye-websocket": { - "version": "0.10.0", - "from": "faye-websocket@0.10.0" - }, - "fb-watchman": { - "version": "1.9.0", - "from": "fb-watchman@1.9.0" - }, - "figures": { - "version": "1.7.0", - "from": "figures@1.7.0" - }, - "file-entry-cache": { - "version": "1.2.4", - "from": "file-entry-cache@1.2.4" - }, - "fileset": { - "version": "0.2.1", - "from": "fileset@0.2.1", - "dependencies": { - "glob": { - "version": "5.0.15", - "from": "glob@5.0.15" - }, - "minimatch": { - "version": "2.0.10", - "from": "minimatch@2.0.10" - } - } - }, - "filesize": { - "version": "3.3.0", - "from": "filesize@3.3.0" - }, - "filled-array": { - "version": "1.1.0", - "from": "filled-array@1.1.0" - }, - "finalhandler": { - "version": "0.4.1", - "from": "finalhandler@0.4.1" - }, - "find-up": { - "version": "1.1.2", - "from": "find-up@1.1.2", - "dependencies": { - "path-exists": { - "version": "2.1.0", - "from": "path-exists@2.1.0" - } - } - }, - "findup": { - "version": "0.1.5", - "from": "findup@0.1.5", - "dependencies": { - "commander": { - "version": "2.1.0", - "from": "commander@2.1.0" - } - } - }, - "findup-sync": { - "version": "0.2.1", - "from": "findup-sync@0.2.1", - "dependencies": { - "glob": { - "version": "4.3.5", - "from": "glob@4.3.5" - }, - "minimatch": { - "version": "2.0.10", - "from": "minimatch@2.0.10" - } - } - }, - "fireworm": { - "version": "0.7.1", - "from": "fireworm@0.7.1", - "dependencies": { - "async": { - "version": "0.2.10", - "from": "async@0.2.10" - } - } - }, - "flat-cache": { - "version": "1.0.10", - "from": "flat-cache@1.0.10" - }, - "forever-agent": { - "version": "0.6.1", - "from": "forever-agent@0.6.1" - }, - "form-data": { - "version": "1.0.0-rc4", - "from": "form-data@1.0.0-rc4" - }, - "formatio": { - "version": "1.1.1", - "from": "formatio@1.1.1" - }, - "forwarded": { - "version": "0.1.0", - "from": "forwarded@0.1.0" - }, - "fresh": { - "version": "0.3.0", - "from": "fresh@0.3.0" - }, - "fs-extra": { - "version": "0.30.0", - "from": "fs-extra@0.30.0" - }, - "fs-monitor-stack": { - "version": "1.1.0", - "from": "fs-monitor-stack@1.1.0" - }, - "fs-readdir-recursive": { - "version": "0.1.2", - "from": "fs-readdir-recursive@0.1.2" - }, - "fs-tree-diff": { - "version": "0.5.0", - "from": "fs-tree-diff@0.5.0" - }, - "fs.realpath": { - "version": "1.0.0", - "from": "fs.realpath@1.0.0" - }, - "function-bind": { - "version": "1.1.0", - "from": "function-bind@1.1.0" - }, - "gauge": { - "version": "1.2.7", - "from": "gauge@1.2.7" - }, - "generate-function": { - "version": "2.0.0", - "from": "generate-function@2.0.0" - }, - "generate-object-property": { - "version": "1.2.0", - "from": "generate-object-property@1.2.0" - }, - "get-caller-file": { - "version": "1.0.1", - "from": "get-caller-file@1.0.1" - }, - "get-pkg-repo": { - "version": "1.2.1", - "from": "get-pkg-repo@1.2.1" - }, - "get-stdin": { - "version": "4.0.1", - "from": "get-stdin@4.0.1" - }, - "getpass": { - "version": "0.1.6", - "from": "getpass@0.1.6", - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "from": "assert-plus@1.0.0" - } - } - }, - "git-raw-commits": { - "version": "1.1.2", - "from": "git-raw-commits@1.1.2" - }, - "git-remote-origin-url": { - "version": "2.0.0", - "from": "git-remote-origin-url@2.0.0" - }, - "git-repo-info": { - "version": "1.1.4", - "from": "git-repo-info@1.1.4" - }, - "git-semver-tags": { - "version": "1.1.2", - "from": "git-semver-tags@1.1.2" - }, - "gitconfiglocal": { - "version": "1.0.0", - "from": "gitconfiglocal@1.0.0" - }, - "github-url-from-git": { - "version": "1.4.0", - "from": "github-url-from-git@1.4.0" - }, - "glob": { - "version": "7.0.5", - "from": "glob@7.0.5" - }, - "globals": { - "version": "6.4.1", - "from": "globals@6.4.1" - }, - "globby": { - "version": "5.0.0", - "from": "globby@5.0.0" - }, - "got": { - "version": "5.6.0", - "from": "got@5.6.0", - "dependencies": { - "isarray": { - "version": "1.0.0", - "from": "isarray@1.0.0" - }, - "readable-stream": { - "version": "2.1.4", - "from": "readable-stream@2.1.4" - } - } - }, - "graceful-fs": { - "version": "4.1.4", - "from": "graceful-fs@4.1.4" - }, - "graceful-readlink": { - "version": "1.0.1", - "from": "graceful-readlink@1.0.1" - }, - "growl": { - "version": "1.9.2", - "from": "growl@1.9.2" - }, - "growly": { - "version": "1.3.0", - "from": "growly@1.3.0" - }, - "handlebars": { - "version": "4.0.5", - "from": "handlebars@4.0.5" - }, - "har-validator": { - "version": "2.0.6", - "from": "har-validator@2.0.6" - }, - "has": { - "version": "1.0.1", - "from": "has@1.0.1" - }, - "has-ansi": { - "version": "0.1.0", - "from": "has-ansi@0.1.0" - }, - "has-binary": { - "version": "0.1.7", - "from": "has-binary@0.1.7" - }, - "has-cors": { - "version": "1.1.0", - "from": "has-cors@1.1.0" - }, - "has-unicode": { - "version": "2.0.1", - "from": "has-unicode@2.0.1" - }, - "hash-for-dep": { - "version": "1.0.2", - "from": "hash-for-dep@1.0.2", - "dependencies": { - "broccoli-kitchen-sink-helpers": { - "version": "0.2.9", - "from": "broccoli-kitchen-sink-helpers@0.2.9" - }, - "glob": { - "version": "5.0.15", - "from": "glob@5.0.15" - } - } - }, - "hawk": { - "version": "3.1.3", - "from": "hawk@3.1.3" - }, - "hoek": { - "version": "2.16.3", - "from": "hoek@2.16.3" - }, - "home-or-tmp": { - "version": "1.0.0", - "from": "home-or-tmp@1.0.0" - }, - "hosted-git-info": { - "version": "2.1.5", - "from": "hosted-git-info@2.1.5" - }, - "http-errors": { - "version": "1.5.0", - "from": "http-errors@1.5.0" - }, - "http-proxy": { - "version": "1.14.0", - "from": "http-proxy@1.14.0" - }, - "http-proxy-agent": { - "version": "1.0.0", - "from": "http-proxy-agent@1.0.0" - }, - "http-signature": { - "version": "1.1.1", - "from": "http-signature@1.1.1" - }, - "https-proxy-agent": { - "version": "1.0.0", - "from": "https-proxy-agent@1.0.0" - }, - "iconv-lite": { - "version": "0.4.13", - "from": "iconv-lite@0.4.13" - }, - "ignore": { - "version": "3.1.3", - "from": "ignore@3.1.3" - }, - "imurmurhash": { - "version": "0.1.4", - "from": "imurmurhash@0.1.4" - }, - "indent-string": { - "version": "2.1.0", - "from": "indent-string@2.1.0", - "dependencies": { - "repeating": { - "version": "2.0.1", - "from": "repeating@2.0.1" - } - } - }, - "indexof": { - "version": "0.0.1", - "from": "indexof@0.0.1" - }, - "inflection": { - "version": "1.10.0", - "from": "inflection@1.10.0" - }, - "inflight": { - "version": "1.0.5", - "from": "inflight@1.0.5" - }, - "inherits": { - "version": "2.0.1", - "from": "inherits@2.0.1" - }, - "ini": { - "version": "1.3.4", - "from": "ini@1.3.4" - }, - "inline-source-map-comment": { - "version": "1.0.5", - "from": "inline-source-map-comment@1.0.5", - "dependencies": { - "minimist": { - "version": "1.2.0", - "from": "minimist@1.2.0" - } - } - }, - "inquirer": { - "version": "0.12.0", - "from": "inquirer@0.12.0", - "dependencies": { - "ansi-regex": { - "version": "2.0.0", - "from": "ansi-regex@2.0.0" - }, - "readline2": { - "version": "1.0.1", - "from": "readline2@1.0.1" - }, - "strip-ansi": { - "version": "3.0.1", - "from": "strip-ansi@3.0.1" - } - } - }, - "interpret": { - "version": "1.0.1", - "from": "interpret@1.0.1" - }, - "invariant": { - "version": "2.2.1", - "from": "invariant@2.2.1" - }, - "invert-kv": { - "version": "1.0.0", - "from": "invert-kv@1.0.0" - }, - "ipaddr.js": { - "version": "1.1.1", - "from": "ipaddr.js@1.1.1" - }, - "is-absolute": { - "version": "0.2.5", - "from": "is-absolute@0.2.5" - }, - "is-arrayish": { - "version": "0.2.1", - "from": "is-arrayish@0.2.1" - }, - "is-buffer": { - "version": "1.1.3", - "from": "is-buffer@1.1.3" - }, - "is-builtin-module": { - "version": "1.0.0", - "from": "is-builtin-module@1.0.0" - }, - "is-finite": { - "version": "1.0.1", - "from": "is-finite@1.0.1" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "from": "is-fullwidth-code-point@1.0.0" - }, - "is-git-url": { - "version": "0.2.3", - "from": "is-git-url@0.2.3" - }, - "is-integer": { - "version": "1.0.6", - "from": "is-integer@1.0.6" - }, - "is-my-json-valid": { - "version": "2.13.1", - "from": "is-my-json-valid@2.13.1" - }, - "is-npm": { - "version": "1.0.0", - "from": "is-npm@1.0.0" - }, - "is-obj": { - "version": "1.0.1", - "from": "is-obj@1.0.1" - }, - "is-path-cwd": { - "version": "1.0.0", - "from": "is-path-cwd@1.0.0" - }, - "is-path-in-cwd": { - "version": "1.0.0", - "from": "is-path-in-cwd@1.0.0" - }, - "is-path-inside": { - "version": "1.0.0", - "from": "is-path-inside@1.0.0" - }, - "is-plain-obj": { - "version": "1.1.0", - "from": "is-plain-obj@1.1.0" - }, - "is-property": { - "version": "1.0.2", - "from": "is-property@1.0.2" - }, - "is-redirect": { - "version": "1.0.0", - "from": "is-redirect@1.0.0" - }, - "is-relative": { - "version": "0.2.1", - "from": "is-relative@0.2.1" - }, - "is-resolvable": { - "version": "1.0.0", - "from": "is-resolvable@1.0.0" - }, - "is-retry-allowed": { - "version": "1.1.0", - "from": "is-retry-allowed@1.1.0" - }, - "is-stream": { - "version": "1.1.0", - "from": "is-stream@1.1.0" - }, - "is-subset": { - "version": "0.1.1", - "from": "is-subset@0.1.1" - }, - "is-text-path": { - "version": "1.0.1", - "from": "is-text-path@1.0.1" - }, - "is-type": { - "version": "0.0.1", - "from": "is-type@0.0.1" - }, - "is-typedarray": { - "version": "1.0.0", - "from": "is-typedarray@1.0.0" - }, - "is-unc-path": { - "version": "0.1.1", - "from": "is-unc-path@0.1.1" - }, - "is-utf8": { - "version": "0.2.1", - "from": "is-utf8@0.2.1" - }, - "is-windows": { - "version": "0.1.1", - "from": "is-windows@0.1.1" - }, - "isarray": { - "version": "0.0.1", - "from": "isarray@0.0.1" - }, - "isbinaryfile": { - "version": "2.0.4", - "from": "isbinaryfile@2.0.4" - }, - "isexe": { - "version": "1.1.2", - "from": "isexe@1.1.2" - }, - "isobject": { - "version": "2.1.0", - "from": "isobject@2.1.0", - "dependencies": { - "isarray": { - "version": "1.0.0", - "from": "isarray@1.0.0" - } - } - }, - "isstream": { - "version": "0.1.2", - "from": "isstream@0.1.2" - }, - "istextorbinary": { - "version": "2.1.0", - "from": "istextorbinary@2.1.0" - }, - "jade": { - "version": "0.26.3", - "from": "jade@0.26.3", - "dependencies": { - "commander": { - "version": "0.6.1", - "from": "commander@0.6.1" - }, - "mkdirp": { - "version": "0.3.0", - "from": "mkdirp@0.3.0" - } - } - }, - "jodid25519": { - "version": "1.0.2", - "from": "jodid25519@1.0.2" - }, - "js-tokens": { - "version": "1.0.1", - "from": "js-tokens@1.0.1" - }, - "js-yaml": { - "version": "3.6.1", - "from": "js-yaml@3.6.1", - "dependencies": { - "esprima": { - "version": "2.7.2", - "from": "esprima@2.7.2" - } - } - }, - "jsbn": { - "version": "0.1.0", - "from": "jsbn@0.1.0" - }, - "jsesc": { - "version": "0.5.0", - "from": "jsesc@0.5.0" - }, - "json-schema": { - "version": "0.2.2", - "from": "json-schema@0.2.2" - }, - "json-stable-stringify": { - "version": "1.0.1", - "from": "json-stable-stringify@1.0.1" - }, - "json-stringify-safe": { - "version": "5.0.1", - "from": "json-stringify-safe@5.0.1" - }, - "json3": { - "version": "3.2.6", - "from": "json3@3.2.6" - }, - "json5": { - "version": "0.4.0", - "from": "json5@0.4.0" - }, - "jsonfile": { - "version": "2.3.1", - "from": "jsonfile@2.3.1" - }, - "jsonify": { - "version": "0.0.0", - "from": "jsonify@0.0.0" - }, - "jsonparse": { - "version": "1.2.0", - "from": "jsonparse@1.2.0" - }, - "jsonpointer": { - "version": "2.0.0", - "from": "jsonpointer@2.0.0" - }, - "JSONStream": { - "version": "1.1.3", - "from": "JSONStream@1.1.3" - }, - "jsprim": { - "version": "1.3.0", - "from": "jsprim@1.3.0" - }, - "kind-of": { - "version": "3.0.3", - "from": "kind-of@3.0.3" - }, - "klaw": { - "version": "1.3.0", - "from": "klaw@1.3.0" - }, - "latest-version": { - "version": "2.0.0", - "from": "latest-version@2.0.0" - }, - "lazy-cache": { - "version": "1.0.4", - "from": "lazy-cache@1.0.4" - }, - "lcid": { - "version": "1.0.0", - "from": "lcid@1.0.0" - }, - "leek": { - "version": "0.0.21", - "from": "leek@0.0.21" - }, - "leven": { - "version": "1.0.2", - "from": "leven@1.0.2" - }, - "levn": { - "version": "0.3.0", - "from": "levn@0.3.0" - }, - "linkify-it": { - "version": "1.2.4", - "from": "linkify-it@1.2.4" - }, - "listify": { - "version": "1.0.0", - "from": "listify@1.0.0" - }, - "livereload-js": { - "version": "2.2.2", - "from": "livereload-js@2.2.2" - }, - "load-json-file": { - "version": "1.1.0", - "from": "load-json-file@1.1.0" - }, - "lockfile": { - "version": "1.0.1", - "from": "lockfile@1.0.1" - }, - "lodash": { - "version": "4.13.1", - "from": "lodash@4.13.1" - }, - "lodash-node": { - "version": "2.4.1", - "from": "lodash-node@2.4.1" - }, - "lodash._arraycopy": { - "version": "3.0.0", - "from": "lodash._arraycopy@3.0.0" - }, - "lodash._arrayeach": { - "version": "3.0.0", - "from": "lodash._arrayeach@3.0.0" - }, - "lodash._baseassign": { - "version": "3.2.0", - "from": "lodash._baseassign@3.2.0" - }, - "lodash._baseclone": { - "version": "4.5.7", - "from": "lodash._baseclone@4.5.7" - }, - "lodash._basecopy": { - "version": "3.0.1", - "from": "lodash._basecopy@3.0.1" - }, - "lodash._basedifference": { - "version": "4.5.0", - "from": "lodash._basedifference@4.5.0" - }, - "lodash._baseflatten": { - "version": "4.2.1", - "from": "lodash._baseflatten@4.2.1" - }, - "lodash._basefor": { - "version": "3.0.3", - "from": "lodash._basefor@3.0.3" - }, - "lodash._baseslice": { - "version": "4.0.0", - "from": "lodash._baseslice@4.0.0" - }, - "lodash._basetostring": { - "version": "4.12.0", - "from": "lodash._basetostring@4.12.0" - }, - "lodash._baseuniq": { - "version": "4.6.0", - "from": "lodash._baseuniq@4.6.0" - }, - "lodash._bindcallback": { - "version": "3.0.1", - "from": "lodash._bindcallback@3.0.1" - }, - "lodash._createassigner": { - "version": "3.1.1", - "from": "lodash._createassigner@3.1.1" - }, - "lodash._createset": { - "version": "4.0.3", - "from": "lodash._createset@4.0.3" - }, - "lodash._getnative": { - "version": "3.9.1", - "from": "lodash._getnative@3.9.1" - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "from": "lodash._isiterateecall@3.0.9" - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "from": "lodash._reinterpolate@3.0.0" - }, - "lodash._root": { - "version": "3.0.1", - "from": "lodash._root@3.0.1" - }, - "lodash.assign": { - "version": "3.2.0", - "from": "lodash.assign@3.2.0" - }, - "lodash.assigninwith": { - "version": "4.0.7", - "from": "lodash.assigninwith@4.0.7" - }, - "lodash.clonedeep": { - "version": "3.0.2", - "from": "lodash.clonedeep@3.0.2", - "dependencies": { - "lodash._baseclone": { - "version": "3.3.0", - "from": "lodash._baseclone@3.3.0" - } - } - }, - "lodash.debounce": { - "version": "3.1.1", - "from": "lodash.debounce@3.1.1" - }, - "lodash.escape": { - "version": "4.0.0", - "from": "lodash.escape@4.0.0" - }, - "lodash.flatten": { - "version": "3.0.2", - "from": "lodash.flatten@3.0.2", - "dependencies": { - "lodash._baseflatten": { - "version": "3.1.4", - "from": "lodash._baseflatten@3.1.4" - } - } - }, - "lodash.isarguments": { - "version": "3.0.8", - "from": "lodash.isarguments@3.0.8" - }, - "lodash.isarray": { - "version": "3.0.4", - "from": "lodash.isarray@3.0.4" - }, - "lodash.isplainobject": { - "version": "4.0.4", - "from": "lodash.isplainobject@4.0.4" - }, - "lodash.istypedarray": { - "version": "3.0.6", - "from": "lodash.istypedarray@3.0.6" - }, - "lodash.keys": { - "version": "3.1.2", - "from": "lodash.keys@3.1.2" - }, - "lodash.keysin": { - "version": "4.1.4", - "from": "lodash.keysin@4.1.4" - }, - "lodash.merge": { - "version": "4.4.0", - "from": "lodash.merge@4.4.0" - }, - "lodash.omit": { - "version": "4.3.0", - "from": "lodash.omit@4.3.0" - }, - "lodash.pad": { - "version": "4.4.0", - "from": "lodash.pad@4.4.0" - }, - "lodash.padend": { - "version": "4.5.0", - "from": "lodash.padend@4.5.0" - }, - "lodash.padstart": { - "version": "4.5.0", - "from": "lodash.padstart@4.5.0" - }, - "lodash.rest": { - "version": "4.0.3", - "from": "lodash.rest@4.0.3" - }, - "lodash.restparam": { - "version": "3.6.1", - "from": "lodash.restparam@3.6.1" - }, - "lodash.template": { - "version": "4.2.5", - "from": "lodash.template@4.2.5", - "dependencies": { - "lodash.keys": { - "version": "4.0.7", - "from": "lodash.keys@4.0.7" - } - } - }, - "lodash.templatesettings": { - "version": "4.0.1", - "from": "lodash.templatesettings@4.0.1" - }, - "lodash.toplainobject": { - "version": "3.0.0", - "from": "lodash.toplainobject@3.0.0", - "dependencies": { - "lodash.keysin": { - "version": "3.0.8", - "from": "lodash.keysin@3.0.8" - } - } - }, - "lodash.tostring": { - "version": "4.1.3", - "from": "lodash.tostring@4.1.3" - }, - "lodash.uniq": { - "version": "4.3.0", - "from": "lodash.uniq@4.3.0" - }, - "lolex": { - "version": "1.3.2", - "from": "lolex@1.3.2" - }, - "longest": { - "version": "1.0.1", - "from": "longest@1.0.1" - }, - "loose-envify": { - "version": "1.2.0", - "from": "loose-envify@1.2.0" - }, - "loud-rejection": { - "version": "1.6.0", - "from": "loud-rejection@1.6.0" - }, - "lowercase-keys": { - "version": "1.0.0", - "from": "lowercase-keys@1.0.0" - }, - "lru-cache": { - "version": "4.0.1", - "from": "lru-cache@4.0.1" - }, - "make-error": { - "version": "1.1.1", - "from": "make-error@1.1.1" - }, - "make-error-cause": { - "version": "1.1.1", - "from": "make-error-cause@1.1.1" - }, - "makeerror": { - "version": "1.0.11", - "from": "makeerror@1.0.11" - }, - "map-obj": { - "version": "1.0.1", - "from": "map-obj@1.0.1" - }, - "markdown-it": { - "version": "4.3.0", - "from": "markdown-it@4.3.0" - }, - "markdown-it-terminal": { - "version": "0.0.3", - "from": "markdown-it-terminal@0.0.3", - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "from": "ansi-styles@2.2.1" - }, - "lodash.isplainobject": { - "version": "3.2.0", - "from": "lodash.isplainobject@3.2.0" - }, - "lodash.keysin": { - "version": "3.0.8", - "from": "lodash.keysin@3.0.8" - }, - "lodash.merge": { - "version": "3.3.2", - "from": "lodash.merge@3.3.2" - }, - "markdown-it": { - "version": "4.4.0", - "from": "markdown-it@4.4.0" - } - } - }, - "marked": { - "version": "0.3.5", - "from": "marked@0.3.5" - }, - "marked-terminal": { - "version": "1.6.1", - "from": "marked-terminal@1.6.1" - }, - "matcher-collection": { - "version": "1.0.2", - "from": "matcher-collection@1.0.2" - }, - "md5-hex": { - "version": "1.3.0", - "from": "md5-hex@1.3.0" - }, - "md5-o-matic": { - "version": "0.1.1", - "from": "md5-o-matic@0.1.1" - }, - "mdurl": { - "version": "1.0.1", - "from": "mdurl@1.0.1" - }, - "media-typer": { - "version": "0.3.0", - "from": "media-typer@0.3.0" - }, - "memory-streams": { - "version": "0.1.0", - "from": "memory-streams@0.1.0" - }, - "meow": { - "version": "3.7.0", - "from": "meow@3.7.0", - "dependencies": { - "minimist": { - "version": "1.2.0", - "from": "minimist@1.2.0" - } - } - }, - "merge": { - "version": "1.2.0", - "from": "merge@1.2.0" - }, - "merge-defaults": { - "version": "0.2.1", - "from": "merge-defaults@0.2.1", - "dependencies": { - "lodash": { - "version": "2.4.2", - "from": "lodash@2.4.2" - } - } - }, - "merge-descriptors": { - "version": "1.0.1", - "from": "merge-descriptors@1.0.1" - }, - "methods": { - "version": "1.1.2", - "from": "methods@1.1.2" - }, - "mime": { - "version": "1.3.4", - "from": "mime@1.3.4" - }, - "mime-db": { - "version": "1.23.0", - "from": "mime-db@1.23.0" - }, - "mime-types": { - "version": "2.1.11", - "from": "mime-types@2.1.11" - }, - "minimatch": { - "version": "3.0.2", - "from": "minimatch@3.0.2" - }, - "minimist": { - "version": "0.0.8", - "from": "minimist@0.0.8" - }, - "mkdirp": { - "version": "0.5.1", - "from": "mkdirp@0.5.1" - }, - "mktemp": { - "version": "0.3.5", - "from": "mktemp@0.3.5" - }, - "modify-values": { - "version": "1.0.0", - "from": "modify-values@1.0.0" - }, - "morgan": { - "version": "1.7.0", - "from": "morgan@1.7.0" - }, - "mout": { - "version": "1.0.0", - "from": "mout@1.0.0" - }, - "ms": { - "version": "0.7.1", - "from": "ms@0.7.1" - }, - "mustache": { - "version": "2.2.1", - "from": "mustache@2.2.1" - }, - "mute-stream": { - "version": "0.0.5", - "from": "mute-stream@0.0.5" - }, - "negotiator": { - "version": "0.6.1", - "from": "negotiator@0.6.1" - }, - "node-emoji": { - "version": "0.1.0", - "from": "node-emoji@0.1.0" - }, - "node-int64": { - "version": "0.4.0", - "from": "node-int64@0.4.0" - }, - "node-modules-path": { - "version": "1.0.1", - "from": "node-modules-path@1.0.1" - }, - "node-notifier": { - "version": "4.6.0", - "from": "node-notifier@4.6.0", - "dependencies": { - "minimist": { - "version": "1.2.0", - "from": "minimist@1.2.0" - } - } - }, - "node-status-codes": { - "version": "1.0.0", - "from": "node-status-codes@1.0.0" - }, - "node-uuid": { - "version": "1.4.7", - "from": "node-uuid@1.4.7" - }, - "nopt": { - "version": "3.0.6", - "from": "nopt@3.0.6" - }, - "normalize-package-data": { - "version": "2.3.5", - "from": "normalize-package-data@2.3.5" - }, - "npm": { - "version": "3.10.2", - "from": "npm@3.10.2", - "dependencies": { - "abbrev": { - "version": "1.0.9", - "from": "abbrev@1.0.9" - }, - "ansi-regex": { - "version": "2.0.0", - "from": "ansi-regex@2.0.0" - }, - "ansicolors": { - "version": "0.3.2", - "from": "ansicolors@>=0.3.2 <0.4.0" - }, - "ansistyles": { - "version": "0.1.3", - "from": "ansistyles@>=0.1.3 <0.2.0" - }, - "aproba": { - "version": "1.0.3", - "from": "aproba@latest" - }, - "archy": { - "version": "1.0.0", - "from": "archy@>=1.0.0 <1.1.0" - }, - "asap": { - "version": "2.0.4", - "from": "asap@latest" - }, - "chownr": { - "version": "1.0.1", - "from": "chownr@>=1.0.1 <1.1.0" - }, - "cmd-shim": { - "version": "2.0.2", - "from": "cmd-shim@2.0.2" - }, - "columnify": { - "version": "1.5.4", - "from": "columnify@1.5.4", - "dependencies": { - "wcwidth": { - "version": "1.0.0", - "from": "wcwidth@>=1.0.0 <2.0.0", - "dependencies": { - "defaults": { - "version": "1.0.3", - "from": "defaults@>=1.0.0 <2.0.0", - "dependencies": { - "clone": { - "version": "1.0.2", - "from": "clone@>=1.0.2 <2.0.0" - } - } - } - } - } - } - }, - "config-chain": { - "version": "1.1.10", - "from": "config-chain@1.1.10", - "dependencies": { - "proto-list": { - "version": "1.2.4", - "from": "proto-list@>=1.2.1 <1.3.0" - } - } - }, - "debuglog": { - "version": "1.0.1", - "from": "debuglog@1.0.1" - }, - "dezalgo": { - "version": "1.0.3", - "from": "dezalgo@>=1.0.3 <1.1.0" - }, - "editor": { - "version": "1.0.0", - "from": "editor@>=1.0.0 <1.1.0" - }, - "fs-vacuum": { - "version": "1.2.9", - "from": "fs-vacuum@latest" - }, - "fs-write-stream-atomic": { - "version": "1.0.8", - "from": "fs-write-stream-atomic@1.0.8" - }, - "fstream": { - "version": "1.0.10", - "from": "fstream@>=1.0.10 <1.1.0" - }, - "fstream-npm": { - "version": "1.1.0", - "from": "fstream-npm@latest", - "dependencies": { - "fstream-ignore": { - "version": "1.0.5", - "from": "fstream-ignore@>=1.0.0 <2.0.0", - "dependencies": { - "minimatch": { - "version": "3.0.0", - "from": "minimatch@>=3.0.0 <4.0.0", - "dependencies": { - "brace-expansion": { - "version": "1.1.4", - "from": "brace-expansion@>=1.0.0 <2.0.0", - "dependencies": { - "balanced-match": { - "version": "0.4.1", - "from": "balanced-match@>=0.4.1 <0.5.0" - }, - "concat-map": { - "version": "0.0.1", - "from": "concat-map@0.0.1" - } - } - } - } - } - } - } - } - }, - "glob": { - "version": "7.0.4", - "from": "glob@>=7.0.3 <7.1.0", - "dependencies": { - "fs.realpath": { - "version": "1.0.0", - "from": "fs.realpath@>=1.0.0 <2.0.0" - }, - "minimatch": { - "version": "3.0.0", - "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0", - "dependencies": { - "brace-expansion": { - "version": "1.1.5", - "from": "brace-expansion@>=1.0.0 <2.0.0", - "dependencies": { - "balanced-match": { - "version": "0.4.1", - "from": "balanced-match@>=0.4.1 <0.5.0" - }, - "concat-map": { - "version": "0.0.1", - "from": "concat-map@0.0.1" - } - } - } - } - }, - "path-is-absolute": { - "version": "1.0.0", - "from": "path-is-absolute@>=1.0.0 <2.0.0" - } - } - }, - "graceful-fs": { - "version": "4.1.4", - "from": "graceful-fs@>=4.1.3 <4.2.0" - }, - "has-unicode": { - "version": "2.0.0", - "from": "has-unicode@2.0.0" - }, - "hosted-git-info": { - "version": "2.1.5", - "from": "hosted-git-info@latest" - }, - "iferr": { - "version": "0.1.5", - "from": "iferr@>=0.1.5 <0.2.0" - }, - "imurmurhash": { - "version": "0.1.4", - "from": "imurmurhash@>=0.1.4 <0.2.0" - }, - "inflight": { - "version": "1.0.5", - "from": "inflight@latest" - }, - "inherits": { - "version": "2.0.1", - "from": "inherits@>=2.0.1 <2.1.0" - }, - "ini": { - "version": "1.3.4", - "from": "ini@>=1.3.4 <1.4.0" - }, - "init-package-json": { - "version": "1.9.4", - "from": "init-package-json@latest", - "dependencies": { - "glob": { - "version": "6.0.4", - "from": "glob@>=6.0.0 <7.0.0", - "dependencies": { - "minimatch": { - "version": "3.0.0", - "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0", - "dependencies": { - "brace-expansion": { - "version": "1.1.4", - "from": "brace-expansion@>=1.0.0 <2.0.0", - "dependencies": { - "balanced-match": { - "version": "0.4.1", - "from": "balanced-match@>=0.4.1 <0.5.0" - }, - "concat-map": { - "version": "0.0.1", - "from": "concat-map@0.0.1" - } - } - } - } - }, - "path-is-absolute": { - "version": "1.0.0", - "from": "path-is-absolute@>=1.0.0 <2.0.0" - } - } - }, - "promzard": { - "version": "0.3.0", - "from": "promzard@>=0.3.0 <0.4.0" - } - } - }, - "lockfile": { - "version": "1.0.1", - "from": "lockfile@>=1.0.1 <1.1.0" - }, - "lodash._baseindexof": { - "version": "3.1.0", - "from": "lodash._baseindexof@3.1.0" - }, - "lodash._baseuniq": { - "version": "4.6.0", - "from": "lodash._baseuniq@latest", - "dependencies": { - "lodash._createset": { - "version": "4.0.3", - "from": "lodash._createset@>=4.0.0 <4.1.0" - }, - "lodash._root": { - "version": "3.0.1", - "from": "lodash._root@>=3.0.0 <3.1.0" - } - } - }, - "lodash._bindcallback": { - "version": "3.0.1", - "from": "lodash._bindcallback@3.0.1" - }, - "lodash._cacheindexof": { - "version": "3.0.2", - "from": "lodash._cacheindexof@3.0.2" - }, - "lodash._createcache": { - "version": "3.1.2", - "from": "lodash._createcache@3.1.2" - }, - "lodash._getnative": { - "version": "3.9.1", - "from": "lodash._getnative@3.9.1" - }, - "lodash.clonedeep": { - "version": "4.3.2", - "from": "lodash.clonedeep@4.3.2", - "dependencies": { - "lodash._baseclone": { - "version": "4.5.3", - "from": "lodash._baseclone@>=4.0.0 <5.0.0" - } - } - }, - "lodash.restparam": { - "version": "3.6.1", - "from": "lodash.restparam@3.6.1" - }, - "lodash.union": { - "version": "4.4.0", - "from": "lodash.union@latest", - "dependencies": { - "lodash._baseflatten": { - "version": "4.2.1", - "from": "lodash._baseflatten@>=4.2.0 <4.3.0" - }, - "lodash.rest": { - "version": "4.0.3", - "from": "lodash.rest@>=4.0.0 <5.0.0" - } - } - }, - "lodash.uniq": { - "version": "4.3.0", - "from": "lodash.uniq@latest" - }, - "lodash.without": { - "version": "4.2.0", - "from": "lodash.without@latest", - "dependencies": { - "lodash._basedifference": { - "version": "4.5.0", - "from": "lodash._basedifference@>=4.5.0 <4.6.0", - "dependencies": { - "lodash._root": { - "version": "3.0.1", - "from": "lodash._root@>=3.0.0 <3.1.0" - } - } - }, - "lodash.rest": { - "version": "4.0.3", - "from": "lodash.rest@>=4.0.0 <5.0.0" - } - } - }, - "mkdirp": { - "version": "0.5.1", - "from": "mkdirp@>=0.5.1 <0.6.0", - "dependencies": { - "minimist": { - "version": "0.0.8", - "from": "minimist@0.0.8" - } - } - }, - "node-gyp": { - "version": "3.3.1", - "from": "node-gyp@3.3.1", - "dependencies": { - "glob": { - "version": "4.5.3", - "from": "glob@>=3.0.0 <4.0.0||>=4.0.0 <5.0.0", - "dependencies": { - "minimatch": { - "version": "2.0.10", - "from": "minimatch@>=2.0.1 <3.0.0", - "dependencies": { - "brace-expansion": { - "version": "1.1.3", - "from": "brace-expansion@>=1.0.0 <2.0.0", - "dependencies": { - "balanced-match": { - "version": "0.3.0", - "from": "balanced-match@>=0.3.0 <0.4.0" - }, - "concat-map": { - "version": "0.0.1", - "from": "concat-map@0.0.1" - } - } - } - } - } - } - }, - "minimatch": { - "version": "1.0.0", - "from": "minimatch@>=1.0.0 <2.0.0", - "dependencies": { - "lru-cache": { - "version": "2.7.3", - "from": "lru-cache@>=2.0.0 <3.0.0" - }, - "sigmund": { - "version": "1.0.1", - "from": "sigmund@>=1.0.0 <1.1.0" - } - } - }, - "npmlog": { - "version": "2.0.4", - "from": "npmlog@>=0.0.0 <1.0.0||>=1.0.0 <2.0.0||>=2.0.0 <3.0.0", - "dependencies": { - "ansi": { - "version": "0.3.1", - "from": "ansi@~0.3.1" - }, - "are-we-there-yet": { - "version": "1.1.2", - "from": "are-we-there-yet@~1.1.2", - "dependencies": { - "delegates": { - "version": "1.0.0", - "from": "delegates@^1.0.0" - } - } - }, - "gauge": { - "version": "1.2.7", - "from": "gauge@>=1.2.5 <1.3.0", - "dependencies": { - "lodash.pad": { - "version": "4.4.0", - "from": "lodash.pad@>=4.1.0 <5.0.0", - "dependencies": { - "lodash._baseslice": { - "version": "4.0.0", - "from": "lodash._baseslice@>=4.0.0 <4.1.0" - }, - "lodash._basetostring": { - "version": "4.12.0", - "from": "lodash._basetostring@>=4.12.0 <4.13.0" - }, - "lodash.tostring": { - "version": "4.1.3", - "from": "lodash.tostring@>=4.0.0 <5.0.0" - } - } - }, - "lodash.padend": { - "version": "4.5.0", - "from": "lodash.padend@>=4.1.0 <5.0.0", - "dependencies": { - "lodash._baseslice": { - "version": "4.0.0", - "from": "lodash._baseslice@~4.0.0" - }, - "lodash._basetostring": { - "version": "4.12.0", - "from": "lodash._basetostring@~4.12.0" - }, - "lodash.tostring": { - "version": "4.1.3", - "from": "lodash.tostring@^4.0.0" - } - } - }, - "lodash.padstart": { - "version": "4.5.0", - "from": "lodash.padstart@>=4.1.0 <5.0.0", - "dependencies": { - "lodash._baseslice": { - "version": "4.0.0", - "from": "lodash._baseslice@~4.0.0" - }, - "lodash._basetostring": { - "version": "4.12.0", - "from": "lodash._basetostring@~4.12.0" - }, - "lodash.tostring": { - "version": "4.1.3", - "from": "lodash.tostring@^4.0.0" - } - } - } - } - } - } - }, - "path-array": { - "version": "1.0.1", - "from": "path-array@>=1.0.0 <2.0.0", - "dependencies": { - "array-index": { - "version": "1.0.0", - "from": "array-index@>=1.0.0 <2.0.0", - "dependencies": { - "debug": { - "version": "2.2.0", - "from": "debug@*", - "dependencies": { - "ms": { - "version": "0.7.1", - "from": "ms@0.7.1" - } - } - }, - "es6-symbol": { - "version": "3.0.2", - "from": "es6-symbol@>=3.0.2 <4.0.0", - "dependencies": { - "d": { - "version": "0.1.1", - "from": "d@>=0.1.1 <0.2.0" - }, - "es5-ext": { - "version": "0.10.11", - "from": "es5-ext@>=0.10.10 <0.11.0", - "dependencies": { - "es6-iterator": { - "version": "2.0.0", - "from": "es6-iterator@>=2.0.0 <3.0.0" - } - } - } - } - } - } - } - } - } - } - }, - "nopt": { - "version": "3.0.6", - "from": "nopt@>=3.0.6 <3.1.0" - }, - "normalize-git-url": { - "version": "3.0.2", - "from": "normalize-git-url@>=3.0.2 <3.1.0" - }, - "normalize-package-data": { - "version": "2.3.5", - "from": "normalize-package-data@>=2.3.5 <2.4.0", - "dependencies": { - "is-builtin-module": { - "version": "1.0.0", - "from": "is-builtin-module@>=1.0.0 <2.0.0", - "dependencies": { - "builtin-modules": { - "version": "1.1.1", - "from": "builtin-modules@>=1.0.0 <2.0.0" - } - } - } - } - }, - "npm-cache-filename": { - "version": "1.0.2", - "from": "npm-cache-filename@>=1.0.2 <1.1.0" - }, - "npm-install-checks": { - "version": "3.0.0", - "from": "npm-install-checks@3.0.0" - }, - "npm-package-arg": { - "version": "4.2.0", - "from": "npm-package-arg@4.2.0" - }, - "npm-registry-client": { - "version": "7.1.2", - "from": "npm-registry-client@latest", - "dependencies": { - "concat-stream": { - "version": "1.5.1", - "from": "concat-stream@>=1.4.6 <2.0.0", - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "from": "readable-stream@>=2.0.0 <2.1.0", - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "from": "core-util-is@>=1.0.0 <1.1.0" - }, - "isarray": { - "version": "1.0.0", - "from": "isarray@>=1.0.0 <1.1.0" - }, - "process-nextick-args": { - "version": "1.0.7", - "from": "process-nextick-args@>=1.0.6 <1.1.0" - }, - "string_decoder": { - "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0" - }, - "util-deprecate": { - "version": "1.0.2", - "from": "util-deprecate@>=1.0.1 <1.1.0" - } - } - }, - "typedarray": { - "version": "0.0.6", - "from": "typedarray@>=0.0.5 <0.1.0" - } - } - }, - "retry": { - "version": "0.8.0", - "from": "retry@>=0.8.0 <0.9.0" - } - } - }, - "npm-user-validate": { - "version": "0.1.4", - "from": "npm-user-validate@latest" - }, - "npmlog": { - "version": "3.1.2", - "from": "npmlog@latest", - "dependencies": { - "are-we-there-yet": { - "version": "1.1.2", - "from": "are-we-there-yet@>=1.1.2 <1.2.0", - "dependencies": { - "delegates": { - "version": "1.0.0", - "from": "delegates@>=1.0.0 <2.0.0" - } - } - }, - "console-control-strings": { - "version": "1.1.0", - "from": "console-control-strings@>=1.1.0 <1.2.0" - }, - "gauge": { - "version": "2.6.0", - "from": "gauge@>=2.6.0 <2.7.0", - "dependencies": { - "has-color": { - "version": "0.1.7", - "from": "has-color@>=0.1.7 <0.2.0" - }, - "object-assign": { - "version": "4.1.0", - "from": "object-assign@>=4.0.1 <5.0.0" - }, - "signal-exit": { - "version": "3.0.0", - "from": "signal-exit@>=3.0.0 <4.0.0" - }, - "string-width": { - "version": "1.0.1", - "from": "string-width@>=1.0.1 <2.0.0", - "dependencies": { - "code-point-at": { - "version": "1.0.0", - "from": "code-point-at@>=1.0.0 <2.0.0", - "dependencies": { - "number-is-nan": { - "version": "1.0.0", - "from": "number-is-nan@>=1.0.0 <2.0.0" - } - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "from": "is-fullwidth-code-point@>=1.0.0 <2.0.0", - "dependencies": { - "number-is-nan": { - "version": "1.0.0", - "from": "number-is-nan@^1.0.0" - } - } - } - } - }, - "wide-align": { - "version": "1.1.0", - "from": "wide-align@>=1.1.0 <2.0.0" - } - } - }, - "set-blocking": { - "version": "2.0.0", - "from": "set-blocking@>=2.0.0 <2.1.0" - } - } - }, - "once": { - "version": "1.3.3", - "from": "once@>=1.3.3 <1.4.0" - }, - "opener": { - "version": "1.4.1", - "from": "opener@>=1.4.1 <1.5.0" - }, - "osenv": { - "version": "0.1.3", - "from": "osenv@>=0.1.3 <0.2.0", - "dependencies": { - "os-homedir": { - "version": "1.0.1", - "from": "os-homedir@>=1.0.0 <2.0.0" - }, - "os-tmpdir": { - "version": "1.0.1", - "from": "os-tmpdir@>=1.0.0 <2.0.0" - } - } - }, - "path-is-inside": { - "version": "1.0.1", - "from": "path-is-inside@>=1.0.1 <1.1.0" - }, - "read": { - "version": "1.0.7", - "from": "read@>=1.0.7 <1.1.0", - "dependencies": { - "mute-stream": { - "version": "0.0.5", - "from": "mute-stream@>=0.0.4 <0.1.0" - } - } - }, - "read-cmd-shim": { - "version": "1.0.1", - "from": "read-cmd-shim@>=1.0.1 <1.1.0" - }, - "read-installed": { - "version": "4.0.3", - "from": "read-installed@>=4.0.3 <4.1.0", - "dependencies": { - "util-extend": { - "version": "1.0.3", - "from": "util-extend@>=1.0.1 <2.0.0" - } - } - }, - "read-package-json": { - "version": "2.0.4", - "from": "read-package-json@>=2.0.3 <2.1.0", - "dependencies": { - "glob": { - "version": "6.0.4", - "from": "glob@>=6.0.0 <7.0.0", - "dependencies": { - "minimatch": { - "version": "3.0.0", - "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0", - "dependencies": { - "brace-expansion": { - "version": "1.1.3", - "from": "brace-expansion@>=1.0.0 <2.0.0", - "dependencies": { - "balanced-match": { - "version": "0.3.0", - "from": "balanced-match@>=0.3.0 <0.4.0" - }, - "concat-map": { - "version": "0.0.1", - "from": "concat-map@0.0.1" - } - } - } - } - }, - "path-is-absolute": { - "version": "1.0.0", - "from": "path-is-absolute@>=1.0.0 <2.0.0" - } - } - }, - "json-parse-helpfulerror": { - "version": "1.0.3", - "from": "json-parse-helpfulerror@>=1.0.2 <2.0.0", - "dependencies": { - "jju": { - "version": "1.3.0", - "from": "jju@>=1.1.0 <2.0.0" - } - } - } - } - }, - "read-package-tree": { - "version": "5.1.4", - "from": "read-package-tree@>=5.1.3 <5.2.0" - }, - "readable-stream": { - "version": "2.1.4", - "from": "readable-stream@latest", - "dependencies": { - "buffer-shims": { - "version": "1.0.0", - "from": "buffer-shims@>=1.0.0 <2.0.0" - }, - "core-util-is": { - "version": "1.0.2", - "from": "core-util-is@>=1.0.0 <1.1.0" - }, - "isarray": { - "version": "1.0.0", - "from": "isarray@>=1.0.0 <1.1.0" - }, - "process-nextick-args": { - "version": "1.0.7", - "from": "process-nextick-args@>=1.0.6 <1.1.0" - }, - "string_decoder": { - "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0" - }, - "util-deprecate": { - "version": "1.0.2", - "from": "util-deprecate@>=1.0.1 <1.1.0" - } - } - }, - "readdir-scoped-modules": { - "version": "1.0.2", - "from": "readdir-scoped-modules@1.0.2" - }, - "realize-package-specifier": { - "version": "3.0.3", - "from": "realize-package-specifier@>=3.0.2 <3.1.0" - }, - "request": { - "version": "2.72.0", - "from": "request@latest", - "dependencies": { - "aws-sign2": { - "version": "0.6.0", - "from": "aws-sign2@>=0.6.0 <0.7.0" - }, - "aws4": { - "version": "1.3.2", - "from": "aws4@>=1.2.1 <2.0.0", - "dependencies": { - "lru-cache": { - "version": "4.0.1", - "from": "lru-cache@>=4.0.0 <5.0.0", - "dependencies": { - "pseudomap": { - "version": "1.0.2", - "from": "pseudomap@>=1.0.1 <2.0.0" - }, - "yallist": { - "version": "2.0.0", - "from": "yallist@>=2.0.0 <3.0.0" - } - } - } - } - }, - "bl": { - "version": "1.1.2", - "from": "bl@>=1.1.2 <1.2.0", - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "from": "readable-stream@>=2.0.5 <2.1.0", - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "from": "core-util-is@>=1.0.0 <1.1.0" - }, - "isarray": { - "version": "1.0.0", - "from": "isarray@>=1.0.0 <1.1.0" - }, - "process-nextick-args": { - "version": "1.0.6", - "from": "process-nextick-args@>=1.0.6 <1.1.0" - }, - "string_decoder": { - "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0" - }, - "util-deprecate": { - "version": "1.0.2", - "from": "util-deprecate@>=1.0.1 <1.1.0" - } - } - } - } - }, - "caseless": { - "version": "0.11.0", - "from": "caseless@>=0.11.0 <0.12.0" - }, - "combined-stream": { - "version": "1.0.5", - "from": "combined-stream@>=1.0.5 <1.1.0", - "dependencies": { - "delayed-stream": { - "version": "1.0.0", - "from": "delayed-stream@>=1.0.0 <1.1.0" - } - } - }, - "extend": { - "version": "3.0.0", - "from": "extend@>=3.0.0 <3.1.0" - }, - "forever-agent": { - "version": "0.6.1", - "from": "forever-agent@>=0.6.1 <0.7.0" - }, - "form-data": { - "version": "1.0.0-rc4", - "from": "form-data@>=1.0.0-rc3 <1.1.0", - "dependencies": { - "async": { - "version": "1.5.2", - "from": "async@>=1.4.0 <2.0.0" - } - } - }, - "har-validator": { - "version": "2.0.6", - "from": "har-validator@>=2.0.2 <2.1.0", - "dependencies": { - "chalk": { - "version": "1.1.3", - "from": "chalk@>=1.1.1 <2.0.0", - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "from": "ansi-styles@>=2.2.1 <3.0.0" - }, - "escape-string-regexp": { - "version": "1.0.5", - "from": "escape-string-regexp@>=1.0.2 <2.0.0" - }, - "has-ansi": { - "version": "2.0.0", - "from": "has-ansi@>=2.0.0 <3.0.0" - }, - "supports-color": { - "version": "2.0.0", - "from": "supports-color@>=2.0.0 <3.0.0" - } - } - }, - "commander": { - "version": "2.9.0", - "from": "commander@>=2.8.1 <3.0.0", - "dependencies": { - "graceful-readlink": { - "version": "1.0.1", - "from": "graceful-readlink@>=1.0.0" - } - } - }, - "is-my-json-valid": { - "version": "2.13.1", - "from": "is-my-json-valid@>=2.12.4 <3.0.0", - "dependencies": { - "generate-function": { - "version": "2.0.0", - "from": "generate-function@>=2.0.0 <3.0.0" - }, - "generate-object-property": { - "version": "1.2.0", - "from": "generate-object-property@>=1.1.0 <2.0.0", - "dependencies": { - "is-property": { - "version": "1.0.2", - "from": "is-property@>=1.0.0 <2.0.0" - } - } - }, - "jsonpointer": { - "version": "2.0.0", - "from": "jsonpointer@2.0.0" - }, - "xtend": { - "version": "4.0.1", - "from": "xtend@>=4.0.0 <5.0.0" - } - } - }, - "pinkie-promise": { - "version": "2.0.1", - "from": "pinkie-promise@>=2.0.0 <3.0.0", - "dependencies": { - "pinkie": { - "version": "2.0.4", - "from": "pinkie@>=2.0.0 <3.0.0" - } - } - } - } - }, - "hawk": { - "version": "3.1.3", - "from": "hawk@>=3.1.0 <3.2.0", - "dependencies": { - "boom": { - "version": "2.10.1", - "from": "boom@>=2.0.0 <3.0.0" - }, - "cryptiles": { - "version": "2.0.5", - "from": "cryptiles@>=2.0.0 <3.0.0" - }, - "hoek": { - "version": "2.16.3", - "from": "hoek@>=2.0.0 <3.0.0" - }, - "sntp": { - "version": "1.0.9", - "from": "sntp@>=1.0.0 <2.0.0" - } - } - }, - "http-signature": { - "version": "1.1.1", - "from": "http-signature@>=1.1.0 <1.2.0", - "dependencies": { - "assert-plus": { - "version": "0.2.0", - "from": "assert-plus@>=0.2.0 <0.3.0" - }, - "jsprim": { - "version": "1.2.2", - "from": "jsprim@>=1.2.2 <2.0.0", - "dependencies": { - "extsprintf": { - "version": "1.0.2", - "from": "extsprintf@1.0.2" - }, - "json-schema": { - "version": "0.2.2", - "from": "json-schema@0.2.2" - }, - "verror": { - "version": "1.3.6", - "from": "verror@1.3.6" - } - } - }, - "sshpk": { - "version": "1.7.4", - "from": "sshpk@>=1.7.0 <2.0.0", - "dependencies": { - "asn1": { - "version": "0.2.3", - "from": "asn1@>=0.2.3 <0.3.0" - }, - "dashdash": { - "version": "1.13.0", - "from": "dashdash@>=1.10.1 <2.0.0", - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "from": "assert-plus@>=1.0.0 <2.0.0" - } - } - }, - "ecc-jsbn": { - "version": "0.1.1", - "from": "ecc-jsbn@>=0.0.1 <1.0.0" - }, - "jodid25519": { - "version": "1.0.2", - "from": "jodid25519@>=1.0.0 <2.0.0" - }, - "jsbn": { - "version": "0.1.0", - "from": "jsbn@>=0.1.0 <0.2.0" - }, - "tweetnacl": { - "version": "0.14.3", - "from": "tweetnacl@>=0.13.0 <1.0.0" - } - } - } - } - }, - "is-typedarray": { - "version": "1.0.0", - "from": "is-typedarray@>=1.0.0 <1.1.0" - }, - "isstream": { - "version": "0.1.2", - "from": "isstream@>=0.1.2 <0.2.0" - }, - "json-stringify-safe": { - "version": "5.0.1", - "from": "json-stringify-safe@>=5.0.1 <5.1.0" - }, - "mime-types": { - "version": "2.1.10", - "from": "mime-types@>=2.1.7 <2.2.0", - "dependencies": { - "mime-db": { - "version": "1.22.0", - "from": "mime-db@>=1.22.0 <1.23.0" - } - } - }, - "node-uuid": { - "version": "1.4.7", - "from": "node-uuid@>=1.4.7 <1.5.0" - }, - "oauth-sign": { - "version": "0.8.1", - "from": "oauth-sign@>=0.8.0 <0.9.0" - }, - "qs": { - "version": "6.1.0", - "from": "qs@>=6.1.0 <6.2.0" - }, - "stringstream": { - "version": "0.0.5", - "from": "stringstream@>=0.0.4 <0.1.0" - }, - "tough-cookie": { - "version": "2.2.2", - "from": "tough-cookie@>=2.2.0 <2.3.0" - }, - "tunnel-agent": { - "version": "0.4.2", - "from": "tunnel-agent@>=0.4.1 <0.5.0" - } - } - }, - "retry": { - "version": "0.9.0", - "from": "retry@latest" - }, - "rimraf": { - "version": "2.5.2", - "from": "rimraf@>=2.5.1 <2.6.0" - }, - "semver": { - "version": "5.1.0", - "from": "semver@>=5.1.0 <5.2.0" - }, - "sha": { - "version": "2.0.1", - "from": "sha@>=2.0.1 <2.1.0" - }, - "slide": { - "version": "1.1.6", - "from": "slide@>=1.1.6 <1.2.0" - }, - "sorted-object": { - "version": "2.0.0", - "from": "sorted-object@latest" - }, - "strip-ansi": { - "version": "3.0.1", - "from": "strip-ansi@*" - }, - "tar": { - "version": "2.2.1", - "from": "tar@>=2.2.1 <2.3.0", - "dependencies": { - "block-stream": { - "version": "0.0.8", - "from": "block-stream@*" - } - } - }, - "text-table": { - "version": "0.2.0", - "from": "text-table@>=0.2.0 <0.3.0" - }, - "uid-number": { - "version": "0.0.6", - "from": "uid-number@0.0.6" - }, - "umask": { - "version": "1.1.0", - "from": "umask@>=1.1.0 <1.2.0" - }, - "unique-filename": { - "version": "1.1.0", - "from": "unique-filename@>=1.1.0 <2.0.0", - "dependencies": { - "unique-slug": { - "version": "2.0.0", - "from": "unique-slug@>=2.0.0 <3.0.0" - } - } - }, - "unpipe": { - "version": "1.0.0", - "from": "unpipe@>=1.0.0 <1.1.0" - }, - "validate-npm-package-license": { - "version": "3.0.1", - "from": "validate-npm-package-license@3.0.1", - "dependencies": { - "spdx-correct": { - "version": "1.0.2", - "from": "spdx-correct@>=1.0.0 <1.1.0", - "dependencies": { - "spdx-license-ids": { - "version": "1.2.0", - "from": "spdx-license-ids@>=1.0.2 <2.0.0" - } - } - }, - "spdx-expression-parse": { - "version": "1.0.2", - "from": "spdx-expression-parse@>=1.0.0 <1.1.0", - "dependencies": { - "spdx-exceptions": { - "version": "1.0.4", - "from": "spdx-exceptions@>=1.0.4 <2.0.0" - }, - "spdx-license-ids": { - "version": "1.2.0", - "from": "spdx-license-ids@>=1.0.0 <2.0.0" - } - } - } - } - }, - "validate-npm-package-name": { - "version": "2.2.2", - "from": "validate-npm-package-name@>=2.2.2 <2.3.0", - "dependencies": { - "builtins": { - "version": "0.0.7", - "from": "builtins@0.0.7" - } - } - }, - "which": { - "version": "1.2.10", - "from": "which@latest", - "dependencies": { - "isexe": { - "version": "1.1.2", - "from": "isexe@>=1.1.1 <2.0.0" - } - } - }, - "wrappy": { - "version": "1.0.2", - "from": "wrappy@latest" - }, - "write-file-atomic": { - "version": "1.1.4", - "from": "write-file-atomic@>=1.1.4 <2.0.0" - } - } - }, - "npmlog": { - "version": "2.0.4", - "from": "npmlog@2.0.4" - }, - "number-is-nan": { - "version": "1.0.0", - "from": "number-is-nan@1.0.0" - }, - "oauth-sign": { - "version": "0.8.2", - "from": "oauth-sign@0.8.2" - }, - "object-assign": { - "version": "4.1.0", - "from": "object-assign@4.1.0" - }, - "object-component": { - "version": "0.0.3", - "from": "object-component@0.0.3" - }, - "object.pick": { - "version": "1.1.2", - "from": "object.pick@1.1.2" - }, - "on-finished": { - "version": "2.3.0", - "from": "on-finished@2.3.0" - }, - "on-headers": { - "version": "1.0.1", - "from": "on-headers@1.0.1" - }, - "once": { - "version": "1.3.3", - "from": "once@1.3.3" - }, - "onetime": { - "version": "1.1.0", - "from": "onetime@1.1.0" - }, - "opn": { - "version": "4.0.1", - "from": "opn@4.0.1" - }, - "optimist": { - "version": "0.6.1", - "from": "optimist@0.6.1" - }, - "optionator": { - "version": "0.8.1", - "from": "optionator@0.8.1", - "dependencies": { - "wordwrap": { - "version": "1.0.0", - "from": "wordwrap@1.0.0" - } - } - }, - "options": { - "version": "0.0.6", - "from": "options@0.0.6" - }, - "ora": { - "version": "0.2.3", - "from": "ora@0.2.3" - }, - "os-homedir": { - "version": "1.0.1", - "from": "os-homedir@1.0.1" - }, - "os-locale": { - "version": "1.4.0", - "from": "os-locale@1.4.0" - }, - "os-tmpdir": { - "version": "1.0.1", - "from": "os-tmpdir@1.0.1" - }, - "osenv": { - "version": "0.1.3", - "from": "osenv@0.1.3" - }, - "output-file-sync": { - "version": "1.1.2", - "from": "output-file-sync@1.1.2" - }, - "package-json": { - "version": "2.3.3", - "from": "package-json@2.3.3" - }, - "parse-github-repo-url": { - "version": "1.3.0", - "from": "parse-github-repo-url@1.3.0" - }, - "parse-json": { - "version": "2.2.0", - "from": "parse-json@2.2.0" - }, - "parsejson": { - "version": "0.0.1", - "from": "parsejson@0.0.1" - }, - "parseqs": { - "version": "0.0.2", - "from": "parseqs@0.0.2" - }, - "parseuri": { - "version": "0.0.4", - "from": "parseuri@0.0.4" - }, - "parseurl": { - "version": "1.3.1", - "from": "parseurl@1.3.1" - }, - "path-exists": { - "version": "1.0.0", - "from": "path-exists@1.0.0" - }, - "path-is-absolute": { - "version": "1.0.0", - "from": "path-is-absolute@1.0.0" - }, - "path-is-inside": { - "version": "1.0.1", - "from": "path-is-inside@1.0.1" - }, - "path-posix": { - "version": "1.0.0", - "from": "path-posix@1.0.0" - }, - "path-to-regexp": { - "version": "0.1.7", - "from": "path-to-regexp@0.1.7" - }, - "path-type": { - "version": "1.1.0", - "from": "path-type@1.1.0" - }, - "pify": { - "version": "2.3.0", - "from": "pify@2.3.0" - }, - "pinkie": { - "version": "2.0.4", - "from": "pinkie@2.0.4" - }, - "pinkie-promise": { - "version": "2.0.1", - "from": "pinkie-promise@2.0.1" - }, - "pluralize": { - "version": "1.2.1", - "from": "pluralize@1.2.1" - }, - "popsicle": { - "version": "5.0.1", - "from": "popsicle@5.0.1", - "dependencies": { - "async": { - "version": "0.9.2", - "from": "async@0.9.2" - }, - "combined-stream": { - "version": "0.0.7", - "from": "combined-stream@0.0.7" - }, - "delayed-stream": { - "version": "0.0.5", - "from": "delayed-stream@0.0.5" - }, - "form-data": { - "version": "0.2.0", - "from": "form-data@0.2.0" - }, - "mime-db": { - "version": "1.12.0", - "from": "mime-db@1.12.0" - }, - "mime-types": { - "version": "2.0.14", - "from": "mime-types@2.0.14" - } - } - }, - "popsicle-proxy-agent": { - "version": "1.0.0", - "from": "popsicle-proxy-agent@1.0.0" - }, - "popsicle-retry": { - "version": "2.0.0", - "from": "popsicle-retry@2.0.0" - }, - "popsicle-status": { - "version": "1.0.2", - "from": "popsicle-status@1.0.2" - }, - "portfinder": { - "version": "1.0.3", - "from": "portfinder@1.0.3" - }, - "prelude-ls": { - "version": "1.1.2", - "from": "prelude-ls@1.1.2" - }, - "prepend-http": { - "version": "1.0.4", - "from": "prepend-http@1.0.4" - }, - "printf": { - "version": "0.2.5", - "from": "printf@0.2.5" - }, - "private": { - "version": "0.1.6", - "from": "private@0.1.6" - }, - "process-nextick-args": { - "version": "1.0.7", - "from": "process-nextick-args@1.0.7" - }, - "process-relative-require": { - "version": "1.0.0", - "from": "process-relative-require@1.0.0" - }, - "progress": { - "version": "1.1.8", - "from": "progress@1.1.8" - }, - "promise-finally": { - "version": "2.2.1", - "from": "promise-finally@2.2.1" - }, - "promise-map-series": { - "version": "0.2.2", - "from": "promise-map-series@0.2.2" - }, - "proxy-addr": { - "version": "1.1.2", - "from": "proxy-addr@1.1.2" - }, - "pseudomap": { - "version": "1.0.2", - "from": "pseudomap@1.0.2" - }, - "q": { - "version": "1.4.1", - "from": "q@1.4.1" - }, - "qs": { - "version": "6.2.0", - "from": "qs@6.2.0" - }, - "quick-temp": { - "version": "0.1.5", - "from": "quick-temp@0.1.5", - "dependencies": { - "rimraf": { - "version": "2.2.8", - "from": "rimraf@2.2.8" - }, - "underscore.string": { - "version": "2.3.3", - "from": "underscore.string@2.3.3" - } - } - }, - "range-parser": { - "version": "1.2.0", - "from": "range-parser@1.2.0" - }, - "raw-body": { - "version": "2.1.7", - "from": "raw-body@2.1.7", - "dependencies": { - "bytes": { - "version": "2.4.0", - "from": "bytes@2.4.0" - } - } - }, - "rc": { - "version": "1.1.6", - "from": "rc@1.1.6", - "dependencies": { - "minimist": { - "version": "1.2.0", - "from": "minimist@1.2.0" - } - } - }, - "read-all-stream": { - "version": "3.1.0", - "from": "read-all-stream@3.1.0", - "dependencies": { - "isarray": { - "version": "1.0.0", - "from": "isarray@1.0.0" - }, - "readable-stream": { - "version": "2.1.4", - "from": "readable-stream@2.1.4" - } - } - }, - "read-json-sync": { - "version": "1.1.1", - "from": "read-json-sync@1.1.1" - }, - "read-pkg": { - "version": "1.1.0", - "from": "read-pkg@1.1.0" - }, - "read-pkg-up": { - "version": "1.0.1", - "from": "read-pkg-up@1.0.1" - }, - "readable-stream": { - "version": "1.0.34", - "from": "readable-stream@1.0.34" - }, - "readline2": { - "version": "0.1.1", - "from": "readline2@0.1.1", - "dependencies": { - "ansi-regex": { - "version": "1.1.1", - "from": "ansi-regex@1.1.1" - }, - "mute-stream": { - "version": "0.0.4", - "from": "mute-stream@0.0.4" - }, - "strip-ansi": { - "version": "2.0.1", - "from": "strip-ansi@2.0.1" - } - } - }, - "recast": { - "version": "0.10.33", - "from": "recast@0.10.33", - "dependencies": { - "source-map": { - "version": "0.5.6", - "from": "source-map@0.5.6" - } - } - }, - "rechoir": { - "version": "0.6.2", - "from": "rechoir@0.6.2" - }, - "redent": { - "version": "1.0.0", - "from": "redent@1.0.0" - }, - "redeyed": { - "version": "0.5.0", - "from": "redeyed@0.5.0", - "dependencies": { - "esprima-fb": { - "version": "12001.1.0-dev-harmony-fb", - "from": "esprima-fb@12001.1.0-dev-harmony-fb" - } - } - }, - "regenerate": { - "version": "1.3.1", - "from": "regenerate@1.3.1" - }, - "regenerator": { - "version": "0.8.40", - "from": "regenerator@0.8.40" - }, - "regenerator-runtime": { - "version": "0.9.5", - "from": "regenerator-runtime@0.9.5" - }, - "regexpu": { - "version": "1.3.0", - "from": "regexpu@1.3.0", - "dependencies": { - "esprima": { - "version": "2.7.2", - "from": "esprima@2.7.2" - } - } - }, - "registry-url": { - "version": "3.1.0", - "from": "registry-url@3.1.0" - }, - "regjsgen": { - "version": "0.2.0", - "from": "regjsgen@0.2.0" - }, - "regjsparser": { - "version": "0.1.5", - "from": "regjsparser@0.1.5" - }, - "repeat-string": { - "version": "1.5.4", - "from": "repeat-string@1.5.4" - }, - "repeating": { - "version": "1.1.3", - "from": "repeating@1.1.3" - }, - "request": { - "version": "2.73.0", - "from": "request@2.73.0" - }, - "require-uncached": { - "version": "1.0.2", - "from": "require-uncached@1.0.2" - }, - "requires-port": { - "version": "1.0.0", - "from": "requires-port@1.0.0" - }, - "resolve": { - "version": "1.1.7", - "from": "resolve@1.1.7" - }, - "resolve-from": { - "version": "1.0.1", - "from": "resolve-from@1.0.1" - }, - "restore-cursor": { - "version": "1.0.1", - "from": "restore-cursor@1.0.1" - }, - "rewire": { - "version": "2.5.2", - "from": "rewire@2.5.2" - }, - "right-align": { - "version": "0.1.3", - "from": "right-align@0.1.3" - }, - "rimraf": { - "version": "2.5.3", - "from": "rimraf@2.5.3" - }, - "rollup": { - "version": "0.30.0", - "from": "rollup@0.30.0", - "dependencies": { - "source-map": { - "version": "0.1.32", - "from": "source-map@0.1.32" - }, - "source-map-support": { - "version": "0.4.1", - "from": "source-map-support@0.4.1" - } - } - }, - "rsvp": { - "version": "3.2.1", - "from": "rsvp@3.2.1" - }, - "run-async": { - "version": "0.1.0", - "from": "run-async@0.1.0" - }, - "rx-lite": { - "version": "3.1.2", - "from": "rx-lite@3.1.2" - }, - "samsam": { - "version": "1.1.2", - "from": "samsam@1.1.2" - }, - "sane": { - "version": "1.4.0", - "from": "sane@1.4.0", - "dependencies": { - "minimist": { - "version": "1.2.0", - "from": "minimist@1.2.0" - } - } - }, - "semver": { - "version": "5.2.0", - "from": "semver@5.2.0" - }, - "semver-diff": { - "version": "2.1.0", - "from": "semver-diff@2.1.0" - }, - "send": { - "version": "0.14.1", - "from": "send@0.14.1" - }, - "serve-static": { - "version": "1.11.1", - "from": "serve-static@1.11.1" - }, - "setprototypeof": { - "version": "1.0.1", - "from": "setprototypeof@1.0.1" - }, - "shebang-regex": { - "version": "1.0.0", - "from": "shebang-regex@1.0.0" - }, - "shelljs": { - "version": "0.7.0", - "from": "shelljs@0.7.0" - }, - "shellwords": { - "version": "0.1.0", - "from": "shellwords@0.1.0" - }, - "sigmund": { - "version": "1.0.1", - "from": "sigmund@1.0.1" - }, - "signal-exit": { - "version": "3.0.0", - "from": "signal-exit@3.0.0" - }, - "silent-error": { - "version": "1.0.0", - "from": "silent-error@1.0.0" - }, - "simple-fmt": { - "version": "0.1.0", - "from": "simple-fmt@0.1.0" - }, - "simple-is": { - "version": "0.2.0", - "from": "simple-is@0.2.0" - }, - "slash": { - "version": "1.0.0", - "from": "slash@1.0.0" - }, - "slice-ansi": { - "version": "0.0.4", - "from": "slice-ansi@0.0.4" - }, - "slide": { - "version": "1.1.6", - "from": "slide@1.1.6" - }, - "sntp": { - "version": "1.0.9", - "from": "sntp@1.0.9" - }, - "socket.io": { - "version": "1.4.8", - "from": "socket.io@1.4.8" - }, - "socket.io-adapter": { - "version": "0.4.0", - "from": "socket.io-adapter@0.4.0", - "dependencies": { - "socket.io-parser": { - "version": "2.2.2", - "from": "socket.io-parser@2.2.2", - "dependencies": { - "debug": { - "version": "0.7.4", - "from": "debug@0.7.4" - } - } - } - } - }, - "socket.io-client": { - "version": "1.4.8", - "from": "socket.io-client@1.4.8", - "dependencies": { - "component-emitter": { - "version": "1.2.0", - "from": "component-emitter@1.2.0" - } - } - }, - "socket.io-parser": { - "version": "2.2.6", - "from": "socket.io-parser@2.2.6", - "dependencies": { - "json3": { - "version": "3.3.2", - "from": "json3@3.3.2" - } - } - }, - "sort-keys": { - "version": "1.1.2", - "from": "sort-keys@1.1.2" - }, - "source-map": { - "version": "0.4.4", - "from": "source-map@0.4.4" - }, - "source-map-support": { - "version": "0.2.10", - "from": "source-map-support@0.2.10", - "dependencies": { - "source-map": { - "version": "0.1.32", - "from": "source-map@0.1.32" - } - } - }, - "source-map-url": { - "version": "0.3.0", - "from": "source-map-url@0.3.0" - }, - "spdx-correct": { - "version": "1.0.2", - "from": "spdx-correct@1.0.2" - }, - "spdx-exceptions": { - "version": "1.0.4", - "from": "spdx-exceptions@1.0.4" - }, - "spdx-expression-parse": { - "version": "1.0.2", - "from": "spdx-expression-parse@1.0.2" - }, - "spdx-license-ids": { - "version": "1.2.1", - "from": "spdx-license-ids@1.2.1" - }, - "split": { - "version": "1.0.0", - "from": "split@1.0.0" - }, - "split2": { - "version": "2.1.0", - "from": "split2@2.1.0" - }, - "sprintf-js": { - "version": "1.0.3", - "from": "sprintf-js@1.0.3" - }, - "sshpk": { - "version": "1.8.3", - "from": "sshpk@1.8.3", - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "from": "assert-plus@1.0.0" - } - } - }, - "stable": { - "version": "0.1.5", - "from": "stable@0.1.5" - }, - "statuses": { - "version": "1.3.0", - "from": "statuses@1.3.0" - }, - "string_decoder": { - "version": "0.10.31", - "from": "string_decoder@0.10.31" - }, - "string-template": { - "version": "1.0.0", - "from": "string-template@1.0.0" - }, - "string-width": { - "version": "1.0.1", - "from": "string-width@1.0.1", - "dependencies": { - "ansi-regex": { - "version": "2.0.0", - "from": "ansi-regex@2.0.0" - }, - "strip-ansi": { - "version": "3.0.1", - "from": "strip-ansi@3.0.1" - } - } - }, - "stringmap": { - "version": "0.2.2", - "from": "stringmap@0.2.2" - }, - "stringset": { - "version": "0.2.1", - "from": "stringset@0.2.1" - }, - "stringstream": { - "version": "0.0.5", - "from": "stringstream@0.0.5" - }, - "strip-ansi": { - "version": "0.3.0", - "from": "strip-ansi@0.3.0" - }, - "strip-bom": { - "version": "2.0.0", - "from": "strip-bom@2.0.0" - }, - "strip-indent": { - "version": "1.0.1", - "from": "strip-indent@1.0.1" - }, - "strip-json-comments": { - "version": "1.0.4", - "from": "strip-json-comments@1.0.4" - }, - "styled_string": { - "version": "0.0.1", - "from": "styled_string@0.0.1" - }, - "sum-up": { - "version": "1.0.3", - "from": "sum-up@1.0.3" - }, - "supports-color": { - "version": "0.2.0", - "from": "supports-color@0.2.0" - }, - "symlink-or-copy": { - "version": "1.1.3", - "from": "symlink-or-copy@1.1.3" - }, - "systemjs": { - "version": "0.19.31", - "from": "systemjs@0.19.31" - }, - "systemjs-builder": { - "version": "0.15.20", - "from": "systemjs-builder@0.15.20", - "dependencies": { - "babel-core": { - "version": "6.10.4", - "from": "babel-core@6.10.4" - }, - "babylon": { - "version": "6.8.4", - "from": "babylon@6.8.4" - }, - "bluebird": { - "version": "3.4.1", - "from": "bluebird@3.4.1" - }, - "source-map": { - "version": "0.5.6", - "from": "source-map@0.5.6" - } - } - }, - "table": { - "version": "3.7.8", - "from": "table@3.7.8", - "dependencies": { - "ansi-regex": { - "version": "2.0.0", - "from": "ansi-regex@2.0.0" - }, - "bluebird": { - "version": "3.4.1", - "from": "bluebird@3.4.1" - }, - "strip-ansi": { - "version": "3.0.1", - "from": "strip-ansi@3.0.1" - } - } - }, - "tap-parser": { - "version": "1.2.2", - "from": "tap-parser@1.2.2", - "dependencies": { - "isarray": { - "version": "1.0.0", - "from": "isarray@1.0.0" - }, - "readable-stream": { - "version": "2.1.4", - "from": "readable-stream@2.1.4" - } - } - }, - "temp": { - "version": "0.8.3", - "from": "temp@0.8.3", - "dependencies": { - "rimraf": { - "version": "2.2.8", - "from": "rimraf@2.2.8" - } - } - }, - "testem": { - "version": "1.9.1", - "from": "testem@1.9.1", - "dependencies": { - "bluebird": { - "version": "3.4.1", - "from": "bluebird@3.4.1" - } - } - }, - "text-extensions": { - "version": "1.3.3", - "from": "text-extensions@1.3.3" - }, - "text-table": { - "version": "0.2.0", - "from": "text-table@0.2.0" - }, - "textextensions": { - "version": "2.0.1", - "from": "textextensions@2.0.1" - }, - "thenify": { - "version": "3.2.0", - "from": "thenify@3.2.0" - }, - "throat": { - "version": "2.0.2", - "from": "throat@2.0.2" - }, - "through": { - "version": "2.3.8", - "from": "through@2.3.8" - }, - "through2": { - "version": "2.0.1", - "from": "through2@2.0.1", - "dependencies": { - "isarray": { - "version": "1.0.0", - "from": "isarray@1.0.0" - }, - "readable-stream": { - "version": "2.0.6", - "from": "readable-stream@2.0.6" - } - } - }, - "timed-out": { - "version": "2.0.0", - "from": "timed-out@2.0.0" - }, - "tiny-lr": { - "version": "0.2.1", - "from": "tiny-lr@0.2.1", - "dependencies": { - "qs": { - "version": "5.1.0", - "from": "qs@5.1.0" - } - } - }, - "tmp": { - "version": "0.0.28", - "from": "tmp@0.0.28" - }, - "tmpl": { - "version": "1.0.4", - "from": "tmpl@1.0.4" - }, - "to-array": { - "version": "0.1.4", - "from": "to-array@0.1.4" - }, - "to-fast-properties": { - "version": "1.0.2", - "from": "to-fast-properties@1.0.2" - }, - "to-iso-string": { - "version": "0.0.2", - "from": "to-iso-string@0.0.2" - }, - "touch": { - "version": "1.0.0", - "from": "touch@1.0.0", - "dependencies": { - "nopt": { - "version": "1.0.10", - "from": "nopt@1.0.10" - } - } - }, - "tough-cookie": { - "version": "2.2.2", - "from": "tough-cookie@2.2.2" - }, - "traceur": { - "version": "0.0.105", - "from": "traceur@0.0.105", - "dependencies": { - "glob": { - "version": "5.0.15", - "from": "glob@5.0.15" - }, - "semver": { - "version": "4.3.6", - "from": "semver@4.3.6" - } - } - }, - "tree-sync": { - "version": "1.1.2", - "from": "tree-sync@1.1.2" - }, - "trim-newlines": { - "version": "1.0.0", - "from": "trim-newlines@1.0.0" - }, - "trim-off-newlines": { - "version": "1.0.0", - "from": "trim-off-newlines@1.0.0" - }, - "trim-right": { - "version": "1.0.1", - "from": "trim-right@1.0.1" - }, - "try-resolve": { - "version": "1.0.1", - "from": "try-resolve@1.0.1" - }, - "tryit": { - "version": "1.0.2", - "from": "tryit@1.0.2" - }, - "tryor": { - "version": "0.1.2", - "from": "tryor@0.1.2" - }, - "tunnel-agent": { - "version": "0.4.3", - "from": "tunnel-agent@0.4.3" - }, - "tv4": { - "version": "1.2.7", - "from": "tv4@1.2.7" - }, - "tweetnacl": { - "version": "0.13.3", - "from": "tweetnacl@0.13.3" - }, - "type-check": { - "version": "0.3.2", - "from": "type-check@0.3.2" - }, - "type-detect": { - "version": "1.0.0", - "from": "type-detect@1.0.0" - }, - "type-is": { - "version": "1.6.13", - "from": "type-is@1.6.13" - }, - "typedarray": { - "version": "0.0.6", - "from": "typedarray@0.0.6" - }, - "typescript": { - "version": "1.8.10", - "from": "typescript@1.8.10" - }, - "typings": { - "version": "0.8.1", - "from": "typings@0.8.1", - "dependencies": { - "bluebird": { - "version": "3.4.1", - "from": "bluebird@3.4.1" - }, - "minimist": { - "version": "1.2.0", - "from": "minimist@1.2.0" - }, - "wordwrap": { - "version": "1.0.0", - "from": "wordwrap@1.0.0" - } - } - }, - "typings-core": { - "version": "0.3.1", - "from": "typings-core@0.3.1", - "dependencies": { - "detect-indent": { - "version": "4.0.0", - "from": "detect-indent@4.0.0" - }, - "repeating": { - "version": "2.0.1", - "from": "repeating@2.0.1" - } - } - }, - "uc.micro": { - "version": "1.0.2", - "from": "uc.micro@1.0.2" - }, - "uglify-js": { - "version": "2.7.0", - "from": "uglify-js@2.7.0", - "dependencies": { - "async": { - "version": "0.2.10", - "from": "async@0.2.10" - }, - "source-map": { - "version": "0.5.6", - "from": "source-map@0.5.6" - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "from": "uglify-to-browserify@1.0.2" - }, - "ultron": { - "version": "1.0.2", - "from": "ultron@1.0.2" - }, - "unc-path-regex": { - "version": "0.1.2", - "from": "unc-path-regex@0.1.2" - }, - "underscore": { - "version": "1.8.3", - "from": "underscore@1.8.3" - }, - "underscore.string": { - "version": "3.3.4", - "from": "underscore.string@3.3.4" - }, - "unpipe": { - "version": "1.0.0", - "from": "unpipe@1.0.0" - }, - "untildify": { - "version": "2.1.0", - "from": "untildify@2.1.0" - }, - "unzip-response": { - "version": "1.0.0", - "from": "unzip-response@1.0.0" - }, - "update-notifier": { - "version": "0.6.3", - "from": "update-notifier@0.6.3" - }, - "url-parse-lax": { - "version": "1.0.0", - "from": "url-parse-lax@1.0.0" - }, - "user-home": { - "version": "1.1.1", - "from": "user-home@1.1.1" - }, - "utf8": { - "version": "2.1.0", - "from": "utf8@2.1.0" - }, - "util": { - "version": "0.10.3", - "from": "util@0.10.3" - }, - "util-deprecate": { - "version": "1.0.2", - "from": "util-deprecate@1.0.2" - }, - "utils-merge": { - "version": "1.0.0", - "from": "utils-merge@1.0.0" - }, - "uuid": { - "version": "2.0.2", - "from": "uuid@2.0.2" - }, - "validate-npm-package-license": { - "version": "3.0.1", - "from": "validate-npm-package-license@3.0.1" - }, - "vary": { - "version": "1.1.0", - "from": "vary@1.1.0" - }, - "verror": { - "version": "1.3.6", - "from": "verror@1.3.6" - }, - "walk-sync": { - "version": "0.2.7", - "from": "walk-sync@0.2.7" - }, - "walker": { - "version": "1.0.7", - "from": "walker@1.0.7" - }, - "watch": { - "version": "0.10.0", - "from": "watch@0.10.0" - }, - "wcwidth": { - "version": "1.0.1", - "from": "wcwidth@1.0.1" - }, - "websocket-driver": { - "version": "0.6.5", - "from": "websocket-driver@0.6.5" - }, - "websocket-extensions": { - "version": "0.1.1", - "from": "websocket-extensions@0.1.1" - }, - "when": { - "version": "3.7.7", - "from": "when@3.7.7" - }, - "which": { - "version": "1.2.10", - "from": "which@1.2.10" - }, - "widest-line": { - "version": "1.0.0", - "from": "widest-line@1.0.0" - }, - "window-size": { - "version": "0.1.0", - "from": "window-size@0.1.0" - }, - "wordwrap": { - "version": "0.0.3", - "from": "wordwrap@0.0.3" - }, - "wrappy": { - "version": "1.0.2", - "from": "wrappy@1.0.2" - }, - "write": { - "version": "0.2.1", - "from": "write@0.2.1" - }, - "write-file-atomic": { - "version": "1.1.4", - "from": "write-file-atomic@1.1.4" - }, - "ws": { - "version": "1.1.0", - "from": "ws@1.1.0" - }, - "xdg-basedir": { - "version": "2.0.0", - "from": "xdg-basedir@2.0.0" - }, - "xmldom": { - "version": "0.1.22", - "from": "xmldom@0.1.22" - }, - "xmlhttprequest-ssl": { - "version": "1.5.1", - "from": "xmlhttprequest-ssl@1.5.1" - }, - "xregexp": { - "version": "3.1.1", - "from": "xregexp@3.1.1" - }, - "xtend": { - "version": "4.0.1", - "from": "xtend@4.0.1" - }, - "y18n": { - "version": "3.2.1", - "from": "y18n@3.2.1" - }, - "yallist": { - "version": "2.0.0", - "from": "yallist@2.0.0" - }, - "yam": { - "version": "0.0.18", - "from": "yam@0.0.18", - "dependencies": { - "fs-extra": { - "version": "0.16.5", - "from": "fs-extra@0.16.5" - }, - "graceful-fs": { - "version": "3.0.8", - "from": "graceful-fs@3.0.8" - }, - "lodash.isplainobject": { - "version": "3.2.0", - "from": "lodash.isplainobject@3.2.0" - }, - "lodash.keysin": { - "version": "3.0.8", - "from": "lodash.keysin@3.0.8" - }, - "lodash.merge": { - "version": "3.3.2", - "from": "lodash.merge@3.3.2" - } - } - }, - "yargs": { - "version": "3.10.0", - "from": "yargs@3.10.0" - }, - "yeast": { - "version": "0.1.2", - "from": "yeast@0.1.2" - }, - "zip-object": { - "version": "0.1.0", - "from": "zip-object@0.1.0" - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 4aafdb5f276e..f3ef0b6eba63 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "scripts": { "test": "node tests/runner", "mobile_test": "mocha tests/e2e/e2e_workflow.spec.js", + "test:inspect": "node --inspect --debug-brk tests/runner", "lint": "eslint ." }, "repository": { @@ -31,32 +32,76 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "broccoli": "^1.0.0-beta.7", - "broccoli-caching-writer": "^2.2.1", - "broccoli-concat": "^2.2.0", - "broccoli-funnel": "^1.0.1", - "broccoli-merge-trees": "^1.1.1", - "broccoli-source": "^1.1.0", - "broccoli-uglify-js": "^0.1.3", - "broccoli-writer": "^0.1.1", + "@angular/compiler-cli": "^0.2.0", + "@types/lodash": "^4.0.25-alpha", + "@types/rimraf": "0.0.25-alpha", + "@types/webpack": "^1.12.22-alpha", + "angular2-template-loader": "^0.4.0", + "awesome-typescript-loader": "^2.0.1", "chalk": "^1.1.3", + "compression-webpack-plugin": "^0.3.1", + "copy-webpack-plugin": "^3.0.1", + "core-js": "^2.4.0", + "css-loader": "^0.23.1", "ember-cli": "2.5.0", "ember-cli-string-utils": "^1.0.0", + "enhanced-resolve": "^2.2.2", "exit": "^0.1.2", + "exports-loader": "^0.6.3", + "expose-loader": "^0.7.1", + "file-loader": "^0.8.5", "fs-extra": "^0.30.0", "glob": "^7.0.3", "handlebars": "^4.0.5", + "html-webpack-plugin": "^2.19.0", + "istanbul-instrumenter-loader": "^0.2.0", + "json-loader": "^0.5.4", + "karma": "^0.13.22", + "karma-chrome-launcher": "^1.0.1", + "karma-coverage": "^1.0.0", + "karma-jasmine": "^1.0.2", + "karma-mocha-reporter": "^2.0.4", + "karma-phantomjs-launcher": "^1.0.0", + "karma-sourcemap-loader": "^0.3.7", + "karma-webpack": "^1.7.0", "leek": "0.0.21", + "less": "^2.7.1", + "less-loader": "^2.2.3", "lodash": "^4.11.1", + "node-sass": "^3.7.0", "npm": "3.10.2", + "offline-plugin": "^3.4.1", "opn": "4.0.1", + "parse5": "^2.1.5", + "phantomjs-polyfill": "0.0.2", + "phantomjs-prebuilt": "^2.1.7", + "postcss-loader": "^0.9.1", + "protractor": "^3.3.0", + "raw-loader": "^0.5.1", + "remap-istanbul": "^0.6.4", "resolve": "^1.1.7", + "rimraf": "^2.5.3", + "sass-loader": "^3.2.0", "shelljs": "^0.7.0", "silent-error": "^1.0.0", + "source-map-loader": "^0.1.5", + "style-loader": "^0.13.1", + "stylus": "^0.54.5", + "stylus-loader": "^2.1.0", "symlink-or-copy": "^1.0.3", - "systemjs-builder": "0.15.20", - "typescript": "^1.8.10", - "typings": "^0.8.1" + "systemjs-builder": "0.15.17", + "ts-helpers": "^1.1.1", + "ts-loader": "^0.8.2", + "tslint": "^3.11.0", + "tslint-loader": "^2.1.4", + "typedoc": "^0.4.2", + "typescript": "^2.0.0", + "typings": "^0.8.1", + "url-loader": "^0.5.7", + "webpack": "2.1.0-beta.17", + "webpack-dev-server": "^1.14.1", + "webpack-md5-hash": "0.0.5", + "webpack-merge": "^0.14.0" }, "ember-addon": { "paths": [ diff --git a/tests/e2e/e2e_workflow.spec.js b/tests/e2e/e2e_workflow.spec.js index 5d8930bfe655..9232c1ba0a00 100644 --- a/tests/e2e/e2e_workflow.spec.js +++ b/tests/e2e/e2e_workflow.spec.js @@ -84,17 +84,20 @@ describe('Basic end-to-end Workflow', function () { // stuck to the first build done sh.exec(`${ngBin} build -prod`); expect(existsSync(path.join(process.cwd(), 'dist'))).to.be.equal(true); - if (!isMobileTest()) { - var mainBundlePath = path.join(process.cwd(), 'dist', 'main.js'); - var mainBundleContent = fs.readFileSync(mainBundlePath, { encoding: 'utf8' }); - // production: true minimized turns into production:!0 - expect(mainBundleContent).to.include('production:!0'); - } - + const indexHtml = fs.readFileSync(path.join(process.cwd(), 'dist/index.html'), 'utf-8'); + // Check for cache busting hash script src + expect(indexHtml).to.match(/main\.[0-9a-f]{20}\.bundle\.js/); // Also does not create new things in GIT. expect(sh.exec('git status --porcelain').output).to.be.equal(undefined); }); + xit('Supports production builds config file replacement', function() { + var mainBundlePath = path.join(process.cwd(), 'dist', 'main.js'); + var mainBundleContent = fs.readFileSync(mainBundlePath, { encoding: 'utf8' }); + // production: true minimized turns into production:!0 + expect(mainBundleContent).to.include('production:!0'); + }); + it_mobile('Enables mobile-specific production features', () => { let index = fs.readFileSync(path.join(process.cwd(), 'dist/index.html'), 'utf-8'); // Service Worker @@ -119,11 +122,9 @@ describe('Basic end-to-end Workflow', function () { }) .then(function () { expect(existsSync(path.join(process.cwd(), 'dist'))).to.be.equal(true); - // Check the index.html to have no handlebar tokens in it. const indexHtml = fs.readFileSync(path.join(process.cwd(), 'dist/index.html'), 'utf-8'); - expect(indexHtml).to.not.include('{{'); - expect(indexHtml).to.include('vendor/es6-shim/es6-shim.js'); + expect(indexHtml).to.include('main.bundle.js'); }) .then(function () { // Also does not create new things in GIT. @@ -186,12 +187,12 @@ describe('Basic end-to-end Workflow', function () { var ngServePid; function executor(resolve, reject) { - var serveProcess = child_process.exec(`${ngBin} serve`); + var serveProcess = child_process.exec(`${ngBin} serve`, {maxBuffer: 500*1024}); var startedProtractor = false; ngServePid = serveProcess.pid; serveProcess.stdout.on('data', (data) => { - if (/Build successful/.test(data) && !startedProtractor) { + if (/webpack: bundle is now VALID/.test(data.toString('utf-8')) && !startedProtractor) { startedProtractor = true; child_process.exec(`${ngBin} e2e`, (error, stdout, stderr) => { if (error !== null) { @@ -200,8 +201,6 @@ describe('Basic end-to-end Workflow', function () { resolve(); } }); - } else if (/ failed with:/.test(data)) { - reject(data); } }); @@ -459,7 +458,7 @@ describe('Basic end-to-end Workflow', function () { }); }); - it_not_mobile('Turn on path mapping in tsconfig.json and rebuild', function () { + xit('Turn on path mapping in tsconfig.json and rebuild', function () { this.timeout(420000); const configFilePath = path.join(process.cwd(), 'src', 'tsconfig.json'); @@ -497,12 +496,12 @@ describe('Basic end-to-end Workflow', function () { var ngServePid; function executor(resolve, reject) { - var serveProcess = child_process.exec(`${ngBin} serve`); + var serveProcess = child_process.exec(`${ngBin} serve`, {maxBuffer: 500*1024}); var startedProtractor = false; ngServePid = serveProcess.pid; serveProcess.stdout.on('data', (data) => { - if (/Build successful/.test(data) && !startedProtractor) { + if (/webpack: bundle is now VALID/.test(data.toString('utf-8')) && !startedProtractor) { startedProtractor = true; child_process.exec(`${ngBin} e2e`, (error, stdout, stderr) => { if (error !== null) { @@ -511,8 +510,6 @@ describe('Basic end-to-end Workflow', function () { resolve(); } }); - } else if (/ failed with:/.test(data)) { - reject(data); } }); diff --git a/tsconfig.json b/tsconfig.json index 9633bb74b268..d37ed087389f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,6 +12,7 @@ "rootDir": ".", "sourceMap": true, "sourceRoot": "/", - "target": "es5" + "target": "es5", + "lib": ["es6", "dom"] } } From 7786ed3f09da866f546fab0cf3f96df7b79629d3 Mon Sep 17 00:00:00 2001 From: Sean Larkin Date: Thu, 14 Jul 2016 18:53:09 -0500 Subject: [PATCH 02/38] chore(lint) Corrected any eslint errors and cleaned up unused files --- .../ng2/files/__path__/tsconfig.json | 4 +- addon/ng2/commands/test.js | 37 +-- addon/ng2/models/builder.ts | 161 ----------- addon/ng2/models/save-for-later.ts | 272 ------------------ addon/ng2/models/webpack-build-common.ts | 2 +- addon/ng2/models/webpack-karma-config.ts | 30 -- addon/ng2/tasks/test.js | 14 +- tests/e2e/e2e_workflow.spec.js | 6 +- 8 files changed, 13 insertions(+), 513 deletions(-) delete mode 100644 addon/ng2/models/builder.ts delete mode 100644 addon/ng2/models/save-for-later.ts delete mode 100644 addon/ng2/models/webpack-karma-config.ts diff --git a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json index 165a050f79b0..b93d0146f892 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json @@ -5,11 +5,11 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "module": "es6", - "target": "es5", "moduleResolution": "node", "outDir": "./dist/", "rootDir": ".", - "sourceMap": true + "sourceMap": true, + "target": "es5" }, "compileOnSave": false, "buildOnSave": false, diff --git a/addon/ng2/commands/test.js b/addon/ng2/commands/test.js index aab5451ace50..15ea63fa075a 100644 --- a/addon/ng2/commands/test.js +++ b/addon/ng2/commands/test.js @@ -3,10 +3,7 @@ var Promise = require('ember-cli/lib/ext/promise'); var TestCommand = require('ember-cli/lib/commands/test'); var win = require('ember-cli/lib/utilities/windows-admin'); -// var BuildTask = require('ember-cli/lib/tasks/build'); -// var BuildWatchTask = require('ember-cli/lib/tasks/build-watch'); -const BuildWebpack = require('../tasks/build-webpack'); -const BuildWebpackWatch = require('../tasks/build-webpack-watch'); + const config = require('../models/config'); const TestTask = require('../tasks/test'); @@ -25,44 +22,16 @@ module.exports = TestCommand.extend({ run: function (commandOptions) { this.project.ngConfig = this.project.ngConfig || config.CliConfig.fromProject(); - // var buildWatchTask = - // new BuildWebpackWatch({ - // ui: this.ui, - // analytics: this.analytics, - // project: this.project - // }); - // var buildTask = new BuildWebpack({ - // ui: this.ui, - // analytics: this.analytics, - // project: this.project - // }); var testTask = new TestTask({ ui: this.ui, analytics: this.analytics, project: this.project }); - // var buildOptions = { - // environment: 'development', - // outputPath: 'dist/' - // }; - - // If not building, mock/suppress build tasks. - // if (!commandOptions.build) { - // buildTask = { - // run: () => { - // return; - // } - // }; - // buildWatchTask = buildTask; - // } - if (commandOptions.watch) { return win.checkWindowsElevation(this.ui) .then( () => { - // perform initial build to avoid race condition - // return buildTask.run(buildOptions); }, () => { /* handle build error to allow watch mode to start */ @@ -74,14 +43,10 @@ module.exports = TestCommand.extend({ // if not watching ensure karma is doing a single run commandOptions.singleRun = true; return win.checkWindowsElevation(this.ui) - // .then(() => { - // return buildTask.run(buildOptions); - // }) .then(() => { return testTask.run(commandOptions); }); } - } }); diff --git a/addon/ng2/models/builder.ts b/addon/ng2/models/builder.ts deleted file mode 100644 index 62b16304c71d..000000000000 --- a/addon/ng2/models/builder.ts +++ /dev/null @@ -1,161 +0,0 @@ -const fs = require('fs-extra'); -const existsSync = require('exists-sync'); -const path = require('path'); -const Promise = require('ember-cli/lib/ext/promise'); -const Task = require('ember-cli/lib/models/task'); -const SilentError = require('silent-error'); -const chalk = require('chalk'); -const attemptNeverIndex = require('ember-cli/lib/utilities/attempt-never-index'); -const findBuildFile = require('ember-cli/lib/utilities/find-build-file'); -const viz = require('broccoli-viz'); -const FSMonitor = require('fs-monitor-stack'); -const Sync = require('tree-sync'); -const mkdirp = require('mkdirp'); - -let resolve = null; -let promise = new Promise((r) => resolve = r); - - - - -var signalsTrapped = false; -var buildCount = 0; - -function outputViz(count, result, monitor) { - var processed = viz.process(result.graph); - - processed.forEach(function(node) { - node.stats.fs = monitor.statsFor(node); - }); - - fs.writeFileSync('graph.' + count + '.dot', viz.dot(processed)); - fs.writeFileSync('graph.' + count + '.json', JSON.stringify({ - summary: { - buildCount: count, - output: result.directory, - totalTime: result.totalTime, - totalNodes: processed.length, - stats: { - fs: monitor.totalStats() - } - }, - nodes: processed - })); -} - -module.exports = Task.extend({ - setupBuilder: function() { - this.environment = this.environment || 'development'; - process.env.ANGULAR_ENV = process.env.ANGULAR_ENV || process.env.EMBER_CLI || this.environment; - process.env.EMBER_ENV = process.env.ANGULAR_ENV; - - var buildFile = findBuildFile('angular-cli-build.js'); - this.tree = buildFile({ project: this.project }); - - if (webpack) { - console.log('webpack'); - } else { - var broccoli = require('ember-cli-broccoli'); - this.builder = new broccoli.Builder(this.tree); - } - }, - - trapSignals: function() { - if (!signalsTrapped) { - process.on('SIGINT', this.onSIGINT.bind(this)); - process.on('SIGTERM', this.onSIGTERM.bind(this)); - process.on('message', this.onMessage.bind(this)); - signalsTrapped = true; - } - }, - - init: function() { - this.setupBuilder(); - this.trapSignals(); - }, - - /** - Determine whether the output path is safe to delete. If the outputPath - appears anywhere in the parents of the project root, the build would - delete the project directory. In this case return `false`, otherwise - return `true`. - */ - canDeleteOutputPath: function(outputPath) { - var rootPathParents = [this.project.root]; - var dir = path.dirname(this.project.root); - rootPathParents.push(dir); - while (dir !== path.dirname(dir)) { - dir = path.dirname(dir); - rootPathParents.push(dir); - } - return rootPathParents.indexOf(outputPath) === -1; - }, - - copyToOutputPath: function(inputPath) { - var outputPath = this.outputPath; - - mkdirp.sync(outputPath); - - if (!this.canDeleteOutputPath(outputPath)) { - throw new SilentError('Using a build destination path of `' + outputPath + '` is not supported.'); - } - - var sync = this._sync; - if (sync === undefined) { - this._sync = sync = new Sync(inputPath, path.resolve(this.outputPath)); - } - - sync.sync(); - }, - - build: function(...args: any[]) { - attemptNeverIndex('tmp'); - return promise; - // return Promise.resolve(); - // if (this.webpack) { - // console.log(1, process.cwd()); - // return new Promise((resolve, reject) => { - // this.webpack.run((err, stats) => { - // console.log(!!err, stats); - // if (err) { - // reject(err); - // } - // resolve(); - // }); - // }); - // } - // return this.builder.build(...args); - }, - - cleanup: function() { - var ui = this.ui; - - // if (this.webpack) { - // this.webpack.cleanupAndExit(); - return Promise.resolve(); - // } else { - // return this.builder.cleanup().catch(function (err) { - // ui.writeLine(chalk.red('Cleanup error.')); - // ui.writeError(err); - // }); - // } - }, - - cleanupAndExit: function() { - this.cleanup().finally(function() { - process.exit(1); - }); - }, - - onSIGINT: function() { - this.cleanupAndExit(); - }, - onSIGTERM: function() { - this.cleanupAndExit(); - }, - onMessage: function(message) { - if (message.kill) { - this.cleanupAndExit(); - } - } -}); diff --git a/addon/ng2/models/save-for-later.ts b/addon/ng2/models/save-for-later.ts deleted file mode 100644 index 643ff92cfaf9..000000000000 --- a/addon/ng2/models/save-for-later.ts +++ /dev/null @@ -1,272 +0,0 @@ - -// new webpack.LoaderOptionsPlugin({ -// minimize: true -// }), -// new webpack.LoaderOptionsPlugin({ -// test: /\.js$/, -// jsfile: true -// }) -// new ClosureCompilerPlugin({ -// compiler: { -// language_in: 'ECMASCRIPT5', -// language_out: 'ECMASCRIPT5', -// compilation_level: 'SIMPLE' -// }, -// concurrency: 3, -// }) - - - - -// ts: { -// configFileName: ngAppResolve('./src/tsconfig.json'), -// silent: true -// }, -// output: { -// path: './dist/', -// filename: '[name].[chunkhash].js', -// sourceMapFilename: '[name].[chunkhash].map', -// chunkFilename: '[chunkhash].js' -// }, -// recordsPath: path.join(__dirname, "records.json"), -// -// -// -// -// new webpack.optimize.CommonsChunkPlugin({ -// names: ['main', 'vendors', 'polyfills'] -// }), -// new webpack.optimize.CommonsChunkPlugin({ -// minChunks: Infinity, -// name: 'inline', -// filename: 'inline.js', -// sourceMapFilename: 'inline.map' -// }), -// new HtmlWebpackPlugin({ -// template:'./src/index.html', -// chunksSortMode: "dependency" -// }) -// -// -// export const materialEntryConfig: {[key: string]: any} = { -// demoMain: [ngAppResolve('./src/demo-app/main.ts')], -// e2eMain: [ngAppResolve('./src/e2e-app/main.ts')], -// core: [ngAppResolve('./src/core/core.ts')], -// vendor: [ -// "@angular/common", -// "@angular/compiler", -// "@angular/core", -// "@angular/http", -// "@angular/platform-browser", -// "@angular/platform-browser-dynamic", -// "@angular/router", -// ], -// polyfills: [ -// "core-js", -// "hammerjs", -// "rxjs", -// "systemjs", -// "zone.js" -// ] -// } - -// export const materialPluginsConfig: any[] = [ -// new webpack.optimize.CommonsChunkPlugin({ -// name: ['polyfills', 'vendor'].reverse() -// }), -// new HtmlWebpackPlugin({ -// template: ngAppResolve('./demo-app/index.html'), -// chunksSortMode: 'dependency' -// }) -// ]; -// -// -// -// -// -// const webpack = require('webpack'); -// const HtmlWebpackPlugin = require('html-webpack-plugin'); -// const CopyWebpackPlugin = require('copy-webpack-plugin'); -// const path = require('path'); -// const ClosureCompilerPlugin = require('webpack-closure-compiler'); -// const autoprefixer = require('autoprefixer'); -// const cssnano = require('cssnano'); -// const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin; -// // Resolve to the generated applications - - - - -// let baseHtmlTemplateConfig = { -// template: ngAppResolve('./src/index.html'), -// chunksSortMode: 'dependency' -// }; -// // These are the output -// const webpackTestPartial = { -// module: { -// plugins: [ -// new ForkCheckerPlugin(), -// new HtmlWebpackPlugin(baseHtmlTemplateConfig), -// ], -// preLoaders: [ -// { -// test: /\.ts$/, -// loader: 'tslint-loader', -// exclude: ['node_modules'] -// }, -// { -// test: /\.js$/, -// loader: 'source-map-loader', -// exclude: [ -// // these packages have problems with their sourcemaps -// ngAppResolve('node_modules/rxjs'), -// ngAppResolve('node_modules/@angular') -// ]} -// ], -// loaders: [ -// { -// test: /\.ts$/, -// loaders: [ -// { -// loader: 'awesome-typescript-loader', -// query: { -// useWebpackText: true, -// tsconfig: ngAppResolve('./src/tsconfig.json'), -// resolveGlobs: false, -// module: "es2015", -// target: "es5", -// library: 'es6', -// useForkChecker: true, -// removeComments: true -// } -// }, -// { -// loader: 'angular2-template-loader' -// } -// ], -// exclude: [/\.(spec|e2e)\.ts$/] -// }, -// { test: /\.json$/, loader: 'json-loader', exclude: [ngAppResolve('src/index.html')] }, -// { test: /\.css$/, loader: 'raw-loader', exclude: [ngAppResolve('src/index.html')] }, -// { test: /\.html$/, loader: 'raw-loader', exclude: [ngAppResolve('src/index.html')] } -// ] -// }, -// tslint: { -// emitErrors: false, -// failOnHint: false, -// resourcePath: 'src' -// }, -// node: { -// global: 'window', -// process: false, -// crypto: 'empty', -// module: false, -// clearImmediate: false, -// setImmediate: false -// } -// }; - -// Webpack Configuration Object -// Used in build.ts - -// var webpack = require('webpack'); -// var path = require('path'); - - -// // Webpack Config -// var webpackConfig = { -// devtool: "#source-map", -// entry: { -// 'angular2polyfills': [ -// // 'ie-shim', -// 'core-js/es6/symbol', -// 'core-js/es6/object', -// 'core-js/es6/function', -// 'core-js/es6/parse-int', -// 'core-js/es6/parse-float', -// 'core-js/es6/number', -// 'core-js/es6/math', -// 'core-js/es6/string', -// 'core-js/es6/date', -// 'core-js/es6/array', -// 'core-js/es6/regexp', -// 'core-js/es6/map', -// 'core-js/es6/set', -// 'core-js/es6/weak-map', -// 'core-js/es6/weak-set', -// 'core-js/es6/typed', -// 'core-js/es6/reflect', -// // 'core-js/es6/promise', // problem with firefox -// 'core-js/es7/reflect', -// 'zone.js/dist/zone', -// 'zone.js/dist/long-stack-trace-zone', -// ], -// 'angular2vendor': [ -// '@angular/platform-browser', -// '@angular/platform-browser-dynamic', -// '@angular/core', -// '@angular/common', -// '@angular/forms', -// '@angular/http', -// '@angular/router', -// ] -// }, - -// output: { -// path: './dist', -// filename: 'dll.[name].[hash].bundle.js', -// sourceMapFilename: '[name].map', -// chunkFilename: '[id].chunk.js', -// library: '__DLL_[name]', -// }, - - -// plugins: [ -// new webpack.DllPlugin({ -// name: '[vendor]', -// path: 'dist/vendor-manifest.json', -// }), -// new webpack.DllPlugin({ -// name: 'polyfills', -// path: 'dist/polyfills-manifest.json', -// }), -// ], - -// module: { -// preLoaders: [ -// { -// test: /\.js$/, -// loader: 'source-map-loader', -// exclude: [ -// // these packages have problems with their sourcemaps -// path.resolve(__dirname, 'node_modules', 'rxjs'), -// path.resolve(__dirname, 'node_modules', '@angular'), -// path.resolve(__dirname, 'node_modules', '@ngrx'), -// path.resolve(__dirname, 'node_modules', '@angular2-material'), -// ] -// } - -// ], -// loaders: [ -// ] -// }, - -// node: { -// global: 'window', -// crypto: 'empty', -// module: false, -// clearImmediate: false, -// setImmediate: false -// } - -// }; - - - - - - - - - - diff --git a/addon/ng2/models/webpack-build-common.ts b/addon/ng2/models/webpack-build-common.ts index 7d07ff0be416..b633ae5c1135 100644 --- a/addon/ng2/models/webpack-build-common.ts +++ b/addon/ng2/models/webpack-build-common.ts @@ -71,7 +71,7 @@ export const getWebpackCommonConfig = function(projectRoot: string) { chunksSortMode: 'dependency' }), new webpack.optimize.CommonsChunkPlugin({ - name: ['polyfills', 'vendor'].reverse() + name: ['vendor', 'polyfills'] }), new webpack.optimize.CommonsChunkPlugin({ minChunks: Infinity, diff --git a/addon/ng2/models/webpack-karma-config.ts b/addon/ng2/models/webpack-karma-config.ts deleted file mode 100644 index 1640043fd31f..000000000000 --- a/addon/ng2/models/webpack-karma-config.ts +++ /dev/null @@ -1,30 +0,0 @@ -export default function(config) { - var testWebpackConfig = require('./webpack.test.js'); - config.set({ - basePath: '', - frameworks: ['jasmine'], - exclude: [ ], - files: [ { pattern: './config/spec-bundle.js', watched: false } ], - coverageReporter: { - dir : 'coverage/', - reporters: [ - { type: 'text-summary' }, - { type: 'json' }, - { type: 'html' } - ] - }, - preprocessors: { './config/spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] }, - webpack: testWebpackConfig, - webpackServer: { noInfo: true }, - reporters: ['progress', 'mocha', 'coverage' ], - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: false, - browsers: [ - // 'Chrome', - 'PhantomJS' - ], - singleRun: true - }); -}; diff --git a/addon/ng2/tasks/test.js b/addon/ng2/tasks/test.js index 79fec18489ca..5fbbcea453e5 100644 --- a/addon/ng2/tasks/test.js +++ b/addon/ng2/tasks/test.js @@ -4,9 +4,7 @@ var Promise = require('ember-cli/lib/ext/promise'); var Task = require('ember-cli/lib/models/task'); var path = require('path'); -var ngAppResolve = require('../models').ngAppResolve; var webpackTestConfig = require('../models/webpack-build-test').getWebpackTestConfig; -var displayOptions = require('../models/webpack-build-utils').webpackOutputOptions; // require dependencies within the target project function requireDependency(root, moduleName) { @@ -24,12 +22,12 @@ module.exports = Task.extend({ var karmaConfig = path.join(projectRoot, this.project.ngConfig.test.karma.config); options.plugins = [ - require("karma-webpack"), - require("karma-jasmine"), - require("karma-chrome-launcher"), - require("karma-coverage"), - require("karma-mocha-reporter"), - require("karma-sourcemap-loader"), + require('karma-webpack'), + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-coverage'), + require('karma-mocha-reporter'), + require('karma-sourcemap-loader') ]; options.reporters = ['coverage', 'mocha', 'progress']; diff --git a/tests/e2e/e2e_workflow.spec.js b/tests/e2e/e2e_workflow.spec.js index 9232c1ba0a00..17f6510063a9 100644 --- a/tests/e2e/e2e_workflow.spec.js +++ b/tests/e2e/e2e_workflow.spec.js @@ -91,7 +91,7 @@ describe('Basic end-to-end Workflow', function () { expect(sh.exec('git status --porcelain').output).to.be.equal(undefined); }); - xit('Supports production builds config file replacement', function() { + xit('Supports production builds config file replacement', function() { var mainBundlePath = path.join(process.cwd(), 'dist', 'main.js'); var mainBundleContent = fs.readFileSync(mainBundlePath, { encoding: 'utf8' }); // production: true minimized turns into production:!0 @@ -187,7 +187,7 @@ describe('Basic end-to-end Workflow', function () { var ngServePid; function executor(resolve, reject) { - var serveProcess = child_process.exec(`${ngBin} serve`, {maxBuffer: 500*1024}); + var serveProcess = child_process.exec(`${ngBin} serve`, { maxBuffer: 500*1024 }); var startedProtractor = false; ngServePid = serveProcess.pid; @@ -496,7 +496,7 @@ describe('Basic end-to-end Workflow', function () { var ngServePid; function executor(resolve, reject) { - var serveProcess = child_process.exec(`${ngBin} serve`, {maxBuffer: 500*1024}); + var serveProcess = child_process.exec(`${ngBin} serve`, { maxBuffer: 500*1024 }); var startedProtractor = false; ngServePid = serveProcess.pid; From cf441a7c92850b84bbc0f9dc9fb063e3aea28fff Mon Sep 17 00:00:00 2001 From: Sean Larkin Date: Thu, 14 Jul 2016 22:43:46 -0500 Subject: [PATCH 03/38] chore(cleanup) additional cleanup tasks performed. Removed unneeded code, indentation causing linting errors, add back tsconfig sourcemapping, removed console logs, deleted material unused files. --- .../ng2/files/__path__/polyfills.ts | 16 +- .../ng2/blueprints/ng2/files/__path__/test.ts | 20 +- .../ng2/files/__path__/tsconfig.json | 4 +- .../blueprints/ng2/files/__path__/vendor.ts | 2 +- addon/ng2/blueprints/ng2/files/package.json | 6 +- addon/ng2/commands/build.ts | 2 - addon/ng2/models/index.ts | 3 - addon/ng2/models/webpack-build-common.ts | 2 +- addon/ng2/models/webpack-build-material2.ts | 224 ------------------ addon/ng2/models/webpack-build-production.ts | 10 +- addon/ng2/models/webpack-config.ts | 26 +- addon/ng2/tasks/build-webpack-watch.ts | 4 +- addon/ng2/tasks/serve-webpack.ts | 7 +- package.json | 3 +- tsconfig.json | 7 +- 15 files changed, 50 insertions(+), 286 deletions(-) delete mode 100644 addon/ng2/models/webpack-build-material2.ts diff --git a/addon/ng2/blueprints/ng2/files/__path__/polyfills.ts b/addon/ng2/blueprints/ng2/files/__path__/polyfills.ts index 492efbe2f5cf..8e73613fac7a 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/polyfills.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/polyfills.ts @@ -1,4 +1,18 @@ // Prefer CoreJS over the polyfills above -import 'core-js/es6'; +import 'core-js/es6/symbol'; +import 'core-js/es6/object'; +import 'core-js/es6/function'; +import 'core-js/es6/parse-int'; +import 'core-js/es6/parse-float'; +import 'core-js/es6/number'; +import 'core-js/es6/math'; +import 'core-js/es6/string'; +import 'core-js/es6/date'; +import 'core-js/es6/array'; +import 'core-js/es6/regexp'; +import 'core-js/es6/map'; +import 'core-js/es6/set'; +import 'core-js/es6/reflect'; + import 'core-js/es7/reflect'; import 'zone.js/dist/zone'; diff --git a/addon/ng2/blueprints/ng2/files/__path__/test.ts b/addon/ng2/blueprints/ng2/files/__path__/test.ts index a5a378a83e22..f1e942cabffd 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/test.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/test.ts @@ -1,20 +1,20 @@ /*global jasmine, __karma__, window*/ -require('core-js/es6'); -require('core-js/es7/reflect'); +import 'core-js/es6' +import 'core-js/es7/reflect' // Typescript emit helpers polyfill -require('ts-helpers'); +import 'ts-helpers' -require('zone.js/dist/zone'); -require('zone.js/dist/long-stack-trace-zone'); -require('zone.js/dist/jasmine-patch'); -require('zone.js/dist/async-test'); -require('zone.js/dist/fake-async-test'); -require('zone.js/dist/sync-test'); +import 'zone.js/dist/zone' +import 'zone.js/dist/long-stack-trace-zone' +import 'zone.js/dist/jasmine-patch' +import 'zone.js/dist/async-test' +import 'zone.js/dist/fake-async-test' +import 'zone.js/dist/sync-test' // RxJS -require('rxjs/Rx'); +import 'rxjs/Rx' Promise.all([ System.import('@angular/core/testing'), diff --git a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json index b93d0146f892..6c9b7c2daaa7 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json @@ -9,7 +9,9 @@ "outDir": "./dist/", "rootDir": ".", "sourceMap": true, - "target": "es5" + "target": "es5", + "maproot": "/", + "inlinesource": true }, "compileOnSave": false, "buildOnSave": false, diff --git a/addon/ng2/blueprints/ng2/files/__path__/vendor.ts b/addon/ng2/blueprints/ng2/files/__path__/vendor.ts index a74ebfcb3957..f0f02685fb31 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/vendor.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/vendor.ts @@ -10,7 +10,7 @@ import '@angular/platform-browser'; import '@angular/platform-browser-dynamic'; <% if(isMobile) { %> - import '@angular/app-shell'; +import '@angular/app-shell'; <% } %> import 'rxjs/add/operator/map'; diff --git a/addon/ng2/blueprints/ng2/files/package.json b/addon/ng2/blueprints/ng2/files/package.json index 4583454e51d0..467f32648b28 100644 --- a/addon/ng2/blueprints/ng2/files/package.json +++ b/addon/ng2/blueprints/ng2/files/package.json @@ -21,11 +21,11 @@ "@angular/platform-browser": "2.0.0-rc.4", "@angular/platform-browser-dynamic": "2.0.0-rc.4", "@angular/router": "3.0.0-beta.2", - "ts-helpers": "^1.1.1", + "core-js": "^2.4.0", "rxjs": "5.0.0-beta.6", "systemjs": "0.19.26", - "zone.js": "0.6.12", - "core-js": "^2.4.0" + "ts-helpers": "^1.1.1", + "zone.js": "0.6.12" }, "devDependencies": {<% if(isMobile) { %> "@angular/platform-server": "2.0.0-rc.4", diff --git a/addon/ng2/commands/build.ts b/addon/ng2/commands/build.ts index afb23572b315..93ea327ed2c0 100644 --- a/addon/ng2/commands/build.ts +++ b/addon/ng2/commands/build.ts @@ -48,8 +48,6 @@ module.exports = Command.extend({ environment: commandOptions.environment }); - console.log(buildTask); - return buildTask.run(commandOptions); } }); diff --git a/addon/ng2/models/index.ts b/addon/ng2/models/index.ts index 7ad3809dced4..f01dfadc6be5 100644 --- a/addon/ng2/models/index.ts +++ b/addon/ng2/models/index.ts @@ -4,6 +4,3 @@ export * from './webpack-build-production'; export * from './webpack-build-development'; export * from './webpack-build-mobile'; export * from './webpack-build-utils'; -export {getWebpackMaterialConfig, getWebpackMaterialE2EConfig} from './webpack-build-material2.ts'; - -export * from './webpack-karma-config'; diff --git a/addon/ng2/models/webpack-build-common.ts b/addon/ng2/models/webpack-build-common.ts index b633ae5c1135..146671ed5501 100644 --- a/addon/ng2/models/webpack-build-common.ts +++ b/addon/ng2/models/webpack-build-common.ts @@ -6,7 +6,7 @@ const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin const CopyWebpackPlugin = require('copy-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); -export const getWebpackCommonConfig = function(projectRoot: string) { +export function getWebpackCommonConfig(projectRoot: string) { const awesomeTypescriptLoaderConfig: LoaderConfig | any = { useWebpackText: true, useForkChecker: true, diff --git a/addon/ng2/models/webpack-build-material2.ts b/addon/ng2/models/webpack-build-material2.ts deleted file mode 100644 index e7629a217bd9..000000000000 --- a/addon/ng2/models/webpack-build-material2.ts +++ /dev/null @@ -1,224 +0,0 @@ -// Angular Material2 Custom CLI Webpack Plugin: This allows for the following: -// To build, serve, and watchmode the angular2-material repo. -// -// Requirements: -// -// Do a find and replace on the src directory -// .css'] => .scss'] -// This allows for angular2-template-loader to transpile the sass correctly. -import * as webpack from 'webpack'; -import {LoaderConfig} from '../utilities/ts-path-mappings-webpack-plugin'; - -const path = require('path'); -const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin; -const CopyWebpackPlugin = require('copy-webpack-plugin'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); - - -// var components = [ -// 'button', -// 'card', -// 'checkbox', -// 'grid-list', -// 'icon', -// 'input', -// 'list', -// 'progress-bar', -// 'progress-circle', -// 'radio', -// 'sidenav', -// 'slide-toggle', -// 'button-toggle', -// 'tabs', -// 'toolbar' -// ]; - -export const getWebpackMaterialConfig = function(projectRoot: string) { - const awesomeTypescriptLoaderConfig: LoaderConfig | any = { - useWebpackText: true, - useForkChecker: true, - tsconfig: path.resolve(projectRoot, './src/demo-app/tsconfig.json') - } - /** Map relative paths to URLs. */ - // var aliasMap: any = { - // '@angular2-material/core': path.resolve(projectRoot, './src/core'), - // }; - - // components.forEach(function (name) { - // aliasMap[("@angular2-material/" + name)] = path.resolve(projectRoot, "./src/components/" + name); - // return aliasMap[("@angular2-material/" + name)] = path.resolve(projectRoot, "./src/components/" + name); - // }); - - return { - devtool: 'inline-source-map', - resolve: { - extensions: ['', '.webpack.js', '.web.js', '.ts', '.tsx', '.js', '.css', '.scss'], - plugins: [ - ] - // alias: aliasMap - }, - sassLoader: { - includePaths: [ - // This allows for automatic resolving of @import's for sass for variables. - path.resolve(projectRoot, './src/core/style') - ] - }, - context: path.resolve(__dirname, './'), - entry: { - main: [path.resolve(projectRoot, './src/demo-app/main.ts')], - vendor: path.resolve(projectRoot, './src/demo-app/vendor.ts') - }, - output: { - path: './dist', - filename: '[name].bundle.js' - }, - module: { - preLoaders: [ - { - test: /\.js$/, - loader: 'source-map-loader', - exclude: [ - path.resolve(projectRoot, 'node_modules/rxjs'), - path.resolve(projectRoot, 'node_modules/@angular'), - ] - } - ], - // ts: { - // configFileName: path.resolve(projectRoot, './src/demo-app/tsconfig.json') - // }, - loaders: [ - { - test: /\.ts$/, - loaders: [ - { - loader: 'awesome-typescript-loader', - query: awesomeTypescriptLoaderConfig - }, - { - loader: 'angular2-template-loader' - } - ], - exclude: [/\.(spec|e2e)\.ts$/] - }, - { test: /\.json$/, loader: 'json-loader'}, - { test: /\.css$/, loaders: ['raw-loader', 'postcss-loader'] }, - { test: /\.styl$/, loaders: ['raw-loader', 'postcss-loader', 'stylus-loader'] }, - { test: /\.less$/, loaders: ['raw-loader', 'less-loader'] }, - { test: /\.s?css$/, loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] }, - { test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000'}, - { test: /\.html$/, loader: 'raw-loader' } - ] - }, - plugins: [ - new webpack.optimize.CommonsChunkPlugin({name: 'vendor'}), - new ForkCheckerPlugin(), - new HtmlWebpackPlugin({ - template: path.resolve(projectRoot, './src/demo-app/index.html'), - chunksSortMode: 'dependency' - }), - ], - node: { - global: 'window', - crypto: 'empty', - module: false, - clearImmediate: false, - setImmediate: false - } - }; -} - -export const getWebpackMaterialE2EConfig = function(projectRoot: string) { - const awesomeTypescriptLoaderConfig: LoaderConfig | any = { - useWebpackText: true, - useForkChecker: true, - tsconfig: path.resolve(projectRoot, './src/e2e-app/tsconfig.json') - } - /** Map relative paths to URLs. */ - // var aliasMap: any = { - // '@angular2-material/core': path.resolve(projectRoot, './src/core'), - // }; - - // components.forEach(function (name) { - // aliasMap[("@angular2-material/" + name)] = path.resolve(projectRoot, "./src/components/" + name); - // return aliasMap[("@angular2-material/" + name)] = path.resolve(projectRoot, "./src/components/" + name); - // }); - - return { - devtool: 'inline-source-map', - resolve: { - extensions: ['', '.webpack.js', '.web.js', '.ts', '.tsx', '.js', '.css', '.scss'], - - plugins: [ - ] - // alias: aliasMap - }, - sassLoader: { - includePaths: [ - // This allows for automatic resolving of @import's for sass for variables. - path.resolve(projectRoot, './src/core/style') - ] - }, - debug: true, - context: path.resolve(__dirname, './'), - entry: { - main: [path.resolve(projectRoot, './src/e2e-app/main.ts')], - vendor: path.resolve(projectRoot, './src/e2e-app/vendor.ts') - }, - output: { - path: './dist', - filename: '[name].bundle.js' - }, - module: { - preLoaders: [ - { - test: /\.js$/, - loader: 'source-map-loader', - exclude: [ - path.resolve(projectRoot, 'node_modules/rxjs'), - path.resolve(projectRoot, 'node_modules/@angular'), - ] - } - ], - // ts: { - // configFileName: path.resolve(projectRoot, './src/e2e-app/tsconfig.json') - // }, - loaders: [ - { - test: /\.ts$/, - loaders: [ - { - loader: 'awesome-typescript-loader', - query: awesomeTypescriptLoaderConfig - }, - { - loader: 'angular2-template-loader' - } - ], - exclude: [/\.(spec|e2e)\.ts$/] - }, - { test: /\.json$/, loader: 'json-loader'}, - { test: /\.css$/, loaders: ['raw-loader', 'postcss-loader'] }, - { test: /\.styl$/, loaders: ['raw-loader', 'postcss-loader', 'stylus-loader'] }, - { test: /\.less$/, loaders: ['raw-loader', 'less-loader'] }, - { test: /\.s?css$/, loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] }, - { test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000'}, - { test: /\.html$/, loader: 'raw-loader' } - ] - }, - plugins: [ - new webpack.optimize.CommonsChunkPlugin({name: 'vendor'}), - new ForkCheckerPlugin(), - new HtmlWebpackPlugin({ - template: path.resolve(projectRoot, './src/e2e-app/index.html'), - chunksSortMode: 'dependency' - }), - ], - node: { - global: 'window', - crypto: 'empty', - module: false, - clearImmediate: false, - setImmediate: false - } - }; -} diff --git a/addon/ng2/models/webpack-build-production.ts b/addon/ng2/models/webpack-build-production.ts index 9b144ac2da39..60028dca1917 100644 --- a/addon/ng2/models/webpack-build-production.ts +++ b/addon/ng2/models/webpack-build-production.ts @@ -3,7 +3,6 @@ import * as webpack from 'webpack'; const path = require('path'); const webpackMerge = require('webpack-merge'); // used to merge webpack configs const WebpackMd5Hash = require('webpack-md5-hash'); -const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin'); //TODO WP2 Typings const CompressionPlugin = require("compression-webpack-plugin"); export const getWebpackProdConfigPartial = function(projectRoot: string) { @@ -18,14 +17,7 @@ export const getWebpackProdConfigPartial = function(projectRoot: string) { }, plugins: [ new WebpackMd5Hash(), - new webpack.optimize.DedupePlugin() - // ~400kb (Doesn't do anything different (yet?)) - // new LoaderOptionsPlugin({ - // test: /\.js/, - // minimize: true, - // optimize: true, - // debug: false - // }), + new webpack.optimize.DedupePlugin(), // ~107kb new webpack.optimize.UglifyJsPlugin({ beautify: false, //prod diff --git a/addon/ng2/models/webpack-config.ts b/addon/ng2/models/webpack-config.ts index 7245c830e118..812f05c1794f 100644 --- a/addon/ng2/models/webpack-config.ts +++ b/addon/ng2/models/webpack-config.ts @@ -3,8 +3,6 @@ import { getWebpackCommonConfig, getWebpackDevConfigPartial, getWebpackProdConfigPartial, - getWebpackMaterialConfig, - getWebpackMaterialE2EConfig, getWebpackMobileConfigPartial, getWebpackMobileProdConfigPartial } from './'; @@ -25,13 +23,7 @@ export class NgCliWebpackConfig { private webpackMobileProdConfigPartial: any; constructor(public ngCliProject: any, public environment: string) { - if (ngCliProject.pkg.name === 'material2') { - this.webpackMaterialConfig = getWebpackMaterialConfig(this.ngCliProject.root); - this.webpackMaterialE2EConfig = getWebpackMaterialE2EConfig(this.ngCliProject.root); - } else { - this.webpackBaseConfig = getWebpackCommonConfig(this.ngCliProject.root); - } - + this.webpackBaseConfig = getWebpackCommonConfig(this.ngCliProject.root); this.webpackDevConfigPartial = getWebpackDevConfigPartial(this.ngCliProject.root); this.webpackProdConfigPartial = getWebpackProdConfigPartial(this.ngCliProject.root); @@ -53,25 +45,13 @@ export class NgCliWebpackConfig { case "develop": this.config = webpackMerge(this.webpackBaseConfig, this.webpackDevConfigPartial); break; + case "p": case "prod": case "production": this.config = webpackMerge(this.webpackBaseConfig, this.webpackProdConfigPartial); break; - case "d:m": - case "dev:mat": - case "dev:material": - case "development:mat": - case "development:material": - this.config = webpackMerge(this.webpackMaterialConfig, this.webpackDevConfigPartial); - break; - case "p:m": - case "prod:mat": - case "prod:material": - case "production:mat": - case "production:material": - this.config = webpackMerge(this.webpackMaterialConfig, this.webpackProdConfigPartial); - break; + default: //TODO: Not sure what to put here. We have a default env passed anyways. this.ngCliProject.ui.writeLine("Envrionment could not be determined while configuring your build system.", 3) diff --git a/addon/ng2/tasks/build-webpack-watch.ts b/addon/ng2/tasks/build-webpack-watch.ts index 2db928c9b8d6..e54275b49af4 100644 --- a/addon/ng2/tasks/build-webpack-watch.ts +++ b/addon/ng2/tasks/build-webpack-watch.ts @@ -4,7 +4,7 @@ import {ServeTaskOptions} from '../commands/serve'; import * as rimraf from 'rimraf'; import * as path from 'path'; -var Task = require('ember-cli/lib/models/task'); +const Task = require('ember-cli/lib/models/task'); const webpack = require('webpack'); const ProgressPlugin = require('webpack/lib/ProgressPlugin'); @@ -14,7 +14,7 @@ let lastHash: any = null; module.exports = Task.extend({ run: function(runTaskOptions: ServeTaskOptions) { - var project = this.cliProject; + const project = this.cliProject; rimraf.sync(path.resolve(project.root, runTaskOptions.outputPath)); diff --git a/addon/ng2/tasks/serve-webpack.ts b/addon/ng2/tasks/serve-webpack.ts index 1e79cab8ed21..315cc3d163ad 100644 --- a/addon/ng2/tasks/serve-webpack.ts +++ b/addon/ng2/tasks/serve-webpack.ts @@ -21,9 +21,11 @@ module.exports = Task.extend({ let webpackCompiler: any; var config: NgCliWebpackConfig = new NgCliWebpackConfig(this.project, 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://localhost:${commandOptions.port}/`); webpackCompiler = webpack(config); - webpackCompiler.apply(new ProgressPlugin({ profile: true, colors: true @@ -33,7 +35,8 @@ module.exports = Task.extend({ contentBase: path.resolve(this.project.root, './src'), historyApiFallback: true, stats: webpackDevServerOutputOptions, - inline: true + inline: true, + hot: true }; const serveMessage:string = chalk.green(`\n*\n*\n NG Live Development Server is running on http://localhost:${commandOptions.port}.\n*\n*`); diff --git a/package.json b/package.json index f3ef0b6eba63..9894e868d372 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "html-webpack-plugin": "^2.19.0", "istanbul-instrumenter-loader": "^0.2.0", "json-loader": "^0.5.4", - "karma": "^0.13.22", "karma-chrome-launcher": "^1.0.1", "karma-coverage": "^1.0.0", "karma-jasmine": "^1.0.2", @@ -99,7 +98,7 @@ "typings": "^0.8.1", "url-loader": "^0.5.7", "webpack": "2.1.0-beta.17", - "webpack-dev-server": "^1.14.1", + "webpack-dev-server": "2.1.0-beta.0", "webpack-md5-hash": "0.0.5", "webpack-merge": "^0.14.0" }, diff --git a/tsconfig.json b/tsconfig.json index d37ed087389f..991af3717a27 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,9 @@ "sourceMap": true, "sourceRoot": "/", "target": "es5", - "lib": ["es6", "dom"] - } + "lib": ["es6"] + }, + "includes": [ + "./custom-typings.d.ts" + ] } From 541d6988d24f561a13802dbfb66f702b6c140a95 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 15 Jul 2016 04:56:38 +0100 Subject: [PATCH 04/38] chore: remove bind from serve command --- addon/ng2/commands/serve.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/addon/ng2/commands/serve.ts b/addon/ng2/commands/serve.ts index 0537c2ad29a4..dd86072e6025 100644 --- a/addon/ng2/commands/serve.ts +++ b/addon/ng2/commands/serve.ts @@ -60,7 +60,7 @@ module.exports = Command.extend({ return this._checkExpressPort(commandOptions) .then(this._autoFindLiveReloadPort.bind(this)) - .then(function(commandOptions: ServeTaskOptions) { + .then((commandOptions: ServeTaskOptions) => { commandOptions = assign({}, commandOptions, { baseURL: this.project.config(commandOptions.environment).baseURL || '/' }); @@ -84,12 +84,12 @@ module.exports = Command.extend({ return win.checkWindowsElevation(this.ui).then(function() { return serve.run(commandOptions); }); - }.bind(this)); + }); }, _checkExpressPort: function(commandOptions: ServeTaskOptions) { return getPort({ port: commandOptions.port, host: commandOptions.host }) - .then(function(foundPort: number) { + .then((foundPort: number) => { if (commandOptions.port !== foundPort && commandOptions.port !== 0) { var message = 'Port ' + commandOptions.port + ' is already in use.'; @@ -100,12 +100,12 @@ module.exports = Command.extend({ commandOptions.port = foundPort; return commandOptions; - }.bind(this)); + }); }, _autoFindLiveReloadPort: function(commandOptions: ServeTaskOptions) { return getPort({ port: commandOptions.liveReloadPort, host: commandOptions.liveReloadHost }) - .then(function(foundPort: number) { + .then((foundPort: number) => { // if live reload port matches express port, try one higher if (foundPort === commandOptions.port) { @@ -122,7 +122,7 @@ module.exports = Command.extend({ commandOptions.liveReloadPort = foundPort; return commandOptions; - }.bind(this)); + }); } }); From 0d1c6336d582c35bea82273515bdfc4452102cd5 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 15 Jul 2016 05:00:20 +0100 Subject: [PATCH 05/38] chore: simplify test command --- addon/ng2/commands/test.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/addon/ng2/commands/test.js b/addon/ng2/commands/test.js index 15ea63fa075a..b0e6b7f5f289 100644 --- a/addon/ng2/commands/test.js +++ b/addon/ng2/commands/test.js @@ -36,9 +36,7 @@ module.exports = TestCommand.extend({ () => { /* handle build error to allow watch mode to start */ }) - .then(() => { - return Promise.all([testTask.run(commandOptions)]); - }); + .then(() => testTask.run(commandOptions)); } else { // if not watching ensure karma is doing a single run commandOptions.singleRun = true; From 4189b9bb4a88819289136d85314c8d2b81b5a3bc Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 15 Jul 2016 05:04:14 +0100 Subject: [PATCH 06/38] chore: fix test warnings --- .../ng2/blueprints/ng2/files/__path__/test.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/addon/ng2/blueprints/ng2/files/__path__/test.ts b/addon/ng2/blueprints/ng2/files/__path__/test.ts index f1e942cabffd..5255aeee5d09 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/test.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/test.ts @@ -1,20 +1,20 @@ /*global jasmine, __karma__, window*/ -import 'core-js/es6' -import 'core-js/es7/reflect' +import 'core-js/es6'; +import 'core-js/es7/reflect'; // Typescript emit helpers polyfill -import 'ts-helpers' +import 'ts-helpers'; -import 'zone.js/dist/zone' -import 'zone.js/dist/long-stack-trace-zone' -import 'zone.js/dist/jasmine-patch' -import 'zone.js/dist/async-test' -import 'zone.js/dist/fake-async-test' -import 'zone.js/dist/sync-test' +import 'zone.js/dist/zone'; +import 'zone.js/dist/long-stack-trace-zone'; +import 'zone.js/dist/jasmine-patch'; +import 'zone.js/dist/async-test'; +import 'zone.js/dist/fake-async-test'; +import 'zone.js/dist/sync-test'; // RxJS -import 'rxjs/Rx' +import 'rxjs/Rx'; Promise.all([ System.import('@angular/core/testing'), From 41653cfc4fdf139278e8137cc65aee5bcaddb31f Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 15 Jul 2016 05:05:41 +0100 Subject: [PATCH 07/38] chore: revert whitespace changes --- addon/ng2/commands/init.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addon/ng2/commands/init.js b/addon/ng2/commands/init.js index 3244bf94e2c0..7c7fff8aa460 100644 --- a/addon/ng2/commands/init.js +++ b/addon/ng2/commands/init.js @@ -9,7 +9,6 @@ var GitInit = require('../tasks/git-init'); var LinkCli = require('../tasks/link-cli'); var NpmInstall = require('../tasks/npm-install'); - module.exports = Command.extend({ name: 'init', description: 'Creates a new angular-cli project in the current folder.', @@ -95,7 +94,7 @@ module.exports = Command.extend({ return Promise.reject(new SilentError(message)); } - + var blueprintOpts = { dryRun: commandOptions.dryRun, blueprint: commandOptions.blueprint || this._defaultBlueprint(), From f0e6e51d9df9888787a92fe1f6e838d5d4dd7d1a Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 15 Jul 2016 05:10:47 +0100 Subject: [PATCH 08/38] chore: re-add mapRoot to tsconfig --- addon/ng2/blueprints/ng2/files/__path__/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json index 6c9b7c2daaa7..1c55b6264b90 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json @@ -10,7 +10,7 @@ "rootDir": ".", "sourceMap": true, "target": "es5", - "maproot": "/", + "mapRoot": "/", "inlinesource": true }, "compileOnSave": false, From bdb86901c9eb8b1e21d67864c69ad07fe5e63c54 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 15 Jul 2016 18:49:01 +0100 Subject: [PATCH 09/38] chore: remove unused import --- addon/ng2/commands/test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/addon/ng2/commands/test.js b/addon/ng2/commands/test.js index b0e6b7f5f289..c90bb83165d1 100644 --- a/addon/ng2/commands/test.js +++ b/addon/ng2/commands/test.js @@ -1,6 +1,5 @@ 'use strict'; -var Promise = require('ember-cli/lib/ext/promise'); var TestCommand = require('ember-cli/lib/commands/test'); var win = require('ember-cli/lib/utilities/windows-admin'); From 8ea2e7218a3330418af98e60cc2b86b04033ccb5 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 15 Jul 2016 19:07:47 +0100 Subject: [PATCH 10/38] bugfix: fix broken tests --- tests/e2e/e2e_workflow.spec.js | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/tests/e2e/e2e_workflow.spec.js b/tests/e2e/e2e_workflow.spec.js index 17f6510063a9..8a1701fe9ba0 100644 --- a/tests/e2e/e2e_workflow.spec.js +++ b/tests/e2e/e2e_workflow.spec.js @@ -11,7 +11,6 @@ var treeKill = require('tree-kill'); var child_process = require('child_process'); var ng = require('../helpers/ng'); var root = path.join(process.cwd(), 'tmp'); -var repoPkgJson = require('../../package.json'); function existsSync(path) { try { @@ -40,34 +39,26 @@ describe('Basic end-to-end Workflow', function () { } - // We don't want to use npm link because then npm dependencies - // that only exist in the project will not be accessible to CLI - // This is particularly problematic for --mobile, which uses Universal - // libs as part of the build process. - // Instead, we'll pack CLI as a tarball it('Installs angular-cli correctly', function () { this.timeout(300000); - sh.exec('npm pack', { silent: true }); - expect(existsSync(path.join(process.cwd(), `angular-cli-${repoPkgJson.version}.tgz`))); + sh.exec('npm link', { silent: true }); + return tmp.setup('./tmp').then(function () { process.chdir('./tmp'); + expect(existsSync(path.join(process.cwd(), 'bin', 'ng'))); }); }); it('Can create new project using `ng new test-project`', function () { this.timeout(4200000); - let args = ['--skip-npm']; + let args = ['--link-cli']; // If testing in the mobile matrix on Travis, create project with mobile flag if (isMobileTest()) { args = args.concat(['--mobile']); } return ng(['new', 'test-project'].concat(args)).then(function () { - // Install Angular CLI from packed version - let tarball = path.resolve(root, `../angular-cli-${repoPkgJson.version}.tgz`); - sh.exec(`npm install && npm install ${tarball}`); - sh.exec(`rm ${tarball}`); expect(existsSync(path.join(root, 'test-project'))); }); }); From 8b6fdc9acb87faa84f6b44ddbc546a2f6363d678 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 15 Jul 2016 20:36:03 +0100 Subject: [PATCH 11/38] fix: fix mobile-specific feature test --- addon/ng2/models/webpack-build-mobile.ts | 7 ++++++- addon/ng2/models/webpack-config.ts | 2 +- tests/e2e/e2e_workflow.spec.js | 20 +++++++++++--------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/addon/ng2/models/webpack-build-mobile.ts b/addon/ng2/models/webpack-build-mobile.ts index 59257ae435c8..397fa412f68c 100644 --- a/addon/ng2/models/webpack-build-mobile.ts +++ b/addon/ng2/models/webpack-build-mobile.ts @@ -1,11 +1,16 @@ import * as webpack from 'webpack'; import * as path from 'path'; import * as OfflinePlugin from 'offline-plugin'; -import { PrerenderWebpackPlugin } from '../utilities/prerender-webpack-plugin.ts' +import * as CopyWebpackPlugin from 'copy-webpack-plugin'; +import { PrerenderWebpackPlugin } from '../utilities/prerender-webpack-plugin.ts'; export const getWebpackMobileConfigPartial = function (projectRoot: string) { return { plugins: [ + new CopyWebpackPlugin([ + {from: path.resolve(projectRoot, './src/icons'), to: path.resolve(projectRoot, './dist/icons')}, + {from: path.resolve(projectRoot, './src/manifest.webapp'), to: path.resolve(projectRoot, './dist')} + ]), new PrerenderWebpackPlugin({ templatePath: 'index.html', configPath: path.resolve(projectRoot, './src/main-app-shell.ts'), diff --git a/addon/ng2/models/webpack-config.ts b/addon/ng2/models/webpack-config.ts index 812f05c1794f..e5cd3e00f294 100644 --- a/addon/ng2/models/webpack-config.ts +++ b/addon/ng2/models/webpack-config.ts @@ -30,7 +30,7 @@ export class NgCliWebpackConfig { if (CliConfig.fromProject().apps[0].mobile){ this.webpackMobileConfigPartial = getWebpackMobileConfigPartial(this.ngCliProject.root); this.webpackMobileProdConfigPartial = getWebpackMobileProdConfigPartial(this.ngCliProject.root); - this.webpackDevConfigPartial = webpackMerge(this.webpackDevConfigPartial, this.webpackMobileConfigPartial); + this.webpackBaseConfig = webpackMerge(this.webpackBaseConfig, this.webpackMobileConfigPartial); this.webpackProdConfigPartial = webpackMerge(this.webpackProdConfigPartial, this.webpackMobileProdConfigPartial); } diff --git a/tests/e2e/e2e_workflow.spec.js b/tests/e2e/e2e_workflow.spec.js index 8a1701fe9ba0..c827c71f4219 100644 --- a/tests/e2e/e2e_workflow.spec.js +++ b/tests/e2e/e2e_workflow.spec.js @@ -89,19 +89,21 @@ describe('Basic end-to-end Workflow', function () { expect(mainBundleContent).to.include('production:!0'); }); - it_mobile('Enables mobile-specific production features', () => { - let index = fs.readFileSync(path.join(process.cwd(), 'dist/index.html'), 'utf-8'); + it_mobile('Enables mobile-specific production features in prod builds', () => { + let indexHtml = fs.readFileSync(path.join(process.cwd(), 'dist/index.html'), 'utf-8'); // Service Worker - expect(index.includes('if (\'serviceWorker\' in navigator) {')).to.be.equal(true); - expect(existsSync(path.join(process.cwd(), 'dist/worker.js'))).to.be.equal(true); - - // Asynchronous bundle - expect(index.includes('')).to.be.equal(true); - expect(existsSync(path.join(process.cwd(), 'dist/app-concat.js'))).to.be.equal(true); + expect(indexHtml).to.match(/sw-install\.[0-9a-f]{20}\.bundle\.js/); + expect(existsSync(path.join(process.cwd(), 'dist/sw.js' ))).to.be.equal(true); // App Manifest - expect(index.includes('')).to.be.equal(true); + expect(indexHtml.includes('')).to.be.equal(true); expect(existsSync(path.join(process.cwd(), 'dist/manifest.webapp'))).to.be.equal(true); + + // Icons folder + expect(existsSync(path.join(process.cwd(), 'dist/icons'))).to.be.equal(true); + + // Prerender content + expect(indexHtml).to.match(/app works!/); }); it('Can run `ng build` in created project', function () { From 87b4cbd95e73bfc08335c040a0b49d792fb25fa4 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 15 Jul 2016 21:08:45 +0100 Subject: [PATCH 12/38] bugfix: fix public folder test --- tests/e2e/e2e_workflow.spec.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tests/e2e/e2e_workflow.spec.js b/tests/e2e/e2e_workflow.spec.js index c827c71f4219..17679fc63532 100644 --- a/tests/e2e/e2e_workflow.spec.js +++ b/tests/e2e/e2e_workflow.spec.js @@ -312,13 +312,8 @@ describe('Basic end-to-end Workflow', function () { const tmpFileLocation = path.join(process.cwd(), 'dist', 'test.abc'); fs.writeFileSync(tmpFile, 'hello world'); - return ng(['build']) - .then(function () { - expect(existsSync(tmpFileLocation)).to.be.equal(true); - }) - .catch(err => { - throw new Error(err) - }); + sh.exec(`${ngBin} build`); + expect(existsSync(tmpFileLocation)).to.be.equal(true); }); it.skip('Installs sass support successfully', function() { From 860526c8ec9578dbee68d5b823cc2d6c6acc03d5 Mon Sep 17 00:00:00 2001 From: Sean Larkin Date: Sun, 17 Jul 2016 12:57:24 -0500 Subject: [PATCH 13/38] fix: fixes for path mappings, tests, and coverage (#1359) * fix(): Multiple fixes for path mappings: * Removed invalid test case that was throwing path mappings tests because of a typescript bug. * Readded PathsPlugin for Path Mappings * Removed coverage preprocessor which was throwing bad type errors against ts code when it shouldn't be. * Added sourcemap support for istanbul instrumenter. Coverage files are still being generated. * fix: fix the way the build command runs for mobile tests * fix: fix the way the build command runs for mobile tests * fix: replaced promise based ng command with sh.exec to allow mappings test to run correctly against mobile * fix: replaced promise based ng command with sh.exec to allow mappings test to run correctly against mobile --- .../ng2/blueprints/ng2/files/__path__/test.ts | 16 +++---- .../ng2/files/__path__/tsconfig.json | 7 +-- addon/ng2/models/webpack-build-common.ts | 7 ++- addon/ng2/models/webpack-build-test.ts | 3 +- addon/ng2/tasks/test.js | 2 +- .../ts-path-mappings-webpack-plugin.ts | 3 -- package.json | 3 +- tests/e2e/e2e_workflow.spec.js | 43 ++++++++++--------- 8 files changed, 38 insertions(+), 46 deletions(-) diff --git a/addon/ng2/blueprints/ng2/files/__path__/test.ts b/addon/ng2/blueprints/ng2/files/__path__/test.ts index 5255aeee5d09..e61005825b11 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/test.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/test.ts @@ -23,18 +23,14 @@ Promise.all([ let testing = providers[0]; let testingBrowser = providers[1]; - testing.setBaseTestProviders(testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, - testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS); + testing.setBaseTestProviders( + testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, + testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS + ); }); -let testContext = require.context('../src', true, /\.spec\.ts/); - -/* - * get all the files, for each file, call the context function - * that will require the file and load it up here. Context will - * loop and require those spec files here - */ -function requireAll(requireContext) { +let testContext: any = require.context('../src', true, /\.spec\.ts/); +function requireAll(requireContext: any) { return requireContext.keys().map(requireContext); } diff --git a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json index 1c55b6264b90..e0831213e64c 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json @@ -10,15 +10,10 @@ "rootDir": ".", "sourceMap": true, "target": "es5", - "mapRoot": "/", - "inlinesource": true + "mapRoot": "/" }, "compileOnSave": false, "buildOnSave": false, - "exclude": [ - "node_modules", - "bower_components" - ], "includes": [ "**.d.ts" ] diff --git a/addon/ng2/models/webpack-build-common.ts b/addon/ng2/models/webpack-build-common.ts index 146671ed5501..c41045021b8f 100644 --- a/addon/ng2/models/webpack-build-common.ts +++ b/addon/ng2/models/webpack-build-common.ts @@ -1,5 +1,5 @@ import * as webpack from 'webpack'; -import {LoaderConfig} from '../utilities/ts-path-mappings-webpack-plugin'; +import {LoaderConfig, PathsPlugin} from '../utilities/ts-path-mappings-webpack-plugin'; const path = require('path'); const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin; @@ -18,7 +18,10 @@ export function getWebpackCommonConfig(projectRoot: string) { resolve: { extensions: ['', '.ts', '.js'], root: path.resolve(projectRoot, './src'), - moduleDirectories: ['node_modules'] + moduleDirectories: ['node_modules'], + plugins: [ + new PathsPlugin(awesomeTypescriptLoaderConfig); + ] }, context: path.resolve(__dirname, './'), entry: { diff --git a/addon/ng2/models/webpack-build-test.ts b/addon/ng2/models/webpack-build-test.ts index 6a1d15bf4410..455b5960c6c0 100644 --- a/addon/ng2/models/webpack-build-test.ts +++ b/addon/ng2/models/webpack-build-test.ts @@ -44,7 +44,6 @@ export const getWebpackTestConfig = function(projectRoot: string) { query: { useWebpackText: true, tsconfig: path.resolve(projectRoot, './src/tsconfig.json'), - // resolveGlobs: false, module: "commonjs", target: "es5", useForkChecker: true, @@ -67,7 +66,7 @@ export const getWebpackTestConfig = function(projectRoot: string) { ], postLoaders: [ { - test: /\.(js|ts)$/, loader: 'istanbul-instrumenter-loader', + test: /\.(js|ts)$/, loader: 'sourcemap-istanbul-instrumenter-loader', exclude: [ /\.(e2e|spec)\.ts$/, /node_modules/ diff --git a/addon/ng2/tasks/test.js b/addon/ng2/tasks/test.js index 5fbbcea453e5..dcf28c2f7e55 100644 --- a/addon/ng2/tasks/test.js +++ b/addon/ng2/tasks/test.js @@ -36,7 +36,7 @@ module.exports = Task.extend({ // Single test entry file. Will run the test.ts bundle and track it. options.files = [{ pattern: './src/test.ts', watched: false }]; - options.preprocessors = { './src/test.ts': ['coverage','webpack','sourcemap'] }; + options.preprocessors = { './src/test.ts': ['webpack','sourcemap'] }; options.webpack = webpackTestConfig(projectRoot); options.webpackMiddleware = { noInfo: true, // Hide webpack output because its noisy. diff --git a/addon/ng2/utilities/ts-path-mappings-webpack-plugin.ts b/addon/ng2/utilities/ts-path-mappings-webpack-plugin.ts index 13bdeb057703..6c35b7fd3183 100644 --- a/addon/ng2/utilities/ts-path-mappings-webpack-plugin.ts +++ b/addon/ng2/utilities/ts-path-mappings-webpack-plugin.ts @@ -183,9 +183,6 @@ export class PathsPlugin implements ResolverPlugin { this.baseUrl ); - console.log("CONFIG FILE AND BASE URL"); - console.log(this.configFilePath, this.absoluteBaseUrl); - this.mappings = []; let paths = this.options.paths || {}; Object.keys(paths).forEach(alias => { diff --git a/package.json b/package.json index 9894e868d372..a93ccae5ae3d 100644 --- a/package.json +++ b/package.json @@ -84,6 +84,7 @@ "shelljs": "^0.7.0", "silent-error": "^1.0.0", "source-map-loader": "^0.1.5", + "sourcemap-istanbul-instrumenter-loader": "^0.2.0", "style-loader": "^0.13.1", "stylus": "^0.54.5", "stylus-loader": "^2.1.0", @@ -97,7 +98,7 @@ "typescript": "^2.0.0", "typings": "^0.8.1", "url-loader": "^0.5.7", - "webpack": "2.1.0-beta.17", + "webpack": "2.1.0-beta.18", "webpack-dev-server": "2.1.0-beta.0", "webpack-md5-hash": "0.0.5", "webpack-merge": "^0.14.0" diff --git a/tests/e2e/e2e_workflow.spec.js b/tests/e2e/e2e_workflow.spec.js index 17679fc63532..3864e7fc9c89 100644 --- a/tests/e2e/e2e_workflow.spec.js +++ b/tests/e2e/e2e_workflow.spec.js @@ -43,7 +43,7 @@ describe('Basic end-to-end Workflow', function () { this.timeout(300000); sh.exec('npm link', { silent: true }); - + return tmp.setup('./tmp').then(function () { process.chdir('./tmp'); expect(existsSync(path.join(process.cwd(), 'bin', 'ng'))); @@ -446,7 +446,7 @@ describe('Basic end-to-end Workflow', function () { }); }); - xit('Turn on path mapping in tsconfig.json and rebuild', function () { + it('Turn on path mapping in tsconfig.json and rebuild', function () { this.timeout(420000); const configFilePath = path.join(process.cwd(), 'src', 'tsconfig.json'); @@ -454,28 +454,29 @@ describe('Basic end-to-end Workflow', function () { config.compilerOptions.baseUrl = ''; - // This should fail. + // #TODO: When https://github.com/Microsoft/TypeScript/issues/9772 is fixed this should fail. config.compilerOptions.paths = { '@angular/*': [] }; fs.writeFileSync(configFilePath, JSON.stringify(config, null, 2), 'utf8'); - return ng(['build']) - .catch(() => { - return true; - }) - .then((passed) => { - expect(passed).to.equal(true); - }) - .then(() => { - // This should succeed. - config.compilerOptions.paths = { - '@angular/*': [ '*' ] - }; - fs.writeFileSync(configFilePath, JSON.stringify(config, null, 2), 'utf8'); - }) - .then(() => ng(['build'])) - .catch(() => { - expect('build failed where it should have succeeded').to.equal(''); - }); + sh.exec(`${ngBin} build`); + // #TODO: Uncomment these lines when https://github.com/Microsoft/TypeScript/issues/9772 is fixed. + // .catch(() => { + // return true; + // }) + // .then((passed) => { + // expect(passed).to.equal(true); + // }) + + // This should succeed. + config.compilerOptions.paths = { + '@angular/*': [ '../node_modules/@angular/*' ] + }; + fs.writeFileSync(configFilePath, JSON.stringify(config, null, 2), 'utf8'); + sh.exec(`${ngBin} build`); + + expect(existsSync(path.join(process.cwd(), 'dist'))).to.be.equal(true); + const indexHtml = fs.readFileSync(path.join(process.cwd(), 'dist/index.html'), 'utf-8'); + expect(indexHtml).to.include('main.bundle.js'); }); it('Serve and run e2e tests after all other commands', function () { From 435cd18a5a5ff675f225002230e6406d92dae322 Mon Sep 17 00:00:00 2001 From: Sean Larkin Date: Mon, 18 Jul 2016 14:35:00 -0500 Subject: [PATCH 14/38] fix: add environment configuration replacement (#1364) * fix: add environment configuration replacement * remove debuggers * fix: move mobile test above config test because it relies on prod build from previous step * fix: removed unneeded interface moved config paths --- .../app/environments}/environment.dev.ts | 0 .../app/environments}/environment.prod.ts | 0 .../app/{ => environments}/environment.ts | 0 .../ng2/files/__path__/app/index.ts | 2 +- addon/ng2/models/webpack-config.ts | 3 +- addon/ng2/utilities/environment-plugin.ts | 79 +++++++++++++++++++ tests/e2e/e2e_workflow.spec.js | 17 ++-- 7 files changed, 92 insertions(+), 9 deletions(-) rename addon/ng2/blueprints/ng2/files/{config => __path__/app/environments}/environment.dev.ts (100%) rename addon/ng2/blueprints/ng2/files/{config => __path__/app/environments}/environment.prod.ts (100%) rename addon/ng2/blueprints/ng2/files/__path__/app/{ => environments}/environment.ts (100%) create mode 100644 addon/ng2/utilities/environment-plugin.ts diff --git a/addon/ng2/blueprints/ng2/files/config/environment.dev.ts b/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.dev.ts similarity index 100% rename from addon/ng2/blueprints/ng2/files/config/environment.dev.ts rename to addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.dev.ts diff --git a/addon/ng2/blueprints/ng2/files/config/environment.prod.ts b/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.prod.ts similarity index 100% rename from addon/ng2/blueprints/ng2/files/config/environment.prod.ts rename to addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.prod.ts diff --git a/addon/ng2/blueprints/ng2/files/__path__/app/environment.ts b/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.ts similarity index 100% rename from addon/ng2/blueprints/ng2/files/__path__/app/environment.ts rename to addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.ts diff --git a/addon/ng2/blueprints/ng2/files/__path__/app/index.ts b/addon/ng2/blueprints/ng2/files/__path__/app/index.ts index 30c9dfb021b8..7aa84b623989 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/app/index.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/app/index.ts @@ -1,2 +1,2 @@ -export * from './environment'; +export * from './environments/environment'; export * from './app.component'; diff --git a/addon/ng2/models/webpack-config.ts b/addon/ng2/models/webpack-config.ts index e5cd3e00f294..95e3ddb3d0d6 100644 --- a/addon/ng2/models/webpack-config.ts +++ b/addon/ng2/models/webpack-config.ts @@ -1,4 +1,5 @@ import { CliConfig } from './config'; +import { NgCliEnvironmentPlugin } from '../utilities/environment-plugin'; import { getWebpackCommonConfig, getWebpackDevConfigPartial, @@ -35,6 +36,7 @@ export class NgCliWebpackConfig { } this.generateConfig(); + this.config.plugins.unshift(new NgCliEnvironmentPlugin({env: this.environment})); } generateConfig(): void { @@ -59,4 +61,3 @@ export class NgCliWebpackConfig { } } } - diff --git a/addon/ng2/utilities/environment-plugin.ts b/addon/ng2/utilities/environment-plugin.ts new file mode 100644 index 000000000000..6825769d8f95 --- /dev/null +++ b/addon/ng2/utilities/environment-plugin.ts @@ -0,0 +1,79 @@ +import * as fs from 'fs'; + +interface WebpackPlugin { + apply(compiler: any): void; +} + +export class NgCliEnvironmentPlugin implements WebpackPlugin { + _file: string; + _alias: string; + _env: string; + + constructor(config: any) { + if (typeof config === 'string') { + config = {env: config}; + } + if (typeof config.env !== 'string') { + throw new Error('must provide env') + } + const ALIAS = { + '"dev"': 'dev', + 'development': 'dev', + '"development"': 'dev', + '"prod"': 'prod', + 'production': 'prod', + '"production"': 'prod', + '"test"': 'test', + 'testing': 'test', + '"testing"': 'test', + }; + const ENV = config.env.toLowerCase(); + + this._file = config.file || 'environment'; + this._alias = config.alias || ALIAS; + this._env = this._alias[ENV] || ENV; + } + + isEnvFile(file: string): boolean { + return file.indexOf(this._file + '.') !== -1; + } + + replaceFile(file: string): any { + return file + .replace(this._file, this._file + '.' + this._env); + } + + updateResult(result: any): any { + ['request', 'userRequest', 'resource'] + .filter((key) => { return result[key]; }) + .forEach((key) => { + result[key] = this.replaceFile(result[key]); + }); + + return result; + } + + apply(compiler: any): void { + compiler.plugin('normal-module-factory', (normalModuleFactory: any) => { + normalModuleFactory.plugin('after-resolve', (result, callback) => { + var _resource = result['resource']; + if (!this.isEnvFile(_resource)) { + return callback(null, result); + } + var envFile = this.replaceFile(_resource); + + fs.stat(envFile, (err, stats) => { + if (err || !stats.isFile()) { + var errorText = (!err && stats.isFile()) ? 'Is not a file.' : 'Does not exist.'; + console.log('\nWARNING:\n' + envFile + '\n' + errorText + ' ' + 'Using file\n' + _resource + '\n'); + return callback(null, result); + } + // mutate result + var newResult = this.updateResult(result); + return callback(null, newResult); + }); + + }); + }); + } +} diff --git a/tests/e2e/e2e_workflow.spec.js b/tests/e2e/e2e_workflow.spec.js index 3864e7fc9c89..053a4d714360 100644 --- a/tests/e2e/e2e_workflow.spec.js +++ b/tests/e2e/e2e_workflow.spec.js @@ -82,13 +82,6 @@ describe('Basic end-to-end Workflow', function () { expect(sh.exec('git status --porcelain').output).to.be.equal(undefined); }); - xit('Supports production builds config file replacement', function() { - var mainBundlePath = path.join(process.cwd(), 'dist', 'main.js'); - var mainBundleContent = fs.readFileSync(mainBundlePath, { encoding: 'utf8' }); - // production: true minimized turns into production:!0 - expect(mainBundleContent).to.include('production:!0'); - }); - it_mobile('Enables mobile-specific production features in prod builds', () => { let indexHtml = fs.readFileSync(path.join(process.cwd(), 'dist/index.html'), 'utf-8'); // Service Worker @@ -106,6 +99,16 @@ describe('Basic end-to-end Workflow', function () { expect(indexHtml).to.match(/app works!/); }); + it('Supports build config file replacement', function() { + this.timeout(420000); + + sh.exec(`${ngBin} build --dev`); + var mainBundlePath = path.join(process.cwd(), 'dist', 'main.bundle.js'); + var mainBundleContent = fs.readFileSync(mainBundlePath, { encoding: 'utf8' }); + + expect(mainBundleContent).to.include('production: false'); + }); + it('Can run `ng build` in created project', function () { this.timeout(420000); From 18318a2b681bf56232cd239dbe08abb6484b4b2b Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Tue, 19 Jul 2016 03:02:42 +0100 Subject: [PATCH 15/38] fix(tests): re-enable sass/less/stylus tests (#1363) --- .../files/__path__/__name__.component.ts | 2 +- addon/ng2/blueprints/component/index.js | 3 +- .../ng2/files/__path__/app/app.component.ts | 2 +- addon/ng2/blueprints/ng2/files/package.json | 2 +- addon/ng2/blueprints/ng2/index.js | 15 +- tests/e2e/e2e_workflow.spec.js | 183 ++++++++---------- 6 files changed, 83 insertions(+), 124 deletions(-) diff --git a/addon/ng2/blueprints/component/files/__path__/__name__.component.ts b/addon/ng2/blueprints/component/files/__path__/__name__.component.ts index cc31f7820898..7e485321bcbe 100644 --- a/addon/ng2/blueprints/component/files/__path__/__name__.component.ts +++ b/addon/ng2/blueprints/component/files/__path__/__name__.component.ts @@ -10,7 +10,7 @@ import { Component, OnInit } from '@angular/core'; `,<% } else { %> templateUrl: '<%= dasherizedModuleName %>.component.html',<% } if(inlineStyle) { %> styles: []<% } else { %> - styleUrls: ['<%= dasherizedModuleName %>.component.css']<% } %> + styleUrls: ['<%= dasherizedModuleName %>.component.<%= styleExt %>']<% } %> }) export class <%= classifiedModuleName %>Component implements OnInit { diff --git a/addon/ng2/blueprints/component/index.js b/addon/ng2/blueprints/component/index.js index 750b8beb25eb..6e81ce1c77f2 100644 --- a/addon/ng2/blueprints/component/index.js +++ b/addon/ng2/blueprints/component/index.js @@ -54,7 +54,8 @@ module.exports = { route: options.route, isLazyRoute: !!options.isLazyRoute, isAppComponent: !!options.isAppComponent, - selector: this.selector + selector: this.selector, + styleExt: this.styleExt }; }, diff --git a/addon/ng2/blueprints/ng2/files/__path__/app/app.component.ts b/addon/ng2/blueprints/ng2/files/__path__/app/app.component.ts index 7fd0dc4b197d..c9b95fe6be12 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/app/app.component.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/app/app.component.ts @@ -11,7 +11,7 @@ import { APP_SHELL_DIRECTIVES } from '@angular/app-shell';<% } %> `, styles: [], directives: [APP_SHELL_DIRECTIVES]<% } else { %>templateUrl: 'app.component.html', - styleUrls: ['app.component.css']<% } %> + styleUrls: ['app.component.<%= styleExt %>']<% } %> }) export class AppComponent { title = 'app works!'; diff --git a/addon/ng2/blueprints/ng2/files/package.json b/addon/ng2/blueprints/ng2/files/package.json index 467f32648b28..f3027ebe6b7e 100644 --- a/addon/ng2/blueprints/ng2/files/package.json +++ b/addon/ng2/blueprints/ng2/files/package.json @@ -47,6 +47,6 @@ "ts-node": "0.9.1", "tslint": "3.11.0", "typescript": "^1.9.0-dev.20160627-1.0", - "typings": "^1.3.1"<%= stylePackage %> + "typings": "^1.3.1" } } diff --git a/addon/ng2/blueprints/ng2/index.js b/addon/ng2/blueprints/ng2/index.js index 827a95b443e0..146ef7c50023 100644 --- a/addon/ng2/blueprints/ng2/index.js +++ b/addon/ng2/blueprints/ng2/index.js @@ -2,7 +2,6 @@ const Blueprint = require('ember-cli/lib/models/blueprint'); const path = require('path'); const stringUtils = require('ember-cli-string-utils'); const getFiles = Blueprint.prototype.files; -const EOL = require('os').EOL; module.exports = { description: '', @@ -29,17 +28,6 @@ module.exports = { const fullAppName = stringUtils.dasherize(options.entity.name) .replace(/-(.)/g, (_, l) => ' ' + l.toUpperCase()) .replace(/^./, (l) => l.toUpperCase()); - - var stylePackage = ''; - switch(options.style.toLowerCase()) { - case 'sass': - case 'scss': - stylePackage = `,${EOL} "node-sass": "3.7.0"`; - break; - case 'styl': - stylePackage = `,${EOL} "stylus": "0.54.5"`; - break; - } return { htmlComponentName: stringUtils.dasherize(options.entity.name), @@ -50,8 +38,7 @@ module.exports = { prefix: options.prefix, styleExt: this.styleExt, refToTypings: refToTypings, - isMobile: options.mobile, - stylePackage: stylePackage + isMobile: options.mobile }; }, diff --git a/tests/e2e/e2e_workflow.spec.js b/tests/e2e/e2e_workflow.spec.js index 053a4d714360..b4a6b984e054 100644 --- a/tests/e2e/e2e_workflow.spec.js +++ b/tests/e2e/e2e_workflow.spec.js @@ -319,120 +319,93 @@ describe('Basic end-to-end Workflow', function () { expect(existsSync(tmpFileLocation)).to.be.equal(true); }); - it.skip('Installs sass support successfully', function() { + // Mobile mode doesn't have styles + it_not_mobile('Supports scss in styleUrls', function() { this.timeout(420000); - sh.exec('npm install node-sass', { silent: true }); - return ng(['generate', 'component', 'test-component']) - .then(() => { - let componentPath = path.join(process.cwd(), 'src', 'app', 'test-component'); - let cssFile = path.join(componentPath, 'test-component.component.css'); - let scssFile = path.join(componentPath, 'test-component.component.scss'); - let scssPartialFile = path.join(componentPath, '_test-component.component.partial.scss'); - - let scssPartialExample = '.partial {\n @extend .outer;\n }'; - fs.writeFileSync(scssPartialFile, scssPartialExample, 'utf8'); - expect(existsSync(scssPartialFile)).to.be.equal(true); - - expect(existsSync(componentPath)).to.be.equal(true); - sh.mv(cssFile, scssFile); - expect(existsSync(scssFile)).to.be.equal(true); - expect(existsSync(cssFile)).to.be.equal(false); - let scssExample = '@import "test-component.component.partial";\n\n.outer {\n .inner { background: #fff; }\n }'; - fs.writeFileSync(scssFile, scssExample, 'utf8'); - - sh.exec(`${ngBin} build`); - let destCss = path.join(process.cwd(), 'dist', 'app', 'test-component', 'test-component.component.css'); - expect(existsSync(destCss)).to.be.equal(true); - let contents = fs.readFileSync(destCss, 'utf8'); - expect(contents).to.include('.outer .inner'); - expect(contents).to.include('.partial .inner'); - - sh.rm('-f', destCss); - process.chdir('src'); - sh.exec(`${ngBin} build`); - expect(existsSync(destCss)).to.be.equal(true); - contents = fs.readFileSync(destCss, 'utf8'); - expect(contents).to.include('.outer .inner'); - expect(contents).to.include('.partial .inner'); - - process.chdir('..'); - sh.exec('npm uninstall node-sass', { silent: true }); - }); + let cssFilename = 'app.component.css'; + let scssFilename = 'app.component.scss'; + let componentPath = path.join(process.cwd(), 'src', 'app'); + let componentFile = path.join(componentPath, 'app.component.ts'); + let cssFile = path.join(componentPath, cssFilename); + let scssFile = path.join(componentPath, scssFilename); + let scssExample = '@import "app.component.partial";\n\n.outer {\n .inner { background: #fff; }\n }'; + let scssPartialFile = path.join(componentPath, '_app.component.partial.scss'); + let scssPartialExample = '.partial {\n @extend .outer;\n }'; + let componentContents = fs.readFileSync(componentFile, 'utf8'); + + sh.mv(cssFile, scssFile); + fs.writeFileSync(scssFile, scssExample, 'utf8'); + fs.writeFileSync(scssPartialFile, scssPartialExample, 'utf8'); + fs.writeFileSync(componentFile, componentContents.replace(new RegExp(cssFilename, 'g'), scssFilename), 'utf8'); + + sh.exec(`${ngBin} build`); + let destCssBundle = path.join(process.cwd(), 'dist', 'main.bundle.js'); + let contents = fs.readFileSync(destCssBundle, 'utf8'); + expect(contents).to.include('.outer .inner'); + expect(contents).to.include('.partial .inner'); + + sh.mv(scssFile, cssFile); + fs.writeFileSync(cssFile, '', 'utf8'); + fs.writeFileSync(componentFile, componentContents, 'utf8'); + sh.rm('-f', scssPartialFile); }); - it.skip('Installs less support successfully', function() { + // Mobile mode doesn't have styles + it_not_mobile('Supports less in styleUrls', function() { this.timeout(420000); - sh.exec('npm install less', { silent: true }); - return ng(['generate', 'component', 'test-component']) - .then(() => { - let componentPath = path.join(process.cwd(), 'src', 'app', 'test-component'); - let cssFile = path.join(componentPath, 'test-component.component.css'); - let lessFile = path.join(componentPath, 'test-component.component.less'); - - expect(existsSync(componentPath)).to.be.equal(true); - sh.mv(cssFile, lessFile); - expect(existsSync(lessFile)).to.be.equal(true); - expect(existsSync(cssFile)).to.be.equal(false); - let lessExample = '.outer {\n .inner { background: #fff; }\n }'; - fs.writeFileSync(lessFile, lessExample, 'utf8'); - - sh.exec(`${ngBin} build`); - let destCss = path.join(process.cwd(), 'dist', 'app', 'test-component', 'test-component.component.css'); - expect(existsSync(destCss)).to.be.equal(true); - let contents = fs.readFileSync(destCss, 'utf8'); - expect(contents).to.include('.outer .inner'); - - sh.rm('-f', destCss); - process.chdir('src'); - sh.exec(`${ngBin} build`); - expect(existsSync(destCss)).to.be.equal(true); - contents = fs.readFileSync(destCss, 'utf8'); - expect(contents).to.include('.outer .inner'); - - process.chdir('..'); - sh.exec('npm uninstall less', { silent: true }); - }); + let cssFilename = 'app.component.css'; + let lessFilename = 'app.component.less'; + let componentPath = path.join(process.cwd(), 'src', 'app'); + let componentFile = path.join(componentPath, 'app.component.ts'); + let cssFile = path.join(componentPath, cssFilename); + let lessFile = path.join(componentPath, lessFilename); + let lessExample = '.outer {\n .inner { background: #fff; }\n }'; + let componentContents = fs.readFileSync(componentFile, 'utf8'); + + sh.mv(cssFile, lessFile); + fs.writeFileSync(lessFile, lessExample, 'utf8'); + fs.writeFileSync(componentFile, componentContents.replace(new RegExp(cssFilename, 'g'), lessFilename), 'utf8'); + + sh.exec(`${ngBin} build`); + let destCssBundle = path.join(process.cwd(), 'dist', 'main.bundle.js'); + let contents = fs.readFileSync(destCssBundle, 'utf8'); + expect(contents).to.include('.outer .inner'); + + fs.writeFileSync(lessFile, '', 'utf8'); + sh.mv(lessFile, cssFile); + fs.writeFileSync(componentFile, componentContents, 'utf8'); }); - it.skip('Installs stylus support successfully', function() { + // Mobile mode doesn't have styles + it_not_mobile('Supports stylus in styleUrls', function() { this.timeout(420000); - sh.exec('npm install stylus', { silent: true }); - return ng(['generate', 'component', 'test-component']) - .then(() => { - let componentPath = path.join(process.cwd(), 'src', 'app', 'test-component'); - let cssFile = path.join(componentPath, 'test-component.component.css'); - let stylusFile = path.join(componentPath, 'test-component.component.styl'); - - sh.mv(cssFile, stylusFile); - expect(existsSync(stylusFile)).to.be.equal(true); - expect(existsSync(cssFile)).to.be.equal(false); - let stylusExample = '.outer {\n .inner { background: #fff; }\n }'; - fs.writeFileSync(stylusFile, stylusExample, 'utf8'); - - sh.exec(`${ngBin} build`); - let destCss = path.join(process.cwd(), 'dist', 'app', 'test-component', 'test-component.component.css'); - expect(existsSync(destCss)).to.be.equal(true); - let contents = fs.readFileSync(destCss, 'utf8'); - expect(contents).to.include('.outer .inner'); - - sh.rm('-f', destCss); - process.chdir('src'); - sh.exec(`${ngBin} build`); - expect(existsSync(destCss)).to.be.equal(true); - contents = fs.readFileSync(destCss, 'utf8'); - expect(contents).to.include('.outer .inner'); - - process.chdir('..'); - sh.exec('npm uninstall stylus', { silent: true }); - }); + let cssFilename = 'app.component.css'; + let stylusFilename = 'app.component.scss'; + let componentPath = path.join(process.cwd(), 'src', 'app'); + let componentFile = path.join(componentPath, 'app.component.ts'); + let cssFile = path.join(componentPath, cssFilename); + let stylusFile = path.join(componentPath, stylusFilename); + let stylusExample = '.outer {\n .inner { background: #fff; }\n }'; + let componentContents = fs.readFileSync(componentFile, 'utf8'); + + sh.mv(cssFile, stylusFile); + fs.writeFileSync(stylusFile, stylusExample, 'utf8'); + fs.writeFileSync(componentFile, componentContents.replace(new RegExp(cssFilename, 'g'), stylusFilename), 'utf8'); + + sh.exec(`${ngBin} build`); + let destCssBundle = path.join(process.cwd(), 'dist', 'main.bundle.js'); + let contents = fs.readFileSync(destCssBundle, 'utf8'); + expect(contents).to.include('.outer .inner'); + + fs.writeFileSync(stylusFile, '', 'utf8'); + sh.mv(stylusFile, cssFile); + fs.writeFileSync(componentFile, componentContents, 'utf8'); }); - // This test causes complications with path resolution in TS broccoli plugin, - // and isn't mobile specific - it_not_mobile('Turn on `noImplicitAny` in tsconfig.json and rebuild', function () { + it('Turn on `noImplicitAny` in tsconfig.json and rebuild', function () { this.timeout(420000); const configFilePath = path.join(process.cwd(), 'src', 'tsconfig.json'); @@ -443,10 +416,8 @@ describe('Basic end-to-end Workflow', function () { sh.rm('-rf', path.join(process.cwd(), 'dist')); - return ng(['build']) - .then(() => { - expect(existsSync(path.join(process.cwd(), 'dist'))).to.be.equal(true); - }); + sh.exec(`${ngBin} build`); + expect(existsSync(path.join(process.cwd(), 'dist'))).to.be.equal(true); }); it('Turn on path mapping in tsconfig.json and rebuild', function () { From de98a64023a1ffb177bf67a73c3600f77448ea27 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Tue, 19 Jul 2016 21:26:36 +0100 Subject: [PATCH 16/38] chore: remove systemjs (#1376) --- addon/ng2/blueprints/component/index.js | 15 +---- .../ng2/files/__path__/system-config.ts | 60 ------------------- .../ng2/files/config/karma-test-shim.js | 56 ----------------- addon/ng2/blueprints/ng2/files/package.json | 1 - package.json | 1 - tests/acceptance/generate-component.spec.js | 11 ---- 6 files changed, 1 insertion(+), 143 deletions(-) delete mode 100644 addon/ng2/blueprints/ng2/files/__path__/system-config.ts delete mode 100644 addon/ng2/blueprints/ng2/files/config/karma-test-shim.js diff --git a/addon/ng2/blueprints/component/index.js b/addon/ng2/blueprints/component/index.js index 6e81ce1c77f2..7f8758026328 100644 --- a/addon/ng2/blueprints/component/index.js +++ b/addon/ng2/blueprints/component/index.js @@ -115,20 +115,7 @@ module.exports = { } if (!options.flat) { - var filePath = path.join(this.project.ngConfig.defaults.sourceDir, 'system-config.ts'); - var barrelUrl = this.appDir.replace(/\\/g, '/'); - if (barrelUrl[0] === '/') { - barrelUrl = barrelUrl.substr(1); - } - - return addBarrelRegistration(this, this.generatePath) - .then(() => { - return this.insertIntoFile( - filePath, - ` '${barrelUrl}',`, - { before: ' /** @cli-barrel */' } - ); - }); + return addBarrelRegistration(this, this.generatePath); } else { return addBarrelRegistration( this, diff --git a/addon/ng2/blueprints/ng2/files/__path__/system-config.ts b/addon/ng2/blueprints/ng2/files/__path__/system-config.ts deleted file mode 100644 index 55e4ac712886..000000000000 --- a/addon/ng2/blueprints/ng2/files/__path__/system-config.ts +++ /dev/null @@ -1,60 +0,0 @@ -// SystemJS configuration file, see links for more information -// https://github.com/systemjs/systemjs -// https://github.com/systemjs/systemjs/blob/master/docs/config-api.md - -/*********************************************************************************************** - * User Configuration. - **********************************************************************************************/ -/** Map relative paths to URLs. */ -const map: any = { -}; - -/** User packages configuration. */ -const packages: any = { -}; - -//////////////////////////////////////////////////////////////////////////////////////////////// -/*********************************************************************************************** - * Everything underneath this line is managed by the CLI. - **********************************************************************************************/ -const barrels: string[] = [ - // Angular specific barrels. - '@angular/core', - '@angular/common', - '@angular/compiler', - '@angular/forms', - '@angular/http', - '@angular/router', - '@angular/platform-browser', - '@angular/platform-browser-dynamic',<% if(isMobile) { %> - '@angular/app-shell',<% } %> - - // Thirdparty barrels. - 'rxjs', - - // App specific barrels. - 'app', - 'app/shared', - /** @cli-barrel */ -]; - -const cliSystemConfigPackages: any = {}; -barrels.forEach((barrelName: string) => { - cliSystemConfigPackages[barrelName] = { main: 'index' }; -}); - -/** Type declaration for ambient System. */ -declare var System: any; - -// Apply the CLI SystemJS configuration. -System.config({ - map: { - '@angular': 'vendor/@angular', - 'rxjs': 'vendor/rxjs', - 'main': 'main.js' - }, - packages: cliSystemConfigPackages -}); - -// Apply the user's configuration. -System.config({ map, packages }); diff --git a/addon/ng2/blueprints/ng2/files/config/karma-test-shim.js b/addon/ng2/blueprints/ng2/files/config/karma-test-shim.js deleted file mode 100644 index b62ba72ff17a..000000000000 --- a/addon/ng2/blueprints/ng2/files/config/karma-test-shim.js +++ /dev/null @@ -1,56 +0,0 @@ -// Test shim for Karma, needed to load files via SystemJS - -/*global jasmine, __karma__, window*/ -Error.stackTraceLimit = Infinity; -jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; - -__karma__.loaded = function () { -}; - -var distPath = '/base/dist/'; -var appPaths = ['app']; //Add all valid source code folders here - -function isJsFile(path) { - return path.slice(-3) == '.js'; -} - -function isSpecFile(path) { - return path.slice(-8) == '.spec.js'; -} - -function isAppFile(path) { - return isJsFile(path) && appPaths.some(function(appPath) { - var fullAppPath = distPath + appPath + '/'; - return path.substr(0, fullAppPath.length) == fullAppPath; - }); -} - -var allSpecFiles = Object.keys(window.__karma__.files) - .filter(isSpecFile) - .filter(isAppFile); - -// Load our SystemJS configuration. -System.config({ - baseURL: distPath -}); - -System.import('system-config.js').then(function() { - // Load and configure the TestComponentBuilder. - return Promise.all([ - System.import('@angular/core/testing'), - System.import('@angular/platform-browser-dynamic/testing') - ]).then(function (providers) { - var testing = providers[0]; - var testingBrowser = providers[1]; - - testing.setBaseTestProviders(testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, - testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS); - }); -}).then(function() { - // Finally, load all spec files. - // This will run the tests directly. - return Promise.all( - allSpecFiles.map(function (moduleName) { - return System.import(moduleName); - })); -}).then(__karma__.start, __karma__.error); diff --git a/addon/ng2/blueprints/ng2/files/package.json b/addon/ng2/blueprints/ng2/files/package.json index f3027ebe6b7e..bc6179cced14 100644 --- a/addon/ng2/blueprints/ng2/files/package.json +++ b/addon/ng2/blueprints/ng2/files/package.json @@ -23,7 +23,6 @@ "@angular/router": "3.0.0-beta.2", "core-js": "^2.4.0", "rxjs": "5.0.0-beta.6", - "systemjs": "0.19.26", "ts-helpers": "^1.1.1", "zone.js": "0.6.12" }, diff --git a/package.json b/package.json index a93ccae5ae3d..0e7e62a39c39 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,6 @@ "stylus": "^0.54.5", "stylus-loader": "^2.1.0", "symlink-or-copy": "^1.0.3", - "systemjs-builder": "0.15.17", "ts-helpers": "^1.1.1", "ts-loader": "^0.8.2", "tslint": "^3.11.0", diff --git a/tests/acceptance/generate-component.spec.js b/tests/acceptance/generate-component.spec.js index a0b126e9cba7..f25005165cbe 100644 --- a/tests/acceptance/generate-component.spec.js +++ b/tests/acceptance/generate-component.spec.js @@ -178,15 +178,4 @@ describe('Acceptance: ng generate component', function () { expect(existsSync(testPath)).to.equal(false); }); }); - - it('ng generate component my-comp --dry-run does not register a barrel in system-config.ts', () => { - var configPath = path.join(root, 'tmp', 'foo', 'src', 'system-config.ts'); - var unmodifiedFile = fs.readFileSync(configPath, 'utf8'); - - return ng(['generate', 'component', 'my-comp', '--dry-run']).then(() => { - var afterGenerateFile = fs.readFileSync(configPath, 'utf8'); - - expect(afterGenerateFile).to.equal(unmodifiedFile); - }); - }); }); From 89b4dd5558e8e42ac42f4677dd85d22f5b07b985 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Tue, 19 Jul 2016 23:35:48 +0100 Subject: [PATCH 17/38] chore: remove vendor.ts (#1383) --- .../ng2/blueprints/ng2/files/__path__/vendor.ts | 17 ----------------- .../blueprints/ng2/files/config/karma.conf.js | 4 ---- addon/ng2/models/webpack-build-common.ts | 3 +-- 3 files changed, 1 insertion(+), 23 deletions(-) delete mode 100644 addon/ng2/blueprints/ng2/files/__path__/vendor.ts diff --git a/addon/ng2/blueprints/ng2/files/__path__/vendor.ts b/addon/ng2/blueprints/ng2/files/__path__/vendor.ts deleted file mode 100644 index f0f02685fb31..000000000000 --- a/addon/ng2/blueprints/ng2/files/__path__/vendor.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Typescript emit helpers polyfill -import 'ts-helpers'; - -import '@angular/core'; -import '@angular/common'; -import '@angular/compiler'; -import '@angular/http'; -import '@angular/router'; -import '@angular/platform-browser'; -import '@angular/platform-browser-dynamic'; - -<% if(isMobile) { %> -import '@angular/app-shell'; -<% } %> - -import 'rxjs/add/operator/map'; -import 'rxjs/add/operator/mergeMap'; diff --git a/addon/ng2/blueprints/ng2/files/config/karma.conf.js b/addon/ng2/blueprints/ng2/files/config/karma.conf.js index cff5f0a204d5..71e33490cf37 100644 --- a/addon/ng2/blueprints/ng2/files/config/karma.conf.js +++ b/addon/ng2/blueprints/ng2/files/config/karma.conf.js @@ -14,10 +14,6 @@ module.exports = function (config) { } }, files: [], - exclude: [ - // Vendor packages might include spec files. We don't want to use those. - 'dist/vendor/**/*.spec.js' - ], preprocessors: {}, reporters: ['progress'], port: 9876, diff --git a/addon/ng2/models/webpack-build-common.ts b/addon/ng2/models/webpack-build-common.ts index c41045021b8f..feb71aba1f3d 100644 --- a/addon/ng2/models/webpack-build-common.ts +++ b/addon/ng2/models/webpack-build-common.ts @@ -26,7 +26,6 @@ export function getWebpackCommonConfig(projectRoot: string) { context: path.resolve(__dirname, './'), entry: { main: [path.resolve(projectRoot, './src/main.ts')], - vendor: path.resolve(projectRoot, './src/vendor.ts'), polyfills: path.resolve(projectRoot, './src/polyfills.ts') }, output: { @@ -74,7 +73,7 @@ export function getWebpackCommonConfig(projectRoot: string) { chunksSortMode: 'dependency' }), new webpack.optimize.CommonsChunkPlugin({ - name: ['vendor', 'polyfills'] + name: ['polyfills'] }), new webpack.optimize.CommonsChunkPlugin({ minChunks: Infinity, From a144db115594c8722bc3a26e672d4f20fb98dc81 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Wed, 20 Jul 2016 00:12:39 +0100 Subject: [PATCH 18/38] chore: remove material2 test option (#1385) --- addon/ng2/commands/build.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/addon/ng2/commands/build.ts b/addon/ng2/commands/build.ts index 93ea327ed2c0..9b99d6587ff9 100644 --- a/addon/ng2/commands/build.ts +++ b/addon/ng2/commands/build.ts @@ -25,10 +25,7 @@ module.exports = Command.extend({ { name: 'output-path', type: 'Path', default: 'dist/', aliases: ['o'] }, { name: 'watch', type: Boolean, default: false, aliases: ['w'] }, { name: 'watcher', type: String }, - { name: 'suppress-sizes', type: Boolean, default: false }, - - // Experimental webpack build for material team - { name: 'm2', type: Boolean, default: false} + { name: 'suppress-sizes', type: Boolean, default: false } ], run: function (commandOptions: BuildOptions) { From 30fd94273c99ac84e09af86840bf8a590aa229db Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Wed, 20 Jul 2016 01:39:43 +0100 Subject: [PATCH 19/38] fix(build): re-add support for sourceDir (#1378) --- .../ng2/blueprints/ng2/files/__path__/test.ts | 2 +- .../ng2/files/__path__/tsconfig.json | 2 +- addon/ng2/models/webpack-build-common.ts | 13 ++++---- addon/ng2/models/webpack-build-development.ts | 5 +-- addon/ng2/models/webpack-build-mobile.ts | 11 ++++--- addon/ng2/models/webpack-build-production.ts | 5 +-- addon/ng2/models/webpack-build-test.ts | 13 ++++---- addon/ng2/models/webpack-config.ts | 12 ++++--- addon/ng2/tasks/serve-webpack.ts | 3 +- addon/ng2/tasks/{test.js => test.ts} | 31 +++++++++---------- 10 files changed, 51 insertions(+), 46 deletions(-) rename addon/ng2/tasks/{test.js => test.ts} (63%) diff --git a/addon/ng2/blueprints/ng2/files/__path__/test.ts b/addon/ng2/blueprints/ng2/files/__path__/test.ts index e61005825b11..6ba450cbd3dd 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/test.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/test.ts @@ -29,7 +29,7 @@ Promise.all([ ); }); -let testContext: any = require.context('../src', true, /\.spec\.ts/); +let testContext: any = require.context('./', true, /\.spec\.ts/); function requireAll(requireContext: any) { return requireContext.keys().map(requireContext); } diff --git a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json index e0831213e64c..5acc3c417061 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "baseUrl":"./src", + "baseUrl":"./", "declaration": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, diff --git a/addon/ng2/models/webpack-build-common.ts b/addon/ng2/models/webpack-build-common.ts index feb71aba1f3d..4d3e5ca27513 100644 --- a/addon/ng2/models/webpack-build-common.ts +++ b/addon/ng2/models/webpack-build-common.ts @@ -1,23 +1,24 @@ import * as webpack from 'webpack'; import {LoaderConfig, PathsPlugin} from '../utilities/ts-path-mappings-webpack-plugin'; +import { CliConfig } from './config'; const path = require('path'); const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin; const CopyWebpackPlugin = require('copy-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); -export function getWebpackCommonConfig(projectRoot: string) { +export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) { const awesomeTypescriptLoaderConfig: LoaderConfig | any = { useWebpackText: true, useForkChecker: true, - tsconfig: path.resolve(projectRoot, './src/tsconfig.json') + tsconfig: path.resolve(projectRoot, `./${sourceDir}/tsconfig.json`) } return { devtool: 'inline-source-map', resolve: { extensions: ['', '.ts', '.js'], - root: path.resolve(projectRoot, './src'), + root: path.resolve(projectRoot, `./${sourceDir}`), moduleDirectories: ['node_modules'], plugins: [ new PathsPlugin(awesomeTypescriptLoaderConfig); @@ -25,8 +26,8 @@ export function getWebpackCommonConfig(projectRoot: string) { }, context: path.resolve(__dirname, './'), entry: { - main: [path.resolve(projectRoot, './src/main.ts')], - polyfills: path.resolve(projectRoot, './src/polyfills.ts') + main: [path.resolve(projectRoot, `./${sourceDir}/main.ts`)], + polyfills: path.resolve(projectRoot, `./${sourceDir}/polyfills.ts`) }, output: { path: path.resolve(projectRoot, './dist'), @@ -69,7 +70,7 @@ export function getWebpackCommonConfig(projectRoot: string) { plugins: [ new ForkCheckerPlugin(), new HtmlWebpackPlugin({ - template: path.resolve(projectRoot, 'src/index.html'), + template: path.resolve(projectRoot, `./${sourceDir}/index.html`), chunksSortMode: 'dependency' }), new webpack.optimize.CommonsChunkPlugin({ diff --git a/addon/ng2/models/webpack-build-development.ts b/addon/ng2/models/webpack-build-development.ts index fc37a5d92b45..61932014d254 100644 --- a/addon/ng2/models/webpack-build-development.ts +++ b/addon/ng2/models/webpack-build-development.ts @@ -1,6 +1,7 @@ +import { CliConfig } from './config'; const path = require('path') -export const getWebpackDevConfigPartial = function(projectRoot: string) { +export const getWebpackDevConfigPartial = function(projectRoot: string, sourceDir: string) { return { debug: true, devtool: 'cheap-module-source-map', @@ -13,7 +14,7 @@ export const getWebpackDevConfigPartial = function(projectRoot: string) { tslint: { emitErrors: false, failOnHint: false, - resourcePath: path.resolve(projectRoot, './src') + resourcePath: path.resolve(projectRoot, `./${sourceDir}`) }, node: { global: 'window', diff --git a/addon/ng2/models/webpack-build-mobile.ts b/addon/ng2/models/webpack-build-mobile.ts index 397fa412f68c..1480a4eebf37 100644 --- a/addon/ng2/models/webpack-build-mobile.ts +++ b/addon/ng2/models/webpack-build-mobile.ts @@ -3,18 +3,19 @@ import * as path from 'path'; import * as OfflinePlugin from 'offline-plugin'; import * as CopyWebpackPlugin from 'copy-webpack-plugin'; import { PrerenderWebpackPlugin } from '../utilities/prerender-webpack-plugin.ts'; +import { CliConfig } from './config'; -export const getWebpackMobileConfigPartial = function (projectRoot: string) { +export const getWebpackMobileConfigPartial = function (projectRoot: string, sourceDir: string) { return { plugins: [ new CopyWebpackPlugin([ - {from: path.resolve(projectRoot, './src/icons'), to: path.resolve(projectRoot, './dist/icons')}, - {from: path.resolve(projectRoot, './src/manifest.webapp'), to: path.resolve(projectRoot, './dist')} + {from: path.resolve(projectRoot, `./${sourceDir}/icons`), to: path.resolve(projectRoot, './dist/icons')}, + {from: path.resolve(projectRoot, `./${sourceDir}/manifest.webapp`), to: path.resolve(projectRoot, './dist')} ]), new PrerenderWebpackPlugin({ templatePath: 'index.html', - configPath: path.resolve(projectRoot, './src/main-app-shell.ts'), - appPath: path.resolve(projectRoot, './src') + configPath: path.resolve(projectRoot, `./${sourceDir}/main-app-shell.ts`), + appPath: path.resolve(projectRoot, `./${sourceDir}`) }) ] } diff --git a/addon/ng2/models/webpack-build-production.ts b/addon/ng2/models/webpack-build-production.ts index 60028dca1917..e5c53d5648e6 100644 --- a/addon/ng2/models/webpack-build-production.ts +++ b/addon/ng2/models/webpack-build-production.ts @@ -1,11 +1,12 @@ import * as webpack from 'webpack'; +import { CliConfig } from './config'; const path = require('path'); const webpackMerge = require('webpack-merge'); // used to merge webpack configs const WebpackMd5Hash = require('webpack-md5-hash'); const CompressionPlugin = require("compression-webpack-plugin"); -export const getWebpackProdConfigPartial = function(projectRoot: string) { +export const getWebpackProdConfigPartial = function(projectRoot: string, sourceDir: string) { return { debug: false, devtool: 'source-map', @@ -36,7 +37,7 @@ export const getWebpackProdConfigPartial = function(projectRoot: string) { tslint: { emitErrors: true, failOnHint: true, - resourcePath: path.resolve(projectRoot, './src') + resourcePath: path.resolve(projectRoot, `./${sourceDir}`) }, htmlLoader: { minimize: true, diff --git a/addon/ng2/models/webpack-build-test.ts b/addon/ng2/models/webpack-build-test.ts index 455b5960c6c0..42ee2bf45dbc 100644 --- a/addon/ng2/models/webpack-build-test.ts +++ b/addon/ng2/models/webpack-build-test.ts @@ -1,17 +1,18 @@ import * as webpack from 'webpack'; +import { CliConfig } from './config'; const path = require('path'); -export const getWebpackTestConfig = function(projectRoot: string) { +export const getWebpackTestConfig = function(projectRoot: string, sourceDir: string) { return { devtool: 'inline-source-map', context: path.resolve(__dirname, './'), resolve: { extensions: ['', '.ts', '.js'], - root: path.resolve(projectRoot, './src') + root: path.resolve(projectRoot, `./${sourceDir}`) }, entry: { - test: path.resolve(projectRoot, './src/test.ts') + test: path.resolve(projectRoot, `./${sourceDir}/test.ts`) }, output: { path: './dist.test', @@ -43,7 +44,7 @@ export const getWebpackTestConfig = function(projectRoot: string) { loader: 'awesome-typescript-loader', query: { useWebpackText: true, - tsconfig: path.resolve(projectRoot, './src/tsconfig.json'), + tsconfig: path.resolve(projectRoot, `./${sourceDir}/tsconfig.json`), module: "commonjs", target: "es5", useForkChecker: true, @@ -62,7 +63,7 @@ export const getWebpackTestConfig = function(projectRoot: string) { { test: /\.less$/, loaders: ['raw-loader', 'postcss-loader', 'less-loader'] }, { test: /\.scss$/, loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] }, { test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000'}, - { test: /\.html$/, loader: 'raw-loader', exclude: [path.resolve(projectRoot, 'src/index.html')] } + { test: /\.html$/, loader: 'raw-loader', exclude: [path.resolve(projectRoot, `./${sourceDir}/index.html`)] } ], postLoaders: [ { @@ -77,7 +78,7 @@ export const getWebpackTestConfig = function(projectRoot: string) { tslint: { emitErrors: false, failOnHint: false, - resourcePath: 'src' + resourcePath: `./${sourceDir}` }, node: { global: 'window', diff --git a/addon/ng2/models/webpack-config.ts b/addon/ng2/models/webpack-config.ts index 95e3ddb3d0d6..5dc9541bb333 100644 --- a/addon/ng2/models/webpack-config.ts +++ b/addon/ng2/models/webpack-config.ts @@ -24,13 +24,15 @@ export class NgCliWebpackConfig { private webpackMobileProdConfigPartial: any; constructor(public ngCliProject: any, public environment: string) { - this.webpackBaseConfig = getWebpackCommonConfig(this.ngCliProject.root); - this.webpackDevConfigPartial = getWebpackDevConfigPartial(this.ngCliProject.root); - this.webpackProdConfigPartial = getWebpackProdConfigPartial(this.ngCliProject.root); + const sourceDir = CliConfig.fromProject().defaults.sourceDir; + + this.webpackBaseConfig = getWebpackCommonConfig(this.ngCliProject.root, sourceDir); + this.webpackDevConfigPartial = getWebpackDevConfigPartial(this.ngCliProject.root, sourceDir); + this.webpackProdConfigPartial = getWebpackProdConfigPartial(this.ngCliProject.root, sourceDir); if (CliConfig.fromProject().apps[0].mobile){ - this.webpackMobileConfigPartial = getWebpackMobileConfigPartial(this.ngCliProject.root); - this.webpackMobileProdConfigPartial = getWebpackMobileProdConfigPartial(this.ngCliProject.root); + this.webpackMobileConfigPartial = getWebpackMobileConfigPartial(this.ngCliProject.root, sourceDir); + this.webpackMobileProdConfigPartial = getWebpackMobileProdConfigPartial(this.ngCliProject.root, sourceDir); this.webpackBaseConfig = webpackMerge(this.webpackBaseConfig, this.webpackMobileConfigPartial); this.webpackProdConfigPartial = webpackMerge(this.webpackProdConfigPartial, this.webpackMobileProdConfigPartial); } diff --git a/addon/ng2/tasks/serve-webpack.ts b/addon/ng2/tasks/serve-webpack.ts index 315cc3d163ad..176af5388902 100644 --- a/addon/ng2/tasks/serve-webpack.ts +++ b/addon/ng2/tasks/serve-webpack.ts @@ -1,6 +1,7 @@ import {webpackDevServerOutputOptions} from '../models/'; import {NgCliWebpackConfig} from '../models/webpack-config'; import {ServeTaskOptions} from '../commands/serve'; +import { CliConfig } from '../models/config'; const path = require('path'); const chalk = require('chalk'); @@ -32,7 +33,7 @@ module.exports = Task.extend({ })); const webpackDevServerConfiguration: IWebpackDevServerConfigurationOptions = { - contentBase: path.resolve(this.project.root, './src'), + contentBase: path.resolve(this.project.root, `./${CliConfig.fromProject().defaults.sourceDir}`), historyApiFallback: true, stats: webpackDevServerOutputOptions, inline: true, diff --git a/addon/ng2/tasks/test.js b/addon/ng2/tasks/test.ts similarity index 63% rename from addon/ng2/tasks/test.js rename to addon/ng2/tasks/test.ts index dcf28c2f7e55..fd8885e28b62 100644 --- a/addon/ng2/tasks/test.js +++ b/addon/ng2/tasks/test.ts @@ -1,25 +1,22 @@ -/* jshint node: true */ -'use strict'; - -var Promise = require('ember-cli/lib/ext/promise'); -var Task = require('ember-cli/lib/models/task'); -var path = require('path'); -var webpackTestConfig = require('../models/webpack-build-test').getWebpackTestConfig; +const Promise = require('ember-cli/lib/ext/promise'); +const Task = require('ember-cli/lib/models/task'); +const path = require('path'); +const webpackTestConfig = require('../models/webpack-build-test').getWebpackTestConfig; // require dependencies within the target project function requireDependency(root, moduleName) { - var packageJson = require(path.join(root, 'node_modules', moduleName, 'package.json')); - var main = path.normalize(packageJson.main); + 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({ +module.exports = Task.extend({ run: function (options) { - var projectRoot = this.project.root; + const projectRoot = this.project.root; return new Promise((resolve) => { - - var karma = requireDependency(projectRoot, 'karma'); - var karmaConfig = path.join(projectRoot, this.project.ngConfig.test.karma.config); + const karma = requireDependency(projectRoot, 'karma'); + const karmaConfig = path.join(projectRoot, this.project.ngConfig.test.karma.config); + const testFile = `./${this.project.ngConfig.defaults.sourceDir}/test.ts`; options.plugins = [ require('karma-webpack'), @@ -35,8 +32,8 @@ module.exports = Task.extend({ // Add those details here. // Single test entry file. Will run the test.ts bundle and track it. - options.files = [{ pattern: './src/test.ts', watched: false }]; - options.preprocessors = { './src/test.ts': ['webpack','sourcemap'] }; + options.files = [{ pattern: testFile, watched: false }]; + options.preprocessors = { [testFile]: ['webpack','sourcemap'] }; options.webpack = webpackTestConfig(projectRoot); options.webpackMiddleware = { noInfo: true, // Hide webpack output because its noisy. @@ -60,7 +57,7 @@ module.exports = Task.extend({ options.configFile = karmaConfig; // :shipit: - var karmaServer = new karma.Server(options, resolve); + const karmaServer = new karma.Server(options, resolve); karmaServer.start(); }); } From aef92b429603e2475b8dc5a4a1ed2f7119b30819 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Wed, 20 Jul 2016 01:59:25 +0100 Subject: [PATCH 20/38] chore(build): remove broccoli (#1386) --- lib/broccoli/angular-broccoli-bundle.js | 26 -- lib/broccoli/angular-broccoli-compass.js | 59 --- lib/broccoli/angular-broccoli-less.js | 54 --- lib/broccoli/angular-broccoli-sass.js | 74 ---- lib/broccoli/angular-broccoli-stylus.js | 57 --- lib/broccoli/angular2-app.js | 487 ----------------------- lib/broccoli/broccoli-handlebars.js | 38 -- lib/broccoli/broccoli-typescript.js | 472 ---------------------- lib/broccoli/environment.js | 28 -- lib/broccoli/is-production.js | 1 - lib/broccoli/require-or-null.js | 10 - lib/cli/index.js | 28 -- 12 files changed, 1334 deletions(-) delete mode 100644 lib/broccoli/angular-broccoli-bundle.js delete mode 100644 lib/broccoli/angular-broccoli-compass.js delete mode 100644 lib/broccoli/angular-broccoli-less.js delete mode 100644 lib/broccoli/angular-broccoli-sass.js delete mode 100644 lib/broccoli/angular-broccoli-stylus.js delete mode 100644 lib/broccoli/angular2-app.js delete mode 100644 lib/broccoli/broccoli-handlebars.js delete mode 100644 lib/broccoli/broccoli-typescript.js delete mode 100644 lib/broccoli/environment.js delete mode 100644 lib/broccoli/is-production.js delete mode 100644 lib/broccoli/require-or-null.js diff --git a/lib/broccoli/angular-broccoli-bundle.js b/lib/broccoli/angular-broccoli-bundle.js deleted file mode 100644 index b00b4426ebf6..000000000000 --- a/lib/broccoli/angular-broccoli-bundle.js +++ /dev/null @@ -1,26 +0,0 @@ -/* jshint node: true, esversion: 6 */ -'use strict'; - -const Plugin = require('broccoli-caching-writer'); -const Builder = require('systemjs-builder'); -const fse = require('fs-extra'); -const path = require('path'); - -class BundlePlugin extends Plugin { - constructor(inputNodes, options) { - super(inputNodes, {}); - options = options || {}; - this.options = options; - } - - build() { - var relativeRoot = path.relative(process.cwd(), this.inputPaths[0]); - var builder = new Builder(relativeRoot, `${relativeRoot}/system-config.js`); - - return builder.bundle('main', `${this.outputPath}/main.js`, { minify: true }) - .then(() => fse.copySync(`${this.inputPaths[0]}/system-config.js`, - `${this.outputPath}/system-config.js`)); - } -} - -module.exports = BundlePlugin; diff --git a/lib/broccoli/angular-broccoli-compass.js b/lib/broccoli/angular-broccoli-compass.js deleted file mode 100644 index f3ac76d37f89..000000000000 --- a/lib/broccoli/angular-broccoli-compass.js +++ /dev/null @@ -1,59 +0,0 @@ -/* jshint node: true, esversion: 6 */ -'use strict'; - -const requireOrNull = require('./require-or-null'); -const Plugin = require('broccoli-caching-writer'); -const fse = require('fs-extra'); -const path = require('path'); -const Funnel = require('broccoli-funnel'); - -let sass = requireOrNull('node-sass'); -let compass = requireOrNull('compass'); -if (!sass || !compass) { - sass = requireOrNull(`${process.env.PROJECT_ROOT}/node_modules/node-sass`); - compass = requireOrNull(`${process.env.PROJECT_ROOT}/node_modules/compass-importer`); -} - -class CompassPlugin extends Plugin { - constructor(inputNodes, options) { - super(inputNodes, {}); - - options = options || {}; - Plugin.call(this, inputNodes, { - cacheInclude: [/\.scss$/, /\.sass$/] - }); - this.options = options; - } - - build() { - this.listEntries().forEach(e => { - let fileName = path.resolve(e.basePath, e.relativePath); - this.compile(fileName, this.inputPaths[0], this.outputPath); - }); - } - - compile(fileName, inputPath, outputPath) { - let sassOptions = Object.assign(this.options, { - data: '@import "compass"; .transition { @include transition(all); }', - file: fileName, - includePaths: [inputPath].concat(this.options.inputPaths || []), - importer: compass - }); - - let result = sass.renderSync(sassOptions); - let filePath = fileName.replace(inputPath, outputPath).replace(/\.s[ac]ss$/, '.css'); - - fse.outputFileSync(filePath, result.css, 'utf8'); - } -} - -exports.makeBroccoliTree = (sourceDir, options) => { - if (sass && compass) { - let compassSrcTree = new Funnel(sourceDir, { - include: ['**/*.scss', '**/*.sass'], - allowEmpty: true - }); - - return new CompassPlugin([compassSrcTree], options); - } -}; diff --git a/lib/broccoli/angular-broccoli-less.js b/lib/broccoli/angular-broccoli-less.js deleted file mode 100644 index 1f2d928eab79..000000000000 --- a/lib/broccoli/angular-broccoli-less.js +++ /dev/null @@ -1,54 +0,0 @@ -/* jshint node: true, esversion: 6 */ -'use strict'; - -const requireOrNull = require('./require-or-null'); -const Plugin = require('broccoli-caching-writer'); -const fs = require('fs'); -const fse = require('fs-extra'); -const path = require('path'); -const Funnel = require('broccoli-funnel'); - -let less = requireOrNull('less'); -if (!less) { - less = requireOrNull(`${process.env.PROJECT_ROOT}/node_modules/less`); -} - -class LESSPlugin extends Plugin { - constructor(inputNodes, options) { - super(inputNodes, {}); - - options = options || {}; - Plugin.call(this, inputNodes, { - cacheInclude: [/\.less$/] - }); - this.options = options; - } - - build() { - return Promise.all(this.listEntries().map(e => { - let fileName = path.resolve(e.basePath, e.relativePath); - return this.compile(fileName, this.inputPaths[0], this.outputPath); - })); - } - - compile(fileName, inputPath, outputPath) { - let content = fs.readFileSync(fileName, 'utf8'); - - return less.render(content, this.options) - .then(output => { - let filePath = fileName.replace(inputPath, outputPath).replace(/\.less$/, '.css'); - fse.outputFileSync(filePath, output.css, 'utf8'); - }); - } -} - -exports.makeBroccoliTree = (sourceDir, options) => { - if (less) { - let lessSrcTree = new Funnel(sourceDir, { - include: ['**/*.less'], - allowEmpty: true - }); - - return new LESSPlugin([lessSrcTree], options); - } -}; diff --git a/lib/broccoli/angular-broccoli-sass.js b/lib/broccoli/angular-broccoli-sass.js deleted file mode 100644 index aca7d93aac20..000000000000 --- a/lib/broccoli/angular-broccoli-sass.js +++ /dev/null @@ -1,74 +0,0 @@ -/* jshint node: true, esversion: 6 */ -'use strict'; - -const requireOrNull = require('./require-or-null'); -const Plugin = require('broccoli-caching-writer'); -const fse = require('fs-extra'); -const path = require('path'); -const Funnel = require('broccoli-funnel'); - -let sass = requireOrNull('node-sass'); -if (!sass) { - sass = requireOrNull(`${process.env.PROJECT_ROOT}/node_modules/node-sass`); -} - -class SASSPlugin extends Plugin { - constructor(inputNodes, options) { - super(inputNodes, {}); - - options = options || {}; - Plugin.call(this, inputNodes, { - cacheInclude: options.cacheInclude || [/\.scss$/, /\.sass$/], - cacheExclude: options.cacheExclude || undefined - }); - this.options = options; - } - - build() { - this.listFiles().forEach(fileName => { - // We skip compiling partials (_*.scss files) - if(!/^_+.*.s[ac]ss$/.test(path.basename(fileName))) { - // Normalize is necessary for changing `\`s into `/`s on windows. - this.compile(path.normalize(fileName), - path.normalize(this.inputPaths[0]), - path.normalize(this.outputPath)); - } - }); - } - - compile(fileName, inputPath, outputPath) { - const outSourceName = fileName.replace(inputPath, outputPath); - const outFileName = outSourceName.replace(/\.s[ac]ss$/, '.css'); - - // We overwrite file, outFile and include the file path for the includePath. - // We also make sure the options don't include a data field. - const sassOptions = Object.assign(this.options, { - file: fileName, - outFile: outFileName, - includePaths: [inputPath].concat(this.options.includePaths || []) - }); - delete sassOptions.data; - - const result = sass.renderSync(sassOptions); - fse.outputFileSync(outFileName, result.css, 'utf-8'); - } -} - -exports.makeBroccoliTree = (sourceDir, options) => { - options = options || {}; - - // include sass support only if compass-importer is not installed - let compass = requireOrNull('compass-importer'); - if (!compass) { - compass = requireOrNull(`${process.env.PROJECT_ROOT}/node_modules/compass-importer`); - } - - if (sass && !compass) { - let sassSrcTree = new Funnel(sourceDir, { - include: ['**/*.sass', '**/*.scss'], - allowEmpty: true - }); - - return new SASSPlugin([sassSrcTree], options); - } -}; diff --git a/lib/broccoli/angular-broccoli-stylus.js b/lib/broccoli/angular-broccoli-stylus.js deleted file mode 100644 index f867eb19a9b5..000000000000 --- a/lib/broccoli/angular-broccoli-stylus.js +++ /dev/null @@ -1,57 +0,0 @@ -/* jshint node: true, esversion: 6 */ -'use strict'; - -const requireOrNull = require('./require-or-null'); -const Plugin = require('broccoli-caching-writer'); -const fs = require('fs'); -const fse = require('fs-extra'); -const path = require('path'); -const Funnel = require('broccoli-funnel'); - -let stylus = requireOrNull('stylus'); -if (!stylus) { - stylus = requireOrNull(`${process.env.PROJECT_ROOT}/node_modules/stylus`); -} - -class StylusPlugin extends Plugin { - constructor(inputNodes, options) { - super(inputNodes, {}); - - options = options || {}; - Plugin.call(this, inputNodes, { - cacheInclude: [/\.styl$/] - }); - this.options = options; - } - - build() { - return Promise.all(this.listEntries().map(e => { - let fileName = path.resolve(e.basePath, e.relativePath); - return this.compile(fileName, this.inputPaths[0], this.outputPath); - })); - } - - compile(fileName, inputPath, outputPath) { - let content = fs.readFileSync(fileName, 'utf8'); - - const options = Object.assign(this.options, { - filename: path.basename(fileName) - }); - - return stylus.render(content, options, function(err, css) { - let filePath = fileName.replace(inputPath, outputPath).replace(/\.styl$/, '.css'); - fse.outputFileSync(filePath, css, 'utf8'); - }); - } -} - -exports.makeBroccoliTree = (sourceDir, options) => { - if (stylus) { - let stylusSrcTree = new Funnel(sourceDir, { - include: ['**/*.styl'], - allowEmpty: true - }); - - return new StylusPlugin([stylusSrcTree], options); - } -}; diff --git a/lib/broccoli/angular2-app.js b/lib/broccoli/angular2-app.js deleted file mode 100644 index 487b9bbe4771..000000000000 --- a/lib/broccoli/angular2-app.js +++ /dev/null @@ -1,487 +0,0 @@ -'use strict'; -const path = require('path'); -const fs = require('fs'); - -const BroccoliPlugin = require('broccoli-writer'); -const BroccoliTypescript = require('./broccoli-typescript'); -const BundlePlugin = require('./angular-broccoli-bundle'); -const BroccoliFunnel = require('broccoli-funnel'); -const BroccoliMergeTrees = require('broccoli-merge-trees'); -const BroccoliSource = require('broccoli-source'); -const UnwatchedDir = BroccoliSource.UnwatchedDir; -const Project = require('ember-cli/lib/models/project'); -const HandlebarReplace = require('./broccoli-handlebars'); -const config = require('../../addon/ng2/models/config'); -const loadEnvironment = require('./environment'); -const concat = require('broccoli-concat'); -const uglify = require('broccoli-uglify-js'); - -class Angular2App extends BroccoliPlugin { - constructor(project, inputNode, options) { - super(); - this.ngConfig = config.CliConfig.fromProject(); - - if (!options) { - options = inputNode; - inputNode = null; - } - - options = options || {}; - - this._options = options; - this._sourceDir = options.sourceDir - || (this.ngConfig.defaults && this.ngConfig.defaults.sourceDir) - || 'src'; - this._options.polyfills = this._options.polyfills || [ - 'vendor/es6-shim/es6-shim.js', - 'vendor/reflect-metadata/Reflect.js', - 'vendor/systemjs/dist/system.src.js', - 'vendor/zone.js/dist/zone.js' - ]; - - this._destDir = options.destDir || ''; - - // By default, add all spec files to the tsCompiler. - this._tsCompiler = options.tsCompiler || { - additionalFiles: ['**/*.spec.ts'] - }; - - this._initProject(); - this._notifyAddonIncluded(); - this._inputNode = inputNode || this._buildInputTree(); - - this._tree = this._buildTree(); - } - - /** - * For compatibility with Ember addons - * @returns {*|{}} - */ - get options(){ - return this._options; - } - - /** - * For backward compatibility. - * @public - * @method toTree - * @return {BroccoliPlugin} A broccoli plugin. - */ - toTree() { - // eslint-disable-next-line no-console - console.warn('Angular2App is now a broccoli plugin. Calling toTree() is deprecated.'); - return this; - } - - /** - * @override - */ - read(readTree) { - return this._tree.read(readTree); - } - - /** - * @override - */ - cleanup() { - return this._tree.cleanup(); - } - - _buildInputTree() { - const inputTreeArray = [ - new BroccoliFunnel(this._sourceDir, { destDir: this._sourceDir }), - new BroccoliFunnel('typings', { destDir: 'typings' }), - this._getConfigTree() - ]; - - if (fs.existsSync('public')) { - inputTreeArray.push(new BroccoliFunnel('public', { destDir: 'public' })); - } - - if (fs.existsSync('icons')) { - inputTreeArray.push(new BroccoliFunnel('icons', { destDir: 'icons' })); - } - - return new BroccoliMergeTrees(inputTreeArray, { overwrite: true }); - } - - /** - * Create and return the app build system tree that: - * - Get the `assets` tree - * - Get the TS tree - * - Get the TS src tree - * - Get the index.html tree - * - Get the NPM modules tree - * - Apply/remove stuff based on the environment (dev|prod) - * - Return the app trees to be extended - * - * @private - * @method _buildTree - * @return {BroccoliFunnel} The app trees that can be used to extend the build. - */ - _buildTree() { - var assetTree = this._getAssetsTree(); - var tsTree = this._getTsTree(); - var indexTree = this._getIndexTree(); - var vendorNpmTree = this._getVendorNpmTree(); - - var buildTrees = [assetTree, tsTree, indexTree, vendorNpmTree]; - - // Add available and supported CSS plugins. - for (const suffix of ['sass', 'less', 'stylus', 'compass']) { - const plugin = require(`./angular-broccoli-${suffix}`); - const tree = plugin.makeBroccoliTree(this._inputNode, this._options[`${suffix}Compiler`]); - - if (!tree) { - continue; - } - - buildTrees.push(new BroccoliFunnel(tree, { - include: ['**/*'], - getDestinationPath: (n) => { - if (n.startsWith(this._sourceDir)) { - return n.substr(this._sourceDir.length); - } - return n; - } - })); - } - - var merged = new BroccoliMergeTrees(buildTrees, { overwrite: true }); - - if (this.ngConfig.apps[0].mobile) { - let AppShellPlugin = require('angular2-broccoli-prerender').AppShellPlugin; - merged = new BroccoliMergeTrees([merged, new AppShellPlugin(merged, 'index.html', 'main-app-shell')], { - overwrite: true - }); - } - - if (loadEnvironment(this.project).production) { - merged = this._getBundleTree(merged); - } - - // Public folder funnel - var publicFolder = new BroccoliFunnel(this._inputNode, { - allowEmpty: true, - srcDir: 'public', - name: 'PublicFolderFunnel' - }); - - merged = new BroccoliMergeTrees([merged, publicFolder]); - - return new BroccoliFunnel(merged, { - destDir: this._destDir, - overwrite: true - }); - } - - - /** - * @private - * @method _initProject - * @param {Object} options - */ - _initProject() { - this.project = Project.closestSync(process.cwd()); - - // project root dir env used on angular-cli side for including packages from project - process.env.PROJECT_ROOT = process.env.PROJECT_ROOT || this.project.root; - } - - /** - * @private - * @method _notifyAddonIncluded - */ - _notifyAddonIncluded() { - this.initializeAddons(); - this.project.addons = this.project.addons.filter(function (addon) { - addon.app = this; - - if (!addon.isEnabled || addon.isEnabled()) { - if (addon.included) { - addon.included(this); - } - - return addon; - } - }, this); - } - - /** - * Loads and initializes addons for this project. - * Calls initializeAddons on the Project. - * - * @private - * @method initializeAddons - */ - initializeAddons() { - this.project.initializeAddons(); - } - - /** - * Returns the content for a specific type (section) for index.html. - * - * Currently supported types: - * - 'head' - * //- 'config-module' - * //- 'app' - * //- 'head-footer' - * //- 'test-header-footer' - * //- 'body-footer' - * //- 'test-body-footer' - * - * Addons can also implement this method and could also define additional - * types (eg. 'some-addon-section'). - * - * @private - * @method _contentFor - * @param {RegExP} match Regular expression to match against - * @param {String} type Type of content - * @return {String} The content. - */ - _contentFor(match, type) { - var content = []; - - /*switch (type) { - case 'head': this._contentForHead(content, config); break; - case 'config-module': this._contentForConfigModule(content, config); break; - case 'app-boot': this._contentForAppBoot(content, config); break; - }*/ - content = this.project.addons.reduce(function (content, addon) { - var addonContent = addon.contentFor ? addon.contentFor(type) : null; - if (addonContent) { - return content.concat(addonContent); - } - - return content; - }, content); - - return content.join('\n'); - } - - /** - * Returns the tree for app/index.html. - * - * @private - * @method _getIndexTree - * @return {Tree} Tree for app/index.html. - */ - _getIndexTree() { - var files = [ - 'index.html' - ]; - var mobile; - - let indexTree = new BroccoliFunnel(this._inputNode, { - include: files.map(name => path.join(this._sourceDir, name)), - getDestinationPath: (n) => { - if (n.startsWith(this._sourceDir)) { - return n.substr(this._sourceDir.length); - } - return n; - } - }); - - if (this.ngConfig.apps[0].mobile) { - mobile = { - icons: [ - { rel: 'apple-touch-icon', href: '/icons/apple-touch-icon.png' }, - { rel: 'apple-touch-icon', sizes: '57x57', href: '/icons/apple-touch-icon-57x57.png' }, - { rel: 'apple-touch-icon', sizes: '60x60', href: '/icons/apple-touch-icon-60x60.png' }, - { rel: 'apple-touch-icon', sizes: '72x72', href: '/icons/apple-touch-icon-72x72.png' }, - { rel: 'apple-touch-icon', sizes: '76x76', href: '/icons/apple-touch-icon-76x76.png' }, - { rel: 'apple-touch-icon', sizes: '114x114', href: '/icons/apple-touch-icon-114x114.png' }, - { rel: 'apple-touch-icon', sizes: '120x120', href: '/icons/apple-touch-icon-120x120.png' }, - { rel: 'apple-touch-icon', sizes: '144x144', href: '/icons/apple-touch-icon-144x144.png' }, - { rel: 'apple-touch-icon', sizes: '152x152', href: '/icons/apple-touch-icon-152x152.png' }, - { rel: 'apple-touch-icon', sizes: '180x180', href: '/icons/apple-touch-icon-180x180.png' }, - { rel: 'apple-touch-startup-image', href: '/icons/apple-touch-icon-180x180.png' } - ] - } - } - - return new HandlebarReplace(indexTree, { - config: this.ngConfig, - environment: loadEnvironment(this.project), - scripts: { - polyfills: this._options.polyfills - }, - mobile: mobile - }, { - helpers: { - 'content-for': (name) => { - // TODO: remove content-for. - // eslint-disable-next-line no-console - console.warn('"{{content-for}}" has been deprecated and will be removed before RC.'); - return this._contentFor(null, name); - } - } - }); - } - - /** - * Returns the TS tree. - * - * @private - * @method _getTsTree - * @return {Tree} Tree for TypeScript files. - */ - _getTsTree() { - var tsConfigPath = path.join(this._sourceDir, 'tsconfig.json'); - var tsTree = new BroccoliTypescript(this._inputNode, tsConfigPath, this._tsCompiler); - - var tsTreeExcludes = ['*.d.ts', 'tsconfig.json']; - var excludeSpecFiles = '**/*.spec.*'; - - if (loadEnvironment(this.project).production) { - tsTreeExcludes.push(excludeSpecFiles); - } - - tsTree = new BroccoliFunnel(tsTree, { - srcDir: this._sourceDir, - exclude: tsTreeExcludes - }); - - return tsTree; - } - - - /** - * Returns the `vendorNpm` tree by merging the CLI dependencies plus the ones - * passed by the user. - * - * @private - * @method _getVendorNpmTree - * @return {Tree} The NPM tree. - */ - _getVendorNpmTree() { - var vendorNpmFiles = [ - ]; - - if (this.ngConfig.apps[0].mobile) { - vendorNpmFiles.push('@angular/service-worker/dist/worker.js') - } - - if (this._options.vendorNpmFiles) { - vendorNpmFiles = vendorNpmFiles.concat(this._options.vendorNpmFiles); - } - - return new BroccoliFunnel(new UnwatchedDir('node_modules'), { - include: vendorNpmFiles, - destDir: 'vendor', - name: 'vendor' - }); - } - - /** - * Returns the `assets` tree. - * - * @private - * @method _getAssetsTree - * @return {Tree} The assets tree. - */ - _getAssetsTree() { - return new BroccoliFunnel(this._inputNode, { - srcDir: this._sourceDir, - exclude: [ - '**/*.ts', - '**/*.scss', - '**/*.sass', - '**/*.less', - '**/*.styl', - '**/tsconfig.json' - ], - allowEmpty: true - }); - } - - /** - * Returns the config files tree. - * - * @private - * @method _getConfigTree - * @return {Tree} The config files tree. - */ - _getConfigTree() { - let env = process.env['EMBER_ENV'] || 'dev'; - - switch (env) { - case 'production': env = 'prod'; break; - case 'development': env = 'dev'; break; - } - - var envConfigFile = `environment.${env}.ts`; - - return new BroccoliFunnel('config', { - include: [envConfigFile], - destDir: `${this._sourceDir}/app`, - getDestinationPath: () => 'environment.ts' - }); - } - - _getBundleTree(preBundleTree){ - var vendorTree = this._getVendorNpmTree(); - var assetsTree = this._getAssetsTree(); - - var scriptTree = new BroccoliFunnel(preBundleTree, { - include: this._options.polyfills - }); - - var nonJsTree = new BroccoliFunnel(preBundleTree, { - exclude: ['**/*.js', '**/*.js.map'] - }); - var jsTree = new BroccoliFunnel(preBundleTree, { - include: ['**/*.js', '**/*.js.map'] - }); - - var bundleTree = new BundlePlugin([jsTree]); - - if (this.ngConfig.apps[0].mobile) { - bundleTree = concat(BroccoliMergeTrees([vendorTree, jsTree, scriptTree, bundleTree], { - overwrite: true - }), { - headerFiles: this._options.polyfills.concat([ - 'system-config.js', - 'main.js' - ]), - inputFiles: [ - 'system-import.js' - ], - header: ';(function() {', - footer: '}());', - sourceMapConfig: { enabled: true }, - allowNone: false, - outputFile: '/app-concat.js' - }); - - bundleTree = uglify(bundleTree, { - mangle: false - }); - - // Required here since the package isn't installed for non-mobile apps. - var ServiceWorkerPlugin = require('@angular/service-worker').ServiceWorkerPlugin; - // worker.js is needed so it can be copied to dist - var workerJsTree = new BroccoliFunnel(jsTree, { - include: ['vendor/@angular/service-worker/dist/worker.js'] - }); - /** - * ServiceWorkerPlugin will automatically pre-fetch and cache every file - * in the tree it receives, so it should only receive the app bundle, - * and non-JS static files from the app. The plugin also needs to have - * the worker.js file available so it can copy it to dist. - **/ - var swTree = new ServiceWorkerPlugin(BroccoliMergeTrees([ - bundleTree, - assetsTree, - workerJsTree - ])); - bundleTree = BroccoliMergeTrees([bundleTree, swTree], { - overwrite: true - }); - } - - return BroccoliMergeTrees([nonJsTree, scriptTree, bundleTree], { overwrite: true }); - } -} - -module.exports = Angular2App; diff --git a/lib/broccoli/broccoli-handlebars.js b/lib/broccoli/broccoli-handlebars.js deleted file mode 100644 index 269cfed8160c..000000000000 --- a/lib/broccoli/broccoli-handlebars.js +++ /dev/null @@ -1,38 +0,0 @@ -'use strict'; - -const fs = require('fs-extra'); -const path = require('path'); -const BroccoliCacheWriter = require('broccoli-caching-writer'); -const Handlebars = require('handlebars'); - - -class HandlebarReplace extends BroccoliCacheWriter { - constructor(inputTree, context, options) { - super([inputTree], options); - if (options && options.helpers) { - Object.keys(options.helpers).forEach((helperName) => { - Handlebars.registerHelper(helperName, function() { - const result = options.helpers[helperName].apply(null, arguments); - return new Handlebars.SafeString(result); - }); - }) - } - this._context = context; - } - - build() { - this.listFiles().forEach((filePath) => { - filePath = path.normalize(filePath); - const destPath = filePath.replace(this.inputPaths[0], this.outputPath); - const content = fs.readFileSync(filePath, 'utf-8'); - const template = Handlebars.compile(content); - - if (!fs.existsSync(path.dirname(destPath))) { - fs.mkdirsSync(path.dirname(destPath)); - } - fs.writeFileSync(destPath, template(this._context), 'utf-8'); - }); - } -} - -module.exports = HandlebarReplace; diff --git a/lib/broccoli/broccoli-typescript.js b/lib/broccoli/broccoli-typescript.js deleted file mode 100644 index 5d33086a063a..000000000000 --- a/lib/broccoli/broccoli-typescript.js +++ /dev/null @@ -1,472 +0,0 @@ -'use strict'; - -const Plugin = require('broccoli-caching-writer'); -const fs = require('fs'); -const fse = require('fs-extra'); -const path = require('path'); -const ts = require('typescript'); -const glob = require('glob'); - -const FS_OPTS = { - encoding: 'utf-8' -}; - - -/** - * Broccoli plugin that implements incremental Typescript compiler. - * - * It instantiates a typescript compiler instance that keeps all the state about the project and - * can re-emit only the files that actually changed. - * - * Limitations: only files that map directly to the changed source file via naming conventions are - * re-emitted. This primarily affects code that uses `const enum`s, because changing the enum value - * requires global emit, which can affect many files. - */ -class BroccoliTypeScriptCompiler extends Plugin { - constructor(inputPath, tsConfigPath, options) { - super([inputPath], {}); - - this._fileRegistry = Object.create(null); - this._rootFilePaths = []; - this._tsOpts = null; - this._tsServiceHost = null; - this._tsService = null; - - this._tsConfigPath = tsConfigPath; - this._options = options; - } - - build() { - if (!this._tsServiceHost) { - this._createServiceHost(); - } - this._doIncrementalBuild(); - } - - _doIncrementalBuild() { - var errorMessages = []; - var entries = this.listEntries(); - const inputPath = this.inputPaths[0]; - - const pathsToEmit = []; - - entries.forEach(entry => { - const tsFilePath = path.join(inputPath, entry.relativePath); - if (!tsFilePath.match(/\.ts$/) || !fs.existsSync(tsFilePath)) { - return; - } - // Remove d.ts files that aren't part of the tsconfig files. - if (tsFilePath.match(/\.d\.ts$/) && this._tsConfigFiles.indexOf(tsFilePath) == -1) { - return; - } - - if (!this._fileRegistry[tsFilePath]) { - // Not in the registry? Add it. - this._addNewFileEntry(entry); - - // We need to add the file to the rootFiles as well, as otherwise it _might_ - // not get compiled. It needs to be referenced at some point, and unless we - // add the spec files first (which we don't know the order), it won't. - // So make every new files an entry point instead. - // TODO(hansl): We need to investigate if we should emit files that are not - // referenced. This doesn't take that into account. - this._tsServiceHost.fileNames.push(tsFilePath); - - pathsToEmit.push(tsFilePath); - } else if (this._fileRegistry[tsFilePath].version >= entry.mtime) { - // Nothing to do for this file. Just link the cached outputs. - this._fileRegistry[tsFilePath].outputs.forEach(absoluteFilePath => { - const outputFilePath = absoluteFilePath.replace(this.cachePath, this.outputPath); - fse.mkdirsSync(path.dirname(outputFilePath)); - try { - fs.symlinkSync(absoluteFilePath, outputFilePath); - } catch (e) { - const contentStr = fs.readFileSync(absoluteFilePath); - fs.writeFileSync(outputFilePath, contentStr); - } - }); - } else { - this._fileRegistry[tsFilePath].version = entry.mtime; - pathsToEmit.push(tsFilePath); - } - }); - - if (pathsToEmit.length > 0) { - // Force the TS Service to recreate the program (ie. call synchronizeHostData). - this._tsServiceHost.projectVersion++; - - pathsToEmit.forEach(tsFilePath => { - var output = this._tsService.getEmitOutput(tsFilePath); - if (output.emitSkipped) { - const allDiagnostics = this._tsService.getCompilerOptionsDiagnostics() - .concat(this._tsService.getSyntacticDiagnostics(tsFilePath)) - .concat(this._tsService.getSemanticDiagnostics(tsFilePath)); - - const errors = this._collectErrors(allDiagnostics); - if (errors) { - // Rebuild it next incremental pass. - delete this._fileRegistry[tsFilePath]; - errorMessages.push(errors); - } - } else { - output.outputFiles.forEach(o => { - this._outputFile(o.name, o.text, this._fileRegistry[tsFilePath]); - }); - } - }); - } - - if (errorMessages.length) { - var error = new Error('Typescript found the following errors:\n' + errorMessages.join('\n')); - error['showStack'] = false; - throw error; - } - } - - _loadTsConfig() { - var tsConfigPath = path.join(this.inputPaths[0], this._tsConfigPath); - var tsconfig = JSON.parse(fs.readFileSync(tsConfigPath, 'utf-8')); - - tsconfig.files = (tsconfig.files || []) - .map(name => path.join(path.dirname(this._tsConfigPath), name)); - - // Add all glob files to files. In some cases we don't want to specify - let globFiles = this._options.additionalFiles; - if (globFiles) { - if (typeof globFiles == 'string') { - globFiles = [globFiles]; - } - - for (const g of globFiles) { - const files = glob(g, { sync: true, cwd: this.inputPaths[0], root: this.inputPaths[0] }); - tsconfig.files = tsconfig.files.concat(files); - } - } - - // Remove dupes in tsconfig.files. - const fileNameMap = {}; - tsconfig.files = tsconfig.files.filter(fileName => { - if (fileNameMap[fileName]) { - return false; - } - fileNameMap[fileName] = true; - return true; - }); - - // Because the tsconfig does not include the source directory, add this as the first path - // element. - tsconfig.files = tsconfig.files.map(name => path.join(this.inputPaths[0], name)); - return tsconfig; - } - - _createServiceHost() { - var tsconfig = this._loadTsConfig(); - - this._tsConfigFiles = tsconfig.files.splice(0); - - this._tsOpts = ts.convertCompilerOptionsFromJson(tsconfig['compilerOptions'], - this.inputPaths[0], this._tsConfigPath).options; - this._tsOpts.rootDir = ''; - this._tsOpts.outDir = ''; - - this._tsServiceHost = new CustomLanguageServiceHost( - this._tsOpts, this._rootFilePaths, this._fileRegistry, this.inputPaths[0], - tsconfig['compilerOptions'].paths, this._tsConfigPath); - this._tsService = ts.createLanguageService(this._tsServiceHost, ts.createDocumentRegistry()); - } - - _collectErrors(allDiagnostics) { - const errors = allDiagnostics.map(diagnostic => { - const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); - if (diagnostic.file) { - const position = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); - const line = position.line; - const character = position.character; - return ` ${diagnostic.file.fileName} (${line + 1}, ${character + 1}): ${message}`; - } else { - return ` Error: ${message}`; - } - }); - - if (errors.length) { - return errors.join('\n'); - } - } - - _outputFile(absoluteFilePath, fileContent, registry) { - absoluteFilePath = path.resolve(this.cachePath, absoluteFilePath); - let inputFilePath = absoluteFilePath; - // Replace the input path by the output. - absoluteFilePath = absoluteFilePath.replace(this.inputPaths[0], this.cachePath); - const outputFilePath = absoluteFilePath.replace(this.cachePath, this.outputPath); - - if (registry) { - registry.outputs.add(absoluteFilePath); - } - - fse.mkdirsSync(path.dirname(absoluteFilePath)); - const content = this.fixSourceMapSources(fileContent, inputFilePath); - fs.writeFileSync(absoluteFilePath, content, FS_OPTS); - - fse.mkdirsSync(path.dirname(outputFilePath)); - try { - fs.symlinkSync(absoluteFilePath, outputFilePath); - } catch (e) { - const contentStr = fs.readFileSync(absoluteFilePath); - fs.writeFileSync(outputFilePath, contentStr); - } - } - - _addNewFileEntry(entry, checkDuplicates /* = true */) { - if (checkDuplicates === undefined) { - checkDuplicates = true; - } - - const p = path.join(this.inputPaths[0], entry.relativePath); - if (checkDuplicates && this._fileRegistry[p]) { - throw `Trying to add a new entry to an already existing one: "${p}`; - } - - this._fileRegistry[p] = { - version: entry.mtime, - outputs: new Set() - }; - } - - /** - * There is a bug in TypeScript 1.6, where the sourceRoot and inlineSourceMap properties - * are exclusive. This means that the sources property always contains relative paths - * (e.g, ../../../../@angular/di/injector.ts). - * - * Here, we normalize the sources property and remove the ../../../ - * - * This issue is fixed in https://github.com/Microsoft/TypeScript/pull/5620. - * Once we switch to TypeScript 1.8, we can remove this method. - */ - fixSourceMapSources(content, inputFilePath) { - try { - const marker = '//# sourceMappingURL=data:application/json;base64,'; - - let index = content.indexOf(marker); - if (index == -1) { - const pathMarker = '//# sourceMappingURL='; - index = content.indexOf(pathMarker); - if (index == -1) { - return content; - } - - // We have a regular path, make it relative to the input path. - let base = content.substring(0, index + pathMarker.length); - let mapPath = content.substring(index + pathMarker.length); - if (mapPath.startsWith(this.outputPath)) { - mapPath = mapPath.replace(this.outputPath, this.inputPaths[0]); - } else if (!mapPath.startsWith(this.inputPaths[0])) { - mapPath = path.join(this.inputPaths[0], path.dirname(this._tsConfigPath), mapPath); - } - - mapPath = path.relative(path.dirname(inputFilePath), mapPath); - return '' + base + mapPath; - } - - var base = content.substring(0, index + marker.length); - var sourceMapBit = new Buffer(content.substring(index + marker.length), 'base64').toString('utf8'); - var sourceMaps = JSON.parse(sourceMapBit); - var source = sourceMaps.sources[0]; - sourceMaps.sources = [source.substring(source.lastIndexOf('../') + 3)]; - return '' + base + new Buffer(JSON.stringify(sourceMaps)).toString('base64'); - } catch (e) { - return content; - } - } -} - -class CustomLanguageServiceHost { - constructor(compilerOptions, fileNames, fileRegistry, treeInputPath, paths, tsConfigPath) { - this.compilerOptions = compilerOptions; - this.fileNames = fileNames; - this.fileRegistry = fileRegistry; - this.treeInputPath = treeInputPath; - this.currentDirectory = treeInputPath; - this.defaultLibFilePath = ts.getDefaultLibFilePath(compilerOptions).replace(/\\/g, '/'); - this.paths = paths; - this.tsConfigPath = tsConfigPath; - this.projectVersion = 0; - } - - getScriptFileNames() { - return this.fileNames; - } - - getScriptVersion(fileName) { - fileName = path.resolve(this.treeInputPath, fileName); - return this.fileRegistry[fileName] && this.fileRegistry[fileName].version.toString(); - } - - getProjectVersion() { - return this.projectVersion.toString(); - } - - /** - * Resolve a moduleName based on the path mapping defined in the tsconfig. - * @param moduleName The module name to resolve. - * @returns {string|boolean} A string that is the path of the module, if found, or a boolean - * indicating if resolution should continue with default. - * @private - */ - _resolveModulePathWithMapping(moduleName) { - // check if module name should be used as-is or it should be mapped to different value - let longestMatchedPrefixLength = 0; - let matchedPattern; - let matchedWildcard; - const paths = this.paths || {}; - - for (let pattern of Object.keys(paths)) { - if (pattern.indexOf('*') != pattern.lastIndexOf('*')) { - throw `Invalid path mapping pattern: "${pattern}"`; - } - - let indexOfWildcard = pattern.indexOf('*'); - if (indexOfWildcard !== -1) { - // check if module name starts with prefix, ends with suffix and these two don't overlap - let prefix = pattern.substr(0, indexOfWildcard); - let suffix = pattern.substr(indexOfWildcard + 1); - if (moduleName.length >= prefix.length + suffix.length && - moduleName.startsWith(prefix) && - moduleName.endsWith(suffix)) { - - // use length of matched prefix as betterness criteria - if (longestMatchedPrefixLength < prefix.length) { - longestMatchedPrefixLength = prefix.length; - matchedPattern = pattern; - matchedWildcard = moduleName.substr(prefix.length, moduleName.length - suffix.length); - } - } - } else { - // Pattern does not contain asterisk - module name should exactly match pattern to succeed. - if (pattern === moduleName) { - matchedPattern = pattern; - matchedWildcard = undefined; - break; - } - } - } - - if (!matchedPattern) { - // We fallback to the old module resolution. - return true; - } - - // some pattern was matched - module name needs to be substituted - let substitutions = this.paths[matchedPattern]; - for (let subst of substitutions) { - if (subst.indexOf('*') != subst.lastIndexOf('*')) { - throw `Invalid substitution: "${subst}" for pattern "${matchedPattern}".`; - } - if (subst == '*') { - // Trigger default module resolution. - return true; - } - // replace * in substitution with matched wildcard - let p = matchedWildcard ? subst.replace('*', matchedWildcard) : subst; - // if substituion is a relative path - combine it with baseUrl - p = path.isAbsolute(p) ? p : path.join(this.treeInputPath, path.dirname(this.tsConfigPath), p); - if (fs.existsSync(p)) { - return p; - } - } - - // This is an error; there was a match but no corresponding mapping was valid. - // Do not call the default module resolution. - return false; - } - - /** - * This method is called quite a bit to lookup 3 kinds of paths: - * 1/ files in the fileRegistry - * - these are the files in our project that we are watching for changes - * - in the future we could add caching for these files and invalidate the cache when - * the file is changed lazily during lookup - * 2/ .d.ts and library files not in the fileRegistry - * - these are not our files, they come from tsd or typescript itself - * - these files change only rarely but since we need them very rarely, it's not worth the - * cache invalidation hassle to cache them - * 3/ bogus paths that typescript compiler tries to lookup during import resolution - * - these paths are tricky to cache since files come and go and paths that was bogus in the - * past might not be bogus later - * - * In the initial experiments the impact of this caching was insignificant (single digit %) and - * not worth the potential issues with stale cache records. - */ - getScriptSnapshot(tsFilePath) { - var absoluteTsFilePath; - if (tsFilePath == this.defaultLibFilePath || path.isAbsolute(tsFilePath)) { - absoluteTsFilePath = tsFilePath; - } else if (this.compilerOptions.moduleResolution === 2 /* NodeJs */ && - tsFilePath.match(/^node_modules/)) { - absoluteTsFilePath = path.resolve(tsFilePath); - } else if (tsFilePath.match(/^rxjs/)) { - absoluteTsFilePath = path.resolve('node_modules', tsFilePath); - } else { - absoluteTsFilePath = path.join(this.treeInputPath, tsFilePath); - } - if (!fs.existsSync(absoluteTsFilePath)) { - // TypeScript seems to request lots of bogus paths during import path lookup and resolution, - // so we we just return undefined when the path is not correct. - return undefined; - } - - return ts.ScriptSnapshot.fromString(fs.readFileSync(absoluteTsFilePath, FS_OPTS)); - } - - resolveModuleNames(moduleNames, containingFile)/*: ResolvedModule[]*/ { - return moduleNames.map((moduleName) => { - let shouldResolveUsingDefaultMethod = false; - for (const ext of ['', '.ts', '.d.ts']) { - const name = `${moduleName}${ext}`; - const maybeModule = this._resolveModulePathWithMapping(name, containingFile); - if (typeof maybeModule == 'string') { - return { - resolvedFileName: maybeModule, - isExternalLibraryImport: false - }; - } else { - shouldResolveUsingDefaultMethod = shouldResolveUsingDefaultMethod || maybeModule; - } - } - - return shouldResolveUsingDefaultMethod && - ts.resolveModuleName(moduleName, containingFile, this.compilerOptions, { - fileExists(fileName) { - return fs.existsSync(fileName); - }, - readFile(fileName) { - return fs.readFileSync(fileName, 'utf-8'); - }, - directoryExists(directoryName) { - try { - const stats = fs.statSync(directoryName); - return stats && stats.isDirectory(); - } catch (e) { - return false; - } - } - }).resolvedModule; - }); - } - - getCurrentDirectory() { - return this.currentDirectory; - } - - getCompilationSettings() { - return this.compilerOptions; - } - - getDefaultLibFileName(/* options */) { - // ignore options argument, options should not change during the lifetime of the plugin - return this.defaultLibFilePath; - } -} - - -module.exports = BroccoliTypeScriptCompiler; diff --git a/lib/broccoli/environment.js b/lib/broccoli/environment.js deleted file mode 100644 index 269ce90e7fc4..000000000000 --- a/lib/broccoli/environment.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; -// Load the environment file defined by the EMBER_ENV environment variable. -const fs = require('fs'); -const path = require('path'); -const ts = require('typescript'); - - -// Export the content of the transpiled file. -module.exports = function loadEnvironment(project, environment) { - let env = environment || process.env['EMBER_ENV'] || 'dev'; - switch (env) { - case 'production': env = 'prod'; break; - case 'development': env = 'dev'; break; - } - - // Load the content of the environment file. - const filePath = path.join(project.root, `config/environment.${env}.ts`); - const source = fs.readFileSync(filePath, 'utf-8'); - const result = ts.transpile(source, { - target: ts.ScriptTarget.ES5, - module: ts.ModuleKind.CommonJs - }); - - const Module = module.constructor; - const m = new Module(); - m._compile(result, filePath); - return m.exports.environment; -}; diff --git a/lib/broccoli/is-production.js b/lib/broccoli/is-production.js deleted file mode 100644 index 64885fd576ae..000000000000 --- a/lib/broccoli/is-production.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = (/(^production$|^prod$)/).test(process.env.EMBER_ENV); diff --git a/lib/broccoli/require-or-null.js b/lib/broccoli/require-or-null.js deleted file mode 100644 index 9866bf69c91f..000000000000 --- a/lib/broccoli/require-or-null.js +++ /dev/null @@ -1,10 +0,0 @@ -/* jshint node: true, esversion: 6 */ -'use strict'; - -module.exports = function(name) { - try { - return require(name); - } catch (e) { - return null; - } -}; diff --git a/lib/cli/index.js b/lib/cli/index.js index bcf0fdd2c3c5..ca8598fc2ee5 100644 --- a/lib/cli/index.js +++ b/lib/cli/index.js @@ -35,34 +35,6 @@ require.extensions['.ts'] = function(m, filename) { }; -/** - * Monkey patch `ember-cli/lib/utilities/find-build-file` to find our build - * file when looking for `ember-cli-build.js`. This needs to be the first - * thing that happens before we `require()` any ember files. - * - * TODO: Remove this hack and replace it with some configuration when/if we - * move away from ember. Or when ember allows us to configure this in - * an addon. - */ -const findBuildFileRequirePath = 'ember-cli/lib/utilities/find-build-file'; -const originalFindBuildFile = require(findBuildFileRequirePath); - -const mod = require.cache[require.resolve(findBuildFileRequirePath)]; -mod.exports = function patchedFindBuildFile(name) { - if (name == 'ember-cli-build.js') { - const result = originalFindBuildFile.call(this, 'angular-cli-build.js'); - - // Fallback to ember-cli-build if angular-cli-build isn't found. - if (result) { - return result; - } - } - - return originalFindBuildFile.apply(this, arguments); -}; - - - const cli = require('ember-cli/lib/cli'); const path = require('path'); From 05b5ca3290acd3c873a96d30c3beab7acbae346c Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Wed, 20 Jul 2016 02:36:13 +0100 Subject: [PATCH 21/38] chore: remove windows elevation check (#1384) --- addon/ng2/commands/build.ts | 9 ++------- addon/ng2/commands/github-pages-deploy.ts | 4 +--- addon/ng2/commands/serve.ts | 6 +----- addon/ng2/commands/test.js | 23 ++++------------------- 4 files changed, 8 insertions(+), 34 deletions(-) diff --git a/addon/ng2/commands/build.ts b/addon/ng2/commands/build.ts index 9b99d6587ff9..1fe80828d0af 100644 --- a/addon/ng2/commands/build.ts +++ b/addon/ng2/commands/build.ts @@ -1,11 +1,6 @@ const Command = require('ember-cli/lib/models/command'); -const win = require('ember-cli/lib/utilities/windows-admin'); - -// const Build = require('../tasks/build'); -// const BuildWatch = require('../tasks/build-watch'); - -var WebpackBuild = require('../tasks/build-webpack'); -var WebpackBuildWatch = require('../tasks/build-webpack-watch'); +const WebpackBuild = require('../tasks/build-webpack'); +const WebpackBuildWatch = require('../tasks/build-webpack-watch'); interface BuildOptions { environment?: string; diff --git a/addon/ng2/commands/github-pages-deploy.ts b/addon/ng2/commands/github-pages-deploy.ts index 8ac1478c1e6f..5dae59a40af6 100644 --- a/addon/ng2/commands/github-pages-deploy.ts +++ b/addon/ng2/commands/github-pages-deploy.ts @@ -7,7 +7,6 @@ import * as fs from 'fs'; import * as fse from 'fs-extra'; import * as path from 'path'; import * as BuildTask from 'ember-cli/lib/tasks/build'; -import * as win from 'ember-cli/lib/utilities/windows-admin'; import * as CreateGithubRepo from '../tasks/create-github-repo'; const fsReadFile = Promise.denodeify(fs.readFile); @@ -117,8 +116,7 @@ module.exports = Command.extend({ function build() { if (options.skipBuild) return Promise.resolve(); - return win.checkWindowsElevation(ui) - .then(() => buildTask.run(buildOptions)); + return buildTask.run(buildOptions); } function saveStartingBranchName() { diff --git a/addon/ng2/commands/serve.ts b/addon/ng2/commands/serve.ts index dd86072e6025..396e167a56ce 100644 --- a/addon/ng2/commands/serve.ts +++ b/addon/ng2/commands/serve.ts @@ -3,10 +3,8 @@ const Command = require('ember-cli/lib/models/command'); const Promise = require('ember-cli/lib/ext/promise'); const SilentError = require('silent-error'); const PortFinder = require('portfinder'); -const win = require('ember-cli/lib/utilities/windows-admin'); const EOL = require('os').EOL; - PortFinder.basePort = 49152; const getPort = Promise.denodeify(PortFinder.getPort); @@ -81,9 +79,7 @@ module.exports = Command.extend({ project: this.project, }); - return win.checkWindowsElevation(this.ui).then(function() { - return serve.run(commandOptions); - }); + return serve.run(commandOptions); }); }, diff --git a/addon/ng2/commands/test.js b/addon/ng2/commands/test.js index c90bb83165d1..e94af33be298 100644 --- a/addon/ng2/commands/test.js +++ b/addon/ng2/commands/test.js @@ -1,12 +1,9 @@ 'use strict'; -var TestCommand = require('ember-cli/lib/commands/test'); -var win = require('ember-cli/lib/utilities/windows-admin'); - +const TestCommand = require('ember-cli/lib/commands/test'); const config = require('../models/config'); const TestTask = require('../tasks/test'); - module.exports = TestCommand.extend({ availableOptions: [ { name: 'watch', type: Boolean, default: true, aliases: ['w'] }, @@ -27,23 +24,11 @@ module.exports = TestCommand.extend({ project: this.project }); - if (commandOptions.watch) { - return win.checkWindowsElevation(this.ui) - .then( - () => { - }, - () => { - /* handle build error to allow watch mode to start */ - }) - .then(() => testTask.run(commandOptions)); - } else { + if (!commandOptions.watch) { // if not watching ensure karma is doing a single run commandOptions.singleRun = true; - return win.checkWindowsElevation(this.ui) - .then(() => { - return testTask.run(commandOptions); - }); - } + } + return testTask.run(commandOptions); } }); From 86c425c1c64468677a42edbadc7d76f3da2e6b25 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Wed, 20 Jul 2016 04:50:53 +0100 Subject: [PATCH 22/38] fix(test): add missing sourceDir (#1387) --- addon/ng2/models/webpack-build-mobile.ts | 2 +- addon/ng2/tasks/test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addon/ng2/models/webpack-build-mobile.ts b/addon/ng2/models/webpack-build-mobile.ts index 1480a4eebf37..0eb18933ddcb 100644 --- a/addon/ng2/models/webpack-build-mobile.ts +++ b/addon/ng2/models/webpack-build-mobile.ts @@ -21,7 +21,7 @@ export const getWebpackMobileConfigPartial = function (projectRoot: string, sour } }; -export const getWebpackMobileProdConfigPartial = function (projectRoot: string) { +export const getWebpackMobileProdConfigPartial = function (projectRoot: string, sourceDir: string) { return { entry: { 'sw-install': path.resolve(__dirname, '../utilities/sw-install.js') diff --git a/addon/ng2/tasks/test.ts b/addon/ng2/tasks/test.ts index fd8885e28b62..4a92a23eb577 100644 --- a/addon/ng2/tasks/test.ts +++ b/addon/ng2/tasks/test.ts @@ -34,7 +34,7 @@ module.exports = Task.extend({ // Single test entry file. Will run the test.ts bundle and track it. options.files = [{ pattern: testFile, watched: false }]; options.preprocessors = { [testFile]: ['webpack','sourcemap'] }; - options.webpack = webpackTestConfig(projectRoot); + options.webpack = webpackTestConfig(projectRoot, this.project.ngConfig.defaults.sourceDir); options.webpackMiddleware = { noInfo: true, // Hide webpack output because its noisy. stats: { // Also prevent chunk and module display output, cleaner look. Only emit errors. From 5b21617ac7ff590f5839c31e3eb1b0eae11f4f3e Mon Sep 17 00:00:00 2001 From: Sean Larkin Date: Wed, 20 Jul 2016 14:13:57 -0500 Subject: [PATCH 23/38] fix: update node polyfill support properties for prod config to allow dev-server (aka ng serve) (#1395) --- addon/ng2/models/webpack-build-production.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon/ng2/models/webpack-build-production.ts b/addon/ng2/models/webpack-build-production.ts index e5c53d5648e6..391f22805fb2 100644 --- a/addon/ng2/models/webpack-build-production.ts +++ b/addon/ng2/models/webpack-build-production.ts @@ -53,7 +53,7 @@ export const getWebpackProdConfigPartial = function(projectRoot: string, sourceD node: { global: 'window', crypto: 'empty', - process: false, + process: true, module: false, clearImmediate: false, setImmediate: false From e6bdf505a006bae658614b16318d3e89da568279 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Wed, 20 Jul 2016 20:41:37 +0100 Subject: [PATCH 24/38] chore(tests): add prod env e2e test (#1394) --- tests/e2e/e2e_workflow.spec.js | 84 +++++++++++++++++----------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/tests/e2e/e2e_workflow.spec.js b/tests/e2e/e2e_workflow.spec.js index b4a6b984e054..fec4b87a6ffa 100644 --- a/tests/e2e/e2e_workflow.spec.js +++ b/tests/e2e/e2e_workflow.spec.js @@ -177,47 +177,6 @@ describe('Basic end-to-end Workflow', function () { }); }); - it('Serve and run e2e tests after initial build', function () { - this.timeout(240000); - - var ngServePid; - - function executor(resolve, reject) { - var serveProcess = child_process.exec(`${ngBin} serve`, { maxBuffer: 500*1024 }); - var startedProtractor = false; - ngServePid = serveProcess.pid; - - serveProcess.stdout.on('data', (data) => { - if (/webpack: bundle is now VALID/.test(data.toString('utf-8')) && !startedProtractor) { - startedProtractor = true; - child_process.exec(`${ngBin} e2e`, (error, stdout, stderr) => { - if (error !== null) { - reject(stderr) - } else { - resolve(); - } - }); - } - }); - - serveProcess.stderr.on('data', (data) => { - reject(data); - }); - serveProcess.on('close', (code) => { - code === 0 ? resolve() : reject('ng serve command closed with error') - }); - } - - return new Promise(executor) - .then(() => { - if (ngServePid) treeKill(ngServePid); - }) - .catch((msg) => { - if (ngServePid) treeKill(ngServePid); - throw new Error(msg); - }); - }); - it('Can create a test component using `ng generate component test-component`', function () { this.timeout(10000); return ng(['generate', 'component', 'test-component']).then(function () { @@ -453,7 +412,7 @@ describe('Basic end-to-end Workflow', function () { expect(indexHtml).to.include('main.bundle.js'); }); - it('Serve and run e2e tests after all other commands', function () { + it('Serve and run e2e tests on dev environment', function () { this.timeout(240000); var ngServePid; @@ -493,6 +452,47 @@ describe('Basic end-to-end Workflow', function () { throw new Error(msg); }); }); + + it('Serve and run e2e tests on prod environment', function () { + this.timeout(240000); + + var ngServePid; + + function executor(resolve, reject) { + var serveProcess = child_process.exec(`${ngBin} serve -e=prod`, { maxBuffer: 500*1024 }); + var startedProtractor = false; + ngServePid = serveProcess.pid; + + serveProcess.stdout.on('data', (data) => { + if (/webpack: bundle is now VALID/.test(data.toString('utf-8')) && !startedProtractor) { + startedProtractor = true; + child_process.exec(`${ngBin} e2e`, (error, stdout, stderr) => { + if (error !== null) { + reject(stderr) + } else { + resolve(); + } + }); + } + }); + + serveProcess.stderr.on('data', (data) => { + reject(data); + }); + serveProcess.on('close', (code) => { + code === 0 ? resolve() : reject('ng serve command closed with error') + }); + } + + return new Promise(executor) + .then(() => { + if (ngServePid) treeKill(ngServePid); + }) + .catch((msg) => { + if (ngServePid) treeKill(ngServePid); + throw new Error(msg); + }); + }); }); function isMobileTest() { From 1a68ce6cfb8e0b731cac14fe0b2ad73561652c8b Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Wed, 20 Jul 2016 21:55:53 +0100 Subject: [PATCH 25/38] chore: cleanup of new files (#1388) --- addon/ng2/blueprints/ng2/files/README.md | 2 +- .../__path__/app/environments/environment.ts | 2 +- .../ng2/files/__path__/tsconfig.json | 6 +- .../blueprints/ng2/files/e2e/tsconfig.json | 3 - addon/ng2/commands/build.ts | 6 +- addon/ng2/commands/serve.ts | 16 ++--- addon/ng2/commands/{test.js => test.ts} | 10 ++- addon/ng2/models/config.ts | 1 - addon/ng2/models/webpack-build-common.ts | 11 ++-- addon/ng2/models/webpack-build-production.ts | 13 ++-- addon/ng2/models/webpack-build-test.ts | 3 +- addon/ng2/models/webpack-build-utils.ts | 2 +- addon/ng2/models/webpack-config.ts | 7 +- addon/ng2/tasks/build-watch.ts | 30 --------- addon/ng2/tasks/build.ts | 55 ---------------- addon/ng2/tasks/serve-webpack.ts | 32 ++++------ addon/ng2/tasks/serve.ts | 64 ------------------- addon/ng2/tasks/test.ts | 10 +-- addon/ng2/utilities/sw-install.js | 2 + 19 files changed, 54 insertions(+), 221 deletions(-) rename addon/ng2/commands/{test.js => test.ts} (83%) delete mode 100644 addon/ng2/tasks/build-watch.ts delete mode 100644 addon/ng2/tasks/build.ts delete mode 100644 addon/ng2/tasks/serve.ts diff --git a/addon/ng2/blueprints/ng2/files/README.md b/addon/ng2/blueprints/ng2/files/README.md index 33838bbe3127..79c75dd19e76 100755 --- a/addon/ng2/blueprints/ng2/files/README.md +++ b/addon/ng2/blueprints/ng2/files/README.md @@ -7,7 +7,7 @@ Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app w ## Code scaffolding -Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/route/class`. +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class`. ## Build diff --git a/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.ts b/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.ts index 79ee96fdfdbd..e63359828bb1 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.ts @@ -1,5 +1,5 @@ // The file for the current environment will overwrite this one during build -// Different environments can be found in config/environment.{dev|prod}.ts +// Different environments can be found in ./environment.{dev|prod}.ts // The build system defaults to the dev environment export const environment = { diff --git a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json index 5acc3c417061..538b19d67754 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json @@ -4,13 +4,11 @@ "declaration": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, + "mapRoot": "./", "module": "es6", "moduleResolution": "node", - "outDir": "./dist/", - "rootDir": ".", "sourceMap": true, - "target": "es5", - "mapRoot": "/" + "target": "es5" }, "compileOnSave": false, "buildOnSave": false, diff --git a/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json b/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json index 93a6038f60b4..eb5d88ecd0bc 100644 --- a/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json @@ -6,9 +6,6 @@ "experimentalDecorators": true, "module": "commonjs", "moduleResolution": "node", - "noEmitOnError": true, - "noImplicitAny": false, - "rootDir": ".", "sourceMap": true, "target": "es5" } diff --git a/addon/ng2/commands/build.ts b/addon/ng2/commands/build.ts index 1fe80828d0af..d564de57362b 100644 --- a/addon/ng2/commands/build.ts +++ b/addon/ng2/commands/build.ts @@ -1,6 +1,6 @@ -const Command = require('ember-cli/lib/models/command'); -const WebpackBuild = require('../tasks/build-webpack'); -const WebpackBuildWatch = require('../tasks/build-webpack-watch'); +import * as Command from 'ember-cli/lib/models/command'; +import * as WebpackBuild from '../tasks/build-webpack'; +import * as WebpackBuildWatch from '../tasks/build-webpack-watch'; interface BuildOptions { environment?: string; diff --git a/addon/ng2/commands/serve.ts b/addon/ng2/commands/serve.ts index 396e167a56ce..b800af766f3f 100644 --- a/addon/ng2/commands/serve.ts +++ b/addon/ng2/commands/serve.ts @@ -1,9 +1,10 @@ -const assign = require('lodash/assign'); -const Command = require('ember-cli/lib/models/command'); -const Promise = require('ember-cli/lib/ext/promise'); -const SilentError = require('silent-error'); -const PortFinder = require('portfinder'); -const EOL = require('os').EOL; +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 EOL from 'os'; +import * as ServeWebpackTask from '../tasks/serve-webpack.ts'; PortFinder.basePort = 49152; @@ -53,7 +54,6 @@ module.exports = Command.extend({ run: function(commandOptions: ServeTaskOptions) { - commandOptions.liveReloadHost = commandOptions.liveReloadHost || commandOptions.host; return this._checkExpressPort(commandOptions) @@ -71,8 +71,6 @@ module.exports = Command.extend({ } } - const ServeWebpackTask = (require('../tasks/serve-webpack.ts')) - var serve = new ServeWebpackTask({ ui: this.ui, analytics: this.analytics, diff --git a/addon/ng2/commands/test.js b/addon/ng2/commands/test.ts similarity index 83% rename from addon/ng2/commands/test.js rename to addon/ng2/commands/test.ts index e94af33be298..5d62c7ba486f 100644 --- a/addon/ng2/commands/test.js +++ b/addon/ng2/commands/test.ts @@ -1,8 +1,6 @@ -'use strict'; - -const TestCommand = require('ember-cli/lib/commands/test'); -const config = require('../models/config'); -const TestTask = require('../tasks/test'); +import * as TestCommand from 'ember-cli/lib/commands/test'; +import * as config from '../models/config'; +import * as TestTask from '../tasks/test'; module.exports = TestCommand.extend({ availableOptions: [ @@ -27,7 +25,7 @@ module.exports = TestCommand.extend({ if (!commandOptions.watch) { // if not watching ensure karma is doing a single run commandOptions.singleRun = true; - } + } return testTask.run(commandOptions); } }); diff --git a/addon/ng2/models/config.ts b/addon/ng2/models/config.ts index e37ea8b760ef..8b41a2e2dc49 100644 --- a/addon/ng2/models/config.ts +++ b/addon/ng2/models/config.ts @@ -7,7 +7,6 @@ const schema = require(schemaPath); export const CLI_CONFIG_FILE_NAME = 'angular-cli.json'; export const ARRAY_METHODS = ['push', 'splice', 'sort', 'reverse', 'pop', 'shift']; - function _findUp(name: string, from: string) { let currentDir = from; while (currentDir && currentDir !== path.parse(currentDir).root) { diff --git a/addon/ng2/models/webpack-build-common.ts b/addon/ng2/models/webpack-build-common.ts index 4d3e5ca27513..dd184195cac1 100644 --- a/addon/ng2/models/webpack-build-common.ts +++ b/addon/ng2/models/webpack-build-common.ts @@ -1,12 +1,11 @@ +import * as path from 'path'; +import * as CopyWebpackPlugin from 'copy-webpack-plugin'; +import * as HtmlWebpackPlugin from 'html-webpack-plugin'; import * as webpack from 'webpack'; -import {LoaderConfig, PathsPlugin} from '../utilities/ts-path-mappings-webpack-plugin'; +import { ForkCheckerPlugin } from 'awesome-typescript-loader'; +import { LoaderConfig, PathsPlugin } from '../utilities/ts-path-mappings-webpack-plugin'; import { CliConfig } from './config'; -const path = require('path'); -const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin; -const CopyWebpackPlugin = require('copy-webpack-plugin'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); - export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) { const awesomeTypescriptLoaderConfig: LoaderConfig | any = { useWebpackText: true, diff --git a/addon/ng2/models/webpack-build-production.ts b/addon/ng2/models/webpack-build-production.ts index 391f22805fb2..af0bfe8bb055 100644 --- a/addon/ng2/models/webpack-build-production.ts +++ b/addon/ng2/models/webpack-build-production.ts @@ -1,11 +1,10 @@ +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'; import { CliConfig } from './config'; -const path = require('path'); -const webpackMerge = require('webpack-merge'); // used to merge webpack configs -const WebpackMd5Hash = require('webpack-md5-hash'); -const CompressionPlugin = require("compression-webpack-plugin"); - export const getWebpackProdConfigPartial = function(projectRoot: string, sourceDir: string) { return { debug: false, @@ -27,8 +26,8 @@ export const getWebpackProdConfigPartial = function(projectRoot: string, sourceD comments: false //prod }), new CompressionPlugin({ - asset: "[path].gz[query]", - algorithm: "gzip", + asset: '[path].gz[query]', + algorithm: 'gzip', test: /\.js$|\.html$/, threshold: 10240, minRatio: 0.8 diff --git a/addon/ng2/models/webpack-build-test.ts b/addon/ng2/models/webpack-build-test.ts index 42ee2bf45dbc..7c63e6e2299a 100644 --- a/addon/ng2/models/webpack-build-test.ts +++ b/addon/ng2/models/webpack-build-test.ts @@ -1,8 +1,7 @@ import * as webpack from 'webpack'; +import * as path from 'path'; import { CliConfig } from './config'; -const path = require('path'); - export const getWebpackTestConfig = function(projectRoot: string, sourceDir: string) { return { devtool: 'inline-source-map', diff --git a/addon/ng2/models/webpack-build-utils.ts b/addon/ng2/models/webpack-build-utils.ts index 572567d1e638..dcaa15558593 100644 --- a/addon/ng2/models/webpack-build-utils.ts +++ b/addon/ng2/models/webpack-build-utils.ts @@ -1,4 +1,4 @@ -const path = require('path'); +import * as path from 'path'; export const ngAppResolve = (resolvePath: string): string => { return path.resolve(process.cwd(), resolvePath); diff --git a/addon/ng2/models/webpack-config.ts b/addon/ng2/models/webpack-config.ts index 5dc9541bb333..f4d9beeedf6a 100644 --- a/addon/ng2/models/webpack-config.ts +++ b/addon/ng2/models/webpack-config.ts @@ -1,3 +1,5 @@ +import * as path from 'path'; +import * as webpackMerge from 'webpack-merge'; import { CliConfig } from './config'; import { NgCliEnvironmentPlugin } from '../utilities/environment-plugin'; import { @@ -8,9 +10,6 @@ import { getWebpackMobileProdConfigPartial } from './'; -const webpackMerge = require('webpack-merge'); -const path = require('path'); - 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 @@ -58,7 +57,7 @@ export class NgCliWebpackConfig { default: //TODO: Not sure what to put here. We have a default env passed anyways. - this.ngCliProject.ui.writeLine("Envrionment could not be determined while configuring your build system.", 3) + this.ngCliProject.ui.writeLine("Environment could not be determined while configuring your build system.", 3) break; } } diff --git a/addon/ng2/tasks/build-watch.ts b/addon/ng2/tasks/build-watch.ts deleted file mode 100644 index d816d47a3fe2..000000000000 --- a/addon/ng2/tasks/build-watch.ts +++ /dev/null @@ -1,30 +0,0 @@ -const chalk = require('chalk'); -const Task = require('ember-cli/lib/models/task'); -const Watcher = require('ember-cli/lib/models/watcher'); -const Promise = require('ember-cli/lib/ext/promise'); - -const Builder = require('../models/builder'); - - -module.exports = Task.extend({ - run: function(options) { - console.log(2); - this.ui.startProgress( - chalk.green('Building'), chalk.green('.') - ); - - return new Watcher({ - ui: this.ui, - builder: new Builder({ - ui: this.ui, - outputPath: options.outputPath, - environment: options.environment, - project: this.project - }), - analytics: this.analytics, - options: options - }).then(function() { - return new Promise(function () {}); // Run until failure or signal to exit - }); - } -}); diff --git a/addon/ng2/tasks/build.ts b/addon/ng2/tasks/build.ts deleted file mode 100644 index 8af2961d35b3..000000000000 --- a/addon/ng2/tasks/build.ts +++ /dev/null @@ -1,55 +0,0 @@ -const chalk = require('chalk'); -const Task = require('ember-cli/lib/models/task'); - -const Builder = require('../models/builder'); - - -module.exports = Task.extend({ - // Options: String outputPath - run: function(options) { - var ui = this.ui; - var analytics = this.analytics; - - ui.startProgress(chalk.green('Building'), chalk.green('.')); - - var builder = new Builder({ - ui: ui, - outputPath: options.outputPath, - environment: options.environment, - project: this.project - }); - - return builder.build() - .then(function(results) { - if (!results) { - return; - } - var totalTime = results.totalTime / 1e6; - - analytics.track({ - name: 'ember build', - message: totalTime + 'ms' - }); - - analytics.trackTiming({ - category: 'rebuild', - variable: 'build time', - label: 'broccoli build time', - value: parseInt(totalTime, 10) - }); - }) - .finally(function() { - ui.stopProgress(); - return builder.cleanup(); - }) - .then(function() { - ui.writeLine(chalk.green('Built project successfully. Stored in "' + - options.outputPath + '".')); - }) - .catch(function(err) { - ui.writeLine(chalk.red('Build failed.')); - - throw err; - }); - } -}); diff --git a/addon/ng2/tasks/serve-webpack.ts b/addon/ng2/tasks/serve-webpack.ts index 176af5388902..277047af405a 100644 --- a/addon/ng2/tasks/serve-webpack.ts +++ b/addon/ng2/tasks/serve-webpack.ts @@ -1,24 +1,18 @@ -import {webpackDevServerOutputOptions} from '../models/'; -import {NgCliWebpackConfig} from '../models/webpack-config'; -import {ServeTaskOptions} from '../commands/serve'; +import * as path from 'path'; +import * as chalk from 'chalk'; +import * as Task from 'ember-cli/lib/models/task'; +import * as webpack from 'webpack'; +import * as WebpackDevServer from 'webpack-dev-server'; +import * as ProgressPlugin from 'webpack/lib/ProgressPlugin'; +import { webpackDevServerOutputOptions } from '../models/'; +import { NgCliWebpackConfig } from '../models/webpack-config'; +import { ServeTaskOptions } from '../commands/serve'; import { CliConfig } from '../models/config'; -const path = require('path'); -const chalk = require('chalk'); - - -const Task = require('ember-cli/lib/models/task'); -const webpack = require('webpack'); -const WebpackDevServer = require('webpack-dev-server'); -const ProgressPlugin = require('webpack/lib/ProgressPlugin'); - - - -let lastHash = null; - module.exports = Task.extend({ run: function(commandOptions: ServeTaskOptions) { - + + let lastHash = null; let webpackCompiler: any; var config: NgCliWebpackConfig = new NgCliWebpackConfig(this.project, commandOptions.environment).config; @@ -44,7 +38,7 @@ module.exports = Task.extend({ const server = new WebpackDevServer(webpackCompiler, webpackDevServerConfiguration); return new Promise((resolve, reject) => { - server.listen(commandOptions.port, "localhost", function(err, stats) { + server.listen(commandOptions.port, 'localhost', function(err, stats) { if(err) { lastHash = null; console.error(err.stack || err); @@ -54,7 +48,7 @@ module.exports = Task.extend({ if(stats && stats.hash && stats.hash !== lastHash) { lastHash = stats.hash; - process.stdout.write(stats.toString(webpackOutputOptions) + "\n" + serveMessage + "\n"); + process.stdout.write(stats.toString(webpackOutputOptions) + '\n' + serveMessage + '\n'); } process.stdout.write(serveMessage); diff --git a/addon/ng2/tasks/serve.ts b/addon/ng2/tasks/serve.ts deleted file mode 100644 index b283942396fc..000000000000 --- a/addon/ng2/tasks/serve.ts +++ /dev/null @@ -1,64 +0,0 @@ -'use strict'; - -var existsSync = require('exists-sync'); -var path = require('path'); -var LiveReloadServer = require('ember-cli/lib/tasks/server/livereload-server'); -var ExpressServer = require('ember-cli/lib/tasks/server/express-server'); -var Promise = require('ember-cli/lib/ext/promise'); -var Task = require('ember-cli/lib/models/task'); -var Watcher = require('ember-cli/lib/models/watcher'); -var Builder = require('../models/builder'); -var ServerWatcher = require('ember-cli/lib/models/server-watcher'); - -module.exports = Task.extend({ - run: function(options) { - var builder = new Builder({ - ui: this.ui, - outputPath: options.outputPath, - project: this.project, - environment: options.environment - }); - - var watcher = new Watcher({ - ui: this.ui, - builder: builder, - analytics: this.analytics, - options: options - }); - - var serverRoot = './server'; - var serverWatcher = null; - if (existsSync(serverRoot)) { - serverWatcher = new ServerWatcher({ - ui: this.ui, - analytics: this.analytics, - watchedDir: path.resolve(serverRoot) - }); - } - - var expressServer = new ExpressServer({ - ui: this.ui, - project: this.project, - watcher: watcher, - serverRoot: serverRoot, - serverWatcher: serverWatcher - }); - - var liveReloadServer = new LiveReloadServer({ - ui: this.ui, - analytics: this.analytics, - project: this.project, - watcher: watcher, - expressServer: expressServer - }); - - return Promise.all([ - liveReloadServer.start(options), - expressServer.start(options) - ]).then(function() { - return new Promise(function() { - // hang until the user exits. - }); - }); - } -}); diff --git a/addon/ng2/tasks/test.ts b/addon/ng2/tasks/test.ts index 4a92a23eb577..8ef8268f9b15 100644 --- a/addon/ng2/tasks/test.ts +++ b/addon/ng2/tasks/test.ts @@ -1,7 +1,7 @@ -const Promise = require('ember-cli/lib/ext/promise'); -const Task = require('ember-cli/lib/models/task'); -const path = require('path'); -const webpackTestConfig = require('../models/webpack-build-test').getWebpackTestConfig; +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) { @@ -34,7 +34,7 @@ module.exports = Task.extend({ // Single test entry file. Will run the test.ts bundle and track it. options.files = [{ pattern: testFile, watched: false }]; options.preprocessors = { [testFile]: ['webpack','sourcemap'] }; - options.webpack = webpackTestConfig(projectRoot, this.project.ngConfig.defaults.sourceDir); + options.webpack = getWebpackTestConfig(projectRoot, this.project.ngConfig.defaults.sourceDir); options.webpackMiddleware = { noInfo: true, // Hide webpack output because its noisy. stats: { // Also prevent chunk and module display output, cleaner look. Only emit errors. diff --git a/addon/ng2/utilities/sw-install.js b/addon/ng2/utilities/sw-install.js index d2e341852813..eadc268397fc 100644 --- a/addon/ng2/utilities/sw-install.js +++ b/addon/ng2/utilities/sw-install.js @@ -1 +1,3 @@ +// this file is used in ../models/webpack-build-mobile.ts to add +// service worker functionality to mobile projects require('offline-plugin/runtime').install(); \ No newline at end of file From 4cfc4638a2df759360db97d9dd9e74e03b738d78 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Thu, 21 Jul 2016 03:52:27 +0100 Subject: [PATCH 26/38] fix(serve): disable HMR (#1402) --- addon/ng2/tasks/serve-webpack.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addon/ng2/tasks/serve-webpack.ts b/addon/ng2/tasks/serve-webpack.ts index 277047af405a..f76e8acda18f 100644 --- a/addon/ng2/tasks/serve-webpack.ts +++ b/addon/ng2/tasks/serve-webpack.ts @@ -30,8 +30,7 @@ module.exports = Task.extend({ contentBase: path.resolve(this.project.root, `./${CliConfig.fromProject().defaults.sourceDir}`), historyApiFallback: true, stats: webpackDevServerOutputOptions, - inline: true, - hot: true + inline: true }; const serveMessage:string = chalk.green(`\n*\n*\n NG Live Development Server is running on http://localhost:${commandOptions.port}.\n*\n*`); From 698ba0c7c03be30d788b47d312e859bffe80bf54 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 22 Jul 2016 00:09:43 +0100 Subject: [PATCH 27/38] chore: review docs (#1407) --- README.md | 52 +++++++++++++++------ addon/ng2/blueprints/ng2/files/package.json | 3 +- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 2deb864fa7b2..fe4b2148d8bf 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,7 @@ If you wish to collaborate while the project is still young, check out [our issu ## Prerequisites -The generated project has dependencies that require -* **Node 4 or greater**. -* **Typings v1 or greater**. +The generated project has dependencies that require **Node 4 or greater**. ## Table of Contents @@ -154,13 +152,7 @@ all dependencies into a single file, and make use of tree-shaking techniques. ng test ``` -Tests will execute after a build is executed via [Karma](http://karma-runner.github.io/0.13/index.html), and it will automatically watch your files for changes. - -You can run tests a single time via `--watch=false`, and turn off building of the app via `--build=false` (useful for running it at the same time as `ng serve`). - -**WARNING:** On Windows, `ng test` is hitting a file descriptor limit (see https://github.com/angular/angular-cli/issues/977). -The solution for now is to instead run `ng serve` and `ng test --build=false` in separate console windows. - +Tests will execute after a build is executed via [Karma](http://karma-runner.github.io/0.13/index.html), and it will automatically watch your files for changes. You can run tests a single time via `--watch=false`. ### Running end-to-end tests @@ -214,7 +206,7 @@ You can modify the these scripts in `package.json` to run whatever tool you pref ### Support for offline applications -The index.html file includes a commented-out code snippet for installing the angular2-service-worker. This support is experimental, please see the angular/mobile-toolkit project and https://mobile.angular.io/ for documentation on how to make use of this functionality. +Angular-CLI includes support for offline applications via the `--mobile` flag on `ng new`. Support is experimental, please see the angular/mobile-toolkit project and https://mobile.angular.io/ for documentation on how to make use of this functionality. ### Commands autocompletion @@ -241,19 +233,47 @@ source ~/.bash_profile ### CSS Preprocessor integration -We support all major CSS preprocessors: +Angular-CLI supports all major CSS preprocessors: - sass (node-sass) - less (less) - compass (compass-importer + node-sass) - stylus (stylus) -To use one just install for example `npm install node-sass` and rename `.css` files in your project to `.scss` or `.sass`. They will be compiled automatically. +To use these prepocessors simply add the file to your component's `styreUrl`: + +``` +@Component({ + moduleId: module.id, + selector: 'app-root', + templateUrl: 'app.component.html', + styleUrls: ['app.component.scss'] +}) +export class AppComponent { + title = 'app works!'; +} +``` + +When generating a new project you can also define which extention you want for +style files: + +```bash +ng new sassy-project --style=sass -The `Angular2App`'s options argument has `sassCompiler`, `lessCompiler`, `stylusCompiler` and `compassCompiler` options that are passed directly to their respective CSS preprocessors. +``` ### 3rd Party Library Installation -The installation of 3rd party libraries are well described at our [Wiki Page](https://github.com/angular/angular-cli/wiki/3rd-party-libs) +Simply install your library via `npm install lib-name` and import it in your code. + +If the library does not include typings, you can search and install them using `npm run typings` npm script provided: + +```bash +npm install moment +npm run typings -- search moment +npm run typings -- install dt~moment --global +``` + +See https://github.com/typings/typings for more information about the `typings` tool. ### Updating angular-cli @@ -323,6 +343,8 @@ the local `angular-cli` from the project which was fetched remotely from npm. Now the `angular-cli` you cloned before is in three places: The folder you cloned it into, npm's folder where it stores global packages and the `angular-cli` project you just created. +You can also use `ng new foo --link-cli` to automatically link the `angular-cli` package. + Please read the official [npm-link documentation](https://www.npmjs.org/doc/cli/npm-link.html) and the [npm-link cheatsheet](http://browsenpm.org/help#linkinganynpmpackagelocally) for more information. diff --git a/addon/ng2/blueprints/ng2/files/package.json b/addon/ng2/blueprints/ng2/files/package.json index bc6179cced14..c8dd5ae9fb10 100644 --- a/addon/ng2/blueprints/ng2/files/package.json +++ b/addon/ng2/blueprints/ng2/files/package.json @@ -9,7 +9,8 @@ "lint": "tslint \"<%= sourceDir %>/**/*.ts\"", "test": "ng test", "pree2e": "webdriver-manager update", - "e2e": "protractor" + "e2e": "protractor", + "typings": "typings" }, "private": true, "dependencies": { From 23e5eb9d0e3064b41dc0d5ef5ee12aee04d5707d Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 22 Jul 2016 01:18:36 +0100 Subject: [PATCH 28/38] feat(env): decouple build from env file (#1404) --- README.md | 32 +++++++++---- .../__path__/app/environments/environment.ts | 7 +-- addon/ng2/commands/build.ts | 17 ++++++- addon/ng2/commands/serve.ts | 14 +++++- addon/ng2/models/webpack-config.ts | 23 +++++---- addon/ng2/tasks/build-webpack-watch.ts | 16 +++---- addon/ng2/tasks/build-webpack.ts | 13 +++-- addon/ng2/tasks/serve-webpack.ts | 2 +- addon/ng2/utilities/environment-plugin.ts | 47 ++++++------------- tests/e2e/e2e_workflow.spec.js | 20 +++++++- 10 files changed, 112 insertions(+), 79 deletions(-) diff --git a/README.md b/README.md index fe4b2148d8bf..6224ddf97030 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ The generated project has dependencies that require **Node 4 or greater**. * [Generating Components, Directives, Pipes and Services](#generating-components-directives-pipes-and-services) * [Generating a Route](#generating-a-route) * [Creating a Build](#creating-a-build) -* [Environments](#environments) +* [Build Targets and Environment Files](#build-targets-and-environment-files) * [Bundling](#bundling) * [Running Unit Tests](#running-unit-tests) * [Running End-to-End Tests](#running-end-to-end-tests) @@ -128,17 +128,33 @@ ng build The build artifacts will be stored in the `dist/` directory. -### Environments +### Build Targets and Environment Files -At build time, the `src/app/environment.ts` will be replaced by either -`config/environment.dev.ts` or `config/environment.prod.ts`, depending on the -current cli environment. The resulting file will be `dist/app/environment.ts`. +A build can specify both a build target (`development` or `production`) and an +environment file to be used with that build. By default, the development build +target is used. -Environment defaults to `dev`, but you can generate a production build via -the `-prod` flag in either `ng build -prod` or `ng serve -prod`. +At build time, `src/app/environments/environment.ts` will be replaced by +`src/app/environments/environment.{NAME}.ts` where `NAME` is the argument +provided to the `--environment` flag. + +These options also apply to the serve command. If you do not pass a value for `environment`, +it will default to `dev` for `development` and `prod` for `production`. + +```bash +# these are equivalent +ng build --target=production --environment=prod +ng build --prod --env=prod +ng build --prod +# and so are these +ng build --target=development --environment=dev +ng build --dev --e=dev +ng build --dev +ng build +``` You can also add your own env files other than `dev` and `prod` by creating a -`config/environment.{NAME}.ts` and use them by using the `--env=NAME` +`src/app/environments/environment.{NAME}.ts` and use them by using the `--env=NAME` flag on the build/serve commands. ### Bundling diff --git a/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.ts b/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.ts index e63359828bb1..5c54e150e57b 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.ts @@ -1,6 +1,7 @@ -// The file for the current environment will overwrite this one during build -// Different environments can be found in ./environment.{dev|prod}.ts -// The build system defaults to the dev environment +// The file for the current environment will overwrite this one during build. +// Different environments can be found in ./environment.{dev|prod}.ts, and +// you can create your own and use it with the --env flag. +// The build system defaults to the dev environment. export const environment = { production: false diff --git a/addon/ng2/commands/build.ts b/addon/ng2/commands/build.ts index d564de57362b..935102fa8484 100644 --- a/addon/ng2/commands/build.ts +++ b/addon/ng2/commands/build.ts @@ -3,6 +3,7 @@ import * as WebpackBuild from '../tasks/build-webpack'; import * as WebpackBuildWatch from '../tasks/build-webpack-watch'; interface BuildOptions { + target?: string; environment?: string; outputPath?: string; watch?: boolean; @@ -16,7 +17,8 @@ module.exports = Command.extend({ aliases: ['b'], availableOptions: [ - { name: 'environment', type: String, default: 'development', aliases: ['e', { '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'] }, { name: 'watcher', type: String }, @@ -24,6 +26,15 @@ module.exports = Command.extend({ ], run: function (commandOptions: BuildOptions) { + 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 ? @@ -31,13 +42,15 @@ module.exports = Command.extend({ cliProject: project, ui: ui, outputPath: commandOptions.outputPath, + target: commandOptions.target, environment: commandOptions.environment }) : new WebpackBuild({ cliProject: project, ui: ui, outputPath: commandOptions.outputPath, - environment: commandOptions.environment + target: commandOptions.target, + environment: commandOptions.environment, }); return buildTask.run(commandOptions); diff --git a/addon/ng2/commands/serve.ts b/addon/ng2/commands/serve.ts index b800af766f3f..4880f1fd2c52 100644 --- a/addon/ng2/commands/serve.ts +++ b/addon/ng2/commands/serve.ts @@ -22,6 +22,7 @@ export interface ServeTaskOptions { liveReloadPort?: number; liveReloadBaseUrl?: string; liveReloadLiveCss?: boolean; + target?: string; environment?: string; outputPath?: string; ssl?: boolean; @@ -45,7 +46,8 @@ module.exports = Command.extend({ { 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: 'environment', type: String, default: 'development', aliases: ['e', { 'dev': 'development' }, { 'mat': 'material'}, { '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: ['op', 'out'] }, { name: 'ssl', type: Boolean, default: false }, { name: 'ssl-key', type: String, default: 'ssl/server.key' }, @@ -53,6 +55,14 @@ module.exports = Command.extend({ ], run: function(commandOptions: ServeTaskOptions) { + if (commandOptions.environment === ''){ + if (commandOptions.target === 'development') { + commandOptions.environment = 'dev'; + } + if (commandOptions.target === 'production') { + commandOptions.environment = 'prod'; + } + } commandOptions.liveReloadHost = commandOptions.liveReloadHost || commandOptions.host; @@ -60,7 +70,7 @@ module.exports = Command.extend({ .then(this._autoFindLiveReloadPort.bind(this)) .then((commandOptions: ServeTaskOptions) => { commandOptions = assign({}, commandOptions, { - baseURL: this.project.config(commandOptions.environment).baseURL || '/' + baseURL: this.project.config(commandOptions.target).baseURL || '/' }); if (commandOptions.proxy) { diff --git a/addon/ng2/models/webpack-config.ts b/addon/ng2/models/webpack-config.ts index f4d9beeedf6a..a215217c0afa 100644 --- a/addon/ng2/models/webpack-config.ts +++ b/addon/ng2/models/webpack-config.ts @@ -1,4 +1,5 @@ import * as path from 'path'; +import * as fs from 'fs'; import * as webpackMerge from 'webpack-merge'; import { CliConfig } from './config'; import { NgCliEnvironmentPlugin } from '../utilities/environment-plugin'; @@ -22,9 +23,11 @@ export class NgCliWebpackConfig { private webpackMobileConfigPartial: any; private webpackMobileProdConfigPartial: any; - constructor(public ngCliProject: any, public environment: string) { + constructor(public ngCliProject: any, public target: string, public environment: string) { const sourceDir = CliConfig.fromProject().defaults.sourceDir; + const environmentPath = `./${sourceDir}/app/environments/environment.${environment}.ts`; + this.webpackBaseConfig = getWebpackCommonConfig(this.ngCliProject.root, sourceDir); this.webpackDevConfigPartial = getWebpackDevConfigPartial(this.ngCliProject.root, sourceDir); this.webpackProdConfigPartial = getWebpackProdConfigPartial(this.ngCliProject.root, sourceDir); @@ -37,27 +40,23 @@ export class NgCliWebpackConfig { } this.generateConfig(); - this.config.plugins.unshift(new NgCliEnvironmentPlugin({env: this.environment})); + this.config.plugins.unshift(new NgCliEnvironmentPlugin({ + path: path.resolve(this.ngCliProject.root, `./${sourceDir}/app/environments/`), + src: 'environment.ts', + dest: `environment.${this.environment}.ts` + })); } generateConfig(): void { - switch (this.environment) { - case "d": - case "dev": + switch (this.target) { case "development": - case "develop": this.config = webpackMerge(this.webpackBaseConfig, this.webpackDevConfigPartial); break; - - case "p": - case "prod": case "production": this.config = webpackMerge(this.webpackBaseConfig, this.webpackProdConfigPartial); break; - default: - //TODO: Not sure what to put here. We have a default env passed anyways. - this.ngCliProject.ui.writeLine("Environment could not be determined while configuring your build system.", 3) + 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 e54275b49af4..7e6514c6513f 100644 --- a/addon/ng2/tasks/build-webpack-watch.ts +++ b/addon/ng2/tasks/build-webpack-watch.ts @@ -1,13 +1,11 @@ -import {NgCliWebpackConfig} from '../models/webpack-config' -import {webpackOutputOptions} from '../models/'; -import {ServeTaskOptions} from '../commands/serve'; import * as rimraf from 'rimraf'; import * as path from 'path'; - -const Task = require('ember-cli/lib/models/task'); -const webpack = require('webpack'); -const ProgressPlugin = require('webpack/lib/ProgressPlugin'); - +import * as Task from 'ember-cli/lib/models/task'; +import * as webpack from 'webpack'; +import * as ProgressPlugin from 'webpack/lib/ProgressPlugin'; +import { NgCliWebpackConfig } from '../models/webpack-config'; +import { webpackOutputOptions } from '../models/'; +import { ServeTaskOptions } from '../commands/serve'; let lastHash: any = null; @@ -18,7 +16,7 @@ module.exports = Task.extend({ rimraf.sync(path.resolve(project.root, runTaskOptions.outputPath)); - const config = new NgCliWebpackConfig(project, runTaskOptions.environment).config; + const config = new NgCliWebpackConfig(project, runTaskOptions.target, runTaskOptions.environment).config; const webpackCompiler = webpack(config); webpackCompiler.apply(new ProgressPlugin({ diff --git a/addon/ng2/tasks/build-webpack.ts b/addon/ng2/tasks/build-webpack.ts index c7ebed1998bd..8d98d76a6812 100644 --- a/addon/ng2/tasks/build-webpack.ts +++ b/addon/ng2/tasks/build-webpack.ts @@ -1,13 +1,12 @@ -import {ServeTaskOptions} from '../commands/serve'; -import {NgCliWebpackConfig} from '../models/webpack-config' -import {webpackOutputOptions} from '../models/' import * as rimraf from 'rimraf'; import * as path from 'path'; +import * as Task from 'ember-cli/lib/models/task'; +import * as webpack from 'webpack'; +import { ServeTaskOptions } from '../commands/serve'; +import { NgCliWebpackConfig } from '../models/webpack-config'; +import { webpackOutputOptions } from '../models/'; // Configure build and output; -var Task = require('ember-cli/lib/models/task'); -const webpack = require('webpack'); - let lastHash: any = null; module.exports = Task.extend({ @@ -17,7 +16,7 @@ module.exports = Task.extend({ var project = this.cliProject; rimraf.sync(path.resolve(project.root, runTaskOptions.outputPath)); - var config = new NgCliWebpackConfig(project, runTaskOptions.environment).config; + var config = new NgCliWebpackConfig(project, runTaskOptions.target, runTaskOptions.environment).config; const webpackCompiler = webpack(config); const ProgressPlugin = require('webpack/lib/ProgressPlugin'); diff --git a/addon/ng2/tasks/serve-webpack.ts b/addon/ng2/tasks/serve-webpack.ts index f76e8acda18f..ff797cd6d050 100644 --- a/addon/ng2/tasks/serve-webpack.ts +++ b/addon/ng2/tasks/serve-webpack.ts @@ -15,7 +15,7 @@ module.exports = Task.extend({ let lastHash = null; let webpackCompiler: any; - var config: NgCliWebpackConfig = new NgCliWebpackConfig(this.project, commandOptions.environment).config; + var config: NgCliWebpackConfig = 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://localhost:${commandOptions.port}/`); diff --git a/addon/ng2/utilities/environment-plugin.ts b/addon/ng2/utilities/environment-plugin.ts index 6825769d8f95..dd489ca0625a 100644 --- a/addon/ng2/utilities/environment-plugin.ts +++ b/addon/ng2/utilities/environment-plugin.ts @@ -1,46 +1,27 @@ import * as fs from 'fs'; +import * as path from 'path'; interface WebpackPlugin { apply(compiler: any): void; } -export class NgCliEnvironmentPlugin implements WebpackPlugin { - _file: string; - _alias: string; - _env: string; +interface EnvOptions { + path: string; + src: string; + dest: string; +} - constructor(config: any) { - if (typeof config === 'string') { - config = {env: config}; - } - if (typeof config.env !== 'string') { - throw new Error('must provide env') - } - const ALIAS = { - '"dev"': 'dev', - 'development': 'dev', - '"development"': 'dev', - '"prod"': 'prod', - 'production': 'prod', - '"production"': 'prod', - '"test"': 'test', - 'testing': 'test', - '"testing"': 'test', - }; - const ENV = config.env.toLowerCase(); +export class NgCliEnvironmentPlugin implements WebpackPlugin { + config: EnvOptions; - this._file = config.file || 'environment'; - this._alias = config.alias || ALIAS; - this._env = this._alias[ENV] || ENV; - } + constructor(public config: EnvOptions) {} isEnvFile(file: string): boolean { - return file.indexOf(this._file + '.') !== -1; + return file === path.resolve(this.config.path, this.config.src); } replaceFile(file: string): any { - return file - .replace(this._file, this._file + '.' + this._env); + return path.resolve(this.config.path, this.config.dest); } updateResult(result: any): any { @@ -64,9 +45,9 @@ export class NgCliEnvironmentPlugin implements WebpackPlugin { fs.stat(envFile, (err, stats) => { if (err || !stats.isFile()) { - var errorText = (!err && stats.isFile()) ? 'Is not a file.' : 'Does not exist.'; - console.log('\nWARNING:\n' + envFile + '\n' + errorText + ' ' + 'Using file\n' + _resource + '\n'); - return callback(null, result); + const destPath = path.resolve(this.config.path, this.config.dest); + const errorText = (!err && stats.isFile()) ? 'is not a file.' : 'does not exist.'; + throw new Error(`${destPath} ${errorText}`); } // mutate result var newResult = this.updateResult(result); diff --git a/tests/e2e/e2e_workflow.spec.js b/tests/e2e/e2e_workflow.spec.js index fec4b87a6ffa..052efd377a21 100644 --- a/tests/e2e/e2e_workflow.spec.js +++ b/tests/e2e/e2e_workflow.spec.js @@ -102,11 +102,27 @@ describe('Basic end-to-end Workflow', function () { it('Supports build config file replacement', function() { this.timeout(420000); - sh.exec(`${ngBin} build --dev`); + sh.exec(`${ngBin} build --env=prod`); var mainBundlePath = path.join(process.cwd(), 'dist', 'main.bundle.js'); var mainBundleContent = fs.readFileSync(mainBundlePath, { encoding: 'utf8' }); - expect(mainBundleContent).to.include('production: false'); + expect(mainBundleContent).to.include('production: true'); + }); + + it('Build fails on invalid build target', function (done) { + this.timeout(420000); + sh.exec(`${ngBin} build --target=potato`, (code) => { + expect(code).to.not.equal(0); + done(); + }); + }); + + it('Build fails on invalid environment file', function (done) { + this.timeout(420000); + sh.exec(`${ngBin} build --environment=potato`, (code) => { + expect(code).to.not.equal(0); + done(); + }); }); it('Can run `ng build` in created project', function () { From 06fc077c8c27661c5adc80fa31803d6fe096f838 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 22 Jul 2016 16:02:49 +0100 Subject: [PATCH 29/38] fix: fix tsconfig for editors (#1420) --- addon/ng2/blueprints/ng2/files/__path__/tsconfig.json | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json index 538b19d67754..faac42382330 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "baseUrl":"./", "declaration": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, @@ -9,10 +8,5 @@ "moduleResolution": "node", "sourceMap": true, "target": "es5" - }, - "compileOnSave": false, - "buildOnSave": false, - "includes": [ - "**.d.ts" - ] + } } From 6562f781326716e5eb6bd2921d292669840f0848 Mon Sep 17 00:00:00 2001 From: Hans Date: Fri, 22 Jul 2016 10:18:17 -0700 Subject: [PATCH 30/38] chore: fix webpack branch after merge conflicts (#1423) --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index f4759ac28f60..a5d5e7233cd1 100644 --- a/package.json +++ b/package.json @@ -110,6 +110,7 @@ "devDependencies": { "chai": "^3.5.0", "conventional-changelog": "^1.1.0", + "denodeify": "^1.2.1", "eslint": "^2.8.0", "exists-sync": "0.0.3", "minimatch": "^3.0.0", From 29f899c53930a6fd3cf06fb10b9a9cac551229a4 Mon Sep 17 00:00:00 2001 From: Sean Larkin Date: Fri, 22 Jul 2016 14:25:31 -0500 Subject: [PATCH 31/38] fix: update to awesome-typescript-loader 2.1.0 (#1425) * fix: update to awesome-typescript-loader 2.1.0 which fixes a few issues shimming typings libs in tsconfig.json * fix: forgot to set libs in tsconfig blueprint --- addon/ng2/blueprints/ng2/files/__path__/tsconfig.json | 1 + addon/ng2/blueprints/ng2/files/__path__/typings.d.ts | 4 ---- package.json | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json index faac42382330..37845baee1b4 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json @@ -3,6 +3,7 @@ "declaration": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, + "lib": ["es6", "dom"], "mapRoot": "./", "module": "es6", "moduleResolution": "node", diff --git a/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts b/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts index 719f7b9a49be..99984cda19dc 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts @@ -3,10 +3,6 @@ // https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html /// -/// -/// -/// - <% if(!isMobile) { %> declare var System: any; <% if(!isMobile) { %>declare var module: { id: string };<% } %> diff --git a/package.json b/package.json index a5d5e7233cd1..41847851c29d 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "@types/rimraf": "0.0.25-alpha", "@types/webpack": "^1.12.22-alpha", "angular2-template-loader": "^0.4.0", - "awesome-typescript-loader": "^2.0.1", + "awesome-typescript-loader": "^2.1.0", "chalk": "^1.1.3", "compression-webpack-plugin": "^0.3.1", "copy-webpack-plugin": "^3.0.1", From b8f502e326954b21f40995b7aaad3ad0b3fa7b53 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 22 Jul 2016 21:08:27 +0100 Subject: [PATCH 32/38] chore(blueprints): remove module.id (#1426) --- .../blueprints/component/files/__path__/__name__.component.ts | 1 - addon/ng2/blueprints/ng2/files/__path__/app/app.component.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/addon/ng2/blueprints/component/files/__path__/__name__.component.ts b/addon/ng2/blueprints/component/files/__path__/__name__.component.ts index 7e485321bcbe..afe021f7b9bb 100644 --- a/addon/ng2/blueprints/component/files/__path__/__name__.component.ts +++ b/addon/ng2/blueprints/component/files/__path__/__name__.component.ts @@ -1,7 +1,6 @@ import { Component, OnInit } from '@angular/core'; @Component({ - moduleId: module.id, selector: '<%= selector %>',<% if(inlineTemplate) { %> template: `

diff --git a/addon/ng2/blueprints/ng2/files/__path__/app/app.component.ts b/addon/ng2/blueprints/ng2/files/__path__/app/app.component.ts index c9b95fe6be12..e29b19409839 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/app/app.component.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/app/app.component.ts @@ -2,7 +2,6 @@ import { Component } from '@angular/core';<% if (isMobile) { %> import { APP_SHELL_DIRECTIVES } from '@angular/app-shell';<% } %> @Component({ - moduleId: module.id, selector: '<%= prefix %>-root', <% if (isMobile) { %>template: `

From 930785f0528a7dbc66ea1eb57a198794937d5c85 Mon Sep 17 00:00:00 2001 From: Sean Larkin Date: Mon, 25 Jul 2016 04:51:26 -0500 Subject: [PATCH 33/38] feat: add host flag support for ng serve (#1442) --- addon/ng2/commands/serve.ts | 4 ++-- addon/ng2/tasks/serve-webpack.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/addon/ng2/commands/serve.ts b/addon/ng2/commands/serve.ts index 4880f1fd2c52..7e048aff2a39 100644 --- a/addon/ng2/commands/serve.ts +++ b/addon/ng2/commands/serve.ts @@ -37,7 +37,7 @@ module.exports = Command.extend({ availableOptions: [ { name: 'port', type: Number, default: defaultPort, aliases: ['p'] }, - { name: 'host', type: String, 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', type: String, aliases: ['pr', 'pxy'] }, { name: 'insecure-proxy', type: Boolean, default: false, aliases: ['inspr'], description: 'Set false to proxy self-signed SSL certificates' }, { name: 'watcher', type: String, default: 'events', aliases: ['w'] }, @@ -61,7 +61,7 @@ module.exports = Command.extend({ } if (commandOptions.target === 'production') { commandOptions.environment = 'prod'; - } + } } commandOptions.liveReloadHost = commandOptions.liveReloadHost || commandOptions.host; diff --git a/addon/ng2/tasks/serve-webpack.ts b/addon/ng2/tasks/serve-webpack.ts index ff797cd6d050..60589e48c011 100644 --- a/addon/ng2/tasks/serve-webpack.ts +++ b/addon/ng2/tasks/serve-webpack.ts @@ -11,14 +11,14 @@ import { CliConfig } from '../models/config'; module.exports = Task.extend({ run: function(commandOptions: ServeTaskOptions) { - + let lastHash = null; let webpackCompiler: any; var config: NgCliWebpackConfig = 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://localhost:${commandOptions.port}/`); + config.entry.main.unshift(`webpack-dev-server/client?http://${commandOptions.host}:${commandOptions.port}/`); webpackCompiler = webpack(config); webpackCompiler.apply(new ProgressPlugin({ @@ -33,11 +33,11 @@ module.exports = Task.extend({ inline: true }; - const serveMessage:string = chalk.green(`\n*\n*\n NG Live Development Server is running on http://localhost:${commandOptions.port}.\n*\n*`); + 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); return new Promise((resolve, reject) => { - server.listen(commandOptions.port, 'localhost', function(err, stats) { + server.listen(commandOptions.port, `${commandOptions.host}`, function(err, stats) { if(err) { lastHash = null; console.error(err.stack || err); From c3fe95950ad8c241f6787218e128e88ddddbcf60 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Mon, 25 Jul 2016 19:35:43 +0100 Subject: [PATCH 34/38] feat(test): add karma plugin (#1437) --- .../blueprints/ng2/files/config/karma.conf.js | 15 +++++-- addon/ng2/blueprints/ng2/files/package.json | 1 + ...ck-build-test.ts => webpack-build-test.js} | 18 ++++---- addon/ng2/tasks/test.ts | 31 -------------- package.json | 5 --- plugins/karma.js | 42 +++++++++++++++++++ 6 files changed, 64 insertions(+), 48 deletions(-) rename addon/ng2/models/{webpack-build-test.ts => webpack-build-test.js} (87%) create mode 100644 plugins/karma.js diff --git a/addon/ng2/blueprints/ng2/files/config/karma.conf.js b/addon/ng2/blueprints/ng2/files/config/karma.conf.js index 71e33490cf37..c86d3243662a 100644 --- a/addon/ng2/blueprints/ng2/files/config/karma.conf.js +++ b/addon/ng2/blueprints/ng2/files/config/karma.conf.js @@ -1,10 +1,12 @@ module.exports = function (config) { config.set({ basePath: '..', - frameworks: ['jasmine'], + frameworks: ['jasmine', 'angular-cli'], plugins: [ require('karma-jasmine'), - require('karma-chrome-launcher') + require('karma-chrome-launcher'), + require('karma-coverage'), + require('angular-cli/plugins/karma') ], customLaunchers: { // chrome setup for travis CI using chromium @@ -13,8 +15,13 @@ module.exports = function (config) { flags: ['--no-sandbox'] } }, - files: [], - preprocessors: {}, + files: [ + { pattern: './src/test.ts', watched: false } + ], + preprocessors: { + './src/test.ts': ['angular-cli'] + }, + angularCliConfig: './angular-cli.json', reporters: ['progress'], port: 9876, colors: true, diff --git a/addon/ng2/blueprints/ng2/files/package.json b/addon/ng2/blueprints/ng2/files/package.json index bf71f84632c0..c3d3b13f9284 100644 --- a/addon/ng2/blueprints/ng2/files/package.json +++ b/addon/ng2/blueprints/ng2/files/package.json @@ -43,6 +43,7 @@ "jasmine-spec-reporter": "2.5.0", "karma": "0.13.22", "karma-chrome-launcher": "0.2.3", + "karma-coverage": "^1.0.0", "karma-jasmine": "0.3.8", "protractor": "3.3.0", "ts-node": "0.9.1", diff --git a/addon/ng2/models/webpack-build-test.ts b/addon/ng2/models/webpack-build-test.js similarity index 87% rename from addon/ng2/models/webpack-build-test.ts rename to addon/ng2/models/webpack-build-test.js index 7c63e6e2299a..0161dac8d922 100644 --- a/addon/ng2/models/webpack-build-test.ts +++ b/addon/ng2/models/webpack-build-test.js @@ -1,8 +1,8 @@ -import * as webpack from 'webpack'; -import * as path from 'path'; -import { CliConfig } from './config'; +// this config must be JS so that the karma plugin can load it -export const getWebpackTestConfig = function(projectRoot: string, sourceDir: string) { +const path = require('path'); + +const getWebpackTestConfig = function(projectRoot, sourceDir) { return { devtool: 'inline-source-map', context: path.resolve(__dirname, './'), @@ -44,8 +44,8 @@ export const getWebpackTestConfig = function(projectRoot: string, sourceDir: str query: { useWebpackText: true, tsconfig: path.resolve(projectRoot, `./${sourceDir}/tsconfig.json`), - module: "commonjs", - target: "es5", + module: 'commonjs', + target: 'es5', useForkChecker: true, removeComments: true } @@ -56,12 +56,12 @@ export const getWebpackTestConfig = function(projectRoot: string, sourceDir: str ], exclude: [/\.e2e\.ts$/] }, - { test: /\.json$/, loader: 'json-loader'}, + { test: /\.json$/, loader: 'json-loader' }, { test: /\.css$/, loaders: ['raw-loader', 'postcss-loader'] }, { test: /\.styl$/, loaders: ['raw-loader', 'postcss-loader', 'stylus-loader'] }, { test: /\.less$/, loaders: ['raw-loader', 'postcss-loader', 'less-loader'] }, { test: /\.scss$/, loaders: ['raw-loader', 'postcss-loader', 'sass-loader'] }, - { test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000'}, + { test: /\.(jpg|png)$/, loader: 'url-loader?limit=128000' }, { test: /\.html$/, loader: 'raw-loader', exclude: [path.resolve(projectRoot, `./${sourceDir}/index.html`)] } ], postLoaders: [ @@ -89,3 +89,5 @@ export const getWebpackTestConfig = function(projectRoot: string, sourceDir: str } }; } + +module.exports.getWebpackTestConfig = getWebpackTestConfig; \ No newline at end of file diff --git a/addon/ng2/tasks/test.ts b/addon/ng2/tasks/test.ts index 8ef8268f9b15..0f8fd6b96f48 100644 --- a/addon/ng2/tasks/test.ts +++ b/addon/ng2/tasks/test.ts @@ -16,37 +16,6 @@ module.exports = Task.extend({ return new Promise((resolve) => { const karma = requireDependency(projectRoot, 'karma'); const karmaConfig = path.join(projectRoot, this.project.ngConfig.test.karma.config); - const testFile = `./${this.project.ngConfig.defaults.sourceDir}/test.ts`; - - options.plugins = [ - require('karma-webpack'), - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-coverage'), - require('karma-mocha-reporter'), - require('karma-sourcemap-loader') - ]; - options.reporters = ['coverage', 'mocha', 'progress']; - - // Abstract the webpack concepts from the local karma config. - // Add those details here. - - // Single test entry file. Will run the test.ts bundle and track it. - options.files = [{ pattern: testFile, watched: false }]; - options.preprocessors = { [testFile]: ['webpack','sourcemap'] }; - options.webpack = getWebpackTestConfig(projectRoot, this.project.ngConfig.defaults.sourceDir); - options.webpackMiddleware = { - noInfo: true, // Hide webpack output because its noisy. - stats: { // Also prevent chunk and module display output, cleaner look. Only emit errors. - assets: false, - colors: true, - version: false, - hash: false, - timings: false, - chunks: false, - chunkModules: false - } - }; // Convert browsers from a string to an array if (options.browsers) { diff --git a/package.json b/package.json index 41847851c29d..38bb352dfe13 100644 --- a/package.json +++ b/package.json @@ -56,11 +56,6 @@ "html-webpack-plugin": "^2.19.0", "istanbul-instrumenter-loader": "^0.2.0", "json-loader": "^0.5.4", - "karma-chrome-launcher": "^1.0.1", - "karma-coverage": "^1.0.0", - "karma-jasmine": "^1.0.2", - "karma-mocha-reporter": "^2.0.4", - "karma-phantomjs-launcher": "^1.0.0", "karma-sourcemap-loader": "^0.3.7", "karma-webpack": "^1.7.0", "leek": "0.0.21", diff --git a/plugins/karma.js b/plugins/karma.js new file mode 100644 index 000000000000..1282650d6659 --- /dev/null +++ b/plugins/karma.js @@ -0,0 +1,42 @@ +const path = require('path'); +const getWebpackTestConfig = require('../addon/ng2/models/webpack-build-test').getWebpackTestConfig; + +const init = (config) => { + + // load Angular CLI config + if (!config.angularCliConfig) throw new Error('Missing \'angularCliConfig\' entry in Karma config'); + const angularCliConfig = require(path.join(config.basePath, config.angularCliConfig)) + + // add webpack config + config.webpack = getWebpackTestConfig(config.basePath, angularCliConfig.defaults.sourceDir); + config.webpackMiddleware = { + noInfo: true, // Hide webpack output because its noisy. + stats: { // Also prevent chunk and module display output, cleaner look. Only emit errors. + assets: false, + colors: true, + version: false, + hash: false, + timings: false, + chunks: false, + chunkModules: false + } + }; + + // replace the angular-cli preprocessor with webpack+sourcemap + Object.keys(config.preprocessors) + .filter((file) => config.preprocessors[file].indexOf('angular-cli') !== -1) + .map((file) => config.preprocessors[file]) + .map((arr) => arr.splice(arr.indexOf('angular-cli'), 1, 'webpack', 'sourcemap')); +} + +init.$inject = ['config'] + +// dummy preprocessor, just to keep karma from showing a warning +const preprocessor = () => (content, file, done) => done(null, content); +preprocessor.$inject = [] + +// also export karma-webpack and karma-sourcemap-loader +module.exports = Object.assign({ + 'framework:angular-cli': ['factory', init], + 'preprocessor:angular-cli': ['factory', preprocessor] +}, require('karma-webpack'), require('karma-sourcemap-loader')); \ No newline at end of file From 8a2e0e512a4ca0983bc1e20083c7a1ca4e0477c2 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Mon, 25 Jul 2016 23:35:29 +0100 Subject: [PATCH 35/38] chore(blueprints): re-add outDir (#1428) --- addon/ng2/blueprints/ng2/files/__path__/tsconfig.json | 1 + addon/ng2/blueprints/ng2/files/__path__/typings.d.ts | 2 +- addon/ng2/blueprints/ng2/files/e2e/tsconfig.json | 1 + addon/ng2/blueprints/ng2/index.js | 4 ++-- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json index 37845baee1b4..fc08b73a705b 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json @@ -7,6 +7,7 @@ "mapRoot": "./", "module": "es6", "moduleResolution": "node", + "outDir": "<%= relativeRootPath %>/dist/out-tsc", "sourceMap": true, "target": "es5" } diff --git a/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts b/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts index 99984cda19dc..c9d1541fdc09 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts @@ -2,7 +2,7 @@ // https://github.com/typings/typings // https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html -/// +/// <% if(!isMobile) { %> declare var System: any; <% if(!isMobile) { %>declare var module: { id: string };<% } %> diff --git a/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json b/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json index eb5d88ecd0bc..3c9a6d4169cd 100644 --- a/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json @@ -6,6 +6,7 @@ "experimentalDecorators": true, "module": "commonjs", "moduleResolution": "node", + "outDir": "../dist/out-tsc-e2e", "sourceMap": true, "target": "es5" } diff --git a/addon/ng2/blueprints/ng2/index.js b/addon/ng2/blueprints/ng2/index.js index 146ef7c50023..90588b23bcf5 100644 --- a/addon/ng2/blueprints/ng2/index.js +++ b/addon/ng2/blueprints/ng2/index.js @@ -24,7 +24,7 @@ module.exports = { this.version = require(path.resolve(__dirname, '..', '..', '..', '..', 'package.json')).version; // Join with / not path.sep as reference to typings require forward slashes. - const refToTypings = options.sourceDir.split(path.sep).map(() => '..').join('/'); + const relativeRootPath = options.sourceDir.split(path.sep).map(() => '..').join('/'); const fullAppName = stringUtils.dasherize(options.entity.name) .replace(/-(.)/g, (_, l) => ' ' + l.toUpperCase()) .replace(/^./, (l) => l.toUpperCase()); @@ -37,7 +37,7 @@ module.exports = { sourceDir: options.sourceDir, prefix: options.prefix, styleExt: this.styleExt, - refToTypings: refToTypings, + relativeRootPath: relativeRootPath, isMobile: options.mobile }; }, From 3d223947345d4535510cb37f6dfa0f3e32a64589 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Tue, 26 Jul 2016 05:10:42 +0100 Subject: [PATCH 36/38] feat: use @types instead of typings (#1449) --- README.md | 7 +- .../ng2/files/__path__/tsconfig.json | 8 +- .../ng2/files/__path__/typings.d.ts | 5 +- .../blueprints/ng2/files/config/karma.conf.js | 5 +- .../blueprints/ng2/files/e2e/tsconfig.json | 5 +- .../ng2/blueprints/ng2/files/e2e/typings.d.ts | 1 - addon/ng2/blueprints/ng2/files/package.json | 16 +- addon/ng2/blueprints/ng2/files/typings.json | 10 - addon/ng2/models/webpack-build-common.ts | 18 +- addon/ng2/models/webpack-build-test.js | 1 - .../ts-path-mappings-webpack-plugin.ts | 252 ------------------ package.json | 4 +- typings.json | 18 -- 13 files changed, 31 insertions(+), 319 deletions(-) delete mode 100644 addon/ng2/blueprints/ng2/files/e2e/typings.d.ts delete mode 100644 addon/ng2/blueprints/ng2/files/typings.json delete mode 100644 addon/ng2/utilities/ts-path-mappings-webpack-plugin.ts delete mode 100644 typings.json diff --git a/README.md b/README.md index a8c01ca1d7ac..968a5bb591c7 100644 --- a/README.md +++ b/README.md @@ -265,16 +265,13 @@ ng new sassy-project --style=sass Simply install your library via `npm install lib-name` and import it in your code. -If the library does not include typings, you can search and install them using `npm run typings` npm script provided: +If the library does not include typings, you can install them using npm: ```bash npm install moment -npm run typings -- search moment -npm run typings -- install dt~moment --global +npm install @types/moment ``` -See https://github.com/typings/typings for more information about the `typings` tool. - ### Updating angular-cli To update `angular-cli` to a new version, you must update both the global package and your project's local package. diff --git a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json index fc08b73a705b..e01a1794bfb5 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/__path__/tsconfig.json @@ -9,6 +9,12 @@ "moduleResolution": "node", "outDir": "<%= relativeRootPath %>/dist/out-tsc", "sourceMap": true, - "target": "es5" + "target": "es5", + "typeRoots": [ + "../node_modules/@types" + ], + "types": [ + "jasmine" + ] } } diff --git a/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts b/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts index c9d1541fdc09..dc0276ded1cd 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/typings.d.ts @@ -2,10 +2,7 @@ // https://github.com/typings/typings // https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html -/// -<% if(!isMobile) { %> declare var System: any; -<% if(!isMobile) { %>declare var module: { id: string };<% } %> +declare var module: { id: string }; declare var require: any; -<% } %> diff --git a/addon/ng2/blueprints/ng2/files/config/karma.conf.js b/addon/ng2/blueprints/ng2/files/config/karma.conf.js index c86d3243662a..118cdc2e7721 100644 --- a/addon/ng2/blueprints/ng2/files/config/karma.conf.js +++ b/addon/ng2/blueprints/ng2/files/config/karma.conf.js @@ -1,3 +1,6 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/0.13/config/configuration-file.html + module.exports = function (config) { config.set({ basePath: '..', @@ -22,7 +25,7 @@ module.exports = function (config) { './src/test.ts': ['angular-cli'] }, angularCliConfig: './angular-cli.json', - reporters: ['progress'], + reporters: ['coverage', 'progress'], port: 9876, colors: true, logLevel: config.LOG_INFO, diff --git a/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json b/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json index 3c9a6d4169cd..656bdb14ff14 100644 --- a/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json +++ b/addon/ng2/blueprints/ng2/files/e2e/tsconfig.json @@ -8,6 +8,9 @@ "moduleResolution": "node", "outDir": "../dist/out-tsc-e2e", "sourceMap": true, - "target": "es5" + "target": "es5", + "typeRoots": [ + "../node_modules/@types" + ] } } diff --git a/addon/ng2/blueprints/ng2/files/e2e/typings.d.ts b/addon/ng2/blueprints/ng2/files/e2e/typings.d.ts deleted file mode 100644 index eebc2728b868..000000000000 --- a/addon/ng2/blueprints/ng2/files/e2e/typings.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/addon/ng2/blueprints/ng2/files/package.json b/addon/ng2/blueprints/ng2/files/package.json index c3d3b13f9284..e7dfbbcc5608 100644 --- a/addon/ng2/blueprints/ng2/files/package.json +++ b/addon/ng2/blueprints/ng2/files/package.json @@ -5,12 +5,10 @@ "angular-cli": {}, "scripts": { "start": "ng serve", - "postinstall": "typings install", "lint": "tslint \"<%= sourceDir %>/**/*.ts\"", "test": "ng test", "pree2e": "webdriver-manager update", - "e2e": "protractor", - "typings": "typings" + "e2e": "protractor" }, "private": true, "dependencies": { @@ -36,9 +34,10 @@ "angular2-universal-polyfills": "0.4.1", "preboot": "2.1.2", "parse5": "1.5.1",<% } %> + "@types/jasmine": "^2.2.30", + "@types/protractor": "^1.5.16", "angular-cli": "^<%= version %>", - "codelyzer": "0.0.20", - "ember-cli-inject-live-reload": "1.4.0", + "codelyzer": "0.0.26", "jasmine-core": "2.4.1", "jasmine-spec-reporter": "2.5.0", "karma": "0.13.22", @@ -46,9 +45,8 @@ "karma-coverage": "^1.0.0", "karma-jasmine": "0.3.8", "protractor": "3.3.0", - "ts-node": "0.9.1", - "tslint": "3.11.0", - "typescript": "^1.9.0-dev.20160627-1.0", - "typings": "^1.3.1" + "ts-node": "1.2.1", + "tslint": "3.13.0", + "typescript": "^2.0.0" } } diff --git a/addon/ng2/blueprints/ng2/files/typings.json b/addon/ng2/blueprints/ng2/files/typings.json deleted file mode 100644 index 6d8375bdd9a0..000000000000 --- a/addon/ng2/blueprints/ng2/files/typings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "globalDevDependencies": { - "angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459", - "jasmine": "registry:dt/jasmine#2.2.0+20160412134438", - "selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654" - }, - "globalDependencies": { - <% if (isMobile) {%>"node": "registry:dt/node#6.0.0+20160621231320" <% } %> - } -} diff --git a/addon/ng2/models/webpack-build-common.ts b/addon/ng2/models/webpack-build-common.ts index dd184195cac1..edb412f710b1 100644 --- a/addon/ng2/models/webpack-build-common.ts +++ b/addon/ng2/models/webpack-build-common.ts @@ -3,25 +3,14 @@ import * as CopyWebpackPlugin from 'copy-webpack-plugin'; import * as HtmlWebpackPlugin from 'html-webpack-plugin'; import * as webpack from 'webpack'; import { ForkCheckerPlugin } from 'awesome-typescript-loader'; -import { LoaderConfig, PathsPlugin } from '../utilities/ts-path-mappings-webpack-plugin'; import { CliConfig } from './config'; export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) { - const awesomeTypescriptLoaderConfig: LoaderConfig | any = { - useWebpackText: true, - useForkChecker: true, - tsconfig: path.resolve(projectRoot, `./${sourceDir}/tsconfig.json`) - } - return { devtool: 'inline-source-map', resolve: { extensions: ['', '.ts', '.js'], - root: path.resolve(projectRoot, `./${sourceDir}`), - moduleDirectories: ['node_modules'], - plugins: [ - new PathsPlugin(awesomeTypescriptLoaderConfig); - ] + root: path.resolve(projectRoot, `./${sourceDir}`) }, context: path.resolve(__dirname, './'), entry: { @@ -49,7 +38,10 @@ export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) { loaders: [ { loader: 'awesome-typescript-loader', - query: awesomeTypescriptLoaderConfig + query: { + useForkChecker: true, + tsconfig: path.resolve(projectRoot, `./${sourceDir}/tsconfig.json`) + } }, { loader: 'angular2-template-loader' diff --git a/addon/ng2/models/webpack-build-test.js b/addon/ng2/models/webpack-build-test.js index 0161dac8d922..cada4fefd3f9 100644 --- a/addon/ng2/models/webpack-build-test.js +++ b/addon/ng2/models/webpack-build-test.js @@ -42,7 +42,6 @@ const getWebpackTestConfig = function(projectRoot, sourceDir) { { loader: 'awesome-typescript-loader', query: { - useWebpackText: true, tsconfig: path.resolve(projectRoot, `./${sourceDir}/tsconfig.json`), module: 'commonjs', target: 'es5', diff --git a/addon/ng2/utilities/ts-path-mappings-webpack-plugin.ts b/addon/ng2/utilities/ts-path-mappings-webpack-plugin.ts deleted file mode 100644 index 6c35b7fd3183..000000000000 --- a/addon/ng2/utilities/ts-path-mappings-webpack-plugin.ts +++ /dev/null @@ -1,252 +0,0 @@ -import * as path from 'path'; -import * as ts from 'typescript'; -import * as _ from 'lodash'; - -const ModulesInRootPlugin: new (a: string, b: string, c: string) => ResolverPlugin = require('enhanced-resolve/lib/ModulesInRootPlugin'); - -const createInnerCallback: CreateInnerCallback = require('enhanced-resolve/lib/createInnerCallback'); -const getInnerRequest: getInnerRequest = require('enhanced-resolve/lib/getInnerRequest'); - -export type ResolverCallback = (request: Request, callback: Callback) => void; -export type QueryOptions = LoaderConfig & ts.CompilerOptions; -export type TsConfig = ts.ParsedCommandLine; - -export type CreateInnerCallback = (callback: Callback, options: Callback, message?: string, messageOptional?: string) => Callback; -type getInnerRequest = (resolver: Resolver, request: Request) => string; - -export interface TSCompilerInfo { - compilerPath: string; - tsImpl: typeof ts; -} - -export interface Request { - request?: Request; - relativePath: string; -} - -export interface Callback { - (err?: Error, result?: any): void; - - log?: any; - stack?: any; - missing?: any; -} - -export interface Configs { - configFilePath: string; - compilerConfig: TsConfig; - loaderConfig: LoaderConfig; -} - -export interface LoaderConfig { - instanceName?: string; - showRecompileReason?: boolean; - compiler?: string; - emitRequireType?: boolean; - reEmitDependentFiles?: boolean; - tsconfig?: string; - useWebpackText?: boolean; - externals?: string[]; - doTypeCheck?: boolean; - ignoreDiagnostics?: number[]; - forkChecker?: boolean; - forkCheckerSilent?: boolean; - useBabel?: boolean; - babelCore?: string; - babelOptions?: any; - usePrecompiledFiles?: boolean; - skipDeclarationFilesCheck?: boolean; - useCache?: boolean; - cacheDirectory?: string; - resolveGlobs?: boolean; - library: string; -} - -export interface ResolverPlugin { - apply(resolver: Resolver): void; -} - -export interface Resolver { - apply(plugin: ResolverPlugin): void; - plugin(source: string, cb: ResolverCallback): void; - doResolve(target: string, req: Request, desc: string, Callback: any): void; - join(relativePath: string, innerRequest: Request): Request; -} - -export interface Mapping { - onlyModule: boolean; - alias: string; - aliasPattern: RegExp; - target: string; -} - -export function readConfigFile(baseDir: string, query: QueryOptions, tsImpl: typeof ts): Configs { - let configFilePath: string; - if (query.tsconfig && query.tsconfig.match(/\.json$/)) { - configFilePath = path.dirname(path.resolve(process.cwd(),query.tsconfig)); - } else { - configFilePath = tsImpl.findConfigFile(process.cwd(), tsImpl.sys.fileExists); - } - - let existingOptions = tsImpl.convertCompilerOptionsFromJson(query, process.cwd(), 'atl.query'); - - if (!configFilePath) { - return { - configFilePath: process.cwd(), - compilerConfig: tsImpl.parseJsonConfigFileContent( - {}, - tsImpl.sys, - process.cwd(), - _.extend({}, ts.getDefaultCompilerOptions(), existingOptions.options) as ts.CompilerOptions, - process.cwd() - ), - loaderConfig: query as LoaderConfig - }; - } - - debugger; - - let jsonConfigFile = tsImpl.readConfigFile(configFilePath, tsImpl.sys.readFile); - - let compilerConfig = tsImpl.parseJsonConfigFileContent( - jsonConfigFile.config, - tsImpl.sys, - process.cwd(), - existingOptions.options, - configFilePath - ); - - return { - jsonConfigFile, - configFilePath, - compilerConfig, - loaderConfig: _.defaults( - query, - jsonConfigFile.config.awesomeTypescriptLoaderOptions) - }; -} - - - -export function setupTs(compiler: string): TSCompilerInfo { - let compilerPath = compiler || 'typescript'; - - let tsImpl: typeof ts; - let tsImplPath: string; - try { - tsImplPath = require.resolve(compilerPath); - tsImpl = require(tsImplPath); - } catch (e) { - console.error(e); - process.exit(1); - } - - let compilerInfo: TSCompilerInfo = { - compilerPath, - tsImpl, - }; - - return compilerInfo; -} - - -function escapeRegExp(str: string) { - return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); -} - -export class PathsPlugin implements ResolverPlugin { - source: string; - target: string; - ts: typeof ts; - configFilePath: string; - options: ts.CompilerOptions; - - baseUrl: string; - mappings: Mapping[]; - absoluteBaseUrl: string; - - - constructor(config: LoaderConfig & ts.CompilerOptions = {} as any) { - this.source = 'described-resolve'; - this.target = 'resolve'; - - this.ts = setupTs(config.compiler).tsImpl; - - let { configFilePath, compilerConfig, jsonConfigFile } = readConfigFile(process.cwd(), config, this.ts); - this.options = compilerConfig.options; - this.configFilePath = configFilePath; - - this.baseUrl = this.options.configFilePath ? this.options.configFilePath : './'; - - this.absoluteBaseUrl = path.resolve( - path.dirname(this.configFilePath), - this.baseUrl - ); - - this.mappings = []; - let paths = this.options.paths || {}; - Object.keys(paths).forEach(alias => { - let onlyModule = alias.indexOf('*') === -1; - let excapedAlias = escapeRegExp(alias); - let targets = paths[alias]; - targets.forEach(target => { - let aliasPattern: RegExp; - if (onlyModule) { - aliasPattern = new RegExp(`^${excapedAlias}$`); - } else { - let withStarCapturing = excapedAlias.replace('\\*', '(.*)'); - aliasPattern = new RegExp(`^${withStarCapturing}`); - } - - this.mappings.push({ - onlyModule, - alias, - aliasPattern, - target: target - }); - }); - }); - } - - apply(resolver: Resolver) { - let { baseUrl, mappings, absoluteBaseUrl } = this; - - if (baseUrl) { - resolver.apply(new ModulesInRootPlugin("module", absoluteBaseUrl, "resolve")); - } - - mappings.forEach(mapping => { - // resolver.plugin(this.source, this.createPlugin(resolver, mapping)); - resolver.plugin(this.source, function(request, callback) { - var innerRequest = getInnerRequest(resolver, request); - if(!innerRequest) return callback(); - - var newRequestStr = mapping.target; - var match = innerRequest.match(mapping.aliasPattern); - if (!match) { - return callback(); - } - if (!mapping.onlyModule) { - newRequestStr = newRequestStr.replace('*', match[1]); - } - if (newRequestStr[0] === '.') { - newRequestStr = path.resolve(absoluteBaseUrl, newRequestStr); - } - var obj: Request = Object.assign({}, request, { - request: newRequestStr - }); - - console.log("aliased'" + innerRequest + "': '" + mapping.alias + "' to '" + newRequestStr + "'", newRequest); - - return resolver.doResolve(this.target, obj,"aliased with mapping '" + innerRequest + "': '" + mapping.alias + "' to '" + newRequestStr + "'", createInnerCallback(function(err, result) { - if(arguments.length > 0) return callback(err, result); - - // don't allow other aliasing or raw request - callback(null, null); - }, callback)); - - return callback(); - }); - }); - } -} diff --git a/package.json b/package.json index 38bb352dfe13..a328abfea19f 100644 --- a/package.json +++ b/package.json @@ -32,12 +32,11 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "^0.2.0", "@types/lodash": "^4.0.25-alpha", "@types/rimraf": "0.0.25-alpha", "@types/webpack": "^1.12.22-alpha", "angular2-template-loader": "^0.4.0", - "awesome-typescript-loader": "^2.1.0", + "awesome-typescript-loader": "^2.1.1", "chalk": "^1.1.3", "compression-webpack-plugin": "^0.3.1", "copy-webpack-plugin": "^3.0.1", @@ -90,7 +89,6 @@ "tslint-loader": "^2.1.4", "typedoc": "^0.4.2", "typescript": "^2.0.0", - "typings": "^0.8.1", "url-loader": "^0.5.7", "webpack": "2.1.0-beta.18", "webpack-dev-server": "2.1.0-beta.0", diff --git a/typings.json b/typings.json deleted file mode 100644 index 5d47c2fc7a0b..000000000000 --- a/typings.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "dependencies": { - "es6-promise": "registry:npm/es6-promise#3.0.0+20160211003958" - }, - "devDependencies": { - "chalk": "github:typings/typed-chalk#a7e422c5455e70292e5675a727d43a7b05fc3e58" - }, - "ambientDevDependencies": { - "assertion-error": "github:DefinitelyTyped/DefinitelyTyped/assertion-error/assertion-error.d.ts#800a7047cf275cc9f695cbd116748cd408a09d6d", - "chai": "github:DefinitelyTyped/DefinitelyTyped/chai/chai.d.ts#9c25433c84251bfe72bf0030a95edbbb2c81c9d5", - "glob": "github:DefinitelyTyped/DefinitelyTyped/glob/glob.d.ts#a14d724826174d1669d4df04c80f4838b7e71fdf", - "minimatch": "github:DefinitelyTyped/DefinitelyTyped/minimatch/minimatch.d.ts#a3900b896f7b3361b79f9b503224777619907d53", - "mocha": "github:DefinitelyTyped/DefinitelyTyped/mocha/mocha.d.ts#d6dd320291705694ba8e1a79497a908e9f5e6617", - "node": "github:DefinitelyTyped/DefinitelyTyped/node/node.d.ts#8cf8164641be73e8f1e652c2a5b967c7210b6729", - "shelljs": "github:DefinitelyTyped/DefinitelyTyped/shelljs/shelljs.d.ts#ce14ae27a020194da3d35aa3468ca1e9e5296316", - "through": "github:DefinitelyTyped/DefinitelyTyped/through/through.d.ts#4ffee4a839f36d4f13ea7b0bc03ed2ca853e79d5" - } -} From 9d420716c29e8575f82053f2df71a0c3664230ce Mon Sep 17 00:00:00 2001 From: Sean Larkin Date: Tue, 26 Jul 2016 00:02:17 -0500 Subject: [PATCH 37/38] fix: make sourcemaps work in test (#1447) --- addon/ng2/models/webpack-build-test.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/addon/ng2/models/webpack-build-test.js b/addon/ng2/models/webpack-build-test.js index cada4fefd3f9..3e249d549929 100644 --- a/addon/ng2/models/webpack-build-test.js +++ b/addon/ng2/models/webpack-build-test.js @@ -1,6 +1,7 @@ // this config must be JS so that the karma plugin can load it const path = require('path'); +const webpack = require('webpack'); const getWebpackTestConfig = function(projectRoot, sourceDir) { return { @@ -73,6 +74,12 @@ const getWebpackTestConfig = function(projectRoot, sourceDir) { } ] }, + plugins: [ + new webpack.SourceMapDevToolPlugin({ + filename: null, // if no value is provided the sourcemap is inlined + test: /\.(ts|js)($|\?)/i // process .js and .ts files only + }) + ], tslint: { emitErrors: false, failOnHint: false, @@ -89,4 +96,4 @@ const getWebpackTestConfig = function(projectRoot, sourceDir) { }; } -module.exports.getWebpackTestConfig = getWebpackTestConfig; \ No newline at end of file +module.exports.getWebpackTestConfig = getWebpackTestConfig; From a3b1bf42702c6698928d9df5fe77a186443a5eb3 Mon Sep 17 00:00:00 2001 From: Hans Date: Tue, 26 Jul 2016 15:14:37 -0700 Subject: [PATCH 38/38] feat: add utilities for typescript ast (#1159) (#1453) 'ast-utils.ts' provides typescript ast utility functions --- addon/ng2/utilities/ast-utils.ts | 54 +++++++ addon/ng2/utilities/dynamic-path-parser.js | 3 +- tests/acceptance/ast-utils.spec.ts | 177 +++++++++++++++++++++ 3 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 addon/ng2/utilities/ast-utils.ts create mode 100644 tests/acceptance/ast-utils.spec.ts diff --git a/addon/ng2/utilities/ast-utils.ts b/addon/ng2/utilities/ast-utils.ts new file mode 100644 index 000000000000..7b9f1104f33f --- /dev/null +++ b/addon/ng2/utilities/ast-utils.ts @@ -0,0 +1,54 @@ +import * as ts from 'typescript'; +import { InsertChange } from './change'; + +/** +* Find all nodes from the AST in the subtree of node of SyntaxKind kind. +* @param node +* @param kind +* @return all nodes of kind kind, or [] if none is found +*/ +export function findNodes(node: ts.Node, kind: ts.SyntaxKind): ts.Node[] { + if (!node) { + return []; + } + let arr: ts.Node[] = []; + if (node.kind === kind) { + arr.push(node); + } + return node.getChildren().reduce((foundNodes, child) => + foundNodes.concat(findNodes(child, kind)), arr); +} + +/** + * Helper for sorting nodes. + * @return function to sort nodes in increasing order of position in sourceFile + */ +function nodesByPosition(first: ts.Node, second: ts.Node): number { + return first.pos - second.pos; +} + +/** + * Insert `toInsert` after the last occurence of `ts.SyntaxKind[nodes[i].kind]` + * or after the last of occurence of `syntaxKind` if the last occurence is a sub child + * of ts.SyntaxKind[nodes[i].kind] and save the changes in file. + * + * @param nodes insert after the last occurence of nodes + * @param toInsert string to insert + * @param file file to insert changes into + * @param fallbackPos position to insert if toInsert happens to be the first occurence + * @param syntaxKind the ts.SyntaxKind of the subchildren to insert after + * @return Change instance + * @throw Error if toInsert is first occurence but fall back is not set + */ +export function insertAfterLastOccurrence(nodes: ts.Node[], toInsert: string, + file: string, fallbackPos?: number, syntaxKind?: ts.SyntaxKind): Change { + var lastItem = nodes.sort(nodesByPosition).pop(); + if (syntaxKind) { + lastItem = findNodes(lastItem, syntaxKind).sort(nodesByPosition).pop(); + } + if (!lastItem && fallbackPos == undefined) { + throw new Error(`tried to insert ${toInsert} as first occurence with no fallback position`); + } + let lastItemPosition: number = lastItem ? lastItem.end : fallbackPos; + return new InsertChange(file, lastItemPosition, toInsert); +} diff --git a/addon/ng2/utilities/dynamic-path-parser.js b/addon/ng2/utilities/dynamic-path-parser.js index 281f9ea17f42..a00300596b70 100644 --- a/addon/ng2/utilities/dynamic-path-parser.js +++ b/addon/ng2/utilities/dynamic-path-parser.js @@ -55,4 +55,5 @@ module.exports = function dynamicPathParser(project, entityName) { parsedPath.appRoot = appRoot return parsedPath; -}; \ No newline at end of file +}; + diff --git a/tests/acceptance/ast-utils.spec.ts b/tests/acceptance/ast-utils.spec.ts new file mode 100644 index 000000000000..cfc2cf42f346 --- /dev/null +++ b/tests/acceptance/ast-utils.spec.ts @@ -0,0 +1,177 @@ +import * as mockFs from 'mock-fs'; +import { expect } from 'chai'; +import * as ts from 'typescript'; +import * as fs from 'fs'; +import { InsertChange, RemoveChange } from '../../addon/ng2/utilities/change'; +import * as Promise from 'ember-cli/lib/ext/promise'; +import { + findNodes, + insertAfterLastOccurrence +} from '../../addon/ng2/utilities/ast-utils'; + +const readFile = Promise.denodeify(fs.readFile); + +describe('ast-utils: findNodes', () => { + const sourceFile = 'tmp/tmp.ts'; + + beforeEach(() => { + let mockDrive = { + 'tmp': { + 'tmp.ts': `import * as myTest from 'tests' \n` + + 'hello.' + } + }; + mockFs(mockDrive); + }); + + afterEach(() => { + mockFs.restore(); + }); + + it('finds no imports', () => { + let editedFile = new RemoveChange(sourceFile, 0, `import * as myTest from 'tests' \n`); + return editedFile + .apply() + .then(() => { + let rootNode = getRootNode(sourceFile); + let nodes = findNodes(rootNode, ts.SyntaxKind.ImportDeclaration); + expect(nodes).to.be.empty; + }); + }); + it('finds one import', () => { + let rootNode = getRootNode(sourceFile); + let nodes = findNodes(rootNode, ts.SyntaxKind.ImportDeclaration); + expect(nodes.length).to.equal(1); + }); + it('finds two imports from inline declarations', () => { + // remove new line and add an inline import + let editedFile = new RemoveChange(sourceFile, 32, '\n'); + return editedFile + .apply() + .then(() => { + let insert = new InsertChange(sourceFile, 32, `import {Routes} from '@angular/routes'`); + return insert.apply(); + }) + .then(() => { + let rootNode = getRootNode(sourceFile); + let nodes = findNodes(rootNode, ts.SyntaxKind.ImportDeclaration); + expect(nodes.length).to.equal(2); + }); + }); + it('finds two imports from new line separated declarations', () => { + let editedFile = new InsertChange(sourceFile, 33, `import {Routes} from '@angular/routes'`); + return editedFile + .apply() + .then(() => { + let rootNode = getRootNode(sourceFile); + let nodes = findNodes(rootNode, ts.SyntaxKind.ImportDeclaration); + expect(nodes.length).to.equal(2); + }); + }); +}); + +describe('ast-utils: insertAfterLastOccurrence', () => { + const sourceFile = 'tmp/tmp.ts'; + beforeEach(() => { + let mockDrive = { + 'tmp': { + 'tmp.ts': '' + } + }; + mockFs(mockDrive); + }); + + afterEach(() => { + mockFs.restore(); + }); + + it('inserts at beginning of file', () => { + let imports = getNodesOfKind(ts.SyntaxKind.ImportDeclaration, sourceFile); + return insertAfterLastOccurrence(imports, `\nimport { Router } from '@angular/router';`, + sourceFile, 0) + .apply() + .then(() => { + return readFile(sourceFile, 'utf8'); + }).then((content) => { + let expected = '\nimport { Router } from \'@angular/router\';'; + expect(content).to.equal(expected); + }); + }); + it('throws an error if first occurence with no fallback position', () => { + let imports = getNodesOfKind(ts.SyntaxKind.ImportDeclaration, sourceFile); + expect(() => insertAfterLastOccurrence(imports, `import { Router } from '@angular/router';`, + sourceFile)).to.throw(Error); + }); + it('inserts after last import', () => { + let content = `import { foo, bar } from 'fizz';`; + let editedFile = new InsertChange(sourceFile, 0, content); + return editedFile + .apply() + .then(() => { + let imports = getNodesOfKind(ts.SyntaxKind.ImportDeclaration, sourceFile); + return insertAfterLastOccurrence(imports, ', baz', sourceFile, + 0, ts.SyntaxKind.Identifier) + .apply(); + }).then(() => { + return readFile(sourceFile, 'utf8'); + }).then(newContent => expect(newContent).to.equal(`import { foo, bar, baz } from 'fizz';`)); + }); + it('inserts after last import declaration', () => { + let content = `import * from 'foo' \n import { bar } from 'baz'`; + let editedFile = new InsertChange(sourceFile, 0, content); + return editedFile + .apply() + .then(() => { + let imports = getNodesOfKind(ts.SyntaxKind.ImportDeclaration, sourceFile); + return insertAfterLastOccurrence(imports, `\nimport Router from '@angular/router'`, + sourceFile) + .apply(); + }).then(() => { + return readFile(sourceFile, 'utf8'); + }).then(newContent => { + let expected = `import * from 'foo' \n import { bar } from 'baz'` + + `\nimport Router from '@angular/router'`; + expect(newContent).to.equal(expected); + }); + }); + it('inserts correctly if no imports', () => { + let content = `import {} from 'foo'`; + let editedFile = new InsertChange(sourceFile, 0, content); + return editedFile + .apply() + .then(() => { + let imports = getNodesOfKind(ts.SyntaxKind.ImportDeclaration, sourceFile); + return insertAfterLastOccurrence(imports, ', bar', sourceFile, undefined, + ts.SyntaxKind.Identifier) + .apply(); + }).catch(() => { + return readFile(sourceFile, 'utf8'); + }) + .then(newContent => { + expect(newContent).to.equal(content); + // use a fallback position for safety + let imports = getNodesOfKind(ts.SyntaxKind.ImportDeclaration, sourceFile); + let pos = findNodes(imports.sort((a, b) => a.pos - b.pos).pop(), + ts.SyntaxKind.CloseBraceToken).pop().pos; + return insertAfterLastOccurrence(imports, ' bar ', + sourceFile, pos, ts.SyntaxKind.Identifier) + .apply(); + }).then(() => { + return readFile(sourceFile, 'utf8'); + }).then(newContent => { + expect(newContent).to.equal(`import { bar } from 'foo'`); + }); + }); +}); + + /** + * Gets node of kind kind from sourceFile + */ +function getNodesOfKind(kind: ts.SyntaxKind, sourceFile: string) { + return findNodes(getRootNode(sourceFile), kind); +} + +function getRootNode(sourceFile: string) { + return ts.createSourceFile(sourceFile, fs.readFileSync(sourceFile).toString(), + ts.ScriptTarget.ES6, true); +}