@webpieces/code-rules 0.3.351 → 0.3.352
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/package.json +7 -2
- package/src/cli.d.ts +1 -1
- package/src/cli.js +27 -5
- package/src/cli.js.map +1 -1
- package/src/code-rules-app.d.ts +13 -0
- package/src/code-rules-app.js +31 -0
- package/src/code-rules-app.js.map +1 -0
- package/src/code-rules-config-table.d.ts +10 -0
- package/src/code-rules-config-table.js +31 -0
- package/src/code-rules-config-table.js.map +1 -0
- package/src/code-rules-context.d.ts +19 -0
- package/src/code-rules-context.js +28 -0
- package/src/code-rules-context.js.map +1 -0
- package/src/code-rules-engine.d.ts +67 -0
- package/src/code-rules-engine.js +156 -0
- package/src/code-rules-engine.js.map +1 -0
- package/src/code-validator.d.ts +10 -0
- package/src/code-validator.js +15 -1
- package/src/code-validator.js.map +1 -1
- package/src/rule-reporter.d.ts +15 -10
- package/src/rule-reporter.js +59 -47
- package/src/rule-reporter.js.map +1 -1
- package/src/validate-catch-error-pattern.js +9 -2
- package/src/validate-catch-error-pattern.js.map +1 -1
- package/src/validate-code.d.ts +8 -5
- package/src/validate-code.js +22 -70
- package/src/validate-code.js.map +1 -1
- package/src/validate-dtos.js +9 -2
- package/src/validate-dtos.js.map +1 -1
- package/src/validate-framework-tag.js +11 -2
- package/src/validate-framework-tag.js.map +1 -1
- package/src/validate-inject-annotation-not-needed-for-concrete-class.js +9 -2
- package/src/validate-inject-annotation-not-needed-for-concrete-class.js.map +1 -1
- package/src/validate-match-rules.d.ts +17 -11
- package/src/validate-match-rules.js +116 -120
- package/src/validate-match-rules.js.map +1 -1
- package/src/validate-modified-files.js +9 -2
- package/src/validate-modified-files.js.map +1 -1
- package/src/validate-modified-methods.js +9 -2
- package/src/validate-modified-methods.js.map +1 -1
- package/src/validate-no-any-unknown.js +9 -2
- package/src/validate-no-any-unknown.js.map +1 -1
- package/src/validate-no-destructure.js +9 -2
- package/src/validate-no-destructure.js.map +1 -1
- package/src/validate-no-direct-api-resolver.js +9 -2
- package/src/validate-no-direct-api-resolver.js.map +1 -1
- package/src/validate-no-function-outside-class.js +9 -2
- package/src/validate-no-function-outside-class.js.map +1 -1
- package/src/validate-no-implicit-any.js +9 -2
- package/src/validate-no-implicit-any.js.map +1 -1
- package/src/validate-no-inline-types.js +9 -2
- package/src/validate-no-inline-types.js.map +1 -1
- package/src/validate-no-process-exit-outside-main.js +9 -2
- package/src/validate-no-process-exit-outside-main.js.map +1 -1
- package/src/validate-no-symbol-di-tokens.js +9 -2
- package/src/validate-no-symbol-di-tokens.js.map +1 -1
- package/src/validate-no-unmanaged-exceptions.js +9 -2
- package/src/validate-no-unmanaged-exceptions.js.map +1 -1
- package/src/validate-prisma-converters.js +9 -2
- package/src/validate-prisma-converters.js.map +1 -1
- package/src/validate-return-types.js +9 -2
- package/src/validate-return-types.js.map +1 -1
- package/src/validate-role-tag.js +11 -2
- package/src/validate-role-tag.js.map +1 -1
- package/src/wp-ci.d.ts +1 -1
- package/src/wp-ci.js +20 -3
- package/src/wp-ci.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpieces/code-rules",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.352",
|
|
4
4
|
"description": "Standalone code validation rules extracted from architecture-validators, no Nx dependency required",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -20,7 +20,12 @@
|
|
|
20
20
|
"directory": "packages/tooling/code-rules"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@webpieces/rules-config": "0.3.
|
|
23
|
+
"@webpieces/rules-config": "0.3.352",
|
|
24
|
+
"@webpieces/core-context": "0.3.352",
|
|
25
|
+
"@webpieces/core-util": "0.3.352",
|
|
26
|
+
"@inversifyjs/binding-decorators": "1.1.5",
|
|
27
|
+
"inversify": "7.10.4",
|
|
28
|
+
"reflect-metadata": "0.2.2"
|
|
24
29
|
},
|
|
25
30
|
"publishConfig": {
|
|
26
31
|
"access": "public"
|
package/src/cli.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
import 'reflect-metadata';
|
package/src/cli.js
CHANGED
|
@@ -1,16 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
|
|
4
|
+
require("reflect-metadata");
|
|
5
|
+
const inversify_1 = require("inversify");
|
|
6
|
+
const binding_decorators_1 = require("@inversifyjs/binding-decorators");
|
|
5
7
|
const rules_config_1 = require("@webpieces/rules-config");
|
|
6
|
-
const
|
|
8
|
+
const code_rules_app_1 = require("./code-rules-app");
|
|
9
|
+
const code_rules_context_1 = require("./code-rules-context");
|
|
10
|
+
const code_rules_config_table_1 = require("./code-rules-config-table");
|
|
7
11
|
async function main() {
|
|
8
12
|
// webpieces-disable no-unmanaged-exceptions -- global entry point for code-rules CLI
|
|
9
13
|
try {
|
|
10
|
-
// Anchor at the repo root so `.webpieces/instruct-ai` docs
|
|
11
|
-
//
|
|
14
|
+
// Anchor at the repo root so `.webpieces/instruct-ai` docs land there, not in whatever subdir
|
|
15
|
+
// this CLI ran from; load config from there.
|
|
12
16
|
const workspaceRoot = new rules_config_1.RepoRootFinder().resolveRepoRoot(process.cwd());
|
|
13
|
-
const
|
|
17
|
+
const loaded = (0, rules_config_1.loadAndValidate)(workspaceRoot);
|
|
18
|
+
if (loaded.configPath === null) {
|
|
19
|
+
console.error('\n❌ No webpieces.config.json found at workspace root (or any ancestor).\n');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
console.log(`\n📄 Loaded config: ${loaded.configPath}`);
|
|
23
|
+
// Composition root: bind the runtime values (workspace root, each rule's config), then let
|
|
24
|
+
// inversify build the ENTIRE validator DAG when we resolve the app.
|
|
25
|
+
const container = new inversify_1.Container();
|
|
26
|
+
container.bind(code_rules_context_1.WorkspaceRoot).toConstantValue(new code_rules_context_1.WorkspaceRoot(workspaceRoot));
|
|
27
|
+
container.bind(code_rules_context_1.MatchRulesHolder).toConstantValue(new code_rules_context_1.MatchRulesHolder(loaded.matchRules));
|
|
28
|
+
for (const binding of code_rules_config_table_1.CONFIG_BINDINGS) {
|
|
29
|
+
const ConfigClass = binding[0];
|
|
30
|
+
const configured = loaded.rulesConfig[binding[1]];
|
|
31
|
+
container.bind(ConfigClass).toConstantValue(configured ?? new ConfigClass());
|
|
32
|
+
}
|
|
33
|
+
await container.load((0, binding_decorators_1.buildProviderModule)());
|
|
34
|
+
const app = container.get(code_rules_app_1.CodeRulesApp);
|
|
35
|
+
const result = await app.run();
|
|
14
36
|
process.exit(result.success ? 0 : 1);
|
|
15
37
|
}
|
|
16
38
|
catch (err) {
|
package/src/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/cli.ts"],"names":[],"mappings":";;;AACA,4BAA0B;AAC1B,yCAAsC;AACtC,wEAAsE;AACtE,0DAAiI;AAEjI,qDAAgD;AAChD,6DAAuE;AACvE,uEAA4D;AAE5D,KAAK,UAAU,IAAI;IACf,qFAAqF;IACrF,IAAI,CAAC;QACD,8FAA8F;QAC9F,6CAA6C;QAC7C,MAAM,aAAa,GAAG,IAAI,6BAAc,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1E,MAAM,MAAM,GAAG,IAAA,8BAAe,EAAC,aAAa,CAAC,CAAC;QAC9C,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC7B,OAAO,CAAC,KAAK,CAAC,2EAA2E,CAAC,CAAC;YAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QAExD,2FAA2F;QAC3F,oEAAoE;QACpE,MAAM,SAAS,GAAG,IAAI,qBAAS,EAAE,CAAC;QAClC,SAAS,CAAC,IAAI,CAAC,kCAAa,CAAC,CAAC,eAAe,CAAC,IAAI,kCAAa,CAAC,aAAa,CAAC,CAAC,CAAC;QAChF,SAAS,CAAC,IAAI,CAAC,qCAAgB,CAAC,CAAC,eAAe,CAAC,IAAI,qCAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;QAC1F,KAAK,MAAM,OAAO,IAAI,yCAAe,EAAE,CAAC;YACpC,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAA+B,CAAC;YAChF,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,eAAe,CAAC,UAAU,IAAI,IAAI,WAAW,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAA,wCAAmB,GAAE,CAAC,CAAC;QAE5C,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,6BAAY,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,IAAA,sBAAO,EAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,KAAK,YAAY,4BAAa,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC;aAAM,IAAI,GAAG,YAAY,4BAAa,EAAE,CAAC;YACtC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,KAAK,CAAC,kCAAkC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC","sourcesContent":["#!/usr/bin/env node\nimport 'reflect-metadata';\nimport { Container } from 'inversify';\nimport { buildProviderModule } from '@inversifyjs/binding-decorators';\nimport { InformAiError, RuleFailError, toError, loadAndValidate, RepoRootFinder, BaseRuleConfig } from '@webpieces/rules-config';\n\nimport { CodeRulesApp } from './code-rules-app';\nimport { WorkspaceRoot, MatchRulesHolder } from './code-rules-context';\nimport { CONFIG_BINDINGS } from './code-rules-config-table';\n\nasync function main(): Promise<void> {\n // webpieces-disable no-unmanaged-exceptions -- global entry point for code-rules CLI\n try {\n // Anchor at the repo root so `.webpieces/instruct-ai` docs land there, not in whatever subdir\n // this CLI ran from; load config from there.\n const workspaceRoot = new RepoRootFinder().resolveRepoRoot(process.cwd());\n const loaded = loadAndValidate(workspaceRoot);\n if (loaded.configPath === null) {\n console.error('\\n❌ No webpieces.config.json found at workspace root (or any ancestor).\\n');\n process.exit(1);\n }\n console.log(`\\n📄 Loaded config: ${loaded.configPath}`);\n\n // Composition root: bind the runtime values (workspace root, each rule's config), then let\n // inversify build the ENTIRE validator DAG when we resolve the app.\n const container = new Container();\n container.bind(WorkspaceRoot).toConstantValue(new WorkspaceRoot(workspaceRoot));\n container.bind(MatchRulesHolder).toConstantValue(new MatchRulesHolder(loaded.matchRules));\n for (const binding of CONFIG_BINDINGS) {\n const ConfigClass = binding[0];\n const configured = loaded.rulesConfig[binding[1]] as BaseRuleConfig | undefined;\n container.bind(ConfigClass).toConstantValue(configured ?? new ConfigClass());\n }\n await container.load(buildProviderModule());\n\n const app = container.get(CodeRulesApp);\n const result = await app.run();\n process.exit(result.success ? 0 : 1);\n } catch (err: unknown) {\n const error = toError(err);\n if (error instanceof RuleFailError) {\n console.error(error.humanMessage);\n } else if (err instanceof InformAiError) {\n console.error(error.message);\n } else {\n console.error(`[code-rules] unexpected error: ${error.message}`);\n }\n process.exit(1);\n }\n}\n\nmain();\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CodeRulesEngine } from './code-rules-engine';
|
|
2
|
+
import { ExecutorResult } from './code-validator';
|
|
3
|
+
/**
|
|
4
|
+
* The code-rules application root. `container.get(CodeRulesApp)` resolves the entire validator DAG
|
|
5
|
+
* (engine → 18 injected validators → their bound configs + shared helpers). `@DocumentDesign` marks
|
|
6
|
+
* it the top-of-DAG the DI-design analyzer roots on, so `role:app` code-rules draws its design.
|
|
7
|
+
*/
|
|
8
|
+
export declare class CodeRulesApp {
|
|
9
|
+
private readonly engine;
|
|
10
|
+
constructor(engine: CodeRulesEngine);
|
|
11
|
+
/** Run every configured code validator against the workspace root bound at bootstrap. */
|
|
12
|
+
run(): Promise<ExecutorResult>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CodeRulesApp = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const core_util_1 = require("@webpieces/core-util");
|
|
6
|
+
const core_context_1 = require("@webpieces/core-context");
|
|
7
|
+
const inversify_1 = require("inversify");
|
|
8
|
+
const code_rules_engine_1 = require("./code-rules-engine");
|
|
9
|
+
/**
|
|
10
|
+
* The code-rules application root. `container.get(CodeRulesApp)` resolves the entire validator DAG
|
|
11
|
+
* (engine → 18 injected validators → their bound configs + shared helpers). `@DocumentDesign` marks
|
|
12
|
+
* it the top-of-DAG the DI-design analyzer roots on, so `role:app` code-rules draws its design.
|
|
13
|
+
*/
|
|
14
|
+
let CodeRulesApp = class CodeRulesApp {
|
|
15
|
+
engine;
|
|
16
|
+
constructor(engine) {
|
|
17
|
+
this.engine = engine;
|
|
18
|
+
}
|
|
19
|
+
/** Run every configured code validator against the workspace root bound at bootstrap. */
|
|
20
|
+
run() {
|
|
21
|
+
return this.engine.run();
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
exports.CodeRulesApp = CodeRulesApp;
|
|
25
|
+
exports.CodeRulesApp = CodeRulesApp = tslib_1.__decorate([
|
|
26
|
+
(0, core_util_1.DocumentDesign)(),
|
|
27
|
+
(0, core_context_1.provideSingleton)(),
|
|
28
|
+
(0, inversify_1.injectable)(),
|
|
29
|
+
tslib_1.__metadata("design:paramtypes", [code_rules_engine_1.CodeRulesEngine])
|
|
30
|
+
], CodeRulesApp);
|
|
31
|
+
//# sourceMappingURL=code-rules-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-rules-app.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/code-rules-app.ts"],"names":[],"mappings":";;;;AAAA,oDAAsD;AACtD,0DAA2D;AAC3D,yCAAuC;AAEvC,2DAAsD;AAGtD;;;;GAIG;AAII,IAAM,YAAY,GAAlB,MAAM,YAAY;IACQ;IAA7B,YAA6B,MAAuB;QAAvB,WAAM,GAAN,MAAM,CAAiB;IAAG,CAAC;IAExD,yFAAyF;IACzF,GAAG;QACC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;IAC7B,CAAC;CACJ,CAAA;AAPY,oCAAY;uBAAZ,YAAY;IAHxB,IAAA,0BAAc,GAAE;IAChB,IAAA,+BAAgB,GAAE;IAClB,IAAA,sBAAU,GAAE;6CAE4B,mCAAe;GAD3C,YAAY,CAOxB","sourcesContent":["import { DocumentDesign } from '@webpieces/core-util';\nimport { provideSingleton } from '@webpieces/core-context';\nimport { injectable } from 'inversify';\n\nimport { CodeRulesEngine } from './code-rules-engine';\nimport { ExecutorResult } from './code-validator';\n\n/**\n * The code-rules application root. `container.get(CodeRulesApp)` resolves the entire validator DAG\n * (engine → 18 injected validators → their bound configs + shared helpers). `@DocumentDesign` marks\n * it the top-of-DAG the DI-design analyzer roots on, so `role:app` code-rules draws its design.\n */\n@DocumentDesign()\n@provideSingleton()\n@injectable()\nexport class CodeRulesApp {\n constructor(private readonly engine: CodeRulesEngine) {}\n\n /** Run every configured code validator against the workspace root bound at bootstrap. */\n run(): Promise<ExecutorResult> {\n return this.engine.run();\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseRuleConfig, WebpiecesRulesConfig } from '@webpieces/rules-config';
|
|
2
|
+
/** A rule config class usable as an inversify inject-by-type token. */
|
|
3
|
+
export type ConfigCtor = new () => BaseRuleConfig;
|
|
4
|
+
/**
|
|
5
|
+
* The 1:1 table of `[config class, webpieces.config.json rule key]`. The composition root iterates it
|
|
6
|
+
* to bind each rule's config into the container (`bind(ConfigClass).toConstantValue(config[key] ??
|
|
7
|
+
* new ConfigClass())`), so every `@provideSingleton` validator injects its config by type. Data only
|
|
8
|
+
* — the binding loop lives inline in the bin (an inline loop, exempt from no-function-outside-class).
|
|
9
|
+
*/
|
|
10
|
+
export declare const CONFIG_BINDINGS: ReadonlyArray<readonly [ConfigCtor, keyof WebpiecesRulesConfig]>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CONFIG_BINDINGS = void 0;
|
|
4
|
+
const rules_config_1 = require("@webpieces/rules-config");
|
|
5
|
+
/**
|
|
6
|
+
* The 1:1 table of `[config class, webpieces.config.json rule key]`. The composition root iterates it
|
|
7
|
+
* to bind each rule's config into the container (`bind(ConfigClass).toConstantValue(config[key] ??
|
|
8
|
+
* new ConfigClass())`), so every `@provideSingleton` validator injects its config by type. Data only
|
|
9
|
+
* — the binding loop lives inline in the bin (an inline loop, exempt from no-function-outside-class).
|
|
10
|
+
*/
|
|
11
|
+
exports.CONFIG_BINDINGS = [
|
|
12
|
+
[rules_config_1.MaxMethodLinesConfig, 'max-method-lines'],
|
|
13
|
+
[rules_config_1.MaxFileLinesConfig, 'max-file-lines'],
|
|
14
|
+
[rules_config_1.RequireReturnTypeConfig, 'require-return-type'],
|
|
15
|
+
[rules_config_1.NoInlineTypeLiteralsConfig, 'no-inline-type-literals'],
|
|
16
|
+
[rules_config_1.NoAnyUnknownConfig, 'no-any-unknown'],
|
|
17
|
+
[rules_config_1.NoImplicitAnyConfig, 'no-implicit-any'],
|
|
18
|
+
[rules_config_1.PrismaValidateDtosConfig, 'prisma-validate-dtos'],
|
|
19
|
+
[rules_config_1.PrismaConverterConfig, 'prisma-converter'],
|
|
20
|
+
[rules_config_1.NoDestructureConfig, 'no-destructure'],
|
|
21
|
+
[rules_config_1.CatchErrorPatternConfig, 'catch-error-pattern'],
|
|
22
|
+
[rules_config_1.NoUnmanagedExceptionsConfig, 'no-unmanaged-exceptions'],
|
|
23
|
+
[rules_config_1.AngularNoDirectApiInResolverConfig, 'angular-no-direct-api-in-resolver'],
|
|
24
|
+
[rules_config_1.NoSymbolDiTokensConfig, 'no-symbol-di-tokens'],
|
|
25
|
+
[rules_config_1.NoProcessExitOutsideMainConfig, 'no-process-exit-outside-main'],
|
|
26
|
+
[rules_config_1.NoFunctionOutsideClassConfig, 'no-function-outside-class'],
|
|
27
|
+
[rules_config_1.InjectAnnotationNotNeededForConcreteClassConfig, 'inject-annotation-not-needed-for-concrete-class'],
|
|
28
|
+
[rules_config_1.FrameworkTagConfig, 'framework-tag'],
|
|
29
|
+
[rules_config_1.RoleTagConfig, 'role-tag'],
|
|
30
|
+
];
|
|
31
|
+
//# sourceMappingURL=code-rules-config-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-rules-config-table.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/code-rules-config-table.ts"],"names":[],"mappings":";;;AAAA,0DAqBiC;AAKjC;;;;;GAKG;AACU,QAAA,eAAe,GAAqE;IAC7F,CAAC,mCAAoB,EAAE,kBAAkB,CAAC;IAC1C,CAAC,iCAAkB,EAAE,gBAAgB,CAAC;IACtC,CAAC,sCAAuB,EAAE,qBAAqB,CAAC;IAChD,CAAC,yCAA0B,EAAE,yBAAyB,CAAC;IACvD,CAAC,iCAAkB,EAAE,gBAAgB,CAAC;IACtC,CAAC,kCAAmB,EAAE,iBAAiB,CAAC;IACxC,CAAC,uCAAwB,EAAE,sBAAsB,CAAC;IAClD,CAAC,oCAAqB,EAAE,kBAAkB,CAAC;IAC3C,CAAC,kCAAmB,EAAE,gBAAgB,CAAC;IACvC,CAAC,sCAAuB,EAAE,qBAAqB,CAAC;IAChD,CAAC,0CAA2B,EAAE,yBAAyB,CAAC;IACxD,CAAC,iDAAkC,EAAE,mCAAmC,CAAC;IACzE,CAAC,qCAAsB,EAAE,qBAAqB,CAAC;IAC/C,CAAC,6CAA8B,EAAE,8BAA8B,CAAC;IAChE,CAAC,2CAA4B,EAAE,2BAA2B,CAAC;IAC3D,CAAC,8DAA+C,EAAE,iDAAiD,CAAC;IACpG,CAAC,iCAAkB,EAAE,eAAe,CAAC;IACrC,CAAC,4BAAa,EAAE,UAAU,CAAC;CAC9B,CAAC","sourcesContent":["import {\n BaseRuleConfig,\n WebpiecesRulesConfig,\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n CatchErrorPatternConfig,\n NoUnmanagedExceptionsConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoProcessExitOutsideMainConfig,\n NoFunctionOutsideClassConfig,\n InjectAnnotationNotNeededForConcreteClassConfig,\n FrameworkTagConfig,\n RoleTagConfig,\n} from '@webpieces/rules-config';\n\n/** A rule config class usable as an inversify inject-by-type token. */\nexport type ConfigCtor = new () => BaseRuleConfig;\n\n/**\n * The 1:1 table of `[config class, webpieces.config.json rule key]`. The composition root iterates it\n * to bind each rule's config into the container (`bind(ConfigClass).toConstantValue(config[key] ??\n * new ConfigClass())`), so every `@provideSingleton` validator injects its config by type. Data only\n * — the binding loop lives inline in the bin (an inline loop, exempt from no-function-outside-class).\n */\nexport const CONFIG_BINDINGS: ReadonlyArray<readonly [ConfigCtor, keyof WebpiecesRulesConfig]> = [\n [MaxMethodLinesConfig, 'max-method-lines'],\n [MaxFileLinesConfig, 'max-file-lines'],\n [RequireReturnTypeConfig, 'require-return-type'],\n [NoInlineTypeLiteralsConfig, 'no-inline-type-literals'],\n [NoAnyUnknownConfig, 'no-any-unknown'],\n [NoImplicitAnyConfig, 'no-implicit-any'],\n [PrismaValidateDtosConfig, 'prisma-validate-dtos'],\n [PrismaConverterConfig, 'prisma-converter'],\n [NoDestructureConfig, 'no-destructure'],\n [CatchErrorPatternConfig, 'catch-error-pattern'],\n [NoUnmanagedExceptionsConfig, 'no-unmanaged-exceptions'],\n [AngularNoDirectApiInResolverConfig, 'angular-no-direct-api-in-resolver'],\n [NoSymbolDiTokensConfig, 'no-symbol-di-tokens'],\n [NoProcessExitOutsideMainConfig, 'no-process-exit-outside-main'],\n [NoFunctionOutsideClassConfig, 'no-function-outside-class'],\n [InjectAnnotationNotNeededForConcreteClassConfig, 'inject-annotation-not-needed-for-concrete-class'],\n [FrameworkTagConfig, 'framework-tag'],\n [RoleTagConfig, 'role-tag'],\n];\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { MatchRuleConfig } from '@webpieces/rules-config';
|
|
2
|
+
/**
|
|
3
|
+
* The resolved repo/workspace root, bound at bootstrap (toConstantValue) and injected where the
|
|
4
|
+
* engine runs validators. A tiny holder class so it is a normal inject-by-type DI node, not a raw
|
|
5
|
+
* string threaded through constructors.
|
|
6
|
+
*/
|
|
7
|
+
export declare class WorkspaceRoot {
|
|
8
|
+
readonly path: string;
|
|
9
|
+
constructor(path: string);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The client-authored match-rules (one validator gets built per entry). Bound at bootstrap so the
|
|
13
|
+
* engine can construct a MatchRulesValidator per config without the config classes leaking into
|
|
14
|
+
* every constructor.
|
|
15
|
+
*/
|
|
16
|
+
export declare class MatchRulesHolder {
|
|
17
|
+
readonly rules: readonly MatchRuleConfig[];
|
|
18
|
+
constructor(rules: readonly MatchRuleConfig[]);
|
|
19
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MatchRulesHolder = exports.WorkspaceRoot = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* The resolved repo/workspace root, bound at bootstrap (toConstantValue) and injected where the
|
|
6
|
+
* engine runs validators. A tiny holder class so it is a normal inject-by-type DI node, not a raw
|
|
7
|
+
* string threaded through constructors.
|
|
8
|
+
*/
|
|
9
|
+
class WorkspaceRoot {
|
|
10
|
+
path;
|
|
11
|
+
constructor(path) {
|
|
12
|
+
this.path = path;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.WorkspaceRoot = WorkspaceRoot;
|
|
16
|
+
/**
|
|
17
|
+
* The client-authored match-rules (one validator gets built per entry). Bound at bootstrap so the
|
|
18
|
+
* engine can construct a MatchRulesValidator per config without the config classes leaking into
|
|
19
|
+
* every constructor.
|
|
20
|
+
*/
|
|
21
|
+
class MatchRulesHolder {
|
|
22
|
+
rules;
|
|
23
|
+
constructor(rules) {
|
|
24
|
+
this.rules = rules;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.MatchRulesHolder = MatchRulesHolder;
|
|
28
|
+
//# sourceMappingURL=code-rules-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-rules-context.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/code-rules-context.ts"],"names":[],"mappings":";;;AAEA;;;;GAIG;AACH,MAAa,aAAa;IACD;IAArB,YAAqB,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;CACxC;AAFD,sCAEC;AAED;;;;GAIG;AACH,MAAa,gBAAgB;IACJ;IAArB,YAAqB,KAAiC;QAAjC,UAAK,GAAL,KAAK,CAA4B;IAAG,CAAC;CAC7D;AAFD,4CAEC","sourcesContent":["import { MatchRuleConfig } from '@webpieces/rules-config';\n\n/**\n * The resolved repo/workspace root, bound at bootstrap (toConstantValue) and injected where the\n * engine runs validators. A tiny holder class so it is a normal inject-by-type DI node, not a raw\n * string threaded through constructors.\n */\nexport class WorkspaceRoot {\n constructor(readonly path: string) {}\n}\n\n/**\n * The client-authored match-rules (one validator gets built per entry). Bound at bootstrap so the\n * engine can construct a MatchRulesValidator per config without the config classes leaking into\n * every constructor.\n */\nexport class MatchRulesHolder {\n constructor(readonly rules: readonly MatchRuleConfig[]) {}\n}\n"]}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ExecutorResult } from './code-validator';
|
|
2
|
+
import { RuleReporter } from './rule-reporter';
|
|
3
|
+
import { WorkspaceRoot, MatchRulesHolder } from './code-rules-context';
|
|
4
|
+
import { MatchRulesChecker } from './validate-match-rules';
|
|
5
|
+
import { MaxMethodLinesValidator } from './validate-modified-methods';
|
|
6
|
+
import { MaxFileLinesValidator } from './validate-modified-files';
|
|
7
|
+
import { RequireReturnTypeValidator } from './validate-return-types';
|
|
8
|
+
import { NoInlineTypeLiteralsValidator } from './validate-no-inline-types';
|
|
9
|
+
import { NoAnyUnknownValidator } from './validate-no-any-unknown';
|
|
10
|
+
import { NoImplicitAnyValidator } from './validate-no-implicit-any';
|
|
11
|
+
import { PrismaValidateDtosValidator } from './validate-dtos';
|
|
12
|
+
import { PrismaConverterValidator } from './validate-prisma-converters';
|
|
13
|
+
import { NoDestructureValidator } from './validate-no-destructure';
|
|
14
|
+
import { CatchErrorPatternValidator } from './validate-catch-error-pattern';
|
|
15
|
+
import { NoUnmanagedExceptionsValidator } from './validate-no-unmanaged-exceptions';
|
|
16
|
+
import { NoDirectApiResolverValidator } from './validate-no-direct-api-resolver';
|
|
17
|
+
import { NoSymbolDiTokensValidator } from './validate-no-symbol-di-tokens';
|
|
18
|
+
import { NoProcessExitOutsideMainValidator } from './validate-no-process-exit-outside-main';
|
|
19
|
+
import { NoFunctionOutsideClassValidator } from './validate-no-function-outside-class';
|
|
20
|
+
import { InjectAnnotationNotNeededForConcreteClassValidator } from './validate-inject-annotation-not-needed-for-concrete-class';
|
|
21
|
+
import { FrameworkTagValidator } from './validate-framework-tag';
|
|
22
|
+
import { RoleTagValidator } from './validate-role-tag';
|
|
23
|
+
/**
|
|
24
|
+
* Owns running the code-rules suite. Every built-in validator is injected as a singleton (its config
|
|
25
|
+
* is bound in the container at bootstrap), so this class IS the code-rules DI DAG the design graph
|
|
26
|
+
* draws. The per-entry match-rules validators are the one exception — they are config-per-instance,
|
|
27
|
+
* so they are built from the injected {@link MatchRulesHolder}.
|
|
28
|
+
*/
|
|
29
|
+
export declare class CodeRulesEngine {
|
|
30
|
+
private readonly workspace;
|
|
31
|
+
private readonly reporter;
|
|
32
|
+
private readonly matchRules;
|
|
33
|
+
private readonly matchChecker;
|
|
34
|
+
private readonly maxMethodLines;
|
|
35
|
+
private readonly maxFileLines;
|
|
36
|
+
private readonly requireReturnType;
|
|
37
|
+
private readonly noInlineTypeLiterals;
|
|
38
|
+
private readonly noAnyUnknown;
|
|
39
|
+
private readonly noImplicitAny;
|
|
40
|
+
private readonly prismaValidateDtos;
|
|
41
|
+
private readonly prismaConverter;
|
|
42
|
+
private readonly noDestructure;
|
|
43
|
+
private readonly catchErrorPattern;
|
|
44
|
+
private readonly noUnmanagedExceptions;
|
|
45
|
+
private readonly noDirectApiResolver;
|
|
46
|
+
private readonly noSymbolDiTokens;
|
|
47
|
+
private readonly noProcessExitOutsideMain;
|
|
48
|
+
private readonly noFunctionOutsideClass;
|
|
49
|
+
private readonly injectAnnotationNotNeeded;
|
|
50
|
+
private readonly frameworkTag;
|
|
51
|
+
private readonly roleTag;
|
|
52
|
+
constructor(workspace: WorkspaceRoot, reporter: RuleReporter, matchRules: MatchRulesHolder, matchChecker: MatchRulesChecker, maxMethodLines: MaxMethodLinesValidator, maxFileLines: MaxFileLinesValidator, requireReturnType: RequireReturnTypeValidator, noInlineTypeLiterals: NoInlineTypeLiteralsValidator, noAnyUnknown: NoAnyUnknownValidator, noImplicitAny: NoImplicitAnyValidator, prismaValidateDtos: PrismaValidateDtosValidator, prismaConverter: PrismaConverterValidator, noDestructure: NoDestructureValidator, catchErrorPattern: CatchErrorPatternValidator, noUnmanagedExceptions: NoUnmanagedExceptionsValidator, noDirectApiResolver: NoDirectApiResolverValidator, noSymbolDiTokens: NoSymbolDiTokensValidator, noProcessExitOutsideMain: NoProcessExitOutsideMainValidator, noFunctionOutsideClass: NoFunctionOutsideClassValidator, injectAnnotationNotNeeded: InjectAnnotationNotNeededForConcreteClassValidator, frameworkTag: FrameworkTagValidator, roleTag: RoleTagValidator);
|
|
53
|
+
/** The 18 injected built-in validators, in run order. */
|
|
54
|
+
private builtIns;
|
|
55
|
+
/**
|
|
56
|
+
* Every ACTIVE run: an injected built-in validator whose `shouldRun()` is true, or an injected
|
|
57
|
+
* match-rule check per configured entry that is active. Built as {@link RuleRun} value objects
|
|
58
|
+
* (name + thunk) so NO DAG member is `new`-ed — the validators and the checker are injected.
|
|
59
|
+
*/
|
|
60
|
+
private activeRuns;
|
|
61
|
+
/**
|
|
62
|
+
* Run all configured code validators against the workspace. A validator runs only when
|
|
63
|
+
* `shouldRun()` is true (mode not OFF and no branch/epoch escape hatch). Per-run isolation lives
|
|
64
|
+
* in {@link RuleReporter} so one validator can never abort the rest.
|
|
65
|
+
*/
|
|
66
|
+
run(): Promise<ExecutorResult>;
|
|
67
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CodeRulesEngine = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const core_context_1 = require("@webpieces/core-context");
|
|
6
|
+
const inversify_1 = require("inversify");
|
|
7
|
+
const code_validator_1 = require("./code-validator");
|
|
8
|
+
const rule_reporter_1 = require("./rule-reporter");
|
|
9
|
+
const code_rules_context_1 = require("./code-rules-context");
|
|
10
|
+
const validate_match_rules_1 = require("./validate-match-rules");
|
|
11
|
+
const validate_modified_methods_1 = require("./validate-modified-methods");
|
|
12
|
+
const validate_modified_files_1 = require("./validate-modified-files");
|
|
13
|
+
const validate_return_types_1 = require("./validate-return-types");
|
|
14
|
+
const validate_no_inline_types_1 = require("./validate-no-inline-types");
|
|
15
|
+
const validate_no_any_unknown_1 = require("./validate-no-any-unknown");
|
|
16
|
+
const validate_no_implicit_any_1 = require("./validate-no-implicit-any");
|
|
17
|
+
const validate_dtos_1 = require("./validate-dtos");
|
|
18
|
+
const validate_prisma_converters_1 = require("./validate-prisma-converters");
|
|
19
|
+
const validate_no_destructure_1 = require("./validate-no-destructure");
|
|
20
|
+
const validate_catch_error_pattern_1 = require("./validate-catch-error-pattern");
|
|
21
|
+
const validate_no_unmanaged_exceptions_1 = require("./validate-no-unmanaged-exceptions");
|
|
22
|
+
const validate_no_direct_api_resolver_1 = require("./validate-no-direct-api-resolver");
|
|
23
|
+
const validate_no_symbol_di_tokens_1 = require("./validate-no-symbol-di-tokens");
|
|
24
|
+
const validate_no_process_exit_outside_main_1 = require("./validate-no-process-exit-outside-main");
|
|
25
|
+
const validate_no_function_outside_class_1 = require("./validate-no-function-outside-class");
|
|
26
|
+
const validate_inject_annotation_not_needed_for_concrete_class_1 = require("./validate-inject-annotation-not-needed-for-concrete-class");
|
|
27
|
+
const validate_framework_tag_1 = require("./validate-framework-tag");
|
|
28
|
+
const validate_role_tag_1 = require("./validate-role-tag");
|
|
29
|
+
/**
|
|
30
|
+
* Owns running the code-rules suite. Every built-in validator is injected as a singleton (its config
|
|
31
|
+
* is bound in the container at bootstrap), so this class IS the code-rules DI DAG the design graph
|
|
32
|
+
* draws. The per-entry match-rules validators are the one exception — they are config-per-instance,
|
|
33
|
+
* so they are built from the injected {@link MatchRulesHolder}.
|
|
34
|
+
*/
|
|
35
|
+
let CodeRulesEngine = class CodeRulesEngine {
|
|
36
|
+
workspace;
|
|
37
|
+
reporter;
|
|
38
|
+
matchRules;
|
|
39
|
+
matchChecker;
|
|
40
|
+
maxMethodLines;
|
|
41
|
+
maxFileLines;
|
|
42
|
+
requireReturnType;
|
|
43
|
+
noInlineTypeLiterals;
|
|
44
|
+
noAnyUnknown;
|
|
45
|
+
noImplicitAny;
|
|
46
|
+
prismaValidateDtos;
|
|
47
|
+
prismaConverter;
|
|
48
|
+
noDestructure;
|
|
49
|
+
catchErrorPattern;
|
|
50
|
+
noUnmanagedExceptions;
|
|
51
|
+
noDirectApiResolver;
|
|
52
|
+
noSymbolDiTokens;
|
|
53
|
+
noProcessExitOutsideMain;
|
|
54
|
+
noFunctionOutsideClass;
|
|
55
|
+
injectAnnotationNotNeeded;
|
|
56
|
+
frameworkTag;
|
|
57
|
+
roleTag;
|
|
58
|
+
// webpieces-disable max-lines-new-methods -- the built-in validator set is flat; each is one injected field
|
|
59
|
+
constructor(workspace, reporter, matchRules, matchChecker, maxMethodLines, maxFileLines, requireReturnType, noInlineTypeLiterals, noAnyUnknown, noImplicitAny, prismaValidateDtos, prismaConverter, noDestructure, catchErrorPattern, noUnmanagedExceptions, noDirectApiResolver, noSymbolDiTokens, noProcessExitOutsideMain, noFunctionOutsideClass, injectAnnotationNotNeeded, frameworkTag, roleTag) {
|
|
60
|
+
this.workspace = workspace;
|
|
61
|
+
this.reporter = reporter;
|
|
62
|
+
this.matchRules = matchRules;
|
|
63
|
+
this.matchChecker = matchChecker;
|
|
64
|
+
this.maxMethodLines = maxMethodLines;
|
|
65
|
+
this.maxFileLines = maxFileLines;
|
|
66
|
+
this.requireReturnType = requireReturnType;
|
|
67
|
+
this.noInlineTypeLiterals = noInlineTypeLiterals;
|
|
68
|
+
this.noAnyUnknown = noAnyUnknown;
|
|
69
|
+
this.noImplicitAny = noImplicitAny;
|
|
70
|
+
this.prismaValidateDtos = prismaValidateDtos;
|
|
71
|
+
this.prismaConverter = prismaConverter;
|
|
72
|
+
this.noDestructure = noDestructure;
|
|
73
|
+
this.catchErrorPattern = catchErrorPattern;
|
|
74
|
+
this.noUnmanagedExceptions = noUnmanagedExceptions;
|
|
75
|
+
this.noDirectApiResolver = noDirectApiResolver;
|
|
76
|
+
this.noSymbolDiTokens = noSymbolDiTokens;
|
|
77
|
+
this.noProcessExitOutsideMain = noProcessExitOutsideMain;
|
|
78
|
+
this.noFunctionOutsideClass = noFunctionOutsideClass;
|
|
79
|
+
this.injectAnnotationNotNeeded = injectAnnotationNotNeeded;
|
|
80
|
+
this.frameworkTag = frameworkTag;
|
|
81
|
+
this.roleTag = roleTag;
|
|
82
|
+
}
|
|
83
|
+
/** The 18 injected built-in validators, in run order. */
|
|
84
|
+
builtIns() {
|
|
85
|
+
return [
|
|
86
|
+
this.maxMethodLines, this.maxFileLines, this.requireReturnType, this.noInlineTypeLiterals,
|
|
87
|
+
this.noAnyUnknown, this.noImplicitAny, this.prismaValidateDtos, this.prismaConverter,
|
|
88
|
+
this.noDestructure, this.catchErrorPattern, this.noUnmanagedExceptions, this.noDirectApiResolver,
|
|
89
|
+
this.noSymbolDiTokens, this.noProcessExitOutsideMain, this.noFunctionOutsideClass,
|
|
90
|
+
this.injectAnnotationNotNeeded, this.frameworkTag, this.roleTag,
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Every ACTIVE run: an injected built-in validator whose `shouldRun()` is true, or an injected
|
|
95
|
+
* match-rule check per configured entry that is active. Built as {@link RuleRun} value objects
|
|
96
|
+
* (name + thunk) so NO DAG member is `new`-ed — the validators and the checker are injected.
|
|
97
|
+
*/
|
|
98
|
+
activeRuns(root) {
|
|
99
|
+
const runs = [];
|
|
100
|
+
for (const v of this.builtIns()) {
|
|
101
|
+
if (v.shouldRun())
|
|
102
|
+
runs.push(new code_validator_1.RuleRun(v.name, () => v.run(root)));
|
|
103
|
+
}
|
|
104
|
+
for (const mr of this.matchRules.rules) {
|
|
105
|
+
if (this.matchChecker.shouldRun(mr))
|
|
106
|
+
runs.push(new code_validator_1.RuleRun(mr.name, () => this.matchChecker.runForConfig(mr, root)));
|
|
107
|
+
}
|
|
108
|
+
return runs;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Run all configured code validators against the workspace. A validator runs only when
|
|
112
|
+
* `shouldRun()` is true (mode not OFF and no branch/epoch escape hatch). Per-run isolation lives
|
|
113
|
+
* in {@link RuleReporter} so one validator can never abort the rest.
|
|
114
|
+
*/
|
|
115
|
+
async run() {
|
|
116
|
+
const runs = this.activeRuns(this.workspace.path);
|
|
117
|
+
if (runs.length === 0) {
|
|
118
|
+
console.log('\n⏭️ Skipping all code validations (all modes: OFF)\n');
|
|
119
|
+
return { success: true };
|
|
120
|
+
}
|
|
121
|
+
console.log('\n📏 Running Code Validations\n');
|
|
122
|
+
console.log(` Active rules: ${runs.map((r) => r.name).join(', ')}`);
|
|
123
|
+
console.log('');
|
|
124
|
+
const result = await this.reporter.runValidators(runs);
|
|
125
|
+
console.log(result.success ? '\n✅ All code validations passed\n' : '\n❌ Some code validations failed\n');
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
exports.CodeRulesEngine = CodeRulesEngine;
|
|
130
|
+
exports.CodeRulesEngine = CodeRulesEngine = tslib_1.__decorate([
|
|
131
|
+
(0, core_context_1.provideSingleton)(),
|
|
132
|
+
(0, inversify_1.injectable)(),
|
|
133
|
+
tslib_1.__metadata("design:paramtypes", [code_rules_context_1.WorkspaceRoot,
|
|
134
|
+
rule_reporter_1.RuleReporter,
|
|
135
|
+
code_rules_context_1.MatchRulesHolder,
|
|
136
|
+
validate_match_rules_1.MatchRulesChecker,
|
|
137
|
+
validate_modified_methods_1.MaxMethodLinesValidator,
|
|
138
|
+
validate_modified_files_1.MaxFileLinesValidator,
|
|
139
|
+
validate_return_types_1.RequireReturnTypeValidator,
|
|
140
|
+
validate_no_inline_types_1.NoInlineTypeLiteralsValidator,
|
|
141
|
+
validate_no_any_unknown_1.NoAnyUnknownValidator,
|
|
142
|
+
validate_no_implicit_any_1.NoImplicitAnyValidator,
|
|
143
|
+
validate_dtos_1.PrismaValidateDtosValidator,
|
|
144
|
+
validate_prisma_converters_1.PrismaConverterValidator,
|
|
145
|
+
validate_no_destructure_1.NoDestructureValidator,
|
|
146
|
+
validate_catch_error_pattern_1.CatchErrorPatternValidator,
|
|
147
|
+
validate_no_unmanaged_exceptions_1.NoUnmanagedExceptionsValidator,
|
|
148
|
+
validate_no_direct_api_resolver_1.NoDirectApiResolverValidator,
|
|
149
|
+
validate_no_symbol_di_tokens_1.NoSymbolDiTokensValidator,
|
|
150
|
+
validate_no_process_exit_outside_main_1.NoProcessExitOutsideMainValidator,
|
|
151
|
+
validate_no_function_outside_class_1.NoFunctionOutsideClassValidator,
|
|
152
|
+
validate_inject_annotation_not_needed_for_concrete_class_1.InjectAnnotationNotNeededForConcreteClassValidator,
|
|
153
|
+
validate_framework_tag_1.FrameworkTagValidator,
|
|
154
|
+
validate_role_tag_1.RoleTagValidator])
|
|
155
|
+
], CodeRulesEngine);
|
|
156
|
+
//# sourceMappingURL=code-rules-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-rules-engine.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/code-rules-engine.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseRuleConfig } from '@webpieces/rules-config';\nimport { provideSingleton } from '@webpieces/core-context';\nimport { injectable } from 'inversify';\n\nimport { CodeValidator, ExecutorResult, RuleRun } from './code-validator';\nimport { RuleReporter } from './rule-reporter';\nimport { WorkspaceRoot, MatchRulesHolder } from './code-rules-context';\nimport { MatchRulesChecker } from './validate-match-rules';\nimport { MaxMethodLinesValidator } from './validate-modified-methods';\nimport { MaxFileLinesValidator } from './validate-modified-files';\nimport { RequireReturnTypeValidator } from './validate-return-types';\nimport { NoInlineTypeLiteralsValidator } from './validate-no-inline-types';\nimport { NoAnyUnknownValidator } from './validate-no-any-unknown';\nimport { NoImplicitAnyValidator } from './validate-no-implicit-any';\nimport { PrismaValidateDtosValidator } from './validate-dtos';\nimport { PrismaConverterValidator } from './validate-prisma-converters';\nimport { NoDestructureValidator } from './validate-no-destructure';\nimport { CatchErrorPatternValidator } from './validate-catch-error-pattern';\nimport { NoUnmanagedExceptionsValidator } from './validate-no-unmanaged-exceptions';\nimport { NoDirectApiResolverValidator } from './validate-no-direct-api-resolver';\nimport { NoSymbolDiTokensValidator } from './validate-no-symbol-di-tokens';\nimport { NoProcessExitOutsideMainValidator } from './validate-no-process-exit-outside-main';\nimport { NoFunctionOutsideClassValidator } from './validate-no-function-outside-class';\nimport { InjectAnnotationNotNeededForConcreteClassValidator } from './validate-inject-annotation-not-needed-for-concrete-class';\nimport { FrameworkTagValidator } from './validate-framework-tag';\nimport { RoleTagValidator } from './validate-role-tag';\n\n/**\n * Owns running the code-rules suite. Every built-in validator is injected as a singleton (its config\n * is bound in the container at bootstrap), so this class IS the code-rules DI DAG the design graph\n * draws. The per-entry match-rules validators are the one exception — they are config-per-instance,\n * so they are built from the injected {@link MatchRulesHolder}.\n */\n@provideSingleton()\n@injectable()\nexport class CodeRulesEngine {\n // webpieces-disable max-lines-new-methods -- the built-in validator set is flat; each is one injected field\n constructor(\n private readonly workspace: WorkspaceRoot,\n private readonly reporter: RuleReporter,\n private readonly matchRules: MatchRulesHolder,\n private readonly matchChecker: MatchRulesChecker,\n private readonly maxMethodLines: MaxMethodLinesValidator,\n private readonly maxFileLines: MaxFileLinesValidator,\n private readonly requireReturnType: RequireReturnTypeValidator,\n private readonly noInlineTypeLiterals: NoInlineTypeLiteralsValidator,\n private readonly noAnyUnknown: NoAnyUnknownValidator,\n private readonly noImplicitAny: NoImplicitAnyValidator,\n private readonly prismaValidateDtos: PrismaValidateDtosValidator,\n private readonly prismaConverter: PrismaConverterValidator,\n private readonly noDestructure: NoDestructureValidator,\n private readonly catchErrorPattern: CatchErrorPatternValidator,\n private readonly noUnmanagedExceptions: NoUnmanagedExceptionsValidator,\n private readonly noDirectApiResolver: NoDirectApiResolverValidator,\n private readonly noSymbolDiTokens: NoSymbolDiTokensValidator,\n private readonly noProcessExitOutsideMain: NoProcessExitOutsideMainValidator,\n private readonly noFunctionOutsideClass: NoFunctionOutsideClassValidator,\n private readonly injectAnnotationNotNeeded: InjectAnnotationNotNeededForConcreteClassValidator,\n private readonly frameworkTag: FrameworkTagValidator,\n private readonly roleTag: RoleTagValidator,\n ) {}\n\n /** The 18 injected built-in validators, in run order. */\n private builtIns(): CodeValidator<BaseRuleConfig>[] {\n return [\n this.maxMethodLines, this.maxFileLines, this.requireReturnType, this.noInlineTypeLiterals,\n this.noAnyUnknown, this.noImplicitAny, this.prismaValidateDtos, this.prismaConverter,\n this.noDestructure, this.catchErrorPattern, this.noUnmanagedExceptions, this.noDirectApiResolver,\n this.noSymbolDiTokens, this.noProcessExitOutsideMain, this.noFunctionOutsideClass,\n this.injectAnnotationNotNeeded, this.frameworkTag, this.roleTag,\n ];\n }\n\n /**\n * Every ACTIVE run: an injected built-in validator whose `shouldRun()` is true, or an injected\n * match-rule check per configured entry that is active. Built as {@link RuleRun} value objects\n * (name + thunk) so NO DAG member is `new`-ed — the validators and the checker are injected.\n */\n private activeRuns(root: string): RuleRun[] {\n const runs: RuleRun[] = [];\n for (const v of this.builtIns()) {\n if (v.shouldRun()) runs.push(new RuleRun(v.name, () => v.run(root)));\n }\n for (const mr of this.matchRules.rules) {\n if (this.matchChecker.shouldRun(mr)) runs.push(new RuleRun(mr.name, () => this.matchChecker.runForConfig(mr, root)));\n }\n return runs;\n }\n\n /**\n * Run all configured code validators against the workspace. A validator runs only when\n * `shouldRun()` is true (mode not OFF and no branch/epoch escape hatch). Per-run isolation lives\n * in {@link RuleReporter} so one validator can never abort the rest.\n */\n async run(): Promise<ExecutorResult> {\n const runs = this.activeRuns(this.workspace.path);\n if (runs.length === 0) {\n console.log('\\n⏭️ Skipping all code validations (all modes: OFF)\\n');\n return { success: true };\n }\n\n console.log('\\n📏 Running Code Validations\\n');\n console.log(` Active rules: ${runs.map((r: RuleRun) => r.name).join(', ')}`);\n console.log('');\n\n const result = await this.reporter.runValidators(runs);\n console.log(result.success ? '\\n✅ All code validations passed\\n' : '\\n❌ Some code validations failed\\n');\n return result;\n }\n}\n"]}
|
package/src/code-validator.d.ts
CHANGED
|
@@ -5,6 +5,16 @@ import { AbstractRule, BaseRuleConfig } from '@webpieces/rules-config';
|
|
|
5
5
|
export interface ExecutorResult {
|
|
6
6
|
success: boolean;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* One named unit of work for {@link RuleReporter} — a validator (or a per-entry match-rule) paired
|
|
10
|
+
* with a thunk that runs it. A value object (not a DAG service), so the engine can build the run list
|
|
11
|
+
* from its injected validators + checker WITHOUT `new`-ing any DAG member.
|
|
12
|
+
*/
|
|
13
|
+
export declare class RuleRun {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly run: () => Promise<ExecutorResult>;
|
|
16
|
+
constructor(name: string, run: () => Promise<ExecutorResult>);
|
|
17
|
+
}
|
|
8
18
|
/**
|
|
9
19
|
* Base class for every code-rules validator.
|
|
10
20
|
*
|
package/src/code-validator.js
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CodeValidator = void 0;
|
|
3
|
+
exports.CodeValidator = exports.RuleRun = void 0;
|
|
4
4
|
const rules_config_1 = require("@webpieces/rules-config");
|
|
5
|
+
/**
|
|
6
|
+
* One named unit of work for {@link RuleReporter} — a validator (or a per-entry match-rule) paired
|
|
7
|
+
* with a thunk that runs it. A value object (not a DAG service), so the engine can build the run list
|
|
8
|
+
* from its injected validators + checker WITHOUT `new`-ing any DAG member.
|
|
9
|
+
*/
|
|
10
|
+
class RuleRun {
|
|
11
|
+
name;
|
|
12
|
+
run;
|
|
13
|
+
constructor(name, run) {
|
|
14
|
+
this.name = name;
|
|
15
|
+
this.run = run;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.RuleRun = RuleRun;
|
|
5
19
|
/**
|
|
6
20
|
* Base class for every code-rules validator.
|
|
7
21
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-validator.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/code-validator.ts"],"names":[],"mappings":";;;AAAA,0DAAuE;AASvE;;;;;;;GAOG;AACH,MAAsB,aAAwC,SAAQ,2BAAe;CAEpF;AAFD,sCAEC","sourcesContent":["import { AbstractRule, BaseRuleConfig } from '@webpieces/rules-config';\n\n/**\n * Result of running a single code validator.\n */\nexport interface ExecutorResult {\n success: boolean;\n}\n\n/**\n * Base class for every code-rules validator.\n *\n * Extends the shared {@link AbstractRule} (which owns `name` + the on/off + escape-hatch\n * decision in `shouldRun()`) and adds the code-rules execution surface: `run(workspaceRoot)`.\n * Each validator is constructed with its typed `*Config` from `@webpieces/rules-config`, so\n * the config classes are genuinely consumed (find-usages / rename work across packages).\n */\nexport abstract class CodeValidator<C extends BaseRuleConfig> extends AbstractRule<C> {\n abstract run(workspaceRoot: string): Promise<ExecutorResult>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"code-validator.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/code-validator.ts"],"names":[],"mappings":";;;AAAA,0DAAuE;AASvE;;;;GAIG;AACH,MAAa,OAAO;IAEH;IACA;IAFb,YACa,IAAY,EACZ,GAAkC;QADlC,SAAI,GAAJ,IAAI,CAAQ;QACZ,QAAG,GAAH,GAAG,CAA+B;IAC5C,CAAC;CACP;AALD,0BAKC;AAED;;;;;;;GAOG;AACH,MAAsB,aAAwC,SAAQ,2BAAe;CAEpF;AAFD,sCAEC","sourcesContent":["import { AbstractRule, BaseRuleConfig } from '@webpieces/rules-config';\n\n/**\n * Result of running a single code validator.\n */\nexport interface ExecutorResult {\n success: boolean;\n}\n\n/**\n * One named unit of work for {@link RuleReporter} — a validator (or a per-entry match-rule) paired\n * with a thunk that runs it. A value object (not a DAG service), so the engine can build the run list\n * from its injected validators + checker WITHOUT `new`-ing any DAG member.\n */\nexport class RuleRun {\n constructor(\n readonly name: string,\n readonly run: () => Promise<ExecutorResult>,\n ) {}\n}\n\n/**\n * Base class for every code-rules validator.\n *\n * Extends the shared {@link AbstractRule} (which owns `name` + the on/off + escape-hatch\n * decision in `shouldRun()`) and adds the code-rules execution surface: `run(workspaceRoot)`.\n * Each validator is constructed with its typed `*Config` from `@webpieces/rules-config`, so\n * the config classes are genuinely consumed (find-usages / rename work across packages).\n */\nexport abstract class CodeValidator<C extends BaseRuleConfig> extends AbstractRule<C> {\n abstract run(workspaceRoot: string): Promise<ExecutorResult>;\n}\n"]}
|
package/src/rule-reporter.d.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CodeValidator, ExecutorResult } from './code-validator';
|
|
1
|
+
import { RuleRun, ExecutorResult } from './code-validator';
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
5
|
-
* (an expected failure) OR a plain `Error` (a bug) — is caught, reported, and marks the run failed,
|
|
6
|
-
* but the remaining validators STILL run. One validator can no longer abort the whole CI run (the
|
|
7
|
-
* previous raw loop had no per-validator try/catch, so a single bug aborted everything).
|
|
8
|
-
*
|
|
9
|
-
* Back-compatible: validators that still `console.error(...)` + `return { success: false }` keep
|
|
10
|
-
* working; their `false` result flips the aggregate exactly as before.
|
|
3
|
+
* Runs the active validators with per-validator isolation and prints failures for humans/CI.
|
|
11
4
|
*/
|
|
12
|
-
export declare
|
|
5
|
+
export declare class RuleReporter {
|
|
6
|
+
/**
|
|
7
|
+
* Run every {@link RuleRun} with per-run isolation: a run that throws — a `RuleFailError` (an
|
|
8
|
+
* expected failure) OR a plain `Error` (a bug) — is caught, reported, and marks the whole run
|
|
9
|
+
* failed, but the remaining runs STILL execute. One validator can no longer abort the CI run.
|
|
10
|
+
*
|
|
11
|
+
* Back-compatible: runs that still `console.error(...)` + `return { success: false }` keep
|
|
12
|
+
* working; their `false` result flips the aggregate exactly as before.
|
|
13
|
+
*/
|
|
14
|
+
runValidators(runs: readonly RuleRun[]): Promise<ExecutorResult>;
|
|
15
|
+
private reportRuleFail;
|
|
16
|
+
private reportCrash;
|
|
17
|
+
}
|