@likec4/core 1.46.4 → 1.48.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.
Files changed (181) hide show
  1. package/LICENSE +1 -1
  2. package/dist/_chunks/Builder.view-element.mjs +3284 -0
  3. package/dist/_chunks/LikeC4Model.d.mts +1287 -0
  4. package/dist/_chunks/LikeC4Styles.mjs +691 -0
  5. package/dist/_chunks/RichText.d.mts +84 -0
  6. package/dist/_chunks/RichText.mjs +148 -0
  7. package/dist/_chunks/_aux.d.mts +289 -0
  8. package/dist/_chunks/_aux.mjs +18 -0
  9. package/dist/_chunks/_types.d.mts +781 -0
  10. package/dist/_chunks/_types2.d.mts +38 -0
  11. package/dist/_chunks/assignTagColors.mjs +24 -0
  12. package/dist/_chunks/calcDriftsFromSnapshot.mjs +379 -0
  13. package/dist/_chunks/connection.mjs +0 -0
  14. package/dist/_chunks/const.d.mts +43 -0
  15. package/dist/_chunks/const.mjs +33 -0
  16. package/dist/_chunks/expression-model.d.mts +192 -0
  17. package/dist/_chunks/expression-model.mjs +103 -0
  18. package/dist/_chunks/expression.d.mts +347 -0
  19. package/dist/_chunks/expression.mjs +107 -0
  20. package/dist/_chunks/find.d.mts +82 -0
  21. package/dist/_chunks/find.mjs +646 -0
  22. package/dist/_chunks/find2.d.mts +78 -0
  23. package/dist/_chunks/find2.mjs +287 -0
  24. package/dist/_chunks/fqnRef.d.mts +58 -0
  25. package/dist/_chunks/fqnRef.mjs +41 -0
  26. package/dist/_chunks/geometry.mjs +335 -0
  27. package/dist/_chunks/index.d.mts +169 -0
  28. package/dist/_chunks/index2.d.mts +937 -0
  29. package/dist/_chunks/index3.d.mts +146 -0
  30. package/dist/_chunks/index4.d.mts +62 -0
  31. package/dist/_chunks/index5.d.mts +42 -0
  32. package/dist/_chunks/index6.d.mts +43 -0
  33. package/dist/{shared/core.OtRNdMxy.d.mts → _chunks/index7.d.mts} +113 -197
  34. package/dist/_chunks/index8.d.mts +144 -0
  35. package/dist/_chunks/invariant.mjs +18 -0
  36. package/dist/_chunks/iterable.mjs +146 -0
  37. package/dist/_chunks/libs/@mantine/colors-generator.mjs +3416 -0
  38. package/dist/_chunks/libs/@ungap/structured-clone.mjs +213 -0
  39. package/dist/_chunks/libs/bail.mjs +14 -0
  40. package/dist/_chunks/libs/ccount.mjs +25 -0
  41. package/dist/_chunks/libs/character-entities-html4.mjs +263 -0
  42. package/dist/_chunks/libs/character-entities-legacy.mjs +117 -0
  43. package/dist/_chunks/libs/character-entities.mjs +2136 -0
  44. package/dist/_chunks/libs/comma-separated-tokens.mjs +18 -0
  45. package/dist/_chunks/libs/decode-named-character-reference.mjs +21 -0
  46. package/dist/_chunks/libs/defu.mjs +42 -0
  47. package/dist/_chunks/libs/devlop.mjs +5 -0
  48. package/dist/_chunks/libs/escape-string-regexp.mjs +8 -0
  49. package/dist/_chunks/libs/extend.mjs +77 -0
  50. package/dist/_chunks/libs/graphology-dag.mjs +703 -0
  51. package/dist/_chunks/libs/graphology-types.d.mts +601 -0
  52. package/dist/_chunks/libs/graphology.d.mts +6 -0
  53. package/dist/_chunks/libs/graphology.mjs +4565 -0
  54. package/dist/_chunks/libs/hast-util-sanitize.mjs +863 -0
  55. package/dist/_chunks/libs/hast-util-to-html.mjs +2696 -0
  56. package/dist/_chunks/libs/is-plain-obj.mjs +9 -0
  57. package/dist/_chunks/libs/longest-streak.mjs +30 -0
  58. package/dist/_chunks/libs/markdown-table.mjs +290 -0
  59. package/dist/_chunks/libs/mdast-util-find-and-replace.mjs +653 -0
  60. package/dist/_chunks/libs/mdast-util-from-markdown.mjs +8522 -0
  61. package/dist/_chunks/libs/mdast-util-gfm.mjs +2393 -0
  62. package/dist/_chunks/libs/mdast-util-to-hast.mjs +1803 -0
  63. package/dist/_chunks/libs/micromark-extension-gfm.mjs +2243 -0
  64. package/dist/_chunks/libs/mnemonist.d.mts +254 -0
  65. package/dist/_chunks/libs/mnemonist.mjs +1978 -0
  66. package/dist/_chunks/libs/natural-compare-lite.mjs +42 -0
  67. package/dist/_chunks/libs/rehype-sanitize.mjs +29 -0
  68. package/dist/_chunks/libs/rehype-stringify.mjs +34 -0
  69. package/dist/_chunks/libs/remark-gfm.mjs +36 -0
  70. package/dist/_chunks/libs/remark-github-blockquote-alert.mjs +100 -0
  71. package/dist/_chunks/libs/remark-parse.mjs +39 -0
  72. package/dist/_chunks/libs/remark-rehype.mjs +171 -0
  73. package/dist/_chunks/libs/remeda.mjs +702 -0
  74. package/dist/_chunks/libs/trough.mjs +158 -0
  75. package/dist/_chunks/libs/unified.mjs +2212 -0
  76. package/dist/_chunks/mnemonist.d.mts +1 -0
  77. package/dist/_chunks/mnemonist.mjs +0 -0
  78. package/dist/_chunks/model.mjs +1898 -0
  79. package/dist/_chunks/model2.mjs +0 -0
  80. package/dist/_chunks/relationships-view.mjs +132 -0
  81. package/dist/_chunks/rolldown-runtime.mjs +42 -0
  82. package/dist/{shared/core.C_3y3eqV.d.mts → _chunks/scalar.d.mts} +13 -43
  83. package/dist/_chunks/scalar.mjs +84 -0
  84. package/dist/_chunks/utils.mjs +483 -0
  85. package/dist/builder/index.d.mts +11 -773
  86. package/dist/builder/index.mjs +631 -978
  87. package/dist/compute-view/index.d.mts +90 -27
  88. package/dist/compute-view/index.mjs +253 -83
  89. package/dist/compute-view/relationships-view/index.d.mts +16 -51
  90. package/dist/compute-view/relationships-view/index.mjs +6 -184
  91. package/dist/geometry/index.d.mts +2 -109
  92. package/dist/geometry/index.mjs +2 -327
  93. package/dist/index.d.mts +18 -20
  94. package/dist/index.mjs +27 -18
  95. package/dist/model/connection/deployment/index.d.mts +12 -15
  96. package/dist/model/connection/deployment/index.mjs +9 -2
  97. package/dist/model/connection/index.d.mts +14 -75
  98. package/dist/model/connection/index.mjs +10 -3
  99. package/dist/model/connection/model/index.d.mts +12 -15
  100. package/dist/model/connection/model/index.mjs +8 -2
  101. package/dist/model/index.d.mts +15 -57
  102. package/dist/model/index.mjs +11 -4
  103. package/dist/styles/index.d.mts +9 -117
  104. package/dist/styles/index.mjs +26 -59
  105. package/dist/types/RichText.d.mts +3 -0
  106. package/dist/types/RichText.mjs +7 -0
  107. package/dist/types/_aux.d.mts +3 -4
  108. package/dist/types/_aux.mjs +2 -7
  109. package/dist/types/expression-model.d.mts +6 -190
  110. package/dist/types/expression-model.mjs +6 -108
  111. package/dist/types/expression.d.mts +5 -6
  112. package/dist/types/expression.mjs +6 -112
  113. package/dist/types/fqnRef.d.mts +4 -60
  114. package/dist/types/fqnRef.mjs +6 -44
  115. package/dist/types/index.d.mts +9 -47
  116. package/dist/types/index.mjs +14 -16
  117. package/dist/types/scalar.d.mts +2 -2
  118. package/dist/types/scalar.mjs +7 -4
  119. package/dist/utils/graphology/index.d.mts +2 -1864
  120. package/dist/utils/graphology/index.mjs +3 -1
  121. package/dist/utils/index.d.mts +11 -124
  122. package/dist/utils/index.mjs +16 -43
  123. package/dist/utils/iterable/index.d.mts +9 -132
  124. package/dist/utils/iterable/index.mjs +2 -61
  125. package/dist/utils/mnemonist.d.mts +2 -0
  126. package/dist/utils/mnemonist.mjs +12 -0
  127. package/package.json +18 -22
  128. package/compute-view/relationships/package.json +0 -4
  129. package/dist/shared/core.3ZhnKAlZ.mjs +0 -106
  130. package/dist/shared/core.78IWAHAE.mjs +0 -332
  131. package/dist/shared/core.B85MJLTf.mjs +0 -5
  132. package/dist/shared/core.BFd1lU9R.mjs +0 -29
  133. package/dist/shared/core.BKlholso.mjs +0 -3
  134. package/dist/shared/core.BPGOjone.d.mts +0 -46
  135. package/dist/shared/core.BYdtmqY5.mjs +0 -1255
  136. package/dist/shared/core.BZCgljZd.d.mts +0 -83
  137. package/dist/shared/core.BbE4y-yl.mjs +0 -177
  138. package/dist/shared/core.BhNcrwzK.mjs +0 -7
  139. package/dist/shared/core.BkVA6gjl.mjs +0 -5
  140. package/dist/shared/core.BoYfZOBm.mjs +0 -3
  141. package/dist/shared/core.BsSXS-_R.mjs +0 -7
  142. package/dist/shared/core.BspBF3SJ.mjs +0 -3944
  143. package/dist/shared/core.BvPm_-u3.d.mts +0 -334
  144. package/dist/shared/core.C-Jdx7xo.d.mts +0 -1263
  145. package/dist/shared/core.C3JowhaZ.mjs +0 -32
  146. package/dist/shared/core.C4x8aaWa.mjs +0 -27
  147. package/dist/shared/core.CBLX4mT8.mjs +0 -28411
  148. package/dist/shared/core.CLSZtnFh.mjs +0 -69
  149. package/dist/shared/core.CRhT4Iio.mjs +0 -785
  150. package/dist/shared/core.CbT8JVYL.mjs +0 -5
  151. package/dist/shared/core.CdNCAwq7.mjs +0 -176
  152. package/dist/shared/core.ClTP6-TN.d.mts +0 -87
  153. package/dist/shared/core.CmGY9blO.mjs +0 -6717
  154. package/dist/shared/core.CmPXpJ8l.mjs +0 -21
  155. package/dist/shared/core.Coi_LOUZ.mjs +0 -7
  156. package/dist/shared/core.CqAJJpK_.mjs +0 -3
  157. package/dist/shared/core.Ctj2S3bD.d.mts +0 -466
  158. package/dist/shared/core.CywrQs86.d.mts +0 -31
  159. package/dist/shared/core.D00YbOhQ.d.mts +0 -300
  160. package/dist/shared/core.D0WZutNd.mjs +0 -94
  161. package/dist/shared/core.D4npX2q8.mjs +0 -18
  162. package/dist/shared/core.DB0Ue5Wx.d.mts +0 -70
  163. package/dist/shared/core.DEK-BO3_.mjs +0 -1206
  164. package/dist/shared/core.DH7TXqXf.mjs +0 -136
  165. package/dist/shared/core.DRJma0Ol.mjs +0 -22
  166. package/dist/shared/core.DSalPD6v.mjs +0 -1352
  167. package/dist/shared/core.DVfPJPJj.mjs +0 -2200
  168. package/dist/shared/core.DXhDWKFZ.d.mts +0 -3
  169. package/dist/shared/core.DbfO90vF.mjs +0 -434
  170. package/dist/shared/core.DcS-0zys.mjs +0 -10
  171. package/dist/shared/core.DeDCYTDR.d.mts +0 -98
  172. package/dist/shared/core.DpKY_3NF.d.mts +0 -504
  173. package/dist/shared/core.Dt0v3djy.d.mts +0 -41
  174. package/dist/shared/core.FZ305VYd.mjs +0 -21
  175. package/dist/shared/core.RfnaEmgA.mjs +0 -7
  176. package/dist/shared/core.oSV6SRfk.mjs +0 -13
  177. package/dist/shared/core.om36dXXW.mjs +0 -41
  178. package/dist/shared/core.q10OP9oJ.mjs +0 -5
  179. package/dist/shared/core.uFk_o9X6.mjs +0 -13
  180. package/dist/shared/core.xeuDd__E.mjs +0 -300
  181. package/dist/shared/core.xgoPk2RG.mjs +0 -4989
