scanoss 0.37.0 → 0.38.0

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 (30) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/build/main/cli/commands/dep.js +2 -2
  3. package/build/main/cli/commands/scan.js +2 -2
  4. package/build/main/sdk/Dependencies/DependencyScanner.d.ts +6 -1
  5. package/build/main/sdk/Dependencies/DependencyScanner.js +9 -4
  6. package/build/main/sdk/Dependencies/LocalDependency/DependencyTypes.d.ts +7 -1
  7. package/build/main/sdk/Dependencies/LocalDependency/LocalDependency.d.ts +4 -1
  8. package/build/main/sdk/Dependencies/LocalDependency/LocalDependency.js +9 -3
  9. package/build/main/sdk/Dependencies/LocalDependency/LocalDependency.spec.js +138 -1
  10. package/build/main/sdk/Dependencies/LocalDependency/parsers/buildGradleParser.d.ts +1 -1
  11. package/build/main/sdk/Dependencies/LocalDependency/parsers/buildGradleParser.js +59 -18
  12. package/build/main/sdk/Dependencies/LocalDependency/parsers/gradle/libsVersionsTomlParser.d.ts +27 -0
  13. package/build/main/sdk/Dependencies/LocalDependency/parsers/gradle/libsVersionsTomlParser.js +207 -0
  14. package/build/main/sdk/Dependencies/LocalDependency/parsers/parser.spec.js +158 -1
  15. package/build/main/tsconfig.tsbuildinfo +1 -1
  16. package/build/module/cli/commands/dep.js +2 -2
  17. package/build/module/cli/commands/scan.js +2 -2
  18. package/build/module/sdk/Dependencies/DependencyScanner.d.ts +6 -1
  19. package/build/module/sdk/Dependencies/DependencyScanner.js +9 -4
  20. package/build/module/sdk/Dependencies/LocalDependency/DependencyTypes.d.ts +7 -1
  21. package/build/module/sdk/Dependencies/LocalDependency/LocalDependency.d.ts +4 -1
  22. package/build/module/sdk/Dependencies/LocalDependency/LocalDependency.js +9 -3
  23. package/build/module/sdk/Dependencies/LocalDependency/LocalDependency.spec.js +102 -1
  24. package/build/module/sdk/Dependencies/LocalDependency/parsers/buildGradleParser.d.ts +1 -1
  25. package/build/module/sdk/Dependencies/LocalDependency/parsers/buildGradleParser.js +58 -17
  26. package/build/module/sdk/Dependencies/LocalDependency/parsers/gradle/libsVersionsTomlParser.d.ts +27 -0
  27. package/build/module/sdk/Dependencies/LocalDependency/parsers/gradle/libsVersionsTomlParser.js +199 -0
  28. package/build/module/sdk/Dependencies/LocalDependency/parsers/parser.spec.js +158 -1
  29. package/build/module/tsconfig.module.tsbuildinfo +1 -1
  30. package/package.json +3 -2
