@likec4/core 1.27.3 → 1.28.1

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 (71) hide show
  1. package/dist/builder/index.d.mts +6 -6
  2. package/dist/builder/index.mjs +23 -13
  3. package/dist/compute-view/index.d.mts +3 -3
  4. package/dist/compute-view/index.mjs +3 -3
  5. package/dist/compute-view/relationships-view/index.d.mts +3 -3
  6. package/dist/index.d.mts +6 -6
  7. package/dist/index.mjs +2 -2
  8. package/dist/model/index.d.mts +6 -6
  9. package/dist/model/index.mjs +1 -1
  10. package/dist/shared/{core.BpuZeqlX.d.mts → core.CZR9J1Qx.d.mts} +2 -2
  11. package/dist/shared/{core.Djro-kuQ.d.mts → core.CiFKryGW.d.mts} +7 -2
  12. package/dist/shared/{core.HKn0jlo_.d.mts → core.D2830qgg.d.mts} +1 -1
  13. package/dist/shared/{core.CFDwncxs.d.mts → core.DJvmfnEi.d.mts} +481 -186
  14. package/dist/shared/{core.BMep80lJ.mjs → core.DgfwjBtu.mjs} +198 -87
  15. package/dist/shared/core.SjLhMA7a.d.mts +62 -0
  16. package/dist/shared/{core.RjpTh3vE.mjs → core.w6BcP9z5.mjs} +263 -168
  17. package/dist/types/index.d.mts +4 -4
  18. package/dist/types/index.mjs +1 -1
  19. package/dist/utils/index.d.mts +2 -2
  20. package/package.json +7 -7
  21. package/src/builder/Builder.ts +1 -0
  22. package/src/builder/Builder.view-common.ts +10 -10
  23. package/src/builder/Builder.view-element.ts +26 -14
  24. package/src/builder/__snapshots__/Builder-style1.spec.ts.snap +23 -8
  25. package/src/builder/__snapshots__/Builder-style2.spec.ts.snap +9 -4
  26. package/src/compute-view/deployment-view/predicates/deploymentRefs-where.ts +18 -0
  27. package/src/compute-view/deployment-view/predicates/relation-direct.ts +6 -0
  28. package/src/compute-view/deployment-view/predicates/relation-in-out.ts +3 -0
  29. package/src/compute-view/deployment-view/predicates/relation-incoming.ts +3 -0
  30. package/src/compute-view/deployment-view/predicates/relation-outgoing.ts +3 -0
  31. package/src/compute-view/deployment-view/predicates/utils.ts +10 -3
  32. package/src/compute-view/deployment-view/utils.ts +7 -4
  33. package/src/compute-view/element-view/__test__/fixture.ts +72 -65
  34. package/src/compute-view/element-view/_types.ts +13 -9
  35. package/src/compute-view/element-view/compute.ts +27 -27
  36. package/src/compute-view/element-view/memory/NodeGroup.ts +4 -3
  37. package/src/compute-view/element-view/memory/memory.ts +3 -2
  38. package/src/compute-view/element-view/memory/stage-include.ts +2 -2
  39. package/src/compute-view/element-view/predicates/_utils.ts +25 -24
  40. package/src/compute-view/element-view/predicates/element-expand.ts +7 -10
  41. package/src/compute-view/element-view/predicates/element-kind-tag.ts +5 -3
  42. package/src/compute-view/element-view/predicates/element-ref.ts +7 -19
  43. package/src/compute-view/element-view/predicates/relation-direct.ts +15 -13
  44. package/src/compute-view/element-view/predicates/relation-in-out.ts +5 -6
  45. package/src/compute-view/element-view/predicates/relation-in.ts +36 -32
  46. package/src/compute-view/element-view/predicates/relation-out.ts +37 -33
  47. package/src/compute-view/element-view/predicates/wildcard.ts +2 -2
  48. package/src/compute-view/utils/applyCustomElementProperties.ts +9 -4
  49. package/src/compute-view/utils/applyCustomRelationProperties.ts +10 -7
  50. package/src/compute-view/utils/elementExpressionToPredicate.ts +27 -26
  51. package/src/compute-view/utils/link-nodes-with-edges.ts +1 -1
  52. package/src/compute-view/utils/relationExpressionToPredicates.ts +10 -17
  53. package/src/compute-view/utils/uniqueTags.ts +3 -3
  54. package/src/index.ts +0 -2
  55. package/src/model/ElementModel.ts +25 -6
  56. package/src/model/LikeC4Model.ts +47 -6
  57. package/src/model/RelationModel.ts +4 -2
  58. package/src/model/view/LikeC4ViewModel.ts +3 -2
  59. package/src/types/_common.ts +0 -4
  60. package/src/types/deployments.ts +3 -2
  61. package/src/types/element.ts +2 -10
  62. package/src/types/expression-v2-model.ts +314 -0
  63. package/src/types/expression-v2.ts +238 -30
  64. package/src/types/index.ts +15 -46
  65. package/src/types/model-data.ts +4 -1
  66. package/src/types/relation.ts +2 -1
  67. package/src/types/scalars.ts +39 -0
  68. package/src/types/view-changes.ts +2 -1
  69. package/src/types/view.ts +7 -8
  70. package/dist/shared/core.30yYKXcZ.d.mts +0 -186
  71. package/src/types/expression.ts +0 -207
