@webpieces/nx-webpieces-rules 0.4.870 → 0.4.871

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/nx-webpieces-rules",
3
- "version": "0.4.870",
3
+ "version": "0.4.871",
4
4
  "description": "Nx-specific webpieces validation rules, graph tooling, executors, and inference plugin.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -20,12 +20,12 @@
20
20
  "README.md"
21
21
  ],
22
22
  "dependencies": {
23
- "@webpieces/api-doc-model": "0.4.870",
24
- "@webpieces/core-util": "0.4.870",
25
- "@webpieces/eslint-rules": "0.4.870",
26
- "@webpieces/rules-config": "0.4.870",
23
+ "@webpieces/api-doc-model": "0.4.871",
24
+ "@webpieces/core-util": "0.4.871",
25
+ "@webpieces/eslint-rules": "0.4.871",
26
+ "@webpieces/rules-config": "0.4.871",
27
27
  "madge": "8.0.0",
28
- "@webpieces/rules-sdk": "0.4.870"
28
+ "@webpieces/rules-sdk": "0.4.871"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "@nx/devkit": ">=18.0.0"
@@ -41,7 +41,7 @@
41
41
  "access": "public"
42
42
  },
43
43
  "devDependencies": {
44
- "@webpieces/tooling-testkit": "0.4.870"
44
+ "@webpieces/tooling-testkit": "0.4.871"
45
45
  },
46
46
  "types": "./src/index.d.ts",
