@likec4/language-server 1.32.0 → 1.32.1

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.
@@ -72,6 +72,7 @@ declare const DocumentParserFromMixins: {
72
72
  convertLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
73
73
  parseLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
74
74
  parseIconProperty(prop: import("../generated/ast").IconProperty | undefined): ProjectId | undefined;
75
+ parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
75
76
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
76
77
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
77
78
  parseDeploymentView(astNode: import("../generated/ast").DeploymentView): import("../ast").ParsedAstDeploymentView;
@@ -148,6 +149,7 @@ declare const DocumentParserFromMixins: {
148
149
  convertLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
149
150
  parseLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
150
151
  parseIconProperty(prop: import("../generated/ast").IconProperty | undefined): ProjectId | undefined;
152
+ parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
151
153
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
152
154
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
153
155
  parseDeploymentView(astNode: import("../generated/ast").DeploymentView): import("../ast").ParsedAstDeploymentView;
@@ -188,6 +190,7 @@ declare const DocumentParserFromMixins: {
188
190
  convertLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
189
191
  parseLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
190
192
  parseIconProperty(prop: import("../generated/ast").IconProperty | undefined): ProjectId | undefined;
193
+ parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
191
194
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
192
195
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
193
196
  };
@@ -240,6 +243,7 @@ declare const DocumentParserFromMixins: {
240
243
  convertLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
241
244
  parseLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
242
245
  parseIconProperty(prop: import("../generated/ast").IconProperty | undefined): ProjectId | undefined;
246
+ parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
243
247
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
244
248
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
245
249
  };
@@ -285,6 +289,7 @@ declare const DocumentParserFromMixins: {
285
289
  convertLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
286
290
  parseLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
287
291
  parseIconProperty(prop: import("../generated/ast").IconProperty | undefined): ProjectId | undefined;
292
+ parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
288
293
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
289
294
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
290
295
  parseDeployment(): void;
@@ -338,6 +343,7 @@ declare const DocumentParserFromMixins: {
338
343
  convertLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
339
344
  parseLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
340
345
  parseIconProperty(prop: import("../generated/ast").IconProperty | undefined): ProjectId | undefined;
346
+ parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
341
347
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
342
348
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
343
349
  };
@@ -384,6 +390,7 @@ declare const DocumentParserFromMixins: {
384
390
  convertLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
385
391
  parseLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
386
392
  parseIconProperty(prop: import("../generated/ast").IconProperty | undefined): ProjectId | undefined;
393
+ parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
387
394
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
388
395
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
389
396
  };
@@ -412,6 +419,7 @@ declare const DocumentParserFromMixins: {
412
419
  convertLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
413
420
  parseLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
414
421
  parseIconProperty(prop: import("../generated/ast").IconProperty | undefined): ProjectId | undefined;
422
+ parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
415
423
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
416
424
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
417
425
  };
@@ -453,6 +461,7 @@ declare const DocumentParserFromMixins: {
453
461
  convertLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
454
462
  parseLinks(source?: import("../generated/ast").LinkProperty["$container"]): ProjectId[] | undefined;
455
463
  parseIconProperty(prop: import("../generated/ast").IconProperty | undefined): ProjectId | undefined;
464
+ parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
456
465
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
457
466
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
458
467
  };
@@ -32,6 +32,7 @@ export declare class BaseParser {
32
32
  convertLinks(source?: ast.LinkProperty['$container']): c4.Link[] | undefined;
33
33
  parseLinks(source?: ast.LinkProperty['$container']): c4.Link[] | undefined;
34
34
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
35
+ parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
35
36
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): ParsedElementStyle;
36
37
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): ParsedElementStyle;
37
38
  }
@@ -7,6 +7,8 @@ import {
7
7
  isBoolean,
8
8
  isEmpty,
9
9
  isNonNullish,
10
+ isNumber,
11
+ isString,
10
12
  isTruthy,
11
13
  map,
12
14
  pipe,
@@ -17,6 +19,7 @@ import { hasLeadingSlash, hasProtocol, isRelative, joinRelativeURL, joinURL } fr
17
19
  import {
18
20
  ast,
19
21
  parseAstOpacityProperty,
22
+ parseAstPercent,
20
23
  parseAstSizeValue,
21
24
  toColor
22
25
  } from "../../ast.js";
@@ -154,6 +157,25 @@ export class BaseParser {
154
157
  }
155
158
  }
156
159
  }
