@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.
Files changed (90) hide show
  1. package/out/ast-augmentation.d.ts +7 -2
  2. package/out/diagram/context-map-diagram-generator.d.ts +9 -2
  3. package/out/diagram/context-map-diagram-generator.js +112 -63
  4. package/out/diagram/context-map-diagram-generator.js.map +1 -1
  5. package/out/generated/ast.d.ts +323 -51
  6. package/out/generated/ast.js +194 -33
  7. package/out/generated/ast.js.map +1 -1
  8. package/out/generated/grammar.js +418 -172
  9. package/out/generated/grammar.js.map +1 -1
  10. package/out/lsp/domain-lang-completion.js +39 -15
  11. package/out/lsp/domain-lang-completion.js.map +1 -1
  12. package/out/lsp/domain-lang-formatter.js +32 -0
  13. package/out/lsp/domain-lang-formatter.js.map +1 -1
  14. package/out/lsp/domain-lang-index-manager.d.ts +2 -3
  15. package/out/lsp/domain-lang-index-manager.js +5 -8
  16. package/out/lsp/domain-lang-index-manager.js.map +1 -1
  17. package/out/lsp/domain-lang-workspace-manager.d.ts +1 -1
  18. package/out/lsp/domain-lang-workspace-manager.js +2 -26
  19. package/out/lsp/domain-lang-workspace-manager.js.map +1 -1
  20. package/out/lsp/explain.js +9 -3
  21. package/out/lsp/explain.js.map +1 -1
  22. package/out/lsp/hover/domain-lang-hover.js +13 -11
  23. package/out/lsp/hover/domain-lang-hover.js.map +1 -1
  24. package/out/lsp/hover/domain-lang-keywords.js +29 -26
  25. package/out/lsp/hover/domain-lang-keywords.js.map +1 -1
  26. package/out/sdk/ast-augmentation.d.ts +29 -21
  27. package/out/sdk/ast-augmentation.js +11 -7
  28. package/out/sdk/ast-augmentation.js.map +1 -1
  29. package/out/sdk/index.d.ts +2 -2
  30. package/out/sdk/index.js +1 -1
  31. package/out/sdk/index.js.map +1 -1
  32. package/out/sdk/loader-node.js +2 -2
  33. package/out/sdk/loader-node.js.map +1 -1
  34. package/out/sdk/patterns.d.ts +50 -61
  35. package/out/sdk/patterns.js +92 -62
  36. package/out/sdk/patterns.js.map +1 -1
  37. package/out/sdk/query.js +54 -43
  38. package/out/sdk/query.js.map +1 -1
  39. package/out/sdk/serializers.js +20 -7
  40. package/out/sdk/serializers.js.map +1 -1
  41. package/out/sdk/types.d.ts +87 -18
  42. package/out/sdk/types.js.map +1 -1
  43. package/out/sdk/validator.js +48 -64
  44. package/out/sdk/validator.js.map +1 -1
  45. package/out/services/performance-optimizer.d.ts +3 -3
  46. package/out/services/performance-optimizer.js +1 -3
  47. package/out/services/performance-optimizer.js.map +1 -1
  48. package/out/services/relationship-inference.d.ts +4 -4
  49. package/out/services/relationship-inference.js +34 -46
  50. package/out/services/relationship-inference.js.map +1 -1
  51. package/out/syntaxes/domain-lang.monarch.js +1 -1
  52. package/out/syntaxes/domain-lang.monarch.js.map +1 -1
  53. package/out/utils/import-utils.d.ts +6 -20
  54. package/out/utils/import-utils.js +3 -63
  55. package/out/utils/import-utils.js.map +1 -1
  56. package/out/validation/constants.d.ts +23 -6
  57. package/out/validation/constants.js +24 -7
  58. package/out/validation/constants.js.map +1 -1
  59. package/out/validation/maps.js +10 -4
  60. package/out/validation/maps.js.map +1 -1
  61. package/out/validation/relationships.d.ts +4 -8
  62. package/out/validation/relationships.js +96 -48
  63. package/out/validation/relationships.js.map +1 -1
  64. package/package.json +1 -1
  65. package/src/ast-augmentation.ts +7 -2
  66. package/src/diagram/context-map-diagram-generator.ts +132 -70
  67. package/src/domain-lang.langium +62 -26
  68. package/src/generated/ast.ts +413 -63
  69. package/src/generated/grammar.ts +418 -172
  70. package/src/lsp/domain-lang-completion.ts +42 -15
  71. package/src/lsp/domain-lang-formatter.ts +34 -0
  72. package/src/lsp/domain-lang-index-manager.ts +6 -9
  73. package/src/lsp/domain-lang-workspace-manager.ts +3 -29
  74. package/src/lsp/explain.ts +10 -2
  75. package/src/lsp/hover/domain-lang-hover.ts +10 -8
  76. package/src/lsp/hover/domain-lang-keywords.ts +27 -24
  77. package/src/sdk/ast-augmentation.ts +30 -21
  78. package/src/sdk/index.ts +11 -1
  79. package/src/sdk/loader-node.ts +2 -2
  80. package/src/sdk/patterns.ts +114 -76
  81. package/src/sdk/query.ts +57 -48
  82. package/src/sdk/serializers.ts +20 -7
  83. package/src/sdk/types.ts +92 -17
  84. package/src/sdk/validator.ts +52 -69
  85. package/src/services/performance-optimizer.ts +4 -6
  86. package/src/services/relationship-inference.ts +43 -54
  87. package/src/utils/import-utils.ts +9 -74
  88. package/src/validation/constants.ts +32 -9
  89. package/src/validation/maps.ts +12 -4
  90. 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 type { BoundedContext, ContextMap, Model, Relationship } from '../generated/ast.js';
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
- Partnership: 'P',
22
- SharedKernel: 'SK',
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 an integration pattern keyword.
31
+ * Returns the abbreviated form of a side pattern AST node.
28
32
  *
