scanoss 0.2.18 → 0.2.21

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 (154) hide show
  1. package/build/main/bin/cli-bin.js +4 -2
  2. package/build/main/commands/dep.js +19 -7
  3. package/build/main/commands/helpers.d.ts +1 -0
  4. package/build/main/commands/helpers.js +22 -0
  5. package/build/main/commands/scan.js +3 -15
  6. package/build/main/index.d.ts +2 -1
  7. package/build/main/index.js +3 -2
  8. package/build/main/lib/dependencies/DependencyScanner.d.ts +10 -0
  9. package/build/main/lib/dependencies/DependencyScanner.js +66 -0
  10. package/build/main/lib/dependencies/DependencyScannerCfg.d.ts +4 -0
  11. package/build/main/lib/dependencies/DependencyScannerCfg.js +11 -0
  12. package/build/main/lib/dependencies/DependencyTypes.d.ts +10 -8
  13. package/build/main/lib/dependencies/LocalDependency/DependencyTypes.d.ts +16 -0
  14. package/build/main/lib/dependencies/LocalDependency/DependencyTypes.js +3 -0
  15. package/build/main/lib/dependencies/LocalDependency/LocalDependency.d.ts +6 -0
  16. package/build/main/lib/dependencies/LocalDependency/LocalDependency.js +51 -0
  17. package/build/main/lib/dependencies/LocalDependency/parsers/golangParser.d.ts +2 -0
  18. package/build/main/lib/dependencies/LocalDependency/parsers/golangParser.js +63 -0
  19. package/build/main/lib/dependencies/LocalDependency/parsers/mavenParser.d.ts +2 -0
  20. package/build/main/lib/dependencies/LocalDependency/parsers/mavenParser.js +57 -0
  21. package/build/main/lib/dependencies/{parsers → LocalDependency/parsers}/npmParser.d.ts +3 -3
  22. package/build/main/lib/dependencies/LocalDependency/parsers/npmParser.js +50 -0
  23. package/build/main/lib/dependencies/LocalDependency/parsers/pyParser.d.ts +2 -0
  24. package/build/main/lib/dependencies/LocalDependency/parsers/pyParser.js +61 -0
  25. package/build/main/lib/dependencies/{parsers → LocalDependency/parsers}/rubyParser.d.ts +3 -3
  26. package/build/main/lib/dependencies/LocalDependency/parsers/rubyParser.js +133 -0
  27. package/build/main/lib/dependencies/{parsers → LocalDependency/parsers}/utils.d.ts +0 -0
  28. package/build/main/lib/dependencies/{parsers → LocalDependency/parsers}/utils.js +1 -1
  29. package/build/main/lib/grpc/GrpcDependencyService.d.ts +11 -0
  30. package/build/main/lib/grpc/GrpcDependencyService.js +88 -0
  31. package/build/main/lib/{dependencies/parsers/golangParser.d.ts → grpc/scanoss/api/common/v2/scanoss-common_grpc_pb.d.ts} +0 -0
  32. package/build/main/lib/grpc/scanoss/api/common/v2/scanoss-common_grpc_pb.js +2 -0
  33. package/build/main/lib/grpc/scanoss/api/common/v2/scanoss-common_pb.d.ts +1 -0
  34. package/build/main/lib/grpc/scanoss/api/common/v2/scanoss-common_pb.js +404 -0
  35. package/build/main/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_grpc_pb.d.ts +42 -0
  36. package/build/main/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_grpc_pb.js +98 -0
  37. package/build/main/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb.d.ts +1 -0
  38. package/build/main/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb.js +1197 -0
  39. package/build/main/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_grpc_pb.d.ts +21 -0
  40. package/build/main/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_grpc_pb.js +66 -0
  41. package/build/main/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_pb.d.ts +1 -0
  42. package/build/main/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_pb.js +14 -0
  43. package/build/main/lib/scanner/Scanner.js +1 -1
  44. package/build/module/bin/cli-bin.js +4 -2
  45. package/build/module/commands/dep.js +19 -7
  46. package/build/module/commands/helpers.d.ts +1 -0
  47. package/build/module/commands/helpers.js +15 -0
  48. package/build/module/commands/scan.js +2 -14
  49. package/build/module/index.d.ts +2 -1
  50. package/build/module/index.js +3 -2
  51. package/build/module/lib/dependencies/DependencyScanner.d.ts +10 -0
  52. package/build/module/lib/dependencies/DependencyScanner.js +64 -0
  53. package/build/module/lib/dependencies/DependencyScannerCfg.d.ts +4 -0
  54. package/build/module/lib/dependencies/DependencyScannerCfg.js +5 -0
  55. package/build/module/lib/dependencies/DependencyTypes.d.ts +10 -8
  56. package/build/module/lib/dependencies/LocalDependency/DependencyTypes.d.ts +16 -0
  57. package/build/module/lib/dependencies/LocalDependency/DependencyTypes.js +2 -0
  58. package/build/module/lib/dependencies/LocalDependency/LocalDependency.d.ts +6 -0
  59. package/build/module/lib/dependencies/LocalDependency/LocalDependency.js +45 -0
  60. package/build/module/lib/dependencies/LocalDependency/parsers/golangParser.d.ts +2 -0
  61. package/build/module/lib/dependencies/LocalDependency/parsers/golangParser.js +55 -0
  62. package/build/module/lib/dependencies/LocalDependency/parsers/mavenParser.d.ts +2 -0
  63. package/build/module/lib/dependencies/LocalDependency/parsers/mavenParser.js +50 -0
  64. package/build/module/lib/dependencies/{parsers → LocalDependency/parsers}/npmParser.d.ts +3 -3
  65. package/build/module/lib/dependencies/LocalDependency/parsers/npmParser.js +42 -0
  66. package/build/module/lib/dependencies/LocalDependency/parsers/pyParser.d.ts +2 -0
  67. package/build/module/lib/dependencies/LocalDependency/parsers/pyParser.js +53 -0
  68. package/build/module/lib/dependencies/{parsers → LocalDependency/parsers}/rubyParser.d.ts +3 -3
  69. package/build/module/lib/dependencies/LocalDependency/parsers/rubyParser.js +130 -0
  70. package/build/module/lib/dependencies/{parsers → LocalDependency/parsers}/utils.d.ts +0 -0
  71. package/build/module/lib/dependencies/LocalDependency/parsers/utils.js +15 -0
  72. package/build/module/lib/grpc/GrpcDependencyService.d.ts +11 -0
  73. package/build/module/lib/grpc/GrpcDependencyService.js +67 -0
  74. package/build/module/lib/{dependencies/parsers/golangParser.d.ts → grpc/scanoss/api/common/v2/scanoss-common_grpc_pb.d.ts} +0 -0
  75. package/build/module/lib/grpc/scanoss/api/common/v2/scanoss-common_grpc_pb.js +2 -0
  76. package/build/module/lib/grpc/scanoss/api/common/v2/scanoss-common_pb.d.ts +1 -0
  77. package/build/module/lib/grpc/scanoss/api/common/v2/scanoss-common_pb.js +404 -0
  78. package/build/module/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_grpc_pb.d.ts +42 -0
  79. package/build/module/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_grpc_pb.js +98 -0
  80. package/build/module/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb.d.ts +1 -0
  81. package/build/module/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb.js +1197 -0
  82. package/build/module/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_grpc_pb.d.ts +21 -0
  83. package/build/module/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_grpc_pb.js +66 -0
  84. package/build/module/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_pb.d.ts +1 -0
  85. package/build/module/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_pb.js +14 -0
  86. package/build/module/lib/scanner/Scanner.js +1 -1
  87. package/build/tsconfig.module.tsbuildinfo +1 -1
  88. package/build/tsconfig.tsbuildinfo +1 -1
  89. package/package.json +3 -1
  90. package/src/bin/cli-bin.ts +4 -1
  91. package/src/commands/dep.ts +18 -6
  92. package/src/commands/helpers.ts +14 -0
  93. package/src/commands/scan.ts +3 -12
  94. package/src/index.ts +5 -1
  95. package/src/lib/dependencies/DependencyScanner.ts +77 -0
  96. package/src/lib/dependencies/DependencyScannerCfg.ts +7 -0
  97. package/src/lib/dependencies/DependencyTypes.ts +16 -14
  98. package/src/lib/dependencies/LocalDependency/DependencyTypes.ts +21 -0
  99. package/src/lib/dependencies/LocalDependency/LocalDependency.ts +48 -0
  100. package/src/lib/dependencies/LocalDependency/parsers/golangParser.ts +78 -0
  101. package/src/lib/dependencies/{parsers → LocalDependency/parsers}/mavenParser.ts +10 -6
  102. package/src/lib/dependencies/{parsers → LocalDependency/parsers}/npmParser.ts +14 -8
  103. package/src/lib/dependencies/LocalDependency/parsers/pyParser.ts +55 -0
  104. package/src/lib/dependencies/{parsers → LocalDependency/parsers}/rubyParser.ts +21 -29
  105. package/src/lib/dependencies/{parsers → LocalDependency/parsers}/utils.ts +0 -1
  106. package/src/lib/grpc/GrpcDependencyService.ts +73 -0
  107. package/src/lib/grpc/scanoss/api/common/v2/scanoss-common_grpc_pb.d.ts +1 -0
  108. package/src/lib/grpc/scanoss/api/common/v2/scanoss-common_grpc_pb.js +1 -0
  109. package/src/lib/grpc/scanoss/api/common/v2/scanoss-common_pb.d.ts +79 -0
  110. package/src/lib/grpc/scanoss/api/common/v2/scanoss-common_pb.js +482 -0
  111. package/src/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_grpc_pb.d.ts +30 -0
  112. package/src/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_grpc_pb.js +109 -0
  113. package/src/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb.d.ts +206 -0
  114. package/src/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb.js +1489 -0
  115. package/src/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_grpc_pb.d.ts +25 -0
  116. package/src/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_grpc_pb.js +73 -0
  117. package/src/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_pb.d.ts +6 -0
  118. package/src/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_pb.js +15 -0
  119. package/src/lib/scanner/Scanner.ts +2 -1
  120. package/tsconfig.json +5 -22
  121. package/yarn.lock +5252 -5213
  122. package/build/main/lib/dependencies/Dependency.d.ts +0 -9
  123. package/build/main/lib/dependencies/Dependency.js +0 -52
  124. package/build/main/lib/dependencies/PurlGenerator.d.ts +0 -2
  125. package/build/main/lib/dependencies/PurlGenerator.js +0 -44
  126. package/build/main/lib/dependencies/parsers/golangParser.js +0 -3
  127. package/build/main/lib/dependencies/parsers/mavenParser.d.ts +0 -2
  128. package/build/main/lib/dependencies/parsers/mavenParser.js +0 -54
  129. package/build/main/lib/dependencies/parsers/npmParser.js +0 -46
  130. package/build/main/lib/dependencies/parsers/pyParser.d.ts +0 -2
  131. package/build/main/lib/dependencies/parsers/pyParser.js +0 -51
  132. package/build/main/lib/dependencies/parsers/rubyParser.js +0 -135
  133. package/build/main/lib/dependencies/parsers/types.d.ts +0 -15
  134. package/build/main/lib/dependencies/parsers/types.js +0 -33
  135. package/build/module/lib/dependencies/Dependency.d.ts +0 -9
  136. package/build/module/lib/dependencies/Dependency.js +0 -47
  137. package/build/module/lib/dependencies/PurlGenerator.d.ts +0 -2
  138. package/build/module/lib/dependencies/PurlGenerator.js +0 -37
  139. package/build/module/lib/dependencies/parsers/golangParser.js +0 -3
  140. package/build/module/lib/dependencies/parsers/mavenParser.d.ts +0 -2
  141. package/build/module/lib/dependencies/parsers/mavenParser.js +0 -47
  142. package/build/module/lib/dependencies/parsers/npmParser.js +0 -38
  143. package/build/module/lib/dependencies/parsers/pyParser.d.ts +0 -2
  144. package/build/module/lib/dependencies/parsers/pyParser.js +0 -44
  145. package/build/module/lib/dependencies/parsers/rubyParser.js +0 -132
  146. package/build/module/lib/dependencies/parsers/types.d.ts +0 -15
  147. package/build/module/lib/dependencies/parsers/types.js +0 -32
  148. package/build/module/lib/dependencies/parsers/utils.js +0 -15
  149. package/package-lock.json +0 -18589
  150. package/src/lib/dependencies/Dependency.ts +0 -60
  151. package/src/lib/dependencies/PurlGenerator.ts +0 -44
  152. package/src/lib/dependencies/parsers/golangParser.ts +0 -4
  153. package/src/lib/dependencies/parsers/pyParser.ts +0 -46
  154. package/src/lib/dependencies/parsers/types.ts +0 -50
