formats all the files
This commit is contained in:
parent
20d7a1b8d9
commit
7cd989508d
@ -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');
|
||||||
|
|||||||
@ -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]');
|
||||||
|
|
||||||
|
|||||||
@ -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');
|
||||||
|
|||||||
@ -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');
|
||||||
|
|||||||
@ -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`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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`
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
export { DataPersistence } from './utils/data-persistence';
|
export {DataPersistence} from './utils/data-persistence';
|
||||||
|
|||||||
@ -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)
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
4
src/schematics/app/schema.d.ts
vendored
4
src/schematics/app/schema.d.ts
vendored
@ -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;
|
||||||
|
|||||||
@ -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)
|
|
||||||
])),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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)
|
|
||||||
])),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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}'`);
|
||||||
|
|||||||
@ -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 !)
|
|
||||||
]))
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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';
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user