@anyshift/backstage-plugin-anyshift 0.1.0-beta.12 → 0.1.0-beta.14

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.
@@ -1,3 +1,5 @@
1
+ import { uniqueOperationCount, architectureEdgeKey, mergeOperationSources } from './architectureGraph.esm.js';
2
+
1
3
  const RUNTIME_INSTANCE_TYPES = /* @__PURE__ */ new Set(["K8S_REPLICASET", "K8S_POD"]);
2
4
  const MAX_DIRECT_DEPENDENCIES = 5;
3
5
  function buildArchitectureDiagram(graph, options = {}) {
@@ -11,6 +13,7 @@ function buildArchitectureDiagram(graph, options = {}) {
11
13
  compact.nodes.map((node) => [node.id, readableNodeLabel(node)])
12
14
  );
13
15
  const lines = ["flowchart LR"];
16
+ const relationships = [];
14
17
  compact.nodes.forEach((node) => {
15
18
  const id = nodeIds.get(node.id);
16
19
  const label = mermaidNodeLabel(node);
@@ -25,9 +28,22 @@ function buildArchitectureDiagram(graph, options = {}) {
25
28
  compact.edges.forEach((edge) => {
26
29
  const from = nodeIds.get(edge.from);
27
30
  const to = nodeIds.get(edge.to);
28
- if (from && to) {
29
- lines.push(` ${from} -->|${sanitize(edge.type)}| ${to}`);
30
- }
31
+ const fromLabel = names.get(edge.from);
32
+ const toLabel = names.get(edge.to);
33
+ if (!from || !to || !fromLabel || !toLabel) return;
34
+ const operationCount = edge.synthetic ? 0 : uniqueOperationCount(edge.operationSources);
35
+ const edgeLabel = operationCount > 0 ? `${edge.type} \xB7 HTTP \xB7 ${operationCount}` : edge.type;
36
+ lines.push(` ${from} -->|${sanitize(edgeLabel)}| ${to}`);
37
+ relationships.push({
38
+ id: architectureEdgeKey(edge),
39
+ diagramIndex: relationships.length,
40
+ label: `${fromLabel} \u2192 ${readableRelationship(edge.type)} \u2192 ${toLabel}`,
41
+ fromLabel,
42
+ toLabel,
43
+ type: edge.type,
44
+ operationCount,
45
+ operationSources: operationCount > 0 ? edge.operationSources ?? [] : []
46
+ });
31
47
  });
32
48
  lines.push(
33
49
  " classDef service fill:#e8f0fe,stroke:#1967d2,color:#174ea6",
@@ -40,11 +56,8 @@ function buildArchitectureDiagram(graph, options = {}) {
40
56
  });
41
57
  return {
42
58
  source: lines.join("\n"),
43
- fallbackRelationships: compact.edges.flatMap((edge) => {
44
- const from = names.get(edge.from);
45
- const to = names.get(edge.to);
46
- return from && to ? [`${from} \u2192 ${readableRelationship(edge.type)} \u2192 ${to}`] : [];
47
- })
59
+ relationships,
60
+ fallbackRelationships: relationships.map((item) => item.label)
48
61
  };
49
62
  }
50
63
  function serviceContextGraph(graph) {
@@ -86,7 +99,19 @@ function compactArchitectureGraph(graph) {
86
99
  if (!targetId || sourceId === targetId) return;
87
100
  const type = target.collapsed ? "RUNS" : target.edgeType;
88
101
  const key = `${sourceId}|${type}|${targetId}`;
89
- compactEdges.set(key, { from: sourceId, to: targetId, type });
102
+ const existing = compactEdges.get(key);
103
+ const synthetic = existing?.synthetic || target.synthetic;
104
+ const operationSources = synthetic ? [] : mergeOperationSources(
105
+ existing?.operationSources,
106
+ target.collapsed ? void 0 : target.operationSources
107
+ );
108
+ compactEdges.set(key, {
109
+ from: sourceId,
110
+ to: targetId,
111
+ type,
112
+ ...synthetic ? { synthetic: true } : {},
113
+ ...operationSources.length > 0 ? { operationSources } : {}
114
+ });
90
115
  });
91
116
  });
92
117
  return {
@@ -135,7 +160,7 @@ function summarizeDirectDependencies(graph) {
135
160
  });
136
161
  edges.push(...visible);
137
162
  edges.push(
138
- direction === "out" ? { from: root, to: aggregateId, type: sample.type } : { from: aggregateId, to: root, type: sample.type }
163
+ direction === "out" ? { from: root, to: aggregateId, type: sample.type, synthetic: true } : { from: aggregateId, to: root, type: sample.type, synthetic: true }
139
164
  );
140
165
  });
141
166
  const referenced = new Set(edges.flatMap((edge) => [edge.from, edge.to]));
