@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.
- package/dist/bin/bragduck.js +101 -19
- package/dist/bin/bragduck.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/bragduck.js
CHANGED
|
@@ -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(
|
|
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
|
-
|
|
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
|
-
|
|
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 ${
|
|
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
|
-
|
|
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
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 ${
|
|
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
|
-
|
|
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`)
|