@anyshift/backstage-plugin-anyshift 0.1.0-beta.15 → 0.1.0-beta.16

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/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.1.0-beta.16
6
+
7
+ - Retry unresolved cloud-change evidence with the provider-native ARN while keeping the stable
8
+ catalog identity and existing entity URLs unchanged.
9
+
5
10
  ## 0.1.0-beta.15
6
11
 
7
12
  - Resolve Affected footprint entries against one Backstage catalog snapshot and link only entities
@@ -54,6 +54,8 @@ class AnyshiftClient {
54
54
  }
55
55
  async cloudResourceBrief(resource, options = {}) {
56
56
  const params = new URLSearchParams({ resource });
57
+ if (options.fallbackResource)
58
+ params.set("fallbackResource", options.fallbackResource);
57
59
  if (options.since) params.set("since", options.since);
58
60
  if (options.cursor) params.set("cursor", options.cursor);
59
61
  if (options.diff !== void 0) params.set("diff", String(options.diff));
@@ -1 +1 @@
1
- {"version":3,"file":"AnyshiftApi.esm.js","sources":["../../src/api/AnyshiftApi.ts"],"sourcesContent":["import {\n createApiRef,\n type DiscoveryApi,\n type FetchApi,\n} from '@backstage/frontend-plugin-api';\nimport type {\n BriefSectionName,\n BriefSectionResponse,\n AnyshiftCapabilities,\n AskAnyshiftRequest,\n AskAnyshiftResponse,\n CatalogSummary,\n CatalogSyncReport,\n CloudResourceBrief,\n DatadogSignals,\n EstateInsights,\n QueryResult,\n ServiceBrief,\n} from './types';\n\nexport interface AnyshiftApi {\n ask(request: AskAnyshiftRequest): Promise<AskAnyshiftResponse>;\n capabilities(): Promise<AnyshiftCapabilities>;\n brief(\n kind: string,\n target: string,\n options?: BriefRequestOptions,\n ): Promise<ServiceBrief>;\n briefSection(\n kind: string,\n target: string,\n section: BriefSectionName,\n options?: BriefRequestOptions,\n ): Promise<BriefSectionResponse>;\n insights(options?: { refresh?: boolean }): Promise<EstateInsights>;\n datadogSignals(options?: { refresh?: boolean }): Promise<DatadogSignals>;\n cloudResourceBrief(\n resource: string,\n options?: CloudResourceBriefRequestOptions,\n ): Promise<CloudResourceBrief>;\n inventory(\n type: string,\n options?: { limit?: number; offset?: number },\n ): Promise<CatalogSummary>;\n query(sql: string): Promise<QueryResult>;\n reconcileCatalog(): Promise<CatalogSyncAccepted>;\n}\n\nexport interface BriefRequestOptions {\n namespace?: string;\n refresh?: boolean;\n configurationEndpoints?: string;\n configurationDependencies?: string;\n configurationTarget?: string;\n}\n\nexport interface CloudResourceBriefRequestOptions {\n since?: string;\n cursor?: string;\n diff?: boolean;\n refresh?: boolean;\n}\n\nexport interface CatalogSyncAccepted {\n accepted: true;\n acceptedAt: string;\n previous?: CatalogSyncReport;\n}\n\nexport const anyshiftApiRef = createApiRef<AnyshiftApi>({\n id: 'plugin.anyshift.service',\n});\n\nexport class AnyshiftRequestError extends Error {\n constructor(\n readonly status: number,\n readonly code: string,\n message: string,\n readonly retryAfterSeconds?: number,\n ) {\n super(message);\n this.name = 'AnyshiftRequestError';\n }\n}\n\nexport class AnyshiftClient implements AnyshiftApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: { discoveryApi: DiscoveryApi; fetchApi: FetchApi }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi;\n }\n\n async ask(request: AskAnyshiftRequest): Promise<AskAnyshiftResponse> {\n return this.request('/ask', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(request),\n });\n }\n\n async capabilities(): Promise<AnyshiftCapabilities> {\n return this.get('/capabilities');\n }\n\n async brief(\n kind: string,\n target: string,\n options: BriefRequestOptions = {},\n ): Promise<ServiceBrief> {\n return this.get(\n `/brief/${encodeURIComponent(kind)}/${encodeURIComponent(\n target,\n )}${briefQuery(options)}`,\n );\n }\n\n async briefSection(\n kind: string,\n target: string,\n section: BriefSectionName,\n options: BriefRequestOptions = {},\n ): Promise<BriefSectionResponse> {\n return this.get(\n `/brief/${encodeURIComponent(kind)}/${encodeURIComponent(\n target,\n )}/sections/${encodeURIComponent(section)}${briefQuery(options)}`,\n );\n }\n\n async insights(options: { refresh?: boolean } = {}): Promise<EstateInsights> {\n return this.get(`/insights${options.refresh ? '?refresh=1' : ''}`);\n }\n\n async datadogSignals(\n options: { refresh?: boolean } = {},\n ): Promise<DatadogSignals> {\n return this.get(`/signals/datadog${options.refresh ? '?refresh=1' : ''}`);\n }\n\n async cloudResourceBrief(\n resource: string,\n options: CloudResourceBriefRequestOptions = {},\n ): Promise<CloudResourceBrief> {\n const params = new URLSearchParams({ resource });\n if (options.since) params.set('since', options.since);\n if (options.cursor) params.set('cursor', options.cursor);\n if (options.diff !== undefined) params.set('diff', String(options.diff));\n if (options.refresh) params.set('refresh', '1');\n return this.get(`/cloud/resources/brief?${params}`);\n }\n\n async inventory(\n type: string,\n options: { limit?: number; offset?: number } = {},\n ): Promise<CatalogSummary> {\n const params = new URLSearchParams({ type });\n if (options.limit !== undefined) params.set('limit', String(options.limit));\n if (options.offset !== undefined)\n params.set('offset', String(options.offset));\n return this.get(`/inventory?${params}`);\n }\n\n async query(sql: string): Promise<QueryResult> {\n return this.request('/query', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ sql }),\n });\n }\n\n async reconcileCatalog(): Promise<CatalogSyncAccepted> {\n return this.request('/anyshift/reconcile', { method: 'POST' }, 'catalog');\n }\n\n private async get<T>(path: string): Promise<T> {\n return this.request(path, { method: 'GET' });\n }\n\n private async request<T>(\n path: string,\n init: RequestInit,\n pluginId = 'anyshift',\n ): Promise<T> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n const response = await this.fetchApi.fetch(`${baseUrl}${path}`, init);\n const text = await response.text();\n let payload: unknown;\n try {\n payload = text ? JSON.parse(text) : {};\n } catch {\n payload = {};\n }\n if (!response.ok) {\n const error = errorEnvelope(payload);\n throw new AnyshiftRequestError(\n response.status,\n error.code,\n error.message ?? `Anyshift request failed (${response.status})`,\n error.retryAfterSeconds,\n );\n }\n return payload as T;\n }\n}\n\nfunction errorEnvelope(payload: unknown): {\n code: string;\n message?: string;\n retryAfterSeconds?: number;\n} {\n const error =\n payload && typeof payload === 'object' && 'error' in payload\n ? (payload as { error?: unknown }).error\n : undefined;\n if (!error || typeof error !== 'object') {\n return { code: 'request_failed' };\n }\n\n const { code, message, retryAfterSeconds } = error as {\n code?: unknown;\n message?: unknown;\n retryAfterSeconds?: unknown;\n };\n return {\n code: typeof code === 'string' ? code : 'request_failed',\n message: typeof message === 'string' && message ? message : undefined,\n retryAfterSeconds:\n typeof retryAfterSeconds === 'number' &&\n Number.isFinite(retryAfterSeconds)\n ? retryAfterSeconds\n : undefined,\n };\n}\n\nfunction briefQuery(options: BriefRequestOptions): string {\n const params = new URLSearchParams();\n if (options.namespace) params.set('namespace', options.namespace);\n if (options.refresh) params.set('refresh', '1');\n if (options.configurationEndpoints)\n params.set('configurationEndpoints', options.configurationEndpoints);\n if (options.configurationDependencies)\n params.set('configurationDependencies', options.configurationDependencies);\n if (options.configurationTarget)\n params.set('configurationTarget', options.configurationTarget);\n const query = params.toString();\n return query ? `?${query}` : '';\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AnyshiftApi.esm.js","sources":["../../src/api/AnyshiftApi.ts"],"sourcesContent":["import {\n createApiRef,\n type DiscoveryApi,\n type FetchApi,\n} from '@backstage/frontend-plugin-api';\nimport type {\n BriefSectionName,\n BriefSectionResponse,\n AnyshiftCapabilities,\n AskAnyshiftRequest,\n AskAnyshiftResponse,\n CatalogSummary,\n CatalogSyncReport,\n CloudResourceBrief,\n DatadogSignals,\n EstateInsights,\n QueryResult,\n ServiceBrief,\n} from './types';\n\nexport interface AnyshiftApi {\n ask(request: AskAnyshiftRequest): Promise<AskAnyshiftResponse>;\n capabilities(): Promise<AnyshiftCapabilities>;\n brief(\n kind: string,\n target: string,\n options?: BriefRequestOptions,\n ): Promise<ServiceBrief>;\n briefSection(\n kind: string,\n target: string,\n section: BriefSectionName,\n options?: BriefRequestOptions,\n ): Promise<BriefSectionResponse>;\n insights(options?: { refresh?: boolean }): Promise<EstateInsights>;\n datadogSignals(options?: { refresh?: boolean }): Promise<DatadogSignals>;\n cloudResourceBrief(\n resource: string,\n options?: CloudResourceBriefRequestOptions,\n ): Promise<CloudResourceBrief>;\n inventory(\n type: string,\n options?: { limit?: number; offset?: number },\n ): Promise<CatalogSummary>;\n query(sql: string): Promise<QueryResult>;\n reconcileCatalog(): Promise<CatalogSyncAccepted>;\n}\n\nexport interface BriefRequestOptions {\n namespace?: string;\n refresh?: boolean;\n configurationEndpoints?: string;\n configurationDependencies?: string;\n configurationTarget?: string;\n}\n\nexport interface CloudResourceBriefRequestOptions {\n fallbackResource?: string;\n since?: string;\n cursor?: string;\n diff?: boolean;\n refresh?: boolean;\n}\n\nexport interface CatalogSyncAccepted {\n accepted: true;\n acceptedAt: string;\n previous?: CatalogSyncReport;\n}\n\nexport const anyshiftApiRef = createApiRef<AnyshiftApi>({\n id: 'plugin.anyshift.service',\n});\n\nexport class AnyshiftRequestError extends Error {\n constructor(\n readonly status: number,\n readonly code: string,\n message: string,\n readonly retryAfterSeconds?: number,\n ) {\n super(message);\n this.name = 'AnyshiftRequestError';\n }\n}\n\nexport class AnyshiftClient implements AnyshiftApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: { discoveryApi: DiscoveryApi; fetchApi: FetchApi }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi;\n }\n\n async ask(request: AskAnyshiftRequest): Promise<AskAnyshiftResponse> {\n return this.request('/ask', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(request),\n });\n }\n\n async capabilities(): Promise<AnyshiftCapabilities> {\n return this.get('/capabilities');\n }\n\n async brief(\n kind: string,\n target: string,\n options: BriefRequestOptions = {},\n ): Promise<ServiceBrief> {\n return this.get(\n `/brief/${encodeURIComponent(kind)}/${encodeURIComponent(\n target,\n )}${briefQuery(options)}`,\n );\n }\n\n async briefSection(\n kind: string,\n target: string,\n section: BriefSectionName,\n options: BriefRequestOptions = {},\n ): Promise<BriefSectionResponse> {\n return this.get(\n `/brief/${encodeURIComponent(kind)}/${encodeURIComponent(\n target,\n )}/sections/${encodeURIComponent(section)}${briefQuery(options)}`,\n );\n }\n\n async insights(options: { refresh?: boolean } = {}): Promise<EstateInsights> {\n return this.get(`/insights${options.refresh ? '?refresh=1' : ''}`);\n }\n\n async datadogSignals(\n options: { refresh?: boolean } = {},\n ): Promise<DatadogSignals> {\n return this.get(`/signals/datadog${options.refresh ? '?refresh=1' : ''}`);\n }\n\n async cloudResourceBrief(\n resource: string,\n options: CloudResourceBriefRequestOptions = {},\n ): Promise<CloudResourceBrief> {\n const params = new URLSearchParams({ resource });\n if (options.fallbackResource)\n params.set('fallbackResource', options.fallbackResource);\n if (options.since) params.set('since', options.since);\n if (options.cursor) params.set('cursor', options.cursor);\n if (options.diff !== undefined) params.set('diff', String(options.diff));\n if (options.refresh) params.set('refresh', '1');\n return this.get(`/cloud/resources/brief?${params}`);\n }\n\n async inventory(\n type: string,\n options: { limit?: number; offset?: number } = {},\n ): Promise<CatalogSummary> {\n const params = new URLSearchParams({ type });\n if (options.limit !== undefined) params.set('limit', String(options.limit));\n if (options.offset !== undefined)\n params.set('offset', String(options.offset));\n return this.get(`/inventory?${params}`);\n }\n\n async query(sql: string): Promise<QueryResult> {\n return this.request('/query', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ sql }),\n });\n }\n\n async reconcileCatalog(): Promise<CatalogSyncAccepted> {\n return this.request('/anyshift/reconcile', { method: 'POST' }, 'catalog');\n }\n\n private async get<T>(path: string): Promise<T> {\n return this.request(path, { method: 'GET' });\n }\n\n private async request<T>(\n path: string,\n init: RequestInit,\n pluginId = 'anyshift',\n ): Promise<T> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n const response = await this.fetchApi.fetch(`${baseUrl}${path}`, init);\n const text = await response.text();\n let payload: unknown;\n try {\n payload = text ? JSON.parse(text) : {};\n } catch {\n payload = {};\n }\n if (!response.ok) {\n const error = errorEnvelope(payload);\n throw new AnyshiftRequestError(\n response.status,\n error.code,\n error.message ?? `Anyshift request failed (${response.status})`,\n error.retryAfterSeconds,\n );\n }\n return payload as T;\n }\n}\n\nfunction errorEnvelope(payload: unknown): {\n code: string;\n message?: string;\n retryAfterSeconds?: number;\n} {\n const error =\n payload && typeof payload === 'object' && 'error' in payload\n ? (payload as { error?: unknown }).error\n : undefined;\n if (!error || typeof error !== 'object') {\n return { code: 'request_failed' };\n }\n\n const { code, message, retryAfterSeconds } = error as {\n code?: unknown;\n message?: unknown;\n retryAfterSeconds?: unknown;\n };\n return {\n code: typeof code === 'string' ? code : 'request_failed',\n message: typeof message === 'string' && message ? message : undefined,\n retryAfterSeconds:\n typeof retryAfterSeconds === 'number' &&\n Number.isFinite(retryAfterSeconds)\n ? retryAfterSeconds\n : undefined,\n };\n}\n\nfunction briefQuery(options: BriefRequestOptions): string {\n const params = new URLSearchParams();\n if (options.namespace) params.set('namespace', options.namespace);\n if (options.refresh) params.set('refresh', '1');\n if (options.configurationEndpoints)\n params.set('configurationEndpoints', options.configurationEndpoints);\n if (options.configurationDependencies)\n params.set('configurationDependencies', options.configurationDependencies);\n if (options.configurationTarget)\n params.set('configurationTarget', options.configurationTarget);\n const query = params.toString();\n return query ? `?${query}` : '';\n}\n"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@ import { useEntity } from '@backstage/plugin-catalog-react';
9
9
  import { anyshiftApiRef } from '../../api/AnyshiftApi.esm.js';
10
10
  import { AskAnyshiftCard } from '../ask/AskAnyshiftCard.esm.js';
11
11
  import { askScopeForEntity } from '../ask/askScope.esm.js';
12
- import { cloudResourceIdentity } from '../entity/entityIdentity.esm.js';
12
+ import { cloudResourceIdentity, cloudResourceFallbackIdentity } from '../entity/entityIdentity.esm.js';
13
13
  import { CloudImpactSection } from './CloudImpactSection.esm.js';
14
14
  import { CloudDependenciesSection, CloudDependentsSection } from './CloudRelationshipSections.esm.js';
15
15
 
@@ -19,6 +19,7 @@ const CloudResourceEvidenceContent = ({ includeAsk = false }) => {
19
19
  const { entity } = useEntity();
20
20
  const api = useApi(anyshiftApiRef);
21
21
  const resourceId = cloudResourceIdentity(entity);
22
+ const fallbackResource = cloudResourceFallbackIdentity(entity);
22
23
  const [loadedBrief, setLoadedBrief] = useState();
23
24
  const brief = loadedBrief && loadedBrief.resourceId === resourceId ? loadedBrief.value : void 0;
24
25
  const [error, setError] = useState();
@@ -56,6 +57,7 @@ const CloudResourceEvidenceContent = ({ includeAsk = false }) => {
56
57
  setError(void 0);
57
58
  try {
58
59
  const next = await api.cloudResourceBrief(resourceId, {
60
+ ...fallbackResource ? { fallbackResource } : {},
59
61
  since: "24h",
60
62
  diff: true,
61
63
  ...refresh ? { refresh: true } : {}
@@ -79,7 +81,7 @@ const CloudResourceEvidenceContent = ({ includeAsk = false }) => {
79
81
  }
80
82
  }
81
83
  },
82
- [api, resourceId]
84
+ [api, fallbackResource, resourceId]
83
85
  );
84
86
  useEffect(() => {
85
87
  void load();
@@ -104,6 +106,7 @@ const CloudResourceEvidenceContent = ({ includeAsk = false }) => {
104
106
  setPaginationError(void 0);
105
107
  try {
106
108
  const next = await api.cloudResourceBrief(resourceId, {
109
+ ...fallbackResource ? { fallbackResource } : {},
107
110
  since: brief.since,
108
111
  diff: true,
109
112
  cursor
@@ -150,7 +153,7 @@ const CloudResourceEvidenceContent = ({ includeAsk = false }) => {
150
153
  setLoadingMore(false);
151
154
  }
152
155
  }
153
- }, [api, brief, resourceId]);
156
+ }, [api, brief, fallbackResource, resourceId]);
154
157
  if (!resourceId) {
155
158
  return /* @__PURE__ */ jsx(Alert, { severity: "info", children: "This catalog entity has no stable Anyshift resource ID or cloud ARN." });
156
159
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CloudResourceContent.esm.js","sources":["../../../src/components/cloud/CloudResourceContent.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport {\n Button,\n Chip,\n CircularProgress,\n Grid,\n Typography,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport { InfoCard, Link, Progress } from '@backstage/core-components';\nimport { useApi } from '@backstage/frontend-plugin-api';\nimport type { Entity } from '@backstage/catalog-model';\nimport {\n ANYSHIFT_CLOUD_ACCOUNT_ANNOTATION,\n ANYSHIFT_CLOUD_PROVIDER_ANNOTATION,\n ANYSHIFT_CLOUD_REGION_ANNOTATION,\n ANYSHIFT_RESOURCE_TYPE_ANNOTATION,\n type BriefSection,\n type CloudEventsEvidence,\n type CloudResourceBrief,\n type IacDriftEvidence,\n type IacEvidence,\n} from '@anyshift/backstage-plugin-anyshift-common';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { anyshiftApiRef } from '../../api/AnyshiftApi';\nimport { AskAnyshiftCard } from '../ask/AskAnyshiftCard';\nimport { askScopeForEntity } from '../ask/askScope';\nimport type { AnyshiftCapabilities, AskScope } from '../../api/types';\nimport { cloudResourceIdentity } from '../entity/entityIdentity';\nimport { CloudImpactSection } from './CloudImpactSection';\nimport {\n CloudDependenciesSection,\n CloudDependentsSection,\n} from './CloudRelationshipSections';\n\nexport const CloudResourceContent = () => <CloudResourceEvidenceContent />;\n\nexport const CloudAnyshiftEntityContent = () => (\n <CloudResourceEvidenceContent includeAsk />\n);\n\nconst CloudResourceEvidenceContent = ({ includeAsk = false }) => {\n const { entity } = useEntity();\n const api = useApi(anyshiftApiRef);\n const resourceId = cloudResourceIdentity(entity);\n const [loadedBrief, setLoadedBrief] = useState<{\n resourceId: string;\n value: CloudResourceBrief;\n }>();\n const brief =\n loadedBrief && loadedBrief.resourceId === resourceId\n ? loadedBrief.value\n : undefined;\n const [error, setError] = useState<string>();\n const [refreshing, setRefreshing] = useState(false);\n const [loadingMore, setLoadingMore] = useState(false);\n const [paginationError, setPaginationError] = useState<string>();\n const [capabilities, setCapabilities] = useState<AnyshiftCapabilities>({\n askEnabled: false,\n queryEnabled: false,\n });\n const operations = useRef({ identity: 0, primary: 0, pagination: 0 });\n const askScope = useMemo(\n () => (includeAsk ? askScopeForEntity(entity) : undefined),\n [entity, includeAsk],\n );\n\n useLayoutEffect(() => {\n operations.current.identity += 1;\n operations.current.primary += 1;\n operations.current.pagination += 1;\n setLoadedBrief(undefined);\n setError(undefined);\n setRefreshing(false);\n setLoadingMore(false);\n setPaginationError(undefined);\n }, [resourceId]);\n\n const load = useCallback(\n async (refresh = false) => {\n if (!resourceId) return;\n const identity = operations.current.identity;\n const primary = ++operations.current.primary;\n ++operations.current.pagination;\n setRefreshing(refresh);\n setLoadingMore(false);\n setPaginationError(undefined);\n setError(undefined);\n try {\n const next = await api.cloudResourceBrief(resourceId, {\n since: '24h',\n diff: true,\n ...(refresh ? { refresh: true } : {}),\n });\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary\n ) {\n ++operations.current.pagination;\n setLoadingMore(false);\n setLoadedBrief({ resourceId, value: next });\n }\n } catch (loadError) {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary\n ) {\n ++operations.current.pagination;\n setLoadingMore(false);\n setError(\n loadError instanceof Error\n ? loadError.message\n : 'Unable to load cloud evidence',\n );\n }\n } finally {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary\n ) {\n setRefreshing(false);\n }\n }\n },\n [api, resourceId],\n );\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!includeAsk) return undefined;\n let active = true;\n api\n .capabilities()\n .then(next => active && setCapabilities(next))\n .catch(\n () =>\n active && setCapabilities({ askEnabled: false, queryEnabled: false }),\n );\n return () => {\n active = false;\n };\n }, [api, includeAsk]);\n\n const loadMore = useCallback(async () => {\n const cursor = brief?.changes.data?.page.nextCursor;\n if (!resourceId || !cursor) return;\n const identity = operations.current.identity;\n const primary = operations.current.primary;\n const pagination = ++operations.current.pagination;\n setLoadingMore(true);\n setPaginationError(undefined);\n try {\n const next = await api.cloudResourceBrief(resourceId, {\n since: brief.since,\n diff: true,\n cursor,\n });\n if (\n operations.current.identity !== identity ||\n operations.current.primary !== primary ||\n operations.current.pagination !== pagination\n ) {\n return;\n }\n if (next.changes.state === 'error') {\n setPaginationError(\n next.changes.message || 'Unable to load more cloud changes',\n );\n return;\n }\n if (next.changes.state === 'data' && next.changes.data) {\n setPaginationError(undefined);\n }\n setLoadedBrief(current => {\n if (\n !current ||\n current.resourceId !== resourceId ||\n !current.value.changes.data ||\n next.changes.state !== 'data' ||\n !next.changes.data\n ) {\n return current;\n }\n return {\n resourceId,\n value: {\n ...current.value,\n refreshedAt: next.refreshedAt,\n changes: {\n state: 'data',\n data: mergeCloudEventsEvidence(\n current.value.changes.data,\n next.changes.data,\n ),\n },\n },\n };\n });\n } catch (loadError) {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary &&\n operations.current.pagination === pagination\n ) {\n setPaginationError(\n loadError instanceof Error\n ? loadError.message\n : 'Unable to load more cloud changes',\n );\n }\n } finally {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary &&\n operations.current.pagination === pagination\n ) {\n setLoadingMore(false);\n }\n }\n }, [api, brief, resourceId]);\n\n if (!resourceId) {\n return (\n <Alert severity=\"info\">\n This catalog entity has no stable Anyshift resource ID or cloud ARN.\n </Alert>\n );\n }\n if (error && !brief) {\n return (\n <Alert severity=\"error\">\n {error} <Button onClick={() => void load(true)}>Retry</Button>\n </Alert>\n );\n }\n if (!brief) return <Progress />;\n\n return (\n <CloudResourceBriefView\n entity={entity}\n brief={brief}\n refreshing={refreshing}\n onRefresh={() => void load(true)}\n loadingMore={loadingMore}\n onLoadMore={() => void loadMore()}\n error={error}\n paginationError={paginationError}\n askEnabled={includeAsk && capabilities.askEnabled && Boolean(askScope)}\n askScope={askScope}\n />\n );\n};\n\nexport function mergeCloudEventsEvidence(\n current: CloudEventsEvidence,\n next: CloudEventsEvidence,\n): CloudEventsEvidence {\n return {\n ...next,\n availability: mergeCloudEventAvailability(\n current.availability,\n next.availability,\n ),\n warnings: [...new Set([...current.warnings, ...next.warnings])],\n items: [...current.items, ...next.items],\n };\n}\n\nfunction mergeCloudEventAvailability(\n current: Record<string, string>,\n next: Record<string, string>,\n): Record<string, string> {\n const availability: Record<string, string> = {};\n for (const field of new Set([\n ...Object.keys(current),\n ...Object.keys(next),\n ])) {\n availability[field] = leastCompleteAvailability(\n current[field],\n next[field],\n );\n }\n return availability;\n}\n\nfunction leastCompleteAvailability(\n current: string | undefined,\n next: string | undefined,\n): string {\n const normalizedCurrent = normalizeAvailability(current);\n const normalizedNext = normalizeAvailability(next);\n return AVAILABILITY_RANK[normalizedCurrent] <=\n AVAILABILITY_RANK[normalizedNext]\n ? normalizedCurrent\n : normalizedNext;\n}\n\nconst AVAILABILITY_RANK: Record<string, number> = {\n unavailable: 0,\n partial: 1,\n available: 2,\n};\n\nfunction normalizeAvailability(value: string | undefined): string {\n return value && value in AVAILABILITY_RANK ? value : 'unavailable';\n}\n\nexport const CloudResourceBriefView = ({\n entity,\n brief,\n refreshing,\n onRefresh,\n loadingMore,\n onLoadMore,\n error,\n paginationError,\n askEnabled = false,\n askScope,\n}: {\n entity: Entity;\n brief: CloudResourceBrief;\n refreshing?: boolean;\n onRefresh: () => void;\n loadingMore?: boolean;\n onLoadMore?: () => void;\n error?: string;\n paginationError?: string;\n askEnabled?: boolean;\n askScope?: AskScope;\n}) => {\n const annotations = entity.metadata.annotations ?? {};\n const consoleLink = entity.metadata.links?.find(link =>\n link.url.startsWith('https://console.aws.amazon.com/'),\n );\n\n return (\n <Grid container spacing={3}>\n {error && (\n <Grid item xs={12}>\n <Alert severity=\"error\">{error}</Alert>\n </Grid>\n )}\n <Grid item xs={12}>\n <InfoCard\n title=\"Cloud evidence\"\n action={\n <Button\n size=\"small\"\n onClick={onRefresh}\n startIcon={\n refreshing ? <CircularProgress size={14} /> : undefined\n }\n >\n Refresh\n </Button>\n }\n >\n <Typography color=\"textSecondary\">\n Read-only Anyshift evidence · last refreshed{' '}\n {formatCloudTimestamp(brief.refreshedAt)} · window {brief.since}\n </Typography>\n </InfoCard>\n </Grid>\n\n <Grid item xs={12}>\n <InfoCard title=\"Cloud identity\">\n <Definition\n label=\"Provider\"\n value={annotations[ANYSHIFT_CLOUD_PROVIDER_ANNOTATION]}\n />\n <Definition\n label=\"Resource type\"\n value={\n annotations[ANYSHIFT_RESOURCE_TYPE_ANNOTATION] ||\n String(entity.spec?.type || '')\n }\n />\n <Definition\n label=\"Region\"\n value={annotations[ANYSHIFT_CLOUD_REGION_ANNOTATION] || 'Global'}\n />\n <Definition\n label=\"Account\"\n value={annotations[ANYSHIFT_CLOUD_ACCOUNT_ANNOTATION]}\n />\n <Definition label=\"Stable resource ID\" value={brief.resourceId} />\n {consoleLink && <Link to={consoleLink.url}>Open in AWS Console</Link>}\n </InfoCard>\n </Grid>\n <Grid item xs={12} md={6}>\n <CloudDependenciesSection entity={entity} />\n </Grid>\n <Grid item xs={12} md={6}>\n <CloudDependentsSection entity={entity} />\n </Grid>\n <Grid item xs={12}>\n <CloudImpactSection section={brief.impact} onRetry={onRefresh} />\n </Grid>\n <Grid item xs={12}>\n <ChangesSection\n section={brief.changes}\n loadingMore={loadingMore}\n onLoadMore={onLoadMore}\n paginationError={paginationError}\n />\n </Grid>\n <Grid item xs={12} md={6}>\n <ProvenanceSection section={brief.provenance} />\n </Grid>\n <Grid item xs={12} md={6}>\n <DriftSection section={brief.drift} />\n </Grid>\n {askEnabled && (\n <Grid item xs={12}>\n <AskAnyshiftCard context=\"entity\" scope={askScope} />\n </Grid>\n )}\n </Grid>\n );\n};\n\nconst ChangesSection = ({\n section,\n loadingMore,\n onLoadMore,\n paginationError,\n}: {\n section: BriefSection<CloudEventsEvidence>;\n loadingMore?: boolean;\n onLoadMore?: () => void;\n paginationError?: string;\n}) => {\n const { hasEvidenceLimitations, actionableWarnings } =\n partitionCloudEventWarnings(\n section.data?.warnings,\n section.data?.items.length ?? 0,\n );\n\n if (section.state === 'empty') {\n return (\n <InfoCard title=\"Recent cloud changes\">\n <Typography color=\"textSecondary\">\n {section.message || 'No cloud changes were found in this window.'}\n </Typography>\n </InfoCard>\n );\n }\n\n return (\n <InfoCard title=\"Recent cloud changes\">\n <SectionState section={section}>\n {paginationError && (\n <Alert severity=\"error\" style={{ marginBottom: 8 }}>\n {paginationError}\n </Alert>\n )}\n {hasEvidenceLimitations && (\n <Typography\n aria-label=\"Cloud event evidence limitations\"\n variant=\"caption\"\n color=\"textSecondary\"\n display=\"block\"\n style={{ marginBottom: 8 }}\n >\n Event source is derived from graph relationships, and event status\n may be incomplete.\n </Typography>\n )}\n {actionableWarnings.map(warning => (\n <Alert severity=\"warning\" key={warning} style={{ marginBottom: 8 }}>\n {humanize(warning)}\n </Alert>\n ))}\n {section.data?.items?.length ? (\n section.data.items.map(event => (\n <div key={event.id} style={{ marginBottom: 20 }}>\n <Typography variant=\"subtitle1\">\n {event.summary || humanize(event.type)}\n </Typography>\n <Typography color=\"textSecondary\">\n {formatCloudTimestamp(event.timestamp)} · {event.category} ·{' '}\n {event.evidence.source} · {event.evidence.status}\n {event.actor?.name || event.actor?.id\n ? ` · ${event.actor.name || event.actor.id}`\n : ''}\n </Typography>\n {event.change.fields.length > 0 && (\n <details>\n <summary>View sanitized field changes</summary>\n <ul>\n {event.change.fields.map(field => {\n const detail = event.change.details.find(\n candidate => candidate.field === field,\n );\n return (\n <li key={field}>\n <code>{field}</code>\n {detail\n ? `: ${detail.before ?? '∅'} → ${\n detail.after ?? '∅'\n }`\n : ''}\n </li>\n );\n })}\n </ul>\n </details>\n )}\n </div>\n ))\n ) : (\n <Typography color=\"textSecondary\">\n No cloud changes were found in this window.\n </Typography>\n )}\n {section.data?.page.hasMore && onLoadMore && (\n <Button\n size=\"small\"\n onClick={onLoadMore}\n disabled={loadingMore}\n startIcon={loadingMore ? <CircularProgress size={14} /> : undefined}\n >\n Load more changes\n </Button>\n )}\n </SectionState>\n </InfoCard>\n );\n};\n\nconst QUIET_EVIDENCE_LIMITATIONS = new Set([\n 'event_source_derived',\n 'event_status_incomplete',\n]);\nconst IDENTITY_COMPLETENESS_WARNINGS = new Set([\n 'target_identity_incomplete',\n 'actor_identity_incomplete',\n]);\n\nfunction partitionCloudEventWarnings(\n warnings: string[] | undefined,\n eventCount: number,\n) {\n const allWarnings = warnings ?? [];\n return {\n hasEvidenceLimitations: allWarnings.some(warning =>\n QUIET_EVIDENCE_LIMITATIONS.has(warning),\n ),\n actionableWarnings: allWarnings.filter(\n warning =>\n !QUIET_EVIDENCE_LIMITATIONS.has(warning) &&\n (eventCount > 0 || !IDENTITY_COMPLETENESS_WARNINGS.has(warning)),\n ),\n };\n}\n\nconst ProvenanceSection = ({\n section,\n}: {\n section: BriefSection<IacEvidence>;\n}) => {\n if (section.state === 'empty') {\n return (\n <InfoCard title=\"IaC provenance\">\n <Typography color=\"textSecondary\">\n {section.message ||\n 'No Terraform provenance is linked to this resource.'}\n </Typography>\n </InfoCard>\n );\n }\n return (\n <InfoCard title=\"IaC provenance\">\n <SectionState section={section}>\n {section.data?.resources?.length ? (\n section.data.resources.map(resource => (\n <div key={resource.terraform.hashedID} style={{ marginBottom: 16 }}>\n <Typography variant=\"subtitle1\">\n {resource.terraform.address}\n </Typography>\n <Chip size=\"small\" label={humanize(resource.status)} />\n <Definition\n label=\"File\"\n value={resource.terraform.fileRef ?? ''}\n />\n <Definition\n label=\"State links\"\n value={String(resource.states.length)}\n />\n <Definition\n label=\"Cloud links\"\n value={String(resource.clouds.length)}\n />\n {resource.terraform.githubUrl && (\n <Link to={resource.terraform.githubUrl}>Open source</Link>\n )}\n </div>\n ))\n ) : (\n <Typography color=\"textSecondary\">\n No Terraform provenance is linked to this resource.\n </Typography>\n )}\n </SectionState>\n </InfoCard>\n );\n};\n\nconst DriftSection = ({\n section,\n}: {\n section: BriefSection<IacDriftEvidence>;\n}) => {\n if (section.state === 'empty') {\n return (\n <InfoCard title=\"IaC drift evidence\">\n <Typography color=\"textSecondary\">\n {section.message || 'No comparable Terraform evidence is available.'}\n </Typography>\n </InfoCard>\n );\n }\n return (\n <InfoCard title=\"IaC drift evidence\">\n <SectionState section={section}>\n {section.data?.items?.length ? (\n section.data.items.map(item => (\n <div key={item.terraform.hashedID} style={{ marginBottom: 16 }}>\n <Typography variant=\"subtitle1\">\n {item.terraform.address}\n </Typography>\n <Chip\n size=\"small\"\n color={item.status === 'drifted' ? 'secondary' : 'default'}\n label={humanize(item.status)}\n />\n <Typography color=\"textSecondary\">\n {item.status === 'unknown'\n ? `Unknown is not drift: ${humanize(item.reason)}.`\n : `${item.comparedFields} supported fields compared.`}\n </Typography>\n {item.differences.length > 0 && (\n <details>\n <summary>View sanitized differences</summary>\n <ul>\n {item.differences.map(difference => (\n <li key={difference.field}>\n <code>{difference.field}</code>:{' '}\n {difference.lastApplied ?? '∅'} →{' '}\n {difference.observed ?? '∅'}\n </li>\n ))}\n </ul>\n </details>\n )}\n </div>\n ))\n ) : (\n <Typography color=\"textSecondary\">\n No comparable Terraform evidence is available.\n </Typography>\n )}\n </SectionState>\n </InfoCard>\n );\n};\n\nconst SectionState = ({\n section,\n children,\n}: {\n section: BriefSection;\n children: ReactNode;\n}) => {\n if (section.state === 'error') {\n return <Alert severity=\"error\">{section.message}</Alert>;\n }\n if (section.state === 'unsupported') {\n return <Alert severity=\"info\">{section.message}</Alert>;\n }\n if (section.state === 'empty') {\n return <Typography color=\"textSecondary\">{section.message}</Typography>;\n }\n return <>{children}</>;\n};\n\nconst Definition = ({ label, value }: { label: string; value?: string }) => (\n <Typography paragraph>\n <strong>{label}:</strong> {value || 'Not available'}\n </Typography>\n);\n\nfunction humanize(value: string): string {\n return value.replaceAll('_', ' ');\n}\n\nexport function formatCloudTimestamp(value: string): string {\n const directTimestamp = Date.parse(value);\n if (!Number.isNaN(directTimestamp)) {\n return new Date(directTimestamp).toLocaleString();\n }\n\n const withoutBracketedZone = value.replace(/\\[[^\\]]+\\]$/, '');\n const normalizedTimestamp = Date.parse(withoutBracketedZone);\n return Number.isNaN(normalizedTimestamp)\n ? value\n : new Date(normalizedTimestamp).toLocaleString();\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AA2CO,MAAM,oBAAA,GAAuB,sBAAM,GAAA,CAAC,4BAAA,EAAA,EAA6B;AAEjE,MAAM,0BAAA,GAA6B,sBACxC,GAAA,CAAC,4BAAA,EAAA,EAA6B,YAAU,IAAA,EAAC;AAG3C,MAAM,4BAAA,GAA+B,CAAC,EAAE,UAAA,GAAa,OAAM,KAAM;AAC/D,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAC7B,EAAA,MAAM,GAAA,GAAM,OAAO,cAAc,CAAA;AACjC,EAAA,MAAM,UAAA,GAAa,sBAAsB,MAAM,CAAA;AAC/C,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,QAAA,EAGnC;AACH,EAAA,MAAM,QACJ,WAAA,IAAe,WAAA,CAAY,UAAA,KAAe,UAAA,GACtC,YAAY,KAAA,GACZ,MAAA;AACN,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAA,EAAiB;AAC3C,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,KAAK,CAAA;AACpD,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAI,QAAA,EAAiB;AAC/D,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,QAAA,CAA+B;AAAA,IACrE,UAAA,EAAY,KAAA;AAAA,IACZ,YAAA,EAAc;AAAA,GACf,CAAA;AACD,EAAA,MAAM,UAAA,GAAa,OAAO,EAAE,QAAA,EAAU,GAAG,OAAA,EAAS,CAAA,EAAG,UAAA,EAAY,CAAA,EAAG,CAAA;AACpE,EAAA,MAAM,QAAA,GAAW,OAAA;AAAA,IACf,MAAO,UAAA,GAAa,iBAAA,CAAkB,MAAM,CAAA,GAAI,MAAA;AAAA,IAChD,CAAC,QAAQ,UAAU;AAAA,GACrB;AAEA,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAA,UAAA,CAAW,QAAQ,QAAA,IAAY,CAAA;AAC/B,IAAA,UAAA,CAAW,QAAQ,OAAA,IAAW,CAAA;AAC9B,IAAA,UAAA,CAAW,QAAQ,UAAA,IAAc,CAAA;AACjC,IAAA,cAAA,CAAe,MAAS,CAAA;AACxB,IAAA,QAAA,CAAS,MAAS,CAAA;AAClB,IAAA,aAAA,CAAc,KAAK,CAAA;AACnB,IAAA,cAAA,CAAe,KAAK,CAAA;AACpB,IAAA,kBAAA,CAAmB,MAAS,CAAA;AAAA,EAC9B,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAA,MAAM,IAAA,GAAO,WAAA;AAAA,IACX,OAAO,UAAU,KAAA,KAAU;AACzB,MAAA,IAAI,CAAC,UAAA,EAAY;AACjB,MAAA,MAAM,QAAA,GAAW,WAAW,OAAA,CAAQ,QAAA;AACpC,MAAA,MAAM,OAAA,GAAU,EAAE,UAAA,CAAW,OAAA,CAAQ,OAAA;AACrC,MAAA,EAAE,WAAW,OAAA,CAAQ,UAAA;AACrB,MAAA,aAAA,CAAc,OAAO,CAAA;AACrB,MAAA,cAAA,CAAe,KAAK,CAAA;AACpB,MAAA,kBAAA,CAAmB,MAAS,CAAA;AAC5B,MAAA,QAAA,CAAS,MAAS,CAAA;AAClB,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,kBAAA,CAAmB,UAAA,EAAY;AAAA,UACpD,KAAA,EAAO,KAAA;AAAA,UACP,IAAA,EAAM,IAAA;AAAA,UACN,GAAI,OAAA,GAAU,EAAE,OAAA,EAAS,IAAA,KAAS;AAAC,SACpC,CAAA;AACD,QAAA,IACE,WAAW,OAAA,CAAQ,QAAA,KAAa,YAChC,UAAA,CAAW,OAAA,CAAQ,YAAY,OAAA,EAC/B;AACA,UAAA,EAAE,WAAW,OAAA,CAAQ,UAAA;AACrB,UAAA,cAAA,CAAe,KAAK,CAAA;AACpB,UAAA,cAAA,CAAe,EAAE,UAAA,EAAY,KAAA,EAAO,IAAA,EAAM,CAAA;AAAA,QAC5C;AAAA,MACF,SAAS,SAAA,EAAW;AAClB,QAAA,IACE,WAAW,OAAA,CAAQ,QAAA,KAAa,YAChC,UAAA,CAAW,OAAA,CAAQ,YAAY,OAAA,EAC/B;AACA,UAAA,EAAE,WAAW,OAAA,CAAQ,UAAA;AACrB,UAAA,cAAA,CAAe,KAAK,CAAA;AACpB,UAAA,QAAA;AAAA,YACE,SAAA,YAAqB,KAAA,GACjB,SAAA,CAAU,OAAA,GACV;AAAA,WACN;AAAA,QACF;AAAA,MACF,CAAA,SAAE;AACA,QAAA,IACE,WAAW,OAAA,CAAQ,QAAA,KAAa,YAChC,UAAA,CAAW,OAAA,CAAQ,YAAY,OAAA,EAC/B;AACA,UAAA,aAAA,CAAc,KAAK,CAAA;AAAA,QACrB;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IACA,CAAC,KAAK,UAAU;AAAA,GAClB;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,KAAK,IAAA,EAAK;AAAA,EACZ,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAY,OAAO,MAAA;AACxB,IAAA,IAAI,MAAA,GAAS,IAAA;AACb,IAAA,GAAA,CACG,YAAA,GACA,IAAA,CAAK,CAAA,IAAA,KAAQ,UAAU,eAAA,CAAgB,IAAI,CAAC,CAAA,CAC5C,KAAA;AAAA,MACC,MACE,UAAU,eAAA,CAAgB,EAAE,YAAY,KAAA,EAAO,YAAA,EAAc,OAAO;AAAA,KACxE;AACF,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,GAAS,KAAA;AAAA,IACX,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,GAAA,EAAK,UAAU,CAAC,CAAA;AAEpB,EAAA,MAAM,QAAA,GAAW,YAAY,YAAY;AACvC,IAAA,MAAM,MAAA,GAAS,KAAA,EAAO,OAAA,CAAQ,IAAA,EAAM,IAAA,CAAK,UAAA;AACzC,IAAA,IAAI,CAAC,UAAA,IAAc,CAAC,MAAA,EAAQ;AAC5B,IAAA,MAAM,QAAA,GAAW,WAAW,OAAA,CAAQ,QAAA;AACpC,IAAA,MAAM,OAAA,GAAU,WAAW,OAAA,CAAQ,OAAA;AACnC,IAAA,MAAM,UAAA,GAAa,EAAE,UAAA,CAAW,OAAA,CAAQ,UAAA;AACxC,IAAA,cAAA,CAAe,IAAI,CAAA;AACnB,IAAA,kBAAA,CAAmB,MAAS,CAAA;AAC5B,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,kBAAA,CAAmB,UAAA,EAAY;AAAA,QACpD,OAAO,KAAA,CAAM,KAAA;AAAA,QACb,IAAA,EAAM,IAAA;AAAA,QACN;AAAA,OACD,CAAA;AACD,MAAA,IACE,UAAA,CAAW,OAAA,CAAQ,QAAA,KAAa,QAAA,IAChC,UAAA,CAAW,OAAA,CAAQ,OAAA,KAAY,OAAA,IAC/B,UAAA,CAAW,OAAA,CAAQ,UAAA,KAAe,UAAA,EAClC;AACA,QAAA;AAAA,MACF;AACA,MAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,KAAA,KAAU,OAAA,EAAS;AAClC,QAAA,kBAAA;AAAA,UACE,IAAA,CAAK,QAAQ,OAAA,IAAW;AAAA,SAC1B;AACA,QAAA;AAAA,MACF;AACA,MAAA,IAAI,KAAK,OAAA,CAAQ,KAAA,KAAU,MAAA,IAAU,IAAA,CAAK,QAAQ,IAAA,EAAM;AACtD,QAAA,kBAAA,CAAmB,KAAA,CAAS,CAAA;AAAA,MAC9B;AACA,MAAA,cAAA,CAAe,CAAA,OAAA,KAAW;AACxB,QAAA,IACE,CAAC,OAAA,IACD,OAAA,CAAQ,UAAA,KAAe,UAAA,IACvB,CAAC,OAAA,CAAQ,KAAA,CAAM,OAAA,CAAQ,IAAA,IACvB,KAAK,OAAA,CAAQ,KAAA,KAAU,UACvB,CAAC,IAAA,CAAK,QAAQ,IAAA,EACd;AACA,UAAA,OAAO,OAAA;AAAA,QACT;AACA,QAAA,OAAO;AAAA,UACL,UAAA;AAAA,UACA,KAAA,EAAO;AAAA,YACL,GAAG,OAAA,CAAQ,KAAA;AAAA,YACX,aAAa,IAAA,CAAK,WAAA;AAAA,YAClB,OAAA,EAAS;AAAA,cACP,KAAA,EAAO,MAAA;AAAA,cACP,IAAA,EAAM,wBAAA;AAAA,gBACJ,OAAA,CAAQ,MAAM,OAAA,CAAQ,IAAA;AAAA,gBACtB,KAAK,OAAA,CAAQ;AAAA;AACf;AACF;AACF,SACF;AAAA,MACF,CAAC,CAAA;AAAA,IACH,SAAS,SAAA,EAAW;AAClB,MAAA,IACE,UAAA,CAAW,OAAA,CAAQ,QAAA,KAAa,QAAA,IAChC,UAAA,CAAW,OAAA,CAAQ,OAAA,KAAY,OAAA,IAC/B,UAAA,CAAW,OAAA,CAAQ,UAAA,KAAe,UAAA,EAClC;AACA,QAAA,kBAAA;AAAA,UACE,SAAA,YAAqB,KAAA,GACjB,SAAA,CAAU,OAAA,GACV;AAAA,SACN;AAAA,MACF;AAAA,IACF,CAAA,SAAE;AACA,MAAA,IACE,UAAA,CAAW,OAAA,CAAQ,QAAA,KAAa,QAAA,IAChC,UAAA,CAAW,OAAA,CAAQ,OAAA,KAAY,OAAA,IAC/B,UAAA,CAAW,OAAA,CAAQ,UAAA,KAAe,UAAA,EAClC;AACA,QAAA,cAAA,CAAe,KAAK,CAAA;AAAA,MACtB;AAAA,IACF;AAAA,EACF,CAAA,EAAG,CAAC,GAAA,EAAK,KAAA,EAAO,UAAU,CAAC,CAAA;AAE3B,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,MAAA,EAAO,QAAA,EAAA,sEAAA,EAEvB,CAAA;AAAA,EAEJ;AACA,EAAA,IAAI,KAAA,IAAS,CAAC,KAAA,EAAO;AACnB,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,OAAA,EACb,QAAA,EAAA;AAAA,MAAA,KAAA;AAAA,MAAM,GAAA;AAAA,sBAAC,GAAA,CAAC,UAAO,OAAA,EAAS,MAAM,KAAK,IAAA,CAAK,IAAI,GAAG,QAAA,EAAA,OAAA,EAAK;AAAA,KAAA,EACvD,CAAA;AAAA,EAEJ;AACA,EAAA,IAAI,CAAC,KAAA,EAAO,uBAAO,GAAA,CAAC,QAAA,EAAA,EAAS,CAAA;AAE7B,EAAA,uBACE,GAAA;AAAA,IAAC,sBAAA;AAAA,IAAA;AAAA,MACC,MAAA;AAAA,MACA,KAAA;AAAA,MACA,UAAA;AAAA,MACA,SAAA,EAAW,MAAM,KAAK,IAAA,CAAK,IAAI,CAAA;AAAA,MAC/B,WAAA;AAAA,MACA,UAAA,EAAY,MAAM,KAAK,QAAA,EAAS;AAAA,MAChC,KAAA;AAAA,MACA,eAAA;AAAA,MACA,UAAA,EAAY,UAAA,IAAc,YAAA,CAAa,UAAA,IAAc,QAAQ,QAAQ,CAAA;AAAA,MACrE;AAAA;AAAA,GACF;AAEJ,CAAA;AAEO,SAAS,wBAAA,CACd,SACA,IAAA,EACqB;AACrB,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,YAAA,EAAc,2BAAA;AAAA,MACZ,OAAA,CAAQ,YAAA;AAAA,MACR,IAAA,CAAK;AAAA,KACP;AAAA,IACA,QAAA,EAAU,CAAC,mBAAG,IAAI,GAAA,CAAI,CAAC,GAAG,OAAA,CAAQ,QAAA,EAAU,GAAG,IAAA,CAAK,QAAQ,CAAC,CAAC,CAAA;AAAA,IAC9D,OAAO,CAAC,GAAG,QAAQ,KAAA,EAAO,GAAG,KAAK,KAAK;AAAA,GACzC;AACF;AAEA,SAAS,2BAAA,CACP,SACA,IAAA,EACwB;AACxB,EAAA,MAAM,eAAuC,EAAC;AAC9C,EAAA,KAAA,MAAW,KAAA,wBAAa,GAAA,CAAI;AAAA,IAC1B,GAAG,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AAAA,IACtB,GAAG,MAAA,CAAO,IAAA,CAAK,IAAI;AAAA,GACpB,CAAA,EAAG;AACF,IAAA,YAAA,CAAa,KAAK,CAAA,GAAI,yBAAA;AAAA,MACpB,QAAQ,KAAK,CAAA;AAAA,MACb,KAAK,KAAK;AAAA,KACZ;AAAA,EACF;AACA,EAAA,OAAO,YAAA;AACT;AAEA,SAAS,yBAAA,CACP,SACA,IAAA,EACQ;AACR,EAAA,MAAM,iBAAA,GAAoB,sBAAsB,OAAO,CAAA;AACvD,EAAA,MAAM,cAAA,GAAiB,sBAAsB,IAAI,CAAA;AACjD,EAAA,OAAO,kBAAkB,iBAAiB,CAAA,IACxC,iBAAA,CAAkB,cAAc,IAC9B,iBAAA,GACA,cAAA;AACN;AAEA,MAAM,iBAAA,GAA4C;AAAA,EAChD,WAAA,EAAa,CAAA;AAAA,EACb,OAAA,EAAS,CAAA;AAAA,EACT,SAAA,EAAW;AACb,CAAA;AAEA,SAAS,sBAAsB,KAAA,EAAmC;AAChE,EAAA,OAAO,KAAA,IAAS,KAAA,IAAS,iBAAA,GAAoB,KAAA,GAAQ,aAAA;AACvD;AAEO,MAAM,yBAAyB,CAAC;AAAA,EACrC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,KAAA;AAAA,EACA,eAAA;AAAA,EACA,UAAA,GAAa,KAAA;AAAA,EACb;AACF,CAAA,KAWM;AACJ,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,KAAA,EAAO,IAAA;AAAA,IAAK,CAAA,IAAA,KAC9C,IAAA,CAAK,GAAA,CAAI,UAAA,CAAW,iCAAiC;AAAA,GACvD;AAEA,EAAA,uBACE,IAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAS,IAAA,EAAC,SAAS,CAAA,EACtB,QAAA,EAAA;AAAA,IAAA,KAAA,oBACC,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EACb,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,OAAA,EAAS,QAAA,EAAA,KAAA,EAAM,CAAA,EACjC,CAAA;AAAA,oBAEF,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,IAAI,EAAA,EACb,QAAA,kBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,gBAAA;AAAA,QACN,MAAA,kBACE,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,OAAA;AAAA,YACL,OAAA,EAAS,SAAA;AAAA,YACT,WACE,UAAA,mBAAa,GAAA,CAAC,gBAAA,EAAA,EAAiB,IAAA,EAAM,IAAI,CAAA,GAAK,MAAA;AAAA,YAEjD,QAAA,EAAA;AAAA;AAAA,SAED;AAAA,QAGF,QAAA,kBAAA,IAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAgB,QAAA,EAAA;AAAA,UAAA,iDAAA;AAAA,UACa,GAAA;AAAA,UAC5C,oBAAA,CAAqB,MAAM,WAAW,CAAA;AAAA,UAAE,eAAA;AAAA,UAAW,KAAA,CAAM;AAAA,SAAA,EAC5D;AAAA;AAAA,KACF,EACF,CAAA;AAAA,oBAEA,GAAA,CAAC,QAAK,IAAA,EAAI,IAAA,EAAC,IAAI,EAAA,EACb,QAAA,kBAAA,IAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,gBAAA,EACd,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,UAAA;AAAA,UACN,KAAA,EAAO,YAAY,kCAAkC;AAAA;AAAA,OACvD;AAAA,sBACA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,eAAA;AAAA,UACN,KAAA,EACE,YAAY,iCAAiC,CAAA,IAC7C,OAAO,MAAA,CAAO,IAAA,EAAM,QAAQ,EAAE;AAAA;AAAA,OAElC;AAAA,sBACA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,QAAA;AAAA,UACN,KAAA,EAAO,WAAA,CAAY,gCAAgC,CAAA,IAAK;AAAA;AAAA,OAC1D;AAAA,sBACA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,SAAA;AAAA,UACN,KAAA,EAAO,YAAY,iCAAiC;AAAA;AAAA,OACtD;AAAA,0BACC,UAAA,EAAA,EAAW,KAAA,EAAM,oBAAA,EAAqB,KAAA,EAAO,MAAM,UAAA,EAAY,CAAA;AAAA,MAC/D,+BAAe,GAAA,CAAC,IAAA,EAAA,EAAK,EAAA,EAAI,WAAA,CAAY,KAAK,QAAA,EAAA,qBAAA,EAAmB;AAAA,KAAA,EAChE,CAAA,EACF,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,wBAAA,EAAA,EAAyB,MAAA,EAAgB,CAAA,EAC5C,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,sBAAA,EAAA,EAAuB,MAAA,EAAgB,CAAA,EAC1C,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EACb,QAAA,kBAAA,GAAA,CAAC,kBAAA,EAAA,EAAmB,OAAA,EAAS,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,WAAW,CAAA,EACjE,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,IAAI,EAAA,EACb,QAAA,kBAAA,GAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACC,SAAS,KAAA,CAAM,OAAA;AAAA,QACf,WAAA;AAAA,QACA,UAAA;AAAA,QACA;AAAA;AAAA,KACF,EACF,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,iBAAA,EAAA,EAAkB,OAAA,EAAS,KAAA,CAAM,YAAY,CAAA,EAChD,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,OAAA,EAAS,KAAA,CAAM,OAAO,CAAA,EACtC,CAAA;AAAA,IACC,UAAA,oBACC,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EACb,QAAA,kBAAA,GAAA,CAAC,eAAA,EAAA,EAAgB,OAAA,EAAQ,QAAA,EAAS,KAAA,EAAO,UAAU,CAAA,EACrD;AAAA,GAAA,EAEJ,CAAA;AAEJ;AAEA,MAAM,iBAAiB,CAAC;AAAA,EACtB,OAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA,KAKM;AACJ,EAAA,MAAM,EAAE,sBAAA,EAAwB,kBAAA,EAAmB,GACjD,2BAAA;AAAA,IACE,QAAQ,IAAA,EAAM,QAAA;AAAA,IACd,OAAA,CAAQ,IAAA,EAAM,KAAA,CAAM,MAAA,IAAU;AAAA,GAChC;AAEF,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,sBAAA,EACd,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA,OAAA,CAAQ,OAAA,IAAW,6CAAA,EACtB,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,2BACG,QAAA,EAAA,EAAS,KAAA,EAAM,sBAAA,EACd,QAAA,kBAAA,IAAA,CAAC,gBAAa,OAAA,EACX,QAAA,EAAA;AAAA,IAAA,eAAA,oBACC,GAAA,CAAC,SAAM,QAAA,EAAS,OAAA,EAAQ,OAAO,EAAE,YAAA,EAAc,CAAA,EAAE,EAC9C,QAAA,EAAA,eAAA,EACH,CAAA;AAAA,IAED,sBAAA,oBACC,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,YAAA,EAAW,kCAAA;AAAA,QACX,OAAA,EAAQ,SAAA;AAAA,QACR,KAAA,EAAM,eAAA;AAAA,QACN,OAAA,EAAQ,OAAA;AAAA,QACR,KAAA,EAAO,EAAE,YAAA,EAAc,CAAA,EAAE;AAAA,QAC1B,QAAA,EAAA;AAAA;AAAA,KAGD;AAAA,IAED,mBAAmB,GAAA,CAAI,CAAA,OAAA,qBACtB,GAAA,CAAC,KAAA,EAAA,EAAM,UAAS,SAAA,EAAwB,KAAA,EAAO,EAAE,YAAA,EAAc,GAAE,EAC9D,QAAA,EAAA,QAAA,CAAS,OAAO,CAAA,EAAA,EADY,OAE/B,CACD,CAAA;AAAA,IACA,OAAA,CAAQ,IAAA,EAAM,KAAA,EAAO,MAAA,GACpB,QAAQ,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,CAAA,KAAA,0BACpB,KAAA,EAAA,EAAmB,KAAA,EAAO,EAAE,YAAA,EAAc,IAAG,EAC5C,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,SAAQ,WAAA,EACjB,QAAA,EAAA,KAAA,CAAM,WAAW,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,EACvC,CAAA;AAAA,sBACA,IAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA;AAAA,QAAA,oBAAA,CAAqB,MAAM,SAAS,CAAA;AAAA,QAAE,QAAA;AAAA,QAAI,KAAA,CAAM,QAAA;AAAA,QAAS,OAAA;AAAA,QAAG,GAAA;AAAA,QAC5D,MAAM,QAAA,CAAS,MAAA;AAAA,QAAO,QAAA;AAAA,QAAI,MAAM,QAAA,CAAS,MAAA;AAAA,QACzC,KAAA,CAAM,KAAA,EAAO,IAAA,IAAQ,KAAA,CAAM,KAAA,EAAO,EAAA,GAC/B,CAAA,MAAA,EAAM,KAAA,CAAM,KAAA,CAAM,IAAA,IAAQ,KAAA,CAAM,KAAA,CAAM,EAAE,CAAA,CAAA,GACxC;AAAA,OAAA,EACN,CAAA;AAAA,MACC,MAAM,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAA,yBAC3B,SAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,aAAQ,QAAA,EAAA,8BAAA,EAA4B,CAAA;AAAA,4BACpC,IAAA,EAAA,EACE,QAAA,EAAA,KAAA,CAAM,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,KAAA,KAAS;AAChC,UAAA,MAAM,MAAA,GAAS,KAAA,CAAM,MAAA,CAAO,OAAA,CAAQ,IAAA;AAAA,YAClC,CAAA,SAAA,KAAa,UAAU,KAAA,KAAU;AAAA,WACnC;AACA,UAAA,4BACG,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,UAAM,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,YACZ,MAAA,GACG,KAAK,MAAA,CAAO,MAAA,IAAU,QAAG,CAAA,QAAA,EACvB,MAAA,CAAO,KAAA,IAAS,QAClB,CAAA,CAAA,GACA;AAAA,WAAA,EAAA,EANG,KAOT,CAAA;AAAA,QAEJ,CAAC,CAAA,EACH;AAAA,OAAA,EACF;AAAA,KAAA,EAAA,EA/BM,KAAA,CAAM,EAiChB,CACD,CAAA,uBAEA,UAAA,EAAA,EAAW,KAAA,EAAM,iBAAgB,QAAA,EAAA,6CAAA,EAElC,CAAA;AAAA,IAED,OAAA,CAAQ,IAAA,EAAM,IAAA,CAAK,OAAA,IAAW,UAAA,oBAC7B,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,OAAA;AAAA,QACL,OAAA,EAAS,UAAA;AAAA,QACT,QAAA,EAAU,WAAA;AAAA,QACV,WAAW,WAAA,mBAAc,GAAA,CAAC,gBAAA,EAAA,EAAiB,IAAA,EAAM,IAAI,CAAA,GAAK,MAAA;AAAA,QAC3D,QAAA,EAAA;AAAA;AAAA;AAED,GAAA,EAEJ,CAAA,EACF,CAAA;AAEJ,CAAA;AAEA,MAAM,0BAAA,uBAAiC,GAAA,CAAI;AAAA,EACzC,sBAAA;AAAA,EACA;AACF,CAAC,CAAA;AACD,MAAM,8BAAA,uBAAqC,GAAA,CAAI;AAAA,EAC7C,4BAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,SAAS,2BAAA,CACP,UACA,UAAA,EACA;AACA,EAAA,MAAM,WAAA,GAAc,YAAY,EAAC;AACjC,EAAA,OAAO;AAAA,IACL,wBAAwB,WAAA,CAAY,IAAA;AAAA,MAAK,CAAA,OAAA,KACvC,0BAAA,CAA2B,GAAA,CAAI,OAAO;AAAA,KACxC;AAAA,IACA,oBAAoB,WAAA,CAAY,MAAA;AAAA,MAC9B,CAAA,OAAA,KACE,CAAC,0BAAA,CAA2B,GAAA,CAAI,OAAO,CAAA,KACtC,UAAA,GAAa,CAAA,IAAK,CAAC,8BAAA,CAA+B,GAAA,CAAI,OAAO,CAAA;AAAA;AAClE,GACF;AACF;AAEA,MAAM,oBAAoB,CAAC;AAAA,EACzB;AACF,CAAA,KAEM;AACJ,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,gBAAA,EACd,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA,OAAA,CAAQ,OAAA,IACP,qDAAA,EACJ,CAAA,EACF,CAAA;AAAA,EAEJ;AACA,EAAA,uBACE,GAAA,CAAC,YAAS,KAAA,EAAM,gBAAA,EACd,8BAAC,YAAA,EAAA,EAAa,OAAA,EACX,QAAA,EAAA,OAAA,CAAQ,IAAA,EAAM,SAAA,EAAW,MAAA,GACxB,QAAQ,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,QAAA,qBACzB,IAAA,CAAC,SAAsC,KAAA,EAAO,EAAE,YAAA,EAAc,EAAA,EAAG,EAC/D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,WAAA,EACjB,QAAA,EAAA,QAAA,CAAS,UAAU,OAAA,EACtB,CAAA;AAAA,oBACA,GAAA,CAAC,QAAK,IAAA,EAAK,OAAA,EAAQ,OAAO,QAAA,CAAS,QAAA,CAAS,MAAM,CAAA,EAAG,CAAA;AAAA,oBACrD,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,MAAA;AAAA,QACN,KAAA,EAAO,QAAA,CAAS,SAAA,CAAU,OAAA,IAAW;AAAA;AAAA,KACvC;AAAA,oBACA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,aAAA;AAAA,QACN,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,MAAM;AAAA;AAAA,KACtC;AAAA,oBACA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,aAAA;AAAA,QACN,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,MAAM;AAAA;AAAA,KACtC;AAAA,IACC,QAAA,CAAS,UAAU,SAAA,oBAClB,GAAA,CAAC,QAAK,EAAA,EAAI,QAAA,CAAS,SAAA,CAAU,SAAA,EAAW,QAAA,EAAA,aAAA,EAAW;AAAA,GAAA,EAAA,EAlB7C,QAAA,CAAS,SAAA,CAAU,QAoB7B,CACD,CAAA,mBAED,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAgB,QAAA,EAAA,qDAAA,EAElC,CAAA,EAEJ,CAAA,EACF,CAAA;AAEJ,CAAA;AAEA,MAAM,eAAe,CAAC;AAAA,EACpB;AACF,CAAA,KAEM;AACJ,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,oBAAA,EACd,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA,OAAA,CAAQ,OAAA,IAAW,gDAAA,EACtB,CAAA,EACF,CAAA;AAAA,EAEJ;AACA,EAAA,uBACE,GAAA,CAAC,YAAS,KAAA,EAAM,oBAAA,EACd,8BAAC,YAAA,EAAA,EAAa,OAAA,EACX,QAAA,EAAA,OAAA,CAAQ,IAAA,EAAM,KAAA,EAAO,MAAA,GACpB,QAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,IAAA,qBACrB,IAAA,CAAC,SAAkC,KAAA,EAAO,EAAE,YAAA,EAAc,EAAA,EAAG,EAC3D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,WAAA,EACjB,QAAA,EAAA,IAAA,CAAK,UAAU,OAAA,EAClB,CAAA;AAAA,oBACA,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,OAAA;AAAA,QACL,KAAA,EAAO,IAAA,CAAK,MAAA,KAAW,SAAA,GAAY,WAAA,GAAc,SAAA;AAAA,QACjD,KAAA,EAAO,QAAA,CAAS,IAAA,CAAK,MAAM;AAAA;AAAA,KAC7B;AAAA,wBACC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA,IAAA,CAAK,WAAW,SAAA,GACb,CAAA,sBAAA,EAAyB,QAAA,CAAS,IAAA,CAAK,MAAM,CAAC,CAAA,CAAA,CAAA,GAC9C,CAAA,EAAG,IAAA,CAAK,cAAc,CAAA,2BAAA,CAAA,EAC5B,CAAA;AAAA,IACC,IAAA,CAAK,WAAA,CAAY,MAAA,GAAS,CAAA,yBACxB,SAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,aAAQ,QAAA,EAAA,4BAAA,EAA0B,CAAA;AAAA,0BAClC,IAAA,EAAA,EACE,QAAA,EAAA,IAAA,CAAK,YAAY,GAAA,CAAI,CAAA,UAAA,0BACnB,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAM,qBAAW,KAAA,EAAM,CAAA;AAAA,QAAO,GAAA;AAAA,QAAE,GAAA;AAAA,QAChC,WAAW,WAAA,IAAe,QAAA;AAAA,QAAI,SAAA;AAAA,QAAG,GAAA;AAAA,QACjC,WAAW,QAAA,IAAY;AAAA,OAAA,EAAA,EAHjB,UAAA,CAAW,KAIpB,CACD,CAAA,EACH;AAAA,KAAA,EACF;AAAA,GAAA,EAAA,EA1BM,IAAA,CAAK,SAAA,CAAU,QA4BzB,CACD,CAAA,mBAED,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAgB,QAAA,EAAA,gDAAA,EAElC,CAAA,EAEJ,CAAA,EACF,CAAA;AAEJ,CAAA;AAEA,MAAM,eAAe,CAAC;AAAA,EACpB,OAAA;AAAA,EACA;AACF,CAAA,KAGM;AACJ,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,OAAA,EAAS,kBAAQ,OAAA,EAAQ,CAAA;AAAA,EAClD;AACA,EAAA,IAAI,OAAA,CAAQ,UAAU,aAAA,EAAe;AACnC,IAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,MAAA,EAAQ,kBAAQ,OAAA,EAAQ,CAAA;AAAA,EACjD;AACA,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBAAO,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAiB,kBAAQ,OAAA,EAAQ,CAAA;AAAA,EAC5D;AACA,EAAA,uCAAU,QAAA,EAAS,CAAA;AACrB,CAAA;AAEA,MAAM,UAAA,GAAa,CAAC,EAAE,KAAA,EAAO,OAAM,qBACjC,IAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAS,IAAA,EACnB,QAAA,EAAA;AAAA,kBAAA,IAAA,CAAC,QAAA,EAAA,EAAQ,QAAA,EAAA;AAAA,IAAA,KAAA;AAAA,IAAM;AAAA,GAAA,EAAC,CAAA;AAAA,EAAS,GAAA;AAAA,EAAE,KAAA,IAAS;AAAA,CAAA,EACtC,CAAA;AAGF,SAAS,SAAS,KAAA,EAAuB;AACvC,EAAA,OAAO,KAAA,CAAM,UAAA,CAAW,GAAA,EAAK,GAAG,CAAA;AAClC;AAEO,SAAS,qBAAqB,KAAA,EAAuB;AAC1D,EAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AACxC,EAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,eAAe,CAAA,EAAG;AAClC,IAAA,OAAO,IAAI,IAAA,CAAK,eAAe,CAAA,CAAE,cAAA,EAAe;AAAA,EAClD;AAEA,EAAA,MAAM,oBAAA,GAAuB,KAAA,CAAM,OAAA,CAAQ,aAAA,EAAe,EAAE,CAAA;AAC5D,EAAA,MAAM,mBAAA,GAAsB,IAAA,CAAK,KAAA,CAAM,oBAAoB,CAAA;AAC3D,EAAA,OAAO,MAAA,CAAO,MAAM,mBAAmB,CAAA,GACnC,QACA,IAAI,IAAA,CAAK,mBAAmB,CAAA,CAAE,cAAA,EAAe;AACnD;;;;"}
1
+ {"version":3,"file":"CloudResourceContent.esm.js","sources":["../../../src/components/cloud/CloudResourceContent.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport {\n Button,\n Chip,\n CircularProgress,\n Grid,\n Typography,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport { InfoCard, Link, Progress } from '@backstage/core-components';\nimport { useApi } from '@backstage/frontend-plugin-api';\nimport type { Entity } from '@backstage/catalog-model';\nimport {\n ANYSHIFT_CLOUD_ACCOUNT_ANNOTATION,\n ANYSHIFT_CLOUD_PROVIDER_ANNOTATION,\n ANYSHIFT_CLOUD_REGION_ANNOTATION,\n ANYSHIFT_RESOURCE_TYPE_ANNOTATION,\n type BriefSection,\n type CloudEventsEvidence,\n type CloudResourceBrief,\n type IacDriftEvidence,\n type IacEvidence,\n} from '@anyshift/backstage-plugin-anyshift-common';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { anyshiftApiRef } from '../../api/AnyshiftApi';\nimport { AskAnyshiftCard } from '../ask/AskAnyshiftCard';\nimport { askScopeForEntity } from '../ask/askScope';\nimport type { AnyshiftCapabilities, AskScope } from '../../api/types';\nimport {\n cloudResourceFallbackIdentity,\n cloudResourceIdentity,\n} from '../entity/entityIdentity';\nimport { CloudImpactSection } from './CloudImpactSection';\nimport {\n CloudDependenciesSection,\n CloudDependentsSection,\n} from './CloudRelationshipSections';\n\nexport const CloudResourceContent = () => <CloudResourceEvidenceContent />;\n\nexport const CloudAnyshiftEntityContent = () => (\n <CloudResourceEvidenceContent includeAsk />\n);\n\nconst CloudResourceEvidenceContent = ({ includeAsk = false }) => {\n const { entity } = useEntity();\n const api = useApi(anyshiftApiRef);\n const resourceId = cloudResourceIdentity(entity);\n const fallbackResource = cloudResourceFallbackIdentity(entity);\n const [loadedBrief, setLoadedBrief] = useState<{\n resourceId: string;\n value: CloudResourceBrief;\n }>();\n const brief =\n loadedBrief && loadedBrief.resourceId === resourceId\n ? loadedBrief.value\n : undefined;\n const [error, setError] = useState<string>();\n const [refreshing, setRefreshing] = useState(false);\n const [loadingMore, setLoadingMore] = useState(false);\n const [paginationError, setPaginationError] = useState<string>();\n const [capabilities, setCapabilities] = useState<AnyshiftCapabilities>({\n askEnabled: false,\n queryEnabled: false,\n });\n const operations = useRef({ identity: 0, primary: 0, pagination: 0 });\n const askScope = useMemo(\n () => (includeAsk ? askScopeForEntity(entity) : undefined),\n [entity, includeAsk],\n );\n\n useLayoutEffect(() => {\n operations.current.identity += 1;\n operations.current.primary += 1;\n operations.current.pagination += 1;\n setLoadedBrief(undefined);\n setError(undefined);\n setRefreshing(false);\n setLoadingMore(false);\n setPaginationError(undefined);\n }, [resourceId]);\n\n const load = useCallback(\n async (refresh = false) => {\n if (!resourceId) return;\n const identity = operations.current.identity;\n const primary = ++operations.current.primary;\n ++operations.current.pagination;\n setRefreshing(refresh);\n setLoadingMore(false);\n setPaginationError(undefined);\n setError(undefined);\n try {\n const next = await api.cloudResourceBrief(resourceId, {\n ...(fallbackResource ? { fallbackResource } : {}),\n since: '24h',\n diff: true,\n ...(refresh ? { refresh: true } : {}),\n });\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary\n ) {\n ++operations.current.pagination;\n setLoadingMore(false);\n setLoadedBrief({ resourceId, value: next });\n }\n } catch (loadError) {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary\n ) {\n ++operations.current.pagination;\n setLoadingMore(false);\n setError(\n loadError instanceof Error\n ? loadError.message\n : 'Unable to load cloud evidence',\n );\n }\n } finally {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary\n ) {\n setRefreshing(false);\n }\n }\n },\n [api, fallbackResource, resourceId],\n );\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!includeAsk) return undefined;\n let active = true;\n api\n .capabilities()\n .then(next => active && setCapabilities(next))\n .catch(\n () =>\n active && setCapabilities({ askEnabled: false, queryEnabled: false }),\n );\n return () => {\n active = false;\n };\n }, [api, includeAsk]);\n\n const loadMore = useCallback(async () => {\n const cursor = brief?.changes.data?.page.nextCursor;\n if (!resourceId || !cursor) return;\n const identity = operations.current.identity;\n const primary = operations.current.primary;\n const pagination = ++operations.current.pagination;\n setLoadingMore(true);\n setPaginationError(undefined);\n try {\n const next = await api.cloudResourceBrief(resourceId, {\n ...(fallbackResource ? { fallbackResource } : {}),\n since: brief.since,\n diff: true,\n cursor,\n });\n if (\n operations.current.identity !== identity ||\n operations.current.primary !== primary ||\n operations.current.pagination !== pagination\n ) {\n return;\n }\n if (next.changes.state === 'error') {\n setPaginationError(\n next.changes.message || 'Unable to load more cloud changes',\n );\n return;\n }\n if (next.changes.state === 'data' && next.changes.data) {\n setPaginationError(undefined);\n }\n setLoadedBrief(current => {\n if (\n !current ||\n current.resourceId !== resourceId ||\n !current.value.changes.data ||\n next.changes.state !== 'data' ||\n !next.changes.data\n ) {\n return current;\n }\n return {\n resourceId,\n value: {\n ...current.value,\n refreshedAt: next.refreshedAt,\n changes: {\n state: 'data',\n data: mergeCloudEventsEvidence(\n current.value.changes.data,\n next.changes.data,\n ),\n },\n },\n };\n });\n } catch (loadError) {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary &&\n operations.current.pagination === pagination\n ) {\n setPaginationError(\n loadError instanceof Error\n ? loadError.message\n : 'Unable to load more cloud changes',\n );\n }\n } finally {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary &&\n operations.current.pagination === pagination\n ) {\n setLoadingMore(false);\n }\n }\n }, [api, brief, fallbackResource, resourceId]);\n\n if (!resourceId) {\n return (\n <Alert severity=\"info\">\n This catalog entity has no stable Anyshift resource ID or cloud ARN.\n </Alert>\n );\n }\n if (error && !brief) {\n return (\n <Alert severity=\"error\">\n {error} <Button onClick={() => void load(true)}>Retry</Button>\n </Alert>\n );\n }\n if (!brief) return <Progress />;\n\n return (\n <CloudResourceBriefView\n entity={entity}\n brief={brief}\n refreshing={refreshing}\n onRefresh={() => void load(true)}\n loadingMore={loadingMore}\n onLoadMore={() => void loadMore()}\n error={error}\n paginationError={paginationError}\n askEnabled={includeAsk && capabilities.askEnabled && Boolean(askScope)}\n askScope={askScope}\n />\n );\n};\n\nexport function mergeCloudEventsEvidence(\n current: CloudEventsEvidence,\n next: CloudEventsEvidence,\n): CloudEventsEvidence {\n return {\n ...next,\n availability: mergeCloudEventAvailability(\n current.availability,\n next.availability,\n ),\n warnings: [...new Set([...current.warnings, ...next.warnings])],\n items: [...current.items, ...next.items],\n };\n}\n\nfunction mergeCloudEventAvailability(\n current: Record<string, string>,\n next: Record<string, string>,\n): Record<string, string> {\n const availability: Record<string, string> = {};\n for (const field of new Set([\n ...Object.keys(current),\n ...Object.keys(next),\n ])) {\n availability[field] = leastCompleteAvailability(\n current[field],\n next[field],\n );\n }\n return availability;\n}\n\nfunction leastCompleteAvailability(\n current: string | undefined,\n next: string | undefined,\n): string {\n const normalizedCurrent = normalizeAvailability(current);\n const normalizedNext = normalizeAvailability(next);\n return AVAILABILITY_RANK[normalizedCurrent] <=\n AVAILABILITY_RANK[normalizedNext]\n ? normalizedCurrent\n : normalizedNext;\n}\n\nconst AVAILABILITY_RANK: Record<string, number> = {\n unavailable: 0,\n partial: 1,\n available: 2,\n};\n\nfunction normalizeAvailability(value: string | undefined): string {\n return value && value in AVAILABILITY_RANK ? value : 'unavailable';\n}\n\nexport const CloudResourceBriefView = ({\n entity,\n brief,\n refreshing,\n onRefresh,\n loadingMore,\n onLoadMore,\n error,\n paginationError,\n askEnabled = false,\n askScope,\n}: {\n entity: Entity;\n brief: CloudResourceBrief;\n refreshing?: boolean;\n onRefresh: () => void;\n loadingMore?: boolean;\n onLoadMore?: () => void;\n error?: string;\n paginationError?: string;\n askEnabled?: boolean;\n askScope?: AskScope;\n}) => {\n const annotations = entity.metadata.annotations ?? {};\n const consoleLink = entity.metadata.links?.find(link =>\n link.url.startsWith('https://console.aws.amazon.com/'),\n );\n\n return (\n <Grid container spacing={3}>\n {error && (\n <Grid item xs={12}>\n <Alert severity=\"error\">{error}</Alert>\n </Grid>\n )}\n <Grid item xs={12}>\n <InfoCard\n title=\"Cloud evidence\"\n action={\n <Button\n size=\"small\"\n onClick={onRefresh}\n startIcon={\n refreshing ? <CircularProgress size={14} /> : undefined\n }\n >\n Refresh\n </Button>\n }\n >\n <Typography color=\"textSecondary\">\n Read-only Anyshift evidence · last refreshed{' '}\n {formatCloudTimestamp(brief.refreshedAt)} · window {brief.since}\n </Typography>\n </InfoCard>\n </Grid>\n\n <Grid item xs={12}>\n <InfoCard title=\"Cloud identity\">\n <Definition\n label=\"Provider\"\n value={annotations[ANYSHIFT_CLOUD_PROVIDER_ANNOTATION]}\n />\n <Definition\n label=\"Resource type\"\n value={\n annotations[ANYSHIFT_RESOURCE_TYPE_ANNOTATION] ||\n String(entity.spec?.type || '')\n }\n />\n <Definition\n label=\"Region\"\n value={annotations[ANYSHIFT_CLOUD_REGION_ANNOTATION] || 'Global'}\n />\n <Definition\n label=\"Account\"\n value={annotations[ANYSHIFT_CLOUD_ACCOUNT_ANNOTATION]}\n />\n <Definition label=\"Stable resource ID\" value={brief.resourceId} />\n {consoleLink && <Link to={consoleLink.url}>Open in AWS Console</Link>}\n </InfoCard>\n </Grid>\n <Grid item xs={12} md={6}>\n <CloudDependenciesSection entity={entity} />\n </Grid>\n <Grid item xs={12} md={6}>\n <CloudDependentsSection entity={entity} />\n </Grid>\n <Grid item xs={12}>\n <CloudImpactSection section={brief.impact} onRetry={onRefresh} />\n </Grid>\n <Grid item xs={12}>\n <ChangesSection\n section={brief.changes}\n loadingMore={loadingMore}\n onLoadMore={onLoadMore}\n paginationError={paginationError}\n />\n </Grid>\n <Grid item xs={12} md={6}>\n <ProvenanceSection section={brief.provenance} />\n </Grid>\n <Grid item xs={12} md={6}>\n <DriftSection section={brief.drift} />\n </Grid>\n {askEnabled && (\n <Grid item xs={12}>\n <AskAnyshiftCard context=\"entity\" scope={askScope} />\n </Grid>\n )}\n </Grid>\n );\n};\n\nconst ChangesSection = ({\n section,\n loadingMore,\n onLoadMore,\n paginationError,\n}: {\n section: BriefSection<CloudEventsEvidence>;\n loadingMore?: boolean;\n onLoadMore?: () => void;\n paginationError?: string;\n}) => {\n const { hasEvidenceLimitations, actionableWarnings } =\n partitionCloudEventWarnings(\n section.data?.warnings,\n section.data?.items.length ?? 0,\n );\n\n if (section.state === 'empty') {\n return (\n <InfoCard title=\"Recent cloud changes\">\n <Typography color=\"textSecondary\">\n {section.message || 'No cloud changes were found in this window.'}\n </Typography>\n </InfoCard>\n );\n }\n\n return (\n <InfoCard title=\"Recent cloud changes\">\n <SectionState section={section}>\n {paginationError && (\n <Alert severity=\"error\" style={{ marginBottom: 8 }}>\n {paginationError}\n </Alert>\n )}\n {hasEvidenceLimitations && (\n <Typography\n aria-label=\"Cloud event evidence limitations\"\n variant=\"caption\"\n color=\"textSecondary\"\n display=\"block\"\n style={{ marginBottom: 8 }}\n >\n Event source is derived from graph relationships, and event status\n may be incomplete.\n </Typography>\n )}\n {actionableWarnings.map(warning => (\n <Alert severity=\"warning\" key={warning} style={{ marginBottom: 8 }}>\n {humanize(warning)}\n </Alert>\n ))}\n {section.data?.items?.length ? (\n section.data.items.map(event => (\n <div key={event.id} style={{ marginBottom: 20 }}>\n <Typography variant=\"subtitle1\">\n {event.summary || humanize(event.type)}\n </Typography>\n <Typography color=\"textSecondary\">\n {formatCloudTimestamp(event.timestamp)} · {event.category} ·{' '}\n {event.evidence.source} · {event.evidence.status}\n {event.actor?.name || event.actor?.id\n ? ` · ${event.actor.name || event.actor.id}`\n : ''}\n </Typography>\n {event.change.fields.length > 0 && (\n <details>\n <summary>View sanitized field changes</summary>\n <ul>\n {event.change.fields.map(field => {\n const detail = event.change.details.find(\n candidate => candidate.field === field,\n );\n return (\n <li key={field}>\n <code>{field}</code>\n {detail\n ? `: ${detail.before ?? '∅'} → ${\n detail.after ?? '∅'\n }`\n : ''}\n </li>\n );\n })}\n </ul>\n </details>\n )}\n </div>\n ))\n ) : (\n <Typography color=\"textSecondary\">\n No cloud changes were found in this window.\n </Typography>\n )}\n {section.data?.page.hasMore && onLoadMore && (\n <Button\n size=\"small\"\n onClick={onLoadMore}\n disabled={loadingMore}\n startIcon={loadingMore ? <CircularProgress size={14} /> : undefined}\n >\n Load more changes\n </Button>\n )}\n </SectionState>\n </InfoCard>\n );\n};\n\nconst QUIET_EVIDENCE_LIMITATIONS = new Set([\n 'event_source_derived',\n 'event_status_incomplete',\n]);\nconst IDENTITY_COMPLETENESS_WARNINGS = new Set([\n 'target_identity_incomplete',\n 'actor_identity_incomplete',\n]);\n\nfunction partitionCloudEventWarnings(\n warnings: string[] | undefined,\n eventCount: number,\n) {\n const allWarnings = warnings ?? [];\n return {\n hasEvidenceLimitations: allWarnings.some(warning =>\n QUIET_EVIDENCE_LIMITATIONS.has(warning),\n ),\n actionableWarnings: allWarnings.filter(\n warning =>\n !QUIET_EVIDENCE_LIMITATIONS.has(warning) &&\n (eventCount > 0 || !IDENTITY_COMPLETENESS_WARNINGS.has(warning)),\n ),\n };\n}\n\nconst ProvenanceSection = ({\n section,\n}: {\n section: BriefSection<IacEvidence>;\n}) => {\n if (section.state === 'empty') {\n return (\n <InfoCard title=\"IaC provenance\">\n <Typography color=\"textSecondary\">\n {section.message ||\n 'No Terraform provenance is linked to this resource.'}\n </Typography>\n </InfoCard>\n );\n }\n return (\n <InfoCard title=\"IaC provenance\">\n <SectionState section={section}>\n {section.data?.resources?.length ? (\n section.data.resources.map(resource => (\n <div key={resource.terraform.hashedID} style={{ marginBottom: 16 }}>\n <Typography variant=\"subtitle1\">\n {resource.terraform.address}\n </Typography>\n <Chip size=\"small\" label={humanize(resource.status)} />\n <Definition\n label=\"File\"\n value={resource.terraform.fileRef ?? ''}\n />\n <Definition\n label=\"State links\"\n value={String(resource.states.length)}\n />\n <Definition\n label=\"Cloud links\"\n value={String(resource.clouds.length)}\n />\n {resource.terraform.githubUrl && (\n <Link to={resource.terraform.githubUrl}>Open source</Link>\n )}\n </div>\n ))\n ) : (\n <Typography color=\"textSecondary\">\n No Terraform provenance is linked to this resource.\n </Typography>\n )}\n </SectionState>\n </InfoCard>\n );\n};\n\nconst DriftSection = ({\n section,\n}: {\n section: BriefSection<IacDriftEvidence>;\n}) => {\n if (section.state === 'empty') {\n return (\n <InfoCard title=\"IaC drift evidence\">\n <Typography color=\"textSecondary\">\n {section.message || 'No comparable Terraform evidence is available.'}\n </Typography>\n </InfoCard>\n );\n }\n return (\n <InfoCard title=\"IaC drift evidence\">\n <SectionState section={section}>\n {section.data?.items?.length ? (\n section.data.items.map(item => (\n <div key={item.terraform.hashedID} style={{ marginBottom: 16 }}>\n <Typography variant=\"subtitle1\">\n {item.terraform.address}\n </Typography>\n <Chip\n size=\"small\"\n color={item.status === 'drifted' ? 'secondary' : 'default'}\n label={humanize(item.status)}\n />\n <Typography color=\"textSecondary\">\n {item.status === 'unknown'\n ? `Unknown is not drift: ${humanize(item.reason)}.`\n : `${item.comparedFields} supported fields compared.`}\n </Typography>\n {item.differences.length > 0 && (\n <details>\n <summary>View sanitized differences</summary>\n <ul>\n {item.differences.map(difference => (\n <li key={difference.field}>\n <code>{difference.field}</code>:{' '}\n {difference.lastApplied ?? '∅'} →{' '}\n {difference.observed ?? '∅'}\n </li>\n ))}\n </ul>\n </details>\n )}\n </div>\n ))\n ) : (\n <Typography color=\"textSecondary\">\n No comparable Terraform evidence is available.\n </Typography>\n )}\n </SectionState>\n </InfoCard>\n );\n};\n\nconst SectionState = ({\n section,\n children,\n}: {\n section: BriefSection;\n children: ReactNode;\n}) => {\n if (section.state === 'error') {\n return <Alert severity=\"error\">{section.message}</Alert>;\n }\n if (section.state === 'unsupported') {\n return <Alert severity=\"info\">{section.message}</Alert>;\n }\n if (section.state === 'empty') {\n return <Typography color=\"textSecondary\">{section.message}</Typography>;\n }\n return <>{children}</>;\n};\n\nconst Definition = ({ label, value }: { label: string; value?: string }) => (\n <Typography paragraph>\n <strong>{label}:</strong> {value || 'Not available'}\n </Typography>\n);\n\nfunction humanize(value: string): string {\n return value.replaceAll('_', ' ');\n}\n\nexport function formatCloudTimestamp(value: string): string {\n const directTimestamp = Date.parse(value);\n if (!Number.isNaN(directTimestamp)) {\n return new Date(directTimestamp).toLocaleString();\n }\n\n const withoutBracketedZone = value.replace(/\\[[^\\]]+\\]$/, '');\n const normalizedTimestamp = Date.parse(withoutBracketedZone);\n return Number.isNaN(normalizedTimestamp)\n ? value\n : new Date(normalizedTimestamp).toLocaleString();\n}\n"],"names":[],"mappings":"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"}
@@ -9,6 +9,16 @@ function cloudResourceIdentity(entity) {
9
9
  const annotations = entity.metadata.annotations ?? {};
10
10
  return annotationValue(annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION]) ?? annotationValue(annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION]);
11
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
+ }
12
22
  function cloudResourceAskTarget(entity) {
13
23
  const annotations = entity.metadata.annotations ?? {};
14
24
  return annotationValue(annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION]) ?? annotationValue(annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION]);
