@likec4/core 1.17.1 → 1.18.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/compute-view/index.d.mts +91 -0
- package/dist/compute-view/index.d.ts +91 -0
- package/dist/compute-view/index.mjs +79 -0
- package/dist/index.d.mts +246 -434
- package/dist/index.d.ts +246 -434
- package/dist/index.mjs +418 -1322
- package/dist/model/index.d.mts +642 -0
- package/dist/model/index.d.ts +642 -0
- package/dist/model/index.mjs +2 -0
- package/dist/shared/core.BBgiAAv1.mjs +144 -0
- package/dist/shared/core.BPyJvuMU.mjs +2420 -0
- package/dist/shared/core.BQ4AbfvB.mjs +9228 -0
- package/dist/shared/{core.CoLQkcYL.d.mts → core.DMYY7C8s.d.mts} +398 -249
- package/dist/shared/{core.CoLQkcYL.d.ts → core.DMYY7C8s.d.ts} +398 -249
- package/dist/shared/core.k12s_keD.mjs +203 -0
- package/dist/types/index.d.mts +69 -1
- package/dist/types/index.d.ts +69 -1
- package/dist/types/index.mjs +21 -1
- package/package.json +38 -40
- package/src/builder/Builder.deployment.ts +219 -0
- package/src/builder/Builder.deploymentModel.ts +360 -0
- package/src/builder/Builder.element.ts +17 -19
- package/src/builder/Builder.model.ts +13 -2
- package/src/builder/Builder.test-d.ts +59 -4
- package/src/builder/Builder.ts +238 -53
- package/src/builder/Builder.view.ts +238 -53
- package/src/builder/_types.ts +87 -15
- package/src/compute-view/LikeC4ModelGraph.ts +330 -0
- package/src/compute-view/compute-view.ts +92 -0
- package/src/compute-view/deployment-view/Memory.ts +108 -0
- package/src/compute-view/deployment-view/Stage.ts +145 -0
- package/src/compute-view/deployment-view/__test__/fixture.ts +210 -0
- package/src/compute-view/deployment-view/_types.ts +29 -0
- package/src/compute-view/deployment-view/clean-connections.ts +229 -0
- package/src/compute-view/deployment-view/compute.ts +111 -0
- package/src/compute-view/deployment-view/predicates/deployment-ref.ts +146 -0
- package/src/compute-view/deployment-view/predicates/relation-direct.ts +130 -0
- package/src/compute-view/deployment-view/predicates/relation-in-out.ts +43 -0
- package/src/compute-view/deployment-view/predicates/relation-incoming.ts +46 -0
- package/src/compute-view/deployment-view/predicates/relation-outgoing.ts +49 -0
- package/src/compute-view/deployment-view/predicates/wildcard.ts +29 -0
- package/src/compute-view/deployment-view/utils.ts +212 -0
- package/src/compute-view/dynamic-view/__test__/fixture.ts +58 -0
- package/src/compute-view/dynamic-view/compute.ts +310 -0
- package/src/compute-view/element-view/__test__/__snapshots__/legacy.spec.ts.snap +456 -0
- package/src/compute-view/element-view/__test__/fixture.ts +645 -0
- package/src/compute-view/element-view/compute.ts +734 -0
- package/src/compute-view/element-view/predicates.ts +517 -0
- package/src/compute-view/index.ts +5 -0
- package/src/compute-view/utils/__snapshots__/sortNodes.spec.ts.snap +113 -0
- package/src/compute-view/utils/ancestorsOfNode.ts +19 -0
- package/src/compute-view/utils/applyCustomElementProperties.ts +66 -0
- package/src/compute-view/utils/applyCustomRelationProperties.ts +41 -0
- package/src/compute-view/utils/applyViewRuleStyles.ts +53 -0
- package/src/compute-view/utils/buildComputedNodes.ts +148 -0
- package/src/compute-view/utils/buildElementNotations.ts +63 -0
- package/src/compute-view/utils/derive-edge-props-from-relationships.ts +97 -0
- package/src/compute-view/utils/elementExpressionToPredicate.ts +52 -0
- package/src/compute-view/utils/link-nodes-with-edges.ts +58 -0
- package/src/compute-view/utils/relationExpressionToPredicates.ts +55 -0
- package/src/compute-view/utils/resolve-extended-views.ts +65 -0
- package/src/compute-view/utils/resolve-global-rules.ts +83 -0
- package/src/compute-view/utils/sortNodes.ts +101 -0
- package/src/compute-view/utils/topological-sort.ts +160 -0
- package/src/compute-view/utils/uniqueTags.test.ts +42 -0
- package/src/compute-view/utils/uniqueTags.ts +21 -0
- package/src/compute-view/utils/view-hash.ts +27 -0
- package/src/compute-view/utils/with-readable-edges.ts +31 -0
- package/src/index.ts +5 -1
- package/src/model/DeploymentElementModel.ts +534 -0
- package/src/model/DeploymentModel.ts +364 -0
- package/src/model/ElementModel.ts +195 -0
- package/src/model/LikeC4Model.test-d.ts +151 -0
- package/src/model/LikeC4Model.ts +280 -457
- package/src/model/RelationModel.ts +84 -0
- package/src/model/__test__/fixture.ts +153 -338
- package/src/model/connection/ConnectionModel.ts +94 -0
- package/src/model/connection/DeploymentConnectionModel.ts +99 -0
- package/src/model/connection/deployment.ts +124 -0
- package/src/model/connection/model.ts +123 -0
- package/src/model/index.ts +4 -2
- package/src/model/types.ts +95 -15
- package/src/model/view/EdgeModel.ts +103 -0
- package/src/model/view/LikeC4ViewModel.ts +220 -0
- package/src/model/view/NodeModel.ts +228 -0
- package/src/types/_common.ts +2 -0
- package/src/types/deployments.ts +237 -0
- package/src/types/element.ts +7 -3
- package/src/types/expression.ts +8 -6
- package/src/types/index.ts +1 -0
- package/src/types/model.ts +68 -9
- package/src/types/overview-graph.ts +2 -2
- package/src/types/relation.ts +4 -4
- package/src/types/view-notation.ts +2 -2
- package/src/types/view.ts +104 -30
- package/src/utils/{commonHead.ts → common-head.ts} +2 -0
- package/src/utils/fqn.ts +83 -27
- package/src/utils/getOrCreate.ts +42 -0
- package/src/utils/graphlib.ts +10 -0
- package/src/utils/index.ts +4 -1
- package/src/utils/object-hash.ts +3 -0
- package/src/utils/set.ts +76 -0
- package/src/utils/string-hash.ts +16 -0
- package/dist/index.cjs +0 -5452
- package/dist/index.d.cts +0 -1053
- package/dist/shared/core.BXTs-8n7.mjs +0 -293
- package/dist/shared/core.CoLQkcYL.d.cts +0 -734
- package/dist/shared/core.DIYZvpVg.cjs +0 -353
- package/dist/types/index.cjs +0 -70
- package/dist/types/index.d.cts +0 -2
- package/src/model/LikeC4DiagramModel.ts +0 -338
- package/src/model/LikeC4ViewModel.ts +0 -320
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
import { isEmpty, only } from 'remeda'
|
|
2
|
+
import type { SetRequired } from 'type-fest'
|
|
3
|
+
import { nonNullable } from '../errors'
|
|
4
|
+
import {
|
|
5
|
+
type ComputedDeploymentView,
|
|
6
|
+
DefaultElementShape,
|
|
7
|
+
DefaultThemeColor,
|
|
8
|
+
type DeployedInstance,
|
|
9
|
+
type DeploymentNode,
|
|
10
|
+
type DeploymentNodeKind,
|
|
11
|
+
type DeploymentRelation,
|
|
12
|
+
type ElementShape as C4ElementShape,
|
|
13
|
+
type Link,
|
|
14
|
+
type PhysicalElementStyle,
|
|
15
|
+
type Tag,
|
|
16
|
+
type Tag as C4Tag,
|
|
17
|
+
type ThemeColor
|
|
18
|
+
} from '../types'
|
|
19
|
+
import { commonAncestor, nameFromFqn } from '../utils'
|
|
20
|
+
import { difference, intersection, union } from '../utils/set'
|
|
21
|
+
import type { LikeC4DeploymentModel } from './DeploymentModel'
|
|
22
|
+
import type { ElementModel } from './ElementModel'
|
|
23
|
+
import type { RelationshipModel, RelationshipsIterator } from './RelationModel'
|
|
24
|
+
import type { AnyAux, IncomingFilter, IteratorLike, OutgoingFilter } from './types'
|
|
25
|
+
import type { LikeC4ViewModel } from './view/LikeC4ViewModel'
|
|
26
|
+
|
|
27
|
+
export type DeploymentElementsIterator<M extends AnyAux> = IteratorLike<DeploymentElementModel<M>>
|
|
28
|
+
export type DeployedInstancesIterator<M extends AnyAux> = IteratorLike<DeployedInstanceModel<M>>
|
|
29
|
+
export type DeploymentNodesIterator<M extends AnyAux> = IteratorLike<DeploymentNodeModel<M>>
|
|
30
|
+
|
|
31
|
+
export abstract class DeploymentElementModel<M extends AnyAux = AnyAux> {
|
|
32
|
+
abstract readonly $model: LikeC4DeploymentModel<M>
|
|
33
|
+
abstract readonly $node: DeploymentNode | DeployedInstance
|
|
34
|
+
|
|
35
|
+
get id(): M['DeploymentFqn'] {
|
|
36
|
+
return this.$node.id
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get style(): SetRequired<PhysicalElementStyle, 'shape' | 'color'> {
|
|
40
|
+
return {
|
|
41
|
+
shape: DefaultElementShape,
|
|
42
|
+
color: DefaultThemeColor,
|
|
43
|
+
...this.$node.style
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
get shape(): C4ElementShape {
|
|
48
|
+
return this.$node.style?.shape ?? DefaultElementShape
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
get color(): ThemeColor {
|
|
52
|
+
return this.$node.style?.color as ThemeColor ?? DefaultThemeColor
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get tags(): ReadonlyArray<C4Tag> {
|
|
56
|
+
return this.$node.tags ?? []
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
get title(): string {
|
|
60
|
+
return this.$node.title ?? nameFromFqn(this.id)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
get description(): string | null {
|
|
64
|
+
return this.$node.description ?? null
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
get technology(): string | null {
|
|
68
|
+
return this.$node.technology ?? null
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
get parent(): DeploymentNodeModel<M> | null {
|
|
72
|
+
return this.$model.parent(this)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
get links(): ReadonlyArray<Link> {
|
|
76
|
+
return this.$node.links ?? []
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get all ancestor elements (i.e. parent, parent’s parent, etc.)
|
|
81
|
+
* (from closest to root)
|
|
82
|
+
*/
|
|
83
|
+
public ancestors(): DeploymentNodesIterator<M> {
|
|
84
|
+
return this.$model.ancestors(this)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Returns the common ancestor of this element and another element.
|
|
89
|
+
*/
|
|
90
|
+
public commonAncestor(another: DeploymentElementModel<M>): DeploymentNodeModel<M> | null {
|
|
91
|
+
const common = commonAncestor(this.id, another.id)
|
|
92
|
+
return common ? this.$model.node(common) : null
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Get all sibling (i.e. same parent)
|
|
97
|
+
*/
|
|
98
|
+
public siblings(): DeploymentElementsIterator<M> {
|
|
99
|
+
return this.$model.siblings(this)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Check if the element is a sibling of another element
|
|
104
|
+
*/
|
|
105
|
+
public isSibling(other: DeploymentElementModel<M>): boolean {
|
|
106
|
+
return this.parent === other.parent
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Resolve siblings of the element and its ancestors
|
|
111
|
+
* (from closest to root)
|
|
112
|
+
*/
|
|
113
|
+
public *ascendingSiblings(): DeploymentElementsIterator<M> {
|
|
114
|
+
yield* this.siblings()
|
|
115
|
+
for (const ancestor of this.ancestors()) {
|
|
116
|
+
yield* ancestor.siblings()
|
|
117
|
+
}
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public incoming(filter: IncomingFilter = 'all'): IteratorLike<DeploymentRelationModel<M>> {
|
|
122
|
+
return this.$model.incoming(this, filter)
|
|
123
|
+
}
|
|
124
|
+
public outgoing(filter: OutgoingFilter = 'all'): IteratorLike<DeploymentRelationModel<M>> {
|
|
125
|
+
return this.$model.outgoing(this, filter)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public *incomers(filter: IncomingFilter = 'all'): IteratorLike<DeploymentRelationEndpoint<M>> {
|
|
129
|
+
const unique = new Set<M['Deployment']>()
|
|
130
|
+
for (const r of this.incoming(filter)) {
|
|
131
|
+
if (unique.has(r.source.id)) {
|
|
132
|
+
continue
|
|
133
|
+
}
|
|
134
|
+
unique.add(r.source.id)
|
|
135
|
+
yield r.source
|
|
136
|
+
}
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
public *outgoers(filter: OutgoingFilter = 'all'): IteratorLike<DeploymentRelationEndpoint<M>> {
|
|
140
|
+
const unique = new Set<M['Deployment']>()
|
|
141
|
+
for (const r of this.outgoing(filter)) {
|
|
142
|
+
if (unique.has(r.target.id)) {
|
|
143
|
+
continue
|
|
144
|
+
}
|
|
145
|
+
unique.add(r.target.id)
|
|
146
|
+
yield r.target
|
|
147
|
+
}
|
|
148
|
+
return
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Iterate over all views that include this deployment element.
|
|
153
|
+
*/
|
|
154
|
+
public *views(): IteratorLike<LikeC4ViewModel<M, ComputedDeploymentView>> {
|
|
155
|
+
for (const view of this.$model.views()) {
|
|
156
|
+
if (view.includesDeployment(this.id)) {
|
|
157
|
+
yield view
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// type guard
|
|
163
|
+
public isDeploymentNode(): this is DeploymentNodeModel<M> {
|
|
164
|
+
return false
|
|
165
|
+
}
|
|
166
|
+
// type guard
|
|
167
|
+
public isInstance(): this is DeployedInstanceModel<M> {
|
|
168
|
+
return false
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
public abstract outgoingFromModel(): RelationshipsIterator<M>
|
|
172
|
+
public abstract incomingFromModel(): RelationshipsIterator<M>
|
|
173
|
+
|
|
174
|
+
protected cachedOutgoing: RelationshipsAccum<M> | null = null
|
|
175
|
+
protected cachedIncoming: RelationshipsAccum<M> | null = null
|
|
176
|
+
|
|
177
|
+
public get allOutgoing(): RelationshipsAccum<M> {
|
|
178
|
+
this.cachedOutgoing ??= new RelationshipsAccum(
|
|
179
|
+
new Set(this.outgoingFromModel()),
|
|
180
|
+
new Set(this.outgoing())
|
|
181
|
+
)
|
|
182
|
+
return this.cachedOutgoing
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
public get allIncoming(): RelationshipsAccum<M> {
|
|
186
|
+
this.cachedIncoming ??= new RelationshipsAccum(
|
|
187
|
+
new Set(this.incomingFromModel()),
|
|
188
|
+
new Set(this.incoming())
|
|
189
|
+
)
|
|
190
|
+
return this.cachedIncoming
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export class DeploymentNodeModel<M extends AnyAux = AnyAux> extends DeploymentElementModel<M> {
|
|
195
|
+
constructor(
|
|
196
|
+
public readonly $model: LikeC4DeploymentModel<M>,
|
|
197
|
+
public readonly $node: DeploymentNode
|
|
198
|
+
) {
|
|
199
|
+
super()
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
get kind(): DeploymentNodeKind {
|
|
203
|
+
return this.$node.kind
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
public children(): ReadonlySet<DeploymentElementModel<M>> {
|
|
207
|
+
return this.$model.children(this)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
public descendants(): DeploymentElementsIterator<M> {
|
|
211
|
+
return this.$model.descendants(this)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
public override isDeploymentNode(): this is DeploymentNodeModel<M> {
|
|
215
|
+
return true
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Iterate over all instances nested in this deployment node.
|
|
220
|
+
*/
|
|
221
|
+
public *instances(): DeployedInstancesIterator<M> {
|
|
222
|
+
for (const nested of this.descendants()) {
|
|
223
|
+
if (nested.isInstance()) {
|
|
224
|
+
yield nested
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Returns deployed instance inside this deployment node
|
|
232
|
+
* if only there are no more instances
|
|
233
|
+
*/
|
|
234
|
+
public onlyOneInstance(): DeployedInstanceModel<M> | null {
|
|
235
|
+
const children = this.children()
|
|
236
|
+
if (children.size !== 1) {
|
|
237
|
+
return null
|
|
238
|
+
}
|
|
239
|
+
const child = only([...children])
|
|
240
|
+
return child?.isInstance() ? child : null
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Cached result of relationships from instances
|
|
245
|
+
*/
|
|
246
|
+
private _relationshipsFromInstances: {
|
|
247
|
+
outgoing: ReadonlySet<RelationshipModel<M>>
|
|
248
|
+
incoming: ReadonlySet<RelationshipModel<M>>
|
|
249
|
+
} | null = null
|
|
250
|
+
|
|
251
|
+
private relationshipsFromInstances() {
|
|
252
|
+
if (this._relationshipsFromInstances) {
|
|
253
|
+
return this._relationshipsFromInstances
|
|
254
|
+
}
|
|
255
|
+
const {
|
|
256
|
+
outgoing,
|
|
257
|
+
incoming
|
|
258
|
+
} = (this._relationshipsFromInstances = {
|
|
259
|
+
outgoing: new Set<RelationshipModel<M>>(),
|
|
260
|
+
incoming: new Set<RelationshipModel<M>>()
|
|
261
|
+
})
|
|
262
|
+
for (const instance of this.instances()) {
|
|
263
|
+
for (const r of instance.$element.outgoing()) {
|
|
264
|
+
outgoing.add(r)
|
|
265
|
+
}
|
|
266
|
+
for (const r of instance.$element.incoming()) {
|
|
267
|
+
incoming.add(r)
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return this._relationshipsFromInstances
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* We return only relationships that are not already present in nested instances
|
|
275
|
+
*/
|
|
276
|
+
public override outgoingFromModel(): RelationshipsIterator<M> {
|
|
277
|
+
const {
|
|
278
|
+
outgoing,
|
|
279
|
+
incoming
|
|
280
|
+
} = this.relationshipsFromInstances()
|
|
281
|
+
return difference(outgoing, incoming).values()
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* We return only relationships that are not already present in nested instances
|
|
286
|
+
*/
|
|
287
|
+
public override incomingFromModel(): RelationshipsIterator<M> {
|
|
288
|
+
const {
|
|
289
|
+
outgoing,
|
|
290
|
+
incoming
|
|
291
|
+
} = this.relationshipsFromInstances()
|
|
292
|
+
return difference(incoming, outgoing).values()
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export class DeployedInstanceModel<M extends AnyAux = AnyAux> extends DeploymentElementModel<M> {
|
|
297
|
+
constructor(
|
|
298
|
+
public readonly $model: LikeC4DeploymentModel<M>,
|
|
299
|
+
public readonly $instance: DeployedInstance,
|
|
300
|
+
public readonly $element: ElementModel<M>
|
|
301
|
+
) {
|
|
302
|
+
super()
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
override get parent(): DeploymentNodeModel<M> {
|
|
306
|
+
return nonNullable(this.$model.parent(this), `Parent of ${this.id} not found`)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
get $node(): DeployedInstance {
|
|
310
|
+
return this.$instance
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
override get style(): SetRequired<PhysicalElementStyle, 'shape' | 'color'> {
|
|
314
|
+
const { icon, style } = this.$element.$element
|
|
315
|
+
return {
|
|
316
|
+
shape: this.$element.shape,
|
|
317
|
+
color: this.$element.color,
|
|
318
|
+
...icon && { icon },
|
|
319
|
+
...style,
|
|
320
|
+
...this.$instance.style
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
override get shape(): C4ElementShape {
|
|
325
|
+
return this.$instance.style?.shape ?? this.$element.shape
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
override get color(): ThemeColor {
|
|
329
|
+
return this.$instance.style?.color as ThemeColor ?? this.$element.color
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
override get tags(): ReadonlyArray<C4Tag> {
|
|
333
|
+
return this.$instance.tags ?? []
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
override get title(): string {
|
|
337
|
+
return this.$instance.title ?? this.$element.title
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
override get description(): string | null {
|
|
341
|
+
return this.$instance.description ?? this.$element.description
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
override get technology(): string | null {
|
|
345
|
+
return this.$instance.technology ?? this.$element.technology
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
override get links(): ReadonlyArray<Link> {
|
|
349
|
+
return this.$instance.links ?? this.$element.links
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
public override isInstance(): this is DeployedInstanceModel<M> {
|
|
353
|
+
return true
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
public override outgoingFromModel(): RelationshipsIterator<M> {
|
|
357
|
+
return this.$element.outgoing()
|
|
358
|
+
}
|
|
359
|
+
public override incomingFromModel(): RelationshipsIterator<M> {
|
|
360
|
+
return this.$element.incoming()
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export class NestedElementOfDeployedInstanceModel<M extends AnyAux> {
|
|
365
|
+
constructor(
|
|
366
|
+
public readonly instance: DeployedInstanceModel<M>,
|
|
367
|
+
public readonly element: ElementModel<M>
|
|
368
|
+
) {
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
get id(): M['DeploymentFqn'] {
|
|
372
|
+
return this.instance.id
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
get style(): SetRequired<PhysicalElementStyle, 'shape' | 'color'> {
|
|
376
|
+
const { icon, style } = this.element.$element
|
|
377
|
+
return {
|
|
378
|
+
shape: this.element.shape,
|
|
379
|
+
color: this.element.color,
|
|
380
|
+
...icon && { icon },
|
|
381
|
+
...style
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
get shape(): C4ElementShape {
|
|
386
|
+
return this.element.shape
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
get color(): ThemeColor {
|
|
390
|
+
return this.element.color
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
get title(): string {
|
|
394
|
+
return this.element.title
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
get description(): string | null {
|
|
398
|
+
return this.element.description
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
get technology(): string | null {
|
|
402
|
+
return this.element.technology
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
public isDeploymentNode(): this is DeploymentNodeModel<M> {
|
|
406
|
+
return false
|
|
407
|
+
}
|
|
408
|
+
public isInstance(): this is DeployedInstanceModel<M> {
|
|
409
|
+
return false
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export type DeploymentRelationEndpoint<M extends AnyAux> =
|
|
414
|
+
| DeploymentElementModel<M>
|
|
415
|
+
| NestedElementOfDeployedInstanceModel<M>
|
|
416
|
+
|
|
417
|
+
export class DeploymentRelationModel<M extends AnyAux> {
|
|
418
|
+
public boundary: DeploymentNodeModel<M> | null
|
|
419
|
+
public source: DeploymentRelationEndpoint<M>
|
|
420
|
+
public target: DeploymentRelationEndpoint<M>
|
|
421
|
+
|
|
422
|
+
constructor(
|
|
423
|
+
public readonly $model: LikeC4DeploymentModel<M>,
|
|
424
|
+
public readonly $relationship: DeploymentRelation
|
|
425
|
+
) {
|
|
426
|
+
this.source = $model.deploymentRef($relationship.source)
|
|
427
|
+
this.target = $model.deploymentRef($relationship.target)
|
|
428
|
+
const parent = commonAncestor(this.source.id, this.target.id)
|
|
429
|
+
this.boundary = parent ? this.$model.node(parent) : null
|
|
430
|
+
}
|
|
431
|
+
get id(): M['RelationId'] {
|
|
432
|
+
return this.$relationship.id
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
get expression(): string {
|
|
436
|
+
return `${this.source.id} -> ${this.target.id}`
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
get title(): string | null {
|
|
440
|
+
if (isEmpty(this.$relationship.title)) {
|
|
441
|
+
return null
|
|
442
|
+
}
|
|
443
|
+
return this.$relationship.title
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
get technology(): string | null {
|
|
447
|
+
if (isEmpty(this.$relationship.technology)) {
|
|
448
|
+
return null
|
|
449
|
+
}
|
|
450
|
+
return this.$relationship.technology
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
get description(): string | null {
|
|
454
|
+
if (isEmpty(this.$relationship.description)) {
|
|
455
|
+
return null
|
|
456
|
+
}
|
|
457
|
+
return this.$relationship.description
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
get tags(): ReadonlyArray<Tag> {
|
|
461
|
+
return this.$relationship.tags ?? []
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
get navigateTo(): LikeC4ViewModel<M> | null {
|
|
465
|
+
return this.$relationship.navigateTo ? this.$model.$model.view(this.$relationship.navigateTo) : null
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
get links(): ReadonlyArray<Link> {
|
|
469
|
+
return this.$relationship.links ?? []
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
public *views(): IteratorLike<LikeC4ViewModel<M, ComputedDeploymentView>> {
|
|
473
|
+
for (const view of this.$model.views()) {
|
|
474
|
+
if (view.includesRelation(this.id)) {
|
|
475
|
+
yield view
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
export class RelationshipsAccum<M extends AnyAux> {
|
|
483
|
+
/**
|
|
484
|
+
* @param model relationships from logical model
|
|
485
|
+
* @param deployment relationships from deployment model
|
|
486
|
+
*/
|
|
487
|
+
constructor(
|
|
488
|
+
public readonly model: ReadonlySet<RelationshipModel<M>>,
|
|
489
|
+
public readonly deployment: ReadonlySet<DeploymentRelationModel<M>>
|
|
490
|
+
) {
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
get isEmpty(): boolean {
|
|
494
|
+
return this.model.size === 0 && this.deployment.size === 0
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
get nonEmpty(): boolean {
|
|
498
|
+
return this.model.size > 0 || this.deployment.size > 0
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
get size(): number {
|
|
502
|
+
return this.model.size + this.deployment.size
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Returns new Accum containing all the elements which are both in this and otherAccum
|
|
507
|
+
*/
|
|
508
|
+
public intersect(otherAccum: RelationshipsAccum<M>): RelationshipsAccum<M> {
|
|
509
|
+
return new RelationshipsAccum(
|
|
510
|
+
intersection(this.model, otherAccum.model),
|
|
511
|
+
intersection(this.deployment, otherAccum.deployment)
|
|
512
|
+
)
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Returns new Accum containing all the elements which are both in this and otherAccum
|
|
517
|
+
*/
|
|
518
|
+
public difference(otherAccum: RelationshipsAccum<M>): RelationshipsAccum<M> {
|
|
519
|
+
return new RelationshipsAccum(
|
|
520
|
+
difference(this.model, otherAccum.model),
|
|
521
|
+
difference(this.deployment, otherAccum.deployment)
|
|
522
|
+
)
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Returns new Accum containing all the elements from both
|
|
527
|
+
*/
|
|
528
|
+
public union(otherAccum: RelationshipsAccum<M>): RelationshipsAccum<M> {
|
|
529
|
+
return new RelationshipsAccum(
|
|
530
|
+
union(this.model, otherAccum.model),
|
|
531
|
+
union(this.deployment, otherAccum.deployment)
|
|
532
|
+
)
|
|
533
|
+
}
|
|
534
|
+
}
|