@aws/lsp-codewhisperer 0.0.3
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/CHANGELOG.md +7 -0
- package/README.md +19 -0
- package/out/client/sigv4/codewhisperer.d.ts +3 -0
- package/out/client/sigv4/codewhisperer.js +14 -0
- package/out/client/sigv4/codewhisperer.js.map +1 -0
- package/out/client/sigv4/service.json +346 -0
- package/out/client/token/bearer-token-service.json +1627 -0
- package/out/client/token/codewhisperer.d.ts +14 -0
- package/out/client/token/codewhisperer.js +23 -0
- package/out/client/token/codewhisperer.js.map +1 -0
- package/out/index.d.ts +2 -0
- package/out/index.js +19 -0
- package/out/index.js.map +1 -0
- package/out/language-server/auto-trigger/autoTrigger.d.ts +38 -0
- package/out/language-server/auto-trigger/autoTrigger.js +119 -0
- package/out/language-server/auto-trigger/autoTrigger.js.map +1 -0
- package/out/language-server/auto-trigger/autoTrigger.test.d.ts +1 -0
- package/out/language-server/auto-trigger/autoTrigger.test.js +82 -0
- package/out/language-server/auto-trigger/autoTrigger.test.js.map +1 -0
- package/out/language-server/auto-trigger/coefficients.json +405 -0
- package/out/language-server/codeWhispererSecurityScanServer.d.ts +4 -0
- package/out/language-server/codeWhispererSecurityScanServer.js +76 -0
- package/out/language-server/codeWhispererSecurityScanServer.js.map +1 -0
- package/out/language-server/codeWhispererServer.d.ts +7 -0
- package/out/language-server/codeWhispererServer.js +425 -0
- package/out/language-server/codeWhispererServer.js.map +1 -0
- package/out/language-server/codeWhispererServer.test.d.ts +1 -0
- package/out/language-server/codeWhispererServer.test.js +1218 -0
- package/out/language-server/codeWhispererServer.test.js.map +1 -0
- package/out/language-server/codeWhispererService.d.ts +84 -0
- package/out/language-server/codeWhispererService.js +168 -0
- package/out/language-server/codeWhispererService.js.map +1 -0
- package/out/language-server/dependencyGraph/commonUtil.d.ts +2 -0
- package/out/language-server/dependencyGraph/commonUtil.js +20 -0
- package/out/language-server/dependencyGraph/commonUtil.js.map +1 -0
- package/out/language-server/dependencyGraph/constants.d.ts +2 -0
- package/out/language-server/dependencyGraph/constants.js +6 -0
- package/out/language-server/dependencyGraph/constants.js.map +1 -0
- package/out/language-server/dependencyGraph/csharpDependencyGraph.d.ts +27 -0
- package/out/language-server/dependencyGraph/csharpDependencyGraph.js +145 -0
- package/out/language-server/dependencyGraph/csharpDependencyGraph.js.map +1 -0
- package/out/language-server/dependencyGraph/csharpDependencyGraph.test.d.ts +1 -0
- package/out/language-server/dependencyGraph/csharpDependencyGraph.test.js +341 -0
- package/out/language-server/dependencyGraph/csharpDependencyGraph.test.js.map +1 -0
- package/out/language-server/dependencyGraph/dependencyGraph.d.ts +125 -0
- package/out/language-server/dependencyGraph/dependencyGraph.js +152 -0
- package/out/language-server/dependencyGraph/dependencyGraph.js.map +1 -0
- package/out/language-server/dependencyGraph/dependencyGraphFactory.d.ts +15 -0
- package/out/language-server/dependencyGraph/dependencyGraphFactory.js +22 -0
- package/out/language-server/dependencyGraph/dependencyGraphFactory.js.map +1 -0
- package/out/language-server/languageDetection.d.ts +3 -0
- package/out/language-server/languageDetection.js +56 -0
- package/out/language-server/languageDetection.js.map +1 -0
- package/out/language-server/mergeRightUtils.d.ts +6 -0
- package/out/language-server/mergeRightUtils.js +37 -0
- package/out/language-server/mergeRightUtils.js.map +1 -0
- package/out/language-server/mergeRightUtils.test.d.ts +1 -0
- package/out/language-server/mergeRightUtils.test.js +53 -0
- package/out/language-server/mergeRightUtils.test.js.map +1 -0
- package/out/language-server/proxy-server.d.ts +2 -0
- package/out/language-server/proxy-server.js +35 -0
- package/out/language-server/proxy-server.js.map +1 -0
- package/out/language-server/securityScan/securityScanHandler.d.ts +17 -0
- package/out/language-server/securityScan/securityScanHandler.js +139 -0
- package/out/language-server/securityScan/securityScanHandler.js.map +1 -0
- package/out/language-server/securityScan/securityScanHandler.test.d.ts +1 -0
- package/out/language-server/securityScan/securityScanHandler.test.js +170 -0
- package/out/language-server/securityScan/securityScanHandler.test.js.map +1 -0
- package/out/language-server/securityScan/types.d.ts +49 -0
- package/out/language-server/securityScan/types.js +3 -0
- package/out/language-server/securityScan/types.js.map +1 -0
- package/out/language-server/session/sessionManager.d.ts +91 -0
- package/out/language-server/session/sessionManager.js +234 -0
- package/out/language-server/session/sessionManager.js.map +1 -0
- package/out/language-server/session/sessionManager.test.d.ts +1 -0
- package/out/language-server/session/sessionManager.test.js +584 -0
- package/out/language-server/session/sessionManager.test.js.map +1 -0
- package/out/language-server/telemetry/codePercentage.d.ts +17 -0
- package/out/language-server/telemetry/codePercentage.js +82 -0
- package/out/language-server/telemetry/codePercentage.js.map +1 -0
- package/out/language-server/telemetry/codePercentage.test.d.ts +1 -0
- package/out/language-server/telemetry/codePercentage.test.js +85 -0
- package/out/language-server/telemetry/codePercentage.test.js.map +1 -0
- package/out/language-server/telemetry/types.d.ts +68 -0
- package/out/language-server/telemetry/types.js +3 -0
- package/out/language-server/telemetry/types.js.map +1 -0
- package/out/language-server/telemetry/userTriggerDecision.test.d.ts +1 -0
- package/out/language-server/telemetry/userTriggerDecision.test.js +946 -0
- package/out/language-server/telemetry/userTriggerDecision.test.js.map +1 -0
- package/out/language-server/telemetry.test.d.ts +1 -0
- package/out/language-server/telemetry.test.js +96 -0
- package/out/language-server/telemetry.test.js.map +1 -0
- package/out/language-server/testUtils.d.ts +69 -0
- package/out/language-server/testUtils.js +90 -0
- package/out/language-server/testUtils.js.map +1 -0
- package/out/language-server/utils.d.ts +6 -0
- package/out/language-server/utils.js +31 -0
- package/out/language-server/utils.js.map +1 -0
- package/package.json +53 -0
- package/script/generateServiceClient.ts +242 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DependencyGraphFactory = void 0;
|
|
4
|
+
const csharpDependencyGraph_1 = require("./csharpDependencyGraph");
|
|
5
|
+
const languageMap = {
|
|
6
|
+
csharp: csharpDependencyGraph_1.CsharpDependencyGraph,
|
|
7
|
+
};
|
|
8
|
+
class DependencyGraphFactory {
|
|
9
|
+
static getDependencyGraphFromFileExtensions(fileName) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
static getDependencyGraph(document, workspace) {
|
|
13
|
+
switch (document.languageId.toLowerCase()) {
|
|
14
|
+
case 'csharp':
|
|
15
|
+
return new languageMap['csharp'](workspace);
|
|
16
|
+
default:
|
|
17
|
+
return this.getDependencyGraphFromFileExtensions(document.uri);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.DependencyGraphFactory = DependencyGraphFactory;
|
|
22
|
+
//# sourceMappingURL=dependencyGraphFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependencyGraphFactory.js","sourceRoot":"","sources":["../../../src/language-server/dependencyGraph/dependencyGraphFactory.ts"],"names":[],"mappings":";;;AAEA,mEAA+D;AAE/D,MAAM,WAAW,GAAG;IAChB,MAAM,EAAE,6CAAqB;CACvB,CAAA;AAOV,MAAa,sBAAsB;IAC/B,MAAM,CAAC,oCAAoC,CAAiB,QAAgB;QACxE,OAAO,SAAS,CAAA;IACpB,CAAC;IAED,MAAM,CAAC,kBAAkB,CAAiB,QAAsB,EAAE,SAA8B;QAC5F,QAAQ,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;YACxC,KAAK,QAAQ;gBACT,OAAO,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAA;YAC/C;gBACI,OAAO,IAAI,CAAC,oCAAoC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;QACtE,CAAC;IACL,CAAC;CACJ;AAbD,wDAaC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
2
|
+
export type CodewhispererLanguage = 'java' | 'python' | 'jsx' | 'javascript' | 'typescript' | 'tsx' | 'csharp' | 'c' | 'cpp' | 'cpp' | 'go' | 'kotlin' | 'php' | 'ruby' | 'rust' | 'scala' | 'shell' | 'shell' | 'sql' | 'plaintext';
|
|
3
|
+
export declare const getSupportedLanguageId: (textDocument: TextDocument | undefined) => CodewhispererLanguage | undefined;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSupportedLanguageId = void 0;
|
|
4
|
+
// This will be extended as more language features
|
|
5
|
+
// are integrated into the language server and clients.
|
|
6
|
+
// See: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocumentItem
|
|
7
|
+
const supportedFileTypes = ['c', 'cpp', 'csharp', 'javascript', 'python', 'typescript'];
|
|
8
|
+
const supportedExtensions = {
|
|
9
|
+
'.c': 'c',
|
|
10
|
+
'.h': 'c',
|
|
11
|
+
'.cpp': 'cpp',
|
|
12
|
+
'.hpp': 'cpp',
|
|
13
|
+
'.cs': 'csharp',
|
|
14
|
+
'.js': 'javascript',
|
|
15
|
+
'.py': 'python',
|
|
16
|
+
'.ts': 'typescript',
|
|
17
|
+
};
|
|
18
|
+
const getSupportedLanguageId = (textDocument) => {
|
|
19
|
+
if (!textDocument) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const languageId = getCodeWhispererLanguageIdByTextDocumentLanguageId(textDocument.languageId);
|
|
23
|
+
if (languageId !== undefined) {
|
|
24
|
+
return languageId;
|
|
25
|
+
}
|
|
26
|
+
for (const extension in supportedExtensions) {
|
|
27
|
+
if (textDocument.uri.endsWith(extension)) {
|
|
28
|
+
return supportedExtensions[extension];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
exports.getSupportedLanguageId = getSupportedLanguageId;
|
|
33
|
+
/**
|
|
34
|
+
* Used to map different IDE values for TextDocument languageIds to CodeWhisperer languageIds.
|
|
35
|
+
* Examples of the CodeWhisperer defined language ids can be found in service-2.json, near "ProgrammingLanguageLanguageNameString"
|
|
36
|
+
* @param textDocumentLanguageId Value of the TextDocument's language id, provided by the IDE
|
|
37
|
+
* @returns Corresponding CodeWhisperer language id
|
|
38
|
+
*/
|
|
39
|
+
function getCodeWhispererLanguageIdByTextDocumentLanguageId(textDocumentLanguageId) {
|
|
40
|
+
if (textDocumentLanguageId === undefined) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
if (supportedFileTypes.includes(textDocumentLanguageId)) {
|
|
44
|
+
return textDocumentLanguageId;
|
|
45
|
+
}
|
|
46
|
+
// IDEs can identify a file's languageId using non-standardized values
|
|
47
|
+
// Eg: 'CSHARP', 'CSharp' => 'csharp'
|
|
48
|
+
// Try to map case-insensitive matches to increase the likelihood of supporting the file in an IDE.
|
|
49
|
+
for (const supportedFileType of supportedFileTypes) {
|
|
50
|
+
if (textDocumentLanguageId.toLowerCase() === supportedFileType.toLowerCase()) {
|
|
51
|
+
return supportedFileType;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=languageDetection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"languageDetection.js","sourceRoot":"","sources":["../../src/language-server/languageDetection.ts"],"names":[],"mappings":";;;AAwBA,kDAAkD;AAClD,uDAAuD;AACvD,oHAAoH;AACpH,MAAM,kBAAkB,GAA4B,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAA;AAChH,MAAM,mBAAmB,GAA6C;IAClE,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,KAAK;IACb,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,YAAY;IACnB,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,YAAY;CACtB,CAAA;AAEM,MAAM,sBAAsB,GAAG,CAAC,YAAsC,EAAqC,EAAE;IAChH,IAAI,CAAC,YAAY,EAAE,CAAC;QAChB,OAAM;IACV,CAAC;IAED,MAAM,UAAU,GAAG,kDAAkD,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA;IAC9F,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,UAAU,CAAA;IACrB,CAAC;IAED,KAAK,MAAM,SAAS,IAAI,mBAAmB,EAAE,CAAC;QAC1C,IAAI,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,OAAO,mBAAmB,CAAC,SAAS,CAAC,CAAA;QACzC,CAAC;IACL,CAAC;AACL,CAAC,CAAA;AAfY,QAAA,sBAAsB,0BAelC;AAED;;;;;GAKG;AACH,SAAS,kDAAkD,CACvD,sBAAsD;IAEtD,IAAI,sBAAsB,KAAK,SAAS,EAAE,CAAC;QACvC,OAAO,SAAS,CAAA;IACpB,CAAC;IAED,IAAI,kBAAkB,CAAC,QAAQ,CAAC,sBAA+C,CAAC,EAAE,CAAC;QAC/E,OAAO,sBAA+C,CAAA;IAC1D,CAAC;IAED,sEAAsE;IACtE,qCAAqC;IACrC,mGAAmG;IACnG,KAAK,MAAM,iBAAiB,IAAI,kBAAkB,EAAE,CAAC;QACjD,IAAI,sBAAsB,CAAC,WAAW,EAAE,KAAK,iBAAiB,CAAC,WAAW,EAAE,EAAE,CAAC;YAC3E,OAAO,iBAA0C,CAAA;QACrD,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAA;AACpB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the longest overlap between the Suffix of firstString and Prefix of second string
|
|
3
|
+
* getPrefixSuffixOverlap("adwg31", "31ggrs") = "31"
|
|
4
|
+
*/
|
|
5
|
+
export declare function getPrefixSuffixOverlap(firstString: string, secondString: string): string;
|
|
6
|
+
export declare function truncateOverlapWithRightContext(rightFileContent: string, suggestion: string): string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.truncateOverlapWithRightContext = exports.getPrefixSuffixOverlap = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Returns the longest overlap between the Suffix of firstString and Prefix of second string
|
|
6
|
+
* getPrefixSuffixOverlap("adwg31", "31ggrs") = "31"
|
|
7
|
+
*/
|
|
8
|
+
function getPrefixSuffixOverlap(firstString, secondString) {
|
|
9
|
+
let i = Math.min(firstString.length, secondString.length);
|
|
10
|
+
while (i > 0) {
|
|
11
|
+
if (secondString.slice(0, i) === firstString.slice(-i)) {
|
|
12
|
+
break;
|
|
13
|
+
}
|
|
14
|
+
i--;
|
|
15
|
+
}
|
|
16
|
+
return secondString.slice(0, i);
|
|
17
|
+
}
|
|
18
|
+
exports.getPrefixSuffixOverlap = getPrefixSuffixOverlap;
|
|
19
|
+
function truncateOverlapWithRightContext(rightFileContent, suggestion) {
|
|
20
|
+
const trimmedSuggestion = suggestion.trim();
|
|
21
|
+
// limit of 5000 for right context matching
|
|
22
|
+
const rightContext = rightFileContent
|
|
23
|
+
.substring(0, 5000)
|
|
24
|
+
.replaceAll('\r\n', '\n')
|
|
25
|
+
.replace(/^[^\S\n]+/, ''); // remove leading tabs and whitespaces
|
|
26
|
+
const overlap = getPrefixSuffixOverlap(trimmedSuggestion, rightContext);
|
|
27
|
+
const overlapIndex = suggestion.lastIndexOf(overlap);
|
|
28
|
+
if (overlapIndex >= 0) {
|
|
29
|
+
const truncated = suggestion.slice(0, overlapIndex);
|
|
30
|
+
return truncated.trim().length ? truncated : '';
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
return suggestion;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.truncateOverlapWithRightContext = truncateOverlapWithRightContext;
|
|
37
|
+
//# sourceMappingURL=mergeRightUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeRightUtils.js","sourceRoot":"","sources":["../../src/language-server/mergeRightUtils.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,SAAgB,sBAAsB,CAAC,WAAmB,EAAE,YAAoB;IAC5E,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,CAAA;IACzD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACX,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,MAAK;QACT,CAAC;QACD,CAAC,EAAE,CAAA;IACP,CAAC;IACD,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACnC,CAAC;AATD,wDASC;AAED,SAAgB,+BAA+B,CAAC,gBAAwB,EAAE,UAAkB;IACxF,MAAM,iBAAiB,GAAG,UAAU,CAAC,IAAI,EAAE,CAAA;IAC3C,2CAA2C;IAC3C,MAAM,YAAY,GAAG,gBAAgB;SAChC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC;SAClB,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC;SACxB,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA,CAAC,sCAAsC;IACpE,MAAM,OAAO,GAAG,sBAAsB,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAA;IACvE,MAAM,YAAY,GAAG,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IACpD,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAA;QACnD,OAAO,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAA;IACnD,CAAC;SAAM,CAAC;QACJ,OAAO,UAAU,CAAA;IACrB,CAAC;AACL,CAAC;AAfD,0EAeC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const mergeRightUtils_1 = require("./mergeRightUtils");
|
|
4
|
+
const testUtils_1 = require("./testUtils");
|
|
5
|
+
const assert = require("assert");
|
|
6
|
+
describe('Merge Right Utils', () => {
|
|
7
|
+
const HELLO_WORLD = `Console.WriteLine("Hello World!");`;
|
|
8
|
+
it('get prefix suffix overlap works as expected', () => {
|
|
9
|
+
const result = (0, mergeRightUtils_1.getPrefixSuffixOverlap)('adwg31', '31ggrs');
|
|
10
|
+
assert.deepEqual(result, '31');
|
|
11
|
+
});
|
|
12
|
+
it('should return empty suggestion when right context equals line content ', () => {
|
|
13
|
+
const result = (0, mergeRightUtils_1.truncateOverlapWithRightContext)(HELLO_WORLD, HELLO_WORLD);
|
|
14
|
+
assert.deepEqual(result, '');
|
|
15
|
+
});
|
|
16
|
+
it('should return empty suggestion when right context equals file content', () => {
|
|
17
|
+
// Without trimStart, this test would fail because the function doesn't trim leading new line from right context
|
|
18
|
+
const result = (0, mergeRightUtils_1.truncateOverlapWithRightContext)(testUtils_1.HELLO_WORLD_IN_CSHARP.trimStart(), testUtils_1.HELLO_WORLD_IN_CSHARP);
|
|
19
|
+
assert.deepEqual(result, '');
|
|
20
|
+
});
|
|
21
|
+
it('should not handle the case where right context fully matches suggestion but starts with a newline ', () => {
|
|
22
|
+
const result = (0, mergeRightUtils_1.truncateOverlapWithRightContext)('\n' + testUtils_1.HELLO_WORLD_IN_CSHARP, testUtils_1.HELLO_WORLD_IN_CSHARP);
|
|
23
|
+
// Even though right context and suggestion are equal, the newline of right context doesn't get trimmed while the newline of suggestion gets trimmed
|
|
24
|
+
// As a result, we end up with no overlap
|
|
25
|
+
assert.deepEqual(result, testUtils_1.HELLO_WORLD_IN_CSHARP);
|
|
26
|
+
});
|
|
27
|
+
it('should return truncated suggestion when right context matches end of the suggestion', () => {
|
|
28
|
+
// File contents will be `nsole.WriteLine("Hello World!");`
|
|
29
|
+
// Suggestion will be the full HELLO_WORLD
|
|
30
|
+
// Final truncated result should be the first two letters of HELLO_WORLD
|
|
31
|
+
const result = (0, mergeRightUtils_1.truncateOverlapWithRightContext)(HELLO_WORLD.substring(2), HELLO_WORLD);
|
|
32
|
+
assert.deepEqual(result, HELLO_WORLD.substring(0, 2));
|
|
33
|
+
});
|
|
34
|
+
it('should trim right-context tabs and whitespaces until first newline', () => {
|
|
35
|
+
const suggestion = '{\n return a + b;\n }';
|
|
36
|
+
const rightContent = ' \n }\n\n }\n}';
|
|
37
|
+
const expected_result = '{\n return a + b;';
|
|
38
|
+
const result = (0, mergeRightUtils_1.truncateOverlapWithRightContext)(rightContent, suggestion);
|
|
39
|
+
assert.deepEqual(result, expected_result);
|
|
40
|
+
});
|
|
41
|
+
it('should handle different line endings', () => {
|
|
42
|
+
const suggestion = '{\n return a + b;\n }';
|
|
43
|
+
const rightContent = '\r\n }\r\n}\r\n}';
|
|
44
|
+
const expected_result = '{\n return a + b;';
|
|
45
|
+
const result = (0, mergeRightUtils_1.truncateOverlapWithRightContext)(rightContent, suggestion);
|
|
46
|
+
assert.deepEqual(result, expected_result);
|
|
47
|
+
});
|
|
48
|
+
it('should handle windows line endings for files', () => {
|
|
49
|
+
const result = (0, mergeRightUtils_1.truncateOverlapWithRightContext)(testUtils_1.HELLO_WORLD_WITH_WINDOWS_ENDING, testUtils_1.HELLO_WORLD_WITH_WINDOWS_ENDING.replaceAll('\r', ''));
|
|
50
|
+
assert.deepEqual(result, '');
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=mergeRightUtils.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeRightUtils.test.js","sourceRoot":"","sources":["../../src/language-server/mergeRightUtils.test.ts"],"names":[],"mappings":";;AAAA,uDAA2F;AAC3F,2CAAoF;AACpF,iCAAiC;AAEjC,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IAC/B,MAAM,WAAW,GAAG,oCAAoC,CAAA;IAExD,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACnD,MAAM,MAAM,GAAG,IAAA,wCAAsB,EAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QACzD,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IAClC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAC9E,MAAM,MAAM,GAAG,IAAA,iDAA+B,EAAC,WAAW,EAAE,WAAW,CAAC,CAAA;QACxE,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAChC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC7E,gHAAgH;QAChH,MAAM,MAAM,GAAG,IAAA,iDAA+B,EAAC,iCAAqB,CAAC,SAAS,EAAE,EAAE,iCAAqB,CAAC,CAAA;QACxG,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAChC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oGAAoG,EAAE,GAAG,EAAE;QAC1G,MAAM,MAAM,GAAG,IAAA,iDAA+B,EAAC,IAAI,GAAG,iCAAqB,EAAE,iCAAqB,CAAC,CAAA;QACnG,oJAAoJ;QACpJ,yCAAyC;QACzC,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,iCAAqB,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qFAAqF,EAAE,GAAG,EAAE;QAC3F,2DAA2D;QAC3D,0CAA0C;QAC1C,wEAAwE;QACxE,MAAM,MAAM,GAAG,IAAA,iDAA+B,EAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAA;QAErF,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC1E,MAAM,UAAU,GAAG,yCAAyC,CAAA;QAC5D,MAAM,YAAY,GAAG,gCAAgC,CAAA;QACrD,MAAM,eAAe,GAAG,8BAA8B,CAAA;QACtD,MAAM,MAAM,GAAG,IAAA,iDAA+B,EAAC,YAAY,EAAE,UAAU,CAAC,CAAA;QAExE,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC5C,MAAM,UAAU,GAAG,yCAAyC,CAAA;QAC5D,MAAM,YAAY,GAAG,yBAAyB,CAAA;QAC9C,MAAM,eAAe,GAAG,8BAA8B,CAAA;QACtD,MAAM,MAAM,GAAG,IAAA,iDAA+B,EAAC,YAAY,EAAE,UAAU,CAAC,CAAA;QAExE,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACpD,MAAM,MAAM,GAAG,IAAA,iDAA+B,EAC1C,2CAA+B,EAC/B,2CAA+B,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CACvD,CAAA;QACD,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAChC,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CodeWhispererSecurityScanServerTokenProxy = exports.CodeWhispererServerTokenProxy = void 0;
|
|
4
|
+
const codeWhispererSecurityScanServer_1 = require("./codeWhispererSecurityScanServer");
|
|
5
|
+
const codeWhispererServer_1 = require("./codeWhispererServer");
|
|
6
|
+
const codeWhispererService_1 = require("./codeWhispererService");
|
|
7
|
+
exports.CodeWhispererServerTokenProxy = (0, codeWhispererServer_1.CodewhispererServerFactory)(credentialsProvider => {
|
|
8
|
+
let additionalAwsConfig = {};
|
|
9
|
+
const proxyUrl = process.env.HTTPS_PROXY ?? process.env.https_proxy;
|
|
10
|
+
if (proxyUrl) {
|
|
11
|
+
const { getProxyHttpAgent } = require('proxy-http-agent');
|
|
12
|
+
const proxyAgent = getProxyHttpAgent({
|
|
13
|
+
proxy: proxyUrl,
|
|
14
|
+
});
|
|
15
|
+
additionalAwsConfig = {
|
|
16
|
+
proxy: proxyAgent,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return new codeWhispererService_1.CodeWhispererServiceToken(credentialsProvider, additionalAwsConfig);
|
|
20
|
+
});
|
|
21
|
+
exports.CodeWhispererSecurityScanServerTokenProxy = (0, codeWhispererSecurityScanServer_1.SecurityScanServerToken)(credentialsProvider => {
|
|
22
|
+
let additionalAwsConfig = {};
|
|
23
|
+
const proxyUrl = process.env.HTTPS_PROXY ?? process.env.https_proxy;
|
|
24
|
+
if (proxyUrl) {
|
|
25
|
+
const { getProxyHttpAgent } = require('proxy-http-agent');
|
|
26
|
+
const proxyAgent = getProxyHttpAgent({
|
|
27
|
+
proxy: proxyUrl,
|
|
28
|
+
});
|
|
29
|
+
additionalAwsConfig = {
|
|
30
|
+
proxy: proxyAgent,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return new codeWhispererService_1.CodeWhispererServiceToken(credentialsProvider, additionalAwsConfig);
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=proxy-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-server.js","sourceRoot":"","sources":["../../src/language-server/proxy-server.ts"],"names":[],"mappings":";;;AAAA,uFAA2E;AAC3E,+DAAkE;AAClE,iEAAkE;AAErD,QAAA,6BAA6B,GAAG,IAAA,gDAA0B,EAAC,mBAAmB,CAAC,EAAE;IAC1F,IAAI,mBAAmB,GAAG,EAAE,CAAA;IAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAA;IAEnE,IAAI,QAAQ,EAAE,CAAC;QACX,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;QACzD,MAAM,UAAU,GAAG,iBAAiB,CAAC;YACjC,KAAK,EAAE,QAAQ;SAClB,CAAC,CAAA;QACF,mBAAmB,GAAG;YAClB,KAAK,EAAE,UAAU;SACpB,CAAA;IACL,CAAC;IACD,OAAO,IAAI,gDAAyB,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAA;AAClF,CAAC,CAAC,CAAA;AAEW,QAAA,yCAAyC,GAAG,IAAA,yDAAuB,EAAC,mBAAmB,CAAC,EAAE;IACnG,IAAI,mBAAmB,GAAG,EAAE,CAAA;IAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAA;IAEnE,IAAI,QAAQ,EAAE,CAAC;QACX,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;QACzD,MAAM,UAAU,GAAG,iBAAiB,CAAC;YACjC,KAAK,EAAE,QAAQ;SAClB,CAAC,CAAA;QACF,mBAAmB,GAAG;YAClB,KAAK,EAAE,UAAU;SACpB,CAAA;IACL,CAAC;IACD,OAAO,IAAI,gDAAyB,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAA;AAClF,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Workspace } from '@aws/language-server-runtimes/out/features';
|
|
3
|
+
import { ArtifactMap, CreateUploadUrlResponse } from '../../client/token/codewhispererbearertokenclient';
|
|
4
|
+
import { CodeWhispererServiceToken } from '../codeWhispererService';
|
|
5
|
+
import { AggregatedCodeScanIssue, RawCodeScanIssue } from './types';
|
|
6
|
+
export declare class SecurityScanHandler {
|
|
7
|
+
private client;
|
|
8
|
+
private workspace;
|
|
9
|
+
constructor(client: CodeWhispererServiceToken, workspace: Workspace);
|
|
10
|
+
getMd5(content: Buffer): string;
|
|
11
|
+
createCodeResourcePresignedUrlHandler(zipContent: Buffer): Promise<ArtifactMap>;
|
|
12
|
+
uploadArtifactToS3(zipBuffer: Buffer, resp: CreateUploadUrlResponse): Promise<import("got").Response<string>>;
|
|
13
|
+
createScanJob(artifactMap: ArtifactMap, languageName: string): Promise<import("aws-sdk/lib/request").PromiseResult<import("../../client/token/codewhispererbearertokenclient").StartCodeAnalysisResponse, import("aws-sdk").AWSError>>;
|
|
14
|
+
pollScanJobStatus(jobId: string): Promise<string>;
|
|
15
|
+
listScanResults(jobId: string, projectPath: string): Promise<AggregatedCodeScanIssue[]>;
|
|
16
|
+
mapToAggregatedList(codeScanIssueMap: Map<string, RawCodeScanIssue[]>, aggregatedCodeScanIssueList: AggregatedCodeScanIssue[], json: string, projectPath: string): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SecurityScanHandler = void 0;
|
|
4
|
+
const got_1 = require("got");
|
|
5
|
+
const js_md5_1 = require("js-md5");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const commonUtil_1 = require("../dependencyGraph/commonUtil");
|
|
8
|
+
class SecurityScanHandler {
|
|
9
|
+
constructor(client, workspace) {
|
|
10
|
+
this.client = client;
|
|
11
|
+
this.workspace = workspace;
|
|
12
|
+
}
|
|
13
|
+
getMd5(content) {
|
|
14
|
+
return js_md5_1.md5.base64(content);
|
|
15
|
+
}
|
|
16
|
+
async createCodeResourcePresignedUrlHandler(zipContent) {
|
|
17
|
+
const request = {
|
|
18
|
+
contentMd5: this.getMd5(zipContent),
|
|
19
|
+
artifactType: 'SourceCode',
|
|
20
|
+
};
|
|
21
|
+
const response = await this.client.createUploadUrl(request);
|
|
22
|
+
await this.uploadArtifactToS3(zipContent, response);
|
|
23
|
+
const artifactMap = {
|
|
24
|
+
SourceCode: response.uploadId,
|
|
25
|
+
};
|
|
26
|
+
return artifactMap;
|
|
27
|
+
}
|
|
28
|
+
async uploadArtifactToS3(zipBuffer, resp) {
|
|
29
|
+
const encryptionContext = `{"uploadId":"${resp.uploadId}"}`;
|
|
30
|
+
const md5Content = this.getMd5(zipBuffer);
|
|
31
|
+
const headersObj = resp.kmsKeyArn !== '' || resp.kmsKeyArn !== undefined
|
|
32
|
+
? {
|
|
33
|
+
'Content-MD5': md5Content,
|
|
34
|
+
'x-amz-server-side-encryption': 'aws:kms',
|
|
35
|
+
'Content-Type': 'application/zip',
|
|
36
|
+
'x-amz-server-side-encryption-aws-kms-key-id': resp.kmsKeyArn,
|
|
37
|
+
'x-amz-server-side-encryption-context': Buffer.from(encryptionContext, 'utf8').toString('base64'),
|
|
38
|
+
}
|
|
39
|
+
: {
|
|
40
|
+
'Content-MD5': md5Content,
|
|
41
|
+
'x-amz-server-side-encryption': 'aws:kms',
|
|
42
|
+
'Content-Type': 'application/zip',
|
|
43
|
+
'x-amz-server-side-encryption-context': Buffer.from(encryptionContext, 'utf8').toString('base64'),
|
|
44
|
+
};
|
|
45
|
+
const response = await got_1.default.put(resp.uploadUrl, { body: zipBuffer, headers: headersObj });
|
|
46
|
+
return response;
|
|
47
|
+
}
|
|
48
|
+
async createScanJob(artifactMap, languageName) {
|
|
49
|
+
const req = {
|
|
50
|
+
artifacts: artifactMap,
|
|
51
|
+
programmingLanguage: {
|
|
52
|
+
languageName,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
const resp = await this.client.startCodeAnalysis(req);
|
|
56
|
+
return resp;
|
|
57
|
+
}
|
|
58
|
+
async pollScanJobStatus(jobId) {
|
|
59
|
+
let status = 'Pending';
|
|
60
|
+
let timer = 0;
|
|
61
|
+
const codeScanJobPollingIntervalSeconds = 1;
|
|
62
|
+
const codeScanJobTimeoutSeconds = 50;
|
|
63
|
+
// eslint-disable-next-line no-constant-condition
|
|
64
|
+
while (true) {
|
|
65
|
+
const req = {
|
|
66
|
+
jobId: jobId,
|
|
67
|
+
};
|
|
68
|
+
const resp = await this.client.getCodeAnalysis(req);
|
|
69
|
+
if (resp.status !== 'Pending') {
|
|
70
|
+
status = resp.status;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
await (0, commonUtil_1.sleep)(codeScanJobPollingIntervalSeconds * 1000);
|
|
74
|
+
timer += codeScanJobPollingIntervalSeconds;
|
|
75
|
+
if (timer > codeScanJobTimeoutSeconds) {
|
|
76
|
+
throw new Error('Scan job timeout.');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return status;
|
|
80
|
+
}
|
|
81
|
+
async listScanResults(jobId, projectPath) {
|
|
82
|
+
const codeScanIssueMap = new Map();
|
|
83
|
+
const aggregatedCodeScanIssueList = [];
|
|
84
|
+
const request = {
|
|
85
|
+
jobId,
|
|
86
|
+
codeAnalysisFindingsSchema: 'codeanalysis/findings/1.0',
|
|
87
|
+
};
|
|
88
|
+
const response = await this.client.listCodeAnalysisFindings(request);
|
|
89
|
+
this.mapToAggregatedList(codeScanIssueMap, aggregatedCodeScanIssueList, response.codeAnalysisFindings, projectPath);
|
|
90
|
+
return aggregatedCodeScanIssueList;
|
|
91
|
+
}
|
|
92
|
+
mapToAggregatedList(codeScanIssueMap, aggregatedCodeScanIssueList, json, projectPath) {
|
|
93
|
+
const codeScanIssues = JSON.parse(json);
|
|
94
|
+
codeScanIssues.forEach(issue => {
|
|
95
|
+
if (codeScanIssueMap.has(issue.filePath)) {
|
|
96
|
+
const list = codeScanIssueMap.get(issue.filePath);
|
|
97
|
+
if (list === undefined) {
|
|
98
|
+
codeScanIssueMap.set(issue.filePath, [issue]);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
list.push(issue);
|
|
102
|
+
codeScanIssueMap.set(issue.filePath, list);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
codeScanIssueMap.set(issue.filePath, [issue]);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
codeScanIssueMap.forEach(async (issues, key) => {
|
|
110
|
+
const filePath = path.join(projectPath, '..', key);
|
|
111
|
+
const fileExists = await this.workspace.fs.exists(filePath);
|
|
112
|
+
if (fileExists) {
|
|
113
|
+
const aggregatedCodeScanIssue = {
|
|
114
|
+
filePath: filePath,
|
|
115
|
+
issues: issues.map(issue => {
|
|
116
|
+
return {
|
|
117
|
+
startLine: issue.startLine - 1 >= 0 ? issue.startLine - 1 : 0,
|
|
118
|
+
endLine: issue.endLine,
|
|
119
|
+
comment: `${issue.title.trim()}: ${issue.description.text.trim()}`,
|
|
120
|
+
title: issue.title,
|
|
121
|
+
description: issue.description,
|
|
122
|
+
detectorId: issue.detectorId,
|
|
123
|
+
detectorName: issue.detectorName,
|
|
124
|
+
findingId: issue.findingId,
|
|
125
|
+
ruleId: issue.ruleId,
|
|
126
|
+
relatedVulnerabilities: issue.relatedVulnerabilities,
|
|
127
|
+
severity: issue.severity,
|
|
128
|
+
recommendation: issue.remediation.recommendation,
|
|
129
|
+
suggestedFixes: issue.remediation.suggestedFixes,
|
|
130
|
+
};
|
|
131
|
+
}),
|
|
132
|
+
};
|
|
133
|
+
aggregatedCodeScanIssueList.push(aggregatedCodeScanIssue);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
exports.SecurityScanHandler = SecurityScanHandler;
|
|
139
|
+
//# sourceMappingURL=securityScanHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"securityScanHandler.js","sourceRoot":"","sources":["../../../src/language-server/securityScan/securityScanHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const assert = require("assert");
|
|
4
|
+
const aws_sdk_1 = require("aws-sdk");
|
|
5
|
+
const got_1 = require("got");
|
|
6
|
+
const Sinon = require("sinon");
|
|
7
|
+
const ts_sinon_1 = require("ts-sinon");
|
|
8
|
+
const securityScanHandler_1 = require("./securityScanHandler");
|
|
9
|
+
const mockCodeScanFindings = JSON.stringify([
|
|
10
|
+
{
|
|
11
|
+
filePath: 'app.py',
|
|
12
|
+
startLine: 1,
|
|
13
|
+
endLine: 1,
|
|
14
|
+
title: 'title',
|
|
15
|
+
description: {
|
|
16
|
+
text: 'text',
|
|
17
|
+
markdown: 'markdown',
|
|
18
|
+
},
|
|
19
|
+
detectorId: 'detectorId',
|
|
20
|
+
detectorName: 'detectorName',
|
|
21
|
+
findingId: 'findingId',
|
|
22
|
+
relatedVulnerabilities: [],
|
|
23
|
+
severity: 'High',
|
|
24
|
+
remediation: {
|
|
25
|
+
recommendation: {
|
|
26
|
+
text: 'text',
|
|
27
|
+
url: 'url',
|
|
28
|
+
},
|
|
29
|
+
suggestedFixes: [],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
]);
|
|
33
|
+
const mocked$Response = {
|
|
34
|
+
$response: {
|
|
35
|
+
hasNextPage: ts_sinon_1.default.mock(),
|
|
36
|
+
nextPage: ts_sinon_1.default.mock(),
|
|
37
|
+
data: undefined,
|
|
38
|
+
error: undefined,
|
|
39
|
+
requestId: '',
|
|
40
|
+
redirectCount: 0,
|
|
41
|
+
retryCount: 0,
|
|
42
|
+
httpResponse: new aws_sdk_1.HttpResponse(),
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
describe('securityScanHandler', () => {
|
|
46
|
+
let client;
|
|
47
|
+
let workspace;
|
|
48
|
+
let securityScanhandler;
|
|
49
|
+
beforeEach(async () => {
|
|
50
|
+
// Set up the server with a mock service
|
|
51
|
+
client = (0, ts_sinon_1.stubInterface)();
|
|
52
|
+
workspace = (0, ts_sinon_1.stubInterface)();
|
|
53
|
+
securityScanhandler = new securityScanHandler_1.SecurityScanHandler(client, workspace);
|
|
54
|
+
});
|
|
55
|
+
describe('Test createCodeResourcePresignedUrlHandler', () => {
|
|
56
|
+
let putStub;
|
|
57
|
+
beforeEach(async () => {
|
|
58
|
+
// mock default return value for createUploadUrl
|
|
59
|
+
client.createUploadUrl.resolves({
|
|
60
|
+
uploadId: 'dummy-upload-id',
|
|
61
|
+
uploadUrl: 'dummy-upload-url',
|
|
62
|
+
kmsKeyArn: 'ResourceArn',
|
|
63
|
+
...mocked$Response,
|
|
64
|
+
});
|
|
65
|
+
putStub = Sinon.stub(got_1.default, 'put');
|
|
66
|
+
});
|
|
67
|
+
it('returns correct source code', async () => {
|
|
68
|
+
const expectedSourceCode = 'dummy-upload-id';
|
|
69
|
+
const res = await securityScanhandler.createCodeResourcePresignedUrlHandler(Buffer.from('dummy-data'));
|
|
70
|
+
ts_sinon_1.default.assert.callCount(putStub, 1);
|
|
71
|
+
assert.equal(res.SourceCode, expectedSourceCode);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('Test createScanJob', () => {
|
|
75
|
+
beforeEach(async () => {
|
|
76
|
+
// mock default return value for createCodeScan
|
|
77
|
+
client.startCodeAnalysis.returns(Promise.resolve({
|
|
78
|
+
jobId: 'dummy-job-id',
|
|
79
|
+
status: 'Pending',
|
|
80
|
+
...mocked$Response,
|
|
81
|
+
}));
|
|
82
|
+
});
|
|
83
|
+
it('should create code scan', async () => {
|
|
84
|
+
const artifactMap = { SourceCode: 'dummy-upload-id' };
|
|
85
|
+
const requestParams = {
|
|
86
|
+
artifacts: { SourceCode: 'dummy-upload-id' },
|
|
87
|
+
programmingLanguage: { languageName: 'csharp' },
|
|
88
|
+
};
|
|
89
|
+
const res = await securityScanhandler.createScanJob(artifactMap, 'csharp');
|
|
90
|
+
ts_sinon_1.default.assert.calledOnceWithExactly(client.startCodeAnalysis, requestParams);
|
|
91
|
+
assert.equal(res.jobId, 'dummy-job-id');
|
|
92
|
+
assert.equal(res.status, 'Pending');
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
describe('Test pollScanJobStatus', () => {
|
|
96
|
+
beforeEach(async () => {
|
|
97
|
+
// mock default return value for getCodeAnalysis
|
|
98
|
+
client.getCodeAnalysis.resolves({
|
|
99
|
+
status: 'Pending',
|
|
100
|
+
...mocked$Response,
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
it('should change job status from pending to completed', async () => {
|
|
104
|
+
client.getCodeAnalysis.onCall(0).resolves({
|
|
105
|
+
status: 'Pending',
|
|
106
|
+
...mocked$Response,
|
|
107
|
+
});
|
|
108
|
+
client.getCodeAnalysis.onCall(1).resolves({
|
|
109
|
+
status: 'Completed',
|
|
110
|
+
...mocked$Response,
|
|
111
|
+
});
|
|
112
|
+
const dummyJobId = 'dummy-job-id';
|
|
113
|
+
const requestParams = { jobId: dummyJobId };
|
|
114
|
+
const res = await securityScanhandler.pollScanJobStatus(dummyJobId);
|
|
115
|
+
ts_sinon_1.default.assert.calledWith(client.getCodeAnalysis, requestParams);
|
|
116
|
+
ts_sinon_1.default.assert.calledTwice(client.getCodeAnalysis);
|
|
117
|
+
assert.equal(res, 'Completed');
|
|
118
|
+
});
|
|
119
|
+
it('should change job status from pending to failed', async () => {
|
|
120
|
+
client.getCodeAnalysis.onCall(0).resolves({
|
|
121
|
+
status: 'Pending',
|
|
122
|
+
...mocked$Response,
|
|
123
|
+
});
|
|
124
|
+
client.getCodeAnalysis.onCall(1).resolves({
|
|
125
|
+
status: 'Failed',
|
|
126
|
+
...mocked$Response,
|
|
127
|
+
});
|
|
128
|
+
const dummyJobId = 'dummy-job-id';
|
|
129
|
+
const requestParams = { jobId: dummyJobId };
|
|
130
|
+
const res = await securityScanhandler.pollScanJobStatus(dummyJobId);
|
|
131
|
+
ts_sinon_1.default.assert.calledWith(client.getCodeAnalysis, requestParams);
|
|
132
|
+
ts_sinon_1.default.assert.calledTwice(client.getCodeAnalysis);
|
|
133
|
+
assert.equal(res, 'Failed');
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe('Test listScanResults', () => {
|
|
137
|
+
beforeEach(() => {
|
|
138
|
+
// mock default return value for listCodeAnalysisFindings
|
|
139
|
+
client.listCodeAnalysisFindings.resolves({
|
|
140
|
+
codeAnalysisFindings: mockCodeScanFindings,
|
|
141
|
+
...mocked$Response,
|
|
142
|
+
});
|
|
143
|
+
workspace.fs.exists = ts_sinon_1.default.stub().resolves(true);
|
|
144
|
+
});
|
|
145
|
+
it('should return appropriate issues', async () => {
|
|
146
|
+
const dummyJobId = 'dummy-job-id';
|
|
147
|
+
const codeAnalysisFindingsSchema = 'codeanalysis/findings/1.0';
|
|
148
|
+
const dummyProjectPath = 'C:\\workspace\\workspaceFolder\\python3.7-plain-sam-app\\hello_world';
|
|
149
|
+
const requestParams = { jobId: dummyJobId, codeAnalysisFindingsSchema };
|
|
150
|
+
const aggregatedCodeScanIssueList = await securityScanhandler.listScanResults(dummyJobId, dummyProjectPath);
|
|
151
|
+
ts_sinon_1.default.assert.calledWith(client.listCodeAnalysisFindings, requestParams);
|
|
152
|
+
assert.equal(aggregatedCodeScanIssueList.length, 1);
|
|
153
|
+
assert.equal(aggregatedCodeScanIssueList[0].issues.length, 1);
|
|
154
|
+
});
|
|
155
|
+
it('should return zero issues', async () => {
|
|
156
|
+
client.listCodeAnalysisFindings.resolves({
|
|
157
|
+
codeAnalysisFindings: '[]',
|
|
158
|
+
...mocked$Response,
|
|
159
|
+
});
|
|
160
|
+
const dummyJobId = 'dummy-job-id';
|
|
161
|
+
const codeAnalysisFindingsSchema = 'codeanalysis/findings/1.0';
|
|
162
|
+
const dummyProjectPath = 'C:\\workspace\\workspaceFolder\\python3.7-plain-sam-app\\hello_world';
|
|
163
|
+
const requestParams = { jobId: dummyJobId, codeAnalysisFindingsSchema };
|
|
164
|
+
const aggregatedCodeScanIssueList = await securityScanhandler.listScanResults(dummyJobId, dummyProjectPath);
|
|
165
|
+
ts_sinon_1.default.assert.calledWith(client.listCodeAnalysisFindings, requestParams);
|
|
166
|
+
assert.equal(aggregatedCodeScanIssueList.length, 0);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
//# sourceMappingURL=securityScanHandler.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"securityScanHandler.test.js","sourceRoot":"","sources":["../../../src/language-server/securityScan/securityScanHandler.test.ts"],"names":[],"mappings":";;AACA,iCAAgC;AAChC,qCAAsC;AACtC,6BAAqB;AACrB,+BAA8B;AAC9B,uCAA2E;AAG3E,+DAA2D;AAG3D,MAAM,oBAAoB,GAAG,IAAI,CAAC,SAAS,CAAC;IACxC;QACI,QAAQ,EAAE,QAAQ;QAClB,SAAS,EAAE,CAAC;QACZ,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,OAAO;QACd,WAAW,EAAE;YACT,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,UAAU;SACvB;QACD,UAAU,EAAE,YAAY;QACxB,YAAY,EAAE,cAAc;QAC5B,SAAS,EAAE,WAAW;QACtB,sBAAsB,EAAE,EAAE;QAC1B,QAAQ,EAAE,MAAM;QAChB,WAAW,EAAE;YACT,cAAc,EAAE;gBACZ,IAAI,EAAE,MAAM;gBACZ,GAAG,EAAE,KAAK;aACb;YACD,cAAc,EAAE,EAAE;SACrB;KACuB;CAC/B,CAAC,CAAA;AAEF,MAAM,eAAe,GAAG;IACpB,SAAS,EAAE;QACP,WAAW,EAAE,kBAAK,CAAC,IAAI,EAAE;QACzB,QAAQ,EAAE,kBAAK,CAAC,IAAI,EAAE;QACtB,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,SAAS,EAAE,EAAE;QACb,aAAa,EAAE,CAAC;QAChB,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,IAAI,sBAAY,EAAE;KACnC;CACJ,CAAA;AAED,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACjC,IAAI,MAAkD,CAAA;IACtD,IAAI,SAAqC,CAAA;IACzC,IAAI,mBAAwC,CAAA;IAC5C,UAAU,CAAC,KAAK,IAAI,EAAE;QAClB,wCAAwC;QACxC,MAAM,GAAG,IAAA,wBAAa,GAA6B,CAAA;QACnD,SAAS,GAAG,IAAA,wBAAa,GAAa,CAAA;QACtC,mBAAmB,GAAG,IAAI,yCAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACpE,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACxD,IAAI,OAAwB,CAAA;QAC5B,UAAU,CAAC,KAAK,IAAI,EAAE;YAClB,gDAAgD;YAChD,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC;gBAC5B,QAAQ,EAAE,iBAAiB;gBAC3B,SAAS,EAAE,kBAAkB;gBAC7B,SAAS,EAAE,aAAa;gBACxB,GAAG,eAAe;aACrB,CAAC,CAAA;YACF,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,aAAG,EAAE,KAAK,CAAC,CAAA;QACpC,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;YACzC,MAAM,kBAAkB,GAAG,iBAAiB,CAAA;YAC5C,MAAM,GAAG,GAAG,MAAM,mBAAmB,CAAC,qCAAqC,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAA;YACtG,kBAAK,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;YAClC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAA;QACpD,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IACF,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAChC,UAAU,CAAC,KAAK,IAAI,EAAE;YAClB,+CAA+C;YAC/C,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAC5B,OAAO,CAAC,OAAO,CAAC;gBACZ,KAAK,EAAE,cAAc;gBACrB,MAAM,EAAE,SAAS;gBACjB,GAAG,eAAe;aACrB,CAAC,CACL,CAAA;QACL,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;YACrC,MAAM,WAAW,GAAG,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAA;YACrD,MAAM,aAAa,GAA6B;gBAC5C,SAAS,EAAE,EAAE,UAAU,EAAE,iBAAiB,EAAE;gBAC5C,mBAAmB,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE;aAClD,CAAA;YACD,MAAM,GAAG,GAAG,MAAM,mBAAmB,CAAC,aAAa,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;YAC1E,kBAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;YAC3E,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,CAAA;YACvC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;QACvC,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACpC,UAAU,CAAC,KAAK,IAAI,EAAE;YAClB,gDAAgD;YAChD,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC;gBAC5B,MAAM,EAAE,SAAS;gBACjB,GAAG,eAAe;aACrB,CAAC,CAAA;QACN,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;YAChE,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACtC,MAAM,EAAE,SAAS;gBACjB,GAAG,eAAe;aACrB,CAAC,CAAA;YACF,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACtC,MAAM,EAAE,WAAW;gBACnB,GAAG,eAAe;aACrB,CAAC,CAAA;YACF,MAAM,UAAU,GAAG,cAAc,CAAA;YACjC,MAAM,aAAa,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;YAC3C,MAAM,GAAG,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAA;YACnE,kBAAK,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC,CAAA;YAC9D,kBAAK,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;YAChD,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;QAClC,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC7D,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACtC,MAAM,EAAE,SAAS;gBACjB,GAAG,eAAe;aACrB,CAAC,CAAA;YACF,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACtC,MAAM,EAAE,QAAQ;gBAChB,GAAG,eAAe;aACrB,CAAC,CAAA;YACF,MAAM,UAAU,GAAG,cAAc,CAAA;YACjC,MAAM,aAAa,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;YAC3C,MAAM,GAAG,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAA;YACnE,kBAAK,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC,CAAA;YAC9D,kBAAK,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;YAChD,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;QAC/B,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAClC,UAAU,CAAC,GAAG,EAAE;YACZ,yDAAyD;YACzD,MAAM,CAAC,wBAAwB,CAAC,QAAQ,CAAC;gBACrC,oBAAoB,EAAE,oBAAoB;gBAC1C,GAAG,eAAe;aACrB,CAAC,CAAA;YACF,SAAS,CAAC,EAAE,CAAC,MAAM,GAAG,kBAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QACrD,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;YAC9C,MAAM,UAAU,GAAG,cAAc,CAAA;YACjC,MAAM,0BAA0B,GAAG,2BAA2B,CAAA;YAC9D,MAAM,gBAAgB,GAAG,sEAAsE,CAAA;YAC/F,MAAM,aAAa,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,0BAA0B,EAAE,CAAA;YAEvE,MAAM,2BAA2B,GAAG,MAAM,mBAAmB,CAAC,eAAe,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAA;YAC3G,kBAAK,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,wBAAwB,EAAE,aAAa,CAAC,CAAA;YACvE,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;YACnD,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;QACjE,CAAC,CAAC,CAAA;QACF,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;YACvC,MAAM,CAAC,wBAAwB,CAAC,QAAQ,CAAC;gBACrC,oBAAoB,EAAE,IAAI;gBAC1B,GAAG,eAAe;aACrB,CAAC,CAAA;YACF,MAAM,UAAU,GAAG,cAAc,CAAA;YACjC,MAAM,0BAA0B,GAAG,2BAA2B,CAAA;YAC9D,MAAM,gBAAgB,GAAG,sEAAsE,CAAA;YAC/F,MAAM,aAAa,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,0BAA0B,EAAE,CAAA;YAEvE,MAAM,2BAA2B,GAAG,MAAM,mBAAmB,CAAC,eAAe,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAA;YAC3G,kBAAK,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,wBAAwB,EAAE,aAAa,CAAC,CAAA;YACvE,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;QACvD,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA"}
|