@axis-backstage/plugin-jira-dashboard-backend 0.5.0 → 0.7.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/README.md +10 -4
- package/config.d.ts +2 -2
- package/dist/index.cjs.js +72 -52
- package/dist/index.cjs.js.map +1 -1
- package/package.json +4 -3
- package/CHANGELOG.md +0 -47
package/README.md
CHANGED
|
@@ -26,16 +26,22 @@ jiraDashboard:
|
|
|
26
26
|
token: ${JIRA_TOKEN}
|
|
27
27
|
baseUrl: ${JIRA_BASE_URL}
|
|
28
28
|
userEmailSuffix: ${JIRA_EMAIL_SUFFIX}
|
|
29
|
-
annotationPrefix
|
|
29
|
+
annotationPrefix: ${JIRA_ANNOTATION_PREFIX} # Optional
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
Configuration Details:
|
|
32
|
+
#### Configuration Details:
|
|
33
33
|
|
|
34
34
|
- `JIRA_TOKEN`: The API token to authenticate towards Jira. It can be found by visiting Atlassians page at https://developer.atlassian.com/cloud/jira/platform/basic-auth-for-rest-apis/. In case you are using a Bearer or Basic token, you need to add it in the beginning of the token. For instance: `Bearer your-secret-token`
|
|
35
35
|
> Note: The JIRA_TOKEN variable from [Roadie's Backstage Jira plugin](https://roadie.io/backstage/plugins/jira) can not be reused here because of the added encoding in this token.
|
|
36
|
-
- `JIRA_BASE_URL`: The base url for Jira in your company, including the API version. For instance: https://jira.se.your-company.com/rest/api/2/
|
|
36
|
+
- `JIRA_BASE_URL`: The base url for Jira in your company, including the API version. For instance: https://jira.se.your-company.com/rest/api/2/
|
|
37
37
|
- `JIRA_EMAIL_SUFFIX`: The email suffix used for retrieving a specific Jira user in a company. For instance: @your-company.com
|
|
38
|
-
- `JIRA_ANNOTATION_PREFIX`: Optional annotation prefix for retrieving a custom annotation.
|
|
38
|
+
- `JIRA_ANNOTATION_PREFIX`: Optional annotation prefix for retrieving a custom annotation. Defaut value is jira.com. If you want to configure the plugin to be compatible with [Roadie's Backstage Jira Plugin](https://roadie.io/backstage/plugins/jira/), use the following annotation prefix:
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
jiraDashboard:
|
|
42
|
+
{/* required configs... */}
|
|
43
|
+
annotationPrefix: jira
|
|
44
|
+
```
|
|
39
45
|
|
|
40
46
|
### Integrating
|
|
41
47
|
|
package/config.d.ts
CHANGED
|
@@ -13,9 +13,9 @@ export interface Config {
|
|
|
13
13
|
baseUrl: string;
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
16
|
+
* Optional email suffix used for retreiving a specific Jira user in a company. For instance @your-company.com. Default value is ''
|
|
17
17
|
*/
|
|
18
|
-
userEmailSuffix
|
|
18
|
+
userEmailSuffix?: string;
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Optional annotation prefix for retrieving a custom annotation. Defaut value is jira.com
|
package/dist/index.cjs.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var backendCommon = require('@backstage/backend-common');
|
|
6
|
+
var catalogModel = require('@backstage/catalog-model');
|
|
6
7
|
var express = require('express');
|
|
7
8
|
var Router = require('express-promise-router');
|
|
8
9
|
var catalogClient = require('@backstage/catalog-client');
|
|
@@ -37,11 +38,7 @@ function resolveJiraToken(config) {
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
function resolveUserEmailSuffix(config) {
|
|
40
|
-
|
|
41
|
-
return config.getString(JIRA_USER_CONFIG_EMAIL_SUFFIX);
|
|
42
|
-
} catch (error) {
|
|
43
|
-
throw new Error(`Invalid Jira user path, ${error}`);
|
|
44
|
-
}
|
|
41
|
+
return config.getOptionalString(JIRA_USER_CONFIG_EMAIL_SUFFIX) || "";
|
|
45
42
|
}
|
|
46
43
|
function resolveAnnotationPrefix(config) {
|
|
47
44
|
const annotationPrefix = config.getOptionalString(JIRA_ANNOTATION);
|
|
@@ -202,9 +199,11 @@ const getAnnotations = (config) => {
|
|
|
202
199
|
const projectKeyAnnotation = `${prefix}/${pluginJiraDashboardCommon.PROJECT_KEY_NAME}`;
|
|
203
200
|
const componentsAnnotation = `${prefix}/${pluginJiraDashboardCommon.COMPONENTS_NAME}`;
|
|
204
201
|
const filtersAnnotation = `${prefix}/${pluginJiraDashboardCommon.FILTERS_NAME}`;
|
|
202
|
+
const componentRoadieAnnotation = `${prefix}/component`;
|
|
205
203
|
return {
|
|
206
204
|
projectKeyAnnotation,
|
|
207
205
|
componentsAnnotation,
|
|
206
|
+
componentRoadieAnnotation,
|
|
208
207
|
filtersAnnotation
|
|
209
208
|
};
|
|
210
209
|
};
|
|
@@ -222,19 +221,25 @@ async function createRouter(options) {
|
|
|
222
221
|
response.json({ status: "ok" });
|
|
223
222
|
});
|
|
224
223
|
router.get(
|
|
225
|
-
"/dashboards/by-entity-ref/:
|
|
224
|
+
"/dashboards/by-entity-ref/:kind/:namespace/:name",
|
|
226
225
|
async (request, response) => {
|
|
227
|
-
var _a, _b, _c, _d, _e, _f;
|
|
228
|
-
const
|
|
226
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
227
|
+
const { kind, namespace, name } = request.params;
|
|
228
|
+
const entityRef = catalogModel.stringifyEntityRef({ kind, namespace, name });
|
|
229
229
|
const { token } = await tokenManager.getToken();
|
|
230
230
|
const entity = await catalogClient$1.getEntityByRef(entityRef, { token });
|
|
231
|
-
const {
|
|
231
|
+
const {
|
|
232
|
+
projectKeyAnnotation,
|
|
233
|
+
componentsAnnotation,
|
|
234
|
+
componentRoadieAnnotation,
|
|
235
|
+
filtersAnnotation
|
|
236
|
+
} = getAnnotations(config);
|
|
232
237
|
if (!entity) {
|
|
233
238
|
logger.info(`No entity found for ${entityRef}`);
|
|
234
239
|
response.status(500).json({ error: `No entity found for ${entityRef}` });
|
|
235
240
|
return;
|
|
236
241
|
}
|
|
237
|
-
const projectKey = (_a = entity.metadata.annotations) == null ? void 0 : _a[projectKeyAnnotation];
|
|
242
|
+
const projectKey = (_b = (_a = entity.metadata.annotations) == null ? void 0 : _a[projectKeyAnnotation]) == null ? void 0 : _b.split(",");
|
|
238
243
|
if (!projectKey) {
|
|
239
244
|
const error = `No jira.com/project-key annotation found for ${entityRef}`;
|
|
240
245
|
logger.info(error);
|
|
@@ -243,11 +248,15 @@ async function createRouter(options) {
|
|
|
243
248
|
}
|
|
244
249
|
let projectResponse;
|
|
245
250
|
try {
|
|
246
|
-
projectResponse = await getProjectResponse(
|
|
251
|
+
projectResponse = await getProjectResponse(
|
|
252
|
+
projectKey[0],
|
|
253
|
+
config,
|
|
254
|
+
cache
|
|
255
|
+
);
|
|
247
256
|
} catch (err) {
|
|
248
|
-
logger.error(`Could not find Jira project ${projectKey}`);
|
|
257
|
+
logger.error(`Could not find Jira project ${projectKey[0]}`);
|
|
249
258
|
response.status(404).json({
|
|
250
|
-
error: `No Jira project found with key ${projectKey}`
|
|
259
|
+
error: `No Jira project found with key ${projectKey[0]}`
|
|
251
260
|
});
|
|
252
261
|
return;
|
|
253
262
|
}
|
|
@@ -256,22 +265,25 @@ async function createRouter(options) {
|
|
|
256
265
|
logger.warn(`Could not find user identity`);
|
|
257
266
|
}
|
|
258
267
|
let filters = [];
|
|
259
|
-
const customFilterAnnotations = (
|
|
268
|
+
const customFilterAnnotations = (_d = (_c = entity.metadata.annotations) == null ? void 0 : _c[filtersAnnotation]) == null ? void 0 : _d.split(",");
|
|
260
269
|
filters = getDefaultFilters(
|
|
261
270
|
config,
|
|
262
|
-
(
|
|
271
|
+
(_e = userIdentity == null ? void 0 : userIdentity.identity) == null ? void 0 : _e.userEntityRef
|
|
263
272
|
);
|
|
264
273
|
if (customFilterAnnotations) {
|
|
265
274
|
filters.push(
|
|
266
275
|
...await getFiltersFromAnnotations(customFilterAnnotations, config)
|
|
267
276
|
);
|
|
268
277
|
}
|
|
269
|
-
let issues = await getIssuesFromFilters(projectKey, filters, config);
|
|
270
|
-
|
|
271
|
-
|
|
278
|
+
let issues = await getIssuesFromFilters(projectKey[0], filters, config);
|
|
279
|
+
let components = (_h = (_g = (_f = entity.metadata.annotations) == null ? void 0 : _f[componentsAnnotation]) == null ? void 0 : _g.split(",")) != null ? _h : [];
|
|
280
|
+
components = components.concat(
|
|
281
|
+
(_k = (_j = (_i = entity.metadata.annotations) == null ? void 0 : _i[componentRoadieAnnotation]) == null ? void 0 : _j.split(",")) != null ? _k : []
|
|
282
|
+
);
|
|
283
|
+
if (components) {
|
|
272
284
|
const componentIssues = await getIssuesFromComponents(
|
|
273
|
-
projectKey,
|
|
274
|
-
|
|
285
|
+
projectKey[0],
|
|
286
|
+
components,
|
|
275
287
|
config
|
|
276
288
|
);
|
|
277
289
|
issues = issues.concat(componentIssues);
|
|
@@ -283,40 +295,48 @@ async function createRouter(options) {
|
|
|
283
295
|
response.json(jiraResponse);
|
|
284
296
|
}
|
|
285
297
|
);
|
|
286
|
-
router.get(
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
298
|
+
router.get(
|
|
299
|
+
"/avatar/by-entity-ref/:kind/:namespace/:name",
|
|
300
|
+
async (request, response) => {
|
|
301
|
+
var _a, _b;
|
|
302
|
+
const { kind, namespace, name } = request.params;
|
|
303
|
+
const entityRef = catalogModel.stringifyEntityRef({ kind, namespace, name });
|
|
304
|
+
const { token } = await tokenManager.getToken();
|
|
305
|
+
const entity = await catalogClient$1.getEntityByRef(entityRef, { token });
|
|
306
|
+
const { projectKeyAnnotation } = getAnnotations(config);
|
|
307
|
+
if (!entity) {
|
|
308
|
+
logger.info(`No entity found for ${entityRef}`);
|
|
309
|
+
response.status(500).json({ error: `No entity found for ${entityRef}` });
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const projectKey = (_b = (_a = entity.metadata.annotations) == null ? void 0 : _a[projectKeyAnnotation]) == null ? void 0 : _b.split(",");
|
|
313
|
+
const projectResponse = await getProjectResponse(
|
|
314
|
+
projectKey[0],
|
|
315
|
+
config,
|
|
316
|
+
cache
|
|
317
|
+
);
|
|
318
|
+
if (!projectResponse) {
|
|
319
|
+
logger.error("Could not find project in Jira");
|
|
320
|
+
response.status(400).json({
|
|
321
|
+
error: `No Jira project found for project key ${projectKey[0]}`
|
|
322
|
+
});
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
const url = projectResponse.avatarUrls["48x48"];
|
|
326
|
+
const avatar = await getProjectAvatar(url, config);
|
|
327
|
+
const ps = new stream__default["default"].PassThrough();
|
|
328
|
+
const val = avatar.headers.get("content-type");
|
|
329
|
+
response.setHeader("content-type", val != null ? val : "");
|
|
330
|
+
stream__default["default"].pipeline(avatar.body, ps, (err) => {
|
|
331
|
+
if (err) {
|
|
332
|
+
logger.error(err);
|
|
333
|
+
response.sendStatus(400);
|
|
334
|
+
}
|
|
335
|
+
return;
|
|
303
336
|
});
|
|
304
|
-
|
|
337
|
+
ps.pipe(response);
|
|
305
338
|
}
|
|
306
|
-
|
|
307
|
-
const avatar = await getProjectAvatar(url, config);
|
|
308
|
-
const ps = new stream__default["default"].PassThrough();
|
|
309
|
-
const val = avatar.headers.get("content-type");
|
|
310
|
-
response.setHeader("content-type", val != null ? val : "");
|
|
311
|
-
stream__default["default"].pipeline(avatar.body, ps, (err) => {
|
|
312
|
-
if (err) {
|
|
313
|
-
logger.error(err);
|
|
314
|
-
response.sendStatus(400);
|
|
315
|
-
}
|
|
316
|
-
return;
|
|
317
|
-
});
|
|
318
|
-
ps.pipe(response);
|
|
319
|
-
});
|
|
339
|
+
);
|
|
320
340
|
router.use(backendCommon.errorHandler());
|
|
321
341
|
return router;
|
|
322
342
|
}
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/config.ts","../src/filters.ts","../src/api.ts","../src/service/service.ts","../src/lib.ts","../src/service/router.ts","../src/plugin.ts"],"sourcesContent":["import { Config } from '@backstage/config';\n\nconst JIRA_BASE_URL_CONFIG_PATH = 'jiraDashboard.baseUrl';\nconst JIRA_TOKEN_CONFIG_PATH = 'jiraDashboard.token';\nconst JIRA_USER_CONFIG_EMAIL_SUFFIX = 'jiraDashboard.userEmailSuffix';\nconst JIRA_ANNOTATION = 'jiraDashboard.annotationPrefix';\n\nexport function resolveJiraBaseUrl(config: Config): string {\n try {\n return config.getString(JIRA_BASE_URL_CONFIG_PATH);\n } catch (error) {\n throw new Error(`Invalid Jira baseUrl, ${error}`);\n }\n}\n\nexport function resolveJiraToken(config: Config): string {\n try {\n return config.getString(JIRA_TOKEN_CONFIG_PATH);\n } catch (error) {\n throw new Error(`Invalid Jira token, ${error}`);\n }\n}\n\nexport function resolveUserEmailSuffix(config: Config): string {\n try {\n return config.getString(JIRA_USER_CONFIG_EMAIL_SUFFIX);\n } catch (error) {\n throw new Error(`Invalid Jira user path, ${error}`);\n }\n}\n\nexport function resolveAnnotationPrefix(config: Config): string {\n const annotationPrefix = config.getOptionalString(JIRA_ANNOTATION);\n return annotationPrefix ?? 'jira.com';\n}\n","import { Config } from '@backstage/config';\nimport { resolveUserEmailSuffix } from './config';\nimport { Filter } from '@axis-backstage/plugin-jira-dashboard-common';\n\nconst getUsernameFromRef = (userRef: string) => {\n return userRef?.split('/').slice(1)[0];\n};\n\nconst openFilter: Filter = {\n name: 'Open Issues',\n shortName: 'OPEN',\n query: 'resolution = Unresolved ORDER BY updated DESC',\n};\n\nconst incomingFilter: Filter = {\n name: 'Incoming Issues',\n shortName: 'INCOMING',\n query: 'status = New ORDER BY created ASC',\n};\n\nexport const getDefaultFilters = (\n config: Config,\n userRef?: string,\n): Filter[] => {\n if (!userRef) {\n return [openFilter, incomingFilter];\n }\n const username = getUsernameFromRef(userRef);\n\n if (!username) {\n return [openFilter, incomingFilter];\n }\n\n const assignedToMeFilter: Filter = {\n name: 'Assigned to me',\n shortName: 'ME',\n query: `assignee = \"${username}${resolveUserEmailSuffix(\n config,\n )}\" AND resolution = Unresolved ORDER BY updated DESC`,\n };\n\n return [openFilter, incomingFilter, assignedToMeFilter];\n};\n","import { Config } from '@backstage/config';\nimport fetch from 'node-fetch';\nimport {\n Filter,\n Issue,\n Project,\n} from '@axis-backstage/plugin-jira-dashboard-common';\nimport { resolveJiraBaseUrl, resolveJiraToken } from './config';\n\nexport const getProjectInfo = async (\n projectKey: string,\n config: Config,\n): Promise<Project> => {\n const response = await fetch(\n `${resolveJiraBaseUrl(config)}project/${projectKey}`,\n {\n method: 'GET',\n headers: {\n Authorization: resolveJiraToken(config),\n Accept: 'application/json',\n },\n },\n );\n if (response.status !== 200) {\n throw Error(`${response.status}`);\n }\n return response.json();\n};\n\nexport const getFilterById = async (\n id: string,\n config: Config,\n): Promise<Filter> => {\n const response = await fetch(`${resolveJiraBaseUrl(config)}filter/${id}`, {\n method: 'GET',\n headers: {\n Authorization: resolveJiraToken(config),\n Accept: 'application/json',\n },\n });\n if (response.status !== 200) {\n throw Error(`${response.status}`);\n }\n const jsonResponse = await response.json();\n return { name: jsonResponse.name, query: jsonResponse.jql } as Filter;\n};\n\nexport const getIssuesByFilter = async (\n projectKey: string,\n query: string,\n config: Config,\n): Promise<Issue[]> => {\n const response = await fetch(\n `${resolveJiraBaseUrl(\n config,\n )}search?jql=project=${projectKey} AND ${query}`,\n {\n method: 'GET',\n headers: {\n Authorization: resolveJiraToken(config),\n Accept: 'application/json',\n },\n },\n ).then(resp => resp.json());\n return response.issues;\n};\n\nexport const getIssuesByComponent = async (\n projectKey: string,\n componentKey: string,\n config: Config,\n): Promise<Issue[]> => {\n const response = await fetch(\n `${resolveJiraBaseUrl(\n config,\n )}search?jql=project=${projectKey} AND component = \"${componentKey}\"`,\n {\n method: 'GET',\n headers: {\n Authorization: resolveJiraToken(config),\n Accept: 'application/json',\n },\n },\n ).then(resp => resp.json());\n return response.issues;\n};\n\nexport async function getProjectAvatar(url: string, config: Config) {\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n Authorization: resolveJiraToken(config),\n },\n });\n return response;\n}\n","import { CacheClient } from '@backstage/backend-common';\nimport { Config } from '@backstage/config';\nimport {\n type Filter,\n type JiraDataResponse,\n type Project,\n} from '@axis-backstage/plugin-jira-dashboard-common';\nimport {\n getFilterById,\n getIssuesByComponent,\n getIssuesByFilter,\n getProjectInfo,\n} from '../api';\n\nexport const getProjectResponse = async (\n projectKey: string,\n config: Config,\n cache: CacheClient,\n): Promise<Project> => {\n let projectResponse: Project;\n\n projectResponse = (await cache.get(projectKey)) as Project;\n\n if (projectResponse) return projectResponse as Project;\n\n try {\n projectResponse = await getProjectInfo(projectKey, config);\n cache.set(projectKey, projectResponse);\n } catch (err: any) {\n if (err.message !== 200) {\n throw Error(`${err.status}`);\n }\n }\n return projectResponse;\n};\n\nexport const getFiltersFromAnnotations = async (\n annotations: string[],\n config: Config,\n): Promise<Filter[]> => {\n const filters: Filter[] = [];\n\n for (const filter of annotations) {\n try {\n const response = await getFilterById(filter, config);\n filters.push(response);\n } catch (err: any) {\n console.warn(\n `${err.message} : Could not find filter with filter id ${filter}`,\n );\n }\n }\n return filters;\n};\n\nexport const getIssuesFromFilters = async (\n projectKey: string,\n filters: Filter[],\n config: Config,\n): Promise<JiraDataResponse[]> => {\n return await Promise.all(\n filters.map(async filter => ({\n name: filter.name,\n type: 'filter',\n issues: await getIssuesByFilter(projectKey, filter.query, config),\n })),\n );\n};\n\nexport const getIssuesFromComponents = async (\n projectKey: string,\n componentAnnotations: string[],\n config: Config,\n): Promise<JiraDataResponse[]> => {\n return await Promise.all(\n componentAnnotations.map(async componentKey => ({\n name: componentKey,\n type: 'component',\n issues: await getIssuesByComponent(projectKey, componentKey, config),\n })),\n );\n};\n","import { resolveAnnotationPrefix } from './config';\nimport {\n COMPONENTS_NAME,\n PROJECT_KEY_NAME,\n FILTERS_NAME,\n} from '@axis-backstage/plugin-jira-dashboard-common';\nimport { Config } from '@backstage/config';\n\nexport const getAnnotations = (config: Config) => {\n const prefix = resolveAnnotationPrefix(config);\n\n const projectKeyAnnotation = `${prefix}/${PROJECT_KEY_NAME}`;\n const componentsAnnotation = `${prefix}/${COMPONENTS_NAME}`;\n const filtersAnnotation = `${prefix}/${FILTERS_NAME}`;\n\n return {\n projectKeyAnnotation,\n componentsAnnotation,\n filtersAnnotation,\n };\n};\n","import {\n CacheManager,\n TokenManager,\n errorHandler,\n} from '@backstage/backend-common';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { Config } from '@backstage/config';\nimport { Logger } from 'winston';\nimport { CatalogClient } from '@backstage/catalog-client';\nimport { DiscoveryApi } from '@backstage/plugin-permission-common';\nimport { IdentityApi } from '@backstage/plugin-auth-node';\n\nimport { getDefaultFilters } from '../filters';\nimport {\n type Filter,\n type JiraResponse,\n type Project,\n} from '@axis-backstage/plugin-jira-dashboard-common';\nimport stream from 'stream';\nimport { getProjectAvatar } from '../api';\nimport {\n getProjectResponse,\n getFiltersFromAnnotations,\n getIssuesFromFilters,\n getIssuesFromComponents,\n} from './service';\nimport { getAnnotations } from '../lib';\n\n/**\n * Constructs a jira dashboard router.\n * @public\n */\nexport interface RouterOptions {\n /**\n * Implementation of Winston logger\n */\n logger: Logger;\n\n /**\n * Backstage config object\n */\n config: Config;\n\n /**\n * Backstage discovery api instance\n */\n discovery: DiscoveryApi;\n\n /**\n * Backstage identity api instance\n */\n identity: IdentityApi;\n\n /**\n * Backstage token manager instance\n */\n tokenManager: TokenManager;\n}\n\nconst DEFAULT_TTL = 1000 * 60;\n\n/**\n * Constructs a jira dashboard router.\n *\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { logger, config, discovery, identity, tokenManager } = options;\n const catalogClient = new CatalogClient({ discoveryApi: discovery });\n logger.info('Initializing Jira Dashboard backend');\n\n const pluginCache =\n CacheManager.fromConfig(config).forPlugin('jira-dashboard');\n const cache = pluginCache.getClient({ defaultTtl: DEFAULT_TTL });\n\n const router = Router();\n router.use(express.json());\n\n router.get('/health', (_, response) => {\n response.json({ status: 'ok' });\n });\n\n router.get(\n '/dashboards/by-entity-ref/:entityRef',\n async (request, response) => {\n const entityRef = request.params.entityRef;\n const { token } = await tokenManager.getToken();\n const entity = await catalogClient.getEntityByRef(entityRef, { token });\n const { projectKeyAnnotation, componentsAnnotation, filtersAnnotation } =\n getAnnotations(config);\n\n if (!entity) {\n logger.info(`No entity found for ${entityRef}`);\n response\n .status(500)\n .json({ error: `No entity found for ${entityRef}` });\n return;\n }\n\n const projectKey = entity.metadata.annotations?.[projectKeyAnnotation]!;\n\n if (!projectKey) {\n const error = `No jira.com/project-key annotation found for ${entityRef}`;\n logger.info(error);\n response.status(404).json(error);\n return;\n }\n\n let projectResponse;\n\n try {\n projectResponse = await getProjectResponse(projectKey, config, cache);\n } catch (err) {\n logger.error(`Could not find Jira project ${projectKey}`);\n response.status(404).json({\n error: `No Jira project found with key ${projectKey}`,\n });\n return;\n }\n\n const userIdentity = await identity.getIdentity({ request: request });\n\n if (!userIdentity) {\n logger.warn(`Could not find user identity`);\n }\n\n let filters: Filter[] = [];\n\n const customFilterAnnotations =\n entity.metadata.annotations?.[filtersAnnotation]?.split(',')!;\n\n filters = getDefaultFilters(\n config,\n userIdentity?.identity?.userEntityRef,\n );\n\n if (customFilterAnnotations) {\n filters.push(\n ...(await getFiltersFromAnnotations(customFilterAnnotations, config)),\n );\n }\n\n let issues = await getIssuesFromFilters(projectKey, filters, config);\n\n const componentAnnotations =\n entity.metadata.annotations?.[componentsAnnotation]?.split(',')!;\n\n if (componentAnnotations) {\n const componentIssues = await getIssuesFromComponents(\n projectKey,\n componentAnnotations,\n config,\n );\n issues = issues.concat(componentIssues);\n }\n\n const jiraResponse: JiraResponse = {\n project: projectResponse as Project,\n data: issues,\n };\n response.json(jiraResponse);\n },\n );\n\n router.get('/avatar/by-entity-ref/:entityRef', async (request, response) => {\n const { entityRef } = request.params;\n const { token } = await tokenManager.getToken();\n const entity = await catalogClient.getEntityByRef(entityRef, { token });\n const { projectKeyAnnotation } = getAnnotations(config);\n\n if (!entity) {\n logger.info(`No entity found for ${entityRef}`);\n response.status(500).json({ error: `No entity found for ${entityRef}` });\n return;\n }\n\n const projectKey = entity.metadata.annotations?.[projectKeyAnnotation]!;\n\n const projectResponse = await getProjectResponse(projectKey, config, cache);\n\n if (!projectResponse) {\n logger.error('Could not find project in Jira');\n response.status(400).json({\n error: `No Jira project found for project key ${projectKey}`,\n });\n return;\n }\n\n const url = projectResponse.avatarUrls['48x48'];\n\n const avatar = await getProjectAvatar(url, config);\n\n const ps = new stream.PassThrough();\n const val = avatar.headers.get('content-type');\n\n response.setHeader('content-type', val ?? '');\n stream.pipeline(avatar.body, ps, err => {\n if (err) {\n logger.error(err);\n response.sendStatus(400);\n }\n return;\n });\n ps.pipe(response);\n });\n router.use(errorHandler());\n return router;\n}\n","import { loggerToWinstonLogger } from '@backstage/backend-common';\nimport {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\n\n/**\n * The Jira Dashboard backend plugin.\n *\n * @public\n */\nexport const jiraDashboardPlugin = createBackendPlugin({\n pluginId: 'jira-dashboard',\n register(env) {\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n discovery: coreServices.discovery,\n identity: coreServices.identity,\n tokenManager: coreServices.tokenManager,\n httpRouter: coreServices.httpRouter,\n },\n async init({\n logger,\n config,\n discovery,\n identity,\n tokenManager,\n httpRouter,\n }) {\n httpRouter.use(\n await createRouter({\n logger: loggerToWinstonLogger(logger),\n config,\n discovery,\n identity,\n tokenManager,\n }),\n );\n },\n });\n },\n});\n"],"names":["fetch","PROJECT_KEY_NAME","COMPONENTS_NAME","FILTERS_NAME","catalogClient","CatalogClient","CacheManager","Router","express","stream","errorHandler","createBackendPlugin","coreServices","loggerToWinstonLogger"],"mappings":";;;;;;;;;;;;;;;;;;;;AAEA,MAAM,yBAA4B,GAAA,uBAAA,CAAA;AAClC,MAAM,sBAAyB,GAAA,qBAAA,CAAA;AAC/B,MAAM,6BAAgC,GAAA,+BAAA,CAAA;AACtC,MAAM,eAAkB,GAAA,gCAAA,CAAA;AAEjB,SAAS,mBAAmB,MAAwB,EAAA;AACzD,EAAI,IAAA;AACF,IAAO,OAAA,MAAA,CAAO,UAAU,yBAAyB,CAAA,CAAA;AAAA,WAC1C,KAAO,EAAA;AACd,IAAA,MAAM,IAAI,KAAA,CAAM,CAAyB,sBAAA,EAAA,KAAK,CAAE,CAAA,CAAA,CAAA;AAAA,GAClD;AACF,CAAA;AAEO,SAAS,iBAAiB,MAAwB,EAAA;AACvD,EAAI,IAAA;AACF,IAAO,OAAA,MAAA,CAAO,UAAU,sBAAsB,CAAA,CAAA;AAAA,WACvC,KAAO,EAAA;AACd,IAAA,MAAM,IAAI,KAAA,CAAM,CAAuB,oBAAA,EAAA,KAAK,CAAE,CAAA,CAAA,CAAA;AAAA,GAChD;AACF,CAAA;AAEO,SAAS,uBAAuB,MAAwB,EAAA;AAC7D,EAAI,IAAA;AACF,IAAO,OAAA,MAAA,CAAO,UAAU,6BAA6B,CAAA,CAAA;AAAA,WAC9C,KAAO,EAAA;AACd,IAAA,MAAM,IAAI,KAAA,CAAM,CAA2B,wBAAA,EAAA,KAAK,CAAE,CAAA,CAAA,CAAA;AAAA,GACpD;AACF,CAAA;AAEO,SAAS,wBAAwB,MAAwB,EAAA;AAC9D,EAAM,MAAA,gBAAA,GAAmB,MAAO,CAAA,iBAAA,CAAkB,eAAe,CAAA,CAAA;AACjE,EAAA,OAAO,gBAAoB,IAAA,IAAA,GAAA,gBAAA,GAAA,UAAA,CAAA;AAC7B;;AC9BA,MAAM,kBAAA,GAAqB,CAAC,OAAoB,KAAA;AAC9C,EAAA,OAAO,OAAS,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,KAAA,CAAM,GAAK,CAAA,CAAA,KAAA,CAAM,CAAG,CAAA,CAAA,CAAA,CAAA,CAAA;AACtC,CAAA,CAAA;AAEA,MAAM,UAAqB,GAAA;AAAA,EACzB,IAAM,EAAA,aAAA;AAAA,EACN,SAAW,EAAA,MAAA;AAAA,EACX,KAAO,EAAA,+CAAA;AACT,CAAA,CAAA;AAEA,MAAM,cAAyB,GAAA;AAAA,EAC7B,IAAM,EAAA,iBAAA;AAAA,EACN,SAAW,EAAA,UAAA;AAAA,EACX,KAAO,EAAA,mCAAA;AACT,CAAA,CAAA;AAEa,MAAA,iBAAA,GAAoB,CAC/B,MAAA,EACA,OACa,KAAA;AACb,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAO,OAAA,CAAC,YAAY,cAAc,CAAA,CAAA;AAAA,GACpC;AACA,EAAM,MAAA,QAAA,GAAW,mBAAmB,OAAO,CAAA,CAAA;AAE3C,EAAA,IAAI,CAAC,QAAU,EAAA;AACb,IAAO,OAAA,CAAC,YAAY,cAAc,CAAA,CAAA;AAAA,GACpC;AAEA,EAAA,MAAM,kBAA6B,GAAA;AAAA,IACjC,IAAM,EAAA,gBAAA;AAAA,IACN,SAAW,EAAA,IAAA;AAAA,IACX,KAAA,EAAO,CAAe,YAAA,EAAA,QAAQ,CAAG,EAAA,sBAAA;AAAA,MAC/B,MAAA;AAAA,KACD,CAAA,mDAAA,CAAA;AAAA,GACH,CAAA;AAEA,EAAO,OAAA,CAAC,UAAY,EAAA,cAAA,EAAgB,kBAAkB,CAAA,CAAA;AACxD,CAAA;;ACjCa,MAAA,cAAA,GAAiB,OAC5B,UAAA,EACA,MACqB,KAAA;AACrB,EAAA,MAAM,WAAW,MAAMA,yBAAA;AAAA,IACrB,CAAG,EAAA,kBAAA,CAAmB,MAAM,CAAC,WAAW,UAAU,CAAA,CAAA;AAAA,IAClD;AAAA,MACE,MAAQ,EAAA,KAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACP,aAAA,EAAe,iBAAiB,MAAM,CAAA;AAAA,QACtC,MAAQ,EAAA,kBAAA;AAAA,OACV;AAAA,KACF;AAAA,GACF,CAAA;AACA,EAAI,IAAA,QAAA,CAAS,WAAW,GAAK,EAAA;AAC3B,IAAA,MAAM,KAAM,CAAA,CAAA,EAAG,QAAS,CAAA,MAAM,CAAE,CAAA,CAAA,CAAA;AAAA,GAClC;AACA,EAAA,OAAO,SAAS,IAAK,EAAA,CAAA;AACvB,CAAA,CAAA;AAEa,MAAA,aAAA,GAAgB,OAC3B,EAAA,EACA,MACoB,KAAA;AACpB,EAAM,MAAA,QAAA,GAAW,MAAMA,yBAAM,CAAA,CAAA,EAAG,mBAAmB,MAAM,CAAC,CAAU,OAAA,EAAA,EAAE,CAAI,CAAA,EAAA;AAAA,IACxE,MAAQ,EAAA,KAAA;AAAA,IACR,OAAS,EAAA;AAAA,MACP,aAAA,EAAe,iBAAiB,MAAM,CAAA;AAAA,MACtC,MAAQ,EAAA,kBAAA;AAAA,KACV;AAAA,GACD,CAAA,CAAA;AACD,EAAI,IAAA,QAAA,CAAS,WAAW,GAAK,EAAA;AAC3B,IAAA,MAAM,KAAM,CAAA,CAAA,EAAG,QAAS,CAAA,MAAM,CAAE,CAAA,CAAA,CAAA;AAAA,GAClC;AACA,EAAM,MAAA,YAAA,GAAe,MAAM,QAAA,CAAS,IAAK,EAAA,CAAA;AACzC,EAAA,OAAO,EAAE,IAAM,EAAA,YAAA,CAAa,IAAM,EAAA,KAAA,EAAO,aAAa,GAAI,EAAA,CAAA;AAC5D,CAAA,CAAA;AAEO,MAAM,iBAAoB,GAAA,OAC/B,UACA,EAAA,KAAA,EACA,MACqB,KAAA;AACrB,EAAA,MAAM,WAAW,MAAMA,yBAAA;AAAA,IACrB,CAAG,EAAA,kBAAA;AAAA,MACD,MAAA;AAAA,KACD,CAAA,mBAAA,EAAsB,UAAU,CAAA,KAAA,EAAQ,KAAK,CAAA,CAAA;AAAA,IAC9C;AAAA,MACE,MAAQ,EAAA,KAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACP,aAAA,EAAe,iBAAiB,MAAM,CAAA;AAAA,QACtC,MAAQ,EAAA,kBAAA;AAAA,OACV;AAAA,KACF;AAAA,GACA,CAAA,IAAA,CAAK,CAAQ,IAAA,KAAA,IAAA,CAAK,MAAM,CAAA,CAAA;AAC1B,EAAA,OAAO,QAAS,CAAA,MAAA,CAAA;AAClB,CAAA,CAAA;AAEO,MAAM,oBAAuB,GAAA,OAClC,UACA,EAAA,YAAA,EACA,MACqB,KAAA;AACrB,EAAA,MAAM,WAAW,MAAMA,yBAAA;AAAA,IACrB,CAAG,EAAA,kBAAA;AAAA,MACD,MAAA;AAAA,KACD,CAAA,mBAAA,EAAsB,UAAU,CAAA,kBAAA,EAAqB,YAAY,CAAA,CAAA,CAAA;AAAA,IAClE;AAAA,MACE,MAAQ,EAAA,KAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACP,aAAA,EAAe,iBAAiB,MAAM,CAAA;AAAA,QACtC,MAAQ,EAAA,kBAAA;AAAA,OACV;AAAA,KACF;AAAA,GACA,CAAA,IAAA,CAAK,CAAQ,IAAA,KAAA,IAAA,CAAK,MAAM,CAAA,CAAA;AAC1B,EAAA,OAAO,QAAS,CAAA,MAAA,CAAA;AAClB,CAAA,CAAA;AAEsB,eAAA,gBAAA,CAAiB,KAAa,MAAgB,EAAA;AAClE,EAAM,MAAA,QAAA,GAAW,MAAMA,yBAAA,CAAM,GAAK,EAAA;AAAA,IAChC,MAAQ,EAAA,KAAA;AAAA,IACR,OAAS,EAAA;AAAA,MACP,aAAA,EAAe,iBAAiB,MAAM,CAAA;AAAA,KACxC;AAAA,GACD,CAAA,CAAA;AACD,EAAO,OAAA,QAAA,CAAA;AACT;;ACjFO,MAAM,kBAAqB,GAAA,OAChC,UACA,EAAA,MAAA,EACA,KACqB,KAAA;AACrB,EAAI,IAAA,eAAA,CAAA;AAEJ,EAAmB,eAAA,GAAA,MAAM,KAAM,CAAA,GAAA,CAAI,UAAU,CAAA,CAAA;AAE7C,EAAI,IAAA,eAAA;AAAiB,IAAO,OAAA,eAAA,CAAA;AAE5B,EAAI,IAAA;AACF,IAAkB,eAAA,GAAA,MAAM,cAAe,CAAA,UAAA,EAAY,MAAM,CAAA,CAAA;AACzD,IAAM,KAAA,CAAA,GAAA,CAAI,YAAY,eAAe,CAAA,CAAA;AAAA,WAC9B,GAAU,EAAA;AACjB,IAAI,IAAA,GAAA,CAAI,YAAY,GAAK,EAAA;AACvB,MAAA,MAAM,KAAM,CAAA,CAAA,EAAG,GAAI,CAAA,MAAM,CAAE,CAAA,CAAA,CAAA;AAAA,KAC7B;AAAA,GACF;AACA,EAAO,OAAA,eAAA,CAAA;AACT,CAAA,CAAA;AAEa,MAAA,yBAAA,GAA4B,OACvC,WAAA,EACA,MACsB,KAAA;AACtB,EAAA,MAAM,UAAoB,EAAC,CAAA;AAE3B,EAAA,KAAA,MAAW,UAAU,WAAa,EAAA;AAChC,IAAI,IAAA;AACF,MAAA,MAAM,QAAW,GAAA,MAAM,aAAc,CAAA,MAAA,EAAQ,MAAM,CAAA,CAAA;AACnD,MAAA,OAAA,CAAQ,KAAK,QAAQ,CAAA,CAAA;AAAA,aACd,GAAU,EAAA;AACjB,MAAQ,OAAA,CAAA,IAAA;AAAA,QACN,CAAG,EAAA,GAAA,CAAI,OAAO,CAAA,wCAAA,EAA2C,MAAM,CAAA,CAAA;AAAA,OACjE,CAAA;AAAA,KACF;AAAA,GACF;AACA,EAAO,OAAA,OAAA,CAAA;AACT,CAAA,CAAA;AAEO,MAAM,oBAAuB,GAAA,OAClC,UACA,EAAA,OAAA,EACA,MACgC,KAAA;AAChC,EAAA,OAAO,MAAM,OAAQ,CAAA,GAAA;AAAA,IACnB,OAAA,CAAQ,GAAI,CAAA,OAAM,MAAW,MAAA;AAAA,MAC3B,MAAM,MAAO,CAAA,IAAA;AAAA,MACb,IAAM,EAAA,QAAA;AAAA,MACN,QAAQ,MAAM,iBAAA,CAAkB,UAAY,EAAA,MAAA,CAAO,OAAO,MAAM,CAAA;AAAA,KAChE,CAAA,CAAA;AAAA,GACJ,CAAA;AACF,CAAA,CAAA;AAEO,MAAM,uBAA0B,GAAA,OACrC,UACA,EAAA,oBAAA,EACA,MACgC,KAAA;AAChC,EAAA,OAAO,MAAM,OAAQ,CAAA,GAAA;AAAA,IACnB,oBAAA,CAAqB,GAAI,CAAA,OAAM,YAAiB,MAAA;AAAA,MAC9C,IAAM,EAAA,YAAA;AAAA,MACN,IAAM,EAAA,WAAA;AAAA,MACN,MAAQ,EAAA,MAAM,oBAAqB,CAAA,UAAA,EAAY,cAAc,MAAM,CAAA;AAAA,KACnE,CAAA,CAAA;AAAA,GACJ,CAAA;AACF,CAAA;;ACzEa,MAAA,cAAA,GAAiB,CAAC,MAAmB,KAAA;AAChD,EAAM,MAAA,MAAA,GAAS,wBAAwB,MAAM,CAAA,CAAA;AAE7C,EAAA,MAAM,oBAAuB,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAIC,0CAAgB,CAAA,CAAA,CAAA;AAC1D,EAAA,MAAM,oBAAuB,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAIC,yCAAe,CAAA,CAAA,CAAA;AACzD,EAAA,MAAM,iBAAoB,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAIC,sCAAY,CAAA,CAAA,CAAA;AAEnD,EAAO,OAAA;AAAA,IACL,oBAAA;AAAA,IACA,oBAAA;AAAA,IACA,iBAAA;AAAA,GACF,CAAA;AACF,CAAA;;ACwCA,MAAM,cAAc,GAAO,GAAA,EAAA,CAAA;AAO3B,eAAsB,aACpB,OACyB,EAAA;AACzB,EAAA,MAAM,EAAE,MAAQ,EAAA,MAAA,EAAQ,SAAW,EAAA,QAAA,EAAU,cAAiB,GAAA,OAAA,CAAA;AAC9D,EAAA,MAAMC,kBAAgB,IAAIC,2BAAA,CAAc,EAAE,YAAA,EAAc,WAAW,CAAA,CAAA;AACnE,EAAA,MAAA,CAAO,KAAK,qCAAqC,CAAA,CAAA;AAEjD,EAAA,MAAM,cACJC,0BAAa,CAAA,UAAA,CAAW,MAAM,CAAA,CAAE,UAAU,gBAAgB,CAAA,CAAA;AAC5D,EAAA,MAAM,QAAQ,WAAY,CAAA,SAAA,CAAU,EAAE,UAAA,EAAY,aAAa,CAAA,CAAA;AAE/D,EAAA,MAAM,SAASC,0BAAO,EAAA,CAAA;AACtB,EAAO,MAAA,CAAA,GAAA,CAAIC,2BAAQ,CAAA,IAAA,EAAM,CAAA,CAAA;AAEzB,EAAA,MAAA,CAAO,GAAI,CAAA,SAAA,EAAW,CAAC,CAAA,EAAG,QAAa,KAAA;AACrC,IAAA,QAAA,CAAS,IAAK,CAAA,EAAE,MAAQ,EAAA,IAAA,EAAM,CAAA,CAAA;AAAA,GAC/B,CAAA,CAAA;AAED,EAAO,MAAA,CAAA,GAAA;AAAA,IACL,sCAAA;AAAA,IACA,OAAO,SAAS,QAAa,KAAA;AAvFjC,MAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,CAAA;AAwFM,MAAM,MAAA,SAAA,GAAY,QAAQ,MAAO,CAAA,SAAA,CAAA;AACjC,MAAA,MAAM,EAAE,KAAA,EAAU,GAAA,MAAM,aAAa,QAAS,EAAA,CAAA;AAC9C,MAAA,MAAM,SAAS,MAAMJ,eAAA,CAAc,eAAe,SAAW,EAAA,EAAE,OAAO,CAAA,CAAA;AACtE,MAAA,MAAM,EAAE,oBAAsB,EAAA,oBAAA,EAAsB,iBAAkB,EAAA,GACpE,eAAe,MAAM,CAAA,CAAA;AAEvB,MAAA,IAAI,CAAC,MAAQ,EAAA;AACX,QAAO,MAAA,CAAA,IAAA,CAAK,CAAuB,oBAAA,EAAA,SAAS,CAAE,CAAA,CAAA,CAAA;AAC9C,QACG,QAAA,CAAA,MAAA,CAAO,GAAG,CACV,CAAA,IAAA,CAAK,EAAE,KAAO,EAAA,CAAA,oBAAA,EAAuB,SAAS,CAAA,CAAA,EAAI,CAAA,CAAA;AACrD,QAAA,OAAA;AAAA,OACF;AAEA,MAAA,MAAM,UAAa,GAAA,CAAA,EAAA,GAAA,MAAA,CAAO,QAAS,CAAA,WAAA,KAAhB,IAA8B,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,CAAA;AAEjD,MAAA,IAAI,CAAC,UAAY,EAAA;AACf,QAAM,MAAA,KAAA,GAAQ,gDAAgD,SAAS,CAAA,CAAA,CAAA;AACvE,QAAA,MAAA,CAAO,KAAK,KAAK,CAAA,CAAA;AACjB,QAAA,QAAA,CAAS,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,KAAK,CAAA,CAAA;AAC/B,QAAA,OAAA;AAAA,OACF;AAEA,MAAI,IAAA,eAAA,CAAA;AAEJ,MAAI,IAAA;AACF,QAAA,eAAA,GAAkB,MAAM,kBAAA,CAAmB,UAAY,EAAA,MAAA,EAAQ,KAAK,CAAA,CAAA;AAAA,eAC7D,GAAK,EAAA;AACZ,QAAO,MAAA,CAAA,KAAA,CAAM,CAA+B,4BAAA,EAAA,UAAU,CAAE,CAAA,CAAA,CAAA;AACxD,QAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA;AAAA,UACxB,KAAA,EAAO,kCAAkC,UAAU,CAAA,CAAA;AAAA,SACpD,CAAA,CAAA;AACD,QAAA,OAAA;AAAA,OACF;AAEA,MAAA,MAAM,eAAe,MAAM,QAAA,CAAS,WAAY,CAAA,EAAE,SAAkB,CAAA,CAAA;AAEpE,MAAA,IAAI,CAAC,YAAc,EAAA;AACjB,QAAA,MAAA,CAAO,KAAK,CAA8B,4BAAA,CAAA,CAAA,CAAA;AAAA,OAC5C;AAEA,MAAA,IAAI,UAAoB,EAAC,CAAA;AAEzB,MAAA,MAAM,2BACJ,EAAO,GAAA,CAAA,EAAA,GAAA,MAAA,CAAA,QAAA,CAAS,gBAAhB,IAA8B,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,iBAAA,CAAA,KAA9B,mBAAkD,KAAM,CAAA,GAAA,CAAA,CAAA;AAE1D,MAAU,OAAA,GAAA,iBAAA;AAAA,QACR,MAAA;AAAA,QACA,CAAA,EAAA,GAAA,YAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,YAAA,CAAc,aAAd,IAAwB,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,aAAA;AAAA,OAC1B,CAAA;AAEA,MAAA,IAAI,uBAAyB,EAAA;AAC3B,QAAQ,OAAA,CAAA,IAAA;AAAA,UACN,GAAI,MAAM,yBAA0B,CAAA,uBAAA,EAAyB,MAAM,CAAA;AAAA,SACrE,CAAA;AAAA,OACF;AAEA,MAAA,IAAI,MAAS,GAAA,MAAM,oBAAqB,CAAA,UAAA,EAAY,SAAS,MAAM,CAAA,CAAA;AAEnE,MAAA,MAAM,wBACJ,EAAO,GAAA,CAAA,EAAA,GAAA,MAAA,CAAA,QAAA,CAAS,gBAAhB,IAA8B,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,KAA9B,mBAAqD,KAAM,CAAA,GAAA,CAAA,CAAA;AAE7D,MAAA,IAAI,oBAAsB,EAAA;AACxB,QAAA,MAAM,kBAAkB,MAAM,uBAAA;AAAA,UAC5B,UAAA;AAAA,UACA,oBAAA;AAAA,UACA,MAAA;AAAA,SACF,CAAA;AACA,QAAS,MAAA,GAAA,MAAA,CAAO,OAAO,eAAe,CAAA,CAAA;AAAA,OACxC;AAEA,MAAA,MAAM,YAA6B,GAAA;AAAA,QACjC,OAAS,EAAA,eAAA;AAAA,QACT,IAAM,EAAA,MAAA;AAAA,OACR,CAAA;AACA,MAAA,QAAA,CAAS,KAAK,YAAY,CAAA,CAAA;AAAA,KAC5B;AAAA,GACF,CAAA;AAEA,EAAA,MAAA,CAAO,GAAI,CAAA,kCAAA,EAAoC,OAAO,OAAA,EAAS,QAAa,KAAA;AAvK9E,IAAA,IAAA,EAAA,CAAA;AAwKI,IAAM,MAAA,EAAE,SAAU,EAAA,GAAI,OAAQ,CAAA,MAAA,CAAA;AAC9B,IAAA,MAAM,EAAE,KAAA,EAAU,GAAA,MAAM,aAAa,QAAS,EAAA,CAAA;AAC9C,IAAA,MAAM,SAAS,MAAMA,eAAA,CAAc,eAAe,SAAW,EAAA,EAAE,OAAO,CAAA,CAAA;AACtE,IAAA,MAAM,EAAE,oBAAA,EAAyB,GAAA,cAAA,CAAe,MAAM,CAAA,CAAA;AAEtD,IAAA,IAAI,CAAC,MAAQ,EAAA;AACX,MAAO,MAAA,CAAA,IAAA,CAAK,CAAuB,oBAAA,EAAA,SAAS,CAAE,CAAA,CAAA,CAAA;AAC9C,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,KAAO,EAAA,CAAA,oBAAA,EAAuB,SAAS,CAAA,CAAA,EAAI,CAAA,CAAA;AACvE,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,MAAM,UAAa,GAAA,CAAA,EAAA,GAAA,MAAA,CAAO,QAAS,CAAA,WAAA,KAAhB,IAA8B,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,CAAA;AAEjD,IAAA,MAAM,eAAkB,GAAA,MAAM,kBAAmB,CAAA,UAAA,EAAY,QAAQ,KAAK,CAAA,CAAA;AAE1E,IAAA,IAAI,CAAC,eAAiB,EAAA;AACpB,MAAA,MAAA,CAAO,MAAM,gCAAgC,CAAA,CAAA;AAC7C,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA;AAAA,QACxB,KAAA,EAAO,yCAAyC,UAAU,CAAA,CAAA;AAAA,OAC3D,CAAA,CAAA;AACD,MAAA,OAAA;AAAA,KACF;AAEA,IAAM,MAAA,GAAA,GAAM,eAAgB,CAAA,UAAA,CAAW,OAAO,CAAA,CAAA;AAE9C,IAAA,MAAM,MAAS,GAAA,MAAM,gBAAiB,CAAA,GAAA,EAAK,MAAM,CAAA,CAAA;AAEjD,IAAM,MAAA,EAAA,GAAK,IAAIK,0BAAA,CAAO,WAAY,EAAA,CAAA;AAClC,IAAA,MAAM,GAAM,GAAA,MAAA,CAAO,OAAQ,CAAA,GAAA,CAAI,cAAc,CAAA,CAAA;AAE7C,IAAS,QAAA,CAAA,SAAA,CAAU,cAAgB,EAAA,GAAA,IAAA,IAAA,GAAA,GAAA,GAAO,EAAE,CAAA,CAAA;AAC5C,IAAAA,0BAAA,CAAO,QAAS,CAAA,MAAA,CAAO,IAAM,EAAA,EAAA,EAAI,CAAO,GAAA,KAAA;AACtC,MAAA,IAAI,GAAK,EAAA;AACP,QAAA,MAAA,CAAO,MAAM,GAAG,CAAA,CAAA;AAChB,QAAA,QAAA,CAAS,WAAW,GAAG,CAAA,CAAA;AAAA,OACzB;AACA,MAAA,OAAA;AAAA,KACD,CAAA,CAAA;AACD,IAAA,EAAA,CAAG,KAAK,QAAQ,CAAA,CAAA;AAAA,GACjB,CAAA,CAAA;AACD,EAAO,MAAA,CAAA,GAAA,CAAIC,4BAAc,CAAA,CAAA;AACzB,EAAO,OAAA,MAAA,CAAA;AACT;;ACtMO,MAAM,sBAAsBC,oCAAoB,CAAA;AAAA,EACrD,QAAU,EAAA,gBAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,QAAQC,6BAAa,CAAA,MAAA;AAAA,QACrB,QAAQA,6BAAa,CAAA,UAAA;AAAA,QACrB,WAAWA,6BAAa,CAAA,SAAA;AAAA,QACxB,UAAUA,6BAAa,CAAA,QAAA;AAAA,QACvB,cAAcA,6BAAa,CAAA,YAAA;AAAA,QAC3B,YAAYA,6BAAa,CAAA,UAAA;AAAA,OAC3B;AAAA,MACA,MAAM,IAAK,CAAA;AAAA,QACT,MAAA;AAAA,QACA,MAAA;AAAA,QACA,SAAA;AAAA,QACA,QAAA;AAAA,QACA,YAAA;AAAA,QACA,UAAA;AAAA,OACC,EAAA;AACD,QAAW,UAAA,CAAA,GAAA;AAAA,UACT,MAAM,YAAa,CAAA;AAAA,YACjB,MAAA,EAAQC,oCAAsB,MAAM,CAAA;AAAA,YACpC,MAAA;AAAA,YACA,SAAA;AAAA,YACA,QAAA;AAAA,YACA,YAAA;AAAA,WACD,CAAA;AAAA,SACH,CAAA;AAAA,OACF;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AACF,CAAC;;;;;"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/config.ts","../src/filters.ts","../src/api.ts","../src/service/service.ts","../src/lib.ts","../src/service/router.ts","../src/plugin.ts"],"sourcesContent":["import { Config } from '@backstage/config';\n\nconst JIRA_BASE_URL_CONFIG_PATH = 'jiraDashboard.baseUrl';\nconst JIRA_TOKEN_CONFIG_PATH = 'jiraDashboard.token';\nconst JIRA_USER_CONFIG_EMAIL_SUFFIX = 'jiraDashboard.userEmailSuffix';\nconst JIRA_ANNOTATION = 'jiraDashboard.annotationPrefix';\n\nexport function resolveJiraBaseUrl(config: Config): string {\n try {\n return config.getString(JIRA_BASE_URL_CONFIG_PATH);\n } catch (error) {\n throw new Error(`Invalid Jira baseUrl, ${error}`);\n }\n}\n\nexport function resolveJiraToken(config: Config): string {\n try {\n return config.getString(JIRA_TOKEN_CONFIG_PATH);\n } catch (error) {\n throw new Error(`Invalid Jira token, ${error}`);\n }\n}\n\nexport function resolveUserEmailSuffix(config: Config): string {\n return config.getOptionalString(JIRA_USER_CONFIG_EMAIL_SUFFIX) || '';\n}\n\nexport function resolveAnnotationPrefix(config: Config): string {\n const annotationPrefix = config.getOptionalString(JIRA_ANNOTATION);\n return annotationPrefix ?? 'jira.com';\n}\n","import { Config } from '@backstage/config';\nimport { resolveUserEmailSuffix } from './config';\nimport { Filter } from '@axis-backstage/plugin-jira-dashboard-common';\n\nconst getUsernameFromRef = (userRef: string) => {\n return userRef?.split('/').slice(1)[0];\n};\n\nconst openFilter: Filter = {\n name: 'Open Issues',\n shortName: 'OPEN',\n query: 'resolution = Unresolved ORDER BY updated DESC',\n};\n\nconst incomingFilter: Filter = {\n name: 'Incoming Issues',\n shortName: 'INCOMING',\n query: 'status = New ORDER BY created ASC',\n};\n\nexport const getDefaultFilters = (\n config: Config,\n userRef?: string,\n): Filter[] => {\n if (!userRef) {\n return [openFilter, incomingFilter];\n }\n const username = getUsernameFromRef(userRef);\n\n if (!username) {\n return [openFilter, incomingFilter];\n }\n\n const assignedToMeFilter: Filter = {\n name: 'Assigned to me',\n shortName: 'ME',\n query: `assignee = \"${username}${resolveUserEmailSuffix(\n config,\n )}\" AND resolution = Unresolved ORDER BY updated DESC`,\n };\n\n return [openFilter, incomingFilter, assignedToMeFilter];\n};\n","import { Config } from '@backstage/config';\nimport fetch from 'node-fetch';\nimport {\n Filter,\n Issue,\n Project,\n} from '@axis-backstage/plugin-jira-dashboard-common';\nimport { resolveJiraBaseUrl, resolveJiraToken } from './config';\n\nexport const getProjectInfo = async (\n projectKey: string,\n config: Config,\n): Promise<Project> => {\n const response = await fetch(\n `${resolveJiraBaseUrl(config)}project/${projectKey}`,\n {\n method: 'GET',\n headers: {\n Authorization: resolveJiraToken(config),\n Accept: 'application/json',\n },\n },\n );\n if (response.status !== 200) {\n throw Error(`${response.status}`);\n }\n return response.json();\n};\n\nexport const getFilterById = async (\n id: string,\n config: Config,\n): Promise<Filter> => {\n const response = await fetch(`${resolveJiraBaseUrl(config)}filter/${id}`, {\n method: 'GET',\n headers: {\n Authorization: resolveJiraToken(config),\n Accept: 'application/json',\n },\n });\n if (response.status !== 200) {\n throw Error(`${response.status}`);\n }\n const jsonResponse = await response.json();\n return { name: jsonResponse.name, query: jsonResponse.jql } as Filter;\n};\n\nexport const getIssuesByFilter = async (\n projectKey: string,\n query: string,\n config: Config,\n): Promise<Issue[]> => {\n const response = await fetch(\n `${resolveJiraBaseUrl(\n config,\n )}search?jql=project=${projectKey} AND ${query}`,\n {\n method: 'GET',\n headers: {\n Authorization: resolveJiraToken(config),\n Accept: 'application/json',\n },\n },\n ).then(resp => resp.json());\n return response.issues;\n};\n\nexport const getIssuesByComponent = async (\n projectKey: string,\n componentKey: string,\n config: Config,\n): Promise<Issue[]> => {\n const response = await fetch(\n `${resolveJiraBaseUrl(\n config,\n )}search?jql=project=${projectKey} AND component = \"${componentKey}\"`,\n {\n method: 'GET',\n headers: {\n Authorization: resolveJiraToken(config),\n Accept: 'application/json',\n },\n },\n ).then(resp => resp.json());\n return response.issues;\n};\n\nexport async function getProjectAvatar(url: string, config: Config) {\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n Authorization: resolveJiraToken(config),\n },\n });\n return response;\n}\n","import { CacheClient } from '@backstage/backend-common';\nimport { Config } from '@backstage/config';\nimport {\n type Filter,\n type JiraDataResponse,\n type Project,\n} from '@axis-backstage/plugin-jira-dashboard-common';\nimport {\n getFilterById,\n getIssuesByComponent,\n getIssuesByFilter,\n getProjectInfo,\n} from '../api';\n\nexport const getProjectResponse = async (\n projectKey: string,\n config: Config,\n cache: CacheClient,\n): Promise<Project> => {\n let projectResponse: Project;\n\n projectResponse = (await cache.get(projectKey)) as Project;\n\n if (projectResponse) return projectResponse as Project;\n\n try {\n projectResponse = await getProjectInfo(projectKey, config);\n cache.set(projectKey, projectResponse);\n } catch (err: any) {\n if (err.message !== 200) {\n throw Error(`${err.status}`);\n }\n }\n return projectResponse;\n};\n\nexport const getFiltersFromAnnotations = async (\n annotations: string[],\n config: Config,\n): Promise<Filter[]> => {\n const filters: Filter[] = [];\n\n for (const filter of annotations) {\n try {\n const response = await getFilterById(filter, config);\n filters.push(response);\n } catch (err: any) {\n console.warn(\n `${err.message} : Could not find filter with filter id ${filter}`,\n );\n }\n }\n return filters;\n};\n\nexport const getIssuesFromFilters = async (\n projectKey: string,\n filters: Filter[],\n config: Config,\n): Promise<JiraDataResponse[]> => {\n return await Promise.all(\n filters.map(async filter => ({\n name: filter.name,\n type: 'filter',\n issues: await getIssuesByFilter(projectKey, filter.query, config),\n })),\n );\n};\n\nexport const getIssuesFromComponents = async (\n projectKey: string,\n componentAnnotations: string[],\n config: Config,\n): Promise<JiraDataResponse[]> => {\n return await Promise.all(\n componentAnnotations.map(async componentKey => ({\n name: componentKey,\n type: 'component',\n issues: await getIssuesByComponent(projectKey, componentKey, config),\n })),\n );\n};\n","import { resolveAnnotationPrefix } from './config';\nimport {\n COMPONENTS_NAME,\n PROJECT_KEY_NAME,\n FILTERS_NAME,\n} from '@axis-backstage/plugin-jira-dashboard-common';\nimport { Config } from '@backstage/config';\n\nexport const getAnnotations = (config: Config) => {\n const prefix = resolveAnnotationPrefix(config);\n\n const projectKeyAnnotation = `${prefix}/${PROJECT_KEY_NAME}`;\n const componentsAnnotation = `${prefix}/${COMPONENTS_NAME}`;\n const filtersAnnotation = `${prefix}/${FILTERS_NAME}`;\n\n /* Adding support for Roadie's component annotation */\n const componentRoadieAnnotation = `${prefix}/component`;\n\n return {\n projectKeyAnnotation,\n componentsAnnotation,\n componentRoadieAnnotation,\n filtersAnnotation,\n };\n};\n","import {\n CacheManager,\n TokenManager,\n errorHandler,\n} from '@backstage/backend-common';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { Config } from '@backstage/config';\nimport { Logger } from 'winston';\nimport { CatalogClient } from '@backstage/catalog-client';\nimport { DiscoveryApi } from '@backstage/plugin-permission-common';\nimport { IdentityApi } from '@backstage/plugin-auth-node';\n\nimport { getDefaultFilters } from '../filters';\nimport {\n type Filter,\n type JiraResponse,\n type Project,\n} from '@axis-backstage/plugin-jira-dashboard-common';\nimport stream from 'stream';\nimport { getProjectAvatar } from '../api';\nimport {\n getProjectResponse,\n getFiltersFromAnnotations,\n getIssuesFromFilters,\n getIssuesFromComponents,\n} from './service';\nimport { getAnnotations } from '../lib';\n\n/**\n * Constructs a jira dashboard router.\n * @public\n */\nexport interface RouterOptions {\n /**\n * Implementation of Winston logger\n */\n logger: Logger;\n\n /**\n * Backstage config object\n */\n config: Config;\n\n /**\n * Backstage discovery api instance\n */\n discovery: DiscoveryApi;\n\n /**\n * Backstage identity api instance\n */\n identity: IdentityApi;\n\n /**\n * Backstage token manager instance\n */\n tokenManager: TokenManager;\n}\n\nconst DEFAULT_TTL = 1000 * 60;\n\n/**\n * Constructs a jira dashboard router.\n *\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { logger, config, discovery, identity, tokenManager } = options;\n const catalogClient = new CatalogClient({ discoveryApi: discovery });\n logger.info('Initializing Jira Dashboard backend');\n\n const pluginCache =\n CacheManager.fromConfig(config).forPlugin('jira-dashboard');\n const cache = pluginCache.getClient({ defaultTtl: DEFAULT_TTL });\n\n const router = Router();\n router.use(express.json());\n\n router.get('/health', (_, response) => {\n response.json({ status: 'ok' });\n });\n\n router.get(\n '/dashboards/by-entity-ref/:kind/:namespace/:name',\n async (request, response) => {\n const { kind, namespace, name } = request.params;\n const entityRef = stringifyEntityRef({ kind, namespace, name });\n const { token } = await tokenManager.getToken();\n const entity = await catalogClient.getEntityByRef(entityRef, { token });\n const {\n projectKeyAnnotation,\n componentsAnnotation,\n componentRoadieAnnotation,\n filtersAnnotation,\n } = getAnnotations(config);\n\n if (!entity) {\n logger.info(`No entity found for ${entityRef}`);\n response\n .status(500)\n .json({ error: `No entity found for ${entityRef}` });\n return;\n }\n\n const projectKey =\n entity.metadata.annotations?.[projectKeyAnnotation]?.split(',')!;\n\n if (!projectKey) {\n const error = `No jira.com/project-key annotation found for ${entityRef}`;\n logger.info(error);\n response.status(404).json(error);\n return;\n }\n\n let projectResponse;\n\n try {\n projectResponse = await getProjectResponse(\n projectKey[0],\n config,\n cache,\n );\n } catch (err) {\n logger.error(`Could not find Jira project ${projectKey[0]}`);\n response.status(404).json({\n error: `No Jira project found with key ${projectKey[0]}`,\n });\n return;\n }\n\n const userIdentity = await identity.getIdentity({ request: request });\n\n if (!userIdentity) {\n logger.warn(`Could not find user identity`);\n }\n\n let filters: Filter[] = [];\n\n const customFilterAnnotations =\n entity.metadata.annotations?.[filtersAnnotation]?.split(',')!;\n\n filters = getDefaultFilters(\n config,\n userIdentity?.identity?.userEntityRef,\n );\n\n if (customFilterAnnotations) {\n filters.push(\n ...(await getFiltersFromAnnotations(customFilterAnnotations, config)),\n );\n }\n\n let issues = await getIssuesFromFilters(projectKey[0], filters, config);\n\n let components =\n entity.metadata.annotations?.[componentsAnnotation]?.split(',') ?? [];\n\n /* Adding support for Roadie's component annotation */\n components = components.concat(\n entity.metadata.annotations?.[componentRoadieAnnotation]?.split(',') ??\n [],\n );\n\n if (components) {\n const componentIssues = await getIssuesFromComponents(\n projectKey[0],\n components,\n config,\n );\n issues = issues.concat(componentIssues);\n }\n\n const jiraResponse: JiraResponse = {\n project: projectResponse as Project,\n data: issues,\n };\n response.json(jiraResponse);\n },\n );\n\n router.get(\n '/avatar/by-entity-ref/:kind/:namespace/:name',\n async (request, response) => {\n const { kind, namespace, name } = request.params;\n const entityRef = stringifyEntityRef({ kind, namespace, name });\n const { token } = await tokenManager.getToken();\n const entity = await catalogClient.getEntityByRef(entityRef, { token });\n const { projectKeyAnnotation } = getAnnotations(config);\n\n if (!entity) {\n logger.info(`No entity found for ${entityRef}`);\n response\n .status(500)\n .json({ error: `No entity found for ${entityRef}` });\n return;\n }\n\n const projectKey =\n entity.metadata.annotations?.[projectKeyAnnotation]?.split(',')!;\n\n const projectResponse = await getProjectResponse(\n projectKey[0],\n config,\n cache,\n );\n\n if (!projectResponse) {\n logger.error('Could not find project in Jira');\n response.status(400).json({\n error: `No Jira project found for project key ${projectKey[0]}`,\n });\n return;\n }\n\n const url = projectResponse.avatarUrls['48x48'];\n\n const avatar = await getProjectAvatar(url, config);\n\n const ps = new stream.PassThrough();\n const val = avatar.headers.get('content-type');\n\n response.setHeader('content-type', val ?? '');\n stream.pipeline(avatar.body, ps, err => {\n if (err) {\n logger.error(err);\n response.sendStatus(400);\n }\n return;\n });\n ps.pipe(response);\n },\n );\n router.use(errorHandler());\n return router;\n}\n","import { loggerToWinstonLogger } from '@backstage/backend-common';\nimport {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\n\n/**\n * The Jira Dashboard backend plugin.\n *\n * @public\n */\nexport const jiraDashboardPlugin = createBackendPlugin({\n pluginId: 'jira-dashboard',\n register(env) {\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n discovery: coreServices.discovery,\n identity: coreServices.identity,\n tokenManager: coreServices.tokenManager,\n httpRouter: coreServices.httpRouter,\n },\n async init({\n logger,\n config,\n discovery,\n identity,\n tokenManager,\n httpRouter,\n }) {\n httpRouter.use(\n await createRouter({\n logger: loggerToWinstonLogger(logger),\n config,\n discovery,\n identity,\n tokenManager,\n }),\n );\n },\n });\n },\n});\n"],"names":["fetch","PROJECT_KEY_NAME","COMPONENTS_NAME","FILTERS_NAME","catalogClient","CatalogClient","CacheManager","Router","express","stringifyEntityRef","stream","errorHandler","createBackendPlugin","coreServices","loggerToWinstonLogger"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axis-backstage/plugin-jira-dashboard-backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"main": "dist/index.cjs.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -22,10 +22,11 @@
|
|
|
22
22
|
"postpack": "backstage-cli package postpack"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@axis-backstage/plugin-jira-dashboard-common": "
|
|
25
|
+
"@axis-backstage/plugin-jira-dashboard-common": "workspace:^",
|
|
26
26
|
"@backstage/backend-common": "^0.20.1",
|
|
27
27
|
"@backstage/backend-plugin-api": "^0.6.9",
|
|
28
28
|
"@backstage/catalog-client": "^1.5.2",
|
|
29
|
+
"@backstage/catalog-model": "^1.4.3",
|
|
29
30
|
"@backstage/config": "^1.1.1",
|
|
30
31
|
"@backstage/plugin-auth-node": "^0.4.3",
|
|
31
32
|
"@backstage/plugin-permission-common": "^0.7.12",
|
|
@@ -47,4 +48,4 @@
|
|
|
47
48
|
"config.d.ts"
|
|
48
49
|
],
|
|
49
50
|
"configSchema": "config.d.ts"
|
|
50
|
-
}
|
|
51
|
+
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# @axis-backstage/plugin-jira-dashboard-backend
|
|
2
|
-
|
|
3
|
-
## 0.5.0
|
|
4
|
-
|
|
5
|
-
### Minor Changes
|
|
6
|
-
|
|
7
|
-
- 97f5bf4: Created optional ANNOTATION_PREFIX config in backend to make it possible to define custom annotations. The jira.com annotation is still used if no config value is provided. Also removed check for annotation in frontend and only return error message 'Could not fetch Jira Dashboard content for defined project key' if no Jira data is returned from backend.
|
|
8
|
-
|
|
9
|
-
### Patch Changes
|
|
10
|
-
|
|
11
|
-
- Updated dependencies [97f5bf4]
|
|
12
|
-
- @axis-backstage/plugin-jira-dashboard-common@0.4.0
|
|
13
|
-
|
|
14
|
-
## 0.4.0
|
|
15
|
-
|
|
16
|
-
### Minor Changes
|
|
17
|
-
|
|
18
|
-
- 864d983: Bumped Backstage version to v.1.22.0
|
|
19
|
-
|
|
20
|
-
### Patch Changes
|
|
21
|
-
|
|
22
|
-
- 1248d02: Removed the single quotes from documentation config strings
|
|
23
|
-
- Updated dependencies [864d983]
|
|
24
|
-
- @axis-backstage/plugin-jira-dashboard-common@0.3.0
|
|
25
|
-
|
|
26
|
-
## 0.3.0
|
|
27
|
-
|
|
28
|
-
### Minor Changes
|
|
29
|
-
|
|
30
|
-
- 23ff76a: Bumped Backstage version to v.1.21.0 in whole monorepo
|
|
31
|
-
|
|
32
|
-
### Patch Changes
|
|
33
|
-
|
|
34
|
-
- Updated dependencies [23ff76a]
|
|
35
|
-
- @axis-backstage/plugin-jira-dashboard-common@0.2.0
|
|
36
|
-
|
|
37
|
-
## 0.2.0
|
|
38
|
-
|
|
39
|
-
### Minor Changes
|
|
40
|
-
|
|
41
|
-
- a67c963: Bumped Backstage to version 1.20.3
|
|
42
|
-
|
|
43
|
-
### Patch Changes
|
|
44
|
-
|
|
45
|
-
- 1e7ee53: Added missing config.d.ts file to package.json
|
|
46
|
-
- Updated dependencies [9cf5ab1]
|
|
47
|
-
- @axis-backstage/plugin-jira-dashboard-common@0.1.1
|