@webpieces/nx-webpieces-rules 0.4.869 → 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 +7 -7
- package/src/lib/di-graph/runtime-client-bindings.d.ts +17 -3
- package/src/lib/di-graph/runtime-client-bindings.js +70 -26
- 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 +15 -3
- package/src/lib/runtime-wiring/source-extractor.js +53 -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,28 @@ 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) — 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
|
|
28
|
+
* symbol, exactly like any other API. An APPLICATION owner must also prove a production business
|
|
29
|
+
* consumer of it; a library module binds an adapter for whichever app selects it, so its
|
|
30
|
+
* consumer lives in that app.
|
|
31
|
+
*/
|
|
21
32
|
private recordExternal;
|
|
22
33
|
private recordRelationship;
|
|
23
34
|
private frameworkCall;
|
|
24
35
|
private recordWiring;
|
|
25
36
|
private moduleSelections;
|
|
26
37
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
38
|
+
* OWNER-canonical: a selected module is declared in THIS wiring.ts, or - for a BindModule an
|
|
39
|
+
* AppWiring selects, and for a library Wiring - in its library owner's canonical src/wiring.ts.
|
|
40
|
+
* Proven by the resolved declaration (so a re-export resolves to its true file), never by a name,
|
|
41
|
+
* and checked before any argument analysis, so an off-file module body is never read.
|
|
30
42
|
*/
|
|
31
43
|
private assertCanonicalDeclaration;
|
|
32
44
|
private exportOwner;
|
|
@@ -54,40 +54,44 @@ 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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
71
|
+
/**
|
|
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
|
|
74
|
+
* symbol, exactly like any other API. An APPLICATION owner must also prove a production business
|
|
75
|
+
* consumer of it; a library module binds an adapter for whichever app selects it, so its
|
|
76
|
+
* consumer lives in that app.
|
|
77
|
+
*/
|
|
78
|
+
recordExternal(call, owner) {
|
|
79
|
+
const api = call.arguments[0];
|
|
80
|
+
if (api === undefined || call.arguments[1] === undefined)
|
|
81
|
+
this.fail('bindExternal requires the external API contract and its vendor implementation.');
|
|
82
|
+
const contract = this.values.identity(api);
|
|
83
|
+
if (this.info.tags.includes('webpieces') &&
|
|
84
|
+
!this.values.hasExternalConsumer(this.info.name, contract.project, contract.exportedName, this.program))
|
|
85
|
+
this.fail(`${contract.project}#${contract.exportedName} has no production business consumer in ${this.info.name}; adapters and test doubles do not establish uses.`);
|
|
79
86
|
const exported = this.exported[owner];
|
|
80
|
-
exported.relationships.push(new declaration_1.WiringRelationship(
|
|
87
|
+
exported.relationships.push(new declaration_1.WiringRelationship(contract, new declaration_1.UsesFacts('external', {
|
|
81
88
|
kind: 'unknown',
|
|
82
89
|
reason: 'Vendor interface; destination classified by approved contract metadata',
|
|
83
90
|
})));
|
|
84
91
|
this.exported[owner] = exported;
|
|
85
92
|
}
|
|
86
93
|
recordRelationship(call, method, owner) {
|
|
87
|
-
const
|
|
88
|
-
? 1
|
|
89
|
-
: 0;
|
|
90
|
-
const api = call.arguments[apiIndex];
|
|
94
|
+
const api = call.arguments[0];
|
|
91
95
|
if (api === undefined)
|
|
92
96
|
this.fail(`${method} requires an explicit API contract.`);
|
|
93
97
|
const contract = this.values.identity(api);
|
|
@@ -95,14 +99,14 @@ class WiringSourceExtractor {
|
|
|
95
99
|
const contractTransport = this.values.transport(api);
|
|
96
100
|
const transport = method === 'addRoutes'
|
|
97
101
|
? contractTransport
|
|
98
|
-
: method === '
|
|
102
|
+
: method === 'createPubSubClientAndBind' || method === 'createPubSubClient'
|
|
99
103
|
? 'pubsub'
|
|
100
104
|
: 'rpc';
|
|
101
105
|
if (transport !== contractTransport)
|
|
102
106
|
this.fail(`${method} transport disagrees with ${contract.project}#${contract.exportedName}.`);
|
|
103
107
|
const target = direction === 'implements'
|
|
104
108
|
? undefined
|
|
105
|
-
: this.values.target(call.arguments[
|
|
109
|
+
: this.values.target(call.arguments[1]);
|
|
106
110
|
const exported = this.exported[owner];
|
|
107
111
|
exported.relationships.push(new declaration_1.WiringRelationship(contract, direction === 'implements'
|
|
108
112
|
? new declaration_1.ImplementsFacts(transport, this.values.condition(call))
|
|
@@ -132,9 +136,11 @@ class WiringSourceExtractor {
|
|
|
132
136
|
this.facts(configure.body, owner);
|
|
133
137
|
return;
|
|
134
138
|
}
|
|
135
|
-
const bindings = this.moduleSelections(owner, types.method(declaration, '
|
|
136
|
-
|
|
137
|
-
const
|
|
139
|
+
const bindings = this.moduleSelections(owner, types.method(declaration, 'getBindModules'), 'binding', kind);
|
|
140
|
+
// The browser has no route channel; a Node Wiring's getRouteModules is required by its type.
|
|
141
|
+
const routeGetter = types.method(declaration, 'getRouteModules');
|
|
142
|
+
const routes = routeGetter === undefined ? [] : this.moduleSelections(owner, routeGetter, 'routing', kind);
|
|
143
|
+
const libraries = kind === 'app' ? this.moduleSelections(owner, types.method(declaration, 'getWirings'), 'wiring', kind) : [];
|
|
138
144
|
if (kind === 'wiring' && types.method(declaration, 'getWirings') !== undefined)
|
|
139
145
|
this.fail(`${owner}: library Wiring cannot select other Wirings.`);
|
|
140
146
|
this.exported[owner] = new declaration_1.WiringExport(kind, [], bindings, routes, libraries);
|
|
@@ -151,9 +157,9 @@ class WiringSourceExtractor {
|
|
|
151
157
|
this.host = project.metadata?.webpieces?.serviceName;
|
|
152
158
|
}
|
|
153
159
|
}
|
|
154
|
-
moduleSelections(owner, method, expected) {
|
|
160
|
+
moduleSelections(owner, method, expected, ownerKind) {
|
|
155
161
|
if (method !== undefined && path.resolve(method.getSourceFile().fileName) !== this.wiringPath)
|
|
156
|
-
this.fail(`${owner}: its selection getter is declared in ${method.getSourceFile().fileName}; declare
|
|
162
|
+
this.fail(`${owner}: its selection getter is declared in ${method.getSourceFile().fileName}; declare getBindModules/getRouteModules/getWirings on ${owner} itself in ${this.wiringPath}.`);
|
|
157
163
|
const statements = method?.body?.statements;
|
|
158
164
|
const expression = statements?.length === 1 && ts.isReturnStatement(statements[0]) ? statements[0].expression : undefined;
|
|
159
165
|
if (expression === undefined || !ts.isArrayLiteralExpression(expression))
|
|
@@ -163,29 +169,35 @@ class WiringSourceExtractor {
|
|
|
163
169
|
if (!ts.isNewExpression(element) || types.kind(element.expression) !== expected)
|
|
164
170
|
this.fail(`Wrong ${expected} selection ${element.getText()}; AppWiring children, delegation and nested lists are forbidden.`);
|
|
165
171
|
const identity = this.values.identity(element.expression);
|
|
166
|
-
this.assertCanonicalDeclaration(owner, element.expression, identity, expected);
|
|
172
|
+
this.assertCanonicalDeclaration(owner, element.expression, identity, expected, ownerKind);
|
|
167
173
|
return new declaration_1.WiringSelection(identity.project, identity.exportedName, this.values.arguments(element), this.values.policies(element));
|
|
168
174
|
});
|
|
169
175
|
}
|
|
170
176
|
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
177
|
+
* OWNER-canonical: a selected module is declared in THIS wiring.ts, or - for a BindModule an
|
|
178
|
+
* AppWiring selects, and for a library Wiring - in its library owner's canonical src/wiring.ts.
|
|
179
|
+
* Proven by the resolved declaration (so a re-export resolves to its true file), never by a name,
|
|
180
|
+
* and checked before any argument analysis, so an off-file module body is never read.
|
|
174
181
|
*/
|
|
175
|
-
assertCanonicalDeclaration(owner, selected, identity, expected) {
|
|
182
|
+
assertCanonicalDeclaration(owner, selected, identity, expected, ownerKind) {
|
|
176
183
|
const declaration = new source_types_1.WiringSourceTypes(this.program.getTypeChecker()).declaration(selected);
|
|
177
184
|
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
|
-
}
|
|
185
|
+
if (declaredIn === this.wiringPath && expected !== 'wiring')
|
|
186
|
+
return;
|
|
184
187
|
const library = this.infos.get(identity.project);
|
|
185
188
|
const canonical = library === undefined ? undefined : path.resolve(this.workspaceRoot, library.root, 'src/wiring.ts');
|
|
186
|
-
|
|
189
|
+
const fromLibrary = identity.project !== this.info.name && canonical !== undefined && declaredIn === canonical;
|
|
190
|
+
if (expected === 'wiring' && fromLibrary)
|
|
191
|
+
return;
|
|
192
|
+
if (expected === 'binding' && ownerKind === 'app' && fromLibrary)
|
|
187
193
|
return;
|
|
188
|
-
|
|
194
|
+
if (expected === 'wiring')
|
|
195
|
+
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'}.`);
|
|
196
|
+
const role = expected === 'binding' ? 'BindModule' : 'RouteModule';
|
|
197
|
+
const where = expected === 'binding' && ownerKind === 'app'
|
|
198
|
+
? ` beside ${owner} in ${this.wiringPath}, or in its library owner's canonical src/wiring.ts`
|
|
199
|
+
: ` beside ${owner} in ${this.wiringPath}`;
|
|
200
|
+
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
201
|
}
|
|
190
202
|
exportOwner(node) {
|
|
191
203
|
let current = node;
|
|
@@ -213,7 +225,7 @@ class WiringSourceExtractor {
|
|
|
213
225
|
}
|
|
214
226
|
fail(message) {
|
|
215
227
|
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
|
|
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),
|
|
217
229
|
]);
|
|
218
230
|
}
|
|
219
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 * 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) — 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"]}
|