@red-hat-developer-hub/backstage-plugin-bulk-import-backend 8.0.0 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/catalog/catalogHttpClient.cjs.js.map +1 -1
- package/dist/database/repositoryDao.cjs.js +6 -1
- package/dist/database/repositoryDao.cjs.js.map +1 -1
- package/dist/github/types.cjs.js.map +1 -1
- package/dist/github/utils/orgUtils.cjs.js.map +1 -1
- package/dist/service/handlers/import/bulkImports.cjs.js.map +1 -1
- package/dist/service/router.cjs.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @red-hat-developer-hub/backstage-plugin-bulk-import-backend
|
|
2
2
|
|
|
3
|
+
## 8.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e0d0986: Updated dependency `prettier` to `3.9.6`.
|
|
8
|
+
- 503c66e: Updated dependency `@openapitools/openapi-generator-cli` to `2.40.1`.
|
|
9
|
+
Updated dependency `@red-hat-developer-hub/backstage-plugin-theme` to `^0.15.0`.
|
|
10
|
+
- 8966faf: Updated dependency `prettier` to `3.9.5`.
|
|
11
|
+
- Updated dependencies [e0d0986]
|
|
12
|
+
- Updated dependencies [8966faf]
|
|
13
|
+
- @red-hat-developer-hub/backstage-plugin-bulk-import-common@8.0.1
|
|
14
|
+
|
|
3
15
|
## 8.0.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
|
@@ -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 { 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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"}
|
|
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 error.message?.includes('ConflictError') ||\n error.body?.error?.name?.includes('ConflictError')\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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"}
|
|
@@ -89,7 +89,12 @@ class ScaffolderTaskDao {
|
|
|
89
89
|
return result[0].taskId;
|
|
90
90
|
}
|
|
91
91
|
async findTasksByRepositoryId(repositoryId) {
|
|
92
|
-
return await this.knex("scaffolder_tasks").where({ repositoryId }).select(
|
|
92
|
+
return await this.knex("scaffolder_tasks").where({ repositoryId }).select(
|
|
93
|
+
"taskId",
|
|
94
|
+
"repositoryId",
|
|
95
|
+
"scaffolderOptions",
|
|
96
|
+
"executedAt"
|
|
97
|
+
);
|
|
93
98
|
}
|
|
94
99
|
async lastExecutedTaskByRepoId(repositoryId) {
|
|
95
100
|
return await this.knex("scaffolder_tasks").where({ repositoryId }).orderBy("executedAt", "desc").first();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repositoryDao.cjs.js","sources":["../../src/database/repositoryDao.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 { LoggerService } from '@backstage/backend-plugin-api';\n\nimport { Knex } from 'knex';\n\nimport { Components } from '../generated/openapi';\n\nexport interface Repository {\n id: number;\n url: string;\n approvalTool: Components.Schemas.ApprovalTool;\n}\n\nexport interface ScaffolderTask {\n taskId: string;\n scaffolderOptions: any;\n repositoryId: number;\n executedAt?: Date;\n}\n\nexport interface PaginatedResult<T> {\n data: T[];\n page: number;\n size: number;\n total: number;\n totalPages: number;\n}\n\nexport async function paginateQuery<T>(\n queryBuilder: Knex.QueryBuilder<any, T[]>,\n page: number = 1,\n size: number = 10,\n search?: { column: string; term?: string },\n): Promise<PaginatedResult<T>> {\n const offset = (page - 1) * size;\n\n let baseQuery = queryBuilder.clone();\n\n if (search?.term) {\n if (queryBuilder.client.dialect === 'postgres') {\n baseQuery = baseQuery.whereILike(search.column, `%${search.term}%`);\n } else {\n baseQuery = baseQuery.whereLike(search.column, `%${search.term}%`);\n }\n }\n\n const countQuery = baseQuery\n .clone()\n .clearSelect()\n .clearOrder()\n .count<{ count: string }[]>('* as count');\n\n const [rows, [{ count }]] = await Promise.all([\n baseQuery.clone().limit(size).offset(offset),\n countQuery,\n ]);\n\n const total = Number(count);\n\n return {\n data: rows as T[],\n page,\n size,\n total,\n totalPages: Math.ceil(total / size),\n };\n}\n\nexport type RepositoryName = 'repositories' | 'orchestrator_repositories';\n\n// @internal\nexport class RepositoryDao<R extends RepositoryName> {\n constructor(\n private readonly knex: Knex<any, any[]>,\n private readonly logger: LoggerService,\n private readonly tableName: R,\n ) {}\n\n async findRepositories(\n page: number = 1,\n size: number = 10,\n search?: string,\n ): Promise<PaginatedResult<Repository>> {\n this.logger.debug(\n `Fetching repositories page=${page}, size=${size}, search=${search}`,\n );\n const query = this.knex(this.tableName).select('id', 'url', 'approvalTool');\n const searchParam = { column: 'url', term: search };\n return paginateQuery<Repository>(query, page, size, searchParam);\n }\n\n async insertRepository(\n repoUrl: string,\n taskOrWorkflowId: string,\n approvalTool: string,\n ): Promise<number> {\n this.logger.debug(\n `Saving repository ${repoUrl} for task/workflow ${taskOrWorkflowId} to database..`,\n );\n const repository = await this.knex(this.tableName)\n .where({ url: repoUrl })\n .first();\n\n let repositoryId;\n if (repository) {\n repositoryId = repository.id;\n } else {\n const [newRepository] = await this.knex(this.tableName)\n .insert({ url: repoUrl, approvalTool: approvalTool })\n .returning('id');\n repositoryId = newRepository.id;\n }\n return repositoryId;\n }\n\n async findRepositoryByUrl(url: string): Promise<Repository | undefined> {\n this.logger.debug(`Fetching repository from database by url ${url}...`);\n return await this.knex(this.tableName).where({ url: url }).first();\n }\n\n async deleteRepository(url: string): Promise<void> {\n this.logger.debug(`Deleting repository from database by url ${url}...`);\n const repository = await this.knex(this.tableName)\n .where({ url: url })\n .first();\n\n if (repository) {\n await this.knex(this.tableName).where({ id: repository.id }).del();\n }\n }\n}\n\n// @internal\nexport class ScaffolderTaskDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async findAllTasks(): Promise<ScaffolderTask[]> {\n return await this.knex('scaffolder_tasks').select<ScaffolderTask[]>(\n 'taskId',\n 'repositoryId',\n 'scaffolderOptions',\n );\n }\n\n async insertTask(task: ScaffolderTask): Promise<string> {\n const result = await this.knex('scaffolder_tasks')\n .insert<ScaffolderTask>({\n taskId: task.taskId,\n repositoryId: task.repositoryId,\n scaffolderOptions: JSON.stringify(task.scaffolderOptions),\n executedAt: task.executedAt,\n })\n .returning<{ taskId: string }[]>('taskId');\n\n return result[0].taskId;\n }\n\n async findTasksByRepositoryId(\n repositoryId: number,\n ): Promise<ScaffolderTask[]> {\n return await this.knex('scaffolder_tasks')\n .where({ repositoryId })\n .select<\n ScaffolderTask[]\n >('taskId', 'repositoryId', 'scaffolderOptions', 'executedAt');\n }\n\n async lastExecutedTaskByRepoId(\n repositoryId: number,\n ): Promise<ScaffolderTask | undefined> {\n return await this.knex('scaffolder_tasks')\n .where({ repositoryId })\n .orderBy('executedAt', 'desc')\n .first<ScaffolderTask>();\n }\n}\n\nexport interface TaskLocation {\n id: number;\n taskId: string;\n location: string;\n type: string;\n}\n\n// @internal\nexport class TaskLocationsDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async addTaskLocation(\n taskId: string,\n location: string,\n type: string = 'component',\n ): Promise<void> {\n await this.knex('task_locations').insert({ taskId, location, type });\n }\n\n async findLocationsByTaskId(taskId: string): Promise<TaskLocation[]> {\n return await this.knex('task_locations')\n .where({ taskId })\n .select<TaskLocation[]>('id', 'taskId', 'location', 'type');\n }\n\n async findAllLocations(): Promise<TaskLocation[]> {\n return await this.knex('task_locations').select<TaskLocation[]>(\n 'id',\n 'taskId',\n 'location',\n 'type',\n );\n }\n}\n\nexport interface OrchestratorWorkflow {\n id: number;\n instanceId: string;\n repositoryId: number;\n createdAt: Date;\n status?: string;\n}\n\n// @internal\nexport class OrchestratorWorkflowDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async insertWorkflow(\n instanceId: string,\n repositoryId: number,\n ): Promise<number> {\n const [newWorkflow] = await this.knex('orchestrator_workflows')\n .insert({\n instance_id: instanceId,\n repositoryId: repositoryId,\n })\n .returning('id');\n return newWorkflow.id;\n }\n\n async lastExecutedWorkflowByRepoId(\n repositoryId: number,\n ): Promise<OrchestratorWorkflow | undefined> {\n const result = await this.knex('orchestrator_workflows')\n .select({\n id: 'id',\n instanceId: 'instance_id',\n repositoryId: 'repositoryId',\n createdAt: 'created_at',\n })\n .where({ repositoryId: repositoryId })\n .orderBy('created_at', 'desc')\n .first();\n return result;\n }\n\n async findWorkflowsByRepositoryId(\n repositoryId: number,\n ): Promise<OrchestratorWorkflow[]> {\n return await this.knex('orchestrator_workflows')\n .where({ repositoryId: repositoryId })\n .select({\n id: 'id',\n instanceId: 'instance_id',\n repositoryId: 'repositoryId',\n createdAt: 'created_at',\n });\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"repositoryDao.cjs.js","sources":["../../src/database/repositoryDao.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 { LoggerService } from '@backstage/backend-plugin-api';\n\nimport { Knex } from 'knex';\n\nimport { Components } from '../generated/openapi';\n\nexport interface Repository {\n id: number;\n url: string;\n approvalTool: Components.Schemas.ApprovalTool;\n}\n\nexport interface ScaffolderTask {\n taskId: string;\n scaffolderOptions: any;\n repositoryId: number;\n executedAt?: Date;\n}\n\nexport interface PaginatedResult<T> {\n data: T[];\n page: number;\n size: number;\n total: number;\n totalPages: number;\n}\n\nexport async function paginateQuery<T>(\n queryBuilder: Knex.QueryBuilder<any, T[]>,\n page: number = 1,\n size: number = 10,\n search?: { column: string; term?: string },\n): Promise<PaginatedResult<T>> {\n const offset = (page - 1) * size;\n\n let baseQuery = queryBuilder.clone();\n\n if (search?.term) {\n if (queryBuilder.client.dialect === 'postgres') {\n baseQuery = baseQuery.whereILike(search.column, `%${search.term}%`);\n } else {\n baseQuery = baseQuery.whereLike(search.column, `%${search.term}%`);\n }\n }\n\n const countQuery = baseQuery\n .clone()\n .clearSelect()\n .clearOrder()\n .count<{ count: string }[]>('* as count');\n\n const [rows, [{ count }]] = await Promise.all([\n baseQuery.clone().limit(size).offset(offset),\n countQuery,\n ]);\n\n const total = Number(count);\n\n return {\n data: rows as T[],\n page,\n size,\n total,\n totalPages: Math.ceil(total / size),\n };\n}\n\nexport type RepositoryName = 'repositories' | 'orchestrator_repositories';\n\n// @internal\nexport class RepositoryDao<R extends RepositoryName> {\n constructor(\n private readonly knex: Knex<any, any[]>,\n private readonly logger: LoggerService,\n private readonly tableName: R,\n ) {}\n\n async findRepositories(\n page: number = 1,\n size: number = 10,\n search?: string,\n ): Promise<PaginatedResult<Repository>> {\n this.logger.debug(\n `Fetching repositories page=${page}, size=${size}, search=${search}`,\n );\n const query = this.knex(this.tableName).select('id', 'url', 'approvalTool');\n const searchParam = { column: 'url', term: search };\n return paginateQuery<Repository>(query, page, size, searchParam);\n }\n\n async insertRepository(\n repoUrl: string,\n taskOrWorkflowId: string,\n approvalTool: string,\n ): Promise<number> {\n this.logger.debug(\n `Saving repository ${repoUrl} for task/workflow ${taskOrWorkflowId} to database..`,\n );\n const repository = await this.knex(this.tableName)\n .where({ url: repoUrl })\n .first();\n\n let repositoryId;\n if (repository) {\n repositoryId = repository.id;\n } else {\n const [newRepository] = await this.knex(this.tableName)\n .insert({ url: repoUrl, approvalTool: approvalTool })\n .returning('id');\n repositoryId = newRepository.id;\n }\n return repositoryId;\n }\n\n async findRepositoryByUrl(url: string): Promise<Repository | undefined> {\n this.logger.debug(`Fetching repository from database by url ${url}...`);\n return await this.knex(this.tableName).where({ url: url }).first();\n }\n\n async deleteRepository(url: string): Promise<void> {\n this.logger.debug(`Deleting repository from database by url ${url}...`);\n const repository = await this.knex(this.tableName)\n .where({ url: url })\n .first();\n\n if (repository) {\n await this.knex(this.tableName).where({ id: repository.id }).del();\n }\n }\n}\n\n// @internal\nexport class ScaffolderTaskDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async findAllTasks(): Promise<ScaffolderTask[]> {\n return await this.knex('scaffolder_tasks').select<ScaffolderTask[]>(\n 'taskId',\n 'repositoryId',\n 'scaffolderOptions',\n );\n }\n\n async insertTask(task: ScaffolderTask): Promise<string> {\n const result = await this.knex('scaffolder_tasks')\n .insert<ScaffolderTask>({\n taskId: task.taskId,\n repositoryId: task.repositoryId,\n scaffolderOptions: JSON.stringify(task.scaffolderOptions),\n executedAt: task.executedAt,\n })\n .returning<{ taskId: string }[]>('taskId');\n\n return result[0].taskId;\n }\n\n async findTasksByRepositoryId(\n repositoryId: number,\n ): Promise<ScaffolderTask[]> {\n return await this.knex('scaffolder_tasks')\n .where({ repositoryId })\n .select<ScaffolderTask[]>(\n 'taskId',\n 'repositoryId',\n 'scaffolderOptions',\n 'executedAt',\n );\n }\n\n async lastExecutedTaskByRepoId(\n repositoryId: number,\n ): Promise<ScaffolderTask | undefined> {\n return await this.knex('scaffolder_tasks')\n .where({ repositoryId })\n .orderBy('executedAt', 'desc')\n .first<ScaffolderTask>();\n }\n}\n\nexport interface TaskLocation {\n id: number;\n taskId: string;\n location: string;\n type: string;\n}\n\n// @internal\nexport class TaskLocationsDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async addTaskLocation(\n taskId: string,\n location: string,\n type: string = 'component',\n ): Promise<void> {\n await this.knex('task_locations').insert({ taskId, location, type });\n }\n\n async findLocationsByTaskId(taskId: string): Promise<TaskLocation[]> {\n return await this.knex('task_locations')\n .where({ taskId })\n .select<TaskLocation[]>('id', 'taskId', 'location', 'type');\n }\n\n async findAllLocations(): Promise<TaskLocation[]> {\n return await this.knex('task_locations').select<TaskLocation[]>(\n 'id',\n 'taskId',\n 'location',\n 'type',\n );\n }\n}\n\nexport interface OrchestratorWorkflow {\n id: number;\n instanceId: string;\n repositoryId: number;\n createdAt: Date;\n status?: string;\n}\n\n// @internal\nexport class OrchestratorWorkflowDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async insertWorkflow(\n instanceId: string,\n repositoryId: number,\n ): Promise<number> {\n const [newWorkflow] = await this.knex('orchestrator_workflows')\n .insert({\n instance_id: instanceId,\n repositoryId: repositoryId,\n })\n .returning('id');\n return newWorkflow.id;\n }\n\n async lastExecutedWorkflowByRepoId(\n repositoryId: number,\n ): Promise<OrchestratorWorkflow | undefined> {\n const result = await this.knex('orchestrator_workflows')\n .select({\n id: 'id',\n instanceId: 'instance_id',\n repositoryId: 'repositoryId',\n createdAt: 'created_at',\n })\n .where({ repositoryId: repositoryId })\n .orderBy('created_at', 'desc')\n .first();\n return result;\n }\n\n async findWorkflowsByRepositoryId(\n repositoryId: number,\n ): Promise<OrchestratorWorkflow[]> {\n return await this.knex('orchestrator_workflows')\n .where({ repositoryId: repositoryId })\n .select({\n id: 'id',\n instanceId: 'instance_id',\n repositoryId: 'repositoryId',\n createdAt: 'created_at',\n });\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs.js","sources":["../../src/github/types.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 GithubCredentials,\n GithubCredentialsProvider,\n} from '@backstage/integration';\n\nimport { type RestEndpointMethodTypes } from '@octokit/rest';\n\nexport type {\n SCMFetchError as GithubFetchError,\n SCMOrganization as GithubOrganization,\n SCMOrganizationResponse as GithubOrganizationResponse,\n SCMRepository as GithubRepository,\n SCMRepositoryResponse as GithubRepositoryResponse,\n} from '../scm/types';\n\nexport type AppCredentialFetchResult = AppCredential | AppCredentialError;\n\nexport type AppCredential = {\n appId: number;\n accessToken: string | undefined;\n installationAccountLogin?: string;\n};\nexport type AppCredentialError = { appId: number; error: Error };\n\nexport type ExtendedGithubCredentials =\n
|
|
1
|
+
{"version":3,"file":"types.cjs.js","sources":["../../src/github/types.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 GithubCredentials,\n GithubCredentialsProvider,\n} from '@backstage/integration';\n\nimport { type RestEndpointMethodTypes } from '@octokit/rest';\n\nexport type {\n SCMFetchError as GithubFetchError,\n SCMOrganization as GithubOrganization,\n SCMOrganizationResponse as GithubOrganizationResponse,\n SCMRepository as GithubRepository,\n SCMRepositoryResponse as GithubRepositoryResponse,\n} from '../scm/types';\n\nexport type AppCredentialFetchResult = AppCredential | AppCredentialError;\n\nexport type AppCredential = {\n appId: number;\n accessToken: string | undefined;\n installationAccountLogin?: string;\n};\nexport type AppCredentialError = { appId: number; error: Error };\n\nexport type ExtendedGithubCredentials =\n GithubCredentials | GithubAppCredentials | GithubAppError;\n\nexport type GithubAppCredentials = GithubCredentials & {\n type: 'app';\n appId: number;\n accountLogin?: string;\n};\n\nexport type GithubAppError = {\n type: 'app';\n appId: number;\n error: Error;\n};\n\nexport function isGithubAppCredential(\n credential: ExtendedGithubCredentials,\n): credential is GithubAppCredentials {\n return 'appId' in credential && credential.type === 'app';\n}\n\nexport interface ExtendedGithubCredentialsProvider extends GithubCredentialsProvider {\n getAllCredentials: (options: {\n host: string;\n }) => Promise<ExtendedGithubCredentials[]>;\n}\n\nexport type AuthenticatedUserRepositoryResponse =\n RestEndpointMethodTypes['repos']['listForAuthenticatedUser']['response'];\n\nexport type AuthenticatedUserRepositoryList =\n AuthenticatedUserRepositoryResponse['data'];\n\nexport type AppInstallationRepositoriesResponse =\n RestEndpointMethodTypes['apps']['listReposAccessibleToInstallation']['response'];\n\nexport type AppInstallationRepositories =\n AppInstallationRepositoriesResponse['data'];\n"],"names":[],"mappings":";;AAuDO,SAAS,sBACd,UAAA,EACoC;AACpC,EAAA,OAAO,OAAA,IAAW,UAAA,IAAc,UAAA,CAAW,IAAA,KAAS,KAAA;AACtD;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orgUtils.cjs.js","sources":["../../../src/github/utils/orgUtils.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 { LoggerService } from '@backstage/backend-plugin-api';\nimport type {\n GithubCredentials,\n GithubIntegrationConfig,\n} from '@backstage/integration';\n\nimport { Octokit } from '@octokit/rest';\n\nimport { logErrorIfNeeded, paginateArray } from '../../helpers';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../../service/handlers/handlers';\nimport type { CustomGithubCredentialsProvider } from '../GithubAppManager';\nimport type { GithubFetchError, GithubOrganization } from '../types';\nimport { computeTotalCountFromGitHubToken, handleError } from './utils';\n\nexport async function getAllAppOrgs(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n ghConfig: GithubIntegrationConfig,\n credentialAccountLogin?: string,\n) {\n const result = new Map<string, GithubOrganization>();\n const resp = await githubCredentialsProvider.getAllAppInstallations(ghConfig);\n for (const installation of resp ?? []) {\n if (\n !(\n installation.account &&\n installation.target_type?.toLowerCase() === 'organization'\n )\n ) {\n continue;\n }\n const acc = installation.account!;\n if (credentialAccountLogin !== acc.login) {\n continue;\n }\n result.set(acc.url, {\n id: acc.id,\n description: acc.description ?? undefined,\n name: acc.login,\n url: acc.html_url,\n html_url: acc.html_url,\n repos_url: acc.repos_url,\n events_url: acc.events_url,\n });\n }\n return result;\n}\n\nexport async function addGithubAppOrgs(\n deps: {\n logger: LoggerService;\n githubCredentialsProvider: CustomGithubCredentialsProvider;\n },\n octokit: Octokit,\n ghConfig: GithubIntegrationConfig,\n params: {\n credentialAccountLogin: string | undefined;\n search: string | undefined;\n orgs: Map<string, GithubOrganization>;\n errors: Map<number, GithubFetchError>;\n },\n): Promise<{ totalCount?: number }> {\n const credentialAccountLogin = params.credentialAccountLogin;\n const search = params.search;\n const orgs = params.orgs;\n const errors = params.errors;\n let totalCount = 0;\n try {\n const resp = await getAllAppOrgs(\n deps.githubCredentialsProvider,\n ghConfig,\n credentialAccountLogin,\n );\n for (const [orgUrl, ghOrg] of resp) {\n if (search && !ghOrg.name.toLowerCase().includes(search.toLowerCase())) {\n continue;\n }\n const orgData = await octokit.request(\n orgUrl.replace('/users/', '/orgs/'),\n );\n orgs.set(ghOrg.name, {\n ...ghOrg,\n public_repos: orgData?.data?.public_repos,\n total_private_repos: orgData?.data?.total_private_repos,\n owned_private_repos: orgData?.data?.owned_private_repos,\n });\n totalCount++;\n }\n } catch (err: any) {\n logErrorIfNeeded(\n deps.logger,\n `Fetching organizations with access token for github app`,\n err,\n );\n errors.set(-1, err.message);\n }\n return { totalCount };\n}\n\nexport async function addGithubTokenOrgs(\n deps: {\n logger: LoggerService;\n },\n octokit: Octokit,\n credential: GithubCredentials,\n params: {\n search: string | undefined;\n orgs: Map<string, GithubOrganization>;\n errors: Map<number, GithubFetchError>;\n pageNumber: number;\n pageSize: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = params.search;\n const orgs = params.orgs;\n const errors = params.errors;\n const pageNumber = params.pageNumber ?? DefaultPageNumber;\n const pageSize = params.pageSize ?? DefaultPageSize;\n\n let totalCount: number | undefined;\n try {\n let matchingOrgs;\n if (search) {\n // Initial idea was to leverage octokit.rest.search.users({q: `${search} type:org`}),\n // but this searches across all of GitHub, not only the orgs accessible by the current creds.\n // That's why we are searching in everything, hoping the list of organizations to not be that big in size\n const resp = await octokit.paginate(\n octokit.rest.orgs.listForAuthenticatedUser,\n {\n sort: 'full_name',\n direction: 'asc',\n },\n );\n const allMatchingOrgs =\n resp?.filter(org =>\n org.login.toLowerCase().includes(search.toLowerCase()),\n ) ?? [];\n const matchingOrgsPage = paginateArray(\n allMatchingOrgs,\n pageNumber,\n pageSize,\n );\n matchingOrgs = matchingOrgsPage.result;\n totalCount = matchingOrgsPage.totalCount;\n } else {\n /**\n * The listForAuthenticatedUser endpoint will grab all the repositories the github token has explicit access to.\n * These would include repositories they own, repositories where they are a collaborator,\n * and repositories that they can access through an organization membership.\n */\n const resp = await octokit.rest.orgs.listForAuthenticatedUser({\n page: pageNumber,\n per_page: pageSize,\n sort: 'full_name',\n direction: 'asc',\n });\n matchingOrgs = resp?.data ?? [];\n\n totalCount = await computeTotalCountFromGitHubToken(\n deps,\n async (lastPageNumber: number) =>\n octokit.orgs\n .listForAuthenticatedUser({\n page: lastPageNumber,\n per_page: 100,\n })\n .then(lastPageResp => lastPageResp.data.length),\n 'orgs.listForAuthenticatedUser',\n resp?.data?.length,\n resp?.headers?.link,\n );\n }\n\n for (const org of matchingOrgs) {\n const orgData = await octokit.request(org.url);\n const ghOrg: GithubOrganization = {\n id: org.id,\n name: org.login,\n description: org.description ?? undefined,\n url: orgData?.data?.html_url ?? org.url,\n repos_url: org.repos_url,\n hooks_url: org.hooks_url,\n issues_url: org.issues_url,\n members_url: org.members_url,\n public_members_url: org.public_members_url,\n avatar_url: org.avatar_url,\n public_repos: orgData?.data?.public_repos,\n total_private_repos: orgData?.data?.total_private_repos,\n owned_private_repos: orgData?.data?.owned_private_repos,\n };\n orgs.set(org.login, ghOrg);\n }\n } catch (err) {\n handleError(\n { logger: deps.logger },\n 'Fetching orgs with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n"],"names":["logErrorIfNeeded","DefaultPageNumber","DefaultPageSize","paginateArray","computeTotalCountFromGitHubToken","handleError"],"mappings":";;;;;;;;;;;;;AAiCA,eAAsB,aAAA,CACpB,yBAAA,EACA,QAAA,EACA,sBAAA,EACA;AACA,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAgC;AACnD,EAAA,MAAM,IAAA,GAAO,MAAM,yBAAA,CAA0B,sBAAA,CAAuB,QAAQ,CAAA;AAC5E,EAAA,KAAA,MAAW,YAAA,IAAgB,IAAA,IAAQ,EAAC,EAAG;AACrC,IAAA,IACE,EACE,YAAA,CAAa,OAAA,IACb,aAAa,WAAA,EAAa,WAAA,OAAkB,cAAA,CAAA,EAE9C;AACA,MAAA;AAAA,IACF;AACA,IAAA,MAAM,MAAM,YAAA,CAAa,OAAA;AACzB,IAAA,IAAI,sBAAA,KAA2B,IAAI,KAAA,EAAO;AACxC,MAAA;AAAA,IACF;AACA,IAAA,MAAA,CAAO,GAAA,CAAI,IAAI,GAAA,EAAK;AAAA,MAClB,IAAI,GAAA,CAAI,EAAA;AAAA,MACR,WAAA,EAAa,IAAI,WAAA,IAAe,MAAA;AAAA,MAChC,MAAM,GAAA,CAAI,KAAA;AAAA,MACV,KAAK,GAAA,CAAI,QAAA;AAAA,MACT,UAAU,GAAA,CAAI,QAAA;AAAA,MACd,WAAW,GAAA,CAAI,SAAA;AAAA,MACf,YAAY,GAAA,CAAI;AAAA,KACjB,CAAA;AAAA,EACH;AACA,EAAA,OAAO,MAAA;AACT;AAEA,eAAsB,gBAAA,CACpB,IAAA,EAIA,OAAA,EACA,QAAA,EACA,MAAA,EAMkC;AAClC,EAAA,MAAM,yBAAyB,MAAA,CAAO,sBAAA;AACtC,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AACpB,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI;AACF,IAAA,MAAM,OAAO,MAAM,aAAA;AAAA,MACjB,IAAA,CAAK,yBAAA;AAAA,MACL,QAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,KAAA,MAAW,CAAC,MAAA,EAAQ,KAAK,CAAA,IAAK,IAAA,EAAM;AAClC,MAAA,IAAI,MAAA,IAAU,CAAC,KAAA,CAAM,IAAA,CAAK,WAAA,GAAc,QAAA,CAAS,MAAA,CAAO,WAAA,EAAa,CAAA,EAAG;AACtE,QAAA;AAAA,MACF;AACA,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,OAAA;AAAA,QAC5B,MAAA,CAAO,OAAA,CAAQ,SAAA,EAAW,QAAQ;AAAA,OACpC;AACA,MAAA,IAAA,CAAK,GAAA,CAAI,MAAM,IAAA,EAAM;AAAA,QACnB,GAAG,KAAA;AAAA,QACH,YAAA,EAAc,SAAS,IAAA,EAAM,YAAA;AAAA,QAC7B,mBAAA,EAAqB,SAAS,IAAA,EAAM,mBAAA;AAAA,QACpC,mBAAA,EAAqB,SAAS,IAAA,EAAM;AAAA,OACrC,CAAA;AACD,MAAA,UAAA,EAAA;AAAA,IACF;AAAA,EACF,SAAS,GAAA,EAAU;AACjB,IAAAA,6BAAA;AAAA,MACE,IAAA,CAAK,MAAA;AAAA,MACL,CAAA,uDAAA,CAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAA,CAAO,GAAA,CAAI,EAAA,EAAI,GAAA,CAAI,OAAO,CAAA;AAAA,EAC5B;AACA,EAAA,OAAO,EAAE,UAAA,EAAW;AACtB;AAEA,eAAsB,kBAAA,CACpB,IAAA,EAGA,OAAA,EACA,UAAA,EACA,MAAA,EAOkC;AAClC,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AACpB,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,EAAA,MAAM,UAAA,GAAa,OAAO,UAAA,IAAcC,0BAAA;AACxC,EAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAYC,wBAAA;AAEpC,EAAA,IAAI,UAAA;AACJ,EAAA,IAAI;AACF,IAAA,IAAI,YAAA;AACJ,IAAA,IAAI,MAAA,EAAQ;AAIV,MAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,QAAA;AAAA,QACzB,OAAA,CAAQ,KAAK,IAAA,CAAK,wBAAA;AAAA,QAClB;AAAA,UACE,IAAA,EAAM,WAAA;AAAA,UACN,SAAA,EAAW;AAAA;AACb,OACF;AACA,MAAA,MAAM,kBACJ,IAAA,EAAM,MAAA;AAAA,QAAO,CAAA,GAAA,KACX,IAAI,KAAA,CAAM,WAAA,GAAc,QAAA,CAAS,MAAA,CAAO,aAAa;AAAA,WAClD,EAAC;AACR,MAAA,MAAM,gBAAA,GAAmBC,wBAAA;AAAA,QACvB,eAAA;AAAA,QACA,UAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,YAAA,GAAe,gBAAA,CAAiB,MAAA;AAChC,MAAA,UAAA,GAAa,gBAAA,CAAiB,UAAA;AAAA,IAChC,CAAA,MAAO;AAML,MAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,IAAA,CAAK,KAAK,wBAAA,CAAyB;AAAA,QAC5D,IAAA,EAAM,UAAA;AAAA,QACN,QAAA,EAAU,QAAA;AAAA,QACV,IAAA,EAAM,WAAA;AAAA,QACN,SAAA,EAAW;AAAA,OACZ,CAAA;AACD,MAAA,YAAA,GAAe,IAAA,EAAM,QAAQ,EAAC;AAE9B,MAAA,UAAA,GAAa,MAAMC,sCAAA;AAAA,QACjB,IAAA;AAAA,QACA,OAAO,cAAA,KACL,OAAA,CAAQ,IAAA,CACL,wBAAA,CAAyB;AAAA,UACxB,IAAA,EAAM,cAAA;AAAA,UACN,QAAA,EAAU;AAAA,SACX,CAAA,CACA,IAAA,CAAK,CAAA,YAAA,KAAgB,YAAA,CAAa,KAAK,MAAM,CAAA;AAAA,QAClD,+BAAA;AAAA,QACA,MAAM,IAAA,EAAM,MAAA;AAAA,QACZ,MAAM,OAAA,EAAS;AAAA,OACjB;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,OAAO,YAAA,EAAc;AAC9B,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,OAAA,CAAQ,IAAI,GAAG,CAAA;AAC7C,MAAA,MAAM,KAAA,GAA4B;AAAA,QAChC,IAAI,GAAA,CAAI,EAAA;AAAA,QACR,MAAM,GAAA,CAAI,KAAA;AAAA,QACV,WAAA,EAAa,IAAI,WAAA,IAAe,KAAA,CAAA;AAAA,QAChC,GAAA,EAAK,OAAA,EAAS,IAAA,EAAM,QAAA,IAAY,GAAA,CAAI,GAAA;AAAA,QACpC,WAAW,GAAA,CAAI,SAAA;AAAA,QACf,WAAW,GAAA,CAAI,SAAA;AAAA,QACf,YAAY,GAAA,CAAI,UAAA;AAAA,QAChB,aAAa,GAAA,CAAI,WAAA;AAAA,QACjB,oBAAoB,GAAA,CAAI,kBAAA;AAAA,QACxB,YAAY,GAAA,CAAI,UAAA;AAAA,QAChB,YAAA,EAAc,SAAS,IAAA,EAAM,YAAA;AAAA,QAC7B,mBAAA,EAAqB,SAAS,IAAA,EAAM,mBAAA;AAAA,QACpC,mBAAA,EAAqB,SAAS,IAAA,EAAM;AAAA,OACtC;AACA,MAAA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,KAAA,EAAO,KAAK,CAAA;AAAA,IAC3B;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAAC,iBAAA;AAAA,MACE,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAO;AAAA,MACtB,qCAAA;AAAA,MACA,UAAA;AAAA,MACA,MAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,EAAE,UAAA,EAAW;AACtB;;;;;;"}
|
|
1
|
+
{"version":3,"file":"orgUtils.cjs.js","sources":["../../../src/github/utils/orgUtils.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 { LoggerService } from '@backstage/backend-plugin-api';\nimport type {\n GithubCredentials,\n GithubIntegrationConfig,\n} from '@backstage/integration';\n\nimport { Octokit } from '@octokit/rest';\n\nimport { logErrorIfNeeded, paginateArray } from '../../helpers';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../../service/handlers/handlers';\nimport type { CustomGithubCredentialsProvider } from '../GithubAppManager';\nimport type { GithubFetchError, GithubOrganization } from '../types';\nimport { computeTotalCountFromGitHubToken, handleError } from './utils';\n\nexport async function getAllAppOrgs(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n ghConfig: GithubIntegrationConfig,\n credentialAccountLogin?: string,\n) {\n const result = new Map<string, GithubOrganization>();\n const resp = await githubCredentialsProvider.getAllAppInstallations(ghConfig);\n for (const installation of resp ?? []) {\n if (!(\n installation.account &&\n installation.target_type?.toLowerCase() === 'organization'\n )) {\n continue;\n }\n const acc = installation.account!;\n if (credentialAccountLogin !== acc.login) {\n continue;\n }\n result.set(acc.url, {\n id: acc.id,\n description: acc.description ?? undefined,\n name: acc.login,\n url: acc.html_url,\n html_url: acc.html_url,\n repos_url: acc.repos_url,\n events_url: acc.events_url,\n });\n }\n return result;\n}\n\nexport async function addGithubAppOrgs(\n deps: {\n logger: LoggerService;\n githubCredentialsProvider: CustomGithubCredentialsProvider;\n },\n octokit: Octokit,\n ghConfig: GithubIntegrationConfig,\n params: {\n credentialAccountLogin: string | undefined;\n search: string | undefined;\n orgs: Map<string, GithubOrganization>;\n errors: Map<number, GithubFetchError>;\n },\n): Promise<{ totalCount?: number }> {\n const credentialAccountLogin = params.credentialAccountLogin;\n const search = params.search;\n const orgs = params.orgs;\n const errors = params.errors;\n let totalCount = 0;\n try {\n const resp = await getAllAppOrgs(\n deps.githubCredentialsProvider,\n ghConfig,\n credentialAccountLogin,\n );\n for (const [orgUrl, ghOrg] of resp) {\n if (search && !ghOrg.name.toLowerCase().includes(search.toLowerCase())) {\n continue;\n }\n const orgData = await octokit.request(\n orgUrl.replace('/users/', '/orgs/'),\n );\n orgs.set(ghOrg.name, {\n ...ghOrg,\n public_repos: orgData?.data?.public_repos,\n total_private_repos: orgData?.data?.total_private_repos,\n owned_private_repos: orgData?.data?.owned_private_repos,\n });\n totalCount++;\n }\n } catch (err: any) {\n logErrorIfNeeded(\n deps.logger,\n `Fetching organizations with access token for github app`,\n err,\n );\n errors.set(-1, err.message);\n }\n return { totalCount };\n}\n\nexport async function addGithubTokenOrgs(\n deps: {\n logger: LoggerService;\n },\n octokit: Octokit,\n credential: GithubCredentials,\n params: {\n search: string | undefined;\n orgs: Map<string, GithubOrganization>;\n errors: Map<number, GithubFetchError>;\n pageNumber: number;\n pageSize: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = params.search;\n const orgs = params.orgs;\n const errors = params.errors;\n const pageNumber = params.pageNumber ?? DefaultPageNumber;\n const pageSize = params.pageSize ?? DefaultPageSize;\n\n let totalCount: number | undefined;\n try {\n let matchingOrgs;\n if (search) {\n // Initial idea was to leverage octokit.rest.search.users({q: `${search} type:org`}),\n // but this searches across all of GitHub, not only the orgs accessible by the current creds.\n // That's why we are searching in everything, hoping the list of organizations to not be that big in size\n const resp = await octokit.paginate(\n octokit.rest.orgs.listForAuthenticatedUser,\n {\n sort: 'full_name',\n direction: 'asc',\n },\n );\n const allMatchingOrgs =\n resp?.filter(org =>\n org.login.toLowerCase().includes(search.toLowerCase()),\n ) ?? [];\n const matchingOrgsPage = paginateArray(\n allMatchingOrgs,\n pageNumber,\n pageSize,\n );\n matchingOrgs = matchingOrgsPage.result;\n totalCount = matchingOrgsPage.totalCount;\n } else {\n /**\n * The listForAuthenticatedUser endpoint will grab all the repositories the github token has explicit access to.\n * These would include repositories they own, repositories where they are a collaborator,\n * and repositories that they can access through an organization membership.\n */\n const resp = await octokit.rest.orgs.listForAuthenticatedUser({\n page: pageNumber,\n per_page: pageSize,\n sort: 'full_name',\n direction: 'asc',\n });\n matchingOrgs = resp?.data ?? [];\n\n totalCount = await computeTotalCountFromGitHubToken(\n deps,\n async (lastPageNumber: number) =>\n octokit.orgs\n .listForAuthenticatedUser({\n page: lastPageNumber,\n per_page: 100,\n })\n .then(lastPageResp => lastPageResp.data.length),\n 'orgs.listForAuthenticatedUser',\n resp?.data?.length,\n resp?.headers?.link,\n );\n }\n\n for (const org of matchingOrgs) {\n const orgData = await octokit.request(org.url);\n const ghOrg: GithubOrganization = {\n id: org.id,\n name: org.login,\n description: org.description ?? undefined,\n url: orgData?.data?.html_url ?? org.url,\n repos_url: org.repos_url,\n hooks_url: org.hooks_url,\n issues_url: org.issues_url,\n members_url: org.members_url,\n public_members_url: org.public_members_url,\n avatar_url: org.avatar_url,\n public_repos: orgData?.data?.public_repos,\n total_private_repos: orgData?.data?.total_private_repos,\n owned_private_repos: orgData?.data?.owned_private_repos,\n };\n orgs.set(org.login, ghOrg);\n }\n } catch (err) {\n handleError(\n { logger: deps.logger },\n 'Fetching orgs with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n"],"names":["logErrorIfNeeded","DefaultPageNumber","DefaultPageSize","paginateArray","computeTotalCountFromGitHubToken","handleError"],"mappings":";;;;;;;;;;;;;AAiCA,eAAsB,aAAA,CACpB,yBAAA,EACA,QAAA,EACA,sBAAA,EACA;AACA,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAgC;AACnD,EAAA,MAAM,IAAA,GAAO,MAAM,yBAAA,CAA0B,sBAAA,CAAuB,QAAQ,CAAA;AAC5E,EAAA,KAAA,MAAW,YAAA,IAAgB,IAAA,IAAQ,EAAC,EAAG;AACrC,IAAA,IAAI,EACF,YAAA,CAAa,OAAA,IACb,aAAa,WAAA,EAAa,WAAA,OAAkB,cAAA,CAAA,EAC3C;AACD,MAAA;AAAA,IACF;AACA,IAAA,MAAM,MAAM,YAAA,CAAa,OAAA;AACzB,IAAA,IAAI,sBAAA,KAA2B,IAAI,KAAA,EAAO;AACxC,MAAA;AAAA,IACF;AACA,IAAA,MAAA,CAAO,GAAA,CAAI,IAAI,GAAA,EAAK;AAAA,MAClB,IAAI,GAAA,CAAI,EAAA;AAAA,MACR,WAAA,EAAa,IAAI,WAAA,IAAe,MAAA;AAAA,MAChC,MAAM,GAAA,CAAI,KAAA;AAAA,MACV,KAAK,GAAA,CAAI,QAAA;AAAA,MACT,UAAU,GAAA,CAAI,QAAA;AAAA,MACd,WAAW,GAAA,CAAI,SAAA;AAAA,MACf,YAAY,GAAA,CAAI;AAAA,KACjB,CAAA;AAAA,EACH;AACA,EAAA,OAAO,MAAA;AACT;AAEA,eAAsB,gBAAA,CACpB,IAAA,EAIA,OAAA,EACA,QAAA,EACA,MAAA,EAMkC;AAClC,EAAA,MAAM,yBAAyB,MAAA,CAAO,sBAAA;AACtC,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AACpB,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI;AACF,IAAA,MAAM,OAAO,MAAM,aAAA;AAAA,MACjB,IAAA,CAAK,yBAAA;AAAA,MACL,QAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,KAAA,MAAW,CAAC,MAAA,EAAQ,KAAK,CAAA,IAAK,IAAA,EAAM;AAClC,MAAA,IAAI,MAAA,IAAU,CAAC,KAAA,CAAM,IAAA,CAAK,WAAA,GAAc,QAAA,CAAS,MAAA,CAAO,WAAA,EAAa,CAAA,EAAG;AACtE,QAAA;AAAA,MACF;AACA,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,OAAA;AAAA,QAC5B,MAAA,CAAO,OAAA,CAAQ,SAAA,EAAW,QAAQ;AAAA,OACpC;AACA,MAAA,IAAA,CAAK,GAAA,CAAI,MAAM,IAAA,EAAM;AAAA,QACnB,GAAG,KAAA;AAAA,QACH,YAAA,EAAc,SAAS,IAAA,EAAM,YAAA;AAAA,QAC7B,mBAAA,EAAqB,SAAS,IAAA,EAAM,mBAAA;AAAA,QACpC,mBAAA,EAAqB,SAAS,IAAA,EAAM;AAAA,OACrC,CAAA;AACD,MAAA,UAAA,EAAA;AAAA,IACF;AAAA,EACF,SAAS,GAAA,EAAU;AACjB,IAAAA,6BAAA;AAAA,MACE,IAAA,CAAK,MAAA;AAAA,MACL,CAAA,uDAAA,CAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAA,CAAO,GAAA,CAAI,EAAA,EAAI,GAAA,CAAI,OAAO,CAAA;AAAA,EAC5B;AACA,EAAA,OAAO,EAAE,UAAA,EAAW;AACtB;AAEA,eAAsB,kBAAA,CACpB,IAAA,EAGA,OAAA,EACA,UAAA,EACA,MAAA,EAOkC;AAClC,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AACpB,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,EAAA,MAAM,UAAA,GAAa,OAAO,UAAA,IAAcC,0BAAA;AACxC,EAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAYC,wBAAA;AAEpC,EAAA,IAAI,UAAA;AACJ,EAAA,IAAI;AACF,IAAA,IAAI,YAAA;AACJ,IAAA,IAAI,MAAA,EAAQ;AAIV,MAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,QAAA;AAAA,QACzB,OAAA,CAAQ,KAAK,IAAA,CAAK,wBAAA;AAAA,QAClB;AAAA,UACE,IAAA,EAAM,WAAA;AAAA,UACN,SAAA,EAAW;AAAA;AACb,OACF;AACA,MAAA,MAAM,kBACJ,IAAA,EAAM,MAAA;AAAA,QAAO,CAAA,GAAA,KACX,IAAI,KAAA,CAAM,WAAA,GAAc,QAAA,CAAS,MAAA,CAAO,aAAa;AAAA,WAClD,EAAC;AACR,MAAA,MAAM,gBAAA,GAAmBC,wBAAA;AAAA,QACvB,eAAA;AAAA,QACA,UAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,YAAA,GAAe,gBAAA,CAAiB,MAAA;AAChC,MAAA,UAAA,GAAa,gBAAA,CAAiB,UAAA;AAAA,IAChC,CAAA,MAAO;AAML,MAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,IAAA,CAAK,KAAK,wBAAA,CAAyB;AAAA,QAC5D,IAAA,EAAM,UAAA;AAAA,QACN,QAAA,EAAU,QAAA;AAAA,QACV,IAAA,EAAM,WAAA;AAAA,QACN,SAAA,EAAW;AAAA,OACZ,CAAA;AACD,MAAA,YAAA,GAAe,IAAA,EAAM,QAAQ,EAAC;AAE9B,MAAA,UAAA,GAAa,MAAMC,sCAAA;AAAA,QACjB,IAAA;AAAA,QACA,OAAO,cAAA,KACL,OAAA,CAAQ,IAAA,CACL,wBAAA,CAAyB;AAAA,UACxB,IAAA,EAAM,cAAA;AAAA,UACN,QAAA,EAAU;AAAA,SACX,CAAA,CACA,IAAA,CAAK,CAAA,YAAA,KAAgB,YAAA,CAAa,KAAK,MAAM,CAAA;AAAA,QAClD,+BAAA;AAAA,QACA,MAAM,IAAA,EAAM,MAAA;AAAA,QACZ,MAAM,OAAA,EAAS;AAAA,OACjB;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,OAAO,YAAA,EAAc;AAC9B,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,OAAA,CAAQ,IAAI,GAAG,CAAA;AAC7C,MAAA,MAAM,KAAA,GAA4B;AAAA,QAChC,IAAI,GAAA,CAAI,EAAA;AAAA,QACR,MAAM,GAAA,CAAI,KAAA;AAAA,QACV,WAAA,EAAa,IAAI,WAAA,IAAe,KAAA,CAAA;AAAA,QAChC,GAAA,EAAK,OAAA,EAAS,IAAA,EAAM,QAAA,IAAY,GAAA,CAAI,GAAA;AAAA,QACpC,WAAW,GAAA,CAAI,SAAA;AAAA,QACf,WAAW,GAAA,CAAI,SAAA;AAAA,QACf,YAAY,GAAA,CAAI,UAAA;AAAA,QAChB,aAAa,GAAA,CAAI,WAAA;AAAA,QACjB,oBAAoB,GAAA,CAAI,kBAAA;AAAA,QACxB,YAAY,GAAA,CAAI,UAAA;AAAA,QAChB,YAAA,EAAc,SAAS,IAAA,EAAM,YAAA;AAAA,QAC7B,mBAAA,EAAqB,SAAS,IAAA,EAAM,mBAAA;AAAA,QACpC,mBAAA,EAAqB,SAAS,IAAA,EAAM;AAAA,OACtC;AACA,MAAA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,KAAA,EAAO,KAAK,CAAA;AAAA,IAC3B;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAAC,iBAAA;AAAA,MACE,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAO;AAAA,MACtB,qCAAA;AAAA,MACA,UAAA;AAAA,MACA,MAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,EAAE,UAAA,EAAW;AACtB;;;;;;"}
|
|
@@ -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 { 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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"}
|
|
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[] | 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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"}
|
|
@@ -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 { 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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"}
|
|
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> | 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> | 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiGA,IAAU,UAAA;AAAA,CAAV,CAAUA,WAAAA,KAAV;AACS,EAAMA,YAAA,IAAA,GAAO,MAAA;AACb,EAAMA,YAAA,kBAAA,GAAqB,iBAAA;AAC3B,EAAMA,YAAA,sBAAA,GAAyB,sBAAA;AAC/B,EAAMA,YAAA,qBAAA,GAAwB,qBAAA;AAE9B,EAAMA,YAAA,iCAAA,GACX,gCAAA;AAEK,EAAMA,YAAA,gBAAA,GAAmB,gBAAA;AACzB,EAAMA,YAAA,qBAAA,GAAwB,oBAAA;AAC9B,EAAMA,YAAA,sCAAA,GACX,oCAAA;AAEK,EAAMA,YAAA,kBAAA,GAAqB,kBAAA;AAC3B,EAAMA,YAAA,uBAAA,GAA0B,sBAAA;AAChC,EAAMA,YAAA,iCAAA,GACX,gCAAA;AAEK,EAAMA,YAAA,0BAAA,GAA6B,wBAAA;AACnC,EAAMA,YAAA,+BAAA,GAAkC,4BAAA;AACxC,EAAMA,YAAA,uCAAA,GACX,oCAAA;AAEK,EAAMA,YAAA,qBAAA,GAAwB,oBAAA;AAC9B,EAAMA,YAAA,0BAAA,GAA6B,wBAAA;AACnC,EAAMA,YAAA,kCAAA,GACX,gCAAA;AAAA,CAAA,EA3BM,UAAA,KAAA,UAAA,GAAA,EAAA,CAAA,CAAA;AA8BV,MAAM,oBAAA,GAAuB,IAAA;AAE7B,MAAM,kBAAkB,CAAC,CAAA,KACvB,OAAO,CAAA,KAAM,QAAA,IACb,MAAM,IAAA,IACN,MAAA,CAAO,OAAO,CAAC,CAAA,CAAE,MAAM,CAAA,GAAA,KAAO,OAAO,QAAQ,QAAA,IAAY,GAAA,CAAI,SAAS,CAAC,CAAA;AAEzE,SAAS,oBAAA,CACP,gBACA,MAAA,EACoC;AACpC,EAAA,IAAI,KAAA;AACJ,EAAA,IAAI,CAAC,gBAAgB,OAAO,MAAA;AAC5B,EAAA,IAAI,cAAA,CAAe,SAAS,oBAAA,EAAsB;AAChD,IAAA,MAAA,CAAO,KAAK,4DAA4D,CAAA;AACxE,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,KAAA,GAAQ,IAAA,CAAK,MAAM,cAAc,CAAA;AACjC,IAAA,IAAI,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACvE,MAAA,MAAM,IAAI,MAAM,oCAAoC,CAAA;AAAA,IACtD;AAAA,EACF,SAAS,CAAA,EAAG;AACV,IAAA,MAAM,IAAIC,iBAAA;AAAA,MACR,CAAA,6BAAA,EAAiC,EAAY,OAAO,CAAA;AAAA,KACtD;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,eAAA,CAAgB,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAIA,iBAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAMA,eAAsB,aACpB,OAAA,EACyB;AACzB,EAAA,MAAM;AAAA,IACJ,MAAA;AAAA,IACA,QAAA;AAAA,UACAC,MAAA;AAAA,IACA,WAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACF,GAAI,OAAA;AAEJ,EAAA,MAAM,IAAA,GAAO,MAAMC,iBAAA,CAAQ,QAAQ,CAAA;AACnC,EAAA,MAAMC,eAAA,GAAgB,IAAIC,2BAAA,CAAc,IAAA,EAAM,QAAQ,cAAc,CAAA;AACpE,EAAA,MAAM,OAAA,GAAU,IAAIC,+BAAA,CAAkB,IAAI,CAAA;AAC1C,EAAA,MAAM,gBAAA,GAAmB,IAAIC,8BAAA,CAAiB,IAAI,CAAA;AAClD,EAAA,MAAM,4BAA4B,IAAIF,2BAAA;AAAA,IACpC,IAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,uBAAA,GAA0B,IAAIG,qCAAA,CAAwB,IAAI,CAAA;AAGhE,EAAA,MAAMC,kBAAA,GAAmB,IAAIC,iCAAA,CAAiB,MAAA,EAAQ,QAAQ,KAAK,CAAA;AACnE,EAAA,MAAMC,kBAAA,GAAmB,IAAIC,iCAAA,CAAiB,MAAA,EAAQ,QAAQ,KAAK,CAAA;AACnE,EAAA,MAAMC,mBAAA,GAAoB,IAAIC,mCAAA,CAAkB;AAAA,IAC9C,MAAA;AAAA,IACA,MAAA;AAAA,UACAZ,MAAA;AAAA,IACA;AAAA,GACD,CAAA;AACD,EAAA,MAAMa,yBAAuB,IAAIC,yCAAA;AAAA,IAC/B,MAAA;AAAA,IACAH;AAAA,GACF;AAGA,EAAA,MAAM,GAAA,GAAM,IAAII,6BAAA,CAAe;AAAA,IAC7B,OAAA,EAAS;AAAA,MACP,OAAA,EAAS,IAAA;AAAA,MACT,OAAA,EAASC;AAAA;AAAA,KACX;AAAA,IACA,QAAA,EAAU,IAAA;AAAA,IACV,UAAA,EAAYC,+BAAA;AAAA,IACZ,QAAA,EAAU;AAAA,MACR,cAAA,EAAgB,OAAO,CAAA,EAAG,IAAA,EAAe,QACvC,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,KAAK,EAAE,GAAA,EAAK,CAAA,CAAE,UAAA,CAAW,QAAQ,CAAA;AAAA,MACnD,UAAU,OAAO,EAAA,EAAI,KAAc,GAAA,KACjC,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,GAAA,EAAK,IAAI,GAAA,CAAI,MAAM,IAAI,GAAA,CAAI,IAAI,eAAe,CAAA;AAAA,MACvE,gBAAgB,OAAO,EAAA,EAAI,KAAc,GAAA,KACvC,GAAA,CACG,OAAO,GAAG,CAAA,CACV,KAAK,EAAE,GAAA,EAAK,IAAI,GAAA,CAAI,MAAM,IAAI,GAAA,CAAI,IAAI,qBAAqB;AAAA;AAClE,GACD,CAAA;AAED,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,iBAAA,CAAkB,2BAA2B,CAAA;AACxE,EAAA,IAAI,gBAAA;AACJ,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,gBAAA,GAAmBC,2BAAqB,WAAW,CAAA;AAAA,EACrD;AAEA,EAAA,MAAM,yBAAyB,MAAA,CAAO,iBAAA;AAAA,IACpC;AAAA,GACF;AAEA,EAAA,MAAM,IAAI,IAAA,EAAK;AAEf,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,IAAA;AAAA,IACX,OAAO,EAAA,EAAa,IAAA,EAAe,GAAA,KAAkB;AACnD,MAAA,MAAM,MAAA,GAAS,MAAMC,SAAA,CAAK,MAAM,CAAA;AAChC,MAAA,OAAO,IAAI,MAAA,CAAO,MAAA,CAAO,UAAU,CAAA,CAAE,IAAA,CAAK,OAAO,YAAY,CAAA;AAAA,IAC/D;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,kBAAA;AAAA,IACX,OAAO,EAAA,EAAa,IAAA,EAAe,GAAA,KAAkB;AACnD,MAAA,MAAM,MAAA,GAAS,MAAMC,mBAAA,CAAgB,MAAM,CAAA;AAC3C,MAAA,OAAO,IAAI,MAAA,CAAO,MAAA,CAAO,UAAU,CAAA,CAAE,IAAA,CAAK,OAAO,YAAY,CAAA;AAAA,IAC/D;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,sBAAA;AAAA,IACX,OAAO,CAAA,EAAY,IAAA,EAAe,GAAA,KAAkB;AAClD,MAAA,MAAM,CAAA,GAAgD;AAAA,QACpD,GAAG,EAAE,OAAA,CAAQ;AAAA,OACf;AAEA,MAAA,CAAA,CAAE,kBAAA,GAAqB,cAAA,CAAe,CAAA,CAAE,kBAAkB,CAAA;AAC1D,MAAA,CAAA,CAAE,kBAAA,GAAqB,cAAA,CAAe,CAAA,CAAE,kBAAkB,CAAA;AAC1D,MAAA,MAAM,WAAW,MAAMC,kCAAA;AAAA,QACrB,MAAA;AAAA,QACA,CAAA,CAAE,YAAA,KAAiB,QAAA,GAAWZ,kBAAA,GAAmBF,kBAAA;AAAA,QACjD,CAAA,CAAE,MAAA;AAAA,QACF,CAAA,CAAE,kBAAA;AAAA,QACF,CAAA,CAAE;AAAA,OACJ;AACA,MAAA,OAAO,GAAA,CAAI,MAAA,CAAO,QAAA,CAAS,UAAU,EAAE,IAAA,CAAK;AAAA,QAC1C,MAAA,EAAQ,SAAS,YAAA,EAAc,MAAA;AAAA,QAC/B,aAAA,EAAe,SAAS,YAAA,EAAc,aAAA;AAAA,QACtC,UAAA,EAAY,SAAS,YAAA,EAAc,UAAA;AAAA,QACnC,kBAAA,EAAoB,SAAS,YAAA,EAAc,kBAAA;AAAA,QAC3C,kBAAA,EAAoB,SAAS,YAAA,EAAc,kBAAA;AAAA,QAC3C,cAAc,CAAA,CAAE;AAAA,OACsB,CAAA;AAAA,IAC1C;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,qBAAA;AAAA,IACX,OAAO,CAAA,EAAY,IAAA,EAAe,GAAA,KAAkB;AAClD,MAAA,MAAM,CAAA,GAA+C;AAAA,QACnD,GAAG,EAAE,OAAA,CAAQ;AAAA,OACf;AAEA,MAAA,CAAA,CAAE,kBAAA,GAAqB,cAAA,CAAe,CAAA,CAAE,kBAAkB,CAAA;AAC1D,MAAA,CAAA,CAAE,kBAAA,GAAqB,cAAA,CAAe,CAAA,CAAE,kBAAkB,CAAA;AAC1D,MAAA,CAAA,CAAE,iBAAA,GAAoB,eAAA,CAAgB,CAAA,CAAE,iBAAiB,CAAA;AAEzD,MAAA,MAAM,UAAA,GAAa,IAAI,MAAA,CAAO,SAAA;AAG9B,MAAA,IAAI,CAAC,UAAA,IAAc,MAAA,CAAO,KAAK,UAAU,CAAA,CAAE,WAAW,CAAA,EAAG;AACvD,QAAA,OAAO,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,UAC1B,KAAA,EACE;AAAA,SACH,CAAA;AAAA,MACH;AAEA,MAAA,MAAM,WAAW,MAAMe,gCAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,MAAA;AAAA,UACA,aAAA,EACE,CAAA,CAAE,YAAA,KAAiB,QAAA,GAAWb,kBAAA,GAAmBF,kBAAA;AAAA,6BACnDI;AAAA,SACF;AAAA,QACA;AAAA,UACE,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,aAAa,CAAA,CAAE,iBAAA;AAAA,UACf,YAAY,CAAA,CAAE,kBAAA;AAAA,UACd,UAAU,CAAA,CAAE,kBAAA;AAAA,UACZ;AAAA;AACF,OACF;AACA,MAAA,MAAM,KAAA,GAAQ,SAAS,YAAA,EAAc,YAAA;AACrC,MAAA,OAAO,GAAA,CAAI,MAAA,CAAO,QAAA,CAAS,UAAU,EAAE,IAAA,CAAK;AAAA,QAC1C,MAAA,EAAQ,SAAS,YAAA,EAAc,MAAA;AAAA,QAC/B,YAAA,EAAc,KAAA;AAAA,QACd,UAAA,EAAY,SAAS,YAAA,EAAc,UAAA;AAAA,QACnC,oBAAoB,CAAA,CAAE,kBAAA;AAAA,QACtB,oBAAoB,CAAA,CAAE,kBAAA;AAAA,QACtB,cAAc,CAAA,CAAE;AAAA,OACoB,CAAA;AAAA,IACxC;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,iCAAA;AAAA,IACX,OAAO,CAAA,EAAY,IAAA,EAAe,GAAA,KAAkB;AAClD,MAAA,MAAM,CAAA,GAA0D;AAAA,QAC9D,GAAG,EAAE,OAAA,CAAQ;AAAA,OACf;AAEA,MAAA,CAAA,CAAE,kBAAA,GAAqB,cAAA,CAAe,CAAA,CAAE,kBAAkB,CAAA;AAC1D,MAAA,CAAA,CAAE,kBAAA,GAAqB,cAAA,CAAe,CAAA,CAAE,kBAAkB,CAAA;AAC1D,MAAA,CAAA,CAAE,iBAAA,GAAoB,eAAA,CAAgB,CAAA,CAAE,iBAAiB,CAAA;AAEzD,MAAA,MAAM,UAAA,GAAa,IAAI,MAAA,CAAO,SAAA;AAG9B,MAAA,IAAI,CAAC,UAAA,IAAc,MAAA,CAAO,KAAK,UAAU,CAAA,CAAE,WAAW,CAAA,EAAG;AACvD,QAAA,OAAO,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,UAC1B,KAAA,EACE;AAAA,SACH,CAAA;AAAA,MACH;AAEA,MAAA,MAAM,WAAW,MAAMY,2CAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,MAAA;AAAA,UACA,aAAA,EACE,CAAA,CAAE,YAAA,KAAiB,QAAA,GAAWd,kBAAA,GAAmBF,kBAAA;AAAA,6BACnDI;AAAA,SACF;AAAA,QACA,CAAA,CAAE,OAAA,CAAQ,MAAA,CAAO,gBAAA,EAAkB,QAAA,EAAS;AAAA,QAC5C,CAAA,CAAE,MAAA;AAAA,QACF,CAAA,CAAE,iBAAA;AAAA,QACF,CAAA,CAAE,kBAAA;AAAA,QACF,CAAA,CAAE,kBAAA;AAAA,QACF;AAAA,OACF;AACA,MAAA,MAAM,KAAA,GAAQ,SAAS,YAAA,EAAc,YAAA;AACrC,MAAA,OAAO,GAAA,CAAI,MAAA,CAAO,QAAA,CAAS,UAAU,EAAE,IAAA,CAAK;AAAA,QAC1C,MAAA,EAAQ,SAAS,YAAA,EAAc,MAAA;AAAA,QAC/B,YAAA,EAAc,KAAA;AAAA,QACd,UAAA,EAAY,SAAS,YAAA,EAAc,UAAA;AAAA,QACnC,oBAAoB,CAAA,CAAE,kBAAA;AAAA,QACtB,oBAAoB,CAAA,CAAE,kBAAA;AAAA,QACtB,cAAc,CAAA,CAAE;AAAA,OACoB,CAAA;AAAA,IACxC;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,gBAAA;AAAA,IACX,OAAO,CAAA,EAAY,IAAA,EAAe,GAAA,KAAkB;AAClD,MAAA,MAAM;AAAA,QACJ,UAAA;AAAA,QACA,QAAA;AAAA,QACA,UAAA;AAAA,QACA,MAAA;AAAA,QACA,UAAA;AAAA,QACA;AAAA,OACF,GAAI,qBAAqB,CAAC,CAAA;AAC1B,MAAA,MAAM,WAAW,MAAMa,0BAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,MAAA;AAAA,4BACAjB,kBAAA;AAAA,4BACAE,kBAAA;AAAA,6BACAE;AAAA,SACF;AAAA,QACA;AAAA,UACE;AAAA,SACF;AAAA,QACA;AAAA,UACE,MAAA;AAAA,UACA,UAAA;AAAA,UACA,QAAA;AAAA,UACA,UAAA;AAAA,UACA;AAAA;AACF,OACF;AACA,MAAA,OAAO,IAAI,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,CAAE,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,IACnE;AAAA,GACF;AACA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,qBAAA;AAAA,IACX,OAAO,CAAA,EAAY,IAAA,EAAe,GAAA,KAAkB;AAClD,MAAA,MAAM,EAAE,YAAY,QAAA,EAAU,MAAA,EAAQ,YAAY,SAAA,EAAU,GAC1D,qBAAqB,CAAC,CAAA;AACxB,MAAA,MAAM,UAA0B,EAAC;AACjC,MAAA,MAAM,YAAA,GAAe,MAAMT,eAAA,CAAc,gBAAA;AAAA,QACvC,UAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,KAAA,MAAW,IAAA,IAAQ,aAAa,IAAA,EAAM;AACpC,QAAA,MAAM,WAAW,MAAMuB,sCAAA;AAAA,UACrB;AAAA,YACE,MAAA;AAAA,YACA,MAAA;AAAA,8BACAlB,kBAAA;AAAA,8BACAE,kBAAA;AAAA,+BACAE,mBAAA;AAAA,2BACAT,eAAA;AAAA,YACA,OAAA;AAAA,YACA,gBAAA;AAAA,YACA,SAAA;AAAA,kBACAF;AAAA,WACF;AAAA,UACA,IAAA,CAAK,GAAA;AAAA,UACL;AAAA,SACF;AACA,QAAA,IAAI,SAAS,YAAA,EAAc;AACzB,UAAA,OAAA,CAAQ,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,QACpC;AAAA,MACF;AAEA,MAAA0B,uBAAA,CAAY,OAAA,EAAS,YAAY,SAAS,CAAA;AAE1C,MAAA,MAAM,YAAA,GAAmD;AAAA,QACvD,OAAA;AAAA,QACA,YAAY,YAAA,CAAa,KAAA;AAAA,QACzB,MAAM,UAAA,IAAc,CAAA;AAAA,QACpB,MAAM,QAAA,IAAY;AAAA,OACpB;AAEA,MAAA,OAAO,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,KAAK,YAAY,CAAA;AAAA,IAC1C;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,sCAAA;AAAA,IACX,OAAO,CAAA,EAAY,GAAA,EAAc,GAAA,KAAkB;AACjD,MAAA,MAAM,EAAE,YAAY,QAAA,EAAU,MAAA,EAAQ,YAAY,SAAA,EAAU,GAC1D,qBAAqB,CAAC,CAAA;AACxB,MAAA,MAAM,UAA0B,EAAC;AACjC,MAAA,MAAM,YAAA,GAAe,MAAM,yBAAA,CAA0B,gBAAA;AAAA,QACnD,UAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,MAAM,KAAA,GAAQ,sBAAsB,GAAG,CAAA;AAEvC,MAAA,KAAA,MAAW,IAAA,IAAQ,aAAa,IAAA,EAAM;AACpC,QAAA,MAAM,WAAW,MAAMC,8CAAA;AAAA,UACrB;AAAA,YACE,MAAA;AAAA,YACA,yBAAA;AAAA,YACA,uBAAA;AAAA,YACA;AAAA,WACF;AAAA,UACA,IAAA,CAAK,GAAA;AAAA,UACL,KAAA;AAAA,UACA;AAAA,SACF;AACA,QAAA,IAAI,SAAS,YAAA,EAAc;AACzB,UAAA,OAAA,CAAQ,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,QACpC;AAAA,MACF;AAEA,MAAAD,uBAAA,CAAY,OAAA,EAAS,YAAY,SAAS,CAAA;AAE1C,MAAA,MAAM,YAAA,GAAmD;AAAA,QACvD,OAAA;AAAA,QACA,YAAY,YAAA,CAAa,KAAA;AAAA,QACzB,MAAM,UAAA,IAAc,CAAA;AAAA,QACpB,MAAM,QAAA,IAAY;AAAA,OACpB;AAEA,MAAA,OAAO,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,KAAK,YAAY,CAAA;AAAA,IAC1C;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,kBAAA;AAAA,IACX,OACE,CAAA,EACA,IAAA,EACA,GAAA,KACG;AACH,MAAA,MAAM,CAAA,GAA4C;AAAA,QAChD,GAAG,EAAE,OAAA,CAAQ;AAAA,OACf;AACA,MAAA,CAAA,CAAE,MAAA,GAAS,eAAA,CAAgB,CAAA,CAAE,MAAM,CAAA;AACnC,MAAA,MAAM,WAAW,MAAME,4BAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,MAAA;AAAA,gBACA5B,MAAA;AAAA,4BACAS,kBAAA;AAAA,4BACAF,kBAAA;AAAA,gCACAM,sBAAA;AAAA,6BACAF;AAAA,SACF;AAAA,QACA;AAAA,UACE,cAAA,EAAgB,EAAE,OAAA,CAAQ,WAAA;AAAA,UAC1B,QAAQ,CAAA,CAAE;AAAA;AACZ,OACF;AACA,MAAA,OAAO,IAAI,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,CAAE,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,IACnE;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,uBAAA;AAAA,IACX,OACE,CAAA,EACA,IAAA,EACA,GAAA,KACG;AACH,MAAA,IAAI,CAAC,gBAAA,EAAkB;AACrB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,0DAAA;AAAA,SACF;AAAA,MACF;AACA,MAAA,MAAM,WAAW,MAAMkB,oCAAA;AAAA,QACrB,gBAAA;AAAA,QACA,SAAA;AAAA,QACA,MAAA;AAAA,QACA7B,MAAA;AAAA,QACA,MAAA;AAAA,QACAE,eAAA;AAAA,QACA,OAAA;AAAA,QACA,gBAAA;AAAA,QACA,EAAE,OAAA,CAAQ,WAAA;AAAA,QACVK;AAAA,OACF;AAEA,MAAA,OAAO,IAAI,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,CAAE,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,IACnE;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,iCAAA;AAAA,IACX,OACE,CAAA,EACA,GAAA,EACA,GAAA,KACG;AACH,MAAA,IAAI,CAAC,sBAAA,EAAwB;AAC3B,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,gEAAA;AAAA,SACF;AAAA,MACF;AAEA,MAAA,MAAM,KAAA,GAAQ,sBAAsB,GAAG,CAAA;AAEvC,MAAA,MAAM,QAAA,GAAW,MAAMuB,oDAAA,CAAyB;AAAA,QAC9C,sBAAA;AAAA,QACA,SAAA;AAAA,QACA,KAAA;AAAA,QACA,WAAA,EAAa,EAAE,OAAA,CAAQ,WAAA;AAAA,QACvB,uBAAA;AAAA,QACA,yBAAA;AAAA,0BACAvB,kBAAA;AAAA,0BACAE;AAAA,OACD,CAAA;AAED,MAAA,GAAA,CAAI,OAAO,QAAA,CAAS,UAAU,CAAA,CAAE,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,IAC5D;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,+BAAA;AAAA,IACX,OAAO,CAAA,EAAY,IAAA,EAAe,GAAA,KAAkB;AAClD,MAAA,MAAM,CAAA,GAAkD;AAAA,QACtD,GAAG,EAAE,OAAA,CAAQ;AAAA,OACf;AACA,MAAA,IAAI,CAAC,CAAA,CAAE,IAAA,EAAM,IAAA,EAAK,EAAG;AACnB,QAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,MAC9C;AACA,MAAA,MAAM,WAAW,MAAMgB,sCAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,MAAA;AAAA,4BACAlB,kBAAA;AAAA,4BACAE,kBAAA;AAAA,6BACAE,mBAAA;AAAA,yBACAT,eAAA;AAAA,UACA,OAAA;AAAA,UACA,gBAAA;AAAA,UACA,SAAA;AAAA,gBACAF;AAAA,SACF;AAAA,QACA,CAAA,CAAE;AAAA,OACJ;AACA,MAAA,OAAO,IAAI,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,CAAE,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,IACnE;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,0BAAA;AAAA,IACX,OAAO,CAAA,EAAY,IAAA,EAAe,GAAA,KAAkB;AAClD,MAAA,MAAM,CAAA,GAAkD;AAAA,QACtD,GAAG,EAAE,OAAA,CAAQ;AAAA,OACf;AACA,MAAA,IAAI,CAAC,CAAA,CAAE,IAAA,EAAM,IAAA,EAAK,EAAG;AACnB,QAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,MAC9C;AACA,MAAA,MAAM,WAAW,MAAM+B,kCAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,MAAA;AAAA,UACA,aAAA,EACE,CAAA,CAAE,YAAA,KAAiB,QAAA,GAAWtB,kBAAA,GAAmBF,kBAAA;AAAA,6BACnDI,mBAAA;AAAA,UACA,cAAc,CAAA,CAAE;AAAA,SAClB;AAAA,QACA,CAAA,CAAE,IAAA;AAAA,QACF,CAAA,CAAE,aAAA;AAAA,QACF;AAAA,OACF;AACA,MAAA,OAAO,IAAI,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,CAAE,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,IACnE;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,uCAAA;AAAA,IACX,OAAO,CAAA,EAAY,GAAA,EAAc,GAAA,KAAkB;AACjD,MAAA,MAAM,CAAA,GAAkD;AAAA,QACtD,GAAG,EAAE,OAAA,CAAQ;AAAA,OACf;AACA,MAAA,IAAI,CAAC,CAAA,CAAE,IAAA,EAAM,IAAA,EAAK,EAAG;AACnB,QAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,MAC9C;AACA,MAAA,MAAM,KAAA,GAAQ,sBAAsB,GAAG,CAAA;AACvC,MAAA,MAAM,WAAW,MAAMgB,8CAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,yBAAA;AAAA,UACA,uBAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,CAAA,CAAE,IAAA;AAAA,QACF;AAAA,OACF;AACA,MAAA,OAAO,IAAI,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,CAAE,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,IACnE;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,0BAAA;AAAA,IACX,OAAO,CAAA,EAAY,IAAA,EAAe,GAAA,KAAkB;AAClD,MAAA,MAAM,CAAA,GAA8C;AAAA,QAClD,GAAG,EAAE,OAAA,CAAQ;AAAA,OACf;AACA,MAAA,IAAI,CAAC,CAAA,CAAE,IAAA,EAAM,IAAA,EAAK,EAAG;AACnB,QAAA,MAAM,IAAI,MAAM,mCAAmC,CAAA;AAAA,MACrD;AACA,MAAA,MAAM,WAAW,MAAMK,kCAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,GAAA,EAAK9B;AAAA,SACP;AAAA,QACA,CAAA,CAAE;AAAA,OACJ;AACA,MAAA,OAAO,IAAI,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,CAAE,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,IACnE;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,qBAAA;AAAA,IACX,OAAO,CAAA,EAAY,IAAA,EAAe,GAAA,KAAkB;AAClD,MAAA,MAAM,CAAA,GAA8C;AAAA,QAClD,GAAG,EAAE,OAAA,CAAQ;AAAA,OACf;AACA,MAAA,IAAI,CAAC,CAAA,CAAE,IAAA,EAAM,IAAA,EAAK,EAAG;AACnB,QAAA,MAAM,IAAI,MAAM,mCAAmC,CAAA;AAAA,MACrD;AACA,MAAA,MAAM,WAAW,MAAM+B,8BAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,MAAA;AAAA,UACA,eACEC,gCAAA,CAA2B,CAAA,CAAE,IAAI,CAAA,KAAM,WACnCzB,kBAAA,GACAF,kBAAA;AAAA,6BACNI;AAAA,SACF;AAAA,QACA,CAAA,CAAE,IAAA;AAAA,QACF,CAAA,CAAE;AAAA,OACJ;AACA,MAAA,OAAO,IAAI,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,CAAE,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,IACnE;AAAA,GACF;AAEA,EAAA,GAAA,CAAI,QAAA;AAAA,IACF,UAAA,CAAW,kCAAA;AAAA,IACX,OAAO,CAAA,EAAY,IAAA,EAAe,GAAA,KAAkB;AAClD,MAAA,MAAM,CAAA,GAA8C;AAAA,QAClD,GAAG,EAAE,OAAA,CAAQ;AAAA,OACf;AACA,MAAA,IAAI,CAAC,CAAA,CAAE,IAAA,EAAM,IAAA,EAAK,EAAG;AACnB,QAAA,MAAM,IAAI,MAAM,mCAAmC,CAAA;AAAA,MACrD;AACA,MAAA,MAAM,WAAW,MAAMqB,kCAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,GAAA,EAAK;AAAA,SACP;AAAA,QACA,CAAA,CAAE;AAAA,OACJ;AACA,MAAA,OAAO,IAAI,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,CAAE,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA,IACnE;AAAA,GACF;AAEA,EAAA,MAAM,SAASG,cAAA,EAAO;AACtB,EAAA,MAAA,CAAO,GAAA,CAAIC,wBAAA,CAAQ,IAAA,EAAM,CAAA;AAKzB,EAAA,MAAA,CAAO,GAAA,CAAI,CAAC,GAAA,EAAK,GAAA,EAAK,IAAA,KAAS;AAC7B,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,cAAc,CAAA;AACtC,IAAA,MAAM,SAAS,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GAAI,GAAA,CAAI,CAAC,CAAA,GAAI,GAAA;AAC7C,IAAA,OAAO,GAAA,CAAI,QAAQ,cAAc,CAAA;AACjC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,IAAI;AACF,QAAA,GAAA,CAAI,MAAA,CAAO,SAAA,GAAY,oBAAA,CAAqB,MAAA,EAAQ,MAAM,CAAA;AAAA,MAC5D,SAAS,CAAA,EAAG;AACV,QAAA,IAAA,CAAK,CAAC,CAAA;AACN,QAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAA,EAAK;AAAA,EACP,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,OAAO,GAAA,EAAK,IAAA,EAAM,IAAA,KAAS;AACpC,IAAA,IAAI,GAAA,CAAI,SAAS,OAAA,EAAS;AACxB,MAAA,IAAI;AACF,QAAA,MAAMC,oBAAA;AAAA,UACJ,OAAA;AAAA,UACA,GAAA,CAAI,cAAA,CAAe,GAAqB,CAAA,EAAG,WAAA;AAAA,UAC3C,WAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF,SAAS,CAAA,EAAG;AACV,QAAA,IAAA,CAAK,CAAC,CAAA;AACN,QAAA;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAA,EAAK;AAAA,EACP,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,OAAO,GAAA,EAAK,GAAA,EAAK,IAAA,KAAS;AACnC,IAAA,MAAM,OAAA,GAAU,GAAA;AAChB,IAAA,MAAM,WAAA,GAAc,GAAA,CAAI,cAAA,CAAe,OAAO,CAAA,EAAG,WAAA;AAEjD,IAAA,MAAM,eAAe,MAAM,+BAAA;AAAA,MACzB,WAAA;AAAA,MACA,GAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,IAAI;AACF,MAAA,MAAM,WAAY,MAAM,GAAA,CAAI,aAAA,CAAc,OAAA,EAAS,KAAK,GAAG,CAAA;AAC3D,MAAA,YAAA,EAAc,OAAA,CAAQ,EAAE,IAAA,EAAM,EAAE,gBAAgB,QAAA,CAAS,UAAA,IAAc,CAAA;AACvE,MAAA,IAAA,EAAK;AAAA,IACP,SAAS,GAAA,EAAU;AACjB,MAAA,YAAA,EAAc,IAAA,CAAK,EAAE,KAAA,EAAO,GAAA,EAAK,MAAM,EAAE,cAAA,EAAgB,GAAA,EAAI,EAAG,CAAA;AAChE,MAAA,IAAA,CAAK,GAAG,CAAA;AAAA,IACV;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM,aAAaC,gCAAA,CAAkB,MAAA,CAAO,EAAE,MAAA,EAAQ,QAAQ,CAAA;AAC9D,EAAA,MAAA,CAAO,GAAA,CAAI,UAAA,CAAW,KAAA,EAAO,CAAA;AAE7B,EAAA,OAAO,MAAA;AACT;AAEA,eAAe,+BAAA,CACb,WAAA,EACA,GAAA,EACA,OAAA,EAC0C;AAC1C,EAAA,IAAI,YAAA;AACJ,EAAA,QAAQ,WAAA;AAAa,IACnB,KAAK,UAAA,CAAW,IAAA;AACd,MAAA,YAAA,GAAe,MAAMC,6BAAA,CAAiB,OAAA,EAAS,MAAA,EAAQ,GAAG,CAAA;AAC1D,MAAA;AAAA,IACF,KAAK,UAAA,CAAW,kBAAA;AACd,MAAA,YAAA,GAAe,MAAMA,6BAAA,CAAiB,OAAA,EAAS,gBAAA,EAAkB,GAAG,CAAA;AACpE,MAAA;AAAA,IAEF,KAAK,UAAA,CAAW,sBAAA;AACd,MAAA,YAAA,GAAe,MAAMA,6BAAA,CAAiB,OAAA,EAAS,UAAA,EAAY,GAAA,EAAK;AAAA,QAC9D,SAAA,EAAW,GAAA,CAAI,KAAA,CAAM,MAAA,GAAS,UAAA,GAAa,KAAA;AAAA,QAC3C,MAAA,EAAQ,IAAI,KAAA,EAAO;AAAA,OACpB,CAAA;AACD,MAAA;AAAA,IACF,KAAK,UAAA,CAAW,qBAAA;AACd,MAAA,YAAA,GAAe,MAAMA,6BAAA,CAAiB,OAAA,EAAS,WAAA,EAAa,GAAA,EAAK;AAAA,QAC/D,SAAA,EAAW,GAAA,CAAI,KAAA,CAAM,MAAA,GAAS,UAAA,GAAa,KAAA;AAAA,QAC3C,MAAA,EAAQ,IAAI,KAAA,CAAM;AAAA,OACnB,CAAA;AACD,MAAA;AAAA,IACF,KAAK,WAAW,iCAAA,EAAmC;AACjD,MAAA,MAAM,gBAAA,GAAmB,GAAA,CAAI,MAAA,CAAO,gBAAA,EAAkB,QAAA,EAAS;AAC/D,MAAA,YAAA,GAAe,MAAMA,6BAAA,CAAiB,OAAA,EAAS,WAAA,EAAa,GAAA,EAAK;AAAA,QAC/D,SAAA,EAAW,QAAA;AAAA,QACX;AAAA,OACD,CAAA;AACD,MAAA;AAAA,IACF;AAAA,IACA,KAAK,UAAA,CAAW,gBAAA;AAAA,IAChB,KAAK,UAAA,CAAW,qBAAA;AAAA,IAChB,KAAK,UAAA,CAAW,sCAAA;AACd,MAAA,YAAA,GAAe,MAAMA,6BAAA,CAAiB,OAAA,EAAS,aAAA,EAAe,GAAA,EAAK;AAAA,QACjE,SAAA,EAAW,GAAA,CAAI,KAAA,CAAM,MAAA,GAAS,UAAA,GAAa,KAAA;AAAA,QAC3C,MAAA,EAAQ,IAAI,KAAA,CAAM;AAAA,OACnB,CAAA;AACD,MAAA;AAAA,IACF,KAAK,UAAA,CAAW,kBAAA;AAAA,IAChB,KAAK,UAAA,CAAW,uBAAA;AAAA,IAChB,KAAK,UAAA,CAAW,iCAAA;AACd,MAAA,YAAA,GAAe,MAAMA,6BAAA,CAAiB,OAAA,EAAS,cAAA,EAAgB,GAAA,EAAK;AAAA,QAClE,UAAA,EAAY;AAAA,OACb,CAAA;AACD,MAAA;AAAA,IACF,KAAK,UAAA,CAAW,0BAAA;AAAA,IAChB,KAAK,UAAA,CAAW,+BAAA;AAAA,IAChB,KAAK,UAAA,CAAW,uCAAA;AACd,MAAA,YAAA,GAAe,MAAMA,6BAAA;AAAA,QACnB,OAAA;AAAA,QACA,oBAAA;AAAA,QACA,GAAA;AAAA,QACA,EAAE,SAAA,EAAW,UAAA,EAAY,IAAA,EAAM,GAAA,CAAI,MAAM,IAAA;AAAK,OAChD;AACA,MAAA;AAAA,IACF,KAAK,UAAA,CAAW,qBAAA;AAAA,IAChB,KAAK,UAAA,CAAW,0BAAA;AAAA,IAChB,KAAK,UAAA,CAAW,kCAAA;AACd,MAAA,YAAA,GAAe,MAAMA,6BAAA,CAAiB,OAAA,EAAS,cAAA,EAAgB,GAAA,EAAK;AAAA,QAClE,UAAA,EAAY,QAAA;AAAA,QACZ,UAAA,EAAY,IAAI,KAAA,CAAM;AAAA,OACvB,CAAA;AACD,MAAA;AAAA,IACF,KAAK,MAAA;AACH,MAAA,YAAA,GAAe,MAAMA,6BAAA,CAAiB,OAAA,EAAS,WAAA,EAAa,GAAG,CAAA;AAC/D,MAAA;AAGA;AAEJ,EAAA,OAAO,YAAA;AACT;AAEA,SAAS,eAAe,CAAA,EAA2C;AACjE,EAAA,OAAO,IAAI,MAAA,CAAO,QAAA,CAAS,EAAE,QAAA,EAAS,EAAG,EAAE,CAAA,GAAI,MAAA;AACjD;AAEA,SAAS,gBAAgB,CAAA,EAA6C;AACpE,EAAA,IAAI,CAAC,CAAA,EAAG;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,CAAA,CAAE,UAAS,KAAM,MAAA;AAC1B;AACA,SAAS,qBAAqB,CAAA,EAO5B;AACA,EAAA,MAAM,CAAA,GAA2C;AAAA,IAC/C,GAAG,EAAE,OAAA,CAAQ;AAAA,GACf;AACA,EAAA,MAAM,UAAA,GAAa,EAAE,aAAa,CAAA;AAClC,EAAA,MAAM,CAAA,GAA0C;AAAA,IAC9C,GAAG,EAAE,OAAA,CAAQ;AAAA,GACf;AAEA,EAAA,IAAI,UAAA;AACJ,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI,UAAA,KAAe,MAAA,IAAa,UAAA,KAAe,IAAA,EAAM;AAEnD,IAAA,UAAA,GAAa,cAAA,CAAe,CAAA,CAAE,IAAA,IAAQ,CAAA,CAAE,kBAAkB,CAAA;AAC1D,IAAA,QAAA,GAAW,cAAA,CAAe,CAAA,CAAE,IAAA,IAAQ,CAAA,CAAE,kBAAkB,CAAA;AAAA,EAC1D,CAAA,MAAO;AAEL,IAAA,UAAA,GAAa,cAAA,CAAe,EAAE,IAAI,CAAA;AAClC,IAAA,QAAA,GAAW,cAAA,CAAe,EAAE,IAAI,CAAA;AAAA,EAClC;AACA,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,QAAQ,CAAA,CAAE,MAAA;AAAA,IACV,YAAY,CAAA,CAAE,UAAA;AAAA,IACd,WAAW,CAAA,CAAE;AAAA,GACf;AACF;AAEA,SAAS,sBAAsB,GAAA,EAA8B;AAC3D,EAAA,MAAM,SAAS,GAAA,CAAI,MAAA,CAAO,eAAe,CAAA,IAAK,IAAI,OAAA,CAAQ,aAAA;AAC1D,EAAA,IAAI,MAAA,EAAQ,UAAA,CAAW,CAAA,OAAA,CAAS,CAAA,EAAG;AACjC,IAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,SAAA,EAAW,EAAE,CAAA;AAAA,EACrC;AACA,EAAA,MAAM,IAAIxC,kBAAW,CAAA,8BAAA,CAAgC,CAAA;AACvD;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@red-hat-developer-hub/backstage-plugin-bulk-import-backend",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.1",
|
|
4
4
|
"main": "./dist/index.cjs.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"@gitbeaker/rest": "^43.4.0",
|
|
62
62
|
"@octokit/auth-app": "^7.2.2",
|
|
63
63
|
"@octokit/rest": "^20.0.2",
|
|
64
|
-
"@red-hat-developer-hub/backstage-plugin-bulk-import-common": "^8.0.
|
|
64
|
+
"@red-hat-developer-hub/backstage-plugin-bulk-import-common": "^8.0.1",
|
|
65
65
|
"@red-hat-developer-hub/backstage-plugin-orchestrator-common": "^3.7.3",
|
|
66
66
|
"ajv-formats": "^3.0.1",
|
|
67
67
|
"eventsource-client": "^1.2.0",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"@backstage/config": "^1.3.8",
|
|
81
81
|
"@backstage/plugin-catalog-backend": "^3.8.0",
|
|
82
82
|
"@backstage/types": "^1.2.2",
|
|
83
|
-
"@openapitools/openapi-generator-cli": "2.
|
|
83
|
+
"@openapitools/openapi-generator-cli": "2.40.1",
|
|
84
84
|
"@spotify/prettier-config": "^15.0.0",
|
|
85
85
|
"@types/express": "4.17.25",
|
|
86
86
|
"@types/git-url-parse": "^9.0.0",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"js-yaml-cli": "0.6.0",
|
|
90
90
|
"msw": "1.3.5",
|
|
91
91
|
"openapicmd": "2.9.2",
|
|
92
|
-
"prettier": "3.
|
|
92
|
+
"prettier": "3.9.6",
|
|
93
93
|
"supertest": "6.3.4"
|
|
94
94
|
},
|
|
95
95
|
"files": [
|