formats all the files

This commit is contained in:
vsavkin 2017-08-24 21:00:12 -04:00
parent 20d7a1b8d9
commit 7cd989508d
18 changed files with 121 additions and 227 deletions

View File

@ -1,7 +1,4 @@
import { import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from './utils';
addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic,
updateFile
} from './utils';
describe('addNgRxToModule', () => { describe('addNgRxToModule', () => {
beforeEach(cleanup); beforeEach(cleanup);
@ -11,14 +8,10 @@ describe('addNgRxToModule', () => {
runSchematic('@nrwl/nx:addNgRxToModule --module=src/app/app.module.ts --root', {projectName: 'proj'}); runSchematic('@nrwl/nx:addNgRxToModule --module=src/app/app.module.ts --root', {projectName: 'proj'});
checkFilesExists( checkFilesExists(
`proj/src/app/+state/app.actions.ts`, `proj/src/app/+state/app.actions.ts`, `proj/src/app/+state/app.effects.ts`,
`proj/src/app/+state/app.effects.ts`, `proj/src/app/+state/app.effects.spec.ts`, `proj/src/app/+state/app.init.ts`,
`proj/src/app/+state/app.effects.spec.ts`, `proj/src/app/+state/app.interfaces.ts`, `proj/src/app/+state/app.reducer.ts`,
`proj/src/app/+state/app.init.ts`, `proj/src/app/+state/app.reducer.spec.ts`);
`proj/src/app/+state/app.interfaces.ts`,
`proj/src/app/+state/app.reducer.ts`,
`proj/src/app/+state/app.reducer.spec.ts`
);
const contents = readFile('proj/src/app/app.module.ts'); const contents = readFile('proj/src/app/app.module.ts');
expect(contents).toContain('StoreModule.forRoot'); expect(contents).toContain('StoreModule.forRoot');
@ -49,14 +42,10 @@ describe('addNgRxToModule', () => {
runSchematic('@nrwl/nx:addNgRxToModule --module=src/app/app.module.ts', {projectName: 'proj3'}); runSchematic('@nrwl/nx:addNgRxToModule --module=src/app/app.module.ts', {projectName: 'proj3'});
checkFilesExists( checkFilesExists(
`proj3/src/app/+state/app.actions.ts`, `proj3/src/app/+state/app.actions.ts`, `proj3/src/app/+state/app.effects.ts`,
`proj3/src/app/+state/app.effects.ts`, `proj3/src/app/+state/app.effects.spec.ts`, `proj3/src/app/+state/app.init.ts`,
`proj3/src/app/+state/app.effects.spec.ts`, `proj3/src/app/+state/app.interfaces.ts`, `proj3/src/app/+state/app.reducer.ts`,
`proj3/src/app/+state/app.init.ts`, `proj3/src/app/+state/app.reducer.spec.ts`);
`proj3/src/app/+state/app.interfaces.ts`,
`proj3/src/app/+state/app.reducer.ts`,
`proj3/src/app/+state/app.reducer.spec.ts`
);
const contents = readFile('proj3/src/app/app.module.ts'); const contents = readFile('proj3/src/app/app.module.ts');
expect(contents).toContain('StoreModule.forFeature'); expect(contents).toContain('StoreModule.forFeature');
@ -68,14 +57,10 @@ describe('addNgRxToModule', () => {
runSchematic('@nrwl/nx:addNgRxToModule --module=src/app/app.module.ts --skipImport', {projectName: 'proj4'}); runSchematic('@nrwl/nx:addNgRxToModule --module=src/app/app.module.ts --skipImport', {projectName: 'proj4'});
checkFilesExists( checkFilesExists(
`proj4/src/app/+state/app.actions.ts`, `proj4/src/app/+state/app.actions.ts`, `proj4/src/app/+state/app.effects.ts`,
`proj4/src/app/+state/app.effects.ts`, `proj4/src/app/+state/app.effects.spec.ts`, `proj4/src/app/+state/app.init.ts`,
`proj4/src/app/+state/app.effects.spec.ts`, `proj4/src/app/+state/app.interfaces.ts`, `proj4/src/app/+state/app.reducer.ts`,
`proj4/src/app/+state/app.init.ts`, `proj4/src/app/+state/app.reducer.spec.ts`);
`proj4/src/app/+state/app.interfaces.ts`,
`proj4/src/app/+state/app.reducer.ts`,
`proj4/src/app/+state/app.reducer.spec.ts`
);
const contents = readFile('proj4/src/app/app.module.ts'); const contents = readFile('proj4/src/app/app.module.ts');
expect(contents).not.toContain('StoreModule'); expect(contents).not.toContain('StoreModule');

View File

@ -1,7 +1,4 @@
import { import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from './utils';
addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic,
updateFile
} from './utils';
describe('application', () => { describe('application', () => {
beforeEach(cleanup); beforeEach(cleanup);
@ -11,14 +8,9 @@ describe('application', () => {
runSchematic('@nrwl/nx:app --name=myApp', {projectName: 'proj'}); runSchematic('@nrwl/nx:app --name=myApp', {projectName: 'proj'});
checkFilesExists( checkFilesExists(
`proj/tsconfig.json`, `proj/tsconfig.json`, `proj/WORKSPACE`, `proj/BUILD.bazel`, `proj/apps/my-app/BUILD.bazel`,
`proj/WORKSPACE`, `proj/apps/my-app/src/index.html`, `proj/apps/my-app/src/app/app.module.ts`,
`proj/BUILD.bazel`, `proj/apps/my-app/src/app/app.component.ts`);
`proj/apps/my-app/BUILD.bazel`,
`proj/apps/my-app/src/index.html`,
`proj/apps/my-app/src/app/app.module.ts`,
`proj/apps/my-app/src/app/app.component.ts`
);
expect(readFile('proj/apps/my-app/src/app/app.module.ts')).toContain('bootstrap: [AppComponent]'); expect(readFile('proj/apps/my-app/src/app/app.module.ts')).toContain('bootstrap: [AppComponent]');

View File

@ -1,7 +1,4 @@
import { import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from './utils';
addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic,
updateFile
} from './utils';
describe('library', () => { describe('library', () => {
beforeEach(cleanup); beforeEach(cleanup);
@ -11,13 +8,8 @@ describe('library', () => {
runSchematic('@nrwl/nx:lib --name=myLib', {projectName: 'proj'}); runSchematic('@nrwl/nx:lib --name=myLib', {projectName: 'proj'});
checkFilesExists( checkFilesExists(
`proj/tsconfig.json`, `proj/tsconfig.json`, `proj/WORKSPACE`, `proj/BUILD.bazel`, `proj/libs/my-lib/BUILD.bazel`,
`proj/WORKSPACE`, `proj/libs/my-lib/index.ts`, `proj/libs/my-lib/src/my-lib.ts`);
`proj/BUILD.bazel`,
`proj/libs/my-lib/BUILD.bazel`,
`proj/libs/my-lib/index.ts`,
`proj/libs/my-lib/src/my-lib.ts`
);
const cliConfig = JSON.parse(readFile('proj/.angular-cli.json')); const cliConfig = JSON.parse(readFile('proj/.angular-cli.json'));
expect(cliConfig.apps[0].name).toEqual('myLib'); expect(cliConfig.apps[0].name).toEqual('myLib');

View File

@ -1,7 +1,4 @@
import { import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from './utils';
addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic,
updateFile
} from './utils';
describe('angular library', () => { describe('angular library', () => {
beforeEach(cleanup); beforeEach(cleanup);
@ -11,13 +8,8 @@ describe('angular library', () => {
runSchematic('@nrwl/nx:nglib --name=myLib', {projectName: 'proj'}); runSchematic('@nrwl/nx:nglib --name=myLib', {projectName: 'proj'});
checkFilesExists( checkFilesExists(
`proj/tsconfig.json`, `proj/tsconfig.json`, `proj/WORKSPACE`, `proj/BUILD.bazel`, `proj/libs/my-lib/BUILD.bazel`,
`proj/WORKSPACE`, `proj/libs/my-lib/index.ts`, `proj/libs/my-lib/src/my-lib.module.ts`);
`proj/BUILD.bazel`,
`proj/libs/my-lib/BUILD.bazel`,
`proj/libs/my-lib/index.ts`,
`proj/libs/my-lib/src/my-lib.module.ts`
);
const cliConfig = JSON.parse(readFile('proj/.angular-cli.json')); const cliConfig = JSON.parse(readFile('proj/.angular-cli.json'));
expect(cliConfig.apps[0].name).toEqual('myLib'); expect(cliConfig.apps[0].name).toEqual('myLib');

View File

@ -1,6 +1,6 @@
import {execSync} from 'child_process'; import {execSync} from 'child_process';
import * as path from 'path';
import {readFileSync, statSync, writeFileSync} from 'fs'; import {readFileSync, statSync, writeFileSync} from 'fs';
import * as path from 'path';
export function newApp(command: string): string { export function newApp(command: string): string {
return execSync(`../node_modules/.bin/ng ${command}`, {cwd: `./tmp`}).toString(); return execSync(`../node_modules/.bin/ng ${command}`, {cwd: `./tmp`}).toString();
@ -26,7 +26,7 @@ export function updateFile(f: string, content: string): void {
export function checkFilesExists(...expectedFiles: string[]) { export function checkFilesExists(...expectedFiles: string[]) {
expectedFiles.forEach(f => { expectedFiles.forEach(f => {
const ff = f.startsWith('/') ? f : path.join(getCwd(), 'tmp', f); const ff = f.startsWith('/') ? f : path.join(getCwd(), 'tmp', f);
if (! exists(ff)) { if (!exists(ff)) {
throw new Error(`File '${ff}' does not exist`); throw new Error(`File '${ff}' does not exist`);
} }
}); });

View File

@ -1,7 +1,4 @@
import { import {addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic, updateFile} from './utils';
addNgRx, checkFilesExists, cleanup, newApp, readFile, runCLI, runCommand, runSchematic,
updateFile
} from './utils';
describe('workspace', () => { describe('workspace', () => {
beforeEach(cleanup); beforeEach(cleanup);
@ -9,10 +6,6 @@ describe('workspace', () => {
it('creates a new workspace for developing angular applications', () => { it('creates a new workspace for developing angular applications', () => {
runSchematic('@nrwl/nx:application --name=proj --version=0.1'); runSchematic('@nrwl/nx:application --name=proj --version=0.1');
checkFilesExists( checkFilesExists(`proj/tsconfig.json`, `proj/WORKSPACE`, `proj/BUILD.bazel`);
`proj/tsconfig.json`,
`proj/WORKSPACE`,
`proj/BUILD.bazel`
);
}); });
}); });

View File

@ -1 +1 @@
export { DataPersistence } from './utils/data-persistence'; export {DataPersistence} from './utils/data-persistence';

View File

@ -1,6 +1,6 @@
import {apply, branchAndMerge, chain, mergeWith, move, Rule, template, Tree, url} from '@angular-devkit/schematics'; import {apply, branchAndMerge, chain, mergeWith, move, Rule, template, Tree, url} from '@angular-devkit/schematics';
import {names, toClassName, toFileName, toPropertyName} from "../name-utils"; import {names, toClassName, toFileName, toPropertyName} from '../name-utils';
import * as path from 'path'; import * as path from 'path';
import * as ts from 'typescript'; import * as ts from 'typescript';
import {addImportToModule, addProviderToModule, insert} from '../utility/ast-utils'; import {addImportToModule, addProviderToModule, insert} from '../utility/ast-utils';
@ -18,7 +18,7 @@ function addImportsToModule(name: string, options: any): Rule {
const modulePath = options.module; const modulePath = options.module;
const sourceText = host.read(modulePath) !.toString('utf-8'); const sourceText = host.read(modulePath)!.toString('utf-8');
const source = ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true); const source = ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true);
if (options.emptyRoot) { if (options.emptyRoot) {
@ -38,42 +38,33 @@ function addImportsToModule(name: string, options: any): Rule {
const effectsName = `${toClassName(name)}Effects`; const effectsName = `${toClassName(name)}Effects`;
const initName = `${toPropertyName(name)}InitialState`; const initName = `${toPropertyName(name)}InitialState`;
const effects = options.root ? `EffectsModule.forRoot([${effectsName}])` : `EffectsModule.forFeature([${effectsName}])`; const effects =
const reducer = options.root ? `StoreModule.forRoot(${reducerName}, {initialState: ${initName}})` : `StoreModule.forFeature('${toPropertyName(name)}', ${reducerName}, {initialState: ${initName}})`; options.root ? `EffectsModule.forRoot([${effectsName}])` : `EffectsModule.forFeature([${effectsName}])`;
const reducer = options.root ?
`StoreModule.forRoot(${reducerName}, {initialState: ${initName}})` :
`StoreModule.forFeature('${toPropertyName(name)}', ${reducerName}, {initialState: ${initName}})`;
insert(host, modulePath, [ insert(host, modulePath, [
insertImport(source, modulePath, 'StoreModule', '@ngrx/store'), insertImport(source, modulePath, 'StoreModule', '@ngrx/store'),
insertImport(source, modulePath, 'EffectsModule', '@ngrx/effects'), insertImport(source, modulePath, 'EffectsModule', '@ngrx/effects'),
insertImport(source, modulePath, reducerName, reducerPath), insertImport(source, modulePath, reducerName, reducerPath),
insertImport(source, modulePath, initName, initPath), insertImport(source, modulePath, initName, initPath),
insertImport(source, modulePath, effectsName, effectsPath), insertImport(source, modulePath, effectsName, effectsPath), ...addImportToModule(source, modulePath, reducer),
...addImportToModule(source, modulePath, reducer), ...addImportToModule(source, modulePath, effects), ...addProviderToModule(source, modulePath, effectsName)
...addImportToModule(source, modulePath, effects),
...addProviderToModule(source, modulePath, effectsName)
]); ]);
return host; return host;
} }
}; };
} }
export default function (options: any): Rule { export default function(options: any): Rule {
const name = path.basename(options.module, ".module.ts"); const name = path.basename(options.module, '.module.ts');
const moduleDir = path.dirname(options.module); const moduleDir = path.dirname(options.module);
if (options.emptyRoot) { if (options.emptyRoot) {
return chain([ return chain([addImportsToModule(name, options)]);
addImportsToModule(name, options)
]);
} else { } else {
const templateSource = apply(url('./files'), [ const templateSource = apply(url('./files'), [template({...options, tmpl: '', ...names(name)}), move(moduleDir)]);
template({...options, tmpl: '', ...names(name)}), return chain([branchAndMerge(chain([mergeWith(templateSource)])), addImportsToModule(name, options)]);
move(moduleDir)
]);
return chain([
branchAndMerge(chain([
mergeWith(templateSource)
])),
addImportsToModule(name, options)
]);
} }
} }

View File

@ -20,25 +20,20 @@ function addBootstrap(path: string): Rule {
function addAppToAngularCliJson(fullPath: string, options: Schema): Rule { function addAppToAngularCliJson(fullPath: string, options: Schema): Rule {
return (host: Tree) => { return (host: Tree) => {
const config = JSON.parse(host.read('.angular-cli.json') !.toString('utf-8')); const config = JSON.parse(host.read('.angular-cli.json')!.toString('utf-8'));
config.apps.push({ config.apps.push({
name: options.name, name: options.name,
root: fullPath, root: fullPath,
assets: ["assets", "favicon.ico"], assets: ['assets', 'favicon.ico'],
index: "index.html", index: 'index.html',
main: "main.ts", main: 'main.ts',
polyfills: "polyfills.ts", polyfills: 'polyfills.ts',
prefix: options.name, prefix: options.name,
styles: [ styles: ['styles.css'],
"styles.css"
],
scripts: [], scripts: [],
environmentSource: "environments/environment.ts", environmentSource: 'environments/environment.ts',
environments: { environments: {'dev': 'environments/environment.ts', 'prod': 'environments/environment.prod.ts'}
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}); });
host.overwrite('.angular-cli.json', JSON.stringify(config, null, 2)); host.overwrite('.angular-cli.json', JSON.stringify(config, null, 2));
@ -47,18 +42,10 @@ function addAppToAngularCliJson(fullPath: string, options: Schema): Rule {
} }
export default function (options: Schema): Rule { export default function(options: Schema): Rule {
const fullPath = path.join(options.directory, toFileName(options.name), options.sourceDir); const fullPath = path.join(options.directory, toFileName(options.name), options.sourceDir);
return chain([ return chain([
mergeWith( mergeWith(apply(url('./files'), [template({...options, ...names(options.name), 'dot': '.', 'tmpl': ''})])),
apply(url('./files'), [
template({
...options,
...names(options.name),
'dot': '.',
'tmpl': ''
})
])),
externalSchematic('@schematics/angular', 'module', { externalSchematic('@schematics/angular', 'module', {
name: 'app', name: 'app',
commonModule: false, commonModule: false,
@ -79,7 +66,6 @@ export default function (options: Schema): Rule {
viewEncapsulation: options.viewEncapsulation, viewEncapsulation: options.viewEncapsulation,
changeDetection: options.changeDetection changeDetection: options.changeDetection
}), }),
addBootstrap(fullPath), addBootstrap(fullPath), addAppToAngularCliJson(fullPath, options)
addAppToAngularCliJson(fullPath, options)
]); ]);
} }

View File

@ -4,8 +4,8 @@ export interface Schema {
sourceDir?: string; sourceDir?: string;
inlineStyle?: boolean; inlineStyle?: boolean;
inlineTemplate?: boolean; inlineTemplate?: boolean;
viewEncapsulation?: ("Emulated" | "Native" | "None"); viewEncapsulation?: ('Emulated'|'Native'|'None');
changeDetection?: ("Default" | "OnPush"); changeDetection?: ('Default'|'OnPush');
prefix?: string; prefix?: string;
style?: string; style?: string;
skipTests?: boolean; skipTests?: boolean;

View File

@ -5,7 +5,7 @@ import {names, toFileName} from '../name-utils';
function addLibToAngularCliJson(fullPath: string, schema: Schema): Rule { function addLibToAngularCliJson(fullPath: string, schema: Schema): Rule {
return (host: Tree) => { return (host: Tree) => {
const source = JSON.parse(host.read('.angular-cli.json') !.toString('utf-8')); const source = JSON.parse(host.read('.angular-cli.json')!.toString('utf-8'));
source.apps.push({ source.apps.push({
name: schema.name, name: schema.name,
root: fullPath, root: fullPath,
@ -15,22 +15,12 @@ function addLibToAngularCliJson(fullPath: string, schema: Schema): Rule {
}; };
} }
export default function (options: any): Rule { export default function(options: any): Rule {
const fullPath = path.join(options.directory, toFileName(options.name), options.sourceDir); const fullPath = path.join(options.directory, toFileName(options.name), options.sourceDir);
const templateSource = apply(url('./files'), [ const templateSource = apply(url('./files'), [template({...options, ...names(options.name), dot: '.', tmpl: ''})]);
template({
...options,
...names(options.name),
dot: '.',
tmpl: ''
})
]);
return chain([ return chain([
branchAndMerge(chain([ branchAndMerge(chain([mergeWith(templateSource), addLibToAngularCliJson(fullPath, options)])),
mergeWith(templateSource),
addLibToAngularCliJson(fullPath, options)
])),
]); ]);
} }

View File

@ -1,10 +1,5 @@
export function names(name: string): any { export function names(name: string): any {
return { return {name, className: toClassName(name), propertyName: toPropertyName(name), fileName: toFileName(name)};
name,
className: toClassName(name),
propertyName: toPropertyName(name),
fileName: toFileName(name)
};
} }
export function toClassName(str: string): string { export function toClassName(str: string): string {
@ -12,9 +7,8 @@ export function toClassName(str: string): string {
} }
export function toPropertyName(s: string): string { export function toPropertyName(s: string): string {
return s return s.replace(/(-|_|\.|\s)+(.)?/g, (_, __, chr) => chr ? chr.toUpperCase() : '')
.replace(/(-|_|\.|\s)+(.)?/g, (_, __, chr) => chr ? chr.toUpperCase() : '') .replace(/^([A-Z])/, m => m.toLowerCase());
.replace(/^([A-Z])/, m => m.toLowerCase());
} }
export function toFileName(s: string): string { export function toFileName(s: string): string {

View File

@ -5,33 +5,19 @@ import {names, toFileName} from '../name-utils';
function addLibToAngularCliJson(fullPath: string, schema: Schema): Rule { function addLibToAngularCliJson(fullPath: string, schema: Schema): Rule {
return (host: Tree) => { return (host: Tree) => {
const source = JSON.parse(host.read('.angular-cli.json') !.toString('utf-8')); const source = JSON.parse(host.read('.angular-cli.json')!.toString('utf-8'));
source.apps.push({ source.apps.push({name: schema.name, root: fullPath, prefix: schema.prefix ? schema.prefix : schema.name});
name: schema.name,
root: fullPath,
prefix: schema.prefix ? schema.prefix : schema.name
});
host.overwrite('.angular-cli.json', JSON.stringify(source, null, 2)); host.overwrite('.angular-cli.json', JSON.stringify(source, null, 2));
return host; return host;
}; };
} }
export default function (options: any): Rule { export default function(options: any): Rule {
const fullPath = path.join(options.directory, toFileName(options.name), options.sourceDir); const fullPath = path.join(options.directory, toFileName(options.name), options.sourceDir);
const templateSource = apply(url('./files'), [ const templateSource = apply(url('./files'), [template({...options, ...names(options.name), dot: '.', tmpl: ''})]);
template({
...options,
...names(options.name),
dot: '.',
tmpl: ''
})
]);
return chain([ return chain([
branchAndMerge(chain([ branchAndMerge(chain([mergeWith(templateSource), addLibToAngularCliJson(fullPath, options)])),
mergeWith(templateSource),
addLibToAngularCliJson(fullPath, options)
])),
]); ]);
} }

View File

@ -5,16 +5,15 @@
* Use of this source code is governed by an MIT-style license that can be * Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import * as ts from 'typescript';
import {Tree} from '@angular-devkit/schematics'; import {Tree} from '@angular-devkit/schematics';
import {getDecoratorMetadata} from '@schematics/angular/utility/ast-utils'; import {getDecoratorMetadata} from '@schematics/angular/utility/ast-utils';
import {Change, InsertChange, NoopChange} from '@schematics/angular/utility/change'; import {Change, InsertChange, NoopChange} from '@schematics/angular/utility/change';
import * as ts from 'typescript';
// This should be moved to @schematics/angular once it allows to pass custom expressions as providers // This should be moved to @schematics/angular once it allows to pass custom expressions as providers
function _addSymbolToNgModuleMetadata(source: ts.SourceFile, function _addSymbolToNgModuleMetadata(
ngModulePath: string, metadataField: string, source: ts.SourceFile, ngModulePath: string, metadataField: string, expression: string): Change[] {
expression: string): Change[] {
const nodes = getDecoratorMetadata(source, 'NgModule', '@angular/core'); const nodes = getDecoratorMetadata(source, 'NgModule', '@angular/core');
let node: any = nodes[0]; // tslint:disable-line:no-any let node: any = nodes[0]; // tslint:disable-line:no-any
@ -25,21 +24,22 @@ function _addSymbolToNgModuleMetadata(source: ts.SourceFile,
// Get all the children property assignment of object literals. // Get all the children property assignment of object literals.
const matchingProperties: ts.ObjectLiteralElement[] = const matchingProperties: ts.ObjectLiteralElement[] =
(node as ts.ObjectLiteralExpression).properties (node as ts.ObjectLiteralExpression)
.filter(prop => prop.kind == ts.SyntaxKind.PropertyAssignment) .properties
// Filter out every fields that's not "metadataField". Also handles string literals .filter(prop => prop.kind == ts.SyntaxKind.PropertyAssignment)
// (but not expressions). // Filter out every fields that's not "metadataField". Also handles string literals
.filter((prop: ts.PropertyAssignment) => { // (but not expressions).
const name = prop.name; .filter((prop: ts.PropertyAssignment) => {
switch (name.kind) { const name = prop.name;
case ts.SyntaxKind.Identifier: switch (name.kind) {
return (name as ts.Identifier).getText(source) == metadataField; case ts.SyntaxKind.Identifier:
case ts.SyntaxKind.StringLiteral: return (name as ts.Identifier).getText(source) == metadataField;
return (name as ts.StringLiteral).text == metadataField; case ts.SyntaxKind.StringLiteral:
} return (name as ts.StringLiteral).text == metadataField;
}
return false; return false;
}); });
// Get the last node of the array literal. // Get the last node of the array literal.
if (!matchingProperties) { if (!matchingProperties) {
@ -136,14 +136,16 @@ function _addSymbolToNgModuleMetadata(source: ts.SourceFile,
return [insert]; return [insert];
} }
export function addImportToModule(source: ts.SourceFile, export function addImportToModule(source: ts.SourceFile, modulePath: string, symbolName: string): Change[] {
modulePath: string, symbolName: string): Change[] { return _addSymbolToNgModuleMetadata(
source,
return _addSymbolToNgModuleMetadata(source, modulePath, 'imports', symbolName,); modulePath,
'imports',
symbolName,
);
} }
export function addProviderToModule(source: ts.SourceFile, export function addProviderToModule(source: ts.SourceFile, modulePath: string, symbolName: string): Change[] {
modulePath: string, symbolName: string): Change[] {
return _addSymbolToNgModuleMetadata(source, modulePath, 'providers', symbolName); return _addSymbolToNgModuleMetadata(source, modulePath, 'providers', symbolName);
} }
@ -153,7 +155,7 @@ export function insert(host: Tree, modulePath: string, changes: Change[]) {
for (const change of changes) { for (const change of changes) {
if (change instanceof InsertChange) { if (change instanceof InsertChange) {
recorder.insertLeft(change.pos, change.toAdd); recorder.insertLeft(change.pos, change.toAdd);
} else if (change instanceof NoopChange) { } else if (change instanceof NoopChange) {
// do nothing // do nothing
} else { } else {
throw new Error(`Unexpected Change '${change}'`); throw new Error(`Unexpected Change '${change}'`);

View File

@ -2,17 +2,7 @@ import {apply, chain, mergeWith, move, Rule, schematic, template, url,} from '@a
import {Schema} from './schema'; import {Schema} from './schema';
import {names} from '../name-utils'; import {names} from '../name-utils';
export default function (options: Schema): Rule { export default function(options: Schema): Rule {
return chain([ return chain([mergeWith(apply(
mergeWith( url('./files'), [template({...options, ...names(options.name), 'dot': '.', 'tmpl': ''}), move(options.name!)]))]);
apply(url('./files'), [
template({
...options,
...names(options.name),
'dot': '.',
'tmpl': ''
}),
move(options.name !)
]))
]);
} }

View File

@ -1,2 +1,2 @@
export { readAll } from './utils/testing'; export {cold, hot} from 'jasmine-marbles';
export { hot, cold } from 'jasmine-marbles'; export {readAll} from './utils/testing';

View File

@ -1,46 +1,46 @@
import {Injectable, Type} from '@angular/core';
import {ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import {Actions} from '@ngrx/effects'; import {Actions} from '@ngrx/effects';
import {ROUTER_NAVIGATION, RouterNavigationAction} from '@ngrx/router-store';
import {Action, State, Store} from '@ngrx/store'; import {Action, State, Store} from '@ngrx/store';
import {Observable} from 'rxjs/Observable'; import {Observable} from 'rxjs/Observable';
import {ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router'; import {of} from 'rxjs/observable/of';
import {ROUTER_NAVIGATION, RouterNavigationAction} from '@ngrx/router-store';
import {Injectable, Type} from '@angular/core';
import {filter} from 'rxjs/operator/filter';
import {withLatestFrom} from 'rxjs/operator/withLatestFrom';
import {switchMap} from 'rxjs/operator/switchMap';
import {_catch} from 'rxjs/operator/catch'; import {_catch} from 'rxjs/operator/catch';
import {concatMap} from 'rxjs/operator/concatMap'; import {concatMap} from 'rxjs/operator/concatMap';
import {filter} from 'rxjs/operator/filter';
import {map} from 'rxjs/operator/map'; import {map} from 'rxjs/operator/map';
import {of} from 'rxjs/observable/of'; import {switchMap} from 'rxjs/operator/switchMap';
import {withLatestFrom} from 'rxjs/operator/withLatestFrom';
/** /**
* See DataPersistence.pessimisticUpdate for more information. * See DataPersistence.pessimisticUpdate for more information.
*/ */
export interface PessimisticUpdateOpts { export interface PessimisticUpdateOpts {
run(a: Action, state?: any): Observable<Action> | Action | void; run(a: Action, state?: any): Observable<Action>|Action|void;
onError(a: Action, e: any): Observable<any> | any; onError(a: Action, e: any): Observable<any>|any;
} }
/** /**
* See DataPersistence.pessimisticUpdate for more information. * See DataPersistence.pessimisticUpdate for more information.
*/ */
export interface OptimisticUpdateOpts { export interface OptimisticUpdateOpts {
run(a: Action, state?: any): Observable<any> | any; run(a: Action, state?: any): Observable<any>|any;
undoAction(a: Action, e: any): Observable<Action> | Action; undoAction(a: Action, e: any): Observable<Action>|Action;
} }
/** /**
* See DataPersistence.navigation for more information. * See DataPersistence.navigation for more information.
*/ */
export interface FetchOpts { export interface FetchOpts {
run(a: Action, state?: any): Observable<Action> | Action | void; run(a: Action, state?: any): Observable<Action>|Action|void;
onError?(a: Action, e: any): Observable<any> | any; onError?(a: Action, e: any): Observable<any>|any;
} }
/** /**
* See DataPersistence.navigation for more information. * See DataPersistence.navigation for more information.
*/ */
export interface HandleNavigationOpts { export interface HandleNavigationOpts {
run(a: ActivatedRouteSnapshot, state?: any): Observable<Action> | Action | void; run(a: ActivatedRouteSnapshot, state?: any): Observable<Action>|Action|void;
onError?(a: ActivatedRouteSnapshot, e: any): Observable<any> | any; onError?(a: ActivatedRouteSnapshot, e: any): Observable<any>|any;
} }
/** /**
@ -188,9 +188,10 @@ export class DataPersistence<T> {
*/ */
navigation(component: Type<any>, opts: HandleNavigationOpts): Observable<any> { navigation(component: Type<any>, opts: HandleNavigationOpts): Observable<any> {
const nav = filter.call( const nav = filter.call(
map.call(this.actions.ofType(ROUTER_NAVIGATION), map.call(
(a: RouterNavigationAction<RouterStateSnapshot>) => findSnapshot(component, a.payload.routerState.root)), this.actions.ofType(ROUTER_NAVIGATION),
s => !!s); (a: RouterNavigationAction<RouterStateSnapshot>) => findSnapshot(component, a.payload.routerState.root)),
s => !!s);
const pairs = withLatestFrom.call(nav, this.store); const pairs = withLatestFrom.call(nav, this.store);
return switchMap.call(pairs, this.runWithErrorHandling(opts.run, opts.onError)); return switchMap.call(pairs, this.runWithErrorHandling(opts.run, opts.onError));
@ -225,8 +226,8 @@ function wrapIntoObservable(obj: any): Observable<any> {
if (!!obj && typeof obj.subscribe === 'function') { if (!!obj && typeof obj.subscribe === 'function') {
return obj; return obj;
} else if (!obj) { } else if (!obj) {
return of(); return of ();
} else { } else {
return of(obj); return of (obj);
} }
} }

View File

@ -1,6 +1,6 @@
import {Observable} from 'rxjs/Observable'; import {Observable} from 'rxjs/Observable';
import {toPromise} from 'rxjs/operator/toPromise';
import {toArray} from 'rxjs/operator/toArray'; import {toArray} from 'rxjs/operator/toArray';
import {toPromise} from 'rxjs/operator/toPromise';
export function readAll<T>(o: Observable<T>): Promise<T[]> { export function readAll<T>(o: Observable<T>): Promise<T[]> {
return toPromise.call(toArray.call(o)); return toPromise.call(toArray.call(o));