@contrast/contrast 1.0.10 → 1.0.13

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 (112) hide show
  1. package/README.md +1 -1
  2. package/dist/audit/{languageAnalysisEngine/report → report}/commonReportingFunctions.js +56 -35
  3. package/dist/audit/report/models/reportGuidanceModel.js +6 -0
  4. package/dist/audit/{languageAnalysisEngine/report → report}/models/reportLibraryModel.js +0 -0
  5. package/dist/audit/{languageAnalysisEngine/report → report}/models/reportListModel.js +0 -0
  6. package/dist/audit/{languageAnalysisEngine/report → report}/models/reportOutputModel.js +1 -2
  7. package/dist/audit/{languageAnalysisEngine/report → report}/models/reportSeverityModel.js +0 -0
  8. package/dist/audit/{languageAnalysisEngine/report → report}/models/severityCountModel.js +1 -0
  9. package/dist/audit/{languageAnalysisEngine/report → report}/reportingFeature.js +12 -8
  10. package/dist/audit/{languageAnalysisEngine/report → report}/utils/reportUtils.js +3 -4
  11. package/dist/commands/audit/auditConfig.js +3 -3
  12. package/dist/commands/audit/help.js +3 -1
  13. package/dist/commands/audit/processAudit.js +14 -2
  14. package/dist/commands/auth/auth.js +1 -1
  15. package/dist/commands/config/config.js +2 -2
  16. package/dist/commands/scan/processScan.js +20 -4
  17. package/dist/commands/scan/sca/scaAnalysis.js +15 -5
  18. package/dist/common/HTTPClient.js +39 -2
  19. package/dist/common/commonHelp.js +19 -0
  20. package/dist/common/fail.js +70 -0
  21. package/dist/common/versionChecker.js +14 -6
  22. package/dist/constants/constants.js +2 -2
  23. package/dist/constants/locales.js +15 -5
  24. package/dist/constants.js +42 -5
  25. package/dist/index.js +6 -3
  26. package/dist/lambda/help.js +2 -3
  27. package/dist/lambda/lambda.js +7 -0
  28. package/dist/scaAnalysis/common/scaParserForGoAndJava.js +32 -0
  29. package/dist/scaAnalysis/common/scaServicesUpload.js +52 -0
  30. package/dist/scaAnalysis/common/treeUpload.js +20 -5
  31. package/dist/scaAnalysis/dotnet/analysis.js +15 -3
  32. package/dist/scaAnalysis/go/goAnalysis.js +8 -2
  33. package/dist/scaAnalysis/java/analysis.js +10 -6
  34. package/dist/scaAnalysis/java/index.js +7 -1
  35. package/dist/scaAnalysis/java/javaBuildDepsParser.js +19 -3
  36. package/dist/scaAnalysis/javascript/index.js +4 -0
  37. package/dist/scaAnalysis/javascript/scaServiceParser.js +109 -0
  38. package/dist/scaAnalysis/php/analysis.js +1 -1
  39. package/dist/scaAnalysis/php/index.js +12 -6
  40. package/dist/scaAnalysis/php/phpNewServicesMapper.js +62 -0
  41. package/dist/scaAnalysis/python/analysis.js +43 -5
  42. package/dist/scaAnalysis/python/index.js +7 -2
  43. package/dist/scaAnalysis/ruby/analysis.js +116 -9
  44. package/dist/scaAnalysis/ruby/index.js +6 -1
  45. package/dist/scan/formatScanOutput.js +6 -5
  46. package/dist/scan/help.js +2 -3
  47. package/dist/scan/populateProjectIdAndProjectName.js +5 -0
  48. package/dist/scan/scan.js +4 -0
  49. package/dist/scan/scanConfig.js +4 -4
  50. package/dist/scan/scanResults.js +46 -3
  51. package/dist/telemetry/telemetry.js +137 -0
  52. package/dist/{audit/languageAnalysisEngine/util → utils}/capabilities.js +0 -0
  53. package/dist/{audit/languageAnalysisEngine/util → utils}/generalAPI.js +14 -5
  54. package/dist/utils/getConfig.js +2 -4
  55. package/dist/utils/parsedCLIOptions.js +3 -1
  56. package/dist/utils/requestUtils.js +7 -1
  57. package/package.json +4 -2
  58. package/src/audit/{languageAnalysisEngine/report → report}/commonReportingFunctions.ts +80 -44
  59. package/src/audit/report/models/reportGuidanceModel.ts +5 -0
  60. package/src/audit/{languageAnalysisEngine/report → report}/models/reportLibraryModel.ts +0 -0
  61. package/src/audit/{languageAnalysisEngine/report → report}/models/reportListModel.ts +0 -0
  62. package/src/audit/{languageAnalysisEngine/report → report}/models/reportOutputModel.ts +1 -7
  63. package/src/audit/{languageAnalysisEngine/report → report}/models/reportSeverityModel.ts +0 -0
  64. package/src/audit/{languageAnalysisEngine/report → report}/models/severityCountModel.ts +2 -0
  65. package/src/audit/{languageAnalysisEngine/report → report}/reportingFeature.ts +16 -9
  66. package/src/audit/{languageAnalysisEngine/report → report}/utils/reportUtils.ts +4 -4
  67. package/src/commands/audit/auditConfig.ts +10 -3
  68. package/src/commands/audit/help.ts +3 -1
  69. package/src/commands/audit/processAudit.ts +24 -2
  70. package/src/commands/auth/auth.js +3 -1
  71. package/src/commands/config/config.js +4 -2
  72. package/src/commands/scan/processScan.js +32 -4
  73. package/src/commands/scan/sca/scaAnalysis.js +23 -5
  74. package/src/common/HTTPClient.js +59 -2
  75. package/src/common/commonHelp.ts +13 -0
  76. package/src/common/fail.js +79 -0
  77. package/src/common/versionChecker.ts +18 -8
  78. package/src/constants/constants.js +2 -2
  79. package/src/constants/locales.js +19 -7
  80. package/src/constants.js +46 -6
  81. package/src/index.ts +18 -4
  82. package/src/lambda/help.ts +2 -3
  83. package/src/lambda/lambda.ts +12 -0
  84. package/src/scaAnalysis/common/scaParserForGoAndJava.js +41 -0
  85. package/src/scaAnalysis/common/scaServicesUpload.js +54 -0
  86. package/src/scaAnalysis/common/treeUpload.js +21 -5
  87. package/src/scaAnalysis/dotnet/analysis.js +21 -3
  88. package/src/scaAnalysis/go/goAnalysis.js +9 -2
  89. package/src/scaAnalysis/java/analysis.js +11 -6
  90. package/src/scaAnalysis/java/index.js +9 -1
  91. package/src/scaAnalysis/java/javaBuildDepsParser.js +25 -6
  92. package/src/scaAnalysis/javascript/index.js +4 -0
  93. package/src/scaAnalysis/javascript/scaServiceParser.js +145 -0
  94. package/src/scaAnalysis/php/analysis.js +1 -1
  95. package/src/scaAnalysis/php/index.js +12 -6
  96. package/src/scaAnalysis/php/phpNewServicesMapper.js +77 -0
  97. package/src/scaAnalysis/python/analysis.js +49 -5
  98. package/src/scaAnalysis/python/index.js +7 -2
  99. package/src/scaAnalysis/ruby/analysis.js +149 -9
  100. package/src/scaAnalysis/ruby/index.js +6 -1
  101. package/src/scan/formatScanOutput.ts +7 -5
  102. package/src/scan/help.js +2 -3
  103. package/src/scan/populateProjectIdAndProjectName.js +5 -1
  104. package/src/scan/scan.ts +4 -0
  105. package/src/scan/scanConfig.js +6 -4
  106. package/src/scan/scanResults.js +52 -3
  107. package/src/telemetry/telemetry.ts +154 -0
  108. package/src/{audit/languageAnalysisEngine/util → utils}/capabilities.js +0 -0
  109. package/src/{audit/languageAnalysisEngine/util → utils}/generalAPI.js +16 -6
  110. package/src/utils/getConfig.ts +2 -11
  111. package/src/utils/parsedCLIOptions.js +14 -1
  112. package/src/utils/requestUtils.js +8 -1