@@ -1,1009 +1,662 @@
1
- import { d as defu } from '../shared/core.CLSZtnFh.mjs';
2
- import { t as t$1, a as t$7 } from '../shared/core.BsSXS-_R.mjs';
3
- import { t as t$5 } from '../shared/core.Coi_LOUZ.mjs';
4
- import { t as t$6 } from '../shared/core.BspBF3SJ.mjs';
5
- import { k as e } from '../shared/core.om36dXXW.mjs';
6
- import { e as e$3 } from '../shared/core.DRJma0Ol.mjs';
7
- import { a as _type, u as e$2, _ as _stage, d as isDeployedInstance, p as isElementView } from '../shared/core.DH7TXqXf.mjs';
8
- import { t as t$2 } from '../shared/core.CbT8JVYL.mjs';
9
- import { a as t$4, c as computeLikeC4Model } from '../shared/core.xgoPk2RG.mjs';
10
- import { t as t$3 } from '../shared/core.DSalPD6v.mjs';
11
- import { assignTagColors } from '../styles/index.mjs';
12
- import { n as nameFromFqn, d as isSameHierarchy, p as parentFqn } from '../shared/core.CdNCAwq7.mjs';
13
- import { e as e$1 } from '../shared/core.CqAJJpK_.mjs';
14
- import { ModelFqnExpr } from '../types/expression-model.mjs';
15
- import { i as invariant } from '../shared/core.D4npX2q8.mjs';
16
- import { e as exact } from '../shared/core.DEK-BO3_.mjs';
17
- import { FqnRef } from '../types/fqnRef.mjs';
18
-
19
- function t(...t){return t$1(Object.fromEntries,t)}
1
+ import { C as t$5, H as t$1, J as n, O as e, P as e$3, Q as t$6, S as t$7, U as t$4, Y as t$2, Z as t$3, j as e$2, w as t, z as e$1 } from "../_chunks/libs/remeda.mjs";
2
+ import { A as isDeployedInstance, I as exact, N as _stage, P as _type, g as isElementView } from "../_chunks/LikeC4Styles.mjs";
3
+ import "../_chunks/libs/natural-compare-lite.mjs";
4
+ import { D as parentFqn, E as nameFromFqn, T as isSameHierarchy } from "../_chunks/utils.mjs";
5
+ import { t as invariant } from "../_chunks/invariant.mjs";
6
+ import { t as assignTagColors } from "../_chunks/assignTagColors.mjs";
7
+ import "../_chunks/libs/@mantine/colors-generator.mjs";
8
+ import "../_chunks/libs/graphology-dag.mjs";
9
+ import { n as import_default_map } from "../_chunks/libs/mnemonist.mjs";
10
+ import { t as defu } from "../_chunks/libs/defu.mjs";
11
+ import "../_chunks/libs/extend.mjs";
12
+ import { m as isGlobalFqn, v as splitGlobalFqn } from "../_chunks/scalar.mjs";
13
+ import { t as FqnRef } from "../_chunks/fqnRef.mjs";
14
+ import { n as ModelFqnExpr } from "../_chunks/expression-model.mjs";
15
+ import { n as computeLikeC4Model, t as $expr } from "../_chunks/Builder.view-element.mjs";
16
+ import "../_chunks/libs/graphology.mjs";
20
17
 
