@likec4/core 1.48.0 → 1.49.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/THIRD-PARTY-LICENSES.md +1012 -0
- package/dist/_chunks/Builder.view-element.mjs +2 -3284
- package/dist/_chunks/LikeC4Model.d.mts +21 -25
- package/dist/_chunks/RichText.mjs +1 -148
- package/dist/_chunks/_types.d.mts +1 -5
- package/dist/_chunks/_types2.d.mts +2 -4
- package/dist/_chunks/assignTagColors.mjs +1 -24
- package/dist/_chunks/calcDriftsFromSnapshot.mjs +1 -379
- package/dist/_chunks/guards.d.mts +2026 -0
- package/dist/_chunks/guards.mjs +4 -0
- package/dist/_chunks/index.d.mts +255 -136
- package/dist/_chunks/libs/@mantine/colors-generator.mjs +2 -3403
- package/dist/_chunks/libs/@radix-ui/colors.mjs +1 -0
- package/dist/_chunks/libs/@ungap/structured-clone.mjs +1 -213
- package/dist/_chunks/libs/bail.mjs +1 -14
- package/dist/_chunks/libs/ccount.mjs +1 -25
- package/dist/_chunks/libs/character-entities-html4.mjs +1 -263
- package/dist/_chunks/libs/character-entities-legacy.mjs +1 -117
- package/dist/_chunks/libs/character-entities.mjs +2 -2136
- package/dist/_chunks/libs/comma-separated-tokens.mjs +1 -18
- package/dist/_chunks/libs/decode-named-character-reference.mjs +1 -21
- package/dist/_chunks/libs/defu.mjs +1 -42
- package/dist/_chunks/libs/devlop.mjs +1 -5
- package/dist/_chunks/libs/escape-string-regexp.mjs +1 -8
- package/dist/_chunks/libs/extend.mjs +1 -77
- package/dist/_chunks/libs/graphology-dag.mjs +1 -703
- package/dist/_chunks/libs/graphology.mjs +1 -4565
- package/dist/_chunks/libs/hast-util-sanitize.mjs +1 -863
- package/dist/_chunks/libs/hast-util-to-html.mjs +9 -2696
- package/dist/_chunks/libs/is-plain-obj.mjs +1 -9
- package/dist/_chunks/libs/longest-streak.mjs +1 -30
- package/dist/_chunks/libs/markdown-table.mjs +2 -290
- package/dist/_chunks/libs/mdast-util-find-and-replace.mjs +1 -653
- package/dist/_chunks/libs/mdast-util-from-markdown.mjs +3 -8522
- package/dist/_chunks/libs/mdast-util-gfm.mjs +15 -2393
- package/dist/_chunks/libs/mdast-util-to-hast.mjs +11 -1803
- package/dist/_chunks/libs/micromark-extension-gfm.mjs +1 -2243
- package/dist/_chunks/libs/mnemonist.d.mts +1 -91
- package/dist/_chunks/libs/mnemonist.mjs +1 -1978
- package/dist/_chunks/libs/natural-compare-lite.mjs +9 -42
- package/dist/_chunks/libs/ohash.mjs +1 -0
- package/dist/_chunks/libs/rehype-sanitize.mjs +1 -29
- package/dist/_chunks/libs/rehype-stringify.mjs +1 -34
- package/dist/_chunks/libs/remark-gfm.mjs +1 -36
- package/dist/_chunks/libs/remark-github-blockquote-alert.mjs +3 -100
- package/dist/_chunks/libs/remark-parse.mjs +1 -39
- package/dist/_chunks/libs/remark-rehype.mjs +1 -171
- package/dist/_chunks/libs/remeda.mjs +1 -702
- package/dist/_chunks/libs/trough.mjs +1 -158
- package/dist/_chunks/libs/unified.mjs +1 -2212
- package/dist/_chunks/rolldown-runtime.mjs +1 -42
- package/dist/_chunks/{index3.d.mts → theme.d.mts} +15 -13
- package/dist/_chunks/{index7.d.mts → to-text.d.mts} +165 -29
- package/dist/_chunks/to-text.mjs +1 -0
- package/dist/_chunks/vector.d.mts +198 -0
- package/dist/_chunks/vector.mjs +1 -0
- package/dist/builder/index.d.mts +2 -8
- package/dist/builder/index.mjs +1 -662
- package/dist/compute-view/index.d.mts +86 -15
- package/dist/compute-view/index.mjs +2 -262
- package/dist/geometry/index.d.mts +2 -2
- package/dist/geometry/index.mjs +1 -3
- package/dist/index.d.mts +9 -13
- package/dist/index.mjs +1 -27
- package/dist/model/index.d.mts +4 -14
- package/dist/model/index.mjs +1 -11
- package/dist/styles/index.d.mts +2 -8
- package/dist/styles/index.mjs +1 -30
- package/dist/types/index.d.mts +3 -9
- package/dist/types/index.mjs +1 -15
- package/dist/utils/graphology/index.d.mts +1 -1
- package/dist/utils/graphology/index.mjs +1 -3
- package/dist/utils/index.d.mts +4 -11
- package/dist/utils/index.mjs +1 -17
- package/package.json +13 -12
- package/dist/_chunks/LikeC4Styles.mjs +0 -691
- package/dist/_chunks/RichText.d.mts +0 -84
- package/dist/_chunks/_aux.d.mts +0 -289
- package/dist/_chunks/_aux.mjs +0 -18
- package/dist/_chunks/connection.mjs +0 -0
- package/dist/_chunks/const.d.mts +0 -43
- package/dist/_chunks/const.mjs +0 -33
- package/dist/_chunks/expression-model.d.mts +0 -192
- package/dist/_chunks/expression-model.mjs +0 -103
- package/dist/_chunks/expression.d.mts +0 -347
- package/dist/_chunks/expression.mjs +0 -107
- package/dist/_chunks/find.d.mts +0 -82
- package/dist/_chunks/find.mjs +0 -646
- package/dist/_chunks/find2.d.mts +0 -78
- package/dist/_chunks/find2.mjs +0 -287
- package/dist/_chunks/fqnRef.d.mts +0 -58
- package/dist/_chunks/fqnRef.mjs +0 -41
- package/dist/_chunks/geometry.mjs +0 -335
- package/dist/_chunks/index2.d.mts +0 -937
- package/dist/_chunks/index4.d.mts +0 -62
- package/dist/_chunks/index5.d.mts +0 -42
- package/dist/_chunks/index6.d.mts +0 -43
- package/dist/_chunks/index8.d.mts +0 -144
- package/dist/_chunks/invariant.mjs +0 -18
- package/dist/_chunks/iterable.mjs +0 -146
- package/dist/_chunks/libs/graphology-types.d.mts +0 -601
- package/dist/_chunks/libs/graphology.d.mts +0 -6
- package/dist/_chunks/mnemonist.d.mts +0 -1
- package/dist/_chunks/mnemonist.mjs +0 -0
- package/dist/_chunks/model.mjs +0 -1898
- package/dist/_chunks/model2.mjs +0 -0
- package/dist/_chunks/relationships-view.mjs +0 -132
- package/dist/_chunks/scalar.d.mts +0 -109
- package/dist/_chunks/scalar.mjs +0 -84
- package/dist/_chunks/utils.mjs +0 -483
- package/dist/compute-view/relationships-view/index.d.mts +0 -16
- package/dist/compute-view/relationships-view/index.mjs +0 -7
- package/dist/model/connection/deployment/index.d.mts +0 -12
- package/dist/model/connection/deployment/index.mjs +0 -9
- package/dist/model/connection/index.d.mts +0 -14
- package/dist/model/connection/index.mjs +0 -10
- package/dist/model/connection/model/index.d.mts +0 -12
- package/dist/model/connection/model/index.mjs +0 -8
- package/dist/types/RichText.d.mts +0 -3
- package/dist/types/RichText.mjs +0 -7
- package/dist/types/_aux.d.mts +0 -3
- package/dist/types/_aux.mjs +0 -3
- package/dist/types/expression-model.d.mts +0 -6
- package/dist/types/expression-model.mjs +0 -7
- package/dist/types/expression.d.mts +0 -5
- package/dist/types/expression.mjs +0 -7
- package/dist/types/fqnRef.d.mts +0 -4
- package/dist/types/fqnRef.mjs +0 -7
- package/dist/types/scalar.d.mts +0 -2
- package/dist/types/scalar.mjs +0 -7
- package/dist/utils/iterable/index.d.mts +0 -9
- package/dist/utils/iterable/index.mjs +0 -3
- package/dist/utils/mnemonist.d.mts +0 -2
- package/dist/utils/mnemonist.mjs +0 -12
package/dist/builder/index.mjs
CHANGED
|
@@ -1,662 +1 @@
|
|
|
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";
|
|
17
|
-
|
|
18
|
-
//#region src/builder/Builder.view-common.ts
|
|
19
|
-
function parseWhere(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}`);
|
|
42
|
-
}
|
|
43
|
-
function $include(...args) {
|
|
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
|
-
};
|
|
65
|
-
}
|
|
66
|
-
function $exclude(...args) {
|
|
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
|
-
};
|
|
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
|
-
*/
|
|
95
|
-
function $style(element, { notation, ...style }) {
|
|
96
|
-
return (b) => b.style({
|
|
97
|
-
targets: (e$1(element) ? element : [element]).map((e) => b.$expr(e)),
|
|
98
|
-
...notation ? { notation } : {},
|
|
99
|
-
style: { ...style }
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
function $autoLayout(layout) {
|
|
103
|
-
return (b) => b.autoLayout(layout);
|
|
104
|
-
}
|
|
105
|
-
function $rules(...rules) {
|
|
106
|
-
return (b) => rules.reduce((b, rule) => rule(b), b);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
//#endregion
|
|
110
|
-
//#region src/builder/Builder.view-deployment.ts
|
|
111
|
-
function $deploymentExpr(expr) {
|
|
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 } });
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
//#endregion
|
|
153
|
-
//#region src/builder/Builder.views.ts
|
|
154
|
-
function mkViewBuilder(view) {
|
|
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;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
//#endregion
|
|
178
|
-
//#region src/builder/Builder.ts
|
|
179
|
-
function ensureObj(value) {
|
|
180
|
-
return e$1(value) ? t$1(value, (_) => ({})) : value;
|
|
181
|
-
}
|
|
182
|
-
function validateSpec({ tags, elements, deployments, relationships, ...specification }) {
|
|
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
|
-
};
|
|
196
|
-
}
|
|
197
|
-
function toMarkdownOrString(input) {
|
|
198
|
-
if (e$2(input)) return null;
|
|
199
|
-
if (typeof input === "string") return { txt: input };
|
|
200
|
-
return input;
|
|
201
|
-
}
|
|
202
|
-
function builder(_spec, _elements = /* @__PURE__ */ new Map(), _relations = [], _views = /* @__PURE__ */ new Map(), _globals = {
|
|
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;
|
|
647
|
-
}
|
|
648
|
-
const Builder = {
|
|
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
|
-
}
|
|
659
|
-
};
|
|
660
|
-
|
|
661
|
-
//#endregion
|
|
662
|
-
export { Builder };
|
|
1
|
+
import{t as defu}from"../_chunks/libs/defu.mjs";import{B as e$1,C as t$7,F as e$3,M as e$2,Q as t$3,T as t,U as t$1,W as t$4,X as t$2,Y as n,et as t$6,k as e,w as t$5}from"../_chunks/libs/remeda.mjs";import{B as isDeployedInstance,J as FqnRef,U as ModelFqnExpr,_t as _type,g as isElementView,gt as _stage,lt as isGlobalFqn,pt as splitGlobalFqn,xt as exact}from"../_chunks/RichText.mjs";import{B as parentFqn,Q as invariant,R as isSameHierarchy,z as nameFromFqn}from"../_chunks/to-text.mjs";import"../_chunks/libs/graphology-dag.mjs";import{t as import_default_map}from"../_chunks/libs/mnemonist.mjs";import"../_chunks/libs/natural-compare-lite.mjs";import"../_chunks/libs/extend.mjs";import"../_chunks/libs/@mantine/colors-generator.mjs";import{n as computeLikeC4Model,t as $expr}from"../_chunks/Builder.view-element.mjs";import"../_chunks/libs/graphology.mjs";import{t as assignTagColors}from"../_chunks/assignTagColors.mjs";function parseWhere(r){if(e(r)){let i=r;switch(!0){case i.startsWith(`tag is not #`):return{tag:{neq:i.replace(`tag is not #`,``)}};case i.startsWith(`tag is #`):return{tag:{eq:i.replace(`tag is #`,``)}};case i.startsWith(`kind is not `):return{kind:{neq:i.replace(`kind is not `,``)}};case i.startsWith(`kind is `):return{kind:{eq:i.replace(`kind is `,``)}};case i.startsWith(`source.`):return{operator:parseWhere(i.replace(`source.`,``)),participant:`source`};case i.startsWith(`target.`):return{operator:parseWhere(i.replace(`target.`,``)),participant:`target`};default:throw Error(`Unknown where operator: ${r}`)}}if(r.and)return{and:t(r.and,parseWhere)};if(r.or)return{or:t(r.or,parseWhere)};if(r.not)return{not:parseWhere(r.not)};throw Error(`Unknown where operator: ${r}`)}function $include(...r){return i=>{let a=i.$expr(r[0]);if(r.length===2){let i=r[1].where?parseWhere(r[1].where):void 0;i&&(a={where:{expr:a,condition:i}});let o=r[1].with;o&&(a=ModelFqnExpr.is(a)?{custom:{...o,expr:a}}:{customRelation:{...o,expr:a}})}return i.include(a),i}}function $exclude(...r){return i=>{let a=i.$expr(r[0]);if(r.length===2&&r[1].where){let i=parseWhere(r[1].where);a={where:{expr:a,condition:i}}}return i.exclude(a),i}}function $style(r,{notation:a,...o}){return s=>s.style({targets:(e$1(r)?r:[r]).map(r=>s.$expr(r)),...a?{notation:a}:{},style:{...o}})}function $autoLayout(r){return i=>i.autoLayout(r)}function $rules(...r){return i=>r.reduce((r,i)=>i(r),i)}function $deploymentExpr(r){if(!e(r))return r;let i=r=>r;if(r===`*`)return i({wildcard:!0});if(r.startsWith(`->`))return r.endsWith(`->`)?i({inout:$deploymentExpr(r.replace(/->/g,``).trim())}):i({incoming:$deploymentExpr(r.replace(`-> `,``))});if(r.endsWith(` ->`))return i({outgoing:$deploymentExpr(r.replace(` ->`,``))});if(r.includes(` <-> `)){let[a,o]=r.split(` <-> `);return i({source:$deploymentExpr(a),target:$deploymentExpr(o),isBidirectional:!0})}if(r.includes(` -> `)){let[a,o]=r.split(` -> `);return i({source:$deploymentExpr(a),target:$deploymentExpr(o)})}return r.endsWith(`._`)?i({ref:{deployment:r.replace(`._`,``)},selector:`expanded`}):r.endsWith(`.**`)?i({ref:{deployment:r.replace(`.**`,``)},selector:`descendants`}):r.endsWith(`.*`)?i({ref:{deployment:r.replace(`.*`,``)},selector:`children`}):i({ref:{deployment:r}})}function mkViewBuilder(r){let i={$expr:r[_type]===`deployment`?$deploymentExpr:$expr,autoLayout(a){return r.rules.push({direction:a}),i},exclude(a){return r.rules.push({exclude:[a]}),i},include(a){return r.rules.push({include:[a]}),i},style(a){return r.rules.push(a),i}};return i}function ensureObj(r){return e$1(r)?t$1(r,r=>({})):r}function validateSpec({tags:r,elements:i,deployments:a,relationships:o,...s}){let c={};r&&Object.assign(c,ensureObj(r));let l=ensureObj(i);for(let[r,i]of t$2(l))if(i.tags)for(let a of i.tags)invariant(a in c,`Invalid specification for element kind "${r}": tag "${a}" not found`);let u=ensureObj(a??{});for(let[r,i]of t$2(u))if(i.tags)for(let a of i.tags)invariant(a in c,`Invalid specification for deployment kind "${r}": tag "${a}" not found`);return{...s,tags:c,elements:l,deployments:u,relationships:ensureObj(o??{})}}function toMarkdownOrString(r){return e$2(r)?null:typeof r==`string`?{txt:r}:r}function builder(i,u=new Map,f=[],h=new Map,y={predicates:{},dynamicPredicates:{},styles:{}},b=new Map,x=[],S=new import_default_map.default(()=>new Map)){let C=validateSpec(i),w=()=>({elements:structuredClone(C.elements),deployments:structuredClone(C.deployments),relationships:structuredClone(C.relationships),tags:assignTagColors(structuredClone(C.tags)),...C.metadataKeys?{metadataKeys:C.metadataKeys}:{},customColors:{}}),T=r=>{if(!(!r||!t$3(r,1)))return t(r,r=>typeof r==`string`?{url:r}:r)},E=(r,i,a)=>{e$3(i)&&(a=i,i={}),i??={};let{links:s=[],title:c=null,description:l=null,tags:u=[],...d}=typeof i==`string`?{title:i}:{...i},f=T(s);return[exact({id:r,title:c,description:toMarkdownOrString(l),tags:u,links:f,_stage:`parsed`,...d}),a]},D=r=>{let[i,a]=splitGlobalFqn(r),o=(i?S.get(i):u).get(a);return invariant(o,`Element with id "${r}" not found`),o},O=r=>{if(typeof r==`string`){let[i,a]=splitGlobalFqn(r);return i?{project:i,model:a}:{model:a}}return`project`in r||`deployment`in r?r:O(r.model)},k={get Types(){throw Error(`Types are not available in runtime`)},clone:()=>{let r=new import_default_map.default(()=>new Map);for(let[i,a]of S)r.set(i,structuredClone(a));return builder(structuredClone(C),structuredClone(u),structuredClone(f),structuredClone(h),structuredClone(y),structuredClone(b),structuredClone(x),r)},__addElement:r=>{let[i,a]=splitGlobalFqn(r.id),o=parentFqn(a),s=i?S.get(i):u;if(o&&invariant(s.get(o),`Parent element with id "${o}" not found for element with id "${r.id}"`),s.has(a))throw Error(`Element with id "${r.id}" already exists`);return s.set(a,i?{...r,id:a}:r),k},__addRelation(r){let i=O(r.source),a=FqnRef.flatten(i),o=O(r.target),s=FqnRef.flatten(o),c=D(a),l=D(s);if(isGlobalFqn(a)&&isGlobalFqn(s))throw Error(`Cannot create relationship between global elements`);return!isGlobalFqn(a)&&!isGlobalFqn(s)&&invariant(!isSameHierarchy(c,l),`Cannot create relationship between elements in the same hierarchy`),f.push({id:`rel${f.length+1}`,...r,source:i,target:o}),k},__fqn(r){return invariant(r.trim()!==``,`Id must be non-empty`),r},__deploymentFqn(r){return invariant(r.trim()!==``,`Id must be non-empty`),r},__addSourcelessRelation(){throw Error(`Can be called only in nested model`)},__addView:r=>{if(h.has(r.id))throw Error(`View with id "${r.id}" already exists`);return isElementView(r)&&`viewOf`in r&&invariant(u.get(r.viewOf),`Invalid scoped view ${r.id}, wlement with id "${r.viewOf}" not found`),h.set(r.id,r),k},__addDeployment:r=>{if(b.has(r.id))throw Error(`Deployment with id "${r.id}" already exists`);let i=parentFqn(r.id);return i&&invariant(b.get(i),`Parent element with id "${i}" not found for node with id "${r.id}"`),isDeployedInstance(r)&&(invariant(i,`Instance ${r.id} of ${r.element} must be deployed under a parent node`),invariant(u.get(r.element),`Instance "${r.id}" references non-existing element "${r.element}"`)),b.set(r.id,r),k},__addDeploymentRelation:r=>(invariant(!isSameHierarchy(r.source.deployment,r.target.deployment),`Cannot create relationship between elements in the same hierarchy`),invariant(b.has(r.source.deployment),`Relation "${r.source.deployment} -> ${r.target.deployment}" references non-existing source`),invariant(b.has(r.target.deployment),`Relation "${r.source.deployment} -> ${r.target.deployment}" references non-existing target`),x.push({id:`deploy_rel${x.length+1}`,...r}),k),build:r=>({[_stage]:`parsed`,projectId:typeof r==`string`?r:r?.id??`from-builder`,project:{id:typeof r==`string`?r:`from-builder`,...typeof r==`object`&&r?r:{}},specification:w(),elements:t$4(structuredClone(Array.from(u.entries()))),relations:t$5(f,r=>[r.id,structuredClone(r)]),globals:structuredClone(y),deployments:{elements:t$4(structuredClone(Array.from(b.entries()))),relations:t$5(x,r=>[r.id,structuredClone(r)])},views:t$4(structuredClone(Array.from(h.entries()))),imports:t$6(Array.from(S.entries()),t(([r,i])=>[r,structuredClone([...i.values()])]),n(([r,i])=>i.length>0),t$4())}),toLikeC4Model:r=>computeLikeC4Model(k.build(r)),helpers:()=>({model:{model:(...r)=>i=>r.reduce((r,i)=>i(r),i),rel:(i,a,o)=>s=>{let{title:c=``,links:l=[],description:u=null,notes:d=null,...f}=defu(typeof o==`string`?{title:o}:{...o},{title:null,links:null}),p=T(l);return s.__addRelation(exact({source:{model:i},target:{model:a},title:c,...u&&{description:toMarkdownOrString(u)},...d&&{notes:toMarkdownOrString(d)},links:p,...f})),s},relTo:(i,a)=>o=>{let{title:s=``,links:c,description:l=null,notes:u=null,...d}=defu(typeof a==`string`?{title:a}:{...a},{title:null,links:null});return o.__addSourcelessRelation(exact({target:{model:i},title:s,...l&&{description:toMarkdownOrString(l)},...u&&{notes:toMarkdownOrString(u)},links:T(c),...d})),o},...t$7(C.elements,({style:r,...i},a)=>(o,s)=>{let c=(c=>{let{links:l,icon:u,color:d,shape:f,style:p,title:m,description:h,summary:g,..._}=typeof s==`string`?{title:s}:{...s},v=u??r?.icon,y=c.__fqn(o);return c.__addElement(exact({id:y,kind:a,title:m??nameFromFqn(y),...h&&{description:toMarkdownOrString(h)},...g&&{summary:toMarkdownOrString(g)},style:exact({icon:v,color:d??r?.color,shape:f??r?.shape,border:r?.border,opacity:r?.opacity,size:r?.size,padding:r?.padding,textSize:r?.textSize,...p}),links:T(l),...i,..._})),c});return c.with=(...r)=>i=>{c(i);let{__fqn:a,__addSourcelessRelation:s}=i;try{i.__fqn=r=>`${a(o)}.${r}`,i.__addSourcelessRelation=r=>i.__addRelation({...r,source:{model:a(o)}}),r.reduce((r,i)=>i(r),i)}finally{i.__fqn=a,i.__addSourcelessRelation=s}return i},c})},views:{views:(...r)=>i=>r.reduce((r,i)=>i(r),i),view:(r,i,a)=>{let[o,s]=E(r,i,a),c={...o,[_type]:`element`,rules:[]},l=r=>(r.__addView(c),s&&s(mkViewBuilder(c)),r);return l.with=(...r)=>i=>{l(i);let a=mkViewBuilder(c);for(let i of r)i(a);return i},l},viewOf:(r,i,a,o)=>{let[s,c]=E(r,a,o),l={...s,viewOf:i,[_type]:`element`,rules:[]},u=r=>(r.__addView(l),c&&c(mkViewBuilder(l)),r);return u.with=(...r)=>i=>{u(i);let a=mkViewBuilder(l);for(let i of r)i(a);return i},u},deploymentView:(r,i,a)=>{let[o,s]=E(r,i,a),c={...o,[_type]:`deployment`,rules:[]},l=r=>(r.__addView(c),s&&s(mkViewBuilder(c)),r);return l.with=(...r)=>i=>{l(i);let a=mkViewBuilder(c);for(let i of r)i(a);return i},l},$autoLayout,$exclude,$include,$rules,$style},deployment:{deployment:(...r)=>i=>r.reduce((r,i)=>i(r),i),instanceOf:(r,i,a)=>o=>{e$2(i)?(i=r,r=nameFromFqn(r)):typeof i==`string`?a??={}:(a=i,i=r,r=nameFromFqn(r));let{links:c,title:l,description:u,summary:d,icon:f,color:p,shape:m,style:h,...g}=typeof a==`string`?{title:a}:{...a},_=o.__deploymentFqn(r);return o.__addDeployment(exact({id:_,element:i,...l&&{title:l},...d&&{summary:toMarkdownOrString(d)},...u&&{description:toMarkdownOrString(u)},style:exact({icon:f,color:p,shape:m,...h}),links:T(c),...g})),o},rel:(r,i,a)=>o=>{let{title:s=null,links:c,description:l=null,notes:u=null,...d}=typeof a==`string`?{title:a}:{...a};return o.__addDeploymentRelation(exact({source:{deployment:r},target:{deployment:i},title:s,...l&&{description:toMarkdownOrString(l)},...u&&{notes:toMarkdownOrString(u)},links:T(c),...d})),o},...t$7(C.deployments??{},({style:r,...i},a)=>(o,s)=>{let c=(c=>{let{links:l,icon:u,style:d,title:f,description:p,summary:m,color:h,shape:g,..._}=typeof s==`string`?{title:s}:{...s},v=u??r?.icon,y=c.__deploymentFqn(o);return c.__addDeployment(exact({id:y,kind:a,title:f??nameFromFqn(y),...p&&{description:toMarkdownOrString(p)},...m&&{summary:toMarkdownOrString(m)},style:exact({icon:v,color:h??r?.color,shape:g??r?.shape,border:r?.border,opacity:r?.opacity,size:r?.size,padding:r?.padding,textSize:r?.textSize,...d}),links:T(l),...i,..._})),c});return c.with=(...r)=>i=>{c(i);let{__deploymentFqn:a}=i;try{i.__deploymentFqn=r=>`${a(o)}.${r}`,r.reduce((r,i)=>i(r),i)}finally{i.__deploymentFqn=a}return i},c})}}),with:(...r)=>{let i=k.clone();return r.reduce((r,i)=>i(r),i)},model:r=>{let i=k.clone(),a=i.helpers().model,o=a.model;return r({...a,_:o},o)(i)},deployment:r=>{let i=k.clone(),a=i.helpers().deployment,o=a.deployment;return r({...a,_:o},o)(i)},views:r=>{let i=k.clone(),a=i.helpers().views;return r({...a,_:a.views},a.views)(i)}};return k}const Builder={forSpecification(r){let i=builder(r);return{...i.helpers(),builder:i}},specification(r){return builder(r)}};export{Builder};
|