@pagerduty/backstage-plugin-backend 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/apis/pagerduty.cjs.js +285 -0
- package/dist/apis/pagerduty.cjs.js.map +1 -1
- package/dist/auth/auth.cjs.js +5 -4
- package/dist/auth/auth.cjs.js.map +1 -1
- package/dist/controllers/mappings-controller.cjs.js +388 -0
- package/dist/controllers/mappings-controller.cjs.js.map +1 -0
- package/dist/db/PagerDutyBackendDatabase.cjs.js +16 -0
- package/dist/db/PagerDutyBackendDatabase.cjs.js.map +1 -1
- package/dist/index.cjs.js +0 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -5
- package/dist/service/router.cjs.js +197 -46
- package/dist/service/router.cjs.js.map +1 -1
- package/dist/services/dataLoader.cjs.js +2 -1
- package/dist/services/dataLoader.cjs.js.map +1 -1
- package/dist/services/pagerduty/index.cjs.js +11 -0
- package/dist/services/pagerduty/index.cjs.js.map +1 -0
- package/dist/utils/catalog-entity.cjs.js +50 -0
- package/dist/utils/catalog-entity.cjs.js.map +1 -0
- package/dist/utils/normalization.cjs.js +3 -2
- package/dist/utils/normalization.cjs.js.map +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["import {\n AuthService,\n DiscoveryService,\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport {\n createLegacyAuthAdapters,\n errorHandler,\n} from '@backstage/backend-common';\nimport {\n getAllEscalationPolicies,\n getChangeEvents,\n getIncidents,\n getOncallUsers,\n getServiceById,\n getServiceByIntegrationKey,\n getServiceStandards,\n getServiceMetrics,\n getAllServices,\n loadPagerDutyEndpointsFromConfig,\n createServiceIntegration,\n getServiceRelationshipsById,\n addServiceRelationsToService,\n removeServiceRelationsFromService,\n} from '../apis/pagerduty';\nimport { loadBothSources, ServiceLoadError } from '../services/dataLoader';\nimport {\n findMatches,\n filterToBestMatchPerService,\n type MatchingConfig,\n} from '../services/matchingEngine';\nimport {\n HttpError,\n PagerDutyChangeEventsResponse,\n PagerDutyIncidentsResponse,\n PagerDutyOnCallUsersResponse,\n PagerDutyServiceResponse,\n PagerDutyServiceStandardsResponse,\n PagerDutyServiceMetricsResponse,\n PagerDutyServicesResponse,\n PagerDutyEntityMapping,\n PagerDutyEntityMappingsResponse,\n PagerDutyService,\n PagerDutyServiceDependency,\n PagerDutySetting,\n} from '@pagerduty/backstage-plugin-common';\nimport { loadAuthConfig } from '../auth/auth';\nimport {\n PagerDutyBackendStore,\n RawDbEntityResultRow,\n} from '../db/PagerDutyBackendDatabase';\nimport * as express from 'express';\nimport Router from 'express-promise-router';\nimport type {\n CatalogApi,\n GetEntitiesResponse,\n} from '@backstage/catalog-client';\n\nexport interface RouterOptions {\n logger: LoggerService;\n config: RootConfigService;\n store: PagerDutyBackendStore;\n discovery: DiscoveryService;\n auth?: AuthService;\n catalogApi?: CatalogApi;\n}\n\nexport type Annotations = {\n 'pagerduty.com/integration-key': string;\n 'pagerduty.com/service-id': string;\n 'pagerduty.com/account': string;\n};\n\nexport async function createComponentEntitiesReferenceDict({\n items: componentEntities,\n}: GetEntitiesResponse): Promise<\n Record<string, { ref: string; name: string }>\n> {\n const componentEntitiesDict: Record<string, { ref: string; name: string }> =\n {};\n\n await Promise.all(\n componentEntities.map(async entity => {\n const serviceId =\n entity.metadata.annotations?.['pagerduty.com/service-id'];\n const integrationKey =\n entity.metadata.annotations?.['pagerduty.com/integration-key'];\n const account = entity.metadata.annotations?.['pagerduty.com/account'];\n\n if (serviceId !== undefined && serviceId !== '') {\n componentEntitiesDict[serviceId] = {\n ref: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase(),\n name: entity.metadata.name,\n };\n } else if (integrationKey !== undefined && integrationKey !== '') {\n // get service id from integration key, we ignore errors here since we're focused\n // only on building a mapping between valid service IDs and the corresponding Backstage entity\n const service = await getServiceByIntegrationKey(\n integrationKey,\n account,\n ).catch(() => undefined);\n\n if (service !== undefined) {\n componentEntitiesDict[service.id] = {\n ref: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase(),\n name: entity.metadata.name,\n };\n }\n }\n }),\n );\n\n return componentEntitiesDict;\n}\n\nexport async function buildEntityMappingsResponse(\n entityMappings: RawDbEntityResultRow[],\n componentEntitiesDict: Record<\n string,\n {\n ref: string;\n name: string;\n }\n >,\n componentEntities: GetEntitiesResponse,\n pagerDutyServices: PagerDutyService[],\n): Promise<PagerDutyEntityMappingsResponse> {\n const result: PagerDutyEntityMappingsResponse = {\n mappings: [],\n };\n\n pagerDutyServices.forEach(service => {\n // Check for service mapping annotation in any entity config file and get the entity ref\n const entityRef = componentEntitiesDict[service.id]?.ref;\n const entityName = componentEntitiesDict[service.id]?.name;\n\n // Check if the service is mapped to an entity in the database\n const entityMapping = entityMappings.find(\n mapping => mapping.serviceId === service.id,\n );\n\n if (entityMapping) {\n if (entityRef === undefined) {\n if (\n entityMapping.entityRef === '' ||\n entityMapping.entityRef === undefined\n ) {\n result.mappings.push({\n entityRef: '',\n entityName: '',\n integrationKey: entityMapping.integrationKey,\n serviceId: entityMapping.serviceId,\n status: 'NotMapped',\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? '',\n escalationPolicy:\n service.escalation_policy !== undefined\n ? service.escalation_policy.name\n : '',\n serviceUrl: service.html_url,\n account: service.account,\n });\n } else {\n const entityRefName =\n componentEntities.items.find(\n entity =>\n `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase() ===\n entityMapping.entityRef,\n )?.metadata.name ?? '';\n\n result.mappings.push({\n entityRef: entityMapping.entityRef,\n entityName: entityRefName,\n serviceId: entityMapping.serviceId,\n integrationKey: entityMapping.integrationKey,\n status: 'OutOfSync',\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? '',\n escalationPolicy:\n service.escalation_policy !== undefined\n ? service.escalation_policy.name\n : '',\n serviceUrl: service.html_url,\n account: service.account,\n });\n }\n } else if (entityRef !== entityMapping.entityRef) {\n const entityRefName =\n componentEntities.items.find(\n entity =>\n `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase() ===\n entityMapping.entityRef,\n )?.metadata.name ?? '';\n\n result.mappings.push({\n entityRef:\n entityMapping.entityRef !== '' ? entityMapping.entityRef : '',\n entityName: entityMapping.entityRef !== '' ? entityRefName : '',\n serviceId: entityMapping.serviceId,\n integrationKey: entityMapping.integrationKey,\n status: 'OutOfSync',\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? '',\n escalationPolicy:\n service.escalation_policy !== undefined\n ? service.escalation_policy.name\n : '',\n serviceUrl: service.html_url,\n account: service.account,\n });\n } else if (entityRef === entityMapping.entityRef) {\n result.mappings.push({\n entityRef:\n entityMapping.entityRef !== '' ? entityMapping.entityRef : '',\n entityName: entityMapping.entityRef !== '' ? entityName : '',\n serviceId: entityMapping.serviceId,\n integrationKey: entityMapping.integrationKey,\n status: 'InSync',\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? '',\n escalationPolicy:\n service.escalation_policy !== undefined\n ? service.escalation_policy.name\n : '',\n serviceUrl: service.html_url,\n account: service.account,\n });\n }\n } else {\n const backstageVendorId = 'PRO19CT';\n const backstageIntegrationKey =\n service.integrations?.find(\n integration => integration.vendor?.id === backstageVendorId,\n )?.integration_key ?? '';\n\n if (entityRef !== undefined) {\n result.mappings.push({\n entityRef: entityRef,\n entityName: entityName,\n serviceId: service.id,\n integrationKey: backstageIntegrationKey,\n status: 'InSync',\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? '',\n escalationPolicy:\n service.escalation_policy !== undefined\n ? service.escalation_policy.name\n : '',\n serviceUrl: service.html_url,\n account: service.account,\n });\n } else {\n result.mappings.push({\n entityRef: '',\n entityName: '',\n serviceId: service.id,\n integrationKey: backstageIntegrationKey,\n status: 'NotMapped',\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? '',\n escalationPolicy:\n service.escalation_policy !== undefined\n ? service.escalation_policy.name\n : '',\n serviceUrl: service.html_url,\n account: service.account,\n });\n }\n }\n });\n\n const sortedResult = result.mappings.sort((a, b) => {\n if (a.serviceName! < b.serviceName!) {\n return -1;\n } else if (a.serviceName! > b.serviceName!) {\n return 1;\n }\n return 0;\n });\n\n result.mappings = sortedResult;\n\n return result;\n}\n\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { logger, config, store, catalogApi } = options;\n let { auth } = options;\n\n if (!auth) {\n auth = createLegacyAuthAdapters(options).auth;\n }\n\n // Get authentication Config\n await loadAuthConfig(config, logger);\n\n // Get optional PagerDuty custom endpoints from config\n loadPagerDutyEndpointsFromConfig(config, logger);\n\n // Create the router\n const router = Router();\n router.use(express.json());\n\n // DELETE /dependencies/service/:serviceId\n router.delete(\n '/dependencies/service/:serviceId',\n async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n if (serviceId === '') {\n response\n .status(400)\n .json(\n \"Bad Request: ':serviceId' must be provided as part of the path\",\n );\n return;\n }\n\n const dependencies: string[] =\n Object.keys(request.body).length === 0 ? [] : request.body;\n if (!dependencies || dependencies.length === 0) {\n response\n .status(400)\n .json(\n \"Bad Request: 'dependencies' must be provided as part of the request body\",\n );\n return;\n }\n\n const serviceRelations: PagerDutyServiceDependency[] = [];\n\n dependencies.forEach(async dependency => {\n serviceRelations.push({\n supporting_service: {\n id: dependency,\n type: 'service',\n },\n dependent_service: {\n id: serviceId,\n type: 'service',\n },\n });\n });\n\n await removeServiceRelationsFromService(serviceRelations, account);\n\n response.sendStatus(200);\n } catch (error) {\n if (error instanceof HttpError) {\n logger.error(\n `Error occurred while processing request: ${error.message}`,\n );\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n },\n );\n\n // POST /dependencies/service/:serviceId\n router.post('/dependencies/service/:serviceId', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n if (serviceId === '') {\n response\n .status(400)\n .json(\n \"Bad Request: ':serviceId' must be provided as part of the path\",\n );\n return;\n }\n\n const dependencies: string[] =\n Object.keys(request.body).length === 0 ? [] : request.body;\n if (!dependencies || dependencies.length === 0) {\n response\n .status(400)\n .json(\n \"Bad Request: 'dependencies' must be provided as part of the request body\",\n );\n return;\n }\n\n const serviceRelations: PagerDutyServiceDependency[] = [];\n\n dependencies.forEach(async dependency => {\n serviceRelations.push({\n supporting_service: {\n id: dependency,\n type: 'service',\n },\n dependent_service: {\n id: serviceId,\n type: 'service',\n },\n });\n });\n\n await addServiceRelationsToService(serviceRelations, account);\n\n response.sendStatus(200);\n } catch (error) {\n if (error instanceof HttpError) {\n logger.error(\n `Error occurred while processing request: ${error.message}`,\n );\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n router.get('/dependencies/service/:serviceId', async (request, response) => {\n try {\n const serviceId = request.params.serviceId;\n const account = (request.query.account as string) || '';\n\n if (serviceId) {\n const serviceRelationships: PagerDutyServiceDependency[] =\n await getServiceRelationshipsById(serviceId, account);\n\n if (serviceRelationships) {\n response.json({\n relationships: serviceRelationships,\n });\n }\n } else {\n response\n .status(400)\n .json(\n \"Bad Request: ':serviceId' must be provided as part of the path\",\n );\n }\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /catalog/entity/:entityRef\n router.get(\n '/catalog/entity/:type/:namespace/:name',\n async (request, response) => {\n const type = request.params.type;\n const namespace = request.params.namespace;\n const name = request.params.name;\n\n try {\n if (type && namespace && name) {\n const entityRef = `${type}:${namespace}/${name}`.toLowerCase();\n const foundEntity = await catalogApi?.getEntityByRef(entityRef);\n\n if (foundEntity) {\n response.json(\n foundEntity.metadata.annotations?.['pagerduty.com/service-id'],\n );\n } else {\n response.status(404);\n }\n } else {\n response\n .status(400)\n .json(\n \"Bad Request: ':entityRef' must be provided as part of the path\",\n );\n }\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n },\n );\n\n // POST /settings\n router.post('/settings', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const settings: PagerDutySetting[] = request.body;\n\n // For each setting, update or insert the value in the database\n await Promise.all(\n settings.map(async setting => {\n if (setting.id === undefined || setting.value === undefined) {\n response\n .status(400)\n .json(\"Bad Request: 'id' and 'value' are required\");\n return;\n }\n\n if (!isValidSetting(setting.value)) {\n response\n .status(400)\n .json(\n \"Bad Request: 'value' is invalid. Valid options are 'backstage', 'pagerduty', 'both' or 'disabled'\",\n );\n return;\n }\n\n await store.updateSetting(setting);\n }),\n );\n\n response.sendStatus(200);\n } catch (error) {\n if (error instanceof HttpError) {\n logger.error(\n `Error occurred while processing request: ${error.message}`,\n );\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /settings/:settingId\n router.get('/settings/:settingId', async (request, response) => {\n try {\n // Get param from the request\n const settingId = request.params.settingId;\n\n // Find setting by id\n const setting = await store.findSetting(settingId);\n\n if (!setting) {\n response.status(404).json({});\n return;\n }\n\n response.json(setting);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n function isValidSetting(value: string): boolean {\n if (\n value === 'backstage' ||\n value === 'pagerduty' ||\n value === 'both' ||\n value === 'disabled'\n ) {\n return true;\n }\n\n return false;\n }\n\n // POST /mapping/entity\n router.post('/mapping/entity', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const entity: PagerDutyEntityMapping = request.body;\n\n if (!entity.serviceId) {\n response\n .status(400)\n .json(\n \"Bad Request: 'serviceId' must be provided as part of the request body\",\n );\n return;\n }\n\n // Get all the entity mappings from the database\n const entityMappings = await store.getAllEntityMappings();\n const oldMapping = entityMappings.find(\n mapping => mapping.serviceId === entity.serviceId,\n );\n\n // in case a mapping is defined and no integration exists,\n // we need to create one\n if (\n entity.entityRef !== '' &&\n (entity.integrationKey === '' || entity.integrationKey === undefined)\n ) {\n const backstageVendorId = 'PRO19CT';\n // check for existing integration key on service\n const service = await getServiceById(entity.serviceId, entity.account);\n const backstageIntegration = service.integrations?.find(\n integration => integration.vendor?.id === backstageVendorId,\n );\n\n if (!backstageIntegration) {\n // If an integration does not exist for service,\n // create it in PagerDuty\n const integrationKey = await createServiceIntegration({\n serviceId: entity.serviceId,\n vendorId: backstageVendorId,\n account: entity.account,\n });\n\n entity.integrationKey = integrationKey;\n } else {\n entity.integrationKey = backstageIntegration.integration_key;\n }\n }\n\n const entityMappingId = await store.insertEntityMapping(entity);\n\n // Refresh new and old entity unless they are empty strings\n if (entity.entityRef !== '') {\n // force refresh of new entity\n await catalogApi?.refreshEntity(entity.entityRef);\n }\n\n if (oldMapping && oldMapping.entityRef !== '') {\n // force refresh of old entity\n await catalogApi?.refreshEntity(oldMapping.entityRef);\n }\n\n response.json({\n id: entityMappingId,\n entityRef: entity.entityRef,\n integrationKey: entity.integrationKey,\n serviceId: entity.serviceId,\n status: entity.status,\n account: entity.account,\n });\n } catch (error) {\n if (error instanceof HttpError) {\n logger.error(\n `Error occurred while processing request: ${error.message}`,\n );\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /mapping/entity\n router.get('/mapping/entity', async (_, response) => {\n try {\n // Get all the entity mappings from the database\n const entityMappings = await store.getAllEntityMappings();\n\n // Get all the entities from the catalog\n const componentEntities = await catalogApi!.getEntities({\n filter: {\n kind: 'Component',\n },\n });\n\n // Build reference dictionary of componentEntities with serviceId as the key and entity reference and name pair as the value\n const componentEntitiesDict: Record<\n string,\n { ref: string; name: string }\n > = await createComponentEntitiesReferenceDict(componentEntities);\n\n // Get all services from PagerDuty\n const pagerDutyServices = await getAllServices();\n\n // Build the response object\n const result: PagerDutyEntityMappingsResponse =\n await buildEntityMappingsResponse(\n entityMappings,\n componentEntitiesDict,\n componentEntities,\n pagerDutyServices,\n );\n\n response.json(result);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /mapping/entity\n router.get(\n '/mapping/entity/:type/:namespace/:name',\n async (request, response) => {\n try {\n // Get the type, namespace and entity name from the request parameters\n const entityType: string = request.params.type || '';\n const entityNamespace: string = request.params.namespace || '';\n const entityName: string = request.params.name || '';\n\n if (entityType === '' || entityNamespace === '' || entityName === '') {\n response.status(400).json('Required params not specified.');\n return;\n }\n\n const entityRef =\n `${entityType}:${entityNamespace}/${entityName}`.toLowerCase();\n\n // Get all the entity mappings from the database\n const entityMapping = await store.findEntityMappingByEntityRef(\n entityRef,\n );\n\n if (!entityMapping) {\n response\n .status(404)\n .json(`Mapping for entityRef ${entityRef} not found.`);\n return;\n }\n\n response.json({\n mapping: entityMapping,\n });\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n },\n );\n\n // GET /mapping/entity/service/:serviceId\n router.get(\n '/mapping/entity/service/:serviceId',\n async (request, response) => {\n try {\n // Get the type, namespace and entity name from the request parameters\n const serviceId: string = request.params.serviceId ?? '';\n\n if (serviceId === '') {\n response.status(400).json('Required params not specified.');\n return;\n }\n\n // Get all the entity mappings from the database\n const entityMapping = await store.findEntityMappingByServiceId(\n serviceId,\n );\n\n if (!entityMapping) {\n response\n .status(404)\n .json(`Mapping for serviceId ${serviceId} not found.`);\n return;\n }\n\n response.json({\n mapping: entityMapping,\n });\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n },\n );\n\n // POST /mapping/entity/auto-match\n router.post('/mapping/entity/auto-match', async (request, response) => {\n try {\n // Default 100% threshold ensures only exact matches, customers can adjust if needed\n const threshold: number = request.body.threshold ?? 100;\n\n if (\n typeof threshold !== 'number' ||\n threshold < 0 ||\n threshold > 100\n ) {\n response.status(400).json({\n error: 'Invalid threshold. Must be a number between 0 and 100.',\n });\n return;\n }\n\n const bestOnly: boolean = request.body.bestOnly ?? false;\n\n const loadStartTime = Date.now();\n const { pdServices, bsComponents } = await loadBothSources({\n catalogApi: catalogApi!,\n });\n const loadTime = Date.now() - loadStartTime;\n\n const matchStartTime = Date.now();\n const matchingConfig: MatchingConfig = { threshold };\n let matches = findMatches(pdServices, bsComponents, matchingConfig);\n\n if (bestOnly) {\n matches = filterToBestMatchPerService(matches);\n }\n\n const matchTime = Date.now() - matchStartTime;\n\n const totalComparisons = pdServices.length * bsComponents.length;\n const exactMatches = matches.filter(m => m.score === 100).length;\n const highConfidence = matches.filter(\n m => m.score >= 90 && m.score < 100,\n ).length;\n const mediumConfidence = matches.filter(\n m => m.score >= 80 && m.score < 90,\n ).length;\n\n const getConfidenceLevel = (score: number): 'exact' | 'high' | 'medium' | 'low' => {\n if (score === 100) return 'exact';\n if (score >= 90) return 'high';\n if (score >= 80) return 'medium';\n return 'low';\n };\n\n response.json({\n matches: matches.map(m => ({\n pagerDutyService: {\n serviceId: m.pagerDutyService.sourceId,\n name: m.pagerDutyService.rawName,\n team: m.pagerDutyService.teamName,\n },\n backstageComponent: {\n entityRef: m.backstageComponent.sourceId,\n name: m.backstageComponent.rawName,\n owner: m.backstageComponent.teamName,\n },\n score: m.score,\n confidence: getConfidenceLevel(m.score),\n scoreBreakdown: m.scoreBreakdown,\n })),\n statistics: {\n totalPagerDutyServices: pdServices.length,\n totalBackstageComponents: bsComponents.length,\n totalPossibleComparisons: totalComparisons,\n matchesFound: matches.length,\n exactMatches,\n highConfidenceMatches: highConfidence,\n mediumConfidenceMatches: mediumConfidence,\n threshold,\n loadTimeMs: loadTime,\n matchTimeMs: matchTime,\n totalTimeMs: loadTime + matchTime,\n },\n });\n } catch (error) {\n logger.error(`Auto-match failed: ${error}`);\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n } else if (error instanceof ServiceLoadError) {\n response.status(503).json({\n error: 'Service temporarily unavailable',\n message: error.message,\n });\n } else {\n response.status(500).json({\n error: 'Auto-match failed',\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n });\n\n // GET /escalation_policies\n router.get('/escalation_policies', async (_, response) => {\n try {\n let escalationPolicyList = await getAllEscalationPolicies();\n\n // sort the escalation policies by account and name\n escalationPolicyList = escalationPolicyList.sort((a, b) => {\n if (a.account === b.account) {\n return a.name.localeCompare(b.name);\n }\n return a.account!.localeCompare(b.account!);\n });\n\n const escalationPolicyDropDownOptions = escalationPolicyList.map(\n policy => {\n let policyLabel = policy.name;\n if (policy.account && policy.account !== 'default') {\n policyLabel = `(${policy.account}) ${policy.name}`;\n }\n\n return {\n label: policyLabel,\n value: policy.id,\n };\n },\n );\n\n response.json(escalationPolicyDropDownOptions);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /oncall\n router.get('/oncall-users', async (request, response) => {\n try {\n // Get the escalation policy ID from the request parameters with parameter name \"escalation_policy_ids[]\"\n const escalationPolicyId: string =\n (request.query.escalation_policy_ids as string) || '';\n const account = (request.query.account as string) || '';\n\n if (escalationPolicyId === '') {\n response\n .status(400)\n .json(\"Bad Request: 'escalation_policy_ids[]' is required\");\n return;\n }\n\n const oncallUsers = await getOncallUsers(escalationPolicyId, account);\n const onCallUsersResponse: PagerDutyOnCallUsersResponse = {\n users: oncallUsers,\n };\n\n response.json(onCallUsersResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /services/:serviceId\n router.get('/services/:serviceId', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n if (serviceId === '') {\n response\n .status(400)\n .json(\n \"Bad Request: ':serviceId' must be provided as part of the path or 'integration_key' as a query parameter\",\n );\n return;\n }\n\n const service = await getServiceById(serviceId, account);\n const serviceResponse: PagerDutyServiceResponse = {\n service: service,\n };\n\n response.json(serviceResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /services?integration_key=:integrationKey\n router.get('/services', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const integrationKey: string =\n (request.query.integration_key as string) || '';\n const account = (request.query.account as string) || '';\n\n if (integrationKey !== '') {\n const service = await getServiceByIntegrationKey(\n integrationKey,\n account,\n );\n const serviceResponse: PagerDutyServiceResponse = {\n service: service,\n };\n\n response.json(serviceResponse);\n } else {\n const services = await getAllServices();\n const servicesResponse: PagerDutyServicesResponse = {\n services: services,\n };\n\n response.json(servicesResponse);\n }\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // POST /services/:serviceId/integration/:vendorId\n router.post(\n '/services/:serviceId/integration/:vendorId',\n async (request, response) => {\n try {\n const serviceId: string = request.params.serviceId || '';\n const vendorId: string = request.params.vendorId || '';\n const account = (request.query.account as string) || '';\n\n if (serviceId === '' || vendorId === '') {\n response\n .status(400)\n .json(\n \"Bad Request: ':serviceId' and ':vendorId' must be provided as part of the path\",\n );\n return;\n }\n\n const integrationKey = await createServiceIntegration({\n serviceId,\n vendorId,\n account,\n });\n\n response.json(integrationKey);\n } catch (error) {\n if (error instanceof HttpError) {\n logger.error(\n `Error occurred while processing request: ${error.message}`,\n );\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n },\n );\n\n // GET /services/:serviceId/change-events\n router.get(\n '/services/:serviceId/change-events',\n async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n const changeEvents = await getChangeEvents(serviceId, account);\n const changeEventsResponse: PagerDutyChangeEventsResponse = {\n change_events: changeEvents,\n };\n\n response.json(changeEventsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n },\n );\n\n // GET /services/:serviceId/incidents\n router.get('/services/:serviceId/incidents', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n const incidents = await getIncidents(serviceId, account);\n const incidentsResponse: PagerDutyIncidentsResponse = {\n incidents,\n };\n\n response.json(incidentsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /services/:serviceId/standards\n router.get('/services/:serviceId/standards', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n const serviceStandards = await getServiceStandards(serviceId, account);\n const serviceStandardsResponse: PagerDutyServiceStandardsResponse = {\n standards: serviceStandards,\n };\n\n response.json(serviceStandardsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /services/:serviceId/metrics\n router.get('/services/:serviceId/metrics', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n const metrics = await getServiceMetrics(serviceId, account);\n\n const metricsResponse: PagerDutyServiceMetricsResponse = {\n metrics: metrics,\n };\n\n response.json(metricsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /health\n router.get('/health', async (_, response) => {\n response.status(200).json({ status: 'ok' });\n });\n\n // Add error handler\n router.use(errorHandler());\n\n // Return the router\n return router;\n}\n"],"names":["getServiceByIntegrationKey","auth","createLegacyAuthAdapters","loadAuthConfig","loadPagerDutyEndpointsFromConfig","Router","express","removeServiceRelationsFromService","HttpError","addServiceRelationsToService","getServiceRelationshipsById","getServiceById","createServiceIntegration","getAllServices","loadBothSources","findMatches","filterToBestMatchPerService","ServiceLoadError","getAllEscalationPolicies","getOncallUsers","getChangeEvents","getIncidents","getServiceStandards","getServiceMetrics","errorHandler"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["import {\n AuthService,\n DiscoveryService,\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport {\n createLegacyAuthAdapters,\n errorHandler,\n} from '@backstage/backend-common';\nimport {\n getAllEscalationPolicies,\n getChangeEvents,\n getIncidents,\n getOncallUsers,\n getServiceById,\n getServiceByIntegrationKey,\n getServiceStandards,\n getServiceMetrics,\n getAllServices,\n getAllTeams,\n getFilteredServices,\n loadPagerDutyEndpointsFromConfig,\n createServiceIntegration,\n getServiceRelationshipsById,\n addServiceRelationsToService,\n removeServiceRelationsFromService,\n} from '../apis/pagerduty';\nimport { loadBothSources, ServiceLoadError } from '../services/dataLoader';\nimport {\n findMatches,\n filterToBestMatchPerService,\n type MatchingConfig,\n} from '../services/matchingEngine';\nimport {\n HttpError,\n PagerDutyChangeEventsResponse,\n PagerDutyIncidentsResponse,\n PagerDutyOnCallUsersResponse,\n PagerDutyServiceResponse,\n PagerDutyServiceStandardsResponse,\n PagerDutyServiceMetricsResponse,\n PagerDutyServicesResponse,\n PagerDutyEntityMapping,\n PagerDutyEntityMappingsResponse,\n PagerDutyService,\n PagerDutyServiceDependency,\n PagerDutySetting,\n} from '@pagerduty/backstage-plugin-common';\nimport { loadAuthConfig } from '../auth/auth';\nimport {\n PagerDutyBackendStore,\n RawDbEntityResultRow,\n} from '../db/PagerDutyBackendDatabase';\nimport * as express from 'express';\nimport Router from 'express-promise-router';\nimport type { CatalogApi, GetEntitiesResponse } from '@backstage/catalog-client';\n\nimport * as MappingsController from '../controllers/mappings-controller';\nimport * as CatalogEntityUtils from '../utils/catalog-entity';\n\nexport interface RouterOptions {\n logger: LoggerService;\n config: RootConfigService;\n store: PagerDutyBackendStore;\n discovery: DiscoveryService;\n auth?: AuthService;\n catalogApi?: CatalogApi;\n}\n\nexport type Annotations = {\n 'pagerduty.com/integration-key': string;\n 'pagerduty.com/service-id': string;\n 'pagerduty.com/account': string;\n};\n\nexport async function buildEntityMappingsResponse(\n entityMappings: RawDbEntityResultRow[],\n componentEntitiesDict: Record<\n string,\n {\n ref: string;\n name: string;\n }\n >,\n componentEntities: GetEntitiesResponse,\n pagerDutyServices: PagerDutyService[],\n): Promise<PagerDutyEntityMappingsResponse> {\n const result: PagerDutyEntityMappingsResponse = {\n mappings: [],\n };\n\n pagerDutyServices.forEach(service => {\n // Check for service mapping annotation in any entity config file and get the entity ref\n const entityRef = componentEntitiesDict[service.id]?.ref;\n const entityName = componentEntitiesDict[service.id]?.name;\n\n // Check if the service is mapped to an entity in the database\n const entityMapping = entityMappings.find(\n mapping => mapping.serviceId === service.id,\n );\n\n if (entityMapping) {\n if (entityRef === undefined) {\n if (\n entityMapping.entityRef === '' ||\n entityMapping.entityRef === undefined\n ) {\n result.mappings.push({\n entityRef: '',\n entityName: '',\n integrationKey: entityMapping.integrationKey,\n serviceId: entityMapping.serviceId,\n status: 'NotMapped',\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? '',\n escalationPolicy:\n service.escalation_policy !== undefined\n ? service.escalation_policy.name\n : '',\n serviceUrl: service.html_url,\n account: service.account,\n });\n } else {\n const entityRefName =\n componentEntities.items.find(\n entity =>\n `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase() ===\n entityMapping.entityRef,\n )?.metadata.name ?? '';\n\n result.mappings.push({\n entityRef: entityMapping.entityRef,\n entityName: entityRefName,\n serviceId: entityMapping.serviceId,\n integrationKey: entityMapping.integrationKey,\n status: 'OutOfSync',\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? '',\n escalationPolicy:\n service.escalation_policy !== undefined\n ? service.escalation_policy.name\n : '',\n serviceUrl: service.html_url,\n account: service.account,\n });\n }\n } else if (entityRef !== entityMapping.entityRef) {\n const entityRefName =\n componentEntities.items.find(\n entity =>\n `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase() ===\n entityMapping.entityRef,\n )?.metadata.name ?? '';\n\n result.mappings.push({\n entityRef:\n entityMapping.entityRef !== '' ? entityMapping.entityRef : '',\n entityName: entityMapping.entityRef !== '' ? entityRefName : '',\n serviceId: entityMapping.serviceId,\n integrationKey: entityMapping.integrationKey,\n status: 'OutOfSync',\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? '',\n escalationPolicy:\n service.escalation_policy !== undefined\n ? service.escalation_policy.name\n : '',\n serviceUrl: service.html_url,\n account: service.account,\n });\n } else if (entityRef === entityMapping.entityRef) {\n result.mappings.push({\n entityRef:\n entityMapping.entityRef !== '' ? entityMapping.entityRef : '',\n entityName: entityMapping.entityRef !== '' ? entityName : '',\n serviceId: entityMapping.serviceId,\n integrationKey: entityMapping.integrationKey,\n status: 'InSync',\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? '',\n escalationPolicy:\n service.escalation_policy !== undefined\n ? service.escalation_policy.name\n : '',\n serviceUrl: service.html_url,\n account: service.account,\n });\n }\n } else {\n const backstageVendorId = 'PRO19CT';\n const backstageIntegrationKey =\n service.integrations?.find(\n integration => integration.vendor?.id === backstageVendorId,\n )?.integration_key ?? '';\n\n if (entityRef !== undefined) {\n result.mappings.push({\n entityRef: entityRef,\n entityName: entityName,\n serviceId: service.id,\n integrationKey: backstageIntegrationKey,\n status: 'InSync',\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? '',\n escalationPolicy:\n service.escalation_policy !== undefined\n ? service.escalation_policy.name\n : '',\n serviceUrl: service.html_url,\n account: service.account,\n });\n } else {\n result.mappings.push({\n entityRef: '',\n entityName: '',\n serviceId: service.id,\n integrationKey: backstageIntegrationKey,\n status: 'NotMapped',\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? '',\n escalationPolicy:\n service.escalation_policy !== undefined\n ? service.escalation_policy.name\n : '',\n serviceUrl: service.html_url,\n account: service.account,\n });\n }\n }\n });\n\n const sortedResult = result.mappings.sort((a, b) => {\n if (a.serviceName! < b.serviceName!) {\n return -1;\n } else if (a.serviceName! > b.serviceName!) {\n return 1;\n }\n return 0;\n });\n\n result.mappings = sortedResult;\n\n return result;\n}\n\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { logger, config, store, catalogApi } = options;\n let { auth } = options;\n\n if (!auth) {\n auth = createLegacyAuthAdapters(options).auth;\n }\n\n if (!catalogApi) {\n throw new Error('Catalog API is required to start the PagerDuty plugin backend');\n }\n\n // Get authentication Config\n await loadAuthConfig(config, logger);\n\n // Get optional PagerDuty custom endpoints from config\n loadPagerDutyEndpointsFromConfig(config, logger);\n\n // Create the router\n const router = Router();\n router.use(express.json());\n\n // DELETE /dependencies/service/:serviceId\n router.delete(\n '/dependencies/service/:serviceId',\n async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n if (serviceId === '') {\n response\n .status(400)\n .json(\n \"Bad Request: ':serviceId' must be provided as part of the path\",\n );\n return;\n }\n\n const dependencies: string[] =\n Object.keys(request.body).length === 0 ? [] : request.body;\n if (!dependencies || dependencies.length === 0) {\n response\n .status(400)\n .json(\n \"Bad Request: 'dependencies' must be provided as part of the request body\",\n );\n return;\n }\n\n const serviceRelations: PagerDutyServiceDependency[] = [];\n\n dependencies.forEach(async dependency => {\n serviceRelations.push({\n supporting_service: {\n id: dependency,\n type: 'service',\n },\n dependent_service: {\n id: serviceId,\n type: 'service',\n },\n });\n });\n\n await removeServiceRelationsFromService(serviceRelations, account);\n\n response.sendStatus(200);\n } catch (error) {\n if (error instanceof HttpError) {\n logger.error(\n `Error occurred while processing request: ${error.message}`,\n );\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n },\n );\n\n // POST /dependencies/service/:serviceId\n router.post('/dependencies/service/:serviceId', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n if (serviceId === '') {\n response\n .status(400)\n .json(\n \"Bad Request: ':serviceId' must be provided as part of the path\",\n );\n return;\n }\n\n const dependencies: string[] =\n Object.keys(request.body).length === 0 ? [] : request.body;\n if (!dependencies || dependencies.length === 0) {\n response\n .status(400)\n .json(\n \"Bad Request: 'dependencies' must be provided as part of the request body\",\n );\n return;\n }\n\n const serviceRelations: PagerDutyServiceDependency[] = [];\n\n dependencies.forEach(async dependency => {\n serviceRelations.push({\n supporting_service: {\n id: dependency,\n type: 'service',\n },\n dependent_service: {\n id: serviceId,\n type: 'service',\n },\n });\n });\n\n await addServiceRelationsToService(serviceRelations, account);\n\n response.sendStatus(200);\n } catch (error) {\n if (error instanceof HttpError) {\n logger.error(\n `Error occurred while processing request: ${error.message}`,\n );\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n router.get('/dependencies/service/:serviceId', async (request, response) => {\n try {\n const serviceId = request.params.serviceId;\n const account = (request.query.account as string) || '';\n\n if (serviceId) {\n const serviceRelationships: PagerDutyServiceDependency[] =\n await getServiceRelationshipsById(serviceId, account);\n\n if (serviceRelationships) {\n response.json({\n relationships: serviceRelationships,\n });\n }\n } else {\n response\n .status(400)\n .json(\n \"Bad Request: ':serviceId' must be provided as part of the path\",\n );\n }\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /catalog/entity/:entityRef\n router.get(\n '/catalog/entity/:type/:namespace/:name',\n async (request, response) => {\n const type = request.params.type;\n const namespace = request.params.namespace;\n const name = request.params.name;\n\n try {\n if (type && namespace && name) {\n const entityRef = `${type}:${namespace}/${name}`.toLowerCase();\n const foundEntity = await catalogApi?.getEntityByRef(entityRef);\n\n if (foundEntity) {\n response.json(\n foundEntity.metadata.annotations?.['pagerduty.com/service-id'],\n );\n } else {\n response.status(404);\n }\n } else {\n response\n .status(400)\n .json(\n \"Bad Request: ':entityRef' must be provided as part of the path\",\n );\n }\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n },\n );\n\n // POST /settings\n router.post('/settings', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const settings: PagerDutySetting[] = request.body;\n\n // For each setting, update or insert the value in the database\n await Promise.all(\n settings.map(async setting => {\n if (setting.id === undefined || setting.value === undefined) {\n response\n .status(400)\n .json(\"Bad Request: 'id' and 'value' are required\");\n return;\n }\n\n if (!isValidSetting(setting.value)) {\n response\n .status(400)\n .json(\n \"Bad Request: 'value' is invalid. Valid options are 'backstage', 'pagerduty', 'both' or 'disabled'\",\n );\n return;\n }\n\n await store.updateSetting(setting);\n }),\n );\n\n response.sendStatus(200);\n } catch (error) {\n if (error instanceof HttpError) {\n logger.error(\n `Error occurred while processing request: ${error.message}`,\n );\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /settings/:settingId\n router.get('/settings/:settingId', async (request, response) => {\n try {\n // Get param from the request\n const settingId = request.params.settingId;\n\n // Find setting by id\n const setting = await store.findSetting(settingId);\n\n if (!setting) {\n response.status(404).json({});\n return;\n }\n\n response.json(setting);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n function isValidSetting(value: string): boolean {\n if (\n value === 'backstage' ||\n value === 'pagerduty' ||\n value === 'both' ||\n value === 'disabled'\n ) {\n return true;\n }\n\n return false;\n }\n\n // POST /mapping/entity\n router.post('/mapping/entity', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const entity: PagerDutyEntityMapping = request.body;\n\n if (!entity.serviceId) {\n response\n .status(400)\n .json(\n \"Bad Request: 'serviceId' must be provided as part of the request body\",\n );\n return;\n }\n\n // Get all the entity mappings from the database\n const entityMappings = await store.getAllEntityMappings();\n const oldMapping = entityMappings.find(\n mapping => mapping.serviceId === entity.serviceId,\n );\n\n // in case a mapping is defined and no integration exists,\n // we need to create one\n if (\n entity.entityRef !== '' &&\n (entity.integrationKey === '' || entity.integrationKey === undefined)\n ) {\n const backstageVendorId = 'PRO19CT';\n // check for existing integration key on service\n const service = await getServiceById(entity.serviceId, entity.account);\n const backstageIntegration = service.integrations?.find(\n integration => integration.vendor?.id === backstageVendorId,\n );\n\n if (!backstageIntegration) {\n // If an integration does not exist for service,\n // create it in PagerDuty\n const integrationKey = await createServiceIntegration({\n serviceId: entity.serviceId,\n vendorId: backstageVendorId,\n account: entity.account,\n });\n\n entity.integrationKey = integrationKey;\n } else {\n entity.integrationKey = backstageIntegration.integration_key;\n }\n }\n\n const entityMappingId = await store.insertEntityMapping(entity);\n\n // Refresh new and old entity unless they are empty strings\n if (entity.entityRef !== '') {\n // force refresh of new entity\n await catalogApi?.refreshEntity(entity.entityRef);\n }\n\n if (oldMapping && oldMapping.entityRef !== '') {\n // force refresh of old entity\n await catalogApi?.refreshEntity(oldMapping.entityRef);\n }\n\n response.json({\n id: entityMappingId,\n entityRef: entity.entityRef,\n integrationKey: entity.integrationKey,\n serviceId: entity.serviceId,\n status: entity.status,\n account: entity.account,\n });\n } catch (error) {\n if (error instanceof HttpError) {\n logger.error(\n `Error occurred while processing request: ${error.message}`,\n );\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n } else {\n logger.error(\n `Unexpected error occurred while processing request: ${error}`,\n );\n response.status(500).json({\n errors: [error instanceof Error ? error.message : String(error)],\n });\n }\n }\n });\n\n // POST /mapping/entities/bulk\n router.post('/mapping/entities/bulk', async (request, response) => {\n try {\n const { mappings } = request.body;\n\n if (!Array.isArray(mappings)) {\n response.status(400).json({\n error: \"Bad Request: 'mappings' must be an array\",\n });\n return;\n }\n\n const existingMappings = await store.getAllEntityMappings();\n const existingServiceIds = new Set(\n existingMappings.map(m => m.serviceId),\n );\n\n const newMappings: PagerDutyEntityMapping[] = [];\n const skipped: PagerDutyEntityMapping[] = [];\n const errors = [];\n\n for (const entity of mappings) {\n if (!entity.serviceId) {\n errors.push({\n entityRef: entity.entityRef,\n error: 'Missing serviceId',\n });\n continue;\n }\n\n if (existingServiceIds.has(entity.serviceId)) {\n skipped.push(entity);\n continue;\n }\n\n if (\n entity.entityRef !== '' &&\n (entity.integrationKey === '' || entity.integrationKey === undefined)\n ) {\n try {\n const backstageVendorId = 'PRO19CT';\n const service = await getServiceById(\n entity.serviceId,\n entity.account,\n );\n const backstageIntegration = service.integrations?.find(\n integration => integration.vendor?.id === backstageVendorId,\n );\n\n if (!backstageIntegration) {\n const integrationKey = await createServiceIntegration({\n serviceId: entity.serviceId,\n vendorId: backstageVendorId,\n account: entity.account,\n });\n\n entity.integrationKey = integrationKey;\n } else {\n entity.integrationKey = backstageIntegration.integration_key;\n }\n } catch (error) {\n errors.push({\n entityRef: entity.entityRef,\n serviceId: entity.serviceId,\n error:\n error instanceof Error\n ? `Failed to create integration: ${error.message}`\n : 'Failed to create integration',\n });\n continue;\n }\n }\n\n newMappings.push(entity);\n }\n\n let insertedIds: string[] = [];\n if (newMappings.length > 0) {\n try {\n insertedIds = await store.bulkInsertEntityMappings(newMappings);\n\n await Promise.all(\n newMappings.map(async entity => {\n if (entity.entityRef !== '') {\n await catalogApi?.refreshEntity(entity.entityRef);\n }\n }),\n );\n } catch (error) {\n logger.error(`Bulk insert failed: ${error}`);\n response.status(500).json({\n errors: ['Bulk insert failed'],\n });\n return;\n }\n }\n\n const results = newMappings.map((entity, index) => ({\n id: insertedIds[index],\n entityRef: entity.entityRef,\n integrationKey: entity.integrationKey,\n serviceId: entity.serviceId,\n status: entity.status,\n account: entity.account,\n }));\n\n response.json({\n success: results,\n skipped: skipped.map(entity => ({\n entityRef: entity.entityRef,\n serviceId: entity.serviceId,\n reason: 'Mapping already exists for this service ID',\n })),\n errors: errors,\n total: mappings.length,\n successCount: results.length,\n skippedCount: skipped.length,\n errorCount: errors.length,\n });\n } catch (error) {\n if (error instanceof HttpError) {\n logger.error(\n `Error occurred while processing bulk mappings: ${error.message}`,\n );\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n } else {\n logger.error(`Unexpected error: ${error}`);\n response.status(500).json({\n errors: ['Internal server error'],\n });\n }\n }\n });\n\n // DEPRECATED: GET /mapping/entity\n router.get('/mapping/entity', async (_, response) => {\n try {\n // Get all the entity mappings from the database\n const entityMappings = await store.getAllEntityMappings();\n\n // Get all the entities from the catalog\n const componentEntities = await catalogApi!.getEntities({\n filter: {\n kind: 'Component',\n },\n });\n\n // Build reference dictionary of componentEntities with serviceId as the key and entity reference and name pair as the value\n const componentEntitiesDict: Record<\n string,\n { ref: string; name: string }\n > = await CatalogEntityUtils.createComponentEntitiesReferenceDict(componentEntities);\n\n // Get all services from PagerDuty\n const pagerDutyServices = await getAllServices();\n\n // Build the response object\n const result: PagerDutyEntityMappingsResponse =\n await buildEntityMappingsResponse(\n entityMappings,\n componentEntitiesDict,\n componentEntities,\n pagerDutyServices,\n );\n\n response.json(result);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n router.post('/mapping/entities', MappingsController.getMappingEntities(store, catalogApi));\n\n // GET /mapping/entity\n router.get(\n '/mapping/entity/:type/:namespace/:name',\n async (request, response) => {\n try {\n // Get the type, namespace and entity name from the request parameters\n const entityType: string = request.params.type || '';\n const entityNamespace: string = request.params.namespace || '';\n const entityName: string = request.params.name || '';\n\n if (entityType === '' || entityNamespace === '' || entityName === '') {\n response.status(400).json('Required params not specified.');\n return;\n }\n\n const entityRef =\n `${entityType}:${entityNamespace}/${entityName}`.toLowerCase();\n\n // Get all the entity mappings from the database\n const entityMapping = await store.findEntityMappingByEntityRef(\n entityRef,\n );\n\n if (!entityMapping) {\n response\n .status(404)\n .json(`Mapping for entityRef ${entityRef} not found.`);\n return;\n }\n\n response.json({\n mapping: entityMapping,\n });\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n },\n );\n\n // GET /mapping/entity/service/:serviceId\n router.get(\n '/mapping/entity/service/:serviceId',\n async (request, response) => {\n try {\n // Get the type, namespace and entity name from the request parameters\n const serviceId: string = request.params.serviceId ?? '';\n\n if (serviceId === '') {\n response.status(400).json('Required params not specified.');\n return;\n }\n\n // Get all the entity mappings from the database\n const entityMapping = await store.findEntityMappingByServiceId(\n serviceId,\n );\n\n if (!entityMapping) {\n response\n .status(404)\n .json(`Mapping for serviceId ${serviceId} not found.`);\n return;\n }\n\n response.json({\n mapping: entityMapping,\n });\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n },\n );\n\n // POST /mapping/entity/auto-match\n router.post('/mapping/entity/auto-match', async (request, response) => {\n try {\n // Default 100% threshold ensures only exact matches, customers can adjust if needed\n const threshold: number = request.body.threshold ?? 100;\n const account: string | undefined = request.body.account;\n\n if (typeof threshold !== 'number' || threshold < 0 || threshold > 100) {\n response.status(400).json({\n error: 'Invalid threshold. Must be a number between 0 and 100.',\n });\n return;\n }\n\n const bestOnly: boolean = request.body.bestOnly ?? false;\n\n const loadStartTime = Date.now();\n const { pdServices, bsComponents } = await loadBothSources({\n catalogApi: catalogApi!,\n });\n\n const filteredPdServices = account\n ? pdServices.filter(service => service.account === account)\n : pdServices;\n\n const loadTime = Date.now() - loadStartTime;\n\n const matchStartTime = Date.now();\n const matchingConfig: MatchingConfig = { threshold };\n let matches = findMatches(filteredPdServices, bsComponents, matchingConfig);\n\n if (bestOnly) {\n matches = filterToBestMatchPerService(matches);\n }\n\n const matchTime = Date.now() - matchStartTime;\n\n const totalComparisons = filteredPdServices.length * bsComponents.length;\n const exactMatches = matches.filter(m => m.score === 100).length;\n const highConfidence = matches.filter(\n m => m.score >= 90 && m.score < 100,\n ).length;\n const mediumConfidence = matches.filter(\n m => m.score >= 80 && m.score < 90,\n ).length;\n\n const getConfidenceLevel = (\n score: number,\n ): 'exact' | 'high' | 'medium' | 'low' => {\n if (score === 100) return 'exact';\n if (score >= 90) return 'high';\n if (score >= 80) return 'medium';\n return 'low';\n };\n\n response.json({\n matches: matches.map(m => ({\n pagerDutyService: {\n serviceId: m.pagerDutyService.sourceId,\n name: m.pagerDutyService.rawName,\n team: m.pagerDutyService.teamName,\n account: m.pagerDutyService.account,\n },\n backstageComponent: {\n entityRef: m.backstageComponent.sourceId,\n name: m.backstageComponent.rawName,\n owner: m.backstageComponent.teamName,\n },\n score: m.score,\n confidence: getConfidenceLevel(m.score),\n scoreBreakdown: m.scoreBreakdown,\n })),\n statistics: {\n totalPagerDutyServices: filteredPdServices.length,\n totalBackstageComponents: bsComponents.length,\n totalPossibleComparisons: totalComparisons,\n matchesFound: matches.length,\n exactMatches,\n highConfidenceMatches: highConfidence,\n mediumConfidenceMatches: mediumConfidence,\n threshold,\n loadTimeMs: loadTime,\n matchTimeMs: matchTime,\n totalTimeMs: loadTime + matchTime,\n },\n });\n } catch (error) {\n logger.error(`Auto-match failed: ${error}`);\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n } else if (error instanceof ServiceLoadError) {\n response.status(503).json({\n error: 'Service temporarily unavailable',\n message: error.message,\n });\n } else {\n response.status(500).json({\n error: 'Auto-match failed',\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n });\n\n // GET /escalation_policies\n router.get('/escalation_policies', async (_, response) => {\n try {\n let escalationPolicyList = await getAllEscalationPolicies();\n\n // sort the escalation policies by account and name\n escalationPolicyList = escalationPolicyList.sort((a, b) => {\n if (a.account === b.account) {\n return a.name.localeCompare(b.name);\n }\n return a.account!.localeCompare(b.account!);\n });\n\n const escalationPolicyDropDownOptions = escalationPolicyList.map(\n policy => {\n let policyLabel = policy.name;\n if (policy.account && policy.account !== 'default') {\n policyLabel = `(${policy.account}) ${policy.name}`;\n }\n\n return {\n label: policyLabel,\n value: policy.id,\n };\n },\n );\n\n response.json(escalationPolicyDropDownOptions);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /oncall\n router.get('/oncall-users', async (request, response) => {\n try {\n // Get the escalation policy ID from the request parameters with parameter name \"escalation_policy_ids[]\"\n const escalationPolicyId: string =\n (request.query.escalation_policy_ids as string) || '';\n const account = (request.query.account as string) || '';\n\n if (escalationPolicyId === '') {\n response\n .status(400)\n .json(\"Bad Request: 'escalation_policy_ids[]' is required\");\n return;\n }\n\n const oncallUsers = await getOncallUsers(escalationPolicyId, account);\n const onCallUsersResponse: PagerDutyOnCallUsersResponse = {\n users: oncallUsers,\n };\n\n response.json(onCallUsersResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /services/:serviceId\n router.get('/services/:serviceId', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n if (serviceId === '') {\n response\n .status(400)\n .json(\n \"Bad Request: ':serviceId' must be provided as part of the path or 'integration_key' as a query parameter\",\n );\n return;\n }\n\n const service = await getServiceById(serviceId, account);\n const serviceResponse: PagerDutyServiceResponse = {\n service: service,\n };\n\n response.json(serviceResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /teams?account=:account\n router.get('/teams', async (request, response) => {\n try {\n const account = request.query.account as string | undefined;\n const teams = await getAllTeams(account);\n response.json(teams);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n\n // GET /services - Unified endpoint for all service queries\n // Query params:\n // - integration_key: fetch service by integration key\n // - team_id, query, limit, account: fetch filtered services\n // - no params: fetch all services\n router.get('/services', async (request, response) => {\n try {\n const integrationKey = request.query.integration_key as string | undefined;\n const teamId = request.query.team_id as string | undefined;\n const query = request.query.query as string | undefined;\n const limit = request.query.limit\n ? parseInt(request.query.limit as string, 10)\n : undefined;\n const account = request.query.account as string | undefined;\n\n // Case 1: Fetch by integration key\n if (integrationKey) {\n const service = await getServiceByIntegrationKey(\n integrationKey,\n account || '',\n );\n const serviceResponse: PagerDutyServiceResponse = {\n service: service,\n };\n response.json(serviceResponse);\n return;\n }\n\n // Case 2: Fetch filtered services (if team_id, query, or limit provided)\n if (teamId || query || limit) {\n const teamIdsArray: string[] | undefined = teamId ? [teamId] : undefined;\n const services = await getFilteredServices(\n teamIdsArray,\n query,\n limit || 100,\n account,\n );\n response.json(services);\n return;\n }\n\n // Case 3: Fetch all services (default)\n const services = await getAllServices();\n const servicesResponse: PagerDutyServicesResponse = {\n services: services,\n };\n response.json(servicesResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n } else {\n logger.error(\n `Unexpected error occurred while processing request: ${error}`,\n );\n response.status(500).json({\n errors: [error instanceof Error ? error.message : String(error)],\n });\n }\n }\n });\n\n // POST /services/:serviceId/integration/:vendorId\n router.post(\n '/services/:serviceId/integration/:vendorId',\n async (request, response) => {\n try {\n const serviceId: string = request.params.serviceId || '';\n const vendorId: string = request.params.vendorId || '';\n const account = (request.query.account as string) || '';\n\n if (serviceId === '' || vendorId === '') {\n response\n .status(400)\n .json(\n \"Bad Request: ':serviceId' and ':vendorId' must be provided as part of the path\",\n );\n return;\n }\n\n const integrationKey = await createServiceIntegration({\n serviceId,\n vendorId,\n account,\n });\n\n response.json(integrationKey);\n } catch (error) {\n if (error instanceof HttpError) {\n logger.error(\n `Error occurred while processing request: ${error.message}`,\n );\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n },\n );\n\n // GET /services/:serviceId/change-events\n router.get(\n '/services/:serviceId/change-events',\n async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n const changeEvents = await getChangeEvents(serviceId, account);\n const changeEventsResponse: PagerDutyChangeEventsResponse = {\n change_events: changeEvents,\n };\n\n response.json(changeEventsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n },\n );\n\n // GET /services/:serviceId/incidents\n router.get('/services/:serviceId/incidents', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n const incidents = await getIncidents(serviceId, account);\n const incidentsResponse: PagerDutyIncidentsResponse = {\n incidents,\n };\n\n response.json(incidentsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /services/:serviceId/standards\n router.get('/services/:serviceId/standards', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n const serviceStandards = await getServiceStandards(serviceId, account);\n const serviceStandardsResponse: PagerDutyServiceStandardsResponse = {\n standards: serviceStandards,\n };\n\n response.json(serviceStandardsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /services/:serviceId/metrics\n router.get('/services/:serviceId/metrics', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n const account = (request.query.account as string) || '';\n\n const metrics = await getServiceMetrics(serviceId, account);\n\n const metricsResponse: PagerDutyServiceMetricsResponse = {\n metrics: metrics,\n };\n\n response.json(metricsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [`${error.message}`],\n });\n }\n }\n });\n\n // GET /accounts\n router.get('/accounts', async (_, response) => {\n try {\n const accountsConfig = config.getOptional('pagerDuty.accounts') as\n | Array<{\n id: string;\n isDefault?: boolean;\n }>\n | undefined;\n\n if (accountsConfig && accountsConfig.length > 0) {\n const accounts = accountsConfig.map(account => ({\n id: account.id,\n isDefault: account.isDefault || false,\n }));\n response.status(200).json({ accounts });\n } else {\n response.status(200).json({ accounts: [] });\n }\n } catch (error) {\n logger.error(`Failed to get accounts: ${error}`);\n response.status(500).json({ error: 'Failed to get accounts' });\n }\n });\n\n // GET /health\n router.get('/health', async (_, response) => {\n response.status(200).json({ status: 'ok' });\n });\n\n // Add error handler\n router.use(errorHandler());\n\n // Return the router\n return router;\n}\n"],"names":["auth","createLegacyAuthAdapters","loadAuthConfig","loadPagerDutyEndpointsFromConfig","Router","express","removeServiceRelationsFromService","HttpError","addServiceRelationsToService","getServiceRelationshipsById","getServiceById","createServiceIntegration","CatalogEntityUtils.createComponentEntitiesReferenceDict","getAllServices","MappingsController.getMappingEntities","loadBothSources","findMatches","filterToBestMatchPerService","ServiceLoadError","getAllEscalationPolicies","getOncallUsers","getAllTeams","getServiceByIntegrationKey","services","getFilteredServices","getChangeEvents","getIncidents","getServiceStandards","getServiceMetrics","errorHandler"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4EA,eAAsB,2BAAA,CACpB,cAAA,EACA,qBAAA,EAOA,iBAAA,EACA,iBAAA,EAC0C;AAC1C,EAAA,MAAM,MAAA,GAA0C;AAAA,IAC9C,UAAU;AAAC,GACb;AAEA,EAAA,iBAAA,CAAkB,QAAQ,CAAA,OAAA,KAAW;AAEnC,IAAA,MAAM,SAAA,GAAY,qBAAA,CAAsB,OAAA,CAAQ,EAAE,CAAA,EAAG,GAAA;AACrD,IAAA,MAAM,UAAA,GAAa,qBAAA,CAAsB,OAAA,CAAQ,EAAE,CAAA,EAAG,IAAA;AAGtD,IAAA,MAAM,gBAAgB,cAAA,CAAe,IAAA;AAAA,MACnC,CAAA,OAAA,KAAW,OAAA,CAAQ,SAAA,KAAc,OAAA,CAAQ;AAAA,KAC3C;AAEA,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,QAAA,IACE,aAAA,CAAc,SAAA,KAAc,EAAA,IAC5B,aAAA,CAAc,cAAc,MAAA,EAC5B;AACA,UAAA,MAAA,CAAO,SAAS,IAAA,CAAK;AAAA,YACnB,SAAA,EAAW,EAAA;AAAA,YACX,UAAA,EAAY,EAAA;AAAA,YACZ,gBAAgB,aAAA,CAAc,cAAA;AAAA,YAC9B,WAAW,aAAA,CAAc,SAAA;AAAA,YACzB,MAAA,EAAQ,WAAA;AAAA,YACR,aAAa,OAAA,CAAQ,IAAA;AAAA,YACrB,IAAA,EAAM,OAAA,CAAQ,KAAA,GAAQ,CAAC,GAAG,IAAA,IAAQ,EAAA;AAAA,YAClC,kBACE,OAAA,CAAQ,iBAAA,KAAsB,MAAA,GAC1B,OAAA,CAAQ,kBAAkB,IAAA,GAC1B,EAAA;AAAA,YACN,YAAY,OAAA,CAAQ,QAAA;AAAA,YACpB,SAAS,OAAA,CAAQ;AAAA,WAClB,CAAA;AAAA,QACH,CAAA,MAAO;AACL,UAAA,MAAM,aAAA,GACJ,kBAAkB,KAAA,CAAM,IAAA;AAAA,YACtB,CAAA,MAAA,KACE,CAAA,EAAG,MAAA,CAAO,IAAI,IAAI,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,CAAA,EAAI,OAAO,QAAA,CAAS,IAAI,CAAA,CAAA,CAAG,WAAA,OACtE,aAAA,CAAc;AAAA,WAClB,EAAG,SAAS,IAAA,IAAQ,EAAA;AAEtB,UAAA,MAAA,CAAO,SAAS,IAAA,CAAK;AAAA,YACnB,WAAW,aAAA,CAAc,SAAA;AAAA,YACzB,UAAA,EAAY,aAAA;AAAA,YACZ,WAAW,aAAA,CAAc,SAAA;AAAA,YACzB,gBAAgB,aAAA,CAAc,cAAA;AAAA,YAC9B,MAAA,EAAQ,WAAA;AAAA,YACR,aAAa,OAAA,CAAQ,IAAA;AAAA,YACrB,IAAA,EAAM,OAAA,CAAQ,KAAA,GAAQ,CAAC,GAAG,IAAA,IAAQ,EAAA;AAAA,YAClC,kBACE,OAAA,CAAQ,iBAAA,KAAsB,MAAA,GAC1B,OAAA,CAAQ,kBAAkB,IAAA,GAC1B,EAAA;AAAA,YACN,YAAY,OAAA,CAAQ,QAAA;AAAA,YACpB,SAAS,OAAA,CAAQ;AAAA,WAClB,CAAA;AAAA,QACH;AAAA,MACF,CAAA,MAAA,IAAW,SAAA,KAAc,aAAA,CAAc,SAAA,EAAW;AAChD,QAAA,MAAM,aAAA,GACJ,kBAAkB,KAAA,CAAM,IAAA;AAAA,UACtB,CAAA,MAAA,KACE,CAAA,EAAG,MAAA,CAAO,IAAI,IAAI,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,CAAA,EAAI,OAAO,QAAA,CAAS,IAAI,CAAA,CAAA,CAAG,WAAA,OACtE,aAAA,CAAc;AAAA,SAClB,EAAG,SAAS,IAAA,IAAQ,EAAA;AAEtB,QAAA,MAAA,CAAO,SAAS,IAAA,CAAK;AAAA,UACnB,SAAA,EACE,aAAA,CAAc,SAAA,KAAc,EAAA,GAAK,cAAc,SAAA,GAAY,EAAA;AAAA,UAC7D,UAAA,EAAY,aAAA,CAAc,SAAA,KAAc,EAAA,GAAK,aAAA,GAAgB,EAAA;AAAA,UAC7D,WAAW,aAAA,CAAc,SAAA;AAAA,UACzB,gBAAgB,aAAA,CAAc,cAAA;AAAA,UAC9B,MAAA,EAAQ,WAAA;AAAA,UACR,aAAa,OAAA,CAAQ,IAAA;AAAA,UACrB,IAAA,EAAM,OAAA,CAAQ,KAAA,GAAQ,CAAC,GAAG,IAAA,IAAQ,EAAA;AAAA,UAClC,kBACE,OAAA,CAAQ,iBAAA,KAAsB,MAAA,GAC1B,OAAA,CAAQ,kBAAkB,IAAA,GAC1B,EAAA;AAAA,UACN,YAAY,OAAA,CAAQ,QAAA;AAAA,UACpB,SAAS,OAAA,CAAQ;AAAA,SAClB,CAAA;AAAA,MACH,CAAA,MAAA,IAAW,SAAA,KAAc,aAAA,CAAc,SAAA,EAAW;AAChD,QAAA,MAAA,CAAO,SAAS,IAAA,CAAK;AAAA,UACnB,SAAA,EACE,aAAA,CAAc,SAAA,KAAc,EAAA,GAAK,cAAc,SAAA,GAAY,EAAA;AAAA,UAC7D,UAAA,EAAY,aAAA,CAAc,SAAA,KAAc,EAAA,GAAK,UAAA,GAAa,EAAA;AAAA,UAC1D,WAAW,aAAA,CAAc,SAAA;AAAA,UACzB,gBAAgB,aAAA,CAAc,cAAA;AAAA,UAC9B,MAAA,EAAQ,QAAA;AAAA,UACR,aAAa,OAAA,CAAQ,IAAA;AAAA,UACrB,IAAA,EAAM,OAAA,CAAQ,KAAA,GAAQ,CAAC,GAAG,IAAA,IAAQ,EAAA;AAAA,UAClC,kBACE,OAAA,CAAQ,iBAAA,KAAsB,MAAA,GAC1B,OAAA,CAAQ,kBAAkB,IAAA,GAC1B,EAAA;AAAA,UACN,YAAY,OAAA,CAAQ,QAAA;AAAA,UACpB,SAAS,OAAA,CAAQ;AAAA,SAClB,CAAA;AAAA,MACH;AAAA,IACF,CAAA,MAAO;AACL,MAAA,MAAM,iBAAA,GAAoB,SAAA;AAC1B,MAAA,MAAM,uBAAA,GACJ,QAAQ,YAAA,EAAc,IAAA;AAAA,QACpB,CAAA,WAAA,KAAe,WAAA,CAAY,MAAA,EAAQ,EAAA,KAAO;AAAA,SACzC,eAAA,IAAmB,EAAA;AAExB,MAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,QAAA,MAAA,CAAO,SAAS,IAAA,CAAK;AAAA,UACnB,SAAA;AAAA,UACA,UAAA;AAAA,UACA,WAAW,OAAA,CAAQ,EAAA;AAAA,UACnB,cAAA,EAAgB,uBAAA;AAAA,UAChB,MAAA,EAAQ,QAAA;AAAA,UACR,aAAa,OAAA,CAAQ,IAAA;AAAA,UACrB,IAAA,EAAM,OAAA,CAAQ,KAAA,GAAQ,CAAC,GAAG,IAAA,IAAQ,EAAA;AAAA,UAClC,kBACE,OAAA,CAAQ,iBAAA,KAAsB,MAAA,GAC1B,OAAA,CAAQ,kBAAkB,IAAA,GAC1B,EAAA;AAAA,UACN,YAAY,OAAA,CAAQ,QAAA;AAAA,UACpB,SAAS,OAAA,CAAQ;AAAA,SAClB,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,MAAA,CAAO,SAAS,IAAA,CAAK;AAAA,UACnB,SAAA,EAAW,EAAA;AAAA,UACX,UAAA,EAAY,EAAA;AAAA,UACZ,WAAW,OAAA,CAAQ,EAAA;AAAA,UACnB,cAAA,EAAgB,uBAAA;AAAA,UAChB,MAAA,EAAQ,WAAA;AAAA,UACR,aAAa,OAAA,CAAQ,IAAA;AAAA,UACrB,IAAA,EAAM,OAAA,CAAQ,KAAA,GAAQ,CAAC,GAAG,IAAA,IAAQ,EAAA;AAAA,UAClC,kBACE,OAAA,CAAQ,iBAAA,KAAsB,MAAA,GAC1B,OAAA,CAAQ,kBAAkB,IAAA,GAC1B,EAAA;AAAA,UACN,YAAY,OAAA,CAAQ,QAAA;AAAA,UACpB,SAAS,OAAA,CAAQ;AAAA,SAClB,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM,eAAe,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM;AAClD,IAAA,IAAI,CAAA,CAAE,WAAA,GAAe,CAAA,CAAE,WAAA,EAAc;AACnC,MAAA,OAAO,EAAA;AAAA,IACT,CAAA,MAAA,IAAW,CAAA,CAAE,WAAA,GAAe,CAAA,CAAE,WAAA,EAAc;AAC1C,MAAA,OAAO,CAAA;AAAA,IACT;AACA,IAAA,OAAO,CAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,QAAA,GAAW,YAAA;AAElB,EAAA,OAAO,MAAA;AACT;AAEA,eAAsB,aACpB,OAAA,EACyB;AACzB,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAQ,KAAA,EAAO,YAAW,GAAI,OAAA;AAC9C,EAAA,IAAI,QAAEA,QAAK,GAAI,OAAA;AAEf,EAAA,IAAI,CAACA,MAAA,EAAM;AACT,IAAAA,MAAA,GAAOC,sCAAA,CAAyB,OAAO,CAAA,CAAE,IAAA;AAAA,EAC3C;AAEA,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,EACjF;AAGA,EAAA,MAAMC,mBAAA,CAAe,QAAQ,MAAM,CAAA;AAGnC,EAAAC,0CAAA,CAAiC,QAAQ,MAAM,CAAA;AAG/C,EAAA,MAAM,SAASC,uBAAA,EAAO;AACtB,EAAA,MAAA,CAAO,GAAA,CAAIC,kBAAA,CAAQ,IAAA,EAAM,CAAA;AAGzB,EAAA,MAAA,CAAO,MAAA;AAAA,IACL,kCAAA;AAAA,IACA,OAAO,SAAS,QAAA,KAAa;AAC3B,MAAA,IAAI;AAEF,QAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,MAAA,CAAO,SAAA,IAAa,EAAA;AAC9C,QAAA,MAAM,OAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,OAAA,IAAsB,EAAA;AAErD,QAAA,IAAI,cAAc,EAAA,EAAI;AACpB,UAAA,QAAA,CACG,MAAA,CAAO,GAAG,CAAA,CACV,IAAA;AAAA,YACC;AAAA,WACF;AACF,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,YAAA,GACJ,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,IAAI,EAAE,MAAA,KAAW,CAAA,GAAI,EAAC,GAAI,OAAA,CAAQ,IAAA;AACxD,QAAA,IAAI,CAAC,YAAA,IAAgB,YAAA,CAAa,MAAA,KAAW,CAAA,EAAG;AAC9C,UAAA,QAAA,CACG,MAAA,CAAO,GAAG,CAAA,CACV,IAAA;AAAA,YACC;AAAA,WACF;AACF,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,mBAAiD,EAAC;AAExD,QAAA,YAAA,CAAa,OAAA,CAAQ,OAAM,UAAA,KAAc;AACvC,UAAA,gBAAA,CAAiB,IAAA,CAAK;AAAA,YACpB,kBAAA,EAAoB;AAAA,cAClB,EAAA,EAAI,UAAA;AAAA,cACJ,IAAA,EAAM;AAAA,aACR;AAAA,YACA,iBAAA,EAAmB;AAAA,cACjB,EAAA,EAAI,SAAA;AAAA,cACJ,IAAA,EAAM;AAAA;AACR,WACD,CAAA;AAAA,QACH,CAAC,CAAA;AAED,QAAA,MAAMC,2CAAA,CAAkC,kBAAkB,OAAO,CAAA;AAEjE,QAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AAAA,MACzB,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,iBAAiBC,+BAAA,EAAW;AAC9B,UAAA,MAAA,CAAO,KAAA;AAAA,YACL,CAAA,yCAAA,EAA4C,MAAM,OAAO,CAAA;AAAA,WAC3D;AACA,UAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,YACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,WAC5B,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAGA,EAAA,MAAA,CAAO,IAAA,CAAK,kCAAA,EAAoC,OAAO,OAAA,EAAS,QAAA,KAAa;AAC3E,IAAA,IAAI;AAEF,MAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,MAAA,CAAO,SAAA,IAAa,EAAA;AAC9C,MAAA,MAAM,OAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,OAAA,IAAsB,EAAA;AAErD,MAAA,IAAI,cAAc,EAAA,EAAI;AACpB,QAAA,QAAA,CACG,MAAA,CAAO,GAAG,CAAA,CACV,IAAA;AAAA,UACC;AAAA,SACF;AACF,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,YAAA,GACJ,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,IAAI,EAAE,MAAA,KAAW,CAAA,GAAI,EAAC,GAAI,OAAA,CAAQ,IAAA;AACxD,MAAA,IAAI,CAAC,YAAA,IAAgB,YAAA,CAAa,MAAA,KAAW,CAAA,EAAG;AAC9C,QAAA,QAAA,CACG,MAAA,CAAO,GAAG,CAAA,CACV,IAAA;AAAA,UACC;AAAA,SACF;AACF,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,mBAAiD,EAAC;AAExD,MAAA,YAAA,CAAa,OAAA,CAAQ,OAAM,UAAA,KAAc;AACvC,QAAA,gBAAA,CAAiB,IAAA,CAAK;AAAA,UACpB,kBAAA,EAAoB;AAAA,YAClB,EAAA,EAAI,UAAA;AAAA,YACJ,IAAA,EAAM;AAAA,WACR;AAAA,UACA,iBAAA,EAAmB;AAAA,YACjB,EAAA,EAAI,SAAA;AAAA,YACJ,IAAA,EAAM;AAAA;AACR,SACD,CAAA;AAAA,MACH,CAAC,CAAA;AAED,MAAA,MAAMC,sCAAA,CAA6B,kBAAkB,OAAO,CAAA;AAE5D,MAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AAAA,IACzB,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBD,+BAAA,EAAW;AAC9B,QAAA,MAAA,CAAO,KAAA;AAAA,UACL,CAAA,yCAAA,EAA4C,MAAM,OAAO,CAAA;AAAA,SAC3D;AACA,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,kCAAA,EAAoC,OAAO,OAAA,EAAS,QAAA,KAAa;AAC1E,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,GAAY,QAAQ,MAAA,CAAO,SAAA;AACjC,MAAA,MAAM,OAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,OAAA,IAAsB,EAAA;AAErD,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,MAAM,oBAAA,GACJ,MAAME,qCAAA,CAA4B,SAAA,EAAW,OAAO,CAAA;AAEtD,QAAA,IAAI,oBAAA,EAAsB;AACxB,UAAA,QAAA,CAAS,IAAA,CAAK;AAAA,YACZ,aAAA,EAAe;AAAA,WAChB,CAAA;AAAA,QACH;AAAA,MACF,CAAA,MAAO;AACL,QAAA,QAAA,CACG,MAAA,CAAO,GAAG,CAAA,CACV,IAAA;AAAA,UACC;AAAA,SACF;AAAA,MACJ;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBF,+BAAA,EAAW;AAC9B,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,wCAAA;AAAA,IACA,OAAO,SAAS,QAAA,KAAa;AAC3B,MAAA,MAAM,IAAA,GAAO,QAAQ,MAAA,CAAO,IAAA;AAC5B,MAAA,MAAM,SAAA,GAAY,QAAQ,MAAA,CAAO,SAAA;AACjC,MAAA,MAAM,IAAA,GAAO,QAAQ,MAAA,CAAO,IAAA;AAE5B,MAAA,IAAI;AACF,QAAA,IAAI,IAAA,IAAQ,aAAa,IAAA,EAAM;AAC7B,UAAA,MAAM,SAAA,GAAY,GAAG,IAAI,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,EAAI,IAAI,GAAG,WAAA,EAAY;AAC7D,UAAA,MAAM,WAAA,GAAc,MAAM,UAAA,EAAY,cAAA,CAAe,SAAS,CAAA;AAE9D,UAAA,IAAI,WAAA,EAAa;AACf,YAAA,QAAA,CAAS,IAAA;AAAA,cACP,WAAA,CAAY,QAAA,CAAS,WAAA,GAAc,0BAA0B;AAAA,aAC/D;AAAA,UACF,CAAA,MAAO;AACL,YAAA,QAAA,CAAS,OAAO,GAAG,CAAA;AAAA,UACrB;AAAA,QACF,CAAA,MAAO;AACL,UAAA,QAAA,CACG,MAAA,CAAO,GAAG,CAAA,CACV,IAAA;AAAA,YACC;AAAA,WACF;AAAA,QACJ;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,iBAAiBA,+BAAA,EAAW;AAC9B,UAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,YACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,WAC5B,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAGA,EAAA,MAAA,CAAO,IAAA,CAAK,WAAA,EAAa,OAAO,OAAA,EAAS,QAAA,KAAa;AACpD,IAAA,IAAI;AAEF,MAAA,MAAM,WAA+B,OAAA,CAAQ,IAAA;AAG7C,MAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,QACZ,QAAA,CAAS,GAAA,CAAI,OAAM,OAAA,KAAW;AAC5B,UAAA,IAAI,OAAA,CAAQ,EAAA,KAAO,KAAA,CAAA,IAAa,OAAA,CAAQ,UAAU,KAAA,CAAA,EAAW;AAC3D,YAAA,QAAA,CACG,MAAA,CAAO,GAAG,CAAA,CACV,IAAA,CAAK,4CAA4C,CAAA;AACpD,YAAA;AAAA,UACF;AAEA,UAAA,IAAI,CAAC,cAAA,CAAe,OAAA,CAAQ,KAAK,CAAA,EAAG;AAClC,YAAA,QAAA,CACG,MAAA,CAAO,GAAG,CAAA,CACV,IAAA;AAAA,cACC;AAAA,aACF;AACF,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,KAAA,CAAM,cAAc,OAAO,CAAA;AAAA,QACnC,CAAC;AAAA,OACH;AAEA,MAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AAAA,IACzB,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBA,+BAAA,EAAW;AAC9B,QAAA,MAAA,CAAO,KAAA;AAAA,UACL,CAAA,yCAAA,EAA4C,MAAM,OAAO,CAAA;AAAA,SAC3D;AACA,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA,CAAI,sBAAA,EAAwB,OAAO,OAAA,EAAS,QAAA,KAAa;AAC9D,IAAA,IAAI;AAEF,MAAA,MAAM,SAAA,GAAY,QAAQ,MAAA,CAAO,SAAA;AAGjC,MAAA,MAAM,OAAA,GAAU,MAAM,KAAA,CAAM,WAAA,CAAY,SAAS,CAAA;AAEjD,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA;AAC5B,QAAA;AAAA,MACF;AAEA,MAAA,QAAA,CAAS,KAAK,OAAO,CAAA;AAAA,IACvB,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBA,+BAAA,EAAW;AAC9B,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,SAAS,eAAe,KAAA,EAAwB;AAC9C,IAAA,IACE,UAAU,WAAA,IACV,KAAA,KAAU,eACV,KAAA,KAAU,MAAA,IACV,UAAU,UAAA,EACV;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,MAAA,CAAO,IAAA,CAAK,iBAAA,EAAmB,OAAO,OAAA,EAAS,QAAA,KAAa;AAC1D,IAAA,IAAI;AAEF,MAAA,MAAM,SAAiC,OAAA,CAAQ,IAAA;AAE/C,MAAA,IAAI,CAAC,OAAO,SAAA,EAAW;AACrB,QAAA,QAAA,CACG,MAAA,CAAO,GAAG,CAAA,CACV,IAAA;AAAA,UACC;AAAA,SACF;AACF,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,cAAA,GAAiB,MAAM,KAAA,CAAM,oBAAA,EAAqB;AACxD,MAAA,MAAM,aAAa,cAAA,CAAe,IAAA;AAAA,QAChC,CAAA,OAAA,KAAW,OAAA,CAAQ,SAAA,KAAc,MAAA,CAAO;AAAA,OAC1C;AAIA,MAAA,IACE,MAAA,CAAO,cAAc,EAAA,KACpB,MAAA,CAAO,mBAAmB,EAAA,IAAM,MAAA,CAAO,mBAAmB,KAAA,CAAA,CAAA,EAC3D;AACA,QAAA,MAAM,iBAAA,GAAoB,SAAA;AAE1B,QAAA,MAAM,UAAU,MAAMG,wBAAA,CAAe,MAAA,CAAO,SAAA,EAAW,OAAO,OAAO,CAAA;AACrE,QAAA,MAAM,oBAAA,GAAuB,QAAQ,YAAA,EAAc,IAAA;AAAA,UACjD,CAAA,WAAA,KAAe,WAAA,CAAY,MAAA,EAAQ,EAAA,KAAO;AAAA,SAC5C;AAEA,QAAA,IAAI,CAAC,oBAAA,EAAsB;AAGzB,UAAA,MAAM,cAAA,GAAiB,MAAMC,kCAAA,CAAyB;AAAA,YACpD,WAAW,MAAA,CAAO,SAAA;AAAA,YAClB,QAAA,EAAU,iBAAA;AAAA,YACV,SAAS,MAAA,CAAO;AAAA,WACjB,CAAA;AAED,UAAA,MAAA,CAAO,cAAA,GAAiB,cAAA;AAAA,QAC1B,CAAA,MAAO;AACL,UAAA,MAAA,CAAO,iBAAiB,oBAAA,CAAqB,eAAA;AAAA,QAC/C;AAAA,MACF;AAEA,MAAA,MAAM,eAAA,GAAkB,MAAM,KAAA,CAAM,mBAAA,CAAoB,MAAM,CAAA;AAG9D,MAAA,IAAI,MAAA,CAAO,cAAc,EAAA,EAAI;AAE3B,QAAA,MAAM,UAAA,EAAY,aAAA,CAAc,MAAA,CAAO,SAAS,CAAA;AAAA,MAClD;AAEA,MAAA,IAAI,UAAA,IAAc,UAAA,CAAW,SAAA,KAAc,EAAA,EAAI;AAE7C,QAAA,MAAM,UAAA,EAAY,aAAA,CAAc,UAAA,CAAW,SAAS,CAAA;AAAA,MACtD;AAEA,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,EAAA,EAAI,eAAA;AAAA,QACJ,WAAW,MAAA,CAAO,SAAA;AAAA,QAClB,gBAAgB,MAAA,CAAO,cAAA;AAAA,QACvB,WAAW,MAAA,CAAO,SAAA;AAAA,QAClB,QAAQ,MAAA,CAAO,MAAA;AAAA,QACf,SAAS,MAAA,CAAO;AAAA,OACjB,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBJ,+BAAA,EAAW;AAC9B,QAAA,MAAA,CAAO,KAAA;AAAA,UACL,CAAA,yCAAA,EAA4C,MAAM,OAAO,CAAA;AAAA,SAC3D;AACA,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,MAAA,CAAO,KAAA;AAAA,UACL,uDAAuD,KAAK,CAAA;AAAA,SAC9D;AACA,QAAA,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,UACxB,MAAA,EAAQ,CAAC,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC;AAAA,SAChE,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,IAAA,CAAK,wBAAA,EAA0B,OAAO,OAAA,EAAS,QAAA,KAAa;AACjE,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,QAAA,EAAS,GAAI,OAAA,CAAQ,IAAA;AAE7B,MAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAC5B,QAAA,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,UACxB,KAAA,EAAO;AAAA,SACR,CAAA;AACD,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,gBAAA,GAAmB,MAAM,KAAA,CAAM,oBAAA,EAAqB;AAC1D,MAAA,MAAM,qBAAqB,IAAI,GAAA;AAAA,QAC7B,gBAAA,CAAiB,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS;AAAA,OACvC;AAEA,MAAA,MAAM,cAAwC,EAAC;AAC/C,MAAA,MAAM,UAAoC,EAAC;AAC3C,MAAA,MAAM,SAAS,EAAC;AAEhB,MAAA,KAAA,MAAW,UAAU,QAAA,EAAU;AAC7B,QAAA,IAAI,CAAC,OAAO,SAAA,EAAW;AACrB,UAAA,MAAA,CAAO,IAAA,CAAK;AAAA,YACV,WAAW,MAAA,CAAO,SAAA;AAAA,YAClB,KAAA,EAAO;AAAA,WACR,CAAA;AACD,UAAA;AAAA,QACF;AAEA,QAAA,IAAI,kBAAA,CAAmB,GAAA,CAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AAC5C,UAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AACnB,UAAA;AAAA,QACF;AAEA,QAAA,IACE,MAAA,CAAO,cAAc,EAAA,KACpB,MAAA,CAAO,mBAAmB,EAAA,IAAM,MAAA,CAAO,mBAAmB,KAAA,CAAA,CAAA,EAC3D;AACA,UAAA,IAAI;AACF,YAAA,MAAM,iBAAA,GAAoB,SAAA;AAC1B,YAAA,MAAM,UAAU,MAAMG,wBAAA;AAAA,cACpB,MAAA,CAAO,SAAA;AAAA,cACP,MAAA,CAAO;AAAA,aACT;AACA,YAAA,MAAM,oBAAA,GAAuB,QAAQ,YAAA,EAAc,IAAA;AAAA,cACjD,CAAA,WAAA,KAAe,WAAA,CAAY,MAAA,EAAQ,EAAA,KAAO;AAAA,aAC5C;AAEA,YAAA,IAAI,CAAC,oBAAA,EAAsB;AACzB,cAAA,MAAM,cAAA,GAAiB,MAAMC,kCAAA,CAAyB;AAAA,gBACpD,WAAW,MAAA,CAAO,SAAA;AAAA,gBAClB,QAAA,EAAU,iBAAA;AAAA,gBACV,SAAS,MAAA,CAAO;AAAA,eACjB,CAAA;AAED,cAAA,MAAA,CAAO,cAAA,GAAiB,cAAA;AAAA,YAC1B,CAAA,MAAO;AACL,cAAA,MAAA,CAAO,iBAAiB,oBAAA,CAAqB,eAAA;AAAA,YAC/C;AAAA,UACF,SAAS,KAAA,EAAO;AACd,YAAA,MAAA,CAAO,IAAA,CAAK;AAAA,cACV,WAAW,MAAA,CAAO,SAAA;AAAA,cAClB,WAAW,MAAA,CAAO,SAAA;AAAA,cAClB,OACE,KAAA,YAAiB,KAAA,GACb,CAAA,8BAAA,EAAiC,KAAA,CAAM,OAAO,CAAA,CAAA,GAC9C;AAAA,aACP,CAAA;AACD,YAAA;AAAA,UACF;AAAA,QACF;AAEA,QAAA,WAAA,CAAY,KAAK,MAAM,CAAA;AAAA,MACzB;AAEA,MAAA,IAAI,cAAwB,EAAC;AAC7B,MAAA,IAAI,WAAA,CAAY,SAAS,CAAA,EAAG;AAC1B,QAAA,IAAI;AACF,UAAA,WAAA,GAAc,MAAM,KAAA,CAAM,wBAAA,CAAyB,WAAW,CAAA;AAE9D,UAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,YACZ,WAAA,CAAY,GAAA,CAAI,OAAM,MAAA,KAAU;AAC9B,cAAA,IAAI,MAAA,CAAO,cAAc,EAAA,EAAI;AAC3B,gBAAA,MAAM,UAAA,EAAY,aAAA,CAAc,MAAA,CAAO,SAAS,CAAA;AAAA,cAClD;AAAA,YACF,CAAC;AAAA,WACH;AAAA,QACF,SAAS,KAAA,EAAO;AACd,UAAA,MAAA,CAAO,KAAA,CAAM,CAAA,oBAAA,EAAuB,KAAK,CAAA,CAAE,CAAA;AAC3C,UAAA,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,YACxB,MAAA,EAAQ,CAAC,oBAAoB;AAAA,WAC9B,CAAA;AACD,UAAA;AAAA,QACF;AAAA,MACF;AAEA,MAAA,MAAM,OAAA,GAAU,WAAA,CAAY,GAAA,CAAI,CAAC,QAAQ,KAAA,MAAW;AAAA,QAClD,EAAA,EAAI,YAAY,KAAK,CAAA;AAAA,QACrB,WAAW,MAAA,CAAO,SAAA;AAAA,QAClB,gBAAgB,MAAA,CAAO,cAAA;AAAA,QACvB,WAAW,MAAA,CAAO,SAAA;AAAA,QAClB,QAAQ,MAAA,CAAO,MAAA;AAAA,QACf,SAAS,MAAA,CAAO;AAAA,OAClB,CAAE,CAAA;AAEF,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,OAAA;AAAA,QACT,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,CAAA,MAAA,MAAW;AAAA,UAC9B,WAAW,MAAA,CAAO,SAAA;AAAA,UAClB,WAAW,MAAA,CAAO,SAAA;AAAA,UAClB,MAAA,EAAQ;AAAA,SACV,CAAE,CAAA;AAAA,QACF,MAAA;AAAA,QACA,OAAO,QAAA,CAAS,MAAA;AAAA,QAChB,cAAc,OAAA,CAAQ,MAAA;AAAA,QACtB,cAAc,OAAA,CAAQ,MAAA;AAAA,QACtB,YAAY,MAAA,CAAO;AAAA,OACpB,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBJ,+BAAA,EAAW;AAC9B,QAAA,MAAA,CAAO,KAAA;AAAA,UACL,CAAA,+CAAA,EAAkD,MAAM,OAAO,CAAA;AAAA,SACjE;AACA,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,MAAA,CAAO,KAAA,CAAM,CAAA,kBAAA,EAAqB,KAAK,CAAA,CAAE,CAAA;AACzC,QAAA,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,UACxB,MAAA,EAAQ,CAAC,uBAAuB;AAAA,SACjC,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA,CAAI,iBAAA,EAAmB,OAAO,CAAA,EAAG,QAAA,KAAa;AACnD,IAAA,IAAI;AAEF,MAAA,MAAM,cAAA,GAAiB,MAAM,KAAA,CAAM,oBAAA,EAAqB;AAGxD,MAAA,MAAM,iBAAA,GAAoB,MAAM,UAAA,CAAY,WAAA,CAAY;AAAA,QACtD,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM;AAAA;AACR,OACD,CAAA;AAGD,MAAA,MAAM,qBAAA,GAGF,MAAMK,kDAAmB,CAAqC,iBAAiB,CAAA;AAGnF,MAAA,MAAM,iBAAA,GAAoB,MAAMC,wBAAA,EAAe;AAG/C,MAAA,MAAM,SACJ,MAAM,2BAAA;AAAA,QACJ,cAAA;AAAA,QACA,qBAAA;AAAA,QACA,iBAAA;AAAA,QACA;AAAA,OACF;AAEF,MAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AAAA,IACtB,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBN,+BAAA,EAAW;AAC9B,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,KAAK,mBAAA,EAAqBO,qCAAmB,CAAmB,KAAA,EAAO,UAAU,CAAC,CAAA;AAGzF,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,wCAAA;AAAA,IACA,OAAO,SAAS,QAAA,KAAa;AAC3B,MAAA,IAAI;AAEF,QAAA,MAAM,UAAA,GAAqB,OAAA,CAAQ,MAAA,CAAO,IAAA,IAAQ,EAAA;AAClD,QAAA,MAAM,eAAA,GAA0B,OAAA,CAAQ,MAAA,CAAO,SAAA,IAAa,EAAA;AAC5D,QAAA,MAAM,UAAA,GAAqB,OAAA,CAAQ,MAAA,CAAO,IAAA,IAAQ,EAAA;AAElD,QAAA,IAAI,UAAA,KAAe,EAAA,IAAM,eAAA,KAAoB,EAAA,IAAM,eAAe,EAAA,EAAI;AACpE,UAAA,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,gCAAgC,CAAA;AAC1D,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,SAAA,GACJ,GAAG,UAAU,CAAA,CAAA,EAAI,eAAe,CAAA,CAAA,EAAI,UAAU,GAAG,WAAA,EAAY;AAG/D,QAAA,MAAM,aAAA,GAAgB,MAAM,KAAA,CAAM,4BAAA;AAAA,UAChC;AAAA,SACF;AAEA,QAAA,IAAI,CAAC,aAAA,EAAe;AAClB,UAAA,QAAA,CACG,OAAO,GAAG,CAAA,CACV,IAAA,CAAK,CAAA,sBAAA,EAAyB,SAAS,CAAA,WAAA,CAAa,CAAA;AACvD,UAAA;AAAA,QACF;AAEA,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS;AAAA,SACV,CAAA;AAAA,MACH,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,iBAAiBP,+BAAA,EAAW;AAC9B,UAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,YACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,WAC5B,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAGA,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,oCAAA;AAAA,IACA,OAAO,SAAS,QAAA,KAAa;AAC3B,MAAA,IAAI;AAEF,QAAA,MAAM,SAAA,GAAoB,OAAA,CAAQ,MAAA,CAAO,SAAA,IAAa,EAAA;AAEtD,QAAA,IAAI,cAAc,EAAA,EAAI;AACpB,UAAA,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,gCAAgC,CAAA;AAC1D,UAAA;AAAA,QACF;AAGA,QAAA,MAAM,aAAA,GAAgB,MAAM,KAAA,CAAM,4BAAA;AAAA,UAChC;AAAA,SACF;AAEA,QAAA,IAAI,CAAC,aAAA,EAAe;AAClB,UAAA,QAAA,CACG,OAAO,GAAG,CAAA,CACV,IAAA,CAAK,CAAA,sBAAA,EAAyB,SAAS,CAAA,WAAA,CAAa,CAAA;AACvD,UAAA;AAAA,QACF;AAEA,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,OAAA,EAAS;AAAA,SACV,CAAA;AAAA,MACH,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,iBAAiBA,+BAAA,EAAW;AAC9B,UAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,YACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,WAC5B,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAGA,EAAA,MAAA,CAAO,IAAA,CAAK,4BAAA,EAA8B,OAAO,OAAA,EAAS,QAAA,KAAa;AACrE,IAAA,IAAI;AAEF,MAAA,MAAM,SAAA,GAAoB,OAAA,CAAQ,IAAA,CAAK,SAAA,IAAa,GAAA;AACpD,MAAA,MAAM,OAAA,GAA8B,QAAQ,IAAA,CAAK,OAAA;AAEjD,MAAA,IAAI,OAAO,SAAA,KAAc,QAAA,IAAY,SAAA,GAAY,CAAA,IAAK,YAAY,GAAA,EAAK;AACrE,QAAA,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,UACxB,KAAA,EAAO;AAAA,SACR,CAAA;AACD,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,GAAoB,OAAA,CAAQ,IAAA,CAAK,QAAA,IAAY,KAAA;AAEnD,MAAA,MAAM,aAAA,GAAgB,KAAK,GAAA,EAAI;AAC/B,MAAA,MAAM,EAAE,UAAA,EAAY,YAAA,EAAa,GAAI,MAAMQ,0BAAA,CAAgB;AAAA,QACzD;AAAA,OACD,CAAA;AAED,MAAA,MAAM,kBAAA,GAAqB,UACvB,UAAA,CAAW,MAAA,CAAO,aAAW,OAAA,CAAQ,OAAA,KAAY,OAAO,CAAA,GACxD,UAAA;AAEJ,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,aAAA;AAE9B,MAAA,MAAM,cAAA,GAAiB,KAAK,GAAA,EAAI;AAChC,MAAA,MAAM,cAAA,GAAiC,EAAE,SAAA,EAAU;AACnD,MAAA,IAAI,OAAA,GAAUC,0BAAA,CAAY,kBAAA,EAAoB,YAAA,EAAc,cAAc,CAAA;AAE1E,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAA,GAAUC,2CAA4B,OAAO,CAAA;AAAA,MAC/C;AAEA,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,EAAI,GAAI,cAAA;AAE/B,MAAA,MAAM,gBAAA,GAAmB,kBAAA,CAAmB,MAAA,GAAS,YAAA,CAAa,MAAA;AAClE,MAAA,MAAM,eAAe,OAAA,CAAQ,MAAA,CAAO,OAAK,CAAA,CAAE,KAAA,KAAU,GAAG,CAAA,CAAE,MAAA;AAC1D,MAAA,MAAM,iBAAiB,OAAA,CAAQ,MAAA;AAAA,QAC7B,CAAA,CAAA,KAAK,CAAA,CAAE,KAAA,IAAS,EAAA,IAAM,EAAE,KAAA,GAAQ;AAAA,OAClC,CAAE,MAAA;AACF,MAAA,MAAM,mBAAmB,OAAA,CAAQ,MAAA;AAAA,QAC/B,CAAA,CAAA,KAAK,CAAA,CAAE,KAAA,IAAS,EAAA,IAAM,EAAE,KAAA,GAAQ;AAAA,OAClC,CAAE,MAAA;AAEF,MAAA,MAAM,kBAAA,GAAqB,CACzB,KAAA,KACwC;AACxC,QAAA,IAAI,KAAA,KAAU,KAAK,OAAO,OAAA;AAC1B,QAAA,IAAI,KAAA,IAAS,IAAI,OAAO,MAAA;AACxB,QAAA,IAAI,KAAA,IAAS,IAAI,OAAO,QAAA;AACxB,QAAA,OAAO,KAAA;AAAA,MACT,CAAA;AAEA,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAA,MAAM;AAAA,UACzB,gBAAA,EAAkB;AAAA,YAChB,SAAA,EAAW,EAAE,gBAAA,CAAiB,QAAA;AAAA,YAC9B,IAAA,EAAM,EAAE,gBAAA,CAAiB,OAAA;AAAA,YACzB,IAAA,EAAM,EAAE,gBAAA,CAAiB,QAAA;AAAA,YACzB,OAAA,EAAS,EAAE,gBAAA,CAAiB;AAAA,WAC9B;AAAA,UACA,kBAAA,EAAoB;AAAA,YAClB,SAAA,EAAW,EAAE,kBAAA,CAAmB,QAAA;AAAA,YAChC,IAAA,EAAM,EAAE,kBAAA,CAAmB,OAAA;AAAA,YAC3B,KAAA,EAAO,EAAE,kBAAA,CAAmB;AAAA,WAC9B;AAAA,UACA,OAAO,CAAA,CAAE,KAAA;AAAA,UACT,UAAA,EAAY,kBAAA,CAAmB,CAAA,CAAE,KAAK,CAAA;AAAA,UACtC,gBAAgB,CAAA,CAAE;AAAA,SACpB,CAAE,CAAA;AAAA,QACF,UAAA,EAAY;AAAA,UACV,wBAAwB,kBAAA,CAAmB,MAAA;AAAA,UAC3C,0BAA0B,YAAA,CAAa,MAAA;AAAA,UACvC,wBAAA,EAA0B,gBAAA;AAAA,UAC1B,cAAc,OAAA,CAAQ,MAAA;AAAA,UACtB,YAAA;AAAA,UACA,qBAAA,EAAuB,cAAA;AAAA,UACvB,uBAAA,EAAyB,gBAAA;AAAA,UACzB,SAAA;AAAA,UACA,UAAA,EAAY,QAAA;AAAA,UACZ,WAAA,EAAa,SAAA;AAAA,UACb,aAAa,QAAA,GAAW;AAAA;AAC1B,OACD,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,MAAA,CAAO,KAAA,CAAM,CAAA,mBAAA,EAAsB,KAAK,CAAA,CAAE,CAAA;AAC1C,MAAA,IAAI,iBAAiBV,+BAAA,EAAW;AAC9B,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH,CAAA,MAAA,IAAW,iBAAiBW,2BAAA,EAAkB;AAC5C,QAAA,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,UACxB,KAAA,EAAO,iCAAA;AAAA,UACP,SAAS,KAAA,CAAM;AAAA,SAChB,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,UACxB,KAAA,EAAO,mBAAA;AAAA,UACP,SAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,SAC/D,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA,CAAI,sBAAA,EAAwB,OAAO,CAAA,EAAG,QAAA,KAAa;AACxD,IAAA,IAAI;AACF,MAAA,IAAI,oBAAA,GAAuB,MAAMC,kCAAA,EAAyB;AAG1D,MAAA,oBAAA,GAAuB,oBAAA,CAAqB,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AACzD,QAAA,IAAI,CAAA,CAAE,OAAA,KAAY,CAAA,CAAE,OAAA,EAAS;AAC3B,UAAA,OAAO,CAAA,CAAE,IAAA,CAAK,aAAA,CAAc,CAAA,CAAE,IAAI,CAAA;AAAA,QACpC;AACA,QAAA,OAAO,CAAA,CAAE,OAAA,CAAS,aAAA,CAAc,CAAA,CAAE,OAAQ,CAAA;AAAA,MAC5C,CAAC,CAAA;AAED,MAAA,MAAM,kCAAkC,oBAAA,CAAqB,GAAA;AAAA,QAC3D,CAAA,MAAA,KAAU;AACR,UAAA,IAAI,cAAc,MAAA,CAAO,IAAA;AACzB,UAAA,IAAI,MAAA,CAAO,OAAA,IAAW,MAAA,CAAO,OAAA,KAAY,SAAA,EAAW;AAClD,YAAA,WAAA,GAAc,CAAA,CAAA,EAAI,MAAA,CAAO,OAAO,CAAA,EAAA,EAAK,OAAO,IAAI,CAAA,CAAA;AAAA,UAClD;AAEA,UAAA,OAAO;AAAA,YACL,KAAA,EAAO,WAAA;AAAA,YACP,OAAO,MAAA,CAAO;AAAA,WAChB;AAAA,QACF;AAAA,OACF;AAEA,MAAA,QAAA,CAAS,KAAK,+BAA+B,CAAA;AAAA,IAC/C,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBZ,+BAAA,EAAW;AAC9B,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA,CAAI,eAAA,EAAiB,OAAO,OAAA,EAAS,QAAA,KAAa;AACvD,IAAA,IAAI;AAEF,MAAA,MAAM,kBAAA,GACH,OAAA,CAAQ,KAAA,CAAM,qBAAA,IAAoC,EAAA;AACrD,MAAA,MAAM,OAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,OAAA,IAAsB,EAAA;AAErD,MAAA,IAAI,uBAAuB,EAAA,EAAI;AAC7B,QAAA,QAAA,CACG,MAAA,CAAO,GAAG,CAAA,CACV,IAAA,CAAK,oDAAoD,CAAA;AAC5D,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,WAAA,GAAc,MAAMa,wBAAA,CAAe,kBAAA,EAAoB,OAAO,CAAA;AACpE,MAAA,MAAM,mBAAA,GAAoD;AAAA,QACxD,KAAA,EAAO;AAAA,OACT;AAEA,MAAA,QAAA,CAAS,KAAK,mBAAmB,CAAA;AAAA,IACnC,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBb,+BAAA,EAAW;AAC9B,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA,CAAI,sBAAA,EAAwB,OAAO,OAAA,EAAS,QAAA,KAAa;AAC9D,IAAA,IAAI;AAEF,MAAA,MAAM,SAAA,GAAoB,OAAA,CAAQ,MAAA,CAAO,SAAA,IAAa,EAAA;AACtD,MAAA,MAAM,OAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,OAAA,IAAsB,EAAA;AAErD,MAAA,IAAI,cAAc,EAAA,EAAI;AACpB,QAAA,QAAA,CACG,MAAA,CAAO,GAAG,CAAA,CACV,IAAA;AAAA,UACC;AAAA,SACF;AACF,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,OAAA,GAAU,MAAMG,wBAAA,CAAe,SAAA,EAAW,OAAO,CAAA;AACvD,MAAA,MAAM,eAAA,GAA4C;AAAA,QAChD;AAAA,OACF;AAEA,MAAA,QAAA,CAAS,KAAK,eAAe,CAAA;AAAA,IAC/B,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBH,+BAAA,EAAW;AAC9B,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA,CAAI,QAAA,EAAU,OAAO,OAAA,EAAS,QAAA,KAAa;AAChD,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,QAAQ,KAAA,CAAM,OAAA;AAC9B,MAAA,MAAM,KAAA,GAAQ,MAAMc,qBAAA,CAAY,OAAO,CAAA;AACvC,MAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AAAA,IACrB,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBd,+BAAA,EAAW;AAC9B,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAQD,EAAA,MAAA,CAAO,GAAA,CAAI,WAAA,EAAa,OAAO,OAAA,EAAS,QAAA,KAAa;AACnD,IAAA,IAAI;AACF,MAAA,MAAM,cAAA,GAAiB,QAAQ,KAAA,CAAM,eAAA;AACrC,MAAA,MAAM,MAAA,GAAS,QAAQ,KAAA,CAAM,OAAA;AAC7B,MAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,CAAM,KAAA;AAC5B,MAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,CAAM,KAAA,GACxB,SAAS,OAAA,CAAQ,KAAA,CAAM,KAAA,EAAiB,EAAE,CAAA,GAC1C,KAAA,CAAA;AACJ,MAAA,MAAM,OAAA,GAAU,QAAQ,KAAA,CAAM,OAAA;AAG9B,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,MAAM,UAAU,MAAMe,oCAAA;AAAA,UACpB,cAAA;AAAA,UACA,OAAA,IAAW;AAAA,SACb;AACA,QAAA,MAAM,eAAA,GAA4C;AAAA,UAChD;AAAA,SACF;AACA,QAAA,QAAA,CAAS,KAAK,eAAe,CAAA;AAC7B,QAAA;AAAA,MACF;AAGA,MAAA,IAAI,MAAA,IAAU,SAAS,KAAA,EAAO;AAC5B,QAAA,MAAM,YAAA,GAAqC,MAAA,GAAS,CAAC,MAAM,CAAA,GAAI,KAAA,CAAA;AAC/D,QAAA,MAAMC,YAAW,MAAMC,6BAAA;AAAA,UACrB,YAAA;AAAA,UACA,KAAA;AAAA,UACA,KAAA,IAAS,GAAA;AAAA,UACT;AAAA,SACF;AACA,QAAA,QAAA,CAAS,KAAKD,SAAQ,CAAA;AACtB,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,QAAA,GAAW,MAAMV,wBAAA,EAAe;AACtC,MAAA,MAAM,gBAAA,GAA8C;AAAA,QAClD;AAAA,OACF;AACA,MAAA,QAAA,CAAS,KAAK,gBAAgB,CAAA;AAAA,IAChC,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBN,+BAAA,EAAW;AAC9B,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,MAAA,CAAO,KAAA;AAAA,UACL,uDAAuD,KAAK,CAAA;AAAA,SAC9D;AACA,QAAA,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,UACxB,MAAA,EAAQ,CAAC,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC;AAAA,SAChE,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,4CAAA;AAAA,IACA,OAAO,SAAS,QAAA,KAAa;AAC3B,MAAA,IAAI;AACF,QAAA,MAAM,SAAA,GAAoB,OAAA,CAAQ,MAAA,CAAO,SAAA,IAAa,EAAA;AACtD,QAAA,MAAM,QAAA,GAAmB,OAAA,CAAQ,MAAA,CAAO,QAAA,IAAY,EAAA;AACpD,QAAA,MAAM,OAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,OAAA,IAAsB,EAAA;AAErD,QAAA,IAAI,SAAA,KAAc,EAAA,IAAM,QAAA,KAAa,EAAA,EAAI;AACvC,UAAA,QAAA,CACG,MAAA,CAAO,GAAG,CAAA,CACV,IAAA;AAAA,YACC;AAAA,WACF;AACF,UAAA;AAAA,QACF;AAEA,QAAA,MAAM,cAAA,GAAiB,MAAMI,kCAAA,CAAyB;AAAA,UACpD,SAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA,SACD,CAAA;AAED,QAAA,QAAA,CAAS,KAAK,cAAc,CAAA;AAAA,MAC9B,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,iBAAiBJ,+BAAA,EAAW;AAC9B,UAAA,MAAA,CAAO,KAAA;AAAA,YACL,CAAA,yCAAA,EAA4C,MAAM,OAAO,CAAA;AAAA,WAC3D;AACA,UAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,YACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,WAC5B,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAGA,EAAA,MAAA,CAAO,GAAA;AAAA,IACL,oCAAA;AAAA,IACA,OAAO,SAAS,QAAA,KAAa;AAC3B,MAAA,IAAI;AAEF,QAAA,MAAM,SAAA,GAAoB,OAAA,CAAQ,MAAA,CAAO,SAAA,IAAa,EAAA;AACtD,QAAA,MAAM,OAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,OAAA,IAAsB,EAAA;AAErD,QAAA,MAAM,YAAA,GAAe,MAAMkB,yBAAA,CAAgB,SAAA,EAAW,OAAO,CAAA;AAC7D,QAAA,MAAM,oBAAA,GAAsD;AAAA,UAC1D,aAAA,EAAe;AAAA,SACjB;AAEA,QAAA,QAAA,CAAS,KAAK,oBAAoB,CAAA;AAAA,MACpC,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,iBAAiBlB,+BAAA,EAAW;AAC9B,UAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,YACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,WAC5B,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAGA,EAAA,MAAA,CAAO,GAAA,CAAI,gCAAA,EAAkC,OAAO,OAAA,EAAS,QAAA,KAAa;AACxE,IAAA,IAAI;AAEF,MAAA,MAAM,SAAA,GAAoB,OAAA,CAAQ,MAAA,CAAO,SAAA,IAAa,EAAA;AACtD,MAAA,MAAM,OAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,OAAA,IAAsB,EAAA;AAErD,MAAA,MAAM,SAAA,GAAY,MAAMmB,sBAAA,CAAa,SAAA,EAAW,OAAO,CAAA;AACvD,MAAA,MAAM,iBAAA,GAAgD;AAAA,QACpD;AAAA,OACF;AAEA,MAAA,QAAA,CAAS,KAAK,iBAAiB,CAAA;AAAA,IACjC,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBnB,+BAAA,EAAW;AAC9B,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA,CAAI,gCAAA,EAAkC,OAAO,OAAA,EAAS,QAAA,KAAa;AACxE,IAAA,IAAI;AAEF,MAAA,MAAM,SAAA,GAAoB,OAAA,CAAQ,MAAA,CAAO,SAAA,IAAa,EAAA;AACtD,MAAA,MAAM,OAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,OAAA,IAAsB,EAAA;AAErD,MAAA,MAAM,gBAAA,GAAmB,MAAMoB,6BAAA,CAAoB,SAAA,EAAW,OAAO,CAAA;AACrE,MAAA,MAAM,wBAAA,GAA8D;AAAA,QAClE,SAAA,EAAW;AAAA,OACb;AAEA,MAAA,QAAA,CAAS,KAAK,wBAAwB,CAAA;AAAA,IACxC,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBpB,+BAAA,EAAW;AAC9B,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA,CAAI,8BAAA,EAAgC,OAAO,OAAA,EAAS,QAAA,KAAa;AACtE,IAAA,IAAI;AAEF,MAAA,MAAM,SAAA,GAAoB,OAAA,CAAQ,MAAA,CAAO,SAAA,IAAa,EAAA;AACtD,MAAA,MAAM,OAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,OAAA,IAAsB,EAAA;AAErD,MAAA,MAAM,OAAA,GAAU,MAAMqB,2BAAA,CAAkB,SAAA,EAAW,OAAO,CAAA;AAE1D,MAAA,MAAM,eAAA,GAAmD;AAAA,QACvD;AAAA,OACF;AAEA,MAAA,QAAA,CAAS,KAAK,eAAe,CAAA;AAAA,IAC/B,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,iBAAiBrB,+BAAA,EAAW;AAC9B,QAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,CAAE,IAAA,CAAK;AAAA,UACjC,MAAA,EAAQ,CAAC,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE;AAAA,SAC5B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA,CAAI,WAAA,EAAa,OAAO,CAAA,EAAG,QAAA,KAAa;AAC7C,IAAA,IAAI;AACF,MAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,WAAA,CAAY,oBAAoB,CAAA;AAO9D,MAAA,IAAI,cAAA,IAAkB,cAAA,CAAe,MAAA,GAAS,CAAA,EAAG;AAC/C,QAAA,MAAM,QAAA,GAAW,cAAA,CAAe,GAAA,CAAI,CAAA,OAAA,MAAY;AAAA,UAC9C,IAAI,OAAA,CAAQ,EAAA;AAAA,UACZ,SAAA,EAAW,QAAQ,SAAA,IAAa;AAAA,SAClC,CAAE,CAAA;AACF,QAAA,QAAA,CAAS,OAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,UAAU,CAAA;AAAA,MACxC,CAAA,MAAO;AACL,QAAA,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,QAAA,EAAU,IAAI,CAAA;AAAA,MAC5C;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAA,CAAO,KAAA,CAAM,CAAA,wBAAA,EAA2B,KAAK,CAAA,CAAE,CAAA;AAC/C,MAAA,QAAA,CAAS,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,KAAA,EAAO,0BAA0B,CAAA;AAAA,IAC/D;AAAA,EACF,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA,CAAI,SAAA,EAAW,OAAO,CAAA,EAAG,QAAA,KAAa;AAC3C,IAAA,QAAA,CAAS,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,MAAA,EAAQ,MAAM,CAAA;AAAA,EAC5C,CAAC,CAAA;AAGD,EAAA,MAAA,CAAO,GAAA,CAAIsB,4BAAc,CAAA;AAGzB,EAAA,OAAO,MAAA;AACT;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataLoader.cjs.js","sources":["../../src/services/dataLoader.ts"],"sourcesContent":["import { getAllServices } from '../apis/pagerduty';\nimport {\n normalizePagerDutyService,\n normalizeBackstageComponent,\n type NormalizedService,\n} from '../utils/normalization';\nimport type { CatalogApi } from '@backstage/catalog-client';\nimport type { PagerDutyService } from '@pagerduty/backstage-plugin-common';\nimport type { Entity } from '@backstage/catalog-model';\n\nexport class ServiceLoadError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ServiceLoadError';\n }\n}\n\nexport interface DataLoaderContext {\n catalogApi: CatalogApi;\n}\n\nexport interface LoadedSources {\n pdServices: NormalizedService[];\n bsComponents: NormalizedService[];\n}\n\nexport async function loadPagerDutyServices(): Promise<NormalizedService[]> {\n try {\n const services: PagerDutyService[] = await getAllServices();\n\n const normalizedServices: NormalizedService[] = services.map(service => {\n const teamName = service.teams?.[0]?.summary ?? '';\n\n return normalizePagerDutyService(\n service.name,\n teamName,\n service.id,\n );\n });\n\n return normalizedServices;\n } catch (error) {\n throw new ServiceLoadError(\n `Failed to load PagerDuty services: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n}\n\nexport async function loadBackstageComponents({\n catalogApi,\n}: DataLoaderContext): Promise<NormalizedService[]> {\n try {\n\n const response = await catalogApi.getEntities({\n filter: {\n kind: 'Component',\n },\n });\n\n const normalizedComponents: NormalizedService[] = response.items.map(\n (entity: Entity) => {\n const entityRef =\n `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase();\n\n const owner =\n typeof entity.spec?.owner === 'string' ? entity.spec.owner : '';\n\n return normalizeBackstageComponent(\n entity.metadata.name,\n owner,\n entityRef,\n );\n },\n );\n\n return normalizedComponents;\n } catch (error) {\n throw new ServiceLoadError(\n `Failed to load Backstage components: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n}\n\nexport async function loadBothSources(\n context: DataLoaderContext,\n): Promise<LoadedSources> {\n const [pdServices, bsComponents] = await Promise.all([\n loadPagerDutyServices(),\n loadBackstageComponents(context),\n ]);\n\n return {\n pdServices,\n bsComponents,\n };\n}\n"],"names":["getAllServices","normalizePagerDutyService","normalizeBackstageComponent"],"mappings":";;;;;AAUO,MAAM,yBAAyB,KAAA,CAAM;AAAA,EAC1C,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AAAA,EACd;AACF;AAWA,eAAsB,qBAAA,GAAsD;AAC1E,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAA+B,MAAMA,wBAAA,EAAe;AAE1D,IAAA,MAAM,kBAAA,GAA0C,QAAA,CAAS,GAAA,CAAI,CAAA,OAAA,KAAW;AACtE,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,GAAQ,CAAC,GAAG,OAAA,IAAW,EAAA;AAEhD,MAAA,OAAOC,uCAAA;AAAA,QACL,OAAA,CAAQ,IAAA;AAAA,QACR,QAAA;AAAA,QACA,OAAA,CAAQ;AAAA,OACV;AAAA,IACF,CAAC,CAAA;AAED,IAAA,OAAO,kBAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAI,gBAAA;AAAA,MACR,sCACE,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CACvD,CAAA;AAAA,KACF;AAAA,EACF;AACF;AAEA,eAAsB,uBAAA,CAAwB;AAAA,EAC5C;AACF,CAAA,EAAoD;AAClD,EAAA,IAAI;AAEF,IAAA,MAAM,QAAA,GAAW,MAAM,UAAA,CAAW,WAAA,CAAY;AAAA,MAC5C,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM;AAAA;AACR,KACD,CAAA;AAED,IAAA,MAAM,oBAAA,GAA4C,SAAS,KAAA,CAAM,GAAA;AAAA,MAC/D,CAAC,MAAA,KAAmB;AAClB,QAAA,MAAM,SAAA,GACJ,CAAA,EAAG,MAAA,CAAO,IAAI,CAAA,CAAA,EAAI,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,CAAA,EAAI,MAAA,CAAO,QAAA,CAAS,IAAI,GAAG,WAAA,EAAY;AAEpF,QAAA,MAAM,KAAA,GACJ,OAAO,MAAA,CAAO,IAAA,EAAM,UAAU,QAAA,GAAW,MAAA,CAAO,KAAK,KAAA,GAAQ,EAAA;AAE/D,QAAA,OAAOC,yCAAA;AAAA,UACL,OAAO,QAAA,CAAS,IAAA;AAAA,UAChB,KAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,KACF;AAEA,IAAA,OAAO,oBAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAI,gBAAA;AAAA,MACR,wCACE,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CACvD,CAAA;AAAA,KACF;AAAA,EACF;AACF;AAEA,eAAsB,gBACpB,OAAA,EACwB;AACxB,EAAA,MAAM,CAAC,UAAA,EAAY,YAAY,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,IACnD,qBAAA,EAAsB;AAAA,IACtB,wBAAwB,OAAO;AAAA,GAChC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA;AAAA,GACF;AACF;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"dataLoader.cjs.js","sources":["../../src/services/dataLoader.ts"],"sourcesContent":["import { getAllServices } from '../apis/pagerduty';\nimport {\n normalizePagerDutyService,\n normalizeBackstageComponent,\n type NormalizedService,\n} from '../utils/normalization';\nimport type { CatalogApi } from '@backstage/catalog-client';\nimport type { PagerDutyService } from '@pagerduty/backstage-plugin-common';\nimport type { Entity } from '@backstage/catalog-model';\n\nexport class ServiceLoadError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ServiceLoadError';\n }\n}\n\nexport interface DataLoaderContext {\n catalogApi: CatalogApi;\n}\n\nexport interface LoadedSources {\n pdServices: NormalizedService[];\n bsComponents: NormalizedService[];\n}\n\nexport async function loadPagerDutyServices(): Promise<NormalizedService[]> {\n try {\n const services: PagerDutyService[] = await getAllServices();\n\n const normalizedServices: NormalizedService[] = services.map(service => {\n const teamName = service.teams?.[0]?.summary ?? '';\n\n return normalizePagerDutyService(\n service.name,\n teamName,\n service.id,\n service.account,\n );\n });\n\n return normalizedServices;\n } catch (error) {\n throw new ServiceLoadError(\n `Failed to load PagerDuty services: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n}\n\nexport async function loadBackstageComponents({\n catalogApi,\n}: DataLoaderContext): Promise<NormalizedService[]> {\n try {\n\n const response = await catalogApi.getEntities({\n filter: {\n kind: 'Component',\n },\n });\n\n const normalizedComponents: NormalizedService[] = response.items.map(\n (entity: Entity) => {\n const entityRef =\n `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase();\n\n const owner =\n typeof entity.spec?.owner === 'string' ? entity.spec.owner : '';\n\n return normalizeBackstageComponent(\n entity.metadata.name,\n owner,\n entityRef,\n );\n },\n );\n\n return normalizedComponents;\n } catch (error) {\n throw new ServiceLoadError(\n `Failed to load Backstage components: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n}\n\nexport async function loadBothSources(\n context: DataLoaderContext,\n): Promise<LoadedSources> {\n const [pdServices, bsComponents] = await Promise.all([\n loadPagerDutyServices(),\n loadBackstageComponents(context),\n ]);\n\n return {\n pdServices,\n bsComponents,\n };\n}\n"],"names":["getAllServices","normalizePagerDutyService","normalizeBackstageComponent"],"mappings":";;;;;AAUO,MAAM,yBAAyB,KAAA,CAAM;AAAA,EAC1C,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AAAA,EACd;AACF;AAWA,eAAsB,qBAAA,GAAsD;AAC1E,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAA+B,MAAMA,wBAAA,EAAe;AAE1D,IAAA,MAAM,kBAAA,GAA0C,QAAA,CAAS,GAAA,CAAI,CAAA,OAAA,KAAW;AACtE,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,GAAQ,CAAC,GAAG,OAAA,IAAW,EAAA;AAEhD,MAAA,OAAOC,uCAAA;AAAA,QACL,OAAA,CAAQ,IAAA;AAAA,QACR,QAAA;AAAA,QACA,OAAA,CAAQ,EAAA;AAAA,QACR,OAAA,CAAQ;AAAA,OACV;AAAA,IACF,CAAC,CAAA;AAED,IAAA,OAAO,kBAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAI,gBAAA;AAAA,MACR,sCACE,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CACvD,CAAA;AAAA,KACF;AAAA,EACF;AACF;AAEA,eAAsB,uBAAA,CAAwB;AAAA,EAC5C;AACF,CAAA,EAAoD;AAClD,EAAA,IAAI;AAEF,IAAA,MAAM,QAAA,GAAW,MAAM,UAAA,CAAW,WAAA,CAAY;AAAA,MAC5C,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM;AAAA;AACR,KACD,CAAA;AAED,IAAA,MAAM,oBAAA,GAA4C,SAAS,KAAA,CAAM,GAAA;AAAA,MAC/D,CAAC,MAAA,KAAmB;AAClB,QAAA,MAAM,SAAA,GACJ,CAAA,EAAG,MAAA,CAAO,IAAI,CAAA,CAAA,EAAI,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,CAAA,EAAI,MAAA,CAAO,QAAA,CAAS,IAAI,GAAG,WAAA,EAAY;AAEpF,QAAA,MAAM,KAAA,GACJ,OAAO,MAAA,CAAO,IAAA,EAAM,UAAU,QAAA,GAAW,MAAA,CAAO,KAAK,KAAA,GAAQ,EAAA;AAE/D,QAAA,OAAOC,yCAAA;AAAA,UACL,OAAO,QAAA,CAAS,IAAA;AAAA,UAChB,KAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,KACF;AAEA,IAAA,OAAO,oBAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAI,gBAAA;AAAA,MACR,wCACE,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CACvD,CAAA;AAAA,KACF;AAAA,EACF;AACF;AAEA,eAAsB,gBACpB,OAAA,EACwB;AACxB,EAAA,MAAM,CAAC,UAAA,EAAY,YAAY,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,IACnD,qBAAA,EAAsB;AAAA,IACtB,wBAAwB,OAAO;AAAA,GAChC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA;AAAA,GACF;AACF;;;;;;;"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var pagerduty = require('../../apis/pagerduty.cjs.js');
|
|
4
|
+
|
|
5
|
+
async function getServicesIdsByPartialName(partialName) {
|
|
6
|
+
const pagerdutyServices = await pagerduty.getServicesByPartialName(partialName);
|
|
7
|
+
return pagerdutyServices.map((service) => service.id);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
exports.getServicesIdsByPartialName = getServicesIdsByPartialName;
|
|
11
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../src/services/pagerduty/index.ts"],"sourcesContent":["import { getServicesByPartialName } from \"../../apis/pagerduty\";\n\nexport async function getServicesIdsByPartialName(partialName: string): Promise<string[]> {\n const pagerdutyServices = await getServicesByPartialName(partialName);\n\n return pagerdutyServices.map(service => service.id);\n}\n"],"names":["getServicesByPartialName"],"mappings":";;;;AAEA,eAAsB,4BAA4B,WAAA,EAAwC;AACxF,EAAA,MAAM,iBAAA,GAAoB,MAAMA,kCAAA,CAAyB,WAAW,CAAA;AAEpE,EAAA,OAAO,iBAAA,CAAkB,GAAA,CAAI,CAAA,OAAA,KAAW,OAAA,CAAQ,EAAE,CAAA;AACpD;;;;"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var pagerduty = require('../apis/pagerduty.cjs.js');
|
|
4
|
+
|
|
5
|
+
function entityRef(entity) {
|
|
6
|
+
return `${entity.kind}:${entity.metadata.namespace ?? "default"}/${entity.metadata.name}`.toLowerCase();
|
|
7
|
+
}
|
|
8
|
+
function getPagerDutyIntegrationKey(entity) {
|
|
9
|
+
return entity.metadata.annotations?.["pagerduty.com/integration-key"];
|
|
10
|
+
}
|
|
11
|
+
function getPagerDutyServiceId(entity) {
|
|
12
|
+
return entity.metadata.annotations?.["pagerduty.com/service-id"];
|
|
13
|
+
}
|
|
14
|
+
function getPagerDutyAccount(entity) {
|
|
15
|
+
return entity.metadata.annotations?.["pagerduty.com/account"];
|
|
16
|
+
}
|
|
17
|
+
async function createComponentEntitiesReferenceDict({
|
|
18
|
+
items: componentEntities
|
|
19
|
+
}) {
|
|
20
|
+
const componentEntitiesDict = {};
|
|
21
|
+
await Promise.all(
|
|
22
|
+
componentEntities.map(async (entity) => {
|
|
23
|
+
const serviceId = getPagerDutyServiceId(entity);
|
|
24
|
+
const integrationKey = getPagerDutyIntegrationKey(entity);
|
|
25
|
+
const account = getPagerDutyAccount(entity);
|
|
26
|
+
if (serviceId) {
|
|
27
|
+
componentEntitiesDict[serviceId] = {
|
|
28
|
+
ref: entityRef(entity),
|
|
29
|
+
name: entity?.metadata.name ?? ""
|
|
30
|
+
};
|
|
31
|
+
} else if (integrationKey) {
|
|
32
|
+
const service = await pagerduty.getServiceByIntegrationKey(integrationKey, account).catch(() => void 0);
|
|
33
|
+
if (service) {
|
|
34
|
+
componentEntitiesDict[service.id] = {
|
|
35
|
+
ref: entityRef(entity).toLowerCase(),
|
|
36
|
+
name: entity?.metadata.name ?? ""
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
return componentEntitiesDict;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
exports.createComponentEntitiesReferenceDict = createComponentEntitiesReferenceDict;
|
|
46
|
+
exports.entityRef = entityRef;
|
|
47
|
+
exports.getPagerDutyAccount = getPagerDutyAccount;
|
|
48
|
+
exports.getPagerDutyIntegrationKey = getPagerDutyIntegrationKey;
|
|
49
|
+
exports.getPagerDutyServiceId = getPagerDutyServiceId;
|
|
50
|
+
//# sourceMappingURL=catalog-entity.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-entity.cjs.js","sources":["../../src/utils/catalog-entity.ts"],"sourcesContent":["import { GetEntitiesByRefsResponse, GetEntitiesResponse } from \"@backstage/catalog-client\";\nimport { getServiceByIntegrationKey } from \"../apis/pagerduty\";\n\n// simplification of the CatalogEntity type - this type is not publicly exposed by the catalog-client package.\ninterface CatalogEntity {\n kind: string;\n metadata: {\n namespace?: string;\n name: string;\n annotations?: {\n [key: string]: string;\n };\n }; \n}\n\nexport function entityRef(entity: CatalogEntity): string {\n return `${entity.kind}:${entity.metadata.namespace ?? 'default'}/${entity.metadata.name}`.toLowerCase();\n}\n\nexport function getPagerDutyIntegrationKey(entity: CatalogEntity): string | undefined {\n return entity.metadata.annotations?.['pagerduty.com/integration-key'];\n}\n\nexport function getPagerDutyServiceId(entity: CatalogEntity): string | undefined {\n return entity.metadata.annotations?.['pagerduty.com/service-id'];\n}\n\nexport function getPagerDutyAccount(entity: CatalogEntity): string | undefined {\n return entity.metadata.annotations?.['pagerduty.com/account'];\n}\n\nexport async function createComponentEntitiesReferenceDict({\n items: componentEntities,\n}: GetEntitiesResponse | GetEntitiesByRefsResponse): Promise<Record<string, { ref: string; name: string }>> {\n const componentEntitiesDict: Record<string, { ref: string; name: string }> = {};\n\n await Promise.all(\n componentEntities.map(async entity => {\n const serviceId = getPagerDutyServiceId(entity!);\n const integrationKey = getPagerDutyIntegrationKey(entity!);\n const account = getPagerDutyAccount(entity!);\n\n if (serviceId) {\n componentEntitiesDict[serviceId] = {\n ref: entityRef(entity!),\n name: entity?.metadata.name ?? '',\n };\n } else if (integrationKey) {\n // get service id from integration key, we ignore errors here since we're focused\n // only on building a mapping between valid service IDs and the corresponding Backstage entity\n const service = await getServiceByIntegrationKey(integrationKey, account,).catch(() => undefined);\n\n if (service) {\n componentEntitiesDict[service.id] = {\n ref: entityRef(entity!).toLowerCase(),\n name: entity?.metadata.name ?? '',\n };\n }\n }\n }),\n );\n\n return componentEntitiesDict;\n}\n"],"names":["getServiceByIntegrationKey"],"mappings":";;;;AAeO,SAAS,UAAU,MAAA,EAA+B;AACvD,EAAA,OAAO,CAAA,EAAG,MAAA,CAAO,IAAI,CAAA,CAAA,EAAI,MAAA,CAAO,QAAA,CAAS,SAAA,IAAa,SAAS,CAAA,CAAA,EAAI,MAAA,CAAO,QAAA,CAAS,IAAI,GAAG,WAAA,EAAY;AACxG;AAEO,SAAS,2BAA2B,MAAA,EAA2C;AACpF,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,+BAA+B,CAAA;AACtE;AAEO,SAAS,sBAAsB,MAAA,EAA2C;AAC/E,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,0BAA0B,CAAA;AACjE;AAEO,SAAS,oBAAoB,MAAA,EAA2C;AAC7E,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,uBAAuB,CAAA;AAC9D;AAEA,eAAsB,oCAAA,CAAqC;AAAA,EACzD,KAAA,EAAO;AACT,CAAA,EAA4G;AAC1G,EAAA,MAAM,wBAAuE,EAAC;AAE9E,EAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,IACZ,iBAAA,CAAkB,GAAA,CAAI,OAAM,MAAA,KAAU;AACpC,MAAA,MAAM,SAAA,GAAY,sBAAsB,MAAO,CAAA;AAC/C,MAAA,MAAM,cAAA,GAAiB,2BAA2B,MAAO,CAAA;AACzD,MAAA,MAAM,OAAA,GAAU,oBAAoB,MAAO,CAAA;AAE3C,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,qBAAA,CAAsB,SAAS,CAAA,GAAI;AAAA,UACjC,GAAA,EAAK,UAAU,MAAO,CAAA;AAAA,UACtB,IAAA,EAAM,MAAA,EAAQ,QAAA,CAAS,IAAA,IAAQ;AAAA,SACjC;AAAA,MACF,WAAW,cAAA,EAAgB;AAGzB,QAAA,MAAM,OAAA,GAAU,MAAMA,oCAAA,CAA2B,cAAA,EAAgB,OAAQ,CAAA,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AAEhG,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,qBAAA,CAAsB,OAAA,CAAQ,EAAE,CAAA,GAAI;AAAA,YAClC,GAAA,EAAK,SAAA,CAAU,MAAO,CAAA,CAAE,WAAA,EAAY;AAAA,YACpC,IAAA,EAAM,MAAA,EAAQ,QAAA,CAAS,IAAA,IAAQ;AAAA,WACjC;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,GACH;AAEA,EAAA,OAAO,qBAAA;AACT;;;;;;;;"}
|
|
@@ -38,14 +38,15 @@ function extractAcronym(name) {
|
|
|
38
38
|
}
|
|
39
39
|
return "";
|
|
40
40
|
}
|
|
41
|
-
function normalizePagerDutyService(name, teamName, serviceId) {
|
|
41
|
+
function normalizePagerDutyService(name, teamName, serviceId, account) {
|
|
42
42
|
return {
|
|
43
43
|
rawName: name,
|
|
44
44
|
normalizedName: normalizeName(name),
|
|
45
45
|
teamName: normalizeName(teamName),
|
|
46
46
|
acronym: extractAcronym(name),
|
|
47
47
|
sourceId: serviceId,
|
|
48
|
-
source: "pagerduty"
|
|
48
|
+
source: "pagerduty",
|
|
49
|
+
account
|
|
49
50
|
};
|
|
50
51
|
}
|
|
51
52
|
function normalizeBackstageComponent(name, owner, entityRef) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalization.cjs.js","sources":["../../src/utils/normalization.ts"],"sourcesContent":["export function normalizeName(name: string): string {\n if (!name) {\n return '';\n }\n\n let normalized = name.toLowerCase();\n normalized = normalized.replace(/_/g, ' ').replace(/-/g, ' ');\n normalized = normalized.replace(/\\s+/g, ' ');\n\n return normalized.trim();\n}\n\nexport function extractAcronym(name: string): string {\n if (!name) {\n return '';\n }\n\n if (name.length <= 5 && /^[A-Z]+$/.test(name)) {\n return name;\n }\n\n if (/[\\s\\-_\\/]/.test(name)) {\n const words = name.split(/[\\s\\-_\\/]+/).filter(word => word.length > 0);\n\n if (words.length === 0) {\n return '';\n }\n\n const acronym = words\n .map(word => word.charAt(0).toUpperCase())\n .join('');\n\n return acronym;\n }\n\n const withBoundaries = name\n .replace(/([a-z])([A-Z])/g, '$1|$2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1|$2');\n\n const words = withBoundaries.split('|').filter(word => word.length > 0);\n\n if (words.length > 1) {\n return words\n .map(word => word.charAt(0).toUpperCase())\n .join('');\n }\n\n const capitals = name.match(/[A-Z]/g);\n if (capitals && capitals.length > 1) {\n return capitals.join('');\n }\n\n if (name.length > 0) {\n return name.charAt(0).toUpperCase();\n }\n\n return '';\n}\n\nexport interface NormalizedService {\n rawName: string;\n normalizedName: string;\n teamName: string;\n acronym: string;\n sourceId: string;\n source: 'pagerduty' | 'backstage';\n}\n\nexport function normalizePagerDutyService(\n name: string,\n teamName: string,\n serviceId: string,\n): NormalizedService {\n return {\n rawName: name,\n normalizedName: normalizeName(name),\n teamName: normalizeName(teamName),\n acronym: extractAcronym(name),\n sourceId: serviceId,\n source: 'pagerduty',\n };\n}\n\nexport function normalizeBackstageComponent(\n name: string,\n owner: string,\n entityRef: string,\n): NormalizedService {\n return {\n rawName: name,\n normalizedName: normalizeName(name),\n teamName: normalizeName(owner),\n acronym: extractAcronym(name),\n sourceId: entityRef,\n source: 'backstage',\n };\n}\n"],"names":["words"],"mappings":";;AAAO,SAAS,cAAc,IAAA,EAAsB;AAClD,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,IAAI,UAAA,GAAa,KAAK,WAAA,EAAY;AAClC,EAAA,UAAA,GAAa,WAAW,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA,CAAE,OAAA,CAAQ,MAAM,GAAG,CAAA;AAC5D,EAAA,UAAA,GAAa,UAAA,CAAW,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA;AAE3C,EAAA,OAAO,WAAW,IAAA,EAAK;AACzB;AAEO,SAAS,eAAe,IAAA,EAAsB;AACnD,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,IAAI,KAAK,MAAA,IAAU,CAAA,IAAK,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA,EAAG;AAC7C,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA,EAAG;AAC1B,IAAA,MAAMA,MAAAA,GAAQ,KAAK,KAAA,CAAM,YAAY,EAAE,MAAA,CAAO,CAAA,IAAA,KAAQ,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AAErE,IAAA,IAAIA,MAAAA,CAAM,WAAW,CAAA,EAAG;AACtB,MAAA,OAAO,EAAA;AAAA,IACT;AAEA,IAAA,MAAM,OAAA,GAAUA,MAAAA,CACb,GAAA,CAAI,CAAA,IAAA,KAAQ,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,CACxC,IAAA,CAAK,EAAE,CAAA;AAEV,IAAA,OAAO,OAAA;AAAA,EACT;AAEA,EAAA,MAAM,cAAA,GAAiB,KACpB,OAAA,CAAQ,iBAAA,EAAmB,OAAO,CAAA,CAClC,OAAA,CAAQ,yBAAyB,OAAO,CAAA;AAE3C,EAAA,MAAM,KAAA,GAAQ,eAAe,KAAA,CAAM,GAAG,EAAE,MAAA,CAAO,CAAA,IAAA,KAAQ,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AAEtE,EAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,IAAA,OAAO,KAAA,CACJ,GAAA,CAAI,CAAA,IAAA,KAAQ,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA,CACxC,IAAA,CAAK,EAAE,CAAA;AAAA,EACZ;AAEA,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA;AACpC,EAAA,IAAI,QAAA,IAAY,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AACnC,IAAA,OAAO,QAAA,CAAS,KAAK,EAAE,CAAA;AAAA,EACzB;AAEA,EAAA,IAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AACnB,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAY;AAAA,EACpC;AAEA,EAAA,OAAO,EAAA;AACT;
|
|
1
|
+
{"version":3,"file":"normalization.cjs.js","sources":["../../src/utils/normalization.ts"],"sourcesContent":["export function normalizeName(name: string): string {\n if (!name) {\n return '';\n }\n\n let normalized = name.toLowerCase();\n normalized = normalized.replace(/_/g, ' ').replace(/-/g, ' ');\n normalized = normalized.replace(/\\s+/g, ' ');\n\n return normalized.trim();\n}\n\nexport function extractAcronym(name: string): string {\n if (!name) {\n return '';\n }\n\n if (name.length <= 5 && /^[A-Z]+$/.test(name)) {\n return name;\n }\n\n if (/[\\s\\-_\\/]/.test(name)) {\n const words = name.split(/[\\s\\-_\\/]+/).filter(word => word.length > 0);\n\n if (words.length === 0) {\n return '';\n }\n\n const acronym = words\n .map(word => word.charAt(0).toUpperCase())\n .join('');\n\n return acronym;\n }\n\n const withBoundaries = name\n .replace(/([a-z])([A-Z])/g, '$1|$2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1|$2');\n\n const words = withBoundaries.split('|').filter(word => word.length > 0);\n\n if (words.length > 1) {\n return words\n .map(word => word.charAt(0).toUpperCase())\n .join('');\n }\n\n const capitals = name.match(/[A-Z]/g);\n if (capitals && capitals.length > 1) {\n return capitals.join('');\n }\n\n if (name.length > 0) {\n return name.charAt(0).toUpperCase();\n }\n\n return '';\n}\n\nexport interface NormalizedService {\n rawName: string;\n normalizedName: string;\n teamName: string;\n acronym: string;\n sourceId: string;\n source: 'pagerduty' | 'backstage';\n account?: string;\n}\n\nexport function normalizePagerDutyService(\n name: string,\n teamName: string,\n serviceId: string,\n account?: string,\n): NormalizedService {\n return {\n rawName: name,\n normalizedName: normalizeName(name),\n teamName: normalizeName(teamName),\n acronym: extractAcronym(name),\n sourceId: serviceId,\n source: 'pagerduty',\n account,\n };\n}\n\nexport function normalizeBackstageComponent(\n name: string,\n owner: string,\n entityRef: string,\n): NormalizedService {\n return {\n rawName: name,\n normalizedName: normalizeName(name),\n teamName: normalizeName(owner),\n acronym: extractAcronym(name),\n sourceId: entityRef,\n source: 'backstage',\n };\n}\n"],"names":["words"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagerduty/backstage-plugin-backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"main": "dist/index.cjs.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@backstage/backend-common": "^0.25.0",
|
|
41
|
-
"@backstage/backend-plugin-api": "^1.6.
|
|
41
|
+
"@backstage/backend-plugin-api": "^1.6.2",
|
|
42
42
|
"@backstage/catalog-client": "^1.12.1",
|
|
43
|
-
"@pagerduty/backstage-plugin-common": "~0.
|
|
43
|
+
"@pagerduty/backstage-plugin-common": "~0.3.0",
|
|
44
44
|
"@skyra/jaro-winkler": "^1.1.1",
|
|
45
45
|
"@types/express": "^4.17.6",
|
|
46
46
|
"express": "^4.20.0",
|
|
@@ -51,9 +51,9 @@
|
|
|
51
51
|
"uuid": "^9.0.1"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@backstage/backend-defaults": "^0.
|
|
55
|
-
"@backstage/backend-test-utils": "^1.10.
|
|
56
|
-
"@backstage/cli": "^0.35.
|
|
54
|
+
"@backstage/backend-defaults": "^0.15.1",
|
|
55
|
+
"@backstage/backend-test-utils": "^1.10.4",
|
|
56
|
+
"@backstage/cli": "^0.35.3",
|
|
57
57
|
"jest-mock": "^30.0.2",
|
|
58
58
|
"supertest": "^7.1.3"
|
|
59
59
|
},
|