@domainlang/language 0.1.82 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -18
- package/out/domain-lang-module.d.ts +2 -0
- package/out/domain-lang-module.js +11 -3
- package/out/domain-lang-module.js.map +1 -1
- package/out/generated/ast.d.ts +8 -19
- package/out/generated/ast.js +1 -10
- package/out/generated/ast.js.map +1 -1
- package/out/generated/grammar.d.ts +1 -1
- package/out/generated/grammar.js +28 -123
- package/out/generated/grammar.js.map +1 -1
- package/out/generated/module.d.ts +1 -1
- package/out/generated/module.js +1 -1
- package/out/index.d.ts +3 -0
- package/out/index.js +5 -0
- package/out/index.js.map +1 -1
- 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-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/domain-lang-hover.js +0 -4
- package/out/lsp/hover/domain-lang-hover.js.map +1 -1
- 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/sdk/index.d.ts +1 -1
- package/out/sdk/loader-node.d.ts +7 -3
- package/out/sdk/loader-node.js +24 -9
- package/out/sdk/loader-node.js.map +1 -1
- package/out/sdk/types.d.ts +0 -21
- package/out/services/dependency-analyzer.d.ts +3 -39
- package/out/services/dependency-analyzer.js +22 -47
- package/out/services/dependency-analyzer.js.map +1 -1
- package/out/services/dependency-resolver.d.ts +68 -45
- package/out/services/dependency-resolver.js +243 -43
- package/out/services/dependency-resolver.js.map +1 -1
- package/out/services/git-url-resolver.browser.d.ts +4 -12
- package/out/services/git-url-resolver.browser.js +5 -1
- package/out/services/git-url-resolver.browser.js.map +1 -1
- package/out/services/git-url-resolver.d.ts +22 -56
- package/out/services/git-url-resolver.js +70 -36
- package/out/services/git-url-resolver.js.map +1 -1
- package/out/services/governance-validator.d.ts +1 -37
- package/out/services/governance-validator.js +4 -10
- package/out/services/governance-validator.js.map +1 -1
- package/out/services/import-resolver.d.ts +65 -6
- package/out/services/import-resolver.js +223 -5
- package/out/services/import-resolver.js.map +1 -1
- package/out/services/performance-optimizer.d.ts +1 -1
- 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 +57 -10
- package/out/services/workspace-manager.js +187 -21
- package/out/services/workspace-manager.js.map +1 -1
- package/out/syntaxes/domain-lang.monarch.js +1 -1
- package/out/syntaxes/domain-lang.monarch.js.map +1 -1
- package/out/utils/import-utils.d.ts +4 -12
- package/out/utils/import-utils.js +35 -135
- package/out/utils/import-utils.js.map +1 -1
- package/out/validation/constants.d.ts +103 -0
- package/out/validation/constants.js +141 -2
- package/out/validation/constants.js.map +1 -1
- package/out/validation/domain.js +46 -1
- package/out/validation/domain.js.map +1 -1
- package/out/validation/import.d.ts +46 -22
- package/out/validation/import.js +187 -85
- package/out/validation/import.js.map +1 -1
- 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.js +10 -6
- package/out/validation/maps.js.map +1 -1
- package/out/validation/metadata.js +5 -1
- package/out/validation/metadata.js.map +1 -1
- package/package.json +8 -6
- package/src/domain-lang-module.ts +18 -6
- package/src/domain-lang.langium +7 -12
- package/src/generated/ast.ts +7 -20
- package/src/generated/grammar.ts +28 -123
- package/src/generated/module.ts +1 -1
- package/src/index.ts +7 -0
- package/src/lsp/domain-lang-code-actions.ts +189 -0
- package/src/lsp/domain-lang-workspace-manager.ts +104 -0
- package/src/lsp/hover/domain-lang-hover.ts +0 -2
- package/src/lsp/manifest-diagnostics.ts +290 -0
- package/src/sdk/index.ts +0 -2
- package/src/sdk/loader-node.ts +29 -9
- package/src/sdk/types.ts +0 -23
- package/src/services/dependency-analyzer.ts +24 -84
- package/src/services/dependency-resolver.ts +301 -84
- package/src/services/git-url-resolver.browser.ts +9 -14
- package/src/services/git-url-resolver.ts +86 -93
- package/src/services/governance-validator.ts +5 -47
- package/src/services/import-resolver.ts +270 -8
- package/src/services/performance-optimizer.ts +1 -1
- package/src/services/semver.ts +213 -0
- package/src/services/types.ts +415 -0
- package/src/services/workspace-manager.ts +237 -46
- package/src/syntaxes/domain-lang.monarch.ts +1 -1
- package/src/utils/import-utils.ts +38 -160
- package/src/validation/constants.ts +182 -2
- package/src/validation/domain.ts +54 -1
- package/src/validation/import.ts +228 -104
- package/src/validation/manifest.ts +439 -0
- package/src/validation/maps.ts +10 -6
- package/src/validation/metadata.ts +5 -1
package/out/validation/import.js
CHANGED
|
@@ -1,134 +1,236 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { ValidationMessages, buildCodeDescription, IssueCodes } from './constants.js';
|
|
2
4
|
/**
|
|
3
5
|
* Validates import statements in DomainLang.
|
|
4
6
|
*
|
|
7
|
+
* Uses async validators (Langium 4.x supports MaybePromise<void>) to leverage
|
|
8
|
+
* the shared WorkspaceManager service with its cached manifest/lock file reading.
|
|
9
|
+
*
|
|
5
10
|
* Checks:
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
8
|
-
* -
|
|
11
|
+
* - External imports require manifest + alias
|
|
12
|
+
* - Local path dependencies stay inside workspace
|
|
13
|
+
* - Lock file exists for external dependencies
|
|
9
14
|
*/
|
|
10
15
|
export class ImportValidator {
|
|
11
16
|
constructor(services) {
|
|
12
|
-
this.
|
|
17
|
+
this.workspaceManager = services.imports.WorkspaceManager;
|
|
13
18
|
}
|
|
14
19
|
/**
|
|
15
|
-
* Validates
|
|
20
|
+
* Validates an import statement asynchronously.
|
|
21
|
+
*
|
|
22
|
+
* Langium validators can return MaybePromise<void>, enabling async operations
|
|
23
|
+
* like reading manifests via the shared, cached WorkspaceManager.
|
|
16
24
|
*/
|
|
17
|
-
async checkImportPath(imp, accept, document) {
|
|
25
|
+
async checkImportPath(imp, accept, document, _cancelToken) {
|
|
18
26
|
if (!imp.uri) {
|
|
19
|
-
accept('error',
|
|
27
|
+
accept('error', ValidationMessages.IMPORT_MISSING_URI(), {
|
|
20
28
|
node: imp,
|
|
21
|
-
keyword: 'import'
|
|
29
|
+
keyword: 'import',
|
|
30
|
+
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
31
|
+
data: { code: IssueCodes.ImportMissingUri }
|
|
22
32
|
});
|
|
23
33
|
return;
|
|
24
34
|
}
|
|
25
|
-
|
|
26
|
-
|
|
35
|
+
if (!this.isExternalImport(imp.uri)) {
|
|
36
|
+
return;
|
|
27
37
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
38
|
+
// Initialize workspace manager from document location
|
|
39
|
+
const docDir = path.dirname(document.uri.fsPath);
|
|
40
|
+
await this.workspaceManager.initialize(docDir);
|
|
41
|
+
const manifest = await this.workspaceManager.getManifest();
|
|
42
|
+
if (!manifest) {
|
|
43
|
+
accept('error', ValidationMessages.IMPORT_REQUIRES_MANIFEST(imp.uri), {
|
|
31
44
|
node: imp,
|
|
32
|
-
property: 'uri'
|
|
45
|
+
property: 'uri',
|
|
46
|
+
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
47
|
+
data: { code: IssueCodes.ImportRequiresManifest, specifier: imp.uri }
|
|
33
48
|
});
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Validates that named imports exist in the target document.
|
|
38
|
-
*/
|
|
39
|
-
async checkNamedImports(imp, accept, document) {
|
|
40
|
-
// Only check if we have named imports
|
|
41
|
-
if (!imp.symbols || imp.symbols.length === 0) {
|
|
42
49
|
return;
|
|
43
50
|
}
|
|
44
|
-
|
|
45
|
-
|
|
51
|
+
const alias = imp.uri.split('/')[0];
|
|
52
|
+
const dependency = this.getDependency(manifest, alias);
|
|
53
|
+
if (!dependency) {
|
|
54
|
+
accept('error', ValidationMessages.IMPORT_NOT_IN_MANIFEST(alias), {
|
|
55
|
+
node: imp,
|
|
56
|
+
property: 'uri',
|
|
57
|
+
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
58
|
+
data: { code: IssueCodes.ImportNotInManifest, alias }
|
|
59
|
+
});
|
|
60
|
+
return;
|
|
46
61
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
if (!
|
|
52
|
-
accept('error',
|
|
62
|
+
this.validateDependencyConfig(dependency, alias, accept, imp);
|
|
63
|
+
// External source dependencies require lock file and cached packages
|
|
64
|
+
if (dependency.source) {
|
|
65
|
+
const lockFile = await this.workspaceManager.getLockFile();
|
|
66
|
+
if (!lockFile) {
|
|
67
|
+
accept('error', ValidationMessages.IMPORT_NOT_INSTALLED(alias), {
|
|
53
68
|
node: imp,
|
|
54
|
-
property: 'uri'
|
|
69
|
+
property: 'uri',
|
|
70
|
+
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
71
|
+
data: { code: IssueCodes.ImportNotInstalled, alias }
|
|
55
72
|
});
|
|
56
73
|
return;
|
|
57
74
|
}
|
|
58
|
-
|
|
59
|
-
const targetModel = targetDoc.parseResult.value;
|
|
60
|
-
const exportedSymbols = this.getExportedSymbols(targetModel);
|
|
61
|
-
// Check each imported symbol
|
|
62
|
-
for (const symbol of imp.symbols) {
|
|
63
|
-
if (!exportedSymbols.has(symbol)) {
|
|
64
|
-
accept('error', `Symbol '${symbol}' not found in ${imp.uri}`, {
|
|
65
|
-
node: imp,
|
|
66
|
-
property: 'symbols'
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
}
|
|
75
|
+
await this.validateCachedPackage(dependency, alias, lockFile, accept, imp);
|
|
70
76
|
}
|
|
71
|
-
|
|
72
|
-
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Determines if an import URI is external (requires manifest).
|
|
80
|
+
*
|
|
81
|
+
* Per PRS-010:
|
|
82
|
+
* - Local relative: ./path, ../path
|
|
83
|
+
* - Path aliases: @/path, @alias/path (resolved via manifest paths section)
|
|
84
|
+
* - External: owner/package (requires manifest dependencies)
|
|
85
|
+
*/
|
|
86
|
+
isExternalImport(uri) {
|
|
87
|
+
if (uri.startsWith('./') || uri.startsWith('../')) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
if (uri.startsWith('@')) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Gets the normalized dependency configuration for an alias.
|
|
97
|
+
*/
|
|
98
|
+
getDependency(manifest, alias) {
|
|
99
|
+
const dep = manifest.dependencies?.[alias];
|
|
100
|
+
if (!dep) {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
if (typeof dep === 'string') {
|
|
104
|
+
return { source: alias, ref: dep };
|
|
105
|
+
}
|
|
106
|
+
if (!dep.source && !dep.path) {
|
|
107
|
+
return { ...dep, source: alias };
|
|
108
|
+
}
|
|
109
|
+
return dep;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Validates dependency configuration.
|
|
113
|
+
*/
|
|
114
|
+
validateDependencyConfig(dependency, alias, accept, imp) {
|
|
115
|
+
if (dependency.source && dependency.path) {
|
|
116
|
+
accept('error', ValidationMessages.IMPORT_CONFLICTING_SOURCE_PATH(alias), {
|
|
117
|
+
node: imp,
|
|
118
|
+
property: 'uri',
|
|
119
|
+
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
120
|
+
data: { code: IssueCodes.ImportConflictingSourcePath, alias }
|
|
121
|
+
});
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (!dependency.source && !dependency.path) {
|
|
125
|
+
accept('error', ValidationMessages.IMPORT_MISSING_SOURCE_OR_PATH(alias), {
|
|
126
|
+
node: imp,
|
|
127
|
+
property: 'uri',
|
|
128
|
+
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
129
|
+
data: { code: IssueCodes.ImportMissingSourceOrPath, alias }
|
|
130
|
+
});
|
|
73
131
|
return;
|
|
74
132
|
}
|
|
133
|
+
if (dependency.source && !dependency.ref) {
|
|
134
|
+
accept('error', ValidationMessages.IMPORT_MISSING_REF(alias), {
|
|
135
|
+
node: imp,
|
|
136
|
+
property: 'uri',
|
|
137
|
+
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
138
|
+
data: { code: IssueCodes.ImportMissingRef, alias }
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
if (dependency.path) {
|
|
142
|
+
this.validateLocalPathDependency(dependency.path, alias, accept, imp);
|
|
143
|
+
}
|
|
75
144
|
}
|
|
76
145
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* In DomainLang, top-level declarations are implicitly exported:
|
|
80
|
-
* - Domains
|
|
81
|
-
* - BoundedContexts
|
|
82
|
-
* - Classifications
|
|
83
|
-
* - Groups
|
|
146
|
+
* Validates local path dependencies stay within workspace.
|
|
84
147
|
*/
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
148
|
+
validateLocalPathDependency(dependencyPath, alias, accept, imp) {
|
|
149
|
+
if (path.isAbsolute(dependencyPath)) {
|
|
150
|
+
accept('error', ValidationMessages.IMPORT_ABSOLUTE_PATH(alias, dependencyPath), {
|
|
151
|
+
node: imp,
|
|
152
|
+
property: 'uri',
|
|
153
|
+
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
154
|
+
data: { code: IssueCodes.ImportAbsolutePath, alias, path: dependencyPath }
|
|
155
|
+
});
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const workspaceRoot = this.workspaceManager.getWorkspaceRoot();
|
|
159
|
+
const resolvedPath = path.resolve(workspaceRoot, dependencyPath);
|
|
160
|
+
const relativeToWorkspace = path.relative(workspaceRoot, resolvedPath);
|
|
161
|
+
if (relativeToWorkspace.startsWith('..') || path.isAbsolute(relativeToWorkspace)) {
|
|
162
|
+
accept('error', ValidationMessages.IMPORT_ESCAPES_WORKSPACE(alias), {
|
|
163
|
+
node: imp,
|
|
164
|
+
property: 'uri',
|
|
165
|
+
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
166
|
+
data: { code: IssueCodes.ImportEscapesWorkspace, alias }
|
|
167
|
+
});
|
|
93
168
|
}
|
|
94
|
-
return symbols;
|
|
95
169
|
}
|
|
96
170
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* This is a warning, not an error, to avoid being too strict.
|
|
171
|
+
* Validates that external dependency is in lock file and cached.
|
|
100
172
|
*/
|
|
101
|
-
|
|
102
|
-
//
|
|
103
|
-
|
|
173
|
+
async validateCachedPackage(dependency, alias, lockFile, accept, imp) {
|
|
174
|
+
// Source is guaranteed to exist when this method is called (see caller)
|
|
175
|
+
const packageKey = dependency.source ?? alias;
|
|
176
|
+
const lockedDep = lockFile.dependencies[packageKey];
|
|
177
|
+
if (!lockedDep) {
|
|
178
|
+
accept('error', ValidationMessages.IMPORT_NOT_INSTALLED(alias), {
|
|
179
|
+
node: imp,
|
|
180
|
+
property: 'uri',
|
|
181
|
+
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
182
|
+
data: { code: IssueCodes.ImportNotInstalled, alias }
|
|
183
|
+
});
|
|
104
184
|
return;
|
|
105
185
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
186
|
+
const workspaceRoot = this.workspaceManager.getWorkspaceRoot();
|
|
187
|
+
const cacheDir = this.getCacheDirectory(workspaceRoot, packageKey, lockedDep.commit);
|
|
188
|
+
const cacheExists = await this.directoryExists(cacheDir);
|
|
189
|
+
if (!cacheExists) {
|
|
190
|
+
accept('error', ValidationMessages.IMPORT_NOT_INSTALLED(alias), {
|
|
191
|
+
node: imp,
|
|
192
|
+
property: 'uri',
|
|
193
|
+
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
194
|
+
data: { code: IssueCodes.ImportNotInstalled, alias }
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Gets the cache directory for a dependency.
|
|
200
|
+
* Per PRS-010: Project-local cache at .dlang/packages/{owner}/{repo}/{commit}/
|
|
201
|
+
*/
|
|
202
|
+
getCacheDirectory(workspaceRoot, source, commitHash) {
|
|
203
|
+
const [owner, repo] = source.split('/');
|
|
204
|
+
return path.join(workspaceRoot, '.dlang', 'packages', owner, repo, commitHash);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Checks if a directory exists (async).
|
|
208
|
+
*/
|
|
209
|
+
async directoryExists(dirPath) {
|
|
210
|
+
try {
|
|
211
|
+
const stat = await fs.stat(dirPath);
|
|
212
|
+
return stat.isDirectory();
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
109
217
|
}
|
|
110
218
|
}
|
|
111
219
|
/**
|
|
112
220
|
* Creates validation checks for import statements.
|
|
221
|
+
*
|
|
222
|
+
* Returns async validators that leverage the shared WorkspaceManager
|
|
223
|
+
* for cached manifest/lock file reading.
|
|
113
224
|
*/
|
|
114
|
-
export function createImportChecks(
|
|
225
|
+
export function createImportChecks(services) {
|
|
226
|
+
const validator = new ImportValidator(services);
|
|
115
227
|
return {
|
|
116
|
-
|
|
228
|
+
// Langium 4.x supports async validators via MaybePromise<void>
|
|
229
|
+
ImportStatement: async (imp, accept, cancelToken) => {
|
|
117
230
|
const document = imp.$document;
|
|
118
231
|
if (!document)
|
|
119
232
|
return;
|
|
120
|
-
|
|
121
|
-
// execute during document validation. These checks will run during
|
|
122
|
-
// the build phase when documents are fully loaded.
|
|
123
|
-
// For now, just do basic syntax validation
|
|
124
|
-
if (!imp.uri) {
|
|
125
|
-
accept('error', 'Import statement must have a URI', {
|
|
126
|
-
node: imp,
|
|
127
|
-
keyword: 'import'
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
// TODO: Implement async validation in a separate build phase
|
|
131
|
-
// This would require using DocumentBuilder.onBuildPhase() or similar
|
|
233
|
+
await validator.checkImportPath(imp, accept, document, cancelToken);
|
|
132
234
|
}
|
|
133
235
|
};
|
|
134
236
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/validation/import.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/validation/import.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest Validation for DomainLang.
|
|
3
|
+
*
|
|
4
|
+
* Provides schema validation and issue detection for model.yaml files.
|
|
5
|
+
* This validation is triggered by the workspace manager when manifests are loaded.
|
|
6
|
+
*
|
|
7
|
+
* Validation includes:
|
|
8
|
+
* - Required fields for publishable packages
|
|
9
|
+
* - Dependency configuration correctness
|
|
10
|
+
* - Path alias validation
|
|
11
|
+
* - Version format validation
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
import type { ModelManifest } from '../services/types.js';
|
|
16
|
+
/**
|
|
17
|
+
* Severity levels for manifest diagnostics.
|
|
18
|
+
*/
|
|
19
|
+
export type ManifestSeverity = 'error' | 'warning' | 'info';
|
|
20
|
+
/**
|
|
21
|
+
* A diagnostic issue found in model.yaml.
|
|
22
|
+
*/
|
|
23
|
+
export interface ManifestDiagnostic {
|
|
24
|
+
/** Issue code for code action mapping */
|
|
25
|
+
readonly code: string;
|
|
26
|
+
/** Error severity */
|
|
27
|
+
readonly severity: ManifestSeverity;
|
|
28
|
+
/** Human-readable message */
|
|
29
|
+
readonly message: string;
|
|
30
|
+
/** YAML path to the issue (e.g., "dependencies.core.version") */
|
|
31
|
+
readonly path: string;
|
|
32
|
+
/** Optional hint for resolution */
|
|
33
|
+
readonly hint?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Result of manifest validation.
|
|
37
|
+
*/
|
|
38
|
+
export interface ManifestValidationResult {
|
|
39
|
+
/** Whether the manifest is valid (no errors) */
|
|
40
|
+
readonly valid: boolean;
|
|
41
|
+
/** All diagnostics found */
|
|
42
|
+
readonly diagnostics: ManifestDiagnostic[];
|
|
43
|
+
/** Count of errors only */
|
|
44
|
+
readonly errorCount: number;
|
|
45
|
+
/** Count of warnings only */
|
|
46
|
+
readonly warningCount: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Issue codes specific to manifest validation.
|
|
50
|
+
* These extend the general IssueCodes for manifest-specific issues.
|
|
51
|
+
*/
|
|
52
|
+
export declare const ManifestIssueCodes: {
|
|
53
|
+
readonly ModelMissingName: "manifest-model-missing-name";
|
|
54
|
+
readonly ModelMissingVersion: "manifest-model-missing-version";
|
|
55
|
+
readonly ModelInvalidVersion: "manifest-model-invalid-version";
|
|
56
|
+
readonly DependencyMissingRef: "manifest-dependency-missing-ref";
|
|
57
|
+
readonly DependencyInvalidRef: "manifest-dependency-invalid-ref";
|
|
58
|
+
readonly DependencyConflictingSourcePath: "manifest-dependency-conflicting-source-path";
|
|
59
|
+
readonly DependencyMissingSourceOrPath: "manifest-dependency-missing-source-or-path";
|
|
60
|
+
readonly DependencyInvalidSource: "manifest-dependency-invalid-source";
|
|
61
|
+
readonly DependencyAbsolutePath: "manifest-dependency-absolute-path";
|
|
62
|
+
readonly PathAliasMissingAtPrefix: "manifest-path-alias-missing-at-prefix";
|
|
63
|
+
readonly PathAliasAbsolutePath: "manifest-path-alias-absolute-path";
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Validates model.yaml manifests and reports issues.
|
|
67
|
+
*
|
|
68
|
+
* Usage:
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const validator = new ManifestValidator();
|
|
71
|
+
* const result = validator.validate(manifest);
|
|
72
|
+
* if (!result.valid) {
|
|
73
|
+
* console.log(result.diagnostics);
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare class ManifestValidator {
|
|
78
|
+
/**
|
|
79
|
+
* Validates a parsed model.yaml manifest.
|
|
80
|
+
*
|
|
81
|
+
* @param manifest - The parsed manifest object
|
|
82
|
+
* @param options - Optional validation options
|
|
83
|
+
* @returns Validation result with diagnostics
|
|
84
|
+
*/
|
|
85
|
+
validate(manifest: ModelManifest, options?: {
|
|
86
|
+
requirePublishable?: boolean;
|
|
87
|
+
}): ManifestValidationResult;
|
|
88
|
+
/**
|
|
89
|
+
* Validates the model section of the manifest.
|
|
90
|
+
*/
|
|
91
|
+
private validateModelSection;
|
|
92
|
+
/**
|
|
93
|
+
* Validates the dependencies section of the manifest.
|
|
94
|
+
*/
|
|
95
|
+
private validateDependenciesSection;
|
|
96
|
+
/**
|
|
97
|
+
* Validates a single dependency entry.
|
|
98
|
+
*/
|
|
99
|
+
private validateDependency;
|
|
100
|
+
/**
|
|
101
|
+
* Validates a git-source based dependency.
|
|
102
|
+
*/
|
|
103
|
+
private validateSourceDependency;
|
|
104
|
+
/**
|
|
105
|
+
* Validates a path-based local dependency.
|
|
106
|
+
*/
|
|
107
|
+
private validatePathDependency;
|
|
108
|
+
/**
|
|
109
|
+
* Validates the paths section of the manifest.
|
|
110
|
+
*/
|
|
111
|
+
private validatePathsSection;
|
|
112
|
+
/**
|
|
113
|
+
* Normalizes a dependency to extended form.
|
|
114
|
+
*/
|
|
115
|
+
private normalizeDependency;
|
|
116
|
+
/**
|
|
117
|
+
* Checks if a version string is valid SemVer.
|
|
118
|
+
*/
|
|
119
|
+
private isValidSemVer;
|
|
120
|
+
/**
|
|
121
|
+
* Checks if a ref spec is valid (tag, branch, or commit SHA).
|
|
122
|
+
*/
|
|
123
|
+
private isValidRefSpec;
|
|
124
|
+
/**
|
|
125
|
+
* Checks if source is valid owner/repo format.
|
|
126
|
+
*/
|
|
127
|
+
private isValidSourceFormat;
|
|
128
|
+
/**
|
|
129
|
+
* Checks if a path is absolute.
|
|
130
|
+
*/
|
|
131
|
+
private isAbsolutePath;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Validates a manifest and returns true if valid, false otherwise.
|
|
135
|
+
* Use this for simple pass/fail checks.
|
|
136
|
+
*/
|
|
137
|
+
export declare function isManifestValid(manifest: ModelManifest): boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Validates a manifest and returns all diagnostics.
|
|
140
|
+
* Use this to display validation errors to users.
|
|
141
|
+
*/
|
|
142
|
+
export declare function validateManifest(manifest: ModelManifest, options?: {
|
|
143
|
+
requirePublishable?: boolean;
|
|
144
|
+
}): ManifestDiagnostic[];
|