@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.
Files changed (100) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +19 -0
  3. package/out/client/sigv4/codewhisperer.d.ts +3 -0
  4. package/out/client/sigv4/codewhisperer.js +14 -0
  5. package/out/client/sigv4/codewhisperer.js.map +1 -0
  6. package/out/client/sigv4/service.json +346 -0
  7. package/out/client/token/bearer-token-service.json +1627 -0
  8. package/out/client/token/codewhisperer.d.ts +14 -0
  9. package/out/client/token/codewhisperer.js +23 -0
  10. package/out/client/token/codewhisperer.js.map +1 -0
  11. package/out/index.d.ts +2 -0
  12. package/out/index.js +19 -0
  13. package/out/index.js.map +1 -0
  14. package/out/language-server/auto-trigger/autoTrigger.d.ts +38 -0
  15. package/out/language-server/auto-trigger/autoTrigger.js +119 -0
  16. package/out/language-server/auto-trigger/autoTrigger.js.map +1 -0
  17. package/out/language-server/auto-trigger/autoTrigger.test.d.ts +1 -0
  18. package/out/language-server/auto-trigger/autoTrigger.test.js +82 -0
  19. package/out/language-server/auto-trigger/autoTrigger.test.js.map +1 -0
  20. package/out/language-server/auto-trigger/coefficients.json +405 -0
  21. package/out/language-server/codeWhispererSecurityScanServer.d.ts +4 -0
  22. package/out/language-server/codeWhispererSecurityScanServer.js +76 -0
  23. package/out/language-server/codeWhispererSecurityScanServer.js.map +1 -0
  24. package/out/language-server/codeWhispererServer.d.ts +7 -0
  25. package/out/language-server/codeWhispererServer.js +425 -0
  26. package/out/language-server/codeWhispererServer.js.map +1 -0
  27. package/out/language-server/codeWhispererServer.test.d.ts +1 -0
  28. package/out/language-server/codeWhispererServer.test.js +1218 -0
  29. package/out/language-server/codeWhispererServer.test.js.map +1 -0
  30. package/out/language-server/codeWhispererService.d.ts +84 -0
  31. package/out/language-server/codeWhispererService.js +168 -0
  32. package/out/language-server/codeWhispererService.js.map +1 -0
  33. package/out/language-server/dependencyGraph/commonUtil.d.ts +2 -0
  34. package/out/language-server/dependencyGraph/commonUtil.js +20 -0
  35. package/out/language-server/dependencyGraph/commonUtil.js.map +1 -0
  36. package/out/language-server/dependencyGraph/constants.d.ts +2 -0
  37. package/out/language-server/dependencyGraph/constants.js +6 -0
  38. package/out/language-server/dependencyGraph/constants.js.map +1 -0
  39. package/out/language-server/dependencyGraph/csharpDependencyGraph.d.ts +27 -0
  40. package/out/language-server/dependencyGraph/csharpDependencyGraph.js +145 -0
  41. package/out/language-server/dependencyGraph/csharpDependencyGraph.js.map +1 -0
  42. package/out/language-server/dependencyGraph/csharpDependencyGraph.test.d.ts +1 -0
  43. package/out/language-server/dependencyGraph/csharpDependencyGraph.test.js +341 -0
  44. package/out/language-server/dependencyGraph/csharpDependencyGraph.test.js.map +1 -0
  45. package/out/language-server/dependencyGraph/dependencyGraph.d.ts +125 -0
  46. package/out/language-server/dependencyGraph/dependencyGraph.js +152 -0
  47. package/out/language-server/dependencyGraph/dependencyGraph.js.map +1 -0
  48. package/out/language-server/dependencyGraph/dependencyGraphFactory.d.ts +15 -0
  49. package/out/language-server/dependencyGraph/dependencyGraphFactory.js +22 -0
  50. package/out/language-server/dependencyGraph/dependencyGraphFactory.js.map +1 -0
  51. package/out/language-server/languageDetection.d.ts +3 -0
  52. package/out/language-server/languageDetection.js +56 -0
  53. package/out/language-server/languageDetection.js.map +1 -0
  54. package/out/language-server/mergeRightUtils.d.ts +6 -0
  55. package/out/language-server/mergeRightUtils.js +37 -0
  56. package/out/language-server/mergeRightUtils.js.map +1 -0
  57. package/out/language-server/mergeRightUtils.test.d.ts +1 -0
  58. package/out/language-server/mergeRightUtils.test.js +53 -0
  59. package/out/language-server/mergeRightUtils.test.js.map +1 -0
  60. package/out/language-server/proxy-server.d.ts +2 -0
  61. package/out/language-server/proxy-server.js +35 -0
  62. package/out/language-server/proxy-server.js.map +1 -0
  63. package/out/language-server/securityScan/securityScanHandler.d.ts +17 -0
  64. package/out/language-server/securityScan/securityScanHandler.js +139 -0
  65. package/out/language-server/securityScan/securityScanHandler.js.map +1 -0
  66. package/out/language-server/securityScan/securityScanHandler.test.d.ts +1 -0
  67. package/out/language-server/securityScan/securityScanHandler.test.js +170 -0
  68. package/out/language-server/securityScan/securityScanHandler.test.js.map +1 -0
  69. package/out/language-server/securityScan/types.d.ts +49 -0
  70. package/out/language-server/securityScan/types.js +3 -0
  71. package/out/language-server/securityScan/types.js.map +1 -0
  72. package/out/language-server/session/sessionManager.d.ts +91 -0
  73. package/out/language-server/session/sessionManager.js +234 -0
  74. package/out/language-server/session/sessionManager.js.map +1 -0
  75. package/out/language-server/session/sessionManager.test.d.ts +1 -0
  76. package/out/language-server/session/sessionManager.test.js +584 -0
  77. package/out/language-server/session/sessionManager.test.js.map +1 -0
  78. package/out/language-server/telemetry/codePercentage.d.ts +17 -0
  79. package/out/language-server/telemetry/codePercentage.js +82 -0
  80. package/out/language-server/telemetry/codePercentage.js.map +1 -0
  81. package/out/language-server/telemetry/codePercentage.test.d.ts +1 -0
  82. package/out/language-server/telemetry/codePercentage.test.js +85 -0
  83. package/out/language-server/telemetry/codePercentage.test.js.map +1 -0
  84. package/out/language-server/telemetry/types.d.ts +68 -0
  85. package/out/language-server/telemetry/types.js +3 -0
  86. package/out/language-server/telemetry/types.js.map +1 -0
  87. package/out/language-server/telemetry/userTriggerDecision.test.d.ts +1 -0
  88. package/out/language-server/telemetry/userTriggerDecision.test.js +946 -0
  89. package/out/language-server/telemetry/userTriggerDecision.test.js.map +1 -0
  90. package/out/language-server/telemetry.test.d.ts +1 -0
  91. package/out/language-server/telemetry.test.js +96 -0
  92. package/out/language-server/telemetry.test.js.map +1 -0
  93. package/out/language-server/testUtils.d.ts +69 -0
  94. package/out/language-server/testUtils.js +90 -0
  95. package/out/language-server/testUtils.js.map +1 -0
  96. package/out/language-server/utils.d.ts +6 -0
  97. package/out/language-server/utils.js +31 -0
  98. package/out/language-server/utils.js.map +1 -0
  99. package/package.json +53 -0
  100. 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,2 @@
1
+ export declare const CodeWhispererServerTokenProxy: import("@aws/language-server-runtimes").Server;
2
+ export declare const CodeWhispererSecurityScanServerTokenProxy: import("@aws/language-server-runtimes").Server;
@@ -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,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":"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"}