@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.
- package/README.md +163 -0
- package/out/ast-augmentation.d.ts +6 -0
- package/out/ast-augmentation.js +2 -0
- package/out/ast-augmentation.js.map +1 -0
- package/out/domain-lang-module.d.ts +57 -0
- package/out/domain-lang-module.js +67 -0
- package/out/domain-lang-module.js.map +1 -0
- package/out/generated/ast.d.ts +759 -0
- package/out/generated/ast.js +556 -0
- package/out/generated/ast.js.map +1 -0
- package/out/generated/grammar.d.ts +6 -0
- package/out/generated/grammar.js +2407 -0
- package/out/generated/grammar.js.map +1 -0
- package/out/generated/module.d.ts +13 -0
- package/out/generated/module.js +21 -0
- package/out/generated/module.js.map +1 -0
- package/out/index.d.ts +16 -0
- package/out/index.js +22 -0
- package/out/index.js.map +1 -0
- package/out/lsp/domain-lang-code-actions.d.ts +55 -0
- package/out/lsp/domain-lang-code-actions.js +143 -0
- package/out/lsp/domain-lang-code-actions.js.map +1 -0
- package/out/lsp/domain-lang-completion.d.ts +37 -0
- package/out/lsp/domain-lang-completion.js +452 -0
- package/out/lsp/domain-lang-completion.js.map +1 -0
- package/out/lsp/domain-lang-formatter.d.ts +15 -0
- package/out/lsp/domain-lang-formatter.js +43 -0
- package/out/lsp/domain-lang-formatter.js.map +1 -0
- package/out/lsp/domain-lang-naming.d.ts +34 -0
- package/out/lsp/domain-lang-naming.js +49 -0
- package/out/lsp/domain-lang-naming.js.map +1 -0
- package/out/lsp/domain-lang-scope.d.ts +59 -0
- package/out/lsp/domain-lang-scope.js +102 -0
- package/out/lsp/domain-lang-scope.js.map +1 -0
- package/out/lsp/domain-lang-workspace-manager.d.ts +21 -0
- package/out/lsp/domain-lang-workspace-manager.js +93 -0
- package/out/lsp/domain-lang-workspace-manager.js.map +1 -0
- package/out/lsp/hover/ddd-pattern-explanations.d.ts +50 -0
- package/out/lsp/hover/ddd-pattern-explanations.js +196 -0
- package/out/lsp/hover/ddd-pattern-explanations.js.map +1 -0
- package/out/lsp/hover/domain-lang-hover.d.ts +19 -0
- package/out/lsp/hover/domain-lang-hover.js +302 -0
- package/out/lsp/hover/domain-lang-hover.js.map +1 -0
- package/out/lsp/hover/domain-lang-keywords.d.ts +13 -0
- package/out/lsp/hover/domain-lang-keywords.js +47 -0
- package/out/lsp/hover/domain-lang-keywords.js.map +1 -0
- package/out/lsp/manifest-diagnostics.d.ts +82 -0
- package/out/lsp/manifest-diagnostics.js +230 -0
- package/out/lsp/manifest-diagnostics.js.map +1 -0
- package/out/main-browser.d.ts +1 -0
- package/out/main-browser.js +11 -0
- package/out/main-browser.js.map +1 -0
- package/out/main.d.ts +1 -0
- package/out/main.js +74 -0
- package/out/main.js.map +1 -0
- package/out/sdk/ast-augmentation.d.ts +136 -0
- package/out/sdk/ast-augmentation.js +62 -0
- package/out/sdk/ast-augmentation.js.map +1 -0
- package/out/sdk/index.d.ts +94 -0
- package/out/sdk/index.js +97 -0
- package/out/sdk/index.js.map +1 -0
- package/out/sdk/indexes.d.ts +16 -0
- package/out/sdk/indexes.js +97 -0
- package/out/sdk/indexes.js.map +1 -0
- package/out/sdk/loader-node.d.ts +51 -0
- package/out/sdk/loader-node.js +119 -0
- package/out/sdk/loader-node.js.map +1 -0
- package/out/sdk/loader.d.ts +49 -0
- package/out/sdk/loader.js +85 -0
- package/out/sdk/loader.js.map +1 -0
- package/out/sdk/patterns.d.ts +93 -0
- package/out/sdk/patterns.js +123 -0
- package/out/sdk/patterns.js.map +1 -0
- package/out/sdk/query.d.ts +90 -0
- package/out/sdk/query.js +679 -0
- package/out/sdk/query.js.map +1 -0
- package/out/sdk/resolution.d.ts +52 -0
- package/out/sdk/resolution.js +68 -0
- package/out/sdk/resolution.js.map +1 -0
- package/out/sdk/types.d.ts +280 -0
- package/out/sdk/types.js +8 -0
- package/out/sdk/types.js.map +1 -0
- package/out/services/dependency-analyzer.d.ts +58 -0
- package/out/services/dependency-analyzer.js +254 -0
- package/out/services/dependency-analyzer.js.map +1 -0
- package/out/services/dependency-resolver.d.ts +146 -0
- package/out/services/dependency-resolver.js +452 -0
- package/out/services/dependency-resolver.js.map +1 -0
- package/out/services/git-url-resolver.browser.d.ts +10 -0
- package/out/services/git-url-resolver.browser.js +19 -0
- package/out/services/git-url-resolver.browser.js.map +1 -0
- package/out/services/git-url-resolver.d.ts +158 -0
- package/out/services/git-url-resolver.js +416 -0
- package/out/services/git-url-resolver.js.map +1 -0
- package/out/services/governance-validator.d.ts +44 -0
- package/out/services/governance-validator.js +153 -0
- package/out/services/governance-validator.js.map +1 -0
- package/out/services/import-resolver.d.ts +77 -0
- package/out/services/import-resolver.js +240 -0
- package/out/services/import-resolver.js.map +1 -0
- package/out/services/performance-optimizer.d.ts +60 -0
- package/out/services/performance-optimizer.js +140 -0
- package/out/services/performance-optimizer.js.map +1 -0
- package/out/services/relationship-inference.d.ts +11 -0
- package/out/services/relationship-inference.js +98 -0
- package/out/services/relationship-inference.js.map +1 -0
- package/out/services/semver.d.ts +98 -0
- package/out/services/semver.js +195 -0
- package/out/services/semver.js.map +1 -0
- package/out/services/types.d.ts +340 -0
- package/out/services/types.js +46 -0
- package/out/services/types.js.map +1 -0
- package/out/services/workspace-manager.d.ts +123 -0
- package/out/services/workspace-manager.js +489 -0
- package/out/services/workspace-manager.js.map +1 -0
- package/out/syntaxes/domain-lang.monarch.d.ts +76 -0
- package/out/syntaxes/domain-lang.monarch.js +29 -0
- package/out/syntaxes/domain-lang.monarch.js.map +1 -0
- package/out/utils/import-utils.d.ts +49 -0
- package/out/utils/import-utils.js +128 -0
- package/out/utils/import-utils.js.map +1 -0
- package/out/validation/bounded-context.d.ts +11 -0
- package/out/validation/bounded-context.js +79 -0
- package/out/validation/bounded-context.js.map +1 -0
- package/out/validation/classification.d.ts +3 -0
- package/out/validation/classification.js +3 -0
- package/out/validation/classification.js.map +1 -0
- package/out/validation/constants.d.ts +180 -0
- package/out/validation/constants.js +235 -0
- package/out/validation/constants.js.map +1 -0
- package/out/validation/domain-lang-validator.d.ts +2 -0
- package/out/validation/domain-lang-validator.js +27 -0
- package/out/validation/domain-lang-validator.js.map +1 -0
- package/out/validation/domain.d.ts +11 -0
- package/out/validation/domain.js +63 -0
- package/out/validation/domain.js.map +1 -0
- package/out/validation/import.d.ts +68 -0
- package/out/validation/import.js +237 -0
- package/out/validation/import.js.map +1 -0
- package/out/validation/manifest.d.ts +144 -0
- package/out/validation/manifest.js +327 -0
- package/out/validation/manifest.js.map +1 -0
- package/out/validation/maps.d.ts +21 -0
- package/out/validation/maps.js +60 -0
- package/out/validation/maps.js.map +1 -0
- package/out/validation/metadata.d.ts +7 -0
- package/out/validation/metadata.js +16 -0
- package/out/validation/metadata.js.map +1 -0
- package/out/validation/model.d.ts +12 -0
- package/out/validation/model.js +29 -0
- package/out/validation/model.js.map +1 -0
- package/out/validation/relationships.d.ts +12 -0
- package/out/validation/relationships.js +94 -0
- package/out/validation/relationships.js.map +1 -0
- package/out/validation/shared.d.ts +6 -0
- package/out/validation/shared.js +12 -0
- package/out/validation/shared.js.map +1 -0
- package/package.json +110 -0
- package/src/ast-augmentation.ts +5 -0
- package/src/domain-lang-module.ts +112 -0
- package/src/domain-lang.langium +351 -0
- package/src/generated/ast.ts +986 -0
- package/src/generated/grammar.ts +2409 -0
- package/src/generated/module.ts +25 -0
- package/src/index.ts +24 -0
- package/src/lsp/domain-lang-code-actions.ts +189 -0
- package/src/lsp/domain-lang-completion.ts +514 -0
- package/src/lsp/domain-lang-formatter.ts +51 -0
- package/src/lsp/domain-lang-naming.ts +56 -0
- package/src/lsp/domain-lang-scope.ts +137 -0
- package/src/lsp/domain-lang-workspace-manager.ts +104 -0
- package/src/lsp/hover/ddd-pattern-explanations.ts +237 -0
- package/src/lsp/hover/domain-lang-hover.ts +338 -0
- package/src/lsp/hover/domain-lang-keywords.ts +50 -0
- package/src/lsp/manifest-diagnostics.ts +290 -0
- package/src/main-browser.ts +15 -0
- package/src/main.ts +85 -0
- package/src/sdk/README.md +297 -0
- package/src/sdk/ast-augmentation.ts +157 -0
- package/src/sdk/index.ts +126 -0
- package/src/sdk/indexes.ts +155 -0
- package/src/sdk/loader-node.ts +146 -0
- package/src/sdk/loader.ts +99 -0
- package/src/sdk/patterns.ts +147 -0
- package/src/sdk/query.ts +802 -0
- package/src/sdk/resolution.ts +78 -0
- package/src/sdk/types.ts +323 -0
- package/src/services/dependency-analyzer.ts +321 -0
- package/src/services/dependency-resolver.ts +551 -0
- package/src/services/git-url-resolver.browser.ts +26 -0
- package/src/services/git-url-resolver.ts +517 -0
- package/src/services/governance-validator.ts +177 -0
- package/src/services/import-resolver.ts +292 -0
- package/src/services/performance-optimizer.ts +170 -0
- package/src/services/relationship-inference.ts +121 -0
- package/src/services/semver.ts +213 -0
- package/src/services/types.ts +415 -0
- package/src/services/workspace-manager.ts +607 -0
- package/src/syntaxes/domain-lang.monarch.ts +29 -0
- package/src/utils/import-utils.ts +152 -0
- package/src/validation/bounded-context.ts +99 -0
- package/src/validation/classification.ts +5 -0
- package/src/validation/constants.ts +304 -0
- package/src/validation/domain-lang-validator.ts +33 -0
- package/src/validation/domain.ts +77 -0
- package/src/validation/import.ts +295 -0
- package/src/validation/manifest.ts +439 -0
- package/src/validation/maps.ts +76 -0
- package/src/validation/metadata.ts +18 -0
- package/src/validation/model.ts +37 -0
- package/src/validation/relationships.ts +154 -0
- package/src/validation/shared.ts +14 -0
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dependency Resolution Service
|
|
3
|
+
*
|
|
4
|
+
* Discovers and resolves transitive dependencies for DomainLang packages.
|
|
5
|
+
* Generates lock files for reproducible builds.
|
|
6
|
+
*
|
|
7
|
+
* Algorithm:
|
|
8
|
+
* 1. Parse root model.yaml
|
|
9
|
+
* 2. Download all direct dependencies
|
|
10
|
+
* 3. Parse each dependency's model.yaml
|
|
11
|
+
* 4. Recursively discover transitive dependencies
|
|
12
|
+
* 5. Resolve version constraints using "Latest Wins" strategy
|
|
13
|
+
* 6. Generate lock file with pinned commit hashes
|
|
14
|
+
*
|
|
15
|
+
* Resolution Strategy ("Latest Wins"):
|
|
16
|
+
* - SemVer tags (same major): Pick highest compatible version
|
|
17
|
+
* - Same branch: No conflict, resolve once
|
|
18
|
+
* - Commit pins: Error (explicit pins are intentional)
|
|
19
|
+
* - Major version mismatch: Error
|
|
20
|
+
* - Tag vs Branch: Error (incompatible intent)
|
|
21
|
+
*/
|
|
22
|
+
import path from 'node:path';
|
|
23
|
+
import fs from 'node:fs/promises';
|
|
24
|
+
import YAML from 'yaml';
|
|
25
|
+
import { GitUrlParser, GitUrlResolver } from './git-url-resolver.js';
|
|
26
|
+
import { parseSemVer, pickLatestSemVer, detectRefType } from './semver.js';
|
|
27
|
+
export class DependencyResolver {
|
|
28
|
+
constructor(workspaceRoot, gitResolver) {
|
|
29
|
+
/** Override messages for CLI output */
|
|
30
|
+
this.overrideMessages = [];
|
|
31
|
+
/** Resolution messages from "Latest Wins" auto-resolution */
|
|
32
|
+
this.resolutionMessages = [];
|
|
33
|
+
this.workspaceRoot = workspaceRoot;
|
|
34
|
+
// Per PRS-010: Project-local cache at .dlang/packages/
|
|
35
|
+
const cacheDir = path.join(workspaceRoot, '.dlang', 'packages');
|
|
36
|
+
this.gitResolver = gitResolver || new GitUrlResolver(cacheDir);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolves all dependencies for a workspace.
|
|
40
|
+
*
|
|
41
|
+
* Process:
|
|
42
|
+
* 1. Load root model.yaml
|
|
43
|
+
* 2. Build dependency graph (discover transitive deps)
|
|
44
|
+
* 3. Resolve version constraints
|
|
45
|
+
* 4. Generate lock file
|
|
46
|
+
* 5. Download all dependencies to cache
|
|
47
|
+
*
|
|
48
|
+
* @returns Generated lock file
|
|
49
|
+
*/
|
|
50
|
+
async resolveDependencies() {
|
|
51
|
+
// Load root package config
|
|
52
|
+
const rootConfig = await this.loadPackageConfig(this.workspaceRoot);
|
|
53
|
+
if (!rootConfig.dependencies || Object.keys(rootConfig.dependencies).length === 0) {
|
|
54
|
+
// No dependencies
|
|
55
|
+
return { version: '1', dependencies: {} };
|
|
56
|
+
}
|
|
57
|
+
// Build dependency graph
|
|
58
|
+
const graph = await this.buildDependencyGraph(rootConfig);
|
|
59
|
+
// Apply overrides before conflict detection
|
|
60
|
+
this.applyOverrides(graph, rootConfig.overrides);
|
|
61
|
+
// Detect version conflicts and package-level cycles before resolving
|
|
62
|
+
this.detectVersionConflicts(graph);
|
|
63
|
+
this.detectPackageCycles(graph);
|
|
64
|
+
// Resolve version constraints
|
|
65
|
+
await this.resolveVersions(graph);
|
|
66
|
+
// Generate and return lock file (caller writes to disk)
|
|
67
|
+
return this.generateLockFile(graph);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Applies ref overrides from model.yaml to resolve conflicts explicitly.
|
|
71
|
+
*
|
|
72
|
+
* Overrides take precedence over all other constraints.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```yaml
|
|
76
|
+
* overrides:
|
|
77
|
+
* domainlang/core: v2.0.0
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
applyOverrides(graph, overrides) {
|
|
81
|
+
if (!overrides)
|
|
82
|
+
return;
|
|
83
|
+
for (const [pkg, overrideRef] of Object.entries(overrides)) {
|
|
84
|
+
const node = graph.nodes[pkg];
|
|
85
|
+
if (node) {
|
|
86
|
+
// Override replaces all constraints with a single definitive ref
|
|
87
|
+
node.constraints = new Set([overrideRef]);
|
|
88
|
+
node.refConstraint = overrideRef;
|
|
89
|
+
// Track that this was an override for messaging
|
|
90
|
+
this.overrideMessages.push(`Override applied: ${pkg}@${overrideRef}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Returns any override messages from the last dependency resolution.
|
|
96
|
+
*/
|
|
97
|
+
getOverrideMessages() {
|
|
98
|
+
return this.overrideMessages;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Builds the complete dependency graph by recursively discovering transitive dependencies.
|
|
102
|
+
*/
|
|
103
|
+
async buildDependencyGraph(rootConfig) {
|
|
104
|
+
const graph = {
|
|
105
|
+
nodes: {},
|
|
106
|
+
root: rootConfig.name || 'root',
|
|
107
|
+
};
|
|
108
|
+
// Process root dependencies
|
|
109
|
+
const queue = [];
|
|
110
|
+
for (const [depName, refConstraint] of Object.entries(rootConfig.dependencies || {})) {
|
|
111
|
+
queue.push({
|
|
112
|
+
packageKey: depName,
|
|
113
|
+
refConstraint,
|
|
114
|
+
parent: graph.root
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
// BFS to discover all transitive dependencies
|
|
118
|
+
const visited = new Set();
|
|
119
|
+
while (queue.length > 0) {
|
|
120
|
+
const entry = queue.shift();
|
|
121
|
+
if (!entry)
|
|
122
|
+
break;
|
|
123
|
+
const { packageKey, refConstraint, parent } = entry;
|
|
124
|
+
// Skip if already processed
|
|
125
|
+
if (visited.has(packageKey)) {
|
|
126
|
+
// Update dependents list and record constraint
|
|
127
|
+
const existing = graph.nodes[packageKey];
|
|
128
|
+
if (!existing.dependents.includes(parent)) {
|
|
129
|
+
existing.dependents.push(parent);
|
|
130
|
+
}
|
|
131
|
+
if (!existing.constraints)
|
|
132
|
+
existing.constraints = new Set();
|
|
133
|
+
existing.constraints.add(refConstraint);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
visited.add(packageKey);
|
|
137
|
+
// Parse package identifier
|
|
138
|
+
const gitInfo = GitUrlParser.parse(packageKey);
|
|
139
|
+
// Download package to get its model.yaml
|
|
140
|
+
const packageUri = await this.gitResolver.resolve(packageKey);
|
|
141
|
+
const packageDir = path.dirname(packageUri.fsPath);
|
|
142
|
+
// Load package config
|
|
143
|
+
const packageConfig = await this.loadPackageConfig(packageDir);
|
|
144
|
+
// Add to graph
|
|
145
|
+
graph.nodes[packageKey] = {
|
|
146
|
+
packageKey,
|
|
147
|
+
refConstraint,
|
|
148
|
+
constraints: new Set([refConstraint]),
|
|
149
|
+
repoUrl: gitInfo.repoUrl,
|
|
150
|
+
dependencies: packageConfig.dependencies || {},
|
|
151
|
+
dependents: [parent],
|
|
152
|
+
};
|
|
153
|
+
// Queue transitive dependencies
|
|
154
|
+
for (const [transDepName, transRefConstraint] of Object.entries(packageConfig.dependencies || {})) {
|
|
155
|
+
queue.push({
|
|
156
|
+
packageKey: transDepName,
|
|
157
|
+
refConstraint: transRefConstraint,
|
|
158
|
+
parent: packageKey,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return graph;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Resolves ref constraints to specific commits.
|
|
166
|
+
*
|
|
167
|
+
* Simple algorithm: Use the ref specified in the constraint.
|
|
168
|
+
* Detects refType (tag, branch, or commit) based on format.
|
|
169
|
+
*/
|
|
170
|
+
async resolveVersions(graph) {
|
|
171
|
+
for (const [packageKey, node] of Object.entries(graph.nodes)) {
|
|
172
|
+
// Parse package to get repo info
|
|
173
|
+
const gitInfo = GitUrlParser.parse(packageKey);
|
|
174
|
+
// Extract ref from constraint
|
|
175
|
+
const ref = this.extractRefFromConstraint(node.refConstraint);
|
|
176
|
+
// Detect ref type based on format
|
|
177
|
+
const refType = detectRefType(ref);
|
|
178
|
+
// Resolve ref to commit hash
|
|
179
|
+
const commitHash = await this.resolveCommitHash(gitInfo.repoUrl, ref);
|
|
180
|
+
node.resolvedRef = ref;
|
|
181
|
+
node.refType = refType;
|
|
182
|
+
node.commitHash = commitHash;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Extracts a ref from a constraint string.
|
|
187
|
+
*
|
|
188
|
+
* Examples:
|
|
189
|
+
* - "^1.0.0" → "1.0.0" (treated as tag)
|
|
190
|
+
* - "~2.3.0" → "2.3.0" (treated as tag)
|
|
191
|
+
* - "1.5.0" → "1.5.0" (treated as tag)
|
|
192
|
+
* - "main" → "main" (treated as branch)
|
|
193
|
+
* - "abc123def" → "abc123def" (treated as commit)
|
|
194
|
+
* - "owner/repo@1.0.0" → "1.0.0"
|
|
195
|
+
*/
|
|
196
|
+
extractRefFromConstraint(constraint) {
|
|
197
|
+
// Remove semver operators (legacy support)
|
|
198
|
+
let ref = constraint.replace(/^[\^~>=<]/, '');
|
|
199
|
+
// Extract ref from full import URL if present
|
|
200
|
+
if (ref.includes('@')) {
|
|
201
|
+
ref = ref.split('@')[1];
|
|
202
|
+
}
|
|
203
|
+
return ref || 'main';
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Resolves a version (tag/branch) to a commit hash using git ls-remote.
|
|
207
|
+
*/
|
|
208
|
+
async resolveCommitHash(repoUrl, version) {
|
|
209
|
+
// This is a placeholder - the actual implementation is in GitUrlResolver
|
|
210
|
+
// We need to extract it or call the resolver
|
|
211
|
+
const gitInfo = GitUrlParser.parse(`${repoUrl}@${version}`);
|
|
212
|
+
const uri = await this.gitResolver.resolve(gitInfo.original);
|
|
213
|
+
// Extract commit hash from cache path
|
|
214
|
+
// Per PRS-010: Project-local cache at .dlang/packages/{owner}/{repo}/{commit}/
|
|
215
|
+
const pathParts = uri.fsPath.split(path.sep);
|
|
216
|
+
const commitHashIndex = pathParts.length - 2; // Second to last segment
|
|
217
|
+
return pathParts[commitHashIndex];
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Generates a lock file from the resolved dependency graph.
|
|
221
|
+
*/
|
|
222
|
+
generateLockFile(graph) {
|
|
223
|
+
const dependencies = {};
|
|
224
|
+
for (const [packageKey, node] of Object.entries(graph.nodes)) {
|
|
225
|
+
if (!node.resolvedRef || !node.commitHash) {
|
|
226
|
+
throw new Error(`Failed to resolve ref for '${packageKey}'.\n` +
|
|
227
|
+
`Hint: Check that the package exists and the ref is valid.`);
|
|
228
|
+
}
|
|
229
|
+
dependencies[packageKey] = {
|
|
230
|
+
ref: node.resolvedRef,
|
|
231
|
+
refType: node.refType ?? 'commit',
|
|
232
|
+
resolved: node.repoUrl || '',
|
|
233
|
+
commit: node.commitHash,
|
|
234
|
+
// Future: Calculate integrity hash
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
version: '1',
|
|
239
|
+
dependencies,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Loads and parses a package's model.yaml file.
|
|
244
|
+
*/
|
|
245
|
+
async loadPackageConfig(packageDir) {
|
|
246
|
+
const yamlPath = path.join(packageDir, 'model.yaml');
|
|
247
|
+
try {
|
|
248
|
+
const yamlContent = await fs.readFile(yamlPath, 'utf-8');
|
|
249
|
+
return this.parseYaml(yamlContent);
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
// No model.yaml found
|
|
253
|
+
return {};
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Parses model.yaml content.
|
|
258
|
+
*
|
|
259
|
+
* Expected structure:
|
|
260
|
+
* model:
|
|
261
|
+
* name: package-name
|
|
262
|
+
* version: 1.0.0
|
|
263
|
+
* entry: index.dlang
|
|
264
|
+
*
|
|
265
|
+
* dependencies:
|
|
266
|
+
* package-name:
|
|
267
|
+
* source: owner/repo
|
|
268
|
+
* ref: v1.0.0
|
|
269
|
+
*/
|
|
270
|
+
parseYaml(content) {
|
|
271
|
+
const parsed = YAML.parse(content);
|
|
272
|
+
const config = {};
|
|
273
|
+
if (parsed.model) {
|
|
274
|
+
config.name = parsed.model.name;
|
|
275
|
+
config.version = parsed.model.version;
|
|
276
|
+
config.entry = parsed.model.entry;
|
|
277
|
+
}
|
|
278
|
+
if (parsed.dependencies) {
|
|
279
|
+
config.dependencies = {};
|
|
280
|
+
for (const [, depInfo] of Object.entries(parsed.dependencies)) {
|
|
281
|
+
if (depInfo.source) {
|
|
282
|
+
const refConstraint = depInfo.ref || 'main';
|
|
283
|
+
// Store as "source@ref" for consistency with import resolution
|
|
284
|
+
config.dependencies[depInfo.source] = refConstraint;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// Parse overrides section for explicit ref control
|
|
289
|
+
if (parsed.overrides) {
|
|
290
|
+
config.overrides = parsed.overrides;
|
|
291
|
+
}
|
|
292
|
+
return config;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Detects ref conflicts and applies "Latest Wins" resolution strategy.
|
|
296
|
+
*
|
|
297
|
+
* Resolution Rules:
|
|
298
|
+
* - SemVer tags (same major): Pick highest version automatically
|
|
299
|
+
* - Same branch refs: No conflict, use single resolution
|
|
300
|
+
* - Commit SHA conflicts: Error (explicit pins are intentional)
|
|
301
|
+
* - Major version mismatch: Error (breaking change)
|
|
302
|
+
* - Tag vs Branch: Error (incompatible intent)
|
|
303
|
+
*
|
|
304
|
+
* Modifies graph nodes in-place to set the resolved constraint.
|
|
305
|
+
* Throws an error only for unresolvable conflicts.
|
|
306
|
+
*/
|
|
307
|
+
detectVersionConflicts(graph) {
|
|
308
|
+
const resolutionMessages = [];
|
|
309
|
+
for (const [pkg, node] of Object.entries(graph.nodes)) {
|
|
310
|
+
const constraints = node.constraints ?? new Set([node.refConstraint]);
|
|
311
|
+
if (constraints.size <= 1)
|
|
312
|
+
continue; // No conflict
|
|
313
|
+
const refs = Array.from(constraints);
|
|
314
|
+
const refTypes = refs.map(ref => ({
|
|
315
|
+
ref,
|
|
316
|
+
type: detectRefType(ref),
|
|
317
|
+
semver: parseSemVer(ref),
|
|
318
|
+
}));
|
|
319
|
+
// Check for mixed types (tag vs branch vs commit)
|
|
320
|
+
const types = new Set(refTypes.map(r => r.type));
|
|
321
|
+
// Case 1: All commits - must be exact match
|
|
322
|
+
if (types.size === 1 && types.has('commit')) {
|
|
323
|
+
this.throwConflictError(pkg, refs, node.dependents, 'Explicit commit pins cannot be automatically resolved.\n' +
|
|
324
|
+
'Add an override in model.yaml:\n\n' +
|
|
325
|
+
' overrides:\n' +
|
|
326
|
+
` ${pkg}: ${refs[0]}`);
|
|
327
|
+
}
|
|
328
|
+
// Case 2: Mixed types (tag vs branch or tag vs commit)
|
|
329
|
+
if (types.size > 1) {
|
|
330
|
+
this.throwConflictError(pkg, refs, node.dependents, 'Cannot mix ref types (tags, branches, commits).\n' +
|
|
331
|
+
'Add an override in model.yaml to specify which to use:\n\n' +
|
|
332
|
+
' overrides:\n' +
|
|
333
|
+
` ${pkg}: <ref>`);
|
|
334
|
+
}
|
|
335
|
+
// Case 3: All branches - must be same branch
|
|
336
|
+
if (types.size === 1 && types.has('branch')) {
|
|
337
|
+
const uniqueBranches = new Set(refs);
|
|
338
|
+
if (uniqueBranches.size > 1) {
|
|
339
|
+
this.throwConflictError(pkg, refs, node.dependents, 'Different branch refs cannot be automatically resolved.\n' +
|
|
340
|
+
'Add an override in model.yaml:\n\n' +
|
|
341
|
+
' overrides:\n' +
|
|
342
|
+
` ${pkg}: ${refs[0]}`);
|
|
343
|
+
}
|
|
344
|
+
// Same branch - no conflict, continue
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
// Case 4: All SemVer tags - apply "Latest Wins"
|
|
348
|
+
const semvers = refTypes
|
|
349
|
+
.filter((r) => r.semver !== undefined)
|
|
350
|
+
.map(r => r.semver);
|
|
351
|
+
if (semvers.length !== refs.length) {
|
|
352
|
+
// Some refs don't parse as SemVer - can't auto-resolve
|
|
353
|
+
this.throwConflictError(pkg, refs, node.dependents, 'Not all refs are valid SemVer tags.\n' +
|
|
354
|
+
'Add an override in model.yaml:\n\n' +
|
|
355
|
+
' overrides:\n' +
|
|
356
|
+
` ${pkg}: <ref>`);
|
|
357
|
+
}
|
|
358
|
+
// Check major version compatibility
|
|
359
|
+
const majors = new Set(semvers.map(s => s.major));
|
|
360
|
+
if (majors.size > 1) {
|
|
361
|
+
const majorList = Array.from(majors).sort().join(' vs ');
|
|
362
|
+
this.throwConflictError(pkg, refs, node.dependents, `Major version mismatch (v${majorList}). This may indicate breaking changes.\n` +
|
|
363
|
+
'Add an override in model.yaml if you want to force a version:\n\n' +
|
|
364
|
+
' overrides:\n' +
|
|
365
|
+
` ${pkg}: ${refs[refs.length - 1]}`);
|
|
366
|
+
}
|
|
367
|
+
// All same major version - pick latest (Latest Wins!)
|
|
368
|
+
const latest = pickLatestSemVer(refs);
|
|
369
|
+
if (latest && latest !== node.refConstraint) {
|
|
370
|
+
// Update the node to use the resolved ref
|
|
371
|
+
node.refConstraint = latest;
|
|
372
|
+
// Log the resolution for user feedback
|
|
373
|
+
const otherRefs = refs.filter(r => r !== latest).join(', ');
|
|
374
|
+
resolutionMessages.push(`Resolved ${pkg}: using ${latest} (satisfies ${otherRefs})`);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
// Store resolution messages for later output
|
|
378
|
+
if (resolutionMessages.length > 0) {
|
|
379
|
+
this.resolutionMessages = resolutionMessages;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Throws a formatted conflict error with actionable hints.
|
|
384
|
+
*/
|
|
385
|
+
throwConflictError(pkg, refs, dependents, hint) {
|
|
386
|
+
const depLines = dependents.map((d, i) => ` └─ ${d} requires ${pkg}@${refs[i] || refs[0]}`).join('\n');
|
|
387
|
+
throw new Error(`Dependency ref conflict for '${pkg}'\n` +
|
|
388
|
+
depLines + '\n\n' +
|
|
389
|
+
hint);
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Returns any resolution messages from the last dependency resolution.
|
|
393
|
+
* Useful for CLI output to inform users about auto-resolved conflicts.
|
|
394
|
+
*/
|
|
395
|
+
getResolutionMessages() {
|
|
396
|
+
return this.resolutionMessages;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Detects package-level cycles in the dependency graph and throws a clear error.
|
|
400
|
+
*/
|
|
401
|
+
detectPackageCycles(graph) {
|
|
402
|
+
const GRAY = 1, BLACK = 2;
|
|
403
|
+
const color = {};
|
|
404
|
+
const stack = [];
|
|
405
|
+
const visit = (pkg) => {
|
|
406
|
+
color[pkg] = GRAY;
|
|
407
|
+
stack.push(pkg);
|
|
408
|
+
const deps = Object.keys(graph.nodes[pkg]?.dependencies ?? {});
|
|
409
|
+
for (const dep of deps) {
|
|
410
|
+
if (!graph.nodes[dep])
|
|
411
|
+
continue; // Unknown dep will resolve later
|
|
412
|
+
if (color[dep] === GRAY) {
|
|
413
|
+
// Found a back edge: cycle
|
|
414
|
+
const cycleStart = stack.indexOf(dep);
|
|
415
|
+
const cyclePath = [...stack.slice(cycleStart), dep].join(' → ');
|
|
416
|
+
throw new Error(`Cyclic package dependency detected:\n` +
|
|
417
|
+
` ${cyclePath}\n\n` +
|
|
418
|
+
`Hint: Extract shared types into a separate package that both can depend on.`);
|
|
419
|
+
}
|
|
420
|
+
if (color[dep] !== BLACK)
|
|
421
|
+
visit(dep);
|
|
422
|
+
}
|
|
423
|
+
stack.pop();
|
|
424
|
+
color[pkg] = BLACK;
|
|
425
|
+
};
|
|
426
|
+
for (const pkg of Object.keys(graph.nodes)) {
|
|
427
|
+
if (!color[pkg])
|
|
428
|
+
visit(pkg);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Loads an existing lock file from disk.
|
|
433
|
+
*/
|
|
434
|
+
static async loadLockFile(workspaceRoot) {
|
|
435
|
+
const lockPath = path.join(workspaceRoot, 'model.lock');
|
|
436
|
+
try {
|
|
437
|
+
const content = await fs.readFile(lockPath, 'utf-8');
|
|
438
|
+
return JSON.parse(content);
|
|
439
|
+
}
|
|
440
|
+
catch {
|
|
441
|
+
// No lock file
|
|
442
|
+
return undefined;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Parses a lock file from JSON format.
|
|
447
|
+
*/
|
|
448
|
+
static parseLockFile(content) {
|
|
449
|
+
return JSON.parse(content);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
//# sourceMappingURL=dependency-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependency-resolver.js","sourceRoot":"","sources":["../../src/services/dependency-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { GitImportInfo } from './types.js';
|
|
2
|
+
export type { GitImportInfo } from './types.js';
|
|
3
|
+
export declare class GitUrlResolver {
|
|
4
|
+
constructor();
|
|
5
|
+
}
|
|
6
|
+
export declare const GitUrlParser: {
|
|
7
|
+
parse(_importStr: string): GitImportInfo;
|
|
8
|
+
isGitUrl(_importStr: string): boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare function loadLockFile(): void;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Browser stub for GitUrlResolver
|
|
2
|
+
// Git operations are not available in the browser environment
|
|
3
|
+
export class GitUrlResolver {
|
|
4
|
+
constructor() {
|
|
5
|
+
throw new Error('GitUrlResolver is not available in the browser.');
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export const GitUrlParser = {
|
|
9
|
+
parse(_importStr) {
|
|
10
|
+
throw new Error('GitUrlParser is not available in the browser.');
|
|
11
|
+
},
|
|
12
|
+
isGitUrl(_importStr) {
|
|
13
|
+
throw new Error('GitUrlParser is not available in the browser.');
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
export function loadLockFile() {
|
|
17
|
+
throw new Error('loadLockFile is not available in the browser.');
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=git-url-resolver.browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-url-resolver.browser.js","sourceRoot":"","sources":["../../src/services/git-url-resolver.browser.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,8DAA8D;AAO9D,MAAM,OAAO,cAAc;IACvB;QACI,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACvE,CAAC;CACJ;AAED,MAAM,CAAC,MAAM,YAAY,GAAG;IACxB,KAAK,CAAC,UAAkB;QACpB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACrE,CAAC;IACD,QAAQ,CAAC,UAAkB;QACvB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACrE,CAAC;CACJ,CAAC;AAEF,MAAM,UAAU,YAAY;IACxB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,158 @@
|
|
|
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 type { GitImportInfo, LockFile } from './types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Parses import URLs into structured git import information.
|
|
16
|
+
*
|
|
17
|
+
* Supported formats:
|
|
18
|
+
* - owner/repo@version (GitHub assumed)
|
|
19
|
+
* - owner/repo (GitHub, defaults to main)
|
|
20
|
+
* - https://github.com/owner/repo@version
|
|
21
|
+
* - https://gitlab.com/owner/repo@version
|
|
22
|
+
* - https://git.example.com/owner/repo@version
|
|
23
|
+
*/
|
|
24
|
+
export declare class GitUrlParser {
|
|
25
|
+
/**
|
|
26
|
+
* Determines if an import string is a git repository import.
|
|
27
|
+
*/
|
|
28
|
+
static isGitUrl(importStr: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Parses a git import URL into structured components.
|
|
31
|
+
*
|
|
32
|
+
* @param importStr - The import URL string
|
|
33
|
+
* @returns Parsed git import information
|
|
34
|
+
* @throws Error if URL format is invalid
|
|
35
|
+
*/
|
|
36
|
+
static parse(importStr: string): GitImportInfo;
|
|
37
|
+
/**
|
|
38
|
+
* Checks if string is GitHub shorthand format.
|
|
39
|
+
*/
|
|
40
|
+
private static isGitHubShorthand;
|
|
41
|
+
/**
|
|
42
|
+
* Parses GitHub shorthand (owner/repo or owner/repo@version).
|
|
43
|
+
*/
|
|
44
|
+
private static parseGitHubShorthand;
|
|
45
|
+
/**
|
|
46
|
+
* Parses full git URLs (https://...).
|
|
47
|
+
*
|
|
48
|
+
* Supported:
|
|
49
|
+
* - https://github.com/owner/repo@version
|
|
50
|
+
* - https://gitlab.com/owner/repo@version
|
|
51
|
+
* - https://git.example.com/owner/repo@version
|
|
52
|
+
*/
|
|
53
|
+
private static parseFullUrl;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Resolves git repository imports to local entry point files.
|
|
57
|
+
*
|
|
58
|
+
* Implements a content-addressable cache:
|
|
59
|
+
* - Cache location: .dlang/packages/ (project-local, per PRS-010)
|
|
60
|
+
* - Cache key: {owner}/{repo}/{commit-hash}
|
|
61
|
+
* - Downloads entire repository on first use
|
|
62
|
+
* - Reads model.yaml to find entry point
|
|
63
|
+
* - Returns URI to entry point file
|
|
64
|
+
*/
|
|
65
|
+
export declare class GitUrlResolver {
|
|
66
|
+
private cacheDir;
|
|
67
|
+
private lockFile?;
|
|
68
|
+
/**
|
|
69
|
+
* Creates a GitUrlResolver with a project-local cache directory.
|
|
70
|
+
*
|
|
71
|
+
* @param cacheDir - The cache directory path. Per PRS-010, this should be
|
|
72
|
+
* the project's `.dlang/packages/` directory for isolation
|
|
73
|
+
* and reproducibility (like node_modules).
|
|
74
|
+
*/
|
|
75
|
+
constructor(cacheDir: string);
|
|
76
|
+
/**
|
|
77
|
+
* Sets the lock file for dependency resolution.
|
|
78
|
+
*
|
|
79
|
+
* When a lock file is set, all package imports will use
|
|
80
|
+
* the locked commit hashes instead of resolving versions.
|
|
81
|
+
* This ensures reproducible builds and handles transitive dependencies.
|
|
82
|
+
*
|
|
83
|
+
* @param lockFile - The parsed lock file from the workspace root
|
|
84
|
+
*/
|
|
85
|
+
setLockFile(lockFile: LockFile | undefined): void;
|
|
86
|
+
/**
|
|
87
|
+
* Resolves a git import URL to the package's entry point file.
|
|
88
|
+
*
|
|
89
|
+
* Process:
|
|
90
|
+
* 1. Parse git URL
|
|
91
|
+
* 2. Check lock file for pinned version (transitive dependency support)
|
|
92
|
+
* 3. Resolve version to commit hash (if not locked)
|
|
93
|
+
* 4. Check cache
|
|
94
|
+
* 5. Download repository if not cached
|
|
95
|
+
* 6. Read model.yaml to find entry point
|
|
96
|
+
* 7. Return URI to entry point file
|
|
97
|
+
*
|
|
98
|
+
* @param importUrl - The git import URL
|
|
99
|
+
* @returns URI to the package's entry point file
|
|
100
|
+
*/
|
|
101
|
+
resolve(importUrl: string, options?: {
|
|
102
|
+
allowNetwork?: boolean;
|
|
103
|
+
}): Promise<URI>;
|
|
104
|
+
/**
|
|
105
|
+
* Reads model.yaml to get the package entry point.
|
|
106
|
+
* Falls back to index.dlang if no model.yaml found.
|
|
107
|
+
*/
|
|
108
|
+
private getEntryPoint;
|
|
109
|
+
/**
|
|
110
|
+
* Parses model.yaml content to extract entry point.
|
|
111
|
+
*
|
|
112
|
+
* Expected structure:
|
|
113
|
+
* model:
|
|
114
|
+
* entry: index.dlang
|
|
115
|
+
*/
|
|
116
|
+
private parseYaml;
|
|
117
|
+
/**
|
|
118
|
+
* Resolves a version (tag/branch) to a commit hash using git ls-remote.
|
|
119
|
+
*/
|
|
120
|
+
private resolveCommit;
|
|
121
|
+
/**
|
|
122
|
+
* Gets the local cache path for a git repository.
|
|
123
|
+
*
|
|
124
|
+
* Format: .dlang/packages/{owner}/{repo}/{version}/
|
|
125
|
+
*
|
|
126
|
+
* Per PRS-010: Project-local cache structure mirrors the Design Considerations
|
|
127
|
+
* section showing `.dlang/packages/{owner}/{repo}/{version}/` layout.
|
|
128
|
+
*/
|
|
129
|
+
private getCachePath;
|
|
130
|
+
/**
|
|
131
|
+
* Checks if a file or directory exists in the cache.
|
|
132
|
+
*/
|
|
133
|
+
private existsInCache;
|
|
134
|
+
/**
|
|
135
|
+
* Downloads a git repository to the cache.
|
|
136
|
+
*
|
|
137
|
+
* Uses shallow clone for efficiency (only downloads the specific commit).
|
|
138
|
+
*/
|
|
139
|
+
private downloadRepo;
|
|
140
|
+
/**
|
|
141
|
+
* Clears the entire cache.
|
|
142
|
+
*/
|
|
143
|
+
clearCache(): Promise<void>;
|
|
144
|
+
/**
|
|
145
|
+
* Gets cache statistics (size, number of cached repos, etc.).
|
|
146
|
+
*
|
|
147
|
+
* Cache structure: .dlang/packages/{owner}/{repo}/{version}/
|
|
148
|
+
*/
|
|
149
|
+
getCacheStats(): Promise<{
|
|
150
|
+
totalSize: number;
|
|
151
|
+
repoCount: number;
|
|
152
|
+
cacheDir: string;
|
|
153
|
+
}>;
|
|
154
|
+
/**
|
|
155
|
+
* Gets the total size of a directory in bytes.
|
|
156
|
+
*/
|
|
157
|
+
private getDirectorySize;
|
|
158
|
+
}
|