@axis-backstage/plugin-jira-dashboard-backend 6.1.5 → 6.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @axis-backstage/plugin-jira-dashboard-backend
2
2
 
3
+ ## 6.1.6
4
+
5
+ ### Patch Changes
6
+
7
+ - 7d575b9: Fix URL encoding of JQL query parameters containing URL-reserved characters.
8
+ - b59789b: Use native fetch instead of "node-fetch".
9
+ - 6a30651: Updated to Backstage 1.54.6
10
+ - Updated dependencies [6a30651]
11
+ - @axis-backstage/plugin-jira-dashboard-common@1.15.4
12
+
3
13
  ## 6.1.5
4
14
 
5
15
  ### Patch Changes
package/dist/api.cjs.js CHANGED
@@ -1,14 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var fetch = require('node-fetch');
4
3
  var queries = require('./queries.cjs.js');
5
4
  var lib = require('./lib.cjs.js');
6
5
  var errors = require('@backstage/errors');
7
6
 
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
7
  const getProjectInfo = async (project) => {
13
8
  const { projectKey, instance } = project;
14
9
  const response = await callApi(
@@ -52,13 +47,15 @@ const getQueryUrl = (instance, jql) => {
52
47
  if (instance.useApiV3) {
53
48
  const baseUrlWithEndpoint2 = `${baseUrl}search/jql`;
54
49
  if (jql) {
55
- return `${baseUrlWithEndpoint2}?jql=${jql}&fields=*all`;
50
+ return `${baseUrlWithEndpoint2}?jql=${encodeURIComponent(
51
+ jql
52
+ )}&fields=*all`;
56
53
  }
57
54
  return baseUrlWithEndpoint2;
58
55
  }
59
56
  const baseUrlWithEndpoint = `${baseUrl}search`;
60
57
  if (jql) {
61
- return `${baseUrlWithEndpoint}?jql=${jql}`;
58
+ return `${baseUrlWithEndpoint}?jql=${encodeURIComponent(jql)}`;
62
59
  }
63
60
  return baseUrlWithEndpoint;
64
61
  };
@@ -164,7 +161,7 @@ async function callApi(instance, url, init) {
164
161
  Authorization: instance.token,
165
162
  ...requestInit.headers
166
163
  };
167
- return fetch__default.default(url, requestInit);
164
+ return fetch(url, requestInit);
168
165
  }
169
166
 
170
167
  exports.callApi = callApi;
@@ -1 +1 @@
1
- {"version":3,"file":"api.cjs.js","sources":["../src/api.ts"],"sourcesContent":["import fetch, { RequestInit } from 'node-fetch';\nimport {\n Filter,\n Issue,\n Project,\n JiraQueryResults,\n} from '@axis-backstage/plugin-jira-dashboard-common';\n\nimport type { ConfigInstance } from './config';\nimport { jqlQueryBuilder } from './queries';\nimport type { JiraProject } from './lib';\nimport { getApiUrl, replaceProjectApiUrl, replaceIssuesApiUrl } from './lib';\nimport { ResponseError } from '@backstage/errors';\n\nexport const getProjectInfo = async (\n project: JiraProject,\n): Promise<Project> => {\n const { projectKey, instance } = project;\n const response = await callApi(\n instance,\n `${getApiUrl(instance)}project/${projectKey}`,\n {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n },\n );\n if (response.status !== 200) {\n throw Error(\n `Request failed with status code ${response.status}: ${response.statusText}`,\n );\n }\n\n const projectResponse = await response.json();\n replaceProjectApiUrl(project.instance, projectResponse);\n return projectResponse;\n};\n\nexport const getFilterById = async (\n id: string,\n instance: ConfigInstance,\n): Promise<Filter> => {\n const response = await callApi(\n instance,\n `${getApiUrl(instance)}filter/${id}`,\n {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\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 getQueryUrl = (instance: ConfigInstance, jql?: string): string => {\n const baseUrl = getApiUrl(instance);\n\n if (instance.useApiV3) {\n const baseUrlWithEndpoint = `${baseUrl}search/jql`;\n if (jql) {\n return `${baseUrlWithEndpoint}?jql=${jql}&fields=*all`;\n }\n return baseUrlWithEndpoint;\n }\n\n const baseUrlWithEndpoint = `${baseUrl}search`;\n if (jql) {\n return `${baseUrlWithEndpoint}?jql=${jql}`;\n }\n return baseUrlWithEndpoint;\n};\n\nexport const getIssuesByFilter = async (\n projects: JiraProject[],\n components: string[],\n query: string,\n): Promise<Issue[]> => {\n if (projects.length === 0) {\n return [];\n }\n\n // All projects are expected to share the same instance — callers (getJiraProjectsFromKeys)\n // stamp every project with the same ConfigInstance, so a single batched JQL query suffices.\n const { instance } = projects[0];\n const projectKeys = projects.map(p => p.projectKey);\n const jql = jqlQueryBuilder({ project: projectKeys, components, query });\n const queryUrl = getQueryUrl(instance, jql);\n\n const response = await callApi(instance, queryUrl, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n })\n .then(resp => resp.json())\n .catch(() => null);\n\n if (response?.errorMessages) {\n throw Error(\n `JQL returned Error: JQL - ${jql} with error: ${response?.errorMessages?.[0]}`,\n );\n }\n\n if (response?.issues) {\n replaceIssuesApiUrl(instance, response.issues);\n return response.issues;\n }\n\n return [];\n};\n\n/**\n * Options available for the Jira JQL query.\n *\n * @public\n */\nexport type SearchOptions = {\n expand?: string[];\n fields?: string[];\n fieldsByKey?: boolean;\n properties?: string[];\n startAt?: number;\n maxResults?: number;\n validateQuery?: string;\n};\n\n/**\n * Asynchronously searches for Jira issues using JQL.\n *\n * For more information about the available options, see the API documentation at:\n * https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-search/#api-rest-api-2-search-post\n *\n * @param config - A Backstage config\n * @param jqlQuery - A string containing the jql query.\n * @param options - Query options that will be passed on to the POST request.\n * @public\n */\nexport const searchJira = async (\n instance: ConfigInstance,\n jqlQuery: string,\n options: SearchOptions,\n): Promise<JiraQueryResults> => {\n const queryUrl = getQueryUrl(instance);\n const requestBody = { jql: jqlQuery, ...options };\n\n const response = await callApi(instance, queryUrl, {\n method: 'POST',\n body: JSON.stringify(requestBody),\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n });\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n const jsonResponse = (await response.json()) as JiraQueryResults;\n replaceIssuesApiUrl(instance, jsonResponse.issues);\n return jsonResponse;\n};\n\nexport const getIssuesByComponent = async (\n projects: JiraProject[],\n componentKeys: string,\n query?: string,\n): Promise<Issue[]> => {\n // Return an empty array if no projects are provided\n if (projects.length === 0) {\n return [];\n }\n\n const projectKeys = projects.map(project => project.projectKey);\n const components = componentKeys\n .split(',')\n .map(component => component.trim());\n\n const jql = jqlQueryBuilder({\n project: projectKeys,\n components,\n query,\n });\n\n const { instance } = projects[0];\n\n try {\n const queryUrl = getQueryUrl(instance, jql);\n const response = await callApi(instance, queryUrl, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n }).then(resp => resp.json());\n\n if (!response.issues || response.issues.length === 0) {\n return [];\n }\n\n replaceIssuesApiUrl(instance, response.issues);\n return response.issues;\n } catch (error: any) {\n if (error.message.includes(\"does not exist for the field 'project'\")) {\n return [];\n }\n throw error;\n }\n};\nexport async function getProjectAvatar(url: string, instance: ConfigInstance) {\n return callApi(instance, url);\n}\n\n/**\n * Get a single Jira issue by its key or ID.\n *\n * @param issueKey - The issue key (e.g., \"PROJ-123\") or ID\n * @param instance - The Jira instance configuration\n * @returns The Jira issue\n * @public\n */\nexport const getIssueByKey = async (\n issueKey: string,\n instance: ConfigInstance,\n): Promise<Issue> => {\n const response = await callApi(\n instance,\n `${getApiUrl(instance)}issue/${issueKey}?fields=summary,description`,\n {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n },\n );\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const issue = (await response.json()) as Issue;\n return issue;\n};\n\n/**\n * Call the Jira API using fetch.\n *\n * This function injects the auth token and custom headers.\n *\n * @public\n */\nexport async function callApi(\n instance: ConfigInstance,\n url: string,\n init?: RequestInit,\n) {\n const requestInit = init ?? { method: 'GET' };\n\n // Inject custom headers from config, Authorization token and headers from the\n // request\n requestInit.headers = {\n ...instance.headers,\n Authorization: instance.token,\n ...requestInit.headers,\n };\n return fetch(url, requestInit);\n}\n"],"names":["getApiUrl","replaceProjectApiUrl","baseUrlWithEndpoint","jqlQueryBuilder","replaceIssuesApiUrl","ResponseError","fetch"],"mappings":"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"}
1
+ {"version":3,"file":"api.cjs.js","sources":["../src/api.ts"],"sourcesContent":["import {\n Filter,\n Issue,\n Project,\n JiraQueryResults,\n} from '@axis-backstage/plugin-jira-dashboard-common';\n\nimport type { ConfigInstance } from './config';\nimport { jqlQueryBuilder } from './queries';\nimport type { JiraProject } from './lib';\nimport { getApiUrl, replaceProjectApiUrl, replaceIssuesApiUrl } from './lib';\nimport { ResponseError } from '@backstage/errors';\n\nexport const getProjectInfo = async (\n project: JiraProject,\n): Promise<Project> => {\n const { projectKey, instance } = project;\n const response = await callApi(\n instance,\n `${getApiUrl(instance)}project/${projectKey}`,\n {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n },\n );\n if (response.status !== 200) {\n throw Error(\n `Request failed with status code ${response.status}: ${response.statusText}`,\n );\n }\n\n const projectResponse = await response.json();\n replaceProjectApiUrl(project.instance, projectResponse);\n return projectResponse;\n};\n\nexport const getFilterById = async (\n id: string,\n instance: ConfigInstance,\n): Promise<Filter> => {\n const response = await callApi(\n instance,\n `${getApiUrl(instance)}filter/${id}`,\n {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\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 getQueryUrl = (instance: ConfigInstance, jql?: string): string => {\n const baseUrl = getApiUrl(instance);\n\n if (instance.useApiV3) {\n const baseUrlWithEndpoint = `${baseUrl}search/jql`;\n if (jql) {\n return `${baseUrlWithEndpoint}?jql=${encodeURIComponent(\n jql,\n )}&fields=*all`;\n }\n return baseUrlWithEndpoint;\n }\n\n const baseUrlWithEndpoint = `${baseUrl}search`;\n if (jql) {\n return `${baseUrlWithEndpoint}?jql=${encodeURIComponent(jql)}`;\n }\n return baseUrlWithEndpoint;\n};\n\nexport const getIssuesByFilter = async (\n projects: JiraProject[],\n components: string[],\n query: string,\n): Promise<Issue[]> => {\n if (projects.length === 0) {\n return [];\n }\n\n // All projects are expected to share the same instance — callers (getJiraProjectsFromKeys)\n // stamp every project with the same ConfigInstance, so a single batched JQL query suffices.\n const { instance } = projects[0];\n const projectKeys = projects.map(p => p.projectKey);\n const jql = jqlQueryBuilder({ project: projectKeys, components, query });\n const queryUrl = getQueryUrl(instance, jql);\n\n const response = await callApi(instance, queryUrl, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n })\n .then(resp => resp.json())\n .catch(() => null);\n\n if (response?.errorMessages) {\n throw Error(\n `JQL returned Error: JQL - ${jql} with error: ${response?.errorMessages?.[0]}`,\n );\n }\n\n if (response?.issues) {\n replaceIssuesApiUrl(instance, response.issues);\n return response.issues;\n }\n\n return [];\n};\n\n/**\n * Options available for the Jira JQL query.\n *\n * @public\n */\nexport type SearchOptions = {\n expand?: string[];\n fields?: string[];\n fieldsByKey?: boolean;\n properties?: string[];\n startAt?: number;\n maxResults?: number;\n validateQuery?: string;\n};\n\n/**\n * Asynchronously searches for Jira issues using JQL.\n *\n * For more information about the available options, see the API documentation at:\n * https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-search/#api-rest-api-2-search-post\n *\n * @param config - A Backstage config\n * @param jqlQuery - A string containing the jql query.\n * @param options - Query options that will be passed on to the POST request.\n * @public\n */\nexport const searchJira = async (\n instance: ConfigInstance,\n jqlQuery: string,\n options: SearchOptions,\n): Promise<JiraQueryResults> => {\n const queryUrl = getQueryUrl(instance);\n const requestBody = { jql: jqlQuery, ...options };\n\n const response = await callApi(instance, queryUrl, {\n method: 'POST',\n body: JSON.stringify(requestBody),\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n });\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n const jsonResponse = (await response.json()) as JiraQueryResults;\n replaceIssuesApiUrl(instance, jsonResponse.issues);\n return jsonResponse;\n};\n\nexport const getIssuesByComponent = async (\n projects: JiraProject[],\n componentKeys: string,\n query?: string,\n): Promise<Issue[]> => {\n // Return an empty array if no projects are provided\n if (projects.length === 0) {\n return [];\n }\n\n const projectKeys = projects.map(project => project.projectKey);\n const components = componentKeys\n .split(',')\n .map(component => component.trim());\n\n const jql = jqlQueryBuilder({\n project: projectKeys,\n components,\n query,\n });\n\n const { instance } = projects[0];\n\n try {\n const queryUrl = getQueryUrl(instance, jql);\n const response = await callApi(instance, queryUrl, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n }).then(resp => resp.json());\n\n if (!response.issues || response.issues.length === 0) {\n return [];\n }\n\n replaceIssuesApiUrl(instance, response.issues);\n return response.issues;\n } catch (error: any) {\n if (error.message.includes(\"does not exist for the field 'project'\")) {\n return [];\n }\n throw error;\n }\n};\nexport async function getProjectAvatar(url: string, instance: ConfigInstance) {\n return callApi(instance, url);\n}\n\n/**\n * Get a single Jira issue by its key or ID.\n *\n * @param issueKey - The issue key (e.g., \"PROJ-123\") or ID\n * @param instance - The Jira instance configuration\n * @returns The Jira issue\n * @public\n */\nexport const getIssueByKey = async (\n issueKey: string,\n instance: ConfigInstance,\n): Promise<Issue> => {\n const response = await callApi(\n instance,\n `${getApiUrl(instance)}issue/${issueKey}?fields=summary,description`,\n {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n },\n );\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const issue = (await response.json()) as Issue;\n return issue;\n};\n\n/**\n * Call the Jira API using fetch.\n *\n * This function injects the auth token and custom headers.\n *\n * @public\n */\nexport async function callApi(\n instance: ConfigInstance,\n url: string,\n init?: RequestInit,\n) {\n const requestInit = init ?? { method: 'GET' };\n\n // Inject custom headers from config, Authorization token and headers from the\n // request\n requestInit.headers = {\n ...instance.headers,\n Authorization: instance.token,\n ...requestInit.headers,\n };\n return fetch(url, requestInit);\n}\n"],"names":["getApiUrl","replaceProjectApiUrl","baseUrlWithEndpoint","jqlQueryBuilder","replaceIssuesApiUrl","ResponseError"],"mappings":";;;;;;AAaO,MAAM,cAAA,GAAiB,OAC5B,OAAA,KACqB;AACrB,EAAA,MAAM,EAAE,UAAA,EAAY,QAAA,EAAS,GAAI,OAAA;AACjC,EAAA,MAAM,WAAW,MAAM,OAAA;AAAA,IACrB,QAAA;AAAA,IACA,CAAA,EAAGA,aAAA,CAAU,QAAQ,CAAC,WAAW,UAAU,CAAA,CAAA;AAAA,IAC3C;AAAA,MACE,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,MAAA,EAAQ;AAAA;AACV;AACF,GACF;AACA,EAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,IAAA,MAAM,KAAA;AAAA,MACJ,CAAA,gCAAA,EAAmC,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA;AAAA,KAC5E;AAAA,EACF;AAEA,EAAA,MAAM,eAAA,GAAkB,MAAM,QAAA,CAAS,IAAA,EAAK;AAC5C,EAAAC,wBAAA,CAAqB,OAAA,CAAQ,UAAU,eAAe,CAAA;AACtD,EAAA,OAAO,eAAA;AACT;AAEO,MAAM,aAAA,GAAgB,OAC3B,EAAA,EACA,QAAA,KACoB;AACpB,EAAA,MAAM,WAAW,MAAM,OAAA;AAAA,IACrB,QAAA;AAAA,IACA,CAAA,EAAGD,aAAA,CAAU,QAAQ,CAAC,UAAU,EAAE,CAAA,CAAA;AAAA,IAClC;AAAA,MACE,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,MAAA,EAAQ;AAAA;AACV;AACF,GACF;AACA,EAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,IAAA,MAAM,KAAA,CAAM,CAAA,EAAG,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,EAClC;AACA,EAAA,MAAM,YAAA,GAAe,MAAM,QAAA,CAAS,IAAA,EAAK;AACzC,EAAA,OAAO,EAAE,IAAA,EAAM,YAAA,CAAa,IAAA,EAAM,KAAA,EAAO,aAAa,GAAA,EAAI;AAC5D;AAEO,MAAM,WAAA,GAAc,CAAC,QAAA,EAA0B,GAAA,KAAyB;AAC7E,EAAA,MAAM,OAAA,GAAUA,cAAU,QAAQ,CAAA;AAElC,EAAA,IAAI,SAAS,QAAA,EAAU;AACrB,IAAA,MAAME,oBAAAA,GAAsB,GAAG,OAAO,CAAA,UAAA,CAAA;AACtC,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,OAAO,CAAA,EAAGA,oBAAmB,CAAA,KAAA,EAAQ,kBAAA;AAAA,QACnC;AAAA,OACD,CAAA,YAAA,CAAA;AAAA,IACH;AACA,IAAA,OAAOA,oBAAAA;AAAA,EACT;AAEA,EAAA,MAAM,mBAAA,GAAsB,GAAG,OAAO,CAAA,MAAA,CAAA;AACtC,EAAA,IAAI,GAAA,EAAK;AACP,IAAA,OAAO,CAAA,EAAG,mBAAmB,CAAA,KAAA,EAAQ,kBAAA,CAAmB,GAAG,CAAC,CAAA,CAAA;AAAA,EAC9D;AACA,EAAA,OAAO,mBAAA;AACT;AAEO,MAAM,iBAAA,GAAoB,OAC/B,QAAA,EACA,UAAA,EACA,KAAA,KACqB;AACrB,EAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,IAAA,OAAO,EAAC;AAAA,EACV;AAIA,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,QAAA,CAAS,CAAC,CAAA;AAC/B,EAAA,MAAM,WAAA,GAAc,QAAA,CAAS,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,UAAU,CAAA;AAClD,EAAA,MAAM,MAAMC,uBAAA,CAAgB,EAAE,SAAS,WAAA,EAAa,UAAA,EAAY,OAAO,CAAA;AACvE,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,QAAA,EAAU,GAAG,CAAA;AAE1C,EAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,QAAA,EAAU,QAAA,EAAU;AAAA,IACjD,MAAA,EAAQ,KAAA;AAAA,IACR,OAAA,EAAS;AAAA,MACP,MAAA,EAAQ;AAAA;AACV,GACD,CAAA,CACE,IAAA,CAAK,CAAA,IAAA,KAAQ,IAAA,CAAK,MAAM,CAAA,CACxB,KAAA,CAAM,MAAM,IAAI,CAAA;AAEnB,EAAA,IAAI,UAAU,aAAA,EAAe;AAC3B,IAAA,MAAM,KAAA;AAAA,MACJ,8BAA8B,GAAG,CAAA,aAAA,EAAgB,QAAA,EAAU,aAAA,GAAgB,CAAC,CAAC,CAAA;AAAA,KAC/E;AAAA,EACF;AAEA,EAAA,IAAI,UAAU,MAAA,EAAQ;AACpB,IAAAC,uBAAA,CAAoB,QAAA,EAAU,SAAS,MAAM,CAAA;AAC7C,IAAA,OAAO,QAAA,CAAS,MAAA;AAAA,EAClB;AAEA,EAAA,OAAO,EAAC;AACV;AA4BO,MAAM,UAAA,GAAa,OACxB,QAAA,EACA,QAAA,EACA,OAAA,KAC8B;AAC9B,EAAA,MAAM,QAAA,GAAW,YAAY,QAAQ,CAAA;AACrC,EAAA,MAAM,WAAA,GAAc,EAAE,GAAA,EAAK,QAAA,EAAU,GAAG,OAAA,EAAQ;AAEhD,EAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,QAAA,EAAU,QAAA,EAAU;AAAA,IACjD,MAAA,EAAQ,MAAA;AAAA,IACR,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,WAAW,CAAA;AAAA,IAChC,OAAA,EAAS;AAAA,MACP,MAAA,EAAQ,kBAAA;AAAA,MACR,cAAA,EAAgB;AAAA;AAClB,GACD,CAAA;AACD,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,MAAMC,oBAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA,EACjD;AACA,EAAA,MAAM,YAAA,GAAgB,MAAM,QAAA,CAAS,IAAA,EAAK;AAC1C,EAAAD,uBAAA,CAAoB,QAAA,EAAU,aAAa,MAAM,CAAA;AACjD,EAAA,OAAO,YAAA;AACT;AAEO,MAAM,oBAAA,GAAuB,OAClC,QAAA,EACA,aAAA,EACA,KAAA,KACqB;AAErB,EAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM,WAAA,GAAc,QAAA,CAAS,GAAA,CAAI,CAAA,OAAA,KAAW,QAAQ,UAAU,CAAA;AAC9D,EAAA,MAAM,UAAA,GAAa,cAChB,KAAA,CAAM,GAAG,EACT,GAAA,CAAI,CAAA,SAAA,KAAa,SAAA,CAAU,IAAA,EAAM,CAAA;AAEpC,EAAA,MAAM,MAAMD,uBAAA,CAAgB;AAAA,IAC1B,OAAA,EAAS,WAAA;AAAA,IACT,UAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,QAAA,CAAS,CAAC,CAAA;AAE/B,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,QAAA,EAAU,GAAG,CAAA;AAC1C,IAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,QAAA,EAAU,QAAA,EAAU;AAAA,MACjD,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,MAAA,EAAQ;AAAA;AACV,KACD,CAAA,CAAE,IAAA,CAAK,CAAA,IAAA,KAAQ,IAAA,CAAK,MAAM,CAAA;AAE3B,IAAA,IAAI,CAAC,QAAA,CAAS,MAAA,IAAU,QAAA,CAAS,MAAA,CAAO,WAAW,CAAA,EAAG;AACpD,MAAA,OAAO,EAAC;AAAA,IACV;AAEA,IAAAC,uBAAA,CAAoB,QAAA,EAAU,SAAS,MAAM,CAAA;AAC7C,IAAA,OAAO,QAAA,CAAS,MAAA;AAAA,EAClB,SAAS,KAAA,EAAY;AACnB,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,QAAA,CAAS,wCAAwC,CAAA,EAAG;AACpE,MAAA,OAAO,EAAC;AAAA,IACV;AACA,IAAA,MAAM,KAAA;AAAA,EACR;AACF;AACA,eAAsB,gBAAA,CAAiB,KAAa,QAAA,EAA0B;AAC5E,EAAA,OAAO,OAAA,CAAQ,UAAU,GAAG,CAAA;AAC9B;AAUO,MAAM,aAAA,GAAgB,OAC3B,QAAA,EACA,QAAA,KACmB;AACnB,EAAA,MAAM,WAAW,MAAM,OAAA;AAAA,IACrB,QAAA;AAAA,IACA,CAAA,EAAGJ,aAAA,CAAU,QAAQ,CAAC,SAAS,QAAQ,CAAA,2BAAA,CAAA;AAAA,IACvC;AAAA,MACE,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,MAAA,EAAQ;AAAA;AACV;AACF,GACF;AACA,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,MAAMK,oBAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA,EACjD;AAEA,EAAA,MAAM,KAAA,GAAS,MAAM,QAAA,CAAS,IAAA,EAAK;AACnC,EAAA,OAAO,KAAA;AACT;AASA,eAAsB,OAAA,CACpB,QAAA,EACA,GAAA,EACA,IAAA,EACA;AACA,EAAA,MAAM,WAAA,GAAc,IAAA,IAAQ,EAAE,MAAA,EAAQ,KAAA,EAAM;AAI5C,EAAA,WAAA,CAAY,OAAA,GAAU;AAAA,IACpB,GAAG,QAAA,CAAS,OAAA;AAAA,IACZ,eAAe,QAAA,CAAS,KAAA;AAAA,IACxB,GAAG,WAAA,CAAY;AAAA,GACjB;AACA,EAAA,OAAO,KAAA,CAAM,KAAK,WAAW,CAAA;AAC/B;;;;;;;;;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
2
2
  import { RootConfigService } from '@backstage/backend-plugin-api';
3
- import fetch, { RequestInit } from 'node-fetch';
4
3
  import { Filter, JiraQueryResults } from '@axis-backstage/plugin-jira-dashboard-common';
5
4
 
6
5
  /**
@@ -101,7 +100,7 @@ declare const searchJira: (instance: ConfigInstance, jqlQuery: string, options:
101
100
  *
102
101
  * @public
103
102
  */
104
- declare function callApi(instance: ConfigInstance, url: string, init?: RequestInit): Promise<fetch.Response>;
103
+ declare function callApi(instance: ConfigInstance, url: string, init?: RequestInit): Promise<Response>;
105
104
 
106
105
  /**
107
106
  * Types for the arguments to the jqlQueryBuilder function.
@@ -234,6 +234,10 @@ async function createRouter(options) {
234
234
  const ps = new stream__default.default.PassThrough();
235
235
  const val = avatar.headers.get("content-type");
236
236
  response.setHeader("content-type", val ?? "");
237
+ if (!avatar.body) {
238
+ response.sendStatus(502);
239
+ return;
240
+ }
237
241
  stream__default.default.pipeline(avatar.body, ps, (err) => {
238
242
  if (err) {
239
243
  logger.error(`${err}`);
@@ -1 +1 @@
1
- {"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["import express from 'express';\nimport Router from 'express-promise-router';\nimport stream from 'stream';\n\nimport {\n AuthService,\n CacheService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n UserInfoService,\n} from '@backstage/backend-plugin-api';\nimport { stringifyEntityRef, UserEntity } from '@backstage/catalog-model';\nimport { CatalogClient } from '@backstage/catalog-client';\n\nimport {\n type Filter,\n type JiraResponse,\n type Project,\n} from '@axis-backstage/plugin-jira-dashboard-common';\n\nimport { getAnnotations, splitProjectKey } from '../lib';\nimport {\n getFiltersFromAnnotations,\n getIssuesFromComponents,\n getIssuesFromFilters,\n getProjectResponse,\n getUserIssues,\n} from './service';\nimport { DEFAULT_MAX_RESULTS_USER_ISSUES } from './defaultValues';\nimport { getAssigneUser, getDefaultFiltersForUser } from '../filters';\nimport { getProjectAvatar } from '../api';\nimport type { ConfigInstance, JiraConfig } from '../config';\n\nexport interface RouterOptions {\n /**\n * Implementation of Authentication Service\n */\n auth: AuthService;\n /**\n * Implementation of Logger Service\n */\n logger: LoggerService;\n /**\n * Parsed Jira config\n */\n config: JiraConfig;\n /**\n * Implementation of Discovery Service\n */\n discovery: DiscoveryService;\n /**\n * Implementation of Http Authentication Service\n */\n httpAuth: HttpAuthService;\n /**\n * Implementation of User Info Service\n */\n userInfo: UserInfoService;\n /**\n * Implementation of Cache Service\n */\n cache: CacheService;\n}\n\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { auth, logger, config, discovery, httpAuth, userInfo, cache } =\n options;\n const catalogClient = new CatalogClient({ discoveryApi: discovery });\n\n logger.info('Initializing Jira Dashboard backend');\n\n const router = Router();\n router.use(express.json());\n\n router.get('/health', (_, response) => {\n logger.info('PONG!');\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 auth.getPluginRequestToken({\n onBehalfOf: await auth.getOwnServiceCredentials(),\n targetPluginId: 'catalog',\n });\n const entity = await catalogClient.getEntityByRef(entityRef, { token });\n const {\n projectKeyAnnotation,\n jqlAnnotation,\n componentsAnnotation,\n filtersAnnotation,\n incomingIssuesAnnotation,\n componentRoadieAnnotation,\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 fullProjectKeys =\n entity.metadata.annotations?.[projectKeyAnnotation]?.split(',')!;\n\n if (!fullProjectKeys) {\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 const projects = fullProjectKeys.map(fullProjectKey =>\n splitProjectKey(config, fullProjectKey),\n );\n const projectResults = await Promise.allSettled(\n projects.map(project => getProjectResponse(project, cache)),\n );\n\n const projectResponses: Project[] = [];\n for (const [i, result] of projectResults.entries()) {\n if (result.status === 'rejected') {\n logger.error(\n `Could not find Jira project ${projects[i].fullProjectKey}: ${\n result.reason?.message ?? result.reason\n }`,\n );\n response.status(404).json({\n error: `Jira project not found with key ${projects[i].fullProjectKey}`,\n });\n return;\n }\n projectResponses.push(result.value);\n }\n\n let userEntity: UserEntity | undefined;\n\n try {\n const credentials = await httpAuth.credentials(request, {\n allow: ['user'],\n });\n const userIdentity = credentials.principal.userEntityRef;\n\n userEntity = (await catalogClient.getEntityByRef(userIdentity, {\n token,\n })) as UserEntity;\n } catch (err) {\n logger.warn('Could not find user identity');\n }\n\n let filters: Filter[] = [];\n\n const incomingStatus =\n entity.metadata.annotations?.[incomingIssuesAnnotation];\n\n filters = getDefaultFiltersForUser(\n projects[0].instance,\n userEntity,\n incomingStatus,\n );\n\n const customFilterAnnotations =\n entity.metadata.annotations?.[filtersAnnotation]?.split(',')!;\n\n if (customFilterAnnotations) {\n filters.push(\n ...(await getFiltersFromAnnotations(\n customFilterAnnotations,\n projects[0].instance,\n )),\n );\n }\n const instance = projects[0]?.instance;\n\n let components =\n entity.metadata.annotations?.[componentsAnnotation]?.split(',') ?? [];\n\n const jqlValue = entity.metadata.annotations?.[jqlAnnotation] ?? '';\n\n const projectKeys = projects.map(project => project.projectKey);\n let issues = await getIssuesFromFilters(\n projectKeys,\n components,\n filters,\n instance,\n cache,\n jqlValue,\n );\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.length > 0) {\n const componentIssues = await getIssuesFromComponents(\n projectKeys,\n components,\n instance,\n cache,\n jqlValue,\n );\n issues = issues.concat(componentIssues);\n }\n\n const jiraResponse: JiraResponse = {\n project: projectResponses,\n data: issues,\n };\n\n response.json(jiraResponse);\n },\n );\n\n router.get('/dashboards/user-issues', async (request, response) => {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await auth.getOwnServiceCredentials(),\n targetPluginId: 'catalog',\n });\n\n const credentials = await httpAuth.credentials(request, {\n allow: ['user'],\n });\n\n // we ignore guest and service users, no issues in response\n if (!auth.isPrincipal(credentials, 'user')) {\n response.status(200).json([]);\n return;\n }\n\n const info = await userInfo.getUserInfo(credentials);\n\n const userEntity = (await catalogClient.getEntityByRef(info.userEntityRef, {\n token,\n })) as UserEntity;\n\n if (!userEntity) {\n const error = `User entity cannot be determined from ${info.userEntityRef}`;\n logger.info(error);\n response.status(400).json(error);\n return;\n }\n\n const getUserIssuesForInstance = async (instance: ConfigInstance) => {\n const username = getAssigneUser(instance, userEntity);\n\n const maxResults = Number(\n request.query.maxResults || DEFAULT_MAX_RESULTS_USER_ISSUES,\n );\n\n const filterName = (request.query?.filterName as string) || 'default';\n\n try {\n const issues = await getUserIssues(\n username,\n maxResults,\n instance,\n cache,\n filterName,\n );\n return { issues, error: undefined };\n } catch (error: any) {\n return { error };\n }\n };\n\n const issuesList = await Promise.all(\n config\n .getInstances()\n .map(instanceName =>\n getUserIssuesForInstance(config.getInstance(instanceName)),\n ),\n );\n\n const issues = issuesList.flatMap(list => list.issues ?? []);\n const errors = issuesList\n .flatMap(list => list.error)\n .filter((v): v is NonNullable<typeof v> => !!v);\n\n if (issues.length > 0 || errors.length === 0) {\n response.status(200).json(issues);\n } else {\n const messages =\n errors.length > 1\n ? `\\n ${errors.map(err => err.message).join('\\n ')}`\n : ` ${errors[0].message}`;\n\n logger.error(`Error during getting user issues:${messages}`);\n response.status(503).json({\n error: `Error during getting user issues:${messages}`,\n });\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 auth.getPluginRequestToken({\n onBehalfOf: await auth.getOwnServiceCredentials(),\n targetPluginId: 'catalog',\n });\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 fullProjectKeys =\n entity.metadata.annotations?.[projectKeyAnnotation]?.split(',')!;\n\n if (!fullProjectKeys) {\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 const projects = fullProjectKeys.map(fullProjectKey =>\n splitProjectKey(config, fullProjectKey),\n );\n\n const projectResponse = await getProjectResponse(projects[0], 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 ${projects[0].projectKey}`,\n });\n return;\n }\n\n const url = projectResponse.avatarUrls['48x48'];\n\n const avatar = await getProjectAvatar(url, projects[0].instance);\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\n return router;\n}\n"],"names":["catalogClient","CatalogClient","Router","express","stringifyEntityRef","getAnnotations","splitProjectKey","getProjectResponse","filters","getDefaultFiltersForUser","getFiltersFromAnnotations","getIssuesFromFilters","getIssuesFromComponents","getAssigneUser","DEFAULT_MAX_RESULTS_USER_ISSUES","issues","getUserIssues","getProjectAvatar","stream"],"mappings":"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"}
1
+ {"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["import express from 'express';\nimport Router from 'express-promise-router';\nimport stream from 'stream';\n\nimport {\n AuthService,\n CacheService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n UserInfoService,\n} from '@backstage/backend-plugin-api';\nimport { stringifyEntityRef, UserEntity } from '@backstage/catalog-model';\nimport { CatalogClient } from '@backstage/catalog-client';\n\nimport {\n type Filter,\n type JiraResponse,\n type Project,\n} from '@axis-backstage/plugin-jira-dashboard-common';\n\nimport { getAnnotations, splitProjectKey } from '../lib';\nimport {\n getFiltersFromAnnotations,\n getIssuesFromComponents,\n getIssuesFromFilters,\n getProjectResponse,\n getUserIssues,\n} from './service';\nimport { DEFAULT_MAX_RESULTS_USER_ISSUES } from './defaultValues';\nimport { getAssigneUser, getDefaultFiltersForUser } from '../filters';\nimport { getProjectAvatar } from '../api';\nimport type { ConfigInstance, JiraConfig } from '../config';\n\nexport interface RouterOptions {\n /**\n * Implementation of Authentication Service\n */\n auth: AuthService;\n /**\n * Implementation of Logger Service\n */\n logger: LoggerService;\n /**\n * Parsed Jira config\n */\n config: JiraConfig;\n /**\n * Implementation of Discovery Service\n */\n discovery: DiscoveryService;\n /**\n * Implementation of Http Authentication Service\n */\n httpAuth: HttpAuthService;\n /**\n * Implementation of User Info Service\n */\n userInfo: UserInfoService;\n /**\n * Implementation of Cache Service\n */\n cache: CacheService;\n}\n\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { auth, logger, config, discovery, httpAuth, userInfo, cache } =\n options;\n const catalogClient = new CatalogClient({ discoveryApi: discovery });\n\n logger.info('Initializing Jira Dashboard backend');\n\n const router = Router();\n router.use(express.json());\n\n router.get('/health', (_, response) => {\n logger.info('PONG!');\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 auth.getPluginRequestToken({\n onBehalfOf: await auth.getOwnServiceCredentials(),\n targetPluginId: 'catalog',\n });\n const entity = await catalogClient.getEntityByRef(entityRef, { token });\n const {\n projectKeyAnnotation,\n jqlAnnotation,\n componentsAnnotation,\n filtersAnnotation,\n incomingIssuesAnnotation,\n componentRoadieAnnotation,\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 fullProjectKeys =\n entity.metadata.annotations?.[projectKeyAnnotation]?.split(',')!;\n\n if (!fullProjectKeys) {\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 const projects = fullProjectKeys.map(fullProjectKey =>\n splitProjectKey(config, fullProjectKey),\n );\n const projectResults = await Promise.allSettled(\n projects.map(project => getProjectResponse(project, cache)),\n );\n\n const projectResponses: Project[] = [];\n for (const [i, result] of projectResults.entries()) {\n if (result.status === 'rejected') {\n logger.error(\n `Could not find Jira project ${projects[i].fullProjectKey}: ${\n result.reason?.message ?? result.reason\n }`,\n );\n response.status(404).json({\n error: `Jira project not found with key ${projects[i].fullProjectKey}`,\n });\n return;\n }\n projectResponses.push(result.value);\n }\n\n let userEntity: UserEntity | undefined;\n\n try {\n const credentials = await httpAuth.credentials(request, {\n allow: ['user'],\n });\n const userIdentity = credentials.principal.userEntityRef;\n\n userEntity = (await catalogClient.getEntityByRef(userIdentity, {\n token,\n })) as UserEntity;\n } catch (err) {\n logger.warn('Could not find user identity');\n }\n\n let filters: Filter[] = [];\n\n const incomingStatus =\n entity.metadata.annotations?.[incomingIssuesAnnotation];\n\n filters = getDefaultFiltersForUser(\n projects[0].instance,\n userEntity,\n incomingStatus,\n );\n\n const customFilterAnnotations =\n entity.metadata.annotations?.[filtersAnnotation]?.split(',')!;\n\n if (customFilterAnnotations) {\n filters.push(\n ...(await getFiltersFromAnnotations(\n customFilterAnnotations,\n projects[0].instance,\n )),\n );\n }\n const instance = projects[0]?.instance;\n\n let components =\n entity.metadata.annotations?.[componentsAnnotation]?.split(',') ?? [];\n\n const jqlValue = entity.metadata.annotations?.[jqlAnnotation] ?? '';\n\n const projectKeys = projects.map(project => project.projectKey);\n let issues = await getIssuesFromFilters(\n projectKeys,\n components,\n filters,\n instance,\n cache,\n jqlValue,\n );\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.length > 0) {\n const componentIssues = await getIssuesFromComponents(\n projectKeys,\n components,\n instance,\n cache,\n jqlValue,\n );\n issues = issues.concat(componentIssues);\n }\n\n const jiraResponse: JiraResponse = {\n project: projectResponses,\n data: issues,\n };\n\n response.json(jiraResponse);\n },\n );\n\n router.get('/dashboards/user-issues', async (request, response) => {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await auth.getOwnServiceCredentials(),\n targetPluginId: 'catalog',\n });\n\n const credentials = await httpAuth.credentials(request, {\n allow: ['user'],\n });\n\n // we ignore guest and service users, no issues in response\n if (!auth.isPrincipal(credentials, 'user')) {\n response.status(200).json([]);\n return;\n }\n\n const info = await userInfo.getUserInfo(credentials);\n\n const userEntity = (await catalogClient.getEntityByRef(info.userEntityRef, {\n token,\n })) as UserEntity;\n\n if (!userEntity) {\n const error = `User entity cannot be determined from ${info.userEntityRef}`;\n logger.info(error);\n response.status(400).json(error);\n return;\n }\n\n const getUserIssuesForInstance = async (instance: ConfigInstance) => {\n const username = getAssigneUser(instance, userEntity);\n\n const maxResults = Number(\n request.query.maxResults || DEFAULT_MAX_RESULTS_USER_ISSUES,\n );\n\n const filterName = (request.query?.filterName as string) || 'default';\n\n try {\n const issues = await getUserIssues(\n username,\n maxResults,\n instance,\n cache,\n filterName,\n );\n return { issues, error: undefined };\n } catch (error: any) {\n return { error };\n }\n };\n\n const issuesList = await Promise.all(\n config\n .getInstances()\n .map(instanceName =>\n getUserIssuesForInstance(config.getInstance(instanceName)),\n ),\n );\n\n const issues = issuesList.flatMap(list => list.issues ?? []);\n const errors = issuesList\n .flatMap(list => list.error)\n .filter((v): v is NonNullable<typeof v> => !!v);\n\n if (issues.length > 0 || errors.length === 0) {\n response.status(200).json(issues);\n } else {\n const messages =\n errors.length > 1\n ? `\\n ${errors.map(err => err.message).join('\\n ')}`\n : ` ${errors[0].message}`;\n\n logger.error(`Error during getting user issues:${messages}`);\n response.status(503).json({\n error: `Error during getting user issues:${messages}`,\n });\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 auth.getPluginRequestToken({\n onBehalfOf: await auth.getOwnServiceCredentials(),\n targetPluginId: 'catalog',\n });\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 fullProjectKeys =\n entity.metadata.annotations?.[projectKeyAnnotation]?.split(',')!;\n\n if (!fullProjectKeys) {\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 const projects = fullProjectKeys.map(fullProjectKey =>\n splitProjectKey(config, fullProjectKey),\n );\n\n const projectResponse = await getProjectResponse(projects[0], 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 ${projects[0].projectKey}`,\n });\n return;\n }\n\n const url = projectResponse.avatarUrls['48x48'];\n\n const avatar = await getProjectAvatar(url, projects[0].instance);\n\n const ps = new stream.PassThrough();\n const val = avatar.headers.get('content-type');\n\n response.setHeader('content-type', val ?? '');\n if (!avatar.body) {\n response.sendStatus(502);\n return;\n }\n\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\n return router;\n}\n"],"names":["catalogClient","CatalogClient","Router","express","stringifyEntityRef","getAnnotations","splitProjectKey","getProjectResponse","filters","getDefaultFiltersForUser","getFiltersFromAnnotations","getIssuesFromFilters","getIssuesFromComponents","getAssigneUser","DEFAULT_MAX_RESULTS_USER_ISSUES","issues","getUserIssues","getProjectAvatar","stream"],"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": "6.1.5",
3
+ "version": "6.1.6",
4
4
  "main": "dist/index.cjs.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -10,6 +10,11 @@
10
10
  "types": "dist/index.d.ts",
11
11
  "directory": "_release/package"
12
12
  },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/AxisCommunications/backstage-plugins",
16
+ "directory": "plugins/jira-dashboard-backend"
17
+ },
13
18
  "backstage": {
14
19
  "role": "backend-plugin",
15
20
  "pluginId": "jira-dashboard",
@@ -32,27 +37,26 @@
32
37
  "postpack": "backstage-cli package postpack"
33
38
  },
34
39
  "dependencies": {
35
- "@axis-backstage/plugin-jira-dashboard-common": "^1.15.3",
36
- "@backstage/backend-defaults": "^0.17.6",
37
- "@backstage/backend-plugin-api": "^1.9.3",
40
+ "@axis-backstage/plugin-jira-dashboard-common": "^1.15.4",
41
+ "@backstage/backend-defaults": "^0.17.8",
42
+ "@backstage/backend-plugin-api": "^1.10.0",
38
43
  "@backstage/catalog-client": "^1.16.1",
39
- "@backstage/catalog-model": "^1.9.0",
44
+ "@backstage/catalog-model": "^1.10.0",
40
45
  "@backstage/config": "^1.3.8",
41
46
  "@backstage/errors": "^1.3.1",
42
47
  "@backstage/types": "^1.2.2",
43
48
  "express": "^4.17.1",
44
- "express-promise-router": "^4.1.0",
45
- "node-fetch": "^2.6.7"
49
+ "express-promise-router": "^4.1.0"
46
50
  },
47
51
  "devDependencies": {
48
- "@backstage/backend-test-utils": "^1.11.5",
49
- "@backstage/cli": "^0.36.4",
50
- "@backstage/plugin-auth-backend": "^0.29.2",
51
- "@backstage/plugin-auth-backend-module-guest-provider": "^0.2.21",
52
+ "@backstage/backend-test-utils": "^1.11.6",
53
+ "@backstage/cli": "^0.36.5",
54
+ "@backstage/plugin-auth-backend": "^0.30.0",
55
+ "@backstage/plugin-auth-backend-module-guest-provider": "^0.2.22",
52
56
  "@types/express": "*",
53
- "@types/supertest": "^2.0.12",
57
+ "@types/supertest": "^7.0.0",
54
58
  "msw": "^2.7.3",
55
- "supertest": "^6.2.4"
59
+ "supertest": "^7.0.0"
56
60
  },
57
61
  "files": [
58
62
  "dist",