@red-hat-developer-hub/backstage-plugin-bulk-import-backend 7.3.7 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @red-hat-developer-hub/backstage-plugin-bulk-import-backend
2
2
 
3
+ ## 8.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 02db099: Backstage version bump to v1.52.0
8
+
9
+ ### Patch Changes
10
+
11
+ - 8eb345e: Updated dependency `js-yaml` to `^4.3.0`.
12
+ - Updated dependencies [02db099]
13
+ - @red-hat-developer-hub/backstage-plugin-bulk-import-common@8.0.0
14
+
3
15
  ## 7.3.7
4
16
 
5
17
  ### Patch Changes
@@ -0,0 +1,21 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "properties": {
5
+ "bulkImport": {
6
+ "type": "object",
7
+ "properties": {
8
+ "importTemplate": {
9
+ "type": "string",
10
+ "description": "The name of the scaffolder template or entity reference to execute for importing a repository.",
11
+ "visibility": "backend"
12
+ },
13
+ "orchestratorWorkflow": {
14
+ "type": "string",
15
+ "description": "The orchestrator workflow id to execute for importing a repository.",
16
+ "visibility": "backend"
17
+ }
18
+ }
19
+ }
20
+ }
21
+ }
@@ -1,53 +1,43 @@
1
1
  'use strict';
2
2
 
3
- var fetch = require('node-fetch');
4
- var auth = require('../helpers/auth.cjs.js');
3
+ require('@backstage/errors');
4
+ require('@backstage/plugin-permission-common');
5
+ require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
6
+ require('just-kebab-case');
5
7
  var loggingUtils = require('../helpers/loggingUtils.cjs.js');
6
8
  require('@backstage/catalog-model');
7
- require('@backstage/errors');
8
9
  require('git-url-parse');
9
10
  var catalogUtils = require('./catalogUtils.cjs.js');
10
11
 
