@domainlang/language 0.1.20

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 (212) hide show
  1. package/README.md +163 -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 +57 -0
  6. package/out/domain-lang-module.js +67 -0
  7. package/out/domain-lang-module.js.map +1 -0
  8. package/out/generated/ast.d.ts +759 -0
  9. package/out/generated/ast.js +556 -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 +2407 -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 +16 -0
  18. package/out/index.js +22 -0
  19. package/out/index.js.map +1 -0
  20. package/out/lsp/domain-lang-code-actions.d.ts +55 -0
  21. package/out/lsp/domain-lang-code-actions.js +143 -0
  22. package/out/lsp/domain-lang-code-actions.js.map +1 -0
  23. package/out/lsp/domain-lang-completion.d.ts +37 -0
  24. package/out/lsp/domain-lang-completion.js +452 -0
  25. package/out/lsp/domain-lang-completion.js.map +1 -0
  26. package/out/lsp/domain-lang-formatter.d.ts +15 -0
  27. package/out/lsp/domain-lang-formatter.js +43 -0
  28. package/out/lsp/domain-lang-formatter.js.map +1 -0
  29. package/out/lsp/domain-lang-naming.d.ts +34 -0
  30. package/out/lsp/domain-lang-naming.js +49 -0
  31. package/out/lsp/domain-lang-naming.js.map +1 -0
  32. package/out/lsp/domain-lang-scope.d.ts +59 -0
  33. package/out/lsp/domain-lang-scope.js +102 -0
  34. package/out/lsp/domain-lang-scope.js.map +1 -0
  35. package/out/lsp/domain-lang-workspace-manager.d.ts +21 -0
  36. package/out/lsp/domain-lang-workspace-manager.js +93 -0
  37. package/out/lsp/domain-lang-workspace-manager.js.map +1 -0
  38. package/out/lsp/hover/ddd-pattern-explanations.d.ts +50 -0
  39. package/out/lsp/hover/ddd-pattern-explanations.js +196 -0
  40. package/out/lsp/hover/ddd-pattern-explanations.js.map +1 -0
  41. package/out/lsp/hover/domain-lang-hover.d.ts +19 -0
  42. package/out/lsp/hover/domain-lang-hover.js +302 -0
  43. package/out/lsp/hover/domain-lang-hover.js.map +1 -0
  44. package/out/lsp/hover/domain-lang-keywords.d.ts +13 -0
  45. package/out/lsp/hover/domain-lang-keywords.js +47 -0
  46. package/out/lsp/hover/domain-lang-keywords.js.map +1 -0
  47. package/out/lsp/manifest-diagnostics.d.ts +82 -0
  48. package/out/lsp/manifest-diagnostics.js +230 -0
  49. package/out/lsp/manifest-diagnostics.js.map +1 -0
  50. package/out/main-browser.d.ts +1 -0
  51. package/out/main-browser.js +11 -0
  52. package/out/main-browser.js.map +1 -0
  53. package/out/main.d.ts +1 -0
  54. package/out/main.js +74 -0
  55. package/out/main.js.map +1 -0
  56. package/out/sdk/ast-augmentation.d.ts +136 -0
  57. package/out/sdk/ast-augmentation.js +62 -0
  58. package/out/sdk/ast-augmentation.js.map +1 -0
  59. package/out/sdk/index.d.ts +94 -0
  60. package/out/sdk/index.js +97 -0
  61. package/out/sdk/index.js.map +1 -0
  62. package/out/sdk/indexes.d.ts +16 -0
  63. package/out/sdk/indexes.js +97 -0
  64. package/out/sdk/indexes.js.map +1 -0
  65. package/out/sdk/loader-node.d.ts +51 -0
  66. package/out/sdk/loader-node.js +119 -0
  67. package/out/sdk/loader-node.js.map +1 -0
  68. package/out/sdk/loader.d.ts +49 -0
  69. package/out/sdk/loader.js +85 -0
  70. package/out/sdk/loader.js.map +1 -0
  71. package/out/sdk/patterns.d.ts +93 -0
  72. package/out/sdk/patterns.js +123 -0
  73. package/out/sdk/patterns.js.map +1 -0
  74. package/out/sdk/query.d.ts +90 -0
  75. package/out/sdk/query.js +679 -0
  76. package/out/sdk/query.js.map +1 -0
  77. package/out/sdk/resolution.d.ts +52 -0
  78. package/out/sdk/resolution.js +68 -0
  79. package/out/sdk/resolution.js.map +1 -0
  80. package/out/sdk/types.d.ts +280 -0
  81. package/out/sdk/types.js +8 -0
  82. package/out/sdk/types.js.map +1 -0
  83. package/out/services/dependency-analyzer.d.ts +58 -0
  84. package/out/services/dependency-analyzer.js +254 -0
  85. package/out/services/dependency-analyzer.js.map +1 -0
  86. package/out/services/dependency-resolver.d.ts +146 -0
  87. package/out/services/dependency-resolver.js +452 -0
  88. package/out/services/dependency-resolver.js.map +1 -0
  89. package/out/services/git-url-resolver.browser.d.ts +10 -0
  90. package/out/services/git-url-resolver.browser.js +19 -0
  91. package/out/services/git-url-resolver.browser.js.map +1 -0
  92. package/out/services/git-url-resolver.d.ts +158 -0
  93. package/out/services/git-url-resolver.js +416 -0
  94. package/out/services/git-url-resolver.js.map +1 -0
  95. package/out/services/governance-validator.d.ts +44 -0
  96. package/out/services/governance-validator.js +153 -0
  97. package/out/services/governance-validator.js.map +1 -0
  98. package/out/services/import-resolver.d.ts +77 -0
  99. package/out/services/import-resolver.js +240 -0
  100. package/out/services/import-resolver.js.map +1 -0
  101. package/out/services/performance-optimizer.d.ts +60 -0
  102. package/out/services/performance-optimizer.js +140 -0
  103. package/out/services/performance-optimizer.js.map +1 -0
  104. package/out/services/relationship-inference.d.ts +11 -0
  105. package/out/services/relationship-inference.js +98 -0
  106. package/out/services/relationship-inference.js.map +1 -0
  107. package/out/services/semver.d.ts +98 -0
  108. package/out/services/semver.js +195 -0
  109. package/out/services/semver.js.map +1 -0
  110. package/out/services/types.d.ts +340 -0
  111. package/out/services/types.js +46 -0
  112. package/out/services/types.js.map +1 -0
  113. package/out/services/workspace-manager.d.ts +123 -0
  114. package/out/services/workspace-manager.js +489 -0
  115. package/out/services/workspace-manager.js.map +1 -0
  116. package/out/syntaxes/domain-lang.monarch.d.ts +76 -0
  117. package/out/syntaxes/domain-lang.monarch.js +29 -0
  118. package/out/syntaxes/domain-lang.monarch.js.map +1 -0
  119. package/out/utils/import-utils.d.ts +49 -0
  120. package/out/utils/import-utils.js +128 -0
  121. package/out/utils/import-utils.js.map +1 -0
  122. package/out/validation/bounded-context.d.ts +11 -0
  123. package/out/validation/bounded-context.js +79 -0
  124. package/out/validation/bounded-context.js.map +1 -0
  125. package/out/validation/classification.d.ts +3 -0
  126. package/out/validation/classification.js +3 -0
  127. package/out/validation/classification.js.map +1 -0
  128. package/out/validation/constants.d.ts +180 -0
  129. package/out/validation/constants.js +235 -0
  130. package/out/validation/constants.js.map +1 -0
  131. package/out/validation/domain-lang-validator.d.ts +2 -0
  132. package/out/validation/domain-lang-validator.js +27 -0
  133. package/out/validation/domain-lang-validator.js.map +1 -0
  134. package/out/validation/domain.d.ts +11 -0
  135. package/out/validation/domain.js +63 -0
  136. package/out/validation/domain.js.map +1 -0
  137. package/out/validation/import.d.ts +68 -0
  138. package/out/validation/import.js +237 -0
  139. package/out/validation/import.js.map +1 -0
  140. package/out/validation/manifest.d.ts +144 -0
  141. package/out/validation/manifest.js +327 -0
  142. package/out/validation/manifest.js.map +1 -0
  143. package/out/validation/maps.d.ts +21 -0
  144. package/out/validation/maps.js +60 -0
  145. package/out/validation/maps.js.map +1 -0
  146. package/out/validation/metadata.d.ts +7 -0
  147. package/out/validation/metadata.js +16 -0
  148. package/out/validation/metadata.js.map +1 -0
  149. package/out/validation/model.d.ts +12 -0
  150. package/out/validation/model.js +29 -0
  151. package/out/validation/model.js.map +1 -0
  152. package/out/validation/relationships.d.ts +12 -0
  153. package/out/validation/relationships.js +94 -0
  154. package/out/validation/relationships.js.map +1 -0
  155. package/out/validation/shared.d.ts +6 -0
  156. package/out/validation/shared.js +12 -0
  157. package/out/validation/shared.js.map +1 -0
  158. package/package.json +110 -0
  159. package/src/ast-augmentation.ts +5 -0
  160. package/src/domain-lang-module.ts +112 -0
  161. package/src/domain-lang.langium +351 -0
  162. package/src/generated/ast.ts +986 -0
  163. package/src/generated/grammar.ts +2409 -0
  164. package/src/generated/module.ts +25 -0
  165. package/src/index.ts +24 -0
  166. package/src/lsp/domain-lang-code-actions.ts +189 -0
  167. package/src/lsp/domain-lang-completion.ts +514 -0
  168. package/src/lsp/domain-lang-formatter.ts +51 -0
  169. package/src/lsp/domain-lang-naming.ts +56 -0
  170. package/src/lsp/domain-lang-scope.ts +137 -0
  171. package/src/lsp/domain-lang-workspace-manager.ts +104 -0
  172. package/src/lsp/hover/ddd-pattern-explanations.ts +237 -0
  173. package/src/lsp/hover/domain-lang-hover.ts +338 -0
  174. package/src/lsp/hover/domain-lang-keywords.ts +50 -0
  175. package/src/lsp/manifest-diagnostics.ts +290 -0
  176. package/src/main-browser.ts +15 -0
  177. package/src/main.ts +85 -0
  178. package/src/sdk/README.md +297 -0
  179. package/src/sdk/ast-augmentation.ts +157 -0
  180. package/src/sdk/index.ts +126 -0
  181. package/src/sdk/indexes.ts +155 -0
  182. package/src/sdk/loader-node.ts +146 -0
  183. package/src/sdk/loader.ts +99 -0
  184. package/src/sdk/patterns.ts +147 -0
  185. package/src/sdk/query.ts +802 -0
  186. package/src/sdk/resolution.ts +78 -0
  187. package/src/sdk/types.ts +323 -0
  188. package/src/services/dependency-analyzer.ts +321 -0
  189. package/src/services/dependency-resolver.ts +551 -0
  190. package/src/services/git-url-resolver.browser.ts +26 -0
  191. package/src/services/git-url-resolver.ts +517 -0
  192. package/src/services/governance-validator.ts +177 -0
  193. package/src/services/import-resolver.ts +292 -0
  194. package/src/services/performance-optimizer.ts +170 -0
  195. package/src/services/relationship-inference.ts +121 -0
  196. package/src/services/semver.ts +213 -0
  197. package/src/services/types.ts +415 -0
  198. package/src/services/workspace-manager.ts +607 -0
  199. package/src/syntaxes/domain-lang.monarch.ts +29 -0
  200. package/src/utils/import-utils.ts +152 -0
  201. package/src/validation/bounded-context.ts +99 -0
  202. package/src/validation/classification.ts +5 -0
  203. package/src/validation/constants.ts +304 -0
  204. package/src/validation/domain-lang-validator.ts +33 -0
  205. package/src/validation/domain.ts +77 -0
  206. package/src/validation/import.ts +295 -0
  207. package/src/validation/manifest.ts +439 -0
  208. package/src/validation/maps.ts +76 -0
  209. package/src/validation/metadata.ts +18 -0
  210. package/src/validation/model.ts +37 -0
  211. package/src/validation/relationships.ts +154 -0
  212. package/src/validation/shared.ts +14 -0
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Semantic Versioning Utilities
3
+ *
4
+ * Centralized SemVer parsing, comparison, and validation for the dependency system.
5
+ * All version-related logic should use these utilities to ensure consistency.
6
+ *
7
+ * Supported formats:
8
+ * - "1.0.0" or "v1.0.0" (tags)
9
+ * - "1.0.0-alpha.1" (pre-release)
10
+ * - "main", "develop" (branches)
11
+ * - "abc123def" (commit SHAs, 7-40 hex chars)
12
+ */
13
+
14
+ import type { SemVer, RefType, ParsedRef } from './types.js';
15
+
16
+ // ============================================================================
17
+ // Parsing
18
+ // ============================================================================
19
+
20
+ /**
21
+ * Parses a version string into SemVer components.
22
+ * Returns undefined if not a valid SemVer.
23
+ *
24
+ * @example
25
+ * parseSemVer("v1.2.3") // { major: 1, minor: 2, patch: 3, original: "v1.2.3" }
26
+ * parseSemVer("1.0.0-alpha") // { major: 1, minor: 0, patch: 0, prerelease: "alpha", ... }
27
+ * parseSemVer("main") // undefined (not SemVer)
28
+ */
29
+ export function parseSemVer(version: string): SemVer | undefined {
30
+ // Strip leading 'v' if present
31
+ const normalized = version.startsWith('v') ? version.slice(1) : version;
32
+
33
+ // Match semver pattern: major.minor.patch[-prerelease]
34
+ const match = normalized.match(/^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);
35
+ if (!match) return undefined;
36
+
37
+ return {
38
+ major: parseInt(match[1], 10),
39
+ minor: parseInt(match[2], 10),
40
+ patch: parseInt(match[3], 10),
41
+ preRelease: match[4],
42
+ original: version,
43
+ };
44
+ }
45
+
46
+ /**
47
+ * Detects the type of a git ref based on its format.
48
+ *
49
+ * @example
50
+ * detectRefType("v1.0.0") // 'tag'
51
+ * detectRefType("1.2.3") // 'tag'
52
+ * detectRefType("main") // 'branch'
53
+ * detectRefType("abc123def") // 'commit'
54
+ */
55
+ export function detectRefType(ref: string): RefType {
56
+ // Commit SHA: 7-40 hex characters
57
+ if (/^[0-9a-f]{7,40}$/i.test(ref)) {
58
+ return 'commit';
59
+ }
60
+ // Tags typically start with 'v' followed by semver
61
+ if (/^v?\d+\.\d+\.\d+/.test(ref)) {
62
+ return 'tag';
63
+ }
64
+ // Everything else is treated as a branch
65
+ return 'branch';
66
+ }
67
+
68
+ /**
69
+ * Parses a ref string into a structured ParsedRef with type and optional SemVer.
70
+ */
71
+ export function parseRef(ref: string): ParsedRef {
72
+ const type = detectRefType(ref);
73
+ const semver = type === 'tag' ? parseSemVer(ref) : undefined;
74
+
75
+ return { original: ref, type, semver };
76
+ }
77
+
78
+ // ============================================================================
79
+ // Comparison
80
+ // ============================================================================
81
+
82
+ /**
83
+ * Compares two SemVer versions.
84
+ * Returns: negative if a < b, positive if a > b, zero if equal.
85
+ *
86
+ * @example
87
+ * compareSemVer(parse("1.0.0"), parse("2.0.0")) // negative (a < b)
88
+ * compareSemVer(parse("1.5.0"), parse("1.2.0")) // positive (a > b)
89
+ * compareSemVer(parse("1.0.0-alpha"), parse("1.0.0")) // negative (prerelease < release)
90
+ */
91
+ export function compareSemVer(a: SemVer, b: SemVer): number {
92
+ if (a.major !== b.major) return a.major - b.major;
93
+ if (a.minor !== b.minor) return a.minor - b.minor;
94
+ if (a.patch !== b.patch) return a.patch - b.patch;
95
+
96
+ // Pre-release versions are lower than release versions
97
+ if (a.preRelease && !b.preRelease) return -1;
98
+ if (!a.preRelease && b.preRelease) return 1;
99
+ if (a.preRelease && b.preRelease) {
100
+ return a.preRelease.localeCompare(b.preRelease);
101
+ }
102
+
103
+ return 0;
104
+ }
105
+
106
+ /**
107
+ * Picks the latest from a list of SemVer refs.
108
+ * Returns the ref string (with original 'v' prefix if present).
109
+ *
110
+ * @example
111
+ * pickLatestSemVer(["v1.0.0", "v1.5.0", "v1.2.0"]) // "v1.5.0"
112
+ */
113
+ export function pickLatestSemVer(refs: string[]): string | undefined {
114
+ const parsed = refs
115
+ .map(ref => ({ ref, semver: parseSemVer(ref) }))
116
+ .filter((item): item is { ref: string; semver: SemVer } => item.semver !== undefined);
117
+
118
+ if (parsed.length === 0) return undefined;
119
+
120
+ parsed.sort((a, b) => compareSemVer(b.semver, a.semver)); // Descending
121
+ return parsed[0].ref;
122
+ }
123
+
124
+ /**
125
+ * Sorts version strings in descending order (newest first).
126
+ * Non-SemVer refs are sorted lexicographically at the end.
127
+ *
128
+ * @example
129
+ * sortVersionsDescending(["v1.0.0", "v2.0.0", "v1.5.0"]) // ["v2.0.0", "v1.5.0", "v1.0.0"]
130
+ */
131
+ export function sortVersionsDescending(versions: string[]): string[] {
132
+ return [...versions].sort((a, b) => {
133
+ const semverA = parseSemVer(a);
134
+ const semverB = parseSemVer(b);
135
+
136
+ // Both are SemVer - compare semantically
137
+ if (semverA && semverB) {
138
+ return compareSemVer(semverB, semverA); // Descending
139
+ }
140
+
141
+ // SemVer comes before non-SemVer
142
+ if (semverA && !semverB) return -1;
143
+ if (!semverA && semverB) return 1;
144
+
145
+ // Both non-SemVer - lexicographic
146
+ return b.localeCompare(a);
147
+ });
148
+ }
149
+
150
+ // ============================================================================
151
+ // Validation
152
+ // ============================================================================
153
+
154
+ /**
155
+ * Checks if a version/ref is a pre-release.
156
+ *
157
+ * Pre-release identifiers: alpha, beta, rc, pre, dev, snapshot
158
+ *
159
+ * @example
160
+ * isPreRelease("v1.0.0") // false
161
+ * isPreRelease("v1.0.0-alpha") // true
162
+ * isPreRelease("v1.0.0-rc.1") // true
163
+ */
164
+ export function isPreRelease(ref: string): boolean {
165
+ const semver = parseSemVer(ref);
166
+ if (semver?.preRelease) {
167
+ return true;
168
+ }
169
+
170
+ // Also check for common pre-release patterns without proper SemVer
171
+ const clean = ref.replace(/^v/, '');
172
+ return /-(alpha|beta|rc|pre|dev|snapshot)/i.test(clean);
173
+ }
174
+
175
+ /**
176
+ * Checks if two SemVer versions are compatible (same major version).
177
+ *
178
+ * @example
179
+ * areSameMajor(parse("1.0.0"), parse("1.5.0")) // true
180
+ * areSameMajor(parse("1.0.0"), parse("2.0.0")) // false
181
+ */
182
+ export function areSameMajor(a: SemVer, b: SemVer): boolean {
183
+ return a.major === b.major;
184
+ }
185
+
186
+ /**
187
+ * Gets the major version number from a ref string.
188
+ * Returns undefined if not a valid SemVer.
189
+ */
190
+ export function getMajorVersion(ref: string): number | undefined {
191
+ return parseSemVer(ref)?.major;
192
+ }
193
+
194
+ // ============================================================================
195
+ // Filtering
196
+ // ============================================================================
197
+
198
+ /**
199
+ * Filters refs to only stable versions (excludes pre-releases).
200
+ *
201
+ * @example
202
+ * filterStableVersions(["v1.0.0", "v1.1.0-alpha", "v1.2.0"]) // ["v1.0.0", "v1.2.0"]
203
+ */
204
+ export function filterStableVersions(refs: string[]): string[] {
205
+ return refs.filter(ref => !isPreRelease(ref));
206
+ }
207
+
208
+ /**
209
+ * Filters refs to only SemVer tags (excludes branches and commits).
210
+ */
211
+ export function filterSemVerTags(refs: string[]): string[] {
212
+ return refs.filter(ref => detectRefType(ref) === 'tag' && parseSemVer(ref) !== undefined);
213
+ }
@@ -0,0 +1,415 @@
1
+ /**
2
+ * Centralized Type Definitions for DomainLang Services
3
+ *
4
+ * Type design principles:
5
+ * - **Atomic**: Each type represents a single, well-defined concept
6
+ * - **Non-overlapping**: Types don't duplicate fields unnecessarily
7
+ * - **Rich**: Types use adjacent types for composition rather than primitives
8
+ * - **Discriminated**: Union types use discriminants for type narrowing
9
+ *
10
+ * Type hierarchy:
11
+ * ```
12
+ * Core Building Blocks
13
+ * ├── RefType (discriminant for git references)
14
+ * └── SemVer (semantic version components)
15
+ *
16
+ * Package Identity
17
+ * └── PackageIdentity (name, version, entry)
18
+ *
19
+ * Dependencies
20
+ * ├── DependencySpec (how deps are specified)
21
+ * │ ├── ShortDependencySpec (string ref only)
22
+ * │ └── ExtendedDependencySpec (full options)
23
+ * └── ResolvedDependency (locked/pinned state)
24
+ *
25
+ * Manifest & Lock
26
+ * ├── ModelManifest (model.yaml schema)
27
+ * └── LockFile (model.lock schema)
28
+ *
29
+ * Resolution Graph
30
+ * ├── DependencyNode (graph node during resolution)
31
+ * └── DependencyGraph (complete resolution graph)
32
+ *
33
+ * Analysis & Governance
34
+ * ├── GovernancePolicy (policy configuration)
35
+ * └── GovernanceViolation (validation result)
36
+ * ```
37
+ *
38
+ * @module services/types
39
+ */
40
+
41
+ // ============================================================================
42
+ // Core Building Blocks
43
+ // ============================================================================
44
+
45
+ /**
46
+ * Type of git reference for version pinning.
47
+ *
48
+ * Used as discriminant in ref-related types:
49
+ * - **tag**: SemVer version tag (v1.0.0, 2.3.4)
50
+ * - **branch**: Branch name (main, develop)
51
+ * - **commit**: Full commit SHA (40 hex chars)
52
+ */
53
+ export type RefType = 'tag' | 'branch' | 'commit';
54
+
55
+ /**
56
+ * Parsed semantic version following SemVer 2.0.0.
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const v: SemVer = {
61
+ * major: 1, minor: 2, patch: 3,
62
+ * preRelease: 'beta.1',
63
+ * original: 'v1.2.3-beta.1'
64
+ * };
65
+ * ```
66
+ */
67
+ export interface SemVer {
68
+ readonly major: number;
69
+ readonly minor: number;
70
+ readonly patch: number;
71
+ /** Pre-release identifier (e.g., "alpha", "beta.1", "rc.2") */
72
+ readonly preRelease?: string;
73
+ /** Build metadata - ignored in version comparison */
74
+ readonly buildMetadata?: string;
75
+ /** Original string representation */
76
+ readonly original: string;
77
+ }
78
+
79
+ /**
80
+ * Result of parsing a git ref string.
81
+ */
82
+ export interface ParsedRef {
83
+ readonly type: RefType;
84
+ /** Present only for valid SemVer tags */
85
+ readonly semver?: SemVer;
86
+ readonly original: string;
87
+ }
88
+
89
+ // ============================================================================
90
+ // Package Identity
91
+ // ============================================================================
92
+
93
+ /**
94
+ * Core package identity and metadata.
95
+ *
96
+ * Used in model.yaml `model:` section and internally during resolution.
97
+ */
98
+ export interface PackageIdentity {
99
+ /** Package name in owner/repo format */
100
+ readonly name?: string;
101
+ /** SemVer version string */
102
+ readonly version?: string;
103
+ /** Entry point file (default: index.dlang) */
104
+ readonly entry?: string;
105
+ }
106
+
107
+ // ============================================================================
108
+ // Dependency Specification Types
109
+ // ============================================================================
110
+
111
+ /**
112
+ * Extended dependency specification with full options.
113
+ *
114
+ * Either `source` OR `path` must be provided (mutually exclusive):
115
+ * - `source`: Remote git coordinates (owner/repo)
116
+ * - `path`: Local filesystem path for monorepo deps
117
+ */
118
+ export interface ExtendedDependencySpec {
119
+ /** Git coordinates (owner/repo) - mutually exclusive with path */
120
+ readonly source?: string;
121
+ /** Git ref (tag, branch, or commit SHA) */
122
+ readonly ref?: string;
123
+ /** Local path - mutually exclusive with source */
124
+ readonly path?: string;
125
+ /** SHA-256 integrity hash for verification */
126
+ readonly integrity?: string;
127
+ /** Human-readable description */
128
+ readonly description?: string;
129
+ }
130
+
131
+ /**
132
+ * Dependency specification in model.yaml.
133
+ *
134
+ * Can be either:
135
+ * - **string**: Short form (just the ref, key is owner/repo)
136
+ * - **ExtendedDependencySpec**: Full form with options
137
+ *
138
+ * @example
139
+ * ```yaml
140
+ * dependencies:
141
+ * acme/core: "v1.0.0" # Short form
142
+ * acme/utils: # Extended form
143
+ * source: acme/utils
144
+ * ref: main
145
+ * integrity: sha256-abc123
146
+ * ```
147
+ */
148
+ export type DependencySpec = string | ExtendedDependencySpec;
149
+
150
+ /**
151
+ * Type guard for extended dependency spec.
152
+ */
153
+ export function isExtendedDependencySpec(dep: DependencySpec): dep is ExtendedDependencySpec {
154
+ return typeof dep === 'object' && dep !== null;
155
+ }
156
+
157
+ // ============================================================================
158
+ // Resolved/Locked Dependency Types
159
+ // ============================================================================
160
+
161
+ /**
162
+ * A fully resolved and locked dependency.
163
+ *
164
+ * Represents a dependency after resolution with all fields pinned
165
+ * to exact values for reproducible builds.
166
+ */
167
+ export interface LockedDependency {
168
+ /** Original ref from manifest */
169
+ readonly ref: string;
170
+ /** Detected ref type */
171
+ readonly refType: RefType;
172
+ /** Full git URL used for fetching */
173
+ readonly resolved: string;
174
+ /** Exact commit hash (40-char SHA) */
175
+ readonly commit: string;
176
+ /** Optional integrity hash */
177
+ readonly integrity?: string;
178
+ }
179
+
180
+ // ============================================================================
181
+ // Manifest Types (model.yaml)
182
+ // ============================================================================
183
+
184
+ /**
185
+ * Path aliases for @ imports.
186
+ *
187
+ * @example
188
+ * ```yaml
189
+ * paths:
190
+ * "@/": "./src/"
191
+ * "@shared/": "./libs/shared/"
192
+ * ```
193
+ */
194
+ export type PathAliases = Readonly<Record<string, string>>;
195
+
196
+ /**
197
+ * Governance policy configuration.
198
+ */
199
+ export interface GovernancePolicy {
200
+ /** Allowed git domains (e.g., ['github.com/acme']) */
201
+ readonly allowedSources?: readonly string[];
202
+ /** Blocked packages or patterns */
203
+ readonly blockedPackages?: readonly string[];
204
+ /** Require stable versions only (no pre-release) */
205
+ readonly requireStableVersions?: boolean;
206
+ /** Require team ownership metadata */
207
+ readonly requireTeamOwnership?: boolean;
208
+ /** Allowed licenses */
209
+ readonly allowedLicenses?: readonly string[];
210
+ }
211
+
212
+ /**
213
+ * Package manifest (model.yaml) schema.
214
+ *
215
+ * This is the user-facing YAML file structure.
216
+ */
217
+ export interface ModelManifest {
218
+ /** Package identity and metadata */
219
+ readonly model?: PackageIdentity;
220
+ /** Path aliases for @ imports */
221
+ readonly paths?: PathAliases;
222
+ /** Dependencies keyed by alias or owner/repo */
223
+ readonly dependencies?: Readonly<Record<string, DependencySpec>>;
224
+ /** Ref overrides for conflict resolution */
225
+ readonly overrides?: Readonly<Record<string, string>>;
226
+ /** Governance policies */
227
+ readonly governance?: GovernancePolicy;
228
+ }
229
+
230
+ // ============================================================================
231
+ // Lock File Types (model.lock)
232
+ // ============================================================================
233
+
234
+ /**
235
+ * Lock file schema (model.lock).
236
+ *
237
+ * Pins exact commits for reproducible builds.
238
+ */
239
+ export interface LockFile {
240
+ /** Lock file format version */
241
+ readonly version: string;
242
+ /** All locked dependencies keyed by package name */
243
+ readonly dependencies: Readonly<Record<string, LockedDependency>>;
244
+ }
245
+
246
+ // ============================================================================
247
+ // Dependency Resolution Types (internal)
248
+ // ============================================================================
249
+
250
+ /**
251
+ * Mutable package metadata during resolution.
252
+ *
253
+ * Unlike PackageIdentity (readonly user-facing), this is mutable
254
+ * because the resolver builds it incrementally during YAML parsing.
255
+ */
256
+ export interface ResolvingPackage {
257
+ name?: string;
258
+ version?: string;
259
+ entry?: string;
260
+ exports?: Record<string, string>;
261
+ /** Dependencies as name → ref constraint */
262
+ dependencies?: Record<string, string>;
263
+ /** Ref overrides */
264
+ overrides?: Record<string, string>;
265
+ }
266
+
267
+ /**
268
+ * Node in the dependency graph during resolution.
269
+ */
270
+ export interface DependencyNode {
271
+ /** Package identifier (owner/repo) */
272
+ readonly packageKey: string;
273
+ /** Primary ref constraint from first encounter */
274
+ refConstraint: string;
275
+ /** All observed constraints from different parents */
276
+ constraints?: Set<string>;
277
+ /** Resolved ref after conflict resolution */
278
+ resolvedRef?: string;
279
+ /** Detected ref type */
280
+ refType?: RefType;
281
+ /** Resolved commit hash */
282
+ commitHash?: string;
283
+ /** Full git repository URL */
284
+ repoUrl?: string;
285
+ /** Direct dependencies of this package */
286
+ dependencies: Record<string, string>;
287
+ /** Parent packages that depend on this one */
288
+ dependents: string[];
289
+ }
290
+
291
+ /**
292
+ * Complete dependency graph for resolution.
293
+ */
294
+ export interface DependencyGraph {
295
+ /** All discovered packages */
296
+ readonly nodes: Record<string, DependencyNode>;
297
+ /** Root package name */
298
+ readonly root: string;
299
+ }
300
+
301
+ // ============================================================================
302
+ // Git Import Types
303
+ // ============================================================================
304
+
305
+ /** Supported git platforms */
306
+ export type GitPlatform = 'github' | 'gitlab' | 'bitbucket' | 'generic';
307
+
308
+ /**
309
+ * Parsed git import with repository information.
310
+ */
311
+ export interface GitImportInfo {
312
+ /** Original import string */
313
+ readonly original: string;
314
+ /** Git platform */
315
+ readonly platform: GitPlatform;
316
+ /** Repository owner/organization */
317
+ readonly owner: string;
318
+ /** Repository name */
319
+ readonly repo: string;
320
+ /** Version (tag, branch, or commit) */
321
+ readonly version: string;
322
+ /** Full git repository URL */
323
+ readonly repoUrl: string;
324
+ /** Package entry point */
325
+ readonly entryPoint: string;
326
+ }
327
+
328
+ // ============================================================================
329
+ // Dependency Analysis Types
330
+ // ============================================================================
331
+
332
+ /**
333
+ * Node in a dependency tree visualization.
334
+ */
335
+ export interface DependencyTreeNode {
336
+ readonly packageKey: string;
337
+ readonly ref: string;
338
+ readonly commit: string;
339
+ readonly dependencies: readonly DependencyTreeNode[];
340
+ /** Depth in tree (0 = root) */
341
+ readonly depth: number;
342
+ }
343
+
344
+ /**
345
+ * Reverse dependency relationship.
346
+ */
347
+ export interface ReverseDependency {
348
+ /** Package that depends on the target */
349
+ readonly dependentPackage: string;
350
+ /** Ref of the dependent */
351
+ readonly ref: string;
352
+ /** Relationship type */
353
+ readonly type: 'direct' | 'transitive';
354
+ }
355
+
356
+ /**
357
+ * Version update policy.
358
+ */
359
+ export interface VersionPolicy {
360
+ readonly policy: 'latest' | 'stable' | 'pinned';
361
+ readonly ref: string;
362
+ readonly availableRefs?: readonly string[];
363
+ }
364
+
365
+ // ============================================================================
366
+ // Governance Types
367
+ // ============================================================================
368
+
369
+ /** Governance violation type discriminant */
370
+ export type GovernanceViolationType =
371
+ | 'blocked-source'
372
+ | 'unstable-version'
373
+ | 'missing-metadata'
374
+ | 'license-violation';
375
+
376
+ /** Governance violation severity */
377
+ export type GovernanceViolationSeverity = 'error' | 'warning';
378
+
379
+ /**
380
+ * A governance policy violation.
381
+ */
382
+ export interface GovernanceViolation {
383
+ readonly type: GovernanceViolationType;
384
+ readonly packageKey: string;
385
+ readonly message: string;
386
+ readonly severity: GovernanceViolationSeverity;
387
+ }
388
+
389
+ /**
390
+ * Governance metadata for a package (from model.yaml).
391
+ */
392
+ export interface GovernanceMetadata {
393
+ readonly team?: string;
394
+ readonly contact?: string;
395
+ readonly domain?: string;
396
+ readonly compliance?: readonly string[];
397
+ }
398
+
399
+ // ============================================================================
400
+ // Workspace Types
401
+ // ============================================================================
402
+
403
+ /**
404
+ * Options for workspace manager initialization.
405
+ */
406
+ export interface WorkspaceManagerOptions {
407
+ /** Auto-resolve dependencies on initialization */
408
+ readonly autoResolve?: boolean;
409
+ /** Manifest file names to search for */
410
+ readonly manifestFiles?: readonly string[];
411
+ /** Lock file names to search for */
412
+ readonly lockFiles?: readonly string[];
413
+ /** Allow network access for git operations */
414
+ readonly allowNetwork?: boolean;
415
+ }