@@ -152,22 +177,30 @@ function walkToVisibleTargets(start, outgoing, nodeById) {
152
177
  const queue = (outgoing.get(start) ?? []).map((edge) => ({
153
178
  id: edge.to,
154
179
  edgeType: edge.type,
155
- collapsed: false
180
+ collapsed: false,
181
+ operationSources: edge.operationSources,
182
+ synthetic: edge.synthetic
156
183
  }));
157
184
  const visited = /* @__PURE__ */ new Set();
158
185
  while (queue.length > 0) {
159
186
  const current = queue.shift();
160
- const visitKey = `${current.id}|${current.collapsed}`;
161
- if (visited.has(visitKey)) continue;
162
- visited.add(visitKey);
163
187
  const node = nodeById.get(current.id);
164
188
  if (!node) continue;
165
189
  if (!isRuntimeInstance(node)) {
166
190
  targets.push({ node, ...current });
167
191
  continue;
168
192
  }
193
+ const visitKey = `${current.id}|${current.collapsed}`;
194
+ if (visited.has(visitKey)) continue;
195
+ visited.add(visitKey);
169
196
  (outgoing.get(current.id) ?? []).forEach((edge) => {
170
- queue.push({ id: edge.to, edgeType: edge.type, collapsed: true });
197
+ queue.push({
198
+ id: edge.to,
199
+ edgeType: edge.type,
200
+ collapsed: true,
201
+ operationSources: void 0,
202
+ synthetic: void 0
203
+ });
171
204
  });
172
205
  }
173
206
  return targets;
@@ -1 +1 @@
1
- {"version":3,"file":"architectureDiagram.esm.js","sources":["../../../src/components/entity/architectureDiagram.ts"],"sourcesContent":["export interface ArchitectureNode {\n id: string;\n name: string;\n type?: string | null;\n namespace?: string | null;\n image?: string | null;\n}\n\nexport interface ArchitectureEdge {\n from: string;\n to: string;\n type: string;\n}\n\nexport interface ArchitectureGraph {\n nodes: ArchitectureNode[];\n edges: ArchitectureEdge[];\n}\n\nexport interface ArchitectureDiagramDefinition {\n source: string;\n fallbackRelationships: string[];\n}\n\ninterface CompactGraph {\n nodes: ArchitectureNode[];\n edges: ArchitectureEdge[];\n}\n\nconst RUNTIME_INSTANCE_TYPES = new Set(['K8S_REPLICASET', 'K8S_POD']);\nconst MAX_DIRECT_DEPENDENCIES = 5;\n\nexport function buildArchitectureDiagram(\n graph: ArchitectureGraph,\n options: { view?: 'context' | 'runtime' } = {},\n): ArchitectureDiagramDefinition {\n const base = compactArchitectureGraph(graph);\n const viewed = options.view === 'context' ? serviceContextGraph(base) : base;\n const compact = summarizeDirectDependencies(viewed);\n const nodeIds = new Map(\n compact.nodes.map((node, index) => [node.id, `n${index}`]),\n );\n const names = new Map(\n compact.nodes.map(node => [node.id, readableNodeLabel(node)]),\n );\n const lines = ['flowchart LR'];\n\n compact.nodes.forEach(node => {\n const id = nodeIds.get(node.id)!;\n const label = mermaidNodeLabel(node);\n if (node.type === 'DATADOG_DATASTORE') {\n lines.push(` ${id}[(\"${label}\")]`);\n } else if (\n node.type === 'DATADOG_EXTERNAL' ||\n node.type === 'DATADOG_DESTINATION'\n ) {\n lines.push(` ${id}([\"${label}\"])`);\n } else {\n lines.push(` ${id}[\"${label}\"]`);\n }\n });\n\n compact.edges.forEach(edge => {\n const from = nodeIds.get(edge.from);\n const to = nodeIds.get(edge.to);\n if (from && to) {\n lines.push(` ${from} -->|${sanitize(edge.type)}| ${to}`);\n }\n });\n\n lines.push(\n ' classDef service fill:#e8f0fe,stroke:#1967d2,color:#174ea6',\n ' classDef runtime fill:#e6f4ea,stroke:#188038,color:#137333',\n ' classDef dependency fill:#fef7e0,stroke:#f9ab00,color:#7a4f01',\n );\n compact.nodes.forEach(node => {\n const id = nodeIds.get(node.id)!;\n lines.push(` class ${id} ${className(node)}`);\n });\n\n return {\n source: lines.join('\\n'),\n fallbackRelationships: compact.edges.flatMap(edge => {\n const from = names.get(edge.from);\n const to = names.get(edge.to);\n return from && to\n ? [`${from} → ${readableRelationship(edge.type)} → ${to}`]\n : [];\n }),\n };\n}\n\nfunction serviceContextGraph(graph: CompactGraph): CompactGraph {\n const nodes = graph.nodes.filter(node => node.type !== 'K8S_CONTAINER');\n const visible = new Set(nodes.map(node => node.id));\n return {\n nodes,\n edges: graph.edges.filter(\n edge => visible.has(edge.from) && visible.has(edge.to),\n ),\n };\n}\n\nfunction compactArchitectureGraph(graph: ArchitectureGraph): CompactGraph {\n const nodeById = new Map(graph.nodes.map(node => [node.id, node]));\n const visibleNodes = graph.nodes\n .filter(node => !isRuntimeInstance(node))\n .map(normalizeNode);\n const canonicalNodes = new Map<string, ArchitectureNode>();\n const canonicalId = new Map<string, string>();\n\n visibleNodes.forEach(node => {\n const key = semanticNodeKey(node);\n const existing = canonicalNodes.get(key);\n if (existing) {\n canonicalId.set(node.id, existing.id);\n } else {\n canonicalNodes.set(key, node);\n canonicalId.set(node.id, node.id);\n }\n });\n\n const outgoing = new Map<string, ArchitectureEdge[]>();\n graph.edges.forEach(edge => {\n const list = outgoing.get(edge.from) ?? [];\n list.push(edge);\n outgoing.set(edge.from, list);\n });\n\n const compactEdges = new Map<string, ArchitectureEdge>();\n visibleNodes.forEach(source => {\n const sourceId = canonicalId.get(source.id)!;\n walkToVisibleTargets(source.id, outgoing, nodeById).forEach(target => {\n const targetId = canonicalId.get(target.node.id);\n if (!targetId || sourceId === targetId) return;\n const type = target.collapsed ? 'RUNS' : target.edgeType;\n const key = `${sourceId}|${type}|${targetId}`;\n compactEdges.set(key, { from: sourceId, to: targetId, type });\n });\n });\n\n return {\n nodes: [...canonicalNodes.values()],\n edges: [...compactEdges.values()],\n };\n}\n\nfunction summarizeDirectDependencies(graph: CompactGraph): CompactGraph {\n const root = graph.edges.find(edge => edge.type === 'RESOLVES_TO')?.from;\n if (!root) return graph;\n\n const nodes = new Map(graph.nodes.map(node => [node.id, node]));\n const groups = new Map<string, ArchitectureEdge[]>();\n const groupedEdges = new Set<ArchitectureEdge>();\n\n graph.edges.forEach(edge => {\n if (edge.type === 'RESOLVES_TO') return;\n let neighborId: string | undefined;\n if (edge.from === root) neighborId = edge.to;\n if (edge.to === root) neighborId = edge.from;\n if (!neighborId) return;\n const neighbor = nodes.get(neighborId);\n if (!neighbor || neighbor.type?.startsWith('K8S_')) return;\n const direction = edge.from === root ? 'out' : 'in';\n const key = `${direction}|${edge.type}|${neighbor.type ?? ''}`;\n const group = groups.get(key) ?? [];\n group.push(edge);\n groups.set(key, group);\n groupedEdges.add(edge);\n });\n\n const edges = graph.edges.filter(edge => !groupedEdges.has(edge));\n const aggregateNodes: ArchitectureNode[] = [];\n groups.forEach((group, key) => {\n if (group.length <= MAX_DIRECT_DEPENDENCIES) {\n edges.push(...group);\n return;\n }\n\n const visible = group.slice(0, MAX_DIRECT_DEPENDENCIES - 1);\n const hidden = group.slice(MAX_DIRECT_DEPENDENCIES - 1);\n const sample = group[0];\n const direction = sample.from === root ? 'out' : 'in';\n const neighbor = nodes.get(direction === 'out' ? sample.to : sample.from)!;\n const aggregateId = `aggregate-${key.replace(/[^A-Za-z0-9]/g, '-')}`;\n aggregateNodes.push({\n id: aggregateId,\n name: `${hidden.length} more ${pluralType(neighbor.type)}`,\n type: neighbor.type,\n });\n edges.push(...visible);\n edges.push(\n direction === 'out'\n ? { from: root, to: aggregateId, type: sample.type }\n : { from: aggregateId, to: root, type: sample.type },\n );\n });\n\n const referenced = new Set(edges.flatMap(edge => [edge.from, edge.to]));\n return {\n nodes: [\n ...graph.nodes.filter(node => referenced.has(node.id)),\n ...aggregateNodes,\n ],\n edges,\n };\n}\n\nfunction walkToVisibleTargets(\n start: string,\n outgoing: Map<string, ArchitectureEdge[]>,\n nodeById: Map<string, ArchitectureNode>,\n): Array<{\n node: ArchitectureNode;\n edgeType: string;\n collapsed: boolean;\n}> {\n const targets: Array<{\n node: ArchitectureNode;\n edgeType: string;\n collapsed: boolean;\n }> = [];\n const queue = (outgoing.get(start) ?? []).map(edge => ({\n id: edge.to,\n edgeType: edge.type,\n collapsed: false,\n }));\n const visited = new Set<string>();\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const visitKey = `${current.id}|${current.collapsed}`;\n if (visited.has(visitKey)) continue;\n visited.add(visitKey);\n\n const node = nodeById.get(current.id);\n if (!node) continue;\n if (!isRuntimeInstance(node)) {\n targets.push({ node, ...current });\n continue;\n }\n\n (outgoing.get(current.id) ?? []).forEach(edge => {\n queue.push({ id: edge.to, edgeType: edge.type, collapsed: true });\n });\n }\n\n return targets;\n}\n\nfunction isRuntimeInstance(node: ArchitectureNode): boolean {\n return RUNTIME_INSTANCE_TYPES.has(node.type ?? '');\n}\n\nfunction normalizeNode(node: ArchitectureNode): ArchitectureNode {\n if (node.type !== 'K8S_CONTAINER') return node;\n const slash = node.name.lastIndexOf('/');\n return {\n ...node,\n name: slash >= 0 ? node.name.slice(slash + 1) : node.name,\n image: node.image ? imageRepository(node.image) : node.image,\n };\n}\n\nfunction imageRepository(image: string): string {\n const withoutDigest = image.split('@', 1)[0];\n const slash = withoutDigest.lastIndexOf('/');\n const tag = withoutDigest.lastIndexOf(':');\n const repository = tag > slash ? withoutDigest.slice(0, tag) : withoutDigest;\n return repository.slice(repository.lastIndexOf('/') + 1);\n}\n\nfunction semanticNodeKey(node: ArchitectureNode): string {\n return [\n node.type ?? '',\n node.namespace ?? '',\n node.name,\n node.image ?? '',\n ].join('|');\n}\n\nfunction readableNodeLabel(node: ArchitectureNode): string {\n const type = shortType(node.type);\n const typed = type ? `${node.name} [${type}]` : node.name;\n return node.type?.startsWith('K8S_') && node.namespace\n ? `${typed} (${node.namespace})`\n : typed;\n}\n\nfunction mermaidNodeLabel(node: ArchitectureNode): string {\n const parts = [sanitize(node.name)];\n const type = shortType(node.type);\n if (type) parts.push(`[${type}]`);\n if (node.type?.startsWith('K8S_') && node.namespace) {\n parts.push(`namespace: ${sanitize(node.namespace)}`);\n }\n if (node.image) parts.push(sanitize(node.image));\n return parts.join('<br/>');\n}\n\nfunction shortType(type?: string | null): string {\n return (type ?? '').replace(/^K8S_|^DATADOG_/, '');\n}\n\nfunction pluralType(type?: string | null): string {\n return `${shortType(type).toLocaleLowerCase()}s`;\n}\n\nfunction readableRelationship(type: string): string {\n return type.toLocaleLowerCase().replace(/_/g, ' ');\n}\n\nfunction sanitize(value: string): string {\n return value\n .replace(/\"/g, \"'\")\n .replace(/[<>|]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction className(node: ArchitectureNode): string {\n if (node.type?.startsWith('K8S_')) return 'runtime';\n if (node.type === 'DATADOG_SERVICE') return 'service';\n return 'dependency';\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"architectureDiagram.esm.js","sources":["../../../src/components/entity/architectureDiagram.ts"],"sourcesContent":["import {\n architectureEdgeKey,\n mergeOperationSources,\n uniqueOperationCount,\n type ArchitectureEdge,\n type ArchitectureGraph,\n type ArchitectureNode,\n type ArchitectureOperationSource,\n} from './architectureGraph';\n\nexport type {\n ArchitectureEdge,\n ArchitectureGraph,\n ArchitectureNode,\n ArchitectureOperationSource,\n} from './architectureGraph';\n\nexport interface ArchitectureDiagramRelationship {\n id: string;\n diagramIndex: number;\n label: string;\n fromLabel: string;\n toLabel: string;\n type: string;\n operationCount: number;\n operationSources: ArchitectureOperationSource[];\n}\n\nexport interface ArchitectureDiagramDefinition {\n source: string;\n relationships: ArchitectureDiagramRelationship[];\n fallbackRelationships: string[];\n}\n\ninterface CompactGraph {\n nodes: ArchitectureNode[];\n edges: ArchitectureEdge[];\n}\n\nconst RUNTIME_INSTANCE_TYPES = new Set(['K8S_REPLICASET', 'K8S_POD']);\nconst MAX_DIRECT_DEPENDENCIES = 5;\n\nexport function buildArchitectureDiagram(\n graph: ArchitectureGraph,\n options: { view?: 'context' | 'runtime' } = {},\n): ArchitectureDiagramDefinition {\n const base = compactArchitectureGraph(graph);\n const viewed = options.view === 'context' ? serviceContextGraph(base) : base;\n const compact = summarizeDirectDependencies(viewed);\n const nodeIds = new Map(\n compact.nodes.map((node, index) => [node.id, `n${index}`]),\n );\n const names = new Map(\n compact.nodes.map(node => [node.id, readableNodeLabel(node)]),\n );\n const lines = ['flowchart LR'];\n const relationships: ArchitectureDiagramRelationship[] = [];\n\n compact.nodes.forEach(node => {\n const id = nodeIds.get(node.id)!;\n const label = mermaidNodeLabel(node);\n if (node.type === 'DATADOG_DATASTORE') {\n lines.push(` ${id}[(\"${label}\")]`);\n } else if (\n node.type === 'DATADOG_EXTERNAL' ||\n node.type === 'DATADOG_DESTINATION'\n ) {\n lines.push(` ${id}([\"${label}\"])`);\n } else {\n lines.push(` ${id}[\"${label}\"]`);\n }\n });\n\n compact.edges.forEach(edge => {\n const from = nodeIds.get(edge.from);\n const to = nodeIds.get(edge.to);\n const fromLabel = names.get(edge.from);\n const toLabel = names.get(edge.to);\n if (!from || !to || !fromLabel || !toLabel) return;\n\n const operationCount = edge.synthetic\n ? 0\n : uniqueOperationCount(edge.operationSources);\n const edgeLabel =\n operationCount > 0\n ? `${edge.type} · HTTP · ${operationCount}`\n : edge.type;\n lines.push(` ${from} -->|${sanitize(edgeLabel)}| ${to}`);\n relationships.push({\n id: architectureEdgeKey(edge),\n diagramIndex: relationships.length,\n label: `${fromLabel} → ${readableRelationship(edge.type)} → ${toLabel}`,\n fromLabel,\n toLabel,\n type: edge.type,\n operationCount,\n operationSources: operationCount > 0 ? edge.operationSources ?? [] : [],\n });\n });\n\n lines.push(\n ' classDef service fill:#e8f0fe,stroke:#1967d2,color:#174ea6',\n ' classDef runtime fill:#e6f4ea,stroke:#188038,color:#137333',\n ' classDef dependency fill:#fef7e0,stroke:#f9ab00,color:#7a4f01',\n );\n compact.nodes.forEach(node => {\n const id = nodeIds.get(node.id)!;\n lines.push(` class ${id} ${className(node)}`);\n });\n\n return {\n source: lines.join('\\n'),\n relationships,\n fallbackRelationships: relationships.map(item => item.label),\n };\n}\n\nfunction serviceContextGraph(graph: CompactGraph): CompactGraph {\n const nodes = graph.nodes.filter(node => node.type !== 'K8S_CONTAINER');\n const visible = new Set(nodes.map(node => node.id));\n return {\n nodes,\n edges: graph.edges.filter(\n edge => visible.has(edge.from) && visible.has(edge.to),\n ),\n };\n}\n\nfunction compactArchitectureGraph(graph: ArchitectureGraph): CompactGraph {\n const nodeById = new Map(graph.nodes.map(node => [node.id, node]));\n const visibleNodes = graph.nodes\n .filter(node => !isRuntimeInstance(node))\n .map(normalizeNode);\n const canonicalNodes = new Map<string, ArchitectureNode>();\n const canonicalId = new Map<string, string>();\n\n visibleNodes.forEach(node => {\n const key = semanticNodeKey(node);\n const existing = canonicalNodes.get(key);\n if (existing) {\n canonicalId.set(node.id, existing.id);\n } else {\n canonicalNodes.set(key, node);\n canonicalId.set(node.id, node.id);\n }\n });\n\n const outgoing = new Map<string, ArchitectureEdge[]>();\n graph.edges.forEach(edge => {\n const list = outgoing.get(edge.from) ?? [];\n list.push(edge);\n outgoing.set(edge.from, list);\n });\n\n const compactEdges = new Map<string, ArchitectureEdge>();\n visibleNodes.forEach(source => {\n const sourceId = canonicalId.get(source.id)!;\n walkToVisibleTargets(source.id, outgoing, nodeById).forEach(target => {\n const targetId = canonicalId.get(target.node.id);\n if (!targetId || sourceId === targetId) return;\n const type = target.collapsed ? 'RUNS' : target.edgeType;\n const key = `${sourceId}|${type}|${targetId}`;\n const existing = compactEdges.get(key);\n const synthetic = existing?.synthetic || target.synthetic;\n const operationSources = synthetic\n ? []\n : mergeOperationSources(\n existing?.operationSources,\n target.collapsed ? undefined : target.operationSources,\n );\n compactEdges.set(key, {\n from: sourceId,\n to: targetId,\n type,\n ...(synthetic ? { synthetic: true } : {}),\n ...(operationSources.length > 0 ? { operationSources } : {}),\n });\n });\n });\n\n return {\n nodes: [...canonicalNodes.values()],\n edges: [...compactEdges.values()],\n };\n}\n\nfunction summarizeDirectDependencies(graph: CompactGraph): CompactGraph {\n const root = graph.edges.find(edge => edge.type === 'RESOLVES_TO')?.from;\n if (!root) return graph;\n\n const nodes = new Map(graph.nodes.map(node => [node.id, node]));\n const groups = new Map<string, ArchitectureEdge[]>();\n const groupedEdges = new Set<ArchitectureEdge>();\n\n graph.edges.forEach(edge => {\n if (edge.type === 'RESOLVES_TO') return;\n let neighborId: string | undefined;\n if (edge.from === root) neighborId = edge.to;\n if (edge.to === root) neighborId = edge.from;\n if (!neighborId) return;\n const neighbor = nodes.get(neighborId);\n if (!neighbor || neighbor.type?.startsWith('K8S_')) return;\n const direction = edge.from === root ? 'out' : 'in';\n const key = `${direction}|${edge.type}|${neighbor.type ?? ''}`;\n const group = groups.get(key) ?? [];\n group.push(edge);\n groups.set(key, group);\n groupedEdges.add(edge);\n });\n\n const edges = graph.edges.filter(edge => !groupedEdges.has(edge));\n const aggregateNodes: ArchitectureNode[] = [];\n groups.forEach((group, key) => {\n if (group.length <= MAX_DIRECT_DEPENDENCIES) {\n edges.push(...group);\n return;\n }\n\n const visible = group.slice(0, MAX_DIRECT_DEPENDENCIES - 1);\n const hidden = group.slice(MAX_DIRECT_DEPENDENCIES - 1);\n const sample = group[0];\n const direction = sample.from === root ? 'out' : 'in';\n const neighbor = nodes.get(direction === 'out' ? sample.to : sample.from)!;\n const aggregateId = `aggregate-${key.replace(/[^A-Za-z0-9]/g, '-')}`;\n aggregateNodes.push({\n id: aggregateId,\n name: `${hidden.length} more ${pluralType(neighbor.type)}`,\n type: neighbor.type,\n });\n edges.push(...visible);\n edges.push(\n direction === 'out'\n ? { from: root, to: aggregateId, type: sample.type, synthetic: true }\n : { from: aggregateId, to: root, type: sample.type, synthetic: true },\n );\n });\n\n const referenced = new Set(edges.flatMap(edge => [edge.from, edge.to]));\n return {\n nodes: [\n ...graph.nodes.filter(node => referenced.has(node.id)),\n ...aggregateNodes,\n ],\n edges,\n };\n}\n\nfunction walkToVisibleTargets(\n start: string,\n outgoing: Map<string, ArchitectureEdge[]>,\n nodeById: Map<string, ArchitectureNode>,\n): Array<{\n node: ArchitectureNode;\n edgeType: string;\n collapsed: boolean;\n operationSources?: ArchitectureOperationSource[];\n synthetic?: boolean;\n}> {\n const targets: Array<{\n node: ArchitectureNode;\n edgeType: string;\n collapsed: boolean;\n operationSources?: ArchitectureOperationSource[];\n synthetic?: boolean;\n }> = [];\n const queue = (outgoing.get(start) ?? []).map(edge => ({\n id: edge.to,\n edgeType: edge.type,\n collapsed: false,\n operationSources: edge.operationSources,\n synthetic: edge.synthetic,\n }));\n const visited = new Set<string>();\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const node = nodeById.get(current.id);\n if (!node) continue;\n if (!isRuntimeInstance(node)) {\n targets.push({ node, ...current });\n continue;\n }\n\n const visitKey = `${current.id}|${current.collapsed}`;\n if (visited.has(visitKey)) continue;\n visited.add(visitKey);\n\n (outgoing.get(current.id) ?? []).forEach(edge => {\n queue.push({\n id: edge.to,\n edgeType: edge.type,\n collapsed: true,\n operationSources: undefined,\n synthetic: undefined,\n });\n });\n }\n\n return targets;\n}\n\nfunction isRuntimeInstance(node: ArchitectureNode): boolean {\n return RUNTIME_INSTANCE_TYPES.has(node.type ?? '');\n}\n\nfunction normalizeNode(node: ArchitectureNode): ArchitectureNode {\n if (node.type !== 'K8S_CONTAINER') return node;\n const slash = node.name.lastIndexOf('/');\n return {\n ...node,\n name: slash >= 0 ? node.name.slice(slash + 1) : node.name,\n image: node.image ? imageRepository(node.image) : node.image,\n };\n}\n\nfunction imageRepository(image: string): string {\n const withoutDigest = image.split('@', 1)[0];\n const slash = withoutDigest.lastIndexOf('/');\n const tag = withoutDigest.lastIndexOf(':');\n const repository = tag > slash ? withoutDigest.slice(0, tag) : withoutDigest;\n return repository.slice(repository.lastIndexOf('/') + 1);\n}\n\nfunction semanticNodeKey(node: ArchitectureNode): string {\n return [\n node.type ?? '',\n node.namespace ?? '',\n node.name,\n node.image ?? '',\n ].join('|');\n}\n\nfunction readableNodeLabel(node: ArchitectureNode): string {\n const type = shortType(node.type);\n const typed = type ? `${node.name} [${type}]` : node.name;\n return node.type?.startsWith('K8S_') && node.namespace\n ? `${typed} (${node.namespace})`\n : typed;\n}\n\nfunction mermaidNodeLabel(node: ArchitectureNode): string {\n const parts = [sanitize(node.name)];\n const type = shortType(node.type);\n if (type) parts.push(`[${type}]`);\n if (node.type?.startsWith('K8S_') && node.namespace) {\n parts.push(`namespace: ${sanitize(node.namespace)}`);\n }\n if (node.image) parts.push(sanitize(node.image));\n return parts.join('<br/>');\n}\n\nfunction shortType(type?: string | null): string {\n return (type ?? '').replace(/^K8S_|^DATADOG_/, '');\n}\n\nfunction pluralType(type?: string | null): string {\n return `${shortType(type).toLocaleLowerCase()}s`;\n}\n\nfunction readableRelationship(type: string): string {\n return type.toLocaleLowerCase().replace(/_/g, ' ');\n}\n\nfunction sanitize(value: string): string {\n return value\n .replace(/\"/g, \"'\")\n .replace(/[<>|]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction className(node: ArchitectureNode): string {\n if (node.type?.startsWith('K8S_')) return 'runtime';\n if (node.type === 'DATADOG_SERVICE') return 'service';\n return 'dependency';\n}\n"],"names":[],"mappings":";;AAuCA,MAAM,yCAAyB,IAAI,GAAA,CAAI,CAAC,gBAAA,EAAkB,SAAS,CAAC,CAAA;AACpE,MAAM,uBAAA,GAA0B,CAAA;AAEzB,SAAS,wBAAA,CACd,KAAA,EACA,OAAA,GAA4C,EAAC,EACd;AAC/B,EAAA,MAAM,IAAA,GAAO,yBAAyB,KAAK,CAAA;AAC3C,EAAA,MAAM,SAAS,OAAA,CAAQ,IAAA,KAAS,SAAA,GAAY,mBAAA,CAAoB,IAAI,CAAA,GAAI,IAAA;AACxE,EAAA,MAAM,OAAA,GAAU,4BAA4B,MAAM,CAAA;AAClD,EAAA,MAAM,UAAU,IAAI,GAAA;AAAA,IAClB,OAAA,CAAQ,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,KAAU,CAAC,IAAA,CAAK,EAAA,EAAI,CAAA,CAAA,EAAI,KAAK,CAAA,CAAE,CAAC;AAAA,GAC3D;AACA,EAAA,MAAM,QAAQ,IAAI,GAAA;AAAA,IAChB,OAAA,CAAQ,KAAA,CAAM,GAAA,CAAI,CAAA,IAAA,KAAQ,CAAC,KAAK,EAAA,EAAI,iBAAA,CAAkB,IAAI,CAAC,CAAC;AAAA,GAC9D;AACA,EAAA,MAAM,KAAA,GAAQ,CAAC,cAAc,CAAA;AAC7B,EAAA,MAAM,gBAAmD,EAAC;AAE1D,EAAA,OAAA,CAAQ,KAAA,CAAM,QAAQ,CAAA,IAAA,KAAQ;AAC5B,IAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA;AAC9B,IAAA,MAAM,KAAA,GAAQ,iBAAiB,IAAI,CAAA;AACnC,IAAA,IAAI,IAAA,CAAK,SAAS,mBAAA,EAAqB;AACrC,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,EAAE,CAAA,GAAA,EAAM,KAAK,CAAA,GAAA,CAAK,CAAA;AAAA,IACpC,WACE,IAAA,CAAK,IAAA,KAAS,kBAAA,IACd,IAAA,CAAK,SAAS,qBAAA,EACd;AACA,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,EAAE,CAAA,GAAA,EAAM,KAAK,CAAA,GAAA,CAAK,CAAA;AAAA,IACpC,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,EAAE,CAAA,EAAA,EAAK,KAAK,CAAA,EAAA,CAAI,CAAA;AAAA,IAClC;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAA,CAAQ,KAAA,CAAM,QAAQ,CAAA,IAAA,KAAQ;AAC5B,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA;AAClC,IAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA;AAC9B,IAAA,MAAM,SAAA,GAAY,KAAA,CAAM,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA;AACrC,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA;AACjC,IAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,MAAM,CAAC,SAAA,IAAa,CAAC,OAAA,EAAS;AAE5C,IAAA,MAAM,iBAAiB,IAAA,CAAK,SAAA,GACxB,CAAA,GACA,oBAAA,CAAqB,KAAK,gBAAgB,CAAA;AAC9C,IAAA,MAAM,SAAA,GACJ,iBAAiB,CAAA,GACb,CAAA,EAAG,KAAK,IAAI,CAAA,gBAAA,EAAa,cAAc,CAAA,CAAA,GACvC,IAAA,CAAK,IAAA;AACX,IAAA,KAAA,CAAM,IAAA,CAAK,KAAK,IAAI,CAAA,KAAA,EAAQ,SAAS,SAAS,CAAC,CAAA,EAAA,EAAK,EAAE,CAAA,CAAE,CAAA;AACxD,IAAA,aAAA,CAAc,IAAA,CAAK;AAAA,MACjB,EAAA,EAAI,oBAAoB,IAAI,CAAA;AAAA,MAC5B,cAAc,aAAA,CAAc,MAAA;AAAA,MAC5B,KAAA,EAAO,GAAG,SAAS,CAAA,QAAA,EAAM,qBAAqB,IAAA,CAAK,IAAI,CAAC,CAAA,QAAA,EAAM,OAAO,CAAA,CAAA;AAAA,MACrE,SAAA;AAAA,MACA,OAAA;AAAA,MACA,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,cAAA;AAAA,MACA,kBAAkB,cAAA,GAAiB,CAAA,GAAI,KAAK,gBAAA,IAAoB,KAAK;AAAC,KACvE,CAAA;AAAA,EACH,CAAC,CAAA;AAED,EAAA,KAAA,CAAM,IAAA;AAAA,IACJ,8DAAA;AAAA,IACA,8DAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,OAAA,CAAQ,KAAA,CAAM,QAAQ,CAAA,IAAA,KAAQ;AAC5B,IAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA;AAC9B,IAAA,KAAA,CAAM,KAAK,CAAA,QAAA,EAAW,EAAE,IAAI,SAAA,CAAU,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,EAC/C,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA;AAAA,IACvB,aAAA;AAAA,IACA,qBAAA,EAAuB,aAAA,CAAc,GAAA,CAAI,CAAA,IAAA,KAAQ,KAAK,KAAK;AAAA,GAC7D;AACF;AAEA,SAAS,oBAAoB,KAAA,EAAmC;AAC9D,EAAA,MAAM,QAAQ,KAAA,CAAM,KAAA,CAAM,OAAO,CAAA,IAAA,KAAQ,IAAA,CAAK,SAAS,eAAe,CAAA;AACtE,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,IAAA,KAAQ,IAAA,CAAK,EAAE,CAAC,CAAA;AAClD,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,KAAA,EAAO,MAAM,KAAA,CAAM,MAAA;AAAA,MACjB,CAAA,IAAA,KAAQ,QAAQ,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,IAAK,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,EAAE;AAAA;AACvD,GACF;AACF;AAEA,SAAS,yBAAyB,KAAA,EAAwC;AACxE,EAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,CAAA,IAAA,KAAQ,CAAC,IAAA,CAAK,EAAA,EAAI,IAAI,CAAC,CAAC,CAAA;AACjE,EAAA,MAAM,YAAA,GAAe,KAAA,CAAM,KAAA,CACxB,MAAA,CAAO,CAAA,IAAA,KAAQ,CAAC,iBAAA,CAAkB,IAAI,CAAC,CAAA,CACvC,GAAA,CAAI,aAAa,CAAA;AACpB,EAAA,MAAM,cAAA,uBAAqB,GAAA,EAA8B;AACzD,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAoB;AAE5C,EAAA,YAAA,CAAa,QAAQ,CAAA,IAAA,KAAQ;AAC3B,IAAA,MAAM,GAAA,GAAM,gBAAgB,IAAI,CAAA;AAChC,IAAA,MAAM,QAAA,GAAW,cAAA,CAAe,GAAA,CAAI,GAAG,CAAA;AACvC,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,WAAA,CAAY,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,QAAA,CAAS,EAAE,CAAA;AAAA,IACtC,CAAA,MAAO;AACL,MAAA,cAAA,CAAe,GAAA,CAAI,KAAK,IAAI,CAAA;AAC5B,MAAA,WAAA,CAAY,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,IAAA,CAAK,EAAE,CAAA;AAAA,IAClC;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAgC;AACrD,EAAA,KAAA,CAAM,KAAA,CAAM,QAAQ,CAAA,IAAA,KAAQ;AAC1B,IAAA,MAAM,OAAO,QAAA,CAAS,GAAA,CAAI,IAAA,CAAK,IAAI,KAAK,EAAC;AACzC,IAAA,IAAA,CAAK,KAAK,IAAI,CAAA;AACd,IAAA,QAAA,CAAS,GAAA,CAAI,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AAAA,EAC9B,CAAC,CAAA;AAED,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAA8B;AACvD,EAAA,YAAA,CAAa,QAAQ,CAAA,MAAA,KAAU;AAC7B,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA;AAC1C,IAAA,oBAAA,CAAqB,OAAO,EAAA,EAAI,QAAA,EAAU,QAAQ,CAAA,CAAE,QAAQ,CAAA,MAAA,KAAU;AACpE,MAAA,MAAM,QAAA,GAAW,WAAA,CAAY,GAAA,CAAI,MAAA,CAAO,KAAK,EAAE,CAAA;AAC/C,MAAA,IAAI,CAAC,QAAA,IAAY,QAAA,KAAa,QAAA,EAAU;AACxC,MAAA,MAAM,IAAA,GAAO,MAAA,CAAO,SAAA,GAAY,MAAA,GAAS,MAAA,CAAO,QAAA;AAChD,MAAA,MAAM,MAAM,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,IAAI,IAAI,QAAQ,CAAA,CAAA;AAC3C,MAAA,MAAM,QAAA,GAAW,YAAA,CAAa,GAAA,CAAI,GAAG,CAAA;AACrC,MAAA,MAAM,SAAA,GAAY,QAAA,EAAU,SAAA,IAAa,MAAA,CAAO,SAAA;AAChD,MAAA,MAAM,gBAAA,GAAmB,SAAA,GACrB,EAAC,GACD,qBAAA;AAAA,QACE,QAAA,EAAU,gBAAA;AAAA,QACV,MAAA,CAAO,SAAA,GAAY,MAAA,GAAY,MAAA,CAAO;AAAA,OACxC;AACJ,MAAA,YAAA,CAAa,IAAI,GAAA,EAAK;AAAA,QACpB,IAAA,EAAM,QAAA;AAAA,QACN,EAAA,EAAI,QAAA;AAAA,QACJ,IAAA;AAAA,QACA,GAAI,SAAA,GAAY,EAAE,SAAA,EAAW,IAAA,KAAS,EAAC;AAAA,QACvC,GAAI,gBAAA,CAAiB,MAAA,GAAS,IAAI,EAAE,gBAAA,KAAqB;AAAC,OAC3D,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,CAAC,GAAG,cAAA,CAAe,QAAQ,CAAA;AAAA,IAClC,KAAA,EAAO,CAAC,GAAG,YAAA,CAAa,QAAQ;AAAA,GAClC;AACF;AAEA,SAAS,4BAA4B,KAAA,EAAmC;AACtE,EAAA,MAAM,IAAA,GAAO,MAAM,KAAA,CAAM,IAAA,CAAK,UAAQ,IAAA,CAAK,IAAA,KAAS,aAAa,CAAA,EAAG,IAAA;AACpE,EAAA,IAAI,CAAC,MAAM,OAAO,KAAA;AAElB,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,CAAA,IAAA,KAAQ,CAAC,IAAA,CAAK,EAAA,EAAI,IAAI,CAAC,CAAC,CAAA;AAC9D,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAgC;AACnD,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAAsB;AAE/C,EAAA,KAAA,CAAM,KAAA,CAAM,QAAQ,CAAA,IAAA,KAAQ;AAC1B,IAAA,IAAI,IAAA,CAAK,SAAS,aAAA,EAAe;AACjC,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI,IAAA,CAAK,IAAA,KAAS,IAAA,EAAM,UAAA,GAAa,IAAA,CAAK,EAAA;AAC1C,IAAA,IAAI,IAAA,CAAK,EAAA,KAAO,IAAA,EAAM,UAAA,GAAa,IAAA,CAAK,IAAA;AACxC,IAAA,IAAI,CAAC,UAAA,EAAY;AACjB,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,GAAA,CAAI,UAAU,CAAA;AACrC,IAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,IAAA,EAAM,UAAA,CAAW,MAAM,CAAA,EAAG;AACpD,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,IAAA,KAAS,IAAA,GAAO,KAAA,GAAQ,IAAA;AAC/C,IAAA,MAAM,GAAA,GAAM,GAAG,SAAS,CAAA,CAAA,EAAI,KAAK,IAAI,CAAA,CAAA,EAAI,QAAA,CAAS,IAAA,IAAQ,EAAE,CAAA,CAAA;AAC5D,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,GAAG,KAAK,EAAC;AAClC,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,IAAA,MAAA,CAAO,GAAA,CAAI,KAAK,KAAK,CAAA;AACrB,IAAA,YAAA,CAAa,IAAI,IAAI,CAAA;AAAA,EACvB,CAAC,CAAA;AAED,EAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,MAAA,CAAO,UAAQ,CAAC,YAAA,CAAa,GAAA,CAAI,IAAI,CAAC,CAAA;AAChE,EAAA,MAAM,iBAAqC,EAAC;AAC5C,EAAA,MAAA,CAAO,OAAA,CAAQ,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC7B,IAAA,IAAI,KAAA,CAAM,UAAU,uBAAA,EAAyB;AAC3C,MAAA,KAAA,CAAM,IAAA,CAAK,GAAG,KAAK,CAAA;AACnB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,0BAA0B,CAAC,CAAA;AAC1D,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,KAAA,CAAM,uBAAA,GAA0B,CAAC,CAAA;AACtD,IAAA,MAAM,MAAA,GAAS,MAAM,CAAC,CAAA;AACtB,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,IAAA,KAAS,IAAA,GAAO,KAAA,GAAQ,IAAA;AACjD,IAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,SAAA,KAAc,QAAQ,MAAA,CAAO,EAAA,GAAK,OAAO,IAAI,CAAA;AACxE,IAAA,MAAM,cAAc,CAAA,UAAA,EAAa,GAAA,CAAI,OAAA,CAAQ,eAAA,EAAiB,GAAG,CAAC,CAAA,CAAA;AAClE,IAAA,cAAA,CAAe,IAAA,CAAK;AAAA,MAClB,EAAA,EAAI,WAAA;AAAA,MACJ,IAAA,EAAM,GAAG,MAAA,CAAO,MAAM,SAAS,UAAA,CAAW,QAAA,CAAS,IAAI,CAAC,CAAA,CAAA;AAAA,MACxD,MAAM,QAAA,CAAS;AAAA,KAChB,CAAA;AACD,IAAA,KAAA,CAAM,IAAA,CAAK,GAAG,OAAO,CAAA;AACrB,IAAA,KAAA,CAAM,IAAA;AAAA,MACJ,SAAA,KAAc,QACV,EAAE,IAAA,EAAM,MAAM,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,SAAA,EAAW,MAAK,GAClE,EAAE,MAAM,WAAA,EAAa,EAAA,EAAI,MAAM,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,SAAA,EAAW,IAAA;AAAK,KACxE;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,KAAA,CAAM,OAAA,CAAQ,CAAA,IAAA,KAAQ,CAAC,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,EAAE,CAAC,CAAC,CAAA;AACtE,EAAA,OAAO;AAAA,IACL,KAAA,EAAO;AAAA,MACL,GAAG,MAAM,KAAA,CAAM,MAAA,CAAO,UAAQ,UAAA,CAAW,GAAA,CAAI,IAAA,CAAK,EAAE,CAAC,CAAA;AAAA,MACrD,GAAG;AAAA,KACL;AAAA,IACA;AAAA,GACF;AACF;AAEA,SAAS,oBAAA,CACP,KAAA,EACA,QAAA,EACA,QAAA,EAOC;AACD,EAAA,MAAM,UAMD,EAAC;AACN,EAAA,MAAM,KAAA,GAAA,CAAS,SAAS,GAAA,CAAI,KAAK,KAAK,EAAC,EAAG,IAAI,CAAA,IAAA,MAAS;AAAA,IACrD,IAAI,IAAA,CAAK,EAAA;AAAA,IACT,UAAU,IAAA,CAAK,IAAA;AAAA,IACf,SAAA,EAAW,KAAA;AAAA,IACX,kBAAkB,IAAA,CAAK,gBAAA;AAAA,IACvB,WAAW,IAAA,CAAK;AAAA,GAClB,CAAE,CAAA;AACF,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAEhC,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACvB,IAAA,MAAM,OAAA,GAAU,MAAM,KAAA,EAAM;AAC5B,IAAA,MAAM,IAAA,GAAO,QAAA,CAAS,GAAA,CAAI,OAAA,CAAQ,EAAE,CAAA;AACpC,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,IAAI,CAAC,iBAAA,CAAkB,IAAI,CAAA,EAAG;AAC5B,MAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,GAAG,SAAS,CAAA;AACjC,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,WAAW,CAAA,EAAG,OAAA,CAAQ,EAAE,CAAA,CAAA,EAAI,QAAQ,SAAS,CAAA,CAAA;AACnD,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC3B,IAAA,OAAA,CAAQ,IAAI,QAAQ,CAAA;AAEpB,IAAA,CAAC,QAAA,CAAS,IAAI,OAAA,CAAQ,EAAE,KAAK,EAAC,EAAG,QAAQ,CAAA,IAAA,KAAQ;AAC/C,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,IAAI,IAAA,CAAK,EAAA;AAAA,QACT,UAAU,IAAA,CAAK,IAAA;AAAA,QACf,SAAA,EAAW,IAAA;AAAA,QACX,gBAAA,EAAkB,MAAA;AAAA,QAClB,SAAA,EAAW;AAAA,OACZ,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,kBAAkB,IAAA,EAAiC;AAC1D,EAAA,OAAO,sBAAA,CAAuB,GAAA,CAAI,IAAA,CAAK,IAAA,IAAQ,EAAE,CAAA;AACnD;AAEA,SAAS,cAAc,IAAA,EAA0C;AAC/D,EAAA,IAAI,IAAA,CAAK,IAAA,KAAS,eAAA,EAAiB,OAAO,IAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,IAAA,CAAK,WAAA,CAAY,GAAG,CAAA;AACvC,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,IAAA,EAAM,SAAS,CAAA,GAAI,IAAA,CAAK,KAAK,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAA,GAAI,IAAA,CAAK,IAAA;AAAA,IACrD,OAAO,IAAA,CAAK,KAAA,GAAQ,gBAAgB,IAAA,CAAK,KAAK,IAAI,IAAA,CAAK;AAAA,GACzD;AACF;AAEA,SAAS,gBAAgB,KAAA,EAAuB;AAC9C,EAAA,MAAM,gBAAgB,KAAA,CAAM,KAAA,CAAM,GAAA,EAAK,CAAC,EAAE,CAAC,CAAA;AAC3C,EAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,WAAA,CAAY,GAAG,CAAA;AAC3C,EAAA,MAAM,GAAA,GAAM,aAAA,CAAc,WAAA,CAAY,GAAG,CAAA;AACzC,EAAA,MAAM,aAAa,GAAA,GAAM,KAAA,GAAQ,cAAc,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,GAAI,aAAA;AAC/D,EAAA,OAAO,WAAW,KAAA,CAAM,UAAA,CAAW,WAAA,CAAY,GAAG,IAAI,CAAC,CAAA;AACzD;AAEA,SAAS,gBAAgB,IAAA,EAAgC;AACvD,EAAA,OAAO;AAAA,IACL,KAAK,IAAA,IAAQ,EAAA;AAAA,IACb,KAAK,SAAA,IAAa,EAAA;AAAA,IAClB,IAAA,CAAK,IAAA;AAAA,IACL,KAAK,KAAA,IAAS;AAAA,GAChB,CAAE,KAAK,GAAG,CAAA;AACZ;AAEA,SAAS,kBAAkB,IAAA,EAAgC;AACzD,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAChC,EAAA,MAAM,KAAA,GAAQ,OAAO,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,IAAI,MAAM,IAAA,CAAK,IAAA;AACrD,EAAA,OAAO,IAAA,CAAK,IAAA,EAAM,UAAA,CAAW,MAAM,CAAA,IAAK,IAAA,CAAK,SAAA,GACzC,CAAA,EAAG,KAAK,CAAA,EAAA,EAAK,IAAA,CAAK,SAAS,CAAA,CAAA,CAAA,GAC3B,KAAA;AACN;AAEA,SAAS,iBAAiB,IAAA,EAAgC;AACxD,EAAA,MAAM,KAAA,GAAQ,CAAC,QAAA,CAAS,IAAA,CAAK,IAAI,CAAC,CAAA;AAClC,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAChC,EAAA,IAAI,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,CAAG,CAAA;AAChC,EAAA,IAAI,KAAK,IAAA,EAAM,UAAA,CAAW,MAAM,CAAA,IAAK,KAAK,SAAA,EAAW;AACnD,IAAA,KAAA,CAAM,KAAK,CAAA,WAAA,EAAc,QAAA,CAAS,IAAA,CAAK,SAAS,CAAC,CAAA,CAAE,CAAA;AAAA,EACrD;AACA,EAAA,IAAI,KAAK,KAAA,EAAO,KAAA,CAAM,KAAK,QAAA,CAAS,IAAA,CAAK,KAAK,CAAC,CAAA;AAC/C,EAAA,OAAO,KAAA,CAAM,KAAK,OAAO,CAAA;AAC3B;AAEA,SAAS,UAAU,IAAA,EAA8B;AAC/C,EAAA,OAAA,CAAQ,IAAA,IAAQ,EAAA,EAAI,OAAA,CAAQ,iBAAA,EAAmB,EAAE,CAAA;AACnD;AAEA,SAAS,WAAW,IAAA,EAA8B;AAChD,EAAA,OAAO,CAAA,EAAG,SAAA,CAAU,IAAI,CAAA,CAAE,mBAAmB,CAAA,CAAA,CAAA;AAC/C;AAEA,SAAS,qBAAqB,IAAA,EAAsB;AAClD,EAAA,OAAO,IAAA,CAAK,iBAAA,EAAkB,CAAE,OAAA,CAAQ,MAAM,GAAG,CAAA;AACnD;AAEA,SAAS,SAAS,KAAA,EAAuB;AACvC,EAAA,OAAO,KAAA,CACJ,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA,CACjB,OAAA,CAAQ,QAAA,EAAU,GAAG,CAAA,CACrB,OAAA,CAAQ,MAAA,EAAQ,GAAG,EACnB,IAAA,EAAK;AACV;AAEA,SAAS,UAAU,IAAA,EAAgC;AACjD,EAAA,IAAI,IAAA,CAAK,IAAA,EAAM,UAAA,CAAW,MAAM,GAAG,OAAO,SAAA;AAC1C,EAAA,IAAI,IAAA,CAAK,IAAA,KAAS,iBAAA,EAAmB,OAAO,SAAA;AAC5C,EAAA,OAAO,YAAA;AACT;;;;"}
@@ -0,0 +1,145 @@
1
+ const UNAVAILABLE_APM_SOURCE = "APM source unavailable";
2
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
3
+ const cleanText = (value) => typeof value === "string" && value.trim() ? value.trim() : null;
4
+ const usableTimestamp = (value) => {
5
+ const text = cleanText(value);
6
+ return text && !Number.isNaN(Date.parse(text)) ? text : null;
7
+ };
8
+ const operationKey = (operation) => `${operation.method ?? ""}\0${operation.pathTemplate ?? ""}`;
9
+ const architectureEdgeKey = (edge) => `${edge.from}\0${edge.type}\0${edge.to}`;
10
+ const uniqueOperationCount = (sources) => new Set(
11
+ (sources ?? []).flatMap((source) => source.operations.map(operationKey))
12
+ ).size;
13
+ const mergeOperationSources = (left, right) => {
14
+ const grouped = /* @__PURE__ */ new Map();
15
+ [...left ?? [], ...right ?? []].forEach((source) => {
16
+ const displaySource = cleanText(source.source) ?? UNAVAILABLE_APM_SOURCE;
17
+ const key = displaySource.toLowerCase();
18
+ const group = grouped.get(key) ?? {
19
+ source: displaySource,
20
+ operations: /* @__PURE__ */ new Map(),
21
+ hasIncompleteOperations: false
22
+ };
23
+ group.hasIncompleteOperations ||= source.hasIncompleteOperations;
24
+ source.operations.forEach((operation) => {
25
+ const normalized = normalizeOperation(operation);
26
+ if (!normalized) return;
27
+ const normalizedKey = operationKey(normalized);
28
+ const existing = group.operations.get(normalizedKey);
29
+ if (!existing || isNewer(normalized.observedAt, existing.observedAt)) {
30
+ group.operations.set(normalizedKey, normalized);
31
+ }
32
+ });
33
+ grouped.set(key, group);
34
+ });
35
+ return [...grouped.values()].map((group) => ({
36
+ source: group.source,
37
+ operations: [...group.operations.values()].sort(compareOperations),
38
+ hasIncompleteOperations: group.hasIncompleteOperations
39
+ })).sort(
40
+ (leftGroup, rightGroup) => compareText(
41
+ leftGroup.source.toLowerCase(),
42
+ rightGroup.source.toLowerCase()
43
+ )
44
+ );
45
+ };
46
+ const architectureGraphFrom = (value) => {
47
+ if (!isRecord(value)) return { nodes: [], edges: [] };
48
+ const nodes = Array.isArray(value.nodes) ? value.nodes.flatMap((node, index) => architectureNodeFrom(node, index)) : [];
49
+ const edges = Array.isArray(value.edges) ? value.edges.flatMap(architectureEdgeFrom) : [];
50
+ return { nodes, edges };
51
+ };
52
+ function architectureNodeFrom(value, index) {
53
+ if (!isRecord(value)) return [];
54
+ const id = cleanText(value.id) ?? cleanText(value.name) ?? `node-${index}`;
55
+ const name = cleanText(value.name) ?? cleanText(value.id) ?? id;
56
+ return [
57
+ {
58
+ id,
59
+ name,
60
+ type: cleanText(value.type),
61
+ namespace: cleanText(value.namespace),
62
+ image: cleanText(value.image)
63
+ }
64
+ ];
65
+ }
66
+ function architectureEdgeFrom(value) {
67
+ if (!isRecord(value)) return [];
68
+ const hasExplicitFrom = Object.prototype.hasOwnProperty.call(value, "from");
69
+ const from = hasExplicitFrom ? endpointId(value.from) : endpointId(value.source);
70
+ const to = endpointId(value.to) ?? endpointId(value.target);
71
+ if (!from || !to) return [];
72
+ const type = cleanText(value.type) ?? cleanText(value.label) ?? cleanText(value.relationship) ?? "RELATES_TO";
73
+ const synthetic = value.synthetic === true;
74
+ const edge = {
75
+ from,
76
+ to,
77
+ type,
78
+ ...synthetic ? { synthetic: true } : {}
79
+ };
80
+ const operationSource = synthetic ? null : operationSourceFrom(value, type, hasExplicitFrom);
81
+ if (operationSource) {
82
+ edge.operationSources = mergeOperationSources([operationSource], void 0);
83
+ }
84
+ return [edge];
85
+ }
86
+ function endpointId(value) {
87
+ if (typeof value === "string") return cleanText(value);
88
+ if (!isRecord(value)) return null;
89
+ return cleanText(value.id) ?? cleanText(value.name);
90
+ }
91
+ function operationSourceFrom(edge, type, hasExplicitFrom) {
92
+ if (type !== "CALLS_TO" || !Array.isArray(edge.operations)) return null;
93
+ const observedAt = usableTimestamp(edge.observedAt);
94
+ const operations = [];
95
+ let hasIncompleteOperations = false;
96
+ edge.operations.forEach((value) => {
97
+ if (!isRecord(value)) return;
98
+ if (!isOptionalText(value.method) || !isOptionalText(value.pathTemplate)) {
99
+ return;
100
+ }
101
+ const method = cleanText(value.method)?.toUpperCase() ?? null;
102
+ const pathTemplate = cleanText(value.pathTemplate) ?? null;
103
+ if (!method && !pathTemplate) {
104
+ hasIncompleteOperations = true;
105
+ return;
106
+ }
107
+ operations.push({ method, pathTemplate, observedAt });
108
+ });
109
+ if (operations.length === 0 && !hasIncompleteOperations) return null;
110
+ const source = hasExplicitFrom ? cleanText(edge.source) ?? UNAVAILABLE_APM_SOURCE : UNAVAILABLE_APM_SOURCE;
111
+ return {
112
+ source,
113
+ operations,
114
+ hasIncompleteOperations
115
+ };
116
+ }
117
+ function isOptionalText(value) {
118
+ return value === void 0 || value === null || typeof value === "string";
119
+ }
120
+ function normalizeOperation(operation) {
121
+ const method = cleanText(operation.method)?.toUpperCase() ?? null;
122
+ const pathTemplate = cleanText(operation.pathTemplate) ?? null;
123
+ if (!method && !pathTemplate) return null;
124
+ return {
125
+ method,
126
+ pathTemplate,
127
+ observedAt: usableTimestamp(operation.observedAt)
128
+ };
129
+ }
130
+ function isNewer(candidate, current) {
131
+ if (!candidate) return false;
132
+ if (!current) return true;
133
+ return Date.parse(candidate) > Date.parse(current);
134
+ }
135
+ function compareOperations(left, right) {
136
+ return compareText(operationKey(left), operationKey(right));
137
+ }
138
+ function compareText(left, right) {
139
+ if (left < right) return -1;
140
+ if (left > right) return 1;
141
+ return 0;
142
+ }
143
+
144
+ export { architectureEdgeKey, architectureGraphFrom, mergeOperationSources, uniqueOperationCount };
145
+ //# sourceMappingURL=architectureGraph.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"architectureGraph.esm.js","sources":["../../../src/components/entity/architectureGraph.ts"],"sourcesContent":["export interface ArchitectureHttpOperation {\n method: string | null;\n pathTemplate: string | null;\n observedAt: string | null;\n}\n\nexport interface ArchitectureOperationSource {\n source: string;\n operations: ArchitectureHttpOperation[];\n hasIncompleteOperations: boolean;\n}\n\nexport interface ArchitectureEdge {\n from: string;\n to: string;\n type: string;\n operationSources?: ArchitectureOperationSource[];\n synthetic?: boolean;\n}\n\nexport interface ArchitectureNode {\n id: string;\n name: string;\n type?: string | null;\n namespace?: string | null;\n image?: string | null;\n}\n\nexport interface ArchitectureGraph {\n nodes: ArchitectureNode[];\n edges: ArchitectureEdge[];\n}\n\nconst UNAVAILABLE_APM_SOURCE = 'APM source unavailable';\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst cleanText = (value: unknown): string | null =>\n typeof value === 'string' && value.trim() ? value.trim() : null;\n\nconst usableTimestamp = (value: unknown): string | null => {\n const text = cleanText(value);\n return text && !Number.isNaN(Date.parse(text)) ? text : null;\n};\n\nconst operationKey = (operation: ArchitectureHttpOperation): string =>\n `${operation.method ?? ''}\\u0000${operation.pathTemplate ?? ''}`;\n\nexport const architectureEdgeKey = (\n edge: Pick<ArchitectureEdge, 'from' | 'to' | 'type'>,\n): string => `${edge.from}\\u0000${edge.type}\\u0000${edge.to}`;\n\nexport const uniqueOperationCount = (\n sources: ArchitectureOperationSource[] | undefined,\n): number =>\n new Set(\n (sources ?? []).flatMap(source => source.operations.map(operationKey)),\n ).size;\n\nexport const mergeOperationSources = (\n left?: ArchitectureOperationSource[],\n right?: ArchitectureOperationSource[],\n): ArchitectureOperationSource[] => {\n const grouped = new Map<\n string,\n {\n source: string;\n operations: Map<string, ArchitectureHttpOperation>;\n hasIncompleteOperations: boolean;\n }\n >();\n\n [...(left ?? []), ...(right ?? [])].forEach(source => {\n const displaySource = cleanText(source.source) ?? UNAVAILABLE_APM_SOURCE;\n const key = displaySource.toLowerCase();\n const group = grouped.get(key) ?? {\n source: displaySource,\n operations: new Map(),\n hasIncompleteOperations: false,\n };\n group.hasIncompleteOperations ||= source.hasIncompleteOperations;\n\n source.operations.forEach(operation => {\n const normalized = normalizeOperation(operation);\n if (!normalized) return;\n const normalizedKey = operationKey(normalized);\n const existing = group.operations.get(normalizedKey);\n if (!existing || isNewer(normalized.observedAt, existing.observedAt)) {\n group.operations.set(normalizedKey, normalized);\n }\n });\n grouped.set(key, group);\n });\n\n return [...grouped.values()]\n .map(group => ({\n source: group.source,\n operations: [...group.operations.values()].sort(compareOperations),\n hasIncompleteOperations: group.hasIncompleteOperations,\n }))\n .sort((leftGroup, rightGroup) =>\n compareText(\n leftGroup.source.toLowerCase(),\n rightGroup.source.toLowerCase(),\n ),\n );\n};\n\nexport const architectureGraphFrom = (value: unknown): ArchitectureGraph => {\n if (!isRecord(value)) return { nodes: [], edges: [] };\n\n const nodes = Array.isArray(value.nodes)\n ? value.nodes.flatMap((node, index) => architectureNodeFrom(node, index))\n : [];\n const edges = Array.isArray(value.edges)\n ? value.edges.flatMap(architectureEdgeFrom)\n : [];\n\n return { nodes, edges };\n};\n\nfunction architectureNodeFrom(\n value: unknown,\n index: number,\n): ArchitectureNode[] {\n if (!isRecord(value)) return [];\n const id = cleanText(value.id) ?? cleanText(value.name) ?? `node-${index}`;\n const name = cleanText(value.name) ?? cleanText(value.id) ?? id;\n return [\n {\n id,\n name,\n type: cleanText(value.type),\n namespace: cleanText(value.namespace),\n image: cleanText(value.image),\n },\n ];\n}\n\nfunction architectureEdgeFrom(value: unknown): ArchitectureEdge[] {\n if (!isRecord(value)) return [];\n\n const hasExplicitFrom = Object.prototype.hasOwnProperty.call(value, 'from');\n const from = hasExplicitFrom\n ? endpointId(value.from)\n : endpointId(value.source);\n const to = endpointId(value.to) ?? endpointId(value.target);\n if (!from || !to) return [];\n\n const type =\n cleanText(value.type) ??\n cleanText(value.label) ??\n cleanText(value.relationship) ??\n 'RELATES_TO';\n const synthetic = value.synthetic === true;\n const edge: ArchitectureEdge = {\n from,\n to,\n type,\n ...(synthetic ? { synthetic: true } : {}),\n };\n const operationSource = synthetic\n ? null\n : operationSourceFrom(value, type, hasExplicitFrom);\n if (operationSource) {\n edge.operationSources = mergeOperationSources([operationSource], undefined);\n }\n return [edge];\n}\n\nfunction endpointId(value: unknown): string | null {\n if (typeof value === 'string') return cleanText(value);\n if (!isRecord(value)) return null;\n return cleanText(value.id) ?? cleanText(value.name);\n}\n\nfunction operationSourceFrom(\n edge: Record<string, unknown>,\n type: string,\n hasExplicitFrom: boolean,\n): ArchitectureOperationSource | null {\n if (type !== 'CALLS_TO' || !Array.isArray(edge.operations)) return null;\n\n const observedAt = usableTimestamp(edge.observedAt);\n const operations: ArchitectureHttpOperation[] = [];\n let hasIncompleteOperations = false;\n edge.operations.forEach(value => {\n if (!isRecord(value)) return;\n if (!isOptionalText(value.method) || !isOptionalText(value.pathTemplate)) {\n return;\n }\n const method = cleanText(value.method)?.toUpperCase() ?? null;\n const pathTemplate = cleanText(value.pathTemplate) ?? null;\n if (!method && !pathTemplate) {\n hasIncompleteOperations = true;\n return;\n }\n operations.push({ method, pathTemplate, observedAt });\n });\n\n if (operations.length === 0 && !hasIncompleteOperations) return null;\n const source = hasExplicitFrom\n ? cleanText(edge.source) ?? UNAVAILABLE_APM_SOURCE\n : UNAVAILABLE_APM_SOURCE;\n return {\n source,\n operations,\n hasIncompleteOperations,\n };\n}\n\nfunction isOptionalText(value: unknown): value is string | null | undefined {\n return value === undefined || value === null || typeof value === 'string';\n}\n\nfunction normalizeOperation(\n operation: ArchitectureHttpOperation,\n): ArchitectureHttpOperation | null {\n const method = cleanText(operation.method)?.toUpperCase() ?? null;\n const pathTemplate = cleanText(operation.pathTemplate) ?? null;\n if (!method && !pathTemplate) return null;\n return {\n method,\n pathTemplate,\n observedAt: usableTimestamp(operation.observedAt),\n };\n}\n\nfunction isNewer(candidate: string | null, current: string | null): boolean {\n if (!candidate) return false;\n if (!current) return true;\n return Date.parse(candidate) > Date.parse(current);\n}\n\nfunction compareOperations(\n left: ArchitectureHttpOperation,\n right: ArchitectureHttpOperation,\n): number {\n return compareText(operationKey(left), operationKey(right));\n}\n\nfunction compareText(left: string, right: string): number {\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  var name = "@anyshift/backstage-plugin-anyshift";
2
- var version = "0.1.0-beta.12";
2
+ var version = "0.1.0-beta.14";
3
3
  var description = "Read-only Anyshift infrastructure context for Backstage";
4
4
  var main = "src/index.ts";
5
5
  var types = "src/index.ts";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anyshift/backstage-plugin-anyshift",
3
- "version": "0.1.0-beta.12",
3
+ "version": "0.1.0-beta.14",
4
4
  "description": "Read-only Anyshift infrastructure context for Backstage",
5
5
  "main": "dist/index.esm.js",
6
6
  "types": "dist/index.d.ts",
@@ -45,7 +45,7 @@
45
45
  "clean": "backstage-cli package clean"
46
46
  },
47
47
  "dependencies": {
48
- "@anyshift/backstage-plugin-anyshift-common": "^0.1.0-beta.12",
48
+ "@anyshift/backstage-plugin-anyshift-common": "^0.1.0-beta.13",
49
49
  "@backstage/catalog-model": "^1.9.0",
50
50
  "@backstage/core-components": "^0.18.11",
51
51
  "@backstage/frontend-plugin-api": "^0.17.2",