@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.
@@ -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 type { Fqn, RelationID, ViewID } from './types'
20
+ import { getId } from './types'
21
+ import type { ElementOrFqn, Fqn, IncomingFilter, OutgoingFilter, RelationID, ViewID } from './types'
8
22
 
9
- const RelationsSet = Set<LikeC4Model.Relationship>
10
- const MapRelations = Map<Fqn, Set<LikeC4Model.Relationship>>
23
+ type PickBySource<Source> = Source extends LikeC4Model.Layouted.SourceModel ? LikeC4Model.Layouted
24
+ : Source extends LikeC4Model.Computed.SourceModel ? LikeC4Model.Computed
25
+ : never
11
26
 
12
- type ElementOrFqn = Fqn | LikeC4Model.Element
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
- #parents = new Map<Fqn, LikeC4Model.Element>()
31
+ private _parents = new Map<Fqn, LikeC4Model.ElementModel<M>>()
19
32
 
20
33
  // Children elements for given FQN
21
- #children = new Map<Fqn, LikeC4Model.Element[]>()
34
+ private _children = new Map<Fqn, LikeC4Model.ElementModel<M>[]>()
22
35
 
23
- #rootElements = new Set<LikeC4Model.Element>()
36
+ private _rootElements = new Set<LikeC4Model.ElementModel<M>>()
24
37
 
25
- #relations = new Map<RelationID, LikeC4Model.Relationship>()
38
+ private _relations = new Map<RelationID, LikeC4Model.Relationship<M>>()
26
39
 
27
40
  // Incoming to an element or its descendants
28
- #incoming = new MapRelations()
41
+ private _incoming = new Map<Fqn, Set<LikeC4Model.Relationship<M>>>()
29
42
 
30
43
  // Outgoing from an element or its descendants
31
- #outgoing = new MapRelations()
44
+ private _outgoing = new Map<Fqn, Set<LikeC4Model.Relationship<M>>>()
32
45
 
33
46
  // Relationships inside the element, among descendants
34
- #internal = new MapRelations()
47
+ private _internal = new Map<Fqn, Set<LikeC4Model.Relationship<M>>>()
35
48
 
36
- #cacheAscendingSiblings = new Map<Fqn, LikeC4Model.Element[]>()
49
+ private _cacheAscendingSiblings = new Map<Fqn, LikeC4Model.ElementModel<M>[]>()
37
50
 
38
- #views: Map<ViewID, LikeC4ViewModel>
51
+ private _views = new Map<Fqn, M>()
39
52
 
