@webpieces/nx-webpieces-rules 0.4.869 → 0.4.870
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -7
- package/src/lib/di-graph/runtime-client-bindings.d.ts +13 -3
- package/src/lib/di-graph/runtime-client-bindings.js +53 -25
- package/src/lib/di-graph/runtime-client-bindings.js.map +1 -1
- package/src/lib/di-graph/token-resolver.js +0 -14
- package/src/lib/di-graph/token-resolver.js.map +1 -1
- package/src/lib/runtime-wiring/assembler.js +3 -3
- package/src/lib/runtime-wiring/assembler.js.map +1 -1
- package/src/lib/runtime-wiring/canonical-clients.d.ts +2 -0
- package/src/lib/runtime-wiring/canonical-clients.js +12 -6
- package/src/lib/runtime-wiring/canonical-clients.js.map +1 -1
- package/src/lib/runtime-wiring/codec.d.ts +1 -0
- package/src/lib/runtime-wiring/codec.js +10 -3
- package/src/lib/runtime-wiring/codec.js.map +1 -1
- package/src/lib/runtime-wiring/declaration.d.ts +3 -3
- package/src/lib/runtime-wiring/declaration.js +5 -5
- package/src/lib/runtime-wiring/declaration.js.map +1 -1
- package/src/lib/runtime-wiring/prepared-targets.js +4 -4
- package/src/lib/runtime-wiring/prepared-targets.js.map +1 -1
- package/src/lib/runtime-wiring/source-extractor.d.ts +14 -3
- package/src/lib/runtime-wiring/source-extractor.js +52 -41
- package/src/lib/runtime-wiring/source-extractor.js.map +1 -1
- package/src/lib/runtime-wiring/source-types.js +1 -1
- package/src/lib/runtime-wiring/source-types.js.map +1 -1
- package/src/lib/runtime-wiring/wiring-format.d.ts +9 -7
- package/src/lib/runtime-wiring/wiring-format.js +52 -56
- package/src/lib/runtime-wiring/wiring-format.js.map +1 -1
- package/src/rule-help.js +2 -2
- package/src/rule-help.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/runtime-wiring/codec.ts"],"names":[],"mappings":"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","sourcesContent":["import { toError } from '../../toError';\nimport { Option, RuleFailError } from '@webpieces/rules-config';\nimport {\n ContractIdentity,\n ImplementsFacts,\n UsesFacts,\n RuntimeDeclaration,\n WiringExport,\n WiringRelationship,\n WiringSelection,\n} from './declaration';\nimport type { DeclaredTarget, PolicyValue } from './declaration';\nimport { isExternalSystemKind } from '../api-usage/api-relations';\n\n/** JSON is validated before it is allowed to influence graph assembly. */\nexport class RuntimeDeclarationCodec {\n decode(text: string, expectedProject: string): RuntimeDeclaration {\n const root = this.record(this.parse(text, expectedProject), [\n 'schemaVersion',\n 'project',\n 'framework',\n 'exports',\n 'entry',\n 'host',\n ]);\n if (root['schemaVersion'] !== 2)\n this.fail('Unsupported runtime-deps schemaVersion; migrate src/wiring.ts to Wiring/AppWiring and explicitly review a version 2 candidate.');\n if (root['project'] !== expectedProject)\n this.fail(`Expected project ${expectedProject}, found ${String(root['project'])}.`);\n const framework = this.string(root['framework']);\n if (framework !== 'node' && framework !== 'angular' && framework !== 'browser')\n this.fail(`Unsupported framework ${framework}.`);\n const exports: Record<string, WiringExport> = {};\n for (const [name, value] of Object.entries(this.record(root['exports'])))\n exports[name] = this.exported(value);\n const entry = root['entry'] === undefined ? undefined : this.string(root['entry']);\n const apps = Object.values(exports).filter((exported: WiringExport) => exported.kind === 'app');\n if ((entry === undefined && apps.length > 0) || (entry !== undefined && apps.length !== 1))\n this.fail('Declare exactly one AppWiring entry for an application; libraries export Wiring without an entry.');\n if (entry !== undefined && exports[entry]?.kind !== 'app')\n this.fail('A runtime entry must select an AppWiring export. Libraries have no entry.');\n if (entry === undefined && root['host'] !== undefined)\n this.fail('Library declarations cannot carry an application host.');\n for (const [name, exported] of Object.entries(exports)) {\n if (exported.kind !== 'app' && exported.wirings.length > 0)\n this.fail(`${name}: only AppWiring may select library Wirings.`);\n if (!['app', 'wiring'].includes(exported.kind) &&\n (exported.bindingModules.length > 0 || exported.routingModules.length > 0))\n this.fail(`${name}: leaf modules cannot select module lists.`);\n if (['app', 'wiring'].includes(exported.kind) && exported.relationships.length > 0)\n this.fail(`${name}: declare relationships in named binding/route modules.`);\n }\n return new RuntimeDeclaration(\n expectedProject,\n framework,\n exports,\n root['entry'] === undefined ? undefined : this.string(root['entry']),\n root['host'] === undefined ? undefined : this.string(root['host']),\n );\n }\n\n // webpieces-disable no-any-unknown -- JSON syntax boundary; fields are narrowed by decode\n private parse(text: string, project: string): unknown {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return JSON.parse(text);\n } catch (err: unknown) {\n const error = toError(err);\n this.fail(`${project}/runtime-deps.json contains invalid JSON.`, error);\n }\n }\n\n // webpieces-disable no-any-unknown -- untrusted JSON is narrowed and validated at the input boundary\n private exported(value: unknown): WiringExport {\n const exported = this.record(value, ['kind', 'relationships', 'bindingModules', 'routingModules', 'wirings']);\n const kind = this.string(exported['kind']);\n if (\n kind !== 'binding' &&\n kind !== 'routing' &&\n kind !== 'wiring' &&\n kind !== 'app' &&\n kind !== 'external'\n )\n this.fail(`Invalid export kind ${kind}.`);\n return new WiringExport(\n kind,\n this.array(exported['relationships']).map((value) => this.relationship(value)),\n this.array(exported['bindingModules']).map((value) => this.selection(value)),\n this.array(exported['routingModules']).map((value) => this.selection(value)),\n this.array(exported['wirings']).map((value) => this.selection(value)),\n );\n }\n\n // webpieces-disable no-any-unknown -- untrusted relationship JSON is narrowed before construction\n private relationship(value: unknown): WiringRelationship {\n const relation = this.record(value, [\n 'contract',\n 'direction',\n 'transport',\n 'target',\n 'policy',\n ]);\n const contract = this.record(relation['contract'], ['project', 'exportedName']);\n const direction = this.string(relation['direction']);\n const transport = this.string(relation['transport']);\n if (direction !== 'implements' && direction !== 'uses')\n this.fail(`Invalid direction ${direction}.`);\n if (transport !== 'rpc' && transport !== 'pubsub' && transport !== 'external')\n this.fail(`Invalid transport ${transport}.`);\n const target =\n relation['target'] === undefined ? undefined : this.target(relation['target']);\n const policy =\n relation['policy'] === undefined ? undefined : this.string(relation['policy']);\n if (direction === 'uses' && target === undefined)\n this.fail('Uses requires an explicit target.');\n if (direction === 'implements' && target !== undefined)\n this.fail('Implements cannot declare a client target.');\n return new WiringRelationship(\n new ContractIdentity(\n this.string(contract['project']),\n this.string(contract['exportedName']),\n ),\n direction === 'uses'\n ? new UsesFacts(transport, target!, policy)\n : new ImplementsFacts(transport, policy),\n );\n }\n\n // webpieces-disable no-any-unknown -- untrusted selection arguments are validated before substitution\n private selection(value: unknown): WiringSelection {\n const selection = this.record(value, ['project', 'exportedName', 'targets', 'policies']);\n const targets: Record<string, DeclaredTarget> = {};\n const policies: Record<string, PolicyValue> = {};\n for (const [name, target] of Object.entries(this.record(selection['targets'])))\n targets[name] = this.target(target);\n for (const [name, policy] of Object.entries(this.record(selection['policies']))) {\n if (typeof policy === 'boolean' || policy === 'runtime') policies[name] = policy;\n else {\n const forwarded = this.record(policy, ['parameter']);\n policies[name] = { parameter: this.string(forwarded['parameter']) };\n }\n }\n return new WiringSelection(\n this.string(selection['project']),\n this.string(selection['exportedName']),\n targets,\n policies,\n );\n }\n\n // webpieces-disable no-any-unknown -- target discriminant controls the exact accepted JSON shape\n private target(value: unknown): DeclaredTarget {\n const target = this.record(value);\n switch (target['kind']) {\n case 'service': {\n this.record(value, ['kind', 'service', 'contract']);\n const contract =\n target['contract'] === undefined\n ? undefined\n : this.record(target['contract'], ['project', 'exportedName']);\n return {\n kind: 'service',\n service: this.string(target['service']),\n contract:\n contract === undefined\n ? undefined\n : new ContractIdentity(\n this.string(contract['project']),\n this.string(contract['exportedName']),\n ),\n };\n }\n case 'parameter':\n this.record(value, ['kind', 'parameter']);\n return { kind: 'parameter', parameter: this.string(target['parameter']) };\n case 'unknown':\n this.record(value, ['kind', 'reason']);\n return { kind: 'unknown', reason: this.string(target['reason']) };\n case 'external': {\n this.record(value, ['kind', 'system']);\n const system = this.record(target['system'], ['kind', 'label']);\n const kind = this.string(system['kind']);\n if (!isExternalSystemKind(kind)) this.fail(`Invalid external system kind ${kind}.`);\n return { kind: 'external', system: { kind, label: this.string(system['label']) } };\n }\n default:\n return this.fail(\n 'Targets require an explicit service, parameter, external, or unknown kind.',\n );\n }\n }\n\n // webpieces-disable no-any-unknown -- JSON record boundary; never a runtime topology type\n private record(value: unknown, allowed?: readonly string[]): Record<string, unknown> {\n if (value === null || typeof value !== 'object' || Array.isArray(value))\n this.fail('Expected a JSON object.');\n const record = value as Record<string, unknown>;\n for (const key of Object.keys(record))\n if (['__proto__', 'constructor', 'prototype'].includes(key))\n this.fail(`Reserved runtime-deps field ${key}.`);\n if (allowed !== undefined)\n for (const key of Object.keys(record))\n if (!allowed.includes(key)) this.fail(`Unknown runtime-deps field ${key}.`);\n return record;\n }\n\n // webpieces-disable no-any-unknown -- JSON array boundary\n private array(value: unknown): unknown[] {\n if (!Array.isArray(value)) this.fail('Expected a JSON array.');\n return value;\n }\n\n // webpieces-disable no-any-unknown -- JSON scalar boundary\n private string(value: unknown): string {\n if (typeof value !== 'string' || value.trim() === '')\n this.fail('Expected a non-empty string.');\n return value;\n }\n\n private fail(message: string, cause?: Error): never {\n throw new RuleFailError(\n 'validate-runtime-architecture',\n message,\n undefined,\n undefined,\n [\n new Option(\n 'Review and correct runtime-deps.json using the versioned runtime wiring schema.',\n true,\n ),\n ],\n undefined,\n cause,\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/runtime-wiring/codec.ts"],"names":[],"mappings":"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","sourcesContent":["import { toError } from '../../toError';\nimport { Option, RuleFailError } from '@webpieces/rules-config';\nimport {\n ContractIdentity,\n ImplementsFacts,\n UsesFacts,\n RuntimeDeclaration,\n WiringExport,\n WiringRelationship,\n WiringSelection,\n} from './declaration';\nimport type { DeclaredTarget, PolicyValue } from './declaration';\nimport { isExternalSystemKind } from '../api-usage/api-relations';\n\n/** JSON is validated before it is allowed to influence graph assembly. */\nexport class RuntimeDeclarationCodec {\n decode(text: string, expectedProject: string): RuntimeDeclaration {\n const root = this.record(this.parse(text, expectedProject), [\n 'schemaVersion',\n 'project',\n 'framework',\n 'exports',\n 'entry',\n 'host',\n ]);\n if (root['schemaVersion'] !== 2)\n this.fail('Unsupported runtime-deps schemaVersion; migrate src/wiring.ts to Wiring/AppWiring and explicitly review a version 2 candidate.');\n if (root['project'] !== expectedProject)\n this.fail(`Expected project ${expectedProject}, found ${String(root['project'])}.`);\n const framework = this.string(root['framework']);\n if (framework !== 'node' && framework !== 'angular' && framework !== 'browser')\n this.fail(`Unsupported framework ${framework}.`);\n const exports: Record<string, WiringExport> = {};\n for (const [name, value] of Object.entries(this.record(root['exports'])))\n exports[name] = this.exported(value);\n const entry = root['entry'] === undefined ? undefined : this.string(root['entry']);\n const apps = Object.values(exports).filter((exported: WiringExport) => exported.kind === 'app');\n if ((entry === undefined && apps.length > 0) || (entry !== undefined && apps.length !== 1))\n this.fail('Declare exactly one AppWiring entry for an application; libraries export Wiring without an entry.');\n if (entry !== undefined && exports[entry]?.kind !== 'app')\n this.fail('A runtime entry must select an AppWiring export. Libraries have no entry.');\n if (entry === undefined && root['host'] !== undefined)\n this.fail('Library declarations cannot carry an application host.');\n for (const [name, exported] of Object.entries(exports)) {\n if (exported.kind !== 'app' && exported.wirings.length > 0)\n this.fail(`${name}: only AppWiring may select library Wirings.`);\n if (!['app', 'wiring'].includes(exported.kind) &&\n (exported.bindModules.length > 0 || exported.routeModules.length > 0))\n this.fail(`${name}: leaf modules cannot select module lists.`);\n if (['app', 'wiring'].includes(exported.kind) && exported.relationships.length > 0)\n this.fail(`${name}: declare relationships in named binding/route modules.`);\n }\n return new RuntimeDeclaration(\n expectedProject,\n framework,\n exports,\n root['entry'] === undefined ? undefined : this.string(root['entry']),\n root['host'] === undefined ? undefined : this.string(root['host']),\n );\n }\n\n // webpieces-disable no-any-unknown -- JSON syntax boundary; fields are narrowed by decode\n private parse(text: string, project: string): unknown {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return JSON.parse(text);\n } catch (err: unknown) {\n const error = toError(err);\n this.fail(`${project}/runtime-deps.json contains invalid JSON.`, error);\n }\n }\n\n // webpieces-disable no-any-unknown -- untrusted JSON is narrowed and validated at the input boundary\n private exported(value: unknown): WiringExport {\n this.renamed(value, 'bindingModules', 'bindModules');\n this.renamed(value, 'routingModules', 'routeModules');\n const exported = this.record(value, ['kind', 'relationships', 'bindModules', 'routeModules', 'wirings']);\n const kind = this.string(exported['kind']);\n if (\n kind !== 'binding' &&\n kind !== 'routing' &&\n kind !== 'wiring' &&\n kind !== 'app' &&\n kind !== 'external'\n )\n this.fail(`Invalid export kind ${kind}.`);\n return new WiringExport(\n kind,\n this.array(exported['relationships']).map((value) => this.relationship(value)),\n this.array(exported['bindModules']).map((value) => this.selection(value)),\n this.array(exported['routeModules']).map((value) => this.selection(value)),\n this.array(exported['wirings']).map((value) => this.selection(value)),\n );\n }\n\n // webpieces-disable no-any-unknown -- untrusted JSON is narrowed before the renamed-field check\n private renamed(value: unknown, old: string, renamed: string): void {\n if (Object.hasOwn(this.record(value), old))\n this.fail(`runtime-deps field ${old} was renamed to ${renamed}; regenerate the candidate from src/wiring.ts (getBindModules/getRouteModules) and review it.`);\n }\n\n // webpieces-disable no-any-unknown -- untrusted relationship JSON is narrowed before construction\n private relationship(value: unknown): WiringRelationship {\n const relation = this.record(value, [\n 'contract',\n 'direction',\n 'transport',\n 'target',\n 'policy',\n ]);\n const contract = this.record(relation['contract'], ['project', 'exportedName']);\n const direction = this.string(relation['direction']);\n const transport = this.string(relation['transport']);\n if (direction !== 'implements' && direction !== 'uses')\n this.fail(`Invalid direction ${direction}.`);\n if (transport !== 'rpc' && transport !== 'pubsub' && transport !== 'external')\n this.fail(`Invalid transport ${transport}.`);\n const target =\n relation['target'] === undefined ? undefined : this.target(relation['target']);\n const policy =\n relation['policy'] === undefined ? undefined : this.string(relation['policy']);\n if (direction === 'uses' && target === undefined)\n this.fail('Uses requires an explicit target.');\n if (direction === 'implements' && target !== undefined)\n this.fail('Implements cannot declare a client target.');\n return new WiringRelationship(\n new ContractIdentity(\n this.string(contract['project']),\n this.string(contract['exportedName']),\n ),\n direction === 'uses'\n ? new UsesFacts(transport, target!, policy)\n : new ImplementsFacts(transport, policy),\n );\n }\n\n // webpieces-disable no-any-unknown -- untrusted selection arguments are validated before substitution\n private selection(value: unknown): WiringSelection {\n const selection = this.record(value, ['project', 'exportedName', 'targets', 'policies']);\n const targets: Record<string, DeclaredTarget> = {};\n const policies: Record<string, PolicyValue> = {};\n for (const [name, target] of Object.entries(this.record(selection['targets'])))\n targets[name] = this.target(target);\n for (const [name, policy] of Object.entries(this.record(selection['policies']))) {\n if (typeof policy === 'boolean' || policy === 'runtime') policies[name] = policy;\n else {\n const forwarded = this.record(policy, ['parameter']);\n policies[name] = { parameter: this.string(forwarded['parameter']) };\n }\n }\n return new WiringSelection(\n this.string(selection['project']),\n this.string(selection['exportedName']),\n targets,\n policies,\n );\n }\n\n // webpieces-disable no-any-unknown -- target discriminant controls the exact accepted JSON shape\n private target(value: unknown): DeclaredTarget {\n const target = this.record(value);\n switch (target['kind']) {\n case 'service': {\n this.record(value, ['kind', 'service', 'contract']);\n const contract =\n target['contract'] === undefined\n ? undefined\n : this.record(target['contract'], ['project', 'exportedName']);\n return {\n kind: 'service',\n service: this.string(target['service']),\n contract:\n contract === undefined\n ? undefined\n : new ContractIdentity(\n this.string(contract['project']),\n this.string(contract['exportedName']),\n ),\n };\n }\n case 'parameter':\n this.record(value, ['kind', 'parameter']);\n return { kind: 'parameter', parameter: this.string(target['parameter']) };\n case 'unknown':\n this.record(value, ['kind', 'reason']);\n return { kind: 'unknown', reason: this.string(target['reason']) };\n case 'external': {\n this.record(value, ['kind', 'system']);\n const system = this.record(target['system'], ['kind', 'label']);\n const kind = this.string(system['kind']);\n if (!isExternalSystemKind(kind)) this.fail(`Invalid external system kind ${kind}.`);\n return { kind: 'external', system: { kind, label: this.string(system['label']) } };\n }\n default:\n return this.fail(\n 'Targets require an explicit service, parameter, external, or unknown kind.',\n );\n }\n }\n\n // webpieces-disable no-any-unknown -- JSON record boundary; never a runtime topology type\n private record(value: unknown, allowed?: readonly string[]): Record<string, unknown> {\n if (value === null || typeof value !== 'object' || Array.isArray(value))\n this.fail('Expected a JSON object.');\n const record = value as Record<string, unknown>;\n for (const key of Object.keys(record))\n if (['__proto__', 'constructor', 'prototype'].includes(key))\n this.fail(`Reserved runtime-deps field ${key}.`);\n if (allowed !== undefined)\n for (const key of Object.keys(record))\n if (!allowed.includes(key)) this.fail(`Unknown runtime-deps field ${key}.`);\n return record;\n }\n\n // webpieces-disable no-any-unknown -- JSON array boundary\n private array(value: unknown): unknown[] {\n if (!Array.isArray(value)) this.fail('Expected a JSON array.');\n return value;\n }\n\n // webpieces-disable no-any-unknown -- JSON scalar boundary\n private string(value: unknown): string {\n if (typeof value !== 'string' || value.trim() === '')\n this.fail('Expected a non-empty string.');\n return value;\n }\n\n private fail(message: string, cause?: Error): never {\n throw new RuleFailError(\n 'validate-runtime-architecture',\n message,\n undefined,\n undefined,\n [\n new Option(\n 'Review and correct runtime-deps.json using the versioned runtime wiring schema.',\n true,\n ),\n ],\n undefined,\n cause,\n );\n }\n}\n"]}
|
|
@@ -56,10 +56,10 @@ export type PolicyValue = boolean | 'runtime' | {
|
|
|
56
56
|
export declare class WiringExport {
|
|
57
57
|
readonly kind: 'binding' | 'routing' | 'wiring' | 'app' | 'external';
|
|
58
58
|
readonly relationships: WiringRelationship[];
|
|
59
|
-
readonly
|
|
60
|
-
readonly
|
|
59
|
+
readonly bindModules: WiringSelection[];
|
|
60
|
+
readonly routeModules: WiringSelection[];
|
|
61
61
|
readonly wirings: WiringSelection[];
|
|
62
|
-
constructor(kind: 'binding' | 'routing' | 'wiring' | 'app' | 'external', relationships: WiringRelationship[],
|
|
62
|
+
constructor(kind: 'binding' | 'routing' | 'wiring' | 'app' | 'external', relationships: WiringRelationship[], bindModules: WiringSelection[], routeModules?: WiringSelection[], wirings?: WiringSelection[]);
|
|
63
63
|
}
|
|
64
64
|
/** No timestamps, machine paths, credentials, deployment URLs, or cache keys belong here. */
|
|
65
65
|
export declare class RuntimeDeclaration {
|
|
@@ -65,14 +65,14 @@ exports.WiringSelection = WiringSelection;
|
|
|
65
65
|
class WiringExport {
|
|
66
66
|
kind;
|
|
67
67
|
relationships;
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
bindModules;
|
|
69
|
+
routeModules;
|
|
70
70
|
wirings;
|
|
71
|
-
constructor(kind, relationships,
|
|
71
|
+
constructor(kind, relationships, bindModules, routeModules = [], wirings = []) {
|
|
72
72
|
this.kind = kind;
|
|
73
73
|
this.relationships = relationships;
|
|
74
|
-
this.
|
|
75
|
-
this.
|
|
74
|
+
this.bindModules = bindModules;
|
|
75
|
+
this.routeModules = routeModules;
|
|
76
76
|
this.wirings = wirings;
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declaration.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/runtime-wiring/declaration.ts"],"names":[],"mappings":";;;AAEA,8FAA8F;AAC9F,MAAa,gBAAgB;IAEL;IACA;IAFpB,YACoB,OAAe,EACf,YAAoB;QADpB,YAAO,GAAP,OAAO,CAAQ;QACf,iBAAY,GAAZ,YAAY,CAAQ;IACrC,CAAC;CACP;AALD,4CAKC;AAQD,MAAa,eAAe;IAIJ;IACA;IAJX,SAAS,GAAG,YAAY,CAAC;IAElC,YACoB,SAAuB,EACvB,MAAe;QADf,cAAS,GAAT,SAAS,CAAc;QACvB,WAAM,GAAN,MAAM,CAAS;IAChC,CAAC;CACP;AAPD,0CAOC;AAED,MAAa,SAAS;IAGE;IACA;IACA;IAJX,SAAS,GAAG,MAAM,CAAC;IAC5B,YACoB,SAAuB,EACvB,MAAsB,EACtB,MAAe;QAFf,cAAS,GAAT,SAAS,CAAc;QACvB,WAAM,GAAN,MAAM,CAAgB;QACtB,WAAM,GAAN,MAAM,CAAS;IAChC,CAAC;CACP;AAPD,8BAOC;AAID,MAAa,kBAAkB;IAOP;IANX,SAAS,CAAwB;IACjC,SAAS,CAAe;IACxB,MAAM,CAAkB;IACxB,MAAM,CAAU;IAEzB,YACoB,QAA0B,EAC1C,KAAkB;QADF,aAAQ,GAAR,QAAQ,CAAkB;QAG1C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QACpE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC/B,CAAC;CACJ;AAfD,gDAeC;AAED,sFAAsF;AACtF,MAAa,eAAe;IAEJ;IACA;IACA;IACA;IAJpB,YACoB,OAAe,EACf,YAAoB,EACpB,OAAuC,EACvC,QAAqC;QAHrC,YAAO,GAAP,OAAO,CAAQ;QACf,iBAAY,GAAZ,YAAY,CAAQ;QACpB,YAAO,GAAP,OAAO,CAAgC;QACvC,aAAQ,GAAR,QAAQ,CAA6B;IACtD,CAAC;CACP;AAPD,0CAOC;AAID,MAAa,YAAY;IAED;IACA;IACA;IACA;IACA;IALpB,YACoB,IAA2D,EAC3D,aAAmC,EACnC,
|
|
1
|
+
{"version":3,"file":"declaration.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/runtime-wiring/declaration.ts"],"names":[],"mappings":";;;AAEA,8FAA8F;AAC9F,MAAa,gBAAgB;IAEL;IACA;IAFpB,YACoB,OAAe,EACf,YAAoB;QADpB,YAAO,GAAP,OAAO,CAAQ;QACf,iBAAY,GAAZ,YAAY,CAAQ;IACrC,CAAC;CACP;AALD,4CAKC;AAQD,MAAa,eAAe;IAIJ;IACA;IAJX,SAAS,GAAG,YAAY,CAAC;IAElC,YACoB,SAAuB,EACvB,MAAe;QADf,cAAS,GAAT,SAAS,CAAc;QACvB,WAAM,GAAN,MAAM,CAAS;IAChC,CAAC;CACP;AAPD,0CAOC;AAED,MAAa,SAAS;IAGE;IACA;IACA;IAJX,SAAS,GAAG,MAAM,CAAC;IAC5B,YACoB,SAAuB,EACvB,MAAsB,EACtB,MAAe;QAFf,cAAS,GAAT,SAAS,CAAc;QACvB,WAAM,GAAN,MAAM,CAAgB;QACtB,WAAM,GAAN,MAAM,CAAS;IAChC,CAAC;CACP;AAPD,8BAOC;AAID,MAAa,kBAAkB;IAOP;IANX,SAAS,CAAwB;IACjC,SAAS,CAAe;IACxB,MAAM,CAAkB;IACxB,MAAM,CAAU;IAEzB,YACoB,QAA0B,EAC1C,KAAkB;QADF,aAAQ,GAAR,QAAQ,CAAkB;QAG1C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QACpE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC/B,CAAC;CACJ;AAfD,gDAeC;AAED,sFAAsF;AACtF,MAAa,eAAe;IAEJ;IACA;IACA;IACA;IAJpB,YACoB,OAAe,EACf,YAAoB,EACpB,OAAuC,EACvC,QAAqC;QAHrC,YAAO,GAAP,OAAO,CAAQ;QACf,iBAAY,GAAZ,YAAY,CAAQ;QACpB,YAAO,GAAP,OAAO,CAAgC;QACvC,aAAQ,GAAR,QAAQ,CAA6B;IACtD,CAAC;CACP;AAPD,0CAOC;AAID,MAAa,YAAY;IAED;IACA;IACA;IACA;IACA;IALpB,YACoB,IAA2D,EAC3D,aAAmC,EACnC,WAA8B,EAC9B,eAAkC,EAAE,EACpC,UAA6B,EAAE;QAJ/B,SAAI,GAAJ,IAAI,CAAuD;QAC3D,kBAAa,GAAb,aAAa,CAAsB;QACnC,gBAAW,GAAX,WAAW,CAAmB;QAC9B,iBAAY,GAAZ,YAAY,CAAwB;QACpC,YAAO,GAAP,OAAO,CAAwB;IAChD,CAAC;CACP;AARD,oCAQC;AAED,6FAA6F;AAC7F,MAAa,kBAAkB;IAQ3B,YACI,OAAe,EACf,SAAyC,EACzC,OAAqC,EACrC,KAAc,EACd,IAAa;QAEb,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;CACJ;AAtBD,gDAsBC","sourcesContent":["import type { ApiTransport, ExternalSystemDeclaration } from '../api-usage/api-relations';\n\n/** Stable source identity. Equal class shapes or short names never establish API identity. */\nexport class ContractIdentity {\n constructor(\n public readonly project: string,\n public readonly exportedName: string,\n ) {}\n}\n\nexport type DeclaredTarget =\n | { kind: 'service'; service: string; contract?: ContractIdentity }\n | { kind: 'parameter'; parameter: string }\n | { kind: 'external'; system: ExternalSystemDeclaration }\n | { kind: 'unknown'; reason: string };\n\nexport class ImplementsFacts {\n readonly direction = 'implements';\n declare readonly target?: never;\n constructor(\n public readonly transport: ApiTransport,\n public readonly policy?: string,\n ) {}\n}\n\nexport class UsesFacts {\n readonly direction = 'uses';\n constructor(\n public readonly transport: ApiTransport,\n public readonly target: DeclaredTarget,\n public readonly policy?: string,\n ) {}\n}\n\nexport type WiringFacts = ImplementsFacts | UsesFacts;\n\nexport class WiringRelationship {\n readonly direction: 'implements' | 'uses';\n readonly transport: ApiTransport;\n readonly target?: DeclaredTarget;\n readonly policy?: string;\n\n constructor(\n public readonly contract: ContractIdentity,\n facts: WiringFacts,\n ) {\n this.direction = facts.direction;\n this.transport = facts.transport;\n this.target = facts.direction === 'uses' ? facts.target : undefined;\n this.policy = facts.policy;\n }\n}\n\n/** Only these exports execute, in this order, with these graph-relevant arguments. */\nexport class WiringSelection {\n constructor(\n public readonly project: string,\n public readonly exportedName: string,\n public readonly targets: Record<string, DeclaredTarget>,\n public readonly policies: Record<string, PolicyValue>,\n ) {}\n}\n\nexport type PolicyValue = boolean | 'runtime' | { parameter: string };\n\nexport class WiringExport {\n constructor(\n public readonly kind: 'binding' | 'routing' | 'wiring' | 'app' | 'external',\n public readonly relationships: WiringRelationship[],\n public readonly bindModules: WiringSelection[],\n public readonly routeModules: WiringSelection[] = [],\n public readonly wirings: WiringSelection[] = [],\n ) {}\n}\n\n/** No timestamps, machine paths, credentials, deployment URLs, or cache keys belong here. */\nexport class RuntimeDeclaration {\n declare readonly schemaVersion: 2;\n declare readonly project: string;\n declare readonly framework: 'node' | 'angular' | 'browser';\n declare readonly exports: Record<string, WiringExport>;\n declare readonly entry?: string;\n declare readonly host?: string;\n\n constructor(\n project: string,\n framework: 'node' | 'angular' | 'browser',\n exports: Record<string, WiringExport>,\n entry?: string,\n host?: string,\n ) {\n this.schemaVersion = 2;\n this.project = project;\n this.framework = framework;\n this.exports = exports;\n this.entry = entry;\n this.host = host;\n }\n}\n"]}
|
|
@@ -46,7 +46,7 @@ class PreparedTargets {
|
|
|
46
46
|
if (channel === 'policy' && ts.isPropertyAccessExpression(node) && node.name.text === 'enabled')
|
|
47
47
|
retain(this.path(node.expression));
|
|
48
48
|
if (channel === 'target' && ts.isCallExpression(node) && this.clientCall(node)) {
|
|
49
|
-
const target = node.arguments[
|
|
49
|
+
const target = node.arguments[1];
|
|
50
50
|
if (target !== undefined)
|
|
51
51
|
retain(this.path(target));
|
|
52
52
|
}
|
|
@@ -74,12 +74,12 @@ class PreparedTargets {
|
|
|
74
74
|
}
|
|
75
75
|
clientCall(call) {
|
|
76
76
|
const signature = this.checker.getResolvedSignature(call)?.declaration;
|
|
77
|
-
if (signature === undefined || (!ts.isMethodDeclaration(signature) && !ts.
|
|
77
|
+
if (signature === undefined || (!ts.isMethodDeclaration(signature) && !ts.isMethodSignature(signature)))
|
|
78
78
|
return false;
|
|
79
79
|
const file = signature.getSourceFile().fileName.replace(/\\/g, '/');
|
|
80
80
|
const name = signature.name?.getText();
|
|
81
|
-
return name !== undefined && ['
|
|
82
|
-
/(?:\/packages\/
|
|
81
|
+
return name !== undefined && ['createRpcClientAndBind', 'createPubSubClientAndBind'].includes(name) &&
|
|
82
|
+
/(?:\/packages\/http\/|\/node_modules\/@webpieces\/)(?:http-routing|http-client-browser)\//.test(file);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
exports.PreparedTargets = PreparedTargets;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepared-targets.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/runtime-wiring/prepared-targets.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"prepared-targets.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/lib/runtime-wiring/prepared-targets.ts"],"names":[],"mappings":"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","sourcesContent":["import * as ts from 'typescript';\nimport { WiringSourceTypes } from './source-types';\n\n/**\n * Infer graph-relevant constructor paths from destination uses and selected named modules. Only\n * classes declared in a canonical src/wiring.ts are walked.\n */\nexport class PreparedTargets {\n private readonly types: WiringSourceTypes;\n\n constructor(private readonly checker: ts.TypeChecker) {\n this.types = new WiringSourceTypes(checker);\n }\n\n paths(invocation: ts.NewExpression | ts.CallExpression, channel: 'target' | 'policy'): string[] {\n const declaration = this.checker.getResolvedSignature(invocation)?.declaration?.parent;\n if (declaration === undefined || !ts.isClassDeclaration(declaration)) return [];\n return this.collect(declaration, new Set<ts.ClassDeclaration>(), channel);\n }\n\n path(expression: ts.Expression): string | undefined {\n if (ts.isIdentifier(expression)) return expression.text;\n if (!ts.isPropertyAccessExpression(expression)) return undefined;\n if (expression.expression.kind === ts.SyntaxKind.ThisKeyword) return expression.name.text;\n const parent = this.path(expression.expression);\n return parent === undefined ? undefined : `${parent}.${expression.name.text}`;\n }\n\n private collect(declaration: ts.ClassDeclaration, active: Set<ts.ClassDeclaration>, channel: 'target' | 'policy'): string[] {\n // Only canonical wiring declarations carry graph-relevant paths; another file's body is never read.\n if (active.has(declaration) || !/(?:^|[\\\\/])src[\\\\/]wiring\\.ts$/.test(declaration.getSourceFile().fileName)) return [];\n const next = new Set([...active, declaration]);\n const parameters = declaration.members.filter(ts.isConstructorDeclaration).flatMap(\n (constructor: ts.ConstructorDeclaration) => constructor.parameters.map(\n (parameter: ts.ParameterDeclaration) => parameter.name.getText(),\n ),\n );\n const paths = new Set<string>();\n const retain = (path: string | undefined): void => {\n if (path !== undefined && parameters.includes(path.split('.')[0])) paths.add(path);\n };\n const visit = (node: ts.Node): void => {\n if (channel === 'policy' && ts.isPropertyAccessExpression(node) && node.name.text === 'enabled')\n retain(this.path(node.expression));\n if (channel === 'target' && ts.isCallExpression(node) && this.clientCall(node)) {\n const target = node.arguments[1];\n if (target !== undefined) retain(this.path(target));\n }\n if (ts.isNewExpression(node) && this.types.kind(node.expression) !== undefined) {\n const child = this.types.declaration(node.expression);\n const signature = this.checker.getResolvedSignature(node);\n if (child !== undefined && ts.isClassDeclaration(child)) {\n for (const path of this.collect(child, next, channel)) {\n const parts = path.split('.');\n const name = parts[0];\n const suffix = parts.slice(1);\n const index = signature?.getParameters().findIndex((parameter: ts.Symbol) => parameter.name === name) ?? -1;\n const argument = node.arguments?.[index];\n if (argument === undefined) continue;\n const parent = this.path(argument);\n retain(parent === undefined ? undefined : [parent, ...suffix].join('.'));\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n ts.forEachChild(declaration, visit);\n return [...paths].sort();\n }\n\n private clientCall(call: ts.CallExpression): boolean {\n const signature = this.checker.getResolvedSignature(call)?.declaration;\n if (signature === undefined || (!ts.isMethodDeclaration(signature) && !ts.isMethodSignature(signature))) return false;\n const file = signature.getSourceFile().fileName.replace(/\\\\/g, '/');\n const name = signature.name?.getText();\n return name !== undefined && ['createRpcClientAndBind', 'createPubSubClientAndBind'].includes(name) &&\n /(?:\\/packages\\/http\\/|\\/node_modules\\/@webpieces\\/)(?:http-routing|http-client-browser)\\//.test(file);\n }\n}\n"]}
|
|
@@ -17,16 +17,27 @@ export declare class WiringSourceExtractor {
|
|
|
17
17
|
* a module declared elsewhere can neither add a relationship nor be discovered as a fallback.
|
|
18
18
|
*/
|
|
19
19
|
extract(): RuntimeDeclaration;
|
|
20
|
+
/**
|
|
21
|
+
* The registration forms that carry graph facts: binder.createRpcClientAndBind /
|
|
22
|
+
* createPubSubClientAndBind / bindExternal and router.addRoutes (plus the factory calls they wrap).
|
|
23
|
+
*/
|
|
20
24
|
private facts;
|
|
25
|
+
/**
|
|
26
|
+
* binder.bindExternal(Api, VendorImpl): the vendor contract's identity comes from the resolved
|
|
27
|
+
* symbol, exactly like any other API. An APPLICATION owner must also prove a production business
|
|
28
|
+
* consumer of it; a library module binds an adapter for whichever app selects it, so its
|
|
29
|
+
* consumer lives in that app.
|
|
30
|
+
*/
|
|
21
31
|
private recordExternal;
|
|
22
32
|
private recordRelationship;
|
|
23
33
|
private frameworkCall;
|
|
24
34
|
private recordWiring;
|
|
25
35
|
private moduleSelections;
|
|
26
36
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
37
|
+
* OWNER-canonical: a selected module is declared in THIS wiring.ts, or - for a BindModule an
|
|
38
|
+
* AppWiring selects, and for a library Wiring - in its library owner's canonical src/wiring.ts.
|
|
39
|
+
* Proven by the resolved declaration (so a re-export resolves to its true file), never by a name,
|
|
40
|
+
* and checked before any argument analysis, so an off-file module body is never read.
|
|
30
41
|
*/
|
|
31
42
|
private assertCanonicalDeclaration;
|
|
32
43
|
private exportOwner;
|
|
@@ -54,40 +54,43 @@ class WiringSourceExtractor {
|
|
|
54
54
|
this.fail(`${this.info.name} requires one unambiguous exported AppWiring in src/wiring.ts.`);
|
|
55
55
|
return new declaration_1.RuntimeDeclaration(this.info.name, framework, this.exported, this.entry, this.host);
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* The registration forms that carry graph facts: binder.createRpcClientAndBind /
|
|
59
|
+
* createPubSubClientAndBind / bindExternal and router.addRoutes (plus the factory calls they wrap).
|
|
60
|
+
*/
|
|
57
61
|
facts(node, owner) {
|
|
58
|
-
if (ts.isNewExpression(node) && new source_types_1.WiringSourceTypes(this.program.getTypeChecker()).isFramework(node.expression, 'ExternalContractUse'))
|
|
59
|
-
this.recordExternal(node, owner);
|
|
60
62
|
if (ts.isCallExpression(node) && this.frameworkCall(node)) {
|
|
61
63
|
const name = this.values.symbolName(node.expression);
|
|
62
|
-
if (
|
|
64
|
+
if (name === 'bindExternal')
|
|
65
|
+
this.recordExternal(node, owner);
|
|
66
|
+
else if (['addRoutes', 'createRpcClient', 'createPubSubClient', 'createRpcClientAndBind', 'createPubSubClientAndBind'].includes(name))
|
|
63
67
|
this.recordRelationship(node, name, owner);
|
|
64
68
|
}
|
|
65
69
|
ts.forEachChild(node, (child) => this.facts(child, owner));
|
|
66
70
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
if (
|
|
76
|
-
this.fail('
|
|
77
|
-
|
|
78
|
-
|
|
71
|
+
/**
|
|
72
|
+
* binder.bindExternal(Api, VendorImpl): the vendor contract's identity comes from the resolved
|
|
73
|
+
* symbol, exactly like any other API. An APPLICATION owner must also prove a production business
|
|
74
|
+
* consumer of it; a library module binds an adapter for whichever app selects it, so its
|
|
75
|
+
* consumer lives in that app.
|
|
76
|
+
*/
|
|
77
|
+
recordExternal(call, owner) {
|
|
78
|
+
const api = call.arguments[0];
|
|
79
|
+
if (api === undefined || call.arguments[1] === undefined)
|
|
80
|
+
this.fail('bindExternal requires the external API contract and its vendor implementation.');
|
|
81
|
+
const contract = this.values.identity(api);
|
|
82
|
+
if (this.info.tags.includes('webpieces') &&
|
|
83
|
+
!this.values.hasExternalConsumer(this.info.name, contract.project, contract.exportedName, this.program))
|
|
84
|
+
this.fail(`${contract.project}#${contract.exportedName} has no production business consumer in ${this.info.name}; adapters and test doubles do not establish uses.`);
|
|
79
85
|
const exported = this.exported[owner];
|
|
80
|
-
exported.relationships.push(new declaration_1.WiringRelationship(
|
|
86
|
+
exported.relationships.push(new declaration_1.WiringRelationship(contract, new declaration_1.UsesFacts('external', {
|
|
81
87
|
kind: 'unknown',
|
|
82
88
|
reason: 'Vendor interface; destination classified by approved contract metadata',
|
|
83
89
|
})));
|
|
84
90
|
this.exported[owner] = exported;
|
|
85
91
|
}
|
|
86
92
|
recordRelationship(call, method, owner) {
|
|
87
|
-
const
|
|
88
|
-
? 1
|
|
89
|
-
: 0;
|
|
90
|
-
const api = call.arguments[apiIndex];
|
|
93
|
+
const api = call.arguments[0];
|
|
91
94
|
if (api === undefined)
|
|
92
95
|
this.fail(`${method} requires an explicit API contract.`);
|
|
93
96
|
const contract = this.values.identity(api);
|
|
@@ -95,14 +98,14 @@ class WiringSourceExtractor {
|
|
|
95
98
|
const contractTransport = this.values.transport(api);
|
|
96
99
|
const transport = method === 'addRoutes'
|
|
97
100
|
? contractTransport
|
|
98
|
-
: method === '
|
|
101
|
+
: method === 'createPubSubClientAndBind' || method === 'createPubSubClient'
|
|
99
102
|
? 'pubsub'
|
|
100
103
|
: 'rpc';
|
|
101
104
|
if (transport !== contractTransport)
|
|
102
105
|
this.fail(`${method} transport disagrees with ${contract.project}#${contract.exportedName}.`);
|
|
103
106
|
const target = direction === 'implements'
|
|
104
107
|
? undefined
|
|
105
|
-
: this.values.target(call.arguments[
|
|
108
|
+
: this.values.target(call.arguments[1]);
|
|
106
109
|
const exported = this.exported[owner];
|
|
107
110
|
exported.relationships.push(new declaration_1.WiringRelationship(contract, direction === 'implements'
|
|
108
111
|
? new declaration_1.ImplementsFacts(transport, this.values.condition(call))
|
|
@@ -132,9 +135,11 @@ class WiringSourceExtractor {
|
|
|
132
135
|
this.facts(configure.body, owner);
|
|
133
136
|
return;
|
|
134
137
|
}
|
|
135
|
-
const bindings = this.moduleSelections(owner, types.method(declaration, '
|
|
136
|
-
|
|
137
|
-
const
|
|
138
|
+
const bindings = this.moduleSelections(owner, types.method(declaration, 'getBindModules'), 'binding', kind);
|
|
139
|
+
// The browser has no route channel; a Node Wiring's getRouteModules is required by its type.
|
|
140
|
+
const routeGetter = types.method(declaration, 'getRouteModules');
|
|
141
|
+
const routes = routeGetter === undefined ? [] : this.moduleSelections(owner, routeGetter, 'routing', kind);
|
|
142
|
+
const libraries = kind === 'app' ? this.moduleSelections(owner, types.method(declaration, 'getWirings'), 'wiring', kind) : [];
|
|
138
143
|
if (kind === 'wiring' && types.method(declaration, 'getWirings') !== undefined)
|
|
139
144
|
this.fail(`${owner}: library Wiring cannot select other Wirings.`);
|
|
140
145
|
this.exported[owner] = new declaration_1.WiringExport(kind, [], bindings, routes, libraries);
|
|
@@ -151,9 +156,9 @@ class WiringSourceExtractor {
|
|
|
151
156
|
this.host = project.metadata?.webpieces?.serviceName;
|
|
152
157
|
}
|
|
153
158
|
}
|
|
154
|
-
moduleSelections(owner, method, expected) {
|
|
159
|
+
moduleSelections(owner, method, expected, ownerKind) {
|
|
155
160
|
if (method !== undefined && path.resolve(method.getSourceFile().fileName) !== this.wiringPath)
|
|
156
|
-
this.fail(`${owner}: its selection getter is declared in ${method.getSourceFile().fileName}; declare
|
|
161
|
+
this.fail(`${owner}: its selection getter is declared in ${method.getSourceFile().fileName}; declare getBindModules/getRouteModules/getWirings on ${owner} itself in ${this.wiringPath}.`);
|
|
157
162
|
const statements = method?.body?.statements;
|
|
158
163
|
const expression = statements?.length === 1 && ts.isReturnStatement(statements[0]) ? statements[0].expression : undefined;
|
|
159
164
|
if (expression === undefined || !ts.isArrayLiteralExpression(expression))
|
|
@@ -163,29 +168,35 @@ class WiringSourceExtractor {
|
|
|
163
168
|
if (!ts.isNewExpression(element) || types.kind(element.expression) !== expected)
|
|
164
169
|
this.fail(`Wrong ${expected} selection ${element.getText()}; AppWiring children, delegation and nested lists are forbidden.`);
|
|
165
170
|
const identity = this.values.identity(element.expression);
|
|
166
|
-
this.assertCanonicalDeclaration(owner, element.expression, identity, expected);
|
|
171
|
+
this.assertCanonicalDeclaration(owner, element.expression, identity, expected, ownerKind);
|
|
167
172
|
return new declaration_1.WiringSelection(identity.project, identity.exportedName, this.values.arguments(element), this.values.policies(element));
|
|
168
173
|
});
|
|
169
174
|
}
|
|
170
175
|
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
176
|
+
* OWNER-canonical: a selected module is declared in THIS wiring.ts, or - for a BindModule an
|
|
177
|
+
* AppWiring selects, and for a library Wiring - in its library owner's canonical src/wiring.ts.
|
|
178
|
+
* Proven by the resolved declaration (so a re-export resolves to its true file), never by a name,
|
|
179
|
+
* and checked before any argument analysis, so an off-file module body is never read.
|
|
174
180
|
*/
|
|
175
|
-
assertCanonicalDeclaration(owner, selected, identity, expected) {
|
|
181
|
+
assertCanonicalDeclaration(owner, selected, identity, expected, ownerKind) {
|
|
176
182
|
const declaration = new source_types_1.WiringSourceTypes(this.program.getTypeChecker()).declaration(selected);
|
|
177
183
|
const declaredIn = declaration === undefined ? 'an unresolved file' : path.resolve(declaration.getSourceFile().fileName);
|
|
178
|
-
if (expected !== 'wiring')
|
|
179
|
-
|
|
180
|
-
return;
|
|
181
|
-
const role = expected === 'binding' ? 'BindingModule' : 'RouteModule';
|
|
182
|
-
this.fail(`${owner} selects ${identity.exportedName}, which is declared in ${declaredIn}. Declare the ${role} class ${identity.exportedName}, with its registrations, beside ${owner} in ${this.wiringPath}.`);
|
|
183
|
-
}
|
|
184
|
+
if (declaredIn === this.wiringPath && expected !== 'wiring')
|
|
185
|
+
return;
|
|
184
186
|
const library = this.infos.get(identity.project);
|
|
185
187
|
const canonical = library === undefined ? undefined : path.resolve(this.workspaceRoot, library.root, 'src/wiring.ts');
|
|
186
|
-
|
|
188
|
+
const fromLibrary = identity.project !== this.info.name && canonical !== undefined && declaredIn === canonical;
|
|
189
|
+
if (expected === 'wiring' && fromLibrary)
|
|
190
|
+
return;
|
|
191
|
+
if (expected === 'binding' && ownerKind === 'app' && fromLibrary)
|
|
187
192
|
return;
|
|
188
|
-
|
|
193
|
+
if (expected === 'wiring')
|
|
194
|
+
this.fail(`${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'}.`);
|
|
195
|
+
const role = expected === 'binding' ? 'BindModule' : 'RouteModule';
|
|
196
|
+
const where = expected === 'binding' && ownerKind === 'app'
|
|
197
|
+
? ` beside ${owner} in ${this.wiringPath}, or in its library owner's canonical src/wiring.ts`
|
|
198
|
+
: ` beside ${owner} in ${this.wiringPath}`;
|
|
199
|
+
this.fail(`${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.`);
|
|
189
200
|
}
|
|
190
201
|
exportOwner(node) {
|
|
191
202
|
let current = node;
|
|
@@ -213,7 +224,7 @@ class WiringSourceExtractor {
|
|
|
213
224
|
}
|
|
214
225
|
fail(message) {
|
|
215
226
|
throw new rules_config_1.RuleFailError('validate-runtime-architecture', message, undefined, undefined, [
|
|
216
|
-
new rules_config_1.Option('Declare each owner\'s Wiring/AppWiring class AND its
|
|
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),
|
|
217
228
|
]);
|
|
218
229
|
}
|
|
219
230
|
}
|
|
@@ -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 * 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 private facts(node: ts.Node, owner: string): void {\n if (ts.isNewExpression(node) && new WiringSourceTypes(this.program.getTypeChecker()).isFramework(node.expression, 'ExternalContractUse'))\n this.recordExternal(node, owner);\n if (ts.isCallExpression(node) && this.frameworkCall(node)) {\n const name = this.values.symbolName(node.expression);\n if (['addRoutes', 'createRpcClient', 'createPubSubClient', 'bindRpc', 'bindPubSub', 'provideRpcClient'].includes(name))\n this.recordRelationship(node, name, owner);\n }\n ts.forEachChild(node, (child: ts.Node) => this.facts(child, owner));\n }\n\n private recordExternal(expression: ts.NewExpression, owner: string): void {\n const identity = expression.arguments?.[0];\n if (identity === undefined || !ts.isStringLiteralLike(identity))\n this.fail(\n 'ExternalContractUse belongs to a selected exported module and requires a literal project#contract identity.',\n );\n const qualified = (identity as ts.StringLiteralLike).text.split('#');\n const project = qualified[0];\n const exportedName = qualified[1];\n const extra = qualified[2];\n if (!project || !exportedName || extra !== undefined)\n this.fail('ExternalContractUse requires one qualified project#contract identity.');\n if (!this.values.hasExternalConsumer(this.info.name, project, exportedName, this.program))\n this.fail(\n `${project}#${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 new ContractIdentity(project, exportedName),\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 apiIndex =\n method === 'bindRpc' || method === 'bindPubSub' || method === 'provideRpcClient'\n ? 1\n : 0;\n const api = call.arguments[apiIndex];\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 === 'bindPubSub' || 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[apiIndex + 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, 'getBindingModules'), 'binding');\n const routes = this.moduleSelections(owner, types.method(declaration, 'getRoutingModules'), 'routing');\n const libraries = kind === 'app' ? this.moduleSelections(owner, types.method(declaration, 'getWirings'), 'wiring') : [];\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'): 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 getBindingModules/getRoutingModules/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);\n return new WiringSelection(identity.project, identity.exportedName, this.values.arguments(element), this.values.policies(element));\n });\n }\n\n /**\n * A selected module must be declared in THIS wiring.ts, and a selected library Wiring in its own\n * owner's src/wiring.ts. Proven by the resolved declaration, never by a name, and checked before\n * 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 ): 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 (expected !== 'wiring') {\n if (declaredIn === this.wiringPath) return;\n const role = expected === 'binding' ? 'BindingModule' : 'RouteModule';\n this.fail(\n `${owner} selects ${identity.exportedName}, which is declared in ${declaredIn}. Declare the ${role} class ${identity.exportedName}, with its registrations, beside ${owner} in ${this.wiringPath}.`,\n );\n }\n const library = this.infos.get(identity.project);\n const canonical = library === undefined ? undefined : path.resolve(this.workspaceRoot, library.root, 'src/wiring.ts');\n if (canonical !== undefined && declaredIn === canonical) return;\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 }\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 BindingModule/RouteModule classes, with their registrations (RuntimeClients.bindRpc(token, Api, deployment), RuntimeTaskClients.bindPubSub, provideRpcClient, addRoutes, addFilter, DI binds), together in that owner\\'s canonical src/wiring.ts, and use the documented getter grammar; extraction reads only wiring.ts 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): 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"]}
|