@likec4/core 1.31.0 → 1.32.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/README.md +407 -5
- package/dist/builder/index.d.mts +221 -42
- package/dist/builder/index.mjs +118 -65
- package/dist/compute-view/index.d.mts +23 -7
- package/dist/compute-view/index.mjs +11 -6
- package/dist/compute-view/relationships-view/index.d.mts +9 -7
- package/dist/compute-view/relationships-view/index.mjs +3 -2
- package/dist/index.d.mts +10 -14
- package/dist/index.mjs +9 -6
- package/dist/model/index.d.mts +173 -19
- package/dist/model/index.mjs +6 -1
- package/dist/shared/core.BaYE_r29.d.mts +258 -0
- package/dist/shared/core.Bk7wEZFG.mjs +276 -0
- package/dist/shared/core.BrCnZFTn.mjs +32 -0
- package/dist/shared/core.BuO4ncfY.d.mts +146 -0
- package/dist/shared/{core.Bq753SYD.mjs → core.CBpKAlhj.mjs} +2012 -4422
- package/dist/shared/core.CCWXGc6G.d.mts +920 -0
- package/dist/shared/core.CUYDgv2-.mjs +214 -0
- package/dist/shared/{core.Cu-UdkSl.mjs → core.CpXlRyE5.mjs} +7 -494
- package/dist/shared/{core.C-YXI-43.mjs → core.Cy9smucx.mjs} +3 -1
- package/dist/shared/core.CywrQs86.d.mts +31 -0
- package/dist/shared/core.DoK86JEe.mjs +518 -0
- package/dist/shared/core.Dpq3P3YJ.d.mts +1265 -0
- package/dist/shared/{core.D2830qgg.d.mts → core.Pf5I9o0e.d.mts} +1 -1
- package/dist/shared/core.cbA9VZ02.mjs +2681 -0
- package/dist/shared/{core.CQXU9DF7.mjs → core.rmvsy0n3.mjs} +23 -32
- package/dist/types/aux.d.mts +3 -0
- package/dist/types/aux.mjs +1 -0
- package/dist/types/index.d.mts +7 -45
- package/dist/types/index.mjs +130 -3
- package/dist/utils/index.d.mts +221 -53
- package/dist/utils/index.mjs +14 -10
- package/package.json +15 -7
- package/src/builder/Builder.deploymentModel.ts +82 -18
- package/src/builder/Builder.element.ts +40 -20
- package/src/builder/Builder.model.ts +66 -17
- package/src/builder/Builder.ts +168 -76
- package/src/builder/Builder.view-common.ts +35 -17
- package/src/builder/Builder.view-deployment.ts +25 -25
- package/src/builder/Builder.view-element.ts +13 -12
- package/src/builder/Builder.views.ts +12 -7
- package/src/builder/__snapshots__/Builder-style1.spec.ts.snap +62 -34
- package/src/builder/__snapshots__/Builder-style2.compute-model.json5 +319 -0
- package/src/builder/__snapshots__/Builder-style2.spec.ts.snap +45 -24
- package/src/builder/_types.ts +34 -27
- package/src/compute-view/compute-view.ts +31 -34
- package/src/compute-view/deployment-view/__test__/TestHelper.ts +27 -14
- package/src/compute-view/deployment-view/__test__/fixture.ts +15 -13
- package/src/compute-view/deployment-view/_types.ts +10 -10
- package/src/compute-view/deployment-view/clean-connections.ts +5 -7
- package/src/compute-view/deployment-view/compute.ts +16 -13
- package/src/compute-view/deployment-view/memory/memory.ts +5 -6
- package/src/compute-view/deployment-view/predicates/deploymentRefs.ts +4 -5
- package/src/compute-view/deployment-view/predicates/relation-direct.ts +25 -50
- package/src/compute-view/deployment-view/predicates/relation-in-out.ts +5 -7
- package/src/compute-view/deployment-view/predicates/relation-incoming.ts +7 -11
- package/src/compute-view/deployment-view/predicates/relation-outgoing.ts +7 -10
- package/src/compute-view/deployment-view/predicates/utils.ts +37 -31
- package/src/compute-view/deployment-view/predicates/wildcard.ts +3 -2
- package/src/compute-view/deployment-view/stages/stage-final.ts +2 -2
- package/src/compute-view/deployment-view/stages/stage-include.ts +1 -1
- package/src/compute-view/deployment-view/utils.ts +79 -72
- package/src/compute-view/dynamic-view/__test__/fixture.ts +20 -11
- package/src/compute-view/dynamic-view/compute.ts +60 -53
- package/src/compute-view/element-view/__test__/TestHelper.ts +53 -29
- package/src/compute-view/element-view/__test__/__snapshots__/legacy.spec.ts.snap +26 -26
- package/src/compute-view/element-view/__test__/fixture.ts +134 -83
- package/src/compute-view/element-view/_types.ts +14 -19
- package/src/compute-view/element-view/clean-connections.ts +12 -8
- package/src/compute-view/element-view/compute.ts +61 -51
- package/src/compute-view/element-view/memory/NodeGroup.ts +8 -9
- package/src/compute-view/element-view/memory/memory.ts +22 -22
- package/src/compute-view/element-view/memory/stage-include.ts +5 -3
- package/src/compute-view/element-view/predicates/_utils.ts +18 -14
- package/src/compute-view/element-view/predicates/element-expand.ts +4 -5
- package/src/compute-view/element-view/predicates/element-kind-tag.ts +3 -4
- package/src/compute-view/element-view/predicates/element-ref.ts +3 -4
- package/src/compute-view/element-view/predicates/relation-direct.ts +16 -12
- package/src/compute-view/element-view/predicates/relation-in-out.ts +7 -8
- package/src/compute-view/element-view/predicates/relation-in.ts +19 -26
- package/src/compute-view/element-view/predicates/relation-out.ts +20 -21
- package/src/compute-view/element-view/predicates/wildcard.ts +3 -3
- package/src/compute-view/element-view/utils.ts +25 -23
- package/src/compute-view/index.ts +1 -1
- package/src/compute-view/memory/AbstractStageExclude.ts +3 -4
- package/src/compute-view/memory/AbstractStageInclude.ts +1 -1
- package/src/compute-view/memory/_types.ts +3 -2
- package/src/compute-view/relationships-view/_types.ts +3 -4
- package/src/compute-view/relationships-view/compute.ts +8 -11
- package/src/compute-view/relationships-view/layout.ts +6 -6
- package/src/compute-view/relationships-view/utils.ts +4 -4
- package/src/compute-view/utils/ancestorsOfNode.ts +7 -7
- package/src/compute-view/utils/applyCustomElementProperties.ts +16 -8
- package/src/compute-view/utils/applyCustomRelationProperties.ts +19 -9
- package/src/compute-view/utils/applyViewRuleStyles.ts +18 -10
- package/src/compute-view/utils/buildComputedNodes.ts +40 -40
- package/src/compute-view/utils/buildElementNotations.ts +14 -14
- package/src/compute-view/utils/elementExpressionToPredicate.ts +14 -15
- package/src/compute-view/utils/link-nodes-with-edges.ts +6 -4
- package/src/compute-view/utils/merge-props-from-relationships.ts +52 -20
- package/src/compute-view/utils/relationExpressionToPredicates.ts +19 -19
- package/src/compute-view/utils/resolve-extended-views.ts +8 -7
- package/src/compute-view/utils/resolve-global-rules.ts +31 -26
- package/src/compute-view/utils/topological-sort.ts +14 -14
- package/src/compute-view/utils/view-hash.ts +2 -2
- package/src/compute-view/utils/with-readable-edges.ts +9 -5
- package/src/index.ts +0 -32
- package/src/model/DeploymentElementModel.ts +171 -144
- package/src/model/DeploymentModel.ts +88 -65
- package/src/model/ElementModel.ts +85 -74
- package/src/model/LikeC4Model.ts +430 -241
- package/src/model/RelationModel.ts +63 -29
- package/src/model/__test__/fixture.ts +50 -36
- package/src/model/connection/Connection.ts +2 -2
- package/src/model/connection/deployment/DeploymentConnectionModel.ts +21 -24
- package/src/model/connection/deployment/find.ts +1 -1
- package/src/model/connection/model/ConnectionModel.ts +21 -20
- package/src/model/connection/model/find.ts +7 -7
- package/src/model/connection/ops.ts +6 -6
- package/src/model/guards.ts +66 -14
- package/src/model/index.ts +20 -7
- package/src/model/types.ts +41 -97
- package/src/model/view/EdgeModel.ts +47 -41
- package/src/model/view/LikeC4ViewModel.ts +130 -80
- package/src/model/view/NodeModel.ts +102 -96
- package/src/theme/element.ts +1 -1
- package/src/theme/index.ts +9 -9
- package/src/theme/relationships.ts +1 -1
- package/src/types/_common.ts +21 -15
- package/src/types/aux.ts +285 -0
- package/src/types/const.ts +34 -0
- package/src/types/expression-model.ts +292 -0
- package/src/types/expression.ts +311 -0
- package/src/types/fqnRef.ts +88 -0
- package/src/types/geometry.ts +131 -0
- package/src/types/global.ts +10 -8
- package/src/types/index.ts +39 -201
- package/src/types/model-data.ts +52 -84
- package/src/types/model-deployment.ts +87 -0
- package/src/types/model-dump.ts +72 -0
- package/src/types/model-logical.ts +111 -0
- package/src/types/model-spec.ts +81 -0
- package/src/types/operators.ts +51 -52
- package/src/types/scalar.ts +114 -0
- package/src/types/styles.ts +123 -0
- package/src/types/view-changes.ts +4 -5
- package/src/types/view-common.ts +157 -0
- package/src/types/view-computed.ts +113 -0
- package/src/types/view-layouted.ts +82 -0
- package/src/types/view-parsed.deployment.ts +40 -0
- package/src/types/view-parsed.dynamic.ts +78 -0
- package/src/types/view-parsed.element.ts +65 -0
- package/src/types/view.ts +122 -542
- package/src/utils/compare-natural.ts +43 -1
- package/src/utils/getOrCreate.ts +0 -34
- package/src/utils/index.ts +7 -12
- package/src/utils/iterable/filter.ts +1 -1
- package/src/utils/iterable/find.ts +3 -1
- package/src/utils/iterable/head.ts +22 -0
- package/src/utils/iterable/index.ts +1 -0
- package/src/utils/iterable/map.ts +1 -1
- package/src/utils/iterable/reduce.ts +1 -1
- package/src/utils/iterable/some.ts +1 -1
- package/src/utils/memoize-prop.ts +30 -0
- package/src/utils/object-hash.ts +1 -1
- package/src/utils/relations.ts +14 -11
- package/src/utils/string-hash.ts +1 -1
- package/dist/shared/core.CQDU11hR.d.mts +0 -753
- package/dist/shared/core.DJvmfnEi.d.mts +0 -1153
- package/dist/shared/core.DgfwjBtu.mjs +0 -495
- package/dist/shared/core.Dx7siloV.d.mts +0 -146
- package/dist/shared/core.SjLhMA7a.d.mts +0 -62
- package/src/builder/__snapshots__/Builder.spec.ts.snap +0 -374
- package/src/compute-view/element-view/predicates.ts +0 -520
- package/src/compute-view/utils/uniqueTags.ts +0 -21
- package/src/types/deployments.ts +0 -170
- package/src/types/element.ts +0 -109
- package/src/types/expression-v2-model.ts +0 -314
- package/src/types/expression-v2.ts +0 -392
- package/src/types/overview-graph.ts +0 -43
- package/src/types/relation.ts +0 -61
- package/src/types/scalars.ts +0 -39
- package/src/types/theme.ts +0 -82
- package/src/types/view-notation.ts +0 -9
- package/src/utils/graphlib.ts +0 -10
- /package/src/{errors/index.ts → utils/invariant.ts} +0 -0
|
@@ -1,44 +1,67 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { IteratorLike } from '../types
|
|
3
|
-
import type { Link } from '../types/element'
|
|
1
|
+
import { isTruthy } from 'remeda'
|
|
2
|
+
import type { AnyAux, Color, IteratorLike, Link, scalar } from '../types'
|
|
4
3
|
import {
|
|
5
|
-
type
|
|
4
|
+
type Relationship,
|
|
6
5
|
type RelationshipLineType,
|
|
7
6
|
DefaultLineStyle,
|
|
8
7
|
DefaultRelationshipColor,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import type
|
|
8
|
+
FqnRef,
|
|
9
|
+
} from '../types'
|
|
10
|
+
import type * as aux from '../types/aux'
|
|
12
11
|
import { commonAncestor } from '../utils/fqn'
|
|
13
12
|
import type { DeploymentRelationModel } from './DeploymentElementModel'
|
|
14
13
|
import type { ElementModel } from './ElementModel'
|
|
14
|
+
import type { isDeploymentRelationModel } from './guards'
|
|
15
15
|
import type { LikeC4Model } from './LikeC4Model'
|
|
16
|
-
import type { AnyAux } from './types'
|
|
17
16
|
import type { LikeC4ViewModel, ViewsIterator } from './view/LikeC4ViewModel'
|
|
18
17
|
|
|
19
|
-
export type RelationshipsIterator<
|
|
18
|
+
export type RelationshipsIterator<A extends AnyAux> = IteratorLike<RelationshipModel<A>>
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A relationship between two elements (in logical or deployment model)
|
|
22
|
+
* use {@link isDeploymentRelationModel} guard to check if the relationship is a deployment relationship
|
|
23
|
+
*/
|
|
24
|
+
export interface AnyRelationshipModel<A extends AnyAux> {
|
|
25
|
+
get id(): scalar.RelationId
|
|
26
|
+
get expression(): string
|
|
27
|
+
get title(): string | null
|
|
28
|
+
get technology(): string | null
|
|
29
|
+
get description(): string | null
|
|
30
|
+
get navigateTo(): LikeC4ViewModel<A> | null
|
|
31
|
+
get tags(): aux.Tags<A>
|
|
32
|
+
get kind(): aux.RelationKind<A> | null
|
|
33
|
+
get links(): ReadonlyArray<Link>
|
|
34
|
+
get color(): Color
|
|
35
|
+
get line(): RelationshipLineType
|
|
36
|
+
isDeploymentRelation(): this is DeploymentRelationModel<A>
|
|
37
|
+
isModelRelation(): this is RelationshipModel<A>
|
|
38
|
+
getMetadata(): aux.Metadata<A>
|
|
39
|
+
getMetadata(field: aux.MetadataKey<A>): string | undefined
|
|
40
|
+
views(): ViewsIterator<A>
|
|
41
|
+
isTagged(tag: aux.LooseTag<A>): boolean
|
|
42
|
+
}
|
|
20
43
|
|
|
21
|
-
export class RelationshipModel<
|
|
22
|
-
public readonly source: ElementModel<
|
|
23
|
-
public readonly target: ElementModel<
|
|
44
|
+
export class RelationshipModel<A extends AnyAux = AnyAux> implements AnyRelationshipModel<A> {
|
|
45
|
+
public readonly source: ElementModel<A>
|
|
46
|
+
public readonly target: ElementModel<A>
|
|
24
47
|
|
|
25
48
|
/**
|
|
26
49
|
* Common ancestor of the source and target elements.
|
|
27
50
|
* Represents the boundary of the Relation.
|
|
28
51
|
*/
|
|
29
|
-
public readonly boundary: ElementModel<
|
|
52
|
+
public readonly boundary: ElementModel<A> | null
|
|
30
53
|
|
|
31
54
|
constructor(
|
|
32
|
-
public readonly model: LikeC4Model<
|
|
33
|
-
public readonly $relationship:
|
|
55
|
+
public readonly model: LikeC4Model<A>,
|
|
56
|
+
public readonly $relationship: Relationship<A>,
|
|
34
57
|
) {
|
|
35
|
-
this.source = model.element($relationship.source)
|
|
36
|
-
this.target = model.element($relationship.target)
|
|
58
|
+
this.source = model.element(FqnRef.flatten($relationship.source))
|
|
59
|
+
this.target = model.element(FqnRef.flatten($relationship.target))
|
|
37
60
|
const parent = commonAncestor(this.source.id, this.target.id)
|
|
38
61
|
this.boundary = parent ? this.model.element(parent) : null
|
|
39
62
|
}
|
|
40
63
|
|
|
41
|
-
get id():
|
|
64
|
+
get id(): scalar.RelationId {
|
|
42
65
|
return this.$relationship.id
|
|
43
66
|
}
|
|
44
67
|
|
|
@@ -47,35 +70,35 @@ export class RelationshipModel<M extends AnyAux = AnyAux> {
|
|
|
47
70
|
}
|
|
48
71
|
|
|
49
72
|
get title(): string | null {
|
|
50
|
-
if (
|
|
73
|
+
if (!isTruthy(this.$relationship.title)) {
|
|
51
74
|
return null
|
|
52
75
|
}
|
|
53
76
|
return this.$relationship.title
|
|
54
77
|
}
|
|
55
78
|
|
|
56
79
|
get technology(): string | null {
|
|
57
|
-
if (
|
|
80
|
+
if (!isTruthy(this.$relationship.technology)) {
|
|
58
81
|
return null
|
|
59
82
|
}
|
|
60
83
|
return this.$relationship.technology
|
|
61
84
|
}
|
|
62
85
|
|
|
63
86
|
get description(): string | null {
|
|
64
|
-
if (
|
|
87
|
+
if (!isTruthy(this.$relationship.description)) {
|
|
65
88
|
return null
|
|
66
89
|
}
|
|
67
90
|
return this.$relationship.description
|
|
68
91
|
}
|
|
69
92
|
|
|
70
|
-
get navigateTo(): LikeC4ViewModel<
|
|
93
|
+
get navigateTo(): LikeC4ViewModel<A> | null {
|
|
71
94
|
return this.$relationship.navigateTo ? this.model.view(this.$relationship.navigateTo) : null
|
|
72
95
|
}
|
|
73
96
|
|
|
74
|
-
get tags():
|
|
97
|
+
get tags(): aux.Tags<A> {
|
|
75
98
|
return this.$relationship.tags ?? []
|
|
76
99
|
}
|
|
77
100
|
|
|
78
|
-
get kind():
|
|
101
|
+
get kind(): aux.RelationKind<A> | null {
|
|
79
102
|
return this.$relationship.kind ?? null
|
|
80
103
|
}
|
|
81
104
|
|
|
@@ -94,7 +117,7 @@ export class RelationshipModel<M extends AnyAux = AnyAux> {
|
|
|
94
117
|
/**
|
|
95
118
|
* Iterate over all views that include this relationship.
|
|
96
119
|
*/
|
|
97
|
-
public *views(): ViewsIterator<
|
|
120
|
+
public *views(): ViewsIterator<A> {
|
|
98
121
|
for (const view of this.model.views()) {
|
|
99
122
|
if (view.includesRelation(this.id)) {
|
|
100
123
|
yield view
|
|
@@ -103,16 +126,27 @@ export class RelationshipModel<M extends AnyAux = AnyAux> {
|
|
|
103
126
|
return
|
|
104
127
|
}
|
|
105
128
|
|
|
106
|
-
public isDeploymentRelation(): this is DeploymentRelationModel<
|
|
129
|
+
public isDeploymentRelation(): this is DeploymentRelationModel<A> {
|
|
107
130
|
return false
|
|
108
131
|
}
|
|
109
132
|
|
|
110
|
-
public
|
|
111
|
-
|
|
112
|
-
|
|
133
|
+
public isModelRelation(): this is RelationshipModel<A> {
|
|
134
|
+
return true
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public getMetadata(): aux.Metadata<A>
|
|
138
|
+
public getMetadata(field: aux.MetadataKey<A>): string | undefined
|
|
139
|
+
public getMetadata(field?: aux.MetadataKey<A>) {
|
|
113
140
|
if (field) {
|
|
114
141
|
return this.$relationship.metadata?.[field]
|
|
115
142
|
}
|
|
116
143
|
return this.$relationship.metadata ?? {}
|
|
117
144
|
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Checks if the relationship has the given tag.
|
|
148
|
+
*/
|
|
149
|
+
public isTagged(tag: aux.LooseTag<A>): boolean {
|
|
150
|
+
return this.tags.includes(tag as aux.Tag<A>)
|
|
151
|
+
}
|
|
118
152
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Builder } from '../../builder/Builder'
|
|
2
|
-
import {
|
|
2
|
+
import { computeParsedModelData } from '../../compute-view/compute-view'
|
|
3
3
|
import { LikeC4Model } from '../LikeC4Model'
|
|
4
4
|
|
|
5
5
|
const {
|
|
@@ -26,33 +26,40 @@ const {
|
|
|
26
26
|
viewOf,
|
|
27
27
|
deploymentView,
|
|
28
28
|
$rules,
|
|
29
|
-
$include
|
|
30
|
-
}
|
|
29
|
+
$include,
|
|
30
|
+
},
|
|
31
31
|
} = Builder.forSpecification({
|
|
32
32
|
elements: {
|
|
33
33
|
person: {
|
|
34
34
|
style: {
|
|
35
|
-
shape: 'person'
|
|
36
|
-
}
|
|
35
|
+
shape: 'person',
|
|
36
|
+
},
|
|
37
37
|
},
|
|
38
38
|
system: {},
|
|
39
39
|
component: {},
|
|
40
40
|
webapp: {
|
|
41
|
+
tags: ['internal'],
|
|
41
42
|
style: {
|
|
42
|
-
shape: 'browser'
|
|
43
|
-
}
|
|
43
|
+
shape: 'browser',
|
|
44
|
+
},
|
|
44
45
|
},
|
|
45
46
|
mobile: {
|
|
46
47
|
style: {
|
|
47
|
-
shape: 'mobile'
|
|
48
|
-
}
|
|
49
|
-
}
|
|
48
|
+
shape: 'mobile',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
tags: {
|
|
53
|
+
internal: {},
|
|
54
|
+
external: {},
|
|
55
|
+
tag1: {},
|
|
56
|
+
tag2: {},
|
|
50
57
|
},
|
|
51
58
|
deployments: {
|
|
52
59
|
env: {},
|
|
53
60
|
zone: {},
|
|
54
|
-
node: {}
|
|
55
|
-
}
|
|
61
|
+
node: {},
|
|
62
|
+
},
|
|
56
63
|
})
|
|
57
64
|
|
|
58
65
|
const local = b
|
|
@@ -61,27 +68,34 @@ const local = b
|
|
|
61
68
|
person('customer'),
|
|
62
69
|
system('cloud').with(
|
|
63
70
|
component('frontend').with(
|
|
64
|
-
webapp('dashboard'
|
|
65
|
-
|
|
71
|
+
webapp('dashboard', {
|
|
72
|
+
tags: ['tag1'],
|
|
73
|
+
}),
|
|
74
|
+
mobile('mobile'),
|
|
66
75
|
),
|
|
67
76
|
component('auth'),
|
|
68
77
|
component('backend').with(
|
|
69
78
|
component('api'),
|
|
70
|
-
component('graphql')
|
|
79
|
+
component('graphql'),
|
|
71
80
|
),
|
|
72
81
|
component('media', {
|
|
73
|
-
|
|
74
|
-
|
|
82
|
+
tags: ['tag2'],
|
|
83
|
+
shape: 'storage',
|
|
84
|
+
}),
|
|
75
85
|
),
|
|
76
86
|
system('aws').with(
|
|
77
87
|
component('rds', {
|
|
78
|
-
|
|
88
|
+
tags: ['tag2'],
|
|
89
|
+
shape: 'storage',
|
|
79
90
|
}),
|
|
80
91
|
component('s3', {
|
|
81
|
-
|
|
82
|
-
|
|
92
|
+
tags: ['tag2'],
|
|
93
|
+
shape: 'storage',
|
|
94
|
+
}),
|
|
83
95
|
),
|
|
84
|
-
system('email'
|
|
96
|
+
system('email', {
|
|
97
|
+
tags: ['external'],
|
|
98
|
+
}),
|
|
85
99
|
),
|
|
86
100
|
$m.model(
|
|
87
101
|
$m.rel('customer', 'cloud', 'uses services'),
|
|
@@ -93,7 +107,7 @@ const local = b
|
|
|
93
107
|
$m.rel('cloud.frontend.mobile', 'cloud.auth', 'authenticates'),
|
|
94
108
|
$m.rel('cloud.frontend.mobile', 'cloud.backend.api', 'fetches data'),
|
|
95
109
|
$m.rel('cloud.frontend.mobile', 'cloud.media', 'fetches media'),
|
|
96
|
-
$m.rel('cloud.frontend', 'cloud.backend')
|
|
110
|
+
$m.rel('cloud.frontend', 'cloud.backend'),
|
|
97
111
|
),
|
|
98
112
|
$m.model(
|
|
99
113
|
$m.rel('cloud.backend.api', 'cloud.auth', 'authorizes'),
|
|
@@ -102,30 +116,30 @@ const local = b
|
|
|
102
116
|
$m.rel('cloud.backend.api', 'email', 'sends emails'),
|
|
103
117
|
$m.rel('cloud', 'email', 'uses'),
|
|
104
118
|
$m.rel('cloud.media', 'aws.s3', 'uploads'),
|
|
105
|
-
$m.rel('email', 'customer', 'sends emails')
|
|
119
|
+
$m.rel('email', 'customer', 'sends emails'),
|
|
106
120
|
),
|
|
107
121
|
deployment(
|
|
108
122
|
node('customer').with(
|
|
109
|
-
instanceOf('instance', 'customer')
|
|
123
|
+
instanceOf('instance', 'customer'),
|
|
110
124
|
),
|
|
111
125
|
env('prod').with(
|
|
112
126
|
zone('eu').with(
|
|
113
127
|
zone('zone1').with(
|
|
114
128
|
instanceOf('ui', 'cloud.frontend.dashboard'),
|
|
115
|
-
instanceOf('api', 'cloud.backend.api')
|
|
129
|
+
instanceOf('api', 'cloud.backend.api'),
|
|
116
130
|
),
|
|
117
131
|
zone('zone2').with(
|
|
118
132
|
instanceOf('ui', 'cloud.frontend.dashboard'),
|
|
119
|
-
instanceOf('api', 'cloud.backend.api')
|
|
133
|
+
instanceOf('api', 'cloud.backend.api'),
|
|
120
134
|
),
|
|
121
135
|
instanceOf('media', 'cloud.media'),
|
|
122
|
-
instanceOf('db', 'aws.rds')
|
|
136
|
+
instanceOf('db', 'aws.rds'),
|
|
123
137
|
),
|
|
124
138
|
zone('us').with(
|
|
125
|
-
instanceOf('db', 'aws.rds')
|
|
126
|
-
)
|
|
139
|
+
instanceOf('db', 'aws.rds'),
|
|
140
|
+
),
|
|
127
141
|
),
|
|
128
|
-
$d.rel('prod.eu.db', 'prod.us.db', 'replicates')
|
|
142
|
+
$d.rel('prod.eu.db', 'prod.us.db', 'replicates'),
|
|
129
143
|
),
|
|
130
144
|
views(
|
|
131
145
|
view('index', $include('*')),
|
|
@@ -134,14 +148,14 @@ const local = b
|
|
|
134
148
|
'cloud',
|
|
135
149
|
$rules(
|
|
136
150
|
$include('*'),
|
|
137
|
-
$include('cloud.frontend.dashboard')
|
|
138
|
-
)
|
|
151
|
+
$include('cloud.frontend.dashboard'),
|
|
152
|
+
),
|
|
139
153
|
),
|
|
140
154
|
deploymentView('prod').with(
|
|
141
155
|
$include('customer.instance'),
|
|
142
|
-
$include('prod.eu.zone1.ui')
|
|
143
|
-
)
|
|
144
|
-
)
|
|
156
|
+
$include('prod.eu.zone1.ui'),
|
|
157
|
+
),
|
|
158
|
+
),
|
|
145
159
|
)
|
|
146
160
|
|
|
147
161
|
export const builder = local.clone()
|
|
@@ -149,6 +163,6 @@ export const builder = local.clone()
|
|
|
149
163
|
export const parsed = local.build()
|
|
150
164
|
export type TestFqn = typeof local.Types.Fqn
|
|
151
165
|
|
|
152
|
-
export const computed =
|
|
166
|
+
export const computed = computeParsedModelData(parsed)
|
|
153
167
|
|
|
154
168
|
export const model = LikeC4Model.create(computed)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { Fqn } from '../../types'
|
|
1
|
+
import type { AnyAux, Fqn } from '../../types'
|
|
2
2
|
import { isAncestor } from '../../utils'
|
|
3
3
|
import type { DeploymentElementModel } from '../DeploymentElementModel'
|
|
4
4
|
import type { ElementModel } from '../ElementModel'
|
|
5
5
|
|
|
6
|
-
export interface Connection<Elem = ElementModel | DeploymentElementModel
|
|
6
|
+
export interface Connection<Elem = ElementModel<AnyAux> | DeploymentElementModel<AnyAux>, Id = string> {
|
|
7
7
|
readonly id: Id
|
|
8
8
|
readonly source: Elem
|
|
9
9
|
readonly target: Elem
|
|
@@ -1,36 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import { stringHash } from '../../../utils'
|
|
1
|
+
import type { AnyAux, aux, IteratorLike } from '../../../types'
|
|
2
|
+
import { invariant, stringHash } from '../../../utils'
|
|
4
3
|
import { customInspectSymbol } from '../../../utils/const'
|
|
5
4
|
import { equals } from '../../../utils/set'
|
|
6
5
|
import {
|
|
7
|
-
type DeployedInstanceModel,
|
|
8
6
|
type DeploymentElementModel,
|
|
9
7
|
type DeploymentRelationModel,
|
|
10
8
|
DeploymentNodeModel,
|
|
11
9
|
RelationshipsAccum,
|
|
12
10
|
} from '../../DeploymentElementModel'
|
|
13
11
|
import type { RelationshipModel } from '../../RelationModel'
|
|
14
|
-
import type { AnyAux } from '../../types'
|
|
15
12
|
import type { Connection } from '../Connection'
|
|
16
13
|
|
|
17
14
|
/**
|
|
18
15
|
* Connection is ephemeral entity, result of a resolving relationships between source and target.
|
|
19
16
|
* Includes direct relationships and/or between their nested elements.
|
|
20
17
|
*/
|
|
21
|
-
export class DeploymentConnectionModel<
|
|
22
|
-
implements Connection<DeploymentElementModel<
|
|
18
|
+
export class DeploymentConnectionModel<A extends AnyAux = AnyAux>
|
|
19
|
+
implements Connection<DeploymentElementModel<A>, aux.EdgeId>
|
|
23
20
|
{
|
|
21
|
+
readonly id: aux.EdgeId
|
|
22
|
+
|
|
24
23
|
constructor(
|
|
25
|
-
public readonly source:
|
|
26
|
-
public readonly target:
|
|
27
|
-
public readonly relations: RelationshipsAccum<
|
|
24
|
+
public readonly source: DeploymentElementModel<A>,
|
|
25
|
+
public readonly target: DeploymentElementModel<A>,
|
|
26
|
+
public readonly relations: RelationshipsAccum<A>,
|
|
28
27
|
) {
|
|
29
|
-
this.id = stringHash(`deployment:${source.id}:${target.id}`) as
|
|
28
|
+
this.id = stringHash(`deployment:${source.id}:${target.id}`) as aux.EdgeId
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
readonly id: M['EdgeId']
|
|
33
|
-
|
|
34
31
|
/**
|
|
35
32
|
* Human readable expression of the connection
|
|
36
33
|
* Mostly used for testing and debugging
|
|
@@ -39,12 +36,12 @@ export class DeploymentConnectionModel<M extends AnyAux = AnyAux>
|
|
|
39
36
|
return `${this.source.id} -> ${this.target.id}`
|
|
40
37
|
}
|
|
41
38
|
|
|
42
|
-
private _boundary: DeploymentNodeModel<
|
|
39
|
+
private _boundary: DeploymentNodeModel<A> | null | undefined
|
|
43
40
|
/**
|
|
44
41
|
* Common ancestor of the source and target elements.
|
|
45
42
|
* Represents the boundary of the connection.
|
|
46
43
|
*/
|
|
47
|
-
get boundary(): DeploymentNodeModel<
|
|
44
|
+
get boundary(): DeploymentNodeModel<A> | null {
|
|
48
45
|
this._boundary ??= this.source.commonAncestor(this.target)
|
|
49
46
|
return this._boundary
|
|
50
47
|
}
|
|
@@ -105,7 +102,7 @@ export class DeploymentConnectionModel<M extends AnyAux = AnyAux>
|
|
|
105
102
|
return false
|
|
106
103
|
}
|
|
107
104
|
|
|
108
|
-
public *values(): IteratorLike<RelationshipModel<
|
|
105
|
+
public *values(): IteratorLike<RelationshipModel<A> | DeploymentRelationModel<A>> {
|
|
109
106
|
yield* this.relations.model
|
|
110
107
|
yield* this.relations.deployment
|
|
111
108
|
}
|
|
@@ -114,13 +111,13 @@ export class DeploymentConnectionModel<M extends AnyAux = AnyAux>
|
|
|
114
111
|
* Merge with another connections, if it has the same source and target.
|
|
115
112
|
* Returns new connection with union of relationships.
|
|
116
113
|
*/
|
|
117
|
-
public mergeWith(others: DeploymentConnectionModel<
|
|
114
|
+
public mergeWith(others: DeploymentConnectionModel<A>[]): DeploymentConnectionModel<A>
|
|
118
115
|
/**
|
|
119
116
|
* Merge with another connection, if it has the same source and target.
|
|
120
117
|
* Returns new connection with union of relationships.
|
|
121
118
|
*/
|
|
122
|
-
public mergeWith(other: DeploymentConnectionModel<
|
|
123
|
-
public mergeWith(other: DeploymentConnectionModel<
|
|
119
|
+
public mergeWith(other: DeploymentConnectionModel<A>): DeploymentConnectionModel<A>
|
|
120
|
+
public mergeWith(other: DeploymentConnectionModel<A> | DeploymentConnectionModel<A>[]): DeploymentConnectionModel<A> {
|
|
124
121
|
if (Array.isArray(other)) {
|
|
125
122
|
return other.reduce((acc, o) => acc.mergeWith(o), this)
|
|
126
123
|
}
|
|
@@ -134,7 +131,7 @@ export class DeploymentConnectionModel<M extends AnyAux = AnyAux>
|
|
|
134
131
|
)
|
|
135
132
|
}
|
|
136
133
|
|
|
137
|
-
public difference(other: DeploymentConnectionModel<
|
|
134
|
+
public difference(other: DeploymentConnectionModel<A>) {
|
|
138
135
|
return new DeploymentConnectionModel(
|
|
139
136
|
this.source,
|
|
140
137
|
this.target,
|
|
@@ -142,7 +139,7 @@ export class DeploymentConnectionModel<M extends AnyAux = AnyAux>
|
|
|
142
139
|
)
|
|
143
140
|
}
|
|
144
141
|
|
|
145
|
-
public intersect(other: DeploymentConnectionModel<
|
|
142
|
+
public intersect(other: DeploymentConnectionModel<A>) {
|
|
146
143
|
return new DeploymentConnectionModel(
|
|
147
144
|
this.source,
|
|
148
145
|
this.target,
|
|
@@ -164,9 +161,9 @@ export class DeploymentConnectionModel<M extends AnyAux = AnyAux>
|
|
|
164
161
|
* if `null` is provided in overrides, the corresponding relation set will be empty.
|
|
165
162
|
*/
|
|
166
163
|
public update(overrides?: {
|
|
167
|
-
model?: ReadonlySet<RelationshipModel<
|
|
168
|
-
deployment?: ReadonlySet<DeploymentRelationModel<
|
|
169
|
-
}): DeploymentConnectionModel<
|
|
164
|
+
model?: ReadonlySet<RelationshipModel<A>> | null
|
|
165
|
+
deployment?: ReadonlySet<DeploymentRelationModel<A>> | null
|
|
166
|
+
}): DeploymentConnectionModel<A> {
|
|
170
167
|
if (overrides) {
|
|
171
168
|
overrides = {
|
|
172
169
|
model: this.relations.model,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { AnyAux } from '../../../types'
|
|
1
2
|
import { isSameHierarchy } from '../../../utils'
|
|
2
3
|
import type { DeploymentElementModel } from '../../DeploymentElementModel'
|
|
3
|
-
import type { AnyAux } from '../../types'
|
|
4
4
|
import { DeploymentConnectionModel } from './DeploymentConnectionModel'
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { isNot } from 'remeda'
|
|
2
|
-
import {
|
|
2
|
+
import type { AnyAux, aux, Unknown } from '../../../types'
|
|
3
|
+
import { invariant } from '../../../utils'
|
|
3
4
|
import { customInspectSymbol } from '../../../utils/const'
|
|
4
5
|
import { ifilter, isome } from '../../../utils/iterable'
|
|
5
6
|
import { difference, equals, intersection, union } from '../../../utils/set'
|
|
6
7
|
import { stringHash } from '../../../utils/string-hash'
|
|
7
8
|
import type { ElementModel } from '../../ElementModel'
|
|
8
9
|
import type { RelationshipModel } from '../../RelationModel'
|
|
9
|
-
import type { AnyAux } from '../../types'
|
|
10
10
|
import type { Connection } from '../Connection'
|
|
11
11
|
import { hasSameSourceTarget } from '../ops'
|
|
12
12
|
import { findConnection } from './find'
|
|
@@ -17,23 +17,23 @@ import { findConnection } from './find'
|
|
|
17
17
|
*
|
|
18
18
|
* Merges relationships together to an single edge on the diagram.
|
|
19
19
|
*/
|
|
20
|
-
export class ConnectionModel<
|
|
21
|
-
public readonly id:
|
|
20
|
+
export class ConnectionModel<A extends AnyAux = Unknown> implements Connection<ElementModel<A>, aux.EdgeId> {
|
|
21
|
+
public readonly id: aux.EdgeId
|
|
22
22
|
|
|
23
23
|
constructor(
|
|
24
|
-
public readonly source: ElementModel<
|
|
25
|
-
public readonly target: ElementModel<
|
|
26
|
-
public readonly relations: ReadonlySet<RelationshipModel<
|
|
24
|
+
public readonly source: ElementModel<A>,
|
|
25
|
+
public readonly target: ElementModel<A>,
|
|
26
|
+
public readonly relations: ReadonlySet<RelationshipModel<A>> = new Set(),
|
|
27
27
|
) {
|
|
28
|
-
this.id = stringHash(`model:${source.id}:${target.id}`) as
|
|
28
|
+
this.id = stringHash(`model:${source.id}:${target.id}`) as aux.EdgeId
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
private _boundary: ElementModel<
|
|
31
|
+
private _boundary: ElementModel<A> | null | undefined
|
|
32
32
|
/**
|
|
33
33
|
* Common ancestor of the source and target elements.
|
|
34
34
|
* Represents the boundary of the connection.
|
|
35
35
|
*/
|
|
36
|
-
get boundary(): ElementModel<
|
|
36
|
+
get boundary(): ElementModel<A> | null {
|
|
37
37
|
return this._boundary ??= this.source.commonAncestor(this.target)
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -59,7 +59,7 @@ export class ConnectionModel<M extends AnyAux = AnyAux> implements Connection<El
|
|
|
59
59
|
return this.nonEmpty() && isome(this.relations, isNot(hasSameSourceTarget(this)))
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
get directRelations(): ReadonlySet<RelationshipModel<
|
|
62
|
+
get directRelations(): ReadonlySet<RelationshipModel<A>> {
|
|
63
63
|
return new Set(ifilter(this.relations, hasSameSourceTarget(this)))
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -67,7 +67,7 @@ export class ConnectionModel<M extends AnyAux = AnyAux> implements Connection<El
|
|
|
67
67
|
return this.relations.size > 0
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
mergeWith(other: ConnectionModel<
|
|
70
|
+
mergeWith(other: ConnectionModel<A>) {
|
|
71
71
|
invariant(this.source.id === other.source.id, 'Cannot merge connections with different sources')
|
|
72
72
|
invariant(this.target.id === other.target.id, 'Cannot merge connections with different targets')
|
|
73
73
|
return new ConnectionModel(
|
|
@@ -77,7 +77,7 @@ export class ConnectionModel<M extends AnyAux = AnyAux> implements Connection<El
|
|
|
77
77
|
)
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
difference(other: ConnectionModel<
|
|
80
|
+
difference(other: ConnectionModel<A>) {
|
|
81
81
|
return new ConnectionModel(
|
|
82
82
|
this.source,
|
|
83
83
|
this.target,
|
|
@@ -85,7 +85,7 @@ export class ConnectionModel<M extends AnyAux = AnyAux> implements Connection<El
|
|
|
85
85
|
)
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
intersect(other: ConnectionModel<
|
|
88
|
+
intersect(other: ConnectionModel<A>) {
|
|
89
89
|
invariant(other instanceof ConnectionModel, 'Cannot intersect connection with different type')
|
|
90
90
|
return new ConnectionModel(
|
|
91
91
|
this.source,
|
|
@@ -96,10 +96,11 @@ export class ConnectionModel<M extends AnyAux = AnyAux> implements Connection<El
|
|
|
96
96
|
|
|
97
97
|
equals(other: Connection): boolean {
|
|
98
98
|
invariant(other instanceof ConnectionModel, 'Cannot merge connection with different type')
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
&& this.
|
|
102
|
-
&&
|
|
99
|
+
const _other = other as ConnectionModel<A>
|
|
100
|
+
return this.id === _other.id
|
|
101
|
+
&& this.source.id === _other.source.id
|
|
102
|
+
&& this.target.id === _other.target.id
|
|
103
|
+
&& equals(this.relations, _other.relations)
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
/**
|
|
@@ -108,7 +109,7 @@ export class ConnectionModel<M extends AnyAux = AnyAux> implements Connection<El
|
|
|
108
109
|
* @param relations - A readonly set of `RelationshipModel` instances representing the new relations.
|
|
109
110
|
* @returns A new `ConnectionModel` instance with the updated relations.
|
|
110
111
|
*/
|
|
111
|
-
update(relations: ReadonlySet<RelationshipModel<
|
|
112
|
+
update(relations: ReadonlySet<RelationshipModel<A>>): ConnectionModel<A> {
|
|
112
113
|
return new ConnectionModel(
|
|
113
114
|
this.source,
|
|
114
115
|
this.target,
|
|
@@ -147,7 +148,7 @@ export class ConnectionModel<M extends AnyAux = AnyAux> implements Connection<El
|
|
|
147
148
|
* Creates a new connection with reversed direction (target becomes source and vice versa)
|
|
148
149
|
* @param search - When true, attempts to find an existing connection between the reversed nodes
|
|
149
150
|
*/
|
|
150
|
-
reversed(search = false): ConnectionModel<
|
|
151
|
+
reversed(search = false): ConnectionModel<A> {
|
|
151
152
|
if (!search) {
|
|
152
153
|
return new ConnectionModel(this.target, this.source)
|
|
153
154
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import type { AnyAux } from '../../../types'
|
|
1
2
|
import { isSameHierarchy } from '../../../utils/fqn'
|
|
2
3
|
import { intersection } from '../../../utils/set'
|
|
3
4
|
import type { ElementModel } from '../../ElementModel'
|
|
4
|
-
import type { AnyAux } from '../../types'
|
|
5
5
|
import { ConnectionModel } from './ConnectionModel'
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -10,13 +10,13 @@ import { ConnectionModel } from './ConnectionModel'
|
|
|
10
10
|
* @param direction - if 'both', also returns connection from target to source
|
|
11
11
|
* @default `directed`
|
|
12
12
|
*/
|
|
13
|
-
export function findConnection<
|
|
14
|
-
source: ElementModel<
|
|
15
|
-
target: ElementModel<
|
|
13
|
+
export function findConnection<A extends AnyAux>(
|
|
14
|
+
source: ElementModel<A>,
|
|
15
|
+
target: ElementModel<A>,
|
|
16
16
|
direction: 'directed' | 'both' = 'directed',
|
|
17
17
|
):
|
|
18
|
-
| [ConnectionModel<
|
|
19
|
-
| [ConnectionModel<
|
|
18
|
+
| [ConnectionModel<A>, ConnectionModel<A>]
|
|
19
|
+
| [ConnectionModel<A>]
|
|
20
20
|
| []
|
|
21
21
|
{
|
|
22
22
|
if (source === target) {
|
|
@@ -69,7 +69,7 @@ export function findConnection<M extends AnyAux>(
|
|
|
69
69
|
*/
|
|
70
70
|
export function findConnectionsBetween<M extends AnyAux>(
|
|
71
71
|
element: ElementModel<M>,
|
|
72
|
-
others: Iterable<ElementModel<
|
|
72
|
+
others: Iterable<ElementModel<M>>,
|
|
73
73
|
direction: 'directed' | 'both' = 'both',
|
|
74
74
|
): readonly ConnectionModel<M>[] {
|
|
75
75
|
if (element.allIncoming.size === 0 && element.allOutgoing.size === 0) {
|
|
@@ -136,14 +136,14 @@ export function findDescendantConnections<C extends ConnectionElemId>(
|
|
|
136
136
|
return connections.filter(isNestedConnection(connection))
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
export function mergeConnections<C extends Connection
|
|
140
|
-
connections:
|
|
141
|
-
): C[] {
|
|
142
|
-
const map = new Map<C['id'], C>()
|
|
139
|
+
export function mergeConnections<C extends IterableContainer<Connection<any, any>>>(
|
|
140
|
+
connections: C,
|
|
141
|
+
): Array<C[number]> {
|
|
142
|
+
const map = new Map<C[number]['id'], C[number]>()
|
|
143
143
|
for (const conn of connections) {
|
|
144
144
|
const existing = map.get(conn.id)
|
|
145
145
|
if (existing) {
|
|
146
|
-
map.set(conn.id, conn.mergeWith(existing)
|
|
146
|
+
map.set(conn.id, conn.mergeWith(existing))
|
|
147
147
|
} else {
|
|
148
148
|
map.set(conn.id, conn)
|
|
149
149
|
}
|
|
@@ -155,7 +155,7 @@ export function mergeConnections<C extends Connection>(
|
|
|
155
155
|
* Excludes the values existing in `other` array.
|
|
156
156
|
* The output maintains the same order as the input.
|
|
157
157
|
*/
|
|
158
|
-
export function differenceConnections<C extends Connection
|
|
158
|
+
export function differenceConnections<C extends Connection<any, any>>(
|
|
159
159
|
source: Iterable<C>,
|
|
160
160
|
exclude: Iterable<C>,
|
|
161
161
|
): C[] {
|