bitbucket-datacenter-api-client 0.1.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 +160 -3
- package/dist/index.d.ts +160 -3
- package/dist/index.js +67 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +67 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
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
|
|
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
|
|
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
|
|
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()}
|
|
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
|
|
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()}
|
|
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
|
};
|
package/dist/index.mjs.map
CHANGED
|
@@ -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": "
|
|
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",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"repository": {
|
|
33
33
|
"type": "git",
|
|
34
|
-
"url": "https://github.com/
|
|
34
|
+
"url": "https://github.com/ElJijuna/BitbucketDataCenterApiClient.git"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@semantic-release/changelog": "^6.0.3",
|