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

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,22 @@
1
1
  # @axis-backstage/plugin-jira-dashboard-backend
2
2
 
3
+ ## 4.8.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 91be7b5: Only the filter.query was passed to the getIssuesFromFilters function, which cased the filter not to be applied in backend. Now, thw whole jql query is passed to the api.
8
+
9
+ ## 4.8.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 70256ff: Add jql annotation to the Jira plugins to allow fully customization of the issues displayed in the Jira Dashboard
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies [70256ff]
18
+ - @axis-backstage/plugin-jira-dashboard-common@1.13.0
19
+
3
20
  ## 4.7.0
4
21
 
5
22
  ### Minor Changes
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":"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"}
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":";;;;;;;;;;;;;;;;;;;;AAuEA,eAAsB,aACpB,OACyB,EAAA;AACzB,EAAM,MAAA;AAAA,IACJ,IAAA;AAAA,IACA,MAAA;AAAA,IACA,UAAA;AAAA,IACA,MAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACE,GAAA,OAAA;AACJ,EAAA,MAAMA,kBAAgB,IAAIC,2BAAA,CAAc,EAAE,YAAA,EAAc,WAAW,CAAA;AAEnE,EAAA,MAAA,CAAO,KAAK,qCAAqC,CAAA;AAEjD,EAAA,MAAM,SAASC,uBAAO,EAAA;AACtB,EAAO,MAAA,CAAA,GAAA,CAAIC,wBAAQ,CAAA,IAAA,EAAM,CAAA;AAEzB,EAAA,MAAA,CAAO,GAAI,CAAA,SAAA,EAAW,CAAC,CAAA,EAAG,QAAa,KAAA;AACrC,IAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AACnB,IAAA,QAAA,CAAS,IAAK,CAAA,EAAE,MAAQ,EAAA,IAAA,EAAM,CAAA;AAAA,GAC/B,CAAA;AAED,EAAO,MAAA,CAAA,GAAA;AAAA,IACL,kDAAA;AAAA,IACA,OAAO,SAAS,QAAa,KAAA;AAC3B,MAAA,MAAM,EAAE,IAAA,EAAM,SAAW,EAAA,IAAA,KAAS,OAAQ,CAAA,MAAA;AAC1C,MAAA,MAAM,YAAYC,+BAAmB,CAAA,EAAE,IAAM,EAAA,SAAA,EAAW,MAAM,CAAA;AAC9D,MAAA,MAAM,EAAE,KAAA,EAAU,GAAA,MAAM,KAAK,qBAAsB,CAAA;AAAA,QACjD,UAAA,EAAY,MAAM,IAAA,CAAK,wBAAyB,EAAA;AAAA,QAChD,cAAgB,EAAA;AAAA,OACjB,CAAA;AACD,MAAA,MAAM,SAAS,MAAMJ,eAAA,CAAc,eAAe,SAAW,EAAA,EAAE,OAAO,CAAA;AACtE,MAAM,MAAA;AAAA,QACJ,oBAAA;AAAA,QACA,oBAAA;AAAA,QACA,iBAAA;AAAA,QACA,wBAAA;AAAA,QACA;AAAA,OACF,GAAIK,mBAAe,MAAM,CAAA;AAEzB,MAAA,IAAI,CAAC,MAAQ,EAAA;AACX,QAAO,MAAA,CAAA,IAAA,CAAK,CAAuB,oBAAA,EAAA,SAAS,CAAE,CAAA,CAAA;AAC9C,QACG,QAAA,CAAA,MAAA,CAAO,GAAG,CACV,CAAA,IAAA,CAAK,EAAE,KAAO,EAAA,CAAA,oBAAA,EAAuB,SAAS,CAAA,CAAA,EAAI,CAAA;AACrD,QAAA;AAAA;AAGF,MAAA,MAAM,kBACJ,MAAO,CAAA,QAAA,CAAS,cAAc,oBAAoB,CAAA,EAAG,MAAM,GAAG,CAAA;AAEhE,MAAA,IAAI,CAAC,eAAiB,EAAA;AACpB,QAAM,MAAA,KAAA,GAAQ,gDAAgD,SAAS,CAAA,CAAA;AACvE,QAAA,MAAA,CAAO,KAAK,KAAK,CAAA;AACjB,QAAA,QAAA,CAAS,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,KAAK,CAAA;AAC/B,QAAA;AAAA;AAGF,MAAA,MAAM,WAAW,eAAgB,CAAA,GAAA;AAAA,QAAI,CAAA,cAAA,KACnCC,mBAAgB,CAAA,MAAA,EAAQ,cAAc;AAAA,OACxC;AACA,MAAA,MAAM,mBAA8B,EAAC;AAErC,MAAA,KAAA,MAAW,WAAW,QAAU,EAAA;AAC9B,QAAI,IAAA;AACF,UAAA,MAAM,WAAc,GAAA,MAAMC,0BAAmB,CAAA,OAAA,EAAS,KAAK,CAAA;AAC3D,UAAA,gBAAA,CAAiB,KAAK,WAAW,CAAA;AAAA,iBAC1B,GAAU,EAAA;AACjB,UAAO,MAAA,CAAA,KAAA;AAAA,YACL,CAA+B,4BAAA,EAAA,OAAA,CAAQ,cAAc,CAAA,EAAA,EAAK,IAAI,OAAO,CAAA;AAAA,WACvE;AACA,UAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA;AAAA,YACxB,KAAA,EAAO,CAAmC,gCAAA,EAAA,OAAA,CAAQ,cAAc,CAAA;AAAA,WACjE,CAAA;AACD,UAAA;AAAA;AACF;AAGF,MAAI,IAAA,UAAA;AAEJ,MAAI,IAAA;AACF,QAAA,MAAM,WAAc,GAAA,MAAM,QAAS,CAAA,WAAA,CAAY,OAAS,EAAA;AAAA,UACtD,KAAA,EAAO,CAAC,MAAM;AAAA,SACf,CAAA;AACD,QAAM,MAAA,YAAA,GAAe,YAAY,SAAU,CAAA,aAAA;AAE3C,QAAc,UAAA,GAAA,MAAMP,eAAc,CAAA,cAAA,CAAe,YAAc,EAAA;AAAA,UAC7D;AAAA,SACD,CAAA;AAAA,eACM,GAAK,EAAA;AACZ,QAAA,MAAA,CAAO,KAAK,8BAA8B,CAAA;AAAA;AAG5C,MAAA,IAAIQ,YAAoB,EAAC;AAEzB,MAAA,MAAM,cACJ,GAAA,MAAA,CAAO,QAAS,CAAA,WAAA,GAAc,wBAAwB,CAAA;AAExD,MAAUA,SAAA,GAAAC,gCAAA;AAAA,QACR,QAAA,CAAS,CAAC,CAAE,CAAA,QAAA;AAAA,QACZ,UAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,MAAM,0BACJ,MAAO,CAAA,QAAA,CAAS,cAAc,iBAAiB,CAAA,EAAG,MAAM,GAAG,CAAA;AAE7D,MAAA,IAAI,uBAAyB,EAAA;AAC3B,QAAQD,SAAA,CAAA,IAAA;AAAA,UACN,GAAI,MAAME,iCAAA;AAAA,YACR,uBAAA;AAAA,YACA,QAAA,CAAS,CAAC,CAAE,CAAA;AAAA;AACd,SACF;AAAA;AAEF,MAAM,MAAA,QAAA,GAAW,QAAS,CAAA,CAAC,CAAG,EAAA,QAAA;AAE9B,MAAI,IAAA,UAAA,GACF,OAAO,QAAS,CAAA,WAAA,GAAc,oBAAoB,CAAG,EAAA,KAAA,CAAM,GAAG,CAAA,IAAK,EAAC;AACtE,MAAA,MAAM,WAAc,GAAA,QAAA,CAAS,GAAI,CAAA,CAAA,OAAA,KAAW,QAAQ,UAAU,CAAA;AAC9D,MAAA,IAAI,SAAS,MAAMC,4BAAA;AAAA,QACjB,WAAA;AAAA,QACA,UAAA;AAAA,QACAH,SAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACF;AAGA,MAAA,UAAA,GAAa,UAAW,CAAA,MAAA;AAAA,QACtB,MAAA,CAAO,SAAS,WAAc,GAAA,yBAAyB,GAAG,KAAM,CAAA,GAAG,KACjE;AAAC,OACL;AAEA,MAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,QAAA,MAAM,kBAAkB,MAAMI,+BAAA;AAAA,UAC5B,WAAA;AAAA,UACA,UAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA,SACF;AACA,QAAS,MAAA,GAAA,MAAA,CAAO,OAAO,eAAe,CAAA;AAAA;AAGxC,MAAA,MAAM,YAA6B,GAAA;AAAA,QACjC,OAAS,EAAA,gBAAA;AAAA,QACT,IAAM,EAAA;AAAA,OACR;AAEA,MAAA,QAAA,CAAS,KAAK,YAAY,CAAA;AAAA;AAC5B,GACF;AAEA,EAAA,MAAA,CAAO,GAAI,CAAA,yBAAA,EAA2B,OAAO,OAAA,EAAS,QAAa,KAAA;AACjE,IAAA,MAAM,EAAE,KAAA,EAAU,GAAA,MAAM,KAAK,qBAAsB,CAAA;AAAA,MACjD,UAAA,EAAY,MAAM,IAAA,CAAK,wBAAyB,EAAA;AAAA,MAChD,cAAgB,EAAA;AAAA,KACjB,CAAA;AAED,IAAA,MAAM,WAAc,GAAA,MAAM,QAAS,CAAA,WAAA,CAAY,OAAS,EAAA;AAAA,MACtD,KAAA,EAAO,CAAC,MAAM;AAAA,KACf,CAAA;AAGD,IAAA,IAAI,CAAC,IAAA,CAAK,WAAY,CAAA,WAAA,EAAa,MAAM,CAAG,EAAA;AAC1C,MAAA,QAAA,CAAS,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,EAAE,CAAA;AAC5B,MAAA;AAAA;AAGF,IAAA,MAAM,IAAO,GAAA,MAAM,QAAS,CAAA,WAAA,CAAY,WAAW,CAAA;AAEnD,IAAA,MAAM,UAAc,GAAA,MAAMZ,eAAc,CAAA,cAAA,CAAe,KAAK,aAAe,EAAA;AAAA,MACzE;AAAA,KACD,CAAA;AAED,IAAA,IAAI,CAAC,UAAY,EAAA;AACf,MAAM,MAAA,KAAA,GAAQ,CAAyC,sCAAA,EAAA,IAAA,CAAK,aAAa,CAAA,CAAA;AACzE,MAAA,MAAA,CAAO,KAAK,KAAK,CAAA;AACjB,MAAA,QAAA,CAAS,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,KAAK,CAAA;AAC/B,MAAA;AAAA;AAGF,IAAM,MAAA,wBAAA,GAA2B,OAAO,QAA6B,KAAA;AACnE,MAAM,MAAA,QAAA,GAAWa,sBAAe,CAAA,QAAA,EAAU,UAAU,CAAA;AAEpD,MAAA,MAAM,UAAa,GAAA,MAAA;AAAA,QACjB,OAAA,CAAQ,MAAM,UAAc,IAAAC;AAAA,OAC9B;AAEA,MAAM,MAAA,UAAA,GAAc,OAAQ,CAAA,KAAA,EAAO,UAAyB,IAAA,SAAA;AAE5D,MAAI,IAAA;AACF,QAAA,MAAMC,UAAS,MAAMC,qBAAA;AAAA,UACnB,QAAA;AAAA,UACA,UAAA;AAAA,UACA,QAAA;AAAA,UACA,KAAA;AAAA,UACA;AAAA,SACF;AACA,QAAA,OAAO,EAAE,MAAA,EAAAD,OAAQ,EAAA,KAAA,EAAO,KAAU,CAAA,EAAA;AAAA,eAC3B,KAAY,EAAA;AACnB,QAAA,OAAO,EAAE,KAAM,EAAA;AAAA;AACjB,KACF;AAEA,IAAM,MAAA,UAAA,GAAa,MAAM,OAAQ,CAAA,GAAA;AAAA,MAC/B,MAAA,CACG,cACA,CAAA,GAAA;AAAA,QAAI,CACH,YAAA,KAAA,wBAAA,CAAyB,MAAO,CAAA,WAAA,CAAY,YAAY,CAAC;AAAA;AAC3D,KACJ;AAEA,IAAA,MAAM,SAAS,UAAW,CAAA,OAAA,CAAQ,UAAQ,IAAK,CAAA,MAAA,IAAU,EAAE,CAAA;AAC3D,IAAA,MAAM,MAAS,GAAA,UAAA,CACZ,OAAQ,CAAA,CAAA,IAAA,KAAQ,IAAK,CAAA,KAAK,CAC1B,CAAA,MAAA,CAAO,CAAC,CAAA,KAAkC,CAAC,CAAC,CAAC,CAAA;AAEhD,IAAA,IAAI,MAAO,CAAA,MAAA,GAAS,CAAK,IAAA,MAAA,CAAO,WAAW,CAAG,EAAA;AAC5C,MAAA,QAAA,CAAS,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,MAAM,CAAA;AAAA,KAC3B,MAAA;AACL,MAAM,MAAA,QAAA,GACJ,MAAO,CAAA,MAAA,GAAS,CACZ,GAAA;AAAA,EAAA,EAAO,MAAO,CAAA,GAAA,CAAI,CAAO,GAAA,KAAA,GAAA,CAAI,OAAO,CAAE,CAAA,IAAA,CAAK,MAAM,CAAC,CAClD,CAAA,GAAA,CAAA,CAAA,EAAI,MAAO,CAAA,CAAC,EAAE,OAAO,CAAA,CAAA;AAE3B,MAAO,MAAA,CAAA,KAAA,CAAM,CAAoC,iCAAA,EAAA,QAAQ,CAAE,CAAA,CAAA;AAC3D,MAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA;AAAA,QACxB,KAAA,EAAO,oCAAoC,QAAQ,CAAA;AAAA,OACpD,CAAA;AAAA;AACH,GACD,CAAA;AAED,EAAO,MAAA,CAAA,GAAA;AAAA,IACL,8CAAA;AAAA,IACA,OAAO,SAAS,QAAa,KAAA;AAC3B,MAAA,MAAM,EAAE,IAAA,EAAM,SAAW,EAAA,IAAA,KAAS,OAAQ,CAAA,MAAA;AAC1C,MAAA,MAAM,YAAYX,+BAAmB,CAAA,EAAE,IAAM,EAAA,SAAA,EAAW,MAAM,CAAA;AAC9D,MAAA,MAAM,EAAE,KAAA,EAAU,GAAA,MAAM,KAAK,qBAAsB,CAAA;AAAA,QACjD,UAAA,EAAY,MAAM,IAAA,CAAK,wBAAyB,EAAA;AAAA,QAChD,cAAgB,EAAA;AAAA,OACjB,CAAA;AACD,MAAA,MAAM,SAAS,MAAMJ,eAAA,CAAc,eAAe,SAAW,EAAA,EAAE,OAAO,CAAA;AACtE,MAAA,MAAM,EAAE,oBAAA,EAAyB,GAAAK,kBAAA,CAAe,MAAM,CAAA;AAEtD,MAAA,IAAI,CAAC,MAAQ,EAAA;AACX,QAAO,MAAA,CAAA,IAAA,CAAK,CAAuB,oBAAA,EAAA,SAAS,CAAE,CAAA,CAAA;AAC9C,QACG,QAAA,CAAA,MAAA,CAAO,GAAG,CACV,CAAA,IAAA,CAAK,EAAE,KAAO,EAAA,CAAA,oBAAA,EAAuB,SAAS,CAAA,CAAA,EAAI,CAAA;AACrD,QAAA;AAAA;AAGF,MAAA,MAAM,kBACJ,MAAO,CAAA,QAAA,CAAS,cAAc,oBAAoB,CAAA,EAAG,MAAM,GAAG,CAAA;AAEhE,MAAA,IAAI,CAAC,eAAiB,EAAA;AACpB,QAAM,MAAA,KAAA,GAAQ,gDAAgD,SAAS,CAAA,CAAA;AACvE,QAAA,MAAA,CAAO,KAAK,KAAK,CAAA;AACjB,QAAA,QAAA,CAAS,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,KAAK,CAAA;AAC/B,QAAA;AAAA;AAGF,MAAA,MAAM,WAAW,eAAgB,CAAA,GAAA;AAAA,QAAI,CAAA,cAAA,KACnCC,mBAAgB,CAAA,MAAA,EAAQ,cAAc;AAAA,OACxC;AAEA,MAAA,MAAM,kBAAkB,MAAMC,0BAAA,CAAmB,QAAS,CAAA,CAAC,GAAG,KAAK,CAAA;AAEnE,MAAA,IAAI,CAAC,eAAiB,EAAA;AACpB,QAAA,MAAA,CAAO,MAAM,gCAAgC,CAAA;AAC7C,QAAS,QAAA,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAK,CAAA;AAAA,UACxB,KAAO,EAAA,CAAA,sCAAA,EAAyC,QAAS,CAAA,CAAC,EAAE,UAAU,CAAA;AAAA,SACvE,CAAA;AACD,QAAA;AAAA;AAGF,MAAM,MAAA,GAAA,GAAM,eAAgB,CAAA,UAAA,CAAW,OAAO,CAAA;AAE9C,MAAA,MAAM,SAAS,MAAMU,oBAAA,CAAiB,KAAK,QAAS,CAAA,CAAC,EAAE,QAAQ,CAAA;AAE/D,MAAM,MAAA,EAAA,GAAK,IAAIC,uBAAA,CAAO,WAAY,EAAA;AAClC,MAAA,MAAM,GAAM,GAAA,MAAA,CAAO,OAAQ,CAAA,GAAA,CAAI,cAAc,CAAA;AAE7C,MAAS,QAAA,CAAA,SAAA,CAAU,cAAgB,EAAA,GAAA,IAAO,EAAE,CAAA;AAC5C,MAAAA,uBAAA,CAAO,QAAS,CAAA,MAAA,CAAO,IAAM,EAAA,EAAA,EAAI,CAAO,GAAA,KAAA;AACtC,QAAA,IAAI,GAAK,EAAA;AACP,UAAO,MAAA,CAAA,KAAA,CAAM,CAAG,EAAA,GAAG,CAAE,CAAA,CAAA;AACrB,UAAA,QAAA,CAAS,WAAW,GAAG,CAAA;AAAA;AAEzB,QAAA;AAAA,OACD,CAAA;AACD,MAAA,EAAA,CAAG,KAAK,QAAQ,CAAA;AAAA;AAClB,GACF;AAEA,EAAA,MAAM,aAAaC,gCAAkB,CAAA,MAAA,CAAO,EAAE,MAAQ,EAAA,MAAA,EAAQ,YAAY,CAAA;AAE1E,EAAO,MAAA,CAAA,GAAA,CAAI,UAAW,CAAA,KAAA,EAAO,CAAA;AAC7B,EAAO,OAAA,MAAA;AACT;;;;"}
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,32 +97,40 @@ 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
- filters.map(async (filter) => ({
104
- name: filter.name,
105
- query: queries.jqlQueryBuilder({
106
- project: projectKeys,
107
- components,
108
- query: filter.query
109
- }),
110
- type: "filter",
111
- issues: await api.getIssuesByFilter(projects, components, filter.query)
112
- }))
103
+ filters.map(async (filter) => {
104
+ const combinedQuery = `${jqlAnnotation ? `(${jqlAnnotation}) AND ` : ""}${filter.query}`;
105
+ return {
106
+ name: filter.name,
107
+ query: queries.jqlQueryBuilder({
108
+ project: projectKeys,
109
+ components,
110
+ query: combinedQuery
111
+ }),
112
+ type: "filter",
113
+ issues: await api.getIssuesByFilter(projects, components, combinedQuery)
114
+ };
115
+ })
113
116
  );