@@ -0,0 +1,27 @@
1
+ import { ILocalDependency } from '../../DependencyTypes';
2
+ export interface ICatalogEntry {
3
+ purl: string;
4
+ version?: string;
5
+ }
6
+ /**
7
+ * Normalizes a TOML alias key to match Gradle accessor notation.
8
+ * Replaces dashes and underscores with dots: "hilt-android" → "hilt.android"
9
+ */
10
+ export declare function normalizeCatalogAlias(alias: string): string;
11
+ /**
12
+ * Builds a map from normalized catalog alias to resolved Maven coordinates.
13
+ * Keys use dot-separated notation matching Kotlin DSL accessors (e.g., "hilt.android").
14
+ */
15
+ export declare function buildCatalogAliasMap(fileContent: string): Map<string, ICatalogEntry>;
16
+ /**
17
+ * Parses a Gradle Version Catalog TOML file (libs.versions.toml) and extracts
18
+ * Maven dependency coordinates as PURLs.
19
+ *
20
+ * Supports:
21
+ * - module + version.ref: `lib = { module = "group:artifact", version.ref = "key" }`
22
+ * - module + inline version: `lib = { module = "group:artifact", version = "1.0" }`
23
+ * - group/name form: `lib = { group = "g", name = "n", version.ref = "key" }`
24
+ * - simple string: `lib = "group:artifact:version"`
25
+ * - no version (BOM-managed): `lib = { module = "group:artifact" }`
26
+ */
27
+ export declare function libsVersionsTomlParser(fileContent: string, filePath: string): Promise<ILocalDependency>;
@@ -0,0 +1,199 @@
1
+ import path from 'path';
2
+ import { PackageURL } from 'packageurl-js';
3
+ /**
4
+ * Known limitations:
5
+ * - Rich versions in [versions] (e.g. { strictly = "[4.0, 5.0[", prefer = "4.12.0" }) are not parsed.
6
+ * Only simple key = "value" entries are supported.
7
+ * - The version catalog is expected at gradle/libs.versions.toml (Gradle default convention).
8
+ * Custom catalog paths configured via settings.gradle.kts versionCatalogs block are not detected.
9
+ * - settings.gradle.kts is not parsed. Plugin declarations and catalog configuration in settings are ignored.
10
+ * - Multi-line library entries are not supported. Each library must be declared on a single line.
11
+ * e.g. `hilt-android = { module = "...", version.ref = "hilt" }` works, but splitting it
12
+ * across multiple lines does not.
13
+ */
14
+ const MANIFEST_FILE = 'libs.versions.toml';
15
+ // --- Exported functions ---
16
+ /**
17
+ * Normalizes a TOML alias key to match Gradle accessor notation.
18
+ * Replaces dashes and underscores with dots: "hilt-android" → "hilt.android"
19
+ */
20
+ export function normalizeCatalogAlias(alias) {
21
+ return alias.replace(/[-_]/g, '.');
22
+ }
23
+ /**
24
+ * Builds a map from normalized catalog alias to resolved Maven coordinates.
25
+ * Keys use dot-separated notation matching Kotlin DSL accessors (e.g., "hilt.android").
26
+ */
27
+ export function buildCatalogAliasMap(fileContent) {
28
+ const map = new Map();
29
+ const versions = parseVersionsSection(fileContent);
30
+ const libraries = parseLibrariesSection(fileContent, versions);
31
+ for (const lib of libraries) {
32
+ if (lib.namespace && lib.name) {
33
+ const aliasKey = normalizeCatalogAlias(lib.alias);
34
+ const purlObj = new PackageURL('maven', lib.namespace, lib.name, undefined, undefined, undefined);
35
+ map.set(aliasKey, { purl: purlObj.toString(), version: lib.version });
36
+ }
37
+ }
38
+ return map;
39
+ }
40
+ /**
41
+ * Parses a Gradle Version Catalog TOML file (libs.versions.toml) and extracts
42
+ * Maven dependency coordinates as PURLs.
43
+ *
44
+ * Supports:
45
+ * - module + version.ref: `lib = { module = "group:artifact", version.ref = "key" }`
46
+ * - module + inline version: `lib = { module = "group:artifact", version = "1.0" }`
47
+ * - group/name form: `lib = { group = "g", name = "n", version.ref = "key" }`
48
+ * - simple string: `lib = "group:artifact:version"`
49
+ * - no version (BOM-managed): `lib = { module = "group:artifact" }`
50
+ */
51
+ export async function libsVersionsTomlParser(fileContent, filePath) {
52
+ const results = { file: filePath, purls: [] };
53
+ if (path.basename(filePath) !== MANIFEST_FILE)
54
+ return results;
55
+ const versions = parseVersionsSection(fileContent);
56
+ const libraries = parseLibrariesSection(fileContent, versions);
57
+ for (const lib of libraries) {
58
+ if (lib.namespace && lib.name) {
59
+ const purlObj = new PackageURL('maven', lib.namespace, lib.name, undefined, undefined, undefined);
60
+ results.purls.push({ purl: purlObj.toString(), ...(lib.version && { requirement: lib.version }) });
61
+ }
62
+ }
63
+ return results;
64
+ }
65
+ // --- Private helpers ---
66
+ /**
67
+ * Extracts the content of a TOML section by header name.
68
+ * Returns the text between `[sectionName]` and the next `[` header (or end of file).
69
+ */
70
+ function extractSection(fileContent, sectionName) {
71
+ const regex = new RegExp(`^\\[${sectionName}\\]\\s*$`, 'm');
72
+ const match = regex.exec(fileContent);
73
+ if (!match)
74
+ return null;
75
+ const start = match.index + match[0].length;
76
+ const nextSection = fileContent.indexOf('\n[', start);
77
+ return nextSection === -1
78
+ ? fileContent.substring(start)
79
+ : fileContent.substring(start, nextSection);
80
+ }
81
+ /**
82
+ * Parses the [versions] section into a map of key -> version string.
83
+ *
84
+ * Example input:
85
+ * [versions]
86
+ * hilt = "2.51.1"
87
+ * kotlin = "2.0.0"
88
+ *
89
+ * Returns: Map { "hilt" → "2.51.1", "kotlin" → "2.0.0" }
90
+ */
91
+ function parseVersionsSection(fileContent) {
92
+ const versions = new Map();
93
+ const section = extractSection(fileContent, 'versions');
94
+ if (!section)
95
+ return versions;
96
+ for (const line of section.split(/\r?\n/)) {
97
+ const trimmed = line.trim();
98
+ if (!trimmed || trimmed.startsWith('#'))
99
+ continue;
100
+ // Match: key = "value" or key = 'value'
101
+ const match = trimmed.match(/^([\w-]+)\s*=\s*["']([^"']+)["']/);
102
+ if (match) {
103
+ versions.set(match[1], match[2]);
104
+ }
105
+ }
106
+ return versions;
107
+ }
108
+ /**
109
+ * Parses the [libraries] section and resolves version references.
110
+ *
111
+ * Example input:
112
+ * [libraries]
113
+ * hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
114
+ * simple = "com.example:simple:1.0.0"
115
+ *
116
+ * Returns: [
117
+ * { alias: "hilt-android", namespace: "com.google.dagger", name: "hilt-android", version: "2.51.1" },
118
+ * { alias: "simple", namespace: "com.example", name: "simple", version: "1.0.0" }
119
+ * ]
120
+ */
121
+ function parseLibrariesSection(fileContent, versions) {
122
+ const libraries = [];
123
+ const section = extractSection(fileContent, 'libraries');
124
+ if (!section)
125
+ return libraries;
126
+ for (const line of section.split(/\r?\n/)) {
127
+ const trimmed = line.trim();
128
+ if (!trimmed || trimmed.startsWith('#'))
129
+ continue;
130
+ // Match the key = value pattern
131
+ const kvMatch = trimmed.match(/^([\w-]+)\s*=\s*(.*)/);
132
+ if (!kvMatch)
133
+ continue;
134
+ const value = kvMatch[2].trim();
135
+ const entry = parseLibraryValue(value, versions);
136
+ if (entry)
137
+ libraries.push({ alias: kvMatch[1], ...entry });
138
+ }
139
+ return libraries;
140
+ }
141
+ /**
142
+ * Parses a single library value from the TOML file.
143
+ */
144
+ function parseLibraryValue(value, versions) {
145
+ // Simple string notation: "group:artifact:version"
146
+ const stringMatch = value.match(/^["']([^"']+)["']/);
147
+ if (stringMatch) {
148
+ const strContent = stringMatch[1];
149
+ const parts = strContent.split(':');
150
+ if (parts.length >= 2) {
151
+ return {
152
+ namespace: parts[0],
153
+ name: parts[1],
154
+ ...(parts[2] && { version: parts[2] }),
155
+ };
156
+ }
157
+ return null;
158
+ }
159
+ // Inline table notation: { ... }
160
+ if (value.startsWith('{')) {
161
+ let namespace;
162
+ let name;
163
+ let version;
164
+ // Check for module = "group:artifact"
165
+ const moduleMatch = value.match(/module\s*=\s*["']([^"']+)["']/);
166
+ if (moduleMatch) {
167
+ const parts = moduleMatch[1].split(':');
168
+ if (parts.length >= 2) {
169
+ namespace = parts[0];
170
+ name = parts[1];
171
+ }
172
+ }
173
+ else {
174
+ // Check for group = "...", name = "..."
175
+ const groupMatch = value.match(/group\s*=\s*["']([^"']+)["']/);
176
+ const nameMatch = value.match(/name\s*=\s*["']([^"']+)["']/);
177
+ if (groupMatch)
178
+ namespace = groupMatch[1];
179
+ if (nameMatch)
180
+ name = nameMatch[1];
181
+ }
182
+ // Resolve version: version.ref = "key" or version = "value"
183
+ const versionRefMatch = value.match(/version\.ref\s*=\s*["']([^"']+)["']/);
184
+ if (versionRefMatch) {
185
+ version = versions.get(versionRefMatch[1]);
186
+ }
187
+ else {
188
+ const versionMatch = value.match(/(?<![.\w])version\s*=\s*["']([^"']+)["']/);
189
+ if (versionMatch) {
190
+ version = versionMatch[1];
191
+ }
192
+ }
193
+ if (namespace && name) {
194
+ return { namespace, name, ...(version && { version }) };
195
+ }
196
+ }
197
+ return null;
198
+ }
199
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlic1ZlcnNpb25zVG9tbFBhcnNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9zZGsvRGVwZW5kZW5jaWVzL0xvY2FsRGVwZW5kZW5jeS9wYXJzZXJzL2dyYWRsZS9saWJzVmVyc2lvbnNUb21sUGFyc2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUN4QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDOzs7Ozs7Ozs7O0dBVUc7QUFFSCxNQUFNLGFBQWEsR0FBRyxvQkFBb0IsQ0FBQztBQWlCM0MsNkJBQTZCO0FBRTdCOzs7R0FHRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxLQUFhO0lBQ2pELE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDckMsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxXQUFtQjtJQUN0RCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsRUFBeUIsQ0FBQztJQUM3QyxNQUFNLFFBQVEsR0FBRyxvQkFBb0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNuRCxNQUFNLFNBQVMsR0FBRyxxQkFBcUIsQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFFL0QsS0FBSyxNQUFNLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUM1QixJQUFJLEdBQUcsQ0FBQyxTQUFTLElBQUksR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQzlCLE1BQU0sUUFBUSxHQUFHLHFCQUFxQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNsRCxNQUFNLE9BQU8sR0FBRyxJQUFJLFVBQVUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVB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