likec4 1.48.0 → 1.50.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/README.md +11 -1
- package/__app__/src/likec4.js +5941 -4496
- package/__app__/src/routes/index.js +3 -153
- package/__app__/src/routes/projects.js +21 -1087
- package/__app__/src/routes/single.js +1228 -16
- package/__app__/src/style.css +1 -1
- package/__app__/src/vendors.js +4649 -1897
- package/__app__/src/webcomponent.js +1 -1
- package/config/schema.json +169 -141
- package/dist/THIRD-PARTY-LICENSES.md +1769 -0
- package/dist/_chunks/LikeC4.mjs +1154 -202
- package/dist/_chunks/binary.mjs +72 -0
- package/dist/_chunks/index.d.mts +234 -140
- package/dist/_chunks/index2.d.mts +2043 -1828
- package/dist/_chunks/libs/@chevrotain/cst-dts-gen.mjs +30 -0
- package/dist/_chunks/libs/@chevrotain/regexp-to-ast.mjs +9 -785
- package/dist/_chunks/libs/@chevrotain/utils.mjs +1 -37
- package/dist/_chunks/libs/@hono/mcp.mjs +34 -0
- package/dist/_chunks/libs/@hono/node-server.mjs +1 -436
- package/dist/_chunks/libs/@logtape/logtape.d.mts +741 -0
- package/dist/_chunks/libs/@logtape/logtape.mjs +6 -1354
- package/dist/_chunks/libs/@lume/kiwi.mjs +1 -1355
- package/dist/_chunks/libs/@modelcontextprotocol/sdk.d.mts +114 -14
- package/dist/_chunks/libs/@modelcontextprotocol/sdk.mjs +12 -25105
- package/dist/_chunks/libs/@msgpack/msgpack.mjs +1 -1503
- package/dist/_chunks/libs/@nanostores/react.d.mts +61 -1
- package/dist/_chunks/libs/@nanostores/react.mjs +1 -30
- package/dist/_chunks/libs/@smithy/is-array-buffer.mjs +1 -10
- package/dist/_chunks/libs/@smithy/util-base64.mjs +1 -100
- package/dist/_chunks/libs/ajv.mjs +1 -777
- package/dist/_chunks/libs/atomically.mjs +1 -362
- package/dist/_chunks/libs/birpc.mjs +1 -201
- package/dist/_chunks/libs/chevrotain-allstar.mjs +2 -850
- package/dist/_chunks/libs/chevrotain.mjs +55 -6229
- package/dist/_chunks/libs/conf.mjs +1 -2258
- package/dist/_chunks/libs/defu.mjs +1 -42
- package/dist/_chunks/libs/esm-env.mjs +1 -5
- package/dist/_chunks/libs/eventemitter3.mjs +1 -243
- package/dist/_chunks/libs/fast-equals.mjs +1 -446
- package/dist/_chunks/libs/find-up-simple.mjs +1 -24
- package/dist/_chunks/libs/get-port.mjs +1 -107
- package/dist/_chunks/libs/is-docker.mjs +1 -26
- package/dist/_chunks/libs/is-error-instance.mjs +1 -26
- package/dist/_chunks/libs/is-inside-container.mjs +1 -20
- package/dist/_chunks/libs/is-plain-obj.mjs +1 -9
- package/dist/_chunks/libs/isexe.mjs +1 -127
- package/dist/_chunks/libs/json5.mjs +14 -959
- package/dist/_chunks/libs/khroma.mjs +1 -605
- package/dist/_chunks/libs/ky.mjs +2 -807
- package/dist/_chunks/libs/langium.d.mts +2913 -2876
- package/dist/_chunks/libs/langium.mjs +33 -20351
- package/dist/_chunks/libs/merge-error-cause.mjs +2 -746
- package/dist/_chunks/libs/p-limit.mjs +1 -120
- package/dist/_chunks/libs/p-queue.mjs +1 -449
- package/dist/_chunks/libs/package-manager-detector.mjs +1 -559
- package/dist/_chunks/libs/package-up.mjs +1 -10
- package/dist/_chunks/libs/pako.mjs +1 -0
- package/dist/_chunks/libs/parse-ms.mjs +1 -36
- package/dist/_chunks/libs/pathe.mjs +1 -0
- package/dist/_chunks/libs/picomatch.mjs +1 -1673
- package/dist/_chunks/libs/pretty-ms.mjs +1 -80
- package/dist/_chunks/libs/remeda.mjs +2 -690
- package/dist/_chunks/libs/safe-stringify.mjs +1 -21
- package/dist/_chunks/libs/strip-indent.mjs +1 -15
- package/dist/_chunks/libs/tinyrainbow.mjs +1 -88
- package/dist/_chunks/libs/ts-graphviz.mjs +4 -725
- package/dist/_chunks/libs/ufo.mjs +1 -240
- package/dist/_chunks/libs/which.mjs +1 -84
- package/dist/_chunks/libs/word-wrap.mjs +12 -43
- package/dist/_chunks/rolldown-runtime.mjs +1 -48
- package/dist/_chunks/sequence.mjs +1 -0
- package/dist/_chunks/src.mjs +15 -0
- package/dist/_chunks/src2.mjs +499 -0
- package/dist/cli/index.mjs +77 -1952
- package/dist/config/index.d.mts +2 -2
- package/dist/config/index.mjs +1 -6
- package/dist/index.d.mts +150 -7
- package/dist/index.mjs +1 -21
- package/dist/model/builder.mjs +1 -3
- package/dist/model/index.d.mts +57 -3
- package/dist/model/index.mjs +1 -5
- package/dist/vite-plugin/index.d.mts +7 -3
- package/dist/vite-plugin/index.mjs +1 -22
- package/dist/vite-plugin/internal.d.mts +6 -7
- package/dist/vite-plugin/internal.mjs +1 -68
- package/package.json +64 -45
- package/react/{index.d.ts → index.d.mts} +114 -72
- package/react/{index.js → index.mjs} +21320 -22041
- package/react/package.json +2 -5
- package/vite-plugin-modules.d.ts +10 -5
- package/dist/_chunks/LikeC4.d.mts +0 -121
- package/dist/_chunks/config-app.prod.d.mts +0 -18
- package/dist/_chunks/config-app.prod.mjs +0 -188
- package/dist/_chunks/config-webcomponent.prod.mjs +0 -71
- package/dist/_chunks/define-config.mjs +0 -409
- package/dist/_chunks/index3.d.mts +0 -60
- package/dist/_chunks/libs/@chevrotain/gast.mjs +0 -3969
- package/dist/_chunks/libs/hono.mjs +0 -1829
- package/dist/_chunks/libs/nanoid.mjs +0 -29
- package/dist/_chunks/libs/nanostores.d.mts +0 -63
- package/dist/_chunks/libs/nanostores.mjs +0 -198
- package/dist/_chunks/model.mjs +0 -12
- package/dist/_chunks/module.d.mts +0 -71
- package/dist/_chunks/module.mjs +0 -18657
- package/dist/_chunks/plugin.mjs +0 -996
- package/dist/_chunks/sequence-view.mjs +0 -575
- package/dist/_chunks/vite-build.mjs +0 -69
- package/dist/_chunks/vite-dev.mjs +0 -79
- package/dist/_chunks/vite-preview.mjs +0 -27
- package/dist/language/module.d.mts +0 -5
- package/dist/language/module.mjs +0 -20
- package/dist/vite/vite-build.d.mts +0 -26
- package/dist/vite/vite-build.mjs +0 -27
- package/dist/vite/vite-dev.d.mts +0 -34
- package/dist/vite/vite-dev.mjs +0 -29
- package/dist/vite/vite-preview.d.mts +0 -20
- package/dist/vite/vite-preview.mjs +0 -26
- /package/dist/_chunks/{index4.d.mts → libs/@chevrotain/types.d.mts} +0 -0
package/dist/_chunks/plugin.mjs
DELETED
|
@@ -1,996 +0,0 @@
|
|
|
1
|
-
import { s as __toESM } from "./rolldown-runtime.mjs";
|
|
2
|
-
import { a as expandToNode, i as toString, n as CompositeGeneratorNode, r as NL, t as joinToNode } from "./libs/langium.mjs";
|
|
3
|
-
import { B as n$2, S as e, U as n, h as t$3, j as t$5, m as t, o as t$2, q as t$1, r as n$1, u as t$4, v as e$2, w as e$1 } from "./libs/remeda.mjs";
|
|
4
|
-
import { t as u } from "./libs/tinyrainbow.mjs";
|
|
5
|
-
import { t as require_lib } from "./libs/json5.mjs";
|
|
6
|
-
import { o as joinURL } from "./libs/ufo.mjs";
|
|
7
|
-
import { t as LikeC4 } from "./LikeC4.mjs";
|
|
8
|
-
import { t as createBirpc } from "./libs/birpc.mjs";
|
|
9
|
-
import { RichText } from "@likec4/core/types";
|
|
10
|
-
import { invariant, isNonEmptyArray, nonexhaustive } from "@likec4/core";
|
|
11
|
-
import { compareNatural } from "@likec4/core/utils";
|
|
12
|
-
|
|
13
|
-
//#region src/vite-plugin/rpc/calcAdhocView.ts
|
|
14
|
-
async function calcAdhocView({ logger, likec4 }, data) {
|
|
15
|
-
logger.info([
|
|
16
|
-
u.green("adhoc:view"),
|
|
17
|
-
u.dim("project:"),
|
|
18
|
-
data.projectId
|
|
19
|
-
].join(" "));
|
|
20
|
-
const view = await likec4.views.adhocView(data.predicates, data.projectId);
|
|
21
|
-
logger.info([u.green("adhoc:view"), "✅"].join(" "));
|
|
22
|
-
return view;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
//#endregion
|
|
26
|
-
//#region src/vite-plugin/rpc/sendError.ts
|
|
27
|
-
function sendError(server, { name, error }) {
|
|
28
|
-
const lines = error.split("\n");
|
|
29
|
-
const test = /^\s+at\s+/;
|
|
30
|
-
let stackBeginAt = lines.findIndex((l) => test.test(l));
|
|
31
|
-
if (stackBeginAt === -1) stackBeginAt = lines.length;
|
|
32
|
-
server.hot.send({
|
|
33
|
-
type: "error",
|
|
34
|
-
err: {
|
|
35
|
-
message: lines.slice(0, stackBeginAt).join("\n"),
|
|
36
|
-
stack: lines.slice(stackBeginAt).join("\n"),
|
|
37
|
-
name: name ?? "LikeC4PluginError",
|
|
38
|
-
plugin: "vite-plugin-likec4"
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
//#endregion
|
|
44
|
-
//#region src/vite-plugin/rpc/updateView.ts
|
|
45
|
-
async function updateView({ logger, likec4 }, data) {
|
|
46
|
-
logger.info([
|
|
47
|
-
u.green("view:onChange"),
|
|
48
|
-
u.dim("project") + ":",
|
|
49
|
-
data.projectId,
|
|
50
|
-
u.dim("view") + ":",
|
|
51
|
-
data.viewId,
|
|
52
|
-
u.dim("change") + ":",
|
|
53
|
-
data.change.op
|
|
54
|
-
].join(" "));
|
|
55
|
-
const result = await likec4.editor.applyChange(data);
|
|
56
|
-
if (!result.success) {
|
|
57
|
-
logger.error(`Failed to apply view change:\n${result.error}`);
|
|
58
|
-
const err = new Error(result.error);
|
|
59
|
-
err.stack = result.error;
|
|
60
|
-
throw err;
|
|
61
|
-
}
|
|
62
|
-
logger.info([u.green("view:onChange"), "✅"].join(" "));
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
//#endregion
|
|
66
|
-
//#region src/vite-plugin/rpc/rpc.ts
|
|
67
|
-
function enablePluginRPC(params) {
|
|
68
|
-
let lastError = null;
|
|
69
|
-
const server = params.server;
|
|
70
|
-
createBirpc({
|
|
71
|
-
updateView: (data) => updateView(params, data),
|
|
72
|
-
calcAdhocView: (data) => calcAdhocView(params, data)
|
|
73
|
-
}, {
|
|
74
|
-
on: (fn) => server.hot.on("likec4:rpc", fn),
|
|
75
|
-
post: (data) => server.hot.send("likec4:rpc", data),
|
|
76
|
-
onFunctionError: (error, functionName) => {
|
|
77
|
-
params.logger.error(`RPC error in ${functionName}`, { error });
|
|
78
|
-
const errorString = error.stack ?? error.message;
|
|
79
|
-
try {
|
|
80
|
-
if (lastError !== errorString) {
|
|
81
|
-
lastError = errorString;
|
|
82
|
-
sendError(server, {
|
|
83
|
-
name: error.name,
|
|
84
|
-
error: errorString
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
} catch (e) {
|
|
88
|
-
params.logger.error(`Failed to send error to client`, { error: e });
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
//#endregion
|
|
95
|
-
//#region ../generators/src/d2/generate-d2.ts
|
|
96
|
-
const capitalizeFirstLetter$2 = (value) => value.charAt(0).toLocaleUpperCase() + value.slice(1);
|
|
97
|
-
const fqnName$2 = (nodeId) => nodeId.split(".").map(capitalizeFirstLetter$2).join("");
|
|
98
|
-
const nodeName$2 = (node) => {
|
|
99
|
-
return fqnName$2(node.parent ? node.id.slice(node.parent.length + 1) : node.id);
|
|
100
|
-
};
|
|
101
|
-
const d2direction = ({ autoLayout }) => {
|
|
102
|
-
switch (autoLayout.direction) {
|
|
103
|
-
case "TB": return "down";
|
|
104
|
-
case "BT": return "up";
|
|
105
|
-
case "LR": return "right";
|
|
106
|
-
case "RL": return "left";
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
const d2shape = ({ shape }) => {
|
|
110
|
-
switch (shape) {
|
|
111
|
-
case "queue":
|
|
112
|
-
case "cylinder":
|
|
113
|
-
case "rectangle":
|
|
114
|
-
case "document": return shape;
|
|
115
|
-
case "person": return "c4-person";
|
|
116
|
-
case "storage": return "stored_data";
|
|
117
|
-
case "bucket":
|
|
118
|
-
case "mobile":
|
|
119
|
-
case "browser": return "rectangle";
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
function generateD2(viewmodel) {
|
|
123
|
-
const view = viewmodel.$view;
|
|
124
|
-
const { nodes, edges } = view;
|
|
125
|
-
const names = /* @__PURE__ */ new Map();
|
|
126
|
-
const printNode = (node, parentName) => {
|
|
127
|
-
const name = nodeName$2(node);
|
|
128
|
-
const fqnName = (parentName ? parentName + "." : "") + name;
|
|
129
|
-
names.set(node.id, fqnName);
|
|
130
|
-
const label = JSON.stringify(node.title);
|
|
131
|
-
const shape = d2shape(node);
|
|
132
|
-
return new CompositeGeneratorNode().append(name, ": {", NL).indent({
|
|
133
|
-
indentedChildren: (indent) => indent.append("label: ", label, NL).appendIf(shape !== "rectangle", "shape: ", shape, NL).appendIf(node.children.length > 0, NL, joinToNode(nodes.filter((n) => n.parent === node.id), (n) => printNode(n, fqnName))),
|
|
134
|
-
indentation: 2
|
|
135
|
-
}).append("}", NL);
|
|
136
|
-
};
|
|
137
|
-
const printEdge = (edge) => {
|
|
138
|
-
return new CompositeGeneratorNode().append(names.get(edge.source), " -> ", names.get(edge.target)).append((out) => edge.label && out.append(": ", JSON.stringify(edge.label)));
|
|
139
|
-
};
|
|
140
|
-
return toString(new CompositeGeneratorNode().append("direction: ", d2direction(view), NL, NL).append(joinToNode(nodes.filter((n) => e(n.parent)), (n) => printNode(n), { appendNewLineIfNotEmpty: true })).appendIf(edges.length > 0, NL, joinToNode(edges, (e) => printEdge(e), { appendNewLineIfNotEmpty: true })));
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
//#endregion
|
|
144
|
-
//#region ../generators/src/mmd/generate-mmd.ts
|
|
145
|
-
const capitalizeFirstLetter$1 = (value) => value.charAt(0).toLocaleUpperCase() + value.slice(1);
|
|
146
|
-
const fqnName$1 = (nodeId) => nodeId.split(".").map(capitalizeFirstLetter$1).join("");
|
|
147
|
-
const nodeName$1 = (node) => {
|
|
148
|
-
return fqnName$1(node.parent ? node.id.slice(node.parent.length + 1) : node.id);
|
|
149
|
-
};
|
|
150
|
-
const toSingleQuotes = (str) => str.replace(/\\?"/g, `'`);
|
|
151
|
-
const mmdshape = ({ shape, title }) => {
|
|
152
|
-
const label = `label: ${JSON.stringify(title)}`;
|
|
153
|
-
switch (shape) {
|
|
154
|
-
case "queue": return `@{ shape: horizontal-cylinder, ${label} }`;
|
|
155
|
-
case "person": return `@{ icon: "fa:user", shape: rounded, ${label} }`;
|
|
156
|
-
case "storage": return `@{ shape: disk, ${label} }`;
|
|
157
|
-
case "cylinder": return `@{ shape: cylinder, ${label} }`;
|
|
158
|
-
case "mobile":
|
|
159
|
-
case "browser": return `@{ shape: rounded, ${label} }`;
|
|
160
|
-
case "bucket": return `@{ shape: trap-t, ${label} }`;
|
|
161
|
-
case "rectangle": return `@{ shape: rectangle, ${label} }`;
|
|
162
|
-
case "document": return `@{ shape: doc, ${label} }`;
|
|
163
|
-
default: nonexhaustive(shape);
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
function generateMermaid(viewmodel) {
|
|
167
|
-
const view = viewmodel.$view;
|
|
168
|
-
const { nodes, edges } = view;
|
|
169
|
-
const names = /* @__PURE__ */ new Map();
|
|
170
|
-
const printNode = (node, parentName) => {
|
|
171
|
-
const name = nodeName$1(node);
|
|
172
|
-
const fqnName = (parentName ? parentName + "." : "") + name;
|
|
173
|
-
names.set(node.id, fqnName);
|
|
174
|
-
const baseNode = new CompositeGeneratorNode();
|
|
175
|
-
if (node.children.length > 0) {
|
|
176
|
-
const label = toSingleQuotes(node.title);
|
|
177
|
-
baseNode.append("subgraph ", fqnName, "[\"`", label, "`\"]", NL).indent({
|
|
178
|
-
indentedChildren: [joinToNode(nodes.filter((n) => n.parent === node.id), (n) => printNode(n, fqnName), { appendNewLineIfNotEmpty: true })],
|
|
179
|
-
indentation: 2
|
|
180
|
-
}).append("end", NL);
|
|
181
|
-
} else baseNode.append(fqnName, mmdshape(node));
|
|
182
|
-
return baseNode;
|
|
183
|
-
};
|
|
184
|
-
const printEdge = (edge) => {
|
|
185
|
-
return new CompositeGeneratorNode().append(names.get(edge.source), " -.", edge.label ? " \"`" + toSingleQuotes(edge.label) + "`\" .-" : "-", "> ", names.get(edge.target));
|
|
186
|
-
};
|
|
187
|
-
return toString(new CompositeGeneratorNode().append("---", NL, `title: ${JSON.stringify(toSingleQuotes(viewmodel.titleOrId))}`, NL, "---", NL).append("graph ", view.autoLayout.direction, NL).indent({
|
|
188
|
-
indentedChildren: (indent) => {
|
|
189
|
-
indent.append(joinToNode(nodes.filter((n) => e(n.parent)), (n) => printNode(n), { appendNewLineIfNotEmpty: true })).appendIf(edges.length > 0, joinToNode(edges, (e) => printEdge(e), { appendNewLineIfNotEmpty: true }));
|
|
190
|
-
},
|
|
191
|
-
indentation: 2
|
|
192
|
-
}));
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
//#endregion
|
|
196
|
-
//#region ../generators/src/puml/generate-puml.ts
|
|
197
|
-
const capitalizeFirstLetter = (value) => value.charAt(0).toLocaleUpperCase() + value.slice(1);
|
|
198
|
-
const fqnName = (nodeId) => {
|
|
199
|
-
return nodeId.split(/[.-]/).map(capitalizeFirstLetter).join("");
|
|
200
|
-
};
|
|
201
|
-
const nodeName = (node) => {
|
|
202
|
-
return fqnName(node.parent ? node.id.slice(node.parent.length + 1) : node.id);
|
|
203
|
-
};
|
|
204
|
-
const pumlColor = (color, customColorProvider, defaultColor = "#3b82f6") => {
|
|
205
|
-
if (color) return customColorProvider(color) ?? defaultColor;
|
|
206
|
-
return defaultColor;
|
|
207
|
-
};
|
|
208
|
-
const pumlDirection = ({ autoLayout }) => {
|
|
209
|
-
switch (autoLayout.direction) {
|
|
210
|
-
case "TB": return "top to bottom";
|
|
211
|
-
case "BT":
|
|
212
|
-
console.warn("Bottom to top direction is not supported. Defaulting to top to bottom.");
|
|
213
|
-
return "top to bottom";
|
|
214
|
-
case "LR": return "left to right";
|
|
215
|
-
case "RL":
|
|
216
|
-
console.warn("Right to left direction is not supported. Defaulting to left to right.");
|
|
217
|
-
return "left to right";
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
const pumlShape = ({ shape }) => {
|
|
221
|
-
switch (shape) {
|
|
222
|
-
case "queue":
|
|
223
|
-
case "rectangle":
|
|
224
|
-
case "person": return shape;
|
|
225
|
-
case "storage":
|
|
226
|
-
case "cylinder": return "database";
|
|
227
|
-
case "document":
|
|
228
|
-
case "mobile":
|
|
229
|
-
case "bucket":
|
|
230
|
-
case "browser": return "rectangle";
|
|
231
|
-
default: nonexhaustive(shape);
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
const escapeLabel = (label) => e$1(label) ? null : JSON.stringify(label).slice(1, -1).replace(/\\"/g, "\"");
|
|
235
|
-
function generatePuml(viewmodel) {
|
|
236
|
-
const view = viewmodel.$view;
|
|
237
|
-
const colors = viewmodel.$model.$styles.theme.colors;
|
|
238
|
-
const { nodes, edges } = view;
|
|
239
|
-
const elemntColorProvider = (key) => (colorKey) => colorKey in colors ? colors[colorKey].elements[key] : void 0;
|
|
240
|
-
const relationshipsColorProvider = (key) => (colorKey) => colorKey in colors ? colors[colorKey].relationships[key] : void 0;
|
|
241
|
-
const names = /* @__PURE__ */ new Map();
|
|
242
|
-
const printHeader = () => {
|
|
243
|
-
return new CompositeGeneratorNode().append("title \"", viewmodel.titleOrId, "\"", NL).append(pumlDirection(view), " direction", NL);
|
|
244
|
-
};
|
|
245
|
-
const printTheme = () => {
|
|
246
|
-
return new CompositeGeneratorNode().append("hide stereotype", NL).append("skinparam ranksep ", "60", NL).append("skinparam nodesep ", "30", NL).append("skinparam {", NL).indent({
|
|
247
|
-
indentedChildren: (indent) => indent.append("arrowFontSize ", "10", NL).append("defaultTextAlignment ", "center", NL).append("wrapWidth ", "200", NL).append("maxMessageSize ", "100", NL).append("shadowing ", "false", NL),
|
|
248
|
-
indentation: 2
|
|
249
|
-
}).append("}", NL);
|
|
250
|
-
};
|
|
251
|
-
const printStereotypes = (node) => {
|
|
252
|
-
const shape = pumlShape(node);
|
|
253
|
-
const fqn = fqnName(node.id);
|
|
254
|
-
return new CompositeGeneratorNode().append("skinparam ", shape, "<<", fqn, ">>", "{", NL).indent({
|
|
255
|
-
indentedChildren: (indent) => indent.append("BackgroundColor ", pumlColor(node.color, elemntColorProvider("fill")), NL).append("FontColor ", pumlColor(node.color, elemntColorProvider("hiContrast"), "#FFFFFF"), NL).append("BorderColor ", pumlColor(node.color, elemntColorProvider("stroke")), NL),
|
|
256
|
-
indentation: 2
|
|
257
|
-
}).append("}", NL);
|
|
258
|
-
};
|
|
259
|
-
const printNode = (node) => {
|
|
260
|
-
const shape = pumlShape(node);
|
|
261
|
-
const fqn = fqnName(node.id);
|
|
262
|
-
const label = escapeLabel(node.title) || nodeName(node);
|
|
263
|
-
const tech = escapeLabel(node.technology);
|
|
264
|
-
names.set(node.id, fqn);
|
|
265
|
-
const description = RichText.from(node.description);
|
|
266
|
-
return new CompositeGeneratorNode().append(shape, " ").append("\"").append("==", label).appendIf(!!tech, `\\n<size:10>[`, tech, "]</size>").appendIf(description.nonEmpty, `\\n\\n`, escapeLabel(description.text)).append("\"", " <<", fqn, ">> ", "as ", fqn, NL);
|
|
267
|
-
};
|
|
268
|
-
const printBoundary = (node) => {
|
|
269
|
-
const label = escapeLabel(node.title) || nodeName(node);
|
|
270
|
-
const fqn = fqnName(node.id);
|
|
271
|
-
names.set(node.id, fqn);
|
|
272
|
-
return new CompositeGeneratorNode().append("rectangle \"", label, "\" <<", fqn, ">> as ", fqn, " {", NL).indent({
|
|
273
|
-
indentedChildren: (indent) => indent.append("skinparam ", "RectangleBorderColor<<", fqn, ">> ", pumlColor(node.color, elemntColorProvider("fill")), NL).append("skinparam ", "RectangleFontColor<<", fqn, ">> ", pumlColor(node.color, elemntColorProvider("fill")), NL).append("skinparam ", "RectangleBorderStyle<<", fqn, ">> ", "dashed", NL, NL).append(joinToNode(nodes.filter((n) => n.parent === node.id), (c) => c.children.length > 0 ? printBoundary(c) : printNode(c))),
|
|
274
|
-
indentation: 2
|
|
275
|
-
}).append("}", NL);
|
|
276
|
-
};
|
|
277
|
-
const printEdge = (edge) => {
|
|
278
|
-
const tech = edge.technology || "";
|
|
279
|
-
const label = edge.label || tech;
|
|
280
|
-
const color = pumlColor(edge.color, relationshipsColorProvider("line"), "#777777");
|
|
281
|
-
const withColor = (text) => `<color:${color}>${text.replaceAll("\"", `'`)}`;
|
|
282
|
-
const out = new CompositeGeneratorNode().append(names.get(edge.source), " .[", color, ",thickness=2].> ", names.get(edge.target));
|
|
283
|
-
if (label || tech) {
|
|
284
|
-
out.append(" : ", label.split("\n").map((l) => e$1(l) ? l : withColor(l)).join("\\n"));
|
|
285
|
-
if (tech && tech !== label) out.append("\\n<size:8>[", withColor(tech), "]</size>");
|
|
286
|
-
}
|
|
287
|
-
return out.append(NL);
|
|
288
|
-
};
|
|
289
|
-
return toString(new CompositeGeneratorNode().append("@startuml", NL).append(printHeader(), NL).append(printTheme(), NL).append(joinToNode(nodes.filter((n) => n.children.length == 0), (n) => printStereotypes(n), { appendNewLineIfNotEmpty: true })).append(joinToNode(nodes.filter((n) => e(n.parent)), (n) => n.children.length > 0 ? printBoundary(n) : printNode(n), { appendNewLineIfNotEmpty: true })).appendIf(edges.length > 0, NL, joinToNode(edges, (e) => printEdge(e), { appendNewLineIfNotEmpty: true })).append(`@enduml`, NL));
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
//#endregion
|
|
293
|
-
//#region src/vite-plugin/virtuals/_shared.ts
|
|
294
|
-
function generateMatches(moduleId, extension = ".js") {
|
|
295
|
-
return {
|
|
296
|
-
matches: (id) => {
|
|
297
|
-
let { module, projectId } = id.match(/^likec4:plugin\/(?<projectId>.+)\/(?<module>.+)$/)?.groups ?? id.match(/^likec4:(?<module>.+)\/(?<projectId>.+)$/)?.groups ?? {};
|
|
298
|
-
if (!module || !projectId) return null;
|
|
299
|
-
if (module.endsWith(extension)) module = module.slice(0, -extension.length);
|
|
300
|
-
if (module === moduleId) return projectId;
|
|
301
|
-
return null;
|
|
302
|
-
},
|
|
303
|
-
virtualId: (projectId) => joinURL(`likec4:plugin`, projectId, moduleId) + extension
|
|
304
|
-
};
|
|
305
|
-
}
|
|
306
|
-
const charMap = {
|
|
307
|
-
"<": "\\u003C",
|
|
308
|
-
">": "\\u003E",
|
|
309
|
-
"/": "\\u002F",
|
|
310
|
-
"\\": "\\\\",
|
|
311
|
-
"\b": "\\b",
|
|
312
|
-
"\f": "\\f",
|
|
313
|
-
"\n": "\\n",
|
|
314
|
-
"\r": "\\r",
|
|
315
|
-
" ": "\\t",
|
|
316
|
-
"\0": "\\0",
|
|
317
|
-
"\u2028": "\\u2028",
|
|
318
|
-
"\u2029": "\\u2029"
|
|
319
|
-
};
|
|
320
|
-
function escapeUnsafeChars(str) {
|
|
321
|
-
return str.replace(/[<>\b\f\n\r\t\0\u2028\u2029\\]/g, (x) => charMap[x]);
|
|
322
|
-
}
|
|
323
|
-
function generateCombinedProjects(moduleId, fnName) {
|
|
324
|
-
return {
|
|
325
|
-
id: `likec4:${moduleId}`,
|
|
326
|
-
virtualId: `likec4:plugin/${moduleId}.js`,
|
|
327
|
-
async load({ logger, projects }) {
|
|
328
|
-
logger.info(u.dim(`generating likec4:${moduleId}`));
|
|
329
|
-
return `
|
|
330
|
-
export let ${fnName}Fn = {
|
|
331
|
-
${projects.map(({ id }) => {
|
|
332
|
-
const pkg = escapeUnsafeChars(JSON.stringify(joinURL(`likec4:${moduleId}`, id)));
|
|
333
|
-
return ` ${JSON.stringify(id)}: () => import(${pkg})`;
|
|
334
|
-
}).join(",\n")}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
export async function ${fnName}(projectId) {
|
|
338
|
-
let fn = ${fnName}Fn[projectId]
|
|
339
|
-
if (!fn) {
|
|
340
|
-
const projects = Object.keys(${fnName}Fn)
|
|
341
|
-
console.error('Unknown projectId: ' + projectId + ' (available: ' + projects + ')')
|
|
342
|
-
if (projects.length === 0) {
|
|
343
|
-
throw new Error('No projects found, invalid state')
|
|
344
|
-
}
|
|
345
|
-
projectId = projects[0]
|
|
346
|
-
console.warn('Falling back to project: ' + projectId)
|
|
347
|
-
fn = ${fnName}Fn[projectId]
|
|
348
|
-
}
|
|
349
|
-
return await fn()
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
if (import.meta.hot) {
|
|
353
|
-
import.meta.hot.accept(md => {
|
|
354
|
-
if (!import.meta.hot.data.$update) {
|
|
355
|
-
import.meta.hot.data.$update = ${fnName}Fn
|
|
356
|
-
}
|
|
357
|
-
const update = md.${fnName}Fn
|
|
358
|
-
if (update) {
|
|
359
|
-
Object.assign(import.meta.hot.data.$update, update)
|
|
360
|
-
} else {
|
|
361
|
-
import.meta.hot.invalidate()
|
|
362
|
-
}
|
|
363
|
-
})
|
|
364
|
-
}
|
|
365
|
-
`;
|
|
366
|
-
}
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
//#endregion
|
|
371
|
-
//#region src/vite-plugin/virtuals/d2.ts
|
|
372
|
-
function code$8(model) {
|
|
373
|
-
const out = new CompositeGeneratorNode();
|
|
374
|
-
out.appendTemplate`
|
|
375
|
-
/******************************************************************************
|
|
376
|
-
* This file was generated
|
|
377
|
-
* DO NOT EDIT MANUALLY!
|
|
378
|
-
******************************************************************************/
|
|
379
|
-
/* eslint-disable */
|
|
380
|
-
|
|
381
|
-
export function d2Source(viewId) {
|
|
382
|
-
switch (viewId) {
|
|
383
|
-
`.appendNewLine().indent({
|
|
384
|
-
indentation: 4,
|
|
385
|
-
indentedChildren(indented) {
|
|
386
|
-
indented.append(joinToNode([...model.views()], (view) => expandToNode`
|
|
387
|
-
case ${JSON.stringify(view.id)}: {
|
|
388
|
-
return ${JSON.stringify(generateD2(view))}
|
|
389
|
-
}
|
|
390
|
-
`, { appendNewLineIfNotEmpty: true })).appendTemplate`
|
|
391
|
-
default: {
|
|
392
|
-
throw new Error('Unknown viewId: ' + viewId)
|
|
393
|
-
}
|
|
394
|
-
`;
|
|
395
|
-
}
|
|
396
|
-
}).append(NL, " }", NL).appendTemplate`
|
|
397
|
-
}
|
|
398
|
-
`.append(NL, NL);
|
|
399
|
-
return toString(out);
|
|
400
|
-
}
|
|
401
|
-
const projectD2Module = {
|
|
402
|
-
...generateMatches("d2"),
|
|
403
|
-
async load({ likec4, project, logger }) {
|
|
404
|
-
logger.info(u.dim(`generating likec4:d2/${project.id}`));
|
|
405
|
-
return code$8(await likec4.computedModel(project.id));
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
const d2Module = generateCombinedProjects("d2", "loadD2Sources");
|
|
409
|
-
|
|
410
|
-
//#endregion
|
|
411
|
-
//#region src/vite-plugin/virtuals/dot.ts
|
|
412
|
-
function code$7(sources) {
|
|
413
|
-
const out = new CompositeGeneratorNode();
|
|
414
|
-
out.appendTemplate`
|
|
415
|
-
/******************************************************************************
|
|
416
|
-
* This file was generated
|
|
417
|
-
* DO NOT EDIT MANUALLY!
|
|
418
|
-
******************************************************************************/
|
|
419
|
-
/* eslint-disable */
|
|
420
|
-
|
|
421
|
-
export function dotSource(viewId) {
|
|
422
|
-
switch (viewId) {
|
|
423
|
-
`.appendNewLine().indent({
|
|
424
|
-
indentation: 4,
|
|
425
|
-
indentedChildren(indented) {
|
|
426
|
-
indented.append(joinToNode(Object.keys(sources), (key) => expandToNode`
|
|
427
|
-
case ${JSON.stringify(key)}: {
|
|
428
|
-
return ${JSON.stringify(sources[key].dot)}
|
|
429
|
-
}
|
|
430
|
-
`, { appendNewLineIfNotEmpty: true })).appendTemplate`
|
|
431
|
-
default: {
|
|
432
|
-
throw new Error('Unknown viewId: ' + viewId)
|
|
433
|
-
}
|
|
434
|
-
`;
|
|
435
|
-
}
|
|
436
|
-
}).append(NL, " }", NL).appendTemplate`
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
export function svgSource(viewId) {
|
|
440
|
-
switch (viewId) {
|
|
441
|
-
`.appendNewLine().indent({
|
|
442
|
-
indentation: 4,
|
|
443
|
-
indentedChildren(indented) {
|
|
444
|
-
indented.append(joinToNode(Object.keys(sources), (key) => expandToNode`
|
|
445
|
-
case ${JSON.stringify(key)}: {
|
|
446
|
-
return ${JSON.stringify(sources[key].svg)}
|
|
447
|
-
}
|
|
448
|
-
`, { appendNewLineIfNotEmpty: true })).appendTemplate`
|
|
449
|
-
default: {
|
|
450
|
-
throw new Error('Unknown viewId: ' + viewId)
|
|
451
|
-
}
|
|
452
|
-
`;
|
|
453
|
-
}
|
|
454
|
-
}).append(NL, " }", NL, "}", NL, NL);
|
|
455
|
-
return toString(out);
|
|
456
|
-
}
|
|
457
|
-
const projectDotSourcesModule = {
|
|
458
|
-
...generateMatches("dot"),
|
|
459
|
-
async load({ likec4, project, logger }) {
|
|
460
|
-
logger.info(u.dim(`generating likec4:dot/${project.id}`));
|
|
461
|
-
return code$7(t(await likec4.views.viewsAsGraphvizOut(project.id), ({ id, svg, dot }) => [id, {
|
|
462
|
-
dot,
|
|
463
|
-
svg
|
|
464
|
-
}]));
|
|
465
|
-
}
|
|
466
|
-
};
|
|
467
|
-
const dotModule = generateCombinedProjects("dot", "loadDotSources");
|
|
468
|
-
|
|
469
|
-
//#endregion
|
|
470
|
-
//#region src/vite-plugin/virtuals/icons.ts
|
|
471
|
-
function code$6(views) {
|
|
472
|
-
const { imports, cases } = t$1(views.flatMap((v) => v.nodes.map((n) => n.icon)), n((s) => e$2(s) && !(s.toLowerCase().startsWith("http:") || s.toLowerCase().startsWith("https:"))), n$1(), t$2(compareNatural)).reduce((acc, s, i) => {
|
|
473
|
-
const isLocalImage = s.startsWith("file:");
|
|
474
|
-
const Component = "Icon" + i.toString().padStart(2, "0");
|
|
475
|
-
if (isLocalImage) {
|
|
476
|
-
acc.imports.push(`import ${Component} from '${s}?inline'`);
|
|
477
|
-
acc.cases.push(` '${s}': () => jsx('img', { src: ${Component} })`);
|
|
478
|
-
return acc;
|
|
479
|
-
}
|
|
480
|
-
const [group, icon] = s.split(":");
|
|
481
|
-
acc.imports.push(`import ${Component} from '@likec4/icons/${group}/${icon}'`);
|
|
482
|
-
acc.cases.push(` '${group}:${icon}': ${Component}`);
|
|
483
|
-
return acc;
|
|
484
|
-
}, {
|
|
485
|
-
imports: [],
|
|
486
|
-
cases: []
|
|
487
|
-
});
|
|
488
|
-
return `
|
|
489
|
-
import { jsx } from 'react/jsx-runtime'
|
|
490
|
-
${imports.join("\n")}
|
|
491
|
-
|
|
492
|
-
const Icons = {
|
|
493
|
-
${cases.join(",\n")}
|
|
494
|
-
}
|
|
495
|
-
export function IconRenderer({ node, ...props }) {
|
|
496
|
-
const IconComponent = Icons[node.icon ?? '']
|
|
497
|
-
if (!IconComponent) {
|
|
498
|
-
return null
|
|
499
|
-
}
|
|
500
|
-
return jsx(IconComponent, props)
|
|
501
|
-
}
|
|
502
|
-
`;
|
|
503
|
-
}
|
|
504
|
-
const projectIconsModule = {
|
|
505
|
-
...generateMatches("icons", ".jsx"),
|
|
506
|
-
async load({ likec4, project, logger }) {
|
|
507
|
-
logger.info(u.dim(`generating likec4:icons/${project.id}`));
|
|
508
|
-
return code$6(await likec4.views.computedViews(project.id));
|
|
509
|
-
}
|
|
510
|
-
};
|
|
511
|
-
const iconsModule = {
|
|
512
|
-
id: "likec4:icons",
|
|
513
|
-
virtualId: "likec4:plugin/icons.jsx",
|
|
514
|
-
async load({ projects, logger }) {
|
|
515
|
-
logger.info(u.dim(`generating likec4:icons`));
|
|
516
|
-
const { imports, cases } = projects.reduce((acc, { id }, i) => {
|
|
517
|
-
const Component = "Icons" + i.toString().padStart(2, "0");
|
|
518
|
-
const pkg = joinURL("likec4:icons", id);
|
|
519
|
-
acc.imports.push(`import { IconRenderer as ${Component} } from ${JSON.stringify(pkg)}`);
|
|
520
|
-
acc.cases.push(` case ${JSON.stringify(id)}: return ${Component}`);
|
|
521
|
-
return acc;
|
|
522
|
-
}, {
|
|
523
|
-
imports: [],
|
|
524
|
-
cases: []
|
|
525
|
-
});
|
|
526
|
-
return `
|
|
527
|
-
import { jsx } from 'react/jsx-runtime'
|
|
528
|
-
${imports.join("\n")}
|
|
529
|
-
|
|
530
|
-
function getProjectIcons(projectId) {
|
|
531
|
-
switch (projectId) {
|
|
532
|
-
${cases.join("\n")}
|
|
533
|
-
default:
|
|
534
|
-
throw new Error('Unknown projectId: ' + projectId)
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
export function ProjectIcons({ projectId, ...props }) {
|
|
539
|
-
const IconComponent = getProjectIcons(projectId)
|
|
540
|
-
return jsx(IconComponent, props)
|
|
541
|
-
}
|
|
542
|
-
`;
|
|
543
|
-
}
|
|
544
|
-
};
|
|
545
|
-
|
|
546
|
-
//#endregion
|
|
547
|
-
//#region src/vite-plugin/virtuals/mmd.ts
|
|
548
|
-
function code$5(model) {
|
|
549
|
-
const out = new CompositeGeneratorNode();
|
|
550
|
-
out.appendTemplate`
|
|
551
|
-
/******************************************************************************
|
|
552
|
-
* This file was generated
|
|
553
|
-
* DO NOT EDIT MANUALLY!
|
|
554
|
-
******************************************************************************/
|
|
555
|
-
/* eslint-disable */
|
|
556
|
-
|
|
557
|
-
export function mmdSource(viewId) {
|
|
558
|
-
switch (viewId) {
|
|
559
|
-
`.appendNewLine().indent({
|
|
560
|
-
indentation: 4,
|
|
561
|
-
indentedChildren(indented) {
|
|
562
|
-
indented.append(joinToNode([...model.views()], (view) => expandToNode`
|
|
563
|
-
case ${JSON.stringify(view.id)}: {
|
|
564
|
-
return ${JSON.stringify(generateMermaid(view))}
|
|
565
|
-
}
|
|
566
|
-
`, { appendNewLineIfNotEmpty: true })).appendTemplate`
|
|
567
|
-
default: {
|
|
568
|
-
throw new Error('Unknown viewId: ' + viewId)
|
|
569
|
-
}
|
|
570
|
-
`;
|
|
571
|
-
}
|
|
572
|
-
}).append(NL, " }", NL).appendTemplate`
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
`.append(NL, NL);
|
|
576
|
-
return toString(out);
|
|
577
|
-
}
|
|
578
|
-
const projectMmdSourcesModule = {
|
|
579
|
-
...generateMatches("mmd"),
|
|
580
|
-
async load({ likec4, project, logger }) {
|
|
581
|
-
logger.info(u.dim(`generating virtual:likec4/mmd/${project.id}`));
|
|
582
|
-
return code$5(await likec4.computedModel(project.id));
|
|
583
|
-
}
|
|
584
|
-
};
|
|
585
|
-
const mmdModule = generateCombinedProjects("mmd", "loadMmdSources");
|
|
586
|
-
|
|
587
|
-
//#endregion
|
|
588
|
-
//#region src/vite-plugin/virtuals/model.ts
|
|
589
|
-
var import_lib = /* @__PURE__ */ __toESM(require_lib(), 1);
|
|
590
|
-
const projectModelCode = (model) => `
|
|
591
|
-
import { createHooksForModel, atom } from 'likec4/vite-plugin/internal'
|
|
592
|
-
|
|
593
|
-
export const $likec4data = atom(${import_lib.default.stringify(model.$data)})
|
|
594
|
-
|
|
595
|
-
export const {
|
|
596
|
-
updateModel,
|
|
597
|
-
$likec4model,
|
|
598
|
-
useLikeC4Model,
|
|
599
|
-
useLikeC4Views,
|
|
600
|
-
useLikeC4View
|
|
601
|
-
} = createHooksForModel($likec4data)
|
|
602
|
-
|
|
603
|
-
if (import.meta.hot) {
|
|
604
|
-
import.meta.hot.accept(md => {
|
|
605
|
-
if (!import.meta.hot.data.$update) {
|
|
606
|
-
import.meta.hot.data.$update = updateModel
|
|
607
|
-
}
|
|
608
|
-
const update = md.$likec4data?.get()
|
|
609
|
-
if (update) {
|
|
610
|
-
import.meta.hot.data.$update(update)
|
|
611
|
-
} else {
|
|
612
|
-
import.meta.hot.invalidate()
|
|
613
|
-
}
|
|
614
|
-
})
|
|
615
|
-
}
|
|
616
|
-
`;
|
|
617
|
-
const projectModelModule = {
|
|
618
|
-
...generateMatches("model"),
|
|
619
|
-
async load({ likec4, project, logger }) {
|
|
620
|
-
logger.info(u.dim(`generating likec4:model/${project.id}`));
|
|
621
|
-
return projectModelCode(await likec4.layoutedModel(project.id));
|
|
622
|
-
}
|
|
623
|
-
};
|
|
624
|
-
const modelModule = generateCombinedProjects("model", "loadModel");
|
|
625
|
-
|
|
626
|
-
//#endregion
|
|
627
|
-
//#region src/vite-plugin/virtuals/projects.ts
|
|
628
|
-
const code$4 = (projects) => `
|
|
629
|
-
import { atom, useStore } from 'likec4/vite-plugin/internal'
|
|
630
|
-
|
|
631
|
-
export const isSingleProject = ${projects.length === 1};
|
|
632
|
-
export const projects = ${import_lib.default.stringify(projects, null, 2)};
|
|
633
|
-
|
|
634
|
-
export const $projects = atom([...projects])
|
|
635
|
-
|
|
636
|
-
export function useLikeC4Projects() {
|
|
637
|
-
return useStore($projects)
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
if (import.meta.hot) {
|
|
641
|
-
import.meta.hot.accept(md => {
|
|
642
|
-
if (!import.meta.hot.data.$projects) {
|
|
643
|
-
import.meta.hot.data.$projects = $projects
|
|
644
|
-
}
|
|
645
|
-
if (!import.meta.hot.data.projects) {
|
|
646
|
-
import.meta.hot.data.projects = projects
|
|
647
|
-
}
|
|
648
|
-
const update = md.projects
|
|
649
|
-
if (update) {
|
|
650
|
-
import.meta.hot.data.projects.length = 0
|
|
651
|
-
import.meta.hot.data.projects.push(...update)
|
|
652
|
-
import.meta.hot.data.$projects.set(update)
|
|
653
|
-
} else {
|
|
654
|
-
import.meta.hot.invalidate()
|
|
655
|
-
}
|
|
656
|
-
})
|
|
657
|
-
}
|
|
658
|
-
`;
|
|
659
|
-
const projectsModule = {
|
|
660
|
-
id: "likec4:projects",
|
|
661
|
-
virtualId: "likec4:plugin/projects.js",
|
|
662
|
-
async load({ logger, projects }) {
|
|
663
|
-
logger.info(u.dim("generating likec4:projects"));
|
|
664
|
-
return code$4(t$3(projects, t$4(["id", "title"])));
|
|
665
|
-
}
|
|
666
|
-
};
|
|
667
|
-
|
|
668
|
-
//#endregion
|
|
669
|
-
//#region src/vite-plugin/virtuals/projectsOverview.ts
|
|
670
|
-
const code$3 = (view) => `
|
|
671
|
-
import { atom, useStore } from 'likec4/vite-plugin/internal'
|
|
672
|
-
|
|
673
|
-
export const $viewdata = atom(${import_lib.default.stringify(view)})
|
|
674
|
-
|
|
675
|
-
export function useLikeC4ProjectsOverview() {
|
|
676
|
-
return useStore($viewdata)
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
if (import.meta.hot) {
|
|
680
|
-
import.meta.hot.accept(md => {
|
|
681
|
-
if (!import.meta.hot.data.$viewdata) {
|
|
682
|
-
import.meta.hot.data.$viewdata = $viewdata
|
|
683
|
-
}
|
|
684
|
-
const update = md.$viewdata?.get()
|
|
685
|
-
if (update) {
|
|
686
|
-
import.meta.hot.data.$viewdata.set(update)
|
|
687
|
-
} else {
|
|
688
|
-
import.meta.hot.invalidate()
|
|
689
|
-
}
|
|
690
|
-
})
|
|
691
|
-
}
|
|
692
|
-
`;
|
|
693
|
-
const noProjects = () => `
|
|
694
|
-
export function useLikeC4ProjectsOverview() {
|
|
695
|
-
throw new Error('No projects overview available for this workspace: single project mode is enabled')
|
|
696
|
-
}
|
|
697
|
-
`;
|
|
698
|
-
const projectsOverviewModule = {
|
|
699
|
-
id: "likec4:projects-overview",
|
|
700
|
-
virtualId: "likec4:plugin/projects-overview.js",
|
|
701
|
-
async load({ logger, projects, likec4 }) {
|
|
702
|
-
if (projects.length < 2) return noProjects();
|
|
703
|
-
logger.info(u.dim("generating likec4:projects-overview"));
|
|
704
|
-
return code$3(await likec4.projectsOverview());
|
|
705
|
-
}
|
|
706
|
-
};
|
|
707
|
-
|
|
708
|
-
//#endregion
|
|
709
|
-
//#region src/vite-plugin/virtuals/puml.ts
|
|
710
|
-
function code$2(model) {
|
|
711
|
-
const out = new CompositeGeneratorNode();
|
|
712
|
-
out.appendTemplate`
|
|
713
|
-
/******************************************************************************
|
|
714
|
-
* This file was generated
|
|
715
|
-
* DO NOT EDIT MANUALLY!
|
|
716
|
-
******************************************************************************/
|
|
717
|
-
/* eslint-disable */
|
|
718
|
-
|
|
719
|
-
export function pumlSource(viewId) {
|
|
720
|
-
switch (viewId) {
|
|
721
|
-
`.appendNewLine().indent({
|
|
722
|
-
indentation: 4,
|
|
723
|
-
indentedChildren(indented) {
|
|
724
|
-
indented.append(joinToNode([...model.views()], (view) => expandToNode`
|
|
725
|
-
case ${JSON.stringify(view.id)}: {
|
|
726
|
-
return ${JSON.stringify(generatePuml(view))}
|
|
727
|
-
}
|
|
728
|
-
`, { appendNewLineIfNotEmpty: true })).appendTemplate`
|
|
729
|
-
default: {
|
|
730
|
-
throw new Error('Unknown viewId: ' + viewId)
|
|
731
|
-
}
|
|
732
|
-
`;
|
|
733
|
-
}
|
|
734
|
-
}).append(NL, " }", NL).appendTemplate`
|
|
735
|
-
}
|
|
736
|
-
`.append(NL, NL);
|
|
737
|
-
return toString(out);
|
|
738
|
-
}
|
|
739
|
-
const projectPumlModule = {
|
|
740
|
-
...generateMatches("puml"),
|
|
741
|
-
async load({ likec4, project, logger }) {
|
|
742
|
-
logger.info(u.dim(`generating likec4:puml/${project.id}`));
|
|
743
|
-
return code$2(await likec4.computedModel(project.id));
|
|
744
|
-
}
|
|
745
|
-
};
|
|
746
|
-
const pumlModule = generateCombinedProjects("puml", "loadPumlSources");
|
|
747
|
-
|
|
748
|
-
//#endregion
|
|
749
|
-
//#region src/vite-plugin/virtuals/react.ts
|
|
750
|
-
const projectCode = (id) => `
|
|
751
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
752
|
-
import { LikeC4ModelProvider as Provider, LikeC4View as GenericView, ReactLikeC4 as GenericReactLikeC4 } from 'likec4/react';
|
|
753
|
-
import { IconRenderer } from 'likec4:icons/${id}'
|
|
754
|
-
|
|
755
|
-
import { useLikeC4Model, useLikeC4Views, useLikeC4View } from 'likec4:model/${id}'
|
|
756
|
-
|
|
757
|
-
export function LikeC4ModelProvider({ children }) {
|
|
758
|
-
const likeC4Model = useLikeC4Model()
|
|
759
|
-
return (_jsx(Provider, { likec4model: likeC4Model, children: children }));
|
|
760
|
-
}
|
|
761
|
-
export function LikeC4View(props) {
|
|
762
|
-
return (_jsx(LikeC4ModelProvider, { children: _jsx(GenericView, { renderIcon: IconRenderer, ...props }) }));
|
|
763
|
-
}
|
|
764
|
-
export function ReactLikeC4(props) {
|
|
765
|
-
return (_jsx(LikeC4ModelProvider, { children: _jsx(GenericReactLikeC4, { renderIcon: IconRenderer, ...props }) }));
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
export {
|
|
769
|
-
useLikeC4Model,
|
|
770
|
-
useLikeC4View,
|
|
771
|
-
useLikeC4Views
|
|
772
|
-
}
|
|
773
|
-
`;
|
|
774
|
-
const projectReactModule = {
|
|
775
|
-
...generateMatches("react"),
|
|
776
|
-
async load({ project, logger }) {
|
|
777
|
-
logger.info(u.dim(`generating likec4:react/${project.id}`));
|
|
778
|
-
return projectCode(project.id);
|
|
779
|
-
}
|
|
780
|
-
};
|
|
781
|
-
const singleProjectReactModule = {
|
|
782
|
-
id: "likec4:react",
|
|
783
|
-
virtualId: "likec4:plugin/react.js",
|
|
784
|
-
async load({ logger, projects }) {
|
|
785
|
-
const project = n$2(projects);
|
|
786
|
-
logger.info(u.dim("generating likec4:react for") + " " + project.id);
|
|
787
|
-
return projectCode(project.id);
|
|
788
|
-
}
|
|
789
|
-
};
|
|
790
|
-
|
|
791
|
-
//#endregion
|
|
792
|
-
//#region src/vite-plugin/virtuals/rpc.ts
|
|
793
|
-
const code$1 = `
|
|
794
|
-
import { createRpc } from 'likec4/vite-plugin/internal'
|
|
795
|
-
|
|
796
|
-
export const isRpcAvailable = !!import.meta.hot
|
|
797
|
-
|
|
798
|
-
let rpc
|
|
799
|
-
if (import.meta.hot) {
|
|
800
|
-
rpc = createRpc({
|
|
801
|
-
send: (event, data) => {
|
|
802
|
-
import.meta.hot.send(event, data)
|
|
803
|
-
},
|
|
804
|
-
on: (event, fn) => {
|
|
805
|
-
import.meta.hot.on(event, fn)
|
|
806
|
-
}
|
|
807
|
-
})
|
|
808
|
-
|
|
809
|
-
import.meta.hot.accept()
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
export const likec4rpc = rpc ?? {
|
|
813
|
-
updateView: () => {
|
|
814
|
-
throw new Error('likec4rpc.updateView is not available in production')
|
|
815
|
-
},
|
|
816
|
-
calcAdhocView: () => {
|
|
817
|
-
throw new Error('likec4rpc.calcAdhocView is not available in production')
|
|
818
|
-
},
|
|
819
|
-
}
|
|
820
|
-
`;
|
|
821
|
-
const rpcModule = {
|
|
822
|
-
id: "likec4:rpc",
|
|
823
|
-
virtualId: "likec4:plugin/rpc.js",
|
|
824
|
-
async load({ logger }) {
|
|
825
|
-
logger.info(u.dim("generating likec4:rpc"));
|
|
826
|
-
return code$1;
|
|
827
|
-
}
|
|
828
|
-
};
|
|
829
|
-
|
|
830
|
-
//#endregion
|
|
831
|
-
//#region src/vite-plugin/virtuals/single-project.ts
|
|
832
|
-
const code = (id) => `
|
|
833
|
-
export { IconRenderer } from 'likec4:icons/${id}'
|
|
834
|
-
export {
|
|
835
|
-
$likec4data,
|
|
836
|
-
$likec4model,
|
|
837
|
-
useLikeC4Model,
|
|
838
|
-
useLikeC4Views,
|
|
839
|
-
useLikeC4View
|
|
840
|
-
} from 'likec4:model/${id}'
|
|
841
|
-
export const projectId = ${JSON.stringify(id)}
|
|
842
|
-
`;
|
|
843
|
-
const singleProjectModule = {
|
|
844
|
-
id: "likec4:single-project",
|
|
845
|
-
virtualId: "likec4:plugin/single-project.js",
|
|
846
|
-
async load({ logger, projects }) {
|
|
847
|
-
const project = n$2(projects);
|
|
848
|
-
logger.info(u.dim("generating likec4:single-project for") + " " + project.id);
|
|
849
|
-
return code(project.id);
|
|
850
|
-
}
|
|
851
|
-
};
|
|
852
|
-
|
|
853
|
-
//#endregion
|
|
854
|
-
//#region src/vite-plugin/plugin.ts
|
|
855
|
-
const hmrProjectVirtuals = [
|
|
856
|
-
projectModelModule,
|
|
857
|
-
projectIconsModule,
|
|
858
|
-
projectD2Module,
|
|
859
|
-
projectDotSourcesModule,
|
|
860
|
-
projectMmdSourcesModule,
|
|
861
|
-
projectPumlModule
|
|
862
|
-
];
|
|
863
|
-
const projectVirtuals = [...hmrProjectVirtuals, projectReactModule];
|
|
864
|
-
const virtuals = [
|
|
865
|
-
projectsModule,
|
|
866
|
-
modelModule,
|
|
867
|
-
projectsOverviewModule,
|
|
868
|
-
singleProjectModule,
|
|
869
|
-
singleProjectReactModule,
|
|
870
|
-
d2Module,
|
|
871
|
-
dotModule,
|
|
872
|
-
mmdModule,
|
|
873
|
-
pumlModule,
|
|
874
|
-
iconsModule,
|
|
875
|
-
rpcModule
|
|
876
|
-
];
|
|
877
|
-
function LikeC4VitePlugin({ environments, ...opts }) {
|
|
878
|
-
let logger;
|
|
879
|
-
let likec4;
|
|
880
|
-
let assetsDir;
|
|
881
|
-
let shouldDisposeOnStop = opts.watch ?? false;
|
|
882
|
-
return {
|
|
883
|
-
name: "vite-plugin-likec4",
|
|
884
|
-
applyToEnvironment(env) {
|
|
885
|
-
return environments ? environments.includes(env.name) : true;
|
|
886
|
-
},
|
|
887
|
-
async configResolved(config) {
|
|
888
|
-
config.server.hmr;
|
|
889
|
-
logger = config.logger;
|
|
890
|
-
if (opts.languageServices) likec4 = opts.languageServices;
|
|
891
|
-
else {
|
|
892
|
-
const watch = shouldDisposeOnStop = opts.watch ?? config.mode === "development";
|
|
893
|
-
likec4 = (await LikeC4.fromWorkspace(opts.workspace ?? config.root, {
|
|
894
|
-
logger,
|
|
895
|
-
graphviz: opts.graphviz ?? "wasm",
|
|
896
|
-
printErrors: opts.printErrors ?? true,
|
|
897
|
-
throwIfInvalid: opts.throwIfInvalid ?? false,
|
|
898
|
-
watch
|
|
899
|
-
})).languageServices;
|
|
900
|
-
}
|
|
901
|
-
assetsDir = likec4.workspaceUri.fsPath;
|
|
902
|
-
},
|
|
903
|
-
resolveId(id) {
|
|
904
|
-
for (const module of projectVirtuals) {
|
|
905
|
-
const projectId = module.matches(id);
|
|
906
|
-
if (projectId) return module.virtualId(projectId);
|
|
907
|
-
}
|
|
908
|
-
for (const module of virtuals) if (module.id === id) return module.virtualId;
|
|
909
|
-
return null;
|
|
910
|
-
},
|
|
911
|
-
async load(id) {
|
|
912
|
-
for (const module of projectVirtuals) {
|
|
913
|
-
const projectId = module.matches(id);
|
|
914
|
-
if (projectId) {
|
|
915
|
-
const project = likec4.project(projectId);
|
|
916
|
-
return await module.load({
|
|
917
|
-
logger,
|
|
918
|
-
likec4,
|
|
919
|
-
project,
|
|
920
|
-
assetsDir
|
|
921
|
-
});
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
for (const module of virtuals) if (module.virtualId === id) {
|
|
925
|
-
const projects = likec4.projects();
|
|
926
|
-
invariant(isNonEmptyArray(projects));
|
|
927
|
-
return await module.load({
|
|
928
|
-
logger,
|
|
929
|
-
likec4,
|
|
930
|
-
projects,
|
|
931
|
-
assetsDir
|
|
932
|
-
});
|
|
933
|
-
}
|
|
934
|
-
return null;
|
|
935
|
-
},
|
|
936
|
-
configureServer(server) {
|
|
937
|
-
const hotChannel = server.hot;
|
|
938
|
-
enablePluginRPC.call(this, {
|
|
939
|
-
logger,
|
|
940
|
-
likec4,
|
|
941
|
-
server
|
|
942
|
-
});
|
|
943
|
-
const readProjects = () => t$3(likec4.projects(), (p) => ({
|
|
944
|
-
id: p.id,
|
|
945
|
-
title: p.title,
|
|
946
|
-
folder: p.folder.fsPath
|
|
947
|
-
}));
|
|
948
|
-
let _projects = readProjects();
|
|
949
|
-
const reloadModule = async (id) => {
|
|
950
|
-
const md = server.moduleGraph.getModuleById(id);
|
|
951
|
-
if (md && md.importers.size > 0) try {
|
|
952
|
-
await server.reloadModule(md);
|
|
953
|
-
} catch (err) {
|
|
954
|
-
logger.error(err);
|
|
955
|
-
}
|
|
956
|
-
};
|
|
957
|
-
likec4.builder.onModelParsed(async () => {
|
|
958
|
-
const [error] = likec4.getErrors();
|
|
959
|
-
if (error) {
|
|
960
|
-
const [message, ...stack] = error.message.split("\n");
|
|
961
|
-
hotChannel.send({
|
|
962
|
-
type: "error",
|
|
963
|
-
err: {
|
|
964
|
-
name: "LikeC4ValidationError",
|
|
965
|
-
message,
|
|
966
|
-
stack: stack.join("\n"),
|
|
967
|
-
plugin: "vite-plugin-likec4",
|
|
968
|
-
loc: {
|
|
969
|
-
file: error.sourceFsPath,
|
|
970
|
-
line: error.line,
|
|
971
|
-
column: error.range.start.character + 1
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
});
|
|
975
|
-
return;
|
|
976
|
-
}
|
|
977
|
-
const _updated = readProjects();
|
|
978
|
-
if (!t$5(_updated, _projects)) {
|
|
979
|
-
_projects = _updated;
|
|
980
|
-
await reloadModule(projectsModule.virtualId);
|
|
981
|
-
await reloadModule(iconsModule.virtualId);
|
|
982
|
-
await reloadModule(modelModule.virtualId);
|
|
983
|
-
if (_projects.length > 1) await reloadModule(projectsOverviewModule.virtualId);
|
|
984
|
-
return;
|
|
985
|
-
}
|
|
986
|
-
for (const project of _projects) for (const projectModule of hmrProjectVirtuals) await reloadModule(projectModule.virtualId(project.id));
|
|
987
|
-
});
|
|
988
|
-
},
|
|
989
|
-
async buildEnd() {
|
|
990
|
-
if (shouldDisposeOnStop) await likec4.dispose();
|
|
991
|
-
}
|
|
992
|
-
};
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
//#endregion
|
|
996
|
-
export { generateD2 as i, generatePuml as n, generateMermaid as r, LikeC4VitePlugin as t };
|