18
+ //#region src/builder/Builder.view-common.ts
21
19
  function parseWhere(where) {
22
- if (e$1(where)) {
23
- const op = where;
24
- switch (true) {
25
- case op.startsWith("tag is not #"):
26
- return {
27
- tag: {
28
- neq: op.replace("tag is not #", "")
29
- }
30
- };
31
- case op.startsWith("tag is #"):
32
- return {
33
- tag: {
34
- eq: op.replace("tag is #", "")
35
- }
36
- };
37
- case op.startsWith("kind is not "):
38
- return {
39
- kind: {
40
- neq: op.replace("kind is not ", "")
41
- }
42
- };
43
- case op.startsWith("kind is "):
44
- return {
45
- kind: {
46
- eq: op.replace("kind is ", "")
47
- }
48
- };
49
- case op.startsWith("source."):
50
- return {
51
- operator: parseWhere(
52
- op.replace("source.", "")
53
- ),
54
- participant: "source"
55
- };
56
- case op.startsWith("target."):
57
- return {
58
- operator: parseWhere(
59
- op.replace("target.", "")
60
- ),
61
- participant: "target"
62
- };
63
- default:
64
- throw new Error(`Unknown where operator: ${where}`);
65
- }
66
- }
67
- if (where.and) {
68
- return {
69
- and: t$2(where.and, parseWhere)
70
- };
71
- }
72
- if (where.or) {
73
- return {
74
- or: t$2(where.or, parseWhere)
75
- };
76
- }
77
- if (where.not) {
78
- return {
79
- not: parseWhere(where.not)
80
- };
81
- }
82
- throw new Error(`Unknown where operator: ${where}`);
20
+ if (e(where)) {
21
+ const op = where;
22
+ switch (true) {
23
+ case op.startsWith("tag is not #"): return { tag: { neq: op.replace("tag is not #", "") } };
24
+ case op.startsWith("tag is #"): return { tag: { eq: op.replace("tag is #", "") } };
25
+ case op.startsWith("kind is not "): return { kind: { neq: op.replace("kind is not ", "") } };
26
+ case op.startsWith("kind is "): return { kind: { eq: op.replace("kind is ", "") } };
27
+ case op.startsWith("source."): return {
28
+ operator: parseWhere(op.replace("source.", "")),
29
+ participant: "source"
30
+ };
31
+ case op.startsWith("target."): return {
32
+ operator: parseWhere(op.replace("target.", "")),
33
+ participant: "target"
34
+ };
35
+ default: throw new Error(`Unknown where operator: ${where}`);
36
+ }
37
+ }
38
+ if (where.and) return { and: t(where.and, parseWhere) };
39
+ if (where.or) return { or: t(where.or, parseWhere) };
40
+ if (where.not) return { not: parseWhere(where.not) };
41
+ throw new Error(`Unknown where operator: ${where}`);
83
42
  }
84
43
  function $include(...args) {
85
- return (b) => {
86
- let expr = b.$expr(args[0]);
87
- if (args.length === 2) {
88
- const condition = args[1].where ? parseWhere(args[1].where) : void 0;
89
- if (condition) {
90
- expr = {
91
- where: {
92
- expr,
93
- condition
94
- }
95
- };
96
- }
97
- const custom = args[1].with;
98
- if (custom) {
99
- const isElement = ModelFqnExpr.is(expr);
100
- if (isElement) {
101
- expr = {
102
- custom: {
103
- ...custom,
104
- expr
105
- }
106
- };
107
- } else {
108
- expr = {
109
- customRelation: {
110
- ...custom,
111
- expr
112
- }
113
- };
114
- }
115
- }
116
- }
117
- b.include(expr);
118
- return b;
119
- };
44
+ return (b) => {
45
+ let expr = b.$expr(args[0]);
46
+ if (args.length === 2) {
47
+ const condition = args[1].where ? parseWhere(args[1].where) : void 0;
48
+ if (condition) expr = { where: {
49
+ expr,
50
+ condition
51
+ } };
52
+ const custom = args[1].with;
53
+ if (custom) if (ModelFqnExpr.is(expr)) expr = { custom: {
54
+ ...custom,
55
+ expr
56
+ } };
57
+ else expr = { customRelation: {
58
+ ...custom,
59
+ expr
60
+ } };
61
+ }
62
+ b.include(expr);
63
+ return b;
64
+ };
120
65
  }
121
66
  function $exclude(...args) {
122
- return (b) => {
123
- let expr = b.$expr(args[0]);
124
- if (args.length === 2 && args[1].where) {
125
- const condition = parseWhere(args[1].where);
126
- expr = {
127
- where: {
128
- expr,
129
- condition
130
- }
131
- };
132
- }
133
- b.exclude(expr);
134
- return b;
135
- };
67
+ return (b) => {
68
+ let expr = b.$expr(args[0]);
69
+ if (args.length === 2 && args[1].where) {
70
+ const condition = parseWhere(args[1].where);
71
+ expr = { where: {
72
+ expr,
73
+ condition
74
+ } };
75
+ }
76
+ b.exclude(expr);
77
+ return b;
78
+ };
136
79
  }
80
+ /**
81
+ * @example
82
+ * builder.views(({ view, $style }, _) =>
83
+ * _(
84
+ * view('view1').with(
85
+ * $style('*', {
86
+ * color: 'red',
87
+ * }),
88
+ * $style(['bob', 'alice'], {
89
+ * color: 'blue',
90
+ * }),
91
+ * ),
92
+ * )
93
+ * )
94
+ */
137
95
  function $style(element, { notation, ...style }) {
138
- return (b) => b.style({
139
- targets: (e(element) ? element : [element]).map((e) => b.$expr(e)),
140
- ...notation ? { notation } : {},
141
- style: {
142
- ...style
143
- }
144
- });
96
+ return (b) => b.style({
97
+ targets: (e$1(element) ? element : [element]).map((e) => b.$expr(e)),
98
+ ...notation ? { notation } : {},
99
+ style: { ...style }
100
+ });
145
101
  }
146
102
  function $autoLayout(layout) {
147
- return (b) => b.autoLayout(layout);
103
+ return (b) => b.autoLayout(layout);
148
104
  }
149
105
  function $rules(...rules) {
150
- return (b) => rules.reduce((b2, rule) => rule(b2), b);
106
+ return (b) => rules.reduce((b, rule) => rule(b), b);
151
107
  }
152
108
 
109
+ //#endregion
110
+ //#region src/builder/Builder.view-deployment.ts
153
111
  function $deploymentExpr(expr) {
154
- if (!e$1(expr)) {
155
- return expr;
156
- }
157
- const asTypedDeploymentExpression = (expr2) => {
158
- return expr2;
159
- };
160
- if (expr === "*") {
161
- return asTypedDeploymentExpression({ wildcard: true });
162
- }
163
- if (expr.startsWith("->")) {
164
- if (expr.endsWith("->")) {
165
- return asTypedDeploymentExpression({
166
- inout: $deploymentExpr(expr.replace(/->/g, "").trim())
167
- });
168
- }
169
- return asTypedDeploymentExpression({
170
- incoming: $deploymentExpr(expr.replace("-> ", ""))
171
- });
172
- }
173
- if (expr.endsWith(" ->")) {
174
- return asTypedDeploymentExpression({
175
- outgoing: $deploymentExpr(expr.replace(" ->", ""))
176
- });
177
- }
178
- if (expr.includes(" <-> ")) {
179
- const [source, target] = expr.split(" <-> ");
180
- return asTypedDeploymentExpression({
181
- source: $deploymentExpr(source),
182
- target: $deploymentExpr(target),
183
- isBidirectional: true
184
- });
185
- }
186
- if (expr.includes(" -> ")) {
187
- const [source, target] = expr.split(" -> ");
188
- return asTypedDeploymentExpression({
189
- source: $deploymentExpr(source),
190
- target: $deploymentExpr(target)
191
- });
192
- }
193
- if (expr.endsWith("._")) {
194
- return asTypedDeploymentExpression({
195
- ref: {
196
- deployment: expr.replace("._", "")
197
- },
198
- selector: "expanded"
199
- });
200
- }
201
- if (expr.endsWith(".**")) {
202
- return asTypedDeploymentExpression({
203
- ref: {
204
- deployment: expr.replace(".**", "")
205
- },
206
- selector: "descendants"
207
- });
208
- }
209
- if (expr.endsWith(".*")) {
210
- return asTypedDeploymentExpression({
211
- ref: {
212
- deployment: expr.replace(".*", "")
213
- },
214
- selector: "children"
215
- });
216
- }
217
- return asTypedDeploymentExpression({
218
- ref: {
219
- deployment: expr
220
- }
221
- });
222
- }
223
-
224
- const asTypedExpr = (expr) => {
225
- return expr;
226
- };
227
- function $expr(expr) {
228
- if (!e$1(expr)) {
229
- return expr;
230
- }
231
- if (expr === "*") {
232
- return asTypedExpr({ wildcard: true });
233
- }
234
- if (expr.startsWith("->")) {
235
- if (expr.endsWith("->")) {
236
- return asTypedExpr({
237
- inout: $expr(expr.replace(/->/g, "").trim())
238
- });
239
- }
240
- return asTypedExpr({
241
- incoming: $expr(expr.replace("-> ", ""))
242
- });
243
- }
244
- if (expr.endsWith(" ->")) {
245
- return asTypedExpr({
246
- outgoing: $expr(expr.replace(" ->", ""))
247
- });
248
- }
249
- if (expr.includes(" <-> ")) {
250
- const [source, target] = expr.split(" <-> ");
251
- return asTypedExpr({
252
- source: $expr(source),
253
- target: $expr(target),
254
- isBidirectional: true
255
- });
256
- }
257
- if (expr.includes(" -> ")) {
258
- const [source, target] = expr.split(" -> ");
259
- return asTypedExpr({
260
- source: $expr(source),
261
- target: $expr(target)
262
- });
263
- }
264
- if (expr.endsWith("._")) {
265
- return asTypedExpr({
266
- ref: {
267
- model: expr.replace("._", "")
268
- },
269
- selector: "expanded"
270
- });
271
- }
272
- if (expr.endsWith(".**")) {
273
- return asTypedExpr({
274
- ref: {
275
- model: expr.replace(".**", "")
276
- },
277
- selector: "descendants"
278
- });
279
- }
280
- if (expr.endsWith(".*")) {
281
- return asTypedExpr({
282
- ref: {
283
- model: expr.replace(".*", "")
284
- },
285
- selector: "children"
286
- });
287
- }
288
- return asTypedExpr({
289
- ref: {
290
- model: expr
291
- }
292
- });
112
+ if (!e(expr)) return expr;
113
+ const asTypedDeploymentExpression = (expr) => {
114
+ return expr;
115
+ };
116
+ if (expr === "*") return asTypedDeploymentExpression({ wildcard: true });
117
+ if (expr.startsWith("->")) {
118
+ if (expr.endsWith("->")) return asTypedDeploymentExpression({ inout: $deploymentExpr(expr.replace(/->/g, "").trim()) });
119
+ return asTypedDeploymentExpression({ incoming: $deploymentExpr(expr.replace("-> ", "")) });
120
+ }
121
+ if (expr.endsWith(" ->")) return asTypedDeploymentExpression({ outgoing: $deploymentExpr(expr.replace(" ->", "")) });
122
+ if (expr.includes(" <-> ")) {
123
+ const [source, target] = expr.split(" <-> ");
124
+ return asTypedDeploymentExpression({
125
+ source: $deploymentExpr(source),
126
+ target: $deploymentExpr(target),
127
+ isBidirectional: true
128
+ });
129
+ }
130
+ if (expr.includes(" -> ")) {
131
+ const [source, target] = expr.split(" -> ");
132
+ return asTypedDeploymentExpression({
133
+ source: $deploymentExpr(source),
134
+ target: $deploymentExpr(target)
135
+ });
136
+ }
137
+ if (expr.endsWith("._")) return asTypedDeploymentExpression({
138
+ ref: { deployment: expr.replace("._", "") },
139
+ selector: "expanded"
140
+ });
141
+ if (expr.endsWith(".**")) return asTypedDeploymentExpression({
142
+ ref: { deployment: expr.replace(".**", "") },
143
+ selector: "descendants"
144
+ });
145
+ if (expr.endsWith(".*")) return asTypedDeploymentExpression({
146
+ ref: { deployment: expr.replace(".*", "") },
147
+ selector: "children"
148
+ });
149
+ return asTypedDeploymentExpression({ ref: { deployment: expr } });
293
150
  }