114
117
  };
115
- const getIssuesFromComponents = async (projectKeys, componentAnnotations, instance, cache) => {
118
+ const getIssuesFromComponents = async (projectKeys, componentAnnotations, instance, cache, jqlAnnotation) => {
116
119
  const projects = await getJiraProjectsFromKeys(projectKeys, instance, cache);
117
120
  return await Promise.all(
118
121
  componentAnnotations.map(async (componentKey) => ({
119
122
  name: componentKey,
120
123
  query: queries.jqlQueryBuilder({
121
124
  project: projectKeys,
122
- components: [componentKey]
125
+ components: [componentKey],
126
+ query: queries.jqlQueryBuilder({
127
+ project: projectKeys,
128
+ components: componentAnnotations,
129
+ query: jqlAnnotation
130
+ })
123
131
  }),
124
132
  type: "component",
125
- issues: await api.getIssuesByComponent(projects, componentKey)
133
+ issues: await api.getIssuesByComponent(projects, componentKey, jqlAnnotation)
126
134
  }))
127
135
  );
128
136
  };
@@ -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 const combinedQuery = `${jqlAnnotation ? `(${jqlAnnotation}) AND ` : ''}${\n filter.query\n }`;\n return {\n name: filter.name,\n query: jqlQueryBuilder({\n project: projectKeys,\n components,\n query: combinedQuery,\n }),\n type: 'filter',\n issues: await getIssuesByFilter(projects, components, combinedQuery),\n };\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.1",
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",