@topogram/cli 0.3.64 → 0.3.65

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.
Files changed (245) hide show
  1. package/package.json +1 -1
  2. package/src/adoption/plan/index.js +703 -0
  3. package/src/adoption/plan.js +12 -703
  4. package/src/agent-ops/query-builders/auth.js +375 -0
  5. package/src/agent-ops/query-builders/change-risk/change-plan.js +123 -0
  6. package/src/agent-ops/query-builders/change-risk/import-plan.js +49 -0
  7. package/src/agent-ops/query-builders/change-risk/maintained.js +286 -0
  8. package/src/agent-ops/query-builders/change-risk/review-packets.js +123 -0
  9. package/src/agent-ops/query-builders/change-risk/risk.js +189 -0
  10. package/src/agent-ops/query-builders/change-risk.js +25 -0
  11. package/src/agent-ops/query-builders/common.js +149 -0
  12. package/src/agent-ops/query-builders/maintained-risk.js +539 -0
  13. package/src/agent-ops/query-builders/maintained-shared.js +120 -0
  14. package/src/agent-ops/query-builders/multi-agent.js +547 -0
  15. package/src/agent-ops/query-builders/projection-impacts.js +514 -0
  16. package/src/agent-ops/query-builders/work-packets.js +417 -0
  17. package/src/agent-ops/query-builders/workflow-context-shared.js +300 -0
  18. package/src/agent-ops/query-builders/workflow-context.js +398 -0
  19. package/src/agent-ops/query-builders/workflow-presets-core.js +676 -0
  20. package/src/agent-ops/query-builders/workflow-presets.js +341 -0
  21. package/src/agent-ops/query-builders.d.ts +26 -26
  22. package/src/agent-ops/query-builders.js +42 -5021
  23. package/src/catalog/constants.js +10 -0
  24. package/src/catalog/copy.js +60 -0
  25. package/src/catalog/diagnostics.js +15 -0
  26. package/src/catalog/entries.js +42 -0
  27. package/src/catalog/files.js +67 -0
  28. package/src/catalog/provenance.js +122 -0
  29. package/src/catalog/source.js +150 -0
  30. package/src/catalog/validation.js +252 -0
  31. package/src/catalog.d.ts +2 -0
  32. package/src/catalog.js +18 -746
  33. package/src/cli/commands/catalog/check.js +31 -0
  34. package/src/cli/commands/catalog/copy.js +59 -0
  35. package/src/cli/commands/catalog/doctor.js +248 -0
  36. package/src/cli/commands/catalog/help.js +21 -0
  37. package/src/cli/commands/catalog/list.js +52 -0
  38. package/src/cli/commands/catalog/runner.js +92 -0
  39. package/src/cli/commands/catalog/shared.js +17 -0
  40. package/src/cli/commands/catalog/show.js +134 -0
  41. package/src/cli/commands/catalog.js +30 -615
  42. package/src/cli/commands/generator-policy/package-info.js +162 -0
  43. package/src/cli/commands/generator-policy/payloads.js +372 -0
  44. package/src/cli/commands/generator-policy/printers.js +159 -0
  45. package/src/cli/commands/generator-policy/runner.js +81 -0
  46. package/src/cli/commands/generator-policy/shared.js +39 -0
  47. package/src/cli/commands/generator-policy.js +15 -783
  48. package/src/cli/commands/import/adopt.js +170 -0
  49. package/src/cli/commands/import/check.js +91 -0
  50. package/src/cli/commands/import/diff.js +84 -0
  51. package/src/cli/commands/import/help.js +47 -0
  52. package/src/cli/commands/import/paths.js +277 -0
  53. package/src/cli/commands/import/plan.js +284 -0
  54. package/src/cli/commands/import/refresh.js +470 -0
  55. package/src/cli/commands/import/status-history.js +196 -0
  56. package/src/cli/commands/import/workspace.js +230 -0
  57. package/src/cli/commands/import.js +33 -1732
  58. package/src/cli/commands/package/constants.js +17 -0
  59. package/src/cli/commands/package/doctor.js +240 -0
  60. package/src/cli/commands/package/help.js +27 -0
  61. package/src/cli/commands/package/lockfile.js +135 -0
  62. package/src/cli/commands/package/npm.js +97 -0
  63. package/src/cli/commands/package/reporting.js +35 -0
  64. package/src/cli/commands/package/runner.js +33 -0
  65. package/src/cli/commands/package/shared.js +9 -0
  66. package/src/cli/commands/package/update-cli.js +252 -0
  67. package/src/cli/commands/package/versions.js +35 -0
  68. package/src/cli/commands/package.js +29 -813
  69. package/src/cli/commands/query/change-plan.js +68 -0
  70. package/src/cli/commands/query/definitions.js +202 -0
  71. package/src/cli/commands/query/import-adopt.js +121 -0
  72. package/src/cli/commands/query/runner/artifacts.js +102 -0
  73. package/src/cli/commands/query/runner/boundaries.js +211 -0
  74. package/src/cli/commands/query/runner/change.js +182 -0
  75. package/src/cli/commands/query/runner/import-adopt.js +111 -0
  76. package/src/cli/commands/query/runner/index.js +31 -0
  77. package/src/cli/commands/query/runner/output.js +12 -0
  78. package/src/cli/commands/query/runner/workflow.js +241 -0
  79. package/src/cli/commands/query/runner.js +3 -0
  80. package/src/cli/commands/query/workflow-context.js +5 -0
  81. package/src/cli/commands/query/workspace.js +274 -0
  82. package/src/cli/commands/query.js +9 -1300
  83. package/src/cli/commands/template/baseline.js +100 -0
  84. package/src/cli/commands/template/check.js +466 -0
  85. package/src/cli/commands/template/constants.js +8 -0
  86. package/src/cli/commands/template/diagnostics.js +26 -0
  87. package/src/cli/commands/template/help.js +28 -0
  88. package/src/cli/commands/template/lifecycle.js +404 -0
  89. package/src/cli/commands/template/list-show.js +287 -0
  90. package/src/cli/commands/template/policy.js +422 -0
  91. package/src/cli/commands/template/shared.js +127 -0
  92. package/src/cli/commands/template/updates.js +352 -0
  93. package/src/cli/commands/template.js +41 -2143
  94. package/src/generator/api/contracts.js +497 -0
  95. package/src/generator/api/metadata.js +221 -0
  96. package/src/generator/api/openapi.js +559 -0
  97. package/src/generator/api/schema.js +124 -0
  98. package/src/generator/api/types.d.ts +98 -0
  99. package/src/generator/api.js +3 -1195
  100. package/src/generator/context/shared/domain-sdlc.js +282 -0
  101. package/src/generator/context/shared/maintained-boundary.js +665 -0
  102. package/src/generator/context/shared/metrics.js +85 -0
  103. package/src/generator/context/shared/primitives.js +64 -0
  104. package/src/generator/context/shared/relationships.js +453 -0
  105. package/src/generator/context/shared/summaries.js +263 -0
  106. package/src/generator/context/shared/types.d.ts +207 -0
  107. package/src/generator/context/shared.d.ts +42 -0
  108. package/src/generator/context/shared.js +80 -1390
  109. package/src/generator/context/slice/core.js +397 -0
  110. package/src/generator/context/slice/sdlc.js +417 -0
  111. package/src/generator/context/slice/ui-packets.js +183 -0
  112. package/src/generator/context/slice.js +2 -859
  113. package/src/generator/registry/index.js +507 -0
  114. package/src/generator/registry.js +18 -504
  115. package/src/generator/runtime/environment/index.js +666 -0
  116. package/src/generator/runtime/environment.js +4 -666
  117. package/src/generator/runtime/runtime-check/index.js +554 -0
  118. package/src/generator/runtime/runtime-check.js +4 -554
  119. package/src/generator/runtime/shared/index.js +572 -0
  120. package/src/generator/runtime/shared.js +19 -570
  121. package/src/generator/shared.d.ts +2 -0
  122. package/src/generator/surfaces/shared.d.ts +3 -0
  123. package/src/generator/widget-conformance/behavior-report.js +258 -0
  124. package/src/generator/widget-conformance/checks.js +371 -0
  125. package/src/generator/widget-conformance/projection-context.js +200 -0
  126. package/src/generator/widget-conformance/report.js +166 -0
  127. package/src/generator/widget-conformance/types.d.ts +121 -0
  128. package/src/generator/widget-conformance.js +3 -824
  129. package/src/import/core/context.d.ts +3 -0
  130. package/src/import/core/contracts.d.ts +1 -0
  131. package/src/import/core/registry.d.ts +4 -0
  132. package/src/import/core/runner/candidates.js +217 -0
  133. package/src/import/core/runner/options.js +22 -0
  134. package/src/import/core/runner/reports.js +50 -0
  135. package/src/import/core/runner/run.js +79 -0
  136. package/src/import/core/runner/tracks.js +150 -0
  137. package/src/import/core/runner/ui-drafts.js +337 -0
  138. package/src/import/core/runner.js +3 -698
  139. package/src/import/core/shared/api-routes.js +221 -0
  140. package/src/import/core/shared/candidates.js +97 -0
  141. package/src/import/core/shared/files.js +177 -0
  142. package/src/import/core/shared/next-app.js +389 -0
  143. package/src/import/core/shared/types.d.ts +51 -0
  144. package/src/import/core/shared/ui-routes.js +230 -0
  145. package/src/import/core/shared.js +60 -861
  146. package/src/new-project/constants.js +128 -0
  147. package/src/new-project/create.js +83 -0
  148. package/src/new-project/json.js +28 -0
  149. package/src/new-project/metadata.js +96 -0
  150. package/src/new-project/package-spec.js +161 -0
  151. package/src/new-project/project-files.js +348 -0
  152. package/src/new-project/template-policy.js +269 -0
  153. package/src/new-project/template-resolution.js +368 -0
  154. package/src/new-project/template-snapshots.js +430 -0
  155. package/src/new-project/template-updates.js +512 -0
  156. package/src/new-project/types.d.ts +83 -0
  157. package/src/new-project.js +6 -2277
  158. package/src/parser.d.ts +87 -1
  159. package/src/parser.js +118 -0
  160. package/src/policy/review-boundaries.d.ts +15 -0
  161. package/src/project-config/index.js +564 -0
  162. package/src/project-config.js +19 -561
  163. package/src/resolver/enrich/acceptance-criterion.js +2 -0
  164. package/src/resolver/enrich/bug.js +2 -0
  165. package/src/resolver/enrich/pitch.js +2 -0
  166. package/src/resolver/enrich/requirement.js +2 -0
  167. package/src/resolver/enrich/task.js +2 -0
  168. package/src/resolver/index.js +19 -2089
  169. package/src/resolver/normalize.js +384 -1
  170. package/src/resolver/plans.js +168 -0
  171. package/src/resolver/projections-api.js +494 -0
  172. package/src/resolver/projections-db.js +133 -0
  173. package/src/resolver/projections-ui.js +317 -0
  174. package/src/resolver/shapes.js +251 -0
  175. package/src/resolver/shared.js +278 -0
  176. package/src/resolver/widgets.js +132 -0
  177. package/src/template-trust/constants.js +62 -0
  178. package/src/template-trust/content.js +258 -0
  179. package/src/template-trust/diff.js +92 -0
  180. package/src/template-trust/policy.js +61 -0
  181. package/src/template-trust/record.js +90 -0
  182. package/src/template-trust/status.js +182 -0
  183. package/src/template-trust.js +24 -687
  184. package/src/text-helpers.d.ts +1 -0
  185. package/src/topogram-types.d.ts +69 -0
  186. package/src/validator/common.js +488 -0
  187. package/src/validator/data-model.js +237 -0
  188. package/src/validator/docs.js +167 -0
  189. package/src/validator/expressions.js +146 -1
  190. package/src/validator/index.d.ts +23 -0
  191. package/src/validator/index.js +32 -3585
  192. package/src/validator/kinds.d.ts +41 -0
  193. package/src/validator/kinds.js +2 -0
  194. package/src/validator/model-helpers.js +46 -0
  195. package/src/validator/per-kind/acceptance-criterion.js +5 -0
  196. package/src/validator/per-kind/bug.js +6 -0
  197. package/src/validator/per-kind/domain.js +15 -2
  198. package/src/validator/per-kind/pitch.js +7 -0
  199. package/src/validator/per-kind/requirement.js +5 -0
  200. package/src/validator/per-kind/task.js +7 -0
  201. package/src/validator/per-kind/widget.js +14 -0
  202. package/src/validator/projections/api-http-async.js +410 -0
  203. package/src/validator/projections/api-http-authz.js +88 -0
  204. package/src/validator/projections/api-http-core.js +205 -0
  205. package/src/validator/projections/api-http-policies.js +339 -0
  206. package/src/validator/projections/api-http-responses.js +233 -0
  207. package/src/validator/projections/api-http.js +44 -0
  208. package/src/validator/projections/db.js +353 -0
  209. package/src/validator/projections/generator-defaults.js +45 -0
  210. package/src/validator/projections/helpers.js +87 -0
  211. package/src/validator/projections/ui-helpers.js +214 -0
  212. package/src/validator/projections/ui-navigation.js +344 -0
  213. package/src/validator/projections/ui-structure.js +364 -0
  214. package/src/validator/projections/ui-widgets.js +493 -0
  215. package/src/validator/projections/ui.js +46 -0
  216. package/src/validator/registry.js +48 -1
  217. package/src/validator/utils.d.ts +20 -0
  218. package/src/validator/utils.js +115 -12
  219. package/src/widget-behavior.d.ts +1 -0
  220. package/src/workflows/import-app/api/collect.js +221 -0
  221. package/src/workflows/import-app/api/openapi.js +257 -0
  222. package/src/workflows/import-app/api/routes.js +327 -0
  223. package/src/workflows/import-app/api/sources.js +22 -0
  224. package/src/workflows/import-app/api.js +2 -797
  225. package/src/workflows/reconcile/adoption-plan/build.js +208 -0
  226. package/src/workflows/reconcile/adoption-plan/dependencies.js +75 -0
  227. package/src/workflows/reconcile/adoption-plan/outputs.js +143 -0
  228. package/src/workflows/reconcile/adoption-plan/paths.js +58 -0
  229. package/src/workflows/reconcile/adoption-plan/projection-patches.js +177 -0
  230. package/src/workflows/reconcile/adoption-plan/reasons.js +107 -0
  231. package/src/workflows/reconcile/adoption-plan.js +30 -740
  232. package/src/workflows/reconcile/auth/closures.js +115 -0
  233. package/src/workflows/reconcile/auth/formatters.js +142 -0
  234. package/src/workflows/reconcile/auth/inference.js +330 -0
  235. package/src/workflows/reconcile/auth/roles.js +122 -0
  236. package/src/workflows/reconcile/auth.js +35 -690
  237. package/src/workflows/reconcile/bundle-core/index.js +600 -0
  238. package/src/workflows/reconcile/bundle-core.js +12 -598
  239. package/src/workflows/reconcile/canonical-surface.js +1 -1
  240. package/src/workflows/reconcile/impacts/adoption-plan.js +192 -0
  241. package/src/workflows/reconcile/impacts/indexes.js +101 -0
  242. package/src/workflows/reconcile/impacts/patches.js +252 -0
  243. package/src/workflows/reconcile/impacts/reports.js +80 -0
  244. package/src/workflows/reconcile/impacts.js +14 -623
  245. package/src/workspace-docs.d.ts +29 -0