294
151
 
152
+ //#endregion
153
+ //#region src/builder/Builder.views.ts
295
154
  function mkViewBuilder(view) {
296
- const viewBuilder = {
297
- $expr: view[_type] === "deployment" ? $deploymentExpr : $expr,
298
- autoLayout(autoLayout) {
299
- view.rules.push({
300
- direction: autoLayout
301
- });
302
- return viewBuilder;
303
- },
304
- exclude(expr) {
305
- view.rules.push({
306
- exclude: [expr]
307
- });
308
- return viewBuilder;
309
- },
310
- include(expr) {
311
- view.rules.push({
312
- include: [expr]
313
- });
314
- return viewBuilder;
315
- },
316
- style(rule) {
317
- view.rules.push(rule);
318
- return viewBuilder;
319
- }
320
- // title(title: string) {
321
- // view.title = title
322
- // return viewBuilder
323
- // },
324
- // description(description: string) {
325
- // view.description = description
326
- // return viewBuilder
327
- // }
328
- };
329
- return viewBuilder;
155
+ const viewBuilder = {
156
+ $expr: view[_type] === "deployment" ? $deploymentExpr : $expr,
157
+ autoLayout(autoLayout) {
158
+ view.rules.push({ direction: autoLayout });
159
+ return viewBuilder;
160
+ },
161
+ exclude(expr) {
162
+ view.rules.push({ exclude: [expr] });
163
+ return viewBuilder;
164
+ },
165
+ include(expr) {
166
+ view.rules.push({ include: [expr] });
167
+ return viewBuilder;
168
+ },
169
+ style(rule) {
170
+ view.rules.push(rule);
171
+ return viewBuilder;
172
+ }
173
+ };
174
+ return viewBuilder;
330
175
  }
331
176
 
177
+ //#endregion
178
+ //#region src/builder/Builder.ts
332
179
  function ensureObj(value) {
333
- return e(value) ? t$6(value, (_) => ({})) : value;
180
+ return e$1(value) ? t$1(value, (_) => ({})) : value;
334
181
  }
335
182
  function validateSpec({ tags, elements, deployments, relationships, ...specification }) {
336
- const spectags = {};
337
- if (tags) {
338
- Object.assign(
339
- spectags,
340
- ensureObj(tags)
341
- );
342
- }
343
- const _elements = ensureObj(elements);
344
- for (const [kind, spec] of t$5(_elements)) {
345
- if (spec.tags) {
346
- for (const tag of spec.tags) {
347
- invariant(tag in spectags, `Invalid specification for element kind "${kind}": tag "${tag}" not found`);
348
- }
349
- }
350
- }
351
- const _deployments = ensureObj(deployments ?? {});
352
- for (const [kind, spec] of t$5(_deployments)) {
353
- if (spec.tags) {
354
- for (const tag of spec.tags) {
355
- invariant(
356
- tag in spectags,
357
- `Invalid specification for deployment kind "${kind}": tag "${tag}" not found`
358
- );
359
- }
360
- }
361
- }
362
- return {
363
- ...specification,
364
- tags: spectags,
365
- elements: _elements,
366
- deployments: _deployments,
367
- relationships: ensureObj(relationships ?? {})
368
- };
183
+ const spectags = {};
184
+ if (tags) Object.assign(spectags, ensureObj(tags));
185
+ const _elements = ensureObj(elements);
186
+ for (const [kind, spec] of t$2(_elements)) if (spec.tags) for (const tag of spec.tags) invariant(tag in spectags, `Invalid specification for element kind "${kind}": tag "${tag}" not found`);
187
+ const _deployments = ensureObj(deployments ?? {});
188
+ for (const [kind, spec] of t$2(_deployments)) if (spec.tags) for (const tag of spec.tags) invariant(tag in spectags, `Invalid specification for deployment kind "${kind}": tag "${tag}" not found`);
189
+ return {
190
+ ...specification,
191
+ tags: spectags,
192
+ elements: _elements,
193
+ deployments: _deployments,
194
+ relationships: ensureObj(relationships ?? {})
195
+ };
369
196
  }
370
197
  function toMarkdownOrString(input) {
371
- if (e$2(input)) {
372
- return null;
373
- }
374
- if (typeof input === "string") {
375
- return { txt: input };
376
- }
377
- return input;
198
+ if (e$2(input)) return null;
199
+ if (typeof input === "string") return { txt: input };
200
+ return input;
378
201
  }