160
+ parseColorLiteral(astNode) {
161
+ if (!this.isValid(astNode)) {
162
+ return void 0;
163
+ }
164
+ if (ast.isHexColor(astNode)) {
165
+ return `#${astNode.hex}`;
166
+ }
167
+ if (ast.isRGBAColor(astNode)) {
168
+ let alpha = isNumber(astNode.alpha) ? astNode.alpha : void 0;
169
+ if (isString(astNode.alpha)) {
170
+ alpha = parseAstPercent(astNode.alpha) / 100;
171
+ }
172
+ if (alpha !== void 0) {
173
+ return `rgba(${astNode.red},${astNode.green},${astNode.blue},${alpha})`;
174
+ }
175
+ return `rgb(${astNode.red},${astNode.green},${astNode.blue})`;
176
+ }
177
+ nonexhaustive(astNode);
178
+ }
157
179
  parseElementStyle(elementProps) {
158
180
  if (!elementProps) {
159
181
  return {};
@@ -47,6 +47,7 @@ export declare function DeploymentModelParser<TBase extends WithExpressionV2>(B:
47
47
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
48
48
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
49
49
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
50
+ parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
50
51
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
51
52
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
52
53
  };
@@ -45,6 +45,7 @@ export declare function DeploymentViewParser<TBase extends WithExpressionV2 & Wi
45
45
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
46
46
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
47
47
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
48
+ parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
48
49
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
49
50
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
50
51
  parseDeployment(): void;
@@ -40,6 +40,7 @@ export declare function ExpressionV2Parser<TBase extends Base>(B: TBase): {
40
40
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
41
41
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
42
42
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
43
+ parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
43
44
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
44
45
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
45
46
  };
@@ -69,6 +69,7 @@ export declare function GlobalsParser<TBase extends WithViewsParser>(B: TBase):
69
69
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
70
70
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
71
71
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
72
+ parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
72
73
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
73
74
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
74
75
  parseDeploymentView(astNode: ast.DeploymentView): import("../../ast").ParsedAstDeploymentView;
@@ -26,6 +26,7 @@ export declare function ImportsParser<TBase extends Base>(B: TBase): {
26
26
  convertLinks(source?: ast.LinkProperty["$container"]): ProjectId[] | undefined;
27
27
  parseLinks(source?: ast.LinkProperty["$container"]): ProjectId[] | undefined;
28
28
  parseIconProperty(prop: ast.IconProperty | undefined): ProjectId | undefined;
29
+ parseColorLiteral(astNode: ast.ColorLiteral): ProjectId | undefined;
29
30
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
30
31
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
31
32
  };
@@ -46,6 +46,7 @@ export declare function ModelParser<TBase extends WithExpressionV2>(B: TBase): {
46
46
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
47
47
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
48
48
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
49
+ parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
49
50
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
50
51
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
51
52
  };
@@ -51,6 +51,7 @@ export declare function PredicatesParser<TBase extends WithExpressionV2>(B: TBas
51
51
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
52
52
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
53
53
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
54
+ parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
54
55
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
55
56
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
56
57
  };
@@ -32,6 +32,7 @@ export declare function SpecificationParser<TBase extends Base>(B: TBase): {
32
32
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
33
33
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
34
34
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
35
+ parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
35
36
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
36
37
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
37
38
  };
@@ -1,3 +1,4 @@
1
+ import { nonNullable } from "@likec4/core/utils";
1
2
  import { filter, isNonNullish, isTruthy, mapToObj, pipe } from "remeda";
2
3
  import { ast, toRelationshipStyleExcludeDefaults } from "../../ast.js";
3
4
  import { logger, logWarnError } from "../../logger.js";
@@ -56,10 +57,11 @@ export function SpecificationParser(B) {
56
57
  for (const tagSpec of tags_specs) {
57
58
  const tag = tagSpec.tag.name;
58
59
  const astPath = this.getAstNodePath(tagSpec.tag);
60
+ const color = tagSpec.color && this.parseColorLiteral(tagSpec.color);
59
61
  if (isTruthy(tag)) {
60
62
  c4Specification.tags[tag] = {
61
63
  astPath,
62
- ...tagSpec.color ? { color: tagSpec.color } : {}
64
+ ...color ? { color } : {}
63
65
  };
64
66
  }
65
67
  }
@@ -72,7 +74,7 @@ export function SpecificationParser(B) {
72
74
  continue;
73
75
  }
74
76
  c4Specification.colors[colorName] = {
75
- color
77
+ color: nonNullable(this.parseColorLiteral(color), `Color "${colorName}" is not valid: ${color}`)
76
78
  };
77
79
  } catch (e) {
78
80
  logWarnError(e);
@@ -67,6 +67,7 @@ export declare function ViewsParser<TBase extends WithPredicates & WithDeploymen
67
67
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
68
68
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
69
69
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
70
+ parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
70
71
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
71
72
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
72
73
  parseDeploymentView(astNode: ast.DeploymentView): import("../../ast").ParsedAstDeploymentView;
@@ -3,7 +3,7 @@ import { type LikeC4LangiumDocument, ast } from '../ast';
3
3
  import type { LikeC4Services } from '../module';
4
4
  type Guard<N extends AstNode> = (n: AstNode) => n is N;
5
5
  type Guarded<G> = G extends Guard<infer N> ? N : never;
6
- declare const isValidatableAstNode: (n: AstNode) => n is ast.DeployedInstance | ast.DeploymentNode | ast.DeploymentViewRulePredicate | ast.DeploymentViewRuleStyle | ast.ViewRuleAutoLayout | ast.DynamicViewGlobalPredicateRef | ast.DynamicViewIncludePredicate | ast.ViewRuleGlobalStyle | ast.ViewRuleStyle | ast.ElementStringProperty | ast.ElementStyleProperty | ast.IconProperty | ast.LinkProperty | ast.MetadataBody | ast.ElementKindExpression | ast.ElementTagExpression | ast.FqnRefExpr | ast.WildcardExpression | ast.FqnExprWhere | ast.FqnExprWith | ast.DirectedRelationExpr | ast.InOutRelationExpr | ast.IncomingRelationExpr | ast.OutgoingRelationExpr | ast.RelationExprWhere | ast.RelationExprWith | ast.Element | ast.ExtendDeployment | ast.ExtendElement | ast.Imported | ast.DeploymentView | ast.DynamicView | ast.ElementView | ast.RelationStringProperty | ast.ArrowProperty | ast.ColorProperty | ast.LineProperty | ast.PaddingSizeProperty | ast.ShapeSizeProperty | ast.TextSizeProperty | ast.MetadataAttribute | ast.NotationProperty | ast.NotesProperty | ast.SpecificationElementStringProperty | ast.SpecificationRelationshipStringProperty | ast.ViewStringProperty | ast.BorderProperty | ast.MultipleProperty | ast.OpacityProperty | ast.ShapeProperty | ast.ViewRuleGlobalPredicateRef | ast.ViewRuleGroup | ast.ViewRulePredicate | ast.SpecificationRelationshipKind | ast.GlobalStyle | ast.SpecificationColor | ast.NavigateToProperty | ast.DynamicViewStep | ast.ElementRef | ast.DeploymentRelation | ast.Tags | ast.SpecificationDeploymentNodeKind | ast.DynamicViewParallelSteps | ast.GlobalDynamicPredicateGroup | ast.Relation | ast.SpecificationElementKind | ast.Globals | ast.GlobalPredicateGroup | ast.GlobalStyleGroup | ast.ImportsFromPoject | ast.SpecificationRule | ast.SpecificationTag;
6
+ declare const isValidatableAstNode: (n: AstNode) => n is ast.HexColor | ast.RGBAColor | ast.DeployedInstance | ast.DeploymentNode | ast.DeploymentViewRulePredicate | ast.DeploymentViewRuleStyle | ast.ViewRuleAutoLayout | ast.DynamicViewGlobalPredicateRef | ast.DynamicViewIncludePredicate | ast.ViewRuleGlobalStyle | ast.ViewRuleStyle | ast.ElementStringProperty | ast.ElementStyleProperty | ast.IconProperty | ast.LinkProperty | ast.MetadataBody | ast.ElementKindExpression | ast.ElementTagExpression | ast.FqnRefExpr | ast.WildcardExpression | ast.FqnExprWhere | ast.FqnExprWith | ast.DirectedRelationExpr | ast.InOutRelationExpr | ast.IncomingRelationExpr | ast.OutgoingRelationExpr | ast.RelationExprWhere | ast.RelationExprWith | ast.Element | ast.ExtendDeployment | ast.ExtendElement | ast.Imported | ast.DeploymentView | ast.DynamicView | ast.ElementView | ast.RelationStringProperty | ast.ArrowProperty | ast.ColorProperty | ast.LineProperty | ast.PaddingSizeProperty | ast.ShapeSizeProperty | ast.TextSizeProperty | ast.MetadataAttribute | ast.NotationProperty | ast.NotesProperty | ast.SpecificationElementStringProperty | ast.SpecificationRelationshipStringProperty | ast.ViewStringProperty | ast.BorderProperty | ast.MultipleProperty | ast.OpacityProperty | ast.ShapeProperty | ast.ViewRuleGlobalPredicateRef | ast.ViewRuleGroup | ast.ViewRulePredicate | ast.SpecificationRelationshipKind | ast.GlobalStyle | ast.SpecificationColor | ast.NavigateToProperty | ast.DynamicViewStep | ast.ElementRef | ast.DeploymentRelation | ast.Tags | ast.SpecificationDeploymentNodeKind | ast.DynamicViewParallelSteps | ast.GlobalDynamicPredicateGroup | ast.Relation | ast.SpecificationElementKind | ast.Globals | ast.GlobalPredicateGroup | ast.GlobalStyleGroup | ast.SpecificationTag | ast.ImportsFromPoject | ast.SpecificationRule;
7
7
  type ValidatableAstNode = Guarded<typeof isValidatableAstNode>;
8
8
  export declare function checksFromDiagnostics(doc: LikeC4LangiumDocument): {
9
9
  isValid: (n: ValidatableAstNode) => boolean;
@@ -13,7 +13,12 @@ import { dynamicViewStep } from "./dynamic-view-step.js";
13
13
  import { checkElement } from "./element.js";
14
14
  import { checkElementRef } from "./element-ref.js";
15
15
  import { checkImported, checkImportsFromPoject } from "./imports.js";
16
- import { iconPropertyRuleChecks, notesPropertyRuleChecks, opacityPropertyRuleChecks } from "./property-checks.js";
16
+ import {
17
+ colorLiteralRuleChecks,
18
+ iconPropertyRuleChecks,
19
+ notesPropertyRuleChecks,
20
+ opacityPropertyRuleChecks
21
+ } from "./property-checks.js";
17
22
  import { checkRelationBody, relationChecks } from "./relation.js";
18
23
  import {
19
24
  checkDeploymentNodeKind,
@@ -82,7 +87,8 @@ const isValidatableAstNode = validatableAstNodeGuards([
82
87
  ast.isSpecificationDeploymentNodeKind,
83
88
  ast.isSpecificationTag,
84
89
  ast.isSpecificationColor,
85
- ast.isSpecificationRule
90
+ ast.isSpecificationRule,
91
+ ast.isColorLiteral
86
92
  ]);
87
93
  const findInvalidContainer = (node) => {
88
94
  let nd = node;
@@ -147,7 +153,8 @@ export function registerValidationChecks(services) {
147
153
  IncomingRelationExpr: checkIncomingRelationExpr(services),
148
154
  OutgoingRelationExpr: checkOutgoingRelationExpr(services),
149
155
  ImportsFromPoject: checkImportsFromPoject(services),
150
- Imported: checkImported(services)
156
+ Imported: checkImported(services),
157
+ ColorLiteral: colorLiteralRuleChecks(services)
151
158
  });
152
159
  const connection = services.shared.lsp.Connection;
153
160
  if (connection) {
@@ -4,3 +4,4 @@ import type { LikeC4Services } from '../module';
4
4
  export declare const opacityPropertyRuleChecks: (_: LikeC4Services) => ValidationCheck<ast.OpacityProperty>;
5
5
  export declare const iconPropertyRuleChecks: (_: LikeC4Services) => ValidationCheck<ast.IconProperty>;
6
6
  export declare const notesPropertyRuleChecks: (_: LikeC4Services) => ValidationCheck<ast.NotesProperty>;
7
+ export declare const colorLiteralRuleChecks: (_: LikeC4Services) => ValidationCheck<ast.ColorLiteral>;
@@ -1,4 +1,6 @@
1
+ import { nonexhaustive } from "@likec4/core";
1
2
  import { AstUtils } from "langium";
3
+ import { isNumber, isString } from "remeda";
2
4
  import { ast } from "../ast.js";
3
5
  import { tryOrLog } from "./_shared.js";
4
6
  export const opacityPropertyRuleChecks = (_) => {
@@ -43,3 +45,63 @@ export const notesPropertyRuleChecks = (_) => {
43
45
  }
44
46
  };
45
47
  };
48
+ export const colorLiteralRuleChecks = (_) => {
49
+ return (node, accept) => {
50
+ if (node.$type === "HexColor") {
51
+ if (node.hex === void 0) {
52
+ accept("error", `Invalid HEX`, {
53
+ node,
54
+ property: "hex"
55
+ });
56
+ return;
57
+ }
58
+ const length = isNumber(node.hex) ? node.hex.toString().length : node.hex.length;
59
+ if (length !== 6 && length !== 3 && length !== 8) {
60
+ accept("error", `Invalid value "${node.$cstNode?.text}", must be 3, 6 or 8 characters long`, {
61
+ node,
62
+ property: "hex"
63
+ });
64
+ }
65
+ return;
66
+ }
67
+ if (node.$type === "RGBAColor") {
68
+ if (!isNumber(node.red) || node.red < 0 || node.red > 255) {
69
+ accept("error", `Invalid value, must be between 0 and 255`, {
70
+ node,
71
+ property: "red"
72
+ });
73
+ }
74
+ if (!isNumber(node.green) || node.green < 0 || node.green > 255) {
75
+ accept("error", `Invalid value, must be between 0 and 255`, {
76
+ node,
77
+ property: "green"
78
+ });
79
+ }
80
+ if (!isNumber(node.blue) || node.blue < 0 || node.blue > 255) {
81
+ accept("error", `Invalid value, must be between 0 and 255`, {
82
+ node,
83
+ property: "blue"
84
+ });
85
+ }
86
+ if (isNumber(node.alpha)) {
87
+ if (node.alpha < 0 || node.alpha > 1) {
88
+ accept("error", `Invalid value, must be between 0 and 1`, {
89
+ node,
90
+ property: "alpha"
91
+ });
92
+ }
93
+ }
94
+ if (isString(node.alpha)) {
95
+ const alpha = parseFloat(node.alpha);
96
+ if (alpha < 0 || alpha > 100) {
97
+ accept("error", `Invalid value, must be between 0% and 100%`, {
98
+ node,
99
+ property: "alpha"
100
+ });
101
+ }
102
+ }
103
+ return;
104
+ }
105
+ nonexhaustive(node);
106
+ };
107
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@likec4/language-server",
3
3
  "description": "LikeC4 Language Server",
4
- "version": "1.32.0",
4
+ "version": "1.32.1",
5
5
  "license": "MIT",
6
6
  "bugs": "https://github.com/likec4/likec4/issues",
7
7
  "homepage": "https://likec4.dev",
@@ -93,11 +93,11 @@
93
93
  },
94
94
  "devDependencies": {
95
95
  "@types/chroma-js": "^3.1.1",
96
- "@modelcontextprotocol/sdk": "^1.10.2",
96
+ "@modelcontextprotocol/sdk": "^1.12.1",
97
97
  "@msgpack/msgpack": "^3.1.1",
98
98
  "@smithy/util-base64": "^4.0.0",
99
99
  "@types/express": "^5.0.2",
100
- "@types/node": "^20.19.0",
100
+ "@types/node": "~20.19.0",
101
101
  "@types/picomatch": "^4.0.0",
102
102
  "@types/which": "^3.0.4",
103
103
  "chroma-js": "^3.1.2",
@@ -117,14 +117,14 @@
117
117
  "pretty-ms": "^9.2.0",
118
118
  "remeda": "^2.23.0",
119
119
  "strip-indent": "^4.0.0",
120
- "tsx": "~4.19.4",
120
+ "tsx": "~4.20.1",
121
121
  "turbo": "^2.5.4",
122
122
  "type-fest": "^4.41.0",
123
123
  "typescript": "^5.8.3",
124
124
  "ufo": "^1.6.1",
125
125
  "unbuild": "^3.5.0",
126
126
  "valibot": "^1.0.0",
127
- "vitest": "^3.2.3",
127
+ "vitest": "3.2.3",
128
128
  "vscode-jsonrpc": "8.2.0",
129
129
  "vscode-languageserver": "9.0.1",
130
130
  "vscode-languageserver-protocol": "3.17.5",
@@ -132,11 +132,11 @@
132
132
  "vscode-uri": "3.1.0",
133
133
  "which": "^5.0.0",
134
134
  "zod": "^3.24.3",
135
- "@likec4/core": "1.32.0",
136
- "@likec4/icons": "1.32.0",
137
- "@likec4/layouts": "1.32.0",
138
- "@likec4/log": "1.32.0",
139
- "@likec4/tsconfig": "1.32.0"
135
+ "@likec4/core": "1.32.1",
136
+ "@likec4/icons": "1.32.1",
137
+ "@likec4/layouts": "1.32.1",
138
+ "@likec4/tsconfig": "1.32.1",
139
+ "@likec4/log": "1.32.1"
140
140
  },
141
141
  "scripts": {
142
142
  "typecheck": "tsc -b --verbose",
@@ -148,7 +148,7 @@
148
148
  "generate": "langium generate && tsx scripts/generate-icons.ts",
149
149
  "dev": "run-p \"watch:*\"",
150
150
  "lint": "run -T eslint src/ --fix",
151
- "clean": "rm -r -f dist contrib",
151
+ "clean": "pnpm rimraf dist contrib lib src/generated src/generated-lib",
152
152
  "test": "vitest run --no-isolate",
153
153
  "test-dbg": "vitest run --no-isolate -t formating",
154
154
  "vitest:ui": "vitest --no-isolate --ui",