fixup! feat(@schematics/angular): Add schematics for generating functional router guards and resolvers

This commit is contained in:
Andrew Scott 2022-11-08 10:58:21 -08:00 committed by Alan Agius
parent 6c39a162be
commit b34c719769
3 changed files with 27 additions and 24 deletions

View File

@ -13,19 +13,20 @@ import { generateFromFiles } from '../utility/generate-from-files';
import { Implement as GuardInterface, Schema as GuardOptions } from './schema';
export default function (options: GuardOptions): Rule {
if (options.implements && options.implements.length > 0 && options.guardType) {
throw new SchematicsException('Options "implements" and "guardType" cannot be used together.');
if (!options.implements) {
throw new SchematicsException('Option "implements" is required.');
}
if (options.implements.length > 1 && options.functional) {
throw new SchematicsException(
'Can only specify one value for implements when generating a functional guard.',
);
}
if (options.guardType) {
const guardType = options.guardType.replace(/^can/, 'Can') + 'Fn';
if (options.functional) {
const guardType = options.implements[0] + 'Fn';
return generateFromFiles({ ...options, templateFilesDirectory: './type-files' }, { guardType });
} else {
if (!options.implements || options.implements.length < 1) {
options.implements = [GuardInterface.CanActivate];
}
const implementations = options.implements
.map((implement) => (implement === 'CanDeactivate' ? 'CanDeactivate<unknown>' : implement))
.join(', ');

View File

@ -92,8 +92,8 @@ describe('Guard Schematic', () => {
expect(fileString).not.toContain('canLoad');
});
it('should respect the guardType value', async () => {
const options = { ...defaultOptions, guardType: 'canActivate' };
it('should respect the functional guard value', async () => {
const options = { ...defaultOptions, implements: ['CanActivate'], functional: true };
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
expect(fileString).toContain('export const fooGuard: CanActivateFn = (route, state) => {');
@ -104,7 +104,7 @@ describe('Guard Schematic', () => {
});
it('should generate a helper function to execute the guard in a test', async () => {
const options = { ...defaultOptions, guardType: 'canActivate' };
const options = { ...defaultOptions, implements: ['CanActivate'], functional: true };
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.spec.ts');
expect(fileString).toContain('const executeGuard: CanActivateFn = (...guardParameters) => ');
@ -113,8 +113,8 @@ describe('Guard Schematic', () => {
);
});
it('should generate CanDeactivateFn with unknown guardType', async () => {
const options = { ...defaultOptions, guardType: 'canDeactivate' };
it('should generate CanDeactivateFn with unknown functional guard', async () => {
const options = { ...defaultOptions, implements: ['CanDeactivate'], functional: true };
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
expect(fileString).toContain(
@ -157,8 +157,8 @@ describe('Guard Schematic', () => {
expect(fileString).toContain(expectedImports);
});
it('should add correct imports based on canLoad guardType', async () => {
const options = { ...defaultOptions, guardType: 'canLoad' };
it('should add correct imports based on canLoad functional guard', async () => {
const options = { ...defaultOptions, implements: ['CanLoad'], functional: true };
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
const expectedImports = `import { CanLoadFn } from '@angular/router';`;
@ -176,8 +176,8 @@ describe('Guard Schematic', () => {
expect(fileString).toContain(expectedImports);
});
it('should add correct imports based on canActivate guardType', async () => {
const options = { ...defaultOptions, guardType: 'canActivate' };
it('should add correct imports based on canActivate functional guard', async () => {
const options = { ...defaultOptions, implements: ['CanActivate'], functional: true };
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
const expectedImports = `import { CanActivateFn } from '@angular/router';`;

View File

@ -41,20 +41,22 @@
"$source": "projectName"
}
},
"functional": {
"type": "boolean",
"description": "Specifies whether to generate a guard as a function.",
"default": false
},
"implements": {
"type": "array",
"description": "Specifies which interfaces to implement.",
"description": "Specifies which type of guard to create.",
"uniqueItems": true,
"minItems": 1,
"items": {
"enum": ["CanActivate", "CanActivateChild", "CanDeactivate", "CanLoad", "CanMatch"],
"type": "string"
}
},
"guardType": {
"type": "string",
"description": "Specifies type of guard to generate.",
"enum": ["canActivate", "canActivateChild", "canDeactivate", "canLoad", "canMatch"]
},
"default": ["CanActivate"],
"x-prompt": "Which type of guard would you like to create?"
}
},
"required": ["name", "project"]