@domainlang/language 0.11.0 → 0.12.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.
Files changed (31) hide show
  1. package/out/diagram/context-map-diagram-generator.d.ts +65 -0
  2. package/out/diagram/context-map-diagram-generator.js +356 -0
  3. package/out/diagram/context-map-diagram-generator.js.map +1 -0
  4. package/out/diagram/context-map-layout-configurator.d.ts +15 -0
  5. package/out/diagram/context-map-layout-configurator.js +39 -0
  6. package/out/diagram/context-map-layout-configurator.js.map +1 -0
  7. package/out/diagram/elk-layout-factory.d.ts +43 -0
  8. package/out/diagram/elk-layout-factory.js +64 -0
  9. package/out/diagram/elk-layout-factory.js.map +1 -0
  10. package/out/domain-lang-module.d.ts +7 -0
  11. package/out/domain-lang-module.js +11 -2
  12. package/out/domain-lang-module.js.map +1 -1
  13. package/out/index.d.ts +3 -0
  14. package/out/index.js +4 -0
  15. package/out/index.js.map +1 -1
  16. package/out/lsp/domain-lang-code-lens-provider.d.ts +8 -0
  17. package/out/lsp/domain-lang-code-lens-provider.js +48 -0
  18. package/out/lsp/domain-lang-code-lens-provider.js.map +1 -0
  19. package/out/lsp/domain-lang-document-symbol-provider.js +5 -5
  20. package/out/lsp/domain-lang-document-symbol-provider.js.map +1 -1
  21. package/out/lsp/tool-handlers.js +63 -57
  22. package/out/lsp/tool-handlers.js.map +1 -1
  23. package/package.json +5 -2
  24. package/src/diagram/context-map-diagram-generator.ts +451 -0
  25. package/src/diagram/context-map-layout-configurator.ts +43 -0
  26. package/src/diagram/elk-layout-factory.ts +83 -0
  27. package/src/domain-lang-module.ts +19 -2
  28. package/src/index.ts +5 -0
  29. package/src/lsp/domain-lang-code-lens-provider.ts +54 -0
  30. package/src/lsp/domain-lang-document-symbol-provider.ts +5 -5
  31. package/src/lsp/tool-handlers.ts +61 -47
@@ -0,0 +1,54 @@
1
+ import { AstUtils, type LangiumDocument } from 'langium';
2
+ import type { CodeLens, CodeLensParams } from 'vscode-languageserver';
3
+ import { isContextMap, type ContextMap, type Model } from '../generated/ast.js';
4
+
5
+ const OPEN_DIAGRAM_COMMAND = 'domainlang.diagram.open';
6
+
7
+ /**
8
+ * Provides contextual code lenses for context map diagram actions.
9
+ */
10
+ export class DomainLangCodeLensProvider {
11
+ async provideCodeLens(document: LangiumDocument, _params: CodeLensParams): Promise<CodeLens[]> {
12
+ try {
13
+ const model = (document as LangiumDocument<Model>).parseResult?.value;
14
+ if (!model) {
15
+ return [];
16
+ }
17
+
18
+ const contextMaps: ContextMap[] = [];
19
+
20
+ if (isContextMap(model)) {
21
+ contextMaps.push(model);
22
+ }
23
+
24
+ for (const node of AstUtils.streamAllContents(model)) {
25
+ if (isContextMap(node)) {
26
+ contextMaps.push(node);
27
+ }
28
+ }
29
+
30
+ return contextMaps.flatMap((contextMap) => {
31
+ const range = contextMap.$cstNode?.range;
32
+ if (!range) {
33
+ return [];
34
+ }
35
+
36
+ return [{
37
+ range: {
38
+ start: { line: range.start.line, character: 0 },
39
+ end: { line: range.start.line, character: 0 },
40
+ },
41
+ command: {
42
+ title: 'Open diagram',
43
+ command: OPEN_DIAGRAM_COMMAND,
44
+ arguments: [{
45
+ uri: document.uri.toString(),
46
+ }],
47
+ },
48
+ }];
49
+ });
50
+ } catch {
51
+ return [];
52
+ }
53
+ }
54
+ }
@@ -147,8 +147,8 @@ export class DomainLangDocumentSymbolProvider extends DefaultDocumentSymbolProvi
147
147
  const cstNode = rel.$cstNode;