40
- static from(computed: c4.ComputedLikeC4Model): LikeC4Model {
41
- return new LikeC4Model(computed)
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
- protected constructor(protected computed: c4.ComputedLikeC4Model) {
45
- for (const el of values(computed.elements)) {
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 values(computed.relations)) {
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.Element> {
60
- return [...this.#rootElements]
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.Element> {
67
- return [...this.#elements.values()]
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.Element {
74
- return nonNullable(this.#elements.get(id), `Element ${id} not found`)
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.#relations.values()]
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): LikeC4Model.Relationship {
88
- return nonNullable(this.#relations.get(id), `Relation ${id} not found`)
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<LikeC4ViewModel> {
95
- return [...this.#views.values()]
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): LikeC4ViewModel {
102
- return nonNullable(this.#views.get(viewId), `View ${viewId} not found`)
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.Element | null {
110
- const id = isString(element) ? element : element.id
111
- return this.#parents.get(id) || null
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.Element> {
119
- const id = isString(element) ? element : element.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.Element> {
127
- const id = isString(element) ? element : element.id
128
- const parent = this.#parents.get(id)
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.Element> {
182
+ public ancestors(element: ElementOrFqn): ReadonlyArray<LikeC4Model.ElementModel<M>> {
138
183
  let id = isString(element) ? element : element.id
139
- const result = [] as LikeC4Model.Element[]
184
+ const result = [] as LikeC4Model.ElementModel<M>[]
140
185
  let parent
141
- while (parent = this.#parents.get(id)) {
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.Element> {
152
- const id = isString(element) ? element : element.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: 'all' | 'direct' | 'to-descendants' = 'all'
164
- ): ReadonlyArray<LikeC4Model.Relationship> {
165
- const id = isString(element) ? element : element.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: 'all' | 'direct' | 'to-descendants' = 'all'
185
- ): ReadonlyArray<LikeC4Model.Element> {
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: 'all' | 'direct' | 'from-descendants' = 'all'
196
- ): ReadonlyArray<LikeC4Model.Relationship> {
197
- const id = isString(element) ? element : element.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: 'all' | 'direct' | 'from-descendants' = 'all'
216
- ): ReadonlyArray<LikeC4Model.Element> {
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 = isString(element) ? element : element.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.Element> {
233
- const id = isString(element) ? element : element.id
234
- let siblings = this.#cacheAscendingSiblings.get(id)
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.#cacheAscendingSiblings.set(id, siblings)
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<LikeC4ViewModel> {
249
- const id = isString(element) ? element : element.id
250
- return [...this.#views.values()].filter(v => v.hasElement(id))
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: c4.Element) {
254
- if (this.#elements.has(parsed.id)) {
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.Element(parsed, this)
258
- this.#elements.set(el.id, el)
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.#parents.set(el.id, this.element(parentId))
306
+ this._parents.set(el.id, this.element(parentId))
262
307
  this._childrenOf(parentId).push(el)
263
308
  } else {
264
- this.#rootElements.add(el)
309
+ this._rootElements.add(el)
265
310
  }
266
311
  }
267
312
 
268
- private addRelation(relation: c4.Relation) {
269
- if (this.#relations.has(relation.id)) {
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.#relations.set(rel.id, rel)
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.#children.get(id)
346
+ let children = this._children.get(id)
302
347
  if (!children) {
303
348
  children = []
304
- this.#children.set(id, children)
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.#incoming.get(id)
355
+ let incoming = this._incoming.get(id)
311
356
  if (!incoming) {
312
- incoming = new RelationsSet()
313
- this.#incoming.set(id, incoming)
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.#outgoing.get(id)
364
+ let outgoing = this._outgoing.get(id)
320
365
  if (!outgoing) {
321
- outgoing = new RelationsSet()
322
- this.#outgoing.set(id, outgoing)
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.#internal.get(id)
373
+ let internal = this._internal.get(id)
329
374
  if (!internal) {
330
- internal = new RelationsSet()
331
- this.#internal.set(id, internal)
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 class Element {
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: c4.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(): c4.ElementShape {
489
+ get shape(): C4ElementShape {
366
490
  return this.element.shape ?? DefaultElementShape
367
491
  }
368
492
 
369
- get color(): c4.Color {
493
+ get color(): C4Color {
370
494
  return this.element.color ?? DefaultThemeColor
371
495
  }
372
496
 
373
- get tags(): c4.Tag[] {
497
+ get tags(): C4Tag[] {
374
498
  return this.element.tags ?? []
375
499
  }
376
500
 
377
- public parent(): LikeC4Model.Element | null {
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?: 'all' | 'direct' | 'to-descendants') {
538
+ public incoming(filter?: IncomingFilter) {
415
539
  return this.model.incoming(this, filter)
416
540
  }
417
541
 
418
- public incomers(filter?: 'all' | 'direct' | 'to-descendants') {
542
+ public incomers(filter?: IncomingFilter) {
419
543
  return this.model.incomers(this, filter)
420
544
  }
421
545
 
422
- public outgoing(filter?: 'all' | 'direct' | 'from-descendants') {
546
+ public outgoing(filter?: OutgoingFilter) {
423
547
  return this.model.outgoing(this, filter)
424
548
  }
425
549
 
426
- public outgoers(filter?: 'all' | 'direct' | 'from-descendants') {
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
  }