@axis-backstage/plugin-jira-dashboard-backend 4.3.0 → 4.4.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/dist/index.cjs.js CHANGED
@@ -2,747 +2,16 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var backendPluginApi = require('@backstage/backend-plugin-api');
6
- var express = require('express');
7
- var Router = require('express-promise-router');
8
- var stream = require('stream');
9
- var rootHttpRouter = require('@backstage/backend-defaults/rootHttpRouter');
10
- var cache = require('@backstage/backend-defaults/cache');
11
- var catalogModel = require('@backstage/catalog-model');
12
- var catalogClient = require('@backstage/catalog-client');
13
- var pluginJiraDashboardCommon = require('@axis-backstage/plugin-jira-dashboard-common');
14
- var fetch = require('node-fetch');
15
- var errors = require('@backstage/errors');
5
+ var plugin = require('./plugin.cjs.js');
6
+ var api = require('./api.cjs.js');
7
+ var config = require('./config.cjs.js');
8
+ var queries = require('./queries.cjs.js');
16
9
 
17
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
18
10
 
19
- var express__default = /*#__PURE__*/_interopDefaultCompat(express);
20
- var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
21
- var stream__default = /*#__PURE__*/_interopDefaultCompat(stream);
22
- var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
23
11
 
24
- const getAnnotations = (config) => {
25
- const prefix = config.annotationPrefix;
26
- const projectKeyAnnotation = `${prefix}/${pluginJiraDashboardCommon.PROJECT_KEY_NAME}`;
27
- const componentsAnnotation = `${prefix}/${pluginJiraDashboardCommon.COMPONENTS_NAME}`;
28
- const filtersAnnotation = `${prefix}/${pluginJiraDashboardCommon.FILTERS_NAME}`;
29
- const incomingIssuesAnnotation = `${prefix}/${pluginJiraDashboardCommon.INCOMING_ISSUES_STATUS}`;
30
- const componentRoadieAnnotation = `${prefix}/component`;
31
- return {
32
- projectKeyAnnotation,
33
- componentsAnnotation,
34
- filtersAnnotation,
35
- incomingIssuesAnnotation,
36
- componentRoadieAnnotation
37
- };
38
- };
39
- function splitProjectKey(config, fullProjectKey) {
40
- const [instance, projectKey] = fullProjectKey.split("/");
41
- if (!projectKey) {
42
- return {
43
- instance: config.getInstance(),
44
- fullProjectKey,
45
- projectKey: instance
46
- };
47
- }
48
- return {
49
- instance: config.getInstance(instance),
50
- fullProjectKey,
51
- projectKey
52
- };
53
- }
54
-
55
- const jqlQueryBuilder = ({
56
- project,
57
- components,
58
- query
59
- }) => {
60
- const projectList = Array.isArray(project) ? project : [project];
61
- let jql = `project in (${projectList.join(",")})`;
62
- if (components && components.length > 0) {
63
- let componentsInclude = "(";
64
- for (let index = 0; index < components.length; index++) {
65
- const component = components[index];
66
- componentsInclude += `'${component}'`;
67
- if (index === components.length - 1) {
68
- componentsInclude += ")";
69
- } else {
70
- componentsInclude += ",";
71
- }
72
- }
73
- jql += ` AND component in ${componentsInclude}`;
74
- }
75
- if (query) {
76
- jql += ` AND ${query}`;
77
- }
78
- return jql;
79
- };
80
-
81
- const getProjectInfo = async (project) => {
82
- const { projectKey, instance } = project;
83
- const response = await callApi(
84
- instance,
85
- `${instance.baseUrl}project/${projectKey}`,
86
- {
87
- method: "GET",
88
- headers: {
89
- Accept: "application/json"
90
- }
91
- }
92
- );
93
- if (response.status !== 200) {
94
- throw Error(
95
- `Request failed with status code ${response.status}: ${response.statusText}`
96
- );
97
- }
98
- return response.json();
99
- };
100
- const getFilterById = async (id, instance) => {
101
- const response = await callApi(instance, `${instance.baseUrl}filter/${id}`, {
102
- method: "GET",
103
- headers: {
104
- Accept: "application/json"
105
- }
106
- });
107
- if (response.status !== 200) {
108
- throw Error(`${response.status}`);
109
- }
110
- const jsonResponse = await response.json();
111
- return { name: jsonResponse.name, query: jsonResponse.jql };
112
- };
113
- const getIssuesByFilter = async (projects, components, query) => {
114
- const issues = [];
115
- for (const project of projects) {
116
- const { projectKey, instance } = project;
117
- const jql = jqlQueryBuilder({ project: [projectKey], components, query });
118
- const response = await callApi(
119
- instance,
120
- `${instance.baseUrl}search?jql=${jql}`,
121
- {
122
- method: "GET",
123
- headers: {
124
- Accept: "application/json"
125
- }
126
- }
127
- ).then((resp) => resp.json()).catch(() => null);
128
- if (response?.issues) {
129
- issues.push(...response.issues);
130
- }
131
- }
132
- return issues;
133
- };
134
- const searchJira = async (instance, jqlQuery, options) => {
135
- const response = await callApi(instance, `${instance.baseUrl}search`, {
136
- method: "POST",
137
- body: JSON.stringify({ jql: jqlQuery, ...options }),
138
- headers: {
139
- Accept: "application/json",
140
- "Content-Type": "application/json"
141
- }
142
- });
143
- if (!response.ok) {
144
- throw await errors.ResponseError.fromResponse(response);
145
- }
146
- const jsonResponse = await response.json();
147
- return jsonResponse;
148
- };
149
- const getIssuesByComponent = async (projects, componentKeys) => {
150
- if (projects.length === 0) {
151
- return [];
152
- }
153
- const projectKeys = projects.map((project) => project.projectKey).join(",");
154
- const components = componentKeys.split(",").map((component) => `'${component.trim()}'`).join(",");
155
- const jql = `project in (${projectKeys}) AND component in (${components})`;
156
- const { instance } = projects[0];
157
- try {
158
- const response = await callApi(
159
- instance,
160
- `${instance.baseUrl}search?jql=${jql}`,
161
- {
162
- method: "GET",
163
- headers: {
164
- Accept: "application/json"
165
- }
166
- }
167
- ).then((resp) => resp.json());
168
- if (!response.issues || response.issues.length === 0) {
169
- return [];
170
- }
171
- return response.issues;
172
- } catch (error) {
173
- if (error.message.includes("does not exist for the field 'project'")) {
174
- return [];
175
- }
176
- throw error;
177
- }
178
- };
179
- async function getProjectAvatar(url, instance) {
180
- return callApi(instance, url);
181
- }
182
- async function callApi(instance, url, init) {
183
- const requestInit = init ?? { method: "GET" };
184
- requestInit.headers = {
185
- ...instance.headers,
186
- Authorization: instance.token,
187
- ...requestInit.headers
188
- };
189
- return fetch__default.default(url, requestInit);
190
- }
191
-
192
- const getProjectResponse = async (project, cache) => {
193
- let projectResponse;
194
- projectResponse = await cache.get(project.fullProjectKey);
195
- if (projectResponse) {
196
- return projectResponse;
197
- }
198
- try {
199
- projectResponse = await getProjectInfo(project);
200
- cache.set(project.fullProjectKey, projectResponse);
201
- } catch (err) {
202
- if (err.message !== 200) {
203
- throw Error(
204
- `Failed to get project info for project key ${project.fullProjectKey} with error: ${err.message}`
205
- );
206
- }
207
- }
208
- return projectResponse;
209
- };
210
- const getJqlResponse = async (jql, config, cache, searchOptions) => {
211
- let issuesResponse;
212
- const cacheKey = `${config.baseUrl} ${jql}`;
213
- issuesResponse = await cache.get(cacheKey);
214
- if (issuesResponse) {
215
- return issuesResponse;
216
- }
217
- try {
218
- issuesResponse = (await searchJira(config, jql, searchOptions)).issues;
219
- cache.set(cacheKey, issuesResponse);
220
- } catch (err) {
221
- if (err.message !== 200) {
222
- throw Error(
223
- `Failed to get issues for JQL ${jql} with error: ${err.message}`
224
- );
225
- }
226
- }
227
- return issuesResponse;
228
- };
229
- const getUserIssues = async (username, maxResults, config, cache, filterName) => {
230
- let jql = `assignee = "${username}" AND resolution = Unresolved ORDER BY priority DESC, updated DESC`;
231
- if (filterName !== "default") {
232
- for (const filter of config.defaultFilters || []) {
233
- if (filterName === filter.name) {
234
- jql = `assignee = "${username}" AND ${filter.query}`;
235
- }
236
- }
237
- }
238
- return getJqlResponse(jql, config, cache, {
239
- fields: [
240
- "key",
241
- "issuetype",
242
- "summary",
243
- "status",
244
- "priority",
245
- "created",
246
- "updated"
247
- ],
248
- maxResults
249
- });
250
- };
251
- const getFiltersFromAnnotations = async (annotations, config) => {
252
- const filters = [];
253
- for (const filter of annotations) {
254
- try {
255
- const response = await getFilterById(filter, config);
256
- filters.push(response);
257
- } catch (err) {
258
- console.warn(
259
- `${err.message} : Could not find filter with filter id ${filter}`
260
- );
261
- }
262
- }
263
- return filters;
264
- };
265
- async function getJiraProjectsFromKeys(projectKeys, instance, cache) {
266
- const jiraProjects = [];
267
- for (const key of projectKeys) {
268
- const cachedProject = await cache.get(key);
269
- let projectInfo;
270
- if (cachedProject) {
271
- projectInfo = cachedProject;
272
- } else {
273
- projectInfo = await getProjectInfo({
274
- projectKey: key,
275
- instance,
276
- fullProjectKey: ""
277
- });
278
- cache.set(key, projectInfo);
279
- }
280
- jiraProjects.push({
281
- instance,
282
- fullProjectKey: projectInfo.key,
283
- projectKey: projectInfo.key
284
- });
285
- }
286
- return jiraProjects;
287
- }
288
- const getIssuesFromFilters = async (projectKeys, components, filters, instance, cache) => {
289
- const projects = await getJiraProjectsFromKeys(projectKeys, instance, cache);
290
- return await Promise.all(
291
- filters.map(async (filter) => ({
292
- name: filter.name,
293
- query: jqlQueryBuilder({
294
- project: projectKeys,
295
- components,
296
- query: filter.query
297
- }),
298
- type: "filter",
299
- issues: await getIssuesByFilter(projects, components, filter.query)
300
- }))
301
- );
302
- };
303
- const getIssuesFromComponents = async (projectKeys, componentAnnotations, instance, cache) => {
304
- const projects = await getJiraProjectsFromKeys(projectKeys, instance, cache);
305
- return await Promise.all(
306
- componentAnnotations.map(async (componentKey) => ({
307
- name: componentKey,
308
- query: jqlQueryBuilder({
309
- project: projectKeys,
310
- components: [componentKey]
311
- }),
312
- type: "component",
313
- issues: await getIssuesByComponent(projects, componentKey)
314
- }))
315
- );
316
- };
317
-
318
- const DEFAULT_TTL = 1e3 * 60;
319
- const DEFAULT_MAX_RESULTS_USER_ISSUES = 10;
320
-
321
- const openFilter = {
322
- name: "Open Issues",
323
- shortName: "OPEN",
324
- query: "resolution = Unresolved ORDER BY updated DESC"
325
- };
326
- const getIncomingFilter = (incomingStatus) => ({
327
- name: "Incoming Issues",
328
- shortName: "INCOMING",
329
- query: `status = '${incomingStatus}' ORDER BY created ASC`
330
- });
331
- const getAssigneUser = (instance, userEntity) => {
332
- const emailSuffixConfig = instance.userEmailSuffix;
333
- return emailSuffixConfig ? `${userEntity.metadata.name}${emailSuffixConfig}` : userEntity.spec?.profile?.email || userEntity.metadata.name;
334
- };
335
- const getAssignedToMeFilter = (userEntity, instance) => {
336
- const email = getAssigneUser(instance, userEntity);
337
- return {
338
- name: "Assigned to me",
339
- shortName: "ME",
340
- query: `assignee = "${email}" AND resolution = Unresolved ORDER BY updated DESC`
341
- };
342
- };
343
- const getDefaultFiltersForUser = (instance, userEntity, incomingStatus) => {
344
- const incomingFilter = getIncomingFilter(incomingStatus ?? "New");
345
- const defaultFilters = instance.defaultFilters?.map((filter) => ({
346
- name: filter.name,
347
- query: filter.query,
348
- shortName: filter.shortName
349
- })) || [];
350
- if (!userEntity) return [openFilter, incomingFilter, ...defaultFilters];
351
- const assigneeToMeFilter = getAssignedToMeFilter(userEntity, instance);
352
- return [openFilter, incomingFilter, assigneeToMeFilter, ...defaultFilters];
353
- };
354
-
355
- async function createRouter(options) {
356
- const { auth, logger, rootConfig, config, discovery, httpAuth, userInfo } = options;
357
- const catalogClient$1 = new catalogClient.CatalogClient({ discoveryApi: discovery });
358
- const pluginCache = cache.CacheManager.fromConfig(rootConfig).forPlugin("jira-dashboard");
359
- const cache$1 = pluginCache.getClient({ defaultTtl: DEFAULT_TTL });
360
- logger.info("Initializing Jira Dashboard backend");
361
- const router = Router__default.default();
362
- router.use(express__default.default.json());
363
- router.get("/health", (_, response) => {
364
- logger.info("PONG!");
365
- response.json({ status: "ok" });
366
- });
367
- router.get(
368
- "/dashboards/by-entity-ref/:kind/:namespace/:name",
369
- async (request, response) => {
370
- const { kind, namespace, name } = request.params;
371
- const entityRef = catalogModel.stringifyEntityRef({ kind, namespace, name });
372
- const { token } = await auth.getPluginRequestToken({
373
- onBehalfOf: await auth.getOwnServiceCredentials(),
374
- targetPluginId: "catalog"
375
- });
376
- const entity = await catalogClient$1.getEntityByRef(entityRef, { token });
377
- const {
378
- projectKeyAnnotation,
379
- componentsAnnotation,
380
- filtersAnnotation,
381
- incomingIssuesAnnotation,
382
- componentRoadieAnnotation
383
- } = getAnnotations(config);
384
- if (!entity) {
385
- logger.info(`No entity found for ${entityRef}`);
386
- response.status(500).json({ error: `No entity found for ${entityRef}` });
387
- return;
388
- }
389
- const fullProjectKeys = entity.metadata.annotations?.[projectKeyAnnotation]?.split(",");
390
- if (!fullProjectKeys) {
391
- const error = `No jira.com/project-key annotation found for ${entityRef}`;
392
- logger.info(error);
393
- response.status(404).json(error);
394
- return;
395
- }
396
- const projects = fullProjectKeys.map(
397
- (fullProjectKey) => splitProjectKey(config, fullProjectKey)
398
- );
399
- let projectResponse;
400
- try {
401
- projectResponse = await getProjectResponse(projects[0], cache$1);
402
- } catch (err) {
403
- logger.error(
404
- `Could not find Jira project ${projects[0].fullProjectKey}: ${err.message}`
405
- );
406
- response.status(404).json({
407
- error: `No Jira project found with key ${projects[0].projectKey}`
408
- });
409
- return;
410
- }
411
- let userEntity;
412
- try {
413
- const credentials = await httpAuth.credentials(request, {
414
- allow: ["user"]
415
- });
416
- const userIdentity = credentials.principal.userEntityRef;
417
- userEntity = await catalogClient$1.getEntityByRef(userIdentity, {
418
- token
419
- });
420
- } catch (err) {
421
- logger.warn("Could not find user identity");
422
- }
423
- let filters = [];
424
- const incomingStatus = entity.metadata.annotations?.[incomingIssuesAnnotation];
425
- filters = getDefaultFiltersForUser(
426
- projects[0].instance,
427
- userEntity,
428
- incomingStatus
429
- );
430
- const customFilterAnnotations = entity.metadata.annotations?.[filtersAnnotation]?.split(",");
431
- if (customFilterAnnotations) {
432
- filters.push(
433
- ...await getFiltersFromAnnotations(
434
- customFilterAnnotations,
435
- projects[0].instance
436
- )
437
- );
438
- }
439
- const instance = projects[0]?.instance;
440
- let components = entity.metadata.annotations?.[componentsAnnotation]?.split(",") ?? [];
441
- const projectKeys = projects.map((project) => project.projectKey);
442
- let issues = await getIssuesFromFilters(
443
- projectKeys,
444
- components,
445
- filters,
446
- instance,
447
- cache$1
448
- );
449
- components = components.concat(
450
- entity.metadata.annotations?.[componentRoadieAnnotation]?.split(",") ?? []
451
- );
452
- if (components.length > 0) {
453
- const componentIssues = await getIssuesFromComponents(
454
- projectKeys,
455
- components,
456
- instance,
457
- cache$1
458
- );
459
- issues = issues.concat(componentIssues);
460
- }
461
- const jiraResponse = {
462
- project: projectResponse,
463
- data: issues
464
- };
465
- response.json(jiraResponse);
466
- }
467
- );
468
- router.get("/dashboards/user-issues", async (request, response) => {
469
- const { token } = await auth.getPluginRequestToken({
470
- onBehalfOf: await auth.getOwnServiceCredentials(),
471
- targetPluginId: "catalog"
472
- });
473
- const credentials = await httpAuth.credentials(request, {
474
- allow: ["user"]
475
- });
476
- if (!auth.isPrincipal(credentials, "user")) {
477
- response.status(200).json([]);
478
- return;
479
- }
480
- const info = await userInfo.getUserInfo(credentials);
481
- const userEntity = await catalogClient$1.getEntityByRef(info.userEntityRef, {
482
- token
483
- });
484
- if (!userEntity) {
485
- const error = `User entity cannot be determined from ${info.userEntityRef}`;
486
- logger.info(error);
487
- response.status(400).json(error);
488
- return;
489
- }
490
- const getUserIssuesForInstance = async (instance) => {
491
- const username = getAssigneUser(instance, userEntity);
492
- const maxResults = Number(
493
- request.query.maxResults || DEFAULT_MAX_RESULTS_USER_ISSUES
494
- );
495
- const filterName = request.query?.filterName || "default";
496
- try {
497
- const issues2 = await getUserIssues(
498
- username,
499
- maxResults,
500
- instance,
501
- cache$1,
502
- filterName
503
- );
504
- return { issues: issues2, error: void 0 };
505
- } catch (error) {
506
- return { error };
507
- }
508
- };
509
- const issuesList = await Promise.all(
510
- config.getInstances().map(
511
- (instanceName) => getUserIssuesForInstance(config.getInstance(instanceName))
512
- )
513
- );
514
- const issues = issuesList.flatMap((list) => list.issues ?? []);
515
- const errors = issuesList.flatMap((list) => list.error).filter((v) => !!v);
516
- if (issues.length > 0 || errors.length === 0) {
517
- response.status(200).json(issues);
518
- } else {
519
- const messages = errors.length > 1 ? `
520
- ${errors.map((err) => err.message).join("\n ")}` : ` ${errors[0].message}`;
521
- logger.error(`Error during getting user issues:${messages}`);
522
- response.status(503).json({
523
- error: `Error during getting user issues:${messages}`
524
- });
525
- }
526
- });
527
- router.get(
528
- "/avatar/by-entity-ref/:kind/:namespace/:name",
529
- async (request, response) => {
530
- const { kind, namespace, name } = request.params;
531
- const entityRef = catalogModel.stringifyEntityRef({ kind, namespace, name });
532
- const { token } = await auth.getPluginRequestToken({
533
- onBehalfOf: await auth.getOwnServiceCredentials(),
534
- targetPluginId: "catalog"
535
- });
536
- const entity = await catalogClient$1.getEntityByRef(entityRef, { token });
537
- const { projectKeyAnnotation } = getAnnotations(config);
538
- if (!entity) {
539
- logger.info(`No entity found for ${entityRef}`);
540
- response.status(500).json({ error: `No entity found for ${entityRef}` });
541
- return;
542
- }
543
- const fullProjectKeys = entity.metadata.annotations?.[projectKeyAnnotation]?.split(",");
544
- if (!fullProjectKeys) {
545
- const error = `No jira.com/project-key annotation found for ${entityRef}`;
546
- logger.info(error);
547
- response.status(404).json(error);
548
- return;
549
- }
550
- const projects = fullProjectKeys.map(
551
- (fullProjectKey) => splitProjectKey(config, fullProjectKey)
552
- );
553
- const projectResponse = await getProjectResponse(projects[0], cache$1);
554
- if (!projectResponse) {
555
- logger.error("Could not find project in Jira");
556
- response.status(400).json({
557
- error: `No Jira project found for project key ${projects[0].projectKey}`
558
- });
559
- return;
560
- }
561
- const url = projectResponse.avatarUrls["48x48"];
562
- const avatar = await getProjectAvatar(url, projects[0].instance);
563
- const ps = new stream__default.default.PassThrough();
564
- const val = avatar.headers.get("content-type");
565
- response.setHeader("content-type", val ?? "");
566
- stream__default.default.pipeline(avatar.body, ps, (err) => {
567
- if (err) {
568
- logger.error(`${err}`);
569
- response.sendStatus(400);
570
- }
571
- return;
572
- });
573
- ps.pipe(response);
574
- }
575
- );
576
- const middleware = rootHttpRouter.MiddlewareFactory.create({ logger, config: rootConfig });
577
- router.use(middleware.error());
578
- return router;
579
- }
580
-
581
- function parseHeaders(config) {
582
- if (!config) {
583
- return {};
584
- }
585
- return Object.fromEntries(
586
- config.keys().map((key) => {
587
- const value = config.getString(key);
588
- return [key, value];
589
- })
590
- );
591
- }
592
- const JIRA_CONFIG_BASE_URL = "baseUrl";
593
- const JIRA_CONFIG_TOKEN = "token";
594
- const JIRA_CONFIG_HEADERS = "headers";
595
- const JIRA_CONFIG_USER_EMAIL_SUFFIX = "userEmailSuffix";
596
- const JIRA_CONFIG_ANNOTATION = "annotationPrefix";
597
- const JIRA_FILTERS = "defaultFilters";
598
- class JiraConfig {
599
- instances = {};
600
- /**
601
- * The annotation prefix to use for Jira annotations
602
- */
603
- annotationPrefix;
604
- constructor(config) {
605
- const jira = config.getConfig("jiraDashboard");
606
- this.annotationPrefix = jira.getOptionalString(JIRA_CONFIG_ANNOTATION) ?? "jira.com";
607
- const instances = jira.getOptionalConfigArray("instances");
608
- if (instances) {
609
- instances.forEach((inst) => {
610
- const name = inst.getString("name");
611
- if (Object.getOwnPropertyNames(this.instances).includes(name)) {
612
- throw new errors.ConflictError(
613
- `Duplicate jiraDashboard instances: '${name}'`
614
- );
615
- }
616
- this.instances[name] = {
617
- token: inst.getString(JIRA_CONFIG_TOKEN),
618
- headers: parseHeaders(inst.getOptionalConfig(JIRA_CONFIG_HEADERS)),
619
- baseUrl: inst.getString(JIRA_CONFIG_BASE_URL),
620
- userEmailSuffix: inst.getOptionalString(
621
- JIRA_CONFIG_USER_EMAIL_SUFFIX
622
- ),
623
- defaultFilters: inst.getOptionalConfigArray(JIRA_FILTERS)?.map((filterConfig) => ({
624
- name: filterConfig.getString("name"),
625
- shortName: filterConfig.getString("shortName"),
626
- query: filterConfig.getString("query")
627
- }))
628
- };
629
- });
630
- } else {
631
- this.instances.default = {
632
- token: jira.getString(JIRA_CONFIG_TOKEN),
633
- headers: parseHeaders(jira.getOptionalConfig(JIRA_CONFIG_HEADERS)),
634
- baseUrl: jira.getString(JIRA_CONFIG_BASE_URL),
635
- userEmailSuffix: jira.getOptionalString(JIRA_CONFIG_USER_EMAIL_SUFFIX),
636
- defaultFilters: jira.getOptionalConfigArray(JIRA_FILTERS)?.map((filterConfig) => ({
637
- name: filterConfig.getString("name"),
638
- shortName: filterConfig.getString("shortName"),
639
- query: filterConfig.getString("query")
640
- }))
641
- };
642
- }
643
- }
644
- /**
645
- * Create a JiraConfig from the root config
646
- */
647
- static fromConfig(config) {
648
- return new JiraConfig(config);
649
- }
650
- forInstance(instanceName) {
651
- const instance = this.instances[instanceName];
652
- if (!instance) {
653
- throw new errors.ServiceUnavailableError(
654
- `No such jira instance '${instanceName}'`
655
- );
656
- }
657
- return instance;
658
- }
659
- /**
660
- * Returns the configuration all instances
661
- */
662
- getInstances() {
663
- return Object.getOwnPropertyNames(this.instances);
664
- }
665
- /**
666
- * Get the jira config for a specific instance
667
- */
668
- getInstance(instanceName) {
669
- return this.forInstance(instanceName ?? "default");
670
- }
671
- /**
672
- * Get the jira base url for a given instance
673
- */
674
- resolveJiraBaseUrl(instanceName) {
675
- const instance = this.forInstance(instanceName);
676
- return instance.baseUrl;
677
- }
678
- /**
679
- * Get the auth token for a given instance
680
- */
681
- resolveJiraToken(instanceName) {
682
- const instance = this.forInstance(instanceName);
683
- return instance.token;
684
- }
685
- /**
686
- * Get the email suffice for a given instance
687
- */
688
- resolveUserEmailSuffix(instanceName) {
689
- const instance = this.forInstance(instanceName);
690
- return instance.userEmailSuffix;
691
- }
692
- /**
693
- * Get the defined default filters for a given instance
694
- */
695
- resolveDefaultFilters(instanceName) {
696
- const instance = this.forInstance(instanceName);
697
- return instance.defaultFilters;
698
- }
699
- }
700
-
701
- const jiraDashboardPlugin = backendPluginApi.createBackendPlugin({
702
- pluginId: "jira-dashboard",
703
- register(env) {
704
- env.registerInit({
705
- deps: {
706
- auth: backendPluginApi.coreServices.auth,
707
- httpRouter: backendPluginApi.coreServices.httpRouter,
708
- logger: backendPluginApi.coreServices.logger,
709
- rootConfig: backendPluginApi.coreServices.rootConfig,
710
- discovery: backendPluginApi.coreServices.discovery,
711
- httpAuth: backendPluginApi.coreServices.httpAuth,
712
- userInfo: backendPluginApi.coreServices.userInfo
713
- },
714
- async init({
715
- auth,
716
- httpRouter,
717
- logger,
718
- rootConfig,
719
- discovery,
720
- httpAuth,
721
- userInfo
722
- }) {
723
- httpRouter.use(
724
- await createRouter({
725
- auth,
726
- logger,
727
- rootConfig,
728
- config: JiraConfig.fromConfig(rootConfig),
729
- discovery,
730
- httpAuth,
731
- userInfo
732
- })
733
- );
734
- httpRouter.addAuthPolicy({
735
- path: "/health",
736
- allow: "unauthenticated"
737
- });
738
- }
739
- });
740
- }
741
- });
742
-
743
- exports.JiraConfig = JiraConfig;
744
- exports.callApi = callApi;
745
- exports.default = jiraDashboardPlugin;
746
- exports.jqlQueryBuilder = jqlQueryBuilder;
747
- exports.searchJira = searchJira;
12
+ exports.default = plugin.jiraDashboardPlugin;
13
+ exports.callApi = api.callApi;
14
+ exports.searchJira = api.searchJira;
15
+ exports.JiraConfig = config.JiraConfig;
16
+ exports.jqlQueryBuilder = queries.jqlQueryBuilder;
748
17
  //# sourceMappingURL=index.cjs.js.map