@@ -1,8 +1,12 @@
1
1
  import { invariant } from '../errors'
2
2
  import type { ExclusiveUnion } from './_common'
3
3
  import type { DeploymentRef as DeploymentModelRef, PredicateSelector } from './deployments'
4
- import type { Fqn } from './element'
4
+ import type { BorderStyle, ElementKind, ElementShape } from './element'
5
5
  import type { WhereOperator } from './operators'
6
+ import type { RelationshipArrowType, RelationshipLineType } from './relation'
7
+ import { type Fqn, type IconUrl, type ProjectId, type Tag, GlobalFqn } from './scalars'
8
+ import type { Color, ShapeSize } from './theme'
9
+ import type { ViewId } from './view'
6
10
 
7
11
  export namespace FqnRef {
8
12
  /**
@@ -37,7 +41,7 @@ export namespace FqnRef {
37
41
 
38
42
  export type DeploymentRef<D = Fqn, M = Fqn> = DeploymentElementRef<D> | InsideInstanceRef<D, M>
39
43
  export const isDeploymentRef = (ref: FqnRef): ref is DeploymentRef => {
40
- return !isModelRef(ref)
44
+ return !isModelRef(ref) && !isImportRef(ref)
41
45
  }
42
46
 
43
47
  /**
@@ -47,7 +51,18 @@ export namespace FqnRef {
47
51
  model: F
48
52
  }
49
53
  export const isModelRef = (ref: FqnRef): ref is ModelRef => {
50
- return 'model' in ref
54
+ return 'model' in ref && !('project' in ref)
55
+ }
56
+
57
+ /**
58
+ * Reference to imported logical model element
59
+ */
60
+ export type ImportRef<F = Fqn> = {
61
+ project: ProjectId
62
+ model: F
63
+ }
64
+ export const isImportRef = (ref: FqnRef): ref is ImportRef => {
65
+ return 'project' in ref && 'model' in ref
51
66
  }
52
67
 
53
68
  export const toDeploymentRef = (ref: FqnRef): DeploymentModelRef => {
@@ -61,28 +76,39 @@ export namespace FqnRef {
61
76
  id: ref.deployment,
62
77
  }
63
78
  }
79
+
80
+ export const toModelFqn = (ref: FqnRef): Fqn => {
81
+ if (isImportRef(ref)) {
82
+ return GlobalFqn(ref.project, ref.model)
83
+ }
84
+ if (isModelRef(ref)) {
85
+ return ref.model
86
+ }
87
+ throw new Error('Expected FqnRef.ModelRef or FqnRef.ImportRef')
88
+ }
64
89
  }
65
90
 
66
91
  export type FqnRef<D = Fqn, M = Fqn> = ExclusiveUnion<{
67
92
  InsideInstanceRef: FqnRef.InsideInstanceRef<D, M>
68
93
  DeploymentRef: FqnRef.DeploymentRef<D>
69
94
  ModelRef: FqnRef.ModelRef<M>
95
+ ImportRef: FqnRef.ImportRef<M>
70
96
  }>
