@ngcompass/common 0.1.1-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +975 -0
- package/dist/index.d.ts +975 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,975 @@
|
|
|
1
|
+
import * as typescript from 'typescript';
|
|
2
|
+
import typescript__default from 'typescript';
|
|
3
|
+
import { Program } from 'oxc-parser';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Constants used across packages
|
|
7
|
+
*/
|
|
8
|
+
declare const TOOL_NAME = "ngcompass";
|
|
9
|
+
declare const PACKAGE_VERSION = "v.0.1.1-beta";
|
|
10
|
+
declare const CACHE_VERSION = "1.0.0";
|
|
11
|
+
declare const CONFIG_FILE_NAMES: readonly [".ngcompassrc.json", ".ngcompassrc.js", ".ngcompass.config.js", "ngcompass.config.json"];
|
|
12
|
+
declare const DEFAULT_CACHE_DIR = "node_modules/.cache/ngcompass";
|
|
13
|
+
declare const DEFAULT_INCLUDE_PATTERNS: readonly ["**/*.ts", "**/*.html"];
|
|
14
|
+
declare const DEFAULT_EXCLUDE_PATTERNS: readonly ["**/node_modules/**", "**/dist/**", "**/build/**", "**/*.spec.ts", "**/*.test.ts"];
|
|
15
|
+
declare const SUPPORTED_ANGULAR_VERSIONS: {
|
|
16
|
+
readonly min: 12;
|
|
17
|
+
readonly max: 21;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Helper to map string offsets to line/column numbers.
|
|
22
|
+
*/
|
|
23
|
+
declare class Locator {
|
|
24
|
+
private readonly lines;
|
|
25
|
+
constructor(content: string);
|
|
26
|
+
location(offset: number): {
|
|
27
|
+
line: number;
|
|
28
|
+
column: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Custom error types
|
|
34
|
+
*/
|
|
35
|
+
declare class AnalyzerError extends Error {
|
|
36
|
+
readonly code?: string | undefined;
|
|
37
|
+
constructor(message: string, code?: string | undefined);
|
|
38
|
+
}
|
|
39
|
+
declare class ConfigurationError extends AnalyzerError {
|
|
40
|
+
constructor(message: string);
|
|
41
|
+
}
|
|
42
|
+
declare class ParseError extends AnalyzerError {
|
|
43
|
+
readonly filePath: string;
|
|
44
|
+
constructor(message: string, filePath: string);
|
|
45
|
+
}
|
|
46
|
+
declare class RuleError extends AnalyzerError {
|
|
47
|
+
readonly ruleId: string;
|
|
48
|
+
constructor(message: string, ruleId: string);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Thrown when a rule handler crashes during execution.
|
|
52
|
+
*
|
|
53
|
+
* Unlike ParseError (which is collected and surfaced as a warning),
|
|
54
|
+
* RuleExecutionError indicates a bug in the rule itself and is re-thrown
|
|
55
|
+
* so the caller can decide whether to fail loudly or skip the rule.
|
|
56
|
+
*/
|
|
57
|
+
declare class RuleExecutionError extends AnalyzerError {
|
|
58
|
+
readonly ruleName: string;
|
|
59
|
+
readonly filePath: string;
|
|
60
|
+
constructor(ruleName: string, filePath: string, cause: unknown);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Categories of infrastructure failures that can occur during analysis.
|
|
64
|
+
*
|
|
65
|
+
* ParseError — AST parsing failed for a source file
|
|
66
|
+
* IOError — File read / write failed
|
|
67
|
+
* WorkerCrash — A worker thread exited with a non-zero code
|
|
68
|
+
* CacheCorruption — A cached entry could not be deserialized
|
|
69
|
+
* SerializationError — stableSerialize() threw (indicates a rule authoring bug)
|
|
70
|
+
*/
|
|
71
|
+
type InfrastructureErrorType = 'ParseError' | 'IOError' | 'WorkerCrash' | 'CacheCorruption' | 'SerializationError' | 'RuleExecutionError';
|
|
72
|
+
/**
|
|
73
|
+
* Structured record of an infrastructure failure.
|
|
74
|
+
*
|
|
75
|
+
* recoverable: true → the pipeline can continue (file is skipped / cold rebuild)
|
|
76
|
+
* recoverable: false → the pipeline cannot produce correct results and should abort
|
|
77
|
+
* and should abort the current run.
|
|
78
|
+
*/
|
|
79
|
+
interface InfrastructureError {
|
|
80
|
+
readonly type: InfrastructureErrorType;
|
|
81
|
+
readonly filePath?: string;
|
|
82
|
+
readonly cause: string;
|
|
83
|
+
readonly timestamp: number;
|
|
84
|
+
readonly recoverable: boolean;
|
|
85
|
+
readonly phase: 'config' | 'planner' | 'engine';
|
|
86
|
+
readonly details?: Readonly<Record<string, unknown>>;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Factory that stamps a timestamp and freezes the error object.
|
|
90
|
+
*/
|
|
91
|
+
declare function createInfrastructureError(type: InfrastructureErrorType, fields: Omit<InfrastructureError, 'type' | 'timestamp'>): InfrastructureError;
|
|
92
|
+
/**
|
|
93
|
+
* Per-run accumulator of infrastructure errors.
|
|
94
|
+
*
|
|
95
|
+
* Passed through the pipeline so callers can inspect failures at the end
|
|
96
|
+
* after execution completes.
|
|
97
|
+
*/
|
|
98
|
+
declare class InfrastructureErrorCollector {
|
|
99
|
+
private readonly _errors;
|
|
100
|
+
record(error: InfrastructureError): void;
|
|
101
|
+
get errors(): ReadonlyArray<InfrastructureError>;
|
|
102
|
+
get hasFatalErrors(): boolean;
|
|
103
|
+
get hasAnyErrors(): boolean;
|
|
104
|
+
/** Returns only errors in a specific phase. */
|
|
105
|
+
forPhase(phase: InfrastructureError['phase']): ReadonlyArray<InfrastructureError>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Violation severity levels:
|
|
110
|
+
*
|
|
111
|
+
* error — hard-constraint violations that should block CI / fail the run.
|
|
112
|
+
* warn — advisory violations surfaced as warnings.
|
|
113
|
+
*/
|
|
114
|
+
type Severity = 'warn' | 'error';
|
|
115
|
+
/**
|
|
116
|
+
* Rule categories for organization
|
|
117
|
+
*/
|
|
118
|
+
declare enum RuleCategory {
|
|
119
|
+
Architecture = "architecture",
|
|
120
|
+
Performance = "performance",
|
|
121
|
+
SSR = "ssr",
|
|
122
|
+
Security = "security",
|
|
123
|
+
Accessibility = "accessibility",
|
|
124
|
+
Testing = "testing",
|
|
125
|
+
CodeSmell = "code-smell",
|
|
126
|
+
Reactivity = "reactivity",
|
|
127
|
+
BestPractice = "best-practice"
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Result type for functional error handling
|
|
131
|
+
*/
|
|
132
|
+
type Result<T, E = Error> = {
|
|
133
|
+
readonly ok: true;
|
|
134
|
+
readonly data: T;
|
|
135
|
+
} | {
|
|
136
|
+
readonly ok: false;
|
|
137
|
+
readonly error: E;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Creates a successful result
|
|
141
|
+
*/
|
|
142
|
+
declare const Ok: <T>(data: T) => Result<T, never>;
|
|
143
|
+
/**
|
|
144
|
+
* Creates a failed result
|
|
145
|
+
*/
|
|
146
|
+
declare const Err: <E>(error: E) => Result<never, E>;
|
|
147
|
+
/**
|
|
148
|
+
* Rule severity levels
|
|
149
|
+
*/
|
|
150
|
+
type RuleSeverity = Severity | 'off';
|
|
151
|
+
/**
|
|
152
|
+
* Short-hand rule configuration (just severity)
|
|
153
|
+
*/
|
|
154
|
+
type RuleConfigShorthand = RuleSeverity;
|
|
155
|
+
/**
|
|
156
|
+
* Full rule configuration (severity + options)
|
|
157
|
+
*/
|
|
158
|
+
interface RuleConfigFull {
|
|
159
|
+
readonly severity: RuleSeverity;
|
|
160
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Rule configuration (either shorthand or full)
|
|
164
|
+
*/
|
|
165
|
+
type RuleConfig = RuleConfigShorthand | RuleConfigFull;
|
|
166
|
+
/**
|
|
167
|
+
* Rules object (ruleName → config)
|
|
168
|
+
*/
|
|
169
|
+
type RulesConfig = Readonly<Record<string, RuleConfig>>;
|
|
170
|
+
/**
|
|
171
|
+
* Dependency types for rules
|
|
172
|
+
*/
|
|
173
|
+
type RuleDependencyType = 'standalone' | 'component' | 'styles' | 'imports' | 'spec';
|
|
174
|
+
/**
|
|
175
|
+
* AST requirements for a rule
|
|
176
|
+
*/
|
|
177
|
+
interface RuleAstRequirements {
|
|
178
|
+
readonly tsAst?: boolean;
|
|
179
|
+
readonly htmlAst?: boolean;
|
|
180
|
+
readonly cssAst?: boolean;
|
|
181
|
+
readonly specAst?: boolean;
|
|
182
|
+
readonly typeChecker?: boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Set to `true` when the rule needs the project-wide import graph,
|
|
185
|
+
* component → template mapping, or other cross-file metadata provided
|
|
186
|
+
* by `ProjectContext`.
|
|
187
|
+
*
|
|
188
|
+
* Rules declaring this are routed to the type-aware execution path (main
|
|
189
|
+
* thread) so they always receive a populated `context.project`.
|
|
190
|
+
* Implies `typeChecker` for routing purposes (the TypeScript Program is
|
|
191
|
+
* required to build the import graph).
|
|
192
|
+
*/
|
|
193
|
+
readonly projectContext?: boolean;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* File type patterns a rule applies to
|
|
197
|
+
*/
|
|
198
|
+
interface RuleFilePatterns {
|
|
199
|
+
readonly include?: ReadonlyArray<string>;
|
|
200
|
+
readonly exclude?: ReadonlyArray<string>;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Rule metadata (describes rule behavior)
|
|
204
|
+
*/
|
|
205
|
+
interface RuleMetadata {
|
|
206
|
+
readonly name: string;
|
|
207
|
+
readonly description: string;
|
|
208
|
+
readonly category: string;
|
|
209
|
+
readonly dependencyType: RuleDependencyType;
|
|
210
|
+
readonly requires: RuleAstRequirements;
|
|
211
|
+
readonly filePatterns?: RuleFilePatterns;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Resolved rule (config + metadata)
|
|
215
|
+
*/
|
|
216
|
+
interface ResolvedRule {
|
|
217
|
+
readonly name: string;
|
|
218
|
+
readonly severity: RuleSeverity;
|
|
219
|
+
readonly options: Readonly<Record<string, unknown>>;
|
|
220
|
+
readonly metadata: RuleMetadata;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Map of resolved rules
|
|
224
|
+
*/
|
|
225
|
+
type ResolvedRulesMap = ReadonlyMap<string, ResolvedRule>;
|
|
226
|
+
/**
|
|
227
|
+
* Preset configuration file structure
|
|
228
|
+
*/
|
|
229
|
+
interface PresetConfig {
|
|
230
|
+
readonly name: string;
|
|
231
|
+
readonly description?: string;
|
|
232
|
+
readonly extends?: string | ReadonlyArray<string>;
|
|
233
|
+
readonly rules: RulesConfig;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Built-in preset names
|
|
237
|
+
*/
|
|
238
|
+
type BuiltinPreset = 'recommended' | 'strict' | 'performance' | 'reactivity' | 'security' | 'ssr' | 'all';
|
|
239
|
+
/**
|
|
240
|
+
* Preset reference (builtin or file path)
|
|
241
|
+
*/
|
|
242
|
+
type PresetReference = string;
|
|
243
|
+
/**
|
|
244
|
+
* Rule resolution result
|
|
245
|
+
*/
|
|
246
|
+
interface RuleResolutionResult {
|
|
247
|
+
readonly rules: ResolvedRulesMap;
|
|
248
|
+
readonly metadata: {
|
|
249
|
+
readonly totalRules: number;
|
|
250
|
+
readonly enabledRules: number;
|
|
251
|
+
readonly disabledRules: number;
|
|
252
|
+
readonly presetsLoaded: ReadonlyArray<string>;
|
|
253
|
+
readonly resolutionTime: number;
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Rule registry entry (for looking up metadata)
|
|
258
|
+
*/
|
|
259
|
+
interface RuleRegistryEntry {
|
|
260
|
+
readonly name: string;
|
|
261
|
+
readonly metadata: RuleMetadata;
|
|
262
|
+
readonly defaultConfig: RuleConfigFull;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Rule registry (ruleName → entry)
|
|
266
|
+
*/
|
|
267
|
+
type RuleRegistryMap = ReadonlyMap<string, RuleRegistryEntry>;
|
|
268
|
+
interface RegisterOptions {
|
|
269
|
+
allowOverride?: boolean;
|
|
270
|
+
}
|
|
271
|
+
interface RulePlugin {
|
|
272
|
+
readonly name: string;
|
|
273
|
+
/**
|
|
274
|
+
* The rule handler. Typed as `unknown` here because `@ngcompass/common`
|
|
275
|
+
* cannot import `RuleHandler` from `@ngcompass/engine` (would create a
|
|
276
|
+
* circular dependency). Call sites in `@ngcompass/rules` narrow this to
|
|
277
|
+
* `RuleHandler<unknown>` when registering.
|
|
278
|
+
*/
|
|
279
|
+
readonly handler: unknown;
|
|
280
|
+
readonly meta?: Partial<RuleMetadata>;
|
|
281
|
+
readonly manifest?: PluginManifest;
|
|
282
|
+
}
|
|
283
|
+
interface RuleRegistry {
|
|
284
|
+
register(plugin: RulePlugin, opts?: RegisterOptions): void;
|
|
285
|
+
get(name: string): unknown;
|
|
286
|
+
has(name: string): boolean;
|
|
287
|
+
getRuleNames(): ReadonlyArray<string>;
|
|
288
|
+
getAll(): ReadonlyMap<string, unknown>;
|
|
289
|
+
getMeta(name: string): Partial<RuleMetadata> | undefined;
|
|
290
|
+
getMetadata(name: string): RuleMetadata | undefined;
|
|
291
|
+
getRegistryEntry(name: string): RuleRegistryEntry | undefined;
|
|
292
|
+
toReadonlyMap(): ReadonlyMap<string, RuleRegistryEntry>;
|
|
293
|
+
readonly size: number;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* A single entry in the rules list output.
|
|
297
|
+
* Consumed by the RulesReporter to render a grouped, filterable rule catalog.
|
|
298
|
+
*/
|
|
299
|
+
interface RuleListEntry {
|
|
300
|
+
readonly name: string;
|
|
301
|
+
readonly description: string;
|
|
302
|
+
readonly domain: string;
|
|
303
|
+
readonly severity: string;
|
|
304
|
+
readonly presets: readonly string[];
|
|
305
|
+
}
|
|
306
|
+
interface RuleFailure {
|
|
307
|
+
readonly filePath: string;
|
|
308
|
+
readonly message: string;
|
|
309
|
+
readonly line: number;
|
|
310
|
+
readonly column: number;
|
|
311
|
+
readonly severity: RuleSeverity;
|
|
312
|
+
readonly ruleName: string;
|
|
313
|
+
/**
|
|
314
|
+
* Optional actionable fix recommendation shown in reporter output.
|
|
315
|
+
* Plain English description of how to resolve the violation.
|
|
316
|
+
* Example: "Add standalone: true to @Component({ ... })"
|
|
317
|
+
*/
|
|
318
|
+
readonly fix?: string;
|
|
319
|
+
/**
|
|
320
|
+
* Optional multi-line code snippet illustrating the correct pattern.
|
|
321
|
+
* Displayed below the fix recommendation when no auto-fix is available.
|
|
322
|
+
* Use plain TypeScript — no ANSI codes.
|
|
323
|
+
*/
|
|
324
|
+
readonly codeExample?: string;
|
|
325
|
+
}
|
|
326
|
+
interface RuleResult {
|
|
327
|
+
readonly ruleName: string;
|
|
328
|
+
readonly failures: ReadonlyArray<RuleFailure>;
|
|
329
|
+
readonly taskId?: string;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Minimal parsed template AST handed to rules via `RuleContext.template`.
|
|
333
|
+
* Mirrors `@ngcompass/ast`'s `HtmlParserResult` without importing it.
|
|
334
|
+
*
|
|
335
|
+
* Rule authors: access `rootNodes` to traverse the Angular HTML tree.
|
|
336
|
+
* Each node is typed `unknown` here; use `@ngcompass/ast`'s node interfaces
|
|
337
|
+
* (e.g. `Element`, `Text`, `BoundAttribute`) for narrowing.
|
|
338
|
+
*/
|
|
339
|
+
interface TemplateAst {
|
|
340
|
+
/** Root-level parsed nodes from the Angular HTML parser. */
|
|
341
|
+
readonly rootNodes: ReadonlyArray<unknown>;
|
|
342
|
+
/** Parse errors emitted by the HTML parser (does not throw). */
|
|
343
|
+
readonly errors: ReadonlyArray<unknown>;
|
|
344
|
+
/**
|
|
345
|
+
* Byte offset of the first template character inside the source file.
|
|
346
|
+
* - External `.html` files: always `0`.
|
|
347
|
+
* - Inline templates inside `.ts` files: position after the opening quote.
|
|
348
|
+
* Add this value to node `sourceSpan.start` before calling
|
|
349
|
+
* `context.locator.location()` to obtain correct line/column numbers.
|
|
350
|
+
*/
|
|
351
|
+
readonly templateStartOffset: number;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Minimal parsed style AST handed to rules via `RuleContext.style`.
|
|
355
|
+
* Mirrors `@ngcompass/ast`'s `CssResult` without importing it.
|
|
356
|
+
*/
|
|
357
|
+
interface StyleAst {
|
|
358
|
+
/** Whether parsing succeeded. */
|
|
359
|
+
readonly ok: boolean;
|
|
360
|
+
/** Transformed CSS bytes — present when `ok` is `true`. */
|
|
361
|
+
readonly code?: Buffer | Uint8Array;
|
|
362
|
+
/** Parse/transform error — present when `ok` is `false`. */
|
|
363
|
+
readonly error?: unknown;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Component file cluster: the TypeScript class file and its associated
|
|
367
|
+
* template, styles, and spec (mirrors ComponentNode in @ngcompass/planner
|
|
368
|
+
* without creating a cross-package dependency).
|
|
369
|
+
*/
|
|
370
|
+
interface ComponentFiles {
|
|
371
|
+
/** Absolute path to the `.component.ts` file. */
|
|
372
|
+
readonly tsPath: string;
|
|
373
|
+
/** Absolute path to the external template file, if any. */
|
|
374
|
+
readonly templatePath?: string;
|
|
375
|
+
/** Absolute paths to associated style files. */
|
|
376
|
+
readonly stylePaths: ReadonlyArray<string>;
|
|
377
|
+
/** Absolute path to the spec file, if any. */
|
|
378
|
+
readonly specPath?: string;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Angular module metadata extracted from `@NgModule` or standalone
|
|
382
|
+
* `@Component` decorators. Populated by CTX-004; initially empty.
|
|
383
|
+
*/
|
|
384
|
+
interface NgModuleInfo {
|
|
385
|
+
/** Absolute path to the module/component file. */
|
|
386
|
+
readonly filePath: string;
|
|
387
|
+
/** Class names declared in this module (or standalone imports array). */
|
|
388
|
+
readonly declarations: ReadonlySet<string>;
|
|
389
|
+
/** Class names imported by this module/standalone component. */
|
|
390
|
+
readonly imports: ReadonlySet<string>;
|
|
391
|
+
/** Class names exported from this module. */
|
|
392
|
+
readonly exports: ReadonlySet<string>;
|
|
393
|
+
/** Provider class names registered in this module/component. */
|
|
394
|
+
readonly providers: ReadonlySet<string>;
|
|
395
|
+
/** `true` for standalone components; `false` for NgModule-based. */
|
|
396
|
+
readonly isStandalone: boolean;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Project-wide, read-only context shared across all rules in a single run.
|
|
400
|
+
*
|
|
401
|
+
* Computed once by `buildProjectContext()` (@ngcompass/engine) before task
|
|
402
|
+
* dispatch and injected into every `RuleContext` for rules that opt-in via
|
|
403
|
+
* `requires.projectContext: true`.
|
|
404
|
+
*
|
|
405
|
+
* All file paths are absolute and normalised with `path.resolve()`.
|
|
406
|
+
*/
|
|
407
|
+
interface ProjectContext {
|
|
408
|
+
/**
|
|
409
|
+
* Forward import graph: absolute file path → set of absolute paths it
|
|
410
|
+
* directly imports (intra-project only; external packages excluded).
|
|
411
|
+
*/
|
|
412
|
+
readonly importGraph: ReadonlyMap<string, ReadonlySet<string>>;
|
|
413
|
+
/**
|
|
414
|
+
* Reverse import graph: absolute file path → set of absolute paths that
|
|
415
|
+
* directly import it. Enables "who uses this file?" queries in O(1).
|
|
416
|
+
*/
|
|
417
|
+
readonly reverseImportGraph: ReadonlyMap<string, ReadonlySet<string>>;
|
|
418
|
+
/**
|
|
419
|
+
* Angular module / standalone component map. (CTX-004)
|
|
420
|
+
*
|
|
421
|
+
* Key: absolute path to the `@NgModule` or standalone `@Component` file.
|
|
422
|
+
* Value: `NgModuleInfo` with declarations, imports, exports, providers.
|
|
423
|
+
*
|
|
424
|
+
* Populated by scanning all `@NgModule` and `@Component({ standalone: true })`
|
|
425
|
+
* decorators in the project. Empty for files that are neither.
|
|
426
|
+
*/
|
|
427
|
+
readonly ngModuleMap: ReadonlyMap<string, NgModuleInfo>;
|
|
428
|
+
/**
|
|
429
|
+
* Set of absolute file paths for all standalone Angular entities. (CTX-004)
|
|
430
|
+
*
|
|
431
|
+
* Includes files that contain `@Component({ standalone: true })`,
|
|
432
|
+
* `@Directive({ standalone: true })`, or `@Pipe({ standalone: true })`.
|
|
433
|
+
*
|
|
434
|
+
* Rules can use this to detect module-based components subject to a
|
|
435
|
+
* standalone-first migration policy, or to validate that standalone
|
|
436
|
+
* components only reference dependencies in their own `imports` array.
|
|
437
|
+
*/
|
|
438
|
+
readonly standaloneComponents: ReadonlySet<string>;
|
|
439
|
+
/**
|
|
440
|
+
* Class name → absolute file path resolver. (CTX-004)
|
|
441
|
+
*
|
|
442
|
+
* Maps the name of every exported class in the project to the absolute
|
|
443
|
+
* path of the file that declares it. Enables NgModule rules to resolve
|
|
444
|
+
* the class names stored in `NgModuleInfo.declarations` / `imports` /
|
|
445
|
+
* `exports` / `providers` to concrete file paths without a linear scan.
|
|
446
|
+
*
|
|
447
|
+
* Only directly-exported class declarations are indexed (`export class Foo`);
|
|
448
|
+
* re-exports through barrel files are not followed.
|
|
449
|
+
*
|
|
450
|
+
* Example:
|
|
451
|
+
* `project.classToFile.get('FooComponent')` → `'/src/app/foo/foo.component.ts'`
|
|
452
|
+
*/
|
|
453
|
+
readonly classToFile: ReadonlyMap<string, string>;
|
|
454
|
+
/**
|
|
455
|
+
* Component file cluster map.
|
|
456
|
+
* Key: absolute path to the `.component.ts` file.
|
|
457
|
+
* Value: associated template, styles, and spec paths.
|
|
458
|
+
*/
|
|
459
|
+
readonly componentGraph: ReadonlyMap<string, ComponentFiles>;
|
|
460
|
+
/**
|
|
461
|
+
* Full set of absolute file paths discovered by the scanner for this run.
|
|
462
|
+
*/
|
|
463
|
+
readonly projectFiles: ReadonlySet<string>;
|
|
464
|
+
/** Root directory of the project (absolute, normalised). */
|
|
465
|
+
readonly rootDir: string;
|
|
466
|
+
/**
|
|
467
|
+
* Set of barrel file absolute paths.
|
|
468
|
+
*
|
|
469
|
+
* A barrel file is one whose every top-level statement is an
|
|
470
|
+
* `export … from '…'` re-export declaration (no regular imports,
|
|
471
|
+
* no class/function/variable declarations). The canonical example is
|
|
472
|
+
* an `index.ts` or `public-api.ts` that re-exports sibling modules.
|
|
473
|
+
*
|
|
474
|
+
* Rules can use this to skip barrel files (no logic to lint) or to
|
|
475
|
+
* follow re-export chains when tracing where a symbol is consumed.
|
|
476
|
+
*/
|
|
477
|
+
readonly barrelFiles: ReadonlySet<string>;
|
|
478
|
+
/**
|
|
479
|
+
* External dependency map (CTX-002).
|
|
480
|
+
*
|
|
481
|
+
* Key: absolute path of the project source file.
|
|
482
|
+
* Value: set of npm package names (scope-aware bare specifiers, e.g.
|
|
483
|
+
* `'@angular/core'`, `'rxjs'`) imported by that file.
|
|
484
|
+
*
|
|
485
|
+
* Sub-path specifiers are normalised to the package name:
|
|
486
|
+
* `'rxjs/operators'` → `'rxjs'`
|
|
487
|
+
* `'@angular/core/rxjs-interop'` → `'@angular/core'`
|
|
488
|
+
*
|
|
489
|
+
* Relative imports and absolute paths are excluded.
|
|
490
|
+
* Entries are only present for files that have at least one external dep —
|
|
491
|
+
* files with no external deps simply have no entry in the map.
|
|
492
|
+
*/
|
|
493
|
+
readonly externalDeps: ReadonlyMap<string, ReadonlySet<string>>;
|
|
494
|
+
/**
|
|
495
|
+
* Reverse map: absolute template file path → absolute component `.ts` path.
|
|
496
|
+
*
|
|
497
|
+
* Enables template rules to answer "which component owns this template?"
|
|
498
|
+
* in O(1) without scanning the whole `componentGraph`.
|
|
499
|
+
*
|
|
500
|
+
* Built automatically from `componentGraph` by `buildProjectContext()`.
|
|
501
|
+
* Only files that have an explicit external template appear here; inline
|
|
502
|
+
* templates are associated via `componentGraph` keyed on the `.ts` path.
|
|
503
|
+
*/
|
|
504
|
+
readonly templateToComponent: ReadonlyMap<string, string>;
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Cross-reference between an Angular component and its associated files.
|
|
508
|
+
*
|
|
509
|
+
* Attached to `RuleContext.crossRef` for rules running on:
|
|
510
|
+
* - `.component.ts` files — gives access to `templatePath`, `stylePaths`,
|
|
511
|
+
* `specPath`, and `templateReferences` (members used in the template).
|
|
512
|
+
* - `.component.html` template files — gives access to `componentPath`
|
|
513
|
+
* and `publicMembers` (members declared on the component class).
|
|
514
|
+
*
|
|
515
|
+
* `undefined` for all other file types and when `project` is unavailable.
|
|
516
|
+
*/
|
|
517
|
+
interface ComponentCrossRef {
|
|
518
|
+
/** Absolute path to the `.component.ts` class file. */
|
|
519
|
+
readonly componentPath: string;
|
|
520
|
+
/**
|
|
521
|
+
* Absolute path to the external template `.html` file.
|
|
522
|
+
* `undefined` when the component uses an inline `template: '…'` string.
|
|
523
|
+
*/
|
|
524
|
+
readonly templatePath?: string;
|
|
525
|
+
/** Absolute paths to associated style files (`.scss`, `.css`, …). */
|
|
526
|
+
readonly stylePaths: ReadonlyArray<string>;
|
|
527
|
+
/** Absolute path to the spec file, if any. */
|
|
528
|
+
readonly specPath?: string;
|
|
529
|
+
/**
|
|
530
|
+
* Names of public members (properties and methods) declared directly in
|
|
531
|
+
* the component class, extracted from the TypeScript `SourceFile`.
|
|
532
|
+
*
|
|
533
|
+
* Available in **template rules** to verify that every bound property /
|
|
534
|
+
* called method actually exists in the component class.
|
|
535
|
+
*
|
|
536
|
+
* Populated only when the type-aware execution path is active
|
|
537
|
+
* (`ts.Program` exists). Private, protected, and `#private` members are
|
|
538
|
+
* excluded.
|
|
539
|
+
*/
|
|
540
|
+
readonly publicMembers?: ReadonlySet<string>;
|
|
541
|
+
/**
|
|
542
|
+
* Public class fields that are known Angular signal-like values.
|
|
543
|
+
*
|
|
544
|
+
* These are safe to invoke from templates as `name()` because the call reads
|
|
545
|
+
* signal state rather than executing arbitrary component work.
|
|
546
|
+
*/
|
|
547
|
+
readonly signalMembers?: ReadonlySet<string>;
|
|
548
|
+
/**
|
|
549
|
+
* Identifiers from the template that reference the component — property
|
|
550
|
+
* reads, method calls, and event-handler expressions whose implicit
|
|
551
|
+
* receiver is the component instance (`this`).
|
|
552
|
+
*
|
|
553
|
+
* Available in **component rules** to detect unused public members (a
|
|
554
|
+
* member not in this set is likely unreferenced in the template).
|
|
555
|
+
*
|
|
556
|
+
* Populated when the template AST is already loaded for the current
|
|
557
|
+
* analysis batch (i.e. the rule or a peer rule declared `htmlAst: true`).
|
|
558
|
+
*/
|
|
559
|
+
readonly templateReferences?: ReadonlySet<string>;
|
|
560
|
+
}
|
|
561
|
+
interface RuleContext {
|
|
562
|
+
/**
|
|
563
|
+
* Lazily-created TypeScript `SourceFile` for this file.
|
|
564
|
+
*
|
|
565
|
+
* Populated on first access by `rule-utils.ts`:`getTsSymbolAtNode()` when a rule
|
|
566
|
+
* requests TypeChecker-based symbol resolution. Creating a `SourceFile` is O(n)
|
|
567
|
+
* in source length; caching it here ensures the cost is paid at most once per
|
|
568
|
+
* file, regardless of how many rules request type information.
|
|
569
|
+
*
|
|
570
|
+
* Rule authors: **do not read or write this field directly.** Use
|
|
571
|
+
* `getTsSymbolAtNode(node, context)` from `rule-utils` instead.
|
|
572
|
+
*/
|
|
573
|
+
readonly sourceFile?: typescript.SourceFile;
|
|
574
|
+
readonly filePath: string;
|
|
575
|
+
readonly fileContent: string;
|
|
576
|
+
readonly locator: Locator;
|
|
577
|
+
readonly program?: Program;
|
|
578
|
+
readonly typeChecker?: typescript.TypeChecker;
|
|
579
|
+
/**
|
|
580
|
+
* Parsed template AST — use `rootNodes` to traverse the Angular HTML tree.
|
|
581
|
+
* Typed as `TemplateAst` (defined above) to avoid a circular dep on `@ngcompass/ast`.
|
|
582
|
+
*/
|
|
583
|
+
readonly template?: TemplateAst;
|
|
584
|
+
/**
|
|
585
|
+
* External template file details used while dispatching template rules.
|
|
586
|
+
*
|
|
587
|
+
* Present only when a component rule batch loaded a separate `.html`
|
|
588
|
+
* template. Template rule execution may use these values so findings point
|
|
589
|
+
* at the HTML file instead of the owning `.component.ts` file.
|
|
590
|
+
*/
|
|
591
|
+
readonly templateFilePath?: string;
|
|
592
|
+
readonly templateFileContent?: string;
|
|
593
|
+
readonly templateLocator?: Locator;
|
|
594
|
+
/**
|
|
595
|
+
* Parsed style AST — check `ok` before accessing `code`.
|
|
596
|
+
* Typed as `StyleAst` (defined above) to avoid a circular dep on `@ngcompass/ast`.
|
|
597
|
+
*/
|
|
598
|
+
readonly style?: StyleAst;
|
|
599
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
600
|
+
/**
|
|
601
|
+
* Project-wide cross-file metadata (import graph, component clusters, …).
|
|
602
|
+
*
|
|
603
|
+
* Populated only for rules that declare `requires.projectContext: true`.
|
|
604
|
+
* `undefined` for all other rules — access is always guarded by an opt-in
|
|
605
|
+
* flag so there is zero overhead on rules that don't need it.
|
|
606
|
+
*/
|
|
607
|
+
readonly project?: ProjectContext;
|
|
608
|
+
/**
|
|
609
|
+
* Component ↔ template cross-reference (CTX-003).
|
|
610
|
+
*
|
|
611
|
+
* Non-`undefined` when `project` is available **and** the file under
|
|
612
|
+
* analysis is either a `.component.ts` file or its associated template.
|
|
613
|
+
* Provides structural links (paths) and optional semantic sets
|
|
614
|
+
* (`publicMembers`, `templateReferences`) at zero extra parse cost for
|
|
615
|
+
* files that don't match either category.
|
|
616
|
+
*/
|
|
617
|
+
readonly crossRef?: ComponentCrossRef;
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* Analysis aggregate output.
|
|
621
|
+
*/
|
|
622
|
+
interface AnalysisResult {
|
|
623
|
+
readonly results: ReadonlyArray<RuleResult>;
|
|
624
|
+
/**
|
|
625
|
+
* Parse errors encountered during analysis (collected, not thrown).
|
|
626
|
+
* Allows analysis to continue for other files while surfacing tool errors
|
|
627
|
+
* separately from rule violations in the reporter output.
|
|
628
|
+
*/
|
|
629
|
+
readonly parseErrors: ReadonlyArray<ParseError>;
|
|
630
|
+
readonly stats: {
|
|
631
|
+
readonly totalFiles: number;
|
|
632
|
+
readonly totalErrors: number;
|
|
633
|
+
readonly totalWarnings: number;
|
|
634
|
+
readonly duration: number;
|
|
635
|
+
/**
|
|
636
|
+
* Fraction of tasks whose results were served from cache (0–1).
|
|
637
|
+
* `undefined` when no cache is in use (e.g. first cold run or worker path).
|
|
638
|
+
* Consumers can display this as a percentage: `(cacheHitRate * 100).toFixed(1)%`.
|
|
639
|
+
*/
|
|
640
|
+
readonly cacheHitRate?: number;
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
/** Describes a task that failed inside a worker thread. */
|
|
644
|
+
interface WorkerTaskError {
|
|
645
|
+
readonly task: {
|
|
646
|
+
readonly taskId: string;
|
|
647
|
+
};
|
|
648
|
+
readonly error: string;
|
|
649
|
+
}
|
|
650
|
+
/** File-level progress event emitted by a worker thread. */
|
|
651
|
+
interface WorkerFileProgress {
|
|
652
|
+
readonly kind: 'file-progress';
|
|
653
|
+
readonly filePath: string;
|
|
654
|
+
readonly taskCount: number;
|
|
655
|
+
readonly issueCount: number;
|
|
656
|
+
readonly errorCount: number;
|
|
657
|
+
readonly warningCount: number;
|
|
658
|
+
readonly duration: number;
|
|
659
|
+
}
|
|
660
|
+
/** Message posted back from a worker thread to the orchestrator. */
|
|
661
|
+
interface WorkerMessageResult {
|
|
662
|
+
readonly results: RuleResult[];
|
|
663
|
+
readonly errors: WorkerTaskError[];
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* Optional manifest that a plugin can export alongside its rules.
|
|
668
|
+
*
|
|
669
|
+
* When present the engine validates:
|
|
670
|
+
* - That the current tool version satisfies engineVersionRange
|
|
671
|
+
* - That required capabilities (typeInfo, templateAST) are available
|
|
672
|
+
*
|
|
673
|
+
* Plugins without a manifest are loaded with a deprecation warning.
|
|
674
|
+
* Enforcement (hard error on missing manifest) is reserved for the next major.
|
|
675
|
+
*/
|
|
676
|
+
interface PluginManifest {
|
|
677
|
+
/** Package name (must match the plugin's npm package name) */
|
|
678
|
+
readonly name: string;
|
|
679
|
+
/** Plugin semver version (e.g. "2.1.0") */
|
|
680
|
+
readonly version: string;
|
|
681
|
+
/** Engine API semver version this plugin was built against */
|
|
682
|
+
readonly apiVersion: string;
|
|
683
|
+
/**
|
|
684
|
+
* Semver range of ngcompass versions this plugin is compatible with.
|
|
685
|
+
* Examples: ">=1.0.0 <2.0.0", "^1.2.0", "*"
|
|
686
|
+
*/
|
|
687
|
+
readonly engineVersionRange: string;
|
|
688
|
+
/** Optional capability declarations */
|
|
689
|
+
readonly capabilities?: {
|
|
690
|
+
/** Plugin uses the TypeScript type-checker (expensive) */
|
|
691
|
+
readonly requiresTypeInfo?: boolean;
|
|
692
|
+
/** Plugin needs the full HTML template AST */
|
|
693
|
+
readonly requiresTemplateAST?: boolean;
|
|
694
|
+
/** Plugin needs the CSS/SCSS AST */
|
|
695
|
+
readonly requiresCssAST?: boolean;
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
/** Minimal telemetry event shape used in config (avoids circular dep with core) */
|
|
699
|
+
interface TelemetryEventBase {
|
|
700
|
+
readonly phase: 'config' | 'planner' | 'engine';
|
|
701
|
+
readonly operation: string;
|
|
702
|
+
readonly durationMs: number;
|
|
703
|
+
readonly cacheHit?: boolean;
|
|
704
|
+
readonly workerId?: number;
|
|
705
|
+
readonly metadata?: Readonly<Record<string, string | number | boolean>>;
|
|
706
|
+
}
|
|
707
|
+
interface TelemetryConfig {
|
|
708
|
+
/** Whether telemetry collection is active (default: false) */
|
|
709
|
+
enabled?: boolean;
|
|
710
|
+
/**
|
|
711
|
+
* Called synchronously for every emitted event.
|
|
712
|
+
* Use this to pipe events to a file, stdout, or an external collector.
|
|
713
|
+
*/
|
|
714
|
+
onEvent?: (event: TelemetryEventBase) => void;
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Reporting output formats
|
|
718
|
+
*/
|
|
719
|
+
type OutputFormat = 'json' | 'text' | 'sarif' | 'html';
|
|
720
|
+
/**
|
|
721
|
+
* Severity level that triggers failure in CI/build
|
|
722
|
+
*/
|
|
723
|
+
type FailSeverity = Severity;
|
|
724
|
+
/**
|
|
725
|
+
* TypeScript parser options
|
|
726
|
+
*/
|
|
727
|
+
interface ParserOptions {
|
|
728
|
+
project?: string;
|
|
729
|
+
tsconfigRootDir?: string;
|
|
730
|
+
sourceType?: 'module' | 'commonjs';
|
|
731
|
+
ecmaVersion?: number;
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Cache configuration options
|
|
735
|
+
*/
|
|
736
|
+
interface CacheOptions {
|
|
737
|
+
enabled?: boolean;
|
|
738
|
+
location?: string;
|
|
739
|
+
strategy?: 'memory' | 'local';
|
|
740
|
+
ttl?: number;
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* Configuration override for specific files
|
|
744
|
+
* Rules in overrides are merged with global rules
|
|
745
|
+
*/
|
|
746
|
+
interface ConfigOverride {
|
|
747
|
+
files: string | string[];
|
|
748
|
+
rules?: Record<string, RuleConfig | Severity | 'off'>;
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Profile-specific configuration (dev/ci)
|
|
752
|
+
* Profiles can override most settings except nested profiles
|
|
753
|
+
*/
|
|
754
|
+
type ProfileConfig = Partial<Omit<AnalyzerConfig, 'profiles'>>;
|
|
755
|
+
/**
|
|
756
|
+
* Main analyzer configuration interface
|
|
757
|
+
* Supports extends, rules, overrides, profiles, and more
|
|
758
|
+
*/
|
|
759
|
+
interface AnalyzerConfig {
|
|
760
|
+
/**
|
|
761
|
+
* Extend from other configuration presets
|
|
762
|
+
*/
|
|
763
|
+
extends?: string | string[];
|
|
764
|
+
/**
|
|
765
|
+
* Files to include in analysis
|
|
766
|
+
*/
|
|
767
|
+
include?: string[];
|
|
768
|
+
/**
|
|
769
|
+
* Files to exclude from analysis
|
|
770
|
+
*/
|
|
771
|
+
exclude?: string[];
|
|
772
|
+
/**
|
|
773
|
+
* Maximum number of worker threads for parallel analysis
|
|
774
|
+
*/
|
|
775
|
+
maxWorkers?: number;
|
|
776
|
+
/**
|
|
777
|
+
* Cache configuration
|
|
778
|
+
*/
|
|
779
|
+
cache?: boolean | CacheOptions;
|
|
780
|
+
/**
|
|
781
|
+
* Output format for reports
|
|
782
|
+
*/
|
|
783
|
+
outputFormat?: OutputFormat;
|
|
784
|
+
/**
|
|
785
|
+
* Output file path for report
|
|
786
|
+
*/
|
|
787
|
+
outputPath?: string;
|
|
788
|
+
/**
|
|
789
|
+
* Severity level that causes non-zero exit code
|
|
790
|
+
*/
|
|
791
|
+
failOnSeverity?: FailSeverity;
|
|
792
|
+
/**
|
|
793
|
+
* Maximum number of violations allowed before failing
|
|
794
|
+
*/
|
|
795
|
+
maxWarnings?: number;
|
|
796
|
+
/**
|
|
797
|
+
* Additional patterns to ignore
|
|
798
|
+
*/
|
|
799
|
+
ignorePatterns?: string[];
|
|
800
|
+
/**
|
|
801
|
+
* External rule plugins to load.
|
|
802
|
+
* Each entry is a package name or file path that exports a RulePlugin or RulePlugin[].
|
|
803
|
+
* Example: ['@my-org/ngcompass-rules', './tools/local-rules']
|
|
804
|
+
*/
|
|
805
|
+
plugins?: string[];
|
|
806
|
+
/**
|
|
807
|
+
* Rule configuration
|
|
808
|
+
*/
|
|
809
|
+
rules?: Record<string, RuleConfig | Severity | 'off'>;
|
|
810
|
+
/**
|
|
811
|
+
* Per-file rule overrides
|
|
812
|
+
*/
|
|
813
|
+
overrides?: ConfigOverride[];
|
|
814
|
+
/**
|
|
815
|
+
* TypeScript parser configuration
|
|
816
|
+
*/
|
|
817
|
+
parserOptions?: ParserOptions;
|
|
818
|
+
/**
|
|
819
|
+
* Environment-specific profiles
|
|
820
|
+
*/
|
|
821
|
+
profiles?: Record<string, ProfileConfig>;
|
|
822
|
+
/**
|
|
823
|
+
* Structured telemetry collection.
|
|
824
|
+
* Disabled by default — enabling it adds a small per-event overhead.
|
|
825
|
+
*/
|
|
826
|
+
telemetry?: TelemetryConfig;
|
|
827
|
+
/**
|
|
828
|
+
* Engine execution thresholds.
|
|
829
|
+
* Override the built-in defaults for parallelism decisions.
|
|
830
|
+
*/
|
|
831
|
+
engine?: {
|
|
832
|
+
/**
|
|
833
|
+
* Number of tasks above which the worker pool is used instead of
|
|
834
|
+
* local pLimit execution. Default: 150.
|
|
835
|
+
*/
|
|
836
|
+
parallelThreshold?: number;
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* Structured configuration issue
|
|
841
|
+
*/
|
|
842
|
+
interface ConfigIssue {
|
|
843
|
+
readonly code: string;
|
|
844
|
+
readonly message: string;
|
|
845
|
+
readonly path?: ReadonlyArray<string | number>;
|
|
846
|
+
readonly severity: 'error' | 'warning';
|
|
847
|
+
readonly file?: string;
|
|
848
|
+
readonly line?: number;
|
|
849
|
+
readonly column?: number;
|
|
850
|
+
readonly suggestion?: string;
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Health report for configuration validation
|
|
854
|
+
*/
|
|
855
|
+
interface HealthReport {
|
|
856
|
+
valid: boolean;
|
|
857
|
+
issues: ConfigIssue[];
|
|
858
|
+
config?: unknown;
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Configuration Report (alias for HealthReport)
|
|
862
|
+
*/
|
|
863
|
+
type ConfigReport = HealthReport;
|
|
864
|
+
/**
|
|
865
|
+
* Result of the configuration initialization
|
|
866
|
+
*/
|
|
867
|
+
interface InitResult {
|
|
868
|
+
success: boolean;
|
|
869
|
+
filePath: string;
|
|
870
|
+
alreadyExists?: boolean;
|
|
871
|
+
}
|
|
872
|
+
interface NormalizedAnalyzerConfig extends Omit<AnalyzerConfig, 'cache' | 'maxWorkers' | 'outputFormat' | 'failOnSeverity' | 'maxWarnings' | 'rules'> {
|
|
873
|
+
/**
|
|
874
|
+
* Cache configuration.
|
|
875
|
+
* Guaranteed to be a full object, never boolean.
|
|
876
|
+
*/
|
|
877
|
+
cache: Required<CacheOptions>;
|
|
878
|
+
/**
|
|
879
|
+
* Maximum number of worker threads.
|
|
880
|
+
* Defaults to (CPUs - 1) or 1.
|
|
881
|
+
*/
|
|
882
|
+
maxWorkers: number;
|
|
883
|
+
/**
|
|
884
|
+
* Reporting format.
|
|
885
|
+
*/
|
|
886
|
+
outputFormat: OutputFormat;
|
|
887
|
+
/**
|
|
888
|
+
* Severity level for non-zero exit code.
|
|
889
|
+
*/
|
|
890
|
+
failOnSeverity: FailSeverity;
|
|
891
|
+
/**
|
|
892
|
+
* Max allowed warnings.
|
|
893
|
+
*/
|
|
894
|
+
maxWarnings: number;
|
|
895
|
+
/**
|
|
896
|
+
* Resolved rule configuration.
|
|
897
|
+
*/
|
|
898
|
+
rules: Record<string, RuleConfig | Severity | 'off'>;
|
|
899
|
+
}
|
|
900
|
+
interface ConfigValidationResult {
|
|
901
|
+
config?: NormalizedAnalyzerConfig;
|
|
902
|
+
report: HealthReport;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
interface Location {
|
|
906
|
+
line: number;
|
|
907
|
+
column: number;
|
|
908
|
+
}
|
|
909
|
+
type LocationMap = Record<string, Location>;
|
|
910
|
+
declare class ASTUtils {
|
|
911
|
+
/**
|
|
912
|
+
* Parses content into a TypeScript SourceFile.
|
|
913
|
+
*/
|
|
914
|
+
static parse(content: string, fileName?: string): typescript__default.SourceFile;
|
|
915
|
+
/**
|
|
916
|
+
* Generates a map of all property locations in the object.
|
|
917
|
+
* Keys are dot-notation paths (e.g. "rules.my-rule").
|
|
918
|
+
*/
|
|
919
|
+
static generateLocationMap(sourceFile: typescript__default.SourceFile): LocationMap;
|
|
920
|
+
private static getPropertyName;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
/**
|
|
924
|
+
* Global Logger Module
|
|
925
|
+
*
|
|
926
|
+
* Provides debug and performance logging capabilities with namespace filtering.
|
|
927
|
+
* Follows industry standards (ESLint, TypeScript debug patterns).
|
|
928
|
+
*/
|
|
929
|
+
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
930
|
+
type Namespace = 'discovery' | 'loader' | 'validator' | 'cache' | 'scanner' | 'parser' | 'rules' | 'workers' | 'reporter' | 'init' | 'config' | 'planner' | 'incremental' | 'dry-run' | 'engine' | 'plugin-loader' | 'env-fingerprint';
|
|
931
|
+
declare const debug: (namespace: Namespace, message: string, ...args: unknown[]) => void;
|
|
932
|
+
declare const info: (namespace: Namespace, message: string, ...args: unknown[]) => void;
|
|
933
|
+
declare const warn: (namespace: Namespace, message: string, ...args: unknown[]) => void;
|
|
934
|
+
declare const error: (namespace: Namespace, message: string, ...args: unknown[]) => void;
|
|
935
|
+
declare const time: (label: string) => void;
|
|
936
|
+
declare const timeEnd: (label: string) => number;
|
|
937
|
+
declare const timeLog: (label: string, namespace: Namespace, message?: string) => number;
|
|
938
|
+
declare const enableDebug: (level?: LogLevel, namespaces?: Namespace[] | "all") => void;
|
|
939
|
+
declare const disableDebug: () => void;
|
|
940
|
+
declare const isDebugEnabled: () => boolean;
|
|
941
|
+
|
|
942
|
+
/**
|
|
943
|
+
* Stable Serialization Utility
|
|
944
|
+
*
|
|
945
|
+
* Produces a deterministic JSON string suitable for use in cache keys and hashes.
|
|
946
|
+
*
|
|
947
|
+
* Guarantees:
|
|
948
|
+
* - Objects: keys sorted alphabetically at every depth level
|
|
949
|
+
* - Arrays: elements preserved in insertion order (NOT sorted)
|
|
950
|
+
* - undefined values in objects: omitted (same as JSON.stringify)
|
|
951
|
+
* - Date: serialized as ISO 8601 string
|
|
952
|
+
* - RegExp: serialized as its string representation (e.g. "/abc/gi")
|
|
953
|
+
* - Circular references: throws SerializationError (never silently sanitizes)
|
|
954
|
+
* - Functions: throws SerializationError
|
|
955
|
+
* - NaN / Infinity: throws SerializationError
|
|
956
|
+
*
|
|
957
|
+
* This replaces bare JSON.stringify() wherever the insertion order of object
|
|
958
|
+
* keys must not affect the resulting string (e.g. batch keys, cache keys).
|
|
959
|
+
*/
|
|
960
|
+
declare class SerializationError extends Error {
|
|
961
|
+
readonly path: string[];
|
|
962
|
+
constructor(message: string, path: string[]);
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Produces a deterministic JSON string by sorting object keys recursively.
|
|
966
|
+
*
|
|
967
|
+
* @param value - The value to serialize
|
|
968
|
+
* @param _path - Internal: tracks key path for error messages
|
|
969
|
+
* @param _seen - Internal: tracks visited objects for circular detection
|
|
970
|
+
* @returns A stable, deterministic JSON string
|
|
971
|
+
* @throws {SerializationError} on circular references, functions, or non-finite numbers
|
|
972
|
+
*/
|
|
973
|
+
declare function stableSerialize(value: unknown, _path?: string[], _seen?: WeakSet<object>): string;
|
|
974
|
+
|
|
975
|
+
export { ASTUtils, type AnalysisResult, type AnalyzerConfig, AnalyzerError, type BuiltinPreset, CACHE_VERSION, CONFIG_FILE_NAMES, type CacheOptions, type ComponentCrossRef, type ComponentFiles, type ConfigIssue, type ConfigOverride, type ConfigReport, type ConfigValidationResult, ConfigurationError, DEFAULT_CACHE_DIR, DEFAULT_EXCLUDE_PATTERNS, DEFAULT_INCLUDE_PATTERNS, Err, type FailSeverity, type HealthReport, type InfrastructureError, InfrastructureErrorCollector, type InfrastructureErrorType, type InitResult, type Location, type LocationMap, Locator, type LogLevel, type Namespace, type NgModuleInfo, type NormalizedAnalyzerConfig, Ok, type OutputFormat, PACKAGE_VERSION, ParseError, type ParserOptions, type PluginManifest, type PresetConfig, type PresetReference, type ProjectContext, type RegisterOptions, type ResolvedRule, type ResolvedRulesMap, type Result, type RuleAstRequirements, RuleCategory, type RuleConfig, type RuleConfigFull, type RuleConfigShorthand, type RuleContext, type RuleDependencyType, RuleError, RuleExecutionError, type RuleFailure, type RuleFilePatterns, type RuleListEntry, type RuleMetadata, type RulePlugin, type RuleRegistry, type RuleRegistryEntry, type RuleRegistryMap, type RuleResolutionResult, type RuleResult, type RuleSeverity, type RulesConfig, SUPPORTED_ANGULAR_VERSIONS, SerializationError, type Severity, type StyleAst, TOOL_NAME, type TelemetryConfig, type TelemetryEventBase, type TemplateAst, type WorkerFileProgress, type WorkerMessageResult, type WorkerTaskError, createInfrastructureError, debug, disableDebug, enableDebug, error, info, isDebugEnabled, stableSerialize, time, timeEnd, timeLog, warn };
|