47
47
  "bin": {
@@ -4,7 +4,9 @@ import { Binding } from './model';
4
4
  * The host binder's client registrations retain the same DI token and singleton boundary as a
5
5
  * hand-written lazy factory: `binder.createRpcClientAndBind(Api, deployment, options?)` and
6
6
  * `binder.createPubSubClientAndBind(...)` bind `options.token` when given, else the API class itself.
7
- * `binder.bindExternal(Api, VendorImpl)` binds the vendor class to its external contract.
7
+ * `binder.bindExternal(Api, VendorImpl)` binds the vendor class to its external contract; the browser
8
+ * spelling `binder.bindExternal(Api, new UseClass(Vendor) | new UseExisting(Token))`
9
+ * resolves through to the same implementation class (an alias walks into its target).
8
10
  */
9
11
  export declare class RuntimeClientBindings {
10
12
  collectNode(call: ts.CallExpression, checker: ts.TypeChecker, root: string): Binding | undefined;
@@ -13,6 +15,8 @@ export declare class RuntimeClientBindings {
13
15
  private binderMethod;
14
16
  private client;
15
17
  private external;
18
+ /** The browser `new UseClass(X)` / `new UseExisting(X)` names X; the Node form is X itself. */
19
+ private externalImpl;
16
20
  private implementation;
17
21
  /** `new ClientBindOptions(token, ...)` names an extra token; omitted, the API class is the token. */
18
22
  private tokenExpression;
@@ -9,7 +9,9 @@ const token_resolver_1 = require("./token-resolver");
9
9
  * The host binder's client registrations retain the same DI token and singleton boundary as a
10
10
  * hand-written lazy factory: `binder.createRpcClientAndBind(Api, deployment, options?)` and
11
11
  * `binder.createPubSubClientAndBind(...)` bind `options.token` when given, else the API class itself.
12
- * `binder.bindExternal(Api, VendorImpl)` binds the vendor class to its external contract.
12
+ * `binder.bindExternal(Api, VendorImpl)` binds the vendor class to its external contract; the browser
13
+ * spelling `binder.bindExternal(Api, new UseClass(Vendor) | new UseExisting(Token))`
14
+ * resolves through to the same implementation class (an alias walks into its target).
13
15
  */
14
16
  class RuntimeClientBindings {
15
17
  collectNode(call, checker, root) {
@@ -21,9 +23,12 @@ class RuntimeClientBindings {
21
23
  return undefined;
22
24
  }
23
25
  collectBrowser(call, checker, root) {
24
- if (this.binderMethod(call, checker, 'http-client-browser') !== 'createRpcClientAndBind')
25
- return;
26
- return this.client(call, checker, root);
26
+ const method = this.binderMethod(call, checker, 'http-client-browser');
27
+ if (method === 'createRpcClientAndBind')
28
+ return this.client(call, checker, root);
29
+ if (method === 'bindExternal')
30
+ return this.external(call, checker, root);
31
+ return undefined;
27
32
  }
28
33
  /** The method name when `call` resolves to the host Binder declared in `pkg`; otherwise undefined. */
29
34
  binderMethod(call, checker, pkg) {
@@ -49,12 +54,23 @@ class RuntimeClientBindings {
49
54
  }
50
55
  external(call, checker, root) {
51
56
  const api = call.arguments[0];
52
- const impl = call.arguments[1];
57
+ const impl = call.arguments[1] === undefined ? undefined : this.externalImpl(call.arguments[1], checker);
53
58
  if (api === undefined || impl === undefined)
54
59
  return;
55
60
  const token = (0, token_resolver_1.resolveTokenKey)(api, checker, root);
56
61
  return new model_1.Binding(token.key, token.display, 'to', 'singleton', this.implementation(impl, checker), impl.getText(), (0, token_resolver_1.relativeFile)(root, call.getSourceFile()));
57
62
  }
63
+ /** The browser `new UseClass(X)` / `new UseExisting(X)` names X; the Node form is X itself. */
64
+ externalImpl(expression, checker) {
65
+ if (!ts.isNewExpression(expression))
66
+ return expression;
67
+ let recipe = checker.getSymbolAtLocation(expression.expression);
68
+ if (recipe !== undefined && (recipe.flags & ts.SymbolFlags.Alias) !== 0)
69
+ recipe = checker.getAliasedSymbol(recipe);
70
+ if (recipe === undefined || !['UseClass', 'UseExisting'].includes(recipe.getName()))
71
+ return undefined;
72
+ return expression.arguments?.[0];
73
+ }
58
74
  implementation(expression, checker) {
59
75
  let symbol = checker.getSymbolAtLocation(expression);
60
76
  if (symbol !== undefined && (symbol.flags & ts.SymbolFlags.Alias) !== 0)
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-client-bindings.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/di-graph/runtime-client-bindings.ts"],"names":[],"mappings":"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","sourcesContent":["import * as ts from 'typescript';\nimport { Binding } from './model';\nimport { relativeFile, resolveTokenKey } from './token-resolver';\n\n/**\n * The host binder's client registrations retain the same DI token and singleton boundary as a\n * hand-written lazy factory: `binder.createRpcClientAndBind(Api, deployment, options?)` and\n * `binder.createPubSubClientAndBind(...)` bind `options.token` when given, else the API class itself.\n * `binder.bindExternal(Api, VendorImpl)` binds the vendor class to its external contract.\n */\nexport class RuntimeClientBindings {\n collectNode(\n call: ts.CallExpression,\n checker: ts.TypeChecker,\n root: string,\n ): Binding | undefined {\n const method = this.binderMethod(call, checker, 'http-routing');\n if (method === 'createRpcClientAndBind' || method === 'createPubSubClientAndBind')\n return this.client(call, checker, root);\n if (method === 'bindExternal') return this.external(call, checker, root);\n return undefined;\n }\n\n collectBrowser(\n call: ts.CallExpression,\n checker: ts.TypeChecker,\n root: string,\n ): Binding | undefined {\n if (this.binderMethod(call, checker, 'http-client-browser') !== 'createRpcClientAndBind') return;\n return this.client(call, checker, root);\n }\n\n /** The method name when `call` resolves to the host Binder declared in `pkg`; otherwise undefined. */\n private binderMethod(call: ts.CallExpression, checker: ts.TypeChecker, pkg: string): string | undefined {\n if (!ts.isPropertyAccessExpression(call.expression)) return undefined;\n const declaration = checker.getResolvedSignature(call)?.declaration;\n if (declaration === undefined) return undefined;\n const file = declaration.getSourceFile().fileName.replace(/\\\\/g, '/');\n if (!new RegExp(`(?:/packages/http/|/node_modules/@webpieces/)${pkg}/`).test(file)) return undefined;\n const owner = declaration.parent;\n const ownerName =\n owner !== undefined && (ts.isClassDeclaration(owner) || ts.isInterfaceDeclaration(owner))\n ? owner.name?.text\n : undefined;\n return ownerName === 'Binder' ? call.expression.name.text : undefined;\n }\n\n private client(call: ts.CallExpression, checker: ts.TypeChecker, root: string): Binding | undefined {\n if (call.arguments.length < 2) return;\n const token = resolveTokenKey(this.tokenExpression(call), checker, root);\n return new Binding(\n token.key,\n token.display,\n 'toDynamicValue',\n 'singleton',\n null,\n call.expression.getText(),\n relativeFile(root, call.getSourceFile()),\n [],\n true,\n );\n }\n\n private external(call: ts.CallExpression, checker: ts.TypeChecker, root: string): Binding | undefined {\n const api = call.arguments[0];\n const impl = call.arguments[1];\n if (api === undefined || impl === undefined) return;\n const token = resolveTokenKey(api, checker, root);\n return new Binding(\n token.key,\n token.display,\n 'to',\n 'singleton',\n this.implementation(impl, checker),\n impl.getText(),\n relativeFile(root, call.getSourceFile()),\n );\n }\n\n private implementation(expression: ts.Expression, checker: ts.TypeChecker): ts.ClassDeclaration | null {\n let symbol = checker.getSymbolAtLocation(expression);\n if (symbol !== undefined && (symbol.flags & ts.SymbolFlags.Alias) !== 0) symbol = checker.getAliasedSymbol(symbol);\n return symbol?.declarations?.find((declaration: ts.Declaration) => ts.isClassDeclaration(declaration)) as ts.ClassDeclaration | undefined ?? null;\n }\n\n /** `new ClientBindOptions(token, ...)` names an extra token; omitted, the API class is the token. */\n private tokenExpression(call: ts.CallExpression): ts.Expression {\n const options = call.arguments[2];\n if (options !== undefined && ts.isNewExpression(options)) {\n const token = options.arguments?.[0];\n if (token !== undefined && token.kind !== ts.SyntaxKind.UndefinedKeyword && token.getText() !== 'undefined')\n return token;\n }\n return call.arguments[0];\n }\n}\n"]}
1
+ {"version":3,"file":"runtime-client-bindings.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/di-graph/runtime-client-bindings.ts"],"names":[],"mappings":"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","sourcesContent":["import * as ts from 'typescript';\nimport { Binding } from './model';\nimport { relativeFile, resolveTokenKey } from './token-resolver';\n\n/**\n * The host binder's client registrations retain the same DI token and singleton boundary as a\n * hand-written lazy factory: `binder.createRpcClientAndBind(Api, deployment, options?)` and\n * `binder.createPubSubClientAndBind(...)` bind `options.token` when given, else the API class itself.\n * `binder.bindExternal(Api, VendorImpl)` binds the vendor class to its external contract; the browser\n * spelling `binder.bindExternal(Api, new UseClass(Vendor) | new UseExisting(Token))`\n * resolves through to the same implementation class (an alias walks into its target).\n */\nexport class RuntimeClientBindings {\n collectNode(\n call: ts.CallExpression,\n checker: ts.TypeChecker,\n root: string,\n ): Binding | undefined {\n const method = this.binderMethod(call, checker, 'http-routing');\n if (method === 'createRpcClientAndBind' || method === 'createPubSubClientAndBind')\n return this.client(call, checker, root);\n if (method === 'bindExternal') return this.external(call, checker, root);\n return undefined;\n }\n\n collectBrowser(\n call: ts.CallExpression,\n checker: ts.TypeChecker,\n root: string,\n ): Binding | undefined {\n const method = this.binderMethod(call, checker, 'http-client-browser');\n if (method === 'createRpcClientAndBind') return this.client(call, checker, root);\n if (method === 'bindExternal') return this.external(call, checker, root);\n return undefined;\n }\n\n /** The method name when `call` resolves to the host Binder declared in `pkg`; otherwise undefined. */\n private binderMethod(call: ts.CallExpression, checker: ts.TypeChecker, pkg: string): string | undefined {\n if (!ts.isPropertyAccessExpression(call.expression)) return undefined;\n const declaration = checker.getResolvedSignature(call)?.declaration;\n if (declaration === undefined) return undefined;\n const file = declaration.getSourceFile().fileName.replace(/\\\\/g, '/');\n if (!new RegExp(`(?:/packages/http/|/node_modules/@webpieces/)${pkg}/`).test(file)) return undefined;\n const owner = declaration.parent;\n const ownerName =\n owner !== undefined && (ts.isClassDeclaration(owner) || ts.isInterfaceDeclaration(owner))\n ? owner.name?.text\n : undefined;\n return ownerName === 'Binder' ? call.expression.name.text : undefined;\n }\n\n private client(call: ts.CallExpression, checker: ts.TypeChecker, root: string): Binding | undefined {\n if (call.arguments.length < 2) return;\n const token = resolveTokenKey(this.tokenExpression(call), checker, root);\n return new Binding(\n token.key,\n token.display,\n 'toDynamicValue',\n 'singleton',\n null,\n call.expression.getText(),\n relativeFile(root, call.getSourceFile()),\n [],\n true,\n );\n }\n\n private external(call: ts.CallExpression, checker: ts.TypeChecker, root: string): Binding | undefined {\n const api = call.arguments[0];\n const impl = call.arguments[1] === undefined ? undefined : this.externalImpl(call.arguments[1], checker);\n if (api === undefined || impl === undefined) return;\n const token = resolveTokenKey(api, checker, root);\n return new Binding(\n token.key,\n token.display,\n 'to',\n 'singleton',\n this.implementation(impl, checker),\n impl.getText(),\n relativeFile(root, call.getSourceFile()),\n );\n }\n\n /** The browser `new UseClass(X)` / `new UseExisting(X)` names X; the Node form is X itself. */\n private externalImpl(expression: ts.Expression, checker: ts.TypeChecker): ts.Expression | undefined {\n if (!ts.isNewExpression(expression)) return expression;\n let recipe = checker.getSymbolAtLocation(expression.expression);\n if (recipe !== undefined && (recipe.flags & ts.SymbolFlags.Alias) !== 0) recipe = checker.getAliasedSymbol(recipe);\n if (recipe === undefined || !['UseClass', 'UseExisting'].includes(recipe.getName())) return undefined;\n return expression.arguments?.[0];\n }\n\n private implementation(expression: ts.Expression, checker: ts.TypeChecker): ts.ClassDeclaration | null {\n let symbol = checker.getSymbolAtLocation(expression);\n if (symbol !== undefined && (symbol.flags & ts.SymbolFlags.Alias) !== 0) symbol = checker.getAliasedSymbol(symbol);\n return symbol?.declarations?.find((declaration: ts.Declaration) => ts.isClassDeclaration(declaration)) as ts.ClassDeclaration | undefined ?? null;\n }\n\n /** `new ClientBindOptions(token, ...)` names an extra token; omitted, the API class is the token. */\n private tokenExpression(call: ts.CallExpression): ts.Expression {\n const options = call.arguments[2];\n if (options !== undefined && ts.isNewExpression(options)) {\n const token = options.arguments?.[0];\n if (token !== undefined && token.kind !== ts.SyntaxKind.UndefinedKeyword && token.getText() !== 'undefined')\n return token;\n }\n return call.arguments[0];\n }\n}\n"]}
@@ -23,7 +23,8 @@ export declare class WiringSourceExtractor {
23
23
  */
24
24
  private facts;
25
25
  /**
26
- * binder.bindExternal(Api, VendorImpl): the vendor contract's identity comes from the resolved
26
+ * binder.bindExternal(Api, VendorImpl) — browser: binder.bindExternal(Api, new UseClass(V)
27
+ * | new UseExisting(T)), recognized by the same name: the vendor contract's identity comes from the resolved
27
28
  * symbol, exactly like any other API. An APPLICATION owner must also prove a production business
28
29
  * consumer of it; a library module binds an adapter for whichever app selects it, so its
29
30
  * consumer lives in that app.
@@ -69,7 +69,8 @@ class WiringSourceExtractor {
69
69
  ts.forEachChild(node, (child) => this.facts(child, owner));
70
70
  }
71
71
  /**
72
- * binder.bindExternal(Api, VendorImpl): the vendor contract's identity comes from the resolved
72
+ * binder.bindExternal(Api, VendorImpl) — browser: binder.bindExternal(Api, new UseClass(V)
73
+ * | new UseExisting(T)), recognized by the same name: the vendor contract's identity comes from the resolved
73
74
  * symbol, exactly like any other API. An APPLICATION owner must also prove a production business
74
75
  * consumer of it; a library module binds an adapter for whichever app selects it, so its
75
76
  * consumer lives in that app.
@@ -224,7 +225,7 @@ class WiringSourceExtractor {
224
225
  }
225
226
  fail(message) {
226
227
  throw new rules_config_1.RuleFailError('validate-runtime-architecture', message, undefined, undefined, [
227
- new rules_config_1.Option('Declare each owner\'s Wiring/AppWiring class AND its BindModule/RouteModule classes, with their registrations (binder.createRpcClientAndBind(Api, deployment), binder.createPubSubClientAndBind, binder.bindExternal(Api, VendorImpl), binder.bind chains, browser binder.provide recipes, router.addRoutes/addFilter), together in that owner\'s canonical src/wiring.ts (an app may also select a BindModule from a library owner\'s canonical src/wiring.ts), and use the documented getter grammar (getBindModules/getRouteModules/getWirings); extraction reads only canonical wiring.ts files and never executes configuration.', true),
228
+ new rules_config_1.Option('Declare each owner\'s Wiring/AppWiring class AND its BindModule/RouteModule classes, with their registrations (binder.createRpcClientAndBind(Api, deployment), binder.createPubSubClientAndBind, binder.bindExternal(Api, VendorImpl) or the browser binder.bindExternal(Api, new UseClass(Vendor) | new UseExisting(Token)), binder.bind chains, browser binder.provide recipes, router.addRoutes/addFilter), together in that owner\'s canonical src/wiring.ts (an app may also select a BindModule from a library owner\'s canonical src/wiring.ts), and use the documented getter grammar (getBindModules/getRouteModules/getWirings); extraction reads only canonical wiring.ts files and never executes configuration.', true),
228
229
  ]);
229
230
  }
230
231
  }
@@ -1 +1 @@
1
- {"version":3,"file":"source-extractor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/runtime-wiring/source-extractor.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 type { ProjectInfo } from '../project-info';\nimport { createProjectProgram } from '../di-graph/program';\nimport {\n ContractIdentity,\n ImplementsFacts,\n UsesFacts,\n RuntimeDeclaration,\n WiringExport,\n WiringRelationship,\n WiringSelection,\n} from './declaration';\nimport { WiringSourceValues } from './source-values';\nimport { WiringSourceTypes } from './source-types';\nimport type { WiringKind } from './source-types';\nimport * as fs from 'fs';\n\n/** Build-only extraction. It never imports application modules or invokes their constructors. */\nclass WiringProjectMetadata {\n declare metadata?: WiringProjectMetadataValues;\n}\nclass WiringProjectMetadataValues {\n declare webpieces?: WiringServiceMetadata;\n}\nclass WiringServiceMetadata {\n declare serviceName?: string;\n}\n\nexport class WiringSourceExtractor {\n private readonly values: WiringSourceValues;\n private readonly exported: Record<string, WiringExport> = {};\n private entry: string | undefined;\n private host: string | undefined;\n\n constructor(\n private readonly workspaceRoot: string,\n private readonly info: ProjectInfo,\n private readonly infos: ReadonlyMap<string, ProjectInfo>,\n private readonly program: ts.Program,\n ) {\n this.values = new WiringSourceValues(workspaceRoot, infos, program.getTypeChecker());\n }\n\n /**\n * Reads ONLY the owner's canonical src/wiring.ts. The program still type-checks every file so\n * imports, aliases and re-exports resolve, but no other file's body is visited for wiring facts:\n * a module declared elsewhere can neither add a relationship nor be discovered as a fallback.\n */\n extract(): RuntimeDeclaration {\n const wiring = this.program.getSourceFile(this.wiringPath);\n if (wiring === undefined) this.fail(`Missing canonical ${this.wiringPath}.`);\n for (const statement of wiring!.statements)\n if (ts.isClassDeclaration(statement)) this.recordWiring(statement);\n const framework = this.info.tags.includes('framework:angular')\n ? 'angular'\n : this.info.tags.some((tag) => tag === 'framework:node' || tag === 'framework:express')\n ? 'node'\n : 'browser';\n if (this.info.tags.includes('webpieces') && this.entry === undefined)\n this.fail(`${this.info.name} requires one unambiguous exported AppWiring in src/wiring.ts.`);\n return new RuntimeDeclaration(\n this.info.name,\n framework,\n this.exported,\n this.entry,\n this.host,\n );\n }\n\n /**\n * The registration forms that carry graph facts: binder.createRpcClientAndBind /\n * createPubSubClientAndBind / bindExternal and router.addRoutes (plus the factory calls they wrap).\n */\n private facts(node: ts.Node, owner: string): void {\n if (ts.isCallExpression(node) && this.frameworkCall(node)) {\n const name = this.values.symbolName(node.expression);\n if (name === 'bindExternal') this.recordExternal(node, owner);\n else if (['addRoutes', 'createRpcClient', 'createPubSubClient', 'createRpcClientAndBind', 'createPubSubClientAndBind'].includes(name))\n this.recordRelationship(node, name, owner);\n }\n ts.forEachChild(node, (child: ts.Node) => this.facts(child, owner));\n }\n\n /**\n * binder.bindExternal(Api, VendorImpl): the vendor contract's identity comes from the resolved\n * symbol, exactly like any other API. An APPLICATION owner must also prove a production business\n * consumer of it; a library module binds an adapter for whichever app selects it, so its\n * consumer lives in that app.\n */\n private recordExternal(call: ts.CallExpression, owner: string): void {\n const api = call.arguments[0];\n if (api === undefined || call.arguments[1] === undefined)\n this.fail('bindExternal requires the external API contract and its vendor implementation.');\n const contract = this.values.identity(api!);\n if (\n this.info.tags.includes('webpieces') &&\n !this.values.hasExternalConsumer(this.info.name, contract.project, contract.exportedName, this.program)\n )\n this.fail(\n `${contract.project}#${contract.exportedName} has no production business consumer in ${this.info.name}; adapters and test doubles do not establish uses.`,\n );\n const exported = this.exported[owner];\n exported.relationships.push(\n new WiringRelationship(\n contract,\n new UsesFacts('external', {\n kind: 'unknown',\n reason: 'Vendor interface; destination classified by approved contract metadata',\n }),\n ),\n );\n this.exported[owner] = exported;\n }\n\n private recordRelationship(call: ts.CallExpression, method: string, owner: string): void {\n const api = call.arguments[0];\n if (api === undefined) this.fail(`${method} requires an explicit API contract.`);\n const contract = this.values.identity(api!);\n const direction = method === 'addRoutes' ? 'implements' : 'uses';\n const contractTransport = this.values.transport(api!);\n const transport =\n method === 'addRoutes'\n ? contractTransport\n : method === 'createPubSubClientAndBind' || method === 'createPubSubClient'\n ? 'pubsub'\n : 'rpc';\n if (transport !== contractTransport)\n this.fail(\n `${method} transport disagrees with ${contract.project}#${contract.exportedName}.`,\n );\n const target =\n direction === 'implements'\n ? undefined\n : this.values.target(call.arguments[1]);\n const exported = this.exported[owner];\n exported.relationships.push(\n new WiringRelationship(\n contract,\n direction === 'implements'\n ? new ImplementsFacts(transport, this.values.condition(call))\n : new UsesFacts(transport, target!, this.values.condition(call)),\n ),\n );\n this.exported[owner] = exported;\n }\n\n private frameworkCall(call: ts.CallExpression): boolean {\n const declaration = this.program.getTypeChecker().getResolvedSignature(call)?.declaration;\n if (declaration === undefined) return false;\n const file = declaration.getSourceFile().fileName.replace(/\\\\/g, '/');\n return /(?:\\/packages\\/(?:http|cloud)\\/|\\/node_modules\\/@webpieces\\/)(?:http-routing|http-client-node|http-client-browser|cloudtasks-client)\\//.test(file);\n }\n\n private recordWiring(declaration: ts.ClassDeclaration): void {\n const types = new WiringSourceTypes(this.program.getTypeChecker());\n const kind = types.kind(declaration);\n const owner = this.exportOwner(declaration);\n if (kind === undefined || owner === undefined) return;\n if (kind === 'binding' || kind === 'routing') {\n this.exported[owner] = new WiringExport(kind, [], []);\n const configure = types.method(declaration, 'configure');\n if (configure === undefined || configure.body === undefined)\n this.fail(`${owner}: named module requires a statically resolvable configure implementation.`);\n if (path.resolve(configure!.getSourceFile().fileName) !== this.wiringPath)\n this.fail(`${owner}: configure is inherited from ${configure!.getSourceFile().fileName}; declare its registrations in ${owner}.configure in ${this.wiringPath}.`);\n this.facts(configure!.body!, owner);\n return;\n }\n const bindings = this.moduleSelections(owner, types.method(declaration, 'getBindModules'), 'binding', kind);\n // The browser has no route channel; a Node Wiring's getRouteModules is required by its type.\n const routeGetter = types.method(declaration, 'getRouteModules');\n const routes = routeGetter === undefined ? [] : this.moduleSelections(owner, routeGetter, 'routing', kind);\n const libraries = kind === 'app' ? this.moduleSelections(owner, types.method(declaration, 'getWirings'), 'wiring', kind) : [];\n if (kind === 'wiring' && types.method(declaration, 'getWirings') !== undefined)\n this.fail(`${owner}: library Wiring cannot select other Wirings.`);\n this.exported[owner] = new WiringExport(kind, [], bindings, routes, libraries);\n if (kind !== 'app') return;\n if (!this.info.tags.includes('webpieces'))\n this.fail(`${owner}: library owners cannot declare an AppWiring entry.`);\n if (this.entry !== undefined) this.fail('Ambiguous AppWiring root; export exactly one application entry.');\n this.entry = owner;\n const projectFile = path.join(this.workspaceRoot, this.info.root, 'project.json');\n if (fs.existsSync(projectFile)) {\n const project = JSON.parse(fs.readFileSync(projectFile, 'utf8')) as WiringProjectMetadata;\n this.host = project.metadata?.webpieces?.serviceName;\n }\n }\n\n private moduleSelections(owner: string, method: ts.MethodDeclaration | undefined, expected: 'binding' | 'routing' | 'wiring', ownerKind: WiringKind): WiringSelection[] {\n if (method !== undefined && path.resolve(method.getSourceFile().fileName) !== this.wiringPath)\n this.fail(`${owner}: its selection getter is declared in ${method.getSourceFile().fileName}; declare getBindModules/getRouteModules/getWirings on ${owner} itself in ${this.wiringPath}.`);\n const statements = method?.body?.statements;\n const expression = statements?.length === 1 && ts.isReturnStatement(statements[0]) ? statements[0].expression : undefined;\n if (expression === undefined || !ts.isArrayLiteralExpression(expression))\n this.fail(`Expected ${expected} getter to contain only return [new NamedModule(preparedInputs)].`);\n const types = new WiringSourceTypes(this.program.getTypeChecker());\n return expression.elements.map((element: ts.Expression) => {\n if (!ts.isNewExpression(element) || types.kind(element.expression) !== expected)\n this.fail(`Wrong ${expected} selection ${element.getText()}; AppWiring children, delegation and nested lists are forbidden.`);\n const identity = this.values.identity(element.expression);\n this.assertCanonicalDeclaration(owner, element.expression, identity, expected, ownerKind);\n return new WiringSelection(identity.project, identity.exportedName, this.values.arguments(element), this.values.policies(element));\n });\n }\n\n /**\n * OWNER-canonical: a selected module is declared in THIS wiring.ts, or - for a BindModule an\n * AppWiring selects, and for a library Wiring - in its library owner's canonical src/wiring.ts.\n * Proven by the resolved declaration (so a re-export resolves to its true file), never by a name,\n * and checked before any argument analysis, so an off-file module body is never read.\n */\n private assertCanonicalDeclaration(\n owner: string,\n selected: ts.Expression,\n identity: ContractIdentity,\n expected: 'binding' | 'routing' | 'wiring',\n ownerKind: WiringKind,\n ): void {\n const declaration = new WiringSourceTypes(this.program.getTypeChecker()).declaration(selected);\n const declaredIn = declaration === undefined ? 'an unresolved file' : path.resolve(declaration.getSourceFile().fileName);\n if (declaredIn === this.wiringPath && expected !== 'wiring') return;\n const library = this.infos.get(identity.project);\n const canonical = library === undefined ? undefined : path.resolve(this.workspaceRoot, library.root, 'src/wiring.ts');\n const fromLibrary = identity.project !== this.info.name && canonical !== undefined && declaredIn === canonical;\n if (expected === 'wiring' && fromLibrary) return;\n if (expected === 'binding' && ownerKind === 'app' && fromLibrary) return;\n if (expected === 'wiring')\n this.fail(\n `${owner} selects library Wiring ${identity.project}#${identity.exportedName}, which is declared in ${declaredIn}. A library Wiring and its modules belong in that library's canonical ${canonical ?? 'src/wiring.ts'}.`,\n );\n const role = expected === 'binding' ? 'BindModule' : 'RouteModule';\n const where = expected === 'binding' && ownerKind === 'app'\n ? ` beside ${owner} in ${this.wiringPath}, or in its library owner's canonical src/wiring.ts`\n : ` beside ${owner} in ${this.wiringPath}`;\n this.fail(\n `${owner} selects ${identity.exportedName}, which is declared in ${declaredIn}. Declare the ${role} class ${identity.exportedName}, with its registrations,${where}; a ContainerModule or a class in any other file is never a module.`,\n );\n }\n\n private exportOwner(node: ts.Node): string | undefined {\n let current: ts.Node | undefined = node;\n while (current !== undefined) {\n if (\n ts.isClassDeclaration(current) &&\n current.name !== undefined &&\n (ts.getModifiers(current) ?? []).some(\n (modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword,\n )\n )\n return current.name.text;\n if (\n ts.isFunctionDeclaration(current) &&\n current.name !== undefined &&\n (ts.getModifiers(current) ?? []).some(\n (modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword,\n )\n )\n return current.name.text;\n if (ts.isVariableDeclaration(current) && ts.isIdentifier(current.name)) {\n const statement = current.parent.parent;\n if (\n ts.isVariableStatement(statement) &&\n (ts.getModifiers(statement) ?? []).some(\n (modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword,\n )\n )\n return current.name.text;\n }\n current = current.parent;\n }\n return undefined;\n }\n\n private get wiringPath(): string {\n return path.resolve(this.workspaceRoot, this.info.root, 'src/wiring.ts');\n }\n\n private fail(message: string): never {\n throw new RuleFailError('validate-runtime-architecture', message, undefined, undefined, [\n new Option(\n 'Declare each owner\\'s Wiring/AppWiring class AND its BindModule/RouteModule classes, with their registrations (binder.createRpcClientAndBind(Api, deployment), binder.createPubSubClientAndBind, binder.bindExternal(Api, VendorImpl), binder.bind chains, browser binder.provide recipes, router.addRoutes/addFilter), together in that owner\\'s canonical src/wiring.ts (an app may also select a BindModule from a library owner\\'s canonical src/wiring.ts), and use the documented getter grammar (getBindModules/getRouteModules/getWirings); extraction reads only canonical wiring.ts files and never executes configuration.',\n true,\n ),\n ]);\n }\n}\n\n/** Factory kept separate so graph assembly cannot accidentally create a compiler. */\nexport class WiringProjectProgram {\n create(workspaceRoot: string, info: ProjectInfo): ts.Program {\n const root = path.resolve(workspaceRoot, info.root);\n const configured = createProjectProgram(root);\n if (configured !== null) return configured;\n const config = ts.findConfigFile(root, ts.sys.fileExists, 'tsconfig.json');\n const parsed =\n config === undefined ? undefined : ts.readConfigFile(config, ts.sys.readFile);\n const options =\n parsed === undefined\n ? {}\n : ts.parseJsonConfigFileContent(parsed.config, ts.sys, root).options;\n const files = ts.sys.readDirectory(\n path.join(root, 'src'),\n ['.ts'],\n ['**/*.spec.ts', '**/*.test.ts'],\n );\n return ts.createProgram(files, options);\n }\n}\n"]}
1
+ {"version":3,"file":"source-extractor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/runtime-wiring/source-extractor.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 type { ProjectInfo } from '../project-info';\nimport { createProjectProgram } from '../di-graph/program';\nimport {\n ContractIdentity,\n ImplementsFacts,\n UsesFacts,\n RuntimeDeclaration,\n WiringExport,\n WiringRelationship,\n WiringSelection,\n} from './declaration';\nimport { WiringSourceValues } from './source-values';\nimport { WiringSourceTypes } from './source-types';\nimport type { WiringKind } from './source-types';\nimport * as fs from 'fs';\n\n/** Build-only extraction. It never imports application modules or invokes their constructors. */\nclass WiringProjectMetadata {\n declare metadata?: WiringProjectMetadataValues;\n}\nclass WiringProjectMetadataValues {\n declare webpieces?: WiringServiceMetadata;\n}\nclass WiringServiceMetadata {\n declare serviceName?: string;\n}\n\nexport class WiringSourceExtractor {\n private readonly values: WiringSourceValues;\n private readonly exported: Record<string, WiringExport> = {};\n private entry: string | undefined;\n private host: string | undefined;\n\n constructor(\n private readonly workspaceRoot: string,\n private readonly info: ProjectInfo,\n private readonly infos: ReadonlyMap<string, ProjectInfo>,\n private readonly program: ts.Program,\n ) {\n this.values = new WiringSourceValues(workspaceRoot, infos, program.getTypeChecker());\n }\n\n /**\n * Reads ONLY the owner's canonical src/wiring.ts. The program still type-checks every file so\n * imports, aliases and re-exports resolve, but no other file's body is visited for wiring facts:\n * a module declared elsewhere can neither add a relationship nor be discovered as a fallback.\n */\n extract(): RuntimeDeclaration {\n const wiring = this.program.getSourceFile(this.wiringPath);\n if (wiring === undefined) this.fail(`Missing canonical ${this.wiringPath}.`);\n for (const statement of wiring!.statements)\n if (ts.isClassDeclaration(statement)) this.recordWiring(statement);\n const framework = this.info.tags.includes('framework:angular')\n ? 'angular'\n : this.info.tags.some((tag) => tag === 'framework:node' || tag === 'framework:express')\n ? 'node'\n : 'browser';\n if (this.info.tags.includes('webpieces') && this.entry === undefined)\n this.fail(`${this.info.name} requires one unambiguous exported AppWiring in src/wiring.ts.`);\n return new RuntimeDeclaration(\n this.info.name,\n framework,\n this.exported,\n this.entry,\n this.host,\n );\n }\n\n /**\n * The registration forms that carry graph facts: binder.createRpcClientAndBind /\n * createPubSubClientAndBind / bindExternal and router.addRoutes (plus the factory calls they wrap).\n */\n private facts(node: ts.Node, owner: string): void {\n if (ts.isCallExpression(node) && this.frameworkCall(node)) {\n const name = this.values.symbolName(node.expression);\n if (name === 'bindExternal') this.recordExternal(node, owner);\n else if (['addRoutes', 'createRpcClient', 'createPubSubClient', 'createRpcClientAndBind', 'createPubSubClientAndBind'].includes(name))\n this.recordRelationship(node, name, owner);\n }\n ts.forEachChild(node, (child: ts.Node) => this.facts(child, owner));\n }\n\n /**\n * binder.bindExternal(Api, VendorImpl) — browser: binder.bindExternal(Api, new UseClass(V)\n * | new UseExisting(T)), recognized by the same name: the vendor contract's identity comes from the resolved\n * symbol, exactly like any other API. An APPLICATION owner must also prove a production business\n * consumer of it; a library module binds an adapter for whichever app selects it, so its\n * consumer lives in that app.\n */\n private recordExternal(call: ts.CallExpression, owner: string): void {\n const api = call.arguments[0];\n if (api === undefined || call.arguments[1] === undefined)\n this.fail('bindExternal requires the external API contract and its vendor implementation.');\n const contract = this.values.identity(api!);\n if (\n this.info.tags.includes('webpieces') &&\n !this.values.hasExternalConsumer(this.info.name, contract.project, contract.exportedName, this.program)\n )\n this.fail(\n `${contract.project}#${contract.exportedName} has no production business consumer in ${this.info.name}; adapters and test doubles do not establish uses.`,\n );\n const exported = this.exported[owner];\n exported.relationships.push(\n new WiringRelationship(\n contract,\n new UsesFacts('external', {\n kind: 'unknown',\n reason: 'Vendor interface; destination classified by approved contract metadata',\n }),\n ),\n );\n this.exported[owner] = exported;\n }\n\n private recordRelationship(call: ts.CallExpression, method: string, owner: string): void {\n const api = call.arguments[0];\n if (api === undefined) this.fail(`${method} requires an explicit API contract.`);\n const contract = this.values.identity(api!);\n const direction = method === 'addRoutes' ? 'implements' : 'uses';\n const contractTransport = this.values.transport(api!);\n const transport =\n method === 'addRoutes'\n ? contractTransport\n : method === 'createPubSubClientAndBind' || method === 'createPubSubClient'\n ? 'pubsub'\n : 'rpc';\n if (transport !== contractTransport)\n this.fail(\n `${method} transport disagrees with ${contract.project}#${contract.exportedName}.`,\n );\n const target =\n direction === 'implements'\n ? undefined\n : this.values.target(call.arguments[1]);\n const exported = this.exported[owner];\n exported.relationships.push(\n new WiringRelationship(\n contract,\n direction === 'implements'\n ? new ImplementsFacts(transport, this.values.condition(call))\n : new UsesFacts(transport, target!, this.values.condition(call)),\n ),\n );\n this.exported[owner] = exported;\n }\n\n private frameworkCall(call: ts.CallExpression): boolean {\n const declaration = this.program.getTypeChecker().getResolvedSignature(call)?.declaration;\n if (declaration === undefined) return false;\n const file = declaration.getSourceFile().fileName.replace(/\\\\/g, '/');\n return /(?:\\/packages\\/(?:http|cloud)\\/|\\/node_modules\\/@webpieces\\/)(?:http-routing|http-client-node|http-client-browser|cloudtasks-client)\\//.test(file);\n }\n\n private recordWiring(declaration: ts.ClassDeclaration): void {\n const types = new WiringSourceTypes(this.program.getTypeChecker());\n const kind = types.kind(declaration);\n const owner = this.exportOwner(declaration);\n if (kind === undefined || owner === undefined) return;\n if (kind === 'binding' || kind === 'routing') {\n this.exported[owner] = new WiringExport(kind, [], []);\n const configure = types.method(declaration, 'configure');\n if (configure === undefined || configure.body === undefined)\n this.fail(`${owner}: named module requires a statically resolvable configure implementation.`);\n if (path.resolve(configure!.getSourceFile().fileName) !== this.wiringPath)\n this.fail(`${owner}: configure is inherited from ${configure!.getSourceFile().fileName}; declare its registrations in ${owner}.configure in ${this.wiringPath}.`);\n this.facts(configure!.body!, owner);\n return;\n }\n const bindings = this.moduleSelections(owner, types.method(declaration, 'getBindModules'), 'binding', kind);\n // The browser has no route channel; a Node Wiring's getRouteModules is required by its type.\n const routeGetter = types.method(declaration, 'getRouteModules');\n const routes = routeGetter === undefined ? [] : this.moduleSelections(owner, routeGetter, 'routing', kind);\n const libraries = kind === 'app' ? this.moduleSelections(owner, types.method(declaration, 'getWirings'), 'wiring', kind) : [];\n if (kind === 'wiring' && types.method(declaration, 'getWirings') !== undefined)\n this.fail(`${owner}: library Wiring cannot select other Wirings.`);\n this.exported[owner] = new WiringExport(kind, [], bindings, routes, libraries);\n if (kind !== 'app') return;\n if (!this.info.tags.includes('webpieces'))\n this.fail(`${owner}: library owners cannot declare an AppWiring entry.`);\n if (this.entry !== undefined) this.fail('Ambiguous AppWiring root; export exactly one application entry.');\n this.entry = owner;\n const projectFile = path.join(this.workspaceRoot, this.info.root, 'project.json');\n if (fs.existsSync(projectFile)) {\n const project = JSON.parse(fs.readFileSync(projectFile, 'utf8')) as WiringProjectMetadata;\n this.host = project.metadata?.webpieces?.serviceName;\n }\n }\n\n private moduleSelections(owner: string, method: ts.MethodDeclaration | undefined, expected: 'binding' | 'routing' | 'wiring', ownerKind: WiringKind): WiringSelection[] {\n if (method !== undefined && path.resolve(method.getSourceFile().fileName) !== this.wiringPath)\n this.fail(`${owner}: its selection getter is declared in ${method.getSourceFile().fileName}; declare getBindModules/getRouteModules/getWirings on ${owner} itself in ${this.wiringPath}.`);\n const statements = method?.body?.statements;\n const expression = statements?.length === 1 && ts.isReturnStatement(statements[0]) ? statements[0].expression : undefined;\n if (expression === undefined || !ts.isArrayLiteralExpression(expression))\n this.fail(`Expected ${expected} getter to contain only return [new NamedModule(preparedInputs)].`);\n const types = new WiringSourceTypes(this.program.getTypeChecker());\n return expression.elements.map((element: ts.Expression) => {\n if (!ts.isNewExpression(element) || types.kind(element.expression) !== expected)\n this.fail(`Wrong ${expected} selection ${element.getText()}; AppWiring children, delegation and nested lists are forbidden.`);\n const identity = this.values.identity(element.expression);\n this.assertCanonicalDeclaration(owner, element.expression, identity, expected, ownerKind);\n return new WiringSelection(identity.project, identity.exportedName, this.values.arguments(element), this.values.policies(element));\n });\n }\n\n /**\n * OWNER-canonical: a selected module is declared in THIS wiring.ts, or - for a BindModule an\n * AppWiring selects, and for a library Wiring - in its library owner's canonical src/wiring.ts.\n * Proven by the resolved declaration (so a re-export resolves to its true file), never by a name,\n * and checked before any argument analysis, so an off-file module body is never read.\n */\n private assertCanonicalDeclaration(\n owner: string,\n selected: ts.Expression,\n identity: ContractIdentity,\n expected: 'binding' | 'routing' | 'wiring',\n ownerKind: WiringKind,\n ): void {\n const declaration = new WiringSourceTypes(this.program.getTypeChecker()).declaration(selected);\n const declaredIn = declaration === undefined ? 'an unresolved file' : path.resolve(declaration.getSourceFile().fileName);\n if (declaredIn === this.wiringPath && expected !== 'wiring') return;\n const library = this.infos.get(identity.project);\n const canonical = library === undefined ? undefined : path.resolve(this.workspaceRoot, library.root, 'src/wiring.ts');\n const fromLibrary = identity.project !== this.info.name && canonical !== undefined && declaredIn === canonical;\n if (expected === 'wiring' && fromLibrary) return;\n if (expected === 'binding' && ownerKind === 'app' && fromLibrary) return;\n if (expected === 'wiring')\n this.fail(\n `${owner} selects library Wiring ${identity.project}#${identity.exportedName}, which is declared in ${declaredIn}. A library Wiring and its modules belong in that library's canonical ${canonical ?? 'src/wiring.ts'}.`,\n );\n const role = expected === 'binding' ? 'BindModule' : 'RouteModule';\n const where = expected === 'binding' && ownerKind === 'app'\n ? ` beside ${owner} in ${this.wiringPath}, or in its library owner's canonical src/wiring.ts`\n : ` beside ${owner} in ${this.wiringPath}`;\n this.fail(\n `${owner} selects ${identity.exportedName}, which is declared in ${declaredIn}. Declare the ${role} class ${identity.exportedName}, with its registrations,${where}; a ContainerModule or a class in any other file is never a module.`,\n );\n }\n\n private exportOwner(node: ts.Node): string | undefined {\n let current: ts.Node | undefined = node;\n while (current !== undefined) {\n if (\n ts.isClassDeclaration(current) &&\n current.name !== undefined &&\n (ts.getModifiers(current) ?? []).some(\n (modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword,\n )\n )\n return current.name.text;\n if (\n ts.isFunctionDeclaration(current) &&\n current.name !== undefined &&\n (ts.getModifiers(current) ?? []).some(\n (modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword,\n )\n )\n return current.name.text;\n if (ts.isVariableDeclaration(current) && ts.isIdentifier(current.name)) {\n const statement = current.parent.parent;\n if (\n ts.isVariableStatement(statement) &&\n (ts.getModifiers(statement) ?? []).some(\n (modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword,\n )\n )\n return current.name.text;\n }\n current = current.parent;\n }\n return undefined;\n }\n\n private get wiringPath(): string {\n return path.resolve(this.workspaceRoot, this.info.root, 'src/wiring.ts');\n }\n\n private fail(message: string): never {\n throw new RuleFailError('validate-runtime-architecture', message, undefined, undefined, [\n new Option(\n 'Declare each owner\\'s Wiring/AppWiring class AND its BindModule/RouteModule classes, with their registrations (binder.createRpcClientAndBind(Api, deployment), binder.createPubSubClientAndBind, binder.bindExternal(Api, VendorImpl) or the browser binder.bindExternal(Api, new UseClass(Vendor) | new UseExisting(Token)), binder.bind chains, browser binder.provide recipes, router.addRoutes/addFilter), together in that owner\\'s canonical src/wiring.ts (an app may also select a BindModule from a library owner\\'s canonical src/wiring.ts), and use the documented getter grammar (getBindModules/getRouteModules/getWirings); extraction reads only canonical wiring.ts files and never executes configuration.',\n true,\n ),\n ]);\n }\n}\n\n/** Factory kept separate so graph assembly cannot accidentally create a compiler. */\nexport class WiringProjectProgram {\n create(workspaceRoot: string, info: ProjectInfo): ts.Program {\n const root = path.resolve(workspaceRoot, info.root);\n const configured = createProjectProgram(root);\n if (configured !== null) return configured;\n const config = ts.findConfigFile(root, ts.sys.fileExists, 'tsconfig.json');\n const parsed =\n config === undefined ? undefined : ts.readConfigFile(config, ts.sys.readFile);\n const options =\n parsed === undefined\n ? {}\n : ts.parseJsonConfigFileContent(parsed.config, ts.sys, root).options;\n const files = ts.sys.readDirectory(\n path.join(root, 'src'),\n ['.ts'],\n ['**/*.spec.ts', '**/*.test.ts'],\n );\n return ts.createProgram(files, options);\n }\n}\n"]}
@@ -203,11 +203,11 @@ class WiringFormat {
203
203
  return;
204
204
  }
205
205
  if (LEGACY_TOPOLOGY.test(expression.getText())) {
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).');
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) (browser: binder.bindExternal(Api, new UseClass(Vendor) | new UseExisting(Token))).');
207
207
  return;
208
208
  }
209
209
  if (!this.registration(expression, scope)) {
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.');
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: new UseClass(Vendor) | new UseExisting(Token)), 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.');
211
211
  return;
212
212
  }
213
213
  for (const argument of this.registrationArguments(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/**\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"]}
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) (browser: binder.bindExternal(Api, new UseClass(Vendor) | new UseExisting(Token))).');\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: new UseClass(Vendor) | new UseExisting(Token)), 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
@@ -10,7 +10,7 @@ exports.ruleHelp = {
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 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.'),
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) and binder.bindExternal(Api, new UseClass(Vendor) | new UseExisting(Token)) 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.'),
@@ -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,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"]}
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,gqBAAgqB,CACnqB;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) and binder.bindExternal(Api, new UseClass(Vendor) | new UseExisting(Token)) 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"]}