@@ -1,18 +1,30 @@
1
1
  import fs from "fs";
2
- import { Dependency } from "..";
2
+ import { DependencyScanner } from "../lib/dependencies/DependencyScanner";
3
+ import { DependencyScannerCfg } from "../lib/dependencies/DependencyScannerCfg";
3
4
  import { Tree } from "../lib/tree/Tree";
5
+ import { isFolder } from "./helpers";
4
6
 
5
7
  export async function depHandler(rootPath: string, options: any): Promise<void> {
8
+
6
9
  rootPath = rootPath.replace(/\/$/, ''); // Remove trailing slash if exists
7
10
  rootPath = rootPath.replace(/^\./, process.env.PWD); // Convert relative path to absolute path.
11
+ const pathIsFolder = await isFolder(rootPath);
12
+ const dependencyScannerCfg = new DependencyScannerCfg();
13
+ if(options.grpcHost) dependencyScannerCfg.DEFAULT_GRPC_HOST = options.grpcHost;
14
+ if(options.grpcPort) dependencyScannerCfg.DEFAULT_GRPC_PORT = options.grpcPort;
15
+
16
+ const dependencyScanner = new DependencyScanner(dependencyScannerCfg);
8
17
 
9
- const tree = new Tree(rootPath);
10
- tree.buildTree();
18
+ let fileList: Array<string> = [];
19
+ fileList.push(rootPath);
11
20
 
12
- const fileList = tree.getRootFolder().getFiles().map((path) => {return rootPath+path});
21
+ if (pathIsFolder) {
22
+ const tree = new Tree(rootPath);
23
+ tree.buildTree();
24
+ fileList = tree.getRootFolder().getFiles().map((path) => {return rootPath+path});
25
+ }
13
26
 
14
- const dependency = new Dependency();
15
- const results = await dependency.scan(fileList);
27
+ const results = await dependencyScanner.scan(fileList);
16
28
 
17
29
  if(options.output) {
18
30
  fs.promises.writeFile(options.output, JSON.stringify(results, null, 2));
@@ -0,0 +1,14 @@
1
+ import fs from 'fs';
2
+
3
+ // Async function that verify if a path is a folder. If the path is not valid the promise will be rejected
4
+ export const isFolder = (path: string): Promise<boolean> => {
5
+ return new Promise((resolve, reject) => {
6
+ fs.stat(path, (err, stats) => {
7
+ if (err) {
8
+ reject(err);
9
+ } else {
10
+ resolve(stats.isDirectory());
11
+ }
12
+ });
13
+ });
14
+ }
@@ -8,20 +8,11 @@ import { DispatcherResponse } from '../lib/scanner/Dispatcher/DispatcherResponse
8
8
  import { defaultFilter } from '../lib/filters/defaultFilter';
9
9
  import { FilterList } from '../lib/filters/filtering';
10
10
 
11
+ import { isFolder } from './helpers';
12
+
11
13
  import fs from 'fs';
12
14
 
13
- // Async function that verify if a path is a folder. If the path is not valid the promise will be rejected
14
- const isFolder = (path: string): Promise<boolean> => {
15
- return new Promise((resolve, reject) => {
16
- fs.stat(path, (err, stats) => {
17
- if (err) {
18
- reject(err);
19
- } else {
20
- resolve(stats.isDirectory());
21
- }
22
- });
23
- });
24
- }
15
+
25
16
 
26
17
  export async function scanHandler(rootPath: string, options: any): Promise<void> {
27
18
 
package/src/index.ts CHANGED
@@ -2,4 +2,8 @@ export * from './lib/scanner/ScannerTypes';
2
2
  export * from './lib/scanner/ScannerCfg'
3
3
  export * from './lib/scanner/Scanner'
4
4
  export * from './lib/dependencies/DependencyTypes';
5
- export * from './lib/dependencies/Dependency';
5
+ export * from './lib/dependencies/DependencyScannerCfg';
6
+ export * from './lib/dependencies/DependencyScanner';
7
+
8
+
9
+
@@ -0,0 +1,77 @@
1
+ import { ILocalDependencies } from "./LocalDependency/DependencyTypes";
2
+ import { GrpcDependencyService } from "../grpc/GrpcDependencyService";
3
+ import { DependencyRequest, DependencyResponse } from "../grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb";
4
+ import { LocalDependencies } from "./LocalDependency/LocalDependency";
5
+ import { DependencyScannerCfg } from "./DependencyScannerCfg";
6
+ import { IDependencyResponse } from "./DependencyTypes";
7
+
8
+ export class DependencyScanner {
9
+
10
+ private localDependency: LocalDependencies;
11
+
12
+ private grpcDependencyService: GrpcDependencyService;
13
+
14
+ constructor(cfg = new DependencyScannerCfg()) {
15
+ this.grpcDependencyService = new GrpcDependencyService(cfg.DEFAULT_GRPC_HOST, cfg.DEFAULT_GRPC_PORT);
16
+ this.localDependency = new LocalDependencies();
17
+ }
18
+
19
+
20
+ public async scan(files: Array<string>): Promise<IDependencyResponse> {
21
+ const localDependencies = await this.localDependency.search(files);
22
+ if (localDependencies.files.length === 0) return null;
23
+ const request = this.buildRequest(localDependencies);
24
+ const grpcResponse = await this.grpcDependencyService.get(request);
25
+ const response = grpcResponse.toObject();
26
+
27
+ // Extract scope from localDependencies and add it to response
28
+ this.mergeScopeField(localDependencies, response);
29
+ return response;
30
+ }
31
+
32
+
33
+ private buildRequest(localDependencies: ILocalDependencies): DependencyRequest {
34
+ try {
35
+ const depRequest = new DependencyRequest();
36
+ for (const file of localDependencies.files) {
37
+ const fileMsg = new DependencyRequest.Files();
38
+ fileMsg.setFile(file.file);
39
+ for (const purl of file.purls) {
40
+ const purlMsg = new DependencyRequest.Purls();
41
+ purlMsg.setPurl(purl.purl);
42
+ purlMsg.setRequirement(purl?.requirements);
43
+ fileMsg.addPurls(purlMsg);
44
+ }
45
+ depRequest.addFiles(fileMsg);
46
+ }
47
+ return depRequest;
48
+ } catch (e) {
49
+ console.error(e);
50
+ return null;
51
+ }
52
+ }
53
+
54
+ private mergeScopeField(localdependency: ILocalDependencies, serverResponse: DependencyResponse.AsObject
55
+ ): IDependencyResponse {
56
+
57
+ const scopeHashMap = {};
58
+
59
+ for (const file of localdependency.files) {
60
+ const filename = file.file
61
+ for (const dependency of file.purls) {
62
+ if (dependency?.scope) scopeHashMap[filename + dependency.purl] = dependency.scope;
63
+ }
64
+ }
65
+
66
+ for (const file of serverResponse.filesList) {
67
+ const filename = file.file
68
+ for (const dependency of file.dependenciesList) {
69
+ const scope = scopeHashMap[filename + dependency.purl];
70
+ if (scope) dependency['scope'] = scope;
71
+ }
72
+ }
73
+
74
+ return serverResponse;
75
+ }
76
+
77
+ }
@@ -0,0 +1,7 @@
1
+ export class DependencyScannerCfg {
2
+
3
+ DEFAULT_GRPC_PORT = '443';
4
+
5
+ DEFAULT_GRPC_HOST = 'scanoss.com';
6
+
7
+ }
@@ -1,22 +1,24 @@
1
-
2
- interface ILicense {
3
- name: string;
1
+ export interface LicensesList {
2
+ name: string;
3
+ spdxId: string;
4
+ isSpdxApproved: boolean;
4
5
  }
5
6
 
6
- export interface IDependency {
7
- component: string;
8
- purl: string;
9
- version: string;
10
- licenses: Array<ILicense>;
7
+ export interface DependenciesList {
8
+ component: string;
9
+ purl: string;
10
+ version?: string;
11
+ scope?: string;
12
+ licensesList: LicensesList[];
11
13
  }
12
14
 
13
- export interface IFile {
14
- file: string;
15
- id: string;
16
- status: string;
17
- dependencies: Array<IDependency>;
15
+ export interface FilesList {
16
+ file: string;
17
+ id: string;
18
+ status: string;
19
+ dependenciesList: DependenciesList[];
18
20
  }
19
21
 
20
22
  export interface IDependencyResponse {
21
- files: Array<IFile>;
23
+ filesList: FilesList[];
22
24
  }
@@ -0,0 +1,21 @@
1
+ export interface ILocalPurl {
2
+ purl: string;
3
+ requirements?: string;
4
+ scope?: string;
5
+ }
6
+
7
+ export interface ILocalDependency {
8
+ file: string;
9
+ purls: Array<ILocalPurl>;
10
+ }
11
+
12
+ export interface ILocalDependencies{
13
+ files: Array<ILocalDependency>;
14
+ }
15
+
16
+ /* Parser funcion definition */
17
+ export type ParserFuncType = (fileContent: string, filePath: string) => ILocalDependency;
18
+
19
+ export interface ParserDefinitions {
20
+ [key: string]: ParserFuncType;
21
+ }
@@ -0,0 +1,48 @@
1
+ import path from 'path';
2
+ import fs from 'fs';
3
+ import { ParserFuncType, ILocalDependencies } from "./DependencyTypes";
4
+ import { requirementsParser } from "./parsers/pyParser";
5
+ import { pomParser } from "./parsers/mavenParser";
6
+ import { packagelockParser, packageParser } from "./parsers/npmParser";
7
+ import { gemfilelockParser, gemfileParser } from "./parsers/rubyParser";
8
+ import { goModParser } from './parsers/golangParser';
9
+
10
+ export class LocalDependencies {
11
+
12
+ private parserMap: Record<string, ParserFuncType>;
13
+
14
+ constructor() {
15
+ /*
16
+ This is a hash map that connect a filename with it's own parser function
17
+ Any parser function must return a ILocalDependencies object (See DependencyTypes.ts)
18
+ */
19
+ this.parserMap = {
20
+ 'requirements.txt': requirementsParser,
21
+ 'pom.xml': pomParser,
22
+ 'package.json': packageParser,
23
+ 'package-lock.json': packagelockParser,
24
+ 'Gemfile': gemfileParser,
25
+ 'Gemfile.lock': gemfilelockParser,
26
+ 'go.mod': goModParser,
27
+ };
28
+ }
29
+
30
+ public async search(files: Array<string>): Promise<ILocalDependencies> {
31
+ let results: ILocalDependencies = {files: []};
32
+ for (const filePath of files) {
33
+ const fileName = path.basename(filePath);
34
+ if(this.parserMap[fileName] != null) {
35
+ try{
36
+ const fileContent = await fs.promises.readFile(filePath, 'utf8');
37
+ const dependency = this.parserMap[fileName](fileContent, filePath);
38
+ if(dependency.purls.length != 0)
39
+ results.files.push(dependency);
40
+ } catch(e) {
41
+ console.error(e);
42
+ continue;
43
+ }
44
+ }
45
+ }
46
+ return results;
47
+ }
48
+ }
@@ -0,0 +1,78 @@
1
+ import { ILocalDependency } from "../DependencyTypes";
2
+
3
+ import { PackageURL } from "packageurl-js";
4
+ import path from "path";
5
+
6
+ function parseModule (str: string) {
7
+ const res = /(?<type>[^\s]+)(?:\s)+(?<ns_name>[^\s]+)\s?(?<version>(.*))/.exec(str);
8
+ return {
9
+ type: res.groups.type,
10
+ ns_name: res.groups.ns_name,
11
+ version: res.groups.version
12
+ };
13
+ }
14
+
15
+ function parseDepLink (str: string) {
16
+ const res = /.*?(?<ns_name>[^\s]+)\s+(?<version>(.*))/.exec(str);
17
+ return {
18
+ ns_name: res?.groups?.ns_name,
19
+ version: res?.groups?.version
20
+ };
21
+ }
22
+
23
+ // Removes comments and spaces
24
+ function preprocessLine(line: string) {
25
+ if (line.includes("//"))
26
+ line = line.substring(0,line.indexOf("//"));
27
+ return line.trim();
28
+ }
29
+
30
+
31
+
32
+
33
+ const PURL_TYPE = 'golang';
34
+
35
+
36
+ // See reference on: https://go.dev/ref/mod#go-mod-file
37
+ const MANIFEST_FILE = 'go.mod';
38
+ export function goModParser(fileContent: string, filePath: string): ILocalDependency {
39
+
40
+ // If the file is not a go.mod manifest file, return an empty results
41
+ const results: ILocalDependency = {file: filePath, purls: []};
42
+ if(path.basename(filePath) != MANIFEST_FILE)
43
+ return results;
44
+
45
+ const lines = fileContent.split('\n');
46
+
47
+ const require = [];
48
+ const exclude = [];
49
+
50
+ for (let num = 0 ; num < lines.length ; num+=1) {
51
+
52
+ let line = preprocessLine(lines[num]);
53
+
54
+
55
+ if(line.includes('require') && line.includes('(')) {
56
+ num+=1;
57
+ line = preprocessLine(lines[num]);
58
+ while (num < lines.length && line!==')') {
59
+
60
+ const {ns_name, version} = parseDepLink(line);
61
+
62
+ const index = ns_name.lastIndexOf('/');
63
+ const namespace = ns_name.substring(0, index);
64
+ const name = ns_name.substring(index + 1);
65
+
66
+ const purlString = new PackageURL(PURL_TYPE, namespace, name, version, undefined, undefined).toString();
67
+ results.purls.push({purl: purlString});
68
+
69
+ require.push(line);
70
+
71
+ num+=1;
72
+ line = preprocessLine(lines[num]);
73
+ }
74
+ }
75
+ }
76
+
77
+ return results;
78
+ }
@@ -1,19 +1,19 @@
1
1
  import path from "path";
2
2
  import { PackageURL } from "packageurl-js";
3
- import { FileDependency } from "./types";
4
- import { isValidPath, isValidUrl } from './utils';
3
+ import { ILocalDependency } from "../DependencyTypes";
5
4
 
6
5
  const PURL_TYPE = 'maven';
7
6
 
8
7
 
8
+
9
9
  // Parse a pom.txt file from maven manifest file
10
10
  // See reference on: https://maven.apache.org/guides/introduction/introduction-to-the-pom.html
11
11
  // and https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
12
12
  const MANIFEST_FILE = 'pom.xml';
13
- export function pomParser(fileContent: string, filePath: string): FileDependency {
13
+ export function pomParser(fileContent: string, filePath: string): ILocalDependency {
14
14
 
15
15
  // If the file is not a python manifest file, return an empty results
16
- const results: FileDependency = {file: filePath, purls: []};
16
+ const results: ILocalDependency = {file: filePath, purls: []};
17
17
  if(path.basename(filePath) != MANIFEST_FILE)
18
18
  return results;
19
19
 
@@ -34,7 +34,7 @@ export function pomParser(fileContent: string, filePath: string): FileDependency
34
34
  let version = versionReg ? versionReg[1] : '';
35
35
 
36
36
  const ver = version.match(/\${(.*?)}/);
37
- if(ver && ver.length >= 1) {
37
+ if(ver && ver.length >= 1) {
38
38
  if(ver[1] === 'project.version') { // TODO: Add support for project.version
39
39
  version = undefined;
40
40
  } else {
@@ -50,8 +50,12 @@ export function pomParser(fileContent: string, filePath: string): FileDependency
50
50
  purlQualifiers['type'] = type[1]
51
51
  }
52
52
 
53
+ // Extract scope.
54
+ const scopeRes = dependency.match(/<scope>([^<]*)<\/scope>/);
55
+ const scope = scopeRes ? scopeRes[1] : undefined;
56
+
53
57
  const purlString = new PackageURL(PURL_TYPE, namespace, name, version, purlQualifiers, undefined).toString();
54
- results.purls.push({purl: purlString});
58
+ results.purls.push({purl: purlString, scope: scope});
55
59
  });
56
60
  }
57
61
  return results;
@@ -1,7 +1,6 @@
1
1
  import path from "path";
2
2
  import { PackageURL } from "packageurl-js";
3
- import { FileDependency } from "./types";
4
- import { isValidPath, isValidUrl } from './utils';
3
+ import { ILocalDependency } from "../DependencyTypes";
5
4
 
6
5
  const PURL_TYPE = 'npm';
7
6
 
@@ -9,19 +8,26 @@ const PURL_TYPE = 'npm';
9
8
  // Parse a package.json file from node projects
10
9
  // See reference on: https://docs.npmjs.com/cli/v8/configuring-npm/package-json
11
10
  const MANIFEST_FILE = 'package.json';
12
- export function packageParser(fileContent: string, filePath: string): FileDependency {
11
+ export function packageParser(fileContent: string, filePath: string): ILocalDependency {
13
12
  // If the file is not manifest file, return an empty results
14
- const results: FileDependency = {file: filePath, purls: []};
13
+ const results: ILocalDependency = {file: filePath, purls: []};
15
14
  if(path.basename(filePath) != MANIFEST_FILE)
16
15
  return results;
17
16
  const o = JSON.parse(fileContent);
18
17
  let devDeps = Object.keys(o.devDependencies || {});
19
18
  let deps = Object.keys(o.dependencies || {});
20
19
  let listDeps = [...deps, ...devDeps];
21
- for(const name of listDeps){
20
+
21
+ for(const name of deps){
22
22
  const purlString = new PackageURL(PURL_TYPE, undefined, name, undefined, undefined, undefined).toString();
23
- results.purls.push({purl: purlString});
23
+ results.purls.push({purl: purlString, scope: "dependencies", requirements: o.dependencies[name]});
24
+ }
25
+
26
+ for(const name of devDeps){
27
+ const purlString = new PackageURL(PURL_TYPE, undefined, name, undefined, undefined, undefined).toString();
28
+ results.purls.push({purl: purlString, scope: "devDependencies", requirements: o.devDependencies[name]});
24
29
  }
30
+
25
31
  return results;
26
32
  }
27
33
 
@@ -29,9 +35,9 @@ export function packageParser(fileContent: string, filePath: string): FileDepend
29
35
  // Parse a package-lock.json file from node projects
30
36
  // See reference on: https://docs.npmjs.com/cli/v8/configuring-npm/package-json
31
37
  const MANIFEST_FILE_1 = 'package-lock.json';
32
- export function packagelockParser(fileContent: string, filePath: string): FileDependency {
38
+ export function packagelockParser(fileContent: string, filePath: string): ILocalDependency {
33
39
 
34
- const results: FileDependency = {file: filePath, purls: []};
40
+ const results: ILocalDependency = {file: filePath, purls: []};
35
41
  if(path.basename(filePath) != MANIFEST_FILE_1)
36
42
  return results;
37
43
 
@@ -0,0 +1,55 @@
1
+ import path from "path";
2
+ import { PackageURL } from "packageurl-js";
3
+ import { ILocalDependency } from "../DependencyTypes";
4
+ import { isValidPath, isValidUrl } from './utils';
5
+
6
+
7
+ function parseDep (str: string) {
8
+ const res = /^(?<name>[-\w]+)\s*(?<sym>[>=~!]*)\s*(?<version>[\d\.]*)/.exec(str);
9
+ return {
10
+ name: res?.groups?.name,
11
+ sym: res?.groups?.sym,
12
+ version: res?.groups?.version,
13
+ };
14
+ }
15
+
16
+ const PURL_TYPE = 'pypi';
17
+
18
+ // Parse a requirements.txt file from python projects
19
+ // See reference on: https://pip.pypa.io/en/stable/reference/requirements-file-format/
20
+ const MANIFEST_FILE = 'requirements.txt';
21
+ export function requirementsParser(fileContent: string, filePath: string): ILocalDependency {
22
+
23
+ // If the file is not a python manifest file, return an empty results
24
+ const results: ILocalDependency = {file: filePath, purls: []};
25
+ if(path.basename(filePath) != MANIFEST_FILE)
26
+ return results;
27
+
28
+ const lines: Array<string> = fileContent.split('\n');
29
+
30
+ for (let line of lines) {
31
+ line = line.trim();
32
+ if(line.length == 0) continue;
33
+ if(!line.startsWith('#') && line.length>0) { // Avoid comments and new lines
34
+ if(isValidUrl(line)) {
35
+ // For reference about the regex see https://www.rfc-editor.org/rfc/rfc3986#appendix-B
36
+ const res = line.match(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/);
37
+ continue;
38
+ }
39
+ else if(isValidPath(line)) {continue;} // Do not parse local dependencies.
40
+ else if(line.startsWith('-r')) {continue;} // Recursive dependencies (NOT SUPPORTED YET)
41
+ else {
42
+
43
+ const dep = parseDep(line);
44
+ if (dep.sym === '==') {
45
+ const purlString = new PackageURL(PURL_TYPE, undefined, dep.name, dep.version, undefined, undefined).toString();
46
+ results.purls.push({purl: purlString});
47
+ } else {
48
+ const purlString = new PackageURL(PURL_TYPE, undefined, dep.name, undefined, undefined, undefined).toString();
49
+ results.purls.push({purl: purlString, requirements: dep.sym+dep.version});
50
+ }
51
+ }
52
+ }
53
+ }
54
+ return results;
55
+ }
@@ -1,8 +1,7 @@
1
1
  import path from "path";
2
2
  import { PackageURL } from "packageurl-js";
3
- import { FileDependency } from "./types";
4
- import { isValidPath, isValidUrl } from './utils';
5
- import { stringify } from "querystring";
3
+ import { ILocalDependency } from "../DependencyTypes";
4
+
6
5
 
7
6
  const PURL_TYPE = 'gem';
8
7
 
@@ -11,10 +10,10 @@ const PURL_TYPE = 'gem';
11
10
  // See reference on: https://bundler.io/gemfile.html
12
11
  // and https://bundler.io/man/gemfile.5.html
13
12
  const MANIFEST_FILE = 'Gemfile';
14
- export function gemfileParser(fileContent: string, filePath: string): FileDependency {
15
-
13
+ export function gemfileParser(fileContent: string, filePath: string): ILocalDependency {
14
+
16
15
  // If the file is not a manifest file, return an empty results
17
- const results: FileDependency = {file: filePath, purls: []};
16
+ const results: ILocalDependency = {file: filePath, purls: []};
18
17
  if(path.basename(filePath) != MANIFEST_FILE)
19
18
  return results;
20
19
 
@@ -32,7 +31,7 @@ export function gemfileParser(fileContent: string, filePath: string): FileDepend
32
31
  compName = compName.replace(/['"]/g, '');
33
32
  const purlString = new PackageURL(PURL_TYPE, undefined, compName, undefined, undefined, undefined).toString();
34
33
  results.purls.push({purl: purlString});
35
- }
34
+ }
36
35
  }
37
36
  }
38
37
  return results;
@@ -40,10 +39,10 @@ export function gemfileParser(fileContent: string, filePath: string): FileDepend
40
39
 
41
40
 
42
41
  const MANIFEST_FILE_1 = 'Gemfile.lock';
43
- export function gemfilelockParser(fileContent: string, filePath: string): FileDependency {
44
-
42
+ export function gemfilelockParser(fileContent: string, filePath: string): ILocalDependency {
43
+
45
44
  // If the file is not a manifest file, return an empty results
46
- const results: FileDependency = {file: filePath, purls: []};
45
+ const results: ILocalDependency = {file: filePath, purls: []};
47
46
  if(path.basename(filePath) != MANIFEST_FILE_1)
48
47
  return results;
49
48
 
@@ -80,13 +79,13 @@ const firstDepLevelRegex = /^ {4}(?! )/;
80
79
  class GemfileLockParser {
81
80
 
82
81
  private statesMap;
83
-
84
- private state;
85
-
86
- private current_options: Record<string, string>;
87
-
88
- private current_gem;
89
-
82
+
83
+ private state;
84
+
85
+ private current_options: Record<string, string>;
86
+
87
+ private current_gem;
88
+
90
89
  private purlList;
91
90
 
92
91
  constructor () {
@@ -127,7 +126,6 @@ class GemfileLockParser {
127
126
  // process the line
128
127
  if (this.state) this.state(line);
129
128
  }
130
- this.refine();
131
129
  return this.purlList;
132
130
  }
133
131
 
@@ -141,21 +139,21 @@ class GemfileLockParser {
141
139
  const key = match.length>=1 ? match[1] : null;
142
140
  const value = match.length>=2 ? match[2] : null;
143
141
  if(key) this.current_options[key] = value;
144
- }
142
+ }
145
143
 
146
144
  private parseDependency(line: string) {}
147
145
  private parsePlatform(line: string){}
148
-
146
+
149
147
 
150
148
  private parseSpec(line: string) {
151
-
149
+
152
150
  if(this.current_gem == GEM) {
153
- if(firstDepLevelRegex.test(line)) {
151
+ if(firstDepLevelRegex.test(line)) {
154
152
  line = line.trimStart();
155
153
  const match = line.match(specRegex);
156
154
 
157
155
  const purl = new PackageURL( PURL_TYPE,
158
- undefined,
156
+ undefined,
159
157
  match.groups.name,
160
158
  match.groups.version,
161
159
  undefined,
@@ -171,11 +169,5 @@ class GemfileLockParser {
171
169
 
172
170
  // Purl from local dependencies are not generated
173
171
  if(this.current_gem == PATH){}
174
-
175
172
  }
176
-
177
- private refine() {}
178
-
179
-
180
-
181
173
  }
@@ -1,4 +1,3 @@
1
- import path from "path";
2
1
  import { URL } from "url";
3
2
 
4
3
  export function isValidUrl(string: string): boolean {