@transitrix/diagrams 1.15.0 → 1.16.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.
- package/dist/compliance/catalogue.d.ts +17 -0
- package/dist/compliance/catalogue.js +68 -0
- package/dist/compliance/index.d.ts +4 -2
- package/dist/compliance/index.js +2 -1
- package/dist/compliance/requirement-chain.d.ts +13 -2
- package/dist/compliance/requirement-chain.js +60 -33
- package/dist/products/types.d.ts +1 -1
- package/dist/products/validate.js +1 -1
- package/dist/standalone/validate.js +64 -3
- package/dist/webview/render-activities.d.ts +6 -0
- package/dist/webview/render-activities.js +2 -2
- package/dist/webview/render-activity-card.d.ts +6 -0
- package/dist/webview/render-activity-card.js +2 -2
- package/dist/webview/render-blocks.d.ts +10 -0
- package/dist/webview/render-blocks.js +4 -4
- package/dist/webview/render-fgca.d.ts +6 -0
- package/dist/webview/render-fgca.js +2 -2
- package/dist/webview/render-goals.d.ts +5 -0
- package/dist/webview/render-goals.js +9 -2
- package/dist/webview/render-process-blueprint.d.ts +6 -0
- package/dist/webview/render-process-blueprint.js +2 -2
- package/dist/webview/render-products.js +1 -0
- package/dist/yaml-normalize.d.ts +3 -1
- package/dist/yaml-normalize.js +11 -3
- package/package.json +1 -1
- package/src/compliance/catalogue.ts +49 -0
- package/src/compliance/index.ts +5 -2
- package/src/compliance/requirement-chain.ts +52 -27
- package/src/products/types.ts +1 -1
- package/src/products/validate.ts +1 -1
- package/src/standalone/validate.ts +38 -2
- package/src/webview/render-activities.ts +8 -2
- package/src/webview/render-activity-card.ts +8 -3
- package/src/webview/render-blocks.ts +14 -4
- package/src/webview/render-fgca.ts +8 -2
- package/src/webview/render-goals.ts +21 -2
- package/src/webview/render-process-blueprint.ts +8 -3
- package/src/webview/render-products.ts +1 -0
- package/src/yaml-normalize.ts +12 -3
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
import type { FGCADoc } from '../fgca/validate.js';
|
|
25
25
|
import { previewEdgePath, DEFAULT_EDGE_CURVATURE, type EdgeStyle } from '../edge-path.js';
|
|
26
26
|
import { parseNodeSizePreset, resolveDgcaNodeSize, type NodeSizePreset } from '../node-size-presets.js';
|
|
27
|
-
import { generateSvgEmbedCss } from '../theme/index.js';
|
|
27
|
+
import { generateSvgEmbedCss, type ThemeId } from '../theme/index.js';
|
|
28
28
|
import { emitCenteredTextSvg, layoutCenteredEntityText, truncateLine } from './entity-text-layout.js';
|
|
29
29
|
import { escXml } from './render-util.js';
|
|
30
30
|
|
|
@@ -137,6 +137,11 @@ export interface RenderFgcaOptions {
|
|
|
137
137
|
scopeCaption?: boolean;
|
|
138
138
|
/** Show completion percent badges on action nodes. */
|
|
139
139
|
showCompletionPercent?: boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Theme CSS embedded as `<style>` so the SVG is self-contained.
|
|
142
|
+
* Defaults to `'transitrix'`. VS Code live preview uses body emitters + webview CSS instead.
|
|
143
|
+
*/
|
|
144
|
+
embedCssTheme?: ThemeId;
|
|
140
145
|
}
|
|
141
146
|
|
|
142
147
|
export function renderFgcaSvg(doc: FGCADoc, options: RenderFgcaOptions = {}): string {
|
|
@@ -150,6 +155,7 @@ export function renderFgcaSvg(doc: FGCADoc, options: RenderFgcaOptions = {}): st
|
|
|
150
155
|
layoutOptions,
|
|
151
156
|
scopeCaption = false,
|
|
152
157
|
showCompletionPercent = true,
|
|
158
|
+
embedCssTheme = 'transitrix',
|
|
153
159
|
} = options;
|
|
154
160
|
const hideChanges = variant === 'dga' || doc.hideChanges === true;
|
|
155
161
|
const nodeSize = resolveDgcaNodeSize(parseNodeSizePreset(nodeSizePreset));
|
|
@@ -180,7 +186,7 @@ export function renderFgcaSvg(doc: FGCADoc, options: RenderFgcaOptions = {}): st
|
|
|
180
186
|
? `<text class="text-caption" x="${PAD}" y="${height + 16}">${escXml('This diagram is shown for the selected goal scope. Actions on it may also serve goals outside that scope.')}</text>`
|
|
181
187
|
: '';
|
|
182
188
|
|
|
183
|
-
const embedCss = generateSvgEmbedCss(
|
|
189
|
+
const embedCss = generateSvgEmbedCss(embedCssTheme);
|
|
184
190
|
|
|
185
191
|
// Calculate final height including caption if present
|
|
186
192
|
const finalHeight = scopeCaption ? height + 24 : height;
|
|
@@ -30,6 +30,11 @@ export interface RenderGoalsOptions {
|
|
|
30
30
|
entryCurvature?: number;
|
|
31
31
|
edgeStyle?: EdgeStyle;
|
|
32
32
|
nodeSizePreset?: NodeSizePreset;
|
|
33
|
+
/**
|
|
34
|
+
* Theme CSS embedded via {@link renderGoalsLayoutSvg}.
|
|
35
|
+
* Defaults to `'transitrix'` for self-contained host-neutral SVG.
|
|
36
|
+
*/
|
|
37
|
+
embedCssTheme?: ThemeId;
|
|
33
38
|
}
|
|
34
39
|
|
|
35
40
|
/**
|
|
@@ -38,7 +43,14 @@ export interface RenderGoalsOptions {
|
|
|
38
43
|
* with the shared theme CSS embedded so the output is self-contained.
|
|
39
44
|
*/
|
|
40
45
|
export function renderGoalsSvg(tree: GoalTree, options: RenderGoalsOptions = {}): string {
|
|
41
|
-
const {
|
|
46
|
+
const {
|
|
47
|
+
treeName = '',
|
|
48
|
+
curvature = DEFAULT_EDGE_CURVATURE,
|
|
49
|
+
entryCurvature,
|
|
50
|
+
edgeStyle,
|
|
51
|
+
nodeSizePreset = 'normal',
|
|
52
|
+
embedCssTheme = 'transitrix',
|
|
53
|
+
} = options;
|
|
42
54
|
const nodeSize = resolveGoalsNodeSize(parseNodeSizePreset(nodeSizePreset));
|
|
43
55
|
|
|
44
56
|
const layout: GoalTreeLayout = layoutGoalTree(tree, {
|
|
@@ -57,7 +69,14 @@ export function renderGoalsSvg(tree: GoalTree, options: RenderGoalsOptions = {})
|
|
|
57
69
|
: '';
|
|
58
70
|
|
|
59
71
|
// Reserve a separate header row; the theme centers text on its y coordinate.
|
|
60
|
-
return renderGoalsLayoutSvg(layout, {
|
|
72
|
+
return renderGoalsLayoutSvg(layout, {
|
|
73
|
+
curvature,
|
|
74
|
+
entryCurvature,
|
|
75
|
+
edgeStyle,
|
|
76
|
+
title,
|
|
77
|
+
topInset: title ? PAD : 0,
|
|
78
|
+
embedCssTheme,
|
|
79
|
+
});
|
|
61
80
|
}
|
|
62
81
|
|
|
63
82
|
export interface RenderGoalsLayoutOptions {
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
resolveProcessBlueprintSize,
|
|
22
22
|
type NodeSizePreset,
|
|
23
23
|
} from '../node-size-presets.js';
|
|
24
|
-
import { generateSvgEmbedCss } from '../theme/index.js';
|
|
24
|
+
import { generateSvgEmbedCss, type ThemeId } from '../theme/index.js';
|
|
25
25
|
import {
|
|
26
26
|
layoutCenteredPillText,
|
|
27
27
|
layoutLeftCellLines,
|
|
@@ -206,13 +206,18 @@ export interface RenderProcessBlueprintOptions {
|
|
|
206
206
|
title?: string;
|
|
207
207
|
nodeSizePreset?: NodeSizePreset;
|
|
208
208
|
layoutOptions?: ProcessBlueprintLayoutOptions;
|
|
209
|
+
/**
|
|
210
|
+
* Theme CSS embedded as `<style>` so the SVG is self-contained.
|
|
211
|
+
* Defaults to `'transitrix'`. VS Code live preview uses body emitters + webview CSS instead.
|
|
212
|
+
*/
|
|
213
|
+
embedCssTheme?: ThemeId;
|
|
209
214
|
}
|
|
210
215
|
|
|
211
216
|
export function renderProcessBlueprintSvg(
|
|
212
217
|
doc: ProcessBlueprintFile,
|
|
213
218
|
options: RenderProcessBlueprintOptions = {},
|
|
214
219
|
): string {
|
|
215
|
-
const { title = '', nodeSizePreset = 'normal', layoutOptions } = options;
|
|
220
|
+
const { title = '', nodeSizePreset = 'normal', layoutOptions, embedCssTheme = 'transitrix' } = options;
|
|
216
221
|
const sizing = resolveProcessBlueprintSize(parseNodeSizePreset(nodeSizePreset));
|
|
217
222
|
|
|
218
223
|
const layout: ProcessBlueprintLayout = layoutProcessBlueprint(doc, {
|
|
@@ -236,7 +241,7 @@ export function renderProcessBlueprintSvg(
|
|
|
236
241
|
? `<text class="text-header" x="${PAD}" y="${PAD - 6}">${escXml(title)}</text>`
|
|
237
242
|
: '';
|
|
238
243
|
|
|
239
|
-
const embedCss = generateSvgEmbedCss(
|
|
244
|
+
const embedCss = generateSvgEmbedCss(embedCssTheme) + BP_EMBED_CSS;
|
|
240
245
|
|
|
241
246
|
return `<svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${h}" viewBox="0 0 ${w} ${h}">
|
|
242
247
|
<style>${embedCss}</style>
|
|
@@ -7,6 +7,7 @@ import type { Product, ProductsCatalogueHeader } from '../products/types.js';
|
|
|
7
7
|
import { escHtml } from './render-util.js';
|
|
8
8
|
|
|
9
9
|
const TYPE_LABEL: Record<string, string> = {
|
|
10
|
+
physical_product: 'Physical Product',
|
|
10
11
|
digital_product: 'Digital Product',
|
|
11
12
|
service: 'Service',
|
|
12
13
|
platform: 'Platform',
|
package/src/yaml-normalize.ts
CHANGED
|
@@ -15,22 +15,31 @@
|
|
|
15
15
|
* A bare `2026-06-01` parses to midnight UTC and round-trips to
|
|
16
16
|
* `"2026-06-01"` regardless of `process.env.TZ`.
|
|
17
17
|
*
|
|
18
|
-
* Walks in place and returns the same reference for convenience.
|
|
18
|
+
* Walks in place and returns the same reference for convenience. Shared
|
|
19
|
+
* object graphs from YAML aliases (and cycles) are visited once via WeakSet
|
|
20
|
+
* so diamond / recursive anchors cannot amplify the walk into a hang.
|
|
19
21
|
*/
|
|
20
22
|
export function coerceDatesToIsoStrings<T>(value: T): T {
|
|
23
|
+
return walk(value, new WeakSet<object>());
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function walk<T>(value: T, seen: WeakSet<object>): T {
|
|
21
27
|
if (value === null || value === undefined) return value;
|
|
22
28
|
if (value instanceof Date) {
|
|
23
29
|
return dateToIsoYmd(value) as unknown as T;
|
|
24
30
|
}
|
|
25
31
|
if (typeof value !== 'object') return value;
|
|
26
32
|
|
|
33
|
+
if (seen.has(value as object)) return value;
|
|
34
|
+
seen.add(value as object);
|
|
35
|
+
|
|
27
36
|
if (Array.isArray(value)) {
|
|
28
37
|
for (let i = 0; i < value.length; i++) {
|
|
29
38
|
const v = value[i];
|
|
30
39
|
if (v instanceof Date) {
|
|
31
40
|
value[i] = dateToIsoYmd(v) as unknown as typeof v;
|
|
32
41
|
} else if (v !== null && typeof v === 'object') {
|
|
33
|
-
|
|
42
|
+
walk(v, seen);
|
|
34
43
|
}
|
|
35
44
|
}
|
|
36
45
|
return value;
|
|
@@ -42,7 +51,7 @@ export function coerceDatesToIsoStrings<T>(value: T): T {
|
|
|
42
51
|
if (v instanceof Date) {
|
|
43
52
|
obj[key] = dateToIsoYmd(v);
|
|
44
53
|
} else if (v !== null && typeof v === 'object') {
|
|
45
|
-
|
|
54
|
+
walk(v, seen);
|
|
46
55
|
}
|
|
47
56
|
}
|
|
48
57
|
return value;
|