@@ -0,0 +1,200 @@
1
+ // @ts-check
2
+
3
+ import { sharedUiProjectionForWeb } from "../surfaces/shared.js";
4
+
5
+ /**
6
+ * @param {any} entries
7
+ * @returns {any}
8
+ */
9
+ export function byId(entries = []) {
10
+ return new Map(entries.map(/** @param {any} entry */ (entry) => [entry.id, entry]));
11
+ }
12
+
13
+ /**
14
+ * @param {any} values
15
+ * @returns {any}
16
+ */
17
+ export function stableUnique(values) {
18
+ return [...new Set(values.filter(Boolean))].sort();
19
+ }
20
+
21
+ /**
22
+ * @param {any} entry
23
+ * @returns {any}
24
+ */
25
+ export function sourcePath(entry) {
26
+ return entry?.loc?.file || null;
27
+ }
28
+
29
+ /**
30
+ * @param {import("./types.d.ts").WidgetStatement} widget
31
+ * @returns {any}
32
+ */
33
+ export function widgetContract(widget) {
34
+ return widget?.widgetContract || null;
35
+ }
36
+
37
+ /**
38
+ * @param {import("./types.d.ts").WidgetProjection} projection
39
+ * @returns {any}
40
+ */
41
+ export function summarizeProjection(projection) {
42
+ return projection
43
+ ? {
44
+ id: projection.id,
45
+ name: projection.name || projection.id,
46
+ type: projection.type || projection.type || null,
47
+ status: projection.status || null,
48
+ source_path: sourcePath(projection)
49
+ }
50
+ : null;
51
+ }
52
+
53
+ /**
54
+ * @param {import("./types.d.ts").WidgetStatement} widget
55
+ * @returns {any}
56
+ */
57
+ export function summarizeWidget(widget) {
58
+ return widget
59
+ ? {
60
+ id: widget.id,
61
+ name: widget.name || widget.id,
62
+ category: widget.category || null,
63
+ version: widget.version || null,
64
+ status: widget.status || null,
65
+ source_path: sourcePath(widget)
66
+ }
67
+ : null;
68
+ }
69
+
70
+ /**
71
+ * @param {import("./types.d.ts").WidgetStatement} widget
72
+ * @returns {any}
73
+ */
74
+ export function summarizeWidgetContract(widget) {
75
+ const contract = widgetContract(widget);
76
+ if (!contract) return null;
77
+ return {
78
+ id: contract.id,
79
+ name: contract.name,
80
+ category: contract.category || null,
81
+ version: contract.version || null,
82
+ status: contract.status || null,
83
+ props: contract.props || [],
84
+ events: contract.events || [],
85
+ behaviors: contract.behaviors || [],
86
+ behavior: contract.behavior || [],
87
+ approvals: contract.approvals || [],
88
+ dependencies: contract.dependencies || [],
89
+ source_path: sourcePath(widget)
90
+ };
91
+ }
92
+
93
+ /**
94
+ * @param {import("./types.d.ts").WidgetProjection} projection
95
+ * @returns {any}
96
+ */
97
+ export function projectionRealizesIds(projection) {
98
+ return new Set((projection?.realizes || []).map(/** @param {any} ref */ (ref) => ref.id).filter(Boolean));
99
+ }
100
+
101
+ /**
102
+ * @param {import("./types.d.ts").WidgetProjection} projection
103
+ * @returns {any}
104
+ */
105
+ export function ownProjectionScreenMap(projection) {
106
+ return new Map((projection?.uiScreens || []).map(/** @param {any} screen */ (screen) => [screen.id, screen]));
107
+ }
108
+
109
+ /**
110
+ * @param {import("./types.d.ts").WidgetProjection} projection
111
+ * @returns {any}
112
+ */
113
+ export function ownProjectionRegionKeys(projection) {
114
+ return new Set((projection?.uiScreenRegions || []).map(/** @param {any} entry */ (entry) => `${entry.screenId}:${entry.region}`));
115
+ }
116
+
117
+ /**
118
+ * @param {import("./types.d.ts").WidgetGraph} graph
119
+ * @returns {any}
120
+ */
121
+ export function projectionById(graph) {
122
+ return byId(graph.byKind.projection || []);
123
+ }
124
+
125
+ /**
126
+ * @param {import("./types.d.ts").WidgetGraph} graph
127
+ * @param {import("./types.d.ts").WidgetProjection} projection
128
+ * @returns {any}
129
+ */
130
+ export function projectionContext(graph, projection) {
131
+ const projections = /** @type {any[]} */ ([]);
132
+ const seen = new Set();
133
+ const projectionsById = projectionById(graph);
134
+
135
+ /**
136
+ * @param {any} current
137
+ * @returns {void}
138
+ */
139
+ function visit(current) {
140
+ if (!current || seen.has(current.id)) {
141
+ return;
142
+ }
143
+ seen.add(current.id);
144
+ projections.push(current);
145
+ for (const ref of current.realizes || []) {
146
+ const target = projectionsById.get(ref.id);
147
+ if (target) {
148
+ visit(target);
149
+ }
150
+ }
151
+ }
152
+
153
+ visit(projection);
154
+ return projections;
155
+ }
156
+
157
+ /**
158
+ * @param {import("./types.d.ts").WidgetGraph} graph
159
+ * @param {import("./types.d.ts").WidgetProjection} projection
160
+ * @returns {any}
161
+ */
162
+ export function projectionScreenMap(graph, projection) {
163
+ const screens = new Map();
164
+ for (const contextProjection of projectionContext(graph, projection).reverse()) {
165
+ for (const [id, screen] of ownProjectionScreenMap(contextProjection)) {
166
+ screens.set(id, screen);
167
+ }
168
+ }
169
+ return screens;
170
+ }
171
+
172
+ /**
173
+ * @param {import("./types.d.ts").WidgetGraph} graph
174
+ * @param {import("./types.d.ts").WidgetProjection} projection
175
+ * @returns {any}
176
+ */
177
+ export function projectionRegionKeys(graph, projection) {
178
+ const regions = new Set();
179
+ for (const contextProjection of projectionContext(graph, projection)) {
180
+ for (const key of ownProjectionRegionKeys(contextProjection)) {
181
+ regions.add(key);
182
+ }
183
+ }
184
+ return regions;
185
+ }
186
+
187
+ /**
188
+ * @param {import("./types.d.ts").WidgetGraph} graph
189
+ * @param {import("./types.d.ts").WidgetProjection} projection
190
+ * @returns {any}
191
+ */
192
+ export function projectionContextRealizesIds(graph, projection) {
193
+ const ids = new Set();
194
+ for (const contextProjection of projectionContext(graph, projection)) {
195
+ for (const id of projectionRealizesIds(contextProjection)) {
196
+ ids.add(id);
197
+ }
198
+ }
199
+ return ids;
200
+ }
@@ -0,0 +1,166 @@
1
+ // @ts-check
2
+
3
+ import { getProjection, sharedUiProjectionForWeb, uiProjectionCandidates } from "../surfaces/shared.js";
4
+ import { buildWidgetBehaviorRealizations } from "../../widget-behavior.js";
5
+ import { collectUsageChecks, widgetUsageKey } from "./checks.js";
6
+ import {
7
+ byId,
8
+ projectionScreenMap,
9
+ sourcePath,
10
+ stableUnique,
11
+ summarizeProjection,
12
+ summarizeWidget,
13
+ summarizeWidgetContract,
14
+ widgetContract
15
+ } from "./projection-context.js";
16
+
17
+ /**
18
+ * @param {import("./types.d.ts").WidgetGraph} graph
19
+ * @param {import("./types.d.ts").WidgetProjection} projection
20
+ * @returns {import("./types.d.ts").WidgetUsageEntry[]}
21
+ */
22
+ export function projectionUsageEntries(graph, projection) {
23
+ const sharedProjection = sharedUiProjectionForWeb(graph, projection);
24
+ const entries = /** @type {import("./types.d.ts").WidgetUsageEntry[]} */ ([]);
25
+ if (sharedProjection) {
26
+ entries.push(...(sharedProjection.widgetBindings || []).map(/** @param {import("./types.d.ts").WidgetUsage} usage @param {any} index */ (usage, index) => ({
27
+ projection,
28
+ sourceProjection: sharedProjection,
29
+ usage,
30
+ index
31
+ })));
32
+ }
33
+ entries.push(...(projection.widgetBindings || []).map(/** @param {import("./types.d.ts").WidgetUsage} usage @param {any} index */ (usage, index) => ({
34
+ projection,
35
+ sourceProjection: projection,
36
+ usage,
37
+ index
38
+ })));
39
+ return entries;
40
+ }
41
+
42
+ /**
43
+ * @param {import("./types.d.ts").WidgetGraph} graph
44
+ * @param {string | null | undefined} projectionId
45
+ * @returns {any}
46
+ */
47
+ export function candidateProjections(graph, projectionId) {
48
+ if (projectionId) {
49
+ return [getProjection(graph, projectionId)];
50
+ }
51
+ const direct = uiProjectionCandidates(graph).filter(/** @param {import("./types.d.ts").WidgetProjection} projection */ (projection) => (projection.widgetBindings || []).length > 0);
52
+ const inherited = (graph.byKind.projection || []).filter(/** @param {import("./types.d.ts").WidgetProjection} projection */ (projection) => {
53
+ if ((projection.widgetBindings || []).length > 0) return false;
54
+ return Boolean(sharedUiProjectionForWeb(graph, projection)?.widgetBindings?.length);
55
+ });
56
+ return [...direct, ...inherited].sort((a, b) => a.id.localeCompare(b.id));
57
+ }
58
+
59
+ /**
60
+ * @param {import("./types.d.ts").WidgetGraph} graph
61
+ * @param {Iterable<string>} widgetIds
62
+ * @param {Iterable<string>} projectionIds
63
+ * @returns {any}
64
+ */
65
+ export function relatedVerificationFiles(graph, widgetIds, projectionIds) {
66
+ const ids = new Set([...widgetIds, ...projectionIds]);
67
+ return stableUnique((graph.byKind.verification || [])
68
+ .filter(/** @param {any} verification */ (verification) => (verification.validates || []).some(/** @param {any} ref */ (ref) => ids.has(ref.id)))
69
+ .map(/** @param {any} verification */ (verification) => sourcePath(verification)));
70
+ }
71
+
72
+ /**
73
+ * @param {import("./types.d.ts").WidgetGraph} graph
74
+ * @param {import("./types.d.ts").WidgetOptions} options
75
+ * @returns {any}
76
+ */
77
+ export function generateWidgetConformanceReport(graph, options = {}) {
78
+ const selectedWidgetId = options.widgetId || options.componentId || null;
79
+ const widgets = byId(graph.byKind.widget || []);
80
+ if (selectedWidgetId && !widgets.has(selectedWidgetId)) {
81
+ throw new Error(`No widget found with id '${selectedWidgetId}'`);
82
+ }
83
+
84
+ const projectionUsageRecords = /** @type {import("./types.d.ts").WidgetProjectionUsageRecord[]} */ ([]);
85
+ const checks = /** @type {any[]} */ ([]);
86
+ const referencedWidgetIds = /** @type {Set<string>} */ (new Set());
87
+ const affectedProjectionIds = /** @type {Set<string>} */ (new Set());
88
+
89
+ for (const projection of candidateProjections(graph, options.projectionId)) {
90
+ for (const entry of projectionUsageEntries(graph, projection)) {
91
+ const widgetId = entry.usage.widget?.id || null;
92
+ if (selectedWidgetId && widgetId !== selectedWidgetId) {
93
+ continue;
94
+ }
95
+ const widget = widgetId ? widgets.get(widgetId) : null;
96
+ if (widgetId) referencedWidgetIds.add(widgetId);
97
+ affectedProjectionIds.add(entry.projection.id);
98
+ if (entry.sourceProjection?.id) affectedProjectionIds.add(entry.sourceProjection.id);
99
+ const usageChecks = collectUsageChecks({ graph, projection: entry.projection, sourceProjection: entry.sourceProjection, usage: entry.usage, widget });
100
+ checks.push(...usageChecks);
101
+ const outcome = usageChecks.some(/** @param {any} check */ (check) => check.severity === "error")
102
+ ? "error"
103
+ : usageChecks.some(/** @param {any} check */ (check) => check.severity === "warning")
104
+ ? "warning"
105
+ : "pass";
106
+ projectionUsageRecords.push({
107
+ key: widgetUsageKey(entry.projection, entry.sourceProjection, entry.usage, entry.index),
108
+ projection: summarizeProjection(entry.projection),
109
+ source_projection: entry.sourceProjection.id === entry.projection.id ? null : summarizeProjection(entry.sourceProjection),
110
+ screen: {
111
+ id: entry.usage.screenId || null,
112
+ kind: projectionScreenMap(graph, entry.sourceProjection).get(entry.usage.screenId)?.kind || null,
113
+ title: projectionScreenMap(graph, entry.sourceProjection).get(entry.usage.screenId)?.title || null
114
+ },
115
+ region: entry.usage.region || null,
116
+ widget: summarizeWidget(widget) || { id: widgetId, name: widgetId, category: null, version: null, status: null, source_path: null },
117
+ data_bindings: entry.usage.dataBindings || [],
118
+ event_bindings: entry.usage.eventBindings || [],
119
+ behavior_realizations: buildWidgetBehaviorRealizations(widgetContract(widget), entry.usage),
120
+ outcome,
121
+ check_codes: usageChecks.map(/** @param {any} check */ (check) => check.code)
122
+ });
123
+ }
124
+ }
125
+
126
+ const widgetFiles = stableUnique([...referencedWidgetIds].map(/** @param {any} id */ (id) => sourcePath(widgets.get(id))));
127
+ const projectionFiles = stableUnique(
128
+ [...affectedProjectionIds].map(/** @param {any} id */ (id) => sourcePath((graph.byKind.projection || []).find(/** @param {import("./types.d.ts").WidgetProjection} projection */ (projection) => projection.id === id)))
129
+ );
130
+ const verificationFiles = relatedVerificationFiles(graph, referencedWidgetIds, affectedProjectionIds);
131
+ const errors = checks.filter(/** @param {any} check */ (check) => check.severity === "error");
132
+ const warnings = checks.filter(/** @param {any} check */ (check) => check.severity === "warning");
133
+
134
+ return {
135
+ type: "widget_conformance_report",
136
+ filters: {
137
+ projection: options.projectionId || null,
138
+ widget: selectedWidgetId
139
+ },
140
+ summary: {
141
+ total_usages: projectionUsageRecords.length,
142
+ passed_usages: projectionUsageRecords.filter(/** @param {import("./types.d.ts").WidgetProjectionUsageRecord} usage */ (usage) => usage.outcome === "pass").length,
143
+ warning_usages: projectionUsageRecords.filter(/** @param {import("./types.d.ts").WidgetProjectionUsageRecord} usage */ (usage) => usage.outcome === "warning").length,
144
+ error_usages: projectionUsageRecords.filter(/** @param {import("./types.d.ts").WidgetProjectionUsageRecord} usage */ (usage) => usage.outcome === "error").length,
145
+ warnings: warnings.length,
146
+ errors: errors.length,
147
+ affected_projections: stableUnique([...affectedProjectionIds]),
148
+ affected_widgets: stableUnique([...referencedWidgetIds])
149
+ },
150
+ projection_usages: projectionUsageRecords,
151
+ checks,
152
+ widget_contracts: stableUnique([...referencedWidgetIds])
153
+ .map(/** @param {any} id */ (id) => summarizeWidgetContract(widgets.get(id)))
154
+ .filter(Boolean),
155
+ write_scope: {
156
+ widget_files: widgetFiles,
157
+ projection_files: projectionFiles,
158
+ verification_files: verificationFiles,
159
+ paths: stableUnique([...widgetFiles, ...projectionFiles, ...verificationFiles])
160
+ },
161
+ impact: {
162
+ projections: stableUnique([...affectedProjectionIds]),
163
+ widgets: stableUnique([...referencedWidgetIds])
164
+ }
165
+ };
166
+ }
@@ -0,0 +1,121 @@
1
+ export type WidgetReference = {
2
+ id?: string;
3
+ kind?: string;
4
+ target?: {
5
+ id?: string;
6
+ kind?: string;
7
+ };
8
+ [key: string]: any;
9
+ };
10
+
11
+ export type WidgetGraph = {
12
+ statements: any[];
13
+ byKind: Record<string, any[]>;
14
+ [key: string]: any;
15
+ };
16
+
17
+ export type WidgetProjection = {
18
+ id: string;
19
+ name?: string;
20
+ type?: string;
21
+ status?: string;
22
+ realizes?: WidgetReference[];
23
+ uiScreens?: any[];
24
+ uiScreenRegions?: any[];
25
+ widgetBindings?: WidgetUsage[];
26
+ loc?: {
27
+ file?: string;
28
+ };
29
+ [key: string]: any;
30
+ };
31
+
32
+ export type WidgetContract = {
33
+ id?: string;
34
+ name?: string;
35
+ category?: string;
36
+ version?: string;
37
+ status?: string;
38
+ props?: any[];
39
+ events?: any[];
40
+ behaviors?: WidgetBehavior[];
41
+ behavior?: WidgetBehavior[];
42
+ approvals?: any[];
43
+ dependencies?: any[];
44
+ patterns?: string[];
45
+ regions?: string[];
46
+ [key: string]: any;
47
+ };
48
+
49
+ export type WidgetStatement = {
50
+ id: string;
51
+ name?: string;
52
+ category?: string;
53
+ version?: string;
54
+ status?: string;
55
+ widgetContract?: WidgetContract;
56
+ loc?: {
57
+ file?: string;
58
+ };
59
+ [key: string]: any;
60
+ };
61
+
62
+ export type WidgetUsage = {
63
+ widget?: WidgetReference;
64
+ screenId?: string;
65
+ region?: string;
66
+ dataBindings?: any[];
67
+ eventBindings?: any[];
68
+ [key: string]: any;
69
+ };
70
+
71
+ export type WidgetUsageEntry = {
72
+ projection: WidgetProjection;
73
+ sourceProjection: WidgetProjection;
74
+ usage: WidgetUsage;
75
+ index: number;
76
+ };
77
+
78
+ export type WidgetBehavior = {
79
+ kind?: string;
80
+ source?: string;
81
+ status?: string;
82
+ directives?: any;
83
+ dataDependencies?: any[];
84
+ emits?: any[];
85
+ actions?: any[];
86
+ effects?: any[];
87
+ [key: string]: any;
88
+ };
89
+
90
+ export type WidgetUsageReport = {
91
+ key?: string;
92
+ projection?: any;
93
+ source_projection?: any;
94
+ screen?: any;
95
+ region?: string | null;
96
+ widget?: any;
97
+ behavior_realizations?: WidgetBehavior[];
98
+ [key: string]: any;
99
+ };
100
+
101
+ export type WidgetProjectionUsageRecord = WidgetUsageReport & {
102
+ outcome: "pass" | "warning" | "error";
103
+ check_codes: string[];
104
+ };
105
+
106
+ export type WidgetConformanceReport = {
107
+ filters?: any;
108
+ summary?: any;
109
+ projection_usages?: WidgetUsageReport[];
110
+ checks?: any[];
111
+ write_scope?: any;
112
+ impact?: any;
113
+ [key: string]: any;
114
+ };
115
+
116
+ export type WidgetOptions = {
117
+ widgetId?: string | null;
118
+ componentId?: string | null;
119
+ projectionId?: string | null;
120
+ [key: string]: any;
121
+ };