@bragduck/cli 2.37.1 → 2.38.2
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 +49 -47
- package/dist/bin/bragduck.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/bragduck.js
CHANGED
|
@@ -63,7 +63,7 @@ var init_constants = __esm({
|
|
|
63
63
|
CLIENT_ID: "kJlsd66DLTnENE8p7Ru2JwqZg1Sie4yZ",
|
|
64
64
|
AUTH_URL: "https://auth.atlassian.com/authorize",
|
|
65
65
|
AUDIENCE: "api.atlassian.com",
|
|
66
|
-
SCOPES: "read:jira-work read:jira-user read:
|
|
66
|
+
SCOPES: "read:jira-work read:jira-user read:confluence-content.all read:confluence-user offline_access",
|
|
67
67
|
ACCESSIBLE_RESOURCES_URL: "https://api.atlassian.com/oauth/token/accessible-resources",
|
|
68
68
|
API_GATEWAY_URL: "https://api.atlassian.com"
|
|
69
69
|
};
|
|
@@ -1891,6 +1891,19 @@ var AtlassianAuthService = class {
|
|
|
1891
1891
|
callbackResult = await resultPromise;
|
|
1892
1892
|
} catch (error) {
|
|
1893
1893
|
storageService.deleteOAuthState();
|
|
1894
|
+
const rawMessage = error?.message ?? String(error);
|
|
1895
|
+
if (/invalid_scope/i.test(rawMessage)) {
|
|
1896
|
+
throw new AtlassianError(
|
|
1897
|
+
"Atlassian rejected the requested scopes. The app must list all of these classic scopes: read:jira-work, read:jira-user, read:confluence-content.all, read:confluence-user, offline_access.",
|
|
1898
|
+
{ originalError: rawMessage }
|
|
1899
|
+
);
|
|
1900
|
+
}
|
|
1901
|
+
if (/redirect_uri|invalid_request/i.test(rawMessage)) {
|
|
1902
|
+
throw new AtlassianError(
|
|
1903
|
+
"Atlassian rejected the redirect URI. All of http://127.0.0.1:8000/callback through http://127.0.0.1:8004/callback must be registered in the Atlassian app callback URL list.",
|
|
1904
|
+
{ originalError: rawMessage }
|
|
1905
|
+
);
|
|
1906
|
+
}
|
|
1894
1907
|
throw error;
|
|
1895
1908
|
}
|
|
1896
1909
|
storageService.deleteOAuthState();
|
|
@@ -4275,6 +4288,13 @@ init_errors();
|
|
|
4275
4288
|
init_logger();
|
|
4276
4289
|
init_storage_service();
|
|
4277
4290
|
init_constants();
|
|
4291
|
+
function adfToText(node) {
|
|
4292
|
+
if (!node) return "";
|
|
4293
|
+
if (typeof node === "string") return node;
|
|
4294
|
+
if (node.text) return node.text;
|
|
4295
|
+
if (node.content) return node.content.map(adfToText).join("");
|
|
4296
|
+
return "";
|
|
4297
|
+
}
|
|
4278
4298
|
var JiraService = class {
|
|
4279
4299
|
MAX_DESCRIPTION_LENGTH = 5e3;
|
|
4280
4300
|
/**
|
|
@@ -4469,9 +4489,10 @@ var JiraService = class {
|
|
|
4469
4489
|
* Determine the type of contribution the current user made to an issue
|
|
4470
4490
|
* Returns: 'created' | 'reported' | 'assigned-resolved' | 'edited'
|
|
4471
4491
|
*/
|
|
4472
|
-
async determineJiraContributionType(issue,
|
|
4473
|
-
const
|
|
4474
|
-
const
|
|
4492
|
+
async determineJiraContributionType(issue, userIdentifier) {
|
|
4493
|
+
const matchesUser = (person) => !!person && (person.accountId === userIdentifier || person.emailAddress === userIdentifier);
|
|
4494
|
+
const isCreator = matchesUser(issue.fields.creator);
|
|
4495
|
+
const isReporter = matchesUser(issue.fields.reporter);
|
|
4475
4496
|
if (isCreator) {
|
|
4476
4497
|
return {
|
|
4477
4498
|
type: "created",
|
|
@@ -4484,9 +4505,9 @@ var JiraService = class {
|
|
|
4484
4505
|
details: `Reported ${issue.fields.issuetype.name}: ${issue.fields.status.name}`
|
|
4485
4506
|
};
|
|
4486
4507
|
}
|
|
4487
|
-
const isAssigned = issue.fields.assignee
|
|
4508
|
+
const isAssigned = matchesUser(issue.fields.assignee);
|
|
4488
4509
|
const isResolved = issue.fields.resolutiondate !== null && issue.fields.resolutiondate !== void 0;
|
|
4489
|
-
const userEdits = issue.changelog?.histories?.filter((history) => history.author
|
|
4510
|
+
const userEdits = issue.changelog?.histories?.filter((history) => matchesUser(history.author)) || [];
|
|
4490
4511
|
const hasEdits = userEdits.length > 0;
|
|
4491
4512
|
if (isAssigned && isResolved) {
|
|
4492
4513
|
return {
|
|
@@ -4558,7 +4579,7 @@ var JiraService = class {
|
|
|
4558
4579
|
);
|
|
4559
4580
|
break;
|
|
4560
4581
|
}
|
|
4561
|
-
const endpoint = `/rest/api/3/search
|
|
4582
|
+
const endpoint = `/rest/api/3/search?jql=${encodeURIComponent(jql)}&startAt=${startAt}&maxResults=${maxResults}&fields=${fields.join(",")}`;
|
|
4562
4583
|
try {
|
|
4563
4584
|
const response = await this.request(endpoint);
|
|
4564
4585
|
if (response.issues.length === 0) {
|
|
@@ -4663,7 +4684,8 @@ var JiraService = class {
|
|
|
4663
4684
|
|
|
4664
4685
|
${contribution.details}`;
|
|
4665
4686
|
if (contribution.type === "created" && issue.fields.description) {
|
|
4666
|
-
const
|
|
4687
|
+
const plainDesc = adfToText(issue.fields.description);
|
|
4688
|
+
const truncatedDesc = plainDesc.substring(0, this.MAX_DESCRIPTION_LENGTH);
|
|
4667
4689
|
message = `${contributionPrefix}${issue.fields.summary}
|
|
4668
4690
|
|
|
4669
4691
|
${truncatedDesc}
|
|
@@ -4673,7 +4695,8 @@ ${contribution.details}`;
|
|
|
4673
4695
|
} else {
|
|
4674
4696
|
message = issue.fields.summary;
|
|
4675
4697
|
if (issue.fields.description) {
|
|
4676
|
-
const
|
|
4698
|
+
const plainDesc = adfToText(issue.fields.description);
|
|
4699
|
+
const truncatedDesc = plainDesc.substring(0, this.MAX_DESCRIPTION_LENGTH);
|
|
4677
4700
|
message = `${issue.fields.summary}
|
|
4678
4701
|
|
|
4679
4702
|
${truncatedDesc}`;
|
|
@@ -4921,16 +4944,13 @@ var ConfluenceService = class {
|
|
|
4921
4944
|
}
|
|
4922
4945
|
/**
|
|
4923
4946
|
* Build CQL query from options
|
|
4924
|
-
*
|
|
4947
|
+
* Always returns a CQL string with at least a user filter so we never return all pages.
|
|
4925
4948
|
*/
|
|
4926
4949
|
buildCQL(options) {
|
|
4927
|
-
if (!options.days && !options.author && !options.cql) {
|
|
4928
|
-
return "";
|
|
4929
|
-
}
|
|
4930
4950
|
const queries = [];
|
|
4931
4951
|
queries.push("type = page");
|
|
4932
4952
|
if (options.days) {
|
|
4933
|
-
queries.push(`
|
|
4953
|
+
queries.push(`lastmodified > startOfDay("-${options.days}d")`);
|
|
4934
4954
|
}
|
|
4935
4955
|
if (options.author) {
|
|
4936
4956
|
const escapedAuthor = options.author.replace(/"/g, '\\"');
|
|
@@ -4954,17 +4974,16 @@ var ConfluenceService = class {
|
|
|
4954
4974
|
* Determine the type of contribution the current user made to a page
|
|
4955
4975
|
* Returns: 'created' | 'edited' | 'commented'
|
|
4956
4976
|
*/
|
|
4957
|
-
async determineContributionType(page,
|
|
4958
|
-
|
|
4977
|
+
async determineContributionType(page, userIdentifier) {
|
|
4978
|
+
const matchesUser = (by) => !!by && (by.accountId === userIdentifier || by.email === userIdentifier);
|
|
4979
|
+
if (matchesUser(page.history?.createdBy)) {
|
|
4959
4980
|
return {
|
|
4960
4981
|
type: "created",
|
|
4961
4982
|
details: `Created page with ${page.version?.number || 1} version${(page.version?.number || 1) > 1 ? "s" : ""}`
|
|
4962
4983
|
};
|
|
4963
4984
|
}
|
|
4964
|
-
const hasEdits = page.version?.by
|
|
4965
|
-
const userComments = page.children?.comment?.results?.filter(
|
|
4966
|
-
(comment) => comment.version?.by?.email === userEmail
|
|
4967
|
-
) || [];
|
|
4985
|
+
const hasEdits = matchesUser(page.version?.by) && (page.version?.number || 0) > 1;
|
|
4986
|
+
const userComments = page.children?.comment?.results?.filter((comment) => matchesUser(comment.version?.by)) || [];
|
|
4968
4987
|
const hasComments = userComments.length > 0;
|
|
4969
4988
|
if (hasEdits && hasComments) {
|
|
4970
4989
|
return {
|
|
@@ -5008,9 +5027,7 @@ var ConfluenceService = class {
|
|
|
5008
5027
|
*/
|
|
5009
5028
|
async getPages(options = {}) {
|
|
5010
5029
|
const cql = this.buildCQL(options);
|
|
5011
|
-
|
|
5012
|
-
logger.debug(`Using CQL query: ${cql}`);
|
|
5013
|
-
}
|
|
5030
|
+
logger.debug(`Using CQL query: ${cql}`);
|
|
5014
5031
|
const allPages = [];
|
|
5015
5032
|
const seenPageIds = /* @__PURE__ */ new Set();
|
|
5016
5033
|
let start = 0;
|
|
@@ -5025,29 +5042,14 @@ var ConfluenceService = class {
|
|
|
5025
5042
|
);
|
|
5026
5043
|
break;
|
|
5027
5044
|
}
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
};
|
|
5037
|
-
const queryString = Object.entries(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
|
|
5038
|
-
endpoint = `/wiki/rest/api/content/search?${queryString}`;
|
|
5039
|
-
} else {
|
|
5040
|
-
logger.debug("Using simple content list (no CQL filters)");
|
|
5041
|
-
params = {
|
|
5042
|
-
type: "page",
|
|
5043
|
-
status: "current",
|
|
5044
|
-
start: start.toString(),
|
|
5045
|
-
limit: limit.toString(),
|
|
5046
|
-
expand: "version,history,children.comment,body.storage"
|
|
5047
|
-
};
|
|
5048
|
-
const queryString = Object.entries(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
|
|
5049
|
-
endpoint = `/wiki/rest/api/content?${queryString}`;
|
|
5050
|
-
}
|
|
5045
|
+
const params = {
|
|
5046
|
+
cql,
|
|
5047
|
+
start: start.toString(),
|
|
5048
|
+
limit: limit.toString(),
|
|
5049
|
+
expand: "version,history,children.comment,body.storage"
|
|
5050
|
+
};
|
|
5051
|
+
const queryString = Object.entries(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
|
|
5052
|
+
const endpoint = `/wiki/rest/api/content/search?${queryString}`;
|
|
5051
5053
|
try {
|
|
5052
5054
|
const response = await this.request(endpoint);
|
|
5053
5055
|
if (response.results.length === 0) {
|
|
@@ -6981,7 +6983,7 @@ async function syncSingleService(sourceType, options, TOTAL_STEPS, sharedDays, s
|
|
|
6981
6983
|
typeKey: refined.suggested_type_key,
|
|
6982
6984
|
impactDescription: refined.impact_description,
|
|
6983
6985
|
impact_description: refined.impact_description,
|
|
6984
|
-
attachments:
|
|
6986
|
+
attachments: [],
|
|
6985
6987
|
orgId: selectedOrgId || void 0,
|
|
6986
6988
|
// External fields for non-git sources (Jira, Confluence, etc.)
|
|
6987
6989
|
externalId: originalCommit?.externalId,
|