@anyshift/backstage-plugin-anyshift 0.1.0-beta.20 → 0.1.0-beta.21

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 (49) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +3 -11
  3. package/dist/api/AnyshiftApi.esm.js +5 -56
  4. package/dist/api/AnyshiftApi.esm.js.map +1 -1
  5. package/dist/components/cloud/CloudResourceContent.esm.js +45 -444
  6. package/dist/components/cloud/CloudResourceContent.esm.js.map +1 -1
  7. package/dist/components/entity/AnyshiftEntityContent.esm.js +23 -128
  8. package/dist/components/entity/AnyshiftEntityContent.esm.js.map +1 -1
  9. package/dist/components/entity/BriefSections.esm.js +4 -24
  10. package/dist/components/entity/BriefSections.esm.js.map +1 -1
  11. package/dist/components/entity/DatadogLiveSignal.esm.js +23 -85
  12. package/dist/components/entity/DatadogLiveSignal.esm.js.map +1 -1
  13. package/dist/components/entity/MermaidArchitecture.esm.js +43 -202
  14. package/dist/components/entity/MermaidArchitecture.esm.js.map +1 -1
  15. package/dist/components/entity/SectionPresenters.esm.js +82 -145
  16. package/dist/components/entity/SectionPresenters.esm.js.map +1 -1
  17. package/dist/components/entity/architectureDiagram.esm.js +15 -48
  18. package/dist/components/entity/architectureDiagram.esm.js.map +1 -1
  19. package/dist/components/explorer/AnyshiftExplorerPage.esm.js +19 -154
  20. package/dist/components/explorer/AnyshiftExplorerPage.esm.js.map +1 -1
  21. package/dist/components/explorer/DatadogOperationsRadar.esm.js +31 -92
  22. package/dist/components/explorer/DatadogOperationsRadar.esm.js.map +1 -1
  23. package/dist/index.d.ts +4 -18
  24. package/dist/index.esm.js +1 -1
  25. package/dist/package.json.esm.js +13 -13
  26. package/dist/plugin.esm.js +2 -6
  27. package/dist/plugin.esm.js.map +1 -1
  28. package/package.json +15 -15
  29. package/CHANGELOG.md +0 -87
  30. package/dist/components/ask/AskAnyshiftCard.esm.js +0 -348
  31. package/dist/components/ask/AskAnyshiftCard.esm.js.map +0 -1
  32. package/dist/components/ask/askPresenters.esm.js +0 -1203
  33. package/dist/components/ask/askPresenters.esm.js.map +0 -1
  34. package/dist/components/ask/askScope.esm.js +0 -27
  35. package/dist/components/ask/askScope.esm.js.map +0 -1
  36. package/dist/components/ask/askSuggestions.esm.js +0 -41
  37. package/dist/components/ask/askSuggestions.esm.js.map +0 -1
  38. package/dist/components/cloud/CloudImpactSection.esm.js +0 -54
  39. package/dist/components/cloud/CloudImpactSection.esm.js.map +0 -1
  40. package/dist/components/cloud/CloudRelationshipSections.esm.js +0 -43
  41. package/dist/components/cloud/CloudRelationshipSections.esm.js.map +0 -1
  42. package/dist/components/entity/ArchitectureOperationDetails.esm.js +0 -107
  43. package/dist/components/entity/ArchitectureOperationDetails.esm.js.map +0 -1
  44. package/dist/components/entity/architectureGraph.esm.js +0 -145
  45. package/dist/components/entity/architectureGraph.esm.js.map +0 -1
  46. package/dist/components/entity/entityIdentity.esm.js +0 -40
  47. package/dist/components/entity/entityIdentity.esm.js.map +0 -1
  48. package/dist/components/entity/relatedCatalogEntities.esm.js +0 -60
  49. package/dist/components/entity/relatedCatalogEntities.esm.js.map +0 -1
