@likec4/core 1.27.2 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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.RjpTh3vE.mjs → core.Bjl6Kmc8.mjs} +260 -168
  11. package/dist/shared/{core.C9JdFlAd.d.mts → core.CZR9J1Qx.d.mts} +2 -2
  12. package/dist/shared/{core.C7IN6igU.d.mts → core.CiFKryGW.d.mts} +7 -2
  13. package/dist/shared/{core.HKn0jlo_.d.mts → core.D2830qgg.d.mts} +1 -1
  14. package/dist/shared/{core.z6g06scf.d.mts → core.DJvmfnEi.d.mts} +484 -189
  15. package/dist/shared/{core.BMep80lJ.mjs → core.DgfwjBtu.mjs} +198 -87
  16. package/dist/shared/core.SjLhMA7a.d.mts +62 -0
  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 +6 -6
  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 +44 -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 +10 -11
  70. package/dist/shared/core.30yYKXcZ.d.mts +0 -186
  71. package/src/types/expression.ts +0 -207
@@ -7,14 +7,12 @@ import type { RelationshipModel } from '../../model/RelationModel'
7
7
  import type { AnyAux } from '../../model/types'
8
8
  import type {
9
9
  ComputedElementView,
10
- ElementPredicateExpression,
11
10
  ElementView,
12
11
  NodeId,
13
- RelationPredicateExpression,
14
12
  ViewRule,
15
13
  } from '../../types'
16
14
  import { isViewRuleAutoLayout, isViewRuleGroup, isViewRulePredicate, whereOperatorAsPredicate } from '../../types'
17
- import * as Expr from '../../types/expression'
15
+ import { ModelLayer } from '../../types/expression-v2-model'
18
16
  import { sortParentsFirst } from '../../utils'
19
17
  import { DefaultMap } from '../../utils/mnemonist'
20
18
  import { applyCustomElementProperties } from '../utils/applyCustomElementProperties'
@@ -41,52 +39,54 @@ import { buildNodes, NoFilter, NoWhere, toComputedEdges } from './utils'
41
39
 
