@transitrix/diagrams 1.0.0 → 1.1.0

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 (315) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +47 -47
  3. package/dist/__tests__/edge-path.test.js +8 -0
  4. package/dist/activities/cpm.js +11 -2
  5. package/dist/activities/gantt.js +6 -3
  6. package/dist/activities/types.d.ts +1 -0
  7. package/dist/activities/validate.js +3 -3
  8. package/dist/activity-card/__tests__/example.test.js +20 -1
  9. package/dist/activity-card/__tests__/layout.test.js +102 -11
  10. package/dist/activity-card/__tests__/resolver.test.js +161 -7
  11. package/dist/activity-card/index.d.ts +1 -1
  12. package/dist/activity-card/layout.d.ts +1 -1
  13. package/dist/activity-card/layout.js +220 -103
  14. package/dist/activity-card/resolver.js +115 -28
  15. package/dist/activity-card/types.d.ts +150 -27
  16. package/dist/activity-card/validate.js +3 -0
  17. package/dist/actor/__tests__/validate.test.js +63 -31
  18. package/dist/actor/index.d.ts +1 -1
  19. package/dist/actor/index.js +1 -1
  20. package/dist/actor/types.d.ts +7 -3
  21. package/dist/actor/types.js +17 -3
  22. package/dist/actor/validate.js +55 -26
  23. package/dist/assertion/types.d.ts +3 -1
  24. package/dist/assertion/types.js +1 -1
  25. package/dist/change/__tests__/validate.test.js +40 -34
  26. package/dist/change/index.d.ts +1 -0
  27. package/dist/change/types.d.ts +1 -1
  28. package/dist/change/types.js +2 -2
  29. package/dist/change/validate.d.ts +6 -1
  30. package/dist/change/validate.js +68 -41
  31. package/dist/compliance/__tests__/classify.test.js +34 -0
  32. package/dist/compliance/__tests__/coverage-metric.test.js +146 -46
  33. package/dist/compliance/__tests__/html.test.js +2 -2
  34. package/dist/compliance/__tests__/impact.test.js +509 -6
  35. package/dist/compliance/classify.d.ts +6 -0
  36. package/dist/compliance/classify.js +9 -1
  37. package/dist/compliance/coverage-metric.d.ts +31 -11
  38. package/dist/compliance/coverage-metric.js +149 -39
  39. package/dist/compliance/html.js +78 -81
  40. package/dist/compliance/impact.d.ts +100 -16
  41. package/dist/compliance/impact.js +272 -28
  42. package/dist/compliance/index.d.ts +2 -2
  43. package/dist/compliance/index.js +1 -1
  44. package/dist/compliance/markdown.js +1 -0
  45. package/dist/compliance/types.d.ts +25 -6
  46. package/dist/edge-path.d.ts +8 -4
  47. package/dist/edge-path.js +11 -6
  48. package/dist/factor/__tests__/validate.test.js +75 -46
  49. package/dist/factor/index.d.ts +3 -2
  50. package/dist/factor/index.js +1 -1
  51. package/dist/factor/types.d.ts +5 -8
  52. package/dist/factor/types.js +10 -5
  53. package/dist/factor/validate.d.ts +6 -1
  54. package/dist/factor/validate.js +68 -50
  55. package/dist/fgca/__tests__/chain-table.test.js +2 -2
  56. package/dist/fgca/__tests__/layout.test.js +11 -11
  57. package/dist/fgca/__tests__/preview-layout.test.js +7 -7
  58. package/dist/fgca/__tests__/resolver.test.js +185 -0
  59. package/dist/fgca/chain-table.d.ts +1 -1
  60. package/dist/fgca/chain-table.js +4 -4
  61. package/dist/fgca/index.d.ts +4 -2
  62. package/dist/fgca/index.js +2 -1
  63. package/dist/fgca/layout.d.ts +2 -2
  64. package/dist/fgca/layout.js +9 -9
  65. package/dist/fgca/nodeTypes.d.ts +1 -1
  66. package/dist/fgca/nodeTypes.js +2 -2
  67. package/dist/fgca/nodes/FGCAFactorNode.d.ts +3 -3
  68. package/dist/fgca/nodes/FGCAFactorNode.js +5 -5
  69. package/dist/fgca/parse-canonical.js +15 -10
  70. package/dist/fgca/preview-layout.d.ts +1 -1
  71. package/dist/fgca/preview-layout.js +4 -4
  72. package/dist/fgca/resolver.d.ts +49 -0
  73. package/dist/fgca/resolver.js +126 -0
  74. package/dist/fgca/types.d.ts +11 -11
  75. package/dist/fgca/types.js +2 -2
  76. package/dist/fgca/validate.d.ts +2 -2
  77. package/dist/fgca/validate.js +17 -14
  78. package/dist/goals/index.d.ts +1 -1
  79. package/dist/index.d.ts +5 -0
  80. package/dist/index.js +5 -0
  81. package/dist/process-blueprint/__tests__/layout.test.js +37 -0
  82. package/dist/process-blueprint/index.d.ts +1 -1
  83. package/dist/process-blueprint/layout.js +66 -35
  84. package/dist/process-blueprint/types.d.ts +36 -1
  85. package/dist/scenarios/index.d.ts +1 -1
  86. package/dist/scenarios/types.d.ts +4 -4
  87. package/dist/stakeholder/__tests__/validate.test.js +49 -47
  88. package/dist/stakeholder/index.d.ts +1 -0
  89. package/dist/stakeholder/types.d.ts +3 -4
  90. package/dist/stakeholder/types.js +2 -3
  91. package/dist/stakeholder/validate.d.ts +6 -1
  92. package/dist/stakeholder/validate.js +71 -50
  93. package/dist/target-state/__tests__/validate.test.js +43 -27
  94. package/dist/target-state/index.d.ts +2 -0
  95. package/dist/target-state/index.js +1 -0
  96. package/dist/target-state/types.d.ts +6 -1
  97. package/dist/target-state/types.js +8 -7
  98. package/dist/target-state/validate.d.ts +6 -1
  99. package/dist/target-state/validate.js +69 -45
  100. package/dist/theme/themes.js +71 -69
  101. package/dist/theme/tokens.d.ts +7 -1
  102. package/dist/theme/tokens.js +3 -1
  103. package/dist/webview/__tests__/entry-notations.test.js +2 -0
  104. package/dist/webview/__tests__/entry.test.js +11 -11
  105. package/dist/webview/__tests__/render-process.test.js +463 -0
  106. package/dist/webview/__tests__/render-util.test.d.ts +1 -0
  107. package/dist/webview/__tests__/render-util.test.js +54 -0
  108. package/dist/webview/entry.d.ts +1 -1
  109. package/dist/webview/entry.js +9 -5
  110. package/dist/webview/render-activities.d.ts +24 -2
  111. package/dist/webview/render-activities.js +92 -57
  112. package/dist/webview/render-activity-card.d.ts +11 -1
  113. package/dist/webview/render-activity-card.js +115 -79
  114. package/dist/webview/render-blocks.d.ts +24 -1
  115. package/dist/webview/render-blocks.js +58 -24
  116. package/dist/webview/render-fgca.d.ts +31 -0
  117. package/dist/webview/render-fgca.js +30 -19
  118. package/dist/webview/render-goals.d.ts +27 -1
  119. package/dist/webview/render-goals.js +42 -32
  120. package/dist/webview/render-process-blueprint.d.ts +11 -1
  121. package/dist/webview/render-process-blueprint.js +118 -53
  122. package/dist/webview/render-process.d.ts +95 -0
  123. package/dist/webview/render-process.js +392 -0
  124. package/dist/webview/render-scenarios.js +2 -2
  125. package/dist/webview/render-util.d.ts +19 -6
  126. package/dist/webview/render-util.js +23 -15
  127. package/package.json +54 -40
  128. package/src/__tests__/edge-path.test.ts +58 -46
  129. package/src/__tests__/scope.test.ts +27 -27
  130. package/src/__tests__/yaml-normalize.test.ts +158 -158
  131. package/src/activities/__tests__/cpm.test.ts +164 -164
  132. package/src/activities/__tests__/gantt.test.ts +245 -245
  133. package/src/activities/__tests__/layout.test.ts +112 -112
  134. package/src/activities/__tests__/validate.test.ts +409 -409
  135. package/src/activities/cpm.ts +107 -95
  136. package/src/activities/gantt.ts +277 -276
  137. package/src/activities/index.ts +28 -28
  138. package/src/activities/layout.ts +112 -112
  139. package/src/activities/types.ts +149 -148
  140. package/src/activities/validate.ts +357 -357
  141. package/src/activity-card/__tests__/example.test.ts +85 -66
  142. package/src/activity-card/__tests__/layout.test.ts +169 -63
  143. package/src/activity-card/__tests__/resolver.test.ts +330 -161
  144. package/src/activity-card/__tests__/validate.test.ts +131 -131
  145. package/src/activity-card/index.ts +38 -32
  146. package/src/activity-card/layout.ts +324 -194
  147. package/src/activity-card/resolver.ts +422 -337
  148. package/src/activity-card/types.ts +376 -237
  149. package/src/activity-card/validate.ts +162 -158
  150. package/src/actor/__tests__/validate.test.ts +70 -31
  151. package/src/actor/index.ts +1 -1
  152. package/src/actor/types.ts +21 -7
  153. package/src/actor/validate.ts +59 -27
  154. package/src/applications/__tests__/validate.test.ts +256 -256
  155. package/src/applications/index.ts +11 -11
  156. package/src/applications/types.ts +43 -43
  157. package/src/applications/validate.ts +131 -131
  158. package/src/assertion/__tests__/example.test.ts +37 -37
  159. package/src/assertion/__tests__/validate.test.ts +142 -142
  160. package/src/assertion/index.ts +12 -12
  161. package/src/assertion/types.ts +60 -58
  162. package/src/assertion/validate.ts +145 -145
  163. package/src/blocks/__tests__/layout.test.ts +169 -169
  164. package/src/blocks/__tests__/validate.test.ts +260 -260
  165. package/src/blocks/index.ts +17 -17
  166. package/src/blocks/layout.ts +186 -186
  167. package/src/blocks/types.ts +62 -62
  168. package/src/blocks/validate.ts +206 -206
  169. package/src/capability-map/__tests__/validate.test.ts +238 -238
  170. package/src/capability-map/index.ts +8 -8
  171. package/src/capability-map/types.ts +29 -29
  172. package/src/capability-map/validate.ts +127 -127
  173. package/src/change/__tests__/validate.test.ts +43 -34
  174. package/src/change/index.ts +1 -0
  175. package/src/change/types.ts +5 -3
  176. package/src/change/validate.ts +75 -43
  177. package/src/compliance/__tests__/classify.test.ts +64 -27
  178. package/src/compliance/__tests__/confidence.test.ts +98 -98
  179. package/src/compliance/__tests__/coverage-metric.test.ts +300 -188
  180. package/src/compliance/__tests__/demo-scenario.test.ts +273 -273
  181. package/src/compliance/__tests__/example.test.ts +57 -57
  182. package/src/compliance/__tests__/gap-report.test.ts +128 -128
  183. package/src/compliance/__tests__/html.test.ts +141 -141
  184. package/src/compliance/__tests__/impact.test.ts +1059 -481
  185. package/src/compliance/__tests__/markdown.test.ts +94 -94
  186. package/src/compliance/__tests__/views.test.ts +64 -64
  187. package/src/compliance/classify.ts +100 -84
  188. package/src/compliance/confidence.ts +69 -69
  189. package/src/compliance/coverage-metric.ts +404 -263
  190. package/src/compliance/gap-report.ts +94 -94
  191. package/src/compliance/html.ts +291 -295
  192. package/src/compliance/impact.ts +979 -677
  193. package/src/compliance/index.ts +57 -56
  194. package/src/compliance/markdown.ts +136 -135
  195. package/src/compliance/reverse-index.ts +33 -33
  196. package/src/compliance/types.ts +136 -120
  197. package/src/compliance/views.ts +46 -46
  198. package/src/compliance-matrix/__tests__/build.test.ts +200 -200
  199. package/src/compliance-matrix/__tests__/example.test.ts +57 -57
  200. package/src/compliance-matrix/index.ts +11 -11
  201. package/src/compliance-matrix/types.ts +102 -102
  202. package/src/edge-path.ts +50 -44
  203. package/src/factor/__tests__/validate.test.ts +81 -46
  204. package/src/factor/index.ts +3 -7
  205. package/src/factor/types.ts +15 -19
  206. package/src/factor/validate.ts +77 -51
  207. package/src/fgca/__tests__/chain-table.test.ts +172 -172
  208. package/src/fgca/__tests__/layout.test.ts +179 -179
  209. package/src/fgca/__tests__/parse-canonical.test.ts +248 -248
  210. package/src/fgca/__tests__/preview-layout.test.ts +124 -124
  211. package/src/fgca/__tests__/resolver.test.ts +209 -0
  212. package/src/fgca/__tests__/validate.test.ts +142 -142
  213. package/src/fgca/chain-table.ts +225 -225
  214. package/src/fgca/index.ts +47 -45
  215. package/src/fgca/layout.ts +204 -204
  216. package/src/fgca/nodeTypes.ts +11 -11
  217. package/src/fgca/nodes/FGCAActivityNode.tsx +65 -65
  218. package/src/fgca/nodes/FGCAChangeNode.tsx +64 -64
  219. package/src/fgca/nodes/FGCAFactorNode.tsx +64 -64
  220. package/src/fgca/nodes/FGCAGoalNode.tsx +72 -72
  221. package/src/fgca/parse-canonical.ts +405 -400
  222. package/src/fgca/preview-layout.ts +217 -217
  223. package/src/fgca/resolver.ts +159 -0
  224. package/src/fgca/types.ts +50 -50
  225. package/src/fgca/validate.ts +129 -126
  226. package/src/geometry.ts +9 -9
  227. package/src/goals/__tests__/layout.test.ts +175 -175
  228. package/src/goals/__tests__/mutations.test.ts +111 -111
  229. package/src/goals/__tests__/parse-canonical.test.ts +145 -145
  230. package/src/goals/__tests__/validate.test.ts +202 -202
  231. package/src/goals/index.ts +20 -21
  232. package/src/goals/layout.ts +172 -172
  233. package/src/goals/mutations.ts +123 -123
  234. package/src/goals/parse-canonical.ts +286 -286
  235. package/src/goals/types.ts +85 -85
  236. package/src/goals/validate.ts +136 -136
  237. package/src/index.ts +28 -23
  238. package/src/process-blueprint/__tests__/compliance-lane.test.ts +320 -320
  239. package/src/process-blueprint/__tests__/layout.test.ts +240 -195
  240. package/src/process-blueprint/__tests__/validate.test.ts +310 -310
  241. package/src/process-blueprint/index.ts +32 -31
  242. package/src/process-blueprint/layout.ts +564 -531
  243. package/src/process-blueprint/types.ts +278 -242
  244. package/src/process-blueprint/validate.ts +181 -181
  245. package/src/process-map/__tests__/validate.test.ts +223 -223
  246. package/src/process-map/index.ts +10 -10
  247. package/src/process-map/types.ts +36 -36
  248. package/src/process-map/validate.ts +135 -135
  249. package/src/products/__tests__/validate.test.ts +239 -239
  250. package/src/products/index.ts +9 -9
  251. package/src/products/types.ts +31 -31
  252. package/src/products/validate.ts +112 -112
  253. package/src/repo-validate/__tests__/validate-repo.test.ts +149 -149
  254. package/src/repo-validate/index.ts +2 -2
  255. package/src/repo-validate/types.ts +50 -50
  256. package/src/repo-validate/validate-repo.ts +196 -196
  257. package/src/requirement/__tests__/example.test.ts +24 -24
  258. package/src/requirement/__tests__/validate.test.ts +96 -96
  259. package/src/requirement/index.ts +4 -4
  260. package/src/requirement/types.ts +35 -35
  261. package/src/requirement/validate.ts +92 -92
  262. package/src/scenarios/__tests__/validate.test.ts +209 -209
  263. package/src/scenarios/index.ts +15 -15
  264. package/src/scenarios/types.ts +37 -37
  265. package/src/scenarios/validate.ts +122 -122
  266. package/src/schema-version.ts +16 -16
  267. package/src/scope.ts +46 -46
  268. package/src/stakeholder/__tests__/validate.test.ts +51 -47
  269. package/src/stakeholder/index.ts +1 -0
  270. package/src/stakeholder/types.ts +7 -7
  271. package/src/stakeholder/validate.ts +79 -52
  272. package/src/target-state/__tests__/validate.test.ts +48 -27
  273. package/src/target-state/index.ts +2 -0
  274. package/src/target-state/types.ts +11 -7
  275. package/src/target-state/validate.ts +76 -46
  276. package/src/theme/index.ts +4 -4
  277. package/src/theme/themes.ts +239 -237
  278. package/src/theme/tokens.ts +135 -133
  279. package/src/typed-id.ts +56 -56
  280. package/src/validation-types.ts +36 -36
  281. package/src/webview/__tests__/entry-notations.test.ts +79 -77
  282. package/src/webview/__tests__/entry.test.ts +64 -64
  283. package/src/webview/__tests__/render-goals.test.ts +72 -72
  284. package/src/webview/__tests__/render-process.test.ts +538 -0
  285. package/src/webview/__tests__/render-util.test.ts +66 -0
  286. package/src/webview/entry.ts +298 -292
  287. package/src/webview/render-activities.ts +111 -69
  288. package/src/webview/render-activity-card.ts +275 -234
  289. package/src/webview/render-blocks.ts +78 -28
  290. package/src/webview/render-fgca.ts +53 -28
  291. package/src/webview/render-goals.ts +133 -110
  292. package/src/webview/render-process-blueprint.ts +281 -207
  293. package/src/webview/render-process.ts +507 -0
  294. package/src/webview/render-scenarios.ts +3 -3
  295. package/src/webview/render-util.ts +27 -14
  296. package/src/webview/styles.css +322 -323
  297. package/src/yaml-normalize.ts +56 -56
  298. package/dist/element-envelope.d.ts +0 -15
  299. package/dist/element-envelope.js +0 -55
  300. package/dist/issues/__tests__/layout.test.js +0 -62
  301. package/dist/issues/__tests__/validate.test.js +0 -82
  302. package/dist/issues/index.d.ts +0 -4
  303. package/dist/issues/index.js +0 -2
  304. package/dist/issues/layout.d.ts +0 -10
  305. package/dist/issues/layout.js +0 -82
  306. package/dist/issues/types.d.ts +0 -61
  307. package/dist/issues/types.js +0 -6
  308. package/dist/issues/validate.d.ts +0 -3
  309. package/dist/issues/validate.js +0 -143
  310. package/dist/webview/transitrix-render.css +0 -323
  311. package/dist/webview/transitrix-render.js +0 -6452
  312. package/dist/webview/transitrix-render.js.map +0 -7
  313. package/src/element-envelope.ts +0 -76
  314. /package/dist/{issues/__tests__/layout.test.d.ts → fgca/__tests__/resolver.test.d.ts} +0 -0
  315. /package/dist/{issues/__tests__/validate.test.d.ts → webview/__tests__/render-process.test.d.ts} +0 -0
