scanoss 0.37.0 → 0.38.1

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 (32) hide show
  1. package/CHANGELOG.md +11 -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/Decompress/Decompressor/DecompressZips.js +17 -2
  5. package/build/main/sdk/Dependencies/DependencyScanner.d.ts +6 -1
  6. package/build/main/sdk/Dependencies/DependencyScanner.js +9 -4
  7. package/build/main/sdk/Dependencies/LocalDependency/DependencyTypes.d.ts +7 -1
  8. package/build/main/sdk/Dependencies/LocalDependency/LocalDependency.d.ts +4 -1
  9. package/build/main/sdk/Dependencies/LocalDependency/LocalDependency.js +9 -3
  10. package/build/main/sdk/Dependencies/LocalDependency/LocalDependency.spec.js +138 -1
  11. package/build/main/sdk/Dependencies/LocalDependency/parsers/buildGradleParser.d.ts +1 -1
  12. package/build/main/sdk/Dependencies/LocalDependency/parsers/buildGradleParser.js +59 -18
  13. package/build/main/sdk/Dependencies/LocalDependency/parsers/gradle/libsVersionsTomlParser.d.ts +27 -0
  14. package/build/main/sdk/Dependencies/LocalDependency/parsers/gradle/libsVersionsTomlParser.js +207 -0
  15. package/build/main/sdk/Dependencies/LocalDependency/parsers/parser.spec.js +158 -1
  16. package/build/main/tsconfig.tsbuildinfo +1 -1
  17. package/build/module/cli/commands/dep.js +2 -2
  18. package/build/module/cli/commands/scan.js +2 -2
  19. package/build/module/sdk/Decompress/Decompressor/DecompressZips.js +17 -2
  20. package/build/module/sdk/Dependencies/DependencyScanner.d.ts +6 -1
  21. package/build/module/sdk/Dependencies/DependencyScanner.js +9 -4
  22. package/build/module/sdk/Dependencies/LocalDependency/DependencyTypes.d.ts +7 -1
  23. package/build/module/sdk/Dependencies/LocalDependency/LocalDependency.d.ts +4 -1
  24. package/build/module/sdk/Dependencies/LocalDependency/LocalDependency.js +9 -3
  25. package/build/module/sdk/Dependencies/LocalDependency/LocalDependency.spec.js +102 -1
  26. package/build/module/sdk/Dependencies/LocalDependency/parsers/buildGradleParser.d.ts +1 -1
  27. package/build/module/sdk/Dependencies/LocalDependency/parsers/buildGradleParser.js +58 -17
  28. package/build/module/sdk/Dependencies/LocalDependency/parsers/gradle/libsVersionsTomlParser.d.ts +27 -0
  29. package/build/module/sdk/Dependencies/LocalDependency/parsers/gradle/libsVersionsTomlParser.js +199 -0
  30. package/build/module/sdk/Dependencies/LocalDependency/parsers/parser.spec.js +158 -1
  31. package/build/module/tsconfig.module.tsbuildinfo +1 -1
  32. package/package.json +3 -2
@@ -1,19 +1,49 @@
1
1
  import path from 'path';
2
+ import fs from 'fs';
2
3
  import { PackageURL } from 'packageurl-js';
3
- const MANIFEST_FILE = 'build.gradle';
4
+ import { buildCatalogAliasMap } from './gradle/libsVersionsTomlParser';
5
+ const MANIFEST_FILES = ['build.gradle', 'build.gradle.kts'];
6
+ // Per-project cache of parsed version catalog (libs.versions.toml) entries.
7
+ // Outer key: project root directory path where gradle/libs.versions.toml was found
8
+ // Inner map: normalized alias (e.g. "androidx.activity.compose") → resolved Maven coordinates
9
+ // Example: { "/home/user/my-project" → { "hilt.android" → { purl: "pkg:maven/com.google.dagger/hilt-android", version: "2.59" } } }
10
+ const catalogCache = new Map();
4
11
  const depBlockRex = /dependencies\s*{\s*(?<dependencies>(.|\n)*?)}/gm;