379
202
  function builder(_spec, _elements = /* @__PURE__ */ new Map(), _relations = [], _views = /* @__PURE__ */ new Map(), _globals = {
380
- predicates: {},
381
- dynamicPredicates: {},
382
- styles: {}
383
- }, _deployments = /* @__PURE__ */ new Map(), _deploymentRelations = []) {
384
- const spec = validateSpec(_spec);
385
- const toLikeC4Specification = () => {
386
- return {
387
- elements: structuredClone(spec.elements),
388
- deployments: structuredClone(spec.deployments),
389
- relationships: structuredClone(spec.relationships),
390
- tags: assignTagColors(structuredClone(spec.tags)),
391
- ...spec.metadataKeys ? { metadataKeys: spec.metadataKeys } : {},
392
- customColors: {}
393
- };
394
- };
395
- const mapLinks = (links) => {
396
- if (!links || !t$7(links, 1)) {
397
- return void 0;
398
- }
399
- return t$2(links, (l) => typeof l === "string" ? { url: l } : l);
400
- };
401
- const createGenericView = (id, _props, builder2) => {
402
- if (e$3(_props)) {
403
- builder2 = _props;
404
- _props = {};
405
- }
406
- _props ??= {};
407
- const {
408
- links: _links = [],
409
- title = null,
410
- description = null,
411
- tags = [],
412
- ...props
413
- } = typeof _props === "string" ? { title: _props } : { ..._props };
414
- const links = mapLinks(_links);
415
- return [
416
- exact({
417
- id,
418
- title,
419
- description: toMarkdownOrString(description),
420
- tags,
421
- links,
422
- _stage: "parsed",
423
- ...props
424
- }),
425
- builder2
426
- ];
427
- };
428
- const self = {
429
- get Types() {
430
- throw new Error("Types are not available in runtime");
431
- },
432
- clone: () => {
433
- return builder(
434
- structuredClone(spec),
435
- structuredClone(_elements),
436
- structuredClone(_relations),
437
- structuredClone(_views),
438
- structuredClone(_globals),
439
- structuredClone(_deployments),
440
- structuredClone(_deploymentRelations)
441
- );
442
- },
443
- __addElement: (element) => {
444
- const parent = parentFqn(element.id);
445
- if (parent) {
446
- invariant(
447
- _elements.get(parent),
448
- `Parent element with id "${parent}" not found for element with id "${element.id}"`
449
- );
450
- }
451
- if (_elements.has(element.id)) {
452
- throw new Error(`Element with id "${element.id}" already exists`);
453
- }
454
- _elements.set(element.id, element);
455
- return self;
456
- },
457
- __addRelation(relation) {
458
- const sourceEl = _elements.get(FqnRef.flatten(relation.source));
459
- invariant(sourceEl, `Element with id "${relation.source.model}" not found`);
460
- const targetEl = _elements.get(FqnRef.flatten(relation.target));
461
- invariant(targetEl, `Element with id "${relation.target.model}" not found`);
462
- invariant(
463
- !isSameHierarchy(sourceEl, targetEl),
464
- "Cannot create relationship between elements in the same hierarchy"
465
- );
466
- _relations.push({
467
- id: `rel${_relations.length + 1}`,
468
- ...relation
469
- });
470
- return self;
471
- },
472
- __fqn(id) {
473
- invariant(id.trim() !== "", "Id must be non-empty");
474
- return id;
475
- },
476
- __deploymentFqn(id) {
477
- invariant(id.trim() !== "", "Id must be non-empty");
478
- return id;
479
- },
480
- __addSourcelessRelation() {
481
- throw new Error("Can be called only in nested model");
482
- },
483
- __addView: (view) => {
484
- if (_views.has(view.id)) {
485
- throw new Error(`View with id "${view.id}" already exists`);
486
- }
487
- if (isElementView(view) && "viewOf" in view) {
488
- invariant(
489
- _elements.get(view.viewOf),
490
- `Invalid scoped view ${view.id}, wlement with id "${view.viewOf}" not found`
491
- );
492
- }
493
- _views.set(view.id, view);
494
- return self;
495
- },
496
- __addDeployment: (node) => {
497
- if (_deployments.has(node.id)) {
498
- throw new Error(`Deployment with id "${node.id}" already exists`);
499
- }
500
- const parent = parentFqn(node.id);
501
- if (parent) {
502
- invariant(
503
- _deployments.get(parent),
504
- `Parent element with id "${parent}" not found for node with id "${node.id}"`
505
- );
506
- }
507
- if (isDeployedInstance(node)) {
508
- invariant(parent, `Instance ${node.id} of ${node.element} must be deployed under a parent node`);
509
- invariant(
510
- _elements.get(node.element),
511
- `Instance "${node.id}" references non-existing element "${node.element}"`
512
- );
513
- }
514
- _deployments.set(node.id, node);
515
- return self;
516
- },
517
- __addDeploymentRelation: (relation) => {
518
- invariant(
519
- !isSameHierarchy(relation.source.deployment, relation.target.deployment),
520
- "Cannot create relationship between elements in the same hierarchy"
521
- );
522
- invariant(
523
- _deployments.has(relation.source.deployment),
524
- `Relation "${relation.source.deployment} -> ${relation.target.deployment}" references non-existing source`
525
- );
526
- invariant(
527
- _deployments.has(relation.target.deployment),
528
- `Relation "${relation.source.deployment} -> ${relation.target.deployment}" references non-existing target`
529
- );
530
- _deploymentRelations.push({
531
- id: `deploy_rel${_deploymentRelations.length + 1}`,
532
- ...relation
533
- });
534
- return self;
535
- },
536
- build: (project) => ({
537
- [_stage]: "parsed",
538
- projectId: project?.id ?? "from-builder",
539
- project: {
540
- id: "from-builder",
541
- ...project
542
- },
543
- specification: toLikeC4Specification(),
544
- elements: t(
545
- structuredClone(
546
- Array.from(_elements.entries())
547
- )
548
- ),
549
- relations: t$4(_relations, (r) => [r.id, structuredClone(r)]),
550
- globals: structuredClone(_globals),
551
- deployments: {
552
- elements: t(
553
- structuredClone(
554
- Array.from(_deployments.entries())
555
- )
556
- ),
557
- relations: t$4(_deploymentRelations, (r) => [r.id, structuredClone(r)])
558
- },
559
- views: t(
560
- structuredClone(
561
- Array.from(_views.entries())
562
- )
563
- ),
564
- imports: {}
565
- }),
566
- toLikeC4Model: (project) => {
567
- const parsed = self.build(project);
568
- return computeLikeC4Model(parsed);
569
- },
570
- helpers: () => ({
571
- model: {
572
- model: (...ops) => {
573
- return (b) => {
574
- return ops.reduce((b2, op) => op(b2), b);
575
- };
576
- },
577
- rel: (source, target, _props) => {
578
- return (b) => {
579
- const {
580
- title = "",
581
- links: _links = [],
582
- description = null,
583
- notes = null,
584
- ...props
585
- } = defu(
586
- typeof _props === "string" ? { title: _props } : { ..._props },
587
- { title: null, links: null }
588
- );
589
- const links = mapLinks(_links);
590
- b.__addRelation(exact({
591
- source: {
592
- model: source
593
- },
594
- target: {
595
- model: target
596
- },
597
- title,
598
- ...description && { description: toMarkdownOrString(description) },
599
- ...notes && { notes: toMarkdownOrString(notes) },
600
- links,
601
- ...props
602
- }));
603
- return b;
604
- };
605
- },
606
- relTo: (target, _props) => {
607
- return (b) => {
608
- const {
609
- title = "",
610
- links,
611
- description = null,
612
- notes = null,
613
- ...props
614
- } = defu(
615
- typeof _props === "string" ? { title: _props } : { ..._props },
616
- { title: null, links: null }
617
- );
618
- b.__addSourcelessRelation(exact({
619
- target: {
620
- model: target
621
- },
622
- title,
623
- ...description && { description: toMarkdownOrString(description) },
624
- ...notes && { notes: toMarkdownOrString(notes) },
625
- links: mapLinks(links),
626
- ...props
627
- }));
628
- return b;
629
- };
630
- },
631
- ...t$3(
632
- spec.elements,
633
- ({ style: specStyle, ...spec2 }, kind) => (id, _props) => {
634
- const add = ((b) => {
635
- const {
636
- links,
637
- icon: _icon,
638
- color,
639
- shape,
640
- style,
641
- title,
642
- description,
643
- summary,
644
- ...props
645
- } = typeof _props === "string" ? { title: _props } : { ..._props };
646
- const icon = _icon ?? specStyle?.icon;
647
- const _id = b.__fqn(id);
648
- b.__addElement(exact({
649
- id: _id,
650
- kind,
651
- title: title ?? nameFromFqn(_id),
652
- ...description && { description: toMarkdownOrString(description) },
653
- ...summary && { summary: toMarkdownOrString(summary) },
654
- style: exact({
655
- icon,
656
- color: color ?? specStyle?.color,
657
- shape: shape ?? specStyle?.shape,
658
- border: specStyle?.border,
659
- opacity: specStyle?.opacity,
660
- size: specStyle?.size,
661
- padding: specStyle?.padding,
662
- textSize: specStyle?.textSize,
663
- ...style
664
- }),
665
- links: mapLinks(links),
666
- ...spec2,
667
- ...props
668
- }));
669
- return b;
670
- });
671
- add.with = (...ops) => (b) => {
672
- add(b);
673
- const { __fqn, __addSourcelessRelation } = b;
674
- try {
675
- b.__fqn = (child) => `${__fqn(id)}.${child}`;
676
- b.__addSourcelessRelation = (relation) => {
677
- return b.__addRelation({
678
- ...relation,
679
- source: {
680
- model: __fqn(id)
681
- }
682
- });
683
- };
684
- ops.reduce((b2, op) => op(b2), b);
685
- } finally {
686
- b.__fqn = __fqn;
687
- b.__addSourcelessRelation = __addSourcelessRelation;
688
- }
689
- return b;
690
- };
691
- return add;
692
- }
693
- )
694
- },
695
- views: {
696
- views: (...ops) => {
697
- return (b) => {
698
- return ops.reduce((b2, op) => op(b2), b);
699
- };
700
- },
701
- view: (id, _props, _builder) => {
702
- const [generic, builder2] = createGenericView(id, _props, _builder);
703
- const view = {
704
- ...generic,
705
- [_type]: "element",
706
- rules: []
707
- };
708
- const add = (b) => {
709
- b.__addView(view);
710
- if (builder2) {
711
- builder2(mkViewBuilder(view));
712
- }
713
- return b;
714
- };
715
- add.with = (...ops) => (b) => {
716
- add(b);
717
- const elementViewBuilder = mkViewBuilder(view);
718
- for (const op of ops) {
719
- op(elementViewBuilder);
720
- }
721
- return b;
722
- };
723
- return add;
724
- },
725
- viewOf: (id, viewOf, _props, _builder) => {
726
- const [generic, builder2] = createGenericView(id, _props, _builder);
727
- const view = {
728
- ...generic,
729
- viewOf,
730
- [_type]: "element",
731
- rules: []
732
- };
733
- const add = (b) => {
734
- b.__addView(view);
735
- if (builder2) {
736
- builder2(mkViewBuilder(view));
737
- }
738
- return b;
739
- };
740
- add.with = (...ops) => (b) => {
741
- add(b);
742
- const elementViewBuilder = mkViewBuilder(view);
743
- for (const op of ops) {
744
- op(elementViewBuilder);
745
- }
746
- return b;
747
- };
748
- return add;
749
- },
750
- deploymentView: (id, _props, _builder) => {
751
- const [generic, builder2] = createGenericView(id, _props, _builder);
752
- const view = {
753
- ...generic,
754
- [_type]: "deployment",
755
- rules: []
756
- };
757
- const add = (b) => {
758
- b.__addView(view);
759
- if (builder2) {
760
- builder2(mkViewBuilder(view));
761
- }
762
- return b;
763
- };
764
- add.with = (...ops) => (b) => {
765
- add(b);
766
- const elementViewBuilder = mkViewBuilder(view);
767
- for (const op of ops) {
768
- op(elementViewBuilder);
769
- }
770
- return b;
771
- };
772
- return add;
773
- },
774
- $autoLayout,
775
- $exclude,
776
- $include,
777
- $rules,
778
- $style
779
- },
780
- deployment: {
781
- deployment: (...ops) => {
782
- return (b) => {
783
- return ops.reduce((b2, op) => op(b2), b);
784
- };
785
- },
786
- instanceOf: (id, target, _props) => {
787
- return (b) => {
788
- if (e$2(target)) {
789
- target = id;
790
- id = nameFromFqn(id);
791
- } else if (typeof target === "string") {
792
- _props ??= {};
793
- } else {
794
- _props = target;
795
- target = id;
796
- id = nameFromFqn(id);
797
- }
798
- const {
799
- links,
800
- title,
801
- description,
802
- summary,
803
- icon,
804
- color,
805
- shape,
806
- style,
807
- ...props
808
- } = typeof _props === "string" ? { title: _props } : { ..._props };
809
- const _id = b.__deploymentFqn(id);
810
- b.__addDeployment(
811
- exact({
812
- id: _id,
813
- element: target,
814
- ...title && { title },
815
- ...summary && { summary: toMarkdownOrString(summary) },
816
- ...description && { description: toMarkdownOrString(description) },
817
- style: exact({
818
- icon,
819
- color,
820
- shape,
821
- ...style
822
- }),
823
- links: mapLinks(links),
824
- ...props
825
- })
826
- );
827
- return b;
828
- };
829
- },
830
- rel: (source, target, _props) => {
831
- return (b) => {
832
- const {
833
- title = null,
834
- links,
835
- description = null,
836
- notes = null,
837
- ...props
838
- } = typeof _props === "string" ? { title: _props } : { ..._props };
839
- b.__addDeploymentRelation(exact({
840
- source: {
841
- deployment: source
842
- },
843
- target: {
844
- deployment: target
845
- },
846
- title,
847
- ...description && { description: toMarkdownOrString(description) },
848
- ...notes && { notes: toMarkdownOrString(notes) },
849
- links: mapLinks(links),
850
- ...props
851
- }));
852
- return b;
853
- };
854
- },
855
- ...t$3(
856
- spec.deployments ?? {},
857
- ({ style: specStyle, ...spec2 }, kind) => (id, _props) => {
858
- const add = ((b) => {
859
- const {
860
- links,
861
- icon: _icon,
862
- style,
863
- title,
864
- description,
865
- summary,
866
- color,
867
- shape,
868
- ...props
869
- } = typeof _props === "string" ? { title: _props } : { ..._props };
870
- const icon = _icon ?? specStyle?.icon;
871
- const _id = b.__deploymentFqn(id);
872
- b.__addDeployment(
873
- exact({
874
- id: _id,
875
- kind,
876
- title: title ?? nameFromFqn(_id),
877
- ...description && { description: toMarkdownOrString(description) },
878
- ...summary && { summary: toMarkdownOrString(summary) },
879
- style: exact({
880
- icon,
881
- color: color ?? specStyle?.color,
882
- shape: shape ?? specStyle?.shape,
883
- border: specStyle?.border,
884
- opacity: specStyle?.opacity,
885
- size: specStyle?.size,
886
- padding: specStyle?.padding,
887
- textSize: specStyle?.textSize,
888
- ...style
889
- }),
890
- links: mapLinks(links),
891
- ...spec2,
892
- ...props
893
- })
894
- );
895
- return b;
896
- });
897
- add.with = (...ops) => (b) => {
898
- add(b);
899
- const { __deploymentFqn } = b;
900
- try {
901
- b.__deploymentFqn = (child) => `${__deploymentFqn(id)}.${child}`;
902
- ops.reduce((b2, op) => op(b2), b);
903
- } finally {
904
- b.__deploymentFqn = __deploymentFqn;
905
- }
906
- return b;
907
- };
908
- return add;
909
- }
910
- )
911
- }
912
- }),
913
- with: (...ops) => {
914
- const b = self.clone();
915
- return ops.reduce((b2, op) => op(b2), b);
916
- },
917
- model: (cb) => {
918
- const b = self.clone();
919
- const helpers = b.helpers().model;
920
- const _ = helpers.model;
921
- return cb({ ...helpers, _ }, _)(b);
922
- },
923
- deployment: (cb) => {
924
- const b = self.clone();
925
- const helpers = b.helpers().deployment;
926
- const _ = helpers.deployment;
927
- return cb({ ...helpers, _ }, _)(b);
928
- },
929
- views: (cb) => {
930
- const b = self.clone();
931
- const helpers = b.helpers().views;
932
- return cb({
933
- ...helpers,
934
- _: helpers.views
935
- }, helpers.views)(b);
936
- }
937
- };
938
- return self;
203
+ predicates: {},
204
+ dynamicPredicates: {},
205
+ styles: {}
206
+ }, _deployments = /* @__PURE__ */ new Map(), _deploymentRelations = [], _imports = new import_default_map.default(() => /* @__PURE__ */ new Map())) {
207
+ const spec = validateSpec(_spec);
208
+ const toLikeC4Specification = () => {
209
+ return {
210
+ elements: structuredClone(spec.elements),
211
+ deployments: structuredClone(spec.deployments),
212
+ relationships: structuredClone(spec.relationships),
213
+ tags: assignTagColors(structuredClone(spec.tags)),
214
+ ...spec.metadataKeys ? { metadataKeys: spec.metadataKeys } : {},
215
+ customColors: {}
216
+ };
217
+ };
218
+ const mapLinks = (links) => {
219
+ if (!links || !t$3(links, 1)) return;
220
+ return t(links, (l) => typeof l === "string" ? { url: l } : l);
221
+ };
222
+ const createGenericView = (id, _props, builder) => {
223
+ if (e$3(_props)) {
224
+ builder = _props;
225
+ _props = {};
226
+ }
227
+ _props ??= {};
228
+ const { links: _links = [], title = null, description = null, tags = [], ...props } = typeof _props === "string" ? { title: _props } : { ..._props };
229
+ const links = mapLinks(_links);
230
+ return [exact({
231
+ id,
232
+ title,
233
+ description: toMarkdownOrString(description),
234
+ tags,
235
+ links,
236
+ _stage: "parsed",
237
+ ...props
238
+ }), builder];
239
+ };
240
+ const checkElementExists = (id) => {
241
+ const [project, fqn] = splitGlobalFqn(id);
242
+ const el = (project ? _imports.get(project) : _elements).get(fqn);
243
+ invariant(el, `Element with id "${id}" not found`);
244
+ return el;
245
+ };
246
+ const parseRelEndpoint = (endpoint) => {
247
+ if (typeof endpoint === "string") {
248
+ const [project, model] = splitGlobalFqn(endpoint);
249
+ if (project) return {
250
+ project,
251
+ model
252
+ };
253
+ return { model };
254
+ }
255
+ if ("project" in endpoint || "deployment" in endpoint) return endpoint;
256
+ return parseRelEndpoint(endpoint.model);
257
+ };
258
+ const self = {
259
+ get Types() {
260
+ throw new Error("Types are not available in runtime");
261
+ },
262
+ clone: () => {
263
+ const imports = new import_default_map.default(() => /* @__PURE__ */ new Map());
264
+ for (const [key, value] of _imports) imports.set(key, structuredClone(value));
265
+ return builder(structuredClone(spec), structuredClone(_elements), structuredClone(_relations), structuredClone(_views), structuredClone(_globals), structuredClone(_deployments), structuredClone(_deploymentRelations), imports);
266
+ },
267
+ __addElement: (element) => {
268
+ const [project, fqn] = splitGlobalFqn(element.id);
269
+ const parent = parentFqn(fqn);
270
+ const lookup = project ? _imports.get(project) : _elements;
271
+ if (parent) invariant(lookup.get(parent), `Parent element with id "${parent}" not found for element with id "${element.id}"`);
272
+ if (lookup.has(fqn)) throw new Error(`Element with id "${element.id}" already exists`);
273
+ lookup.set(fqn, project ? {
274
+ ...element,
275
+ id: fqn
276
+ } : element);
277
+ return self;
278
+ },
279
+ __addRelation(relation) {
280
+ const source = parseRelEndpoint(relation.source);
281
+ const sourceFqn = FqnRef.flatten(source);
282
+ const target = parseRelEndpoint(relation.target);
283
+ const targetFqn = FqnRef.flatten(target);
284
+ const sourceEl = checkElementExists(sourceFqn);
285
+ const targetEl = checkElementExists(targetFqn);
286
+ if (isGlobalFqn(sourceFqn) && isGlobalFqn(targetFqn)) throw new Error("Cannot create relationship between global elements");
287
+ if (!isGlobalFqn(sourceFqn) && !isGlobalFqn(targetFqn)) invariant(!isSameHierarchy(sourceEl, targetEl), "Cannot create relationship between elements in the same hierarchy");
288
+ _relations.push({
289
+ id: `rel${_relations.length + 1}`,
290
+ ...relation,
291
+ source,
292
+ target
293
+ });
294
+ return self;
295
+ },
296
+ __fqn(id) {
297
+ invariant(id.trim() !== "", "Id must be non-empty");
298
+ return id;
299
+ },
300
+ __deploymentFqn(id) {
301
+ invariant(id.trim() !== "", "Id must be non-empty");
302
+ return id;
303
+ },
304
+ __addSourcelessRelation() {
305
+ throw new Error("Can be called only in nested model");
306
+ },
307
+ __addView: (view) => {
308
+ if (_views.has(view.id)) throw new Error(`View with id "${view.id}" already exists`);
309
+ if (isElementView(view) && "viewOf" in view) invariant(_elements.get(view.viewOf), `Invalid scoped view ${view.id}, wlement with id "${view.viewOf}" not found`);
310
+ _views.set(view.id, view);
311
+ return self;
312
+ },
313
+ __addDeployment: (node) => {
314
+ if (_deployments.has(node.id)) throw new Error(`Deployment with id "${node.id}" already exists`);
315
+ const parent = parentFqn(node.id);
316
+ if (parent) invariant(_deployments.get(parent), `Parent element with id "${parent}" not found for node with id "${node.id}"`);
317
+ if (isDeployedInstance(node)) {
318
+ invariant(parent, `Instance ${node.id} of ${node.element} must be deployed under a parent node`);
319
+ invariant(_elements.get(node.element), `Instance "${node.id}" references non-existing element "${node.element}"`);
320
+ }
321
+ _deployments.set(node.id, node);
322
+ return self;
323
+ },
324
+ __addDeploymentRelation: (relation) => {
325
+ invariant(!isSameHierarchy(relation.source.deployment, relation.target.deployment), "Cannot create relationship between elements in the same hierarchy");
326
+ invariant(_deployments.has(relation.source.deployment), `Relation "${relation.source.deployment} -> ${relation.target.deployment}" references non-existing source`);
327
+ invariant(_deployments.has(relation.target.deployment), `Relation "${relation.source.deployment} -> ${relation.target.deployment}" references non-existing target`);
328
+ _deploymentRelations.push({
329
+ id: `deploy_rel${_deploymentRelations.length + 1}`,
330
+ ...relation
331
+ });
332
+ return self;
333
+ },
334
+ build: (project) => ({
335
+ [_stage]: "parsed",
336
+ projectId: typeof project === "string" ? project : project?.id ?? "from-builder",
337
+ project: {
338
+ id: typeof project === "string" ? project : "from-builder",
339
+ ...typeof project === "object" && project !== null ? project : {}
340
+ },
341
+ specification: toLikeC4Specification(),
342
+ elements: t$4(structuredClone(Array.from(_elements.entries()))),
343
+ relations: t$5(_relations, (r) => [r.id, structuredClone(r)]),
344
+ globals: structuredClone(_globals),
345
+ deployments: {
346
+ elements: t$4(structuredClone(Array.from(_deployments.entries()))),
347
+ relations: t$5(_deploymentRelations, (r) => [r.id, structuredClone(r)])
348
+ },
349
+ views: t$4(structuredClone(Array.from(_views.entries()))),
350
+ imports: t$6(Array.from(_imports.entries()), t(([projectId, elementsMap]) => [projectId, structuredClone([...elementsMap.values()])]), n(([_, elements]) => elements.length > 0), t$4())
351
+ }),
352
+ toLikeC4Model: (project) => {
353
+ return computeLikeC4Model(self.build(project));
354
+ },
355
+ helpers: () => ({
356
+ model: {
357
+ model: (...ops) => {
358
+ return (b) => {
359
+ return ops.reduce((b, op) => op(b), b);
360
+ };
361
+ },
362
+ rel: (source, target, _props) => {
363
+ return (b) => {
364
+ const { title = "", links: _links = [], description = null, notes = null, ...props } = defu(typeof _props === "string" ? { title: _props } : { ..._props }, {
365
+ title: null,
366
+ links: null
367
+ });
368
+ const links = mapLinks(_links);
369
+ b.__addRelation(exact({
370
+ source: { model: source },
371
+ target: { model: target },
372
+ title,
373
+ ...description && { description: toMarkdownOrString(description) },
374
+ ...notes && { notes: toMarkdownOrString(notes) },
375
+ links,
376
+ ...props
377
+ }));
378
+ return b;
379
+ };
380
+ },
381
+ relTo: (target, _props) => {
382
+ return (b) => {
383
+ const { title = "", links, description = null, notes = null, ...props } = defu(typeof _props === "string" ? { title: _props } : { ..._props }, {
384
+ title: null,
385
+ links: null
386
+ });
387
+ b.__addSourcelessRelation(exact({
388
+ target: { model: target },
389
+ title,
390
+ ...description && { description: toMarkdownOrString(description) },
391
+ ...notes && { notes: toMarkdownOrString(notes) },
392
+ links: mapLinks(links),
393
+ ...props
394
+ }));
395
+ return b;
396
+ };
397
+ },
398
+ ...t$7(spec.elements, ({ style: specStyle, ...spec }, kind) => (id, _props) => {
399
+ const add = ((b) => {
400
+ const { links, icon: _icon, color, shape, style, title, description, summary, ...props } = typeof _props === "string" ? { title: _props } : { ..._props };
401
+ const icon = _icon ?? specStyle?.icon;
402
+ const _id = b.__fqn(id);
403
+ b.__addElement(exact({
404
+ id: _id,
405
+ kind,
406
+ title: title ?? nameFromFqn(_id),
407
+ ...description && { description: toMarkdownOrString(description) },
408
+ ...summary && { summary: toMarkdownOrString(summary) },
409
+ style: exact({
410
+ icon,
411
+ color: color ?? specStyle?.color,
412
+ shape: shape ?? specStyle?.shape,
413
+ border: specStyle?.border,
414
+ opacity: specStyle?.opacity,
415
+ size: specStyle?.size,
416
+ padding: specStyle?.padding,
417
+ textSize: specStyle?.textSize,
418
+ ...style
419
+ }),
420
+ links: mapLinks(links),
421
+ ...spec,
422
+ ...props
423
+ }));
424
+ return b;
425
+ });
426
+ add.with = (...ops) => (b) => {
427
+ add(b);
428
+ const { __fqn, __addSourcelessRelation } = b;
429
+ try {
430
+ b.__fqn = (child) => `${__fqn(id)}.${child}`;
431
+ b.__addSourcelessRelation = (relation) => {
432
+ return b.__addRelation({
433
+ ...relation,
434
+ source: { model: __fqn(id) }
435
+ });
436
+ };
437
+ ops.reduce((b, op) => op(b), b);
438
+ } finally {
439
+ b.__fqn = __fqn;
440
+ b.__addSourcelessRelation = __addSourcelessRelation;
441
+ }
442
+ return b;
443
+ };
444
+ return add;
445
+ })
446
+ },
447
+ views: {
448
+ views: (...ops) => {
449
+ return (b) => {
450
+ return ops.reduce((b, op) => op(b), b);
451
+ };
452
+ },
453
+ view: (id, _props, _builder) => {
454
+ const [generic, builder] = createGenericView(id, _props, _builder);
455
+ const view = {
456
+ ...generic,
457
+ [_type]: "element",
458
+ rules: []
459
+ };
460
+ const add = (b) => {
461
+ b.__addView(view);
462
+ if (builder) builder(mkViewBuilder(view));
463
+ return b;
464
+ };
465
+ add.with = (...ops) => (b) => {
466
+ add(b);
467
+ const elementViewBuilder = mkViewBuilder(view);
468
+ for (const op of ops) op(elementViewBuilder);
469
+ return b;
470
+ };
471
+ return add;
472
+ },
473
+ viewOf: (id, viewOf, _props, _builder) => {
474
+ const [generic, builder] = createGenericView(id, _props, _builder);
475
+ const view = {
476
+ ...generic,
477
+ viewOf,
478
+ [_type]: "element",
479
+ rules: []
480
+ };
481
+ const add = (b) => {
482
+ b.__addView(view);
483
+ if (builder) builder(mkViewBuilder(view));
484
+ return b;
485
+ };
486
+ add.with = (...ops) => (b) => {
487
+ add(b);
488
+ const elementViewBuilder = mkViewBuilder(view);
489
+ for (const op of ops) op(elementViewBuilder);
490
+ return b;
491
+ };
492
+ return add;
493
+ },
494
+ deploymentView: (id, _props, _builder) => {
495
+ const [generic, builder] = createGenericView(id, _props, _builder);
496
+ const view = {
497
+ ...generic,
498
+ [_type]: "deployment",
499
+ rules: []
500
+ };
501
+ const add = (b) => {
502
+ b.__addView(view);
503
+ if (builder) builder(mkViewBuilder(view));
504
+ return b;
505
+ };
506
+ add.with = (...ops) => (b) => {
507
+ add(b);
508
+ const elementViewBuilder = mkViewBuilder(view);
509
+ for (const op of ops) op(elementViewBuilder);
510
+ return b;
511
+ };
512
+ return add;
513
+ },
514
+ $autoLayout,
515
+ $exclude,
516
+ $include,
517
+ $rules,
518
+ $style
519
+ },
520
+ deployment: {
521
+ deployment: (...ops) => {
522
+ return (b) => {
523
+ return ops.reduce((b, op) => op(b), b);
524
+ };
525
+ },
526
+ instanceOf: (id, target, _props) => {
527
+ return (b) => {
528
+ if (e$2(target)) {
529
+ target = id;
530
+ id = nameFromFqn(id);
531
+ } else if (typeof target === "string") _props ??= {};
532
+ else {
533
+ _props = target;
534
+ target = id;
535
+ id = nameFromFqn(id);
536
+ }
537
+ const { links, title, description, summary, icon, color, shape, style, ...props } = typeof _props === "string" ? { title: _props } : { ..._props };
538
+ const _id = b.__deploymentFqn(id);
539
+ b.__addDeployment(exact({
540
+ id: _id,
541
+ element: target,
542
+ ...title && { title },
543
+ ...summary && { summary: toMarkdownOrString(summary) },
544
+ ...description && { description: toMarkdownOrString(description) },
545
+ style: exact({
546
+ icon,
547
+ color,
548
+ shape,
549
+ ...style
550
+ }),
551
+ links: mapLinks(links),
552
+ ...props
553
+ }));
554
+ return b;
555
+ };
556
+ },
557
+ rel: (source, target, _props) => {
558
+ return (b) => {
559
+ const { title = null, links, description = null, notes = null, ...props } = typeof _props === "string" ? { title: _props } : { ..._props };
560
+ b.__addDeploymentRelation(exact({
561
+ source: { deployment: source },
562
+ target: { deployment: target },
563
+ title,
564
+ ...description && { description: toMarkdownOrString(description) },
565
+ ...notes && { notes: toMarkdownOrString(notes) },
566
+ links: mapLinks(links),
567
+ ...props
568
+ }));
569
+ return b;
570
+ };
571
+ },
572
+ ...t$7(spec.deployments ?? {}, ({ style: specStyle, ...spec }, kind) => (id, _props) => {
573
+ const add = ((b) => {
574
+ const { links, icon: _icon, style, title, description, summary, color, shape, ...props } = typeof _props === "string" ? { title: _props } : { ..._props };
575
+ const icon = _icon ?? specStyle?.icon;
576
+ const _id = b.__deploymentFqn(id);
577
+ b.__addDeployment(exact({
578
+ id: _id,
579
+ kind,
580
+ title: title ?? nameFromFqn(_id),
581
+ ...description && { description: toMarkdownOrString(description) },
582
+ ...summary && { summary: toMarkdownOrString(summary) },
583
+ style: exact({
584
+ icon,
585
+ color: color ?? specStyle?.color,
586
+ shape: shape ?? specStyle?.shape,
587
+ border: specStyle?.border,
588
+ opacity: specStyle?.opacity,
589
+ size: specStyle?.size,
590
+ padding: specStyle?.padding,
591
+ textSize: specStyle?.textSize,
592
+ ...style
593
+ }),
594
+ links: mapLinks(links),
595
+ ...spec,
596
+ ...props
597
+ }));
598
+ return b;
599
+ });
600
+ add.with = (...ops) => (b) => {
601
+ add(b);
602
+ const { __deploymentFqn } = b;
603
+ try {
604
+ b.__deploymentFqn = (child) => `${__deploymentFqn(id)}.${child}`;
605
+ ops.reduce((b, op) => op(b), b);
606
+ } finally {
607
+ b.__deploymentFqn = __deploymentFqn;
608
+ }
609
+ return b;
610
+ };
611
+ return add;
612
+ })
613
+ }
614
+ }),
615
+ with: (...ops) => {
616
+ const b = self.clone();
617
+ return ops.reduce((b, op) => op(b), b);
618
+ },
619
+ model: (cb) => {
620
+ const b = self.clone();
621
+ const helpers = b.helpers().model;
622
+ const _ = helpers.model;
623
+ return cb({
624
+ ...helpers,
625
+ _
626
+ }, _)(b);
627
+ },
628
+ deployment: (cb) => {
629
+ const b = self.clone();
630
+ const helpers = b.helpers().deployment;
631
+ const _ = helpers.deployment;
632
+ return cb({
633
+ ...helpers,
634
+ _
635
+ }, _)(b);
636
+ },
637
+ views: (cb) => {
638
+ const b = self.clone();
639
+ const helpers = b.helpers().views;
640
+ return cb({
641
+ ...helpers,
642
+ _: helpers.views
643
+ }, helpers.views)(b);
644
+ }
645
+ };
646
+ return self;
939
647
  }
