@likec4/core 1.39.5 → 1.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builder/index.d.mts +75 -14
- package/dist/builder/index.mjs +111 -47
- package/dist/compute-view/index.d.mts +5 -5
- package/dist/compute-view/index.mjs +3 -3
- package/dist/compute-view/relationships-view/index.d.mts +5 -5
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +5 -5
- package/dist/model/connection/deployment/index.d.mts +7 -7
- package/dist/model/connection/deployment/index.mjs +1 -1
- package/dist/model/connection/index.d.mts +8 -8
- package/dist/model/connection/index.mjs +1 -1
- package/dist/model/connection/model/index.d.mts +7 -7
- package/dist/model/index.d.mts +10 -10
- package/dist/model/index.mjs +3 -3
- package/dist/shared/{core.CxGKeL-L.mjs → core.6_Vp2iiN.mjs} +29 -1
- package/dist/shared/{core.BqVo8LrH.mjs → core.Ae86Y3tB.mjs} +27 -8
- package/dist/shared/{core.DozSPE83.mjs → core.Asc11Mjy.mjs} +47 -11
- package/dist/shared/{core.PFqKFee4.d.mts → core.BXsxn-hf.d.mts} +44 -8
- package/dist/shared/core.BazD6cot.mjs +14 -0
- package/dist/shared/{core.B4scjmM6.d.mts → core.BhpgpOep.d.mts} +24 -4
- package/dist/shared/{core.CNhp8dSD.mjs → core.BvMRMo7Z.mjs} +69 -46
- package/dist/shared/{core.DmFVWyBc.d.mts → core.CUG6vpyL.d.mts} +2 -2
- package/dist/shared/{core.yHe79zEl.mjs → core.CXy1NLUG.mjs} +2 -2
- package/dist/shared/{core.B65NlqR_.d.mts → core.D-ZGWDDt.d.mts} +49 -39
- package/dist/shared/{core.CsbOakly.mjs → core.DA5vzwZ9.mjs} +30 -4
- package/dist/shared/{core.T-eLZTW_.mjs → core.DJp8fgok.mjs} +6 -2
- package/dist/shared/{core.1_FtXl46.d.mts → core.DgesAwC8.d.mts} +12 -3
- package/dist/shared/{core.1ypAWObi.d.mts → core.FUPplpae.d.mts} +1 -1
- package/dist/shared/{core.BZs_hKMJ.d.mts → core.hfOE3RfK.d.mts} +4 -4
- package/dist/shared/{core.Chtad_Hv.d.mts → core.xSQO0XYD.d.mts} +2 -2
- package/dist/shared/{core.Bq0r6_yG.d.mts → core.zxTBF_PD.d.mts} +3 -3
- package/dist/types/_aux.d.mts +2 -2
- package/dist/types/_aux.mjs +1 -5
- package/dist/types/expression-model.d.mts +3 -3
- package/dist/types/expression.d.mts +3 -3
- package/dist/types/fqnRef.d.mts +2 -2
- package/dist/types/index.d.mts +6 -6
- package/dist/types/index.mjs +5 -5
- package/dist/utils/index.d.mts +2 -2
- package/dist/utils/iterable/index.d.mts +1 -1
- package/package.json +2 -2
- package/src/builder/Builder.ts +119 -43
- package/src/builder/_types.ts +12 -8
- package/src/compute-view/deployment-view/utils.ts +47 -36
- package/src/compute-view/dynamic-view/compute.ts +1 -0
- package/src/compute-view/relationships-view/layout.ts +7 -6
- package/src/compute-view/utils/buildComputedNodes.ts +23 -10
- package/src/compute-view/utils/buildElementNotations.ts +2 -1
- package/src/model/DeploymentElementModel.ts +33 -3
- package/src/model/ElementModel.ts +25 -2
- package/src/model/RelationModel.ts +1 -1
- package/src/model/view/EdgeModel.ts +3 -2
- package/src/model/view/LikeC4ViewModel.ts +25 -7
- package/src/model/view/NodeModel.ts +1 -1
- package/src/types/RichText.ts +6 -4
- package/src/types/_aux.ts +26 -0
- package/src/types/_common.ts +24 -2
- package/src/types/geometry.ts +29 -1
- package/src/types/index.ts +2 -0
- package/src/types/model-deployment.ts +8 -18
- package/src/types/model-logical.ts +31 -16
- package/src/types/model-spec.ts +3 -0
- package/src/types/view-computed.ts +28 -13
- package/src/types/view-layouted.ts +7 -4
- package/src/types/view-parsed.dynamic.ts +11 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isEmpty, isTruthy, unique } from 'remeda'
|
|
1
|
+
import { isEmpty, isShallowEqual, isTruthy, unique } from 'remeda'
|
|
2
2
|
import type { SetRequired } from 'type-fest'
|
|
3
3
|
import type { Any, AnyAux, Color, IteratorLike } from '../types'
|
|
4
4
|
import {
|
|
@@ -12,6 +12,8 @@ import {
|
|
|
12
12
|
DefaultElementShape,
|
|
13
13
|
DefaultShapeSize,
|
|
14
14
|
DefaultThemeColor,
|
|
15
|
+
preferDescription,
|
|
16
|
+
preferSummary,
|
|
15
17
|
RichText,
|
|
16
18
|
splitGlobalFqn,
|
|
17
19
|
} from '../types'
|
|
@@ -95,8 +97,29 @@ export class ElementModel<A extends AnyAux = Any> implements WithTags<A>, WithMe
|
|
|
95
97
|
return this.$element.title
|
|
96
98
|
}
|
|
97
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Returns true if the element has a summary and a description
|
|
102
|
+
* (if one is missing - it falls back to another)
|
|
103
|
+
*/
|
|
104
|
+
get hasSummary(): boolean {
|
|
105
|
+
return !!this.$element.summary && !!this.$element.description &&
|
|
106
|
+
!isShallowEqual(this.$element.summary, this.$element.description)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Short description of the element.
|
|
111
|
+
* Falls back to description if summary is not provided.
|
|
112
|
+
*/
|
|
113
|
+
get summary(): RichTextOrEmpty {
|
|
114
|
+
return RichText.memoize(this, 'summary', preferSummary(this.$element))
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Long description of the element.
|
|
119
|
+
* Falls back to summary if description is not provided.
|
|
120
|
+
*/
|
|
98
121
|
get description(): RichTextOrEmpty {
|
|
99
|
-
return RichText.memoize(this, this.$element
|
|
122
|
+
return RichText.memoize(this, 'description', preferDescription(this.$element))
|
|
100
123
|
}
|
|
101
124
|
|
|
102
125
|
get technology(): string | null {
|
|
@@ -83,7 +83,7 @@ export class RelationshipModel<A extends AnyAux = AnyAux> implements AnyRelation
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
get description(): RichTextOrEmpty {
|
|
86
|
-
return RichText.memoize(this, this.$relationship.description)
|
|
86
|
+
return RichText.memoize(this, 'description', this.$relationship.description)
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
get navigateTo(): LikeC4ViewModel<A> | null {
|
|
@@ -6,12 +6,13 @@ import {
|
|
|
6
6
|
type DiagramEdge,
|
|
7
7
|
type IteratorLike,
|
|
8
8
|
type RelationshipLineType,
|
|
9
|
+
type RichTextOrEmpty,
|
|
9
10
|
type scalar,
|
|
10
11
|
type StepEdgeId,
|
|
11
12
|
extractStep,
|
|
12
13
|
isStepEdgeId,
|
|
14
|
+
RichText,
|
|
13
15
|
} from '../../types'
|
|
14
|
-
import { type RichTextOrEmpty, RichText } from '../../types'
|
|
15
16
|
import type { DeploymentRelationModel } from '../DeploymentElementModel'
|
|
16
17
|
import type { RelationshipModel } from '../RelationModel'
|
|
17
18
|
import type { $View, WithTags } from '../types'
|
|
@@ -44,7 +45,7 @@ export class EdgeModel<A extends Any = Any, View extends $View<A> = $View<A>> im
|
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
get description(): RichTextOrEmpty {
|
|
47
|
-
return RichText.memoize(this, this.#edge.description)
|
|
48
|
+
return RichText.memoize(this, 'description', this.#edge.description)
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
get technology(): string | null {
|
|
@@ -2,6 +2,7 @@ import { isTruthy } from 'remeda'
|
|
|
2
2
|
import type {
|
|
3
3
|
Any,
|
|
4
4
|
AnyView,
|
|
5
|
+
DynamicViewDisplayVariant,
|
|
5
6
|
IteratorLike,
|
|
6
7
|
Link,
|
|
7
8
|
scalar,
|
|
@@ -149,7 +150,7 @@ export class LikeC4ViewModel<A extends Any = Any, V extends $View<A> = $View<A>>
|
|
|
149
150
|
}
|
|
150
151
|
|
|
151
152
|
get description(): RichTextOrEmpty {
|
|
152
|
-
return RichText.memoize(this, this.$view.description)
|
|
153
|
+
return RichText.memoize(this, 'description', this.$view.description)
|
|
153
154
|
}
|
|
154
155
|
|
|
155
156
|
get tags(): aux.Tags<A> {
|
|
@@ -168,6 +169,17 @@ export class LikeC4ViewModel<A extends Any = Any, V extends $View<A> = $View<A>>
|
|
|
168
169
|
return null
|
|
169
170
|
}
|
|
170
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Available for dynamic views only
|
|
174
|
+
* throws error if view is not dynamic
|
|
175
|
+
*/
|
|
176
|
+
get mode(): DynamicViewDisplayVariant {
|
|
177
|
+
if (this.isDynamicView()) {
|
|
178
|
+
return this.$view.variant ?? 'diagram'
|
|
179
|
+
}
|
|
180
|
+
throw new Error('View is not dynamic')
|
|
181
|
+
}
|
|
182
|
+
|
|
171
183
|
/**
|
|
172
184
|
* All tags from nodes and edges.
|
|
173
185
|
*/
|
|
@@ -223,17 +235,26 @@ export class LikeC4ViewModel<A extends Any = Any, V extends $View<A> = $View<A>>
|
|
|
223
235
|
}
|
|
224
236
|
|
|
225
237
|
/**
|
|
226
|
-
*
|
|
238
|
+
* Get edge by id, throws error if edge is not found.
|
|
239
|
+
* Use {@link findEdge} if you are not sure if the edge exists.
|
|
240
|
+
*
|
|
227
241
|
* @param edge Edge or id
|
|
228
|
-
* @returns EdgeModel
|
|
242
|
+
* @returns {@link EdgeModel}
|
|
229
243
|
*/
|
|
230
244
|
public edge(edge: EdgeOrId): EdgeModel<A, V> {
|
|
231
245
|
const edgeId = getId(edge)
|
|
232
246
|
return nonNullable(this.#edges.get(edgeId), `Edge ${edgeId} not found in view ${this.$view.id}`)
|
|
233
247
|
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Find edge by id.
|
|
251
|
+
* @param edge Edge or id
|
|
252
|
+
* @returns {@link EdgeModel} or null if edge is not found
|
|
253
|
+
*/
|
|
234
254
|
public findEdge(edge: EdgeOrId): EdgeModel<A, V> | null {
|
|
235
255
|
return this.#edges.get(getId(edge)) ?? null
|
|
236
256
|
}
|
|
257
|
+
|
|
237
258
|
/**
|
|
238
259
|
* Iterate over all edges.
|
|
239
260
|
*/
|
|
@@ -336,8 +357,5 @@ export namespace LikeC4ViewModel {
|
|
|
336
357
|
{
|
|
337
358
|
}
|
|
338
359
|
|
|
339
|
-
export
|
|
340
|
-
extends LikeC4ViewModel<A, ViewWithType<V, 'dynamic'>>
|
|
341
|
-
{
|
|
342
|
-
}
|
|
360
|
+
export type DynamicView<A extends Any, V extends $View<A> = $View<A>> = LikeC4ViewModel<A, ViewWithType<V, 'dynamic'>>
|
|
343
361
|
}
|
|
@@ -49,7 +49,7 @@ export class NodeModel<A extends Any = Any, V extends $View<A> = $View<A>> imple
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
get description(): RichTextOrEmpty {
|
|
52
|
-
return RichText.memoize(this, this.#node.description)
|
|
52
|
+
return RichText.memoize(this, 'description', this.#node.description)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
get technology(): string | null {
|
package/src/types/RichText.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { markdownToHtml, markdownToText, memoizeProp, nonexhaustive } from '../utils'
|
|
2
2
|
import type { MarkdownOrString } from './scalar'
|
|
3
3
|
|
|
4
|
-
const richtxt = Symbol.for('richtxt')
|
|
5
4
|
const symb_text = Symbol.for('text')
|
|
6
5
|
const symb_html = Symbol.for('html')
|
|
7
6
|
|
|
@@ -48,8 +47,8 @@ export class RichText {
|
|
|
48
47
|
* return RichText.memoize(this, this.$element.description)
|
|
49
48
|
* }
|
|
50
49
|
*/
|
|
51
|
-
static memoize(obj: object, source: MarkdownOrString | null | undefined): RichTextOrEmpty {
|
|
52
|
-
return memoizeProp(obj,
|
|
50
|
+
static memoize(obj: object, tag: symbol | string, source: MarkdownOrString | null | undefined): RichTextOrEmpty {
|
|
51
|
+
return memoizeProp(obj, tag, () => RichText.from(source))
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
/**
|
|
@@ -63,7 +62,10 @@ export class RichText {
|
|
|
63
62
|
return source as RichTextOrEmpty
|
|
64
63
|
}
|
|
65
64
|
if (typeof source === 'string') {
|
|
66
|
-
|
|
65
|
+
if (source.trim() === emptyTxt) {
|
|
66
|
+
return RichText.EMPTY
|
|
67
|
+
}
|
|
68
|
+
return new RichText({ txt: source }) as RichTextOrEmpty
|
|
67
69
|
}
|
|
68
70
|
if ('isEmpty' in source && source.isEmpty) {
|
|
69
71
|
return RichText.EMPTY
|
package/src/types/_aux.ts
CHANGED
|
@@ -255,6 +255,28 @@ export type StrictDeploymentKind<A> = A extends infer T extends Any ? scalar.Dep
|
|
|
255
255
|
: never
|
|
256
256
|
export type StrictRelationKind<A> = A extends infer T extends Any ? scalar.RelationshipKind<RelationKind<T>> : never
|
|
257
257
|
|
|
258
|
+
export type WithDescriptionAndTech = {
|
|
259
|
+
// short summary (displayed in the diagram)
|
|
260
|
+
readonly summary?: scalar.MarkdownOrString | null
|
|
261
|
+
// long description (displayed in the details panel, or in the diagram if summary is not set)
|
|
262
|
+
readonly description?: scalar.MarkdownOrString | null
|
|
263
|
+
readonly technology?: string | null
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Returns summary if it is not null, otherwise returns description
|
|
268
|
+
*/
|
|
269
|
+
export function preferSummary(a: WithDescriptionAndTech): scalar.MarkdownOrString | null | undefined {
|
|
270
|
+
return a.summary ?? a.description
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Returns description if it is not null, otherwise returns summary
|
|
275
|
+
*/
|
|
276
|
+
export function preferDescription(a: WithDescriptionAndTech): scalar.MarkdownOrString | null | undefined {
|
|
277
|
+
return a.description ?? a.summary
|
|
278
|
+
}
|
|
279
|
+
|
|
258
280
|
export type WithTags<A extends Any> = {
|
|
259
281
|
readonly tags: Tags<A>
|
|
260
282
|
}
|
|
@@ -275,6 +297,10 @@ export type WithMetadata<A extends Any> = {
|
|
|
275
297
|
readonly metadata?: Metadata<A>
|
|
276
298
|
}
|
|
277
299
|
|
|
300
|
+
export type WithNotation = {
|
|
301
|
+
readonly notation?: string | null
|
|
302
|
+
}
|
|
303
|
+
|
|
278
304
|
/**
|
|
279
305
|
* @see {@link LiteralUnion} from type-fest (https://github.com/sindresorhus/type-fest/blob/main/source/literal-union.d.ts)
|
|
280
306
|
*/
|
package/src/types/_common.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { omitBy } from 'remeda'
|
|
2
|
+
import type {
|
|
3
|
+
Exact,
|
|
4
|
+
IsAny,
|
|
5
|
+
KeysOfUnion,
|
|
6
|
+
Simplify,
|
|
7
|
+
UnionToIntersection,
|
|
8
|
+
} from 'type-fest'
|
|
2
9
|
|
|
3
10
|
export type NonEmptyArray<T> = [T, ...T[]]
|
|
4
11
|
|
|
@@ -62,7 +69,7 @@ export type NTuple<
|
|
|
62
69
|
Result extends Array<unknown> = [],
|
|
63
70
|
> = Result['length'] extends N ? Result : NTuple<T, N, [...Result, T]>
|
|
64
71
|
|
|
65
|
-
export type IteratorLike<T> = IteratorObject<T, BuiltinIteratorReturn>
|
|
72
|
+
export type IteratorLike<T> = IteratorObject<T, BuiltinIteratorReturn, unknown>
|
|
66
73
|
|
|
67
74
|
export type Predicate<T> = (x: T) => boolean
|
|
68
75
|
|
|
@@ -78,3 +85,18 @@ export interface Link {
|
|
|
78
85
|
* Coalesce `V` to a string if it is `any`
|
|
79
86
|
*/
|
|
80
87
|
export type Coalesce<V extends string, OrIfAny = string> = IsAny<V> extends true ? OrIfAny : V
|
|
88
|
+
|
|
89
|
+
type ExactObject<T, InputType = unknown> =
|
|
90
|
+
& {
|
|
91
|
+
[KeyType in keyof T]: undefined extends T[KeyType] ? T[KeyType] | undefined : T[KeyType]
|
|
92
|
+
}
|
|
93
|
+
& Record<Exclude<keyof InputType, KeysOfUnion<T>>, never>
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Allows only exact properties of `U` to be present in `T` and omits undefined values
|
|
97
|
+
*
|
|
98
|
+
* See {@link Exact} for more details (this version is non-deep)
|
|
99
|
+
*/
|
|
100
|
+
export function omitUndefined<Expected, T extends ExactObject<Expected, T>>(a: T): Expected {
|
|
101
|
+
return omitBy(a, v => v === undefined) as Expected
|
|
102
|
+
}
|
package/src/types/geometry.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { hasAtLeast } from 'remeda'
|
|
1
2
|
import { invariant } from '../utils/invariant'
|
|
2
3
|
|
|
3
4
|
export type Point = readonly [x: number, y: number]
|
|
@@ -34,7 +35,10 @@ export namespace BBox {
|
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
export function merge(...boxes: BBox[]): BBox {
|
|
37
|
-
invariant(boxes
|
|
38
|
+
invariant(hasAtLeast(boxes, 1), 'No boxes provided')
|
|
39
|
+
if (boxes.length === 1) {
|
|
40
|
+
return boxes[0]
|
|
41
|
+
}
|
|
38
42
|
let minX = Infinity
|
|
39
43
|
let minY = Infinity
|
|
40
44
|
let maxX = -Infinity
|
|
@@ -61,6 +65,30 @@ export namespace BBox {
|
|
|
61
65
|
y2: box.y + box.height,
|
|
62
66
|
}
|
|
63
67
|
}
|
|
68
|
+
|
|
69
|
+
export function expand(box: BBox, plus: number): BBox {
|
|
70
|
+
if (plus === 0) {
|
|
71
|
+
return box
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
x: box.x - plus,
|
|
75
|
+
y: box.y - plus,
|
|
76
|
+
width: box.width + plus * 2,
|
|
77
|
+
height: box.height + plus * 2,
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function shrink(box: BBox, minus: number): BBox {
|
|
82
|
+
if (minus === 0) {
|
|
83
|
+
return box
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
x: box.x + minus,
|
|
87
|
+
y: box.y + minus,
|
|
88
|
+
width: box.width - minus * 2,
|
|
89
|
+
height: box.height - minus * 2,
|
|
90
|
+
}
|
|
91
|
+
}
|
|
64
92
|
}
|
|
65
93
|
|
|
66
94
|
export interface RectBox {
|
package/src/types/index.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { isTruthy } from 'remeda'
|
|
2
2
|
import type * as aux from './_aux'
|
|
3
3
|
import type { AnyAux, Unknown } from './_aux'
|
|
4
|
-
import type { Link } from './_common'
|
|
5
4
|
import type { FqnRef } from './fqnRef'
|
|
6
5
|
import type { AbstractRelationship, ElementStyle } from './model-logical'
|
|
7
6
|
import type { Icon } from './scalar'
|
|
8
|
-
import type * as scalar from './scalar'
|
|
9
7
|
import type { Color, ElementShape } from './styles'
|
|
10
8
|
|
|
11
9
|
export interface DeploymentElementStyle extends ElementStyle {
|
|
@@ -17,30 +15,28 @@ export interface DeploymentElementStyle extends ElementStyle {
|
|
|
17
15
|
// dprint-ignore
|
|
18
16
|
export interface DeploymentNode<A extends AnyAux = Unknown>
|
|
19
17
|
extends
|
|
18
|
+
aux.WithDescriptionAndTech,
|
|
20
19
|
aux.WithOptionalTags<A>,
|
|
21
20
|
aux.WithOptionalLinks,
|
|
22
|
-
aux.WithMetadata<A
|
|
21
|
+
aux.WithMetadata<A>,
|
|
22
|
+
aux.WithNotation
|
|
23
23
|
{
|
|
24
24
|
element?: never
|
|
25
25
|
// Full-qualified-name for Deployment model
|
|
26
26
|
readonly id: aux.StrictDeploymentFqn<A>
|
|
27
27
|
readonly kind: aux.DeploymentKind<A>
|
|
28
28
|
readonly title: string
|
|
29
|
-
readonly description?: scalar.MarkdownOrString | null
|
|
30
|
-
readonly technology?: string | null
|
|
31
|
-
readonly tags?: aux.Tags<A> | null
|
|
32
|
-
readonly links?: readonly Link[] | null
|
|
33
29
|
readonly style: DeploymentElementStyle
|
|
34
|
-
readonly notation?: string | null
|
|
35
|
-
readonly metadata?: aux.Metadata<A>
|
|
36
30
|
}
|
|
37
31
|
|
|
38
32
|
// dprint-ignore
|
|
39
33
|
export interface DeployedInstance<A extends AnyAux = Unknown>
|
|
40
34
|
extends
|
|
35
|
+
aux.WithDescriptionAndTech,
|
|
41
36
|
aux.WithOptionalTags<A>,
|
|
42
37
|
aux.WithOptionalLinks,
|
|
43
|
-
aux.WithMetadata<A
|
|
38
|
+
aux.WithMetadata<A>,
|
|
39
|
+
aux.WithNotation
|
|
44
40
|
{
|
|
45
41
|
kind?: never
|
|
46
42
|
/**
|
|
@@ -50,13 +46,7 @@ export interface DeployedInstance<A extends AnyAux = Unknown>
|
|
|
50
46
|
readonly id: aux.StrictDeploymentFqn<A>
|
|
51
47
|
readonly element: aux.StrictFqn<A>
|
|
52
48
|
readonly title?: string
|
|
53
|
-
readonly description?: scalar.MarkdownOrString | null
|
|
54
|
-
readonly technology?: string | null
|
|
55
|
-
readonly tags?: aux.Tags<A> | null
|
|
56
|
-
readonly links?: readonly Link[] | null
|
|
57
49
|
readonly style?: DeploymentElementStyle
|
|
58
|
-
readonly notation?: string
|
|
59
|
-
readonly metadata?: aux.Metadata<A>
|
|
60
50
|
}
|
|
61
51
|
|
|
62
52
|
export type DeploymentElement<A extends AnyAux = Unknown> = DeploymentNode<A> | DeployedInstance<A>
|
|
@@ -67,11 +57,11 @@ export type DeploymentElementRef<A extends AnyAux = Unknown> = {
|
|
|
67
57
|
}
|
|
68
58
|
|
|
69
59
|
export function isDeploymentNode<A extends AnyAux>(el: DeploymentElement<A>): el is DeploymentNode<A> {
|
|
70
|
-
return
|
|
60
|
+
return isTruthy(el.kind) && !isTruthy(el.element)
|
|
71
61
|
}
|
|
72
62
|
|
|
73
63
|
export function isDeployedInstance<A extends AnyAux>(el: DeploymentElement<A>): el is DeployedInstance<A> {
|
|
74
|
-
return
|
|
64
|
+
return isTruthy(el.element) && !isTruthy(el.kind)
|
|
75
65
|
}
|
|
76
66
|
|
|
77
67
|
/**
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type * as aux from './_aux'
|
|
2
2
|
import type { AnyAux } from './_aux'
|
|
3
|
-
import type { Link } from './_common'
|
|
4
3
|
import type { FqnRef } from './fqnRef'
|
|
5
4
|
import type * as scalar from './scalar'
|
|
6
5
|
import type {
|
|
@@ -17,9 +16,10 @@ import type {
|
|
|
17
16
|
|
|
18
17
|
export const DefaultThemeColor: ThemeColor = 'primary'
|
|
19
18
|
export const DefaultElementShape: ElementShape = 'rectangle'
|
|
20
|
-
export const
|
|
21
|
-
export const
|
|
22
|
-
export const
|
|
19
|
+
export const DefaultSize = 'md'
|
|
20
|
+
export const DefaultShapeSize: ShapeSize = DefaultSize
|
|
21
|
+
export const DefaultPaddingSize: SpacingSize = DefaultSize
|
|
22
|
+
export const DefaultTextSize: TextSize = DefaultSize
|
|
23
23
|
|
|
24
24
|
export interface ElementStyle {
|
|
25
25
|
readonly border?: BorderStyle
|
|
@@ -47,26 +47,45 @@ export interface ElementStyle {
|
|
|
47
47
|
readonly textSize?: TextSize
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
type WithSizes = Pick<ElementStyle, 'size' | 'padding' | 'textSize'>
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Ensures that the sizes are set to default values if they are not set
|
|
54
|
+
*/
|
|
55
|
+
export function ensureSizes<S extends WithSizes>({
|
|
56
|
+
size,
|
|
57
|
+
padding,
|
|
58
|
+
textSize,
|
|
59
|
+
...rest
|
|
60
|
+
}: S): Omit<S, 'size' | 'padding' | 'textSize'> & Required<WithSizes> {
|
|
61
|
+
size ??= DefaultSize
|
|
62
|
+
textSize ??= size
|
|
63
|
+
padding ??= size
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
...rest,
|
|
67
|
+
size,
|
|
68
|
+
padding,
|
|
69
|
+
textSize,
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
50
73
|
// dprint-ignore
|
|
51
74
|
export interface Element<A extends AnyAux = AnyAux>
|
|
52
75
|
extends
|
|
76
|
+
aux.WithDescriptionAndTech,
|
|
53
77
|
aux.WithOptionalTags<A>,
|
|
54
78
|
aux.WithOptionalLinks,
|
|
55
|
-
aux.WithMetadata<A
|
|
79
|
+
aux.WithMetadata<A>,
|
|
80
|
+
aux.WithNotation
|
|
56
81
|
{
|
|
57
82
|
readonly id: aux.StrictFqn<A>
|
|
58
83
|
readonly kind: aux.ElementKind<A>
|
|
59
84
|
readonly title: string
|
|
60
|
-
readonly description?: scalar.MarkdownOrString | null
|
|
61
|
-
readonly technology?: string | null
|
|
62
|
-
readonly tags?: aux.Tags<A> | null
|
|
63
|
-
readonly links?: readonly Link[] | null
|
|
64
85
|
readonly icon?: scalar.Icon
|
|
65
86
|
readonly shape?: ElementShape
|
|
66
87
|
readonly color?: Color
|
|
67
88
|
readonly style?: ElementStyle
|
|
68
|
-
readonly notation?: string | null
|
|
69
|
-
readonly metadata?: aux.Metadata<A>
|
|
70
89
|
}
|
|
71
90
|
|
|
72
91
|
export const DefaultLineStyle: RelationshipLineType = 'dashed'
|
|
@@ -76,24 +95,20 @@ export const DefaultRelationshipColor: ThemeColor = 'gray'
|
|
|
76
95
|
// dprint-ignore
|
|
77
96
|
export interface AbstractRelationship<A extends AnyAux>
|
|
78
97
|
extends
|
|
98
|
+
aux.WithDescriptionAndTech,
|
|
79
99
|
aux.WithOptionalTags<A>,
|
|
80
100
|
aux.WithOptionalLinks,
|
|
81
101
|
aux.WithMetadata<A>
|
|
82
102
|
{
|
|
83
103
|
readonly id: scalar.RelationId
|
|
84
104
|
readonly title?: string | null
|
|
85
|
-
readonly description?: scalar.MarkdownOrString | null
|
|
86
|
-
readonly technology?: string | null
|
|
87
105
|
readonly kind?: aux.RelationKind<A>
|
|
88
106
|
readonly color?: Color
|
|
89
107
|
readonly line?: RelationshipLineType
|
|
90
108
|
readonly head?: RelationshipArrowType
|
|
91
109
|
readonly tail?: RelationshipArrowType
|
|
92
|
-
readonly tags?: aux.Tags<A> | null
|
|
93
|
-
readonly links?: readonly Link[] | null
|
|
94
110
|
// Link to dynamic view
|
|
95
111
|
readonly navigateTo?: aux.ViewId<A>
|
|
96
|
-
readonly metadata?: aux.Metadata<A>
|
|
97
112
|
}
|
|
98
113
|
|
|
99
114
|
/**
|
package/src/types/model-spec.ts
CHANGED
|
@@ -26,6 +26,9 @@ import type {
|
|
|
26
26
|
export interface ElementSpecification {
|
|
27
27
|
tags?: scalar.Tag[]
|
|
28
28
|
title?: string
|
|
29
|
+
// short summary
|
|
30
|
+
summary?: scalar.MarkdownOrString
|
|
31
|
+
// long description
|
|
29
32
|
description?: scalar.MarkdownOrString
|
|
30
33
|
technology?: string
|
|
31
34
|
notation?: string
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type * as aux from './_aux'
|
|
2
|
-
import type {
|
|
2
|
+
import type { AnyAux } from './_aux'
|
|
3
3
|
import type { _stage, _type } from './const'
|
|
4
4
|
import type { ElementStyle } from './model-logical'
|
|
5
5
|
import type * as scalar from './scalar'
|
|
@@ -19,27 +19,35 @@ import type {
|
|
|
19
19
|
ViewWithHash,
|
|
20
20
|
ViewWithNotation,
|
|
21
21
|
} from './view-common'
|
|
22
|
+
import type { DynamicViewDisplayVariant } from './view-parsed.dynamic'
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
// dprint-ignore
|
|
25
|
+
export interface ComputedNode<A extends AnyAux = AnyAux>
|
|
26
|
+
extends
|
|
27
|
+
aux.WithTags<A>,
|
|
28
|
+
aux.WithOptionalLinks
|
|
29
|
+
{
|
|
24
30
|
id: scalar.NodeId
|
|
25
31
|
kind: aux.ElementKind<A> | aux.DeploymentKind<A> | '@group'
|
|
26
32
|
parent: scalar.NodeId | null
|
|
27
33
|
/**
|
|
28
34
|
* Reference to model element
|
|
29
35
|
*/
|
|
30
|
-
modelRef?: aux.Fqn<A>
|
|
36
|
+
modelRef?: aux.Fqn<A>
|
|
31
37
|
/**
|
|
32
38
|
* Reference to deployment element
|
|
33
39
|
*/
|
|
34
|
-
deploymentRef?: aux.DeploymentFqn<A>
|
|
40
|
+
deploymentRef?: aux.DeploymentFqn<A>
|
|
35
41
|
title: string
|
|
42
|
+
/**
|
|
43
|
+
* Description of the node
|
|
44
|
+
* either summary or description
|
|
45
|
+
*/
|
|
36
46
|
description?: scalar.MarkdownOrString | null
|
|
37
47
|
technology?: string | null
|
|
38
|
-
notation?: string
|
|
39
48
|
children: scalar.NodeId[]
|
|
40
49
|
inEdges: scalar.EdgeId[]
|
|
41
50
|
outEdges: scalar.EdgeId[]
|
|
42
|
-
tags: aux.Tags<A>
|
|
43
51
|
shape: ElementShape
|
|
44
52
|
color: Color
|
|
45
53
|
icon?: Icon
|
|
@@ -47,21 +55,22 @@ export interface ComputedNode<A extends Any = Any> extends aux.WithOptionalLinks
|
|
|
47
55
|
navigateTo?: aux.StrictViewId<A> | null
|
|
48
56
|
level: number
|
|
49
57
|
// For compound nodes, the max depth of nested nodes
|
|
50
|
-
depth?: number
|
|
58
|
+
depth?: number | null
|
|
51
59
|
/**
|
|
52
60
|
* If this node was customized in the view
|
|
53
61
|
*/
|
|
54
62
|
isCustomized?: boolean
|
|
63
|
+
notation?: string | null
|
|
55
64
|
}
|
|
56
65
|
|
|
57
|
-
export interface ComputedEdge<A extends
|
|
66
|
+
export interface ComputedEdge<A extends AnyAux = AnyAux> extends aux.WithOptionalTags<A> {
|
|
58
67
|
id: scalar.EdgeId
|
|
59
68
|
parent: scalar.NodeId | null
|
|
60
69
|
source: scalar.NodeId
|
|
61
70
|
target: scalar.NodeId
|
|
62
71
|
label: string | null
|
|
63
72
|
description?: scalar.MarkdownOrString | null
|
|
64
|
-
technology?: string
|
|
73
|
+
technology?: string | null
|
|
65
74
|
relations: scalar.RelationId[]
|
|
66
75
|
kind?: aux.RelationKind<A> | typeof scalar.StepEdgeKind
|
|
67
76
|
notation?: string
|
|
@@ -84,7 +93,7 @@ export interface ComputedEdge<A extends Any = Any> extends aux.WithOptionalTags<
|
|
|
84
93
|
dir?: 'forward' | 'back' | 'both'
|
|
85
94
|
}
|
|
86
95
|
|
|
87
|
-
interface BaseComputedViewProperties<A extends
|
|
96
|
+
interface BaseComputedViewProperties<A extends AnyAux> extends BaseViewProperties<A>, ViewWithHash, ViewWithNotation {
|
|
88
97
|
readonly [_stage]: 'computed'
|
|
89
98
|
readonly autoLayout: ViewAutoLayout
|
|
90
99
|
readonly nodes: ComputedNode<A>[]
|
|
@@ -96,16 +105,22 @@ interface BaseComputedViewProperties<A extends Any> extends BaseViewProperties<A
|
|
|
96
105
|
readonly manualLayout?: ViewManualLayout | undefined
|
|
97
106
|
}
|
|
98
107
|
|
|
99
|
-
export interface ComputedElementView<A extends
|
|
108
|
+
export interface ComputedElementView<A extends AnyAux = AnyAux> extends BaseComputedViewProperties<A> {
|
|
100
109
|
readonly [_type]: 'element'
|
|
101
110
|
readonly viewOf?: aux.StrictFqn<A>
|
|
102
111
|
readonly extends?: aux.StrictViewId<A>
|
|
103
112
|
}
|
|
104
113
|
|
|
105
|
-
export interface ComputedDeploymentView<A extends
|
|
114
|
+
export interface ComputedDeploymentView<A extends AnyAux = AnyAux> extends BaseComputedViewProperties<A> {
|
|
106
115
|
readonly [_type]: 'deployment'
|
|
107
116
|
}
|
|
108
117
|
|
|
109
|
-
export interface ComputedDynamicView<A extends
|
|
118
|
+
export interface ComputedDynamicView<A extends AnyAux = AnyAux> extends BaseComputedViewProperties<A> {
|
|
110
119
|
readonly [_type]: 'dynamic'
|
|
120
|
+
/**
|
|
121
|
+
* How to display the dynamic view
|
|
122
|
+
* - `diagram`: display as a regular likec4 view
|
|
123
|
+
* - `sequence`: display as a sequence diagram
|
|
124
|
+
*/
|
|
125
|
+
readonly variant: DynamicViewDisplayVariant
|
|
111
126
|
}
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
ViewWithNotation,
|
|
11
11
|
} from './view-common'
|
|
12
12
|
import type { ComputedEdge, ComputedNode } from './view-computed'
|
|
13
|
+
import type { DynamicViewDisplayVariant } from './view-parsed.dynamic'
|
|
13
14
|
|
|
14
15
|
export interface DiagramNode<A extends AnyAux = AnyAux> extends ComputedNode<A>, BBox {
|
|
15
16
|
x: number
|
|
@@ -26,10 +27,6 @@ export interface DiagramNode<A extends AnyAux = AnyAux> extends ComputedNode<A>,
|
|
|
26
27
|
* (Absolute coordinates)
|
|
27
28
|
*/
|
|
28
29
|
labelBBox: BBox
|
|
29
|
-
|
|
30
|
-
// description?: scalar.HtmlOrString | null
|
|
31
|
-
// technology?: scalar.HtmlOrString | null
|
|
32
|
-
// notation?: scalar.HtmlOrString | null
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
export interface DiagramEdge<A extends AnyAux = AnyAux> extends ComputedEdge<A> {
|
|
@@ -88,4 +85,10 @@ export interface LayoutedDeploymentView<A extends AnyAux = AnyAux> extends BaseL
|
|
|
88
85
|
|
|
89
86
|
export interface LayoutedDynamicView<A extends AnyAux = AnyAux> extends BaseLayoutedViewProperties<A> {
|
|
90
87
|
readonly [_type]: 'dynamic'
|
|
88
|
+
/**
|
|
89
|
+
* How to display the dynamic view
|
|
90
|
+
* - `diagram`: display as a regular likec4 view
|
|
91
|
+
* - `sequence`: display as a sequence diagram
|
|
92
|
+
*/
|
|
93
|
+
readonly variant: DynamicViewDisplayVariant
|
|
91
94
|
}
|
|
@@ -65,8 +65,19 @@ export type DynamicViewRule<A extends AnyAux = AnyAux> = ExclusiveUnion<{
|
|
|
65
65
|
AutoLayout: ViewRuleAutoLayout
|
|
66
66
|
}>
|
|
67
67
|
|
|
68
|
+
export type DynamicViewDisplayVariant = 'diagram' | 'sequence'
|
|
69
|
+
|
|
68
70
|
export interface ParsedDynamicView<A extends AnyAux = AnyAux> extends BaseParsedViewProperties<A> {
|
|
69
71
|
[_type]: 'dynamic'
|
|
72
|
+
/**
|
|
73
|
+
* How to display the dynamic view
|
|
74
|
+
* - `diagram`: display as a regular likec4 view
|
|
75
|
+
* - `sequence`: display as a sequence diagram
|
|
76
|
+
*
|
|
77
|
+
* @default 'diagram'
|
|
78
|
+
*/
|
|
79
|
+
readonly variant?: DynamicViewDisplayVariant
|
|
80
|
+
|
|
70
81
|
readonly steps: DynamicViewStepOrParallel<A>[]
|
|
71
82
|
readonly rules: DynamicViewRule<A>[]
|
|
72
83
|
}
|