@bragduck/cli 2.9.5 → 2.10.1

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.
@@ -3379,12 +3379,19 @@ var JiraService = class {
3379
3379
  */
3380
3380
  buildJQL(options) {
3381
3381
  const queries = [];
3382
- queries.push("status IN (Done, Resolved, Closed)");
3383
3382
  if (options.days) {
3384
- queries.push(`updated >= -${options.days}d`);
3383
+ queries.push(
3384
+ `(created >= -${options.days}d OR resolved >= -${options.days}d OR updated >= -${options.days}d)`
3385
+ );
3385
3386
  }
3386
3387
  if (options.author) {
3387
- queries.push(`creator = "${options.author}"`);
3388
+ if (options.author.includes("@")) {
3389
+ queries.push("(creator = currentUser() OR assignee = currentUser())");
3390
+ } else {
3391
+ queries.push(`(creator = "${options.author}" OR assignee = "${options.author}")`);
3392
+ }
3393
+ } else {
3394
+ queries.push("(creator = currentUser() OR assignee = currentUser())");
3388
3395
  }
3389
3396
  if (options.jql) {
3390
3397
  queries.push(`(${options.jql})`);
@@ -3409,6 +3416,7 @@ var JiraService = class {
3409
3416
  */
3410
3417
  async getIssues(options = {}) {
3411
3418
  const jql = this.buildJQL(options);
3419
+ logger.debug(`Using JQL query: ${jql}`);
3412
3420
  const fields = [
3413
3421
  "summary",
3414
3422
  "description",
@@ -3420,16 +3428,41 @@ var JiraService = class {
3420
3428
  "issuetype"
3421
3429
  ];
3422
3430
  const allIssues = [];
3431
+ const seenIssueKeys = /* @__PURE__ */ new Set();
3423
3432
  let startAt = 0;
3424
3433
  const maxResults = 100;
3434
+ const maxIterations = 1e3;
3435
+ let iterations = 0;
3425
3436
  while (true) {
3437
+ iterations++;
3438
+ if (iterations > maxIterations) {
3439
+ logger.warning(
3440
+ `Reached maximum iteration limit (${maxIterations}). Stopping pagination to prevent infinite loop.`
3441
+ );
3442
+ break;
3443
+ }
3426
3444
  const endpoint = `/rest/api/2/search?jql=${encodeURIComponent(jql)}&startAt=${startAt}&maxResults=${maxResults}&fields=${fields.join(",")}`;
3427
3445
  try {
3428
3446
  const response = await this.request(endpoint);
3429
- allIssues.push(...response.issues);
3447
+ if (response.issues.length === 0) {
3448
+ logger.debug("No more results returned, stopping pagination");
3449
+ break;
3450
+ }
3451
+ let newIssuesCount = 0;
3452
+ for (const issue of response.issues) {
3453
+ if (!seenIssueKeys.has(issue.key)) {
3454
+ seenIssueKeys.add(issue.key);
3455
+ allIssues.push(issue);
3456
+ newIssuesCount++;
3457
+ }
3458
+ }
3430
3459
  logger.debug(
3431
- `Fetched ${response.issues.length} issues (total: ${allIssues.length} of ${response.total})${startAt + maxResults < response.total ? ", fetching next page..." : ""}`
3460
+ `Fetched ${newIssuesCount} new issues (total: ${allIssues.length} of ${response.total})${startAt + maxResults < response.total ? ", fetching next page..." : ""}`
3432
3461
  );
3462
+ if (newIssuesCount === 0) {
3463
+ logger.debug("All results are duplicates, stopping pagination");
3464
+ break;
3465
+ }
3433
3466
  if (startAt + maxResults >= response.total) {
3434
3467
  break;
3435
3468
  }
@@ -3447,7 +3480,10 @@ var JiraService = class {
3447
3480
  break;
3448
3481
  }
3449
3482
  if (startAt === 0) {
3450
- throw error;
3483
+ logger.warning(
3484
+ "No accessible issues found. Some resources may be deleted, archived, or you may not have permission to view them."
3485
+ );
3486
+ return [];
3451
3487
  }
3452
3488
  startAt += maxResults;
3453
3489
  continue;
@@ -3668,10 +3704,15 @@ var ConfluenceService = class {
3668
3704
  }
3669
3705
  /**
3670
3706
  * Build CQL query from options
3707
+ * Returns empty string if no filters need CQL (will use simple endpoint instead)
3671
3708
  */
3672
3709
  buildCQL(options) {
3710
+ if (!options.days && !options.author && !options.cql) {
3711
+ return "";
3712
+ }
3673
3713
  const queries = [];
3674
3714
  queries.push("type=page");
3715
+ queries.push("status=current");
3675
3716
  if (options.days) {
3676
3717
  queries.push(`lastModified >= now("-${options.days}d")`);
3677
3718
  }
@@ -3696,27 +3737,64 @@ var ConfluenceService = class {
3696
3737
  async getPages(options = {}) {
3697
3738
  const cql = this.buildCQL(options);
3698
3739
  const allPages = [];
3740
+ const seenPageIds = /* @__PURE__ */ new Set();
3699
3741
  let start = 0;
3700
3742
  const limit = 100;
3743
+ const maxIterations = 1e3;
3744
+ let iterations = 0;
3701
3745
  while (true) {
3702
- const params = {
3703
- type: "page",
3704
- status: "current",
3705
- start: start.toString(),
3706
- limit: limit.toString(),
3707
- expand: "version,body.storage"
3708
- };
3746
+ iterations++;
3747
+ if (iterations > maxIterations) {
3748
+ logger.warning(
3749
+ `Reached maximum iteration limit (${maxIterations}). Stopping pagination to prevent infinite loop.`
3750
+ );
3751
+ break;
3752
+ }
3753
+ let endpoint;
3754
+ let params;
3709
3755
  if (cql) {
3710
- params.cql = cql;
3756
+ logger.debug(`Using CQL search: ${cql}`);
3757
+ params = {
3758
+ cql,
3759
+ start: start.toString(),
3760
+ limit: limit.toString(),
3761
+ expand: "version,body.storage"
3762
+ };
3763
+ const queryString = Object.entries(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
3764
+ endpoint = `/wiki/rest/api/content/search?${queryString}`;
3765
+ } else {
3766
+ logger.debug("Using simple content list (no CQL filters)");
3767
+ params = {
3768
+ type: "page",
3769
+ status: "current",
3770
+ start: start.toString(),
3771
+ limit: limit.toString(),
3772
+ expand: "version,body.storage"
3773
+ };
3774
+ const queryString = Object.entries(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
3775
+ endpoint = `/wiki/rest/api/content?${queryString}`;
3711
3776
  }
3712
- const queryString = Object.entries(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
3713
- const endpoint = `/wiki/rest/api/content?${queryString}`;
3714
3777
  try {
3715
3778
  const response = await this.request(endpoint);
3716
- allPages.push(...response.results);
3779
+ if (response.results.length === 0) {
3780
+ logger.debug("No more results returned, stopping pagination");
3781
+ break;
3782
+ }
3783
+ let newPagesCount = 0;
3784
+ for (const page of response.results) {
3785
+ if (!seenPageIds.has(page.id)) {
3786
+ seenPageIds.add(page.id);
3787
+ allPages.push(page);
3788
+ newPagesCount++;
3789
+ }
3790
+ }
3717
3791
  logger.debug(
3718
- `Fetched ${response.size} pages (total: ${allPages.length})${response.size === limit ? ", fetching next page..." : ""}`
3792
+ `Fetched ${newPagesCount} new pages (total: ${allPages.length}, duplicates: ${response.results.length - newPagesCount})${response.size === limit ? ", fetching next page..." : ""}`
3719
3793
  );
3794
+ if (newPagesCount === 0) {
3795
+ logger.debug("All results are duplicates, stopping pagination");
3796
+ break;
3797
+ }
3720
3798
  if (response.size === 0 || response.size < limit) {
3721
3799
  break;
3722
3800
  }
@@ -3734,7 +3812,10 @@ var ConfluenceService = class {
3734
3812
  break;
3735
3813
  }
3736
3814
  if (start === 0) {
3737
- throw error;
3815
+ logger.warning(
3816
+ "No accessible pages found. Some resources may be deleted, archived, or you may not have permission to view them."
3817
+ );
3818
+ return [];
3738
3819
  }
3739
3820
  start += limit;
3740
3821
  continue;
@@ -4644,6 +4725,7 @@ async function syncAllAuthenticatedServices(options) {
4644
4725
  const results = [];
4645
4726
  for (let i = 0; i < servicesToSync.length; i++) {
4646
4727
  const service = servicesToSync[i];
4728
+ if (!service) continue;
4647
4729
  const serviceLabel = service.charAt(0).toUpperCase() + service.slice(1);
4648
4730
  logger.log(
4649
4731
  colors.highlight(`\u2501\u2501\u2501 Syncing ${i + 1}/${servicesToSync.length}: ${serviceLabel} \u2501\u2501\u2501`)