@likec4/core 1.27.3 → 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.
- package/dist/builder/index.d.mts +6 -6
- package/dist/builder/index.mjs +23 -13
- package/dist/compute-view/index.d.mts +3 -3
- package/dist/compute-view/index.mjs +3 -3
- package/dist/compute-view/relationships-view/index.d.mts +3 -3
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +2 -2
- package/dist/model/index.d.mts +6 -6
- package/dist/model/index.mjs +1 -1
- package/dist/shared/{core.RjpTh3vE.mjs → core.Bjl6Kmc8.mjs} +260 -168
- package/dist/shared/{core.BpuZeqlX.d.mts → core.CZR9J1Qx.d.mts} +2 -2
- package/dist/shared/{core.Djro-kuQ.d.mts → core.CiFKryGW.d.mts} +7 -2
- package/dist/shared/{core.HKn0jlo_.d.mts → core.D2830qgg.d.mts} +1 -1
- package/dist/shared/{core.CFDwncxs.d.mts → core.DJvmfnEi.d.mts} +481 -186
- package/dist/shared/{core.BMep80lJ.mjs → core.DgfwjBtu.mjs} +198 -87
- package/dist/shared/core.SjLhMA7a.d.mts +62 -0
- package/dist/types/index.d.mts +4 -4
- package/dist/types/index.mjs +1 -1
- package/dist/utils/index.d.mts +2 -2
- package/package.json +6 -6
- package/src/builder/Builder.ts +1 -0
- package/src/builder/Builder.view-common.ts +10 -10
- package/src/builder/Builder.view-element.ts +26 -14
- package/src/builder/__snapshots__/Builder-style1.spec.ts.snap +23 -8
- package/src/builder/__snapshots__/Builder-style2.spec.ts.snap +9 -4
- package/src/compute-view/deployment-view/predicates/deploymentRefs-where.ts +18 -0
- package/src/compute-view/deployment-view/predicates/relation-direct.ts +6 -0
- package/src/compute-view/deployment-view/predicates/relation-in-out.ts +3 -0
- package/src/compute-view/deployment-view/predicates/relation-incoming.ts +3 -0
- package/src/compute-view/deployment-view/predicates/relation-outgoing.ts +3 -0
- package/src/compute-view/deployment-view/predicates/utils.ts +10 -3
- package/src/compute-view/deployment-view/utils.ts +7 -4
- package/src/compute-view/element-view/__test__/fixture.ts +72 -65
- package/src/compute-view/element-view/_types.ts +13 -9
- package/src/compute-view/element-view/compute.ts +27 -27
- package/src/compute-view/element-view/memory/NodeGroup.ts +4 -3
- package/src/compute-view/element-view/memory/memory.ts +3 -2
- package/src/compute-view/element-view/memory/stage-include.ts +2 -2
- package/src/compute-view/element-view/predicates/_utils.ts +25 -24
- package/src/compute-view/element-view/predicates/element-expand.ts +7 -10
- package/src/compute-view/element-view/predicates/element-kind-tag.ts +5 -3
- package/src/compute-view/element-view/predicates/element-ref.ts +7 -19
- package/src/compute-view/element-view/predicates/relation-direct.ts +15 -13
- package/src/compute-view/element-view/predicates/relation-in-out.ts +5 -6
- package/src/compute-view/element-view/predicates/relation-in.ts +36 -32
- package/src/compute-view/element-view/predicates/relation-out.ts +37 -33
- package/src/compute-view/element-view/predicates/wildcard.ts +2 -2
- package/src/compute-view/utils/applyCustomElementProperties.ts +9 -4
- package/src/compute-view/utils/applyCustomRelationProperties.ts +10 -7
- package/src/compute-view/utils/elementExpressionToPredicate.ts +27 -26
- package/src/compute-view/utils/link-nodes-with-edges.ts +1 -1
- package/src/compute-view/utils/relationExpressionToPredicates.ts +10 -17
- package/src/compute-view/utils/uniqueTags.ts +3 -3
- package/src/index.ts +0 -2
- package/src/model/ElementModel.ts +25 -6
- package/src/model/LikeC4Model.ts +44 -6
- package/src/model/RelationModel.ts +4 -2
- package/src/model/view/LikeC4ViewModel.ts +3 -2
- package/src/types/_common.ts +0 -4
- package/src/types/deployments.ts +3 -2
- package/src/types/element.ts +2 -10
- package/src/types/expression-v2-model.ts +314 -0
- package/src/types/expression-v2.ts +238 -30
- package/src/types/index.ts +15 -46
- package/src/types/model-data.ts +4 -1
- package/src/types/relation.ts +2 -1
- package/src/types/scalars.ts +39 -0
- package/src/types/view-changes.ts +2 -1
- package/src/types/view.ts +7 -8
- package/dist/shared/core.30yYKXcZ.d.mts +0 -186
- 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
|
|
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:
|
|
45
|
-
// | [expr:
|
|
46
|
-
expr:
|
|
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<
|
|
46
|
+
ctx: Omit<PredicateCtx<ModelLayer.AnyFqnExpr>, 'expr'>,
|
|
49
47
|
): Stage {
|
|
50
48
|
switch (true) {
|
|
51
|
-
case
|
|
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
|
|
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
|
|
60
|
+
case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'expanded': {
|
|
63
61
|
return ExpandedElementPredicate[op]({ ...ctx, expr } as any) ?? ctx.stage
|
|
64
62
|
}
|
|
65
|
-
case
|
|
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
|
-
|
|
71
|
-
case
|
|
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:
|
|
78
|
+
expr: ModelLayer.AnyRelationExpr,
|
|
79
79
|
op: 'include' | 'exclude',
|
|
80
|
-
ctx: Omit<PredicateCtx<
|
|
80
|
+
ctx: Omit<PredicateCtx<ModelLayer.AnyRelationExpr>, 'expr'>,
|
|
81
81
|
): Stage {
|
|
82
82
|
switch (true) {
|
|
83
|
-
case
|
|
83
|
+
case ModelLayer.RelationExpr.isCustom(expr): {
|
|
84
84
|
if (op === 'include') {
|
|
85
|
-
return processRelationtPredicate(expr.customRelation.
|
|
85
|
+
return processRelationtPredicate(expr.customRelation.expr, op, ctx)
|
|
86
86
|
}
|
|
87
87
|
return ctx.stage
|
|
88
88
|
}
|
|
89
|
-
case
|
|
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
|
|
107
|
+
case ModelLayer.RelationExpr.isInOut(expr): {
|
|
108
108
|
return InOutRelationPredicate[op]({ ...ctx, expr } as any) ?? ctx.stage
|
|
109
109
|
}
|
|
110
|
-
case
|
|
110
|
+
case ModelLayer.RelationExpr.isDirect(expr): {
|
|
111
111
|
return DirectRelationExprPredicate[op]({ ...ctx, expr } as any) ?? ctx.stage
|
|
112
112
|
}
|
|
113
|
-
case
|
|
113
|
+
case ModelLayer.RelationExpr.isOutgoing(expr): {
|
|
114
114
|
return OutgoingExprPredicate[op]({ ...ctx, expr } as any) ?? ctx.stage
|
|
115
115
|
}
|
|
116
|
-
case
|
|
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
|
|
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
|
|
156
|
+
case ModelLayer.isAnyRelationExpr(expr):
|
|
157
157
|
stage = processRelationtPredicate(expr, op, {
|
|
158
158
|
...ctx,
|
|
159
159
|
stage,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ElementKind
|
|
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 {
|
|
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 (
|
|
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
|
|
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:
|
|
13
|
+
export function resolveElements(model: LikeC4Model, expr: ModelLayer.FqnExpr.NonWildcard): Elem[] {
|
|
14
14
|
switch (true) {
|
|
15
|
-
case
|
|
16
|
-
|
|
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
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
|
33
|
-
return [
|
|
34
|
-
|
|
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:
|
|
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 (
|
|
80
|
-
if (nonWildcard.
|
|
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
|
|
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<
|
|
6
|
+
export const ExpandedElementPredicate: PredicateExecutor<ModelLayer.FqnExpr.ModelRef> = {
|
|
6
7
|
include: ({ expr, model, stage, where }) => {
|
|
7
|
-
const parent = model.element(expr.
|
|
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,
|
|
25
|
-
const
|
|
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
|
|
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<
|
|
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
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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 =
|
|
17
|
-
const targetIsWildcard =
|
|
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(!
|
|
170
|
-
invariant(!
|
|
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 =
|
|
190
|
-
const targetIsWildcard =
|
|
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(!
|
|
253
|
-
invariant(!
|
|
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:
|
|
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 (
|
|
293
|
-
const parent = model.element(
|
|
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
|
|
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<
|
|
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 (
|
|
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 (
|
|
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
|
|
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<
|
|
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 (
|
|
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 (
|
|
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:
|
|
83
|
+
expr: ModelLayer.FqnExpr.NonWildcard,
|
|
84
84
|
): ConnectionWhere {
|
|
85
85
|
switch (true) {
|
|
86
|
-
case
|
|
87
|
-
case
|
|
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
|
|
91
|
+
case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'children': {
|
|
92
|
+
const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
|
|
92
93
|
return anyPass(
|
|
93
|
-
[...model.children(
|
|
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
|
|
99
|
+
case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'descendants': {
|
|
100
|
+
const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
|
|
99
101
|
return anyPass([
|
|
100
|
-
Connection.isInside(
|
|
101
|
-
...[...model.children(
|
|
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
|
|
108
|
+
case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'expanded': {
|
|
109
|
+
const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
|
|
107
110
|
return anyPass([
|
|
108
|
-
Connection.isIncoming(
|
|
109
|
-
Connection.isInside(
|
|
111
|
+
Connection.isIncoming(fqn),
|
|
112
|
+
Connection.isInside(fqn),
|
|
110
113
|
])
|
|
111
114
|
}
|
|
112
|
-
case
|
|
113
|
-
|
|
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)
|