@likec4/language-server 1.10.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.cjs +5 -1
- package/dist/browser.d.cts +9 -8
- package/dist/browser.d.mts +9 -8
- package/dist/browser.d.ts +9 -8
- package/dist/browser.mjs +3 -2
- package/dist/index.cjs +15 -2
- package/dist/index.d.cts +14 -11
- package/dist/index.d.mts +14 -11
- package/dist/index.d.ts +14 -11
- package/dist/index.mjs +17 -1
- package/dist/likec4lib.cjs +949 -952
- package/dist/likec4lib.d.cts +1 -1
- package/dist/likec4lib.d.mts +1 -1
- package/dist/likec4lib.d.ts +1 -1
- package/dist/likec4lib.mjs +949 -952
- package/dist/model-graph/index.cjs +1 -1
- package/dist/model-graph/index.mjs +1 -1
- package/dist/protocol.cjs +1 -1
- package/dist/protocol.d.cts +3 -1
- package/dist/protocol.d.mts +3 -1
- package/dist/protocol.d.ts +3 -1
- package/dist/protocol.mjs +1 -1
- package/dist/shared/{language-server.JWkqVjGv.cjs → language-server.C8lV6gDw.cjs} +120 -118
- package/dist/shared/{language-server.DBJJUUgF.mjs → language-server.CCOotWDz.mjs} +120 -119
- package/dist/shared/{language-server.DtBRb9os.mjs → language-server.CbqwHp7Q.mjs} +23 -9
- package/dist/shared/{language-server.CtKHXJDD.d.ts → language-server.Cyw-bCtc.d.ts} +145 -138
- package/dist/shared/{language-server.D-84I33F.d.mts → language-server.DGjTE7xL.d.mts} +145 -138
- package/dist/shared/{language-server.DwyCJvXm.cjs → language-server.DJhoJBWh.cjs} +17 -3
- package/dist/shared/{language-server.CjFzaJwI.d.cts → language-server.Ol32Kygo.d.cts} +145 -138
- package/package.json +34 -29
- package/src/Rpc.ts +10 -6
- package/src/ast.ts +1 -1
- package/src/browser.ts +5 -0
- package/src/formatting/LikeC4Formatter.ts +4 -2
- package/src/generated/ast.ts +99 -1
- package/src/generated/grammar.ts +1 -1
- package/src/generated/module.ts +1 -1
- package/src/generated-lib/icons.ts +949 -952
- package/src/index.ts +23 -2
- package/src/likec4lib.ts +1 -1
- package/src/logger.ts +16 -16
- package/src/lsp/CompletionProvider.ts +1 -1
- package/src/model/model-builder.ts +12 -12
- package/src/model-graph/compute-view/compute.ts +9 -4
- package/src/model-graph/utils/applyCustomRelationProperties.ts +1 -1
- package/src/model-graph/utils/uniqueTags.test.ts +42 -0
- package/src/model-graph/utils/uniqueTags.ts +19 -0
- package/src/protocol.ts +5 -1
- package/src/shared/WorkspaceManager.ts +1 -1
- package/dist/node.cjs +0 -18
- package/dist/node.d.cts +0 -20
- package/dist/node.d.mts +0 -20
- package/dist/node.d.ts +0 -20
- package/dist/node.mjs +0 -16
- package/src/node.ts +0 -20
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { AbstractAstReflection, loadGrammarFromJson, DocumentState, AstUtils, GrammarUtils, MultiMap, CstUtils, stream, StreamImpl, DONE_RESULT, interruptAndCheck, Disposable, DefaultScopeComputation, DefaultScopeProvider, EMPTY_STREAM, StreamScope, MapScope, EMPTY_SCOPE, URI, UriUtils, isAstNode, DefaultWorkspaceManager, WorkspaceCache, inject, EmptyFileSystem } from 'langium';
|
|
2
2
|
import { DefaultCompletionProvider, DefaultDocumentHighlightProvider, AstNodeHoverProvider, AbstractSemanticTokenProvider, DefaultWorkspaceSymbolProvider, Formatting, AbstractFormatter, createDefaultModule, createDefaultSharedModule } from 'langium/lsp';
|
|
3
3
|
import { rootLogger, LogLevels, logger as logger$1 } from '@likec4/log';
|
|
4
|
+
import { isError, isNullish, isDefined, clamp, isTruthy, pipe, map, filter, isEmpty, find, values, first, last, unique, hasAtLeast, mapToObj, groupBy, forEach, prop, mapValues, flatMap, reduce, sort, reverse, indexBy, isNumber, isNonNullish, findLast, entries, debounce } from 'remeda';
|
|
4
5
|
import { nonexhaustive, DefaultRelationshipColor, DefaultLineStyle, DefaultArrowType, AsFqn, parentFqn, nameFromFqn, isComputedElementView, isExtendsElementView, invariant, compareNatural, isElementView as isElementView$1, isScopedElementView, computeColorValues, sortByFqnHierarchically, compareRelations, isOrOperator, isNonEmptyArray, isAndOperator, isAncestor, hasAtLeast as hasAtLeast$1, isSameHierarchy } from '@likec4/core';
|
|
5
|
-
import { isNullish, isDefined, clamp, isTruthy, pipe, map, filter, isEmpty, find, values, first, last, unique, hasAtLeast, mapToObj, groupBy, forEach, prop, mapValues, flatMap, reduce, sort, reverse, indexBy, isNumber, isNonNullish, findLast, entries, debounce } from 'remeda';
|
|
6
6
|
import { DiagnosticSeverity, SymbolKind, SemanticTokenTypes, SemanticTokenModifiers, TextEdit, CompletionItemKind } from 'vscode-languageserver-types';
|
|
7
7
|
import indentString from 'indent-string';
|
|
8
8
|
import { decode, encode } from '@msgpack/msgpack';
|
|
@@ -13,100 +13,11 @@ import { URI as URI$1 } from 'vscode-uri';
|
|
|
13
13
|
import stripIndent from 'strip-indent';
|
|
14
14
|
import hash from 'string-hash';
|
|
15
15
|
import { deepEqual } from 'fast-equals';
|
|
16
|
-
import { i as isAcyclic, f as findCycles, p as postorder, L as LikeC4ModelGraph, a as computeView, b as computeDynamicView } from './language-server.
|
|
16
|
+
import { i as isAcyclic, f as findCycles, p as postorder, L as LikeC4ModelGraph, a as computeView, b as computeDynamicView } from './language-server.CbqwHp7Q.mjs';
|
|
17
17
|
import { hasProtocol, hasLeadingSlash, isRelative, withoutLeadingSlash, withoutBase, parsePath } from 'ufo';
|
|
18
18
|
import { Graph } from '@dagrejs/graphlib';
|
|
19
19
|
import { DocumentHighlight, DocumentHighlightKind } from 'vscode-languageserver';
|
|
20
20
|
|
|
21
|
-
const logger = rootLogger.withTag("lsp");
|
|
22
|
-
function logError(err) {
|
|
23
|
-
logger.error(err);
|
|
24
|
-
}
|
|
25
|
-
function logWarnError(err) {
|
|
26
|
-
if (err instanceof Error) {
|
|
27
|
-
logger.warn(err.stack ?? err.message);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
logger.warn(err);
|
|
31
|
-
}
|
|
32
|
-
function setLogLevel(level) {
|
|
33
|
-
logger.level = LogLevels[level];
|
|
34
|
-
}
|
|
35
|
-
function logErrorToTelemetry(connection) {
|
|
36
|
-
const reporter = {
|
|
37
|
-
log: ({ level, ...logObj }, ctx) => {
|
|
38
|
-
if (level !== LogLevels.error && level !== LogLevels.fatal) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
const tag = logObj.tag || "";
|
|
42
|
-
const parts = logObj.args.map((arg) => {
|
|
43
|
-
if (arg && typeof arg.stack === "string") {
|
|
44
|
-
return arg.message + "\n" + arg.stack;
|
|
45
|
-
}
|
|
46
|
-
if (typeof arg === "string") {
|
|
47
|
-
return arg;
|
|
48
|
-
}
|
|
49
|
-
return String(arg);
|
|
50
|
-
});
|
|
51
|
-
if (tag) {
|
|
52
|
-
parts.unshift(`[${tag}]`);
|
|
53
|
-
}
|
|
54
|
-
const message = parts.join(" ");
|
|
55
|
-
connection.telemetry.logEvent({ eventName: "error", error: message });
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
rootLogger.addReporter(reporter);
|
|
59
|
-
logger.setReporters(rootLogger.options.reporters);
|
|
60
|
-
}
|
|
61
|
-
function logToLspConnection(connection) {
|
|
62
|
-
const reporter = {
|
|
63
|
-
log: ({ level, ...logObj }, ctx) => {
|
|
64
|
-
const tag = logObj.tag || "";
|
|
65
|
-
const parts = logObj.args.map((arg) => {
|
|
66
|
-
if (arg && typeof arg.stack === "string") {
|
|
67
|
-
return arg.message + "\n" + arg.stack;
|
|
68
|
-
}
|
|
69
|
-
if (typeof arg === "string") {
|
|
70
|
-
return arg;
|
|
71
|
-
}
|
|
72
|
-
return String(arg);
|
|
73
|
-
});
|
|
74
|
-
if (tag) {
|
|
75
|
-
parts.unshift(`[${tag}]`);
|
|
76
|
-
}
|
|
77
|
-
const message = parts.join(" ");
|
|
78
|
-
switch (true) {
|
|
79
|
-
case level >= LogLevels.trace: {
|
|
80
|
-
connection.tracer.log(message);
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
case level >= LogLevels.debug: {
|
|
84
|
-
connection.console.debug(message);
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
case level >= LogLevels.info: {
|
|
88
|
-
connection.console.info(message);
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
case level >= LogLevels.log: {
|
|
92
|
-
connection.console.log(message);
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
case level >= LogLevels.warn: {
|
|
96
|
-
connection.console.warn(message);
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
case level >= LogLevels.fatal: {
|
|
100
|
-
connection.console.error(message);
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
rootLogger.addReporter(reporter);
|
|
107
|
-
logger.setReporters(rootLogger.options.reporters);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
21
|
const DynamicViewRule = "DynamicViewRule";
|
|
111
22
|
function isDynamicViewRule(item) {
|
|
112
23
|
return reflection.isInstance(item, DynamicViewRule);
|
|
@@ -1488,6 +1399,94 @@ const LikeC4GeneratedModule = {
|
|
|
1488
1399
|
}
|
|
1489
1400
|
};
|
|
1490
1401
|
|
|
1402
|
+
const logger = rootLogger.withTag("lsp");
|
|
1403
|
+
function logError(err) {
|
|
1404
|
+
logger.error(err);
|
|
1405
|
+
}
|
|
1406
|
+
function logWarnError(err) {
|
|
1407
|
+
if (err instanceof Error) {
|
|
1408
|
+
logger.warn(err.stack ?? err.message);
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
logger.warn(err);
|
|
1412
|
+
}
|
|
1413
|
+
function setLogLevel(level) {
|
|
1414
|
+
logger.level = LogLevels[level];
|
|
1415
|
+
}
|
|
1416
|
+
function logErrorToTelemetry(connection) {
|
|
1417
|
+
const reporter = {
|
|
1418
|
+
log: ({ level, ...logObj }, ctx) => {
|
|
1419
|
+
if (level !== LogLevels.error && level !== LogLevels.fatal) {
|
|
1420
|
+
return;
|
|
1421
|
+
}
|
|
1422
|
+
const tag = logObj.tag || "";
|
|
1423
|
+
const parts = logObj.args.map((arg) => {
|
|
1424
|
+
if (isError(arg)) {
|
|
1425
|
+
return arg.stack ?? arg.message;
|
|
1426
|
+
}
|
|
1427
|
+
if (typeof arg === "string") {
|
|
1428
|
+
return arg;
|
|
1429
|
+
}
|
|
1430
|
+
return "" + arg;
|
|
1431
|
+
});
|
|
1432
|
+
if (tag) {
|
|
1433
|
+
parts.unshift(`[${tag}]`);
|
|
1434
|
+
}
|
|
1435
|
+
const message = parts.join(" ");
|
|
1436
|
+
connection.telemetry.logEvent({ eventName: "error", error: message });
|
|
1437
|
+
}
|
|
1438
|
+
};
|
|
1439
|
+
rootLogger.addReporter(reporter);
|
|
1440
|
+
logger.setReporters(rootLogger.options.reporters);
|
|
1441
|
+
}
|
|
1442
|
+
function logToLspConnection(connection) {
|
|
1443
|
+
const reporter = {
|
|
1444
|
+
log: ({ level, ...logObj }, ctx) => {
|
|
1445
|
+
const tag = logObj.tag || "";
|
|
1446
|
+
const parts = logObj.args.map((arg) => {
|
|
1447
|
+
if (isError(arg)) {
|
|
1448
|
+
return arg.stack ?? arg.message;
|
|
1449
|
+
}
|
|
1450
|
+
if (typeof arg === "string") {
|
|
1451
|
+
return arg;
|
|
1452
|
+
}
|
|
1453
|
+
return "" + arg;
|
|
1454
|
+
});
|
|
1455
|
+
if (tag) {
|
|
1456
|
+
parts.unshift(`[${tag}]`);
|
|
1457
|
+
}
|
|
1458
|
+
const message = parts.join(" ");
|
|
1459
|
+
switch (true) {
|
|
1460
|
+
case level >= LogLevels.debug: {
|
|
1461
|
+
connection.console.debug(message);
|
|
1462
|
+
break;
|
|
1463
|
+
}
|
|
1464
|
+
// case level >= LogLevels.info: {
|
|
1465
|
+
// connection.console.info(message)
|
|
1466
|
+
// break
|
|
1467
|
+
// }
|
|
1468
|
+
case level >= LogLevels.log: {
|
|
1469
|
+
connection.console.info(message);
|
|
1470
|
+
break;
|
|
1471
|
+
}
|
|
1472
|
+
case level >= LogLevels.warn: {
|
|
1473
|
+
connection.console.warn(message);
|
|
1474
|
+
break;
|
|
1475
|
+
}
|
|
1476
|
+
case level >= LogLevels.fatal: {
|
|
1477
|
+
connection.console.error(message);
|
|
1478
|
+
break;
|
|
1479
|
+
}
|
|
1480
|
+
default: {
|
|
1481
|
+
connection.console.log(message);
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
};
|
|
1486
|
+
rootLogger.setReporters([reporter]);
|
|
1487
|
+
logger.setReporters(rootLogger.options.reporters);
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1491
1490
|
function elementRef(node) {
|
|
1492
1491
|
return node.el.ref;
|
|
1493
1492
|
}
|
|
@@ -1609,7 +1608,7 @@ function checksFromDiagnostics(doc) {
|
|
|
1609
1608
|
};
|
|
1610
1609
|
}
|
|
1611
1610
|
function* streamModel(doc, isValid) {
|
|
1612
|
-
const traverseStack = doc.parseResult.value.models.flatMap((m) =>
|
|
1611
|
+
const traverseStack = doc.parseResult.value.models.flatMap((m) => m.elements);
|
|
1613
1612
|
const relations = [];
|
|
1614
1613
|
let el;
|
|
1615
1614
|
while (el = traverseStack.shift()) {
|
|
@@ -2540,8 +2539,6 @@ class FqnIndex {
|
|
|
2540
2539
|
}
|
|
2541
2540
|
}
|
|
2542
2541
|
|
|
2543
|
-
const printDocs = (docs) => docs.map((d) => " - " + d.uri.toString(true)).join("\n");
|
|
2544
|
-
|
|
2545
2542
|
function assignNavigateTo(views) {
|
|
2546
2543
|
const allElementViews = /* @__PURE__ */ new Map();
|
|
2547
2544
|
for (const v of views) {
|
|
@@ -2935,8 +2932,7 @@ class LikeC4ModelBuilder {
|
|
|
2935
2932
|
async (docs, _cancelToken) => {
|
|
2936
2933
|
let parsed = [];
|
|
2937
2934
|
try {
|
|
2938
|
-
logger.debug(`[ModelBuilder] onValidated (${docs.length} docs)
|
|
2939
|
-
${printDocs(docs)}`);
|
|
2935
|
+
logger.debug(`[ModelBuilder] onValidated (${docs.length} docs)`);
|
|
2940
2936
|
for (const doc of parser.parse(docs)) {
|
|
2941
2937
|
parsed.push(doc.uri);
|
|
2942
2938
|
}
|
|
@@ -2966,8 +2962,7 @@ ${printDocs(docs)}`);
|
|
|
2966
2962
|
logger.debug("[ModelBuilder] No documents to build model from");
|
|
2967
2963
|
return null;
|
|
2968
2964
|
}
|
|
2969
|
-
logger.debug(`[ModelBuilder]
|
|
2970
|
-
${printDocs(docs)}`);
|
|
2965
|
+
logger.debug(`[ModelBuilder] onValidated (${docs.length} docs)`);
|
|
2971
2966
|
return buildModel(this.services, docs);
|
|
2972
2967
|
});
|
|
2973
2968
|
}
|
|
@@ -3024,14 +3019,14 @@ ${printDocs(docs)}`);
|
|
|
3024
3019
|
if (cache.has(CACHE_KEY_COMPUTED_MODEL)) {
|
|
3025
3020
|
return cache.get(CACHE_KEY_COMPUTED_MODEL);
|
|
3026
3021
|
}
|
|
3027
|
-
const model = await this.buildModel(cancelToken);
|
|
3028
|
-
if (!model) {
|
|
3029
|
-
return null;
|
|
3030
|
-
}
|
|
3031
3022
|
return await this.services.shared.workspace.WorkspaceLock.read(async () => {
|
|
3032
3023
|
if (cancelToken) {
|
|
3033
3024
|
await interruptAndCheck(cancelToken);
|
|
3034
3025
|
}
|
|
3026
|
+
const model = this.unsafeSyncBuildModel();
|
|
3027
|
+
if (!model) {
|
|
3028
|
+
return null;
|
|
3029
|
+
}
|
|
3035
3030
|
return this.unsafeSyncBuildComputedModel(model);
|
|
3036
3031
|
});
|
|
3037
3032
|
}
|
|
@@ -3041,17 +3036,17 @@ ${printDocs(docs)}`);
|
|
|
3041
3036
|
if (cache.has(cacheKey)) {
|
|
3042
3037
|
return cache.get(cacheKey);
|
|
3043
3038
|
}
|
|
3044
|
-
const model = await this.buildModel(cancelToken);
|
|
3045
|
-
const view = model?.views[viewId];
|
|
3046
|
-
if (!view) {
|
|
3047
|
-
logger.warn(`[ModelBuilder] Cannot find view ${viewId}`);
|
|
3048
|
-
return null;
|
|
3049
|
-
}
|
|
3050
3039
|
return await this.services.shared.workspace.WorkspaceLock.read(async () => {
|
|
3051
3040
|
if (cancelToken) {
|
|
3052
3041
|
await interruptAndCheck(cancelToken);
|
|
3053
3042
|
}
|
|
3054
3043
|
return cache.get(cacheKey, () => {
|
|
3044
|
+
const model = this.unsafeSyncBuildModel();
|
|
3045
|
+
const view = model?.views[viewId];
|
|
3046
|
+
if (!view) {
|
|
3047
|
+
logger.warn(`[ModelBuilder] Cannot find view ${viewId}`);
|
|
3048
|
+
return null;
|
|
3049
|
+
}
|
|
3055
3050
|
const index = new LikeC4ModelGraph(model);
|
|
3056
3051
|
const result = isElementView$1(view) ? computeView(view, index) : computeDynamicView(view, index);
|
|
3057
3052
|
if (!result.isSuccess) {
|
|
@@ -4737,14 +4732,16 @@ class Rpc {
|
|
|
4737
4732
|
const LangiumDocuments = this.services.shared.workspace.LangiumDocuments;
|
|
4738
4733
|
const DocumentBuilder = this.services.shared.workspace.DocumentBuilder;
|
|
4739
4734
|
const notifyModelParsed = debounce(
|
|
4740
|
-
() =>
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4735
|
+
() => {
|
|
4736
|
+
connection.sendNotification(onDidChangeModel, "").catch((e) => {
|
|
4737
|
+
logger.error(`[ServerRpc] error sending onDidChangeModel: ${e}`);
|
|
4738
|
+
return Promise.resolve();
|
|
4739
|
+
});
|
|
4740
|
+
},
|
|
4744
4741
|
{
|
|
4745
4742
|
timing: "both",
|
|
4746
|
-
waitMs:
|
|
4747
|
-
maxWaitMs:
|
|
4743
|
+
waitMs: 300,
|
|
4744
|
+
maxWaitMs: 600
|
|
4748
4745
|
}
|
|
4749
4746
|
);
|
|
4750
4747
|
let isFirstBuild = true;
|
|
@@ -4753,7 +4750,10 @@ class Rpc {
|
|
|
4753
4750
|
notifyModelParsed.cancel();
|
|
4754
4751
|
}),
|
|
4755
4752
|
modelBuilder.onModelParsed(() => notifyModelParsed.call()),
|
|
4756
|
-
connection.onRequest(fetchComputedModel, async (cancelToken) => {
|
|
4753
|
+
connection.onRequest(fetchComputedModel, async ({ cleanCaches }, cancelToken) => {
|
|
4754
|
+
if (cleanCaches) {
|
|
4755
|
+
this.services.WorkspaceCache.clear();
|
|
4756
|
+
}
|
|
4757
4757
|
const model = await modelBuilder.buildComputedModel(cancelToken);
|
|
4758
4758
|
return { model };
|
|
4759
4759
|
}),
|
|
@@ -4929,8 +4929,8 @@ class LikeC4WorkspaceManager extends DefaultWorkspaceManager {
|
|
|
4929
4929
|
* your language, which can be either loaded from provided files or constructed in memory.
|
|
4930
4930
|
*/
|
|
4931
4931
|
async loadAdditionalDocuments(folders, collector) {
|
|
4932
|
-
await super.loadAdditionalDocuments(folders, collector);
|
|
4933
4932
|
collector(this.documentFactory.fromString(LibIcons, URI$1.parse(Uri)));
|
|
4933
|
+
await super.loadAdditionalDocuments(folders, collector);
|
|
4934
4934
|
}
|
|
4935
4935
|
workspace() {
|
|
4936
4936
|
if (this.folders && hasAtLeast$1(this.folders, 1)) {
|
|
@@ -5450,7 +5450,8 @@ class LikeC4Formatter extends AbstractFormatter {
|
|
|
5450
5450
|
}
|
|
5451
5451
|
formatRelation(node) {
|
|
5452
5452
|
this.on(node, isRelation, (n, f) => {
|
|
5453
|
-
|
|
5453
|
+
const sourceNodes = n?.source?.$cstNode ? [n?.source?.$cstNode] : [];
|
|
5454
|
+
f.cst(sourceNodes).append(FormattingOptions.oneSpace);
|
|
5454
5455
|
f.keywords("]->").prepend(FormattingOptions.noSpace);
|
|
5455
5456
|
f.keywords("-[").append(FormattingOptions.noSpace);
|
|
5456
5457
|
f.properties("target", "title", "technology", "tags").prepend(FormattingOptions.oneSpace);
|
|
@@ -5468,7 +5469,7 @@ class LikeC4Formatter extends AbstractFormatter {
|
|
|
5468
5469
|
f.keywords("-[").append(FormattingOptions.noSpace);
|
|
5469
5470
|
});
|
|
5470
5471
|
this.on(node, isIncomingRelationExpression)?.keywords("->").append(FormattingOptions.oneSpace);
|
|
5471
|
-
this.on(node, isInOutRelationExpression)?.
|
|
5472
|
+
this.on(node, isInOutRelationExpression)?.keyword("->").prepend(FormattingOptions.oneSpace);
|
|
5472
5473
|
}
|
|
5473
5474
|
removeIndentFromTopLevelStatements(node) {
|
|
5474
5475
|
if (isModel(node) || isSpecificationRule(node) || isModelViews(node) || isLikeC4Lib(node)) {
|
|
@@ -5734,4 +5735,4 @@ function _merge(target, source) {
|
|
|
5734
5735
|
return target;
|
|
5735
5736
|
}
|
|
5736
5737
|
|
|
5737
|
-
export { LikeC4Module as L,
|
|
5738
|
+
export { LikeC4Module as L, createCustomLanguageServices as a, createLanguageServices as c, logger as l, setLogLevel as s };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Expr, whereOperatorAsPredicate, parentFqn, nonexhaustive, isViewRuleStyle, compareByFqnHierarchically, DefaultThemeColor, DefaultElementShape, compareRelations, invariant, nonNullable, isAncestor, isViewRulePredicate, ancestorsFqn, isViewRuleAutoLayout, isScopedElementView, commonAncestor, StepEdgeId, isDynamicViewParallelSteps, isDynamicViewIncludeRule, DefaultRelationshipColor, DefaultLineStyle, DefaultArrowType, isSameHierarchy } from '@likec4/core';
|
|
2
|
-
import { pipe, map, pick, mapToObj, isTruthy, isNullish, omitBy, isEmpty, filter, anyPass, isDefined, groupBy, prop, mapValues, piped, unique, entries, flatMap, sortBy, sort, difference, allPass, omit, hasAtLeast
|
|
1
|
+
import { Expr, whereOperatorAsPredicate, parentFqn, nonexhaustive, isViewRuleStyle, compareByFqnHierarchically, DefaultThemeColor, DefaultElementShape, compareRelations, invariant, nonNullable, compareNatural, hasAtLeast, isAncestor, isViewRulePredicate, ancestorsFqn, isViewRuleAutoLayout, isScopedElementView, commonAncestor, StepEdgeId, isDynamicViewParallelSteps, isDynamicViewIncludeRule, DefaultRelationshipColor, DefaultLineStyle, DefaultArrowType, isSameHierarchy } from '@likec4/core';
|
|
2
|
+
import { pipe, map, pick, mapToObj, isTruthy, isNullish, omitBy, isEmpty, filter, anyPass, isDefined, groupBy, prop, mapValues, piped, unique, entries, flatMap, sortBy, sort, difference, allPass, omit, hasAtLeast as hasAtLeast$1, only, reduce, isNonNull, isString, isArray } from 'remeda';
|
|
3
3
|
import graphlib, { Graph } from '@dagrejs/graphlib';
|
|
4
4
|
import objectHash from 'object-hash';
|
|
5
5
|
|
|
@@ -366,6 +366,16 @@ function sortNodes({
|
|
|
366
366
|
return sorted;
|
|
367
367
|
}
|
|
368
368
|
|
|
369
|
+
function uniqueTags(elements) {
|
|
370
|
+
const tags = pipe(
|
|
371
|
+
elements,
|
|
372
|
+
flatMap((e) => e.tags ?? []),
|
|
373
|
+
unique(),
|
|
374
|
+
sort(compareNatural)
|
|
375
|
+
);
|
|
376
|
+
return hasAtLeast(tags, 1) ? tags : null;
|
|
377
|
+
}
|
|
378
|
+
|
|
369
379
|
const NoFilter = () => true;
|
|
370
380
|
const Identity = (x) => x;
|
|
371
381
|
const filterBy = (pred) => pred === NoFilter ? Identity : filter(pred);
|
|
@@ -865,7 +875,7 @@ class ComputeCtx {
|
|
|
865
875
|
}
|
|
866
876
|
computeEdges() {
|
|
867
877
|
return this.ctxEdges.map((e) => {
|
|
868
|
-
invariant(hasAtLeast(e.relations, 1), "Edge must have at least one relation");
|
|
878
|
+
invariant(hasAtLeast$1(e.relations, 1), "Edge must have at least one relation");
|
|
869
879
|
const relations = sort(e.relations, compareRelations);
|
|
870
880
|
const source = e.source.id;
|
|
871
881
|
const target = e.target.id;
|
|
@@ -878,7 +888,11 @@ class ComputeCtx {
|
|
|
878
888
|
relations: relations.map((r) => r.id)
|
|
879
889
|
};
|
|
880
890
|
let relation;
|
|
881
|
-
relation = relations
|
|
891
|
+
relation = only(relations) ?? pipe(
|
|
892
|
+
relations,
|
|
893
|
+
filter((r) => r.source === source && r.target === target),
|
|
894
|
+
only()
|
|
895
|
+
);
|
|
882
896
|
if (!relation) {
|
|
883
897
|
const allprops = pipe(
|
|
884
898
|
relations,
|
|
@@ -935,7 +949,7 @@ class ComputeCtx {
|
|
|
935
949
|
navigateTo: only(allprops.navigateTo)
|
|
936
950
|
};
|
|
937
951
|
}
|
|
938
|
-
const tags =
|
|
952
|
+
const tags = uniqueTags(relations);
|
|
939
953
|
return Object.assign(
|
|
940
954
|
edge,
|
|
941
955
|
this.getEdgeLabel(relation),
|
|
@@ -947,7 +961,7 @@ class ComputeCtx {
|
|
|
947
961
|
relation.head && { head: relation.head },
|
|
948
962
|
relation.tail && { tail: relation.tail },
|
|
949
963
|
relation.navigateTo && { navigateTo: relation.navigateTo },
|
|
950
|
-
|
|
964
|
+
tags && { tags }
|
|
951
965
|
);
|
|
952
966
|
});
|
|
953
967
|
}
|
|
@@ -969,7 +983,7 @@ class ComputeCtx {
|
|
|
969
983
|
}
|
|
970
984
|
addEdges(edges) {
|
|
971
985
|
for (const e of edges) {
|
|
972
|
-
if (!hasAtLeast(e.relations, 1)) {
|
|
986
|
+
if (!hasAtLeast$1(e.relations, 1)) {
|
|
973
987
|
continue;
|
|
974
988
|
}
|
|
975
989
|
const existing = this.ctxEdges.find(
|
|
@@ -1357,8 +1371,8 @@ class DynamicViewComputeCtx {
|
|
|
1357
1371
|
filter(isTruthy),
|
|
1358
1372
|
unique()
|
|
1359
1373
|
);
|
|
1360
|
-
const tags = hasAtLeast(alltags, 1) ? alltags : null;
|
|
1361
|
-
const relations = hasAtLeast(relationships, 1) ? map(relationships, (r) => r.id) : null;
|
|
1374
|
+
const tags = hasAtLeast$1(alltags, 1) ? alltags : null;
|
|
1375
|
+
const relations = hasAtLeast$1(relationships, 1) ? map(relationships, (r) => r.id) : null;
|
|
1362
1376
|
const relation = only(relationships) || relationships.find((r) => r.source === source.id && r.target === target.id);
|
|
1363
1377
|
const title = isTruthy(relation?.title) ? relation.title : pipe(
|
|
1364
1378
|
relationships,
|