@slalom-salesforce/sf-pr-comments 0.0.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/LICENSE.txt +12 -0
- package/README.md +147 -0
- package/lib/commands/azure/postcomments.d.ts +21 -0
- package/lib/commands/azure/postcomments.js +139 -0
- package/lib/commands/azure/postcomments.js.map +1 -0
- package/lib/commands/bitbucket/postcomments.d.ts +22 -0
- package/lib/commands/bitbucket/postcomments.js +141 -0
- package/lib/commands/bitbucket/postcomments.js.map +1 -0
- package/lib/commands/github/postcomments.d.ts +13 -0
- package/lib/commands/github/postcomments.js +39 -0
- package/lib/commands/github/postcomments.js.map +1 -0
- package/lib/helper/azureDevOps.d.ts +14 -0
- package/lib/helper/azureDevOps.js +151 -0
- package/lib/helper/azureDevOps.js.map +1 -0
- package/lib/helper/bitbucketDevOps.d.ts +17 -0
- package/lib/helper/bitbucketDevOps.js +206 -0
- package/lib/helper/bitbucketDevOps.js.map +1 -0
- package/lib/helper/utils.d.ts +20 -0
- package/lib/helper/utils.js +215 -0
- package/lib/helper/utils.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +9 -0
- package/lib/index.js.map +1 -0
- package/lib/interfaces/Comment.d.ts +10 -0
- package/lib/interfaces/Comment.js +3 -0
- package/lib/interfaces/Comment.js.map +1 -0
- package/lib/interfaces/CommentsByFile.d.ts +5 -0
- package/lib/interfaces/CommentsByFile.js +16 -0
- package/lib/interfaces/CommentsByFile.js.map +1 -0
- package/lib/interfaces/PrDiff.d.ts +5 -0
- package/lib/interfaces/PrDiff.js +3 -0
- package/lib/interfaces/PrDiff.js.map +1 -0
- package/lib/interfaces/ScannerResult.d.ts +6 -0
- package/lib/interfaces/ScannerResult.js +3 -0
- package/lib/interfaces/ScannerResult.js.map +1 -0
- package/lib/interfaces/Violation.d.ts +11 -0
- package/lib/interfaces/Violation.js +3 -0
- package/lib/interfaces/Violation.js.map +1 -0
- package/messages/azure.postcomments.md +51 -0
- package/messages/bitbucket.postcomments.md +55 -0
- package/messages/github.postcomments.md +16 -0
- package/oclif.manifest.json +209 -0
- package/package.json +218 -0
- package/schemas/hello-world.json +19 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2023, salesforce.com, inc.
|
|
5
|
+
* All rights reserved.
|
|
6
|
+
* Licensed under the BSD 3-Clause license.
|
|
7
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
8
|
+
*/
|
|
9
|
+
const azdev = require("azure-devops-node-api");
|
|
10
|
+
const utils_1 = require("./utils");
|
|
11
|
+
class AzureDevOps {
|
|
12
|
+
constructor(authorizationToken, organizationName) {
|
|
13
|
+
this.authorizationToken = authorizationToken;
|
|
14
|
+
this.organizationName = organizationName;
|
|
15
|
+
this.orgUrl = `https://dev.azure.com/${this.organizationName}`;
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
17
|
+
const authHandler = azdev.getPersonalAccessTokenHandler(this.authorizationToken);
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
19
|
+
this.connection = new azdev.WebApi(this.orgUrl, authHandler);
|
|
20
|
+
}
|
|
21
|
+
async getPrUrl(prId, projectName) {
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
23
|
+
const gitApi = await this.connection.getGitApi();
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
25
|
+
const prProperties = await gitApi.getPullRequestById(prId, projectName);
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-unsafe-member-access
|
|
27
|
+
return `${prProperties?.repository?.webUrl}/pullrequest/${prId}`;
|
|
28
|
+
}
|
|
29
|
+
async fetchPrComments(projectName, repoName, prId) {
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
31
|
+
const existingThreads = await // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
32
|
+
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
34
|
+
(await this.connection.getGitApi()).getThreads(repoName, prId, projectName);
|
|
35
|
+
const commentsByFileArray = [];
|
|
36
|
+
existingThreads.forEach((thread) => {
|
|
37
|
+
if (thread) {
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
39
|
+
const threadContext = thread.threadContext;
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
41
|
+
if (threadContext && !thread.isDeleted) {
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
43
|
+
const primaryComment = thread.comments[0];
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
45
|
+
const indexOfExistingFile = commentsByFileArray.findIndex(
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
47
|
+
(element) => element.fileName === threadContext.filePath.substring(1));
|
|
48
|
+
if (indexOfExistingFile === -1) {
|
|
49
|
+
commentsByFileArray.push({
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
51
|
+
fileName: threadContext.filePath.substring(1),
|
|
52
|
+
comments: [
|
|
53
|
+
{
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
55
|
+
lineNumber: thread.threadContext.rightFileStart.line,
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
57
|
+
content: primaryComment.content,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
commentsByFileArray[indexOfExistingFile].comments.push({
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
65
|
+
lineNumber: thread.threadContext.rightFileStart.line,
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
67
|
+
content: primaryComment.content,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return commentsByFileArray;
|
|
74
|
+
}
|
|
75
|
+
async postPrComment(projectName, repoName, prId, commentsPerFiles
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
77
|
+
) {
|
|
78
|
+
const fetchResultPromises = [];
|
|
79
|
+
if (commentsPerFiles) {
|
|
80
|
+
commentsPerFiles.forEach((commentsPerFile) => {
|
|
81
|
+
if (commentsPerFile.comments) {
|
|
82
|
+
// create comment threads per file
|
|
83
|
+
fetchResultPromises.concat(this.sendRequestPostPRComments(repoName, prId, projectName, commentsPerFile));
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
if (fetchResultPromises) {
|
|
87
|
+
const responses = await Promise.all(fetchResultPromises);
|
|
88
|
+
const responseJsonPromises = [];
|
|
89
|
+
responses.forEach((response) => {
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
91
|
+
responseJsonPromises.push(response.json());
|
|
92
|
+
});
|
|
93
|
+
// TO-DO - add logic to ensure post is successful
|
|
94
|
+
// (await Promise.all(responseJsonPromises)).forEach((responseJson) => {
|
|
95
|
+
// console.log(responseJson);
|
|
96
|
+
// });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
101
|
+
async sendRequestPostPRComments(repoName, prId, projectName, commentsPerFile) {
|
|
102
|
+
const resultPromises = [];
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
104
|
+
const gitAPI = await this.connection.getGitApi();
|
|
105
|
+
commentsPerFile.comments.forEach((comment) => {
|
|
106
|
+
const newCommentThread = {};
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
108
|
+
newCommentThread.comments = [
|
|
109
|
+
{
|
|
110
|
+
parentCommentId: 0,
|
|
111
|
+
commentType: 1,
|
|
112
|
+
content: comment.content.replace(new RegExp('\\\\n', 'g'), '\n'),
|
|
113
|
+
},
|
|
114
|
+
];
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
116
|
+
newCommentThread.status = 1;
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
118
|
+
newCommentThread.threadContext = {
|
|
119
|
+
filePath: `/${commentsPerFile.fileName}`,
|
|
120
|
+
rightFileStart: {
|
|
121
|
+
line: comment.startLineNumber,
|
|
122
|
+
offset: 1,
|
|
123
|
+
},
|
|
124
|
+
rightFileEnd: {
|
|
125
|
+
// line: comment.endLineNumber,
|
|
126
|
+
line: comment.startLineNumber,
|
|
127
|
+
offset: 1,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
131
|
+
resultPromises.push(gitAPI.createThread(newCommentThread, repoName, prId, projectName));
|
|
132
|
+
});
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
134
|
+
return resultPromises;
|
|
135
|
+
}
|
|
136
|
+
async getPrDiff(projectName, prId, gitFolderPath = './') {
|
|
137
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
138
|
+
const prInfo = await // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
139
|
+
|
|
140
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
141
|
+
(await this.connection.getGitApi()).getPullRequestById(prId, projectName);
|
|
142
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
|
|
143
|
+
const destinationBranchName = `origin/${(0, utils_1.removeRefHeadFromBranchName)(prInfo.targetRefName)}`;
|
|
144
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
|
|
145
|
+
const sourceBranchName = `origin/${(0, utils_1.removeRefHeadFromBranchName)(prInfo.sourceRefName)}`;
|
|
146
|
+
const diffFilesLinesadded = (0, utils_1.parseDiff)(gitFolderPath, destinationBranchName, sourceBranchName);
|
|
147
|
+
return diffFilesLinesadded;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
exports.default = AzureDevOps;
|
|
151
|
+
//# sourceMappingURL=azureDevOps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"azureDevOps.js","sourceRoot":"","sources":["../../src/helper/azureDevOps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AnyJson } from '@salesforce/ts-types';
|
|
2
|
+
import { CommentsByFile } from '../interfaces/CommentsByFile';
|
|
3
|
+
import { PrDiff } from '../interfaces/PrDiff';
|
|
4
|
+
export default class BitbucketDevOps {
|
|
5
|
+
static BITBUCKET_API_URL: string;
|
|
6
|
+
static BITBUCKET_WEBAPP_URL: string;
|
|
7
|
+
private PAGELENGTH;
|
|
8
|
+
private username;
|
|
9
|
+
private password;
|
|
10
|
+
private workspaceName;
|
|
11
|
+
private baseUrl;
|
|
12
|
+
constructor(username: string, password: string, workspaceName: string);
|
|
13
|
+
fetchPrComments(repoSlugName: string, prId: number): Promise<CommentsByFile[]>;
|
|
14
|
+
postPrComment(repoSlugName: string, prId: number, commentsPerFiles: CommentsByFile[]): Promise<any>;
|
|
15
|
+
sendRequestPostPRComments(repoName: string, prId: number, body: AnyJson): Promise<any>;
|
|
16
|
+
getPrDiff(repoName: string, prId: number, gitFolderPath?: string): Promise<PrDiff[]>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2020, salesforce.com, inc.
|
|
5
|
+
* All rights reserved.
|
|
6
|
+
* Licensed under the BSD 3-Clause license.
|
|
7
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
8
|
+
*/
|
|
9
|
+
const node_fetch_1 = require("node-fetch");
|
|
10
|
+
const core_1 = require("@salesforce/core");
|
|
11
|
+
const utils_1 = require("../helper/utils");
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
|
|
13
|
+
const parser = require('git-pr-diff-parser');
|
|
14
|
+
// TO-DO - Error handling
|
|
15
|
+
class BitbucketDevOps {
|
|
16
|
+
// private projectName: string;
|
|
17
|
+
// private repoName: string;
|
|
18
|
+
constructor(username, password, workspaceName) {
|
|
19
|
+
this.PAGELENGTH = 50;
|
|
20
|
+
this.username = username;
|
|
21
|
+
this.password = password;
|
|
22
|
+
this.workspaceName = workspaceName;
|
|
23
|
+
this.baseUrl = `${BitbucketDevOps.BITBUCKET_API_URL}/repositories/${this.workspaceName}`;
|
|
24
|
+
}
|
|
25
|
+
async fetchPrComments(repoSlugName, prId) {
|
|
26
|
+
const existingCommentsByFiles = [];
|
|
27
|
+
const options = {
|
|
28
|
+
method: 'GET',
|
|
29
|
+
headers: {
|
|
30
|
+
Authorization: 'Basic ' + Buffer.from(this.username + ':' + this.password).toString('base64'),
|
|
31
|
+
Accept: 'application/json',
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
const url = `${this.baseUrl}/${repoSlugName}/pullrequests/${prId}/comments?pagelen=${this.PAGELENGTH}`;
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
|
36
|
+
const response = await (0, node_fetch_1.default)(url, options);
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
38
|
+
const data = await response.json();
|
|
39
|
+
let currentPage = 1;
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
41
|
+
const totalSize = data.size;
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
43
|
+
const pageLength = data.pagelen;
|
|
44
|
+
const totalPages = Math.ceil(totalSize / pageLength);
|
|
45
|
+
const fetchedCommentsPromisesArray = [];
|
|
46
|
+
(0, utils_1.printMessage)(`Pulling ${totalSize} inline comments from PR ${prId}`, utils_1.MessageType.Info, core_1.Logger.getRoot().getLevel());
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
48
|
+
let comments = data.values;
|
|
49
|
+
while (currentPage < totalPages) {
|
|
50
|
+
currentPage++;
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
52
|
+
fetchedCommentsPromisesArray.push((0, node_fetch_1.default)(`${url}&page=${currentPage}`, options));
|
|
53
|
+
}
|
|
54
|
+
const fetchedCommentsArray = await Promise.all(fetchedCommentsPromisesArray);
|
|
55
|
+
const dataPromises = [];
|
|
56
|
+
fetchedCommentsArray.forEach((fetchedComments) => {
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
58
|
+
dataPromises.push(fetchedComments.json());
|
|
59
|
+
});
|
|
60
|
+
const dataArray = await Promise.all(dataPromises);
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
62
|
+
dataArray.forEach((data) => {
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
64
|
+
comments = [...comments, ...data.values];
|
|
65
|
+
});
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
67
|
+
comments.forEach((comment) => {
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
69
|
+
if (comment.inline) {
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
71
|
+
const indexOfExistingFile = existingCommentsByFiles.findIndex(
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
73
|
+
(element) => element.fileName === comment.inline.path);
|
|
74
|
+
if (indexOfExistingFile > -1) {
|
|
75
|
+
const matchedElement = existingCommentsByFiles[indexOfExistingFile];
|
|
76
|
+
if (!matchedElement.comments) {
|
|
77
|
+
matchedElement.comments = [];
|
|
78
|
+
}
|
|
79
|
+
matchedElement.comments.push({
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
81
|
+
startLineNumber: comment.inline.from,
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
83
|
+
endLineNumber: comment.inline.to,
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
85
|
+
lineNumber: comment.inline.from || comment.inline.to,
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
87
|
+
htmlContent: comment.content.html,
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
89
|
+
content: comment.content.raw,
|
|
90
|
+
});
|
|
91
|
+
existingCommentsByFiles[indexOfExistingFile] = matchedElement;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
existingCommentsByFiles.push({
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
96
|
+
fileName: comment.inline.path,
|
|
97
|
+
comments: [
|
|
98
|
+
{
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
100
|
+
startLineNumber: comment.inline.from,
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
102
|
+
endLineNumber: comment.inline.to,
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
104
|
+
lineNumber: comment.inline.from || comment.inline.to,
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
106
|
+
htmlContent: comment.content.html,
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
108
|
+
content: comment.content.raw,
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
if (existingCommentsByFiles.length > 0) {
|
|
116
|
+
(0, utils_1.printMessage)(`Total files with comments - ${existingCommentsByFiles.length}`, utils_1.MessageType.Info, core_1.Logger.getRoot().getLevel());
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
(0, utils_1.printMessage)('No comments found for the PR', utils_1.MessageType.Warn, core_1.Logger.getRoot().getLevel());
|
|
120
|
+
}
|
|
121
|
+
return existingCommentsByFiles;
|
|
122
|
+
}
|
|
123
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
124
|
+
async postPrComment(repoSlugName, prId, commentsPerFiles) {
|
|
125
|
+
const fetchResultPromises = [];
|
|
126
|
+
if (commentsPerFiles) {
|
|
127
|
+
commentsPerFiles.forEach((commentsPerFile) => {
|
|
128
|
+
if (commentsPerFile.comments) {
|
|
129
|
+
commentsPerFile.comments.forEach((comment) => {
|
|
130
|
+
const requestBody = `{"content":{"raw":"${comment.content}"}, "inline":{"to":${comment.lineNumber}, "path":"${commentsPerFile.fileName}"}}`;
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
132
|
+
fetchResultPromises.push(this.sendRequestPostPRComments(repoSlugName, prId, JSON.parse(requestBody)));
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
if (fetchResultPromises) {
|
|
137
|
+
const responses = await Promise.all(fetchResultPromises);
|
|
138
|
+
const responseJsonPromises = [];
|
|
139
|
+
responses.forEach((response) => {
|
|
140
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
141
|
+
responseJsonPromises.push(response.json());
|
|
142
|
+
});
|
|
143
|
+
// TO-DO - add logic to ensure post is successful
|
|
144
|
+
// (await Promise.all(responseJsonPromises)).forEach((responseJson) => {
|
|
145
|
+
// console.log(responseJson);
|
|
146
|
+
// });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/require-await
|
|
151
|
+
async sendRequestPostPRComments(repoName, prId, body) {
|
|
152
|
+
const options = {
|
|
153
|
+
method: 'POST',
|
|
154
|
+
headers: {
|
|
155
|
+
Authorization: 'Basic ' + Buffer.from(this.username + ':' + this.password).toString('base64'),
|
|
156
|
+
'Content-Type': 'application/json',
|
|
157
|
+
},
|
|
158
|
+
body: JSON.stringify(body),
|
|
159
|
+
};
|
|
160
|
+
const url = `${this.baseUrl}/${repoName}/pullrequests/${prId}/comments`;
|
|
161
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
|
162
|
+
const response = (0, node_fetch_1.default)(url, options);
|
|
163
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
164
|
+
return response;
|
|
165
|
+
}
|
|
166
|
+
async getPrDiff(repoName, prId, gitFolderPath = './') {
|
|
167
|
+
const options = {
|
|
168
|
+
method: 'GET',
|
|
169
|
+
headers: {
|
|
170
|
+
Authorization: 'Basic ' + Buffer.from(this.username + ':' + this.password).toString('base64'),
|
|
171
|
+
'Content-Type': 'application/json',
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
const url = `${this.baseUrl}/${repoName}/pullrequests/${prId}`;
|
|
175
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
176
|
+
const { destination, source } = await (await (0, node_fetch_1.default)(url, options)).json();
|
|
177
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-unsafe-member-access
|
|
178
|
+
const destinationBranchName = `origin/${destination.branch.name}`;
|
|
179
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-unsafe-member-access
|
|
180
|
+
const sourceBranchName = `origin/${source.branch.name}`;
|
|
181
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
|
182
|
+
const parsedDiff = await parser(gitFolderPath, destinationBranchName, sourceBranchName);
|
|
183
|
+
const diffFilesLinesadded = [];
|
|
184
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
185
|
+
parsedDiff.forEach((eachFile) => {
|
|
186
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
187
|
+
let addedLine = eachFile.lines.filter((line) => {
|
|
188
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
|
|
189
|
+
if (line.type === 'add')
|
|
190
|
+
return line;
|
|
191
|
+
});
|
|
192
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
193
|
+
if (addedLine && addedLine.length > 0) {
|
|
194
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
|
|
195
|
+
addedLine = addedLine.map((line) => line.ln);
|
|
196
|
+
}
|
|
197
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
198
|
+
diffFilesLinesadded.push({ fileName: eachFile.to, linesAdded: addedLine });
|
|
199
|
+
});
|
|
200
|
+
return diffFilesLinesadded;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
exports.default = BitbucketDevOps;
|
|
204
|
+
BitbucketDevOps.BITBUCKET_API_URL = 'https://api.bitbucket.org/2.0';
|
|
205
|
+
BitbucketDevOps.BITBUCKET_WEBAPP_URL = 'https://bitbucket.org';
|
|
206
|
+
//# sourceMappingURL=bitbucketDevOps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bitbucketDevOps.js","sourceRoot":"","sources":["../../src/helper/bitbucketDevOps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { LoggerLevel } from '@salesforce/core';
|
|
2
|
+
import { ScannerResult } from '../interfaces/ScannerResult';
|
|
3
|
+
import { CommentsByFile } from '../interfaces/CommentsByFile';
|
|
4
|
+
import { Violation } from '../interfaces/Violation';
|
|
5
|
+
import { PrDiff } from '../interfaces/PrDiff';
|
|
6
|
+
export declare enum MessageType {
|
|
7
|
+
Info = 0,
|
|
8
|
+
Debug = 1,
|
|
9
|
+
Success = 2,
|
|
10
|
+
Warn = 3,
|
|
11
|
+
Error = 4
|
|
12
|
+
}
|
|
13
|
+
export declare function getCommentBody(violation: Violation): string;
|
|
14
|
+
export declare function parseScannerOutput(scannerResults: ScannerResult[], diffFolderName: string): CommentsByFile[];
|
|
15
|
+
export declare function filterToNewCommentsToPost(CodeReviewCommentsByFilesToPost: CommentsByFile[], existingCommentsByFiles: CommentsByFile[]): CommentsByFile[];
|
|
16
|
+
export declare function getCodeReviewFromFile(filename: string): ScannerResult[];
|
|
17
|
+
export declare function printMessage(message: string, messageType: MessageType, loggerLevel: LoggerLevel): void;
|
|
18
|
+
export declare function filterCommentsToDiff(diffFilesLinesadded: PrDiff[], newCommentsByFilesToPost: CommentsByFile[]): CommentsByFile[];
|
|
19
|
+
export declare function parseDiff(gitFolderPath: string, destinationBranchName: string, sourceBranchName: string): Promise<PrDiff[]>;
|
|
20
|
+
export declare function removeRefHeadFromBranchName(branchRefName: string): string;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.removeRefHeadFromBranchName = exports.parseDiff = exports.filterCommentsToDiff = exports.printMessage = exports.getCodeReviewFromFile = exports.filterToNewCommentsToPost = exports.parseScannerOutput = exports.getCommentBody = exports.MessageType = void 0;
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (c) 2020, salesforce.com, inc.
|
|
6
|
+
* All rights reserved.
|
|
7
|
+
* Licensed under the BSD 3-Clause license.
|
|
8
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
9
|
+
*/
|
|
10
|
+
const fs_1 = require("fs");
|
|
11
|
+
const core_1 = require("@salesforce/core");
|
|
12
|
+
const chalk = require("chalk");
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
|
|
14
|
+
const parser = require('git-pr-diff-parser');
|
|
15
|
+
// Initialize Messages with the current plugin directory
|
|
16
|
+
core_1.Messages.importMessagesDirectory(__dirname);
|
|
17
|
+
const messages = core_1.Messages.load('@slalom-salesforce/sf-pr-comments', 'bitbucket.postcomments', [
|
|
18
|
+
'summary',
|
|
19
|
+
'examples',
|
|
20
|
+
'flags.username.summary',
|
|
21
|
+
'flags.authtoken.summary',
|
|
22
|
+
'flags.bitbucketworkspace.summary',
|
|
23
|
+
'flags.bitbucketreposlug.summary',
|
|
24
|
+
'flags.bitbucketprid.summary',
|
|
25
|
+
'flags.foldernamefordiff.summary',
|
|
26
|
+
'flags.gitfoldername.summary',
|
|
27
|
+
'flags.reviewresultjsonfile.summary',
|
|
28
|
+
'error.AuthFailed',
|
|
29
|
+
'error.PermissionIssue',
|
|
30
|
+
'error.CodeReviewInput',
|
|
31
|
+
'error.CodeReviewFile',
|
|
32
|
+
]);
|
|
33
|
+
var MessageType;
|
|
34
|
+
(function (MessageType) {
|
|
35
|
+
MessageType[MessageType["Info"] = 0] = "Info";
|
|
36
|
+
MessageType[MessageType["Debug"] = 1] = "Debug";
|
|
37
|
+
MessageType[MessageType["Success"] = 2] = "Success";
|
|
38
|
+
MessageType[MessageType["Warn"] = 3] = "Warn";
|
|
39
|
+
MessageType[MessageType["Error"] = 4] = "Error";
|
|
40
|
+
})(MessageType = exports.MessageType || (exports.MessageType = {}));
|
|
41
|
+
function getCommentBody(violation) {
|
|
42
|
+
const commentBody = `Severity : ${violation.severity} \\n \\n ` +
|
|
43
|
+
`Category : ${violation.category} \\n \\n ` +
|
|
44
|
+
`Rule Name : ${violation.ruleName} \\n \\n ` +
|
|
45
|
+
// eslint-disable-next-line no-control-regex
|
|
46
|
+
`Issue : ${violation.message.replace(new RegExp('\n', 'g'), '')} \\n\\n ` +
|
|
47
|
+
`Reference : ${violation.url}`;
|
|
48
|
+
return commentBody;
|
|
49
|
+
}
|
|
50
|
+
exports.getCommentBody = getCommentBody;
|
|
51
|
+
function parseScannerOutput(scannerResults, diffFolderName) {
|
|
52
|
+
const parsedResult = [];
|
|
53
|
+
scannerResults.forEach((scannerResult) => {
|
|
54
|
+
const comments = [];
|
|
55
|
+
scannerResult.violations.forEach((violation) => {
|
|
56
|
+
const contentRaw = getCommentBody(violation);
|
|
57
|
+
comments.push({
|
|
58
|
+
lineNumber: parseInt(violation.line, 10),
|
|
59
|
+
content: contentRaw,
|
|
60
|
+
startLineNumber: parseInt(violation.line, 10),
|
|
61
|
+
startColumnNumber: parseInt(violation.column, 10),
|
|
62
|
+
endLineNumber: parseInt(violation.endLine, 10),
|
|
63
|
+
endColumnNumber: parseInt(violation.endColumn, 10),
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
let fileName = scannerResult.fileName;
|
|
67
|
+
if (diffFolderName && fileName.startsWith(diffFolderName)) {
|
|
68
|
+
fileName = fileName.split(diffFolderName)[1];
|
|
69
|
+
}
|
|
70
|
+
parsedResult.push({
|
|
71
|
+
fileName,
|
|
72
|
+
comments,
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
return parsedResult;
|
|
76
|
+
}
|
|
77
|
+
exports.parseScannerOutput = parseScannerOutput;
|
|
78
|
+
function filterToNewCommentsToPost(CodeReviewCommentsByFilesToPost, existingCommentsByFiles) {
|
|
79
|
+
let newCommentsByFilesToPost = [];
|
|
80
|
+
if (CodeReviewCommentsByFilesToPost && CodeReviewCommentsByFilesToPost.length > 0) {
|
|
81
|
+
if (existingCommentsByFiles && existingCommentsByFiles.length > 0) {
|
|
82
|
+
CodeReviewCommentsByFilesToPost.forEach((codeReviewCommentsByFile) => {
|
|
83
|
+
const matchedExistingCommentsByFile = existingCommentsByFiles.find((eachCommentsByFile) => eachCommentsByFile.fileName === codeReviewCommentsByFile.fileName);
|
|
84
|
+
if (matchedExistingCommentsByFile) {
|
|
85
|
+
const tempNewCommentsByFileToPost = {
|
|
86
|
+
fileName: matchedExistingCommentsByFile.fileName,
|
|
87
|
+
comments: [],
|
|
88
|
+
};
|
|
89
|
+
codeReviewCommentsByFile.comments.forEach((reviewComment) => {
|
|
90
|
+
const matchedComment = matchedExistingCommentsByFile.comments.find((comment) =>
|
|
91
|
+
// eslint-disable-next-line no-control-regex
|
|
92
|
+
comment.content.replace(new RegExp('\n', 'g'), '\\n') === reviewComment.content &&
|
|
93
|
+
comment.lineNumber === reviewComment.lineNumber);
|
|
94
|
+
if (!matchedComment) {
|
|
95
|
+
tempNewCommentsByFileToPost.comments.push(reviewComment);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
if (tempNewCommentsByFileToPost.comments.length > 0) {
|
|
99
|
+
newCommentsByFilesToPost.push(tempNewCommentsByFileToPost);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
newCommentsByFilesToPost.push(codeReviewCommentsByFile);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
newCommentsByFilesToPost = CodeReviewCommentsByFilesToPost;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return newCommentsByFilesToPost;
|
|
112
|
+
}
|
|
113
|
+
exports.filterToNewCommentsToPost = filterToNewCommentsToPost;
|
|
114
|
+
function getCodeReviewFromFile(filename) {
|
|
115
|
+
let scannerResults;
|
|
116
|
+
try {
|
|
117
|
+
if (filename && (0, fs_1.existsSync)(filename)) {
|
|
118
|
+
const rawdata = (0, fs_1.readFileSync)(filename, 'utf8');
|
|
119
|
+
try {
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
121
|
+
scannerResults = JSON.parse(rawdata);
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
throw new core_1.SfError(messages.getMessage('error.CodeReviewInput'), 'CodeReviewInputError');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
throw new core_1.SfError(messages.getMessage('error.CodeReviewFile'), 'CodeReviewInputError');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
throw new core_1.SfError(messages.getMessage('error.CodeReviewFile'), 'CodeReviewInputError');
|
|
133
|
+
}
|
|
134
|
+
return scannerResults;
|
|
135
|
+
}
|
|
136
|
+
exports.getCodeReviewFromFile = getCodeReviewFromFile;
|
|
137
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
138
|
+
function printMessage(message, messageType = MessageType.Info, loggerLevel) {
|
|
139
|
+
if (messageType === MessageType.Info && loggerLevel <= core_1.LoggerLevel.INFO) {
|
|
140
|
+
// eslint-disable-next-line no-console
|
|
141
|
+
console.log(chalk.bgBlueBright.blue.bold(message));
|
|
142
|
+
}
|
|
143
|
+
else if (messageType === MessageType.Success && loggerLevel <= core_1.LoggerLevel.INFO) {
|
|
144
|
+
// eslint-disable-next-line no-console
|
|
145
|
+
console.log(chalk.bgGreenBright.green.bold(message));
|
|
146
|
+
}
|
|
147
|
+
else if (messageType === MessageType.Debug && loggerLevel <= core_1.LoggerLevel.DEBUG) {
|
|
148
|
+
// eslint-disable-next-line no-console
|
|
149
|
+
console.log(chalk.cyan.bold(message));
|
|
150
|
+
}
|
|
151
|
+
else if (messageType === MessageType.Warn && loggerLevel <= core_1.LoggerLevel.WARN) {
|
|
152
|
+
// eslint-disable-next-line no-console
|
|
153
|
+
console.log(chalk.bgYellowBright.yellow.bold(message));
|
|
154
|
+
}
|
|
155
|
+
else if (messageType === MessageType.Error && loggerLevel <= core_1.LoggerLevel.ERROR) {
|
|
156
|
+
// eslint-disable-next-line no-console
|
|
157
|
+
console.log(chalk.bgRedBright.red.bold(message));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
exports.printMessage = printMessage;
|
|
161
|
+
function filterCommentsToDiff(diffFilesLinesadded, newCommentsByFilesToPost) {
|
|
162
|
+
const newCommentsByFilesToPostFilteredToDiff = [];
|
|
163
|
+
newCommentsByFilesToPost.forEach((commentsByFile) => {
|
|
164
|
+
let commentsByFileToPost;
|
|
165
|
+
const commentsByFilesToPost = newCommentsByFilesToPostFilteredToDiff.filter((eachElement) => eachElement.fileName === commentsByFile.fileName);
|
|
166
|
+
if (commentsByFilesToPost && commentsByFilesToPost.length > 0) {
|
|
167
|
+
commentsByFileToPost = commentsByFilesToPost[0];
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
commentsByFileToPost = { fileName: commentsByFile.fileName, comments: [] };
|
|
171
|
+
}
|
|
172
|
+
const matchingDiff = diffFilesLinesadded.filter((diffFile) => diffFile.fileName === commentsByFile.fileName);
|
|
173
|
+
if (matchingDiff && matchingDiff.length > 0) {
|
|
174
|
+
commentsByFile.comments.forEach((comment) => {
|
|
175
|
+
const index = matchingDiff[0].linesAdded.findIndex((lineNumber) => lineNumber === comment.lineNumber);
|
|
176
|
+
if (index > -1) {
|
|
177
|
+
commentsByFileToPost.comments.push(comment);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
if (commentsByFileToPost.comments.length > 0) {
|
|
182
|
+
newCommentsByFilesToPostFilteredToDiff.push(commentsByFileToPost);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
return newCommentsByFilesToPostFilteredToDiff;
|
|
186
|
+
}
|
|
187
|
+
exports.filterCommentsToDiff = filterCommentsToDiff;
|
|
188
|
+
async function parseDiff(gitFolderPath, destinationBranchName, sourceBranchName) {
|
|
189
|
+
const diffFilesLinesadded = [];
|
|
190
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
|
191
|
+
const parsedDiff = await parser(gitFolderPath, destinationBranchName, sourceBranchName);
|
|
192
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
193
|
+
parsedDiff.forEach((eachFile) => {
|
|
194
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
195
|
+
let addedLine = eachFile.lines.filter((line) => {
|
|
196
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return
|
|
197
|
+
if (line.type === 'add')
|
|
198
|
+
return line;
|
|
199
|
+
});
|
|
200
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
201
|
+
if (addedLine && addedLine.length > 0) {
|
|
202
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
|
|
203
|
+
addedLine = addedLine.map((line) => line.ln);
|
|
204
|
+
}
|
|
205
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
206
|
+
diffFilesLinesadded.push({ fileName: eachFile.to, linesAdded: addedLine });
|
|
207
|
+
});
|
|
208
|
+
return diffFilesLinesadded;
|
|
209
|
+
}
|
|
210
|
+
exports.parseDiff = parseDiff;
|
|
211
|
+
function removeRefHeadFromBranchName(branchRefName) {
|
|
212
|
+
return branchRefName.startsWith('refs/heads/') ? branchRefName.substring(11) : branchRefName;
|
|
213
|
+
}
|
|
214
|
+
exports.removeRefHeadFromBranchName = removeRefHeadFromBranchName;
|
|
215
|
+
//# sourceMappingURL=utils.js.map
|