@axis-backstage/plugin-jira-dashboard-backend 4.7.0 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.cjs.js CHANGED
@@ -90,7 +90,7 @@ const searchJira = async (instance, jqlQuery, options) => {
90
90
  lib.replaceIssuesApiUrl(instance, jsonResponse.issues);
91
91
  return jsonResponse;
92
92
  };
93
- const getIssuesByComponent = async (projects, componentKeys) => {
93
+ const getIssuesByComponent = async (projects, componentKeys, query) => {
94
94
  if (projects.length === 0) {
95
95
  return [];
96
96
  }
@@ -98,7 +98,8 @@ const getIssuesByComponent = async (projects, componentKeys) => {
98
98
  const components = componentKeys.split(",").map((component) => component.trim());
99
99
  const jql = queries.jqlQueryBuilder({
100
100
  project: projectKeys,
101
- components
101
+ components,
102
+ query
102
103
  });
103
104
  const { instance } = projects[0];
104
105
  try {
@@ -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 getIssuesByFilter = async (\n projects: JiraProject[],\n components: string[],\n query: string,\n): Promise<Issue[]> => {\n const issues: Issue[] = [];\n for (const project of projects) {\n const { projectKey, instance } = project;\n const jql = jqlQueryBuilder({ project: [projectKey], components, query });\n const response = await callApi(\n instance,\n `${getApiUrl(instance)}search?jql=${jql}`,\n {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n },\n )\n .then(resp => resp.json())\n .catch(() => null);\n if (response?.errorMessages) {\n throw Error(\n `JQL returned Error: JQL - ${jql} with error: ${response?.errorMessages?.[0]}`,\n );\n }\n if (response?.issues) {\n replaceIssuesApiUrl(project.instance, response.issues);\n issues.push(...response.issues);\n }\n }\n\n return issues;\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 response = await callApi(instance, `${getApiUrl(instance)}search`, {\n method: 'POST',\n body: JSON.stringify({ jql: jqlQuery, ...options }),\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): 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 });\n\n const { instance } = projects[0];\n\n try {\n const response = await callApi(\n instance,\n `${getApiUrl(instance)}search?jql=${jql}`,\n {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\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 * 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","jqlQueryBuilder","replaceIssuesApiUrl","ResponseError","fetch"],"mappings":"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"}
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 getIssuesByFilter = async (\n projects: JiraProject[],\n components: string[],\n query: string,\n): Promise<Issue[]> => {\n const issues: Issue[] = [];\n for (const project of projects) {\n const { projectKey, instance } = project;\n const jql = jqlQueryBuilder({ project: [projectKey], components, query });\n const response = await callApi(\n instance,\n `${getApiUrl(instance)}search?jql=${jql}`,\n {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n },\n )\n .then(resp => resp.json())\n .catch(() => null);\n if (response?.errorMessages) {\n throw Error(\n `JQL returned Error: JQL - ${jql} with error: ${response?.errorMessages?.[0]}`,\n );\n }\n if (response?.issues) {\n replaceIssuesApiUrl(project.instance, response.issues);\n issues.push(...response.issues);\n }\n }\n\n return issues;\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 response = await callApi(instance, `${getApiUrl(instance)}search`, {\n method: 'POST',\n body: JSON.stringify({ jql: jqlQuery, ...options }),\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 response = await callApi(\n instance,\n `${getApiUrl(instance)}search?jql=${jql}`,\n {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\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 * 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","jqlQueryBuilder","replaceIssuesApiUrl","ResponseError","fetch"],"mappings":";;;;;;;;;;;AAca,MAAA,cAAA,GAAiB,OAC5B,OACqB,KAAA;AACrB,EAAM,MAAA,EAAE,UAAY,EAAA,QAAA,EAAa,GAAA,OAAA;AACjC,EAAA,MAAM,WAAW,MAAM,OAAA;AAAA,IACrB,QAAA;AAAA,IACA,CAAG,EAAAA,aAAA,CAAU,QAAQ,CAAC,WAAW,UAAU,CAAA,CAAA;AAAA,IAC3C;AAAA,MACE,MAAQ,EAAA,KAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACP,MAAQ,EAAA;AAAA;AACV;AACF,GACF;AACA,EAAI,IAAA,QAAA,CAAS,WAAW,GAAK,EAAA;AAC3B,IAAM,MAAA,KAAA;AAAA,MACJ,CAAmC,gCAAA,EAAA,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA;AAAA,KAC5E;AAAA;AAGF,EAAM,MAAA,eAAA,GAAkB,MAAM,QAAA,CAAS,IAAK,EAAA;AAC5C,EAAqBC,wBAAA,CAAA,OAAA,CAAQ,UAAU,eAAe,CAAA;AACtD,EAAO,OAAA,eAAA;AACT;AAEa,MAAA,aAAA,GAAgB,OAC3B,EAAA,EACA,QACoB,KAAA;AACpB,EAAA,MAAM,WAAW,MAAM,OAAA;AAAA,IACrB,QAAA;AAAA,IACA,CAAG,EAAAD,aAAA,CAAU,QAAQ,CAAC,UAAU,EAAE,CAAA,CAAA;AAAA,IAClC;AAAA,MACE,MAAQ,EAAA,KAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACP,MAAQ,EAAA;AAAA;AACV;AACF,GACF;AACA,EAAI,IAAA,QAAA,CAAS,WAAW,GAAK,EAAA;AAC3B,IAAA,MAAM,KAAM,CAAA,CAAA,EAAG,QAAS,CAAA,MAAM,CAAE,CAAA,CAAA;AAAA;AAElC,EAAM,MAAA,YAAA,GAAe,MAAM,QAAA,CAAS,IAAK,EAAA;AACzC,EAAA,OAAO,EAAE,IAAM,EAAA,YAAA,CAAa,IAAM,EAAA,KAAA,EAAO,aAAa,GAAI,EAAA;AAC5D;AAEO,MAAM,iBAAoB,GAAA,OAC/B,QACA,EAAA,UAAA,EACA,KACqB,KAAA;AACrB,EAAA,MAAM,SAAkB,EAAC;AACzB,EAAA,KAAA,MAAW,WAAW,QAAU,EAAA;AAC9B,IAAM,MAAA,EAAE,UAAY,EAAA,QAAA,EAAa,GAAA,OAAA;AACjC,IAAM,MAAA,GAAA,GAAME,wBAAgB,EAAE,OAAA,EAAS,CAAC,UAAU,CAAA,EAAG,UAAY,EAAA,KAAA,EAAO,CAAA;AACxE,IAAA,MAAM,WAAW,MAAM,OAAA;AAAA,MACrB,QAAA;AAAA,MACA,CAAG,EAAAF,aAAA,CAAU,QAAQ,CAAC,cAAc,GAAG,CAAA,CAAA;AAAA,MACvC;AAAA,QACE,MAAQ,EAAA,KAAA;AAAA,QACR,OAAS,EAAA;AAAA,UACP,MAAQ,EAAA;AAAA;AACV;AACF,KACF,CACG,KAAK,CAAQ,IAAA,KAAA,IAAA,CAAK,MAAM,CAAA,CACxB,KAAM,CAAA,MAAM,IAAI,CAAA;AACnB,IAAA,IAAI,UAAU,aAAe,EAAA;AAC3B,MAAM,MAAA,KAAA;AAAA,QACJ,8BAA8B,GAAG,CAAA,aAAA,EAAgB,QAAU,EAAA,aAAA,GAAgB,CAAC,CAAC,CAAA;AAAA,OAC/E;AAAA;AAEF,IAAA,IAAI,UAAU,MAAQ,EAAA;AACpB,MAAoBG,uBAAA,CAAA,OAAA,CAAQ,QAAU,EAAA,QAAA,CAAS,MAAM,CAAA;AACrD,MAAO,MAAA,CAAA,IAAA,CAAK,GAAG,QAAA,CAAS,MAAM,CAAA;AAAA;AAChC;AAGF,EAAO,OAAA,MAAA;AACT;AA4BO,MAAM,UAAa,GAAA,OACxB,QACA,EAAA,QAAA,EACA,OAC8B,KAAA;AAC9B,EAAM,MAAA,QAAA,GAAW,MAAM,OAAQ,CAAA,QAAA,EAAU,GAAGH,aAAU,CAAA,QAAQ,CAAC,CAAU,MAAA,CAAA,EAAA;AAAA,IACvE,MAAQ,EAAA,MAAA;AAAA,IACR,IAAA,EAAM,KAAK,SAAU,CAAA,EAAE,KAAK,QAAU,EAAA,GAAG,SAAS,CAAA;AAAA,IAClD,OAAS,EAAA;AAAA,MACP,MAAQ,EAAA,kBAAA;AAAA,MACR,cAAgB,EAAA;AAAA;AAClB,GACD,CAAA;AACD,EAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,IAAM,MAAA,MAAMI,oBAAc,CAAA,YAAA,CAAa,QAAQ,CAAA;AAAA;AAEjD,EAAM,MAAA,YAAA,GAAgB,MAAM,QAAA,CAAS,IAAK,EAAA;AAC1C,EAAoBD,uBAAA,CAAA,QAAA,EAAU,aAAa,MAAM,CAAA;AACjD,EAAO,OAAA,YAAA;AACT;AAEO,MAAM,oBAAuB,GAAA,OAClC,QACA,EAAA,aAAA,EACA,KACqB,KAAA;AAErB,EAAI,IAAA,QAAA,CAAS,WAAW,CAAG,EAAA;AACzB,IAAA,OAAO,EAAC;AAAA;AAGV,EAAA,MAAM,WAAc,GAAA,QAAA,CAAS,GAAI,CAAA,CAAA,OAAA,KAAW,QAAQ,UAAU,CAAA;AAC9D,EAAM,MAAA,UAAA,GAAa,cAChB,KAAM,CAAA,GAAG,EACT,GAAI,CAAA,CAAA,SAAA,KAAa,SAAU,CAAA,IAAA,EAAM,CAAA;AAEpC,EAAA,MAAM,MAAMD,uBAAgB,CAAA;AAAA,IAC1B,OAAS,EAAA,WAAA;AAAA,IACT,UAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,EAAE,QAAA,EAAa,GAAA,QAAA,CAAS,CAAC,CAAA;AAE/B,EAAI,IAAA;AACF,IAAA,MAAM,WAAW,MAAM,OAAA;AAAA,MACrB,QAAA;AAAA,MACA,CAAG,EAAAF,aAAA,CAAU,QAAQ,CAAC,cAAc,GAAG,CAAA,CAAA;AAAA,MACvC;AAAA,QACE,MAAQ,EAAA,KAAA;AAAA,QACR,OAAS,EAAA;AAAA,UACP,MAAQ,EAAA;AAAA;AACV;AACF,KACA,CAAA,IAAA,CAAK,CAAQ,IAAA,KAAA,IAAA,CAAK,MAAM,CAAA;AAE1B,IAAA,IAAI,CAAC,QAAS,CAAA,MAAA,IAAU,QAAS,CAAA,MAAA,CAAO,WAAW,CAAG,EAAA;AACpD,MAAA,OAAO,EAAC;AAAA;AAGV,IAAoBG,uBAAA,CAAA,QAAA,EAAU,SAAS,MAAM,CAAA;AAC7C,IAAA,OAAO,QAAS,CAAA,MAAA;AAAA,WACT,KAAY,EAAA;AACnB,IAAA,IAAI,KAAM,CAAA,OAAA,CAAQ,QAAS,CAAA,wCAAwC,CAAG,EAAA;AACpE,MAAA,OAAO,EAAC;AAAA;AAEV,IAAM,MAAA,KAAA;AAAA;AAEV;AACsB,eAAA,gBAAA,CAAiB,KAAa,QAA0B,EAAA;AAC5E,EAAO,OAAA,OAAA,CAAQ,UAAU,GAAG,CAAA;AAC9B;AASsB,eAAA,OAAA,CACpB,QACA,EAAA,GAAA,EACA,IACA,EAAA;AACA,EAAA,MAAM,WAAc,GAAA,IAAA,IAAQ,EAAE,MAAA,EAAQ,KAAM,EAAA;AAI5C,EAAA,WAAA,CAAY,OAAU,GAAA;AAAA,IACpB,GAAG,QAAS,CAAA,OAAA;AAAA,IACZ,eAAe,QAAS,CAAA,KAAA;AAAA,IACxB,GAAG,WAAY,CAAA;AAAA,GACjB;AACA,EAAO,OAAAE,sBAAA,CAAM,KAAK,WAAW,CAAA;AAC/B;;;;;;;;;;"}
package/dist/lib.cjs.js CHANGED
@@ -5,12 +5,14 @@ var pluginJiraDashboardCommon = require('@axis-backstage/plugin-jira-dashboard-c
5
5
  const getAnnotations = (config) => {
6
6
  const prefix = config.annotationPrefix;
7
7
  const projectKeyAnnotation = `${prefix}/${pluginJiraDashboardCommon.PROJECT_KEY_NAME}`;
8
+ const jqlAnnotation = `${prefix}/${pluginJiraDashboardCommon.JQL}`;
8
9
  const componentsAnnotation = `${prefix}/${pluginJiraDashboardCommon.COMPONENTS_NAME}`;
9
10
  const filtersAnnotation = `${prefix}/${pluginJiraDashboardCommon.FILTERS_NAME}`;
10
11
  const incomingIssuesAnnotation = `${prefix}/${pluginJiraDashboardCommon.INCOMING_ISSUES_STATUS}`;
11
12
  const componentRoadieAnnotation = `${prefix}/component`;
12
13
  return {
13
14
  projectKeyAnnotation,
15
+ jqlAnnotation,
14
16
  componentsAnnotation,
15
17
  filtersAnnotation,
16
18
  incomingIssuesAnnotation,
@@ -1 +1 @@
1
- {"version":3,"file":"lib.cjs.js","sources":["../src/lib.ts"],"sourcesContent":["import {\n COMPONENTS_NAME,\n PROJECT_KEY_NAME,\n FILTERS_NAME,\n INCOMING_ISSUES_STATUS,\n Project,\n Issue,\n} from '@axis-backstage/plugin-jira-dashboard-common';\n\nimport type { ConfigInstance, JiraConfig } from './config';\n\nexport const getAnnotations = (config: JiraConfig) => {\n const prefix = config.annotationPrefix;\n\n const projectKeyAnnotation = `${prefix}/${PROJECT_KEY_NAME}`;\n const componentsAnnotation = `${prefix}/${COMPONENTS_NAME}`;\n const filtersAnnotation = `${prefix}/${FILTERS_NAME}`;\n const incomingIssuesAnnotation = `${prefix}/${INCOMING_ISSUES_STATUS}`;\n\n /* Adding support for Roadie's component annotation */\n const componentRoadieAnnotation = `${prefix}/component`;\n\n return {\n projectKeyAnnotation,\n componentsAnnotation,\n filtersAnnotation,\n incomingIssuesAnnotation,\n componentRoadieAnnotation,\n };\n};\n\nexport interface JiraProject {\n instance: ConfigInstance;\n fullProjectKey: string;\n projectKey: string;\n}\n\n/**\n * Splits a project key \"instance/key\" into a config instance and a project\n * key, falling back to 'default' for unprefixed keys\n */\nexport function splitProjectKey(\n config: JiraConfig,\n fullProjectKey: string,\n): JiraProject {\n const [instance, projectKey] = fullProjectKey.split('/');\n if (!projectKey) {\n // No specific instance specified - use default\n return {\n instance: config.getInstance(),\n fullProjectKey,\n projectKey: instance,\n };\n }\n\n return {\n instance: config.getInstance(instance),\n fullProjectKey,\n projectKey,\n };\n}\n\nexport function getApiUrl(instance: ConfigInstance) {\n return instance.apiUrl || instance.baseUrl;\n}\n\nexport function replaceProjectApiUrl(\n instance: ConfigInstance,\n project: Project,\n) {\n if (instance.apiUrl) {\n const apiUrl = instance.apiUrl;\n project.self = project.self.replace(apiUrl, instance.baseUrl);\n }\n}\n\nexport function replaceIssuesApiUrl(instance: ConfigInstance, issues: Issue[]) {\n if (instance.apiUrl) {\n const apiUrl = instance.apiUrl;\n issues.forEach(\n issue => (issue.self = issue.self.replace(apiUrl, instance.baseUrl)),\n );\n }\n}\n"],"names":["PROJECT_KEY_NAME","COMPONENTS_NAME","FILTERS_NAME","INCOMING_ISSUES_STATUS"],"mappings":";;;;AAWa,MAAA,cAAA,GAAiB,CAAC,MAAuB,KAAA;AACpD,EAAA,MAAM,SAAS,MAAO,CAAA,gBAAA;AAEtB,EAAA,MAAM,oBAAuB,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAIA,0CAAgB,CAAA,CAAA;AAC1D,EAAA,MAAM,oBAAuB,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAIC,yCAAe,CAAA,CAAA;AACzD,EAAA,MAAM,iBAAoB,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAIC,sCAAY,CAAA,CAAA;AACnD,EAAA,MAAM,wBAA2B,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAIC,gDAAsB,CAAA,CAAA;AAGpE,EAAM,MAAA,yBAAA,GAA4B,GAAG,MAAM,CAAA,UAAA,CAAA;AAE3C,EAAO,OAAA;AAAA,IACL,oBAAA;AAAA,IACA,oBAAA;AAAA,IACA,iBAAA;AAAA,IACA,wBAAA;AAAA,IACA;AAAA,GACF;AACF;AAYgB,SAAA,eAAA,CACd,QACA,cACa,EAAA;AACb,EAAA,MAAM,CAAC,QAAU,EAAA,UAAU,CAAI,GAAA,cAAA,CAAe,MAAM,GAAG,CAAA;AACvD,EAAA,IAAI,CAAC,UAAY,EAAA;AAEf,IAAO,OAAA;AAAA,MACL,QAAA,EAAU,OAAO,WAAY,EAAA;AAAA,MAC7B,cAAA;AAAA,MACA,UAAY,EAAA;AAAA,KACd;AAAA;AAGF,EAAO,OAAA;AAAA,IACL,QAAA,EAAU,MAAO,CAAA,WAAA,CAAY,QAAQ,CAAA;AAAA,IACrC,cAAA;AAAA,IACA;AAAA,GACF;AACF;AAEO,SAAS,UAAU,QAA0B,EAAA;AAClD,EAAO,OAAA,QAAA,CAAS,UAAU,QAAS,CAAA,OAAA;AACrC;AAEgB,SAAA,oBAAA,CACd,UACA,OACA,EAAA;AACA,EAAA,IAAI,SAAS,MAAQ,EAAA;AACnB,IAAA,MAAM,SAAS,QAAS,CAAA,MAAA;AACxB,IAAA,OAAA,CAAQ,OAAO,OAAQ,CAAA,IAAA,CAAK,OAAQ,CAAA,MAAA,EAAQ,SAAS,OAAO,CAAA;AAAA;AAEhE;AAEgB,SAAA,mBAAA,CAAoB,UAA0B,MAAiB,EAAA;AAC7E,EAAA,IAAI,SAAS,MAAQ,EAAA;AACnB,IAAA,MAAM,SAAS,QAAS,CAAA,MAAA;AACxB,IAAO,MAAA,CAAA,OAAA;AAAA,MACL,CAAA,KAAA,KAAU,MAAM,IAAO,GAAA,KAAA,CAAM,KAAK,OAAQ,CAAA,MAAA,EAAQ,SAAS,OAAO;AAAA,KACpE;AAAA;AAEJ;;;;;;;;"}
1
+ {"version":3,"file":"lib.cjs.js","sources":["../src/lib.ts"],"sourcesContent":["import {\n COMPONENTS_NAME,\n PROJECT_KEY_NAME,\n FILTERS_NAME,\n INCOMING_ISSUES_STATUS,\n Project,\n Issue,\n JQL,\n} from '@axis-backstage/plugin-jira-dashboard-common';\n\nimport type { ConfigInstance, JiraConfig } from './config';\n\nexport const getAnnotations = (config: JiraConfig) => {\n const prefix = config.annotationPrefix;\n\n const projectKeyAnnotation = `${prefix}/${PROJECT_KEY_NAME}`;\n const jqlAnnotation = `${prefix}/${JQL}`;\n const componentsAnnotation = `${prefix}/${COMPONENTS_NAME}`;\n const filtersAnnotation = `${prefix}/${FILTERS_NAME}`;\n const incomingIssuesAnnotation = `${prefix}/${INCOMING_ISSUES_STATUS}`;\n\n /* Adding support for Roadie's component annotation */\n const componentRoadieAnnotation = `${prefix}/component`;\n\n return {\n projectKeyAnnotation,\n jqlAnnotation,\n componentsAnnotation,\n filtersAnnotation,\n incomingIssuesAnnotation,\n componentRoadieAnnotation,\n };\n};\n\nexport interface JiraProject {\n instance: ConfigInstance;\n fullProjectKey: string;\n projectKey: string;\n}\n\n/**\n * Splits a project key \"instance/key\" into a config instance and a project\n * key, falling back to 'default' for unprefixed keys\n */\nexport function splitProjectKey(\n config: JiraConfig,\n fullProjectKey: string,\n): JiraProject {\n const [instance, projectKey] = fullProjectKey.split('/');\n if (!projectKey) {\n // No specific instance specified - use default\n return {\n instance: config.getInstance(),\n fullProjectKey,\n projectKey: instance,\n };\n }\n\n return {\n instance: config.getInstance(instance),\n fullProjectKey,\n projectKey,\n };\n}\n\nexport function getApiUrl(instance: ConfigInstance) {\n return instance.apiUrl || instance.baseUrl;\n}\n\nexport function replaceProjectApiUrl(\n instance: ConfigInstance,\n project: Project,\n) {\n if (instance.apiUrl) {\n const apiUrl = instance.apiUrl;\n project.self = project.self.replace(apiUrl, instance.baseUrl);\n }\n}\n\nexport function replaceIssuesApiUrl(instance: ConfigInstance, issues: Issue[]) {\n if (instance.apiUrl) {\n const apiUrl = instance.apiUrl;\n issues.forEach(\n issue => (issue.self = issue.self.replace(apiUrl, instance.baseUrl)),\n );\n }\n}\n"],"names":["PROJECT_KEY_NAME","JQL","COMPONENTS_NAME","FILTERS_NAME","INCOMING_ISSUES_STATUS"],"mappings":";;;;AAYa,MAAA,cAAA,GAAiB,CAAC,MAAuB,KAAA;AACpD,EAAA,MAAM,SAAS,MAAO,CAAA,gBAAA;AAEtB,EAAA,MAAM,oBAAuB,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAIA,0CAAgB,CAAA,CAAA;AAC1D,EAAA,MAAM,aAAgB,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAIC,6BAAG,CAAA,CAAA;AACtC,EAAA,MAAM,oBAAuB,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAIC,yCAAe,CAAA,CAAA;AACzD,EAAA,MAAM,iBAAoB,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAIC,sCAAY,CAAA,CAAA;AACnD,EAAA,MAAM,wBAA2B,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAIC,gDAAsB,CAAA,CAAA;AAGpE,EAAM,MAAA,yBAAA,GAA4B,GAAG,MAAM,CAAA,UAAA,CAAA;AAE3C,EAAO,OAAA;AAAA,IACL,oBAAA;AAAA,IACA,aAAA;AAAA,IACA,oBAAA;AAAA,IACA,iBAAA;AAAA,IACA,wBAAA;AAAA,IACA;AAAA,GACF;AACF;AAYgB,SAAA,eAAA,CACd,QACA,cACa,EAAA;AACb,EAAA,MAAM,CAAC,QAAU,EAAA,UAAU,CAAI,GAAA,cAAA,CAAe,MAAM,GAAG,CAAA;AACvD,EAAA,IAAI,CAAC,UAAY,EAAA;AAEf,IAAO,OAAA;AAAA,MACL,QAAA,EAAU,OAAO,WAAY,EAAA;AAAA,MAC7B,cAAA;AAAA,MACA,UAAY,EAAA;AAAA,KACd;AAAA;AAGF,EAAO,OAAA;AAAA,IACL,QAAA,EAAU,MAAO,CAAA,WAAA,CAAY,QAAQ,CAAA;AAAA,IACrC,cAAA;AAAA,IACA;AAAA,GACF;AACF;AAEO,SAAS,UAAU,QAA0B,EAAA;AAClD,EAAO,OAAA,QAAA,CAAS,UAAU,QAAS,CAAA,OAAA;AACrC;AAEgB,SAAA,oBAAA,CACd,UACA,OACA,EAAA;AACA,EAAA,IAAI,SAAS,MAAQ,EAAA;AACnB,IAAA,MAAM,SAAS,QAAS,CAAA,MAAA;AACxB,IAAA,OAAA,CAAQ,OAAO,OAAQ,CAAA,IAAA,CAAK,OAAQ,CAAA,MAAA,EAAQ,SAAS,OAAO,CAAA;AAAA;AAEhE;AAEgB,SAAA,mBAAA,CAAoB,UAA0B,MAAiB,EAAA;AAC7E,EAAA,IAAI,SAAS,MAAQ,EAAA;AACnB,IAAA,MAAM,SAAS,QAAS,CAAA,MAAA;AACxB,IAAO,MAAA,CAAA,OAAA;AAAA,MACL,CAAA,KAAA,KAAU,MAAM,IAAO,GAAA,KAAA,CAAM,KAAK,OAAQ,CAAA,MAAA,EAAQ,SAAS,OAAO;AAAA,KACpE;AAAA;AAEJ;;;;;;;;"}
@@ -49,6 +49,7 @@ async function createRouter(options) {
49
49
  const entity = await catalogClient$1.getEntityByRef(entityRef, { token });
50
50
  const {
51
51
  projectKeyAnnotation,
52
+ jqlAnnotation,
52
53
  componentsAnnotation,
53
54
  filtersAnnotation,
54
55
  incomingIssuesAnnotation,
@@ -114,13 +115,15 @@ async function createRouter(options) {
114
115
  }
115
116
  const instance = projects[0]?.instance;
116
117
  let components = entity.metadata.annotations?.[componentsAnnotation]?.split(",") ?? [];
118
+ const jqlValue = entity.metadata.annotations?.[jqlAnnotation] ?? "";
117
119
  const projectKeys = projects.map((project) => project.projectKey);
118
120
  let issues = await service.getIssuesFromFilters(
119
121
  projectKeys,
120
122
  components,
121
123
  filters$1,
122
124
  instance,
123
- cache
125
+ cache,
126
+ jqlValue
124
127
  );
125
128
  components = components.concat(
126
129
  entity.metadata.annotations?.[componentRoadieAnnotation]?.split(",") ?? []
@@ -130,7 +133,8 @@ async function createRouter(options) {
130
133
  projectKeys,
131
134
  components,
132
135
  instance,
133
- cache
136
+ cache,
137
+ jqlValue
134
138
  );
135
139
  issues = issues.concat(componentIssues);
136
140
  }
@@ -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 { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport {\n AuthService,\n CacheService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n RootConfigService,\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 * Implementation of Config Service\n */\n rootConfig: RootConfigService;\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 {\n auth,\n logger,\n rootConfig,\n config,\n discovery,\n httpAuth,\n userInfo,\n 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 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 projectResponses: Project[] = [];\n\n for (const project of projects) {\n try {\n const projectData = await getProjectResponse(project, cache);\n projectResponses.push(projectData);\n } catch (err: any) {\n logger.error(\n `Could not find Jira project ${project.fullProjectKey}: ${err.message}`,\n );\n response.status(404).json({\n error: `Jira project not found with key ${project.fullProjectKey}`,\n });\n return;\n }\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 const projectKeys = projects.map(project => project.projectKey);\n let issues = await getIssuesFromFilters(\n projectKeys,\n components,\n filters,\n instance,\n cache,\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 );\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 const middleware = MiddlewareFactory.create({ logger, config: rootConfig });\n\n router.use(middleware.error());\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","MiddlewareFactory"],"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 { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport {\n AuthService,\n CacheService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n RootConfigService,\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 * Implementation of Config Service\n */\n rootConfig: RootConfigService;\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 {\n auth,\n logger,\n rootConfig,\n config,\n discovery,\n httpAuth,\n userInfo,\n 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 projectResponses: Project[] = [];\n\n for (const project of projects) {\n try {\n const projectData = await getProjectResponse(project, cache);\n projectResponses.push(projectData);\n } catch (err: any) {\n logger.error(\n `Could not find Jira project ${project.fullProjectKey}: ${err.message}`,\n );\n response.status(404).json({\n error: `Jira project not found with key ${project.fullProjectKey}`,\n });\n return;\n }\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 const middleware = MiddlewareFactory.create({ logger, config: rootConfig });\n\n router.use(middleware.error());\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","MiddlewareFactory"],"mappings":"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"}
@@ -97,7 +97,7 @@ async function getJiraProjectsFromKeys(projectKeys, instance, cache) {
97
97
  }
98
98
  return jiraProjects;
99
99
  }
100
- const getIssuesFromFilters = async (projectKeys, components, filters, instance, cache) => {
100
+ const getIssuesFromFilters = async (projectKeys, components, filters, instance, cache, jqlAnnotation) => {
101
101
  const projects = await getJiraProjectsFromKeys(projectKeys, instance, cache);
102
102
  return await Promise.all(
103
103
  filters.map(async (filter) => ({
@@ -105,24 +105,29 @@ const getIssuesFromFilters = async (projectKeys, components, filters, instance,
105
105
  query: queries.jqlQueryBuilder({
106
106
  project: projectKeys,
107
107
  components,
108
- query: filter.query
108
+ query: `${jqlAnnotation ? `(${jqlAnnotation}) AND ` : ""}${filter.query}`
109
109
  }),
110
110
  type: "filter",
111
111
  issues: await api.getIssuesByFilter(projects, components, filter.query)
112
112
  }))
113
113
  );
114
114
  };
115
- const getIssuesFromComponents = async (projectKeys, componentAnnotations, instance, cache) => {
115
+ const getIssuesFromComponents = async (projectKeys, componentAnnotations, instance, cache, jqlAnnotation) => {
116
116
  const projects = await getJiraProjectsFromKeys(projectKeys, instance, cache);
117
117
  return await Promise.all(
118
118
  componentAnnotations.map(async (componentKey) => ({
119
119
  name: componentKey,
120
120
  query: queries.jqlQueryBuilder({
121
121
  project: projectKeys,
122
- components: [componentKey]
122
+ components: [componentKey],
123
+ query: queries.jqlQueryBuilder({
124
+ project: projectKeys,
125
+ components: componentAnnotations,
126
+ query: jqlAnnotation
127
+ })
123
128
  }),
124
129
  type: "component",
125
- issues: await api.getIssuesByComponent(projects, componentKey)
130
+ issues: await api.getIssuesByComponent(projects, componentKey, jqlAnnotation)
126
131
  }))
127
132
  );
128
133
  };
@@ -1 +1 @@
1
- {"version":3,"file":"service.cjs.js","sources":["../../src/service/service.ts"],"sourcesContent":["import { CacheService } from '@backstage/backend-plugin-api';\nimport {\n type Filter,\n Issue,\n type JiraDataResponse,\n type Project,\n} from '@axis-backstage/plugin-jira-dashboard-common';\nimport {\n getFilterById,\n getIssuesByComponent,\n getIssuesByFilter,\n getProjectInfo,\n searchJira,\n SearchOptions,\n} from '../api';\nimport { jqlQueryBuilder } from '../queries';\nimport type { ConfigInstance } from '../config';\nimport { JiraProject } from '../lib';\n\nexport const getProjectResponse = async (\n project: JiraProject,\n cache: CacheService,\n): Promise<Project> => {\n let projectResponse: Project;\n\n projectResponse = (await cache.get(project.fullProjectKey)) as Project;\n\n if (projectResponse) {\n return projectResponse as Project;\n }\n\n try {\n projectResponse = await getProjectInfo(project);\n cache.set(project.fullProjectKey, projectResponse);\n } catch (err: any) {\n if (err.message !== 200) {\n throw Error(\n `Failed to get project info for project key ${project.fullProjectKey} with error: ${err.message}`,\n );\n }\n }\n return projectResponse;\n};\n\nexport const getJqlResponse = async (\n jql: string,\n config: ConfigInstance,\n cache: CacheService,\n searchOptions: SearchOptions,\n): Promise<Issue[]> => {\n let issuesResponse: Issue[];\n\n const cacheKey = `${config.baseUrl} ${jql}`;\n\n issuesResponse = (await cache.get(cacheKey)) as Issue[];\n\n if (issuesResponse) {\n return issuesResponse;\n }\n\n try {\n issuesResponse = (await searchJira(config, jql, searchOptions)).issues;\n cache.set(cacheKey, issuesResponse);\n } catch (err: any) {\n if (err.message !== 200) {\n throw Error(\n `Failed to get issues for JQL ${jql} with error: ${err.message}`,\n );\n }\n }\n return issuesResponse;\n};\n\nexport const getUserIssues = async (\n username: string,\n maxResults: number,\n config: ConfigInstance,\n cache: CacheService,\n filterName: string,\n): Promise<Issue[]> => {\n let jql = `assignee = \"${username}\" AND resolution = Unresolved ORDER BY priority DESC, updated DESC`;\n if (filterName !== 'default') {\n for (const filter of config.defaultFilters || []) {\n if (filterName === filter.name) {\n jql = `assignee = \"${username}\" AND ${filter.query}`;\n }\n }\n }\n\n return getJqlResponse(jql, config, cache, {\n fields: [\n 'key',\n 'issuetype',\n 'summary',\n 'status',\n 'priority',\n 'created',\n 'updated',\n ],\n maxResults,\n });\n};\n\nexport const getFiltersFromAnnotations = async (\n annotations: string[],\n config: ConfigInstance,\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};\nasync function getJiraProjectsFromKeys(\n projectKeys: string[],\n instance: ConfigInstance,\n cache: CacheService,\n): Promise<JiraProject[]> {\n const jiraProjects: JiraProject[] = [];\n for (const key of projectKeys) {\n const cachedProject = (await cache.get(key)) as Project;\n let projectInfo: Project;\n\n if (cachedProject) {\n projectInfo = cachedProject;\n } else {\n projectInfo = await getProjectInfo({\n projectKey: key,\n instance,\n fullProjectKey: '',\n });\n cache.set(key, projectInfo);\n }\n\n jiraProjects.push({\n instance,\n fullProjectKey: projectInfo.key,\n projectKey: projectInfo.key,\n });\n }\n return jiraProjects;\n}\nexport const getIssuesFromFilters = async (\n projectKeys: string[],\n components: string[],\n filters: Filter[],\n instance: ConfigInstance,\n cache: CacheService,\n): Promise<JiraDataResponse[]> => {\n const projects = await getJiraProjectsFromKeys(projectKeys, instance, cache);\n return await Promise.all(\n filters.map(async filter => ({\n name: filter.name,\n query: jqlQueryBuilder({\n project: projectKeys,\n components,\n query: filter.query,\n }),\n type: 'filter',\n issues: await getIssuesByFilter(projects, components, filter.query),\n })),\n );\n};\n\nexport const getIssuesFromComponents = async (\n projectKeys: string[],\n componentAnnotations: string[],\n instance: ConfigInstance,\n cache: CacheService,\n): Promise<JiraDataResponse[]> => {\n const projects = await getJiraProjectsFromKeys(projectKeys, instance, cache);\n return await Promise.all(\n componentAnnotations.map(async componentKey => ({\n name: componentKey,\n query: jqlQueryBuilder({\n project: projectKeys,\n components: [componentKey],\n }),\n type: 'component',\n issues: await getIssuesByComponent(projects, componentKey),\n })),\n );\n};\n"],"names":["getProjectInfo","searchJira","getFilterById","jqlQueryBuilder","getIssuesByFilter","getIssuesByComponent"],"mappings":"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"}
1
+ {"version":3,"file":"service.cjs.js","sources":["../../src/service/service.ts"],"sourcesContent":["import { CacheService } from '@backstage/backend-plugin-api';\nimport {\n type Filter,\n Issue,\n type JiraDataResponse,\n type Project,\n} from '@axis-backstage/plugin-jira-dashboard-common';\nimport {\n getFilterById,\n getIssuesByComponent,\n getIssuesByFilter,\n getProjectInfo,\n searchJira,\n SearchOptions,\n} from '../api';\nimport { jqlQueryBuilder } from '../queries';\nimport type { ConfigInstance } from '../config';\nimport { JiraProject } from '../lib';\n\nexport const getProjectResponse = async (\n project: JiraProject,\n cache: CacheService,\n): Promise<Project> => {\n let projectResponse: Project;\n\n projectResponse = (await cache.get(project.fullProjectKey)) as Project;\n\n if (projectResponse) {\n return projectResponse as Project;\n }\n\n try {\n projectResponse = await getProjectInfo(project);\n cache.set(project.fullProjectKey, projectResponse);\n } catch (err: any) {\n if (err.message !== 200) {\n throw Error(\n `Failed to get project info for project key ${project.fullProjectKey} with error: ${err.message}`,\n );\n }\n }\n return projectResponse;\n};\n\nexport const getJqlResponse = async (\n jql: string,\n config: ConfigInstance,\n cache: CacheService,\n searchOptions: SearchOptions,\n): Promise<Issue[]> => {\n let issuesResponse: Issue[];\n\n const cacheKey = `${config.baseUrl} ${jql}`;\n\n issuesResponse = (await cache.get(cacheKey)) as Issue[];\n\n if (issuesResponse) {\n return issuesResponse;\n }\n\n try {\n issuesResponse = (await searchJira(config, jql, searchOptions)).issues;\n cache.set(cacheKey, issuesResponse);\n } catch (err: any) {\n if (err.message !== 200) {\n throw Error(\n `Failed to get issues for JQL ${jql} with error: ${err.message}`,\n );\n }\n }\n return issuesResponse;\n};\n\nexport const getUserIssues = async (\n username: string,\n maxResults: number,\n config: ConfigInstance,\n cache: CacheService,\n filterName: string,\n): Promise<Issue[]> => {\n let jql = `assignee = \"${username}\" AND resolution = Unresolved ORDER BY priority DESC, updated DESC`;\n if (filterName !== 'default') {\n for (const filter of config.defaultFilters || []) {\n if (filterName === filter.name) {\n jql = `assignee = \"${username}\" AND ${filter.query}`;\n }\n }\n }\n\n return getJqlResponse(jql, config, cache, {\n fields: [\n 'key',\n 'issuetype',\n 'summary',\n 'status',\n 'priority',\n 'created',\n 'updated',\n ],\n maxResults,\n });\n};\n\nexport const getFiltersFromAnnotations = async (\n annotations: string[],\n config: ConfigInstance,\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};\nasync function getJiraProjectsFromKeys(\n projectKeys: string[],\n instance: ConfigInstance,\n cache: CacheService,\n): Promise<JiraProject[]> {\n const jiraProjects: JiraProject[] = [];\n for (const key of projectKeys) {\n const cachedProject = (await cache.get(key)) as Project;\n let projectInfo: Project;\n\n if (cachedProject) {\n projectInfo = cachedProject;\n } else {\n projectInfo = await getProjectInfo({\n projectKey: key,\n instance,\n fullProjectKey: '',\n });\n cache.set(key, projectInfo);\n }\n\n jiraProjects.push({\n instance,\n fullProjectKey: projectInfo.key,\n projectKey: projectInfo.key,\n });\n }\n return jiraProjects;\n}\nexport const getIssuesFromFilters = async (\n projectKeys: string[],\n components: string[],\n filters: Filter[],\n instance: ConfigInstance,\n cache: CacheService,\n jqlAnnotation?: string,\n): Promise<JiraDataResponse[]> => {\n const projects = await getJiraProjectsFromKeys(projectKeys, instance, cache);\n return await Promise.all(\n filters.map(async filter => ({\n name: filter.name,\n query: jqlQueryBuilder({\n project: projectKeys,\n components,\n query: `${jqlAnnotation ? `(${jqlAnnotation}) AND ` : ''}${\n filter.query\n }`,\n }),\n type: 'filter',\n issues: await getIssuesByFilter(projects, components, filter.query),\n })),\n );\n};\n\nexport const getIssuesFromComponents = async (\n projectKeys: string[],\n componentAnnotations: string[],\n instance: ConfigInstance,\n cache: CacheService,\n jqlAnnotation?: string,\n): Promise<JiraDataResponse[]> => {\n const projects = await getJiraProjectsFromKeys(projectKeys, instance, cache);\n return await Promise.all(\n componentAnnotations.map(async componentKey => ({\n name: componentKey,\n query: jqlQueryBuilder({\n project: projectKeys,\n components: [componentKey],\n query: jqlQueryBuilder({\n project: projectKeys,\n components: componentAnnotations,\n query: jqlAnnotation,\n }),\n }),\n type: 'component',\n issues: await getIssuesByComponent(projects, componentKey, jqlAnnotation),\n })),\n );\n};\n"],"names":["getProjectInfo","searchJira","getFilterById","jqlQueryBuilder","getIssuesByFilter","getIssuesByComponent"],"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": "4.7.0",
3
+ "version": "4.8.0",
4
4
  "main": "dist/index.cjs.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -32,7 +32,7 @@
32
32
  "postpack": "backstage-cli package postpack"
33
33
  },
34
34
  "dependencies": {
35
- "@axis-backstage/plugin-jira-dashboard-common": "^1.12.0",
35
+ "@axis-backstage/plugin-jira-dashboard-common": "^1.13.0",
36
36
  "@backstage/backend-defaults": "^0.11.0",
37
37
  "@backstage/backend-plugin-api": "^1.4.0",
38
38
  "@backstage/catalog-client": "^1.10.1",
@@ -65,4 +65,4 @@
65
65
  }
66
66
  },
67
67
  "directory": "_release/package"
68
- }
68
+ }
package/CHANGELOG.md DELETED
@@ -1,380 +0,0 @@
1
- # @axis-backstage/plugin-jira-dashboard-backend
2
-
3
- ## 4.7.0
4
-
5
- ### Minor Changes
6
-
7
- - 798d630: Add a new 'apiUrl' config parameter which can be used for scoped API tokens
8
-
9
- ## 4.6.0
10
-
11
- ### Minor Changes
12
-
13
- - 86c01b7: Bumped to Backstage 1.40
14
-
15
- ### Patch Changes
16
-
17
- - Updated dependencies [86c01b7]
18
- - @axis-backstage/plugin-jira-dashboard-common@1.12.0
19
-
20
- ## 4.5.1
21
-
22
- ### Patch Changes
23
-
24
- - 99c44e9: Fix incorrect 404 response
25
-
26
- ## 4.5.0
27
-
28
- ### Minor Changes
29
-
30
- - 15f1ee8: Support Multiple Jira Project Cards in Tabbed View
31
-
32
- ### Patch Changes
33
-
34
- - Updated dependencies [15f1ee8]
35
- - @axis-backstage/plugin-jira-dashboard-common@1.11.0
36
-
37
- ## 4.4.1
38
-
39
- ### Patch Changes
40
-
41
- - 39d98e4: Each project key in the JQL query are now wrapped in single qoutes to handle projects that contains reserved JQL words.
42
-
43
- ## 4.4.0
44
-
45
- ### Minor Changes
46
-
47
- - ede8341: Updated to Backstage v1.36.1.
48
-
49
- ### Patch Changes
50
-
51
- - Updated dependencies [ede8341]
52
- - @axis-backstage/plugin-jira-dashboard-common@1.10.0
53
-
54
- ## 4.3.1
55
-
56
- ### Patch Changes
57
-
58
- - 22754be: Remove unused `@backstage/backend-common` package dependency.
59
-
60
- ## 4.3.0
61
-
62
- ### Minor Changes
63
-
64
- - b3b6065: Adds ability to use an optional provided Jira filter defined in app-config for JiraUserIssuesViewCard
65
-
66
- ## 4.2.0
67
-
68
- ### Minor Changes
69
-
70
- - 3f9ac75: Support Multiple Project Keys in JQL Query Builder
71
- Issue https://github.com/AxisCommunications/backstage-plugins/issues/232
72
-
73
- Signed-off-by: enaysaa <saachi.nayyer@ericsson.com>
74
-
75
- ## 4.1.1
76
-
77
- ### Patch Changes
78
-
79
- - 82161b3: Fixed so JiraDashboard content can read config value from app-config file.
80
-
81
- ## 4.1.0
82
-
83
- ### Minor Changes
84
-
85
- - 24aff26: Support for user defined additional filters
86
- Issue https://github.com/AxisCommunications/backstage-plugins/issues/210
87
-
88
- Signed-off-by: enaysaa <saachi.nayyer@ericsson.com>
89
-
90
- ### Patch Changes
91
-
92
- - 8148766: The `callApi` function is now exported to make it easy to use the `jira-dashboard-backend`
93
- configuration in any Backstage plugin.
94
-
95
- ## 4.0.3
96
-
97
- ### Patch Changes
98
-
99
- - 1b47182: The backend now exports the `JiraConfig` class. This is needed to create config
100
- instances for the `searchJira`function.
101
-
102
- ## 4.0.2
103
-
104
- ### Patch Changes
105
-
106
- - Updated dependencies [060bcf6]
107
- - @axis-backstage/plugin-jira-dashboard-common@1.9.1
108
-
109
- ## 4.0.1
110
-
111
- ### Patch Changes
112
-
113
- - eab8f06: Added support for configuring custom headers for API requests
114
-
115
- ## 4.0.0
116
-
117
- ### Major Changes
118
-
119
- - 18fba21: BREAKING: The backend has been migrated to the new backend system. The createRouter function now requires the new auth and httpAuth services to be passed in, instead of the removed identity and tokenManager services. If you are using the new backend system module, this does not affect you.
120
- - 18fba21: Introduced TypeScript type definitions SearchJiraResponse and JiraQueryResults to represent Jira search responses and pagination details.
121
- Updated the searchJira function to return search results as a SearchJiraResponse, incorporating the new types.
122
- The searchJira function now returns an object containing both the search results and the HTTP status code, improving error resilience and clarity in handling search operations.
123
- The JiraQueryResults type outlines the structure of a paginated Jira search response, facilitating better data handling.
124
- These changes streamline the Jira Dashboard plugin's codebase, improving error resilience and clarity in handling search operations.
125
-
126
- ### Minor Changes
127
-
128
- - 18fba21: Add support for multiple Jira instances
129
-
130
- ### Patch Changes
131
-
132
- - 6c9c4b6: Fixed caching of user issues when having multiple Jira instances.
133
- - Updated dependencies [18fba21]
134
- - Updated dependencies [18fba21]
135
- - @axis-backstage/plugin-jira-dashboard-common@1.9.0
136
-
137
- ## 3.1.0
138
-
139
- ### Minor Changes
140
-
141
- - 39b1dbf: Add support for multiple Jira instances
142
-
143
- ### Patch Changes
144
-
145
- - Updated dependencies [39b1dbf]
146
- - @axis-backstage/plugin-jira-dashboard-common@1.8.0
147
-
148
- ## 3.0.0
149
-
150
- ### Major Changes
151
-
152
- - b6b406c: BREAKING: The backend has been migrated to the new backend system. The createRouter function now requires the new auth and httpAuth services to be passed in, instead of the removed identity and tokenManager services. If you are using the new backend system module, this does not affect you.
153
-
154
- ## 2.7.0
155
-
156
- ### Minor Changes
157
-
158
- - d3129c0: Adding jql query to support links within JiraTable title
159
-
160
- ### Patch Changes
161
-
162
- - Updated dependencies [d3129c0]
163
- - @axis-backstage/plugin-jira-dashboard-common@1.7.0
164
-
165
- ## 2.6.1
166
-
167
- ### Patch Changes
168
-
169
- - 65ae7b3: Removed deprecated types and fixed the standalone server
170
- - 1db0ada: Marked `createRouter` and `RouterOptions` as deprecated, to be removed soon after the Backstage `1.32.0` release in October
171
- - 56e84d6: Quote the incoming status string in the JQL. This makes it possible to have strings that contain whitespace.
172
-
173
- ## 2.6.0
174
-
175
- ### Minor Changes
176
-
177
- - 9bc46fc: New component - JiraUserIssuesCardView - listing user issues view for current logged user
178
-
179
- ### Patch Changes
180
-
181
- - Updated dependencies [9bc46fc]
182
- - @axis-backstage/plugin-jira-dashboard-common@1.6.0
183
-
184
- ## 2.5.0
185
-
186
- ### Minor Changes
187
-
188
- - 6fd284d: Updated to Backstage v1.30.1.
189
-
190
- ### Patch Changes
191
-
192
- - Updated dependencies [6fd284d]
193
- - @axis-backstage/plugin-jira-dashboard-common@1.5.0
194
-
195
- ## 2.4.0
196
-
197
- ### Minor Changes
198
-
199
- - 0b948ea: Generate pluginIds for plugins and bumping @backstage/cli
200
-
201
- ### Patch Changes
202
-
203
- - Updated dependencies [0b948ea]
204
- - @axis-backstage/plugin-jira-dashboard-common@1.4.0
205
-
206
- ## 2.3.1
207
-
208
- ### Patch Changes
209
-
210
- - Updated dependencies [e416aff]
211
- - @axis-backstage/plugin-jira-dashboard-common@1.3.0
212
-
213
- ## 2.3.0
214
-
215
- ### Minor Changes
216
-
217
- - 916589b: Bumped Backstage to v.27.7 and removed the TechRadar plugin since it was not used and caused problems with the new version.
218
-
219
- ### Patch Changes
220
-
221
- - Updated dependencies [916589b]
222
- - @axis-backstage/plugin-jira-dashboard-common@1.2.0
223
-
224
- ## 2.2.0
225
-
226
- ### Minor Changes
227
-
228
- - 0ec1f12: Created the incoming-issues-annotation to make it possible for users to define Jira status for Incoming issues other than "New". Made some smaller refactoring in filter.ts to create better consistency among functions.
229
- - 56c3a07: The Backstage user entity profile email is now used as default for "Assigned to me" filters. Made the JIRA_EMAIL_SUFFIX optional, so it still can be used if Backstage email does not match the one in Jira.
230
-
231
- ### Patch Changes
232
-
233
- - 7f0b7cd: Added additional documentation how to authenticate with Jira.
234
- - Updated dependencies [0ec1f12]
235
- - @axis-backstage/plugin-jira-dashboard-common@1.1.0
236
-
237
- ## 2.1.0
238
-
239
- ### Minor Changes
240
-
241
- - 5fd2a31: Querying for components that contain spaces should now return the expected results. Component
242
- names is now wrapped in single quotations.
243
-
244
- Added the `jqlQueryBuilder` function that will create a JQL query based on the arguments. This is
245
- exported from the backend plugin to be used outside the context of the plugin together with the
246
- `searchJira` function.
247
-
248
- ### Patch Changes
249
-
250
- - 11822da: Enhance error message when querying for projects
251
-
252
- ## 2.0.0
253
-
254
- ### Major Changes
255
-
256
- - 0535af4: **BREAKING** The Jira dashboard backend now uses the new auth service introduced in Backstage v1.24.0. This is only applicable when using this plugin in the new Backstage backend. This could break the usage in Backstage installations older than v1.24.0 if the new backend system is used.
257
-
258
- ### Patch Changes
259
-
260
- - 0535af4: Bumped backstage dependencies to match 1.26.0
261
- - 0535af4: Updated the installation instructions for the new backend system.
262
- - Updated dependencies [0535af4]
263
- - @axis-backstage/plugin-jira-dashboard-common@1.0.1
264
-
265
- ## 1.0.0
266
-
267
- ### Major Changes
268
-
269
- - 9456530: Updated the getIssuesByFilter function to accept an array of components,
270
- enabling the construction of more flexible JQL queries.
271
- Introduced a new variable named componentQuery to represent the portion of the JQL query related to components.
272
-
273
- Enhanced the getIssuesFromFilters function to include support for filtering by components.
274
- Now, along with project keys and filters, the function also accepts an array of components.
275
- This change allows for more comprehensive filtering options when retrieving issues from Jira.
276
-
277
- Modified the router implementation to pass the array of components to the getIssuesFromFilters function.
278
- By including components in the request, users can now specify additional criteria for filtering Jira issues,
279
- resulting in more refined search results.
280
-
281
- The introduced changes provide users with greater flexibility and control when retrieving Jira issues,
282
- allowing for more precise filtering based on project keys, components, and filter criteria.
283
- This enhancement improves the overall usability and effectiveness of the Jira integration functionality.
284
-
285
- ### Patch Changes
286
-
287
- - Updated dependencies [517c68a]
288
- - @axis-backstage/plugin-jira-dashboard-common@1.0.0
289
-
290
- ## 0.7.4
291
-
292
- ### Patch Changes
293
-
294
- - f23bacd: added content type header to searchJira call
295
-
296
- ## 0.7.3
297
-
298
- ### Patch Changes
299
-
300
- - f3203e9: Fix dependencies in published packages
301
-
302
- ## 0.7.2
303
-
304
- ### Patch Changes
305
-
306
- - 5bb3330: Added and exported a function `searchJira` that searches for Jira issues using
307
- JQL. This can be used outside this plugin to search for issues. For more information about the available options see the API documentation at
308
- [issue search](https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-search/#api-rest-api-2-search-post).
309
-
310
- ## 0.7.1
311
-
312
- ### Patch Changes
313
-
314
- - ae965c0: Fix broken workspace dependencies
315
-
316
- ## 0.7.0
317
-
318
- ### Minor Changes
319
-
320
- - 135e3b2: Updated the resolveUserEmailSuffix function to utilize config.getOptionalString method, providing a more concise approach. This modification ensures that an empty string is returned if the Jira user email suffix configuration is missing, effectively preventing failures and enhancing error logging capabilities.
321
-
322
- Modified the retrieval of project keys in the router module to handle multiple project keys specified in annotations for e.g., jira.com/project-key: abc,def,ghi
323
- The updated logic now parses multiple project keys properly and supports comma-separated values. It's important to note that in cases where multiple project keys are present, only the first project key (projectKey[0]) is used for display on the project card i.e, in this case project-key "abc", assuming it represents the main project. However, the response table will include data from all project keys specified in the annotations.
324
-
325
- ## 0.6.0
326
-
327
- ### Minor Changes
328
-
329
- - 33497c0: Dashboard and Avatar backend APIs adjusted to consume entityRef as /:kind/:namespace/:name. Fixes a 404 routing issue where a proxy like oauth2Proxy could decode the URI encoded path parameter /:entityRef known to contain the reserved path delimiter '/'.
330
-
331
- ### Patch Changes
332
-
333
- - d45e6cb: The Jira Dashboard backend now also looks for the `/component`-annotation, in order to support Roadies annotation.
334
- - 3adbfd1: Fix inaccuracy in config documentation in README.md
335
-
336
- ## 0.5.0
337
-
338
- ### Minor Changes
339
-
340
- - 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.
341
-
342
- ### Patch Changes
343
-
344
- - Updated dependencies [97f5bf4]
345
- - @axis-backstage/plugin-jira-dashboard-common@0.4.0
346
-
347
- ## 0.4.0
348
-
349
- ### Minor Changes
350
-
351
- - 864d983: Bumped Backstage version to v.1.22.0
352
-
353
- ### Patch Changes
354
-
355
- - 1248d02: Removed the single quotes from documentation config strings
356
- - Updated dependencies [864d983]
357
- - @axis-backstage/plugin-jira-dashboard-common@0.3.0
358
-
359
- ## 0.3.0
360
-
361
- ### Minor Changes
362
-
363
- - 23ff76a: Bumped Backstage version to v.1.21.0 in whole monorepo
364
-
365
- ### Patch Changes
366
-
367
- - Updated dependencies [23ff76a]
368
- - @axis-backstage/plugin-jira-dashboard-common@0.2.0
369
-
370
- ## 0.2.0
371
-
372
- ### Minor Changes
373
-
374
- - a67c963: Bumped Backstage to version 1.20.3
375
-
376
- ### Patch Changes
377
-
378
- - 1e7ee53: Added missing config.d.ts file to package.json
379
- - Updated dependencies [9cf5ab1]
380
- - @axis-backstage/plugin-jira-dashboard-common@0.1.1