@@ -26,5 +36,5 @@ function annotationValue(value) {
26
36
  return trimmed || void 0;
27
37
  }
28
38
 
29
- export { cloudResourceAskTarget, cloudResourceIdentity, entityTarget, isCloudResourceEntity };
39
+ export { cloudResourceAskTarget, cloudResourceFallbackIdentity, cloudResourceIdentity, entityTarget, isCloudResourceEntity };
30
40
  //# sourceMappingURL=entityIdentity.esm.js.map
@@ -1 +1 @@
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 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,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
+ {"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;;;;"}
package/dist/index.d.ts CHANGED
@@ -211,6 +211,7 @@ interface BriefRequestOptions {
211
211
  configurationTarget?: string;
212
212
  }
213
213
  interface CloudResourceBriefRequestOptions {
214
+ fallbackResource?: string;
214
215
  since?: string;
215
216
  cursor?: string;
216
217
  diff?: boolean;
@@ -1,5 +1,5 @@
1
1
  var name = "@anyshift/backstage-plugin-anyshift";
2
- var version = "0.1.0-beta.15";
2
+ var version = "0.1.0-beta.16";
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.15",
3
+ "version": "0.1.0-beta.16",
4
4
  "description": "Read-only Anyshift infrastructure context for Backstage",
5
5
  "main": "dist/index.esm.js",
6
6
  "types": "dist/index.d.ts",