@red-hat-developer-hub/backstage-plugin-bulk-import-backend 7.2.0 → 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/README.md +41 -4
- package/dist/database/repositoryDao.cjs.js +6 -0
- package/dist/database/repositoryDao.cjs.js.map +1 -1
- package/dist/generated/openapidocument.cjs.js +89 -0
- package/dist/generated/openapidocument.cjs.js.map +1 -1
- package/dist/github/GithubAppManager.cjs.js +3 -0
- package/dist/github/GithubAppManager.cjs.js.map +1 -1
- package/dist/github/githubApiService.cjs.js +140 -144
- package/dist/github/githubApiService.cjs.js.map +1 -1
- package/dist/github/types.cjs.js.map +1 -1
- package/dist/github/utils/ghUtils.cjs.js +3 -3
- package/dist/github/utils/ghUtils.cjs.js.map +1 -1
- package/dist/github/utils/repoUtils.cjs.js +53 -99
- package/dist/github/utils/repoUtils.cjs.js.map +1 -1
- package/dist/gitlab/GitlabAppManager.cjs.js +2 -0
- package/dist/gitlab/GitlabAppManager.cjs.js.map +1 -1
- package/dist/gitlab/gitlabApiService.cjs.js +65 -8
- package/dist/gitlab/gitlabApiService.cjs.js.map +1 -1
- package/dist/gitlab/utils/glUtils.cjs.js +1 -1
- package/dist/gitlab/utils/glUtils.cjs.js.map +1 -1
- package/dist/gitlab/utils/repoUtils.cjs.js +32 -57
- package/dist/gitlab/utils/repoUtils.cjs.js.map +1 -1
- package/dist/service/handlers/import/bulkImports.cjs.js +14 -6
- package/dist/service/handlers/import/bulkImports.cjs.js.map +1 -1
- package/dist/service/handlers/import/importStatus.cjs.js.map +1 -1
- package/dist/service/handlers/organization/organizations.cjs.js +2 -2
- package/dist/service/handlers/organization/organizations.cjs.js.map +1 -1
- package/dist/service/handlers/repository/repositories.cjs.js +41 -6
- package/dist/service/handlers/repository/repositories.cjs.js.map +1 -1
- package/dist/service/handlers/scm/scm.cjs.js +16 -0
- package/dist/service/handlers/scm/scm.cjs.js.map +1 -0
- package/dist/service/router.cjs.js +81 -9
- package/dist/service/router.cjs.js.map +1 -1
- package/package.json +16 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repoUtils.cjs.js","sources":["../../../src/gitlab/utils/repoUtils.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 { Config } from '@backstage/config';\nimport type {\n GitlabCredentials,\n GitLabIntegrationConfig,\n ScmIntegrations,\n} from '@backstage/integration';\n\nimport {\n AllGroupProjectsOptions,\n BasePaginationRequestOptions,\n Gitlab,\n OffsetPaginationRequestOptions,\n ProjectSchema,\n ShowExpanded,\n Sudo,\n} from '@gitbeaker/rest';\nimport gitUrlParse from 'git-url-parse';\n\nimport { getBranchName } from '../../catalog/catalogUtils';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../../service/handlers/handlers';\nimport { CustomGitlabCredentialsProvider } from '../GitlabAppManager';\nimport type {\n ExtendedGitlabCredentials,\n GitlabFetchError,\n GitlabRepository,\n} from '../types';\nimport { computeTotalCountFromPaginationInfo, handleError } from './utils';\n\nexport type ValidatedRepo = {\n glConfig: GitLabIntegrationConfig;\n credentials: ExtendedGitlabCredentials[];\n owner: string;\n repo: string;\n branchName: string;\n};\n\nexport async function validateAndBuildRepoData(\n gitlabCredentialsProvider: CustomGitlabCredentialsProvider,\n integrations: ScmIntegrations,\n config: Config,\n input: {\n repoUrl: string;\n },\n): Promise<ValidatedRepo> {\n const glConfig = integrations.gitlab.byUrl(input.repoUrl)?.config;\n if (!glConfig) {\n throw new Error(`Could not find GL integration from ${input.repoUrl}`);\n }\n\n const gitUrl = gitUrlParse(input.repoUrl);\n const owner = gitUrl.organization;\n const repo = gitUrl.name;\n\n const credentials = await gitlabCredentialsProvider.getAllCredentials({\n host: glConfig.host,\n });\n if (credentials.length === 0) {\n throw new Error(`No credentials for GL integration`);\n }\n\n const branchName = getBranchName(config);\n return { glConfig, owner, repo, credentials, branchName };\n}\n\nexport async function searchRepos(\n gitlab: InstanceType<typeof Gitlab<false>>,\n glSearchQuery: string,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n): Promise<{ totalCount?: number; repositories: GitlabRepository[] }> {\n const repoSearchResp = await gitlab.Projects.all<true, 'offset'>({\n search: glSearchQuery,\n membership: true,\n perPage: pageSize,\n page: pageNumber,\n });\n\n return {\n totalCount: repoSearchResp?.paginationInfo?.total,\n repositories:\n repoSearchResp?.data?.map((repo: ProjectSchema) => {\n return {\n name: repo.name,\n full_name: repo.path_with_namespace,\n url: repo._links.self,\n html_url: repo.web_url,\n default_branch: repo.default_branch,\n updated_at: repo.updated_at,\n };\n }) ?? [],\n };\n}\n\n/**\n * Adds the user or organization repositories accessible by the github token to the provided repositories Map<string, GithubRepository> if they're owned by the specified owner\n * If any errors occurs, adds them to the provided errors Map<number, GithubFetchError>\n */\nexport async function addGitlabTokenRepositories(\n deps: {\n logger: LoggerService;\n },\n gitlab: InstanceType<typeof Gitlab<false>>,\n credential: GitlabCredentials,\n repositories: Map<string, GitlabRepository>,\n errors: Map<number, GitlabFetchError>,\n reqParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = reqParams?.search;\n const pageNumber = reqParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = reqParams?.pageSize ?? DefaultPageSize;\n let totalCount: number | undefined;\n try {\n if (search) {\n // Use the projects api with the search param\n // that api gives us all the things the token has access to including the different projects in various groups\n\n const searchResp = await searchRepos(\n gitlab,\n search,\n pageNumber,\n pageSize,\n );\n totalCount = searchResp.totalCount;\n searchResp.repositories.forEach(repo =>\n repositories.set(repo.full_name, repo),\n );\n } else {\n /**\n * The Projects.all method with the membership: true option will grab all the repositories/projects the gitlab 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 { data, paginationInfo } = await gitlab.Projects.all<\n true,\n 'offset'\n >({\n membership: true,\n perPage: pageSize,\n page: pageNumber,\n showExpanded: true,\n });\n\n data?.forEach((repo: ProjectSchema) => {\n repositories.set(repo.path_with_namespace, {\n name: repo.name,\n full_name: repo.path_with_namespace,\n url: repo._links.self,\n html_url: repo.web_url,\n default_branch: repo.default_branch,\n updated_at: repo?.updated_at,\n });\n });\n\n /*\n paginationInfo: {\n total: , This is the total amount of repos, but will be NaN if the value is above 10k, see: https://github.com/jdalrymple/gitbeaker/issues/839#issuecomment-636482319\n next: ,\n current: ,\n previous: ,\n perPage: ,\n totalPages:\n }\n */\n\n totalCount = await computeTotalCountFromPaginationInfo(\n deps,\n paginationInfo,\n pageSize, // Not thrilled with this for some reason\n );\n }\n } catch (err) {\n handleError(\n deps,\n 'Fetching repositories with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n\nexport async function addGitlabTokenOrgRepositories(\n deps: {\n logger: LoggerService;\n },\n gitlab: InstanceType<typeof Gitlab<false>>,\n credential: GitlabCredentials,\n org: string,\n repositories: Map<string, GitlabRepository>,\n errors: Map<number, GitlabFetchError>,\n reqParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = reqParams?.search;\n const pageNumber = reqParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = reqParams?.pageSize ?? DefaultPageSize;\n let totalCount: number | undefined;\n try {\n // For Search: Use the group allProjects api with the search param.\n // I noticed that using this api will only return values when 3 or more characters are used for the search\n // that api gives us all the things the token has access\n const params:\n | (AllGroupProjectsOptions &\n BasePaginationRequestOptions<'offset'> &\n OffsetPaginationRequestOptions &\n Sudo &\n ShowExpanded<true>)\n | undefined = {\n perPage: pageSize,\n search: search ?? undefined,\n page: pageNumber,\n showExpanded: true,\n };\n\n const { data, paginationInfo } = await gitlab.Groups.allProjects<\n true,\n 'offset'\n >(org, params);\n\n data?.forEach((repo: ProjectSchema) => {\n repositories.set(repo.path_with_namespace, {\n name: repo.name,\n full_name: repo.path_with_namespace,\n url: repo._links.self,\n html_url: repo.web_url,\n default_branch: repo.default_branch,\n updated_at: repo.updated_at,\n });\n });\n\n totalCount = await computeTotalCountFromPaginationInfo(\n deps,\n paginationInfo,\n pageSize, // Not thrilled with this for some reason\n );\n } catch (err) {\n handleError(\n deps,\n 'Fetching org repositories with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n\nexport async function fileExistsInDefaultBranch(\n logger: LoggerService,\n gitlab: InstanceType<typeof Gitlab<false>>,\n owner: string,\n repo: string,\n fileName: string,\n defaultBranch: string = 'main',\n) {\n try {\n await gitlab.RepositoryFiles.show(\n `${owner}/${repo}`,\n fileName,\n defaultBranch,\n );\n return true;\n } catch (error: any) {\n if (error.cause.response.status === 404) {\n return false;\n }\n logger.debug(\n `Unable to determine if a file named ${fileName} already exists in repo ${repo}: ${error}`,\n );\n return undefined;\n }\n}\n\nexport async function createOrUpdateFileInBranch(\n gitlab: InstanceType<typeof Gitlab<false>>,\n owner: string,\n repo: string,\n branchName: string,\n fileName: string,\n fileContent: string,\n): Promise<void> {\n try {\n const existingFile = await gitlab.RepositoryFiles.show(\n `${owner}/${repo}`,\n fileName,\n branchName,\n );\n // Response can either be a directory (array of files) or a single file element. In this case, we ensure it has the sha property to update it.\n if (Array.isArray(existingFile) || !('content_sha256' in existingFile)) {\n throw new Error(\n `The content at path ${fileName} is not a file or the response from gitlab does not contain the 'content_sha256' property.`,\n );\n }\n // If the file already exists, update it\n await gitlab.RepositoryFiles.edit(\n `${owner}/${repo}`,\n fileName,\n branchName,\n fileContent,\n `Add ${fileName} config file`,\n );\n } catch (error: any) {\n if (error.cause.response.status === 404) {\n // If the file does not exist, create it\n await gitlab.RepositoryFiles.create(\n `${owner}/${repo}`,\n fileName,\n branchName,\n fileContent,\n `Add ${fileName} config file`,\n );\n } else {\n throw error;\n }\n }\n}\n"],"names":["gitUrlParse","getBranchName","DefaultPageNumber","DefaultPageSize","computeTotalCountFromPaginationInfo","handleError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"repoUtils.cjs.js","sources":["../../../src/gitlab/utils/repoUtils.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 { Config } from '@backstage/config';\nimport type {\n GitlabCredentials,\n GitLabIntegrationConfig,\n ScmIntegrations,\n} from '@backstage/integration';\n\nimport {\n AllGroupProjectsOptions,\n BasePaginationRequestOptions,\n Gitlab,\n OffsetPaginationRequestOptions,\n ProjectSchema,\n ShowExpanded,\n Sudo,\n} from '@gitbeaker/rest';\nimport gitUrlParse from 'git-url-parse';\n\nimport { getBranchName } from '../../catalog/catalogUtils';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../../service/handlers/handlers';\nimport { CustomGitlabCredentialsProvider } from '../GitlabAppManager';\nimport type {\n ExtendedGitlabCredentials,\n GitlabFetchError,\n GitlabRepository,\n} from '../types';\nimport { computeTotalCountFromPaginationInfo, handleError } from './utils';\n\nexport type ValidatedRepo = {\n glConfig: GitLabIntegrationConfig;\n credentials: ExtendedGitlabCredentials[];\n owner: string;\n repo: string;\n branchName: string;\n};\n\nexport async function validateAndBuildRepoData(\n gitlabCredentialsProvider: CustomGitlabCredentialsProvider,\n integrations: ScmIntegrations,\n config: Config,\n input: {\n repoUrl: string;\n },\n): Promise<ValidatedRepo> {\n const glConfig = integrations.gitlab.byUrl(input.repoUrl)?.config;\n if (!glConfig) {\n throw new Error(`Could not find GL integration from ${input.repoUrl}`);\n }\n\n const gitUrl = gitUrlParse(input.repoUrl);\n const owner = gitUrl.organization;\n const repo = gitUrl.name;\n\n const credentials = await gitlabCredentialsProvider.getAllCredentials({\n host: glConfig.host,\n });\n if (credentials.length === 0) {\n throw new Error(`No credentials for GL integration`);\n }\n\n const branchName = getBranchName(config);\n return { glConfig, owner, repo, credentials, branchName };\n}\n\nexport async function searchRepos(\n gitlab: InstanceType<typeof Gitlab<false>>,\n glSearchQuery: string,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n): Promise<{ totalCount?: number; repositories: GitlabRepository[] }> {\n const repoSearchResp = await gitlab.Projects.all<true, 'offset'>({\n search: glSearchQuery,\n membership: true,\n perPage: pageSize,\n page: pageNumber,\n });\n\n return {\n totalCount: repoSearchResp?.paginationInfo?.total,\n repositories:\n repoSearchResp?.data?.map((repo: ProjectSchema) => {\n return {\n name: repo.name,\n full_name: repo.path_with_namespace,\n url: repo._links.self,\n html_url: repo.web_url,\n default_branch: repo.default_branch,\n updated_at: repo.updated_at,\n };\n }) ?? [],\n };\n}\n\n/**\n * Adds the user or organization repositories accessible by the github token to the provided repositories Map<string, GithubRepository> if they're owned by the specified owner\n * If any errors occurs, adds them to the provided errors Map<number, GithubFetchError>\n */\nexport async function addGitlabTokenRepositories(\n deps: {\n logger: LoggerService;\n },\n gitlab: InstanceType<typeof Gitlab<false>>,\n credential: GitlabCredentials,\n repositories: Map<string, GitlabRepository>,\n errors: Map<number, GitlabFetchError>,\n reqParams?: {\n search?: string;\n },\n): Promise<{ totalCount?: number }> {\n const lowercaseSearch = reqParams?.search?.toLocaleLowerCase();\n let totalCount: number | undefined;\n\n try {\n const allRepositories = await listAllRepositoriesForAuthenticatedUser(\n deps,\n gitlab,\n );\n const filteredRepositories = lowercaseSearch\n ? allRepositories.filter(repo =>\n repo.name.toLocaleLowerCase().includes(lowercaseSearch),\n )\n : allRepositories;\n\n filteredRepositories.forEach(repo => {\n repositories.set(repo.path_with_namespace, {\n name: repo.name,\n full_name: repo.path_with_namespace,\n url: repo._links.self,\n html_url: repo.web_url,\n default_branch: repo.default_branch,\n updated_at: repo?.updated_at,\n });\n });\n\n totalCount = filteredRepositories.length;\n } catch (err) {\n handleError(\n deps,\n 'Fetching repositories with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n\nexport async function addGitlabTokenOrgRepositories(\n deps: {\n logger: LoggerService;\n },\n gitlab: InstanceType<typeof Gitlab<false>>,\n credential: GitlabCredentials,\n org: string,\n repositories: Map<string, GitlabRepository>,\n errors: Map<number, GitlabFetchError>,\n reqParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = reqParams?.search;\n const pageNumber = reqParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = reqParams?.pageSize ?? DefaultPageSize;\n let totalCount: number | undefined;\n try {\n // For Search: Use the group allProjects api with the search param.\n // I noticed that using this api will only return values when 3 or more characters are used for the search\n // that api gives us all the things the token has access\n const params:\n | (AllGroupProjectsOptions &\n BasePaginationRequestOptions<'offset'> &\n OffsetPaginationRequestOptions &\n Sudo &\n ShowExpanded<true>)\n | undefined = {\n perPage: pageSize,\n search: search ?? undefined,\n page: pageNumber,\n showExpanded: true,\n };\n\n const { data, paginationInfo } = await gitlab.Groups.allProjects<\n true,\n 'offset'\n >(org, params);\n\n data?.forEach((repo: ProjectSchema) => {\n repositories.set(repo.path_with_namespace, {\n name: repo.name,\n full_name: repo.path_with_namespace,\n url: repo._links.self,\n html_url: repo.web_url,\n default_branch: repo.default_branch,\n updated_at: repo.updated_at,\n });\n });\n\n totalCount = await computeTotalCountFromPaginationInfo(\n deps,\n paginationInfo,\n pageSize, // Not thrilled with this for some reason\n );\n } catch (err) {\n handleError(\n deps,\n 'Fetching org repositories with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n\nexport async function fileExistsInDefaultBranch(\n logger: LoggerService,\n gitlab: InstanceType<typeof Gitlab<false>>,\n owner: string,\n repo: string,\n fileName: string,\n defaultBranch: string = 'main',\n) {\n try {\n await gitlab.RepositoryFiles.show(\n `${owner}/${repo}`,\n fileName,\n defaultBranch,\n );\n return true;\n } catch (error: any) {\n if (error.cause.response.status === 404) {\n return false;\n }\n logger.debug(\n `Unable to determine if a file named ${fileName} already exists in repo ${repo}: ${error}`,\n );\n return undefined;\n }\n}\n\nexport async function createOrUpdateFileInBranch(\n gitlab: InstanceType<typeof Gitlab<false>>,\n owner: string,\n repo: string,\n branchName: string,\n fileName: string,\n fileContent: string,\n): Promise<void> {\n try {\n const existingFile = await gitlab.RepositoryFiles.show(\n `${owner}/${repo}`,\n fileName,\n branchName,\n );\n // Response can either be a directory (array of files) or a single file element. In this case, we ensure it has the sha property to update it.\n if (Array.isArray(existingFile) || !('content_sha256' in existingFile)) {\n throw new Error(\n `The content at path ${fileName} is not a file or the response from gitlab does not contain the 'content_sha256' property.`,\n );\n }\n // If the file already exists, update it\n await gitlab.RepositoryFiles.edit(\n `${owner}/${repo}`,\n fileName,\n branchName,\n fileContent,\n `Add ${fileName} config file`,\n );\n } catch (error: any) {\n if (error.cause.response.status === 404) {\n // If the file does not exist, create it\n await gitlab.RepositoryFiles.create(\n `${owner}/${repo}`,\n fileName,\n branchName,\n fileContent,\n `Add ${fileName} config file`,\n );\n } else {\n throw error;\n }\n }\n}\n\nasync function listAllRepositoriesForAuthenticatedUser(\n deps: {\n logger: LoggerService;\n },\n gitlab: InstanceType<typeof Gitlab<false>>,\n): Promise<ProjectSchema[]> {\n try {\n /**\n * The Projects.all method with the membership: true option will grab all the repositories/projects the gitlab 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 allProjects = await gitlab.Projects.all<true, 'keyset'>({\n membership: true,\n showExpanded: true,\n orderBy: 'name',\n sort: 'asc',\n });\n\n return allProjects.data;\n } catch (error) {\n deps.logger.error(\n `Failed to list all repositories for authenticated user: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["gitUrlParse","getBranchName","handleError","DefaultPageNumber","DefaultPageSize","computeTotalCountFromPaginationInfo"],"mappings":"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"}
|
|
@@ -597,11 +597,13 @@ async function findTaskImportStatusByRepo(deps, repoUrl, skipTasks) {
|
|
|
597
597
|
const approvalTool = repository.approvalTool;
|
|
598
598
|
const pullRequest = await parsePullOrMergeRequestInfo(
|
|
599
599
|
data.state?.checkpoints,
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
600
|
+
{
|
|
601
|
+
githubApiService: deps.githubApiService,
|
|
602
|
+
gitlabApiService: deps.gitlabApiService,
|
|
603
|
+
approvalTool,
|
|
604
|
+
logger: deps.logger,
|
|
605
|
+
repoUrl
|
|
606
|
+
}
|
|
605
607
|
);
|
|
606
608
|
if (pullRequest && approvalTool === "GITLAB") {
|
|
607
609
|
result.gitlab = { pullRequest };
|
|
@@ -704,7 +706,13 @@ async function findOrchestratorImportStatusByRepo(deps, repoUrl, token, skipWork
|
|
|
704
706
|
responseBody: result
|
|
705
707
|
};
|
|
706
708
|
}
|
|
707
|
-
async function parsePullOrMergeRequestInfo(checkpoints,
|
|
709
|
+
async function parsePullOrMergeRequestInfo(checkpoints, {
|
|
710
|
+
githubApiService,
|
|
711
|
+
gitlabApiService,
|
|
712
|
+
approvalTool,
|
|
713
|
+
logger,
|
|
714
|
+
repoUrl
|
|
715
|
+
}) {
|
|
708
716
|
if (approvalTool !== "GITLAB" && approvalTool !== "GIT") {
|
|
709
717
|
return void 0;
|
|
710
718
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bulkImports.cjs.js","sources":["../../../../src/service/handlers/import/bulkImports.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n AuthService,\n DiscoveryService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { CatalogApi } from '@backstage/catalog-client';\nimport type { Config } from '@backstage/config';\nimport { NotFoundError } from '@backstage/errors';\n\nimport gitUrlParse from 'git-url-parse';\n\nimport {\n Configuration,\n DefaultApi,\n} from '@red-hat-developer-hub/backstage-plugin-orchestrator-common';\n\nimport { CatalogHttpClient } from '../../../catalog/catalogHttpClient';\nimport type { CatalogInfoGenerator } from '../../../catalog/catalogInfoGenerator';\nimport {\n getCatalogFilename,\n getCatalogUrl,\n} from '../../../catalog/catalogUtils';\nimport {\n OrchestratorWorkflow,\n OrchestratorWorkflowDao,\n RepositoryDao,\n RepositoryName,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../../../database/repositoryDao';\nimport type { Components, Paths } from '../../../generated/openapi';\nimport type { GithubApiService } from '../../../github';\nimport { GitlabApiService } from '../../../gitlab';\nimport {\n getNestedValue,\n logErrorIfNeeded,\n paginateArray,\n parseGitURLForApprovalTool,\n} from '../../../helpers';\nimport {\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: GithubApiService | GitlabApiService,\n logger: LoggerService,\n req: Components.Schemas.ImportRequest,\n gitUrl: gitUrlParse.GitUrl,\n catalogInfoGenerator: CatalogInfoGenerator,\n config: Config,\n) {\n const appTitle =\n config.getOptionalString('app.title') ?? 'Red Hat Developer Hub';\n const appBaseUrl = config.getString('app.baseUrl');\n const catalogFileName = getCatalogFilename(config);\n return await gitApiService.submitPrToRepo(logger, {\n repoUrl: req.repository.url,\n gitUrl: gitUrl,\n defaultBranch: req.repository.defaultBranch,\n catalogInfoContent:\n req.catalogInfoContent ??\n (await catalogInfoGenerator.generateDefaultCatalogInfoContent(\n req.repository.url,\n )),\n prTitle:\n req[req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']?.pullRequest\n ?.title ?? `Add ${catalogFileName}`,\n prBody:\n req[req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']?.pullRequest\n ?.body ??\n `\nThis pull request adds a **Backstage entity metadata file** to this repository so that the component can be added to a Backstage application.\n\nAfter this pull request is merged, the component will become available in the [${appTitle} software catalog](${appBaseUrl}).\n\nFor more information, read an [overview of the Backstage software catalog](https://backstage.io/docs/features/software-catalog/).\n`,\n });\n}\n\nasync function handleAddedReposFromCreateImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n importRequests: Components.Schemas.ImportRequest[],\n) {\n const result: Components.Schemas.Import[] = [];\n\n for (const req of importRequests) {\n // Check if repo is already imported\n const repoCatalogUrl = getCatalogUrl(\n deps.config,\n req.repository.url,\n req.repository.defaultBranch,\n );\n const hasLocation =\n await deps.catalogHttpClient.verifyLocationExistence(repoCatalogUrl);\n if (!hasLocation) {\n continue;\n }\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const hasCatalogInfoFileInRepo = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: getCatalogFilename(deps.config),\n });\n if (!hasCatalogInfoFileInRepo) {\n continue;\n }\n\n const ghRepo = await gitApiService.getRepositoryFromIntegrations(\n req.repository.url,\n );\n\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n req.repository.url,\n req.repository.defaultBranch,\n );\n\n const gitUrl = gitUrlParse(req.repository.url);\n result.push({\n status: 'ADDED',\n lastUpdate: ghRepo?.repository?.updated_at ?? undefined,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n });\n }\n return result;\n}\n\nasync function handlePrCreationRequest(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n req: Components.Schemas.ImportRequest,\n gitUrl: gitUrlParse.GitUrl,\n): Promise<Components.Schemas.Import> {\n const repoCatalogUrl = getCatalogUrl(\n deps.config,\n req.repository.url,\n req.repository.defaultBranch,\n );\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const prToRepo = await createPR(\n gitApiService,\n deps.logger,\n req,\n gitUrl,\n deps.catalogInfoGenerator,\n deps.config,\n );\n if (prToRepo.errors && prToRepo.errors.length > 0) {\n return {\n errors: prToRepo.errors,\n status: 'PR_ERROR',\n repository: req.repository,\n };\n }\n if (prToRepo.prUrl) {\n deps.logger.debug(`Created new PR from request: ${prToRepo.prUrl}`);\n }\n\n // Create Location\n await deps.catalogHttpClient.possiblyCreateLocation(repoCatalogUrl);\n\n if (prToRepo.hasChanges === false) {\n deps.logger.debug(\n `No bulk import PR created on ${req.repository.url} since its default branch (${req.repository.defaultBranch}) already contains a catalog-info file`,\n );\n\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n req.repository.url,\n req.repository.defaultBranch,\n );\n return {\n status: 'ADDED',\n lastUpdate: prToRepo.lastUpdate,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n };\n }\n\n return {\n approvalTool: req.approvalTool ?? 'GIT',\n errors: prToRepo.errors,\n status: 'WAIT_PR_APPROVAL',\n lastUpdate: prToRepo.lastUpdate,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n [req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']: {\n pullRequest: {\n url: prToRepo.prUrl,\n number: prToRepo.prNumber,\n },\n },\n };\n}\n\nexport async function createImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n reqParams: {\n importRequests: Paths.CreateImportJobs.RequestBody;\n dryRun?: boolean;\n },\n): Promise<HandlerResponse<Components.Schemas.Import[]>> {\n const dryRun = reqParams.dryRun ?? false;\n const importRequests = reqParams.importRequests;\n deps.logger.debug(\n `Handling request to import ${importRequests?.length} repo(s) (dryRun=${dryRun})..`,\n );\n\n if (importRequests.length === 0) {\n deps.logger.debug('Missing import requests from request body');\n return {\n statusCode: 400,\n responseBody: [],\n };\n }\n\n if (dryRun) {\n return {\n statusCode: 202,\n responseBody: await dryRunCreateImportJobs(deps, importRequests),\n };\n }\n\n const result: Components.Schemas.Import[] = [];\n\n const addedRepos = await handleAddedReposFromCreateImportJobs(\n deps,\n importRequests,\n );\n result.push(...addedRepos);\n const addedReposMap = new Map(\n addedRepos.map(res => [res.repository?.url, res]),\n );\n const remainingRequests = importRequests.filter(\n req => !addedReposMap.has(req.repository.url),\n );\n\n for (const req of remainingRequests) {\n const gitUrl = gitUrlParse(req.repository.url);\n\n // Create PR\n try {\n result.push(await handlePrCreationRequest(deps, req, gitUrl));\n } catch (error: any) {\n result.push({\n errors: [error.message],\n status: 'PR_ERROR',\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n } as Components.Schemas.Import);\n }\n }\n\n sortImports(result);\n\n return {\n statusCode: 202,\n responseBody: result,\n };\n}\n\nasync function dryRunCreateImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n importRequests: Paths.CreateImportJobs.RequestBody,\n) {\n const result: Components.Schemas.Import[] = [];\n for (const req of importRequests) {\n const gitUrl = gitUrlParse(req.repository.url);\n\n const dryRunChecks = await performDryRunChecks(deps, req);\n if (dryRunChecks.errors?.length > 0) {\n deps.logger.warn(\n `Errors while performing dry-run checks: ${dryRunChecks.errors}`,\n );\n }\n result.push({\n errors: dryRunChecks.dryRunStatuses,\n catalogEntityName: req.catalogEntityName,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n });\n }\n return result;\n}\n\nasync function performDryRunChecks(\n deps: {\n logger: LoggerService;\n auth: AuthService;\n catalogApi: CatalogApi;\n config: Config;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n req: Components.Schemas.ImportRequest,\n): Promise<{ dryRunStatuses: CreateImportDryRunStatus[]; errors: string[] }> {\n const checkCatalog = async (\n catalogEntityName: string,\n ): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const hasEntity =\n await deps.catalogHttpClient.hasEntityInCatalog(catalogEntityName);\n if (hasEntity) {\n return { dryRunStatuses: ['CATALOG_ENTITY_CONFLICT'] };\n }\n return {};\n };\n\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const checkEmptyRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const empty = await gitApiService.isRepoEmpty({\n repoUrl: req.repository.url,\n });\n if (empty) {\n return {\n dryRunStatuses: ['REPO_EMPTY'],\n };\n }\n return {};\n };\n\n const checkCatalogInfoPresenceInRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const exists = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: getCatalogFilename(deps.config),\n });\n if (exists) {\n return {\n dryRunStatuses: ['CATALOG_INFO_FILE_EXISTS_IN_REPO'],\n };\n }\n return {};\n };\n\n const checkCodeOwnersFileInRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const gitDirLocation =\n req.approvalTool === 'GITLAB' ? '.gitlab' : '.github';\n const exists = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: `${gitDirLocation}/CODEOWNERS`,\n });\n if (!exists) {\n return {\n dryRunStatuses: ['CODEOWNERS_FILE_NOT_FOUND_IN_REPO'],\n };\n }\n return {};\n };\n\n const dryRunStatuses: CreateImportDryRunStatus[] = [];\n const errors: string[] = [];\n const allChecksFn = [checkEmptyRepo(), checkCatalogInfoPresenceInRepo()];\n if (req.catalogEntityName?.trim()) {\n allChecksFn.push(checkCatalog(req.catalogEntityName));\n }\n if (req.codeOwnersFileAsEntityOwner) {\n allChecksFn.push(checkCodeOwnersFileInRepo());\n }\n const allChecks = await Promise.all(allChecksFn);\n allChecks.flat().forEach(res => {\n if (res.dryRunStatuses) {\n dryRunStatuses.push(...res.dryRunStatuses);\n }\n if (res.errors) {\n errors.push(...res.errors);\n }\n });\n\n dryRunStatuses.sort((a, b) => a.localeCompare(b));\n\n return {\n dryRunStatuses,\n errors,\n };\n}\n\nexport async function findImportStatusByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitlabApiService | GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n approvalTool: string | undefined;\n },\n repoUrl: string,\n defaultBranch?: string,\n includeCatalogInfoContent?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(`Getting bulk import job status for ${repoUrl}..`);\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n defaultBranch,\n },\n approvalTool: deps.approvalTool,\n status: null,\n } as Components.Schemas.Import;\n try {\n // Check to see if there are any PR\n const openImportPr = await deps.gitApiService.findImportOpenPr(\n deps.logger,\n {\n repoUrl: repoUrl,\n includeCatalogInfoContent,\n },\n );\n\n if (!openImportPr?.prUrl) {\n const catalogLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations()\n ).uniqueCatalogUrlLocations.keys();\n\n const catalogUrl = getCatalogUrl(deps.config, repoUrl, defaultBranch);\n let exists = false;\n for (const loc of catalogLocations) {\n if (loc === catalogUrl) {\n exists = true;\n break;\n }\n }\n if (\n exists &&\n (await deps.gitApiService.hasFileInRepo({\n repoUrl,\n defaultBranch,\n fileName: getCatalogFilename(deps.config),\n }))\n ) {\n result.status = 'ADDED';\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n repoUrl,\n defaultBranch,\n );\n }\n // No import PR => let's determine last update from the repository\n const ghRepo =\n await deps.gitApiService.getRepositoryFromIntegrations(repoUrl);\n result.lastUpdate = ghRepo.repository?.updated_at ?? undefined;\n return {\n statusCode: 200,\n responseBody: result,\n };\n }\n result.status = 'WAIT_PR_APPROVAL';\n result[deps.approvalTool === 'GITLAB' ? 'gitlab' : 'github'] = {\n pullRequest: {\n number: openImportPr.prNum,\n url: openImportPr.prUrl,\n title: openImportPr.prTitle,\n body: openImportPr.prBody,\n catalogInfoContent: openImportPr.prCatalogInfoContent,\n },\n };\n\n result.lastUpdate = openImportPr.lastUpdate;\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n if (error.message?.includes('Not Found')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n result.status = 'PR_ERROR';\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nexport async function findTaskImportStatusByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n githubApiService: GithubApiService;\n gitlabApiService: GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n repositoryDao: RepositoryDao<'repositories'>;\n taskDao: ScaffolderTaskDao;\n taskLocationsDao: TaskLocationsDao;\n discovery: DiscoveryService;\n auth: AuthService;\n },\n repoUrl: string,\n skipTasks?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(`Getting bulk import job status for ${repoUrl}.`);\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result: Components.Schemas.Import = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n },\n };\n try {\n const repository = await deps.repositoryDao.findRepositoryByUrl(repoUrl);\n if (!repository) {\n throw new NotFoundError(`Repository ${repoUrl} info was not found`);\n }\n\n const task = await deps.taskDao.lastExecutedTaskByRepoId(repository?.id);\n if (!task) {\n throw new NotFoundError(\n `Unable to find scaffolder task for repository: ${repository?.id}`,\n );\n }\n\n const scaffolderUrl = await deps.discovery.getBaseUrl('scaffolder');\n const { token } = await deps.auth.getPluginRequestToken({\n onBehalfOf: await deps.auth.getOwnServiceCredentials(),\n targetPluginId: 'scaffolder',\n });\n\n const response = await fetch(`${scaffolderUrl}/v2/tasks/${task.taskId}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n if (!skipTasks) {\n const tasks = await deps.taskDao.findTasksByRepositoryId(repository.id);\n const tasksWithLocations = await Promise.all(\n tasks.map(async taskItem => {\n const locations = await deps.taskLocationsDao.findLocationsByTaskId(\n taskItem.taskId,\n );\n const taskLocations = locations.map(location => location.location);\n return {\n ...taskItem,\n locations: taskLocations,\n };\n }),\n );\n result.tasks = tasksWithLocations;\n }\n\n result.task = { taskId: task.taskId };\n let data;\n if (response.ok) {\n data = await response.json();\n result.lastUpdate = data.lastHeartbeatAt;\n\n const approvalTool =\n repository.approvalTool as unknown as Components.Schemas.ApprovalTool;\n const pullRequest = await parsePullOrMergeRequestInfo(\n data.state?.checkpoints,\n deps.gitlabApiService,\n deps.githubApiService,\n approvalTool,\n deps.logger,\n repoUrl,\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 githubApiService: GitlabApiService,\n gitlabApiService: GithubApiService,\n approvalTool: Components.Schemas.ApprovalTool,\n logger: LoggerService,\n repoUrl: string,\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: GithubApiService | GitlabApiService;\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 { CatalogApi } from '@backstage/catalog-client';\nimport type { Config } from '@backstage/config';\nimport { NotFoundError } from '@backstage/errors';\n\nimport gitUrlParse from 'git-url-parse';\n\nimport {\n Configuration,\n DefaultApi,\n} from '@red-hat-developer-hub/backstage-plugin-orchestrator-common';\n\nimport { CatalogHttpClient } from '../../../catalog/catalogHttpClient';\nimport type { CatalogInfoGenerator } from '../../../catalog/catalogInfoGenerator';\nimport {\n getCatalogFilename,\n getCatalogUrl,\n} from '../../../catalog/catalogUtils';\nimport {\n OrchestratorWorkflow,\n OrchestratorWorkflowDao,\n RepositoryDao,\n RepositoryName,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../../../database/repositoryDao';\nimport type { Components, Paths } from '../../../generated/openapi';\nimport type { GithubApiService } from '../../../github';\nimport { GitlabApiService } from '../../../gitlab';\nimport {\n getNestedValue,\n logErrorIfNeeded,\n paginateArray,\n parseGitURLForApprovalTool,\n} from '../../../helpers';\nimport { GitApiService } from '../../../scm/GitApiService';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n DefaultSortColumn,\n DefaultSortOrder,\n type HandlerResponse,\n} from '../handlers';\n\ntype CreateImportDryRunStatus =\n | 'CATALOG_ENTITY_CONFLICT'\n | 'CATALOG_INFO_FILE_EXISTS_IN_REPO'\n | 'CODEOWNERS_FILE_NOT_FOUND_IN_REPO'\n | 'REPO_EMPTY';\n\ntype FindAllImportsResponse =\n | Components.Schemas.Import[]\n | Components.Schemas.ImportJobListV2;\n\nexport function sortImports(\n imports: Components.Schemas.Import[],\n sortColumn: Components.Parameters.SortColumnQueryParam = DefaultSortColumn,\n sortOrder: Components.Parameters.SortOrderQueryParam = DefaultSortOrder,\n) {\n imports.sort((a, b) => {\n const value1 = getNestedValue(a, sortColumn);\n const value2 = getNestedValue(b, sortColumn);\n // Handle cases where values are undefined\n if (value1 === undefined && value2 === undefined) return 0;\n if (value1 === undefined) return sortOrder === 'asc' ? -1 : 1;\n if (value2 === undefined) return sortOrder === 'asc' ? 1 : -1;\n\n if (sortColumn === 'lastUpdate') {\n const date1 = new Date(value1); // Convert string to Date object\n const date2 = new Date(value2); // Convert string to Date object\n // Compare dates\n return sortOrder === 'asc'\n ? date2.getTime() - date1.getTime()\n : date1.getTime() - date2.getTime();\n }\n // Compare values based on sort order\n return sortOrder === 'asc'\n ? value1.localeCompare(value2)\n : value2.localeCompare(value1);\n });\n}\n\nexport async function findAllImports(\n deps: {\n logger: LoggerService;\n config: Config;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n requestHeaders?: {\n apiVersion?: Paths.FindAllImports.Parameters.ApiVersion;\n },\n queryParams?: {\n search?: string;\n pageNumber?: number;\n pageSize?: number;\n sortColumn?: Components.Parameters.SortColumnQueryParam;\n sortOrder?: Components.Parameters.SortOrderQueryParam;\n },\n): Promise<HandlerResponse<FindAllImportsResponse>> {\n const apiVersion = requestHeaders?.apiVersion ?? 'v1';\n const search = queryParams?.search;\n const pageNumber = queryParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = queryParams?.pageSize ?? DefaultPageSize;\n const sortColumn = queryParams?.sortColumn ?? DefaultSortColumn;\n const sortOrder = queryParams?.sortOrder ?? DefaultSortOrder;\n\n const catalogFilename = getCatalogFilename(deps.config);\n\n const allLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations(\n search,\n pageNumber,\n pageSize,\n )\n ).uniqueCatalogUrlLocations;\n\n // resolve default branches for each unique repo URL from GH,\n // because we cannot easily determine that from the location target URL.\n // It can be 'main' or something more convoluted like 'our/awesome/main'.\n const defaultBranchByRepoUrl = await resolveReposDefaultBranches(\n deps.logger,\n deps.gitlabApiService,\n deps.githubApiService,\n allLocations.keys(),\n catalogFilename,\n );\n\n // filter out locations that do not match what we are expecting, i.e.:\n // an URL to a catalog-info YAML file at the root of the repo\n const importCandidates = findImportCandidates(\n allLocations.keys(),\n defaultBranchByRepoUrl,\n catalogFilename,\n );\n\n // Keep only repos that are accessible from the configured GH/GL integrations\n const importsReachableFromGHIntegrations =\n await deps.githubApiService.filterLocationsAccessibleFromIntegrations(\n importCandidates.filter(val => {\n return parseGitURLForApprovalTool(val) === 'GIT';\n }),\n );\n\n const importsReachableFromGLIntegrations =\n await deps.gitlabApiService.filterLocationsAccessibleFromIntegrations(\n importCandidates.filter(val => {\n return parseGitURLForApprovalTool(val) === 'GITLAB';\n }),\n );\n\n // Merge the two lists together and map the appropriate approvalTool\n const mergedReachbleFromIntegrations = importsReachableFromGHIntegrations\n .map(val => {\n return {\n loc: val,\n approvalTool: 'GIT',\n };\n })\n .concat(\n importsReachableFromGLIntegrations.map(val => {\n return {\n loc: val,\n approvalTool: 'GITLAB',\n };\n }),\n );\n\n const repoUrlToLocation = new Map<string, string>();\n\n // now fetch the import statuses in different promises\n const importStatusPromises: Promise<\n HandlerResponse<Components.Schemas.Import>\n >[] = [];\n for (const imports of mergedReachbleFromIntegrations) {\n const repoUrl = repoUrlFromLocation(imports.loc);\n if (!repoUrl) {\n continue;\n }\n repoUrlToLocation.set(repoUrl, imports.loc);\n\n importStatusPromises.push(\n findImportStatusByRepo(\n {\n logger: deps.logger,\n config: deps.config,\n gitApiService:\n imports.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService,\n catalogHttpClient: deps.catalogHttpClient,\n approvalTool: imports.approvalTool,\n },\n repoUrl,\n defaultBranchByRepoUrl.get(repoUrl),\n false,\n ),\n );\n }\n\n const result = await Promise.all(importStatusPromises);\n const imports = result\n .filter(res => res.responseBody)\n .map(res => res.responseBody!)\n .map(res => {\n const key = res?.repository?.url;\n const location = key ? repoUrlToLocation.get(key) : undefined;\n return {\n ...res,\n source: location ? allLocations.get(location)?.source : undefined,\n };\n });\n\n // sorting the output to make it deterministic and easy to navigate in the UI\n\n sortImports(imports, sortColumn, sortOrder);\n const paginated = paginateArray(imports, pageNumber, pageSize);\n if (apiVersion === 'v1') {\n return {\n statusCode: 200,\n responseBody: paginated.result,\n };\n }\n return {\n statusCode: 200,\n responseBody: {\n imports: paginated.result,\n totalCount: paginated.totalCount,\n page: pageNumber,\n size: pageSize,\n },\n };\n}\n\nasync function resolveReposDefaultBranches(\n logger: LoggerService,\n gitlabApiService: GitlabApiService,\n githubApiService: GithubApiService,\n allLocations: Iterable<string>,\n catalogFilename: string,\n) {\n const defaultBranchByRepoUrlPromises: Promise<{\n repoUrl: string;\n defaultBranch?: string;\n }>[] = [];\n for (const loc of allLocations) {\n // loc has the following format: https://github.com/<org>/<repo>/blob/<default-branch>/catalog-info.yaml\n // but it can have a more convoluted format like 'https://github.com/redhat-developer/rhdh-plugins/blob/main/plugins/scaffolder-annotator-action/examples/templates/01-scaffolder-template.yaml'\n // if registered manually from the 'Register existing component' feature in Backstage.\n if (!loc.endsWith(catalogFilename)) {\n logger.debug(\n `Ignored location ${loc} because it does not point to a file named ${catalogFilename}`,\n );\n continue;\n }\n const repoUrl = repoUrlFromLocation(loc);\n if (!repoUrl) {\n continue;\n }\n // Have to do this for Both the gitlab/github, possibly a better way?\n // Should probably parse the URL to figure out which to use?\n defaultBranchByRepoUrlPromises.push(\n (parseGitURLForApprovalTool(repoUrl) === 'GITLAB'\n ? gitlabApiService\n : githubApiService\n )\n .getRepositoryFromIntegrations(repoUrl)\n .then(resp => {\n return { repoUrl, defaultBranch: resp?.repository?.default_branch };\n })\n .catch((err: any) => {\n logErrorIfNeeded(\n logger,\n `Ignored repo ${repoUrl} due to an error while fetching details from GitHub`,\n err,\n );\n return {\n repoUrl,\n defaultBranch: undefined,\n };\n }),\n );\n }\n const defaultBranchesResponses = await Promise.all(\n defaultBranchByRepoUrlPromises,\n );\n return new Map(\n defaultBranchesResponses\n .flat()\n .filter(r => r.defaultBranch)\n .map(r => [r.repoUrl, r.defaultBranch!]),\n );\n}\n\nfunction repoUrlFromLocation(loc: string) {\n const split = loc.split('/blob/');\n if (split.length < 2) {\n return undefined;\n }\n return split[0];\n}\n\nfunction findImportCandidates(\n allLocations: Iterable<string>,\n defaultBranchByRepoUrl: Map<string, string>,\n catalogFilename: string,\n) {\n const filteredLocations: string[] = [];\n for (const loc of allLocations) {\n const repoUrl = repoUrlFromLocation(loc);\n if (!repoUrl) {\n continue;\n }\n\n const defaultBranch = defaultBranchByRepoUrl.get(repoUrl);\n if (!defaultBranch) {\n continue;\n }\n if (loc !== `${repoUrl}/blob/${defaultBranch}/${catalogFilename}`) {\n // Because users can use the \"Register existing component\" workflow to register a Location\n // using any file path in the repo, we consider a repository as an Import Location only\n // if it is at the root of the repository, because that is what the import PR ultimately does.\n continue;\n }\n filteredLocations.push(loc);\n }\n return filteredLocations;\n}\n\nasync function createPR(\n gitApiService: GitApiService,\n logger: LoggerService,\n req: Components.Schemas.ImportRequest,\n gitUrl: gitUrlParse.GitUrl,\n catalogInfoGenerator: CatalogInfoGenerator,\n config: Config,\n) {\n const appTitle =\n config.getOptionalString('app.title') ?? 'Red Hat Developer Hub';\n const appBaseUrl = config.getString('app.baseUrl');\n const catalogFileName = getCatalogFilename(config);\n return await gitApiService.submitPrToRepo(logger, {\n repoUrl: req.repository.url,\n gitUrl: gitUrl,\n defaultBranch: req.repository.defaultBranch,\n catalogInfoContent:\n req.catalogInfoContent ??\n (await catalogInfoGenerator.generateDefaultCatalogInfoContent(\n req.repository.url,\n )),\n prTitle:\n req[req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']?.pullRequest\n ?.title ?? `Add ${catalogFileName}`,\n prBody:\n req[req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']?.pullRequest\n ?.body ??\n `\nThis pull request adds a **Backstage entity metadata file** to this repository so that the component can be added to a Backstage application.\n\nAfter this pull request is merged, the component will become available in the [${appTitle} software catalog](${appBaseUrl}).\n\nFor more information, read an [overview of the Backstage software catalog](https://backstage.io/docs/features/software-catalog/).\n`,\n });\n}\n\nasync function handleAddedReposFromCreateImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n importRequests: Components.Schemas.ImportRequest[],\n) {\n const result: Components.Schemas.Import[] = [];\n\n for (const req of importRequests) {\n // Check if repo is already imported\n const repoCatalogUrl = getCatalogUrl(\n deps.config,\n req.repository.url,\n req.repository.defaultBranch,\n );\n const hasLocation =\n await deps.catalogHttpClient.verifyLocationExistence(repoCatalogUrl);\n if (!hasLocation) {\n continue;\n }\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const hasCatalogInfoFileInRepo = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: getCatalogFilename(deps.config),\n });\n if (!hasCatalogInfoFileInRepo) {\n continue;\n }\n\n const ghRepo = await gitApiService.getRepositoryFromIntegrations(\n req.repository.url,\n );\n\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n req.repository.url,\n req.repository.defaultBranch,\n );\n\n const gitUrl = gitUrlParse(req.repository.url);\n result.push({\n status: 'ADDED',\n lastUpdate: ghRepo?.repository?.updated_at ?? undefined,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n });\n }\n return result;\n}\n\nasync function handlePrCreationRequest(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n req: Components.Schemas.ImportRequest,\n gitUrl: gitUrlParse.GitUrl,\n): Promise<Components.Schemas.Import> {\n const repoCatalogUrl = getCatalogUrl(\n deps.config,\n req.repository.url,\n req.repository.defaultBranch,\n );\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const prToRepo = await createPR(\n gitApiService,\n deps.logger,\n req,\n gitUrl,\n deps.catalogInfoGenerator,\n deps.config,\n );\n if (prToRepo.errors && prToRepo.errors.length > 0) {\n return {\n errors: prToRepo.errors,\n status: 'PR_ERROR',\n repository: req.repository,\n };\n }\n if (prToRepo.prUrl) {\n deps.logger.debug(`Created new PR from request: ${prToRepo.prUrl}`);\n }\n\n // Create Location\n await deps.catalogHttpClient.possiblyCreateLocation(repoCatalogUrl);\n\n if (prToRepo.hasChanges === false) {\n deps.logger.debug(\n `No bulk import PR created on ${req.repository.url} since its default branch (${req.repository.defaultBranch}) already contains a catalog-info file`,\n );\n\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n req.repository.url,\n req.repository.defaultBranch,\n );\n return {\n status: 'ADDED',\n lastUpdate: prToRepo.lastUpdate,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n };\n }\n\n return {\n approvalTool: req.approvalTool ?? 'GIT',\n errors: prToRepo.errors,\n status: 'WAIT_PR_APPROVAL',\n lastUpdate: prToRepo.lastUpdate,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n [req.approvalTool === 'GITLAB' ? 'gitlab' : 'github']: {\n pullRequest: {\n url: prToRepo.prUrl,\n number: prToRepo.prNumber,\n },\n },\n };\n}\n\nexport async function createImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n reqParams: {\n importRequests: Paths.CreateImportJobs.RequestBody;\n dryRun?: boolean;\n },\n): Promise<HandlerResponse<Components.Schemas.Import[]>> {\n const dryRun = reqParams.dryRun ?? false;\n const importRequests = reqParams.importRequests;\n deps.logger.debug(\n `Handling request to import ${importRequests?.length} repo(s) (dryRun=${dryRun})..`,\n );\n\n if (importRequests.length === 0) {\n deps.logger.debug('Missing import requests from request body');\n return {\n statusCode: 400,\n responseBody: [],\n };\n }\n\n if (dryRun) {\n return {\n statusCode: 202,\n responseBody: await dryRunCreateImportJobs(deps, importRequests),\n };\n }\n\n const result: Components.Schemas.Import[] = [];\n\n const addedRepos = await handleAddedReposFromCreateImportJobs(\n deps,\n importRequests,\n );\n result.push(...addedRepos);\n const addedReposMap = new Map(\n addedRepos.map(res => [res.repository?.url, res]),\n );\n const remainingRequests = importRequests.filter(\n req => !addedReposMap.has(req.repository.url),\n );\n\n for (const req of remainingRequests) {\n const gitUrl = gitUrlParse(req.repository.url);\n\n // Create PR\n try {\n result.push(await handlePrCreationRequest(deps, req, gitUrl));\n } catch (error: any) {\n result.push({\n errors: [error.message],\n status: 'PR_ERROR',\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n } as Components.Schemas.Import);\n }\n }\n\n sortImports(result);\n\n return {\n statusCode: 202,\n responseBody: result,\n };\n}\n\nasync function dryRunCreateImportJobs(\n deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalogApi: CatalogApi;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogInfoGenerator: CatalogInfoGenerator;\n catalogHttpClient: CatalogHttpClient;\n },\n importRequests: Paths.CreateImportJobs.RequestBody,\n) {\n const result: Components.Schemas.Import[] = [];\n for (const req of importRequests) {\n const gitUrl = gitUrlParse(req.repository.url);\n\n const dryRunChecks = await performDryRunChecks(deps, req);\n if (dryRunChecks.errors?.length > 0) {\n deps.logger.warn(\n `Errors while performing dry-run checks: ${dryRunChecks.errors}`,\n );\n }\n result.push({\n errors: dryRunChecks.dryRunStatuses,\n catalogEntityName: req.catalogEntityName,\n repository: {\n url: req.repository.url,\n name: gitUrl.name,\n organization: gitUrl.organization,\n },\n });\n }\n return result;\n}\n\nasync function performDryRunChecks(\n deps: {\n logger: LoggerService;\n auth: AuthService;\n catalogApi: CatalogApi;\n config: Config;\n gitlabApiService: GitlabApiService;\n githubApiService: GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n req: Components.Schemas.ImportRequest,\n): Promise<{ dryRunStatuses: CreateImportDryRunStatus[]; errors: string[] }> {\n const checkCatalog = async (\n catalogEntityName: string,\n ): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const hasEntity =\n await deps.catalogHttpClient.hasEntityInCatalog(catalogEntityName);\n if (hasEntity) {\n return { dryRunStatuses: ['CATALOG_ENTITY_CONFLICT'] };\n }\n return {};\n };\n\n const gitApiService =\n req.approvalTool === 'GITLAB'\n ? deps.gitlabApiService\n : deps.githubApiService;\n const checkEmptyRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const empty = await gitApiService.isRepoEmpty({\n repoUrl: req.repository.url,\n });\n if (empty) {\n return {\n dryRunStatuses: ['REPO_EMPTY'],\n };\n }\n return {};\n };\n\n const checkCatalogInfoPresenceInRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const exists = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: getCatalogFilename(deps.config),\n });\n if (exists) {\n return {\n dryRunStatuses: ['CATALOG_INFO_FILE_EXISTS_IN_REPO'],\n };\n }\n return {};\n };\n\n const checkCodeOwnersFileInRepo = async (): Promise<{\n dryRunStatuses?: CreateImportDryRunStatus[];\n errors?: string[];\n }> => {\n const gitDirLocation =\n req.approvalTool === 'GITLAB' ? '.gitlab' : '.github';\n const exists = await gitApiService.hasFileInRepo({\n repoUrl: req.repository.url,\n defaultBranch: req.repository.defaultBranch,\n fileName: `${gitDirLocation}/CODEOWNERS`,\n });\n if (!exists) {\n return {\n dryRunStatuses: ['CODEOWNERS_FILE_NOT_FOUND_IN_REPO'],\n };\n }\n return {};\n };\n\n const dryRunStatuses: CreateImportDryRunStatus[] = [];\n const errors: string[] = [];\n const allChecksFn = [checkEmptyRepo(), checkCatalogInfoPresenceInRepo()];\n if (req.catalogEntityName?.trim()) {\n allChecksFn.push(checkCatalog(req.catalogEntityName));\n }\n if (req.codeOwnersFileAsEntityOwner) {\n allChecksFn.push(checkCodeOwnersFileInRepo());\n }\n const allChecks = await Promise.all(allChecksFn);\n allChecks.flat().forEach(res => {\n if (res.dryRunStatuses) {\n dryRunStatuses.push(...res.dryRunStatuses);\n }\n if (res.errors) {\n errors.push(...res.errors);\n }\n });\n\n dryRunStatuses.sort((a, b) => a.localeCompare(b));\n\n return {\n dryRunStatuses,\n errors,\n };\n}\n\nexport async function findImportStatusByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitlabApiService | GithubApiService;\n catalogHttpClient: CatalogHttpClient;\n approvalTool: string | undefined;\n },\n repoUrl: string,\n defaultBranch?: string,\n includeCatalogInfoContent?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(`Getting bulk import job status for ${repoUrl}..`);\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n defaultBranch,\n },\n approvalTool: deps.approvalTool,\n status: null,\n } as Components.Schemas.Import;\n try {\n // Check to see if there are any PR\n const openImportPr = await deps.gitApiService.findImportOpenPr(\n deps.logger,\n {\n repoUrl: repoUrl,\n includeCatalogInfoContent,\n },\n );\n\n if (!openImportPr?.prUrl) {\n const catalogLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations()\n ).uniqueCatalogUrlLocations.keys();\n\n const catalogUrl = getCatalogUrl(deps.config, repoUrl, defaultBranch);\n let exists = false;\n for (const loc of catalogLocations) {\n if (loc === catalogUrl) {\n exists = true;\n break;\n }\n }\n if (\n exists &&\n (await deps.gitApiService.hasFileInRepo({\n repoUrl,\n defaultBranch,\n fileName: getCatalogFilename(deps.config),\n }))\n ) {\n result.status = 'ADDED';\n // Force a refresh of the Location, so that the entities from the catalog-info.yaml can show up quickly (not guaranteed however).\n await deps.catalogHttpClient.refreshLocationByRepoUrl(\n repoUrl,\n defaultBranch,\n );\n }\n // No import PR => let's determine last update from the repository\n const ghRepo =\n await deps.gitApiService.getRepositoryFromIntegrations(repoUrl);\n result.lastUpdate = ghRepo.repository?.updated_at ?? undefined;\n return {\n statusCode: 200,\n responseBody: result,\n };\n }\n result.status = 'WAIT_PR_APPROVAL';\n result[deps.approvalTool === 'GITLAB' ? 'gitlab' : 'github'] = {\n pullRequest: {\n number: openImportPr.prNum,\n url: openImportPr.prUrl,\n title: openImportPr.prTitle,\n body: openImportPr.prBody,\n catalogInfoContent: openImportPr.prCatalogInfoContent,\n },\n };\n\n result.lastUpdate = openImportPr.lastUpdate;\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n if (error.message?.includes('Not Found')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n result.status = 'PR_ERROR';\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nexport async function findTaskImportStatusByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n githubApiService: GithubApiService;\n gitlabApiService: GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n repositoryDao: RepositoryDao<'repositories'>;\n taskDao: ScaffolderTaskDao;\n taskLocationsDao: TaskLocationsDao;\n discovery: DiscoveryService;\n auth: AuthService;\n },\n repoUrl: string,\n skipTasks?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(`Getting bulk import job status for ${repoUrl}.`);\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result: Components.Schemas.Import = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n },\n };\n try {\n const repository = await deps.repositoryDao.findRepositoryByUrl(repoUrl);\n if (!repository) {\n throw new NotFoundError(`Repository ${repoUrl} info was not found`);\n }\n\n const task = await deps.taskDao.lastExecutedTaskByRepoId(repository?.id);\n if (!task) {\n throw new NotFoundError(\n `Unable to find scaffolder task for repository: ${repository?.id}`,\n );\n }\n\n const scaffolderUrl = await deps.discovery.getBaseUrl('scaffolder');\n const { token } = await deps.auth.getPluginRequestToken({\n onBehalfOf: await deps.auth.getOwnServiceCredentials(),\n targetPluginId: 'scaffolder',\n });\n\n const response = await fetch(`${scaffolderUrl}/v2/tasks/${task.taskId}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n if (!skipTasks) {\n const tasks = await deps.taskDao.findTasksByRepositoryId(repository.id);\n const tasksWithLocations = await Promise.all(\n tasks.map(async taskItem => {\n const locations = await deps.taskLocationsDao.findLocationsByTaskId(\n taskItem.taskId,\n );\n const taskLocations = locations.map(location => location.location);\n return {\n ...taskItem,\n locations: taskLocations,\n };\n }),\n );\n result.tasks = tasksWithLocations;\n }\n\n result.task = { taskId: task.taskId };\n let data;\n if (response.ok) {\n data = await response.json();\n result.lastUpdate = data.lastHeartbeatAt;\n\n const approvalTool =\n repository.approvalTool as unknown as Components.Schemas.ApprovalTool;\n const pullRequest = await parsePullOrMergeRequestInfo(\n data.state?.checkpoints,\n {\n githubApiService: deps.githubApiService,\n gitlabApiService: deps.gitlabApiService,\n approvalTool,\n logger: deps.logger,\n repoUrl,\n },\n );\n if (pullRequest && approvalTool === 'GITLAB') {\n result.gitlab = { pullRequest };\n }\n if (pullRequest && approvalTool === 'GIT') {\n result.github = { pullRequest };\n }\n\n result.status =\n `TASK_${(data.status as string)?.toLocaleUpperCase()}` as Components.Schemas.TaskImportStatus;\n } else {\n const errMsg =\n (await response.text()) ??\n `Failed to fetch task ${task.taskId}. Response status: ${response.status}`;\n throw new Error(errMsg);\n }\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n result.status = 'TASK_FETCH_FAILED';\n if (error.name?.includes('NotFoundError')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nexport async function findOrchestratorImportStatusByRepo(\n deps: {\n logger: LoggerService;\n orchestratorRepositoryDao: RepositoryDao<'orchestrator_repositories'>;\n orchestratorWorkflowDao: OrchestratorWorkflowDao;\n discovery: DiscoveryService;\n },\n repoUrl: string,\n token: string,\n skipWorkflows?: boolean,\n): Promise<HandlerResponse<Components.Schemas.Import>> {\n deps.logger.debug(\n `Getting orchestrator workflow import job status for ${repoUrl}.`,\n );\n\n const gitUrl = gitUrlParse(repoUrl);\n\n const errors: string[] = [];\n const result: Components.Schemas.Import = {\n id: repoUrl,\n repository: {\n url: repoUrl,\n name: gitUrl.name,\n organization: gitUrl.organization,\n id: `${gitUrl.organization}/${gitUrl.name}`,\n },\n };\n try {\n const repository =\n await deps.orchestratorRepositoryDao.findRepositoryByUrl(repoUrl);\n if (repository) {\n const workflow =\n await deps.orchestratorWorkflowDao.lastExecutedWorkflowByRepoId(\n repository.id,\n );\n if (!workflow) {\n throw new NotFoundError(\n `Workflow for repository ${repoUrl} was not found`,\n );\n }\n if (workflow.instanceId) {\n const baseUrl = await deps.discovery.getBaseUrl('orchestrator');\n const orchestratorApi = new DefaultApi(new Configuration(), baseUrl);\n const response = await orchestratorApi.getInstanceById(\n workflow.instanceId,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n },\n );\n\n const instance = response.data;\n if (instance) {\n result.workflow = {\n workflowId: instance.id,\n };\n if (!skipWorkflows) {\n const workflows =\n await deps.orchestratorWorkflowDao.findWorkflowsByRepositoryId(\n repository.id,\n );\n result.workflows = workflows.map((w: OrchestratorWorkflow) => ({\n workflowId: w.instanceId,\n }));\n }\n\n result.approvalTool =\n repository.approvalTool as unknown as Components.Schemas.ApprovalTool;\n result.lastUpdate = instance.end;\n const status =\n `WORKFLOW_${(instance.state as string)?.toLocaleUpperCase()}` as Components.Schemas.WorkflowImportStatus;\n result.status = status;\n }\n }\n }\n } catch (error: any) {\n errors.push(error.message);\n result.errors = errors;\n result.status = 'WORKFLOW_FETCH_FAILED';\n if (error.name?.includes('NotFoundError')) {\n return {\n statusCode: 404,\n responseBody: result,\n };\n }\n }\n\n return {\n statusCode: 200,\n responseBody: result,\n };\n}\n\nasync function parsePullOrMergeRequestInfo(\n checkpoints: Record<string, any>,\n {\n githubApiService,\n gitlabApiService,\n approvalTool,\n logger,\n repoUrl,\n }: {\n githubApiService: GithubApiService;\n gitlabApiService: GitlabApiService;\n approvalTool: Components.Schemas.ApprovalTool;\n logger: LoggerService;\n repoUrl: string;\n },\n): Promise<Components.Schemas.PullRequest | undefined> {\n // return errors ?\n if (approvalTool !== 'GITLAB' && approvalTool !== 'GIT') {\n return undefined;\n }\n const gitApiService =\n approvalTool === 'GITLAB' ? gitlabApiService : githubApiService;\n\n for (const key in checkpoints) {\n if (!checkpoints.hasOwnProperty(key)) {\n continue;\n }\n try {\n if (\n key.startsWith('v1.task.checkpoint.publish.create.pr') ||\n key.startsWith('v1.task.checkpoint.publish.create.mr')\n ) {\n const url =\n checkpoints[key]?.value?.html_url ??\n checkpoints[key]?.value?.mrWebUrl;\n if (!url) {\n continue;\n }\n const prNumber = Number.parseInt(url.split('/').pop()!, 10);\n const prDetails = await gitApiService.getPullRequest(repoUrl, prNumber);\n\n let catalogInfoContent: string | undefined;\n if (prDetails.prSha) {\n catalogInfoContent = await gitApiService.getCatalogInfoFile(logger, {\n repoUrl,\n prHeadSha: prDetails.prSha,\n prNumber,\n });\n }\n return {\n url,\n number: prNumber,\n title: prDetails.title,\n body: prDetails.body,\n status: prDetails.merged ? 'PR_MERGED' : 'WAIT_PR_APPROVAL',\n catalogInfoContent,\n };\n }\n } catch (err) {\n logger.warn(`Error while processing checkpoint ${key}: ${err}`);\n continue;\n }\n }\n\n return undefined;\n}\n\nexport async function deleteImportByRepo(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n repoUrl: string,\n defaultBranch?: string,\n): Promise<HandlerResponse<void>> {\n deps.logger.debug(`Deleting bulk import job status for ${repoUrl}..`);\n\n // Check to see if there are any PR\n const openImportPr = await deps.gitApiService.findImportOpenPr(deps.logger, {\n repoUrl: repoUrl,\n });\n\n const gitUrl = gitUrlParse(repoUrl);\n if (openImportPr?.prUrl) {\n // Close PR\n const appTitle =\n deps.config.getOptionalString('app.title') ?? 'Red Hat Developer Hub';\n const appBaseUrl = deps.config.getString('app.baseUrl');\n\n await deps.gitApiService.closeImportPR(deps.logger, {\n repoUrl,\n gitUrl,\n comment: `Closing PR upon request for bulk import deletion. This request was created from [${appTitle}](${appBaseUrl}).`,\n });\n }\n // Also delete the import branch, so that it is not outdated if we try later to import the repo again\n await deps.gitApiService.deleteImportBranch({\n repoUrl,\n gitUrl,\n });\n // Remove Location from catalog\n const catalogUrl = getCatalogUrl(deps.config, repoUrl, defaultBranch);\n const findLocationFrom = (list: { id?: string; target: string }[]) => {\n for (const loc of list) {\n if (loc.target === catalogUrl) {\n return loc.id;\n }\n }\n return undefined;\n };\n\n const locationId = findLocationFrom(\n (\n await deps.catalogHttpClient.listCatalogUrlLocationsByIdFromLocationsEndpoint()\n ).locations,\n );\n if (locationId) {\n await deps.catalogHttpClient.deleteCatalogLocationById(locationId);\n }\n\n return {\n statusCode: 204,\n responseBody: undefined,\n };\n}\n\nexport async function deleteRepositoryRecord<\n DAO extends RepositoryDao<RepositoryName>,\n>(\n deps: {\n logger: LoggerService;\n dao: DAO;\n },\n repoUrl: string,\n): Promise<HandlerResponse<void>> {\n deps.logger.debug(`Deleting repository from database by name ${repoUrl}...`);\n try {\n await deps.dao.deleteRepository(repoUrl);\n\n return {\n statusCode: 204,\n responseBody: undefined,\n };\n } catch (error: any) {\n deps.logger.error(\n `Failed to delete repository from database by url ${repoUrl}`,\n error,\n );\n return {\n statusCode: 500,\n };\n }\n}\n"],"names":["DefaultSortColumn","DefaultSortOrder","getNestedValue","DefaultPageNumber","DefaultPageSize","getCatalogFilename","parseGitURLForApprovalTool","imports","paginateArray","logErrorIfNeeded","getCatalogUrl","gitUrlParse","errors","NotFoundError","DefaultApi","Configuration"],"mappings":";;;;;;;;;;;;;;;;;;AA0EO,SAAS,WAAA,CACd,OAAA,EACA,UAAA,GAAyDA,0BAAA,EACzD,YAAuDC,yBAAA,EACvD;AACA,EAAA,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AACrB,IAAA,MAAM,MAAA,GAASC,oBAAA,CAAe,CAAA,EAAG,UAAU,CAAA;AAC3C,IAAA,MAAM,MAAA,GAASA,oBAAA,CAAe,CAAA,EAAG,UAAU,CAAA;AAE3C,IAAA,IAAI,MAAA,KAAW,MAAA,IAAa,MAAA,KAAW,MAAA,EAAW,OAAO,CAAA;AACzD,IAAA,IAAI,MAAA,KAAW,MAAA,EAAW,OAAO,SAAA,KAAc,QAAQ,EAAA,GAAK,CAAA;AAC5D,IAAA,IAAI,MAAA,KAAW,MAAA,EAAW,OAAO,SAAA,KAAc,QAAQ,CAAA,GAAI,EAAA;AAE3D,IAAA,IAAI,eAAe,YAAA,EAAc;AAC/B,MAAA,MAAM,KAAA,GAAQ,IAAI,IAAA,CAAK,MAAM,CAAA;AAC7B,MAAA,MAAM,KAAA,GAAQ,IAAI,IAAA,CAAK,MAAM,CAAA;AAE7B,MAAA,OAAO,SAAA,KAAc,KAAA,GACjB,KAAA,CAAM,OAAA,EAAQ,GAAI,KAAA,CAAM,OAAA,EAAQ,GAChC,KAAA,CAAM,OAAA,EAAQ,GAAI,KAAA,CAAM,OAAA,EAAQ;AAAA,IACtC;AAEA,IAAA,OAAO,SAAA,KAAc,QACjB,MAAA,CAAO,aAAA,CAAc,MAAM,CAAA,GAC3B,MAAA,CAAO,cAAc,MAAM,CAAA;AAAA,EACjC,CAAC,CAAA;AACH;AAEA,eAAsB,cAAA,CACpB,IAAA,EAOA,cAAA,EAGA,WAAA,EAOkD;AAClD,EAAA,MAAM,UAAA,GAAa,gBAAgB,UAAA,IAAc,IAAA;AACjD,EAAA,MAAM,SAAS,WAAA,EAAa,MAAA;AAC5B,EAAA,MAAM,UAAA,GAAa,aAAa,UAAA,IAAcC,0BAAA;AAC9C,EAAA,MAAM,QAAA,GAAW,aAAa,QAAA,IAAYC,wBAAA;AAC1C,EAAA,MAAM,UAAA,GAAa,aAAa,UAAA,IAAcJ,0BAAA;AAC9C,EAAA,MAAM,SAAA,GAAY,aAAa,SAAA,IAAaC,yBAAA;AAE5C,EAAA,MAAM,eAAA,GAAkBI,+BAAA,CAAmB,IAAA,CAAK,MAAM,CAAA;AAEtD,EAAA,MAAM,YAAA,GAAA,CACJ,MAAM,IAAA,CAAK,iBAAA,CAAkB,uBAAA;AAAA,IAC3B,MAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF,EACA,yBAAA;AAKF,EAAA,MAAM,yBAAyB,MAAM,2BAAA;AAAA,IACnC,IAAA,CAAK,MAAA;AAAA,IACL,IAAA,CAAK,gBAAA;AAAA,IACL,IAAA,CAAK,gBAAA;AAAA,IACL,aAAa,IAAA,EAAK;AAAA,IAClB;AAAA,GACF;AAIA,EAAA,MAAM,gBAAA,GAAmB,oBAAA;AAAA,IACvB,aAAa,IAAA,EAAK;AAAA,IAClB,sBAAA;AAAA,IACA;AAAA,GACF;AAGA,EAAA,MAAM,kCAAA,GACJ,MAAM,IAAA,CAAK,gBAAA,CAAiB,yCAAA;AAAA,IAC1B,gBAAA,CAAiB,OAAO,CAAA,GAAA,KAAO;AAC7B,MAAA,OAAOC,gCAAA,CAA2B,GAAG,CAAA,KAAM,KAAA;AAAA,IAC7C,CAAC;AAAA,GACH;AAEF,EAAA,MAAM,kCAAA,GACJ,MAAM,IAAA,CAAK,gBAAA,CAAiB,yCAAA;AAAA,IAC1B,gBAAA,CAAiB,OAAO,CAAA,GAAA,KAAO;AAC7B,MAAA,OAAOA,gCAAA,CAA2B,GAAG,CAAA,KAAM,QAAA;AAAA,IAC7C,CAAC;AAAA,GACH;AAGF,EAAA,MAAM,8BAAA,GAAiC,kCAAA,CACpC,GAAA,CAAI,CAAA,GAAA,KAAO;AACV,IAAA,OAAO;AAAA,MACL,GAAA,EAAK,GAAA;AAAA,MACL,YAAA,EAAc;AAAA,KAChB;AAAA,EACF,CAAC,CAAA,CACA,MAAA;AAAA,IACC,kCAAA,CAAmC,IAAI,CAAA,GAAA,KAAO;AAC5C,MAAA,OAAO;AAAA,QACL,GAAA,EAAK,GAAA;AAAA,QACL,YAAA,EAAc;AAAA,OAChB;AAAA,IACF,CAAC;AAAA,GACH;AAEF,EAAA,MAAM,iBAAA,uBAAwB,GAAA,EAAoB;AAGlD,EAAA,MAAM,uBAEA,EAAC;AACP,EAAA,KAAA,MAAWC,YAAW,8BAAA,EAAgC;AACpD,IAAA,MAAM,OAAA,GAAU,mBAAA,CAAoBA,QAAAA,CAAQ,GAAG,CAAA;AAC/C,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA;AAAA,IACF;AACA,IAAA,iBAAA,CAAkB,GAAA,CAAI,OAAA,EAASA,QAAAA,CAAQ,GAAG,CAAA;AAE1C,IAAA,oBAAA,CAAqB,IAAA;AAAA,MACnB,sBAAA;AAAA,QACE;AAAA,UACE,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,eACEA,QAAAA,CAAQ,YAAA,KAAiB,QAAA,GACrB,IAAA,CAAK,mBACL,IAAA,CAAK,gBAAA;AAAA,UACX,mBAAmB,IAAA,CAAK,iBAAA;AAAA,UACxB,cAAcA,QAAAA,CAAQ;AAAA,SACxB;AAAA,QACA,OAAA;AAAA,QACA,sBAAA,CAAuB,IAAI,OAAO,CAAA;AAAA,QAClC;AAAA;AACF,KACF;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,GAAA,CAAI,oBAAoB,CAAA;AACrD,EAAA,MAAM,OAAA,GAAU,MAAA,CACb,MAAA,CAAO,CAAA,GAAA,KAAO,GAAA,CAAI,YAAY,CAAA,CAC9B,GAAA,CAAI,CAAA,GAAA,KAAO,GAAA,CAAI,YAAa,CAAA,CAC5B,IAAI,CAAA,GAAA,KAAO;AACV,IAAA,MAAM,GAAA,GAAM,KAAK,UAAA,EAAY,GAAA;AAC7B,IAAA,MAAM,QAAA,GAAW,GAAA,GAAM,iBAAA,CAAkB,GAAA,CAAI,GAAG,CAAA,GAAI,MAAA;AACpD,IAAA,OAAO;AAAA,MACL,GAAG,GAAA;AAAA,MACH,QAAQ,QAAA,GAAW,YAAA,CAAa,GAAA,CAAI,QAAQ,GAAG,MAAA,GAAS;AAAA,KAC1D;AAAA,EACF,CAAC,CAAA;AAIH,EAAA,WAAA,CAAY,OAAA,EAAS,YAAY,SAAS,CAAA;AAC1C,EAAA,MAAM,SAAA,GAAYC,wBAAA,CAAc,OAAA,EAAS,UAAA,EAAY,QAAQ,CAAA;AAC7D,EAAA,IAAI,eAAe,IAAA,EAAM;AACvB,IAAA,OAAO;AAAA,MACL,UAAA,EAAY,GAAA;AAAA,MACZ,cAAc,SAAA,CAAU;AAAA,KAC1B;AAAA,EACF;AACA,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,GAAA;AAAA,IACZ,YAAA,EAAc;AAAA,MACZ,SAAS,SAAA,CAAU,MAAA;AAAA,MACnB,YAAY,SAAA,CAAU,UAAA;AAAA,MACtB,IAAA,EAAM,UAAA;AAAA,MACN,IAAA,EAAM;AAAA;AACR,GACF;AACF;AAEA,eAAe,2BAAA,CACb,MAAA,EACA,gBAAA,EACA,gBAAA,EACA,cACA,eAAA,EACA;AACA,EAAA,MAAM,iCAGC,EAAC;AACR,EAAA,KAAA,MAAW,OAAO,YAAA,EAAc;AAI9B,IAAA,IAAI,CAAC,GAAA,CAAI,QAAA,CAAS,eAAe,CAAA,EAAG;AAClC,MAAA,MAAA,CAAO,KAAA;AAAA,QACL,CAAA,iBAAA,EAAoB,GAAG,CAAA,2CAAA,EAA8C,eAAe,CAAA;AAAA,OACtF;AACA,MAAA;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAU,oBAAoB,GAAG,CAAA;AACvC,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA;AAAA,IACF;AAGA,IAAA,8BAAA,CAA+B,IAAA;AAAA,MAAA,CAC5BF,gCAAA,CAA2B,OAAO,CAAA,KAAM,QAAA,GACrC,gBAAA,GACA,kBAED,6BAAA,CAA8B,OAAO,CAAA,CACrC,IAAA,CAAK,CAAA,IAAA,KAAQ;AACZ,QAAA,OAAO,EAAE,OAAA,EAAS,aAAA,EAAe,IAAA,EAAM,YAAY,cAAA,EAAe;AAAA,MACpE,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,GAAA,KAAa;AACnB,QAAAG,6BAAA;AAAA,UACE,MAAA;AAAA,UACA,gBAAgB,OAAO,CAAA,mDAAA,CAAA;AAAA,UACvB;AAAA,SACF;AACA,QAAA,OAAO;AAAA,UACL,OAAA;AAAA,UACA,aAAA,EAAe;AAAA,SACjB;AAAA,MACF,CAAC;AAAA,KACL;AAAA,EACF;AACA,EAAA,MAAM,wBAAA,GAA2B,MAAM,OAAA,CAAQ,GAAA;AAAA,IAC7C;AAAA,GACF;AACA,EAAA,OAAO,IAAI,GAAA;AAAA,IACT,wBAAA,CACG,IAAA,EAAK,CACL,MAAA,CAAO,OAAK,CAAA,CAAE,aAAa,CAAA,CAC3B,GAAA,CAAI,OAAK,CAAC,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,aAAc,CAAC;AAAA,GAC3C;AACF;AAEA,SAAS,oBAAoB,GAAA,EAAa;AACxC,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA;AAChC,EAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,MAAM,CAAC,CAAA;AAChB;AAEA,SAAS,oBAAA,CACP,YAAA,EACA,sBAAA,EACA,eAAA,EACA;AACA,EAAA,MAAM,oBAA8B,EAAC;AACrC,EAAA,KAAA,MAAW,OAAO,YAAA,EAAc;AAC9B,IAAA,MAAM,OAAA,GAAU,oBAAoB,GAAG,CAAA;AACvC,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,aAAA,GAAgB,sBAAA,CAAuB,GAAA,CAAI,OAAO,CAAA;AACxD,IAAA,IAAI,CAAC,aAAA,EAAe;AAClB,MAAA;AAAA,IACF;AACA,IAAA,IAAI,QAAQ,CAAA,EAAG,OAAO,SAAS,aAAa,CAAA,CAAA,EAAI,eAAe,CAAA,CAAA,EAAI;AAIjE,MAAA;AAAA,IACF;AACA,IAAA,iBAAA,CAAkB,KAAK,GAAG,CAAA;AAAA,EAC5B;AACA,EAAA,OAAO,iBAAA;AACT;AAEA,eAAe,SACb,aAAA,EACA,MAAA,EACA,GAAA,EACA,MAAA,EACA,sBACA,MAAA,EACA;AACA,EAAA,MAAM,QAAA,GACJ,MAAA,CAAO,iBAAA,CAAkB,WAAW,CAAA,IAAK,uBAAA;AAC3C,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,SAAA,CAAU,aAAa,CAAA;AACjD,EAAA,MAAM,eAAA,GAAkBJ,gCAAmB,MAAM,CAAA;AACjD,EAAA,OAAO,MAAM,aAAA,CAAc,cAAA,CAAe,MAAA,EAAQ;AAAA,IAChD,OAAA,EAAS,IAAI,UAAA,CAAW,GAAA;AAAA,IACxB,MAAA;AAAA,IACA,aAAA,EAAe,IAAI,UAAA,CAAW,aAAA;AAAA,IAC9B,kBAAA,EACE,GAAA,CAAI,kBAAA,IACH,MAAM,oBAAA,CAAqB,iCAAA;AAAA,MAC1B,IAAI,UAAA,CAAW;AAAA,KACjB;AAAA,IACF,OAAA,EACE,GAAA,CAAI,GAAA,CAAI,YAAA,KAAiB,QAAA,GAAW,QAAA,GAAW,QAAQ,CAAA,EAAG,WAAA,EACtD,KAAA,IAAS,CAAA,IAAA,EAAO,eAAe,CAAA,CAAA;AAAA,IACrC,MAAA,EACE,IAAI,GAAA,CAAI,YAAA,KAAiB,WAAW,QAAA,GAAW,QAAQ,CAAA,EAAG,WAAA,EACtD,IAAA,IACJ;AAAA;;AAAA,+EAAA,EAG2E,QAAQ,sBAAsB,UAAU,CAAA;;AAAA;AAAA;AAAA,GAItH,CAAA;AACH;AAEA,eAAe,oCAAA,CACb,MAUA,cAAA,EACA;AACA,EAAA,MAAM,SAAsC,EAAC;AAE7C,EAAA,KAAA,MAAW,OAAO,cAAA,EAAgB;AAEhC,IAAA,MAAM,cAAA,GAAiBK,0BAAA;AAAA,MACrB,IAAA,CAAK,MAAA;AAAA,MACL,IAAI,UAAA,CAAW,GAAA;AAAA,MACf,IAAI,UAAA,CAAW;AAAA,KACjB;AACA,IAAA,MAAM,WAAA,GACJ,MAAM,IAAA,CAAK,iBAAA,CAAkB,wBAAwB,cAAc,CAAA;AACrE,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA;AAAA,IACF;AACA,IAAA,MAAM,gBACJ,GAAA,CAAI,YAAA,KAAiB,QAAA,GACjB,IAAA,CAAK,mBACL,IAAA,CAAK,gBAAA;AACX,IAAA,MAAM,wBAAA,GAA2B,MAAM,aAAA,CAAc,aAAA,CAAc;AAAA,MACjE,OAAA,EAAS,IAAI,UAAA,CAAW,GAAA;AAAA,MACxB,aAAA,EAAe,IAAI,UAAA,CAAW,aAAA;AAAA,MAC9B,QAAA,EAAUL,+BAAA,CAAmB,IAAA,CAAK,MAAM;AAAA,KACzC,CAAA;AACD,IAAA,IAAI,CAAC,wBAAA,EAA0B;AAC7B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,6BAAA;AAAA,MACjC,IAAI,UAAA,CAAW;AAAA,KACjB;AAGA,IAAA,MAAM,KAAK,iBAAA,CAAkB,wBAAA;AAAA,MAC3B,IAAI,UAAA,CAAW,GAAA;AAAA,MACf,IAAI,UAAA,CAAW;AAAA,KACjB;AAEA,IAAA,MAAM,MAAA,GAASM,4BAAA,CAAY,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA;AAC7C,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,MAAA,EAAQ,OAAA;AAAA,MACR,UAAA,EAAY,MAAA,EAAQ,UAAA,EAAY,UAAA,IAAc,MAAA;AAAA,MAC9C,UAAA,EAAY;AAAA,QACV,GAAA,EAAK,IAAI,UAAA,CAAW,GAAA;AAAA,QACpB,MAAM,MAAA,CAAO,IAAA;AAAA,QACb,cAAc,MAAA,CAAO;AAAA;AACvB,KACD,CAAA;AAAA,EACH;AACA,EAAA,OAAO,MAAA;AACT;AAEA,eAAe,uBAAA,CACb,IAAA,EAUA,GAAA,EACA,MAAA,EACoC;AACpC,EAAA,MAAM,cAAA,GAAiBD,0BAAA;AAAA,IACrB,IAAA,CAAK,MAAA;AAAA,IACL,IAAI,UAAA,CAAW,GAAA;AAAA,IACf,IAAI,UAAA,CAAW;AAAA,GACjB;AACA,EAAA,MAAM,gBACJ,GAAA,CAAI,YAAA,KAAiB,QAAA,GACjB,IAAA,CAAK,mBACL,IAAA,CAAK,gBAAA;AACX,EAAA,MAAM,WAAW,MAAM,QAAA;AAAA,IACrB,aAAA;AAAA,IACA,IAAA,CAAK,MAAA;AAAA,IACL,GAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAA,CAAK,oBAAA;AAAA,IACL,IAAA,CAAK;AAAA,GACP;AACA,EAAA,IAAI,QAAA,CAAS,MAAA,IAAU,QAAA,CAAS,MAAA,CAAO,SAAS,CAAA,EAAG;AACjD,IAAA,OAAO;AAAA,MACL,QAAQ,QAAA,CAAS,MAAA;AAAA,MACjB,MAAA,EAAQ,UAAA;AAAA,MACR,YAAY,GAAA,CAAI;AAAA,KAClB;AAAA,EACF;AACA,EAAA,IAAI,SAAS,KAAA,EAAO;AAClB,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,6BAAA,EAAgC,QAAA,CAAS,KAAK,CAAA,CAAE,CAAA;AAAA,EACpE;AAGA,EAAA,MAAM,IAAA,CAAK,iBAAA,CAAkB,sBAAA,CAAuB,cAAc,CAAA;AAElE,EAAA,IAAI,QAAA,CAAS,eAAe,KAAA,EAAO;AACjC,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,MACV,gCAAgC,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA,2BAAA,EAA8B,GAAA,CAAI,WAAW,aAAa,CAAA,sCAAA;AAAA,KAC9G;AAGA,IAAA,MAAM,KAAK,iBAAA,CAAkB,wBAAA;AAAA,MAC3B,IAAI,UAAA,CAAW,GAAA;AAAA,MACf,IAAI,UAAA,CAAW;AAAA,KACjB;AACA,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,OAAA;AAAA,MACR,YAAY,QAAA,CAAS,UAAA;AAAA,MACrB,UAAA,EAAY;AAAA,QACV,GAAA,EAAK,IAAI,UAAA,CAAW,GAAA;AAAA,QACpB,MAAM,MAAA,CAAO,IAAA;AAAA,QACb,cAAc,MAAA,CAAO;AAAA;AACvB,KACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,YAAA,EAAc,IAAI,YAAA,IAAgB,KAAA;AAAA,IAClC,QAAQ,QAAA,CAAS,MAAA;AAAA,IACjB,MAAA,EAAQ,kBAAA;AAAA,IACR,YAAY,QAAA,CAAS,UAAA;AAAA,IACrB,UAAA,EAAY;AAAA,MACV,GAAA,EAAK,IAAI,UAAA,CAAW,GAAA;AAAA,MACpB,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,cAAc,MAAA,CAAO;AAAA,KACvB;AAAA,IACA,CAAC,GAAA,CAAI,YAAA,KAAiB,QAAA,GAAW,QAAA,GAAW,QAAQ,GAAG;AAAA,MACrD,WAAA,EAAa;AAAA,QACX,KAAK,QAAA,CAAS,KAAA;AAAA,QACd,QAAQ,QAAA,CAAS;AAAA;AACnB;AACF,GACF;AACF;AAEA,eAAsB,gBAAA,CACpB,MAUA,SAAA,EAIuD;AACvD,EAAA,MAAM,MAAA,GAAS,UAAU,MAAA,IAAU,KAAA;AACnC,EAAA,MAAM,iBAAiB,SAAA,CAAU,cAAA;AACjC,EAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,IACV,CAAA,2BAAA,EAA8B,cAAA,EAAgB,MAAM,CAAA,iBAAA,EAAoB,MAAM,CAAA,GAAA;AAAA,GAChF;AAEA,EAAA,IAAI,cAAA,CAAe,WAAW,CAAA,EAAG;AAC/B,IAAA,IAAA,CAAK,MAAA,CAAO,MAAM,2CAA2C,CAAA;AAC7D,IAAA,OAAO;AAAA,MACL,UAAA,EAAY,GAAA;AAAA,MACZ,cAAc;AAAC,KACjB;AAAA,EACF;AAEA,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,OAAO;AAAA,MACL,UAAA,EAAY,GAAA;AAAA,MACZ,YAAA,EAAc,MAAM,sBAAA,CAAuB,IAAA,EAAM,cAAc;AAAA,KACjE;AAAA,EACF;AAEA,EAAA,MAAM,SAAsC,EAAC;AAE7C,EAAA,MAAM,aAAa,MAAM,oCAAA;AAAA,IACvB,IAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAA,CAAO,IAAA,CAAK,GAAG,UAAU,CAAA;AACzB,EAAA,MAAM,gBAAgB,IAAI,GAAA;AAAA,IACxB,UAAA,CAAW,IAAI,CAAA,GAAA,KAAO,CAAC,IAAI,UAAA,EAAY,GAAA,EAAK,GAAG,CAAC;AAAA,GAClD;AACA,EAAA,MAAM,oBAAoB,cAAA,CAAe,MAAA;AAAA,IACvC,SAAO,CAAC,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,WAAW,GAAG;AAAA,GAC9C;AAEA,EAAA,KAAA,MAAW,OAAO,iBAAA,EAAmB;AACnC,IAAA,MAAM,MAAA,GAASC,4BAAA,CAAY,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA;AAG7C,IAAA,IAAI;AACF,MAAA,MAAA,CAAO,KAAK,MAAM,uBAAA,CAAwB,IAAA,EAAM,GAAA,EAAK,MAAM,CAAC,CAAA;AAAA,IAC9D,SAAS,KAAA,EAAY;AACnB,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,MAAA,EAAQ,CAAC,KAAA,CAAM,OAAO,CAAA;AAAA,QACtB,MAAA,EAAQ,UAAA;AAAA,QACR,UAAA,EAAY;AAAA,UACV,GAAA,EAAK,IAAI,UAAA,CAAW,GAAA;AAAA,UACpB,MAAM,MAAA,CAAO,IAAA;AAAA,UACb,cAAc,MAAA,CAAO;AAAA;AACvB,OAC4B,CAAA;AAAA,IAChC;AAAA,EACF;AAEA,EAAA,WAAA,CAAY,MAAM,CAAA;AAElB,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,GAAA;AAAA,IACZ,YAAA,EAAc;AAAA,GAChB;AACF;AAEA,eAAe,sBAAA,CACb,MAUA,cAAA,EACA;AACA,EAAA,MAAM,SAAsC,EAAC;AAC7C,EAAA,KAAA,MAAW,OAAO,cAAA,EAAgB;AAChC,IAAA,MAAM,MAAA,GAASA,4BAAA,CAAY,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA;AAE7C,IAAA,MAAM,YAAA,GAAe,MAAM,mBAAA,CAAoB,IAAA,EAAM,GAAG,CAAA;AACxD,IAAA,IAAI,YAAA,CAAa,MAAA,EAAQ,MAAA,GAAS,CAAA,EAAG;AACnC,MAAA,IAAA,CAAK,MAAA,CAAO,IAAA;AAAA,QACV,CAAA,wCAAA,EAA2C,aAAa,MAAM,CAAA;AAAA,OAChE;AAAA,IACF;AACA,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,QAAQ,YAAA,CAAa,cAAA;AAAA,MACrB,mBAAmB,GAAA,CAAI,iBAAA;AAAA,MACvB,UAAA,EAAY;AAAA,QACV,GAAA,EAAK,IAAI,UAAA,CAAW,GAAA;AAAA,QACpB,MAAM,MAAA,CAAO,IAAA;AAAA,QACb,cAAc,MAAA,CAAO;AAAA;AACvB,KACD,CAAA;AAAA,EACH;AACA,EAAA,OAAO,MAAA;AACT;AAEA,eAAe,mBAAA,CACb,MASA,GAAA,EAC2E;AAC3E,EAAA,MAAM,YAAA,GAAe,OACnB,iBAAA,KAII;AACJ,IAAA,MAAM,SAAA,GACJ,MAAM,IAAA,CAAK,iBAAA,CAAkB,mBAAmB,iBAAiB,CAAA;AACnE,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,OAAO,EAAE,cAAA,EAAgB,CAAC,yBAAyB,CAAA,EAAE;AAAA,IACvD;AACA,IAAA,OAAO,EAAC;AAAA,EACV,CAAA;AAEA,EAAA,MAAM,gBACJ,GAAA,CAAI,YAAA,KAAiB,QAAA,GACjB,IAAA,CAAK,mBACL,IAAA,CAAK,gBAAA;AACX,EAAA,MAAM,iBAAiB,YAGjB;AACJ,IAAA,MAAM,KAAA,GAAQ,MAAM,aAAA,CAAc,WAAA,CAAY;AAAA,MAC5C,OAAA,EAAS,IAAI,UAAA,CAAW;AAAA,KACzB,CAAA;AACD,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,OAAO;AAAA,QACL,cAAA,EAAgB,CAAC,YAAY;AAAA,OAC/B;AAAA,IACF;AACA,IAAA,OAAO,EAAC;AAAA,EACV,CAAA;AAEA,EAAA,MAAM,iCAAiC,YAGjC;AACJ,IAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,aAAA,CAAc;AAAA,MAC/C,OAAA,EAAS,IAAI,UAAA,CAAW,GAAA;AAAA,MACxB,aAAA,EAAe,IAAI,UAAA,CAAW,aAAA;AAAA,MAC9B,QAAA,EAAUN,+BAAA,CAAmB,IAAA,CAAK,MAAM;AAAA,KACzC,CAAA;AACD,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,OAAO;AAAA,QACL,cAAA,EAAgB,CAAC,kCAAkC;AAAA,OACrD;AAAA,IACF;AACA,IAAA,OAAO,EAAC;AAAA,EACV,CAAA;AAEA,EAAA,MAAM,4BAA4B,YAG5B;AACJ,IAAA,MAAM,cAAA,GACJ,GAAA,CAAI,YAAA,KAAiB,QAAA,GAAW,SAAA,GAAY,SAAA;AAC9C,IAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc,aAAA,CAAc;AAAA,MAC/C,OAAA,EAAS,IAAI,UAAA,CAAW,GAAA;AAAA,MACxB,aAAA,EAAe,IAAI,UAAA,CAAW,aAAA;AAAA,MAC9B,QAAA,EAAU,GAAG,cAAc,CAAA,WAAA;AAAA,KAC5B,CAAA;AACD,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,OAAO;AAAA,QACL,cAAA,EAAgB,CAAC,mCAAmC;AAAA,OACtD;AAAA,IACF;AACA,IAAA,OAAO,EAAC;AAAA,EACV,CAAA;AAEA,EAAA,MAAM,iBAA6C,EAAC;AACpD,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,MAAM,WAAA,GAAc,CAAC,cAAA,EAAe,EAAG,gCAAgC,CAAA;AACvE,EAAA,IAAI,GAAA,CAAI,iBAAA,EAAmB,IAAA,EAAK,EAAG;AACjC,IAAA,WAAA,CAAY,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,iBAAiB,CAAC,CAAA;AAAA,EACtD;AACA,EAAA,IAAI,IAAI,2BAAA,EAA6B;AACnC,IAAA,WAAA,CAAY,IAAA,CAAK,2BAA2B,CAAA;AAAA,EAC9C;AACA,EAAA,MAAM,SAAA,GAAY,MAAM,OAAA,CAAQ,GAAA,CAAI,WAAW,CAAA;AAC/C,EAAA,SAAA,CAAU,IAAA,EAAK,CAAE,OAAA,CAAQ,CAAA,GAAA,KAAO;AAC9B,IAAA,IAAI,IAAI,cAAA,EAAgB;AACtB,MAAA,cAAA,CAAe,IAAA,CAAK,GAAG,GAAA,CAAI,cAAc,CAAA;AAAA,IAC3C;AACA,IAAA,IAAI,IAAI,MAAA,EAAQ;AACd,MAAA,MAAA,CAAO,IAAA,CAAK,GAAG,GAAA,CAAI,MAAM,CAAA;AAAA,IAC3B;AAAA,EACF,CAAC,CAAA;AAED,EAAA,cAAA,CAAe,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,aAAA,CAAc,CAAC,CAAC,CAAA;AAEhD,EAAA,OAAO;AAAA,IACL,cAAA;AAAA,IACA;AAAA,GACF;AACF;AAEA,eAAsB,sBAAA,CACpB,IAAA,EAOA,OAAA,EACA,aAAA,EACA,yBAAA,EACqD;AACrD,EAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,mCAAA,EAAsC,OAAO,CAAA,EAAA,CAAI,CAAA;AAEnE,EAAA,MAAM,MAAA,GAASM,6BAAY,OAAO,CAAA;AAElC,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,EAAA,EAAI,OAAA;AAAA,IACJ,UAAA,EAAY;AAAA,MACV,GAAA,EAAK,OAAA;AAAA,MACL,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,cAAc,MAAA,CAAO,YAAA;AAAA,MACrB,IAAI,CAAA,EAAG,MAAA,CAAO,YAAY,CAAA,CAAA,EAAI,OAAO,IAAI,CAAA,CAAA;AAAA,MACzC;AAAA,KACF;AAAA,IACA,cAAc,IAAA,CAAK,YAAA;AAAA,IACnB,MAAA,EAAQ;AAAA,GACV;AACA,EAAA,IAAI;AAEF,IAAA,MAAM,YAAA,GAAe,MAAM,IAAA,CAAK,aAAA,CAAc,gBAAA;AAAA,MAC5C,IAAA,CAAK,MAAA;AAAA,MACL;AAAA,QACE,OAAA;AAAA,QACA;AAAA;AACF,KACF;AAEA,IAAA,IAAI,CAAC,cAAc,KAAA,EAAO;AACxB,MAAA,MAAM,oBACJ,MAAM,IAAA,CAAK,kBAAkB,uBAAA,EAAwB,EACrD,0BAA0B,IAAA,EAAK;AAEjC,MAAA,MAAM,UAAA,GAAaD,0BAAA,CAAc,IAAA,CAAK,MAAA,EAAQ,SAAS,aAAa,CAAA;AACpE,MAAA,IAAI,MAAA,GAAS,KAAA;AACb,MAAA,KAAA,MAAW,OAAO,gBAAA,EAAkB;AAClC,QAAA,IAAI,QAAQ,UAAA,EAAY;AACtB,UAAA,MAAA,GAAS,IAAA;AACT,UAAA;AAAA,QACF;AAAA,MACF;AACA,MAAA,IACE,MAAA,IACC,MAAM,IAAA,CAAK,aAAA,CAAc,aAAA,CAAc;AAAA,QACtC,OAAA;AAAA,QACA,aAAA;AAAA,QACA,QAAA,EAAUL,+BAAA,CAAmB,IAAA,CAAK,MAAM;AAAA,OACzC,CAAA,EACD;AACA,QAAA,MAAA,CAAO,MAAA,GAAS,OAAA;AAEhB,QAAA,MAAM,KAAK,iBAAA,CAAkB,wBAAA;AAAA,UAC3B,OAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAEA,MAAA,MAAM,MAAA,GACJ,MAAM,IAAA,CAAK,aAAA,CAAc,8BAA8B,OAAO,CAAA;AAChE,MAAA,MAAA,CAAO,UAAA,GAAa,MAAA,CAAO,UAAA,EAAY,UAAA,IAAc,KAAA,CAAA;AACrD,MAAA,OAAO;AAAA,QACL,UAAA,EAAY,GAAA;AAAA,QACZ,YAAA,EAAc;AAAA,OAChB;AAAA,IACF;AACA,IAAA,MAAA,CAAO,MAAA,GAAS,kBAAA;AAChB,IAAA,MAAA,CAAO,IAAA,CAAK,YAAA,KAAiB,QAAA,GAAW,QAAA,GAAW,QAAQ,CAAA,GAAI;AAAA,MAC7D,WAAA,EAAa;AAAA,QACX,QAAQ,YAAA,CAAa,KAAA;AAAA,QACrB,KAAK,YAAA,CAAa,KAAA;AAAA,QAClB,OAAO,YAAA,CAAa,OAAA;AAAA,QACpB,MAAM,YAAA,CAAa,MAAA;AAAA,QACnB,oBAAoB,YAAA,CAAa;AAAA;AACnC,KACF;AAEA,IAAA,MAAA,CAAO,aAAa,YAAA,CAAa,UAAA;AAAA,EACnC,SAAS,KAAA,EAAY;AACnB,IAAA,MAAA,CAAO,IAAA,CAAK,MAAM,OAAO,CAAA;AACzB,IAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAChB,IAAA,IAAI,KAAA,CAAM,OAAA,EAAS,QAAA,CAAS,WAAW,CAAA,EAAG;AACxC,MAAA,OAAO;AAAA,QACL,UAAA,EAAY,GAAA;AAAA,QACZ,YAAA,EAAc;AAAA,OAChB;AAAA,IACF;AACA,IAAA,MAAA,CAAO,MAAA,GAAS,UAAA;AAAA,EAClB;AAEA,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,GAAA;AAAA,IACZ,YAAA,EAAc;AAAA,GAChB;AACF;AAEA,eAAsB,0BAAA,CACpB,IAAA,EAYA,OAAA,EACA,SAAA,EACqD;AACrD,EAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,mCAAA,EAAsC,OAAO,CAAA,CAAA,CAAG,CAAA;AAElE,EAAA,MAAM,MAAA,GAASM,6BAAY,OAAO,CAAA;AAElC,EAAA,MAAMC,WAAmB,EAAC;AAC1B,EAAA,MAAM,MAAA,GAAoC;AAAA,IACxC,EAAA,EAAI,OAAA;AAAA,IACJ,UAAA,EAAY;AAAA,MACV,GAAA,EAAK,OAAA;AAAA,MACL,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,cAAc,MAAA,CAAO,YAAA;AAAA,MACrB,IAAI,CAAA,EAAG,MAAA,CAAO,YAAY,CAAA,CAAA,EAAI,OAAO,IAAI,CAAA;AAAA;AAC3C,GACF;AACA,EAAA,IAAI;AACF,IAAA,MAAM,UAAA,GAAa,MAAM,IAAA,CAAK,aAAA,CAAc,oBAAoB,OAAO,CAAA;AACvE,IAAA,IAAI,CAAC,UAAA,EAAY;AACf,MAAA,MAAM,IAAIC,oBAAA,CAAc,CAAA,WAAA,EAAc,OAAO,CAAA,mBAAA,CAAqB,CAAA;AAAA,IACpE;AAEA,IAAA,MAAM,OAAO,MAAM,IAAA,CAAK,OAAA,CAAQ,wBAAA,CAAyB,YAAY,EAAE,CAAA;AACvE,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,IAAIA,oBAAA;AAAA,QACR,CAAA,+CAAA,EAAkD,YAAY,EAAE,CAAA;AAAA,OAClE;AAAA,IACF;AAEA,IAAA,MAAM,aAAA,GAAgB,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,YAAY,CAAA;AAClE,IAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,IAAA,CAAK,KAAK,qBAAA,CAAsB;AAAA,MACtD,UAAA,EAAY,MAAM,IAAA,CAAK,IAAA,CAAK,wBAAA,EAAyB;AAAA,MACrD,cAAA,EAAgB;AAAA,KACjB,CAAA;AAED,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,CAAA,EAAG,aAAa,CAAA,UAAA,EAAa,IAAA,CAAK,MAAM,CAAA,CAAA,EAAI;AAAA,MACvE,OAAA,EAAS;AAAA,QACP,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA;AAChC,KACD,CAAA;AACD,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,MAAM,QAAQ,MAAM,IAAA,CAAK,OAAA,CAAQ,uBAAA,CAAwB,WAAW,EAAE,CAAA;AACtE,MAAA,MAAM,kBAAA,GAAqB,MAAM,OAAA,CAAQ,GAAA;AAAA,QACvC,KAAA,CAAM,GAAA,CAAI,OAAM,QAAA,KAAY;AAC1B,UAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,gBAAA,CAAiB,qBAAA;AAAA,YAC5C,QAAA,CAAS;AAAA,WACX;AACA,UAAA,MAAM,aAAA,GAAgB,SAAA,CAAU,GAAA,CAAI,CAAA,QAAA,KAAY,SAAS,QAAQ,CAAA;AACjE,UAAA,OAAO;AAAA,YACL,GAAG,QAAA;AAAA,YACH,SAAA,EAAW;AAAA,WACb;AAAA,QACF,CAAC;AAAA,OACH;AACA,MAAA,MAAA,CAAO,KAAA,GAAQ,kBAAA;AAAA,IACjB;AAEA,IAAA,MAAA,CAAO,IAAA,GAAO,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAO;AACpC,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI,SAAS,EAAA,EAAI;AACf,MAAA,IAAA,GAAO,MAAM,SAAS,IAAA,EAAK;AAC3B,MAAA,MAAA,CAAO,aAAa,IAAA,CAAK,eAAA;AAEzB,MAAA,MAAM,eACJ,UAAA,CAAW,YAAA;AACb,MAAA,MAAM,cAAc,MAAM,2BAAA;AAAA,QACxB,KAAK,KAAA,EAAO,WAAA;AAAA,QACZ;AAAA,UACE,kBAAkB,IAAA,CAAK,gBAAA;AAAA,UACvB,kBAAkB,IAAA,CAAK,gBAAA;AAAA,UACvB,YAAA;AAAA,UACA,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb;AAAA;AACF,OACF;AACA,MAAA,IAAI,WAAA,IAAe,iBAAiB,QAAA,EAAU;AAC5C,QAAA,MAAA,CAAO,MAAA,GAAS,EAAE,WAAA,EAAY;AAAA,MAChC;AACA,MAAA,IAAI,WAAA,IAAe,iBAAiB,KAAA,EAAO;AACzC,QAAA,MAAA,CAAO,MAAA,GAAS,EAAE,WAAA,EAAY;AAAA,MAChC;AAEA,MAAA,MAAA,CAAO,MAAA,GACL,CAAA,KAAA,EAAS,IAAA,CAAK,MAAA,EAAmB,mBAAmB,CAAA,CAAA;AAAA,IACxD,CAAA,MAAO;AACL,MAAA,MAAM,MAAA,GACH,MAAM,QAAA,CAAS,IAAA,EAAK,IACrB,wBAAwB,IAAA,CAAK,MAAM,CAAA,mBAAA,EAAsB,QAAA,CAAS,MAAM,CAAA,CAAA;AAC1E,MAAA,MAAM,IAAI,MAAM,MAAM,CAAA;AAAA,IACxB;AAAA,EACF,SAAS,KAAA,EAAY;AACnB,IAAAD,QAAA,CAAO,IAAA,CAAK,MAAM,OAAO,CAAA;AACzB,IAAA,MAAA,CAAO,MAAA,GAASA,QAAA;AAChB,IAAA,MAAA,CAAO,MAAA,GAAS,mBAAA;AAChB,IAAA,IAAI,KAAA,CAAM,IAAA,EAAM,QAAA,CAAS,eAAe,CAAA,EAAG;AACzC,MAAA,OAAO;AAAA,QACL,UAAA,EAAY,GAAA;AAAA,QACZ,YAAA,EAAc;AAAA,OAChB;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,GAAA;AAAA,IACZ,YAAA,EAAc;AAAA,GAChB;AACF;AAEA,eAAsB,kCAAA,CACpB,IAAA,EAMA,OAAA,EACA,KAAA,EACA,aAAA,EACqD;AACrD,EAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,IACV,uDAAuD,OAAO,CAAA,CAAA;AAAA,GAChE;AAEA,EAAA,MAAM,MAAA,GAASD,6BAAY,OAAO,CAAA;AAElC,EAAA,MAAMC,WAAmB,EAAC;AAC1B,EAAA,MAAM,MAAA,GAAoC;AAAA,IACxC,EAAA,EAAI,OAAA;AAAA,IACJ,UAAA,EAAY;AAAA,MACV,GAAA,EAAK,OAAA;AAAA,MACL,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,cAAc,MAAA,CAAO,YAAA;AAAA,MACrB,IAAI,CAAA,EAAG,MAAA,CAAO,YAAY,CAAA,CAAA,EAAI,OAAO,IAAI,CAAA;AAAA;AAC3C,GACF;AACA,EAAA,IAAI;AACF,IAAA,MAAM,UAAA,GACJ,MAAM,IAAA,CAAK,yBAAA,CAA0B,oBAAoB,OAAO,CAAA;AAClE,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,MAAM,QAAA,GACJ,MAAM,IAAA,CAAK,uBAAA,CAAwB,4BAAA;AAAA,QACjC,UAAA,CAAW;AAAA,OACb;AACF,MAAA,IAAI,CAAC,QAAA,EAAU;AACb,QAAA,MAAM,IAAIC,oBAAA;AAAA,UACR,2BAA2B,OAAO,CAAA,cAAA;AAAA,SACpC;AAAA,MACF;AACA,MAAA,IAAI,SAAS,UAAA,EAAY;AACvB,QAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,cAAc,CAAA;AAC9D,QAAA,MAAM,kBAAkB,IAAIC,4CAAA,CAAW,IAAIC,+CAAA,IAAiB,OAAO,CAAA;AACnE,QAAA,MAAM,QAAA,GAAW,MAAM,eAAA,CAAgB,eAAA;AAAA,UACrC,QAAA,CAAS,UAAA;AAAA,UACT;AAAA,YACE,OAAA,EAAS;AAAA,cACP,aAAA,EAAe,UAAU,KAAK,CAAA,CAAA;AAAA,cAC9B,cAAA,EAAgB;AAAA;AAClB;AACF,SACF;AAEA,QAAA,MAAM,WAAW,QAAA,CAAS,IAAA;AAC1B,QAAA,IAAI,QAAA,EAAU;AACZ,UAAA,MAAA,CAAO,QAAA,GAAW;AAAA,YAChB,YAAY,QAAA,CAAS;AAAA,WACvB;AACA,UAAA,IAAI,CAAC,aAAA,EAAe;AAClB,YAAA,MAAM,SAAA,GACJ,MAAM,IAAA,CAAK,uBAAA,CAAwB,2BAAA;AAAA,cACjC,UAAA,CAAW;AAAA,aACb;AACF,YAAA,MAAA,CAAO,SAAA,GAAY,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,MAA6B;AAAA,cAC7D,YAAY,CAAA,CAAE;AAAA,aAChB,CAAE,CAAA;AAAA,UACJ;AAEA,UAAA,MAAA,CAAO,eACL,UAAA,CAAW,YAAA;AACb,UAAA,MAAA,CAAO,aAAa,QAAA,CAAS,GAAA;AAC7B,UAAA,MAAM,MAAA,GACJ,CAAA,SAAA,EAAa,QAAA,CAAS,KAAA,EAAkB,mBAAmB,CAAA,CAAA;AAC7D,UAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,KAAA,EAAY;AACnB,IAAAH,QAAA,CAAO,IAAA,CAAK,MAAM,OAAO,CAAA;AACzB,IAAA,MAAA,CAAO,MAAA,GAASA,QAAA;AAChB,IAAA,MAAA,CAAO,MAAA,GAAS,uBAAA;AAChB,IAAA,IAAI,KAAA,CAAM,IAAA,EAAM,QAAA,CAAS,eAAe,CAAA,EAAG;AACzC,MAAA,OAAO;AAAA,QACL,UAAA,EAAY,GAAA;AAAA,QACZ,YAAA,EAAc;AAAA,OAChB;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,GAAA;AAAA,IACZ,YAAA,EAAc;AAAA,GAChB;AACF;AAEA,eAAe,4BACb,WAAA,EACA;AAAA,EACE,gBAAA;AAAA,EACA,gBAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAOqD;AAErD,EAAA,IAAI,YAAA,KAAiB,QAAA,IAAY,YAAA,KAAiB,KAAA,EAAO;AACvD,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,MAAM,aAAA,GACJ,YAAA,KAAiB,QAAA,GAAW,gBAAA,GAAmB,gBAAA;AAEjD,EAAA,KAAA,MAAW,OAAO,WAAA,EAAa;AAC7B,IAAA,IAAI,CAAC,WAAA,CAAY,cAAA,CAAe,GAAG,CAAA,EAAG;AACpC,MAAA;AAAA,IACF;AACA,IAAA,IAAI;AACF,MAAA,IACE,IAAI,UAAA,CAAW,sCAAsC,KACrD,GAAA,CAAI,UAAA,CAAW,sCAAsC,CAAA,EACrD;AACA,QAAA,MAAM,GAAA,GACJ,YAAY,GAAG,CAAA,EAAG,OAAO,QAAA,IACzB,WAAA,CAAY,GAAG,CAAA,EAAG,KAAA,EAAO,QAAA;AAC3B,QAAA,IAAI,CAAC,GAAA,EAAK;AACR,UAAA;AAAA,QACF;AACA,QAAA,MAAM,QAAA,GAAW,OAAO,QAAA,CAAS,GAAA,CAAI,MAAM,GAAG,CAAA,CAAE,GAAA,EAAI,EAAI,EAAE,CAAA;AAC1D,QAAA,MAAM,SAAA,GAAY,MAAM,aAAA,CAAc,cAAA,CAAe,SAAS,QAAQ,CAAA;AAEtE,QAAA,IAAI,kBAAA;AACJ,QAAA,IAAI,UAAU,KAAA,EAAO;AACnB,UAAA,kBAAA,GAAqB,MAAM,aAAA,CAAc,kBAAA,CAAmB,MAAA,EAAQ;AAAA,YAClE,OAAA;AAAA,YACA,WAAW,SAAA,CAAU,KAAA;AAAA,YACrB;AAAA,WACD,CAAA;AAAA,QACH;AACA,QAAA,OAAO;AAAA,UACL,GAAA;AAAA,UACA,MAAA,EAAQ,QAAA;AAAA,UACR,OAAO,SAAA,CAAU,KAAA;AAAA,UACjB,MAAM,SAAA,CAAU,IAAA;AAAA,UAChB,MAAA,EAAQ,SAAA,CAAU,MAAA,GAAS,WAAA,GAAc,kBAAA;AAAA,UACzC;AAAA,SACF;AAAA,MACF;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,kCAAA,EAAqC,GAAG,CAAA,EAAA,EAAK,GAAG,CAAA,CAAE,CAAA;AAC9D,MAAA;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEA,eAAsB,kBAAA,CACpB,IAAA,EAMA,OAAA,EACA,aAAA,EACgC;AAChC,EAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,oCAAA,EAAuC,OAAO,CAAA,EAAA,CAAI,CAAA;AAGpE,EAAA,MAAM,eAAe,MAAM,IAAA,CAAK,aAAA,CAAc,gBAAA,CAAiB,KAAK,MAAA,EAAQ;AAAA,IAC1E;AAAA,GACD,CAAA;AAED,EAAA,MAAM,MAAA,GAASD,6BAAY,OAAO,CAAA;AAClC,EAAA,IAAI,cAAc,KAAA,EAAO;AAEvB,IAAA,MAAM,QAAA,GACJ,IAAA,CAAK,MAAA,CAAO,iBAAA,CAAkB,WAAW,CAAA,IAAK,uBAAA;AAChD,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,aAAa,CAAA;AAEtD,IAAA,MAAM,IAAA,CAAK,aAAA,CAAc,aAAA,CAAc,IAAA,CAAK,MAAA,EAAQ;AAAA,MAClD,OAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAA,EAAS,CAAA,iFAAA,EAAoF,QAAQ,CAAA,EAAA,EAAK,UAAU,CAAA,EAAA;AAAA,KACrH,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,IAAA,CAAK,cAAc,kBAAA,CAAmB;AAAA,IAC1C,OAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,UAAA,GAAaD,0BAAA,CAAc,IAAA,CAAK,MAAA,EAAQ,SAAS,aAAa,CAAA;AACpE,EAAA,MAAM,gBAAA,GAAmB,CAAC,IAAA,KAA4C;AACpE,IAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,MAAA,IAAI,GAAA,CAAI,WAAW,UAAA,EAAY;AAC7B,QAAA,OAAO,GAAA,CAAI,EAAA;AAAA,MACb;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,UAAA,GAAa,gBAAA;AAAA,IAAA,CAEf,MAAM,IAAA,CAAK,iBAAA,CAAkB,gDAAA,EAAiD,EAC9E;AAAA,GACJ;AACA,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,MAAM,IAAA,CAAK,iBAAA,CAAkB,yBAAA,CAA0B,UAAU,CAAA;AAAA,EACnE;AAEA,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,GAAA;AAAA,IACZ,YAAA,EAAc;AAAA,GAChB;AACF;AAEA,eAAsB,sBAAA,CAGpB,MAIA,OAAA,EACgC;AAChC,EAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,0CAAA,EAA6C,OAAO,CAAA,GAAA,CAAK,CAAA;AAC3E,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,gBAAA,CAAiB,OAAO,CAAA;AAEvC,IAAA,OAAO;AAAA,MACL,UAAA,EAAY,GAAA;AAAA,MACZ,YAAA,EAAc,KAAA;AAAA,KAChB;AAAA,EACF,SAAS,KAAA,EAAY;AACnB,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,MACV,oDAAoD,OAAO,CAAA,CAAA;AAAA,MAC3D;AAAA,KACF;AACA,IAAA,OAAO;AAAA,MACL,UAAA,EAAY;AAAA,KACd;AAAA,EACF;AACF;;;;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"importStatus.cjs.js","sources":["../../../../src/service/handlers/import/importStatus.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 { Config } from '@backstage/config';\n\nimport { CatalogHttpClient } from '../../../catalog/catalogHttpClient';\nimport {\n getCatalogFilename,\n getCatalogUrl,\n} from '../../../catalog/catalogUtils';\nimport type { Components } from '../../../generated/openapi';\nimport
|
|
1
|
+
{"version":3,"file":"importStatus.cjs.js","sources":["../../../../src/service/handlers/import/importStatus.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 { Config } from '@backstage/config';\n\nimport { CatalogHttpClient } from '../../../catalog/catalogHttpClient';\nimport {\n getCatalogFilename,\n getCatalogUrl,\n} from '../../../catalog/catalogUtils';\nimport type { Components } from '../../../generated/openapi';\nimport { GitApiService } from '../../../scm/GitApiService';\n\nexport async function getImportStatusFromLocations(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n repoUrl: string,\n catalogUrlLocations: Iterable<string>,\n defaultBranch?: string,\n): Promise<{\n status: Components.Schemas.ImportStatus;\n lastUpdate?: string;\n} | null> {\n return getImportStatusWithCheckerFn(\n deps,\n repoUrl,\n async (catalogUrl: string) => {\n for (const loc of catalogUrlLocations) {\n if (catalogUrl === loc) {\n return true;\n }\n }\n return false;\n },\n defaultBranch,\n );\n}\n\nasync function getImportStatusWithCheckerFn(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n repoUrl: string,\n catalogExistenceCheckFn: (catalogUrl: string) => Promise<boolean>,\n defaultBranch?: string,\n): Promise<{\n status: Components.Schemas.ImportStatus;\n lastUpdate?: string;\n} | null> {\n // Check to see if there are any PR\n const openImportPr = await deps.gitApiService.findImportOpenPr(deps.logger, {\n repoUrl,\n });\n if (!openImportPr?.prUrl) {\n const existsInCatalog = await catalogExistenceCheckFn(\n getCatalogUrl(deps.config, repoUrl, defaultBranch),\n );\n const existsInRepo = await deps.gitApiService.hasFileInRepo({\n repoUrl,\n defaultBranch,\n fileName: getCatalogFilename(deps.config),\n });\n if (existsInCatalog && existsInRepo) {\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 return { status: 'ADDED' };\n }\n return null;\n }\n return { status: 'WAIT_PR_APPROVAL', lastUpdate: openImportPr.lastUpdate };\n}\n"],"names":["getCatalogUrl","getCatalogFilename"],"mappings":";;;;AA2BA,eAAsB,4BAAA,CACpB,IAAA,EAMA,OAAA,EACA,mBAAA,EACA,aAAA,EAIQ;AACR,EAAA,OAAO,4BAAA;AAAA,IACL,IAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAO,UAAA,KAAuB;AAC5B,MAAA,KAAA,MAAW,OAAO,mBAAA,EAAqB;AACrC,QAAA,IAAI,eAAe,GAAA,EAAK;AACtB,UAAA,OAAO,IAAA;AAAA,QACT;AAAA,MACF;AACA,MAAA,OAAO,KAAA;AAAA,IACT,CAAA;AAAA,IACA;AAAA,GACF;AACF;AAEA,eAAe,4BAAA,CACb,IAAA,EAMA,OAAA,EACA,uBAAA,EACA,aAAA,EAIQ;AAER,EAAA,MAAM,eAAe,MAAM,IAAA,CAAK,aAAA,CAAc,gBAAA,CAAiB,KAAK,MAAA,EAAQ;AAAA,IAC1E;AAAA,GACD,CAAA;AACD,EAAA,IAAI,CAAC,cAAc,KAAA,EAAO;AACxB,IAAA,MAAM,kBAAkB,MAAM,uBAAA;AAAA,MAC5BA,0BAAA,CAAc,IAAA,CAAK,MAAA,EAAQ,OAAA,EAAS,aAAa;AAAA,KACnD;AACA,IAAA,MAAM,YAAA,GAAe,MAAM,IAAA,CAAK,aAAA,CAAc,aAAA,CAAc;AAAA,MAC1D,OAAA;AAAA,MACA,aAAA;AAAA,MACA,QAAA,EAAUC,+BAAA,CAAmB,IAAA,CAAK,MAAM;AAAA,KACzC,CAAA;AACD,IAAA,IAAI,mBAAmB,YAAA,EAAc;AAEnC,MAAA,MAAM,KAAK,iBAAA,CAAkB,wBAAA;AAAA,QAC3B,OAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,OAAO,EAAE,QAAQ,OAAA,EAAQ;AAAA,IAC3B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,EAAE,MAAA,EAAQ,kBAAA,EAAoB,UAAA,EAAY,aAAa,UAAA,EAAW;AAC3E;;;;"}
|
|
@@ -7,9 +7,9 @@ async function findAllOrganizations(logger, gitApiService, search, pageNumber =
|
|
|
7
7
|
`Getting all organizations (search,page,size)=('${search ?? ""}',${pageNumber},${pageSize})..`
|
|
8
8
|
);
|
|
9
9
|
const allOrgsAccessible = await gitApiService.getOrganizationsFromIntegrations(
|
|
10
|
-
search,
|
|
11
10
|
pageNumber,
|
|
12
|
-
pageSize
|
|
11
|
+
pageSize,
|
|
12
|
+
search
|
|
13
13
|
);
|
|
14
14
|
const errorList = [];
|
|
15
15
|
for (const err of allOrgsAccessible.errors ?? []) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizations.cjs.js","sources":["../../../../src/service/handlers/organization/organizations.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 type { Components } from '../../../generated/openapi';\nimport
|
|
1
|
+
{"version":3,"file":"organizations.cjs.js","sources":["../../../../src/service/handlers/organization/organizations.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 type { Components } from '../../../generated/openapi';\nimport { GitApiService } from '../../../scm/GitApiService';\nimport { SCMOrganizationResponse } from '../../../scm/types';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n type HandlerResponse,\n} from '../handlers';\n\nexport async function findAllOrganizations(\n logger: LoggerService,\n gitApiService: GitApiService,\n search?: string,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n): Promise<HandlerResponse<Components.Schemas.OrganizationList>> {\n logger.debug(\n `Getting all organizations (search,page,size)=('${\n search ?? ''\n }',${pageNumber},${pageSize})..`,\n );\n\n const allOrgsAccessible =\n await gitApiService.getOrganizationsFromIntegrations(\n pageNumber,\n pageSize,\n search,\n );\n\n const errorList: string[] = [];\n for (const err of allOrgsAccessible.errors ?? []) {\n if (err.error?.message) {\n errorList.push(err.error.message);\n }\n }\n if (allOrgsAccessible.organizations?.length === 0 && errorList.length > 0) {\n return {\n statusCode: 500,\n responseBody: {\n errors: errorList,\n },\n };\n }\n\n const orgMap = extractOrgMap(allOrgsAccessible);\n\n // sorting the output to make it deterministic and easy to navigate in the UI\n const organizations = sortOrgs(orgMap);\n\n return {\n statusCode: 200,\n responseBody: {\n errors: errorList,\n organizations,\n totalCount: allOrgsAccessible.totalCount,\n pagePerIntegration: pageNumber,\n sizePerIntegration: pageSize,\n },\n };\n}\n\nfunction extractOrgMap(allOrgsAccessible: SCMOrganizationResponse) {\n const orgMap = new Map<string, Components.Schemas.Organization>();\n for (const org of allOrgsAccessible.organizations ?? []) {\n let totalRepoCount: number | undefined;\n if (\n org.public_repos !== undefined ||\n org.total_private_repos !== undefined ||\n org.owned_private_repos !== undefined\n ) {\n totalRepoCount =\n (org.public_repos ?? 0) +\n (org.owned_private_repos ?? org.total_private_repos ?? 0);\n }\n orgMap.set(org.name, {\n id: `${org.id}`,\n name: org.name,\n description: org.description,\n url: org.url,\n totalRepoCount,\n errors: [],\n });\n }\n return orgMap;\n}\n\nfunction sortOrgs(orgMap: Map<string, Components.Schemas.Organization>) {\n const organizations = Array.from(orgMap.values());\n organizations.sort((a, b) => {\n if (a.name === undefined && b.name === undefined) {\n return 0;\n }\n if (a.name === undefined) {\n return -1;\n }\n if (b.name === undefined) {\n return 1;\n }\n return a.name.localeCompare(b.name);\n });\n return organizations;\n}\n"],"names":["DefaultPageNumber","DefaultPageSize"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var gitUrlParse = require('git-url-parse');
|
|
4
|
+
var catalogUtils = require('../../../catalog/catalogUtils.cjs.js');
|
|
4
5
|
var handlers = require('../handlers.cjs.js');
|
|
5
6
|
require('@backstage/errors');
|
|
6
7
|
require('@red-hat-developer-hub/backstage-plugin-orchestrator-common');
|
|
@@ -19,18 +20,53 @@ async function findAllRepositories(deps, reqParams) {
|
|
|
19
20
|
const checkStatus = reqParams?.checkStatus ?? false;
|
|
20
21
|
const pageNumber = reqParams?.pageNumber ?? handlers.DefaultPageNumber;
|
|
21
22
|
const pageSize = reqParams?.pageSize ?? handlers.DefaultPageSize;
|
|
23
|
+
const userTokens = reqParams?.userTokens;
|
|
22
24
|
deps.logger.debug(
|
|
23
25
|
`Getting all repositories - (search,page,size)=('${search ?? ""}',${pageNumber},${pageSize})..`
|
|
24
26
|
);
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
+
const [alreadyImportedRepositories, allRepositoriesResponse] = await Promise.all([
|
|
28
|
+
deps.catalogHttpClient.listCatalogUrlLocations(),
|
|
29
|
+
deps.gitApiService.getRepositoriesFromIntegrations(search, userTokens)
|
|
30
|
+
]);
|
|
31
|
+
const alreadyImportedRepositoriesLocationTargets = new Set(
|
|
32
|
+
alreadyImportedRepositories.uniqueCatalogUrlLocations.keys()
|
|
33
|
+
);
|
|
34
|
+
const { repositories: allRepositories, errors } = allRepositoriesResponse;
|
|
35
|
+
const notImportedYetRepositories = allRepositories.filter((repo) => {
|
|
36
|
+
const catalogUrl = catalogUtils.getCatalogUrl(
|
|
37
|
+
deps.config,
|
|
38
|
+
repo.html_url.replace(/\/$/, ""),
|
|
39
|
+
repo.default_branch
|
|
40
|
+
);
|
|
41
|
+
let alreadyImported = alreadyImportedRepositoriesLocationTargets.has(catalogUrl);
|
|
42
|
+
if (!alreadyImported) {
|
|
43
|
+
alreadyImported = alreadyImportedRepositoriesLocationTargets.has(
|
|
44
|
+
catalogUrl.replace("/blob/", "/tree/")
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
return !alreadyImported;
|
|
48
|
+
});
|
|
49
|
+
sortRepos(notImportedYetRepositories);
|
|
50
|
+
const gitRepositoryResponse = {
|
|
51
|
+
repositories: notImportedYetRepositories,
|
|
52
|
+
errors,
|
|
53
|
+
totalCount: notImportedYetRepositories.length
|
|
54
|
+
};
|
|
55
|
+
return await formatResponse(deps, gitRepositoryResponse, checkStatus);
|
|
27
56
|
}
|
|
28
|
-
async function findRepositoriesByOrganization(deps, orgName, search, checkStatus = false, pageNumber = handlers.DefaultPageNumber, pageSize = handlers.DefaultPageSize) {
|
|
57
|
+
async function findRepositoriesByOrganization(deps, orgName, search, checkStatus = false, pageNumber = handlers.DefaultPageNumber, pageSize = handlers.DefaultPageSize, userTokens) {
|
|
29
58
|
deps.logger.debug(
|
|
30
59
|
`Getting all repositories for org "${orgName}" - (search,page,size)=(${search},${pageNumber},${pageSize})..`
|
|
31
60
|
);
|
|
32
|
-
const glReposByOrg = await deps.gitApiService.getOrgRepositoriesFromIntegrations(
|
|
33
|
-
|
|
61
|
+
const glReposByOrg = await deps.gitApiService.getOrgRepositoriesFromIntegrations(
|
|
62
|
+
orgName,
|
|
63
|
+
search,
|
|
64
|
+
pageNumber,
|
|
65
|
+
pageSize,
|
|
66
|
+
userTokens
|
|
67
|
+
);
|
|
68
|
+
sortRepos(glReposByOrg.repositories);
|
|
69
|
+
return formatResponse(deps, glReposByOrg, checkStatus);
|
|
34
70
|
}
|
|
35
71
|
function sortRepos(repoList) {
|
|
36
72
|
repoList.sort((a, b) => {
|
|
@@ -88,7 +124,6 @@ async function formatResponse(deps, allReposAccessible, checkStatus) {
|
|
|
88
124
|
errors
|
|
89
125
|
});
|
|
90
126
|
}
|
|
91
|
-
sortRepos(repoList);
|
|
92
127
|
return {
|
|
93
128
|
statusCode: 200,
|
|
94
129
|
responseBody: {
|