@webpieces/nx-webpieces-rules 0.4.868 → 0.4.870
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 -7
- package/src/lib/di-graph/runtime-client-bindings.d.ts +13 -3
- package/src/lib/di-graph/runtime-client-bindings.js +53 -25
- package/src/lib/di-graph/runtime-client-bindings.js.map +1 -1
- package/src/lib/di-graph/token-resolver.js +0 -14
- package/src/lib/di-graph/token-resolver.js.map +1 -1
- package/src/lib/runtime-wiring/assembler.js +3 -3
- package/src/lib/runtime-wiring/assembler.js.map +1 -1
- package/src/lib/runtime-wiring/canonical-clients.d.ts +2 -0
- package/src/lib/runtime-wiring/canonical-clients.js +12 -6
- package/src/lib/runtime-wiring/canonical-clients.js.map +1 -1
- package/src/lib/runtime-wiring/codec.d.ts +1 -0
- package/src/lib/runtime-wiring/codec.js +10 -3
- package/src/lib/runtime-wiring/codec.js.map +1 -1
- package/src/lib/runtime-wiring/declaration.d.ts +3 -3
- package/src/lib/runtime-wiring/declaration.js +5 -5
- package/src/lib/runtime-wiring/declaration.js.map +1 -1
- package/src/lib/runtime-wiring/prepared-targets.js +4 -4
- package/src/lib/runtime-wiring/prepared-targets.js.map +1 -1
- package/src/lib/runtime-wiring/source-extractor.d.ts +14 -3
- package/src/lib/runtime-wiring/source-extractor.js +52 -41
- package/src/lib/runtime-wiring/source-extractor.js.map +1 -1
- package/src/lib/runtime-wiring/source-types.js +1 -1
- package/src/lib/runtime-wiring/source-types.js.map +1 -1
- package/src/lib/runtime-wiring/wiring-format.d.ts +9 -7
- package/src/lib/runtime-wiring/wiring-format.js +52 -56
- package/src/lib/runtime-wiring/wiring-format.js.map +1 -1
- package/src/rule-help.js +2 -2
- package/src/rule-help.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-types.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/runtime-wiring/source-types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"source-types.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/runtime-wiring/source-types.ts"],"names":[],"mappings":"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","sourcesContent":["import * as ts from 'typescript';\n\nexport type WiringKind = 'app' | 'wiring' | 'binding' | 'routing';\n\n/** Identity comes from resolved framework declarations, including aliases and inherited roles. */\nexport class WiringSourceTypes {\n constructor(private readonly checker: ts.TypeChecker) {}\n\n declaration(node: ts.Node): ts.Declaration | undefined {\n let symbol = this.checker.getSymbolAtLocation(node);\n if (symbol !== undefined && (symbol.flags & ts.SymbolFlags.Alias) !== 0)\n symbol = this.checker.getAliasedSymbol(symbol);\n return symbol?.valueDeclaration ?? symbol?.declarations?.[0];\n }\n\n kind(node: ts.ClassDeclaration | ts.Expression): WiringKind | undefined {\n const declaration = ts.isClassDeclaration(node) ? node : this.declaration(node);\n if (declaration === undefined) return undefined;\n return this.role(declaration, new Set<ts.Declaration>());\n }\n\n isFramework(node: ts.Node, name: string): boolean {\n const declaration = this.declaration(node);\n if (declaration === undefined || (!ts.isClassDeclaration(declaration) && !ts.isInterfaceDeclaration(declaration))) return false;\n return declaration.name?.text === name && /(?:\\/packages\\/(?:http|cloud)\\/|\\/node_modules\\/@webpieces\\/)(?:http-routing|http-client-node|http-client-browser|http-client-core|cloudtasks-client)\\//.test(declaration.getSourceFile().fileName.replace(/\\\\/g, '/'));\n }\n\n method(declaration: ts.ClassDeclaration, name: string): ts.MethodDeclaration | undefined {\n const property = this.checker.getTypeAtLocation(declaration).getProperty(name);\n const method = property?.valueDeclaration;\n return method !== undefined && ts.isMethodDeclaration(method) ? method : undefined;\n }\n\n isPolicy(node: ts.Expression): boolean {\n const symbol = this.checker.getTypeAtLocation(node).getSymbol();\n const declaration = symbol?.valueDeclaration;\n return declaration !== undefined && ts.isClassDeclaration(declaration) &&\n declaration.name !== undefined && this.isFramework(declaration.name, 'WiringPolicy');\n }\n\n private role(declaration: ts.Declaration, seen: Set<ts.Declaration>): WiringKind | undefined {\n if (seen.has(declaration)) return undefined;\n seen.add(declaration);\n if (!ts.isClassDeclaration(declaration) && !ts.isInterfaceDeclaration(declaration))\n return undefined;\n const name = declaration.name?.text;\n const file = declaration.getSourceFile().fileName.replace(/\\\\/g, '/');\n const framework = /(?:\\/packages\\/http\\/|\\/node_modules\\/@webpieces\\/)(?:http-routing|http-client-browser|http-client-core)\\/.*Wiring\\.(?:d\\.)?ts$/.test(file);\n if (framework) {\n if (name === 'AppWiring') return 'app';\n if (name === 'Wiring') return 'wiring';\n if (name === 'BindModule') return 'binding';\n if (name === 'RouteModule') return 'routing';\n }\n const roles: WiringKind[] = [];\n for (const clause of declaration.heritageClauses ?? []) {\n for (const type of clause.types) {\n const parent = this.declaration(type.expression);\n if (parent === undefined) continue;\n const role = this.role(parent, seen);\n if (role !== undefined) roles.push(role);\n }\n }\n return roles.includes('app') ? 'app' : roles[0];\n }\n}\n"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
/**
|
|
3
3
|
* One canonical-file grammar. Each owner's src/wiring.ts holds its Wiring/AppWiring class AND the
|
|
4
|
-
*
|
|
5
|
-
* may read imports; format
|
|
4
|
+
* BindModule/RouteModule classes it selects, with their actual registrations. A library owner's
|
|
5
|
+
* canonical wiring.ts may export only BindModules. Symbol resolution may read imports; format
|
|
6
|
+
* checking never does.
|
|
6
7
|
*/
|
|
7
8
|
export declare class WiringFormat {
|
|
8
9
|
private readonly checker;
|
|
@@ -13,16 +14,17 @@ export declare class WiringFormat {
|
|
|
13
14
|
assert(problems: readonly string[]): void;
|
|
14
15
|
private classProblems;
|
|
15
16
|
private arrayProblems;
|
|
16
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Proven through the resolved declaration: a selected module lives in THIS file; a BindModule an
|
|
19
|
+
* AppWiring selects may instead live in a library owner's canonical wiring.ts, and a library
|
|
20
|
+
* Wiring always does. The extractor additionally proves that file is the owner's src/wiring.ts.
|
|
21
|
+
*/
|
|
17
22
|
private placementProblems;
|
|
18
23
|
private prepared;
|
|
19
24
|
private configureProblems;
|
|
20
25
|
private registration;
|
|
21
|
-
/** Every argument of every call in a registration chain
|
|
26
|
+
/** Every argument of every call in a registration chain. */
|
|
22
27
|
private registrationArguments;
|
|
23
|
-
/** `X.load`, `new X(prepared).load` or `createX(prepared).load`: an explicit, opaque module load. */
|
|
24
|
-
private moduleReceiver;
|
|
25
|
-
private clientBinder;
|
|
26
28
|
/** Returns the first non-declarative node inside a registration argument, or undefined. */
|
|
27
29
|
private offending;
|
|
28
30
|
private firstOffending;
|
|
@@ -9,10 +9,16 @@ const source_types_1 = require("./source-types");
|
|
|
9
9
|
const canonical_clients_1 = require("./canonical-clients");
|
|
10
10
|
const WEBPIECES_SDK = /(?:\/packages\/(?:http|cloud)\/|\/node_modules\/@webpieces\/)(?:http-routing|http-client-node|http-client-browser|http-client-core|cloudtasks-client)\//;
|
|
11
11
|
const INVERSIFY = /\/node_modules\/(?:@inversifyjs\/|inversify\/)/;
|
|
12
|
-
/**
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Methods that START a registration on the host's binder or router: a DI bind, a client created and
|
|
14
|
+
* bound, a vendor implementation bound to its external contract, a browser provider recipe, a route
|
|
15
|
+
* or a filter.
|
|
16
|
+
*/
|
|
17
|
+
const REGISTRATION_ROOTS = ['bind', 'createRpcClientAndBind', 'createPubSubClientAndBind', 'bindExternal', 'provide', 'addRoutes', 'addFilter'];
|
|
18
|
+
/** Removed authoring shapes; their presence means an old wrapper, helper or an anonymous module survived. */
|
|
19
|
+
const LEGACY_TOPOLOGY = /\b(?:rpcTarget|RpcTarget|ContainerModule|ServerWiring|ServerWiringOptions|BrowserWiring|getRuntimeWiring|RuntimeClients|RuntimeTaskClients|provideRpcClient|ExternalContractUse|BrowserBindings|BindingModule)\b/;
|
|
20
|
+
/** Getters renamed with BindingModule -> BindModule. */
|
|
21
|
+
const RENAMED_GETTERS = { getBindingModules: 'getBindModules', getRoutingModules: 'getRouteModules' };
|
|
16
22
|
/** Environment discovery belongs in prepared configuration, never in a registration argument. */
|
|
17
23
|
const ENVIRONMENT = new Set(['process', 'window', 'document', 'localStorage', 'sessionStorage', 'navigator', 'location', 'globalThis']);
|
|
18
24
|
/** The one canonical file being checked, its owner directory and where problems go. */
|
|
@@ -28,8 +34,9 @@ class CanonicalFile {
|
|
|
28
34
|
}
|
|
29
35
|
/**
|
|
30
36
|
* One canonical-file grammar. Each owner's src/wiring.ts holds its Wiring/AppWiring class AND the
|
|
31
|
-
*
|
|
32
|
-
* may read imports; format
|
|
37
|
+
* BindModule/RouteModule classes it selects, with their actual registrations. A library owner's
|
|
38
|
+
* canonical wiring.ts may export only BindModules. Symbol resolution may read imports; format
|
|
39
|
+
* checking never does.
|
|
33
40
|
*/
|
|
34
41
|
class WiringFormat {
|
|
35
42
|
checker;
|
|
@@ -51,7 +58,7 @@ class WiringFormat {
|
|
|
51
58
|
const scope = new CanonicalFile(file, path.dirname(path.dirname(path.resolve(file.fileName))), report);
|
|
52
59
|
const lines = file.text.trimEnd().split('\n').length;
|
|
53
60
|
if (lines > this.maxLines)
|
|
54
|
-
report(file, `wiring.ts has ${lines} lines, above maxLines ${this.maxLines}. Keep every
|
|
61
|
+
report(file, `wiring.ts has ${lines} lines, above maxLines ${this.maxLines}. Keep every BindModule/RouteModule and its registrations here beside the Wiring class; shorten the file by moving configuration building, translations, environment discovery and initializer or factory bodies into imported implementations, or give a cohesive group its own library owner with its own wiring.ts.`);
|
|
55
62
|
for (const statement of file.statements) {
|
|
56
63
|
if (ts.isImportDeclaration(statement) || ts.isExportDeclaration(statement))
|
|
57
64
|
continue;
|
|
@@ -61,7 +68,9 @@ class WiringFormat {
|
|
|
61
68
|
}
|
|
62
69
|
const kind = this.types.kind(statement);
|
|
63
70
|
if (kind === undefined) {
|
|
64
|
-
report(statement,
|
|
71
|
+
report(statement, LEGACY_TOPOLOGY.test(statement.getText())
|
|
72
|
+
? 'Removed authoring shape (BindingModule, ExternalContractUse, RuntimeClients, provideRpcClient, BrowserBindings); implement BindModule and register through the binder.'
|
|
73
|
+
: 'Implement the framework Wiring, AppWiring, BindModule or RouteModule contract.');
|
|
65
74
|
continue;
|
|
66
75
|
}
|
|
67
76
|
this.classProblems(statement, kind, scope);
|
|
@@ -72,7 +81,7 @@ class WiringFormat {
|
|
|
72
81
|
if (problems.length === 0)
|
|
73
82
|
return;
|
|
74
83
|
throw new rules_config_1.RuleFailError('wiring-format', problems.join('\n'), undefined, undefined, [
|
|
75
|
-
new rules_config_1.Option("Declare each owner's Wiring/AppWiring class together with its named
|
|
84
|
+
new rules_config_1.Option("Declare each owner's Wiring/AppWiring class together with its named BindModule/RouteModule classes and their registrations in its src/wiring.ts, selected by literal getters (getBindModules/getRouteModules/getWirings); an app may select a BindModule declared in a library owner's canonical src/wiring.ts. Register through the binder (binder.bind, binder.createRpcClientAndBind, binder.createPubSubClientAndBind, binder.bindExternal, browser binder.provide) and the router. Keep configuration building, environment discovery and initializer/factory bodies in imported implementations, and keep named WiringPolicy conditions explicit.", true),
|
|
76
85
|
]);
|
|
77
86
|
}
|
|
78
87
|
classProblems(declaration, kind, scope) {
|
|
@@ -88,11 +97,14 @@ class WiringFormat {
|
|
|
88
97
|
continue;
|
|
89
98
|
}
|
|
90
99
|
const name = member.name.getText();
|
|
91
|
-
if (
|
|
92
|
-
|
|
100
|
+
if (Object.hasOwn(RENAMED_GETTERS, name)) {
|
|
101
|
+
report(member, `${name} was renamed to ${RENAMED_GETTERS[name]}.`);
|
|
102
|
+
}
|
|
103
|
+
else if (['getBindModules', 'getRouteModules', 'getWirings'].includes(name)) {
|
|
104
|
+
const expected = name === 'getWirings' ? 'wiring' : name === 'getBindModules' ? 'binding' : 'routing';
|
|
93
105
|
if (name === 'getWirings' && kind !== 'app')
|
|
94
106
|
report(member, 'Only AppWiring can declare getWirings; libraries cannot compose libraries.');
|
|
95
|
-
this.arrayProblems(member, expected, scope);
|
|
107
|
+
this.arrayProblems(member, expected, kind, scope);
|
|
96
108
|
}
|
|
97
109
|
else if (name === 'configure' && ['binding', 'routing'].includes(kind)) {
|
|
98
110
|
for (const statement of member.body?.statements ?? [])
|
|
@@ -107,11 +119,14 @@ class WiringFormat {
|
|
|
107
119
|
report(declaration, `configure is inherited from ${configure.getSourceFile().fileName}; declare this module's registrations in its own configure here in wiring.ts.`);
|
|
108
120
|
}
|
|
109
121
|
if (kind === 'app' || kind === 'wiring') {
|
|
110
|
-
|
|
122
|
+
// getRouteModules is Node-only (its Wiring type requires it); the browser has no route channel.
|
|
123
|
+
const names = ['getBindModules', 'getRouteModules', ...(kind === 'app' ? ['getWirings'] : [])];
|
|
111
124
|
for (const name of names) {
|
|
112
125
|
const method = this.types.method(declaration, name);
|
|
113
|
-
if (method === undefined)
|
|
114
|
-
|
|
126
|
+
if (method === undefined) {
|
|
127
|
+
if (name !== 'getRouteModules')
|
|
128
|
+
report(declaration, `Missing ${name} literal array getter.`);
|
|
129
|
+
}
|
|
115
130
|
else if (method.getSourceFile() !== scope.file)
|
|
116
131
|
report(declaration, `${name} is inherited from ${method.getSourceFile().fileName}; declare the selection getter on this class in wiring.ts.`);
|
|
117
132
|
}
|
|
@@ -119,7 +134,7 @@ class WiringFormat {
|
|
|
119
134
|
report(declaration, 'A library Wiring must not inherit getWirings.');
|
|
120
135
|
}
|
|
121
136
|
}
|
|
122
|
-
arrayProblems(method, expected, scope) {
|
|
137
|
+
arrayProblems(method, expected, ownerKind, scope) {
|
|
123
138
|
const report = scope.report;
|
|
124
139
|
const statements = method.body?.statements;
|
|
125
140
|
const returned = statements?.length === 1 && ts.isReturnStatement(statements[0]) ? statements[0].expression : undefined;
|
|
@@ -132,25 +147,33 @@ class WiringFormat {
|
|
|
132
147
|
report(element, `Select a named framework ${expected} instance; nested arrays and AppWiring children are forbidden.`);
|
|
133
148
|
continue;
|
|
134
149
|
}
|
|
135
|
-
this.placementProblems(element.expression, expected, scope);
|
|
150
|
+
this.placementProblems(element.expression, expected, ownerKind, scope);
|
|
136
151
|
for (const argument of element.arguments ?? []) {
|
|
137
152
|
if (!this.prepared(argument))
|
|
138
153
|
report(argument, 'Pass prepared inputs or a named WiringPolicy; no callbacks, topology wrappers or computed setup.');
|
|
139
154
|
}
|
|
140
155
|
}
|
|
141
156
|
}
|
|
142
|
-
/**
|
|
143
|
-
|
|
157
|
+
/**
|
|
158
|
+
* Proven through the resolved declaration: a selected module lives in THIS file; a BindModule an
|
|
159
|
+
* AppWiring selects may instead live in a library owner's canonical wiring.ts, and a library
|
|
160
|
+
* Wiring always does. The extractor additionally proves that file is the owner's src/wiring.ts.
|
|
161
|
+
*/
|
|
162
|
+
placementProblems(selected, expected, ownerKind, scope) {
|
|
144
163
|
const declared = this.types.declaration(selected)?.getSourceFile();
|
|
145
164
|
const where = declared === undefined ? 'an unresolved file' : declared.fileName;
|
|
165
|
+
const canonical = declared !== undefined && /(?:^|[\\/])wiring\.(?:d\.)?ts$/.test(declared.fileName);
|
|
146
166
|
if (expected !== 'wiring') {
|
|
147
167
|
if (declared === scope.file)
|
|
148
168
|
return;
|
|
149
|
-
|
|
150
|
-
|
|
169
|
+
if (expected === 'binding' && ownerKind === 'app' && canonical)
|
|
170
|
+
return;
|
|
171
|
+
const role = expected === 'binding' ? 'BindModule' : 'RouteModule';
|
|
172
|
+
const library = expected === 'binding' && ownerKind === 'app' ? ", or in its library owner's canonical src/wiring.ts" : '';
|
|
173
|
+
scope.report(selected, `${selected.getText()} is declared in ${where}; declare this ${role} class, with its registrations, here in wiring.ts beside the Wiring class that selects it${library}.`);
|
|
151
174
|
return;
|
|
152
175
|
}
|
|
153
|
-
if (
|
|
176
|
+
if (canonical)
|
|
154
177
|
return;
|
|
155
178
|
scope.report(selected, `Library Wiring ${selected.getText()} is declared in ${where}; select a Wiring declared in its library's canonical src/wiring.ts.`);
|
|
156
179
|
}
|
|
@@ -167,12 +190,6 @@ class WiringFormat {
|
|
|
167
190
|
}
|
|
168
191
|
configureProblems(statement, scope) {
|
|
169
192
|
const report = scope.report;
|
|
170
|
-
if (ts.isVariableStatement(statement)) {
|
|
171
|
-
const declarations = statement.declarationList.declarations;
|
|
172
|
-
const initializer = declarations.length === 1 ? declarations[0].initializer : undefined;
|
|
173
|
-
if ((statement.declarationList.flags & ts.NodeFlags.Const) !== 0 && initializer !== undefined && this.clientBinder(initializer))
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
193
|
if (ts.isIfStatement(statement) && ts.isPropertyAccessExpression(statement.expression) && statement.expression.name.text === 'enabled' && this.types.isPolicy(statement.expression.expression) && statement.elseStatement === undefined) {
|
|
177
194
|
const body = ts.isBlock(statement.thenStatement) ? statement.thenStatement.statements : [statement.thenStatement];
|
|
178
195
|
for (const child of body)
|
|
@@ -182,15 +199,15 @@ class WiringFormat {
|
|
|
182
199
|
const written = ts.isExpressionStatement(statement) || ts.isReturnStatement(statement) ? statement.expression : undefined;
|
|
183
200
|
const expression = written !== undefined && ts.isAwaitExpression(written) ? written.expression : written;
|
|
184
201
|
if (expression === undefined || (!ts.isCallExpression(expression) && !ts.isNewExpression(expression))) {
|
|
185
|
-
report(statement, 'configure contains only registration declarations (DI binds,
|
|
202
|
+
report(statement, 'configure contains only registration declarations (binder DI binds, clients created and bound, external vendor bindings, provider recipes, routes, filters) and named policy conditions.');
|
|
186
203
|
return;
|
|
187
204
|
}
|
|
188
205
|
if (LEGACY_TOPOLOGY.test(expression.getText())) {
|
|
189
|
-
report(expression, 'Removed topology shape (rpcTarget,
|
|
206
|
+
report(expression, 'Removed topology shape (rpcTarget, a ContainerModule, a plan wrapper, RuntimeClients/RuntimeTaskClients, provideRpcClient or ExternalContractUse); register through the binder: binder.createRpcClientAndBind(Api, deployment), binder.createPubSubClientAndBind(Api, deployment), binder.bindExternal(Api, VendorImpl).');
|
|
190
207
|
return;
|
|
191
208
|
}
|
|
192
209
|
if (!this.registration(expression, scope)) {
|
|
193
|
-
report(expression, 'Use a recognized registration declaration:
|
|
210
|
+
report(expression, 'Use a recognized registration declaration: binder.bind(...) chains, binder.createRpcClientAndBind(Api, deployment, options?), binder.createPubSubClientAndBind(Api, deployment, options?), binder.bindExternal(Api, VendorImpl), browser binder.provide(...recipes), router.addRoutes/addFilter. Move custom setup into imported implementations, and give a vendor ContainerModule its own library BindModule in that library\'s canonical wiring.ts.');
|
|
194
211
|
return;
|
|
195
212
|
}
|
|
196
213
|
for (const argument of this.registrationArguments(expression)) {
|
|
@@ -201,8 +218,7 @@ class WiringFormat {
|
|
|
201
218
|
}
|
|
202
219
|
registration(expression, scope) {
|
|
203
220
|
if (ts.isNewExpression(expression))
|
|
204
|
-
return
|
|
205
|
-
(expression.arguments ?? []).every((argument) => ts.isStringLiteralLike(argument));
|
|
221
|
+
return false;
|
|
206
222
|
if (!ts.isPropertyAccessExpression(expression.expression))
|
|
207
223
|
return false;
|
|
208
224
|
const name = expression.expression.name.text;
|
|
@@ -210,42 +226,22 @@ class WiringFormat {
|
|
|
210
226
|
const file = this.signatureFile(expression);
|
|
211
227
|
if (file === undefined)
|
|
212
228
|
return false;
|
|
213
|
-
if (name === 'load')
|
|
214
|
-
return INVERSIFY.test(file) && this.moduleReceiver(receiver);
|
|
215
229
|
if (!WEBPIECES_SDK.test(file) && !INVERSIFY.test(file))
|
|
216
230
|
return false;
|
|
217
231
|
if (ts.isCallExpression(receiver))
|
|
218
232
|
return this.registration(receiver, scope);
|
|
219
|
-
return REGISTRATION_ROOTS.includes(name) &&
|
|
233
|
+
return REGISTRATION_ROOTS.includes(name) && this.path(receiver);
|
|
220
234
|
}
|
|
221
|
-
/** Every argument of every call in a registration chain
|
|
235
|
+
/** Every argument of every call in a registration chain. */
|
|
222
236
|
registrationArguments(expression) {
|
|
223
237
|
const own = [...(expression.arguments ?? [])];
|
|
224
238
|
if (!ts.isCallExpression(expression) || !ts.isPropertyAccessExpression(expression.expression))
|
|
225
239
|
return own;
|
|
226
240
|
const receiver = this.unwrap(expression.expression.expression);
|
|
227
|
-
if (ts.isCallExpression(receiver))
|
|
228
|
-
if (expression.expression.name.text === 'load')
|
|
229
|
-
return [...own, ...receiver.arguments];
|
|
241
|
+
if (ts.isCallExpression(receiver))
|
|
230
242
|
return [...own, ...this.registrationArguments(receiver)];
|
|
231
|
-
}
|
|
232
|
-
if (ts.isNewExpression(receiver))
|
|
233
|
-
return [...own, ...(receiver.arguments ?? [])];
|
|
234
243
|
return own;
|
|
235
244
|
}
|
|
236
|
-
/** `X.load`, `new X(prepared).load` or `createX(prepared).load`: an explicit, opaque module load. */
|
|
237
|
-
moduleReceiver(receiver) {
|
|
238
|
-
if (this.path(receiver))
|
|
239
|
-
return true;
|
|
240
|
-
if (ts.isNewExpression(receiver) || ts.isCallExpression(receiver))
|
|
241
|
-
return this.path(receiver.expression) && !LEGACY_TOPOLOGY.test(receiver.expression.getText());
|
|
242
|
-
return false;
|
|
243
|
-
}
|
|
244
|
-
clientBinder(expression) {
|
|
245
|
-
return ts.isNewExpression(expression) &&
|
|
246
|
-
['RuntimeClients', 'RuntimeTaskClients'].some((name) => this.types.isFramework(expression.expression, name)) &&
|
|
247
|
-
(expression.arguments ?? []).every((argument) => this.prepared(argument));
|
|
248
|
-
}
|
|
249
245
|
/** Returns the first non-declarative node inside a registration argument, or undefined. */
|
|
250
246
|
offending(expression, scope) {
|
|
251
247
|
const value = this.unwrap(expression);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wiring-format.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/runtime-wiring/wiring-format.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\nimport * as ts from 'typescript';\nimport { Option, RuleFailError } from '@webpieces/rules-config';\nimport { WiringSourceTypes, WiringKind } from './source-types';\nimport { CanonicalClientBindings } from './canonical-clients';\n\nconst WEBPIECES_SDK = /(?:\\/packages\\/(?:http|cloud)\\/|\\/node_modules\\/@webpieces\\/)(?:http-routing|http-client-node|http-client-browser|http-client-core|cloudtasks-client)\\//;\nconst INVERSIFY = /\\/node_modules\\/(?:@inversifyjs\\/|inversify\\/)/;\n/** Methods that START a registration: a DI bind, a client binding, a provider recipe, a route or a filter. */\nconst REGISTRATION_ROOTS = ['bind', 'bindRpc', 'bindPubSub', 'add', 'addRoutes', 'addFilter'];\n/** Removed authoring shapes; their presence means an old wrapper or an anonymous module survived. */\nconst LEGACY_TOPOLOGY = /\\b(?:rpcTarget|RpcTarget|ContainerModule|ServerWiring|ServerWiringOptions|BrowserWiring|getRuntimeWiring)\\b/;\n/** Environment discovery belongs in prepared configuration, never in a registration argument. */\nconst ENVIRONMENT = new Set(['process', 'window', 'document', 'localStorage', 'sessionStorage', 'navigator', 'location', 'globalThis']);\n\n/** The one canonical file being checked, its owner directory and where problems go. */\nclass CanonicalFile {\n constructor(\n readonly file: ts.SourceFile,\n readonly ownerRoot: string,\n readonly report: (node: ts.Node, message: string) => void,\n ) {}\n}\n\n/**\n * One canonical-file grammar. Each owner's src/wiring.ts holds its Wiring/AppWiring class AND the\n * BindingModule/RouteModule classes it selects, with their actual registrations. Symbol resolution\n * may read imports; format checking never does.\n */\nexport class WiringFormat {\n private readonly types: WiringSourceTypes;\n\n constructor(private readonly checker: ts.TypeChecker, private readonly maxLines: number) {\n this.types = new WiringSourceTypes(checker);\n }\n\n problems(file: ts.SourceFile): string[] {\n if (!/(?:^|\\/)wiring\\.ts$/.test(file.fileName)) return [];\n const problems: string[] = new CanonicalClientBindings(this.checker).problems(file);\n const report = (node: ts.Node, message: string): void => {\n const at = file.getLineAndCharacterOfPosition(node.getStart(file));\n problems.push(`${file.fileName}:${at.line + 1}:${at.character + 1}: ${message}`);\n };\n const scope = new CanonicalFile(file, path.dirname(path.dirname(path.resolve(file.fileName))), report);\n const lines = file.text.trimEnd().split('\\n').length;\n if (lines > this.maxLines)\n report(\n file,\n `wiring.ts has ${lines} lines, above maxLines ${this.maxLines}. Keep every BindingModule/RouteModule and its registrations here beside the Wiring class; shorten the file by moving configuration building, translations, environment discovery and initializer or factory bodies into imported implementations, or give a cohesive group its own library owner with its own wiring.ts.`,\n );\n for (const statement of file.statements) {\n if (ts.isImportDeclaration(statement) || ts.isExportDeclaration(statement)) continue;\n if (!ts.isClassDeclaration(statement)) {\n report(statement, 'Only imports, exports and named declarative classes belong in wiring.ts.');\n continue;\n }\n const kind = this.types.kind(statement);\n if (kind === undefined) {\n report(statement, 'Implement the framework Wiring, AppWiring, BindingModule or RouteModule contract.');\n continue;\n }\n this.classProblems(statement, kind, scope);\n }\n return problems;\n }\n\n assert(problems: readonly string[]): void {\n if (problems.length === 0) return;\n throw new RuleFailError('wiring-format', problems.join('\\n'), undefined, undefined, [\n new Option(\n \"Declare each owner's Wiring/AppWiring class together with its named BindingModule/RouteModule classes and their registrations in its src/wiring.ts, selected by literal getters. Keep configuration building, environment discovery and initializer/factory bodies in imported implementations, and keep named WiringPolicy conditions explicit.\",\n true,\n ),\n ]);\n }\n\n private classProblems(declaration: ts.ClassDeclaration, kind: WiringKind, scope: CanonicalFile): void {\n const report = scope.report;\n for (const member of declaration.members) {\n if (ts.isConstructorDeclaration(member)) {\n if (member.body !== undefined && member.body.statements.length > 0)\n report(member, 'Use constructor parameter properties to store prepared inputs; no setup logic.');\n continue;\n }\n if (!ts.isMethodDeclaration(member)) {\n report(member, 'Store prepared inputs in constructor parameter properties.');\n continue;\n }\n const name = member.name.getText();\n if (['getBindingModules', 'getRoutingModules', 'getWirings'].includes(name)) {\n const expected = name === 'getWirings' ? 'wiring' : name === 'getBindingModules' ? 'binding' : 'routing';\n if (name === 'getWirings' && kind !== 'app')\n report(member, 'Only AppWiring can declare getWirings; libraries cannot compose libraries.');\n this.arrayProblems(member, expected, scope);\n } else if (name === 'configure' && ['binding', 'routing'].includes(kind)) {\n for (const statement of member.body?.statements ?? []) this.configureProblems(statement, scope);\n } else if (name !== 'getHeaders' || kind !== 'app')\n report(member, 'Keep only canonical selection getters and short configure declarations; getRuntimeWiring and helper methods were removed.');\n }\n if (kind === 'binding' || kind === 'routing') {\n const configure = this.types.method(declaration, 'configure');\n if (configure !== undefined && configure.getSourceFile() !== scope.file)\n report(declaration, `configure is inherited from ${configure.getSourceFile().fileName}; declare this module's registrations in its own configure here in wiring.ts.`);\n }\n if (kind === 'app' || kind === 'wiring') {\n const names = ['getBindingModules', 'getRoutingModules', ...(kind === 'app' ? ['getWirings'] : [])];\n for (const name of names) {\n const method = this.types.method(declaration, name);\n if (method === undefined) report(declaration, `Missing ${name} literal array getter.`);\n else if (method.getSourceFile() !== scope.file)\n report(declaration, `${name} is inherited from ${method.getSourceFile().fileName}; declare the selection getter on this class in wiring.ts.`);\n }\n if (kind === 'wiring' && this.types.method(declaration, 'getWirings') !== undefined)\n report(declaration, 'A library Wiring must not inherit getWirings.');\n }\n }\n\n private arrayProblems(method: ts.MethodDeclaration, expected: WiringKind, scope: CanonicalFile): void {\n const report = scope.report;\n const statements = method.body?.statements;\n const returned = statements?.length === 1 && ts.isReturnStatement(statements[0]) ? statements[0].expression : undefined;\n if (returned === undefined || !ts.isArrayLiteralExpression(returned)) {\n report(method, 'Getter body must be exactly return [new NamedModule(preparedInputs)]; no delegation, spreads, helpers or conditions.');\n return;\n }\n for (const element of returned.elements) {\n if (!ts.isNewExpression(element) || this.types.kind(element.expression) !== expected) {\n report(element, `Select a named framework ${expected} instance; nested arrays and AppWiring children are forbidden.`);\n continue;\n }\n this.placementProblems(element.expression, expected, scope);\n for (const argument of element.arguments ?? []) {\n if (!this.prepared(argument)) report(argument, 'Pass prepared inputs or a named WiringPolicy; no callbacks, topology wrappers or computed setup.');\n }\n }\n }\n\n /** Proven through the resolved declaration: a selected module lives in THIS file, a library Wiring in its own wiring.ts. */\n private placementProblems(selected: ts.Expression, expected: WiringKind, scope: CanonicalFile): void {\n const declared = this.types.declaration(selected)?.getSourceFile();\n const where = declared === undefined ? 'an unresolved file' : declared.fileName;\n if (expected !== 'wiring') {\n if (declared === scope.file) return;\n const role = expected === 'binding' ? 'BindingModule' : 'RouteModule';\n scope.report(selected, `${selected.getText()} is declared in ${where}; declare this ${role} class, with its registrations, here in wiring.ts beside the Wiring class that selects it.`);\n return;\n }\n if (declared !== undefined && /(?:^|[\\\\/])wiring\\.(?:d\\.)?ts$/.test(declared.fileName)) return;\n scope.report(selected, `Library Wiring ${selected.getText()} is declared in ${where}; select a Wiring declared in its library's canonical src/wiring.ts.`);\n }\n\n private prepared(expression: ts.Expression): boolean {\n if (ts.isIdentifier(expression) || ts.isLiteralExpression(expression)) return true;\n if (ts.isPropertyAccessExpression(expression)) return this.prepared(expression.expression);\n if ([ts.SyntaxKind.TrueKeyword, ts.SyntaxKind.FalseKeyword, ts.SyntaxKind.ThisKeyword].includes(expression.kind)) return true;\n if (!ts.isNewExpression(expression)) return false;\n return this.types.isFramework(expression.expression, 'WiringPolicy');\n }\n\n private configureProblems(statement: ts.Statement, scope: CanonicalFile): void {\n const report = scope.report;\n if (ts.isVariableStatement(statement)) {\n const declarations = statement.declarationList.declarations;\n const initializer = declarations.length === 1 ? declarations[0].initializer : undefined;\n if ((statement.declarationList.flags & ts.NodeFlags.Const) !== 0 && initializer !== undefined && this.clientBinder(initializer)) return;\n }\n if (ts.isIfStatement(statement) && ts.isPropertyAccessExpression(statement.expression) && statement.expression.name.text === 'enabled' && this.types.isPolicy(statement.expression.expression) && statement.elseStatement === undefined) {\n const body = ts.isBlock(statement.thenStatement) ? statement.thenStatement.statements : [statement.thenStatement];\n for (const child of body) this.configureProblems(child, scope);\n return;\n }\n const written = ts.isExpressionStatement(statement) || ts.isReturnStatement(statement) ? statement.expression : undefined;\n const expression = written !== undefined && ts.isAwaitExpression(written) ? written.expression : written;\n if (expression === undefined || (!ts.isCallExpression(expression) && !ts.isNewExpression(expression))) {\n report(statement, 'configure contains only registration declarations (DI binds, client bindings, provider recipes, routes, filters, module loads, external-contract markers) and named policy conditions.');\n return;\n }\n if (LEGACY_TOPOLOGY.test(expression.getText())) {\n report(expression, 'Removed topology shape (rpcTarget, an anonymous ContainerModule or a plan wrapper); declare a named module registration instead.');\n return;\n }\n if (!this.registration(expression, scope)) {\n report(expression, 'Use a recognized registration declaration: options.bind(...) chains, RuntimeClients.bindRpc, RuntimeTaskClients.bindPubSub, bindings.add(provider recipes), router.addRoutes/addFilter, (await) NamedModule.load(options) or new ExternalContractUse(...). Move custom setup into imported implementations.');\n return;\n }\n for (const argument of this.registrationArguments(expression)) {\n const offending = this.offending(argument, scope);\n if (offending !== undefined)\n report(offending, 'Pass declarative registration arguments: tokens, classes, prepared fields, literals, named factory or initializer references, provider recipe objects and calls, and short DI factory callbacks such as (ctx) => ctx.get(Token). Move computed setup, environment reads, helper calls of this owner and callback bodies into imported implementations or prepared constructor inputs.');\n }\n }\n\n private registration(expression: ts.CallExpression | ts.NewExpression, scope: CanonicalFile): boolean {\n if (ts.isNewExpression(expression))\n return this.types.isFramework(expression.expression, 'ExternalContractUse') &&\n (expression.arguments ?? []).every((argument: ts.Expression) => ts.isStringLiteralLike(argument));\n if (!ts.isPropertyAccessExpression(expression.expression)) return false;\n const name = expression.expression.name.text;\n const receiver = this.unwrap(expression.expression.expression);\n const file = this.signatureFile(expression);\n if (file === undefined) return false;\n if (name === 'load') return INVERSIFY.test(file) && this.moduleReceiver(receiver);\n if (!WEBPIECES_SDK.test(file) && !INVERSIFY.test(file)) return false;\n if (ts.isCallExpression(receiver)) return this.registration(receiver, scope);\n return REGISTRATION_ROOTS.includes(name) && (this.path(receiver) || this.clientBinder(receiver));\n }\n\n /** Every argument of every call in a registration chain, plus a loaded module's construction arguments. */\n private registrationArguments(expression: ts.CallExpression | ts.NewExpression): ts.Expression[] {\n const own = [...(expression.arguments ?? [])];\n if (!ts.isCallExpression(expression) || !ts.isPropertyAccessExpression(expression.expression)) return own;\n const receiver = this.unwrap(expression.expression.expression);\n if (ts.isCallExpression(receiver)) {\n if (expression.expression.name.text === 'load') return [...own, ...receiver.arguments];\n return [...own, ...this.registrationArguments(receiver)];\n }\n if (ts.isNewExpression(receiver)) return [...own, ...(receiver.arguments ?? [])];\n return own;\n }\n\n /** `X.load`, `new X(prepared).load` or `createX(prepared).load`: an explicit, opaque module load. */\n private moduleReceiver(receiver: ts.Expression): boolean {\n if (this.path(receiver)) return true;\n if (ts.isNewExpression(receiver) || ts.isCallExpression(receiver))\n return this.path(receiver.expression) && !LEGACY_TOPOLOGY.test(receiver.expression.getText());\n return false;\n }\n\n private clientBinder(expression: ts.Expression): boolean {\n return ts.isNewExpression(expression) &&\n ['RuntimeClients', 'RuntimeTaskClients'].some((name: string) => this.types.isFramework(expression.expression, name)) &&\n (expression.arguments ?? []).every((argument: ts.Expression) => this.prepared(argument));\n }\n\n /** Returns the first non-declarative node inside a registration argument, or undefined. */\n private offending(expression: ts.Expression, scope: CanonicalFile): ts.Node | undefined {\n const value = this.unwrap(expression);\n if (this.literal(value)) return undefined;\n if (ts.isIdentifier(value) || value.kind === ts.SyntaxKind.ThisKeyword || ts.isPropertyAccessExpression(value))\n return this.path(value) ? undefined : value;\n if (ts.isArrayLiteralExpression(value)) {\n for (const element of value.elements) {\n const found = this.offending(ts.isSpreadElement(element) ? element.expression : element, scope);\n if (found !== undefined) return found;\n }\n return undefined;\n }\n if (ts.isObjectLiteralExpression(value)) {\n for (const property of value.properties) {\n if (ts.isShorthandPropertyAssignment(property)) {\n if (ENVIRONMENT.has(property.name.text)) return property;\n continue;\n }\n const initializer = ts.isPropertyAssignment(property) && !ts.isComputedPropertyName(property.name)\n ? property.initializer : ts.isSpreadAssignment(property) ? property.expression : undefined;\n if (initializer === undefined) return property;\n const found = this.offending(initializer, scope);\n if (found !== undefined) return found;\n }\n return undefined;\n }\n if (ts.isNewExpression(value)) {\n if (!this.path(value.expression) || LEGACY_TOPOLOGY.test(value.expression.getText())) return value;\n return this.firstOffending(value.arguments ?? [], scope);\n }\n if (ts.isCallExpression(value)) {\n const callee = value.expression;\n const receiverOk = this.path(callee) ||\n (ts.isPropertyAccessExpression(callee) && ts.isNewExpression(callee.expression) && this.offending(callee.expression, scope) === undefined);\n if (!receiverOk || !this.outsideOwner(value, scope)) return value;\n return this.firstOffending(value.arguments, scope);\n }\n if (ts.isArrowFunction(value)) return this.factoryCallback(value) ? undefined : value;\n return value;\n }\n\n private firstOffending(values: readonly ts.Expression[], scope: CanonicalFile): ts.Node | undefined {\n for (const value of values) {\n const found = this.offending(value, scope);\n if (found !== undefined) return found;\n }\n return undefined;\n }\n\n /**\n * A provider recipe or vendor factory (Angular, webpieces, another library) is a declaration; a\n * call into this owner's own helpers would hide the registrations it returns.\n */\n private outsideOwner(call: ts.CallExpression, scope: CanonicalFile): boolean {\n const file = this.signatureFile(call);\n if (file === undefined) return false;\n return file.includes('/node_modules/') || !file.startsWith(scope.ownerRoot.replace(/\\\\/g, '/') + '/');\n }\n\n /** A short DI factory: `(ctx) => ctx.get(Token)`, `(dep) => dep.build()` or `(dep) => new Named(dep)`. */\n private factoryCallback(arrow: ts.ArrowFunction): boolean {\n if (ts.isBlock(arrow.body)) return false;\n const parameters = new Set(arrow.parameters.map((parameter: ts.ParameterDeclaration) => parameter.name.getText()));\n const body = this.unwrap(arrow.body);\n const simple = (argument: ts.Expression): boolean => this.literal(this.unwrap(argument)) || this.path(this.unwrap(argument));\n if (ts.isNewExpression(body)) return this.path(body.expression) && (body.arguments ?? []).every(simple);\n if (!ts.isCallExpression(body) || !ts.isPropertyAccessExpression(body.expression)) return false;\n const receiver = body.expression.expression;\n return ts.isIdentifier(receiver) && parameters.has(receiver.text) && body.arguments.every(simple);\n }\n\n /** An identifier, `this`, or a property path over them that does not read the environment. */\n private path(expression: ts.Expression): boolean {\n if (ts.isIdentifier(expression)) return !ENVIRONMENT.has(expression.text);\n if (expression.kind === ts.SyntaxKind.ThisKeyword) return true;\n return ts.isPropertyAccessExpression(expression) && this.path(expression.expression);\n }\n\n private literal(expression: ts.Expression): boolean {\n if (ts.isStringLiteralLike(expression) || ts.isNumericLiteral(expression)) return true;\n if (ts.isPrefixUnaryExpression(expression)) return ts.isNumericLiteral(expression.operand);\n return [ts.SyntaxKind.TrueKeyword, ts.SyntaxKind.FalseKeyword, ts.SyntaxKind.NullKeyword].includes(expression.kind) ||\n (ts.isIdentifier(expression) && expression.text === 'undefined');\n }\n\n private unwrap(expression: ts.Expression): ts.Expression {\n if (ts.isParenthesizedExpression(expression) || ts.isAsExpression(expression) || ts.isNonNullExpression(expression) || ts.isSatisfiesExpression(expression))\n return this.unwrap(expression.expression);\n return expression;\n }\n\n private signatureFile(call: ts.CallExpression): string | undefined {\n const declaration = this.checker.getResolvedSignature(call)?.declaration;\n return declaration === undefined ? undefined : path.resolve(declaration.getSourceFile().fileName).replace(/\\\\/g, '/');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"wiring-format.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/runtime-wiring/wiring-format.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\nimport * as ts from 'typescript';\nimport { Option, RuleFailError } from '@webpieces/rules-config';\nimport { WiringSourceTypes, WiringKind } from './source-types';\nimport { CanonicalClientBindings } from './canonical-clients';\n\nconst WEBPIECES_SDK = /(?:\\/packages\\/(?:http|cloud)\\/|\\/node_modules\\/@webpieces\\/)(?:http-routing|http-client-node|http-client-browser|http-client-core|cloudtasks-client)\\//;\nconst INVERSIFY = /\\/node_modules\\/(?:@inversifyjs\\/|inversify\\/)/;\n/**\n * Methods that START a registration on the host's binder or router: a DI bind, a client created and\n * bound, a vendor implementation bound to its external contract, a browser provider recipe, a route\n * or a filter.\n */\nconst REGISTRATION_ROOTS = ['bind', 'createRpcClientAndBind', 'createPubSubClientAndBind', 'bindExternal', 'provide', 'addRoutes', 'addFilter'];\n/** Removed authoring shapes; their presence means an old wrapper, helper or an anonymous module survived. */\nconst LEGACY_TOPOLOGY = /\\b(?:rpcTarget|RpcTarget|ContainerModule|ServerWiring|ServerWiringOptions|BrowserWiring|getRuntimeWiring|RuntimeClients|RuntimeTaskClients|provideRpcClient|ExternalContractUse|BrowserBindings|BindingModule)\\b/;\n/** Getters renamed with BindingModule -> BindModule. */\nconst RENAMED_GETTERS: Readonly<Record<string, string>> = { getBindingModules: 'getBindModules', getRoutingModules: 'getRouteModules' };\n/** Environment discovery belongs in prepared configuration, never in a registration argument. */\nconst ENVIRONMENT = new Set(['process', 'window', 'document', 'localStorage', 'sessionStorage', 'navigator', 'location', 'globalThis']);\n\n/** The one canonical file being checked, its owner directory and where problems go. */\nclass CanonicalFile {\n constructor(\n readonly file: ts.SourceFile,\n readonly ownerRoot: string,\n readonly report: (node: ts.Node, message: string) => void,\n ) {}\n}\n\n/**\n * One canonical-file grammar. Each owner's src/wiring.ts holds its Wiring/AppWiring class AND the\n * BindModule/RouteModule classes it selects, with their actual registrations. A library owner's\n * canonical wiring.ts may export only BindModules. Symbol resolution may read imports; format\n * checking never does.\n */\nexport class WiringFormat {\n private readonly types: WiringSourceTypes;\n\n constructor(private readonly checker: ts.TypeChecker, private readonly maxLines: number) {\n this.types = new WiringSourceTypes(checker);\n }\n\n problems(file: ts.SourceFile): string[] {\n if (!/(?:^|\\/)wiring\\.ts$/.test(file.fileName)) return [];\n const problems: string[] = new CanonicalClientBindings(this.checker).problems(file);\n const report = (node: ts.Node, message: string): void => {\n const at = file.getLineAndCharacterOfPosition(node.getStart(file));\n problems.push(`${file.fileName}:${at.line + 1}:${at.character + 1}: ${message}`);\n };\n const scope = new CanonicalFile(file, path.dirname(path.dirname(path.resolve(file.fileName))), report);\n const lines = file.text.trimEnd().split('\\n').length;\n if (lines > this.maxLines)\n report(\n file,\n `wiring.ts has ${lines} lines, above maxLines ${this.maxLines}. Keep every BindModule/RouteModule and its registrations here beside the Wiring class; shorten the file by moving configuration building, translations, environment discovery and initializer or factory bodies into imported implementations, or give a cohesive group its own library owner with its own wiring.ts.`,\n );\n for (const statement of file.statements) {\n if (ts.isImportDeclaration(statement) || ts.isExportDeclaration(statement)) continue;\n if (!ts.isClassDeclaration(statement)) {\n report(statement, 'Only imports, exports and named declarative classes belong in wiring.ts.');\n continue;\n }\n const kind = this.types.kind(statement);\n if (kind === undefined) {\n report(statement, LEGACY_TOPOLOGY.test(statement.getText())\n ? 'Removed authoring shape (BindingModule, ExternalContractUse, RuntimeClients, provideRpcClient, BrowserBindings); implement BindModule and register through the binder.'\n : 'Implement the framework Wiring, AppWiring, BindModule or RouteModule contract.');\n continue;\n }\n this.classProblems(statement, kind, scope);\n }\n return problems;\n }\n\n assert(problems: readonly string[]): void {\n if (problems.length === 0) return;\n throw new RuleFailError('wiring-format', problems.join('\\n'), undefined, undefined, [\n new Option(\n \"Declare each owner's Wiring/AppWiring class together with its named BindModule/RouteModule classes and their registrations in its src/wiring.ts, selected by literal getters (getBindModules/getRouteModules/getWirings); an app may select a BindModule declared in a library owner's canonical src/wiring.ts. Register through the binder (binder.bind, binder.createRpcClientAndBind, binder.createPubSubClientAndBind, binder.bindExternal, browser binder.provide) and the router. Keep configuration building, environment discovery and initializer/factory bodies in imported implementations, and keep named WiringPolicy conditions explicit.\",\n true,\n ),\n ]);\n }\n\n private classProblems(declaration: ts.ClassDeclaration, kind: WiringKind, scope: CanonicalFile): void {\n const report = scope.report;\n for (const member of declaration.members) {\n if (ts.isConstructorDeclaration(member)) {\n if (member.body !== undefined && member.body.statements.length > 0)\n report(member, 'Use constructor parameter properties to store prepared inputs; no setup logic.');\n continue;\n }\n if (!ts.isMethodDeclaration(member)) {\n report(member, 'Store prepared inputs in constructor parameter properties.');\n continue;\n }\n const name = member.name.getText();\n if (Object.hasOwn(RENAMED_GETTERS, name)) {\n report(member, `${name} was renamed to ${RENAMED_GETTERS[name]}.`);\n } else if (['getBindModules', 'getRouteModules', 'getWirings'].includes(name)) {\n const expected = name === 'getWirings' ? 'wiring' : name === 'getBindModules' ? 'binding' : 'routing';\n if (name === 'getWirings' && kind !== 'app')\n report(member, 'Only AppWiring can declare getWirings; libraries cannot compose libraries.');\n this.arrayProblems(member, expected, kind, scope);\n } else if (name === 'configure' && ['binding', 'routing'].includes(kind)) {\n for (const statement of member.body?.statements ?? []) this.configureProblems(statement, scope);\n } else if (name !== 'getHeaders' || kind !== 'app')\n report(member, 'Keep only canonical selection getters and short configure declarations; getRuntimeWiring and helper methods were removed.');\n }\n if (kind === 'binding' || kind === 'routing') {\n const configure = this.types.method(declaration, 'configure');\n if (configure !== undefined && configure.getSourceFile() !== scope.file)\n report(declaration, `configure is inherited from ${configure.getSourceFile().fileName}; declare this module's registrations in its own configure here in wiring.ts.`);\n }\n if (kind === 'app' || kind === 'wiring') {\n // getRouteModules is Node-only (its Wiring type requires it); the browser has no route channel.\n const names = ['getBindModules', 'getRouteModules', ...(kind === 'app' ? ['getWirings'] : [])];\n for (const name of names) {\n const method = this.types.method(declaration, name);\n if (method === undefined) {\n if (name !== 'getRouteModules') report(declaration, `Missing ${name} literal array getter.`);\n } else if (method.getSourceFile() !== scope.file)\n report(declaration, `${name} is inherited from ${method.getSourceFile().fileName}; declare the selection getter on this class in wiring.ts.`);\n }\n if (kind === 'wiring' && this.types.method(declaration, 'getWirings') !== undefined)\n report(declaration, 'A library Wiring must not inherit getWirings.');\n }\n }\n\n private arrayProblems(method: ts.MethodDeclaration, expected: WiringKind, ownerKind: WiringKind, scope: CanonicalFile): void {\n const report = scope.report;\n const statements = method.body?.statements;\n const returned = statements?.length === 1 && ts.isReturnStatement(statements[0]) ? statements[0].expression : undefined;\n if (returned === undefined || !ts.isArrayLiteralExpression(returned)) {\n report(method, 'Getter body must be exactly return [new NamedModule(preparedInputs)]; no delegation, spreads, helpers or conditions.');\n return;\n }\n for (const element of returned.elements) {\n if (!ts.isNewExpression(element) || this.types.kind(element.expression) !== expected) {\n report(element, `Select a named framework ${expected} instance; nested arrays and AppWiring children are forbidden.`);\n continue;\n }\n this.placementProblems(element.expression, expected, ownerKind, scope);\n for (const argument of element.arguments ?? []) {\n if (!this.prepared(argument)) report(argument, 'Pass prepared inputs or a named WiringPolicy; no callbacks, topology wrappers or computed setup.');\n }\n }\n }\n\n /**\n * Proven through the resolved declaration: a selected module lives in THIS file; a BindModule an\n * AppWiring selects may instead live in a library owner's canonical wiring.ts, and a library\n * Wiring always does. The extractor additionally proves that file is the owner's src/wiring.ts.\n */\n private placementProblems(selected: ts.Expression, expected: WiringKind, ownerKind: WiringKind, scope: CanonicalFile): void {\n const declared = this.types.declaration(selected)?.getSourceFile();\n const where = declared === undefined ? 'an unresolved file' : declared.fileName;\n const canonical = declared !== undefined && /(?:^|[\\\\/])wiring\\.(?:d\\.)?ts$/.test(declared.fileName);\n if (expected !== 'wiring') {\n if (declared === scope.file) return;\n if (expected === 'binding' && ownerKind === 'app' && canonical) return;\n const role = expected === 'binding' ? 'BindModule' : 'RouteModule';\n const library = expected === 'binding' && ownerKind === 'app' ? \", or in its library owner's canonical src/wiring.ts\" : '';\n scope.report(selected, `${selected.getText()} is declared in ${where}; declare this ${role} class, with its registrations, here in wiring.ts beside the Wiring class that selects it${library}.`);\n return;\n }\n if (canonical) return;\n scope.report(selected, `Library Wiring ${selected.getText()} is declared in ${where}; select a Wiring declared in its library's canonical src/wiring.ts.`);\n }\n\n private prepared(expression: ts.Expression): boolean {\n if (ts.isIdentifier(expression) || ts.isLiteralExpression(expression)) return true;\n if (ts.isPropertyAccessExpression(expression)) return this.prepared(expression.expression);\n if ([ts.SyntaxKind.TrueKeyword, ts.SyntaxKind.FalseKeyword, ts.SyntaxKind.ThisKeyword].includes(expression.kind)) return true;\n if (!ts.isNewExpression(expression)) return false;\n return this.types.isFramework(expression.expression, 'WiringPolicy');\n }\n\n private configureProblems(statement: ts.Statement, scope: CanonicalFile): void {\n const report = scope.report;\n if (ts.isIfStatement(statement) && ts.isPropertyAccessExpression(statement.expression) && statement.expression.name.text === 'enabled' && this.types.isPolicy(statement.expression.expression) && statement.elseStatement === undefined) {\n const body = ts.isBlock(statement.thenStatement) ? statement.thenStatement.statements : [statement.thenStatement];\n for (const child of body) this.configureProblems(child, scope);\n return;\n }\n const written = ts.isExpressionStatement(statement) || ts.isReturnStatement(statement) ? statement.expression : undefined;\n const expression = written !== undefined && ts.isAwaitExpression(written) ? written.expression : written;\n if (expression === undefined || (!ts.isCallExpression(expression) && !ts.isNewExpression(expression))) {\n report(statement, 'configure contains only registration declarations (binder DI binds, clients created and bound, external vendor bindings, provider recipes, routes, filters) and named policy conditions.');\n return;\n }\n if (LEGACY_TOPOLOGY.test(expression.getText())) {\n report(expression, 'Removed topology shape (rpcTarget, a ContainerModule, a plan wrapper, RuntimeClients/RuntimeTaskClients, provideRpcClient or ExternalContractUse); register through the binder: binder.createRpcClientAndBind(Api, deployment), binder.createPubSubClientAndBind(Api, deployment), binder.bindExternal(Api, VendorImpl).');\n return;\n }\n if (!this.registration(expression, scope)) {\n report(expression, 'Use a recognized registration declaration: binder.bind(...) chains, binder.createRpcClientAndBind(Api, deployment, options?), binder.createPubSubClientAndBind(Api, deployment, options?), binder.bindExternal(Api, VendorImpl), browser binder.provide(...recipes), router.addRoutes/addFilter. Move custom setup into imported implementations, and give a vendor ContainerModule its own library BindModule in that library\\'s canonical wiring.ts.');\n return;\n }\n for (const argument of this.registrationArguments(expression)) {\n const offending = this.offending(argument, scope);\n if (offending !== undefined)\n report(offending, 'Pass declarative registration arguments: tokens, classes, prepared fields, literals, named factory or initializer references, provider recipe objects and calls, and short DI factory callbacks such as (ctx) => ctx.get(Token). Move computed setup, environment reads, helper calls of this owner and callback bodies into imported implementations or prepared constructor inputs.');\n }\n }\n\n private registration(expression: ts.CallExpression | ts.NewExpression, scope: CanonicalFile): boolean {\n if (ts.isNewExpression(expression)) return false;\n if (!ts.isPropertyAccessExpression(expression.expression)) return false;\n const name = expression.expression.name.text;\n const receiver = this.unwrap(expression.expression.expression);\n const file = this.signatureFile(expression);\n if (file === undefined) return false;\n if (!WEBPIECES_SDK.test(file) && !INVERSIFY.test(file)) return false;\n if (ts.isCallExpression(receiver)) return this.registration(receiver, scope);\n return REGISTRATION_ROOTS.includes(name) && this.path(receiver);\n }\n\n /** Every argument of every call in a registration chain. */\n private registrationArguments(expression: ts.CallExpression | ts.NewExpression): ts.Expression[] {\n const own = [...(expression.arguments ?? [])];\n if (!ts.isCallExpression(expression) || !ts.isPropertyAccessExpression(expression.expression)) return own;\n const receiver = this.unwrap(expression.expression.expression);\n if (ts.isCallExpression(receiver)) return [...own, ...this.registrationArguments(receiver)];\n return own;\n }\n\n /** Returns the first non-declarative node inside a registration argument, or undefined. */\n private offending(expression: ts.Expression, scope: CanonicalFile): ts.Node | undefined {\n const value = this.unwrap(expression);\n if (this.literal(value)) return undefined;\n if (ts.isIdentifier(value) || value.kind === ts.SyntaxKind.ThisKeyword || ts.isPropertyAccessExpression(value))\n return this.path(value) ? undefined : value;\n if (ts.isArrayLiteralExpression(value)) {\n for (const element of value.elements) {\n const found = this.offending(ts.isSpreadElement(element) ? element.expression : element, scope);\n if (found !== undefined) return found;\n }\n return undefined;\n }\n if (ts.isObjectLiteralExpression(value)) {\n for (const property of value.properties) {\n if (ts.isShorthandPropertyAssignment(property)) {\n if (ENVIRONMENT.has(property.name.text)) return property;\n continue;\n }\n const initializer = ts.isPropertyAssignment(property) && !ts.isComputedPropertyName(property.name)\n ? property.initializer : ts.isSpreadAssignment(property) ? property.expression : undefined;\n if (initializer === undefined) return property;\n const found = this.offending(initializer, scope);\n if (found !== undefined) return found;\n }\n return undefined;\n }\n if (ts.isNewExpression(value)) {\n if (!this.path(value.expression) || LEGACY_TOPOLOGY.test(value.expression.getText())) return value;\n return this.firstOffending(value.arguments ?? [], scope);\n }\n if (ts.isCallExpression(value)) {\n const callee = value.expression;\n const receiverOk = this.path(callee) ||\n (ts.isPropertyAccessExpression(callee) && ts.isNewExpression(callee.expression) && this.offending(callee.expression, scope) === undefined);\n if (!receiverOk || !this.outsideOwner(value, scope)) return value;\n return this.firstOffending(value.arguments, scope);\n }\n if (ts.isArrowFunction(value)) return this.factoryCallback(value) ? undefined : value;\n return value;\n }\n\n private firstOffending(values: readonly ts.Expression[], scope: CanonicalFile): ts.Node | undefined {\n for (const value of values) {\n const found = this.offending(value, scope);\n if (found !== undefined) return found;\n }\n return undefined;\n }\n\n /**\n * A provider recipe or vendor factory (Angular, webpieces, another library) is a declaration; a\n * call into this owner's own helpers would hide the registrations it returns.\n */\n private outsideOwner(call: ts.CallExpression, scope: CanonicalFile): boolean {\n const file = this.signatureFile(call);\n if (file === undefined) return false;\n return file.includes('/node_modules/') || !file.startsWith(scope.ownerRoot.replace(/\\\\/g, '/') + '/');\n }\n\n /** A short DI factory: `(ctx) => ctx.get(Token)`, `(dep) => dep.build()` or `(dep) => new Named(dep)`. */\n private factoryCallback(arrow: ts.ArrowFunction): boolean {\n if (ts.isBlock(arrow.body)) return false;\n const parameters = new Set(arrow.parameters.map((parameter: ts.ParameterDeclaration) => parameter.name.getText()));\n const body = this.unwrap(arrow.body);\n const simple = (argument: ts.Expression): boolean => this.literal(this.unwrap(argument)) || this.path(this.unwrap(argument));\n if (ts.isNewExpression(body)) return this.path(body.expression) && (body.arguments ?? []).every(simple);\n if (!ts.isCallExpression(body) || !ts.isPropertyAccessExpression(body.expression)) return false;\n const receiver = body.expression.expression;\n return ts.isIdentifier(receiver) && parameters.has(receiver.text) && body.arguments.every(simple);\n }\n\n /** An identifier, `this`, or a property path over them that does not read the environment. */\n private path(expression: ts.Expression): boolean {\n if (ts.isIdentifier(expression)) return !ENVIRONMENT.has(expression.text);\n if (expression.kind === ts.SyntaxKind.ThisKeyword) return true;\n return ts.isPropertyAccessExpression(expression) && this.path(expression.expression);\n }\n\n private literal(expression: ts.Expression): boolean {\n if (ts.isStringLiteralLike(expression) || ts.isNumericLiteral(expression)) return true;\n if (ts.isPrefixUnaryExpression(expression)) return ts.isNumericLiteral(expression.operand);\n return [ts.SyntaxKind.TrueKeyword, ts.SyntaxKind.FalseKeyword, ts.SyntaxKind.NullKeyword].includes(expression.kind) ||\n (ts.isIdentifier(expression) && expression.text === 'undefined');\n }\n\n private unwrap(expression: ts.Expression): ts.Expression {\n if (ts.isParenthesizedExpression(expression) || ts.isAsExpression(expression) || ts.isNonNullExpression(expression) || ts.isSatisfiesExpression(expression))\n return this.unwrap(expression.expression);\n return expression;\n }\n\n private signatureFile(call: ts.CallExpression): string | undefined {\n const declaration = this.checker.getResolvedSignature(call)?.declaration;\n return declaration === undefined ? undefined : path.resolve(declaration.getSourceFile().fileName).replace(/\\\\/g, '/');\n }\n}\n"]}
|
package/src/rule-help.js
CHANGED
|
@@ -4,13 +4,13 @@ exports.ruleHelp = void 0;
|
|
|
4
4
|
const rules_sdk_1 = require("@webpieces/rules-sdk");
|
|
5
5
|
/** Owner-authored guidance consumed by the registry catalog. */
|
|
6
6
|
exports.ruleHelp = {
|
|
7
|
-
'wiring-format': new rules_sdk_1.RuleHelp('Check every canonical wiring.ts: its Wiring/AppWiring class plus the
|
|
7
|
+
'wiring-format': new rules_sdk_1.RuleHelp('Check every canonical wiring.ts: its Wiring/AppWiring class plus the BindModule/RouteModule classes it selects, with their actual registrations.', 'Declare each owner\'s Wiring/AppWiring class beside its named BindModule/RouteModule classes and their registrations (binder.createRpcClientAndBind, binder.createPubSubClientAndBind, binder.bindExternal, binder.bind chains, browser binder.provide recipes, addRoutes, addFilter) in its src/wiring.ts; select them with literal getBindModules/getRouteModules/getWirings return arrays. An AppWiring may also select a BindModule declared in a library owner\'s canonical src/wiring.ts, and only an AppWiring selects library Wirings. Keep constructors as prepared-input storage, keep configuration building, environment discovery and initializer/factory bodies in imported implementations, use direct service strings and explicit WiringPolicy declarations. Set maxLines explicitly (agreed upstream limit: 400).'),
|
|
8
8
|
'no-file-import-cycles': new rules_sdk_1.RuleHelp('Keep each project free of circular file imports.', 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.'),
|
|
9
9
|
'runtime-architecture': new rules_sdk_1.RuleHelp('Validate runtime service and API dependency declarations.', 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.'),
|
|
10
10
|
'nx-wiring': new rules_sdk_1.RuleHelp('Wire the required validation targets into the Nx execution graph.', 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.'),
|
|
11
11
|
'di-graph': new rules_sdk_1.RuleHelp('Generate and validate dependency-injection design graphs.', 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.'),
|
|
12
12
|
'missing-design-annotation': new rules_sdk_1.RuleHelp('Declare the application design roots required for DI analysis.', 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.'),
|
|
13
|
-
'validate-architecture-unchanged': new rules_sdk_1.RuleHelp('Keep the committed architecture graph aligned with current dependencies.', 'In src/wiring.ts
|
|
13
|
+
'validate-architecture-unchanged': new rules_sdk_1.RuleHelp('Keep the committed architecture graph aligned with current dependencies.', 'In src/wiring.ts register clients through the BindModule\'s Binder: binder.createRpcClientAndBind(Api, deployment, new ClientBindOptions(token?, filters?)) and binder.createPubSubClientAndBind(Api, deployment, new PubSubBindOptions(token?)) from @webpieces/http-routing, binder.bindExternal(Api, VendorImpl) for vendor contracts, and the browser binder.createRpcClientAndBind(Api, deployment) from @webpieces/http-client-browser. wiring-format checks canonical wiring.ts in all participating owners; preserve tokens and filters. Review graph changes and runtime-deps.json candidates explicitly.'),
|
|
14
14
|
'validate-no-architecture-cycles': new rules_sdk_1.RuleHelp('Keep the project dependency architecture free of cycles.', 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.'),
|
|
15
15
|
'validate-packagejson': new rules_sdk_1.RuleHelp('Align package dependencies with declared project dependencies.', 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.'),
|
|
16
16
|
'validate-versions-locked': new rules_sdk_1.RuleHelp('Pin dependency versions consistently across governed projects.', 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.'),
|
package/src/rule-help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-help.js","sourceRoot":"","sources":["../../../../../packages/tooling/nx-webpieces-rules/src/rule-help.ts"],"names":[],"mappings":";;;AAAA,oDAAgD;AAEhD,gEAAgE;AACnD,QAAA,QAAQ,GAAuC;IACxD,eAAe,EAAE,IAAI,oBAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"rule-help.js","sourceRoot":"","sources":["../../../../../packages/tooling/nx-webpieces-rules/src/rule-help.ts"],"names":[],"mappings":";;;AAAA,oDAAgD;AAEhD,gEAAgE;AACnD,QAAA,QAAQ,GAAuC;IACxD,eAAe,EAAE,IAAI,oBAAQ,CAAC,kJAAkJ,EAAE,qyBAAqyB,CAAC;IACx9B,uBAAuB,EAAE,IAAI,oBAAQ,CACjC,kDAAkD,EAClD,sIAAsI,CACzI;IACD,sBAAsB,EAAE,IAAI,oBAAQ,CAChC,2DAA2D,EAC3D,sIAAsI,CACzI;IACD,WAAW,EAAE,IAAI,oBAAQ,CACrB,mEAAmE,EACnE,sIAAsI,CACzI;IACD,UAAU,EAAE,IAAI,oBAAQ,CACpB,2DAA2D,EAC3D,sIAAsI,CACzI;IACD,2BAA2B,EAAE,IAAI,oBAAQ,CACrC,gEAAgE,EAChE,sIAAsI,CACzI;IACD,iCAAiC,EAAE,IAAI,oBAAQ,CAC3C,0EAA0E,EAC1E,olBAAolB,CACvlB;IACD,iCAAiC,EAAE,IAAI,oBAAQ,CAC3C,0DAA0D,EAC1D,sIAAsI,CACzI;IACD,sBAAsB,EAAE,IAAI,oBAAQ,CAChC,gEAAgE,EAChE,sIAAsI,CACzI;IACD,0BAA0B,EAAE,IAAI,oBAAQ,CACpC,gEAAgE,EAChE,sIAAsI,CACzI;IACD,sBAAsB,EAAE,IAAI,oBAAQ,CAChC,8EAA8E,EAC9E,sIAAsI,CACzI;IACD,wBAAwB,EAAE,IAAI,oBAAQ,CAClC,qEAAqE,EACrE,sIAAsI,CACzI;IACD,uBAAuB,EAAE,IAAI,oBAAQ,CACjC,uEAAuE,EACvE,sIAAsI,CACzI;IACD,mBAAmB,EAAE,IAAI,oBAAQ,CAC7B,mEAAmE,EACnE,sIAAsI,CACzI;IACD,sBAAsB,EAAE,IAAI,oBAAQ,CAChC,+DAA+D,EAC/D,sIAAsI,CACzI;IACD,cAAc,EAAE,IAAI,oBAAQ,CACxB,sDAAsD,EACtD,sIAAsI,CACzI;IACD,kBAAkB,EAAE,IAAI,oBAAQ,CAC5B,gEAAgE,EAChE,sIAAsI,CACzI;CACJ,CAAC","sourcesContent":["import { RuleHelp } from '@webpieces/rules-sdk';\n\n/** Owner-authored guidance consumed by the registry catalog. */\nexport const ruleHelp: Readonly<Record<string, RuleHelp>> = {\n 'wiring-format': new RuleHelp('Check every canonical wiring.ts: its Wiring/AppWiring class plus the BindModule/RouteModule classes it selects, with their actual registrations.', 'Declare each owner\\'s Wiring/AppWiring class beside its named BindModule/RouteModule classes and their registrations (binder.createRpcClientAndBind, binder.createPubSubClientAndBind, binder.bindExternal, binder.bind chains, browser binder.provide recipes, addRoutes, addFilter) in its src/wiring.ts; select them with literal getBindModules/getRouteModules/getWirings return arrays. An AppWiring may also select a BindModule declared in a library owner\\'s canonical src/wiring.ts, and only an AppWiring selects library Wirings. Keep constructors as prepared-input storage, keep configuration building, environment discovery and initializer/factory bodies in imported implementations, use direct service strings and explicit WiringPolicy declarations. Set maxLines explicitly (agreed upstream limit: 400).'),\n 'no-file-import-cycles': new RuleHelp(\n 'Keep each project free of circular file imports.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'runtime-architecture': new RuleHelp(\n 'Validate runtime service and API dependency declarations.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'nx-wiring': new RuleHelp(\n 'Wire the required validation targets into the Nx execution graph.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'di-graph': new RuleHelp(\n 'Generate and validate dependency-injection design graphs.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'missing-design-annotation': new RuleHelp(\n 'Declare the application design roots required for DI analysis.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'validate-architecture-unchanged': new RuleHelp(\n 'Keep the committed architecture graph aligned with current dependencies.',\n 'In src/wiring.ts register clients through the BindModule\\'s Binder: binder.createRpcClientAndBind(Api, deployment, new ClientBindOptions(token?, filters?)) and binder.createPubSubClientAndBind(Api, deployment, new PubSubBindOptions(token?)) from @webpieces/http-routing, binder.bindExternal(Api, VendorImpl) for vendor contracts, and the browser binder.createRpcClientAndBind(Api, deployment) from @webpieces/http-client-browser. wiring-format checks canonical wiring.ts in all participating owners; preserve tokens and filters. Review graph changes and runtime-deps.json candidates explicitly.',\n ),\n 'validate-no-architecture-cycles': new RuleHelp(\n 'Keep the project dependency architecture free of cycles.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'validate-packagejson': new RuleHelp(\n 'Align package dependencies with declared project dependencies.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'validate-versions-locked': new RuleHelp(\n 'Pin dependency versions consistently across governed projects.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'validate-eslint-sync': new RuleHelp(\n 'Keep managed ESLint configuration synchronized with its installed templates.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'no-root-union-api-type': new RuleHelp(\n 'Use a stable named root API contract rather than a root union type.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'api-rules-for-openapi': new RuleHelp(\n 'Validate API contracts against their configured OpenAPI requirements.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'api-rules-for-mcp': new RuleHelp(\n 'Validate API contracts against their configured MCP requirements.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'api-lib-dependencies': new RuleHelp(\n 'Validate the configured API library dependency relationships.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'api-lib-path': new RuleHelp(\n 'Use the configured paths for API contract libraries.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n 'framework-folder': new RuleHelp(\n 'Align framework declarations with their project folder layout.',\n 'Apply this policy in source, or review its explicit settings in {configFile}. An intentional opt-out requires complete OFF settings.',\n ),\n};\n"]}
|