@domainlang/language 0.12.0 → 0.13.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/ast-augmentation.d.ts +7 -2
- package/out/diagram/context-map-diagram-generator.d.ts +9 -2
- package/out/diagram/context-map-diagram-generator.js +112 -63
- package/out/diagram/context-map-diagram-generator.js.map +1 -1
- package/out/generated/ast.d.ts +323 -51
- package/out/generated/ast.js +194 -33
- package/out/generated/ast.js.map +1 -1
- package/out/generated/grammar.js +418 -172
- package/out/generated/grammar.js.map +1 -1
- package/out/lsp/domain-lang-completion.js +39 -15
- package/out/lsp/domain-lang-completion.js.map +1 -1
- package/out/lsp/domain-lang-formatter.js +32 -0
- package/out/lsp/domain-lang-formatter.js.map +1 -1
- package/out/lsp/domain-lang-index-manager.d.ts +2 -3
- package/out/lsp/domain-lang-index-manager.js +5 -8
- package/out/lsp/domain-lang-index-manager.js.map +1 -1
- package/out/lsp/domain-lang-workspace-manager.d.ts +1 -1
- package/out/lsp/domain-lang-workspace-manager.js +2 -26
- package/out/lsp/domain-lang-workspace-manager.js.map +1 -1
- package/out/lsp/explain.js +9 -3
- package/out/lsp/explain.js.map +1 -1
- package/out/lsp/hover/domain-lang-hover.js +13 -11
- package/out/lsp/hover/domain-lang-hover.js.map +1 -1
- package/out/lsp/hover/domain-lang-keywords.js +29 -26
- package/out/lsp/hover/domain-lang-keywords.js.map +1 -1
- package/out/sdk/ast-augmentation.d.ts +29 -21
- package/out/sdk/ast-augmentation.js +11 -7
- package/out/sdk/ast-augmentation.js.map +1 -1
- package/out/sdk/index.d.ts +2 -2
- package/out/sdk/index.js +1 -1
- package/out/sdk/index.js.map +1 -1
- package/out/sdk/loader-node.js +2 -2
- package/out/sdk/loader-node.js.map +1 -1
- package/out/sdk/patterns.d.ts +50 -61
- package/out/sdk/patterns.js +92 -62
- package/out/sdk/patterns.js.map +1 -1
- package/out/sdk/query.js +54 -43
- package/out/sdk/query.js.map +1 -1
- package/out/sdk/serializers.js +20 -7
- package/out/sdk/serializers.js.map +1 -1
- package/out/sdk/types.d.ts +87 -18
- package/out/sdk/types.js.map +1 -1
- package/out/sdk/validator.js +48 -64
- package/out/sdk/validator.js.map +1 -1
- package/out/services/performance-optimizer.d.ts +3 -3
- package/out/services/performance-optimizer.js +1 -3
- package/out/services/performance-optimizer.js.map +1 -1
- package/out/services/relationship-inference.d.ts +4 -4
- package/out/services/relationship-inference.js +34 -46
- package/out/services/relationship-inference.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 +6 -20
- package/out/utils/import-utils.js +3 -63
- package/out/utils/import-utils.js.map +1 -1
- package/out/validation/constants.d.ts +23 -6
- package/out/validation/constants.js +24 -7
- package/out/validation/constants.js.map +1 -1
- package/out/validation/maps.js +10 -4
- package/out/validation/maps.js.map +1 -1
- package/out/validation/relationships.d.ts +4 -8
- package/out/validation/relationships.js +96 -48
- package/out/validation/relationships.js.map +1 -1
- package/package.json +1 -1
- package/src/ast-augmentation.ts +7 -2
- package/src/diagram/context-map-diagram-generator.ts +132 -70
- package/src/domain-lang.langium +62 -26
- package/src/generated/ast.ts +413 -63
- package/src/generated/grammar.ts +418 -172
- package/src/lsp/domain-lang-completion.ts +42 -15
- package/src/lsp/domain-lang-formatter.ts +34 -0
- package/src/lsp/domain-lang-index-manager.ts +6 -9
- package/src/lsp/domain-lang-workspace-manager.ts +3 -29
- package/src/lsp/explain.ts +10 -2
- package/src/lsp/hover/domain-lang-hover.ts +10 -8
- package/src/lsp/hover/domain-lang-keywords.ts +27 -24
- package/src/sdk/ast-augmentation.ts +30 -21
- package/src/sdk/index.ts +11 -1
- package/src/sdk/loader-node.ts +2 -2
- package/src/sdk/patterns.ts +114 -76
- package/src/sdk/query.ts +57 -48
- package/src/sdk/serializers.ts +20 -7
- package/src/sdk/types.ts +92 -17
- package/src/sdk/validator.ts +52 -69
- package/src/services/performance-optimizer.ts +4 -6
- package/src/services/relationship-inference.ts +43 -54
- package/src/utils/import-utils.ts +9 -74
- package/src/validation/constants.ts +32 -9
- package/src/validation/maps.ts +12 -4
- package/src/validation/relationships.ts +150 -71
|
@@ -2,8 +2,9 @@ import type { LangiumDocument } from 'langium';
|
|
|
2
2
|
import type { SGraph, SModelElement, SModelRoot, SEdge, SNode } from 'sprotty-protocol';
|
|
3
3
|
import { LangiumDiagramGenerator, type GeneratorContext } from 'langium-sprotty';
|
|
4
4
|
import { fromDocument } from '../sdk/query.js';
|
|
5
|
-
import type { Query } from '../sdk/types.js';
|
|
6
|
-
import
|
|
5
|
+
import type { Query, RelationshipView } from '../sdk/types.js';
|
|
6
|
+
import { isBigBallOfMud } from '../generated/ast.js';
|
|
7
|
+
import type { BoundedContext, ContextMap, Model, Relationship, SidePattern } from '../generated/ast.js';
|
|
7
8
|
|
|
8
9
|
/** Ellipse sizing for bounded context nodes — sized for long names like "CustomerManagementContext" */
|
|
9
10
|
const NODE_WIDTH = 280;
|
|
@@ -18,29 +19,32 @@ const PATTERN_ABBREVIATIONS: Readonly<Record<string, string>> = {
|
|
|
18
19
|
PublishedLanguage: 'PL',
|
|
19
20
|
AntiCorruptionLayer: 'ACL',
|
|
20
21
|
Conformist: 'CF',
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
Supplier: 'S',
|
|
23
|
+
Customer: 'C',
|
|
23
24
|
BigBallOfMud: 'BBoM',
|
|
25
|
+
SharedKernel: 'SK',
|
|
26
|
+
Partnership: 'P',
|
|
27
|
+
SeparateWays: 'SW',
|
|
24
28
|
};
|
|
25
29
|
|
|
26
30
|
/**
|
|
27
|
-
* Returns the abbreviated form of
|
|
31
|
+
* Returns the abbreviated form of a side pattern AST node.
|
|
28
32
|
*
|
|
29
|
-
*
|
|
30
|
-
* `
|
|
33
|
+
* Maps the `$type` (e.g. `OpenHostService`, `Conformist`) to its standard
|
|
34
|
+
* DDD abbreviation (e.g. `OHS`, `CF`). Unknown types are returned as-is.
|
|
31
35
|
*/
|
|
32
|
-
function
|
|
33
|
-
return PATTERN_ABBREVIATIONS[pattern] ?? pattern;
|
|
36
|
+
function normalizePatternNode(pattern: SidePattern): string {
|
|
37
|
+
return PATTERN_ABBREVIATIONS[pattern.$type] ?? pattern.$type;
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
/**
|
|
37
|
-
* Returns `true` when the pattern identifies a Big Ball of Mud participant.
|
|
41
|
+
* Returns `true` when the side pattern identifies a Big Ball of Mud participant.
|
|
38
42
|
*
|
|
39
43
|
* BBoM is surfaced as a cloud node shape on the bounded context itself, not as
|
|
40
44
|
* a text annotation in the edge badge, so it should be excluded from badge text.
|
|
41
45
|
*/
|
|
42
|
-
function
|
|
43
|
-
return pattern
|
|
46
|
+
function isBBoMSidePattern(pattern: SidePattern): boolean {
|
|
47
|
+
return isBigBallOfMud(pattern);
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
interface DiagramSelection {
|
|
@@ -51,11 +55,7 @@ interface DiagramSelection {
|
|
|
51
55
|
interface RelationshipEdgeParams {
|
|
52
56
|
leftNode: SNode;
|
|
53
57
|
rightNode: SNode;
|
|
54
|
-
|
|
55
|
-
leftPatterns: readonly string[];
|
|
56
|
-
rightPatterns: readonly string[];
|
|
57
|
-
type: string | undefined;
|
|
58
|
-
astNode: Relationship;
|
|
58
|
+
relationship: RelationshipView;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/**
|
|
@@ -98,11 +98,13 @@ export class DomainLangContextMapDiagramGenerator extends LangiumDiagramGenerato
|
|
|
98
98
|
// the `node:bbom` Sprotty type so the webview renders them as clouds.
|
|
99
99
|
const bboMNodeKeys = new Set<string>();
|
|
100
100
|
for (const rel of relationships) {
|
|
101
|
-
if (rel.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
if (rel.type === 'directional') {
|
|
102
|
+
if (rel.left.patterns.some(isBBoMSidePattern)) {
|
|
103
|
+
bboMNodeKeys.add(this.getNodeKey(query, rel.left.context));
|
|
104
|
+
}
|
|
105
|
+
if (rel.right.patterns.some(isBBoMSidePattern)) {
|
|
106
|
+
bboMNodeKeys.add(this.getNodeKey(query, rel.right.context));
|
|
107
|
+
}
|
|
106
108
|
}
|
|
107
109
|
}
|
|
108
110
|
|
|
@@ -110,13 +112,13 @@ export class DomainLangContextMapDiagramGenerator extends LangiumDiagramGenerato
|
|
|
110
112
|
this.collectContextMapNodes(selectedMap, query, nodeMap, bboMNodeKeys, args);
|
|
111
113
|
|
|
112
114
|
for (const relationship of relationships) {
|
|
113
|
-
this.ensureNode(nodeMap, query, relationship.left, bboMNodeKeys, args);
|
|
114
|
-
this.ensureNode(nodeMap, query, relationship.right, bboMNodeKeys, args);
|
|
115
|
+
this.ensureNode(nodeMap, query, relationship.left.context, bboMNodeKeys, args);
|
|
116
|
+
this.ensureNode(nodeMap, query, relationship.right.context, bboMNodeKeys, args);
|
|
115
117
|
}
|
|
116
118
|
|
|
117
119
|
const edges = relationships.flatMap((relationship) => {
|
|
118
|
-
const leftKey = this.getNodeKey(query, relationship.left);
|
|
119
|
-
const rightKey = this.getNodeKey(query, relationship.right);
|
|
120
|
+
const leftKey = this.getNodeKey(query, relationship.left.context);
|
|
121
|
+
const rightKey = this.getNodeKey(query, relationship.right.context);
|
|
120
122
|
const leftNode = nodeMap.get(leftKey);
|
|
121
123
|
const rightNode = nodeMap.get(rightKey);
|
|
122
124
|
|
|
@@ -127,11 +129,7 @@ export class DomainLangContextMapDiagramGenerator extends LangiumDiagramGenerato
|
|
|
127
129
|
return this.createRelationshipEdge({
|
|
128
130
|
leftNode,
|
|
129
131
|
rightNode,
|
|
130
|
-
|
|
131
|
-
leftPatterns: relationship.leftPatterns,
|
|
132
|
-
rightPatterns: relationship.rightPatterns,
|
|
133
|
-
type: relationship.type,
|
|
134
|
-
astNode: relationship.astNode,
|
|
132
|
+
relationship,
|
|
135
133
|
}, args);
|
|
136
134
|
});
|
|
137
135
|
|
|
@@ -159,8 +157,17 @@ export class DomainLangContextMapDiagramGenerator extends LangiumDiagramGenerato
|
|
|
159
157
|
params: RelationshipEdgeParams,
|
|
160
158
|
args: GeneratorContext
|
|
161
159
|
): SEdge[] {
|
|
162
|
-
const { leftNode, rightNode,
|
|
163
|
-
|
|
160
|
+
const { leftNode, rightNode, relationship } = params;
|
|
161
|
+
const astNode = relationship.astNode;
|
|
162
|
+
|
|
163
|
+
if (relationship.type === 'symmetric') {
|
|
164
|
+
return this.createSymmetricEdge(leftNode, rightNode, relationship.kind, astNode, args);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Directional
|
|
168
|
+
const { arrow, kind, left, right } = relationship;
|
|
169
|
+
|
|
170
|
+
// Determine source/target nodes based on arrow direction
|
|
164
171
|
const sourceId = arrow === '<-' ? rightNode.id : leftNode.id;
|
|
165
172
|
const targetId = arrow === '<-' ? leftNode.id : rightNode.id;
|
|
166
173
|
|
|
@@ -171,22 +178,22 @@ export class DomainLangContextMapDiagramGenerator extends LangiumDiagramGenerato
|
|
|
171
178
|
|
|
172
179
|
const children: SModelElement[] = [];
|
|
173
180
|
|
|
174
|
-
if (
|
|
175
|
-
//
|
|
176
|
-
this.addUDBadge(children, edgeId, 'source',
|
|
177
|
-
this.addUDBadge(children, edgeId, 'target',
|
|
178
|
-
} else if (arrow === '><') {
|
|
179
|
-
// Separate Ways — no U/D, no patterns
|
|
181
|
+
if (kind === 'Bidirectional') {
|
|
182
|
+
// No upstream/downstream roles — show patterns positionally
|
|
183
|
+
this.addUDBadge(children, edgeId, 'source', left.patterns, undefined, args);
|
|
184
|
+
this.addUDBadge(children, edgeId, 'target', right.patterns, undefined, args);
|
|
180
185
|
} else {
|
|
181
|
-
//
|
|
182
|
-
const sourcePatterns = arrow === '<-' ?
|
|
183
|
-
const targetPatterns = arrow === '<-' ?
|
|
184
|
-
|
|
185
|
-
|
|
186
|
+
// Upstream/downstream or Customer/Supplier
|
|
187
|
+
const sourcePatterns = arrow === '<-' ? right.patterns : left.patterns;
|
|
188
|
+
const targetPatterns = arrow === '<-' ? left.patterns : right.patterns;
|
|
189
|
+
const sourceRole: 'U' | 'D' | 'S' | 'C' = kind === 'CustomerSupplier' ? 'S' : 'U';
|
|
190
|
+
const targetRole: 'U' | 'D' | 'S' | 'C' = kind === 'CustomerSupplier' ? 'C' : 'D';
|
|
191
|
+
this.addUDBadge(children, edgeId, 'source', sourcePatterns, sourceRole, args);
|
|
192
|
+
this.addUDBadge(children, edgeId, 'target', targetPatterns, targetRole, args);
|
|
186
193
|
}
|
|
187
194
|
|
|
188
|
-
// Center label: relationship
|
|
189
|
-
const centerLabel = this.
|
|
195
|
+
// Center label: relationship kind
|
|
196
|
+
const centerLabel = this.formatRelationshipKind(kind);
|
|
190
197
|
if (centerLabel) {
|
|
191
198
|
children.push({
|
|
192
199
|
type: 'label:edge',
|
|
@@ -202,9 +209,7 @@ export class DomainLangContextMapDiagramGenerator extends LangiumDiagramGenerato
|
|
|
202
209
|
}
|
|
203
210
|
|
|
204
211
|
let edgeCssClasses: string[] | undefined;
|
|
205
|
-
if (arrow === '
|
|
206
|
-
edgeCssClasses = ['separate-ways'];
|
|
207
|
-
} else if (arrow === '<->') {
|
|
212
|
+
if (arrow === '<->') {
|
|
208
213
|
edgeCssClasses = ['partnership'];
|
|
209
214
|
}
|
|
210
215
|
|
|
@@ -221,6 +226,63 @@ export class DomainLangContextMapDiagramGenerator extends LangiumDiagramGenerato
|
|
|
221
226
|
return [edge];
|
|
222
227
|
}
|
|
223
228
|
|
|
229
|
+
/**
|
|
230
|
+
* Creates an undirected edge for symmetric relationships (SK, P, SW).
|
|
231
|
+
*
|
|
232
|
+
* Symmetric relationships have no upstream/downstream directionality.
|
|
233
|
+
* The center label shows the relationship kind (e.g. "Shared Kernel").
|
|
234
|
+
*/
|
|
235
|
+
private createSymmetricEdge(
|
|
236
|
+
leftNode: SNode,
|
|
237
|
+
rightNode: SNode,
|
|
238
|
+
kind: string | undefined,
|
|
239
|
+
astNode: Relationship,
|
|
240
|
+
args: GeneratorContext
|
|
241
|
+
): SEdge[] {
|
|
242
|
+
const edgeId = args.idCache.uniqueId(
|
|
243
|
+
`edge:${leftNode.id}:${rightNode.id}`,
|
|
244
|
+
astNode
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
const children: SModelElement[] = [];
|
|
248
|
+
|
|
249
|
+
const centerLabel = this.formatRelationshipKind(kind);
|
|
250
|
+
if (centerLabel) {
|
|
251
|
+
children.push({
|
|
252
|
+
type: 'label:edge',
|
|
253
|
+
id: args.idCache.uniqueId(`${edgeId}:type`),
|
|
254
|
+
text: centerLabel,
|
|
255
|
+
edgePlacement: {
|
|
256
|
+
side: 'on',
|
|
257
|
+
position: 0.5,
|
|
258
|
+
rotate: false,
|
|
259
|
+
offset: 10,
|
|
260
|
+
},
|
|
261
|
+
} as unknown as SModelElement);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
let edgeCssClasses: string[] | undefined;
|
|
265
|
+
if (kind === 'SeparateWays') {
|
|
266
|
+
edgeCssClasses = ['separate-ways'];
|
|
267
|
+
} else if (kind === 'Partnership') {
|
|
268
|
+
edgeCssClasses = ['partnership'];
|
|
269
|
+
} else if (kind === 'SharedKernel') {
|
|
270
|
+
edgeCssClasses = ['shared-kernel'];
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const edge: SEdge = {
|
|
274
|
+
type: 'edge',
|
|
275
|
+
id: edgeId,
|
|
276
|
+
sourceId: leftNode.id,
|
|
277
|
+
targetId: rightNode.id,
|
|
278
|
+
cssClasses: edgeCssClasses,
|
|
279
|
+
children: children.length > 0 ? children : undefined,
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
this.traceProvider.trace(edge as SModelElement, astNode as unknown as import('langium').AstNode);
|
|
283
|
+
return [edge];
|
|
284
|
+
}
|
|
285
|
+
|
|
224
286
|
/**
|
|
225
287
|
* Adds a U/D badge label at the source or target end of an edge.
|
|
226
288
|
*
|
|
@@ -235,14 +297,18 @@ export class DomainLangContextMapDiagramGenerator extends LangiumDiagramGenerato
|
|
|
235
297
|
children: SModelElement[],
|
|
236
298
|
edgeId: string,
|
|
237
299
|
placement: 'source' | 'target',
|
|
238
|
-
patterns: readonly
|
|
239
|
-
role: 'U' | 'D' | undefined,
|
|
300
|
+
patterns: readonly SidePattern[],
|
|
301
|
+
role: 'U' | 'D' | 'S' | 'C' | undefined,
|
|
240
302
|
args: GeneratorContext
|
|
241
303
|
): void {
|
|
242
|
-
// Normalise pattern names and strip BBoM (shown on node, not in badge)
|
|
304
|
+
// Normalise pattern names and strip BBoM (shown on node, not in badge).
|
|
305
|
+
// Also strip Supplier/Customer when they are already expressed as the role letter
|
|
306
|
+
// to prevent duplicate annotations like "S S" or "C C".
|
|
243
307
|
const badgePatterns = patterns
|
|
244
|
-
.filter((p) => !
|
|
245
|
-
.
|
|
308
|
+
.filter((p) => !isBBoMSidePattern(p))
|
|
309
|
+
.filter((p) => !(role === 'S' && p.$type === 'Supplier'))
|
|
310
|
+
.filter((p) => !(role === 'C' && p.$type === 'Customer'))
|
|
311
|
+
.map(normalizePatternNode);
|
|
246
312
|
|
|
247
313
|
if (!role && badgePatterns.length === 0) {
|
|
248
314
|
return;
|
|
@@ -278,25 +344,21 @@ export class DomainLangContextMapDiagramGenerator extends LangiumDiagramGenerato
|
|
|
278
344
|
* For `<->` without explicit type, defaults to "Partnership".
|
|
279
345
|
* For `><`, defaults to "Separate Ways".
|
|
280
346
|
*/
|
|
281
|
-
private
|
|
282
|
-
if (
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
if (arrow === '<->') {
|
|
286
|
-
return 'Partnership';
|
|
287
|
-
}
|
|
288
|
-
if (arrow === '><') {
|
|
289
|
-
return 'Separate Ways';
|
|
290
|
-
}
|
|
291
|
-
return undefined;
|
|
347
|
+
private formatRelationshipKind(kind: string | undefined): string | undefined {
|
|
348
|
+
if (!kind) return undefined;
|
|
349
|
+
return this.displayRelationshipKind(kind);
|
|
292
350
|
}
|
|
293
351
|
|
|
294
|
-
private
|
|
295
|
-
switch (
|
|
296
|
-
|
|
352
|
+
private displayRelationshipKind(kind: string): string | undefined {
|
|
353
|
+
switch (kind) {
|
|
354
|
+
// Directional kinds are already conveyed by U/D and C/S role badges — no center label needed
|
|
355
|
+
case 'CustomerSupplier': return undefined;
|
|
356
|
+
case 'UpstreamDownstream': return undefined;
|
|
357
|
+
// Symmetric and bidirectional kinds have no role badges, so label them explicitly
|
|
297
358
|
case 'SharedKernel': return 'Shared Kernel';
|
|
298
|
-
case '
|
|
299
|
-
|
|
359
|
+
case 'SeparateWays': return 'Separate Ways';
|
|
360
|
+
case 'Partnership': return 'Partnership';
|
|
361
|
+
default: return kind;
|
|
300
362
|
}
|
|
301
363
|
}
|
|
302
364
|
|
package/src/domain-lang.langium
CHANGED
|
@@ -204,17 +204,53 @@ DomainMap:
|
|
|
204
204
|
|
|
205
205
|
/**
|
|
206
206
|
* Relationship - Connection between two Bounded Contexts.
|
|
207
|
-
*
|
|
207
|
+
* Uses entity–relationship–entity structure where the relationship expression
|
|
208
|
+
* (type, arrow, side annotations) sits between the two entity references.
|
|
209
|
+
*
|
|
210
|
+
* Forms:
|
|
211
|
+
* Directional: Orders [OHS] -> [CF] Payments
|
|
212
|
+
* Symmetric: CardManagement [SK] AccountManagement
|
|
213
|
+
* Separate Ways arrow: Orders >< Payments
|
|
208
214
|
*
|
|
209
215
|
* [Read more on domainlang.net](https://domainlang.net/reference/language#relationships)
|
|
210
216
|
*/
|
|
211
217
|
Relationship:
|
|
212
|
-
|
|
218
|
+
DirectionalRelationship | SymmetricRelationship
|
|
219
|
+
;
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Directional relationship - upstream/downstream with optional side patterns.
|
|
223
|
+
*
|
|
224
|
+
* Examples:
|
|
225
|
+
* Orders [OHS] -> [CF] Payments
|
|
226
|
+
* Orders [S] -> [C] Payments
|
|
227
|
+
* Orders -> Payments
|
|
228
|
+
* Orders [OHS] <-> [CF] Payments
|
|
229
|
+
*/
|
|
230
|
+
DirectionalRelationship:
|
|
231
|
+
left=BoundedContextRef
|
|
232
|
+
('[' leftPatterns+=SidePattern (',' leftPatterns+=SidePattern)* ']')?
|
|
233
|
+
arrow=DirectionalArrow
|
|
234
|
+
('[' rightPatterns+=SidePattern (',' rightPatterns+=SidePattern)* ']')?
|
|
235
|
+
right=BoundedContextRef
|
|
236
|
+
;
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Symmetric relationship - mutual pattern between two contexts, no directionality.
|
|
240
|
+
*
|
|
241
|
+
* Examples:
|
|
242
|
+
* CardManagement [SK] AccountManagement
|
|
243
|
+
* Orders [P] Payments
|
|
244
|
+
* Orders >< Payments
|
|
245
|
+
* Orders [SW] Payments
|
|
246
|
+
*/
|
|
247
|
+
SymmetricRelationship:
|
|
213
248
|
left=BoundedContextRef
|
|
214
|
-
|
|
215
|
-
|
|
249
|
+
(
|
|
250
|
+
'[' pattern=SymmetricPattern ']'
|
|
251
|
+
| arrow='><'
|
|
252
|
+
)
|
|
216
253
|
right=BoundedContextRef
|
|
217
|
-
(Assignment type=RelationshipType)?
|
|
218
254
|
;
|
|
219
255
|
|
|
220
256
|
/**
|
|
@@ -225,40 +261,40 @@ BoundedContextRef:
|
|
|
225
261
|
;
|
|
226
262
|
|
|
227
263
|
/**
|
|
228
|
-
*
|
|
264
|
+
* Directional relationship arrows.
|
|
229
265
|
*
|
|
230
266
|
* Arrow semantics:
|
|
231
267
|
* -> Upstream to downstream (left provides, right consumes)
|
|
232
268
|
* <- Downstream to upstream (right provides, left consumes)
|
|
233
|
-
* <-> Bidirectional
|
|
234
|
-
* >< Separate Ways (no integration, teams go their own way)
|
|
269
|
+
* <-> Bidirectional (mutual data flow with explicit patterns)
|
|
235
270
|
*/
|
|
236
|
-
|
|
237
|
-
'<->' | '->' | '<-'
|
|
271
|
+
DirectionalArrow returns string:
|
|
272
|
+
'<->' | '->' | '<-'
|
|
238
273
|
;
|
|
239
274
|
|
|
240
275
|
/**
|
|
241
|
-
* DDD
|
|
276
|
+
* DDD Side Patterns - describe one side's role in a directional relationship.
|
|
277
|
+
* Each pattern produces a distinct AST node type via {infer} actions.
|
|
278
|
+
* Short and long forms parse to the same node type.
|
|
242
279
|
*/
|
|
243
|
-
|
|
244
|
-
'
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
280
|
+
SidePattern:
|
|
281
|
+
{infer OpenHostService} ('OHS' | 'OpenHostService')
|
|
282
|
+
| {infer PublishedLanguage} ('PL' | 'PublishedLanguage')
|
|
283
|
+
| {infer Conformist} ('CF' | 'Conformist')
|
|
284
|
+
| {infer AntiCorruptionLayer} ('ACL' | 'AntiCorruptionLayer')
|
|
285
|
+
| {infer Supplier} ('S' | 'Supplier')
|
|
286
|
+
| {infer Customer} ('C' | 'Customer')
|
|
287
|
+
| {infer BigBallOfMud} ('BBoM'| 'BigBallOfMud')
|
|
251
288
|
;
|
|
252
289
|
|
|
253
290
|
/**
|
|
254
|
-
* DDD
|
|
291
|
+
* DDD Symmetric Patterns - describe the relationship between two contexts.
|
|
292
|
+
* These are mutual/shared patterns, not directional.
|
|
255
293
|
*/
|
|
256
|
-
|
|
257
|
-
'
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
| 'UpstreamDownstream'
|
|
261
|
-
| 'SeparateWays'
|
|
294
|
+
SymmetricPattern:
|
|
295
|
+
{infer SharedKernel} ('SK' | 'SharedKernel')
|
|
296
|
+
| {infer Partnership} ('P' | 'Partnership')
|
|
297
|
+
| {infer SeparateWays} ('SW' | 'SeparateWays')
|
|
262
298
|
;
|
|
263
299
|
|
|
264
300
|
// ============================================================================
|