5
- var GRADLE_STATES;
6
- (function (GRADLE_STATES) {
7
- GRADLE_STATES[GRADLE_STATES["WALKING"] = 0] = "WALKING";
8
- GRADLE_STATES[GRADLE_STATES["SINGLELINE_DEPENDENCY"] = 1] = "SINGLELINE_DEPENDENCY";
9
- GRADLE_STATES[GRADLE_STATES["MULTILINE_DEPENDENCY"] = 2] = "MULTILINE_DEPENDENCY";
10
- })(GRADLE_STATES || (GRADLE_STATES = {}));
11
- export async function buildGradleParser(fileContent, filePath) {
12
+ function resolveCatalogAlias(line, catalogMap) {
13
+ const match = line.match(/\blibs\.([a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*)\b/);
14
+ if (match)
15
+ return catalogMap.get(match[1]);
16
+ }
17
+ function findCatalogMap(gradleFilePath, basePath) {
18
+ let dir = path.dirname(path.resolve(gradleFilePath));
19
+ const root = path.parse(dir).root;
20
+ // Stop at basePath (scan root) to avoid searching outside the project scope.
21
+ // Falls back to filesystem root when basePath is not provided.
22
+ const boundary = basePath ? path.resolve(basePath) : root;
23
+ while (true) {
24
+ if (catalogCache.has(dir))
25
+ return catalogCache.get(dir);
26
+ const tomlPath = path.join(dir, 'gradle', 'libs.versions.toml');
27
+ if (fs.existsSync(tomlPath)) {
28
+ const content = fs.readFileSync(tomlPath, 'utf8');
29
+ const map = buildCatalogAliasMap(content);
30
+ catalogCache.set(dir, map);
31
+ return map;
32
+ }
33
+ if (dir === boundary || dir === root)
34
+ break;
35
+ dir = path.dirname(dir);
36
+ }
37
+ return new Map();
38
+ }
39
+ export async function buildGradleParser(fileContent, filePath, basePath) {
12
40
  // If the file is not a manifest file, return an empty results
13
41
  const results = { file: filePath, purls: [] };
14
- if (path.basename(filePath) != MANIFEST_FILE)
42
+ if (!MANIFEST_FILES.includes(path.basename(filePath)))
15
43
  return results;
44
+ const catalogMap = findCatalogMap(filePath, basePath);
16
45
  //For each dependency block, generate purls
46
+ depBlockRex.lastIndex = 0;
17
47
  let gradle;
18
48
  while ((gradle = depBlockRex.exec(fileContent)) !== null) {
19
49
  let depBlock = gradle?.groups?.dependencies;
@@ -27,8 +57,8 @@ export async function buildGradleParser(fileContent, filePath) {
27
57
  if (line == '')
28
58
  continue;
29
59
  current_config_name = getConfigNameFromLine(line);
30
- //Multiline dependency
31
- if (current_config_name && line.includes("(")) {
60
+ //Multiline dependency (only if line has '(' but not ')' on the same line)
61
+ if (current_config_name && line.includes("(") && !line.includes(")")) {
32
62
  while (i < lines.length && !lines[i].includes(")")) {
33
63
  const componentData = createPurlNameFromLine(lines[i]);
34
64
  if (componentData != null) {
@@ -38,6 +68,12 @@ export async function buildGradleParser(fileContent, filePath) {
38
68
  scope: current_config_name
39
69
  });
40
70
  }
71
+ else {
72
+ const entry = resolveCatalogAlias(lines[i], catalogMap);
73
+ if (entry) {
74
+ results.purls.push({ purl: entry.purl, requirement: entry.version, scope: current_config_name });
75
+ }
76
+ }
41
77
  i++;
42
78
  }
43
79
  current_config_name = '';
@@ -45,6 +81,11 @@ export async function buildGradleParser(fileContent, filePath) {
45
81
  else { //Single line dependency
46
82
  const componentData = createPurlNameFromLine(line);
47
83
  if (componentData == null) {
84
+ // Try resolving via catalog alias
85
+ const entry = resolveCatalogAlias(line, catalogMap);
86
+ if (entry) {
87
+ results.purls.push({ purl: entry.purl, requirement: entry.version, scope: current_config_name });
88
+ }
48
89
  current_config_name = '';
49
90
  continue;
50
91
  }
@@ -56,9 +97,9 @@ export async function buildGradleParser(fileContent, filePath) {
56
97
  }
57
98
  function getConfigNameFromLine(line) {
58
99
  let configName = "";
59
- const dep = line.split(/\s/);
100
+ const dep = line.split(/[\s(]/);
60
101
  if (dep.length)
61
- configName = dep[0].replace("(", "").trim();
102
+ configName = dep[0].trim();
62
103
  return configName;
63
104
  }
64
105
  function createPurlNameFromLine(line) {
@@ -73,9 +114,9 @@ function createPurlNameFromLine(line) {
73
114
  version = dep.groups.version;
74
115
  }
75
116
  else if (line.includes("group") && line.includes("name") && line.includes("version")) {
76
- version = line.match(/version:\s+['"](?<version>[\w\.\-\d]+)['"]/).groups.version;
77
- name = line.match(/name:\s+['"](?<name>[\w\.\-\d]+)['"]/).groups?.name;
78
- namespace = line.match(/group:\s+['"](?<group>[\w\.\-\d]+)['"]/).groups?.group;
117
+ version = line.match(/version\s*[:=]\s*['"](?<version>[\w\.\-\d]+)['"]/)?.groups?.version;
118
+ name = line.match(/name\s*[:=]\s*['"](?<name>[\w\.\-\d]+)['"]/)?.groups?.name;
119
+ namespace = line.match(/group\s*[:=]\s*['"](?<group>[\w\.\-\d]+)['"]/)?.groups?.group;
79
120
  }
80
121
  let purlName = "";
81
122
  if (name && namespace) {
@@ -84,4 +125,4 @@ function createPurlNameFromLine(line) {
84
125
  }
85
126
  return null;
86
127
  }
87
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRHcmFkbGVQYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvc2RrL0RlcGVuZGVuY2llcy9Mb2NhbERlcGVuZGVuY3kvcGFyc2Vycy9idWlsZEdyYWRsZVBhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFDeEIsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUczQyxNQUFNLGFBQWEsR0FBRyxjQUFjLENBQUM7QUFDckMsTUFBTSxXQUFXLEdBQUcsaURBQWlELENBQUM7QUFFdEUsSUFBSyxhQUlKO0FBSkQsV0FBSyxhQUFhO0lBQ2hCLHVEQUFPLENBQUE7SUFDUCxtRkFBcUIsQ0FBQTtJQUNyQixpRkFBb0IsQ0FBQTtBQUN0QixDQUFDLEVBSkksYUFBYSxLQUFiLGFBQWEsUUFJakI7QUFDRCxNQUFNLENBQUMsS0FBSyxVQUFVLGlCQUFpQixDQUFDLFdBQW1CLEVBQUUsUUFBZ0I7SUFHM0UsOERBQThEO0lBQzlELE1BQU0sT0FBTyxHQUFxQixFQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBQyxDQUFDO0lBQzlELElBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxhQUFhO1FBQ3pDLE9BQU8sT0FBTyxDQUFDO0lBRWpCLDJDQUEyQztJQUMzQyxJQUFJLE1BQU0sQ0FBQztJQUNYLE9BQU8sQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ3pELElBQUksUUFBUSxHQUFHLE1BQU0sRUFBRSxNQUFNLEVBQUUsWUFBWSxDQUFDO1FBRzVDLElBQUksbUJBQW1CLEdBQUcsRUFBRSxDQUFDLENBQUcsb0NBQW9DO1FBQ3BFLElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsT0FB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
128
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRHcmFkbGVQYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvc2RrL0RlcGVuZGVuY2llcy9Mb2NhbERlcGVuZGVuY3kvcGFyc2Vycy9idWlsZEdyYWRsZVBhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFDeEIsT0FBTyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3BCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFpQixvQkFBb0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBR3RGLE1BQU0sY0FBYyxHQUFHLENBQUMsY0FBYyxFQUFFLGtCQUFrQixDQUFDLENBQUM7QUFDNUQsNEVBQTRFO0FBQzVFLG1GQUFtRjtBQUNuRiw4RkFBOEY7QUFDOUYsb0lBQW9JO0FBQ3BJLE1BQU0sWUFBWSxHQUFHLElBQUksR0FBRyxFQUFzQyxDQUFDO0FBQ25FLE1BQU0sV0FBVyxHQUFHLGlEQUFpRCxDQUFDO0FBR3RFLFNBQVMsbUJBQW1CLENBQUMsSUFBWSxFQUFFLFVBQXNDO0lBQy9FLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztJQUN4RSxJQUFJLEtBQUs7UUFBRSxPQUFPLFVBQVUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0MsQ0FBQztBQUVELFNBQVMsY0FBYyxDQUFDLGNBQXNCLEVBQUUsUUFBaUI7SUFDL0QsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7SUFDckQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDbEMsNkVBQTZFO0lBQzdFLCtEQUEr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
@@ -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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