bitbucket-datacenter-api-client 1.3.0 → 1.4.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/index.d.mts +27 -1
- package/dist/index.d.ts +27 -1
- package/dist/index.js +13 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +13 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1086,6 +1086,32 @@ declare class BitbucketClient {
|
|
|
1086
1086
|
user(slug: string): UserResource;
|
|
1087
1087
|
}
|
|
1088
1088
|
|
|
1089
|
+
/**
|
|
1090
|
+
* Thrown when the Bitbucket Data Center API returns a non-2xx response.
|
|
1091
|
+
*
|
|
1092
|
+
* @example
|
|
1093
|
+
* ```typescript
|
|
1094
|
+
* import { BitbucketApiError } from 'bitbucket-datacenter-api-client';
|
|
1095
|
+
*
|
|
1096
|
+
* try {
|
|
1097
|
+
* await bb.project('NONEXISTENT');
|
|
1098
|
+
* } catch (err) {
|
|
1099
|
+
* if (err instanceof BitbucketApiError) {
|
|
1100
|
+
* console.log(err.status); // 404
|
|
1101
|
+
* console.log(err.statusText); // 'Not Found'
|
|
1102
|
+
* console.log(err.message); // 'Bitbucket API error: 404 Not Found'
|
|
1103
|
+
* }
|
|
1104
|
+
* }
|
|
1105
|
+
* ```
|
|
1106
|
+
*/
|
|
1107
|
+
declare class BitbucketApiError extends Error {
|
|
1108
|
+
/** HTTP status code (e.g. `404`, `401`, `403`) */
|
|
1109
|
+
readonly status: number;
|
|
1110
|
+
/** HTTP status text (e.g. `'Not Found'`, `'Unauthorized'`) */
|
|
1111
|
+
readonly statusText: string;
|
|
1112
|
+
constructor(status: number, statusText: string);
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1089
1115
|
/**
|
|
1090
1116
|
* Handles Basic Authentication for Bitbucket Data Center REST API requests.
|
|
1091
1117
|
*
|
|
@@ -1135,4 +1161,4 @@ declare class Security {
|
|
|
1135
1161
|
getHeaders(): Record<string, string>;
|
|
1136
1162
|
}
|
|
1137
1163
|
|
|
1138
|
-
export { type ActivitiesParams, type BitbucketActivityUser, type BitbucketBranch, type BitbucketBuildCount, type BitbucketBuildSummaries, type BitbucketChange, type BitbucketChangePath, BitbucketClient, type BitbucketClientOptions, type BitbucketCommit, type BitbucketCommitAuthor, type BitbucketIssue, type BitbucketLastModifiedEntry, type BitbucketParticipant, type BitbucketProject, type BitbucketPullRequest, type BitbucketPullRequestActivity, type BitbucketPullRequestComment, type BitbucketPullRequestTask, type BitbucketRef, type BitbucketReport, type BitbucketReportData, type BitbucketRepository, type BitbucketRepositorySize, type BitbucketTag, type BitbucketUser, type BitbucketUserPermission, type BranchesParams, type ChangeNodeType, type ChangeType, type ChangesParams, type CommitsParams, type LastModifiedParams, type PagedResponse, type PaginationParams, ProjectResource, type ProjectUsersParams, type ProjectsParams, type PullRequestActivityAction, PullRequestResource, type PullRequestTaskAnchor, type PullRequestTaskPermittedOperations, type PullRequestTaskState, type PullRequestsParams, type RawFileParams, type ReportDataType, type ReportResult, type ReportsParams, type ReposParams, RepositoryResource, Security, type TagsParams, type TasksParams, UserResource, type UsersParams };
|
|
1164
|
+
export { type ActivitiesParams, type BitbucketActivityUser, BitbucketApiError, type BitbucketBranch, type BitbucketBuildCount, type BitbucketBuildSummaries, type BitbucketChange, type BitbucketChangePath, BitbucketClient, type BitbucketClientOptions, type BitbucketCommit, type BitbucketCommitAuthor, type BitbucketIssue, type BitbucketLastModifiedEntry, type BitbucketParticipant, type BitbucketProject, type BitbucketPullRequest, type BitbucketPullRequestActivity, type BitbucketPullRequestComment, type BitbucketPullRequestTask, type BitbucketRef, type BitbucketReport, type BitbucketReportData, type BitbucketRepository, type BitbucketRepositorySize, type BitbucketTag, type BitbucketUser, type BitbucketUserPermission, type BranchesParams, type ChangeNodeType, type ChangeType, type ChangesParams, type CommitsParams, type LastModifiedParams, type PagedResponse, type PaginationParams, ProjectResource, type ProjectUsersParams, type ProjectsParams, type PullRequestActivityAction, PullRequestResource, type PullRequestTaskAnchor, type PullRequestTaskPermittedOperations, type PullRequestTaskState, type PullRequestsParams, type RawFileParams, type ReportDataType, type ReportResult, type ReportsParams, type ReposParams, RepositoryResource, Security, type TagsParams, type TasksParams, UserResource, type UsersParams };
|
package/dist/index.d.ts
CHANGED
|
@@ -1086,6 +1086,32 @@ declare class BitbucketClient {
|
|
|
1086
1086
|
user(slug: string): UserResource;
|
|
1087
1087
|
}
|
|
1088
1088
|
|
|
1089
|
+
/**
|
|
1090
|
+
* Thrown when the Bitbucket Data Center API returns a non-2xx response.
|
|
1091
|
+
*
|
|
1092
|
+
* @example
|
|
1093
|
+
* ```typescript
|
|
1094
|
+
* import { BitbucketApiError } from 'bitbucket-datacenter-api-client';
|
|
1095
|
+
*
|
|
1096
|
+
* try {
|
|
1097
|
+
* await bb.project('NONEXISTENT');
|
|
1098
|
+
* } catch (err) {
|
|
1099
|
+
* if (err instanceof BitbucketApiError) {
|
|
1100
|
+
* console.log(err.status); // 404
|
|
1101
|
+
* console.log(err.statusText); // 'Not Found'
|
|
1102
|
+
* console.log(err.message); // 'Bitbucket API error: 404 Not Found'
|
|
1103
|
+
* }
|
|
1104
|
+
* }
|
|
1105
|
+
* ```
|
|
1106
|
+
*/
|
|
1107
|
+
declare class BitbucketApiError extends Error {
|
|
1108
|
+
/** HTTP status code (e.g. `404`, `401`, `403`) */
|
|
1109
|
+
readonly status: number;
|
|
1110
|
+
/** HTTP status text (e.g. `'Not Found'`, `'Unauthorized'`) */
|
|
1111
|
+
readonly statusText: string;
|
|
1112
|
+
constructor(status: number, statusText: string);
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1089
1115
|
/**
|
|
1090
1116
|
* Handles Basic Authentication for Bitbucket Data Center REST API requests.
|
|
1091
1117
|
*
|
|
@@ -1135,4 +1161,4 @@ declare class Security {
|
|
|
1135
1161
|
getHeaders(): Record<string, string>;
|
|
1136
1162
|
}
|
|
1137
1163
|
|
|
1138
|
-
export { type ActivitiesParams, type BitbucketActivityUser, type BitbucketBranch, type BitbucketBuildCount, type BitbucketBuildSummaries, type BitbucketChange, type BitbucketChangePath, BitbucketClient, type BitbucketClientOptions, type BitbucketCommit, type BitbucketCommitAuthor, type BitbucketIssue, type BitbucketLastModifiedEntry, type BitbucketParticipant, type BitbucketProject, type BitbucketPullRequest, type BitbucketPullRequestActivity, type BitbucketPullRequestComment, type BitbucketPullRequestTask, type BitbucketRef, type BitbucketReport, type BitbucketReportData, type BitbucketRepository, type BitbucketRepositorySize, type BitbucketTag, type BitbucketUser, type BitbucketUserPermission, type BranchesParams, type ChangeNodeType, type ChangeType, type ChangesParams, type CommitsParams, type LastModifiedParams, type PagedResponse, type PaginationParams, ProjectResource, type ProjectUsersParams, type ProjectsParams, type PullRequestActivityAction, PullRequestResource, type PullRequestTaskAnchor, type PullRequestTaskPermittedOperations, type PullRequestTaskState, type PullRequestsParams, type RawFileParams, type ReportDataType, type ReportResult, type ReportsParams, type ReposParams, RepositoryResource, Security, type TagsParams, type TasksParams, UserResource, type UsersParams };
|
|
1164
|
+
export { type ActivitiesParams, type BitbucketActivityUser, BitbucketApiError, type BitbucketBranch, type BitbucketBuildCount, type BitbucketBuildSummaries, type BitbucketChange, type BitbucketChangePath, BitbucketClient, type BitbucketClientOptions, type BitbucketCommit, type BitbucketCommitAuthor, type BitbucketIssue, type BitbucketLastModifiedEntry, type BitbucketParticipant, type BitbucketProject, type BitbucketPullRequest, type BitbucketPullRequestActivity, type BitbucketPullRequestComment, type BitbucketPullRequestTask, type BitbucketRef, type BitbucketReport, type BitbucketReportData, type BitbucketRepository, type BitbucketRepositorySize, type BitbucketTag, type BitbucketUser, type BitbucketUserPermission, type BranchesParams, type ChangeNodeType, type ChangeType, type ChangesParams, type CommitsParams, type LastModifiedParams, type PagedResponse, type PaginationParams, ProjectResource, type ProjectUsersParams, type ProjectsParams, type PullRequestActivityAction, PullRequestResource, type PullRequestTaskAnchor, type PullRequestTaskPermittedOperations, type PullRequestTaskState, type PullRequestsParams, type RawFileParams, type ReportDataType, type ReportResult, type ReportsParams, type ReposParams, RepositoryResource, Security, type TagsParams, type TasksParams, UserResource, type UsersParams };
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
BitbucketApiError: () => BitbucketApiError,
|
|
23
24
|
BitbucketClient: () => BitbucketClient,
|
|
24
25
|
ProjectResource: () => ProjectResource,
|
|
25
26
|
PullRequestResource: () => PullRequestResource,
|
|
@@ -439,6 +440,16 @@ var ProjectResource = class {
|
|
|
439
440
|
}
|
|
440
441
|
};
|
|
441
442
|
|
|
443
|
+
// src/errors/BitbucketApiError.ts
|
|
444
|
+
var BitbucketApiError = class extends Error {
|
|
445
|
+
constructor(status, statusText) {
|
|
446
|
+
super(`Bitbucket API error: ${status} ${statusText}`);
|
|
447
|
+
this.name = "BitbucketApiError";
|
|
448
|
+
this.status = status;
|
|
449
|
+
this.statusText = statusText;
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
|
|
442
453
|
// src/resources/UserResource.ts
|
|
443
454
|
var UserResource = class {
|
|
444
455
|
/** @internal */
|
|
@@ -488,7 +499,7 @@ var BitbucketClient = class {
|
|
|
488
499
|
const url = buildUrl(base, params);
|
|
489
500
|
const response = await fetch(url, { headers: this.security.getHeaders() });
|
|
490
501
|
if (!response.ok) {
|
|
491
|
-
throw new
|
|
502
|
+
throw new BitbucketApiError(response.status, response.statusText);
|
|
492
503
|
}
|
|
493
504
|
return response.json();
|
|
494
505
|
}
|
|
@@ -497,7 +508,7 @@ var BitbucketClient = class {
|
|
|
497
508
|
const url = buildUrl(base, params);
|
|
498
509
|
const response = await fetch(url, { headers: this.security.getHeaders() });
|
|
499
510
|
if (!response.ok) {
|
|
500
|
-
throw new
|
|
511
|
+
throw new BitbucketApiError(response.status, response.statusText);
|
|
501
512
|
}
|
|
502
513
|
return response.text();
|
|
503
514
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/security/Security.ts","../src/resources/PullRequestResource.ts","../src/resources/RepositoryResource.ts","../src/resources/ProjectResource.ts","../src/resources/UserResource.ts","../src/BitbucketClient.ts"],"sourcesContent":["export { BitbucketClient } from './BitbucketClient';\nexport type { BitbucketClientOptions } from './BitbucketClient';\nexport { Security } from './security/Security';\nexport { ProjectResource } from './resources/ProjectResource';\nexport { RepositoryResource } from './resources/RepositoryResource';\nexport { PullRequestResource } from './resources/PullRequestResource';\nexport { UserResource } from './resources/UserResource';\nexport type { BitbucketProject, ProjectsParams } from './domain/Project';\nexport type { BitbucketRepository, ReposParams } from './domain/Repository';\nexport type { BitbucketPullRequest, BitbucketParticipant, BitbucketRef, PullRequestsParams } from './domain/PullRequest';\nexport type { BitbucketPullRequestActivity, BitbucketPullRequestComment, BitbucketActivityUser, PullRequestActivityAction, ActivitiesParams } from './domain/PullRequestActivity';\nexport type { BitbucketPullRequestTask, PullRequestTaskState, PullRequestTaskPermittedOperations, PullRequestTaskAnchor, TasksParams } from './domain/PullRequestTask';\nexport type { BitbucketChange, BitbucketChangePath, ChangeType, ChangeNodeType, ChangesParams } from './domain/Change';\nexport type { BitbucketReport, BitbucketReportData, ReportResult, ReportDataType, ReportsParams } from './domain/Report';\nexport type { BitbucketBuildSummaries, BitbucketBuildCount } from './domain/BuildSummary';\nexport type { BitbucketIssue } from './domain/Issue';\nexport type { BitbucketUser, BitbucketUserPermission, UsersParams, ProjectUsersParams } from './domain/User';\nexport type { BitbucketCommit, BitbucketCommitAuthor, CommitsParams } from './domain/Commit';\nexport type { BitbucketBranch, BranchesParams } from './domain/Branch';\nexport type { BitbucketTag, TagsParams } from './domain/Tag';\nexport type { BitbucketRepositorySize } from './domain/RepositorySize';\nexport type { BitbucketLastModifiedEntry, LastModifiedParams } from './domain/LastModified';\nexport type { RawFileParams } from './domain/RawFile';\nexport type { PaginationParams, PagedResponse } from './domain/Pagination';\n","/**\n * Encodes a string to Base64 in a way that works in both Node.js and browsers.\n * @internal\n */\nfunction toBase64(value: string): string {\n if (typeof btoa !== 'undefined') {\n return btoa(value);\n }\n return Buffer.from(value).toString('base64');\n}\n\n/**\n * Handles Basic Authentication for Bitbucket Data Center REST API requests.\n *\n * @example\n * ```typescript\n * const security = new Security(\n * 'https://bitbucket.example.com',\n * 'my-user',\n * 'my-token'\n * );\n *\n * const headers = security.getHeaders();\n * // { Authorization: 'Basic <base64>', 'Content-Type': 'application/json', Accept: 'application/json' }\n * ```\n */\nexport class Security {\n private readonly apiUrl: string;\n private readonly authorizationHeader: string;\n\n /**\n * Creates a new Security instance with Basic Authentication credentials.\n *\n * @param apiUrl - The base URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`).\n * Must be a valid URL; throws if it cannot be parsed.\n * @param user - The username to authenticate with\n * @param token - The personal access token or password to authenticate with\n *\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor(apiUrl: string, user: string, token: string) {\n if (!URL.canParse(apiUrl)) {\n throw new TypeError(`Invalid apiUrl: \"${apiUrl}\" is not a valid URL`);\n }\n this.apiUrl = apiUrl.replace(/\\/$/, '');\n this.authorizationHeader = `Basic ${toBase64(`${user}:${token}`)}`;\n }\n\n /**\n * Returns the base URL of the Bitbucket Data Center instance, without a trailing slash.\n *\n * @returns The API base URL\n */\n getApiUrl(): string {\n return this.apiUrl;\n }\n\n /**\n * Returns the value of the `Authorization` header for Basic Authentication.\n *\n * @returns The Authorization header value in the format `Basic <base64-encoded-credentials>`\n */\n getAuthorizationHeader(): string {\n return this.authorizationHeader;\n }\n\n /**\n * Returns the full set of HTTP headers required for authenticated API requests.\n *\n * @returns An object containing `Authorization`, `Content-Type`, and `Accept` headers\n */\n getHeaders(): Record<string, string> {\n return {\n Authorization: this.authorizationHeader,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n }\n}\n","import type { BitbucketPullRequest } from '../domain/PullRequest';\nimport type { BitbucketPullRequestActivity, ActivitiesParams } from '../domain/PullRequestActivity';\nimport type { BitbucketPullRequestTask, TasksParams } from '../domain/PullRequestTask';\nimport type { BitbucketCommit } from '../domain/Commit';\nimport type { BitbucketChange, ChangesParams } from '../domain/Change';\nimport type { BitbucketReport, ReportsParams } from '../domain/Report';\nimport type { BitbucketBuildSummaries } from '../domain/BuildSummary';\nimport type { BitbucketIssue } from '../domain/Issue';\nimport type { PagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn } from './ProjectResource';\n\n/**\n * Represents a Bitbucket pull request resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketPullRequest>` so it can be awaited directly\n * to fetch the pull request info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get pull request info\n * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);\n *\n * // Get activities\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n *\n * // Get tasks\n * const tasks = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).tasks();\n *\n * // Get commits\n * const commits = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).commits();\n *\n * // Get changes\n * const changes = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).changes();\n *\n * // Get reports\n * const reports = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).reports();\n *\n * // Get build summaries\n * const builds = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).buildSummaries();\n *\n * // Get linked Jira issues\n * const issues = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).issues();\n * ```\n */\nexport class PullRequestResource implements PromiseLike<BitbucketPullRequest> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n projectKey: string,\n repoSlug: string,\n pullRequestId: number,\n ) {\n this.basePath = `/projects/${projectKey}/repos/${repoSlug}/pull-requests/${pullRequestId}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the pull request info.\n * Delegates to {@link PullRequestResource.get}.\n */\n then<TResult1 = BitbucketPullRequest, TResult2 = never>(\n onfulfilled?: ((value: BitbucketPullRequest) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the pull request details.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}`\n *\n * @returns The pull request object\n */\n async get(): Promise<BitbucketPullRequest> {\n return this.request<BitbucketPullRequest>(this.basePath);\n }\n\n /**\n * Fetches the activity feed for this pull request.\n *\n * Activities include comments, approvals, reviews, rescopes, merges, and declines.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/activities`\n *\n * @param params - Optional filters: `limit`, `start`, `fromId`, `fromType`\n * @returns An array of pull request activities, ordered from most recent to oldest\n */\n async activities(params?: ActivitiesParams): Promise<PagedResponse<BitbucketPullRequestActivity>> {\n return this.request<PagedResponse<BitbucketPullRequestActivity>>(\n `${this.basePath}/activities`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the tasks (review to-do items) for this pull request.\n *\n * Tasks are created by reviewers on specific comments and can be `OPEN` or `RESOLVED`.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/tasks`\n *\n * @param params - Optional filters: `limit`, `start`\n * @returns An array of pull request tasks\n */\n async tasks(params?: TasksParams): Promise<PagedResponse<BitbucketPullRequestTask>> {\n return this.request<PagedResponse<BitbucketPullRequestTask>>(\n `${this.basePath}/tasks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the commits included in this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/commits`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns An array of commits\n */\n async commits(params?: PaginationParams): Promise<PagedResponse<BitbucketCommit>> {\n return this.request<PagedResponse<BitbucketCommit>>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the file changes included in this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/changes`\n *\n * @param params - Optional filters: `limit`, `start`, `withComments`\n * @returns An array of file changes\n */\n async changes(params?: ChangesParams): Promise<PagedResponse<BitbucketChange>> {\n return this.request<PagedResponse<BitbucketChange>>(\n `${this.basePath}/changes`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the Code Insights reports for this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/reports`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns An array of Code Insights reports\n */\n async reports(params?: ReportsParams): Promise<PagedResponse<BitbucketReport>> {\n return this.request<PagedResponse<BitbucketReport>>(\n `${this.basePath}/reports`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the aggregated build summaries for this pull request.\n *\n * Returns a map of commit hash → build counts per state\n * (`successful`, `failed`, `inProgress`, `cancelled`, `unknown`).\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/build-summaries`\n *\n * @returns A record keyed by commit SHA with aggregated build counts\n */\n async buildSummaries(): Promise<BitbucketBuildSummaries> {\n return this.request<BitbucketBuildSummaries>(`${this.basePath}/build-summaries`);\n }\n\n /**\n * Fetches the Jira issues linked to this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/issues`\n *\n * @returns An array of linked Jira issues\n */\n async issues(): Promise<BitbucketIssue[]> {\n return this.request<BitbucketIssue[]>(`${this.basePath}/issues`);\n }\n}\n","import type { BitbucketRepository } from '../domain/Repository';\nimport type { BitbucketPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { BitbucketCommit, CommitsParams } from '../domain/Commit';\nimport type { BitbucketBranch, BranchesParams } from '../domain/Branch';\nimport type { BitbucketTag, TagsParams } from '../domain/Tag';\nimport type { BitbucketRepositorySize } from '../domain/RepositorySize';\nimport type { BitbucketLastModifiedEntry, LastModifiedParams } from '../domain/LastModified';\nimport type { RawFileParams } from '../domain/RawFile';\nimport type { PagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn, RequestTextFn } from './ProjectResource';\nimport { PullRequestResource } from './PullRequestResource';\n\n/**\n * Represents a Bitbucket repository resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketRepository>` so it can be awaited directly\n * to fetch repository info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get repository info\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n *\n * // Get pull requests\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n *\n * // Navigate into a specific pull request\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n *\n * // Get commits\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * ```\n */\nexport class RepositoryResource implements PromiseLike<BitbucketRepository> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestText: RequestTextFn,\n private readonly projectKey: string,\n private readonly repoSlug: string,\n ) {\n this.basePath = `/projects/${projectKey}/repos/${repoSlug}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the repository info.\n * Delegates to {@link RepositoryResource.get}.\n */\n then<TResult1 = BitbucketRepository, TResult2 = never>(\n onfulfilled?: ((value: BitbucketRepository) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the repository details.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}`\n *\n * @returns The repository object\n */\n async get(): Promise<BitbucketRepository> {\n return this.request<BitbucketRepository>(this.basePath);\n }\n\n /**\n * Fetches pull requests for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests`\n *\n * @param params - Optional filters: `limit`, `start`, `state`, `direction`, `at`, `order`\n * @returns An array of pull requests\n */\n async pullRequests(params?: PullRequestsParams): Promise<PagedResponse<BitbucketPullRequest>> {\n return this.request<PagedResponse<BitbucketPullRequest>>(\n `${this.basePath}/pull-requests`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches commits for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/commits`\n *\n * @param params - Optional filters: `limit`, `start`, `until`, `since`, `path`, `merges`, `followRenames`, `ignoreMissing`\n * @returns An array of commits\n */\n async commits(params?: CommitsParams): Promise<PagedResponse<BitbucketCommit>> {\n return this.request<PagedResponse<BitbucketCommit>>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the files last modified in this repository along with the commit that last touched each.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/last-modified`\n *\n * @param params - Optional filters: `limit`, `start`, `at`\n * @returns An array of last-modified entries\n */\n async lastModified(params?: LastModifiedParams): Promise<PagedResponse<BitbucketLastModifiedEntry>> {\n return this.request<PagedResponse<BitbucketLastModifiedEntry>>(\n `${this.basePath}/last-modified`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the size of this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/sizes`\n *\n * @returns The repository size object\n */\n async size(): Promise<BitbucketRepositorySize> {\n return this.request<BitbucketRepositorySize>(`${this.basePath}/sizes`);\n }\n\n /**\n * Fetches branches for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/branches`\n *\n * @param params - Optional filters: `limit`, `start`, `filterText`, `orderBy`, `details`, `base`, `boostMatches`\n * @returns An array of branches\n */\n async branches(params?: BranchesParams): Promise<PagedResponse<BitbucketBranch>> {\n return this.request<PagedResponse<BitbucketBranch>>(\n `${this.basePath}/branches`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the forks of this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/forks`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns A paged response of forked repositories\n */\n async forks(params?: PaginationParams): Promise<PagedResponse<BitbucketRepository>> {\n return this.request<PagedResponse<BitbucketRepository>>(\n `${this.basePath}/forks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches tags for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/tags`\n *\n * @param params - Optional filters: `limit`, `start`, `filterText`, `orderBy`\n * @returns A paged response of tags\n */\n async tags(params?: TagsParams): Promise<PagedResponse<BitbucketTag>> {\n return this.request<PagedResponse<BitbucketTag>>(\n `${this.basePath}/tags`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link PullRequestResource} for a given pull request ID, providing\n * access to pull request data and sub-resources (activities, etc.).\n *\n * The returned resource can be awaited directly to fetch pull request info,\n * or chained to access nested resources.\n *\n * @param pullRequestId - The numeric pull request ID\n * @returns A chainable pull request resource\n *\n * @example\n * ```typescript\n * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n * ```\n */\n /**\n * Fetches the raw content of a file in this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/raw/{path}`\n *\n * @param filePath - Path to the file (e.g., `'src/index.ts'`)\n * @param params - Optional: `at` (branch, tag, or commit SHA)\n * @returns The raw file content as a string\n */\n async raw(filePath: string, params?: RawFileParams): Promise<string> {\n return this.requestText(\n `${this.basePath}/raw/${filePath}`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n pullRequest(pullRequestId: number): PullRequestResource {\n return new PullRequestResource(this.request, this.projectKey, this.repoSlug, pullRequestId);\n }\n}\n","import type { BitbucketProject } from '../domain/Project';\nimport type { BitbucketRepository, ReposParams } from '../domain/Repository';\nimport type { BitbucketUserPermission, ProjectUsersParams } from '../domain/User';\nimport type { PagedResponse } from '../domain/Pagination';\nimport { RepositoryResource } from './RepositoryResource';\n\n/** @internal */\nexport type RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<T>;\n\n/** @internal */\nexport type RequestTextFn = (\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<string>;\n\n/**\n * Represents a Bitbucket project resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketProject>` so it can be awaited directly\n * to fetch the project info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get project info\n * const project = await bbClient.project('PROJ');\n *\n * // Get repositories with filters\n * const repos = await bbClient.project('PROJ').repos({ limit: 50, name: 'api' });\n *\n * // Navigate into a specific repository\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests();\n *\n * // Get users with access to the project\n * const users = await bbClient.project('PROJ').users({ permission: 'PROJECT_WRITE' });\n * ```\n */\nexport class ProjectResource implements PromiseLike<BitbucketProject> {\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestText: RequestTextFn,\n private readonly key: string,\n ) {}\n\n /**\n * Allows the resource to be awaited directly, resolving with the project info.\n * Delegates to {@link ProjectResource.get}.\n */\n then<TResult1 = BitbucketProject, TResult2 = never>(\n onfulfilled?: ((value: BitbucketProject) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the project details.\n *\n * `GET /rest/api/latest/projects/{key}`\n *\n * @returns The project object\n */\n async get(): Promise<BitbucketProject> {\n return this.request<BitbucketProject>(`/projects/${this.key}`);\n }\n\n /**\n * Fetches repositories belonging to this project.\n *\n * `GET /rest/api/latest/projects/{key}/repos`\n *\n * @param params - Optional filters: `limit`, `start`, `slug`, `name`, `permission`\n * @returns An array of repositories\n */\n async repos(params?: ReposParams): Promise<PagedResponse<BitbucketRepository>> {\n return this.request<PagedResponse<BitbucketRepository>>(\n `/projects/${this.key}/repos`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given repository slug, providing\n * access to repository-level data and sub-resources (pull requests, commits, etc.).\n *\n * The returned resource can be awaited directly to fetch repository info,\n * or chained to access nested resources.\n *\n * @param repoSlug - The repository slug (e.g., `'my-repo'`)\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * ```\n */\n repo(repoSlug: string): RepositoryResource {\n return new RepositoryResource(this.request, this.requestText, this.key, repoSlug);\n }\n\n /**\n * Fetches users with explicit permissions on this project.\n *\n * `GET /rest/api/latest/projects/{key}/permissions/users`\n *\n * @param params - Optional filters: `limit`, `start`, `filter`, `permission`\n * @returns An array of user–permission pairs\n */\n async users(params?: ProjectUsersParams): Promise<PagedResponse<BitbucketUserPermission>> {\n return this.request<PagedResponse<BitbucketUserPermission>>(\n `/projects/${this.key}/permissions/users`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","import type { BitbucketUser } from '../domain/User';\nimport type { RequestFn } from './ProjectResource';\n\n/**\n * Represents a Bitbucket user resource.\n *\n * Implements `PromiseLike<BitbucketUser>` so it can be awaited directly\n * to fetch user info.\n *\n * @example\n * ```typescript\n * // Await directly to get user info\n * const user = await bbClient.user('pilmee');\n * ```\n */\nexport class UserResource implements PromiseLike<BitbucketUser> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n slug: string,\n ) {\n this.basePath = `/users/${slug}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the user info.\n * Delegates to {@link UserResource.get}.\n */\n then<TResult1 = BitbucketUser, TResult2 = never>(\n onfulfilled?: ((value: BitbucketUser) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the user details.\n *\n * `GET /rest/api/latest/users/{slug}`\n *\n * @returns The user object\n */\n async get(): Promise<BitbucketUser> {\n return this.request<BitbucketUser>(this.basePath);\n }\n}\n","import { Security } from './security/Security';\nimport { ProjectResource, type RequestFn, type RequestTextFn } from './resources/ProjectResource';\nimport { UserResource } from './resources/UserResource';\nimport type { BitbucketProject, ProjectsParams } from './domain/Project';\nimport type { BitbucketUser, UsersParams } from './domain/User';\nimport type { PagedResponse } from './domain/Pagination';\n\n/**\n * Constructor options for {@link BitbucketClient}.\n */\nexport interface BitbucketClientOptions {\n /** The host URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`) */\n apiUrl: string;\n /** The API path to prepend to every request (e.g., `'rest/api/latest'`) */\n apiPath: string;\n /** The username to authenticate with */\n user: string;\n /** The personal access token or password to authenticate with */\n token: string;\n}\n\n/**\n * Main entry point for the Bitbucket Data Center REST API client.\n *\n * @example\n * ```typescript\n * const bbClient = new BitbucketClient({\n * apiUrl: 'https://bitbucket.example.com',\n * apiPath: 'rest/api/latest',\n * user: 'pilmee',\n * token: 'my-token',\n * });\n *\n * const projects = await bbClient.projects({ limit: 50 });\n * const project = await bbClient.project('PROJ');\n * const repos = await bbClient.project('PROJ').repos({ name: 'api' });\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * const users = await bbClient.users({ filter: 'john' });\n * const user = await bbClient.user('pilmee');\n * ```\n */\nexport class BitbucketClient {\n private readonly security: Security;\n private readonly apiPath: string;\n\n /**\n * @param options - Connection and authentication options\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor({ apiUrl, apiPath, user, token }: BitbucketClientOptions) {\n this.security = new Security(apiUrl, user, token);\n this.apiPath = apiPath.replace(/^\\/|\\/$/g, '');\n }\n\n /**\n * Performs an authenticated GET request to the Bitbucket REST API.\n *\n * @param path - API path appended directly to `apiUrl` (e.g., `'/projects'`)\n * @param params - Optional query parameters to append to the URL\n * @throws {Error} If the HTTP response is not OK\n * @internal\n */\n private async request<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<T> {\n const base = `${this.security.getApiUrl()}/${this.apiPath}${path}`;\n const url = buildUrl(base, params);\n const response = await fetch(url, { headers: this.security.getHeaders() });\n if (!response.ok) {\n throw new Error(`Bitbucket API error: ${response.status} ${response.statusText}`);\n }\n return response.json() as Promise<T>;\n }\n\n private async requestText(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<string> {\n const base = `${this.security.getApiUrl()}/${this.apiPath}${path}`;\n const url = buildUrl(base, params);\n const response = await fetch(url, { headers: this.security.getHeaders() });\n if (!response.ok) {\n throw new Error(`Bitbucket API error: ${response.status} ${response.statusText}`);\n }\n return response.text();\n }\n\n /**\n * Fetches all projects accessible to the authenticated user.\n *\n * `GET /rest/api/latest/projects`\n *\n * @param params - Optional filters: `limit`, `start`, `name`, `permission`\n * @returns An array of projects\n */\n async projects(params?: ProjectsParams): Promise<PagedResponse<BitbucketProject>> {\n return this.request<PagedResponse<BitbucketProject>>(\n '/projects',\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link ProjectResource} for a given project key, providing access\n * to project-level data and sub-resources.\n *\n * The returned resource can be awaited directly to fetch project info,\n * or chained to access nested resources.\n *\n * @param projectKey - The project key (e.g., `'PROJ'`)\n * @returns A chainable project resource\n *\n * @example\n * ```typescript\n * const project = await bbClient.project('PROJ');\n * const repos = await bbClient.project('PROJ').repos({ limit: 10 });\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests();\n * ```\n */\n project(projectKey: string): ProjectResource {\n const request: RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ) => this.request<T>(path, params);\n const requestText: RequestTextFn = (path, params) => this.requestText(path, params);\n return new ProjectResource(request, requestText, projectKey);\n }\n\n /**\n * Fetches all users accessible to the authenticated user.\n *\n * `GET /rest/api/latest/users`\n *\n * @param params - Optional filters: `limit`, `start`, `filter`\n * @returns An array of users\n */\n async users(params?: UsersParams): Promise<PagedResponse<BitbucketUser>> {\n return this.request<PagedResponse<BitbucketUser>>(\n '/users',\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link UserResource} for a given user slug, providing access\n * to user data.\n *\n * The returned resource can be awaited directly to fetch user info.\n *\n * @param slug - The user slug (e.g., `'pilmee'`)\n * @returns A chainable user resource\n *\n * @example\n * ```typescript\n * const user = await bbClient.user('pilmee');\n * ```\n */\n user(slug: string): UserResource {\n const request: RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ) => this.request<T>(path, params);\n return new UserResource(request, slug);\n }\n}\n\n/**\n * Appends query parameters to a URL string, skipping `undefined` values.\n * @internal\n */\nfunction buildUrl(base: string, params?: Record<string, string | number | boolean>): string {\n if (!params) return base;\n const entries = Object.entries(params).filter(([, v]) => v !== undefined);\n if (entries.length === 0) return base;\n const search = new URLSearchParams(entries.map(([k, v]) => [k, String(v)]));\n return `${base}?${search.toString()}`;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/security/Security.ts","../src/resources/PullRequestResource.ts","../src/resources/RepositoryResource.ts","../src/resources/ProjectResource.ts","../src/errors/BitbucketApiError.ts","../src/resources/UserResource.ts","../src/BitbucketClient.ts"],"sourcesContent":["export { BitbucketClient } from './BitbucketClient';\nexport { BitbucketApiError } from './errors/BitbucketApiError';\nexport type { BitbucketClientOptions } from './BitbucketClient';\nexport { Security } from './security/Security';\nexport { ProjectResource } from './resources/ProjectResource';\nexport { RepositoryResource } from './resources/RepositoryResource';\nexport { PullRequestResource } from './resources/PullRequestResource';\nexport { UserResource } from './resources/UserResource';\nexport type { BitbucketProject, ProjectsParams } from './domain/Project';\nexport type { BitbucketRepository, ReposParams } from './domain/Repository';\nexport type { BitbucketPullRequest, BitbucketParticipant, BitbucketRef, PullRequestsParams } from './domain/PullRequest';\nexport type { BitbucketPullRequestActivity, BitbucketPullRequestComment, BitbucketActivityUser, PullRequestActivityAction, ActivitiesParams } from './domain/PullRequestActivity';\nexport type { BitbucketPullRequestTask, PullRequestTaskState, PullRequestTaskPermittedOperations, PullRequestTaskAnchor, TasksParams } from './domain/PullRequestTask';\nexport type { BitbucketChange, BitbucketChangePath, ChangeType, ChangeNodeType, ChangesParams } from './domain/Change';\nexport type { BitbucketReport, BitbucketReportData, ReportResult, ReportDataType, ReportsParams } from './domain/Report';\nexport type { BitbucketBuildSummaries, BitbucketBuildCount } from './domain/BuildSummary';\nexport type { BitbucketIssue } from './domain/Issue';\nexport type { BitbucketUser, BitbucketUserPermission, UsersParams, ProjectUsersParams } from './domain/User';\nexport type { BitbucketCommit, BitbucketCommitAuthor, CommitsParams } from './domain/Commit';\nexport type { BitbucketBranch, BranchesParams } from './domain/Branch';\nexport type { BitbucketTag, TagsParams } from './domain/Tag';\nexport type { BitbucketRepositorySize } from './domain/RepositorySize';\nexport type { BitbucketLastModifiedEntry, LastModifiedParams } from './domain/LastModified';\nexport type { RawFileParams } from './domain/RawFile';\nexport type { PaginationParams, PagedResponse } from './domain/Pagination';\n","/**\n * Encodes a string to Base64 in a way that works in both Node.js and browsers.\n * @internal\n */\nfunction toBase64(value: string): string {\n if (typeof btoa !== 'undefined') {\n return btoa(value);\n }\n return Buffer.from(value).toString('base64');\n}\n\n/**\n * Handles Basic Authentication for Bitbucket Data Center REST API requests.\n *\n * @example\n * ```typescript\n * const security = new Security(\n * 'https://bitbucket.example.com',\n * 'my-user',\n * 'my-token'\n * );\n *\n * const headers = security.getHeaders();\n * // { Authorization: 'Basic <base64>', 'Content-Type': 'application/json', Accept: 'application/json' }\n * ```\n */\nexport class Security {\n private readonly apiUrl: string;\n private readonly authorizationHeader: string;\n\n /**\n * Creates a new Security instance with Basic Authentication credentials.\n *\n * @param apiUrl - The base URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`).\n * Must be a valid URL; throws if it cannot be parsed.\n * @param user - The username to authenticate with\n * @param token - The personal access token or password to authenticate with\n *\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor(apiUrl: string, user: string, token: string) {\n if (!URL.canParse(apiUrl)) {\n throw new TypeError(`Invalid apiUrl: \"${apiUrl}\" is not a valid URL`);\n }\n this.apiUrl = apiUrl.replace(/\\/$/, '');\n this.authorizationHeader = `Basic ${toBase64(`${user}:${token}`)}`;\n }\n\n /**\n * Returns the base URL of the Bitbucket Data Center instance, without a trailing slash.\n *\n * @returns The API base URL\n */\n getApiUrl(): string {\n return this.apiUrl;\n }\n\n /**\n * Returns the value of the `Authorization` header for Basic Authentication.\n *\n * @returns The Authorization header value in the format `Basic <base64-encoded-credentials>`\n */\n getAuthorizationHeader(): string {\n return this.authorizationHeader;\n }\n\n /**\n * Returns the full set of HTTP headers required for authenticated API requests.\n *\n * @returns An object containing `Authorization`, `Content-Type`, and `Accept` headers\n */\n getHeaders(): Record<string, string> {\n return {\n Authorization: this.authorizationHeader,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n }\n}\n","import type { BitbucketPullRequest } from '../domain/PullRequest';\nimport type { BitbucketPullRequestActivity, ActivitiesParams } from '../domain/PullRequestActivity';\nimport type { BitbucketPullRequestTask, TasksParams } from '../domain/PullRequestTask';\nimport type { BitbucketCommit } from '../domain/Commit';\nimport type { BitbucketChange, ChangesParams } from '../domain/Change';\nimport type { BitbucketReport, ReportsParams } from '../domain/Report';\nimport type { BitbucketBuildSummaries } from '../domain/BuildSummary';\nimport type { BitbucketIssue } from '../domain/Issue';\nimport type { PagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn } from './ProjectResource';\n\n/**\n * Represents a Bitbucket pull request resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketPullRequest>` so it can be awaited directly\n * to fetch the pull request info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get pull request info\n * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);\n *\n * // Get activities\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n *\n * // Get tasks\n * const tasks = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).tasks();\n *\n * // Get commits\n * const commits = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).commits();\n *\n * // Get changes\n * const changes = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).changes();\n *\n * // Get reports\n * const reports = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).reports();\n *\n * // Get build summaries\n * const builds = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).buildSummaries();\n *\n * // Get linked Jira issues\n * const issues = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).issues();\n * ```\n */\nexport class PullRequestResource implements PromiseLike<BitbucketPullRequest> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n projectKey: string,\n repoSlug: string,\n pullRequestId: number,\n ) {\n this.basePath = `/projects/${projectKey}/repos/${repoSlug}/pull-requests/${pullRequestId}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the pull request info.\n * Delegates to {@link PullRequestResource.get}.\n */\n then<TResult1 = BitbucketPullRequest, TResult2 = never>(\n onfulfilled?: ((value: BitbucketPullRequest) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the pull request details.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}`\n *\n * @returns The pull request object\n */\n async get(): Promise<BitbucketPullRequest> {\n return this.request<BitbucketPullRequest>(this.basePath);\n }\n\n /**\n * Fetches the activity feed for this pull request.\n *\n * Activities include comments, approvals, reviews, rescopes, merges, and declines.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/activities`\n *\n * @param params - Optional filters: `limit`, `start`, `fromId`, `fromType`\n * @returns An array of pull request activities, ordered from most recent to oldest\n */\n async activities(params?: ActivitiesParams): Promise<PagedResponse<BitbucketPullRequestActivity>> {\n return this.request<PagedResponse<BitbucketPullRequestActivity>>(\n `${this.basePath}/activities`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the tasks (review to-do items) for this pull request.\n *\n * Tasks are created by reviewers on specific comments and can be `OPEN` or `RESOLVED`.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/tasks`\n *\n * @param params - Optional filters: `limit`, `start`\n * @returns An array of pull request tasks\n */\n async tasks(params?: TasksParams): Promise<PagedResponse<BitbucketPullRequestTask>> {\n return this.request<PagedResponse<BitbucketPullRequestTask>>(\n `${this.basePath}/tasks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the commits included in this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/commits`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns An array of commits\n */\n async commits(params?: PaginationParams): Promise<PagedResponse<BitbucketCommit>> {\n return this.request<PagedResponse<BitbucketCommit>>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the file changes included in this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/changes`\n *\n * @param params - Optional filters: `limit`, `start`, `withComments`\n * @returns An array of file changes\n */\n async changes(params?: ChangesParams): Promise<PagedResponse<BitbucketChange>> {\n return this.request<PagedResponse<BitbucketChange>>(\n `${this.basePath}/changes`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the Code Insights reports for this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/reports`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns An array of Code Insights reports\n */\n async reports(params?: ReportsParams): Promise<PagedResponse<BitbucketReport>> {\n return this.request<PagedResponse<BitbucketReport>>(\n `${this.basePath}/reports`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the aggregated build summaries for this pull request.\n *\n * Returns a map of commit hash → build counts per state\n * (`successful`, `failed`, `inProgress`, `cancelled`, `unknown`).\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/build-summaries`\n *\n * @returns A record keyed by commit SHA with aggregated build counts\n */\n async buildSummaries(): Promise<BitbucketBuildSummaries> {\n return this.request<BitbucketBuildSummaries>(`${this.basePath}/build-summaries`);\n }\n\n /**\n * Fetches the Jira issues linked to this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/issues`\n *\n * @returns An array of linked Jira issues\n */\n async issues(): Promise<BitbucketIssue[]> {\n return this.request<BitbucketIssue[]>(`${this.basePath}/issues`);\n }\n}\n","import type { BitbucketRepository } from '../domain/Repository';\nimport type { BitbucketPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { BitbucketCommit, CommitsParams } from '../domain/Commit';\nimport type { BitbucketBranch, BranchesParams } from '../domain/Branch';\nimport type { BitbucketTag, TagsParams } from '../domain/Tag';\nimport type { BitbucketRepositorySize } from '../domain/RepositorySize';\nimport type { BitbucketLastModifiedEntry, LastModifiedParams } from '../domain/LastModified';\nimport type { RawFileParams } from '../domain/RawFile';\nimport type { PagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn, RequestTextFn } from './ProjectResource';\nimport { PullRequestResource } from './PullRequestResource';\n\n/**\n * Represents a Bitbucket repository resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketRepository>` so it can be awaited directly\n * to fetch repository info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get repository info\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n *\n * // Get pull requests\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n *\n * // Navigate into a specific pull request\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n *\n * // Get commits\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * ```\n */\nexport class RepositoryResource implements PromiseLike<BitbucketRepository> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestText: RequestTextFn,\n private readonly projectKey: string,\n private readonly repoSlug: string,\n ) {\n this.basePath = `/projects/${projectKey}/repos/${repoSlug}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the repository info.\n * Delegates to {@link RepositoryResource.get}.\n */\n then<TResult1 = BitbucketRepository, TResult2 = never>(\n onfulfilled?: ((value: BitbucketRepository) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the repository details.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}`\n *\n * @returns The repository object\n */\n async get(): Promise<BitbucketRepository> {\n return this.request<BitbucketRepository>(this.basePath);\n }\n\n /**\n * Fetches pull requests for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests`\n *\n * @param params - Optional filters: `limit`, `start`, `state`, `direction`, `at`, `order`\n * @returns An array of pull requests\n */\n async pullRequests(params?: PullRequestsParams): Promise<PagedResponse<BitbucketPullRequest>> {\n return this.request<PagedResponse<BitbucketPullRequest>>(\n `${this.basePath}/pull-requests`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches commits for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/commits`\n *\n * @param params - Optional filters: `limit`, `start`, `until`, `since`, `path`, `merges`, `followRenames`, `ignoreMissing`\n * @returns An array of commits\n */\n async commits(params?: CommitsParams): Promise<PagedResponse<BitbucketCommit>> {\n return this.request<PagedResponse<BitbucketCommit>>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the files last modified in this repository along with the commit that last touched each.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/last-modified`\n *\n * @param params - Optional filters: `limit`, `start`, `at`\n * @returns An array of last-modified entries\n */\n async lastModified(params?: LastModifiedParams): Promise<PagedResponse<BitbucketLastModifiedEntry>> {\n return this.request<PagedResponse<BitbucketLastModifiedEntry>>(\n `${this.basePath}/last-modified`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the size of this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/sizes`\n *\n * @returns The repository size object\n */\n async size(): Promise<BitbucketRepositorySize> {\n return this.request<BitbucketRepositorySize>(`${this.basePath}/sizes`);\n }\n\n /**\n * Fetches branches for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/branches`\n *\n * @param params - Optional filters: `limit`, `start`, `filterText`, `orderBy`, `details`, `base`, `boostMatches`\n * @returns An array of branches\n */\n async branches(params?: BranchesParams): Promise<PagedResponse<BitbucketBranch>> {\n return this.request<PagedResponse<BitbucketBranch>>(\n `${this.basePath}/branches`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the forks of this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/forks`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns A paged response of forked repositories\n */\n async forks(params?: PaginationParams): Promise<PagedResponse<BitbucketRepository>> {\n return this.request<PagedResponse<BitbucketRepository>>(\n `${this.basePath}/forks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches tags for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/tags`\n *\n * @param params - Optional filters: `limit`, `start`, `filterText`, `orderBy`\n * @returns A paged response of tags\n */\n async tags(params?: TagsParams): Promise<PagedResponse<BitbucketTag>> {\n return this.request<PagedResponse<BitbucketTag>>(\n `${this.basePath}/tags`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link PullRequestResource} for a given pull request ID, providing\n * access to pull request data and sub-resources (activities, etc.).\n *\n * The returned resource can be awaited directly to fetch pull request info,\n * or chained to access nested resources.\n *\n * @param pullRequestId - The numeric pull request ID\n * @returns A chainable pull request resource\n *\n * @example\n * ```typescript\n * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n * ```\n */\n /**\n * Fetches the raw content of a file in this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/raw/{path}`\n *\n * @param filePath - Path to the file (e.g., `'src/index.ts'`)\n * @param params - Optional: `at` (branch, tag, or commit SHA)\n * @returns The raw file content as a string\n */\n async raw(filePath: string, params?: RawFileParams): Promise<string> {\n return this.requestText(\n `${this.basePath}/raw/${filePath}`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n pullRequest(pullRequestId: number): PullRequestResource {\n return new PullRequestResource(this.request, this.projectKey, this.repoSlug, pullRequestId);\n }\n}\n","import type { BitbucketProject } from '../domain/Project';\nimport type { BitbucketRepository, ReposParams } from '../domain/Repository';\nimport type { BitbucketUserPermission, ProjectUsersParams } from '../domain/User';\nimport type { PagedResponse } from '../domain/Pagination';\nimport { RepositoryResource } from './RepositoryResource';\n\n/** @internal */\nexport type RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<T>;\n\n/** @internal */\nexport type RequestTextFn = (\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<string>;\n\n/**\n * Represents a Bitbucket project resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketProject>` so it can be awaited directly\n * to fetch the project info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get project info\n * const project = await bbClient.project('PROJ');\n *\n * // Get repositories with filters\n * const repos = await bbClient.project('PROJ').repos({ limit: 50, name: 'api' });\n *\n * // Navigate into a specific repository\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests();\n *\n * // Get users with access to the project\n * const users = await bbClient.project('PROJ').users({ permission: 'PROJECT_WRITE' });\n * ```\n */\nexport class ProjectResource implements PromiseLike<BitbucketProject> {\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestText: RequestTextFn,\n private readonly key: string,\n ) {}\n\n /**\n * Allows the resource to be awaited directly, resolving with the project info.\n * Delegates to {@link ProjectResource.get}.\n */\n then<TResult1 = BitbucketProject, TResult2 = never>(\n onfulfilled?: ((value: BitbucketProject) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the project details.\n *\n * `GET /rest/api/latest/projects/{key}`\n *\n * @returns The project object\n */\n async get(): Promise<BitbucketProject> {\n return this.request<BitbucketProject>(`/projects/${this.key}`);\n }\n\n /**\n * Fetches repositories belonging to this project.\n *\n * `GET /rest/api/latest/projects/{key}/repos`\n *\n * @param params - Optional filters: `limit`, `start`, `slug`, `name`, `permission`\n * @returns An array of repositories\n */\n async repos(params?: ReposParams): Promise<PagedResponse<BitbucketRepository>> {\n return this.request<PagedResponse<BitbucketRepository>>(\n `/projects/${this.key}/repos`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given repository slug, providing\n * access to repository-level data and sub-resources (pull requests, commits, etc.).\n *\n * The returned resource can be awaited directly to fetch repository info,\n * or chained to access nested resources.\n *\n * @param repoSlug - The repository slug (e.g., `'my-repo'`)\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * ```\n */\n repo(repoSlug: string): RepositoryResource {\n return new RepositoryResource(this.request, this.requestText, this.key, repoSlug);\n }\n\n /**\n * Fetches users with explicit permissions on this project.\n *\n * `GET /rest/api/latest/projects/{key}/permissions/users`\n *\n * @param params - Optional filters: `limit`, `start`, `filter`, `permission`\n * @returns An array of user–permission pairs\n */\n async users(params?: ProjectUsersParams): Promise<PagedResponse<BitbucketUserPermission>> {\n return this.request<PagedResponse<BitbucketUserPermission>>(\n `/projects/${this.key}/permissions/users`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","/**\n * Thrown when the Bitbucket Data Center API returns a non-2xx response.\n *\n * @example\n * ```typescript\n * import { BitbucketApiError } from 'bitbucket-datacenter-api-client';\n *\n * try {\n * await bb.project('NONEXISTENT');\n * } catch (err) {\n * if (err instanceof BitbucketApiError) {\n * console.log(err.status); // 404\n * console.log(err.statusText); // 'Not Found'\n * console.log(err.message); // 'Bitbucket API error: 404 Not Found'\n * }\n * }\n * ```\n */\nexport class BitbucketApiError extends Error {\n /** HTTP status code (e.g. `404`, `401`, `403`) */\n readonly status: number;\n /** HTTP status text (e.g. `'Not Found'`, `'Unauthorized'`) */\n readonly statusText: string;\n\n constructor(status: number, statusText: string) {\n super(`Bitbucket API error: ${status} ${statusText}`);\n this.name = 'BitbucketApiError';\n this.status = status;\n this.statusText = statusText;\n }\n}\n","import type { BitbucketUser } from '../domain/User';\nimport type { RequestFn } from './ProjectResource';\n\n/**\n * Represents a Bitbucket user resource.\n *\n * Implements `PromiseLike<BitbucketUser>` so it can be awaited directly\n * to fetch user info.\n *\n * @example\n * ```typescript\n * // Await directly to get user info\n * const user = await bbClient.user('pilmee');\n * ```\n */\nexport class UserResource implements PromiseLike<BitbucketUser> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n slug: string,\n ) {\n this.basePath = `/users/${slug}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the user info.\n * Delegates to {@link UserResource.get}.\n */\n then<TResult1 = BitbucketUser, TResult2 = never>(\n onfulfilled?: ((value: BitbucketUser) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the user details.\n *\n * `GET /rest/api/latest/users/{slug}`\n *\n * @returns The user object\n */\n async get(): Promise<BitbucketUser> {\n return this.request<BitbucketUser>(this.basePath);\n }\n}\n","import { Security } from './security/Security';\nimport { ProjectResource, type RequestFn, type RequestTextFn } from './resources/ProjectResource';\nimport { BitbucketApiError } from './errors/BitbucketApiError';\nimport { UserResource } from './resources/UserResource';\nimport type { BitbucketProject, ProjectsParams } from './domain/Project';\nimport type { BitbucketUser, UsersParams } from './domain/User';\nimport type { PagedResponse } from './domain/Pagination';\n\n/**\n * Constructor options for {@link BitbucketClient}.\n */\nexport interface BitbucketClientOptions {\n /** The host URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`) */\n apiUrl: string;\n /** The API path to prepend to every request (e.g., `'rest/api/latest'`) */\n apiPath: string;\n /** The username to authenticate with */\n user: string;\n /** The personal access token or password to authenticate with */\n token: string;\n}\n\n/**\n * Main entry point for the Bitbucket Data Center REST API client.\n *\n * @example\n * ```typescript\n * const bbClient = new BitbucketClient({\n * apiUrl: 'https://bitbucket.example.com',\n * apiPath: 'rest/api/latest',\n * user: 'pilmee',\n * token: 'my-token',\n * });\n *\n * const projects = await bbClient.projects({ limit: 50 });\n * const project = await bbClient.project('PROJ');\n * const repos = await bbClient.project('PROJ').repos({ name: 'api' });\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * const users = await bbClient.users({ filter: 'john' });\n * const user = await bbClient.user('pilmee');\n * ```\n */\nexport class BitbucketClient {\n private readonly security: Security;\n private readonly apiPath: string;\n\n /**\n * @param options - Connection and authentication options\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor({ apiUrl, apiPath, user, token }: BitbucketClientOptions) {\n this.security = new Security(apiUrl, user, token);\n this.apiPath = apiPath.replace(/^\\/|\\/$/g, '');\n }\n\n /**\n * Performs an authenticated GET request to the Bitbucket REST API.\n *\n * @param path - API path appended directly to `apiUrl` (e.g., `'/projects'`)\n * @param params - Optional query parameters to append to the URL\n * @throws {Error} If the HTTP response is not OK\n * @internal\n */\n private async request<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<T> {\n const base = `${this.security.getApiUrl()}/${this.apiPath}${path}`;\n const url = buildUrl(base, params);\n const response = await fetch(url, { headers: this.security.getHeaders() });\n if (!response.ok) {\n throw new BitbucketApiError(response.status, response.statusText);\n }\n return response.json() as Promise<T>;\n }\n\n private async requestText(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<string> {\n const base = `${this.security.getApiUrl()}/${this.apiPath}${path}`;\n const url = buildUrl(base, params);\n const response = await fetch(url, { headers: this.security.getHeaders() });\n if (!response.ok) {\n throw new BitbucketApiError(response.status, response.statusText);\n }\n return response.text();\n }\n\n /**\n * Fetches all projects accessible to the authenticated user.\n *\n * `GET /rest/api/latest/projects`\n *\n * @param params - Optional filters: `limit`, `start`, `name`, `permission`\n * @returns An array of projects\n */\n async projects(params?: ProjectsParams): Promise<PagedResponse<BitbucketProject>> {\n return this.request<PagedResponse<BitbucketProject>>(\n '/projects',\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link ProjectResource} for a given project key, providing access\n * to project-level data and sub-resources.\n *\n * The returned resource can be awaited directly to fetch project info,\n * or chained to access nested resources.\n *\n * @param projectKey - The project key (e.g., `'PROJ'`)\n * @returns A chainable project resource\n *\n * @example\n * ```typescript\n * const project = await bbClient.project('PROJ');\n * const repos = await bbClient.project('PROJ').repos({ limit: 10 });\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests();\n * ```\n */\n project(projectKey: string): ProjectResource {\n const request: RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ) => this.request<T>(path, params);\n const requestText: RequestTextFn = (path, params) => this.requestText(path, params);\n return new ProjectResource(request, requestText, projectKey);\n }\n\n /**\n * Fetches all users accessible to the authenticated user.\n *\n * `GET /rest/api/latest/users`\n *\n * @param params - Optional filters: `limit`, `start`, `filter`\n * @returns An array of users\n */\n async users(params?: UsersParams): Promise<PagedResponse<BitbucketUser>> {\n return this.request<PagedResponse<BitbucketUser>>(\n '/users',\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link UserResource} for a given user slug, providing access\n * to user data.\n *\n * The returned resource can be awaited directly to fetch user info.\n *\n * @param slug - The user slug (e.g., `'pilmee'`)\n * @returns A chainable user resource\n *\n * @example\n * ```typescript\n * const user = await bbClient.user('pilmee');\n * ```\n */\n user(slug: string): UserResource {\n const request: RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ) => this.request<T>(path, params);\n return new UserResource(request, slug);\n }\n}\n\n/**\n * Appends query parameters to a URL string, skipping `undefined` values.\n * @internal\n */\nfunction buildUrl(base: string, params?: Record<string, string | number | boolean>): string {\n if (!params) return base;\n const entries = Object.entries(params).filter(([, v]) => v !== undefined);\n if (entries.length === 0) return base;\n const search = new URLSearchParams(entries.map(([k, v]) => [k, String(v)]));\n return `${base}?${search.toString()}`;\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -408,6 +408,16 @@ var ProjectResource = class {
|
|
|
408
408
|
}
|
|
409
409
|
};
|
|
410
410
|
|
|
411
|
+
// src/errors/BitbucketApiError.ts
|
|
412
|
+
var BitbucketApiError = class extends Error {
|
|
413
|
+
constructor(status, statusText) {
|
|
414
|
+
super(`Bitbucket API error: ${status} ${statusText}`);
|
|
415
|
+
this.name = "BitbucketApiError";
|
|
416
|
+
this.status = status;
|
|
417
|
+
this.statusText = statusText;
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
|
|
411
421
|
// src/resources/UserResource.ts
|
|
412
422
|
var UserResource = class {
|
|
413
423
|
/** @internal */
|
|
@@ -457,7 +467,7 @@ var BitbucketClient = class {
|
|
|
457
467
|
const url = buildUrl(base, params);
|
|
458
468
|
const response = await fetch(url, { headers: this.security.getHeaders() });
|
|
459
469
|
if (!response.ok) {
|
|
460
|
-
throw new
|
|
470
|
+
throw new BitbucketApiError(response.status, response.statusText);
|
|
461
471
|
}
|
|
462
472
|
return response.json();
|
|
463
473
|
}
|
|
@@ -466,7 +476,7 @@ var BitbucketClient = class {
|
|
|
466
476
|
const url = buildUrl(base, params);
|
|
467
477
|
const response = await fetch(url, { headers: this.security.getHeaders() });
|
|
468
478
|
if (!response.ok) {
|
|
469
|
-
throw new
|
|
479
|
+
throw new BitbucketApiError(response.status, response.statusText);
|
|
470
480
|
}
|
|
471
481
|
return response.text();
|
|
472
482
|
}
|
|
@@ -547,6 +557,7 @@ function buildUrl(base, params) {
|
|
|
547
557
|
return `${base}?${search.toString()}`;
|
|
548
558
|
}
|
|
549
559
|
export {
|
|
560
|
+
BitbucketApiError,
|
|
550
561
|
BitbucketClient,
|
|
551
562
|
ProjectResource,
|
|
552
563
|
PullRequestResource,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/security/Security.ts","../src/resources/PullRequestResource.ts","../src/resources/RepositoryResource.ts","../src/resources/ProjectResource.ts","../src/resources/UserResource.ts","../src/BitbucketClient.ts"],"sourcesContent":["/**\n * Encodes a string to Base64 in a way that works in both Node.js and browsers.\n * @internal\n */\nfunction toBase64(value: string): string {\n if (typeof btoa !== 'undefined') {\n return btoa(value);\n }\n return Buffer.from(value).toString('base64');\n}\n\n/**\n * Handles Basic Authentication for Bitbucket Data Center REST API requests.\n *\n * @example\n * ```typescript\n * const security = new Security(\n * 'https://bitbucket.example.com',\n * 'my-user',\n * 'my-token'\n * );\n *\n * const headers = security.getHeaders();\n * // { Authorization: 'Basic <base64>', 'Content-Type': 'application/json', Accept: 'application/json' }\n * ```\n */\nexport class Security {\n private readonly apiUrl: string;\n private readonly authorizationHeader: string;\n\n /**\n * Creates a new Security instance with Basic Authentication credentials.\n *\n * @param apiUrl - The base URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`).\n * Must be a valid URL; throws if it cannot be parsed.\n * @param user - The username to authenticate with\n * @param token - The personal access token or password to authenticate with\n *\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor(apiUrl: string, user: string, token: string) {\n if (!URL.canParse(apiUrl)) {\n throw new TypeError(`Invalid apiUrl: \"${apiUrl}\" is not a valid URL`);\n }\n this.apiUrl = apiUrl.replace(/\\/$/, '');\n this.authorizationHeader = `Basic ${toBase64(`${user}:${token}`)}`;\n }\n\n /**\n * Returns the base URL of the Bitbucket Data Center instance, without a trailing slash.\n *\n * @returns The API base URL\n */\n getApiUrl(): string {\n return this.apiUrl;\n }\n\n /**\n * Returns the value of the `Authorization` header for Basic Authentication.\n *\n * @returns The Authorization header value in the format `Basic <base64-encoded-credentials>`\n */\n getAuthorizationHeader(): string {\n return this.authorizationHeader;\n }\n\n /**\n * Returns the full set of HTTP headers required for authenticated API requests.\n *\n * @returns An object containing `Authorization`, `Content-Type`, and `Accept` headers\n */\n getHeaders(): Record<string, string> {\n return {\n Authorization: this.authorizationHeader,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n }\n}\n","import type { BitbucketPullRequest } from '../domain/PullRequest';\nimport type { BitbucketPullRequestActivity, ActivitiesParams } from '../domain/PullRequestActivity';\nimport type { BitbucketPullRequestTask, TasksParams } from '../domain/PullRequestTask';\nimport type { BitbucketCommit } from '../domain/Commit';\nimport type { BitbucketChange, ChangesParams } from '../domain/Change';\nimport type { BitbucketReport, ReportsParams } from '../domain/Report';\nimport type { BitbucketBuildSummaries } from '../domain/BuildSummary';\nimport type { BitbucketIssue } from '../domain/Issue';\nimport type { PagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn } from './ProjectResource';\n\n/**\n * Represents a Bitbucket pull request resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketPullRequest>` so it can be awaited directly\n * to fetch the pull request info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get pull request info\n * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);\n *\n * // Get activities\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n *\n * // Get tasks\n * const tasks = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).tasks();\n *\n * // Get commits\n * const commits = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).commits();\n *\n * // Get changes\n * const changes = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).changes();\n *\n * // Get reports\n * const reports = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).reports();\n *\n * // Get build summaries\n * const builds = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).buildSummaries();\n *\n * // Get linked Jira issues\n * const issues = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).issues();\n * ```\n */\nexport class PullRequestResource implements PromiseLike<BitbucketPullRequest> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n projectKey: string,\n repoSlug: string,\n pullRequestId: number,\n ) {\n this.basePath = `/projects/${projectKey}/repos/${repoSlug}/pull-requests/${pullRequestId}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the pull request info.\n * Delegates to {@link PullRequestResource.get}.\n */\n then<TResult1 = BitbucketPullRequest, TResult2 = never>(\n onfulfilled?: ((value: BitbucketPullRequest) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the pull request details.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}`\n *\n * @returns The pull request object\n */\n async get(): Promise<BitbucketPullRequest> {\n return this.request<BitbucketPullRequest>(this.basePath);\n }\n\n /**\n * Fetches the activity feed for this pull request.\n *\n * Activities include comments, approvals, reviews, rescopes, merges, and declines.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/activities`\n *\n * @param params - Optional filters: `limit`, `start`, `fromId`, `fromType`\n * @returns An array of pull request activities, ordered from most recent to oldest\n */\n async activities(params?: ActivitiesParams): Promise<PagedResponse<BitbucketPullRequestActivity>> {\n return this.request<PagedResponse<BitbucketPullRequestActivity>>(\n `${this.basePath}/activities`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the tasks (review to-do items) for this pull request.\n *\n * Tasks are created by reviewers on specific comments and can be `OPEN` or `RESOLVED`.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/tasks`\n *\n * @param params - Optional filters: `limit`, `start`\n * @returns An array of pull request tasks\n */\n async tasks(params?: TasksParams): Promise<PagedResponse<BitbucketPullRequestTask>> {\n return this.request<PagedResponse<BitbucketPullRequestTask>>(\n `${this.basePath}/tasks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the commits included in this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/commits`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns An array of commits\n */\n async commits(params?: PaginationParams): Promise<PagedResponse<BitbucketCommit>> {\n return this.request<PagedResponse<BitbucketCommit>>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the file changes included in this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/changes`\n *\n * @param params - Optional filters: `limit`, `start`, `withComments`\n * @returns An array of file changes\n */\n async changes(params?: ChangesParams): Promise<PagedResponse<BitbucketChange>> {\n return this.request<PagedResponse<BitbucketChange>>(\n `${this.basePath}/changes`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the Code Insights reports for this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/reports`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns An array of Code Insights reports\n */\n async reports(params?: ReportsParams): Promise<PagedResponse<BitbucketReport>> {\n return this.request<PagedResponse<BitbucketReport>>(\n `${this.basePath}/reports`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the aggregated build summaries for this pull request.\n *\n * Returns a map of commit hash → build counts per state\n * (`successful`, `failed`, `inProgress`, `cancelled`, `unknown`).\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/build-summaries`\n *\n * @returns A record keyed by commit SHA with aggregated build counts\n */\n async buildSummaries(): Promise<BitbucketBuildSummaries> {\n return this.request<BitbucketBuildSummaries>(`${this.basePath}/build-summaries`);\n }\n\n /**\n * Fetches the Jira issues linked to this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/issues`\n *\n * @returns An array of linked Jira issues\n */\n async issues(): Promise<BitbucketIssue[]> {\n return this.request<BitbucketIssue[]>(`${this.basePath}/issues`);\n }\n}\n","import type { BitbucketRepository } from '../domain/Repository';\nimport type { BitbucketPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { BitbucketCommit, CommitsParams } from '../domain/Commit';\nimport type { BitbucketBranch, BranchesParams } from '../domain/Branch';\nimport type { BitbucketTag, TagsParams } from '../domain/Tag';\nimport type { BitbucketRepositorySize } from '../domain/RepositorySize';\nimport type { BitbucketLastModifiedEntry, LastModifiedParams } from '../domain/LastModified';\nimport type { RawFileParams } from '../domain/RawFile';\nimport type { PagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn, RequestTextFn } from './ProjectResource';\nimport { PullRequestResource } from './PullRequestResource';\n\n/**\n * Represents a Bitbucket repository resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketRepository>` so it can be awaited directly\n * to fetch repository info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get repository info\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n *\n * // Get pull requests\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n *\n * // Navigate into a specific pull request\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n *\n * // Get commits\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * ```\n */\nexport class RepositoryResource implements PromiseLike<BitbucketRepository> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestText: RequestTextFn,\n private readonly projectKey: string,\n private readonly repoSlug: string,\n ) {\n this.basePath = `/projects/${projectKey}/repos/${repoSlug}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the repository info.\n * Delegates to {@link RepositoryResource.get}.\n */\n then<TResult1 = BitbucketRepository, TResult2 = never>(\n onfulfilled?: ((value: BitbucketRepository) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the repository details.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}`\n *\n * @returns The repository object\n */\n async get(): Promise<BitbucketRepository> {\n return this.request<BitbucketRepository>(this.basePath);\n }\n\n /**\n * Fetches pull requests for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests`\n *\n * @param params - Optional filters: `limit`, `start`, `state`, `direction`, `at`, `order`\n * @returns An array of pull requests\n */\n async pullRequests(params?: PullRequestsParams): Promise<PagedResponse<BitbucketPullRequest>> {\n return this.request<PagedResponse<BitbucketPullRequest>>(\n `${this.basePath}/pull-requests`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches commits for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/commits`\n *\n * @param params - Optional filters: `limit`, `start`, `until`, `since`, `path`, `merges`, `followRenames`, `ignoreMissing`\n * @returns An array of commits\n */\n async commits(params?: CommitsParams): Promise<PagedResponse<BitbucketCommit>> {\n return this.request<PagedResponse<BitbucketCommit>>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the files last modified in this repository along with the commit that last touched each.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/last-modified`\n *\n * @param params - Optional filters: `limit`, `start`, `at`\n * @returns An array of last-modified entries\n */\n async lastModified(params?: LastModifiedParams): Promise<PagedResponse<BitbucketLastModifiedEntry>> {\n return this.request<PagedResponse<BitbucketLastModifiedEntry>>(\n `${this.basePath}/last-modified`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the size of this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/sizes`\n *\n * @returns The repository size object\n */\n async size(): Promise<BitbucketRepositorySize> {\n return this.request<BitbucketRepositorySize>(`${this.basePath}/sizes`);\n }\n\n /**\n * Fetches branches for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/branches`\n *\n * @param params - Optional filters: `limit`, `start`, `filterText`, `orderBy`, `details`, `base`, `boostMatches`\n * @returns An array of branches\n */\n async branches(params?: BranchesParams): Promise<PagedResponse<BitbucketBranch>> {\n return this.request<PagedResponse<BitbucketBranch>>(\n `${this.basePath}/branches`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the forks of this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/forks`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns A paged response of forked repositories\n */\n async forks(params?: PaginationParams): Promise<PagedResponse<BitbucketRepository>> {\n return this.request<PagedResponse<BitbucketRepository>>(\n `${this.basePath}/forks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches tags for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/tags`\n *\n * @param params - Optional filters: `limit`, `start`, `filterText`, `orderBy`\n * @returns A paged response of tags\n */\n async tags(params?: TagsParams): Promise<PagedResponse<BitbucketTag>> {\n return this.request<PagedResponse<BitbucketTag>>(\n `${this.basePath}/tags`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link PullRequestResource} for a given pull request ID, providing\n * access to pull request data and sub-resources (activities, etc.).\n *\n * The returned resource can be awaited directly to fetch pull request info,\n * or chained to access nested resources.\n *\n * @param pullRequestId - The numeric pull request ID\n * @returns A chainable pull request resource\n *\n * @example\n * ```typescript\n * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n * ```\n */\n /**\n * Fetches the raw content of a file in this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/raw/{path}`\n *\n * @param filePath - Path to the file (e.g., `'src/index.ts'`)\n * @param params - Optional: `at` (branch, tag, or commit SHA)\n * @returns The raw file content as a string\n */\n async raw(filePath: string, params?: RawFileParams): Promise<string> {\n return this.requestText(\n `${this.basePath}/raw/${filePath}`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n pullRequest(pullRequestId: number): PullRequestResource {\n return new PullRequestResource(this.request, this.projectKey, this.repoSlug, pullRequestId);\n }\n}\n","import type { BitbucketProject } from '../domain/Project';\nimport type { BitbucketRepository, ReposParams } from '../domain/Repository';\nimport type { BitbucketUserPermission, ProjectUsersParams } from '../domain/User';\nimport type { PagedResponse } from '../domain/Pagination';\nimport { RepositoryResource } from './RepositoryResource';\n\n/** @internal */\nexport type RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<T>;\n\n/** @internal */\nexport type RequestTextFn = (\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<string>;\n\n/**\n * Represents a Bitbucket project resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketProject>` so it can be awaited directly\n * to fetch the project info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get project info\n * const project = await bbClient.project('PROJ');\n *\n * // Get repositories with filters\n * const repos = await bbClient.project('PROJ').repos({ limit: 50, name: 'api' });\n *\n * // Navigate into a specific repository\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests();\n *\n * // Get users with access to the project\n * const users = await bbClient.project('PROJ').users({ permission: 'PROJECT_WRITE' });\n * ```\n */\nexport class ProjectResource implements PromiseLike<BitbucketProject> {\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestText: RequestTextFn,\n private readonly key: string,\n ) {}\n\n /**\n * Allows the resource to be awaited directly, resolving with the project info.\n * Delegates to {@link ProjectResource.get}.\n */\n then<TResult1 = BitbucketProject, TResult2 = never>(\n onfulfilled?: ((value: BitbucketProject) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the project details.\n *\n * `GET /rest/api/latest/projects/{key}`\n *\n * @returns The project object\n */\n async get(): Promise<BitbucketProject> {\n return this.request<BitbucketProject>(`/projects/${this.key}`);\n }\n\n /**\n * Fetches repositories belonging to this project.\n *\n * `GET /rest/api/latest/projects/{key}/repos`\n *\n * @param params - Optional filters: `limit`, `start`, `slug`, `name`, `permission`\n * @returns An array of repositories\n */\n async repos(params?: ReposParams): Promise<PagedResponse<BitbucketRepository>> {\n return this.request<PagedResponse<BitbucketRepository>>(\n `/projects/${this.key}/repos`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given repository slug, providing\n * access to repository-level data and sub-resources (pull requests, commits, etc.).\n *\n * The returned resource can be awaited directly to fetch repository info,\n * or chained to access nested resources.\n *\n * @param repoSlug - The repository slug (e.g., `'my-repo'`)\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * ```\n */\n repo(repoSlug: string): RepositoryResource {\n return new RepositoryResource(this.request, this.requestText, this.key, repoSlug);\n }\n\n /**\n * Fetches users with explicit permissions on this project.\n *\n * `GET /rest/api/latest/projects/{key}/permissions/users`\n *\n * @param params - Optional filters: `limit`, `start`, `filter`, `permission`\n * @returns An array of user–permission pairs\n */\n async users(params?: ProjectUsersParams): Promise<PagedResponse<BitbucketUserPermission>> {\n return this.request<PagedResponse<BitbucketUserPermission>>(\n `/projects/${this.key}/permissions/users`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","import type { BitbucketUser } from '../domain/User';\nimport type { RequestFn } from './ProjectResource';\n\n/**\n * Represents a Bitbucket user resource.\n *\n * Implements `PromiseLike<BitbucketUser>` so it can be awaited directly\n * to fetch user info.\n *\n * @example\n * ```typescript\n * // Await directly to get user info\n * const user = await bbClient.user('pilmee');\n * ```\n */\nexport class UserResource implements PromiseLike<BitbucketUser> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n slug: string,\n ) {\n this.basePath = `/users/${slug}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the user info.\n * Delegates to {@link UserResource.get}.\n */\n then<TResult1 = BitbucketUser, TResult2 = never>(\n onfulfilled?: ((value: BitbucketUser) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the user details.\n *\n * `GET /rest/api/latest/users/{slug}`\n *\n * @returns The user object\n */\n async get(): Promise<BitbucketUser> {\n return this.request<BitbucketUser>(this.basePath);\n }\n}\n","import { Security } from './security/Security';\nimport { ProjectResource, type RequestFn, type RequestTextFn } from './resources/ProjectResource';\nimport { UserResource } from './resources/UserResource';\nimport type { BitbucketProject, ProjectsParams } from './domain/Project';\nimport type { BitbucketUser, UsersParams } from './domain/User';\nimport type { PagedResponse } from './domain/Pagination';\n\n/**\n * Constructor options for {@link BitbucketClient}.\n */\nexport interface BitbucketClientOptions {\n /** The host URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`) */\n apiUrl: string;\n /** The API path to prepend to every request (e.g., `'rest/api/latest'`) */\n apiPath: string;\n /** The username to authenticate with */\n user: string;\n /** The personal access token or password to authenticate with */\n token: string;\n}\n\n/**\n * Main entry point for the Bitbucket Data Center REST API client.\n *\n * @example\n * ```typescript\n * const bbClient = new BitbucketClient({\n * apiUrl: 'https://bitbucket.example.com',\n * apiPath: 'rest/api/latest',\n * user: 'pilmee',\n * token: 'my-token',\n * });\n *\n * const projects = await bbClient.projects({ limit: 50 });\n * const project = await bbClient.project('PROJ');\n * const repos = await bbClient.project('PROJ').repos({ name: 'api' });\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * const users = await bbClient.users({ filter: 'john' });\n * const user = await bbClient.user('pilmee');\n * ```\n */\nexport class BitbucketClient {\n private readonly security: Security;\n private readonly apiPath: string;\n\n /**\n * @param options - Connection and authentication options\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor({ apiUrl, apiPath, user, token }: BitbucketClientOptions) {\n this.security = new Security(apiUrl, user, token);\n this.apiPath = apiPath.replace(/^\\/|\\/$/g, '');\n }\n\n /**\n * Performs an authenticated GET request to the Bitbucket REST API.\n *\n * @param path - API path appended directly to `apiUrl` (e.g., `'/projects'`)\n * @param params - Optional query parameters to append to the URL\n * @throws {Error} If the HTTP response is not OK\n * @internal\n */\n private async request<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<T> {\n const base = `${this.security.getApiUrl()}/${this.apiPath}${path}`;\n const url = buildUrl(base, params);\n const response = await fetch(url, { headers: this.security.getHeaders() });\n if (!response.ok) {\n throw new Error(`Bitbucket API error: ${response.status} ${response.statusText}`);\n }\n return response.json() as Promise<T>;\n }\n\n private async requestText(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<string> {\n const base = `${this.security.getApiUrl()}/${this.apiPath}${path}`;\n const url = buildUrl(base, params);\n const response = await fetch(url, { headers: this.security.getHeaders() });\n if (!response.ok) {\n throw new Error(`Bitbucket API error: ${response.status} ${response.statusText}`);\n }\n return response.text();\n }\n\n /**\n * Fetches all projects accessible to the authenticated user.\n *\n * `GET /rest/api/latest/projects`\n *\n * @param params - Optional filters: `limit`, `start`, `name`, `permission`\n * @returns An array of projects\n */\n async projects(params?: ProjectsParams): Promise<PagedResponse<BitbucketProject>> {\n return this.request<PagedResponse<BitbucketProject>>(\n '/projects',\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link ProjectResource} for a given project key, providing access\n * to project-level data and sub-resources.\n *\n * The returned resource can be awaited directly to fetch project info,\n * or chained to access nested resources.\n *\n * @param projectKey - The project key (e.g., `'PROJ'`)\n * @returns A chainable project resource\n *\n * @example\n * ```typescript\n * const project = await bbClient.project('PROJ');\n * const repos = await bbClient.project('PROJ').repos({ limit: 10 });\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests();\n * ```\n */\n project(projectKey: string): ProjectResource {\n const request: RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ) => this.request<T>(path, params);\n const requestText: RequestTextFn = (path, params) => this.requestText(path, params);\n return new ProjectResource(request, requestText, projectKey);\n }\n\n /**\n * Fetches all users accessible to the authenticated user.\n *\n * `GET /rest/api/latest/users`\n *\n * @param params - Optional filters: `limit`, `start`, `filter`\n * @returns An array of users\n */\n async users(params?: UsersParams): Promise<PagedResponse<BitbucketUser>> {\n return this.request<PagedResponse<BitbucketUser>>(\n '/users',\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link UserResource} for a given user slug, providing access\n * to user data.\n *\n * The returned resource can be awaited directly to fetch user info.\n *\n * @param slug - The user slug (e.g., `'pilmee'`)\n * @returns A chainable user resource\n *\n * @example\n * ```typescript\n * const user = await bbClient.user('pilmee');\n * ```\n */\n user(slug: string): UserResource {\n const request: RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ) => this.request<T>(path, params);\n return new UserResource(request, slug);\n }\n}\n\n/**\n * Appends query parameters to a URL string, skipping `undefined` values.\n * @internal\n */\nfunction buildUrl(base: string, params?: Record<string, string | number | boolean>): string {\n if (!params) return base;\n const entries = Object.entries(params).filter(([, v]) => v !== undefined);\n if (entries.length === 0) return base;\n const search = new URLSearchParams(entries.map(([k, v]) => [k, String(v)]));\n return `${base}?${search.toString()}`;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/security/Security.ts","../src/resources/PullRequestResource.ts","../src/resources/RepositoryResource.ts","../src/resources/ProjectResource.ts","../src/errors/BitbucketApiError.ts","../src/resources/UserResource.ts","../src/BitbucketClient.ts"],"sourcesContent":["/**\n * Encodes a string to Base64 in a way that works in both Node.js and browsers.\n * @internal\n */\nfunction toBase64(value: string): string {\n if (typeof btoa !== 'undefined') {\n return btoa(value);\n }\n return Buffer.from(value).toString('base64');\n}\n\n/**\n * Handles Basic Authentication for Bitbucket Data Center REST API requests.\n *\n * @example\n * ```typescript\n * const security = new Security(\n * 'https://bitbucket.example.com',\n * 'my-user',\n * 'my-token'\n * );\n *\n * const headers = security.getHeaders();\n * // { Authorization: 'Basic <base64>', 'Content-Type': 'application/json', Accept: 'application/json' }\n * ```\n */\nexport class Security {\n private readonly apiUrl: string;\n private readonly authorizationHeader: string;\n\n /**\n * Creates a new Security instance with Basic Authentication credentials.\n *\n * @param apiUrl - The base URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`).\n * Must be a valid URL; throws if it cannot be parsed.\n * @param user - The username to authenticate with\n * @param token - The personal access token or password to authenticate with\n *\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor(apiUrl: string, user: string, token: string) {\n if (!URL.canParse(apiUrl)) {\n throw new TypeError(`Invalid apiUrl: \"${apiUrl}\" is not a valid URL`);\n }\n this.apiUrl = apiUrl.replace(/\\/$/, '');\n this.authorizationHeader = `Basic ${toBase64(`${user}:${token}`)}`;\n }\n\n /**\n * Returns the base URL of the Bitbucket Data Center instance, without a trailing slash.\n *\n * @returns The API base URL\n */\n getApiUrl(): string {\n return this.apiUrl;\n }\n\n /**\n * Returns the value of the `Authorization` header for Basic Authentication.\n *\n * @returns The Authorization header value in the format `Basic <base64-encoded-credentials>`\n */\n getAuthorizationHeader(): string {\n return this.authorizationHeader;\n }\n\n /**\n * Returns the full set of HTTP headers required for authenticated API requests.\n *\n * @returns An object containing `Authorization`, `Content-Type`, and `Accept` headers\n */\n getHeaders(): Record<string, string> {\n return {\n Authorization: this.authorizationHeader,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n }\n}\n","import type { BitbucketPullRequest } from '../domain/PullRequest';\nimport type { BitbucketPullRequestActivity, ActivitiesParams } from '../domain/PullRequestActivity';\nimport type { BitbucketPullRequestTask, TasksParams } from '../domain/PullRequestTask';\nimport type { BitbucketCommit } from '../domain/Commit';\nimport type { BitbucketChange, ChangesParams } from '../domain/Change';\nimport type { BitbucketReport, ReportsParams } from '../domain/Report';\nimport type { BitbucketBuildSummaries } from '../domain/BuildSummary';\nimport type { BitbucketIssue } from '../domain/Issue';\nimport type { PagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn } from './ProjectResource';\n\n/**\n * Represents a Bitbucket pull request resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketPullRequest>` so it can be awaited directly\n * to fetch the pull request info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get pull request info\n * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);\n *\n * // Get activities\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n *\n * // Get tasks\n * const tasks = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).tasks();\n *\n * // Get commits\n * const commits = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).commits();\n *\n * // Get changes\n * const changes = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).changes();\n *\n * // Get reports\n * const reports = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).reports();\n *\n * // Get build summaries\n * const builds = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).buildSummaries();\n *\n * // Get linked Jira issues\n * const issues = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).issues();\n * ```\n */\nexport class PullRequestResource implements PromiseLike<BitbucketPullRequest> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n projectKey: string,\n repoSlug: string,\n pullRequestId: number,\n ) {\n this.basePath = `/projects/${projectKey}/repos/${repoSlug}/pull-requests/${pullRequestId}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the pull request info.\n * Delegates to {@link PullRequestResource.get}.\n */\n then<TResult1 = BitbucketPullRequest, TResult2 = never>(\n onfulfilled?: ((value: BitbucketPullRequest) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the pull request details.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}`\n *\n * @returns The pull request object\n */\n async get(): Promise<BitbucketPullRequest> {\n return this.request<BitbucketPullRequest>(this.basePath);\n }\n\n /**\n * Fetches the activity feed for this pull request.\n *\n * Activities include comments, approvals, reviews, rescopes, merges, and declines.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/activities`\n *\n * @param params - Optional filters: `limit`, `start`, `fromId`, `fromType`\n * @returns An array of pull request activities, ordered from most recent to oldest\n */\n async activities(params?: ActivitiesParams): Promise<PagedResponse<BitbucketPullRequestActivity>> {\n return this.request<PagedResponse<BitbucketPullRequestActivity>>(\n `${this.basePath}/activities`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the tasks (review to-do items) for this pull request.\n *\n * Tasks are created by reviewers on specific comments and can be `OPEN` or `RESOLVED`.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/tasks`\n *\n * @param params - Optional filters: `limit`, `start`\n * @returns An array of pull request tasks\n */\n async tasks(params?: TasksParams): Promise<PagedResponse<BitbucketPullRequestTask>> {\n return this.request<PagedResponse<BitbucketPullRequestTask>>(\n `${this.basePath}/tasks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the commits included in this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/commits`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns An array of commits\n */\n async commits(params?: PaginationParams): Promise<PagedResponse<BitbucketCommit>> {\n return this.request<PagedResponse<BitbucketCommit>>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the file changes included in this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/changes`\n *\n * @param params - Optional filters: `limit`, `start`, `withComments`\n * @returns An array of file changes\n */\n async changes(params?: ChangesParams): Promise<PagedResponse<BitbucketChange>> {\n return this.request<PagedResponse<BitbucketChange>>(\n `${this.basePath}/changes`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the Code Insights reports for this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/reports`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns An array of Code Insights reports\n */\n async reports(params?: ReportsParams): Promise<PagedResponse<BitbucketReport>> {\n return this.request<PagedResponse<BitbucketReport>>(\n `${this.basePath}/reports`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the aggregated build summaries for this pull request.\n *\n * Returns a map of commit hash → build counts per state\n * (`successful`, `failed`, `inProgress`, `cancelled`, `unknown`).\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/build-summaries`\n *\n * @returns A record keyed by commit SHA with aggregated build counts\n */\n async buildSummaries(): Promise<BitbucketBuildSummaries> {\n return this.request<BitbucketBuildSummaries>(`${this.basePath}/build-summaries`);\n }\n\n /**\n * Fetches the Jira issues linked to this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/issues`\n *\n * @returns An array of linked Jira issues\n */\n async issues(): Promise<BitbucketIssue[]> {\n return this.request<BitbucketIssue[]>(`${this.basePath}/issues`);\n }\n}\n","import type { BitbucketRepository } from '../domain/Repository';\nimport type { BitbucketPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { BitbucketCommit, CommitsParams } from '../domain/Commit';\nimport type { BitbucketBranch, BranchesParams } from '../domain/Branch';\nimport type { BitbucketTag, TagsParams } from '../domain/Tag';\nimport type { BitbucketRepositorySize } from '../domain/RepositorySize';\nimport type { BitbucketLastModifiedEntry, LastModifiedParams } from '../domain/LastModified';\nimport type { RawFileParams } from '../domain/RawFile';\nimport type { PagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn, RequestTextFn } from './ProjectResource';\nimport { PullRequestResource } from './PullRequestResource';\n\n/**\n * Represents a Bitbucket repository resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketRepository>` so it can be awaited directly\n * to fetch repository info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get repository info\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n *\n * // Get pull requests\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n *\n * // Navigate into a specific pull request\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n *\n * // Get commits\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * ```\n */\nexport class RepositoryResource implements PromiseLike<BitbucketRepository> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestText: RequestTextFn,\n private readonly projectKey: string,\n private readonly repoSlug: string,\n ) {\n this.basePath = `/projects/${projectKey}/repos/${repoSlug}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the repository info.\n * Delegates to {@link RepositoryResource.get}.\n */\n then<TResult1 = BitbucketRepository, TResult2 = never>(\n onfulfilled?: ((value: BitbucketRepository) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the repository details.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}`\n *\n * @returns The repository object\n */\n async get(): Promise<BitbucketRepository> {\n return this.request<BitbucketRepository>(this.basePath);\n }\n\n /**\n * Fetches pull requests for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests`\n *\n * @param params - Optional filters: `limit`, `start`, `state`, `direction`, `at`, `order`\n * @returns An array of pull requests\n */\n async pullRequests(params?: PullRequestsParams): Promise<PagedResponse<BitbucketPullRequest>> {\n return this.request<PagedResponse<BitbucketPullRequest>>(\n `${this.basePath}/pull-requests`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches commits for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/commits`\n *\n * @param params - Optional filters: `limit`, `start`, `until`, `since`, `path`, `merges`, `followRenames`, `ignoreMissing`\n * @returns An array of commits\n */\n async commits(params?: CommitsParams): Promise<PagedResponse<BitbucketCommit>> {\n return this.request<PagedResponse<BitbucketCommit>>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the files last modified in this repository along with the commit that last touched each.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/last-modified`\n *\n * @param params - Optional filters: `limit`, `start`, `at`\n * @returns An array of last-modified entries\n */\n async lastModified(params?: LastModifiedParams): Promise<PagedResponse<BitbucketLastModifiedEntry>> {\n return this.request<PagedResponse<BitbucketLastModifiedEntry>>(\n `${this.basePath}/last-modified`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the size of this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/sizes`\n *\n * @returns The repository size object\n */\n async size(): Promise<BitbucketRepositorySize> {\n return this.request<BitbucketRepositorySize>(`${this.basePath}/sizes`);\n }\n\n /**\n * Fetches branches for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/branches`\n *\n * @param params - Optional filters: `limit`, `start`, `filterText`, `orderBy`, `details`, `base`, `boostMatches`\n * @returns An array of branches\n */\n async branches(params?: BranchesParams): Promise<PagedResponse<BitbucketBranch>> {\n return this.request<PagedResponse<BitbucketBranch>>(\n `${this.basePath}/branches`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches the forks of this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/forks`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns A paged response of forked repositories\n */\n async forks(params?: PaginationParams): Promise<PagedResponse<BitbucketRepository>> {\n return this.request<PagedResponse<BitbucketRepository>>(\n `${this.basePath}/forks`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Fetches tags for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/tags`\n *\n * @param params - Optional filters: `limit`, `start`, `filterText`, `orderBy`\n * @returns A paged response of tags\n */\n async tags(params?: TagsParams): Promise<PagedResponse<BitbucketTag>> {\n return this.request<PagedResponse<BitbucketTag>>(\n `${this.basePath}/tags`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link PullRequestResource} for a given pull request ID, providing\n * access to pull request data and sub-resources (activities, etc.).\n *\n * The returned resource can be awaited directly to fetch pull request info,\n * or chained to access nested resources.\n *\n * @param pullRequestId - The numeric pull request ID\n * @returns A chainable pull request resource\n *\n * @example\n * ```typescript\n * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n * ```\n */\n /**\n * Fetches the raw content of a file in this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/raw/{path}`\n *\n * @param filePath - Path to the file (e.g., `'src/index.ts'`)\n * @param params - Optional: `at` (branch, tag, or commit SHA)\n * @returns The raw file content as a string\n */\n async raw(filePath: string, params?: RawFileParams): Promise<string> {\n return this.requestText(\n `${this.basePath}/raw/${filePath}`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n pullRequest(pullRequestId: number): PullRequestResource {\n return new PullRequestResource(this.request, this.projectKey, this.repoSlug, pullRequestId);\n }\n}\n","import type { BitbucketProject } from '../domain/Project';\nimport type { BitbucketRepository, ReposParams } from '../domain/Repository';\nimport type { BitbucketUserPermission, ProjectUsersParams } from '../domain/User';\nimport type { PagedResponse } from '../domain/Pagination';\nimport { RepositoryResource } from './RepositoryResource';\n\n/** @internal */\nexport type RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<T>;\n\n/** @internal */\nexport type RequestTextFn = (\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<string>;\n\n/**\n * Represents a Bitbucket project resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketProject>` so it can be awaited directly\n * to fetch the project info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get project info\n * const project = await bbClient.project('PROJ');\n *\n * // Get repositories with filters\n * const repos = await bbClient.project('PROJ').repos({ limit: 50, name: 'api' });\n *\n * // Navigate into a specific repository\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests();\n *\n * // Get users with access to the project\n * const users = await bbClient.project('PROJ').users({ permission: 'PROJECT_WRITE' });\n * ```\n */\nexport class ProjectResource implements PromiseLike<BitbucketProject> {\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestText: RequestTextFn,\n private readonly key: string,\n ) {}\n\n /**\n * Allows the resource to be awaited directly, resolving with the project info.\n * Delegates to {@link ProjectResource.get}.\n */\n then<TResult1 = BitbucketProject, TResult2 = never>(\n onfulfilled?: ((value: BitbucketProject) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the project details.\n *\n * `GET /rest/api/latest/projects/{key}`\n *\n * @returns The project object\n */\n async get(): Promise<BitbucketProject> {\n return this.request<BitbucketProject>(`/projects/${this.key}`);\n }\n\n /**\n * Fetches repositories belonging to this project.\n *\n * `GET /rest/api/latest/projects/{key}/repos`\n *\n * @param params - Optional filters: `limit`, `start`, `slug`, `name`, `permission`\n * @returns An array of repositories\n */\n async repos(params?: ReposParams): Promise<PagedResponse<BitbucketRepository>> {\n return this.request<PagedResponse<BitbucketRepository>>(\n `/projects/${this.key}/repos`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link RepositoryResource} for a given repository slug, providing\n * access to repository-level data and sub-resources (pull requests, commits, etc.).\n *\n * The returned resource can be awaited directly to fetch repository info,\n * or chained to access nested resources.\n *\n * @param repoSlug - The repository slug (e.g., `'my-repo'`)\n * @returns A chainable repository resource\n *\n * @example\n * ```typescript\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * ```\n */\n repo(repoSlug: string): RepositoryResource {\n return new RepositoryResource(this.request, this.requestText, this.key, repoSlug);\n }\n\n /**\n * Fetches users with explicit permissions on this project.\n *\n * `GET /rest/api/latest/projects/{key}/permissions/users`\n *\n * @param params - Optional filters: `limit`, `start`, `filter`, `permission`\n * @returns An array of user–permission pairs\n */\n async users(params?: ProjectUsersParams): Promise<PagedResponse<BitbucketUserPermission>> {\n return this.request<PagedResponse<BitbucketUserPermission>>(\n `/projects/${this.key}/permissions/users`,\n params as Record<string, string | number | boolean>,\n );\n }\n}\n","/**\n * Thrown when the Bitbucket Data Center API returns a non-2xx response.\n *\n * @example\n * ```typescript\n * import { BitbucketApiError } from 'bitbucket-datacenter-api-client';\n *\n * try {\n * await bb.project('NONEXISTENT');\n * } catch (err) {\n * if (err instanceof BitbucketApiError) {\n * console.log(err.status); // 404\n * console.log(err.statusText); // 'Not Found'\n * console.log(err.message); // 'Bitbucket API error: 404 Not Found'\n * }\n * }\n * ```\n */\nexport class BitbucketApiError extends Error {\n /** HTTP status code (e.g. `404`, `401`, `403`) */\n readonly status: number;\n /** HTTP status text (e.g. `'Not Found'`, `'Unauthorized'`) */\n readonly statusText: string;\n\n constructor(status: number, statusText: string) {\n super(`Bitbucket API error: ${status} ${statusText}`);\n this.name = 'BitbucketApiError';\n this.status = status;\n this.statusText = statusText;\n }\n}\n","import type { BitbucketUser } from '../domain/User';\nimport type { RequestFn } from './ProjectResource';\n\n/**\n * Represents a Bitbucket user resource.\n *\n * Implements `PromiseLike<BitbucketUser>` so it can be awaited directly\n * to fetch user info.\n *\n * @example\n * ```typescript\n * // Await directly to get user info\n * const user = await bbClient.user('pilmee');\n * ```\n */\nexport class UserResource implements PromiseLike<BitbucketUser> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n slug: string,\n ) {\n this.basePath = `/users/${slug}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the user info.\n * Delegates to {@link UserResource.get}.\n */\n then<TResult1 = BitbucketUser, TResult2 = never>(\n onfulfilled?: ((value: BitbucketUser) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the user details.\n *\n * `GET /rest/api/latest/users/{slug}`\n *\n * @returns The user object\n */\n async get(): Promise<BitbucketUser> {\n return this.request<BitbucketUser>(this.basePath);\n }\n}\n","import { Security } from './security/Security';\nimport { ProjectResource, type RequestFn, type RequestTextFn } from './resources/ProjectResource';\nimport { BitbucketApiError } from './errors/BitbucketApiError';\nimport { UserResource } from './resources/UserResource';\nimport type { BitbucketProject, ProjectsParams } from './domain/Project';\nimport type { BitbucketUser, UsersParams } from './domain/User';\nimport type { PagedResponse } from './domain/Pagination';\n\n/**\n * Constructor options for {@link BitbucketClient}.\n */\nexport interface BitbucketClientOptions {\n /** The host URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`) */\n apiUrl: string;\n /** The API path to prepend to every request (e.g., `'rest/api/latest'`) */\n apiPath: string;\n /** The username to authenticate with */\n user: string;\n /** The personal access token or password to authenticate with */\n token: string;\n}\n\n/**\n * Main entry point for the Bitbucket Data Center REST API client.\n *\n * @example\n * ```typescript\n * const bbClient = new BitbucketClient({\n * apiUrl: 'https://bitbucket.example.com',\n * apiPath: 'rest/api/latest',\n * user: 'pilmee',\n * token: 'my-token',\n * });\n *\n * const projects = await bbClient.projects({ limit: 50 });\n * const project = await bbClient.project('PROJ');\n * const repos = await bbClient.project('PROJ').repos({ name: 'api' });\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * const users = await bbClient.users({ filter: 'john' });\n * const user = await bbClient.user('pilmee');\n * ```\n */\nexport class BitbucketClient {\n private readonly security: Security;\n private readonly apiPath: string;\n\n /**\n * @param options - Connection and authentication options\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor({ apiUrl, apiPath, user, token }: BitbucketClientOptions) {\n this.security = new Security(apiUrl, user, token);\n this.apiPath = apiPath.replace(/^\\/|\\/$/g, '');\n }\n\n /**\n * Performs an authenticated GET request to the Bitbucket REST API.\n *\n * @param path - API path appended directly to `apiUrl` (e.g., `'/projects'`)\n * @param params - Optional query parameters to append to the URL\n * @throws {Error} If the HTTP response is not OK\n * @internal\n */\n private async request<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<T> {\n const base = `${this.security.getApiUrl()}/${this.apiPath}${path}`;\n const url = buildUrl(base, params);\n const response = await fetch(url, { headers: this.security.getHeaders() });\n if (!response.ok) {\n throw new BitbucketApiError(response.status, response.statusText);\n }\n return response.json() as Promise<T>;\n }\n\n private async requestText(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<string> {\n const base = `${this.security.getApiUrl()}/${this.apiPath}${path}`;\n const url = buildUrl(base, params);\n const response = await fetch(url, { headers: this.security.getHeaders() });\n if (!response.ok) {\n throw new BitbucketApiError(response.status, response.statusText);\n }\n return response.text();\n }\n\n /**\n * Fetches all projects accessible to the authenticated user.\n *\n * `GET /rest/api/latest/projects`\n *\n * @param params - Optional filters: `limit`, `start`, `name`, `permission`\n * @returns An array of projects\n */\n async projects(params?: ProjectsParams): Promise<PagedResponse<BitbucketProject>> {\n return this.request<PagedResponse<BitbucketProject>>(\n '/projects',\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link ProjectResource} for a given project key, providing access\n * to project-level data and sub-resources.\n *\n * The returned resource can be awaited directly to fetch project info,\n * or chained to access nested resources.\n *\n * @param projectKey - The project key (e.g., `'PROJ'`)\n * @returns A chainable project resource\n *\n * @example\n * ```typescript\n * const project = await bbClient.project('PROJ');\n * const repos = await bbClient.project('PROJ').repos({ limit: 10 });\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests();\n * ```\n */\n project(projectKey: string): ProjectResource {\n const request: RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ) => this.request<T>(path, params);\n const requestText: RequestTextFn = (path, params) => this.requestText(path, params);\n return new ProjectResource(request, requestText, projectKey);\n }\n\n /**\n * Fetches all users accessible to the authenticated user.\n *\n * `GET /rest/api/latest/users`\n *\n * @param params - Optional filters: `limit`, `start`, `filter`\n * @returns An array of users\n */\n async users(params?: UsersParams): Promise<PagedResponse<BitbucketUser>> {\n return this.request<PagedResponse<BitbucketUser>>(\n '/users',\n params as Record<string, string | number | boolean>,\n );\n }\n\n /**\n * Returns a {@link UserResource} for a given user slug, providing access\n * to user data.\n *\n * The returned resource can be awaited directly to fetch user info.\n *\n * @param slug - The user slug (e.g., `'pilmee'`)\n * @returns A chainable user resource\n *\n * @example\n * ```typescript\n * const user = await bbClient.user('pilmee');\n * ```\n */\n user(slug: string): UserResource {\n const request: RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ) => this.request<T>(path, params);\n return new UserResource(request, slug);\n }\n}\n\n/**\n * Appends query parameters to a URL string, skipping `undefined` values.\n * @internal\n */\nfunction buildUrl(base: string, params?: Record<string, string | number | boolean>): string {\n if (!params) return base;\n const entries = Object.entries(params).filter(([, v]) => v !== undefined);\n if (entries.length === 0) return base;\n const search = new URLSearchParams(entries.map(([k, v]) => [k, String(v)]));\n return `${base}?${search.toString()}`;\n}\n"],"mappings":"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","names":[]}
|