@@ -1,145 +0,0 @@
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
@@ -1 +0,0 @@
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":"AAiCA,MAAM,sBAAA,GAAyB,wBAAA;AAE/B,MAAM,QAAA,GAAW,CAAC,KAAA,KAChB,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA;AAErE,MAAM,SAAA,GAAY,CAAC,KAAA,KACjB,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,IAAA,EAAK,GAAI,KAAA,CAAM,IAAA,EAAK,GAAI,IAAA;AAE7D,MAAM,eAAA,GAAkB,CAAC,KAAA,KAAkC;AACzD,EAAA,MAAM,IAAA,GAAO,UAAU,KAAK,CAAA;AAC5B,EAAA,OAAO,IAAA,IAAQ,CAAC,MAAA,CAAO,KAAA,CAAM,KAAK,KAAA,CAAM,IAAI,CAAC,CAAA,GAAI,IAAA,GAAO,IAAA;AAC1D,CAAA;AAEA,MAAM,YAAA,GAAe,CAAC,SAAA,KACpB,CAAA,EAAG,SAAA,CAAU,UAAU,EAAE,CAAA,EAAA,EAAS,SAAA,CAAU,YAAA,IAAgB,EAAE,CAAA,CAAA;AAEzD,MAAM,mBAAA,GAAsB,CACjC,IAAA,KACW,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,EAAS,IAAA,CAAK,IAAI,CAAA,EAAA,EAAS,IAAA,CAAK,EAAE,CAAA;AAEpD,MAAM,oBAAA,GAAuB,CAClC,OAAA,KAEA,IAAI,GAAA;AAAA,EAAA,CACD,OAAA,IAAW,EAAC,EAAG,OAAA,CAAQ,YAAU,MAAA,CAAO,UAAA,CAAW,GAAA,CAAI,YAAY,CAAC;AACvE,CAAA,CAAE;AAEG,MAAM,qBAAA,GAAwB,CACnC,IAAA,EACA,KAAA,KACkC;AAClC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAOlB;AAEF,EAAA,CAAC,GAAI,IAAA,IAAQ,EAAC,EAAI,GAAI,SAAS,EAAG,CAAA,CAAE,OAAA,CAAQ,CAAA,MAAA,KAAU;AACpD,IAAA,MAAM,aAAA,GAAgB,SAAA,CAAU,MAAA,CAAO,MAAM,CAAA,IAAK,sBAAA;AAClD,IAAA,MAAM,GAAA,GAAM,cAAc,WAAA,EAAY;AACtC,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA,IAAK;AAAA,MAChC,MAAA,EAAQ,aAAA;AAAA,MACR,UAAA,sBAAgB,GAAA,EAAI;AAAA,MACpB,uBAAA,EAAyB;AAAA,KAC3B;AACA,IAAA,KAAA,CAAM,4BAA4B,MAAA,CAAO,uBAAA;AAEzC,IAAA,MAAA,CAAO,UAAA,CAAW,QAAQ,CAAA,SAAA,KAAa;AACrC,MAAA,MAAM,UAAA,GAAa,mBAAmB,SAAS,CAAA;AAC/C,MAAA,IAAI,CAAC,UAAA,EAAY;AACjB,MAAA,MAAM,aAAA,GAAgB,aAAa,UAAU,CAAA;AAC7C,MAAA,MAAM,QAAA,GAAW,KAAA,CAAM,UAAA,CAAW,GAAA,CAAI,aAAa,CAAA;AACnD,MAAA,IAAI,CAAC,QAAA,IAAY,OAAA,CAAQ,WAAW,UAAA,EAAY,QAAA,CAAS,UAAU,CAAA,EAAG;AACpE,QAAA,KAAA,CAAM,UAAA,CAAW,GAAA,CAAI,aAAA,EAAe,UAAU,CAAA;AAAA,MAChD;AAAA,IACF,CAAC,CAAA;AACD,IAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,EACxB,CAAC,CAAA;AAED,EAAA,OAAO,CAAC,GAAG,OAAA,CAAQ,QAAQ,CAAA,CACxB,IAAI,CAAA,KAAA,MAAU;AAAA,IACb,QAAQ,KAAA,CAAM,MAAA;AAAA,IACd,UAAA,EAAY,CAAC,GAAG,KAAA,CAAM,WAAW,MAAA,EAAQ,CAAA,CAAE,IAAA,CAAK,iBAAiB,CAAA;AAAA,IACjE,yBAAyB,KAAA,CAAM;AAAA,IAC/B,CAAA,CACD,IAAA;AAAA,IAAK,CAAC,WAAW,UAAA,KAChB,WAAA;AAAA,MACE,SAAA,CAAU,OAAO,WAAA,EAAY;AAAA,MAC7B,UAAA,CAAW,OAAO,WAAA;AAAY;AAChC,GACF;AACJ;AAEO,MAAM,qBAAA,GAAwB,CAAC,KAAA,KAAsC;AAC1E,EAAA,IAAI,CAAC,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,EAAE,KAAA,EAAO,EAAC,EAAG,KAAA,EAAO,EAAC,EAAE;AAEpD,EAAA,MAAM,QAAQ,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,KAAK,IACnC,KAAA,CAAM,KAAA,CAAM,OAAA,CAAQ,CAAC,MAAM,KAAA,KAAU,oBAAA,CAAqB,MAAM,KAAK,CAAC,IACtE,EAAC;AACL,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,GACnC,KAAA,CAAM,KAAA,CAAM,OAAA,CAAQ,oBAAoB,CAAA,GACxC,EAAC;AAEL,EAAA,OAAO,EAAE,OAAO,KAAA,EAAM;AACxB;AAEA,SAAS,oBAAA,CACP,OACA,KAAA,EACoB;AACpB,EAAA,IAAI,CAAC,QAAA,CAAS,KAAK,CAAA,SAAU,EAAC;AAC9B,EAAA,MAAM,EAAA,GAAK,SAAA,CAAU,KAAA,CAAM,EAAE,CAAA,IAAK,UAAU,KAAA,CAAM,IAAI,CAAA,IAAK,CAAA,KAAA,EAAQ,KAAK,CAAA,CAAA;AACxE,EAAA,MAAM,IAAA,GAAO,UAAU,KAAA,CAAM,IAAI,KAAK,SAAA,CAAU,KAAA,CAAM,EAAE,CAAA,IAAK,EAAA;AAC7D,EAAA,OAAO;AAAA,IACL;AAAA,MACE,EAAA;AAAA,MACA,IAAA;AAAA,MACA,IAAA,EAAM,SAAA,CAAU,KAAA,CAAM,IAAI,CAAA;AAAA,MAC1B,SAAA,EAAW,SAAA,CAAU,KAAA,CAAM,SAAS,CAAA;AAAA,MACpC,KAAA,EAAO,SAAA,CAAU,KAAA,CAAM,KAAK;AAAA;AAC9B,GACF;AACF;AAEA,SAAS,qBAAqB,KAAA,EAAoC;AAChE,EAAA,IAAI,CAAC,QAAA,CAAS,KAAK,CAAA,SAAU,EAAC;AAE9B,EAAA,MAAM,kBAAkB,MAAA,CAAO,SAAA,CAAU,cAAA,CAAe,IAAA,CAAK,OAAO,MAAM,CAAA;AAC1E,EAAA,MAAM,IAAA,GAAO,kBACT,UAAA,CAAW,KAAA,CAAM,IAAI,CAAA,GACrB,UAAA,CAAW,MAAM,MAAM,CAAA;AAC3B,EAAA,MAAM,KAAK,UAAA,CAAW,KAAA,CAAM,EAAE,CAAA,IAAK,UAAA,CAAW,MAAM,MAAM,CAAA;AAC1D,EAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,EAAA,SAAW,EAAC;AAE1B,EAAA,MAAM,IAAA,GACJ,SAAA,CAAU,KAAA,CAAM,IAAI,CAAA,IACpB,SAAA,CAAU,KAAA,CAAM,KAAK,CAAA,IACrB,SAAA,CAAU,KAAA,CAAM,YAAY,CAAA,IAC5B,YAAA;AACF,EAAA,MAAM,SAAA,GAAY,MAAM,SAAA,KAAc,IAAA;AACtC,EAAA,MAAM,IAAA,GAAyB;AAAA,IAC7B,IAAA;AAAA,IACA,EAAA;AAAA,IACA,IAAA;AAAA,IACA,GAAI,SAAA,GAAY,EAAE,SAAA,EAAW,IAAA,KAAS;AAAC,GACzC;AACA,EAAA,MAAM,kBAAkB,SAAA,GACpB,IAAA,GACA,mBAAA,CAAoB,KAAA,EAAO,MAAM,eAAe,CAAA;AACpD,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,IAAA,CAAK,gBAAA,GAAmB,qBAAA,CAAsB,CAAC,eAAe,GAAG,MAAS,CAAA;AAAA,EAC5E;AACA,EAAA,OAAO,CAAC,IAAI,CAAA;AACd;AAEA,SAAS,WAAW,KAAA,EAA+B;AACjD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,UAAU,KAAK,CAAA;AACrD,EAAA,IAAI,CAAC,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,IAAA;AAC7B,EAAA,OAAO,UAAU,KAAA,CAAM,EAAE,CAAA,IAAK,SAAA,CAAU,MAAM,IAAI,CAAA;AACpD;AAEA,SAAS,mBAAA,CACP,IAAA,EACA,IAAA,EACA,eAAA,EACoC;AACpC,EAAA,IAAI,IAAA,KAAS,cAAc,CAAC,KAAA,CAAM,QAAQ,IAAA,CAAK,UAAU,GAAG,OAAO,IAAA;AAEnE,EAAA,MAAM,UAAA,GAAa,eAAA,CAAgB,IAAA,CAAK,UAAU,CAAA;AAClD,EAAA,MAAM,aAA0C,EAAC;AACjD,EAAA,IAAI,uBAAA,GAA0B,KAAA;AAC9B,EAAA,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAA,KAAA,KAAS;AAC/B,IAAA,IAAI,CAAC,QAAA,CAAS,KAAK,CAAA,EAAG;AACtB,IAAA,IAAI,CAAC,eAAe,KAAA,CAAM,MAAM,KAAK,CAAC,cAAA,CAAe,KAAA,CAAM,YAAY,CAAA,EAAG;AACxE,MAAA;AAAA,IACF;AACA,IAAA,MAAM,SAAS,SAAA,CAAU,KAAA,CAAM,MAAM,CAAA,EAAG,aAAY,IAAK,IAAA;AACzD,IAAA,MAAM,YAAA,GAAe,SAAA,CAAU,KAAA,CAAM,YAAY,CAAA,IAAK,IAAA;AACtD,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,YAAA,EAAc;AAC5B,MAAA,uBAAA,GAA0B,IAAA;AAC1B,MAAA;AAAA,IACF;AACA,IAAA,UAAA,CAAW,IAAA,CAAK,EAAE,MAAA,EAAQ,YAAA,EAAc,YAAY,CAAA;AAAA,EACtD,CAAC,CAAA;AAED,EAAA,IAAI,UAAA,CAAW,MAAA,KAAW,CAAA,IAAK,CAAC,yBAAyB,OAAO,IAAA;AAChE,EAAA,MAAM,SAAS,eAAA,GACX,SAAA,CAAU,IAAA,CAAK,MAAM,KAAK,sBAAA,GAC1B,sBAAA;AACJ,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AACF;AAEA,SAAS,eAAe,KAAA,EAAoD;AAC1E,EAAA,OAAO,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA;AACnE;AAEA,SAAS,mBACP,SAAA,EACkC;AAClC,EAAA,MAAM,SAAS,SAAA,CAAU,SAAA,CAAU,MAAM,CAAA,EAAG,aAAY,IAAK,IAAA;AAC7D,EAAA,MAAM,YAAA,GAAe,SAAA,CAAU,SAAA,CAAU,YAAY,CAAA,IAAK,IAAA;AAC1D,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,YAAA,EAAc,OAAO,IAAA;AACrC,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA,EAAY,eAAA,CAAgB,SAAA,CAAU,UAAU;AAAA,GAClD;AACF;AAEA,SAAS,OAAA,CAAQ,WAA0B,OAAA,EAAiC;AAC1E,EAAA,IAAI,CAAC,WAAW,OAAO,KAAA;AACvB,EAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AACrB,EAAA,OAAO,KAAK,KAAA,CAAM,SAAS,CAAA,GAAI,IAAA,CAAK,MAAM,OAAO,CAAA;AACnD;AAEA,SAAS,iBAAA,CACP,MACA,KAAA,EACQ;AACR,EAAA,OAAO,YAAY,YAAA,CAAa,IAAI,CAAA,EAAG,YAAA,CAAa,KAAK,CAAC,CAAA;AAC5D;AAEA,SAAS,WAAA,CAAY,MAAc,KAAA,EAAuB;AACxD,EAAA,IAAI,IAAA,GAAO,OAAO,OAAO,EAAA;AACzB,EAAA,IAAI,IAAA,GAAO,OAAO,OAAO,CAAA;AACzB,EAAA,OAAO,CAAA;AACT;;;;"}
@@ -1,40 +0,0 @@
1
- import { ANYSHIFT_CLOUD_PROVIDER_ANNOTATION, ANYSHIFT_RESOURCE_ID_ANNOTATION, ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION, ANYSHIFT_TARGET_ANNOTATION, GITHUB_PROJECT_SLUG_ANNOTATION } from '@anyshift/backstage-plugin-anyshift-common';
2
-
3
- function isCloudResourceEntity(entity) {
4
- return entity.kind.toLocaleLowerCase("en-US") === "resource" && Boolean(
5
- entity.metadata.annotations?.[ANYSHIFT_CLOUD_PROVIDER_ANNOTATION]?.trim()
6
- );
7
- }
8
- function cloudResourceIdentity(entity) {
9
- const annotations = entity.metadata.annotations ?? {};
10
- return annotationValue(annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION]) ?? annotationValue(annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION]);
11
- }
12
- function cloudResourceFallbackIdentity(entity) {
13
- const annotations = entity.metadata.annotations ?? {};
14
- const resourceId = annotationValue(
15
- annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION]
16
- );
17
- const arn = annotationValue(
18
- annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION]
19
- );
20
- return arn && arn !== resourceId ? arn : void 0;
21
- }
22
- function cloudResourceAskTarget(entity) {
23
- const annotations = entity.metadata.annotations ?? {};
24
- return annotationValue(annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION]) ?? annotationValue(annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION]);
25
- }
26
- function entityTarget(entity) {
27
- const annotations = entity.metadata.annotations ?? {};
28
- const explicit = annotationValue(annotations[ANYSHIFT_TARGET_ANNOTATION]);
29
- if (explicit) return explicit;
30
- const slug = annotationValue(annotations[GITHUB_PROJECT_SLUG_ANNOTATION]);
31
- const repository = slug?.split("/").filter(Boolean).at(-1);
32
- return repository || entity.metadata.name;
33
- }
34
- function annotationValue(value) {
35
- const trimmed = value?.trim();
36
- return trimmed || void 0;
37
- }
38
-
39
- export { cloudResourceAskTarget, cloudResourceFallbackIdentity, cloudResourceIdentity, entityTarget, isCloudResourceEntity };
40
- //# sourceMappingURL=entityIdentity.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entityIdentity.esm.js","sources":["../../../src/components/entity/entityIdentity.ts"],"sourcesContent":["import type { Entity } from '@backstage/catalog-model';\nimport {\n ANYSHIFT_CLOUD_PROVIDER_ANNOTATION,\n ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION,\n ANYSHIFT_RESOURCE_ID_ANNOTATION,\n ANYSHIFT_TARGET_ANNOTATION,\n GITHUB_PROJECT_SLUG_ANNOTATION,\n} from '@anyshift/backstage-plugin-anyshift-common';\n\nexport function isCloudResourceEntity(entity: Entity): boolean {\n return (\n entity.kind.toLocaleLowerCase('en-US') === 'resource' &&\n Boolean(\n entity.metadata.annotations?.[ANYSHIFT_CLOUD_PROVIDER_ANNOTATION]?.trim(),\n )\n );\n}\n\nexport function cloudResourceIdentity(entity: Entity): string | undefined {\n const annotations = entity.metadata.annotations ?? {};\n return (\n annotationValue(annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION]) ??\n annotationValue(annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION])\n );\n}\n\nexport function cloudResourceFallbackIdentity(\n entity: Entity,\n): string | undefined {\n const annotations = entity.metadata.annotations ?? {};\n const resourceId = annotationValue(\n annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION],\n );\n const arn = annotationValue(\n annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION],\n );\n return arn && arn !== resourceId ? arn : undefined;\n}\n\nexport function cloudResourceAskTarget(entity: Entity): string | undefined {\n const annotations = entity.metadata.annotations ?? {};\n return (\n annotationValue(annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION]) ??\n annotationValue(annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION])\n );\n}\n\nexport function entityTarget(entity: Entity): string {\n const annotations = entity.metadata.annotations ?? {};\n const explicit = annotationValue(annotations[ANYSHIFT_TARGET_ANNOTATION]);\n if (explicit) return explicit;\n\n const slug = annotationValue(annotations[GITHUB_PROJECT_SLUG_ANNOTATION]);\n const repository = slug?.split('/').filter(Boolean).at(-1);\n return repository || entity.metadata.name;\n}\n\nfunction annotationValue(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed || undefined;\n}\n"],"names":[],"mappings":";;AASO,SAAS,sBAAsB,MAAA,EAAyB;AAC7D,EAAA,OACE,MAAA,CAAO,IAAA,CAAK,iBAAA,CAAkB,OAAO,MAAM,UAAA,IAC3C,OAAA;AAAA,IACE,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,kCAAkC,GAAG,IAAA;AAAK,GAC1E;AAEJ;AAEO,SAAS,sBAAsB,MAAA,EAAoC;AACxE,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,OACE,eAAA,CAAgB,YAAY,+BAA+B,CAAC,KAC5D,eAAA,CAAgB,WAAA,CAAY,sCAAsC,CAAC,CAAA;AAEvE;AAEO,SAAS,8BACd,MAAA,EACoB;AACpB,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,MAAM,UAAA,GAAa,eAAA;AAAA,IACjB,YAAY,+BAA+B;AAAA,GAC7C;AACA,EAAA,MAAM,GAAA,GAAM,eAAA;AAAA,IACV,YAAY,sCAAsC;AAAA,GACpD;AACA,EAAA,OAAO,GAAA,IAAO,GAAA,KAAQ,UAAA,GAAa,GAAA,GAAM,MAAA;AAC3C;AAEO,SAAS,uBAAuB,MAAA,EAAoC;AACzE,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,OACE,eAAA,CAAgB,YAAY,sCAAsC,CAAC,KACnE,eAAA,CAAgB,WAAA,CAAY,+BAA+B,CAAC,CAAA;AAEhE;AAEO,SAAS,aAAa,MAAA,EAAwB;AACnD,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,MAAM,QAAA,GAAW,eAAA,CAAgB,WAAA,CAAY,0BAA0B,CAAC,CAAA;AACxE,EAAA,IAAI,UAAU,OAAO,QAAA;AAErB,EAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,WAAA,CAAY,8BAA8B,CAAC,CAAA;AACxE,EAAA,MAAM,UAAA,GAAa,MAAM,KAAA,CAAM,GAAG,EAAE,MAAA,CAAO,OAAO,CAAA,CAAE,EAAA,CAAG,EAAE,CAAA;AACzD,EAAA,OAAO,UAAA,IAAc,OAAO,QAAA,CAAS,IAAA;AACvC;AAEA,SAAS,gBAAgB,KAAA,EAA+C;AACtE,EAAA,MAAM,OAAA,GAAU,OAAO,IAAA,EAAK;AAC5B,EAAA,OAAO,OAAA,IAAW,MAAA;AACpB;;;;"}
@@ -1,60 +0,0 @@
1
- import { stringifyEntityRef, parseEntityRef } from '@backstage/catalog-model';
2
-
3
- const normalizeEntityName = (value) => value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 63).replace(/-+$/g, "");
4
- const canonicalEntityRef = (value) => {
5
- try {
6
- return stringifyEntityRef(parseEntityRef(value));
7
- } catch {
8
- return void 0;
9
- }
10
- };
11
- const addCandidate = (index, name, entityRef) => {
12
- const key = normalizeEntityName(name);
13
- if (!key) return;
14
- const refs = index.get(key) ?? [];
15
- if (!refs.includes(entityRef)) refs.push(entityRef);
16
- index.set(key, refs);
17
- };
18
- const resolveRelatedCatalogEntities = (relatedEntities, catalogEntities) => {
19
- const catalogRefs = /* @__PURE__ */ new Set();
20
- const componentsByName = /* @__PURE__ */ new Map();
21
- const resourcesByName = /* @__PURE__ */ new Map();
22
- for (const entity of catalogEntities) {
23
- const kind = entity.kind.toLowerCase();
24
- if (kind !== "component" && kind !== "resource") continue;
25
- const entityRef = stringifyEntityRef(entity);
26
- catalogRefs.add(entityRef);
27
- addCandidate(
28
- kind === "component" ? componentsByName : resourcesByName,
29
- entity.metadata.name,
30
- entityRef
31
- );
32
- }
33
- const seenNames = /* @__PURE__ */ new Set();
34
- const resolved = [];
35
- for (const related of relatedEntities) {
36
- const logicalName = normalizeEntityName(related.name);
37
- if (seenNames.has(logicalName)) continue;
38
- seenNames.add(logicalName);
39
- const legacyRef = related.entityRef ? canonicalEntityRef(related.entityRef) : void 0;
40
- let entityRef = legacyRef && catalogRefs.has(legacyRef) ? legacyRef : void 0;
41
- if (!entityRef) {
42
- const componentMatches = componentsByName.get(logicalName) ?? [];
43
- if (componentMatches.length === 1) {
44
- [entityRef] = componentMatches;
45
- } else if (componentMatches.length === 0) {
46
- const resourceMatches = resourcesByName.get(logicalName) ?? [];
47
- if (resourceMatches.length === 1) [entityRef] = resourceMatches;
48
- }
49
- }
50
- resolved.push({
51
- name: related.name,
52
- category: related.category,
53
- ...entityRef ? { entityRef } : {}
54
- });
55
- }
56
- return resolved;
57
- };
58
-
59
- export { resolveRelatedCatalogEntities };
60
- //# sourceMappingURL=relatedCatalogEntities.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"relatedCatalogEntities.esm.js","sources":["../../../src/components/entity/relatedCatalogEntities.ts"],"sourcesContent":["import {\n parseEntityRef,\n stringifyEntityRef,\n type Entity,\n} from '@backstage/catalog-model';\nimport type { EntityImpactRelatedEntity } from '../../api/types';\n\nconst normalizeEntityName = (value: string): string =>\n value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 63)\n .replace(/-+$/g, '');\n\nconst canonicalEntityRef = (value: string): string | undefined => {\n try {\n return stringifyEntityRef(parseEntityRef(value));\n } catch {\n return undefined;\n }\n};\n\nconst addCandidate = (\n index: Map<string, string[]>,\n name: string,\n entityRef: string,\n) => {\n const key = normalizeEntityName(name);\n if (!key) return;\n const refs = index.get(key) ?? [];\n if (!refs.includes(entityRef)) refs.push(entityRef);\n index.set(key, refs);\n};\n\nexport const resolveRelatedCatalogEntities = (\n relatedEntities: EntityImpactRelatedEntity[],\n catalogEntities: Entity[],\n): EntityImpactRelatedEntity[] => {\n const catalogRefs = new Set<string>();\n const componentsByName = new Map<string, string[]>();\n const resourcesByName = new Map<string, string[]>();\n\n for (const entity of catalogEntities) {\n const kind = entity.kind.toLowerCase();\n if (kind !== 'component' && kind !== 'resource') continue;\n const entityRef = stringifyEntityRef(entity);\n catalogRefs.add(entityRef);\n addCandidate(\n kind === 'component' ? componentsByName : resourcesByName,\n entity.metadata.name,\n entityRef,\n );\n }\n\n const seenNames = new Set<string>();\n const resolved: EntityImpactRelatedEntity[] = [];\n\n for (const related of relatedEntities) {\n const logicalName = normalizeEntityName(related.name);\n if (seenNames.has(logicalName)) continue;\n seenNames.add(logicalName);\n\n const legacyRef = related.entityRef\n ? canonicalEntityRef(related.entityRef)\n : undefined;\n let entityRef =\n legacyRef && catalogRefs.has(legacyRef) ? legacyRef : undefined;\n\n if (!entityRef) {\n const componentMatches = componentsByName.get(logicalName) ?? [];\n if (componentMatches.length === 1) {\n [entityRef] = componentMatches;\n } else if (componentMatches.length === 0) {\n const resourceMatches = resourcesByName.get(logicalName) ?? [];\n if (resourceMatches.length === 1) [entityRef] = resourceMatches;\n }\n }\n\n resolved.push({\n name: related.name,\n category: related.category,\n ...(entityRef ? { entityRef } : {}),\n });\n }\n\n return resolved;\n};\n"],"names":[],"mappings":"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"}