mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-18 11:44:05 +08:00
fixup! feat(@schematics/angular): Add schematics for generating functional router guards and resolvers
This commit is contained in:
parent
6c39a162be
commit
b34c719769
@ -13,19 +13,20 @@ import { generateFromFiles } from '../utility/generate-from-files';
|
|||||||
import { Implement as GuardInterface, Schema as GuardOptions } from './schema';
|
import { Implement as GuardInterface, Schema as GuardOptions } from './schema';
|
||||||
|
|
||||||
export default function (options: GuardOptions): Rule {
|
export default function (options: GuardOptions): Rule {
|
||||||
if (options.implements && options.implements.length > 0 && options.guardType) {
|
if (!options.implements) {
|
||||||
throw new SchematicsException('Options "implements" and "guardType" cannot be used together.');
|
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) {
|
if (options.functional) {
|
||||||
const guardType = options.guardType.replace(/^can/, 'Can') + 'Fn';
|
const guardType = options.implements[0] + 'Fn';
|
||||||
|
|
||||||
return generateFromFiles({ ...options, templateFilesDirectory: './type-files' }, { guardType });
|
return generateFromFiles({ ...options, templateFilesDirectory: './type-files' }, { guardType });
|
||||||
} else {
|
} else {
|
||||||
if (!options.implements || options.implements.length < 1) {
|
|
||||||
options.implements = [GuardInterface.CanActivate];
|
|
||||||
}
|
|
||||||
|
|
||||||
const implementations = options.implements
|
const implementations = options.implements
|
||||||
.map((implement) => (implement === 'CanDeactivate' ? 'CanDeactivate<unknown>' : implement))
|
.map((implement) => (implement === 'CanDeactivate' ? 'CanDeactivate<unknown>' : implement))
|
||||||
.join(', ');
|
.join(', ');
|
||||||
|
@ -92,8 +92,8 @@ describe('Guard Schematic', () => {
|
|||||||
expect(fileString).not.toContain('canLoad');
|
expect(fileString).not.toContain('canLoad');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should respect the guardType value', async () => {
|
it('should respect the functional guard value', async () => {
|
||||||
const options = { ...defaultOptions, guardType: 'canActivate' };
|
const options = { ...defaultOptions, implements: ['CanActivate'], functional: true };
|
||||||
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
|
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
|
||||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
||||||
expect(fileString).toContain('export const fooGuard: CanActivateFn = (route, state) => {');
|
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 () => {
|
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 tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
|
||||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.spec.ts');
|
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.spec.ts');
|
||||||
expect(fileString).toContain('const executeGuard: CanActivateFn = (...guardParameters) => ');
|
expect(fileString).toContain('const executeGuard: CanActivateFn = (...guardParameters) => ');
|
||||||
@ -113,8 +113,8 @@ describe('Guard Schematic', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate CanDeactivateFn with unknown guardType', async () => {
|
it('should generate CanDeactivateFn with unknown functional guard', async () => {
|
||||||
const options = { ...defaultOptions, guardType: 'canDeactivate' };
|
const options = { ...defaultOptions, implements: ['CanDeactivate'], functional: true };
|
||||||
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
|
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
|
||||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
||||||
expect(fileString).toContain(
|
expect(fileString).toContain(
|
||||||
@ -157,8 +157,8 @@ describe('Guard Schematic', () => {
|
|||||||
expect(fileString).toContain(expectedImports);
|
expect(fileString).toContain(expectedImports);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add correct imports based on canLoad guardType', async () => {
|
it('should add correct imports based on canLoad functional guard', async () => {
|
||||||
const options = { ...defaultOptions, guardType: 'canLoad' };
|
const options = { ...defaultOptions, implements: ['CanLoad'], functional: true };
|
||||||
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
|
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
|
||||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
||||||
const expectedImports = `import { CanLoadFn } from '@angular/router';`;
|
const expectedImports = `import { CanLoadFn } from '@angular/router';`;
|
||||||
@ -176,8 +176,8 @@ describe('Guard Schematic', () => {
|
|||||||
expect(fileString).toContain(expectedImports);
|
expect(fileString).toContain(expectedImports);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add correct imports based on canActivate guardType', async () => {
|
it('should add correct imports based on canActivate functional guard', async () => {
|
||||||
const options = { ...defaultOptions, guardType: 'canActivate' };
|
const options = { ...defaultOptions, implements: ['CanActivate'], functional: true };
|
||||||
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
|
const tree = await schematicRunner.runSchematicAsync('guard', options, appTree).toPromise();
|
||||||
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
|
||||||
const expectedImports = `import { CanActivateFn } from '@angular/router';`;
|
const expectedImports = `import { CanActivateFn } from '@angular/router';`;
|
||||||
|
@ -41,20 +41,22 @@
|
|||||||
"$source": "projectName"
|
"$source": "projectName"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"functional": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Specifies whether to generate a guard as a function.",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
"implements": {
|
"implements": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"description": "Specifies which interfaces to implement.",
|
"description": "Specifies which type of guard to create.",
|
||||||
"uniqueItems": true,
|
"uniqueItems": true,
|
||||||
"minItems": 1,
|
"minItems": 1,
|
||||||
"items": {
|
"items": {
|
||||||
"enum": ["CanActivate", "CanActivateChild", "CanDeactivate", "CanLoad", "CanMatch"],
|
"enum": ["CanActivate", "CanActivateChild", "CanDeactivate", "CanLoad", "CanMatch"],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
},
|
||||||
},
|
"default": ["CanActivate"],
|
||||||
"guardType": {
|
"x-prompt": "Which type of guard would you like to create?"
|
||||||
"type": "string",
|
|
||||||
"description": "Specifies type of guard to generate.",
|
|
||||||
"enum": ["canActivate", "canActivateChild", "canDeactivate", "canLoad", "canMatch"]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["name", "project"]
|
"required": ["name", "project"]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user