71
97
 
72
98
  export namespace FqnExpr {
73
99
  export type Wildcard = {
74
100
  wildcard: true
75
101
  }
76
- export const isWildcard = (expr: ExpressionV2): expr is Wildcard => {
102
+ export const isWildcard = (expr: ExpressionV2): expr is FqnExpr.Wildcard => {
77
103
  return 'wildcard' in expr && expr.wildcard === true
78
104
  }
79
105
 
80
106
  export type ModelRef<M = Fqn> = {
81
- ref: FqnRef.ModelRef<M>
107
+ ref: FqnRef.ModelRef<M> | FqnRef.ImportRef<M>
82
108
  selector?: PredicateSelector
83
109
  }
84
- export const isModelRef = (ref: ExpressionV2): ref is ModelRef => {
85
- return 'ref' in ref && FqnRef.isModelRef(ref.ref)
110
+ export const isModelRef = (ref: ExpressionV2): ref is FqnExpr.ModelRef => {
111
+ return 'ref' in ref && (FqnRef.isModelRef(ref.ref) || FqnRef.isImportRef(ref.ref))
86
112
  }
87
113
 
88
114
  export type DeploymentRef<D = Fqn, M = Fqn> = {
@@ -93,53 +119,216 @@ export namespace FqnExpr {
93
119
  return 'ref' in ref && FqnRef.isDeploymentRef(ref.ref)
94
120
  }
95
121
 
122
+ export type ElementKindExpr = {
123
+ elementKind: ElementKind
124
+ isEqual: boolean
125
+ }
126
+ export function isElementKindExpr(expr: ExpressionV2): expr is ElementKindExpr {
127
+ return 'elementKind' in expr && 'isEqual' in expr
128
+ }
129
+
130
+ export type ElementTagExpr = {
131
+ elementTag: Tag
132
+ isEqual: boolean
133
+ }
134
+ export function isElementTagExpr(expr: ExpressionV2): expr is ElementTagExpr {
135
+ return 'elementTag' in expr && 'isEqual' in expr
136
+ }
137
+
96
138
  export type NonWildcard<D = Fqn, M = Fqn> = ExclusiveUnion<{
97
139
  ModelRef: ModelRef<M>
98
140
  DeploymentRef: DeploymentRef<D, M>
141
+ ElementKind: ElementKindExpr
142
+ ElementTag: ElementTagExpr
143
+ }>
144
+
145
+ export type Where<D = Fqn, M = Fqn> = {
146
+ where: {
147
+ expr: ExclusiveUnion<{
148
+ Wildcard: Wildcard
149
+ ModelRef: ModelRef<M>
150
+ DeploymentRef: DeploymentRef<D, M>
151
+ ElementKind: ElementKindExpr
152
+ ElementTag: ElementTagExpr
153
+ }>
154
+ condition: WhereOperator<string, string>
155
+ }
156
+ }
157
+
158
+ export const isWhere = (expr: ExpressionV2): expr is FqnExpr.Where => {
159
+ return 'where' in expr && is(expr.where.expr)
160
+ }
161
+
162
+ export type Custom<D = Fqn, M = Fqn> = {
163
+ custom: {
164
+ expr: OrWhere<D, M>
165
+ title?: string
166
+ description?: string
167
+ technology?: string
168
+ notation?: string
169
+ shape?: ElementShape
170
+ color?: Color
171
+ icon?: IconUrl
172
+ border?: BorderStyle
173
+ opacity?: number
174
+ navigateTo?: ViewId
175
+ multiple?: boolean
176
+ size?: ShapeSize
177
+ padding?: ShapeSize
178
+ textSize?: ShapeSize
179
+ }
180
+ }
181
+
182
+ export const isCustom = (expr: ExpressionV2): expr is Custom => {
183
+ return 'custom' in expr && (is(expr.custom.expr) || isWhere(expr.custom.expr))
184
+ }
185
+
186
+ export const is = (expr: ExpressionV2): expr is FqnExpr => {
187
+ return isWildcard(expr)
188
+ || isModelRef(expr)
189
+ || isDeploymentRef(expr)
190
+ || isElementKindExpr(expr)
191
+ || isElementTagExpr(expr)
192
+ }
193
+
194
+ export type OrWhere<D = Fqn, M = Fqn> = ExclusiveUnion<{
195
+ Wildcard: FqnExpr.Wildcard
196
+ ModelRef: FqnExpr.ModelRef<M>
197
+ DeploymentRef: FqnExpr.DeploymentRef<D, M>
198
+ ElementKind: ElementKindExpr
199
+ ElementTag: ElementTagExpr
200
+ Where: FqnExpr.Where<D, M>
201
+ }>
202
+
203
+ export type Any<D = Fqn, M = Fqn> = ExclusiveUnion<{
204
+ Wildcard: Wildcard
205
+ ModelRef: ModelRef<M>
206
+ DeploymentRef: DeploymentRef<D, M>
207
+ ElementKind: ElementKindExpr
208
+ ElementTag: ElementTagExpr
209
+ Where: Where<D, M>
210
+ Custom: Custom<D, M>
99
211
  }>
212
+
213
+ export const unwrap = (expr: FqnExpr): Wildcard | ModelRef | DeploymentRef | ElementKindExpr | ElementTagExpr => {
214
+ if (isCustom(expr)) {
215
+ expr = expr.custom.expr
216
+ }
217
+ if (isWhere(expr)) {
218
+ expr = expr.where.expr
219
+ }
220
+ return expr
221
+ }
100
222
  }
101
223
 
102
224
  export type FqnExpr<D = Fqn, M = Fqn> = ExclusiveUnion<{
103
225
  Wildcard: FqnExpr.Wildcard
104
226
  ModelRef: FqnExpr.ModelRef<M>
105
227
  DeploymentRef: FqnExpr.DeploymentRef<D, M>
228
+ ElementKind: FqnExpr.ElementKindExpr
229
+ ElementTag: FqnExpr.ElementTagExpr
106
230
  }>
107
231
 
108
232
  export namespace RelationExpr {
233
+ export type Endpoint<D = Fqn, M = Fqn> = FqnExpr.Where<D, M>['where']['expr']
234
+
109
235
  export type Direct<D = Fqn, M = Fqn> = {
110
- source: FqnExpr<D, M>
111
- target: FqnExpr<D, M>
236
+ source: Endpoint<D, M>
237
+ target: Endpoint<D, M>
112
238
  isBidirectional?: boolean
113
239
  }
114
- export const isDirect = (expr: ExpressionV2): expr is Direct => {
240
+ export const isDirect = (expr: ExpressionV2): expr is RelationExpr.Direct => {
115
241
  return 'source' in expr && 'target' in expr
116
242
  }
117
243
  export type Incoming<D = Fqn, M = Fqn> = {
118
- incoming: FqnExpr<D, M>
244
+ incoming: Endpoint<D, M>
119
245
  }
120
- export const isIncoming = (expr: ExpressionV2): expr is Incoming => {
246
+ export const isIncoming = (expr: ExpressionV2): expr is RelationExpr.Incoming => {
121
247
  return 'incoming' in expr
122
248
  }
123
249
  export type Outgoing<D = Fqn, M = Fqn> = {
124
- outgoing: FqnExpr<D, M>
250
+ outgoing: Endpoint<D, M>
125
251
  }
126
- export const isOutgoing = (expr: ExpressionV2): expr is Outgoing => {
252
+ export const isOutgoing = (expr: ExpressionV2): expr is RelationExpr.Outgoing => {
127
253
  return 'outgoing' in expr
128
254
  }
129
255
  export type InOut<D = Fqn, M = Fqn> = {
130
- inout: FqnExpr<D, M>
256
+ inout: Endpoint<D, M>
131
257
  }
132
- export const isInOut = (expr: ExpressionV2): expr is InOut => {
258
+ export const isInOut = (expr: ExpressionV2): expr is RelationExpr.InOut => {
133
259
  return 'inout' in expr
134
260
  }
135
261
  export type Where<D = Fqn, M = Fqn> = {
136
262
  where: {
137
- expr: ExpressionV2<D, M>
263
+ expr: ExclusiveUnion<{
264
+ Direct: RelationExpr.Direct<D, M>
265
+ Incoming: RelationExpr.Incoming<D, M>
266
+ Outgoing: RelationExpr.Outgoing<D, M>
267
+ InOut: RelationExpr.InOut<D, M>
268
+ }>
138
269
  condition: WhereOperator<string, string>
139
270
  }
140
271
  }
141
- export const isWhere = (expr: ExpressionV2): expr is Where => {
142
- return 'where' in expr
272
+ export const isWhere = (expr: ExpressionV2): expr is RelationExpr.Where => {
273
+ return 'where' in expr &&
274
+ (isDirect(expr.where.expr) || isIncoming(expr.where.expr) || isOutgoing(expr.where.expr) ||
275
+ isInOut(expr.where.expr))
276
+ }
277
+
278
+ export type Custom<D = Fqn, M = Fqn> = {
279
+ customRelation: {
280
+ expr: OrWhere<D, M>
281
+ title?: string
282
+ description?: string
283
+ technology?: string
284
+ notation?: string
285
+ // Link to dynamic view
286
+ navigateTo?: ViewId
287
+ // Notes for walkthrough
288
+ notes?: string
289
+ color?: Color
290
+ line?: RelationshipLineType
291
+ head?: RelationshipArrowType
292
+ tail?: RelationshipArrowType
293
+ }
294
+ }
295
+
296
+ export const isCustom = (expr: ExpressionV2): expr is Custom => {
297
+ return 'customRelation' in expr
298
+ }
299
+
300
+ export const is = (expr: ExpressionV2): expr is RelationExpr => {
301
+ return isDirect(expr)
302
+ || isIncoming(expr)
303
+ || isOutgoing(expr)
304
+ || isInOut(expr)
305
+ }
306
+
307
+ export type OrWhere<D = Fqn, M = Fqn> = ExclusiveUnion<{
308
+ Direct: Direct<D, M>
309
+ Incoming: Incoming<D, M>
310
+ Outgoing: Outgoing<D, M>
311
+ InOut: InOut<D, M>
312
+ Where: Where<D, M>
313
+ }>
314
+
315
+ export type Any<D = Fqn, M = Fqn> = ExclusiveUnion<{
316
+ Direct: Direct<D, M>
317
+ Incoming: Incoming<D, M>
318
+ Outgoing: Outgoing<D, M>
319
+ InOut: InOut<D, M>
320
+ Where: Where<D, M>
321
+ Custom: Custom<D, M>
322
+ }>
323
+
324
+ export const unwrap = (expr: RelationExpr): Direct | Incoming | Outgoing | InOut => {
325
+ if (isCustom(expr)) {
326
+ expr = expr.customRelation.expr
327
+ }
328
+ if (isWhere(expr)) {
329
+ expr = expr.where.expr
330
+ }
331
+ return expr
143
332
  }
144
333
  }
145
334
 
@@ -148,7 +337,6 @@ export type RelationExpr<D = Fqn, M = Fqn> = ExclusiveUnion<{
148
337
  Incoming: RelationExpr.Incoming<D, M>
149
338
  Outgoing: RelationExpr.Outgoing<D, M>
150
339
  InOut: RelationExpr.InOut<D, M>
151
- Where: RelationExpr.Where<D, M>
152
340
  }>
153
341
 
154
342
  /**
@@ -161,24 +349,44 @@ export type ExpressionV2<D = Fqn, M = Fqn> = ExclusiveUnion<{
161
349
  Wildcard: FqnExpr.Wildcard
162
350
  ModelRef: FqnExpr.ModelRef<M>
163
351
  DeploymentRef: FqnExpr.DeploymentRef<D, M>
352
+ ElementKind: FqnExpr.ElementKindExpr
353
+ ElementTag: FqnExpr.ElementTagExpr
354
+ Custom: FqnExpr.Custom<D, M>
164
355
  Direct: RelationExpr.Direct<D, M>
165
356
  Incoming: RelationExpr.Incoming<D, M>
166
357
  Outgoing: RelationExpr.Outgoing<D, M>
167
358
  InOut: RelationExpr.InOut<D, M>
168
- RelationPredicateOrWhere: RelationExpr.Where<D, M>
359
+ Where: ExpressionV2.Where<D, M>
360
+ CustomRelation: RelationExpr.Custom<D, M>
169
361
  }>
170
362
 
171
363
  export namespace ExpressionV2 {
172
- export const isFqnExpr = (expr: ExpressionV2): expr is FqnExpr => {
173
- return FqnExpr.isWildcard(expr)
174
- || FqnExpr.isModelRef(expr)
175
- || FqnExpr.isDeploymentRef(expr)
364
+ export type Where<D = Fqn, M = Fqn> = FqnExpr.Where<D, M> | RelationExpr.Where<D, M>
365
+ // export type Where<D = Fqn, M = Fqn> = {
366
+ // where: ExclusiveUnion<{
367
+ // Fqn: FqnExpr.Where<D, M>['where']['expr']
368
+ // Relation: RelationExpr.Where<D, M>['where']['expr']
369
+ // }>
370
+ // condition: WhereOperator<string, string>
371
+ // }
372
+
373
+ export const isWhere = (expr: ExpressionV2): expr is ExpressionV2.Where => {
374
+ return 'where' in expr
375
+ }
376
+
377
+ export const isRelationWhere = (expr: ExpressionV2): expr is RelationExpr.Where => {
378
+ return RelationExpr.isWhere(expr)
379
+ }
380
+
381
+ export const isFqnExprWhere = (expr: ExpressionV2): expr is FqnExpr.Where => {
382
+ return FqnExpr.isWhere(expr)
383
+ }
384
+
385
+ export const isFqnExpr = (expr: ExpressionV2): expr is FqnExpr.Any => {
386
+ return FqnExpr.is(expr) || FqnExpr.isWhere(expr) || FqnExpr.isCustom(expr)
176
387
  }
177
388
 
178
- export const isRelation = (expr: ExpressionV2): expr is RelationExpr => {
179
- return RelationExpr.isDirect(expr)
180
- || RelationExpr.isIncoming(expr)
181
- || RelationExpr.isOutgoing(expr)
182
- || RelationExpr.isInOut(expr)
389
+ export const isRelation = (expr: ExpressionV2): expr is RelationExpr.Any => {
390
+ return RelationExpr.is(expr) || RelationExpr.isWhere(expr) || RelationExpr.isCustom(expr)
183
391
  }
184
392
  }
@@ -1,7 +1,6 @@
1
1
  export type {
2
2
  CustomColor,
3
3
  ExclusiveUnion,
4
- IconUrl,
5
4
  IteratorLike,
6
5
  KeysOf,
7
6
  NonEmptyArray,
@@ -9,10 +8,23 @@ export type {
9
8
  NTuple,
10
9
  Point,
11
10
  Predicate,
12
- ProjectId,
13
11
  XYPoint,
14
12
  } from './_common'
15
13
 
14
+ export {
15
+ AsFqn,
16
+ GlobalFqn,
17
+ isGlobalFqn,
18
+ splitGlobalFqn,
19
+ } from './scalars'
20
+
21
+ export type {
22
+ Fqn,
23
+ IconUrl,
24
+ ProjectId,
25
+ Tag,
26
+ } from './scalars'
27
+
16
28
  export { DeploymentElement } from './deployments'
17
29
  export type {
18
30
  DeployedInstance,
@@ -26,7 +38,6 @@ export type {
26
38
  } from './deployments'
27
39
 
28
40
  export {
29
- AsFqn,
30
41
  BorderStyles,
31
42
  DefaultElementShape,
32
43
  DefaultPaddingSize,
@@ -43,55 +54,13 @@ export type {
43
54
  ElementKindSpecificationStyle,
44
55
  ElementShape,
45
56
  ElementStyle,
46
- Fqn,
47
57
  Link,
48
- Tag,
49
58
  TagSpec,
50
59
  TypedElement,
51
60
  } from './element'
52
61
 
53
- export {
54
- isCustomElement,
55
- isCustomRelationExpr,
56
- isElement,
57
- isElementKindExpr,
58
- isElementPredicateExpr,
59
- isElementRef,
60
- isElementTagExpr,
61
- isElementWhere,
62
- isExpandedElementExpr,
63
- isIncoming,
64
- isInOut,
65
- isOutgoing,
66
- isRelation,
67
- isRelationExpression,
68
- isRelationPredicateExpr,
69
- isRelationWhere,
70
- isWildcard,
71
- } from './expression'
72
- export type {
73
- CustomElementExpr,
74
- CustomRelationExpr,
75
- DirectRelationExpr,
76
- ElementExpression,
77
- ElementKindExpr,
78
- ElementPredicateExpression,
79
- ElementRefExpr,
80
- ElementTagExpr,
81
- ElementWhereExpr,
82
- ExpandedElementExpr,
83
- Expression,
84
- IncomingExpr,
85
- InOutExpr,
86
- NonWilcard,
87
- OutgoingExpr,
88
- RelationExpression,
89
- RelationPredicateExpression,
90
- RelationWhereExpr,
91
- WildcardExpr,
92
- } from './expression'
93
-
94
62
  export { ExpressionV2, FqnExpr, FqnRef, RelationExpr } from './expression-v2'
63
+ export { ModelLayer } from './expression-v2-model'
95
64
 
96
65
  export type {
97
66
  GlobalDynamicPredicates,
@@ -1,12 +1,14 @@
1
+ import type { NonEmptyArray } from './_common'
1
2
  import type {
2
3
  DeploymentElement,
3
4
  DeploymentNodeKind,
4
5
  DeploymentNodeKindSpecification,
5
6
  DeploymentRelation,
6
7
  } from './deployments'
7
- import type { ElementKindSpecification, Tag, TypedElement } from './element'
8
+ import type { Element, ElementKindSpecification, TypedElement } from './element'
8
9
  import type { ModelGlobals } from './global'
9
10
  import type { ModelRelation, RelationId, RelationshipKindSpecification } from './relation'
11
+ import type { ProjectId, Tag } from './scalars'
10
12
  import type { ComputedView, DiagramView, LikeC4View } from './view'
11
13
 
12
14
  /**
@@ -50,6 +52,7 @@ export interface ParsedLikeC4ModelData<
50
52
  elements: Record<DeploymentFqns, DeploymentElement>
51
53
  relations: Record<RelationId, DeploymentRelation>
52
54
  }
55
+ imports: Record<ProjectId, NonEmptyArray<Element>>
53
56
  }
54
57
 
55
58
  export type AnyParsedLikeC4ModelData = ParsedLikeC4ModelData<any, any, any, any, any, any>
@@ -1,6 +1,7 @@
1
1
  import type { Tagged } from 'type-fest'
2
2
  import type { NonEmptyArray } from './_common'
3
- import type { Fqn, Link, Tag } from './element'
3
+ import type { Link } from './element'
4
+ import type { Fqn, Tag } from './scalars'
4
5
  import type { Color, ThemeColor } from './theme'
5
6
  import type { ViewId } from './view'
6
7
 
@@ -0,0 +1,39 @@
1
+ import { isTruthy } from 'remeda'
2
+ import type { Tagged } from 'type-fest'
3
+ import { invariant } from '../errors'
4
+
5
+ export type ProjectId = Tagged<string, 'ProjectID'>
6
+
7
+ export type IconUrl = Tagged<string, 'IconUrl'> | 'none'
8
+
9
+ // Full-qualified-name
10
+ export type Fqn<Id extends string = string> = Tagged<Id, 'Fqn'>
11
+
12
+ export type Tag<Tags extends string = string> = Tagged<Tags, 'Tag'>
13
+
14
+ export function AsFqn(name: string, parent?: Fqn | null): Fqn {
15
+ return (parent ? parent + '.' + name : name) as Fqn
16
+ }
17
+
18
+ export type GlobalFqn<Id extends string = string> = Tagged<Fqn<Id>, 'GlobalFqn'>
19
+ export function GlobalFqn(projectId: ProjectId, name: string): GlobalFqn {
20
+ invariant(isTruthy(projectId), 'Project ID must start with @')
21
+ return '@' + projectId + '.' + name as GlobalFqn
22
+ }
23
+
24
+ export function isGlobalFqn(fqn: string): fqn is GlobalFqn {
25
+ return fqn.startsWith('@')
26
+ }
27
+
28
+ export function splitGlobalFqn<Id extends string>(fqn: Fqn<Id> | GlobalFqn<Id>): [ProjectId | null, Fqn<Id>] {
29
+ if (!fqn.startsWith('@')) {
30
+ return [null, fqn]
31
+ }
32
+ const firstDot = fqn.indexOf('.')
33
+ if (firstDot < 2) {
34
+ throw new Error('Invalid global FQN')
35
+ }
36
+ const projectId = fqn.slice(1, firstDot) as ProjectId
37
+ const name = fqn.slice(firstDot + 1) as Fqn<Id>
38
+ return [projectId, name]
39
+ }
@@ -1,5 +1,6 @@
1
1
  import type { NonEmptyArray } from './_common'
2
- import type { BorderStyle, ElementShape, Fqn } from './element'
2
+ import type { BorderStyle, ElementShape } from './element'
3
+ import type { Fqn } from './scalars'
3
4
  import type { ThemeColor } from './theme'
4
5
  import type { AutoLayoutDirection, ViewManualLayout } from './view'
5
6
 
package/src/types/view.ts CHANGED
@@ -1,19 +1,18 @@
1
1
  import { isArray, isNullish } from 'remeda'
2
2
  import type { Tagged } from 'type-fest'
3
- import type { IconUrl, NonEmptyArray, Point, XYPoint } from './_common'
3
+ import type { NonEmptyArray, Point, XYPoint } from './_common'
4
4
  import {
5
5
  type BorderStyle,
6
6
  type ElementShape,
7
7
  type ElementStyle,
8
- type Fqn,
9
8
  type Link,
10
- type Tag,
11
9
  ElementKind,
12
10
  } from './element'
13
- import type { ElementExpression, ElementPredicateExpression, Expression } from './expression'
14
11
  import type { ExpressionV2, FqnExpr } from './expression-v2'
12
+ import type { ModelLayer } from './expression-v2-model'
15
13
  import type { GlobalPredicateId, GlobalStyleID } from './global'
16
14
  import type { RelationId, RelationshipArrowType, RelationshipKind, RelationshipLineType } from './relation'
15
+ import type { Fqn, IconUrl, Tag } from './scalars'
17
16
  import type { Color, ShapeSize, SpacingSize, TextSize, ThemeColorValues } from './theme'
18
17
  import type { ElementNotation } from './view-notation'
19
18
 
@@ -21,12 +20,12 @@ export type ViewId<Id extends string = string> = Tagged<Id, 'ViewID'>
21
20
 
22
21
  export type ViewRulePredicate =
23
22
  | {
24
- include: Expression[]
23
+ include: ModelLayer.Expression[]
25
24
  exclude?: never
26
25
  }
27
26
  | {
28
27
  include?: never
29
- exclude: Expression[]
28
+ exclude: ModelLayer.Expression[]
30
29
  }
31
30
 
32
31
  export function isViewRulePredicate(rule: DeploymentViewRule): rule is DeploymentViewRulePredicate
@@ -47,7 +46,7 @@ export function isViewRuleGlobalPredicateRef(rule: ViewRule): rule is ViewRuleGl
47
46
  }
48
47
 
49
48
  export interface ViewRuleStyle {
50
- targets: ElementExpression[]
49
+ targets: ModelLayer.FqnExpr[]
51
50
  notation?: string
52
51
  style: ElementStyle & {
53
52
  color?: Color
@@ -198,7 +197,7 @@ export interface DynamicViewParallelSteps {
198
197
  export type DynamicViewStepOrParallel = DynamicViewStep | DynamicViewParallelSteps
199
198
 
200
199
  export type DynamicViewIncludeRule = {
201
- include: ElementPredicateExpression[]
200
+ include: ModelLayer.AnyFqnExpr[]
202
201
  }
203
202
 
204
203
  export type DynamicViewRule =