@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.
@@ -0,0 +1,388 @@
1
+ 'use strict';
2
+
3
+ var index = require('../services/pagerduty/index.cjs.js');
4
+ var catalogEntity = require('../utils/catalog-entity.cjs.js');
5
+ var backstagePluginCommon = require('@pagerduty/backstage-plugin-common');
6
+ var pagerduty = require('../apis/pagerduty.cjs.js');
7
+
8
+ const STATUS_ORDER = {
9
+ "ErrorWhenFetchingService": 0,
10
+ "NotMapped": 1,
11
+ "OutOfSync": 2,
12
+ "InSync": 3
13
+ };
14
+ const MAX_ENTITIES_FOR_POST_PROCESSING = 1e4;
15
+ function compareEntities(a, b, column, direction) {
16
+ let comparison = 0;
17
+ const fieldMap = {
18
+ name: "name",
19
+ team: "owner",
20
+ serviceName: "serviceName",
21
+ status: "status"
22
+ };
23
+ const field = fieldMap[column];
24
+ if (field === "status") {
25
+ const aStatus = a.status || "NotMapped";
26
+ const bStatus = b.status || "NotMapped";
27
+ const aOrder = STATUS_ORDER[aStatus];
28
+ const bOrder = STATUS_ORDER[bStatus];
29
+ comparison = aOrder - bOrder;
30
+ } else {
31
+ const aValue = (a[field] || "").toLowerCase();
32
+ const bValue = (b[field] || "").toLowerCase();
33
+ if (aValue < bValue) {
34
+ comparison = -1;
35
+ } else if (aValue > bValue) {
36
+ comparison = 1;
37
+ }
38
+ }
39
+ return direction === "ascending" ? comparison : -comparison;
40
+ }
41
+ function getMappingEntities(store, catalogApi) {
42
+ return async function getMappingEntitiesFunction(request, response) {
43
+ try {
44
+ const { offset = 0, limit = 10, filters = {}, sort, account } = request.body;
45
+ if (typeof offset !== "number" || typeof limit !== "number" || offset < 0 || limit <= 0) {
46
+ response.status(400).json({ errors: ["Bad Request: 'offset' and 'limit' must be valid numbers"] });
47
+ return;
48
+ }
49
+ const validSortColumns = ["name", "team", "serviceName", "status"];
50
+ const validSortDirections = ["ascending", "descending"];
51
+ if (sort !== void 0) {
52
+ if (typeof sort !== "object" || sort === null) {
53
+ response.status(400).json({ errors: ["Bad Request: 'sort' must be an object"] });
54
+ return;
55
+ }
56
+ if (typeof sort.column !== "string" || !validSortColumns.includes(sort.column)) {
57
+ response.status(400).json({ errors: [`Bad Request: 'sort.column' must be one of: ${validSortColumns.join(", ")}`] });
58
+ return;
59
+ }
60
+ if (typeof sort.direction !== "string" || !validSortDirections.includes(sort.direction)) {
61
+ response.status(400).json({ errors: [`Bad Request: 'sort.direction' must be one of: ${validSortDirections.join(", ")}`] });
62
+ return;
63
+ }
64
+ }
65
+ const hasStatusFilter = filters?.status?.trim();
66
+ const hasNameFilter = filters?.name?.trim();
67
+ const hasTeamNameFilter = filters?.teamName?.trim();
68
+ const needsBothFullTextFilters = hasNameFilter && hasTeamNameFilter;
69
+ const needsSortPostProcessing = !!sort;
70
+ const needsPostProcessing = hasStatusFilter || needsBothFullTextFilters || needsSortPostProcessing;
71
+ const queryOptions = {
72
+ filter: [{ kind: "Component" }],
73
+ limit: needsPostProcessing ? MAX_ENTITIES_FOR_POST_PROCESSING : limit,
74
+ offset: needsPostProcessing ? 0 : offset
75
+ };
76
+ const allEntityMappings = await store.getAllEntityMappings();
77
+ if (filters?.serviceName?.trim()) {
78
+ const serviceQuery = filters.serviceName.trim();
79
+ const matchingPagerDutyServiceIds = await index.getServicesIdsByPartialName(serviceQuery);
80
+ if (matchingPagerDutyServiceIds.length > 0) {
81
+ const mappingsWithMatchingPagerdutyServices = allEntityMappings.filter(
82
+ (mapping) => matchingPagerDutyServiceIds.includes(mapping.serviceId)
83
+ );
84
+ const entityRefs = mappingsWithMatchingPagerdutyServices.map((mapping) => mapping.entityRef).filter(Boolean);
85
+ if (entityRefs.length > 0) {
86
+ queryOptions.filter = entityRefs.map(_extractQueryFilterFromEntityRef).filter((f) => f !== null);
87
+ if (queryOptions.filter.length === 0) {
88
+ response.json({ entities: [], totalCount: 0 });
89
+ return;
90
+ }
91
+ } else {
92
+ response.json({ entities: [], totalCount: 0 });
93
+ return;
94
+ }
95
+ } else {
96
+ response.json({ entities: [], totalCount: 0 });
97
+ return;
98
+ }
99
+ }
100
+ const componentEntities = await _queryEntitiesWithFilters(
101
+ catalogApi,
102
+ queryOptions,
103
+ filters.name,
104
+ filters.teamName
105
+ );
106
+ const currentPageMappings = allEntityMappings.filter((mapping) => {
107
+ return componentEntities.items.some((entity) => {
108
+ const entityRef = catalogEntity.entityRef(entity).toLowerCase();
109
+ const integrationKey = catalogEntity.getPagerDutyIntegrationKey(entity);
110
+ return mapping.entityRef === entityRef || mapping.integrationKey === integrationKey;
111
+ });
112
+ });
113
+ const currentPagePagerDutyServiceIds = currentPageMappings.map((mapping) => mapping.serviceId).filter(Boolean);
114
+ const currentPagePagerDutyServices = await pagerduty.getServicesByIds(currentPagePagerDutyServiceIds);
115
+ const componentEntitiesDict = await catalogEntity.createComponentEntitiesReferenceDict(componentEntities);
116
+ const maps = await _buildEntityMappingsResponse(
117
+ allEntityMappings,
118
+ componentEntitiesDict,
119
+ componentEntities,
120
+ currentPagePagerDutyServices
121
+ );
122
+ let formattedEntities = await Promise.all(
123
+ componentEntities.items.map(async (entity) => {
124
+ const annotations = {
125
+ "pagerduty.com/integration-key": catalogEntity.getPagerDutyIntegrationKey(entity) ?? "",
126
+ "pagerduty.com/service-id": catalogEntity.getPagerDutyServiceId(entity) ?? ""
127
+ };
128
+ const formattedEntity = {
129
+ name: entity.metadata?.name,
130
+ id: entity.metadata?.uid ?? "",
131
+ namespace: entity.metadata?.namespace ?? "",
132
+ type: entity.kind ?? "",
133
+ system: entity.spec?.system ? JSON.stringify(entity.spec?.system) : "",
134
+ owner: entity.spec?.owner ? JSON.stringify(entity.spec?.owner) : "",
135
+ lifecycle: entity.spec?.lifecycle ? JSON.stringify(entity.spec?.lifecycle) : "",
136
+ annotations,
137
+ status: "NotMapped",
138
+ serviceName: "",
139
+ serviceUrl: "",
140
+ team: "",
141
+ escalationPolicy: "",
142
+ account: ""
143
+ };
144
+ let service = null;
145
+ let isServiceError = null;
146
+ if (annotations["pagerduty.com/service-id"]) {
147
+ const serviceId = annotations["pagerduty.com/service-id"];
148
+ service = currentPagePagerDutyServices.find((s) => s.id === serviceId);
149
+ } else if (annotations["pagerduty.com/integration-key"]) {
150
+ const integrationKey = annotations["pagerduty.com/integration-key"];
151
+ const entityAccount = entity.metadata?.annotations?.["pagerduty.com/account"] || "";
152
+ try {
153
+ service = await pagerduty.getServiceByIntegrationKey(integrationKey, entityAccount);
154
+ } catch (e) {
155
+ if (e instanceof backstagePluginCommon.HttpError && e.status !== 404) {
156
+ isServiceError = true;
157
+ }
158
+ }
159
+ }
160
+ const entityRef = catalogEntity.entityRef(entity).toLowerCase();
161
+ const entityMapping = maps.mappings.find(
162
+ (mapping) => mapping.entityRef === entityRef || mapping.integrationKey && mapping.integrationKey === annotations["pagerduty.com/integration-key"] || mapping.serviceId && mapping.serviceId === annotations["pagerduty.com/service-id"]
163
+ );
164
+ if (service) {
165
+ formattedEntity.serviceName = service.name;
166
+ formattedEntity.serviceUrl = service.html_url;
167
+ formattedEntity.team = service.teams?.[0]?.name ?? "";
168
+ formattedEntity.escalationPolicy = service.escalation_policy?.name ?? "";
169
+ formattedEntity.account = service.account || "";
170
+ if (entityMapping) {
171
+ const expectedEntityRef = componentEntitiesDict[service.id]?.ref;
172
+ if (expectedEntityRef && expectedEntityRef === entityMapping.entityRef) {
173
+ formattedEntity.status = entityMapping.status || "NotMapped";
174
+ } else {
175
+ formattedEntity.status = "NotMapped";
176
+ }
177
+ }
178
+ } else if (isServiceError) {
179
+ formattedEntity.status = "ErrorWhenFetchingService";
180
+ }
181
+ return formattedEntity;
182
+ })
183
+ );
184
+ if (hasStatusFilter) {
185
+ formattedEntities = formattedEntities.filter((entity) => entity.status === filters.status.trim());
186
+ }
187
+ if (account) {
188
+ formattedEntities = formattedEntities.filter((entity) => {
189
+ const entityRef = catalogEntity.entityRef({
190
+ kind: entity.type,
191
+ metadata: { name: entity.name, namespace: entity.namespace }
192
+ }).toLowerCase();
193
+ const entityMapping = allEntityMappings.find(
194
+ (mapping) => mapping.entityRef === entityRef
195
+ );
196
+ return entityMapping ? entityMapping.account === account : true;
197
+ });
198
+ }
199
+ if (sort) {
200
+ formattedEntities.sort((a, b) => compareEntities(a, b, sort.column, sort.direction));
201
+ }
202
+ const totalCount = needsPostProcessing ? formattedEntities.length : componentEntities.totalItems;
203
+ const paginatedEntities = needsPostProcessing ? formattedEntities.slice(offset, offset + limit) : formattedEntities;
204
+ response.json({
205
+ entities: paginatedEntities,
206
+ totalCount
207
+ });
208
+ } catch (error) {
209
+ if (error instanceof backstagePluginCommon.HttpError) {
210
+ response.status(error.status).json({
211
+ errors: [`${error.message}`]
212
+ });
213
+ }
214
+ }
215
+ };
216
+ }
217
+ function _extractQueryFilterFromEntityRef(entityRef) {
218
+ const [, namespaceAndName] = entityRef.split(":");
219
+ if (!namespaceAndName) {
220
+ return null;
221
+ }
222
+ const [namespace, name] = namespaceAndName.split("/");
223
+ return {
224
+ kind: "Component",
225
+ "metadata.namespace": namespace,
226
+ "metadata.name": name
227
+ };
228
+ }
229
+ async function _queryEntitiesWithFilters(catalog, baseQueryOptions, nameFilter, teamNameFilter) {
230
+ const hasNameFilter = nameFilter?.trim();
231
+ const hasTeamNameFilter = teamNameFilter?.trim();
232
+ if (hasNameFilter && hasTeamNameFilter) {
233
+ const [nameResults, teamResults] = await Promise.all([
234
+ catalog.queryEntities({
235
+ ...baseQueryOptions,
236
+ fullTextFilter: {
237
+ term: hasNameFilter,
238
+ fields: ["metadata.name"]
239
+ }
240
+ }),
241
+ catalog.queryEntities({
242
+ ...baseQueryOptions,
243
+ fullTextFilter: {
244
+ term: hasTeamNameFilter,
245
+ fields: ["spec.owner"]
246
+ }
247
+ })
248
+ ]);
249
+ const nameResultUids = new Set(nameResults.items.map((entity) => entity.metadata?.uid).filter(Boolean));
250
+ const intersectedEntities = teamResults.items.filter((entity) => nameResultUids.has(entity.metadata?.uid));
251
+ return {
252
+ items: intersectedEntities,
253
+ totalItems: intersectedEntities.length,
254
+ pageInfo: teamResults.pageInfo
255
+ };
256
+ }
257
+ const queryOptions = { ...baseQueryOptions };
258
+ if (hasNameFilter) {
259
+ queryOptions.fullTextFilter = {
260
+ term: hasNameFilter,
261
+ fields: ["metadata.name"]
262
+ };
263
+ } else if (hasTeamNameFilter) {
264
+ queryOptions.fullTextFilter = {
265
+ term: hasTeamNameFilter,
266
+ fields: ["spec.owner"]
267
+ };
268
+ }
269
+ return catalog.queryEntities(queryOptions);
270
+ }
271
+ async function _buildEntityMappingsResponse(entityMappings, componentEntitiesDict, componentEntities, pagerDutyServices) {
272
+ const result = {
273
+ mappings: []
274
+ };
275
+ pagerDutyServices.forEach((service) => {
276
+ const entityRef = componentEntitiesDict[service.id]?.ref;
277
+ const entityName = componentEntitiesDict[service.id]?.name;
278
+ const entityMapping = entityMappings.find((mapping) => mapping.serviceId === service.id);
279
+ if (entityMapping) {
280
+ if (entityRef === void 0) {
281
+ if (entityMapping.entityRef === "" || entityMapping.entityRef === void 0) {
282
+ result.mappings.push({
283
+ entityRef: "",
284
+ entityName: "",
285
+ integrationKey: entityMapping.integrationKey,
286
+ serviceId: entityMapping.serviceId,
287
+ status: "NotMapped",
288
+ serviceName: service.name,
289
+ team: service.teams?.[0]?.name ?? "",
290
+ escalationPolicy: service.escalation_policy !== void 0 ? service.escalation_policy.name : "",
291
+ serviceUrl: service.html_url,
292
+ account: service.account
293
+ });
294
+ } else {
295
+ const entityRefName = componentEntities.items.find(
296
+ (entity) => `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase() === entityMapping.entityRef
297
+ )?.metadata.name ?? "";
298
+ result.mappings.push({
299
+ entityRef: entityMapping.entityRef,
300
+ entityName: entityRefName,
301
+ serviceId: entityMapping.serviceId,
302
+ integrationKey: entityMapping.integrationKey,
303
+ status: "OutOfSync",
304
+ serviceName: service.name,
305
+ team: service.teams?.[0]?.name ?? "",
306
+ escalationPolicy: service.escalation_policy !== void 0 ? service.escalation_policy.name : "",
307
+ serviceUrl: service.html_url,
308
+ account: service.account
309
+ });
310
+ }
311
+ } else if (entityRef !== entityMapping.entityRef) {
312
+ const entityRefName = componentEntities.items.find(
313
+ (entity) => `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase() === entityMapping.entityRef
314
+ )?.metadata.name ?? "";
315
+ result.mappings.push({
316
+ entityRef: entityMapping.entityRef !== "" ? entityMapping.entityRef : "",
317
+ entityName: entityMapping.entityRef !== "" ? entityRefName : "",
318
+ serviceId: entityMapping.serviceId,
319
+ integrationKey: entityMapping.integrationKey,
320
+ status: "OutOfSync",
321
+ serviceName: service.name,
322
+ team: service.teams?.[0]?.name ?? "",
323
+ escalationPolicy: service.escalation_policy !== void 0 ? service.escalation_policy.name : "",
324
+ serviceUrl: service.html_url,
325
+ account: service.account
326
+ });
327
+ } else if (entityRef === entityMapping.entityRef) {
328
+ result.mappings.push({
329
+ entityRef: entityMapping.entityRef !== "" ? entityMapping.entityRef : "",
330
+ entityName: entityMapping.entityRef !== "" ? entityName : "",
331
+ serviceId: entityMapping.serviceId,
332
+ integrationKey: entityMapping.integrationKey,
333
+ status: "InSync",
334
+ serviceName: service.name,
335
+ team: service.teams?.[0]?.name ?? "",
336
+ escalationPolicy: service.escalation_policy !== void 0 ? service.escalation_policy.name : "",
337
+ serviceUrl: service.html_url,
338
+ account: service.account
339
+ });
340
+ }
341
+ } else {
342
+ const backstageVendorId = "PRO19CT";
343
+ const backstageIntegrationKey = service.integrations?.find(
344
+ (integration) => integration.vendor?.id === backstageVendorId
345
+ )?.integration_key ?? "";
346
+ if (entityRef !== void 0) {
347
+ result.mappings.push({
348
+ entityRef,
349
+ entityName,
350
+ serviceId: service.id,
351
+ integrationKey: backstageIntegrationKey,
352
+ status: "InSync",
353
+ serviceName: service.name,
354
+ team: service.teams?.[0]?.name ?? "",
355
+ escalationPolicy: service.escalation_policy !== void 0 ? service.escalation_policy.name : "",
356
+ serviceUrl: service.html_url,
357
+ account: service.account
358
+ });
359
+ } else {
360
+ result.mappings.push({
361
+ entityRef: "",
362
+ entityName: "",
363
+ serviceId: service.id,
364
+ integrationKey: backstageIntegrationKey,
365
+ status: "NotMapped",
366
+ serviceName: service.name,
367
+ team: service.teams?.[0]?.name ?? "",
368
+ escalationPolicy: service.escalation_policy !== void 0 ? service.escalation_policy.name : "",
369
+ serviceUrl: service.html_url,
370
+ account: service.account
371
+ });
372
+ }
373
+ }
374
+ });
375
+ const sortedResult = result.mappings.sort((a, b) => {
376
+ if (a.serviceName < b.serviceName) {
377
+ return -1;
378
+ } else if (a.serviceName > b.serviceName) {
379
+ return 1;
380
+ }
381
+ return 0;
382
+ });
383
+ result.mappings = sortedResult;
384
+ return result;
385
+ }
386
+
387
+ exports.getMappingEntities = getMappingEntities;
388
+ //# sourceMappingURL=mappings-controller.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mappings-controller.cjs.js","sources":["../../src/controllers/mappings-controller.ts"],"sourcesContent":["import { Request, Response } from 'express';\nimport * as Pagerduty from '../services/pagerduty';\nimport * as CatalogEntityUtils from '../utils/catalog-entity';\nimport { PagerDutyBackendStore } from '../db';\nimport { CatalogApi, GetEntitiesResponse, QueryEntitiesResponse } from '@backstage/catalog-client';\nimport { HttpError, PagerDutyEntityMappingsResponse, PagerDutyService, FormattedBackstageEntity } from '@pagerduty/backstage-plugin-common';\nimport { getServiceByIntegrationKey, getServicesByIds } from '../apis/pagerduty';\nimport { RawDbEntityResultRow } from '../db/PagerDutyBackendDatabase';\n\n// Status order for sorting (from least to most complete)\nconst STATUS_ORDER: Record<NonNullable<FormattedBackstageEntity['status']>, number> = {\n 'ErrorWhenFetchingService': 0,\n 'NotMapped': 1,\n 'OutOfSync': 2,\n 'InSync': 3,\n};\n\n// Maximum number of entities to fetch when post-processing filters are needed\nconst MAX_ENTITIES_FOR_POST_PROCESSING = 10000;\n\nfunction compareEntities(\n a: FormattedBackstageEntity,\n b: FormattedBackstageEntity,\n column: string,\n direction: 'ascending' | 'descending',\n): number {\n let comparison = 0;\n\n const fieldMap: Record<string, keyof FormattedBackstageEntity> = {\n name: 'name',\n team: 'owner',\n serviceName: 'serviceName',\n status: 'status',\n };\n\n const field = fieldMap[column];\n\n if (field === 'status') {\n const aStatus = (a.status || 'NotMapped') as NonNullable<FormattedBackstageEntity['status']>;\n const bStatus = (b.status || 'NotMapped') as NonNullable<FormattedBackstageEntity['status']>;\n const aOrder = STATUS_ORDER[aStatus];\n const bOrder = STATUS_ORDER[bStatus];\n comparison = aOrder - bOrder;\n } else {\n const aValue = ((a[field] || '') as string).toLowerCase();\n const bValue = ((b[field] || '') as string).toLowerCase();\n\n if (aValue < bValue) {\n comparison = -1;\n } else if (aValue > bValue) {\n comparison = 1;\n }\n }\n\n return direction === 'ascending' ? comparison : -comparison;\n}\n\nexport function getMappingEntities(store: PagerDutyBackendStore, catalogApi: CatalogApi) {\n return async function getMappingEntitiesFunction(request: Request, response: Response) {\n try {\n const { offset = 0, limit = 10, filters = {}, sort, account } = request.body;\n\n if (typeof offset !== 'number' || typeof limit !== 'number' || offset < 0 || limit <= 0) {\n response\n .status(400)\n .json({ errors: [\"Bad Request: 'offset' and 'limit' must be valid numbers\"] });\n\n return;\n }\n\n const validSortColumns = ['name', 'team', 'serviceName', 'status'];\n const validSortDirections = ['ascending', 'descending'];\n\n if (sort !== undefined) {\n if (typeof sort !== 'object' || sort === null) {\n response\n .status(400)\n .json({ errors: [\"Bad Request: 'sort' must be an object\"] });\n return;\n }\n\n if (typeof sort.column !== 'string' || !validSortColumns.includes(sort.column)) {\n response\n .status(400)\n .json({ errors: [`Bad Request: 'sort.column' must be one of: ${validSortColumns.join(', ')}`] });\n return;\n }\n\n if (typeof sort.direction !== 'string' || !validSortDirections.includes(sort.direction)) {\n response\n .status(400)\n .json({ errors: [`Bad Request: 'sort.direction' must be one of: ${validSortDirections.join(', ')}`] });\n return;\n }\n }\n\n const hasStatusFilter = filters?.status?.trim();\n const hasNameFilter = filters?.name?.trim();\n const hasTeamNameFilter = filters?.teamName?.trim();\n const needsBothFullTextFilters = hasNameFilter && hasTeamNameFilter;\n const needsSortPostProcessing = !!sort;\n\n const needsPostProcessing = hasStatusFilter || needsBothFullTextFilters || needsSortPostProcessing;\n\n const queryOptions: {\n filter: Array<{\n kind: string;\n 'metadata.namespace'?: string;\n 'metadata.name'?: string;\n }>;\n limit: number;\n offset: number;\n fullTextFilter?: { term: string; fields: string[] };\n } = {\n filter: [{ kind: 'Component' }],\n limit: needsPostProcessing ? MAX_ENTITIES_FOR_POST_PROCESSING : limit,\n offset: needsPostProcessing ? 0 : offset,\n };\n\n const allEntityMappings = await store.getAllEntityMappings();\n\n if (filters?.serviceName?.trim()) {\n const serviceQuery = filters.serviceName.trim();\n\n const matchingPagerDutyServiceIds = await Pagerduty.getServicesIdsByPartialName(serviceQuery);\n\n if (matchingPagerDutyServiceIds.length > 0) { \n const mappingsWithMatchingPagerdutyServices = allEntityMappings.filter(\n mapping => matchingPagerDutyServiceIds.includes(mapping.serviceId),\n );\n\n const entityRefs: Array<string> =\n mappingsWithMatchingPagerdutyServices\n .map(mapping => mapping.entityRef)\n .filter(Boolean);\n\n if (entityRefs.length > 0) {\n // extract shape of { kind: 'Component', 'metadata.namespace': string, 'metadata.name': string }\n queryOptions.filter = entityRefs.map(_extractQueryFilterFromEntityRef).filter(f => f !== null);\n\n if (queryOptions.filter.length === 0) {\n response.json({ entities: [], totalCount: 0 });\n return;\n }\n } else {\n response.json({ entities: [], totalCount: 0 });\n return;\n }\n } else {\n response.json({ entities: [], totalCount: 0 });\n return;\n }\n }\n\n const componentEntities = await _queryEntitiesWithFilters(\n catalogApi,\n queryOptions,\n filters.name,\n filters.teamName,\n );\n \n const currentPageMappings = allEntityMappings.filter(mapping => {\n return componentEntities.items.some(entity => {\n const entityRef = CatalogEntityUtils.entityRef(entity).toLowerCase();\n\n const integrationKey = CatalogEntityUtils.getPagerDutyIntegrationKey(entity);\n\n return (mapping.entityRef === entityRef || mapping.integrationKey === integrationKey);\n });\n });\n\n const currentPagePagerDutyServiceIds = currentPageMappings.map(mapping => mapping.serviceId).filter(Boolean);\n\n const currentPagePagerDutyServices = await getServicesByIds(currentPagePagerDutyServiceIds);\n\n const componentEntitiesDict =\n await CatalogEntityUtils.createComponentEntitiesReferenceDict(componentEntities);\n\n const maps = await _buildEntityMappingsResponse(\n allEntityMappings,\n componentEntitiesDict,\n componentEntities,\n currentPagePagerDutyServices,\n );\n\n let formattedEntities: Array<FormattedBackstageEntity> = await Promise.all(\n componentEntities.items.map(async entity => {\n const annotations = {\n 'pagerduty.com/integration-key': CatalogEntityUtils.getPagerDutyIntegrationKey(entity) ?? '',\n 'pagerduty.com/service-id': CatalogEntityUtils.getPagerDutyServiceId(entity) ?? '',\n };\n\n const formattedEntity = {\n name: entity.metadata?.name,\n id: entity.metadata?.uid ?? '',\n namespace: entity.metadata?.namespace ?? '',\n type: entity.kind ?? '',\n system: entity.spec?.system ? JSON.stringify(entity.spec?.system) : '',\n owner: entity.spec?.owner ? JSON.stringify(entity.spec?.owner) : '',\n lifecycle: entity.spec?.lifecycle ? JSON.stringify(entity.spec?.lifecycle) : '',\n annotations,\n status: 'NotMapped' as NonNullable<FormattedBackstageEntity['status']>,\n serviceName: '',\n serviceUrl: '',\n team: '',\n escalationPolicy: '',\n account: '',\n };\n\n // Try to find a service by service ID or integration key\n let service = null;\n let isServiceError = null;\n\n if (annotations['pagerduty.com/service-id']) {\n const serviceId = annotations['pagerduty.com/service-id'];\n service = currentPagePagerDutyServices.find(s => s.id === serviceId);\n } else if (annotations['pagerduty.com/integration-key']) {\n const integrationKey = annotations['pagerduty.com/integration-key'];\n const entityAccount = entity.metadata?.annotations?.['pagerduty.com/account'] || '';\n\n try {\n service = await getServiceByIntegrationKey(integrationKey, entityAccount);\n } catch (e) {\n if (e instanceof HttpError && e.status !== 404) {\n isServiceError = true;\n }\n }\n }\n\n const entityRef = CatalogEntityUtils.entityRef(entity).toLowerCase();\n\n const entityMapping = maps.mappings.find(\n mapping =>\n mapping.entityRef === entityRef ||\n (mapping.integrationKey && mapping.integrationKey === annotations['pagerduty.com/integration-key']) ||\n (mapping.serviceId && mapping.serviceId === annotations['pagerduty.com/service-id']),\n );\n\n if (service) {\n formattedEntity.serviceName = service.name;\n formattedEntity.serviceUrl = service.html_url;\n formattedEntity.team = service.teams?.[0]?.name ?? '';\n formattedEntity.escalationPolicy = service.escalation_policy?.name ?? '';\n formattedEntity.account = service.account || '';\n\n if (entityMapping) {\n const expectedEntityRef = componentEntitiesDict[service.id]?.ref;\n\n if (expectedEntityRef && expectedEntityRef === entityMapping.entityRef) {\n formattedEntity.status = \n (entityMapping.status || 'NotMapped') as NonNullable<FormattedBackstageEntity['status']>;\n } else {\n formattedEntity.status = 'NotMapped' as NonNullable<FormattedBackstageEntity['status']>;\n }\n }\n } else if (isServiceError) {\n formattedEntity.status = 'ErrorWhenFetchingService';\n }\n\n return formattedEntity;\n }),\n );\n\n if (hasStatusFilter) {\n formattedEntities = formattedEntities.filter(entity => entity.status === filters.status.trim());\n }\n\n if (account) {\n formattedEntities = formattedEntities.filter(entity => {\n const entityRef = CatalogEntityUtils.entityRef({\n kind: entity.type,\n metadata: { name: entity.name, namespace: entity.namespace }\n }).toLowerCase();\n\n const entityMapping = allEntityMappings.find(\n mapping => mapping.entityRef === entityRef\n );\n\n return entityMapping ? entityMapping.account === account : true;\n });\n }\n\n if (sort) {\n formattedEntities.sort((a, b) => compareEntities(a, b, sort.column, sort.direction));\n }\n\n const totalCount = needsPostProcessing ? formattedEntities.length : componentEntities.totalItems;\n\n const paginatedEntities = needsPostProcessing\n ? formattedEntities.slice(offset, offset + limit)\n : formattedEntities;\n\n response.json({\n entities: paginatedEntities,\n totalCount,\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\nfunction _extractQueryFilterFromEntityRef(entityRef: string) {\n const [, namespaceAndName] = entityRef.split(':');\n\n if (!namespaceAndName) {\n return null;\n }\n\n const [namespace, name] = namespaceAndName.split('/');\n\n return {\n kind: 'Component',\n 'metadata.namespace': namespace,\n 'metadata.name': name,\n };\n}\n\nasync function _queryEntitiesWithFilters(\n catalog: CatalogApi,\n baseQueryOptions: {\n filter: Array<{\n kind: string;\n 'metadata.namespace'?: string;\n 'metadata.name'?: string;\n }>;\n limit: number;\n offset: number;\n },\n nameFilter?: string,\n teamNameFilter?: string,\n): Promise<QueryEntitiesResponse> {\n const hasNameFilter = nameFilter?.trim();\n const hasTeamNameFilter = teamNameFilter?.trim();\n\n if (hasNameFilter && hasTeamNameFilter) {\n const [nameResults, teamResults] = await Promise.all([\n catalog.queryEntities({\n ...baseQueryOptions,\n fullTextFilter: {\n term: hasNameFilter,\n fields: ['metadata.name'],\n },\n }),\n catalog.queryEntities({\n ...baseQueryOptions,\n fullTextFilter: {\n term: hasTeamNameFilter,\n fields: ['spec.owner'],\n },\n }),\n ]);\n\n const nameResultUids = new Set(nameResults.items.map(entity => entity.metadata?.uid).filter(Boolean));\n\n const intersectedEntities = teamResults.items.filter(entity => nameResultUids.has(entity.metadata?.uid));\n\n return {\n items: intersectedEntities,\n totalItems: intersectedEntities.length,\n pageInfo: teamResults.pageInfo,\n };\n }\n\n const queryOptions: {\n filter: Array<{\n kind: string;\n 'metadata.namespace'?: string;\n 'metadata.name'?: string;\n }>;\n limit: number;\n offset: number;\n fullTextFilter?: { term: string; fields: string[] };\n } = { ...baseQueryOptions };\n\n if (hasNameFilter) {\n queryOptions.fullTextFilter = {\n term: hasNameFilter,\n fields: ['metadata.name'],\n };\n } else if (hasTeamNameFilter) {\n queryOptions.fullTextFilter = {\n term: hasTeamNameFilter,\n fields: ['spec.owner'],\n };\n }\n\n return catalog.queryEntities(queryOptions);\n}\n\nasync function _buildEntityMappingsResponse(\n entityMappings: RawDbEntityResultRow[],\n componentEntitiesDict: Record<string, { ref: string; name: string; }>,\n componentEntities: GetEntitiesResponse,\n pagerDutyServices: PagerDutyService[],\n): Promise<PagerDutyEntityMappingsResponse> {\n const result: PagerDutyEntityMappingsResponse = {\n mappings: [],\n };\n\n pagerDutyServices.forEach(service => {\n const entityRef = componentEntitiesDict[service.id]?.ref;\n const entityName = componentEntitiesDict[service.id]?.name;\n\n const entityMapping = entityMappings.find(mapping => mapping.serviceId === service.id);\n\n if (entityMapping) {\n if (entityRef === undefined) {\n if (entityMapping.entityRef === '' ||entityMapping.entityRef === undefined) {\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: service.escalation_policy !== undefined ? service.escalation_policy.name : '',\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: service.escalation_policy !== undefined ? service.escalation_policy.name : '',\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: 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: service.escalation_policy !== undefined ? service.escalation_policy.name : '',\n serviceUrl: service.html_url,\n account: service.account,\n });\n } else if (entityRef === entityMapping.entityRef) {\n result.mappings.push({\n entityRef: 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: service.escalation_policy !== undefined ? service.escalation_policy.name : '',\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: service.escalation_policy !== undefined ? service.escalation_policy.name : '',\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: service.escalation_policy !== undefined ? service.escalation_policy.name : '',\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"],"names":["Pagerduty.getServicesIdsByPartialName","CatalogEntityUtils.entityRef","CatalogEntityUtils.getPagerDutyIntegrationKey","getServicesByIds","CatalogEntityUtils.createComponentEntitiesReferenceDict","CatalogEntityUtils.getPagerDutyServiceId","getServiceByIntegrationKey","HttpError"],"mappings":"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"}
@@ -34,6 +34,22 @@ class PagerDutyBackendDatabase {
34
34
  }).onConflict(["serviceId"]).merge(["entityRef", "integrationKey", "account", "processedDate"]).returning("id");
