@likec4/core 1.10.0 → 1.11.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/index.cjs +610 -223
- package/dist/index.d.cts +202 -221
- package/dist/index.d.mts +202 -221
- package/dist/index.d.ts +202 -221
- package/dist/index.mjs +611 -225
- package/dist/shared/{core.DeifT5lC.mjs → core.CUlHblBQ.mjs} +5 -5
- package/dist/shared/{core.CpR2fq5B.d.cts → core.aVt8heZL.d.cts} +199 -354
- package/dist/shared/{core.CpR2fq5B.d.mts → core.aVt8heZL.d.mts} +199 -354
- package/dist/shared/{core.CpR2fq5B.d.ts → core.aVt8heZL.d.ts} +199 -354
- package/dist/types/index.cjs +1 -2
- package/dist/types/index.d.cts +2 -1
- package/dist/types/index.d.mts +2 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.mjs +1 -1
- package/package.json +14 -10
- package/src/index.ts +2 -0
- package/src/model/LikeC4DiagramModel.ts +338 -0
- package/src/model/LikeC4Model.ts +227 -145
- package/src/model/LikeC4ViewModel.ts +45 -43
- package/src/model/index.ts +3 -2
- package/src/model/types.ts +13 -0
- package/src/types/_common.ts +2 -0
- package/src/types/index.ts +0 -2
- package/src/types/model.ts +10 -1
- package/src/utils/promises.ts +13 -2
- package/src/model/__test__/LikeC4Model.spec.ts +0 -79
- package/src/utils/compare-natural.spec.ts +0 -37
- package/src/utils/fqn.spec.ts +0 -202
- package/src/utils/relations.spec.ts +0 -266
- package/dist/shared/{core.Db3ntVII.cjs → core.D78YmZ_A.cjs} +4 -4
package/src/model/LikeC4Model.ts
CHANGED
|
@@ -1,131 +1,176 @@
|
|
|
1
1
|
import { isString, isTruthy, values } from 'remeda'
|
|
2
2
|
import { nonNullable } from '../errors'
|
|
3
|
-
import type * as c4 from '../types'
|
|
4
3
|
import { DefaultElementShape, DefaultThemeColor } from '../types/element'
|
|
4
|
+
import type {
|
|
5
|
+
Element as C4Element,
|
|
6
|
+
ElementKind as C4ElementKind,
|
|
7
|
+
ElementShape as C4ElementShape,
|
|
8
|
+
Fqn as C4Fqn,
|
|
9
|
+
Tag as C4Tag
|
|
10
|
+
} from '../types/element'
|
|
11
|
+
import type {
|
|
12
|
+
ComputedLikeC4Model as C4ComputedLikeC4Model,
|
|
13
|
+
LayoutedLikeC4Model as C4LayoutedLikeC4Model
|
|
14
|
+
} from '../types/model'
|
|
15
|
+
import type { Relation as C4Relation } from '../types/relation'
|
|
16
|
+
import type { Color as C4Color } from '../types/theme'
|
|
5
17
|
import { ancestorsFqn, commonAncestor, parentFqn } from '../utils/fqn'
|
|
18
|
+
import { LikeC4DiagramModel } from './LikeC4DiagramModel'
|
|
6
19
|
import { LikeC4ViewModel } from './LikeC4ViewModel'
|
|
7
|
-
import
|
|
20
|
+
import { getId } from './types'
|
|
21
|
+
import type { ElementOrFqn, Fqn, IncomingFilter, OutgoingFilter, RelationID, ViewID } from './types'
|
|
8
22
|
|
|
9
|
-
|
|
10
|
-
|
|
23
|
+
type PickBySource<Source> = Source extends LikeC4Model.Layouted.SourceModel ? LikeC4Model.Layouted
|
|
24
|
+
: Source extends LikeC4Model.Computed.SourceModel ? LikeC4Model.Computed
|
|
25
|
+
: never
|
|
11
26
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export class LikeC4Model {
|
|
15
|
-
#elements = new Map<Fqn, LikeC4Model.Element>()
|
|
27
|
+
export class LikeC4Model<M extends LikeC4Model.ViewModel = LikeC4Model.ViewModel> {
|
|
28
|
+
private _elements = new Map<Fqn, LikeC4Model.ElementModel<M>>()
|
|
16
29
|
|
|
17
30
|
// Parent element for given FQN
|
|
18
|
-
|
|
31
|
+
private _parents = new Map<Fqn, LikeC4Model.ElementModel<M>>()
|
|
19
32
|
|
|
20
33
|
// Children elements for given FQN
|
|
21
|
-
|
|
34
|
+
private _children = new Map<Fqn, LikeC4Model.ElementModel<M>[]>()
|
|
22
35
|
|
|
23
|
-
|
|
36
|
+
private _rootElements = new Set<LikeC4Model.ElementModel<M>>()
|
|
24
37
|
|
|
25
|
-
|
|
38
|
+
private _relations = new Map<RelationID, LikeC4Model.Relationship<M>>()
|
|
26
39
|
|
|
27
40
|
// Incoming to an element or its descendants
|
|
28
|
-
|
|
41
|
+
private _incoming = new Map<Fqn, Set<LikeC4Model.Relationship<M>>>()
|
|
29
42
|
|
|
30
43
|
// Outgoing from an element or its descendants
|
|
31
|
-
|
|
44
|
+
private _outgoing = new Map<Fqn, Set<LikeC4Model.Relationship<M>>>()
|
|
32
45
|
|
|
33
46
|
// Relationships inside the element, among descendants
|
|
34
|
-
|
|
47
|
+
private _internal = new Map<Fqn, Set<LikeC4Model.Relationship<M>>>()
|
|
35
48
|
|
|
36
|
-
|
|
49
|
+
private _cacheAscendingSiblings = new Map<Fqn, LikeC4Model.ElementModel<M>[]>()
|
|
37
50
|
|
|
38
|
-
|
|
51
|
+
private _views = new Map<Fqn, M>()
|
|
39
52
|
|
|
40
|
-
static
|
|
41
|
-
|
|
53
|
+
static create(source: LikeC4Model.SourceModel): PickBySource<typeof source> {
|
|
54
|
+
// static create<MM extends LikeC4Model>(source: MM['s']): PickBySource<typeof source> {
|
|
55
|
+
if (source.__ === 'layouted') {
|
|
56
|
+
return LikeC4Model.layouted(source)
|
|
57
|
+
}
|
|
58
|
+
return LikeC4Model.computed(source)
|
|
42
59
|
}
|
|
43
60
|
|
|
44
|
-
|
|
45
|
-
|
|
61
|
+
static computed(source: C4ComputedLikeC4Model): LikeC4Model<LikeC4ViewModel> {
|
|
62
|
+
const instance = new LikeC4Model<LikeC4ViewModel>(
|
|
63
|
+
'computed',
|
|
64
|
+
source,
|
|
65
|
+
values(source.elements),
|
|
66
|
+
values(source.relations)
|
|
67
|
+
)
|
|
68
|
+
for (const view of values(source.views)) {
|
|
69
|
+
instance._views.set(view.id, new LikeC4ViewModel(view, instance))
|
|
70
|
+
}
|
|
71
|
+
return instance
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static layouted(source: C4LayoutedLikeC4Model): LikeC4Model<LikeC4DiagramModel> {
|
|
75
|
+
const instance = new LikeC4Model<LikeC4DiagramModel>(
|
|
76
|
+
'layouted',
|
|
77
|
+
source,
|
|
78
|
+
values(source.elements),
|
|
79
|
+
values(source.relations)
|
|
80
|
+
)
|
|
81
|
+
for (const view of values(source.views)) {
|
|
82
|
+
instance._views.set(view.id, new LikeC4DiagramModel(view, instance))
|
|
83
|
+
}
|
|
84
|
+
return instance
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
protected constructor(
|
|
88
|
+
public readonly type: LikeC4Model.ModelType<M>,
|
|
89
|
+
public readonly sourcemodel: LikeC4Model.SourceModel<M>,
|
|
90
|
+
elements: C4Element[],
|
|
91
|
+
relations: C4Relation[]
|
|
92
|
+
) {
|
|
93
|
+
for (const el of elements) {
|
|
46
94
|
this.addElement(el)
|
|
47
95
|
}
|
|
48
|
-
for (const rel of
|
|
96
|
+
for (const rel of relations) {
|
|
49
97
|
this.addRelation(rel)
|
|
50
98
|
}
|
|
51
|
-
this.#views = new Map(
|
|
52
|
-
values(computed.views).map(v => [v.id, new LikeC4ViewModel(v, this)])
|
|
53
|
-
)
|
|
54
99
|
}
|
|
55
100
|
|
|
56
101
|
/**
|
|
57
102
|
* Returns the root elements of the model.
|
|
58
103
|
*/
|
|
59
|
-
public roots(): ReadonlyArray<LikeC4Model.
|
|
60
|
-
return [...this
|
|
104
|
+
public roots(): ReadonlyArray<LikeC4Model.ElementModel<M>> {
|
|
105
|
+
return [...this._rootElements]
|
|
61
106
|
}
|
|
62
107
|
|
|
63
108
|
/**
|
|
64
109
|
* Returns all elements in the model.
|
|
65
110
|
*/
|
|
66
|
-
public elements(): ReadonlyArray<LikeC4Model.
|
|
67
|
-
return [...this
|
|
111
|
+
public elements(): ReadonlyArray<LikeC4Model.ElementModel<M>> {
|
|
112
|
+
return [...this._elements.values()]
|
|
68
113
|
}
|
|
69
114
|
|
|
70
115
|
/**
|
|
71
116
|
* Returns a specific element by its FQN.
|
|
72
117
|
*/
|
|
73
|
-
public element(id: Fqn): LikeC4Model.
|
|
74
|
-
return nonNullable(this
|
|
118
|
+
public element(id: Fqn): LikeC4Model.ElementModel<M> {
|
|
119
|
+
return nonNullable(this._elements.get(id), `Element ${id} not found`)
|
|
75
120
|
}
|
|
76
121
|
|
|
77
122
|
/**
|
|
78
123
|
* Returns all relationships in the model.
|
|
79
124
|
*/
|
|
80
|
-
public relationships(): ReadonlyArray<LikeC4Model.Relationship
|
|
81
|
-
return [...this
|
|
125
|
+
public relationships(): ReadonlyArray<LikeC4Model.Relationship<M>> {
|
|
126
|
+
return [...this._relations.values()]
|
|
82
127
|
}
|
|
83
128
|
|
|
84
129
|
/**
|
|
85
130
|
* Returns a specific relationship by its ID.
|
|
86
131
|
*/
|
|
87
|
-
public relationship(id: RelationID)
|
|
88
|
-
return nonNullable(this
|
|
132
|
+
public relationship(id: RelationID) {
|
|
133
|
+
return nonNullable(this._relations.get(id), `Relation ${id} not found`)
|
|
89
134
|
}
|
|
90
135
|
|
|
91
136
|
/**
|
|
92
137
|
* Returns all views in the model.
|
|
93
138
|
*/
|
|
94
|
-
public views(): ReadonlyArray<
|
|
95
|
-
return [...this
|
|
139
|
+
public views(): ReadonlyArray<M> {
|
|
140
|
+
return [...this._views.values()]
|
|
96
141
|
}
|
|
97
142
|
|
|
98
143
|
/**
|
|
99
144
|
* Returns a specific view by its ID.
|
|
100
145
|
*/
|
|
101
|
-
public view(viewId: ViewID):
|
|
102
|
-
return nonNullable(this
|
|
146
|
+
public view(viewId: ViewID): M {
|
|
147
|
+
return nonNullable(this._views.get(viewId), `View ${viewId} not found`)
|
|
103
148
|
}
|
|
104
149
|
|
|
105
150
|
/**
|
|
106
151
|
* Returns the parent element of given element.
|
|
107
152
|
* @see ancestors
|
|
108
153
|
*/
|
|
109
|
-
public parent(element: ElementOrFqn): LikeC4Model.
|
|
110
|
-
const id =
|
|
111
|
-
return this
|
|
154
|
+
public parent(element: ElementOrFqn): LikeC4Model.ElementModel<M> | null {
|
|
155
|
+
const id = getId(element)
|
|
156
|
+
return this._parents.get(id) || null
|
|
112
157
|
}
|
|
113
158
|
|
|
114
159
|
/**
|
|
115
160
|
* Get all children of the element (only direct children),
|
|
116
161
|
* @see descendants
|
|
117
162
|
*/
|
|
118
|
-
public children(element: ElementOrFqn): ReadonlyArray<LikeC4Model.
|
|
119
|
-
const id =
|
|
163
|
+
public children(element: ElementOrFqn): ReadonlyArray<LikeC4Model.ElementModel<M>> {
|
|
164
|
+
const id = getId(element)
|
|
120
165
|
return this._childrenOf(id)
|
|
121
166
|
}
|
|
122
167
|
|
|
123
168
|
/**
|
|
124
169
|
* Get all sibling (i.e. same parent)
|
|
125
170
|
*/
|
|
126
|
-
public siblings(element: ElementOrFqn): ReadonlyArray<LikeC4Model.
|
|
127
|
-
const id =
|
|
128
|
-
const parent = this
|
|
171
|
+
public siblings(element: ElementOrFqn): ReadonlyArray<LikeC4Model.ElementModel<M>> {
|
|
172
|
+
const id = getId(element)
|
|
173
|
+
const parent = this._parents.get(id)
|
|
129
174
|
const siblings = parent ? this._childrenOf(parent.id) : this.roots()
|
|
130
175
|
return siblings.filter(e => e.id !== id)
|
|
131
176
|
}
|
|
@@ -134,11 +179,11 @@ export class LikeC4Model {
|
|
|
134
179
|
* Get all ancestor elements (i.e. parent, parent’s parent, etc.)
|
|
135
180
|
* (from closest to root)
|
|
136
181
|
*/
|
|
137
|
-
public ancestors(element: ElementOrFqn): ReadonlyArray<LikeC4Model.
|
|
182
|
+
public ancestors(element: ElementOrFqn): ReadonlyArray<LikeC4Model.ElementModel<M>> {
|
|
138
183
|
let id = isString(element) ? element : element.id
|
|
139
|
-
const result = [] as LikeC4Model.
|
|
184
|
+
const result = [] as LikeC4Model.ElementModel<M>[]
|
|
140
185
|
let parent
|
|
141
|
-
while (parent = this
|
|
186
|
+
while (parent = this._parents.get(id)) {
|
|
142
187
|
result.push(parent)
|
|
143
188
|
id = parent.id
|
|
144
189
|
}
|
|
@@ -148,8 +193,8 @@ export class LikeC4Model {
|
|
|
148
193
|
/**
|
|
149
194
|
* Get all descendant elements (i.e. children, children’s children, etc.)
|
|
150
195
|
*/
|
|
151
|
-
public descendants(element: ElementOrFqn): ReadonlyArray<LikeC4Model.
|
|
152
|
-
const id =
|
|
196
|
+
public descendants(element: ElementOrFqn): ReadonlyArray<LikeC4Model.ElementModel<M>> {
|
|
197
|
+
const id = getId(element)
|
|
153
198
|
const children = this._childrenOf(id)
|
|
154
199
|
return children.flatMap(c => [c, ...this.descendants(c.id)])
|
|
155
200
|
}
|
|
@@ -160,9 +205,9 @@ export class LikeC4Model {
|
|
|
160
205
|
*/
|
|
161
206
|
public incoming(
|
|
162
207
|
element: ElementOrFqn,
|
|
163
|
-
filter:
|
|
164
|
-
): ReadonlyArray<LikeC4Model.Relationship
|
|
165
|
-
const id =
|
|
208
|
+
filter: IncomingFilter = 'all'
|
|
209
|
+
): ReadonlyArray<LikeC4Model.Relationship<M>> {
|
|
210
|
+
const id = getId(element)
|
|
166
211
|
const incoming = Array.from(this._incomingTo(id))
|
|
167
212
|
if (filter === 'all' || incoming.length === 0) {
|
|
168
213
|
return incoming
|
|
@@ -181,8 +226,8 @@ export class LikeC4Model {
|
|
|
181
226
|
*/
|
|
182
227
|
public incomers(
|
|
183
228
|
element: ElementOrFqn,
|
|
184
|
-
filter:
|
|
185
|
-
): ReadonlyArray<LikeC4Model.
|
|
229
|
+
filter: IncomingFilter = 'all'
|
|
230
|
+
): ReadonlyArray<LikeC4Model.ElementModel<M>> {
|
|
186
231
|
return this.incoming(element, filter).map(r => r.source)
|
|
187
232
|
}
|
|
188
233
|
|
|
@@ -192,9 +237,9 @@ export class LikeC4Model {
|
|
|
192
237
|
*/
|
|
193
238
|
public outgoing(
|
|
194
239
|
element: ElementOrFqn,
|
|
195
|
-
filter:
|
|
196
|
-
): ReadonlyArray<LikeC4Model.Relationship
|
|
197
|
-
const id =
|
|
240
|
+
filter: OutgoingFilter = 'all'
|
|
241
|
+
): ReadonlyArray<LikeC4Model.Relationship<M>> {
|
|
242
|
+
const id = getId(element)
|
|
198
243
|
const outgoing = Array.from(this._outgoingFrom(id))
|
|
199
244
|
if (filter === 'all' || outgoing.length === 0) {
|
|
200
245
|
return outgoing
|
|
@@ -212,16 +257,16 @@ export class LikeC4Model {
|
|
|
212
257
|
*/
|
|
213
258
|
public outgoers(
|
|
214
259
|
element: ElementOrFqn,
|
|
215
|
-
filter:
|
|
216
|
-
): ReadonlyArray<LikeC4Model.
|
|
260
|
+
filter: OutgoingFilter = 'all'
|
|
261
|
+
): ReadonlyArray<LikeC4Model.ElementModel<M>> {
|
|
217
262
|
return this.outgoing(element, filter).map(r => r.target)
|
|
218
263
|
}
|
|
219
264
|
|
|
220
265
|
/**
|
|
221
266
|
* Relationships inside the element, among descendants
|
|
222
267
|
*/
|
|
223
|
-
public internal(element: ElementOrFqn): ReadonlyArray<LikeC4Model.Relationship
|
|
224
|
-
const id =
|
|
268
|
+
public internal(element: ElementOrFqn): ReadonlyArray<LikeC4Model.Relationship<M>> {
|
|
269
|
+
const id = getId(element)
|
|
225
270
|
return Array.from(this._internalOf(id))
|
|
226
271
|
}
|
|
227
272
|
|
|
@@ -229,15 +274,15 @@ export class LikeC4Model {
|
|
|
229
274
|
* Resolve siblings of the element and siblings of ancestors
|
|
230
275
|
* (from closest to root)
|
|
231
276
|
*/
|
|
232
|
-
public ascendingSiblings(element: ElementOrFqn): ReadonlyArray<LikeC4Model.
|
|
233
|
-
const id =
|
|
234
|
-
let siblings = this
|
|
277
|
+
public ascendingSiblings(element: ElementOrFqn): ReadonlyArray<LikeC4Model.ElementModel<M>> {
|
|
278
|
+
const id = getId(element)
|
|
279
|
+
let siblings = this._cacheAscendingSiblings.get(id)
|
|
235
280
|
if (!siblings) {
|
|
236
281
|
siblings = [
|
|
237
282
|
...this.siblings(id),
|
|
238
283
|
...this.ancestors(id).flatMap(a => this.siblings(a.id))
|
|
239
284
|
]
|
|
240
|
-
this
|
|
285
|
+
this._cacheAscendingSiblings.set(id, siblings)
|
|
241
286
|
}
|
|
242
287
|
return siblings.slice()
|
|
243
288
|
}
|
|
@@ -245,32 +290,32 @@ export class LikeC4Model {
|
|
|
245
290
|
/**
|
|
246
291
|
* Resolve all views that contain the element
|
|
247
292
|
*/
|
|
248
|
-
public viewsWithElement(element: ElementOrFqn): ReadonlyArray<
|
|
249
|
-
const id =
|
|
250
|
-
return [...this
|
|
293
|
+
public viewsWithElement(element: ElementOrFqn): ReadonlyArray<M> {
|
|
294
|
+
const id = getId(element)
|
|
295
|
+
return [...this._views.values()].filter(v => v.hasElement(id))
|
|
251
296
|
}
|
|
252
297
|
|
|
253
|
-
private addElement(parsed:
|
|
254
|
-
if (this
|
|
298
|
+
private addElement(parsed: C4Element) {
|
|
299
|
+
if (this._elements.has(parsed.id)) {
|
|
255
300
|
throw new Error(`Element ${parsed.id} already exists`)
|
|
256
301
|
}
|
|
257
|
-
const el = new LikeC4Model.
|
|
258
|
-
this
|
|
302
|
+
const el = new LikeC4Model.ElementModel(parsed, this)
|
|
303
|
+
this._elements.set(el.id, el)
|
|
259
304
|
const parentId = parentFqn(el.id)
|
|
260
305
|
if (parentId) {
|
|
261
|
-
this
|
|
306
|
+
this._parents.set(el.id, this.element(parentId))
|
|
262
307
|
this._childrenOf(parentId).push(el)
|
|
263
308
|
} else {
|
|
264
|
-
this
|
|
309
|
+
this._rootElements.add(el)
|
|
265
310
|
}
|
|
266
311
|
}
|
|
267
312
|
|
|
268
|
-
private addRelation(relation:
|
|
269
|
-
if (this
|
|
313
|
+
private addRelation(relation: C4Relation) {
|
|
314
|
+
if (this._relations.has(relation.id)) {
|
|
270
315
|
throw new Error(`Relation ${relation.id} already exists`)
|
|
271
316
|
}
|
|
272
317
|
const rel = new LikeC4Model.Relationship(relation, this)
|
|
273
|
-
this
|
|
318
|
+
this._relations.set(rel.id, rel)
|
|
274
319
|
this._incomingTo(relation.target).add(rel)
|
|
275
320
|
this._outgoingFrom(relation.source).add(rel)
|
|
276
321
|
|
|
@@ -298,47 +343,126 @@ export class LikeC4Model {
|
|
|
298
343
|
}
|
|
299
344
|
|
|
300
345
|
private _childrenOf(id: Fqn) {
|
|
301
|
-
let children = this
|
|
346
|
+
let children = this._children.get(id)
|
|
302
347
|
if (!children) {
|
|
303
348
|
children = []
|
|
304
|
-
this
|
|
349
|
+
this._children.set(id, children)
|
|
305
350
|
}
|
|
306
351
|
return children
|
|
307
352
|
}
|
|
308
353
|
|
|
309
354
|
private _incomingTo(id: Fqn) {
|
|
310
|
-
let incoming = this
|
|
355
|
+
let incoming = this._incoming.get(id)
|
|
311
356
|
if (!incoming) {
|
|
312
|
-
incoming = new
|
|
313
|
-
this
|
|
357
|
+
incoming = new Set()
|
|
358
|
+
this._incoming.set(id, incoming)
|
|
314
359
|
}
|
|
315
360
|
return incoming
|
|
316
361
|
}
|
|
317
362
|
|
|
318
363
|
private _outgoingFrom(id: Fqn) {
|
|
319
|
-
let outgoing = this
|
|
364
|
+
let outgoing = this._outgoing.get(id)
|
|
320
365
|
if (!outgoing) {
|
|
321
|
-
outgoing = new
|
|
322
|
-
this
|
|
366
|
+
outgoing = new Set()
|
|
367
|
+
this._outgoing.set(id, outgoing)
|
|
323
368
|
}
|
|
324
369
|
return outgoing
|
|
325
370
|
}
|
|
326
371
|
|
|
327
372
|
private _internalOf(id: Fqn) {
|
|
328
|
-
let internal = this
|
|
373
|
+
let internal = this._internal.get(id)
|
|
329
374
|
if (!internal) {
|
|
330
|
-
internal = new
|
|
331
|
-
this
|
|
375
|
+
internal = new Set()
|
|
376
|
+
this._internal.set(id, internal)
|
|
332
377
|
}
|
|
333
378
|
return internal
|
|
334
379
|
}
|
|
335
380
|
}
|
|
336
381
|
|
|
337
382
|
export namespace LikeC4Model {
|
|
338
|
-
export
|
|
383
|
+
export function isModel(model: any): model is LikeC4Model {
|
|
384
|
+
return model instanceof LikeC4Model
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export type SourceModel<M extends ViewModel = ViewModel> = M extends LikeC4DiagramModel ? C4LayoutedLikeC4Model
|
|
388
|
+
: C4ComputedLikeC4Model
|
|
389
|
+
|
|
390
|
+
export type ViewModel = LikeC4ViewModel | LikeC4DiagramModel
|
|
391
|
+
export namespace ViewModel {
|
|
392
|
+
export type Relationship = LikeC4Model.Relationship<ViewModel>
|
|
393
|
+
|
|
394
|
+
export function isLayouted(model: ViewModel): model is LikeC4DiagramModel {
|
|
395
|
+
return model instanceof LikeC4DiagramModel
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
export type Computed = LikeC4Model<LikeC4ViewModel>
|
|
400
|
+
export namespace Computed {
|
|
401
|
+
export type ViewModel = LikeC4ViewModel
|
|
402
|
+
export type SourceModel = LikeC4Model.SourceModel<ViewModel>
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
export type Layouted = LikeC4Model<LikeC4DiagramModel>
|
|
406
|
+
export namespace Layouted {
|
|
407
|
+
export type ViewModel = LikeC4DiagramModel
|
|
408
|
+
export type SourceModel = LikeC4Model.SourceModel<ViewModel>
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
export type ModelType<M extends ViewModel = ViewModel> = M extends LikeC4DiagramModel ? 'layouted'
|
|
412
|
+
: M extends LikeC4ViewModel ? 'computed'
|
|
413
|
+
: never
|
|
414
|
+
|
|
415
|
+
export function isLayouted(model: LikeC4Model): model is Layouted {
|
|
416
|
+
return model.type === 'layouted'
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export class Relationship<M extends ViewModel> {
|
|
420
|
+
constructor(
|
|
421
|
+
public readonly relationship: C4Relation,
|
|
422
|
+
private model: LikeC4Model<M>
|
|
423
|
+
) {
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
get id() {
|
|
427
|
+
return this.relationship.id
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
get title() {
|
|
431
|
+
return this.relationship.title
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
get kind() {
|
|
435
|
+
return this.relationship.kind ?? null
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
get tags(): C4Tag[] {
|
|
439
|
+
return this.relationship.tags ?? []
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
get source() {
|
|
443
|
+
return this.model.element(this.relationship.source)
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
get target() {
|
|
447
|
+
return this.model.element(this.relationship.target)
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
public metadata(key: string): string | undefined
|
|
451
|
+
public metadata(key: string, defaultValue: string): string
|
|
452
|
+
public metadata(key: string, defaultValue?: string): string | undefined {
|
|
453
|
+
return this.relationship.metadata?.[key] ?? defaultValue
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
public hasMetadata(key: string): boolean {
|
|
457
|
+
return isTruthy(this.relationship.metadata?.[key])
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// Class renamed to ElementModel, otherwise generated DTS will be incorrect
|
|
462
|
+
export class ElementModel<M extends ViewModel> {
|
|
339
463
|
constructor(
|
|
340
|
-
public readonly element:
|
|
341
|
-
private model: LikeC4Model
|
|
464
|
+
public readonly element: C4Element,
|
|
465
|
+
private model: LikeC4Model<M>
|
|
342
466
|
) {
|
|
343
467
|
}
|
|
344
468
|
|
|
@@ -350,7 +474,7 @@ export namespace LikeC4Model {
|
|
|
350
474
|
return this.element.title
|
|
351
475
|
}
|
|
352
476
|
|
|
353
|
-
get kind() {
|
|
477
|
+
get kind(): C4ElementKind {
|
|
354
478
|
return this.element.kind
|
|
355
479
|
}
|
|
356
480
|
|
|
@@ -362,19 +486,19 @@ export namespace LikeC4Model {
|
|
|
362
486
|
return this.model.children(this).length > 0
|
|
363
487
|
}
|
|
364
488
|
|
|
365
|
-
get shape():
|
|
489
|
+
get shape(): C4ElementShape {
|
|
366
490
|
return this.element.shape ?? DefaultElementShape
|
|
367
491
|
}
|
|
368
492
|
|
|
369
|
-
get color():
|
|
493
|
+
get color(): C4Color {
|
|
370
494
|
return this.element.color ?? DefaultThemeColor
|
|
371
495
|
}
|
|
372
496
|
|
|
373
|
-
get tags():
|
|
497
|
+
get tags(): C4Tag[] {
|
|
374
498
|
return this.element.tags ?? []
|
|
375
499
|
}
|
|
376
500
|
|
|
377
|
-
public parent():
|
|
501
|
+
public parent(): ElementModel<M> | null {
|
|
378
502
|
return this.model.parent(this)
|
|
379
503
|
}
|
|
380
504
|
|
|
@@ -411,19 +535,19 @@ export namespace LikeC4Model {
|
|
|
411
535
|
return this.model.viewsWithElement(this)
|
|
412
536
|
}
|
|
413
537
|
|
|
414
|
-
public incoming(filter?:
|
|
538
|
+
public incoming(filter?: IncomingFilter) {
|
|
415
539
|
return this.model.incoming(this, filter)
|
|
416
540
|
}
|
|
417
541
|
|
|
418
|
-
public incomers(filter?:
|
|
542
|
+
public incomers(filter?: IncomingFilter) {
|
|
419
543
|
return this.model.incomers(this, filter)
|
|
420
544
|
}
|
|
421
545
|
|
|
422
|
-
public outgoing(filter?:
|
|
546
|
+
public outgoing(filter?: OutgoingFilter) {
|
|
423
547
|
return this.model.outgoing(this, filter)
|
|
424
548
|
}
|
|
425
549
|
|
|
426
|
-
public outgoers(filter?:
|
|
550
|
+
public outgoers(filter?: OutgoingFilter) {
|
|
427
551
|
return this.model.outgoers(this, filter)
|
|
428
552
|
}
|
|
429
553
|
|
|
@@ -435,46 +559,4 @@ export namespace LikeC4Model {
|
|
|
435
559
|
// return
|
|
436
560
|
// }
|
|
437
561
|
}
|
|
438
|
-
|
|
439
|
-
export class Relationship {
|
|
440
|
-
constructor(
|
|
441
|
-
public readonly relationship: c4.Relation,
|
|
442
|
-
private model: LikeC4Model
|
|
443
|
-
) {
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
get id() {
|
|
447
|
-
return this.relationship.id
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
get title() {
|
|
451
|
-
return this.relationship.title
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
get kind() {
|
|
455
|
-
return this.relationship.kind ?? null
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
get tags(): c4.Tag[] {
|
|
459
|
-
return this.relationship.tags ?? []
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
get source(): LikeC4Model.Element {
|
|
463
|
-
return this.model.element(this.relationship.source)
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
get target(): LikeC4Model.Element {
|
|
467
|
-
return this.model.element(this.relationship.target)
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
public metadata(key: string): string | undefined
|
|
471
|
-
public metadata(key: string, defaultValue: string): string
|
|
472
|
-
public metadata(key: string, defaultValue?: string): string | undefined {
|
|
473
|
-
return this.relationship.metadata?.[key] ?? defaultValue
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
public hasMetadata(key: string): boolean {
|
|
477
|
-
return isTruthy(this.relationship.metadata?.[key])
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
562
|
}
|