42
40
  function processElementPredicate(
43
41
  // ...args:
44
- // | [expr: ElementPredicateExpression, op: 'include', IncludePredicateCtx<ElementPredicateExpression>]
45
- // | [expr: ElementPredicateExpression, op: 'exclude', ExcludePredicateCtx<ElementPredicateExpression>]
46
- expr: ElementPredicateExpression,
42
+ // | [expr: ModelLayer.AnyFqnExpr, op: 'include', IncludePredicateCtx<ModelLayer.AnyFqnExpr>]
43
+ // | [expr: ModelLayer.AnyFqnExpr, op: 'exclude', ExcludePredicateCtx<ModelLayer.AnyFqnExpr>]
44
+ expr: ModelLayer.AnyFqnExpr,
47
45
  op: 'include' | 'exclude',
48
- ctx: Omit<PredicateCtx<RelationPredicateExpression>, 'expr'>,
46
+ ctx: Omit<PredicateCtx<ModelLayer.AnyFqnExpr>, 'expr'>,
49
47
  ): Stage {
50
48
  switch (true) {
51
- case Expr.isCustomElement(expr): {
49
+ case ModelLayer.FqnExpr.isCustom(expr): {
52
50
  if (op === 'include') {
53
51
  return processElementPredicate(expr.custom.expr, op, ctx)
54
52
  }
55
53
  return ctx.stage
56
54
  }
57
- case Expr.isElementWhere(expr): {
55
+ case ModelLayer.FqnExpr.isWhere(expr): {
58
56
  const where = whereOperatorAsPredicate(expr.where.condition)
59
57
  const filterWhere = filter<Elem>(where)
60
58
  return processElementPredicate(expr.where.expr, op, { ...ctx, where, filterWhere } as any)
61
59
  }
62
- case Expr.isExpandedElementExpr(expr): {
60
+ case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'expanded': {
63
61
  return ExpandedElementPredicate[op]({ ...ctx, expr } as any) ?? ctx.stage
64
62
  }
65
- case Expr.isElementRef(expr): {
66
- return ElementRefPredicate[op]({ ...ctx, expr } as any) ?? ctx.stage
67
- }
68
- case Expr.isWildcard(expr):
63
+ case ModelLayer.FqnExpr.isWildcard(expr): {
69
64
  return WildcardPredicate[op]({ ...ctx, expr } as any) ?? ctx.stage
70
- case Expr.isElementKindExpr(expr):
71
- case Expr.isElementTagExpr(expr):
65
+ }
66
+ case ModelLayer.FqnExpr.isElementKindExpr(expr):
67
+ case ModelLayer.FqnExpr.isElementTagExpr(expr): {
72
68
  return ElementKindOrTagPredicate[op]({ ...ctx, expr } as any) ?? ctx.stage
69
+ }
70
+ case ModelLayer.FqnExpr.isModelRef(expr): {
71
+ return ElementRefPredicate[op]({ ...ctx, expr } as any) ?? ctx.stage
72
+ }
73
73
  default:
74
74
  nonexhaustive(expr)
75
75
  }
76
76
  }
77
77
  function processRelationtPredicate(
78
- expr: RelationPredicateExpression,
78
+ expr: ModelLayer.AnyRelationExpr,
79
79
  op: 'include' | 'exclude',
80
- ctx: Omit<PredicateCtx<RelationPredicateExpression>, 'expr'>,
80
+ ctx: Omit<PredicateCtx<ModelLayer.AnyRelationExpr>, 'expr'>,
81
81
  ): Stage {
82
82
  switch (true) {
83
- case Expr.isCustomRelationExpr(expr): {
83
+ case ModelLayer.RelationExpr.isCustom(expr): {
84
84
  if (op === 'include') {
85
- return processRelationtPredicate(expr.customRelation.relation, op, ctx)
85
+ return processRelationtPredicate(expr.customRelation.expr, op, ctx)
86
86
  }
87
87
  return ctx.stage
88
88
  }
89
- case Expr.isRelationWhere(expr): {
89
+ case ModelLayer.RelationExpr.isWhere(expr): {
90
90
  const where = whereOperatorAsPredicate(expr.where.condition)
91
91
  const filterRelations = (relations: ReadonlySet<RelationshipModel>) => {
92
92
  return new Set(filter([...relations], where))
@@ -104,16 +104,16 @@ function processRelationtPredicate(
104
104
  filterWhere,
105
105
  })
106
106
  }
107
- case Expr.isInOut(expr): {
107
+ case ModelLayer.RelationExpr.isInOut(expr): {
108
108
  return InOutRelationPredicate[op]({ ...ctx, expr } as any) ?? ctx.stage
109
109
  }
110
- case Expr.isRelation(expr): {
110
+ case ModelLayer.RelationExpr.isDirect(expr): {
111
111
  return DirectRelationExprPredicate[op]({ ...ctx, expr } as any) ?? ctx.stage
112
112
  }
113
- case Expr.isOutgoing(expr): {
113
+ case ModelLayer.RelationExpr.isOutgoing(expr): {
114
114
  return OutgoingExprPredicate[op]({ ...ctx, expr } as any) ?? ctx.stage
115
115
  }
116
- case Expr.isIncoming(expr): {
116
+ case ModelLayer.RelationExpr.isIncoming(expr): {
117
117
  return IncomingExprPredicate[op]({ ...ctx, expr } as any) ?? ctx.stage
118
118
  }
119
119
  default:
@@ -146,14 +146,14 @@ export function processPredicates<M extends AnyAux>(
146
146
  for (const expr of exprs) {
147
147
  let stage = op === 'include' ? memory.stageInclude(expr) : memory.stageExclude(expr)
148
148
  switch (true) {
149
- case Expr.isElementPredicateExpr(expr):
149
+ case ModelLayer.isAnyFqnExpr(expr):
150
150
  stage = processElementPredicate(expr, op, {
151
151
  ...ctx,
152
152
  stage,
153
153
  memory,
154
154
  } as any) ?? stage
155
155
  break
156
- case Expr.isRelationPredicateExpr(expr):
156
+ case ModelLayer.isAnyRelationExpr(expr):
157
157
  stage = processRelationtPredicate(expr, op, {
158
158
  ...ctx,
159
159
  stage,
@@ -1,4 +1,5 @@
1
- import { ElementKind, type NodeId, type ViewRuleGroup } from '../../../types'
1
+ import { ElementKind } from '../../../types/element'
2
+ import { type NodeId, type ViewRuleGroup } from '../../../types/view'
2
3
  import type { Elem } from '../_types'
3
4
 
4
5
  export class NodesGroup {
@@ -8,7 +9,7 @@ export class NodesGroup {
8
9
  public readonly id: NodeId,
9
10
  public readonly viewRule: ViewRuleGroup,
10
11
  public readonly parent: NodeId | null = null,
11
- public readonly elements: ReadonlySet<Elem> = new Set<Elem>()
12
+ public readonly elements: ReadonlySet<Elem> = new Set<Elem>(),
12
13
  ) {
13
14
  }
14
15
 
@@ -21,7 +22,7 @@ export class NodesGroup {
21
22
  this.id,
22
23
  this.viewRule,
23
24
  this.parent,
24
- elements
25
+ elements,
25
26
  )
26
27
  }
27
28
 
@@ -1,7 +1,8 @@
1
1
  import { nonNullable } from '../../../errors'
2
2
  import type { ConnectionModel } from '../../../model/connection'
3
3
  import type { ElementModel } from '../../../model/ElementModel'
4
- import type { Expression, NodeId, ViewRuleGroup } from '../../../types'
4
+ import type { ModelLayer } from '../../../types/expression-v2-model'
5
+ import type { NodeId, ViewRuleGroup } from '../../../types/view'
5
6
  import { Stack } from '../../../utils/mnemonist'
6
7
  import { type ComputeCtx, type CtxElement, type MutableState, type StageExpression, AbstractMemory } from '../../memory'
7
8
  import { NodesGroup } from './NodeGroup'
@@ -15,7 +16,7 @@ export interface Ctx extends
15
16
  Memory<Ctx>,
16
17
  StageInclude<Ctx>,
17
18
  StageExclude,
18
- Expression
19
+ ModelLayer.Expression
19
20
  >
20
21
  {
21
22
  MutableState: {
@@ -1,6 +1,6 @@
1
1
  import { dropWhile, forEach, pipe, take, zip } from 'remeda'
2
- import { Expr } from '../../..'
3
2
  import { findConnection, findConnectionsBetween } from '../../../model/connection/model'
3
+ import { ModelLayer } from '../../../types/expression-v2-model'
4
4
  import { difference, isAncestor, isIterable } from '../../../utils'
5
5
  import { toArray } from '../../../utils/iterable'
6
6
  import { type CtxConnection, type StageExpression, AbstractStageInclude } from '../../memory'
@@ -62,7 +62,7 @@ export class StageInclude<C extends Ctx = Ctx> extends AbstractStageInclude<C> {
62
62
  }
63
63
 
64
64
  protected override processConnections(connections: CtxConnection<Ctx>[]) {
65
- if (Expr.isRelationPredicateExpr(this.expression)) {
65
+ if (ModelLayer.isAnyRelationExpr(this.expression)) {
66
66
  return connections
67
67
  }
68
68
 
@@ -1,7 +1,7 @@
1
1
  import { anyPass } from 'remeda'
2
2
  import { nonexhaustive } from '../../../errors'
3
- import type { LikeC4Model } from '../../../model'
4
- import * as Expr from '../../../types/expression'
3
+ import type { LikeC4Model } from '../../../model/LikeC4Model'
4
+ import { ModelLayer } from '../../../types/expression-v2-model'
5
5
  import { isDescendantOf } from '../../../utils/fqn'
6
6
  import { ifilter, toArray } from '../../../utils/iterable'
7
7
  import type { Elem, Memory, PredicateCtx } from '../_types'
@@ -10,33 +10,34 @@ import type { Elem, Memory, PredicateCtx } from '../_types'
10
10
  * Resolve elements from the model based on the given expression
11
11
  */
12
12
 
13
- export function resolveElements(model: LikeC4Model, expr: Exclude<Expr.ElementExpression, Expr.WildcardExpr>): Elem[] {
13
+ export function resolveElements(model: LikeC4Model, expr: ModelLayer.FqnExpr.NonWildcard): Elem[] {
14
14
  switch (true) {
15
- case Expr.isExpandedElementExpr(expr): {
16
- const element = model.element(expr.expanded)
15
+ case ModelLayer.FqnExpr.isElementKindExpr(expr): {
16
+ return [...ifilter(model.elements(), el => {
17
+ return expr.isEqual === (el.kind === expr.elementKind)
18
+ })]
19
+ }
20
+ case ModelLayer.FqnExpr.isElementTagExpr(expr): {
21
+ return [...ifilter(model.elements(), el => {
22
+ return expr.isEqual === el.tags.includes(expr.elementTag)
23
+ })]
24
+ }
25
+ case expr.selector === 'expanded': {
26
+ const element = model.element(ModelLayer.FqnRef.toFqn(expr.ref))
17
27
  return [
18
28
  element,
19
29
  ...element.children(),
20
30
  ]
21
31
  }
22
- case Expr.isElementRef(expr): {
23
- const element = model.element(expr.element)
24
- let children
25
- if (expr.isChildren) {
26
- children = toArray(element.children())
27
- } else if (expr.isDescendants) {
28
- children = toArray(element.descendants())
29
- }
32
+ case expr.selector === 'children':
33
+ case expr.selector === 'descendants': {
34
+ const element = model.element(ModelLayer.FqnRef.toFqn(expr.ref))
35
+ let children = expr.selector === 'children' ? toArray(element.children()) : toArray(element.descendants())
30
36
  return children && children.length > 0 ? children : [element]
31
37
  }
32
- case Expr.isElementKindExpr(expr):
33
- return [...ifilter(model.elements(), el => {
34
- return expr.isEqual === (el.kind === expr.elementKind)
35
- })]
36
- case Expr.isElementTagExpr(expr):
37
- return [...ifilter(model.elements(), el => {
38
- return expr.isEqual === el.tags.includes(expr.elementTag)
39
- })]
38
+ case ModelLayer.FqnExpr.isModelRef(expr): {
39
+ return [model.element(ModelLayer.FqnRef.toFqn(expr.ref))]
40
+ }
40
41
  default:
41
42
  nonexhaustive(expr)
42
43
  }
@@ -69,15 +70,15 @@ export function includeDescendantsFromMemory(elements: Elem[], memory: Memory):
69
70
  * Combination of `resolveElements` and `includeDescendantsFromMemory`
70
71
  */
71
72
  export function resolveAndIncludeFromMemory(
72
- nonWildcard: Expr.NonWilcard,
73
+ nonWildcard: ModelLayer.FqnExpr.NonWildcard,
73
74
  { memory, model }: Pick<PredicateCtx, 'model' | 'memory'>,
74
75
  ): Elem[] {
75
76
  const resolved = resolveElements(model, nonWildcard)
76
77
  // We include from memory only if the expression is:
77
78
  // - expanded element
78
79
  // - element reference with or with children (but not descendants - they are already included)
79
- if (Expr.isExpandedElementExpr(nonWildcard) || Expr.isElementRef(nonWildcard)) {
80
- if (nonWildcard.isDescendants === true) {
80
+ if (ModelLayer.FqnExpr.isModelRef(nonWildcard)) {
81
+ if (nonWildcard.selector === 'descendants') {
81
82
  return resolved
82
83
  }
83
84
  return includeDescendantsFromMemory(resolved, memory)
@@ -1,10 +1,11 @@
1
1
  import { findConnectionsWithin } from '../../../model/connection/model'
2
- import type * as Expr from '../../../types/expression'
2
+ import { ModelLayer } from '../../../types/expression-v2-model'
3
3
  import type { Elem, PredicateExecutor } from '../_types'
4
+ import { resolveElements } from './_utils'
4
5
 
5
- export const ExpandedElementPredicate: PredicateExecutor<Expr.ExpandedElementExpr> = {
6
+ export const ExpandedElementPredicate: PredicateExecutor<ModelLayer.FqnExpr.ModelRef> = {
6
7
  include: ({ expr, model, stage, where }) => {
7
- const parent = model.element(expr.expanded)
8
+ const parent = model.element(ModelLayer.FqnRef.toFqn(expr.ref))
8
9
  if (where(parent)) {
9
10
  stage.addExplicit(parent)
10
11
  stage.connectWithExisting(parent)
@@ -21,13 +22,9 @@ export const ExpandedElementPredicate: PredicateExecutor<Expr.ExpandedElementExp
21
22
  stage.addConnections(findConnectionsWithin(expanded))
22
23
  return stage
23
24
  },
24
- exclude: ({ expr, model, stage, where }) => {
25
- const parent = model.element(expr.expanded)
26
- const elements = [
27
- parent,
28
- ...parent.children()
29
- ].filter(where)
25
+ exclude: ({ expr, model, stage, filterWhere }) => {
26
+ const elements = filterWhere(resolveElements(model, expr))
30
27
  stage.exclude(elements)
31
28
  return stage
32
- }
29
+ },
33
30
  }
@@ -1,9 +1,11 @@
1
1
  import { findConnectionsWithin } from '../../../model/connection/model'
2
- import * as Expr from '../../../types/expression'
2
+ import type { ModelLayer } from '../../../types/expression-v2-model'
3
3
  import type { PredicateExecutor } from '../_types'
4
4
  import { resolveElements } from './_utils'
5
5
 
6
- export const ElementKindOrTagPredicate: PredicateExecutor<Expr.ElementKindExpr | Expr.ElementTagExpr> = {
6
+ export const ElementKindOrTagPredicate: PredicateExecutor<
7
+ ModelLayer.FqnExpr.ElementKindExpr | ModelLayer.FqnExpr.ElementTagExpr
8
+ > = {
7
9
  include: ({ expr, model, stage, filterWhere }) => {
8
10
  const elements = filterWhere(resolveElements(model, expr))
9
11
  if (elements.length === 0) {
@@ -22,5 +24,5 @@ export const ElementKindOrTagPredicate: PredicateExecutor<Expr.ElementKindExpr |
22
24
  stage.exclude(elements)
23
25
 
24
26
  return stage
25
- }
27
+ },
26
28
  }
@@ -1,22 +1,11 @@
1
1
  import { findConnectionsWithin } from '../../../model/connection/model'
2
- import type { ElementRefExpr } from '../../../types/expression'
3
- import * as Expr from '../../../types/expression'
2
+ import { ModelLayer } from '../../../types/expression-v2-model'
4
3
  import type { Elem, PredicateExecutor } from '../_types'
4
+ import { resolveElements } from './_utils'
5
5
 
6
- function applyElementSelector(elem: Elem, expr: Expr.ElementRefExpr) {
7
- let children
8
- if (expr.isChildren) {
9
- children = [...elem.children()]
10
- } else if (expr.isDescendants) {
11
- children = [...elem.descendants()]
12
- }
13
- return children && children.length > 0 ? children : [elem]
14
- }
15
-
16
- export const ElementRefPredicate: PredicateExecutor<ElementRefExpr> = {
17
- include: ({ expr, model, stage, where }) => {
18
- const element = model.element(expr.element)
19
- const elements = applyElementSelector(element, expr).filter(where)
6
+ export const ElementRefPredicate: PredicateExecutor<ModelLayer.FqnExpr.ModelRef> = {
7
+ include: ({ expr, model, stage, filterWhere }) => {
8
+ const elements = filterWhere(resolveElements(model, expr))
20
9
  if (elements.length === 0) {
21
10
  return
22
11
  }
@@ -28,10 +17,9 @@ export const ElementRefPredicate: PredicateExecutor<ElementRefExpr> = {
28
17
  return stage
29
18
  },
30
19
  exclude: ({ expr, model, stage, filterWhere }) => {
31
- const element = model.element(expr.element)
32
- const elements = filterWhere(applyElementSelector(element, expr))
20
+ const elements = filterWhere(resolveElements(model, expr))
33
21
  stage.exclude(elements)
34
22
 
35
23
  return stage
36
- }
24
+ },
37
25
  }
@@ -3,7 +3,7 @@ import { invariant } from '../../../errors'
3
3
  import { ConnectionModel, findConnectionsBetween, findConnectionsWithin } from '../../../model/connection/model'
4
4
  import type { RelationshipModel } from '../../../model/RelationModel'
5
5
  import type { AnyAux } from '../../../model/types'
6
- import * as Expr from '../../../types/expression'
6
+ import { ModelLayer } from '../../../types/expression-v2-model'
7
7
  import { isSameHierarchy } from '../../../utils'
8
8
  import { ifilter, iflat, iunique, toArray, toSet } from '../../../utils/iterable'
9
9
  import { intersection, union } from '../../../utils/set'
@@ -11,10 +11,12 @@ import type { Elem, PredicateCtx, PredicateExecutor } from '../_types'
11
11
  import { NoWhere } from '../utils'
12
12
  import { includeDescendantsFromMemory, resolveAndIncludeFromMemory, resolveElements } from './_utils'
13
13
 
14
- export const DirectRelationExprPredicate: PredicateExecutor<Expr.DirectRelationExpr> = {
14
+ const isWildcard = ModelLayer.FqnExpr.isWildcard
15
+
16
+ export const DirectRelationExprPredicate: PredicateExecutor<ModelLayer.RelationExpr.Direct> = {
15
17
  include: ({ expr: { source, target, isBidirectional = false }, memory, model, stage, where, filterWhere }) => {
16
- const sourceIsWildcard = Expr.isWildcard(source)
17
- const targetIsWildcard = Expr.isWildcard(target)
18
+ const sourceIsWildcard = isWildcard(source)
19
+ const targetIsWildcard = isWildcard(target)
18
20
 
19
21
  const connections = [] as ConnectionModel<AnyAux>[]
20
22
  switch (true) {
@@ -166,8 +168,8 @@ export const DirectRelationExprPredicate: PredicateExecutor<Expr.DirectRelationE
166
168
  }
167
169
 
168
170
  default: {
169
- invariant(!Expr.isWildcard(source), 'Inference failed - source must be not a wildcard')
170
- invariant(!Expr.isWildcard(target), 'Inference failed - target must be not a wildcard')
171
+ invariant(!isWildcard(source), 'Inference failed - source must be not a wildcard')
172
+ invariant(!isWildcard(target), 'Inference failed - target must be not a wildcard')
171
173
  const sources = resolveAndIncludeFromMemory(source, { memory, model })
172
174
  const targets = resolveAndIncludeFromMemory(target, { memory, model })
173
175
  const dir = isBidirectional ? 'both' : 'directed'
@@ -186,8 +188,8 @@ export const DirectRelationExprPredicate: PredicateExecutor<Expr.DirectRelationE
186
188
  return stage
187
189
  },
188
190
  exclude: ({ expr: { source, target, isBidirectional }, model, memory, stage, where }) => {
189
- const sourceIsWildcard = Expr.isWildcard(source)
190
- const targetIsWildcard = Expr.isWildcard(target)
191
+ const sourceIsWildcard = isWildcard(source)
192
+ const targetIsWildcard = isWildcard(target)
191
193
 
192
194
  let relations: Set<RelationshipModel<AnyAux>>
193
195
 
@@ -249,8 +251,8 @@ export const DirectRelationExprPredicate: PredicateExecutor<Expr.DirectRelationE
249
251
  }
250
252
 
251
253
  default: {
252
- invariant(!Expr.isWildcard(source), 'Inferrence failed - source must be not a wildcard')
253
- invariant(!Expr.isWildcard(target), 'Inferrence failed - target must be not a wildcard')
254
+ invariant(!isWildcard(source), 'Inferrence failed - source must be not a wildcard')
255
+ invariant(!isWildcard(target), 'Inferrence failed - target must be not a wildcard')
254
256
  const sources = resolveElements(model, source)
255
257
  const targets = resolveElements(model, target)
256
258
 
@@ -281,7 +283,7 @@ export const DirectRelationExprPredicate: PredicateExecutor<Expr.DirectRelationE
281
283
  * Resolve elements for both source and target, when one of them is a wildcard
282
284
  */
283
285
  function resolveWildcard(
284
- nonWildcard: Expr.NonWilcard,
286
+ nonWildcard: ModelLayer.FqnExpr.NonWildcard,
285
287
  { memory, model }: Pick<PredicateCtx, 'model' | 'memory'>,
286
288
  ): [elements: Elem[], wildcard: Elem[]] {
287
289
  let sources = resolveElements(model, nonWildcard)
@@ -289,8 +291,8 @@ function resolveWildcard(
289
291
  return [[], []]
290
292
  }
291
293
 
292
- if (Expr.isExpandedElementExpr(nonWildcard) || Expr.isElementRef(nonWildcard)) {
293
- const parent = model.element(nonWildcard.element ?? nonWildcard.expanded)
294
+ if (ModelLayer.FqnExpr.isModelRef(nonWildcard)) {
295
+ const parent = model.element(ModelLayer.FqnRef.toFqn(nonWildcard.ref))
294
296
  const targets = toArray(parent.ascendingSiblings())
295
297
  return [
296
298
  includeDescendantsFromMemory(sources, memory),
@@ -2,16 +2,15 @@ import { unique } from 'remeda'
2
2
  import { type ConnectionModel, findConnectionsBetween } from '../../../model/connection/model'
3
3
  import type { RelationshipModel } from '../../../model/RelationModel'
4
4
  import type { AnyAux } from '../../../model/types'
5
- import * as Expr from '../../../types/expression'
6
- import { toArray } from '../../../utils/iterable'
7
- import { toSet } from '../../../utils/iterable/to'
5
+ import { ModelLayer } from '../../../types/expression-v2-model'
6
+ import { toArray, toSet } from '../../../utils/iterable/to'
8
7
  import type { PredicateExecutor } from '../_types'
9
8
  import { resolveAndIncludeFromMemory, resolveElements } from './_utils'
10
9
 
11
- export const InOutRelationPredicate: PredicateExecutor<Expr.InOutExpr> = {
10
+ export const InOutRelationPredicate: PredicateExecutor<ModelLayer.RelationExpr.InOut> = {
12
11
  include: ({ expr: { inout }, scope, model, memory, stage, filterWhere }) => {
13
12
  const connections = [] as ConnectionModel<AnyAux>[]
14
- if (Expr.isWildcard(inout)) {
13
+ if (ModelLayer.FqnExpr.isWildcard(inout)) {
15
14
  if (!scope) {
16
15
  return
17
16
  }
@@ -47,7 +46,7 @@ export const InOutRelationPredicate: PredicateExecutor<Expr.InOutExpr> = {
47
46
  },
48
47
  exclude: ({ expr: { inout }, model, scope, stage, where }) => {
49
48
  const excluded = [] as RelationshipModel[]
50
- if (Expr.isWildcard(inout)) {
49
+ if (ModelLayer.FqnExpr.isWildcard(inout)) {
51
50
  if (!scope) {
52
51
  return
53
52
  }
@@ -2,23 +2,23 @@ import { anyPass, unique } from 'remeda'
2
2
  import { nonexhaustive } from '../../../errors'
3
3
  import type { LikeC4Model } from '../../../model'
4
4
  import {
5
- Connection,
6
5
  type ConnectionModel,
6
+ Connection,
7
7
  findConnection,
8
- findConnectionsBetween
8
+ findConnectionsBetween,
9
9
  } from '../../../model/connection/model'
10
10
  import type { RelationshipModel } from '../../../model/RelationModel'
11
11
  import type { AnyAux } from '../../../model/types'
12
- import * as Expr from '../../../types/expression'
12
+ import { ModelLayer } from '../../../types/expression-v2-model'
13
13
  import { elementExprToPredicate } from '../../utils/elementExpressionToPredicate'
14
14
  import type { ConnectionWhere, PredicateExecutor } from '../_types'
15
15
  import { resolveAndIncludeFromMemory, resolveElements } from './_utils'
16
16
 
17
- export const IncomingExprPredicate: PredicateExecutor<Expr.IncomingExpr> = {
17
+ export const IncomingExprPredicate: PredicateExecutor<ModelLayer.RelationExpr.Incoming> = {
18
18
  include: ({ expr, scope, model, memory, stage, filterWhere }) => {
19
19
  const target = expr.incoming
20
20
  const connections = [] as ConnectionModel<AnyAux>[]
21
- if (Expr.isWildcard(target)) {
21
+ if (ModelLayer.FqnExpr.isWildcard(target)) {
22
22
  if (!scope) {
23
23
  return
24
24
  }
@@ -27,8 +27,8 @@ export const IncomingExprPredicate: PredicateExecutor<Expr.IncomingExpr> = {
27
27
  ...findConnection(
28
28
  sibling,
29
29
  scope,
30
- 'directed'
31
- )
30
+ 'directed',
31
+ ),
32
32
  )
33
33
  }
34
34
  } else {
@@ -37,8 +37,8 @@ export const IncomingExprPredicate: PredicateExecutor<Expr.IncomingExpr> = {
37
37
  if (visibleElements.length === 0) {
38
38
  visibleElements.push(
39
39
  ...unique(
40
- targets.flatMap(el => [...el.ascendingSiblings()])
41
- )
40
+ targets.flatMap(el => [...el.ascendingSiblings()]),
41
+ ),
42
42
  )
43
43
  }
44
44
  const ensureIncoming = incomingConnectionPredicate(model, target)
@@ -47,21 +47,21 @@ export const IncomingExprPredicate: PredicateExecutor<Expr.IncomingExpr> = {
47
47
  ...findConnectionsBetween(
48
48
  visible,
49
49
  targets,
50
- 'directed'
51
- ).filter(ensureIncoming)
50
+ 'directed',
51
+ ).filter(ensureIncoming),
52
52
  )
53
53
  }
54
54
  }
55
55
 
56
56
  stage.addConnections(
57
- filterWhere(connections)
57
+ filterWhere(connections),
58
58
  )
59
59
 
60
60
  return stage
61
61
  },
62
62
  exclude: ({ expr: { incoming }, model, scope, stage, where }) => {
63
63
  const excluded = [] as RelationshipModel[]
64
- if (Expr.isWildcard(incoming)) {
64
+ if (ModelLayer.FqnExpr.isWildcard(incoming)) {
65
65
  if (!scope) {
66
66
  return
67
67
  }
@@ -69,48 +69,52 @@ export const IncomingExprPredicate: PredicateExecutor<Expr.IncomingExpr> = {
69
69
  } else {
70
70
  const elements = resolveElements(model, incoming)
71
71
  excluded.push(
72
- ...elements.flatMap(e => [...e.allIncoming])
72
+ ...elements.flatMap(e => [...e.allIncoming]),
73
73
  )
74
74
  }
75
75
  stage.excludeRelations(new Set(excluded.filter(where)))
76
76
 
77
77
  return stage
78
- }
78
+ },
79
79
  }
80
80
 
81
81
  export function incomingConnectionPredicate(
82
82
  model: LikeC4Model,
83
- expr: Exclude<Expr.ElementExpression, Expr.WildcardExpr>
83
+ expr: ModelLayer.FqnExpr.NonWildcard,
84
84
  ): ConnectionWhere {
85
85
  switch (true) {
86
- case Expr.isElementKindExpr(expr):
87
- case Expr.isElementTagExpr(expr): {
86
+ case ModelLayer.FqnExpr.isElementKindExpr(expr):
87
+ case ModelLayer.FqnExpr.isElementTagExpr(expr): {
88
88
  const isElement = elementExprToPredicate(expr)
89
89
  return (connection) => isElement(connection.target)
90
90
  }
91
- case Expr.isElementRef(expr) && expr.isChildren: {
91
+ case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'children': {
92
+ const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
92
93
  return anyPass(
93
- [...model.children(expr.element)].map(
94
- el => Connection.isIncoming(el.id)
95
- )
94
+ [...model.children(fqn)].map(
95
+ el => Connection.isIncoming(el.id),
96
+ ),
96
97
  )
97
98
  }
98
- case Expr.isElementRef(expr) && expr.isDescendants: {
99
+ case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'descendants': {
100
+ const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
99
101
  return anyPass([
100
- Connection.isInside(expr.element),
101
- ...[...model.children(expr.element)].map(
102
- el => Connection.isIncoming(el.id)
103
- )
102
+ Connection.isInside(fqn),
103
+ ...[...model.children(fqn)].map(
104
+ el => Connection.isIncoming(el.id),
105
+ ),
104
106
  ])
105
107
  }
106
- case Expr.isExpandedElementExpr(expr): {
108
+ case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'expanded': {
109
+ const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
107
110
  return anyPass([
108
- Connection.isIncoming(expr.expanded),
109
- Connection.isInside(expr.expanded)
111
+ Connection.isIncoming(fqn),
112
+ Connection.isInside(fqn),
110
113
  ])
111
114
  }
112
- case Expr.isElementRef(expr): {
113
- return Connection.isIncoming(expr.element)
115
+ case ModelLayer.FqnExpr.isModelRef(expr): {
116
+ const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
117
+ return Connection.isIncoming(fqn)
114
118
  }
115
119
  default:
116
120
  nonexhaustive(expr)