bitbucket-datacenter-api-client 1.0.0 → 1.1.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 CHANGED
@@ -205,6 +205,141 @@ interface CommitsParams extends PaginationParams {
205
205
  ignoreMissing?: boolean;
206
206
  }
207
207
 
208
+ /** Minimal user shape used inside activity records. */
209
+ interface BitbucketActivityUser {
210
+ name: string;
211
+ emailAddress: string;
212
+ id: number;
213
+ displayName: string;
214
+ active: boolean;
215
+ slug: string;
216
+ type: string;
217
+ }
218
+ /** A comment posted on a pull request. */
219
+ interface BitbucketPullRequestComment {
220
+ id: number;
221
+ version: number;
222
+ text: string;
223
+ author: BitbucketActivityUser;
224
+ createdDate: number;
225
+ updatedDate: number;
226
+ comments: BitbucketPullRequestComment[];
227
+ tasks: unknown[];
228
+ links: Record<string, unknown>;
229
+ }
230
+ /**
231
+ * All possible action types for a pull request activity.
232
+ *
233
+ * - `OPENED` — PR was opened
234
+ * - `APPROVED` — a reviewer approved
235
+ * - `UNAPPROVED` — a reviewer removed their approval
236
+ * - `NEEDS_WORK` — a reviewer requested changes
237
+ * - `COMMENTED` — a comment was posted
238
+ * - `RESCOPED` — commits were added or removed from the PR
239
+ * - `MERGED` — PR was merged
240
+ * - `DECLINED` — PR was declined
241
+ * - `REVIEWED` — PR was reviewed without an explicit vote
242
+ */
243
+ type PullRequestActivityAction = 'OPENED' | 'APPROVED' | 'UNAPPROVED' | 'NEEDS_WORK' | 'COMMENTED' | 'RESCOPED' | 'MERGED' | 'DECLINED' | 'REVIEWED';
244
+ /**
245
+ * Represents a single activity entry on a Bitbucket Data Center pull request.
246
+ *
247
+ * The optional fields are populated depending on `action`:
248
+ * - `COMMENTED` → `comment` is present
249
+ * - `RESCOPED` → `addedCommits`, `removedCommits`, `fromHash`, `toHash`, etc. are present
250
+ * - `APPROVED` / `UNAPPROVED` / `NEEDS_WORK` → `participant` is present
251
+ */
252
+ interface BitbucketPullRequestActivity {
253
+ id: number;
254
+ createdDate: number;
255
+ user: BitbucketActivityUser;
256
+ action: PullRequestActivityAction;
257
+ /** Present when `action` is `'COMMENTED'` */
258
+ comment?: BitbucketPullRequestComment;
259
+ /** Present when `action` is `'APPROVED'`, `'UNAPPROVED'`, or `'NEEDS_WORK'` */
260
+ participant?: BitbucketParticipant;
261
+ /** Present when `action` is `'RESCOPED'` — commits added to the PR */
262
+ addedCommits?: BitbucketCommit[];
263
+ /** Present when `action` is `'RESCOPED'` — commits removed from the PR */
264
+ removedCommits?: BitbucketCommit[];
265
+ fromHash?: string;
266
+ previousFromHash?: string;
267
+ previousToHash?: string;
268
+ toHash?: string;
269
+ }
270
+ /**
271
+ * Query parameters accepted by
272
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/activities`.
273
+ *
274
+ * @see {@link https://developer.atlassian.com/server/bitbucket/rest/v819/api-group-pull-requests/#api-api-latest-projects-projectkey-repos-repositoryslug-pull-requests-pullrequestid-activities-get}
275
+ */
276
+ interface ActivitiesParams extends PaginationParams {
277
+ /**
278
+ * Filter the results to contain only activities with the supplied `id`
279
+ * as the anchor, starting from the supplied activity.
280
+ */
281
+ fromId?: number;
282
+ /**
283
+ * When `fromId` is set, filter by activity type:
284
+ * - `'COMMENT'` — start from a comment
285
+ * - `'ACTIVITY'` — start from a generic activity
286
+ */
287
+ fromType?: 'COMMENT' | 'ACTIVITY';
288
+ }
289
+
290
+ /**
291
+ * Represents a Bitbucket pull request resource with chainable async methods.
292
+ *
293
+ * Implements `PromiseLike<BitbucketPullRequest>` so it can be awaited directly
294
+ * to fetch the pull request info, while also exposing sub-resource methods.
295
+ *
296
+ * @example
297
+ * ```typescript
298
+ * // Await directly to get pull request info
299
+ * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);
300
+ *
301
+ * // Get activities
302
+ * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();
303
+ *
304
+ * // With filters
305
+ * const comments = await bbClient
306
+ * .project('PROJ')
307
+ * .repo('my-repo')
308
+ * .pullRequest(42)
309
+ * .activities({ fromId: 10, fromType: 'COMMENT' });
310
+ * ```
311
+ */
312
+ declare class PullRequestResource implements PromiseLike<BitbucketPullRequest> {
313
+ private readonly request;
314
+ private readonly basePath;
315
+ /** @internal */
316
+ constructor(request: RequestFn, projectKey: string, repoSlug: string, pullRequestId: number);
317
+ /**
318
+ * Allows the resource to be awaited directly, resolving with the pull request info.
319
+ * Delegates to {@link PullRequestResource.get}.
320
+ */
321
+ then<TResult1 = BitbucketPullRequest, TResult2 = never>(onfulfilled?: ((value: BitbucketPullRequest) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): PromiseLike<TResult1 | TResult2>;
322
+ /**
323
+ * Fetches the pull request details.
324
+ *
325
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}`
326
+ *
327
+ * @returns The pull request object
328
+ */
329
+ get(): Promise<BitbucketPullRequest>;
330
+ /**
331
+ * Fetches the activity feed for this pull request.
332
+ *
333
+ * Activities include comments, approvals, reviews, rescopes, merges, and declines.
334
+ *
335
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/activities`
336
+ *
337
+ * @param params - Optional filters: `limit`, `start`, `fromId`, `fromType`
338
+ * @returns An array of pull request activities, ordered from most recent to oldest
339
+ */
340
+ activities(params?: ActivitiesParams): Promise<BitbucketPullRequestActivity[]>;
341
+ }
342
+
208
343
  /**
209
344
  * Represents a Bitbucket repository resource with chainable async methods.
210
345
  *
@@ -219,12 +354,17 @@ interface CommitsParams extends PaginationParams {
219
354
  * // Get pull requests
220
355
  * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });
221
356
  *
357
+ * // Navigate into a specific pull request
358
+ * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();
359
+ *
222
360
  * // Get commits
223
361
  * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });
224
362
  * ```
225
363
  */
226
364
  declare class RepositoryResource implements PromiseLike<BitbucketRepository> {
227
365
  private readonly request;
366
+ private readonly projectKey;
367
+ private readonly repoSlug;
228
368
  private readonly basePath;
229
369
  /** @internal */
230
370
  constructor(request: RequestFn, projectKey: string, repoSlug: string);
@@ -259,6 +399,23 @@ declare class RepositoryResource implements PromiseLike<BitbucketRepository> {
259
399
  * @returns An array of commits
260
400
  */
261
401
  commits(params?: CommitsParams): Promise<BitbucketCommit[]>;
402
+ /**
403
+ * Returns a {@link PullRequestResource} for a given pull request ID, providing
404
+ * access to pull request data and sub-resources (activities, etc.).
405
+ *
406
+ * The returned resource can be awaited directly to fetch pull request info,
407
+ * or chained to access nested resources.
408
+ *
409
+ * @param pullRequestId - The numeric pull request ID
410
+ * @returns A chainable pull request resource
411
+ *
412
+ * @example
413
+ * ```typescript
414
+ * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);
415
+ * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();
416
+ * ```
417
+ */
418
+ pullRequest(pullRequestId: number): PullRequestResource;
262
419
  }
263
420
 
264
421
  /** @internal */
@@ -345,7 +502,7 @@ interface BitbucketClientOptions {
345
502
  * @example
346
503
  * ```typescript
347
504
  * const bbClient = new BitbucketClient({
348
- * apiUrl: 'https://bitbucket.example.com',
505
+ * apiUrl: 'https://bitbucket.example.com/rest/api/latest',
349
506
  * user: 'john.doe',
350
507
  * token: 'my-token',
351
508
  * });
@@ -368,7 +525,7 @@ declare class BitbucketClient {
368
525
  /**
369
526
  * Performs an authenticated GET request to the Bitbucket REST API.
370
527
  *
371
- * @param path - API path relative to `/rest/api/latest` (e.g., `'/projects'`)
528
+ * @param path - API path appended directly to `apiUrl` (e.g., `'/projects'`)
372
529
  * @param params - Optional query parameters to append to the URL
373
530
  * @throws {Error} If the HTTP response is not OK
374
531
  * @internal
@@ -452,4 +609,4 @@ declare class Security {
452
609
  getHeaders(): Record<string, string>;
453
610
  }
454
611
 
455
- export { BitbucketClient, type BitbucketClientOptions, type BitbucketCommit, type BitbucketCommitAuthor, type BitbucketParticipant, type BitbucketProject, type BitbucketPullRequest, type BitbucketRef, type BitbucketRepository, type CommitsParams, type PagedResponse, type PaginationParams, ProjectResource, type ProjectsParams, type PullRequestsParams, type ReposParams, RepositoryResource, Security };
612
+ export { type ActivitiesParams, type BitbucketActivityUser, BitbucketClient, type BitbucketClientOptions, type BitbucketCommit, type BitbucketCommitAuthor, type BitbucketParticipant, type BitbucketProject, type BitbucketPullRequest, type BitbucketPullRequestActivity, type BitbucketPullRequestComment, type BitbucketRef, type BitbucketRepository, type CommitsParams, type PagedResponse, type PaginationParams, ProjectResource, type ProjectsParams, type PullRequestActivityAction, PullRequestResource, type PullRequestsParams, type ReposParams, RepositoryResource, Security };
package/dist/index.d.ts CHANGED
@@ -205,6 +205,141 @@ interface CommitsParams extends PaginationParams {
205
205
  ignoreMissing?: boolean;
206
206
  }
207
207
 
208
+ /** Minimal user shape used inside activity records. */
209
+ interface BitbucketActivityUser {
210
+ name: string;
211
+ emailAddress: string;
212
+ id: number;
213
+ displayName: string;
214
+ active: boolean;
215
+ slug: string;
216
+ type: string;
217
+ }
218
+ /** A comment posted on a pull request. */
219
+ interface BitbucketPullRequestComment {
220
+ id: number;
221
+ version: number;
222
+ text: string;
223
+ author: BitbucketActivityUser;
224
+ createdDate: number;
225
+ updatedDate: number;
226
+ comments: BitbucketPullRequestComment[];
227
+ tasks: unknown[];
228
+ links: Record<string, unknown>;
229
+ }
230
+ /**
231
+ * All possible action types for a pull request activity.
232
+ *
233
+ * - `OPENED` — PR was opened
234
+ * - `APPROVED` — a reviewer approved
235
+ * - `UNAPPROVED` — a reviewer removed their approval
236
+ * - `NEEDS_WORK` — a reviewer requested changes
237
+ * - `COMMENTED` — a comment was posted
238
+ * - `RESCOPED` — commits were added or removed from the PR
239
+ * - `MERGED` — PR was merged
240
+ * - `DECLINED` — PR was declined
241
+ * - `REVIEWED` — PR was reviewed without an explicit vote
242
+ */
243
+ type PullRequestActivityAction = 'OPENED' | 'APPROVED' | 'UNAPPROVED' | 'NEEDS_WORK' | 'COMMENTED' | 'RESCOPED' | 'MERGED' | 'DECLINED' | 'REVIEWED';
244
+ /**
245
+ * Represents a single activity entry on a Bitbucket Data Center pull request.
246
+ *
247
+ * The optional fields are populated depending on `action`:
248
+ * - `COMMENTED` → `comment` is present
249
+ * - `RESCOPED` → `addedCommits`, `removedCommits`, `fromHash`, `toHash`, etc. are present
250
+ * - `APPROVED` / `UNAPPROVED` / `NEEDS_WORK` → `participant` is present
251
+ */
252
+ interface BitbucketPullRequestActivity {
253
+ id: number;
254
+ createdDate: number;
255
+ user: BitbucketActivityUser;
256
+ action: PullRequestActivityAction;
257
+ /** Present when `action` is `'COMMENTED'` */
258
+ comment?: BitbucketPullRequestComment;
259
+ /** Present when `action` is `'APPROVED'`, `'UNAPPROVED'`, or `'NEEDS_WORK'` */
260
+ participant?: BitbucketParticipant;
261
+ /** Present when `action` is `'RESCOPED'` — commits added to the PR */
262
+ addedCommits?: BitbucketCommit[];
263
+ /** Present when `action` is `'RESCOPED'` — commits removed from the PR */
264
+ removedCommits?: BitbucketCommit[];
265
+ fromHash?: string;
266
+ previousFromHash?: string;
267
+ previousToHash?: string;
268
+ toHash?: string;
269
+ }
270
+ /**
271
+ * Query parameters accepted by
272
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/activities`.
273
+ *
274
+ * @see {@link https://developer.atlassian.com/server/bitbucket/rest/v819/api-group-pull-requests/#api-api-latest-projects-projectkey-repos-repositoryslug-pull-requests-pullrequestid-activities-get}
275
+ */
276
+ interface ActivitiesParams extends PaginationParams {
277
+ /**
278
+ * Filter the results to contain only activities with the supplied `id`
279
+ * as the anchor, starting from the supplied activity.
280
+ */
281
+ fromId?: number;
282
+ /**
283
+ * When `fromId` is set, filter by activity type:
284
+ * - `'COMMENT'` — start from a comment
285
+ * - `'ACTIVITY'` — start from a generic activity
286
+ */
287
+ fromType?: 'COMMENT' | 'ACTIVITY';
288
+ }
289
+
290
+ /**
291
+ * Represents a Bitbucket pull request resource with chainable async methods.
292
+ *
293
+ * Implements `PromiseLike<BitbucketPullRequest>` so it can be awaited directly
294
+ * to fetch the pull request info, while also exposing sub-resource methods.
295
+ *
296
+ * @example
297
+ * ```typescript
298
+ * // Await directly to get pull request info
299
+ * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);
300
+ *
301
+ * // Get activities
302
+ * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();
303
+ *
304
+ * // With filters
305
+ * const comments = await bbClient
306
+ * .project('PROJ')
307
+ * .repo('my-repo')
308
+ * .pullRequest(42)
309
+ * .activities({ fromId: 10, fromType: 'COMMENT' });
310
+ * ```
311
+ */
312
+ declare class PullRequestResource implements PromiseLike<BitbucketPullRequest> {
313
+ private readonly request;
314
+ private readonly basePath;
315
+ /** @internal */
316
+ constructor(request: RequestFn, projectKey: string, repoSlug: string, pullRequestId: number);
317
+ /**
318
+ * Allows the resource to be awaited directly, resolving with the pull request info.
319
+ * Delegates to {@link PullRequestResource.get}.
320
+ */
321
+ then<TResult1 = BitbucketPullRequest, TResult2 = never>(onfulfilled?: ((value: BitbucketPullRequest) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): PromiseLike<TResult1 | TResult2>;
322
+ /**
323
+ * Fetches the pull request details.
324
+ *
325
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}`
326
+ *
327
+ * @returns The pull request object
328
+ */
329
+ get(): Promise<BitbucketPullRequest>;
330
+ /**
331
+ * Fetches the activity feed for this pull request.
332
+ *
333
+ * Activities include comments, approvals, reviews, rescopes, merges, and declines.
334
+ *
335
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/activities`
336
+ *
337
+ * @param params - Optional filters: `limit`, `start`, `fromId`, `fromType`
338
+ * @returns An array of pull request activities, ordered from most recent to oldest
339
+ */
340
+ activities(params?: ActivitiesParams): Promise<BitbucketPullRequestActivity[]>;
341
+ }
342
+
208
343
  /**
209
344
  * Represents a Bitbucket repository resource with chainable async methods.
210
345
  *
@@ -219,12 +354,17 @@ interface CommitsParams extends PaginationParams {
219
354
  * // Get pull requests
220
355
  * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });
221
356
  *
357
+ * // Navigate into a specific pull request
358
+ * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();
359
+ *
222
360
  * // Get commits
223
361
  * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });
224
362
  * ```
225
363
  */
226
364
  declare class RepositoryResource implements PromiseLike<BitbucketRepository> {
227
365
  private readonly request;
366
+ private readonly projectKey;
367
+ private readonly repoSlug;
228
368
  private readonly basePath;
229
369
  /** @internal */
230
370
  constructor(request: RequestFn, projectKey: string, repoSlug: string);
@@ -259,6 +399,23 @@ declare class RepositoryResource implements PromiseLike<BitbucketRepository> {
259
399
  * @returns An array of commits
260
400
  */
261
401
  commits(params?: CommitsParams): Promise<BitbucketCommit[]>;
402
+ /**
403
+ * Returns a {@link PullRequestResource} for a given pull request ID, providing
404
+ * access to pull request data and sub-resources (activities, etc.).
405
+ *
406
+ * The returned resource can be awaited directly to fetch pull request info,
407
+ * or chained to access nested resources.
408
+ *
409
+ * @param pullRequestId - The numeric pull request ID
410
+ * @returns A chainable pull request resource
411
+ *
412
+ * @example
413
+ * ```typescript
414
+ * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);
415
+ * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();
416
+ * ```
417
+ */
418
+ pullRequest(pullRequestId: number): PullRequestResource;
262
419
  }
263
420
 
264
421
  /** @internal */
@@ -345,7 +502,7 @@ interface BitbucketClientOptions {
345
502
  * @example
346
503
  * ```typescript
347
504
  * const bbClient = new BitbucketClient({
348
- * apiUrl: 'https://bitbucket.example.com',
505
+ * apiUrl: 'https://bitbucket.example.com/rest/api/latest',
349
506
  * user: 'john.doe',
350
507
  * token: 'my-token',
351
508
  * });
@@ -368,7 +525,7 @@ declare class BitbucketClient {
368
525
  /**
369
526
  * Performs an authenticated GET request to the Bitbucket REST API.
370
527
  *
371
- * @param path - API path relative to `/rest/api/latest` (e.g., `'/projects'`)
528
+ * @param path - API path appended directly to `apiUrl` (e.g., `'/projects'`)
372
529
  * @param params - Optional query parameters to append to the URL
373
530
  * @throws {Error} If the HTTP response is not OK
374
531
  * @internal
@@ -452,4 +609,4 @@ declare class Security {
452
609
  getHeaders(): Record<string, string>;
453
610
  }
454
611
 
455
- export { BitbucketClient, type BitbucketClientOptions, type BitbucketCommit, type BitbucketCommitAuthor, type BitbucketParticipant, type BitbucketProject, type BitbucketPullRequest, type BitbucketRef, type BitbucketRepository, type CommitsParams, type PagedResponse, type PaginationParams, ProjectResource, type ProjectsParams, type PullRequestsParams, type ReposParams, RepositoryResource, Security };
612
+ export { type ActivitiesParams, type BitbucketActivityUser, BitbucketClient, type BitbucketClientOptions, type BitbucketCommit, type BitbucketCommitAuthor, type BitbucketParticipant, type BitbucketProject, type BitbucketPullRequest, type BitbucketPullRequestActivity, type BitbucketPullRequestComment, type BitbucketRef, type BitbucketRepository, type CommitsParams, type PagedResponse, type PaginationParams, ProjectResource, type ProjectsParams, type PullRequestActivityAction, PullRequestResource, type PullRequestsParams, type ReposParams, RepositoryResource, Security };
package/dist/index.js CHANGED
@@ -22,6 +22,7 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  BitbucketClient: () => BitbucketClient,
24
24
  ProjectResource: () => ProjectResource,
25
+ PullRequestResource: () => PullRequestResource,
25
26
  RepositoryResource: () => RepositoryResource,
26
27
  Security: () => Security
27
28
  });
@@ -82,11 +83,56 @@ var Security = class {
82
83
  }
83
84
  };
84
85
 
86
+ // src/resources/PullRequestResource.ts
87
+ var PullRequestResource = class {
88
+ /** @internal */
89
+ constructor(request, projectKey, repoSlug, pullRequestId) {
90
+ this.request = request;
91
+ this.basePath = `/projects/${projectKey}/repos/${repoSlug}/pull-requests/${pullRequestId}`;
92
+ }
93
+ /**
94
+ * Allows the resource to be awaited directly, resolving with the pull request info.
95
+ * Delegates to {@link PullRequestResource.get}.
96
+ */
97
+ then(onfulfilled, onrejected) {
98
+ return this.get().then(onfulfilled, onrejected);
99
+ }
100
+ /**
101
+ * Fetches the pull request details.
102
+ *
103
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}`
104
+ *
105
+ * @returns The pull request object
106
+ */
107
+ async get() {
108
+ return this.request(this.basePath);
109
+ }
110
+ /**
111
+ * Fetches the activity feed for this pull request.
112
+ *
113
+ * Activities include comments, approvals, reviews, rescopes, merges, and declines.
114
+ *
115
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/activities`
116
+ *
117
+ * @param params - Optional filters: `limit`, `start`, `fromId`, `fromType`
118
+ * @returns An array of pull request activities, ordered from most recent to oldest
119
+ */
120
+ async activities(params) {
121
+ const data = await this.request(
122
+ `${this.basePath}/activities`,
123
+ params
124
+ );
125
+ return data.values;
126
+ }
127
+ };
128
+
85
129
  // src/resources/RepositoryResource.ts
86
130
  var RepositoryResource = class {
87
131
  /** @internal */
88
132
  constructor(request, projectKey, repoSlug) {
89
133
  this.request = request;
134
+ this.projectKey = projectKey;
135
+ this.repoSlug = repoSlug;
90
136
  this.basePath = `/projects/${projectKey}/repos/${repoSlug}`;
91
137
  }
92
138
  /**
@@ -136,6 +182,25 @@ var RepositoryResource = class {
136
182
  );
137
183
  return data.values;
138
184
  }
185
+ /**
186
+ * Returns a {@link PullRequestResource} for a given pull request ID, providing
187
+ * access to pull request data and sub-resources (activities, etc.).
188
+ *
189
+ * The returned resource can be awaited directly to fetch pull request info,
190
+ * or chained to access nested resources.
191
+ *
192
+ * @param pullRequestId - The numeric pull request ID
193
+ * @returns A chainable pull request resource
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);
198
+ * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();
199
+ * ```
200
+ */
201
+ pullRequest(pullRequestId) {
202
+ return new PullRequestResource(this.request, this.projectKey, this.repoSlug, pullRequestId);
203
+ }
139
204
  };
140
205
 
141
206
  // src/resources/ProjectResource.ts
@@ -211,13 +276,13 @@ var BitbucketClient = class {
211
276
  /**
212
277
  * Performs an authenticated GET request to the Bitbucket REST API.
213
278
  *
214
- * @param path - API path relative to `/rest/api/latest` (e.g., `'/projects'`)
279
+ * @param path - API path appended directly to `apiUrl` (e.g., `'/projects'`)
215
280
  * @param params - Optional query parameters to append to the URL
216
281
  * @throws {Error} If the HTTP response is not OK
217
282
  * @internal
218
283
  */
219
284
  async request(path, params) {
220
- const base = `${this.security.getApiUrl()}/rest/api/latest${path}`;
285
+ const base = `${this.security.getApiUrl()}${path}`;
221
286
  const url = buildUrl(base, params);
222
287
  const response = await fetch(url, { headers: this.security.getHeaders() });
223
288
  if (!response.ok) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/security/Security.ts","../src/resources/RepositoryResource.ts","../src/resources/ProjectResource.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 type { BitbucketProject, ProjectsParams } from './domain/Project';\nexport type { BitbucketRepository, ReposParams } from './domain/Repository';\nexport type { BitbucketPullRequest, BitbucketParticipant, BitbucketRef, PullRequestsParams } from './domain/PullRequest';\nexport type { BitbucketCommit, BitbucketCommitAuthor, CommitsParams } from './domain/Commit';\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 { BitbucketRepository } from '../domain/Repository';\nimport type { BitbucketPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { BitbucketCommit, CommitsParams } from '../domain/Commit';\nimport type { PagedResponse } from '../domain/Pagination';\nimport type { RequestFn } from './ProjectResource';\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 * // 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 projectKey: string,\n 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<BitbucketPullRequest[]> {\n const data = await this.request<PagedResponse<BitbucketPullRequest>>(\n `${this.basePath}/pull-requests`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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<BitbucketCommit[]> {\n const data = await this.request<PagedResponse<BitbucketCommit>>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\n }\n}\n","import type { BitbucketProject } from '../domain/Project';\nimport type { BitbucketRepository, ReposParams } from '../domain/Repository';\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/**\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 */\nexport class ProjectResource implements PromiseLike<BitbucketProject> {\n /** @internal */\n constructor(\n private readonly request: RequestFn,\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<BitbucketRepository[]> {\n const data = await this.request<PagedResponse<BitbucketRepository>>(\n `/projects/${this.key}/repos`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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.key, repoSlug);\n }\n}\n","import { Security } from './security/Security';\nimport { ProjectResource, type RequestFn } from './resources/ProjectResource';\nimport type { BitbucketProject, ProjectsParams } from './domain/Project';\nimport type { PagedResponse } from './domain/Pagination';\n\n/**\n * Constructor options for {@link BitbucketClient}.\n */\nexport interface BitbucketClientOptions {\n /** The base URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`) */\n apiUrl: 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 * user: 'john.doe',\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 * ```\n */\nexport class BitbucketClient {\n private readonly security: Security;\n\n /**\n * @param options - Connection and authentication options\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor({ apiUrl, user, token }: BitbucketClientOptions) {\n this.security = new Security(apiUrl, user, token);\n }\n\n /**\n * Performs an authenticated GET request to the Bitbucket REST API.\n *\n * @param path - API path relative to `/rest/api/latest` (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()}/rest/api/latest${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 /**\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<BitbucketProject[]> {\n const data = await this.request<PagedResponse<BitbucketProject>>(\n '/projects',\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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 return new ProjectResource(request, projectKey);\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/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 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 { BitbucketCommit, BitbucketCommitAuthor, CommitsParams } from './domain/Commit';\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 { PagedResponse } 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 * // With filters\n * const comments = await bbClient\n * .project('PROJ')\n * .repo('my-repo')\n * .pullRequest(42)\n * .activities({ fromId: 10, fromType: 'COMMENT' });\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<BitbucketPullRequestActivity[]> {\n const data = await this.request<PagedResponse<BitbucketPullRequestActivity>>(\n `${this.basePath}/activities`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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 { PagedResponse } from '../domain/Pagination';\nimport type { RequestFn } 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 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<BitbucketPullRequest[]> {\n const data = await this.request<PagedResponse<BitbucketPullRequest>>(\n `${this.basePath}/pull-requests`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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<BitbucketCommit[]> {\n const data = await this.request<PagedResponse<BitbucketCommit>>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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 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 { 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/**\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 */\nexport class ProjectResource implements PromiseLike<BitbucketProject> {\n /** @internal */\n constructor(\n private readonly request: RequestFn,\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<BitbucketRepository[]> {\n const data = await this.request<PagedResponse<BitbucketRepository>>(\n `/projects/${this.key}/repos`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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.key, repoSlug);\n }\n}\n","import { Security } from './security/Security';\nimport { ProjectResource, type RequestFn } from './resources/ProjectResource';\nimport type { BitbucketProject, ProjectsParams } from './domain/Project';\nimport type { PagedResponse } from './domain/Pagination';\n\n/**\n * Constructor options for {@link BitbucketClient}.\n */\nexport interface BitbucketClientOptions {\n /** The base URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`) */\n apiUrl: 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/rest/api/latest',\n * user: 'john.doe',\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 * ```\n */\nexport class BitbucketClient {\n private readonly security: Security;\n\n /**\n * @param options - Connection and authentication options\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor({ apiUrl, user, token }: BitbucketClientOptions) {\n this.security = new Security(apiUrl, user, token);\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()}${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 /**\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<BitbucketProject[]> {\n const data = await this.request<PagedResponse<BitbucketProject>>(\n '/projects',\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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 return new ProjectResource(request, projectKey);\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
@@ -53,11 +53,56 @@ var Security = class {
53
53
  }
54
54
  };
55
55
 
56
+ // src/resources/PullRequestResource.ts
57
+ var PullRequestResource = class {
58
+ /** @internal */
59
+ constructor(request, projectKey, repoSlug, pullRequestId) {
60
+ this.request = request;
61
+ this.basePath = `/projects/${projectKey}/repos/${repoSlug}/pull-requests/${pullRequestId}`;
62
+ }
63
+ /**
64
+ * Allows the resource to be awaited directly, resolving with the pull request info.
65
+ * Delegates to {@link PullRequestResource.get}.
66
+ */
67
+ then(onfulfilled, onrejected) {
68
+ return this.get().then(onfulfilled, onrejected);
69
+ }
70
+ /**
71
+ * Fetches the pull request details.
72
+ *
73
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}`
74
+ *
75
+ * @returns The pull request object
76
+ */
77
+ async get() {
78
+ return this.request(this.basePath);
79
+ }
80
+ /**
81
+ * Fetches the activity feed for this pull request.
82
+ *
83
+ * Activities include comments, approvals, reviews, rescopes, merges, and declines.
84
+ *
85
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/activities`
86
+ *
87
+ * @param params - Optional filters: `limit`, `start`, `fromId`, `fromType`
88
+ * @returns An array of pull request activities, ordered from most recent to oldest
89
+ */
90
+ async activities(params) {
91
+ const data = await this.request(
92
+ `${this.basePath}/activities`,
93
+ params
94
+ );
95
+ return data.values;
96
+ }
97
+ };
98
+
56
99
  // src/resources/RepositoryResource.ts
57
100
  var RepositoryResource = class {
58
101
  /** @internal */
59
102
  constructor(request, projectKey, repoSlug) {
60
103
  this.request = request;
104
+ this.projectKey = projectKey;
105
+ this.repoSlug = repoSlug;
61
106
  this.basePath = `/projects/${projectKey}/repos/${repoSlug}`;
62
107
  }
63
108
  /**
@@ -107,6 +152,25 @@ var RepositoryResource = class {
107
152
  );
108
153
  return data.values;
109
154
  }
155
+ /**
156
+ * Returns a {@link PullRequestResource} for a given pull request ID, providing
157
+ * access to pull request data and sub-resources (activities, etc.).
158
+ *
159
+ * The returned resource can be awaited directly to fetch pull request info,
160
+ * or chained to access nested resources.
161
+ *
162
+ * @param pullRequestId - The numeric pull request ID
163
+ * @returns A chainable pull request resource
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);
168
+ * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();
169
+ * ```
170
+ */
171
+ pullRequest(pullRequestId) {
172
+ return new PullRequestResource(this.request, this.projectKey, this.repoSlug, pullRequestId);
173
+ }
110
174
  };
111
175
 
112
176
  // src/resources/ProjectResource.ts
@@ -182,13 +246,13 @@ var BitbucketClient = class {
182
246
  /**
183
247
  * Performs an authenticated GET request to the Bitbucket REST API.
184
248
  *
185
- * @param path - API path relative to `/rest/api/latest` (e.g., `'/projects'`)
249
+ * @param path - API path appended directly to `apiUrl` (e.g., `'/projects'`)
186
250
  * @param params - Optional query parameters to append to the URL
187
251
  * @throws {Error} If the HTTP response is not OK
188
252
  * @internal
189
253
  */
190
254
  async request(path, params) {
191
- const base = `${this.security.getApiUrl()}/rest/api/latest${path}`;
255
+ const base = `${this.security.getApiUrl()}${path}`;
192
256
  const url = buildUrl(base, params);
193
257
  const response = await fetch(url, { headers: this.security.getHeaders() });
194
258
  if (!response.ok) {
@@ -243,6 +307,7 @@ function buildUrl(base, params) {
243
307
  export {
244
308
  BitbucketClient,
245
309
  ProjectResource,
310
+ PullRequestResource,
246
311
  RepositoryResource,
247
312
  Security
248
313
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/security/Security.ts","../src/resources/RepositoryResource.ts","../src/resources/ProjectResource.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 { BitbucketRepository } from '../domain/Repository';\nimport type { BitbucketPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { BitbucketCommit, CommitsParams } from '../domain/Commit';\nimport type { PagedResponse } from '../domain/Pagination';\nimport type { RequestFn } from './ProjectResource';\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 * // 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 projectKey: string,\n 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<BitbucketPullRequest[]> {\n const data = await this.request<PagedResponse<BitbucketPullRequest>>(\n `${this.basePath}/pull-requests`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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<BitbucketCommit[]> {\n const data = await this.request<PagedResponse<BitbucketCommit>>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\n }\n}\n","import type { BitbucketProject } from '../domain/Project';\nimport type { BitbucketRepository, ReposParams } from '../domain/Repository';\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/**\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 */\nexport class ProjectResource implements PromiseLike<BitbucketProject> {\n /** @internal */\n constructor(\n private readonly request: RequestFn,\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<BitbucketRepository[]> {\n const data = await this.request<PagedResponse<BitbucketRepository>>(\n `/projects/${this.key}/repos`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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.key, repoSlug);\n }\n}\n","import { Security } from './security/Security';\nimport { ProjectResource, type RequestFn } from './resources/ProjectResource';\nimport type { BitbucketProject, ProjectsParams } from './domain/Project';\nimport type { PagedResponse } from './domain/Pagination';\n\n/**\n * Constructor options for {@link BitbucketClient}.\n */\nexport interface BitbucketClientOptions {\n /** The base URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`) */\n apiUrl: 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 * user: 'john.doe',\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 * ```\n */\nexport class BitbucketClient {\n private readonly security: Security;\n\n /**\n * @param options - Connection and authentication options\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor({ apiUrl, user, token }: BitbucketClientOptions) {\n this.security = new Security(apiUrl, user, token);\n }\n\n /**\n * Performs an authenticated GET request to the Bitbucket REST API.\n *\n * @param path - API path relative to `/rest/api/latest` (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()}/rest/api/latest${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 /**\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<BitbucketProject[]> {\n const data = await this.request<PagedResponse<BitbucketProject>>(\n '/projects',\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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 return new ProjectResource(request, projectKey);\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/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 { PagedResponse } 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 * // With filters\n * const comments = await bbClient\n * .project('PROJ')\n * .repo('my-repo')\n * .pullRequest(42)\n * .activities({ fromId: 10, fromType: 'COMMENT' });\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<BitbucketPullRequestActivity[]> {\n const data = await this.request<PagedResponse<BitbucketPullRequestActivity>>(\n `${this.basePath}/activities`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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 { PagedResponse } from '../domain/Pagination';\nimport type { RequestFn } 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 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<BitbucketPullRequest[]> {\n const data = await this.request<PagedResponse<BitbucketPullRequest>>(\n `${this.basePath}/pull-requests`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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<BitbucketCommit[]> {\n const data = await this.request<PagedResponse<BitbucketCommit>>(\n `${this.basePath}/commits`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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 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 { 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/**\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 */\nexport class ProjectResource implements PromiseLike<BitbucketProject> {\n /** @internal */\n constructor(\n private readonly request: RequestFn,\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<BitbucketRepository[]> {\n const data = await this.request<PagedResponse<BitbucketRepository>>(\n `/projects/${this.key}/repos`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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.key, repoSlug);\n }\n}\n","import { Security } from './security/Security';\nimport { ProjectResource, type RequestFn } from './resources/ProjectResource';\nimport type { BitbucketProject, ProjectsParams } from './domain/Project';\nimport type { PagedResponse } from './domain/Pagination';\n\n/**\n * Constructor options for {@link BitbucketClient}.\n */\nexport interface BitbucketClientOptions {\n /** The base URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`) */\n apiUrl: 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/rest/api/latest',\n * user: 'john.doe',\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 * ```\n */\nexport class BitbucketClient {\n private readonly security: Security;\n\n /**\n * @param options - Connection and authentication options\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor({ apiUrl, user, token }: BitbucketClientOptions) {\n this.security = new Security(apiUrl, user, token);\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()}${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 /**\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<BitbucketProject[]> {\n const data = await this.request<PagedResponse<BitbucketProject>>(\n '/projects',\n params as Record<string, string | number | boolean>,\n );\n return data.values;\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 return new ProjectResource(request, projectKey);\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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitbucket-datacenter-api-client",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "TypeScript client for Bitbucket Data Center REST API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",