@red-hat-developer-hub/backstage-plugin-bulk-import-backend 6.1.3 → 6.1.5
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,19 @@
|
|
|
1
1
|
### Dependencies
|
|
2
2
|
|
|
3
|
+
## 6.1.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0fb7550: Fixes `/imports` endpoint unable to create `catalog-info.yaml` PR
|
|
8
|
+
|
|
9
|
+
## 6.1.4
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- a79f849: Updated dependency `prettier` to `3.6.2`.
|
|
14
|
+
- Updated dependencies [a79f849]
|
|
15
|
+
- @red-hat-developer-hub/backstage-plugin-bulk-import-common@1.7.2
|
|
16
|
+
|
|
3
17
|
## 6.1.3
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -103,14 +103,12 @@ The Bulk Import Backend plugin emits audit events for various operations. Events
|
|
|
103
103
|
- **`org-read`**: tracks `GET` requests to the `/organizations` endpoint, which returns the list of organizations accessible from all configured GitHub Integrations.
|
|
104
104
|
|
|
105
105
|
Filter on `queryType`.
|
|
106
|
-
|
|
107
106
|
- **`all`**: tracks fetching all organizations. (GET `/organizations`)
|
|
108
107
|
- **`by-query`**: tracks fetching organization filtered by the query parameter 'search'. (GET `/organizations`)
|
|
109
108
|
|
|
110
109
|
- **`repo-read`**: tracks `GET` requests to the endpoint, which returns the list of repositories accessible from all configured GitHub Integrations.
|
|
111
110
|
|
|
112
111
|
Filter on `queryType`.
|
|
113
|
-
|
|
114
112
|
- **`all`**: tracks fetching a list of all repositories accessible by Backstage Github Integrations. (GET `/repositories`)
|
|
115
113
|
- **`by-query`**: tracks fetching a list of repositories filtered by the query parameter 'search'. (GET `/repositories`)
|
|
116
114
|
- **`by-org`**: tracks `GET` requests to the `/organizations/:orgName/repositories` endpoint, which returns the list of repositories for the specified organization (accessible from any of the configured GitHub Integrations)
|
|
@@ -118,20 +116,17 @@ The Bulk Import Backend plugin emits audit events for various operations. Events
|
|
|
118
116
|
- **`import-read`**: tracks `GET` requests to the `/imports` endpoint, which returns the list of existing import jobs along with their statuses.
|
|
119
117
|
|
|
120
118
|
Filter on `queryType`.
|
|
121
|
-
|
|
122
119
|
- **`all`**: tracks fetching all imports.
|
|
123
120
|
- **`by-query`**: tracks fetching imports filtered by the query parameter 'search'.
|
|
124
121
|
|
|
125
122
|
- **`import-status-read`**: tracks `GET` requests to the `/import/by-repo` endpoint, which fetches details about the import job for the specified repository.
|
|
126
123
|
|
|
127
124
|
Filter on `queryType`.
|
|
128
|
-
|
|
129
125
|
- **`by-query`**: tracks fetching import status filtered by the query parameter 'repo'. (GET `/import/by-repo`).
|
|
130
126
|
|
|
131
127
|
- **`import-write`** tracks events about midification imports.
|
|
132
128
|
|
|
133
129
|
Filter on `actionType`.
|
|
134
|
-
|
|
135
130
|
- **`create`**: tracks creating import job. Event submitted on `POST` `/imports`, which allows to submit requests to bulk-import one or many repositories into the Backstage Catalog, by eventually creating import Pull Requests in the target repositories.
|
|
136
131
|
- **`delete`**: tracks deleting import by query parameter 'repo'. Event submitted on `DELETE` `/import/by-repo` requests, which deletes any existing import job for the specified repository, by closing any open import Pull Request that could have been created.
|
|
137
132
|
|
|
@@ -168,7 +168,7 @@ class CatalogHttpClient {
|
|
|
168
168
|
);
|
|
169
169
|
return result.exists;
|
|
170
170
|
} catch (error) {
|
|
171
|
-
if (error.message?.includes("NotFoundError")) {
|
|
171
|
+
if (error.message?.includes("NotFoundError") || error.cause?.message?.includes("NotFoundError")) {
|
|
172
172
|
return false;
|
|
173
173
|
}
|
|
174
174
|
throw error;
|
|
@@ -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 (error.message?.includes('NotFoundError')) {\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 (!error.message?.includes('ConflictError')) {\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":"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"}
|
|
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.cause?.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 (!error.message?.includes('ConflictError')) {\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":"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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": "6.1.
|
|
3
|
+
"version": "6.1.5",
|
|
4
4
|
"main": "./dist/index.cjs.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@backstage/plugin-permission-node": "^0.10.0",
|
|
61
61
|
"@octokit/auth-app": "^6.0.3",
|
|
62
62
|
"@octokit/rest": "^20.0.2",
|
|
63
|
-
"@red-hat-developer-hub/backstage-plugin-bulk-import-common": "^1.7.
|
|
63
|
+
"@red-hat-developer-hub/backstage-plugin-bulk-import-common": "^1.7.2",
|
|
64
64
|
"ajv-formats": "^3.0.1",
|
|
65
65
|
"express": "^4.17.1",
|
|
66
66
|
"git-url-parse": "^14.0.0",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"js-yaml-cli": "0.6.0",
|
|
88
88
|
"msw": "1.3.5",
|
|
89
89
|
"openapicmd": "2.7.0",
|
|
90
|
-
"prettier": "3.
|
|
90
|
+
"prettier": "3.6.2",
|
|
91
91
|
"supertest": "6.3.4"
|
|
92
92
|
},
|
|
93
93
|
"peerDependencies": {
|