From 8612fb44505e8d2ca89e7fa47e4a37e7622545e4 Mon Sep 17 00:00:00 2001 From: erdemcaygor Date: Mon, 21 Apr 2025 13:17:46 +0300 Subject: [PATCH] clean commas rule added --- .../src/commands/change-theme/index.ts | 71 +++++++++++++++++++ .../packages/schematics/src/utils/ast.ts | 7 ++ 2 files changed, 78 insertions(+) diff --git a/npm/ng-packs/packages/schematics/src/commands/change-theme/index.ts b/npm/ng-packs/packages/schematics/src/commands/change-theme/index.ts index 937af3f1c2..70a8c21244 100644 --- a/npm/ng-packs/packages/schematics/src/commands/change-theme/index.ts +++ b/npm/ng-packs/packages/schematics/src/commands/change-theme/index.ts @@ -13,6 +13,7 @@ import { updateWorkspace, WorkspaceDefinition, getAppConfigPath, + removeEmptyElementsFromArrayLiteral, } from '../../utils'; import { ThemeOptionsEnum } from './theme-options.enum'; import { findNodes, getDecoratorMetadata, getMetadataField } from '../../utils/angular/ast-utils'; @@ -80,6 +81,7 @@ function updateAppModule(selectedProject: string, targetThemeName: ThemeOptionsE insertImports(selectedProject, targetThemeName), insertProviders(selectedProject, targetThemeName), formatFile(appModulePath), + cleanNgModuleCommasRule(appModulePath, isStandalone), ]); }; } @@ -361,3 +363,72 @@ export const formatFile = (filePath: string): Rule => { return tree; }; }; + +export function cleanNgModuleCommasRule(modulePath: string, isStandalone: boolean): Rule { + return (host: Tree) => { + const buffer = host.read(modulePath); + if (!buffer) throw new SchematicsException(`Cannot read ${modulePath}`); + + const source = ts.createSourceFile( + modulePath, + buffer.toString('utf-8'), + ts.ScriptTarget.Latest, + true, + ); + const recorder = host.beginUpdate(modulePath); + const printer = ts.createPrinter(); + + if (isStandalone) { + const varStatements = findNodes(source, ts.isVariableStatement); + + for (const stmt of varStatements) { + const declList = stmt.declarationList; + for (const decl of declList.declarations) { + if (!decl.initializer || !ts.isObjectLiteralExpression(decl.initializer)) continue; + + const obj = decl.initializer; + + const providersProp = obj.properties.find( + prop => + ts.isPropertyAssignment(prop) && + ts.isIdentifier(prop.name) && + prop.name.text === 'providers', + ) as ts.PropertyAssignment; + + if (!providersProp || !ts.isArrayLiteralExpression(providersProp.initializer)) continue; + + const arrayLiteral = providersProp.initializer; + const cleanedArray = removeEmptyElementsFromArrayLiteral(arrayLiteral); + + recorder.remove(arrayLiteral.getStart(), arrayLiteral.getWidth()); + recorder.insertLeft( + arrayLiteral.getStart(), + printer.printNode(ts.EmitHint.Expression, cleanedArray, source), + ); + } + } + } else { + const ngModuleNode = getDecoratorMetadata(source, 'NgModule', '@angular/core')[0]; + if (!ngModuleNode) return host; + + const metadataKeys = ['imports', 'providers']; + for (const key of metadataKeys) { + const metadataField = getMetadataField(ngModuleNode as ts.ObjectLiteralExpression, key); + if (!metadataField.length) continue; + + const assignment = metadataField[0] as ts.PropertyAssignment; + const arrayLiteral = assignment.initializer as ts.ArrayLiteralExpression; + + const cleanedArray = removeEmptyElementsFromArrayLiteral(arrayLiteral); + + recorder.remove(arrayLiteral.getStart(), arrayLiteral.getWidth()); + recorder.insertLeft( + arrayLiteral.getStart(), + printer.printNode(ts.EmitHint.Expression, cleanedArray, source), + ); + } + } + host.commitUpdate(recorder); + return host; + }; +} diff --git a/npm/ng-packs/packages/schematics/src/utils/ast.ts b/npm/ng-packs/packages/schematics/src/utils/ast.ts index a1ffe5a319..0b720e63cc 100644 --- a/npm/ng-packs/packages/schematics/src/utils/ast.ts +++ b/npm/ng-packs/packages/schematics/src/utils/ast.ts @@ -35,3 +35,10 @@ export function isBooleanStringOrNumberLiteral( node.kind === ts.SyntaxKind.FalseKeyword ); } + +export function removeEmptyElementsFromArrayLiteral( + array: ts.ArrayLiteralExpression, +): ts.ArrayLiteralExpression { + const cleaned = array.elements.filter(el => el.kind !== ts.SyntaxKind.OmittedExpression); + return ts.factory.updateArrayLiteralExpression(array, ts.factory.createNodeArray(cleaned)); +}