@likec4/core 1.18.0 → 1.19.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/LICENSE +1 -1
- package/dist/builder/index.d.mts +502 -0
- package/dist/builder/index.d.ts +502 -0
- package/dist/builder/index.js +871 -0
- package/dist/compute-view/index.d.mts +9 -78
- package/dist/compute-view/index.d.ts +9 -78
- package/dist/compute-view/index.js +78 -0
- package/dist/index.d.mts +9 -730
- package/dist/index.d.ts +9 -730
- package/dist/{index.mjs → index.js} +7 -784
- package/dist/model/index.d.mts +218 -606
- package/dist/model/index.d.ts +218 -606
- package/dist/model/index.js +1 -0
- package/dist/shared/chunk-RAAYCPUM.M-JWF7SS.js +21 -0
- package/dist/shared/core.BIfgabEw.d.ts +719 -0
- package/dist/shared/core.BZ9Msq7w.d.mts +719 -0
- package/dist/shared/{core.DMYY7C8s.d.mts → core.C05RDLhi.d.ts} +179 -230
- package/dist/shared/{core.DMYY7C8s.d.ts → core.CmYMqgha.d.mts} +179 -230
- package/dist/shared/core.D6-fWbM3.d.ts +127 -0
- package/dist/shared/core.D74xkKkG.d.mts +148 -0
- package/dist/shared/core.D74xkKkG.d.ts +148 -0
- package/dist/shared/core.sLaWHBjR.d.mts +127 -0
- package/dist/shared/index.-BdzdI2C.js +7443 -0
- package/dist/shared/object_hash.CE_oF3I3.js +1222 -0
- package/dist/shared/view.CyZrG8BJ.js +354 -0
- package/dist/types/index.d.mts +4 -2
- package/dist/types/index.d.ts +4 -2
- package/dist/types/index.js +20 -0
- package/dist/utils/index.d.mts +404 -0
- package/dist/utils/index.d.ts +404 -0
- package/dist/utils/index.js +330 -0
- package/package.json +47 -33
- package/src/builder/Builder-style1.test-d.ts +190 -0
- package/src/builder/Builder-style2.test-d.ts +175 -0
- package/src/builder/Builder.deployment.ts +25 -20
- package/src/builder/Builder.deploymentModel.ts +80 -55
- package/src/builder/Builder.element.ts +2 -0
- package/src/builder/Builder.model.ts +57 -43
- package/src/builder/Builder.ts +412 -431
- package/src/builder/Builder.view-common.ts +234 -0
- package/src/builder/Builder.view-deployment.ts +135 -0
- package/src/builder/Builder.view-element.ts +189 -0
- package/src/builder/Builder.views.ts +109 -33
- package/src/builder/Builder.with.ts +475 -0
- package/src/builder/__snapshots__/Builder-style1.spec.ts.snap +374 -0
- package/src/builder/__snapshots__/Builder-style2.spec.ts.snap +183 -0
- package/src/builder/__snapshots__/Builder.spec.ts.snap +374 -0
- package/src/builder/_types.ts +28 -5
- package/src/builder/index.ts +10 -4
- package/src/colors/index.ts +2 -2
- package/src/compute-view/compute-view.ts +45 -54
- package/src/compute-view/deployment-view/__test__/TestHelper.ts +236 -0
- package/src/compute-view/deployment-view/__test__/fixture.ts +50 -62
- package/src/compute-view/deployment-view/_types.ts +26 -18
- package/src/compute-view/deployment-view/clean-connections.ts +173 -164
- package/src/compute-view/deployment-view/compute.ts +51 -37
- package/src/compute-view/deployment-view/memory/index.ts +9 -0
- package/src/compute-view/deployment-view/memory/memory.ts +97 -0
- package/src/compute-view/deployment-view/predicates/elements.ts +144 -0
- package/src/compute-view/deployment-view/predicates/relation-direct.ts +183 -76
- package/src/compute-view/deployment-view/predicates/relation-in-out.ts +38 -20
- package/src/compute-view/deployment-view/predicates/relation-incoming.ts +72 -23
- package/src/compute-view/deployment-view/predicates/relation-outgoing.ts +61 -22
- package/src/compute-view/deployment-view/predicates/wildcard.ts +15 -15
- package/src/compute-view/deployment-view/stages/stage-exclude.ts +5 -0
- package/src/compute-view/deployment-view/stages/stage-final.ts +245 -0
- package/src/compute-view/deployment-view/stages/stage-include.ts +95 -0
- package/src/compute-view/deployment-view/utils.ts +95 -31
- package/src/compute-view/dynamic-view/__test__/fixture.ts +4 -4
- package/src/compute-view/dynamic-view/compute.ts +59 -45
- package/src/compute-view/element-view/__test__/TestHelper.ts +258 -0
- package/src/compute-view/element-view/__test__/__snapshots__/legacy.spec.ts.snap +64 -62
- package/src/compute-view/element-view/__test__/fixture.ts +147 -117
- package/src/compute-view/element-view/_types.ts +48 -0
- package/src/compute-view/element-view/clean-connections.ts +113 -0
- package/src/compute-view/element-view/compute.ts +264 -683
- package/src/compute-view/element-view/memory/NodeGroup.ts +31 -0
- package/src/compute-view/element-view/memory/index.ts +10 -0
- package/src/compute-view/element-view/memory/memory.ts +177 -0
- package/src/compute-view/element-view/memory/stage-exclude.ts +59 -0
- package/src/compute-view/element-view/memory/stage-final.ts +129 -0
- package/src/compute-view/element-view/memory/stage-include.ts +128 -0
- package/src/compute-view/element-view/predicates/_utils.ts +86 -0
- package/src/compute-view/element-view/predicates/element-expand.ts +33 -0
- package/src/compute-view/element-view/predicates/element-kind-tag.ts +26 -0
- package/src/compute-view/element-view/predicates/element-ref.ts +37 -0
- package/src/compute-view/element-view/predicates/relation-direct.ts +309 -0
- package/src/compute-view/element-view/predicates/relation-in-out.ts +66 -0
- package/src/compute-view/element-view/predicates/relation-in.ts +118 -0
- package/src/compute-view/element-view/predicates/relation-out.ts +116 -0
- package/src/compute-view/element-view/predicates/wildcard.ts +88 -0
- package/src/compute-view/element-view/utils.ts +59 -0
- package/src/compute-view/index.ts +3 -4
- package/src/compute-view/memory/AbstractMemory.ts +45 -0
- package/src/compute-view/memory/AbstractStageExclude.ts +216 -0
- package/src/compute-view/memory/AbstractStageInclude.ts +200 -0
- package/src/compute-view/memory/_types.ts +147 -0
- package/src/compute-view/memory/index.ts +5 -0
- package/src/compute-view/memory/ops.ts +43 -0
- package/src/compute-view/utils/buildComputedNodes.ts +4 -4
- package/src/compute-view/utils/elementExpressionToPredicate.ts +1 -3
- package/src/compute-view/utils/link-nodes-with-edges.ts +3 -7
- package/src/compute-view/utils/{derive-edge-props-from-relationships.ts → merge-props-from-relationships.ts} +54 -23
- package/src/compute-view/utils/relationExpressionToPredicates.ts +2 -2
- package/src/compute-view/utils/resolve-extended-views.ts +44 -40
- package/src/compute-view/utils/resolve-global-rules.ts +6 -6
- package/src/compute-view/utils/topological-sort.ts +167 -71
- package/src/compute-view/utils/with-readable-edges.ts +14 -9
- package/src/index.ts +22 -16
- package/src/model/DeploymentElementModel.ts +150 -85
- package/src/model/DeploymentModel.ts +27 -21
- package/src/model/ElementModel.ts +51 -25
- package/src/model/LikeC4Model.test-d.ts +4 -3
- package/src/model/LikeC4Model.ts +98 -42
- package/src/model/RelationModel.ts +5 -4
- package/src/model/__test__/fixture.ts +5 -9
- package/src/model/connection/Connection.ts +72 -0
- package/src/model/connection/deployment/DeploymentConnectionModel.ts +178 -0
- package/src/model/connection/{deployment.ts → deployment/find.ts} +14 -18
- package/src/model/connection/deployment/index.ts +8 -0
- package/src/model/connection/index.ts +22 -0
- package/src/model/connection/model/ConnectionModel.ts +157 -0
- package/src/model/connection/{model.ts → model/find.ts} +43 -49
- package/src/model/connection/model/index.ts +8 -0
- package/src/model/connection/ops.ts +274 -0
- package/src/model/guards.ts +9 -0
- package/src/model/index.ts +45 -3
- package/src/model/types.ts +35 -18
- package/src/model/view/EdgeModel.ts +6 -6
- package/src/model/view/LikeC4ViewModel.ts +14 -8
- package/src/model/view/NodeModel.ts +6 -5
- package/src/types/_common.ts +53 -1
- package/src/types/deployments.ts +88 -156
- package/src/types/element.ts +2 -2
- package/src/types/expression-v2.ts +172 -0
- package/src/types/expression.ts +9 -5
- package/src/types/global.ts +3 -3
- package/src/types/index.ts +220 -13
- package/src/types/model.ts +28 -24
- package/src/types/operators.ts +1 -1
- package/src/types/relation.ts +14 -10
- package/src/types/theme.ts +0 -1
- package/src/types/view.ts +20 -18
- package/src/utils/const.ts +1 -0
- package/src/utils/fqn.ts +140 -49
- package/src/utils/getOrCreate.ts +1 -1
- package/src/utils/index.ts +74 -9
- package/src/utils/iterable/_types.ts +5 -0
- package/src/utils/iterable/filter.ts +55 -0
- package/src/utils/iterable/flat.ts +17 -0
- package/src/utils/iterable/index.ts +12 -0
- package/src/utils/iterable/map.ts +40 -0
- package/src/utils/iterable/reduce.ts +24 -0
- package/src/utils/iterable/some.ts +36 -0
- package/src/utils/iterable/to.ts +19 -0
- package/src/utils/iterable/unique.ts +29 -0
- package/src/utils/relations.ts +3 -64
- package/src/utils/set.ts +11 -9
- package/src/utils/string-hash.ts +1 -1
- package/dist/compute-view/index.mjs +0 -79
- package/dist/model/index.mjs +0 -2
- package/dist/shared/core.BBgiAAv1.mjs +0 -144
- package/dist/shared/core.BPyJvuMU.mjs +0 -2420
- package/dist/shared/core.BQ4AbfvB.mjs +0 -9228
- package/dist/shared/core.k12s_keD.mjs +0 -203
- package/dist/types/index.mjs +0 -21
- package/src/builder/Builder.test-d.ts +0 -124
- package/src/builder/Builder.view.ts +0 -543
- package/src/compute-view/LikeC4ModelGraph.ts +0 -330
- package/src/compute-view/deployment-view/Memory.ts +0 -108
- package/src/compute-view/deployment-view/Stage.ts +0 -145
- package/src/compute-view/deployment-view/predicates/deployment-ref.ts +0 -146
- package/src/compute-view/element-view/predicates.ts +0 -517
- package/src/compute-view/utils/sortNodes.ts +0 -101
- package/src/model/connection/ConnectionModel.ts +0 -94
- package/src/model/connection/DeploymentConnectionModel.ts +0 -99
package/src/builder/Builder.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import defu from 'defu'
|
|
2
|
-
import { fromEntries, hasAtLeast, isFunction, isNonNullish, map, mapToObj, mapValues, pickBy } from 'remeda'
|
|
2
|
+
import { fromEntries, hasAtLeast, isFunction, isNonNullish, isNullish, map, mapToObj, mapValues, pickBy } from 'remeda'
|
|
3
3
|
import type { Writable } from 'type-fest'
|
|
4
|
-
import { computeViews } from '../compute-view'
|
|
5
4
|
import { invariant } from '../errors'
|
|
6
5
|
import { LikeC4Model } from '../model/LikeC4Model'
|
|
7
6
|
import {
|
|
@@ -20,32 +19,29 @@ import {
|
|
|
20
19
|
type LikeC4View,
|
|
21
20
|
type Link,
|
|
22
21
|
type ModelGlobals,
|
|
22
|
+
type ModelRelation,
|
|
23
23
|
type NonEmptyArray,
|
|
24
|
-
type Relation,
|
|
25
24
|
type RelationId,
|
|
26
|
-
type Tag
|
|
25
|
+
type Tag,
|
|
27
26
|
} from '../types'
|
|
28
|
-
import type { ParsedLikeC4Model } from '../types/model'
|
|
29
27
|
import { isSameHierarchy, nameFromFqn, parentFqn } from '../utils/fqn'
|
|
30
28
|
import type { AnyTypes, BuilderSpecification, Types } from './_types'
|
|
31
29
|
import type { AddDeploymentNode } from './Builder.deployment'
|
|
32
|
-
import type {
|
|
30
|
+
import type {
|
|
31
|
+
AddDeploymentNodeHelpers,
|
|
32
|
+
DeloymentModelBuildFunction,
|
|
33
|
+
DeloymentModelHelpers,
|
|
34
|
+
DeploymentModelBuilder,
|
|
35
|
+
} from './Builder.deploymentModel'
|
|
33
36
|
import type { AddElement } from './Builder.element'
|
|
34
|
-
import type { AddElementHelpers, ModelBuilder, ModelHelpers } from './Builder.model'
|
|
35
|
-
import {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
mkViewBuilder,
|
|
43
|
-
type ViewHelpers,
|
|
44
|
-
type ViewRuleBuilderOp
|
|
45
|
-
} from './Builder.view'
|
|
46
|
-
import { type ViewsBuilder } from './Builder.views'
|
|
47
|
-
|
|
48
|
-
export interface Builder<T extends AnyTypes> {
|
|
37
|
+
import type { AddElementHelpers, ModelBuilder, ModelBuilderFunction, ModelHelpers } from './Builder.model'
|
|
38
|
+
import { $autoLayout, $exclude, $include, $rules, $style } from './Builder.view-common'
|
|
39
|
+
import type { DeploymentRulesBuilderOp } from './Builder.view-deployment'
|
|
40
|
+
import type { ElementViewRulesBuilder } from './Builder.view-element'
|
|
41
|
+
import { mkViewBuilder, type ViewsBuilder, type ViewsBuilderFunction, type ViewsHelpers } from './Builder.views'
|
|
42
|
+
import type { BuilderMethods } from './Builder.with'
|
|
43
|
+
|
|
44
|
+
export interface Builder<T extends AnyTypes> extends BuilderMethods<T> {
|
|
49
45
|
/**
|
|
50
46
|
* Only available in compile time
|
|
51
47
|
*/
|
|
@@ -58,211 +54,120 @@ export interface Builder<T extends AnyTypes> {
|
|
|
58
54
|
*/
|
|
59
55
|
helpers(): {
|
|
60
56
|
model: ModelHelpers<T>
|
|
61
|
-
views:
|
|
57
|
+
views: ViewsHelpers
|
|
62
58
|
deployment: DeloymentModelHelpers<T>
|
|
63
59
|
}
|
|
64
60
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Adds model elements
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* builder.model(({ el }, _) =>
|
|
66
|
+
* _(
|
|
67
|
+
* el('a'),
|
|
68
|
+
* el('a.b').with(
|
|
69
|
+
* el('c')
|
|
70
|
+
* )
|
|
71
|
+
* )
|
|
72
|
+
* )
|
|
73
|
+
*
|
|
74
|
+
* builder.model((_, m) =>
|
|
75
|
+
* m(
|
|
76
|
+
* _.el('a'),
|
|
77
|
+
* _.el('a.b').with(
|
|
78
|
+
* _.el('c')
|
|
79
|
+
* )
|
|
80
|
+
* )
|
|
81
|
+
* )
|
|
82
|
+
*/
|
|
83
|
+
model<Out extends AnyTypes>(
|
|
84
|
+
callback: ModelBuilderFunction<T, Out>,
|
|
85
|
+
): Builder<Out>
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Adds deployment model
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* builder.deployment(({ node, instanceOf }, _) =>
|
|
92
|
+
* _(
|
|
93
|
+
* node('node1'),
|
|
94
|
+
* node('node1.child1').with(
|
|
95
|
+
* instanceOf('model.element')
|
|
96
|
+
* )
|
|
97
|
+
* )
|
|
98
|
+
* )
|
|
99
|
+
*
|
|
100
|
+
* builder.deployment((_,d) =>
|
|
101
|
+
* d(
|
|
102
|
+
* _.node('node1'),
|
|
103
|
+
* _.node('node1.child1').with(
|
|
104
|
+
* _.instanceOf('model.element')
|
|
105
|
+
* )
|
|
106
|
+
* )
|
|
107
|
+
* )
|
|
108
|
+
*/
|
|
109
|
+
deployment<Out extends AnyTypes>(
|
|
110
|
+
callback: DeloymentModelBuildFunction<T, Out>,
|
|
111
|
+
): Builder<Out>
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Adds views
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* builder.views(({ view, $include }, _) =>
|
|
118
|
+
* _(
|
|
119
|
+
* view('index').with(
|
|
120
|
+
* $include('a -> b')
|
|
121
|
+
* )
|
|
122
|
+
* )
|
|
123
|
+
* )
|
|
124
|
+
*/
|
|
125
|
+
views<Out extends AnyTypes>(
|
|
126
|
+
callback: ViewsBuilderFunction<T, Out>,
|
|
127
|
+
): Builder<Out>
|
|
68
128
|
|
|
69
129
|
/**
|
|
70
130
|
* Returns model as result of parsing only
|
|
71
|
-
*
|
|
131
|
+
* Views are not computed or layouted
|
|
132
|
+
* {@link toLikeC4Model} should be used to get model with computed views
|
|
72
133
|
*/
|
|
73
|
-
build():
|
|
74
|
-
T['ElementKind'],
|
|
75
|
-
T['RelationshipKind'],
|
|
76
|
-
T['Tag'],
|
|
77
|
-
T['Fqn'],
|
|
78
|
-
T['ViewId'],
|
|
79
|
-
T['DeploymentFqn']
|
|
80
|
-
>
|
|
134
|
+
build(): Types.ToParsedLikeC4Model<T>
|
|
81
135
|
|
|
82
136
|
/**
|
|
83
|
-
* Returns
|
|
137
|
+
* Returns LikeC4Model with computed views
|
|
84
138
|
*/
|
|
85
|
-
|
|
86
|
-
T['Fqn'],
|
|
87
|
-
T['DeploymentFqn'],
|
|
88
|
-
T['ViewId']
|
|
89
|
-
>
|
|
90
|
-
|
|
91
|
-
with<
|
|
92
|
-
A extends AnyTypes
|
|
93
|
-
>(
|
|
94
|
-
op1: (input: Builder<T>) => Builder<A>
|
|
95
|
-
): Builder<A>
|
|
96
|
-
|
|
97
|
-
with<
|
|
98
|
-
A extends AnyTypes,
|
|
99
|
-
B extends AnyTypes
|
|
100
|
-
>(
|
|
101
|
-
op1: (input: Builder<T>) => Builder<A>,
|
|
102
|
-
op2: (input: Builder<A>) => Builder<B>
|
|
103
|
-
): Builder<B>
|
|
104
|
-
|
|
105
|
-
with<
|
|
106
|
-
A extends AnyTypes,
|
|
107
|
-
B extends AnyTypes,
|
|
108
|
-
C extends AnyTypes
|
|
109
|
-
>(
|
|
110
|
-
op1: (input: Builder<T>) => Builder<A>,
|
|
111
|
-
op2: (input: Builder<A>) => Builder<B>,
|
|
112
|
-
op3: (input: Builder<B>) => Builder<C>
|
|
113
|
-
): Builder<C>
|
|
114
|
-
|
|
115
|
-
with<
|
|
116
|
-
A extends AnyTypes,
|
|
117
|
-
B extends AnyTypes,
|
|
118
|
-
C extends AnyTypes,
|
|
119
|
-
D extends AnyTypes
|
|
120
|
-
>(
|
|
121
|
-
op1: (input: Builder<T>) => Builder<A>,
|
|
122
|
-
op2: (input: Builder<A>) => Builder<B>,
|
|
123
|
-
op3: (input: Builder<B>) => Builder<C>,
|
|
124
|
-
op4: (input: Builder<C>) => Builder<D>
|
|
125
|
-
): Builder<D>
|
|
126
|
-
|
|
127
|
-
with<
|
|
128
|
-
A extends AnyTypes,
|
|
129
|
-
B extends AnyTypes,
|
|
130
|
-
C extends AnyTypes,
|
|
131
|
-
D extends AnyTypes,
|
|
132
|
-
E extends AnyTypes
|
|
133
|
-
>(
|
|
134
|
-
op1: (input: Builder<T>) => Builder<A>,
|
|
135
|
-
op2: (input: Builder<A>) => Builder<B>,
|
|
136
|
-
op3: (input: Builder<B>) => Builder<C>,
|
|
137
|
-
op4: (input: Builder<C>) => Builder<D>,
|
|
138
|
-
op5: (input: Builder<D>) => Builder<E>
|
|
139
|
-
): Builder<E>
|
|
140
|
-
|
|
141
|
-
with<
|
|
142
|
-
A extends AnyTypes,
|
|
143
|
-
B extends AnyTypes,
|
|
144
|
-
C extends AnyTypes,
|
|
145
|
-
D extends AnyTypes,
|
|
146
|
-
E extends AnyTypes,
|
|
147
|
-
F extends AnyTypes
|
|
148
|
-
>(
|
|
149
|
-
op1: (input: Builder<T>) => Builder<A>,
|
|
150
|
-
op2: (input: Builder<A>) => Builder<B>,
|
|
151
|
-
op3: (input: Builder<B>) => Builder<C>,
|
|
152
|
-
op4: (input: Builder<C>) => Builder<D>,
|
|
153
|
-
op5: (input: Builder<D>) => Builder<E>,
|
|
154
|
-
op6: (input: Builder<E>) => Builder<F>
|
|
155
|
-
): Builder<F>
|
|
156
|
-
|
|
157
|
-
with<
|
|
158
|
-
A extends AnyTypes,
|
|
159
|
-
B extends AnyTypes,
|
|
160
|
-
C extends AnyTypes,
|
|
161
|
-
D extends AnyTypes,
|
|
162
|
-
E extends AnyTypes,
|
|
163
|
-
F extends AnyTypes,
|
|
164
|
-
G extends AnyTypes
|
|
165
|
-
>(
|
|
166
|
-
op1: (input: Builder<T>) => Builder<A>,
|
|
167
|
-
op2: (input: Builder<A>) => Builder<B>,
|
|
168
|
-
op3: (input: Builder<B>) => Builder<C>,
|
|
169
|
-
op4: (input: Builder<C>) => Builder<D>,
|
|
170
|
-
op5: (input: Builder<D>) => Builder<E>,
|
|
171
|
-
op6: (input: Builder<E>) => Builder<F>,
|
|
172
|
-
op7: (input: Builder<F>) => Builder<G>
|
|
173
|
-
): Builder<G>
|
|
174
|
-
|
|
175
|
-
with<
|
|
176
|
-
A extends AnyTypes,
|
|
177
|
-
B extends AnyTypes,
|
|
178
|
-
C extends AnyTypes,
|
|
179
|
-
D extends AnyTypes,
|
|
180
|
-
E extends AnyTypes,
|
|
181
|
-
F extends AnyTypes,
|
|
182
|
-
G extends AnyTypes,
|
|
183
|
-
H extends AnyTypes
|
|
184
|
-
>(
|
|
185
|
-
op1: (input: Builder<T>) => Builder<A>,
|
|
186
|
-
op2: (input: Builder<A>) => Builder<B>,
|
|
187
|
-
op3: (input: Builder<B>) => Builder<C>,
|
|
188
|
-
op4: (input: Builder<C>) => Builder<D>,
|
|
189
|
-
op5: (input: Builder<D>) => Builder<E>,
|
|
190
|
-
op6: (input: Builder<E>) => Builder<F>,
|
|
191
|
-
op7: (input: Builder<F>) => Builder<G>,
|
|
192
|
-
op8: (input: Builder<G>) => Builder<H>
|
|
193
|
-
): Builder<H>
|
|
194
|
-
|
|
195
|
-
with<
|
|
196
|
-
A extends AnyTypes,
|
|
197
|
-
B extends AnyTypes,
|
|
198
|
-
C extends AnyTypes,
|
|
199
|
-
D extends AnyTypes,
|
|
200
|
-
E extends AnyTypes,
|
|
201
|
-
F extends AnyTypes,
|
|
202
|
-
G extends AnyTypes,
|
|
203
|
-
H extends AnyTypes,
|
|
204
|
-
I extends AnyTypes
|
|
205
|
-
>(
|
|
206
|
-
op1: (input: Builder<T>) => Builder<A>,
|
|
207
|
-
op2: (input: Builder<A>) => Builder<B>,
|
|
208
|
-
op3: (input: Builder<B>) => Builder<C>,
|
|
209
|
-
op4: (input: Builder<C>) => Builder<D>,
|
|
210
|
-
op5: (input: Builder<D>) => Builder<E>,
|
|
211
|
-
op6: (input: Builder<E>) => Builder<F>,
|
|
212
|
-
op7: (input: Builder<F>) => Builder<G>,
|
|
213
|
-
op8: (input: Builder<G>) => Builder<H>,
|
|
214
|
-
op9: (input: Builder<H>) => Builder<I>
|
|
215
|
-
): Builder<I>
|
|
216
|
-
|
|
217
|
-
with<
|
|
218
|
-
A extends AnyTypes,
|
|
219
|
-
B extends AnyTypes,
|
|
220
|
-
C extends AnyTypes,
|
|
221
|
-
D extends AnyTypes,
|
|
222
|
-
E extends AnyTypes,
|
|
223
|
-
F extends AnyTypes,
|
|
224
|
-
G extends AnyTypes,
|
|
225
|
-
H extends AnyTypes,
|
|
226
|
-
I extends AnyTypes,
|
|
227
|
-
J extends AnyTypes
|
|
228
|
-
>(
|
|
229
|
-
op1: (input: Builder<T>) => Builder<A>,
|
|
230
|
-
op2: (input: Builder<A>) => Builder<B>,
|
|
231
|
-
op3: (input: Builder<B>) => Builder<C>,
|
|
232
|
-
op4: (input: Builder<C>) => Builder<D>,
|
|
233
|
-
op5: (input: Builder<D>) => Builder<E>,
|
|
234
|
-
op6: (input: Builder<E>) => Builder<F>,
|
|
235
|
-
op7: (input: Builder<F>) => Builder<G>,
|
|
236
|
-
op8: (input: Builder<G>) => Builder<H>,
|
|
237
|
-
op9: (input: Builder<H>) => Builder<I>,
|
|
238
|
-
op10: (input: Builder<I>) => Builder<J>
|
|
239
|
-
): Builder<J>
|
|
139
|
+
toLikeC4Model(): Types.ToLikeC4Model<T>
|
|
240
140
|
}
|
|
241
141
|
|
|
142
|
+
interface Internals<T extends AnyTypes> extends ViewsBuilder<T>, ModelBuilder<T>, DeploymentModelBuilder<T> {
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
type Op<T> = (b: T) => T
|
|
146
|
+
|
|
242
147
|
function builder<Spec extends BuilderSpecification, T extends AnyTypes>(
|
|
243
148
|
spec: Spec,
|
|
244
149
|
_elements = new Map<string, Element>(),
|
|
245
|
-
_relations = [] as
|
|
150
|
+
_relations = [] as ModelRelation[],
|
|
246
151
|
_views = new Map<string, LikeC4View>(),
|
|
247
152
|
_globals = {
|
|
248
153
|
predicates: {},
|
|
249
154
|
dynamicPredicates: {},
|
|
250
|
-
styles: {}
|
|
155
|
+
styles: {},
|
|
251
156
|
} as ModelGlobals,
|
|
252
157
|
_deployments = new Map<string, DeploymentElement>(),
|
|
253
|
-
_deploymentRelations = [] as DeploymentRelation[]
|
|
158
|
+
_deploymentRelations = [] as DeploymentRelation[],
|
|
254
159
|
): Builder<T> {
|
|
255
160
|
const toLikeC4Specification = (): Types.ToParsedLikeC4Model<T>['specification'] => ({
|
|
256
161
|
elements: {
|
|
257
|
-
...spec.elements as any
|
|
162
|
+
...structuredClone(spec.elements) as any,
|
|
258
163
|
},
|
|
259
164
|
deployments: {
|
|
260
|
-
...spec.deployments as any
|
|
165
|
+
...structuredClone(spec.deployments) as any,
|
|
261
166
|
},
|
|
262
167
|
relationships: {
|
|
263
|
-
...spec.relationships
|
|
168
|
+
...structuredClone(spec.relationships) as any,
|
|
264
169
|
},
|
|
265
|
-
tags: (spec.tags ?? []) as Tag<T['Tag']>[]
|
|
170
|
+
tags: (spec.tags ?? []) as Tag<T['Tag']>[],
|
|
266
171
|
})
|
|
267
172
|
|
|
268
173
|
const mapLinks = (links?: Array<string | { title?: string; url: string }>): NonEmptyArray<Link> | null => {
|
|
@@ -272,7 +177,37 @@ function builder<Spec extends BuilderSpecification, T extends AnyTypes>(
|
|
|
272
177
|
return map(links, l => (typeof l === 'string' ? { url: l } : l))
|
|
273
178
|
}
|
|
274
179
|
|
|
275
|
-
const
|
|
180
|
+
const createGenericView = <B extends Op<any> | undefined>(
|
|
181
|
+
id: string,
|
|
182
|
+
_props: T['NewViewProps'] | string | B | null,
|
|
183
|
+
builder: B,
|
|
184
|
+
): [Omit<LikeC4View, 'rules'>, B] => {
|
|
185
|
+
if (isFunction(_props)) {
|
|
186
|
+
builder = _props as B
|
|
187
|
+
_props = {}
|
|
188
|
+
}
|
|
189
|
+
_props ??= {}
|
|
190
|
+
const {
|
|
191
|
+
links: _links = [],
|
|
192
|
+
title = null,
|
|
193
|
+
description = null,
|
|
194
|
+
tags = null,
|
|
195
|
+
...props
|
|
196
|
+
} = typeof _props === 'string' ? { title: _props } : { ..._props }
|
|
197
|
+
|
|
198
|
+
const links = mapLinks(_links)
|
|
199
|
+
return [{
|
|
200
|
+
id: id as any,
|
|
201
|
+
title,
|
|
202
|
+
description,
|
|
203
|
+
tags,
|
|
204
|
+
links,
|
|
205
|
+
customColorDefinitions: {},
|
|
206
|
+
...props,
|
|
207
|
+
}, builder]
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const self: Builder<T> & Internals<T> = {
|
|
276
211
|
get Types(): T {
|
|
277
212
|
throw new Error('Types are not available in runtime')
|
|
278
213
|
},
|
|
@@ -284,114 +219,137 @@ function builder<Spec extends BuilderSpecification, T extends AnyTypes>(
|
|
|
284
219
|
structuredClone(_views),
|
|
285
220
|
structuredClone(_globals),
|
|
286
221
|
structuredClone(_deployments),
|
|
287
|
-
structuredClone(_deploymentRelations)
|
|
222
|
+
structuredClone(_deploymentRelations),
|
|
288
223
|
)
|
|
289
224
|
},
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
invariant(
|
|
295
|
-
_elements.get(parent),
|
|
296
|
-
`Parent element with id "${parent}" not found for element with id "${element.id}"`
|
|
297
|
-
)
|
|
298
|
-
}
|
|
299
|
-
if (_elements.has(element.id)) {
|
|
300
|
-
throw new Error(`Element with id "${element.id}" already exists`)
|
|
301
|
-
}
|
|
302
|
-
_elements.set(element.id, element)
|
|
303
|
-
return self
|
|
304
|
-
},
|
|
305
|
-
addRelation(relation) {
|
|
306
|
-
const sourceEl = _elements.get(relation.source)
|
|
307
|
-
invariant(sourceEl, `Element with id "${relation.source}" not found`)
|
|
308
|
-
const targetEl = _elements.get(relation.target)
|
|
309
|
-
invariant(targetEl, `Element with id "${relation.target}" not found`)
|
|
225
|
+
|
|
226
|
+
__addElement: (element) => {
|
|
227
|
+
const parent = parentFqn(element.id)
|
|
228
|
+
if (parent) {
|
|
310
229
|
invariant(
|
|
311
|
-
|
|
312
|
-
|
|
230
|
+
_elements.get(parent),
|
|
231
|
+
`Parent element with id "${parent}" not found for element with id "${element.id}"`,
|
|
313
232
|
)
|
|
314
|
-
_relations.push({
|
|
315
|
-
id: `rel${_relations.length + 1}` as RelationId,
|
|
316
|
-
...relation
|
|
317
|
-
})
|
|
318
|
-
return self
|
|
319
|
-
},
|
|
320
|
-
/**
|
|
321
|
-
* Fully qualified name for nested elements
|
|
322
|
-
*/
|
|
323
|
-
fqn(id) {
|
|
324
|
-
return id as Fqn
|
|
325
|
-
},
|
|
326
|
-
addSourcelessRelation() {
|
|
327
|
-
throw new Error('Can be called only in nested model')
|
|
328
233
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
addView: (view) => {
|
|
332
|
-
if (isScopedElementView(view)) {
|
|
333
|
-
invariant(_elements.get(view.viewOf), `Invalid view ${view.id}, wlement with id "${view.viewOf}" not found`)
|
|
334
|
-
}
|
|
335
|
-
_views.set(view.id, view)
|
|
336
|
-
return self
|
|
234
|
+
if (_elements.has(element.id)) {
|
|
235
|
+
throw new Error(`Element with id "${element.id}" already exists`)
|
|
337
236
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
237
|
+
_elements.set(element.id, element)
|
|
238
|
+
return self
|
|
239
|
+
},
|
|
240
|
+
__addRelation(relation) {
|
|
241
|
+
const sourceEl = _elements.get(relation.source)
|
|
242
|
+
invariant(sourceEl, `Element with id "${relation.source}" not found`)
|
|
243
|
+
const targetEl = _elements.get(relation.target)
|
|
244
|
+
invariant(targetEl, `Element with id "${relation.target}" not found`)
|
|
245
|
+
invariant(
|
|
246
|
+
!isSameHierarchy(sourceEl, targetEl),
|
|
247
|
+
'Cannot create relationship between elements in the same hierarchy',
|
|
248
|
+
)
|
|
249
|
+
_relations.push({
|
|
250
|
+
id: `rel${_relations.length + 1}` as RelationId,
|
|
251
|
+
...relation,
|
|
252
|
+
})
|
|
253
|
+
return self
|
|
254
|
+
},
|
|
255
|
+
/**
|
|
256
|
+
* Fully qualified name for nested elements
|
|
257
|
+
*/
|
|
258
|
+
__fqn(id) {
|
|
259
|
+
invariant(id.trim() !== '', 'Id must be non-empty')
|
|
260
|
+
return id as Fqn
|
|
261
|
+
},
|
|
262
|
+
__addSourcelessRelation() {
|
|
263
|
+
throw new Error('Can be called only in nested model')
|
|
264
|
+
},
|
|
265
|
+
__addView: (view) => {
|
|
266
|
+
if (_views.has(view.id)) {
|
|
267
|
+
throw new Error(`View with id "${view.id}" already exists`)
|
|
268
|
+
}
|
|
269
|
+
if (isScopedElementView(view)) {
|
|
358
270
|
invariant(
|
|
359
|
-
|
|
360
|
-
|
|
271
|
+
_elements.get(view.viewOf),
|
|
272
|
+
`Invalid scoped view ${view.id}, wlement with id "${view.viewOf}" not found`,
|
|
361
273
|
)
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
274
|
+
}
|
|
275
|
+
_views.set(view.id, view)
|
|
276
|
+
return self
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
__addDeployment: (node: DeploymentElement) => {
|
|
280
|
+
if (_deployments.has(node.id)) {
|
|
281
|
+
throw new Error(`Deployment with id "${node.id}" already exists`)
|
|
282
|
+
}
|
|
283
|
+
const parent = parentFqn(node.id)
|
|
284
|
+
if (parent) {
|
|
285
|
+
invariant(
|
|
286
|
+
_deployments.get(parent),
|
|
287
|
+
`Parent element with id "${parent}" not found for node with id "${node.id}"`,
|
|
288
|
+
)
|
|
289
|
+
}
|
|
290
|
+
if (DeploymentElement.isInstance(node)) {
|
|
291
|
+
invariant(parent, `Instance ${node.id} of ${node.element} must be deployed under a parent node`)
|
|
292
|
+
invariant(
|
|
293
|
+
_elements.get(node.element),
|
|
294
|
+
`Instance "${node.id}" references non-existing element "${node.element}"`,
|
|
295
|
+
)
|
|
296
|
+
}
|
|
297
|
+
_deployments.set(node.id, node)
|
|
298
|
+
return self
|
|
299
|
+
},
|
|
300
|
+
__addDeploymentRelation: (relation) => {
|
|
301
|
+
invariant(
|
|
302
|
+
!isSameHierarchy(relation.source.id, relation.target.id),
|
|
303
|
+
'Cannot create relationship between elements in the same hierarchy',
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
invariant(
|
|
307
|
+
_deployments.has(relation.source.id),
|
|
308
|
+
`Relation "${relation.source.id} -> ${relation.target.id}" references non-existing source`,
|
|
309
|
+
)
|
|
310
|
+
invariant(
|
|
311
|
+
_deployments.has(relation.target.id),
|
|
312
|
+
`Relation "${relation.source.id} -> ${relation.target.id}" references non-existing target`,
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
_deploymentRelations.push({
|
|
316
|
+
id: `deploy_rel${_deploymentRelations.length + 1}` as RelationId,
|
|
317
|
+
...relation,
|
|
318
|
+
})
|
|
319
|
+
return self
|
|
320
|
+
},
|
|
370
321
|
build: () => ({
|
|
371
322
|
specification: toLikeC4Specification(),
|
|
372
|
-
elements: fromEntries(
|
|
373
|
-
|
|
323
|
+
elements: fromEntries(
|
|
324
|
+
structuredClone(
|
|
325
|
+
Array.from(_elements.entries()),
|
|
326
|
+
),
|
|
327
|
+
),
|
|
328
|
+
relations: mapToObj(_relations, r => [r.id, structuredClone(r)]),
|
|
374
329
|
globals: structuredClone(_globals),
|
|
375
330
|
deployments: {
|
|
376
|
-
elements: fromEntries(
|
|
377
|
-
|
|
331
|
+
elements: fromEntries(
|
|
332
|
+
structuredClone(
|
|
333
|
+
Array.from(_deployments.entries()),
|
|
334
|
+
),
|
|
335
|
+
),
|
|
336
|
+
relations: mapToObj(_deploymentRelations, r => [r.id, structuredClone(r)]),
|
|
378
337
|
},
|
|
379
|
-
views: fromEntries(
|
|
380
|
-
|
|
381
|
-
|
|
338
|
+
views: fromEntries(
|
|
339
|
+
structuredClone(
|
|
340
|
+
Array.from(_views.entries()),
|
|
341
|
+
),
|
|
342
|
+
),
|
|
343
|
+
} as any),
|
|
344
|
+
toLikeC4Model: () => {
|
|
382
345
|
const parsed = self.build()
|
|
383
|
-
|
|
384
|
-
return LikeC4Model.create(computed)
|
|
346
|
+
return LikeC4Model.compute(parsed)
|
|
385
347
|
},
|
|
386
348
|
helpers: () => ({
|
|
387
349
|
model: {
|
|
388
350
|
model: (...ops: ((b: ModelBuilder<T>) => ModelBuilder<T>)[]) => {
|
|
389
351
|
return (b: Builder<T>) => {
|
|
390
|
-
|
|
391
|
-
for (const op of ops) {
|
|
392
|
-
op(v)
|
|
393
|
-
}
|
|
394
|
-
return b
|
|
352
|
+
return ops.reduce((b, op) => op(b), b as any as ModelBuilder<T>) as any
|
|
395
353
|
}
|
|
396
354
|
},
|
|
397
355
|
rel: (source: string, target: string, _props?: T['NewRelationshipProps'] | string) => {
|
|
@@ -402,15 +360,15 @@ function builder<Spec extends BuilderSpecification, T extends AnyTypes>(
|
|
|
402
360
|
...props
|
|
403
361
|
} = defu(
|
|
404
362
|
typeof _props === 'string' ? { title: _props } : { ..._props },
|
|
405
|
-
{ title: null, links: null }
|
|
363
|
+
{ title: null, links: null },
|
|
406
364
|
)
|
|
407
365
|
const links = mapLinks(_links)
|
|
408
|
-
b.
|
|
366
|
+
b.__addRelation({
|
|
409
367
|
source: source as any,
|
|
410
368
|
target: target as any,
|
|
411
369
|
title,
|
|
412
370
|
...(links && { links }),
|
|
413
|
-
...props
|
|
371
|
+
...props,
|
|
414
372
|
})
|
|
415
373
|
return b
|
|
416
374
|
}
|
|
@@ -423,14 +381,14 @@ function builder<Spec extends BuilderSpecification, T extends AnyTypes>(
|
|
|
423
381
|
...props
|
|
424
382
|
} = defu(
|
|
425
383
|
typeof _props === 'string' ? { title: _props } : { ..._props },
|
|
426
|
-
{ title: null, links: null }
|
|
384
|
+
{ title: null, links: null },
|
|
427
385
|
)
|
|
428
386
|
const links = mapLinks(_links)
|
|
429
|
-
b.
|
|
387
|
+
b.__addSourcelessRelation({
|
|
430
388
|
target,
|
|
431
389
|
title,
|
|
432
390
|
...(links && { links }),
|
|
433
|
-
...props
|
|
391
|
+
...props,
|
|
434
392
|
})
|
|
435
393
|
return b
|
|
436
394
|
}
|
|
@@ -440,7 +398,7 @@ function builder<Spec extends BuilderSpecification, T extends AnyTypes>(
|
|
|
440
398
|
({ style: specStyle, ...spec }, kind) =>
|
|
441
399
|
<Id extends string>(
|
|
442
400
|
id: Id,
|
|
443
|
-
_props?: T['NewElementProps'] | string
|
|
401
|
+
_props?: T['NewElementProps'] | string,
|
|
444
402
|
): AddElement<Id> => {
|
|
445
403
|
const add = (<T extends AnyTypes>(b: ModelBuilder<T>) => {
|
|
446
404
|
const {
|
|
@@ -455,9 +413,9 @@ function builder<Spec extends BuilderSpecification, T extends AnyTypes>(
|
|
|
455
413
|
|
|
456
414
|
const icon = _icon ?? specStyle?.icon
|
|
457
415
|
|
|
458
|
-
const _id = b.
|
|
416
|
+
const _id = b.__fqn(id)
|
|
459
417
|
|
|
460
|
-
b.
|
|
418
|
+
b.__addElement({
|
|
461
419
|
id: _id,
|
|
462
420
|
kind: kind as any,
|
|
463
421
|
title: title ?? nameFromFqn(_id),
|
|
@@ -469,192 +427,183 @@ function builder<Spec extends BuilderSpecification, T extends AnyTypes>(
|
|
|
469
427
|
style: pickBy({
|
|
470
428
|
border: specStyle?.border,
|
|
471
429
|
opacity: specStyle?.opacity,
|
|
472
|
-
...style
|
|
430
|
+
...style,
|
|
473
431
|
}, isNonNullish),
|
|
474
432
|
links,
|
|
475
433
|
...icon && { icon: icon as IconUrl },
|
|
476
434
|
...spec,
|
|
477
|
-
...props
|
|
435
|
+
...props,
|
|
478
436
|
})
|
|
479
437
|
return b
|
|
480
438
|
}) as AddElement<Id>
|
|
481
439
|
|
|
482
440
|
add.with = (...ops: Array<(input: ModelBuilder<any>) => ModelBuilder<any>>) => (b: ModelBuilder<any>) => {
|
|
483
441
|
add(b)
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
return b.
|
|
442
|
+
const { __fqn, __addSourcelessRelation } = b
|
|
443
|
+
try {
|
|
444
|
+
b.__fqn = (child) => `${__fqn(id)}.${child}` as Fqn
|
|
445
|
+
b.__addSourcelessRelation = (relation) => {
|
|
446
|
+
return b.__addRelation({
|
|
489
447
|
...relation,
|
|
490
|
-
source:
|
|
448
|
+
source: __fqn(id),
|
|
491
449
|
})
|
|
492
450
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
451
|
+
ops.reduce((b, op) => op(b), b as any as ModelBuilder<T>) as any
|
|
452
|
+
} finally {
|
|
453
|
+
b.__fqn = __fqn
|
|
454
|
+
b.__addSourcelessRelation = __addSourcelessRelation
|
|
496
455
|
}
|
|
497
456
|
return b
|
|
498
457
|
}
|
|
458
|
+
|
|
499
459
|
return add
|
|
500
|
-
}
|
|
501
|
-
) as AddElementHelpers<T
|
|
460
|
+
},
|
|
461
|
+
) as AddElementHelpers<T>,
|
|
502
462
|
},
|
|
503
463
|
views: {
|
|
504
464
|
views: (...ops: ((b: ViewsBuilder<T>) => ViewsBuilder<T>)[]) => {
|
|
505
465
|
return (b: Builder<T>) => {
|
|
506
|
-
|
|
507
|
-
for (const op of ops) {
|
|
508
|
-
op(v)
|
|
509
|
-
}
|
|
510
|
-
return b
|
|
466
|
+
return ops.reduce((b, op) => op(b), b as any as ViewsBuilder<T>) as any
|
|
511
467
|
}
|
|
512
468
|
},
|
|
513
|
-
view: (
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
469
|
+
view: (
|
|
470
|
+
id: string,
|
|
471
|
+
_props?: T['NewViewProps'] | string | ElementViewRulesBuilder<any>,
|
|
472
|
+
_builder?: ElementViewRulesBuilder<any>,
|
|
473
|
+
) => {
|
|
474
|
+
const [generic, builder] = createGenericView(id, _props, _builder)
|
|
475
|
+
const view: Writable<ElementView> = {
|
|
476
|
+
...generic,
|
|
477
|
+
__: 'element',
|
|
478
|
+
rules: [],
|
|
517
479
|
}
|
|
518
|
-
return <T extends AnyTypes>(b: ViewsBuilder<T>): ViewsBuilder<T> => {
|
|
519
|
-
const {
|
|
520
|
-
links: _links = [],
|
|
521
|
-
title = null,
|
|
522
|
-
...props
|
|
523
|
-
} = typeof _props === 'string' ? { title: _props } : { ..._props }
|
|
524
|
-
|
|
525
|
-
const links = mapLinks(_links)
|
|
526
|
-
|
|
527
|
-
const view: Writable<ElementView> = {
|
|
528
|
-
id: id as any,
|
|
529
|
-
__: 'element',
|
|
530
|
-
title,
|
|
531
|
-
description: null,
|
|
532
|
-
tags: null,
|
|
533
|
-
rules: [],
|
|
534
|
-
links,
|
|
535
|
-
customColorDefinitions: {},
|
|
536
|
-
...props
|
|
537
|
-
}
|
|
538
|
-
b.addView(view)
|
|
539
480
|
|
|
481
|
+
const add = (b: ViewsBuilder<any>): ViewsBuilder<any> => {
|
|
482
|
+
b.__addView(view)
|
|
540
483
|
if (builder) {
|
|
541
484
|
builder(mkViewBuilder(view))
|
|
542
485
|
}
|
|
543
|
-
|
|
544
486
|
return b
|
|
545
487
|
}
|
|
488
|
+
add.with = (...ops: ElementViewRulesBuilder<any>[]) => (b: ViewsBuilder<any>) => {
|
|
489
|
+
add(b)
|
|
490
|
+
const elementViewBuilder = mkViewBuilder(view)
|
|
491
|
+
for (const op of ops) {
|
|
492
|
+
op(elementViewBuilder)
|
|
493
|
+
}
|
|
494
|
+
return b
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
return add
|
|
546
498
|
},
|
|
547
499
|
viewOf: (
|
|
548
500
|
id,
|
|
549
|
-
viewOf,
|
|
550
|
-
_props?: T['NewViewProps'] | string |
|
|
551
|
-
|
|
501
|
+
viewOf: string,
|
|
502
|
+
_props?: T['NewViewProps'] | string | ElementViewRulesBuilder<any>,
|
|
503
|
+
_builder?: ElementViewRulesBuilder<any>,
|
|
552
504
|
) => {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
505
|
+
const [generic, builder] = createGenericView(id, _props, _builder)
|
|
506
|
+
const view: Writable<ElementView> = {
|
|
507
|
+
...generic,
|
|
508
|
+
viewOf: viewOf as Fqn,
|
|
509
|
+
__: 'element',
|
|
510
|
+
rules: [],
|
|
556
511
|
}
|
|
557
|
-
return <T extends AnyTypes>(b: ViewsBuilder<T>): ViewsBuilder<T> => {
|
|
558
|
-
const {
|
|
559
|
-
links: _links = [],
|
|
560
|
-
title = null,
|
|
561
|
-
...props
|
|
562
|
-
} = typeof _props === 'string' ? { title: _props } : { ..._props }
|
|
563
|
-
|
|
564
|
-
const links = mapLinks(_links)
|
|
565
|
-
|
|
566
|
-
const view: Writable<ElementView> = {
|
|
567
|
-
id: id as any,
|
|
568
|
-
__: 'element',
|
|
569
|
-
viewOf,
|
|
570
|
-
title,
|
|
571
|
-
description: null,
|
|
572
|
-
tags: null,
|
|
573
|
-
rules: [],
|
|
574
|
-
links,
|
|
575
|
-
customColorDefinitions: {},
|
|
576
|
-
...props
|
|
577
|
-
}
|
|
578
|
-
b.addView(view)
|
|
579
512
|
|
|
513
|
+
const add = (b: ViewsBuilder<any>): ViewsBuilder<any> => {
|
|
514
|
+
b.__addView(view)
|
|
580
515
|
if (builder) {
|
|
581
516
|
builder(mkViewBuilder(view))
|
|
582
517
|
}
|
|
518
|
+
return b
|
|
519
|
+
}
|
|
583
520
|
|
|
521
|
+
add.with = (...ops: ElementViewRulesBuilder<any>[]) => (b: ViewsBuilder<any>) => {
|
|
522
|
+
add(b)
|
|
523
|
+
const elementViewBuilder = mkViewBuilder(view)
|
|
524
|
+
for (const op of ops) {
|
|
525
|
+
op(elementViewBuilder)
|
|
526
|
+
}
|
|
584
527
|
return b
|
|
585
528
|
}
|
|
529
|
+
|
|
530
|
+
return add
|
|
586
531
|
},
|
|
532
|
+
|
|
587
533
|
deploymentView: (
|
|
588
|
-
id,
|
|
589
|
-
_props?: T['NewViewProps'] | string |
|
|
590
|
-
|
|
534
|
+
id: string,
|
|
535
|
+
_props?: T['NewViewProps'] | string | DeploymentRulesBuilderOp<any>,
|
|
536
|
+
_builder?: DeploymentRulesBuilderOp<any>,
|
|
591
537
|
) => {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
538
|
+
const [generic, builder] = createGenericView(id, _props, _builder)
|
|
539
|
+
const view: Writable<DeploymentView> = {
|
|
540
|
+
...generic,
|
|
541
|
+
__: 'deployment',
|
|
542
|
+
rules: [],
|
|
595
543
|
}
|
|
596
|
-
return <T extends AnyTypes>(b: ViewsBuilder<T>): ViewsBuilder<T> => {
|
|
597
|
-
const {
|
|
598
|
-
links: _links = [],
|
|
599
|
-
title = null,
|
|
600
|
-
...props
|
|
601
|
-
} = typeof _props === 'string' ? { title: _props } : { ..._props }
|
|
602
|
-
|
|
603
|
-
const links = mapLinks(_links)
|
|
604
|
-
|
|
605
|
-
const view: Writable<DeploymentView> = {
|
|
606
|
-
id: id as any,
|
|
607
|
-
__: 'deployment',
|
|
608
|
-
title,
|
|
609
|
-
description: null,
|
|
610
|
-
tags: null,
|
|
611
|
-
rules: [],
|
|
612
|
-
links,
|
|
613
|
-
customColorDefinitions: {},
|
|
614
|
-
...props
|
|
615
|
-
}
|
|
616
|
-
b.addView(view)
|
|
617
544
|
|
|
545
|
+
const add = (b: ViewsBuilder<any>): ViewsBuilder<any> => {
|
|
546
|
+
b.__addView(view)
|
|
618
547
|
if (builder) {
|
|
619
548
|
builder(mkViewBuilder(view))
|
|
620
549
|
}
|
|
550
|
+
return b
|
|
551
|
+
}
|
|
621
552
|
|
|
553
|
+
add.with = (...ops: DeploymentRulesBuilderOp<any>[]) => (b: ViewsBuilder<any>) => {
|
|
554
|
+
add(b)
|
|
555
|
+
const elementViewBuilder = mkViewBuilder(view)
|
|
556
|
+
for (const op of ops) {
|
|
557
|
+
op(elementViewBuilder)
|
|
558
|
+
}
|
|
622
559
|
return b
|
|
623
560
|
}
|
|
561
|
+
|
|
562
|
+
return add
|
|
624
563
|
},
|
|
625
564
|
$autoLayout,
|
|
626
565
|
$exclude,
|
|
627
566
|
$include,
|
|
628
567
|
$rules,
|
|
629
|
-
$style
|
|
568
|
+
$style,
|
|
630
569
|
},
|
|
631
570
|
deployment: {
|
|
632
571
|
deployment: (...ops: ((b: DeploymentModelBuilder<T>) => DeploymentModelBuilder<T>)[]) => {
|
|
633
572
|
return (b: Builder<T>) => {
|
|
634
|
-
|
|
635
|
-
for (const op of ops) {
|
|
636
|
-
op(v)
|
|
637
|
-
}
|
|
638
|
-
return b
|
|
573
|
+
return ops.reduce((b, op) => op(b), b as any as DeploymentModelBuilder<T>) as any
|
|
639
574
|
}
|
|
640
575
|
},
|
|
641
|
-
instanceOf: (
|
|
576
|
+
instanceOf: (
|
|
577
|
+
id: string,
|
|
578
|
+
target?: string | T['NewDeploymentNodeProps'],
|
|
579
|
+
_props?: string | T['NewDeploymentNodeProps'],
|
|
580
|
+
) => {
|
|
642
581
|
return <T extends AnyTypes>(
|
|
643
|
-
b: DeploymentModelBuilder<T
|
|
582
|
+
b: DeploymentModelBuilder<T>,
|
|
644
583
|
): DeploymentModelBuilder<Types.AddDeploymentFqn<T, any>> => {
|
|
584
|
+
if (isNullish(target)) {
|
|
585
|
+
target = id
|
|
586
|
+
id = nameFromFqn(id)
|
|
587
|
+
} else if (typeof target === 'string') {
|
|
588
|
+
_props ??= {}
|
|
589
|
+
} else {
|
|
590
|
+
_props = target
|
|
591
|
+
target = id
|
|
592
|
+
id = nameFromFqn(id)
|
|
593
|
+
}
|
|
645
594
|
const {
|
|
646
595
|
links,
|
|
647
596
|
title,
|
|
648
597
|
...props
|
|
649
598
|
} = typeof _props === 'string' ? { title: _props } : { ..._props }
|
|
650
|
-
const _id = b.
|
|
651
|
-
invariant(_elements.has(
|
|
652
|
-
b.
|
|
599
|
+
const _id = b.__fqn(id)
|
|
600
|
+
invariant(_elements.has(target), `Target element with id "${target}" not found`)
|
|
601
|
+
b.__addDeployment({
|
|
653
602
|
id: _id,
|
|
654
|
-
element:
|
|
603
|
+
element: target as any,
|
|
655
604
|
...title && { title },
|
|
656
605
|
...links && { links: mapLinks(links) },
|
|
657
|
-
...props
|
|
606
|
+
...props,
|
|
658
607
|
})
|
|
659
608
|
return b as any
|
|
660
609
|
}
|
|
@@ -667,16 +616,16 @@ function builder<Spec extends BuilderSpecification, T extends AnyTypes>(
|
|
|
667
616
|
...props
|
|
668
617
|
} = typeof _props === 'string' ? { title: _props } : { ..._props }
|
|
669
618
|
|
|
670
|
-
b.
|
|
619
|
+
b.__addDeploymentRelation({
|
|
671
620
|
source: {
|
|
672
|
-
id: source as any
|
|
621
|
+
id: source as any,
|
|
673
622
|
},
|
|
674
623
|
target: {
|
|
675
|
-
id: target as any
|
|
624
|
+
id: target as any,
|
|
676
625
|
},
|
|
677
626
|
...title && { title },
|
|
678
627
|
...links && { links: mapLinks(links) },
|
|
679
|
-
...props
|
|
628
|
+
...props,
|
|
680
629
|
})
|
|
681
630
|
return b
|
|
682
631
|
}
|
|
@@ -686,7 +635,7 @@ function builder<Spec extends BuilderSpecification, T extends AnyTypes>(
|
|
|
686
635
|
({ style: specStyle, ...spec }, kind) =>
|
|
687
636
|
<Id extends string>(
|
|
688
637
|
id: Id,
|
|
689
|
-
_props?: T['NewDeploymentNodeProps'] | string
|
|
638
|
+
_props?: T['NewDeploymentNodeProps'] | string,
|
|
690
639
|
): AddDeploymentNode<Id> => {
|
|
691
640
|
const add = (<T extends AnyTypes>(b: DeploymentModelBuilder<T>) => {
|
|
692
641
|
const {
|
|
@@ -699,9 +648,9 @@ function builder<Spec extends BuilderSpecification, T extends AnyTypes>(
|
|
|
699
648
|
|
|
700
649
|
const icon = _icon ?? specStyle?.icon
|
|
701
650
|
|
|
702
|
-
const _id = b.
|
|
651
|
+
const _id = b.__fqn(id)
|
|
703
652
|
|
|
704
|
-
b.
|
|
653
|
+
b.__addDeployment({
|
|
705
654
|
id: _id,
|
|
706
655
|
kind: kind as any,
|
|
707
656
|
title: title ?? nameFromFqn(_id),
|
|
@@ -713,12 +662,12 @@ function builder<Spec extends BuilderSpecification, T extends AnyTypes>(
|
|
|
713
662
|
style: pickBy({
|
|
714
663
|
border: specStyle?.border,
|
|
715
664
|
opacity: specStyle?.opacity,
|
|
716
|
-
...style
|
|
665
|
+
...style,
|
|
717
666
|
}, isNonNullish),
|
|
718
667
|
...links && { links: mapLinks(links) },
|
|
719
668
|
...icon && { icon: icon as IconUrl },
|
|
720
669
|
...spec,
|
|
721
|
-
...props
|
|
670
|
+
...props,
|
|
722
671
|
})
|
|
723
672
|
return b
|
|
724
673
|
}) as AddDeploymentNode<Id>
|
|
@@ -727,41 +676,73 @@ function builder<Spec extends BuilderSpecification, T extends AnyTypes>(
|
|
|
727
676
|
(...ops: Array<(input: DeploymentModelBuilder<any>) => DeploymentModelBuilder<any>>) =>
|
|
728
677
|
(b: DeploymentModelBuilder<any>) => {
|
|
729
678
|
add(b)
|
|
730
|
-
const
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
679
|
+
const { __fqn } = b
|
|
680
|
+
try {
|
|
681
|
+
b.__fqn = (child) => `${__fqn(id)}.${child}` as Fqn
|
|
682
|
+
ops.reduce((b, op) => op(b), b as any as DeploymentModelBuilder<T>) as any
|
|
683
|
+
} finally {
|
|
684
|
+
b.__fqn = __fqn
|
|
736
685
|
}
|
|
737
686
|
return b
|
|
738
687
|
}
|
|
739
688
|
return add
|
|
740
|
-
}
|
|
741
|
-
) as AddDeploymentNodeHelpers<T
|
|
742
|
-
}
|
|
689
|
+
},
|
|
690
|
+
) as AddDeploymentNodeHelpers<T>,
|
|
691
|
+
},
|
|
692
|
+
} as {
|
|
693
|
+
model: ModelHelpers<T>
|
|
694
|
+
views: ViewsHelpers
|
|
695
|
+
deployment: DeloymentModelHelpers<T>
|
|
743
696
|
}),
|
|
744
697
|
with: (...ops: ((b: Builder<T>) => Builder<T>)[]) => {
|
|
745
|
-
return ops.reduce((b, op) => op(b), self).clone()
|
|
746
|
-
}
|
|
698
|
+
return ops.reduce((b, op) => op(b), self as Builder<T>).clone()
|
|
699
|
+
},
|
|
700
|
+
model: <Out extends AnyTypes>(cb: ModelBuilderFunction<T, Out>) => {
|
|
701
|
+
const b = self.clone()
|
|
702
|
+
const helpers = b.helpers().model
|
|
703
|
+
const _ = helpers.model as any
|
|
704
|
+
return cb({ ...helpers, _ }, _)(b as Internals<T>) as any
|
|
705
|
+
},
|
|
706
|
+
deployment: <Out extends AnyTypes>(cb: DeloymentModelBuildFunction<T, Out>) => {
|
|
707
|
+
const b = self.clone()
|
|
708
|
+
const helpers = b.helpers().deployment
|
|
709
|
+
const _ = helpers.deployment as any
|
|
710
|
+
return cb({ ...helpers, _ }, _)(b as Internals<T>) as any
|
|
711
|
+
},
|
|
712
|
+
views: <Out extends AnyTypes>(cb: ViewsBuilderFunction<T, Out>) => {
|
|
713
|
+
const b = self.clone()
|
|
714
|
+
const helpers = b.helpers().views
|
|
715
|
+
return cb({
|
|
716
|
+
...helpers,
|
|
717
|
+
_: helpers.views as any,
|
|
718
|
+
} as any, helpers.views as any)(b as Internals<T>) as any
|
|
719
|
+
},
|
|
747
720
|
}
|
|
748
721
|
|
|
749
722
|
return self
|
|
750
723
|
}
|
|
751
724
|
|
|
752
725
|
export namespace Builder {
|
|
726
|
+
export type Any = Builder<AnyTypes>
|
|
727
|
+
|
|
753
728
|
export function forSpecification<const Spec extends BuilderSpecification>(
|
|
754
|
-
spec: Spec
|
|
729
|
+
spec: Spec,
|
|
755
730
|
): {
|
|
756
731
|
builder: Builder<Types.FromSpecification<Spec>>
|
|
757
732
|
model: ModelHelpers<Types.FromSpecification<Spec>>
|
|
758
733
|
deployment: DeloymentModelHelpers<Types.FromSpecification<Spec>>
|
|
759
|
-
views:
|
|
734
|
+
views: ViewsHelpers
|
|
760
735
|
} {
|
|
761
736
|
const b = builder<Spec, Types.FromSpecification<Spec>>(spec)
|
|
762
737
|
return {
|
|
763
738
|
...b.helpers(),
|
|
764
|
-
builder: b
|
|
739
|
+
builder: b,
|
|
765
740
|
}
|
|
766
741
|
}
|
|
742
|
+
|
|
743
|
+
export function specification<const Spec extends BuilderSpecification>(
|
|
744
|
+
spec: Spec,
|
|
745
|
+
): Builder<Types.FromSpecification<Spec>> {
|
|
746
|
+
return builder<Spec, Types.FromSpecification<Spec>>(spec)
|
|
747
|
+
}
|
|
767
748
|
}
|