├── tools ├── .gitignore ├── utils │ ├── project │ │ └── sample_util.ts │ ├── project.utils.ts │ ├── seed.utils.ts │ └── seed │ │ ├── tsproject.ts │ │ ├── template_locals.ts │ │ ├── watch.ts │ │ ├── clean.ts │ │ ├── code_change_tools.ts │ │ ├── tasks_tools.ts │ │ └── server.ts ├── manual_typings │ ├── project │ │ └── sample.package.d.ts │ └── seed │ │ ├── slash.d.ts │ │ ├── tildify.d.ts │ │ ├── connect-livereload.d.ts │ │ ├── tiny-lr.d.ts │ │ ├── walk.d.ts │ │ ├── open.d.ts │ │ ├── autoprefixer.d.ts │ │ ├── istream.d.ts │ │ ├── angular2-hot-loader.d.ts │ │ ├── merge-stream.d.ts │ │ ├── karma.d.ts │ │ ├── colorguard.d.ts │ │ ├── doiuse.d.ts │ │ ├── stylelint.d.ts │ │ ├── systemjs-builder.d.ts │ │ ├── cssnano.d.ts │ │ ├── express-history-api-fallback.d.ts │ │ └── postcss-reporter.d.ts ├── config.ts ├── utils.ts ├── tasks │ ├── seed │ │ ├── watch.e2e.ts │ │ ├── serve.coverage.ts │ │ ├── watch.test.ts │ │ ├── server.prod.ts │ │ ├── server.start.ts │ │ ├── watch.dev.ts │ │ ├── serve.docs.ts │ │ ├── webdriver.ts │ │ ├── clean.all.ts │ │ ├── clean.dev.ts │ │ ├── clean.prod.ts │ │ ├── karma.start.ts │ │ ├── copy.js.prod.ts │ │ ├── generate.manifest.ts │ │ ├── build.assets.dev.ts │ │ ├── build.bundles.app.ts │ │ ├── tslint.ts │ │ ├── build.js.tools.ts │ │ ├── build.js.e2e.ts │ │ ├── build.assets.prod.ts │ │ ├── e2e.ts │ │ ├── build.js.prod.ts │ │ ├── build.js.test.ts │ │ ├── build.js.dev.ts │ │ ├── build.docs.ts │ │ ├── build.bundles.ts │ │ ├── clean.tools.ts │ │ ├── check.versions.ts │ │ ├── build.index.prod.ts │ │ ├── css-lint.ts │ │ ├── build.index.dev.ts │ │ └── build.html_css.ts │ └── project │ │ └── sample.task.ts ├── env │ └── config.json ├── config │ ├── seed.config.interfaces.ts │ ├── project.config.ts │ └── seed.config.ts ├── debug.ts └── README.md ├── src └── client │ ├── typings.d.ts │ ├── app │ ├── shared │ │ ├── toolbar │ │ │ ├── toolbar.component.html │ │ │ ├── index.ts │ │ │ ├── toolbar.component.ts │ │ │ └── toolbar.component.css │ │ ├── navbar │ │ │ ├── index.ts │ │ │ ├── navbar.component.html │ │ │ ├── navbar.component.ts │ │ │ └── navbar.component.css │ │ ├── index.ts │ │ └── config │ │ │ └── env.config.ts │ ├── app.component.html │ ├── +stripe-form │ │ ├── stripe-form.component.html │ │ ├── index.ts │ │ ├── stripe-form.component.css │ │ ├── stripe-form.routes.ts │ │ └── stripe-form.component.ts │ ├── +custom-form │ │ ├── index.ts │ │ ├── custom-form.routes.ts │ │ ├── custom-form.component.css │ │ ├── custom-form.component.html │ │ └── custom-form.component.ts │ ├── app.routes.ts │ ├── hot_loader_main.ts │ ├── app.component.ts │ └── main.ts │ ├── assets │ ├── data.json │ └── svg │ │ └── more.svg │ ├── tsconfig.json │ ├── css │ └── main.css │ └── index.html ├── README.md ├── tsconfig.json ├── .gitignore ├── LICENSE ├── protractor.conf.js ├── appveyor.yml ├── tslint.json ├── gulpfile.ts ├── test-main.js ├── typings.json ├── karma.conf.js └── package.json /tools/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | *.js.map 3 | 4 | -------------------------------------------------------------------------------- /src/client/typings.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/client/app/shared/toolbar/toolbar.component.html: -------------------------------------------------------------------------------- 1 |

Angular 2 Seed

