bitbucket-datacenter-api-client 1.1.0 → 1.2.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.js CHANGED
@@ -24,7 +24,8 @@ __export(index_exports, {
24
24
  ProjectResource: () => ProjectResource,
25
25
  PullRequestResource: () => PullRequestResource,
26
26
  RepositoryResource: () => RepositoryResource,
27
- Security: () => Security
27
+ Security: () => Security,
28
+ UserResource: () => UserResource
28
29
  });
29
30
  module.exports = __toCommonJS(index_exports);
30
31
 
@@ -124,13 +125,99 @@ var PullRequestResource = class {
124
125
  );
125
126
  return data.values;
126
127
  }
128
+ /**
129
+ * Fetches the tasks (review to-do items) for this pull request.
130
+ *
131
+ * Tasks are created by reviewers on specific comments and can be `OPEN` or `RESOLVED`.
132
+ *
133
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/tasks`
134
+ *
135
+ * @param params - Optional filters: `limit`, `start`
136
+ * @returns An array of pull request tasks
137
+ */
138
+ async tasks(params) {
139
+ const data = await this.request(
140
+ `${this.basePath}/tasks`,
141
+ params
142
+ );
143
+ return data.values;
144
+ }
145
+ /**
146
+ * Fetches the commits included in this pull request.
147
+ *
148
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/commits`
149
+ *
150
+ * @param params - Optional pagination: `limit`, `start`
151
+ * @returns An array of commits
152
+ */
153
+ async commits(params) {
154
+ const data = await this.request(
155
+ `${this.basePath}/commits`,
156
+ params
157
+ );
158
+ return data.values;
159
+ }
160
+ /**
161
+ * Fetches the file changes included in this pull request.
162
+ *
163
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/changes`
164
+ *
165
+ * @param params - Optional filters: `limit`, `start`, `withComments`
166
+ * @returns An array of file changes
167
+ */
168
+ async changes(params) {
169
+ const data = await this.request(
170
+ `${this.basePath}/changes`,
171
+ params
172
+ );
173
+ return data.values;
174
+ }
175
+ /**
176
+ * Fetches the Code Insights reports for this pull request.
177
+ *
178
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/reports`
179
+ *
180
+ * @param params - Optional pagination: `limit`, `start`
181
+ * @returns An array of Code Insights reports
182
+ */
183
+ async reports(params) {
184
+ const data = await this.request(
185
+ `${this.basePath}/reports`,
186
+ params
187
+ );
188
+ return data.values;
189
+ }
190
+ /**
191
+ * Fetches the aggregated build summaries for this pull request.
192
+ *
193
+ * Returns a map of commit hash → build counts per state
194
+ * (`successful`, `failed`, `inProgress`, `cancelled`, `unknown`).
195
+ *
196
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/build-summaries`
197
+ *
198
+ * @returns A record keyed by commit SHA with aggregated build counts
199
+ */
200
+ async buildSummaries() {
201
+ return this.request(`${this.basePath}/build-summaries`);
202
+ }
203
+ /**
204
+ * Fetches the Jira issues linked to this pull request.
205
+ *
206
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/issues`
207
+ *
208
+ * @returns An array of linked Jira issues
209
+ */
210
+ async issues() {
211
+ return this.request(`${this.basePath}/issues`);
212
+ }
127
213
  };
128
214
 
129
215
  // src/resources/RepositoryResource.ts
