@pagerduty/backstage-plugin-backend 0.9.6 → 0.9.7

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,698 @@
1
+ 'use strict';
2
+
3
+ var fetch = require('node-fetch');
4
+ var auth = require('../auth/auth.cjs.js');
5
+ var common = require('common');
6
+ var luxon = require('luxon');
7
+
8
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
9
+
10
+ var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
11
+
12
+ const EndpointConfig = {};
13
+ let fallbackEndpointConfig;
14
+ let isLegacyConfig = false;
15
+ function setFallbackEndpointConfig(account) {
16
+ fallbackEndpointConfig = {
17
+ eventsBaseUrl: account.eventsBaseUrl ?? "https://events.pagerduty.com/v2",
18
+ apiBaseUrl: account.apiBaseUrl ?? "https://api.pagerduty.com"
19
+ };
20
+ }
21
+ function insertEndpointConfig(account) {
22
+ EndpointConfig[account.id] = {
23
+ eventsBaseUrl: account.eventsBaseUrl ?? "https://events.pagerduty.com/v2",
24
+ apiBaseUrl: account.apiBaseUrl ?? "https://api.pagerduty.com"
25
+ };
26
+ }
27
+ function loadPagerDutyEndpointsFromConfig(config, logger) {
28
+ if (config.getOptional("pagerDuty.accounts")) {
29
+ logger.debug(`New accounts configuration detected. Loading PagerDuty endpoints from config.`);
30
+ isLegacyConfig = false;
31
+ const accounts = config.getOptional("pagerDuty.accounts");
32
+ if (accounts?.length === 1) {
33
+ logger.debug(`Single account configuration detected. Loading PagerDuty endpoints from config to 'default'.`);
34
+ EndpointConfig.default = {
35
+ eventsBaseUrl: accounts[0].eventsBaseUrl !== void 0 ? accounts[0].eventsBaseUrl : "https://events.pagerduty.com/v2",
36
+ apiBaseUrl: accounts[0].apiBaseUrl !== void 0 ? accounts[0].apiBaseUrl : "https://api.pagerduty.com"
37
+ };
38
+ } else {
39
+ logger.debug(`Multiple account configuration detected. Loading PagerDuty endpoints from config.`);
40
+ accounts?.forEach((account) => {
41
+ if (account.isDefault) {
42
+ setFallbackEndpointConfig(account);
43
+ }
44
+ insertEndpointConfig(account);
45
+ });
46
+ }
47
+ } else {
48
+ logger.debug(`Loading legacy PagerDuty endpoints from config.`);
49
+ isLegacyConfig = true;
50
+ EndpointConfig.default = {
51
+ eventsBaseUrl: config.getOptionalString("pagerDuty.eventsBaseUrl") !== void 0 ? config.getString("pagerDuty.eventsBaseUrl") : "https://events.pagerduty.com/v2",
52
+ apiBaseUrl: config.getOptionalString("pagerDuty.apiBaseUrl") !== void 0 ? config.getString("pagerDuty.apiBaseUrl") : "https://api.pagerduty.com"
53
+ };
54
+ }
55
+ }
56
+ function getApiBaseUrl(account) {
57
+ if (isLegacyConfig === true) {
58
+ return EndpointConfig.default.apiBaseUrl;
59
+ }
60
+ if (account) {
61
+ return EndpointConfig[account].apiBaseUrl;
62
+ }
63
+ return fallbackEndpointConfig.apiBaseUrl;
64
+ }
65
+ async function addServiceRelationsToService(serviceRelations, account) {
66
+ let response;
67
+ const options = {
68
+ method: "POST",
69
+ headers: {
70
+ Authorization: await auth.getAuthToken(account),
71
+ "Accept": "application/vnd.pagerduty+json;version=2",
72
+ "Content-Type": "application/json"
73
+ },
74
+ body: JSON.stringify({
75
+ relationships: serviceRelations
76
+ })
77
+ };
78
+ const apiBaseUrl = getApiBaseUrl(account);
79
+ const baseUrl = `${apiBaseUrl}/service_dependencies/associate`;
80
+ try {
81
+ response = await fetchWithRetries(baseUrl, options);
82
+ } catch (error) {
83
+ throw new Error(`Failed to retrieve service dependencies: ${error}`);
84
+ }
85
+ if (response.status >= 500) {
86
+ throw new common.HttpError(`Failed to add service dependencies. PagerDuty API returned a server error. Retrying with the same arguments will not work.`, response.status);
87
+ }
88
+ switch (response.status) {
89
+ case 400:
90
+ throw new common.HttpError("Failed to add service dependencies. Caller provided invalid arguments. Please review the response for error details. Retrying with the same arguments will not work.", 400);
91
+ case 401:
92
+ throw new common.HttpError("Failed to add service dependencies. Caller did not supply credentials or did not provide the correct credentials. If you are using an API key, it may be invalid or your Authorization header may be malformed.", 401);
93
+ case 403:
94
+ throw new common.HttpError("Failed to add service dependencies. Caller is not authorized to view the requested resource. While your authentication is valid, the authenticated user or token does not have permission to perform this action.", 403);
95
+ case 404:
96
+ throw new common.HttpError("Failed to add service dependencies. The requested resource was not found.", 404);
97
+ }
98
+ let result;
99
+ try {
100
+ result = await response.json();
101
+ return result.relationships;
102
+ } catch (error) {
103
+ throw new common.HttpError(`Failed to parse service dependency information: ${error}`, 500);
104
+ }
105
+ }
106
+ async function removeServiceRelationsFromService(serviceRelations, account) {
107
+ let response;
108
+ const options = {
109
+ method: "POST",
110
+ headers: {
111
+ Authorization: await auth.getAuthToken(account),
112
+ "Accept": "application/vnd.pagerduty+json;version=2",
113
+ "Content-Type": "application/json"
114
+ },
115
+ body: JSON.stringify({
116
+ relationships: serviceRelations
117
+ })
118
+ };
119
+ const apiBaseUrl = getApiBaseUrl(account);
120
+ const baseUrl = `${apiBaseUrl}/service_dependencies/disassociate`;
121
+ try {
122
+ response = await fetchWithRetries(`${baseUrl}`, options);
123
+ } catch (error) {
124
+ throw new Error(`Failed to retrieve service dependencies: ${error}`);
125
+ }
126
+ if (response.status >= 500) {
127
+ throw new common.HttpError(`Failed to remove service dependencies. PagerDuty API returned a server error. Retrying with the same arguments will not work.`, response.status);
128
+ }
129
+ switch (response.status) {
130
+ case 400:
131
+ throw new common.HttpError("Failed to remove service dependencies. Caller provided invalid arguments. Please review the response for error details. Retrying with the same arguments will not work.", 400);
132
+ case 401:
133
+ throw new common.HttpError("Failed to remove service dependencies. Caller did not supply credentials or did not provide the correct credentials. If you are using an API key, it may be invalid or your Authorization header may be malformed.", 401);
134
+ case 403:
135
+ throw new common.HttpError("Failed to remove service dependencies. Caller is not authorized to view the requested resource. While your authentication is valid, the authenticated user or token does not have permission to perform this action.", 403);
136
+ case 404:
137
+ throw new common.HttpError("Failed to remove service dependencies. The requested resource was not found.", 404);
138
+ }
139
+ let result;
140
+ try {
141
+ result = await response.json();
142
+ return result.relationships;
143
+ } catch (error) {
144
+ throw new common.HttpError(`Failed to parse service dependency information: ${error}`, 500);
145
+ }
146
+ }
147
+ async function getServiceRelationshipsById(serviceId, account) {
148
+ let response;
149
+ const options = {
150
+ method: "GET",
151
+ headers: {
152
+ Authorization: await auth.getAuthToken(account),
153
+ "Accept": "application/vnd.pagerduty+json;version=2",
154
+ "Content-Type": "application/json"
155
+ }
156
+ };
157
+ const apiBaseUrl = getApiBaseUrl(account);
158
+ const baseUrl = `${apiBaseUrl}/service_dependencies/technical_services/${serviceId}`;
159
+ try {
160
+ response = await fetchWithRetries(baseUrl, options);
161
+ } catch (error) {
162
+ throw new Error(`Failed to retrieve service dependencies: ${error}`);
163
+ }
164
+ if (response.status >= 500) {
165
+ throw new common.HttpError(`Failed to list service dependencies. PagerDuty API returned a server error. Retrying with the same arguments will not work.`, response.status);
166
+ }
167
+ switch (response.status) {
168
+ case 400:
169
+ throw new common.HttpError("Failed to list service dependencies. Caller provided invalid arguments. Please review the response for error details. Retrying with the same arguments will not work.", 400);
170
+ case 401:
171
+ throw new common.HttpError("Failed to list service dependencies. Caller did not supply credentials or did not provide the correct credentials. If you are using an API key, it may be invalid or your Authorization header may be malformed.", 401);
172
+ case 403:
173
+ throw new common.HttpError("Failed to list service dependencies. Caller is not authorized to view the requested resource. While your authentication is valid, the authenticated user or token does not have permission to perform this action.", 403);
174
+ case 404:
175
+ throw new common.HttpError("Failed to list service dependencies. The requested resource was not found.", 404);
176
+ }
177
+ let result;
178
+ try {
179
+ result = await response.json();
180
+ return result.relationships;
181
+ } catch (error) {
182
+ throw new common.HttpError(`Failed to parse service dependency information: ${error}`, 500);
183
+ }
184
+ }
185
+ async function getEscalationPolicies(offset, limit, account) {
186
+ let response;
187
+ const params = `total=true&sort_by=name&offset=${offset}&limit=${limit}`;
188
+ const options = {
189
+ method: "GET",
190
+ headers: {
191
+ Authorization: await auth.getAuthToken(account),
192
+ "Accept": "application/vnd.pagerduty+json;version=2",
193
+ "Content-Type": "application/json"
194
+ }
195
+ };
196
+ const apiBaseUrl = getApiBaseUrl(account);
197
+ const baseUrl = `${apiBaseUrl}/escalation_policies`;
198
+ try {
199
+ response = await fetchWithRetries(`${baseUrl}?${params}`, options);
200
+ } catch (error) {
201
+ throw new Error(`Failed to retrieve escalation policies: ${error}`);
202
+ }
203
+ if (response.status >= 500) {
204
+ throw new common.HttpError(`Failed to list escalation policies. PagerDuty API returned a server error. Retrying with the same arguments will not work.`, response.status);
205
+ }
206
+ switch (response.status) {
207
+ case 400:
208
+ throw new common.HttpError("Failed to list escalation policies. Caller provided invalid arguments.", 400);
209
+ case 401:
210
+ throw new common.HttpError("Failed to list escalation policies. Caller did not supply credentials or did not provide the correct credentials.", 401);
211
+ case 403:
212
+ throw new common.HttpError("Failed to list escalation policies. Caller is not authorized to view the requested resource.", 403);
213
+ case 429:
214
+ throw new common.HttpError("Failed to list escalation policies. Rate limit exceeded.", 429);
215
+ }
216
+ let result;
217
+ try {
218
+ result = await response.json();
219
+ return [result.more ?? false, result.escalation_policies];
220
+ } catch (error) {
221
+ throw new common.HttpError(`Failed to parse escalation policy information: ${error}`, 500);
222
+ }
223
+ }
224
+ async function getAllEscalationPolicies() {
225
+ const limit = 50;
226
+ let offset = 0;
227
+ let moreResults = false;
228
+ let results = [];
229
+ await Promise.all(
230
+ Object.keys(EndpointConfig).map(async (account) => {
231
+ try {
232
+ offset = 0;
233
+ do {
234
+ const res = await getEscalationPolicies(offset, limit, account);
235
+ res[1].forEach((policy) => {
236
+ policy.account = account;
237
+ });
238
+ results = results.concat(res[1]);
239
+ if (res[0] === true) {
240
+ moreResults = true;
241
+ offset += limit;
242
+ } else {
243
+ moreResults = false;
244
+ }
245
+ } while (moreResults === true);
246
+ } catch (error) {
247
+ if (error instanceof common.HttpError) {
248
+ throw error;
249
+ } else {
250
+ throw new common.HttpError(`${error}`, 500);
251
+ }
252
+ }
253
+ })
254
+ );
255
+ return results;
256
+ }
257
+ async function getOncallUsers(escalationPolicy, account) {
258
+ let response;
259
+ const params = `time_zone=UTC&include[]=users&escalation_policy_ids[]=${escalationPolicy}`;
260
+ const options = {
261
+ method: "GET",
262
+ headers: {
263
+ Authorization: await auth.getAuthToken(account),
264
+ "Accept": "application/vnd.pagerduty+json;version=2",
265
+ "Content-Type": "application/json"
266
+ }
267
+ };
268
+ const apiBaseUrl = getApiBaseUrl(account);
269
+ const baseUrl = `${apiBaseUrl}/oncalls`;
270
+ try {
271
+ response = await fetchWithRetries(`${baseUrl}?${params}`, options);
272
+ } catch (error) {
273
+ throw new Error(`Failed to retrieve oncalls: ${error}`);
274
+ }
275
+ if (response.status >= 500) {
276
+ throw new common.HttpError(`Failed to list oncalls. PagerDuty API returned a server error. Retrying with the same arguments will not work.`, response.status);
277
+ }
278
+ switch (response.status) {
279
+ case 400:
280
+ throw new common.HttpError("Failed to list oncalls. Caller provided invalid arguments.", 400);
281
+ case 401:
282
+ throw new common.HttpError("Failed to list oncalls. Caller did not supply credentials or did not provide the correct credentials.", 401);
283
+ case 403:
284
+ throw new common.HttpError("Failed to list oncalls. Caller is not authorized to view the requested resource.", 403);
285
+ case 429:
286
+ throw new common.HttpError("Failed to list oncalls. Rate limit exceeded.", 429);
287
+ }
288
+ let result;
289
+ let usersItem;
290
+ try {
291
+ result = await response.json();
292
+ if (result.oncalls.length !== 0) {
293
+ const oncallsSorted = [...result.oncalls].sort((a, b) => {
294
+ return a.escalation_level - b.escalation_level;
295
+ });
296
+ const oncallsFiltered = oncallsSorted.filter((oncall) => {
297
+ return oncall.escalation_level === oncallsSorted[0].escalation_level;
298
+ });
299
+ usersItem = [...oncallsFiltered].sort((a, b) => a.user.name > b.user.name ? 1 : -1).map((oncall) => oncall.user);
300
+ const uniqueUsers = /* @__PURE__ */ new Map();
301
+ usersItem.forEach((user) => {
302
+ uniqueUsers.set(user.id, user);
303
+ });
304
+ usersItem.length = 0;
305
+ uniqueUsers.forEach((user) => {
306
+ usersItem.push(user);
307
+ });
308
+ return usersItem;
309
+ }
310
+ return [];
311
+ } catch (error) {
312
+ throw new common.HttpError(`Failed to parse oncall information: ${error}`, 500);
313
+ }
314
+ }
315
+ async function getServiceById(serviceId, account) {
316
+ let response;
317
+ const params = `time_zone=UTC&include[]=integrations&include[]=escalation_policies`;
318
+ const token = await auth.getAuthToken(account);
319
+ const options = {
320
+ method: "GET",
321
+ headers: {
322
+ Authorization: token,
323
+ "Accept": "application/vnd.pagerduty+json;version=2",
324
+ "Content-Type": "application/json"
325
+ }
326
+ };
327
+ const apiBaseUrl = getApiBaseUrl(account);
328
+ const baseUrl = `${apiBaseUrl}/services`;
329
+ try {
330
+ response = await fetchWithRetries(`${baseUrl}/${serviceId}?${params}`, options);
331
+ } catch (error) {
332
+ throw new Error(`Failed to retrieve service: ${error}`);
333
+ }
334
+ if (response.status >= 500) {
335
+ throw new common.HttpError(`Failed to get service. PagerDuty API returned a server error. Retrying with the same arguments will not work.`, response.status);
336
+ }
337
+ switch (response.status) {
338
+ case 400:
339
+ throw new common.HttpError("Failed to get service. Caller provided invalid arguments.", 400);
340
+ case 401:
341
+ throw new common.HttpError("Failed to get service. Caller did not supply credentials or did not provide the correct credentials.", 401);
342
+ case 403:
343
+ throw new common.HttpError("Failed to get service. Caller is not authorized to view the requested resource.", 403);
344
+ case 404:
345
+ throw new common.HttpError("Failed to get service. The requested resource was not found.", 404);
346
+ }
347
+ let result;
348
+ try {
349
+ result = await response.json();
350
+ return result.service;
351
+ } catch (error) {
352
+ throw new common.HttpError(`Failed to parse service information: ${error}`, 500);
353
+ }
354
+ }
355
+ async function getServiceByIntegrationKey(integrationKey, account) {
356
+ let response;
357
+ const params = `query=${integrationKey}&time_zone=UTC&include[]=integrations&include[]=escalation_policies`;
358
+ const token = await auth.getAuthToken(account);
359
+ const options = {
360
+ method: "GET",
361
+ headers: {
362
+ Authorization: token,
363
+ "Accept": "application/vnd.pagerduty+json;version=2",
364
+ "Content-Type": "application/json"
365
+ }
366
+ };
367
+ const apiBaseUrl = getApiBaseUrl(account);
368
+ const baseUrl = `${apiBaseUrl}/services`;
369
+ try {
370
+ response = await fetchWithRetries(`${baseUrl}?${params}`, options);
371
+ } catch (error) {
372
+ throw new Error(`Failed to retrieve service: ${error}`);
373
+ }
374
+ if (response.status >= 500) {
375
+ throw new common.HttpError(`Failed to get service. PagerDuty API returned a server error. Retrying with the same arguments will not work.`, response.status);
376
+ }
377
+ switch (response.status) {
378
+ case 400:
379
+ throw new common.HttpError("Failed to get service. Caller provided invalid arguments.", 400);
380
+ case 401:
381
+ throw new common.HttpError("Failed to get service. Caller did not supply credentials or did not provide the correct credentials.", 401);
382
+ case 403:
383
+ throw new common.HttpError("Failed to get service. Caller is not authorized to view the requested resource.", 403);
384
+ case 404:
385
+ throw new common.HttpError("Failed to get service. The requested resource was not found.", 404);
386
+ }
387
+ let result;
388
+ try {
389
+ result = await response.json();
390
+ } catch (error) {
391
+ throw new common.HttpError(`Failed to parse service information: ${error}`, 500);
392
+ }
393
+ if (result.services.length === 0) {
394
+ throw new common.HttpError(`Failed to get service. The requested resource was not found.`, 404);
395
+ }
396
+ return result.services[0];
397
+ }
398
+ async function getAllServices() {
399
+ const allServices = [];
400
+ await Promise.all(
401
+ Object.entries(EndpointConfig).map(async ([account, _]) => {
402
+ let response;
403
+ const params = `time_zone=UTC&include[]=integrations&include[]=escalation_policies&include[]=teams&total=true`;
404
+ const token = await auth.getAuthToken(account);
405
+ const options = {
406
+ method: "GET",
407
+ headers: {
408
+ Authorization: token,
409
+ "Accept": "application/vnd.pagerduty+json;version=2",
410
+ "Content-Type": "application/json"
411
+ }
412
+ };
413
+ const apiBaseUrl = getApiBaseUrl(account);
414
+ const baseUrl = `${apiBaseUrl}/services`;
415
+ let offset = 0;
416
+ const limit = 50;
417
+ let result;
418
+ try {
419
+ do {
420
+ const paginatedUrl = `${baseUrl}?${params}&offset=${offset}&limit=${limit}`;
421
+ response = await fetchWithRetries(paginatedUrl, options);
422
+ if (response.status >= 500) {
423
+ throw new common.HttpError(`Failed to get services. PagerDuty API returned a server error. Retrying with the same arguments will not work.`, response.status);
424
+ }
425
+ switch (response.status) {
426
+ case 400:
427
+ throw new common.HttpError("Failed to get services. Caller provided invalid arguments.", 400);
428
+ case 401:
429
+ throw new common.HttpError("Failed to get services. Caller did not supply credentials or did not provide the correct credentials.", 401);
430
+ case 403:
431
+ throw new common.HttpError("Failed to get services. Caller is not authorized to view the requested resource.", 403);
432
+ default:
433
+ break;
434
+ }
435
+ result = await response.json();
436
+ result.services.forEach((service) => {
437
+ service.account = account;
438
+ });
439
+ allServices.push(...result.services);
440
+ offset += limit;
441
+ } while (offset < result.total);
442
+ } catch (error) {
443
+ throw error;
444
+ }
445
+ })
446
+ );
447
+ return allServices;
448
+ }
449
+ async function getChangeEvents(serviceId, account) {
450
+ let response;
451
+ const params = `limit=5&time_zone=UTC&sort_by=timestamp`;
452
+ const options = {
453
+ method: "GET",
454
+ headers: {
455
+ Authorization: await auth.getAuthToken(account),
456
+ "Accept": "application/vnd.pagerduty+json;version=2",
457
+ "Content-Type": "application/json"
458
+ }
459
+ };
460
+ const apiBaseUrl = getApiBaseUrl(account);
461
+ const baseUrl = `${apiBaseUrl}/services`;
462
+ try {
463
+ response = await fetchWithRetries(`${baseUrl}/${serviceId}/change_events?${params}`, options);
464
+ } catch (error) {
465
+ throw new Error(`Failed to retrieve change events for service: ${error}`);
466
+ }
467
+ if (response.status >= 500) {
468
+ throw new common.HttpError(`Failed to get change events for service. PagerDuty API returned a server error. Retrying with the same arguments will not work.`, response.status);
469
+ }
470
+ switch (response.status) {
471
+ case 400:
472
+ throw new common.HttpError("Failed to get change events for service. Caller provided invalid arguments.", 400);
473
+ case 401:
474
+ throw new common.HttpError("Failed to get change events for service. Caller did not supply credentials or did not provide the correct credentials.", 401);
475
+ case 403:
476
+ throw new common.HttpError("Failed to get change events for service. Caller is not authorized to view the requested resource.", 403);
477
+ case 404:
478
+ throw new common.HttpError("Failed to get change events for service. The requested resource was not found.", 404);
479
+ }
480
+ let result;
481
+ try {
482
+ result = await response.json();
483
+ return result.change_events;
484
+ } catch (error) {
485
+ throw new common.HttpError(`Failed to parse change events information: ${error}`, 500);
486
+ }
487
+ }
488
+ async function getIncidents(serviceId, account) {
489
+ let response;
490
+ const params = `time_zone=UTC&sort_by=created_at&statuses[]=triggered&statuses[]=acknowledged&service_ids[]=${serviceId}`;
491
+ const options = {
492
+ method: "GET",
493
+ headers: {
494
+ Authorization: await auth.getAuthToken(account),
495
+ "Accept": "application/vnd.pagerduty+json;version=2",
496
+ "Content-Type": "application/json"
497
+ }
498
+ };
499
+ const apiBaseUrl = getApiBaseUrl(account);
500
+ const baseUrl = `${apiBaseUrl}/incidents`;
501
+ try {
502
+ response = await fetchWithRetries(`${baseUrl}?${params}`, options);
503
+ } catch (error) {
504
+ throw new Error(`Failed to retrieve incidents for service: ${error}`);
505
+ }
506
+ if (response.status >= 500) {
507
+ throw new common.HttpError(`Failed to get incidents for service. PagerDuty API returned a server error. Retrying with the same arguments will not work.`, response.status);
508
+ }
509
+ switch (response.status) {
510
+ case 400:
511
+ throw new common.HttpError("Failed to get incidents for service. Caller provided invalid arguments.", 400);
512
+ case 401:
513
+ throw new common.HttpError("Failed to get incidents for service. Caller did not supply credentials or did not provide the correct credentials.", 401);
514
+ case 402:
515
+ throw new common.HttpError("Failed to get incidents for service. Account does not have the abilities to perform the action. Please review the response for the required abilities.", 402);
516
+ case 403:
517
+ throw new common.HttpError("Failed to get incidents for service. Caller is not authorized to view the requested resource.", 403);
518
+ case 429:
519
+ throw new common.HttpError("Failed to get incidents for service. Too many requests have been made, the rate limit has been reached.", 429);
520
+ }
521
+ let result;
522
+ try {
523
+ result = await response.json();
524
+ return result.incidents;
525
+ } catch (error) {
526
+ throw new common.HttpError(`Failed to parse incidents information: ${error}`, 500);
527
+ }
528
+ }
529
+ async function getServiceStandards(serviceId, account) {
530
+ let response;
531
+ const options = {
532
+ method: "GET",
533
+ headers: {
534
+ Authorization: await auth.getAuthToken(account),
535
+ "Accept": "application/vnd.pagerduty+json;version=2",
536
+ "Content-Type": "application/json"
537
+ }
538
+ };
539
+ const apiBaseUrl = getApiBaseUrl(account);
540
+ const baseUrl = `${apiBaseUrl}/standards/scores/technical_services/${serviceId}`;
541
+ try {
542
+ response = await fetchWithRetries(baseUrl, options);
543
+ } catch (error) {
544
+ throw new Error(`Failed to retrieve service standards for service: ${error}`);
545
+ }
546
+ if (response.status >= 500) {
547
+ throw new common.HttpError(`Failed to get service standards for service. PagerDuty API returned a server error. Retrying with the same arguments will not work.`, response.status);
548
+ }
549
+ switch (response.status) {
550
+ case 401:
551
+ throw new common.HttpError("Failed to get service standards for service. Caller did not supply credentials or did not provide the correct credentials.", 401);
552
+ case 403:
553
+ throw new common.HttpError("Failed to get service standards for service. Caller is not authorized to view the requested resource.", 403);
554
+ case 429:
555
+ throw new common.HttpError("Failed to get service standards for service. Too many requests have been made, the rate limit has been reached.", 429);
556
+ }
557
+ try {
558
+ const result = await response.json();
559
+ return result;
560
+ } catch (error) {
561
+ throw new common.HttpError(`Failed to parse service standards information: ${error}`, 500);
562
+ }
563
+ }
564
+ async function getServiceMetrics(serviceId, account) {
565
+ let response;
566
+ const endDate = luxon.DateTime.now();
567
+ const startDate = endDate.minus({ days: 30 });
568
+ const body = JSON.stringify({
569
+ filters: {
570
+ created_at_start: startDate.toISO(),
571
+ created_at_end: endDate.toISO(),
572
+ service_ids: [
573
+ serviceId
574
+ ]
575
+ }
576
+ });
577
+ const options = {
578
+ method: "POST",
579
+ headers: {
580
+ Authorization: await auth.getAuthToken(account),
581
+ "Accept": "application/vnd.pagerduty+json;version=2",
582
+ "Content-Type": "application/json"
583
+ },
584
+ body
585
+ };
586
+ const apiBaseUrl = getApiBaseUrl(account);
587
+ const baseUrl = `${apiBaseUrl}/analytics/metrics/incidents/services`;
588
+ try {
589
+ response = await fetchWithRetries(baseUrl, options);
590
+ } catch (error) {
591
+ throw new Error(`Failed to retrieve service metrics for service: ${error}`);
592
+ }
593
+ if (response.status >= 500) {
594
+ throw new common.HttpError(`Failed to get service metrics for service. PagerDuty API returned a server error. Retrying with the same arguments will not work.`, response.status);
595
+ }
596
+ switch (response.status) {
597
+ case 400:
598
+ throw new common.HttpError("Failed to get service metrics for service. Caller provided invalid arguments. Please review the response for error details. Retrying with the same arguments will not work.", 400);
599
+ case 429:
600
+ throw new common.HttpError("Failed to get service metrics for service. Too many requests have been made, the rate limit has been reached.", 429);
601
+ }
602
+ try {
603
+ const result = await response.json();
604
+ return result.data;
605
+ } catch (error) {
606
+ throw new common.HttpError(`Failed to parse service metrics information: ${error}`, 500);
607
+ }
608
+ }
609
+ async function createServiceIntegration({ serviceId, vendorId, account }) {
610
+ let response;
611
+ const apiBaseUrl = getApiBaseUrl(account);
612
+ const baseUrl = `${apiBaseUrl}/services`;
613
+ const token = await auth.getAuthToken(account);
614
+ const options = {
615
+ method: "POST",
616
+ body: JSON.stringify({
617
+ integration: {
618
+ name: "Backstage",
619
+ service: {
620
+ id: serviceId,
621
+ type: "service_reference"
622
+ },
623
+ vendor: {
624
+ id: vendorId,
625
+ type: "vendor_reference"
626
+ }
627
+ }
628
+ }),
629
+ headers: {
630
+ Authorization: token,
631
+ "Accept": "application/vnd.pagerduty+json;version=2",
632
+ "Content-Type": "application/json"
633
+ }
634
+ };
635
+ try {
636
+ response = await fetchWithRetries(`${baseUrl}/${serviceId}/integrations`, options);
637
+ } catch (error) {
638
+ throw new Error(`Failed to create service integration: ${error}`);
639
+ }
640
+ if (response.status >= 500) {
641
+ throw new Error(`Failed to create service integration. PagerDuty API returned a server error. Retrying with the same arguments will not work.`);
642
+ }
643
+ switch (response.status) {
644
+ case 400:
645
+ throw new Error(`Failed to create service integration. Caller provided invalid arguments.`);
646
+ case 401:
647
+ throw new Error(`Failed to create service integration. Caller did not supply credentials or did not provide the correct credentials.`);
648
+ case 403:
649
+ throw new Error(`Failed to create service integration. Caller is not authorized to view the requested resource.`);
650
+ case 429:
651
+ throw new Error(`Failed to create service integration. Rate limit exceeded.`);
652
+ }
653
+ let result;
654
+ try {
655
+ result = await response.json();
656
+ return result.integration.integration_key ?? "";
657
+ } catch (error) {
658
+ throw new Error(`Failed to parse service information: ${error}`);
659
+ }
660
+ }
661
+ async function fetchWithRetries(url, options) {
662
+ let response;
663
+ let error = new Error();
664
+ const maxRetries = 5;
665
+ const delay = 1e3;
666
+ let factor = 2;
667
+ for (let i = 0; i < maxRetries; i++) {
668
+ try {
669
+ response = await fetch__default.default(url, options);
670
+ return response;
671
+ } catch (e) {
672
+ error = e;
673
+ }
674
+ const timeout = delay * factor;
675
+ await new Promise((resolve) => setTimeout(resolve, timeout));
676
+ factor *= 2;
677
+ }
678
+ throw new Error(`Failed to fetch data after ${maxRetries} retries. Last error: ${error}`);
679
+ }
680
+
681
+ exports.addServiceRelationsToService = addServiceRelationsToService;
682
+ exports.createServiceIntegration = createServiceIntegration;
683
+ exports.fetchWithRetries = fetchWithRetries;
684
+ exports.getAllEscalationPolicies = getAllEscalationPolicies;
685
+ exports.getAllServices = getAllServices;
686
+ exports.getChangeEvents = getChangeEvents;
687
+ exports.getIncidents = getIncidents;
688
+ exports.getOncallUsers = getOncallUsers;
689
+ exports.getServiceById = getServiceById;
690
+ exports.getServiceByIntegrationKey = getServiceByIntegrationKey;
691
+ exports.getServiceMetrics = getServiceMetrics;
692
+ exports.getServiceRelationshipsById = getServiceRelationshipsById;
693
+ exports.getServiceStandards = getServiceStandards;
694
+ exports.insertEndpointConfig = insertEndpointConfig;
695
+ exports.loadPagerDutyEndpointsFromConfig = loadPagerDutyEndpointsFromConfig;
696
+ exports.removeServiceRelationsFromService = removeServiceRelationsFromService;
697
+ exports.setFallbackEndpointConfig = setFallbackEndpointConfig;
698
+ //# sourceMappingURL=pagerduty.cjs.js.map