940
648
  const Builder = {
941
- /**
942
- * Creates a builder with compositional methods
943
- *
944
- * @example
945
- * ```ts
946
- * const {
947
- * model: { model, system, component, relTo },
948
- * deployment: { env, vm},
949
- * views: { view, $include },
950
- * builder,
951
- * } = Builder.forSpecification({
952
- * elements: {
953
- * system: {},
954
- * component: {},
955
- * },
956
- * deployments: ['env', 'vm'],
957
- * })
958
- *
959
- * const b = builder
960
- * .with(
961
- * model(
962
- * system('cloud').with(
963
- * component('backend'),
964
- * component('backend.api'),
965
- * component('frontend').with(
966
- * relTo('cloud.backend.api'),
967
- * ),
968
- * ),
969
- * ),
970
- * )
971
- * ```
972
- */
973
- forSpecification(spec) {
974
- const b = builder(spec);
975
- return {
976
- ...b.helpers(),
977
- builder: b
978
- };
979
- },
980
- /**
981
- * Creates a builder with chainable methods
982
- *
983
- * @example
984
- * ```ts
985
- * const b = Builder
986
- * .specification({
987
- * elements: ['system', 'component'],
988
- * deployments: ['env', 'vm'],
989
- * })
990
- * .model(({ system, component, relTo }, _) =>
991
- * _(
992
- * system('cloud').with(
993
- * component('backend').with(
994
- * component('api'),
995
- * ),
996
- * component('frontend').with(
997
- * relTo('cloud.backend.api'),
998
- * )
999
- * )
1000
- * )
1001
- * )
1002
- * ```
1003
- */
1004
- specification(spec) {
1005
- return builder(spec);
1006
- }
649
+ forSpecification(spec) {
650
+ const b = builder(spec);
651
+ return {
652
+ ...b.helpers(),
653
+ builder: b
654
+ };
655
+ },
656
+ specification(spec) {
657
+ return builder(spec);
658
+ }
1007
659
  };
1008
660
 
1009
- export { Builder };
661
+ //#endregion
662
+ export { Builder };