BREAKING CHANGES: The minimal flag is set to true The syntax flag is set to creators The useDataPersistence flag is set to false BEFORE: By default, the root Store and Effects modules are registered, with a generated feature By default, the action classes syntax is used for scaffolding By default, the DataPersistence class in injected and used in Effects AFTER: By default, only the root Store and Effects modules are registered By default, the creator functions are used for scaffolding with schematics By default, the DataPersistence operators are used in Effects
115 lines
2.8 KiB
TypeScript
115 lines
2.8 KiB
TypeScript
import {
|
|
apply,
|
|
chain,
|
|
url,
|
|
mergeWith,
|
|
template,
|
|
move,
|
|
noop,
|
|
filter,
|
|
Rule,
|
|
Tree,
|
|
SchematicContext
|
|
} from '@angular-devkit/schematics';
|
|
|
|
import { Schema } from './schema';
|
|
import * as path from 'path';
|
|
|
|
import { names, toFileName } from '@nrwl/workspace';
|
|
|
|
import {
|
|
addImportsToModule,
|
|
addNgRxToPackageJson,
|
|
addExportsToBarrel,
|
|
RequestContext
|
|
} from './rules';
|
|
import { formatFiles } from '@nrwl/workspace';
|
|
|
|
/**
|
|
* Rule to generate the Nx 'ngrx' Collection
|
|
* Note: see https://nx.dev/angular/guides/misc-ngrx for guide to generated files
|
|
*/
|
|
export default function generateNgrxCollection(_options: Schema): Rule {
|
|
return (host: Tree, context: SchematicContext) => {
|
|
const options = normalizeOptions(_options);
|
|
|
|
if (!options.module) {
|
|
throw new Error(`The required --module option must be passed`);
|
|
} else if (!host.exists(options.module)) {
|
|
throw new Error(`Path does not exist: ${options.module}`);
|
|
}
|
|
|
|
const requestContext: RequestContext = {
|
|
featureName: options.name,
|
|
moduleDir: path.dirname(options.module),
|
|
options,
|
|
host
|
|
};
|
|
|
|
if (options.minimal) {
|
|
options.onlyEmptyRoot = true;
|
|
}
|
|
|
|
if (options.skipImport) {
|
|
options.onlyAddFiles = true;
|
|
}
|
|
|
|
const fileGeneration =
|
|
!options.onlyEmptyRoot || (!options.root && options.minimal)
|
|
? [generateNgrxFilesFromTemplates(options)]
|
|
: [];
|
|
|
|
const moduleModification = !options.onlyAddFiles
|
|
? [
|
|
addImportsToModule(requestContext),
|
|
addExportsToBarrel(requestContext.options)
|
|
]
|
|
: [];
|
|
|
|
const packageJsonModification = !options.skipPackageJson
|
|
? [addNgRxToPackageJson()]
|
|
: [];
|
|
|
|
return chain([
|
|
...fileGeneration,
|
|
...moduleModification,
|
|
...packageJsonModification,
|
|
formatFiles(options)
|
|
])(host, context);
|
|
};
|
|
}
|
|
|
|
// ********************************************************
|
|
// Internal Function
|
|
// ********************************************************
|
|
|
|
/**
|
|
* Generate 'feature' scaffolding: actions, reducer, effects, interfaces, selectors, facade
|
|
*/
|
|
function generateNgrxFilesFromTemplates(options: Schema) {
|
|
const name = options.name;
|
|
const moduleDir = path.dirname(options.module);
|
|
const excludeFacade = path => path.match(/^((?!facade).)*$/);
|
|
|
|
const templateSource = apply(
|
|
url(options.syntax === 'creators' ? './creator-files' : './files'),
|
|
[
|
|
!options.facade ? filter(excludeFacade) : noop(),
|
|
template({ ...options, tmpl: '', ...names(name) }),
|
|
move(moduleDir)
|
|
]
|
|
);
|
|
|
|
return mergeWith(templateSource);
|
|
}
|
|
|
|
/**
|
|
* Extract the parent 'directory' for the specified
|
|
*/
|
|
function normalizeOptions(options: Schema): Schema {
|
|
return {
|
|
...options,
|
|
directory: toFileName(options.directory)
|
|
};
|
|
}
|