@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.
- package/README.md +32 -0
- package/out/ast-augmentation.d.ts +6 -0
- package/out/ast-augmentation.js +2 -0
- package/out/ast-augmentation.js.map +1 -0
- package/out/domain-lang-module.d.ts +55 -0
- package/out/domain-lang-module.js +59 -0
- package/out/domain-lang-module.js.map +1 -0
- package/out/generated/ast.d.ts +770 -0
- package/out/generated/ast.js +565 -0
- package/out/generated/ast.js.map +1 -0
- package/out/generated/grammar.d.ts +6 -0
- package/out/generated/grammar.js +2502 -0
- package/out/generated/grammar.js.map +1 -0
- package/out/generated/module.d.ts +13 -0
- package/out/generated/module.js +21 -0
- package/out/generated/module.js.map +1 -0
- package/out/index.d.ts +13 -0
- package/out/index.js +17 -0
- package/out/index.js.map +1 -0
- package/out/lsp/domain-lang-completion.d.ts +37 -0
- package/out/lsp/domain-lang-completion.js +452 -0
- package/out/lsp/domain-lang-completion.js.map +1 -0
- package/out/lsp/domain-lang-formatter.d.ts +15 -0
- package/out/lsp/domain-lang-formatter.js +43 -0
- package/out/lsp/domain-lang-formatter.js.map +1 -0
- package/out/lsp/domain-lang-naming.d.ts +34 -0
- package/out/lsp/domain-lang-naming.js +49 -0
- package/out/lsp/domain-lang-naming.js.map +1 -0
- package/out/lsp/domain-lang-scope.d.ts +59 -0
- package/out/lsp/domain-lang-scope.js +102 -0
- package/out/lsp/domain-lang-scope.js.map +1 -0
- package/out/lsp/hover/ddd-pattern-explanations.d.ts +50 -0
- package/out/lsp/hover/ddd-pattern-explanations.js +196 -0
- package/out/lsp/hover/ddd-pattern-explanations.js.map +1 -0
- package/out/lsp/hover/domain-lang-hover.d.ts +19 -0
- package/out/lsp/hover/domain-lang-hover.js +306 -0
- package/out/lsp/hover/domain-lang-hover.js.map +1 -0
- package/out/lsp/hover/domain-lang-keywords.d.ts +13 -0
- package/out/lsp/hover/domain-lang-keywords.js +47 -0
- package/out/lsp/hover/domain-lang-keywords.js.map +1 -0
- package/out/main-browser.d.ts +1 -0
- package/out/main-browser.js +11 -0
- package/out/main-browser.js.map +1 -0
- package/out/main.d.ts +1 -0
- package/out/main.js +74 -0
- package/out/main.js.map +1 -0
- package/out/sdk/ast-augmentation.d.ts +136 -0
- package/out/sdk/ast-augmentation.js +62 -0
- package/out/sdk/ast-augmentation.js.map +1 -0
- package/out/sdk/index.d.ts +94 -0
- package/out/sdk/index.js +97 -0
- package/out/sdk/index.js.map +1 -0
- package/out/sdk/indexes.d.ts +16 -0
- package/out/sdk/indexes.js +97 -0
- package/out/sdk/indexes.js.map +1 -0
- package/out/sdk/loader-node.d.ts +47 -0
- package/out/sdk/loader-node.js +104 -0
- package/out/sdk/loader-node.js.map +1 -0
- package/out/sdk/loader.d.ts +49 -0
- package/out/sdk/loader.js +85 -0
- package/out/sdk/loader.js.map +1 -0
- package/out/sdk/patterns.d.ts +93 -0
- package/out/sdk/patterns.js +123 -0
- package/out/sdk/patterns.js.map +1 -0
- package/out/sdk/query.d.ts +90 -0
- package/out/sdk/query.js +679 -0
- package/out/sdk/query.js.map +1 -0
- package/out/sdk/resolution.d.ts +52 -0
- package/out/sdk/resolution.js +68 -0
- package/out/sdk/resolution.js.map +1 -0
- package/out/sdk/types.d.ts +301 -0
- package/out/sdk/types.js +8 -0
- package/out/sdk/types.js.map +1 -0
- package/out/services/dependency-analyzer.d.ts +94 -0
- package/out/services/dependency-analyzer.js +279 -0
- package/out/services/dependency-analyzer.js.map +1 -0
- package/out/services/dependency-resolver.d.ts +123 -0
- package/out/services/dependency-resolver.js +252 -0
- package/out/services/dependency-resolver.js.map +1 -0
- package/out/services/git-url-resolver.browser.d.ts +18 -0
- package/out/services/git-url-resolver.browser.js +15 -0
- package/out/services/git-url-resolver.browser.js.map +1 -0
- package/out/services/git-url-resolver.d.ts +192 -0
- package/out/services/git-url-resolver.js +382 -0
- package/out/services/git-url-resolver.js.map +1 -0
- package/out/services/governance-validator.d.ts +80 -0
- package/out/services/governance-validator.js +159 -0
- package/out/services/governance-validator.js.map +1 -0
- package/out/services/import-resolver.d.ts +18 -0
- package/out/services/import-resolver.js +22 -0
- package/out/services/import-resolver.js.map +1 -0
- package/out/services/performance-optimizer.d.ts +60 -0
- package/out/services/performance-optimizer.js +140 -0
- package/out/services/performance-optimizer.js.map +1 -0
- package/out/services/relationship-inference.d.ts +11 -0
- package/out/services/relationship-inference.js +98 -0
- package/out/services/relationship-inference.js.map +1 -0
- package/out/services/workspace-manager.d.ts +76 -0
- package/out/services/workspace-manager.js +323 -0
- package/out/services/workspace-manager.js.map +1 -0
- package/out/syntaxes/domain-lang.monarch.d.ts +76 -0
- package/out/syntaxes/domain-lang.monarch.js +29 -0
- package/out/syntaxes/domain-lang.monarch.js.map +1 -0
- package/out/utils/import-utils.d.ts +57 -0
- package/out/utils/import-utils.js +228 -0
- package/out/utils/import-utils.js.map +1 -0
- package/out/validation/bounded-context.d.ts +11 -0
- package/out/validation/bounded-context.js +79 -0
- package/out/validation/bounded-context.js.map +1 -0
- package/out/validation/classification.d.ts +3 -0
- package/out/validation/classification.js +3 -0
- package/out/validation/classification.js.map +1 -0
- package/out/validation/constants.d.ts +77 -0
- package/out/validation/constants.js +96 -0
- package/out/validation/constants.js.map +1 -0
- package/out/validation/domain-lang-validator.d.ts +2 -0
- package/out/validation/domain-lang-validator.js +27 -0
- package/out/validation/domain-lang-validator.js.map +1 -0
- package/out/validation/domain.d.ts +11 -0
- package/out/validation/domain.js +18 -0
- package/out/validation/domain.js.map +1 -0
- package/out/validation/import.d.ts +44 -0
- package/out/validation/import.js +135 -0
- package/out/validation/import.js.map +1 -0
- package/out/validation/maps.d.ts +21 -0
- package/out/validation/maps.js +56 -0
- package/out/validation/maps.js.map +1 -0
- package/out/validation/metadata.d.ts +7 -0
- package/out/validation/metadata.js +12 -0
- package/out/validation/metadata.js.map +1 -0
- package/out/validation/model.d.ts +12 -0
- package/out/validation/model.js +29 -0
- package/out/validation/model.js.map +1 -0
- package/out/validation/relationships.d.ts +12 -0
- package/out/validation/relationships.js +94 -0
- package/out/validation/relationships.js.map +1 -0
- package/out/validation/shared.d.ts +6 -0
- package/out/validation/shared.js +12 -0
- package/out/validation/shared.js.map +1 -0
- package/package.json +97 -0
- package/src/ast-augmentation.ts +5 -0
- package/src/domain-lang-module.ts +100 -0
- package/src/domain-lang.langium +356 -0
- package/src/generated/ast.ts +999 -0
- package/src/generated/grammar.ts +2504 -0
- package/src/generated/module.ts +25 -0
- package/src/index.ts +17 -0
- package/src/lsp/domain-lang-completion.ts +514 -0
- package/src/lsp/domain-lang-formatter.ts +51 -0
- package/src/lsp/domain-lang-naming.ts +56 -0
- package/src/lsp/domain-lang-scope.ts +137 -0
- package/src/lsp/hover/ddd-pattern-explanations.ts +237 -0
- package/src/lsp/hover/domain-lang-hover.ts +340 -0
- package/src/lsp/hover/domain-lang-keywords.ts +50 -0
- package/src/main-browser.ts +15 -0
- package/src/main.ts +85 -0
- package/src/sdk/README.md +297 -0
- package/src/sdk/ast-augmentation.ts +157 -0
- package/src/sdk/index.ts +128 -0
- package/src/sdk/indexes.ts +155 -0
- package/src/sdk/loader-node.ts +126 -0
- package/src/sdk/loader.ts +99 -0
- package/src/sdk/patterns.ts +147 -0
- package/src/sdk/query.ts +802 -0
- package/src/sdk/resolution.ts +78 -0
- package/src/sdk/types.ts +346 -0
- package/src/services/dependency-analyzer.ts +381 -0
- package/src/services/dependency-resolver.ts +334 -0
- package/src/services/git-url-resolver.browser.ts +31 -0
- package/src/services/git-url-resolver.ts +524 -0
- package/src/services/governance-validator.ts +219 -0
- package/src/services/import-resolver.ts +30 -0
- package/src/services/performance-optimizer.ts +170 -0
- package/src/services/relationship-inference.ts +121 -0
- package/src/services/workspace-manager.ts +416 -0
- package/src/syntaxes/domain-lang.monarch.ts +29 -0
- package/src/utils/import-utils.ts +274 -0
- package/src/validation/bounded-context.ts +99 -0
- package/src/validation/classification.ts +5 -0
- package/src/validation/constants.ts +124 -0
- package/src/validation/domain-lang-validator.ts +33 -0
- package/src/validation/domain.ts +24 -0
- package/src/validation/import.ts +171 -0
- package/src/validation/maps.ts +72 -0
- package/src/validation/metadata.ts +14 -0
- package/src/validation/model.ts +37 -0
- package/src/validation/relationships.ts +154 -0
- package/src/validation/shared.ts +14 -0
|
@@ -0,0 +1,62 @@
|
|
|
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
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=ast-augmentation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-augmentation.js","sourceRoot":"","sources":["../../src/sdk/ast-augmentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG"}
|
|
@@ -0,0 +1,94 @@
|
|
|
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
|
+
export { loadModelFromText } from './loader.js';
|
|
91
|
+
export { fromModel, fromDocument, fromServices, augmentModel } from './query.js';
|
|
92
|
+
export { Pattern, PatternFullName, PatternAliases, matchesPattern, isUpstreamPattern, isDownstreamPattern, isMutualPattern, UpstreamPatterns, DownstreamPatterns, MutualPatterns, } from './patterns.js';
|
|
93
|
+
export type { IntegrationPattern } from './patterns.js';
|
|
94
|
+
export type { Query, QueryBuilder, QueryContext, LoadOptions, BcQueryBuilder, RelationshipView, AugmentedBoundedContext, AugmentedDomain, } from './types.js';
|
package/out/sdk/index.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
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
|
+
// Browser-safe entry points
|
|
91
|
+
export { loadModelFromText } from './loader.js';
|
|
92
|
+
export { fromModel, fromDocument, fromServices, augmentModel } from './query.js';
|
|
93
|
+
// Note: loadModel() is NOT exported here - it requires Node.js filesystem
|
|
94
|
+
// For CLI/Node.js usage: import { loadModel } from '@domainlang/language/sdk/loader-node';
|
|
95
|
+
// Integration patterns for type-safe pattern matching (no magic strings)
|
|
96
|
+
export { Pattern, PatternFullName, PatternAliases, matchesPattern, isUpstreamPattern, isDownstreamPattern, isMutualPattern, UpstreamPatterns, DownstreamPatterns, MutualPatterns, } from './patterns.js';
|
|
97
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sdk/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AAEH,4BAA4B;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEjF,0EAA0E;AAC1E,2FAA2F;AAE3F,yEAAyE;AACzE,OAAO,EACH,OAAO,EACP,eAAe,EACf,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,GACjB,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Index building for O(1) lookups in the Model Query SDK.
|
|
3
|
+
* Builds maps for FQN, name, team, strategic classification, and metadata lookups.
|
|
4
|
+
*
|
|
5
|
+
* Indexes are built once during model loading and enable fast queries.
|
|
6
|
+
*/
|
|
7
|
+
import type { Model } from '../generated/ast.js';
|
|
8
|
+
import type { ModelIndexes } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Builds all indexes for a model.
|
|
11
|
+
* Called once during model loading.
|
|
12
|
+
*
|
|
13
|
+
* @param model - Root model node
|
|
14
|
+
* @returns ModelIndexes containing all lookup maps
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildIndexes(model: Model): ModelIndexes;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Index building for O(1) lookups in the Model Query SDK.
|
|
3
|
+
* Builds maps for FQN, name, team, strategic classification, and metadata lookups.
|
|
4
|
+
*
|
|
5
|
+
* Indexes are built once during model loading and enable fast queries.
|
|
6
|
+
*/
|
|
7
|
+
import { AstUtils } from 'langium';
|
|
8
|
+
import { isBoundedContext, isClassification, isContextMap, isDomain, isDomainMap, isMetadata, isNamespaceDeclaration, isTeam, } from '../generated/ast.js';
|
|
9
|
+
import { QualifiedNameProvider } from '../lsp/domain-lang-naming.js';
|
|
10
|
+
import { metadataAsMap, effectiveClassification, effectiveTeam, } from './resolution.js';
|
|
11
|
+
/**
|
|
12
|
+
* Builds all indexes for a model.
|
|
13
|
+
* Called once during model loading.
|
|
14
|
+
*
|
|
15
|
+
* @param model - Root model node
|
|
16
|
+
* @returns ModelIndexes containing all lookup maps
|
|
17
|
+
*/
|
|
18
|
+
export function buildIndexes(model) {
|
|
19
|
+
const byFqn = new Map();
|
|
20
|
+
const byName = new Map();
|
|
21
|
+
const byTeam = new Map();
|
|
22
|
+
const byClassification = new Map();
|
|
23
|
+
const byMetadataKey = new Map();
|
|
24
|
+
const fqnProvider = new QualifiedNameProvider();
|
|
25
|
+
// Stream all AST nodes and index them
|
|
26
|
+
for (const node of AstUtils.streamAllContents(model)) {
|
|
27
|
+
// Index named types only
|
|
28
|
+
if (!hasName(node)) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const name = node.name;
|
|
32
|
+
const fqn = fqnProvider.getQualifiedName(node.$container, name);
|
|
33
|
+
// Index by FQN (unique)
|
|
34
|
+
byFqn.set(fqn, node);
|
|
35
|
+
// Index by simple name (may have duplicates)
|
|
36
|
+
const nameList = byName.get(name) ?? [];
|
|
37
|
+
nameList.push(node);
|
|
38
|
+
byName.set(name, nameList);
|
|
39
|
+
// BoundedContext-specific indexes
|
|
40
|
+
if (isBoundedContext(node)) {
|
|
41
|
+
indexBoundedContext(node, byTeam, byClassification, byMetadataKey);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
byFqn,
|
|
46
|
+
byName,
|
|
47
|
+
byTeam,
|
|
48
|
+
byClassification,
|
|
49
|
+
byMetadataKey,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Indexes a BoundedContext by team, strategic classification, and metadata.
|
|
54
|
+
*
|
|
55
|
+
* @param bc - BoundedContext node
|
|
56
|
+
* @param byTeam - Team index map
|
|
57
|
+
* @param byClassification - Strategic classification index map
|
|
58
|
+
* @param byMetadataKey - Metadata key index map
|
|
59
|
+
*/
|
|
60
|
+
function indexBoundedContext(bc, byTeam, byClassification, byMetadataKey) {
|
|
61
|
+
// Index by team
|
|
62
|
+
const team = effectiveTeam(bc);
|
|
63
|
+
if (team?.name) {
|
|
64
|
+
const teamList = byTeam.get(team.name) ?? [];
|
|
65
|
+
teamList.push(bc);
|
|
66
|
+
byTeam.set(team.name, teamList);
|
|
67
|
+
}
|
|
68
|
+
// Index by strategic classification
|
|
69
|
+
const classification = effectiveClassification(bc);
|
|
70
|
+
if (classification?.name) {
|
|
71
|
+
const classificationList = byClassification.get(classification.name) ?? [];
|
|
72
|
+
classificationList.push(bc);
|
|
73
|
+
byClassification.set(classification.name, classificationList);
|
|
74
|
+
}
|
|
75
|
+
// Index by metadata keys
|
|
76
|
+
const metadata = metadataAsMap(bc);
|
|
77
|
+
for (const key of metadata.keys()) {
|
|
78
|
+
const metaList = byMetadataKey.get(key) ?? [];
|
|
79
|
+
metaList.push(bc);
|
|
80
|
+
byMetadataKey.set(key, metaList);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Type guard for named AST nodes.
|
|
85
|
+
* Only these types are indexed by name.
|
|
86
|
+
*/
|
|
87
|
+
function hasName(node) {
|
|
88
|
+
return (isDomain(node) ||
|
|
89
|
+
isBoundedContext(node) ||
|
|
90
|
+
isTeam(node) ||
|
|
91
|
+
isClassification(node) ||
|
|
92
|
+
isContextMap(node) ||
|
|
93
|
+
isDomainMap(node) ||
|
|
94
|
+
isNamespaceDeclaration(node) ||
|
|
95
|
+
isMetadata(node));
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=indexes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexes.js","sourceRoot":"","sources":["../../src/sdk/indexes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAYnC,OAAO,EACH,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,UAAU,EACV,sBAAsB,EACtB,MAAM,GACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAErE,OAAO,EACH,aAAa,EACb,uBAAuB,EACvB,aAAa,GAChB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,KAAY;IACrC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IACnD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA4B,CAAC;IAC7D,MAAM,aAAa,GAAG,IAAI,GAAG,EAA4B,CAAC;IAE1D,MAAM,WAAW,GAAG,IAAI,qBAAqB,EAAE,CAAC;IAEhD,sCAAsC;IACtC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,yBAAyB;QACzB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACjB,SAAS;QACb,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,MAAM,GAAG,GAAG,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAEhE,wBAAwB;QACxB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAErB,6CAA6C;QAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACxC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAE3B,kCAAkC;QAClC,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC;QACvE,CAAC;IACL,CAAC;IAED,OAAO;QACH,KAAK;QACL,MAAM;QACN,MAAM;QACN,gBAAgB;QAChB,aAAa;KAChB,CAAC;AACN,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,mBAAmB,CACxB,EAAkB,EAClB,MAAqC,EACrC,gBAA+C,EAC/C,aAA4C;IAE5C,gBAAgB;IAChB,MAAM,IAAI,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;IAC/B,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC;QACb,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC7C,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED,oCAAoC;IACpC,MAAM,cAAc,GAAG,uBAAuB,CAAC,EAAE,CAAC,CAAC;IACnD,IAAI,cAAc,EAAE,IAAI,EAAE,CAAC;QACvB,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC3E,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5B,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IAClE,CAAC;IAED,yBAAyB;IACzB,MAAM,QAAQ,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;IACnC,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClB,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,IAAa;IAC1B,OAAO,CACH,QAAQ,CAAC,IAAI,CAAC;QACd,gBAAgB,CAAC,IAAI,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC;QACZ,gBAAgB,CAAC,IAAI,CAAC;QACtB,YAAY,CAAC,IAAI,CAAC;QAClB,WAAW,CAAC,IAAI,CAAC;QACjB,sBAAsB,CAAC,IAAI,CAAC;QAC5B,UAAU,CAAC,IAAI,CAAC,CACnB,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js-specific loader for DomainLang models.
|
|
3
|
+
*
|
|
4
|
+
* **WARNING: This module is NOT browser-compatible.**
|
|
5
|
+
*
|
|
6
|
+
* For browser environments, use:
|
|
7
|
+
* - `fromDocument()` with documents from the LSP
|
|
8
|
+
* - `fromModel()` with pre-parsed models
|
|
9
|
+
* - `loadModelFromText()` for in-memory parsing
|
|
10
|
+
*
|
|
11
|
+
* This loader creates **isolated Langium services** for standalone CLI usage.
|
|
12
|
+
* It does NOT integrate with an existing LSP workspace.
|
|
13
|
+
*
|
|
14
|
+
* For full workspace management with cross-file imports:
|
|
15
|
+
* - Use the WorkspaceManager service
|
|
16
|
+
* - Or host the LSP server and use its services
|
|
17
|
+
*
|
|
18
|
+
* @module sdk/loader-node
|
|
19
|
+
*/
|
|
20
|
+
import type { LoadOptions, QueryContext } from './types.js';
|
|
21
|
+
/**
|
|
22
|
+
* Loads a DomainLang model from a file on disk.
|
|
23
|
+
*
|
|
24
|
+
* **Node.js only** - uses file system APIs.
|
|
25
|
+
*
|
|
26
|
+
* Note: This loads a single file. For multi-file models with imports,
|
|
27
|
+
* consider using the WorkspaceManager or hosting an LSP server.
|
|
28
|
+
*
|
|
29
|
+
* @param entryFile - Path to the entry .dlang file
|
|
30
|
+
* @param options - Optional load configuration
|
|
31
|
+
* @returns QueryContext with model, documents, and query API
|
|
32
|
+
* @throws Error if file cannot be loaded or parsing fails
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* import { loadModel } from '@domainlang/language/sdk/loader-node';
|
|
37
|
+
*
|
|
38
|
+
* const { query, model } = await loadModel('./domains.dlang', {
|
|
39
|
+
* workspaceDir: process.cwd()
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* for (const bc of query.boundedContexts()) {
|
|
43
|
+
* console.log(bc.name);
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare function loadModel(entryFile: string, options?: LoadOptions): Promise<QueryContext>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js-specific loader for DomainLang models.
|
|
3
|
+
*
|
|
4
|
+
* **WARNING: This module is NOT browser-compatible.**
|
|
5
|
+
*
|
|
6
|
+
* For browser environments, use:
|
|
7
|
+
* - `fromDocument()` with documents from the LSP
|
|
8
|
+
* - `fromModel()` with pre-parsed models
|
|
9
|
+
* - `loadModelFromText()` for in-memory parsing
|
|
10
|
+
*
|
|
11
|
+
* This loader creates **isolated Langium services** for standalone CLI usage.
|
|
12
|
+
* It does NOT integrate with an existing LSP workspace.
|
|
13
|
+
*
|
|
14
|
+
* For full workspace management with cross-file imports:
|
|
15
|
+
* - Use the WorkspaceManager service
|
|
16
|
+
* - Or host the LSP server and use its services
|
|
17
|
+
*
|
|
18
|
+
* @module sdk/loader-node
|
|
19
|
+
*/
|
|
20
|
+
import { DocumentState, URI } from 'langium';
|
|
21
|
+
import { NodeFileSystem } from 'langium/node';
|
|
22
|
+
import { isModel } from '../generated/ast.js';
|
|
23
|
+
import { createDomainLangServices } from '../domain-lang-module.js';
|
|
24
|
+
import { fromModel, augmentModel } from './query.js';
|
|
25
|
+
/**
|
|
26
|
+
* Loads a DomainLang model from a file on disk.
|
|
27
|
+
*
|
|
28
|
+
* **Node.js only** - uses file system APIs.
|
|
29
|
+
*
|
|
30
|
+
* Note: This loads a single file. For multi-file models with imports,
|
|
31
|
+
* consider using the WorkspaceManager or hosting an LSP server.
|
|
32
|
+
*
|
|
33
|
+
* @param entryFile - Path to the entry .dlang file
|
|
34
|
+
* @param options - Optional load configuration
|
|
35
|
+
* @returns QueryContext with model, documents, and query API
|
|
36
|
+
* @throws Error if file cannot be loaded or parsing fails
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* import { loadModel } from '@domainlang/language/sdk/loader-node';
|
|
41
|
+
*
|
|
42
|
+
* const { query, model } = await loadModel('./domains.dlang', {
|
|
43
|
+
* workspaceDir: process.cwd()
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* for (const bc of query.boundedContexts()) {
|
|
47
|
+
* console.log(bc.name);
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export async function loadModel(entryFile, options) {
|
|
52
|
+
// Resolve absolute path
|
|
53
|
+
const path = await import('path');
|
|
54
|
+
const absolutePath = path.isAbsolute(entryFile)
|
|
55
|
+
? entryFile
|
|
56
|
+
: path.resolve(options?.workspaceDir ?? process.cwd(), entryFile);
|
|
57
|
+
// Create or reuse services
|
|
58
|
+
const servicesObj = options?.services
|
|
59
|
+
? { shared: options.services.shared, DomainLang: options.services }
|
|
60
|
+
: createDomainLangServices(NodeFileSystem);
|
|
61
|
+
const services = servicesObj.DomainLang;
|
|
62
|
+
const shared = servicesObj.shared;
|
|
63
|
+
// Initialize workspace if directory provided
|
|
64
|
+
if (options?.workspaceDir) {
|
|
65
|
+
const workspaceManager = services.imports.WorkspaceManager;
|
|
66
|
+
await workspaceManager.initialize(options.workspaceDir);
|
|
67
|
+
}
|
|
68
|
+
// Read file content and create document
|
|
69
|
+
const fs = await import('fs/promises');
|
|
70
|
+
const fileContent = await fs.readFile(absolutePath, 'utf-8');
|
|
71
|
+
const uri = URI.file(absolutePath);
|
|
72
|
+
// Use proper Langium document creation
|
|
73
|
+
const document = shared.workspace.LangiumDocumentFactory.fromString(fileContent, uri);
|
|
74
|
+
// Register document and build it
|
|
75
|
+
shared.workspace.LangiumDocuments.addDocument(document);
|
|
76
|
+
await shared.workspace.DocumentBuilder.build([document], { validation: true });
|
|
77
|
+
// Wait for document to be fully processed
|
|
78
|
+
if (document.state < DocumentState.Validated) {
|
|
79
|
+
throw new Error(`Document not fully processed: ${absolutePath}`);
|
|
80
|
+
}
|
|
81
|
+
// Check for parsing errors
|
|
82
|
+
if (document.parseResult.lexerErrors.length > 0) {
|
|
83
|
+
const errors = document.parseResult.lexerErrors.map(e => e.message).join('\n ');
|
|
84
|
+
throw new Error(`Lexer errors in ${entryFile}:\n ${errors}`);
|
|
85
|
+
}
|
|
86
|
+
if (document.parseResult.parserErrors.length > 0) {
|
|
87
|
+
const errors = document.parseResult.parserErrors.map(e => e.message).join('\n ');
|
|
88
|
+
throw new Error(`Parser errors in ${entryFile}:\n ${errors}`);
|
|
89
|
+
}
|
|
90
|
+
const model = document.parseResult.value;
|
|
91
|
+
if (!isModel(model)) {
|
|
92
|
+
throw new Error(`Document root is not a Model: ${entryFile}`);
|
|
93
|
+
}
|
|
94
|
+
// Augment AST nodes with SDK properties
|
|
95
|
+
augmentModel(model);
|
|
96
|
+
// Collect all document URIs
|
|
97
|
+
const documentUris = Array.from(shared.workspace.LangiumDocuments.all).map(doc => doc.uri);
|
|
98
|
+
return {
|
|
99
|
+
model,
|
|
100
|
+
documents: documentUris,
|
|
101
|
+
query: fromModel(model),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=loader-node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader-node.js","sourceRoot":"","sources":["../../src/sdk/loader-node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe loader for in-memory model parsing.
|
|
3
|
+
*
|
|
4
|
+
* This module provides `loadModelFromText()` which works in both
|
|
5
|
+
* browser and Node.js environments by using Langium's EmptyFileSystem.
|
|
6
|
+
*
|
|
7
|
+
* For file-based loading in Node.js CLI tools, use:
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { loadModel } from '@domainlang/language/sdk/loader-node';
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* For LSP/validation code that already has a linked AST, use the sync entry points:
|
|
13
|
+
* - `fromDocument()` - from a LangiumDocument
|
|
14
|
+
* - `fromModel()` - from a Model AST node
|
|
15
|
+
* - `fromServices()` - from DomainLangServices container
|
|
16
|
+
*
|
|
17
|
+
* @module sdk/loader
|
|
18
|
+
*/
|
|
19
|
+
import type { LoadOptions, QueryContext } from './types.js';
|
|
20
|
+
/**
|
|
21
|
+
* Loads a DomainLang model from a text string.
|
|
22
|
+
*
|
|
23
|
+
* **Browser-safe** - uses in-memory file system (EmptyFileSystem).
|
|
24
|
+
*
|
|
25
|
+
* Useful for:
|
|
26
|
+
* - Testing
|
|
27
|
+
* - REPL environments
|
|
28
|
+
* - Web-based editors
|
|
29
|
+
* - Any environment without file system access
|
|
30
|
+
*
|
|
31
|
+
* @param text - DomainLang source code
|
|
32
|
+
* @param options - Optional load configuration
|
|
33
|
+
* @returns QueryContext with model and query API
|
|
34
|
+
* @throws Error if parsing fails
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* import { loadModelFromText } from '@domainlang/language/sdk';
|
|
39
|
+
*
|
|
40
|
+
* const { query } = await loadModelFromText(`
|
|
41
|
+
* Domain Sales { vision: "Handle sales" }
|
|
42
|
+
* bc OrderContext for Sales
|
|
43
|
+
* `);
|
|
44
|
+
*
|
|
45
|
+
* const sales = query.domain('Sales');
|
|
46
|
+
* console.log(sales?.resolvedVision);
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function loadModelFromText(text: string, options?: LoadOptions): Promise<QueryContext>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe loader for in-memory model parsing.
|
|
3
|
+
*
|
|
4
|
+
* This module provides `loadModelFromText()` which works in both
|
|
5
|
+
* browser and Node.js environments by using Langium's EmptyFileSystem.
|
|
6
|
+
*
|
|
7
|
+
* For file-based loading in Node.js CLI tools, use:
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { loadModel } from '@domainlang/language/sdk/loader-node';
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* For LSP/validation code that already has a linked AST, use the sync entry points:
|
|
13
|
+
* - `fromDocument()` - from a LangiumDocument
|
|
14
|
+
* - `fromModel()` - from a Model AST node
|
|
15
|
+
* - `fromServices()` - from DomainLangServices container
|
|
16
|
+
*
|
|
17
|
+
* @module sdk/loader
|
|
18
|
+
*/
|
|
19
|
+
import { EmptyFileSystem, URI } from 'langium';
|
|
20
|
+
import { isModel } from '../generated/ast.js';
|
|
21
|
+
import { createDomainLangServices } from '../domain-lang-module.js';
|
|
22
|
+
import { augmentModel, fromModel } from './query.js';
|
|
23
|
+
/**
|
|
24
|
+
* Loads a DomainLang model from a text string.
|
|
25
|
+
*
|
|
26
|
+
* **Browser-safe** - uses in-memory file system (EmptyFileSystem).
|
|
27
|
+
*
|
|
28
|
+
* Useful for:
|
|
29
|
+
* - Testing
|
|
30
|
+
* - REPL environments
|
|
31
|
+
* - Web-based editors
|
|
32
|
+
* - Any environment without file system access
|
|
33
|
+
*
|
|
34
|
+
* @param text - DomainLang source code
|
|
35
|
+
* @param options - Optional load configuration
|
|
36
|
+
* @returns QueryContext with model and query API
|
|
37
|
+
* @throws Error if parsing fails
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* import { loadModelFromText } from '@domainlang/language/sdk';
|
|
42
|
+
*
|
|
43
|
+
* const { query } = await loadModelFromText(`
|
|
44
|
+
* Domain Sales { vision: "Handle sales" }
|
|
45
|
+
* bc OrderContext for Sales
|
|
46
|
+
* `);
|
|
47
|
+
*
|
|
48
|
+
* const sales = query.domain('Sales');
|
|
49
|
+
* console.log(sales?.resolvedVision);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export async function loadModelFromText(text, options) {
|
|
53
|
+
// Create or reuse services (use EmptyFileSystem for in-memory parsing)
|
|
54
|
+
const servicesObj = options?.services
|
|
55
|
+
? { shared: options.services.shared, DomainLang: options.services }
|
|
56
|
+
: createDomainLangServices(EmptyFileSystem);
|
|
57
|
+
const shared = servicesObj.shared;
|
|
58
|
+
// Create document from text with a virtual URI
|
|
59
|
+
const uri = URI.parse('memory:///model.dlang');
|
|
60
|
+
const document = shared.workspace.LangiumDocumentFactory.fromString(text, uri);
|
|
61
|
+
// Register and build document
|
|
62
|
+
shared.workspace.LangiumDocuments.addDocument(document);
|
|
63
|
+
await shared.workspace.DocumentBuilder.build([document], { validation: true });
|
|
64
|
+
// Check for parsing errors
|
|
65
|
+
if (document.parseResult.lexerErrors.length > 0) {
|
|
66
|
+
const errors = document.parseResult.lexerErrors.map(e => e.message).join('\n ');
|
|
67
|
+
throw new Error(`Lexer errors:\n ${errors}`);
|
|
68
|
+
}
|
|
69
|
+
if (document.parseResult.parserErrors.length > 0) {
|
|
70
|
+
const errors = document.parseResult.parserErrors.map(e => e.message).join('\n ');
|
|
71
|
+
throw new Error(`Parser errors:\n ${errors}`);
|
|
72
|
+
}
|
|
73
|
+
const model = document.parseResult.value;
|
|
74
|
+
if (!isModel(model)) {
|
|
75
|
+
throw new Error(`Document root is not a Model`);
|
|
76
|
+
}
|
|
77
|
+
// Augment AST nodes with SDK properties
|
|
78
|
+
augmentModel(model);
|
|
79
|
+
return {
|
|
80
|
+
model,
|
|
81
|
+
documents: [document.uri],
|
|
82
|
+
query: fromModel(model),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=loader.js.map
|