From 9406cad7afc02baf6551cd78635585b4a88af554 Mon Sep 17 00:00:00 2001 From: Rainer Hahnekamp Date: Sun, 1 Dec 2024 02:01:42 +0100 Subject: [PATCH 1/6] feat(signals): add migration for `withProps` This migration script applies to an update to version 19.0.0 RC 1. It addresses #4608, and will rename `computed` to `props` in the following scenarios: - `signalStoreFeature({computed: type<{}>())` - `signalStoreFeature(type<{computed: Signal())` - `SignalStoreFeature<{computed: {}}>` - `EntityComputed` and `NamedEntityComputed` --- .../18_0_0-rc_3-protected-state/index.ts | 14 +- .../19_0_0-rc_1-props/index.spec.ts | 259 ++++++++++++++++++ .../migrations/19_0_0-rc_1-props/index.ts | 224 +++++++++++++++ modules/signals/migrations/migration.json | 5 + .../signals/schematics-core/tsconfig.lib.json | 2 +- .../schematics-core/utility/visitors.ts | 80 ++++++ 6 files changed, 570 insertions(+), 14 deletions(-) create mode 100644 modules/signals/migrations/19_0_0-rc_1-props/index.spec.ts create mode 100644 modules/signals/migrations/19_0_0-rc_1-props/index.ts diff --git a/modules/signals/migrations/18_0_0-rc_3-protected-state/index.ts b/modules/signals/migrations/18_0_0-rc_3-protected-state/index.ts index 84004d620d..9fbe95b5fb 100644 --- a/modules/signals/migrations/18_0_0-rc_3-protected-state/index.ts +++ b/modules/signals/migrations/18_0_0-rc_3-protected-state/index.ts @@ -6,6 +6,7 @@ import { import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; import * as ts from 'typescript'; import { commitChanges } from '../../schematics-core'; +import { visitImportDeclaration } from '../../schematics-core/utility/visitors'; export default function migrateWritableStateSource(): Rule { return (tree: Tree, ctx: SchematicContext) => { @@ -89,19 +90,6 @@ function visitCallExpression( }); } -function visitImportDeclaration( - node: ts.Node, - callback: (importDeclaration: ts.ImportDeclaration) => void -) { - if (ts.isImportDeclaration(node)) { - callback(node); - } - - ts.forEachChild(node, (child) => { - visitImportDeclaration(child, callback); - }); -} - function findImportedName(source: ts.SourceFile) { let importedName = ''; visitImportDeclaration(source, (importDeclaration) => { diff --git a/modules/signals/migrations/19_0_0-rc_1-props/index.spec.ts b/modules/signals/migrations/19_0_0-rc_1-props/index.spec.ts new file mode 100644 index 0000000000..3b2c03c29d --- /dev/null +++ b/modules/signals/migrations/19_0_0-rc_1-props/index.spec.ts @@ -0,0 +1,259 @@ +import * as path from 'path'; +import { + SchematicTestRunner, + UnitTestTree, +} from '@angular-devkit/schematics/testing'; +import { createWorkspace } from '@ngrx/schematics-core/testing'; +import { tags } from '@angular-devkit/core'; +import { LogEntry } from '@angular-devkit/core/src/logger'; + +describe('migrate to props', () => { + const collectionPath = path.join(__dirname, '../migration.json'); + const schematicRunner = new SchematicTestRunner('schematics', collectionPath); + + let appTree: UnitTestTree; + + beforeEach(async () => { + appTree = await createWorkspace(schematicRunner, appTree); + }); + + const verifySchematic = async (input: string, output: string) => { + appTree.create('main.ts', input); + + const logEntries: string[] = []; + schematicRunner.logger.subscribe((logEntry) => + logEntries.push(logEntry.message) + ); + + const tree = await schematicRunner.runSchematic( + `19_0_0-rc_1-props`, + {}, + appTree + ); + + const actual = tree.readContent('main.ts'); + + expect(actual).toBe(output); + + return logEntries; + }; + + it('renames (Named)EntityComputed imports to (Named)EntityProps', async () => { + const input = tags.stripIndent` +import { EntityComputed, NamedEntityComputed } from '@ngrx/signals/entities'; +`; + + const output = tags.stripIndent` +import { EntityProps, NamedEntityProps } from '@ngrx/signals/entities'; +`; + + const logEntries = await verifySchematic(input, output); + expect(logEntries).toEqual([ + "[@ngrx/signals] Renamed '(Named)EntityComputed' to '(Named)EntityProps' in /main.ts", + ]); + }); + + it('replaces property `computed` in `SignalStoreFeature` to `props`', async () => { + const input = tags.stripIndent` +import { signalStoreFeature, type } from '@ngrx/signals'; +import { Signal } from '@angular/core'; + +export function withMyFeature() { + return signalStoreFeature({ computed: type<{ num: Signal }>() }); +} +`; + + const output = tags.stripIndent` +import { signalStoreFeature, type } from '@ngrx/signals'; +import { Signal } from '@angular/core'; + +export function withMyFeature() { + return signalStoreFeature({ props: type<{ num: Signal }>() }); +} +`; + + const logEntries = await verifySchematic(input, output); + expect(logEntries).toEqual([ + "[@ngrx/signals] Renamed 'computed' to 'props' in signalStoreFeature() in /main.ts", + ]); + }); + + it('replaces property `computed` in `type` with `signalStoreFeature` to `props`', async () => { + const input = tags.stripIndent` +export function withMyFeature() { + return signalStoreFeature( + type<{ computed: { num: Signal } }>() + ); +} +`; + + const output = tags.stripIndent` +export function withMyFeature() { + return signalStoreFeature( + type<{ props: { num: Signal } }>() + ); +} +`; + + await verifySchematic(input, output); + }); + + it('replaces `computed` in `SignalStoreFeature` to `props`', async () => { + const input = tags.stripIndent` +import { SignalStoreFeature } from '@ngrx/signals'; +import { Signal } from '@angular/core'; + +declare function withMyFeature(): SignalStoreFeature< + { state: {}; computed: { num1: Signal }; methods: {} }, + { state: {}; computed: { num2: Signal }; methods: {} } +>; +`; + + const output = tags.stripIndent` +import { SignalStoreFeature } from '@ngrx/signals'; +import { Signal } from '@angular/core'; + +declare function withMyFeature(): SignalStoreFeature< + { state: {}; props: { num1: Signal }; methods: {} }, + { state: {}; props: { num2: Signal }; methods: {} } +>; +`; + + const logEntries = await verifySchematic(input, output); + expect(logEntries).toEqual([ + "[@ngrx/signals] Renamed 'computed' to 'props' in SignalStoreFeature<> in /main.ts", + ]); + }); + + test('kitchen sink', async () => { + const input = tags.stripIndent` +import { EntityComputed, NamedEntityComputed } from '@ngrx/signals/entities'; +import { + EmptyFeatureResult, + SignalStoreFeature, + signalStoreFeature, + type, + withHooks, + withMethods, +} from '@ngrx/signals'; +import { rxMethod } from '@ngrx/signals/rxjs-interop'; +import { tap } from 'rxjs/operators'; +import { Signal } from '@angular/core'; + +declare function withNamedDataService< + E extends { id: number }, + Collection extends string +>(): SignalStoreFeature< + EmptyFeatureResult & { computed: NamedEntityComputed } +>; + +declare function withDataService< + E extends { id: number }, + Collection extends string +>(): SignalStoreFeature }>; + +export function withConsoleLogger() { + return signalStoreFeature( + { computed: type<{ pretty: Signal }>() }, + withMethods(() => ({ + log: rxMethod(tap((message) => console.log(message))), + })), + withHooks((store) => ({ + onInit() { + store.log(store.pretty()); + }, + })) + ); +}`; + + const output = tags.stripIndent` +import { EntityProps, NamedEntityProps } from '@ngrx/signals/entities'; +import { + EmptyFeatureResult, + SignalStoreFeature, + signalStoreFeature, + type, + withHooks, + withMethods, +} from '@ngrx/signals'; +import { rxMethod } from '@ngrx/signals/rxjs-interop'; +import { tap } from 'rxjs/operators'; +import { Signal } from '@angular/core'; + +declare function withNamedDataService< + E extends { id: number }, + Collection extends string +>(): SignalStoreFeature< + EmptyFeatureResult & { props: NamedEntityProps } +>; + +declare function withDataService< + E extends { id: number }, + Collection extends string +>(): SignalStoreFeature }>; + +export function withConsoleLogger() { + return signalStoreFeature( + { props: type<{ pretty: Signal }>() }, + withMethods(() => ({ + log: rxMethod(tap((message) => console.log(message))), + })), + withHooks((store) => ({ + onInit() { + store.log(store.pretty()); + }, + })) + ); +}`; + + const logEntries = await verifySchematic(input, output); + expect(logEntries).toEqual([ + "[@ngrx/signals] Renamed '(Named)EntityComputed' to '(Named)EntityProps' in /main.ts", + "[@ngrx/signals] Renamed 'computed' to 'props' in SignalStoreFeature<> in /main.ts", + "[@ngrx/signals] Renamed 'computed' to 'props' in signalStoreFeature() in /main.ts", + ]); + }); + + it('creates two files with minimal changes and checks both files', async () => { + const input1 = tags.stripIndent` +import { EntityComputed } from '@ngrx/signals/entities'; +`; + + const output1 = tags.stripIndent` +import { EntityProps } from '@ngrx/signals/entities'; +`; + + const input2 = tags.stripIndent` +import { NamedEntityComputed } from '@ngrx/signals/entities'; +`; + + const output2 = tags.stripIndent` +import { NamedEntityProps } from '@ngrx/signals/entities'; + `; + + appTree.create('file1.ts', input1); + appTree.create('file2.ts', input2); + + const logEntries: string[] = []; + schematicRunner.logger.subscribe((logEntry) => + logEntries.push(logEntry.message) + ); + + const tree = await schematicRunner.runSchematic( + `19_0_0-rc_1-props`, + {}, + appTree + ); + + const actual1 = tree.readContent('file1.ts'); + const actual2 = tree.readContent('file2.ts'); + + expect(actual1).toBe(output1); + expect(actual2).toBe(output2); + + expect(logEntries).toEqual([ + "[@ngrx/signals] Renamed '(Named)EntityComputed' to '(Named)EntityProps' in /file1.ts", + "[@ngrx/signals] Renamed '(Named)EntityComputed' to '(Named)EntityProps' in /file2.ts", + ]); + }); +}); diff --git a/modules/signals/migrations/19_0_0-rc_1-props/index.ts b/modules/signals/migrations/19_0_0-rc_1-props/index.ts new file mode 100644 index 0000000000..919ae85230 --- /dev/null +++ b/modules/signals/migrations/19_0_0-rc_1-props/index.ts @@ -0,0 +1,224 @@ +import { + chain, + Rule, + SchematicContext, + Tree, +} from '@angular-devkit/schematics'; +import { + Change, + commitChanges, + createReplaceChange, + visitTSSourceFiles, +} from '../../schematics-core'; +import { + visitCallExpression, + visitImportDeclaration, + visitImportSpecifier, + visitTypeLiteral, + visitTypeReference, +} from '../../schematics-core/utility/visitors'; +import * as ts from 'typescript'; + +function migratedToEntityProps(sourceFile: ts.SourceFile) { + const changes: Change[] = []; + visitImportDeclaration(sourceFile, (importDeclaration, moduleName) => { + if (moduleName !== '@ngrx/signals/entities') { + return; + } + + visitImportSpecifier(importDeclaration, (importSpecifier) => { + if (importSpecifier.name.getText() === 'EntityComputed') { + changes.push( + createReplaceChange( + sourceFile, + importSpecifier, + importSpecifier.getText(), + 'EntityProps' + ) + ); + + visitTypeReference(sourceFile, (type) => { + if (type.typeName.getText() === 'EntityComputed') { + changes.push( + createReplaceChange( + sourceFile, + type, + type.typeName.getText(), + 'EntityProps' + ) + ); + } + }); + } + + if (importSpecifier.name.getText() === 'NamedEntityComputed') { + changes.push( + createReplaceChange( + sourceFile, + importSpecifier, + importSpecifier.getText(), + 'NamedEntityProps' + ) + ); + + visitTypeReference(sourceFile, (typeReference) => { + if (typeReference.typeName.getText() === 'NamedEntityComputed') { + changes.push( + createReplaceChange( + sourceFile, + typeReference.typeName, + typeReference.typeName.getText(), + 'NamedEntityProps' + ) + ); + } + }); + } + }); + }); + + return changes; +} + +function migrateToPropsInSignalStoreFeatureType( + sourceFile: ts.SourceFile +): Change[] { + const changes: Change[] = []; + visitTypeReference(sourceFile, (typeReference) => { + if (typeReference.typeName.getText() !== 'SignalStoreFeature') { + return; + } + + visitTypeLiteral(typeReference, (typeLiteral) => { + const typeLiteralChildren = typeLiteral.members; + for (const propertySignature of typeLiteralChildren) { + if (ts.isPropertySignature(propertySignature)) { + if (propertySignature.name.getText() === 'computed') { + changes.push( + createReplaceChange( + sourceFile, + propertySignature.name, + 'computed', + 'props' + ) + ); + } + } + } + }); + }); + + return changes; +} + +function migrateToPropsInSignalStoreFeatureWithObjectLiteral( + objectLiteral: ts.ObjectLiteralExpression, + sourceFile: ts.SourceFile +): Change[] { + const computedKey = objectLiteral.properties + .filter(ts.isPropertyAssignment) + .find((property) => property.name.getText() === 'computed'); + if (computedKey) { + return [createReplaceChange(sourceFile, computedKey, 'computed', 'props')]; + } + + return []; +} + +function migrateToPropsInSignalStoreFeatureWithCallExpression( + callExpression: ts.CallExpression, + sourceFile: ts.SourceFile +): Change[] { + if (callExpression.expression.getText() === 'type') { + const typeArgument = callExpression.typeArguments?.at(0); + + if (typeArgument && ts.isTypeLiteralNode(typeArgument)) { + const computedKey = typeArgument.members + .filter(ts.isPropertySignature) + .find( + (propertySignature) => propertySignature.name.getText() === 'computed' + ); + + if (computedKey) { + return [ + createReplaceChange(sourceFile, computedKey, 'computed', 'props'), + ]; + } + } + } + + return []; +} + +function migrateToPropsInSignalStoreFeatureFunction( + sourceFile: ts.SourceFile +): Change[] { + const changes: Change[] = []; + visitCallExpression(sourceFile, (callExpression) => { + if (callExpression.expression.getText() !== 'signalStoreFeature') { + return; + } + + const objectLiteralOrCallExpression = callExpression.arguments[0]; + if (!objectLiteralOrCallExpression) { + return; + } + + if (ts.isObjectLiteralExpression(objectLiteralOrCallExpression)) { + changes.push( + ...migrateToPropsInSignalStoreFeatureWithObjectLiteral( + objectLiteralOrCallExpression, + sourceFile + ) + ); + } else if (ts.isCallExpression(objectLiteralOrCallExpression)) { + changes.push( + ...migrateToPropsInSignalStoreFeatureWithCallExpression( + objectLiteralOrCallExpression, + sourceFile + ) + ); + } + }); + + return changes; +} + +export function migrate(): Rule { + return (tree: Tree, ctx: SchematicContext) => { + visitTSSourceFiles(tree, (sourceFile) => { + const entityPropsChanges = migratedToEntityProps(sourceFile); + const propsInSignalStoreFeatureTypeChanges = + migrateToPropsInSignalStoreFeatureType(sourceFile); + const propsInSignalStoreFeatureFunctionChanges = + migrateToPropsInSignalStoreFeatureFunction(sourceFile); + const changes = [ + ...entityPropsChanges, + ...propsInSignalStoreFeatureTypeChanges, + ...propsInSignalStoreFeatureFunctionChanges, + ]; + + commitChanges(tree, sourceFile.fileName, changes); + + if (entityPropsChanges.length) { + ctx.logger.info( + `[@ngrx/signals] Renamed '(Named)EntityComputed' to '(Named)EntityProps' in ${sourceFile.fileName}` + ); + } + if (propsInSignalStoreFeatureTypeChanges.length) { + ctx.logger.info( + `[@ngrx/signals] Renamed 'computed' to 'props' in SignalStoreFeature<> in ${sourceFile.fileName}` + ); + } + if (propsInSignalStoreFeatureFunctionChanges.length) { + ctx.logger.info( + `[@ngrx/signals] Renamed 'computed' to 'props' in signalStoreFeature() in ${sourceFile.fileName}` + ); + } + }); + }; +} + +export default function (): Rule { + return chain([migrate()]); +} diff --git a/modules/signals/migrations/migration.json b/modules/signals/migrations/migration.json index 9d2168ca35..eb0c016b60 100644 --- a/modules/signals/migrations/migration.json +++ b/modules/signals/migrations/migration.json @@ -10,6 +10,11 @@ "description": "Replace StateSignal usages with WritableStateSource", "version": "18.0.0-rc.3", "factory": "./18_0_0-rc_3-writablestatesource/index" + }, + "19_0_0-rc_1-props": { + "description": "Replace several properties with a single props object", + "version": "19.0.0-rc.1", + "factory": "./19_0_0-rc_1-props/index" } } } diff --git a/modules/signals/schematics-core/tsconfig.lib.json b/modules/signals/schematics-core/tsconfig.lib.json index c0f1097a2b..13021f14d8 100644 --- a/modules/signals/schematics-core/tsconfig.lib.json +++ b/modules/signals/schematics-core/tsconfig.lib.json @@ -8,7 +8,7 @@ "outDir": "../../dist/modules/schematics-score", "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/signals/schematics-core/utility/visitors.ts b/modules/signals/schematics-core/utility/visitors.ts index fa4edd06af..b0e0229e13 100644 --- a/modules/signals/schematics-core/utility/visitors.ts +++ b/modules/signals/schematics-core/utility/visitors.ts @@ -198,6 +198,86 @@ export function visitDecorator( }); } +export function visitImportDeclaration( + node: ts.Node, + callback: ( + importDeclaration: ts.ImportDeclaration, + moduleName?: string + ) => void +) { + if (ts.isImportDeclaration(node)) { + const moduleSpecifier = node.moduleSpecifier.getText(); + const moduleName = moduleSpecifier.replaceAll('"', '').replaceAll("'", ''); + + callback(node, moduleName); + } + + ts.forEachChild(node, (child) => { + visitImportDeclaration(child, callback); + }); +} + +export function visitImportSpecifier( + node: ts.ImportDeclaration, + callback: (importSpecifier: ts.ImportSpecifier) => void +) { + const { importClause } = node; + if (!importClause) { + return; + } + + const importClauseChildren = importClause.getChildren(); + for (const namedImport of importClauseChildren) { + if (ts.isNamedImports(namedImport)) { + const namedImportChildren = namedImport.elements; + for (const importSpecifier of namedImportChildren) { + if (ts.isImportSpecifier(importSpecifier)) { + callback(importSpecifier); + } + } + } + } +} + +export function visitTypeReference( + node: ts.Node, + callback: (typeReference: ts.TypeReferenceNode) => void +) { + if (ts.isTypeReferenceNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeReference(child, callback); + }); +} + +export function visitTypeLiteral( + node: ts.Node, + callback: (typeLiteral: ts.TypeLiteralNode) => void +) { + if (ts.isTypeLiteralNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeLiteral(child, callback); + }); +} + +export function visitCallExpression( + node: ts.Node, + callback: (callExpression: ts.CallExpression) => void +) { + if (ts.isCallExpression(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitCallExpression(child, callback); + }); +} + function* visit(directory: DirEntry): IterableIterator { for (const path of directory.subfiles) { if (path.endsWith('.ts') && !path.endsWith('.d.ts')) { From ee676b195a4f6ba494df4c2fc1c40ed57177e34a Mon Sep 17 00:00:00 2001 From: Rainer Hahnekamp Date: Mon, 2 Dec 2024 12:12:23 +0100 Subject: [PATCH 2/6] Update modules/signals/migrations/migration.json Co-authored-by: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> --- modules/signals/migrations/migration.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/signals/migrations/migration.json b/modules/signals/migrations/migration.json index eb0c016b60..ce57cac464 100644 --- a/modules/signals/migrations/migration.json +++ b/modules/signals/migrations/migration.json @@ -13,8 +13,8 @@ }, "19_0_0-rc_1-props": { "description": "Replace several properties with a single props object", - "version": "19.0.0-rc.1", - "factory": "./19_0_0-rc_1-props/index" + "version": "19.0.0-rc.0", + "factory": "./19_0_0-rc_0-props/index" } } } From c8bbabd2b072389a92b070d95d9a8d8ba9f911ab Mon Sep 17 00:00:00 2001 From: Rainer Hahnekamp Date: Mon, 2 Dec 2024 21:58:08 +0100 Subject: [PATCH 3/6] refactor: move migration script to 19.0.0-rc-0 --- .../{19_0_0-rc_1-props => 19_0_0-rc_0-props}/index.spec.ts | 5 ++--- .../{19_0_0-rc_1-props => 19_0_0-rc_0-props}/index.ts | 0 modules/signals/migrations/migration.json | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) rename modules/signals/migrations/{19_0_0-rc_1-props => 19_0_0-rc_0-props}/index.spec.ts (98%) rename modules/signals/migrations/{19_0_0-rc_1-props => 19_0_0-rc_0-props}/index.ts (100%) diff --git a/modules/signals/migrations/19_0_0-rc_1-props/index.spec.ts b/modules/signals/migrations/19_0_0-rc_0-props/index.spec.ts similarity index 98% rename from modules/signals/migrations/19_0_0-rc_1-props/index.spec.ts rename to modules/signals/migrations/19_0_0-rc_0-props/index.spec.ts index 3b2c03c29d..7822157f59 100644 --- a/modules/signals/migrations/19_0_0-rc_1-props/index.spec.ts +++ b/modules/signals/migrations/19_0_0-rc_0-props/index.spec.ts @@ -5,7 +5,6 @@ import { } from '@angular-devkit/schematics/testing'; import { createWorkspace } from '@ngrx/schematics-core/testing'; import { tags } from '@angular-devkit/core'; -import { LogEntry } from '@angular-devkit/core/src/logger'; describe('migrate to props', () => { const collectionPath = path.join(__dirname, '../migration.json'); @@ -26,7 +25,7 @@ describe('migrate to props', () => { ); const tree = await schematicRunner.runSchematic( - `19_0_0-rc_1-props`, + `19_0_0-rc_0-props`, {}, appTree ); @@ -240,7 +239,7 @@ import { NamedEntityProps } from '@ngrx/signals/entities'; ); const tree = await schematicRunner.runSchematic( - `19_0_0-rc_1-props`, + `19_0_0-rc_0-props`, {}, appTree ); diff --git a/modules/signals/migrations/19_0_0-rc_1-props/index.ts b/modules/signals/migrations/19_0_0-rc_0-props/index.ts similarity index 100% rename from modules/signals/migrations/19_0_0-rc_1-props/index.ts rename to modules/signals/migrations/19_0_0-rc_0-props/index.ts diff --git a/modules/signals/migrations/migration.json b/modules/signals/migrations/migration.json index ce57cac464..d208435769 100644 --- a/modules/signals/migrations/migration.json +++ b/modules/signals/migrations/migration.json @@ -11,7 +11,7 @@ "version": "18.0.0-rc.3", "factory": "./18_0_0-rc_3-writablestatesource/index" }, - "19_0_0-rc_1-props": { + "19_0_0-rc_0-props": { "description": "Replace several properties with a single props object", "version": "19.0.0-rc.0", "factory": "./19_0_0-rc_0-props/index" From c2c68e6a66902eb4531914c06c603d4a30010896 Mon Sep 17 00:00:00 2001 From: Rainer Hahnekamp Date: Mon, 2 Dec 2024 22:13:48 +0100 Subject: [PATCH 4/6] feat: extend schematics visitors --- .../schematics-core/tsconfig.lib.json | 2 +- .../schematics-core/utility/visitors.ts | 80 +++++++++++++++++++ .../schematics-core/tsconfig.lib.json | 2 +- .../schematics-core/utility/visitors.ts | 80 +++++++++++++++++++ .../data/schematics-core/tsconfig.lib.json | 2 +- .../data/schematics-core/utility/visitors.ts | 80 +++++++++++++++++++ .../effects/schematics-core/tsconfig.lib.json | 2 +- .../schematics-core/utility/visitors.ts | 80 +++++++++++++++++++ .../entity/schematics-core/tsconfig.lib.json | 2 +- .../schematics-core/utility/visitors.ts | 80 +++++++++++++++++++ .../schematics-core/tsconfig.lib.json | 2 +- .../schematics-core/utility/visitors.ts | 80 +++++++++++++++++++ .../schematics-core/tsconfig.lib.json | 2 +- .../schematics-core/utility/visitors.ts | 80 +++++++++++++++++++ modules/schematics-core/tsconfig.lib.json | 2 +- modules/schematics-core/utility/visitors.ts | 80 +++++++++++++++++++ .../schematics-core/tsconfig.lib.json | 2 +- .../schematics-core/utility/visitors.ts | 80 +++++++++++++++++++ .../schematics-core/tsconfig.lib.json | 2 +- .../schematics-core/utility/visitors.ts | 80 +++++++++++++++++++ .../store/schematics-core/tsconfig.lib.json | 2 +- .../store/schematics-core/utility/visitors.ts | 80 +++++++++++++++++++ 22 files changed, 891 insertions(+), 11 deletions(-) diff --git a/modules/component-store/schematics-core/tsconfig.lib.json b/modules/component-store/schematics-core/tsconfig.lib.json index c0f1097a2b..13021f14d8 100644 --- a/modules/component-store/schematics-core/tsconfig.lib.json +++ b/modules/component-store/schematics-core/tsconfig.lib.json @@ -8,7 +8,7 @@ "outDir": "../../dist/modules/schematics-score", "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/component-store/schematics-core/utility/visitors.ts b/modules/component-store/schematics-core/utility/visitors.ts index fa4edd06af..b0e0229e13 100644 --- a/modules/component-store/schematics-core/utility/visitors.ts +++ b/modules/component-store/schematics-core/utility/visitors.ts @@ -198,6 +198,86 @@ export function visitDecorator( }); } +export function visitImportDeclaration( + node: ts.Node, + callback: ( + importDeclaration: ts.ImportDeclaration, + moduleName?: string + ) => void +) { + if (ts.isImportDeclaration(node)) { + const moduleSpecifier = node.moduleSpecifier.getText(); + const moduleName = moduleSpecifier.replaceAll('"', '').replaceAll("'", ''); + + callback(node, moduleName); + } + + ts.forEachChild(node, (child) => { + visitImportDeclaration(child, callback); + }); +} + +export function visitImportSpecifier( + node: ts.ImportDeclaration, + callback: (importSpecifier: ts.ImportSpecifier) => void +) { + const { importClause } = node; + if (!importClause) { + return; + } + + const importClauseChildren = importClause.getChildren(); + for (const namedImport of importClauseChildren) { + if (ts.isNamedImports(namedImport)) { + const namedImportChildren = namedImport.elements; + for (const importSpecifier of namedImportChildren) { + if (ts.isImportSpecifier(importSpecifier)) { + callback(importSpecifier); + } + } + } + } +} + +export function visitTypeReference( + node: ts.Node, + callback: (typeReference: ts.TypeReferenceNode) => void +) { + if (ts.isTypeReferenceNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeReference(child, callback); + }); +} + +export function visitTypeLiteral( + node: ts.Node, + callback: (typeLiteral: ts.TypeLiteralNode) => void +) { + if (ts.isTypeLiteralNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeLiteral(child, callback); + }); +} + +export function visitCallExpression( + node: ts.Node, + callback: (callExpression: ts.CallExpression) => void +) { + if (ts.isCallExpression(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitCallExpression(child, callback); + }); +} + function* visit(directory: DirEntry): IterableIterator { for (const path of directory.subfiles) { if (path.endsWith('.ts') && !path.endsWith('.d.ts')) { diff --git a/modules/component/schematics-core/tsconfig.lib.json b/modules/component/schematics-core/tsconfig.lib.json index c0f1097a2b..13021f14d8 100644 --- a/modules/component/schematics-core/tsconfig.lib.json +++ b/modules/component/schematics-core/tsconfig.lib.json @@ -8,7 +8,7 @@ "outDir": "../../dist/modules/schematics-score", "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/component/schematics-core/utility/visitors.ts b/modules/component/schematics-core/utility/visitors.ts index fa4edd06af..b0e0229e13 100644 --- a/modules/component/schematics-core/utility/visitors.ts +++ b/modules/component/schematics-core/utility/visitors.ts @@ -198,6 +198,86 @@ export function visitDecorator( }); } +export function visitImportDeclaration( + node: ts.Node, + callback: ( + importDeclaration: ts.ImportDeclaration, + moduleName?: string + ) => void +) { + if (ts.isImportDeclaration(node)) { + const moduleSpecifier = node.moduleSpecifier.getText(); + const moduleName = moduleSpecifier.replaceAll('"', '').replaceAll("'", ''); + + callback(node, moduleName); + } + + ts.forEachChild(node, (child) => { + visitImportDeclaration(child, callback); + }); +} + +export function visitImportSpecifier( + node: ts.ImportDeclaration, + callback: (importSpecifier: ts.ImportSpecifier) => void +) { + const { importClause } = node; + if (!importClause) { + return; + } + + const importClauseChildren = importClause.getChildren(); + for (const namedImport of importClauseChildren) { + if (ts.isNamedImports(namedImport)) { + const namedImportChildren = namedImport.elements; + for (const importSpecifier of namedImportChildren) { + if (ts.isImportSpecifier(importSpecifier)) { + callback(importSpecifier); + } + } + } + } +} + +export function visitTypeReference( + node: ts.Node, + callback: (typeReference: ts.TypeReferenceNode) => void +) { + if (ts.isTypeReferenceNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeReference(child, callback); + }); +} + +export function visitTypeLiteral( + node: ts.Node, + callback: (typeLiteral: ts.TypeLiteralNode) => void +) { + if (ts.isTypeLiteralNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeLiteral(child, callback); + }); +} + +export function visitCallExpression( + node: ts.Node, + callback: (callExpression: ts.CallExpression) => void +) { + if (ts.isCallExpression(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitCallExpression(child, callback); + }); +} + function* visit(directory: DirEntry): IterableIterator { for (const path of directory.subfiles) { if (path.endsWith('.ts') && !path.endsWith('.d.ts')) { diff --git a/modules/data/schematics-core/tsconfig.lib.json b/modules/data/schematics-core/tsconfig.lib.json index c0f1097a2b..13021f14d8 100644 --- a/modules/data/schematics-core/tsconfig.lib.json +++ b/modules/data/schematics-core/tsconfig.lib.json @@ -8,7 +8,7 @@ "outDir": "../../dist/modules/schematics-score", "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/data/schematics-core/utility/visitors.ts b/modules/data/schematics-core/utility/visitors.ts index fa4edd06af..b0e0229e13 100644 --- a/modules/data/schematics-core/utility/visitors.ts +++ b/modules/data/schematics-core/utility/visitors.ts @@ -198,6 +198,86 @@ export function visitDecorator( }); } +export function visitImportDeclaration( + node: ts.Node, + callback: ( + importDeclaration: ts.ImportDeclaration, + moduleName?: string + ) => void +) { + if (ts.isImportDeclaration(node)) { + const moduleSpecifier = node.moduleSpecifier.getText(); + const moduleName = moduleSpecifier.replaceAll('"', '').replaceAll("'", ''); + + callback(node, moduleName); + } + + ts.forEachChild(node, (child) => { + visitImportDeclaration(child, callback); + }); +} + +export function visitImportSpecifier( + node: ts.ImportDeclaration, + callback: (importSpecifier: ts.ImportSpecifier) => void +) { + const { importClause } = node; + if (!importClause) { + return; + } + + const importClauseChildren = importClause.getChildren(); + for (const namedImport of importClauseChildren) { + if (ts.isNamedImports(namedImport)) { + const namedImportChildren = namedImport.elements; + for (const importSpecifier of namedImportChildren) { + if (ts.isImportSpecifier(importSpecifier)) { + callback(importSpecifier); + } + } + } + } +} + +export function visitTypeReference( + node: ts.Node, + callback: (typeReference: ts.TypeReferenceNode) => void +) { + if (ts.isTypeReferenceNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeReference(child, callback); + }); +} + +export function visitTypeLiteral( + node: ts.Node, + callback: (typeLiteral: ts.TypeLiteralNode) => void +) { + if (ts.isTypeLiteralNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeLiteral(child, callback); + }); +} + +export function visitCallExpression( + node: ts.Node, + callback: (callExpression: ts.CallExpression) => void +) { + if (ts.isCallExpression(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitCallExpression(child, callback); + }); +} + function* visit(directory: DirEntry): IterableIterator { for (const path of directory.subfiles) { if (path.endsWith('.ts') && !path.endsWith('.d.ts')) { diff --git a/modules/effects/schematics-core/tsconfig.lib.json b/modules/effects/schematics-core/tsconfig.lib.json index c0f1097a2b..13021f14d8 100644 --- a/modules/effects/schematics-core/tsconfig.lib.json +++ b/modules/effects/schematics-core/tsconfig.lib.json @@ -8,7 +8,7 @@ "outDir": "../../dist/modules/schematics-score", "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/effects/schematics-core/utility/visitors.ts b/modules/effects/schematics-core/utility/visitors.ts index fa4edd06af..b0e0229e13 100644 --- a/modules/effects/schematics-core/utility/visitors.ts +++ b/modules/effects/schematics-core/utility/visitors.ts @@ -198,6 +198,86 @@ export function visitDecorator( }); } +export function visitImportDeclaration( + node: ts.Node, + callback: ( + importDeclaration: ts.ImportDeclaration, + moduleName?: string + ) => void +) { + if (ts.isImportDeclaration(node)) { + const moduleSpecifier = node.moduleSpecifier.getText(); + const moduleName = moduleSpecifier.replaceAll('"', '').replaceAll("'", ''); + + callback(node, moduleName); + } + + ts.forEachChild(node, (child) => { + visitImportDeclaration(child, callback); + }); +} + +export function visitImportSpecifier( + node: ts.ImportDeclaration, + callback: (importSpecifier: ts.ImportSpecifier) => void +) { + const { importClause } = node; + if (!importClause) { + return; + } + + const importClauseChildren = importClause.getChildren(); + for (const namedImport of importClauseChildren) { + if (ts.isNamedImports(namedImport)) { + const namedImportChildren = namedImport.elements; + for (const importSpecifier of namedImportChildren) { + if (ts.isImportSpecifier(importSpecifier)) { + callback(importSpecifier); + } + } + } + } +} + +export function visitTypeReference( + node: ts.Node, + callback: (typeReference: ts.TypeReferenceNode) => void +) { + if (ts.isTypeReferenceNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeReference(child, callback); + }); +} + +export function visitTypeLiteral( + node: ts.Node, + callback: (typeLiteral: ts.TypeLiteralNode) => void +) { + if (ts.isTypeLiteralNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeLiteral(child, callback); + }); +} + +export function visitCallExpression( + node: ts.Node, + callback: (callExpression: ts.CallExpression) => void +) { + if (ts.isCallExpression(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitCallExpression(child, callback); + }); +} + function* visit(directory: DirEntry): IterableIterator { for (const path of directory.subfiles) { if (path.endsWith('.ts') && !path.endsWith('.d.ts')) { diff --git a/modules/entity/schematics-core/tsconfig.lib.json b/modules/entity/schematics-core/tsconfig.lib.json index c0f1097a2b..13021f14d8 100644 --- a/modules/entity/schematics-core/tsconfig.lib.json +++ b/modules/entity/schematics-core/tsconfig.lib.json @@ -8,7 +8,7 @@ "outDir": "../../dist/modules/schematics-score", "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/entity/schematics-core/utility/visitors.ts b/modules/entity/schematics-core/utility/visitors.ts index fa4edd06af..b0e0229e13 100644 --- a/modules/entity/schematics-core/utility/visitors.ts +++ b/modules/entity/schematics-core/utility/visitors.ts @@ -198,6 +198,86 @@ export function visitDecorator( }); } +export function visitImportDeclaration( + node: ts.Node, + callback: ( + importDeclaration: ts.ImportDeclaration, + moduleName?: string + ) => void +) { + if (ts.isImportDeclaration(node)) { + const moduleSpecifier = node.moduleSpecifier.getText(); + const moduleName = moduleSpecifier.replaceAll('"', '').replaceAll("'", ''); + + callback(node, moduleName); + } + + ts.forEachChild(node, (child) => { + visitImportDeclaration(child, callback); + }); +} + +export function visitImportSpecifier( + node: ts.ImportDeclaration, + callback: (importSpecifier: ts.ImportSpecifier) => void +) { + const { importClause } = node; + if (!importClause) { + return; + } + + const importClauseChildren = importClause.getChildren(); + for (const namedImport of importClauseChildren) { + if (ts.isNamedImports(namedImport)) { + const namedImportChildren = namedImport.elements; + for (const importSpecifier of namedImportChildren) { + if (ts.isImportSpecifier(importSpecifier)) { + callback(importSpecifier); + } + } + } + } +} + +export function visitTypeReference( + node: ts.Node, + callback: (typeReference: ts.TypeReferenceNode) => void +) { + if (ts.isTypeReferenceNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeReference(child, callback); + }); +} + +export function visitTypeLiteral( + node: ts.Node, + callback: (typeLiteral: ts.TypeLiteralNode) => void +) { + if (ts.isTypeLiteralNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeLiteral(child, callback); + }); +} + +export function visitCallExpression( + node: ts.Node, + callback: (callExpression: ts.CallExpression) => void +) { + if (ts.isCallExpression(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitCallExpression(child, callback); + }); +} + function* visit(directory: DirEntry): IterableIterator { for (const path of directory.subfiles) { if (path.endsWith('.ts') && !path.endsWith('.d.ts')) { diff --git a/modules/operators/schematics-core/tsconfig.lib.json b/modules/operators/schematics-core/tsconfig.lib.json index c0f1097a2b..13021f14d8 100644 --- a/modules/operators/schematics-core/tsconfig.lib.json +++ b/modules/operators/schematics-core/tsconfig.lib.json @@ -8,7 +8,7 @@ "outDir": "../../dist/modules/schematics-score", "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/operators/schematics-core/utility/visitors.ts b/modules/operators/schematics-core/utility/visitors.ts index fa4edd06af..b0e0229e13 100644 --- a/modules/operators/schematics-core/utility/visitors.ts +++ b/modules/operators/schematics-core/utility/visitors.ts @@ -198,6 +198,86 @@ export function visitDecorator( }); } +export function visitImportDeclaration( + node: ts.Node, + callback: ( + importDeclaration: ts.ImportDeclaration, + moduleName?: string + ) => void +) { + if (ts.isImportDeclaration(node)) { + const moduleSpecifier = node.moduleSpecifier.getText(); + const moduleName = moduleSpecifier.replaceAll('"', '').replaceAll("'", ''); + + callback(node, moduleName); + } + + ts.forEachChild(node, (child) => { + visitImportDeclaration(child, callback); + }); +} + +export function visitImportSpecifier( + node: ts.ImportDeclaration, + callback: (importSpecifier: ts.ImportSpecifier) => void +) { + const { importClause } = node; + if (!importClause) { + return; + } + + const importClauseChildren = importClause.getChildren(); + for (const namedImport of importClauseChildren) { + if (ts.isNamedImports(namedImport)) { + const namedImportChildren = namedImport.elements; + for (const importSpecifier of namedImportChildren) { + if (ts.isImportSpecifier(importSpecifier)) { + callback(importSpecifier); + } + } + } + } +} + +export function visitTypeReference( + node: ts.Node, + callback: (typeReference: ts.TypeReferenceNode) => void +) { + if (ts.isTypeReferenceNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeReference(child, callback); + }); +} + +export function visitTypeLiteral( + node: ts.Node, + callback: (typeLiteral: ts.TypeLiteralNode) => void +) { + if (ts.isTypeLiteralNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeLiteral(child, callback); + }); +} + +export function visitCallExpression( + node: ts.Node, + callback: (callExpression: ts.CallExpression) => void +) { + if (ts.isCallExpression(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitCallExpression(child, callback); + }); +} + function* visit(directory: DirEntry): IterableIterator { for (const path of directory.subfiles) { if (path.endsWith('.ts') && !path.endsWith('.d.ts')) { diff --git a/modules/router-store/schematics-core/tsconfig.lib.json b/modules/router-store/schematics-core/tsconfig.lib.json index c0f1097a2b..13021f14d8 100644 --- a/modules/router-store/schematics-core/tsconfig.lib.json +++ b/modules/router-store/schematics-core/tsconfig.lib.json @@ -8,7 +8,7 @@ "outDir": "../../dist/modules/schematics-score", "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/router-store/schematics-core/utility/visitors.ts b/modules/router-store/schematics-core/utility/visitors.ts index fa4edd06af..b0e0229e13 100644 --- a/modules/router-store/schematics-core/utility/visitors.ts +++ b/modules/router-store/schematics-core/utility/visitors.ts @@ -198,6 +198,86 @@ export function visitDecorator( }); } +export function visitImportDeclaration( + node: ts.Node, + callback: ( + importDeclaration: ts.ImportDeclaration, + moduleName?: string + ) => void +) { + if (ts.isImportDeclaration(node)) { + const moduleSpecifier = node.moduleSpecifier.getText(); + const moduleName = moduleSpecifier.replaceAll('"', '').replaceAll("'", ''); + + callback(node, moduleName); + } + + ts.forEachChild(node, (child) => { + visitImportDeclaration(child, callback); + }); +} + +export function visitImportSpecifier( + node: ts.ImportDeclaration, + callback: (importSpecifier: ts.ImportSpecifier) => void +) { + const { importClause } = node; + if (!importClause) { + return; + } + + const importClauseChildren = importClause.getChildren(); + for (const namedImport of importClauseChildren) { + if (ts.isNamedImports(namedImport)) { + const namedImportChildren = namedImport.elements; + for (const importSpecifier of namedImportChildren) { + if (ts.isImportSpecifier(importSpecifier)) { + callback(importSpecifier); + } + } + } + } +} + +export function visitTypeReference( + node: ts.Node, + callback: (typeReference: ts.TypeReferenceNode) => void +) { + if (ts.isTypeReferenceNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeReference(child, callback); + }); +} + +export function visitTypeLiteral( + node: ts.Node, + callback: (typeLiteral: ts.TypeLiteralNode) => void +) { + if (ts.isTypeLiteralNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeLiteral(child, callback); + }); +} + +export function visitCallExpression( + node: ts.Node, + callback: (callExpression: ts.CallExpression) => void +) { + if (ts.isCallExpression(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitCallExpression(child, callback); + }); +} + function* visit(directory: DirEntry): IterableIterator { for (const path of directory.subfiles) { if (path.endsWith('.ts') && !path.endsWith('.d.ts')) { diff --git a/modules/schematics-core/tsconfig.lib.json b/modules/schematics-core/tsconfig.lib.json index c0f1097a2b..13021f14d8 100644 --- a/modules/schematics-core/tsconfig.lib.json +++ b/modules/schematics-core/tsconfig.lib.json @@ -8,7 +8,7 @@ "outDir": "../../dist/modules/schematics-score", "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/schematics-core/utility/visitors.ts b/modules/schematics-core/utility/visitors.ts index fa4edd06af..b0e0229e13 100644 --- a/modules/schematics-core/utility/visitors.ts +++ b/modules/schematics-core/utility/visitors.ts @@ -198,6 +198,86 @@ export function visitDecorator( }); } +export function visitImportDeclaration( + node: ts.Node, + callback: ( + importDeclaration: ts.ImportDeclaration, + moduleName?: string + ) => void +) { + if (ts.isImportDeclaration(node)) { + const moduleSpecifier = node.moduleSpecifier.getText(); + const moduleName = moduleSpecifier.replaceAll('"', '').replaceAll("'", ''); + + callback(node, moduleName); + } + + ts.forEachChild(node, (child) => { + visitImportDeclaration(child, callback); + }); +} + +export function visitImportSpecifier( + node: ts.ImportDeclaration, + callback: (importSpecifier: ts.ImportSpecifier) => void +) { + const { importClause } = node; + if (!importClause) { + return; + } + + const importClauseChildren = importClause.getChildren(); + for (const namedImport of importClauseChildren) { + if (ts.isNamedImports(namedImport)) { + const namedImportChildren = namedImport.elements; + for (const importSpecifier of namedImportChildren) { + if (ts.isImportSpecifier(importSpecifier)) { + callback(importSpecifier); + } + } + } + } +} + +export function visitTypeReference( + node: ts.Node, + callback: (typeReference: ts.TypeReferenceNode) => void +) { + if (ts.isTypeReferenceNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeReference(child, callback); + }); +} + +export function visitTypeLiteral( + node: ts.Node, + callback: (typeLiteral: ts.TypeLiteralNode) => void +) { + if (ts.isTypeLiteralNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeLiteral(child, callback); + }); +} + +export function visitCallExpression( + node: ts.Node, + callback: (callExpression: ts.CallExpression) => void +) { + if (ts.isCallExpression(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitCallExpression(child, callback); + }); +} + function* visit(directory: DirEntry): IterableIterator { for (const path of directory.subfiles) { if (path.endsWith('.ts') && !path.endsWith('.d.ts')) { diff --git a/modules/schematics/schematics-core/tsconfig.lib.json b/modules/schematics/schematics-core/tsconfig.lib.json index c0f1097a2b..13021f14d8 100644 --- a/modules/schematics/schematics-core/tsconfig.lib.json +++ b/modules/schematics/schematics-core/tsconfig.lib.json @@ -8,7 +8,7 @@ "outDir": "../../dist/modules/schematics-score", "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/schematics/schematics-core/utility/visitors.ts b/modules/schematics/schematics-core/utility/visitors.ts index fa4edd06af..b0e0229e13 100644 --- a/modules/schematics/schematics-core/utility/visitors.ts +++ b/modules/schematics/schematics-core/utility/visitors.ts @@ -198,6 +198,86 @@ export function visitDecorator( }); } +export function visitImportDeclaration( + node: ts.Node, + callback: ( + importDeclaration: ts.ImportDeclaration, + moduleName?: string + ) => void +) { + if (ts.isImportDeclaration(node)) { + const moduleSpecifier = node.moduleSpecifier.getText(); + const moduleName = moduleSpecifier.replaceAll('"', '').replaceAll("'", ''); + + callback(node, moduleName); + } + + ts.forEachChild(node, (child) => { + visitImportDeclaration(child, callback); + }); +} + +export function visitImportSpecifier( + node: ts.ImportDeclaration, + callback: (importSpecifier: ts.ImportSpecifier) => void +) { + const { importClause } = node; + if (!importClause) { + return; + } + + const importClauseChildren = importClause.getChildren(); + for (const namedImport of importClauseChildren) { + if (ts.isNamedImports(namedImport)) { + const namedImportChildren = namedImport.elements; + for (const importSpecifier of namedImportChildren) { + if (ts.isImportSpecifier(importSpecifier)) { + callback(importSpecifier); + } + } + } + } +} + +export function visitTypeReference( + node: ts.Node, + callback: (typeReference: ts.TypeReferenceNode) => void +) { + if (ts.isTypeReferenceNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeReference(child, callback); + }); +} + +export function visitTypeLiteral( + node: ts.Node, + callback: (typeLiteral: ts.TypeLiteralNode) => void +) { + if (ts.isTypeLiteralNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeLiteral(child, callback); + }); +} + +export function visitCallExpression( + node: ts.Node, + callback: (callExpression: ts.CallExpression) => void +) { + if (ts.isCallExpression(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitCallExpression(child, callback); + }); +} + function* visit(directory: DirEntry): IterableIterator { for (const path of directory.subfiles) { if (path.endsWith('.ts') && !path.endsWith('.d.ts')) { diff --git a/modules/store-devtools/schematics-core/tsconfig.lib.json b/modules/store-devtools/schematics-core/tsconfig.lib.json index c0f1097a2b..13021f14d8 100644 --- a/modules/store-devtools/schematics-core/tsconfig.lib.json +++ b/modules/store-devtools/schematics-core/tsconfig.lib.json @@ -8,7 +8,7 @@ "outDir": "../../dist/modules/schematics-score", "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/store-devtools/schematics-core/utility/visitors.ts b/modules/store-devtools/schematics-core/utility/visitors.ts index fa4edd06af..b0e0229e13 100644 --- a/modules/store-devtools/schematics-core/utility/visitors.ts +++ b/modules/store-devtools/schematics-core/utility/visitors.ts @@ -198,6 +198,86 @@ export function visitDecorator( }); } +export function visitImportDeclaration( + node: ts.Node, + callback: ( + importDeclaration: ts.ImportDeclaration, + moduleName?: string + ) => void +) { + if (ts.isImportDeclaration(node)) { + const moduleSpecifier = node.moduleSpecifier.getText(); + const moduleName = moduleSpecifier.replaceAll('"', '').replaceAll("'", ''); + + callback(node, moduleName); + } + + ts.forEachChild(node, (child) => { + visitImportDeclaration(child, callback); + }); +} + +export function visitImportSpecifier( + node: ts.ImportDeclaration, + callback: (importSpecifier: ts.ImportSpecifier) => void +) { + const { importClause } = node; + if (!importClause) { + return; + } + + const importClauseChildren = importClause.getChildren(); + for (const namedImport of importClauseChildren) { + if (ts.isNamedImports(namedImport)) { + const namedImportChildren = namedImport.elements; + for (const importSpecifier of namedImportChildren) { + if (ts.isImportSpecifier(importSpecifier)) { + callback(importSpecifier); + } + } + } + } +} + +export function visitTypeReference( + node: ts.Node, + callback: (typeReference: ts.TypeReferenceNode) => void +) { + if (ts.isTypeReferenceNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeReference(child, callback); + }); +} + +export function visitTypeLiteral( + node: ts.Node, + callback: (typeLiteral: ts.TypeLiteralNode) => void +) { + if (ts.isTypeLiteralNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeLiteral(child, callback); + }); +} + +export function visitCallExpression( + node: ts.Node, + callback: (callExpression: ts.CallExpression) => void +) { + if (ts.isCallExpression(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitCallExpression(child, callback); + }); +} + function* visit(directory: DirEntry): IterableIterator { for (const path of directory.subfiles) { if (path.endsWith('.ts') && !path.endsWith('.d.ts')) { diff --git a/modules/store/schematics-core/tsconfig.lib.json b/modules/store/schematics-core/tsconfig.lib.json index c0f1097a2b..13021f14d8 100644 --- a/modules/store/schematics-core/tsconfig.lib.json +++ b/modules/store/schematics-core/tsconfig.lib.json @@ -8,7 +8,7 @@ "outDir": "../../dist/modules/schematics-score", "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/store/schematics-core/utility/visitors.ts b/modules/store/schematics-core/utility/visitors.ts index fa4edd06af..b0e0229e13 100644 --- a/modules/store/schematics-core/utility/visitors.ts +++ b/modules/store/schematics-core/utility/visitors.ts @@ -198,6 +198,86 @@ export function visitDecorator( }); } +export function visitImportDeclaration( + node: ts.Node, + callback: ( + importDeclaration: ts.ImportDeclaration, + moduleName?: string + ) => void +) { + if (ts.isImportDeclaration(node)) { + const moduleSpecifier = node.moduleSpecifier.getText(); + const moduleName = moduleSpecifier.replaceAll('"', '').replaceAll("'", ''); + + callback(node, moduleName); + } + + ts.forEachChild(node, (child) => { + visitImportDeclaration(child, callback); + }); +} + +export function visitImportSpecifier( + node: ts.ImportDeclaration, + callback: (importSpecifier: ts.ImportSpecifier) => void +) { + const { importClause } = node; + if (!importClause) { + return; + } + + const importClauseChildren = importClause.getChildren(); + for (const namedImport of importClauseChildren) { + if (ts.isNamedImports(namedImport)) { + const namedImportChildren = namedImport.elements; + for (const importSpecifier of namedImportChildren) { + if (ts.isImportSpecifier(importSpecifier)) { + callback(importSpecifier); + } + } + } + } +} + +export function visitTypeReference( + node: ts.Node, + callback: (typeReference: ts.TypeReferenceNode) => void +) { + if (ts.isTypeReferenceNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeReference(child, callback); + }); +} + +export function visitTypeLiteral( + node: ts.Node, + callback: (typeLiteral: ts.TypeLiteralNode) => void +) { + if (ts.isTypeLiteralNode(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitTypeLiteral(child, callback); + }); +} + +export function visitCallExpression( + node: ts.Node, + callback: (callExpression: ts.CallExpression) => void +) { + if (ts.isCallExpression(node)) { + callback(node); + } + + ts.forEachChild(node, (child) => { + visitCallExpression(child, callback); + }); +} + function* visit(directory: DirEntry): IterableIterator { for (const path of directory.subfiles) { if (path.endsWith('.ts') && !path.endsWith('.d.ts')) { From b1753941bdeb2c11d0efb49bdc832714caa3553b Mon Sep 17 00:00:00 2001 From: Rainer Hahnekamp Date: Thu, 5 Dec 2024 11:41:17 +0100 Subject: [PATCH 5/6] feat: enable target es2022 for schematics --- modules/component-store/tsconfig.schematics.json | 2 +- modules/component/tsconfig.schematics.json | 2 +- modules/data/tsconfig.schematics.json | 2 +- modules/effects/tsconfig.schematics.json | 2 +- modules/entity/tsconfig.schematics.json | 2 +- modules/eslint-plugin/tsconfig.schematics.json | 2 +- modules/operators/tsconfig.schematics.json | 2 +- modules/router-store/tsconfig.schematics.json | 2 +- modules/schematics/tsconfig.schematics.json | 2 +- modules/signals/tsconfig.schematics.json | 2 +- modules/store-devtools/tsconfig.schematics.json | 2 +- modules/store/tsconfig.schematics.json | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/component-store/tsconfig.schematics.json b/modules/component-store/tsconfig.schematics.json index 6ce954388f..7ae7a6a734 100644 --- a/modules/component-store/tsconfig.schematics.json +++ b/modules/component-store/tsconfig.schematics.json @@ -12,7 +12,7 @@ }, "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["ES2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/component/tsconfig.schematics.json b/modules/component/tsconfig.schematics.json index a4ddb29020..044886ed53 100644 --- a/modules/component/tsconfig.schematics.json +++ b/modules/component/tsconfig.schematics.json @@ -12,7 +12,7 @@ }, "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["ES2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/data/tsconfig.schematics.json b/modules/data/tsconfig.schematics.json index 10cc7e381d..f779bfe34f 100644 --- a/modules/data/tsconfig.schematics.json +++ b/modules/data/tsconfig.schematics.json @@ -12,7 +12,7 @@ }, "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["ES2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/effects/tsconfig.schematics.json b/modules/effects/tsconfig.schematics.json index 88dcd0495a..fec5cc794a 100644 --- a/modules/effects/tsconfig.schematics.json +++ b/modules/effects/tsconfig.schematics.json @@ -12,7 +12,7 @@ }, "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["ES2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/entity/tsconfig.schematics.json b/modules/entity/tsconfig.schematics.json index 6e4991381c..34e4210ff2 100644 --- a/modules/entity/tsconfig.schematics.json +++ b/modules/entity/tsconfig.schematics.json @@ -12,7 +12,7 @@ }, "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["ES2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/eslint-plugin/tsconfig.schematics.json b/modules/eslint-plugin/tsconfig.schematics.json index 15bad1c7c8..96abb46af4 100644 --- a/modules/eslint-plugin/tsconfig.schematics.json +++ b/modules/eslint-plugin/tsconfig.schematics.json @@ -10,7 +10,7 @@ "outDir": "../../dist/modules/eslint-plugin", "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["ES2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/operators/tsconfig.schematics.json b/modules/operators/tsconfig.schematics.json index 772e1f63c6..db4d6dca3b 100644 --- a/modules/operators/tsconfig.schematics.json +++ b/modules/operators/tsconfig.schematics.json @@ -12,7 +12,7 @@ }, "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["ES2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/router-store/tsconfig.schematics.json b/modules/router-store/tsconfig.schematics.json index b8ca15b6e3..687d09b3ae 100644 --- a/modules/router-store/tsconfig.schematics.json +++ b/modules/router-store/tsconfig.schematics.json @@ -12,7 +12,7 @@ }, "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["ES2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/schematics/tsconfig.schematics.json b/modules/schematics/tsconfig.schematics.json index 3fc1f247f3..ec9260da3e 100644 --- a/modules/schematics/tsconfig.schematics.json +++ b/modules/schematics/tsconfig.schematics.json @@ -12,7 +12,7 @@ }, "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["ES2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/signals/tsconfig.schematics.json b/modules/signals/tsconfig.schematics.json index c5bb5a37e5..66bc9d8890 100644 --- a/modules/signals/tsconfig.schematics.json +++ b/modules/signals/tsconfig.schematics.json @@ -12,7 +12,7 @@ }, "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["ES2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/store-devtools/tsconfig.schematics.json b/modules/store-devtools/tsconfig.schematics.json index 2dfddef2e7..ebb3b29630 100644 --- a/modules/store-devtools/tsconfig.schematics.json +++ b/modules/store-devtools/tsconfig.schematics.json @@ -12,7 +12,7 @@ }, "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["ES2022", "dom"], "skipLibCheck": true, "strict": true }, diff --git a/modules/store/tsconfig.schematics.json b/modules/store/tsconfig.schematics.json index e53393e33e..27b53d323c 100644 --- a/modules/store/tsconfig.schematics.json +++ b/modules/store/tsconfig.schematics.json @@ -12,7 +12,7 @@ }, "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["ES2022", "dom"], "skipLibCheck": true, "strict": true }, From 9db54ddd2736273b2d4ad60fac25a234d6588798 Mon Sep 17 00:00:00 2001 From: Rainer Hahnekamp Date: Thu, 5 Dec 2024 12:06:55 +0100 Subject: [PATCH 6/6] feat: enable target es2022 for schematics --- modules/schematics/tsconfig.build.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/schematics/tsconfig.build.json b/modules/schematics/tsconfig.build.json index 172550d658..9727e0bca0 100644 --- a/modules/schematics/tsconfig.build.json +++ b/modules/schematics/tsconfig.build.json @@ -11,7 +11,7 @@ }, "sourceMap": true, "inlineSources": true, - "lib": ["es2018", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "strict": true },