@backstage-community/plugin-mend-backend 1.0.0 → 1.1.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,17 @@
|
|
|
1
1
|
# @backstage-community/plugin-mend-backend
|
|
2
2
|
|
|
3
|
+
## 1.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ba05827: Enhance Mapping Logic to support GitLab Subgroup Repository
|
|
8
|
+
|
|
9
|
+
## 1.1.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 93f75d2: Backstage version bump to v1.48.2
|
|
14
|
+
|
|
3
15
|
## 1.0.0
|
|
4
16
|
|
|
5
17
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
# Mend.io - backend
|
|
2
2
|
|
|
3
|
-
> [!IMPORTANT]
|
|
4
|
-
> New Backend System
|
|
5
|
-
|
|
6
3
|
In your `packages/backend/src/index.ts` file:
|
|
7
4
|
|
|
8
5
|
```ts
|
|
9
6
|
backend.add(import('@backstage-community/plugin-mend-backend'));
|
|
10
7
|
```
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
## Mend.io Projects Control (Optional)
|
|
13
10
|
|
|
14
11
|
The plugin supports configuration-based permission control to filter which projects are visible to users.
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
### How It Works
|
|
14
|
+
|
|
15
|
+
- **Project Filtering**: Provide a list of project IDs in the configuration to filter projects
|
|
16
|
+
- **Control Modes**: Use the `exclude` property to control the filtering behavior:
|
|
17
|
+
- `true` (blocklist mode): Show all projects **EXCEPT** those in the list
|
|
18
|
+
- `false` (allowlist mode): Show **ONLY** projects in the list
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
### Configuration
|
|
21
|
+
|
|
22
|
+
Add the following configuration to your `app-config.yaml` or `app-config.production.yaml`:
|
|
22
23
|
|
|
23
24
|
```yaml
|
|
24
25
|
mend:
|
|
@@ -30,13 +31,39 @@ mend:
|
|
|
30
31
|
exclude: true # Set to true for blocklist mode, false for allowlist mode
|
|
31
32
|
```
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
### Configuration Options
|
|
35
|
+
|
|
36
|
+
| Option | Type | Default | Description |
|
|
37
|
+
| --------- | ------- | ------- | ----------------------------------------------------------- |
|
|
38
|
+
| `ids` | Array | - | Array of project UUIDs to include or exclude |
|
|
39
|
+
| `exclude` | Boolean | `true` | Filtering mode: `true` for blocklist, `false` for allowlist |
|
|
40
|
+
|
|
41
|
+
### Mode Examples
|
|
42
|
+
|
|
43
|
+
#### Blocklist Mode (exclude: true)
|
|
44
|
+
|
|
45
|
+
```yaml
|
|
46
|
+
permissionControl:
|
|
47
|
+
ids:
|
|
48
|
+
- project-123
|
|
49
|
+
- project-456
|
|
50
|
+
exclude: true
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
_Result: Show all projects **except** project-123 and project-456_
|
|
54
|
+
|
|
55
|
+
#### Allowlist Mode (exclude: false)
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
permissionControl:
|
|
59
|
+
ids:
|
|
60
|
+
- project-789
|
|
61
|
+
- project-101
|
|
62
|
+
exclude: false
|
|
63
|
+
```
|
|
34
64
|
|
|
35
|
-
|
|
36
|
-
- `exclude`: Boolean flag (default: `true`)
|
|
37
|
-
- `true`: Exclude the listed projects (blocklist)
|
|
38
|
-
- `false`: Only show the listed projects (allowlist)
|
|
65
|
+
_Result: Show **only** project-789 and project-101_
|
|
39
66
|
|
|
40
|
-
|
|
67
|
+
## Add the Mend.io frontend plugin
|
|
41
68
|
|
|
42
69
|
See the [mend frontend plugin instructions](../mend/README.md).
|
|
@@ -63,7 +63,7 @@ const dataProjectParser = (projectStatistics, organizationProjects) => {
|
|
|
63
63
|
uuid: next.uuid,
|
|
64
64
|
name: next.name,
|
|
65
65
|
path: next.path,
|
|
66
|
-
|
|
66
|
+
entityUrl: next.entityUrl,
|
|
67
67
|
applicationName: organizationData[next.uuid].applicationName,
|
|
68
68
|
applicationUuid: next.applicationUuid,
|
|
69
69
|
lastScan: next.statistics["LAST_SCAN" /* LAST_SCAN */].lastScanTime,
|
|
@@ -88,7 +88,8 @@ const parseEntityURL = (entityUrl) => {
|
|
|
88
88
|
if (!entityUrl) {
|
|
89
89
|
return null;
|
|
90
90
|
}
|
|
91
|
-
const
|
|
91
|
+
const cleanUrl = entityUrl.replace(/^url:/, "");
|
|
92
|
+
const matches = cleanUrl.match(
|
|
92
93
|
/https?:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}(:[0-9]{1,5})?(\/.*)?/g
|
|
93
94
|
);
|
|
94
95
|
if (!matches) {
|
|
@@ -96,15 +97,42 @@ const parseEntityURL = (entityUrl) => {
|
|
|
96
97
|
}
|
|
97
98
|
const url = new URL(matches[0]);
|
|
98
99
|
const hostname = url.host.toLowerCase();
|
|
99
|
-
let
|
|
100
|
+
let path;
|
|
100
101
|
if (hostname === constants.AZURE_HOST_NAME) {
|
|
101
|
-
matcher = pathToRegexp.match("/:org/:project/_git/:repo", { end: false });
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
102
|
+
const matcher = pathToRegexp.match("/:org/:project/_git/:repo", { end: false });
|
|
103
|
+
const extracted = matcher(url.pathname);
|
|
104
|
+
if (extracted) {
|
|
105
|
+
path = `/${extracted.params.org}/${extracted.params.project}/_git/${extracted.params.repo}`;
|
|
106
|
+
}
|
|
107
|
+
} else if (hostname.includes("gitlab")) {
|
|
108
|
+
const cleanPath = url.pathname.replace(/\/-\/(tree|blob)\/[^\/]+.*$/, "");
|
|
109
|
+
const matcher = pathToRegexp.match("/:org/:repo", { end: false });
|
|
110
|
+
const extracted = matcher(cleanPath);
|
|
111
|
+
if (extracted) {
|
|
112
|
+
path = cleanPath;
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
const matcher = pathToRegexp.match("/:org/:repo", { end: false });
|
|
116
|
+
const extracted = matcher(url.pathname);
|
|
117
|
+
if (extracted) {
|
|
118
|
+
path = `/${extracted.params.org}/${extracted.params.repo}`;
|
|
119
|
+
}
|
|
106
120
|
}
|
|
121
|
+
return path ? { host: hostname, path } : null;
|
|
122
|
+
} catch (error) {
|
|
107
123
|
return null;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
const generateEntityUrl = (entity) => {
|
|
127
|
+
try {
|
|
128
|
+
const source = "catalog";
|
|
129
|
+
const namespace = entity?.metadata?.namespace;
|
|
130
|
+
const kind = entity?.kind?.toLowerCase();
|
|
131
|
+
const entityName = entity?.metadata?.name;
|
|
132
|
+
if (!namespace || !kind || !entityName) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
return `/${source}/${namespace}/${kind}/${entityName}`;
|
|
108
136
|
} catch (error) {
|
|
109
137
|
return null;
|
|
110
138
|
}
|
|
@@ -113,24 +141,20 @@ const dataMatcher = (entities, projects) => {
|
|
|
113
141
|
const projectSourceURL = getSourceURLWiseProject(projects);
|
|
114
142
|
return entities.reduce(
|
|
115
143
|
(prev, next) => {
|
|
116
|
-
const
|
|
144
|
+
const parsedSourceLocation = parseEntityURL(
|
|
117
145
|
next?.metadata?.annotations?.["backstage.io/source-location"]
|
|
118
146
|
);
|
|
119
|
-
if (!
|
|
147
|
+
if (!parsedSourceLocation) {
|
|
120
148
|
return prev;
|
|
121
149
|
}
|
|
122
|
-
const relatedProjects = projectSourceURL[`${
|
|
150
|
+
const relatedProjects = projectSourceURL[`${parsedSourceLocation?.host}${parsedSourceLocation?.path}`]?.projectObjs;
|
|
123
151
|
if (!relatedProjects) {
|
|
124
152
|
return prev;
|
|
125
153
|
}
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
kind: "component",
|
|
131
|
-
source: "catalog"
|
|
132
|
-
};
|
|
133
|
-
relatedProjects.forEach((project) => prev.push({ ...project, entity }));
|
|
154
|
+
const entityUrl = generateEntityUrl(next);
|
|
155
|
+
relatedProjects.forEach(
|
|
156
|
+
(project) => prev.push({ ...project, entityUrl: entityUrl ?? void 0 })
|
|
157
|
+
);
|
|
134
158
|
return prev;
|
|
135
159
|
},
|
|
136
160
|
[]
|
|
@@ -292,6 +316,7 @@ exports.dataFindingParser = dataFindingParser;
|
|
|
292
316
|
exports.dataMatcher = dataMatcher;
|
|
293
317
|
exports.dataProjectParser = dataProjectParser;
|
|
294
318
|
exports.fetchQueryPagination = fetchQueryPagination;
|
|
319
|
+
exports.generateEntityUrl = generateEntityUrl;
|
|
295
320
|
exports.getSourceURLWiseProject = getSourceURLWiseProject;
|
|
296
321
|
exports.parseEntityURL = parseEntityURL;
|
|
297
322
|
//# sourceMappingURL=data.service.helpers.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.service.helpers.cjs.js","sources":["../../src/service/data.service.helpers.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity } from '@backstage/catalog-model';\nimport { match } from 'path-to-regexp';\nimport type { QueryParams } from '../api';\nimport {\n ProjectStatisticsSuccessResponseData,\n EntityURL,\n OrganizationProjectSuccessResponseData,\n PaginationQueryParams,\n Project,\n CodeFindingSuccessResponseData,\n DependenciesFindingSuccessResponseData,\n ContainersFindingSuccessResponseData,\n Finding,\n StatisticsEngine,\n StatisticsName,\n} from './data.service.types';\nimport { AZURE_HOST_NAME } from '../constants';\n\nenum FINDING_TYPE {\n DEPENDENCIES = 'ALERTS',\n CODE = 'SAST_VULNERABILITIES_BY_SEVERITY',\n CONTAINERS = 'IMG_SECURITY',\n LAST_SCAN = 'LAST_SCAN',\n}\n\ntype OverviewData = {\n projectList: Project[];\n};\n\nexport const dataProjectParser = (\n projectStatistics: Array<\n ProjectStatisticsSuccessResponseData & { entity: EntityURL }\n >,\n organizationProjects: OrganizationProjectSuccessResponseData[],\n) => {\n const organizationData = organizationProjects.reduce((prev, next) => {\n prev[next.uuid] = next;\n return prev;\n }, {} as { [key: string]: OrganizationProjectSuccessResponseData });\n\n const projectData = projectStatistics.reduce(\n (\n prev: OverviewData,\n next: ProjectStatisticsSuccessResponseData & { entity: EntityURL },\n ) => {\n const dependenciesCritical =\n next.statistics[FINDING_TYPE.DEPENDENCIES]\n .criticalSeverityVulnerabilities;\n const dependenciesHigh =\n next.statistics[FINDING_TYPE.DEPENDENCIES].highSeverityVulnerabilities;\n const dependenciesMedium =\n next.statistics[FINDING_TYPE.DEPENDENCIES]\n .mediumSeverityVulnerabilities;\n const dependenciesLow =\n next.statistics[FINDING_TYPE.DEPENDENCIES].lowSeverityVulnerabilities;\n const dependeciesTotal =\n dependenciesCritical +\n dependenciesHigh +\n dependenciesMedium +\n dependenciesLow;\n\n const codeHigh =\n next.statistics[FINDING_TYPE.CODE].sastHighVulnerabilities;\n const codeMedium =\n next.statistics[FINDING_TYPE.CODE].sastMediumVulnerabilities;\n const codeLow = next.statistics[FINDING_TYPE.CODE].sastLowVulnerabilities;\n const codeTotal = codeHigh + codeMedium + codeLow;\n\n const containersCritical =\n next.statistics[FINDING_TYPE.CONTAINERS].imgCriticalVulnerabilities;\n const containersHigh =\n next.statistics[FINDING_TYPE.CONTAINERS].imgHighVulnerabilities;\n const containersMedium =\n next.statistics[FINDING_TYPE.CONTAINERS].imgMediumVulnerabilities;\n const containersLow =\n next.statistics[FINDING_TYPE.CONTAINERS].imgLowVulnerabilities;\n const containersTotal =\n containersCritical + containersHigh + containersMedium + containersLow;\n\n const criticalTotal = dependenciesCritical + containersCritical;\n const highTotal = dependenciesHigh + codeHigh + containersHigh;\n const mediumTotal = dependenciesMedium + codeMedium + containersMedium;\n const lowTotal = dependenciesLow + codeLow + containersLow;\n const total = dependeciesTotal + codeTotal + containersTotal;\n\n const statistics = {\n [StatisticsEngine.DEPENDENCIES]: {\n critical: dependenciesCritical,\n high: dependenciesHigh,\n medium: dependenciesMedium,\n low: dependenciesLow,\n total: dependeciesTotal,\n },\n [StatisticsEngine.CODE]: {\n critical: null,\n high: codeHigh,\n medium: codeMedium,\n low: codeLow,\n total: codeTotal,\n },\n [StatisticsEngine.CONTAINERS]: {\n critical: containersCritical,\n high: containersHigh,\n medium: containersMedium,\n low: containersLow,\n total: containersTotal,\n },\n critical: criticalTotal,\n high: highTotal,\n medium: mediumTotal,\n low: lowTotal,\n total: total,\n };\n\n const project = {\n statistics,\n uuid: next.uuid,\n name: next.name,\n path: next.path,\n entity: next.entity,\n applicationName: organizationData[next.uuid].applicationName,\n applicationUuid: next.applicationUuid,\n lastScan: next.statistics[FINDING_TYPE.LAST_SCAN].lastScanTime,\n languages: next.statistics?.LIBRARY_TYPE_HISTOGRAM\n ? Object.entries(next.statistics.LIBRARY_TYPE_HISTOGRAM).sort(\n (a, b) => b[1] - a[1],\n )\n : ([] as [string, number][]),\n };\n\n prev.projectList.unshift(project);\n return prev;\n },\n {\n projectList: [],\n },\n );\n\n projectData.projectList.sort(\n (a, b) => b.statistics.critical - a.statistics.critical,\n );\n\n return projectData;\n};\n\nexport const parseEntityURL = (entityUrl?: string) => {\n try {\n if (!entityUrl) {\n return null;\n }\n\n const matches = entityUrl.match(\n /https?:\\/\\/[a-zA-Z0-9\\-\\.]+\\.[a-zA-Z]{2,}(:[0-9]{1,5})?(\\/.*)?/g,\n );\n\n if (!matches) {\n return null;\n }\n const url = new URL(matches[0]);\n const hostname = url.host.toLowerCase();\n let matcher = match('/:org/:repo', { end: false });\n\n if (hostname === AZURE_HOST_NAME) {\n matcher = match('/:org/:project/_git/:repo', { end: false });\n }\n const extractedContent = matcher(url.pathname);\n if (extractedContent) {\n return { ...extractedContent, host: hostname };\n }\n return null;\n } catch (error) {\n return null;\n }\n};\n\nexport const dataMatcher = (\n entities: Entity[],\n projects: ProjectStatisticsSuccessResponseData[],\n) => {\n const projectSourceURL = getSourceURLWiseProject(projects);\n return entities.reduce(\n (\n prev: Array<\n ProjectStatisticsSuccessResponseData & {\n entity: EntityURL;\n }\n >,\n next: Entity,\n ) => {\n const entityURL = parseEntityURL(\n next?.metadata?.annotations?.['backstage.io/source-location'],\n );\n\n if (!entityURL) {\n return prev;\n }\n\n // NOTE: Find project based on Github URL\n const relatedProjects =\n projectSourceURL[`${entityURL?.host}${entityURL?.path}`]?.projectObjs;\n\n if (!relatedProjects) {\n return prev;\n }\n\n const entity = {\n path: entityURL.path,\n params: entityURL.params,\n namespace: next.metadata.namespace,\n kind: 'component',\n source: 'catalog',\n };\n\n relatedProjects.forEach(project => prev.push({ ...project, entity }));\n\n return prev;\n },\n [],\n );\n};\n\n/**\n * Extracts the source URL details from each project and returns a dictionary\n * where each key is a combination of the URL's host and pathname,\n * and the value is an object containing the original project and the parsed source URL data.\n *\n * @param projects Array of ProjectStatisticsSuccessResponseData\n * @returns A dictionary object with keys as `${host}${pathname}` strings extracted from sourceUrl and values as:\n * {\n * projectObjs: ProjectStatisticsSuccessResponseData[];\n sourceUrl: string | null;\n host: string | null;\n pathname: string | null;\n * }\n */\nexport function getSourceURLWiseProject(\n projects: ProjectStatisticsSuccessResponseData[],\n) {\n return projects.reduce(\n (acc, project) => {\n const projectTags = project.tags as Array<{ key: string; value: string }>;\n const sourceUrlTag = projectTags?.find(tag => tag.key === 'sourceUrl');\n let host = null;\n let pathname = null;\n let sourceUrl = null;\n\n if (sourceUrlTag && typeof sourceUrlTag.value === 'string') {\n sourceUrl = sourceUrlTag.value;\n const urlString = sourceUrl.startsWith('http')\n ? sourceUrl\n : `https://${sourceUrl}`;\n\n try {\n const urlObj = new URL(urlString);\n host = urlObj.host.toLocaleLowerCase();\n // Remove leading/trailing slashes and split\n pathname = urlObj.pathname;\n } catch (e) {\n // fallback: leave as nulls\n }\n }\n\n if (acc[`${host}${pathname}`]) {\n acc[`${host}${pathname}`].projectObjs.push(project);\n } else {\n acc[`${host}${pathname}`] = {\n projectObjs: [project],\n sourceUrl,\n host,\n pathname,\n };\n }\n return acc;\n },\n {} as Record<\n string,\n {\n projectObjs: ProjectStatisticsSuccessResponseData[];\n sourceUrl: string | null;\n host: string | null;\n pathname: string | null;\n }\n >,\n );\n}\n\nconst getIssueStatus = (\n engine: StatisticsEngine,\n finding:\n | CodeFindingSuccessResponseData\n | DependenciesFindingSuccessResponseData\n | ContainersFindingSuccessResponseData,\n): string => {\n if (engine === StatisticsEngine.CODE) {\n if ((finding as CodeFindingSuccessResponseData)?.suppressed)\n return 'suppressed';\n if (\n (finding as CodeFindingSuccessResponseData)?.almIssues?.jiraPlatform\n ?.issueStatus\n )\n return 'created';\n if ((finding as CodeFindingSuccessResponseData)?.reviewed)\n return 'reviewed';\n }\n\n if (engine === StatisticsEngine.DEPENDENCIES) {\n // NOTE: Available status: IGNORED and ACTIVE\n // ACTIVE means unreviewed\n // IGNORED means suppressed, comment fields are available to this status\n if (\n (finding as DependenciesFindingSuccessResponseData)?.findingInfo\n ?.status === 'IGNORED'\n )\n return 'suppressed';\n }\n\n return 'unreviewed';\n};\n\nexport const dataFindingParser = (\n code: CodeFindingSuccessResponseData[] = [],\n dependencies: DependenciesFindingSuccessResponseData[] = [],\n containers: ContainersFindingSuccessResponseData[] = [],\n projectName: string = '',\n) => {\n let codeFindings: Finding[] = [];\n let dependenciesFindings: Finding[] = [];\n let containersFindings: Finding[] = [];\n\n if (code.length) {\n codeFindings = code.map(finding => {\n return {\n kind: StatisticsEngine.CODE,\n level: finding.severity.toLowerCase() as StatisticsName,\n name: finding.type.cwe.title,\n origin: `${finding.sharedStep.file}:${finding.sharedStep.line}`,\n time: finding?.createdTime,\n projectId: finding.projectId,\n projectName: projectName,\n issue: {\n issueStatus: finding.almIssues.jiraPlatform.issueStatus,\n reporter: finding.almIssues.jiraPlatform.createdByName,\n creationDate: finding.almIssues.jiraPlatform.createdTime,\n ticketName: finding.almIssues.jiraPlatform.issueKey,\n link: `${finding.almIssues.jiraPlatform.publicLink}/browse/${finding.almIssues.jiraPlatform.issueKey}`,\n status: getIssueStatus(StatisticsEngine.CODE, finding),\n },\n };\n });\n }\n\n if (dependencies.length) {\n dependenciesFindings = dependencies.map(finding => {\n return {\n kind: StatisticsEngine.DEPENDENCIES,\n level: finding.vulnerability.severity.toLowerCase() as StatisticsName,\n name: finding.vulnerability.name,\n origin: finding.component.name,\n time: finding.vulnerability.modifiedDate,\n projectId: finding.project.uuid,\n projectName: projectName,\n issue: {\n issueStatus: '',\n reporter: '',\n creationDate: '',\n ticketName: '',\n link: '',\n status: getIssueStatus(StatisticsEngine.DEPENDENCIES, finding),\n },\n };\n });\n }\n\n if (containers.length) {\n containersFindings = containers.map(finding => {\n return {\n kind: StatisticsEngine.CONTAINERS,\n level: finding.severity.toLowerCase() as StatisticsName,\n name: finding.vulnerabilityId,\n origin: finding.packageName,\n time: finding.detectionDate,\n projectId: finding.projectUuid,\n projectName: projectName,\n issue: {\n issueStatus: '',\n reporter: '',\n creationDate: '',\n ticketName: '',\n link: '',\n status: getIssueStatus(StatisticsEngine.CONTAINERS, finding), // NOTE: Currently, issue for finding in containers no exist.\n },\n };\n });\n }\n\n const order: { [k: string]: number } = {\n critical: 1,\n high: 2,\n medium: 3,\n low: 4,\n };\n\n return [...codeFindings, ...dependenciesFindings, ...containersFindings].sort(\n (a, b) => {\n return order[a.level] - order[b.level];\n },\n );\n};\n\nconst parseQueryString = (href = '?'): QueryParams => {\n const [, queryString] = href.split('?');\n\n const queryParams: QueryParams = {};\n new URLSearchParams(queryString).forEach((val, key) => {\n queryParams[key] = val;\n });\n\n return queryParams;\n};\n\nexport const fetchQueryPagination = async <T>(cb: Function) => {\n const defaultQueryParams = { limit: '10000', cursor: '0' };\n const collection: T[] = [];\n\n const fetchLoop = async (queryParams: PaginationQueryParams) => {\n const result = await cb({ queryParams });\n\n collection.push(...result.response);\n\n const nextQuery = result.additionalData?.paging?.next;\n\n if (nextQuery) {\n const newQueryParams = parseQueryString(nextQuery);\n await fetchLoop(newQueryParams);\n }\n };\n\n await fetchLoop(defaultQueryParams);\n\n return collection;\n};\n"],"names":["StatisticsEngine","match","AZURE_HOST_NAME"],"mappings":";;;;;;AA4CO,MAAM,iBAAA,GAAoB,CAC/B,iBAAA,EAGA,oBAAA,KACG;AACH,EAAA,MAAM,gBAAA,GAAmB,oBAAA,CAAqB,MAAA,CAAO,CAAC,MAAM,IAAA,KAAS;AACnE,IAAA,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA;AAClB,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,EAAG,EAA+D,CAAA;AAElE,EAAA,MAAM,cAAc,iBAAA,CAAkB,MAAA;AAAA,IACpC,CACE,MACA,IAAA,KACG;AACH,MAAA,MAAM,oBAAA,GACJ,IAAA,CAAK,UAAA,CAAW,QAAA,oBAAyB,CACtC,+BAAA;AACL,MAAA,MAAM,gBAAA,GACJ,IAAA,CAAK,UAAA,CAAW,QAAA,oBAAyB,CAAE,2BAAA;AAC7C,MAAA,MAAM,kBAAA,GACJ,IAAA,CAAK,UAAA,CAAW,QAAA,oBAAyB,CACtC,6BAAA;AACL,MAAA,MAAM,eAAA,GACJ,IAAA,CAAK,UAAA,CAAW,QAAA,oBAAyB,CAAE,0BAAA;AAC7C,MAAA,MAAM,gBAAA,GACJ,oBAAA,GACA,gBAAA,GACA,kBAAA,GACA,eAAA;AAEF,MAAA,MAAM,QAAA,GACJ,IAAA,CAAK,UAAA,CAAW,kCAAA,YAAiB,CAAE,uBAAA;AACrC,MAAA,MAAM,UAAA,GACJ,IAAA,CAAK,UAAA,CAAW,kCAAA,YAAiB,CAAE,yBAAA;AACrC,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,UAAA,CAAW,kCAAA,YAAiB,CAAE,sBAAA;AACnD,MAAA,MAAM,SAAA,GAAY,WAAW,UAAA,GAAa,OAAA;AAE1C,MAAA,MAAM,kBAAA,GACJ,IAAA,CAAK,UAAA,CAAW,cAAA,kBAAuB,CAAE,0BAAA;AAC3C,MAAA,MAAM,cAAA,GACJ,IAAA,CAAK,UAAA,CAAW,cAAA,kBAAuB,CAAE,sBAAA;AAC3C,MAAA,MAAM,gBAAA,GACJ,IAAA,CAAK,UAAA,CAAW,cAAA,kBAAuB,CAAE,wBAAA;AAC3C,MAAA,MAAM,aAAA,GACJ,IAAA,CAAK,UAAA,CAAW,cAAA,kBAAuB,CAAE,qBAAA;AAC3C,MAAA,MAAM,eAAA,GACJ,kBAAA,GAAqB,cAAA,GAAiB,gBAAA,GAAmB,aAAA;AAE3D,MAAA,MAAM,gBAAgB,oBAAA,GAAuB,kBAAA;AAC7C,MAAA,MAAM,SAAA,GAAY,mBAAmB,QAAA,GAAW,cAAA;AAChD,MAAA,MAAM,WAAA,GAAc,qBAAqB,UAAA,GAAa,gBAAA;AACtD,MAAA,MAAM,QAAA,GAAW,kBAAkB,OAAA,GAAU,aAAA;AAC7C,MAAA,MAAM,KAAA,GAAQ,mBAAmB,SAAA,GAAY,eAAA;AAE7C,MAAA,MAAM,UAAA,GAAa;AAAA,QACjB,CAACA,mCAAA,CAAiB,YAAY,GAAG;AAAA,UAC/B,QAAA,EAAU,oBAAA;AAAA,UACV,IAAA,EAAM,gBAAA;AAAA,UACN,MAAA,EAAQ,kBAAA;AAAA,UACR,GAAA,EAAK,eAAA;AAAA,UACL,KAAA,EAAO;AAAA,SACT;AAAA,QACA,CAACA,mCAAA,CAAiB,IAAI,GAAG;AAAA,UACvB,QAAA,EAAU,IAAA;AAAA,UACV,IAAA,EAAM,QAAA;AAAA,UACN,MAAA,EAAQ,UAAA;AAAA,UACR,GAAA,EAAK,OAAA;AAAA,UACL,KAAA,EAAO;AAAA,SACT;AAAA,QACA,CAACA,mCAAA,CAAiB,UAAU,GAAG;AAAA,UAC7B,QAAA,EAAU,kBAAA;AAAA,UACV,IAAA,EAAM,cAAA;AAAA,UACN,MAAA,EAAQ,gBAAA;AAAA,UACR,GAAA,EAAK,aAAA;AAAA,UACL,KAAA,EAAO;AAAA,SACT;AAAA,QACA,QAAA,EAAU,aAAA;AAAA,QACV,IAAA,EAAM,SAAA;AAAA,QACN,MAAA,EAAQ,WAAA;AAAA,QACR,GAAA,EAAK,QAAA;AAAA,QACL;AAAA,OACF;AAEA,MAAA,MAAM,OAAA,GAAU;AAAA,QACd,UAAA;AAAA,QACA,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,eAAA,EAAiB,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA,CAAE,eAAA;AAAA,QAC7C,iBAAiB,IAAA,CAAK,eAAA;AAAA,QACtB,QAAA,EAAU,IAAA,CAAK,UAAA,CAAW,WAAA,iBAAsB,CAAE,YAAA;AAAA,QAClD,SAAA,EAAW,KAAK,UAAA,EAAY,sBAAA,GACxB,OAAO,OAAA,CAAQ,IAAA,CAAK,UAAA,CAAW,sBAAsB,CAAA,CAAE,IAAA;AAAA,UACrD,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,CAAC,CAAA,GAAI,EAAE,CAAC;AAAA,YAErB;AAAC,OACR;AAEA,MAAA,IAAA,CAAK,WAAA,CAAY,QAAQ,OAAO,CAAA;AAChC,MAAA,OAAO,IAAA;AAAA,IACT,CAAA;AAAA,IACA;AAAA,MACE,aAAa;AAAC;AAChB,GACF;AAEA,EAAA,WAAA,CAAY,WAAA,CAAY,IAAA;AAAA,IACtB,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,UAAA,CAAW,QAAA,GAAW,EAAE,UAAA,CAAW;AAAA,GACjD;AAEA,EAAA,OAAO,WAAA;AACT;AAEO,MAAM,cAAA,GAAiB,CAAC,SAAA,KAAuB;AACpD,EAAA,IAAI;AACF,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,UAAU,SAAA,CAAU,KAAA;AAAA,MACxB;AAAA,KACF;AAEA,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,OAAA,CAAQ,CAAC,CAAC,CAAA;AAC9B,IAAA,MAAM,QAAA,GAAW,GAAA,CAAI,IAAA,CAAK,WAAA,EAAY;AACtC,IAAA,IAAI,UAAUC,kBAAA,CAAM,aAAA,EAAe,EAAE,GAAA,EAAK,OAAO,CAAA;AAEjD,IAAA,IAAI,aAAaC,yBAAA,EAAiB;AAChC,MAAA,OAAA,GAAUD,kBAAA,CAAM,2BAAA,EAA6B,EAAE,GAAA,EAAK,OAAO,CAAA;AAAA,IAC7D;AACA,IAAA,MAAM,gBAAA,GAAmB,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA;AAC7C,IAAA,IAAI,gBAAA,EAAkB;AACpB,MAAA,OAAO,EAAE,GAAG,gBAAA,EAAkB,IAAA,EAAM,QAAA,EAAS;AAAA,IAC/C;AACA,IAAA,OAAO,IAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEO,MAAM,WAAA,GAAc,CACzB,QAAA,EACA,QAAA,KACG;AACH,EAAA,MAAM,gBAAA,GAAmB,wBAAwB,QAAQ,CAAA;AACzD,EAAA,OAAO,QAAA,CAAS,MAAA;AAAA,IACd,CACE,MAKA,IAAA,KACG;AACH,MAAA,MAAM,SAAA,GAAY,cAAA;AAAA,QAChB,IAAA,EAAM,QAAA,EAAU,WAAA,GAAc,8BAA8B;AAAA,OAC9D;AAEA,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,OAAO,IAAA;AAAA,MACT;AAGA,MAAA,MAAM,eAAA,GACJ,iBAAiB,CAAA,EAAG,SAAA,EAAW,IAAI,CAAA,EAAG,SAAA,EAAW,IAAI,CAAA,CAAE,CAAA,EAAG,WAAA;AAE5D,MAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,MAAM,MAAA,GAAS;AAAA,QACb,MAAM,SAAA,CAAU,IAAA;AAAA,QAChB,QAAQ,SAAA,CAAU,MAAA;AAAA,QAClB,SAAA,EAAW,KAAK,QAAA,CAAS,SAAA;AAAA,QACzB,IAAA,EAAM,WAAA;AAAA,QACN,MAAA,EAAQ;AAAA,OACV;AAEA,MAAA,eAAA,CAAgB,OAAA,CAAQ,aAAW,IAAA,CAAK,IAAA,CAAK,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,CAAC,CAAA;AAEpE,MAAA,OAAO,IAAA;AAAA,IACT,CAAA;AAAA,IACA;AAAC,GACH;AACF;AAgBO,SAAS,wBACd,QAAA,EACA;AACA,EAAA,OAAO,QAAA,CAAS,MAAA;AAAA,IACd,CAAC,KAAK,OAAA,KAAY;AAChB,MAAA,MAAM,cAAc,OAAA,CAAQ,IAAA;AAC5B,MAAA,MAAM,eAAe,WAAA,EAAa,IAAA,CAAK,CAAA,GAAA,KAAO,GAAA,CAAI,QAAQ,WAAW,CAAA;AACrE,MAAA,IAAI,IAAA,GAAO,IAAA;AACX,MAAA,IAAI,QAAA,GAAW,IAAA;AACf,MAAA,IAAI,SAAA,GAAY,IAAA;AAEhB,MAAA,IAAI,YAAA,IAAgB,OAAO,YAAA,CAAa,KAAA,KAAU,QAAA,EAAU;AAC1D,QAAA,SAAA,GAAY,YAAA,CAAa,KAAA;AACzB,QAAA,MAAM,YAAY,SAAA,CAAU,UAAA,CAAW,MAAM,CAAA,GACzC,SAAA,GACA,WAAW,SAAS,CAAA,CAAA;AAExB,QAAA,IAAI;AACF,UAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,SAAS,CAAA;AAChC,UAAA,IAAA,GAAO,MAAA,CAAO,KAAK,iBAAA,EAAkB;AAErC,UAAA,QAAA,GAAW,MAAA,CAAO,QAAA;AAAA,QACpB,SAAS,CAAA,EAAG;AAAA,QAEZ;AAAA,MACF;AAEA,MAAA,IAAI,IAAI,CAAA,EAAG,IAAI,CAAA,EAAG,QAAQ,EAAE,CAAA,EAAG;AAC7B,QAAA,GAAA,CAAI,CAAA,EAAG,IAAI,CAAA,EAAG,QAAQ,EAAE,CAAA,CAAE,WAAA,CAAY,KAAK,OAAO,CAAA;AAAA,MACpD,CAAA,MAAO;AACL,QAAA,GAAA,CAAI,CAAA,EAAG,IAAI,CAAA,EAAG,QAAQ,EAAE,CAAA,GAAI;AAAA,UAC1B,WAAA,EAAa,CAAC,OAAO,CAAA;AAAA,UACrB,SAAA;AAAA,UACA,IAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AACA,MAAA,OAAO,GAAA;AAAA,IACT,CAAA;AAAA,IACA;AAAC,GASH;AACF;AAEA,MAAM,cAAA,GAAiB,CACrB,MAAA,EACA,OAAA,KAIW;AACX,EAAA,IAAI,MAAA,KAAWD,oCAAiB,IAAA,EAAM;AACpC,IAAA,IAAK,OAAA,EAA4C,UAAA;AAC/C,MAAA,OAAO,YAAA;AACT,IAAA,IACG,OAAA,EAA4C,WAAW,YAAA,EACpD,WAAA;AAEJ,MAAA,OAAO,SAAA;AACT,IAAA,IAAK,OAAA,EAA4C,QAAA;AAC/C,MAAA,OAAO,UAAA;AAAA,EACX;AAEA,EAAA,IAAI,MAAA,KAAWA,oCAAiB,YAAA,EAAc;AAI5C,IAAA,IACG,OAAA,EAAoD,aACjD,MAAA,KAAW,SAAA;AAEf,MAAA,OAAO,YAAA;AAAA,EACX;AAEA,EAAA,OAAO,YAAA;AACT,CAAA;AAEO,MAAM,iBAAA,GAAoB,CAC/B,IAAA,GAAyC,EAAC,EAC1C,YAAA,GAAyD,EAAC,EAC1D,UAAA,GAAqD,EAAC,EACtD,WAAA,GAAsB,EAAA,KACnB;AACH,EAAA,IAAI,eAA0B,EAAC;AAC/B,EAAA,IAAI,uBAAkC,EAAC;AACvC,EAAA,IAAI,qBAAgC,EAAC;AAErC,EAAA,IAAI,KAAK,MAAA,EAAQ;AACf,IAAA,YAAA,GAAe,IAAA,CAAK,IAAI,CAAA,OAAA,KAAW;AACjC,MAAA,OAAO;AAAA,QACL,MAAMA,mCAAA,CAAiB,IAAA;AAAA,QACvB,KAAA,EAAO,OAAA,CAAQ,QAAA,CAAS,WAAA,EAAY;AAAA,QACpC,IAAA,EAAM,OAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,KAAA;AAAA,QACvB,MAAA,EAAQ,GAAG,OAAA,CAAQ,UAAA,CAAW,IAAI,CAAA,CAAA,EAAI,OAAA,CAAQ,WAAW,IAAI,CAAA,CAAA;AAAA,QAC7D,MAAM,OAAA,EAAS,WAAA;AAAA,QACf,WAAW,OAAA,CAAQ,SAAA;AAAA,QACnB,WAAA;AAAA,QACA,KAAA,EAAO;AAAA,UACL,WAAA,EAAa,OAAA,CAAQ,SAAA,CAAU,YAAA,CAAa,WAAA;AAAA,UAC5C,QAAA,EAAU,OAAA,CAAQ,SAAA,CAAU,YAAA,CAAa,aAAA;AAAA,UACzC,YAAA,EAAc,OAAA,CAAQ,SAAA,CAAU,YAAA,CAAa,WAAA;AAAA,UAC7C,UAAA,EAAY,OAAA,CAAQ,SAAA,CAAU,YAAA,CAAa,QAAA;AAAA,UAC3C,IAAA,EAAM,CAAA,EAAG,OAAA,CAAQ,SAAA,CAAU,YAAA,CAAa,UAAU,CAAA,QAAA,EAAW,OAAA,CAAQ,SAAA,CAAU,YAAA,CAAa,QAAQ,CAAA,CAAA;AAAA,UACpG,MAAA,EAAQ,cAAA,CAAeA,mCAAA,CAAiB,IAAA,EAAM,OAAO;AAAA;AACvD,OACF;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,aAAa,MAAA,EAAQ;AACvB,IAAA,oBAAA,GAAuB,YAAA,CAAa,IAAI,CAAA,OAAA,KAAW;AACjD,MAAA,OAAO;AAAA,QACL,MAAMA,mCAAA,CAAiB,YAAA;AAAA,QACvB,KAAA,EAAO,OAAA,CAAQ,aAAA,CAAc,QAAA,CAAS,WAAA,EAAY;AAAA,QAClD,IAAA,EAAM,QAAQ,aAAA,CAAc,IAAA;AAAA,QAC5B,MAAA,EAAQ,QAAQ,SAAA,CAAU,IAAA;AAAA,QAC1B,IAAA,EAAM,QAAQ,aAAA,CAAc,YAAA;AAAA,QAC5B,SAAA,EAAW,QAAQ,OAAA,CAAQ,IAAA;AAAA,QAC3B,WAAA;AAAA,QACA,KAAA,EAAO;AAAA,UACL,WAAA,EAAa,EAAA;AAAA,UACb,QAAA,EAAU,EAAA;AAAA,UACV,YAAA,EAAc,EAAA;AAAA,UACd,UAAA,EAAY,EAAA;AAAA,UACZ,IAAA,EAAM,EAAA;AAAA,UACN,MAAA,EAAQ,cAAA,CAAeA,mCAAA,CAAiB,YAAA,EAAc,OAAO;AAAA;AAC/D,OACF;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,WAAW,MAAA,EAAQ;AACrB,IAAA,kBAAA,GAAqB,UAAA,CAAW,IAAI,CAAA,OAAA,KAAW;AAC7C,MAAA,OAAO;AAAA,QACL,MAAMA,mCAAA,CAAiB,UAAA;AAAA,QACvB,KAAA,EAAO,OAAA,CAAQ,QAAA,CAAS,WAAA,EAAY;AAAA,QACpC,MAAM,OAAA,CAAQ,eAAA;AAAA,QACd,QAAQ,OAAA,CAAQ,WAAA;AAAA,QAChB,MAAM,OAAA,CAAQ,aAAA;AAAA,QACd,WAAW,OAAA,CAAQ,WAAA;AAAA,QACnB,WAAA;AAAA,QACA,KAAA,EAAO;AAAA,UACL,WAAA,EAAa,EAAA;AAAA,UACb,QAAA,EAAU,EAAA;AAAA,UACV,YAAA,EAAc,EAAA;AAAA,UACd,UAAA,EAAY,EAAA;AAAA,UACZ,IAAA,EAAM,EAAA;AAAA,UACN,MAAA,EAAQ,cAAA,CAAeA,mCAAA,CAAiB,UAAA,EAAY,OAAO;AAAA;AAAA;AAC7D,OACF;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,KAAA,GAAiC;AAAA,IACrC,QAAA,EAAU,CAAA;AAAA,IACV,IAAA,EAAM,CAAA;AAAA,IACN,MAAA,EAAQ,CAAA;AAAA,IACR,GAAA,EAAK;AAAA,GACP;AAEA,EAAA,OAAO,CAAC,GAAG,YAAA,EAAc,GAAG,oBAAA,EAAsB,GAAG,kBAAkB,CAAA,CAAE,IAAA;AAAA,IACvE,CAAC,GAAG,CAAA,KAAM;AACR,MAAA,OAAO,MAAM,CAAA,CAAE,KAAK,CAAA,GAAI,KAAA,CAAM,EAAE,KAAK,CAAA;AAAA,IACvC;AAAA,GACF;AACF;AAEA,MAAM,gBAAA,GAAmB,CAAC,IAAA,GAAO,GAAA,KAAqB;AACpD,EAAA,MAAM,GAAG,WAAW,CAAA,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA;AAEtC,EAAA,MAAM,cAA2B,EAAC;AAClC,EAAA,IAAI,gBAAgB,WAAW,CAAA,CAAE,OAAA,CAAQ,CAAC,KAAK,GAAA,KAAQ;AACrD,IAAA,WAAA,CAAY,GAAG,CAAA,GAAI,GAAA;AAAA,EACrB,CAAC,CAAA;AAED,EAAA,OAAO,WAAA;AACT,CAAA;AAEO,MAAM,oBAAA,GAAuB,OAAU,EAAA,KAAiB;AAC7D,EAAA,MAAM,kBAAA,GAAqB,EAAE,KAAA,EAAO,OAAA,EAAS,QAAQ,GAAA,EAAI;AACzD,EAAA,MAAM,aAAkB,EAAC;AAEzB,EAAA,MAAM,SAAA,GAAY,OAAO,WAAA,KAAuC;AAC9D,IAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,EAAE,aAAa,CAAA;AAEvC,IAAA,UAAA,CAAW,IAAA,CAAK,GAAG,MAAA,CAAO,QAAQ,CAAA;AAElC,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,cAAA,EAAgB,MAAA,EAAQ,IAAA;AAEjD,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,MAAM,cAAA,GAAiB,iBAAiB,SAAS,CAAA;AACjD,MAAA,MAAM,UAAU,cAAc,CAAA;AAAA,IAChC;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,UAAU,kBAAkB,CAAA;AAElC,EAAA,OAAO,UAAA;AACT;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"data.service.helpers.cjs.js","sources":["../../src/service/data.service.helpers.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Entity } from '@backstage/catalog-model';\nimport { match } from 'path-to-regexp';\nimport type { QueryParams } from '../api';\nimport {\n ProjectStatisticsSuccessResponseData,\n OrganizationProjectSuccessResponseData,\n PaginationQueryParams,\n Project,\n CodeFindingSuccessResponseData,\n DependenciesFindingSuccessResponseData,\n ContainersFindingSuccessResponseData,\n Finding,\n StatisticsEngine,\n StatisticsName,\n} from './data.service.types';\nimport { AZURE_HOST_NAME } from '../constants';\n\nenum FINDING_TYPE {\n DEPENDENCIES = 'ALERTS',\n CODE = 'SAST_VULNERABILITIES_BY_SEVERITY',\n CONTAINERS = 'IMG_SECURITY',\n LAST_SCAN = 'LAST_SCAN',\n}\n\ntype OverviewData = {\n projectList: Project[];\n};\n\nexport const dataProjectParser = (\n projectStatistics: Array<\n ProjectStatisticsSuccessResponseData & { entityUrl?: string }\n >,\n organizationProjects: OrganizationProjectSuccessResponseData[],\n) => {\n const organizationData = organizationProjects.reduce((prev, next) => {\n prev[next.uuid] = next;\n return prev;\n }, {} as { [key: string]: OrganizationProjectSuccessResponseData });\n\n const projectData = projectStatistics.reduce(\n (\n prev: OverviewData,\n next: ProjectStatisticsSuccessResponseData & { entityUrl?: string },\n ) => {\n const dependenciesCritical =\n next.statistics[FINDING_TYPE.DEPENDENCIES]\n .criticalSeverityVulnerabilities;\n const dependenciesHigh =\n next.statistics[FINDING_TYPE.DEPENDENCIES].highSeverityVulnerabilities;\n const dependenciesMedium =\n next.statistics[FINDING_TYPE.DEPENDENCIES]\n .mediumSeverityVulnerabilities;\n const dependenciesLow =\n next.statistics[FINDING_TYPE.DEPENDENCIES].lowSeverityVulnerabilities;\n const dependeciesTotal =\n dependenciesCritical +\n dependenciesHigh +\n dependenciesMedium +\n dependenciesLow;\n\n const codeHigh =\n next.statistics[FINDING_TYPE.CODE].sastHighVulnerabilities;\n const codeMedium =\n next.statistics[FINDING_TYPE.CODE].sastMediumVulnerabilities;\n const codeLow = next.statistics[FINDING_TYPE.CODE].sastLowVulnerabilities;\n const codeTotal = codeHigh + codeMedium + codeLow;\n\n const containersCritical =\n next.statistics[FINDING_TYPE.CONTAINERS].imgCriticalVulnerabilities;\n const containersHigh =\n next.statistics[FINDING_TYPE.CONTAINERS].imgHighVulnerabilities;\n const containersMedium =\n next.statistics[FINDING_TYPE.CONTAINERS].imgMediumVulnerabilities;\n const containersLow =\n next.statistics[FINDING_TYPE.CONTAINERS].imgLowVulnerabilities;\n const containersTotal =\n containersCritical + containersHigh + containersMedium + containersLow;\n\n const criticalTotal = dependenciesCritical + containersCritical;\n const highTotal = dependenciesHigh + codeHigh + containersHigh;\n const mediumTotal = dependenciesMedium + codeMedium + containersMedium;\n const lowTotal = dependenciesLow + codeLow + containersLow;\n const total = dependeciesTotal + codeTotal + containersTotal;\n\n const statistics = {\n [StatisticsEngine.DEPENDENCIES]: {\n critical: dependenciesCritical,\n high: dependenciesHigh,\n medium: dependenciesMedium,\n low: dependenciesLow,\n total: dependeciesTotal,\n },\n [StatisticsEngine.CODE]: {\n critical: null,\n high: codeHigh,\n medium: codeMedium,\n low: codeLow,\n total: codeTotal,\n },\n [StatisticsEngine.CONTAINERS]: {\n critical: containersCritical,\n high: containersHigh,\n medium: containersMedium,\n low: containersLow,\n total: containersTotal,\n },\n critical: criticalTotal,\n high: highTotal,\n medium: mediumTotal,\n low: lowTotal,\n total: total,\n };\n\n const project = {\n statistics,\n uuid: next.uuid,\n name: next.name,\n path: next.path,\n entityUrl: next.entityUrl,\n applicationName: organizationData[next.uuid].applicationName,\n applicationUuid: next.applicationUuid,\n lastScan: next.statistics[FINDING_TYPE.LAST_SCAN].lastScanTime,\n languages: next.statistics?.LIBRARY_TYPE_HISTOGRAM\n ? Object.entries(next.statistics.LIBRARY_TYPE_HISTOGRAM).sort(\n (a, b) => b[1] - a[1],\n )\n : ([] as [string, number][]),\n };\n\n prev.projectList.unshift(project);\n return prev;\n },\n {\n projectList: [],\n },\n );\n\n projectData.projectList.sort(\n (a, b) => b.statistics.critical - a.statistics.critical,\n );\n\n return projectData;\n};\n\nexport const parseEntityURL = (entityUrl?: string) => {\n try {\n if (!entityUrl) {\n return null;\n }\n\n // Extract the base URL (remove \"url:\" prefix if present)\n const cleanUrl = entityUrl.replace(/^url:/, '');\n const matches = cleanUrl.match(\n /https?:\\/\\/[a-zA-Z0-9\\-\\.]+\\.[a-zA-Z]{2,}(:[0-9]{1,5})?(\\/.*)?/g,\n );\n\n if (!matches) {\n return null;\n }\n const url = new URL(matches[0]);\n const hostname = url.host.toLowerCase();\n\n // Handle different SCM providers using path-to-regexp patterns\n let path;\n if (hostname === AZURE_HOST_NAME) {\n // Azure DevOps format: /org/project/_git/repo\n const matcher = match('/:org/:project/_git/:repo', { end: false });\n const extracted = matcher(url.pathname);\n if (extracted) {\n path = `/${extracted.params.org}/${extracted.params.project}/_git/${extracted.params.repo}`;\n }\n } else if (hostname.includes('gitlab')) {\n // GitLab format: /org/repo or /group/subgroup/.../repo\n // Remove GitLab-specific parts like /-/tree/branch\n const cleanPath = url.pathname.replace(/\\/-\\/(tree|blob)\\/[^\\/]+.*$/, '');\n\n // Use a pattern that matches any number of segments between org and repo\n const matcher = match('/:org/:repo', { end: false });\n const extracted = matcher(cleanPath);\n\n if (extracted) {\n // For GitLab, preserve the full path structure to support subgroups\n path = cleanPath;\n }\n } else {\n // GitHub and Bitbucket format: /org/repo\n const matcher = match('/:org/:repo', { end: false });\n const extracted = matcher(url.pathname);\n if (extracted) {\n path = `/${extracted.params.org}/${extracted.params.repo}`;\n }\n }\n\n return path ? { host: hostname, path } : null;\n } catch (error) {\n return null;\n }\n};\n\n/**\n * Generates entity URL for Backstage navigation\n * @param entity - Backstage entity\n * @returns Entity URL string or null if unable to generate\n */\nexport const generateEntityUrl = (entity: Entity): string | null => {\n try {\n const source = 'catalog';\n const namespace = entity?.metadata?.namespace;\n const kind = entity?.kind?.toLowerCase();\n const entityName = entity?.metadata?.name;\n\n if (!namespace || !kind || !entityName) {\n return null;\n }\n\n return `/${source}/${namespace}/${kind}/${entityName}`;\n } catch (error) {\n return null;\n }\n};\n\nexport const dataMatcher = (\n entities: Entity[],\n projects: ProjectStatisticsSuccessResponseData[],\n) => {\n const projectSourceURL = getSourceURLWiseProject(projects);\n return entities.reduce(\n (\n prev: Array<\n ProjectStatisticsSuccessResponseData & { entityUrl?: string }\n >,\n next: Entity,\n ) => {\n const parsedSourceLocation = parseEntityURL(\n next?.metadata?.annotations?.['backstage.io/source-location'],\n );\n\n if (!parsedSourceLocation) {\n return prev;\n }\n\n // NOTE: Find project based on Github URL\n const relatedProjects =\n projectSourceURL[\n `${parsedSourceLocation?.host}${parsedSourceLocation?.path}`\n ]?.projectObjs;\n\n if (!relatedProjects) {\n return prev;\n }\n\n const entityUrl = generateEntityUrl(next);\n\n relatedProjects.forEach(project =>\n prev.push({ ...project, entityUrl: entityUrl ?? undefined }),\n );\n\n return prev;\n },\n [],\n );\n};\n\n/**\n * Extracts the source URL details from each project and returns a dictionary\n * where each key is a combination of the URL's host and pathname,\n * and the value is an object containing the original project and the parsed source URL data.\n *\n * @param projects Array of ProjectStatisticsSuccessResponseData\n * @returns A dictionary object with keys as `${host}${pathname}` strings extracted from sourceUrl and values as:\n * {\n * projectObjs: ProjectStatisticsSuccessResponseData[];\n sourceUrl: string | null;\n host: string | null;\n pathname: string | null;\n * }\n */\nexport function getSourceURLWiseProject(\n projects: ProjectStatisticsSuccessResponseData[],\n) {\n return projects.reduce(\n (acc, project) => {\n const projectTags = project.tags as Array<{ key: string; value: string }>;\n const sourceUrlTag = projectTags?.find(tag => tag.key === 'sourceUrl');\n let host = null;\n let pathname = null;\n let sourceUrl = null;\n\n if (sourceUrlTag && typeof sourceUrlTag.value === 'string') {\n sourceUrl = sourceUrlTag.value;\n const urlString = sourceUrl.startsWith('http')\n ? sourceUrl\n : `https://${sourceUrl}`;\n\n try {\n const urlObj = new URL(urlString);\n host = urlObj.host.toLocaleLowerCase();\n // Remove leading/trailing slashes and split\n pathname = urlObj.pathname;\n } catch (e) {\n // fallback: leave as nulls\n }\n }\n\n if (acc[`${host}${pathname}`]) {\n acc[`${host}${pathname}`].projectObjs.push(project);\n } else {\n acc[`${host}${pathname}`] = {\n projectObjs: [project],\n sourceUrl,\n host,\n pathname,\n };\n }\n return acc;\n },\n {} as Record<\n string,\n {\n projectObjs: ProjectStatisticsSuccessResponseData[];\n sourceUrl: string | null;\n host: string | null;\n pathname: string | null;\n }\n >,\n );\n}\n\nconst getIssueStatus = (\n engine: StatisticsEngine,\n finding:\n | CodeFindingSuccessResponseData\n | DependenciesFindingSuccessResponseData\n | ContainersFindingSuccessResponseData,\n): string => {\n if (engine === StatisticsEngine.CODE) {\n if ((finding as CodeFindingSuccessResponseData)?.suppressed)\n return 'suppressed';\n if (\n (finding as CodeFindingSuccessResponseData)?.almIssues?.jiraPlatform\n ?.issueStatus\n )\n return 'created';\n if ((finding as CodeFindingSuccessResponseData)?.reviewed)\n return 'reviewed';\n }\n\n if (engine === StatisticsEngine.DEPENDENCIES) {\n // NOTE: Available status: IGNORED and ACTIVE\n // ACTIVE means unreviewed\n // IGNORED means suppressed, comment fields are available to this status\n if (\n (finding as DependenciesFindingSuccessResponseData)?.findingInfo\n ?.status === 'IGNORED'\n )\n return 'suppressed';\n }\n\n return 'unreviewed';\n};\n\nexport const dataFindingParser = (\n code: CodeFindingSuccessResponseData[] = [],\n dependencies: DependenciesFindingSuccessResponseData[] = [],\n containers: ContainersFindingSuccessResponseData[] = [],\n projectName: string = '',\n) => {\n let codeFindings: Finding[] = [];\n let dependenciesFindings: Finding[] = [];\n let containersFindings: Finding[] = [];\n\n if (code.length) {\n codeFindings = code.map(finding => {\n return {\n kind: StatisticsEngine.CODE,\n level: finding.severity.toLowerCase() as StatisticsName,\n name: finding.type.cwe.title,\n origin: `${finding.sharedStep.file}:${finding.sharedStep.line}`,\n time: finding?.createdTime,\n projectId: finding.projectId,\n projectName: projectName,\n issue: {\n issueStatus: finding.almIssues.jiraPlatform.issueStatus,\n reporter: finding.almIssues.jiraPlatform.createdByName,\n creationDate: finding.almIssues.jiraPlatform.createdTime,\n ticketName: finding.almIssues.jiraPlatform.issueKey,\n link: `${finding.almIssues.jiraPlatform.publicLink}/browse/${finding.almIssues.jiraPlatform.issueKey}`,\n status: getIssueStatus(StatisticsEngine.CODE, finding),\n },\n };\n });\n }\n\n if (dependencies.length) {\n dependenciesFindings = dependencies.map(finding => {\n return {\n kind: StatisticsEngine.DEPENDENCIES,\n level: finding.vulnerability.severity.toLowerCase() as StatisticsName,\n name: finding.vulnerability.name,\n origin: finding.component.name,\n time: finding.vulnerability.modifiedDate,\n projectId: finding.project.uuid,\n projectName: projectName,\n issue: {\n issueStatus: '',\n reporter: '',\n creationDate: '',\n ticketName: '',\n link: '',\n status: getIssueStatus(StatisticsEngine.DEPENDENCIES, finding),\n },\n };\n });\n }\n\n if (containers.length) {\n containersFindings = containers.map(finding => {\n return {\n kind: StatisticsEngine.CONTAINERS,\n level: finding.severity.toLowerCase() as StatisticsName,\n name: finding.vulnerabilityId,\n origin: finding.packageName,\n time: finding.detectionDate,\n projectId: finding.projectUuid,\n projectName: projectName,\n issue: {\n issueStatus: '',\n reporter: '',\n creationDate: '',\n ticketName: '',\n link: '',\n status: getIssueStatus(StatisticsEngine.CONTAINERS, finding), // NOTE: Currently, issue for finding in containers no exist.\n },\n };\n });\n }\n\n const order: { [k: string]: number } = {\n critical: 1,\n high: 2,\n medium: 3,\n low: 4,\n };\n\n return [...codeFindings, ...dependenciesFindings, ...containersFindings].sort(\n (a, b) => {\n return order[a.level] - order[b.level];\n },\n );\n};\n\nconst parseQueryString = (href = '?'): QueryParams => {\n const [, queryString] = href.split('?');\n\n const queryParams: QueryParams = {};\n new URLSearchParams(queryString).forEach((val, key) => {\n queryParams[key] = val;\n });\n\n return queryParams;\n};\n\nexport const fetchQueryPagination = async <T>(cb: Function) => {\n const defaultQueryParams = { limit: '10000', cursor: '0' };\n const collection: T[] = [];\n\n const fetchLoop = async (queryParams: PaginationQueryParams) => {\n const result = await cb({ queryParams });\n\n collection.push(...result.response);\n\n const nextQuery = result.additionalData?.paging?.next;\n\n if (nextQuery) {\n const newQueryParams = parseQueryString(nextQuery);\n await fetchLoop(newQueryParams);\n }\n };\n\n await fetchLoop(defaultQueryParams);\n\n return collection;\n};\n"],"names":["StatisticsEngine","AZURE_HOST_NAME","match"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.service.types.cjs.js","sources":["../../src/service/data.service.types.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport type PaginationQueryParams = {\n cursor?: string;\n limit?: string;\n};\n\ntype PaginationSuccessResponseData = {\n additionalData: {\n totalItems: number;\n paging: {\n next?: string;\n };\n };\n};\n\ntype BodyParams = {\n projectUuids?: string[];\n applicationUuid?: string[];\n};\n\ntype PathParams = {\n uuid: string;\n};\n\nexport type GetOrganizationProjectRequestData = {\n queryParams?: PaginationQueryParams;\n};\n\nexport type OrganizationProjectSuccessResponseData = {\n uuid: string;\n name: string;\n path: string;\n applicationName: string;\n applicationUuid: string;\n};\n\nexport type GetOrganizationProjectSuccessResponseData = {\n supportToken: string;\n response: OrganizationProjectSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type GetProjectStatisticsRequestData = {\n queryParams?: PaginationQueryParams;\n bodyParams?: BodyParams;\n};\n\nexport type ProjectStatisticsSuccessResponseData = {\n uuid: string;\n name: string;\n path: string;\n applicationUuid: string;\n creationDate: string;\n tags: [];\n labels: [];\n statistics: {\n UNIFIED_VULNERABILITIES: {\n unifiedCriticalVulnerabilities: number;\n unifiedHighVulnerabilities: number;\n unifiedMediumVulnerabilities: number;\n unifiedLowVulnerabilities: number;\n unifiedVulnerabilities: number;\n };\n VULNERABILITY_EFFECTIVENESS: {};\n LIBRARY_TYPE_HISTOGRAM: Record<string, number>;\n IMG_USAGE: {};\n POLICY_VIOLATION_LIBRARIES: {\n policyViolatingLibraries: number;\n };\n SAST_VULNERABILITIES_BY_TYPE: Record<string, number>;\n GENERAL: {\n totalLibraries: number;\n };\n LLM_SECURITY: {\n llmTotalLines: number;\n };\n IMG_SECURITY: {\n imgCriticalVulnerabilities: number;\n imgMaxRiskScore: number;\n imgMediumVulnerabilities: number;\n imgLowVulnerabilities: number;\n imgSecretMediumVulnerabilities: number;\n imgUnknownVulnerabilities: number;\n imgSecretHighVulnerabilities: number;\n imgTotalVulnerabilities: number;\n imgHighVulnerabilities: number;\n imgSecretCriticalVulnerabilities: number;\n imgSecretLowVulnerabilities: number;\n };\n ALERTS: {\n criticalSeverityVulnerabilities: number;\n highSeverityVulnerabilities: number;\n vulnerableLibraries: number;\n mediumSeverityVulnerabilities: number;\n lowSeverityVulnerabilities: number;\n };\n OUTDATED_LIBRARIES: {\n outdatedLibraries: number;\n };\n POLICY_VIOLATIONS: {};\n SAST_SCAN: {\n sastTotalLines: number;\n sastTestedFiles: number;\n sastTotalFiles: number;\n sastTestedLines: number;\n sastTotalMended: number;\n sastTotalRemediations: number;\n };\n VULNERABILITY_SEVERITY_LIBRARIES: {\n lowSeverityLibraries: number;\n highSeverityLibraries: number;\n mediumSeverityLibraries: number;\n criticalSeverityLibraries: number;\n };\n LICENSE_RISK: {\n highRiskLicenses: number;\n mediumRiskLicenses: number;\n lowRiskLicenses: number;\n };\n IAC_SECURITY: {\n iacCriticalMisconfigurations: number;\n iacHighMisconfigurations: number;\n iacTotalMisconfigurations: number;\n iacLowMisconfigurations: number;\n iacMediumMisconfigurations: number;\n };\n SCA_SECURITY: {};\n LICENSE_HISTOGRAM: Record<string, number>;\n SAST_VULNERABILITIES_BY_SEVERITY: {\n sastVulnerabilities: number;\n sastHighVulnerabilities: number;\n sastMediumVulnerabilities: number;\n sastLowVulnerabilities: number;\n };\n LAST_SCAN: {\n lastScanTime: number;\n lastScaScanTime: number;\n lastImgScanTime: number;\n lastSastScanTime: number;\n };\n };\n};\n\nexport type GetProjectStatisticsSuccessResponseData = {\n supportToken: string;\n response: ProjectStatisticsSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type EntityURL = {\n path: string;\n params: {\n org?: string;\n repo?: string;\n };\n namespace?: string;\n kind: string;\n source: string;\n};\n\nexport enum StatisticsName {\n CRITICAL = 'critical',\n HIGH = 'high',\n MEDIUM = 'medium',\n LOW = 'low',\n TOTAL = 'total',\n}\n\nexport enum StatisticsEngine {\n DEPENDENCIES = 'dependencies',\n CODE = 'code',\n CONTAINERS = 'containers',\n}\n\ntype StatisticsBase = {\n [StatisticsName.CRITICAL]: number;\n [StatisticsName.HIGH]: number;\n [StatisticsName.MEDIUM]: number;\n [StatisticsName.LOW]: number;\n [StatisticsName.TOTAL]: number;\n};\n\nexport type Statistics = {\n [StatisticsEngine.DEPENDENCIES]: StatisticsBase;\n [StatisticsEngine.CODE]: Omit<StatisticsBase, StatisticsName.CRITICAL> & {\n [StatisticsName.CRITICAL]: null;\n };\n [StatisticsEngine.CONTAINERS]: StatisticsBase;\n} & StatisticsBase;\n\nexport type Project = {\n statistics: Statistics;\n uuid: string;\n name: string;\n path: string;\n applicationName: string;\n applicationUuid: string;\n lastScan: number;\n languages: Array<[string, number]>;\n entity: EntityURL;\n};\n\n// Code Finding API Data\ntype CodeFindingDataFlowSuccessResponseData = {\n id: string;\n sink: string;\n sinkKind: string;\n sinkFile: string;\n sinkSnippet: string;\n sinkLine: number;\n inputSource: string;\n inputKind: string;\n inputFlow: [\n {\n name: string;\n kind: string;\n file: string;\n snippet: string;\n line: number;\n startLine: number;\n endLine: number;\n },\n ];\n functionCalls: [\n {\n name: string;\n kind: string;\n file: string;\n snippet: string;\n line: number;\n startLine: number;\n endLine: number;\n },\n ];\n filter: {\n isFiltered: boolean;\n filterTypes: unknown[];\n };\n isNew: boolean;\n rating: number;\n confidenceRating: number;\n ageRating: number;\n};\n\nexport type CodeFindingSuccessResponseData = {\n id: string;\n scanId: string;\n snapshotId: string;\n projectId: string;\n appId: string;\n type: {\n id: number;\n name: string;\n engineId: number;\n language: string;\n sarif: string;\n sarifLevel: string;\n order: number;\n severity: StatisticsName;\n severityRating: number;\n description: string;\n recommendations: [string];\n references: [string];\n cwe: {\n id: string;\n title: string;\n url: string;\n };\n pcidss: {\n section: string;\n title: string;\n };\n nist: {\n control: string;\n priority: string;\n title: string;\n url: string;\n };\n hipaa: {\n control: string;\n title: string;\n };\n hitrust: {\n control: string;\n title: string;\n };\n owasp: {\n index: string;\n title: string;\n url: string;\n };\n owasp2021: {\n index: string;\n title: string;\n url: string;\n };\n capec: {\n id: string;\n title: string;\n url: string;\n };\n sansTop25: {\n rank: number;\n title: string;\n };\n };\n description: string;\n createdTime: string;\n isNew: boolean;\n severity: StatisticsName;\n baseline: boolean;\n hasRemediation: boolean;\n suppressed: boolean;\n suppressedBy: string;\n suppressionTime: string;\n suppressionMessage: string;\n reviewed: boolean;\n IssueStatus: number;\n sharedStep: {\n name: string;\n kind: string;\n file: string;\n snippet: string;\n line: number;\n startLine: number;\n endLine: number;\n lineBlame: {\n commitId: string;\n file: string;\n line: number;\n };\n };\n dataFlows: CodeFindingDataFlowSuccessResponseData[];\n severityRating: number;\n confidenceRating: number;\n ageRating: number;\n rating: number;\n almIssues: {\n jira: {\n issueId: string;\n project: string;\n };\n azure: {\n workItemId: number;\n project: string;\n };\n jiraPlatform: {\n internalStatus: string;\n issueStatus: string;\n issueKey: string;\n publicLink: string;\n createdTime: string;\n createdBy: string;\n createdByName: string;\n };\n };\n comments: unknown[];\n};\n\nexport type GetCodeFindingSuccessResponseData = {\n response: CodeFindingSuccessResponseData[];\n supportToken: string;\n} & PaginationSuccessResponseData;\n\nexport type GetCodeFindingsRequestData = {\n queryParams?: PaginationQueryParams;\n pathParams: PathParams;\n};\n\n// Dependencies Finding API Data\nexport type DependenciesFindingSuccessResponseData = {\n uuid: string;\n name: string;\n type: string;\n component: {\n uuid: string;\n name: string;\n description: string;\n componentType: string;\n libraryType: string;\n rootLibrary: boolean;\n references: {\n url: string;\n homePage: string;\n genericPackageIndex: string;\n };\n groupId: string;\n artifactId: string;\n version: string;\n path: string;\n };\n findingInfo: {\n status: string;\n comment: unknown;\n detectedAt: string;\n modifiedAt: string;\n };\n project: {\n uuid: string;\n name: string;\n path: string;\n applicationUuid: string;\n };\n application: {\n uuid: string;\n name: string;\n };\n vulnerability: {\n name: string;\n type: string;\n description: string;\n score: number;\n severity: StatisticsName;\n publishDate: string;\n modifiedDate: string;\n vulnerabilityScoring: {\n score: number;\n severity: string;\n type: string;\n }[];\n };\n topFix: {\n id: number;\n vulnerability: string;\n type: string;\n origin: string;\n url: string;\n fixResolution: string;\n date: string;\n message: string;\n };\n effective: string;\n threatAssessment: {\n exploitCodeMaturity: string;\n epssPercentage: number;\n };\n exploitable: boolean;\n scoreMetadataVector: string;\n};\n\nexport type GetDependenciesFindingSuccessResponseData = {\n supportToken: string;\n response: DependenciesFindingSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type GetDependenciesFindingsRequestData = {\n queryParams?: PaginationQueryParams;\n pathParams: PathParams;\n};\n\n// Containers Finding API Data\nexport type ContainersFindingSuccessResponseData = {\n uuid: string;\n vulnerabilityId: string;\n description: string;\n projectUuid: string;\n imageName: string;\n packageName: string;\n packageVersion: string;\n severity: StatisticsName;\n cvss: number;\n epss: number;\n hasFix: false;\n fixVersion: string;\n publishedDate: string;\n detectionDate: string;\n};\n\nexport type GetContainersFindingSuccessResponseData = {\n supportToken: string;\n response: ContainersFindingSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type GetContainersFindingsRequestData = {\n queryParams?: PaginationQueryParams;\n pathParams: PathParams;\n};\n\nexport type Finding = {\n kind: StatisticsEngine;\n level: StatisticsName;\n name: string;\n origin: string;\n time: string;\n projectId: string;\n projectName: string;\n issue: {\n issueStatus: string;\n reporter: string;\n creationDate: string;\n ticketName: string;\n link: string;\n status: string;\n };\n};\n"],"names":["StatisticsEngine"],"mappings":";;AAoLO,IAAK,gBAAA,qBAAAA,iBAAAA,KAAL;AACL,EAAAA,kBAAA,cAAA,CAAA,GAAe,cAAA;AACf,EAAAA,kBAAA,MAAA,CAAA,GAAO,MAAA;AACP,EAAAA,kBAAA,YAAA,CAAA,GAAa,YAAA;AAHH,EAAA,OAAAA,iBAAAA;AAAA,CAAA,EAAA,gBAAA,IAAA,EAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"data.service.types.cjs.js","sources":["../../src/service/data.service.types.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport type PaginationQueryParams = {\n cursor?: string;\n limit?: string;\n};\n\ntype PaginationSuccessResponseData = {\n additionalData: {\n totalItems: number;\n paging: {\n next?: string;\n };\n };\n};\n\ntype BodyParams = {\n projectUuids?: string[];\n applicationUuid?: string[];\n};\n\ntype PathParams = {\n uuid: string;\n};\n\nexport type GetOrganizationProjectRequestData = {\n queryParams?: PaginationQueryParams;\n};\n\nexport type OrganizationProjectSuccessResponseData = {\n uuid: string;\n name: string;\n path: string;\n applicationName: string;\n applicationUuid: string;\n};\n\nexport type GetOrganizationProjectSuccessResponseData = {\n supportToken: string;\n response: OrganizationProjectSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type GetProjectStatisticsRequestData = {\n queryParams?: PaginationQueryParams;\n bodyParams?: BodyParams;\n};\n\nexport type ProjectStatisticsSuccessResponseData = {\n uuid: string;\n name: string;\n path: string;\n applicationUuid: string;\n creationDate: string;\n tags: [];\n labels: [];\n statistics: {\n UNIFIED_VULNERABILITIES: {\n unifiedCriticalVulnerabilities: number;\n unifiedHighVulnerabilities: number;\n unifiedMediumVulnerabilities: number;\n unifiedLowVulnerabilities: number;\n unifiedVulnerabilities: number;\n };\n VULNERABILITY_EFFECTIVENESS: {};\n LIBRARY_TYPE_HISTOGRAM: Record<string, number>;\n IMG_USAGE: {};\n POLICY_VIOLATION_LIBRARIES: {\n policyViolatingLibraries: number;\n };\n SAST_VULNERABILITIES_BY_TYPE: Record<string, number>;\n GENERAL: {\n totalLibraries: number;\n };\n LLM_SECURITY: {\n llmTotalLines: number;\n };\n IMG_SECURITY: {\n imgCriticalVulnerabilities: number;\n imgMaxRiskScore: number;\n imgMediumVulnerabilities: number;\n imgLowVulnerabilities: number;\n imgSecretMediumVulnerabilities: number;\n imgUnknownVulnerabilities: number;\n imgSecretHighVulnerabilities: number;\n imgTotalVulnerabilities: number;\n imgHighVulnerabilities: number;\n imgSecretCriticalVulnerabilities: number;\n imgSecretLowVulnerabilities: number;\n };\n ALERTS: {\n criticalSeverityVulnerabilities: number;\n highSeverityVulnerabilities: number;\n vulnerableLibraries: number;\n mediumSeverityVulnerabilities: number;\n lowSeverityVulnerabilities: number;\n };\n OUTDATED_LIBRARIES: {\n outdatedLibraries: number;\n };\n POLICY_VIOLATIONS: {};\n SAST_SCAN: {\n sastTotalLines: number;\n sastTestedFiles: number;\n sastTotalFiles: number;\n sastTestedLines: number;\n sastTotalMended: number;\n sastTotalRemediations: number;\n };\n VULNERABILITY_SEVERITY_LIBRARIES: {\n lowSeverityLibraries: number;\n highSeverityLibraries: number;\n mediumSeverityLibraries: number;\n criticalSeverityLibraries: number;\n };\n LICENSE_RISK: {\n highRiskLicenses: number;\n mediumRiskLicenses: number;\n lowRiskLicenses: number;\n };\n IAC_SECURITY: {\n iacCriticalMisconfigurations: number;\n iacHighMisconfigurations: number;\n iacTotalMisconfigurations: number;\n iacLowMisconfigurations: number;\n iacMediumMisconfigurations: number;\n };\n SCA_SECURITY: {};\n LICENSE_HISTOGRAM: Record<string, number>;\n SAST_VULNERABILITIES_BY_SEVERITY: {\n sastVulnerabilities: number;\n sastHighVulnerabilities: number;\n sastMediumVulnerabilities: number;\n sastLowVulnerabilities: number;\n };\n LAST_SCAN: {\n lastScanTime: number;\n lastScaScanTime: number;\n lastImgScanTime: number;\n lastSastScanTime: number;\n };\n };\n};\n\nexport type GetProjectStatisticsSuccessResponseData = {\n supportToken: string;\n response: ProjectStatisticsSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport enum StatisticsName {\n CRITICAL = 'critical',\n HIGH = 'high',\n MEDIUM = 'medium',\n LOW = 'low',\n TOTAL = 'total',\n}\n\nexport enum StatisticsEngine {\n DEPENDENCIES = 'dependencies',\n CODE = 'code',\n CONTAINERS = 'containers',\n}\n\ntype StatisticsBase = {\n [StatisticsName.CRITICAL]: number;\n [StatisticsName.HIGH]: number;\n [StatisticsName.MEDIUM]: number;\n [StatisticsName.LOW]: number;\n [StatisticsName.TOTAL]: number;\n};\n\nexport type Statistics = {\n [StatisticsEngine.DEPENDENCIES]: StatisticsBase;\n [StatisticsEngine.CODE]: Omit<StatisticsBase, StatisticsName.CRITICAL> & {\n [StatisticsName.CRITICAL]: null;\n };\n [StatisticsEngine.CONTAINERS]: StatisticsBase;\n} & StatisticsBase;\n\nexport type Project = {\n statistics: Statistics;\n uuid: string;\n name: string;\n path: string;\n applicationName: string;\n applicationUuid: string;\n lastScan: number;\n languages: Array<[string, number]>;\n entityUrl?: string;\n};\n\n// Code Finding API Data\ntype CodeFindingDataFlowSuccessResponseData = {\n id: string;\n sink: string;\n sinkKind: string;\n sinkFile: string;\n sinkSnippet: string;\n sinkLine: number;\n inputSource: string;\n inputKind: string;\n inputFlow: [\n {\n name: string;\n kind: string;\n file: string;\n snippet: string;\n line: number;\n startLine: number;\n endLine: number;\n },\n ];\n functionCalls: [\n {\n name: string;\n kind: string;\n file: string;\n snippet: string;\n line: number;\n startLine: number;\n endLine: number;\n },\n ];\n filter: {\n isFiltered: boolean;\n filterTypes: unknown[];\n };\n isNew: boolean;\n rating: number;\n confidenceRating: number;\n ageRating: number;\n};\n\nexport type CodeFindingSuccessResponseData = {\n id: string;\n scanId: string;\n snapshotId: string;\n projectId: string;\n appId: string;\n type: {\n id: number;\n name: string;\n engineId: number;\n language: string;\n sarif: string;\n sarifLevel: string;\n order: number;\n severity: StatisticsName;\n severityRating: number;\n description: string;\n recommendations: [string];\n references: [string];\n cwe: {\n id: string;\n title: string;\n url: string;\n };\n pcidss: {\n section: string;\n title: string;\n };\n nist: {\n control: string;\n priority: string;\n title: string;\n url: string;\n };\n hipaa: {\n control: string;\n title: string;\n };\n hitrust: {\n control: string;\n title: string;\n };\n owasp: {\n index: string;\n title: string;\n url: string;\n };\n owasp2021: {\n index: string;\n title: string;\n url: string;\n };\n capec: {\n id: string;\n title: string;\n url: string;\n };\n sansTop25: {\n rank: number;\n title: string;\n };\n };\n description: string;\n createdTime: string;\n isNew: boolean;\n severity: StatisticsName;\n baseline: boolean;\n hasRemediation: boolean;\n suppressed: boolean;\n suppressedBy: string;\n suppressionTime: string;\n suppressionMessage: string;\n reviewed: boolean;\n IssueStatus: number;\n sharedStep: {\n name: string;\n kind: string;\n file: string;\n snippet: string;\n line: number;\n startLine: number;\n endLine: number;\n lineBlame: {\n commitId: string;\n file: string;\n line: number;\n };\n };\n dataFlows: CodeFindingDataFlowSuccessResponseData[];\n severityRating: number;\n confidenceRating: number;\n ageRating: number;\n rating: number;\n almIssues: {\n jira: {\n issueId: string;\n project: string;\n };\n azure: {\n workItemId: number;\n project: string;\n };\n jiraPlatform: {\n internalStatus: string;\n issueStatus: string;\n issueKey: string;\n publicLink: string;\n createdTime: string;\n createdBy: string;\n createdByName: string;\n };\n };\n comments: unknown[];\n};\n\nexport type GetCodeFindingSuccessResponseData = {\n response: CodeFindingSuccessResponseData[];\n supportToken: string;\n} & PaginationSuccessResponseData;\n\nexport type GetCodeFindingsRequestData = {\n queryParams?: PaginationQueryParams;\n pathParams: PathParams;\n};\n\n// Dependencies Finding API Data\nexport type DependenciesFindingSuccessResponseData = {\n uuid: string;\n name: string;\n type: string;\n component: {\n uuid: string;\n name: string;\n description: string;\n componentType: string;\n libraryType: string;\n rootLibrary: boolean;\n references: {\n url: string;\n homePage: string;\n genericPackageIndex: string;\n };\n groupId: string;\n artifactId: string;\n version: string;\n path: string;\n };\n findingInfo: {\n status: string;\n comment: unknown;\n detectedAt: string;\n modifiedAt: string;\n };\n project: {\n uuid: string;\n name: string;\n path: string;\n applicationUuid: string;\n };\n application: {\n uuid: string;\n name: string;\n };\n vulnerability: {\n name: string;\n type: string;\n description: string;\n score: number;\n severity: StatisticsName;\n publishDate: string;\n modifiedDate: string;\n vulnerabilityScoring: {\n score: number;\n severity: string;\n type: string;\n }[];\n };\n topFix: {\n id: number;\n vulnerability: string;\n type: string;\n origin: string;\n url: string;\n fixResolution: string;\n date: string;\n message: string;\n };\n effective: string;\n threatAssessment: {\n exploitCodeMaturity: string;\n epssPercentage: number;\n };\n exploitable: boolean;\n scoreMetadataVector: string;\n};\n\nexport type GetDependenciesFindingSuccessResponseData = {\n supportToken: string;\n response: DependenciesFindingSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type GetDependenciesFindingsRequestData = {\n queryParams?: PaginationQueryParams;\n pathParams: PathParams;\n};\n\n// Containers Finding API Data\nexport type ContainersFindingSuccessResponseData = {\n uuid: string;\n vulnerabilityId: string;\n description: string;\n projectUuid: string;\n imageName: string;\n packageName: string;\n packageVersion: string;\n severity: StatisticsName;\n cvss: number;\n epss: number;\n hasFix: false;\n fixVersion: string;\n publishedDate: string;\n detectionDate: string;\n};\n\nexport type GetContainersFindingSuccessResponseData = {\n supportToken: string;\n response: ContainersFindingSuccessResponseData[];\n} & PaginationSuccessResponseData;\n\nexport type GetContainersFindingsRequestData = {\n queryParams?: PaginationQueryParams;\n pathParams: PathParams;\n};\n\nexport type Finding = {\n kind: StatisticsEngine;\n level: StatisticsName;\n name: string;\n origin: string;\n time: string;\n projectId: string;\n projectName: string;\n issue: {\n issueStatus: string;\n reporter: string;\n creationDate: string;\n ticketName: string;\n link: string;\n status: string;\n };\n};\n"],"names":["StatisticsEngine"],"mappings":";;AAyKO,IAAK,gBAAA,qBAAAA,iBAAAA,KAAL;AACL,EAAAA,kBAAA,cAAA,CAAA,GAAe,cAAA;AACf,EAAAA,kBAAA,MAAA,CAAA,GAAO,MAAA;AACP,EAAAA,kBAAA,YAAA,CAAA,GAAa,YAAA;AAHH,EAAA,OAAAA,iBAAAA;AAAA,CAAA,EAAA,gBAAA,IAAA,EAAA;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage-community/plugin-mend-backend",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"main": "dist/index.cjs.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"postpack": "backstage-cli package postpack"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@backstage/backend-defaults": "^0.
|
|
41
|
-
"@backstage/backend-plugin-api": "^1.
|
|
42
|
-
"@backstage/catalog-client": "^1.
|
|
40
|
+
"@backstage/backend-defaults": "^0.15.2",
|
|
41
|
+
"@backstage/backend-plugin-api": "^1.7.0",
|
|
42
|
+
"@backstage/catalog-client": "^1.13.0",
|
|
43
43
|
"@backstage/catalog-model": "^1.7.6",
|
|
44
44
|
"@backstage/config": "^1.3.6",
|
|
45
|
-
"@backstage/plugin-permission-common": "^0.9.
|
|
46
|
-
"@backstage/plugin-permission-node": "^0.10.
|
|
45
|
+
"@backstage/plugin-permission-common": "^0.9.6",
|
|
46
|
+
"@backstage/plugin-permission-node": "^0.10.10",
|
|
47
47
|
"@types/express": "^4.17.6",
|
|
48
48
|
"express": "^4.17.1",
|
|
49
49
|
"express-promise-router": "^4.1.0",
|
|
@@ -55,11 +55,11 @@
|
|
|
55
55
|
"zod": "^3.23.8"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@backstage/backend-test-utils": "^1.
|
|
59
|
-
"@backstage/cli": "^0.35.
|
|
60
|
-
"@backstage/plugin-auth-backend": "^0.
|
|
61
|
-
"@backstage/plugin-auth-backend-module-guest-provider": "^0.2.
|
|
62
|
-
"@backstage/plugin-catalog-backend": "^3.
|
|
58
|
+
"@backstage/backend-test-utils": "^1.11.0",
|
|
59
|
+
"@backstage/cli": "^0.35.4",
|
|
60
|
+
"@backstage/plugin-auth-backend": "^0.27.0",
|
|
61
|
+
"@backstage/plugin-auth-backend-module-guest-provider": "^0.2.16",
|
|
62
|
+
"@backstage/plugin-catalog-backend": "^3.4.0",
|
|
63
63
|
"@types/supertest": "^6.0.0",
|
|
64
64
|
"msw": "^1.0.0",
|
|
65
65
|
"supertest": "^7.0.0"
|