@domainlang/language 0.7.0 → 0.9.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/out/domain-lang-module.d.ts +2 -0
- package/out/domain-lang-module.js +21 -2
- package/out/domain-lang-module.js.map +1 -1
- package/out/lsp/domain-lang-completion.d.ts +142 -1
- package/out/lsp/domain-lang-completion.js +620 -22
- package/out/lsp/domain-lang-completion.js.map +1 -1
- package/out/lsp/domain-lang-document-symbol-provider.d.ts +79 -0
- package/out/lsp/domain-lang-document-symbol-provider.js +210 -0
- package/out/lsp/domain-lang-document-symbol-provider.js.map +1 -0
- package/out/lsp/domain-lang-index-manager.d.ts +34 -5
- package/out/lsp/domain-lang-index-manager.js +66 -27
- package/out/lsp/domain-lang-index-manager.js.map +1 -1
- package/out/lsp/domain-lang-node-kind-provider.d.ts +27 -0
- package/out/lsp/domain-lang-node-kind-provider.js +87 -0
- package/out/lsp/domain-lang-node-kind-provider.js.map +1 -0
- package/out/lsp/domain-lang-scope-provider.d.ts +53 -20
- package/out/lsp/domain-lang-scope-provider.js +119 -44
- package/out/lsp/domain-lang-scope-provider.js.map +1 -1
- package/out/lsp/domain-lang-workspace-manager.d.ts +23 -2
- package/out/lsp/domain-lang-workspace-manager.js +51 -6
- package/out/lsp/domain-lang-workspace-manager.js.map +1 -1
- package/out/lsp/hover/domain-lang-hover.d.ts +16 -6
- package/out/lsp/hover/domain-lang-hover.js +160 -134
- package/out/lsp/hover/domain-lang-hover.js.map +1 -1
- package/out/lsp/hover/hover-builders.d.ts +57 -0
- package/out/lsp/hover/hover-builders.js +171 -0
- package/out/lsp/hover/hover-builders.js.map +1 -0
- package/out/main.js +2 -1
- package/out/main.js.map +1 -1
- package/out/sdk/index.d.ts +31 -11
- package/out/sdk/index.js +30 -11
- package/out/sdk/index.js.map +1 -1
- package/out/sdk/loader-node.d.ts +2 -0
- package/out/sdk/loader-node.js +3 -1
- package/out/sdk/loader-node.js.map +1 -1
- package/out/sdk/loader.d.ts +55 -2
- package/out/sdk/loader.js +87 -28
- package/out/sdk/loader.js.map +1 -1
- package/out/sdk/query.js +14 -11
- package/out/sdk/query.js.map +1 -1
- package/out/sdk/validator.d.ts +134 -0
- package/out/sdk/validator.js +249 -0
- package/out/sdk/validator.js.map +1 -0
- package/out/services/package-boundary-detector.d.ts +101 -0
- package/out/services/package-boundary-detector.js +211 -0
- package/out/services/package-boundary-detector.js.map +1 -0
- package/out/services/performance-optimizer.js +6 -2
- package/out/services/performance-optimizer.js.map +1 -1
- package/out/services/types.d.ts +24 -0
- package/out/services/types.js.map +1 -1
- package/out/services/workspace-manager.d.ts +73 -6
- package/out/services/workspace-manager.js +210 -57
- package/out/services/workspace-manager.js.map +1 -1
- package/out/utils/import-utils.d.ts +9 -6
- package/out/utils/import-utils.js +26 -15
- package/out/utils/import-utils.js.map +1 -1
- package/out/validation/constants.d.ts +7 -0
- package/out/validation/constants.js +21 -3
- package/out/validation/constants.js.map +1 -1
- package/out/validation/import.d.ts +11 -1
- package/out/validation/import.js +42 -14
- package/out/validation/import.js.map +1 -1
- package/out/validation/maps.js +50 -1
- package/out/validation/maps.js.map +1 -1
- package/package.json +8 -9
- package/src/domain-lang-module.ts +24 -3
- package/src/lsp/domain-lang-completion.ts +736 -27
- package/src/lsp/domain-lang-document-symbol-provider.ts +254 -0
- package/src/lsp/domain-lang-index-manager.ts +79 -27
- package/src/lsp/domain-lang-node-kind-provider.ts +119 -0
- package/src/lsp/domain-lang-scope-provider.ts +171 -55
- package/src/lsp/domain-lang-workspace-manager.ts +64 -6
- package/src/lsp/hover/domain-lang-hover.ts +189 -131
- package/src/lsp/hover/hover-builders.ts +208 -0
- package/src/main.ts +3 -1
- package/src/sdk/index.ts +33 -11
- package/src/sdk/loader-node.ts +6 -1
- package/src/sdk/loader.ts +125 -34
- package/src/sdk/query.ts +15 -11
- package/src/sdk/validator.ts +358 -0
- package/src/services/package-boundary-detector.ts +238 -0
- package/src/services/performance-optimizer.ts +6 -2
- package/src/services/types.ts +25 -0
- package/src/services/workspace-manager.ts +259 -62
- package/src/utils/import-utils.ts +27 -15
- package/src/validation/constants.ts +23 -6
- package/src/validation/import.ts +49 -14
- package/src/validation/maps.ts +59 -2
package/src/validation/import.ts
CHANGED
|
@@ -78,35 +78,36 @@ export class ImportValidator {
|
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
const
|
|
81
|
+
// Find the matching dependency by key (owner/package format)
|
|
82
|
+
const match = this.findDependency(manifest, imp.uri);
|
|
83
83
|
|
|
84
|
-
if (!
|
|
85
|
-
accept('error', ValidationMessages.IMPORT_NOT_IN_MANIFEST(
|
|
84
|
+
if (!match) {
|
|
85
|
+
accept('error', ValidationMessages.IMPORT_NOT_IN_MANIFEST(imp.uri), {
|
|
86
86
|
node: imp,
|
|
87
87
|
property: 'uri',
|
|
88
88
|
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
89
|
-
data: { code: IssueCodes.ImportNotInManifest, alias }
|
|
89
|
+
data: { code: IssueCodes.ImportNotInManifest, alias: imp.uri }
|
|
90
90
|
});
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
const { key, dependency } = match;
|
|
95
|
+
this.validateDependencyConfig(dependency, key, accept, imp);
|
|
95
96
|
|
|
96
97
|
// External source dependencies require lock file and cached packages
|
|
97
98
|
if (dependency.source) {
|
|
98
99
|
const lockFile = await this.workspaceManager.getLockFile();
|
|
99
100
|
if (!lockFile) {
|
|
100
|
-
accept('error', ValidationMessages.IMPORT_NOT_INSTALLED(
|
|
101
|
+
accept('error', ValidationMessages.IMPORT_NOT_INSTALLED(key), {
|
|
101
102
|
node: imp,
|
|
102
103
|
property: 'uri',
|
|
103
104
|
codeDescription: buildCodeDescription('language.md', 'imports'),
|
|
104
|
-
data: { code: IssueCodes.ImportNotInstalled, alias }
|
|
105
|
+
data: { code: IssueCodes.ImportNotInstalled, alias: key }
|
|
105
106
|
});
|
|
106
107
|
return;
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
await this.validateCachedPackage(dependency,
|
|
110
|
+
await this.validateCachedPackage(dependency, key, lockFile, accept, imp);
|
|
110
111
|
}
|
|
111
112
|
}
|
|
112
113
|
|
|
@@ -186,20 +187,54 @@ export class ImportValidator {
|
|
|
186
187
|
}
|
|
187
188
|
|
|
188
189
|
/**
|
|
189
|
-
*
|
|
190
|
+
* Finds the dependency configuration that matches the import specifier.
|
|
191
|
+
*
|
|
192
|
+
* Dependencies can be keyed as:
|
|
193
|
+
* - owner/package (recommended, matches "owner/package" or "owner/package/subpath")
|
|
194
|
+
* - short-alias (matches "short-alias" or "short-alias/subpath")
|
|
195
|
+
*
|
|
196
|
+
* @returns The matching key and normalized dependency, or undefined if not found
|
|
197
|
+
*/
|
|
198
|
+
private findDependency(
|
|
199
|
+
manifest: ModelManifest,
|
|
200
|
+
specifier: string
|
|
201
|
+
): { key: string; dependency: ExtendedDependencySpec } | undefined {
|
|
202
|
+
const dependencies = manifest.dependencies;
|
|
203
|
+
if (!dependencies) {
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Sort keys by length descending to match most specific first
|
|
208
|
+
const sortedKeys = Object.keys(dependencies).sort((a, b) => b.length - a.length);
|
|
209
|
+
|
|
210
|
+
for (const key of sortedKeys) {
|
|
211
|
+
// Exact match or prefix match (key followed by /)
|
|
212
|
+
if (specifier === key || specifier.startsWith(`${key}/`)) {
|
|
213
|
+
const dependency = this.getDependency(manifest, key);
|
|
214
|
+
if (dependency) {
|
|
215
|
+
return { key, dependency };
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return undefined;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Gets the normalized dependency configuration for a key.
|
|
190
225
|
*/
|
|
191
|
-
private getDependency(manifest: ModelManifest,
|
|
192
|
-
const dep = manifest.dependencies?.[
|
|
226
|
+
private getDependency(manifest: ModelManifest, key: string): ExtendedDependencySpec | undefined {
|
|
227
|
+
const dep = manifest.dependencies?.[key];
|
|
193
228
|
if (!dep) {
|
|
194
229
|
return undefined;
|
|
195
230
|
}
|
|
196
231
|
|
|
197
232
|
if (typeof dep === 'string') {
|
|
198
|
-
return { source:
|
|
233
|
+
return { source: key, ref: dep };
|
|
199
234
|
}
|
|
200
235
|
|
|
201
236
|
if (!dep.source && !dep.path) {
|
|
202
|
-
return { ...dep, source:
|
|
237
|
+
return { ...dep, source: key };
|
|
203
238
|
}
|
|
204
239
|
|
|
205
240
|
return dep;
|
package/src/validation/maps.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ValidationAcceptor } from 'langium';
|
|
2
|
-
import type { ContextMap, DomainMap } from '../generated/ast.js';
|
|
2
|
+
import type { ContextMap, DomainMap, Relationship, BoundedContextRef } from '../generated/ast.js';
|
|
3
|
+
import { isThisRef } from '../generated/ast.js';
|
|
3
4
|
import { ValidationMessages, buildCodeDescription, IssueCodes } from './constants.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -121,10 +122,66 @@ function validateDomainMapReferences(
|
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Gets a canonical name for a BoundedContextRef for comparison purposes.
|
|
127
|
+
*/
|
|
128
|
+
function getRefKey(ref: BoundedContextRef): string {
|
|
129
|
+
if (isThisRef(ref)) {
|
|
130
|
+
return 'this';
|
|
131
|
+
}
|
|
132
|
+
return ref.link?.$refText ?? '';
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Builds a canonical key for a relationship for duplicate detection.
|
|
137
|
+
* The key captures both endpoints, arrow direction, and integration patterns.
|
|
138
|
+
*/
|
|
139
|
+
function buildRelationshipKey(rel: Relationship): string {
|
|
140
|
+
const left = getRefKey(rel.left);
|
|
141
|
+
const right = getRefKey(rel.right);
|
|
142
|
+
const leftPatterns = (rel.leftPatterns ?? []).slice().sort((a, b) => a.localeCompare(b)).join(',');
|
|
143
|
+
const rightPatterns = (rel.rightPatterns ?? []).slice().sort((a, b) => a.localeCompare(b)).join(',');
|
|
144
|
+
return `[${leftPatterns}]${left}${rel.arrow}[${rightPatterns}]${right}`;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Validates that a context map does not contain duplicate relationships.
|
|
149
|
+
* Two relationships are considered duplicate if they have the same endpoints,
|
|
150
|
+
* direction, and integration patterns.
|
|
151
|
+
*
|
|
152
|
+
* @param map - The context map to validate
|
|
153
|
+
* @param accept - The validation acceptor for reporting issues
|
|
154
|
+
*/
|
|
155
|
+
function validateNoDuplicateRelationships(
|
|
156
|
+
map: ContextMap,
|
|
157
|
+
accept: ValidationAcceptor
|
|
158
|
+
): void {
|
|
159
|
+
if (!map.relationships || map.relationships.length < 2) return;
|
|
160
|
+
|
|
161
|
+
const seen = new Map<string, number>();
|
|
162
|
+
for (let i = 0; i < map.relationships.length; i++) {
|
|
163
|
+
const rel = map.relationships[i];
|
|
164
|
+
const key = buildRelationshipKey(rel);
|
|
165
|
+
|
|
166
|
+
if (seen.has(key)) {
|
|
167
|
+
accept('warning', ValidationMessages.CONTEXT_MAP_DUPLICATE_RELATIONSHIP(
|
|
168
|
+
getRefKey(rel.left), getRefKey(rel.right)
|
|
169
|
+
), {
|
|
170
|
+
node: rel,
|
|
171
|
+
property: 'arrow',
|
|
172
|
+
codeDescription: buildCodeDescription('language.md', 'context-maps')
|
|
173
|
+
});
|
|
174
|
+
} else {
|
|
175
|
+
seen.set(key, i);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
124
180
|
export const contextMapChecks = [
|
|
125
181
|
validateContextMapHasContexts,
|
|
126
182
|
validateContextMapReferences,
|
|
127
|
-
validateContextMapHasRelationships
|
|
183
|
+
validateContextMapHasRelationships,
|
|
184
|
+
validateNoDuplicateRelationships
|
|
128
185
|
];
|
|
129
186
|
|
|
130
187
|
export const domainMapChecks = [
|