@@ -1,133 +1,135 @@
1
- /** Transitrix brand palette. */
2
- export const BRAND = {
3
- petrol: '#004d67',
4
- amber: '#ffaf00',
5
- orange: '#ff4d00',
6
- } as const;
7
-
8
- /** Functional status colors. */
9
- export const FUNCTIONAL = {
10
- success: '#1a7f5c',
11
- warning: '#c07030',
12
- error: '#b91c1c',
13
- info: '#1d6fa8',
14
- } as const;
15
-
16
- /** Fill colors for FGCA notation columns. */
17
- export const LAYER_COLORS = {
18
- factor: { light: '#fef3c7', dark: '#292108', hc: '#f59e0b' },
19
- goal: { light: '#e0e7ff', dark: '#1e1b4b', hc: '#818cf8' },
20
- change: { light: '#dbeafe', dark: '#0c2042', hc: '#60a5fa' },
21
- activity: { light: '#d4edda', dark: '#0a2414', hc: '#4ade80' },
22
- } as const;
23
-
24
- /** Level fill colors for Goals tree nodes — 8 slots, cycled by level index. */
25
- export const LEVEL_COLORS = {
26
- light: ['#dbeafe', '#e0e7ff', '#d4edda', '#fef3c7', '#fce7f3', '#e0f2fe', '#f3e8ff', '#fef9c3'],
27
- dark: ['#0c2042', '#1e1b4b', '#0a2414', '#292108', '#2a0c1f', '#071e2e', '#1a0c33', '#2a2107'],
28
- hc: ['#60a5fa', '#818cf8', '#4ade80', '#f59e0b', '#f472b6', '#38bdf8', '#a78bfa', '#facc15'],
29
- } as const;
30
-
31
- /** Structural diagram colors (nodes, edges, text). */
32
- export const STRUCTURAL = {
33
- nodeStroke: { light: '#94a3b8', dark: '#475569', hc: '#e2e8f0' },
34
- edgeStroke: { light: '#94a3b8', dark: '#475569', hc: '#e2e8f0' },
35
- textPrimary: { light: '#1e293b', dark: '#f1f5f9', hc: '#ffffff' },
36
- textSecondary: { light: '#64748b', dark: '#94a3b8', hc: '#cbd5e1' },
37
- headerText: { light: '#374151', dark: '#e5e7eb', hc: '#ffffff' },
38
- } as const;
39
-
40
- /**
41
- * Maturity scale fill colors — Likert 1..5, danger→success.
42
- * Used by Capability Map and any future maturity-based notation.
43
- */
44
- export const MATURITY_COLORS = {
45
- light: ['#b91c1c', '#d97706', '#ca8a04', '#65a30d', '#15803d'],
46
- dark: ['#7f1d1d', '#92400e', '#854d0e', '#3f6212', '#14532d'],
47
- hc: ['#f87171', '#fb923c', '#facc15', '#a3e635', '#4ade80'],
48
- } as const;
49
-
50
- /**
51
- * Typography hierarchy. All previews resolve text styling from these roles
52
- * — never from inline font-* attributes on individual <text> elements.
53
- *
54
- * fontFamily threads through the VS Code font setting so the preview reads
55
- * as part of the editor; size + weight encode the visual hierarchy.
56
- */
57
- export const TYPOGRAPHY = {
58
- fontFamily: 'var(--vscode-font-family, system-ui, -apple-system, sans-serif)',
59
- sizes: {
60
- header: 13, // stage/column headers, diagram captions
61
- primary: 12, // primary node/cell labels
62
- secondary: 11, // annotations, secondary lines, meta
63
- id: 10, // compact id/code chips
64
- pill: 11, // pill labels (process-blueprint aspects, badges)
65
- caption: 11, // figcaption under the canvas
66
- },
67
- weights: {
68
- header: 700,
69
- primary: 600,
70
- secondary: 400,
71
- id: 600,
72
- pill: 500,
73
- caption: 400,
74
- },
75
- } as const;
76
-
77
- /** Adaptive shell tokens (background, text, border, status). */
78
- export interface AdaptiveTokens {
79
- bg: string;
80
- bgSurface: string;
81
- bgElevated: string;
82
- text: string;
83
- textMuted: string;
84
- textInverse: string;
85
- border: string;
86
- divider: string;
87
- statusSuccessBg: string;
88
- statusSuccessFg: string;
89
- statusWarningBg: string;
90
- statusWarningFg: string;
91
- statusInfoBg: string;
92
- statusInfoFg: string;
93
- statusErrorBg: string;
94
- statusErrorFg: string;
95
- }
96
-
97
- /** CSS custom property names for --ts-* variables. */
98
- export const CSS_VAR = {
99
- bg: '--ts-bg',
100
- bgSurface: '--ts-bg-surface',
101
- bgElevated: '--ts-bg-elevated',
102
- text: '--ts-text',
103
- textMuted: '--ts-text-muted',
104
- textInverse: '--ts-text-inverse',
105
- border: '--ts-border',
106
- divider: '--ts-divider',
107
- statusSuccessBg: '--ts-status-success-bg',
108
- statusSuccessFg: '--ts-status-success-fg',
109
- statusWarningBg: '--ts-status-warning-bg',
110
- statusWarningFg: '--ts-status-warning-fg',
111
- statusInfoBg: '--ts-status-info-bg',
112
- statusInfoFg: '--ts-status-info-fg',
113
- statusErrorBg: '--ts-status-error-bg',
114
- statusErrorFg: '--ts-status-error-fg',
115
- layerFactor: '--ts-layer-factor',
116
- layerGoal: '--ts-layer-goal',
117
- layerChange: '--ts-layer-change',
118
- layerActivity: '--ts-layer-activity',
119
- nodeStroke: '--ts-node-stroke',
120
- edgeStroke: '--ts-edge-stroke',
121
- textPrimary: '--ts-text-primary',
122
- textSecondary: '--ts-text-secondary',
123
- headerText: '--ts-header-text',
124
- maturity1: '--ts-maturity-1',
125
- maturity2: '--ts-maturity-2',
126
- maturity3: '--ts-maturity-3',
127
- maturity4: '--ts-maturity-4',
128
- maturity5: '--ts-maturity-5',
129
- } as const;
130
-
131
- export function getBaseResetCss(): string {
132
- return `*,*:before,*:after{box-sizing:border-box;}html,body{margin:0;padding:0;}`;
133
- }
1
+ /** Transitrix brand palette. */
2
+ export const BRAND = {
3
+ petrol: '#004d67',
4
+ amber: '#ffaf00',
5
+ orange: '#ff4d00',
6
+ } as const;
7
+
8
+ /** Functional status colors. */
9
+ export const FUNCTIONAL = {
10
+ success: '#1a7f5c',
11
+ warning: '#c07030',
12
+ error: '#b91c1c',
13
+ info: '#1d6fa8',
14
+ } as const;
15
+
16
+ /** Fill colors for FGCA/DGCA notation columns. */
17
+ export const LAYER_COLORS = {
18
+ driver: { light: '#fef3c7', dark: '#292108', hc: '#f59e0b' },
19
+ factor: { light: '#fef3c7', dark: '#292108', hc: '#f59e0b' },
20
+ goal: { light: '#e0e7ff', dark: '#1e1b4b', hc: '#818cf8' },
21
+ change: { light: '#dbeafe', dark: '#0c2042', hc: '#60a5fa' },
22
+ activity: { light: '#d4edda', dark: '#0a2414', hc: '#4ade80' },
23
+ } as const;
24
+
25
+ /** Level fill colors for Goals tree nodes — 8 slots, cycled by level index. */
26
+ export const LEVEL_COLORS = {
27
+ light: ['#dbeafe', '#e0e7ff', '#d4edda', '#fef3c7', '#fce7f3', '#e0f2fe', '#f3e8ff', '#fef9c3'],
28
+ dark: ['#0c2042', '#1e1b4b', '#0a2414', '#292108', '#2a0c1f', '#071e2e', '#1a0c33', '#2a2107'],
29
+ hc: ['#60a5fa', '#818cf8', '#4ade80', '#f59e0b', '#f472b6', '#38bdf8', '#a78bfa', '#facc15'],
30
+ } as const;
31
+
32
+ /** Structural diagram colors (nodes, edges, text). */
33
+ export const STRUCTURAL = {
34
+ nodeStroke: { light: '#94a3b8', dark: '#475569', hc: '#e2e8f0' },
35
+ edgeStroke: { light: '#94a3b8', dark: '#475569', hc: '#e2e8f0' },
36
+ textPrimary: { light: '#1e293b', dark: '#f1f5f9', hc: '#ffffff' },
37
+ textSecondary: { light: '#64748b', dark: '#94a3b8', hc: '#cbd5e1' },
38
+ headerText: { light: '#374151', dark: '#e5e7eb', hc: '#ffffff' },
39
+ } as const;
40
+
41
+ /**
42
+ * Maturity scale fill colors — Likert 1..5, danger→success.
43
+ * Used by Capability Map and any future maturity-based notation.
44
+ */
45
+ export const MATURITY_COLORS = {
46
+ light: ['#b91c1c', '#d97706', '#ca8a04', '#65a30d', '#15803d'],
47
+ dark: ['#7f1d1d', '#92400e', '#854d0e', '#3f6212', '#14532d'],
48
+ hc: ['#f87171', '#fb923c', '#facc15', '#a3e635', '#4ade80'],
49
+ } as const;
50
+
51
+ /**
52
+ * Typography hierarchy. All previews resolve text styling from these roles
53
+ * — never from inline font-* attributes on individual <text> elements.
54
+ *
55
+ * fontFamily threads through the VS Code font setting so the preview reads
56
+ * as part of the editor; size + weight encode the visual hierarchy.
57
+ */
58
+ export const TYPOGRAPHY = {
59
+ fontFamily: 'var(--vscode-font-family, system-ui, -apple-system, sans-serif)',
60
+ sizes: {
61
+ header: 13, // stage/column headers, diagram captions
62
+ primary: 12, // primary node/cell labels
63
+ secondary: 11, // annotations, secondary lines, meta
64
+ id: 10, // compact id/code chips
65
+ pill: 11, // pill labels (process-blueprint aspects, badges)
66
+ caption: 11, // figcaption under the canvas
67
+ },
68
+ weights: {
69
+ header: 700,
70
+ primary: 600,
71
+ secondary: 400,
72
+ id: 600,
73
+ pill: 500,
74
+ caption: 400,
75
+ },
76
+ } as const;
77
+
78
+ /** Adaptive shell tokens (background, text, border, status). */
79
+ export interface AdaptiveTokens {
80
+ bg: string;
81
+ bgSurface: string;
82
+ bgElevated: string;
83
+ text: string;
84
+ textMuted: string;
85
+ textInverse: string;
86
+ border: string;
87
+ divider: string;
88
+ statusSuccessBg: string;
89
+ statusSuccessFg: string;
90
+ statusWarningBg: string;
91
+ statusWarningFg: string;
92
+ statusInfoBg: string;
93
+ statusInfoFg: string;
94
+ statusErrorBg: string;
95
+ statusErrorFg: string;
96
+ }
97
+
98
+ /** CSS custom property names for --ts-* variables. */
99
+ export const CSS_VAR = {
100
+ bg: '--ts-bg',
101
+ bgSurface: '--ts-bg-surface',
102
+ bgElevated: '--ts-bg-elevated',
103
+ text: '--ts-text',
104
+ textMuted: '--ts-text-muted',
105
+ textInverse: '--ts-text-inverse',
106
+ border: '--ts-border',
107
+ divider: '--ts-divider',
108
+ statusSuccessBg: '--ts-status-success-bg',
109
+ statusSuccessFg: '--ts-status-success-fg',
110
+ statusWarningBg: '--ts-status-warning-bg',
111
+ statusWarningFg: '--ts-status-warning-fg',
112
+ statusInfoBg: '--ts-status-info-bg',
113
+ statusInfoFg: '--ts-status-info-fg',
114
+ statusErrorBg: '--ts-status-error-bg',
115
+ statusErrorFg: '--ts-status-error-fg',
116
+ layerDriver: '--ts-layer-driver',
117
+ layerFactor: '--ts-layer-factor',
118
+ layerGoal: '--ts-layer-goal',
119
+ layerChange: '--ts-layer-change',
120
+ layerActivity: '--ts-layer-activity',
121
+ nodeStroke: '--ts-node-stroke',
122
+ edgeStroke: '--ts-edge-stroke',
123
+ textPrimary: '--ts-text-primary',
124
+ textSecondary: '--ts-text-secondary',
125
+ headerText: '--ts-header-text',
126
+ maturity1: '--ts-maturity-1',
127
+ maturity2: '--ts-maturity-2',
128
+ maturity3: '--ts-maturity-3',
129
+ maturity4: '--ts-maturity-4',
130
+ maturity5: '--ts-maturity-5',
131
+ } as const;
132
+
133
+ export function getBaseResetCss(): string {
134
+ return `*,*:before,*:after{box-sizing:border-box;}html,body{margin:0;padding:0;}`;
135
+ }
package/src/typed-id.ts CHANGED
@@ -1,56 +1,56 @@
1
- // Canonical typed-ID grammar + cross-reference resolution catalogue.
2
- //
3
- // Every element ID and cross-reference in the Transitrix canon follows the
4
- // grammar in methodology `notations/IDS_AND_REFERENCES.md` §1:
5
- //
6
- // <TYPE>-[<middle segment(s)>-]<INTEGER>
7
- //
8
- // - TYPE: uppercase, starts with a letter, may contain digits and `_`
9
- // (multi-word TYPEs like INTERNAL_STANDARD / PROCESS_BLUEPRINT).
10
- // - middle: optional, notation-specific segments.
11
- // - INTEGER: terminal positive integer, no leading zeros.
12
- //
13
- // CAPABILITY is the one exception (§2): its terminal is a V/H diagram address
14
- // (CAPABILITY-V1.2) rather than a plain integer. Compliance artefacts only
15
- // *resolve* capability ids (they never own one), so the catalogue handles
16
- // them; the strict integer-terminal grammar below is used only for an
17
- // artefact's own id (REQUIREMENT-… / ASSERTION-…).
18
-
19
- /** TYPE prefix of a typed id — the segment before the first hyphen. */
20
- const TYPE_PREFIX_RE = /^([A-Z][A-Z0-9_]*)-/;
21
-
22
- /** Full integer-terminal canonical id. Middle segments may be mixed-case
23
- * (real canon ids such as INTERNAL_STANDARD-coding-conventions-1 exist). */
24
- const CANONICAL_ID_RE = /^[A-Z][A-Z0-9_]*(?:-[A-Za-z0-9]+)*-[1-9][0-9]*$/;
25
-
26
- /** Extracts the TYPE prefix of a typed id, or null when `id` is not a typed
27
- * reference (`PRODUCT-MOBILE-1` → `PRODUCT`, `CAPABILITY-V2` → `CAPABILITY`). */
28
- export function typeOfId(id: unknown): string | null {
29
- if (typeof id !== 'string') return null;
30
- const m = TYPE_PREFIX_RE.exec(id);
31
- return m ? m[1] : null;
32
- }
33
-
34
- /** True when `id` is a well-formed integer-terminal canonical id. */
35
- export function isCanonicalId(id: unknown): id is string {
36
- return typeof id === 'string' && CANONICAL_ID_RE.test(id);
37
- }
38
-
39
- /** True when `id` is a well-formed canonical id whose TYPE is exactly `type`. */
40
- export function isCanonicalIdOfType(id: unknown, type: string): boolean {
41
- return isCanonicalId(id) && typeOfId(id) === type;
42
- }
43
-
44
- /**
45
- * A read-only view of an organisation's admitted canon, used to resolve typed
46
- * cross-references during validation. Phase 1 validators accept it optionally:
47
- * with no catalogue they perform shape + prefix-TYPE checks only; given one,
48
- * they additionally enforce the resolution rules (REQ-002, ASSERT-002/004/005…)
49
- * that depend on whether a referenced artefact actually exists.
50
- *
51
- * The compliance previews (Phase 2+) build a catalogue by scanning the repo.
52
- */
53
- export interface CanonCatalog {
54
- /** TYPE of an admitted artefact with this id, or undefined if not admitted. */
55
- typeOf(id: string): string | undefined;
56
- }
1
+ // Canonical typed-ID grammar + cross-reference resolution catalogue.
2
+ //
3
+ // Every element ID and cross-reference in the Transitrix canon follows the
4
+ // grammar in methodology `notations/IDS_AND_REFERENCES.md` §1:
5
+ //
6
+ // <TYPE>-[<middle segment(s)>-]<INTEGER>
7
+ //
8
+ // - TYPE: uppercase, starts with a letter, may contain digits and `_`
9
+ // (multi-word TYPEs like INTERNAL_STANDARD / PROCESS_BLUEPRINT).
10
+ // - middle: optional, notation-specific segments.
11
+ // - INTEGER: terminal positive integer, no leading zeros.
12
+ //
13
+ // CAPABILITY is the one exception (§2): its terminal is a V/H diagram address
14
+ // (CAPABILITY-V1.2) rather than a plain integer. Compliance artefacts only
15
+ // *resolve* capability ids (they never own one), so the catalogue handles
16
+ // them; the strict integer-terminal grammar below is used only for an
17
+ // artefact's own id (REQUIREMENT-… / ASSERTION-…).
18
+
19
+ /** TYPE prefix of a typed id — the segment before the first hyphen. */
20
+ const TYPE_PREFIX_RE = /^([A-Z][A-Z0-9_]*)-/;
21
+
22
+ /** Full integer-terminal canonical id. Middle segments may be mixed-case
23
+ * (real canon ids such as INTERNAL_STANDARD-coding-conventions-1 exist). */
24
+ const CANONICAL_ID_RE = /^[A-Z][A-Z0-9_]*(?:-[A-Za-z0-9]+)*-[1-9][0-9]*$/;
25
+
26
+ /** Extracts the TYPE prefix of a typed id, or null when `id` is not a typed
27
+ * reference (`PRODUCT-MOBILE-1` → `PRODUCT`, `CAPABILITY-V2` → `CAPABILITY`). */
28
+ export function typeOfId(id: unknown): string | null {
29
+ if (typeof id !== 'string') return null;
30
+ const m = TYPE_PREFIX_RE.exec(id);
31
+ return m ? m[1] : null;
32
+ }
33
+
34
+ /** True when `id` is a well-formed integer-terminal canonical id. */
35
+ export function isCanonicalId(id: unknown): id is string {
36
+ return typeof id === 'string' && CANONICAL_ID_RE.test(id);
37
+ }
38
+
39
+ /** True when `id` is a well-formed canonical id whose TYPE is exactly `type`. */
40
+ export function isCanonicalIdOfType(id: unknown, type: string): boolean {
41
+ return isCanonicalId(id) && typeOfId(id) === type;
42
+ }
43
+
44
+ /**
45
+ * A read-only view of an organisation's admitted canon, used to resolve typed
46
+ * cross-references during validation. Phase 1 validators accept it optionally:
47
+ * with no catalogue they perform shape + prefix-TYPE checks only; given one,
48
+ * they additionally enforce the resolution rules (REQ-002, ASSERT-002/004/005…)
49
+ * that depend on whether a referenced artefact actually exists.
50
+ *
51
+ * The compliance previews (Phase 2+) build a catalogue by scanning the repo.
52
+ */
53
+ export interface CanonCatalog {
54
+ /** TYPE of an admitted artefact with this id, or undefined if not admitted. */
55
+ typeOf(id: string): string | undefined;
56
+ }
@@ -1,36 +1,36 @@
1
- /**
2
- * Shared validation result shape across every notation module in this
3
- * package.
4
- *
5
- * Before this file existed, each notation declared its own
6
- * `ValidationError` / `ValidationWarning` / `ValidationResult` triple inside
7
- * its own `validate.ts`. The shapes happened to agree (or almost agree —
8
- * some had an optional `path` field, others didn't), but having N parallel
9
- * declarations made it easy to accidentally drift one of them, and made the
10
- * "what does our validator return?" answer fuzzier than it should be.
11
- *
12
- * The pre-release code review on 2026-05-21 called this out as a
13
- * `should-fix` cross-module concern; this is the canonical shape.
14
- *
15
- * Notations that historically exported PREFIXED type names — `FGCA…` and
16
- * `Activity…` — keep those names as type aliases re-exported from their own
17
- * modules, so existing consumers continue to compile.
18
- */
19
- export interface ValidationError {
20
- code: string;
21
- message: string;
22
- /** Optional JSON-path-ish locator inside the source document. */
23
- path?: string;
24
- }
25
-
26
- export interface ValidationWarning {
27
- code: string;
28
- message: string;
29
- path?: string;
30
- }
31
-
32
- export interface ValidationResult {
33
- valid: boolean;
34
- errors: ValidationError[];
35
- warnings: ValidationWarning[];
36
- }
1
+ /**
2
+ * Shared validation result shape across every notation module in this
3
+ * package.
4
+ *
5
+ * Before this file existed, each notation declared its own
6
+ * `ValidationError` / `ValidationWarning` / `ValidationResult` triple inside
7
+ * its own `validate.ts`. The shapes happened to agree (or almost agree —
8
+ * some had an optional `path` field, others didn't), but having N parallel
9
+ * declarations made it easy to accidentally drift one of them, and made the
10
+ * "what does our validator return?" answer fuzzier than it should be.
11
+ *
12
+ * The pre-release code review on 2026-05-21 called this out as a
13
+ * `should-fix` cross-module concern; this is the canonical shape.
14
+ *
15
+ * Notations that historically exported PREFIXED type names — `FGCA…` and
16
+ * `Activity…` — keep those names as type aliases re-exported from their own
17
+ * modules, so existing consumers continue to compile.
18
+ */
19
+ export interface ValidationError {
20
+ code: string;
21
+ message: string;
22
+ /** Optional JSON-path-ish locator inside the source document. */
23
+ path?: string;
24
+ }
25
+
26
+ export interface ValidationWarning {
27
+ code: string;
28
+ message: string;
29
+ path?: string;
30
+ }
31
+
32
+ export interface ValidationResult {
33
+ valid: boolean;
34
+ errors: ValidationError[];
35
+ warnings: ValidationWarning[];
36
+ }
@@ -1,77 +1,79 @@
1
- /**
2
- * Step 4 parity check: every supported notation must render through the
3
- * webview bundle's `render(kind, source)` API from the same example fixtures
4
- * the VS Code previews consume — a valid document yields `status: 'ok'` with
5
- * non-empty markup, and a malformed document degrades to the error panel
6
- * (structured errors, no thrown exception reaching the JVM host).
7
- */
8
- import { readFileSync } from 'node:fs';
9
- import path from 'node:path';
10
- import { fileURLToPath } from 'node:url';
11
-
12
- import { describe, expect, it } from 'vitest';
13
-
14
- import { api, render, type NotationKind } from '../entry.js';
15
-
16
- const EXAMPLES = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../../tests/fixtures/notation-corpus');
17
-
18
- interface Fixture {
19
- kind: NotationKind;
20
- file: string;
21
- /** The markup wrapper the renderer emits: an <svg> diagram or an HTML <section>. */
22
- markup: 'svg' | 'section';
23
- }
24
-
25
- // Mirrors the fixtures used by the VS Code previews. One representative
26
- // example per notation is enough to prove the dispatch + renderer wiring.
27
- const FIXTURES: Fixture[] = [
28
- { kind: 'goals', file: 'goals/strategy-2026.goals.transitrix.yaml', markup: 'svg' },
29
- { kind: 'fgca', file: 'fgca/strategy-2026.fgca.transitrix.yaml', markup: 'svg' },
30
- { kind: 'fga', file: 'fga/strategy-2026.fga.transitrix.yaml', markup: 'svg' },
31
- { kind: 'activities', file: 'activities/platform-launch.activities.transitrix.yaml', markup: 'svg' },
32
- { kind: 'activity-card', file: 'activity-card/eu-programme.activity-card.transitrix.yaml', markup: 'svg' },
33
- { kind: 'process-blueprint', file: 'process-blueprint/order-fulfilment.process-blueprint.transitrix.yaml', markup: 'svg' },
34
- { kind: 'blocks', file: 'blocks/architecture.blocks.transitrix.yaml', markup: 'svg' },
35
- { kind: 'applications', file: 'applications/portfolio-2026.applications.transitrix.yaml', markup: 'section' },
36
- { kind: 'products', file: 'products/portfolio-2026.products.transitrix.yaml', markup: 'section' },
37
- { kind: 'process-map', file: 'process-map/enterprise.process-map.transitrix.yaml', markup: 'section' },
38
- { kind: 'scenarios', file: 'scenarios/omnichannel-2028.scenarios.transitrix.yaml', markup: 'section' },
39
- { kind: 'capability-map', file: 'capability-map/business.capability-map.transitrix.yaml', markup: 'section' },
40
- ];
41
-
42
- describe('webview/entry — Step 4 notation coverage', () => {
43
- it('wires every supported kind (no kind left on NOTATION-NOT-WIRED)', () => {
44
- // The fixture table must cover the full supported-kinds surface, so a new
45
- // kind added to the bundle without a renderer fails this test loudly.
46
- const covered = new Set(FIXTURES.map((f) => f.kind));
47
- for (const kind of api.supportedKinds) {
48
- expect(covered.has(kind)).toBe(true);
49
- }
50
- });
51
-
52
- for (const fx of FIXTURES) {
53
- it(`renders ${fx.kind} from its example fixture`, () => {
54
- const source = readFileSync(path.join(EXAMPLES, fx.file), 'utf8');
55
- const r = render(fx.kind, source);
56
- expect(r.notation).toBe(fx.kind);
57
- expect(r.errors).toEqual([]);
58
- expect(r.status).toBe('ok');
59
- expect(r.svg.length).toBeGreaterThan(0);
60
- expect(r.svg).toContain(fx.markup === 'svg' ? '<svg ' : '<section');
61
- });
62
- }
63
-
64
- it('degrades malformed input to the error panel for a diagram notation', () => {
65
- const r = render('process-blueprint', 'process_blueprint:\n stages: "not a list"\n');
66
- expect(r.status).toBe('error');
67
- expect(r.errors.length).toBeGreaterThan(0);
68
- expect(r.svg).toBe('');
69
- });
70
-
71
- it('degrades malformed input to the error panel for a catalogue notation', () => {
72
- const r = render('applications', 'applications_catalogue:\n applications: "not a list"\n');
73
- expect(r.status).toBe('error');
74
- expect(r.errors.length).toBeGreaterThan(0);
75
- expect(r.svg).toBe('');
76
- });
77
- });
1
+ /**
2
+ * Step 4 parity check: every supported notation must render through the
3
+ * webview bundle's `render(kind, source)` API from the same example fixtures
4
+ * the VS Code previews consume — a valid document yields `status: 'ok'` with
5
+ * non-empty markup, and a malformed document degrades to the error panel
6
+ * (structured errors, no thrown exception reaching the JVM host).
7
+ */
8
+ import { readFileSync } from 'node:fs';
9
+ import path from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+
12
+ import { describe, expect, it } from 'vitest';
13
+
14
+ import { api, render, type NotationKind } from '../entry.js';
15
+
16
+ const EXAMPLES = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../../tests/fixtures/notation-corpus');
17
+
18
+ interface Fixture {
19
+ kind: NotationKind;
20
+ file: string;
21
+ /** The markup wrapper the renderer emits: an <svg> diagram or an HTML <section>. */
22
+ markup: 'svg' | 'section';
23
+ }
24
+
25
+ // Mirrors the fixtures used by the VS Code previews. One representative
26
+ // example per notation is enough to prove the dispatch + renderer wiring.
27
+ const FIXTURES: Fixture[] = [
28
+ { kind: 'goals', file: 'goals/strategy-2026.goals.transitrix.yaml', markup: 'svg' },
29
+ { kind: 'dgca', file: 'dgca/strategy-2026.dgca.transitrix.yaml', markup: 'svg' },
30
+ { kind: 'dga', file: 'dga/strategy-2026.dga.transitrix.yaml', markup: 'svg' },
31
+ { kind: 'fgca', file: 'fgca/strategy-2026.fgca.transitrix.yaml', markup: 'svg' },
32
+ { kind: 'fga', file: 'fga/strategy-2026.fga.transitrix.yaml', markup: 'svg' },
33
+ { kind: 'activities', file: 'activities/platform-launch.activities.transitrix.yaml', markup: 'svg' },
34
+ { kind: 'activity-card', file: 'activity-card/eu-programme.activity-card.transitrix.yaml', markup: 'svg' },
35
+ { kind: 'process-blueprint', file: 'process-blueprint/order-fulfilment.process-blueprint.transitrix.yaml', markup: 'svg' },
36
+ { kind: 'blocks', file: 'blocks/architecture.blocks.transitrix.yaml', markup: 'svg' },
37
+ { kind: 'applications', file: 'applications/portfolio-2026.applications.transitrix.yaml', markup: 'section' },
38
+ { kind: 'products', file: 'products/portfolio-2026.products.transitrix.yaml', markup: 'section' },
39
+ { kind: 'process-map', file: 'process-map/enterprise.process-map.transitrix.yaml', markup: 'section' },
40
+ { kind: 'scenarios', file: 'scenarios/omnichannel-2028.scenarios.transitrix.yaml', markup: 'section' },
41
+ { kind: 'capability-map', file: 'capability-map/business.capability-map.transitrix.yaml', markup: 'section' },
42
+ ];
43
+
44
+ describe('webview/entry — Step 4 notation coverage', () => {
45
+ it('wires every supported kind (no kind left on NOTATION-NOT-WIRED)', () => {
46
+ // The fixture table must cover the full supported-kinds surface, so a new
47
+ // kind added to the bundle without a renderer fails this test loudly.
48
+ const covered = new Set(FIXTURES.map((f) => f.kind));
49
+ for (const kind of api.supportedKinds) {
50
+ expect(covered.has(kind)).toBe(true);
51
+ }
52
+ });
53
+
54
+ for (const fx of FIXTURES) {
55
+ it(`renders ${fx.kind} from its example fixture`, () => {
56
+ const source = readFileSync(path.join(EXAMPLES, fx.file), 'utf8');
57
+ const r = render(fx.kind, source);
58
+ expect(r.notation).toBe(fx.kind);
59
+ expect(r.errors).toEqual([]);
60
+ expect(r.status).toBe('ok');
61
+ expect(r.svg.length).toBeGreaterThan(0);
62
+ expect(r.svg).toContain(fx.markup === 'svg' ? '<svg ' : '<section');
63
+ });
64
+ }
65
+
66
+ it('degrades malformed input to the error panel for a diagram notation', () => {
67
+ const r = render('process-blueprint', 'process_blueprint:\n stages: "not a list"\n');
68
+ expect(r.status).toBe('error');
69
+ expect(r.errors.length).toBeGreaterThan(0);
70
+ expect(r.svg).toBe('');
71
+ });
72
+
73
+ it('degrades malformed input to the error panel for a catalogue notation', () => {
74
+ const r = render('applications', 'applications_catalogue:\n applications: "not a list"\n');
75
+ expect(r.status).toBe('error');
76
+ expect(r.errors.length).toBeGreaterThan(0);
77
+ expect(r.svg).toBe('');
78
+ });
79
+ });