@domainlang/language 0.1.81

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 (188) hide show
  1. package/README.md +32 -0
  2. package/out/ast-augmentation.d.ts +6 -0
  3. package/out/ast-augmentation.js +2 -0
  4. package/out/ast-augmentation.js.map +1 -0
  5. package/out/domain-lang-module.d.ts +55 -0
  6. package/out/domain-lang-module.js +59 -0
  7. package/out/domain-lang-module.js.map +1 -0
  8. package/out/generated/ast.d.ts +770 -0
  9. package/out/generated/ast.js +565 -0
  10. package/out/generated/ast.js.map +1 -0
  11. package/out/generated/grammar.d.ts +6 -0
  12. package/out/generated/grammar.js +2502 -0
  13. package/out/generated/grammar.js.map +1 -0
  14. package/out/generated/module.d.ts +13 -0
  15. package/out/generated/module.js +21 -0
  16. package/out/generated/module.js.map +1 -0
  17. package/out/index.d.ts +13 -0
  18. package/out/index.js +17 -0
  19. package/out/index.js.map +1 -0
  20. package/out/lsp/domain-lang-completion.d.ts +37 -0
  21. package/out/lsp/domain-lang-completion.js +452 -0
  22. package/out/lsp/domain-lang-completion.js.map +1 -0
  23. package/out/lsp/domain-lang-formatter.d.ts +15 -0
  24. package/out/lsp/domain-lang-formatter.js +43 -0
  25. package/out/lsp/domain-lang-formatter.js.map +1 -0
  26. package/out/lsp/domain-lang-naming.d.ts +34 -0
  27. package/out/lsp/domain-lang-naming.js +49 -0
  28. package/out/lsp/domain-lang-naming.js.map +1 -0
  29. package/out/lsp/domain-lang-scope.d.ts +59 -0
  30. package/out/lsp/domain-lang-scope.js +102 -0
  31. package/out/lsp/domain-lang-scope.js.map +1 -0
  32. package/out/lsp/hover/ddd-pattern-explanations.d.ts +50 -0
  33. package/out/lsp/hover/ddd-pattern-explanations.js +196 -0
  34. package/out/lsp/hover/ddd-pattern-explanations.js.map +1 -0
  35. package/out/lsp/hover/domain-lang-hover.d.ts +19 -0
  36. package/out/lsp/hover/domain-lang-hover.js +306 -0
  37. package/out/lsp/hover/domain-lang-hover.js.map +1 -0
  38. package/out/lsp/hover/domain-lang-keywords.d.ts +13 -0
  39. package/out/lsp/hover/domain-lang-keywords.js +47 -0
  40. package/out/lsp/hover/domain-lang-keywords.js.map +1 -0
  41. package/out/main-browser.d.ts +1 -0
  42. package/out/main-browser.js +11 -0
  43. package/out/main-browser.js.map +1 -0
  44. package/out/main.d.ts +1 -0
  45. package/out/main.js +74 -0
  46. package/out/main.js.map +1 -0
  47. package/out/sdk/ast-augmentation.d.ts +136 -0
  48. package/out/sdk/ast-augmentation.js +62 -0
  49. package/out/sdk/ast-augmentation.js.map +1 -0
  50. package/out/sdk/index.d.ts +94 -0
  51. package/out/sdk/index.js +97 -0
  52. package/out/sdk/index.js.map +1 -0
  53. package/out/sdk/indexes.d.ts +16 -0
  54. package/out/sdk/indexes.js +97 -0
  55. package/out/sdk/indexes.js.map +1 -0
  56. package/out/sdk/loader-node.d.ts +47 -0
  57. package/out/sdk/loader-node.js +104 -0
  58. package/out/sdk/loader-node.js.map +1 -0
  59. package/out/sdk/loader.d.ts +49 -0
  60. package/out/sdk/loader.js +85 -0
  61. package/out/sdk/loader.js.map +1 -0
  62. package/out/sdk/patterns.d.ts +93 -0
  63. package/out/sdk/patterns.js +123 -0
  64. package/out/sdk/patterns.js.map +1 -0
  65. package/out/sdk/query.d.ts +90 -0
  66. package/out/sdk/query.js +679 -0
  67. package/out/sdk/query.js.map +1 -0
  68. package/out/sdk/resolution.d.ts +52 -0
  69. package/out/sdk/resolution.js +68 -0
  70. package/out/sdk/resolution.js.map +1 -0
  71. package/out/sdk/types.d.ts +301 -0
  72. package/out/sdk/types.js +8 -0
  73. package/out/sdk/types.js.map +1 -0
  74. package/out/services/dependency-analyzer.d.ts +94 -0
  75. package/out/services/dependency-analyzer.js +279 -0
  76. package/out/services/dependency-analyzer.js.map +1 -0
  77. package/out/services/dependency-resolver.d.ts +123 -0
  78. package/out/services/dependency-resolver.js +252 -0
  79. package/out/services/dependency-resolver.js.map +1 -0
  80. package/out/services/git-url-resolver.browser.d.ts +18 -0
  81. package/out/services/git-url-resolver.browser.js +15 -0
  82. package/out/services/git-url-resolver.browser.js.map +1 -0
  83. package/out/services/git-url-resolver.d.ts +192 -0
  84. package/out/services/git-url-resolver.js +382 -0
  85. package/out/services/git-url-resolver.js.map +1 -0
  86. package/out/services/governance-validator.d.ts +80 -0
  87. package/out/services/governance-validator.js +159 -0
  88. package/out/services/governance-validator.js.map +1 -0
  89. package/out/services/import-resolver.d.ts +18 -0
  90. package/out/services/import-resolver.js +22 -0
  91. package/out/services/import-resolver.js.map +1 -0
  92. package/out/services/performance-optimizer.d.ts +60 -0
  93. package/out/services/performance-optimizer.js +140 -0
  94. package/out/services/performance-optimizer.js.map +1 -0
  95. package/out/services/relationship-inference.d.ts +11 -0
  96. package/out/services/relationship-inference.js +98 -0
  97. package/out/services/relationship-inference.js.map +1 -0
  98. package/out/services/workspace-manager.d.ts +76 -0
  99. package/out/services/workspace-manager.js +323 -0
  100. package/out/services/workspace-manager.js.map +1 -0
  101. package/out/syntaxes/domain-lang.monarch.d.ts +76 -0
  102. package/out/syntaxes/domain-lang.monarch.js +29 -0
  103. package/out/syntaxes/domain-lang.monarch.js.map +1 -0
  104. package/out/utils/import-utils.d.ts +57 -0
  105. package/out/utils/import-utils.js +228 -0
  106. package/out/utils/import-utils.js.map +1 -0
  107. package/out/validation/bounded-context.d.ts +11 -0
  108. package/out/validation/bounded-context.js +79 -0
  109. package/out/validation/bounded-context.js.map +1 -0
  110. package/out/validation/classification.d.ts +3 -0
  111. package/out/validation/classification.js +3 -0
  112. package/out/validation/classification.js.map +1 -0
  113. package/out/validation/constants.d.ts +77 -0
  114. package/out/validation/constants.js +96 -0
  115. package/out/validation/constants.js.map +1 -0
  116. package/out/validation/domain-lang-validator.d.ts +2 -0
  117. package/out/validation/domain-lang-validator.js +27 -0
  118. package/out/validation/domain-lang-validator.js.map +1 -0
  119. package/out/validation/domain.d.ts +11 -0
  120. package/out/validation/domain.js +18 -0
  121. package/out/validation/domain.js.map +1 -0
  122. package/out/validation/import.d.ts +44 -0
  123. package/out/validation/import.js +135 -0
  124. package/out/validation/import.js.map +1 -0
  125. package/out/validation/maps.d.ts +21 -0
  126. package/out/validation/maps.js +56 -0
  127. package/out/validation/maps.js.map +1 -0
  128. package/out/validation/metadata.d.ts +7 -0
  129. package/out/validation/metadata.js +12 -0
  130. package/out/validation/metadata.js.map +1 -0
  131. package/out/validation/model.d.ts +12 -0
  132. package/out/validation/model.js +29 -0
  133. package/out/validation/model.js.map +1 -0
  134. package/out/validation/relationships.d.ts +12 -0
  135. package/out/validation/relationships.js +94 -0
  136. package/out/validation/relationships.js.map +1 -0
  137. package/out/validation/shared.d.ts +6 -0
  138. package/out/validation/shared.js +12 -0
  139. package/out/validation/shared.js.map +1 -0
  140. package/package.json +97 -0
  141. package/src/ast-augmentation.ts +5 -0
  142. package/src/domain-lang-module.ts +100 -0
  143. package/src/domain-lang.langium +356 -0
  144. package/src/generated/ast.ts +999 -0
  145. package/src/generated/grammar.ts +2504 -0
  146. package/src/generated/module.ts +25 -0
  147. package/src/index.ts +17 -0
  148. package/src/lsp/domain-lang-completion.ts +514 -0
  149. package/src/lsp/domain-lang-formatter.ts +51 -0
  150. package/src/lsp/domain-lang-naming.ts +56 -0
  151. package/src/lsp/domain-lang-scope.ts +137 -0
  152. package/src/lsp/hover/ddd-pattern-explanations.ts +237 -0
  153. package/src/lsp/hover/domain-lang-hover.ts +340 -0
  154. package/src/lsp/hover/domain-lang-keywords.ts +50 -0
  155. package/src/main-browser.ts +15 -0
  156. package/src/main.ts +85 -0
  157. package/src/sdk/README.md +297 -0
  158. package/src/sdk/ast-augmentation.ts +157 -0
  159. package/src/sdk/index.ts +128 -0
  160. package/src/sdk/indexes.ts +155 -0
  161. package/src/sdk/loader-node.ts +126 -0
  162. package/src/sdk/loader.ts +99 -0
  163. package/src/sdk/patterns.ts +147 -0
  164. package/src/sdk/query.ts +802 -0
  165. package/src/sdk/resolution.ts +78 -0
  166. package/src/sdk/types.ts +346 -0
  167. package/src/services/dependency-analyzer.ts +381 -0
  168. package/src/services/dependency-resolver.ts +334 -0
  169. package/src/services/git-url-resolver.browser.ts +31 -0
  170. package/src/services/git-url-resolver.ts +524 -0
  171. package/src/services/governance-validator.ts +219 -0
  172. package/src/services/import-resolver.ts +30 -0
  173. package/src/services/performance-optimizer.ts +170 -0
  174. package/src/services/relationship-inference.ts +121 -0
  175. package/src/services/workspace-manager.ts +416 -0
  176. package/src/syntaxes/domain-lang.monarch.ts +29 -0
  177. package/src/utils/import-utils.ts +274 -0
  178. package/src/validation/bounded-context.ts +99 -0
  179. package/src/validation/classification.ts +5 -0
  180. package/src/validation/constants.ts +124 -0
  181. package/src/validation/domain-lang-validator.ts +33 -0
  182. package/src/validation/domain.ts +24 -0
  183. package/src/validation/import.ts +171 -0
  184. package/src/validation/maps.ts +72 -0
  185. package/src/validation/metadata.ts +14 -0
  186. package/src/validation/model.ts +37 -0
  187. package/src/validation/relationships.ts +154 -0
  188. package/src/validation/shared.ts +14 -0
