/** * @angular-modernizer/plugin-angular - Magic String Selector Rule * * Detects magic string selector arguments passed to dynamic component loading * methods. Passing a raw string or template literal to methods like * `getComponentBySelector` or `loadComponent` creates fragile implicit * contracts that cannot be verified by the TypeScript compiler and break * silently when component selectors are renamed. * * Detection scope: * - `CallExpression` nodes whose called method name matches a configured * `targetMethodPatterns` list (default: `'getComponentBySelector'`, * `'loadComponent'`, `/get.*Component/i`). * - Argument classification: * - `StringLiteral` → `argumentType: 'string-literal'`, `severity: 'error'` * - `NoSubstitutionTemplateLiteral` / `TemplateExpression` → `argumentType: 'template-literal'`, `severity: 'error'` * - `PropertyAccessExpression` (e.g. `this.config.selector`) → `argumentType: 'config-property'`, `severity: 'warning'` * - All other argument kinds → not flagged (too many false positives). * * Skipped: * - `.d.ts` declaration files. * - Call expressions with no arguments. * - First arguments that are plain identifiers, function calls, or other * non-literal, non-property-access expressions. * * Pattern compilation: * - String entries in `targetMethodPatterns` are compiled to exact-match * regexes (`'^' + p + '$'`), preventing partial matches such as * `'load'` matching `'loadComponentFactory'`. * - `RegExp` entries are passed through unchanged (they express partial * matching explicitly, e.g. `/get.*Component/i`). * * @example * ```typescript * const rule = new MagicStringSelectorRule(); * const results = await rule.analyze(createContext(sourceFile, project)); * // results[0].metadata.violationType → 'magic-string-selector' * // results[0].metadata.methodName → 'getComponentBySelector' * // results[0].metadata.argumentType → 'string-literal' * // results[0].metadata.severity → 'error' * ``` */ import type { AnalysisRule, AnalysisContext, AnalysisResult } from '@angular-modernizer/plugin-system'; export interface MagicStringSelectorConfig { /** Method name patterns to check. Strings are compiled to exact-match regexes; RegExps pass through unchanged. */ targetMethodPatterns: (string | RegExp)[]; } export interface MagicStringSelectorMetadata { violationType: 'magic-string-selector'; methodName: string; argumentType: 'string-literal' | 'template-literal' | 'config-property'; selectorValue: string; severity: 'error' | 'warning'; } export declare class MagicStringSelectorRule implements AnalysisRule { readonly id = "angular:magic-string-selector"; readonly name = "Magic String Selector"; readonly description = "Detects magic string selector arguments passed to dynamic component loading methods"; readonly severity: "error"; readonly category = "angular-architecture"; readonly tags: string[]; private readonly config; private readonly compiledPatterns; constructor(config?: Partial); /** * Compiles the mixed `(string | RegExp)[]` pattern list into `RegExp[]`. * String entries are anchored (`^...$`) to prevent partial method-name matches. * RegExp entries are passed through unchanged. */ private compilePatterns; analyze(context: AnalysisContext): Promise; private detectMagicStringSelector; private extractMethodName; private classifyArgument; } //# sourceMappingURL=magic-string-selector.rule.d.ts.map