renovate 44.84.0 → 44.85.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.
Files changed (36) hide show
  1. package/dist/config/presets/forgejo/index.js +3 -2
  2. package/dist/config/presets/forgejo/index.js.map +1 -1
  3. package/dist/config/presets/gitea/index.js +10 -3
  4. package/dist/config/presets/gitea/index.js.map +1 -1
  5. package/dist/modules/platform/api.js +6 -6
  6. package/dist/modules/platform/forgejo/index.js +21 -587
  7. package/dist/modules/platform/forgejo/index.js.map +1 -1
  8. package/dist/modules/platform/gitea/gitea-helper.js +90 -74
  9. package/dist/modules/platform/gitea/gitea-helper.js.map +1 -1
  10. package/dist/modules/platform/gitea/index.js +561 -529
  11. package/dist/modules/platform/gitea/index.js.map +1 -1
  12. package/dist/modules/platform/gitea/labels.js +42 -0
  13. package/dist/modules/platform/gitea/labels.js.map +1 -0
  14. package/dist/modules/platform/gitea/pr-cache.js +66 -28
  15. package/dist/modules/platform/gitea/pr-cache.js.map +1 -1
  16. package/dist/modules/platform/gitea/schema.js +141 -5
  17. package/dist/modules/platform/gitea/schema.js.map +1 -1
  18. package/dist/modules/platform/gitea/utils.js +10 -8
  19. package/dist/modules/platform/gitea/utils.js.map +1 -1
  20. package/dist/util/cache/repository/types.d.ts +13 -8
  21. package/dist/util/http/forgejo.js +6 -35
  22. package/dist/util/http/forgejo.js.map +1 -1
  23. package/dist/workers/repository/update/pr/changelog/forgejo/index.js +1 -1
  24. package/dist/workers/repository/update/pr/changelog/forgejo/index.js.map +1 -1
  25. package/dist/workers/repository/update/pr/changelog/gitea/index.js +3 -3
  26. package/dist/workers/repository/update/pr/changelog/gitea/index.js.map +1 -1
  27. package/package.json +1 -1
  28. package/renovate-schema.json +2 -2
  29. package/dist/modules/platform/forgejo/forgejo-helper.js +0 -235
  30. package/dist/modules/platform/forgejo/forgejo-helper.js.map +0 -1
  31. package/dist/modules/platform/forgejo/pr-cache.js +0 -114
  32. package/dist/modules/platform/forgejo/pr-cache.js.map +0 -1
  33. package/dist/modules/platform/forgejo/schema.js +0 -149
  34. package/dist/modules/platform/forgejo/schema.js.map +0 -1
  35. package/dist/modules/platform/forgejo/utils.js +0 -115
  36. package/dist/modules/platform/forgejo/utils.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["helper\n .getRepoLabels","helper\n .getOrgLabels","helper.searchRepos","helper.getCurrentUser","helper.getVersion","helper.getRepoContents","helper.getRepo","helper.isOrg","git.initRepo","helper.orgListRepos","git.getBranchCommit","helper.createCommitStatus","helper.renovateToForgejoStatusMapping","helper.getCombinedCommitStatus","helper.forgejoToRenovateStatusMapping","helper.getPR","helper.getPRByBranch","helper.createPR","helper.mergePR","helper.updatePR","helper\n .searchIssues","helper.getIssue","helper.closeIssue","helper.updateIssue","helper.updateIssueLabels","helper.createIssue","helper.unassignLabel","helper.getComments","helper.createComment","helper.updateComment","helper.deleteComment","helper.requestPrReviewers"],"sources":["../../../../lib/modules/platform/forgejo/index.ts"],"sourcesContent":["import { isNumber, isString } from '@sindresorhus/is';\nimport semver from 'semver';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport {\n REPOSITORY_ACCESS_FORBIDDEN,\n REPOSITORY_ARCHIVED,\n REPOSITORY_BLOCKED,\n REPOSITORY_CHANGED,\n REPOSITORY_EMPTY,\n REPOSITORY_MIRRORED,\n} from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport type { BranchStatus } from '../../../types/index.ts';\nimport { coerceArray, deduplicateArray } from '../../../util/array.ts';\nimport { parseJson } from '../../../util/common.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport * as git from '../../../util/git/index.ts';\nimport { setBaseUrl } from '../../../util/http/forgejo.ts';\nimport { map } from '../../../util/promises.ts';\nimport { sanitize } from '../../../util/sanitize.ts';\nimport { ensureTrailingSlash } from '../../../util/url.ts';\nimport { getPrBodyStruct, hashBody } from '../pr-body.ts';\nimport type {\n AutodiscoverConfig,\n BranchStatusConfig,\n CreatePRConfig,\n EnsureCommentConfig,\n EnsureCommentRemovalConfig,\n EnsureIssueConfig,\n FindPRConfig,\n Issue,\n MergePRConfig,\n Platform,\n PlatformParams,\n PlatformResult,\n Pr,\n RepoParams,\n RepoResult,\n RepoSortMethod,\n SortMethod,\n UpdatePrConfig,\n} from '../types.ts';\nimport { repoFingerprint } from '../util.ts';\nimport { smartTruncate } from '../utils/pr-body.ts';\nimport * as helper from './forgejo-helper.ts';\nimport { forgejoHttp } from './forgejo-helper.ts';\nimport { ForgejoPrCache } from './pr-cache.ts';\nimport type { Comment, Label, PRMergeMethod, Repo } from './schema.ts';\nimport type { CombinedCommitStatus, PRUpdateParams } from './types.ts';\nimport {\n DRAFT_PREFIX,\n getMergeMethod,\n getRepoUrl,\n isAllowed,\n smartLinks,\n toRenovatePR,\n trimTrailingApiPath,\n usableRepo,\n} from './utils.ts';\n\ninterface ForgejoRepoConfig {\n ignorePrAuthor: boolean;\n repository: string;\n mergeMethod: PRMergeMethod;\n\n issueList: Promise<Issue[]> | null;\n labelList: Promise<Label[]> | null;\n defaultBranch: string;\n cloneSubmodules: boolean;\n cloneSubmodulesFilter: string[] | undefined;\n hasIssuesEnabled: boolean;\n isOrgRepo: boolean;\n orgName: string;\n}\n\nexport const id = 'forgejo';\n\nconst defaults = {\n hostType: 'forgejo',\n endpoint: 'https://code.forgejo.org/',\n version: '0.0.0',\n};\n\nlet config: ForgejoRepoConfig = {} as any;\nlet botUserID: number;\nlet botUserName: string;\n\nexport function resetPlatform(): void {\n config = {} as any;\n botUserID = undefined as never;\n botUserName = undefined as never;\n defaults.hostType = 'forgejo';\n defaults.endpoint = 'https://code.forgejo.org/';\n defaults.version = '0.0.0';\n setBaseUrl(defaults.endpoint);\n}\n\nfunction toRenovateIssue(data: Issue): Issue {\n return {\n number: data.number,\n state: data.state,\n title: data.title,\n body: data.body,\n };\n}\n\nfunction matchesState(actual: string, expected: string): boolean {\n if (expected === 'all') {\n return true;\n }\n if (expected.startsWith('!')) {\n return actual !== expected.substring(1);\n }\n\n return actual === expected;\n}\n\nfunction findCommentByTopic(\n comments: Comment[],\n topic: string,\n): Comment | null {\n return comments.find((c) => c.body.startsWith(`### ${topic}\\n\\n`)) ?? null;\n}\n\nfunction findCommentByContent(\n comments: Comment[],\n content: string,\n): Comment | null {\n return comments.find((c) => c.body.trim() === content) ?? null;\n}\n\nfunction getLabelList(): Promise<Label[]> {\n if (config.labelList === null) {\n const repoLabels = helper\n .getRepoLabels(config.repository, {\n memCache: false,\n })\n .then((labels) => {\n logger.debug(`Retrieved ${labels.length} repo labels`);\n return labels;\n });\n\n const orgLabels = config.isOrgRepo\n ? helper\n .getOrgLabels(config.orgName, {\n memCache: false,\n })\n .then((labels) => {\n logger.debug(`Retrieved ${labels.length} org labels`);\n return labels;\n })\n .catch((err) => {\n // Will fail if owner of repo is not org\n logger.debug({ err }, `Unable to fetch organization labels`);\n return [] as Label[];\n })\n : Promise.resolve([]);\n\n config.labelList = Promise.all([repoLabels, orgLabels]).then((labels) =>\n ([] as Label[]).concat(...labels),\n );\n }\n\n return config.labelList;\n}\n\nasync function lookupLabelByName(name: string): Promise<number | null> {\n logger.debug(`lookupLabelByName(${name})`);\n const labelList = await getLabelList();\n return labelList.find((l) => l.name === name)?.id ?? null;\n}\n\ninterface FetchRepositoriesArgs {\n topic?: string;\n sort?: RepoSortMethod;\n order?: SortMethod;\n}\n\nasync function fetchRepositories({\n topic,\n sort,\n order,\n}: FetchRepositoriesArgs): Promise<string[]> {\n const repos = await helper.searchRepos({\n uid: botUserID,\n archived: false,\n ...(topic && {\n topic: true,\n q: topic,\n }),\n ...(sort && {\n sort,\n }),\n ...(order && {\n order,\n }),\n });\n return repos.filter(usableRepo).map((r) => r.full_name);\n}\n\nconst platform: Platform = {\n async initPlatform({\n endpoint,\n token,\n }: PlatformParams): Promise<PlatformResult> {\n if (!token) {\n throw new Error(\n 'Init: You must configure a Forgejo personal access token',\n );\n }\n\n if (endpoint) {\n let baseEndpoint = trimTrailingApiPath(endpoint);\n baseEndpoint = ensureTrailingSlash(baseEndpoint);\n defaults.endpoint = baseEndpoint;\n } else {\n logger.debug(`Using default Forgejo endpoint: ${defaults.endpoint}`);\n }\n setBaseUrl(defaults.endpoint);\n\n let gitAuthor: string;\n try {\n const user = await helper.getCurrentUser({ token });\n // oxlint-disable-next-line typescript/prefer-nullish-coalescing -- `full_name` can be emtpy string\n gitAuthor = `${user.full_name || user.login} <${user.email}>`;\n botUserID = user.id;\n botUserName = user.login;\n const env = getEnv();\n /* v8 ignore if: experimental feature */\n if (semver.valid(env.RENOVATE_X_PLATFORM_VERSION)) {\n defaults.version = env.RENOVATE_X_PLATFORM_VERSION!;\n } else {\n defaults.version = await helper.getVersion({ token });\n }\n\n logger.debug(`Forgejo version: ${defaults.version}`);\n } catch (err) {\n logger.debug(\n { err },\n 'Error authenticating with Forgejo. Check your token',\n );\n throw new Error('Init: Authentication failure');\n }\n\n return {\n endpoint: defaults.endpoint,\n gitAuthor,\n };\n },\n\n async getRawFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n ): Promise<string | null> {\n const repo = repoName ?? config.repository;\n const contents = await helper.getRepoContents(repo, fileName, branchOrTag);\n if (contents.type !== 'file') {\n return null;\n }\n return contents.contentString ?? null;\n },\n\n async getJsonFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n ): Promise<any> {\n // TODO #22198\n const raw = await platform.getRawFile(fileName, repoName, branchOrTag);\n return parseJson(raw, fileName);\n },\n\n async initRepo({\n repository,\n cloneSubmodules,\n cloneSubmodulesFilter,\n gitUrl,\n }: RepoParams): Promise<RepoResult> {\n let repo: Repo;\n\n config = {} as any;\n config.repository = repository;\n config.cloneSubmodules = !!cloneSubmodules;\n config.cloneSubmodulesFilter = cloneSubmodulesFilter;\n config.ignorePrAuthor = GlobalConfig.get('ignorePrAuthor');\n\n // Try to fetch information about repository\n try {\n repo = await helper.getRepo(repository);\n } catch (err) {\n logger.debug({ err }, 'Unknown Forgejo initRepo error');\n throw err;\n }\n\n // Ensure appropriate repository state and permissions\n if (repo.archived) {\n logger.debug('Repository is archived - aborting renovation');\n throw new Error(REPOSITORY_ARCHIVED);\n }\n if (repo.mirror) {\n logger.debug('Repository is a mirror - aborting renovation');\n throw new Error(REPOSITORY_MIRRORED);\n }\n if (!repo.permissions.pull || !repo.permissions.push) {\n logger.debug(\n 'Repository does not permit pull or push - aborting renovation',\n );\n throw new Error(REPOSITORY_ACCESS_FORBIDDEN);\n }\n if (repo.empty) {\n logger.debug('Repository is empty - aborting renovation');\n throw new Error(REPOSITORY_EMPTY);\n }\n\n if (repo.has_pull_requests === false) {\n logger.debug('Repo has disabled pull requests - aborting renovation');\n throw new Error(REPOSITORY_BLOCKED);\n }\n\n // similar to forgejo behaviour- if default merge style is allowed, use this;\n // else fall back to predefined order. Order chosen to minimize commits - see\n // https://github.com/renovatebot/renovate/pull/37768 for discussion.\n const preferredOrder: PRMergeMethod[] = [\n ...(repo.default_merge_style ? [repo.default_merge_style] : []),\n 'fast-forward-only',\n 'squash',\n 'merge',\n 'rebase',\n 'rebase-merge',\n ];\n\n const mergeStyle = preferredOrder.find((style) => isAllowed(style, repo));\n\n if (mergeStyle) {\n config.mergeMethod = mergeStyle;\n } else {\n logger.debug(\n 'Repository has no allowed merge methods - aborting renovation',\n );\n throw new Error(REPOSITORY_BLOCKED);\n }\n\n try {\n config.isOrgRepo = await helper.isOrg(repo.owner.login);\n } catch (err) {\n logger.debug({ err }, 'Forgejo initRepo() error');\n throw err;\n }\n\n // Determine author email and branches\n config.defaultBranch = repo.default_branch;\n logger.debug(`${repository} default branch = ${config.defaultBranch}`);\n\n const url = getRepoUrl(repo, gitUrl, defaults.endpoint);\n\n // Initialize Git storage\n await git.initRepo({\n ...config,\n url,\n });\n\n // Reset cached resources\n config.issueList = null;\n config.labelList = null;\n config.hasIssuesEnabled = !repo.external_tracker && repo.has_issues;\n config.orgName = repo.owner.login;\n\n return {\n defaultBranch: config.defaultBranch,\n isFork: !!repo.fork,\n repoFingerprint: repoFingerprint(repo.id, defaults.endpoint),\n };\n },\n\n async getRepos(config?: AutodiscoverConfig): Promise<string[]> {\n logger.debug('Auto-discovering Forgejo repositories');\n try {\n if (config?.topics) {\n logger.debug({ topics: config.topics }, 'Auto-discovering by topics');\n const fetchRepoArgs: FetchRepositoriesArgs[] = config.topics.map(\n (topic) => {\n return {\n topic,\n sort: config.sort,\n order: config.order,\n };\n },\n );\n const repos = await map(fetchRepoArgs, fetchRepositories);\n return deduplicateArray(repos.flat());\n }\n if (config?.namespaces) {\n logger.debug(\n { namespaces: config.namespaces },\n 'Auto-discovering by organization',\n );\n const repos = await map(\n config.namespaces,\n async (organization: string) => {\n const orgRepos = await helper.orgListRepos(organization);\n return orgRepos\n .filter((r) => !r.mirror && !r.archived)\n .map((r) => r.full_name);\n },\n );\n return deduplicateArray(repos.flat());\n }\n return await fetchRepositories({\n sort: config?.sort,\n order: config?.order,\n });\n } catch (err) {\n logger.error({ err }, 'Forgejo getRepos() error');\n throw err;\n }\n },\n\n async setBranchStatus({\n branchName,\n context,\n description,\n state,\n url: target_url,\n }: BranchStatusConfig): Promise<void> {\n try {\n // Create new status for branch commit\n const branchCommit = git.getBranchCommit(branchName);\n // TODO: check branchCommit\n\n await helper.createCommitStatus(config.repository, branchCommit!, {\n state: helper.renovateToForgejoStatusMapping[state] || 'pending',\n context,\n description,\n ...(target_url && { target_url }),\n });\n\n // Refresh caches by re-fetching commit status for branch\n await helper.getCombinedCommitStatus(config.repository, branchName, {\n memCache: false,\n });\n } catch (err) {\n logger.warn({ err }, 'Failed to set branch status');\n }\n },\n\n async getBranchStatus(\n branchName: string,\n internalChecksAsSuccess: boolean,\n ): Promise<BranchStatus> {\n let ccs: CombinedCommitStatus;\n try {\n ccs = await helper.getCombinedCommitStatus(config.repository, branchName);\n } catch (err) {\n if (err.statusCode === 404) {\n logger.debug(\n 'Received 404 when checking branch status, assuming branch deletion',\n );\n throw new Error(REPOSITORY_CHANGED);\n }\n\n logger.debug('Unknown error when checking branch status');\n throw err;\n }\n\n logger.debug({ ccs }, 'Branch status check result');\n if (\n !internalChecksAsSuccess &&\n ccs.worstStatus === 'success' &&\n ccs.statuses.every((status) => status.context?.startsWith('renovate/'))\n ) {\n logger.debug(\n 'Successful checks are all internal renovate/ checks, so returning \"pending\" branch status',\n );\n return 'yellow';\n }\n\n return helper.forgejoToRenovateStatusMapping[ccs.worstStatus];\n },\n\n async getBranchStatusCheck(\n branchName: string,\n context: string,\n ): Promise<BranchStatus | null> {\n const ccs = await helper.getCombinedCommitStatus(\n config.repository,\n branchName,\n );\n const cs = ccs.statuses.find((s) => s.context === context);\n if (!cs) {\n return null;\n } // no status check exists\n return helper.forgejoToRenovateStatusMapping[cs.status];\n },\n\n getPrList(): Promise<Pr[]> {\n return ForgejoPrCache.getPrs(\n forgejoHttp,\n config.repository,\n config.ignorePrAuthor,\n botUserName,\n );\n },\n\n async getPr(number: number): Promise<Pr | null> {\n // Search for pull request in cached list or attempt to query directly\n const prList = await platform.getPrList();\n let pr = prList.find((p) => p.number === number) ?? null;\n if (pr) {\n logger.debug('Returning from cached PRs');\n } else {\n logger.debug('PR not found in cached PRs - trying to fetch directly');\n const gpr = await helper.getPR(config.repository, number);\n pr = toRenovatePR(gpr, botUserName);\n\n // Add pull request to cache for further lookups / queries\n if (pr) {\n await ForgejoPrCache.setPr(\n forgejoHttp,\n config.repository,\n config.ignorePrAuthor,\n botUserName,\n pr,\n );\n }\n }\n\n // Abort and return null if no match was found\n if (!pr) {\n return null;\n }\n\n return pr;\n },\n\n async findPr({\n branchName,\n prTitle: title,\n state = 'all',\n includeOtherAuthors,\n targetBranch,\n }: FindPRConfig): Promise<Pr | null> {\n logger.debug(`findPr(${branchName}, ${title!}, ${state})`);\n if (includeOtherAuthors && isString(targetBranch)) {\n // do not use pr cache as it only fetches prs created by the Renovate account\n const pr = await helper.getPRByBranch(\n config.repository,\n targetBranch,\n branchName,\n );\n if (!pr) {\n return null;\n }\n\n return toRenovatePR(pr, null);\n }\n const prList = await platform.getPrList();\n const pr = prList.find(\n (p) =>\n p.sourceRepo === config.repository &&\n p.sourceBranch === branchName &&\n matchesState(p.state, state) &&\n (!title || p.title === title),\n );\n\n if (pr) {\n logger.debug(`Found PR #${pr.number}`);\n }\n return pr ?? null;\n },\n\n async createPr({\n sourceBranch,\n targetBranch,\n prTitle,\n prBody: rawBody,\n labels: labelNames,\n platformPrOptions,\n draftPR,\n }: CreatePRConfig): Promise<Pr> {\n let title = prTitle;\n const base = targetBranch;\n const head = sourceBranch;\n const body = sanitize(rawBody);\n if (draftPR) {\n title = DRAFT_PREFIX + title;\n }\n\n logger.debug(`Creating pull request: ${title} (${head} => ${base})`);\n try {\n const labels = Array.isArray(labelNames)\n ? await map(labelNames, lookupLabelByName)\n : [];\n const gpr = await helper.createPR(config.repository, {\n base,\n head,\n title,\n body,\n labels: labels.filter(isNumber),\n });\n\n if (platformPrOptions?.usePlatformAutomerge) {\n // Only Forgejo v10.0.0+ support delete_branch_after_merge.\n // This is required to not have undesired behavior when renovate finds existing branches on next run.\n // Codeberg usees git versioning like `11.0.1-99-c504062+gitea-1.22.0` so allow any version >= 10.0.0-0.\n if (semver.gte(defaults.version, '10.0.0-0')) {\n try {\n await helper.mergePR(config.repository, gpr.number, {\n Do:\n getMergeMethod(platformPrOptions?.automergeStrategy) ??\n config.mergeMethod,\n merge_when_checks_succeed: true,\n delete_branch_after_merge: true,\n });\n\n logger.debug(\n { prNumber: gpr.number },\n 'Forgejo-native automerge: success',\n );\n } catch (err) {\n logger.warn(\n { err, prNumber: gpr.number },\n 'Forgejo-native automerge: fail',\n );\n }\n } else {\n logger.debug(\n { prNumber: gpr.number },\n `Forgejo-native automerge: not supported on this version of Forgejo. Use 10.0.0 or newer.`,\n );\n }\n }\n\n const pr = toRenovatePR(gpr, botUserName);\n if (!pr) {\n throw new Error('Can not parse newly created Pull Request');\n }\n\n await ForgejoPrCache.setPr(\n forgejoHttp,\n config.repository,\n config.ignorePrAuthor,\n botUserName,\n pr,\n );\n return pr;\n } catch (err) {\n // When the user manually deletes a branch from Renovate, the PR remains but is no longer linked to any branch. In\n // the most recent versions of Forgejo, the PR gets automatically closed when that happens, but older versions do\n // not handle this properly and keep the PR open. As pushing a branch with the same name resurrects the PR, this\n // would cause a HTTP 409 conflict error, which we hereby gracefully handle.\n if (err.statusCode === 409) {\n logger.warn(\n { prTitle: title, sourceBranch },\n 'Attempting to gracefully recover from 409 Conflict response in createPr()',\n );\n\n // Refresh cached PR list and search for pull request with matching information\n ForgejoPrCache.forceSync();\n const pr = await platform.findPr({\n branchName: sourceBranch,\n state: 'open',\n });\n\n // If a valid PR was found, return and gracefully recover from the error. Otherwise, abort and throw error.\n // v8 ignore else -- TODO: add test #40625\n if (pr?.bodyStruct) {\n if (pr.title !== title || pr.bodyStruct.hash !== hashBody(body)) {\n logger.debug(\n `Recovered from 409 Conflict, but PR for ${sourceBranch} is outdated. Updating...`,\n );\n await platform.updatePr({\n number: pr.number,\n prTitle: title,\n prBody: body,\n });\n pr.title = title;\n pr.bodyStruct = getPrBodyStruct(body);\n } else {\n logger.debug(\n `Recovered from 409 Conflict and PR for ${sourceBranch} is up-to-date`,\n );\n }\n\n return pr;\n }\n }\n\n throw err;\n }\n },\n\n async updatePr({\n number,\n prTitle,\n prBody: body,\n labels,\n state,\n targetBranch,\n }: UpdatePrConfig): Promise<void> {\n let title = prTitle;\n if ((await getPrList()).find((pr) => pr.number === number)?.isDraft) {\n title = DRAFT_PREFIX + title;\n }\n\n const prUpdateParams: PRUpdateParams = {\n title,\n ...(body && { body }),\n ...(state && { state }),\n };\n if (targetBranch) {\n prUpdateParams.base = targetBranch;\n }\n\n /**\n * Update PR labels.\n * In the Forgejo API, labels are replaced on each update if the field is present.\n * If the field is not present (i.e., undefined), labels aren't updated.\n * However, the labels array must contain label IDs instead of names,\n * so a lookup is performed to fetch the details (including the ID) of each label.\n */\n if (Array.isArray(labels)) {\n prUpdateParams.labels = (await map(labels, lookupLabelByName)).filter(\n isNumber,\n );\n if (labels.length !== prUpdateParams.labels.length) {\n logger.warn(\n 'Some labels could not be looked up. Renovate may halt label updates assuming changes by others.',\n );\n }\n }\n\n const gpr = await helper.updatePR(\n config.repository,\n number,\n prUpdateParams,\n );\n const pr = toRenovatePR(gpr, botUserName);\n if (pr) {\n await ForgejoPrCache.setPr(\n forgejoHttp,\n config.repository,\n config.ignorePrAuthor,\n botUserName,\n pr,\n );\n }\n },\n\n async mergePr({ id, strategy }: MergePRConfig): Promise<boolean> {\n try {\n await helper.mergePR(config.repository, id, {\n Do: getMergeMethod(strategy) ?? config.mergeMethod,\n });\n return true;\n } catch (err) {\n logger.warn({ err, id }, 'Merging of PR failed');\n return false;\n }\n },\n\n getIssueList(): Promise<Issue[]> {\n if (config.hasIssuesEnabled === false) {\n return Promise.resolve([]);\n }\n config.issueList ??= helper\n .searchIssues(config.repository, { state: 'all' }, { memCache: false })\n .then((issues) => {\n const issueList = issues.map(toRenovateIssue);\n logger.debug(`Retrieved ${issueList.length} Issues`);\n return issueList;\n });\n\n return config.issueList;\n },\n\n async getIssue(number: number, memCache = true): Promise<Issue | null> {\n if (config.hasIssuesEnabled === false) {\n return null;\n }\n try {\n const body = (\n await helper.getIssue(config.repository, number, { memCache })\n ).body;\n return {\n number,\n body,\n };\n } catch (err) {\n logger.debug({ err, number }, 'Error getting issue');\n return null;\n }\n },\n\n async findIssue(title: string): Promise<Issue | null> {\n const issueList = await platform.getIssueList();\n const issue = issueList.find(\n (i) => i.state === 'open' && i.title === title,\n );\n\n if (!issue) {\n return null;\n }\n // TODO: types (#22198)\n logger.debug(`Found Issue #${issue.number!}`);\n // TODO #22198\n return getIssue!(issue.number!);\n },\n\n async ensureIssue({\n title,\n reuseTitle,\n body: content,\n labels: labelNames,\n shouldReOpen,\n once,\n }: EnsureIssueConfig): Promise<'updated' | 'created' | null> {\n logger.debug(`ensureIssue(${title})`);\n if (config.hasIssuesEnabled === false) {\n logger.info(\n 'Cannot ensure issue because issues are disabled in this repository',\n );\n return null;\n }\n try {\n const body = smartLinks(content);\n\n const issueList = await platform.getIssueList();\n let issues = issueList.filter((i) => i.title === title);\n if (!issues.length) {\n issues = issueList.filter((i) => i.title === reuseTitle);\n }\n\n const labels = Array.isArray(labelNames)\n ? (await Promise.all(labelNames.map(lookupLabelByName))).filter(\n isNumber,\n )\n : undefined;\n\n // Update any matching issues which currently exist\n if (issues.length) {\n let activeIssue = issues.find((i) => i.state === 'open');\n\n // If no active issue was found, decide if it shall be skipped, re-opened or updated without state change\n if (!activeIssue) {\n if (once) {\n logger.debug('Issue already closed - skipping update');\n return null;\n }\n if (shouldReOpen) {\n logger.debug('Reopening previously closed Issue');\n }\n\n // Pick the last issue in the list as the active one\n activeIssue = issues.at(-1)!;\n }\n\n // Close any duplicate issues\n for (const issue of issues) {\n if (issue.state === 'open' && issue.number !== activeIssue.number) {\n // TODO: types (#22198)\n logger.warn({ issueNo: issue.number! }, 'Closing duplicate issue');\n // TODO #22198\n await helper.closeIssue(config.repository, issue.number!);\n }\n }\n\n // Check if issue has already correct state\n if (\n activeIssue.title === title &&\n activeIssue.body === body &&\n activeIssue.state === 'open'\n ) {\n logger.debug(\n // TODO: types (#22198)\n `Issue #${activeIssue.number!} is open and up to date - nothing to do`,\n );\n return null;\n }\n\n if (shouldReOpen || activeIssue.state === 'open') {\n // Update issue body and re-open\n logger.debug(`Updating Issue #${activeIssue.number}`);\n const existingIssue = await helper.updateIssue(\n config.repository,\n // TODO #22198\n activeIssue.number!,\n {\n body,\n title,\n state: 'open',\n },\n );\n\n // Test whether the issues need to be updated\n const existingLabelIds = coerceArray(existingIssue.labels).map(\n (label) => label.id,\n );\n if (\n labels &&\n (labels.length !== existingLabelIds.length ||\n labels.filter((labelId) => !existingLabelIds.includes(labelId))\n .length !== 0)\n ) {\n await helper.updateIssueLabels(\n config.repository,\n // TODO #22198\n activeIssue.number!,\n {\n labels,\n },\n );\n }\n\n return 'updated';\n }\n }\n\n // Create new issue and reset cache\n const issue = await helper.createIssue(config.repository, {\n body,\n title,\n labels,\n });\n logger.debug(`Created new Issue #${issue.number}`);\n config.issueList = null;\n\n return 'created';\n } catch (err) {\n logger.warn({ err }, 'Could not ensure issue');\n }\n\n return null;\n },\n\n async ensureIssueClosing(title: string): Promise<void> {\n logger.debug(`ensureIssueClosing(${title})`);\n if (config.hasIssuesEnabled === false) {\n return;\n }\n const issueList = await platform.getIssueList();\n for (const issue of issueList) {\n if (issue.state === 'open' && issue.title === title) {\n logger.debug(`Closing issue...issueNo: ${issue.number!}`);\n // TODO #22198\n await helper.closeIssue(config.repository, issue.number!);\n }\n }\n },\n\n async deleteLabel(issue: number, labelName: string): Promise<void> {\n logger.debug(`Deleting label ${labelName} from Issue #${issue}`);\n const label = await lookupLabelByName(labelName);\n if (label) {\n await helper.unassignLabel(config.repository, issue, label);\n } else {\n logger.warn({ issue, labelName }, 'Failed to lookup label for deletion');\n }\n },\n\n async ensureComment({\n number: issue,\n topic,\n content,\n }: EnsureCommentConfig): Promise<boolean> {\n try {\n let body = sanitize(content);\n const commentList = await helper.getComments(config.repository, issue);\n\n // Search comment by either topic or exact body\n let comment: Comment | null = null;\n if (topic) {\n comment = findCommentByTopic(commentList, topic);\n body = `### ${topic}\\n\\n${body}`;\n } else {\n comment = findCommentByContent(commentList, body);\n }\n\n // Create a new comment if no match has been found, otherwise update if necessary\n if (!comment) {\n comment = await helper.createComment(config.repository, issue, body);\n logger.info(\n { repository: config.repository, issue, comment: comment.id },\n 'Comment added',\n );\n } else if (comment.body === body) {\n logger.debug(`Comment #${comment.id} is already up-to-date`);\n } else {\n await helper.updateComment(config.repository, comment.id, body);\n logger.debug(\n { repository: config.repository, issue, comment: comment.id },\n 'Comment updated',\n );\n }\n\n return true;\n } catch (err) {\n logger.warn({ err, issue, subject: topic }, 'Error ensuring comment');\n return false;\n }\n },\n\n async ensureCommentRemoval(\n deleteConfig: EnsureCommentRemovalConfig,\n ): Promise<void> {\n const { number: issue } = deleteConfig;\n const key =\n deleteConfig.type === 'by-topic'\n ? deleteConfig.topic\n : deleteConfig.content;\n logger.debug(`Ensuring comment \"${key}\" in #${issue} is removed`);\n const commentList = await helper.getComments(config.repository, issue);\n\n let comment: Comment | null = null;\n // v8 ignore else -- TODO: add test #40625\n if (deleteConfig.type === 'by-topic') {\n comment = findCommentByTopic(commentList, deleteConfig.topic);\n } else if (deleteConfig.type === 'by-content') {\n const body = sanitize(deleteConfig.content);\n comment = findCommentByContent(commentList, body);\n }\n\n // Abort and do nothing if no matching comment was found\n if (!comment) {\n return;\n }\n\n // Try to delete comment\n try {\n await helper.deleteComment(config.repository, comment.id);\n } catch (err) {\n logger.warn(\n { err, issue, config: deleteConfig },\n 'Error deleting comment',\n );\n }\n },\n\n async getBranchPr(branchName: string): Promise<Pr | null> {\n logger.debug(`getBranchPr(${branchName})`);\n const pr = await platform.findPr({ branchName, state: 'open' });\n return pr ? platform.getPr(pr.number) : null;\n },\n\n async addAssignees(number: number, assignees: string[]): Promise<void> {\n logger.debug(\n `Updating assignees '${assignees?.join(', ')}' on Issue #${number}`,\n );\n await helper.updateIssue(config.repository, number, {\n assignees,\n });\n },\n\n async addReviewers(number: number, reviewers: string[]): Promise<void> {\n logger.debug(`Adding reviewers '${reviewers?.join(', ')}' to #${number}`);\n try {\n const teamReviewers = new Set(\n reviewers\n .filter((r) => r.startsWith('team:'))\n .map((r) => r.substring(5)),\n );\n const userReviewers = new Set(\n reviewers.filter((r) => !r.startsWith('team:')),\n );\n\n await helper.requestPrReviewers(config.repository, number, {\n reviewers: [...userReviewers],\n ...(teamReviewers.size && {\n team_reviewers: [...teamReviewers],\n }),\n });\n } catch (err) {\n logger.warn({ err, number, reviewers }, 'Failed to assign reviewer');\n }\n },\n\n massageMarkdown(prBody: string): string {\n return smartTruncate(smartLinks(prBody), maxBodyLength());\n },\n\n maxBodyLength,\n};\n\nexport function maxBodyLength(): number {\n return 1000000;\n}\n\n/* oxlint-disable typescript/unbound-method */\nexport const {\n addAssignees,\n addReviewers,\n createPr,\n deleteLabel,\n ensureComment,\n ensureCommentRemoval,\n ensureIssue,\n ensureIssueClosing,\n findIssue,\n findPr,\n getBranchPr,\n getBranchStatus,\n getBranchStatusCheck,\n getIssue,\n getRawFile,\n getJsonFile,\n getIssueList,\n getPr,\n massageMarkdown,\n getPrList,\n getRepos,\n initPlatform,\n initRepo,\n mergePr,\n setBranchStatus,\n updatePr,\n} = platform;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/modules/platform/forgejo/index.ts"],"sourcesContent":["import semver from 'semver';\nimport { logger } from '../../../logger/index.ts';\nimport { ForgejoHttp, setBaseUrl } from '../../../util/http/forgejo.ts';\nimport { createPlatform } from '../gitea/index.ts';\n\nexport const id = 'forgejo';\n\nexport const forgejoHttp = new ForgejoHttp();\n\nfunction logDetectedVersion(version: string): void {\n logger.debug(`Forgejo version: ${version}`);\n}\n\nfunction checkNativeAutomerge(version: string): string | null {\n // Only Forgejo v10.0.0+ supports delete_branch_after_merge.\n // Codeberg uses git versioning like `11.0.1-99-c504062+gitea-1.22.0` so allow any version >= 10.0.0-0.\n if (semver.gte(version, '10.0.0-0')) {\n return null;\n }\n return `Forgejo-native automerge: not supported on this version of Forgejo. Use 10.0.0 or newer.`;\n}\n\nconst { platform, resetPlatform } = createPlatform({\n id,\n defaultEndpoint: 'https://code.forgejo.org/',\n http: forgejoHttp,\n setBaseUrl,\n logDetectedVersion,\n checkNativeAutomerge,\n});\n\nexport { resetPlatform };\n\n/* oxlint-disable typescript/unbound-method */\nexport const {\n addAssignees,\n addReviewers,\n createPr,\n deleteLabel,\n ensureComment,\n ensureCommentRemoval,\n ensureIssue,\n ensureIssueClosing,\n findIssue,\n findPr,\n getBranchPr,\n getBranchStatus,\n getBranchStatusCheck,\n getIssue,\n getRawFile,\n getJsonFile,\n getIssueList,\n getPr,\n massageMarkdown,\n maxBodyLength,\n getPrList,\n getRepos,\n initPlatform,\n initRepo,\n mergePr,\n setBranchStatus,\n updatePr,\n} = platform;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,MAAa,KAAK;AAElB,MAAa,cAAc,IAAI,YAAY;AAE3C,SAAS,mBAAmB,SAAuB;CACjD,OAAO,MAAM,oBAAoB,SAAS;AAC5C;AAEA,SAAS,qBAAqB,SAAgC;CAG5D,IAAI,OAAO,IAAI,SAAS,UAAU,GAChC,OAAO;CAET,OAAO;AACT;AAEA,MAAM,EAAE,UAAU,kBAAkB,eAAe;CACjD;CACA,iBAAiB;CACjB,MAAM;CACN;CACA;CACA;AACF,CAAC;AAKD,MAAa,EACX,cACA,cACA,UACA,aACA,eACA,sBACA,aACA,oBACA,WACA,QACA,aACA,iBACA,sBACA,UACA,YACA,aACA,cACA,OACA,iBACA,eACA,WACA,UACA,cACA,UACA,SACA,iBACA,aACE"}
