@likec4/language-server 1.31.0 → 1.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/LikeC4LanguageServices.d.ts +2 -1
  2. package/dist/LikeC4LanguageServices.js +4 -3
  3. package/dist/Rpc.js +11 -4
  4. package/dist/ast.d.ts +11 -15
  5. package/dist/bundled.mjs +2539 -2476
  6. package/dist/formatting/LikeC4Formatter.js +7 -6
  7. package/dist/generated/ast.d.ts +33 -14
  8. package/dist/generated/ast.js +38 -16
  9. package/dist/generated/grammar.js +1 -1
  10. package/dist/lsp/CompletionProvider.js +1 -1
  11. package/dist/lsp/DocumentLinkProvider.js +4 -3
  12. package/dist/lsp/HoverProvider.js +9 -1
  13. package/dist/lsp/SemanticTokenProvider.js +18 -4
  14. package/dist/mcp/LikeC4MCPServerFactory.d.ts +5 -2
  15. package/dist/mcp/LikeC4MCPServerFactory.js +2 -72
  16. package/dist/mcp/LikeC4MCPTools.js +5 -3
  17. package/dist/mcp/sseserver/MCPServerFactory.d.ts +8 -0
  18. package/dist/mcp/sseserver/MCPServerFactory.js +78 -0
  19. package/dist/mcp/sseserver/with-mcp-server.d.ts +2 -0
  20. package/dist/mcp/sseserver/with-mcp-server.js +5 -1
  21. package/dist/mcp/utils.d.ts +5 -4
  22. package/dist/mcp/utils.js +2 -2
  23. package/dist/model/builder/MergedExtends.d.ts +4 -4
  24. package/dist/model/builder/MergedExtends.js +1 -1
  25. package/dist/model/builder/MergedSpecification.d.ts +4 -3
  26. package/dist/model/builder/MergedSpecification.js +9 -8
  27. package/dist/model/builder/assignTagColors.d.ts +7 -0
  28. package/dist/model/builder/assignTagColors.js +51 -0
  29. package/dist/model/builder/buildModel.d.ts +2 -2
  30. package/dist/model/builder/buildModel.js +40 -18
  31. package/dist/model/deployments-index.js +2 -2
  32. package/dist/model/fqn-index.d.ts +1 -1
  33. package/dist/model/fqn-index.js +6 -6
  34. package/dist/model/model-builder.d.ts +10 -4
  35. package/dist/model/model-builder.js +22 -19
  36. package/dist/model/model-locator.d.ts +10 -2
  37. package/dist/model/model-locator.js +65 -9
  38. package/dist/model/model-parser-where.d.ts +1 -1
  39. package/dist/model/model-parser-where.js +1 -1
  40. package/dist/model/model-parser.d.ts +10 -11
  41. package/dist/model/model-parser.js +11 -7
  42. package/dist/model/parser/Base.js +2 -3
  43. package/dist/model/parser/DeploymentModelParser.d.ts +1 -1
  44. package/dist/model/parser/DeploymentModelParser.js +7 -5
  45. package/dist/model/parser/DeploymentViewParser.d.ts +3 -3
  46. package/dist/model/parser/DeploymentViewParser.js +2 -1
  47. package/dist/model/parser/FqnRefParser.d.ts +1 -1
  48. package/dist/model/parser/FqnRefParser.js +2 -5
  49. package/dist/model/parser/GlobalsParser.d.ts +23 -24
  50. package/dist/model/parser/GlobalsParser.js +4 -4
  51. package/dist/model/parser/ModelParser.d.ts +1 -1
  52. package/dist/model/parser/ModelParser.js +1 -1
  53. package/dist/model/parser/PredicatesParser.d.ts +12 -12
  54. package/dist/model/parser/SpecificationParser.d.ts +5 -2
  55. package/dist/model/parser/SpecificationParser.js +18 -30
  56. package/dist/model/parser/ViewsParser.d.ts +23 -23
  57. package/dist/model/parser/ViewsParser.js +12 -19
  58. package/dist/model-change/changeElementStyle.d.ts +2 -2
  59. package/dist/model-change/changeElementStyle.js +6 -2
  60. package/dist/module.d.ts +1 -1
  61. package/dist/module.js +5 -2
  62. package/dist/protocol.d.ts +24 -3
  63. package/dist/protocol.js +4 -0
  64. package/dist/references/scope-computation.js +2 -3
  65. package/dist/test/testServices.d.ts +15 -0
  66. package/dist/test/testServices.js +1 -1
  67. package/dist/validation/relation.js +1 -1
  68. package/dist/validation/specification.js +1 -1
  69. package/dist/view-utils/assignNavigateTo.d.ts +1 -1
  70. package/dist/view-utils/assignNavigateTo.js +3 -3
  71. package/dist/views/likec4-views.d.ts +1 -3
  72. package/dist/views/likec4-views.js +68 -44
  73. package/package.json +21 -19
  74. /package/dist/mcp/sseserver/{SSELikeC4MCPServer.d.ts → MCPServer.d.ts} +0 -0
  75. /package/dist/mcp/sseserver/{SSELikeC4MCPServer.js → MCPServer.js} +0 -0