130
216
  var RepositoryResource = class {
131
217
  /** @internal */
132
- constructor(request, projectKey, repoSlug) {
218
+ constructor(request, requestText, projectKey, repoSlug) {
133
219
  this.request = request;
220
+ this.requestText = requestText;
134
221
  this.projectKey = projectKey;
135
222
  this.repoSlug = repoSlug;
136
223
  this.basePath = `/projects/${projectKey}/repos/${repoSlug}`;
@@ -182,6 +269,46 @@ var RepositoryResource = class {
182
269
  );
183
270
  return data.values;
184
271
  }
272
+ /**
273
+ * Fetches the files last modified in this repository along with the commit that last touched each.
274
+ *
275
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/last-modified`
276
+ *
277
+ * @param params - Optional filters: `limit`, `start`, `at`
278
+ * @returns An array of last-modified entries
279
+ */
280
+ async lastModified(params) {
281
+ const data = await this.request(
282
+ `${this.basePath}/last-modified`,
283
+ params
284
+ );
285
+ return data.values;
286
+ }
287
+ /**
288
+ * Fetches the size of this repository.
289
+ *
290
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/sizes`
291
+ *
292
+ * @returns The repository size object
293
+ */
294
+ async size() {
295
+ return this.request(`${this.basePath}/sizes`);
296
+ }
297
+ /**
298
+ * Fetches branches for this repository.
299
+ *
300
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/branches`
301
+ *
302
+ * @param params - Optional filters: `limit`, `start`, `filterText`, `orderBy`, `details`, `base`, `boostMatches`
303
+ * @returns An array of branches
304
+ */
305
+ async branches(params) {
306
+ const data = await this.request(
307
+ `${this.basePath}/branches`,
308
+ params
309
+ );
310
+ return data.values;
311
+ }
185
312
  /**
186
313
  * Returns a {@link PullRequestResource} for a given pull request ID, providing
187
314
  * access to pull request data and sub-resources (activities, etc.).
@@ -198,6 +325,21 @@ var RepositoryResource = class {
198
325
  * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();
199
326
  * ```
200
327
  */
328
+ /**
329
+ * Fetches the raw content of a file in this repository.
330
+ *
331
+ * `GET /rest/api/latest/projects/{key}/repos/{slug}/raw/{path}`
332
+ *
333
+ * @param filePath - Path to the file (e.g., `'src/index.ts'`)
334
+ * @param params - Optional: `at` (branch, tag, or commit SHA)
335
+ * @returns The raw file content as a string
336
+ */
337
+ async raw(filePath, params) {
338
+ return this.requestText(
339
+ `${this.basePath}/raw/${filePath}`,
340
+ params
341
+ );
342
+ }
201
343
  pullRequest(pullRequestId) {
202
344
  return new PullRequestResource(this.request, this.projectKey, this.repoSlug, pullRequestId);
203
345
  }
@@ -206,8 +348,9 @@ var RepositoryResource = class {
206
348
  // src/resources/ProjectResource.ts
207
349
  var ProjectResource = class {
208
350
  /** @internal */
209
- constructor(request, key) {
351
+ constructor(request, requestText, key) {
210
352
  this.request = request;
353
+ this.requestText = requestText;
211
354
  this.key = key;
212
355
  }
213
356
  /**
@@ -260,7 +403,48 @@ var ProjectResource = class {
260
403
  * ```
261
404
  */
262
405
  repo(repoSlug) {
263
- return new RepositoryResource(this.request, this.key, repoSlug);
406
+ return new RepositoryResource(this.request, this.requestText, this.key, repoSlug);
407
+ }
408
+ /**
409
+ * Fetches users with explicit permissions on this project.
410
+ *
411
+ * `GET /rest/api/latest/projects/{key}/permissions/users`
412
+ *
413
+ * @param params - Optional filters: `limit`, `start`, `filter`, `permission`
414
+ * @returns An array of user–permission pairs
415
+ */
416
+ async users(params) {
417
+ const data = await this.request(
418
+ `/projects/${this.key}/permissions/users`,
419
+ params
420
+ );
421
+ return data.values;
422
+ }
423
+ };
424
+
425
+ // src/resources/UserResource.ts
426
+ var UserResource = class {
427
+ /** @internal */
428
+ constructor(request, slug) {
429
+ this.request = request;
430
+ this.basePath = `/users/${slug}`;
431
+ }
432
+ /**
433
+ * Allows the resource to be awaited directly, resolving with the user info.
434
+ * Delegates to {@link UserResource.get}.
435
+ */
436
+ then(onfulfilled, onrejected) {
437
+ return this.get().then(onfulfilled, onrejected);
438
+ }
439
+ /**
440
+ * Fetches the user details.
441
+ *
442
+ * `GET /rest/api/latest/users/{slug}`
443
+ *
444
+ * @returns The user object
445
+ */
446
+ async get() {
447
+ return this.request(this.basePath);
264
448
  }
265
449
  };
266
450
 
@@ -270,8 +454,9 @@ var BitbucketClient = class {
270
454
  * @param options - Connection and authentication options
271
455
  * @throws {TypeError} If `apiUrl` is not a valid URL
272
456
  */
273
- constructor({ apiUrl, user, token }) {
457
+ constructor({ apiUrl, apiPath, user, token }) {
274
458
  this.security = new Security(apiUrl, user, token);
459
+ this.apiPath = apiPath.replace(/^\/|\/$/g, "");
275
460
  }
276
461
  /**
277
462
  * Performs an authenticated GET request to the Bitbucket REST API.
@@ -282,7 +467,7 @@ var BitbucketClient = class {
282
467
  * @internal
283
468
  */
284
469
  async request(path, params) {
285
- const base = `${this.security.getApiUrl()}${path}`;
470
+ const base = `${this.security.getApiUrl()}/${this.apiPath}${path}`;
286
471
  const url = buildUrl(base, params);
287
472
  const response = await fetch(url, { headers: this.security.getHeaders() });
288
473
  if (!response.ok) {
@@ -290,6 +475,15 @@ var BitbucketClient = class {
290
475
  }
291
476
  return response.json();
292
477
  }
478
+ async requestText(path, params) {
479
+ const base = `${this.security.getApiUrl()}/${this.apiPath}${path}`;
480
+ const url = buildUrl(base, params);
481
+ const response = await fetch(url, { headers: this.security.getHeaders() });
482
+ if (!response.ok) {
483
+ throw new Error(`Bitbucket API error: ${response.status} ${response.statusText}`);
484
+ }
485
+ return response.text();
486
+ }
293
487
  /**
294
488
  * Fetches all projects accessible to the authenticated user.
295
489
  *
@@ -324,7 +518,41 @@ var BitbucketClient = class {
324
518
  */
325
519
  project(projectKey) {
326
520
  const request = (path, params) => this.request(path, params);
327
- return new ProjectResource(request, projectKey);
521
+ const requestText = (path, params) => this.requestText(path, params);
522
+ return new ProjectResource(request, requestText, projectKey);
523
+ }
524
+ /**
525
+ * Fetches all users accessible to the authenticated user.
526
+ *
527
+ * `GET /rest/api/latest/users`
528
+ *
529
+ * @param params - Optional filters: `limit`, `start`, `filter`
530
+ * @returns An array of users
531
+ */
532
+ async users(params) {
533
+ const data = await this.request(
534
+ "/users",
535
+ params
536
+ );
537
+ return data.values;
538
+ }
539
+ /**
540
+ * Returns a {@link UserResource} for a given user slug, providing access
541
+ * to user data.
542
+ *
543
+ * The returned resource can be awaited directly to fetch user info.
544
+ *
545
+ * @param slug - The user slug (e.g., `'pilmee'`)
546
+ * @returns A chainable user resource
547
+ *
548
+ * @example
549
+ * ```typescript
550
+ * const user = await bbClient.user('pilmee');
551
+ * ```
552
+ */
553
+ user(slug) {
554
+ const request = (path, params) => this.request(path, params);
555
+ return new UserResource(request, slug);
328
556
  }
329
557
  };
330
558
  function buildUrl(base, params) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/security/Security.ts","../src/resources/PullRequestResource.ts","../src/resources/RepositoryResource.ts","../src/resources/ProjectResource.ts","../src/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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACIA,SAAS,SAAS,OAAuB;AACvC,MAAI,OAAO,SAAS,aAAa;AAC/B,WAAO,KAAK,KAAK;AAAA,EACnB;AACA,SAAO,OAAO,KAAK,KAAK,EAAE,SAAS,QAAQ;AAC7C;AAiBO,IAAM,WAAN,MAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcpB,YAAY,QAAgB,MAAc,OAAe;AACvD,QAAI,CAAC,IAAI,SAAS,MAAM,GAAG;AACzB,YAAM,IAAI,UAAU,oBAAoB,MAAM,sBAAsB;AAAA,IACtE;AACA,SAAK,SAAS,OAAO,QAAQ,OAAO,EAAE;AACtC,SAAK,sBAAsB,SAAS,SAAS,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,yBAAiC;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAqC;AACnC,WAAO;AAAA,MACL,eAAe,KAAK;AAAA,MACpB,gBAAgB;AAAA,MAChB,QAAQ;AAAA,IACV;AAAA,EACF;AACF;;;ACnDO,IAAM,sBAAN,MAAuE;AAAA;AAAA,EAI5E,YACmB,SACjB,YACA,UACA,eACA;AAJiB;AAKjB,SAAK,WAAW,aAAa,UAAU,UAAU,QAAQ,kBAAkB,aAAa;AAAA,EAC1F;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KACE,aACA,YACkC;AAClC,WAAO,KAAK,IAAI,EAAE,KAAK,aAAa,UAAU;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAAqC;AACzC,WAAO,KAAK,QAA8B,KAAK,QAAQ;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,WAAW,QAAoE;AACnF,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,GAAG,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AACF;;;ACnDO,IAAM,qBAAN,MAAqE;AAAA;AAAA,EAI1E,YACmB,SACA,YACA,UACjB;AAHiB;AACA;AACA;AAEjB,SAAK,WAAW,aAAa,UAAU,UAAU,QAAQ;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KACE,aACA,YACkC;AAClC,WAAO,KAAK,IAAI,EAAE,KAAK,aAAa,UAAU;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAAoC;AACxC,WAAO,KAAK,QAA6B,KAAK,QAAQ;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aAAa,QAA8D;AAC/E,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,GAAG,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QAAQ,QAAoD;AAChE,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,GAAG,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,YAAY,eAA4C;AACtD,WAAO,IAAI,oBAAoB,KAAK,SAAS,KAAK,YAAY,KAAK,UAAU,aAAa;AAAA,EAC5F;AACF;;;ACpFO,IAAM,kBAAN,MAA+D;AAAA;AAAA,EAEpE,YACmB,SACA,KACjB;AAFiB;AACA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMH,KACE,aACA,YACkC;AAClC,WAAO,KAAK,IAAI,EAAE,KAAK,aAAa,UAAU;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAAiC;AACrC,WAAO,KAAK,QAA0B,aAAa,KAAK,GAAG,EAAE;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,MAAM,QAAsD;AAChE,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,aAAa,KAAK,GAAG;AAAA,MACrB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,KAAK,UAAsC;AACzC,WAAO,IAAI,mBAAmB,KAAK,SAAS,KAAK,KAAK,QAAQ;AAAA,EAChE;AACF;;;AC1DO,IAAM,kBAAN,MAAsB;AAAA;AAAA;AAAA;AAAA;AAAA,EAO3B,YAAY,EAAE,QAAQ,MAAM,MAAM,GAA2B;AAC3D,SAAK,WAAW,IAAI,SAAS,QAAQ,MAAM,KAAK;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,QACZ,MACA,QACY;AACZ,UAAM,OAAO,GAAG,KAAK,SAAS,UAAU,CAAC,GAAG,IAAI;AAChD,UAAM,MAAM,SAAS,MAAM,MAAM;AACjC,UAAM,WAAW,MAAM,MAAM,KAAK,EAAE,SAAS,KAAK,SAAS,WAAW,EAAE,CAAC;AACzE,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,wBAAwB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,IAClF;AACA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,SAAS,QAAsD;AACnE,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,QAAQ,YAAqC;AAC3C,UAAM,UAAqB,CACzB,MACA,WACG,KAAK,QAAW,MAAM,MAAM;AACjC,WAAO,IAAI,gBAAgB,SAAS,UAAU;AAAA,EAChD;AACF;AAMA,SAAS,SAAS,MAAc,QAA4D;AAC1F,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,UAAU,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS;AACxE,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,QAAM,SAAS,IAAI,gBAAgB,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAC1E,SAAO,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC;AACrC;","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/resources/UserResource.ts","../src/BitbucketClient.ts"],"sourcesContent":["export { BitbucketClient } from './BitbucketClient';\nexport type { BitbucketClientOptions } from './BitbucketClient';\nexport { Security } from './security/Security';\nexport { ProjectResource } from './resources/ProjectResource';\nexport { RepositoryResource } from './resources/RepositoryResource';\nexport { PullRequestResource } from './resources/PullRequestResource';\nexport { UserResource } from './resources/UserResource';\nexport type { BitbucketProject, ProjectsParams } from './domain/Project';\nexport type { BitbucketRepository, ReposParams } from './domain/Repository';\nexport type { BitbucketPullRequest, BitbucketParticipant, BitbucketRef, PullRequestsParams } from './domain/PullRequest';\nexport type { BitbucketPullRequestActivity, BitbucketPullRequestComment, BitbucketActivityUser, PullRequestActivityAction, ActivitiesParams } from './domain/PullRequestActivity';\nexport type { BitbucketPullRequestTask, PullRequestTaskState, PullRequestTaskPermittedOperations, PullRequestTaskAnchor, TasksParams } from './domain/PullRequestTask';\nexport type { BitbucketChange, BitbucketChangePath, ChangeType, ChangeNodeType, ChangesParams } from './domain/Change';\nexport type { BitbucketReport, BitbucketReportData, ReportResult, ReportDataType, ReportsParams } from './domain/Report';\nexport type { BitbucketBuildSummaries, BitbucketBuildCount } from './domain/BuildSummary';\nexport type { BitbucketIssue } from './domain/Issue';\nexport type { BitbucketUser, BitbucketUserPermission, UsersParams, ProjectUsersParams } from './domain/User';\nexport type { BitbucketCommit, BitbucketCommitAuthor, CommitsParams } from './domain/Commit';\nexport type { BitbucketBranch, BranchesParams } from './domain/Branch';\nexport type { BitbucketRepositorySize } from './domain/RepositorySize';\nexport type { BitbucketLastModifiedEntry, LastModifiedParams } from './domain/LastModified';\nexport type { RawFileParams } from './domain/RawFile';\nexport type { PaginationParams, PagedResponse } from './domain/Pagination';\n","/**\n * Encodes a string to Base64 in a way that works in both Node.js and browsers.\n * @internal\n */\nfunction toBase64(value: string): string {\n if (typeof btoa !== 'undefined') {\n return btoa(value);\n }\n return Buffer.from(value).toString('base64');\n}\n\n/**\n * Handles Basic Authentication for Bitbucket Data Center REST API requests.\n *\n * @example\n * ```typescript\n * const security = new Security(\n * 'https://bitbucket.example.com',\n * 'my-user',\n * 'my-token'\n * );\n *\n * const headers = security.getHeaders();\n * // { Authorization: 'Basic <base64>', 'Content-Type': 'application/json', Accept: 'application/json' }\n * ```\n */\nexport class Security {\n private readonly apiUrl: string;\n private readonly authorizationHeader: string;\n\n /**\n * Creates a new Security instance with Basic Authentication credentials.\n *\n * @param apiUrl - The base URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`).\n * Must be a valid URL; throws if it cannot be parsed.\n * @param user - The username to authenticate with\n * @param token - The personal access token or password to authenticate with\n *\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor(apiUrl: string, user: string, token: string) {\n if (!URL.canParse(apiUrl)) {\n throw new TypeError(`Invalid apiUrl: \"${apiUrl}\" is not a valid URL`);\n }\n this.apiUrl = apiUrl.replace(/\\/$/, '');\n this.authorizationHeader = `Basic ${toBase64(`${user}:${token}`)}`;\n }\n\n /**\n * Returns the base URL of the Bitbucket Data Center instance, without a trailing slash.\n *\n * @returns The API base URL\n */\n getApiUrl(): string {\n return this.apiUrl;\n }\n\n /**\n * Returns the value of the `Authorization` header for Basic Authentication.\n *\n * @returns The Authorization header value in the format `Basic <base64-encoded-credentials>`\n */\n getAuthorizationHeader(): string {\n return this.authorizationHeader;\n }\n\n /**\n * Returns the full set of HTTP headers required for authenticated API requests.\n *\n * @returns An object containing `Authorization`, `Content-Type`, and `Accept` headers\n */\n getHeaders(): Record<string, string> {\n return {\n Authorization: this.authorizationHeader,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n }\n}\n","import type { BitbucketPullRequest } from '../domain/PullRequest';\nimport type { BitbucketPullRequestActivity, ActivitiesParams } from '../domain/PullRequestActivity';\nimport type { BitbucketPullRequestTask, TasksParams } from '../domain/PullRequestTask';\nimport type { BitbucketCommit } from '../domain/Commit';\nimport type { BitbucketChange, ChangesParams } from '../domain/Change';\nimport type { BitbucketReport, ReportsParams } from '../domain/Report';\nimport type { BitbucketBuildSummaries } from '../domain/BuildSummary';\nimport type { BitbucketIssue } from '../domain/Issue';\nimport type { PagedResponse, PaginationParams } from '../domain/Pagination';\nimport type { RequestFn } from './ProjectResource';\n\n/**\n * Represents a Bitbucket pull request resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketPullRequest>` so it can be awaited directly\n * to fetch the pull request info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get pull request info\n * const pr = await bbClient.project('PROJ').repo('my-repo').pullRequest(42);\n *\n * // Get activities\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n *\n * // Get tasks\n * const tasks = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).tasks();\n *\n * // Get commits\n * const commits = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).commits();\n *\n * // Get changes\n * const changes = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).changes();\n *\n * // Get reports\n * const reports = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).reports();\n *\n * // Get build summaries\n * const builds = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).buildSummaries();\n *\n * // Get linked Jira issues\n * const issues = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).issues();\n * ```\n */\nexport class PullRequestResource implements PromiseLike<BitbucketPullRequest> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n projectKey: string,\n repoSlug: string,\n pullRequestId: number,\n ) {\n this.basePath = `/projects/${projectKey}/repos/${repoSlug}/pull-requests/${pullRequestId}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the pull request info.\n * Delegates to {@link PullRequestResource.get}.\n */\n then<TResult1 = BitbucketPullRequest, TResult2 = never>(\n onfulfilled?: ((value: BitbucketPullRequest) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the pull request details.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}`\n *\n * @returns The pull request object\n */\n async get(): Promise<BitbucketPullRequest> {\n return this.request<BitbucketPullRequest>(this.basePath);\n }\n\n /**\n * Fetches the activity feed for this pull request.\n *\n * Activities include comments, approvals, reviews, rescopes, merges, and declines.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/activities`\n *\n * @param params - Optional filters: `limit`, `start`, `fromId`, `fromType`\n * @returns An array of pull request activities, ordered from most recent to oldest\n */\n async activities(params?: ActivitiesParams): Promise<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 /**\n * Fetches the tasks (review to-do items) for this pull request.\n *\n * Tasks are created by reviewers on specific comments and can be `OPEN` or `RESOLVED`.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/tasks`\n *\n * @param params - Optional filters: `limit`, `start`\n * @returns An array of pull request tasks\n */\n async tasks(params?: TasksParams): Promise<BitbucketPullRequestTask[]> {\n const data = await this.request<PagedResponse<BitbucketPullRequestTask>>(\n `${this.basePath}/tasks`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\n }\n\n /**\n * Fetches the commits included in this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/commits`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns An array of commits\n */\n async commits(params?: PaginationParams): Promise<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 * Fetches the file changes included in this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/changes`\n *\n * @param params - Optional filters: `limit`, `start`, `withComments`\n * @returns An array of file changes\n */\n async changes(params?: ChangesParams): Promise<BitbucketChange[]> {\n const data = await this.request<PagedResponse<BitbucketChange>>(\n `${this.basePath}/changes`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\n }\n\n /**\n * Fetches the Code Insights reports for this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/reports`\n *\n * @param params - Optional pagination: `limit`, `start`\n * @returns An array of Code Insights reports\n */\n async reports(params?: ReportsParams): Promise<BitbucketReport[]> {\n const data = await this.request<PagedResponse<BitbucketReport>>(\n `${this.basePath}/reports`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\n }\n\n /**\n * Fetches the aggregated build summaries for this pull request.\n *\n * Returns a map of commit hash → build counts per state\n * (`successful`, `failed`, `inProgress`, `cancelled`, `unknown`).\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/build-summaries`\n *\n * @returns A record keyed by commit SHA with aggregated build counts\n */\n async buildSummaries(): Promise<BitbucketBuildSummaries> {\n return this.request<BitbucketBuildSummaries>(`${this.basePath}/build-summaries`);\n }\n\n /**\n * Fetches the Jira issues linked to this pull request.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests/{id}/issues`\n *\n * @returns An array of linked Jira issues\n */\n async issues(): Promise<BitbucketIssue[]> {\n return this.request<BitbucketIssue[]>(`${this.basePath}/issues`);\n }\n}\n","import type { BitbucketRepository } from '../domain/Repository';\nimport type { BitbucketPullRequest, PullRequestsParams } from '../domain/PullRequest';\nimport type { BitbucketCommit, CommitsParams } from '../domain/Commit';\nimport type { BitbucketBranch, BranchesParams } from '../domain/Branch';\nimport type { BitbucketRepositorySize } from '../domain/RepositorySize';\nimport type { BitbucketLastModifiedEntry, LastModifiedParams } from '../domain/LastModified';\nimport type { RawFileParams } from '../domain/RawFile';\nimport type { PagedResponse } from '../domain/Pagination';\nimport type { RequestFn, RequestTextFn } from './ProjectResource';\nimport { PullRequestResource } from './PullRequestResource';\n\n/**\n * Represents a Bitbucket repository resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketRepository>` so it can be awaited directly\n * to fetch repository info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get repository info\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n *\n * // Get pull requests\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n *\n * // Navigate into a specific pull request\n * const activities = await bbClient.project('PROJ').repo('my-repo').pullRequest(42).activities();\n *\n * // Get commits\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * ```\n */\nexport class RepositoryResource implements PromiseLike<BitbucketRepository> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestText: RequestTextFn,\n private readonly projectKey: string,\n private readonly repoSlug: string,\n ) {\n this.basePath = `/projects/${projectKey}/repos/${repoSlug}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the repository info.\n * Delegates to {@link RepositoryResource.get}.\n */\n then<TResult1 = BitbucketRepository, TResult2 = never>(\n onfulfilled?: ((value: BitbucketRepository) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the repository details.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}`\n *\n * @returns The repository object\n */\n async get(): Promise<BitbucketRepository> {\n return this.request<BitbucketRepository>(this.basePath);\n }\n\n /**\n * Fetches pull requests for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/pull-requests`\n *\n * @param params - Optional filters: `limit`, `start`, `state`, `direction`, `at`, `order`\n * @returns An array of pull requests\n */\n async pullRequests(params?: PullRequestsParams): Promise<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 * Fetches the files last modified in this repository along with the commit that last touched each.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/last-modified`\n *\n * @param params - Optional filters: `limit`, `start`, `at`\n * @returns An array of last-modified entries\n */\n async lastModified(params?: LastModifiedParams): Promise<BitbucketLastModifiedEntry[]> {\n const data = await this.request<PagedResponse<BitbucketLastModifiedEntry>>(\n `${this.basePath}/last-modified`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\n }\n\n /**\n * Fetches the size of this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/sizes`\n *\n * @returns The repository size object\n */\n async size(): Promise<BitbucketRepositorySize> {\n return this.request<BitbucketRepositorySize>(`${this.basePath}/sizes`);\n }\n\n /**\n * Fetches branches for this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/branches`\n *\n * @param params - Optional filters: `limit`, `start`, `filterText`, `orderBy`, `details`, `base`, `boostMatches`\n * @returns An array of branches\n */\n async branches(params?: BranchesParams): Promise<BitbucketBranch[]> {\n const data = await this.request<PagedResponse<BitbucketBranch>>(\n `${this.basePath}/branches`,\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 /**\n * Fetches the raw content of a file in this repository.\n *\n * `GET /rest/api/latest/projects/{key}/repos/{slug}/raw/{path}`\n *\n * @param filePath - Path to the file (e.g., `'src/index.ts'`)\n * @param params - Optional: `at` (branch, tag, or commit SHA)\n * @returns The raw file content as a string\n */\n async raw(filePath: string, params?: RawFileParams): Promise<string> {\n return this.requestText(\n `${this.basePath}/raw/${filePath}`,\n params as Record<string, string | number | boolean>,\n );\n }\n\n pullRequest(pullRequestId: number): PullRequestResource {\n return new PullRequestResource(this.request, this.projectKey, this.repoSlug, pullRequestId);\n }\n}\n","import type { BitbucketProject } from '../domain/Project';\nimport type { BitbucketRepository, ReposParams } from '../domain/Repository';\nimport type { BitbucketUserPermission, ProjectUsersParams } from '../domain/User';\nimport type { PagedResponse } from '../domain/Pagination';\nimport { RepositoryResource } from './RepositoryResource';\n\n/** @internal */\nexport type RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<T>;\n\n/** @internal */\nexport type RequestTextFn = (\n path: string,\n params?: Record<string, string | number | boolean>,\n) => Promise<string>;\n\n/**\n * Represents a Bitbucket project resource with chainable async methods.\n *\n * Implements `PromiseLike<BitbucketProject>` so it can be awaited directly\n * to fetch the project info, while also exposing sub-resource methods.\n *\n * @example\n * ```typescript\n * // Await directly to get project info\n * const project = await bbClient.project('PROJ');\n *\n * // Get repositories with filters\n * const repos = await bbClient.project('PROJ').repos({ limit: 50, name: 'api' });\n *\n * // Navigate into a specific repository\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests();\n *\n * // Get users with access to the project\n * const users = await bbClient.project('PROJ').users({ permission: 'PROJECT_WRITE' });\n * ```\n */\nexport class ProjectResource implements PromiseLike<BitbucketProject> {\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n private readonly requestText: RequestTextFn,\n private readonly key: string,\n ) {}\n\n /**\n * Allows the resource to be awaited directly, resolving with the project info.\n * Delegates to {@link ProjectResource.get}.\n */\n then<TResult1 = BitbucketProject, TResult2 = never>(\n onfulfilled?: ((value: BitbucketProject) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the project details.\n *\n * `GET /rest/api/latest/projects/{key}`\n *\n * @returns The project object\n */\n async get(): Promise<BitbucketProject> {\n return this.request<BitbucketProject>(`/projects/${this.key}`);\n }\n\n /**\n * Fetches repositories belonging to this project.\n *\n * `GET /rest/api/latest/projects/{key}/repos`\n *\n * @param params - Optional filters: `limit`, `start`, `slug`, `name`, `permission`\n * @returns An array of repositories\n */\n async repos(params?: ReposParams): Promise<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.requestText, this.key, repoSlug);\n }\n\n /**\n * Fetches users with explicit permissions on this project.\n *\n * `GET /rest/api/latest/projects/{key}/permissions/users`\n *\n * @param params - Optional filters: `limit`, `start`, `filter`, `permission`\n * @returns An array of user–permission pairs\n */\n async users(params?: ProjectUsersParams): Promise<BitbucketUserPermission[]> {\n const data = await this.request<PagedResponse<BitbucketUserPermission>>(\n `/projects/${this.key}/permissions/users`,\n params as Record<string, string | number | boolean>,\n );\n return data.values;\n }\n}\n","import type { BitbucketUser } from '../domain/User';\nimport type { RequestFn } from './ProjectResource';\n\n/**\n * Represents a Bitbucket user resource.\n *\n * Implements `PromiseLike<BitbucketUser>` so it can be awaited directly\n * to fetch user info.\n *\n * @example\n * ```typescript\n * // Await directly to get user info\n * const user = await bbClient.user('pilmee');\n * ```\n */\nexport class UserResource implements PromiseLike<BitbucketUser> {\n private readonly basePath: string;\n\n /** @internal */\n constructor(\n private readonly request: RequestFn,\n slug: string,\n ) {\n this.basePath = `/users/${slug}`;\n }\n\n /**\n * Allows the resource to be awaited directly, resolving with the user info.\n * Delegates to {@link UserResource.get}.\n */\n then<TResult1 = BitbucketUser, TResult2 = never>(\n onfulfilled?: ((value: BitbucketUser) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n /**\n * Fetches the user details.\n *\n * `GET /rest/api/latest/users/{slug}`\n *\n * @returns The user object\n */\n async get(): Promise<BitbucketUser> {\n return this.request<BitbucketUser>(this.basePath);\n }\n}\n","import { Security } from './security/Security';\nimport { ProjectResource, type RequestFn, type RequestTextFn } from './resources/ProjectResource';\nimport { UserResource } from './resources/UserResource';\nimport type { BitbucketProject, ProjectsParams } from './domain/Project';\nimport type { BitbucketUser, UsersParams } from './domain/User';\nimport type { PagedResponse } from './domain/Pagination';\n\n/**\n * Constructor options for {@link BitbucketClient}.\n */\nexport interface BitbucketClientOptions {\n /** The host URL of the Bitbucket Data Center instance (e.g., `https://bitbucket.example.com`) */\n apiUrl: string;\n /** The API path to prepend to every request (e.g., `'rest/api/latest'`) */\n apiPath: string;\n /** The username to authenticate with */\n user: string;\n /** The personal access token or password to authenticate with */\n token: string;\n}\n\n/**\n * Main entry point for the Bitbucket Data Center REST API client.\n *\n * @example\n * ```typescript\n * const bbClient = new BitbucketClient({\n * apiUrl: 'https://bitbucket.example.com',\n * apiPath: 'rest/api/latest',\n * user: 'pilmee',\n * token: 'my-token',\n * });\n *\n * const projects = await bbClient.projects({ limit: 50 });\n * const project = await bbClient.project('PROJ');\n * const repos = await bbClient.project('PROJ').repos({ name: 'api' });\n * const repo = await bbClient.project('PROJ').repo('my-repo');\n * const prs = await bbClient.project('PROJ').repo('my-repo').pullRequests({ state: 'OPEN' });\n * const commits = await bbClient.project('PROJ').repo('my-repo').commits({ limit: 10 });\n * const users = await bbClient.users({ filter: 'john' });\n * const user = await bbClient.user('pilmee');\n * ```\n */\nexport class BitbucketClient {\n private readonly security: Security;\n private readonly apiPath: string;\n\n /**\n * @param options - Connection and authentication options\n * @throws {TypeError} If `apiUrl` is not a valid URL\n */\n constructor({ apiUrl, apiPath, user, token }: BitbucketClientOptions) {\n this.security = new Security(apiUrl, user, token);\n this.apiPath = apiPath.replace(/^\\/|\\/$/g, '');\n }\n\n /**\n * Performs an authenticated GET request to the Bitbucket REST API.\n *\n * @param path - API path appended directly to `apiUrl` (e.g., `'/projects'`)\n * @param params - Optional query parameters to append to the URL\n * @throws {Error} If the HTTP response is not OK\n * @internal\n */\n private async request<T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<T> {\n const base = `${this.security.getApiUrl()}/${this.apiPath}${path}`;\n const url = buildUrl(base, params);\n const response = await fetch(url, { headers: this.security.getHeaders() });\n if (!response.ok) {\n throw new Error(`Bitbucket API error: ${response.status} ${response.statusText}`);\n }\n return response.json() as Promise<T>;\n }\n\n private async requestText(\n path: string,\n params?: Record<string, string | number | boolean>,\n ): Promise<string> {\n const base = `${this.security.getApiUrl()}/${this.apiPath}${path}`;\n const url = buildUrl(base, params);\n const response = await fetch(url, { headers: this.security.getHeaders() });\n if (!response.ok) {\n throw new Error(`Bitbucket API error: ${response.status} ${response.statusText}`);\n }\n return response.text();\n }\n\n /**\n * Fetches all projects accessible to the authenticated user.\n *\n * `GET /rest/api/latest/projects`\n *\n * @param params - Optional filters: `limit`, `start`, `name`, `permission`\n * @returns An array of projects\n */\n async projects(params?: ProjectsParams): Promise<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 const requestText: RequestTextFn = (path, params) => this.requestText(path, params);\n return new ProjectResource(request, requestText, projectKey);\n }\n\n /**\n * Fetches all users accessible to the authenticated user.\n *\n * `GET /rest/api/latest/users`\n *\n * @param params - Optional filters: `limit`, `start`, `filter`\n * @returns An array of users\n */\n async users(params?: UsersParams): Promise<BitbucketUser[]> {\n const data = await this.request<PagedResponse<BitbucketUser>>(\n '/users',\n params as Record<string, string | number | boolean>,\n );\n return data.values;\n }\n\n /**\n * Returns a {@link UserResource} for a given user slug, providing access\n * to user data.\n *\n * The returned resource can be awaited directly to fetch user info.\n *\n * @param slug - The user slug (e.g., `'pilmee'`)\n * @returns A chainable user resource\n *\n * @example\n * ```typescript\n * const user = await bbClient.user('pilmee');\n * ```\n */\n user(slug: string): UserResource {\n const request: RequestFn = <T>(\n path: string,\n params?: Record<string, string | number | boolean>,\n ) => this.request<T>(path, params);\n return new UserResource(request, slug);\n }\n}\n\n/**\n * Appends query parameters to a URL string, skipping `undefined` values.\n * @internal\n */\nfunction buildUrl(base: string, params?: Record<string, string | number | boolean>): string {\n if (!params) return base;\n const entries = Object.entries(params).filter(([, v]) => v !== undefined);\n if (entries.length === 0) return base;\n const search = new URLSearchParams(entries.map(([k, v]) => [k, String(v)]));\n return `${base}?${search.toString()}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACIA,SAAS,SAAS,OAAuB;AACvC,MAAI,OAAO,SAAS,aAAa;AAC/B,WAAO,KAAK,KAAK;AAAA,EACnB;AACA,SAAO,OAAO,KAAK,KAAK,EAAE,SAAS,QAAQ;AAC7C;AAiBO,IAAM,WAAN,MAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcpB,YAAY,QAAgB,MAAc,OAAe;AACvD,QAAI,CAAC,IAAI,SAAS,MAAM,GAAG;AACzB,YAAM,IAAI,UAAU,oBAAoB,MAAM,sBAAsB;AAAA,IACtE;AACA,SAAK,SAAS,OAAO,QAAQ,OAAO,EAAE;AACtC,SAAK,sBAAsB,SAAS,SAAS,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,yBAAiC;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAqC;AACnC,WAAO;AAAA,MACL,eAAe,KAAK;AAAA,MACpB,gBAAgB;AAAA,MAChB,QAAQ;AAAA,IACV;AAAA,EACF;AACF;;;AClCO,IAAM,sBAAN,MAAuE;AAAA;AAAA,EAI5E,YACmB,SACjB,YACA,UACA,eACA;AAJiB;AAKjB,SAAK,WAAW,aAAa,UAAU,UAAU,QAAQ,kBAAkB,aAAa;AAAA,EAC1F;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KACE,aACA,YACkC;AAClC,WAAO,KAAK,IAAI,EAAE,KAAK,aAAa,UAAU;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAAqC;AACzC,WAAO,KAAK,QAA8B,KAAK,QAAQ;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,WAAW,QAAoE;AACnF,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,GAAG,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,MAAM,QAA2D;AACrE,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,GAAG,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QAAQ,QAAuD;AACnE,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,GAAG,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QAAQ,QAAoD;AAChE,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,GAAG,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QAAQ,QAAoD;AAChE,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,GAAG,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,iBAAmD;AACvD,WAAO,KAAK,QAAiC,GAAG,KAAK,QAAQ,kBAAkB;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,SAAoC;AACxC,WAAO,KAAK,QAA0B,GAAG,KAAK,QAAQ,SAAS;AAAA,EACjE;AACF;;;AC3JO,IAAM,qBAAN,MAAqE;AAAA;AAAA,EAI1E,YACmB,SACA,aACA,YACA,UACjB;AAJiB;AACA;AACA;AACA;AAEjB,SAAK,WAAW,aAAa,UAAU,UAAU,QAAQ;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KACE,aACA,YACkC;AAClC,WAAO,KAAK,IAAI,EAAE,KAAK,aAAa,UAAU;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAAoC;AACxC,WAAO,KAAK,QAA6B,KAAK,QAAQ;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aAAa,QAA8D;AAC/E,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,GAAG,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QAAQ,QAAoD;AAChE,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,GAAG,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aAAa,QAAoE;AACrF,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,GAAG,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAyC;AAC7C,WAAO,KAAK,QAAiC,GAAG,KAAK,QAAQ,QAAQ;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,SAAS,QAAqD;AAClE,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,GAAG,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2BA,MAAM,IAAI,UAAkB,QAAyC;AACnE,WAAO,KAAK;AAAA,MACV,GAAG,KAAK,QAAQ,QAAQ,QAAQ;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY,eAA4C;AACtD,WAAO,IAAI,oBAAoB,KAAK,SAAS,KAAK,YAAY,KAAK,UAAU,aAAa;AAAA,EAC5F;AACF;;;AC1IO,IAAM,kBAAN,MAA+D;AAAA;AAAA,EAEpE,YACmB,SACA,aACA,KACjB;AAHiB;AACA;AACA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMH,KACE,aACA,YACkC;AAClC,WAAO,KAAK,IAAI,EAAE,KAAK,aAAa,UAAU;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAAiC;AACrC,WAAO,KAAK,QAA0B,aAAa,KAAK,GAAG,EAAE;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,MAAM,QAAsD;AAChE,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,aAAa,KAAK,GAAG;AAAA,MACrB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,KAAK,UAAsC;AACzC,WAAO,IAAI,mBAAmB,KAAK,SAAS,KAAK,aAAa,KAAK,KAAK,QAAQ;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,MAAM,QAAiE;AAC3E,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,aAAa,KAAK,GAAG;AAAA,MACrB;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AACF;;;AC1GO,IAAM,eAAN,MAAyD;AAAA;AAAA,EAI9D,YACmB,SACjB,MACA;AAFiB;AAGjB,SAAK,WAAW,UAAU,IAAI;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KACE,aACA,YACkC;AAClC,WAAO,KAAK,IAAI,EAAE,KAAK,aAAa,UAAU;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAA8B;AAClC,WAAO,KAAK,QAAuB,KAAK,QAAQ;AAAA,EAClD;AACF;;;ACJO,IAAM,kBAAN,MAAsB;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ3B,YAAY,EAAE,QAAQ,SAAS,MAAM,MAAM,GAA2B;AACpE,SAAK,WAAW,IAAI,SAAS,QAAQ,MAAM,KAAK;AAChD,SAAK,UAAU,QAAQ,QAAQ,YAAY,EAAE;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,QACZ,MACA,QACY;AACZ,UAAM,OAAO,GAAG,KAAK,SAAS,UAAU,CAAC,IAAI,KAAK,OAAO,GAAG,IAAI;AAChE,UAAM,MAAM,SAAS,MAAM,MAAM;AACjC,UAAM,WAAW,MAAM,MAAM,KAAK,EAAE,SAAS,KAAK,SAAS,WAAW,EAAE,CAAC;AACzE,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,wBAAwB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,IAClF;AACA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA,EAEA,MAAc,YACZ,MACA,QACiB;AACjB,UAAM,OAAO,GAAG,KAAK,SAAS,UAAU,CAAC,IAAI,KAAK,OAAO,GAAG,IAAI;AAChE,UAAM,MAAM,SAAS,MAAM,MAAM;AACjC,UAAM,WAAW,MAAM,MAAM,KAAK,EAAE,SAAS,KAAK,SAAS,WAAW,EAAE,CAAC;AACzE,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,wBAAwB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,IAClF;AACA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,SAAS,QAAsD;AACnE,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,QAAQ,YAAqC;AAC3C,UAAM,UAAqB,CACzB,MACA,WACG,KAAK,QAAW,MAAM,MAAM;AACjC,UAAM,cAA6B,CAAC,MAAM,WAAW,KAAK,YAAY,MAAM,MAAM;AAClF,WAAO,IAAI,gBAAgB,SAAS,aAAa,UAAU;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,MAAM,QAAgD;AAC1D,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,KAAK,MAA4B;AAC/B,UAAM,UAAqB,CACzB,MACA,WACG,KAAK,QAAW,MAAM,MAAM;AACjC,WAAO,IAAI,aAAa,SAAS,IAAI;AAAA,EACvC;AACF;AAMA,SAAS,SAAS,MAAc,QAA4D;AAC1F,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,UAAU,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS;AACxE,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,QAAM,SAAS,IAAI,gBAAgB,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAC1E,SAAO,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC;AACrC;","names":[]}