@@ -0,0 +1,297 @@
1
+ # Model Query SDK
2
+
3
+ Fluent, type-safe query API for DomainLang models.
4
+
5
+ ## SDK Architecture
6
+
7
+ The SDK is **read-only and query-focused**. It provides:
8
+
9
+ - Augmented AST properties (`effectiveClassification`, `effectiveTeam`, etc.)
10
+ - Fluent query chains with lazy iteration
11
+ - O(1) indexed lookups by FQN/name
12
+
13
+ The SDK does **NOT** manage:
14
+
15
+ - Workspace lifecycle (LSP/WorkspaceManager handles this)
16
+ - File watching or change detection (LSP handles this)
17
+ - Cross-file import resolution (DocumentBuilder handles this)
18
+
19
+ ## Entry Points by Deployment Target
20
+
21
+ | Target | Entry Point | Browser-Safe | Notes |
22
+ | --- | --- | --- | --- |
23
+ | VS Code Extension | `fromDocument()` | ✅ | Zero-copy LSP integration |
24
+ | Web Editor | `fromDocument()`, `loadModelFromText()` | ✅ | Browser-compatible |
25
+ | CLI (Node.js) | `loadModel()` | ❌ | Requires `sdk/loader-node` |
26
+ | Hosted LSP | `fromDocument()`, `fromServices()` | ✅ | Server-side |
27
+ | Testing | `loadModelFromText()` | ✅ | In-memory parsing |
28
+
29
+ ## Installation
30
+
31
+ The SDK is bundled with the `domain-lang-language` package:
32
+
33
+ ```typescript
34
+ // Browser-safe imports (VS Code, web editor, testing)
35
+ import { loadModelFromText, fromDocument, fromModel } from 'domain-lang-language/sdk';
36
+
37
+ // Node.js CLI only (NOT browser-safe)
38
+ import { loadModel } from 'domain-lang-language/sdk/loader-node';
39
+ ```
40
+
41
+ ## Entry Points
42
+
43
+ ### For Node.js CLI, Scripts
44
+
45
+ ```typescript
46
+ // Note: This import requires Node.js filesystem
47
+ import { loadModel } from 'domain-lang-language/sdk/loader-node';
48
+
49
+ // Load from file (async)
50
+ const { query, model } = await loadModel('./domains.dlang', {
51
+ workspaceDir: process.cwd()
52
+ });
53
+ ```
54
+
55
+ ### For Testing, REPL, Web Editor
56
+
57
+ ```typescript
58
+ import { loadModelFromText } from 'domain-lang-language/sdk';
59
+
60
+ // Load from string (async, browser-safe)
61
+ const { query } = await loadModelFromText(`
62
+ Domain Sales { vision: "Handle sales operations" }
63
+ bc OrderContext for Sales as Core
64
+ `);
65
+ ```
66
+
67
+ ### For LSP, Validation (Zero-Copy)
68
+
69
+ ```typescript
70
+ import { fromModel, fromDocument, fromServices } from 'domain-lang-language/sdk';
71
+
72
+ // From Model node (sync)
73
+ const query = fromModel(model);
74
+
75
+ // From LangiumDocument (sync)
76
+ const query = fromDocument(document);
77
+
78
+ // From services + URI (sync)
79
+ const query = fromServices(services, documentUri);
80
+ ```
81
+
82
+ ## Query API
83
+
84
+ ### Collections
85
+
86
+ ```typescript
87
+ // All bounded contexts
88
+ query.boundedContexts()
89
+
90
+ // All domains
91
+ query.domains()
92
+
93
+ // All teams
94
+ query.teams()
95
+
96
+ // All classifications
97
+ query.classifications()
98
+
99
+ // All relationships
100
+ query.relationships()
101
+
102
+ // All context maps
103
+ query.contextMaps()
104
+ ```
105
+
106
+ ### Fluent Chaining
107
+
108
+ ```typescript
109
+ // Filter by strategic classification
110
+ query.boundedContexts()
111
+ .withClassification('Core')
112
+ .withTeam('PaymentTeam')
113
+ .toArray()
114
+
115
+ // Filter by domain
116
+ query.boundedContexts()
117
+ .inDomain('Sales')
118
+ .withMetadata('Language', 'TypeScript')
119
+
120
+ // Custom predicates
121
+ query.domains()
122
+ .where(d => d.parent !== undefined)
123
+ .where(d => d.type?.ref?.name === 'Core') // Direct reference access
124
+ ```
125
+
126
+ ### Direct Lookups (O(1))
127
+
128
+ ```typescript
129
+ // By FQN
130
+ const bc = query.byFqn<BoundedContext>('Sales.OrderContext');
131
+
132
+ // By simple name
133
+ const domain = query.domain('Sales');
134
+ const context = query.boundedContext('OrderContext');
135
+
136
+ // Get FQN
137
+ const fqn = query.fqn(bc);
138
+ ```
139
+
140
+ ## SDK-Augmented Properties
141
+
142
+ The SDK augments AST nodes **only for properties that add value beyond direct access**:
143
+
144
+ ### BoundedContext
145
+
146
+ **Augmented (precedence resolution, transformation, computed):**
147
+
148
+ ```typescript
149
+ bc.effectiveClassification // Inline header (`as`) → body (`classification:`) precedence
150
+ bc.effectiveTeam // Inline header (`by`) → body (`team:`) precedence
151
+ bc.metadataMap // Metadata entries as ReadonlyMap<string, string>
152
+ bc.fqn // Computed fully qualified name
153
+ bc.hasClassification('Core') // Check if classification matches
154
+ bc.hasTeam('SalesTeam') // Check if team matches
155
+ bc.hasMetadata('Lang') // Check if metadata key exists
156
+ ```
157
+
158
+ **Direct AST access (no augmentation needed):**
159
+
160
+ ```typescript
161
+ bc.description // Direct string property
162
+ bc.businessModel?.ref // Direct reference to Classification
163
+ bc.evolution?.ref // Direct reference to Classification
164
+ bc.archetype?.ref // Direct reference to Classification
165
+ bc.relationships // Direct array of Relationship
166
+ bc.terminology // Direct array of DomainTerm
167
+ bc.decisions // Direct array of AbstractDecision
168
+ ```
169
+
170
+ ### Domain
171
+
172
+ **Augmented (computed):**
173
+
174
+ ```typescript
175
+ domain.fqn // Computed fully qualified name
176
+ domain.hasType('Core') // Check type matches
177
+ ```
178
+
179
+ **Direct AST access (no augmentation needed):**
180
+
181
+ ```typescript
182
+ domain.description // Direct string property
183
+ domain.vision // Direct string property
184
+ domain.type?.ref // Direct reference to Classification
185
+ ```
186
+
187
+ ## Examples
188
+
189
+ ### Find All Core Contexts with C# Stack
190
+
191
+ ```typescript
192
+ const { query } = await loadModel('./banking.dlang');
193
+
194
+ const results = query.boundedContexts()
195
+ .withClassification('Core')
196
+ .withMetadata('Language', 'CSharp')
197
+ .toArray();
198
+
199
+ for (const bc of results) {
200
+ console.log(`${bc.fqn}: ${bc.description ?? 'n/a'}`);
201
+ console.log(` Team: ${bc.effectiveTeam?.name ?? 'unassigned'}`);
202
+ console.log(` Evolution: ${bc.evolution?.ref?.name ?? 'n/a'}`);
203
+ }
204
+ ```
205
+
206
+ ### List All Relationships for a Domain
207
+
208
+ ```typescript
209
+ const sales = query.domain('Sales');
210
+
211
+ const relationships = query.relationships()
212
+ .where(rel =>
213
+ rel.left.domain?.ref?.name === 'Sales' ||
214
+ rel.right.domain?.ref?.name === 'Sales'
215
+ );
216
+
217
+ for (const rel of relationships) {
218
+ const type = rel.type ?? rel.inferredType ?? 'unknown';
219
+ console.log(`${rel.left.name} ${rel.arrow} ${rel.right.name} [${type}]`);
220
+ }
221
+ ```
222
+
223
+
224
+ ### Extract Documentation
225
+
226
+ ```typescript
227
+ const docs = query.boundedContexts()
228
+ .where(bc => bc.description !== undefined)
229
+ .toArray()
230
+ .map(bc => ({
231
+ fqn: bc.fqn,
232
+ description: bc.description,
233
+ team: bc.effectiveTeam?.name,
234
+ metadata: Object.fromEntries(bc.metadataMap),
235
+ }));
236
+
237
+ console.log(JSON.stringify(docs, null, 2));
238
+ ```
239
+
240
+ ## Resolution Rules
241
+
242
+ The SDK provides precedence resolution **only for properties with multiple assignment locations**:
243
+
244
+ | Augmented Property | Precedence | Why Augmented |
245
+ | --- | --- | --- |
246
+ | `bc.effectiveClassification` | Header inline (`as`) → body (`classification:`) | Array-based precedence |
247
+ | `bc.effectiveTeam` | Header inline (`by`) → body (`team:`) | Array-based precedence |
248
+ | `bc.metadataMap` | Later entries override earlier | Array to Map conversion |
249
+
250
+ **Direct access (no precedence needed):**
251
+
252
+ | Property | Access Pattern | Why Direct |
253
+ | --- | --- | --- |
254
+ | `bc.description` | Direct | Single location |
255
+ | `bc.businessModel?.ref` | Direct reference | Single location |
256
+ | `bc.evolution?.ref` | Direct reference | Single location |
257
+ | `bc.archetype?.ref` | Direct reference | Single location |
258
+ | `domain.description` | Direct | Single location |
259
+ | `domain.vision` | Direct | Single location |
260
+ | `domain.type?.ref` | Direct reference | Single location |
261
+
262
+ ## Performance
263
+
264
+ - **O(1) lookups**: `byFqn()`, indexed team/classification/metadata filters
265
+ - **Lazy iteration**: QueryBuilder chains don't materialize until consumed
266
+ - **Zero-copy**: `fromModel()` / `fromDocument()` reuse existing AST
267
+
268
+ ## Architecture
269
+
270
+ The SDK is an **internal module** within the language package:
271
+
272
+ ```text
273
+ packages/language/src/sdk/
274
+ ├── index.ts # Public API
275
+ ├── types.ts # Type definitions
276
+ ├── query.ts # Query & QueryBuilder
277
+ ├── resolution.ts # Property resolution (internal)
278
+ ├── indexes.ts # Index building (internal)
279
+ └── loader.ts # loadModel functions (internal)
280
+ ```
281
+
282
+ ### Internal vs Public
283
+
284
+ **Public** (exported from `sdk/index.ts`):
285
+
286
+ - `loadModel`, `loadModelFromText`
287
+ - `fromModel`, `fromDocument`, `fromServices`
288
+ - `Query`, `QueryBuilder`, `BcQueryBuilder`
289
+ - Type definitions
290
+
291
+ **Internal** (not exported):
292
+
293
+ - `effectiveClassification`, `effectiveTeam`, `metadataAsMap`, etc.
294
+ - `buildIndexes`, `buildFqnIndex`, etc.
295
+ - Implementation classes
296
+
297
+ Use SDK-augmented properties (`bc.effectiveClassification`) instead of calling resolution functions directly.
@@ -0,0 +1,157 @@
1
+ /**
2
+ * SDK AST Augmentation - Module augmentation for native SDK properties.
3
+ *
4
+ * This file uses TypeScript's declaration merging to add computed helpers
5
+ * directly to the AST types. After importing this module, BoundedContext,
6
+ * Domain, and Relationship instances expose convenience getters.
7
+ *
8
+ * **Only properties that add value beyond direct AST access are augmented:**
9
+ * - Precedence resolution: `effectiveClassification`, `effectiveTeam` (for array-based properties)
10
+ * - Data transformation: `metadataMap` (array to Map)
11
+ * - Computed values: `fqn` (fully qualified name)
12
+ * - Helper methods: `hasClassification()`, `hasTeam()`, `hasMetadata()`, `hasType()`
13
+ *
14
+ * **Direct AST access (no augmentation needed):**
15
+ * - `bc.description` - Direct string property
16
+ * - `bc.businessModel?.ref` - Direct reference
17
+ * - `bc.evolution?.ref` - Direct reference
18
+ * - `bc.archetype?.ref` - Direct reference
19
+ * - `domain.description` - Direct string property
20
+ * - `domain.vision` - Direct string property
21
+ * - `domain.type?.ref` - Direct reference
22
+ *
23
+ * **Usage:**
24
+ * ```typescript
25
+ * import '../sdk/ast-augmentation.js'; // Enable augmented properties
26
+ * import { fromDocument } from '../sdk/index.js';
27
+ *
28
+ * fromDocument(document); // Ensures augmentation
29
+ * const bc: BoundedContext = ...;
30
+ * console.log(bc.effectiveClassification?.name);
31
+ * console.log(bc.metadataMap.get('Language'));
32
+ * // Direct access for simple properties:
33
+ * console.log(bc.businessModel?.ref?.name);
34
+ * ```
35
+ *
36
+ * **Properties added to BoundedContext:**
37
+ * - `effectiveClassification` - Inline `as` header → body `classification:`
38
+ * - `effectiveTeam` - Inline `team` header → body `team:`
39
+ * - `metadataMap` - Metadata entries exposed as a ReadonlyMap
40
+ * - `fqn` - Computed fully qualified name
41
+ * - `hasClassification(name)` - Check if classification matches
42
+ * - `hasTeam(name)` - Check if team matches
43
+ * - `hasMetadata(key, value?)` - Check metadata
44
+ *
45
+ * **Properties added to Domain:**
46
+ * - `fqn` - Computed fully qualified name
47
+ * - `hasType(name)` - Check type matches
48
+ *
49
+ * **Properties added to Relationship:**
50
+ * - `hasPattern(pattern)` - Check if pattern exists on either side
51
+ * - `hasLeftPattern(pattern)` - Check left patterns
52
+ * - `hasRightPattern(pattern)` - Check right patterns
53
+ * - `isUpstream(side)` - Check if side is upstream
54
+ * - `isDownstream(side)` - Check if side is downstream
55
+ * - `isBidirectional` - Check if relationship is bidirectional
56
+ * - `leftContextName` - Resolved name of left context
57
+ * - `rightContextName` - Resolved name of right context
58
+ *
59
+ * @module sdk/ast-augmentation
60
+ */
61
+
62
+ // Note: Types are referenced directly via import('...').TypeName in the declare module
63
+ // to avoid importing and re-exporting type-only modules that cause compilation issues
64
+
65
+ /**
66
+ * Module augmentation for native SDK properties on AST types.
67
+ */
68
+ declare module '../generated/ast.js' {
69
+ /**
70
+ * Augmented BoundedContext with SDK-computed properties.
71
+ *
72
+ * Note: description, businessModel, evolution, archetype, metadata, relationships,
73
+ * terminology, and decisions are direct AST properties - use them directly.
74
+ */
75
+ interface BoundedContext {
76
+ /** Effective classification with inline precedence (header `as` > body `classification:`) */
77
+ readonly effectiveClassification: import('../generated/ast.js').Classification | undefined;
78
+
79
+ /** Effective team with inline precedence (header `by` > body `team:`) */
80
+ readonly effectiveTeam: import('../generated/ast.js').Team | undefined;
81
+
82
+ /** Metadata entries exposed as a map for O(1) lookups */
83
+ readonly metadataMap: ReadonlyMap<string, string>;
84
+
85
+ /** SDK-computed fully qualified name */
86
+ readonly fqn: string;
87
+
88
+ /** Checks if this bounded context has the specified classification. */
89
+ hasClassification(name: string | import('../generated/ast.js').Classification): boolean;
90
+
91
+ /** Checks if this bounded context is owned by the specified team. */
92
+ hasTeam(name: string | import('../generated/ast.js').Team): boolean;
93
+
94
+ /** Checks if this bounded context has metadata with the given key (and optionally value). */
95
+ hasMetadata(key: string, value?: string): boolean;
96
+ }
97
+
98
+ /**
99
+ * Augmented Domain with SDK-computed properties.
100
+ *
101
+ * Note: description, vision, and type are direct AST properties - use them directly.
102
+ */
103
+ interface Domain {
104
+ /** SDK-computed fully qualified name */
105
+ readonly fqn: string;
106
+
107
+ /** Checks if this domain has the specified type. */
108
+ hasType(name: string | import('../generated/ast.js').Classification): boolean;
109
+ }
110
+
111
+ /**
112
+ * Augmented Relationship with SDK helper methods.
113
+ */
114
+ interface Relationship {
115
+ /** Resolved name of left context (handles 'this') */
116
+ readonly leftContextName: string;
117
+ /** Resolved name of right context (handles 'this') */
118
+ readonly rightContextName: string;
119
+ /** Whether this is a bidirectional relationship (<->) */
120
+ readonly isBidirectional: boolean;
121
+
122
+ /**
123
+ * Checks if the relationship has a specific integration pattern on either side.
124
+ * Accepts both abbreviations (SK, ACL) and full names (SharedKernel, AntiCorruptionLayer).
125
+ * @param pattern - Pattern abbreviation or full name
126
+ */
127
+ hasPattern(pattern: import('./patterns.js').IntegrationPattern | string): boolean;
128
+
129
+ /**
130
+ * Checks if the left side has a specific integration pattern.
131
+ * @param pattern - Pattern abbreviation or full name
132
+ */
133
+ hasLeftPattern(pattern: import('./patterns.js').IntegrationPattern | string): boolean;
134
+
135
+ /**
136
+ * Checks if the right side has a specific integration pattern.
137
+ * @param pattern - Pattern abbreviation or full name
138
+ */
139
+ hasRightPattern(pattern: import('./patterns.js').IntegrationPattern | string): boolean;
140
+
141
+ /**
142
+ * Checks if the specified side is upstream (provider) in this relationship.
143
+ * @param side - 'left' or 'right'
144
+ */
145
+ isUpstream(side: 'left' | 'right'): boolean;
146
+
147
+ /**
148
+ * Checks if the specified side is downstream (consumer) in this relationship.
149
+ * @param side - 'left' or 'right'
150
+ */
151
+ isDownstream(side: 'left' | 'right'): boolean;
152
+ }
153
+ }
154
+
155
+ // Export nothing - this file is purely for type augmentation
156
+ // The actual implementation is in query.ts via Object.defineProperties
157
+ export {};
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Model Query SDK - Public API
3
+ *
4
+ * Provides fluent, type-safe query operations on DomainLang models.
5
+ *
6
+ * ## Architecture: SDK vs LSP Responsibilities
7
+ *
8
+ * The SDK is **read-only and query-focused**. It does NOT manage:
9
+ * - Workspace lifecycle (LSP/WorkspaceManager handles this)
10
+ * - File watching or change detection (LSP/TextDocuments handles this)
11
+ * - Cross-file import resolution (LSP/DocumentBuilder handles this)
12
+ * - Document validation scheduling (LSP handles this)
13
+ *
14
+ * **SDK responsibilities:**
15
+ * - Augmented AST properties (transparent property access with precedence rules)
16
+ * - Fluent query chains with lazy iteration
17
+ * - O(1) indexed lookups by FQN/name
18
+ * - Resolution rules (which block wins for 0..1 properties)
19
+ *
20
+ * **Entry points for different deployment targets:**
21
+ *
22
+ * | Target | Entry Point | Browser-Safe | Notes |
23
+ * |--------|-------------|--------------|-------|
24
+ * | VS Code Extension | `fromDocument()` | ✅ | Zero-copy LSP integration |
25
+ * | Web Editor | `fromDocument()`, `loadModelFromText()` | ✅ | Browser-compatible |
26
+ * | CLI (Node.js) | `loadModel()` from `sdk/loader-node` | ❌ | File system access |
27
+ * | Hosted LSP | `fromDocument()`, `fromServices()` | ✅ | Server-side only |
28
+ * | Testing | `loadModelFromText()` | ✅ | In-memory parsing |
29
+ *
30
+ * ## Browser vs Node.js
31
+ *
32
+ * This module (`sdk/index`) is **browser-safe** and exports only:
33
+ * - `loadModelFromText()` - uses EmptyFileSystem
34
+ * - `fromModel()`, `fromDocument()`, `fromServices()` - zero-copy wrappers
35
+ *
36
+ * For file-based loading in Node.js CLI tools:
37
+ * ```typescript
38
+ * import { loadModel } from 'domain-lang-language/sdk/loader-node';
39
+ * ```
40
+ *
41
+ * @packageDocumentation
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * // Node.js CLI: Load from file (requires sdk/loader-node)
46
+ * import { loadModel } from 'domain-lang-language/sdk/loader-node';
47
+ *
48
+ * const { query } = await loadModel('./domains.dlang', {
49
+ * workspaceDir: process.cwd()
50
+ * });
51
+ *
52
+ * const coreContexts = query.boundedContexts()
53
+ * .withClassification('Core')
54
+ * .withTeam('PaymentTeam');
55
+ *
56
+ * for (const bc of coreContexts) {
57
+ * console.log(`${bc.name}: ${bc.description ?? 'n/a'}`);
58
+ * }
59
+ * ```
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * // Browser/Testing: Load from text (browser-safe)
64
+ * import { loadModelFromText } from '@domainlang/language/sdk';
65
+ *
66
+ * const { query } = await loadModelFromText(`
67
+ * Domain Sales { vision: "Handle sales" }
68
+ * bc OrderContext for Sales
69
+ * `);
70
+ *
71
+ * const sales = query.domain('Sales');
72
+ * console.log(sales?.vision);
73
+ * ```
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * // LSP Integration: Zero-copy access to existing AST (browser-safe)
78
+ * import { fromDocument } from '@domainlang/language/sdk';
79
+ *
80
+ * export class HoverProvider {
81
+ * getHover(document: LangiumDocument<Model>) {
82
+ * // SDK wraps existing AST - no reloading, no file I/O
83
+ * const query = fromDocument(document);
84
+ * const bc = query.boundedContext('OrderContext');
85
+ * return bc?.description;
86
+ * }
87
+ * }
88
+ * ```
89
+ */
90
+
91
+ // Browser-safe entry points
92
+ export { loadModelFromText } from './loader.js';
93
+ export { fromModel, fromDocument, fromServices, augmentModel } from './query.js';
94
+
95
+ // Note: loadModel() is NOT exported here - it requires Node.js filesystem
96
+ // For CLI/Node.js usage: import { loadModel } from '@domainlang/language/sdk/loader-node';
97
+
98
+ // Integration patterns for type-safe pattern matching (no magic strings)
99
+ export {
100
+ Pattern,
101
+ PatternFullName,
102
+ PatternAliases,
103
+ matchesPattern,
104
+ isUpstreamPattern,
105
+ isDownstreamPattern,
106
+ isMutualPattern,
107
+ UpstreamPatterns,
108
+ DownstreamPatterns,
109
+ MutualPatterns,
110
+ } from './patterns.js';
111
+
112
+ export type { IntegrationPattern } from './patterns.js';
113
+
114
+ // AST augmentation - import for type declarations
115
+ // Usage: import '@domainlang/language/sdk/ast-augmentation';
116
+ // This enables native SDK properties on AST types via declaration merging
117
+
118
+ // Public types
119
+ export type {
120
+ Query,
121
+ QueryBuilder,
122
+ QueryContext,
123
+ LoadOptions,
124
+ BcQueryBuilder,
125
+ RelationshipView,
126
+ AugmentedBoundedContext,
127
+ AugmentedDomain,
128
+ } from './types.js';