@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,123 @@
|
|
|
1
|
+
import { GitUrlResolver } from './git-url-resolver.js';
|
|
2
|
+
import type { LockFile, ModelManifest, PathAliases, WorkspaceManagerOptions } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Coordinates workspace discovery, lock file lifecycle management, and git resolver configuration.
|
|
5
|
+
*/
|
|
6
|
+
export declare class WorkspaceManager {
|
|
7
|
+
private readonly options;
|
|
8
|
+
private readonly manifestFiles;
|
|
9
|
+
private readonly lockFiles;
|
|
10
|
+
private workspaceRoot;
|
|
11
|
+
private lockFile;
|
|
12
|
+
private gitResolver;
|
|
13
|
+
private dependencyResolver;
|
|
14
|
+
private initializePromise;
|
|
15
|
+
private manifestCache;
|
|
16
|
+
constructor(options?: WorkspaceManagerOptions);
|
|
17
|
+
/**
|
|
18
|
+
* Finds the workspace root, loads any existing lock file, and prepares the git resolver.
|
|
19
|
+
* Repeated calls await the same initialization work.
|
|
20
|
+
*/
|
|
21
|
+
initialize(startPath: string): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Returns the absolute path of the workspace root.
|
|
24
|
+
* @throws Error if {@link initialize} has not completed successfully.
|
|
25
|
+
*/
|
|
26
|
+
getWorkspaceRoot(): string;
|
|
27
|
+
/**
|
|
28
|
+
* Resolves the manifest file path within the workspace, if present.
|
|
29
|
+
*/
|
|
30
|
+
getManifestPath(): Promise<string | undefined>;
|
|
31
|
+
/**
|
|
32
|
+
* Returns the parsed manifest when present, otherwise undefined.
|
|
33
|
+
* Uses cached contents when unchanged on disk.
|
|
34
|
+
*/
|
|
35
|
+
getManifest(): Promise<ModelManifest | undefined>;
|
|
36
|
+
/**
|
|
37
|
+
* Returns the cached lock file or triggers resolution when missing.
|
|
38
|
+
*/
|
|
39
|
+
ensureLockFile(): Promise<LockFile>;
|
|
40
|
+
/**
|
|
41
|
+
* Gets the currently cached lock file without refreshing from disk.
|
|
42
|
+
*/
|
|
43
|
+
getLockFile(): Promise<LockFile | undefined>;
|
|
44
|
+
/**
|
|
45
|
+
* Reloads the lock file from disk, updating the git resolver.
|
|
46
|
+
*/
|
|
47
|
+
refreshLockFile(): Promise<LockFile | undefined>;
|
|
48
|
+
/**
|
|
49
|
+
* Invalidates all cached data (manifest and lock file).
|
|
50
|
+
* Call this when config files change externally (e.g., from CLI commands).
|
|
51
|
+
*
|
|
52
|
+
* After invalidation, the next call to getManifest() or getLockFile()
|
|
53
|
+
* will re-read from disk.
|
|
54
|
+
*/
|
|
55
|
+
invalidateCache(): void;
|
|
56
|
+
/**
|
|
57
|
+
* Invalidates only the manifest cache.
|
|
58
|
+
* Call this when model.yaml changes.
|
|
59
|
+
*/
|
|
60
|
+
invalidateManifestCache(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Invalidates only the lock file cache.
|
|
63
|
+
* Call this when model.lock changes.
|
|
64
|
+
*/
|
|
65
|
+
invalidateLockCache(): void;
|
|
66
|
+
/**
|
|
67
|
+
* Provides the shared git URL resolver configured with the current lock file.
|
|
68
|
+
*/
|
|
69
|
+
getGitResolver(): Promise<GitUrlResolver>;
|
|
70
|
+
/**
|
|
71
|
+
* Forces dependency resolution and regenerates lock files on disk.
|
|
72
|
+
*/
|
|
73
|
+
regenerateLockFile(): Promise<LockFile>;
|
|
74
|
+
/**
|
|
75
|
+
* Returns the path aliases from the manifest, if present.
|
|
76
|
+
*/
|
|
77
|
+
getPathAliases(): Promise<PathAliases | undefined>;
|
|
78
|
+
/**
|
|
79
|
+
* Normalizes a dependency entry to its extended form.
|
|
80
|
+
* Handles both short form (string version) and extended form (object).
|
|
81
|
+
*
|
|
82
|
+
* In the new format, the key IS the owner/package, so source is derived from key
|
|
83
|
+
* ONLY for git dependencies (not for path-based local dependencies).
|
|
84
|
+
*/
|
|
85
|
+
private normalizeDependency;
|
|
86
|
+
/**
|
|
87
|
+
* Resolves a manifest dependency to its git import string.
|
|
88
|
+
*
|
|
89
|
+
* NEW FORMAT (PRS-010): Dependencies are keyed by owner/package directly
|
|
90
|
+
* @param specifier - Import specifier (owner/package format, may include subpaths)
|
|
91
|
+
* @returns Resolved git import string or undefined when not found
|
|
92
|
+
*/
|
|
93
|
+
resolveDependencyImport(specifier: string): Promise<string | undefined>;
|
|
94
|
+
private performInitialization;
|
|
95
|
+
private ensureInitialized;
|
|
96
|
+
private applyLockFile;
|
|
97
|
+
private generateLockFile;
|
|
98
|
+
private ensureDependencyResolver;
|
|
99
|
+
private writeJsonLockFile;
|
|
100
|
+
private loadLockFileFromDisk;
|
|
101
|
+
private tryReadLockFile;
|
|
102
|
+
private loadManifest;
|
|
103
|
+
/**
|
|
104
|
+
* Validates manifest structure and dependency configurations.
|
|
105
|
+
* Throws detailed errors for invalid manifests.
|
|
106
|
+
*
|
|
107
|
+
* Supports both new format (owner/package: version) and extended format.
|
|
108
|
+
*/
|
|
109
|
+
private validateManifest;
|
|
110
|
+
/**
|
|
111
|
+
* Validates path aliases for security and correctness.
|
|
112
|
+
*/
|
|
113
|
+
private validatePathAliases;
|
|
114
|
+
/**
|
|
115
|
+
* Validates local path dependencies for security.
|
|
116
|
+
* Ensures paths don't escape workspace boundary.
|
|
117
|
+
*/
|
|
118
|
+
private validateLocalPath;
|
|
119
|
+
private parseJsonLockFile;
|
|
120
|
+
private findWorkspaceRoot;
|
|
121
|
+
private containsManifest;
|
|
122
|
+
private fileExists;
|
|
123
|
+
}
|
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import YAML from 'yaml';
|
|
4
|
+
import { DependencyResolver } from './dependency-resolver.js';
|
|
5
|
+
import { GitUrlResolver } from './git-url-resolver.js';
|
|
6
|
+
import { getGlobalOptimizer } from './performance-optimizer.js';
|
|
7
|
+
const DEFAULT_MANIFEST_FILES = [
|
|
8
|
+
'model.yaml'
|
|
9
|
+
];
|
|
10
|
+
const DEFAULT_LOCK_FILES = [
|
|
11
|
+
'model.lock'
|
|
12
|
+
];
|
|
13
|
+
const JSON_SPACE = 2;
|
|
14
|
+
/**
|
|
15
|
+
* Coordinates workspace discovery, lock file lifecycle management, and git resolver configuration.
|
|
16
|
+
*/
|
|
17
|
+
export class WorkspaceManager {
|
|
18
|
+
constructor(options = {}) {
|
|
19
|
+
this.options = options;
|
|
20
|
+
this.manifestFiles = options.manifestFiles ?? [...DEFAULT_MANIFEST_FILES];
|
|
21
|
+
this.lockFiles = options.lockFiles ?? [...DEFAULT_LOCK_FILES];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Finds the workspace root, loads any existing lock file, and prepares the git resolver.
|
|
25
|
+
* Repeated calls await the same initialization work.
|
|
26
|
+
*/
|
|
27
|
+
async initialize(startPath) {
|
|
28
|
+
if (!this.initializePromise) {
|
|
29
|
+
this.initializePromise = this.performInitialization(startPath);
|
|
30
|
+
}
|
|
31
|
+
await this.initializePromise;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Returns the absolute path of the workspace root.
|
|
35
|
+
* @throws Error if {@link initialize} has not completed successfully.
|
|
36
|
+
*/
|
|
37
|
+
getWorkspaceRoot() {
|
|
38
|
+
if (!this.workspaceRoot) {
|
|
39
|
+
throw new Error('WorkspaceManager not initialized. Call initialize() first.');
|
|
40
|
+
}
|
|
41
|
+
return this.workspaceRoot;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolves the manifest file path within the workspace, if present.
|
|
45
|
+
*/
|
|
46
|
+
async getManifestPath() {
|
|
47
|
+
await this.ensureInitialized();
|
|
48
|
+
const root = this.workspaceRoot;
|
|
49
|
+
if (!root) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
for (const manifest of this.manifestFiles) {
|
|
53
|
+
const candidate = path.join(root, manifest);
|
|
54
|
+
if (await this.fileExists(candidate)) {
|
|
55
|
+
return candidate;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Returns the parsed manifest when present, otherwise undefined.
|
|
62
|
+
* Uses cached contents when unchanged on disk.
|
|
63
|
+
*/
|
|
64
|
+
async getManifest() {
|
|
65
|
+
await this.ensureInitialized();
|
|
66
|
+
return this.loadManifest();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Returns the cached lock file or triggers resolution when missing.
|
|
70
|
+
*/
|
|
71
|
+
async ensureLockFile() {
|
|
72
|
+
await this.ensureInitialized();
|
|
73
|
+
if (!this.lockFile) {
|
|
74
|
+
// Try loading from cache first
|
|
75
|
+
const optimizer = getGlobalOptimizer();
|
|
76
|
+
const cached = await optimizer.getCachedLockFile(this.workspaceRoot || '');
|
|
77
|
+
if (cached) {
|
|
78
|
+
this.lockFile = cached;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
if (this.options.allowNetwork === false) {
|
|
82
|
+
throw new Error('Lock file (model.lock) not found and network access is disabled.\n' +
|
|
83
|
+
'Hint: Run \'dlang install\' to generate the lock file.');
|
|
84
|
+
}
|
|
85
|
+
await this.generateLockFile();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (!this.lockFile) {
|
|
89
|
+
throw new Error('Unable to resolve workspace lock file.\n' +
|
|
90
|
+
'Hint: Ensure model.yaml exists and run \'dlang install\' to generate model.lock.');
|
|
91
|
+
}
|
|
92
|
+
return this.lockFile;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Gets the currently cached lock file without refreshing from disk.
|
|
96
|
+
*/
|
|
97
|
+
async getLockFile() {
|
|
98
|
+
await this.ensureInitialized();
|
|
99
|
+
return this.lockFile;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Reloads the lock file from disk, updating the git resolver.
|
|
103
|
+
*/
|
|
104
|
+
async refreshLockFile() {
|
|
105
|
+
await this.ensureInitialized();
|
|
106
|
+
const loaded = await this.loadLockFileFromDisk();
|
|
107
|
+
this.applyLockFile(loaded);
|
|
108
|
+
return this.lockFile;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Invalidates all cached data (manifest and lock file).
|
|
112
|
+
* Call this when config files change externally (e.g., from CLI commands).
|
|
113
|
+
*
|
|
114
|
+
* After invalidation, the next call to getManifest() or getLockFile()
|
|
115
|
+
* will re-read from disk.
|
|
116
|
+
*/
|
|
117
|
+
invalidateCache() {
|
|
118
|
+
this.manifestCache = undefined;
|
|
119
|
+
this.lockFile = undefined;
|
|
120
|
+
// Re-apply undefined to git resolver to clear its lock file
|
|
121
|
+
if (this.gitResolver) {
|
|
122
|
+
this.gitResolver.setLockFile(undefined);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Invalidates only the manifest cache.
|
|
127
|
+
* Call this when model.yaml changes.
|
|
128
|
+
*/
|
|
129
|
+
invalidateManifestCache() {
|
|
130
|
+
this.manifestCache = undefined;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Invalidates only the lock file cache.
|
|
134
|
+
* Call this when model.lock changes.
|
|
135
|
+
*/
|
|
136
|
+
invalidateLockCache() {
|
|
137
|
+
this.lockFile = undefined;
|
|
138
|
+
if (this.gitResolver) {
|
|
139
|
+
this.gitResolver.setLockFile(undefined);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Provides the shared git URL resolver configured with the current lock file.
|
|
144
|
+
*/
|
|
145
|
+
async getGitResolver() {
|
|
146
|
+
await this.ensureInitialized();
|
|
147
|
+
if (!this.gitResolver) {
|
|
148
|
+
throw new Error('GitUrlResolver not available. Workspace initialization failed.');
|
|
149
|
+
}
|
|
150
|
+
return this.gitResolver;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Forces dependency resolution and regenerates lock files on disk.
|
|
154
|
+
*/
|
|
155
|
+
async regenerateLockFile() {
|
|
156
|
+
await this.ensureInitialized();
|
|
157
|
+
await this.generateLockFile(true);
|
|
158
|
+
if (!this.lockFile) {
|
|
159
|
+
throw new Error('Failed to regenerate workspace lock file.');
|
|
160
|
+
}
|
|
161
|
+
return this.lockFile;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Returns the path aliases from the manifest, if present.
|
|
165
|
+
*/
|
|
166
|
+
async getPathAliases() {
|
|
167
|
+
const manifest = await this.getManifest();
|
|
168
|
+
return manifest?.paths;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Normalizes a dependency entry to its extended form.
|
|
172
|
+
* Handles both short form (string version) and extended form (object).
|
|
173
|
+
*
|
|
174
|
+
* In the new format, the key IS the owner/package, so source is derived from key
|
|
175
|
+
* ONLY for git dependencies (not for path-based local dependencies).
|
|
176
|
+
*/
|
|
177
|
+
normalizeDependency(key, dep) {
|
|
178
|
+
if (typeof dep === 'string') {
|
|
179
|
+
// Short form: "owner/package": "v1.0.0" or "main"
|
|
180
|
+
// Key is the source (owner/package format)
|
|
181
|
+
return { source: key, ref: dep };
|
|
182
|
+
}
|
|
183
|
+
// Extended form:
|
|
184
|
+
// - If has source: use as-is
|
|
185
|
+
// - If has path: it's a local dep, don't set source
|
|
186
|
+
// - If neither: derive source from key (owner/package becomes source)
|
|
187
|
+
if (dep.source || dep.path) {
|
|
188
|
+
return dep;
|
|
189
|
+
}
|
|
190
|
+
return { ...dep, source: key };
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Resolves a manifest dependency to its git import string.
|
|
194
|
+
*
|
|
195
|
+
* NEW FORMAT (PRS-010): Dependencies are keyed by owner/package directly
|
|
196
|
+
* @param specifier - Import specifier (owner/package format, may include subpaths)
|
|
197
|
+
* @returns Resolved git import string or undefined when not found
|
|
198
|
+
*/
|
|
199
|
+
async resolveDependencyImport(specifier) {
|
|
200
|
+
await this.ensureInitialized();
|
|
201
|
+
const manifest = await this.loadManifest();
|
|
202
|
+
const dependencies = manifest?.dependencies;
|
|
203
|
+
if (!dependencies) {
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
// NEW: Dependencies are keyed by owner/package (e.g., "domainlang/core")
|
|
207
|
+
// Import specifier is also owner/package, potentially with subpath
|
|
208
|
+
for (const [key, dep] of Object.entries(dependencies)) {
|
|
209
|
+
const normalized = this.normalizeDependency(key, dep);
|
|
210
|
+
// Skip path-based dependencies (handled by path aliases)
|
|
211
|
+
if (normalized.path) {
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (!normalized.source) {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
// Match if specifier equals key or starts with key/
|
|
218
|
+
if (specifier === key || specifier.startsWith(`${key}/`)) {
|
|
219
|
+
const suffix = specifier.slice(key.length);
|
|
220
|
+
const ref = normalized.ref ?? '';
|
|
221
|
+
const refSegment = ref
|
|
222
|
+
? (ref.startsWith('@') ? ref : `@${ref}`)
|
|
223
|
+
: '';
|
|
224
|
+
return `${normalized.source}${refSegment}${suffix}`;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return undefined;
|
|
228
|
+
}
|
|
229
|
+
async performInitialization(startPath) {
|
|
230
|
+
this.workspaceRoot = await this.findWorkspaceRoot(startPath) ?? path.resolve(startPath);
|
|
231
|
+
// Per PRS-010: Project-local cache at .dlang/packages/ (like node_modules)
|
|
232
|
+
const cacheDir = path.join(this.workspaceRoot, '.dlang', 'packages');
|
|
233
|
+
this.gitResolver = new GitUrlResolver(cacheDir);
|
|
234
|
+
const loaded = await this.loadLockFileFromDisk();
|
|
235
|
+
this.applyLockFile(loaded);
|
|
236
|
+
if (!this.lockFile && this.options.autoResolve !== false && this.options.allowNetwork !== false) {
|
|
237
|
+
await this.generateLockFile();
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
async ensureInitialized() {
|
|
241
|
+
if (this.initializePromise) {
|
|
242
|
+
await this.initializePromise;
|
|
243
|
+
}
|
|
244
|
+
else if (!this.workspaceRoot) {
|
|
245
|
+
throw new Error('WorkspaceManager not initialized. Call initialize() first.');
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
applyLockFile(loaded) {
|
|
249
|
+
if (!this.gitResolver) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (loaded) {
|
|
253
|
+
this.lockFile = loaded.lockFile;
|
|
254
|
+
this.gitResolver.setLockFile(this.lockFile);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
this.lockFile = undefined;
|
|
258
|
+
this.gitResolver.setLockFile(undefined);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
async generateLockFile(force = false) {
|
|
262
|
+
if (!this.workspaceRoot || !this.gitResolver) {
|
|
263
|
+
throw new Error('WorkspaceManager not initialized.');
|
|
264
|
+
}
|
|
265
|
+
const resolver = this.ensureDependencyResolver();
|
|
266
|
+
if (!force && this.lockFile) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
const lockFile = await resolver.resolveDependencies();
|
|
270
|
+
this.lockFile = lockFile;
|
|
271
|
+
this.gitResolver.setLockFile(lockFile);
|
|
272
|
+
// Write JSON lock file
|
|
273
|
+
await this.writeJsonLockFile(lockFile);
|
|
274
|
+
}
|
|
275
|
+
ensureDependencyResolver() {
|
|
276
|
+
if (!this.workspaceRoot || !this.gitResolver) {
|
|
277
|
+
throw new Error('WorkspaceManager not initialized.');
|
|
278
|
+
}
|
|
279
|
+
if (!this.dependencyResolver) {
|
|
280
|
+
this.dependencyResolver = new DependencyResolver(this.workspaceRoot, this.gitResolver);
|
|
281
|
+
}
|
|
282
|
+
return this.dependencyResolver;
|
|
283
|
+
}
|
|
284
|
+
async writeJsonLockFile(lockFile) {
|
|
285
|
+
if (!this.workspaceRoot) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
const jsonPath = path.join(this.workspaceRoot, 'model.lock');
|
|
289
|
+
const payload = {
|
|
290
|
+
version: lockFile.version,
|
|
291
|
+
dependencies: lockFile.dependencies,
|
|
292
|
+
};
|
|
293
|
+
await fs.writeFile(jsonPath, JSON.stringify(payload, undefined, JSON_SPACE), 'utf-8');
|
|
294
|
+
}
|
|
295
|
+
async loadLockFileFromDisk() {
|
|
296
|
+
if (!this.workspaceRoot) {
|
|
297
|
+
return undefined;
|
|
298
|
+
}
|
|
299
|
+
for (const filename of this.lockFiles) {
|
|
300
|
+
const filePath = path.join(this.workspaceRoot, filename);
|
|
301
|
+
const lockFile = await this.tryReadLockFile(filePath, filename);
|
|
302
|
+
if (lockFile) {
|
|
303
|
+
return { lockFile, filePath };
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return undefined;
|
|
307
|
+
}
|
|
308
|
+
async tryReadLockFile(filePath, _filename) {
|
|
309
|
+
try {
|
|
310
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
311
|
+
return this.parseJsonLockFile(content);
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
if (error?.code === 'ENOENT') {
|
|
315
|
+
return undefined;
|
|
316
|
+
}
|
|
317
|
+
throw error;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
async loadManifest() {
|
|
321
|
+
const manifestPath = await this.getManifestPath();
|
|
322
|
+
if (!manifestPath) {
|
|
323
|
+
this.manifestCache = undefined;
|
|
324
|
+
return undefined;
|
|
325
|
+
}
|
|
326
|
+
try {
|
|
327
|
+
const stat = await fs.stat(manifestPath);
|
|
328
|
+
if (this.manifestCache &&
|
|
329
|
+
this.manifestCache.path === manifestPath &&
|
|
330
|
+
this.manifestCache.mtimeMs === stat.mtimeMs) {
|
|
331
|
+
return this.manifestCache.manifest;
|
|
332
|
+
}
|
|
333
|
+
const content = await fs.readFile(manifestPath, 'utf-8');
|
|
334
|
+
const manifest = (YAML.parse(content) ?? {});
|
|
335
|
+
// Validate manifest structure
|
|
336
|
+
this.validateManifest(manifest, manifestPath);
|
|
337
|
+
this.manifestCache = {
|
|
338
|
+
manifest,
|
|
339
|
+
path: manifestPath,
|
|
340
|
+
mtimeMs: stat.mtimeMs,
|
|
341
|
+
};
|
|
342
|
+
return manifest;
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
if (error?.code === 'ENOENT') {
|
|
346
|
+
this.manifestCache = undefined;
|
|
347
|
+
return undefined;
|
|
348
|
+
}
|
|
349
|
+
throw error;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Validates manifest structure and dependency configurations.
|
|
354
|
+
* Throws detailed errors for invalid manifests.
|
|
355
|
+
*
|
|
356
|
+
* Supports both new format (owner/package: version) and extended format.
|
|
357
|
+
*/
|
|
358
|
+
validateManifest(manifest, manifestPath) {
|
|
359
|
+
// Validate path aliases
|
|
360
|
+
if (manifest.paths) {
|
|
361
|
+
this.validatePathAliases(manifest.paths, manifestPath);
|
|
362
|
+
}
|
|
363
|
+
if (!manifest.dependencies) {
|
|
364
|
+
return; // No dependencies to validate
|
|
365
|
+
}
|
|
366
|
+
for (const [key, dep] of Object.entries(manifest.dependencies)) {
|
|
367
|
+
const normalized = this.normalizeDependency(key, dep);
|
|
368
|
+
// Validate mutually exclusive source and path
|
|
369
|
+
if (normalized.source && normalized.path) {
|
|
370
|
+
throw new Error(`Invalid dependency '${key}' in ${manifestPath}:\n` +
|
|
371
|
+
`Cannot specify both 'source' and 'path'.\n` +
|
|
372
|
+
`Hint: Use 'source' for git dependencies or 'path' for local workspace dependencies.`);
|
|
373
|
+
}
|
|
374
|
+
// For string format, source is always derived from key (valid)
|
|
375
|
+
// For extended format without source or path, error
|
|
376
|
+
if (typeof dep !== 'string' && !normalized.source && !normalized.path) {
|
|
377
|
+
throw new Error(`Invalid dependency '${key}' in ${manifestPath}:\n` +
|
|
378
|
+
`Must specify either 'source' or 'path'.\n` +
|
|
379
|
+
`Hint: Add 'source: owner/repo' for git dependencies, or 'path: ./local/path' for local packages.`);
|
|
380
|
+
}
|
|
381
|
+
// Validate path is relative and within workspace
|
|
382
|
+
if (normalized.path) {
|
|
383
|
+
this.validateLocalPath(normalized.path, key, manifestPath);
|
|
384
|
+
}
|
|
385
|
+
// Validate source has ref when specified
|
|
386
|
+
if (normalized.source && !normalized.ref) {
|
|
387
|
+
throw new Error(`Invalid dependency '${key}' in ${manifestPath}:\n` +
|
|
388
|
+
`Git dependencies must specify a 'ref' (git reference).\n` +
|
|
389
|
+
`Hint: Add 'ref: v1.0.0' (tag), 'ref: main' (branch), or a commit SHA.`);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Validates path aliases for security and correctness.
|
|
395
|
+
*/
|
|
396
|
+
validatePathAliases(paths, manifestPath) {
|
|
397
|
+
for (const [alias, targetPath] of Object.entries(paths)) {
|
|
398
|
+
// Validate alias starts with @
|
|
399
|
+
if (!alias.startsWith('@')) {
|
|
400
|
+
throw new Error(`Invalid path alias '${alias}' in ${manifestPath}:\n` +
|
|
401
|
+
`Path aliases must start with '@'.\n` +
|
|
402
|
+
`Hint: Rename to '@${alias}' in your model.yaml paths section.`);
|
|
403
|
+
}
|
|
404
|
+
// Validate target path doesn't escape workspace
|
|
405
|
+
this.validateLocalPath(targetPath, alias, manifestPath);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Validates local path dependencies for security.
|
|
410
|
+
* Ensures paths don't escape workspace boundary.
|
|
411
|
+
*/
|
|
412
|
+
validateLocalPath(localPath, alias, manifestPath) {
|
|
413
|
+
// Reject absolute paths
|
|
414
|
+
if (path.isAbsolute(localPath)) {
|
|
415
|
+
throw new Error(`Invalid local path '${alias}' in ${manifestPath}:\n` +
|
|
416
|
+
`Cannot use absolute path '${localPath}'.\n` +
|
|
417
|
+
`Hint: Use relative paths (e.g., './lib', '../shared') for local dependencies.`);
|
|
418
|
+
}
|
|
419
|
+
// Resolve path relative to manifest directory
|
|
420
|
+
const manifestDir = path.dirname(manifestPath);
|
|
421
|
+
const resolvedPath = path.resolve(manifestDir, localPath);
|
|
422
|
+
const workspaceRoot = this.workspaceRoot || manifestDir;
|
|
423
|
+
// Check if resolved path is within workspace
|
|
424
|
+
const relativePath = path.relative(workspaceRoot, resolvedPath);
|
|
425
|
+
if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) {
|
|
426
|
+
throw new Error(`Invalid local path '${alias}' in ${manifestPath}:\n` +
|
|
427
|
+
`Path '${localPath}' resolves outside workspace boundary.\n` +
|
|
428
|
+
`Resolved: ${resolvedPath}\n` +
|
|
429
|
+
`Workspace: ${workspaceRoot}\n` +
|
|
430
|
+
`Hint: Local dependencies must be within the workspace. Consider moving the dependency or using a git-based source.`);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
parseJsonLockFile(content) {
|
|
434
|
+
const parsed = JSON.parse(content);
|
|
435
|
+
const version = typeof parsed.version === 'string' ? parsed.version : '1';
|
|
436
|
+
const dependencies = {};
|
|
437
|
+
for (const [key, value] of Object.entries(parsed.dependencies ?? {})) {
|
|
438
|
+
if (!value || typeof value.ref !== 'string' || typeof value.resolved !== 'string' || typeof value.commit !== 'string') {
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
dependencies[key] = {
|
|
442
|
+
ref: value.ref,
|
|
443
|
+
refType: value.refType ?? 'commit', // Default to commit for backwards compatibility
|
|
444
|
+
resolved: value.resolved,
|
|
445
|
+
commit: value.commit,
|
|
446
|
+
integrity: value.integrity,
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
return { version, dependencies };
|
|
450
|
+
}
|
|
451
|
+
async findWorkspaceRoot(startPath) {
|
|
452
|
+
let current = path.resolve(startPath);
|
|
453
|
+
const { root } = path.parse(current);
|
|
454
|
+
while (true) {
|
|
455
|
+
if (await this.containsManifest(current)) {
|
|
456
|
+
return current;
|
|
457
|
+
}
|
|
458
|
+
if (current === root) {
|
|
459
|
+
return undefined;
|
|
460
|
+
}
|
|
461
|
+
const parent = path.dirname(current);
|
|
462
|
+
if (parent === current) {
|
|
463
|
+
return undefined;
|
|
464
|
+
}
|
|
465
|
+
current = parent;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
async containsManifest(dir) {
|
|
469
|
+
for (const manifest of this.manifestFiles) {
|
|
470
|
+
if (await this.fileExists(path.join(dir, manifest))) {
|
|
471
|
+
return true;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return false;
|
|
475
|
+
}
|
|
476
|
+
async fileExists(targetPath) {
|
|
477
|
+
try {
|
|
478
|
+
await fs.access(targetPath);
|
|
479
|
+
return true;
|
|
480
|
+
}
|
|
481
|
+
catch (error) {
|
|
482
|
+
if (error?.code === 'ENOENT') {
|
|
483
|
+
return false;
|
|
484
|
+
}
|
|
485
|
+
throw error;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
//# sourceMappingURL=workspace-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-manager.js","sourceRoot":"","sources":["../../src/services/workspace-manager.ts"],"names":[],"mappings":"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"}
|