@domainlang/language 0.1.20

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 (212) hide show
  1. package/README.md +163 -0
  2. package/out/ast-augmentation.d.ts +6 -0
  3. package/out/ast-augmentation.js +2 -0
  4. package/out/ast-augmentation.js.map +1 -0
  5. package/out/domain-lang-module.d.ts +57 -0
  6. package/out/domain-lang-module.js +67 -0
  7. package/out/domain-lang-module.js.map +1 -0
  8. package/out/generated/ast.d.ts +759 -0
  9. package/out/generated/ast.js +556 -0
  10. package/out/generated/ast.js.map +1 -0
  11. package/out/generated/grammar.d.ts +6 -0
  12. package/out/generated/grammar.js +2407 -0
  13. package/out/generated/grammar.js.map +1 -0
  14. package/out/generated/module.d.ts +13 -0
  15. package/out/generated/module.js +21 -0
  16. package/out/generated/module.js.map +1 -0
  17. package/out/index.d.ts +16 -0
  18. package/out/index.js +22 -0
  19. package/out/index.js.map +1 -0
  20. package/out/lsp/domain-lang-code-actions.d.ts +55 -0
  21. package/out/lsp/domain-lang-code-actions.js +143 -0
  22. package/out/lsp/domain-lang-code-actions.js.map +1 -0
  23. package/out/lsp/domain-lang-completion.d.ts +37 -0
  24. package/out/lsp/domain-lang-completion.js +452 -0
  25. package/out/lsp/domain-lang-completion.js.map +1 -0
  26. package/out/lsp/domain-lang-formatter.d.ts +15 -0
  27. package/out/lsp/domain-lang-formatter.js +43 -0
  28. package/out/lsp/domain-lang-formatter.js.map +1 -0
  29. package/out/lsp/domain-lang-naming.d.ts +34 -0
  30. package/out/lsp/domain-lang-naming.js +49 -0
  31. package/out/lsp/domain-lang-naming.js.map +1 -0
  32. package/out/lsp/domain-lang-scope.d.ts +59 -0
  33. package/out/lsp/domain-lang-scope.js +102 -0
  34. package/out/lsp/domain-lang-scope.js.map +1 -0
  35. package/out/lsp/domain-lang-workspace-manager.d.ts +21 -0
  36. package/out/lsp/domain-lang-workspace-manager.js +93 -0
  37. package/out/lsp/domain-lang-workspace-manager.js.map +1 -0
  38. package/out/lsp/hover/ddd-pattern-explanations.d.ts +50 -0
  39. package/out/lsp/hover/ddd-pattern-explanations.js +196 -0
  40. package/out/lsp/hover/ddd-pattern-explanations.js.map +1 -0
  41. package/out/lsp/hover/domain-lang-hover.d.ts +19 -0
  42. package/out/lsp/hover/domain-lang-hover.js +302 -0
  43. package/out/lsp/hover/domain-lang-hover.js.map +1 -0
  44. package/out/lsp/hover/domain-lang-keywords.d.ts +13 -0
  45. package/out/lsp/hover/domain-lang-keywords.js +47 -0
  46. package/out/lsp/hover/domain-lang-keywords.js.map +1 -0
  47. package/out/lsp/manifest-diagnostics.d.ts +82 -0
  48. package/out/lsp/manifest-diagnostics.js +230 -0
  49. package/out/lsp/manifest-diagnostics.js.map +1 -0
  50. package/out/main-browser.d.ts +1 -0
  51. package/out/main-browser.js +11 -0
  52. package/out/main-browser.js.map +1 -0
  53. package/out/main.d.ts +1 -0
  54. package/out/main.js +74 -0
  55. package/out/main.js.map +1 -0
  56. package/out/sdk/ast-augmentation.d.ts +136 -0
  57. package/out/sdk/ast-augmentation.js +62 -0
  58. package/out/sdk/ast-augmentation.js.map +1 -0
  59. package/out/sdk/index.d.ts +94 -0
  60. package/out/sdk/index.js +97 -0
  61. package/out/sdk/index.js.map +1 -0
  62. package/out/sdk/indexes.d.ts +16 -0
  63. package/out/sdk/indexes.js +97 -0
  64. package/out/sdk/indexes.js.map +1 -0
  65. package/out/sdk/loader-node.d.ts +51 -0
  66. package/out/sdk/loader-node.js +119 -0
  67. package/out/sdk/loader-node.js.map +1 -0
  68. package/out/sdk/loader.d.ts +49 -0
  69. package/out/sdk/loader.js +85 -0
  70. package/out/sdk/loader.js.map +1 -0
  71. package/out/sdk/patterns.d.ts +93 -0
  72. package/out/sdk/patterns.js +123 -0
  73. package/out/sdk/patterns.js.map +1 -0
  74. package/out/sdk/query.d.ts +90 -0
  75. package/out/sdk/query.js +679 -0
  76. package/out/sdk/query.js.map +1 -0
  77. package/out/sdk/resolution.d.ts +52 -0
  78. package/out/sdk/resolution.js +68 -0
  79. package/out/sdk/resolution.js.map +1 -0
  80. package/out/sdk/types.d.ts +280 -0
  81. package/out/sdk/types.js +8 -0
  82. package/out/sdk/types.js.map +1 -0
  83. package/out/services/dependency-analyzer.d.ts +58 -0
  84. package/out/services/dependency-analyzer.js +254 -0
  85. package/out/services/dependency-analyzer.js.map +1 -0
  86. package/out/services/dependency-resolver.d.ts +146 -0
  87. package/out/services/dependency-resolver.js +452 -0
  88. package/out/services/dependency-resolver.js.map +1 -0
  89. package/out/services/git-url-resolver.browser.d.ts +10 -0
  90. package/out/services/git-url-resolver.browser.js +19 -0
  91. package/out/services/git-url-resolver.browser.js.map +1 -0
  92. package/out/services/git-url-resolver.d.ts +158 -0
  93. package/out/services/git-url-resolver.js +416 -0
  94. package/out/services/git-url-resolver.js.map +1 -0
  95. package/out/services/governance-validator.d.ts +44 -0
  96. package/out/services/governance-validator.js +153 -0
  97. package/out/services/governance-validator.js.map +1 -0
  98. package/out/services/import-resolver.d.ts +77 -0
  99. package/out/services/import-resolver.js +240 -0
  100. package/out/services/import-resolver.js.map +1 -0
  101. package/out/services/performance-optimizer.d.ts +60 -0
  102. package/out/services/performance-optimizer.js +140 -0
  103. package/out/services/performance-optimizer.js.map +1 -0
  104. package/out/services/relationship-inference.d.ts +11 -0
  105. package/out/services/relationship-inference.js +98 -0
  106. package/out/services/relationship-inference.js.map +1 -0
  107. package/out/services/semver.d.ts +98 -0
  108. package/out/services/semver.js +195 -0
  109. package/out/services/semver.js.map +1 -0
  110. package/out/services/types.d.ts +340 -0
  111. package/out/services/types.js +46 -0
  112. package/out/services/types.js.map +1 -0
  113. package/out/services/workspace-manager.d.ts +123 -0
  114. package/out/services/workspace-manager.js +489 -0
  115. package/out/services/workspace-manager.js.map +1 -0
  116. package/out/syntaxes/domain-lang.monarch.d.ts +76 -0
  117. package/out/syntaxes/domain-lang.monarch.js +29 -0
  118. package/out/syntaxes/domain-lang.monarch.js.map +1 -0
  119. package/out/utils/import-utils.d.ts +49 -0
  120. package/out/utils/import-utils.js +128 -0
  121. package/out/utils/import-utils.js.map +1 -0
  122. package/out/validation/bounded-context.d.ts +11 -0
  123. package/out/validation/bounded-context.js +79 -0
  124. package/out/validation/bounded-context.js.map +1 -0
  125. package/out/validation/classification.d.ts +3 -0
  126. package/out/validation/classification.js +3 -0
  127. package/out/validation/classification.js.map +1 -0
  128. package/out/validation/constants.d.ts +180 -0
  129. package/out/validation/constants.js +235 -0
  130. package/out/validation/constants.js.map +1 -0
  131. package/out/validation/domain-lang-validator.d.ts +2 -0
  132. package/out/validation/domain-lang-validator.js +27 -0
  133. package/out/validation/domain-lang-validator.js.map +1 -0
  134. package/out/validation/domain.d.ts +11 -0
  135. package/out/validation/domain.js +63 -0
  136. package/out/validation/domain.js.map +1 -0
  137. package/out/validation/import.d.ts +68 -0
  138. package/out/validation/import.js +237 -0
  139. package/out/validation/import.js.map +1 -0
  140. package/out/validation/manifest.d.ts +144 -0
  141. package/out/validation/manifest.js +327 -0
  142. package/out/validation/manifest.js.map +1 -0
  143. package/out/validation/maps.d.ts +21 -0
  144. package/out/validation/maps.js +60 -0
  145. package/out/validation/maps.js.map +1 -0
  146. package/out/validation/metadata.d.ts +7 -0
  147. package/out/validation/metadata.js +16 -0
  148. package/out/validation/metadata.js.map +1 -0
  149. package/out/validation/model.d.ts +12 -0
  150. package/out/validation/model.js +29 -0
  151. package/out/validation/model.js.map +1 -0
  152. package/out/validation/relationships.d.ts +12 -0
  153. package/out/validation/relationships.js +94 -0
  154. package/out/validation/relationships.js.map +1 -0
  155. package/out/validation/shared.d.ts +6 -0
  156. package/out/validation/shared.js +12 -0
  157. package/out/validation/shared.js.map +1 -0
  158. package/package.json +110 -0
  159. package/src/ast-augmentation.ts +5 -0
  160. package/src/domain-lang-module.ts +112 -0
  161. package/src/domain-lang.langium +351 -0
  162. package/src/generated/ast.ts +986 -0
  163. package/src/generated/grammar.ts +2409 -0
  164. package/src/generated/module.ts +25 -0
  165. package/src/index.ts +24 -0
  166. package/src/lsp/domain-lang-code-actions.ts +189 -0
  167. package/src/lsp/domain-lang-completion.ts +514 -0
  168. package/src/lsp/domain-lang-formatter.ts +51 -0
  169. package/src/lsp/domain-lang-naming.ts +56 -0
  170. package/src/lsp/domain-lang-scope.ts +137 -0
  171. package/src/lsp/domain-lang-workspace-manager.ts +104 -0
  172. package/src/lsp/hover/ddd-pattern-explanations.ts +237 -0
  173. package/src/lsp/hover/domain-lang-hover.ts +338 -0
  174. package/src/lsp/hover/domain-lang-keywords.ts +50 -0
  175. package/src/lsp/manifest-diagnostics.ts +290 -0
  176. package/src/main-browser.ts +15 -0
  177. package/src/main.ts +85 -0
  178. package/src/sdk/README.md +297 -0
  179. package/src/sdk/ast-augmentation.ts +157 -0
  180. package/src/sdk/index.ts +126 -0
  181. package/src/sdk/indexes.ts +155 -0
  182. package/src/sdk/loader-node.ts +146 -0
  183. package/src/sdk/loader.ts +99 -0
  184. package/src/sdk/patterns.ts +147 -0
  185. package/src/sdk/query.ts +802 -0
  186. package/src/sdk/resolution.ts +78 -0
  187. package/src/sdk/types.ts +323 -0
  188. package/src/services/dependency-analyzer.ts +321 -0
  189. package/src/services/dependency-resolver.ts +551 -0
  190. package/src/services/git-url-resolver.browser.ts +26 -0
  191. package/src/services/git-url-resolver.ts +517 -0
  192. package/src/services/governance-validator.ts +177 -0
  193. package/src/services/import-resolver.ts +292 -0
  194. package/src/services/performance-optimizer.ts +170 -0
  195. package/src/services/relationship-inference.ts +121 -0
  196. package/src/services/semver.ts +213 -0
  197. package/src/services/types.ts +415 -0
  198. package/src/services/workspace-manager.ts +607 -0
  199. package/src/syntaxes/domain-lang.monarch.ts +29 -0
  200. package/src/utils/import-utils.ts +152 -0
  201. package/src/validation/bounded-context.ts +99 -0
  202. package/src/validation/classification.ts +5 -0
  203. package/src/validation/constants.ts +304 -0
  204. package/src/validation/domain-lang-validator.ts +33 -0
  205. package/src/validation/domain.ts +77 -0
  206. package/src/validation/import.ts +295 -0
  207. package/src/validation/manifest.ts +439 -0
  208. package/src/validation/maps.ts +76 -0
  209. package/src/validation/metadata.ts +18 -0
  210. package/src/validation/model.ts +37 -0
  211. package/src/validation/relationships.ts +154 -0
  212. package/src/validation/shared.ts +14 -0
