diff --git a/modules/store/migrations/13_0_0-beta/index.spec.ts b/modules/store/migrations/13_0_0-beta/index.spec.ts new file mode 100644 index 0000000000..e29c2a4a8a --- /dev/null +++ b/modules/store/migrations/13_0_0-beta/index.spec.ts @@ -0,0 +1,54 @@ +import { Tree } from '@angular-devkit/schematics'; +import { + SchematicTestRunner, + UnitTestTree, +} from '@angular-devkit/schematics/testing'; +import * as path from 'path'; + +describe('Store Migration 13_0_0 beta', () => { + const collectionPath = path.join(__dirname, '../migration.json'); + const pkgName = 'store'; + + it(`should replace createFeatureSelector usages with 2 generics`, async () => { + const contents = ` +import {createFeatureSelector} from '@ngrx/store' + +// untouched +const featureSelector1 = createFeatureSelector('feature1'); +const featureSelector2 = createFeatureSelector(feature2); +const featureSelector3 = createFeatureSelector(feature3); +const featureSelector4 = createFeatureSelector('feature4'); + +// modified +const featureSelector5 = createFeatureSelector('feature5'); +const featureSelector6 = createFeatureSelector(feature6); +const featureSelector7 = createFeatureSelector('feature7'); +`; + + const expected = ` +import {createFeatureSelector} from '@ngrx/store' + +// untouched +const featureSelector1 = createFeatureSelector('feature1'); +const featureSelector2 = createFeatureSelector(feature2); +const featureSelector3 = createFeatureSelector(feature3); +const featureSelector4 = createFeatureSelector('feature4'); + +// modified +const featureSelector5 = createFeatureSelector< Feature>('feature5'); +const featureSelector6 = createFeatureSelector(feature6); +const featureSelector7 = createFeatureSelector< fromFeat.State>('feature7'); +`; + + const appTree = new UnitTestTree(Tree.empty()); + appTree.create('./fixture.ts', contents); + const runner = new SchematicTestRunner('schematics', collectionPath); + + const newTree = await runner + .runSchematicAsync(`ngrx-${pkgName}-migration-13-beta`, {}, appTree) + .toPromise(); + const file = newTree.readContent('fixture.ts'); + + expect(file).toBe(expected); + }); +}); diff --git a/modules/store/migrations/13_0_0-beta/index.ts b/modules/store/migrations/13_0_0-beta/index.ts new file mode 100644 index 0000000000..f53d064fa7 --- /dev/null +++ b/modules/store/migrations/13_0_0-beta/index.ts @@ -0,0 +1,55 @@ +import * as ts from 'typescript'; +import { Rule, chain, Tree } from '@angular-devkit/schematics'; +import { + visitTSSourceFiles, + RemoveChange, + commitChanges, +} from '../../schematics-core'; + +function updateCreateFeatureSelectorGenerics(): Rule { + return (tree: Tree) => { + visitTSSourceFiles(tree, (sourceFile) => { + const runMigration = sourceFile.statements + .filter(ts.isImportDeclaration) + .filter( + (importDeclaration) => + importDeclaration.moduleSpecifier.getText(sourceFile) === + "'@ngrx/store'" || + importDeclaration.moduleSpecifier.getText(sourceFile) === + '"@ngrx/store"' + ) + .some((importDeclaration) => { + return importDeclaration.importClause?.namedBindings + ?.getText(sourceFile) + .includes('createFeatureSelector'); + }); + + if (!runMigration) return; + + const changes: RemoveChange[] = []; + ts.forEachChild(sourceFile, crawl); + return commitChanges(tree, sourceFile.fileName, changes); + + function crawl(node: ts.Node) { + ts.forEachChild(node, crawl); + + if (!ts.isCallExpression(node)) return; + if (node.typeArguments?.length !== 2) return; + if (!ts.isIdentifier(node.expression)) return; + if (node.expression.text !== 'createFeatureSelector') return; + + changes.push( + new RemoveChange( + sourceFile.fileName, + node.typeArguments[0].pos, + node.typeArguments[1].pos + ) + ); + } + }); + }; +} + +export default function (): Rule { + return chain([updateCreateFeatureSelectorGenerics()]); +} diff --git a/modules/store/migrations/migration.json b/modules/store/migrations/migration.json index 907c89cc56..28a89f3352 100644 --- a/modules/store/migrations/migration.json +++ b/modules/store/migrations/migration.json @@ -15,6 +15,11 @@ "description": "The road to v8 RC", "version": "8-rc.1", "factory": "./8_0_0-rc/index" + }, + "ngrx-store-migration-13-beta": { + "description": "The road to v13 beta", + "version": "13-beta", + "factory": "./13_0_0-beta/index" } } }