package/src/index.ts CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  isCorrectNodeVersion
15
15
  } from './common/versionChecker'
16
16
  import { findCommandOnError } from './common/errorHandling'
17
-
17
+ import { sendTelemetryConfigAsConfObj } from './telemetry/telemetry'
18
18
  const {
19
19
  commandLineDefinitions: { mainUsageGuide, mainDefinition }
20
20
  } = constants
@@ -57,7 +57,7 @@ const start = async () => {
57
57
  config.set('numOfRuns', config.get('numOfRuns') + 1)
58
58
 
59
59
  // @ts-ignore
60
- if (config.get('numOfRuns') >= 1) {
60
+ if (config.get('numOfRuns') >= 10) {
61
61
  await findLatestCLIVersion(config)
62
62
  config.set('numOfRuns', 0)
63
63
  }
@@ -75,11 +75,11 @@ const start = async () => {
75
75
  }
76
76
 
77
77
  if (command === 'scan') {
78
- return await processScan(argvMain)
78
+ return await processScan(config, argvMain)
79
79
  }
80
80
 
81
81
  if (command === 'audit') {
82
- return await processAudit(argvMain)
82
+ return await processAudit(config, argvMain)
83
83
  }
84
84
 
85
85
  if (
@@ -98,10 +98,24 @@ const start = async () => {
98
98
  : console.log(
99
99
  `Unknown Command: ${command} \nUse --help for the full list`
100
100
  )
101
+ await sendTelemetryConfigAsConfObj(
102
+ config,
103
+ command,
104
+ argvMain,
105
+ 'FAILURE',
106
+ 'undefined'
107
+ )
101
108
  } else {
102
109
  console.log(
103
110
  `Unknown Command: ${command} \nUse --help for the full list`
104
111
  )
112
+ await sendTelemetryConfigAsConfObj(
113
+ config,
114
+ command,
115
+ argvMain,
116
+ 'FAILURE',
117
+ 'undefined'
118
+ )
105
119
  }
106
120
  process.exit(9)
107
121
  } else {
@@ -1,5 +1,6 @@
1
1
  import commandLineUsage from 'command-line-usage'
2
2
  import i18n from 'i18n'
3
+ import { commonHelpLinks } from '../common/commonHelp'
3
4
 
4
5
  const lambdaUsageGuide = commandLineUsage([
5
6
  {
@@ -80,9 +81,7 @@ const lambdaUsageGuide = commandLineUsage([
80
81
  { name: i18n.__('lambdaHelpOption'), summary: i18n.__('helpSummary') }
81
82
  ]
82
83
  },
83
- {
84
- content: '{underline https://www.contrastsecurity.com/developer/codesec}'
85
- }
84
+ commonHelpLinks()
86
85
  ])
87
86
 
88
87
  export { lambdaUsageGuide }
@@ -17,6 +17,7 @@ import ora from '../utils/oraWrapper'
17
17
  import { postAnalytics } from './analytics'
18
18
  import { LambdaOptions, AnalyticsOption, StatusType, EventType } from './types'
19
19
  import { APP_VERSION } from '../constants/constants'
20
+ import chalk from 'chalk'
20
21
 
21
22
  type ApiParams = {
22
23
  organizationId: string
@@ -114,6 +115,9 @@ const processLambda = async (argv: string[]) => {
114
115
  await postAnalytics(endCommandAnalytics).catch((error: Error) => {
115
116
  /* ignore */
116
117
  })
118
+
119
+ postRunMessage()
120
+
117
121
  if (errorMsg) {
118
122
  process.exit(1)
119
123
  }
@@ -221,4 +225,12 @@ const handleLambdaHelp = () => {
221
225
  process.exit(0)
222
226
  }
223
227
 
228
+ const postRunMessage = () => {
229
+ console.log('\n' + chalk.underline.bold('Other Codesec Features:'))
230
+ console.log("'contrast scan' to run CodeSec’s industry leading SAST scanner")
231
+ console.log(
232
+ "'contrast audit' to find vulnerabilities in your open source dependencies\n"
233
+ )
234
+ }
235
+
224
236
  export { processLambda, LambdaOptions, ApiParams, getAvailableFunctions }
@@ -0,0 +1,41 @@
1
+ const parseDependenciesForSCAServices = dependencyTreeObject => {
2
+ let parsedDependencyTree = {}
3
+ let subDeps
4
+
5
+ for (let tree in dependencyTreeObject) {
6
+ let unParsedDependencyTree = dependencyTreeObject[tree]
7
+ for (let dependency in unParsedDependencyTree) {
8
+ subDeps = parseSubDependencies(unParsedDependencyTree[dependency].edges)
9
+
10
+ let parsedDependency = {
11
+ name: unParsedDependencyTree[dependency].artifactID,
12
+ group: unParsedDependencyTree[dependency].group,
13
+ version: unParsedDependencyTree[dependency].version,
14
+ directDependency: unParsedDependencyTree[dependency].type === 'direct',
15
+ isProduction: true,
16
+ dependencies: subDeps
17
+ }
18
+ parsedDependencyTree[dependency] = parsedDependency
19
+ }
20
+ }
21
+ return parsedDependencyTree
22
+ }
23
+
24
+ const parseSubDependencies = dependencies => {
25
+ // converting:
26
+ // dependencies: {
27
+ // 'gopkg.in/check.v1@v0.0.0-2': 'gopkg.in/check.v1@v0.0.0-2'
28
+ // }
29
+ // to:
30
+ // dependencies: [ 'gopkg.in/check.v1@v0.0.0-2' ]
31
+ let subDeps = []
32
+ for (let x in dependencies) {
33
+ subDeps.push(dependencies[x])
34
+ }
35
+ return subDeps
36
+ }
37
+
38
+ module.exports = {
39
+ parseDependenciesForSCAServices,
40
+ parseSubDependencies
41
+ }
@@ -0,0 +1,54 @@
1
+ const commonApi = require('../../utils/commonApi')
2
+ const { APP_VERSION } = require('../../constants/constants')
3
+ const requestUtils = require('../../utils/requestUtils')
4
+
5
+ const scaTreeUpload = async (analysis, config) => {
6
+ const requestBody = {
7
+ applicationId: config.applicationId,
8
+ dependencyTree: analysis,
9
+ organizationId: config.organizationId,
10
+ language: 'NODE',
11
+ tool: {
12
+ name: 'Contrast Codesec',
13
+ version: APP_VERSION
14
+ }
15
+ }
16
+
17
+ const client = commonApi.getHttpClient(config)
18
+ const reportID = await client
19
+ .scaServiceIngest(requestBody, config)
20
+ .then(res => {
21
+ if (res.statusCode === 201) {
22
+ return res.body.libraryIngestJobId
23
+ } else {
24
+ throw new Error(res.statusCode + ` error ingesting dependencies`)
25
+ }
26
+ })
27
+ .catch(err => {
28
+ throw err
29
+ })
30
+
31
+ let keepChecking = true
32
+ while (keepChecking) {
33
+ keepChecking = await client
34
+ .scaServiceReportStatus(config, reportID)
35
+ .then(res => {
36
+ console.log(res.body)
37
+ if (res.body.status == 'COMPLETED') {
38
+ client.scaServiceReport(config, reportID).then(res => {
39
+ console.log(res.statusCode)
40
+ console.log(res.body)
41
+ })
42
+
43
+ return (keepChecking = false)
44
+ } else {
45
+ return (keepChecking = true)
46
+ }
47
+ })
48
+ await requestUtils.sleep(5000)
49
+ }
50
+ }
51
+
52
+ module.exports = {
53
+ scaTreeUpload
54
+ }
@@ -2,11 +2,14 @@ const commonApi = require('../../utils/commonApi')
2
2
  const { APP_VERSION } = require('../../constants/constants')
3
3
 
4
4
  const commonSendSnapShot = async (analysis, config) => {
5
- const requestBody = {
6
- appID: config.applicationId,
7
- cliVersion: APP_VERSION,
8
- snapshot: analysis
9
- }
5
+ let requestBody = {}
6
+ config.experimental === true
7
+ ? (requestBody = sendToSCAServices(config, analysis))
8
+ : (requestBody = {
9
+ appID: config.applicationId,
10
+ cliVersion: APP_VERSION,
11
+ snapshot: analysis
12
+ })
10
13
 
11
14
  const client = commonApi.getHttpClient(config)
12
15
  return client
@@ -23,6 +26,19 @@ const commonSendSnapShot = async (analysis, config) => {
23
26
  })
24
27
  }
25
28
 
29
+ const sendToSCAServices = (config, analysis) => {
30
+ return {
31
+ applicationId: config.applicationId,
32
+ dependencyTree: analysis,
33
+ organizationId: config.organizationId,
34
+ language: config.language,
35
+ tool: {
36
+ name: 'Contrast Codesec',
37
+ version: APP_VERSION
38
+ }
39
+ }
40
+ }
41
+
26
42
  module.exports = {
27
43
  commonSendSnapShot
28
44
  }
@@ -40,9 +40,26 @@ const readAndParseLockFile = lockFilePath => {
40
40
  return lockFile
41
41
  }
42
42
 
43
+ const checkForCorrectFiles = languageFiles => {
44
+ if (!languageFiles.includes('packages.lock.json')) {
45
+ throw new Error(i18n.__('languageAnalysisHasNoLockFile', '.NET'))
46
+ }
47
+
48
+ if (!languageFiles.some(i => i.includes('.csproj'))) {
49
+ throw new Error(i18n.__('languageAnalysisProjectFileError', '.NET'))
50
+ }
51
+ }
52
+
43
53
  const getDotNetDeps = (filePath, languageFiles) => {
44
- const projectFile = readAndParseProjectFile(filePath + `/${languageFiles[0]}`)
45
- const lockFile = readAndParseLockFile(filePath + `/${languageFiles[1]}`)
54
+ checkForCorrectFiles(languageFiles)
55
+ const projectFileName = languageFiles.find(fileName =>
56
+ fileName.includes('.csproj')
57
+ )
58
+ const lockFileName = languageFiles.find(fileName =>
59
+ fileName.includes('.json')
60
+ )
61
+ const projectFile = readAndParseProjectFile(filePath + `/${projectFileName}`)
62
+ const lockFile = readAndParseLockFile(filePath + `/${lockFileName}`)
46
63
 
47
64
  return { projectFile, lockFile }
48
65
  }
@@ -50,5 +67,6 @@ const getDotNetDeps = (filePath, languageFiles) => {
50
67
  module.exports = {
51
68
  getDotNetDeps,
52
69
  readAndParseProjectFile,
53
- readAndParseLockFile
70
+ readAndParseLockFile,
71
+ checkForCorrectFiles
54
72
  }
@@ -1,14 +1,21 @@
1
1
  const { createGoTSMessage } = require('../common/formatMessage')
2
+ const {
3
+ parseDependenciesForSCAServices
4
+ } = require('../common/scaParserForGoAndJava')
2
5
  const goReadDepFile = require('./goReadDepFile')
3
6
  const goParseDeps = require('./goParseDeps')
4
7
 
5
- const goAnalysis = (config, languageFiles) => {
8
+ const goAnalysis = config => {
6
9
  try {
7
10
  const rawGoDependencies = goReadDepFile.getGoDependencies(config)
8
11
  const parsedGoDependencies =
9
12
  goParseDeps.parseGoDependencies(rawGoDependencies)
10
13
 
11
- return createGoTSMessage(parsedGoDependencies)
14
+ if (config.experimental) {
15
+ return parseDependenciesForSCAServices(parsedGoDependencies)
16
+ } else {
17
+ return createGoTSMessage(parsedGoDependencies)
18
+ }
12
19
  } catch (e) {
13
20
  console.log(e.message.toString())
14
21
  }
@@ -6,9 +6,13 @@ const fs = require('fs')
6
6
  const MAVEN = 'maven'
7
7
  const GRADLE = 'gradle'
8
8
 
9
- const determineProjectTypeAndCwd = (files, file) => {
9
+ const determineProjectTypeAndCwd = (files, config) => {
10
10
  const projectData = {}
11
11
 
12
+ if (files.length > 1) {
13
+ files = files.filter(i => config.fileName.includes(i))
14
+ }
15
+
12
16
  if (files[0].includes('pom.xml')) {
13
17
  projectData.projectType = MAVEN
14
18
  } else if (files[0].includes('build.gradle')) {
@@ -16,9 +20,9 @@ const determineProjectTypeAndCwd = (files, file) => {
16
20
  }
17
21
 
18
22
  //clean up the path to be a folder not a file
19
- projectData.cwd = file
20
- ? file.replace('pom.xml', '').replace('build.gradle', '')
21
- : file
23
+ projectData.cwd = config.file
24
+ ? config.file.replace('pom.xml', '').replace('build.gradle', '')
25
+ : config.file
22
26
 
23
27
  return projectData
24
28
  }
@@ -124,7 +128,7 @@ const getJavaBuildDeps = (config, files) => {
124
128
  }
125
129
 
126
130
  try {
127
- const projectData = determineProjectTypeAndCwd(files, config.file)
131
+ const projectData = determineProjectTypeAndCwd(files, config)
128
132
  if (projectData.projectType === MAVEN) {
129
133
  output.mvnDependancyTreeOutput = buildMaven(config, projectData, timeout)
130
134
  } else if (projectData.projectType === GRADLE) {
@@ -138,5 +142,6 @@ const getJavaBuildDeps = (config, files) => {
138
142
  }
139
143
 
140
144
  module.exports = {
141
- getJavaBuildDeps
145
+ getJavaBuildDeps,
146
+ determineProjectTypeAndCwd
142
147
  }
@@ -1,6 +1,9 @@
1
1
  const analysis = require('./analysis')
2
2
  const { parseBuildDeps } = require('./javaBuildDepsParser')
3
3
  const { createJavaTSMessage } = require('../common/formatMessage')
4
+ const {
5
+ parseDependenciesForSCAServices
6
+ } = require('../common/scaParserForGoAndJava')
4
7
 
5
8
  const javaAnalysis = (config, languageFiles) => {
6
9
  languageFiles.JAVA.forEach(file => {
@@ -8,7 +11,12 @@ const javaAnalysis = (config, languageFiles) => {
8
11
  })
9
12
 
10
13
  const javaDeps = buildJavaTree(config, languageFiles.JAVA)
11
- return createJavaTSMessage(javaDeps)
14
+
15
+ if (config.experimental) {
16
+ return parseDependenciesForSCAServices(javaDeps)
17
+ } else {
18
+ return createJavaTSMessage(javaDeps)
19
+ }
12
20
  }
13
21
 
14
22
  const buildJavaTree = (config, files) => {
@@ -14,14 +14,14 @@ const parseBuildDeps = (config, input) => {
14
14
  const preParser = shavedOutput => {
15
15
  let obj = []
16
16
  for (let dep in shavedOutput) {
17
+ shavedOutput[dep] = shaveDependencyType(shavedOutput[dep])
18
+
17
19
  obj.push(
18
20
  shavedOutput[dep]
19
21
  .replace('+-', '+---')
20
22
  .replace('[INFO]', '')
21
23
  .replace('\\-', '\\---')
22
24
  .replace(':jar:', ':')
23
- .replace(':test', '')
24
- .replace(':compile', '')
25
25
  .replace(' +', '+')
26
26
  .replace(' |', '|')
27
27
  .replace(' \\', '\\')
@@ -56,11 +56,29 @@ const preParser = shavedOutput => {
56
56
  return depTree
57
57
  }
58
58
 
59
+ const shaveDependencyType = dep => {
60
+ if (dep.endsWith('\r')) {
61
+ dep = dep.slice(0, -1)
62
+ }
63
+
64
+ if (dep.endsWith(':test')) {
65
+ dep = dep.slice(0, -5)
66
+ }
67
+
68
+ if (dep.endsWith(':compile')) {
69
+ dep = dep.slice(0, -8)
70
+ }
71
+
72
+ if (dep.endsWith(':provided')) {
73
+ dep = dep.slice(0, -9)
74
+ }
75
+
76
+ return dep
77
+ }
78
+
59
79
  const shaveOutput = (gradleDependencyTreeOutput, projectType) => {
60
80
  let shavedOutput = gradleDependencyTreeOutput.split('\n')
61
81
 
62
- // console.log(projectType)
63
-
64
82
  if (projectType === 'maven') {
65
83
  shavedOutput = preParser(shavedOutput)
66
84
  }
@@ -375,7 +393,6 @@ const validateIndentation = shavedOutput => {
375
393
 
376
394
  const parseGradle = (gradleDependencyTreeOutput, config, projectType) => {
377
395
  let shavedOutput = shaveOutput(gradleDependencyTreeOutput, projectType)
378
-
379
396
  if (config.subProject) {
380
397
  let subProject = parseSubProject(shavedOutput)
381
398
  let validatedOutput = validateIndentation(subProject)
@@ -400,5 +417,7 @@ module.exports = {
400
417
  computeRelationToLastElement,
401
418
  addIndentation,
402
419
  computeLevel,
403
- computeIndentation
420
+ computeIndentation,
421
+ shaveDependencyType,
422
+ preParser
404
423
  }
@@ -1,6 +1,7 @@
1
1
  const analysis = require('./analysis')
2
2
  const i18n = require('i18n')
3
3
  const formatMessage = require('../common/formatMessage')
4
+ const scaServiceParser = require('./scaServiceParser')
4
5
 
5
6
  const jsAnalysis = async (config, languageFiles) => {
6
7
  checkForCorrectFiles(languageFiles)
@@ -13,6 +14,9 @@ const jsAnalysis = async (config, languageFiles) => {
13
14
  const buildNodeTree = async (config, files) => {
14
15
  let analysis = await readFiles(config, files)
15
16
  const rawNode = await parseFiles(config, files, analysis)
17
+ if (config.experimental) {
18
+ return scaServiceParser.parseJS(rawNode)
19
+ }
16
20
  return formatMessage.createJavaScriptTSMessage(rawNode)
17
21
  }
18
22
 
@@ -0,0 +1,145 @@
1
+ const parseJS = rawNode => {
2
+ let dependencyTree = {}
3
+ let combinedPackageJSONDep = {
4
+ ...rawNode.packageJSON?.dependencies,
5
+ ...rawNode.packageJSON?.devDependencies
6
+ }
7
+ let analyseLock = chooseLockFile(rawNode)
8
+
9
+ if (analyseLock.type === 'yarn') {
10
+ dependencyTree = yarnCreateDepTree(
11
+ dependencyTree,
12
+ combinedPackageJSONDep,
13
+ analyseLock.lockFile,
14
+ rawNode
15
+ )
16
+ }
17
+
18
+ if (analyseLock.type === 'npm') {
19
+ dependencyTree = npmCreateDepTree(
20
+ dependencyTree,
21
+ combinedPackageJSONDep,
22
+ analyseLock.lockFile,
23
+ rawNode
24
+ )
25
+ }
26
+
27
+ return dependencyTree
28
+ }
29
+
30
+ const npmCreateDepTree = (
31
+ dependencyTree,
32
+ combinedPackageJSONDep,
33
+ packageLock,
34
+ rawNode
35
+ ) => {
36
+ for (const [key, value] of Object.entries(packageLock)) {
37
+ dependencyTree[key] = {
38
+ name: key,
39
+ version: getResolvedVersion(key, packageLock),
40
+ group: null,
41
+ isProduction: checkIfInPackageJSON(rawNode.packageJSON.dependencies, key),
42
+ directDependency: checkIfInPackageJSON(combinedPackageJSONDep, key),
43
+ dependencies: createNPMChildDependencies(packageLock, key)
44
+ }
45
+ }
46
+ return dependencyTree
47
+ }
48
+
49
+ const yarnCreateDepTree = (
50
+ dependencyTree,
51
+ combinedPackageJSONDep,
52
+ packageLock,
53
+ rawNode
54
+ ) => {
55
+ for (const [key, value] of Object.entries(packageLock)) {
56
+ let gav = getNameFromGAV(key)
57
+ let nag = getDepNameWithoutVersion(key)
58
+ dependencyTree[key] = {
59
+ name: gav,
60
+ version: getResolvedVersion(key, packageLock),
61
+ group: null,
62
+ isProduction: checkIfInPackageJSON(rawNode.packageJSON.dependencies, nag),
63
+ directDependency: checkIfInPackageJSON(combinedPackageJSONDep, nag),
64
+ dependencies: createChildDependencies(packageLock, key)
65
+ }
66
+ }
67
+ return dependencyTree
68
+ }
69
+
70
+ const chooseLockFile = rawNode => {
71
+ if (rawNode?.yarn?.yarnLockFile !== undefined) {
72
+ return { lockFile: rawNode?.yarn?.yarnLockFile?.object, type: 'yarn' }
73
+ } else if (rawNode.npmLockFile !== undefined) {
74
+ return { lockFile: rawNode?.npmLockFile?.dependencies, type: 'npm' }
75
+ } else {
76
+ return undefined
77
+ }
78
+ }
79
+
80
+ const createKeyName = (dep, version) => {
81
+ return dep + '@' + version
82
+ }
83
+
84
+ const checkIfInPackageJSON = (list, dep) => {
85
+ return Object.keys(list).includes(dep)
86
+ }
87
+
88
+ const createChildDependencies = (lockFileDep, currentDep) => {
89
+ let depArray = []
90
+ if (lockFileDep[currentDep]?.dependencies) {
91
+ for (const [key, value] of Object.entries(
92
+ lockFileDep[currentDep]?.dependencies
93
+ )) {
94
+ depArray.push(createKeyName(key, value))
95
+ }
96
+ }
97
+ return depArray
98
+ }
99
+
100
+ const createNPMChildDependencies = (lockFileDep, currentDep) => {
101
+ let depArray = []
102
+ if (lockFileDep[currentDep]?.requires) {
103
+ for (const [key, value] of Object.entries(
104
+ lockFileDep[currentDep]?.requires
105
+ )) {
106
+ depArray.push(key)
107
+ }
108
+ }
109
+ return depArray
110
+ }
111
+
112
+ const getDepNameWithoutVersion = depKey => {
113
+ let dependency = depKey.split('@')
114
+ if (dependency.length - 1 > 1) {
115
+ return '@' + dependency[1]
116
+ }
117
+ return dependency[0]
118
+ }
119
+
120
+ const getNameFromGAV = depKey => {
121
+ let dependency = depKey.split('/')
122
+ if (dependency.length == 2) {
123
+ dependency = getDepNameWithoutVersion(dependency[1])
124
+ return dependency
125
+ }
126
+ if (dependency.length == 1) {
127
+ dependency = getDepNameWithoutVersion(depKey)
128
+ return dependency
129
+ }
130
+ //what should we do if there's no version? The service will fall over but do we want to throw error for only one wrong version?
131
+ return depKey
132
+ }
133
+
134
+ const getResolvedVersion = (depKey, packageLock) => {
135
+ return packageLock[depKey]?.version
136
+ }
137
+
138
+ module.exports = {
139
+ parseJS,
140
+ checkIfInPackageJSON,
141
+ getNameFromGAV,
142
+ getResolvedVersion,
143
+ chooseLockFile,
144
+ createNPMChildDependencies
145
+ }
@@ -5,7 +5,7 @@ const _ = require('lodash')
5
5
  const readFile = (config, nameOfFile) => {
6
6
  if (config.file) {
7
7
  try {
8
- return fs.readFileSync(config.file + '/' + nameOfFile)
8
+ return fs.readFileSync(config.file + '/' + nameOfFile, 'utf8')
9
9
  } catch (error) {
10
10
  console.log('Unable to find file')
11
11
  console.log(error)
@@ -1,13 +1,19 @@
1
1
  const { readFile, parseProjectFiles } = require('./analysis')
2
2
  const { createPhpTSMessage } = require('../common/formatMessage')
3
+ const { parsePHPLockFileForScaServices } = require('./phpNewServicesMapper')
3
4
 
4
- const phpAnalysis = (config, files) => {
5
- let analysis = readFiles(config, files.PHP)
6
- const phpDep = parseProjectFiles(analysis)
7
- return createPhpTSMessage(phpDep)
5
+ const phpAnalysis = config => {
6
+ let analysis = readFiles(config)
7
+
8
+ if (config.experimental) {
9
+ return parsePHPLockFileForScaServices(analysis.rawLockFileContents)
10
+ } else {
11
+ const phpDep = parseProjectFiles(analysis)
12
+ return createPhpTSMessage(phpDep)
13
+ }
8
14
  }
9
15
 
10
- const readFiles = (config, files) => {
16
+ const readFiles = config => {
11
17
  let php = {}
12
18
 
13
19
  php.composerJSON = JSON.parse(readFile(config, 'composer.json'))
@@ -18,5 +24,5 @@ const readFiles = (config, files) => {
18
24
  }
19
25
 
20
26
  module.exports = {
21
- phpAnalysis
27
+ phpAnalysis: phpAnalysis
22
28
  }