@@ -1,10 +1,11 @@
1
- import { fromBase64 } from "../../../util/string.js";
2
1
  import { logger } from "../../../logger/index.js";
3
2
  import { getQueryString } from "../../../util/url.js";
4
- import { GiteaHttp } from "../../../util/http/gitea.js";
3
+ import { getCache } from "../../../util/cache/repository/index.js";
4
+ import { Comment, CommitStatus, Issue, Label, PR, Repo, RepoContents, RepoSearchResults, User, Version } from "./schema.js";
5
5
  import { API_PATH } from "./utils.js";
6
+ import { isBoolean } from "@sindresorhus/is";
7
+ import { z } from "zod/v4";
6
8
  //#region lib/modules/platform/gitea/gitea-helper.ts
7
- const giteaHttp = new GiteaHttp();
8
9
  function urlEscape(raw) {
9
10
  return encodeURIComponent(raw);
10
11
  }
@@ -16,170 +17,185 @@ const commitStatusStates = [
16
17
  "failure",
17
18
  "error"
18
19
  ];
19
- async function getCurrentUser(options) {
20
+ async function getCurrentUser(http, options = {}) {
20
21
  const url = `${API_PATH}/user`;
21
- return (await giteaHttp.getJsonUnchecked(url, options)).body;
22
+ return (await http.getJson(url, options, User)).body;
22
23
  }
23
- async function getVersion(options) {
24
+ async function getVersion(http, options = {}) {
24
25
  const url = `${API_PATH}/version`;
25
- return (await giteaHttp.getJsonUnchecked(url, options)).body.version;
26
+ return (await http.getJson(url, options, Version)).body.version;
27
+ }
28
+ async function isOrg(http, platform, organization) {
29
+ const repoCache = getCache();
30
+ repoCache.platform ??= {};
31
+ const platformCache = repoCache.platform[platform] ??= {};
32
+ platformCache.orgs ??= {};
33
+ const cached = platformCache.orgs[organization];
34
+ if (isBoolean(cached)) return cached;
35
+ try {
36
+ const url = `${API_PATH}/orgs/${organization}`;
37
+ const res = await http.getJsonUnchecked(url);
38
+ platformCache.orgs[organization] = res.statusCode === 200;
39
+ return res.statusCode === 200;
40
+ } catch (err) {
41
+ if (err.statusCode === 404) return false;
42
+ throw err;
43
+ }
26
44
  }
27
- async function searchRepos(params, options) {
45
+ async function searchRepos(http, params, options) {
28
46
  const query = getQueryString(params);
29
47
  const url = `${API_PATH}/repos/search?${query}`;
30
- const res = await giteaHttp.getJsonUnchecked(url, {
48
+ const res = await http.getJson(url, {
31
49
  ...options,
32
50
  paginate: true
33
- });
51
+ }, RepoSearchResults);
34
52
  if (!res.body.ok) throw new Error("Unable to search for repositories, ok flag has not been set");
35
53
  return res.body.data;
36
54
  }
37
- async function orgListRepos(organization, options) {
55
+ async function orgListRepos(http, organization, options) {
38
56
  const url = `${API_PATH}/orgs/${organization}/repos`;
39
- return (await giteaHttp.getJsonUnchecked(url, {
57
+ return (await http.getJson(url, {
40
58
  ...options,
41
59
  paginate: true
42
- })).body;
60
+ }, z.array(Repo))).body;
43
61
  }
44
- async function getRepo(repoPath, options) {
62
+ async function getRepo(http, repoPath, options = {}) {
45
63
  const url = `${API_PATH}/repos/${repoPath}`;
46
- return (await giteaHttp.getJsonUnchecked(url, options)).body;
64
+ return (await http.getJson(url, options, Repo)).body;
47
65
  }
48
- async function getRepoContents(repoPath, filePath, ref, options) {
66
+ async function getRepoContents(http, repoPath, filePath, ref, options = {}) {
49
67
  const query = getQueryString(ref ? { ref } : {});
50
68
  const url = `${API_PATH}/repos/${repoPath}/contents/${urlEscape(filePath)}?${query}`;
51
- const res = await giteaHttp.getJsonUnchecked(url, options);
52
- if (res.body.content) res.body.contentString = fromBase64(res.body.content);
53
- return res.body;
69
+ return (await http.getJson(url, options, RepoContents)).body;
54
70
  }
55
- async function createPR(repoPath, params, options) {
71
+ async function createPR(http, repoPath, params, options) {
56
72
  const url = `${API_PATH}/repos/${repoPath}/pulls`;
57
- return (await giteaHttp.postJson(url, {
73
+ return (await http.postJson(url, {
58
74
  ...options,
59
75
  body: params
60
- })).body;
76
+ }, PR)).body;
61
77
  }
62
- async function updatePR(repoPath, idx, params, options) {
78
+ async function updatePR(http, repoPath, idx, params, options) {
63
79
  const url = `${API_PATH}/repos/${repoPath}/pulls/${idx}`;
64
- return (await giteaHttp.patchJson(url, {
80
+ return (await http.patchJson(url, {
65
81
  ...options,
66
82
  body: params
67
- })).body;
83
+ }, PR)).body;
68
84
  }
69
- async function mergePR(repoPath, idx, params, options) {
85
+ async function mergePR(http, repoPath, idx, params, options) {
70
86
  const url = `${API_PATH}/repos/${repoPath}/pulls/${idx}/merge`;
71
- await giteaHttp.postJson(url, {
87
+ await http.postJson(url, {
72
88
  ...options,
73
89
  body: params
74
90
  });
75
91
  }
76
- async function getPR(repoPath, idx, options) {
92
+ async function getPR(http, repoPath, idx, options = {}) {
77
93
  const url = `${API_PATH}/repos/${repoPath}/pulls/${idx}`;
78
- return (await giteaHttp.getJsonUnchecked(url, options)).body;
94
+ return (await http.getJson(url, options, PR)).body;
79
95
  }
80
- async function getPRByBranch(repoPath, base, head, options) {
96
+ async function getPRByBranch(http, repoPath, base, head, options = {}) {
81
97
  const url = `${API_PATH}/repos/${repoPath}/pulls/${base}/${head}`;
82
98
  try {
83
- return (await giteaHttp.getJsonUnchecked(url, options)).body;
99
+ return (await http.getJson(url, options, PR)).body;
84
100
  } catch (err) {
85
101
  logger.trace({ err }, "Error while fetching PR");
86
102
  if (err.statusCode !== 404) logger.debug({ err }, "Error while fetching PR");
87
103
  return null;
88
104
  }
89
105
  }
90
- async function requestPrReviewers(repoPath, idx, params, options) {
106
+ async function requestPrReviewers(http, repoPath, idx, params, options) {
91
107
  const url = `${API_PATH}/repos/${repoPath}/pulls/${idx}/requested_reviewers`;
92
- await giteaHttp.postJson(url, {
108
+ await http.postJson(url, {
93
109
  ...options,
94
110
  body: params
95
111
  });
96
112
  }
97
- async function createIssue(repoPath, params, options) {
113
+ async function createIssue(http, repoPath, params, options) {
98
114
  const url = `${API_PATH}/repos/${repoPath}/issues`;
99
- return (await giteaHttp.postJson(url, {
115
+ return (await http.postJson(url, {
100
116
  ...options,
101
117
  body: params
102
- })).body;
118
+ }, Issue)).body;
103
119
  }
104
- async function updateIssue(repoPath, idx, params, options) {
120
+ async function updateIssue(http, repoPath, idx, params, options) {
105
121
  const url = `${API_PATH}/repos/${repoPath}/issues/${idx}`;
106
- return (await giteaHttp.patchJson(url, {
122
+ return (await http.patchJson(url, {
107
123
  ...options,
108
124
  body: params
109
- })).body;
125
+ }, Issue)).body;
110
126
  }
111
- async function updateIssueLabels(repoPath, idx, params, options) {
127
+ async function updateIssueLabels(http, repoPath, idx, params, options) {
112
128
  const url = `${API_PATH}/repos/${repoPath}/issues/${idx}/labels`;
113
- return (await giteaHttp.putJson(url, {
129
+ return (await http.putJson(url, {
114
130
  ...options,
115
131
  body: params
116
- })).body;
132
+ }, z.array(Label))).body;
117
133
  }
118
- async function closeIssue(repoPath, idx, options) {
119
- await updateIssue(repoPath, idx, {
134
+ async function closeIssue(http, repoPath, idx, options) {
135
+ await updateIssue(http, repoPath, idx, {
120
136
  ...options,
121
137
  state: "closed"
122
138
  });
123
139
  }
124
- async function searchIssues(repoPath, params, options) {
140
+ async function searchIssues(http, repoPath, params, options) {
125
141
  const query = getQueryString({
126
142
  ...params,
127
143
  type: "issues"
128
144
  });
129
145
  const url = `${API_PATH}/repos/${repoPath}/issues?${query}`;
130
- return (await giteaHttp.getJsonUnchecked(url, {
146
+ return (await http.getJson(url, {
131
147
  ...options,
132
148
  paginate: true
133
- })).body;
149
+ }, z.array(Issue))).body;
134
150
  }
135
- async function getIssue(repoPath, idx, options) {
151
+ async function getIssue(http, repoPath, idx, options = {}) {
136
152
  const url = `${API_PATH}/repos/${repoPath}/issues/${idx}`;
137
- return (await giteaHttp.getJsonUnchecked(url, options)).body;
153
+ return (await http.getJson(url, options, Issue)).body;
138
154
  }
139
- async function getRepoLabels(repoPath, options) {
155
+ async function getRepoLabels(http, repoPath, options = {}) {
140
156
  const url = `${API_PATH}/repos/${repoPath}/labels`;
141
- return (await giteaHttp.getJsonUnchecked(url, options)).body;
157
+ return (await http.getJson(url, options, z.array(Label))).body;
142
158
  }
143
- async function getOrgLabels(orgName, options) {
159
+ async function getOrgLabels(http, orgName, options = {}) {
144
160
  const url = `${API_PATH}/orgs/${orgName}/labels`;
145
- return (await giteaHttp.getJsonUnchecked(url, options)).body;
161
+ return (await http.getJson(url, options, z.array(Label))).body;
146
162
  }
147
- async function unassignLabel(repoPath, issue, label, options) {
163
+ async function unassignLabel(http, repoPath, issue, label, options) {
148
164
  const url = `${API_PATH}/repos/${repoPath}/issues/${issue}/labels/${label}`;
149
- await giteaHttp.deleteJson(url, options);
165
+ await http.deleteJson(url, options);
150
166
  }
151
- async function createComment(repoPath, issue, body, options) {
167
+ async function createComment(http, repoPath, issue, body, options) {
152
168
  const params = { body };
153
169
  const url = `${API_PATH}/repos/${repoPath}/issues/${issue}/comments`;
154
- return (await giteaHttp.postJson(url, {
170
+ return (await http.postJson(url, {
155
171
  ...options,
156
172
  body: params
157
- })).body;
173
+ }, Comment)).body;
158
174
  }
159
- async function updateComment(repoPath, idx, body, options) {
175
+ async function updateComment(http, repoPath, idx, body, options) {
160
176
  const params = { body };
161
177
  const url = `${API_PATH}/repos/${repoPath}/issues/comments/${idx}`;
162
- return (await giteaHttp.patchJson(url, {
178
+ return (await http.patchJson(url, {
163
179
  ...options,
164
180
  body: params
165
- })).body;
181
+ }, Comment)).body;
166
182
  }
167
- async function deleteComment(repoPath, idx, options) {
183
+ async function deleteComment(http, repoPath, idx, options) {
168
184
  const url = `${API_PATH}/repos/${repoPath}/issues/comments/${idx}`;
169
- await giteaHttp.deleteJson(url, options);
185
+ await http.deleteJson(url, options);
170
186
  }
171
- async function getComments(repoPath, issue, options) {
187
+ async function getComments(http, repoPath, issue, options = {}) {
172
188
  const url = `${API_PATH}/repos/${repoPath}/issues/${issue}/comments`;
173
- return (await giteaHttp.getJsonUnchecked(url, options)).body;
189
+ return (await http.getJson(url, options, z.array(Comment))).body;
174
190
  }
175
- async function createCommitStatus(repoPath, branchCommit, params, options) {
191
+ async function createCommitStatus(http, repoPath, branchCommit, params, options) {
176
192
  const url = `${API_PATH}/repos/${repoPath}/statuses/${branchCommit}`;
177
- return (await giteaHttp.postJson(url, {
193
+ return (await http.postJson(url, {
178
194
  ...options,
179
195
  body: params
180
- })).body;
196
+ }, CommitStatus)).body;
181
197
  }
182
- const giteaToRenovateStatusMapping = {
198
+ const toRenovateStatusMapping = {
183
199
  unknown: "yellow",
184
200
  success: "green",
185
201
  pending: "yellow",
@@ -187,7 +203,7 @@ const giteaToRenovateStatusMapping = {
187
203
  failure: "red",
188
204
  error: "red"
189
205
  };
190
- const renovateToGiteaStatusMapping = {
206
+ const toPlatformStatusMapping = {
191
207
  green: "success",
192
208
  yellow: "pending",
193
209
  red: "failure"
@@ -197,12 +213,12 @@ function filterStatus(data) {
197
213
  for (const i of data) if (!ret[i.context] || ret[i.context].id < i.id) ret[i.context] = i;
198
214
  return Object.values(ret);
199
215
  }
200
- async function getCombinedCommitStatus(repoPath, branchName, options) {
216
+ async function getCombinedCommitStatus(http, repoPath, branchName, options) {
201
217
  const url = `${API_PATH}/repos/${repoPath}/commits/${urlEscape(branchName)}/statuses`;
202
- const res = await giteaHttp.getJsonUnchecked(url, {
218
+ const res = await http.getJson(url, {
203
219
  ...options,
204
220
  paginate: true
205
- });
221
+ }, z.array(CommitStatus));
206
222
  let worstState = 0;
207
223
  const statuses = filterStatus(res.body);
208
224
  for (const cs of statuses) worstState = Math.max(worstState, commitStatusStates.indexOf(cs.status));
@@ -212,6 +228,6 @@ async function getCombinedCommitStatus(repoPath, branchName, options) {
212
228
  };
213
229
  }
214
230
  //#endregion
215
- export { closeIssue, createComment, createCommitStatus, createIssue, createPR, deleteComment, getCombinedCommitStatus, getComments, getCurrentUser, getIssue, getOrgLabels, getPR, getPRByBranch, getRepo, getRepoContents, getRepoLabels, getVersion, giteaHttp, giteaToRenovateStatusMapping, mergePR, orgListRepos, renovateToGiteaStatusMapping, requestPrReviewers, searchIssues, searchRepos, unassignLabel, updateComment, updateIssue, updateIssueLabels, updatePR };
231
+ export { closeIssue, createComment, createCommitStatus, createIssue, createPR, deleteComment, getCombinedCommitStatus, getComments, getCurrentUser, getIssue, getOrgLabels, getPR, getPRByBranch, getRepo, getRepoContents, getRepoLabels, getVersion, isOrg, mergePR, orgListRepos, requestPrReviewers, searchIssues, searchRepos, toPlatformStatusMapping, toRenovateStatusMapping, unassignLabel, updateComment, updateIssue, updateIssueLabels, updatePR };
216
232
 
217
233
  //# sourceMappingURL=gitea-helper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gitea-helper.js","names":[],"sources":["../../../../lib/modules/platform/gitea/gitea-helper.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport type { BranchStatus } from '../../../types/index.ts';\nimport type { GiteaHttpOptions } from '../../../util/http/gitea.ts';\nimport { GiteaHttp } from '../../../util/http/gitea.ts';\nimport { fromBase64 } from '../../../util/string.ts';\nimport { getQueryString } from '../../../util/url.ts';\nimport type {\n Branch,\n CombinedCommitStatus,\n Comment,\n CommentCreateParams,\n CommentUpdateParams,\n CommitStatus,\n CommitStatusCreateParams,\n CommitStatusType,\n Issue,\n IssueCreateParams,\n IssueSearchParams,\n IssueUpdateLabelsParams,\n IssueUpdateParams,\n Label,\n PR,\n PRCreateParams,\n PRMergeParams,\n PRUpdateParams,\n PrReviewersParams,\n Repo,\n RepoContents,\n RepoSearchParams,\n RepoSearchResults,\n User,\n} from './types.ts';\nimport { API_PATH } from './utils.ts';\n\nexport const giteaHttp = new GiteaHttp();\n\nfunction urlEscape(raw: string): string {\n return encodeURIComponent(raw);\n}\nconst commitStatusStates: CommitStatusType[] = [\n 'unknown',\n 'success',\n 'pending',\n 'warning',\n 'failure',\n 'error',\n];\n\nexport async function getCurrentUser(\n options?: GiteaHttpOptions,\n): Promise<User> {\n const url = `${API_PATH}/user`;\n const res = await giteaHttp.getJsonUnchecked<User>(url, options);\n return res.body;\n}\n\nexport async function getVersion(options?: GiteaHttpOptions): Promise<string> {\n const url = `${API_PATH}/version`;\n const res = await giteaHttp.getJsonUnchecked<{ version: string }>(\n url,\n options,\n );\n return res.body.version;\n}\n\nexport async function searchRepos(\n params: RepoSearchParams,\n options?: GiteaHttpOptions,\n): Promise<Repo[]> {\n const query = getQueryString(params);\n const url = `${API_PATH}/repos/search?${query}`;\n const res = await giteaHttp.getJsonUnchecked<RepoSearchResults>(url, {\n ...options,\n paginate: true,\n });\n\n if (!res.body.ok) {\n throw new Error(\n 'Unable to search for repositories, ok flag has not been set',\n );\n }\n\n return res.body.data;\n}\n\nexport async function orgListRepos(\n organization: string,\n options?: GiteaHttpOptions,\n): Promise<Repo[]> {\n const url = `${API_PATH}/orgs/${organization}/repos`;\n const res = await giteaHttp.getJsonUnchecked<Repo[]>(url, {\n ...options,\n paginate: true,\n });\n\n return res.body;\n}\n\nexport async function getRepo(\n repoPath: string,\n options?: GiteaHttpOptions,\n): Promise<Repo> {\n const url = `${API_PATH}/repos/${repoPath}`;\n const res = await giteaHttp.getJsonUnchecked<Repo>(url, options);\n return res.body;\n}\n\nexport async function getRepoContents(\n repoPath: string,\n filePath: string,\n ref?: string | null,\n options?: GiteaHttpOptions,\n): Promise<RepoContents> {\n const query = getQueryString(ref ? { ref } : {});\n const url = `${API_PATH}/repos/${repoPath}/contents/${urlEscape(\n filePath,\n )}?${query}`;\n const res = await giteaHttp.getJsonUnchecked<RepoContents>(url, options);\n\n if (res.body.content) {\n res.body.contentString = fromBase64(res.body.content);\n }\n\n return res.body;\n}\n\nexport async function createPR(\n repoPath: string,\n params: PRCreateParams,\n options?: GiteaHttpOptions,\n): Promise<PR> {\n const url = `${API_PATH}/repos/${repoPath}/pulls`;\n const res = await giteaHttp.postJson<PR>(url, {\n ...options,\n body: params,\n });\n\n return res.body;\n}\n\nexport async function updatePR(\n repoPath: string,\n idx: number,\n params: PRUpdateParams,\n options?: GiteaHttpOptions,\n): Promise<PR> {\n const url = `${API_PATH}/repos/${repoPath}/pulls/${idx}`;\n const res = await giteaHttp.patchJson<PR>(url, {\n ...options,\n body: params,\n });\n\n return res.body;\n}\n\nexport async function closePR(\n repoPath: string,\n idx: number,\n options?: GiteaHttpOptions,\n): Promise<void> {\n await updatePR(repoPath, idx, {\n ...options,\n state: 'closed',\n });\n}\n\nexport async function mergePR(\n repoPath: string,\n idx: number,\n params: PRMergeParams,\n options?: GiteaHttpOptions,\n): Promise<void> {\n const url = `${API_PATH}/repos/${repoPath}/pulls/${idx}/merge`;\n await giteaHttp.postJson(url, {\n ...options,\n body: params,\n });\n}\n\nexport async function getPR(\n repoPath: string,\n idx: number,\n options?: GiteaHttpOptions,\n): Promise<PR> {\n const url = `${API_PATH}/repos/${repoPath}/pulls/${idx}`;\n const res = await giteaHttp.getJsonUnchecked<PR>(url, options);\n return res.body;\n}\n\nexport async function getPRByBranch(\n repoPath: string,\n base: string,\n head: string,\n options?: GiteaHttpOptions,\n): Promise<PR | null> {\n const url = `${API_PATH}/repos/${repoPath}/pulls/${base}/${head}`;\n try {\n const res = await giteaHttp.getJsonUnchecked<PR>(url, options);\n return res.body;\n } catch (err) {\n logger.trace({ err }, 'Error while fetching PR');\n if (err.statusCode !== 404) {\n logger.debug({ err }, 'Error while fetching PR');\n }\n return null;\n }\n}\n\nexport async function requestPrReviewers(\n repoPath: string,\n idx: number,\n params: PrReviewersParams,\n options?: GiteaHttpOptions,\n): Promise<void> {\n const url = `${API_PATH}/repos/${repoPath}/pulls/${idx}/requested_reviewers`;\n await giteaHttp.postJson(url, {\n ...options,\n body: params,\n });\n}\n\nexport async function createIssue(\n repoPath: string,\n params: IssueCreateParams,\n options?: GiteaHttpOptions,\n): Promise<Issue> {\n const url = `${API_PATH}/repos/${repoPath}/issues`;\n const res = await giteaHttp.postJson<Issue>(url, {\n ...options,\n body: params,\n });\n\n return res.body;\n}\n\nexport async function updateIssue(\n repoPath: string,\n idx: number,\n params: IssueUpdateParams,\n options?: GiteaHttpOptions,\n): Promise<Issue> {\n const url = `${API_PATH}/repos/${repoPath}/issues/${idx}`;\n const res = await giteaHttp.patchJson<Issue>(url, {\n ...options,\n body: params,\n });\n\n return res.body;\n}\n\nexport async function updateIssueLabels(\n repoPath: string,\n idx: number,\n params: IssueUpdateLabelsParams,\n options?: GiteaHttpOptions,\n): Promise<Label[]> {\n const url = `${API_PATH}/repos/${repoPath}/issues/${idx}/labels`;\n const res = await giteaHttp.putJson<Label[]>(url, {\n ...options,\n body: params,\n });\n\n return res.body;\n}\n\nexport async function closeIssue(\n repoPath: string,\n idx: number,\n options?: GiteaHttpOptions,\n): Promise<void> {\n await updateIssue(repoPath, idx, {\n ...options,\n state: 'closed',\n });\n}\n\nexport async function searchIssues(\n repoPath: string,\n params: IssueSearchParams,\n options?: GiteaHttpOptions,\n): Promise<Issue[]> {\n const query = getQueryString({ ...params, type: 'issues' });\n const url = `${API_PATH}/repos/${repoPath}/issues?${query}`;\n const res = await giteaHttp.getJsonUnchecked<Issue[]>(url, {\n ...options,\n paginate: true,\n });\n\n return res.body;\n}\n\nexport async function getIssue(\n repoPath: string,\n idx: number,\n options?: GiteaHttpOptions,\n): Promise<Issue> {\n const url = `${API_PATH}/repos/${repoPath}/issues/${idx}`;\n const res = await giteaHttp.getJsonUnchecked<Issue>(url, options);\n return res.body;\n}\n\nexport async function getRepoLabels(\n repoPath: string,\n options?: GiteaHttpOptions,\n): Promise<Label[]> {\n const url = `${API_PATH}/repos/${repoPath}/labels`;\n const res = await giteaHttp.getJsonUnchecked<Label[]>(url, options);\n\n return res.body;\n}\n\nexport async function getOrgLabels(\n orgName: string,\n options?: GiteaHttpOptions,\n): Promise<Label[]> {\n const url = `${API_PATH}/orgs/${orgName}/labels`;\n const res = await giteaHttp.getJsonUnchecked<Label[]>(url, options);\n\n return res.body;\n}\n\nexport async function unassignLabel(\n repoPath: string,\n issue: number,\n label: number,\n options?: GiteaHttpOptions,\n): Promise<void> {\n const url = `${API_PATH}/repos/${repoPath}/issues/${issue}/labels/${label}`;\n await giteaHttp.deleteJson(url, options);\n}\n\nexport async function createComment(\n repoPath: string,\n issue: number,\n body: string,\n options?: GiteaHttpOptions,\n): Promise<Comment> {\n const params: CommentCreateParams = { body };\n const url = `${API_PATH}/repos/${repoPath}/issues/${issue}/comments`;\n const res = await giteaHttp.postJson<Comment>(url, {\n ...options,\n body: params,\n });\n\n return res.body;\n}\n\nexport async function updateComment(\n repoPath: string,\n idx: number,\n body: string,\n options?: GiteaHttpOptions,\n): Promise<Comment> {\n const params: CommentUpdateParams = { body };\n const url = `${API_PATH}/repos/${repoPath}/issues/comments/${idx}`;\n const res = await giteaHttp.patchJson<Comment>(url, {\n ...options,\n body: params,\n });\n\n return res.body;\n}\n\nexport async function deleteComment(\n repoPath: string,\n idx: number,\n options?: GiteaHttpOptions,\n): Promise<void> {\n const url = `${API_PATH}/repos/${repoPath}/issues/comments/${idx}`;\n await giteaHttp.deleteJson(url, options);\n}\n\nexport async function getComments(\n repoPath: string,\n issue: number,\n options?: GiteaHttpOptions,\n): Promise<Comment[]> {\n const url = `${API_PATH}/repos/${repoPath}/issues/${issue}/comments`;\n const res = await giteaHttp.getJsonUnchecked<Comment[]>(url, options);\n\n return res.body;\n}\n\nexport async function createCommitStatus(\n repoPath: string,\n branchCommit: string,\n params: CommitStatusCreateParams,\n options?: GiteaHttpOptions,\n): Promise<CommitStatus> {\n const url = `${API_PATH}/repos/${repoPath}/statuses/${branchCommit}`;\n const res = await giteaHttp.postJson<CommitStatus>(url, {\n ...options,\n body: params,\n });\n\n return res.body;\n}\n\nexport const giteaToRenovateStatusMapping: Record<\n CommitStatusType,\n BranchStatus | null\n> = {\n unknown: 'yellow',\n success: 'green',\n pending: 'yellow',\n warning: 'red',\n failure: 'red',\n error: 'red',\n};\n\nexport const renovateToGiteaStatusMapping: Record<\n BranchStatus,\n CommitStatusType\n> = {\n green: 'success',\n yellow: 'pending',\n red: 'failure',\n};\n\nfunction filterStatus(data: CommitStatus[]): CommitStatus[] {\n const ret: Record<string, CommitStatus> = {};\n for (const i of data) {\n if (!ret[i.context] || ret[i.context].id < i.id) {\n ret[i.context] = i;\n }\n }\n return Object.values(ret);\n}\n\nexport async function getCombinedCommitStatus(\n repoPath: string,\n branchName: string,\n options?: GiteaHttpOptions,\n): Promise<CombinedCommitStatus> {\n const url = `${API_PATH}/repos/${repoPath}/commits/${urlEscape(\n branchName,\n )}/statuses`;\n const res = await giteaHttp.getJsonUnchecked<CommitStatus[]>(url, {\n ...options,\n paginate: true,\n });\n\n let worstState = 0;\n const statuses = filterStatus(res.body);\n for (const cs of statuses) {\n worstState = Math.max(worstState, commitStatusStates.indexOf(cs.status));\n }\n\n return {\n worstStatus: commitStatusStates[worstState],\n statuses,\n };\n}\n\nexport async function getBranch(\n repoPath: string,\n branchName: string,\n options?: GiteaHttpOptions,\n): Promise<Branch> {\n const url = `${API_PATH}/repos/${repoPath}/branches/${urlEscape(branchName)}`;\n const res = await giteaHttp.getJsonUnchecked<Branch>(url, options);\n\n return res.body;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"gitea-helper.js","names":[],"sources":["../../../../lib/modules/platform/gitea/gitea-helper.ts"],"sourcesContent":["import { isBoolean } from '@sindresorhus/is';\nimport { z } from 'zod/v4';\nimport { logger } from '../../../logger/index.ts';\nimport type { BranchStatus } from '../../../types/index.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport type { GiteaHttpOptions } from '../../../util/http/gitea.ts';\nimport { getQueryString } from '../../../util/url.ts';\nimport {\n Branch,\n Comment,\n CommitStatus,\n type CommitStatusType,\n Issue,\n Label,\n PR,\n Repo,\n RepoContents,\n RepoSearchResults,\n User,\n Version,\n} from './schema.ts';\nimport type {\n CombinedCommitStatus,\n CommentCreateParams,\n CommitStatusCreateParams,\n GiteaLikeHttp,\n GiteaPlatformKey,\n IssueCreateParams,\n IssueSearchParams,\n IssueUpdateLabelsParams,\n IssueUpdateParams,\n PRCreateParams,\n PRMergeParams,\n PRUpdateParams,\n PrReviewersParams,\n RepoSearchParams,\n} from './types.ts';\nimport { API_PATH } from './utils.ts';\n\nfunction urlEscape(raw: string): string {\n return encodeURIComponent(raw);\n}\nconst commitStatusStates: CommitStatusType[] = [\n 'unknown',\n 'success',\n 'pending',\n 'warning',\n 'failure',\n 'error',\n];\n\nexport async function getCurrentUser(\n http: GiteaLikeHttp,\n options: GiteaHttpOptions = {},\n): Promise<User> {\n const url = `${API_PATH}/user`;\n const res = await http.getJson(url, options, User);\n return res.body;\n}\n\nexport async function getVersion(\n http: GiteaLikeHttp,\n options: GiteaHttpOptions = {},\n): Promise<string> {\n const url = `${API_PATH}/version`;\n const res = await http.getJson(url, options, Version);\n return res.body.version;\n}\n\nexport async function isOrg(\n http: GiteaLikeHttp,\n platform: GiteaPlatformKey,\n organization: string,\n): Promise<boolean> {\n const repoCache = getCache();\n repoCache.platform ??= {};\n const platformCache = (repoCache.platform[platform] ??= {});\n platformCache.orgs ??= {};\n const cached = platformCache.orgs[organization];\n if (isBoolean(cached)) {\n return cached;\n }\n try {\n const url = `${API_PATH}/orgs/${organization}`;\n const res = await http.getJsonUnchecked(url);\n platformCache.orgs[organization] = res.statusCode === 200;\n return res.statusCode === 200;\n } catch (err) {\n if (err.statusCode === 404) {\n return false;\n }\n // throw other errors\n throw err;\n }\n}\n\nexport async function searchRepos(\n http: GiteaLikeHttp,\n params: RepoSearchParams,\n options?: GiteaHttpOptions,\n): Promise<Repo[]> {\n const query = getQueryString(params);\n const url = `${API_PATH}/repos/search?${query}`;\n const res = await http.getJson(\n url,\n {\n ...options,\n paginate: true,\n },\n RepoSearchResults,\n );\n\n if (!res.body.ok) {\n throw new Error(\n 'Unable to search for repositories, ok flag has not been set',\n );\n }\n\n return res.body.data;\n}\n\nexport async function orgListRepos(\n http: GiteaLikeHttp,\n organization: string,\n options?: GiteaHttpOptions,\n): Promise<Repo[]> {\n const url = `${API_PATH}/orgs/${organization}/repos`;\n const res = await http.getJson(\n url,\n {\n ...options,\n paginate: true,\n },\n z.array(Repo),\n );\n\n return res.body;\n}\n\nexport async function getRepo(\n http: GiteaLikeHttp,\n repoPath: string,\n options: GiteaHttpOptions = {},\n): Promise<Repo> {\n const url = `${API_PATH}/repos/${repoPath}`;\n const res = await http.getJson(url, options, Repo);\n return res.body;\n}\n\nexport async function getRepoContents(\n http: GiteaLikeHttp,\n repoPath: string,\n filePath: string,\n ref?: string | null,\n options: GiteaHttpOptions = {},\n): Promise<RepoContents> {\n const query = getQueryString(ref ? { ref } : {});\n const url = `${API_PATH}/repos/${repoPath}/contents/${urlEscape(\n filePath,\n )}?${query}`;\n const res = await http.getJson(url, options, RepoContents);\n\n return res.body;\n}\n\nexport async function createPR(\n http: GiteaLikeHttp,\n repoPath: string,\n params: PRCreateParams,\n options?: GiteaHttpOptions,\n): Promise<PR> {\n const url = `${API_PATH}/repos/${repoPath}/pulls`;\n const res = await http.postJson(\n url,\n {\n ...options,\n body: params,\n },\n PR,\n );\n\n return res.body;\n}\n\nexport async function updatePR(\n http: GiteaLikeHttp,\n repoPath: string,\n idx: number,\n params: PRUpdateParams,\n options?: GiteaHttpOptions,\n): Promise<PR> {\n const url = `${API_PATH}/repos/${repoPath}/pulls/${idx}`;\n const res = await http.patchJson(\n url,\n {\n ...options,\n body: params,\n },\n PR,\n );\n\n return res.body;\n}\n\nexport async function closePR(\n http: GiteaLikeHttp,\n repoPath: string,\n idx: number,\n options?: GiteaHttpOptions,\n): Promise<void> {\n await updatePR(http, repoPath, idx, {\n ...options,\n state: 'closed',\n });\n}\n\nexport async function mergePR(\n http: GiteaLikeHttp,\n repoPath: string,\n idx: number,\n params: PRMergeParams,\n options?: GiteaHttpOptions,\n): Promise<void> {\n const url = `${API_PATH}/repos/${repoPath}/pulls/${idx}/merge`;\n await http.postJson(url, {\n ...options,\n body: params,\n });\n}\n\nexport async function getPR(\n http: GiteaLikeHttp,\n repoPath: string,\n idx: number,\n options: GiteaHttpOptions = {},\n): Promise<PR> {\n const url = `${API_PATH}/repos/${repoPath}/pulls/${idx}`;\n const res = await http.getJson(url, options, PR);\n return res.body;\n}\n\nexport async function getPRByBranch(\n http: GiteaLikeHttp,\n repoPath: string,\n base: string,\n head: string,\n options: GiteaHttpOptions = {},\n): Promise<PR | null> {\n const url = `${API_PATH}/repos/${repoPath}/pulls/${base}/${head}`;\n try {\n const res = await http.getJson(url, options, PR);\n return res.body;\n } catch (err) {\n logger.trace({ err }, 'Error while fetching PR');\n if (err.statusCode !== 404) {\n logger.debug({ err }, 'Error while fetching PR');\n }\n return null;\n }\n}\n\nexport async function requestPrReviewers(\n http: GiteaLikeHttp,\n repoPath: string,\n idx: number,\n params: PrReviewersParams,\n options?: GiteaHttpOptions,\n): Promise<void> {\n const url = `${API_PATH}/repos/${repoPath}/pulls/${idx}/requested_reviewers`;\n await http.postJson(url, {\n ...options,\n body: params,\n });\n}\n\nexport async function createIssue(\n http: GiteaLikeHttp,\n repoPath: string,\n params: IssueCreateParams,\n options?: GiteaHttpOptions,\n): Promise<Issue> {\n const url = `${API_PATH}/repos/${repoPath}/issues`;\n const res = await http.postJson(\n url,\n {\n ...options,\n body: params,\n },\n Issue,\n );\n\n return res.body;\n}\n\nexport async function updateIssue(\n http: GiteaLikeHttp,\n repoPath: string,\n idx: number,\n params: IssueUpdateParams,\n options?: GiteaHttpOptions,\n): Promise<Issue> {\n const url = `${API_PATH}/repos/${repoPath}/issues/${idx}`;\n const res = await http.patchJson(\n url,\n {\n ...options,\n body: params,\n },\n Issue,\n );\n\n return res.body;\n}\n\nexport async function updateIssueLabels(\n http: GiteaLikeHttp,\n repoPath: string,\n idx: number,\n params: IssueUpdateLabelsParams,\n options?: GiteaHttpOptions,\n): Promise<Label[]> {\n const url = `${API_PATH}/repos/${repoPath}/issues/${idx}/labels`;\n const res = await http.putJson(\n url,\n {\n ...options,\n body: params,\n },\n z.array(Label),\n );\n\n return res.body;\n}\n\nexport async function closeIssue(\n http: GiteaLikeHttp,\n repoPath: string,\n idx: number,\n options?: GiteaHttpOptions,\n): Promise<void> {\n await updateIssue(http, repoPath, idx, {\n ...options,\n state: 'closed',\n });\n}\n\nexport async function searchIssues(\n http: GiteaLikeHttp,\n repoPath: string,\n params: IssueSearchParams,\n options?: GiteaHttpOptions,\n): Promise<Issue[]> {\n const query = getQueryString({ ...params, type: 'issues' });\n const url = `${API_PATH}/repos/${repoPath}/issues?${query}`;\n const res = await http.getJson(\n url,\n {\n ...options,\n paginate: true,\n },\n z.array(Issue),\n );\n\n return res.body;\n}\n\nexport async function getIssue(\n http: GiteaLikeHttp,\n repoPath: string,\n idx: number,\n options: GiteaHttpOptions = {},\n): Promise<Issue> {\n const url = `${API_PATH}/repos/${repoPath}/issues/${idx}`;\n const res = await http.getJson(url, options, Issue);\n return res.body;\n}\n\nexport async function getRepoLabels(\n http: GiteaLikeHttp,\n repoPath: string,\n options: GiteaHttpOptions = {},\n): Promise<Label[]> {\n const url = `${API_PATH}/repos/${repoPath}/labels`;\n const res = await http.getJson(url, options, z.array(Label));\n\n return res.body;\n}\n\nexport async function getOrgLabels(\n http: GiteaLikeHttp,\n orgName: string,\n options: GiteaHttpOptions = {},\n): Promise<Label[]> {\n const url = `${API_PATH}/orgs/${orgName}/labels`;\n const res = await http.getJson(url, options, z.array(Label));\n\n return res.body;\n}\n\nexport async function unassignLabel(\n http: GiteaLikeHttp,\n repoPath: string,\n issue: number,\n label: number,\n options?: GiteaHttpOptions,\n): Promise<void> {\n const url = `${API_PATH}/repos/${repoPath}/issues/${issue}/labels/${label}`;\n await http.deleteJson(url, options);\n}\n\nexport async function createComment(\n http: GiteaLikeHttp,\n repoPath: string,\n issue: number,\n body: string,\n options?: GiteaHttpOptions,\n): Promise<Comment> {\n const params: CommentCreateParams = { body };\n const url = `${API_PATH}/repos/${repoPath}/issues/${issue}/comments`;\n const res = await http.postJson(\n url,\n {\n ...options,\n body: params,\n },\n Comment,\n );\n\n return res.body;\n}\n\nexport async function updateComment(\n http: GiteaLikeHttp,\n repoPath: string,\n idx: number,\n body: string,\n options?: GiteaHttpOptions,\n): Promise<Comment> {\n const params: CommentCreateParams = { body };\n const url = `${API_PATH}/repos/${repoPath}/issues/comments/${idx}`;\n const res = await http.patchJson(\n url,\n {\n ...options,\n body: params,\n },\n Comment,\n );\n\n return res.body;\n}\n\nexport async function deleteComment(\n http: GiteaLikeHttp,\n repoPath: string,\n idx: number,\n options?: GiteaHttpOptions,\n): Promise<void> {\n const url = `${API_PATH}/repos/${repoPath}/issues/comments/${idx}`;\n await http.deleteJson(url, options);\n}\n\nexport async function getComments(\n http: GiteaLikeHttp,\n repoPath: string,\n issue: number,\n options: GiteaHttpOptions = {},\n): Promise<Comment[]> {\n const url = `${API_PATH}/repos/${repoPath}/issues/${issue}/comments`;\n const res = await http.getJson(url, options, z.array(Comment));\n\n return res.body;\n}\n\nexport async function createCommitStatus(\n http: GiteaLikeHttp,\n repoPath: string,\n branchCommit: string,\n params: CommitStatusCreateParams,\n options?: GiteaHttpOptions,\n): Promise<CommitStatus> {\n const url = `${API_PATH}/repos/${repoPath}/statuses/${branchCommit}`;\n const res = await http.postJson(\n url,\n {\n ...options,\n body: params,\n },\n CommitStatus,\n );\n\n return res.body;\n}\n\nexport const toRenovateStatusMapping: Record<CommitStatusType, BranchStatus> = {\n unknown: 'yellow',\n success: 'green',\n pending: 'yellow',\n warning: 'red',\n failure: 'red',\n error: 'red',\n};\n\nexport const toPlatformStatusMapping: Record<BranchStatus, CommitStatusType> = {\n green: 'success',\n yellow: 'pending',\n red: 'failure',\n};\n\nfunction filterStatus(data: CommitStatus[]): CommitStatus[] {\n const ret: Record<string, CommitStatus> = {};\n for (const i of data) {\n if (!ret[i.context] || ret[i.context].id < i.id) {\n ret[i.context] = i;\n }\n }\n return Object.values(ret);\n}\n\nexport async function getCombinedCommitStatus(\n http: GiteaLikeHttp,\n repoPath: string,\n branchName: string,\n options?: GiteaHttpOptions,\n): Promise<CombinedCommitStatus> {\n const url = `${API_PATH}/repos/${repoPath}/commits/${urlEscape(\n branchName,\n )}/statuses`;\n const res = await http.getJson(\n url,\n {\n ...options,\n paginate: true,\n },\n z.array(CommitStatus),\n );\n\n let worstState = 0;\n const statuses = filterStatus(res.body);\n for (const cs of statuses) {\n worstState = Math.max(worstState, commitStatusStates.indexOf(cs.status));\n }\n\n return {\n worstStatus: commitStatusStates[worstState],\n statuses,\n };\n}\n\nexport async function getBranch(\n http: GiteaLikeHttp,\n repoPath: string,\n branchName: string,\n options: GiteaHttpOptions = {},\n): Promise<Branch> {\n const url = `${API_PATH}/repos/${repoPath}/branches/${urlEscape(branchName)}`;\n const res = await http.getJson(url, options, Branch);\n\n return res.body;\n}\n"],"mappings":"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"}