From 055a654699182b733777d6ecad0720a013a6ca15 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 4 Apr 2025 11:48:04 -0400 Subject: [PATCH] fix(@schematics/angular): generate resolvers with a dash type separator To align with the updated style guide, Angular v20 will generate resolvers with file extension `resolver` type prefixed with a `-` separator instead of a `.` by default. Projects will automatically use this naming convention. Projects can however opt-out by setting the `typeSeparator` option to `.` for the resolver schematic. This can be done as a default in the `angular.json` or directly on the commandline via `--type-separator=.` when executing `ng generate`. As an example, `example.resolver.ts` will now be named `example-resolver.ts`. The TypeScript declaration will continue to contain `Resolver` such as with `ExampleResolver`. --- packages/schematics/angular/guard/schema.json | 3 +- packages/schematics/angular/pipe/schema.json | 3 +- ..._typeSeparator__resolver.spec.ts.template} | 2 +- ...ze____typeSeparator__resolver.ts.template} | 0 ..._typeSeparator__resolver.spec.ts.template} | 2 +- ...ze____typeSeparator__resolver.ts.template} | 0 .../schematics/angular/resolver/index_spec.ts | 40 ++++++++++++++----- .../schematics/angular/resolver/schema.json | 6 +++ 8 files changed, 43 insertions(+), 13 deletions(-) rename packages/schematics/angular/resolver/class-files/{__name@dasherize__.resolver.spec.ts.template => __name@dasherize____typeSeparator__resolver.spec.ts.template} (91%) rename packages/schematics/angular/resolver/class-files/{__name@dasherize__.resolver.ts.template => __name@dasherize____typeSeparator__resolver.ts.template} (100%) rename packages/schematics/angular/resolver/functional-files/{__name@dasherize__.resolver.spec.ts.template => __name@dasherize____typeSeparator__resolver.spec.ts.template} (93%) rename packages/schematics/angular/resolver/functional-files/{__name@dasherize__.resolver.ts.template => __name@dasherize____typeSeparator__resolver.ts.template} (100%) diff --git a/packages/schematics/angular/guard/schema.json b/packages/schematics/angular/guard/schema.json index feb6385e356a..9e1a9f3084c6 100644 --- a/packages/schematics/angular/guard/schema.json +++ b/packages/schematics/angular/guard/schema.json @@ -62,7 +62,8 @@ "typeSeparator": { "type": "string", "default": "-", - "enum": ["-", "."] + "enum": ["-", "."], + "description": "The separator character to use before the type within the generated file's name. For example, if you set the option to `.`, the file will be named `example.guard.ts`." } }, "required": ["name", "project"] diff --git a/packages/schematics/angular/pipe/schema.json b/packages/schematics/angular/pipe/schema.json index 69b86cc9fe1c..19803a524ed4 100644 --- a/packages/schematics/angular/pipe/schema.json +++ b/packages/schematics/angular/pipe/schema.json @@ -65,7 +65,8 @@ "typeSeparator": { "type": "string", "default": "-", - "enum": ["-", "."] + "enum": ["-", "."], + "description": "The separator character to use before the type within the generated file's name. For example, if you set the option to `.`, the file will be named `example.pipe.ts`." } }, "required": ["name", "project"] diff --git a/packages/schematics/angular/resolver/class-files/__name@dasherize__.resolver.spec.ts.template b/packages/schematics/angular/resolver/class-files/__name@dasherize____typeSeparator__resolver.spec.ts.template similarity index 91% rename from packages/schematics/angular/resolver/class-files/__name@dasherize__.resolver.spec.ts.template rename to packages/schematics/angular/resolver/class-files/__name@dasherize____typeSeparator__resolver.spec.ts.template index 3cd1e381185e..af27433460e5 100644 --- a/packages/schematics/angular/resolver/class-files/__name@dasherize__.resolver.spec.ts.template +++ b/packages/schematics/angular/resolver/class-files/__name@dasherize____typeSeparator__resolver.spec.ts.template @@ -1,6 +1,6 @@ import { TestBed } from '@angular/core/testing'; -import { <%= classify(name) %>Resolver } from './<%= dasherize(name) %>.resolver'; +import { <%= classify(name) %>Resolver } from './<%= dasherize(name) %><%= typeSeparator %>resolver'; describe('<%= classify(name) %>Resolver', () => { let resolver: <%= classify(name) %>Resolver; diff --git a/packages/schematics/angular/resolver/class-files/__name@dasherize__.resolver.ts.template b/packages/schematics/angular/resolver/class-files/__name@dasherize____typeSeparator__resolver.ts.template similarity index 100% rename from packages/schematics/angular/resolver/class-files/__name@dasherize__.resolver.ts.template rename to packages/schematics/angular/resolver/class-files/__name@dasherize____typeSeparator__resolver.ts.template diff --git a/packages/schematics/angular/resolver/functional-files/__name@dasherize__.resolver.spec.ts.template b/packages/schematics/angular/resolver/functional-files/__name@dasherize____typeSeparator__resolver.spec.ts.template similarity index 93% rename from packages/schematics/angular/resolver/functional-files/__name@dasherize__.resolver.spec.ts.template rename to packages/schematics/angular/resolver/functional-files/__name@dasherize____typeSeparator__resolver.spec.ts.template index 4e03cb15174e..c9f42a1a0bd5 100644 --- a/packages/schematics/angular/resolver/functional-files/__name@dasherize__.resolver.spec.ts.template +++ b/packages/schematics/angular/resolver/functional-files/__name@dasherize____typeSeparator__resolver.spec.ts.template @@ -1,7 +1,7 @@ import { TestBed } from '@angular/core/testing'; import { ResolveFn } from '@angular/router'; -import { <%= camelize(name) %>Resolver } from './<%= dasherize(name) %>.resolver'; +import { <%= camelize(name) %>Resolver } from './<%= dasherize(name) %><%= typeSeparator %>resolver'; describe('<%= camelize(name) %>Resolver', () => { const executeResolver: ResolveFn = (...resolverParameters) => diff --git a/packages/schematics/angular/resolver/functional-files/__name@dasherize__.resolver.ts.template b/packages/schematics/angular/resolver/functional-files/__name@dasherize____typeSeparator__resolver.ts.template similarity index 100% rename from packages/schematics/angular/resolver/functional-files/__name@dasherize__.resolver.ts.template rename to packages/schematics/angular/resolver/functional-files/__name@dasherize____typeSeparator__resolver.ts.template diff --git a/packages/schematics/angular/resolver/index_spec.ts b/packages/schematics/angular/resolver/index_spec.ts index 66a935e45261..1315ee6f01ce 100644 --- a/packages/schematics/angular/resolver/index_spec.ts +++ b/packages/schematics/angular/resolver/index_spec.ts @@ -48,9 +48,9 @@ describe('resolver Schematic', () => { appTree, ); const files = tree.files; - expect(files).toContain('/projects/bar/src/app/foo.resolver.spec.ts'); - expect(files).toContain('/projects/bar/src/app/foo.resolver.ts'); - const fileString = tree.readContent('/projects/bar/src/app/foo.resolver.ts'); + expect(files).toContain('/projects/bar/src/app/foo-resolver.spec.ts'); + expect(files).toContain('/projects/bar/src/app/foo-resolver.ts'); + const fileString = tree.readContent('/projects/bar/src/app/foo-resolver.ts'); expect(fileString).toContain('export class FooResolver implements Resolve'); }); @@ -59,8 +59,30 @@ describe('resolver Schematic', () => { const tree = await schematicRunner.runSchematic('resolver', options, appTree); const files = tree.files; - expect(files).not.toContain('/projects/bar/src/app/foo.resolver.spec.ts'); + expect(files).not.toContain('/projects/bar/src/app/foo-resolver.spec.ts'); + expect(files).toContain('/projects/bar/src/app/foo-resolver.ts'); + }); + + it('should use a `.` type separator when specified', async () => { + const options = { ...defaultOptions, typeSeparator: '.' }; + + const tree = await schematicRunner.runSchematic('resolver', options, appTree); + const files = tree.files; + expect(files).toContain('/projects/bar/src/app/foo.resolver.spec.ts'); expect(files).toContain('/projects/bar/src/app/foo.resolver.ts'); + const specContent = tree.readContent('/projects/bar/src/app/foo.resolver.spec.ts'); + expect(specContent).toContain(`'./foo.resolver'`); + }); + + it('should use a `-` type separator when specified', async () => { + const options = { ...defaultOptions, typeSeparator: '-' }; + + const tree = await schematicRunner.runSchematic('resolver', options, appTree); + const files = tree.files; + expect(files).toContain('/projects/bar/src/app/foo-resolver.spec.ts'); + expect(files).toContain('/projects/bar/src/app/foo-resolver.ts'); + const specContent = tree.readContent('/projects/bar/src/app/foo-resolver.spec.ts'); + expect(specContent).toContain(`'./foo-resolver'`); }); it('should respect the flat flag', async () => { @@ -68,8 +90,8 @@ describe('resolver Schematic', () => { const tree = await schematicRunner.runSchematic('resolver', options, appTree); const files = tree.files; - expect(files).toContain('/projects/bar/src/app/foo/foo.resolver.spec.ts'); - expect(files).toContain('/projects/bar/src/app/foo/foo.resolver.ts'); + expect(files).toContain('/projects/bar/src/app/foo/foo-resolver.spec.ts'); + expect(files).toContain('/projects/bar/src/app/foo/foo-resolver.ts'); }); it('should respect the sourceRoot value', async () => { @@ -77,12 +99,12 @@ describe('resolver Schematic', () => { config.projects.bar.sourceRoot = 'projects/bar/custom'; appTree.overwrite('/angular.json', JSON.stringify(config, null, 2)); appTree = await schematicRunner.runSchematic('resolver', defaultOptions, appTree); - expect(appTree.files).toContain('/projects/bar/custom/app/foo.resolver.ts'); + expect(appTree.files).toContain('/projects/bar/custom/app/foo-resolver.ts'); }); it('should create a functional resolver', async () => { const tree = await schematicRunner.runSchematic('resolver', defaultOptions, appTree); - const fileString = tree.readContent('/projects/bar/src/app/foo.resolver.ts'); + const fileString = tree.readContent('/projects/bar/src/app/foo-resolver.ts'); expect(fileString).toContain( 'export const fooResolver: ResolveFn = (route, state) => {', ); @@ -90,7 +112,7 @@ describe('resolver Schematic', () => { it('should create a helper function to run a functional resolver in a test', async () => { const tree = await schematicRunner.runSchematic('resolver', defaultOptions, appTree); - const fileString = tree.readContent('/projects/bar/src/app/foo.resolver.spec.ts'); + const fileString = tree.readContent('/projects/bar/src/app/foo-resolver.spec.ts'); expect(fileString).toContain( 'const executeResolver: ResolveFn = (...resolverParameters) => ', ); diff --git a/packages/schematics/angular/resolver/schema.json b/packages/schematics/angular/resolver/schema.json index a364e9271397..1a5654f3c7cf 100644 --- a/packages/schematics/angular/resolver/schema.json +++ b/packages/schematics/angular/resolver/schema.json @@ -45,6 +45,12 @@ "$default": { "$source": "projectName" } + }, + "typeSeparator": { + "type": "string", + "default": "-", + "enum": ["-", "."], + "description": "The separator character to use before the type within the generated file's name. For example, if you set the option to `.`, the file will be named `example.resolver.ts`." } }, "required": ["name", "project"]