148
148
  if (!cstNode) return undefined;
149
149
 
150
- const left = isThisRef(rel.left) ? 'this' : rel.left?.link?.ref?.name ?? '?';
151
- const right = isThisRef(rel.right) ? 'this' : rel.right?.link?.ref?.name ?? '?';
150
+ const left = isThisRef(rel.left) ? 'this' : rel.left?.link?.$refText ?? '?';
151
+ const right = isThisRef(rel.right) ? 'this' : rel.right?.link?.$refText ?? '?';
152
152
  const name = `${left} → ${right}`;
153
153
 
154
154
  const range = CstUtils.toDocumentSegment(cstNode).range;
@@ -168,7 +168,7 @@ export class DomainLangDocumentSymbolProvider extends DefaultDocumentSymbolProvi
168
168
  const cstNode = meta.$cstNode;
169
169
  if (!cstNode) return undefined;
170
170
 
171
- const name = meta.key?.ref?.name ?? 'unknown';
171
+ const name = meta.key?.$refText ?? 'unknown';
172
172
  const range = CstUtils.toDocumentSegment(cstNode).range;
173
173
 
174
174
  return DocumentSymbol.create(
@@ -197,8 +197,8 @@ export class DomainLangDocumentSymbolProvider extends DefaultDocumentSymbolProvi
197
197
  /** Builds BC detail: "BC for DomainName — description". */
198
198
  private getBcDetail(node: BoundedContext): string | undefined {
199
199
  const parts: string[] = [];
200
- if (node.domain?.ref?.name) {
201
- parts.push(`BC for ${node.domain.ref.name}`);
200
+ if (node.domain?.$refText) {
201
+ parts.push(`BC for ${node.domain.$refText}`);
202
202
  }
203
203
  if (node.description) {
204
204
  parts.push(node.description);
@@ -337,54 +337,68 @@ function executeListQuery(
337
337
  entityType: QueryEntityType,
338
338
  filters: QueryFilters
339
339
  ): Record<string, unknown>[] {
340
- switch (entityType) {
341
- case 'domains': {
342
- let builder = query.domains();
343
- if (filters.name) builder = builder.withName(filters.name);
344
- if (filters.fqn) builder = builder.withFqn(filters.fqn);
345
- return builder.toArray().map((d) => serializeNode(d, query));
346
- }
347
- case 'bcs': {
348
- let builder = query.boundedContexts();
349
- if (filters.domain) builder = builder.inDomain(filters.domain);
350
- if (filters.team) builder = builder.withTeam(filters.team);
351
- if (filters.classification)
352
- builder = builder.withClassification(filters.classification);
353
- if (filters.metadata) {
354
- const [key, value] = filters.metadata.split('=');
355
- builder = builder.withMetadata(key, value);
356
- }
357
- if (filters.name) builder = builder.withName(filters.name) as ReturnType<Query['boundedContexts']>;
358
- if (filters.fqn) builder = builder.withFqn(filters.fqn) as ReturnType<Query['boundedContexts']>;
359
- return builder.toArray().map((bc) => serializeNode(bc, query));
360
- }
361
- case 'teams': {
362
- let builder = query.teams();
363
- if (filters.name) builder = builder.withName(filters.name);
364
- return builder.toArray().map((t) => serializeNode(t, query));
365
- }
366
- case 'classifications': {
367
- let builder = query.classifications();
368
- if (filters.name) builder = builder.withName(filters.name);
369
- return builder.toArray().map((c) => serializeNode(c, query));
370
- }
371
- case 'relationships': {
372
- const rels = query.relationships().toArray();
373
- return rels.map((r) => serializeRelationship(r));
374
- }
375
- case 'context-maps': {
376
- let builder = query.contextMaps();
377
- if (filters.name) builder = builder.withName(filters.name);
378
- return builder.toArray().map((cm) => serializeNode(cm, query));
379
- }
380
- case 'domain-maps': {
381
- let builder = query.domainMaps();
382
- if (filters.name) builder = builder.withName(filters.name);
383
- return builder.toArray().map((dm) => serializeNode(dm, query));
384
- }
385
- default:
386
- return [];
340
+ const handlers: Record<QueryEntityType, (activeQuery: Query, activeFilters: QueryFilters) => Record<string, unknown>[]> = {
341
+ domains: listDomains,
342
+ bcs: listBoundedContexts,
343
+ teams: listTeams,
344
+ classifications: listClassifications,
345
+ relationships: listRelationships,
346
+ 'context-maps': listContextMaps,
347
+ 'domain-maps': listDomainMaps,
348
+ };
349
+
350
+ return handlers[entityType](query, filters);
351
+ }
352
+
353
+ function listDomains(query: Query, filters: QueryFilters): Record<string, unknown>[] {
354
+ let builder = query.domains();
355
+ if (filters.name) builder = builder.withName(filters.name);
356
+ if (filters.fqn) builder = builder.withFqn(filters.fqn);
357
+ return builder.toArray().map((domain) => serializeNode(domain, query));
358
+ }
359
+
360
+ function listBoundedContexts(query: Query, filters: QueryFilters): Record<string, unknown>[] {
361
+ let builder = query.boundedContexts();
362
+ if (filters.domain) builder = builder.inDomain(filters.domain);
363
+ if (filters.team) builder = builder.withTeam(filters.team);
364
+ if (filters.classification) {
365
+ builder = builder.withClassification(filters.classification);
387
366
  }
367
+ if (filters.metadata) {
368
+ const [key, value] = filters.metadata.split('=');
369
+ builder = builder.withMetadata(key, value);
370
+ }
371
+ if (filters.name) builder = builder.withName(filters.name) as ReturnType<Query['boundedContexts']>;
372
+ if (filters.fqn) builder = builder.withFqn(filters.fqn) as ReturnType<Query['boundedContexts']>;
373
+ return builder.toArray().map((boundedContext) => serializeNode(boundedContext, query));
374
+ }
375
+
376
+ function listTeams(query: Query, filters: QueryFilters): Record<string, unknown>[] {
377
+ let builder = query.teams();
378
+ if (filters.name) builder = builder.withName(filters.name);
379
+ return builder.toArray().map((team) => serializeNode(team, query));
380
+ }
381
+
382
+ function listClassifications(query: Query, filters: QueryFilters): Record<string, unknown>[] {
383
+ let builder = query.classifications();
384
+ if (filters.name) builder = builder.withName(filters.name);
385
+ return builder.toArray().map((classification) => serializeNode(classification, query));
386
+ }
387
+
388
+ function listRelationships(query: Query, _filters: QueryFilters): Record<string, unknown>[] {
389
+ return query.relationships().toArray().map((relationship) => serializeRelationship(relationship));
390
+ }
391
+
392
+ function listContextMaps(query: Query, filters: QueryFilters): Record<string, unknown>[] {
393
+ let builder = query.contextMaps();
394
+ if (filters.name) builder = builder.withName(filters.name);
395
+ return builder.toArray().map((contextMap) => serializeNode(contextMap, query));
396
+ }
397
+
398
+ function listDomainMaps(query: Query, filters: QueryFilters): Record<string, unknown>[] {
399
+ let builder = query.domainMaps();
400
+ if (filters.name) builder = builder.withName(filters.name);
401
+ return builder.toArray().map((domainMap) => serializeNode(domainMap, query));
388
402
  }
389
403
 
390
404
  /**