@likec4/core 1.19.1 → 1.20.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.cjs +881 -0
- package/dist/builder/index.d.cts +503 -0
- package/dist/builder/index.d.mts +5 -4
- package/dist/builder/index.d.ts +5 -4
- package/dist/builder/{index.js → index.mjs} +14 -4
- package/dist/compute-view/index.cjs +86 -0
- package/dist/compute-view/index.d.cts +23 -0
- package/dist/compute-view/index.d.mts +3 -2
- package/dist/compute-view/index.d.ts +3 -2
- package/dist/compute-view/{index.js → index.mjs} +6 -5
- package/dist/index.cjs +4320 -0
- package/dist/index.d.cts +270 -0
- package/dist/index.d.mts +130 -4
- package/dist/index.d.ts +130 -4
- package/dist/{index.js → index.mjs} +512 -7
- package/dist/model/index.cjs +40 -0
- package/dist/model/index.d.cts +259 -0
- package/dist/model/index.d.mts +8 -3
- package/dist/model/index.d.ts +8 -3
- package/dist/model/index.mjs +1 -0
- package/dist/shared/core.B2QYWlYe.cjs +435 -0
- package/dist/shared/core.B72vUaNB.d.cts +850 -0
- package/dist/shared/core.BGus30EM.cjs +8027 -0
- package/dist/shared/core.BRuJ3Wzf.d.mts +12 -0
- package/dist/shared/{core.BZ9Msq7w.d.mts → core.BdbFkE_p.d.cts} +14 -4
- package/dist/shared/core.BvdNMbcA.d.cts +12 -0
- package/dist/shared/{object_hash.CE_oF3I3.js → core.BxvDITEI.mjs} +26 -389
- package/dist/shared/core.ByNgh-mC.d.cts +127 -0
- package/dist/shared/core.C9DCnJh8.cjs +908 -0
- package/dist/shared/{index.DafVOuVd.js → core.CqCTxzMY.mjs} +1111 -572
- package/dist/shared/core.D74xkKkG.d.cts +148 -0
- package/dist/shared/{core.C05RDLhi.d.ts → core.D_Gc58Gt.d.ts} +23 -5
- package/dist/shared/core.Damrzla-.d.ts +12 -0
- package/dist/shared/{core.CmYMqgha.d.mts → core.Dfzrh1VA.d.mts} +23 -5
- package/dist/shared/core.DsoCu540.cjs +26 -0
- package/dist/shared/{view.CyZrG8BJ.js → core.DunIMHRf.mjs} +27 -1
- package/dist/shared/{core.BIfgabEw.d.ts → core.ZWiGANIJ.d.ts} +14 -4
- package/dist/shared/core.gv1bMwCC.cjs +39 -0
- package/dist/shared/core.jy6z2iRn.d.mts +729 -0
- package/dist/shared/core.m3rCQAv6.mjs +37 -0
- package/dist/types/index.cjs +107 -0
- package/dist/types/index.d.cts +72 -0
- package/dist/types/index.d.mts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/{index.js → index.mjs} +1 -1
- package/dist/utils/index.cjs +95 -0
- package/dist/utils/index.d.cts +356 -0
- package/dist/utils/index.d.mts +1 -64
- package/dist/utils/index.d.ts +1 -64
- package/dist/utils/index.mjs +56 -0
- package/package.json +52 -26
- package/src/builder/Builder.view-common.ts +21 -1
- package/src/compute-view/deployment-view/__test__/fixture.ts +31 -3
- package/src/compute-view/deployment-view/_types.ts +2 -1
- package/src/compute-view/deployment-view/compute.ts +4 -36
- package/src/compute-view/deployment-view/predicates/index.ts +8 -0
- package/src/compute-view/deployment-view/predicates/relation-direct.ts +125 -99
- package/src/compute-view/deployment-view/predicates/relation-in-out.ts +16 -8
- package/src/compute-view/deployment-view/predicates/relation-incoming.ts +18 -12
- package/src/compute-view/deployment-view/predicates/relation-outgoing.ts +16 -9
- package/src/compute-view/deployment-view/predicates/relation-where.ts +18 -0
- package/src/compute-view/deployment-view/predicates/utils.ts +214 -0
- package/src/compute-view/element-view/__test__/fixture.ts +17 -4
- package/src/compute-view/element-view/compute.ts +3 -2
- package/src/compute-view/element-view/predicates.ts +520 -0
- package/src/compute-view/element-view/utils.ts +11 -7
- package/src/compute-view/index.ts +1 -0
- package/src/compute-view/relationships-view/_types.ts +16 -0
- package/src/compute-view/relationships-view/compute.ts +74 -0
- package/src/compute-view/relationships-view/layout.ts +357 -0
- package/src/compute-view/relationships-view/utils.ts +40 -0
- package/src/compute-view/utils/relationExpressionToPredicates.ts +11 -4
- package/src/index.ts +16 -0
- package/src/model/DeploymentElementModel.ts +18 -1
- package/src/model/ElementModel.ts +13 -0
- package/src/model/LikeC4Model.ts +2 -2
- package/src/model/RelationModel.ts +9 -0
- package/src/model/connection/deployment/DeploymentConnectionModel.ts +11 -1
- package/src/model/guards.ts +17 -1
- package/src/model/view/LikeC4ViewModel.ts +7 -1
- package/src/model/view/NodeModel.ts +5 -0
- package/src/types/deployments.ts +1 -0
- package/src/types/expression-v2.ts +12 -0
- package/src/types/index.ts +1 -0
- package/src/types/operators.ts +46 -6
- package/src/types/view.ts +2 -2
- package/src/utils/index.ts +0 -5
- package/src/utils/iterable/unique.ts +1 -7
- package/dist/model/index.js +0 -1
- package/dist/utils/index.js +0 -347
- /package/dist/shared/{chunk-RAAYCPUM.M-JWF7SS.js → core.M-JWF7SS.mjs} +0 -0
|
@@ -1,24 +1,27 @@
|
|
|
1
|
+
import { filter, pipe } from 'remeda'
|
|
1
2
|
import { invariant } from '../../../errors'
|
|
2
3
|
import { findConnectionsBetween } from '../../../model/connection/deployment'
|
|
3
4
|
import type { RelationshipModel } from '../../../model/RelationModel'
|
|
4
5
|
import type { AnyAux } from '../../../model/types'
|
|
5
|
-
import {
|
|
6
|
+
import { type RelationExpr, FqnExpr } from '../../../types/expression-v2'
|
|
6
7
|
import { union } from '../../../utils/set'
|
|
7
8
|
import type { PredicateExecutor } from '../_types'
|
|
8
9
|
import { resolveElements, resolveModelElements } from '../utils'
|
|
9
|
-
import {
|
|
10
|
+
import { resolveAscendingSiblings } from './relation-direct'
|
|
10
11
|
import { filterIncomingConnections } from './relation-incoming'
|
|
11
12
|
import { filterOutgoingConnections } from './relation-outgoing'
|
|
13
|
+
import { applyPredicate, excludeModelRelations, matchConnections } from './utils'
|
|
12
14
|
|
|
13
15
|
//
|
|
14
16
|
export const InOutRelationPredicate: PredicateExecutor<RelationExpr.InOut> = {
|
|
15
|
-
include: ({ expr, model, memory, stage }) => {
|
|
17
|
+
include: ({ expr, model, memory, stage, where }) => {
|
|
16
18
|
const sources = [...memory.elements]
|
|
17
19
|
|
|
18
20
|
if (FqnExpr.isWildcard(expr.inout)) {
|
|
19
21
|
for (const source of sources) {
|
|
20
22
|
const targets = [...resolveAscendingSiblings(source)]
|
|
21
|
-
|
|
23
|
+
const toInclude = matchConnections(findConnectionsBetween(source, targets, 'both'), where)
|
|
24
|
+
stage.addConnections(toInclude)
|
|
22
25
|
}
|
|
23
26
|
return stage
|
|
24
27
|
}
|
|
@@ -26,12 +29,13 @@ export const InOutRelationPredicate: PredicateExecutor<RelationExpr.InOut> = {
|
|
|
26
29
|
|
|
27
30
|
const targets = resolveElements(model, expr.inout)
|
|
28
31
|
for (const source of sources) {
|
|
29
|
-
|
|
32
|
+
const toInclude = matchConnections(findConnectionsBetween(source, targets, 'both'), where)
|
|
33
|
+
stage.addConnections(toInclude)
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
return stage
|
|
33
37
|
},
|
|
34
|
-
exclude: ({ expr, model, memory, stage }) => {
|
|
38
|
+
exclude: ({ expr, model, memory, stage, where }) => {
|
|
35
39
|
// Exclude all connections that have model relationshps with the elements
|
|
36
40
|
if (FqnExpr.isModelRef(expr.inout)) {
|
|
37
41
|
const elements = resolveModelElements(model, expr.inout)
|
|
@@ -42,7 +46,7 @@ export const InOutRelationPredicate: PredicateExecutor<RelationExpr.InOut> = {
|
|
|
42
46
|
new Set<RelationshipModel<AnyAux>>(),
|
|
43
47
|
...elements.flatMap(e => [e.allIncoming, e.allOutgoing]),
|
|
44
48
|
)
|
|
45
|
-
return excludeModelRelations(excludedRelations, { stage, memory })
|
|
49
|
+
return excludeModelRelations(excludedRelations, { stage, memory }, where)
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
if (FqnExpr.isWildcard(expr.inout)) {
|
|
@@ -54,7 +58,11 @@ export const InOutRelationPredicate: PredicateExecutor<RelationExpr.InOut> = {
|
|
|
54
58
|
const isIncoming = filterIncomingConnections(elements)
|
|
55
59
|
const isOutgoing = filterOutgoingConnections(elements)
|
|
56
60
|
|
|
57
|
-
const toExclude =
|
|
61
|
+
const toExclude = pipe(
|
|
62
|
+
memory.connections,
|
|
63
|
+
filter(c => isIncoming(c) !== isOutgoing(c)),
|
|
64
|
+
applyPredicate(where),
|
|
65
|
+
)
|
|
58
66
|
stage.excludeConnections(toExclude)
|
|
59
67
|
return stage
|
|
60
68
|
},
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { anyPass } from 'remeda'
|
|
1
|
+
import { anyPass, filter, pipe } from 'remeda'
|
|
2
2
|
import { invariant } from '../../../errors'
|
|
3
|
+
import type { AnyAux, RelationshipModel } from '../../../model'
|
|
3
4
|
import { findConnectionsBetween } from '../../../model/connection/deployment'
|
|
4
5
|
import type { LikeC4DeploymentModel } from '../../../model/DeploymentModel'
|
|
5
|
-
import type
|
|
6
|
-
import
|
|
7
|
-
import { FqnExpr, type RelationExpr } from '../../../types'
|
|
8
|
-
import { isAncestor } from '../../../utils/fqn'
|
|
6
|
+
import { type RelationExpr, FqnExpr } from '../../../types'
|
|
7
|
+
import { isAncestor } from '../../../utils'
|
|
9
8
|
import type { Connection, Elem, PredicateExecutor } from '../_types'
|
|
10
9
|
import { resolveElements, resolveModelElements } from '../utils'
|
|
11
|
-
import {
|
|
10
|
+
import { resolveAscendingSiblings } from './relation-direct'
|
|
11
|
+
import { applyPredicate, excludeModelRelations } from './utils'
|
|
12
12
|
|
|
13
13
|
// from visible element incoming to this
|
|
14
14
|
export const IncomingRelationPredicate: PredicateExecutor<RelationExpr.Incoming> = {
|
|
15
|
-
include: ({ expr, model, memory, stage }) => {
|
|
15
|
+
include: ({ expr, model, memory, stage, where }) => {
|
|
16
16
|
const sources = [...memory.elements]
|
|
17
17
|
|
|
18
18
|
if (FqnExpr.isWildcard(expr.incoming)) {
|
|
@@ -21,7 +21,8 @@ export const IncomingRelationPredicate: PredicateExecutor<RelationExpr.Incoming>
|
|
|
21
21
|
continue
|
|
22
22
|
}
|
|
23
23
|
const targets = [...resolveAscendingSiblings(source)]
|
|
24
|
-
|
|
24
|
+
const toInclude = applyPredicate(findConnectionsBetween(source, targets, 'directed'), where)
|
|
25
|
+
stage.addConnections(toInclude)
|
|
25
26
|
}
|
|
26
27
|
return stage
|
|
27
28
|
}
|
|
@@ -29,16 +30,17 @@ export const IncomingRelationPredicate: PredicateExecutor<RelationExpr.Incoming>
|
|
|
29
30
|
|
|
30
31
|
const targets = resolveElements(model, expr.incoming)
|
|
31
32
|
for (const source of sources) {
|
|
32
|
-
|
|
33
|
+
const toInclude = applyPredicate(findConnectionsBetween(source, targets, 'directed'), where)
|
|
34
|
+
stage.addConnections(toInclude)
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
return stage
|
|
36
38
|
},
|
|
37
|
-
exclude: ({ expr, model, memory, stage }) => {
|
|
39
|
+
exclude: ({ expr, model, memory, stage, where }) => {
|
|
38
40
|
// Exclude all connections that have model relationshps with the elements
|
|
39
41
|
if (FqnExpr.isModelRef(expr.incoming)) {
|
|
40
42
|
const excludedRelations = resolveAllImcomingRelations(model, expr.incoming)
|
|
41
|
-
return excludeModelRelations(excludedRelations, { stage, memory })
|
|
43
|
+
return excludeModelRelations(excludedRelations, { stage, memory }, where)
|
|
42
44
|
}
|
|
43
45
|
if (FqnExpr.isWildcard(expr.incoming)) {
|
|
44
46
|
// non-sense
|
|
@@ -46,7 +48,11 @@ export const IncomingRelationPredicate: PredicateExecutor<RelationExpr.Incoming>
|
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
const isIncoming = filterIncomingConnections(resolveElements(model, expr.incoming))
|
|
49
|
-
const toExclude =
|
|
51
|
+
const toExclude = pipe(
|
|
52
|
+
memory.connections,
|
|
53
|
+
filter(isIncoming),
|
|
54
|
+
applyPredicate(where),
|
|
55
|
+
)
|
|
50
56
|
stage.excludeConnections(toExclude)
|
|
51
57
|
return stage
|
|
52
58
|
},
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { anyPass } from 'remeda'
|
|
1
|
+
import { anyPass, filter, pipe } from 'remeda'
|
|
2
2
|
import { invariant } from '../../../errors'
|
|
3
3
|
import type { LikeC4DeploymentModel } from '../../../model'
|
|
4
4
|
import { findConnection, findConnectionsBetween } from '../../../model/connection/deployment'
|
|
5
5
|
import type { RelationshipModel } from '../../../model/RelationModel'
|
|
6
|
-
import {
|
|
6
|
+
import { type RelationExpr, FqnExpr } from '../../../types'
|
|
7
7
|
import { isAncestor } from '../../../utils'
|
|
8
8
|
import type { Connection, Elem, PredicateExecutor } from '../_types'
|
|
9
9
|
import { resolveElements, resolveModelElements } from '../utils'
|
|
10
|
-
import {
|
|
10
|
+
import { resolveAscendingSiblings } from './relation-direct'
|
|
11
|
+
import { applyPredicate, excludeModelRelations } from './utils'
|
|
11
12
|
|
|
12
13
|
export const OutgoingRelationPredicate: PredicateExecutor<RelationExpr.Outgoing> = {
|
|
13
|
-
include: ({ expr, model, memory, stage }) => {
|
|
14
|
+
include: ({ expr, model, memory, stage, where }) => {
|
|
14
15
|
const targets = [...memory.elements]
|
|
15
16
|
|
|
16
17
|
// * -> (to visible elements)
|
|
@@ -21,7 +22,8 @@ export const OutgoingRelationPredicate: PredicateExecutor<RelationExpr.Outgoing>
|
|
|
21
22
|
continue
|
|
22
23
|
}
|
|
23
24
|
for (const source of resolveAscendingSiblings(target)) {
|
|
24
|
-
|
|
25
|
+
const toInclude = applyPredicate(findConnection(source, target, 'directed'), where)
|
|
26
|
+
stage.addConnections(toInclude)
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
return stage
|
|
@@ -30,16 +32,17 @@ export const OutgoingRelationPredicate: PredicateExecutor<RelationExpr.Outgoing>
|
|
|
30
32
|
|
|
31
33
|
const sources = resolveElements(model, expr.outgoing)
|
|
32
34
|
for (const source of sources) {
|
|
33
|
-
|
|
35
|
+
const toInclude = applyPredicate(findConnectionsBetween(source, targets, 'directed'), where)
|
|
36
|
+
stage.addConnections(toInclude)
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
return stage
|
|
37
40
|
},
|
|
38
|
-
exclude: ({ expr, model, memory, stage }) => {
|
|
41
|
+
exclude: ({ expr, model, memory, stage, where }) => {
|
|
39
42
|
// Exclude all connections that have model relationshps with the elements
|
|
40
43
|
if (FqnExpr.isModelRef(expr.outgoing)) {
|
|
41
44
|
const excludedRelations = resolveAllOutgoingRelations(model, expr.outgoing)
|
|
42
|
-
return excludeModelRelations(excludedRelations, { stage, memory })
|
|
45
|
+
return excludeModelRelations(excludedRelations, { stage, memory }, where)
|
|
43
46
|
}
|
|
44
47
|
if (FqnExpr.isWildcard(expr.outgoing)) {
|
|
45
48
|
// non-sense
|
|
@@ -47,7 +50,11 @@ export const OutgoingRelationPredicate: PredicateExecutor<RelationExpr.Outgoing>
|
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
const isOutgoing = filterOutgoingConnections(resolveElements(model, expr.outgoing))
|
|
50
|
-
const toExclude =
|
|
53
|
+
const toExclude = pipe(
|
|
54
|
+
memory.connections,
|
|
55
|
+
filter(isOutgoing),
|
|
56
|
+
applyPredicate(where),
|
|
57
|
+
)
|
|
51
58
|
stage.excludeConnections(toExclude)
|
|
52
59
|
return stage
|
|
53
60
|
},
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { whereOperatorAsPredicate, type RelationExpr } from '../../../types'
|
|
2
|
+
import type { PredicateExecutor } from '../_types'
|
|
3
|
+
import type { StageExclude, StageInclude } from '../memory'
|
|
4
|
+
import { predicateToPatch } from './utils'
|
|
5
|
+
|
|
6
|
+
// relation matches the condition
|
|
7
|
+
export const WhereRelationPredicate: PredicateExecutor<RelationExpr.Where> = {
|
|
8
|
+
include: ({ expr, model, memory, stage }) => {
|
|
9
|
+
const where = whereOperatorAsPredicate(expr.where.condition)
|
|
10
|
+
|
|
11
|
+
return predicateToPatch('include', { expr: expr.where.expr, model, stage, memory, where }) as StageInclude
|
|
12
|
+
},
|
|
13
|
+
exclude: ({ expr, model, memory, stage }) => {
|
|
14
|
+
const where = whereOperatorAsPredicate(expr.where.condition)
|
|
15
|
+
|
|
16
|
+
return predicateToPatch('exclude', { expr: expr.where.expr, model, stage, memory, where }) as StageExclude
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { filter, isArray, map, pick, pipe } from 'remeda'
|
|
2
|
+
import { nonexhaustive } from '../../../errors'
|
|
3
|
+
import { type DeploymentConnectionModel, ElementModel, isDeployedInstance, isDeploymentNode } from '../../../model'
|
|
4
|
+
import type {
|
|
5
|
+
DeploymentElementModel,
|
|
6
|
+
DeploymentRelationEndpoint,
|
|
7
|
+
DeploymentRelationModel,
|
|
8
|
+
} from '../../../model/DeploymentElementModel'
|
|
9
|
+
import { isElementModel } from '../../../model/ElementModel'
|
|
10
|
+
import { isDeploymentElementModel, isNestedElementOfDeployedInstanceModel } from '../../../model/guards'
|
|
11
|
+
import type { RelationshipModel } from '../../../model/RelationModel'
|
|
12
|
+
import type { AnyAux } from '../../../model/types'
|
|
13
|
+
import { type Filterable, type OperatorPredicate, FqnExpr, RelationExpr } from '../../../types'
|
|
14
|
+
import { hasIntersection, intersection } from '../../../utils/set'
|
|
15
|
+
import type { ExcludePredicateCtx, PredicateCtx } from '../_types'
|
|
16
|
+
import type { StageExclude, StageInclude } from '../memory'
|
|
17
|
+
import { DeploymentRefPredicate } from './elements'
|
|
18
|
+
import { DirectRelationPredicate } from './relation-direct'
|
|
19
|
+
import { InOutRelationPredicate } from './relation-in-out'
|
|
20
|
+
import { IncomingRelationPredicate } from './relation-incoming'
|
|
21
|
+
import { OutgoingRelationPredicate } from './relation-outgoing'
|
|
22
|
+
import { WhereRelationPredicate } from './relation-where'
|
|
23
|
+
import { WildcardPredicate } from './wildcard'
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Builds a patch object from an expression
|
|
27
|
+
*/
|
|
28
|
+
export function predicateToPatch(
|
|
29
|
+
op: 'include' | 'exclude',
|
|
30
|
+
{ expr, where, ...ctx }: PredicateCtx,
|
|
31
|
+
): StageExclude | StageInclude | undefined {
|
|
32
|
+
switch (true) {
|
|
33
|
+
case FqnExpr.isModelRef(expr):
|
|
34
|
+
// Ignore model refs in deployment view
|
|
35
|
+
return undefined
|
|
36
|
+
case FqnExpr.isDeploymentRef(expr):
|
|
37
|
+
return DeploymentRefPredicate[op]({ ...ctx, expr, where } as any)
|
|
38
|
+
case FqnExpr.isWildcard(expr):
|
|
39
|
+
return WildcardPredicate[op]({ ...ctx, expr, where } as any)
|
|
40
|
+
case RelationExpr.isDirect(expr):
|
|
41
|
+
return DirectRelationPredicate[op]({ ...ctx, expr, where } as any)
|
|
42
|
+
case RelationExpr.isInOut(expr):
|
|
43
|
+
return InOutRelationPredicate[op]({ ...ctx, expr, where } as any)
|
|
44
|
+
case RelationExpr.isOutgoing(expr):
|
|
45
|
+
return OutgoingRelationPredicate[op]({ ...ctx, expr, where } as any)
|
|
46
|
+
case RelationExpr.isIncoming(expr):
|
|
47
|
+
return IncomingRelationPredicate[op]({ ...ctx, expr, where } as any)
|
|
48
|
+
case RelationExpr.isWhere(expr):
|
|
49
|
+
return WhereRelationPredicate[op]({ ...ctx, expr, where } as any)
|
|
50
|
+
default:
|
|
51
|
+
nonexhaustive(expr)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function excludeModelRelations(
|
|
56
|
+
relationsToExclude: ReadonlySet<RelationshipModel<AnyAux>>,
|
|
57
|
+
{ stage, memory }: Pick<ExcludePredicateCtx, 'stage' | 'memory'>,
|
|
58
|
+
where: OperatorPredicate<Filterable> | null,
|
|
59
|
+
// Optional filter to scope the connections to exclude
|
|
60
|
+
filterConnections: (c: DeploymentConnectionModel) => boolean = () => true,
|
|
61
|
+
): StageExclude {
|
|
62
|
+
if (relationsToExclude.size === 0) {
|
|
63
|
+
return stage
|
|
64
|
+
}
|
|
65
|
+
const toExclude = pipe(
|
|
66
|
+
memory.connections,
|
|
67
|
+
filter(c => filterConnections(c)),
|
|
68
|
+
// Find connections that have at least one relation in common with the excluded relations
|
|
69
|
+
filter(c => hasIntersection(c.relations.model, relationsToExclude)),
|
|
70
|
+
map(c =>
|
|
71
|
+
c.update({
|
|
72
|
+
deployment: null,
|
|
73
|
+
model: intersection(c.relations.model, relationsToExclude),
|
|
74
|
+
})
|
|
75
|
+
),
|
|
76
|
+
applyPredicate(where),
|
|
77
|
+
filter(c => c.nonEmpty()),
|
|
78
|
+
)
|
|
79
|
+
if (toExclude.length === 0) {
|
|
80
|
+
return stage
|
|
81
|
+
}
|
|
82
|
+
return stage.excludeConnections(toExclude)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function matchConnection<M extends AnyAux>(
|
|
86
|
+
c: DeploymentConnectionModel<M>,
|
|
87
|
+
where: OperatorPredicate<Filterable> | null,
|
|
88
|
+
): boolean {
|
|
89
|
+
return applyPredicate(c, where).nonEmpty()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Filters relations of the provided connections using the provided predicate.
|
|
94
|
+
* And copy of the connection with the filtered relations will be created.
|
|
95
|
+
* Connections left without relations are removed from resulting collection.
|
|
96
|
+
*
|
|
97
|
+
* @param c The connection to apply the predicate to
|
|
98
|
+
* @param where The predicate
|
|
99
|
+
* @returns A copy of the connection with the filtered relations
|
|
100
|
+
*/
|
|
101
|
+
export function applyPredicate<M extends AnyAux>(
|
|
102
|
+
c: readonly DeploymentConnectionModel<M>[],
|
|
103
|
+
where: OperatorPredicate<Filterable> | null,
|
|
104
|
+
): readonly DeploymentConnectionModel<M>[]
|
|
105
|
+
/**
|
|
106
|
+
* Filters relations of the connection using the provided predicate.
|
|
107
|
+
*
|
|
108
|
+
* @param c The connection to apply the predicate to
|
|
109
|
+
* @param where The predicate
|
|
110
|
+
* @returns A deep copy of the original collection with the filtered relations
|
|
111
|
+
*/
|
|
112
|
+
export function applyPredicate<M extends AnyAux>(
|
|
113
|
+
c: DeploymentConnectionModel<M>,
|
|
114
|
+
where: OperatorPredicate<Filterable> | null,
|
|
115
|
+
): DeploymentConnectionModel<M>
|
|
116
|
+
/**
|
|
117
|
+
* Creates a function that filters relations of the provided connections using the provided predicate.
|
|
118
|
+
* Connections left without relations are removed from resulting collection.
|
|
119
|
+
*
|
|
120
|
+
* @param c The connection to apply the predicate to
|
|
121
|
+
* @param where The predicate
|
|
122
|
+
* @returns A function to create a filtered copy of connections
|
|
123
|
+
*/
|
|
124
|
+
export function applyPredicate<M extends AnyAux>(
|
|
125
|
+
where: OperatorPredicate<Filterable> | null,
|
|
126
|
+
): (data: readonly DeploymentConnectionModel<M>[]) => readonly DeploymentConnectionModel<M>[]
|
|
127
|
+
export function applyPredicate<M extends AnyAux>(
|
|
128
|
+
...args:
|
|
129
|
+
| [readonly DeploymentConnectionModel<M>[], OperatorPredicate<Filterable> | null]
|
|
130
|
+
| [OperatorPredicate<Filterable> | null]
|
|
131
|
+
| [c: DeploymentConnectionModel<M>, OperatorPredicate<Filterable> | null]
|
|
132
|
+
):
|
|
133
|
+
| DeploymentConnectionModel<M>
|
|
134
|
+
| readonly DeploymentConnectionModel<M>[]
|
|
135
|
+
| ((data: readonly DeploymentConnectionModel<M>[]) => readonly DeploymentConnectionModel<M>[])
|
|
136
|
+
{
|
|
137
|
+
if (args.length === 1) {
|
|
138
|
+
return x => applyPredicate(x, args[0])
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const [c, where] = args
|
|
142
|
+
if (where === null) {
|
|
143
|
+
return c
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (isArray(c)) {
|
|
147
|
+
return c
|
|
148
|
+
.map(x => applyPredicate(x, where))
|
|
149
|
+
.filter(x => x.nonEmpty())
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return c.update({
|
|
153
|
+
model: new Set([...c.relations.model.values()].filter(r => where(toFilterableRelation(c)(r)))),
|
|
154
|
+
deployment: new Set([...c.relations.deployment.values()].filter(r => where(toFilterableRelation(c)(r)))),
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function matchConnections<M extends AnyAux>(
|
|
159
|
+
connections: readonly DeploymentConnectionModel<M>[],
|
|
160
|
+
where: OperatorPredicate<Filterable> | null,
|
|
161
|
+
): readonly DeploymentConnectionModel[] {
|
|
162
|
+
if (!where) {
|
|
163
|
+
return connections
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return pipe(
|
|
167
|
+
connections,
|
|
168
|
+
filter(c => matchConnection(c, where)),
|
|
169
|
+
)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Builds filterable presentation for relation endpoint. Enriches model properties with deployment properties when needed.
|
|
174
|
+
* @param relationEndpoint Endpoint for which to build presentation
|
|
175
|
+
* @param connectionEndpoint Endpoint of connection which was build from the relation.
|
|
176
|
+
* @returns Presentation of the endpoint for usage in predicates
|
|
177
|
+
*/
|
|
178
|
+
function toFilterable<M extends AnyAux>(
|
|
179
|
+
relationEndpoint: ElementModel<M> | DeploymentRelationEndpoint<M>,
|
|
180
|
+
connectionEndpoint: DeploymentRelationEndpoint<M>,
|
|
181
|
+
): Filterable {
|
|
182
|
+
if (isElementModel(relationEndpoint)) { // Element itself. Extend with tags of the deployed instance (TODO)
|
|
183
|
+
const deployedInstance = isDeploymentElementModel(connectionEndpoint) && isDeployedInstance(connectionEndpoint)
|
|
184
|
+
? connectionEndpoint
|
|
185
|
+
: null
|
|
186
|
+
return {
|
|
187
|
+
kind: relationEndpoint.kind,
|
|
188
|
+
tags: [...relationEndpoint.tags, ...(deployedInstance?.tags ?? [])],
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (isNestedElementOfDeployedInstanceModel(relationEndpoint)) { // Nested element. Has no own instance. No need to extend
|
|
192
|
+
return pick(relationEndpoint.element, ['tags', 'kind'])
|
|
193
|
+
}
|
|
194
|
+
if (isDeployedInstance(relationEndpoint)) { // Deployed instance. Extend with tags of the model element
|
|
195
|
+
return {
|
|
196
|
+
kind: relationEndpoint.element.kind,
|
|
197
|
+
tags: [...relationEndpoint.tags, ...relationEndpoint.element.tags],
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (isDeploymentNode(relationEndpoint)) { // Deployment node. Has no representation in model. No need to extend
|
|
201
|
+
return pick(relationEndpoint, ['tags', 'kind'])
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
nonexhaustive(relationEndpoint)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function toFilterableRelation<M extends AnyAux>(c: DeploymentConnectionModel<M>) {
|
|
208
|
+
return (relation: RelationshipModel<M> | DeploymentRelationModel<M>) => ({
|
|
209
|
+
tags: relation.tags,
|
|
210
|
+
kind: relation.kind,
|
|
211
|
+
source: toFilterable(relation.source, c.source),
|
|
212
|
+
target: toFilterable(relation.target, c.target),
|
|
213
|
+
})
|
|
214
|
+
}
|
|
@@ -18,10 +18,7 @@ import {
|
|
|
18
18
|
type IconUrl,
|
|
19
19
|
type IncomingExpr as C4IncomingExpr,
|
|
20
20
|
type InOutExpr as C4InOutExpr,
|
|
21
|
-
|
|
22
|
-
isElementWhere,
|
|
23
|
-
isRelationExpression,
|
|
24
|
-
isRelationWhere,
|
|
21
|
+
type KindEqual,
|
|
25
22
|
type ModelRelation,
|
|
26
23
|
type NonEmptyArray,
|
|
27
24
|
type OutgoingExpr as C4OutgoingExpr,
|
|
@@ -30,6 +27,7 @@ import {
|
|
|
30
27
|
type RelationshipLineType,
|
|
31
28
|
type RelationWhereExpr,
|
|
32
29
|
type Tag,
|
|
30
|
+
type TagEqual,
|
|
33
31
|
type ViewId,
|
|
34
32
|
type ViewRule,
|
|
35
33
|
type ViewRuleGlobalPredicateRef,
|
|
@@ -38,8 +36,13 @@ import {
|
|
|
38
36
|
type ViewRulePredicate,
|
|
39
37
|
type ViewRuleStyle,
|
|
40
38
|
type WhereOperator,
|
|
39
|
+
isElementRef,
|
|
40
|
+
isElementWhere,
|
|
41
|
+
isRelationExpression,
|
|
42
|
+
isRelationWhere,
|
|
41
43
|
} from '../../../types'
|
|
42
44
|
import { type DirectRelationExpr as C4RelationExpr } from '../../../types/expression'
|
|
45
|
+
import type { Participant } from '../../../types/operators'
|
|
43
46
|
import { withReadableEdges } from '../../utils/with-readable-edges'
|
|
44
47
|
import { computeElementView } from '../compute'
|
|
45
48
|
|
|
@@ -482,6 +485,16 @@ export function $where(
|
|
|
482
485
|
}
|
|
483
486
|
}
|
|
484
487
|
|
|
488
|
+
export function $participant(
|
|
489
|
+
participant: Participant,
|
|
490
|
+
operator: TagEqual<TestTag> | KindEqual<TestTag>,
|
|
491
|
+
): WhereOperator<TestTag, string> {
|
|
492
|
+
return {
|
|
493
|
+
participant,
|
|
494
|
+
operator,
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
485
498
|
export function $inout(
|
|
486
499
|
expr: InOutExpr | C4ElementExpression,
|
|
487
500
|
): C4InOutExpr {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import DefaultMap from 'mnemonist/default-map'
|
|
2
2
|
import { filter, findLast, forEach, map, pipe } from 'remeda'
|
|
3
3
|
import { invariant, nonexhaustive, nonNullable } from '../../errors'
|
|
4
|
-
import { type ElementModel, LikeC4Model } from '../../model'
|
|
5
4
|
import { ConnectionModel } from '../../model/connection/model/ConnectionModel'
|
|
5
|
+
import { type ElementModel } from '../../model/ElementModel'
|
|
6
|
+
import { LikeC4Model } from '../../model/LikeC4Model'
|
|
6
7
|
import type { RelationshipModel } from '../../model/RelationModel'
|
|
7
8
|
import type { AnyAux } from '../../model/types'
|
|
8
9
|
import type {
|
|
@@ -15,7 +16,7 @@ import type {
|
|
|
15
16
|
} from '../../types'
|
|
16
17
|
import { isViewRuleAutoLayout, isViewRuleGroup, isViewRulePredicate, whereOperatorAsPredicate } from '../../types'
|
|
17
18
|
import * as Expr from '../../types/expression'
|
|
18
|
-
import {
|
|
19
|
+
import { sortParentsFirst } from '../../utils'
|
|
19
20
|
import { applyCustomElementProperties } from '../utils/applyCustomElementProperties'
|
|
20
21
|
import { applyCustomRelationProperties } from '../utils/applyCustomRelationProperties'
|
|
21
22
|
import { applyViewRuleStyles } from '../utils/applyViewRuleStyles'
|