@paklo/core 0.7.3 → 0.9.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/dist/azure/index.d.mts +930 -116
- package/dist/azure/index.mjs +412 -229
- package/dist/azure/index.mjs.map +1 -1
- package/dist/dependabot/index.d.mts +3 -3
- package/dist/dependabot/index.mjs +3 -4
- package/dist/{dependabot-_TVZhG0L.mjs → dependabot-rtPO9HdD.mjs} +21 -14
- package/dist/dependabot-rtPO9HdD.mjs.map +1 -0
- package/dist/github/index.d.mts +1 -1
- package/dist/github/index.mjs +1 -1
- package/dist/{index-BWftXTYB.d.mts → index-BfwWezjJ.d.mts} +1 -1
- package/dist/{index-vaaBSJ7v.d.mts → index-Byxjhvfz.d.mts} +67 -59
- package/dist/{job-DQiSYFHb.mjs → job-BxOZ-hqF.mjs} +2 -2
- package/dist/job-BxOZ-hqF.mjs.map +1 -0
- package/dist/{logger-BqvUa-Ue.mjs → logger-5PEqZVLr.mjs} +10 -3
- package/dist/{logger-BqvUa-Ue.mjs.map → logger-5PEqZVLr.mjs.map} +1 -1
- package/dist/logger.mjs +1 -1
- package/dist/usage.d.mts +1 -1
- package/dist/usage.mjs +1 -1
- package/package.json +6 -9
- package/dist/dependabot-_TVZhG0L.mjs.map +0 -1
- package/dist/http/index.d.mts +0 -121
- package/dist/http/index.mjs +0 -3
- package/dist/http-D2wwAKQ-.mjs +0 -241
- package/dist/http-D2wwAKQ-.mjs.map +0 -1
- package/dist/job-DQiSYFHb.mjs.map +0 -1
package/dist/azure/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["path","reason: string | undefined","reviewers: IdentityRefWithVote[]","body: string | undefined","configPath: undefined | string","configContents: undefined | string","organisation: string","path"],"sources":["../../src/azure/types.ts","../../src/azure/models.ts","../../src/azure/utils.ts","../../src/azure/client.ts","../../src/azure/config.ts","../../src/azure/url-parts.ts"],"sourcesContent":["export enum VersionControlChangeType {\n None = 0,\n Add = 1,\n Edit = 2,\n Encoding = 4,\n Rename = 8,\n Delete = 16,\n Undelete = 32,\n Branch = 64,\n Merge = 128,\n Lock = 256,\n Rollback = 512,\n SourceRename = 1024,\n TargetRename = 2048,\n Property = 4096,\n All = 8191,\n}\n\nexport enum GitPullRequestMergeStrategy {\n NoFastForward = 1,\n Squash = 2,\n Rebase = 3,\n RebaseMerge = 4,\n}\n\nexport enum CommentThreadStatus {\n Unknown = 0,\n Active = 1,\n Fixed = 2,\n WontFix = 3,\n Closed = 4,\n ByDesign = 5,\n Pending = 6,\n}\nexport enum CommentType {\n Unknown = 0,\n Text = 1,\n CodeChange = 2,\n System = 3,\n}\nexport enum ItemContentType {\n RawText = 0,\n Base64Encoded = 1,\n}\nexport enum PullRequestAsyncStatus {\n NotSet = 0,\n Queued = 1,\n Conflicts = 2,\n Succeeded = 3,\n RejectedByPolicy = 4,\n Failure = 5,\n}\nexport enum PullRequestStatus {\n NotSet = 0,\n Active = 1,\n Abandoned = 2,\n Completed = 3,\n All = 4,\n}\n\nexport type IdentityRefWithVote = {\n id?: string;\n displayName?: string;\n uniqueName?: string;\n url?: string;\n imageUrl?: string;\n vote?: number;\n hasDeclined?: boolean;\n isFlagged?: boolean;\n isRequired?: boolean;\n};\n\nexport type AzdoProject = {\n id: string;\n name: string;\n description?: string;\n url: string;\n state: 'deleting' | 'new' | 'wellFormed' | 'createPending' | 'all' | 'unchanged' | 'deleted';\n _links?: {\n self: { href: string };\n collection: { href: string };\n web: { href: string };\n };\n};\n\nexport type AzdoRepository = {\n id: string;\n name: string;\n defaultBranch?: string;\n project: AzdoProject;\n isDisabled?: boolean;\n isFork?: boolean;\n url: string;\n remoteUrl: string;\n webUrl: string;\n};\n\nexport type AzdoListResponse<T> = {\n value: T[];\n count: number;\n};\n\nexport type AzdoRepositoryItem = {\n latestProcessedChange?: {\n commitId?: string;\n };\n content?: string;\n};\n","import type { GitPullRequestMergeStrategy, VersionControlChangeType } from './types';\n\n/**\n * Pull request property names used to store metadata about the pull request.\n * https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-properties\n */\nexport const DEVOPS_PR_PROPERTY_MICROSOFT_GIT_SOURCE_REF_NAME = 'Microsoft.Git.PullRequest.SourceRefName';\nexport const DEVOPS_PR_PROPERTY_DEPENDABOT_PACKAGE_MANAGER = 'Dependabot.PackageManager';\nexport const DEVOPS_PR_PROPERTY_DEPENDABOT_DEPENDENCIES = 'Dependabot.Dependencies';\n\n/** File change */\nexport interface IFileChange {\n changeType: VersionControlChangeType;\n path: string;\n content?: string;\n encoding?: string;\n}\n\n/** Pull request properties */\nexport interface IPullRequestProperties {\n id: number;\n properties?: {\n name: string;\n value: string;\n }[];\n}\n\n/** Pull request creation request */\nexport interface ICreatePullRequest {\n project: string;\n repository: string;\n source: {\n commit: string;\n branch: string;\n };\n target: {\n branch: string;\n };\n author?: {\n email: string;\n name: string;\n };\n title: string;\n description: string;\n commitMessage: string;\n autoComplete?: {\n ignorePolicyConfigIds?: number[];\n mergeStrategy?: GitPullRequestMergeStrategy;\n };\n assignees?: string[];\n labels?: string[];\n workItems?: string[];\n changes: IFileChange[];\n properties?: {\n name: string;\n value: string;\n }[];\n}\n\n/** Pull request update request */\nexport interface IUpdatePullRequest {\n project: string;\n repository: string;\n pullRequestId: number;\n commit: string;\n author?: {\n email: string;\n name: string;\n };\n changes: IFileChange[];\n skipIfDraft?: boolean;\n skipIfCommitsFromAuthorsOtherThan?: string;\n skipIfNotBehindTargetBranch?: boolean;\n}\n\n/** Pull request approval request */\nexport interface IApprovePullRequest {\n project: string;\n repository: string;\n pullRequestId: number;\n}\n\n/** Pull request abandon request */\nexport interface IAbandonPullRequest {\n project: string;\n repository: string;\n pullRequestId: number;\n comment?: string;\n deleteSourceBranch?: boolean;\n}\n\n/** Pull request comment */\nexport interface IPullRequestComment {\n project: string;\n repository: string;\n pullRequestId: number;\n content: string;\n userId?: string;\n}\n","import * as path from 'node:path';\n\nimport {\n type DependabotClosePullRequest,\n type DependabotCreatePullRequest,\n type DependabotDependency,\n type DependabotExistingGroupPR,\n DependabotExistingGroupPRSchema,\n type DependabotExistingPR,\n DependabotExistingPRSchema,\n type DependabotUpdatePullRequest,\n} from '@/dependabot';\nimport {\n DEVOPS_PR_PROPERTY_DEPENDABOT_DEPENDENCIES,\n DEVOPS_PR_PROPERTY_DEPENDABOT_PACKAGE_MANAGER,\n type IFileChange,\n type IPullRequestProperties,\n} from './models';\nimport { VersionControlChangeType } from './types';\n\nexport function normalizeFilePath(path: string): string {\n // Convert backslashes to forward slashes, convert './' => '/' and ensure the path starts with a forward slash if it doesn't already, this is how DevOps paths are formatted\n return path\n ?.replace(/\\\\/g, '/')\n ?.replace(/^\\.\\//, '/')\n ?.replace(/^([^/])/, '/$1');\n}\n\nexport function normalizeBranchName(branch?: string): string | undefined {\n // Strip the 'refs/heads/' prefix from the branch name, if present\n return branch?.replace(/^refs\\/heads\\//i, '');\n}\n\nexport const DependenciesPrPropertySchema = DependabotExistingPRSchema.array().or(DependabotExistingGroupPRSchema);\n\nexport function buildPullRequestProperties(\n packageManager: string,\n dependencies: DependabotExistingPR[] | DependabotExistingGroupPR,\n) {\n return [\n {\n name: DEVOPS_PR_PROPERTY_DEPENDABOT_PACKAGE_MANAGER,\n value: packageManager,\n },\n {\n name: DEVOPS_PR_PROPERTY_DEPENDABOT_DEPENDENCIES,\n value: JSON.stringify(dependencies),\n },\n ];\n}\n\nexport function parsePullRequestProperties(\n pullRequests: IPullRequestProperties[],\n packageManager: string | null,\n): Record<string, DependabotExistingPR[] | DependabotExistingGroupPR> {\n return Object.fromEntries(\n pullRequests\n .filter((pr) => {\n return pr.properties?.find(\n (p) =>\n p.name === DEVOPS_PR_PROPERTY_DEPENDABOT_PACKAGE_MANAGER &&\n (packageManager === null || p.value === packageManager),\n );\n })\n .map((pr) => {\n return [\n pr.id,\n DependenciesPrPropertySchema.parse(\n JSON.parse(pr.properties!.find((p) => p.name === DEVOPS_PR_PROPERTY_DEPENDABOT_DEPENDENCIES)!.value),\n ),\n ];\n }),\n );\n}\n\nexport function getPullRequestForDependencyNames(\n existingPullRequests: IPullRequestProperties[],\n packageManager: string,\n dependencyNames: string[],\n): IPullRequestProperties | undefined {\n return existingPullRequests.find((pr) => {\n return (\n pr.properties?.find(\n (p) => p.name === DEVOPS_PR_PROPERTY_DEPENDABOT_PACKAGE_MANAGER && p.value === packageManager,\n ) &&\n pr.properties?.find(\n (p) =>\n p.name === DEVOPS_PR_PROPERTY_DEPENDABOT_DEPENDENCIES &&\n areEqual(getDependencyNames(DependenciesPrPropertySchema.parse(JSON.parse(p.value))), dependencyNames),\n )\n );\n });\n}\n\nfunction getDependencyNames(dependencies: DependabotExistingPR[] | DependabotExistingGroupPR): string[] {\n const deps = Array.isArray(dependencies) ? dependencies : dependencies.dependencies;\n return deps.map((dep) => dep['dependency-name']?.toString());\n}\n\nfunction areEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n return a.every((name) => b.includes(name));\n}\n\nexport function getPullRequestChangedFilesForOutputData(\n data: DependabotCreatePullRequest | DependabotUpdatePullRequest,\n): IFileChange[] {\n return data['updated-dependency-files']\n .filter((file) => file.type === 'file')\n .map((file) => {\n let changeType = VersionControlChangeType.None;\n if (file.deleted === true || file.operation === 'delete') {\n changeType = VersionControlChangeType.Delete;\n } else if (file.operation === 'update') {\n changeType = VersionControlChangeType.Edit;\n } else {\n changeType = VersionControlChangeType.Add;\n }\n return {\n changeType: changeType,\n path: path.join(file.directory, file.name),\n content: file.content ?? undefined,\n encoding: file.content_encoding || 'utf-8', // default to 'utf-8' if nullish or empty string\n } satisfies IFileChange;\n });\n}\n\nexport function getPullRequestCloseReasonForOutputData(data: DependabotClosePullRequest): string | undefined {\n // The first dependency is the \"lead\" dependency in a multi-dependency update\n const leadDependencyName = data['dependency-names'][0];\n let reason: string | undefined;\n switch (data.reason) {\n case 'dependencies_changed':\n reason = `Looks like the dependencies have changed`;\n break;\n case 'dependency_group_empty':\n reason = `Looks like the dependencies in this group are now empty`;\n break;\n case 'dependency_removed':\n reason = `Looks like ${leadDependencyName} is no longer a dependency`;\n break;\n case 'up_to_date':\n reason = `Looks like ${leadDependencyName} is up-to-date now`;\n break;\n case 'update_no_longer_possible':\n reason = `Looks like ${leadDependencyName} can no longer be updated`;\n break;\n }\n if (reason && reason.length > 0) {\n reason += ', so this is no longer needed.';\n }\n return reason;\n}\n\nexport function getPullRequestDependenciesPropertyValueForOutputData(\n data: DependabotCreatePullRequest,\n): DependabotExistingPR[] | DependabotExistingGroupPR {\n const dependencies = data.dependencies?.map((dep) => {\n return {\n 'dependency-name': dep.name,\n 'dependency-version': dep.version,\n directory: dep.directory,\n };\n });\n const dependencyGroupName = data['dependency-group']?.name;\n if (!dependencyGroupName) return dependencies;\n return {\n 'dependency-group-name': dependencyGroupName,\n dependencies: dependencies,\n } as DependabotExistingGroupPR;\n}\n\nexport function getPullRequestDescription(\n packageManager: string,\n body: string | null | undefined,\n dependencies: DependabotDependency[],\n): string {\n let header = '';\n const footer = '';\n\n // Fix up GitHub mentions encoding issues by removing instances of the zero-width space '\\u200B' as it does not render correctly in Azure DevOps.\n // https://github.com/dependabot/dependabot-core/issues/9572\n // https://github.com/dependabot/dependabot-core/blob/313fcff149b3126cb78b38d15f018907d729f8cc/common/lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb#L245-L252\n const description = (body || '').replace(new RegExp(decodeURIComponent('%EF%BF%BD%EF%BF%BD%EF%BF%BD'), 'g'), '');\n\n // If there is exactly one dependency, add a compatibility score badge to the description header.\n // Compatibility scores are intended for single dependency security updates, not group updates.\n // https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores\n if (dependencies.length === 1) {\n const compatibilityScoreBadges = dependencies.map((dep) => {\n return ``;\n });\n header += `${compatibilityScoreBadges.join(' ')}\\n\\n`;\n }\n\n // Build the full pull request description.\n // The header/footer must not be truncated. If the description is too long, we truncate the body.\n const maxDescriptionLength = 4000;\n const maxDescriptionLengthAfterHeaderAndFooter = maxDescriptionLength - header.length - footer.length;\n return `${header}${description.substring(0, maxDescriptionLengthAfterHeaderAndFooter)}${footer}`;\n}\n","import { HttpRequestError, isErrorTemporaryFailure } from '@/http';\nimport { logger } from '@/logger';\nimport type {\n IAbandonPullRequest,\n IApprovePullRequest,\n ICreatePullRequest,\n IPullRequestComment,\n IPullRequestProperties,\n IUpdatePullRequest,\n} from './models';\nimport {\n type AzdoListResponse,\n type AzdoProject,\n type AzdoRepository,\n type AzdoRepositoryItem,\n CommentThreadStatus,\n CommentType,\n type IdentityRefWithVote,\n ItemContentType,\n PullRequestAsyncStatus,\n PullRequestStatus,\n VersionControlChangeType,\n} from './types';\nimport type { AzureDevOpsOrganizationUrl } from './url-parts';\nimport { normalizeBranchName, normalizeFilePath } from './utils';\n\n/** Returned from AzureDevOpsWebApiClient.getUserId() when no user is authenticated */\nexport const ANONYMOUS_USER_ID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa';\n\n/** Azure DevOps REST API client. */\nexport class AzureDevOpsWebApiClient {\n private readonly organisationApiUrl: string;\n private readonly identityApiUrl: string;\n private readonly accessToken: string;\n private readonly debug: boolean;\n\n private authenticatedUserId?: string;\n private resolvedUserIds: Record<string, string>;\n\n public static API_VERSION = '5.0'; // this is the same version used by dependabot-core\n public static API_VERSION_PREVIEW = '5.0-preview';\n\n constructor(url: AzureDevOpsOrganizationUrl, accessToken: string, debug: boolean = false) {\n const organisationApiUrl = url.value.toString();\n this.organisationApiUrl = organisationApiUrl.replace(/\\/$/, ''); // trim trailing slash\n this.identityApiUrl = getIdentityApiUrl(organisationApiUrl).replace(/\\/$/, ''); // trim trailing slash\n this.accessToken = accessToken;\n this.debug = debug;\n this.resolvedUserIds = {};\n }\n\n /**\n * Get the identity of the authenticated user.\n * @returns\n */\n public async getUserId(): Promise<string> {\n if (!this.authenticatedUserId) {\n const connectionData = await this.restApiGet(\n `${this.organisationApiUrl}/_apis/connectiondata`,\n undefined,\n AzureDevOpsWebApiClient.API_VERSION_PREVIEW,\n );\n this.authenticatedUserId = connectionData?.authenticatedUser?.id;\n if (!this.authenticatedUserId) {\n throw new Error('Failed to get authenticated user ID');\n }\n }\n return this.authenticatedUserId;\n }\n\n /**\n * Get the identity id from a user name, email, or group name.\n * Requires scope \"Identity (Read)\" (vso.identity).\n * @param userNameEmailOrGroupName\n * @returns\n */\n public async resolveIdentityId(userNameEmailOrGroupName: string): Promise<string | undefined> {\n if (this.resolvedUserIds[userNameEmailOrGroupName]) {\n return this.resolvedUserIds[userNameEmailOrGroupName];\n }\n try {\n const identities = await this.restApiGet(`${this.identityApiUrl}/_apis/identities`, {\n searchFilter: 'General',\n filterValue: userNameEmailOrGroupName,\n queryMembership: 'None',\n });\n if (!identities?.value || identities.value.length === 0) {\n return undefined;\n }\n this.resolvedUserIds[userNameEmailOrGroupName] = identities.value[0]?.id;\n return this.resolvedUserIds[userNameEmailOrGroupName];\n } catch (e) {\n logger.error(`Failed to resolve user id: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return undefined;\n }\n }\n\n public async getProjects(): Promise<AzdoListResponse<AzdoProject> | undefined> {\n try {\n const projects = await this.restApiGet(`${this.organisationApiUrl}/_apis/projects`);\n return projects;\n } catch (e) {\n logger.error(`Failed to get projects: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return undefined;\n }\n }\n\n public async getProject(idOrName: string): Promise<AzdoProject | undefined> {\n try {\n const project = await this.restApiGet(\n `${this.organisationApiUrl}/_apis/projects/${encodeURIComponent(idOrName)}`,\n );\n return project;\n } catch (e) {\n logger.error(`Failed to get project: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return undefined;\n }\n }\n\n public async getRepositories(projectIdOrName: string): Promise<AzdoListResponse<AzdoRepository> | undefined> {\n try {\n const repos = await this.restApiGet(\n `${this.organisationApiUrl}/${encodeURIComponent(projectIdOrName)}/_apis/git/repositories`,\n );\n return repos;\n } catch (e) {\n logger.error(`Failed to get repositories: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return undefined;\n }\n }\n\n public async getRepository(projectIdOrName: string, repositoryIdOrName: string): Promise<AzdoRepository | undefined> {\n try {\n const repo = await this.restApiGet(\n `${this.organisationApiUrl}/${encodeURIComponent(projectIdOrName)}/_apis/git/repositories/${encodeURIComponent(repositoryIdOrName)}`,\n );\n return repo;\n } catch (e) {\n if (e instanceof HttpRequestError && e.code === 404) {\n // repository no longer exists\n return undefined;\n } else {\n logger.error(`Failed to get repository: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n }\n return undefined;\n }\n }\n\n public async getRepositoryItem(\n projectIdOrName: string,\n repositoryIdOrName: string,\n path: string,\n includeContent: boolean = true,\n latestProcessedChange: boolean = true,\n ): Promise<AzdoRepositoryItem | undefined> {\n try {\n const item = await this.restApiGet(\n `${this.organisationApiUrl}/${encodeURIComponent(projectIdOrName)}/_apis/git/repositories/${encodeURIComponent(repositoryIdOrName)}/items`,\n {\n path,\n includeContent,\n latestProcessedChange,\n },\n );\n return item;\n } catch (e) {\n if (e instanceof HttpRequestError && e.code === 404) {\n // item does not exist\n return undefined;\n } else {\n logger.error(`Failed to get repository item: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n }\n return undefined;\n }\n }\n\n /**\n * Get the default branch for a repository.\n * Requires scope \"Code (Read)\" (vso.code).\n * @param project\n * @param repository\n * @returns\n */\n public async getDefaultBranch(project: string, repository: string): Promise<string | undefined> {\n try {\n const repo = await this.restApiGet(`${this.organisationApiUrl}/${project}/_apis/git/repositories/${repository}`);\n if (!repo) {\n throw new Error(`Repository '${project}/${repository}' not found`);\n }\n\n return normalizeBranchName(repo.defaultBranch);\n } catch (e) {\n logger.error(`Failed to get default branch for '${project}/${repository}': ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return undefined;\n }\n }\n\n /**\n * Get the list of branch names for a repository.\n * Requires scope \"Code (Read)\" (vso.code).\n * @param project\n * @param repository\n * @returns\n */\n public async getBranchNames(project: string, repository: string): Promise<string[] | undefined> {\n try {\n const refs = await this.restApiGet(\n `${this.organisationApiUrl}/${project}/_apis/git/repositories/${repository}/refs`,\n );\n if (!refs) {\n throw new Error(`Repository '${project}/${repository}' not found`);\n }\n\n return refs.value?.map((r: { name?: string }) => normalizeBranchName(r.name)) || [];\n } catch (e) {\n logger.error(`Failed to list branch names for '${project}/${repository}': ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return undefined;\n }\n }\n\n /**\n * Get the properties for all active pull request created by the supplied user.\n * Requires scope \"Code (Read)\" (vso.code).\n * @param project\n * @param repository\n * @param creator\n * @returns\n */\n public async getActivePullRequestProperties(\n project: string,\n repository: string,\n creator: string,\n ): Promise<IPullRequestProperties[]> {\n try {\n const pullRequests = await this.restApiGet(\n `${this.organisationApiUrl}/${project}/_apis/git/repositories/${repository}/pullrequests`,\n {\n 'searchCriteria.creatorId': isGuid(creator) ? creator : await this.getUserId(),\n 'searchCriteria.status': 'Active',\n },\n );\n if (!pullRequests?.value || pullRequests.value.length === 0) {\n return [];\n }\n\n return await Promise.all(\n pullRequests.value.map(async (pr: { pullRequestId: number }) => {\n const properties = await this.restApiGet(\n `${this.organisationApiUrl}/${project}/_apis/git/repositories/${repository}/pullrequests/${pr.pullRequestId}/properties`,\n );\n return {\n id: pr.pullRequestId,\n properties:\n Object.keys(properties?.value || {}).map((key) => {\n return {\n name: key,\n value: properties.value[key]?.$value,\n };\n }) || [],\n };\n }),\n );\n } catch (e) {\n logger.error(`Failed to list active pull request properties: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return [];\n }\n }\n\n /**\n * Create a new pull request.\n * Requires scope \"Code (Write)\" (vso.code_write).\n * Requires scope \"Identity (Read)\" (vso.identity), if assignees are specified.\n * @param pr\n * @returns\n */\n public async createPullRequest(pr: ICreatePullRequest): Promise<number | null> {\n logger.info(`Creating pull request '${pr.title}'...`);\n try {\n const userId = await this.getUserId();\n\n // Map the list of the pull request reviewer ids\n // NOTE: Azure DevOps does not have a concept of assignees.\n // We treat them as optional reviewers. Branch policies should be used for required reviewers.\n const reviewers: IdentityRefWithVote[] = [];\n if (pr.assignees && pr.assignees.length > 0) {\n for (const assignee of pr.assignees) {\n const identityId = isGuid(assignee) ? assignee : await this.resolveIdentityId(assignee);\n if (identityId && !reviewers.some((r) => r.id === identityId)) {\n reviewers.push({\n id: identityId,\n });\n } else {\n logger.warn(`Unable to resolve assignee identity '${assignee}'`);\n }\n }\n }\n\n // Create the source branch and push a commit with the dependency file changes\n logger.info(` - Pushing ${pr.changes.length} file change(s) to branch '${pr.source.branch}'...`);\n const push = await this.restApiPost(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pushes`,\n {\n refUpdates: [\n {\n name: `refs/heads/${pr.source.branch}`,\n oldObjectId: pr.source.commit,\n },\n ],\n commits: [\n {\n comment: pr.commitMessage,\n author: pr.author,\n changes: pr.changes\n .filter((change) => change.changeType !== VersionControlChangeType.None)\n .map(({ changeType, ...change }) => {\n return {\n changeType,\n item: { path: normalizeFilePath(change.path) },\n newContent:\n changeType !== VersionControlChangeType.Delete\n ? {\n content: Buffer.from(change.content!, <BufferEncoding>change.encoding).toString('base64'),\n contentType: ItemContentType.Base64Encoded,\n }\n : undefined,\n };\n }),\n },\n ],\n },\n );\n if (!push?.commits?.length) {\n throw new Error('Failed to push changes to source branch, no commits were created');\n }\n logger.info(` - Pushed commit: ${push.commits.map((c: { commitId: string }) => c.commitId).join(', ')}.`);\n\n // Create the pull request\n logger.info(` - Creating pull request to merge '${pr.source.branch}' into '${pr.target.branch}'...`);\n const pullRequest = await this.restApiPost(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests`,\n {\n sourceRefName: `refs/heads/${pr.source.branch}`,\n targetRefName: `refs/heads/${pr.target.branch}`,\n title: pr.title,\n description: pr.description,\n reviewers: reviewers,\n workItemRefs: pr.workItems?.map((id) => ({ id: id })),\n labels: pr.labels?.map((label) => ({ name: label })),\n },\n );\n if (!pullRequest?.pullRequestId) {\n throw new Error('Failed to create pull request, no pull request id was returned');\n }\n logger.info(` - Created pull request: #${pullRequest.pullRequestId}.`);\n\n // Add the pull request properties\n if (pr.properties && pr.properties.length > 0) {\n logger.info(` - Adding dependency metadata to pull request properties...`);\n const newProperties = await this.restApiPatch(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests/${pullRequest.pullRequestId}/properties`,\n pr.properties.map((property) => {\n return {\n op: 'add',\n path: `/${property.name}`,\n value: property.value,\n };\n }),\n 'application/json-patch+json',\n );\n if (!newProperties?.count) {\n throw new Error('Failed to add dependency metadata properties to pull request');\n }\n }\n\n // TODO: Upload the pull request description as a 'changes.md' file attachment?\n // This might be a way to work around the 4000 character limit for PR descriptions, but needs more investigation.\n // https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-attachments/create?view=azure-devops-rest-7.1\n\n // Set the pull request auto-complete status\n if (pr.autoComplete) {\n logger.info(` - Updating auto-complete options...`);\n const updatedPullRequest = await this.restApiPatch(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests/${pullRequest.pullRequestId}`,\n {\n autoCompleteSetBy: {\n id: userId,\n },\n completionOptions: {\n autoCompleteIgnoreConfigIds: pr.autoComplete.ignorePolicyConfigIds,\n deleteSourceBranch: true,\n mergeCommitMessage: mergeCommitMessage(pullRequest.pullRequestId, pr.title, pr.description),\n mergeStrategy: pr.autoComplete.mergeStrategy,\n transitionWorkItems: false,\n },\n },\n );\n if (!updatedPullRequest || updatedPullRequest.autoCompleteSetBy?.id !== userId) {\n throw new Error('Failed to set auto-complete on pull request');\n }\n }\n\n logger.info(` - Pull request was created successfully.`);\n return pullRequest.pullRequestId;\n } catch (e) {\n logger.error(`Failed to create pull request: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return null;\n }\n }\n\n /**\n * Update a pull request.\n * Requires scope \"Code (Read & Write)\" (vso.code, vso.code_write).\n * @param pr\n * @returns\n */\n public async updatePullRequest(pr: IUpdatePullRequest): Promise<boolean> {\n logger.info(`Updating pull request #${pr.pullRequestId}...`);\n try {\n // Get the pull request details\n const pullRequest = await this.restApiGet(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests/${pr.pullRequestId}`,\n );\n if (!pullRequest) {\n throw new Error(`Pull request #${pr.pullRequestId} not found`);\n }\n\n // Skip if the pull request is a draft\n if (pr.skipIfDraft && pullRequest.isDraft) {\n logger.info(` - Skipping update as pull request is currently marked as a draft.`);\n return true;\n }\n\n // Skip if the pull request has been modified by another author\n if (pr.skipIfCommitsFromAuthorsOtherThan) {\n const commits = await this.restApiGet(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests/${pr.pullRequestId}/commits`,\n );\n if (\n commits?.value?.some(\n (c: { author?: { email?: string } }) => c.author?.email !== pr.skipIfCommitsFromAuthorsOtherThan,\n )\n ) {\n logger.info(` - Skipping update as pull request has been modified by another user.`);\n return true;\n }\n }\n\n // Get the branch stats to check if the source branch is behind the target branch\n const stats = await this.restApiGet(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/stats/branches`,\n {\n name: normalizeBranchName(pullRequest.sourceRefName),\n },\n );\n if (stats?.behindCount === undefined) {\n throw new Error(`Failed to get branch stats for '${pullRequest.sourceRefName}'`);\n }\n\n // Skip if the source branch is not behind the target branch\n if (pr.skipIfNotBehindTargetBranch && stats.behindCount === 0) {\n logger.info(` - Skipping update as source branch is not behind target branch.`);\n return true;\n }\n\n // Rebase the target branch into the source branch to reset the \"behind\" count\n const sourceBranchName = normalizeBranchName(pullRequest.sourceRefName);\n const targetBranchName = normalizeBranchName(pullRequest.targetRefName);\n if (stats.behindCount > 0) {\n logger.info(\n ` - Rebasing '${targetBranchName}' into '${sourceBranchName}' (${stats.behindCount} commit(s) behind)...`,\n );\n const rebase = await this.restApiPost(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/refs`,\n [\n {\n name: pullRequest.sourceRefName,\n oldObjectId: pullRequest.lastMergeSourceCommit.commitId,\n newObjectId: pr.commit,\n },\n ],\n );\n if (rebase?.value?.[0]?.success !== true) {\n throw new Error('Failed to rebase the target branch into the source branch');\n }\n }\n\n // Push all file changes to the source branch\n logger.info(` - Pushing ${pr.changes.length} file change(s) to branch '${pullRequest.sourceRefName}'...`);\n const push = await this.restApiPost(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pushes`,\n {\n refUpdates: [\n {\n name: pullRequest.sourceRefName,\n oldObjectId: pr.commit,\n },\n ],\n commits: [\n {\n comment:\n pullRequest.mergeStatus === PullRequestAsyncStatus.Conflicts\n ? 'Resolve merge conflicts'\n : `Rebase '${sourceBranchName}' onto '${targetBranchName}'`,\n author: pr.author,\n changes: pr.changes\n .filter((change) => change.changeType !== VersionControlChangeType.None)\n .map(({ changeType, ...change }) => {\n return {\n changeType,\n item: { path: normalizeFilePath(change.path) },\n newContent:\n changeType !== VersionControlChangeType.Delete\n ? {\n content: Buffer.from(change.content!, <BufferEncoding>change.encoding).toString('base64'),\n contentType: ItemContentType.Base64Encoded,\n }\n : undefined,\n };\n }),\n },\n ],\n },\n );\n if (!push?.commits?.length) {\n throw new Error('Failed to push changes to source branch, no commits were created');\n }\n logger.info(` - Pushed commit: ${push.commits.map((c: { commitId: string }) => c.commitId).join(', ')}.`);\n\n logger.info(` - Pull request was updated successfully.`);\n return true;\n } catch (e) {\n logger.error(`Failed to update pull request: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return false;\n }\n }\n\n /**\n * Approve a pull request.\n * Requires scope \"Code (Write)\" (vso.code_write).\n * @param pr\n * @returns\n */\n public async approvePullRequest(pr: IApprovePullRequest): Promise<boolean> {\n logger.info(`Approving pull request #${pr.pullRequestId}...`);\n try {\n // Approve the pull request\n logger.info(` - Updating reviewer vote on pull request...`);\n const userId = await this.getUserId();\n const userVote = await this.restApiPut(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests/${pr.pullRequestId}/reviewers/${userId}`,\n {\n // Vote 10 = \"approved\"; 5 = \"approved with suggestions\"; 0 = \"no vote\"; -5 = \"waiting for author\"; -10 = \"rejected\"\n vote: 10,\n // Reapprove must be set to true after the 2023 August 23 update;\n // Approval of a previous PR iteration does not count in later iterations, which means we must (re)approve every after push to the source branch\n // See: https://learn.microsoft.com/en-us/azure/devops/release-notes/2023/sprint-226-update#new-branch-policy-preventing-users-to-approve-their-own-changes\n // https://github.com/mburumaxwell/dependabot-azure-devops/issues/1069\n isReapprove: true,\n },\n // API version 7.1 is required to use the 'isReapprove' parameter\n // See: https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-reviewers/create-pull-request-reviewer?view=azure-devops-rest-7.1&tabs=HTTP#request-body\n // https://learn.microsoft.com/en-us/azure/devops/integrate/concepts/rest-api-versioning?view=azure-devops#supported-versions\n '7.1',\n );\n if (userVote?.vote !== 10) {\n throw new Error('Failed to approve pull request, vote was not recorded');\n }\n\n logger.info(` - Pull request was approved successfully.`);\n return true;\n } catch (e) {\n logger.error(`Failed to approve pull request: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return false;\n }\n }\n\n /**\n * Abandon a pull request.\n * Requires scope \"Code (Write)\" (vso.code_write).\n * @param pr\n * @returns\n */\n public async abandonPullRequest(pr: IAbandonPullRequest): Promise<boolean> {\n logger.info(`Abandoning pull request #${pr.pullRequestId}...`);\n try {\n const userId = await this.getUserId();\n\n // Add a comment to the pull request, if supplied\n if (pr.comment) {\n logger.info(` - Adding abandonment reason comment to pull request...`);\n const threadId = await this.addCommentThread({\n ...pr,\n content: pr.comment,\n userId,\n });\n if (!threadId) {\n throw new Error('Failed to add comment to pull request, thread was not created');\n }\n }\n\n // Abandon the pull request\n logger.info(` - Abandoning pull request...`);\n const abandonedPullRequest = await this.restApiPatch(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests/${pr.pullRequestId}`,\n {\n status: PullRequestStatus.Abandoned,\n closedBy: {\n id: userId,\n },\n },\n );\n if (abandonedPullRequest?.status?.toLowerCase() !== 'abandoned') {\n throw new Error('Failed to abandon pull request, status was not updated');\n }\n\n // Delete the source branch if required\n if (pr.deleteSourceBranch) {\n logger.info(` - Deleting source branch...`);\n const deletedBranch = await this.restApiPost(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/refs`,\n [\n {\n name: abandonedPullRequest.sourceRefName,\n oldObjectId: abandonedPullRequest.lastMergeSourceCommit.commitId,\n newObjectId: '0000000000000000000000000000000000000000',\n isLocked: false,\n },\n ],\n );\n if (deletedBranch?.value?.[0]?.success !== true) {\n throw new Error('Failed to delete the source branch');\n }\n }\n\n logger.info(` - Pull request was abandoned successfully.`);\n return true;\n } catch (e) {\n logger.error(`Failed to abandon pull request: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return false;\n }\n }\n\n /**\n * Add a comment thread on a pull request.\n * Requires scope \"Code (Write)\" (vso.code_write).\n */\n public async addCommentThread(comment: IPullRequestComment): Promise<number | undefined> {\n const userId = comment.userId ?? (await this.getUserId());\n const thread = await this.restApiPost(\n `${this.organisationApiUrl}/${comment.project}/_apis/git/repositories/${comment.repository}/pullrequests/${comment.pullRequestId}/threads`,\n {\n status: CommentThreadStatus.Closed,\n comments: [\n {\n author: {\n id: userId,\n },\n content: comment.content,\n commentType: CommentType.System,\n },\n ],\n },\n );\n return thread?.id;\n }\n\n private async restApiGet(\n url: string,\n params?: Record<string, unknown>,\n apiVersion: string = AzureDevOpsWebApiClient.API_VERSION,\n ) {\n params ??= {};\n const queryString = Object.keys(params)\n .map((key) => `${key}=${params[key]}`)\n .join('&');\n const fullUrl = `${url}?api-version=${apiVersion}${queryString ? `&${queryString}` : ''}`;\n\n return await sendRestApiRequestWithRetry(\n 'GET',\n fullUrl,\n undefined,\n async () => {\n return await fetch(fullUrl, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n Authorization: `Basic ${Buffer.from(`:${this.accessToken}`).toString('base64')}`,\n },\n });\n },\n this.debug,\n );\n }\n\n private async restApiPost(url: string, data?: unknown, apiVersion: string = AzureDevOpsWebApiClient.API_VERSION) {\n const fullUrl = `${url}?api-version=${apiVersion}`;\n return await sendRestApiRequestWithRetry(\n 'POST',\n fullUrl,\n data,\n async () => {\n return await fetch(fullUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Basic ${Buffer.from(`:${this.accessToken}`).toString('base64')}`,\n },\n body: JSON.stringify(data),\n });\n },\n this.debug,\n );\n }\n\n private async restApiPut(url: string, data?: unknown, apiVersion: string = AzureDevOpsWebApiClient.API_VERSION) {\n const fullUrl = `${url}?api-version=${apiVersion}`;\n return await sendRestApiRequestWithRetry(\n 'PUT',\n fullUrl,\n data,\n async () => {\n return await fetch(fullUrl, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Basic ${Buffer.from(`:${this.accessToken}`).toString('base64')}`,\n },\n body: JSON.stringify(data),\n });\n },\n this.debug,\n );\n }\n\n private async restApiPatch(\n url: string,\n data?: unknown,\n contentType?: string,\n apiVersion: string = AzureDevOpsWebApiClient.API_VERSION,\n ) {\n const fullUrl = `${url}?api-version=${apiVersion}`;\n return await sendRestApiRequestWithRetry(\n 'PATCH',\n fullUrl,\n data,\n async () => {\n return await fetch(fullUrl, {\n method: 'PATCH',\n headers: {\n 'Content-Type': contentType || 'application/json',\n Authorization: `Basic ${Buffer.from(`:${this.accessToken}`).toString('base64')}`,\n },\n body: JSON.stringify(data),\n });\n },\n this.debug,\n );\n }\n}\n\nfunction mergeCommitMessage(id: number, title: string, description: string): string {\n //\n // The merge commit message should contain the PR number and title for tracking.\n // This is the default behaviour in Azure DevOps.\n // Example:\n // Merged PR 24093: Bump Tingle.Extensions.Logging.LogAnalytics from 3.4.2-ci0005 to 3.4.2-ci0006\n //\n // Bumps [Tingle.Extensions.Logging.LogAnalytics](...) from 3.4.2-ci0005 to 3.4.2-ci0006\n // - [Release notes](....)\n // - [Changelog](....)\n // - [Commits](....)\n //\n // There appears to be a DevOps bug when setting \"completeOptions\" with a \"mergeCommitMessage\" even when truncated to 4000 characters.\n // The error message is:\n // Invalid argument value.\n // Parameter name: Completion options have exceeded the maximum encoded length (4184/4000)\n //\n // The effective limit seems to be about 3500 characters:\n // https://developercommunity.visualstudio.com/t/raise-the-character-limit-for-pull-request-descrip/365708#T-N424531\n //\n return `Merged PR ${id}: ${title}\\n\\n${description}`.slice(0, 3500);\n}\n\nfunction isGuid(guid: string): boolean {\n const regex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\n return regex.test(guid);\n}\n\nfunction getIdentityApiUrl(organisationApiUrl: string): string {\n const uri = new URL(organisationApiUrl);\n const hostname = uri.hostname.toLowerCase();\n\n // If the organisation is hosted on Azure DevOps, use the 'vssps.dev.azure.com' domain\n if (hostname === 'dev.azure.com' || hostname.endsWith('.visualstudio.com')) {\n uri.host = 'vssps.dev.azure.com';\n }\n return uri.toString();\n}\n\nexport async function sendRestApiRequestWithRetry(\n method: string,\n url: string,\n payload: unknown,\n requestAsync: () => Promise<Response>,\n isDebug: boolean = false,\n retryCount: number = 3,\n retryDelay: number = 3000,\n) {\n let body: string | undefined;\n try {\n // Send the request, ready the response\n if (isDebug) logger.debug(`🌎 🠊 [${method}] ${url}`);\n const response = await requestAsync();\n body = await response.text();\n const { status: statusCode, statusText: statusMessage } = response;\n if (isDebug) logger.debug(`🌎 🠈 [${statusCode}] ${statusMessage}`);\n\n // Check that the request was successful\n if (statusCode < 200 || statusCode > 299) {\n throw new HttpRequestError(`HTTP ${method} '${url}' failed: ${statusCode} ${statusMessage}`, statusCode);\n }\n\n // Parse the response\n return JSON.parse(body);\n } catch (e) {\n const err = e as Error;\n // Retry the request if the error is a temporary failure\n if (retryCount > 1 && isErrorTemporaryFailure(err)) {\n logger.warn(err.message);\n if (isDebug) logger.debug(`⏳ Retrying request in ${retryDelay}ms...`);\n await new Promise((resolve) => setTimeout(resolve, retryDelay));\n return sendRestApiRequestWithRetry(method, url, payload, requestAsync, isDebug, retryCount - 1, retryDelay);\n }\n\n // In debug mode, log the error, request, and response for debugging\n if (isDebug) {\n if (payload) {\n logger.debug(`REQUEST: ${JSON.stringify(payload)}`);\n }\n if (body) {\n logger.debug(`RESPONSE: ${body}`);\n }\n }\n\n logger.trace(`THROW${e}`);\n throw e;\n }\n}\n","import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport * as path from 'node:path';\n\nimport {\n type DependabotConfig,\n POSSIBLE_CONFIG_FILE_PATHS,\n parseDependabotConfig,\n type VariableFinderFn,\n} from '@/dependabot';\nimport { logger } from '@/logger';\nimport type { AzureDevOpsRepositoryUrl } from './url-parts';\n\n/**\n * Parse the dependabot config YAML file to specify update configuration.\n * The file should be located at any of `POSSIBLE_CONFIG_FILE_PATHS`.\n *\n * To view YAML file format, visit\n * https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#allow\n *\n * @returns {DependabotConfig} config - the dependabot configuration\n */\nexport async function getDependabotConfig({\n url,\n token,\n remote,\n rootDir = process.cwd(),\n variableFinder,\n}: {\n url: AzureDevOpsRepositoryUrl;\n token: string;\n /**\n * Whether to fetch the configuration file via the REST API (true) or look for it locally (false).\n */\n remote: boolean;\n rootDir?: string;\n variableFinder: VariableFinderFn;\n}): Promise<DependabotConfig> {\n let configPath: undefined | string;\n let configContents: undefined | string;\n\n /*\n * The configuration file can be available locally if the repository is cloned.\n * Otherwise, we should get it via the API which supports 2 scenarios:\n * 1. Running the pipeline without cloning, which is useful for huge repositories (multiple submodules or large commit log)\n * 2. Running a single pipeline to update multiple repositories https://github.com/mburumaxwell/dependabot-azure-devops/issues/328\n */\n\n if (remote) {\n logger.debug(`Attempting to fetch configuration file via REST API ...`);\n for (const fp of POSSIBLE_CONFIG_FILE_PATHS) {\n // make HTTP request\n const requestUrl = `${url.value}${url.project}/_apis/git/repositories/${url.repository}/items?path=/${fp}`;\n logger.debug(`GET ${requestUrl}`);\n\n try {\n const authHeader = `Basic ${Buffer.from(`x-access-token:${token}`).toString('base64')}`;\n const response = await fetch(requestUrl, {\n headers: {\n Authorization: authHeader,\n Accept: '*/*', // Gotcha!!! without this SH*T fails terribly\n },\n });\n if (response.ok) {\n logger.debug(`Found configuration file at '${requestUrl}'`);\n configContents = await response.text();\n configPath = fp;\n break;\n } else if (response.status === 404) {\n logger.trace(`No configuration file at '${requestUrl}'`);\n // biome-ignore lint/complexity/noUselessContinue: continue is useful here for clarity\n continue;\n } else if (response.status === 401) {\n throw new Error(`No or invalid access token has been provided to access '${requestUrl}'`);\n } else if (response.status === 403) {\n throw new Error(`The access token provided does not have permissions to access '${requestUrl}'`);\n }\n } catch (error) {\n if (error instanceof Error && error.message.includes('access token')) {\n throw error;\n } else {\n throw error;\n }\n }\n }\n } else {\n for (const fp of POSSIBLE_CONFIG_FILE_PATHS) {\n const filePath = path.join(rootDir, fp);\n if (existsSync(filePath)) {\n logger.debug(`Found configuration file cloned at ${filePath}`);\n configContents = await readFile(filePath, 'utf-8');\n configPath = filePath;\n break;\n } else {\n logger.trace(`No configuration file cloned at ${filePath}`);\n }\n }\n }\n\n // Ensure we have file contents. Otherwise throw a well readable error.\n if (!configContents || !configPath || typeof configContents !== 'string') {\n throw new Error(`Configuration file not found at possible locations: ${POSSIBLE_CONFIG_FILE_PATHS.join(', ')}`);\n } else {\n logger.trace('Configuration file contents read.');\n }\n\n return await parseDependabotConfig({ configContents, configPath, variableFinder });\n}\n","export type AzureDevOpsOrganizationUrl = {\n /** URL of the organisation. This may lack the project name */\n value: URL;\n\n /** Organisation URL hostname */\n hostname: string;\n\n /** Organisation API endpoint URL */\n 'api-endpoint': string;\n\n /** Organisation name/slug */\n organisation: string;\n\n /** Virtual directory if present (on-premises only) */\n 'virtual-directory'?: string;\n};\n\nexport type AzureDevOpsProjectUrl = AzureDevOpsOrganizationUrl & {\n /** Project ID or Name */\n project: string;\n};\n\nexport type AzureDevOpsRepositoryUrl = AzureDevOpsProjectUrl & {\n /** Repository ID or Name */\n repository: string;\n\n /** Slug of the repository e.g. `contoso/prj1/_git/repo1`, `tfs/contoso/prj1/_git/repo1` */\n 'repository-slug': string;\n};\n\nexport function extractOrganizationUrl({ organisationUrl }: { organisationUrl: string }): AzureDevOpsOrganizationUrl {\n // convert url string into a valid JS URL object\n const value = new URL(organisationUrl);\n const protocol = value.protocol.slice(0, -1);\n let { hostname } = value;\n const visualStudioUrlRegex = /^(?<prefix>\\S+)\\.visualstudio\\.com$/iu;\n if (visualStudioUrlRegex.test(hostname)) hostname = 'dev.azure.com';\n\n const organisation: string = extractOrganisation(organisationUrl);\n\n const virtualDirectory = extractVirtualDirectory(value);\n const apiEndpoint = `${protocol}://${hostname}${value.port ? `:${value.port}` : ''}/${virtualDirectory ? `${virtualDirectory}/` : ''}`;\n\n return {\n value,\n hostname,\n 'api-endpoint': apiEndpoint,\n organisation,\n 'virtual-directory': virtualDirectory,\n };\n}\n\nexport function extractProjectUrl({\n organisationUrl,\n project,\n}: {\n organisationUrl: string;\n project: string;\n}): AzureDevOpsProjectUrl {\n const extracted = extractOrganizationUrl({ organisationUrl });\n const escapedProject = encodeURI(project); // encode special characters like spaces\n\n return {\n ...extracted,\n project: escapedProject,\n };\n}\n\nexport function extractRepositoryUrl({\n organisationUrl,\n project,\n repository,\n}: {\n organisationUrl: string;\n project: string;\n repository: string;\n}): AzureDevOpsRepositoryUrl {\n const extracted = extractProjectUrl({ organisationUrl, project });\n const { organisation, 'virtual-directory': virtualDirectory, project: escapedProject } = extracted;\n\n const escapedRepository = encodeURI(repository); // encode special characters like spaces\n const repoSlug = `${virtualDirectory ? `${virtualDirectory}/` : ''}${organisation}/${escapedProject}/_git/${escapedRepository}`;\n\n return {\n ...extracted,\n repository: escapedRepository,\n 'repository-slug': repoSlug,\n };\n}\n\n/**\n * Extract organisation name from organisation URL\n *\n * @param organisationUrl\n *\n * @returns organisation name\n */\nfunction extractOrganisation(organisationUrl: string): string {\n const url = new URL(organisationUrl);\n const { hostname, pathname } = url;\n\n // Check for old style: https://x.visualstudio.com/\n if (hostname.endsWith('.visualstudio.com')) {\n return hostname.split('.')[0]!;\n }\n\n // For new style and on-premise, parse the pathname\n // pathname examples: '/contoso/', '/contoso', '/tfs/contoso/', '/tfs/contoso', '/contoso/Core'\n const pathSegments = pathname.split('/').filter((segment) => segment !== '');\n\n // Check for on-premise style: https://server.domain.com/tfs/contoso/\n if (pathSegments.length >= 2 && hostname !== 'dev.azure.com') {\n return pathSegments[1]!; // Return 'contoso' from '/tfs/contoso/'\n }\n\n // Check for new style: https://dev.azure.com/contoso/ or https://dev.azure.com/contoso or https://dev.azure.com/contoso/Core\n if (pathSegments.length >= 1) {\n return pathSegments[0]!; // Always return the first path segment for dev.azure.com\n }\n\n throw new Error(`Error parsing organisation from organisation url: '${organisationUrl}'.`);\n}\n\n/**\n * Extract virtual directory from organisation URL\n *\n * Virtual Directories are sometimes used in on-premises\n * @param organisationUrl\n *\n * @returns virtual directory\n *\n * @example URLs typically are like this:`https://server.domain.com/tfs/x/` and `tfs` is the virtual directory\n */\nfunction extractVirtualDirectory(organisationUrl: URL) {\n // extract the pathname from the url then split\n // pathname takes the shape '/tfs/x/'\n const path = organisationUrl.pathname.split('/');\n\n // Virtual Directories are sometimes used in on-premises\n // URLs typically are like this: https://server.domain.com/tfs/x/\n // The pathname extracted looks like this: '/tfs/x/'\n return path.length === 4 ? path[1]! : undefined;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["path","changeType: AzdoVersionControlChangeType","reason: string | undefined","reviewers: AzdoIdentityRefWithVote[]","configPath: undefined | string","configContents: undefined | string","organisation: string","path"],"sources":["../../src/azure/models.ts","../../src/azure/utils.ts","../../src/azure/client.ts","../../src/azure/config.ts","../../src/azure/types.ts","../../src/azure/url-parts.ts"],"sourcesContent":["import type { AzdoPullRequestMergeStrategy, AzdoVersionControlChangeType } from './types';\n\n/**\n * Pull request property names used to store metadata about the pull request.\n * https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-properties\n */\nexport const DEVOPS_PR_PROPERTY_MICROSOFT_GIT_SOURCE_REF_NAME = 'Microsoft.Git.PullRequest.SourceRefName';\nexport const DEVOPS_PR_PROPERTY_DEPENDABOT_PACKAGE_MANAGER = 'Dependabot.PackageManager';\nexport const DEVOPS_PR_PROPERTY_DEPENDABOT_DEPENDENCIES = 'Dependabot.Dependencies';\n\n/** File change */\nexport interface IFileChange {\n changeType: AzdoVersionControlChangeType;\n path: string;\n content?: string;\n encoding?: string;\n}\n\n/** Pull request properties */\nexport interface IPullRequestProperties {\n id: number;\n properties?: {\n name: string;\n value: string;\n }[];\n}\n\n/** Pull request creation request */\nexport interface ICreatePullRequest {\n project: string;\n repository: string;\n source: {\n commit: string;\n branch: string;\n };\n target: {\n branch: string;\n };\n author?: {\n email: string;\n name: string;\n };\n title: string;\n description: string;\n commitMessage: string;\n autoComplete?: {\n ignorePolicyConfigIds?: number[];\n mergeStrategy?: AzdoPullRequestMergeStrategy;\n };\n assignees?: string[];\n labels?: string[];\n workItems?: string[];\n changes: IFileChange[];\n properties?: {\n name: string;\n value: string;\n }[];\n}\n\n/** Pull request update request */\nexport interface IUpdatePullRequest {\n project: string;\n repository: string;\n pullRequestId: number;\n commit: string;\n author?: {\n email: string;\n name: string;\n };\n changes: IFileChange[];\n skipIfDraft?: boolean;\n skipIfCommitsFromAuthorsOtherThan?: string;\n skipIfNotBehindTargetBranch?: boolean;\n}\n\n/** Pull request approval request */\nexport interface IApprovePullRequest {\n project: string;\n repository: string;\n pullRequestId: number;\n}\n\n/** Pull request abandon request */\nexport interface IAbandonPullRequest {\n project: string;\n repository: string;\n pullRequestId: number;\n comment?: string;\n deleteSourceBranch?: boolean;\n}\n\n/** Pull request comment */\nexport interface IPullRequestComment {\n project: string;\n repository: string;\n pullRequestId: number;\n content: string;\n userId?: string;\n}\n","import * as path from 'node:path';\n\nimport {\n type DependabotClosePullRequest,\n type DependabotCreatePullRequest,\n type DependabotDependency,\n type DependabotExistingGroupPR,\n DependabotExistingGroupPRSchema,\n type DependabotExistingPR,\n DependabotExistingPRSchema,\n type DependabotUpdatePullRequest,\n} from '@/dependabot';\nimport {\n DEVOPS_PR_PROPERTY_DEPENDABOT_DEPENDENCIES,\n DEVOPS_PR_PROPERTY_DEPENDABOT_PACKAGE_MANAGER,\n type IFileChange,\n type IPullRequestProperties,\n} from './models';\nimport type { AzdoVersionControlChangeType } from './types';\n\nexport function normalizeFilePath(path: string): string {\n // Convert backslashes to forward slashes, convert './' => '/' and ensure the path starts with a forward slash if it doesn't already, this is how DevOps paths are formatted\n return path\n ?.replace(/\\\\/g, '/')\n ?.replace(/^\\.\\//, '/')\n ?.replace(/^([^/])/, '/$1');\n}\n\nexport function normalizeBranchName(branch: string): string;\nexport function normalizeBranchName(branch?: string): string | undefined;\nexport function normalizeBranchName(branch?: string): string | undefined {\n // Strip the 'refs/heads/' prefix from the branch name, if present\n return branch?.replace(/^refs\\/heads\\//i, '');\n}\n\nexport const DependenciesPrPropertySchema = DependabotExistingPRSchema.array().or(DependabotExistingGroupPRSchema);\n\nexport function buildPullRequestProperties(\n packageManager: string,\n dependencies: DependabotExistingPR[] | DependabotExistingGroupPR,\n) {\n return [\n {\n name: DEVOPS_PR_PROPERTY_DEPENDABOT_PACKAGE_MANAGER,\n value: packageManager,\n },\n {\n name: DEVOPS_PR_PROPERTY_DEPENDABOT_DEPENDENCIES,\n value: JSON.stringify(dependencies),\n },\n ];\n}\n\nexport function parsePullRequestProperties(\n pullRequests: IPullRequestProperties[],\n packageManager: string | null,\n): Record<string, DependabotExistingPR[] | DependabotExistingGroupPR> {\n return Object.fromEntries(\n pullRequests\n .filter((pr) => {\n return pr.properties?.find(\n (p) =>\n p.name === DEVOPS_PR_PROPERTY_DEPENDABOT_PACKAGE_MANAGER &&\n (packageManager === null || p.value === packageManager),\n );\n })\n .map((pr) => {\n return [\n pr.id,\n DependenciesPrPropertySchema.parse(\n JSON.parse(pr.properties!.find((p) => p.name === DEVOPS_PR_PROPERTY_DEPENDABOT_DEPENDENCIES)!.value),\n ),\n ];\n }),\n );\n}\n\nexport function getPullRequestForDependencyNames(\n existingPullRequests: IPullRequestProperties[],\n packageManager: string,\n dependencyNames: string[],\n): IPullRequestProperties | undefined {\n return existingPullRequests.find((pr) => {\n return (\n pr.properties?.find(\n (p) => p.name === DEVOPS_PR_PROPERTY_DEPENDABOT_PACKAGE_MANAGER && p.value === packageManager,\n ) &&\n pr.properties?.find(\n (p) =>\n p.name === DEVOPS_PR_PROPERTY_DEPENDABOT_DEPENDENCIES &&\n areEqual(getDependencyNames(DependenciesPrPropertySchema.parse(JSON.parse(p.value))), dependencyNames),\n )\n );\n });\n}\n\nfunction getDependencyNames(dependencies: DependabotExistingPR[] | DependabotExistingGroupPR): string[] {\n const deps = Array.isArray(dependencies) ? dependencies : dependencies.dependencies;\n return deps.map((dep) => dep['dependency-name']?.toString());\n}\n\nfunction areEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n return a.every((name) => b.includes(name));\n}\n\nexport function getPullRequestChangedFilesForOutputData(\n data: DependabotCreatePullRequest | DependabotUpdatePullRequest,\n): IFileChange[] {\n return data['updated-dependency-files']\n .filter((file) => file.type === 'file')\n .map((file) => {\n let changeType: AzdoVersionControlChangeType = 'none';\n if (file.deleted === true || file.operation === 'delete') {\n changeType = 'delete';\n } else if (file.operation === 'update') {\n changeType = 'edit';\n } else {\n changeType = 'add';\n }\n return {\n changeType: changeType,\n path: path.join(file.directory, file.name),\n content: file.content ?? undefined,\n encoding: file.content_encoding || 'utf-8', // default to 'utf-8' if nullish or empty string\n } satisfies IFileChange;\n });\n}\n\nexport function getPullRequestCloseReasonForOutputData(data: DependabotClosePullRequest): string | undefined {\n // The first dependency is the \"lead\" dependency in a multi-dependency update\n const leadDependencyName = data['dependency-names'][0];\n let reason: string | undefined;\n switch (data.reason) {\n case 'dependencies_changed':\n reason = `Looks like the dependencies have changed`;\n break;\n case 'dependency_group_empty':\n reason = `Looks like the dependencies in this group are now empty`;\n break;\n case 'dependency_removed':\n reason = `Looks like ${leadDependencyName} is no longer a dependency`;\n break;\n case 'up_to_date':\n reason = `Looks like ${leadDependencyName} is up-to-date now`;\n break;\n case 'update_no_longer_possible':\n reason = `Looks like ${leadDependencyName} can no longer be updated`;\n break;\n }\n if (reason && reason.length > 0) {\n reason += ', so this is no longer needed.';\n }\n return reason;\n}\n\nexport function getPullRequestDependenciesPropertyValueForOutputData(\n data: DependabotCreatePullRequest,\n): DependabotExistingPR[] | DependabotExistingGroupPR {\n const dependencies = data.dependencies?.map((dep) => {\n return {\n 'dependency-name': dep.name,\n 'dependency-version': dep.version,\n directory: dep.directory,\n };\n });\n const dependencyGroupName = data['dependency-group']?.name;\n if (!dependencyGroupName) return dependencies;\n return {\n 'dependency-group-name': dependencyGroupName,\n dependencies: dependencies,\n } as DependabotExistingGroupPR;\n}\n\nexport function getPullRequestDescription(\n packageManager: string,\n body: string | null | undefined,\n dependencies: DependabotDependency[],\n): string {\n let header = '';\n const footer = '';\n\n // Fix up GitHub mentions encoding issues by removing instances of the zero-width space '\\u200B' as it does not render correctly in Azure DevOps.\n // https://github.com/dependabot/dependabot-core/issues/9572\n // https://github.com/dependabot/dependabot-core/blob/313fcff149b3126cb78b38d15f018907d729f8cc/common/lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb#L245-L252\n const description = (body || '').replace(new RegExp(decodeURIComponent('%EF%BF%BD%EF%BF%BD%EF%BF%BD'), 'g'), '');\n\n // If there is exactly one dependency, add a compatibility score badge to the description header.\n // Compatibility scores are intended for single dependency security updates, not group updates.\n // https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores\n if (dependencies.length === 1) {\n const compatibilityScoreBadges = dependencies.map((dep) => {\n return ``;\n });\n header += `${compatibilityScoreBadges.join(' ')}\\n\\n`;\n }\n\n // Build the full pull request description.\n // The header/footer must not be truncated. If the description is too long, we truncate the body.\n const maxDescriptionLength = 4000;\n const maxDescriptionLengthAfterHeaderAndFooter = maxDescriptionLength - header.length - footer.length;\n return `${header}${description.substring(0, maxDescriptionLengthAfterHeaderAndFooter)}${footer}`;\n}\n","import ky, { isHTTPError, type KyInstance } from 'ky';\nimport { logger } from '@/logger';\nimport type {\n IAbandonPullRequest,\n IApprovePullRequest,\n ICreatePullRequest,\n IPullRequestComment,\n IPullRequestProperties,\n IUpdatePullRequest,\n} from './models';\nimport type {\n AdoProperties,\n AzdoConnectionData,\n AzdoGitBranchStats,\n AzdoGitCommitRef,\n AzdoGitPush,\n AzdoGitPushCreate,\n AzdoGitRef,\n AzdoGitRefUpdateResult,\n AzdoIdentity,\n AzdoIdentityRefWithVote,\n AzdoListResponse,\n AzdoProject,\n AzdoPullRequest,\n AzdoPullRequestCommentThread,\n AzdoRepository,\n AzdoRepositoryItem,\n} from './types';\nimport type { AzureDevOpsOrganizationUrl } from './url-parts';\nimport { normalizeBranchName, normalizeFilePath } from './utils';\n\n/** Returned from AzureDevOpsWebApiClient.getUserId() when no user is authenticated */\nexport const ANONYMOUS_USER_ID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa';\n\n/** Azure DevOps REST API client. */\nexport class AzureDevOpsWebApiClient {\n private readonly organisationApiUrl: string;\n private readonly identityApiUrl: string;\n private readonly accessToken: string;\n private readonly debug: boolean;\n private readonly client: KyInstance;\n\n private authenticatedUserId?: string;\n private resolvedUserIds: Record<string, string>;\n\n public static API_VERSION = '5.0'; // this is the same version used by dependabot-core\n public static API_VERSION_PREVIEW = '5.0-preview';\n\n constructor(url: AzureDevOpsOrganizationUrl, accessToken: string, debug: boolean = false) {\n this.organisationApiUrl = url.value.toString().replace(/\\/$/, ''); // trim trailing slash\n this.identityApiUrl = url['identity-api-url'].toString().replace(/\\/$/, ''); // trim trailing slash\n this.accessToken = accessToken;\n this.debug = debug;\n this.resolvedUserIds = {};\n\n this.client = this.createClient();\n }\n\n /**\n * Get the identity of the authenticated user.\n * @returns\n */\n public async getUserId(): Promise<string> {\n if (!this.authenticatedUserId) {\n const connectionData = await this.client\n .get<AzdoConnectionData>(\n this.makeUrl(`${this.organisationApiUrl}/_apis/connectiondata`, AzureDevOpsWebApiClient.API_VERSION_PREVIEW),\n )\n .json();\n this.authenticatedUserId = connectionData?.authenticatedUser?.id;\n if (!this.authenticatedUserId) {\n throw new Error('Failed to get authenticated user ID');\n }\n }\n return this.authenticatedUserId;\n }\n\n /**\n * Get the identity id from a user name, email, or group name.\n * Requires scope \"Identity (Read)\" (vso.identity).\n * @param userNameEmailOrGroupName\n * @returns\n */\n public async resolveIdentityId(userNameEmailOrGroupName: string): Promise<string | undefined> {\n if (this.resolvedUserIds[userNameEmailOrGroupName]) {\n return this.resolvedUserIds[userNameEmailOrGroupName];\n }\n try {\n const identities = await this.client\n .get<AzdoListResponse<AzdoIdentity[]>>(\n this.makeUrl(`${this.identityApiUrl}/_apis/identities`, {\n searchFilter: 'General',\n filterValue: userNameEmailOrGroupName,\n queryMembership: 'None',\n }),\n )\n .json();\n if (!identities?.value || identities.value.length === 0) {\n return undefined;\n }\n this.resolvedUserIds[userNameEmailOrGroupName] = identities.value[0]!.id;\n return this.resolvedUserIds[userNameEmailOrGroupName];\n } catch (e) {\n logger.error(`Failed to resolve user id: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return undefined;\n }\n }\n\n public async getProjects(): Promise<AzdoListResponse<AzdoProject[]> | undefined> {\n try {\n const projects = await this.client\n .get<AzdoListResponse<AzdoProject[]>>(this.makeUrl(`${this.organisationApiUrl}/_apis/projects`))\n .json();\n return projects;\n } catch (e) {\n logger.error(`Failed to get projects: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return undefined;\n }\n }\n\n public async getProject(idOrName: string): Promise<AzdoProject | undefined> {\n try {\n const project = await this.client\n .get<AzdoProject>(this.makeUrl(`${this.organisationApiUrl}/_apis/projects/${encodeURIComponent(idOrName)}`))\n .json();\n return project;\n } catch (e) {\n logger.error(`Failed to get project: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return undefined;\n }\n }\n\n public async getRepositories(projectIdOrName: string): Promise<AzdoListResponse<AzdoRepository[]> | undefined> {\n try {\n const repos = await this.client\n .get<AzdoListResponse<AzdoRepository[]>>(\n this.makeUrl(`${this.organisationApiUrl}/${encodeURIComponent(projectIdOrName)}/_apis/git/repositories`),\n )\n .json();\n return repos;\n } catch (e) {\n logger.error(`Failed to get repositories: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return undefined;\n }\n }\n\n public async getRepository(projectIdOrName: string, repositoryIdOrName: string): Promise<AzdoRepository | undefined> {\n try {\n const repo = await this.client\n .get<AzdoRepository>(\n this.makeUrl(\n `${this.organisationApiUrl}/${encodeURIComponent(projectIdOrName)}/_apis/git/repositories/${encodeURIComponent(repositoryIdOrName)}`,\n ),\n )\n .json();\n return repo;\n } catch (e) {\n if (isHTTPError(e) && e.response.status === 404) {\n // repository no longer exists\n return undefined;\n } else {\n logger.error(`Failed to get repository: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n }\n return undefined;\n }\n }\n\n public async getRepositoryItem(\n projectIdOrName: string,\n repositoryIdOrName: string,\n path: string,\n includeContent: boolean = true,\n latestProcessedChange: boolean = true,\n ): Promise<AzdoRepositoryItem | undefined> {\n try {\n const item = await this.client\n .get<AzdoRepositoryItem>(\n this.makeUrl(\n `${this.organisationApiUrl}/${encodeURIComponent(projectIdOrName)}/_apis/git/repositories/${encodeURIComponent(repositoryIdOrName)}/items`,\n {\n path,\n includeContent,\n latestProcessedChange,\n },\n ),\n )\n .json();\n return item;\n } catch (e) {\n if (isHTTPError(e) && e.response.status === 404) {\n // item does not exist\n return undefined;\n } else {\n logger.error(`Failed to get repository item: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n }\n return undefined;\n }\n }\n\n /**\n * Get the default branch for a repository.\n * Requires scope \"Code (Read)\" (vso.code).\n * @param project\n * @param repository\n * @returns\n */\n public async getDefaultBranch(project: string, repository: string): Promise<string | undefined> {\n try {\n const repo = await this.client\n .get<AzdoRepository>(this.makeUrl(`${this.organisationApiUrl}/${project}/_apis/git/repositories/${repository}`))\n .json();\n if (!repo) {\n throw new Error(`Repository '${project}/${repository}' not found`);\n }\n\n return normalizeBranchName(repo.defaultBranch);\n } catch (e) {\n logger.error(`Failed to get default branch for '${project}/${repository}': ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return undefined;\n }\n }\n\n /**\n * Get the list of branch names for a repository.\n * Requires scope \"Code (Read)\" (vso.code).\n * @param project\n * @param repository\n * @returns\n */\n public async getBranchNames(project: string, repository: string): Promise<string[] | undefined> {\n try {\n const refs = await this.client\n .get<AzdoListResponse<AzdoGitRef[]>>(\n this.makeUrl(`${this.organisationApiUrl}/${project}/_apis/git/repositories/${repository}/refs`),\n )\n .json();\n if (!refs) {\n throw new Error(`Repository '${project}/${repository}' not found`);\n }\n\n return refs.value?.map((r) => normalizeBranchName(r.name)) || [];\n } catch (e) {\n logger.error(`Failed to list branch names for '${project}/${repository}': ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return undefined;\n }\n }\n\n /**\n * Get the properties for all active pull request created by the supplied user.\n * Requires scope \"Code (Read)\" (vso.code).\n * @param project\n * @param repository\n * @param creator\n * @returns\n */\n public async getActivePullRequestProperties(\n project: string,\n repository: string,\n creator: string,\n ): Promise<IPullRequestProperties[]> {\n try {\n const pullRequests = await this.client\n .get<AzdoListResponse<AzdoPullRequest[]>>(\n this.makeUrl(`${this.organisationApiUrl}/${project}/_apis/git/repositories/${repository}/pullrequests`, {\n 'searchCriteria.creatorId': isGuid(creator) ? creator : await this.getUserId(),\n 'searchCriteria.status': 'Active',\n }),\n )\n .json();\n if (!pullRequests?.value || pullRequests.value.length === 0) {\n return [];\n }\n\n return await Promise.all(\n pullRequests.value.map(async (pr) => {\n const properties = await this.client\n .get<AzdoListResponse<AdoProperties>>(\n this.makeUrl(\n `${this.organisationApiUrl}/${project}/_apis/git/repositories/${repository}/pullrequests/${pr.pullRequestId}/properties`,\n ),\n )\n .json();\n return {\n id: pr.pullRequestId,\n properties: Object.entries(properties?.value || {}).map(([key, val]) => ({\n name: key,\n value: val?.$value,\n })),\n };\n }),\n );\n } catch (e) {\n logger.error(`Failed to list active pull request properties: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return [];\n }\n }\n\n /**\n * Create a new pull request.\n * Requires scope \"Code (Write)\" (vso.code_write).\n * Requires scope \"Identity (Read)\" (vso.identity), if assignees are specified.\n * @param pr\n * @returns\n */\n public async createPullRequest(pr: ICreatePullRequest): Promise<number | null> {\n logger.info(`Creating pull request '${pr.title}'...`);\n try {\n const userId = await this.getUserId();\n\n // Map the list of the pull request reviewer ids\n // NOTE: Azure DevOps does not have a concept of assignees.\n // We treat them as optional reviewers. Branch policies should be used for required reviewers.\n const reviewers: AzdoIdentityRefWithVote[] = [];\n if (pr.assignees && pr.assignees.length > 0) {\n for (const assignee of pr.assignees) {\n const identityId = isGuid(assignee) ? assignee : await this.resolveIdentityId(assignee);\n if (identityId && !reviewers.some((r) => r.id === identityId)) {\n reviewers.push({\n id: identityId,\n });\n } else {\n logger.warn(`Unable to resolve assignee identity '${assignee}'`);\n }\n }\n }\n\n // Create the source branch and push a commit with the dependency file changes\n logger.info(` - Pushing ${pr.changes.length} file change(s) to branch '${pr.source.branch}'...`);\n const push = await this.client\n .post<AzdoGitPush>(\n this.makeUrl(`${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pushes`),\n {\n json: {\n refUpdates: [\n {\n name: `refs/heads/${pr.source.branch}`,\n oldObjectId: pr.source.commit,\n },\n ],\n commits: [\n {\n comment: pr.commitMessage,\n author: pr.author,\n changes: pr.changes\n .filter((change) => change.changeType !== 'none')\n .map(({ changeType, ...change }) => {\n return {\n changeType,\n item: { path: normalizeFilePath(change.path) },\n newContent:\n changeType !== 'delete'\n ? {\n content: Buffer.from(change.content!, <BufferEncoding>change.encoding).toString(\n 'base64',\n ),\n contentType: 'base64encoded',\n }\n : undefined,\n } satisfies AzdoGitPushCreate['commits'][0]['changes'][0];\n }),\n },\n ],\n } satisfies AzdoGitPushCreate,\n },\n )\n .json();\n if (!push?.commits?.length) {\n throw new Error('Failed to push changes to source branch, no commits were created');\n }\n logger.info(` - Pushed commit: ${push.commits.map((c) => c.commitId).join(', ')}.`);\n\n // Create the pull request\n logger.info(` - Creating pull request to merge '${pr.source.branch}' into '${pr.target.branch}'...`);\n const pullRequest = await this.client\n .post<AzdoPullRequest>(\n this.makeUrl(`${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests`),\n {\n json: {\n sourceRefName: `refs/heads/${pr.source.branch}`,\n targetRefName: `refs/heads/${pr.target.branch}`,\n title: pr.title,\n description: pr.description,\n reviewers: reviewers,\n workItemRefs: pr.workItems?.map((id) => ({ id: id })),\n labels: pr.labels?.map((label) => ({ name: label })),\n },\n },\n )\n .json();\n if (!pullRequest?.pullRequestId) {\n throw new Error('Failed to create pull request, no pull request id was returned');\n }\n logger.info(` - Created pull request: #${pullRequest.pullRequestId}.`);\n\n // Add the pull request properties\n if (pr.properties && pr.properties.length > 0) {\n logger.info(` - Adding dependency metadata to pull request properties...`);\n const newProperties = await this.client\n .patch<AzdoListResponse<AdoProperties>>(\n this.makeUrl(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests/${pullRequest.pullRequestId}/properties`,\n ),\n {\n json: pr.properties.map((property) => {\n return {\n op: 'add',\n path: `/${property.name}`,\n value: property.value,\n };\n }),\n headers: { 'Content-Type': 'application/json-patch+json' },\n },\n )\n .json();\n if (!newProperties?.count) {\n throw new Error('Failed to add dependency metadata properties to pull request');\n }\n }\n\n // TODO: Upload the pull request description as a 'changes.md' file attachment?\n // This might be a way to work around the 4000 character limit for PR descriptions, but needs more investigation.\n // https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-attachments/create?view=azure-devops-rest-7.1\n\n // Set the pull request auto-complete status\n if (pr.autoComplete) {\n logger.info(` - Updating auto-complete options...`);\n const updatedPullRequest = await this.client\n .patch<AzdoPullRequest>(\n this.makeUrl(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests/${pullRequest.pullRequestId}`,\n ),\n {\n json: {\n autoCompleteSetBy: { id: userId },\n completionOptions: {\n autoCompleteIgnoreConfigIds: pr.autoComplete.ignorePolicyConfigIds,\n deleteSourceBranch: true,\n mergeCommitMessage: mergeCommitMessage(pullRequest.pullRequestId, pr.title, pr.description),\n mergeStrategy: pr.autoComplete.mergeStrategy,\n transitionWorkItems: false,\n },\n },\n },\n )\n .json();\n if (!updatedPullRequest || updatedPullRequest.autoCompleteSetBy?.id !== userId) {\n throw new Error('Failed to set auto-complete on pull request');\n }\n }\n\n logger.info(` - Pull request was created successfully.`);\n return pullRequest.pullRequestId;\n } catch (e) {\n logger.error(`Failed to create pull request: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return null;\n }\n }\n\n /**\n * Update a pull request.\n * Requires scope \"Code (Read & Write)\" (vso.code, vso.code_write).\n * @param pr\n * @returns\n */\n public async updatePullRequest(pr: IUpdatePullRequest): Promise<boolean> {\n logger.info(`Updating pull request #${pr.pullRequestId}...`);\n try {\n // Get the pull request details\n const pullRequest = await this.client\n .get<AzdoPullRequest>(\n this.makeUrl(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests/${pr.pullRequestId}`,\n ),\n )\n .json();\n if (!pullRequest) {\n throw new Error(`Pull request #${pr.pullRequestId} not found`);\n }\n\n // Skip if the pull request is a draft\n if (pr.skipIfDraft && pullRequest.isDraft) {\n logger.info(` - Skipping update as pull request is currently marked as a draft.`);\n return true;\n }\n\n // Skip if the pull request has been modified by another author\n if (pr.skipIfCommitsFromAuthorsOtherThan) {\n const commits = await this.client\n .get<AzdoListResponse<AzdoGitCommitRef[]>>(\n this.makeUrl(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests/${pr.pullRequestId}/commits`,\n ),\n )\n .json();\n if (commits?.value?.some((c) => c.author?.email !== pr.skipIfCommitsFromAuthorsOtherThan)) {\n logger.info(` - Skipping update as pull request has been modified by another user.`);\n return true;\n }\n }\n\n // Get the branch stats to check if the source branch is behind the target branch\n const stats = await this.client\n .get<AzdoGitBranchStats>(\n this.makeUrl(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/stats/branches`,\n {\n name: normalizeBranchName(pullRequest.sourceRefName),\n },\n ),\n )\n .json();\n if (stats?.behindCount === undefined) {\n throw new Error(`Failed to get branch stats for '${pullRequest.sourceRefName}'`);\n }\n\n // Skip if the source branch is not behind the target branch\n if (pr.skipIfNotBehindTargetBranch && stats.behindCount === 0) {\n logger.info(` - Skipping update as source branch is not behind target branch.`);\n return true;\n }\n\n // Rebase the target branch into the source branch to reset the \"behind\" count\n const sourceBranchName = normalizeBranchName(pullRequest.sourceRefName);\n const targetBranchName = normalizeBranchName(pullRequest.targetRefName);\n if (stats.behindCount > 0) {\n logger.info(\n ` - Rebasing '${targetBranchName}' into '${sourceBranchName}' (${stats.behindCount} commit(s) behind)...`,\n );\n const rebase = await this.client\n .post<AzdoListResponse<AzdoGitRefUpdateResult[]>>(\n this.makeUrl(`${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/refs`),\n {\n json: [\n {\n name: pullRequest.sourceRefName,\n oldObjectId: pullRequest.lastMergeSourceCommit.commitId,\n newObjectId: pr.commit,\n },\n ],\n },\n )\n .json();\n if (rebase?.value?.[0]?.success !== true) {\n throw new Error('Failed to rebase the target branch into the source branch');\n }\n }\n\n // Push all file changes to the source branch\n logger.info(` - Pushing ${pr.changes.length} file change(s) to branch '${pullRequest.sourceRefName}'...`);\n const push = await this.client\n .post<AzdoGitPush>(\n this.makeUrl(`${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pushes`),\n {\n json: {\n refUpdates: [\n {\n name: pullRequest.sourceRefName,\n oldObjectId: pr.commit,\n },\n ],\n commits: [\n {\n comment:\n pullRequest.mergeStatus === 'conflicts'\n ? 'Resolve merge conflicts'\n : `Rebase '${sourceBranchName}' onto '${targetBranchName}'`,\n author: pr.author,\n changes: pr.changes\n .filter((change) => change.changeType !== 'none')\n .map(({ changeType, ...change }) => {\n return {\n changeType,\n item: { path: normalizeFilePath(change.path) },\n newContent:\n changeType !== 'delete'\n ? {\n content: Buffer.from(change.content!, <BufferEncoding>change.encoding).toString(\n 'base64',\n ),\n contentType: 'base64encoded',\n }\n : undefined,\n } satisfies AzdoGitPushCreate['commits'][0]['changes'][0];\n }),\n },\n ],\n } satisfies AzdoGitPushCreate,\n },\n )\n .json();\n if (!push?.commits?.length) {\n throw new Error('Failed to push changes to source branch, no commits were created');\n }\n logger.info(` - Pushed commit: ${push.commits.map((c) => c.commitId).join(', ')}.`);\n\n logger.info(` - Pull request was updated successfully.`);\n return true;\n } catch (e) {\n logger.error(`Failed to update pull request: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return false;\n }\n }\n\n /**\n * Approve a pull request.\n * Requires scope \"Code (Write)\" (vso.code_write).\n * @param pr\n * @returns\n */\n public async approvePullRequest(pr: IApprovePullRequest): Promise<boolean> {\n logger.info(`Approving pull request #${pr.pullRequestId}...`);\n try {\n // Approve the pull request\n logger.info(` - Updating reviewer vote on pull request...`);\n const userId = await this.getUserId();\n const userVote = await this.client\n .put<AzdoIdentityRefWithVote>(\n this.makeUrl(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests/${pr.pullRequestId}/reviewers/${userId}`,\n // API version 7.1 is required to use the 'isReapprove' parameter\n // See: https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-reviewers/create-pull-request-reviewer?view=azure-devops-rest-7.1&tabs=HTTP#request-body\n // https://learn.microsoft.com/en-us/azure/devops/integrate/concepts/rest-api-versioning?view=azure-devops#supported-versions\n '7.1',\n ),\n {\n json: {\n // Vote 10 = \"approved\"; 5 = \"approved with suggestions\"; 0 = \"no vote\"; -5 = \"waiting for author\"; -10 = \"rejected\"\n vote: 10,\n // Reapprove must be set to true after the 2023 August 23 update;\n // Approval of a previous PR iteration does not count in later iterations, which means we must (re)approve every after push to the source branch\n // See: https://learn.microsoft.com/en-us/azure/devops/release-notes/2023/sprint-226-update#new-branch-policy-preventing-users-to-approve-their-own-changes\n // https://github.com/mburumaxwell/dependabot-azure-devops/issues/1069\n isReapprove: true,\n },\n },\n )\n .json();\n if (userVote?.vote !== 10) {\n throw new Error('Failed to approve pull request, vote was not recorded');\n }\n\n logger.info(` - Pull request was approved successfully.`);\n return true;\n } catch (e) {\n logger.error(`Failed to approve pull request: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return false;\n }\n }\n\n /**\n * Abandon a pull request.\n * Requires scope \"Code (Write)\" (vso.code_write).\n * @param pr\n * @returns\n */\n public async abandonPullRequest(pr: IAbandonPullRequest): Promise<boolean> {\n logger.info(`Abandoning pull request #${pr.pullRequestId}...`);\n try {\n const userId = await this.getUserId();\n\n // Add a comment to the pull request, if supplied\n if (pr.comment) {\n logger.info(` - Adding abandonment reason comment to pull request...`);\n const threadId = await this.addCommentThread({\n ...pr,\n content: pr.comment,\n userId,\n });\n if (!threadId) {\n throw new Error('Failed to add comment to pull request, thread was not created');\n }\n }\n\n // Abandon the pull request\n logger.info(` - Abandoning pull request...`);\n const abandonedPullRequest = await this.client\n .patch<AzdoPullRequest>(\n this.makeUrl(\n `${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/pullrequests/${pr.pullRequestId}`,\n ),\n {\n json: {\n status: 'abandoned',\n closedBy: { id: userId },\n } satisfies Pick<AzdoPullRequest, 'status' | 'closedBy'>,\n },\n )\n .json();\n if (abandonedPullRequest?.status !== 'abandoned') {\n throw new Error('Failed to abandon pull request, status was not updated');\n }\n\n // Delete the source branch if required\n if (pr.deleteSourceBranch) {\n logger.info(` - Deleting source branch...`);\n const deletedBranch = await this.client\n .post<AzdoListResponse<AzdoGitRefUpdateResult[]>>(\n this.makeUrl(`${this.organisationApiUrl}/${pr.project}/_apis/git/repositories/${pr.repository}/refs`),\n {\n json: [\n {\n name: abandonedPullRequest.sourceRefName,\n oldObjectId: abandonedPullRequest.lastMergeSourceCommit.commitId,\n newObjectId: '0000000000000000000000000000000000000000',\n isLocked: false,\n },\n ],\n },\n )\n .json();\n if (deletedBranch?.value?.[0]?.success !== true) {\n throw new Error('Failed to delete the source branch');\n }\n }\n\n logger.info(` - Pull request was abandoned successfully.`);\n return true;\n } catch (e) {\n logger.error(`Failed to abandon pull request: ${e}`);\n logger.debug(e); // Dump the error stack trace to help with debugging\n return false;\n }\n }\n\n /**\n * Add a comment thread on a pull request.\n * Requires scope \"Code (Write)\" (vso.code_write).\n */\n public async addCommentThread(comment: IPullRequestComment): Promise<number | undefined> {\n const userId = comment.userId ?? (await this.getUserId());\n type CreationType = {\n status: AzdoPullRequestCommentThread['status'];\n comments: Partial<AzdoPullRequestCommentThread['comments'][number]>[];\n };\n const thread = await this.client\n .post<AzdoPullRequestCommentThread>(\n this.makeUrl(\n `${this.organisationApiUrl}/${comment.project}/_apis/git/repositories/${comment.repository}/pullrequests/${comment.pullRequestId}/threads`,\n ),\n {\n json: {\n status: 'closed',\n comments: [\n {\n author: { id: userId },\n content: comment.content,\n commentType: 'system',\n },\n ],\n } satisfies CreationType,\n },\n )\n .json();\n return thread?.id;\n }\n\n private makeUrl(url: string): string;\n private makeUrl(url: string, apiVersion: string): string;\n private makeUrl(url: string, params: Record<string, unknown>): string;\n private makeUrl(url: string, params: Record<string, unknown>, apiVersion: string): string;\n private makeUrl(\n url: string,\n params?: Record<string, unknown> | string,\n apiVersion: string = AzureDevOpsWebApiClient.API_VERSION,\n ): string {\n if (typeof params === 'string') {\n apiVersion = params;\n params = {};\n }\n\n const queryString = Object.entries({ 'api-version': apiVersion, ...params })\n .map(([key, value]) => `${key}=${value}`)\n .join('&');\n return `${url}?${queryString}`;\n }\n\n private createClient() {\n return ky.create({\n headers: {\n Authorization: `Basic ${Buffer.from(`:${this.accessToken}`).toString('base64')}`,\n Accept: 'application/json',\n },\n hooks: {\n beforeRequest: [\n async (request, options) => {\n if (this.debug) logger.debug(`🌎 🠊 [${request.method}] ${request.url}`);\n },\n ],\n afterResponse: [\n async (request, options, response) => {\n if (this.debug) {\n logger.debug(`🌎 🠈 [${response.status}] ${response.statusText}`);\n\n // log the request and response for debugging\n if (request.body) {\n logger.debug(`REQUEST: ${JSON.stringify(request.body)}`);\n }\n // const body = await response.text();\n // if (body) {\n // logger.debug(`RESPONSE: ${body}`);\n // }\n }\n },\n ],\n beforeRetry: [\n async ({ request, options, error, retryCount }) => {\n if (this.debug && isHTTPError(error)) {\n logger.debug(`⏳ Retrying failed request with status code: ${error.response.status}`);\n }\n },\n ],\n },\n retry: {\n limit: 3,\n delay: (attempt) => 3000, // all attempts after 3 seconds\n },\n });\n }\n}\n\nfunction mergeCommitMessage(id: number, title: string, description: string): string {\n //\n // The merge commit message should contain the PR number and title for tracking.\n // This is the default behaviour in Azure DevOps.\n // Example:\n // Merged PR 24093: Bump Tingle.Extensions.Logging.LogAnalytics from 3.4.2-ci0005 to 3.4.2-ci0006\n //\n // Bumps [Tingle.Extensions.Logging.LogAnalytics](...) from 3.4.2-ci0005 to 3.4.2-ci0006\n // - [Release notes](....)\n // - [Changelog](....)\n // - [Commits](....)\n //\n // There appears to be a DevOps bug when setting \"completeOptions\" with a \"mergeCommitMessage\" even when truncated to 4000 characters.\n // The error message is:\n // Invalid argument value.\n // Parameter name: Completion options have exceeded the maximum encoded length (4184/4000)\n //\n // The effective limit seems to be about 3500 characters:\n // https://developercommunity.visualstudio.com/t/raise-the-character-limit-for-pull-request-descrip/365708#T-N424531\n //\n return `Merged PR ${id}: ${title}\\n\\n${description}`.slice(0, 3500);\n}\n\nfunction isGuid(guid: string): boolean {\n const regex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\n return regex.test(guid);\n}\n","import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport * as path from 'node:path';\nimport ky from 'ky';\n\nimport {\n type DependabotConfig,\n POSSIBLE_CONFIG_FILE_PATHS,\n parseDependabotConfig,\n type VariableFinderFn,\n} from '@/dependabot';\nimport { logger } from '@/logger';\nimport type { AzureDevOpsRepositoryUrl } from './url-parts';\n\n/**\n * Parse the dependabot config YAML file to specify update configuration.\n * The file should be located at any of `POSSIBLE_CONFIG_FILE_PATHS`.\n *\n * To view YAML file format, visit\n * https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#allow\n *\n * @returns {DependabotConfig} config - the dependabot configuration\n */\nexport async function getDependabotConfig({\n url,\n token,\n remote,\n rootDir = process.cwd(),\n variableFinder,\n}: {\n url: AzureDevOpsRepositoryUrl;\n token: string;\n /**\n * Whether to fetch the configuration file via the REST API (true) or look for it locally (false).\n */\n remote: boolean;\n rootDir?: string;\n variableFinder: VariableFinderFn;\n}): Promise<DependabotConfig> {\n let configPath: undefined | string;\n let configContents: undefined | string;\n\n /*\n * The configuration file can be available locally if the repository is cloned.\n * Otherwise, we should get it via the API which supports 2 scenarios:\n * 1. Running the pipeline without cloning, which is useful for huge repositories (multiple submodules or large commit log)\n * 2. Running a single pipeline to update multiple repositories https://github.com/mburumaxwell/dependabot-azure-devops/issues/328\n */\n\n if (remote) {\n logger.debug(`Attempting to fetch configuration file via REST API ...`);\n for (const fp of POSSIBLE_CONFIG_FILE_PATHS) {\n // make HTTP request\n const requestUrl = `${url.value}${url.project}/_apis/git/repositories/${url.repository}/items?path=/${fp}`;\n logger.debug(`GET ${requestUrl}`);\n\n try {\n const authHeader = `Basic ${Buffer.from(`x-access-token:${token}`).toString('base64')}`;\n const response = await ky.get(requestUrl, {\n headers: {\n Authorization: authHeader,\n Accept: '*/*', // Gotcha!!! without this SH*T fails terribly\n },\n // 401, 403 and 404 are handled explicitly\n throwHttpErrors: (status) => ![401, 403, 404].includes(status),\n });\n if (response.ok) {\n logger.debug(`Found configuration file at '${requestUrl}'`);\n configContents = await response.text();\n configPath = fp;\n break;\n } else if (response.status === 404) {\n logger.trace(`No configuration file at '${requestUrl}'`);\n // biome-ignore lint/complexity/noUselessContinue: continue is useful here for clarity\n continue;\n } else if (response.status === 401) {\n throw new Error(`No or invalid access token has been provided to access '${requestUrl}'`);\n } else if (response.status === 403) {\n throw new Error(`The access token provided does not have permissions to access '${requestUrl}'`);\n }\n } catch (error) {\n if (error instanceof Error && error.message.includes('access token')) {\n throw error;\n } else {\n throw error;\n }\n }\n }\n } else {\n for (const fp of POSSIBLE_CONFIG_FILE_PATHS) {\n const filePath = path.join(rootDir, fp);\n if (existsSync(filePath)) {\n logger.debug(`Found configuration file cloned at ${filePath}`);\n configContents = await readFile(filePath, 'utf-8');\n configPath = filePath;\n break;\n } else {\n logger.trace(`No configuration file cloned at ${filePath}`);\n }\n }\n }\n\n // Ensure we have file contents. Otherwise throw a well readable error.\n if (!configContents || !configPath || typeof configContents !== 'string') {\n throw new Error(`Configuration file not found at possible locations: ${POSSIBLE_CONFIG_FILE_PATHS.join(', ')}`);\n } else {\n logger.trace('Configuration file contents read.');\n }\n\n return await parseDependabotConfig({ configContents, configPath, variableFinder });\n}\n","import { z } from 'zod';\n\nexport const AzdoVersionControlChangeTypeSchema = z.enum([\n 'none',\n 'add',\n 'edit',\n 'encoding',\n 'rename',\n 'delete',\n 'undelete',\n 'branch',\n 'merge',\n 'lock',\n 'rollback',\n 'sourceRename',\n 'targetRename',\n 'property',\n 'all',\n]);\nexport type AzdoVersionControlChangeType = z.infer<typeof AzdoVersionControlChangeTypeSchema>;\n\nexport const AZDO_PULL_REQUEST_MERGE_STRATEGIES = ['noFastForward', 'squash', 'rebase', 'rebaseMerge'] as const;\nexport const AzdoPullRequestMergeStrategySchema = z.enum(AZDO_PULL_REQUEST_MERGE_STRATEGIES);\nexport type AzdoPullRequestMergeStrategy = z.infer<typeof AzdoPullRequestMergeStrategySchema>;\n\nexport const AzdoCommentThreadStatusSchema = z.enum([\n 'unknown',\n 'active',\n 'fixed',\n 'wontFix',\n 'closed',\n 'byDesign',\n 'pending',\n]);\nexport type AzdoCommentThreadStatus = z.infer<typeof AzdoCommentThreadStatusSchema>;\nexport const AzdoCommentTypeSchema = z.enum(['unknown', 'text', 'codeChange', 'system']);\nexport type AzdoCommentType = z.infer<typeof AzdoCommentTypeSchema>;\n\nexport const AzdoPullRequestAsyncStatusSchema = z.enum([\n 'notSet',\n 'queued',\n 'conflicts',\n 'succeeded',\n 'rejectedByPolicy',\n 'failure',\n]);\nexport type AzdoPullRequestAsyncStatus = z.infer<typeof AzdoPullRequestAsyncStatusSchema>;\nexport const AzdoPullRequestStatusSchema = z.enum(['notSet', 'active', 'abandoned', 'completed', 'all']);\nexport type AzdoPullRequestStatus = z.infer<typeof AzdoPullRequestStatusSchema>;\n\nexport const AzdoProjectSchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string().optional(),\n url: z.string(),\n state: z.enum(['deleting', 'new', 'wellFormed', 'createPending', 'all', 'unchanged', 'deleted']),\n _links: z\n .object({\n self: z.object({ href: z.string() }),\n collection: z.object({ href: z.string() }),\n web: z.object({ href: z.string() }),\n })\n .optional(),\n});\nexport type AzdoProject = z.infer<typeof AzdoProjectSchema>;\n\nexport const AzdoRepositorySchema = z.object({\n id: z.string(),\n name: z.string(),\n defaultBranch: z.string().optional(),\n project: AzdoProjectSchema,\n isDisabled: z.boolean().optional(),\n isFork: z.boolean().optional(),\n url: z.string(),\n remoteUrl: z.string(),\n webUrl: z.string(),\n});\nexport type AzdoRepository = z.infer<typeof AzdoRepositorySchema>;\n\nexport type AzdoListResponse<T> = {\n value?: T;\n count: number;\n};\n\nexport const AzdoIdentitySchema = z.object({\n id: z.string(),\n displayName: z.string(),\n url: z.string(),\n});\nexport type AzdoIdentity = z.infer<typeof AzdoIdentitySchema>;\nexport const AzdoIdentityRefSchema = z.object({\n id: z.string().optional(),\n displayName: z.string().optional(),\n url: z.string().optional(),\n});\nexport type AzdoIdentityRef = z.infer<typeof AzdoIdentityRefSchema>;\n\nexport const AzdoConnectionDataSchema = z.object({\n authenticatedUser: AzdoIdentitySchema,\n authorizedUser: AzdoIdentitySchema,\n});\nexport type AzdoConnectionData = z.infer<typeof AzdoConnectionDataSchema>;\n\nexport const AzdoGitUserDateSchema = z.object({\n name: z.string(),\n email: z.string(),\n date: z.string().optional(),\n});\nexport type AzdoGitUserDate = z.infer<typeof AzdoGitUserDateSchema>;\nexport const AzdoGitRefSchema = z.object({\n name: z.string(),\n objectId: z.string(),\n isLocked: z.boolean().optional(),\n});\nexport type AzdoGitRef = z.infer<typeof AzdoGitRefSchema>;\nexport const AzdoGitRefUpdateResultSchema = AzdoGitRefSchema.extend({\n oldObjectId: z.string(),\n newObjectId: z.string(),\n success: z.boolean(),\n customMessage: z.string().optional(),\n});\nexport type AzdoGitRefUpdateResult = z.infer<typeof AzdoGitRefUpdateResultSchema>;\nexport const AzdoGitChangeSchema = z.object({\n changeType: AzdoVersionControlChangeTypeSchema,\n newContent: z\n .object({\n content: z.string(),\n contentType: z.enum(['rawtext', 'base64encoded']),\n })\n .optional(),\n});\nexport type AzdoGitChange = z.infer<typeof AzdoGitChangeSchema>;\nexport const AzdoGitCommitRefSchema = z.object({\n commitId: z.string().optional(),\n author: AzdoGitUserDateSchema.optional(),\n committer: AzdoGitUserDateSchema.optional(),\n changes: AzdoGitChangeSchema.array(),\n});\nexport type AzdoGitCommitRef = z.infer<typeof AzdoGitCommitRefSchema>;\nexport const AzdoGitPushSchema = z.object({\n commits: AzdoGitCommitRefSchema.array(),\n refUpdates: AzdoGitRefSchema.array(),\n});\nexport type AzdoGitPush = z.infer<typeof AzdoGitPushSchema>;\nexport const AzdoGitPushCreateSchema = z.object({\n refUpdates: z\n .object({\n name: z.string(),\n oldObjectId: z.string(),\n newObjectId: z.string().optional(),\n })\n .array(),\n commits: z\n .object({\n comment: z.string(),\n author: AzdoGitUserDateSchema.optional(),\n changes: AzdoGitChangeSchema.extend({\n item: z.object({ path: z.string() }),\n }).array(),\n })\n .array(),\n});\nexport type AzdoGitPushCreate = z.infer<typeof AzdoGitPushCreateSchema>;\nexport const AzdoGitBranchStatsSchema = z.object({\n aheadCount: z.number(),\n behindCount: z.number(),\n});\nexport type AzdoGitBranchStats = z.infer<typeof AzdoGitBranchStatsSchema>;\n\nexport const AzdoRepositoryItemSchema = z.object({\n latestProcessedChange: AzdoGitCommitRefSchema.optional(),\n content: z.string().optional(),\n});\nexport type AzdoRepositoryItem = z.infer<typeof AzdoRepositoryItemSchema>;\n\nexport const AzdoPullRequestSchema = z.object({\n pullRequestId: z.number(),\n status: AzdoPullRequestStatusSchema,\n isDraft: z.boolean(),\n sourceRefName: z.string(),\n targetRefName: z.string(),\n lastMergeCommit: AzdoGitCommitRefSchema,\n lastMergeSourceCommit: AzdoGitCommitRefSchema,\n mergeStatus: AzdoPullRequestAsyncStatusSchema,\n autoCompleteSetBy: AzdoIdentityRefSchema.optional(),\n closedBy: AzdoIdentityRefSchema.optional(),\n});\nexport type AzdoPullRequest = z.infer<typeof AzdoPullRequestSchema>;\n\nexport const AdoPropertiesSchema = z.record(\n z.string(),\n z.object({\n $type: z.string(),\n $value: z.string(),\n }),\n);\nexport type AdoProperties = z.infer<typeof AdoPropertiesSchema>;\n\nexport const AzdoIdentityRefWithVoteSchema = z.object({\n id: z.string().optional(),\n displayName: z.string().optional(),\n vote: z.number().optional(),\n hasDeclined: z.boolean().optional(),\n isFlagged: z.boolean().optional(),\n isRequired: z.boolean().optional(),\n});\nexport type AzdoIdentityRefWithVote = z.infer<typeof AzdoIdentityRefWithVoteSchema>;\n\nexport const AzdoPullRequestCommentSchema = z.object({\n id: z.number(),\n parentCommentId: z.number().nullable(),\n content: z.string(),\n commentType: AzdoCommentTypeSchema,\n publishedDate: z.string(),\n author: AzdoIdentityRefSchema.optional(),\n});\nexport type AzdoPullRequestComment = z.infer<typeof AzdoPullRequestCommentSchema>;\nexport const AzdoPullRequestCommentThreadSchema = z.object({\n id: z.number(),\n comments: AzdoPullRequestCommentSchema.array(),\n status: AzdoCommentThreadStatusSchema,\n});\nexport type AzdoPullRequestCommentThread = z.infer<typeof AzdoPullRequestCommentThreadSchema>;\n\nexport const AzdoSubscriptionSchema = z.object({\n id: z.string().optional(),\n status: z.enum(['enabled', 'onProbation', 'disabledByUser', 'disabledBySystem', 'disabledByInactiveIdentity']),\n publisherId: z.string(),\n publisherInputs: z.record(z.string(), z.string()),\n consumerId: z.string().optional(),\n consumerActionId: z.string().optional(),\n consumerInputs: z.record(z.string(), z.string()),\n eventType: z.string(), // not enum because we do not know all the values\n resourceVersion: z.string(),\n eventDescription: z.string().optional(),\n actionDescription: z.string().optional(),\n});\nexport type AzdoSubscription = z.infer<typeof AzdoSubscriptionSchema>;\n\nexport const AzdoSubscriptionsQueryResponseSchema = z.object({\n results: AzdoSubscriptionSchema.array(),\n});\nexport type AzdoSubscriptionsQueryResponse = z.infer<typeof AzdoSubscriptionsQueryResponseSchema>;\n\nexport const AzdoSubscriptionsQueryInputFilterSchema = z.object({\n conditions: z\n .object({\n caseSensitive: z.boolean().optional(),\n inputId: z.string().optional(),\n inputValue: z.string().optional(),\n operator: z.enum(['equals', 'notEquals']),\n })\n .array()\n .optional(),\n});\nexport type AzdoSubscriptionsQueryInputFilter = z.infer<typeof AzdoSubscriptionsQueryInputFilterSchema>;\n\nexport const AzdoSubscriptionsQuerySchema = z.object({\n consumerActionId: z.string().optional(),\n consumerId: z.string().optional(),\n consumerInputFilters: AzdoSubscriptionsQueryInputFilterSchema.array().optional(),\n eventType: z.string().optional(),\n publisherId: z.string().optional(),\n publisherInputFilters: AzdoSubscriptionsQueryInputFilterSchema.array().optional(),\n subscriberId: z.string().optional(),\n});\nexport type AzdoSubscriptionsQuery = z.infer<typeof AzdoSubscriptionsQuerySchema>;\n\nexport const AzdoEventTypeSchema = z.enum([\n // Code is pushed to a Git repository.\n 'git.push',\n // Pull request is updated – status, review list, reviewer vote\n // changed or the source branch is updated with a push.\n 'git.pullrequest.updated',\n // Pull request - Branch merge attempted.\n 'git.pullrequest.merged',\n // Comments are added to a pull request.\n 'ms.vss-code.git-pullrequest-comment-event',\n]);\nexport type AzdoEventType = z.infer<typeof AzdoEventTypeSchema>;\n\nexport const AzdoEventRepositorySchema = z.object({\n id: z.string(),\n name: z.string(),\n project: z.object({\n id: z.string(),\n name: z.string(),\n url: z.string(),\n }),\n defaultBranch: z.string().optional(),\n remoteUrl: z.string(),\n});\nexport const AzdoEventPullRequestResourceSchema = z.object({\n repository: AzdoEventRepositorySchema,\n pullRequestId: z.number(),\n status: AzdoPullRequestStatusSchema,\n title: z.string(),\n sourceRefName: z.string(),\n targetRefName: z.string(),\n mergeStatus: AzdoPullRequestAsyncStatusSchema,\n mergeId: z.string(),\n url: z.string(),\n});\nexport type AzdoEventPullRequestResource = z.infer<typeof AzdoEventPullRequestResourceSchema>;\nexport const AzdoEventPullRequestCommentEventResourceSchema = z.object({\n pullRequest: AzdoEventPullRequestResourceSchema,\n comment: AzdoPullRequestCommentSchema,\n});\nexport type AzdoEventPullRequestCommentEventResource = z.infer<typeof AzdoEventPullRequestCommentEventResourceSchema>;\nexport const AzdoEventCodePushResourceSchema = z.object({\n repository: AzdoEventRepositorySchema,\n refUpdates: z\n .object({\n name: z.string(),\n oldObjectId: z.string().nullish(),\n newObjectId: z.string().nullish(),\n })\n .array(),\n});\nexport type AzdoEventCodePushResource = z.infer<typeof AzdoEventCodePushResourceSchema>;\nexport const AzdoEventSchema = z.object({ subscriptionId: z.string(), notificationId: z.number() }).and(\n z.discriminatedUnion('eventType', [\n z.object({ eventType: z.literal('git.push'), resource: AzdoEventCodePushResourceSchema }),\n z.object({ eventType: z.literal('git.pullrequest.updated'), resource: AzdoEventPullRequestResourceSchema }),\n z.object({ eventType: z.literal('git.pullrequest.merged'), resource: AzdoEventPullRequestResourceSchema }),\n z.object({\n eventType: z.literal('ms.vss-code.git-pullrequest-comment-event'),\n resource: AzdoEventPullRequestCommentEventResourceSchema,\n }),\n ]),\n);\nexport type AzdoEvent = z.infer<typeof AzdoEventSchema>;\n","export type AzureDevOpsOrganizationUrl = {\n /** URL of the organisation. This may lack the project name */\n value: URL;\n\n /** Organisation URL hostname */\n hostname: string;\n\n /** Organisation API endpoint URL */\n 'api-endpoint': string;\n\n /** Organisation name/slug */\n organisation: string;\n\n /** Virtual directory if present (on-premises only) */\n 'virtual-directory'?: string;\n\n /**\n * Organization Identity API URL (different from the API endpoint).\n * Used for querying user identities.\n */\n 'identity-api-url': URL;\n};\n\nexport type AzureDevOpsProjectUrl = AzureDevOpsOrganizationUrl & {\n /** Project ID or Name */\n project: string;\n};\n\nexport type AzureDevOpsRepositoryUrl = AzureDevOpsProjectUrl & {\n /** Repository ID or Name */\n repository: string;\n\n /** Slug of the repository e.g. `contoso/prj1/_git/repo1`, `tfs/contoso/prj1/_git/repo1` */\n 'repository-slug': string;\n};\n\nexport function extractOrganizationUrl({ organisationUrl }: { organisationUrl: string }): AzureDevOpsOrganizationUrl {\n // convert url string into a valid JS URL object\n const value = new URL(organisationUrl);\n const protocol = value.protocol.slice(0, -1);\n let { hostname } = value;\n const visualStudioUrlRegex = /^(?<prefix>\\S+)\\.visualstudio\\.com$/iu;\n if (visualStudioUrlRegex.test(hostname)) hostname = 'dev.azure.com';\n\n const organisation: string = extractOrganisation(organisationUrl);\n\n const virtualDirectory = extractVirtualDirectory(value);\n const apiEndpoint = `${protocol}://${hostname}${value.port ? `:${value.port}` : ''}/${virtualDirectory ? `${virtualDirectory}/` : ''}`;\n\n // determine identity api url\n // if hosted on Azure DevOps, use the 'vssps.dev.azure.com' domain\n const identityApiUrl =\n hostname === 'dev.azure.com' || hostname.endsWith('.visualstudio.com')\n ? // https://learn.microsoft.com/en-us/rest/api/azure/devops/ims/identities/read-identities\n new URL(`https://vssps.dev.azure.com/${organisation}/`)\n : value;\n\n return {\n value,\n hostname,\n 'api-endpoint': apiEndpoint,\n organisation,\n 'virtual-directory': virtualDirectory,\n 'identity-api-url': identityApiUrl,\n };\n}\n\nexport function extractProjectUrl({\n organisationUrl,\n project,\n}: {\n organisationUrl: string;\n project: string;\n}): AzureDevOpsProjectUrl {\n const extracted = extractOrganizationUrl({ organisationUrl });\n const escapedProject = encodeURI(project); // encode special characters like spaces\n\n return {\n ...extracted,\n project: escapedProject,\n };\n}\n\nexport function extractRepositoryUrl({\n organisationUrl,\n project,\n repository,\n}: {\n organisationUrl: string;\n project: string;\n repository: string;\n}): AzureDevOpsRepositoryUrl {\n const extracted = extractProjectUrl({ organisationUrl, project });\n const { organisation, 'virtual-directory': virtualDirectory, project: escapedProject } = extracted;\n\n const escapedRepository = encodeURI(repository); // encode special characters like spaces\n const repoSlug = `${virtualDirectory ? `${virtualDirectory}/` : ''}${organisation}/${escapedProject}/_git/${escapedRepository}`;\n\n return {\n ...extracted,\n repository: escapedRepository,\n 'repository-slug': repoSlug,\n };\n}\n\n/**\n * Extract organisation name from organisation URL\n *\n * @param organisationUrl\n *\n * @returns organisation name\n */\nfunction extractOrganisation(organisationUrl: string): string {\n const url = new URL(organisationUrl);\n const { hostname, pathname } = url;\n\n // Check for old style: https://x.visualstudio.com/\n if (hostname.endsWith('.visualstudio.com')) {\n return hostname.split('.')[0]!;\n }\n\n // For new style and on-premise, parse the pathname\n // pathname examples: '/contoso/', '/contoso', '/tfs/contoso/', '/tfs/contoso', '/contoso/Core'\n const pathSegments = pathname.split('/').filter((segment) => segment !== '');\n\n // Check for on-premise style: https://server.domain.com/tfs/contoso/\n if (pathSegments.length >= 2 && hostname !== 'dev.azure.com') {\n return pathSegments[1]!; // Return 'contoso' from '/tfs/contoso/'\n }\n\n // Check for new style: https://dev.azure.com/contoso/ or https://dev.azure.com/contoso or https://dev.azure.com/contoso/Core\n if (pathSegments.length >= 1) {\n return pathSegments[0]!; // Always return the first path segment for dev.azure.com\n }\n\n throw new Error(`Error parsing organisation from organisation url: '${organisationUrl}'.`);\n}\n\n/**\n * Extract virtual directory from organisation URL\n *\n * Virtual Directories are sometimes used in on-premises\n * @param organisationUrl\n *\n * @returns virtual directory\n *\n * @example URLs typically are like this:`https://server.domain.com/tfs/x/` and `tfs` is the virtual directory\n */\nfunction extractVirtualDirectory(organisationUrl: URL) {\n // extract the pathname from the url then split\n // pathname takes the shape '/tfs/x/'\n const path = organisationUrl.pathname.split('/');\n\n // Virtual Directories are sometimes used in on-premises\n // URLs typically are like this: https://server.domain.com/tfs/x/\n // The pathname extracted looks like this: '/tfs/x/'\n return path.length === 4 ? path[1]! : undefined;\n}\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import "../index-
|
|
3
|
-
export { CertificateAuthority, CertificateAuthoritySchema, CreateApiServerAppOptions, DEFAULT_EXPERIMENTS, DEPENDABOT_DEFAULT_AUTHOR_EMAIL, DEPENDABOT_DEFAULT_AUTHOR_NAME, DependabotAllowCondition, DependabotAllowConditionSchema, DependabotAllowed, DependabotAllowedSchema, DependabotClosePullRequest, DependabotClosePullRequestReason, DependabotClosePullRequestReasonEnum, DependabotClosePullRequestSchema, DependabotCommand, DependabotCommandSchema, DependabotCommitMessage, DependabotCommitMessageSchema, DependabotCommitOptions, DependabotCommitOptionsSchema, DependabotCondition, DependabotConditionSchema, DependabotConfig, DependabotConfigSchema, DependabotCooldown, DependabotCooldownSchema, DependabotCreatePullRequest, DependabotCreatePullRequestSchema, DependabotCredential, DependabotCredentialSchema, DependabotDependency, DependabotDependencyFile, DependabotDependencyFileSchema, DependabotDependencySchema, DependabotDependencySubmission, DependabotDependencySubmissionSchema, DependabotEcosystemMeta, DependabotEcosystemMetaSchema, DependabotEcosystemVersionManager, DependabotEcosystemVersionManagerSchema, DependabotExistingGroupPR, DependabotExistingGroupPRSchema, DependabotExistingPR, DependabotExistingPRSchema, DependabotExperiments, DependabotExperimentsSchema, DependabotGroup, DependabotGroupJob, DependabotGroupJobSchema, DependabotGroupRuleJob, DependabotGroupRuleJobSchema, DependabotGroupSchema, DependabotIgnoreCondition, DependabotIgnoreConditionSchema, DependabotIncrementMetric, DependabotIncrementMetricSchema, DependabotJobBuilder, DependabotJobBuilderOutput, DependabotJobConfig, DependabotJobConfigSchema, DependabotJobFile, DependabotJobFileSchema, DependabotMarkAsProcessed, DependabotMarkAsProcessedSchema, DependabotMetric, DependabotMetricSchema, DependabotMultiEcosystemGroup, DependabotMultiEcosystemGroupSchema, DependabotPackageManager, DependabotPackageManagerSchema, DependabotProxyConfig, DependabotProxyConfigSchema, DependabotPullRequestBranchName, DependabotRecordCooldownMeta, DependabotRecordCooldownMetaSchema, DependabotRecordEcosystemMeta, DependabotRecordEcosystemMetaSchema, DependabotRecordEcosystemVersions, DependabotRecordEcosystemVersionsSchema, DependabotRecordUpdateJobError, DependabotRecordUpdateJobErrorSchema, DependabotRecordUpdateJobUnknownError, DependabotRecordUpdateJobUnknownErrorSchema, DependabotRecordUpdateJobWarning, DependabotRecordUpdateJobWarningSchema, DependabotRegistry, DependabotRegistrySchema, DependabotRequest, DependabotRequestSchema, DependabotRequestType, DependabotRequestTypeSchema, DependabotRequirement, DependabotRequirementSchema, DependabotRequirementSource, DependabotRequirementSourceSchema, DependabotSchedule, DependabotScheduleSchema, DependabotSecurityAdvisory, DependabotSecurityAdvisorySchema, DependabotSource, DependabotSourceInfo, DependabotSourceProvider, DependabotSourceProviderSchema, DependabotSourceSchema, DependabotTokenType, DependabotUpdate, DependabotUpdateDependencyList, DependabotUpdateDependencyListSchema, DependabotUpdatePullRequest, DependabotUpdatePullRequestSchema, DependabotUpdateSchema, FetchedFiles, FileFetcherInput, FileUpdaterInput, GitAuthor, POSSIBLE_CONFIG_FILE_PATHS, PackageEcosystem, PackageEcosystemSchema, VariableFinderFn, VersioningStrategy, VersioningStrategySchema, convertPlaceholder, createApiServerApp, extractPlaceholder, getBranchNameForUpdate, makeDirectoryKey,
|
|
1
|
+
import { $ as mapSecurityAdvisories, $t as DependabotAllowCondition, A as DependabotRecordUpdateJobUnknownErrorSchema, An as convertPlaceholder, At as DependabotGroupRuleJob, B as DependabotRequestType, Bt as DependabotRequirement, C as DependabotRecordEcosystemMeta, Cn as VersioningStrategy, Ct as DependabotExistingGroupPRSchema, D as DependabotRecordUpdateJobError, Dn as parseUpdates, Dt as DependabotExperimentsSchema, E as DependabotRecordEcosystemVersionsSchema, En as parseRegistries, Et as DependabotExperiments, F as DependabotUpdatePullRequest, Ft as DependabotJobFileSchema, G as DependabotJobBuilderOutput, Gt as DependabotSecurityAdvisorySchema, H as DependabotTokenType, Ht as DependabotRequirementSource, I as DependabotUpdatePullRequestSchema, It as DependabotPackageManager, J as mapCredentials, Jt as DependabotSourceProviderSchema, K as DependabotSourceInfo, Kt as DependabotSource, L as CreateApiServerAppOptions, Lt as DependabotPackageManagerSchema, M as DependabotRecordUpdateJobWarningSchema, Mn as DEPENDABOT_DEFAULT_AUTHOR_EMAIL, Mt as DependabotJobConfig, N as DependabotUpdateDependencyList, Nn as DEPENDABOT_DEFAULT_AUTHOR_NAME, Nt as DependabotJobConfigSchema, O as DependabotRecordUpdateJobErrorSchema, On as validateConfiguration, Ot as DependabotGroupJob, P as DependabotUpdateDependencyListSchema, Pn as GitAuthor, Pt as DependabotJobFile, Q as mapPackageEcosystemToPackageManager, Qt as FileUpdaterInput, R as DependabotRequest, Rt as DependabotProxyConfig, S as DependabotRecordCooldownMetaSchema, Sn as PackageEcosystemSchema, St as DependabotExistingGroupPR, T as DependabotRecordEcosystemVersions, Tn as parseDependabotConfig, Tt as DependabotExistingPRSchema, U as createApiServerApp, Ut as DependabotRequirementSourceSchema, V as DependabotRequestTypeSchema, Vt as DependabotRequirementSchema, W as DependabotJobBuilder, Wt as DependabotSecurityAdvisory, X as mapGroupsFromDependabotConfigToJobConfig, Xt as FetchedFiles, Y as mapExperiments, Yt as DependabotSourceSchema, Z as mapIgnoreConditionsFromDependabotConfigToJobConfig, Zt as FileFetcherInput, _ as DependabotMarkAsProcessed, _n as DependabotScheduleSchema, _t as DependabotConditionSchema, a as DependabotCreatePullRequest, an as DependabotCooldown, at as makeDirectoryKey, b as DependabotMetricSchema, bn as POSSIBLE_CONFIG_FILE_PATHS, bt as DependabotDependency, c as DependabotDependencyFileSchema, cn as DependabotGroupSchema, ct as CertificateAuthority, d as DependabotEcosystemMeta, dn as DependabotMultiEcosystemGroup, dt as DependabotAllowedSchema, en as DependabotAllowConditionSchema, et as mapSourceFromDependabotConfigToJobConfig, f as DependabotEcosystemMetaSchema, fn as DependabotMultiEcosystemGroupSchema, ft as DependabotCommand, g as DependabotIncrementMetricSchema, gn as DependabotSchedule, gt as DependabotCondition, h as DependabotIncrementMetric, hn as DependabotRegistrySchema, ht as DependabotCommitOptionsSchema, i as DependabotClosePullRequestSchema, in as DependabotConfigSchema, it as setExperiment, j as DependabotRecordUpdateJobWarning, jn as extractPlaceholder, jt as DependabotGroupRuleJobSchema, k as DependabotRecordUpdateJobUnknownError, kn as VariableFinderFn, kt as DependabotGroupJobSchema, l as DependabotDependencySubmission, ln as DependabotIgnoreCondition, lt as CertificateAuthoritySchema, m as DependabotEcosystemVersionManagerSchema, mn as DependabotRegistry, mt as DependabotCommitOptions, n as DependabotClosePullRequestReason, nn as DependabotCommitMessageSchema, nt as DEFAULT_EXPERIMENTS, o as DependabotCreatePullRequestSchema, on as DependabotCooldownSchema, ot as getBranchNameForUpdate, p as DependabotEcosystemVersionManager, pn as DependabotPullRequestBranchName, pt as DependabotCommandSchema, q as mapAllowedUpdatesFromDependabotConfigToJobConfig, qt as DependabotSourceProvider, r as DependabotClosePullRequestReasonEnum, rn as DependabotConfig, rt as parseExperiments, s as DependabotDependencyFile, sn as DependabotGroup, st as sanitizeRef, t as DependabotClosePullRequest, tn as DependabotCommitMessage, tt as mapVersionStrategyToRequirementsUpdateStrategy, u as DependabotDependencySubmissionSchema, un as DependabotIgnoreConditionSchema, ut as DependabotAllowed, v as DependabotMarkAsProcessedSchema, vn as DependabotUpdate, vt as DependabotCredential, w as DependabotRecordEcosystemMetaSchema, wn as VersioningStrategySchema, wt as DependabotExistingPR, x as DependabotRecordCooldownMeta, xn as PackageEcosystem, xt as DependabotDependencySchema, y as DependabotMetric, yn as DependabotUpdateSchema, yt as DependabotCredentialSchema, z as DependabotRequestSchema, zt as DependabotProxyConfigSchema } from "../index-Byxjhvfz.mjs";
|
|
2
|
+
import "../index-BfwWezjJ.mjs";
|
|
3
|
+
export { CertificateAuthority, CertificateAuthoritySchema, CreateApiServerAppOptions, DEFAULT_EXPERIMENTS, DEPENDABOT_DEFAULT_AUTHOR_EMAIL, DEPENDABOT_DEFAULT_AUTHOR_NAME, DependabotAllowCondition, DependabotAllowConditionSchema, DependabotAllowed, DependabotAllowedSchema, DependabotClosePullRequest, DependabotClosePullRequestReason, DependabotClosePullRequestReasonEnum, DependabotClosePullRequestSchema, DependabotCommand, DependabotCommandSchema, DependabotCommitMessage, DependabotCommitMessageSchema, DependabotCommitOptions, DependabotCommitOptionsSchema, DependabotCondition, DependabotConditionSchema, DependabotConfig, DependabotConfigSchema, DependabotCooldown, DependabotCooldownSchema, DependabotCreatePullRequest, DependabotCreatePullRequestSchema, DependabotCredential, DependabotCredentialSchema, DependabotDependency, DependabotDependencyFile, DependabotDependencyFileSchema, DependabotDependencySchema, DependabotDependencySubmission, DependabotDependencySubmissionSchema, DependabotEcosystemMeta, DependabotEcosystemMetaSchema, DependabotEcosystemVersionManager, DependabotEcosystemVersionManagerSchema, DependabotExistingGroupPR, DependabotExistingGroupPRSchema, DependabotExistingPR, DependabotExistingPRSchema, DependabotExperiments, DependabotExperimentsSchema, DependabotGroup, DependabotGroupJob, DependabotGroupJobSchema, DependabotGroupRuleJob, DependabotGroupRuleJobSchema, DependabotGroupSchema, DependabotIgnoreCondition, DependabotIgnoreConditionSchema, DependabotIncrementMetric, DependabotIncrementMetricSchema, DependabotJobBuilder, DependabotJobBuilderOutput, DependabotJobConfig, DependabotJobConfigSchema, DependabotJobFile, DependabotJobFileSchema, DependabotMarkAsProcessed, DependabotMarkAsProcessedSchema, DependabotMetric, DependabotMetricSchema, DependabotMultiEcosystemGroup, DependabotMultiEcosystemGroupSchema, DependabotPackageManager, DependabotPackageManagerSchema, DependabotProxyConfig, DependabotProxyConfigSchema, DependabotPullRequestBranchName, DependabotRecordCooldownMeta, DependabotRecordCooldownMetaSchema, DependabotRecordEcosystemMeta, DependabotRecordEcosystemMetaSchema, DependabotRecordEcosystemVersions, DependabotRecordEcosystemVersionsSchema, DependabotRecordUpdateJobError, DependabotRecordUpdateJobErrorSchema, DependabotRecordUpdateJobUnknownError, DependabotRecordUpdateJobUnknownErrorSchema, DependabotRecordUpdateJobWarning, DependabotRecordUpdateJobWarningSchema, DependabotRegistry, DependabotRegistrySchema, DependabotRequest, DependabotRequestSchema, DependabotRequestType, DependabotRequestTypeSchema, DependabotRequirement, DependabotRequirementSchema, DependabotRequirementSource, DependabotRequirementSourceSchema, DependabotSchedule, DependabotScheduleSchema, DependabotSecurityAdvisory, DependabotSecurityAdvisorySchema, DependabotSource, DependabotSourceInfo, DependabotSourceProvider, DependabotSourceProviderSchema, DependabotSourceSchema, DependabotTokenType, DependabotUpdate, DependabotUpdateDependencyList, DependabotUpdateDependencyListSchema, DependabotUpdatePullRequest, DependabotUpdatePullRequestSchema, DependabotUpdateSchema, FetchedFiles, FileFetcherInput, FileUpdaterInput, GitAuthor, POSSIBLE_CONFIG_FILE_PATHS, PackageEcosystem, PackageEcosystemSchema, VariableFinderFn, VersioningStrategy, VersioningStrategySchema, convertPlaceholder, createApiServerApp, extractPlaceholder, getBranchNameForUpdate, makeDirectoryKey, mapAllowedUpdatesFromDependabotConfigToJobConfig, mapCredentials, mapExperiments, mapGroupsFromDependabotConfigToJobConfig, mapIgnoreConditionsFromDependabotConfigToJobConfig, mapPackageEcosystemToPackageManager, mapSecurityAdvisories, mapSourceFromDependabotConfigToJobConfig, mapVersionStrategyToRequirementsUpdateStrategy, parseDependabotConfig, parseExperiments, parseRegistries, parseUpdates, sanitizeRef, setExperiment, validateConfiguration };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import "../
|
|
2
|
-
import { A as
|
|
3
|
-
import { A as mapSecurityAdvisories, C as makeRandomJobId, D as mapGroupsFromDependabotConfigToJobConfig, E as mapExperiments, F as getBranchNameForUpdate, I as sanitizeRef, L as DEPENDABOT_DEFAULT_AUTHOR_EMAIL, M as mapVersionStrategyToRequirementsUpdateStrategy, N as DEFAULT_EXPERIMENTS, O as mapIgnoreConditionsFromDependabotConfigToJobConfig, P as parseExperiments, R as DEPENDABOT_DEFAULT_AUTHOR_NAME, S as DependabotJobBuilder, T as mapCredentials, _ as DependabotRecordUpdateJobErrorSchema, a as DependabotClosePullRequestSchema, b as DependabotUpdateDependencyListSchema, c as DependabotDependencySubmissionSchema, d as DependabotIncrementMetricSchema, f as DependabotMarkAsProcessedSchema, g as DependabotRecordEcosystemVersionsSchema, h as DependabotRecordEcosystemMetaSchema, i as DependabotClosePullRequestReasonEnum, j as mapSourceFromDependabotConfigToJobConfig, k as mapPackageEcosystemToPackageManager, l as DependabotEcosystemMetaSchema, m as DependabotRecordCooldownMetaSchema, n as DependabotRequestTypeSchema, o as DependabotCreatePullRequestSchema, p as DependabotMetricSchema, r as createApiServerApp, s as DependabotDependencyFileSchema, t as DependabotRequestSchema, u as DependabotEcosystemVersionManagerSchema, v as DependabotRecordUpdateJobUnknownErrorSchema, w as mapAllowedUpdatesFromDependabotConfigToJobConfig, x as DependabotUpdatePullRequestSchema, y as DependabotRecordUpdateJobWarningSchema } from "../dependabot-_TVZhG0L.mjs";
|
|
1
|
+
import { A as DependabotScheduleSchema, B as extractPlaceholder, C as DependabotCommitMessageSchema, D as DependabotIgnoreConditionSchema, E as DependabotGroupSchema, F as parseDependabotConfig, I as parseRegistries, L as parseUpdates, M as POSSIBLE_CONFIG_FILE_PATHS, N as PackageEcosystemSchema, O as DependabotMultiEcosystemGroupSchema, P as VersioningStrategySchema, R as validateConfiguration, S as DependabotAllowConditionSchema, T as DependabotCooldownSchema, V as makeDirectoryKey, _ as DependabotRequirementSchema, a as DependabotConditionSchema, b as DependabotSourceProviderSchema, c as DependabotExistingGroupPRSchema, d as DependabotGroupJobSchema, f as DependabotGroupRuleJobSchema, g as DependabotProxyConfigSchema, h as DependabotPackageManagerSchema, i as DependabotCommitOptionsSchema, j as DependabotUpdateSchema, k as DependabotRegistrySchema, l as DependabotExistingPRSchema, m as DependabotJobFileSchema, n as DependabotAllowedSchema, o as DependabotCredentialSchema, p as DependabotJobConfigSchema, r as DependabotCommandSchema, s as DependabotDependencySchema, t as CertificateAuthoritySchema, u as DependabotExperimentsSchema, v as DependabotRequirementSourceSchema, w as DependabotConfigSchema, x as DependabotSourceSchema, y as DependabotSecurityAdvisorySchema, z as convertPlaceholder } from "../job-BxOZ-hqF.mjs";
|
|
2
|
+
import { A as mapSourceFromDependabotConfigToJobConfig, C as mapAllowedUpdatesFromDependabotConfigToJobConfig, D as mapIgnoreConditionsFromDependabotConfigToJobConfig, E as mapGroupsFromDependabotConfigToJobConfig, F as getBranchNameForUpdate, I as sanitizeRef, L as DEPENDABOT_DEFAULT_AUTHOR_EMAIL, M as DEFAULT_EXPERIMENTS, N as parseExperiments, O as mapPackageEcosystemToPackageManager, P as setExperiment, R as DEPENDABOT_DEFAULT_AUTHOR_NAME, S as DependabotJobBuilder, T as mapExperiments, _ as DependabotRecordUpdateJobErrorSchema, a as DependabotClosePullRequestSchema, b as DependabotUpdateDependencyListSchema, c as DependabotDependencySubmissionSchema, d as DependabotIncrementMetricSchema, f as DependabotMarkAsProcessedSchema, g as DependabotRecordEcosystemVersionsSchema, h as DependabotRecordEcosystemMetaSchema, i as DependabotClosePullRequestReasonEnum, j as mapVersionStrategyToRequirementsUpdateStrategy, k as mapSecurityAdvisories, l as DependabotEcosystemMetaSchema, m as DependabotRecordCooldownMetaSchema, n as DependabotRequestTypeSchema, o as DependabotCreatePullRequestSchema, p as DependabotMetricSchema, r as createApiServerApp, s as DependabotDependencyFileSchema, t as DependabotRequestSchema, u as DependabotEcosystemVersionManagerSchema, v as DependabotRecordUpdateJobUnknownErrorSchema, w as mapCredentials, x as DependabotUpdatePullRequestSchema, y as DependabotRecordUpdateJobWarningSchema } from "../dependabot-rtPO9HdD.mjs";
|
|
4
3
|
|
|
5
|
-
export { CertificateAuthoritySchema, DEFAULT_EXPERIMENTS, DEPENDABOT_DEFAULT_AUTHOR_EMAIL, DEPENDABOT_DEFAULT_AUTHOR_NAME, DependabotAllowConditionSchema, DependabotAllowedSchema, DependabotClosePullRequestReasonEnum, DependabotClosePullRequestSchema, DependabotCommandSchema, DependabotCommitMessageSchema, DependabotCommitOptionsSchema, DependabotConditionSchema, DependabotConfigSchema, DependabotCooldownSchema, DependabotCreatePullRequestSchema, DependabotCredentialSchema, DependabotDependencyFileSchema, DependabotDependencySchema, DependabotDependencySubmissionSchema, DependabotEcosystemMetaSchema, DependabotEcosystemVersionManagerSchema, DependabotExistingGroupPRSchema, DependabotExistingPRSchema, DependabotExperimentsSchema, DependabotGroupJobSchema, DependabotGroupRuleJobSchema, DependabotGroupSchema, DependabotIgnoreConditionSchema, DependabotIncrementMetricSchema, DependabotJobBuilder, DependabotJobConfigSchema, DependabotJobFileSchema, DependabotMarkAsProcessedSchema, DependabotMetricSchema, DependabotMultiEcosystemGroupSchema, DependabotPackageManagerSchema, DependabotProxyConfigSchema, DependabotRecordCooldownMetaSchema, DependabotRecordEcosystemMetaSchema, DependabotRecordEcosystemVersionsSchema, DependabotRecordUpdateJobErrorSchema, DependabotRecordUpdateJobUnknownErrorSchema, DependabotRecordUpdateJobWarningSchema, DependabotRegistrySchema, DependabotRequestSchema, DependabotRequestTypeSchema, DependabotRequirementSchema, DependabotRequirementSourceSchema, DependabotScheduleSchema, DependabotSecurityAdvisorySchema, DependabotSourceProviderSchema, DependabotSourceSchema, DependabotUpdateDependencyListSchema, DependabotUpdatePullRequestSchema, DependabotUpdateSchema, POSSIBLE_CONFIG_FILE_PATHS, PackageEcosystemSchema, VersioningStrategySchema, convertPlaceholder, createApiServerApp, extractPlaceholder, getBranchNameForUpdate, makeDirectoryKey,
|
|
4
|
+
export { CertificateAuthoritySchema, DEFAULT_EXPERIMENTS, DEPENDABOT_DEFAULT_AUTHOR_EMAIL, DEPENDABOT_DEFAULT_AUTHOR_NAME, DependabotAllowConditionSchema, DependabotAllowedSchema, DependabotClosePullRequestReasonEnum, DependabotClosePullRequestSchema, DependabotCommandSchema, DependabotCommitMessageSchema, DependabotCommitOptionsSchema, DependabotConditionSchema, DependabotConfigSchema, DependabotCooldownSchema, DependabotCreatePullRequestSchema, DependabotCredentialSchema, DependabotDependencyFileSchema, DependabotDependencySchema, DependabotDependencySubmissionSchema, DependabotEcosystemMetaSchema, DependabotEcosystemVersionManagerSchema, DependabotExistingGroupPRSchema, DependabotExistingPRSchema, DependabotExperimentsSchema, DependabotGroupJobSchema, DependabotGroupRuleJobSchema, DependabotGroupSchema, DependabotIgnoreConditionSchema, DependabotIncrementMetricSchema, DependabotJobBuilder, DependabotJobConfigSchema, DependabotJobFileSchema, DependabotMarkAsProcessedSchema, DependabotMetricSchema, DependabotMultiEcosystemGroupSchema, DependabotPackageManagerSchema, DependabotProxyConfigSchema, DependabotRecordCooldownMetaSchema, DependabotRecordEcosystemMetaSchema, DependabotRecordEcosystemVersionsSchema, DependabotRecordUpdateJobErrorSchema, DependabotRecordUpdateJobUnknownErrorSchema, DependabotRecordUpdateJobWarningSchema, DependabotRegistrySchema, DependabotRequestSchema, DependabotRequestTypeSchema, DependabotRequirementSchema, DependabotRequirementSourceSchema, DependabotScheduleSchema, DependabotSecurityAdvisorySchema, DependabotSourceProviderSchema, DependabotSourceSchema, DependabotUpdateDependencyListSchema, DependabotUpdatePullRequestSchema, DependabotUpdateSchema, POSSIBLE_CONFIG_FILE_PATHS, PackageEcosystemSchema, VersioningStrategySchema, convertPlaceholder, createApiServerApp, extractPlaceholder, getBranchNameForUpdate, makeDirectoryKey, mapAllowedUpdatesFromDependabotConfigToJobConfig, mapCredentials, mapExperiments, mapGroupsFromDependabotConfigToJobConfig, mapIgnoreConditionsFromDependabotConfigToJobConfig, mapPackageEcosystemToPackageManager, mapSecurityAdvisories, mapSourceFromDependabotConfigToJobConfig, mapVersionStrategyToRequirementsUpdateStrategy, parseDependabotConfig, parseExperiments, parseRegistries, parseUpdates, sanitizeRef, setExperiment, validateConfiguration };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { n as logger } from "./logger-
|
|
2
|
-
import { h as DependabotPackageManagerSchema, s as DependabotDependencySchema } from "./job-
|
|
1
|
+
import { n as logger } from "./logger-5PEqZVLr.mjs";
|
|
2
|
+
import { h as DependabotPackageManagerSchema, s as DependabotDependencySchema } from "./job-BxOZ-hqF.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
-
import * as crypto
|
|
4
|
+
import * as crypto from "node:crypto";
|
|
5
5
|
import { zValidator } from "@hono/zod-validator";
|
|
6
6
|
import { Hono } from "hono";
|
|
7
7
|
|
|
@@ -14,7 +14,7 @@ const DEPENDABOT_DEFAULT_AUTHOR_NAME = "dependabot[bot]";
|
|
|
14
14
|
function getBranchNameForUpdate(packageEcosystem, targetBranchName, directory, dependencyGroupName, dependencies, separator = "/") {
|
|
15
15
|
let branchName;
|
|
16
16
|
if (dependencyGroupName || dependencies.length > 1) {
|
|
17
|
-
const dependencyDigest = crypto
|
|
17
|
+
const dependencyDigest = crypto.createHash("md5").update(dependencies.map((d) => `${d["dependency-name"]}-${d["dependency-version"]}`).join(",")).digest("hex").substring(0, 10);
|
|
18
18
|
branchName = `${dependencyGroupName || "multi"}-${dependencyDigest}`;
|
|
19
19
|
} else branchName = `${dependencies.map((d) => d["dependency-name"]).join("-and-").replace(/[:[]]/g, "-").replace(/@/g, "")}-${dependencies[0]?.removed ? "removed" : dependencies[0]?.["dependency-version"]}`;
|
|
20
20
|
return sanitizeRef([
|
|
@@ -69,6 +69,20 @@ function parseExperiments(raw) {
|
|
|
69
69
|
return acc;
|
|
70
70
|
}, {});
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Set experiment in the given experiments map.
|
|
74
|
+
* If the experiments map is undefined, a new map will be created.
|
|
75
|
+
* @param experiments The experiments map to set the experiment in.
|
|
76
|
+
* @param name The name of the experiment to set.
|
|
77
|
+
* @param value The value of the experiment to set. Defaults to true.
|
|
78
|
+
* @returns The updated experiments map.
|
|
79
|
+
*/
|
|
80
|
+
function setExperiment(experiments, name, value = true) {
|
|
81
|
+
return {
|
|
82
|
+
...experiments || {},
|
|
83
|
+
[name]: value
|
|
84
|
+
};
|
|
85
|
+
}
|
|
72
86
|
|
|
73
87
|
//#endregion
|
|
74
88
|
//#region src/dependabot/job-builder.ts
|
|
@@ -86,8 +100,8 @@ var DependabotJobBuilder = class {
|
|
|
86
100
|
constructor({ source, config, update, systemAccessUser, systemAccessToken, githubToken, experiments, debug }) {
|
|
87
101
|
this.config = config;
|
|
88
102
|
this.update = update;
|
|
89
|
-
this.experiments = experiments;
|
|
90
103
|
this.debug = debug;
|
|
104
|
+
this.experiments = setExperiment(experiments, "enable_beta_ecosystems", config["enable-beta-ecosystems"]);
|
|
91
105
|
this.packageManager = mapPackageEcosystemToPackageManager(update["package-ecosystem"]);
|
|
92
106
|
this.source = mapSourceFromDependabotConfigToJobConfig(source, update);
|
|
93
107
|
this.credentials = mapCredentials({
|
|
@@ -102,7 +116,6 @@ var DependabotJobBuilder = class {
|
|
|
102
116
|
* Create a dependabot update job that updates nothing, but will discover the dependency list for a package ecosystem
|
|
103
117
|
*/
|
|
104
118
|
forDependenciesList({ id, command }) {
|
|
105
|
-
id ??= makeRandomJobId();
|
|
106
119
|
return {
|
|
107
120
|
job: {
|
|
108
121
|
id,
|
|
@@ -140,7 +153,6 @@ var DependabotJobBuilder = class {
|
|
|
140
153
|
* Create a dependabot update job that updates all dependencies for a package ecosystem
|
|
141
154
|
*/
|
|
142
155
|
forUpdate({ id, command, dependencyNamesToUpdate, existingPullRequests, pullRequestToUpdate, securityVulnerabilities }) {
|
|
143
|
-
id ??= makeRandomJobId();
|
|
144
156
|
const securityOnlyUpdate = this.update["open-pull-requests-limit"] === 0;
|
|
145
157
|
let updatingPullRequest;
|
|
146
158
|
let updateDependencyGroupName = null;
|
|
@@ -323,11 +335,6 @@ function mapCredentials({ sourceHostname, systemAccessUser, systemAccessToken, g
|
|
|
323
335
|
if (registries) credentials.push(...Object.values(registries));
|
|
324
336
|
return credentials;
|
|
325
337
|
}
|
|
326
|
-
function makeRandomJobId() {
|
|
327
|
-
const array = new Uint32Array(1);
|
|
328
|
-
crypto.getRandomValues(array);
|
|
329
|
-
return `${array[0] % 1e10}`;
|
|
330
|
-
}
|
|
331
338
|
|
|
332
339
|
//#endregion
|
|
333
340
|
//#region src/dependabot/update.ts
|
|
@@ -623,5 +630,5 @@ function createApiServerApp({ basePath = `/api/update_jobs`, authenticate, getJo
|
|
|
623
630
|
}
|
|
624
631
|
|
|
625
632
|
//#endregion
|
|
626
|
-
export {
|
|
627
|
-
//# sourceMappingURL=dependabot-
|
|
633
|
+
export { mapSourceFromDependabotConfigToJobConfig as A, mapAllowedUpdatesFromDependabotConfigToJobConfig as C, mapIgnoreConditionsFromDependabotConfigToJobConfig as D, mapGroupsFromDependabotConfigToJobConfig as E, getBranchNameForUpdate as F, sanitizeRef as I, DEPENDABOT_DEFAULT_AUTHOR_EMAIL as L, DEFAULT_EXPERIMENTS as M, parseExperiments as N, mapPackageEcosystemToPackageManager as O, setExperiment as P, DEPENDABOT_DEFAULT_AUTHOR_NAME as R, DependabotJobBuilder as S, mapExperiments as T, DependabotRecordUpdateJobErrorSchema as _, DependabotClosePullRequestSchema as a, DependabotUpdateDependencyListSchema as b, DependabotDependencySubmissionSchema as c, DependabotIncrementMetricSchema as d, DependabotMarkAsProcessedSchema as f, DependabotRecordEcosystemVersionsSchema as g, DependabotRecordEcosystemMetaSchema as h, DependabotClosePullRequestReasonEnum as i, mapVersionStrategyToRequirementsUpdateStrategy as j, mapSecurityAdvisories as k, DependabotEcosystemMetaSchema as l, DependabotRecordCooldownMetaSchema as m, DependabotRequestTypeSchema as n, DependabotCreatePullRequestSchema as o, DependabotMetricSchema as p, createApiServerApp as r, DependabotDependencyFileSchema as s, DependabotRequestSchema as t, DependabotEcosystemVersionManagerSchema as u, DependabotRecordUpdateJobUnknownErrorSchema as v, mapCredentials as w, DependabotUpdatePullRequestSchema as x, DependabotRecordUpdateJobWarningSchema as y };
|
|
634
|
+
//# sourceMappingURL=dependabot-rtPO9HdD.mjs.map
|