11
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
12
-
13
- var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
14
-
15
12
  class CatalogHttpClient {
16
13
  logger;
17
14
  config;
18
- discovery;
19
15
  auth;
20
- catalogApi;
16
+ catalog;
21
17
  constructor(deps) {
22
18
  this.logger = deps.logger;
23
19
  this.config = deps.config;
24
- this.discovery = deps.discovery;
25
20
  this.auth = deps.auth;
26
- this.catalogApi = deps.catalogApi;
21
+ this.catalog = deps.catalog;
22
+ }
23
+ async getCredentials() {
24
+ return this.auth.getOwnServiceCredentials();
27
25
  }
28
26
  // Wrapper for https://backstage.io/docs/features/software-catalog/software-catalog-api/#post-analyze-location
29
27
  async analyzeLocation(repoUrl) {
30
28
  this.logger.debug(`Forwarding request to analyze location: ${repoUrl}`);
31
- const response = await fetch__default.default(
32
- `${await this.discovery.getBaseUrl("catalog")}/analyze-location`,
29
+ const response = await this.catalog.analyzeLocation(
33
30
  {
34
- headers: {
35
- "Content-Type": "application/json",
36
- Authorization: `Bearer ${await auth.getTokenForPlugin(
37
- this.auth,
38
- "catalog"
39
- )}`
40
- },
41
- method: "POST",
42
- body: JSON.stringify({
43
- location: {
44
- type: "github",
45
- target: repoUrl
46
- }
47
- })
31
+ location: {
32
+ type: "github",
33
+ target: repoUrl
34
+ }
35
+ },
36
+ {
37
+ credentials: await this.getCredentials()
48
38
  }
49
39
  );
50
- return (await response.json()).generateEntities ?? [];
40
+ return response.generateEntities ?? [];
51
41
  }
52
42
  async listCatalogUrlLocations(search, pageNumber, pageSize) {
53
43
  const byId = await this.listCatalogUrlLocationsById(
@@ -80,27 +70,19 @@ class CatalogHttpClient {
80
70
  };
81
71
  }
82
72
  async listCatalogUrlLocationsByIdFromLocationsEndpoint(search) {
83
- const url = `${await this.discovery.getBaseUrl("catalog")}/locations`;
84
- const response = await fetch__default.default(url, {
85
- headers: {
86
- Accept: "application/json",
87
- Authorization: `Bearer ${await auth.getTokenForPlugin(
88
- this.auth,
89
- "catalog"
90
- )}`
91
- },
92
- method: "GET"
93
- });
94
- const locations = await response.json();
73
+ const { items: locations } = await this.catalog.getLocations(
74
+ {},
75
+ {
76
+ credentials: await this.getCredentials()
77
+ }
78
+ );
95
79
  if (!Array.isArray(locations)) {
96
80
  return { locations: [] };
97
81
  }
98
- const res = locations.filter(
99
- (location) => location.data?.target && location.data?.type === "url"
100
- ).map((location) => {
82
+ const res = locations.filter((location) => location.target && location.type === "url").map((location) => {
101
83
  return {
102
- id: location.data?.id,
103
- target: location.data.target,
84
+ id: location.id,
85
+ target: location.target,
104
86
  source: "location"
105
87
  };
106
88
  });
@@ -123,7 +105,7 @@ class CatalogHttpClient {
123
105
  return { locations: filtered, totalCount: filtered.length };
124
106
  }
125
107
  async listCatalogUrlLocationEntitiesById(search, _pageNumber, _pageSize) {
126
- const result = await this.catalogApi.getEntities(
108
+ const result = await this.catalog.getEntities(
127
109
  {
128
110
  filter: {
129
111
  kind: "Location"
@@ -135,7 +117,7 @@ class CatalogHttpClient {
135
117
  order: { field: "metadata.name", order: "desc" }
136
118
  },
137
119
  {
138
- token: await auth.getTokenForPlugin(this.auth, "catalog")
120
+ credentials: await this.getCredentials()
139
121
  }
140
122
  );
141
123
  const locations = result?.items ?? [];
@@ -159,14 +141,14 @@ class CatalogHttpClient {
159
141
  */
160
142
  async verifyLocationExistence(repoCatalogUrl) {
161
143
  try {
162
- const result = await this.catalogApi.addLocation(
144
+ const result = await this.catalog.addLocation(
163
145
  {
164
146
  type: "url",
165
147
  target: repoCatalogUrl,
166
148
  dryRun: true
167
149
  },
168
150
  {
169
- token: await auth.getTokenForPlugin(this.auth, "catalog")
151
+ credentials: await this.getCredentials()
170
152
  }
171
153
  );
172
154
  return result.exists;
@@ -178,7 +160,7 @@ class CatalogHttpClient {
178
160
  }
179
161
  }
180
162
  async hasEntityInCatalog(entityName) {
181
- return this.catalogApi.queryEntities(
163
+ return this.catalog.queryEntities(
182
164
  {
183
165
  filter: {
184
166
  "metadata.name": entityName
@@ -186,19 +168,19 @@ class CatalogHttpClient {
186
168
  limit: 1
187
169
  },
188
170
  {
189
- token: await auth.getTokenForPlugin(this.auth, "catalog")
171
+ credentials: await this.getCredentials()
190
172
  }
191
173
  ).then((resp) => resp.items?.length > 0);
192
174
  }
193
175
  async possiblyCreateLocation(repoCatalogUrl) {
194
176
  try {
195
- await this.catalogApi.addLocation(
177
+ await this.catalog.addLocation(
196
178
  {
197
179
  type: "url",
198
180
  target: repoCatalogUrl
199
181
  },
200
182
  {
201
- token: await auth.getTokenForPlugin(this.auth, "catalog")
183
+ credentials: await this.getCredentials()
202
184
  }
203
185
  );
204
186
  } catch (error) {
@@ -209,18 +191,8 @@ class CatalogHttpClient {
209
191
  }
210
192
  async deleteCatalogLocationById(locationId) {
211
193
  try {
212
- const url = `${await this.discovery.getBaseUrl(
213
- "catalog"
214
- )}/locations/${locationId}`;
215
- await fetch__default.default(url, {
216
- headers: {
217
- Accept: "application/json",
218
- Authorization: `Bearer ${await auth.getTokenForPlugin(
219
- this.auth,
220
- "catalog"
221
- )}`
222
- },
223
- method: "DELETE"
194
+ await this.catalog.removeLocationById(locationId, {
195
+ credentials: await this.getCredentials()
224
196
  });
225
197
  } catch (error) {
226
198
  loggingUtils.logErrorIfNeeded(
@@ -231,8 +203,8 @@ class CatalogHttpClient {
231
203
  }
232
204
  }
233
205
  async deleteCatalogLocationEntityById(locationUid) {
234
- await this.catalogApi.removeEntityByUid(locationUid, {
235
- token: await auth.getTokenForPlugin(this.auth, "catalog")
206
+ await this.catalog.removeEntityByUid(locationUid, {
207
+ credentials: await this.getCredentials()
236
208
  });
237
209
  }
238
210
  async findLocationEntitiesByRepoUrl(repoUrl, defaultBranch) {
@@ -241,7 +213,7 @@ class CatalogHttpClient {
241
213
  );
242
214
  }
243
215
  async findLocationEntitiesByTargetUrl(targetUrl, limit) {
244
- return this.catalogApi.queryEntities(
216
+ return this.catalog.queryEntities(
245
217
  {
246
218
  filter: [
247
219
  { kind: "Location", "spec.type": "url", "spec.target": targetUrl }
@@ -250,7 +222,7 @@ class CatalogHttpClient {
250
222
  limit
251
223
  },
252
224
  {
253
- token: await auth.getTokenForPlugin(this.auth, "catalog")
225
+ credentials: await this.getCredentials()
254
226
  }
255
227
  ).then((resp) => resp.items);
256
228
  }
@@ -282,8 +254,8 @@ class CatalogHttpClient {
282
254
  async refreshEntity(kind, name, namespace = "default") {
283
255
  const entityRef = `${kind}:${namespace}/${name}`;
284
256
  this.logger.debug(`Refreshing entityRef: ${entityRef}`);
285
- await this.catalogApi.refreshEntity(entityRef, {
286
- token: await auth.getTokenForPlugin(this.auth, "catalog")
257
+ await this.catalog.refreshEntity(entityRef, {
258
+ credentials: await this.getCredentials()
287
259
  });
288
260
  }
289
261
  }
@@ -1 +1 @@
1
- {"version":3,"file":"catalogHttpClient.cjs.js","sources":["../../src/catalog/catalogHttpClient.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 */\n\nimport type {\n AuthService,\n DiscoveryService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { CatalogApi } from '@backstage/catalog-client';\nimport type { LocationEntity } from '@backstage/catalog-model';\nimport type { Config } from '@backstage/config';\n\nimport fetch from 'node-fetch';\n\nimport { getTokenForPlugin, logErrorIfNeeded } from '../helpers';\nimport { filterLocations, getCatalogUrl } from './catalogUtils';\nimport { CatalogLocation } from './types';\n\nexport class CatalogHttpClient {\n private readonly logger: LoggerService;\n private readonly config: Config;\n private readonly discovery: DiscoveryService;\n private readonly auth: AuthService;\n private readonly catalogApi: CatalogApi;\n\n constructor(deps: {\n logger: LoggerService;\n config: Config;\n discovery: DiscoveryService;\n auth: AuthService;\n catalogApi: CatalogApi;\n }) {\n this.logger = deps.logger;\n this.config = deps.config;\n this.discovery = deps.discovery;\n this.auth = deps.auth;\n this.catalogApi = deps.catalogApi;\n }\n\n // Wrapper for https://backstage.io/docs/features/software-catalog/software-catalog-api/#post-analyze-location\n async analyzeLocation(repoUrl: string): Promise<any[]> {\n this.logger.debug(`Forwarding request to analyze location: ${repoUrl}`);\n const response = await fetch(\n `${await this.discovery.getBaseUrl('catalog')}/analyze-location`,\n {\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${await getTokenForPlugin(\n this.auth,\n 'catalog',\n )}`,\n },\n method: 'POST',\n body: JSON.stringify({\n location: {\n type: 'github',\n target: repoUrl,\n },\n }),\n },\n );\n return (await response.json()).generateEntities ?? [];\n }\n\n async listCatalogUrlLocations(\n search?: string,\n pageNumber?: number,\n pageSize?: number,\n ): Promise<{\n uniqueCatalogUrlLocations: Map<string, CatalogLocation>;\n totalCount?: number;\n }> {\n // byId order: config, locations, other\n const byId = await this.listCatalogUrlLocationsById(\n search,\n pageNumber,\n pageSize,\n );\n const result = new Map<string, CatalogLocation>();\n\n for (const l of byId.locations) {\n if (!result.has(l.target)) {\n result.set(l.target, l);\n }\n }\n return {\n uniqueCatalogUrlLocations: result,\n totalCount: byId.totalCount,\n };\n }\n\n async listCatalogUrlLocationsById(\n search?: string,\n pageNumber?: number,\n pageSize?: number,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const result = await Promise.all([\n this.listCatalogUrlLocationsFromConfig(search),\n this.listCatalogUrlLocationsByIdFromLocationsEndpoint(search),\n this.listCatalogUrlLocationEntitiesById(search, pageNumber, pageSize),\n ]);\n const locations = result.flatMap(u => u.locations);\n // we might have duplicate elements here\n const totalCount = result\n .map(l => l.totalCount ?? 0)\n .reduce((accumulator, currentValue) => accumulator + currentValue, 0);\n return {\n locations,\n totalCount,\n };\n }\n\n async listCatalogUrlLocationsByIdFromLocationsEndpoint(\n search?: string,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const url = `${await this.discovery.getBaseUrl('catalog')}/locations`;\n const response = await fetch(url, {\n headers: {\n Accept: 'application/json',\n Authorization: `Bearer ${await getTokenForPlugin(\n this.auth,\n 'catalog',\n )}`,\n },\n method: 'GET',\n });\n const locations = (await response.json()) as {\n data: { id: string; target: string; type: string };\n }[];\n if (!Array.isArray(locations)) {\n return { locations: [] };\n }\n const res = locations\n .filter(\n location => location.data?.target && location.data?.type === 'url',\n )\n .map(location => {\n return {\n id: location.data?.id,\n target: location.data.target,\n source: 'location',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n listCatalogUrlLocationsFromConfig(search?: string): {\n locations: CatalogLocation[];\n totalCount?: number;\n } {\n const locationConfigs =\n this.config.getOptionalConfigArray('catalog.locations') ?? [];\n const res = locationConfigs\n .filter(\n location =>\n location.getOptionalString('target') &&\n location.getOptionalString('type') === 'url',\n )\n .map(location => {\n const target = location.getString('target');\n return {\n id: `app-config-location--${target}`,\n target,\n source: 'config',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n async listCatalogUrlLocationEntitiesById(\n search?: string,\n _pageNumber?: number,\n _pageSize?: number,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const result = await this.catalogApi.getEntities(\n {\n filter: {\n kind: 'Location',\n },\n // There is no query parameter to find entities with target URLs containing a string.\n // The existing filter does an exact matching. That's why we are retrieving this hard-coded high number of Locations.\n limit: 9999,\n offset: 0,\n order: { field: 'metadata.name', order: 'desc' },\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n );\n const locations = (result?.items ?? []) as LocationEntity[];\n const res = locations\n .filter(\n location => location.spec?.target && location.spec?.type === 'url',\n )\n .map(location => {\n return {\n id: location.metadata.uid,\n target: location.spec.target!,\n source: 'integration',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n /**\n * verifyLocationExistence checks for the existence of the Location target.\n * Under the hood, it attempts to read the target URL and will return false if the target could not be found\n * and even if there is already a Location row in the database.\n * @param repoCatalogUrl\n */\n async verifyLocationExistence(repoCatalogUrl: string): Promise<boolean> {\n try {\n const result = await this.catalogApi.addLocation(\n {\n type: 'url',\n target: repoCatalogUrl,\n dryRun: true,\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n );\n // The `result.exists` field is only filled in dryRun mode\n return result.exists as boolean;\n } catch (error: any) {\n if (\n error.message?.includes('NotFoundError') ||\n error.body?.error?.message?.includes('NotFoundError')\n ) {\n return false;\n }\n throw error;\n }\n }\n\n async hasEntityInCatalog(entityName: string) {\n return this.catalogApi\n .queryEntities(\n {\n filter: {\n 'metadata.name': entityName,\n },\n limit: 1,\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n )\n .then(resp => resp.items?.length > 0);\n }\n\n async possiblyCreateLocation(repoCatalogUrl: string) {\n try {\n await this.catalogApi.addLocation(\n {\n type: 'url',\n target: repoCatalogUrl,\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n );\n } catch (error: any) {\n if (\n !(\n error.message?.includes('ConflictError') ||\n error.body?.error?.name?.includes('ConflictError')\n )\n ) {\n throw error;\n }\n // Location already exists, which is fine\n }\n }\n\n async deleteCatalogLocationById(locationId: string): Promise<void> {\n try {\n const url = `${await this.discovery.getBaseUrl(\n 'catalog',\n )}/locations/${locationId}`;\n await fetch(url, {\n headers: {\n Accept: 'application/json',\n Authorization: `Bearer ${await getTokenForPlugin(\n this.auth,\n 'catalog',\n )}`,\n },\n method: 'DELETE',\n });\n } catch (error: any) {\n logErrorIfNeeded(\n this.logger,\n `Could not delete location ${locationId}`,\n error,\n );\n }\n }\n\n async deleteCatalogLocationEntityById(locationUid: string): Promise<void> {\n await this.catalogApi.removeEntityByUid(locationUid, {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n });\n }\n\n async findLocationEntitiesByRepoUrl(repoUrl: string, defaultBranch?: string) {\n return this.findLocationEntitiesByTargetUrl(\n getCatalogUrl(this.config, repoUrl, defaultBranch),\n );\n }\n\n async findLocationEntitiesByTargetUrl(targetUrl: string, limit?: number) {\n return this.catalogApi\n .queryEntities(\n {\n filter: [\n { kind: 'Location', 'spec.type': 'url', 'spec.target': targetUrl },\n ],\n fields: ['metadata.namespace', 'metadata.name', 'metadata.uid'],\n limit,\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n )\n .then(resp => resp.items);\n }\n\n async refreshLocationByRepoUrl(repoUrl: string, defaultBranch?: string) {\n const promises: Promise<void>[] = [];\n this.findLocationEntitiesByRepoUrl(repoUrl, defaultBranch).then(\n entities => {\n const nbEntities = entities.length;\n if (nbEntities === 0) {\n this.logger.debug(`No Location Entity found for repo: ${repoUrl}`);\n return;\n }\n this.logger.debug(\n `Refreshing ${nbEntities} Location(s) for repo: ${repoUrl}`,\n );\n entities.forEach(ent =>\n promises.push(\n this.refreshEntity(\n 'location',\n ent.metadata.name,\n ent.metadata.namespace,\n ),\n ),\n );\n },\n );\n await Promise.all(promises);\n }\n\n async refreshEntity(\n kind: string,\n name: string,\n namespace: string = 'default',\n ) {\n const entityRef = `${kind}:${namespace}/${name}`;\n this.logger.debug(`Refreshing entityRef: ${entityRef}`);\n await this.catalogApi.refreshEntity(entityRef, {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n });\n }\n}\n"],"names":["fetch","getTokenForPlugin","filterLocations","logErrorIfNeeded","getCatalogUrl"],"mappings":";;;;;;;;;;;;;;AA+BO,MAAM,iBAAA,CAAkB;AAAA,EACZ,MAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,IAAA;AAAA,EACA,UAAA;AAAA,EAEjB,YAAY,IAAA,EAMT;AACD,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AACtB,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA;AAAA,EACzB;AAAA;AAAA,EAGA,MAAM,gBAAgB,OAAA,EAAiC;AACrD,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,wCAAA,EAA2C,OAAO,CAAA,CAAE,CAAA;AACtE,IAAA,MAAM,WAAW,MAAMA,sBAAA;AAAA,MACrB,GAAG,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA,CAAW,SAAS,CAAC,CAAA,iBAAA,CAAA;AAAA,MAC7C;AAAA,QACE,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,kBAAA;AAAA,UAChB,aAAA,EAAe,UAAU,MAAMC,sBAAA;AAAA,YAC7B,IAAA,CAAK,IAAA;AAAA,YACL;AAAA,WACD,CAAA;AAAA,SACH;AAAA,QACA,MAAA,EAAQ,MAAA;AAAA,QACR,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,QAAA,EAAU;AAAA,YACR,IAAA,EAAM,QAAA;AAAA,YACN,MAAA,EAAQ;AAAA;AACV,SACD;AAAA;AACH,KACF;AACA,IAAA,OAAA,CAAQ,MAAM,QAAA,CAAS,IAAA,EAAK,EAAG,oBAAoB,EAAC;AAAA,EACtD;AAAA,EAEA,MAAM,uBAAA,CACJ,MAAA,EACA,UAAA,EACA,QAAA,EAIC;AAED,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,2BAAA;AAAA,MACtB,MAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAM,MAAA,uBAAa,GAAA,EAA6B;AAEhD,IAAA,KAAA,MAAW,CAAA,IAAK,KAAK,SAAA,EAAW;AAC9B,MAAA,IAAI,CAAC,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA,EAAG;AACzB,QAAA,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,MAAA,EAAQ,CAAC,CAAA;AAAA,MACxB;AAAA,IACF;AACA,IAAA,OAAO;AAAA,MACL,yBAAA,EAA2B,MAAA;AAAA,MAC3B,YAAY,IAAA,CAAK;AAAA,KACnB;AAAA,EACF;AAAA,EAEA,MAAM,2BAAA,CACJ,MAAA,EACA,UAAA,EACA,QAAA,EAIC;AACD,IAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,GAAA,CAAI;AAAA,MAC/B,IAAA,CAAK,kCAAkC,MAAM,CAAA;AAAA,MAC7C,IAAA,CAAK,iDAAiD,MAAM,CAAA;AAAA,MAC5D,IAAA,CAAK,kCAAA,CAAmC,MAAA,EAAQ,UAAA,EAAY,QAAQ;AAAA,KACrE,CAAA;AACD,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,OAAA,CAAQ,CAAA,CAAA,KAAK,EAAE,SAAS,CAAA;AAEjD,IAAA,MAAM,UAAA,GAAa,MAAA,CAChB,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,UAAA,IAAc,CAAC,CAAA,CAC1B,MAAA,CAAO,CAAC,WAAA,EAAa,YAAA,KAAiB,WAAA,GAAc,cAAc,CAAC,CAAA;AACtE,IAAA,OAAO;AAAA,MACL,SAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA,EAEA,MAAM,iDACJ,MAAA,EAIC;AACD,IAAA,MAAM,MAAM,CAAA,EAAG,MAAM,KAAK,SAAA,CAAU,UAAA,CAAW,SAAS,CAAC,CAAA,UAAA,CAAA;AACzD,IAAA,MAAM,QAAA,GAAW,MAAMD,sBAAA,CAAM,GAAA,EAAK;AAAA,MAChC,OAAA,EAAS;AAAA,QACP,MAAA,EAAQ,kBAAA;AAAA,QACR,aAAA,EAAe,UAAU,MAAMC,sBAAA;AAAA,UAC7B,IAAA,CAAK,IAAA;AAAA,UACL;AAAA,SACD,CAAA;AAAA,OACH;AAAA,MACA,MAAA,EAAQ;AAAA,KACT,CAAA;AACD,IAAA,MAAM,SAAA,GAAa,MAAM,QAAA,CAAS,IAAA,EAAK;AAGvC,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,SAAS,CAAA,EAAG;AAC7B,MAAA,OAAO,EAAE,SAAA,EAAW,EAAC,EAAE;AAAA,IACzB;AACA,IAAA,MAAM,MAAM,SAAA,CACT,MAAA;AAAA,MACC,cAAY,QAAA,CAAS,IAAA,EAAM,MAAA,IAAU,QAAA,CAAS,MAAM,IAAA,KAAS;AAAA,KAC/D,CACC,IAAI,CAAA,QAAA,KAAY;AACf,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,SAAS,IAAA,EAAM,EAAA;AAAA,QACnB,MAAA,EAAQ,SAAS,IAAA,CAAK,MAAA;AAAA,QACtB,MAAA,EAAQ;AAAA,OACV;AAAA,IACF,CAAC,CAAA;AACH,IAAA,MAAM,QAAA,GAAWC,4BAAA,CAAgB,GAAA,EAAK,MAAM,CAAA;AAC5C,IAAA,OAAO,EAAE,SAAA,EAAW,QAAA,EAAU,UAAA,EAAY,SAAS,MAAA,EAAO;AAAA,EAC5D;AAAA,EAEA,kCAAkC,MAAA,EAGhC;AACA,IAAA,MAAM,kBACJ,IAAA,CAAK,MAAA,CAAO,sBAAA,CAAuB,mBAAmB,KAAK,EAAC;AAC9D,IAAA,MAAM,MAAM,eAAA,CACT,MAAA;AAAA,MACC,CAAA,QAAA,KACE,SAAS,iBAAA,CAAkB,QAAQ,KACnC,QAAA,CAAS,iBAAA,CAAkB,MAAM,CAAA,KAAM;AAAA,KAC3C,CACC,IAAI,CAAA,QAAA,KAAY;AACf,MAAA,MAAM,MAAA,GAAS,QAAA,CAAS,SAAA,CAAU,QAAQ,CAAA;AAC1C,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,wBAAwB,MAAM,CAAA,CAAA;AAAA,QAClC,MAAA;AAAA,QACA,MAAA,EAAQ;AAAA,OACV;AAAA,IACF,CAAC,CAAA;AACH,IAAA,MAAM,QAAA,GAAWA,4BAAA,CAAgB,GAAA,EAAK,MAAM,CAAA;AAC5C,IAAA,OAAO,EAAE,SAAA,EAAW,QAAA,EAAU,UAAA,EAAY,SAAS,MAAA,EAAO;AAAA,EAC5D;AAAA,EAEA,MAAM,kCAAA,CACJ,MAAA,EACA,WAAA,EACA,SAAA,EAIC;AACD,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,UAAA,CAAW,WAAA;AAAA,MACnC;AAAA,QACE,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM;AAAA,SACR;AAAA;AAAA;AAAA,QAGA,KAAA,EAAO,IAAA;AAAA,QACP,MAAA,EAAQ,CAAA;AAAA,QACR,KAAA,EAAO,EAAE,KAAA,EAAO,eAAA,EAAiB,OAAO,MAAA;AAAO,OACjD;AAAA,MACA;AAAA,QACE,KAAA,EAAO,MAAMD,sBAAA,CAAkB,IAAA,CAAK,MAAM,SAAS;AAAA;AACrD,KACF;AACA,IAAA,MAAM,SAAA,GAAa,MAAA,EAAQ,KAAA,IAAS,EAAC;AACrC,IAAA,MAAM,MAAM,SAAA,CACT,MAAA;AAAA,MACC,cAAY,QAAA,CAAS,IAAA,EAAM,MAAA,IAAU,QAAA,CAAS,MAAM,IAAA,KAAS;AAAA,KAC/D,CACC,IAAI,CAAA,QAAA,KAAY;AACf,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,SAAS,QAAA,CAAS,GAAA;AAAA,QACtB,MAAA,EAAQ,SAAS,IAAA,CAAK,MAAA;AAAA,QACtB,MAAA,EAAQ;AAAA,OACV;AAAA,IACF,CAAC,CAAA;AACH,IAAA,MAAM,QAAA,GAAWC,4BAAA,CAAgB,GAAA,EAAK,MAAM,CAAA;AAC5C,IAAA,OAAO,EAAE,SAAA,EAAW,QAAA,EAAU,UAAA,EAAY,SAAS,MAAA,EAAO;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,wBAAwB,cAAA,EAA0C;AACtE,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,UAAA,CAAW,WAAA;AAAA,QACnC;AAAA,UACE,IAAA,EAAM,KAAA;AAAA,UACN,MAAA,EAAQ,cAAA;AAAA,UACR,MAAA,EAAQ;AAAA,SACV;AAAA,QACA;AAAA,UACE,KAAA,EAAO,MAAMD,sBAAA,CAAkB,IAAA,CAAK,MAAM,SAAS;AAAA;AACrD,OACF;AAEA,MAAA,OAAO,MAAA,CAAO,MAAA;AAAA,IAChB,SAAS,KAAA,EAAY;AACnB,MAAA,IACE,KAAA,CAAM,OAAA,EAAS,QAAA,CAAS,eAAe,CAAA,IACvC,KAAA,CAAM,IAAA,EAAM,KAAA,EAAO,OAAA,EAAS,QAAA,CAAS,eAAe,CAAA,EACpD;AACA,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,mBAAmB,UAAA,EAAoB;AAC3C,IAAA,OAAO,KAAK,UAAA,CACT,aAAA;AAAA,MACC;AAAA,QACE,MAAA,EAAQ;AAAA,UACN,eAAA,EAAiB;AAAA,SACnB;AAAA,QACA,KAAA,EAAO;AAAA,OACT;AAAA,MACA;AAAA,QACE,KAAA,EAAO,MAAMA,sBAAA,CAAkB,IAAA,CAAK,MAAM,SAAS;AAAA;AACrD,MAED,IAAA,CAAK,CAAA,IAAA,KAAQ,IAAA,CAAK,KAAA,EAAO,SAAS,CAAC,CAAA;AAAA,EACxC;AAAA,EAEA,MAAM,uBAAuB,cAAA,EAAwB;AACnD,IAAA,IAAI;AACF,MAAA,MAAM,KAAK,UAAA,CAAW,WAAA;AAAA,QACpB;AAAA,UACE,IAAA,EAAM,KAAA;AAAA,UACN,MAAA,EAAQ;AAAA,SACV;AAAA,QACA;AAAA,UACE,KAAA,EAAO,MAAMA,sBAAA,CAAkB,IAAA,CAAK,MAAM,SAAS;AAAA;AACrD,OACF;AAAA,IACF,SAAS,KAAA,EAAY;AACnB,MAAA,IACE,EACE,KAAA,CAAM,OAAA,EAAS,QAAA,CAAS,eAAe,CAAA,IACvC,KAAA,CAAM,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,QAAA,CAAS,eAAe,CAAA,CAAA,EAEnD;AACA,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAAA,EAEA,MAAM,0BAA0B,UAAA,EAAmC;AACjE,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,CAAA,EAAG,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA;AAAA,QAClC;AAAA,OACD,cAAc,UAAU,CAAA,CAAA;AACzB,MAAA,MAAMD,uBAAM,GAAA,EAAK;AAAA,QACf,OAAA,EAAS;AAAA,UACP,MAAA,EAAQ,kBAAA;AAAA,UACR,aAAA,EAAe,UAAU,MAAMC,sBAAA;AAAA,YAC7B,IAAA,CAAK,IAAA;AAAA,YACL;AAAA,WACD,CAAA;AAAA,SACH;AAAA,QACA,MAAA,EAAQ;AAAA,OACT,CAAA;AAAA,IACH,SAAS,KAAA,EAAY;AACnB,MAAAE,6BAAA;AAAA,QACE,IAAA,CAAK,MAAA;AAAA,QACL,6BAA6B,UAAU,CAAA,CAAA;AAAA,QACvC;AAAA,OACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,gCAAgC,WAAA,EAAoC;AACxE,IAAA,MAAM,IAAA,CAAK,UAAA,CAAW,iBAAA,CAAkB,WAAA,EAAa;AAAA,MACnD,KAAA,EAAO,MAAMF,sBAAA,CAAkB,IAAA,CAAK,MAAM,SAAS;AAAA,KACpD,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,6BAAA,CAA8B,OAAA,EAAiB,aAAA,EAAwB;AAC3E,IAAA,OAAO,IAAA,CAAK,+BAAA;AAAA,MACVG,0BAAA,CAAc,IAAA,CAAK,MAAA,EAAQ,OAAA,EAAS,aAAa;AAAA,KACnD;AAAA,EACF;AAAA,EAEA,MAAM,+BAAA,CAAgC,SAAA,EAAmB,KAAA,EAAgB;AACvE,IAAA,OAAO,KAAK,UAAA,CACT,aAAA;AAAA,MACC;AAAA,QACE,MAAA,EAAQ;AAAA,UACN,EAAE,IAAA,EAAM,UAAA,EAAY,WAAA,EAAa,KAAA,EAAO,eAAe,SAAA;AAAU,SACnE;AAAA,QACA,MAAA,EAAQ,CAAC,oBAAA,EAAsB,eAAA,EAAiB,cAAc,CAAA;AAAA,QAC9D;AAAA,OACF;AAAA,MACA;AAAA,QACE,KAAA,EAAO,MAAMH,sBAAA,CAAkB,IAAA,CAAK,MAAM,SAAS;AAAA;AACrD,KACF,CACC,IAAA,CAAK,CAAA,IAAA,KAAQ,IAAA,CAAK,KAAK,CAAA;AAAA,EAC5B;AAAA,EAEA,MAAM,wBAAA,CAAyB,OAAA,EAAiB,aAAA,EAAwB;AACtE,IAAA,MAAM,WAA4B,EAAC;AACnC,IAAA,IAAA,CAAK,6BAAA,CAA8B,OAAA,EAAS,aAAa,CAAA,CAAE,IAAA;AAAA,MACzD,CAAA,QAAA,KAAY;AACV,QAAA,MAAM,aAAa,QAAA,CAAS,MAAA;AAC5B,QAAA,IAAI,eAAe,CAAA,EAAG;AACpB,UAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,mCAAA,EAAsC,OAAO,CAAA,CAAE,CAAA;AACjE,UAAA;AAAA,QACF;AACA,QAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,UACV,CAAA,WAAA,EAAc,UAAU,CAAA,uBAAA,EAA0B,OAAO,CAAA;AAAA,SAC3D;AACA,QAAA,QAAA,CAAS,OAAA;AAAA,UAAQ,SACf,QAAA,CAAS,IAAA;AAAA,YACP,IAAA,CAAK,aAAA;AAAA,cACH,UAAA;AAAA,cACA,IAAI,QAAA,CAAS,IAAA;AAAA,cACb,IAAI,QAAA,CAAS;AAAA;AACf;AACF,SACF;AAAA,MACF;AAAA,KACF;AACA,IAAA,MAAM,OAAA,CAAQ,IAAI,QAAQ,CAAA;AAAA,EAC5B;AAAA,EAEA,MAAM,aAAA,CACJ,IAAA,EACA,IAAA,EACA,YAAoB,SAAA,EACpB;AACA,IAAA,MAAM,YAAY,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,SAAS,IAAI,IAAI,CAAA,CAAA;AAC9C,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,sBAAA,EAAyB,SAAS,CAAA,CAAE,CAAA;AACtD,IAAA,MAAM,IAAA,CAAK,UAAA,CAAW,aAAA,CAAc,SAAA,EAAW;AAAA,MAC7C,KAAA,EAAO,MAAMA,sBAAA,CAAkB,IAAA,CAAK,MAAM,SAAS;AAAA,KACpD,CAAA;AAAA,EACH;AACF;;;;"}
1
+ {"version":3,"file":"catalogHttpClient.cjs.js","sources":["../../src/catalog/catalogHttpClient.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 */\n\nimport type { AuthService, LoggerService } from '@backstage/backend-plugin-api';\nimport type { LocationEntity } from '@backstage/catalog-model';\nimport type { Config } from '@backstage/config';\nimport type { CatalogService } from '@backstage/plugin-catalog-node';\n\nimport { logErrorIfNeeded } from '../helpers';\nimport { filterLocations, getCatalogUrl } from './catalogUtils';\nimport { CatalogLocation } from './types';\n\nexport class CatalogHttpClient {\n private readonly logger: LoggerService;\n private readonly config: Config;\n private readonly auth: AuthService;\n private readonly catalog: CatalogService;\n\n constructor(deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalog: CatalogService;\n }) {\n this.logger = deps.logger;\n this.config = deps.config;\n this.auth = deps.auth;\n this.catalog = deps.catalog;\n }\n\n private async getCredentials() {\n return this.auth.getOwnServiceCredentials();\n }\n\n // Wrapper for https://backstage.io/docs/features/software-catalog/software-catalog-api/#post-analyze-location\n async analyzeLocation(repoUrl: string): Promise<any[]> {\n this.logger.debug(`Forwarding request to analyze location: ${repoUrl}`);\n const response = await this.catalog.analyzeLocation(\n {\n location: {\n type: 'github',\n target: repoUrl,\n },\n },\n {\n credentials: await this.getCredentials(),\n },\n );\n return response.generateEntities ?? [];\n }\n\n async listCatalogUrlLocations(\n search?: string,\n pageNumber?: number,\n pageSize?: number,\n ): Promise<{\n uniqueCatalogUrlLocations: Map<string, CatalogLocation>;\n totalCount?: number;\n }> {\n // byId order: config, locations, other\n const byId = await this.listCatalogUrlLocationsById(\n search,\n pageNumber,\n pageSize,\n );\n const result = new Map<string, CatalogLocation>();\n\n for (const l of byId.locations) {\n if (!result.has(l.target)) {\n result.set(l.target, l);\n }\n }\n return {\n uniqueCatalogUrlLocations: result,\n totalCount: byId.totalCount,\n };\n }\n\n async listCatalogUrlLocationsById(\n search?: string,\n pageNumber?: number,\n pageSize?: number,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const result = await Promise.all([\n this.listCatalogUrlLocationsFromConfig(search),\n this.listCatalogUrlLocationsByIdFromLocationsEndpoint(search),\n this.listCatalogUrlLocationEntitiesById(search, pageNumber, pageSize),\n ]);\n const locations = result.flatMap(u => u.locations);\n // we might have duplicate elements here\n const totalCount = result\n .map(l => l.totalCount ?? 0)\n .reduce((accumulator, currentValue) => accumulator + currentValue, 0);\n return {\n locations,\n totalCount,\n };\n }\n\n async listCatalogUrlLocationsByIdFromLocationsEndpoint(\n search?: string,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const { items: locations } = await this.catalog.getLocations(\n {},\n {\n credentials: await this.getCredentials(),\n },\n );\n if (!Array.isArray(locations)) {\n return { locations: [] };\n }\n const res = locations\n .filter(location => location.target && location.type === 'url')\n .map(location => {\n return {\n id: location.id,\n target: location.target,\n source: 'location',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n listCatalogUrlLocationsFromConfig(search?: string): {\n locations: CatalogLocation[];\n totalCount?: number;\n } {\n const locationConfigs =\n this.config.getOptionalConfigArray('catalog.locations') ?? [];\n const res = locationConfigs\n .filter(\n location =>\n location.getOptionalString('target') &&\n location.getOptionalString('type') === 'url',\n )\n .map(location => {\n const target = location.getString('target');\n return {\n id: `app-config-location--${target}`,\n target,\n source: 'config',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n async listCatalogUrlLocationEntitiesById(\n search?: string,\n _pageNumber?: number,\n _pageSize?: number,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const result = await this.catalog.getEntities(\n {\n filter: {\n kind: 'Location',\n },\n // There is no query parameter to find entities with target URLs containing a string.\n // The existing filter does an exact matching. That's why we are retrieving this hard-coded high number of Locations.\n limit: 9999,\n offset: 0,\n order: { field: 'metadata.name', order: 'desc' },\n },\n {\n credentials: await this.getCredentials(),\n },\n );\n const locations = (result?.items ?? []) as LocationEntity[];\n const res = locations\n .filter(\n location => location.spec?.target && location.spec?.type === 'url',\n )\n .map(location => {\n return {\n id: location.metadata.uid,\n target: location.spec.target!,\n source: 'integration',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n /**\n * verifyLocationExistence checks for the existence of the Location target.\n * Under the hood, it attempts to read the target URL and will return false if the target could not be found\n * and even if there is already a Location row in the database.\n * @param repoCatalogUrl\n */\n async verifyLocationExistence(repoCatalogUrl: string): Promise<boolean> {\n try {\n const result = await this.catalog.addLocation(\n {\n type: 'url',\n target: repoCatalogUrl,\n dryRun: true,\n },\n {\n credentials: await this.getCredentials(),\n },\n );\n // The `result.exists` field is only filled in dryRun mode\n return result.exists as boolean;\n } catch (error: any) {\n if (\n error.message?.includes('NotFoundError') ||\n error.body?.error?.message?.includes('NotFoundError')\n ) {\n return false;\n }\n throw error;\n }\n }\n\n async hasEntityInCatalog(entityName: string) {\n return this.catalog\n .queryEntities(\n {\n filter: {\n 'metadata.name': entityName,\n },\n limit: 1,\n },\n {\n credentials: await this.getCredentials(),\n },\n )\n .then(resp => resp.items?.length > 0);\n }\n\n async possiblyCreateLocation(repoCatalogUrl: string) {\n try {\n await this.catalog.addLocation(\n {\n type: 'url',\n target: repoCatalogUrl,\n },\n {\n credentials: await this.getCredentials(),\n },\n );\n } catch (error: any) {\n if (\n !(\n error.message?.includes('ConflictError') ||\n error.body?.error?.name?.includes('ConflictError')\n )\n ) {\n throw error;\n }\n // Location already exists, which is fine\n }\n }\n\n async deleteCatalogLocationById(locationId: string): Promise<void> {\n try {\n await this.catalog.removeLocationById(locationId, {\n credentials: await this.getCredentials(),\n });\n } catch (error: any) {\n logErrorIfNeeded(\n this.logger,\n `Could not delete location ${locationId}`,\n error,\n );\n }\n }\n\n async deleteCatalogLocationEntityById(locationUid: string): Promise<void> {\n await this.catalog.removeEntityByUid(locationUid, {\n credentials: await this.getCredentials(),\n });\n }\n\n async findLocationEntitiesByRepoUrl(repoUrl: string, defaultBranch?: string) {\n return this.findLocationEntitiesByTargetUrl(\n getCatalogUrl(this.config, repoUrl, defaultBranch),\n );\n }\n\n async findLocationEntitiesByTargetUrl(targetUrl: string, limit?: number) {\n return this.catalog\n .queryEntities(\n {\n filter: [\n { kind: 'Location', 'spec.type': 'url', 'spec.target': targetUrl },\n ],\n fields: ['metadata.namespace', 'metadata.name', 'metadata.uid'],\n limit,\n },\n {\n credentials: await this.getCredentials(),\n },\n )\n .then(resp => resp.items);\n }\n\n async refreshLocationByRepoUrl(repoUrl: string, defaultBranch?: string) {\n const promises: Promise<void>[] = [];\n this.findLocationEntitiesByRepoUrl(repoUrl, defaultBranch).then(\n entities => {\n const nbEntities = entities.length;\n if (nbEntities === 0) {\n this.logger.debug(`No Location Entity found for repo: ${repoUrl}`);\n return;\n }\n this.logger.debug(\n `Refreshing ${nbEntities} Location(s) for repo: ${repoUrl}`,\n );\n entities.forEach(ent =>\n promises.push(\n this.refreshEntity(\n 'location',\n ent.metadata.name,\n ent.metadata.namespace,\n ),\n ),\n );\n },\n );\n await Promise.all(promises);\n }\n\n async refreshEntity(\n kind: string,\n name: string,\n namespace: string = 'default',\n ) {\n const entityRef = `${kind}:${namespace}/${name}`;\n this.logger.debug(`Refreshing entityRef: ${entityRef}`);\n await this.catalog.refreshEntity(entityRef, {\n credentials: await this.getCredentials(),\n });\n }\n}\n"],"names":["filterLocations","logErrorIfNeeded","getCatalogUrl"],"mappings":"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"}
@@ -28,14 +28,6 @@ async function permissionCheck(auditor, openApiOperationId, permissions, httpAut
28
28
  throw err;
29
29
  }
30
30
  }
31
- async function getTokenForPlugin(auth, targetPluginId) {
32
- const resp = await auth.getPluginRequestToken({
33
- onBehalfOf: await auth.getOwnServiceCredentials(),
34
- targetPluginId
35
- });
36
- return resp.token;
37
- }
38
31
 
39
- exports.getTokenForPlugin = getTokenForPlugin;
40
32
  exports.permissionCheck = permissionCheck;
41
33
  //# sourceMappingURL=auth.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.cjs.js","sources":["../../src/helpers/auth.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 */\n\nimport type {\n AuditorService,\n AuthService,\n HttpAuthService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport { NotAllowedError } from '@backstage/errors';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\n\nimport express from 'express';\n\nimport { bulkImportPermission } from '@red-hat-developer-hub/backstage-plugin-bulk-import-common';\n\nimport { auditCreateEvent } from './auditorUtils';\n\n/**\n * This will resolve to { result: AuthorizeResult.ALLOW } if the permission framework is disabled\n */\nexport async function permissionCheck(\n auditor: AuditorService,\n openApiOperationId: string | undefined,\n permissions: PermissionsService,\n httpAuth: HttpAuthService,\n req: express.Request,\n) {\n const decision = (\n await permissions.authorize(\n [\n {\n permission: bulkImportPermission,\n resourceRef: bulkImportPermission.resourceType,\n },\n ],\n {\n credentials: await httpAuth.credentials(req),\n },\n )\n )[0];\n\n if (decision.result === AuthorizeResult.DENY) {\n const err = new NotAllowedError('Unauthorized');\n const auditorEvent = await auditCreateEvent(\n auditor,\n openApiOperationId,\n req,\n );\n await auditorEvent.fail({ error: err, meta: { responseStatus: 403 } });\n throw err;\n }\n}\n\nexport async function getTokenForPlugin(\n auth: AuthService,\n targetPluginId: string,\n): Promise<string> {\n const resp = await auth.getPluginRequestToken({\n onBehalfOf: await auth.getOwnServiceCredentials(),\n targetPluginId,\n });\n return resp.token;\n}\n"],"names":["bulkImportPermission","AuthorizeResult","NotAllowedError","auditCreateEvent"],"mappings":";;;;;;;AAkCA,eAAsB,eAAA,CACpB,OAAA,EACA,kBAAA,EACA,WAAA,EACA,UACA,GAAA,EACA;AACA,EAAA,MAAM,QAAA,GAAA,CACJ,MAAM,WAAA,CAAY,SAAA;AAAA,IAChB;AAAA,MACE;AAAA,QACE,UAAA,EAAYA,oDAAA;AAAA,QACZ,aAAaA,oDAAA,CAAqB;AAAA;AACpC,KACF;AAAA,IACA;AAAA,MACE,WAAA,EAAa,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG;AAAA;AAC7C,KAEF,CAAC,CAAA;AAEH,EAAA,IAAI,QAAA,CAAS,MAAA,KAAWC,sCAAA,CAAgB,IAAA,EAAM;AAC5C,IAAA,MAAM,GAAA,GAAM,IAAIC,sBAAA,CAAgB,cAAc,CAAA;AAC9C,IAAA,MAAM,eAAe,MAAMC,6BAAA;AAAA,MACzB,OAAA;AAAA,MACA,kBAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAM,YAAA,CAAa,IAAA,CAAK,EAAE,KAAA,EAAO,GAAA,EAAK,MAAM,EAAE,cAAA,EAAgB,GAAA,EAAI,EAAG,CAAA;AACrE,IAAA,MAAM,GAAA;AAAA,EACR;AACF;AAEA,eAAsB,iBAAA,CACpB,MACA,cAAA,EACiB;AACjB,EAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,qBAAA,CAAsB;AAAA,IAC5C,UAAA,EAAY,MAAM,IAAA,CAAK,wBAAA,EAAyB;AAAA,IAChD;AAAA,GACD,CAAA;AACD,EAAA,OAAO,IAAA,CAAK,KAAA;AACd;;;;;"}
1
+ {"version":3,"file":"auth.cjs.js","sources":["../../src/helpers/auth.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 */\n\nimport type {\n AuditorService,\n HttpAuthService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport { NotAllowedError } from '@backstage/errors';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\n\nimport express from 'express';\n\nimport { bulkImportPermission } from '@red-hat-developer-hub/backstage-plugin-bulk-import-common';\n\nimport { auditCreateEvent } from './auditorUtils';\n\n/**\n * This will resolve to { result: AuthorizeResult.ALLOW } if the permission framework is disabled\n */\nexport async function permissionCheck(\n auditor: AuditorService,\n openApiOperationId: string | undefined,\n permissions: PermissionsService,\n httpAuth: HttpAuthService,\n req: express.Request,\n) {\n const decision = (\n await permissions.authorize(\n [\n {\n permission: bulkImportPermission,\n resourceRef: bulkImportPermission.resourceType,\n },\n ],\n {\n credentials: await httpAuth.credentials(req),\n },\n )\n )[0];\n\n if (decision.result === AuthorizeResult.DENY) {\n const err = new NotAllowedError('Unauthorized');\n const auditorEvent = await auditCreateEvent(\n auditor,\n openApiOperationId,\n req,\n );\n await auditorEvent.fail({ error: err, meta: { responseStatus: 403 } });\n throw err;\n }\n}\n"],"names":["bulkImportPermission","AuthorizeResult","NotAllowedError","auditCreateEvent"],"mappings":";;;;;;;AAiCA,eAAsB,eAAA,CACpB,OAAA,EACA,kBAAA,EACA,WAAA,EACA,UACA,GAAA,EACA;AACA,EAAA,MAAM,QAAA,GAAA,CACJ,MAAM,WAAA,CAAY,SAAA;AAAA,IAChB;AAAA,MACE;AAAA,QACE,UAAA,EAAYA,oDAAA;AAAA,QACZ,aAAaA,oDAAA,CAAqB;AAAA;AACpC,KACF;AAAA,IACA;AAAA,MACE,WAAA,EAAa,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG;AAAA;AAC7C,KAEF,CAAC,CAAA;AAEH,EAAA,IAAI,QAAA,CAAS,MAAA,KAAWC,sCAAA,CAAgB,IAAA,EAAM;AAC5C,IAAA,MAAM,GAAA,GAAM,IAAIC,sBAAA,CAAgB,cAAc,CAAA;AAC9C,IAAA,MAAM,eAAe,MAAMC,6BAAA;AAAA,MACzB,OAAA;AAAA,MACA,kBAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAM,YAAA,CAAa,IAAA,CAAK,EAAE,KAAA,EAAO,GAAA,EAAK,MAAM,EAAE,cAAA,EAAgB,GAAA,EAAI,EAAG,CAAA;AACrE,IAAA,MAAM,GAAA;AAAA,EACR;AACF;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
2
2
  import { LoggerService, CacheService, DiscoveryService, HttpAuthService, AuthService, AuditorService, DatabaseService } from '@backstage/backend-plugin-api';
3
- import { CatalogApi } from '@backstage/catalog-client';
4
3
  import { Config } from '@backstage/config';
4
+ import { CatalogService } from '@backstage/plugin-catalog-node';
5
5
  import { PermissionEvaluator } from '@backstage/plugin-permission-common';
6
6
  import express from 'express';
7
7
 
@@ -23,7 +23,7 @@ interface RouterOptions {
23
23
  discovery: DiscoveryService;
24
24
  httpAuth: HttpAuthService;
25
25
  auth: AuthService;
26
- catalogApi: CatalogApi;
26
+ catalog: CatalogService;
27
27
  auditor: AuditorService;
28
28
  database: DatabaseService;
29
29
  }
@@ -1,7 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var backendPluginApi = require('@backstage/backend-plugin-api');
4
- var alpha = require('@backstage/plugin-catalog-node/alpha');
4
+ var pluginCatalogNode = require('@backstage/plugin-catalog-node');
5
+ var backstagePluginBulkImportCommon = require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
5
6
  var router = require('./service/router.cjs.js');
6
7
 
7
8
  const bulkImportPlugin = backendPluginApi.createBackendPlugin({
@@ -15,9 +16,10 @@ const bulkImportPlugin = backendPluginApi.createBackendPlugin({
15
16
  cache: backendPluginApi.coreServices.cache,
16
17
  discovery: backendPluginApi.coreServices.discovery,
17
18
  permissions: backendPluginApi.coreServices.permissions,
19
+ permissionsRegistry: backendPluginApi.coreServices.permissionsRegistry,
18
20
  httpAuth: backendPluginApi.coreServices.httpAuth,
19
21
  auth: backendPluginApi.coreServices.auth,
20
- catalogApi: alpha.catalogServiceRef,
22
+ catalog: pluginCatalogNode.catalogServiceRef,
21
23
  auditor: backendPluginApi.coreServices.auditor,
22
24
  database: backendPluginApi.coreServices.database
23
25
  },
@@ -28,12 +30,14 @@ const bulkImportPlugin = backendPluginApi.createBackendPlugin({
28
30
  cache,
29
31
  discovery,
30
32
  permissions,
33
+ permissionsRegistry,
31
34
  httpAuth,
32
35
  auth,
33
- catalogApi,
36
+ catalog,
34
37
  auditor,
35
38
  database
36
39
  }) {
40
+ permissionsRegistry.addPermissions([backstagePluginBulkImportCommon.bulkImportPermission]);
37
41
  const router$1 = await router.createRouter({
38
42
  config,
39
43
  cache,
@@ -42,7 +46,7 @@ const bulkImportPlugin = backendPluginApi.createBackendPlugin({
42
46
  logger,
43
47
  httpAuth,
44
48
  auth,
45
- catalogApi,
49
+ catalog,
46
50
  auditor,
47
51
  database
48
52
  });
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 */\n\nimport {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';\n\nimport { createRouter } from './service/router';\n\n/**\n * The bulk-import backend plugin.\n * @public\n */\nexport const bulkImportPlugin = createBackendPlugin({\n pluginId: 'bulk-import',\n register(env) {\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n http: coreServices.httpRouter,\n cache: coreServices.cache,\n discovery: coreServices.discovery,\n permissions: coreServices.permissions,\n httpAuth: coreServices.httpAuth,\n auth: coreServices.auth,\n catalogApi: catalogServiceRef,\n auditor: coreServices.auditor,\n database: coreServices.database,\n },\n async init({\n config,\n logger,\n http,\n cache,\n discovery,\n permissions,\n httpAuth,\n auth,\n catalogApi,\n auditor,\n database,\n }) {\n const router = await createRouter({\n config,\n cache,\n discovery,\n permissions,\n logger,\n httpAuth,\n auth,\n catalogApi,\n auditor,\n database,\n });\n http.use(router);\n http.addAuthPolicy({\n path: '/ping',\n allow: 'unauthenticated',\n });\n },\n });\n },\n});\n"],"names":["createBackendPlugin","coreServices","catalogServiceRef","router","createRouter"],"mappings":";;;;;;AA4BO,MAAM,mBAAmBA,oCAAA,CAAoB;AAAA,EAClD,QAAA,EAAU,aAAA;AAAA,EACV,SAAS,GAAA,EAAK;AACZ,IAAA,GAAA,CAAI,YAAA,CAAa;AAAA,MACf,IAAA,EAAM;AAAA,QACJ,QAAQC,6BAAA,CAAa,MAAA;AAAA,QACrB,QAAQA,6BAAA,CAAa,UAAA;AAAA,QACrB,MAAMA,6BAAA,CAAa,UAAA;AAAA,QACnB,OAAOA,6BAAA,CAAa,KAAA;AAAA,QACpB,WAAWA,6BAAA,CAAa,SAAA;AAAA,QACxB,aAAaA,6BAAA,CAAa,WAAA;AAAA,QAC1B,UAAUA,6BAAA,CAAa,QAAA;AAAA,QACvB,MAAMA,6BAAA,CAAa,IAAA;AAAA,QACnB,UAAA,EAAYC,uBAAA;AAAA,QACZ,SAASD,6BAAA,CAAa,OAAA;AAAA,QACtB,UAAUA,6BAAA,CAAa;AAAA,OACzB;AAAA,MACA,MAAM,IAAA,CAAK;AAAA,QACT,MAAA;AAAA,QACA,MAAA;AAAA,QACA,IAAA;AAAA,QACA,KAAA;AAAA,QACA,SAAA;AAAA,QACA,WAAA;AAAA,QACA,QAAA;AAAA,QACA,IAAA;AAAA,QACA,UAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA,OACF,EAAG;AACD,QAAA,MAAME,QAAA,GAAS,MAAMC,mBAAA,CAAa;AAAA,UAChC,MAAA;AAAA,UACA,KAAA;AAAA,UACA,SAAA;AAAA,UACA,WAAA;AAAA,UACA,MAAA;AAAA,UACA,QAAA;AAAA,UACA,IAAA;AAAA,UACA,UAAA;AAAA,UACA,OAAA;AAAA,UACA;AAAA,SACD,CAAA;AACD,QAAA,IAAA,CAAK,IAAID,QAAM,CAAA;AACf,QAAA,IAAA,CAAK,aAAA,CAAc;AAAA,UACjB,IAAA,EAAM,OAAA;AAAA,UACN,KAAA,EAAO;AAAA,SACR,CAAA;AAAA,MACH;AAAA,KACD,CAAA;AAAA,EACH;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 */\n\nimport {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node';\n\nimport { bulkImportPermission } from '@red-hat-developer-hub/backstage-plugin-bulk-import-common';\n\nimport { createRouter } from './service/router';\n\n/**\n * The bulk-import backend plugin.\n * @public\n */\nexport const bulkImportPlugin = createBackendPlugin({\n pluginId: 'bulk-import',\n register(env) {\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n http: coreServices.httpRouter,\n cache: coreServices.cache,\n discovery: coreServices.discovery,\n permissions: coreServices.permissions,\n permissionsRegistry: coreServices.permissionsRegistry,\n httpAuth: coreServices.httpAuth,\n auth: coreServices.auth,\n catalog: catalogServiceRef,\n auditor: coreServices.auditor,\n database: coreServices.database,\n },\n async init({\n config,\n logger,\n http,\n cache,\n discovery,\n permissions,\n permissionsRegistry,\n httpAuth,\n auth,\n catalog,\n auditor,\n database,\n }) {\n permissionsRegistry.addPermissions([bulkImportPermission]);\n\n const router = await createRouter({\n config,\n cache,\n discovery,\n permissions,\n logger,\n httpAuth,\n auth,\n catalog,\n auditor,\n database,\n });\n http.use(router);\n http.addAuthPolicy({\n path: '/ping',\n allow: 'unauthenticated',\n });\n },\n });\n },\n});\n"],"names":["createBackendPlugin","coreServices","catalogServiceRef","bulkImportPermission","router","createRouter"],"mappings":";;;;;;;AA8BO,MAAM,mBAAmBA,oCAAA,CAAoB;AAAA,EAClD,QAAA,EAAU,aAAA;AAAA,EACV,SAAS,GAAA,EAAK;AACZ,IAAA,GAAA,CAAI,YAAA,CAAa;AAAA,MACf,IAAA,EAAM;AAAA,QACJ,QAAQC,6BAAA,CAAa,MAAA;AAAA,QACrB,QAAQA,6BAAA,CAAa,UAAA;AAAA,QACrB,MAAMA,6BAAA,CAAa,UAAA;AAAA,QACnB,OAAOA,6BAAA,CAAa,KAAA;AAAA,QACpB,WAAWA,6BAAA,CAAa,SAAA;AAAA,QACxB,aAAaA,6BAAA,CAAa,WAAA;AAAA,QAC1B,qBAAqBA,6BAAA,CAAa,mBAAA;AAAA,QAClC,UAAUA,6BAAA,CAAa,QAAA;AAAA,QACvB,MAAMA,6BAAA,CAAa,IAAA;AAAA,QACnB,OAAA,EAASC,mCAAA;AAAA,QACT,SAASD,6BAAA,CAAa,OAAA;AAAA,QACtB,UAAUA,6BAAA,CAAa;AAAA,OACzB;AAAA,MACA,MAAM,IAAA,CAAK;AAAA,QACT,MAAA;AAAA,QACA,MAAA;AAAA,QACA,IAAA;AAAA,QACA,KAAA;AAAA,QACA,SAAA;AAAA,QACA,WAAA;AAAA,QACA,mBAAA;AAAA,QACA,QAAA;AAAA,QACA,IAAA;AAAA,QACA,OAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA,OACF,EAAG;AACD,QAAA,mBAAA,CAAoB,cAAA,CAAe,CAACE,oDAAoB,CAAC,CAAA;AAEzD,QAAA,MAAMC,QAAA,GAAS,MAAMC,mBAAA,CAAa;AAAA,UAChC,MAAA;AAAA,UACA,KAAA;AAAA,UACA,SAAA;AAAA,UACA,WAAA;AAAA,UACA,MAAA;AAAA,UACA,QAAA;AAAA,UACA,IAAA;AAAA,UACA,OAAA;AAAA,UACA,OAAA;AAAA,UACA;AAAA,SACD,CAAA;AACD,QAAA,IAAA,CAAK,IAAID,QAAM,CAAA;AACf,QAAA,IAAA,CAAK,aAAA,CAAc;AAAA,UACjB,IAAA,EAAM,OAAA;AAAA,UACN,KAAA,EAAO;AAAA,SACR,CAAA;AAAA,MACH;AAAA,KACD,CAAA;AAAA,EACH;AACF,CAAC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"bulkImports.cjs.js","sources":["../../../../src/service/handlers/import/bulkImports.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 */\n\nimport type {\n AuthService,\n DiscoveryService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { CatalogApi } from '@backstage/catalog-client';\nimport type { Config } from '@backstage/config';\nimport { NotFoundError } from '@backstage/errors';\n\nimport gitUrlParse from 'git-url-parse';\n\nimport {\n Configuration,\n DefaultApi,\n} from '@red-hat-developer-hub/backstage-plugin-orchestrator-common';\n\nimport { CatalogHttpClient } from '../../../catalog/catalogHttpClient';\nimport type { CatalogInfoGenerator } from '../../../catalog/catalogInfoGenerator';\nimport {\n getCatalogFilename,\n getCatalogUrl,\n} from '../../../catalog/catalogUtils';\nimport {\n OrchestratorWorkflow,\n OrchestratorWorkflowDao,\n RepositoryDao,\n RepositoryName,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../../../database/repositoryDao';\nimport type { Components, Paths } from '../../../generated/openapi';\nimport type { GithubApiService } from '../../../github';\nimport { GitlabApiService } from '../../../gitlab';\nimport {\n getNestedValue,\n logErrorIfNeeded,\n paginateArray,\n parseGitURLForApprovalTool,\n} from '../../../helpers';\nimport { GitApiService } from '../../../scm/GitApiService';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n DefaultSortColumn,\n DefaultSortOrder,\n type HandlerResponse,\n} from '../handlers';\n\ntype CreateImportDryRunStatus =\n | 'CATALOG_ENTITY_CONFLICT'\n | 'CATALOG_INFO_FILE_EXISTS_IN_REPO'\n | 'CODEOWNERS_FILE_NOT_FOUND_IN_REPO'\n | 'REPO_EMPTY';\n\ntype FindAllImportsResponse =\n | Components.Schemas.Import[]\n | Components.Schemas.ImportJobListV2;\n\nexport function sortImports(\n imports: Components.Schemas.Import[],\n sortColumn: Components.Parameters.SortColumnQueryParam = DefaultSortColumn,\n sortOrder: Components.Parameters.SortOrderQueryParam = DefaultSortOrder,\n) {\n imports.sort((a, b) => {\n const value1 = getNestedValue(a, sortColumn);\n const value2 = getNestedValue(b, sortColumn);\n // Handle cases where values are undefined\n if (value1 === undefined && value2 === undefined) return 0;\n if (value1 === undefined) return sortOrder === 'asc' ? -1 : 1;\n if (value2 === undefined) return sortOrder === 'asc' ? 1 : -1;\n\n if (sortColumn === 'lastUpdate') {\n const date1 = new Date(value1); // Convert string to Date object\n const date2 = new Date(value2); // Convert string to Date object\n // Compare dates\n return sortOrder === 'asc'\n ? date2.getTime() - date1.getTime()\n : date1.getTime() - date2.getTime();\n }\n // Compare values based on sort order\n return sortOrder === 'asc'\n ? value1.localeCompare(value2)\n : value2.localeCompare(value1);\n });\n}\n\nexport async function findAllImports(\n deps: {\n logger: LoggerService;\n config: Config;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n requestHeaders?: {\n apiVersion?: Paths.FindAllImports.Parameters.ApiVersion;\n },\n queryParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n sortColumn?: Components.Parameters.SortColumnQueryParam;\n sortOrder?: Components.Parameters.SortOrderQueryParam;\n },\n): Promise<HandlerResponse<FindAllImportsResponse>> {\n const apiVersion = requestHeaders?.apiVersion ?? 'v1';\n const search = queryParams?.search;\n const pageNumber = queryParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = queryParams?.pageSize ?? DefaultPageSize;\n const sortColumn = queryParams?.sortColumn ?? DefaultSortColumn;\n const sortOrder = queryParams?.sortOrder ?? DefaultSortOrder;\n\n const catalogFilename = getCatalogFilename(deps.config);\n\n const allLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations(\n search,\n pageNumber,\n pageSize,\n )\n ).uniqueCatalogUrlLocations;\n\n // resolve default branches for each unique repo URL from GH,\n // because we cannot easily determine that from the location target URL.\n // It can be 'main' or something more convoluted like 'our/awesome/main'.\n const defaultBranchByRepoUrl = await resolveReposDefaultBranches(\n deps.logger,\n deps.gitlabApiService,\n deps.githubApiService,\n allLocations.keys(),\n catalogFilename,\n );\n\n // filter out locations that do not match what we are expecting, i.e.:\n // an URL to a catalog-info YAML file at the root of the repo\n const importCandidates = findImportCandidates(\n allLocations.keys(),\n defaultBranchByRepoUrl,\n catalogFilename,\n );\n\n // Keep only repos that are accessible from the configured GH/GL integrations\n const importsReachableFromGHIntegrations =\n await deps.githubApiService.filterLocationsAccessibleFromIntegrations(\n importCandidates.filter(val => {\n return parseGitURLForApprovalTool(val) === 'GIT';\n }),\n );\n\n const importsReachableFromGLIntegrations =\n await deps.gitlabApiService.filterLocationsAccessibleFromIntegrations(\n importCandidates.filter(val => {\n return parseGitURLForApprovalTool(val) === 'GITLAB';\n }),\n );\n\n // Merge the two lists together and map the appropriate approvalTool\n const mergedReachbleFromIntegrations = importsReachableFromGHIntegrations\n .map(val => {\n return {\n loc: val,\n approvalTool: 'GIT',\n };\n })\n .concat(\n importsReachableFromGLIntegrations.map(val => {\n return {\n loc: val,\n approvalTool: 'GITLAB',\n };\n }),\n );\n\n const repoUrlToLocation = new Map<string, string>();\n\n // now fetch the import statuses in different promises\n const importStatusPromises: Promise<\n HandlerResponse<Components.Schemas.Import>\n >[] = [];\n for (const imports of mergedReachbleFromIntegrations) {\n const repoUrl = repoUrlFromLocation(imports.loc);\n if (!repoUrl) {\n continue;\n }\n repoUrlToLocation.set(repoUrl, imports.loc);\n\n importStatusPromises.push(\n findImportStatusByRepo(\n {\n logger: deps.logger,\n config: deps.config,\n gitApiService:\n imports.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService,\n catalogHttpClient: deps.catalogHttpClient,\n approvalTool: imports.approvalTool,\n },\n repoUrl,\n defaultBranchByRepoUrl.get(repoUrl),\n false,\n ),\n );\n }\n\n const result = await Promise.all(importStatusPromises);\n const imports = result\n .filter(res => res.responseBody)\n .map(res => res.responseBody!)\n .map(res => {\n const key = res?.repository?.url;\n const location = key ? repoUrlToLocation.get(key) : undefined;\n return {\n ...res,\n source: location ? allLocations.get(location)?.source : undefined,\n };\n });\n\n // sorting the output to make it deterministic and easy to navigate in the UI\n\n sortImports(imports, sortColumn, sortOrder);\n const paginated = paginateArray(imports, pageNumber, pageSize);\n if (apiVersion === 'v1') {\n return {\n statusCode: 200,\n responseBody: paginated.result,\n };\n }\n return {\n statusCode: 200,\n responseBody: {\n imports: paginated.result,\n totalCount: paginated.totalCount,\n page: pageNumber,\n size: pageSize,\n },\n };\n}\n\nasync function resolveReposDefaultBranches(\n logger: LoggerService,\n gitlabApiService: GitlabApiService,\n githubApiService: GithubApiService,\n allLocations: Iterable<string>,\n catalogFilename: string,\n) {\n const defaultBranchByRepoUrlPromises: Promise<{\n repoUrl: string;\n defaultBranch?: string;\n }>[] = [];\n for (const loc of allLocations) {\n // loc has the following format: https://github.com/<org>/<repo>/blob/<default-branch>/catalog-info.yaml\n // but it can have a more convoluted format like 'https://github.com/redhat-developer/rhdh-plugins/blob/main/plugins/scaffolder-annotator-action/examples/templates/01-scaffolder-template.yaml'\n // if registered manually from the 'Register existing component' feature in Backstage.\n if (!loc.endsWith(catalogFilename)) {\n logger.debug(\n `Ignored location ${loc} because it does not point to a file named ${catalogFilename}`,\n );\n continue;\n }\n const repoUrl = repoUrlFromLocation(loc);\n if (!repoUrl) {\n continue;\n }\n // Have to do this for Both the gitlab/github, possibly a better way?\n // Should probably parse the URL to figure out which to use?\n defaultBranchByRepoUrlPromises.push(\n (parseGitURLForApprovalTool(repoUrl) === 'GITLAB'\n ? gitlabApiService\n : githubApiService\n )\n .getRepositoryFromIntegrations(repoUrl)\n .then(resp => {\n return { repoUrl, defaultBranch: resp?.repository?.default_branch };\n })\n .catch((err: any) => {\n logErrorIfNeeded(\n logger,\n `Ignored repo ${repoUrl} due to an error while fetching details from GitHub`,\n err,\n );\n return {\n repoUrl,\n defaultBranch: undefined,\n };\n }),\n );\n }\n const defaultBranchesResponses = await Promise.all(\n defaultBranchByRepoUrlPromises,\n );\n return new Map(\n defaultBranchesResponses\n .flat()\n .filter(r => r.defaultBranch)\n .map(r => [r.repoUrl, r.defaultBranch!]),\n );\n}\n\nfunction repoUrlFromLocation(loc: string) {\n const split = loc.split('/blob/');\n if (split.length < 2) {\n return undefined;\n }\n return split[0];\n}\n\nfunction findImportCandidates(\n allLocations: Iterable<string>,\n defaultBranchByRepoUrl: Map<string, string>,\n catalogFilename: string,\n) {\n const filteredLocations: string[] = [];\n for (const loc of allLocations) {\n const repoUrl = repoUrlFromLocation(loc);\n if (!repoUrl) {\n continue;\n }\n\n const defaultBranch = defaultBranchByRepoUrl.get(repoUrl);\n if (!defaultBranch) {\n continue;\n }\n if (loc !== `${repoUrl}/blob/${defaultBranch}/${catalogFilename}`) {\n // Because users can use the \"Register existing component\" workflow to register a Location\n // using any file path in the repo, we consider a repository as an Import Location only\n // if it is at the root of the repository, because that is what the import PR ultimately does.\n continue;\n }\n filteredLocations.push(loc);\n }\n return filteredLocations;\n}\n\nasync function createPR(\n gitApiService: GitApiService,\n logger: LoggerService,\n req: Components.Schemas.ImportRequest,\n gitUrl: gitUrlParse.GitUrl,\n catalogInfoGenerator: CatalogInfoGenerator,\n config: Config,\n) {\n const appTitle =\n config.getOptionalString('app.title') ?? 'Red Hat Developer Hub';\n const appBaseUrl = config.getString('app.baseUrl');\n const catalogFileName = getCatalogFilename(config);\n return await gitApiService.submitPrToRepo(logger, {\n repoUrl: req.repository.url,\n gitUrl: gitUrl,\n defaultBranch: req.repository.defaultBranch,\n catalogInfoContent:\n req.catalogInfoContent ??\n (await catalogInfoGenerator.generateDefaultCatalogInfoContent(\n req.repository.url,\n )),\n prTitle:\n req[req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']?.pullRequest\n ?.title ?? `Add ${catalogFileName}`,\n prBody:\n req[req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']?.pullRequest\n ?.body ??\n `\nThis pull request adds a **Backstage entity metadata file** to this repository so that the component can be added to a Backstage application.\n\nAfter this pull request is merged, the component will become available in the [${appTitle} software catalog](${appBaseUrl}).\n\nFor more information, read an [overview of the Backstage software catalog](https://backstage.io/docs/features/software-catalog/).\n`,\n });\n}\n\nasync function handleAddedReposFromCreateImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n importRequests: Components.Schemas.ImportRequest[],\n) {\n const result: Components.Schemas.Import[] = [];\n\n for (const req of importRequests) {\n // Check if repo is already imported\n const repoCatalogUrl = getCatalogUrl(\n deps.config,\n req.repository.url,\n req.repository.defaultBranch,\n );\n const hasLocation =\n await deps.catalogHttpClient.verifyLocationExistence(repoCatalogUrl);\n if (!hasLocation) {\n continue;\n }\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const hasCatalogInfoFileInRepo = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: getCatalogFilename(deps.config),\n });\n if (!hasCatalogInfoFileInRepo) {\n continue;\n }\n\n const ghRepo = await gitApiService.getRepositoryFromIntegrations(\n req.repository.url,\n );\n\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n req.repository.url,\n req.repository.defaultBranch,\n );\n\n const gitUrl = gitUrlParse(req.repository.url);\n result.push({\n status: 'ADDED',\n lastUpdate: ghRepo?.repository?.updated_at ?? undefined,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n });\n }\n return result;\n}\n\nasync function handlePrCreationRequest(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n req: Components.Schemas.ImportRequest,\n gitUrl: gitUrlParse.GitUrl,\n): Promise<Components.Schemas.Import> {\n const repoCatalogUrl = getCatalogUrl(\n deps.config,\n req.repository.url,\n req.repository.defaultBranch,\n );\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const prToRepo = await createPR(\n gitApiService,\n deps.logger,\n req,\n gitUrl,\n deps.catalogInfoGenerator,\n deps.config,\n );\n if (prToRepo.errors && prToRepo.errors.length > 0) {\n return {\n errors: prToRepo.errors,\n status: 'PR_ERROR',\n repository: req.repository,\n };\n }\n if (prToRepo.prUrl) {\n deps.logger.debug(`Created new PR from request: ${prToRepo.prUrl}`);\n }\n\n // Create Location\n await deps.catalogHttpClient.possiblyCreateLocation(repoCatalogUrl);\n\n if (prToRepo.hasChanges === false) {\n deps.logger.debug(\n `No bulk import PR created on ${req.repository.url} since its default branch (${req.repository.defaultBranch}) already contains a catalog-info file`,\n );\n\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n req.repository.url,\n req.repository.defaultBranch,\n );\n return {\n status: 'ADDED',\n lastUpdate: prToRepo.lastUpdate,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n };\n }\n\n return {\n approvalTool: req.approvalTool ?? 'GIT',\n errors: prToRepo.errors,\n status: 'WAIT_PR_APPROVAL',\n lastUpdate: prToRepo.lastUpdate,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n [req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']: {\n pullRequest: {\n url: prToRepo.prUrl,\n number: prToRepo.prNumber,\n },\n },\n };\n}\n\nexport async function createImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n reqParams: {\n importRequests: Paths.CreateImportJobs.RequestBody;\n dryRun?: boolean;\n },\n): Promise<HandlerResponse<Components.Schemas.Import[]>> {\n const dryRun = reqParams.dryRun ?? false;\n const importRequests = reqParams.importRequests;\n deps.logger.debug(\n `Handling request to import ${importRequests?.length} repo(s) (dryRun=${dryRun})..`,\n );\n\n if (importRequests.length === 0) {\n deps.logger.debug('Missing import requests from request body');\n return {\n statusCode: 400,\n responseBody: [],\n };\n }\n\n if (dryRun) {\n return {\n statusCode: 202,\n responseBody: await dryRunCreateImportJobs(deps, importRequests),\n };\n }\n\n const result: Components.Schemas.Import[] = [];\n\n const addedRepos = await handleAddedReposFromCreateImportJobs(\n deps,\n importRequests,\n );\n result.push(...addedRepos);\n const addedReposMap = new Map(\n addedRepos.map(res => [res.repository?.url, res]),\n );\n const remainingRequests = importRequests.filter(\n req => !addedReposMap.has(req.repository.url),\n );\n\n for (const req of remainingRequests) {\n const gitUrl = gitUrlParse(req.repository.url);\n\n // Create PR\n try {\n result.push(await handlePrCreationRequest(deps, req, gitUrl));\n } catch (error: any) {\n result.push({\n errors: [error.message],\n status: 'PR_ERROR',\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n } as Components.Schemas.Import);\n }\n }\n\n sortImports(result);\n\n return {\n statusCode: 202,\n responseBody: result,\n };\n}\n\nasync function dryRunCreateImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n importRequests: Paths.CreateImportJobs.RequestBody,\n) {\n const result: Components.Schemas.Import[] = [];\n for (const req of importRequests) {\n const gitUrl = gitUrlParse(req.repository.url);\n\n const dryRunChecks = await performDryRunChecks(deps, req);\n if (dryRunChecks.errors?.length > 0) {\n deps.logger.warn(\n `Errors while performing dry-run checks: ${dryRunChecks.errors}`,\n );\n }\n result.push({\n errors: dryRunChecks.dryRunStatuses,\n catalogEntityName: req.catalogEntityName,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n });\n }\n return result;\n}\n\nasync function performDryRunChecks(\n deps: {\n logger: LoggerService;\n auth: AuthService;\n catalogApi: CatalogApi;\n config: Config;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n req: Components.Schemas.ImportRequest,\n): Promise<{ dryRunStatuses: CreateImportDryRunStatus[]; errors: string[] }> {\n const checkCatalog = async (\n catalogEntityName: string,\n ): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const hasEntity =\n await deps.catalogHttpClient.hasEntityInCatalog(catalogEntityName);\n if (hasEntity) {\n return { dryRunStatuses: ['CATALOG_ENTITY_CONFLICT'] };\n }\n return {};\n };\n\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const checkEmptyRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const empty = await gitApiService.isRepoEmpty({\n repoUrl: req.repository.url,\n });\n if (empty) {\n return {\n dryRunStatuses: ['REPO_EMPTY'],\n };\n }\n return {};\n };\n\n const checkCatalogInfoPresenceInRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const exists = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: getCatalogFilename(deps.config),\n });\n if (exists) {\n return {\n dryRunStatuses: ['CATALOG_INFO_FILE_EXISTS_IN_REPO'],\n };\n }\n return {};\n };\n\n const checkCodeOwnersFileInRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const gitDirLocation =\n req.approvalTool === 'GITLAB' ? '.gitlab' : '.github';\n const exists = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: `${gitDirLocation}/CODEOWNERS`,\n });\n if (!exists) {\n return {\n dryRunStatuses: ['CODEOWNERS_FILE_NOT_FOUND_IN_REPO'],\n };\n }\n return {};\n };\n\n const dryRunStatuses: CreateImportDryRunStatus[] = [];\n const errors: string[] = [];\n const allChecksFn = [checkEmptyRepo(), checkCatalogInfoPresenceInRepo()];\n if (req.catalogEntityName?.trim()) {\n allChecksFn.push(checkCatalog(req.catalogEntityName));\n }\n if (req.codeOwnersFileAsEntityOwner) {\n allChecksFn.push(checkCodeOwnersFileInRepo());\n }\n const allChecks = await Promise.all(allChecksFn);\n allChecks.flat().forEach(res => {\n if (res.dryRunStatuses) {\n dryRunStatuses.push(...res.dryRunStatuses);\n }\n if (res.errors) {\n errors.push(...res.errors);\n }\n });\n\n dryRunStatuses.sort((a, b) => a.localeCompare(b));\n\n return {\n dryRunStatuses,\n errors,\n };\n}\n\nexport async function findImportStatusByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitlabApiService | GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n approvalTool: string | undefined;\n },\n repoUrl: string,\n defaultBranch?: string,\n includeCatalogInfoContent?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(`Getting bulk import job status for ${repoUrl}..`);\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n defaultBranch,\n },\n approvalTool: deps.approvalTool,\n status: null,\n } as Components.Schemas.Import;\n try {\n // Check to see if there are any PR\n const openImportPr = await deps.gitApiService.findImportOpenPr(\n deps.logger,\n {\n repoUrl: repoUrl,\n includeCatalogInfoContent,\n },\n );\n\n if (!openImportPr?.prUrl) {\n const catalogLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations()\n ).uniqueCatalogUrlLocations.keys();\n\n const catalogUrl = getCatalogUrl(deps.config, repoUrl, defaultBranch);\n let exists = false;\n for (const loc of catalogLocations) {\n if (loc === catalogUrl) {\n exists = true;\n break;\n }\n }\n if (\n exists &&\n (await deps.gitApiService.hasFileInRepo({\n repoUrl,\n defaultBranch,\n fileName: getCatalogFilename(deps.config),\n }))\n ) {\n result.status = 'ADDED';\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n repoUrl,\n defaultBranch,\n );\n }\n // No import PR => let's determine last update from the repository\n const ghRepo =\n await deps.gitApiService.getRepositoryFromIntegrations(repoUrl);\n result.lastUpdate = ghRepo.repository?.updated_at ?? undefined;\n return {\n statusCode: 200,\n responseBody: result,\n };\n }\n result.status = 'WAIT_PR_APPROVAL';\n result[deps.approvalTool === 'GITLAB' ? 'gitlab' : 'github'] = {\n pullRequest: {\n number: openImportPr.prNum,\n url: openImportPr.prUrl,\n title: openImportPr.prTitle,\n body: openImportPr.prBody,\n catalogInfoContent: openImportPr.prCatalogInfoContent,\n },\n };\n\n result.lastUpdate = openImportPr.lastUpdate;\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n if (error.message?.includes('Not Found')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n result.status = 'PR_ERROR';\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nexport async function findTaskImportStatusByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n githubApiService: GithubApiService;\n gitlabApiService: GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n repositoryDao: RepositoryDao<'repositories'>;\n taskDao: ScaffolderTaskDao;\n taskLocationsDao: TaskLocationsDao;\n discovery: DiscoveryService;\n auth: AuthService;\n },\n repoUrl: string,\n skipTasks?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(`Getting bulk import job status for ${repoUrl}.`);\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result: Components.Schemas.Import = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n },\n };\n try {\n const repository = await deps.repositoryDao.findRepositoryByUrl(repoUrl);\n if (!repository) {\n throw new NotFoundError(`Repository ${repoUrl} info was not found`);\n }\n\n const task = await deps.taskDao.lastExecutedTaskByRepoId(repository?.id);\n if (!task) {\n throw new NotFoundError(\n `Unable to find scaffolder task for repository: ${repository?.id}`,\n );\n }\n\n const scaffolderUrl = await deps.discovery.getBaseUrl('scaffolder');\n const { token } = await deps.auth.getPluginRequestToken({\n onBehalfOf: await deps.auth.getOwnServiceCredentials(),\n targetPluginId: 'scaffolder',\n });\n\n const response = await fetch(`${scaffolderUrl}/v2/tasks/${task.taskId}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n if (!skipTasks) {\n const tasks = await deps.taskDao.findTasksByRepositoryId(repository.id);\n const tasksWithLocations = await Promise.all(\n tasks.map(async taskItem => {\n const locations = await deps.taskLocationsDao.findLocationsByTaskId(\n taskItem.taskId,\n );\n const taskLocations = locations.map(location => location.location);\n return {\n ...taskItem,\n locations: taskLocations,\n };\n }),\n );\n result.tasks = tasksWithLocations;\n }\n\n result.task = { taskId: task.taskId };\n let data;\n if (response.ok) {\n data = await response.json();\n result.lastUpdate = data.lastHeartbeatAt;\n\n const approvalTool =\n repository.approvalTool as unknown as Components.Schemas.ApprovalTool;\n const pullRequest = await parsePullOrMergeRequestInfo(\n data.state?.checkpoints,\n {\n githubApiService: deps.githubApiService,\n gitlabApiService: deps.gitlabApiService,\n approvalTool,\n logger: deps.logger,\n repoUrl,\n },\n );\n if (pullRequest && approvalTool === 'GITLAB') {\n result.gitlab = { pullRequest };\n }\n if (pullRequest && approvalTool === 'GIT') {\n result.github = { pullRequest };\n }\n\n result.status =\n `TASK_${(data.status as string)?.toLocaleUpperCase()}` as Components.Schemas.TaskImportStatus;\n } else {\n const errMsg =\n (await response.text()) ??\n `Failed to fetch task ${task.taskId}. Response status: ${response.status}`;\n throw new Error(errMsg);\n }\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n result.status = 'TASK_FETCH_FAILED';\n if (error.name?.includes('NotFoundError')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nexport async function findOrchestratorImportStatusByRepo(\n deps: {\n logger: LoggerService;\n orchestratorRepositoryDao: RepositoryDao<'orchestrator_repositories'>;\n orchestratorWorkflowDao: OrchestratorWorkflowDao;\n discovery: DiscoveryService;\n },\n repoUrl: string,\n token: string,\n skipWorkflows?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(\n `Getting orchestrator workflow import job status for ${repoUrl}.`,\n );\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result: Components.Schemas.Import = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n },\n };\n try {\n const repository =\n await deps.orchestratorRepositoryDao.findRepositoryByUrl(repoUrl);\n if (repository) {\n const workflow =\n await deps.orchestratorWorkflowDao.lastExecutedWorkflowByRepoId(\n repository.id,\n );\n if (!workflow) {\n throw new NotFoundError(\n `Workflow for repository ${repoUrl} was not found`,\n );\n }\n if (workflow.instanceId) {\n const baseUrl = await deps.discovery.getBaseUrl('orchestrator');\n const orchestratorApi = new DefaultApi(new Configuration(), baseUrl);\n const response = await orchestratorApi.getInstanceById(\n workflow.instanceId,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n },\n );\n\n const instance = response.data;\n if (instance) {\n result.workflow = {\n workflowId: instance.id,\n };\n if (!skipWorkflows) {\n const workflows =\n await deps.orchestratorWorkflowDao.findWorkflowsByRepositoryId(\n repository.id,\n );\n result.workflows = workflows.map((w: OrchestratorWorkflow) => ({\n workflowId: w.instanceId,\n }));\n }\n\n result.approvalTool =\n repository.approvalTool as unknown as Components.Schemas.ApprovalTool;\n result.lastUpdate = instance.end;\n const status =\n `WORKFLOW_${(instance.state as string)?.toLocaleUpperCase()}` as Components.Schemas.WorkflowImportStatus;\n result.status = status;\n }\n }\n }\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n result.status = 'WORKFLOW_FETCH_FAILED';\n if (error.name?.includes('NotFoundError')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nasync function parsePullOrMergeRequestInfo(\n checkpoints: Record<string, any>,\n {\n githubApiService,\n gitlabApiService,\n approvalTool,\n logger,\n repoUrl,\n }: {\n githubApiService: GithubApiService;\n gitlabApiService: GitlabApiService;\n approvalTool: Components.Schemas.ApprovalTool;\n logger: LoggerService;\n repoUrl: string;\n },\n): Promise<Components.Schemas.PullRequest | undefined> {\n // return errors ?\n if (approvalTool !== 'GITLAB' && approvalTool !== 'GIT') {\n return undefined;\n }\n const gitApiService =\n approvalTool === 'GITLAB' ? gitlabApiService : githubApiService;\n\n for (const key in checkpoints) {\n if (!checkpoints.hasOwnProperty(key)) {\n continue;\n }\n try {\n if (\n key.startsWith('v1.task.checkpoint.publish.create.pr') ||\n key.startsWith('v1.task.checkpoint.publish.create.mr')\n ) {\n const url =\n checkpoints[key]?.value?.html_url ??\n checkpoints[key]?.value?.mrWebUrl;\n if (!url) {\n continue;\n }\n const prNumber = Number.parseInt(url.split('/').pop()!, 10);\n const prDetails = await gitApiService.getPullRequest(repoUrl, prNumber);\n\n let catalogInfoContent: string | undefined;\n if (prDetails.prSha) {\n catalogInfoContent = await gitApiService.getCatalogInfoFile(logger, {\n repoUrl,\n prHeadSha: prDetails.prSha,\n prNumber,\n });\n }\n return {\n url,\n number: prNumber,\n title: prDetails.title,\n body: prDetails.body,\n status: prDetails.merged ? 'PR_MERGED' : 'WAIT_PR_APPROVAL',\n catalogInfoContent,\n };\n }\n } catch (err) {\n logger.warn(`Error while processing checkpoint ${key}: ${err}`);\n continue;\n }\n }\n\n return undefined;\n}\n\nexport async function deleteImportByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n repoUrl: string,\n defaultBranch?: string,\n): Promise<HandlerResponse<void>> {\n deps.logger.debug(`Deleting bulk import job status for ${repoUrl}..`);\n\n // Check to see if there are any PR\n const openImportPr = await deps.gitApiService.findImportOpenPr(deps.logger, {\n repoUrl: repoUrl,\n });\n\n const gitUrl = gitUrlParse(repoUrl);\n if (openImportPr?.prUrl) {\n // Close PR\n const appTitle =\n deps.config.getOptionalString('app.title') ?? 'Red Hat Developer Hub';\n const appBaseUrl = deps.config.getString('app.baseUrl');\n\n await deps.gitApiService.closeImportPR(deps.logger, {\n repoUrl,\n gitUrl,\n comment: `Closing PR upon request for bulk import deletion. This request was created from [${appTitle}](${appBaseUrl}).`,\n });\n }\n // Also delete the import branch, so that it is not outdated if we try later to import the repo again\n await deps.gitApiService.deleteImportBranch({\n repoUrl,\n gitUrl,\n });\n // Remove Location from catalog\n const catalogUrl = getCatalogUrl(deps.config, repoUrl, defaultBranch);\n const findLocationFrom = (list: { id?: string; target: string }[]) => {\n for (const loc of list) {\n if (loc.target === catalogUrl) {\n return loc.id;\n }\n }\n return undefined;\n };\n\n const locationId = findLocationFrom(\n (\n await deps.catalogHttpClient.listCatalogUrlLocationsByIdFromLocationsEndpoint()\n ).locations,\n );\n if (locationId) {\n await deps.catalogHttpClient.deleteCatalogLocationById(locationId);\n }\n\n return {\n statusCode: 204,\n responseBody: undefined,\n };\n}\n\nexport async function deleteRepositoryRecord<\n DAO extends RepositoryDao<RepositoryName>,\n>(\n deps: {\n logger: LoggerService;\n dao: DAO;\n },\n repoUrl: string,\n): Promise<HandlerResponse<void>> {\n deps.logger.debug(`Deleting repository from database by name ${repoUrl}...`);\n try {\n await deps.dao.deleteRepository(repoUrl);\n\n return {\n statusCode: 204,\n responseBody: undefined,\n };\n } catch (error: any) {\n deps.logger.error(\n `Failed to delete repository from database by url ${repoUrl}`,\n error,\n );\n return {\n statusCode: 500,\n };\n }\n}\n"],"names":["DefaultSortColumn","DefaultSortOrder","getNestedValue","DefaultPageNumber","DefaultPageSize","getCatalogFilename","parseGitURLForApprovalTool","imports","paginateArray","logErrorIfNeeded","getCatalogUrl","gitUrlParse","errors","NotFoundError","DefaultApi","Configuration"],"mappings":"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"}
1
+ {"version":3,"file":"bulkImports.cjs.js","sources":["../../../../src/service/handlers/import/bulkImports.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 */\n\nimport type {\n AuthService,\n DiscoveryService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport { NotFoundError } from '@backstage/errors';\n\nimport gitUrlParse from 'git-url-parse';\n\nimport {\n Configuration,\n DefaultApi,\n} from '@red-hat-developer-hub/backstage-plugin-orchestrator-common';\n\nimport { CatalogHttpClient } from '../../../catalog/catalogHttpClient';\nimport type { CatalogInfoGenerator } from '../../../catalog/catalogInfoGenerator';\nimport {\n getCatalogFilename,\n getCatalogUrl,\n} from '../../../catalog/catalogUtils';\nimport {\n OrchestratorWorkflow,\n OrchestratorWorkflowDao,\n RepositoryDao,\n RepositoryName,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../../../database/repositoryDao';\nimport type { Components, Paths } from '../../../generated/openapi';\nimport type { GithubApiService } from '../../../github';\nimport { GitlabApiService } from '../../../gitlab';\nimport {\n getNestedValue,\n logErrorIfNeeded,\n paginateArray,\n parseGitURLForApprovalTool,\n} from '../../../helpers';\nimport { GitApiService } from '../../../scm/GitApiService';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n DefaultSortColumn,\n DefaultSortOrder,\n type HandlerResponse,\n} from '../handlers';\n\ntype CreateImportDryRunStatus =\n | 'CATALOG_ENTITY_CONFLICT'\n | 'CATALOG_INFO_FILE_EXISTS_IN_REPO'\n | 'CODEOWNERS_FILE_NOT_FOUND_IN_REPO'\n | 'REPO_EMPTY';\n\ntype FindAllImportsResponse =\n | Components.Schemas.Import[]\n | Components.Schemas.ImportJobListV2;\n\nexport function sortImports(\n imports: Components.Schemas.Import[],\n sortColumn: Components.Parameters.SortColumnQueryParam = DefaultSortColumn,\n sortOrder: Components.Parameters.SortOrderQueryParam = DefaultSortOrder,\n) {\n imports.sort((a, b) => {\n const value1 = getNestedValue(a, sortColumn);\n const value2 = getNestedValue(b, sortColumn);\n // Handle cases where values are undefined\n if (value1 === undefined && value2 === undefined) return 0;\n if (value1 === undefined) return sortOrder === 'asc' ? -1 : 1;\n if (value2 === undefined) return sortOrder === 'asc' ? 1 : -1;\n\n if (sortColumn === 'lastUpdate') {\n const date1 = new Date(value1); // Convert string to Date object\n const date2 = new Date(value2); // Convert string to Date object\n // Compare dates\n return sortOrder === 'asc'\n ? date2.getTime() - date1.getTime()\n : date1.getTime() - date2.getTime();\n }\n // Compare values based on sort order\n return sortOrder === 'asc'\n ? value1.localeCompare(value2)\n : value2.localeCompare(value1);\n });\n}\n\nexport async function findAllImports(\n deps: {\n logger: LoggerService;\n config: Config;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n requestHeaders?: {\n apiVersion?: Paths.FindAllImports.Parameters.ApiVersion;\n },\n queryParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n sortColumn?: Components.Parameters.SortColumnQueryParam;\n sortOrder?: Components.Parameters.SortOrderQueryParam;\n },\n): Promise<HandlerResponse<FindAllImportsResponse>> {\n const apiVersion = requestHeaders?.apiVersion ?? 'v1';\n const search = queryParams?.search;\n const pageNumber = queryParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = queryParams?.pageSize ?? DefaultPageSize;\n const sortColumn = queryParams?.sortColumn ?? DefaultSortColumn;\n const sortOrder = queryParams?.sortOrder ?? DefaultSortOrder;\n\n const catalogFilename = getCatalogFilename(deps.config);\n\n const allLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations(\n search,\n pageNumber,\n pageSize,\n )\n ).uniqueCatalogUrlLocations;\n\n // resolve default branches for each unique repo URL from GH,\n // because we cannot easily determine that from the location target URL.\n // It can be 'main' or something more convoluted like 'our/awesome/main'.\n const defaultBranchByRepoUrl = await resolveReposDefaultBranches(\n deps.logger,\n deps.gitlabApiService,\n deps.githubApiService,\n allLocations.keys(),\n catalogFilename,\n );\n\n // filter out locations that do not match what we are expecting, i.e.:\n // an URL to a catalog-info YAML file at the root of the repo\n const importCandidates = findImportCandidates(\n allLocations.keys(),\n defaultBranchByRepoUrl,\n catalogFilename,\n );\n\n // Keep only repos that are accessible from the configured GH/GL integrations\n const importsReachableFromGHIntegrations =\n await deps.githubApiService.filterLocationsAccessibleFromIntegrations(\n importCandidates.filter(val => {\n return parseGitURLForApprovalTool(val) === 'GIT';\n }),\n );\n\n const importsReachableFromGLIntegrations =\n await deps.gitlabApiService.filterLocationsAccessibleFromIntegrations(\n importCandidates.filter(val => {\n return parseGitURLForApprovalTool(val) === 'GITLAB';\n }),\n );\n\n // Merge the two lists together and map the appropriate approvalTool\n const mergedReachbleFromIntegrations = importsReachableFromGHIntegrations\n .map(val => {\n return {\n loc: val,\n approvalTool: 'GIT',\n };\n })\n .concat(\n importsReachableFromGLIntegrations.map(val => {\n return {\n loc: val,\n approvalTool: 'GITLAB',\n };\n }),\n );\n\n const repoUrlToLocation = new Map<string, string>();\n\n // now fetch the import statuses in different promises\n const importStatusPromises: Promise<\n HandlerResponse<Components.Schemas.Import>\n >[] = [];\n for (const imports of mergedReachbleFromIntegrations) {\n const repoUrl = repoUrlFromLocation(imports.loc);\n if (!repoUrl) {\n continue;\n }\n repoUrlToLocation.set(repoUrl, imports.loc);\n\n importStatusPromises.push(\n findImportStatusByRepo(\n {\n logger: deps.logger,\n config: deps.config,\n gitApiService:\n imports.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService,\n catalogHttpClient: deps.catalogHttpClient,\n approvalTool: imports.approvalTool,\n },\n repoUrl,\n defaultBranchByRepoUrl.get(repoUrl),\n false,\n ),\n );\n }\n\n const result = await Promise.all(importStatusPromises);\n const imports = result\n .filter(res => res.responseBody)\n .map(res => res.responseBody!)\n .map(res => {\n const key = res?.repository?.url;\n const location = key ? repoUrlToLocation.get(key) : undefined;\n return {\n ...res,\n source: location ? allLocations.get(location)?.source : undefined,\n };\n });\n\n // sorting the output to make it deterministic and easy to navigate in the UI\n\n sortImports(imports, sortColumn, sortOrder);\n const paginated = paginateArray(imports, pageNumber, pageSize);\n if (apiVersion === 'v1') {\n return {\n statusCode: 200,\n responseBody: paginated.result,\n };\n }\n return {\n statusCode: 200,\n responseBody: {\n imports: paginated.result,\n totalCount: paginated.totalCount,\n page: pageNumber,\n size: pageSize,\n },\n };\n}\n\nasync function resolveReposDefaultBranches(\n logger: LoggerService,\n gitlabApiService: GitlabApiService,\n githubApiService: GithubApiService,\n allLocations: Iterable<string>,\n catalogFilename: string,\n) {\n const defaultBranchByRepoUrlPromises: Promise<{\n repoUrl: string;\n defaultBranch?: string;\n }>[] = [];\n for (const loc of allLocations) {\n // loc has the following format: https://github.com/<org>/<repo>/blob/<default-branch>/catalog-info.yaml\n // but it can have a more convoluted format like 'https://github.com/redhat-developer/rhdh-plugins/blob/main/plugins/scaffolder-annotator-action/examples/templates/01-scaffolder-template.yaml'\n // if registered manually from the 'Register existing component' feature in Backstage.\n if (!loc.endsWith(catalogFilename)) {\n logger.debug(\n `Ignored location ${loc} because it does not point to a file named ${catalogFilename}`,\n );\n continue;\n }\n const repoUrl = repoUrlFromLocation(loc);\n if (!repoUrl) {\n continue;\n }\n // Have to do this for Both the gitlab/github, possibly a better way?\n // Should probably parse the URL to figure out which to use?\n defaultBranchByRepoUrlPromises.push(\n (parseGitURLForApprovalTool(repoUrl) === 'GITLAB'\n ? gitlabApiService\n : githubApiService\n )\n .getRepositoryFromIntegrations(repoUrl)\n .then(resp => {\n return { repoUrl, defaultBranch: resp?.repository?.default_branch };\n })\n .catch((err: any) => {\n logErrorIfNeeded(\n logger,\n `Ignored repo ${repoUrl} due to an error while fetching details from GitHub`,\n err,\n );\n return {\n repoUrl,\n defaultBranch: undefined,\n };\n }),\n );\n }\n const defaultBranchesResponses = await Promise.all(\n defaultBranchByRepoUrlPromises,\n );\n return new Map(\n defaultBranchesResponses\n .flat()\n .filter(r => r.defaultBranch)\n .map(r => [r.repoUrl, r.defaultBranch!]),\n );\n}\n\nfunction repoUrlFromLocation(loc: string) {\n const split = loc.split('/blob/');\n if (split.length < 2) {\n return undefined;\n }\n return split[0];\n}\n\nfunction findImportCandidates(\n allLocations: Iterable<string>,\n defaultBranchByRepoUrl: Map<string, string>,\n catalogFilename: string,\n) {\n const filteredLocations: string[] = [];\n for (const loc of allLocations) {\n const repoUrl = repoUrlFromLocation(loc);\n if (!repoUrl) {\n continue;\n }\n\n const defaultBranch = defaultBranchByRepoUrl.get(repoUrl);\n if (!defaultBranch) {\n continue;\n }\n if (loc !== `${repoUrl}/blob/${defaultBranch}/${catalogFilename}`) {\n // Because users can use the \"Register existing component\" workflow to register a Location\n // using any file path in the repo, we consider a repository as an Import Location only\n // if it is at the root of the repository, because that is what the import PR ultimately does.\n continue;\n }\n filteredLocations.push(loc);\n }\n return filteredLocations;\n}\n\nasync function createPR(\n gitApiService: GitApiService,\n logger: LoggerService,\n req: Components.Schemas.ImportRequest,\n gitUrl: gitUrlParse.GitUrl,\n catalogInfoGenerator: CatalogInfoGenerator,\n config: Config,\n) {\n const appTitle =\n config.getOptionalString('app.title') ?? 'Red Hat Developer Hub';\n const appBaseUrl = config.getString('app.baseUrl');\n const catalogFileName = getCatalogFilename(config);\n return await gitApiService.submitPrToRepo(logger, {\n repoUrl: req.repository.url,\n gitUrl: gitUrl,\n defaultBranch: req.repository.defaultBranch,\n catalogInfoContent:\n req.catalogInfoContent ??\n (await catalogInfoGenerator.generateDefaultCatalogInfoContent(\n req.repository.url,\n )),\n prTitle:\n req[req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']?.pullRequest\n ?.title ?? `Add ${catalogFileName}`,\n prBody:\n req[req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']?.pullRequest\n ?.body ??\n `\nThis pull request adds a **Backstage entity metadata file** to this repository so that the component can be added to a Backstage application.\n\nAfter this pull request is merged, the component will become available in the [${appTitle} software catalog](${appBaseUrl}).\n\nFor more information, read an [overview of the Backstage software catalog](https://backstage.io/docs/features/software-catalog/).\n`,\n });\n}\n\nasync function handleAddedReposFromCreateImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n importRequests: Components.Schemas.ImportRequest[],\n) {\n const result: Components.Schemas.Import[] = [];\n\n for (const req of importRequests) {\n // Check if repo is already imported\n const repoCatalogUrl = getCatalogUrl(\n deps.config,\n req.repository.url,\n req.repository.defaultBranch,\n );\n const hasLocation =\n await deps.catalogHttpClient.verifyLocationExistence(repoCatalogUrl);\n if (!hasLocation) {\n continue;\n }\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const hasCatalogInfoFileInRepo = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: getCatalogFilename(deps.config),\n });\n if (!hasCatalogInfoFileInRepo) {\n continue;\n }\n\n const ghRepo = await gitApiService.getRepositoryFromIntegrations(\n req.repository.url,\n );\n\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n req.repository.url,\n req.repository.defaultBranch,\n );\n\n const gitUrl = gitUrlParse(req.repository.url);\n result.push({\n status: 'ADDED',\n lastUpdate: ghRepo?.repository?.updated_at ?? undefined,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n });\n }\n return result;\n}\n\nasync function handlePrCreationRequest(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n req: Components.Schemas.ImportRequest,\n gitUrl: gitUrlParse.GitUrl,\n): Promise<Components.Schemas.Import> {\n const repoCatalogUrl = getCatalogUrl(\n deps.config,\n req.repository.url,\n req.repository.defaultBranch,\n );\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const prToRepo = await createPR(\n gitApiService,\n deps.logger,\n req,\n gitUrl,\n deps.catalogInfoGenerator,\n deps.config,\n );\n if (prToRepo.errors && prToRepo.errors.length > 0) {\n return {\n errors: prToRepo.errors,\n status: 'PR_ERROR',\n repository: req.repository,\n };\n }\n if (prToRepo.prUrl) {\n deps.logger.debug(`Created new PR from request: ${prToRepo.prUrl}`);\n }\n\n // Create Location\n await deps.catalogHttpClient.possiblyCreateLocation(repoCatalogUrl);\n\n if (prToRepo.hasChanges === false) {\n deps.logger.debug(\n `No bulk import PR created on ${req.repository.url} since its default branch (${req.repository.defaultBranch}) already contains a catalog-info file`,\n );\n\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n req.repository.url,\n req.repository.defaultBranch,\n );\n return {\n status: 'ADDED',\n lastUpdate: prToRepo.lastUpdate,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n };\n }\n\n return {\n approvalTool: req.approvalTool ?? 'GIT',\n errors: prToRepo.errors,\n status: 'WAIT_PR_APPROVAL',\n lastUpdate: prToRepo.lastUpdate,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n [req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']: {\n pullRequest: {\n url: prToRepo.prUrl,\n number: prToRepo.prNumber,\n },\n },\n };\n}\n\nexport async function createImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n reqParams: {\n importRequests: Paths.CreateImportJobs.RequestBody;\n dryRun?: boolean;\n },\n): Promise<HandlerResponse<Components.Schemas.Import[]>> {\n const dryRun = reqParams.dryRun ?? false;\n const importRequests = reqParams.importRequests;\n deps.logger.debug(\n `Handling request to import ${importRequests?.length} repo(s) (dryRun=${dryRun})..`,\n );\n\n if (importRequests.length === 0) {\n deps.logger.debug('Missing import requests from request body');\n return {\n statusCode: 400,\n responseBody: [],\n };\n }\n\n if (dryRun) {\n return {\n statusCode: 202,\n responseBody: await dryRunCreateImportJobs(deps, importRequests),\n };\n }\n\n const result: Components.Schemas.Import[] = [];\n\n const addedRepos = await handleAddedReposFromCreateImportJobs(\n deps,\n importRequests,\n );\n result.push(...addedRepos);\n const addedReposMap = new Map(\n addedRepos.map(res => [res.repository?.url, res]),\n );\n const remainingRequests = importRequests.filter(\n req => !addedReposMap.has(req.repository.url),\n );\n\n for (const req of remainingRequests) {\n const gitUrl = gitUrlParse(req.repository.url);\n\n // Create PR\n try {\n result.push(await handlePrCreationRequest(deps, req, gitUrl));\n } catch (error: any) {\n result.push({\n errors: [error.message],\n status: 'PR_ERROR',\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n } as Components.Schemas.Import);\n }\n }\n\n sortImports(result);\n\n return {\n statusCode: 202,\n responseBody: result,\n };\n}\n\nasync function dryRunCreateImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n importRequests: Paths.CreateImportJobs.RequestBody,\n) {\n const result: Components.Schemas.Import[] = [];\n for (const req of importRequests) {\n const gitUrl = gitUrlParse(req.repository.url);\n\n const dryRunChecks = await performDryRunChecks(deps, req);\n if (dryRunChecks.errors?.length > 0) {\n deps.logger.warn(\n `Errors while performing dry-run checks: ${dryRunChecks.errors}`,\n );\n }\n result.push({\n errors: dryRunChecks.dryRunStatuses,\n catalogEntityName: req.catalogEntityName,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n });\n }\n return result;\n}\n\nasync function performDryRunChecks(\n deps: {\n logger: LoggerService;\n auth: AuthService;\n config: Config;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n req: Components.Schemas.ImportRequest,\n): Promise<{ dryRunStatuses: CreateImportDryRunStatus[]; errors: string[] }> {\n const checkCatalog = async (\n catalogEntityName: string,\n ): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const hasEntity =\n await deps.catalogHttpClient.hasEntityInCatalog(catalogEntityName);\n if (hasEntity) {\n return { dryRunStatuses: ['CATALOG_ENTITY_CONFLICT'] };\n }\n return {};\n };\n\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const checkEmptyRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const empty = await gitApiService.isRepoEmpty({\n repoUrl: req.repository.url,\n });\n if (empty) {\n return {\n dryRunStatuses: ['REPO_EMPTY'],\n };\n }\n return {};\n };\n\n const checkCatalogInfoPresenceInRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const exists = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: getCatalogFilename(deps.config),\n });\n if (exists) {\n return {\n dryRunStatuses: ['CATALOG_INFO_FILE_EXISTS_IN_REPO'],\n };\n }\n return {};\n };\n\n const checkCodeOwnersFileInRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const gitDirLocation =\n req.approvalTool === 'GITLAB' ? '.gitlab' : '.github';\n const exists = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: `${gitDirLocation}/CODEOWNERS`,\n });\n if (!exists) {\n return {\n dryRunStatuses: ['CODEOWNERS_FILE_NOT_FOUND_IN_REPO'],\n };\n }\n return {};\n };\n\n const dryRunStatuses: CreateImportDryRunStatus[] = [];\n const errors: string[] = [];\n const allChecksFn = [checkEmptyRepo(), checkCatalogInfoPresenceInRepo()];\n if (req.catalogEntityName?.trim()) {\n allChecksFn.push(checkCatalog(req.catalogEntityName));\n }\n if (req.codeOwnersFileAsEntityOwner) {\n allChecksFn.push(checkCodeOwnersFileInRepo());\n }\n const allChecks = await Promise.all(allChecksFn);\n allChecks.flat().forEach(res => {\n if (res.dryRunStatuses) {\n dryRunStatuses.push(...res.dryRunStatuses);\n }\n if (res.errors) {\n errors.push(...res.errors);\n }\n });\n\n dryRunStatuses.sort((a, b) => a.localeCompare(b));\n\n return {\n dryRunStatuses,\n errors,\n };\n}\n\nexport async function findImportStatusByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitlabApiService | GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n approvalTool: string | undefined;\n },\n repoUrl: string,\n defaultBranch?: string,\n includeCatalogInfoContent?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(`Getting bulk import job status for ${repoUrl}..`);\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n defaultBranch,\n },\n approvalTool: deps.approvalTool,\n status: null,\n } as Components.Schemas.Import;\n try {\n // Check to see if there are any PR\n const openImportPr = await deps.gitApiService.findImportOpenPr(\n deps.logger,\n {\n repoUrl: repoUrl,\n includeCatalogInfoContent,\n },\n );\n\n if (!openImportPr?.prUrl) {\n const catalogLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations()\n ).uniqueCatalogUrlLocations.keys();\n\n const catalogUrl = getCatalogUrl(deps.config, repoUrl, defaultBranch);\n let exists = false;\n for (const loc of catalogLocations) {\n if (loc === catalogUrl) {\n exists = true;\n break;\n }\n }\n if (\n exists &&\n (await deps.gitApiService.hasFileInRepo({\n repoUrl,\n defaultBranch,\n fileName: getCatalogFilename(deps.config),\n }))\n ) {\n result.status = 'ADDED';\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n repoUrl,\n defaultBranch,\n );\n }\n // No import PR => let's determine last update from the repository\n const ghRepo =\n await deps.gitApiService.getRepositoryFromIntegrations(repoUrl);\n result.lastUpdate = ghRepo.repository?.updated_at ?? undefined;\n return {\n statusCode: 200,\n responseBody: result,\n };\n }\n result.status = 'WAIT_PR_APPROVAL';\n result[deps.approvalTool === 'GITLAB' ? 'gitlab' : 'github'] = {\n pullRequest: {\n number: openImportPr.prNum,\n url: openImportPr.prUrl,\n title: openImportPr.prTitle,\n body: openImportPr.prBody,\n catalogInfoContent: openImportPr.prCatalogInfoContent,\n },\n };\n\n result.lastUpdate = openImportPr.lastUpdate;\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n if (error.message?.includes('Not Found')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n result.status = 'PR_ERROR';\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nexport async function findTaskImportStatusByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n githubApiService: GithubApiService;\n gitlabApiService: GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n repositoryDao: RepositoryDao<'repositories'>;\n taskDao: ScaffolderTaskDao;\n taskLocationsDao: TaskLocationsDao;\n discovery: DiscoveryService;\n auth: AuthService;\n },\n repoUrl: string,\n skipTasks?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(`Getting bulk import job status for ${repoUrl}.`);\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result: Components.Schemas.Import = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n },\n };\n try {\n const repository = await deps.repositoryDao.findRepositoryByUrl(repoUrl);\n if (!repository) {\n throw new NotFoundError(`Repository ${repoUrl} info was not found`);\n }\n\n const task = await deps.taskDao.lastExecutedTaskByRepoId(repository?.id);\n if (!task) {\n throw new NotFoundError(\n `Unable to find scaffolder task for repository: ${repository?.id}`,\n );\n }\n\n const scaffolderUrl = await deps.discovery.getBaseUrl('scaffolder');\n const { token } = await deps.auth.getPluginRequestToken({\n onBehalfOf: await deps.auth.getOwnServiceCredentials(),\n targetPluginId: 'scaffolder',\n });\n\n const response = await fetch(`${scaffolderUrl}/v2/tasks/${task.taskId}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n if (!skipTasks) {\n const tasks = await deps.taskDao.findTasksByRepositoryId(repository.id);\n const tasksWithLocations = await Promise.all(\n tasks.map(async taskItem => {\n const locations = await deps.taskLocationsDao.findLocationsByTaskId(\n taskItem.taskId,\n );\n const taskLocations = locations.map(location => location.location);\n return {\n ...taskItem,\n locations: taskLocations,\n };\n }),\n );\n result.tasks = tasksWithLocations;\n }\n\n result.task = { taskId: task.taskId };\n let data;\n if (response.ok) {\n data = await response.json();\n result.lastUpdate = data.lastHeartbeatAt;\n\n const approvalTool =\n repository.approvalTool as unknown as Components.Schemas.ApprovalTool;\n const pullRequest = await parsePullOrMergeRequestInfo(\n data.state?.checkpoints,\n {\n githubApiService: deps.githubApiService,\n gitlabApiService: deps.gitlabApiService,\n approvalTool,\n logger: deps.logger,\n repoUrl,\n },\n );\n if (pullRequest && approvalTool === 'GITLAB') {\n result.gitlab = { pullRequest };\n }\n if (pullRequest && approvalTool === 'GIT') {\n result.github = { pullRequest };\n }\n\n result.status =\n `TASK_${(data.status as string)?.toLocaleUpperCase()}` as Components.Schemas.TaskImportStatus;\n } else {\n const errMsg =\n (await response.text()) ??\n `Failed to fetch task ${task.taskId}. Response status: ${response.status}`;\n throw new Error(errMsg);\n }\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n result.status = 'TASK_FETCH_FAILED';\n if (error.name?.includes('NotFoundError')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nexport async function findOrchestratorImportStatusByRepo(\n deps: {\n logger: LoggerService;\n orchestratorRepositoryDao: RepositoryDao<'orchestrator_repositories'>;\n orchestratorWorkflowDao: OrchestratorWorkflowDao;\n discovery: DiscoveryService;\n },\n repoUrl: string,\n token: string,\n skipWorkflows?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(\n `Getting orchestrator workflow import job status for ${repoUrl}.`,\n );\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result: Components.Schemas.Import = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n },\n };\n try {\n const repository =\n await deps.orchestratorRepositoryDao.findRepositoryByUrl(repoUrl);\n if (repository) {\n const workflow =\n await deps.orchestratorWorkflowDao.lastExecutedWorkflowByRepoId(\n repository.id,\n );\n if (!workflow) {\n throw new NotFoundError(\n `Workflow for repository ${repoUrl} was not found`,\n );\n }\n if (workflow.instanceId) {\n const baseUrl = await deps.discovery.getBaseUrl('orchestrator');\n const orchestratorApi = new DefaultApi(new Configuration(), baseUrl);\n const response = await orchestratorApi.getInstanceById(\n workflow.instanceId,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n },\n );\n\n const instance = response.data;\n if (instance) {\n result.workflow = {\n workflowId: instance.id,\n };\n if (!skipWorkflows) {\n const workflows =\n await deps.orchestratorWorkflowDao.findWorkflowsByRepositoryId(\n repository.id,\n );\n result.workflows = workflows.map((w: OrchestratorWorkflow) => ({\n workflowId: w.instanceId,\n }));\n }\n\n result.approvalTool =\n repository.approvalTool as unknown as Components.Schemas.ApprovalTool;\n result.lastUpdate = instance.end;\n const status =\n `WORKFLOW_${(instance.state as string)?.toLocaleUpperCase()}` as Components.Schemas.WorkflowImportStatus;\n result.status = status;\n }\n }\n }\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n result.status = 'WORKFLOW_FETCH_FAILED';\n if (error.name?.includes('NotFoundError')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nasync function parsePullOrMergeRequestInfo(\n checkpoints: Record<string, any>,\n {\n githubApiService,\n gitlabApiService,\n approvalTool,\n logger,\n repoUrl,\n }: {\n githubApiService: GithubApiService;\n gitlabApiService: GitlabApiService;\n approvalTool: Components.Schemas.ApprovalTool;\n logger: LoggerService;\n repoUrl: string;\n },\n): Promise<Components.Schemas.PullRequest | undefined> {\n // return errors ?\n if (approvalTool !== 'GITLAB' && approvalTool !== 'GIT') {\n return undefined;\n }\n const gitApiService =\n approvalTool === 'GITLAB' ? gitlabApiService : githubApiService;\n\n for (const key in checkpoints) {\n if (!checkpoints.hasOwnProperty(key)) {\n continue;\n }\n try {\n if (\n key.startsWith('v1.task.checkpoint.publish.create.pr') ||\n key.startsWith('v1.task.checkpoint.publish.create.mr')\n ) {\n const url =\n checkpoints[key]?.value?.html_url ??\n checkpoints[key]?.value?.mrWebUrl;\n if (!url) {\n continue;\n }\n const prNumber = Number.parseInt(url.split('/').pop()!, 10);\n const prDetails = await gitApiService.getPullRequest(repoUrl, prNumber);\n\n let catalogInfoContent: string | undefined;\n if (prDetails.prSha) {\n catalogInfoContent = await gitApiService.getCatalogInfoFile(logger, {\n repoUrl,\n prHeadSha: prDetails.prSha,\n prNumber,\n });\n }\n return {\n url,\n number: prNumber,\n title: prDetails.title,\n body: prDetails.body,\n status: prDetails.merged ? 'PR_MERGED' : 'WAIT_PR_APPROVAL',\n catalogInfoContent,\n };\n }\n } catch (err) {\n logger.warn(`Error while processing checkpoint ${key}: ${err}`);\n continue;\n }\n }\n\n return undefined;\n}\n\nexport async function deleteImportByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n repoUrl: string,\n defaultBranch?: string,\n): Promise<HandlerResponse<void>> {\n deps.logger.debug(`Deleting bulk import job status for ${repoUrl}..`);\n\n // Check to see if there are any PR\n const openImportPr = await deps.gitApiService.findImportOpenPr(deps.logger, {\n repoUrl: repoUrl,\n });\n\n const gitUrl = gitUrlParse(repoUrl);\n if (openImportPr?.prUrl) {\n // Close PR\n const appTitle =\n deps.config.getOptionalString('app.title') ?? 'Red Hat Developer Hub';\n const appBaseUrl = deps.config.getString('app.baseUrl');\n\n await deps.gitApiService.closeImportPR(deps.logger, {\n repoUrl,\n gitUrl,\n comment: `Closing PR upon request for bulk import deletion. This request was created from [${appTitle}](${appBaseUrl}).`,\n });\n }\n // Also delete the import branch, so that it is not outdated if we try later to import the repo again\n await deps.gitApiService.deleteImportBranch({\n repoUrl,\n gitUrl,\n });\n // Remove Location from catalog\n const catalogUrl = getCatalogUrl(deps.config, repoUrl, defaultBranch);\n const findLocationFrom = (list: { id?: string; target: string }[]) => {\n for (const loc of list) {\n if (loc.target === catalogUrl) {\n return loc.id;\n }\n }\n return undefined;\n };\n\n const locationId = findLocationFrom(\n (\n await deps.catalogHttpClient.listCatalogUrlLocationsByIdFromLocationsEndpoint()\n ).locations,\n );\n if (locationId) {\n await deps.catalogHttpClient.deleteCatalogLocationById(locationId);\n }\n\n return {\n statusCode: 204,\n responseBody: undefined,\n };\n}\n\nexport async function deleteRepositoryRecord<\n DAO extends RepositoryDao<RepositoryName>,\n>(\n deps: {\n logger: LoggerService;\n dao: DAO;\n },\n repoUrl: string,\n): Promise<HandlerResponse<void>> {\n deps.logger.debug(`Deleting repository from database by name ${repoUrl}...`);\n try {\n await deps.dao.deleteRepository(repoUrl);\n\n return {\n statusCode: 204,\n responseBody: undefined,\n };\n } catch (error: any) {\n deps.logger.error(\n `Failed to delete repository from database by url ${repoUrl}`,\n error,\n );\n return {\n statusCode: 500,\n };\n }\n}\n"],"names":["DefaultSortColumn","DefaultSortOrder","getNestedValue","DefaultPageNumber","DefaultPageSize","getCatalogFilename","parseGitURLForApprovalTool","imports","paginateArray","logErrorIfNeeded","getCatalogUrl","gitUrlParse","errors","NotFoundError","DefaultApi","Configuration"],"mappings":"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"}
@@ -2,11 +2,9 @@
2
2
 
3
3
  var rootHttpRouter = require('@backstage/backend-defaults/rootHttpRouter');
4
4
  var errors = require('@backstage/errors');
5
- var pluginPermissionNode = require('@backstage/plugin-permission-node');
6
5
  var formats = require('ajv-formats/dist/formats');
7
6
  var express = require('express');
8
7
  var openapiBackend = require('openapi-backend');
9
- var backstagePluginBulkImportCommon = require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
10
8
  var catalogHttpClient = require('../catalog/catalogHttpClient.cjs.js');
11
9
  var catalogInfoGenerator = require('../catalog/catalogInfoGenerator.cjs.js');
12
10
  var migration = require('../database/migration.cjs.js');
@@ -88,7 +86,7 @@ async function createRouter(options) {
88
86
  config,
89
87
  cache,
90
88
  discovery,
91
- catalogApi,
89
+ catalog,
92
90
  auditor,
93
91
  database
94
92
  } = options;
@@ -107,9 +105,8 @@ async function createRouter(options) {
107
105
  const catalogHttpClient$1 = new catalogHttpClient.CatalogHttpClient({
108
106
  logger,
109
107
  config,
110
- discovery,
111
108
  auth: auth$1,
112
- catalogApi
109
+ catalog
113
110
  });
114
111
  const catalogInfoGenerator$1 = new catalogInfoGenerator.CatalogInfoGenerator(
115
112
  logger,
@@ -381,7 +378,6 @@ async function createRouter(options) {
381
378
  logger,
382
379
  config,
383
380
  auth: auth$1,
384
- catalogApi,
385
381
  gitlabApiService: gitlabApiService$1,
386
382
  githubApiService: githubApiService$1,
387
383
  catalogInfoGenerator: catalogInfoGenerator$1,
@@ -576,10 +572,6 @@ async function createRouter(options) {
576
572
  );
577
573
  const router = express.Router();
578
574
  router.use(express__default.default.json());
579
- const permissionIntegrationRouter = pluginPermissionNode.createPermissionIntegrationRouter({
580
- permissions: [backstagePluginBulkImportCommon.bulkImportPermission]
581
- });
582
- router.use(permissionIntegrationRouter);
583
575
  router.use((req, res, next) => {
584
576
  const raw = req.headers["x-scm-tokens"];
585
577
  const rawStr = Array.isArray(raw) ? raw[0] : raw;
@@ -1 +1 @@
1
- {"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 */\n\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport type {\n AuditorService,\n AuditorServiceEvent,\n AuthService,\n CacheService,\n DatabaseService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { CatalogApi } from '@backstage/catalog-client';\nimport type { Config } from '@backstage/config';\nimport { InputError } from '@backstage/errors';\nimport type { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\n\nimport { fullFormats } from 'ajv-formats/dist/formats';\nimport express, { Router, type Request, type Response } from 'express';\nimport {\n Document,\n OpenAPIBackend,\n type Context,\n type Request as OpenAPIRequest,\n} from 'openapi-backend';\n\nimport { bulkImportPermission } from '@red-hat-developer-hub/backstage-plugin-bulk-import-common';\n\nimport { CatalogHttpClient } from '../catalog/catalogHttpClient';\nimport { CatalogInfoGenerator } from '../catalog/catalogInfoGenerator';\nimport { migrate } from '../database/migration';\nimport {\n OrchestratorWorkflowDao,\n RepositoryDao,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../database/repositoryDao';\nimport type { Components, Paths, SourceImport } from '../generated/openapi.d';\nimport { openApiDocument } from '../generated/openapidocument';\nimport { GithubApiService } from '../github';\nimport { GitlabApiService } from '../gitlab';\nimport {\n getImportTemplateRef,\n parseGitURLForApprovalTool,\n permissionCheck,\n} from '../helpers';\nimport { auditCreateEvent } from '../helpers/auditorUtils';\nimport {\n createImportJobs,\n deleteImportByRepo,\n deleteRepositoryRecord,\n findAllImports,\n findImportStatusByRepo,\n findOrchestratorImportStatusByRepo,\n findTaskImportStatusByRepo,\n sortImports,\n} from './handlers/import';\nimport { createWorkflowImportJobs } from './handlers/import/execute-orchestrator-workflow';\nimport { createTaskImportJobs } from './handlers/import/execute-template';\nimport { findAllOrganizations } from './handlers/organization';\nimport { ping } from './handlers/ping';\nimport {\n findAllRepositories,\n findRepositoriesByOrganization,\n} from './handlers/repository';\nimport { findAllSCMHosts } from './handlers/scm/scm';\n\n/**\n * Router Options\n * @public\n */\nexport interface RouterOptions {\n logger: LoggerService;\n permissions: PermissionEvaluator;\n config: Config;\n cache: CacheService;\n discovery: DiscoveryService;\n httpAuth: HttpAuthService;\n auth: AuthService;\n catalogApi: CatalogApi;\n auditor: AuditorService;\n database: DatabaseService;\n}\n\nnamespace Operations {\n export const PING = 'ping';\n export const FIND_ALL_SCM_HOSTS = 'findAllSCMHosts';\n export const FIND_ALL_ORGANIZATIONS = 'findAllOrganizations';\n export const FIND_ALL_REPOSITORIES = 'findAllRepositories';\n\n export const FIND_REPOSITORIES_BY_ORGANIZATION =\n 'findRepositoriesByOrganization';\n\n export const FIND_ALL_IMPORTS = 'findAllImports';\n export const FIND_ALL_TASK_IMPORTS = 'findAllTaskImports';\n export const FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS =\n 'findAllOrchestratorWorkflowImports';\n\n export const CREATE_IMPORT_JOBS = 'createImportJobs';\n export const CREATE_TASK_IMPORT_JOBS = 'createTaskImportJobs';\n export const CREATE_ORCHESTRATOR_WORKFLOW_JOBS =\n 'createOrchestratorWorkflowJobs';\n\n export const FIND_IMPORT_STATUS_BY_REPO = 'findImportStatusByRepo';\n export const FIND_TASK_IMPORT_STATUS_BY_REPO = 'findTaskImportStatusByRepo';\n export const FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO =\n 'findOrchestratorImportStatusByRepo';\n\n export const DELETE_IMPORT_BY_REPO = 'deleteImportByRepo';\n export const DELETE_TASK_IMPORT_BY_REPO = 'deleteTaskImportByRepo';\n export const DELETE_ORCHESTRATOR_IMPORT_BY_REPO =\n 'deleteOrchestratorImportByRepo';\n}\n\nconst SCM_TOKENS_MAX_BYTES = 4096;\n\nconst isValidTokenMap = (v: unknown): v is Record<string, string> =>\n typeof v === 'object' &&\n v !== null &&\n Object.values(v).every(val => typeof val === 'string' && val.length > 0);\n\nfunction parseScmTokensHeader(\n rawTokenHeader: string | undefined,\n logger: LoggerService,\n): Record<string, string> | undefined {\n let token: Record<string, string> | undefined;\n if (!rawTokenHeader) return undefined;\n if (rawTokenHeader.length > SCM_TOKENS_MAX_BYTES) {\n logger.warn('x-scm-tokens header exceeds maximum allowed size; ignoring');\n return undefined;\n }\n try {\n token = JSON.parse(rawTokenHeader) as Record<string, string>;\n if (typeof token !== 'object' || token === null || Array.isArray(token)) {\n throw new Error('x-scm-tokens must be a JSON object');\n }\n } catch (e) {\n throw new InputError(\n `Invalid x-scm-tokens header: ${(e as Error).message}`,\n );\n }\n\n if (!isValidTokenMap(token)) {\n throw new InputError(\n 'Invalid x-scm-tokens header: all values must be non-empty strings',\n );\n }\n return token;\n}\n\n/**\n * Router\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const {\n logger,\n httpAuth,\n auth,\n permissions,\n config,\n cache,\n discovery,\n catalogApi,\n auditor: auditor,\n database,\n } = options;\n\n const knex = await migrate(database);\n const repositoryDao = new RepositoryDao(knex, logger, 'repositories');\n const taskDao = new ScaffolderTaskDao(knex);\n const taskLocationsDao = new TaskLocationsDao(knex);\n const orchestratorRepositoryDao = new RepositoryDao(\n knex,\n logger,\n 'orchestrator_repositories',\n );\n const orchestratorWorkflowDao = new OrchestratorWorkflowDao(knex);\n // GitHub and GitLab both implement the GitApiService interface; the router\n // selects the appropriate service per request based on approvalTool.\n const githubApiService = new GithubApiService(logger, config, cache);\n const gitlabApiService = new GitlabApiService(logger, config, cache);\n const catalogHttpClient = new CatalogHttpClient({\n logger,\n config,\n discovery,\n auth,\n catalogApi,\n });\n const catalogInfoGenerator = new CatalogInfoGenerator(\n logger,\n catalogHttpClient,\n );\n\n // create openapi requests handler\n const api = new OpenAPIBackend({\n ajvOpts: {\n verbose: true,\n formats: fullFormats, // open issue: https://github.com/openapistack/openapi-backend/issues/280\n },\n validate: true,\n definition: openApiDocument,\n handlers: {\n validationFail: async (c, _req: Request, res: Response) =>\n res.status(400).json({ err: c.validation.errors }),\n notFound: async (_c, req: Request, res: Response) =>\n res.status(404).json({ err: `'${req.method} ${req.path}' not found` }),\n notImplemented: async (_c, req: Request, res: Response) =>\n res\n .status(500)\n .json({ err: `'${req.method} ${req.path}' not implemented` }),\n },\n });\n\n const templateRef = config.getOptionalString('bulkImport.importTemplate');\n let finalTemplateRef: string | undefined;\n if (templateRef) {\n finalTemplateRef = getImportTemplateRef(templateRef);\n }\n\n const orchestratorWorkflowId = config.getOptionalString(\n 'bulkImport.orchestratorWorkflow',\n );\n\n await api.init();\n\n api.register(\n Operations.PING,\n async (_c: Context, _req: Request, res: Response) => {\n const result = await ping(logger);\n return res.status(result.statusCode).json(result.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_SCM_HOSTS,\n async (_c: Context, _req: Request, res: Response) => {\n const result = await findAllSCMHosts(config);\n return res.status(result.statusCode).json(result.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_ORGANIZATIONS,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindAllOrganizations.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n const response = await findAllOrganizations(\n logger,\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n q.search,\n q.pagePerIntegration,\n q.sizePerIntegration,\n );\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n organizations: response.responseBody?.organizations,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: response.responseBody?.pagePerIntegration,\n sizePerIntegration: response.responseBody?.sizePerIntegration,\n approvalTool: q.approvalTool,\n } as Components.Schemas.OrganizationList);\n },\n );\n\n api.register(\n Operations.FIND_ALL_REPOSITORIES,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindAllRepositories.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n q.checkImportStatus = stringToBoolean(q.checkImportStatus);\n\n const userTokens = res.locals.scmTokens as\n | Record<string, string>\n | undefined;\n\n if (!userTokens || Object.keys(userTokens).length === 0) {\n return res.status(401).json({\n error:\n 'User SCM credentials are required to list repositories. Ensure the SCM OAuth integration is configured.',\n });\n }\n\n const response = await findAllRepositories(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n },\n {\n search: q.search,\n checkStatus: q.checkImportStatus,\n pageNumber: q.pagePerIntegration,\n pageSize: q.sizePerIntegration,\n userTokens,\n },\n );\n const repos = response.responseBody?.repositories;\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n repositories: repos,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: q.pagePerIntegration,\n sizePerIntegration: q.sizePerIntegration,\n approvalTool: q.approvalTool,\n } as Components.Schemas.RepositoryList);\n },\n );\n\n api.register(\n Operations.FIND_REPOSITORIES_BY_ORGANIZATION,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindRepositoriesByOrganization.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n q.checkImportStatus = stringToBoolean(q.checkImportStatus);\n\n const userTokens = res.locals.scmTokens as\n | Record<string, string>\n | undefined;\n\n if (!userTokens || Object.keys(userTokens).length === 0) {\n return res.status(401).json({\n error:\n 'User SCM credentials are required to list repositories. Ensure the SCM OAuth integration is configured.',\n });\n }\n\n const response = await findRepositoriesByOrganization(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n },\n c.request.params.organizationName?.toString(),\n q.search,\n q.checkImportStatus,\n q.pagePerIntegration,\n q.sizePerIntegration,\n userTokens,\n );\n const repos = response.responseBody?.repositories;\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n repositories: repos,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: q.pagePerIntegration,\n sizePerIntegration: q.sizePerIntegration,\n approvalTool: q.approvalTool,\n } as Components.Schemas.RepositoryList);\n },\n );\n\n api.register(\n Operations.FIND_ALL_IMPORTS,\n async (c: Context, _req: Request, res: Response) => {\n const {\n pageNumber,\n pageSize,\n apiVersion,\n search,\n sortColumn,\n sortOrder,\n } = getFindImportsParams(c);\n const response = await findAllImports(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n },\n {\n apiVersion,\n },\n {\n search,\n pageNumber,\n pageSize,\n sortColumn,\n sortOrder,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n api.register(\n Operations.FIND_ALL_TASK_IMPORTS,\n async (c: Context, _req: Request, res: Response) => {\n const { pageNumber, pageSize, search, sortColumn, sortOrder } =\n getFindImportsParams(c);\n const imports: SourceImport[] = [];\n const repositories = await repositoryDao.findRepositories(\n pageNumber,\n pageSize,\n search,\n );\n\n for (const repo of repositories.data) {\n const response = await findTaskImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n discovery,\n auth,\n },\n repo.url,\n true,\n );\n if (response.responseBody) {\n imports.push(response.responseBody);\n }\n }\n\n sortImports(imports, sortColumn, sortOrder);\n\n const responseBody: Components.Schemas.ImportJobListV2 = {\n imports,\n totalCount: repositories.total,\n page: pageNumber || 1,\n size: pageSize || 5,\n };\n\n return res.status(200).json(responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS,\n async (c: Context, req: Request, res: Response) => {\n const { pageNumber, pageSize, search, sortColumn, sortOrder } =\n getFindImportsParams(c);\n const imports: SourceImport[] = [];\n const repositories = await orchestratorRepositoryDao.findRepositories(\n pageNumber,\n pageSize,\n search,\n );\n\n const token = getBearerTokenFromReq(req);\n\n for (const repo of repositories.data) {\n const response = await findOrchestratorImportStatusByRepo(\n {\n logger,\n orchestratorRepositoryDao,\n orchestratorWorkflowDao,\n discovery,\n },\n repo.url,\n token,\n true,\n );\n if (response.responseBody) {\n imports.push(response.responseBody);\n }\n }\n\n sortImports(imports, sortColumn, sortOrder);\n\n const responseBody: Components.Schemas.ImportJobListV2 = {\n imports,\n totalCount: repositories.total,\n page: pageNumber || 1,\n size: pageSize || 5,\n };\n\n return res.status(200).json(responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_IMPORT_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n _req: Request,\n res: Response,\n ) => {\n const q: Paths.CreateImportJobs.QueryParameters = {\n ...c.request.query,\n };\n q.dryRun = stringToBoolean(q.dryRun);\n const response = await createImportJobs(\n {\n logger,\n config,\n auth,\n catalogApi,\n gitlabApiService,\n githubApiService,\n catalogInfoGenerator,\n catalogHttpClient,\n },\n {\n importRequests: c.request.requestBody,\n dryRun: q.dryRun,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_TASK_IMPORT_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n _req: Request,\n res: Response,\n ) => {\n if (!finalTemplateRef) {\n throw new Error(\n `Missing required config value: 'bulkImport.importTemplate'`,\n );\n }\n const response = await createTaskImportJobs(\n finalTemplateRef,\n discovery,\n logger,\n auth,\n config,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n c.request.requestBody,\n githubApiService,\n );\n\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n req: Request,\n res: Response,\n ) => {\n if (!orchestratorWorkflowId) {\n throw new Error(\n `Missing required config value: 'bulkImport.orchestratorWorkflow'`,\n );\n }\n\n const token = getBearerTokenFromReq(req);\n\n const response = await createWorkflowImportJobs({\n orchestratorWorkflowId,\n discovery,\n token,\n requestBody: c.request.requestBody,\n orchestratorWorkflowDao,\n orchestratorRepositoryDao,\n githubApiService,\n gitlabApiService,\n });\n\n res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_TASK_IMPORT_STATUS_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const response = await findTaskImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n discovery,\n auth,\n },\n q.repo,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_IMPORT_STATUS_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const response = await findImportStatusByRepo(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n approvalTool: q.approvalTool,\n },\n q.repo,\n q.defaultBranch,\n true,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO,\n async (c: Context, req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const token = getBearerTokenFromReq(req);\n const response = await findOrchestratorImportStatusByRepo(\n {\n logger,\n orchestratorRepositoryDao,\n orchestratorWorkflowDao,\n discovery,\n },\n q.repo,\n token,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_TASK_IMPORT_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteRepositoryRecord(\n {\n logger,\n dao: repositoryDao,\n },\n q.repo,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_IMPORT_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteImportByRepo(\n {\n logger,\n config,\n gitApiService:\n parseGitURLForApprovalTool(q.repo) === 'GITLAB'\n ? gitlabApiService\n : githubApiService,\n catalogHttpClient,\n },\n q.repo,\n q.defaultBranch,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_ORCHESTRATOR_IMPORT_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteRepositoryRecord(\n {\n logger,\n dao: orchestratorRepositoryDao,\n },\n q.repo,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n const router = Router();\n router.use(express.json());\n\n const permissionIntegrationRouter = createPermissionIntegrationRouter({\n permissions: [bulkImportPermission],\n });\n router.use(permissionIntegrationRouter);\n\n // Strip x-scm-tokens from req.headers before the permission check and audit\n // middleware run so that OAuth tokens are never captured in audit logs.\n // The parsed map is stored in res.locals.scmTokens for handler use.\n router.use((req, res, next) => {\n const raw = req.headers['x-scm-tokens'];\n const rawStr = Array.isArray(raw) ? raw[0] : raw;\n delete req.headers['x-scm-tokens'];\n if (rawStr) {\n try {\n res.locals.scmTokens = parseScmTokensHeader(rawStr, logger);\n } catch (e) {\n next(e);\n return;\n }\n }\n next();\n });\n\n router.use(async (req, _res, next) => {\n if (req.path !== '/ping') {\n try {\n await permissionCheck(\n auditor,\n api.matchOperation(req as OpenAPIRequest)?.operationId,\n permissions,\n httpAuth,\n req,\n );\n } catch (e) {\n next(e);\n return;\n }\n }\n next();\n });\n\n router.use(async (req, res, next) => {\n const reqCast = req as OpenAPIRequest;\n const operationId = api.matchOperation(reqCast)?.operationId;\n\n const auditorEvent = await createAuditorEventByOperationId(\n operationId,\n req,\n auditor,\n );\n try {\n const response = (await api.handleRequest(reqCast, req, res)) as Response;\n auditorEvent?.success({ meta: { responseStatus: response.statusCode } });\n next();\n } catch (err: any) {\n auditorEvent?.fail({ error: err, meta: { responseStatus: 500 } });\n next(err);\n }\n });\n\n const middleware = MiddlewareFactory.create({ logger, config });\n router.use(middleware.error());\n\n return router;\n}\n\nasync function createAuditorEventByOperationId(\n operationId: string | undefined,\n req: Request,\n auditor: AuditorService,\n): Promise<AuditorServiceEvent | undefined> {\n let auditorEvent;\n switch (operationId) {\n case Operations.PING:\n auditorEvent = await auditCreateEvent(auditor, 'ping', req);\n break;\n case Operations.FIND_ALL_SCM_HOSTS:\n auditorEvent = await auditCreateEvent(auditor, 'scm-hosts-read', req);\n break;\n\n case Operations.FIND_ALL_ORGANIZATIONS:\n auditorEvent = await auditCreateEvent(auditor, 'org-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query?.search,\n });\n break;\n case Operations.FIND_ALL_REPOSITORIES:\n auditorEvent = await auditCreateEvent(auditor, 'repo-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query.search,\n });\n break;\n case Operations.FIND_REPOSITORIES_BY_ORGANIZATION: {\n const organizationName = req.params.organizationName?.toString();\n auditorEvent = await auditCreateEvent(auditor, 'repo-read', req, {\n queryType: 'by-org',\n organizationName,\n });\n break;\n }\n case Operations.FIND_ALL_IMPORTS:\n case Operations.FIND_ALL_TASK_IMPORTS:\n case Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS:\n auditorEvent = await auditCreateEvent(auditor, 'import-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query.search,\n });\n break;\n case Operations.CREATE_IMPORT_JOBS:\n case Operations.CREATE_TASK_IMPORT_JOBS:\n case Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS:\n auditorEvent = await auditCreateEvent(auditor, 'import-write', req, {\n actionType: 'create',\n });\n break;\n case Operations.FIND_IMPORT_STATUS_BY_REPO:\n case Operations.FIND_TASK_IMPORT_STATUS_BY_REPO:\n case Operations.FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO:\n auditorEvent = await auditCreateEvent(\n auditor,\n 'import-status-read',\n req,\n { queryType: 'by-query', repo: req.query.repo },\n );\n break;\n case Operations.DELETE_IMPORT_BY_REPO:\n case Operations.DELETE_TASK_IMPORT_BY_REPO:\n case Operations.DELETE_ORCHESTRATOR_IMPORT_BY_REPO:\n auditorEvent = await auditCreateEvent(auditor, 'import-write', req, {\n actionType: 'delete',\n repository: req.query.repo,\n });\n break;\n case undefined:\n auditorEvent = await auditCreateEvent(auditor, operationId, req);\n break;\n default:\n // do nothing\n break;\n }\n return auditorEvent;\n}\n\nfunction stringToNumber(s: number | undefined): number | undefined {\n return s ? Number.parseInt(s.toString(), 10) : undefined;\n}\n\nfunction stringToBoolean(s: boolean | undefined): boolean | undefined {\n if (!s) {\n return undefined;\n }\n return s.toString() === 'true';\n}\nfunction getFindImportsParams(c: Context<any, any, any, any, any, Document>): {\n pageNumber?: number;\n pageSize?: number;\n apiVersion?: Paths.FindAllImports.Parameters.ApiVersion;\n search?: string;\n sortColumn?: Components.Parameters.SortColumnQueryParam;\n sortOrder?: Components.Parameters.SortOrderQueryParam;\n} {\n const h: Paths.FindAllImports.HeaderParameters = {\n ...c.request.headers,\n };\n const apiVersion = h['api-version'];\n const q: Paths.FindAllImports.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n let pageNumber: number | undefined;\n let pageSize: number | undefined;\n if (apiVersion === undefined || apiVersion === 'v1') {\n // pagePerIntegration and sizePerIntegration deprecated in v1. 'page' and 'size' take precedence.\n pageNumber = stringToNumber(q.page || q.pagePerIntegration);\n pageSize = stringToNumber(q.size || q.sizePerIntegration);\n } else {\n // pagePerIntegration and sizePerIntegration removed in v2+ and replaced by 'page' and 'size'.\n pageNumber = stringToNumber(q.page);\n pageSize = stringToNumber(q.size);\n }\n return {\n pageNumber,\n pageSize,\n apiVersion: apiVersion,\n search: q.search,\n sortColumn: q.sortColumn,\n sortOrder: q.sortOrder,\n };\n}\n\nfunction getBearerTokenFromReq(req: express.Request): string {\n const header = req.header('authorization') ?? req.headers.authorization;\n if (header?.startsWith(`Bearer `)) {\n return header.replace('Bearer ', '');\n }\n throw new InputError(`Request provided without token`);\n}\n"],"names":["Operations","InputError","auth","migrate","repositoryDao","RepositoryDao","ScaffolderTaskDao","TaskLocationsDao","OrchestratorWorkflowDao","githubApiService","GithubApiService","gitlabApiService","GitlabApiService","catalogHttpClient","CatalogHttpClient","catalogInfoGenerator","CatalogInfoGenerator","OpenAPIBackend","fullFormats","openApiDocument","getImportTemplateRef","ping","findAllSCMHosts","findAllOrganizations","findAllRepositories","findRepositoriesByOrganization","findAllImports","findTaskImportStatusByRepo","sortImports","findOrchestratorImportStatusByRepo","createImportJobs","createTaskImportJobs","createWorkflowImportJobs","findImportStatusByRepo","deleteRepositoryRecord","deleteImportByRepo","parseGitURLForApprovalTool","Router","express","createPermissionIntegrationRouter","bulkImportPermission","permissionCheck","MiddlewareFactory","auditCreateEvent"],"mappings":"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"}
1
+ {"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 */\n\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport type {\n AuditorService,\n AuditorServiceEvent,\n AuthService,\n CacheService,\n DatabaseService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport { InputError } from '@backstage/errors';\nimport type { CatalogService } from '@backstage/plugin-catalog-node';\nimport type { PermissionEvaluator } from '@backstage/plugin-permission-common';\n\nimport { fullFormats } from 'ajv-formats/dist/formats';\nimport express, { Router, type Request, type Response } from 'express';\nimport {\n Document,\n OpenAPIBackend,\n type Context,\n type Request as OpenAPIRequest,\n} from 'openapi-backend';\n\nimport { CatalogHttpClient } from '../catalog/catalogHttpClient';\nimport { CatalogInfoGenerator } from '../catalog/catalogInfoGenerator';\nimport { migrate } from '../database/migration';\nimport {\n OrchestratorWorkflowDao,\n RepositoryDao,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../database/repositoryDao';\nimport type { Components, Paths, SourceImport } from '../generated/openapi.d';\nimport { openApiDocument } from '../generated/openapidocument';\nimport { GithubApiService } from '../github';\nimport { GitlabApiService } from '../gitlab';\nimport {\n getImportTemplateRef,\n parseGitURLForApprovalTool,\n permissionCheck,\n} from '../helpers';\nimport { auditCreateEvent } from '../helpers/auditorUtils';\nimport {\n createImportJobs,\n deleteImportByRepo,\n deleteRepositoryRecord,\n findAllImports,\n findImportStatusByRepo,\n findOrchestratorImportStatusByRepo,\n findTaskImportStatusByRepo,\n sortImports,\n} from './handlers/import';\nimport { createWorkflowImportJobs } from './handlers/import/execute-orchestrator-workflow';\nimport { createTaskImportJobs } from './handlers/import/execute-template';\nimport { findAllOrganizations } from './handlers/organization';\nimport { ping } from './handlers/ping';\nimport {\n findAllRepositories,\n findRepositoriesByOrganization,\n} from './handlers/repository';\nimport { findAllSCMHosts } from './handlers/scm/scm';\n\n/**\n * Router Options\n * @public\n */\nexport interface RouterOptions {\n logger: LoggerService;\n permissions: PermissionEvaluator;\n config: Config;\n cache: CacheService;\n discovery: DiscoveryService;\n httpAuth: HttpAuthService;\n auth: AuthService;\n catalog: CatalogService;\n auditor: AuditorService;\n database: DatabaseService;\n}\n\nnamespace Operations {\n export const PING = 'ping';\n export const FIND_ALL_SCM_HOSTS = 'findAllSCMHosts';\n export const FIND_ALL_ORGANIZATIONS = 'findAllOrganizations';\n export const FIND_ALL_REPOSITORIES = 'findAllRepositories';\n\n export const FIND_REPOSITORIES_BY_ORGANIZATION =\n 'findRepositoriesByOrganization';\n\n export const FIND_ALL_IMPORTS = 'findAllImports';\n export const FIND_ALL_TASK_IMPORTS = 'findAllTaskImports';\n export const FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS =\n 'findAllOrchestratorWorkflowImports';\n\n export const CREATE_IMPORT_JOBS = 'createImportJobs';\n export const CREATE_TASK_IMPORT_JOBS = 'createTaskImportJobs';\n export const CREATE_ORCHESTRATOR_WORKFLOW_JOBS =\n 'createOrchestratorWorkflowJobs';\n\n export const FIND_IMPORT_STATUS_BY_REPO = 'findImportStatusByRepo';\n export const FIND_TASK_IMPORT_STATUS_BY_REPO = 'findTaskImportStatusByRepo';\n export const FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO =\n 'findOrchestratorImportStatusByRepo';\n\n export const DELETE_IMPORT_BY_REPO = 'deleteImportByRepo';\n export const DELETE_TASK_IMPORT_BY_REPO = 'deleteTaskImportByRepo';\n export const DELETE_ORCHESTRATOR_IMPORT_BY_REPO =\n 'deleteOrchestratorImportByRepo';\n}\n\nconst SCM_TOKENS_MAX_BYTES = 4096;\n\nconst isValidTokenMap = (v: unknown): v is Record<string, string> =>\n typeof v === 'object' &&\n v !== null &&\n Object.values(v).every(val => typeof val === 'string' && val.length > 0);\n\nfunction parseScmTokensHeader(\n rawTokenHeader: string | undefined,\n logger: LoggerService,\n): Record<string, string> | undefined {\n let token: Record<string, string> | undefined;\n if (!rawTokenHeader) return undefined;\n if (rawTokenHeader.length > SCM_TOKENS_MAX_BYTES) {\n logger.warn('x-scm-tokens header exceeds maximum allowed size; ignoring');\n return undefined;\n }\n try {\n token = JSON.parse(rawTokenHeader) as Record<string, string>;\n if (typeof token !== 'object' || token === null || Array.isArray(token)) {\n throw new Error('x-scm-tokens must be a JSON object');\n }\n } catch (e) {\n throw new InputError(\n `Invalid x-scm-tokens header: ${(e as Error).message}`,\n );\n }\n\n if (!isValidTokenMap(token)) {\n throw new InputError(\n 'Invalid x-scm-tokens header: all values must be non-empty strings',\n );\n }\n return token;\n}\n\n/**\n * Router\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const {\n logger,\n httpAuth,\n auth,\n permissions,\n config,\n cache,\n discovery,\n catalog,\n auditor,\n database,\n } = options;\n\n const knex = await migrate(database);\n const repositoryDao = new RepositoryDao(knex, logger, 'repositories');\n const taskDao = new ScaffolderTaskDao(knex);\n const taskLocationsDao = new TaskLocationsDao(knex);\n const orchestratorRepositoryDao = new RepositoryDao(\n knex,\n logger,\n 'orchestrator_repositories',\n );\n const orchestratorWorkflowDao = new OrchestratorWorkflowDao(knex);\n // GitHub and GitLab both implement the GitApiService interface; the router\n // selects the appropriate service per request based on approvalTool.\n const githubApiService = new GithubApiService(logger, config, cache);\n const gitlabApiService = new GitlabApiService(logger, config, cache);\n const catalogHttpClient = new CatalogHttpClient({\n logger,\n config,\n auth,\n catalog,\n });\n const catalogInfoGenerator = new CatalogInfoGenerator(\n logger,\n catalogHttpClient,\n );\n\n // create openapi requests handler\n const api = new OpenAPIBackend({\n ajvOpts: {\n verbose: true,\n formats: fullFormats, // open issue: https://github.com/openapistack/openapi-backend/issues/280\n },\n validate: true,\n definition: openApiDocument,\n handlers: {\n validationFail: async (c, _req: Request, res: Response) =>\n res.status(400).json({ err: c.validation.errors }),\n notFound: async (_c, req: Request, res: Response) =>\n res.status(404).json({ err: `'${req.method} ${req.path}' not found` }),\n notImplemented: async (_c, req: Request, res: Response) =>\n res\n .status(500)\n .json({ err: `'${req.method} ${req.path}' not implemented` }),\n },\n });\n\n const templateRef = config.getOptionalString('bulkImport.importTemplate');\n let finalTemplateRef: string | undefined;\n if (templateRef) {\n finalTemplateRef = getImportTemplateRef(templateRef);\n }\n\n const orchestratorWorkflowId = config.getOptionalString(\n 'bulkImport.orchestratorWorkflow',\n );\n\n await api.init();\n\n api.register(\n Operations.PING,\n async (_c: Context, _req: Request, res: Response) => {\n const result = await ping(logger);\n return res.status(result.statusCode).json(result.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_SCM_HOSTS,\n async (_c: Context, _req: Request, res: Response) => {\n const result = await findAllSCMHosts(config);\n return res.status(result.statusCode).json(result.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_ORGANIZATIONS,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindAllOrganizations.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n const response = await findAllOrganizations(\n logger,\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n q.search,\n q.pagePerIntegration,\n q.sizePerIntegration,\n );\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n organizations: response.responseBody?.organizations,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: response.responseBody?.pagePerIntegration,\n sizePerIntegration: response.responseBody?.sizePerIntegration,\n approvalTool: q.approvalTool,\n } as Components.Schemas.OrganizationList);\n },\n );\n\n api.register(\n Operations.FIND_ALL_REPOSITORIES,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindAllRepositories.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n q.checkImportStatus = stringToBoolean(q.checkImportStatus);\n\n const userTokens = res.locals.scmTokens as\n | Record<string, string>\n | undefined;\n\n if (!userTokens || Object.keys(userTokens).length === 0) {\n return res.status(401).json({\n error:\n 'User SCM credentials are required to list repositories. Ensure the SCM OAuth integration is configured.',\n });\n }\n\n const response = await findAllRepositories(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n },\n {\n search: q.search,\n checkStatus: q.checkImportStatus,\n pageNumber: q.pagePerIntegration,\n pageSize: q.sizePerIntegration,\n userTokens,\n },\n );\n const repos = response.responseBody?.repositories;\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n repositories: repos,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: q.pagePerIntegration,\n sizePerIntegration: q.sizePerIntegration,\n approvalTool: q.approvalTool,\n } as Components.Schemas.RepositoryList);\n },\n );\n\n api.register(\n Operations.FIND_REPOSITORIES_BY_ORGANIZATION,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindRepositoriesByOrganization.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n q.checkImportStatus = stringToBoolean(q.checkImportStatus);\n\n const userTokens = res.locals.scmTokens as\n | Record<string, string>\n | undefined;\n\n if (!userTokens || Object.keys(userTokens).length === 0) {\n return res.status(401).json({\n error:\n 'User SCM credentials are required to list repositories. Ensure the SCM OAuth integration is configured.',\n });\n }\n\n const response = await findRepositoriesByOrganization(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n },\n c.request.params.organizationName?.toString(),\n q.search,\n q.checkImportStatus,\n q.pagePerIntegration,\n q.sizePerIntegration,\n userTokens,\n );\n const repos = response.responseBody?.repositories;\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n repositories: repos,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: q.pagePerIntegration,\n sizePerIntegration: q.sizePerIntegration,\n approvalTool: q.approvalTool,\n } as Components.Schemas.RepositoryList);\n },\n );\n\n api.register(\n Operations.FIND_ALL_IMPORTS,\n async (c: Context, _req: Request, res: Response) => {\n const {\n pageNumber,\n pageSize,\n apiVersion,\n search,\n sortColumn,\n sortOrder,\n } = getFindImportsParams(c);\n const response = await findAllImports(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n },\n {\n apiVersion,\n },\n {\n search,\n pageNumber,\n pageSize,\n sortColumn,\n sortOrder,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n api.register(\n Operations.FIND_ALL_TASK_IMPORTS,\n async (c: Context, _req: Request, res: Response) => {\n const { pageNumber, pageSize, search, sortColumn, sortOrder } =\n getFindImportsParams(c);\n const imports: SourceImport[] = [];\n const repositories = await repositoryDao.findRepositories(\n pageNumber,\n pageSize,\n search,\n );\n\n for (const repo of repositories.data) {\n const response = await findTaskImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n discovery,\n auth,\n },\n repo.url,\n true,\n );\n if (response.responseBody) {\n imports.push(response.responseBody);\n }\n }\n\n sortImports(imports, sortColumn, sortOrder);\n\n const responseBody: Components.Schemas.ImportJobListV2 = {\n imports,\n totalCount: repositories.total,\n page: pageNumber || 1,\n size: pageSize || 5,\n };\n\n return res.status(200).json(responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS,\n async (c: Context, req: Request, res: Response) => {\n const { pageNumber, pageSize, search, sortColumn, sortOrder } =\n getFindImportsParams(c);\n const imports: SourceImport[] = [];\n const repositories = await orchestratorRepositoryDao.findRepositories(\n pageNumber,\n pageSize,\n search,\n );\n\n const token = getBearerTokenFromReq(req);\n\n for (const repo of repositories.data) {\n const response = await findOrchestratorImportStatusByRepo(\n {\n logger,\n orchestratorRepositoryDao,\n orchestratorWorkflowDao,\n discovery,\n },\n repo.url,\n token,\n true,\n );\n if (response.responseBody) {\n imports.push(response.responseBody);\n }\n }\n\n sortImports(imports, sortColumn, sortOrder);\n\n const responseBody: Components.Schemas.ImportJobListV2 = {\n imports,\n totalCount: repositories.total,\n page: pageNumber || 1,\n size: pageSize || 5,\n };\n\n return res.status(200).json(responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_IMPORT_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n _req: Request,\n res: Response,\n ) => {\n const q: Paths.CreateImportJobs.QueryParameters = {\n ...c.request.query,\n };\n q.dryRun = stringToBoolean(q.dryRun);\n const response = await createImportJobs(\n {\n logger,\n config,\n auth,\n gitlabApiService,\n githubApiService,\n catalogInfoGenerator,\n catalogHttpClient,\n },\n {\n importRequests: c.request.requestBody,\n dryRun: q.dryRun,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_TASK_IMPORT_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n _req: Request,\n res: Response,\n ) => {\n if (!finalTemplateRef) {\n throw new Error(\n `Missing required config value: 'bulkImport.importTemplate'`,\n );\n }\n const response = await createTaskImportJobs(\n finalTemplateRef,\n discovery,\n logger,\n auth,\n config,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n c.request.requestBody,\n githubApiService,\n );\n\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n req: Request,\n res: Response,\n ) => {\n if (!orchestratorWorkflowId) {\n throw new Error(\n `Missing required config value: 'bulkImport.orchestratorWorkflow'`,\n );\n }\n\n const token = getBearerTokenFromReq(req);\n\n const response = await createWorkflowImportJobs({\n orchestratorWorkflowId,\n discovery,\n token,\n requestBody: c.request.requestBody,\n orchestratorWorkflowDao,\n orchestratorRepositoryDao,\n githubApiService,\n gitlabApiService,\n });\n\n res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_TASK_IMPORT_STATUS_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const response = await findTaskImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n discovery,\n auth,\n },\n q.repo,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_IMPORT_STATUS_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const response = await findImportStatusByRepo(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n approvalTool: q.approvalTool,\n },\n q.repo,\n q.defaultBranch,\n true,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO,\n async (c: Context, req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const token = getBearerTokenFromReq(req);\n const response = await findOrchestratorImportStatusByRepo(\n {\n logger,\n orchestratorRepositoryDao,\n orchestratorWorkflowDao,\n discovery,\n },\n q.repo,\n token,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_TASK_IMPORT_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteRepositoryRecord(\n {\n logger,\n dao: repositoryDao,\n },\n q.repo,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_IMPORT_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteImportByRepo(\n {\n logger,\n config,\n gitApiService:\n parseGitURLForApprovalTool(q.repo) === 'GITLAB'\n ? gitlabApiService\n : githubApiService,\n catalogHttpClient,\n },\n q.repo,\n q.defaultBranch,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_ORCHESTRATOR_IMPORT_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteRepositoryRecord(\n {\n logger,\n dao: orchestratorRepositoryDao,\n },\n q.repo,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n const router = Router();\n router.use(express.json());\n\n // Strip x-scm-tokens from req.headers before the permission check and audit\n // middleware run so that OAuth tokens are never captured in audit logs.\n // The parsed map is stored in res.locals.scmTokens for handler use.\n router.use((req, res, next) => {\n const raw = req.headers['x-scm-tokens'];\n const rawStr = Array.isArray(raw) ? raw[0] : raw;\n delete req.headers['x-scm-tokens'];\n if (rawStr) {\n try {\n res.locals.scmTokens = parseScmTokensHeader(rawStr, logger);\n } catch (e) {\n next(e);\n return;\n }\n }\n next();\n });\n\n router.use(async (req, _res, next) => {\n if (req.path !== '/ping') {\n try {\n await permissionCheck(\n auditor,\n api.matchOperation(req as OpenAPIRequest)?.operationId,\n permissions,\n httpAuth,\n req,\n );\n } catch (e) {\n next(e);\n return;\n }\n }\n next();\n });\n\n router.use(async (req, res, next) => {\n const reqCast = req as OpenAPIRequest;\n const operationId = api.matchOperation(reqCast)?.operationId;\n\n const auditorEvent = await createAuditorEventByOperationId(\n operationId,\n req,\n auditor,\n );\n try {\n const response = (await api.handleRequest(reqCast, req, res)) as Response;\n auditorEvent?.success({ meta: { responseStatus: response.statusCode } });\n next();\n } catch (err: any) {\n auditorEvent?.fail({ error: err, meta: { responseStatus: 500 } });\n next(err);\n }\n });\n\n const middleware = MiddlewareFactory.create({ logger, config });\n router.use(middleware.error());\n\n return router;\n}\n\nasync function createAuditorEventByOperationId(\n operationId: string | undefined,\n req: Request,\n auditor: AuditorService,\n): Promise<AuditorServiceEvent | undefined> {\n let auditorEvent;\n switch (operationId) {\n case Operations.PING:\n auditorEvent = await auditCreateEvent(auditor, 'ping', req);\n break;\n case Operations.FIND_ALL_SCM_HOSTS:\n auditorEvent = await auditCreateEvent(auditor, 'scm-hosts-read', req);\n break;\n\n case Operations.FIND_ALL_ORGANIZATIONS:\n auditorEvent = await auditCreateEvent(auditor, 'org-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query?.search,\n });\n break;\n case Operations.FIND_ALL_REPOSITORIES:\n auditorEvent = await auditCreateEvent(auditor, 'repo-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query.search,\n });\n break;\n case Operations.FIND_REPOSITORIES_BY_ORGANIZATION: {\n const organizationName = req.params.organizationName?.toString();\n auditorEvent = await auditCreateEvent(auditor, 'repo-read', req, {\n queryType: 'by-org',\n organizationName,\n });\n break;\n }\n case Operations.FIND_ALL_IMPORTS:\n case Operations.FIND_ALL_TASK_IMPORTS:\n case Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS:\n auditorEvent = await auditCreateEvent(auditor, 'import-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query.search,\n });\n break;\n case Operations.CREATE_IMPORT_JOBS:\n case Operations.CREATE_TASK_IMPORT_JOBS:\n case Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS:\n auditorEvent = await auditCreateEvent(auditor, 'import-write', req, {\n actionType: 'create',\n });\n break;\n case Operations.FIND_IMPORT_STATUS_BY_REPO:\n case Operations.FIND_TASK_IMPORT_STATUS_BY_REPO:\n case Operations.FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO:\n auditorEvent = await auditCreateEvent(\n auditor,\n 'import-status-read',\n req,\n { queryType: 'by-query', repo: req.query.repo },\n );\n break;\n case Operations.DELETE_IMPORT_BY_REPO:\n case Operations.DELETE_TASK_IMPORT_BY_REPO:\n case Operations.DELETE_ORCHESTRATOR_IMPORT_BY_REPO:\n auditorEvent = await auditCreateEvent(auditor, 'import-write', req, {\n actionType: 'delete',\n repository: req.query.repo,\n });\n break;\n case undefined:\n auditorEvent = await auditCreateEvent(auditor, operationId, req);\n break;\n default:\n // do nothing\n break;\n }\n return auditorEvent;\n}\n\nfunction stringToNumber(s: number | undefined): number | undefined {\n return s ? Number.parseInt(s.toString(), 10) : undefined;\n}\n\nfunction stringToBoolean(s: boolean | undefined): boolean | undefined {\n if (!s) {\n return undefined;\n }\n return s.toString() === 'true';\n}\nfunction getFindImportsParams(c: Context<any, any, any, any, any, Document>): {\n pageNumber?: number;\n pageSize?: number;\n apiVersion?: Paths.FindAllImports.Parameters.ApiVersion;\n search?: string;\n sortColumn?: Components.Parameters.SortColumnQueryParam;\n sortOrder?: Components.Parameters.SortOrderQueryParam;\n} {\n const h: Paths.FindAllImports.HeaderParameters = {\n ...c.request.headers,\n };\n const apiVersion = h['api-version'];\n const q: Paths.FindAllImports.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n let pageNumber: number | undefined;\n let pageSize: number | undefined;\n if (apiVersion === undefined || apiVersion === 'v1') {\n // pagePerIntegration and sizePerIntegration deprecated in v1. 'page' and 'size' take precedence.\n pageNumber = stringToNumber(q.page || q.pagePerIntegration);\n pageSize = stringToNumber(q.size || q.sizePerIntegration);\n } else {\n // pagePerIntegration and sizePerIntegration removed in v2+ and replaced by 'page' and 'size'.\n pageNumber = stringToNumber(q.page);\n pageSize = stringToNumber(q.size);\n }\n return {\n pageNumber,\n pageSize,\n apiVersion: apiVersion,\n search: q.search,\n sortColumn: q.sortColumn,\n sortOrder: q.sortOrder,\n };\n}\n\nfunction getBearerTokenFromReq(req: express.Request): string {\n const header = req.header('authorization') ?? req.headers.authorization;\n if (header?.startsWith(`Bearer `)) {\n return header.replace('Bearer ', '');\n }\n throw new InputError(`Request provided without token`);\n}\n"],"names":["Operations","InputError","auth","migrate","repositoryDao","RepositoryDao","ScaffolderTaskDao","TaskLocationsDao","OrchestratorWorkflowDao","githubApiService","GithubApiService","gitlabApiService","GitlabApiService","catalogHttpClient","CatalogHttpClient","catalogInfoGenerator","CatalogInfoGenerator","OpenAPIBackend","fullFormats","openApiDocument","getImportTemplateRef","ping","findAllSCMHosts","findAllOrganizations","findAllRepositories","findRepositoriesByOrganization","findAllImports","findTaskImportStatusByRepo","sortImports","findOrchestratorImportStatusByRepo","createImportJobs","createTaskImportJobs","createWorkflowImportJobs","findImportStatusByRepo","deleteRepositoryRecord","deleteImportByRepo","parseGitURLForApprovalTool","Router","express","permissionCheck","MiddlewareFactory","auditCreateEvent"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@red-hat-developer-hub/backstage-plugin-bulk-import-backend",
3
- "version": "7.3.7",
3
+ "version": "8.0.0",
4
4
  "main": "./dist/index.cjs.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -50,44 +50,41 @@
50
50
  "openapi": "./scripts/openapi.sh"
51
51
  },
52
52
  "dependencies": {
53
- "@backstage/backend-defaults": "^0.16.0",
54
- "@backstage/backend-plugin-api": "^1.8.0",
55
- "@backstage/catalog-model": "^1.7.7",
56
- "@backstage/config": "^1.3.6",
57
- "@backstage/errors": "^1.2.7",
58
- "@backstage/integration": "^2.0.0",
59
- "@backstage/plugin-catalog-node": "^2.1.0",
60
- "@backstage/plugin-permission-common": "^0.9.7",
61
- "@backstage/plugin-permission-node": "^0.10.11",
53
+ "@backstage/backend-defaults": "0.17.3",
54
+ "@backstage/backend-plugin-api": "^1.9.2",
55
+ "@backstage/catalog-model": "^1.9.0",
56
+ "@backstage/config": "^1.3.8",
57
+ "@backstage/errors": "^1.3.1",
58
+ "@backstage/integration": "^2.0.3",
59
+ "@backstage/plugin-catalog-node": "^2.2.2",
60
+ "@backstage/plugin-permission-common": "^0.9.9",
62
61
  "@gitbeaker/rest": "^43.4.0",
63
62
  "@octokit/auth-app": "^7.2.2",
64
63
  "@octokit/rest": "^20.0.2",
65
- "@red-hat-developer-hub/backstage-plugin-bulk-import-common": "^7.3.7",
66
- "@red-hat-developer-hub/backstage-plugin-orchestrator-common": "^3.2.0",
64
+ "@red-hat-developer-hub/backstage-plugin-bulk-import-common": "^8.0.0",
65
+ "@red-hat-developer-hub/backstage-plugin-orchestrator-common": "^3.7.3",
67
66
  "ajv-formats": "^3.0.1",
68
67
  "eventsource-client": "^1.2.0",
69
68
  "express": "^4.17.1",
70
69
  "git-url-parse": "^14.0.0",
71
- "js-yaml": "^4.1.0",
70
+ "js-yaml": "^4.3.0",
72
71
  "just-kebab-case": "4.2.0",
73
72
  "knex": "^3.0.0",
74
73
  "luxon": "^3.4.4",
75
- "node-fetch": "^2.6.7",
76
74
  "openapi-backend": "^5.10.6"
77
75
  },
78
76
  "devDependencies": {
79
- "@backstage/backend-test-utils": "^1.11.1",
80
- "@backstage/catalog-client": "^1.14.0",
81
- "@backstage/cli": "^0.36.0",
82
- "@backstage/config": "^1.3.6",
83
- "@backstage/plugin-catalog-backend": "^3.5.0",
77
+ "@backstage/backend-test-utils": "^1.11.4",
78
+ "@backstage/catalog-client": "^1.16.0",
79
+ "@backstage/cli": "^0.36.3",
80
+ "@backstage/config": "^1.3.8",
81
+ "@backstage/plugin-catalog-backend": "^3.8.0",
84
82
  "@backstage/types": "^1.2.2",
85
83
  "@openapitools/openapi-generator-cli": "2.39.0",
86
84
  "@spotify/prettier-config": "^15.0.0",
87
85
  "@types/express": "4.17.25",
88
86
  "@types/git-url-parse": "^9.0.0",
89
87
  "@types/knex": "^0.16.1",
90
- "@types/node-fetch": "^2.5.12",
91
88
  "@types/supertest": "2.0.16",
92
89
  "js-yaml-cli": "0.6.0",
93
90
  "msw": "1.3.5",
@@ -98,12 +95,12 @@
98
95
  "files": [
99
96
  "dist",
100
97
  "migrations",
101
- "config.d.ts",
98
+ "config.schema.json",
102
99
  "dist-dynamic/*.*",
103
100
  "dist-dynamic/dist/**",
104
101
  "app-config.yaml"
105
102
  ],
106
- "configSchema": "config.d.ts",
103
+ "configSchema": "config.schema.json",
107
104
  "repository": {
108
105
  "type": "git",
109
106
  "url": "https://github.com/redhat-developer/rhdh-plugins",
package/config.d.ts DELETED
@@ -1,30 +0,0 @@
1
- /*
2
- * Copyright Red Hat, Inc.
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
-
17
- export interface Config {
18
- bulkImport?: {
19
- /**
20
- * The name of the scaffolder template or entity reference to execute for importing a repository.
21
- * @visibility backend
22
- */
23
- importTemplate?: string;
24
- /**
25
- * The orchestrator workflow id to execute for importing a repository.
26
- * @visibility backend
27
- */
28
- orchestratorWorkflow?: string;
29
- };
30
- }