@defai.digital/ax-cli 3.3.0 → 3.4.0
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/.ax-cli/memory.json +6 -6
- package/README.md +110 -0
- package/config/settings.yaml +6 -0
- package/dist/agent/dependency-resolver.js +2 -1
- package/dist/agent/dependency-resolver.js.map +1 -1
- package/dist/agent/llm-agent.d.ts +3 -0
- package/dist/agent/llm-agent.js +57 -8
- package/dist/agent/llm-agent.js.map +1 -1
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.d.ts +29 -0
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js +103 -0
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js.map +1 -0
- package/dist/analyzers/architecture/architecture-analyzer.d.ts +58 -0
- package/dist/analyzers/architecture/architecture-analyzer.js +276 -0
- package/dist/analyzers/architecture/architecture-analyzer.js.map +1 -0
- package/dist/analyzers/architecture/index.d.ts +12 -0
- package/dist/analyzers/architecture/index.js +14 -0
- package/dist/analyzers/architecture/index.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.d.ts +27 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.js +31 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js +57 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js +43 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.js +49 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.js.map +1 -0
- package/dist/analyzers/architecture/project-structure-scanner.d.ts +54 -0
- package/dist/analyzers/architecture/project-structure-scanner.js +200 -0
- package/dist/analyzers/architecture/project-structure-scanner.js.map +1 -0
- package/dist/analyzers/best-practices/base-rule.d.ts +45 -0
- package/dist/analyzers/best-practices/base-rule.js +45 -0
- package/dist/analyzers/best-practices/base-rule.js.map +1 -0
- package/dist/analyzers/best-practices/best-practice-validator.d.ts +35 -0
- package/dist/analyzers/best-practices/best-practice-validator.js +181 -0
- package/dist/analyzers/best-practices/best-practice-validator.js.map +1 -0
- package/dist/analyzers/best-practices/rules/index.d.ts +7 -0
- package/dist/analyzers/best-practices/rules/index.js +56 -0
- package/dist/analyzers/best-practices/rules/index.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js +41 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.d.ts +27 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.js +76 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/index.d.ts +15 -0
- package/dist/analyzers/best-practices/rules/typescript/index.js +16 -0
- package/dist/analyzers/best-practices/rules/typescript/index.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.d.ts +18 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.js +25 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.js +27 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.d.ts +18 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js +39 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js +32 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js +36 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.js +33 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js +34 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js +27 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js.map +1 -0
- package/dist/analyzers/best-practices/types.d.ts +86 -0
- package/dist/analyzers/best-practices/types.js +7 -0
- package/dist/analyzers/best-practices/types.js.map +1 -0
- package/dist/analyzers/cache/analysis-cache.d.ts +41 -0
- package/dist/analyzers/cache/analysis-cache.js +84 -0
- package/dist/analyzers/cache/analysis-cache.js.map +1 -0
- package/dist/analyzers/errors.d.ts +51 -0
- package/dist/analyzers/errors.js +79 -0
- package/dist/analyzers/errors.js.map +1 -0
- package/dist/commands/doctor.js +2 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/mcp.js +243 -0
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/setup.js +85 -28
- package/dist/commands/setup.js.map +1 -1
- package/dist/constants.d.ts +3 -0
- package/dist/constants.js +3 -0
- package/dist/constants.js.map +1 -1
- package/dist/hooks/use-input-handler.js +2 -1
- package/dist/hooks/use-input-handler.js.map +1 -1
- package/dist/llm/tools.js +86 -0
- package/dist/llm/tools.js.map +1 -1
- package/dist/mcp/client.d.ts +5 -0
- package/dist/mcp/client.js +55 -0
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/health.d.ts +11 -2
- package/dist/mcp/health.js +35 -12
- package/dist/mcp/health.js.map +1 -1
- package/dist/mcp/reconnection.d.ts +93 -0
- package/dist/mcp/reconnection.js +216 -0
- package/dist/mcp/reconnection.js.map +1 -0
- package/dist/mcp/registry.d.ts +71 -0
- package/dist/mcp/registry.js +257 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/resources.d.ts +53 -0
- package/dist/mcp/resources.js +135 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/validation.d.ts +25 -0
- package/dist/mcp/validation.js +209 -0
- package/dist/mcp/validation.js.map +1 -0
- package/dist/memory/context-generator.js +1 -2
- package/dist/memory/context-generator.js.map +1 -1
- package/dist/planner/types.d.ts +2 -2
- package/dist/schemas/index.d.ts +4 -4
- package/dist/schemas/tool-schemas.d.ts +2 -2
- package/dist/schemas/yaml-schemas.d.ts +15 -0
- package/dist/schemas/yaml-schemas.js +3 -0
- package/dist/schemas/yaml-schemas.js.map +1 -1
- package/dist/sdk/index.d.ts +138 -0
- package/dist/sdk/index.js +173 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/types.d.ts +53 -0
- package/dist/sdk/types.js +8 -0
- package/dist/sdk/types.js.map +1 -0
- package/dist/tools/analysis-tools/architecture-tool.d.ts +46 -0
- package/dist/tools/analysis-tools/architecture-tool.js +124 -0
- package/dist/tools/analysis-tools/architecture-tool.js.map +1 -0
- package/dist/tools/analysis-tools/validation-tool.d.ts +51 -0
- package/dist/tools/analysis-tools/validation-tool.js +121 -0
- package/dist/tools/analysis-tools/validation-tool.js.map +1 -0
- package/dist/tools/web-search/cache.d.ts +62 -0
- package/dist/tools/web-search/cache.js +105 -0
- package/dist/tools/web-search/cache.js.map +1 -0
- package/dist/tools/web-search/engines/brave.d.ts +16 -0
- package/dist/tools/web-search/engines/brave.js +99 -0
- package/dist/tools/web-search/engines/brave.js.map +1 -0
- package/dist/tools/web-search/engines/crates.d.ts +19 -0
- package/dist/tools/web-search/engines/crates.js +87 -0
- package/dist/tools/web-search/engines/crates.js.map +1 -0
- package/dist/tools/web-search/engines/npm.d.ts +18 -0
- package/dist/tools/web-search/engines/npm.js +86 -0
- package/dist/tools/web-search/engines/npm.js.map +1 -0
- package/dist/tools/web-search/engines/pypi.d.ts +18 -0
- package/dist/tools/web-search/engines/pypi.js +75 -0
- package/dist/tools/web-search/engines/pypi.js.map +1 -0
- package/dist/tools/web-search/engines/tavily.d.ts +17 -0
- package/dist/tools/web-search/engines/tavily.js +73 -0
- package/dist/tools/web-search/engines/tavily.js.map +1 -0
- package/dist/tools/web-search/index.d.ts +13 -0
- package/dist/tools/web-search/index.js +13 -0
- package/dist/tools/web-search/index.js.map +1 -0
- package/dist/tools/web-search/router.d.ts +36 -0
- package/dist/tools/web-search/router.js +280 -0
- package/dist/tools/web-search/router.js.map +1 -0
- package/dist/tools/web-search/types.d.ts +45 -0
- package/dist/tools/web-search/types.js +6 -0
- package/dist/tools/web-search/types.js.map +1 -0
- package/dist/tools/web-search/web-search-tool.d.ts +51 -0
- package/dist/tools/web-search/web-search-tool.js +256 -0
- package/dist/tools/web-search/web-search-tool.js.map +1 -0
- package/dist/types/analysis.d.ts +177 -0
- package/dist/types/analysis.js +8 -0
- package/dist/types/analysis.js.map +1 -0
- package/dist/ui/components/chat-interface.js +11 -1
- package/dist/ui/components/chat-interface.js.map +1 -1
- package/dist/ui/components/keyboard-hints.js +2 -2
- package/dist/ui/components/keyboard-hints.js.map +1 -1
- package/dist/ui/components/status-bar.d.ts +1 -0
- package/dist/ui/components/status-bar.js +37 -39
- package/dist/ui/components/status-bar.js.map +1 -1
- package/dist/ui/components/toast-notification.js +2 -2
- package/dist/ui/components/toast-notification.js.map +1 -1
- package/dist/ui/components/welcome-panel.d.ts +1 -0
- package/dist/ui/components/welcome-panel.js +94 -11
- package/dist/ui/components/welcome-panel.js.map +1 -1
- package/dist/utils/analysis-logger.d.ts +47 -0
- package/dist/utils/analysis-logger.js +70 -0
- package/dist/utils/analysis-logger.js.map +1 -0
- package/dist/utils/automatosx-detector.d.ts +19 -0
- package/dist/utils/automatosx-detector.js +52 -0
- package/dist/utils/automatosx-detector.js.map +1 -0
- package/dist/utils/config-loader.d.ts +3 -0
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/confirmation-service.js +1 -1
- package/dist/utils/confirmation-service.js.map +1 -1
- package/dist/utils/init-previewer.js +26 -4
- package/dist/utils/init-previewer.js.map +1 -1
- package/package.json +19 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-implicit-any.js","sourceRoot":"","sources":["../../../../../src/analyzers/best-practices/rules/typescript/no-implicit-any.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIxD,MAAM,OAAO,iBAAkB,SAAQ,kBAAkB;IAC9C,EAAE,GAAG,iBAAiB,CAAC;IACvB,IAAI,GAAG,iBAAiB,CAAC;IACzB,WAAW,GAAG,8DAA8D,CAAC;IAC7E,QAAQ,GAAa,QAAQ,CAAC;IAC9B,QAAQ,GAAiB,aAAa,CAAC;IACvC,WAAW,GAAG,KAAK,CAAC;IAE7B,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,OAAe;QAC3C,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,wDAAwD;QACxD,MAAM,eAAe,GAAG,+BAA+B,CAAC;QACxD,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;QAEjD,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;QAClE,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,UAAU,CAAC,CAAC;QAEvE,OAAO,UAAU,CAAC;IACpB,CAAC;IAEO,YAAY,CAClB,OAAe,EACf,QAAgB,EAChB,OAAe,EACf,UAAuB;QAEvB,IAAI,KAA6B,CAAC;QAClC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAChD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAExB,uBAAuB;YACvB,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACvD,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;gBAC9B,uDAAuD;gBACvD,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACzD,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;oBAEnD,UAAU,CAAC,IAAI,CACb,IAAI,CAAC,eAAe,CAClB,QAAQ,EACR,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,MAAM,EACV,cAAc,KAAK,0DAA0D,EAC7E,yBAAyB,KAAK,aAAa,CAC5C,CACF,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* No Magic Numbers Rule
|
|
3
|
+
*
|
|
4
|
+
* Use named constants instead of magic numbers
|
|
5
|
+
*/
|
|
6
|
+
import { BaseValidationRule } from '../../base-rule.js';
|
|
7
|
+
import type { Violation, Severity } from '../../../../types/analysis.js';
|
|
8
|
+
import type { RuleCategory } from '../../types.js';
|
|
9
|
+
export declare class NoMagicNumbersRule extends BaseValidationRule {
|
|
10
|
+
readonly id = "no-magic-numbers";
|
|
11
|
+
readonly name = "No Magic Numbers";
|
|
12
|
+
readonly description = "Use named constants instead of magic numbers";
|
|
13
|
+
readonly severity: Severity;
|
|
14
|
+
readonly category: RuleCategory;
|
|
15
|
+
readonly autoFixable = false;
|
|
16
|
+
check(filePath: string, content: string): Promise<Violation[]>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* No Magic Numbers Rule
|
|
3
|
+
*
|
|
4
|
+
* Use named constants instead of magic numbers
|
|
5
|
+
*/
|
|
6
|
+
import { BaseValidationRule } from '../../base-rule.js';
|
|
7
|
+
export class NoMagicNumbersRule extends BaseValidationRule {
|
|
8
|
+
id = 'no-magic-numbers';
|
|
9
|
+
name = 'No Magic Numbers';
|
|
10
|
+
description = 'Use named constants instead of magic numbers';
|
|
11
|
+
severity = 'low';
|
|
12
|
+
category = 'best-practices';
|
|
13
|
+
autoFixable = false;
|
|
14
|
+
async check(filePath, content) {
|
|
15
|
+
const violations = [];
|
|
16
|
+
// Pattern: numeric literals (excluding 0, 1, -1 which are common)
|
|
17
|
+
const magicNumberPattern = /(?<!\w)(?:[2-9]|[1-9]\d+)(?!\w|:)/g;
|
|
18
|
+
let match;
|
|
19
|
+
while ((match = magicNumberPattern.exec(content)) !== null) {
|
|
20
|
+
const number = match[0];
|
|
21
|
+
// Skip if it's part of a const declaration
|
|
22
|
+
const beforeMatch = content.substring(Math.max(0, match.index - 50), match.index);
|
|
23
|
+
if (/const\s+\w+\s*=\s*$/.test(beforeMatch)) {
|
|
24
|
+
continue; // This IS a constant declaration
|
|
25
|
+
}
|
|
26
|
+
const pos = this.getPosition(content, match.index);
|
|
27
|
+
violations.push(this.createViolation(filePath, pos.line, pos.column, `Magic number "${number}" found. Use a named constant instead.`, `const MEANINGFUL_NAME = ${number};`));
|
|
28
|
+
}
|
|
29
|
+
return violations;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=no-magic-numbers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-magic-numbers.js","sourceRoot":"","sources":["../../../../../src/analyzers/best-practices/rules/typescript/no-magic-numbers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIxD,MAAM,OAAO,kBAAmB,SAAQ,kBAAkB;IAC/C,EAAE,GAAG,kBAAkB,CAAC;IACxB,IAAI,GAAG,kBAAkB,CAAC;IAC1B,WAAW,GAAG,8CAA8C,CAAC;IAC7D,QAAQ,GAAa,KAAK,CAAC;IAC3B,QAAQ,GAAiB,gBAAgB,CAAC;IAC1C,WAAW,GAAG,KAAK,CAAC;IAE7B,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,OAAe;QAC3C,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,kEAAkE;QAClE,MAAM,kBAAkB,GAAG,oCAAoC,CAAC;QAEhE,IAAI,KAA6B,CAAC;QAClC,OAAO,CAAC,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC3D,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAExB,2CAA2C;YAC3C,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAClF,IAAI,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC5C,SAAS,CAAC,iCAAiC;YAC7C,CAAC;YAED,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAEnD,UAAU,CAAC,IAAI,CACb,IAAI,CAAC,eAAe,CAClB,QAAQ,EACR,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,MAAM,EACV,iBAAiB,MAAM,wCAAwC,EAC/D,2BAA2B,MAAM,GAAG,CACrC,CACF,CAAC;QACJ,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* No Unused Variables Rule
|
|
3
|
+
*
|
|
4
|
+
* Remove unused variables to keep code clean
|
|
5
|
+
*/
|
|
6
|
+
import { BaseValidationRule } from '../../base-rule.js';
|
|
7
|
+
import type { Violation, Severity } from '../../../../types/analysis.js';
|
|
8
|
+
import type { RuleCategory } from '../../types.js';
|
|
9
|
+
export declare class NoUnusedVarsRule extends BaseValidationRule {
|
|
10
|
+
readonly id = "no-unused-vars";
|
|
11
|
+
readonly name = "No Unused Variables";
|
|
12
|
+
readonly description = "Remove unused variables to keep code clean";
|
|
13
|
+
readonly severity: Severity;
|
|
14
|
+
readonly category: RuleCategory;
|
|
15
|
+
readonly autoFixable = true;
|
|
16
|
+
check(filePath: string, content: string): Promise<Violation[]>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* No Unused Variables Rule
|
|
3
|
+
*
|
|
4
|
+
* Remove unused variables to keep code clean
|
|
5
|
+
*/
|
|
6
|
+
import { BaseValidationRule } from '../../base-rule.js';
|
|
7
|
+
export class NoUnusedVarsRule extends BaseValidationRule {
|
|
8
|
+
id = 'no-unused-vars';
|
|
9
|
+
name = 'No Unused Variables';
|
|
10
|
+
description = 'Remove unused variables to keep code clean';
|
|
11
|
+
severity = 'medium';
|
|
12
|
+
category = 'code-quality';
|
|
13
|
+
autoFixable = true;
|
|
14
|
+
async check(filePath, content) {
|
|
15
|
+
const violations = [];
|
|
16
|
+
// Simple heuristic: Look for variable declarations and check if they're used
|
|
17
|
+
const varPattern = /(?:const|let|var)\s+(\w+)\s*=/g;
|
|
18
|
+
let match;
|
|
19
|
+
while ((match = varPattern.exec(content)) !== null) {
|
|
20
|
+
const varName = match[1];
|
|
21
|
+
// Don't check common patterns
|
|
22
|
+
if (varName.startsWith('_'))
|
|
23
|
+
continue; // Intentionally unused
|
|
24
|
+
// Count occurrences of the variable name
|
|
25
|
+
const usagePattern = new RegExp(`\\b${varName}\\b`, 'g');
|
|
26
|
+
const usages = content.match(usagePattern);
|
|
27
|
+
// If only appears once (the declaration), it's unused
|
|
28
|
+
if (usages && usages.length === 1) {
|
|
29
|
+
const pos = this.getPosition(content, match.index);
|
|
30
|
+
violations.push(this.createViolation(filePath, pos.line, pos.column, `Variable "${varName}" is declared but never used.`, `Remove the unused variable or prefix with "_" if intentionally unused`));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return violations;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=no-unused-vars.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-unused-vars.js","sourceRoot":"","sources":["../../../../../src/analyzers/best-practices/rules/typescript/no-unused-vars.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIxD,MAAM,OAAO,gBAAiB,SAAQ,kBAAkB;IAC7C,EAAE,GAAG,gBAAgB,CAAC;IACtB,IAAI,GAAG,qBAAqB,CAAC;IAC7B,WAAW,GAAG,4CAA4C,CAAC;IAC3D,QAAQ,GAAa,QAAQ,CAAC;IAC9B,QAAQ,GAAiB,cAAc,CAAC;IACxC,WAAW,GAAG,IAAI,CAAC;IAE5B,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,OAAe;QAC3C,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,6EAA6E;QAC7E,MAAM,UAAU,GAAG,gCAAgC,CAAC;QAEpD,IAAI,KAA6B,CAAC;QAClC,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACnD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAEzB,8BAA8B;YAC9B,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS,CAAC,uBAAuB;YAE9D,yCAAyC;YACzC,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,MAAM,OAAO,KAAK,EAAE,GAAG,CAAC,CAAC;YACzD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAE3C,sDAAsD;YACtD,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;gBAEnD,UAAU,CAAC,IAAI,CACb,IAAI,CAAC,eAAe,CAClB,QAAQ,EACR,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,MAAM,EACV,aAAa,OAAO,+BAA+B,EACnD,uEAAuE,CACxE,CACF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prefer Const Rule
|
|
3
|
+
*
|
|
4
|
+
* Prefer const over let when variables are not reassigned
|
|
5
|
+
*/
|
|
6
|
+
import { BaseValidationRule } from '../../base-rule.js';
|
|
7
|
+
import type { Violation, Severity } from '../../../../types/analysis.js';
|
|
8
|
+
import type { RuleCategory } from '../../types.js';
|
|
9
|
+
export declare class PreferConstRule extends BaseValidationRule {
|
|
10
|
+
readonly id = "prefer-const";
|
|
11
|
+
readonly name = "Prefer Const";
|
|
12
|
+
readonly description = "Use \"const\" instead of \"let\" when variables are not reassigned";
|
|
13
|
+
readonly severity: Severity;
|
|
14
|
+
readonly category: RuleCategory;
|
|
15
|
+
readonly autoFixable = true;
|
|
16
|
+
check(filePath: string, content: string): Promise<Violation[]>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prefer Const Rule
|
|
3
|
+
*
|
|
4
|
+
* Prefer const over let when variables are not reassigned
|
|
5
|
+
*/
|
|
6
|
+
import { BaseValidationRule } from '../../base-rule.js';
|
|
7
|
+
export class PreferConstRule extends BaseValidationRule {
|
|
8
|
+
id = 'prefer-const';
|
|
9
|
+
name = 'Prefer Const';
|
|
10
|
+
description = 'Use "const" instead of "let" when variables are not reassigned';
|
|
11
|
+
severity = 'low';
|
|
12
|
+
category = 'best-practices';
|
|
13
|
+
autoFixable = true;
|
|
14
|
+
async check(filePath, content) {
|
|
15
|
+
const violations = [];
|
|
16
|
+
// Simple heuristic: Look for 'let' declarations
|
|
17
|
+
const letPattern = /\blet\s+(\w+)\s*=/g;
|
|
18
|
+
let match;
|
|
19
|
+
while ((match = letPattern.exec(content)) !== null) {
|
|
20
|
+
const variableName = match[1];
|
|
21
|
+
const pos = this.getPosition(content, match.index);
|
|
22
|
+
// Check if variable is reassigned later (simple check)
|
|
23
|
+
const reassignmentPattern = new RegExp(`\\b${variableName}\\s*=`, 'g');
|
|
24
|
+
const reassignments = content.match(reassignmentPattern);
|
|
25
|
+
// If only one assignment (the declaration), suggest const
|
|
26
|
+
if (reassignments && reassignments.length === 1) {
|
|
27
|
+
violations.push(this.createViolation(filePath, pos.line, pos.column, `Variable "${variableName}" is never reassigned. Use "const" instead of "let".`, `Change "let ${variableName}" to "const ${variableName}"`));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return violations;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=prefer-const.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefer-const.js","sourceRoot":"","sources":["../../../../../src/analyzers/best-practices/rules/typescript/prefer-const.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIxD,MAAM,OAAO,eAAgB,SAAQ,kBAAkB;IAC5C,EAAE,GAAG,cAAc,CAAC;IACpB,IAAI,GAAG,cAAc,CAAC;IACtB,WAAW,GAAG,gEAAgE,CAAC;IAC/E,QAAQ,GAAa,KAAK,CAAC;IAC3B,QAAQ,GAAiB,gBAAgB,CAAC;IAC1C,WAAW,GAAG,IAAI,CAAC;IAE5B,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,OAAe;QAC3C,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,gDAAgD;QAChD,MAAM,UAAU,GAAG,oBAAoB,CAAC;QAExC,IAAI,KAA6B,CAAC;QAClC,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACnD,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAEnD,uDAAuD;YACvD,MAAM,mBAAmB,GAAG,IAAI,MAAM,CAAC,MAAM,YAAY,OAAO,EAAE,GAAG,CAAC,CAAC;YACvE,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAEzD,0DAA0D;YAC1D,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChD,UAAU,CAAC,IAAI,CACb,IAAI,CAAC,eAAe,CAClB,QAAQ,EACR,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,MAAM,EACV,aAAa,YAAY,sDAAsD,EAC/E,eAAe,YAAY,eAAe,YAAY,GAAG,CAC1D,CACF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prefer Readonly Rule
|
|
3
|
+
*
|
|
4
|
+
* Use readonly for properties that are not modified after initialization
|
|
5
|
+
*/
|
|
6
|
+
import { BaseValidationRule } from '../../base-rule.js';
|
|
7
|
+
import type { Violation, Severity } from '../../../../types/analysis.js';
|
|
8
|
+
import type { RuleCategory } from '../../types.js';
|
|
9
|
+
export declare class PreferReadonlyRule extends BaseValidationRule {
|
|
10
|
+
readonly id = "prefer-readonly";
|
|
11
|
+
readonly name = "Prefer Readonly";
|
|
12
|
+
readonly description = "Use readonly for properties that are not modified after initialization";
|
|
13
|
+
readonly severity: Severity;
|
|
14
|
+
readonly category: RuleCategory;
|
|
15
|
+
readonly autoFixable = true;
|
|
16
|
+
check(filePath: string, content: string): Promise<Violation[]>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prefer Readonly Rule
|
|
3
|
+
*
|
|
4
|
+
* Use readonly for properties that are not modified after initialization
|
|
5
|
+
*/
|
|
6
|
+
import { BaseValidationRule } from '../../base-rule.js';
|
|
7
|
+
export class PreferReadonlyRule extends BaseValidationRule {
|
|
8
|
+
id = 'prefer-readonly';
|
|
9
|
+
name = 'Prefer Readonly';
|
|
10
|
+
description = 'Use readonly for properties that are not modified after initialization';
|
|
11
|
+
severity = 'low';
|
|
12
|
+
category = 'type-safety';
|
|
13
|
+
autoFixable = true;
|
|
14
|
+
async check(filePath, content) {
|
|
15
|
+
const violations = [];
|
|
16
|
+
// Pattern: class properties without readonly
|
|
17
|
+
const propertyPattern = /^\s*(private|public|protected)\s+(?!readonly)(\w+):/gm;
|
|
18
|
+
let match;
|
|
19
|
+
while ((match = propertyPattern.exec(content)) !== null) {
|
|
20
|
+
const visibility = match[1];
|
|
21
|
+
const propertyName = match[2];
|
|
22
|
+
// Check if property is assigned after constructor (simple heuristic)
|
|
23
|
+
const assignmentPattern = new RegExp(`this\\.${propertyName}\\s*=`, 'g');
|
|
24
|
+
const assignments = content.match(assignmentPattern);
|
|
25
|
+
// If only assigned once (likely in constructor), suggest readonly
|
|
26
|
+
if (assignments && assignments.length === 1) {
|
|
27
|
+
const pos = this.getPosition(content, match.index);
|
|
28
|
+
violations.push(this.createViolation(filePath, pos.line, pos.column, `Property "${propertyName}" is never modified. Consider making it readonly.`, `${visibility} readonly ${propertyName}:`));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return violations;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=prefer-readonly.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefer-readonly.js","sourceRoot":"","sources":["../../../../../src/analyzers/best-practices/rules/typescript/prefer-readonly.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIxD,MAAM,OAAO,kBAAmB,SAAQ,kBAAkB;IAC/C,EAAE,GAAG,iBAAiB,CAAC;IACvB,IAAI,GAAG,iBAAiB,CAAC;IACzB,WAAW,GAAG,wEAAwE,CAAC;IACvF,QAAQ,GAAa,KAAK,CAAC;IAC3B,QAAQ,GAAiB,aAAa,CAAC;IACvC,WAAW,GAAG,IAAI,CAAC;IAE5B,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,OAAe;QAC3C,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,6CAA6C;QAC7C,MAAM,eAAe,GAAG,uDAAuD,CAAC;QAEhF,IAAI,KAA6B,CAAC;QAClC,OAAO,CAAC,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACxD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAE9B,qEAAqE;YACrE,MAAM,iBAAiB,GAAG,IAAI,MAAM,CAAC,UAAU,YAAY,OAAO,EAAE,GAAG,CAAC,CAAC;YACzE,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAErD,kEAAkE;YAClE,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;gBAEnD,UAAU,CAAC,IAAI,CACb,IAAI,CAAC,eAAe,CAClB,QAAQ,EACR,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,MAAM,EACV,aAAa,YAAY,mDAAmD,EAC5E,GAAG,UAAU,aAAa,YAAY,GAAG,CAC1C,CACF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proper Error Handling Rule
|
|
3
|
+
*
|
|
4
|
+
* Catch blocks should not be empty and should handle errors properly
|
|
5
|
+
*/
|
|
6
|
+
import { BaseValidationRule } from '../../base-rule.js';
|
|
7
|
+
import type { Violation, Severity } from '../../../../types/analysis.js';
|
|
8
|
+
import type { RuleCategory } from '../../types.js';
|
|
9
|
+
export declare class ProperErrorHandlingRule extends BaseValidationRule {
|
|
10
|
+
readonly id = "proper-error-handling";
|
|
11
|
+
readonly name = "Proper Error Handling";
|
|
12
|
+
readonly description = "Catch blocks should not be empty and should handle errors properly";
|
|
13
|
+
readonly severity: Severity;
|
|
14
|
+
readonly category: RuleCategory;
|
|
15
|
+
readonly autoFixable = false;
|
|
16
|
+
check(filePath: string, content: string): Promise<Violation[]>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proper Error Handling Rule
|
|
3
|
+
*
|
|
4
|
+
* Catch blocks should not be empty and should handle errors properly
|
|
5
|
+
*/
|
|
6
|
+
import { BaseValidationRule } from '../../base-rule.js';
|
|
7
|
+
export class ProperErrorHandlingRule extends BaseValidationRule {
|
|
8
|
+
id = 'proper-error-handling';
|
|
9
|
+
name = 'Proper Error Handling';
|
|
10
|
+
description = 'Catch blocks should not be empty and should handle errors properly';
|
|
11
|
+
severity = 'high';
|
|
12
|
+
category = 'code-quality';
|
|
13
|
+
autoFixable = false;
|
|
14
|
+
async check(filePath, content) {
|
|
15
|
+
const violations = [];
|
|
16
|
+
// Pattern: catch blocks with empty or minimal handling
|
|
17
|
+
const emptyCatchPattern = /catch\s*\([^)]*\)\s*\{\s*\}/g;
|
|
18
|
+
let match;
|
|
19
|
+
// Check for completely empty catch blocks
|
|
20
|
+
while ((match = emptyCatchPattern.exec(content)) !== null) {
|
|
21
|
+
const pos = this.getPosition(content, match.index);
|
|
22
|
+
violations.push(this.createViolation(filePath, pos.line, pos.column, 'Empty catch block. Handle or log the error properly.', 'Add error logging: console.error(error) or rethrow the error'));
|
|
23
|
+
}
|
|
24
|
+
return violations;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=proper-error-handling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proper-error-handling.js","sourceRoot":"","sources":["../../../../../src/analyzers/best-practices/rules/typescript/proper-error-handling.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIxD,MAAM,OAAO,uBAAwB,SAAQ,kBAAkB;IACpD,EAAE,GAAG,uBAAuB,CAAC;IAC7B,IAAI,GAAG,uBAAuB,CAAC;IAC/B,WAAW,GAAG,oEAAoE,CAAC;IACnF,QAAQ,GAAa,MAAM,CAAC;IAC5B,QAAQ,GAAiB,cAAc,CAAC;IACxC,WAAW,GAAG,KAAK,CAAC;IAE7B,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,OAAe;QAC3C,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,uDAAuD;QACvD,MAAM,iBAAiB,GAAG,8BAA8B,CAAC;QAEzD,IAAI,KAA6B,CAAC;QAElC,0CAA0C;QAC1C,OAAO,CAAC,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAEnD,UAAU,CAAC,IAAI,CACb,IAAI,CAAC,eAAe,CAClB,QAAQ,EACR,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,MAAM,EACV,sDAAsD,EACtD,8DAA8D,CAC/D,CACF,CAAC;QACJ,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best Practice Validator Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for validation rules and results
|
|
5
|
+
*/
|
|
6
|
+
import type { Violation, ValidationResult, BatchValidationResult } from '../../types/analysis.js';
|
|
7
|
+
import type { Severity } from '../../types/analysis.js';
|
|
8
|
+
/**
|
|
9
|
+
* Rule category classification
|
|
10
|
+
*/
|
|
11
|
+
export type RuleCategory = 'type-safety' | 'code-quality' | 'maintainability' | 'performance' | 'security' | 'best-practices';
|
|
12
|
+
/**
|
|
13
|
+
* Validation rule interface
|
|
14
|
+
* All rules must implement this interface
|
|
15
|
+
*/
|
|
16
|
+
export interface ValidationRule {
|
|
17
|
+
readonly id: string;
|
|
18
|
+
readonly name: string;
|
|
19
|
+
readonly description: string;
|
|
20
|
+
readonly severity: Severity;
|
|
21
|
+
readonly category: RuleCategory;
|
|
22
|
+
readonly autoFixable: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Check a file for violations of this rule
|
|
25
|
+
*/
|
|
26
|
+
check(filePath: string, content: string): Promise<Violation[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Generate automated fix for a violation (if autoFixable)
|
|
29
|
+
*/
|
|
30
|
+
fix?(violation: Violation, content: string): Promise<ViolationFix | null>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Automated fix for a violation
|
|
34
|
+
*/
|
|
35
|
+
export interface ViolationFix {
|
|
36
|
+
readonly description: string;
|
|
37
|
+
readonly edits: ReadonlyArray<TextEdit>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Text edit for automated fixes
|
|
41
|
+
*/
|
|
42
|
+
export interface TextEdit {
|
|
43
|
+
readonly range: TextRange;
|
|
44
|
+
readonly newText: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Text range
|
|
48
|
+
*/
|
|
49
|
+
export interface TextRange {
|
|
50
|
+
readonly start: Position;
|
|
51
|
+
readonly end: Position;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Position in text
|
|
55
|
+
*/
|
|
56
|
+
export interface Position {
|
|
57
|
+
readonly line: number;
|
|
58
|
+
readonly column: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Rule configuration
|
|
62
|
+
*/
|
|
63
|
+
export interface RuleConfig {
|
|
64
|
+
readonly enabled: boolean;
|
|
65
|
+
readonly severity?: Severity;
|
|
66
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Validation options
|
|
70
|
+
*/
|
|
71
|
+
export interface ValidationOptions {
|
|
72
|
+
readonly rules?: Readonly<Record<string, RuleConfig>>;
|
|
73
|
+
readonly language?: 'typescript' | 'javascript';
|
|
74
|
+
readonly fix?: boolean;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Rule registry interface
|
|
78
|
+
* Manages all available rules
|
|
79
|
+
*/
|
|
80
|
+
export interface RuleRegistry {
|
|
81
|
+
register(rule: ValidationRule): void;
|
|
82
|
+
get(id: string): ValidationRule | undefined;
|
|
83
|
+
getAll(): readonly ValidationRule[];
|
|
84
|
+
getByCategory(category: RuleCategory): readonly ValidationRule[];
|
|
85
|
+
}
|
|
86
|
+
export type { Violation, ValidationResult, BatchValidationResult };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/analyzers/best-practices/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analysis Cache
|
|
3
|
+
*
|
|
4
|
+
* LRU cache for analysis results with TTL and content hash validation.
|
|
5
|
+
* Prevents re-analyzing unchanged projects.
|
|
6
|
+
*/
|
|
7
|
+
export declare class AnalysisCache<T> {
|
|
8
|
+
private cache;
|
|
9
|
+
private readonly ttl;
|
|
10
|
+
private readonly maxSize;
|
|
11
|
+
/**
|
|
12
|
+
* Create new analysis cache
|
|
13
|
+
* @param ttl Time-to-live in milliseconds (default: 5 minutes)
|
|
14
|
+
* @param maxSize Maximum number of entries (default: 100)
|
|
15
|
+
*/
|
|
16
|
+
constructor(ttl?: number, maxSize?: number);
|
|
17
|
+
/**
|
|
18
|
+
* Get cached value if it exists and is valid
|
|
19
|
+
*/
|
|
20
|
+
get(key: string, hash: string): Promise<T | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Set cached value
|
|
23
|
+
*/
|
|
24
|
+
set(key: string, value: T, hash: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Check if key exists in cache (doesn't validate expiration)
|
|
27
|
+
*/
|
|
28
|
+
has(key: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Clear entire cache
|
|
31
|
+
*/
|
|
32
|
+
clear(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Get cache statistics
|
|
35
|
+
*/
|
|
36
|
+
getStats(): {
|
|
37
|
+
size: number;
|
|
38
|
+
maxSize: number;
|
|
39
|
+
ttl: number;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analysis Cache
|
|
3
|
+
*
|
|
4
|
+
* LRU cache for analysis results with TTL and content hash validation.
|
|
5
|
+
* Prevents re-analyzing unchanged projects.
|
|
6
|
+
*/
|
|
7
|
+
export class AnalysisCache {
|
|
8
|
+
cache = new Map();
|
|
9
|
+
ttl;
|
|
10
|
+
maxSize;
|
|
11
|
+
/**
|
|
12
|
+
* Create new analysis cache
|
|
13
|
+
* @param ttl Time-to-live in milliseconds (default: 5 minutes)
|
|
14
|
+
* @param maxSize Maximum number of entries (default: 100)
|
|
15
|
+
*/
|
|
16
|
+
constructor(ttl = 5 * 60 * 1000, maxSize = 100) {
|
|
17
|
+
this.ttl = ttl;
|
|
18
|
+
this.maxSize = maxSize;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get cached value if it exists and is valid
|
|
22
|
+
*/
|
|
23
|
+
async get(key, hash) {
|
|
24
|
+
const entry = this.cache.get(key);
|
|
25
|
+
if (!entry) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
// Check if expired
|
|
29
|
+
if (Date.now() - entry.timestamp > this.ttl) {
|
|
30
|
+
this.cache.delete(key);
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
// Check if content changed
|
|
34
|
+
if (entry.hash !== hash) {
|
|
35
|
+
this.cache.delete(key);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
// Move to end (LRU)
|
|
39
|
+
this.cache.delete(key);
|
|
40
|
+
this.cache.set(key, entry);
|
|
41
|
+
return entry.value;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Set cached value
|
|
45
|
+
*/
|
|
46
|
+
set(key, value, hash) {
|
|
47
|
+
// Implement LRU eviction if cache is full
|
|
48
|
+
if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
|
|
49
|
+
// Remove oldest entry (first in map)
|
|
50
|
+
const oldestKey = this.cache.keys().next().value;
|
|
51
|
+
if (oldestKey !== undefined) {
|
|
52
|
+
this.cache.delete(oldestKey);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
this.cache.set(key, {
|
|
56
|
+
value,
|
|
57
|
+
timestamp: Date.now(),
|
|
58
|
+
hash,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Check if key exists in cache (doesn't validate expiration)
|
|
63
|
+
*/
|
|
64
|
+
has(key) {
|
|
65
|
+
return this.cache.has(key);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Clear entire cache
|
|
69
|
+
*/
|
|
70
|
+
clear() {
|
|
71
|
+
this.cache.clear();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get cache statistics
|
|
75
|
+
*/
|
|
76
|
+
getStats() {
|
|
77
|
+
return {
|
|
78
|
+
size: this.cache.size,
|
|
79
|
+
maxSize: this.maxSize,
|
|
80
|
+
ttl: this.ttl,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=analysis-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis-cache.js","sourceRoot":"","sources":["../../../src/analyzers/cache/analysis-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,OAAO,aAAa;IAChB,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAChC,GAAG,CAAS;IACZ,OAAO,CAAS;IAEjC;;;;OAIG;IACH,YAAY,MAAc,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,UAAkB,GAAG;QAC5D,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,IAAY;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QAED,mBAAmB;QACnB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,2BAA2B;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE3B,OAAO,KAAK,CAAC,KAAK,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW,EAAE,KAAQ,EAAE,IAAY;QACrC,0CAA0C;QAC1C,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5D,qCAAqC;YACrC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YACjD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;YAClB,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,QAAQ;QAKN,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analysis Error Classes
|
|
3
|
+
*
|
|
4
|
+
* Structured error hierarchy for analysis operations.
|
|
5
|
+
* All errors extend from AnalysisError base class and include context information.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Base error class for all analysis errors
|
|
9
|
+
*/
|
|
10
|
+
export declare abstract class AnalysisError extends Error {
|
|
11
|
+
readonly code: string;
|
|
12
|
+
readonly context?: Readonly<Record<string, unknown>> | undefined;
|
|
13
|
+
constructor(message: string, code: string, context?: Readonly<Record<string, unknown>> | undefined);
|
|
14
|
+
/**
|
|
15
|
+
* Convert error to JSON for logging/serialization
|
|
16
|
+
*/
|
|
17
|
+
toJSON(): Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Error thrown when project structure cannot be analyzed
|
|
21
|
+
*/
|
|
22
|
+
export declare class ProjectStructureError extends AnalysisError {
|
|
23
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Error thrown when a file cannot be parsed or read
|
|
27
|
+
*/
|
|
28
|
+
export declare class FileParseError extends AnalysisError {
|
|
29
|
+
readonly filePath: string;
|
|
30
|
+
constructor(message: string, filePath: string, context?: Record<string, unknown>);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Error thrown when validation fails
|
|
34
|
+
*/
|
|
35
|
+
export declare class ValidationError extends AnalysisError {
|
|
36
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Error thrown when analysis exceeds timeout
|
|
40
|
+
*/
|
|
41
|
+
export declare class AnalysisTimeoutError extends AnalysisError {
|
|
42
|
+
readonly timeoutMs: number;
|
|
43
|
+
constructor(message: string, timeoutMs: number, context?: Record<string, unknown>);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Error thrown when pattern detection fails
|
|
47
|
+
*/
|
|
48
|
+
export declare class PatternDetectionError extends AnalysisError {
|
|
49
|
+
readonly patternName: string;
|
|
50
|
+
constructor(message: string, patternName: string, context?: Record<string, unknown>);
|
|
51
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analysis Error Classes
|
|
3
|
+
*
|
|
4
|
+
* Structured error hierarchy for analysis operations.
|
|
5
|
+
* All errors extend from AnalysisError base class and include context information.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Base error class for all analysis errors
|
|
9
|
+
*/
|
|
10
|
+
export class AnalysisError extends Error {
|
|
11
|
+
code;
|
|
12
|
+
context;
|
|
13
|
+
constructor(message, code, context) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.code = code;
|
|
16
|
+
this.context = context;
|
|
17
|
+
this.name = this.constructor.name;
|
|
18
|
+
Error.captureStackTrace(this, this.constructor);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Convert error to JSON for logging/serialization
|
|
22
|
+
*/
|
|
23
|
+
toJSON() {
|
|
24
|
+
return {
|
|
25
|
+
name: this.name,
|
|
26
|
+
message: this.message,
|
|
27
|
+
code: this.code,
|
|
28
|
+
context: this.context,
|
|
29
|
+
stack: this.stack,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Error thrown when project structure cannot be analyzed
|
|
35
|
+
*/
|
|
36
|
+
export class ProjectStructureError extends AnalysisError {
|
|
37
|
+
constructor(message, context) {
|
|
38
|
+
super(message, 'PROJECT_STRUCTURE_ERROR', context);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Error thrown when a file cannot be parsed or read
|
|
43
|
+
*/
|
|
44
|
+
export class FileParseError extends AnalysisError {
|
|
45
|
+
filePath;
|
|
46
|
+
constructor(message, filePath, context) {
|
|
47
|
+
super(message, 'FILE_PARSE_ERROR', { ...context, filePath });
|
|
48
|
+
this.filePath = filePath;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Error thrown when validation fails
|
|
53
|
+
*/
|
|
54
|
+
export class ValidationError extends AnalysisError {
|
|
55
|
+
constructor(message, context) {
|
|
56
|
+
super(message, 'VALIDATION_ERROR', context);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Error thrown when analysis exceeds timeout
|
|
61
|
+
*/
|
|
62
|
+
export class AnalysisTimeoutError extends AnalysisError {
|
|
63
|
+
timeoutMs;
|
|
64
|
+
constructor(message, timeoutMs, context) {
|
|
65
|
+
super(message, 'ANALYSIS_TIMEOUT', { ...context, timeoutMs });
|
|
66
|
+
this.timeoutMs = timeoutMs;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Error thrown when pattern detection fails
|
|
71
|
+
*/
|
|
72
|
+
export class PatternDetectionError extends AnalysisError {
|
|
73
|
+
patternName;
|
|
74
|
+
constructor(message, patternName, context) {
|
|
75
|
+
super(message, 'PATTERN_DETECTION_ERROR', { ...context, patternName });
|
|
76
|
+
this.patternName = patternName;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/analyzers/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,OAAgB,aAAc,SAAQ,KAAK;IAG7B;IACA;IAHlB,YACE,OAAe,EACC,IAAY,EACZ,OAA2C;QAE3D,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAAQ;QACZ,YAAO,GAAP,OAAO,CAAoC;QAG3D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAClC,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;IACJ,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,qBAAsB,SAAQ,aAAa;IACtD,YAAY,OAAe,EAAE,OAAiC;QAC5D,KAAK,CAAC,OAAO,EAAE,yBAAyB,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,cAAe,SAAQ,aAAa;IAG7B;IAFlB,YACE,OAAe,EACC,QAAgB,EAChC,OAAiC;QAEjC,KAAK,CAAC,OAAO,EAAE,kBAAkB,EAAE,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;QAH7C,aAAQ,GAAR,QAAQ,CAAQ;IAIlC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,aAAa;IAChD,YAAY,OAAe,EAAE,OAAiC;QAC5D,KAAK,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,oBAAqB,SAAQ,aAAa;IAGnC;IAFlB,YACE,OAAe,EACC,SAAiB,EACjC,OAAiC;QAEjC,KAAK,CAAC,OAAO,EAAE,kBAAkB,EAAE,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;QAH9C,cAAS,GAAT,SAAS,CAAQ;IAInC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,qBAAsB,SAAQ,aAAa;IAGpC;IAFlB,YACE,OAAe,EACC,WAAmB,EACnC,OAAiC;QAEjC,KAAK,CAAC,OAAO,EAAE,yBAAyB,EAAE,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;QAHvD,gBAAW,GAAX,WAAW,CAAQ;IAIrC,CAAC;CACF"}
|