29
- * Short forms (e.g. `OHS`, `ACL`) are returned unchanged. Long forms (e.g.
30
- * `OpenHostService`, `AntiCorruptionLayer`) are mapped to their abbreviation.
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 normalizePattern(pattern: string): string {
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 isBBoMPattern(pattern: string): boolean {
43
- return pattern === 'BBoM' || pattern === 'BigBallOfMud';
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
- arrow: string;
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.leftPatterns.some(isBBoMPattern)) {
102
- bboMNodeKeys.add(this.getNodeKey(query, rel.left));
103
- }
104
- if (rel.rightPatterns.some(isBBoMPattern)) {
105
- bboMNodeKeys.add(this.getNodeKey(query, rel.right));
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
- arrow: relationship.arrow,
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, arrow, leftPatterns, rightPatterns, type, astNode } = params;
163
- // Determine source/target based on arrow direction
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 (arrow === '<->') {
175
- // Partnership / bidirectionalno U/D roles
176
- this.addUDBadge(children, edgeId, 'source', leftPatterns, undefined, args);
177
- this.addUDBadge(children, edgeId, 'target', rightPatterns, undefined, args);
178
- } else if (arrow === '><') {
179
- // Separate Ways — no U/D, no patterns
181
+ if (kind === 'Bidirectional') {
182
+ // No upstream/downstream rolesshow 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
- // Unidirectional: -> or <-
182
- const sourcePatterns = arrow === '<-' ? rightPatterns : leftPatterns;
183
- const targetPatterns = arrow === '<-' ? leftPatterns : rightPatterns;
184
- this.addUDBadge(children, edgeId, 'source', sourcePatterns, 'U', args);
185
- this.addUDBadge(children, edgeId, 'target', targetPatterns, 'D', args);
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 type
189
- const centerLabel = this.formatRelationshipType(type, arrow);
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 string[],
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) => !isBBoMPattern(p))
245
- .map(normalizePattern);
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 formatRelationshipType(type: string | undefined, arrow: string): string | undefined {
282
- if (type) {
283
- return this.displayRelationshipType(type);
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 displayRelationshipType(type: string): string {
295
- switch (type) {
296
- case 'CustomerSupplier': return 'Customer/Supplier';
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 'UpstreamDownstream': return 'Upstream/Downstream';
299
- default: return type;
359
+ case 'SeparateWays': return 'Separate Ways';
360
+ case 'Partnership': return 'Partnership';
361
+ default: return kind;
300
362
  }
301
363
  }
302
364
 
@@ -204,17 +204,53 @@ DomainMap:
204
204
 
205
205
  /**
206
206
  * Relationship - Connection between two Bounded Contexts.
207
- * Supports DDD integration patterns (ACL, OHS, PL, etc.) and relationship types.
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
- ('[' leftPatterns+=IntegrationPattern (',' leftPatterns+=IntegrationPattern)* ']')?
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
- arrow=RelationshipArrow
215
- ('[' rightPatterns+=IntegrationPattern (',' rightPatterns+=IntegrationPattern)* ']')?
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
- * Relationship arrows - symbolic and named types.
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/Partnership (mutual dependency)
234
- * >< Separate Ways (no integration, teams go their own way)
269
+ * <-> Bidirectional (mutual data flow with explicit patterns)
235
270
  */
236
- RelationshipArrow returns string:
237
- '<->' | '->' | '<-' | '><' // Separate Ways
271
+ DirectionalArrow returns string:
272
+ '<->' | '->' | '<-'
238
273
  ;
239
274
 
240
275
  /**
241
- * DDD Integration Patterns (used in relationships).
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
- IntegrationPattern returns string:
244
- 'PL' | 'PublishedLanguage' // Published Language
245
- | 'OHS' | 'OpenHostService' // Open Host Service
246
- | 'CF' | 'Conformist' // Conformist
247
- | 'ACL' | 'AntiCorruptionLayer' // Anti-Corruption Layer
248
- | 'P' | 'Partnership' // Partnership
249
- | 'SK' | 'SharedKernel' // Shared Kernel
250
- | 'BBoM' | 'BigBallOfMud' // Big Ball of Mud
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 Relationship Types.
291
+ * DDD Symmetric Patterns - describe the relationship between two contexts.
292
+ * These are mutual/shared patterns, not directional.
255
293
  */
256
- RelationshipType returns string:
257
- 'Partnership'
258
- | 'SharedKernel'
259
- | 'CustomerSupplier'
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
  // ============================================================================