2 | 3 | -------------------------------------------------------------------------------- /tools/utils/project/sample_util.ts: -------------------------------------------------------------------------------- 1 | export function myUtil() { 2 | // Code goes here 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Demo for using Stripe with Angular 2. 4 | 5 | # License 6 | 7 | MIT 8 | 9 | -------------------------------------------------------------------------------- /tools/manual_typings/project/sample.package.d.ts: -------------------------------------------------------------------------------- 1 | // declare module "moment/moment" { 2 | // export = moment; 3 | // } 4 | -------------------------------------------------------------------------------- /src/client/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/client/assets/data.json: -------------------------------------------------------------------------------- 1 | [ 2 | "Edsger Dijkstra", 3 | "Donald Knuth", 4 | "Alan Turing", 5 | "Grace Hopper" 6 | ] 7 | -------------------------------------------------------------------------------- /src/client/app/+stripe-form/stripe-form.component.html: -------------------------------------------------------------------------------- 1 |

Default Stripe Form

2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tools/config.ts: -------------------------------------------------------------------------------- 1 | import { ProjectConfig } from './config/project.config'; 2 | 3 | const config: ProjectConfig = new ProjectConfig(); 4 | export = config; 5 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/slash.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'slash' { 2 | function slash(path: string): string; 3 | module slash {} 4 | export = slash; 5 | } 6 | -------------------------------------------------------------------------------- /tools/utils/project.utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This barrel file provides the exports for the project specific utilities. 3 | */ 4 | export * from './project/sample_util'; 5 | -------------------------------------------------------------------------------- /src/client/app/shared/navbar/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This barrel file provides the export for the shared NavbarComponent. 3 | */ 4 | export * from './navbar.component'; 5 | -------------------------------------------------------------------------------- /src/client/app/shared/toolbar/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This barrel file provides the export for the shared ToolbarComponent. 3 | */ 4 | export * from './toolbar.component'; 5 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/tildify.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'tildify' { 2 | function tildify(path: string): string; 3 | module tildify {} 4 | export = tildify; 5 | } 6 | -------------------------------------------------------------------------------- /src/client/app/shared/navbar/navbar.component.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /tools/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This barrel file provides the export for the utilities provided by the project and the seed. 3 | */ 4 | export * from './utils/project.utils'; 5 | export * from './utils/seed.utils'; 6 | -------------------------------------------------------------------------------- /src/client/app/+custom-form/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This barrel file provides the export for the lazy loaded HomeComponent. 3 | */ 4 | export * from './custom-form.component'; 5 | export * from './custom-form.routes'; 6 | 7 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/connect-livereload.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'connect-livereload' { 2 | function connectLivereload(options?: any): any; 3 | module connectLivereload {} 4 | export = connectLivereload; 5 | } 6 | -------------------------------------------------------------------------------- /tools/tasks/seed/watch.e2e.ts: -------------------------------------------------------------------------------- 1 | import { watch } from '../../utils'; 2 | 3 | /** 4 | * Executes the build process, watching for file changes and rebuilding the e2e environment. 5 | */ 6 | export = watch('build.e2e'); 7 | -------------------------------------------------------------------------------- /src/client/app/+stripe-form/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This barrel file provides the export for the lazy loaded AboutComponent. 3 | */ 4 | export * from './stripe-form.component'; 5 | export * from './stripe-form.routes'; 6 | 7 | -------------------------------------------------------------------------------- /tools/env/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "dev": { 3 | "API": "https://demo.com" 4 | }, 5 | "prod": { 6 | "API": "https://prod.com" 7 | }, 8 | "staging": { 9 | "API": "https://staging.com" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tools/tasks/seed/serve.coverage.ts: -------------------------------------------------------------------------------- 1 | import { serveCoverage } from '../../utils'; 2 | 3 | /** 4 | * Executes the build process, serving unit test coverage report using an `express` server. 5 | */ 6 | export = serveCoverage; 7 | -------------------------------------------------------------------------------- /tools/tasks/seed/watch.test.ts: -------------------------------------------------------------------------------- 1 | import { watch } from '../../utils'; 2 | 3 | /** 4 | * Executes the build process, watching for file changes and rebuilding the test environment. 5 | */ 6 | export = watch('build.test'); 7 | -------------------------------------------------------------------------------- /tools/tasks/seed/server.prod.ts: -------------------------------------------------------------------------------- 1 | import { serveProd } from '../../utils'; 2 | 3 | /** 4 | * Executes the build process, serving the files of the production environment using an `express` server. 5 | */ 6 | export = serveProd; 7 | -------------------------------------------------------------------------------- /tools/tasks/seed/server.start.ts: -------------------------------------------------------------------------------- 1 | import { serveSPA } from '../../utils'; 2 | 3 | /** 4 | * Executes the build process, serving the files of the development environment using an `express` server. 5 | */ 6 | export = serveSPA; 7 | -------------------------------------------------------------------------------- /tools/tasks/seed/watch.dev.ts: -------------------------------------------------------------------------------- 1 | import { watch } from '../../utils'; 2 | 3 | /** 4 | * Executes the build process, watching for file changes and rebuilding the development environment. 5 | */ 6 | export = watch('build.dev'); 7 | -------------------------------------------------------------------------------- /tools/tasks/seed/serve.docs.ts: -------------------------------------------------------------------------------- 1 | // import { serveDocs } from '../../utils'; 2 | // 3 | // /** 4 | // * Executes the build process, serving the application documentation using an `express` server. 5 | // */ 6 | // export = serveDocs; 7 | 8 | -------------------------------------------------------------------------------- /tools/tasks/seed/webdriver.ts: -------------------------------------------------------------------------------- 1 | import { webdriver_update } from 'gulp-protractor'; 2 | 3 | /** 4 | * Executes the build process, installing the selenium webdriver used for the protractor e2e specs. 5 | */ 6 | export = webdriver_update; 7 | -------------------------------------------------------------------------------- /tools/tasks/seed/clean.all.ts: -------------------------------------------------------------------------------- 1 | import { DIST_DIR } from '../../config'; 2 | import { clean } from '../../utils'; 3 | 4 | /** 5 | * Executes the build process, cleaning all files within the `/dist` directory. 6 | */ 7 | export = clean(DIST_DIR); 8 | -------------------------------------------------------------------------------- /src/client/app/shared/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This barrel file provides the exports for the shared resources (services, components). 3 | */ 4 | export * from './navbar/index'; 5 | export * from './toolbar/index'; 6 | export * from './config/env.config'; 7 | -------------------------------------------------------------------------------- /tools/tasks/seed/clean.dev.ts: -------------------------------------------------------------------------------- 1 | import { DEV_DEST } from '../../config'; 2 | import { clean } from '../../utils'; 3 | 4 | /** 5 | * Executes the build process, cleaning all files within the `/dist/dev` directory. 6 | */ 7 | export = clean(DEV_DEST); 8 | -------------------------------------------------------------------------------- /src/client/app/shared/config/env.config.ts: -------------------------------------------------------------------------------- 1 | // Feel free to extend this interface 2 | // depending on your app specific config. 3 | export interface IConfig { 4 | API: string; 5 | } 6 | 7 | export const Config: IConfig = JSON.parse('<%= ENV_CONFIG %>'); 8 | -------------------------------------------------------------------------------- /src/client/app/+stripe-form/stripe-form.component.css: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | padding: 0 16px; 4 | } 5 | 6 | h2 { 7 | font-size: 20px; 8 | font-weight: 500; 9 | letter-spacing: 0.005em; 10 | margin-bottom: 0; 11 | margin-top: 0.83em; 12 | } 13 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/tiny-lr.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'tiny-lr' { 2 | function tinylr(): ITinylr; 3 | module tinylr {} 4 | export = tinylr; 5 | 6 | interface ITinylr { 7 | changed(options: any): void; 8 | listen(port: number): void; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/walk.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'walk' { 2 | interface Walker { 3 | on(eventName: string, cb: Function): any; 4 | } 5 | interface Walk { 6 | walk(path: string, options: any): Walker; 7 | } 8 | const walk: Walk; 9 | export = walk; 10 | } 11 | -------------------------------------------------------------------------------- /tools/tasks/seed/clean.prod.ts: -------------------------------------------------------------------------------- 1 | import { PROD_DEST, TMP_DIR } from '../../config'; 2 | import { clean } from '../../utils'; 3 | 4 | /** 5 | * Executes the build process, cleaning all files within the `/dist/dev` and `dist/tmp` directory. 6 | */ 7 | export = clean([PROD_DEST, TMP_DIR]); 8 | -------------------------------------------------------------------------------- /src/client/app/+stripe-form/stripe-form.routes.ts: -------------------------------------------------------------------------------- 1 | import { RouterConfig } from '@angular/router'; 2 | 3 | import { StripeFormComponent } from './index'; 4 | 5 | export const StripeFormRoutes: RouterConfig = [ 6 | { 7 | path: '', 8 | component: StripeFormComponent 9 | } 10 | ]; 11 | -------------------------------------------------------------------------------- /src/client/app/+custom-form/custom-form.routes.ts: -------------------------------------------------------------------------------- 1 | import { RouterConfig } from '@angular/router'; 2 | 3 | import { CustomFormComponent } from './index'; 4 | 5 | export const CustomFormRoutes: RouterConfig = [ 6 | { 7 | path: 'custom-form', 8 | component: CustomFormComponent 9 | }, 10 | ]; 11 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/open.d.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/borisyankov/DefinitelyTyped/tree/master/open 2 | // Does not support ES2015 import (import * as open from 'open'). 3 | 4 | declare module 'open' { 5 | function open(target: string, app?: string): void; 6 | module open {} 7 | export = open; 8 | } 9 | -------------------------------------------------------------------------------- /src/client/app/+custom-form/custom-form.component.css: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | padding: 0 16px; 4 | } 5 | 6 | input { 7 | width: 250px; 8 | } 9 | 10 | ul { 11 | list-style-type: none; 12 | padding: 0 0 0 8px; 13 | } 14 | 15 | .payment-message { 16 | display: block; 17 | height: 20px; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/autoprefixer.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'autoprefixer' { 2 | 3 | interface IOptions { 4 | browsers: string[]; 5 | } 6 | 7 | interface IAutoprefixer { 8 | (opts?: IOptions): NodeJS.ReadWriteStream; 9 | } 10 | 11 | const autoprefixer: IAutoprefixer; 12 | export = autoprefixer; 13 | } 14 | -------------------------------------------------------------------------------- /tools/config/seed.config.interfaces.ts: -------------------------------------------------------------------------------- 1 | export interface InjectableDependency { 2 | src: string; 3 | inject: string | boolean; 4 | vendor?: boolean; 5 | env?: string[] | string; 6 | } 7 | 8 | export interface Environments { 9 | DEVELOPMENT: string; 10 | PRODUCTION: string; 11 | [key: string]: string; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/istream.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'isstream' { 2 | function istream(stream: any): boolean; 3 | interface Istream { 4 | isReadable(stream: any): boolean; 5 | isWritable(stream: any): boolean; 6 | isDuplex(stream: any): boolean; 7 | } 8 | module istream {} 9 | export = istream; 10 | } 11 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/angular2-hot-loader.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'angular2-hot-loader' { 2 | export interface Options { 3 | port?: number; 4 | path?: string; 5 | processPath?: Function; 6 | } 7 | export function listen(localConfig?: Options): void; 8 | export function onChange(files: string[]): void; 9 | } 10 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/merge-stream.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'merge-stream' { 2 | function mergeStream(...streams: NodeJS.ReadWriteStream[]): MergeStream; 3 | interface MergeStream extends NodeJS.ReadWriteStream { 4 | add(stream: NodeJS.ReadWriteStream): MergeStream; 5 | } 6 | module mergeStream {} 7 | export = mergeStream; 8 | } 9 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/karma.d.ts: -------------------------------------------------------------------------------- 1 | // Use this minimalistic definition file as bluebird dependency 2 | // generate a lot of errors. 3 | 4 | declare module 'karma' { 5 | var karma: IKarma; 6 | export = karma; 7 | interface IKarma { 8 | server: { 9 | start(options: any, callback: Function): void 10 | }; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/client/assets/svg/more.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /tools/tasks/seed/karma.start.ts: -------------------------------------------------------------------------------- 1 | import * as karma from 'karma'; 2 | import { join } from 'path'; 3 | 4 | /** 5 | * Executes the build process, running all unit tests using `karma`. 6 | */ 7 | export = (done: any) => { 8 | new (karma).Server({ 9 | configFile: join(process.cwd(), 'karma.conf.js'), 10 | singleRun: true 11 | }).start(done); 12 | }; 13 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/colorguard.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'colorguard' { 2 | 3 | interface IOptions { 4 | ignore?: string[]; 5 | threshold?: number; 6 | whitelist?: string[]; 7 | } 8 | 9 | interface IColorguard { 10 | (opts?: IOptions): NodeJS.ReadWriteStream; 11 | } 12 | 13 | const colorguard: IColorguard; 14 | export = colorguard; 15 | } 16 | -------------------------------------------------------------------------------- /src/client/app/shared/toolbar/toolbar.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | /** 4 | * This class represents the toolbar component. 5 | */ 6 | @Component({ 7 | moduleId: module.id, 8 | selector: 'sd-toolbar', 9 | templateUrl: 'toolbar.component.html', 10 | styleUrls: ['toolbar.component.css'] 11 | }) 12 | export class ToolbarComponent {} 13 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/doiuse.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'doiuse' { 2 | 3 | interface IOptions { 4 | browsers?: string[]; 5 | ignore?: string[]; 6 | ignoreFiles?: string[]; 7 | onFeatureUsage?: Function; 8 | } 9 | 10 | interface IDoiuse { 11 | (opts?: IOptions): NodeJS.ReadWriteStream; 12 | } 13 | 14 | const doiuse: IDoiuse; 15 | export = doiuse; 16 | } 17 | -------------------------------------------------------------------------------- /tools/utils/seed.utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This barrel file provides the export for the utilities provided by the seed. 3 | */ 4 | export * from './seed/clean'; 5 | export * from './seed/code_change_tools'; 6 | export * from './seed/server'; 7 | export * from './seed/tasks_tools'; 8 | export * from './seed/template_locals'; 9 | export * from './seed/tsproject'; 10 | export * from './seed/watch'; 11 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/stylelint.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'stylelint' { 2 | 3 | interface IOptions { 4 | config?: Object; 5 | configFile?: string; 6 | configBasedir?: string; 7 | configOverrides?: Object; 8 | } 9 | 10 | interface IStylelint { 11 | (opts?: IOptions): NodeJS.ReadWriteStream; 12 | } 13 | 14 | const stylelint: IStylelint; 15 | export = stylelint; 16 | } 17 | -------------------------------------------------------------------------------- /src/client/app/app.routes.ts: -------------------------------------------------------------------------------- 1 | import { provideRouter, RouterConfig } from '@angular/router'; 2 | 3 | import { StripeFormRoutes } from './+stripe-form/index'; 4 | import { CustomFormRoutes } from './+custom-form/index'; 5 | 6 | const routes: RouterConfig = [ 7 | ...StripeFormRoutes, 8 | ...CustomFormRoutes 9 | ]; 10 | 11 | export const APP_ROUTER_PROVIDERS = [ 12 | provideRouter(routes), 13 | ]; 14 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/systemjs-builder.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'systemjs-builder' { 2 | class Builder { 3 | constructor(configObject?: any, baseUrl?: string, configPath?: string); 4 | bundle(source: string, target: string, options?: any): Promise; 5 | buildStatic(source: string, target: string, options?: any): Promise; 6 | } 7 | 8 | module Builder {} 9 | export = Builder; 10 | } 11 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/cssnano.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'cssnano' { 2 | 3 | interface IOptions { 4 | discardComments?: { 5 | removeAll: boolean; 6 | }; 7 | discardUnused?: boolean; 8 | zindex?: boolean; 9 | reduceIdents?: boolean; 10 | } 11 | 12 | interface ICssnano { 13 | (opts?: IOptions): NodeJS.ReadWriteStream; 14 | } 15 | 16 | const cssnano: ICssnano; 17 | export = cssnano; 18 | } 19 | -------------------------------------------------------------------------------- /tools/debug.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import { argv } from 'yargs'; 3 | 4 | require('../gulpfile'); 5 | 6 | const TASK = argv['task']; 7 | 8 | if (!TASK) { 9 | throw new Error('You must specify a task name.'); 10 | } 11 | 12 | console.log('**********************'); 13 | console.log('* angular2-seed tools '); 14 | console.log('* debugging task:', TASK); 15 | console.log('**********************'); 16 | 17 | gulp.start(TASK); 18 | -------------------------------------------------------------------------------- /tools/tasks/project/sample.task.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import { join } from 'path'; 3 | 4 | import { APP_DEST, APP_SRC } from '../../config'; 5 | 6 | /** 7 | * This sample task copies all TypeScript files over to the appropiate `dist/dev|prod|test` directory, depending on the 8 | * current application environment. 9 | */ 10 | export = () => { 11 | return gulp.src(join(APP_SRC, '**/*.ts')) 12 | .pipe(gulp.dest(APP_DEST)); 13 | }; 14 | -------------------------------------------------------------------------------- /src/client/app/shared/navbar/navbar.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { ROUTER_DIRECTIVES } from '@angular/router'; 3 | 4 | /** 5 | * This class represents the navigation bar component. 6 | */ 7 | @Component({ 8 | moduleId: module.id, 9 | selector: 'sd-navbar', 10 | templateUrl: 'navbar.component.html', 11 | styleUrls: ['navbar.component.css'], 12 | directives: [ROUTER_DIRECTIVES] 13 | }) 14 | export class NavbarComponent {} 15 | -------------------------------------------------------------------------------- /src/client/app/shared/navbar/navbar.component.css: -------------------------------------------------------------------------------- 1 | :host { 2 | border-color: #e1e1e1; 3 | border-style: solid; 4 | border-width: 0 0 1px; 5 | display: block; 6 | height: 48px; 7 | padding: 0 16px; 8 | } 9 | 10 | nav a { 11 | color: #8f8f8f; 12 | font-size: 14px; 13 | font-weight: 500; 14 | line-height: 48px; 15 | margin-right: 20px; 16 | text-decoration: none; 17 | vertical-align: middle; 18 | } 19 | 20 | nav a.router-link-active { 21 | color: #106cc8; 22 | } 23 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/express-history-api-fallback.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'express-history-api-fallback' { 2 | 3 | import { RequestHandler } from 'express'; 4 | 5 | interface IOptions { 6 | maxAge?: number; 7 | root?: string; 8 | lastModified?: number; 9 | headers?: { [key: string]: string; }; 10 | dotfiles?: boolean; 11 | } 12 | 13 | function fallback(index: string, options?: IOptions): RequestHandler; 14 | 15 | module fallback {} 16 | 17 | export = fallback; 18 | } 19 | -------------------------------------------------------------------------------- /tools/tasks/seed/copy.js.prod.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import { join } from 'path'; 3 | 4 | import { APP_SRC, TMP_DIR } from '../../config'; 5 | 6 | /** 7 | * Executes the build task, copying all TypeScript files over to the `dist/tmp` directory. 8 | */ 9 | export = () => { 10 | return gulp.src([ 11 | join(APP_SRC, '**/*.ts'), 12 | '!' + join(APP_SRC, '**/*.spec.ts'), 13 | '!' + join(APP_SRC, '**/*.e2e-spec.ts') 14 | ]) 15 | .pipe(gulp.dest(TMP_DIR)); 16 | }; 17 | -------------------------------------------------------------------------------- /src/client/app/shared/toolbar/toolbar.component.css: -------------------------------------------------------------------------------- 1 | :host { 2 | background-color: #106cc8; 3 | color: rgba(255, 255, 255, 0.87); 4 | display: block; 5 | height: 48px; 6 | padding: 0 16px; 7 | } 8 | 9 | h1 { 10 | display: inline; 11 | font-size: 20px; 12 | font-weight: normal; 13 | letter-spacing: 0.1px; 14 | line-height: 48px; 15 | } 16 | 17 | more { 18 | background: url("./assets/svg/more.svg"); 19 | float: right; 20 | height: 24px; 21 | margin-top: 12px; 22 | width: 24px; 23 | } 24 | -------------------------------------------------------------------------------- /tools/manual_typings/seed/postcss-reporter.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'postcss-reporter' { 2 | 3 | interface IOptions { 4 | clearMessages?: boolean; 5 | formatter?: Function; 6 | plugins?: string[]; 7 | throwError?: boolean; 8 | sortByPosition?: boolean; 9 | positionless?: string; 10 | noIcon?: boolean; 11 | noPlugin?: boolean; 12 | } 13 | 14 | interface IPostcssReporter { 15 | (opts?: IOptions): NodeJS.ReadWriteStream; 16 | } 17 | 18 | const postcssReporter: IPostcssReporter; 19 | export = postcssReporter; 20 | } 21 | -------------------------------------------------------------------------------- /src/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "declaration": false, 6 | "removeComments": true, 7 | "noLib": false, 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "sourceMap": true, 11 | "pretty": true, 12 | "allowUnreachableCode": false, 13 | "allowUnusedLabels": false, 14 | "noImplicitAny": true, 15 | "noImplicitReturns": true, 16 | "noImplicitUseStrict": false, 17 | "noFallthroughCasesInSwitch": true 18 | }, 19 | "compileOnSave": false 20 | } 21 | -------------------------------------------------------------------------------- /tools/tasks/seed/generate.manifest.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | 3 | import { APP_DEST } from '../../config'; 4 | 5 | /** 6 | * Executes the build process, generating the manifest file using `angular2-service-worker`. 7 | */ 8 | export = () => { 9 | return require('angular2-service-worker') 10 | .gulpGenManifest({ 11 | group: [{ 12 | name: 'css', 13 | sources: gulp.src(`${APP_DEST}/**/*.css`) 14 | }, { 15 | name: 'js', 16 | sources: gulp.src(`${APP_DEST}/**/*.js`) 17 | }] 18 | }) 19 | .pipe(gulp.dest(APP_DEST)); 20 | }; 21 | -------------------------------------------------------------------------------- /src/client/app/hot_loader_main.ts: -------------------------------------------------------------------------------- 1 | // Hot loading is temporary disabled 2 | // 3 | // import { HashLocationStrategy, HashLocationStrategy } from '@angular/common'; 4 | // import { provide } from '@angular/core'; 5 | // import { ROUTER_PROVIDERS } from '@angular/router'; 6 | // import { AppComponent } from './app.component'; 7 | 8 | // System.import('//localhost:<%= HOT_LOADER_PORT %>/ng2-hot-loader') 9 | // .then(loader => { 10 | // loader.ng2HotLoaderBootstrap(AppComponent, [ 11 | // ROUTER_PROVIDERS, 12 | // provide(LocationStrategy, { useClass: HashLocationStrategy }) 13 | // ]); 14 | // }); 15 | -------------------------------------------------------------------------------- /tools/tasks/seed/build.assets.dev.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import { join } from 'path'; 3 | 4 | import { APP_DEST, APP_SRC, TEMP_FILES } from '../../config'; 5 | 6 | /** 7 | * Executes the build process, copying the assets located in `src/client` over to the appropriate 8 | * `dist/dev` directory. 9 | */ 10 | export = () => { 11 | let paths: string[] = [ 12 | join(APP_SRC, '**'), 13 | '!' + join(APP_SRC, '**', '*.ts'), 14 | '!' + join(APP_SRC, '**', '*.scss') 15 | ].concat(TEMP_FILES.map((p) => { return '!' + p; })); 16 | 17 | return gulp.src(paths) 18 | .pipe(gulp.dest(APP_DEST)); 19 | }; 20 | -------------------------------------------------------------------------------- /tools/utils/seed/tsproject.ts: -------------------------------------------------------------------------------- 1 | import * as gulpLoadPlugins from 'gulp-load-plugins'; 2 | 3 | const plugins = gulpLoadPlugins(); 4 | 5 | let tsProject: any; 6 | 7 | /** 8 | * Creates a TypeScript project with the given options using the gulp typescript plugin. 9 | * @param {Object} options - The additional options for the project configuration. 10 | */ 11 | export function makeTsProject(options?: Object) { 12 | if (!tsProject) { 13 | const config = Object.assign({ 14 | typescript: require('typescript') 15 | }, options); 16 | tsProject = plugins.typescript.createProject('tsconfig.json', config); 17 | } 18 | return tsProject; 19 | } 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "declaration": false, 6 | "removeComments": true, 7 | "noLib": false, 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "sourceMap": true, 11 | "pretty": true, 12 | "allowUnreachableCode": false, 13 | "allowUnusedLabels": false, 14 | "noImplicitAny": true, 15 | "noImplicitReturns": true, 16 | "noImplicitUseStrict": false, 17 | "noFallthroughCasesInSwitch": true 18 | }, 19 | "exclude": [ 20 | "node_modules", 21 | "dist", 22 | "typings/index.d.ts", 23 | "typings/modules", 24 | "src" 25 | ], 26 | "compileOnSave": false 27 | } 28 | -------------------------------------------------------------------------------- /tools/utils/seed/template_locals.ts: -------------------------------------------------------------------------------- 1 | import { argv } from 'yargs'; 2 | import * as CONFIG from '../../config'; 3 | 4 | /** 5 | * Returns the project configuration (consisting of the base configuration provided by see.config.ts and the additional 6 | * project specific overrides as defined in project.config.ts) 7 | */ 8 | export function templateLocals() { 9 | const configEnvName = argv['config-env'] || 'dev'; 10 | const configEnv = CONFIG.getPluginConfig('environment-config')[configEnvName]; 11 | 12 | if (!configEnv) { 13 | throw new Error('Invalid configuration name'); 14 | } 15 | 16 | const config = { 17 | ENV_CONFIG: JSON.stringify(configEnv) 18 | }; 19 | 20 | return Object.assign(config, CONFIG); 21 | } 22 | -------------------------------------------------------------------------------- /tools/utils/seed/watch.ts: -------------------------------------------------------------------------------- 1 | import * as gulpLoadPlugins from 'gulp-load-plugins'; 2 | import { join } from 'path'; 3 | import * as runSequence from 'run-sequence'; 4 | 5 | import { APP_SRC, TEMP_FILES } from '../../config'; 6 | import { notifyLiveReload } from '../../utils'; 7 | 8 | const plugins = gulpLoadPlugins(); 9 | 10 | /** 11 | * Watches the task with the given taskname. 12 | * @param {string} taskname - The name of the task. 13 | */ 14 | export function watch(taskname: string) { 15 | return function () { 16 | let paths:string[]=[ 17 | join(APP_SRC,'**') 18 | ].concat(TEMP_FILES.map((p) => { return '!'+p; })); 19 | 20 | plugins.watch(paths, (e:any) => 21 | runSequence(taskname, () => notifyLiveReload(e)) 22 | ); 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /tools/tasks/seed/build.bundles.app.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'path'; 2 | import * as Builder from 'systemjs-builder'; 3 | 4 | import { 5 | BOOTSTRAP_MODULE, 6 | JS_PROD_APP_BUNDLE, 7 | JS_DEST, 8 | SYSTEM_BUILDER_CONFIG, 9 | TMP_DIR 10 | } from '../../config'; 11 | 12 | const BUNDLER_OPTIONS = { 13 | format: 'cjs', 14 | minify: true, 15 | mangle: false 16 | }; 17 | 18 | /** 19 | * Executes the build process, bundling the JavaScript files using the SystemJS builder. 20 | */ 21 | export = (done: any) => { 22 | let builder = new Builder(SYSTEM_BUILDER_CONFIG); 23 | builder 24 | .buildStatic(join(TMP_DIR, BOOTSTRAP_MODULE), 25 | join(JS_DEST, JS_PROD_APP_BUNDLE), 26 | BUNDLER_OPTIONS) 27 | .then(() => done()) 28 | .catch(err => done(err)); 29 | }; 30 | -------------------------------------------------------------------------------- /src/client/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { ROUTER_DIRECTIVES } from '@angular/router'; 3 | import { HTTP_PROVIDERS } from '@angular/http'; 4 | 5 | import { Config, NavbarComponent, ToolbarComponent } from './shared/index'; 6 | 7 | /** 8 | * This class represents the main application component. Within the @Routes annotation is the configuration of the 9 | * applications routes, configuring the paths for the lazy loaded components (HomeComponent, AboutComponent). 10 | */ 11 | @Component({ 12 | moduleId: module.id, 13 | selector: 'sd-app', 14 | viewProviders: [HTTP_PROVIDERS], 15 | templateUrl: 'app.component.html', 16 | directives: [ROUTER_DIRECTIVES, NavbarComponent, ToolbarComponent] 17 | }) 18 | export class AppComponent { 19 | constructor() { 20 | console.log('Environment config', Config); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tools/tasks/seed/tslint.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import * as gulpLoadPlugins from 'gulp-load-plugins'; 3 | import { join } from 'path'; 4 | 5 | import { APP_SRC, CODELYZER_RULES, TOOLS_DIR } from '../../config'; 6 | 7 | const plugins = gulpLoadPlugins(); 8 | 9 | /** 10 | * Executes the build process, linting the TypeScript files using `codelyzer`. 11 | */ 12 | export = () => { 13 | let src = [ 14 | join(APP_SRC, '**/*.ts'), 15 | '!' + join(APP_SRC, '**/*.d.ts'), 16 | join(TOOLS_DIR, '**/*.ts'), 17 | '!' + join(TOOLS_DIR, '**/*.d.ts') 18 | ]; 19 | 20 | return gulp.src(src) 21 | .pipe(plugins.tslint({ 22 | rulesDirectory: CODELYZER_RULES 23 | })) 24 | .pipe(plugins.tslint.report(require('tslint-stylish'), { 25 | emitError: require('is-ci'), 26 | sort: true, 27 | bell: true 28 | })); 29 | }; 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Commenting this out is preferred by some people, see 24 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 | /node_modules/ 26 | /typings/ 27 | 28 | # Users Environment Variables 29 | .lock-wscript 30 | .tsdrc 31 | .typingsrc 32 | 33 | #IDE configuration files 34 | .idea 35 | .vscode 36 | *.iml 37 | 38 | /tools/**/*.js 39 | dist 40 | dev 41 | docs 42 | lib 43 | test 44 | tmp 45 | 46 | gulpfile.js 47 | gulpfile.js.map 48 | -------------------------------------------------------------------------------- /tools/config/project.config.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'path'; 2 | 3 | import { SeedConfig } from './seed.config'; 4 | 5 | /** 6 | * This class extends the basic seed configuration, allowing for project specific overrides. A few examples can be found 7 | * below. 8 | */ 9 | export class ProjectConfig extends SeedConfig { 10 | 11 | PROJECT_TASKS_DIR = join(process.cwd(), this.TOOLS_DIR, 'tasks', 'project'); 12 | 13 | constructor() { 14 | super(); 15 | // this.APP_TITLE = 'Put name of your app here'; 16 | 17 | // Add third-party libraries to be injected/bundled. 18 | this.NPM_DEPENDENCIES = [ 19 | ...this.NPM_DEPENDENCIES, 20 | // {src: 'jquery/dist/jquery.min.js', inject: 'libs'}, 21 | // {src: 'lodash/lodash.min.js', inject: 'libs'}, 22 | ]; 23 | 24 | /* Add to or override NPM module configurations: */ 25 | //this.mergeObject(this.PLUGIN_CONFIGS['browser-sync'], { ghostMode: false }); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /tools/utils/seed/clean.ts: -------------------------------------------------------------------------------- 1 | import * as util from 'gulp-util'; 2 | import * as rimraf from 'rimraf'; 3 | 4 | /** 5 | * Cleans the given path(s) using `rimraf`. 6 | * @param {string or string[]} paths - The path or list of paths to clean. 7 | */ 8 | export function clean(paths: string|string[]): (done: () => void) => void { 9 | return done => { 10 | let pathsToClean: string[]; 11 | if (paths instanceof Array) { 12 | pathsToClean = paths; 13 | } else { 14 | pathsToClean = [paths]; 15 | } 16 | 17 | let promises = pathsToClean.map(p => { 18 | return new Promise(resolve => { 19 | rimraf(p, e => { 20 | if (e) { 21 | util.log('Clean task failed with', e); 22 | } else { 23 | util.log('Deleted', util.colors.yellow(p || '-')); 24 | } 25 | resolve(); 26 | }); 27 | }); 28 | }); 29 | Promise.all(promises).then(() => done()); 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /tools/tasks/seed/build.js.tools.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import * as gulpLoadPlugins from 'gulp-load-plugins'; 3 | import { join } from 'path'; 4 | 5 | import { TOOLS_DIR } from '../../config'; 6 | import { makeTsProject, templateLocals, } from '../../utils'; 7 | 8 | const plugins = gulpLoadPlugins(); 9 | 10 | /** 11 | * Executes the build process, transpiling the TypeScript files within the `tools` directory. 12 | */ 13 | export = () => { 14 | let tsProject = makeTsProject(); 15 | let src = [ 16 | 'typings/index.d.ts', 17 | TOOLS_DIR + '/manual_typings/**/*.d.ts', 18 | join(TOOLS_DIR, '**/*.ts') 19 | ]; 20 | let result = gulp.src(src, { base: './' }) 21 | .pipe(plugins.plumber()) 22 | .pipe(plugins.sourcemaps.init()) 23 | .pipe(plugins.typescript(tsProject)); 24 | 25 | return result.js 26 | .pipe(plugins.sourcemaps.write()) 27 | .pipe(plugins.template(templateLocals())) 28 | .pipe(gulp.dest('./')); 29 | }; 30 | -------------------------------------------------------------------------------- /src/client/app/+custom-form/custom-form.component.html: -------------------------------------------------------------------------------- 1 |

Custom Stripe Form

2 | 3 |
4 | {{message}} 5 | 6 |
7 | 11 |
12 | 13 |
14 | 18 | / 19 | 20 |
21 | 22 |
23 | 27 |
28 | 29 | 30 |
31 | 32 | -------------------------------------------------------------------------------- /tools/tasks/seed/build.js.e2e.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import * as gulpLoadPlugins from 'gulp-load-plugins'; 3 | import { join } from 'path'; 4 | 5 | import { APP_DEST, APP_SRC, TOOLS_DIR } from '../../config'; 6 | import { makeTsProject, templateLocals } from '../../utils'; 7 | 8 | const plugins = gulpLoadPlugins(); 9 | 10 | /** 11 | * Executes the build process, transpiling the TypeScript files (including the e2e-spec files, excluding the spec files) 12 | * for the e2e environment. 13 | */ 14 | export = () => { 15 | let tsProject = makeTsProject(); 16 | let src = [ 17 | 'typings/index.d.ts', 18 | TOOLS_DIR + '/manual_typings/**/*.d.ts', 19 | join(APP_SRC, '**/*.ts'), 20 | '!' + join(APP_SRC, '**/*.spec.ts') 21 | ]; 22 | let result = gulp.src(src) 23 | .pipe(plugins.plumber()) 24 | .pipe(plugins.sourcemaps.init()) 25 | .pipe(plugins.typescript(tsProject)); 26 | 27 | return result.js 28 | .pipe(plugins.sourcemaps.write()) 29 | .pipe(plugins.template(templateLocals())) 30 | .pipe(gulp.dest(APP_DEST)); 31 | }; 32 | -------------------------------------------------------------------------------- /src/client/app/+stripe-form/stripe-form.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Renderer } from '@angular/core'; 2 | 3 | @Component({ 4 | moduleId: module.id, 5 | selector: 'sd-stripe-form', 6 | templateUrl: 'stripe-form.component.html', 7 | styleUrls: ['stripe-form.component.css'] 8 | }) 9 | export class StripeFormComponent { 10 | globalListener: any; 11 | 12 | constructor(private renderer: Renderer) {} 13 | 14 | openCheckout() { 15 | var handler = (window).StripeCheckout.configure({ 16 | key: 'pk_test_oi0sKPJYLGjdvOXOM8tE8cMa', 17 | locale: 'auto', 18 | token: function (token: any) { 19 | // You can access the token ID with `token.id`. 20 | // Get the token ID to your server-side code for use. 21 | } 22 | }); 23 | 24 | handler.open({ 25 | name: 'Demo Site', 26 | description: '2 widgets', 27 | amount: 2000 28 | }); 29 | 30 | this.globalListener = this.renderer.listenGlobal('window', 'popstate', () => { 31 | handler.close(); 32 | }); 33 | } 34 | 35 | ngOnDestroy() { 36 | this.globalListener(); 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /tools/tasks/seed/build.assets.prod.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import { join } from 'path'; 3 | 4 | import { APP_DEST, APP_SRC, ASSETS_SRC, TEMP_FILES } from '../../config'; 5 | 6 | // TODO There should be more elegant to prevent empty directories from copying 7 | let es: any = require('event-stream'); 8 | var onlyDirs = function (es: any) { 9 | return es.map(function (file: any, cb: any) { 10 | if (file.stat.isFile()) { 11 | return cb(null, file); 12 | } else { 13 | return cb(); 14 | } 15 | }); 16 | }; 17 | 18 | /** 19 | * Executes the build process, copying the assets located in `src/client` over to the appropriate 20 | * `dist/prod` directory. 21 | */ 22 | export = () => { 23 | return gulp.src([ 24 | join(APP_SRC, '**'), 25 | '!' + join(APP_SRC, '**', '*.ts'), 26 | '!' + join(APP_SRC, '**', '*.css'), 27 | '!' + join(APP_SRC, '**', '*.html'), 28 | '!' + join(APP_SRC, '**', '*.scss'), 29 | '!' + join(ASSETS_SRC, '**', '*.js') 30 | ].concat(TEMP_FILES.map((p) => { return '!' + p; }))) 31 | .pipe(onlyDirs(es)) 32 | .pipe(gulp.dest(APP_DEST)); 33 | }; 34 | -------------------------------------------------------------------------------- /tools/tasks/seed/e2e.ts: -------------------------------------------------------------------------------- 1 | import * as express from 'express'; 2 | import * as history from 'express-history-api-fallback'; 3 | import * as gulp from 'gulp'; 4 | import { resolve } from 'path'; 5 | import { protractor } from 'gulp-protractor'; 6 | 7 | class Protractor { 8 | server(port: number, dir: string) { 9 | let app = express(); 10 | let root = resolve(process.cwd(), dir); 11 | app.use(express.static(root)); 12 | app.use(history('index.html', { root })); 13 | return new Promise((resolve, reject) => { 14 | let server = app.listen(port, () => { 15 | resolve(server); 16 | }); 17 | }); 18 | } 19 | } 20 | 21 | /** 22 | * Executes the build process, running all e2e specs using `protractor`. 23 | */ 24 | export = (done: any) => { 25 | new Protractor() 26 | .server(5555, './dist/prod') 27 | .then((server: any) => { 28 | gulp 29 | .src('./dist/dev/**/*.e2e-spec.js') 30 | .pipe(protractor({ configFile: 'protractor.conf.js' })) 31 | .on('error', (error: string) => { throw error; }) 32 | .on('end', () => { server.close(done); }); 33 | }); 34 | }; 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Minko Gechev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tools/tasks/seed/build.js.prod.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import * as gulpLoadPlugins from 'gulp-load-plugins'; 3 | import { join } from 'path'; 4 | 5 | import { TMP_DIR, TOOLS_DIR } from '../../config'; 6 | import { makeTsProject, templateLocals } from '../../utils'; 7 | 8 | const plugins = gulpLoadPlugins(); 9 | 10 | const INLINE_OPTIONS = { 11 | base: TMP_DIR, 12 | useRelativePaths: true, 13 | removeLineBreaks: true 14 | }; 15 | 16 | /** 17 | * Executes the build process, transpiling the TypeScript files for the production environment. 18 | */ 19 | 20 | export = () => { 21 | let tsProject = makeTsProject(); 22 | let src = [ 23 | 'typings/index.d.ts', 24 | TOOLS_DIR + '/manual_typings/**/*.d.ts', 25 | join(TMP_DIR, '**/*.ts') 26 | ]; 27 | let result = gulp.src(src) 28 | .pipe(plugins.plumber()) 29 | .pipe(plugins.inlineNg2Template(INLINE_OPTIONS)) 30 | .pipe(plugins.typescript(tsProject)) 31 | .once('error', function () { 32 | this.once('finish', () => process.exit(1)); 33 | }); 34 | 35 | 36 | return result.js 37 | .pipe(plugins.template(templateLocals())) 38 | .pipe(gulp.dest(TMP_DIR)); 39 | }; 40 | -------------------------------------------------------------------------------- /tools/tasks/seed/build.js.test.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import * as gulpLoadPlugins from 'gulp-load-plugins'; 3 | import { join} from 'path'; 4 | 5 | import { APP_DEST, APP_SRC, BOOTSTRAP_MODULE, TOOLS_DIR } from '../../config'; 6 | import { makeTsProject } from '../../utils'; 7 | 8 | const plugins = gulpLoadPlugins(); 9 | 10 | /** 11 | * Executes the build process, transpiling the TypeScript files (excluding the spec and e2e-spec files) for the test 12 | * environment. 13 | */ 14 | export = () => { 15 | let tsProject = makeTsProject(); 16 | let src = [ 17 | 'typings/index.d.ts', 18 | TOOLS_DIR + '/manual_typings/**/*.d.ts', 19 | join(APP_SRC, '**/*.ts'), 20 | '!' + join(APP_SRC, '**/*.e2e-spec.ts'), 21 | '!' + join(APP_SRC, `${BOOTSTRAP_MODULE}.ts`) 22 | ]; 23 | let result = gulp.src(src) 24 | .pipe(plugins.plumber()) 25 | .pipe(plugins.sourcemaps.init()) 26 | .pipe(plugins.inlineNg2Template({ 27 | base: APP_SRC, 28 | useRelativePaths: true 29 | })) 30 | .pipe(plugins.typescript(tsProject)); 31 | 32 | return result.js 33 | .pipe(plugins.sourcemaps.write()) 34 | .pipe(gulp.dest(APP_DEST)); 35 | }; 36 | -------------------------------------------------------------------------------- /src/client/app/+custom-form/custom-form.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, NgZone } from '@angular/core'; 2 | import { REACTIVE_FORM_DIRECTIVES } from '@angular/forms'; 3 | 4 | @Component({ 5 | moduleId: module.id, 6 | selector: 'sd-custom-form', 7 | templateUrl: 'custom-form.component.html', 8 | styleUrls: ['custom-form.component.css'], 9 | directives: [REACTIVE_FORM_DIRECTIVES] 10 | }) 11 | export class CustomFormComponent { 12 | cardNumber: string; 13 | expiryMonth: string; 14 | expiryYear: string; 15 | cvc: string; 16 | 17 | message: string; 18 | 19 | constructor(private _zone: NgZone) {} 20 | 21 | getToken() { 22 | this.message = 'Loading...'; 23 | 24 | (window).Stripe.card.createToken({ 25 | number: this.cardNumber, 26 | exp_month: this.expiryMonth, 27 | exp_year: this.expiryYear, 28 | cvc: this.cvc 29 | }, (status: number, response: any) => { 30 | 31 | // Wrapping inside the Angular zone 32 | this._zone.run(() => { 33 | if (status === 200) { 34 | this.message = `Success! Card token ${response.card.id}.`; 35 | } else { 36 | this.message = response.error.message; 37 | } 38 | }); 39 | }); 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/client/css/main.css: -------------------------------------------------------------------------------- 1 | /* Reset */ 2 | html, 3 | body, 4 | div { 5 | border: 0; 6 | margin: 0; 7 | padding: 0; 8 | } 9 | 10 | /* Box-sizing border-box */ 11 | * { 12 | box-sizing: border-box; 13 | } 14 | 15 | /* Set up a default font and some padding to provide breathing room */ 16 | body { 17 | font-family: Roboto, "Helvetica Neue", sans-serif; 18 | font-size: 16px; 19 | -webkit-font-smoothing: antialiased; 20 | -moz-osx-font-smoothing: grayscale; 21 | } 22 | 23 | p { 24 | font-weight: 400; 25 | letter-spacing: 0.01em; 26 | line-height: 20px; 27 | margin-bottom: 1em; 28 | margin-top: 1em; 29 | } 30 | 31 | ul { 32 | margin: 10px 0 0 0; 33 | padding: 0 0 0 20px; 34 | } 35 | 36 | li { 37 | font-weight: 400; 38 | margin-top: 4px; 39 | } 40 | 41 | input { 42 | border: 1px solid #106cc8; 43 | font-size: 14px; 44 | height: 40px; 45 | outline: none; 46 | padding: 8px; 47 | } 48 | 49 | button { 50 | background-color: #106cc8; 51 | border-style: none; 52 | color: rgba(255, 255, 255, 0.87); 53 | cursor: pointer; 54 | display: inline-block; 55 | font-size: 14px; 56 | height: 40px; 57 | padding: 8px 18px; 58 | text-decoration: none; 59 | } 60 | 61 | button:hover { 62 | background-color: #28739e; 63 | } 64 | -------------------------------------------------------------------------------- /tools/tasks/seed/build.js.dev.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import * as gulpLoadPlugins from 'gulp-load-plugins'; 3 | import * as merge from 'merge-stream'; 4 | import { join } from 'path'; 5 | 6 | import { APP_DEST, APP_SRC, TOOLS_DIR } from '../../config'; 7 | import { makeTsProject, templateLocals } from '../../utils'; 8 | 9 | const plugins = gulpLoadPlugins(); 10 | 11 | /** 12 | * Executes the build process, transpiling the TypeScript files (except the spec and e2e-spec files) for the development 13 | * environment. 14 | */ 15 | export = () => { 16 | let tsProject = makeTsProject(); 17 | let typings = gulp.src([ 18 | 'typings/index.d.ts', 19 | TOOLS_DIR + '/manual_typings/**/*.d.ts' 20 | ]); 21 | let src = [ 22 | join(APP_SRC, '**/*.ts'), 23 | '!' + join(APP_SRC, '**/*.spec.ts'), 24 | '!' + join(APP_SRC, '**/*.e2e-spec.ts') 25 | ]; 26 | 27 | let projectFiles = gulp.src(src).pipe(plugins.cached()); 28 | let result = merge(typings, projectFiles) 29 | .pipe(plugins.plumber()) 30 | .pipe(plugins.sourcemaps.init()) 31 | .pipe(plugins.typescript(tsProject)); 32 | 33 | return result.js 34 | .pipe(plugins.sourcemaps.write()) 35 | .pipe(plugins.template(templateLocals())) 36 | .pipe(gulp.dest(APP_DEST)); 37 | }; 38 | -------------------------------------------------------------------------------- /tools/tasks/seed/build.docs.ts: -------------------------------------------------------------------------------- 1 | // import * as gulp from 'gulp'; 2 | // import * as gulpLoadPlugins from 'gulp-load-plugins'; 3 | // import { join } from 'path'; 4 | // 5 | // import { APP_SRC, APP_TITLE, DOCS_DEST } from '../../config'; 6 | // 7 | // const plugins = gulpLoadPlugins(); 8 | // 9 | // /** 10 | // * Executes the build process, building the documentation for the TypeScript 11 | // * files (excluding spec and e2e-spec files) using `typedoc`. 12 | // */ 13 | // export = () => { 14 | // 15 | // let src = [ 16 | // 'typings/index.d.ts', 17 | // join(APP_SRC, '**/*.ts'), 18 | // '!' + join(APP_SRC, '**/*.spec.ts'), 19 | // '!' + join(APP_SRC, '**/*.e2e-spec.ts') 20 | // ]; 21 | // 22 | // return gulp.src(src) 23 | // .pipe(plugins.typedoc({ 24 | // // TypeScript options (see typescript docs) 25 | // module: 'commonjs', 26 | // target: 'es5', 27 | // // excludeExternals: true, 28 | // includeDeclarations: true, 29 | // // Output options (see typedoc docs) 30 | // out: DOCS_DEST, 31 | // json: join(DOCS_DEST, 'data/docs.json'), 32 | // name: APP_TITLE, 33 | // ignoreCompilerErrors: false, 34 | // experimentalDecorators: true, 35 | // version: true 36 | // })); 37 | // }; 38 | 39 | -------------------------------------------------------------------------------- /protractor.conf.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | baseUrl: 'http://localhost:5555/', 3 | 4 | specs: [ 5 | './dist/dev/**/*.e2e-spec.js' 6 | ], 7 | 8 | exclude: [], 9 | 10 | // 'jasmine' by default will use the latest jasmine framework 11 | framework: 'jasmine', 12 | 13 | // allScriptsTimeout: 110000, 14 | 15 | jasmineNodeOpts: { 16 | // showTiming: true, 17 | showColors: true, 18 | isVerbose: false, 19 | includeStackTrace: false, 20 | // defaultTimeoutInterval: 400000 21 | }, 22 | 23 | directConnect: true, 24 | 25 | capabilities: { 26 | browserName: 'chrome' 27 | }, 28 | 29 | onPrepare: function() { 30 | const SpecReporter = require('jasmine-spec-reporter'); 31 | // add jasmine spec reporter 32 | jasmine.getEnv().addReporter(new SpecReporter({ displayStacktrace: true })); 33 | 34 | browser.ignoreSynchronization = false; 35 | }, 36 | 37 | 38 | /** 39 | * Angular 2 configuration 40 | * 41 | * useAllAngular2AppRoots: tells Protractor to wait for any angular2 apps on the page instead of just the one matching 42 | * `rootEl` 43 | */ 44 | useAllAngular2AppRoots: true 45 | }; 46 | 47 | if (process.env.TRAVIS) { 48 | config.capabilities = { 49 | browserName: 'firefox' 50 | }; 51 | } 52 | 53 | exports.config = config; 54 | -------------------------------------------------------------------------------- /tools/tasks/seed/build.bundles.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import * as gulpLoadPlugins from 'gulp-load-plugins'; 3 | import * as merge from 'merge-stream'; 4 | 5 | import { DEPENDENCIES, JS_DEST, JS_PROD_SHIMS_BUNDLE } from '../../config'; 6 | 7 | const plugins = gulpLoadPlugins(); 8 | 9 | /** 10 | * Executes the build process, bundling the shim files. 11 | */ 12 | export = () => merge(bundleShims()); 13 | 14 | /** 15 | * Returns the shim files to be injected. 16 | */ 17 | function getShims() { 18 | let libs = DEPENDENCIES 19 | .filter(d => /\.js$/.test(d.src)); 20 | 21 | return libs.filter(l => l.inject === 'shims') 22 | .concat(libs.filter(l => l.inject === 'libs')) 23 | .concat(libs.filter(l => l.inject === true)) 24 | .map(l => l.src); 25 | } 26 | 27 | /** 28 | * Bundles the shim files. 29 | */ 30 | function bundleShims() { 31 | return gulp.src(getShims()) 32 | // Strip comments and sourcemaps 33 | .pipe(plugins.uglify({ 34 | mangle: false 35 | })) 36 | .pipe(plugins.concat(JS_PROD_SHIMS_BUNDLE)) 37 | // Strip the first (global) 'use strict' added by reflect-metadata, but don't strip any others to avoid unintended scope leaks. 38 | .pipe(plugins.replace(/('|")use strict\1;var Reflect;/, 'var Reflect;')) 39 | .pipe(gulp.dest(JS_DEST)); 40 | } 41 | -------------------------------------------------------------------------------- /tools/tasks/seed/clean.tools.ts: -------------------------------------------------------------------------------- 1 | import { lstatSync, readdirSync } from 'fs'; 2 | import * as util from 'gulp-util'; 3 | import * as rimraf from 'rimraf'; 4 | import { join } from 'path'; 5 | 6 | import { TOOLS_DIR } from '../../config'; 7 | 8 | /** 9 | * Executes the build process, deleting all JavaScrip files (which were transpiled from the TypeScript sources) with in 10 | * the `tools` directory. 11 | */ 12 | export = (done: any) => { 13 | deleteAndWalk(TOOLS_DIR); 14 | done(); 15 | }; 16 | 17 | /** 18 | * Recursively walks along the given path and deletes all JavaScript files. 19 | * @param {any} path - The path to walk and clean. 20 | */ 21 | function walk(path: any) { 22 | let files = readdirSync(path); 23 | for (let i = 0; i < files.length; i += 1) { 24 | let curPath = join(path, files[i]); 25 | if (lstatSync(curPath).isDirectory()) { // recurse 26 | deleteAndWalk(curPath); 27 | } 28 | } 29 | } 30 | 31 | /** 32 | * Deletes the JavaScript file with the given path. 33 | * @param {any} path - The path of the JavaScript file to be deleted. 34 | */ 35 | function deleteAndWalk(path: any) { 36 | try { 37 | rimraf.sync(join(path, '*.js')); 38 | util.log('Deleted', util.colors.yellow(`${path}/*.js`)); 39 | } catch (e) { 40 | util.log('Error while deleting', util.colors.yellow(`${path}/*.js`), e); 41 | } 42 | walk(path); 43 | } 44 | -------------------------------------------------------------------------------- /tools/tasks/seed/check.versions.ts: -------------------------------------------------------------------------------- 1 | import * as util from 'gulp-util'; 2 | import { VERSION_NODE, VERSION_NPM } from '../../config'; 3 | 4 | function reportError(message: string) { 5 | console.error(util.colors.white.bgRed.bold(message)); 6 | process.exit(1); 7 | } 8 | 9 | /** 10 | * Executes the build process, verifying that the installed NodeJS and NPM version matches the required versions as 11 | * defined in the application configuration. 12 | */ 13 | export = () => { 14 | let exec = require('child_process').exec; 15 | let semver = require('semver'); 16 | 17 | exec('npm --version', 18 | function(error: Error, stdout: NodeBuffer, stderr: NodeBuffer) { 19 | if (error !== null) { 20 | reportError('npm preinstall error: ' + error + stderr); 21 | } 22 | 23 | if (!semver.gte(stdout, VERSION_NPM)) { 24 | reportError('NPM is not in required version! Required is ' + VERSION_NPM + ' and you\'re using ' + stdout); 25 | } 26 | }); 27 | 28 | exec('node --version', 29 | function(error: Error, stdout: NodeBuffer, stderr: NodeBuffer) { 30 | if (error !== null) { 31 | reportError('npm preinstall error: ' + error + stderr); 32 | } 33 | 34 | if (!semver.gte(stdout, VERSION_NODE)) { 35 | reportError('NODE is not in required version! Required is ' + VERSION_NODE + ' and you\'re using ' + stdout); 36 | } 37 | }); 38 | }; 39 | -------------------------------------------------------------------------------- /src/client/app/main.ts: -------------------------------------------------------------------------------- 1 | import { APP_BASE_HREF } from '@angular/common'; 2 | import { disableDeprecatedForms, provideForms } from '@angular/forms'; 3 | import { enableProdMode } from '@angular/core'; 4 | import { bootstrap } from '@angular/platform-browser-dynamic'; 5 | 6 | import { APP_ROUTER_PROVIDERS } from './app.routes'; 7 | import { AppComponent } from './app.component'; 8 | 9 | if ('<%= ENV %>' === 'prod') { enableProdMode(); } 10 | 11 | /** 12 | * Bootstraps the application and makes the ROUTER_PROVIDERS and the APP_BASE_HREF available to it. 13 | * @see https://angular.io/docs/ts/latest/api/platform-browser-dynamic/index/bootstrap-function.html 14 | */ 15 | bootstrap(AppComponent, [ 16 | disableDeprecatedForms(), 17 | provideForms(), 18 | APP_ROUTER_PROVIDERS, 19 | { 20 | provide: APP_BASE_HREF, 21 | useValue: '<%= APP_BASE %>' 22 | } 23 | ]); 24 | 25 | // In order to start the Service Worker located at "./worker.js" 26 | // uncomment this line. More about Service Workers here 27 | // https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers 28 | // 29 | // if ('serviceWorker' in navigator) { 30 | // (navigator).serviceWorker.register('./worker.js').then((registration: any) => 31 | // console.log('ServiceWorker registration successful with scope: ', registration.scope)) 32 | // .catch((err: any) => 33 | // console.log('ServiceWorker registration failed: ', err)); 34 | // } 35 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # AppVeyor file 2 | # http://www.appveyor.com/docs/appveyor-yml 3 | # This file: cloned from https://github.com/gruntjs/grunt/blob/master/appveyor.yml 4 | 5 | # Build version format 6 | version: "{build}" 7 | 8 | # Test against this version of Node.js 9 | environment: 10 | nodejs_version: "Stable" 11 | # https://github.com/DefinitelyTyped/tsd#tsdrc 12 | # Token has no scope (read-only access to public information) 13 | TSD_GITHUB_TOKEN: "9b18c72997769f3867ef2ec470e626d39661795d" 14 | 15 | build: off 16 | 17 | clone_depth: 10 18 | 19 | # Fix line endings on Windows 20 | init: 21 | - git config --global core.autocrlf true 22 | 23 | install: 24 | - ps: Install-Product node $env:nodejs_version 25 | - npm install -g npm 26 | - ps: $env:path = $env:appdata + "\npm;" + $env:path 27 | - npm install && npm install karma-ie-launcher 28 | 29 | test_script: 30 | # Output useful info for debugging. 31 | - node --version && npm --version 32 | # We test multiple Windows shells because of prior stdout buffering issues 33 | # filed against Grunt. https://github.com/joyent/node/issues/3584 34 | - ps: "npm --version # PowerShell" # Pass comment to PS for easier debugging 35 | - npm run tests.all 36 | 37 | notifications: 38 | - provider: Webhook 39 | url: https://webhooks.gitter.im/e/cfd8ce5ddee6f3a0b0c9 40 | on_build_success: false 41 | on_build_failure: true 42 | on_build_status_changed: true 43 | 44 | cache: node_modules 45 | -------------------------------------------------------------------------------- /src/client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= APP_TITLE %> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Loading... 16 | 17 | 21 | 22 | 23 | 24 | 25 | <% if (ENV === 'dev') { %> 26 | 31 | <% } %> 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | <% if (ENV === 'dev') { %> 40 | 47 | <% } %> 48 | 49 | 50 | 51 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /tools/utils/seed/code_change_tools.ts: -------------------------------------------------------------------------------- 1 | import * as browserSync from 'browser-sync'; 2 | // import * as path from 'path'; 3 | 4 | import { getPluginConfig } from '../../config'; 5 | 6 | /** 7 | * Initialises BrowserSync with the configuration defined in seed.config.ts (or if overriden: project.config.ts). 8 | */ 9 | let runServer = () => { 10 | browserSync.init(getPluginConfig('browser-sync')); 11 | }; 12 | 13 | /** 14 | * Runs BrowserSync as the listening process for the application. 15 | */ 16 | let listen = () => { 17 | // if (ENABLE_HOT_LOADING) { 18 | // ng2HotLoader.listen({ 19 | // port: HOT_LOADER_PORT, 20 | // processPath: file => { 21 | // return file.replace(join(PROJECT_ROOT, APP_SRC), join('dist', 'dev')); 22 | // } 23 | // }); 24 | // } 25 | runServer(); 26 | }; 27 | 28 | /** 29 | * Provides a flag to mark which files have changed and reloads BrowserSync accordingly. 30 | */ 31 | let changed = (files: any) => { 32 | if (!(files instanceof Array)) { 33 | files = [files]; 34 | } 35 | 36 | // let onlyStylesChanged = 37 | // files 38 | // .map((f:string) => path.parse(f).ext) 39 | // .reduce((prev:string, current:string) => prev && (current === '.scss' || current === '.css'), true); 40 | // 41 | // if (ENABLE_HOT_LOADING) { 42 | // ng2HotLoader.onChange(files); 43 | // } else { 44 | //TODO: Figure out why you can't pass a file to reload 45 | // if (onlyStylesChanged === false) { 46 | browserSync.reload(files); 47 | // } else { 48 | // browserSync.reload('*.css'); 49 | // } 50 | //} 51 | }; 52 | 53 | export { listen, changed }; 54 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": ["node_modules/codelyzer"], 3 | "rules": { 4 | "class-name": true, 5 | "curly": false, 6 | "eofline": true, 7 | "indent": ["spaces"], 8 | "max-line-length": [true, 140], 9 | "member-ordering": [true, 10 | "public-before-private", 11 | "static-before-instance", 12 | "variables-before-functions" 13 | ], 14 | "no-arg": true, 15 | "no-construct": true, 16 | "no-duplicate-key": true, 17 | "no-duplicate-variable": true, 18 | "no-empty": true, 19 | "no-eval": true, 20 | "no-trailing-whitespace": true, 21 | "no-unused-expression": true, 22 | "no-unused-variable": true, 23 | "no-unreachable": true, 24 | "no-use-before-declare": true, 25 | "one-line": [true, 26 | "check-open-brace", 27 | "check-catch", 28 | "check-else", 29 | "check-whitespace" 30 | ], 31 | "quotemark": [true, "single"], 32 | "semicolon": true, 33 | "trailing-comma": true, 34 | "triple-equals": true, 35 | "variable-name": false, 36 | 37 | "directive-selector-name": [true, "camelCase"], 38 | "component-selector-name": [true, "kebab-case"], 39 | "directive-selector-type": [true, "attribute"], 40 | "component-selector-type": [true, "element"], 41 | "use-input-property-decorator": true, 42 | "use-output-property-decorator": true, 43 | "use-host-property-decorator": true, 44 | "no-input-rename": true, 45 | "no-output-rename": true, 46 | "use-life-cycle-interface": true, 47 | "use-pipe-transform-interface": true, 48 | "component-class-suffix": true, 49 | "directive-class-suffix": true 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tools/utils/seed/tasks_tools.ts: -------------------------------------------------------------------------------- 1 | import { existsSync, lstatSync, readdirSync } from 'fs'; 2 | import * as gulp from 'gulp'; 3 | import * as util from 'gulp-util'; 4 | import * as isstream from 'isstream'; 5 | import { join } from 'path'; 6 | import * as tildify from 'tildify'; 7 | 8 | /** 9 | * Loads the tasks within the given path. 10 | * @param {string} path - The path to load the tasks from. 11 | */ 12 | export function loadTasks(path: string): void { 13 | util.log('Loading tasks folder', util.colors.yellow(path)); 14 | readDir(path, taskname => registerTask(taskname, path)); 15 | } 16 | 17 | /** 18 | * Registers the task by the given taskname and path. 19 | * @param {string} taskname - The name of the task. 20 | * @param {string} path - The path of the task. 21 | */ 22 | function registerTask(taskname: string, path: string): void { 23 | const TASK = join(path, taskname); 24 | util.log('Registering task', util.colors.yellow(tildify(TASK))); 25 | 26 | gulp.task(taskname, (done: any) => { 27 | const task = require(TASK); 28 | if (task.length > 0) { 29 | return task(done); 30 | } 31 | 32 | const taskReturnedValue = task(); 33 | if (isstream(taskReturnedValue)) { 34 | return taskReturnedValue; 35 | } 36 | 37 | // TODO: add promise handling if needed at some point. 38 | 39 | done(); 40 | }); 41 | } 42 | 43 | /** 44 | * Reads the files in the given root directory and executes the given callback per found file. 45 | * @param {string} root - The root directory to read. 46 | * @param {function} cb - The callback to execute per found file. 47 | */ 48 | function readDir(root: string, cb: (taskname: string) => void) { 49 | if (!existsSync(root)) { 50 | return; 51 | } 52 | 53 | walk(root); 54 | 55 | function walk(path: string) { 56 | let files = readdirSync(path); 57 | for (let i = 0; i < files.length; i += 1) { 58 | let file = files[i]; 59 | let curPath = join(path, file); 60 | if (lstatSync(curPath).isFile() && /\.ts$/.test(file)) { 61 | let taskname = file.replace(/\.ts$/, ''); 62 | cb(taskname); 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tools/tasks/seed/build.index.prod.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import * as gulpLoadPlugins from 'gulp-load-plugins'; 3 | import { join, sep, normalize } from 'path'; 4 | import * as slash from 'slash'; 5 | 6 | import { 7 | APP_BASE, 8 | APP_DEST, 9 | APP_SRC, 10 | CSS_DEST, 11 | CSS_PROD_BUNDLE, 12 | JS_DEST, 13 | JS_PROD_APP_BUNDLE, 14 | JS_PROD_SHIMS_BUNDLE 15 | } from '../../config'; 16 | import { templateLocals } from '../../utils'; 17 | 18 | const plugins = gulpLoadPlugins(); 19 | 20 | /** 21 | * Executes the build process, injecting the JavaScript and CSS dependencies into the `index.html` for the production 22 | * environment. 23 | */ 24 | export = () => { 25 | return gulp.src(join(APP_SRC, 'index.html')) 26 | .pipe(injectJs()) 27 | .pipe(injectCss()) 28 | .pipe(plugins.template(templateLocals())) 29 | .pipe(gulp.dest(APP_DEST)); 30 | }; 31 | 32 | /** 33 | * Injects the given file array and transforms the path of the files. 34 | * @param {Array} files - The files to be injected. 35 | */ 36 | function inject(...files: Array) { 37 | return plugins.inject(gulp.src(files, { read: false }), { 38 | files, 39 | transform: transformPath() 40 | }); 41 | } 42 | 43 | /** 44 | * Injects the bundled JavaScript shims and application bundles for the production environment. 45 | */ 46 | function injectJs() { 47 | return inject(join(JS_DEST, JS_PROD_SHIMS_BUNDLE), join(JS_DEST, JS_PROD_APP_BUNDLE)); 48 | } 49 | 50 | /** 51 | * Injects the bundled CSS files for the production environment. 52 | */ 53 | function injectCss() { 54 | return inject(join(CSS_DEST, CSS_PROD_BUNDLE)); 55 | } 56 | 57 | /** 58 | * Transform the path of a dependency to its location within the `dist` directory according to the applications 59 | * environment. 60 | */ 61 | function transformPath() { 62 | return function(filepath: string) { 63 | let path: Array = normalize(filepath).split(sep); 64 | arguments[0] = APP_BASE + path.slice(3, path.length).join(sep) + `?${Date.now()}`; 65 | return slash(plugins.inject.transform.apply(plugins.inject.transform, arguments)); 66 | }; 67 | } 68 | -------------------------------------------------------------------------------- /tools/tasks/seed/css-lint.ts: -------------------------------------------------------------------------------- 1 | import * as colorguard from 'colorguard'; 2 | import * as doiuse from 'doiuse'; 3 | import * as gulp from 'gulp'; 4 | import * as gulpLoadPlugins from 'gulp-load-plugins'; 5 | import * as merge from 'merge-stream'; 6 | import * as reporter from 'postcss-reporter'; 7 | import * as stylelint from 'stylelint'; 8 | import { join } from 'path'; 9 | 10 | import { APP_ASSETS, APP_SRC, BROWSER_LIST, CSS_SRC, ENV, DEPENDENCIES, ENABLE_SCSS } from '../../config'; 11 | 12 | const plugins = gulpLoadPlugins(); 13 | 14 | const isProd = ENV === 'prod'; 15 | var stylesheetType = ENABLE_SCSS ? 'scss' : 'css'; 16 | 17 | const processors = [ 18 | doiuse({ 19 | browsers: BROWSER_LIST, 20 | }), 21 | colorguard(), 22 | stylelint(), 23 | reporter({clearMessages: true}) 24 | ]; 25 | 26 | function lintComponentStylesheets() { 27 | return gulp.src([ 28 | join(APP_SRC, '**', `*.${stylesheetType}`), 29 | `!${join(APP_SRC, 'assets', '**', '*.scss')}`, 30 | `!${join(CSS_SRC, '**', '*.css')}` 31 | ]).pipe(isProd ? plugins.cached('css-lint') : plugins.util.noop()) 32 | .pipe(ENABLE_SCSS ? plugins.sassLint() : plugins.postcss(processors)) 33 | .pipe(ENABLE_SCSS ? plugins.sassLint.format() : plugins.util.noop()) 34 | .pipe(ENABLE_SCSS ? plugins.sassLint.failOnError() : plugins.util.noop()); 35 | } 36 | 37 | function lintExternalStylesheets() { 38 | return gulp.src(getExternalStylesheets().map(r => r.src)) 39 | .pipe(isProd ? plugins.cached('css-lint') : plugins.util.noop()) 40 | .pipe(ENABLE_SCSS ? plugins.sassLint() : plugins.postcss(processors)) 41 | .pipe(ENABLE_SCSS ? plugins.sassLint.format() : plugins.util.noop()) 42 | .pipe(ENABLE_SCSS ? plugins.sassLint.failOnError() : plugins.util.noop()); 43 | } 44 | 45 | function getExternalStylesheets() { 46 | let stylesheets = ENABLE_SCSS ? DEPENDENCIES : APP_ASSETS; 47 | return stylesheets 48 | .filter(d => new RegExp(`\.${stylesheetType}$`) 49 | .test(d.src) && !d.vendor); 50 | } 51 | 52 | /** 53 | * Executes the build process, linting the component and external CSS files using `stylelint`. 54 | */ 55 | export = () => merge(lintComponentStylesheets(), lintExternalStylesheets()); 56 | -------------------------------------------------------------------------------- /tools/utils/seed/server.ts: -------------------------------------------------------------------------------- 1 | import * as express from 'express'; 2 | import * as fallback from 'express-history-api-fallback'; 3 | import * as openResource from 'open'; 4 | import { resolve } from 'path'; 5 | import * as serveStatic from 'serve-static'; 6 | 7 | import * as codeChangeTool from './code_change_tools'; 8 | import { APP_BASE, COVERAGE_PORT, DOCS_DEST, DOCS_PORT, PORT, PROD_DEST } from '../../config'; 9 | 10 | /** 11 | * Serves the Single Page Application. More specifically, calls the `listen` method, which itself launches BrowserSync. 12 | */ 13 | export function serveSPA() { 14 | codeChangeTool.listen(); 15 | } 16 | 17 | /** 18 | * This utility method is used to notify that a file change has happened and subsequently calls the `changed` method, 19 | * which itself initiates a BrowserSync reload. 20 | * @param {any} e - The file that has changed. 21 | */ 22 | export function notifyLiveReload(e:any) { 23 | let fileName = e.path; 24 | codeChangeTool.changed(fileName); 25 | } 26 | 27 | /** 28 | * Starts a new `express` server, serving the static documentation files. 29 | */ 30 | export function serveDocs() { 31 | let server = express(); 32 | 33 | server.use( 34 | APP_BASE, 35 | serveStatic(resolve(process.cwd(), DOCS_DEST)) 36 | ); 37 | 38 | server.listen(DOCS_PORT, () => 39 | openResource('http://localhost:' + DOCS_PORT + APP_BASE) 40 | ); 41 | } 42 | 43 | /** 44 | * Starts a new `express` server, serving the static unit test code coverage report. 45 | */ 46 | export function serveCoverage() { 47 | let server = express(); 48 | 49 | server.use( 50 | APP_BASE, 51 | serveStatic(resolve(process.cwd(), 'coverage')) 52 | ); 53 | 54 | server.listen(COVERAGE_PORT, () => 55 | openResource('http://localhost:' + COVERAGE_PORT + APP_BASE) 56 | ); 57 | } 58 | 59 | /** 60 | * Starts a new `express` server, serving the built files from `dist/prod`. 61 | */ 62 | export function serveProd() { 63 | let root = resolve(process.cwd(), PROD_DEST); 64 | let server = express(); 65 | 66 | server.use(APP_BASE, serveStatic(root)); 67 | 68 | server.use(fallback('index.html', { root })); 69 | 70 | server.listen(PORT, () => 71 | openResource('http://localhost:' + PORT + APP_BASE) 72 | ); 73 | }; 74 | -------------------------------------------------------------------------------- /tools/tasks/seed/build.index.dev.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import * as gulpLoadPlugins from 'gulp-load-plugins'; 3 | import { join } from 'path'; 4 | import * as slash from 'slash'; 5 | 6 | import { APP_BASE, APP_DEST, APP_SRC, DEPENDENCIES, CSS_DEST, ASSETS_SRC } from '../../config'; 7 | import { templateLocals } from '../../utils'; 8 | 9 | const plugins = gulpLoadPlugins(); 10 | 11 | 12 | /** 13 | * Executes the build process, injecting the shims and libs into the `index.hml` for the development environment. 14 | */ 15 | export = () => { 16 | return gulp.src(join(APP_SRC, 'index.html')) 17 | .pipe(inject('shims')) 18 | .pipe(inject('libs')) 19 | .pipe(inject()) 20 | .pipe(plugins.template(templateLocals())) 21 | .pipe(gulp.dest(APP_DEST)); 22 | }; 23 | 24 | /** 25 | * Injects the file with the given name. 26 | * @param {string} name - The file to be injected. 27 | */ 28 | function inject(name?: string) { 29 | return plugins.inject(gulp.src(getInjectablesDependenciesRef(name), { read: false }), { 30 | name, 31 | transform: transformPath() 32 | }); 33 | } 34 | 35 | /** 36 | * Returns the injectable dependency, mapping its filename to its path. 37 | * @param {string} name - The dependency to be mapped. 38 | */ 39 | function getInjectablesDependenciesRef(name?: string) { 40 | return DEPENDENCIES 41 | .filter(dep => dep['inject'] && dep['inject'] === (name || true)) 42 | .map(mapPath); 43 | } 44 | 45 | /** 46 | * Maps the path of the given dependency to its path according to the applications environment. 47 | * @param {any} dep - The dependency to be mapped. 48 | */ 49 | function mapPath(dep: any) { 50 | let envPath = dep.src; 51 | if (envPath.startsWith(APP_SRC) && !envPath.endsWith('.scss')) { 52 | envPath = join(APP_DEST, envPath.replace(APP_SRC, '')); 53 | } else if (envPath.startsWith(APP_SRC) && envPath.endsWith('.scss')) { 54 | envPath = envPath.replace(ASSETS_SRC, CSS_DEST).replace('.scss', '.css'); 55 | } 56 | return envPath; 57 | } 58 | 59 | /** 60 | * Transform the path of a dependecy to its location within the `dist` directory according to the applications 61 | * environment. 62 | */ 63 | function transformPath() { 64 | return function (filepath: string) { 65 | arguments[0] = join(APP_BASE, filepath) + `?${Date.now()}`; 66 | return slash(plugins.inject.transform.apply(plugins.inject.transform, arguments)); 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /gulpfile.ts: -------------------------------------------------------------------------------- 1 | import * as gulp from 'gulp'; 2 | import * as runSequence from 'run-sequence'; 3 | 4 | import { PROJECT_TASKS_DIR, SEED_TASKS_DIR } from './tools/config'; 5 | import { loadTasks } from './tools/utils'; 6 | 7 | 8 | loadTasks(SEED_TASKS_DIR); 9 | loadTasks(PROJECT_TASKS_DIR); 10 | 11 | 12 | // -------------- 13 | // Build dev. 14 | gulp.task('build.dev', (done: any) => 15 | runSequence(//'clean.dev', 16 | // 'tslint', 17 | // 'css-lint', 18 | 'build.assets.dev', 19 | 'build.html_css', 20 | 'build.js.dev', 21 | 'build.index.dev', 22 | done)); 23 | 24 | // -------------- 25 | // Build dev watch. 26 | gulp.task('build.dev.watch', (done: any) => 27 | runSequence('build.dev', 28 | 'watch.dev', 29 | done)); 30 | 31 | // -------------- 32 | // Build e2e. 33 | gulp.task('build.e2e', (done: any) => 34 | runSequence('clean.dev', 35 | 'tslint', 36 | 'build.assets.dev', 37 | 'build.js.e2e', 38 | 'build.index.dev', 39 | done)); 40 | 41 | // -------------- 42 | // Build prod. 43 | gulp.task('build.prod', (done: any) => 44 | runSequence('clean.prod', 45 | 'tslint', 46 | 'css-lint', 47 | 'build.assets.prod', 48 | 'build.html_css', 49 | 'copy.js.prod', 50 | 'build.js.prod', 51 | 'build.bundles', 52 | 'build.bundles.app', 53 | 'build.index.prod', 54 | done)); 55 | 56 | // -------------- 57 | // Build test. 58 | gulp.task('build.test', (done: any) => 59 | runSequence('clean.dev', 60 | 'tslint', 61 | 'build.assets.dev', 62 | 'build.js.test', 63 | 'build.index.dev', 64 | done)); 65 | 66 | // -------------- 67 | // Build test watch. 68 | gulp.task('build.test.watch', (done: any) => 69 | runSequence('build.test', 70 | 'watch.test', 71 | done)); 72 | 73 | // -------------- 74 | // Build tools. 75 | gulp.task('build.tools', (done: any) => 76 | runSequence('clean.tools', 77 | 'build.js.tools', 78 | done)); 79 | 80 | // -------------- 81 | // Docs 82 | // gulp.task('docs', (done: any) => 83 | // runSequence('build.docs', 84 | // 'serve.docs', 85 | // done)); 86 | 87 | // -------------- 88 | // Serve dev 89 | gulp.task('serve.dev', (done: any) => 90 | runSequence('build.dev', 91 | 'server.start', 92 | 'watch.dev', 93 | done)); 94 | 95 | // -------------- 96 | // Serve e2e 97 | gulp.task('serve.e2e', (done: any) => 98 | runSequence('build.e2e', 99 | 'server.start', 100 | 'watch.e2e', 101 | done)); 102 | 103 | 104 | // -------------- 105 | // Serve prod 106 | gulp.task('serve.prod', (done: any) => 107 | runSequence('build.prod', 108 | 'server.prod', 109 | done)); 110 | 111 | 112 | // -------------- 113 | // Test. 114 | gulp.task('test', (done: any) => 115 | runSequence('build.test', 116 | 'karma.start', 117 | done)); 118 | -------------------------------------------------------------------------------- /test-main.js: -------------------------------------------------------------------------------- 1 | if (!Object.hasOwnProperty('name')) { 2 | Object.defineProperty(Function.prototype, 'name', { 3 | get: function() { 4 | var matches = this.toString().match(/^\s*function\s*(\S*)\s*\(/); 5 | var name = matches && matches.length > 1 ? matches[1] : ""; 6 | Object.defineProperty(this, 'name', {value: name}); 7 | return name; 8 | } 9 | }); 10 | } 11 | 12 | // Turn on full stack traces in errors to help debugging 13 | Error.stackTraceLimit = Infinity; 14 | 15 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; 16 | 17 | // Cancel Karma's synchronous start, 18 | // we will call `__karma__.start()` later, once all the specs are loaded. 19 | __karma__.loaded = function() {}; 20 | 21 | // Load our SystemJS configuration. 22 | System.config({ 23 | baseURL: '/base/' 24 | }); 25 | 26 | System.config({ 27 | defaultJSExtensions: true, 28 | map: { 29 | 'rxjs': 'node_modules/rxjs', 30 | '@angular': 'node_modules/@angular' 31 | }, 32 | packages: { 33 | '@angular/common': { 34 | main: 'index.js', 35 | defaultExtension: 'js' 36 | }, 37 | '@angular/compiler': { 38 | main: 'index.js', 39 | defaultExtension: 'js' 40 | }, 41 | '@angular/core': { 42 | main: 'index.js', 43 | defaultExtension: 'js' 44 | }, 45 | '@angular/forms': { 46 | main: 'index.js', 47 | defaultExtension: 'js' 48 | }, 49 | '@angular/http': { 50 | main: 'index.js', 51 | defaultExtension: 'js' 52 | }, 53 | '@angular/platform-browser': { 54 | main: 'index.js', 55 | defaultExtension: 'js' 56 | }, 57 | '@angular/platform-browser-dynamic': { 58 | main: 'index.js', 59 | defaultExtension: 'js' 60 | }, 61 | '@angular/router': { 62 | main: 'index.js', 63 | defaultExtension: 'js' 64 | }, 65 | 'rxjs': { 66 | defaultExtension: 'js' 67 | } 68 | } 69 | }); 70 | 71 | Promise.all([ 72 | System.import('@angular/core/testing'), 73 | System.import('@angular/platform-browser-dynamic/testing') 74 | ]).then(function (providers) { 75 | var testing = providers[0]; 76 | var testingBrowser = providers[1]; 77 | 78 | testing.setBaseTestProviders(testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, 79 | testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS); 80 | 81 | }).then(function() { 82 | return Promise.all( 83 | Object.keys(window.__karma__.files) // All files served by Karma. 84 | .filter(onlySpecFiles) 85 | .map(file2moduleName) 86 | .map(function(path) { 87 | return System.import(path).then(function(module) { 88 | if (module.hasOwnProperty('main')) { 89 | module.main(); 90 | } else { 91 | throw new Error('Module ' + path + ' does not implement main() method.'); 92 | } 93 | }); 94 | })); 95 | }) 96 | .then(function() { 97 | __karma__.start(); 98 | }, function(error) { 99 | console.error(error.stack || error); 100 | __karma__.start(); 101 | }); 102 | 103 | function onlySpecFiles(path) { 104 | // check for individual files, if not given, always matches to all 105 | var patternMatched = __karma__.config.files ? 106 | path.match(new RegExp(__karma__.config.files)) : true; 107 | 108 | return patternMatched && /[\.|_]spec\.js$/.test(path); 109 | } 110 | 111 | // Normalize paths to module names. 112 | function file2moduleName(filePath) { 113 | return filePath.replace(/\\/g, '/') 114 | .replace(/^\/base\//, '') 115 | .replace(/\.js$/, ''); 116 | } 117 | -------------------------------------------------------------------------------- /typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "xhr2": "github:gdi2290/typed-xhr2#69f2b8d40d0cd407c1b2a2f2f41fecc6852cabbb" 4 | }, 5 | "devDependencies": {}, 6 | "globalDependencies": { 7 | "Q": "github:DefinitelyTyped/DefinitelyTyped/q/Q.d.ts#5c3e47967affa3c4128a3875d1664ba206ae1b0f", 8 | "angular-protractor": "github:DefinitelyTyped/DefinitelyTyped/angular-protractor/angular-protractor.d.ts#64b25f63f0ec821040a5d3e049a976865062ed9d", 9 | "async": "github:DefinitelyTyped/DefinitelyTyped/async/async.d.ts#5c3e47967affa3c4128a3875d1664ba206ae1b0f", 10 | "browser-sync": "github:DefinitelyTyped/DefinitelyTyped/browser-sync/browser-sync.d.ts#d9b5b35ba3a79ac778c5890531393442439df5dd", 11 | "chalk": "github:DefinitelyTyped/DefinitelyTyped/chalk/chalk.d.ts#5a8fc5ee71701431e4fdbb80c506e3c13f85a9ff", 12 | "chokidar": "github:DefinitelyTyped/DefinitelyTyped/chokidar/chokidar.d.ts#ae81e340a9e897167cfef3122a5a3aed04293814", 13 | "core-js": "registry:dt/core-js#0.0.0+20160317120654", 14 | "express": "github:DefinitelyTyped/DefinitelyTyped/express/express.d.ts#5c3e47967affa3c4128a3875d1664ba206ae1b0f", 15 | "glob": "github:DefinitelyTyped/DefinitelyTyped/glob/glob.d.ts#5c3e47967affa3c4128a3875d1664ba206ae1b0f", 16 | "gulp": "github:DefinitelyTyped/DefinitelyTyped/gulp/gulp.d.ts#5c3e47967affa3c4128a3875d1664ba206ae1b0f", 17 | "gulp-load-plugins": "github:DefinitelyTyped/DefinitelyTyped/gulp-load-plugins/gulp-load-plugins.d.ts#e081148d88b857d66509e3b46edbd08b3f75f96a", 18 | "gulp-protractor": "registry:dt/gulp-protractor#1.0.0+20160316155526", 19 | "gulp-sass": "github:DefinitelyTyped/DefinitelyTyped/gulp-sass/gulp-sass.d.ts#56295f5058cac7ae458540423c50ac2dcf9fc711", 20 | "gulp-shell": "github:DefinitelyTyped/DefinitelyTyped/gulp-shell/gulp-shell.d.ts#5c3e47967affa3c4128a3875d1664ba206ae1b0f", 21 | "gulp-util": "github:DefinitelyTyped/DefinitelyTyped/gulp-util/gulp-util.d.ts#5a8fc5ee71701431e4fdbb80c506e3c13f85a9ff", 22 | "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#26c98c8a9530c44f8c801ccc3b2057e2101187ee", 23 | "micromatch": "github:DefinitelyTyped/DefinitelyTyped/micromatch/micromatch.d.ts#7cda84786520fd0673c934fde1aa722083e05f7b", 24 | "mime": "github:DefinitelyTyped/DefinitelyTyped/mime/mime.d.ts#5c3e47967affa3c4128a3875d1664ba206ae1b0f", 25 | "minimatch": "github:DefinitelyTyped/DefinitelyTyped/minimatch/minimatch.d.ts#5c3e47967affa3c4128a3875d1664ba206ae1b0f", 26 | "ng2": "github:gdi2290/typings-ng2/ng2.d.ts#32998ff5584c0eab0cd9dc7704abb1c5c450701c", 27 | "node": "github:DefinitelyTyped/DefinitelyTyped/node/node.d.ts#138ad74b9e8e6c08af7633964962835add4c91e2", 28 | "orchestrator": "github:DefinitelyTyped/DefinitelyTyped/orchestrator/orchestrator.d.ts#5c3e47967affa3c4128a3875d1664ba206ae1b0f", 29 | "parse-glob": "github:DefinitelyTyped/DefinitelyTyped/parse-glob/parse-glob.d.ts#1ae2ddf27c6e9b98ad7e7fa496788f1aadf37933", 30 | "rimraf": "github:DefinitelyTyped/DefinitelyTyped/rimraf/rimraf.d.ts#09f3d7a8dc79f448b538862c3ad5872f75112d60", 31 | "run-sequence": "github:DefinitelyTyped/DefinitelyTyped/run-sequence/run-sequence.d.ts#052725d74978d6b8d7c4ff537b5a3b21ee755a49", 32 | "selenium-webdriver": "github:DefinitelyTyped/DefinitelyTyped/selenium-webdriver/selenium-webdriver.d.ts#a83677ed13add14c2ab06c7325d182d0ba2784ea", 33 | "serve-static": "github:DefinitelyTyped/DefinitelyTyped/serve-static/serve-static.d.ts#5c3e47967affa3c4128a3875d1664ba206ae1b0f", 34 | "systemjs": "github:DefinitelyTyped/DefinitelyTyped/systemjs/systemjs.d.ts#5c3e47967affa3c4128a3875d1664ba206ae1b0f", 35 | "through2": "github:DefinitelyTyped/DefinitelyTyped/through2/through2.d.ts#5a8fc5ee71701431e4fdbb80c506e3c13f85a9ff", 36 | "vinyl": "github:DefinitelyTyped/DefinitelyTyped/vinyl/vinyl.d.ts#5a8fc5ee71701431e4fdbb80c506e3c13f85a9ff", 37 | "vinyl-source-stream": "github:DefinitelyTyped/DefinitelyTyped/vinyl-source-stream/vinyl-source-stream.d.ts#ffceea9dd124d277c4597c7bd12930666ec074c5", 38 | "yargs": "github:DefinitelyTyped/DefinitelyTyped/yargs/yargs.d.ts#6a287502dab374e7d4cbf18ea1ac5dff7f74726a", 39 | "zone.js": "github:DefinitelyTyped/DefinitelyTyped/zone.js/zone.js.d.ts#b923a5aaf013ac84c566f27ba6b5843211981c7a" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Wed Jul 15 2015 09:44:02 GMT+0200 (Romance Daylight Time) 3 | 'use strict'; 4 | 5 | var argv = require('yargs').argv; 6 | 7 | module.exports = function(config) { 8 | config.set({ 9 | 10 | // base path that will be used to resolve all patterns (eg. files, exclude) 11 | basePath: './', 12 | 13 | 14 | // frameworks to use 15 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 16 | frameworks: ['jasmine'], 17 | 18 | 19 | // list of files / patterns to load in the browser 20 | files: [ 21 | // Polyfills. 22 | 'node_modules/core-js/client/shim.min.js', 23 | 24 | // System.js for module loading 25 | 'node_modules/systemjs/dist/system.src.js', 26 | 27 | // Zone.js dependencies 28 | 'node_modules/zone.js/dist/zone.js', 29 | 'node_modules/zone.js/dist/jasmine-patch.js', 30 | 'node_modules/zone.js/dist/async-test.js', 31 | 'node_modules/zone.js/dist/fake-async-test.js', 32 | 33 | // RxJs. 34 | { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, 35 | { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false }, 36 | 37 | // paths loaded via module imports 38 | // Angular itself 39 | { pattern: 'node_modules/@angular/**/*.js', included: false, watched: true }, 40 | 41 | { pattern: 'dist/dev/**/*.js', included: false, watched: true }, 42 | { pattern: 'dist/dev/**/*.html', included: false, watched: true, served: true }, 43 | { pattern: 'dist/dev/**/*.css', included: false, watched: true, served: true }, 44 | { pattern: 'node_modules/systemjs/dist/system-polyfills.js', included: false, watched: false }, // PhantomJS2 (and possibly others) might require it 45 | 46 | // suppress annoying 404 warnings for resources, images, etc. 47 | { pattern: 'dist/dev/assets/**/*', watched: false, included: false, served: true }, 48 | 49 | 'test-main.js' 50 | ], 51 | 52 | // must go along with above, suppress annoying 404 warnings. 53 | proxies: { 54 | '/assets/': '/base/dist/dev/assets/' 55 | }, 56 | 57 | // list of files to exclude 58 | exclude: [ 59 | 'node_modules/**/*spec.js' 60 | ], 61 | 62 | 63 | // preprocess matching files before serving them to the browser 64 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 65 | preprocessors: { 66 | 'dist/**/!(*spec).js': ['coverage'] 67 | }, 68 | 69 | // test results reporter to use 70 | // possible values: 'dots', 'progress' 71 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 72 | reporters: ['mocha', 'coverage'], 73 | 74 | 75 | // web server port 76 | port: 9876, 77 | 78 | 79 | // enable / disable colors in the output (reporters and logs) 80 | colors: true, 81 | 82 | 83 | // level of logging 84 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 85 | logLevel: config.LOG_INFO, 86 | 87 | 88 | // enable / disable watching file and executing tests whenever any file changes 89 | autoWatch: true, 90 | 91 | 92 | // start these browsers 93 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 94 | browsers: [ 95 | 'Chrome' 96 | ], 97 | 98 | 99 | customLaunchers: { 100 | Chrome_travis_ci: { 101 | base: 'Chrome', 102 | flags: ['--no-sandbox'] 103 | } 104 | }, 105 | 106 | coverageReporter: { 107 | dir: 'coverage/', 108 | reporters: [ 109 | { type: 'text-summary' }, 110 | { type: 'json', subdir: '.', file: 'coverage-final.json' }, 111 | { type: 'html' } 112 | ] 113 | }, 114 | 115 | // Continuous Integration mode 116 | // if true, Karma captures browsers, runs the tests and exits 117 | singleRun: false, 118 | 119 | // Passing command line arguments to tests 120 | client: { 121 | files: argv.files 122 | } 123 | }); 124 | 125 | if (process.env.APPVEYOR) { 126 | config.browsers = ['IE']; 127 | config.singleRun = true; 128 | config.browserNoActivityTimeout = 90000; // Note: default value (10000) is not enough 129 | } 130 | 131 | if (process.env.TRAVIS || process.env.CIRCLECI) { 132 | config.browsers = ['Chrome_travis_ci']; 133 | config.singleRun = true; 134 | } 135 | }; 136 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular2-seed", 3 | "version": "0.0.0", 4 | "description": "Modular seed project for Angular 2 apps with fast, statically typed build", 5 | "repository": { 6 | "url": "https://github.com/mgechev/angular2-seed" 7 | }, 8 | "scripts": { 9 | "build.dev": "gulp build.dev --color", 10 | "build.dev.watch": "gulp build.dev.watch --color", 11 | "build.e2e": "gulp build.e2e --color", 12 | "build.prod": "gulp build.prod --color", 13 | "build.test": "gulp build.test --color", 14 | "build.test.watch": "gulp build.test.watch --color", 15 | "generate.manifest": "gulp generate.manifest --color", 16 | "e2e": "protractor", 17 | "e2e.live": "protractor --elementExplorer", 18 | "gulp": "gulp", 19 | "karma": "karma", 20 | "karma.start": "karma start", 21 | "postinstall": "typings install && gulp check.versions && npm prune && gulp webdriver", 22 | "reinstall": "npm cache clean && npm install", 23 | "serve.coverage": "remap-istanbul -b src/ -i coverage/coverage-final.json -o coverage -t html && npm run gulp -- serve.coverage --color", 24 | "serve.dev": "gulp serve.dev --color", 25 | "serve.e2e": "gulp serve.e2e --color", 26 | "serve.prod": "gulp serve.prod --color", 27 | "start": "gulp serve.dev --color", 28 | "tasks.list": "gulp --tasks-simple --color", 29 | "test": "gulp test --color", 30 | "e2e.ci": "gulp build.prod --color && gulp build.js.e2e --color && gulp e2e --color", 31 | "tests.all": "npm test && npm run e2e.ci", 32 | "webdriver-start": "webdriver-manager start", 33 | "webdriver-update": "webdriver-manager update" 34 | }, 35 | "author": "Minko Gechev ", 36 | "license": "MIT", 37 | "devDependencies": { 38 | "async": "^1.4.2", 39 | "autoprefixer": "^6.3.6", 40 | "browser-sync": "^2.11.2", 41 | "codelyzer": "0.0.20", 42 | "colorguard": "^1.1.1", 43 | "connect": "^3.4.1", 44 | "connect-history-api-fallback": "^1.2.0", 45 | "connect-livereload": "^0.5.3", 46 | "cssnano": "^3.5.2", 47 | "deep-extend": "^0.4.1", 48 | "doiuse": "^2.3.0", 49 | "event-stream": "^3.3.2", 50 | "express": "~4.13.4", 51 | "express-history-api-fallback": "^2.0.0", 52 | "extend": "^3.0.0", 53 | "gulp": "^3.9.1", 54 | "gulp-cached": "^1.1.0", 55 | "gulp-clean-css": "^2.0.7", 56 | "gulp-concat": "^2.6.0", 57 | "gulp-concat-css": "^2.2.0", 58 | "gulp-filter": "^4.0.0", 59 | "gulp-inject": "^4.0.0", 60 | "gulp-inline-ng2-template": "^1.1.2", 61 | "gulp-load-plugins": "^1.2.2", 62 | "gulp-plumber": "~1.1.0", 63 | "gulp-postcss": "^6.1.1", 64 | "gulp-progeny": "^0.2.1", 65 | "gulp-protractor": "^2.3.0", 66 | "gulp-replace": "^0.5.4", 67 | "gulp-sass": "^2.3.1", 68 | "gulp-sass-lint": "^1.1.1", 69 | "gulp-shell": "~0.5.2", 70 | "gulp-sourcemaps": "2.0.0-alpha", 71 | "gulp-template": "^4.0.0", 72 | "gulp-tslint": "^4.3.3", 73 | "gulp-typescript": "~2.13.4", 74 | "gulp-uglify": "^1.5.3", 75 | "gulp-util": "^3.0.7", 76 | "gulp-watch": "^4.3.5", 77 | "is-ci": "^1.0.8", 78 | "isstream": "^0.1.2", 79 | "jasmine-core": "~2.4.1", 80 | "jasmine-spec-reporter": "^2.4.0", 81 | "karma": "~0.13.22", 82 | "karma-chrome-launcher": "~1.0.1", 83 | "karma-coverage": "^1.0.0", 84 | "karma-jasmine": "~1.0.2", 85 | "karma-mocha-reporter": "^2.0.3", 86 | "merge-stream": "^1.0.0", 87 | "open": "0.0.5", 88 | "postcss-reporter": "^1.3.3", 89 | "protractor": "^3.3.0", 90 | "remap-istanbul": "^0.6.3", 91 | "rimraf": "^2.5.2", 92 | "run-sequence": "^1.1.5", 93 | "semver": "^5.1.0", 94 | "serve-static": "^1.10.2", 95 | "slash": "~1.0.0", 96 | "stream-series": "^0.1.1", 97 | "stylelint": "^6.3.3", 98 | "stylelint-config-standard": "^6.0.0", 99 | "systemjs-builder": "0.15.14", 100 | "tildify": "^1.2.0", 101 | "tiny-lr": "^0.2.1", 102 | "traceur": "^0.0.91", 103 | "ts-node": "^0.7.3", 104 | "tslint": "^3.10.2", 105 | "tslint-stylish": "2.1.0-beta", 106 | "typescript": "~1.8.10", 107 | "typings": "^1.0.4", 108 | "vinyl-buffer": "^1.0.0", 109 | "vinyl-source-stream": "^1.1.0", 110 | "walk": "^2.3.9", 111 | "yargs": "^4.2.0" 112 | }, 113 | "dependencies": { 114 | "@angular/common": "2.0.0-rc.4", 115 | "@angular/compiler": "2.0.0-rc.4", 116 | "@angular/core": "2.0.0-rc.4", 117 | "@angular/forms": "0.2.0", 118 | "@angular/http": "2.0.0-rc.4", 119 | "@angular/platform-browser": "2.0.0-rc.4", 120 | "@angular/platform-browser-dynamic": "2.0.0-rc.4", 121 | "@angular/router": "3.0.0-beta.2", 122 | "es6-module-loader": "^0.17.8", 123 | "core-js": "^2.4.0", 124 | "rxjs": "5.0.0-beta.6", 125 | "systemjs": "0.19.27", 126 | "zone.js": "^0.6.12" 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /tools/tasks/seed/build.html_css.ts: -------------------------------------------------------------------------------- 1 | import * as autoprefixer from 'autoprefixer'; 2 | import * as cssnano from 'cssnano'; 3 | import * as gulp from 'gulp'; 4 | import * as gulpLoadPlugins from 'gulp-load-plugins'; 5 | import * as merge from 'merge-stream'; 6 | import { join } from 'path'; 7 | 8 | import { 9 | APP_DEST, 10 | APP_SRC, 11 | BROWSER_LIST, 12 | CSS_DEST, 13 | CSS_PROD_BUNDLE, 14 | CSS_SRC, 15 | DEPENDENCIES, 16 | ENABLE_SCSS, 17 | ENV, 18 | TMP_DIR, 19 | } from '../../config'; 20 | 21 | const plugins = gulpLoadPlugins(); 22 | const cleanCss = require('gulp-clean-css'); 23 | 24 | const processors = [ 25 | autoprefixer({ 26 | browsers: BROWSER_LIST 27 | }) 28 | ]; 29 | 30 | const isProd = ENV === 'prod'; 31 | 32 | if (isProd) { 33 | processors.push( 34 | cssnano({ 35 | discardComments: {removeAll: true}, 36 | discardUnused: false, // unsafe, see http://goo.gl/RtrzwF 37 | zindex: false, // unsafe, see http://goo.gl/vZ4gbQ 38 | reduceIdents: false // unsafe, see http://goo.gl/tNOPv0 39 | }) 40 | ); 41 | } 42 | 43 | /** 44 | * Copies all HTML files in `src/client` over to the `dist/tmp` directory. 45 | */ 46 | function prepareTemplates() { 47 | return gulp.src(join(APP_SRC, '**', '*.html')) 48 | .pipe(gulp.dest(TMP_DIR)); 49 | } 50 | 51 | /** 52 | * Execute the appropriate component-stylesheet processing method based on user stylesheet preference. 53 | */ 54 | function processComponentStylesheets() { 55 | return ENABLE_SCSS ? processComponentScss() : processComponentCss(); 56 | } 57 | 58 | /** 59 | * Process scss files referenced from Angular component `styleUrls` metadata 60 | */ 61 | function processComponentScss() { 62 | return gulp.src(join(APP_SRC, '**', '*.scss')) 63 | .pipe(isProd ? plugins.cached('process-component-scss') : plugins.util.noop()) 64 | .pipe(isProd ? plugins.progeny() : plugins.util.noop()) 65 | .pipe(plugins.sourcemaps.init()) 66 | .pipe(plugins.sass({includePaths: ['./node_modules/']}).on('error', plugins.sass.logError)) 67 | .pipe(plugins.postcss(processors)) 68 | .pipe(plugins.sourcemaps.write(isProd ? '.' : '')) 69 | .pipe(gulp.dest(isProd ? TMP_DIR : APP_DEST)); 70 | } 71 | 72 | /** 73 | * Processes the CSS files within `src/client` excluding those in `src/client/assets` using `postcss` with the 74 | * configured processors. 75 | */ 76 | function processComponentCss() { 77 | return gulp.src([ 78 | join(APP_SRC, '**', '*.css'), 79 | '!' + join(APP_SRC, 'assets', '**', '*.css') 80 | ]) 81 | .pipe(isProd ? plugins.cached('process-component-css') : plugins.util.noop()) 82 | .pipe(plugins.postcss(processors)) 83 | .pipe(gulp.dest(isProd ? TMP_DIR : APP_DEST)); 84 | } 85 | 86 | /** 87 | * Execute external-stylesheet processing method based on presence of --scss flag. 88 | */ 89 | function processExternalStylesheets() { 90 | return ENABLE_SCSS ? processAllExternalStylesheets() : processExternalCss(); 91 | } 92 | 93 | /** 94 | * Process scss stylesheets located in `src/client/css` and any css dependencies specified in 95 | * the global project configuration. 96 | */ 97 | function processAllExternalStylesheets() { 98 | return merge(getExternalCssStream(), getExternalScssStream()) 99 | .pipe(isProd ? plugins.concatCss(CSS_PROD_BUNDLE) : plugins.util.noop()) 100 | .pipe(plugins.postcss(processors)) 101 | .pipe(isProd ? cleanCss() : plugins.util.noop()) 102 | .pipe(gulp.dest(CSS_DEST)); 103 | } 104 | 105 | /** 106 | * Get a stream of external css files for subsequent processing. 107 | */ 108 | function getExternalCssStream() { 109 | return gulp.src(getExternalCss()) 110 | .pipe(isProd ? plugins.cached('process-external-css') : plugins.util.noop()); 111 | } 112 | 113 | /** 114 | * Get an array of filenames referring to all external css stylesheets. 115 | */ 116 | function getExternalCss() { 117 | return DEPENDENCIES.filter(dep => /\.css$/.test(dep.src)).map(dep => dep.src); 118 | } 119 | 120 | /** 121 | * Get a stream of external scss files for subsequent processing. 122 | */ 123 | function getExternalScssStream() { 124 | return gulp.src(getExternalScss()) 125 | .pipe(isProd ? plugins.cached('process-external-scss') : plugins.util.noop()) 126 | .pipe(isProd ? plugins.progeny() : plugins.util.noop()) 127 | .pipe(plugins.sass({includePaths: ['./node_modules/']}).on('error', plugins.sass.logError)); 128 | } 129 | 130 | /** 131 | * Get an array of filenames referring to external scss stylesheets located in the global DEPENDENCIES 132 | * as well as in `src/css`. 133 | */ 134 | function getExternalScss() { 135 | return DEPENDENCIES.filter(dep => /\.scss$/.test(dep.src)).map(dep => dep.src) 136 | .concat([join(CSS_SRC, '**', '*.scss')]); 137 | } 138 | 139 | /** 140 | * Processes the external CSS files using `postcss` with the configured processors. 141 | */ 142 | function processExternalCss() { 143 | return getExternalCssStream() 144 | .pipe(plugins.postcss(processors)) 145 | .pipe(isProd ? plugins.concatCss(CSS_PROD_BUNDLE) : plugins.util.noop()) 146 | .pipe(isProd ? cleanCss() : plugins.util.noop()) 147 | .pipe(gulp.dest(CSS_DEST)); 148 | } 149 | 150 | /** 151 | * Executes the build process, processing the HTML and CSS files. 152 | */ 153 | export = () => merge(processComponentStylesheets(), prepareTemplates(), processExternalStylesheets()); 154 | -------------------------------------------------------------------------------- /tools/README.md: -------------------------------------------------------------------------------- 1 | # Tools documentation 2 | 3 | This document contains information about the tools section of the `angular2-seed`. 4 | 5 | ## General Information 6 | 7 | The root of this folder contains the following files: 8 | 9 | | Filename | Description | 10 | | :----------- | :---------- | 11 | | `.gitignore` | Adds the generated `*.js` and `.js.map` files to the list of ignores files for git | 12 | | `config.ts` | Exports the project configuration, which contains of the basic configuration provided by `/config/seed.config.ts` and the project specific overrides defined by `/config/project.config.ts` | 13 | | `debug.ts` | Provides the ability to debug a specific build task | 14 | | `README.md` | The documentation of the tools section | 15 | | `utils.ts` | Exports the utilities provided by the seed barrel file (`/utils/seed.utils.ts`) and the project specific barrel file (`/utils/project.utils.ts`) | 16 | 17 | The subfolders provide further folders to distinguish between files which are provided by the seed (located in the corresponding `seed` folder) and files which can be specific by project (to be located in the corresponding `project` folder). This helps you to include updates from the `angular2-seed` without causing conflicts with you personal customisations. 18 | 19 | ## Configuration 20 | 21 | The configuration of the seed contains of a basic configuration provided by `/config/seed.config.ts` file. You can add your own custom configuration within the `/config/project.config.ts` file, which extends the seed configuration. 22 | 23 | ## Manual Typings 24 | 25 | The `manual_typings` folder contains of manual TypeScript typings provided by the seed (`/manual_typings/seed`) and project specific TypeScript typings (`/manual_typings/project`). As for the project specific typings there is a sample provided (`/manual_typings/project/sample.package.d.ts`) to help you get started. 26 | 27 | ## Tasks 28 | 29 | The `tasks` folder contains of tasks provided by the seed (`/tasks/seed`) and project specific tasks (`/tasks/project`). As for the project specific tasks there is a sample provided (`/tasks/project/sample.task.ts`) to help you get started. 30 | 31 | The seed provides the following tasks: 32 | 33 | | Filename | Description | 34 | | :--------------------- | :---------- | 35 | | `build.assets.dev.ts` | Copies the assets (located in `src/client/assets`) over to the `dist/dev/assets` directory | 36 | | `build.assets.prod.ts` | Copies the assets (located in `src/client/assets`) over to the `dist/prod/assets` directory | 37 | | `build.bundles.app.ts` | Bundles the JavaScript files using the SystemJS Builder | 38 | | `build.bundles.ts` | Bundles the JavaScript shim dependencies | 39 | | `build.docs.ts` | Builds the documentation for the TypeScript files using `typedoc` | 40 | | `build.html_css.ts` | Builds the `html` and `css` files and applies CSS postprocessing | 41 | | `build.index.dev.ts` | Builds the `index.html` for the `dev` environment | 42 | | `build.index.prod.ts` | Builds the `index.html` for the `prod` environment | 43 | | `build.js.dev.ts` | Transpiles the TypeScript files (excluding specs and e2e specs) for the `dev` environment | 44 | | `build.js.e2e.ts` | Transpiles the TypeScript files (excluding specs and e2e specs) for the `e2e` environment | 45 | | `build.js.prod.ts` | Transpiles the TypeScript files (excluding specs and e2e specs) for the `prod` environment | 46 | | `build.js.test.ts` | Transpiles the TypeScript files (excluding specs and e2e specs) for the `test` environment | 47 | | `build.js.tools.ts` | Transpiles the TypeScript files located in `/tools` | 48 | | `check.versions.ts` | Checks if the required Node and NPM (as defined in `/config/seed.config.ts`) are installed | 49 | | `clean.all.ts` | Cleans all files within the `/dist` directory | 50 | | `clean.dev.ts` | Cleans all files within the `/dist/dev` directory | 51 | | `clean.prod.ts` | Cleans all files within the `/dist/prod` directory | 52 | | `clean.tools.ts` | Cleans all JavaScript files (which got transpiled from the TypeScript files) within the `/tools` directory | 53 | | `copy.js.prod.ts` | Copies all TypeScript files (excluding specs and e2e specs) over to the `/tmp` dir | 54 | | `css-lint.ts` | Lints all `css` files using `stylelint` | 55 | | `e2e.ts` | Runs all e2e specs using `protractor` | 56 | | `generate.manifest.ts` | Generates a `manifest` file for the application | 57 | | `karma.start.ts` | Starts the unit tests using `karma` | 58 | | `serve.coverage.ts` | Serves the unit test coverage report using an `express` server | 59 | | `serve.docs.ts` | Serves the application documentation using an `express` server | 60 | | `serve.prod.ts` | Serves the files from `/dist/prod` using an `express` server | 61 | | `serve.start.ts` | Serves the files from `/dist/dev` using an `express` server | 62 | | `tslint.ts` | Lints the TypeScript files using `codelyzer` | 63 | | `watch.dev.ts` | Watches for code changes and rebuilds the files in `/dist/dev` | 64 | | `watch.e2e.ts` | Watches for code changes and rebuilds the files in `/dist/e2e` | 65 | | `watch.test.ts` | Watches for code changes and rebuilds the files in `/dist/test` | 66 | | `webdriver.ts` | Installs the Selenium webdriver used for the Protractor e2e specs | 67 | 68 | ## Utilities 69 | 70 | The `utils` folder contains of utilities provided by the seed (`/utils/seed`) and project specific utilities (`/utils/project`). As for the project specific utilities there is a sample provided (`/utils/project/sample_util.ts`) to help you get started. 71 | 72 | The utilities are exported by the barrel files `project.utils.ts` (for the project specific utilities) and `seed.utils.ts` (for the utilities provided by the seed). 73 | 74 | The seed provides the following utilities: 75 | 76 | | Filename | Description | 77 | | :--------------------- | :---------- | 78 | | `clean.ts` | Provides a utility to clean files and directories | 79 | | `code_change_tools.ts` | Provides utilities to make use of BrowserSync to refresh the browser after a code change | 80 | | `server.ts` | Provides utilities to start `express` servers for the application, the documentation and the unit test coverage | 81 | | `task_tools.ts` | Provides utilities to start tasks (matching task names as string input parameters from the `gulpfile.ts` to the corresponding files) | 82 | | `template_locals.ts` | Provides a utility for template locals | 83 | | `tsproject.ts` | Provides a utility to configure the TypeScript transpilation | 84 | | `watch.ts` | Provides a utility to watch for file changes and notify live reloads | 85 | -------------------------------------------------------------------------------- /tools/config/seed.config.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'path'; 2 | import { argv } from 'yargs'; 3 | 4 | import { Environments, InjectableDependency } from './seed.config.interfaces'; 5 | 6 | /** 7 | * The enumeration of available environments. 8 | * @type {Environments} 9 | */ 10 | export const ENVIRONMENTS: Environments = { 11 | DEVELOPMENT: 'dev', 12 | PRODUCTION: 'prod' 13 | }; 14 | 15 | /** 16 | * This class represents the basic configuration of the seed. 17 | * It provides the following: 18 | * - Constants for directories, ports, versions etc. 19 | * - Injectable NPM dependencies 20 | * - Injectable application assets 21 | * - Temporary editor files to be ignored by the watcher and asset builder 22 | * - SystemJS configuration 23 | * - Autoprefixer configuration 24 | * - BrowserSync configuration 25 | * - Utilities 26 | */ 27 | export class SeedConfig { 28 | 29 | /** 30 | * The port where the application will run. 31 | * The default port is `5555`, which can be overriden by the `--port` flag when running `npm start`. 32 | * @type {number} 33 | */ 34 | PORT = argv['port'] || 5555; 35 | 36 | /** 37 | * The root folder of the project (up two levels from the current directory). 38 | */ 39 | PROJECT_ROOT = join(__dirname, '../..'); 40 | 41 | /** 42 | * The current environment. 43 | * The default environment is `dev`, which can be overriden by the `--config-env ENV_NAME` flag when running `npm start`. 44 | */ 45 | ENV = getEnvironment(); 46 | 47 | /** 48 | * The flag for the debug option of the application. 49 | * The default value is `false`, which can be overriden by the `--debug` flag when running `npm start`. 50 | * @type {boolean} 51 | */ 52 | DEBUG = argv['debug'] || false; 53 | 54 | /** 55 | * The port where the documentation application will run. 56 | * The default docs port is `4003`, which can be overriden by the `--docs-port` flag when running `npm start`. 57 | * @type {number} 58 | */ 59 | DOCS_PORT = argv['docs-port'] || 4003; 60 | 61 | /** 62 | * The port where the unit test coverage report application will run. 63 | * The default coverage port is `4004`, which can by overriden by the `--coverage-port` flag when running `npm start`. 64 | * @type {number} 65 | */ 66 | COVERAGE_PORT = argv['coverage-port'] || 4004; 67 | 68 | /** 69 | * The path for the base of the application at runtime. 70 | * The default path is `/`, which can be overriden by the `--base` flag when running `npm start`. 71 | * @type {string} 72 | */ 73 | APP_BASE = argv['base'] || '/'; 74 | 75 | /** 76 | * The base path of node modules. 77 | * @type {string} 78 | */ 79 | NPM_BASE = join(this.APP_BASE, 'node_modules/'); 80 | 81 | /** 82 | * The flag for the hot-loader option of the application. 83 | * Per default the option is not set, but can be set by the `--hot-loader` flag when running `npm start`. 84 | * @type {boolean} 85 | */ 86 | ENABLE_HOT_LOADING = argv['hot-loader']; 87 | 88 | /** 89 | * The port where the application will run, if the `hot-loader` option mode is used. 90 | * The default hot-loader port is `5578`. 91 | * @type {number} 92 | */ 93 | HOT_LOADER_PORT = 5578; 94 | 95 | /** 96 | * The directory where the bootstrap file is located. 97 | * The default directory is `app`. 98 | * @type {string} 99 | */ 100 | BOOTSTRAP_DIR = 'app'; 101 | 102 | /** 103 | * The directory where the client files are located. 104 | * The default directory is `client`. 105 | * @type {string} 106 | */ 107 | APP_CLIENT = argv['client'] || 'client'; 108 | 109 | /** 110 | * The bootstrap file to be used to boot the application. The file to be used is dependent if the hot-loader option is 111 | * used or not. 112 | * Per default (non hot-loader mode) the `main.ts` file will be used, with the hot-loader option enabled, the 113 | * `hot_loader_main.ts` file will be used. 114 | * @type {string} 115 | */ 116 | BOOTSTRAP_MODULE = `${this.BOOTSTRAP_DIR}/` + (this.ENABLE_HOT_LOADING ? 'hot_loader_main' : 'main'); 117 | 118 | /** 119 | * The default title of the application as used in the `` tag of the 120 | * `index.html`. 121 | * @type {string} 122 | */ 123 | APP_TITLE = 'Welcome to angular2-seed!'; 124 | 125 | /** 126 | * The base folder of the applications source files. 127 | * @type {string} 128 | */ 129 | APP_SRC = `src/${this.APP_CLIENT}`; 130 | 131 | /** 132 | * The folder of the applications asset files. 133 | * @type {string} 134 | */ 135 | ASSETS_SRC = `${this.APP_SRC}/assets`; 136 | 137 | /** 138 | * The folder of the applications css files. 139 | * @type {string} 140 | */ 141 | CSS_SRC = `${this.APP_SRC}/css`; 142 | 143 | /** 144 | * The directory of the applications tools 145 | * @type {string} 146 | */ 147 | TOOLS_DIR = 'tools'; 148 | 149 | /** 150 | * The directory of the tasks provided by the seed. 151 | */ 152 | SEED_TASKS_DIR = join(process.cwd(), this.TOOLS_DIR, 'tasks', 'seed'); 153 | 154 | /** 155 | * The destination folder for the generated documentation. 156 | * @type {string} 157 | */ 158 | DOCS_DEST = 'docs'; 159 | 160 | /** 161 | * The base folder for built files. 162 | * @type {string} 163 | */ 164 | DIST_DIR = 'dist'; 165 | 166 | /** 167 | * The folder for built files in the `dev` environment. 168 | * @type {string} 169 | */ 170 | DEV_DEST = `${this.DIST_DIR}/dev`; 171 | 172 | /** 173 | * The folder for the built files in the `prod` environment. 174 | * @type {string} 175 | */ 176 | PROD_DEST = `${this.DIST_DIR}/prod`; 177 | 178 | /** 179 | * The folder for temporary files. 180 | * @type {string} 181 | */ 182 | TMP_DIR = `${this.DIST_DIR}/tmp`; 183 | 184 | /** 185 | * The folder for the built files, corresponding to the current environment. 186 | * @type {string} 187 | */ 188 | APP_DEST = this.ENV === ENVIRONMENTS.DEVELOPMENT ? this.DEV_DEST : this.PROD_DEST; 189 | 190 | /** 191 | * The folder for the built CSS files. 192 | * @type {strings} 193 | */ 194 | CSS_DEST = `${this.APP_DEST}/css`; 195 | 196 | /** 197 | * The folder for the built JavaScript files. 198 | * @type {string} 199 | */ 200 | JS_DEST = `${this.APP_DEST}/js`; 201 | 202 | /** 203 | * The version of the application as defined in the `package.json`. 204 | */ 205 | VERSION = appVersion(); 206 | 207 | /** 208 | * The name of the bundle file to includes all CSS files. 209 | * @type {string} 210 | */ 211 | CSS_PROD_BUNDLE = 'main.css'; 212 | 213 | /** 214 | * The name of the bundle file to include all JavaScript shims. 215 | * @type {string} 216 | */ 217 | JS_PROD_SHIMS_BUNDLE = 'shims.js'; 218 | 219 | /** 220 | * The name of the bundle file to include all JavaScript application files. 221 | * @type {string} 222 | */ 223 | JS_PROD_APP_BUNDLE = 'app.js'; 224 | 225 | /** 226 | * The required NPM version to run the application. 227 | * @type {string} 228 | */ 229 | VERSION_NPM = '2.14.2'; 230 | 231 | /** 232 | * The required NodeJS version to run the application. 233 | * @type {string} 234 | */ 235 | VERSION_NODE = '4.0.0'; 236 | 237 | /** 238 | * The ruleset to be used by `codelyzer` for linting the TypeScript files. 239 | */ 240 | CODELYZER_RULES = customRules(); 241 | 242 | /** 243 | * The flag to enable handling of SCSS files 244 | * The default value is false. Override with the '--scss' flag. 245 | * @type {boolean} 246 | */ 247 | ENABLE_SCSS = argv['scss'] || false; 248 | 249 | /** 250 | * The list of NPM dependcies to be injected in the `index.html`. 251 | * @type {InjectableDependency[]} 252 | */ 253 | NPM_DEPENDENCIES: InjectableDependency[] = [ 254 | { src: 'zone.js/dist/zone.js', inject: 'libs' }, 255 | { src: 'core-js/client/shim.min.js', inject: 'shims' }, 256 | { src: 'systemjs/dist/system.src.js', inject: 'shims', env: ENVIRONMENTS.DEVELOPMENT }, 257 | { src: 'rxjs/bundles/Rx.js', inject: 'libs', env: ENVIRONMENTS.DEVELOPMENT } 258 | ]; 259 | 260 | /** 261 | * The list of local files to be injected in the `index.html`. 262 | * @type {InjectableDependency[]} 263 | */ 264 | APP_ASSETS: InjectableDependency[] = [ 265 | { src: `${this.CSS_SRC}/main.${ this.getInjectableStyleExtension() }`, inject: true, vendor: false }, 266 | ]; 267 | 268 | /** 269 | * The list of editor temporary files to ignore in watcher and asset builder. 270 | * @type {string[]} 271 | */ 272 | TEMP_FILES: string[] = [ 273 | '**/*___jb_tmp___', 274 | '**/*~', 275 | ]; 276 | 277 | /** 278 | * Returns the array of injectable dependencies (npm dependencies and assets). 279 | * @return {InjectableDependency[]} The array of npm dependencies and assets. 280 | */ 281 | get DEPENDENCIES(): InjectableDependency[] { 282 | return normalizeDependencies(this.NPM_DEPENDENCIES.filter(filterDependency.bind(null, this.ENV))) 283 | .concat(this.APP_ASSETS.filter(filterDependency.bind(null, this.ENV))); 284 | } 285 | 286 | /** 287 | * The configuration of SystemJS for the `dev` environment. 288 | * @type {any} 289 | */ 290 | protected SYSTEM_CONFIG_DEV: any = { 291 | defaultJSExtensions: true, 292 | packageConfigPaths: [ 293 | `/node_modules/*/package.json`, 294 | `/node_modules/**/package.json`, 295 | `/node_modules/@angular/*/package.json` 296 | ], 297 | paths: { 298 | [this.BOOTSTRAP_MODULE]: `${this.APP_BASE}${this.BOOTSTRAP_MODULE}`, 299 | '@angular/common': `node_modules/@angular/common/bundles/common.umd.js`, 300 | '@angular/compiler': `node_modules/@angular/compiler/bundles/compiler.umd.js`, 301 | '@angular/core': `node_modules/@angular/core/bundles/core.umd.js`, 302 | '@angular/forms': `node_modules/@angular/forms/bundles/forms.umd.js`, 303 | '@angular/http': `node_modules/@angular/http/bundles/http.umd.js`, 304 | '@angular/platform-browser': `node_modules/@angular/platform-browser/bundles/platform-browser.umd.js`, 305 | '@angular/platform-browser-dynamic': `node_modules/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js`, 306 | '@angular/router': `node_modules/@angular/router/index.js`, 307 | 'rxjs/*': `node_modules/rxjs/*`, 308 | 'app/*': `/app/*`, 309 | '*': `node_modules/*` 310 | }, 311 | packages: { 312 | rxjs: { defaultExtension: false } 313 | } 314 | }; 315 | 316 | /** 317 | * The configuration of SystemJS of the application. 318 | * Per default, the configuration of the `dev` environment will be used. 319 | * @type {any} 320 | */ 321 | SYSTEM_CONFIG: any = this.SYSTEM_CONFIG_DEV; 322 | 323 | /** 324 | * The system builder configuration of the application. 325 | * @type {any} 326 | */ 327 | SYSTEM_BUILDER_CONFIG: any = { 328 | defaultJSExtensions: true, 329 | packageConfigPaths: [ 330 | join(this.PROJECT_ROOT, 'node_modules', '*', 'package.json'), 331 | join(this.PROJECT_ROOT, 'node_modules', '@angular', '*', 'package.json') 332 | ], 333 | paths: { 334 | [`${this.TMP_DIR}/*`]: `${this.TMP_DIR}/*`, 335 | '*': 'node_modules/*' 336 | }, 337 | packages: { 338 | '@angular/common': { 339 | main: 'index.js', 340 | defaultExtension: 'js' 341 | }, 342 | '@angular/compiler': { 343 | main: 'index.js', 344 | defaultExtension: 'js' 345 | }, 346 | '@angular/core': { 347 | main: 'index.js', 348 | defaultExtension: 'js' 349 | }, 350 | '@angular/forms': { 351 | main: 'index.js', 352 | defaultExtension: 'js' 353 | }, 354 | '@angular/http': { 355 | main: 'index.js', 356 | defaultExtension: 'js' 357 | }, 358 | '@angular/platform-browser': { 359 | main: 'index.js', 360 | defaultExtension: 'js' 361 | }, 362 | '@angular/platform-browser-dynamic': { 363 | main: 'index.js', 364 | defaultExtension: 'js' 365 | }, 366 | '@angular/router': { 367 | main: 'index.js', 368 | defaultExtension: 'js' 369 | }, 370 | 'rxjs': { 371 | defaultExtension: 'js' 372 | } 373 | } 374 | }; 375 | 376 | /** 377 | * The Autoprefixer configuration for the application. 378 | * @type {Array} 379 | */ 380 | BROWSER_LIST = [ 381 | 'ie >= 10', 382 | 'ie_mob >= 10', 383 | 'ff >= 30', 384 | 'chrome >= 34', 385 | 'safari >= 7', 386 | 'opera >= 23', 387 | 'ios >= 7', 388 | 'android >= 4.4', 389 | 'bb >= 10' 390 | ]; 391 | 392 | /** 393 | * Configurations for NPM module configurations. Add to or override in project.config.ts. 394 | * If you like, use the mergeObject() method to assist with this. 395 | */ 396 | PLUGIN_CONFIGS: any = { 397 | /** 398 | * The BrowserSync configuration of the application. 399 | * The default open behavior is to open the browser. To prevent the browser from opening use the `--b` flag when 400 | * running `npm start` (tested with serve.dev). 401 | * Example: `npm start -- --b` 402 | * @type {any} 403 | */ 404 | 'browser-sync': { 405 | middleware: [require('connect-history-api-fallback')({ index: `${this.APP_BASE}index.html` })], 406 | port: this.PORT, 407 | startPath: this.APP_BASE, 408 | open: argv['b'] ? false : true, 409 | injectChanges: false, 410 | server: { 411 | baseDir: `${this.DIST_DIR}/empty/`, 412 | routes: { 413 | [`${this.APP_BASE}${this.APP_DEST}`]: this.APP_DEST, 414 | [`${this.APP_BASE}node_modules`]: 'node_modules', 415 | [`${this.APP_BASE.replace(/\/$/, '')}`]: this.APP_DEST 416 | } 417 | } 418 | }, 419 | // Note: you can customize the location of the file 420 | 'environment-config': require('../env/config.json') 421 | }; 422 | 423 | /** 424 | * Recursively merge source onto target. 425 | * @param {any} target The target object (to receive values from source) 426 | * @param {any} source The source object (to be merged onto target) 427 | */ 428 | mergeObject(target: any, source: any) { 429 | const deepExtend = require('deep-extend'); 430 | deepExtend(target, source); 431 | } 432 | 433 | /** 434 | * Locate a plugin configuration object by plugin key. 435 | * @param {any} pluginKey The object key to look up in PLUGIN_CONFIGS. 436 | */ 437 | getPluginConfig(pluginKey: string): any { 438 | if (this.PLUGIN_CONFIGS[ pluginKey ]) { 439 | return this.PLUGIN_CONFIGS[pluginKey]; 440 | } 441 | return null; 442 | } 443 | 444 | getInjectableStyleExtension() { 445 | return this.ENV === ENVIRONMENTS.PRODUCTION && this.ENABLE_SCSS ? 'scss' : 'css'; 446 | } 447 | 448 | } 449 | 450 | /** 451 | * Normalizes the given `deps` to skip globs. 452 | * @param {InjectableDependency[]} deps - The dependencies to be normalized. 453 | */ 454 | export function normalizeDependencies(deps: InjectableDependency[]) { 455 | deps 456 | .filter((d: InjectableDependency) => !/\*/.test(d.src)) // Skip globs 457 | .forEach((d: InjectableDependency) => d.src = require.resolve(d.src)); 458 | return deps; 459 | } 460 | 461 | /** 462 | * Returns if the given dependency is used in the given environment. 463 | * @param {string} env - The environment to be filtered for. 464 | * @param {InjectableDependency} d - The dependency to check. 465 | * @return {boolean} `true` if the dependency is used in this environment, `false` otherwise. 466 | */ 467 | function filterDependency(env: string, d: InjectableDependency): boolean { 468 | if (!d.env) { 469 | d.env = Object.keys(ENVIRONMENTS).map(k => ENVIRONMENTS[k]); 470 | } 471 | if (!(d.env instanceof Array)) { 472 | (<any>d).env = [d.env]; 473 | } 474 | return d.env.indexOf(env) >= 0; 475 | } 476 | 477 | /** 478 | * Returns the applications version as defined in the `package.json`. 479 | * @return {number} The applications version. 480 | */ 481 | function appVersion(): number | string { 482 | var pkg = require('../../package.json'); 483 | return pkg.version; 484 | } 485 | 486 | /** 487 | * Returns the linting configuration to be used for `codelyzer`. 488 | * @return {string[]} The list of linting rules. 489 | */ 490 | function customRules(): string[] { 491 | var lintConf = require('../../tslint.json'); 492 | return lintConf.rulesDirectory; 493 | } 494 | 495 | /** 496 | * Returns the environment of the application. 497 | */ 498 | function getEnvironment() { 499 | let base: string[] = argv['_']; 500 | let prodKeyword = !!base.filter(o => o.indexOf(ENVIRONMENTS.PRODUCTION) >= 0).pop(); 501 | let env = (argv['env'] || '').toLowerCase(); 502 | if ((base && prodKeyword) || env === ENVIRONMENTS.PRODUCTION) { 503 | return ENVIRONMENTS.PRODUCTION; 504 | } else { 505 | return ENVIRONMENTS.DEVELOPMENT; 506 | } 507 | } 508 | --------------------------------------------------------------------------------