35
35
  return result.id;
36
36
  }
37
+ async bulkInsertEntityMappings(entities) {
38
+ if (entities.length === 0) {
39
+ return [];
40
+ }
41
+ const rows = entities.map((entity) => ({
42
+ id: uuid.v4(),
43
+ entityRef: entity.entityRef,
44
+ serviceId: entity.serviceId,
45
+ integrationKey: entity.integrationKey,
46
+ account: entity.account
47
+ }));
48
+ const results = await this.db(
49
+ "pagerduty_entity_mapping"
50
+ ).insert(rows).returning("id");
51
+ return results.map((r) => r.id);
52
+ }
37
53
  async getAllEntityMappings() {
38
54
  const rawEntities = await this.db(
39
55
  "pagerduty_entity_mapping"
@@ -1 +1 @@
1
- {"version":3,"file":"PagerDutyBackendDatabase.cjs.js","sources":["../../src/db/PagerDutyBackendDatabase.ts"],"sourcesContent":["import {\n PagerDutyEntityMapping,\n PagerDutySetting,\n} from '@pagerduty/backstage-plugin-common';\nimport { resolvePackagePath } from '@backstage/backend-plugin-api';\nimport { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\n\nexport type RawDbEntityResultRow = {\n id: string;\n entityRef: string;\n serviceId: string;\n integrationKey: string;\n account?: string;\n processedDate?: Date;\n};\n\n/** @public */\nexport interface PagerDutyBackendStore {\n insertEntityMapping(entity: PagerDutyEntityMapping): Promise<string>;\n getAllEntityMappings(): Promise<RawDbEntityResultRow[]>;\n findEntityMappingByEntityRef(\n entityRef: string,\n ): Promise<RawDbEntityResultRow | undefined>;\n findEntityMappingByServiceId(\n serviceId: string,\n ): Promise<RawDbEntityResultRow | undefined>;\n updateSetting(setting: PagerDutySetting): Promise<string>;\n findSetting(settingId: string): Promise<PagerDutySetting | undefined>;\n getAllSettings(): Promise<PagerDutySetting[]>;\n}\n\ntype Options = {\n skipMigrations?: boolean;\n};\n\n/** @public */\nexport class PagerDutyBackendDatabase implements PagerDutyBackendStore {\n static async create(\n knex: Knex,\n options?: Options,\n ): Promise<PagerDutyBackendStore> {\n if (!options?.skipMigrations) {\n const migrationsDir = resolvePackagePath(\n '@pagerduty/backstage-plugin-backend',\n 'migrations',\n );\n\n await knex.migrate.latest({\n directory: migrationsDir,\n extension: 'js',\n });\n }\n\n return new PagerDutyBackendDatabase(knex);\n }\n\n constructor(private readonly db: Knex) {}\n\n async insertEntityMapping(entity: PagerDutyEntityMapping): Promise<string> {\n const entityMappingId = uuid();\n\n const [result] = await this.db<RawDbEntityResultRow>(\n 'pagerduty_entity_mapping',\n )\n .insert({\n id: entityMappingId,\n entityRef: entity.entityRef,\n serviceId: entity.serviceId,\n integrationKey: entity.integrationKey,\n account: entity.account,\n processedDate: new Date(),\n })\n .onConflict(['serviceId'])\n .merge(['entityRef', 'integrationKey', 'account', 'processedDate'])\n .returning('id');\n\n return result.id;\n }\n\n async getAllEntityMappings(): Promise<RawDbEntityResultRow[]> {\n const rawEntities = await this.db<RawDbEntityResultRow>(\n 'pagerduty_entity_mapping',\n );\n\n if (!rawEntities) {\n return [];\n }\n\n return rawEntities;\n }\n\n async findEntityMappingByEntityRef(\n entityRef: string,\n ): Promise<RawDbEntityResultRow | undefined> {\n const rawEntity = await this.db<RawDbEntityResultRow>(\n 'pagerduty_entity_mapping',\n )\n .where('entityRef', entityRef)\n .first();\n\n return rawEntity;\n }\n\n async findEntityMappingByServiceId(\n serviceId: string,\n ): Promise<RawDbEntityResultRow | undefined> {\n const rawEntity = await this.db<RawDbEntityResultRow>(\n 'pagerduty_entity_mapping',\n )\n .where('serviceId', serviceId)\n .first();\n\n return rawEntity;\n }\n\n async updateSetting(setting: PagerDutySetting): Promise<string> {\n const [result] = await this.db<PagerDutySetting>('pagerduty_settings')\n .insert({\n id: setting.id,\n value: setting.value,\n })\n .onConflict(['id'])\n .merge(['value'])\n .returning('id');\n\n return result.id;\n }\n\n async findSetting(settingId: string): Promise<PagerDutySetting | undefined> {\n const rawEntity = await this.db<PagerDutySetting>('pagerduty_settings')\n .where('id', settingId)\n .first();\n\n return rawEntity;\n }\n\n async getAllSettings(): Promise<PagerDutySetting[]> {\n const rawEntities = await this.db<PagerDutySetting>('pagerduty_settings');\n\n if (!rawEntities) {\n return [];\n }\n\n return rawEntities;\n }\n}\n"],"names":["resolvePackagePath","uuid"],"mappings":"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"}
1
+ {"version":3,"file":"PagerDutyBackendDatabase.cjs.js","sources":["../../src/db/PagerDutyBackendDatabase.ts"],"sourcesContent":["import {\n PagerDutyEntityMapping,\n PagerDutySetting,\n} from '@pagerduty/backstage-plugin-common';\nimport { resolvePackagePath } from '@backstage/backend-plugin-api';\nimport { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\n\nexport type RawDbEntityResultRow = {\n id: string;\n entityRef: string;\n serviceId: string;\n integrationKey: string;\n account?: string;\n processedDate?: Date;\n};\n\n/** @public */\nexport interface PagerDutyBackendStore {\n insertEntityMapping(entity: PagerDutyEntityMapping): Promise<string>;\n bulkInsertEntityMappings(\n entities: PagerDutyEntityMapping[],\n ): Promise<string[]>;\n getAllEntityMappings(): Promise<RawDbEntityResultRow[]>;\n findEntityMappingByEntityRef(\n entityRef: string,\n ): Promise<RawDbEntityResultRow | undefined>;\n findEntityMappingByServiceId(\n serviceId: string,\n ): Promise<RawDbEntityResultRow | undefined>;\n updateSetting(setting: PagerDutySetting): Promise<string>;\n findSetting(settingId: string): Promise<PagerDutySetting | undefined>;\n getAllSettings(): Promise<PagerDutySetting[]>;\n}\n\ntype Options = {\n skipMigrations?: boolean;\n};\n\n/** @public */\nexport class PagerDutyBackendDatabase implements PagerDutyBackendStore {\n static async create(\n knex: Knex,\n options?: Options,\n ): Promise<PagerDutyBackendStore> {\n if (!options?.skipMigrations) {\n const migrationsDir = resolvePackagePath(\n '@pagerduty/backstage-plugin-backend',\n 'migrations',\n );\n\n await knex.migrate.latest({\n directory: migrationsDir,\n extension: 'js',\n });\n }\n\n return new PagerDutyBackendDatabase(knex);\n }\n\n constructor(private readonly db: Knex) {}\n\n async insertEntityMapping(entity: PagerDutyEntityMapping): Promise<string> {\n const entityMappingId = uuid();\n\n const [result] = await this.db<RawDbEntityResultRow>(\n 'pagerduty_entity_mapping',\n )\n .insert({\n id: entityMappingId,\n entityRef: entity.entityRef,\n serviceId: entity.serviceId,\n integrationKey: entity.integrationKey,\n account: entity.account,\n processedDate: new Date(),\n })\n .onConflict(['serviceId'])\n .merge(['entityRef', 'integrationKey', 'account', 'processedDate'])\n .returning('id');\n\n return result.id;\n }\n\n async bulkInsertEntityMappings(\n entities: PagerDutyEntityMapping[],\n ): Promise<string[]> {\n if (entities.length === 0) {\n return [];\n }\n\n const rows = entities.map(entity => ({\n id: uuid(),\n entityRef: entity.entityRef,\n serviceId: entity.serviceId,\n integrationKey: entity.integrationKey,\n account: entity.account,\n }));\n\n const results = await this.db<RawDbEntityResultRow>(\n 'pagerduty_entity_mapping',\n )\n .insert(rows)\n .returning('id');\n\n return results.map(r => r.id);\n }\n\n async getAllEntityMappings(): Promise<RawDbEntityResultRow[]> {\n const rawEntities = await this.db<RawDbEntityResultRow>(\n 'pagerduty_entity_mapping',\n );\n\n if (!rawEntities) {\n return [];\n }\n\n return rawEntities;\n }\n\n async findEntityMappingByEntityRef(\n entityRef: string,\n ): Promise<RawDbEntityResultRow | undefined> {\n const rawEntity = await this.db<RawDbEntityResultRow>(\n 'pagerduty_entity_mapping',\n )\n .where('entityRef', entityRef)\n .first();\n\n return rawEntity;\n }\n\n async findEntityMappingByServiceId(\n serviceId: string,\n ): Promise<RawDbEntityResultRow | undefined> {\n const rawEntity = await this.db<RawDbEntityResultRow>(\n 'pagerduty_entity_mapping',\n )\n .where('serviceId', serviceId)\n .first();\n\n return rawEntity;\n }\n\n async updateSetting(setting: PagerDutySetting): Promise<string> {\n const [result] = await this.db<PagerDutySetting>('pagerduty_settings')\n .insert({\n id: setting.id,\n value: setting.value,\n })\n .onConflict(['id'])\n .merge(['value'])\n .returning('id');\n\n return result.id;\n }\n\n async findSetting(settingId: string): Promise<PagerDutySetting | undefined> {\n const rawEntity = await this.db<PagerDutySetting>('pagerduty_settings')\n .where('id', settingId)\n .first();\n\n return rawEntity;\n }\n\n async getAllSettings(): Promise<PagerDutySetting[]> {\n const rawEntities = await this.db<PagerDutySetting>('pagerduty_settings');\n\n if (!rawEntities) {\n return [];\n }\n\n return rawEntities;\n }\n}\n"],"names":["resolvePackagePath","uuid"],"mappings":"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"}
package/dist/index.cjs.js CHANGED
@@ -8,7 +8,6 @@ var plugin = require('./plugin.cjs.js');
8
8
 
9
9
 
10
10
  exports.buildEntityMappingsResponse = router.buildEntityMappingsResponse;
11
- exports.createComponentEntitiesReferenceDict = router.createComponentEntitiesReferenceDict;
12
11
  exports.createRouter = router.createRouter;
13
12
  exports.default = plugin.pagerDutyPlugin;
14
13
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
package/dist/index.d.ts CHANGED
@@ -15,6 +15,7 @@ type RawDbEntityResultRow = {
15
15
  /** @public */
16
16
  interface PagerDutyBackendStore {
17
17
  insertEntityMapping(entity: PagerDutyEntityMapping): Promise<string>;
18
+ bulkInsertEntityMappings(entities: PagerDutyEntityMapping[]): Promise<string[]>;
18
19
  getAllEntityMappings(): Promise<RawDbEntityResultRow[]>;
19
20
  findEntityMappingByEntityRef(entityRef: string): Promise<RawDbEntityResultRow | undefined>;
20
21
  findEntityMappingByServiceId(serviceId: string): Promise<RawDbEntityResultRow | undefined>;
@@ -36,10 +37,6 @@ type Annotations = {
36
37
  'pagerduty.com/service-id': string;
37
38
  'pagerduty.com/account': string;
38
39
  };
39
- declare function createComponentEntitiesReferenceDict({ items: componentEntities, }: GetEntitiesResponse): Promise<Record<string, {
40
- ref: string;
41
- name: string;
42
- }>>;
43
40
  declare function buildEntityMappingsResponse(entityMappings: RawDbEntityResultRow[], componentEntitiesDict: Record<string, {
44
41
  ref: string;
45
42
  name: string;
@@ -49,5 +46,5 @@ declare function createRouter(options: RouterOptions): Promise<express.Router>;
49
46
  /** @public */
50
47
  declare const pagerDutyPlugin: _backstage_backend_plugin_api.BackendFeature;
51
48
 
52
- export { buildEntityMappingsResponse, createComponentEntitiesReferenceDict, createRouter, pagerDutyPlugin as default };
49
+ export { buildEntityMappingsResponse, createRouter, pagerDutyPlugin as default };
53
50
  export type { Annotations, RouterOptions };