@@ -0,0 +1,416 @@
1
+ /**
2
+ * Git Repository Resolver Service
3
+ *
4
+ * Resolves git-based package imports to local cached repositories.
5
+ * Supports simplified GitHub syntax (owner/repo@version) and full URLs.
6
+ *
7
+ * Design: Repository-level imports (not individual files)
8
+ * - Imports load entire package
9
+ * - Package entry point defined in model.yaml
10
+ * - Version pinning at repository level
11
+ */
12
+ import { URI } from 'langium';
13
+ import path from 'node:path';
14
+ import fs from 'node:fs/promises';
15
+ import { exec } from 'node:child_process';
16
+ import { promisify } from 'node:util';
17
+ import YAML from 'yaml';
18
+ const execAsync = promisify(exec);
19
+ /**
20
+ * Parses import URLs into structured git import information.
21
+ *
22
+ * Supported formats:
23
+ * - owner/repo@version (GitHub assumed)
24
+ * - owner/repo (GitHub, defaults to main)
25
+ * - https://github.com/owner/repo@version
26
+ * - https://gitlab.com/owner/repo@version
27
+ * - https://git.example.com/owner/repo@version
28
+ */
29
+ export class GitUrlParser {
30
+ /**
31
+ * Determines if an import string is a git repository import.
32
+ */
33
+ static isGitUrl(importStr) {
34
+ // GitHub shorthand: owner/repo or owner/repo@version
35
+ if (/^[a-zA-Z0-9-]+\/[a-zA-Z0-9-_.]+(@[^/]+)?$/.test(importStr)) {
36
+ return true;
37
+ }
38
+ // Full URLs
39
+ return (importStr.startsWith('https://github.com/') ||
40
+ importStr.startsWith('https://gitlab.com/') ||
41
+ importStr.startsWith('https://bitbucket.org/') ||
42
+ importStr.startsWith('https://git.') ||
43
+ importStr.startsWith('git://'));
44
+ }
45
+ /**
46
+ * Parses a git import URL into structured components.
47
+ *
48
+ * @param importStr - The import URL string
49
+ * @returns Parsed git import information
50
+ * @throws Error if URL format is invalid
51
+ */
52
+ static parse(importStr) {
53
+ // Handle GitHub shorthand (owner/repo or owner/repo@version)
54
+ if (this.isGitHubShorthand(importStr)) {
55
+ return this.parseGitHubShorthand(importStr);
56
+ }
57
+ // Handle full URLs
58
+ if (importStr.startsWith('https://') || importStr.startsWith('git://')) {
59
+ return this.parseFullUrl(importStr);
60
+ }
61
+ throw new Error(`Invalid git import URL: '${importStr}'.\n` +
62
+ `Hint: Use 'owner/repo' or 'owner/repo@version' format (e.g., 'domainlang/core@v1.0.0').`);
63
+ }
64
+ /**
65
+ * Checks if string is GitHub shorthand format.
66
+ */
67
+ static isGitHubShorthand(importStr) {
68
+ return /^[a-zA-Z0-9-]+\/[a-zA-Z0-9-_.]+(@[^/]+)?$/.test(importStr);
69
+ }
70
+ /**
71
+ * Parses GitHub shorthand (owner/repo or owner/repo@version).
72
+ */
73
+ static parseGitHubShorthand(importStr) {
74
+ const match = importStr.match(/^([a-zA-Z0-9-]+)\/([a-zA-Z0-9-_.]+)(?:@([^/]+))?$/);
75
+ if (!match) {
76
+ throw new Error(`Invalid GitHub shorthand format: '${importStr}'.\n` +
77
+ `Hint: Use 'owner/repo' or 'owner/repo@version' format.`);
78
+ }
79
+ const [, owner, repo, version] = match;
80
+ const resolvedVersion = version || 'main';
81
+ return {
82
+ original: importStr,
83
+ platform: 'github',
84
+ owner,
85
+ repo,
86
+ version: resolvedVersion,
87
+ repoUrl: `https://github.com/${owner}/${repo}`,
88
+ entryPoint: 'index.dlang', // Default, will be resolved from model.yaml
89
+ };
90
+ }
91
+ /**
92
+ * Parses full git URLs (https://...).
93
+ *
94
+ * Supported:
95
+ * - https://github.com/owner/repo@version
96
+ * - https://gitlab.com/owner/repo@version
97
+ * - https://git.example.com/owner/repo@version
98
+ */
99
+ static parseFullUrl(importStr) {
100
+ // GitHub
101
+ const ghMatch = importStr.match(/^https:\/\/github\.com\/([^/]+)\/([^/@]+)(?:@([^/]+))?$/);
102
+ if (ghMatch) {
103
+ const [, owner, repo, version] = ghMatch;
104
+ return {
105
+ original: importStr,
106
+ platform: 'github',
107
+ owner,
108
+ repo,
109
+ version: version || 'main',
110
+ repoUrl: `https://github.com/${owner}/${repo}`,
111
+ entryPoint: 'index.dlang',
112
+ };
113
+ }
114
+ // GitLab
115
+ const glMatch = importStr.match(/^https:\/\/gitlab\.com\/([^/]+)\/([^/@]+)(?:@([^/]+))?$/);
116
+ if (glMatch) {
117
+ const [, owner, repo, version] = glMatch;
118
+ return {
119
+ original: importStr,
120
+ platform: 'gitlab',
121
+ owner,
122
+ repo,
123
+ version: version || 'main',
124
+ repoUrl: `https://gitlab.com/${owner}/${repo}`,
125
+ entryPoint: 'index.dlang',
126
+ };
127
+ }
128
+ // Bitbucket
129
+ const bbMatch = importStr.match(/^https:\/\/bitbucket\.org\/([^/]+)\/([^/@]+)(?:@([^/]+))?$/);
130
+ if (bbMatch) {
131
+ const [, owner, repo, version] = bbMatch;
132
+ return {
133
+ original: importStr,
134
+ platform: 'bitbucket',
135
+ owner,
136
+ repo,
137
+ version: version || 'main',
138
+ repoUrl: `https://bitbucket.org/${owner}/${repo}`,
139
+ entryPoint: 'index.dlang',
140
+ };
141
+ }
142
+ // Generic git URL
143
+ const genericMatch = importStr.match(/^(?:https|git):\/\/([^/]+)\/([^/]+)\/([^/@]+)(?:@([^/]+))?$/);
144
+ if (genericMatch) {
145
+ const [, host, owner, repo, version] = genericMatch;
146
+ return {
147
+ original: importStr,
148
+ platform: 'generic',
149
+ owner,
150
+ repo,
151
+ version: version || 'main',
152
+ repoUrl: `https://${host}/${owner}/${repo}`,
153
+ entryPoint: 'index.dlang',
154
+ };
155
+ }
156
+ throw new Error(`Unsupported git URL format: '${importStr}'.\n` +
157
+ `Supported formats:\n` +
158
+ ` • owner/repo (GitHub shorthand)\n` +
159
+ ` • owner/repo@version\n` +
160
+ ` • https://github.com/owner/repo\n` +
161
+ ` • https://gitlab.com/owner/repo`);
162
+ }
163
+ }
164
+ /**
165
+ * Resolves git repository imports to local entry point files.
166
+ *
167
+ * Implements a content-addressable cache:
168
+ * - Cache location: .dlang/packages/ (project-local, per PRS-010)
169
+ * - Cache key: {owner}/{repo}/{commit-hash}
170
+ * - Downloads entire repository on first use
171
+ * - Reads model.yaml to find entry point
172
+ * - Returns URI to entry point file
173
+ */
174
+ export class GitUrlResolver {
175
+ /**
176
+ * Creates a GitUrlResolver with a project-local cache directory.
177
+ *
178
+ * @param cacheDir - The cache directory path. Per PRS-010, this should be
179
+ * the project's `.dlang/packages/` directory for isolation
180
+ * and reproducibility (like node_modules).
181
+ */
182
+ constructor(cacheDir) {
183
+ this.cacheDir = cacheDir;
184
+ }
185
+ /**
186
+ * Sets the lock file for dependency resolution.
187
+ *
188
+ * When a lock file is set, all package imports will use
189
+ * the locked commit hashes instead of resolving versions.
190
+ * This ensures reproducible builds and handles transitive dependencies.
191
+ *
192
+ * @param lockFile - The parsed lock file from the workspace root
193
+ */
194
+ setLockFile(lockFile) {
195
+ this.lockFile = lockFile;
196
+ }
197
+ /**
198
+ * Resolves a git import URL to the package's entry point file.
199
+ *
200
+ * Process:
201
+ * 1. Parse git URL
202
+ * 2. Check lock file for pinned version (transitive dependency support)
203
+ * 3. Resolve version to commit hash (if not locked)
204
+ * 4. Check cache
205
+ * 5. Download repository if not cached
206
+ * 6. Read model.yaml to find entry point
207
+ * 7. Return URI to entry point file
208
+ *
209
+ * @param importUrl - The git import URL
210
+ * @returns URI to the package's entry point file
211
+ */
212
+ async resolve(importUrl, options = {}) {
213
+ const gitInfo = GitUrlParser.parse(importUrl);
214
+ // Check lock file for pinned version (handles transitive dependencies)
215
+ let commitHash;
216
+ const packageKey = `${gitInfo.owner}/${gitInfo.repo}`;
217
+ if (this.lockFile?.dependencies[packageKey]) {
218
+ // Use locked commit hash (reproducible build)
219
+ commitHash = this.lockFile.dependencies[packageKey].commit;
220
+ }
221
+ else {
222
+ // No lock file entry - need to resolve dynamically
223
+ if (options.allowNetwork === false) {
224
+ // LSP mode: cannot perform network operations
225
+ throw new Error(`Dependency '${packageKey}' not installed.\n` +
226
+ `Hint: Run 'dlang install' to fetch dependencies and generate model.lock.`);
227
+ }
228
+ // CLI/dev mode: resolve version via network
229
+ commitHash = await this.resolveCommit(gitInfo);
230
+ }
231
+ // Check cache
232
+ const cachedPath = this.getCachePath(gitInfo, commitHash);
233
+ if (!(await this.existsInCache(cachedPath))) {
234
+ if (options.allowNetwork === false) {
235
+ throw new Error(`Dependency '${packageKey}' not installed.\n` +
236
+ `Hint: Run 'dlang install' to fetch dependencies.`);
237
+ }
238
+ // Download repository
239
+ await this.downloadRepo(gitInfo, commitHash, cachedPath);
240
+ }
241
+ // Read package metadata to get entry point
242
+ const entryPoint = await this.getEntryPoint(cachedPath);
243
+ const entryFile = path.join(cachedPath, entryPoint);
244
+ // Verify entry point exists
245
+ if (!(await this.existsInCache(entryFile))) {
246
+ throw new Error(`Entry point '${entryPoint}' not found in package '${gitInfo.owner}/${gitInfo.repo}@${gitInfo.version}'.\n` +
247
+ `Hint: Ensure the package has an entry point file (default: index.dlang).`);
248
+ }
249
+ return URI.file(entryFile);
250
+ }
251
+ /**
252
+ * Reads model.yaml to get the package entry point.
253
+ * Falls back to index.dlang if no model.yaml found.
254
+ */
255
+ async getEntryPoint(repoPath) {
256
+ const yamlPath = path.join(repoPath, 'model.yaml');
257
+ try {
258
+ const yamlContent = await fs.readFile(yamlPath, 'utf-8');
259
+ const metadata = this.parseYaml(yamlContent);
260
+ return metadata.entry ?? 'index.dlang';
261
+ }
262
+ catch {
263
+ // No model.yaml or parse error, use default
264
+ return 'index.dlang';
265
+ }
266
+ }
267
+ /**
268
+ * Parses model.yaml content to extract entry point.
269
+ *
270
+ * Expected structure:
271
+ * model:
272
+ * entry: index.dlang
273
+ */
274
+ parseYaml(content) {
275
+ const parsed = YAML.parse(content);
276
+ return {
277
+ entry: parsed.model?.entry,
278
+ name: parsed.model?.name,
279
+ version: parsed.model?.version,
280
+ };
281
+ }
282
+ /**
283
+ * Resolves a version (tag/branch) to a commit hash using git ls-remote.
284
+ */
285
+ async resolveCommit(gitInfo) {
286
+ try {
287
+ // Try to resolve as tag or branch
288
+ const { stdout } = await execAsync(`git ls-remote ${gitInfo.repoUrl} ${gitInfo.version}`);
289
+ if (stdout.trim()) {
290
+ const commitHash = stdout.split('\t')[0];
291
+ return commitHash;
292
+ }
293
+ // If not found, assume it's already a commit hash
294
+ if (/^[0-9a-f]{7,40}$/i.test(gitInfo.version)) {
295
+ return gitInfo.version;
296
+ }
297
+ throw new Error(`Could not resolve version '${gitInfo.version}' for ${gitInfo.repoUrl}.\n` +
298
+ `Hint: Check that the version (tag, branch, or commit) exists in the repository.`);
299
+ }
300
+ catch (error) {
301
+ throw new Error(`Failed to resolve git version '${gitInfo.version}' for ${gitInfo.repoUrl}.\n` +
302
+ `Error: ${error}\n` +
303
+ `Hint: Verify the repository URL is correct and accessible.`);
304
+ }
305
+ }
306
+ /**
307
+ * Gets the local cache path for a git repository.
308
+ *
309
+ * Format: .dlang/packages/{owner}/{repo}/{version}/
310
+ *
311
+ * Per PRS-010: Project-local cache structure mirrors the Design Considerations
312
+ * section showing `.dlang/packages/{owner}/{repo}/{version}/` layout.
313
+ */
314
+ getCachePath(gitInfo, commitHash) {
315
+ return path.join(this.cacheDir, gitInfo.owner, gitInfo.repo, commitHash);
316
+ }
317
+ /**
318
+ * Checks if a file or directory exists in the cache.
319
+ */
320
+ async existsInCache(filePath) {
321
+ try {
322
+ await fs.access(filePath);
323
+ return true;
324
+ }
325
+ catch {
326
+ return false;
327
+ }
328
+ }
329
+ /**
330
+ * Downloads a git repository to the cache.
331
+ *
332
+ * Uses shallow clone for efficiency (only downloads the specific commit).
333
+ */
334
+ async downloadRepo(gitInfo, commitHash, cachePath) {
335
+ const targetDir = path.resolve(cachePath);
336
+ const parentDir = path.dirname(targetDir);
337
+ await fs.mkdir(parentDir, { recursive: true });
338
+ try {
339
+ await execAsync(`git clone ${gitInfo.repoUrl}.git "${targetDir}" --no-checkout`);
340
+ await execAsync(`git -C "${targetDir}" fetch --depth 1 origin ${commitHash}`);
341
+ await execAsync(`git -C "${targetDir}" checkout --force --detach ${commitHash}`);
342
+ await fs.rm(path.join(targetDir, '.git'), { recursive: true, force: true });
343
+ }
344
+ catch (error) {
345
+ await fs.rm(targetDir, { recursive: true, force: true });
346
+ const message = error instanceof Error ? error.message : String(error);
347
+ throw new Error(`Failed to download package '${gitInfo.owner}/${gitInfo.repo}@${gitInfo.version}'.\n` +
348
+ `Error: ${message}\n` +
349
+ `Hint: Check your network connection and verify the repository URL is correct.`);
350
+ }
351
+ }
352
+ /**
353
+ * Clears the entire cache.
354
+ */
355
+ async clearCache() {
356
+ await fs.rm(this.cacheDir, { recursive: true, force: true });
357
+ }
358
+ /**
359
+ * Gets cache statistics (size, number of cached repos, etc.).
360
+ *
361
+ * Cache structure: .dlang/packages/{owner}/{repo}/{version}/
362
+ */
363
+ async getCacheStats() {
364
+ let totalSize = 0;
365
+ let repoCount = 0;
366
+ try {
367
+ const owners = await fs.readdir(this.cacheDir);
368
+ for (const owner of owners) {
369
+ const ownerPath = path.join(this.cacheDir, owner);
370
+ const ownerStat = await fs.stat(ownerPath);
371
+ if (!ownerStat.isDirectory())
372
+ continue;
373
+ const repos = await fs.readdir(ownerPath);
374
+ for (const repo of repos) {
375
+ const repoPath = path.join(ownerPath, repo);
376
+ const repoStat = await fs.stat(repoPath);
377
+ if (!repoStat.isDirectory())
378
+ continue;
379
+ const versions = await fs.readdir(repoPath);
380
+ repoCount += versions.length;
381
+ for (const version of versions) {
382
+ const versionPath = path.join(repoPath, version);
383
+ totalSize += await this.getDirectorySize(versionPath);
384
+ }
385
+ }
386
+ }
387
+ }
388
+ catch {
389
+ // Cache directory doesn't exist yet
390
+ }
391
+ return {
392
+ totalSize,
393
+ repoCount,
394
+ cacheDir: this.cacheDir,
395
+ };
396
+ }
397
+ /**
398
+ * Gets the total size of a directory in bytes.
399
+ */
400
+ async getDirectorySize(dirPath) {
401
+ let size = 0;
402
+ const entries = await fs.readdir(dirPath, { withFileTypes: true });
403
+ for (const entry of entries) {
404
+ const entryPath = path.join(dirPath, entry.name);
405
+ if (entry.isDirectory()) {
406
+ size += await this.getDirectorySize(entryPath);
407
+ }
408
+ else {
409
+ const stats = await fs.stat(entryPath);
410
+ size += stats.size;
411
+ }
412
+ }
413
+ return size;
414
+ }
415
+ }
416
+ //# sourceMappingURL=git-url-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-url-resolver.js","sourceRoot":"","sources":["../../src/services/git-url-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Governance and Compliance Validation Service
3
+ *
4
+ * Enforces organizational policies and best practices:
5
+ * - Allowed/blocked dependency sources
6
+ * - Version policy enforcement (no pre-release in production)
7
+ * - Team ownership validation
8
+ * - License compliance
9
+ * - Audit trail generation
10
+ *
11
+ * Governance policies are defined in the `governance` section of model.yaml:
12
+ *
13
+ * ```yaml
14
+ * governance:
15
+ * allowedSources:
16
+ * - github.com/acme
17
+ * requireStableVersions: true
18
+ * requireTeamOwnership: true
19
+ * ```
20
+ */
21
+ import type { LockFile, GovernancePolicy, GovernanceMetadata, GovernanceViolation } from './types.js';
22
+ /**
23
+ * Validates dependencies against organizational governance policies.
24
+ */
25
+ export declare class GovernanceValidator {
26
+ private readonly policy;
27
+ constructor(policy: GovernancePolicy);
28
+ /**
29
+ * Validates a lock file against governance policies.
30
+ */
31
+ validate(lockFile: LockFile, workspaceRoot: string): Promise<GovernanceViolation[]>;
32
+ /**
33
+ * Loads governance metadata from model.yaml.
34
+ */
35
+ loadGovernanceMetadata(workspaceRoot: string): Promise<GovernanceMetadata>;
36
+ /**
37
+ * Generates an audit report for compliance tracking.
38
+ */
39
+ generateAuditReport(lockFile: LockFile, workspaceRoot: string): Promise<string>;
40
+ }
41
+ /**
42
+ * Loads governance policy from model.yaml governance section.
43
+ */
44
+ export declare function loadGovernancePolicy(workspaceRoot: string): Promise<GovernancePolicy>;
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Governance and Compliance Validation Service
3
+ *
4
+ * Enforces organizational policies and best practices:
5
+ * - Allowed/blocked dependency sources
6
+ * - Version policy enforcement (no pre-release in production)
7
+ * - Team ownership validation
8
+ * - License compliance
9
+ * - Audit trail generation
10
+ *
11
+ * Governance policies are defined in the `governance` section of model.yaml:
12
+ *
13
+ * ```yaml
14
+ * governance:
15
+ * allowedSources:
16
+ * - github.com/acme
17
+ * requireStableVersions: true
18
+ * requireTeamOwnership: true
19
+ * ```
20
+ */
21
+ import path from 'node:path';
22
+ import fs from 'node:fs/promises';
23
+ import YAML from 'yaml';
24
+ import { isPreRelease } from './semver.js';
25
+ /**
26
+ * Validates dependencies against organizational governance policies.
27
+ */
28
+ export class GovernanceValidator {
29
+ constructor(policy) {
30
+ this.policy = policy;
31
+ }
32
+ /**
33
+ * Validates a lock file against governance policies.
34
+ */
35
+ async validate(lockFile, workspaceRoot) {
36
+ const violations = [];
37
+ // Validate each dependency
38
+ for (const [packageKey, locked] of Object.entries(lockFile.dependencies)) {
39
+ // Check allowed sources
40
+ if (this.policy.allowedSources && this.policy.allowedSources.length > 0) {
41
+ const isAllowed = this.policy.allowedSources.some(pattern => locked.resolved.includes(pattern) || packageKey.startsWith(pattern));
42
+ if (!isAllowed) {
43
+ violations.push({
44
+ type: 'blocked-source',
45
+ packageKey,
46
+ message: `Package from unauthorized source: ${locked.resolved}`,
47
+ severity: 'error',
48
+ });
49
+ }
50
+ }
51
+ // Check blocked packages
52
+ if (this.policy.blockedPackages) {
53
+ const isBlocked = this.policy.blockedPackages.some(pattern => packageKey.includes(pattern));
54
+ if (isBlocked) {
55
+ violations.push({
56
+ type: 'blocked-source',
57
+ packageKey,
58
+ message: `Package is blocked by governance policy`,
59
+ severity: 'error',
60
+ });
61
+ }
62
+ }
63
+ // Check version stability
64
+ if (this.policy.requireStableVersions) {
65
+ if (isPreRelease(locked.ref)) {
66
+ violations.push({
67
+ type: 'unstable-version',
68
+ packageKey,
69
+ message: `Pre-release ref not allowed: ${locked.ref}`,
70
+ severity: 'error',
71
+ });
72
+ }
73
+ }
74
+ }
75
+ // Validate workspace metadata
76
+ if (this.policy.requireTeamOwnership) {
77
+ const metadata = await this.loadGovernanceMetadata(workspaceRoot);
78
+ if (!metadata.team || !metadata.contact) {
79
+ violations.push({
80
+ type: 'missing-metadata',
81
+ packageKey: 'workspace',
82
+ message: 'Missing required team ownership metadata in model.yaml',
83
+ severity: 'warning',
84
+ });
85
+ }
86
+ }
87
+ return violations;
88
+ }
89
+ /**
90
+ * Loads governance metadata from model.yaml.
91
+ */
92
+ async loadGovernanceMetadata(workspaceRoot) {
93
+ const manifestPath = path.join(workspaceRoot, 'model.yaml');
94
+ try {
95
+ const content = await fs.readFile(manifestPath, 'utf-8');
96
+ const manifest = YAML.parse(content);
97
+ return manifest.metadata || {};
98
+ }
99
+ catch {
100
+ return {};
101
+ }
102
+ }
103
+ /**
104
+ * Generates an audit report for compliance tracking.
105
+ */
106
+ async generateAuditReport(lockFile, workspaceRoot) {
107
+ const metadata = await this.loadGovernanceMetadata(workspaceRoot);
108
+ const violations = await this.validate(lockFile, workspaceRoot);
109
+ const lines = [];
110
+ lines.push('=== Dependency Audit Report ===');
111
+ lines.push('');
112
+ lines.push(`Workspace: ${workspaceRoot}`);
113
+ lines.push(`Team: ${metadata.team || 'N/A'}`);
114
+ lines.push(`Contact: ${metadata.contact || 'N/A'}`);
115
+ lines.push(`Domain: ${metadata.domain || 'N/A'}`);
116
+ lines.push('');
117
+ lines.push('Dependencies:');
118
+ for (const [packageKey, locked] of Object.entries(lockFile.dependencies)) {
119
+ lines.push(` - ${packageKey}@${locked.ref}`);
120
+ lines.push(` Source: ${locked.resolved}`);
121
+ lines.push(` Commit: ${locked.commit}`);
122
+ }
123
+ if (violations.length > 0) {
124
+ lines.push('');
125
+ lines.push('Violations:');
126
+ for (const violation of violations) {
127
+ lines.push(` [${violation.severity.toUpperCase()}] ${violation.packageKey}: ${violation.message}`);
128
+ }
129
+ }
130
+ else {
131
+ lines.push('');
132
+ lines.push('\u2713 No policy violations detected');
133
+ }
134
+ return lines.join('\n');
135
+ }
136
+ }
137
+ /**
138
+ * Loads governance policy from model.yaml governance section.
139
+ */
140
+ export async function loadGovernancePolicy(workspaceRoot) {
141
+ const manifestPath = path.join(workspaceRoot, 'model.yaml');
142
+ try {
143
+ const content = await fs.readFile(manifestPath, 'utf-8');
144
+ const manifest = YAML.parse(content);
145
+ // Return governance section or empty policy if not defined
146
+ return manifest.governance || {};
147
+ }
148
+ catch {
149
+ // No manifest or parse error = permissive defaults
150
+ return {};
151
+ }
152
+ }
153
+ //# sourceMappingURL=governance-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"governance-validator.js","sourceRoot":"","sources":["../../src/services/governance-validator.ts"],"names":[],"mappings":"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"}