@@ -156,11 +156,13 @@ export function DeploymentModelParser(B) {
156
156
  parseDeploymentRelation(astNode) {
157
157
  const isValid = this.isValid;
158
158
  const astPath = this.getAstNodePath(astNode);
159
- const source = FqnRef.toDeploymentRef(this._resolveDeploymentRelationSource(astNode));
160
- const target = FqnRef.toDeploymentRef(this.parseFqnRef(astNode.target));
159
+ const source = this._resolveDeploymentRelationSource(astNode);
160
+ invariant(FqnRef.isDeploymentRef(source), "Invalid source for deployment relation");
161
+ const target = this.parseFqnRef(astNode.target);
162
+ invariant(FqnRef.isDeploymentRef(target), "Invalid target for deployment relation");
161
163
  const tags = this.convertTags(astNode) ?? this.convertTags(astNode.body);
162
164
  const links = this.convertLinks(astNode.body);
163
- const kind = astNode.kind?.ref?.name;
165
+ const kind = (astNode.kind ?? astNode.dotKind?.kind)?.ref?.name;
164
166
  const metadata = this.getMetadata(astNode.body?.props.find(ast.isMetadataProperty));
165
167
  const bodyProps = mapToObj(
166
168
  astNode.body?.props.filter(ast.isRelationStringProperty) ?? [],
@@ -180,8 +182,8 @@ export function DeploymentModelParser(B) {
180
182
  const id = stringHash(
181
183
  "deployment",
182
184
  astPath,
183
- source.id,
184
- target.id
185
+ source.deployment,
186
+ target.deployment
185
187
  );
186
188
  return {
187
189
  id,
@@ -1,4 +1,4 @@
1
- import type * as c4 from '@likec4/core';
1
+ import * as c4 from '@likec4/core';
2
2
  import { type ParsedAstDeploymentView, ast } from '../../ast';
3
3
  import type { WithDeploymentModel } from './DeploymentModelParser';
4
4
  import type { WithExpressionV2 } from './FqnRefParser';
@@ -7,10 +7,10 @@ export declare function DeploymentViewParser<TBase extends WithExpressionV2 & Wi
7
7
  new (...args: any[]): {
8
8
  parseDeploymentView(astNode: ast.DeploymentView): ParsedAstDeploymentView;
9
9
  parseDeploymentViewRule(astRule: ast.DeploymentViewRule): c4.DeploymentViewRule;
10
- parseDeploymentViewRulePredicate(astRule: ast.DeploymentViewRulePredicate): c4.DeploymentViewRulePredicate;
10
+ parseDeploymentViewRulePredicate(astRule: ast.DeploymentViewRulePredicate): c4.DeploymentViewPredicate;
11
11
  parseDeploymentViewRuleStyle(astRule: ast.DeploymentViewRuleStyle): c4.DeploymentViewRuleStyle;
12
12
  parseFqnRef(astNode: ast.FqnRef): c4.FqnRef;
13
- parseExpressionV2(astNode: ast.ExpressionV2): c4.ExpressionV2;
13
+ parseExpressionV2(astNode: ast.ExpressionV2): c4.Expression;
14
14
  parseFqnExprOrWith(astNode: ast.FqnExprOrWith): c4.FqnExpr.Any;
15
15
  parseFqnExprWith(astNode: ast.FqnExprWith): c4.FqnExpr.Custom;
16
16
  parseFqnExprOrWhere(astNode: ast.FqnExprOrWhere): c4.FqnExpr.OrWhere;
@@ -1,3 +1,4 @@
1
+ import * as c4 from "@likec4/core";
1
2
  import { invariant, isNonEmptyArray, nonexhaustive } from "@likec4/core";
2
3
  import { isNonNullish } from "remeda";
3
4
  import { ast, toAutoLayout, ViewOps } from "../../ast.js";
@@ -26,7 +27,7 @@ export function DeploymentViewParser(B) {
26
27
  ViewOps.writeId(astNode, id);
27
28
  const manualLayout = parseViewManualLayout(astNode);
28
29
  return {
29
- __: "deployment",
30
+ [c4._type]: "deployment",
30
31
  id,
31
32
  astPath,
32
33
  title,
@@ -5,7 +5,7 @@ export type WithExpressionV2 = ReturnType<typeof ExpressionV2Parser>;
5
5
  export declare function ExpressionV2Parser<TBase extends Base>(B: TBase): {
6
6
  new (...args: any[]): {
7
7
  parseFqnRef(astNode: ast.FqnRef): c4.FqnRef;
8
- parseExpressionV2(astNode: ast.ExpressionV2): c4.ExpressionV2;
8
+ parseExpressionV2(astNode: ast.ExpressionV2): c4.Expression;
9
9
  parseFqnExprOrWith(astNode: ast.FqnExprOrWith): c4.FqnExpr.Any;
10
10
  parseFqnExprWith(astNode: ast.FqnExprWith): c4.FqnExpr.Custom;
11
11
  parseFqnExprOrWhere(astNode: ast.FqnExprOrWhere): c4.FqnExpr.OrWhere;
@@ -197,11 +197,8 @@ export function ExpressionV2Parser(B) {
197
197
  };
198
198
  }
199
199
  if (ast.isElementTagExpression(astNode)) {
200
- invariant(astNode.tag?.ref, "ElementTagExpr tag is not resolved: " + astNode.$cstNode?.text);
201
- let elementTag = astNode.tag.$refText;
202
- if (elementTag.startsWith("#")) {
203
- elementTag = elementTag.slice(1);
204
- }
200
+ invariant(astNode.tag.tag.ref, "ElementTagExpr tag is not resolved: " + astNode.$cstNode?.text);
201
+ let elementTag = astNode.tag.tag.$refText;
205
202
  return {
206
203
  elementTag,
207
204
  isEqual: astNode.isEqual
@@ -1,41 +1,40 @@
1
1
  import type * as c4 from '@likec4/core';
2
- import { ast, type ParsedAstGlobals } from '../../ast';
2
+ import { type ParsedAstGlobals, ast } from '../../ast';
3
3
  import type { WithViewsParser } from './ViewsParser';
4
4
  export declare function GlobalsParser<TBase extends WithViewsParser>(B: TBase): {
5
5
  new (...args: any[]): {
6
6
  parseGlobals(): void;
7
7
  parseAndStoreGlobalPredicateGroupOrDynamic(astRule: ast.GlobalPredicateGroup | ast.GlobalDynamicPredicateGroup, id: c4.GlobalPredicateId, c4Globals: ParsedAstGlobals): void;
8
- parseGlobalPredicateGroup(astRule: ast.GlobalPredicateGroup): c4.ViewRulePredicate[];
8
+ parseGlobalPredicateGroup(astRule: ast.GlobalPredicateGroup): c4.ElementViewPredicate[];
9
9
  parseGlobalDynamicPredicateGroup(astRule: ast.GlobalDynamicPredicateGroup): c4.DynamicViewIncludeRule[];
10
- parseGlobalStyleOrGroup(astRule: ast.GlobalStyle | ast.GlobalStyleGroup): c4.ViewRuleStyle[];
10
+ parseGlobalStyleOrGroup(astRule: ast.GlobalStyle | ast.GlobalStyleGroup): c4.ElementViewRuleStyle[];
11
11
  parseViews(): void;
12
- parseElementView(astNode: ast.ElementView, additionalStyles: c4.ViewRuleStyleOrGlobalRef[]): import("../../ast").ParsedAstElementView;
13
- parseViewRule(astRule: ast.ViewRule): c4.ViewRule;
14
- parseViewRulePredicate(astNode: ast.ViewRulePredicate): c4.ViewRulePredicate;
12
+ parseElementView(astNode: ast.ElementView, additionalStyles: any[]): import("../../ast").ParsedAstElementView;
13
+ parseElementViewRule(astRule: ast.ViewRule): c4.ElementViewRule;
14
+ parseViewRulePredicate(astNode: ast.ViewRulePredicate): c4.ElementViewPredicate;
15
15
  parseViewRuleGlobalPredicateRef(astRule: ast.ViewRuleGlobalPredicateRef | ast.DynamicViewGlobalPredicateRef): c4.ViewRuleGlobalPredicateRef;
16
- parseViewRuleStyleOrGlobalRef(astRule: ast.ViewRuleStyleOrGlobalRef): c4.ViewRuleStyleOrGlobalRef;
17
- parseViewRuleGroup(astNode: ast.ViewRuleGroup): c4.ViewRuleGroup;
18
- parseViewRuleStyle(astRule: ast.ViewRuleStyle | ast.GlobalStyle): c4.ViewRuleStyle;
19
- parseRuleStyle(styleProperties: ast.StyleProperty[], elementExpressionsIterator: ast.FqnExpressions, notationProperty?: ast.NotationProperty): c4.ViewRuleStyle;
16
+ parseViewRuleStyleOrGlobalRef(astRule: ast.ViewRuleStyleOrGlobalRef): any;
17
+ parseViewRuleGroup(astNode: ast.ViewRuleGroup): c4.ElementViewRuleGroup;
18
+ parseViewRuleStyle(astRule: ast.ViewRuleStyle | ast.GlobalStyle): c4.ElementViewRuleStyle;
20
19
  parseViewRuleGlobalStyle(astRule: ast.ViewRuleGlobalStyle): c4.ViewRuleGlobalStyle;
21
- parseDynamicElementView(astNode: ast.DynamicView, additionalStyles: c4.ViewRuleStyleOrGlobalRef[]): import("../../ast").ParsedAstDynamicView;
20
+ parseDynamicElementView(astNode: ast.DynamicView, additionalStyles: any[]): import("../../ast").ParsedAstDynamicView;
22
21
  parseDynamicViewRule(astRule: ast.DynamicViewRule): c4.DynamicViewRule;
23
22
  parseDynamicViewIncludePredicate(astRule: ast.DynamicViewIncludePredicate): c4.DynamicViewIncludeRule;
24
23
  parseDynamicParallelSteps(node: ast.DynamicViewParallelSteps): c4.DynamicViewParallelSteps;
25
24
  parseDynamicStep(node: ast.DynamicViewStep): c4.DynamicViewStep;
26
- parsePredicate(astNode: ast.ExpressionV2): c4.ModelLayer.Expression;
27
- parseElementPredicate(astNode: ast.FqnExprOrWith): c4.ModelLayer.AnyFqnExpr;
28
- parseElementPredicateOrWhere(astNode: ast.FqnExprOrWhere): c4.ModelLayer.FqnExprOrWhere;
29
- parseElementExpression(astNode: ast.FqnExpr): c4.ModelLayer.FqnExpr;
30
- parseElementPredicateWhere(astNode: ast.FqnExprWhere): c4.ModelLayer.FqnExpr.Where;
31
- parseElementPredicateWith(astNode: ast.FqnExprWith): c4.ModelLayer.FqnExpr.Custom;
32
- parseRelationPredicate(astNode: ast.RelationExprOrWith): c4.ModelLayer.AnyRelationExpr;
33
- parseRelationPredicateOrWhere(astNode: ast.RelationExprOrWhere): c4.ModelLayer.RelationExprOrWhere;
34
- parseRelationPredicateWhere(astNode: ast.RelationExprWhere): c4.ModelLayer.RelationExpr.Where;
35
- parseRelationPredicateWith(astNode: ast.RelationExprWith): c4.ModelLayer.RelationExpr.Custom;
36
- parseRelationExpression(astNode: ast.RelationExpr): c4.ModelLayer.RelationExpr;
25
+ parsePredicate(astNode: ast.ExpressionV2): c4.ModelExpression;
26
+ parseElementPredicate(astNode: ast.FqnExprOrWith): c4.ModelFqnExpr.Any;
27
+ parseElementPredicateOrWhere(astNode: ast.FqnExprOrWhere): c4.ModelFqnExpr.OrWhere;
28
+ parseElementExpression(astNode: ast.FqnExpr): c4.ModelFqnExpr;
29
+ parseElementPredicateWhere(astNode: ast.FqnExprWhere): c4.ModelFqnExpr.Where;
30
+ parseElementPredicateWith(astNode: ast.FqnExprWith): c4.ModelFqnExpr.Custom;
31
+ parseRelationPredicate(astNode: ast.RelationExprOrWith): c4.ModelRelationExpr.Any;
32
+ parseRelationPredicateOrWhere(astNode: ast.RelationExprOrWhere): c4.ModelRelationExpr.OrWhere;
33
+ parseRelationPredicateWhere(astNode: ast.RelationExprWhere): c4.ModelRelationExpr.Where;
34
+ parseRelationPredicateWith(astNode: ast.RelationExprWith): c4.ModelRelationExpr.Custom;
35
+ parseRelationExpression(astNode: ast.RelationExpr): c4.ModelRelationExpr;
37
36
  parseFqnRef(astNode: ast.FqnRef): c4.FqnRef;
38
- parseExpressionV2(astNode: ast.ExpressionV2): c4.ExpressionV2;
37
+ parseExpressionV2(astNode: ast.ExpressionV2): c4.Expression;
39
38
  parseFqnExprOrWith(astNode: ast.FqnExprOrWith): c4.FqnExpr.Any;
40
39
  parseFqnExprWith(astNode: ast.FqnExprWith): c4.FqnExpr.Custom;
41
40
  parseFqnExprOrWhere(astNode: ast.FqnExprOrWhere): c4.FqnExpr.OrWhere;
@@ -74,7 +73,7 @@ export declare function GlobalsParser<TBase extends WithViewsParser>(B: TBase):
74
73
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
75
74
  parseDeploymentView(astNode: ast.DeploymentView): import("../../ast").ParsedAstDeploymentView;
76
75
  parseDeploymentViewRule(astRule: ast.DeploymentViewRule): c4.DeploymentViewRule;
77
- parseDeploymentViewRulePredicate(astRule: ast.DeploymentViewRulePredicate): c4.DeploymentViewRulePredicate;
76
+ parseDeploymentViewRulePredicate(astRule: ast.DeploymentViewRulePredicate): c4.DeploymentViewPredicate;
78
77
  parseDeploymentViewRuleStyle(astRule: ast.DeploymentViewRuleStyle): c4.DeploymentViewRuleStyle;
79
78
  parseDeployment(): void;
80
79
  parseDeploymentNode(astNode: ast.DeploymentNode): import("../../ast").ParsedAstDeployment.Node;
@@ -1,5 +1,5 @@
1
1
  import { nonexhaustive } from "@likec4/core";
2
- import { isTruthy } from "remeda";
2
+ import { hasAtLeast, isTruthy } from "remeda";
3
3
  import { ast } from "../../ast.js";
4
4
  import { logger, logWarnError } from "../../logger.js";
5
5
  export function GlobalsParser(B) {
@@ -36,7 +36,7 @@ export function GlobalsParser(B) {
36
36
  continue;
37
37
  }
38
38
  const styles2 = this.parseGlobalStyleOrGroup(style);
39
- if (styles2.length > 0) {
39
+ if (hasAtLeast(styles2, 1)) {
40
40
  c4Globals.styles[globalStyleId] = styles2;
41
41
  }
42
42
  } catch (e) {
@@ -47,14 +47,14 @@ export function GlobalsParser(B) {
47
47
  parseAndStoreGlobalPredicateGroupOrDynamic(astRule, id, c4Globals) {
48
48
  if (ast.isGlobalPredicateGroup(astRule)) {
49
49
  const predicates = this.parseGlobalPredicateGroup(astRule);
50
- if (predicates.length > 0) {
50
+ if (hasAtLeast(predicates, 1)) {
51
51
  c4Globals.predicates[id] = predicates;
52
52
  }
53
53
  return;
54
54
  }
55
55
  if (ast.isGlobalDynamicPredicateGroup(astRule)) {
56
56
  const predicates = this.parseGlobalDynamicPredicateGroup(astRule);
57
- if (predicates.length > 0) {
57
+ if (hasAtLeast(predicates, 1)) {
58
58
  c4Globals.dynamicPredicates[id] = predicates;
59
59
  }
60
60
  return;
@@ -11,7 +11,7 @@ export declare function ModelParser<TBase extends WithExpressionV2>(B: TBase): {
11
11
  _resolveRelationSource(node: ast.Relation): FqnRef.ModelRef | FqnRef.ImportRef;
12
12
  parseRelation(astNode: ast.Relation): ParsedAstRelation;
13
13
  parseFqnRef(astNode: ast.FqnRef): c4.FqnRef;
14
- parseExpressionV2(astNode: ast.ExpressionV2): c4.ExpressionV2;
14
+ parseExpressionV2(astNode: ast.ExpressionV2): c4.Expression;
15
15
  parseFqnExprOrWith(astNode: ast.FqnExprOrWith): c4.FqnExpr.Any;
16
16
  parseFqnExprWith(astNode: ast.FqnExprWith): c4.FqnExpr.Custom;
17
17
  parseFqnExprOrWhere(astNode: ast.FqnExprOrWhere): c4.FqnExpr.OrWhere;
@@ -137,7 +137,7 @@ ${error}`, {
137
137
  invariant(FqnRef.isModelRef(target) || FqnRef.isImportRef(target), "Target must be a model reference");
138
138
  const tags = this.parseTags(astNode) ?? this.parseTags(astNode.body);
139
139
  const links = this.parseLinks(astNode.body);
140
- const kind = astNode.kind?.ref?.name;
140
+ const kind = (astNode.kind ?? astNode.dotKind?.kind)?.ref?.name;
141
141
  const metadata = this.getMetadata(astNode.body?.props.find(ast.isMetadataProperty));
142
142
  const astPath = this.getAstNodePath(astNode);
143
143
  const bodyProps = mapToObj(
@@ -4,19 +4,19 @@ import type { WithExpressionV2 } from './FqnRefParser';
4
4
  export type WithPredicates = ReturnType<typeof PredicatesParser>;
5
5
  export declare function PredicatesParser<TBase extends WithExpressionV2>(B: TBase): {
6
6
  new (...args: any[]): {
7
- parsePredicate(astNode: ast.ExpressionV2): c4.ModelLayer.Expression;
8
- parseElementPredicate(astNode: ast.FqnExprOrWith): c4.ModelLayer.AnyFqnExpr;
9
- parseElementPredicateOrWhere(astNode: ast.FqnExprOrWhere): c4.ModelLayer.FqnExprOrWhere;
10
- parseElementExpression(astNode: ast.FqnExpr): c4.ModelLayer.FqnExpr;
11
- parseElementPredicateWhere(astNode: ast.FqnExprWhere): c4.ModelLayer.FqnExpr.Where;
12
- parseElementPredicateWith(astNode: ast.FqnExprWith): c4.ModelLayer.FqnExpr.Custom;
13
- parseRelationPredicate(astNode: ast.RelationExprOrWith): c4.ModelLayer.AnyRelationExpr;
14
- parseRelationPredicateOrWhere(astNode: ast.RelationExprOrWhere): c4.ModelLayer.RelationExprOrWhere;
15
- parseRelationPredicateWhere(astNode: ast.RelationExprWhere): c4.ModelLayer.RelationExpr.Where;
16
- parseRelationPredicateWith(astNode: ast.RelationExprWith): c4.ModelLayer.RelationExpr.Custom;
17
- parseRelationExpression(astNode: ast.RelationExpr): c4.ModelLayer.RelationExpr;
7
+ parsePredicate(astNode: ast.ExpressionV2): c4.ModelExpression;
8
+ parseElementPredicate(astNode: ast.FqnExprOrWith): c4.ModelFqnExpr.Any;
9
+ parseElementPredicateOrWhere(astNode: ast.FqnExprOrWhere): c4.ModelFqnExpr.OrWhere;
10
+ parseElementExpression(astNode: ast.FqnExpr): c4.ModelFqnExpr;
11
+ parseElementPredicateWhere(astNode: ast.FqnExprWhere): c4.ModelFqnExpr.Where;
12
+ parseElementPredicateWith(astNode: ast.FqnExprWith): c4.ModelFqnExpr.Custom;
13
+ parseRelationPredicate(astNode: ast.RelationExprOrWith): c4.ModelRelationExpr.Any;
14
+ parseRelationPredicateOrWhere(astNode: ast.RelationExprOrWhere): c4.ModelRelationExpr.OrWhere;
15
+ parseRelationPredicateWhere(astNode: ast.RelationExprWhere): c4.ModelRelationExpr.Where;
16
+ parseRelationPredicateWith(astNode: ast.RelationExprWith): c4.ModelRelationExpr.Custom;
17
+ parseRelationExpression(astNode: ast.RelationExpr): c4.ModelRelationExpr;
18
18
  parseFqnRef(astNode: ast.FqnRef): c4.FqnRef;
19
- parseExpressionV2(astNode: ast.ExpressionV2): c4.ExpressionV2;
19
+ parseExpressionV2(astNode: ast.ExpressionV2): c4.Expression;
20
20
  parseFqnExprOrWith(astNode: ast.FqnExprOrWith): c4.FqnExpr.Any;
21
21
  parseFqnExprWith(astNode: ast.FqnExprWith): c4.FqnExpr.Custom;
22
22
  parseFqnExprOrWhere(astNode: ast.FqnExprOrWhere): c4.FqnExpr.OrWhere;
@@ -4,8 +4,11 @@ import { type Base } from './Base';
4
4
  export declare function SpecificationParser<TBase extends Base>(B: TBase): {
5
5
  new (...args: any[]): {
6
6
  parseSpecification(): void;
7
- parseSpecificationDeploymentNodeKind({ kind, props }: ast.SpecificationDeploymentNodeKind): {
8
- [key: c4.DeploymentNodeKind]: c4.DeploymentNodeKindSpecification;
7
+ parseElementSpecificationNode(specAst: ast.SpecificationElementKind): {
8
+ [key: c4.ElementKind]: c4.ElementSpecification;
9
+ };
10
+ parseElementSpecificationNode(specAst: ast.SpecificationDeploymentNodeKind): {
11
+ [key: c4.DeploymentKind]: c4.ElementSpecification;
9
12
  };
10
13
  isValid: import("../../validation").IsValidFn;
11
14
  readonly services: import("../..").LikeC4Services;
@@ -14,27 +14,16 @@ export function SpecificationParser(B) {
14
14
  c4Specification
15
15
  } = this.doc;
16
16
  const isValid = this.isValid;
17
- const element_specs = specifications.flatMap((s) => s.elements.filter(this.isValid));
18
- for (const { kind, props } of element_specs) {
17
+ for (const elementSpec of specifications.flatMap((s) => s.elements.filter(isValid))) {
19
18
  try {
20
- const kindName = kind.name;
21
- if (!isTruthy(kindName)) {
22
- continue;
23
- }
24
- if (kindName in c4Specification.elements) {
25
- logger.warn(`Element kind "${kindName}" is already defined`);
26
- continue;
27
- }
28
- const style = this.parseElementStyle(props.find(ast.isElementStyleProperty));
29
- const bodyProps = pipe(
30
- props.filter(ast.isSpecificationElementStringProperty) ?? [],
31
- filter((p) => this.isValid(p) && isNonNullish(p.value)),
32
- mapToObj((p) => [p.key, removeIndent(p.value)])
33
- );
34
- c4Specification.elements[kindName] = {
35
- ...bodyProps,
36
- style
37
- };
19
+ Object.assign(c4Specification.elements, this.parseElementSpecificationNode(elementSpec));
20
+ } catch (e) {
21
+ logWarnError(e);
22
+ }
23
+ }
24
+ for (const deploymentNodeSpec of specifications.flatMap((s) => s.deploymentNodes.filter(isValid))) {
25
+ try {
26
+ Object.assign(c4Specification.deployments, this.parseElementSpecificationNode(deploymentNodeSpec));
38
27
  } catch (e) {
39
28
  logWarnError(e);
40
29
  }
@@ -66,16 +55,12 @@ export function SpecificationParser(B) {
66
55
  const tags_specs = specifications.flatMap((s) => s.tags.filter(this.isValid));
67
56
  for (const tagSpec of tags_specs) {
68
57
  const tag = tagSpec.tag.name;
58
+ const astPath = this.getAstNodePath(tagSpec.tag);
69
59
  if (isTruthy(tag)) {
70
- c4Specification.tags.add(tag);
71
- }
72
- }
73
- const deploymentNodes_specs = specifications.flatMap((s) => s.deploymentNodes.filter(isValid));
74
- for (const deploymentNode of deploymentNodes_specs) {
75
- try {
76
- Object.assign(c4Specification.deployments, this.parseSpecificationDeploymentNodeKind(deploymentNode));
77
- } catch (e) {
78
- logWarnError(e);
60
+ c4Specification.tags[tag] = {
61
+ astPath,
62
+ ...tagSpec.color ? { color: tagSpec.color } : {}
63
+ };
79
64
  }
80
65
  }
81
66
  const colors_specs = specifications.flatMap((s) => s.colors.filter(isValid));
@@ -94,11 +79,13 @@ export function SpecificationParser(B) {
94
79
  }
95
80
  }
96
81
  }
97
- parseSpecificationDeploymentNodeKind({ kind, props }) {
82
+ parseElementSpecificationNode(specAst) {
83
+ const { kind, props } = specAst;
98
84
  const kindName = kind.name;
99
85
  if (!isTruthy(kindName)) {
100
86
  throw new Error("DeploymentNodeKind name is not resolved");
101
87
  }
88
+ const tags = this.parseTags(specAst);
102
89
  const style = this.parseElementStyle(props.find(ast.isElementStyleProperty));
103
90
  const bodyProps = pipe(
104
91
  props.filter(ast.isSpecificationElementStringProperty) ?? [],
@@ -108,6 +95,7 @@ export function SpecificationParser(B) {
108
95
  return {
109
96
  [kindName]: {
110
97
  ...bodyProps,
98
+ ...tags && { tags },
111
99
  style
112
100
  }
113
101
  };
@@ -1,39 +1,38 @@
1
- import type * as c4 from '@likec4/core';
1
+ import * as c4 from '@likec4/core';
2
2
  import { type ParsedAstDynamicView, type ParsedAstElementView, ast } from '../../ast';
3
- import type { NotationProperty } from '../../generated/ast';
4
3
  import type { WithDeploymentView } from './DeploymentViewParser';
5
4
  import type { WithPredicates } from './PredicatesParser';
6
5
  export type WithViewsParser = ReturnType<typeof ViewsParser>;
6
+ type ViewRuleStyleOrGlobalRef = c4.ElementViewRuleStyle | c4.ViewRuleGlobalStyle;
7
7
  export declare function ViewsParser<TBase extends WithPredicates & WithDeploymentView>(B: TBase): {
8
8
  new (...args: any[]): {
9
9
  parseViews(): void;
10
- parseElementView(astNode: ast.ElementView, additionalStyles: c4.ViewRuleStyleOrGlobalRef[]): ParsedAstElementView;
11
- parseViewRule(astRule: ast.ViewRule): c4.ViewRule;
12
- parseViewRulePredicate(astNode: ast.ViewRulePredicate): c4.ViewRulePredicate;
10
+ parseElementView(astNode: ast.ElementView, additionalStyles: ViewRuleStyleOrGlobalRef[]): ParsedAstElementView;
11
+ parseElementViewRule(astRule: ast.ViewRule): c4.ElementViewRule;
12
+ parseViewRulePredicate(astNode: ast.ViewRulePredicate): c4.ElementViewPredicate;
13
13
  parseViewRuleGlobalPredicateRef(astRule: ast.ViewRuleGlobalPredicateRef | ast.DynamicViewGlobalPredicateRef): c4.ViewRuleGlobalPredicateRef;
14
- parseViewRuleStyleOrGlobalRef(astRule: ast.ViewRuleStyleOrGlobalRef): c4.ViewRuleStyleOrGlobalRef;
15
- parseViewRuleGroup(astNode: ast.ViewRuleGroup): c4.ViewRuleGroup;
16
- parseViewRuleStyle(astRule: ast.ViewRuleStyle | ast.GlobalStyle): c4.ViewRuleStyle;
17
- parseRuleStyle(styleProperties: ast.StyleProperty[], elementExpressionsIterator: ast.FqnExpressions, notationProperty?: NotationProperty): c4.ViewRuleStyle;
14
+ parseViewRuleStyleOrGlobalRef(astRule: ast.ViewRuleStyleOrGlobalRef): ViewRuleStyleOrGlobalRef;
15
+ parseViewRuleGroup(astNode: ast.ViewRuleGroup): c4.ElementViewRuleGroup;
16
+ parseViewRuleStyle(astRule: ast.ViewRuleStyle | ast.GlobalStyle): c4.ElementViewRuleStyle;
18
17
  parseViewRuleGlobalStyle(astRule: ast.ViewRuleGlobalStyle): c4.ViewRuleGlobalStyle;
19
- parseDynamicElementView(astNode: ast.DynamicView, additionalStyles: c4.ViewRuleStyleOrGlobalRef[]): ParsedAstDynamicView;
18
+ parseDynamicElementView(astNode: ast.DynamicView, additionalStyles: ViewRuleStyleOrGlobalRef[]): ParsedAstDynamicView;
20
19
  parseDynamicViewRule(astRule: ast.DynamicViewRule): c4.DynamicViewRule;
21
20
  parseDynamicViewIncludePredicate(astRule: ast.DynamicViewIncludePredicate): c4.DynamicViewIncludeRule;
22
21
  parseDynamicParallelSteps(node: ast.DynamicViewParallelSteps): c4.DynamicViewParallelSteps;
23
22
  parseDynamicStep(node: ast.DynamicViewStep): c4.DynamicViewStep;
24
- parsePredicate(astNode: ast.ExpressionV2): c4.ModelLayer.Expression;
25
- parseElementPredicate(astNode: ast.FqnExprOrWith): c4.ModelLayer.AnyFqnExpr;
26
- parseElementPredicateOrWhere(astNode: ast.FqnExprOrWhere): c4.ModelLayer.FqnExprOrWhere;
27
- parseElementExpression(astNode: ast.FqnExpr): c4.ModelLayer.FqnExpr;
28
- parseElementPredicateWhere(astNode: ast.FqnExprWhere): c4.ModelLayer.FqnExpr.Where;
29
- parseElementPredicateWith(astNode: ast.FqnExprWith): c4.ModelLayer.FqnExpr.Custom;
30
- parseRelationPredicate(astNode: ast.RelationExprOrWith): c4.ModelLayer.AnyRelationExpr;
31
- parseRelationPredicateOrWhere(astNode: ast.RelationExprOrWhere): c4.ModelLayer.RelationExprOrWhere;
32
- parseRelationPredicateWhere(astNode: ast.RelationExprWhere): c4.ModelLayer.RelationExpr.Where;
33
- parseRelationPredicateWith(astNode: ast.RelationExprWith): c4.ModelLayer.RelationExpr.Custom;
34
- parseRelationExpression(astNode: ast.RelationExpr): c4.ModelLayer.RelationExpr;
23
+ parsePredicate(astNode: ast.ExpressionV2): c4.ModelExpression;
24
+ parseElementPredicate(astNode: ast.FqnExprOrWith): c4.ModelFqnExpr.Any;
25
+ parseElementPredicateOrWhere(astNode: ast.FqnExprOrWhere): c4.ModelFqnExpr.OrWhere;
26
+ parseElementExpression(astNode: ast.FqnExpr): c4.ModelFqnExpr;
27
+ parseElementPredicateWhere(astNode: ast.FqnExprWhere): c4.ModelFqnExpr.Where;
28
+ parseElementPredicateWith(astNode: ast.FqnExprWith): c4.ModelFqnExpr.Custom;
29
+ parseRelationPredicate(astNode: ast.RelationExprOrWith): c4.ModelRelationExpr.Any;
30
+ parseRelationPredicateOrWhere(astNode: ast.RelationExprOrWhere): c4.ModelRelationExpr.OrWhere;
31
+ parseRelationPredicateWhere(astNode: ast.RelationExprWhere): c4.ModelRelationExpr.Where;
32
+ parseRelationPredicateWith(astNode: ast.RelationExprWith): c4.ModelRelationExpr.Custom;
33
+ parseRelationExpression(astNode: ast.RelationExpr): c4.ModelRelationExpr;
35
34
  parseFqnRef(astNode: ast.FqnRef): c4.FqnRef;
36
- parseExpressionV2(astNode: ast.ExpressionV2): c4.ExpressionV2;
35
+ parseExpressionV2(astNode: ast.ExpressionV2): c4.Expression;
37
36
  parseFqnExprOrWith(astNode: ast.FqnExprOrWith): c4.FqnExpr.Any;
38
37
  parseFqnExprWith(astNode: ast.FqnExprWith): c4.FqnExpr.Custom;
39
38
  parseFqnExprOrWhere(astNode: ast.FqnExprOrWhere): c4.FqnExpr.OrWhere;
@@ -72,7 +71,7 @@ export declare function ViewsParser<TBase extends WithPredicates & WithDeploymen
72
71
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
73
72
  parseDeploymentView(astNode: ast.DeploymentView): import("../../ast").ParsedAstDeploymentView;
74
73
  parseDeploymentViewRule(astRule: ast.DeploymentViewRule): c4.DeploymentViewRule;
75
- parseDeploymentViewRulePredicate(astRule: ast.DeploymentViewRulePredicate): c4.DeploymentViewRulePredicate;
74
+ parseDeploymentViewRulePredicate(astRule: ast.DeploymentViewRulePredicate): c4.DeploymentViewPredicate;
76
75
  parseDeploymentViewRuleStyle(astRule: ast.DeploymentViewRuleStyle): c4.DeploymentViewRuleStyle;
77
76
  parseDeployment(): void;
78
77
  parseDeploymentNode(astNode: ast.DeploymentNode): import("../../ast").ParsedAstDeployment.Node;
@@ -82,3 +81,4 @@ export declare function ViewsParser<TBase extends WithPredicates & WithDeploymen
82
81
  parseDeploymentRelation(astNode: ast.DeploymentRelation): import("../../ast").ParsedAstDeploymentRelation;
83
82
  };
84
83
  } & TBase;
84
+ export {};
@@ -1,4 +1,5 @@
1
- import { invariant, isNonEmptyArray, ModelLayer, nonexhaustive } from "@likec4/core";
1
+ import * as c4 from "@likec4/core";
2
+ import { invariant, isNonEmptyArray, nonexhaustive } from "@likec4/core";
2
3
  import { isArray, isDefined, isNonNullish, isTruthy } from "remeda";
3
4
  import {
4
5
  ast,
@@ -76,7 +77,7 @@ export function ViewsParser(B) {
76
77
  const links = this.convertLinks(body);
77
78
  const manualLayout = parseViewManualLayout(astNode);
78
79
  const view = {
79
- __: "element",
80
+ [c4._type]: "element",
80
81
  id,
81
82
  astPath,
82
83
  title,
@@ -87,7 +88,7 @@ export function ViewsParser(B) {
87
88
  ...additionalStyles,
88
89
  ...body.rules.flatMap((n) => {
89
90
  try {
90
- return this.isValid(n) ? this.parseViewRule(n) : [];
91
+ return this.isValid(n) ? this.parseElementViewRule(n) : [];
91
92
  } catch (e) {
92
93
  logWarnError(e);
93
94
  return [];
@@ -107,7 +108,7 @@ export function ViewsParser(B) {
107
108
  }
108
109
  return view;
109
110
  }
110
- parseViewRule(astRule) {
111
+ parseElementViewRule(astRule) {
111
112
  if (ast.isViewRulePredicate(astRule)) {
112
113
  return this.parseViewRulePredicate(astRule);
113
114
  }
@@ -186,23 +187,15 @@ export function ViewsParser(B) {
186
187
  };
187
188
  }
188
189
  parseViewRuleStyle(astRule) {
189
- const styleProps = astRule.props.filter(ast.isStyleProperty);
190
- const targets = astRule.targets;
191
- const notation = astRule.props.find(ast.isNotationProperty);
192
- return this.parseRuleStyle(styleProps, targets, notation);
193
- }
194
- parseRuleStyle(styleProperties, elementExpressionsIterator, notationProperty) {
195
- const styleProps = this.parseStyleProps(styleProperties);
196
- const notation = removeIndent(notationProperty?.value);
197
- const targets = this.parseFqnExpressions(elementExpressionsIterator).filter(
198
- (e) => ModelLayer.Expression.isFqnExpr(e)
190
+ const targets = this.parseFqnExpressions(astRule.targets).filter(
191
+ (e) => c4.ModelExpression.isFqnExpr(e)
199
192
  );
193
+ const style = this.parseStyleProps(astRule.props.filter(ast.isStyleProperty));
194
+ const notation = removeIndent(astRule.props.find(ast.isNotationProperty)?.value);
200
195
  return {
201
196
  targets,
202
- ...notation && { notation },
203
- style: {
204
- ...styleProps
205
- }
197
+ style,
198
+ ...notation && { notation }
206
199
  };
207
200
  }
208
201
  parseViewRuleGlobalStyle(astRule) {
@@ -230,7 +223,7 @@ export function ViewsParser(B) {
230
223
  ViewOps.writeId(astNode, id);
231
224
  const manualLayout = parseViewManualLayout(astNode);
232
225
  return {
233
- __: "dynamic",
226
+ [c4._type]: "dynamic",
234
227
  id,
235
228
  astPath,
236
229
  title,
@@ -1,4 +1,4 @@
1
- import { type Fqn, type NonEmptyArray, type ViewChange } from '@likec4/core';
1
+ import { type DeploymentFqn, type Fqn, type NonEmptyArray, type ViewChange } from '@likec4/core';
2
2
  import { type Range, TextEdit } from 'vscode-languageserver-types';
3
3
  import { type ParsedAstView, type ParsedLikeC4LangiumDocument, ast } from '../ast';
4
4
  import type { LikeC4Services } from '../module';
@@ -6,7 +6,7 @@ type ChangeElementStyleArg = {
6
6
  view: ParsedAstView;
7
7
  doc: ParsedLikeC4LangiumDocument;
8
8
  viewAst: ast.LikeC4View;
9
- targets: NonEmptyArray<Fqn>;
9
+ targets: NonEmptyArray<Fqn | DeploymentFqn>;
10
10
  style: ViewChange.ChangeElementStyle['style'];
11
11
  };
12
12
  export declare function changeElementStyle(services: LikeC4Services, { view, viewAst, targets, style, }: ChangeElementStyleArg): {
@@ -1,4 +1,8 @@
1
- import { invariant, isAncestor } from "@likec4/core";
1
+ import {
2
+ _type,
3
+ invariant,
4
+ isAncestor
5
+ } from "@likec4/core";
2
6
  import { GrammarUtils } from "langium";
3
7
  import { entries, filter, findLast, isTruthy, last } from "remeda";
4
8
  import { TextEdit } from "vscode-languageserver-types";
@@ -43,7 +47,7 @@ export function changeElementStyle(services, {
43
47
  viewAst.body.rules,
44
48
  (r) => ast.isViewRuleStyle(r) || ast.isDeploymentViewRuleStyle(r)
45
49
  );
46
- const viewOf = view.__ === "element" ? view.viewOf : null;
50
+ const viewOf = view[_type] === "element" ? view.viewOf ?? null : null;
47
51
  const existing = [];
48
52
  const insert = [];
49
53
  targets.forEach((target) => {
package/dist/module.d.ts CHANGED
@@ -4,7 +4,7 @@ import { type DefaultSharedModuleContext, type LangiumServices, type LangiumShar
4
4
  import { LikeC4DocumentationProvider } from './documentation';
5
5
  import { type LikeC4LanguageServices } from './LikeC4LanguageServices';
6
6
  import { LikeC4CodeLensProvider, LikeC4CompletionProvider, LikeC4DocumentHighlightProvider, LikeC4DocumentLinkProvider, LikeC4DocumentSymbolProvider, LikeC4HoverProvider, LikeC4SemanticTokenProvider } from './lsp';
7
- import { type LikeC4MCPServer, LikeC4MCPServerFactory } from './mcp/LikeC4MCPServerFactory';
7
+ import { type LikeC4MCPServer, type LikeC4MCPServerFactory } from './mcp/LikeC4MCPServerFactory';
8
8
  import { type LikeC4MCPTools } from './mcp/LikeC4MCPTools';
9
9
  import { type LikeC4ModelBuilder, DeploymentsIndex, FqnIndex, LikeC4ModelLocator, LikeC4ModelParser } from './model';
10
10
  import { LikeC4ModelChanges } from './model-change/ModelChanges';
package/dist/module.js CHANGED
@@ -26,7 +26,10 @@ import {
26
26
  LikeC4HoverProvider,
27
27
  LikeC4SemanticTokenProvider
28
28
  } from "./lsp/index.js";
29
- import { LikeC4MCPServerFactory, NoopLikeC4MCPServer } from "./mcp/LikeC4MCPServerFactory.js";
29
+ import {
30
+ NoopLikeC4MCPServer,
31
+ NoopLikeC4MCPServerFactory
32
+ } from "./mcp/LikeC4MCPServerFactory.js";
30
33
  import { DefaultLikeC4MCPTools } from "./mcp/LikeC4MCPTools.js";
31
34
  import {
32
35
  DefaultLikeC4ModelBuilder,
@@ -79,7 +82,7 @@ export const LikeC4Module = {
79
82
  mcp: {
80
83
  Tools: bind(DefaultLikeC4MCPTools),
81
84
  Server: bind(NoopLikeC4MCPServer),
82
- ServerFactory: bind(LikeC4MCPServerFactory)
85
+ ServerFactory: bind(NoopLikeC4MCPServerFactory)
83
86
  },
84
87
  likec4: {
85
88
  LanguageServices: bind(DefaultLikeC4LanguageServices),
@@ -1,6 +1,6 @@
1
- import type { ComputedLikeC4ModelData, ComputedView, DiagramView, Fqn, LayoutedLikeC4ModelData, NonEmptyArray, ProjectId, RelationId, ViewChange, ViewId } from '@likec4/core';
1
+ import type { ComputedLikeC4ModelData, ComputedView, DeploymentFqn, DiagramView, Fqn, LayoutedLikeC4ModelData, NonEmptyArray, ProjectId, RelationId, ViewChange, ViewId } from '@likec4/core';
2
2
  import { NotificationType, RequestType, RequestType0 } from 'vscode-jsonrpc';
3
- import type { DiagnosticSeverity, DocumentUri, Location, Position } from 'vscode-languageserver-types';
3
+ import type { DiagnosticSeverity, DocumentUri, Location, Position, Range } from 'vscode-languageserver-types';
4
4
  export declare namespace DidChangeModelNotification {
5
5
  const type: NotificationType<string>;
6
6
  type Type = typeof type;
@@ -143,7 +143,7 @@ export declare namespace Locate {
143
143
  projectId?: string | undefined;
144
144
  relation: RelationId;
145
145
  } | {
146
- deployment: Fqn;
146
+ deployment: DeploymentFqn;
147
147
  projectId?: string | undefined;
148
148
  property?: string;
149
149
  } | {
@@ -186,3 +186,24 @@ export declare namespace FetchTelemetryMetrics {
186
186
  const req: RequestType0<Res, void>;
187
187
  type Req = typeof req;
188
188
  }
189
+ /**
190
+ * Request to fetch all tags of a document
191
+ */
192
+ export declare namespace GetDocumentTags {
193
+ type Params = {
194
+ documentUri: DocumentUri;
195
+ };
196
+ type Res = {
197
+ /**
198
+ * Used tags in the document
199
+ */
200
+ tags: Array<{
201
+ name: string;
202
+ range: Range;
203
+ color: string;
204
+ isSpecification?: boolean;
205
+ }>;
206
+ };
207
+ const req: RequestType<Params, Res, void>;
208
+ type Req = typeof req;
209
+ }
package/dist/protocol.js CHANGED
@@ -47,3 +47,7 @@ export var FetchTelemetryMetrics;
47
47
  ((FetchTelemetryMetrics2) => {
48
48
  FetchTelemetryMetrics2.req = new RequestType0("likec4/metrics");
49
49
  })(FetchTelemetryMetrics || (FetchTelemetryMetrics = {}));
50
+ export var GetDocumentTags;
51
+ ((GetDocumentTags2) => {
52
+ GetDocumentTags2.req = new RequestType("likec4/document-tags");
53
+ })(GetDocumentTags || (GetDocumentTags = {}));