From 801c93388cfbbc26eab19f5aa637b99df82fb01b Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Fri, 29 Jan 2016 14:19:42 -0600 Subject: [PATCH] Various web updates This doesn't implement any features, but is fairly large and I would like to get it merged. Includes: * Use tslint in webpack instead of on its own * Add code style conventions * Name the "page" components accordingly * Various other cleanup things --- web/README.md | 27 ++ web/app/AppComponent.ts | 43 +- web/app/actions.ts | 8 + web/app/app.scss | 8 +- web/app/boot.ts | 5 +- web/app/header/HeaderComponent.ts | 12 +- web/app/header/_header.scss | 4 +- .../HomePageComponent.ts} | 2 +- .../_home.scss => home-page/_home-page.scss} | 0 web/app/initialState.ts | 22 + .../PackageListComponent.ts | 8 +- .../PackagePageComponent.ts} | 57 ++- .../_package-page.scss} | 0 .../PackagesPageComponent.ts} | 6 +- .../_packages-page.scss} | 0 web/app/rootReducer.ts | 49 +- .../SignInPageComponent.ts} | 6 +- .../_sign-in-page.scss} | 0 web/app/util.ts | 4 +- web/doc/files.md | 13 +- web/npm-shrinkwrap.json | 428 ++++++++++++++++-- web/package.json | 5 +- web/webpack.config.js | 12 +- 23 files changed, 566 insertions(+), 153 deletions(-) rename web/app/{home/HomeComponent.ts => home-page/HomePageComponent.ts} (97%) rename web/app/{home/_home.scss => home-page/_home-page.scss} (100%) create mode 100644 web/app/initialState.ts rename web/app/{package => package-page}/PackageListComponent.ts (85%) rename web/app/{package/PackageComponent.ts => package-page/PackagePageComponent.ts} (62%) rename web/app/{package/_package.scss => package-page/_package-page.scss} (100%) rename web/app/{packages/PackagesComponent.ts => packages-page/PackagesPageComponent.ts} (93%) rename web/app/{packages/_packages.scss => packages-page/_packages-page.scss} (100%) rename web/app/{sign-in/SignInComponent.ts => sign-in-page/SignInPageComponent.ts} (89%) rename web/app/{sign-in/_sign-in.scss => sign-in-page/_sign-in-page.scss} (100%) diff --git a/web/README.md b/web/README.md index a2fd359071..b9e74c5c98 100644 --- a/web/README.md +++ b/web/README.md @@ -33,6 +33,33 @@ TASK_NAME`. * `repl`: Start a TypeScript REPL * `start`: Watch for changes and start a development server running on port 3000 +### Code Style Conventions + +These are guidelines for how to structure and format code in the application. + +* TypeScript is linted with [TSLint](http://palantir.github.io/tslint/). The + rules followed in this repository are in the [tslint.json](tslint.json) file. + Check your code with `npm run lint-js`. +* SCSS is linted with [Sass Lint](https://github.com/sasstools/sass-lint). The + rules followed in this repository are in the [.sass-lint.yml](.sass-lint.yml) + file. Check your code with `npm run lint-css`. +* TypeScript files should be named the same name as their default export (or the + main thing they are concerned with, if there is no default export), so if a + file has `export default class AppComponent {}`, it should be named + AppComponent.ts. If a module exports many things, it should given an + appropriate name and use camelCase. +* Directories should be made for components and their associated files when + there is more than one file that pertains to a component. +* Directories that end in -page/ and components that are SomethingPageComponent + are "page components", meaning they represent something that functions as a + page in the app. All of these should be used in the `RouteConfig` of the + AppComponent. +* Directory names and SCSS file names should use snake-case. +* SCSS files should start with an underscore and use snake-case: + \_my-thing.scss. (in Sass, files that start with underscore are partials and + can be loaded into other files. [app/app.scss](app/app.scss) imports these + files.) + ## "Production" To build the JavaScript and CSS files, run `npm run build`. diff --git a/web/app/AppComponent.ts b/web/app/AppComponent.ts index 8e84fe3dfa..850a4c8bf9 100644 --- a/web/app/AppComponent.ts +++ b/web/app/AppComponent.ts @@ -5,17 +5,17 @@ // is made available under an open source license such as the Apache 2.0 License. import {AppStore} from "./AppStore"; -import {Component, Inject} from "angular2/core"; +import {Component} from "angular2/core"; import {HeaderComponent} from "./header/HeaderComponent"; -import {HomeComponent} from "./home/HomeComponent"; -import {PackageComponent} from "./package/PackageComponent"; -import {PackagesComponent} from "./packages/PackagesComponent"; -import {Router, RouteConfig, ROUTER_DIRECTIVES} from "angular2/router"; -import {SignInComponent} from "./sign-in/SignInComponent"; +import {HomePageComponent} from "./home-page/HomePageComponent"; +import {PackagePageComponent} from "./package-page/PackagePageComponent"; +import {PackagesPageComponent} from "./packages-page/PackagesPageComponent"; +import {RouteConfig, Router, RouterOutlet} from "angular2/router"; +import {SignInPageComponent} from "./sign-in-page/SignInPageComponent"; import {routeChange} from "./actions"; @Component({ - directives: [ROUTER_DIRECTIVES, HeaderComponent], + directives: [HeaderComponent, RouterOutlet], selector: "bldr", template: `
@@ -31,27 +31,32 @@ import {routeChange} from "./actions"; }) @RouteConfig([ - { path: "/", name: "Home", component: HomeComponent }, - { path: "/packages", name: "Packages", component: PackagesComponent }, - { path: "/packages/:derivation", name: "PackagesForDerivation", component: PackagesComponent }, + { path: "/", name: "Home", component: HomePageComponent }, + { path: "/packages", name: "Packages", component: PackagesPageComponent }, + { path: "/packages/:derivation", name: "PackagesForDerivation", + component: PackagesPageComponent }, { path: "/packages/:derivation/:name/:version/:release", name: "Package", - component: PackageComponent }, - { path: "/sign-in", name: "Sign In", component: SignInComponent }, + component: PackagePageComponent }, + { path: "/sign-in", name: "Sign In", component: SignInPageComponent }, ]) export class AppComponent { - private state; - constructor(private router: Router, private store: AppStore) { - this.state = store.getState(); - + // Whenever the Angular route has an event, dispatch an event with the new + // route data. router.subscribe(value => store.dispatch(routeChange(value))); + // Listen for changes on the state. store.subscribe(state => { - let requestedRoute = store.getState().requestedRoute; - console.log("New state received ", state.toObject()); - + // If the state has a requestedRoute attribute, use the router to navigate + // to the route that was requested. + const requestedRoute = state.requestedRoute; if (requestedRoute) { router.navigate(requestedRoute); } + + // For now, just dump the state in the console whenever it changes. + console.log("New state received ", state.toObject()); }); } + + get state() { return this.store.getState(); } } diff --git a/web/app/actions.ts b/web/app/actions.ts index 26d99b8623..097e155503 100644 --- a/web/app/actions.ts +++ b/web/app/actions.ts @@ -6,6 +6,7 @@ export const ROUTE_CHANGE = "ROUTE_CHANGE"; export const ROUTE_REQUESTED = "ROUTE_REQUESTED"; +export const SET_CURRENT_PACKAGE = "SET_CURRENT_PACKAGE"; export const SET_VISIBLE_PACKAGES = "SET_VISIBLE_PACKAGES"; export const SIGN_IN_ATTEMPT = "SIGN_IN_ATTEMPT"; export const SIGN_UP_ATTEMPT = "SIGN_UP_ATTEMPT"; @@ -51,6 +52,13 @@ export function requestRoute(requestedRoute: Array) { }; } +export function setCurrentPackage(pkg) { + return { + type: SET_CURRENT_PACKAGE, + payload: pkg, + }; +} + export function toggleUserNavMenu() { return { type: TOGGLE_USER_NAV_MENU diff --git a/web/app/app.scss b/web/app/app.scss index 28e0f64524..d4e6c4d219 100644 --- a/web/app/app.scss +++ b/web/app/app.scss @@ -10,10 +10,10 @@ @import "header/header"; @import "header/user-nav/user-nav"; -@import "home/home"; -@import "package/package"; -@import "packages/packages"; -@import "sign-in/sign-in"; +@import "home-page/home-page"; +@import "package-page/package-page"; +@import "packages-page/packages-page"; +@import "sign-in-page/sign-in-page"; @import "sign-up-form/sign-up-form"; .bldr-container { diff --git a/web/app/boot.ts b/web/app/boot.ts index 48a31a0aef..b5dd50da0f 100644 --- a/web/app/boot.ts +++ b/web/app/boot.ts @@ -7,10 +7,13 @@ import "angular2/bundles/angular2-polyfills"; import {AppComponent} from "./AppComponent"; import {AppStore} from "./AppStore"; -import {ROUTER_PROVIDERS} from "angular2/router"; +import {bind} from "angular2/core"; +import {LocationStrategy, HashLocationStrategy, ROUTER_PROVIDERS} from "angular2/router"; import {bootstrap} from "angular2/platform/browser"; bootstrap(AppComponent, [ AppStore, ROUTER_PROVIDERS, +// Temporarily commenting this out +// bind(LocationStrategy).toClass(HashLocationStrategy) ]); diff --git a/web/app/header/HeaderComponent.ts b/web/app/header/HeaderComponent.ts index e5f9d346e2..b3c7d19f05 100644 --- a/web/app/header/HeaderComponent.ts +++ b/web/app/header/HeaderComponent.ts @@ -5,12 +5,12 @@ // is made available under an open source license such as the Apache 2.0 License. import {Component} from "angular2/core"; -import {ROUTER_DIRECTIVES} from "angular2/router"; +import {RouterLink} from "angular2/router"; import {UserNavComponent} from "./user-nav/UserNavComponent"; @Component({ - directives: [ROUTER_DIRECTIVES, UserNavComponent], - inputs: ["appName"], + directives: [RouterLink, UserNavComponent], + inputs: ["appName", "routeParams"], selector: "bldr-header", template: `
@@ -29,12 +29,6 @@ import {UserNavComponent} from "./user-nav/UserNavComponent"; }) export class HeaderComponent { - // Ok I get that some of the state exists in the URL, but why aren't you using - // something like RouteParams instead of window.location? - // - // Because I was having some trouble with those and this works. - // - // See also https://github.com/angular/angular/issues/4016 get onAllPackages() { return window.location.pathname === "/packages" && window.location.search.replace("?show=", "") !== "mine"; diff --git a/web/app/header/_header.scss b/web/app/header/_header.scss index 6fbe49fbad..24f5c97a9c 100644 --- a/web/app/header/_header.scss +++ b/web/app/header/_header.scss @@ -3,14 +3,14 @@ margin-bottom: $base-spacing; h1 { - @include span-columns(1); + @include span-columns(2); display: inline; margin-bottom: 0; } &-links { padding: 0.3em; - @include span-columns(10); + @include span-columns(9); display: inline-block; ul { diff --git a/web/app/home/HomeComponent.ts b/web/app/home-page/HomePageComponent.ts similarity index 97% rename from web/app/home/HomeComponent.ts rename to web/app/home-page/HomePageComponent.ts index c65808f80a..91ac06daba 100644 --- a/web/app/home/HomeComponent.ts +++ b/web/app/home-page/HomePageComponent.ts @@ -24,7 +24,7 @@ import {requestRoute} from "../actions"; `, }) -export class HomeComponent { +export class HomePageComponent { constructor(private store: AppStore) {} ngOnInit() { diff --git a/web/app/home/_home.scss b/web/app/home-page/_home-page.scss similarity index 100% rename from web/app/home/_home.scss rename to web/app/home-page/_home-page.scss diff --git a/web/app/initialState.ts b/web/app/initialState.ts new file mode 100644 index 0000000000..ba58b137bd --- /dev/null +++ b/web/app/initialState.ts @@ -0,0 +1,22 @@ +/// + +import * as Immutable from "immutable"; +import packages from "../fixtures/packages.ts"; + +export default Immutable.Record({ + appName: "bldr", + currentPackage: null, + currentYear: new Date().getFullYear(), + email: null, + isSignUpFormSubmitted: false, + isSignedIn: true, + isUserNavOpen: false, + packages, + password: null, + requestedRoute: null, + route: null, + username: "smith", + visiblePackages: [], +})(); + + diff --git a/web/app/package/PackageListComponent.ts b/web/app/package-page/PackageListComponent.ts similarity index 85% rename from web/app/package/PackageListComponent.ts rename to web/app/package-page/PackageListComponent.ts index e50d29a322..ed2c4a26ed 100644 --- a/web/app/package/PackageListComponent.ts +++ b/web/app/package-page/PackageListComponent.ts @@ -5,11 +5,11 @@ // is made available under an open source license such as the Apache 2.0 License. import {Component} from "angular2/core"; -import {RouterLink, RouteParams} from "angular2/router"; +import {RouterLink} from "angular2/router"; import {isPackage, packageString} from "../util"; @Component({ - inputs: ["packages"], + inputs: ["currentPackage", "packages"], directives: [RouterLink], selector: "package-list", template: ` @@ -28,8 +28,8 @@ import {isPackage, packageString} from "../util"; }) export class PackageListComponent { - constructor(private routeParams: RouteParams) {} + private currentPackage: Object; + private packages: Array; private isPackage(x, y) { return isPackage(x, y); } private packageString(pkg) { return packageString(pkg); } - get currentPackage() { return this.routeParams.params; } } diff --git a/web/app/package/PackageComponent.ts b/web/app/package-page/PackagePageComponent.ts similarity index 62% rename from web/app/package/PackageComponent.ts rename to web/app/package-page/PackagePageComponent.ts index 7fd0bb0487..2e9cf6cebe 100644 --- a/web/app/package/PackageComponent.ts +++ b/web/app/package-page/PackagePageComponent.ts @@ -4,12 +4,14 @@ // this file ("Licensee") apply to Licensee's use of the Software until such time that the Software // is made available under an open source license such as the Apache 2.0 License. +import query from "../query"; import {AppStore} from "../AppStore"; import {Component} from "angular2/core"; -import {RouteParams, RouterLink} from "angular2/router"; +import {OnInit} from "angular2/core"; import {PackageListComponent} from "./PackageListComponent"; -import {packageString} from "../util"; -import query from "../query"; +import {RouteParams, RouterLink} from "angular2/router"; +import {isPackage, packageString} from "../util"; +import {setCurrentPackage} from "../actions"; @Component({ directives: [PackageListComponent, RouterLink], @@ -17,7 +19,7 @@ import query from "../query";

Not Found

-

{{currentPackageIdString}} does not exist.

+

{{packageString(package)}} does not exist.

Here's how you would make it: …

@@ -48,54 +50,61 @@ import query from "../query";

Available Versions

- +

Releases of version {{package.version}}

- +

Build Dependencies

- +

Runtime Dependencies

- +
`, }) -export class PackageComponent { - private currentPackageParams; - private allPackages; +export class PackagePageComponent implements OnInit { private releases; private versions; constructor (private routeParams: RouteParams, private store: AppStore) { - this.allPackages = this.store.getState().packages; - this.currentPackageParams = this.routeParams.params; this.releases = query(this.allPackages). allReleasesForPackageVersion(this.package). toArray(); this.versions = query(this.allPackages). allVersionsForPackage(this.package). toArray(); - console.log(this.versions); } - get currentPackageIdString() { - return packageString(this.currentPackageParams); - } + // Initially set up the package to be whatever comes from the params, + // so we can query for its versions and releases. In ngOnInit, we'll + // populate more data by dispatching setCurrentPackage. + get package() { + const currentPackageFromState = this.store.getState().currentPackage; + const params = this.routeParams.params; - get package () { - return query(this.allPackages). - fromParams(this.currentPackageParams). - first(); + // Use the currentPackage from the state if it's the same package we want + // here. + if (isPackage(currentPackageFromState || {}, params)) { + return currentPackageFromState; + } else { + return params; + } } - packageString(pkg) { - return packageString(pkg); - } + get allPackages() { return this.store.getState().packages; } + + ngOnInit() { this.store.dispatch(setCurrentPackage(this.package)); } + + packageString(params) { return packageString(params); } } diff --git a/web/app/package/_package.scss b/web/app/package-page/_package-page.scss similarity index 100% rename from web/app/package/_package.scss rename to web/app/package-page/_package-page.scss diff --git a/web/app/packages/PackagesComponent.ts b/web/app/packages-page/PackagesPageComponent.ts similarity index 93% rename from web/app/packages/PackagesComponent.ts rename to web/app/packages-page/PackagesPageComponent.ts index d0b65b1067..834828bea9 100644 --- a/web/app/packages/PackagesComponent.ts +++ b/web/app/packages-page/PackagesPageComponent.ts @@ -5,8 +5,8 @@ // is made available under an open source license such as the Apache 2.0 License. import {AppStore} from "../AppStore"; -import {Component} from "angular2/core"; -import {RouteParams, Router, RouterLink} from "angular2/router"; +import {Component, OnInit} from "angular2/core"; +import {RouteParams, RouterLink} from "angular2/router"; import {filterPackagesBy, requestRoute} from "../actions"; @Component({ @@ -39,7 +39,7 @@ import {filterPackagesBy, requestRoute} from "../actions"; ` }) -export class PackagesComponent { +export class PackagesPageComponent implements OnInit { constructor(private store: AppStore, private routeParams: RouteParams) {} get derivation() { diff --git a/web/app/packages/_packages.scss b/web/app/packages-page/_packages-page.scss similarity index 100% rename from web/app/packages/_packages.scss rename to web/app/packages-page/_packages-page.scss diff --git a/web/app/rootReducer.ts b/web/app/rootReducer.ts index 580135cf72..e7eabbc629 100644 --- a/web/app/rootReducer.ts +++ b/web/app/rootReducer.ts @@ -4,64 +4,61 @@ // this file ("Licensee") apply to Licensee's use of the Software until such time that the Software // is made available under an open source license such as the Apache 2.0 License. -/// - -import * as Immutable from "immutable"; import * as actionTypes from "./actions"; -import packages from "../fixtures/packages.ts"; +import initialState from "./initialState"; import query from "./query"; -const initialState = Immutable.Record({ - appName: "bldr", - currentYear: new Date().getFullYear(), - email: null, - isSignUpFormSubmitted: false, - isSignedIn: true, - isUserNavOpen: false, - packages, - password: null, - requestedRoute: null, - route: null, - username: "smith", - visiblePackages: [], -})(); - export function rootReducer(state = initialState, action) { switch (action.type) { + case actionTypes.ROUTE_CHANGE: return state.set("route", action.payload). set("requestedRoute", null); + case actionTypes.SIGN_UP_ATTEMPT: return state. set("isSignUpFormSubmitted", true). set("username", action.payload.username). set("email", action.payload.email). set("password", action.payload.password); + case actionTypes.SIGN_IN_ATTEMPT: return state. set("username", action.payload.username). set("isSignedIn", true); + case actionTypes.SIGN_OUT: return state. set("isSignUpFormSubmitted", false). set("isSignedIn", false); + case actionTypes.ROUTE_REQUESTED: - return state.set("requestedRoute", action.payload); + return state. + set("requestedRoute", action.payload); + + // Query the list of packages to set the currentPackage data. + case actionTypes.SET_CURRENT_PACKAGE: + return state.set("currentPackage", + query(state.get("packages")). + fromParams(action.payload).first()); + case actionTypes.SET_VISIBLE_PACKAGES: const q = query(state.get("packages")); + let p; if (action.payload.filter === "all") { - return state.set("visiblePackages", q.allMostRecent().toArray()); + p = q.allMostRecent(); } else if (action.payload.filter === "mine") { - return state.set("visiblePackages", q.allMostRecentForDerivation( - "smith").toArray()); + p = q.allMostRecentForDerivation("smith"); } else if (action.payload.derivation) { - return state.set("visiblePackages", q.allMostRecentForDerivation( - action.payload.derivation).toArray()); + p = q.allMostRecentForDerivation(action.payload.derivation); } else { - return state.set("visiblePackages", q.allMostRecent().toArray()); + p = q.allMostRecent(); } + return state.set("visiblePackages", p.toArray()); + case actionTypes.TOGGLE_USER_NAV_MENU: return state.set("isUserNavOpen", !state.get("isUserNavOpen")); + default: return state; } diff --git a/web/app/sign-in/SignInComponent.ts b/web/app/sign-in-page/SignInPageComponent.ts similarity index 89% rename from web/app/sign-in/SignInComponent.ts rename to web/app/sign-in-page/SignInPageComponent.ts index e29330362c..c95b706fc1 100644 --- a/web/app/sign-in/SignInComponent.ts +++ b/web/app/sign-in-page/SignInPageComponent.ts @@ -1,4 +1,4 @@ -// Copyright:: Copyright (c) 2015-2016 Chef Software, Inc. +// Copyright:: Copyright (c) 2016 Chef Software, Inc. // // The terms of the Evaluation Agreement (Bldr) between Chef Software Inc. and the party accessing // this file ("Licensee") apply to Licensee's use of the Software until such time that the Software @@ -7,7 +7,7 @@ import {Component} from "angular2/core"; import {Router} from "angular2/router"; import {AppStore} from "../AppStore"; -import {attemptSignIn, requestRoute} from "../actions" +import {attemptSignIn, requestRoute} from "../actions"; @Component({ template: ` @@ -22,7 +22,7 @@ import {attemptSignIn, requestRoute} from "../actions" ` }) -export class SignInComponent { +export class SignInPageComponent { constructor(private store: AppStore) {} get username() { diff --git a/web/app/sign-in/_sign-in.scss b/web/app/sign-in-page/_sign-in-page.scss similarity index 100% rename from web/app/sign-in/_sign-in.scss rename to web/app/sign-in-page/_sign-in-page.scss diff --git a/web/app/util.ts b/web/app/util.ts index 4f8412624b..655fe45c9e 100644 --- a/web/app/util.ts +++ b/web/app/util.ts @@ -1,11 +1,11 @@ // Compare the identifying attributes of two packages to see if they are the // same -export function isPackage(x, y) { +export function isPackage(x = {}, y = {}) { return packageString(x) === packageString(y); }; // Take a package and make a string separated by slashes of its identifying // attributes -export function packageString (o) { +export function packageString (o = {}) { return `${o["derivation"]}/${o["name"]}/${o["version"]}/${o["release"]}`; }; diff --git a/web/doc/files.md b/web/doc/files.md index 507888be24..4fbd47ea79 100644 --- a/web/doc/files.md +++ b/web/doc/files.md @@ -5,15 +5,14 @@ all of these are present when you first check out the app, but they may appear after running some `npm` scripts (`npm install`, `npm start`, etc.) and using the app. app/ # The app/ directory contains the code that makes up the app. - home/ # The top level directories contain the app's components. - package/ # For example, the package/ directory has + home-page/ # The top level directories contain the app's components. + package-page/ # For example, the package-page/ directory has _package.scss # [Sass](http://sass-lang.com/) SCSS stylesheet, - PackageComponent.ts # a component that represents a page, + PackagePageComponent.ts # a component that represents a page, PackageListComponent.ts # and possibly more components that are used by that one. - packages/ - sign-in/ - sign-up-form/ - user-nav/ + packages-page/ # Directories that end in -page/ contain + sign-in-page/ # components that act like pages. + sign-up-form/ # But other directories have components that do not. actions.ts # [Actions](http://redux.js.org/docs/basics/Actions.html). app.scss # Main entry point for the SCSS. AppComponent.ts # The top level component of the app. diff --git a/web/npm-shrinkwrap.json b/web/npm-shrinkwrap.json index 144fc0ab12..4c13c580e5 100644 --- a/web/npm-shrinkwrap.json +++ b/web/npm-shrinkwrap.json @@ -616,16 +616,16 @@ "from": "ini@~1.3.0", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz" }, - "is-my-json-valid": { - "version": "2.12.3", - "from": "is-my-json-valid@^2.12.3", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.12.3.tgz" - }, "is-property": { "version": "1.0.2", "from": "is-property@^1.0.0", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz" }, + "is-my-json-valid": { + "version": "2.12.3", + "from": "is-my-json-valid@^2.12.3", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.12.3.tgz" + }, "is-typedarray": { "version": "1.0.0", "from": "is-typedarray@~1.0.0", @@ -721,16 +721,16 @@ "from": "mkdirp@>=0.3.0 <0.4.0||>=0.4.0 <0.5.0||>=0.5.0 <0.6.0", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz" }, - "npmlog": { - "version": "2.0.0", - "from": "npmlog@~2.0.0", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.0.tgz" - }, "node-uuid": { "version": "1.4.7", "from": "node-uuid@~1.4.7", "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz" }, + "npmlog": { + "version": "2.0.0", + "from": "npmlog@~2.0.0", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.0.tgz" + }, "oauth-sign": { "version": "0.8.0", "from": "oauth-sign@~0.8.0", @@ -6002,89 +6002,316 @@ } } }, - "systemjs": { - "version": "0.19.6", - "from": "https://registry.npmjs.org/systemjs/-/systemjs-0.19.6.tgz", - "resolved": "https://registry.npmjs.org/systemjs/-/systemjs-0.19.6.tgz", - "dependencies": { - "es6-module-loader": { - "version": "0.17.10", - "from": "https://registry.npmjs.org/es6-module-loader/-/es6-module-loader-0.17.10.tgz", - "resolved": "https://registry.npmjs.org/es6-module-loader/-/es6-module-loader-0.17.10.tgz" - }, - "when": { - "version": "3.7.7", - "from": "https://registry.npmjs.org/when/-/when-3.7.7.tgz", - "resolved": "https://registry.npmjs.org/when/-/when-3.7.7.tgz" - } - } - }, "ts-loader": { "version": "0.8.0", - "from": "ts-loader@*", + "from": "https://registry.npmjs.org/ts-loader/-/ts-loader-0.8.0.tgz", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-0.8.0.tgz", "dependencies": { "arrify": { "version": "1.0.1", - "from": "arrify@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" }, "colors": { "version": "1.1.2", - "from": "colors@>=1.0.3 <2.0.0", + "from": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz" }, "enhanced-resolve": { "version": "0.9.1", - "from": "enhanced-resolve@>=0.9.0 <0.10.0", + "from": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", "dependencies": { "tapable": { "version": "0.1.10", - "from": "tapable@>=0.1.8 <0.2.0", + "from": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz" }, "memory-fs": { "version": "0.2.0", - "from": "memory-fs@>=0.2.0 <0.3.0", + "from": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz" }, "graceful-fs": { "version": "4.1.2", - "from": "graceful-fs@>=4.1.2 <5.0.0", + "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" } } }, "loader-utils": { "version": "0.2.12", - "from": "loader-utils@>=0.2.6 <0.3.0", + "from": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.12.tgz", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.12.tgz", "dependencies": { "big.js": { "version": "3.1.3", - "from": "big.js@>=3.0.2 <4.0.0", + "from": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz", "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz" }, "json5": { "version": "0.4.0", - "from": "json5@>=0.4.0 <0.5.0", + "from": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz", "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz" } } }, "object-assign": { "version": "2.1.1", - "from": "object-assign@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz" }, "semver": { "version": "5.1.0", - "from": "semver@>=5.0.1 <6.0.0", + "from": "https://registry.npmjs.org/semver/-/semver-5.1.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.1.0.tgz" } } }, + "ts-node": { + "version": "0.5.5", + "from": "ts-node@*", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-0.5.5.tgz", + "dependencies": { + "arrify": { + "version": "1.0.1", + "from": "arrify@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + }, + "chalk": { + "version": "1.1.1", + "from": "chalk@>=1.1.1 <2.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz", + "dependencies": { + "ansi-styles": { + "version": "2.1.0", + "from": "ansi-styles@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz" + }, + "escape-string-regexp": { + "version": "1.0.4", + "from": "escape-string-regexp@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.4.tgz" + }, + "has-ansi": { + "version": "2.0.0", + "from": "has-ansi@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "dependencies": { + "ansi-regex": { + "version": "2.0.0", + "from": "ansi-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" + } + } + }, + "strip-ansi": { + "version": "3.0.0", + "from": "strip-ansi@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", + "dependencies": { + "ansi-regex": { + "version": "2.0.0", + "from": "ansi-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" + } + } + }, + "supports-color": { + "version": "2.0.0", + "from": "supports-color@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" + } + } + }, + "diff": { + "version": "2.2.1", + "from": "diff@>=2.1.1 <3.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-2.2.1.tgz" + }, + "make-error": { + "version": "1.1.0", + "from": "make-error@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.1.0.tgz" + }, + "minimist": { + "version": "1.2.0", + "from": "minimist@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" + }, + "source-map-support": { + "version": "0.4.0", + "from": "source-map-support@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.0.tgz", + "dependencies": { + "source-map": { + "version": "0.1.32", + "from": "source-map@0.1.32", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz", + "dependencies": { + "amdefine": { + "version": "1.0.0", + "from": "amdefine@>=0.0.4", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz" + } + } + } + } + }, + "tsconfig": { + "version": "2.2.0", + "from": "tsconfig@>=2.1.1 <3.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-2.2.0.tgz", + "dependencies": { + "array-uniq": { + "version": "1.0.2", + "from": "array-uniq@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz" + }, + "globby": { + "version": "4.0.0", + "from": "globby@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-4.0.0.tgz", + "dependencies": { + "array-union": { + "version": "1.0.1", + "from": "array-union@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.1.tgz" + }, + "glob": { + "version": "6.0.4", + "from": "glob@>=6.0.1 <7.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "dependencies": { + "inflight": { + "version": "1.0.4", + "from": "inflight@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "minimatch": { + "version": "3.0.0", + "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.0.tgz", + "dependencies": { + "brace-expansion": { + "version": "1.1.2", + "from": "brace-expansion@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.2.tgz", + "dependencies": { + "balanced-match": { + "version": "0.3.0", + "from": "balanced-match@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.3.0.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + } + } + } + } + }, + "once": { + "version": "1.3.3", + "from": "once@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + }, + "path-is-absolute": { + "version": "1.0.0", + "from": "path-is-absolute@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz" + } + } + }, + "object-assign": { + "version": "4.0.1", + "from": "object-assign@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.0.1.tgz" + }, + "pify": { + "version": "2.3.0", + "from": "pify@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" + } + } + }, + "parse-json": { + "version": "2.2.0", + "from": "parse-json@>=2.2.0 <3.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "dependencies": { + "error-ex": { + "version": "1.3.0", + "from": "error-ex@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.0.tgz", + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "from": "is-arrayish@>=0.2.1 <0.3.0", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + } + } + } + } + }, + "pinkie-promise": { + "version": "2.0.0", + "from": "pinkie-promise@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.0.tgz", + "dependencies": { + "pinkie": { + "version": "2.0.1", + "from": "pinkie@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.1.tgz" + } + } + }, + "strip-bom": { + "version": "2.0.0", + "from": "strip-bom@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "dependencies": { + "is-utf8": { + "version": "0.2.1", + "from": "is-utf8@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz" + } + } + }, + "strip-json-comments": { + "version": "2.0.0", + "from": "strip-json-comments@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.0.tgz" + } + } + }, + "xtend": { + "version": "4.0.1", + "from": "xtend@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + } + } + }, "tsd": { "version": "0.6.5", "from": "tsd@*", @@ -7385,6 +7612,119 @@ } } }, + "tslint-loader": { + "version": "2.1.0", + "from": "tslint-loader@*", + "resolved": "https://registry.npmjs.org/tslint-loader/-/tslint-loader-2.1.0.tgz", + "dependencies": { + "loader-utils": { + "version": "0.2.12", + "from": "loader-utils@>=0.2.7 <0.3.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.12.tgz", + "dependencies": { + "big.js": { + "version": "3.1.3", + "from": "big.js@>=3.0.2 <4.0.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz" + }, + "json5": { + "version": "0.4.0", + "from": "json5@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz" + } + } + }, + "mkdirp": { + "version": "0.5.1", + "from": "mkdirp@>=0.5.1 <0.6.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "dependencies": { + "minimist": { + "version": "0.0.8", + "from": "minimist@0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" + } + } + }, + "rimraf": { + "version": "2.5.1", + "from": "rimraf@>=2.4.4 <3.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.1.tgz", + "dependencies": { + "glob": { + "version": "6.0.4", + "from": "glob@>=6.0.1 <7.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "dependencies": { + "inflight": { + "version": "1.0.4", + "from": "inflight@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "minimatch": { + "version": "3.0.0", + "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.0.tgz", + "dependencies": { + "brace-expansion": { + "version": "1.1.2", + "from": "brace-expansion@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.2.tgz", + "dependencies": { + "balanced-match": { + "version": "0.3.0", + "from": "balanced-match@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.3.0.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + } + } + } + } + }, + "once": { + "version": "1.3.3", + "from": "once@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + }, + "path-is-absolute": { + "version": "1.0.0", + "from": "path-is-absolute@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz" + } + } + } + } + }, + "strip-json-comments": { + "version": "1.0.4", + "from": "strip-json-comments@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz" + } + } + }, "typescript": { "version": "1.7.5", "from": "https://registry.npmjs.org/typescript/-/typescript-1.7.5.tgz", @@ -8487,16 +8827,16 @@ "from": "inherits@*", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, - "is-my-json-valid": { - "version": "2.12.3", - "from": "is-my-json-valid@^2.12.3", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.12.3.tgz" - }, "ini": { "version": "1.3.4", "from": "ini@~1.3.0", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz" }, + "is-my-json-valid": { + "version": "2.12.3", + "from": "is-my-json-valid@^2.12.3", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.12.3.tgz" + }, "is-property": { "version": "1.0.2", "from": "is-property@^1.0.0", diff --git a/web/package.json b/web/package.json index ade02f52ff..d439e48e40 100644 --- a/web/package.json +++ b/web/package.json @@ -7,7 +7,7 @@ "build": "concurrent \"npm run build-js\" \"npm run build-css\"", "build-css": "npm run lint-css && node-sass --source-map=true --include-path=node_modules/bourbon-neat/app/assets/stylesheets --include-path=node_modules/bourbon/app/assets/stylesheets --include-path=node_modules/normalize-scss/sass --include-path=node_modules/normalize-scss/node_modules/support-for/sass --include-path=stylesheets --output=. app/app.scss", "build-css-watch": "npm run build-css && npm run build-css -- --watch", - "build-js": "npm run lint-js && webpack", + "build-js": "webpack", "build-js-watch": "npm run build-js -- --watch", "clean": "concurrent \"npm run clean-js\" \"npm run clean-css\"", "clean-css": "rm -fv app.css app.css.map", @@ -21,7 +21,7 @@ "help": "cat README.md", "repl": "ts-node", "postinstall": "tsd install", - "start": "concurrent \"npm run build-css-watch\" \"npm run build-js-watch\" \"npm run lint-css-watch\" \"npm run lint-js-watch\" \"lite-server\"" + "start": "concurrent \"npm run build-css-watch\" \"npm run build-js-watch\" \"npm run lint-css-watch\" \"lite-server\"" }, "dependencies": { "angular2": "^2.0.0-beta.1", @@ -46,6 +46,7 @@ "ts-node": "^0.5.5", "tsd": "^0.6.5", "tslint": "^3.2.2", + "tslint-loader": "^2.1.0", "typescript": "^1.7.3", "watch": "^0.17.1", "webpack": "^1.12.11" diff --git a/web/webpack.config.js b/web/webpack.config.js index 458d18de4a..b424e3fdb3 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -8,9 +8,17 @@ module.exports = { extensions: ["", ".webpack.js", ".web.js", ".ts", ".js"] }, module: { + preLoaders: [ + { test: /\.ts$/, loader: "tslint" }, + ], loaders: [ - { test: /\.ts$/, loader: "ts-loader" } + { test: /\.ts$/, loader: "ts-loader" }, + { test: "app.js", loader: "uglify" }, ], noParse: [ /angular2\/bundles\/.+/ ] - } + }, + tslint: { + emitErrors: true, + failOnHint: true, + }, }