@likec4/language-server 1.40.0 → 1.42.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 (94) hide show
  1. package/browser/package.json +4 -0
  2. package/browser-worker/package.json +4 -0
  3. package/dist/LikeC4LanguageServices.d.ts +1 -1
  4. package/dist/LikeC4LanguageServices.mjs +3 -2
  5. package/dist/Rpc.mjs +30 -24
  6. package/dist/ast.d.ts +4 -9
  7. package/dist/ast.mjs +0 -10
  8. package/dist/bundled.mjs +4158 -3687
  9. package/dist/documentation/documentation-provider.mjs +1 -1
  10. package/dist/filesystem/FileSystemWatcher.d.ts +2 -2
  11. package/dist/filesystem/index.d.ts +1 -1
  12. package/dist/formatting/LikeC4Formatter.mjs +42 -10
  13. package/dist/formatting/utils.d.ts +3 -3
  14. package/dist/formatting/utils.mjs +1 -1
  15. package/dist/generated/ast.d.ts +40 -19
  16. package/dist/generated/ast.mjs +71 -26
  17. package/dist/generated/grammar.mjs +1 -1
  18. package/dist/logger.d.ts +1 -1
  19. package/dist/logger.mjs +3 -0
  20. package/dist/lsp/CompletionProvider.mjs +1 -1
  21. package/dist/lsp/DocumentLinkProvider.d.ts +1 -1
  22. package/dist/lsp/DocumentLinkProvider.mjs +1 -1
  23. package/dist/lsp/DocumentSymbolProvider.mjs +1 -1
  24. package/dist/lsp/HoverProvider.mjs +14 -2
  25. package/dist/mcp/NoopLikeC4MCPServer.d.ts +1 -1
  26. package/dist/mcp/NoopLikeC4MCPServer.mjs +1 -1
  27. package/dist/mcp/server/StdioLikeC4MCPServer.mjs +4 -1
  28. package/dist/mcp/server/StreamableLikeC4MCPServer.mjs +3 -3
  29. package/dist/mcp/server/WithMCPServer.mjs +2 -2
  30. package/dist/mcp/tools/_common.mjs +2 -2
  31. package/dist/model/builder/MergedSpecification.d.ts +3 -3
  32. package/dist/model/builder/MergedSpecification.mjs +37 -59
  33. package/dist/model/builder/buildModel.mjs +14 -17
  34. package/dist/model/model-builder.d.ts +1 -1
  35. package/dist/model/model-builder.mjs +12 -9
  36. package/dist/model/model-locator.d.ts +5 -0
  37. package/dist/model/model-locator.mjs +40 -3
  38. package/dist/model/model-parser-where.mjs +1 -2
  39. package/dist/model/model-parser.d.ts +91 -47
  40. package/dist/model/parser/Base.d.ts +13 -7
  41. package/dist/model/parser/Base.mjs +32 -21
  42. package/dist/model/parser/DeploymentModelParser.d.ts +9 -5
  43. package/dist/model/parser/DeploymentModelParser.mjs +49 -47
  44. package/dist/model/parser/DeploymentViewParser.d.ts +9 -5
  45. package/dist/model/parser/DeploymentViewParser.mjs +1 -2
  46. package/dist/model/parser/FqnRefParser.d.ts +12 -6
  47. package/dist/model/parser/FqnRefParser.mjs +28 -15
  48. package/dist/model/parser/GlobalsParser.d.ts +16 -7
  49. package/dist/model/parser/GlobalsParser.mjs +5 -3
  50. package/dist/model/parser/ImportsParser.d.ts +8 -5
  51. package/dist/model/parser/ImportsParser.mjs +4 -2
  52. package/dist/model/parser/ModelParser.d.ts +9 -5
  53. package/dist/model/parser/ModelParser.mjs +42 -42
  54. package/dist/model/parser/PredicatesParser.d.ts +9 -5
  55. package/dist/model/parser/SpecificationParser.d.ts +8 -5
  56. package/dist/model/parser/SpecificationParser.mjs +17 -23
  57. package/dist/model/parser/ValueConverter.mjs +1 -1
  58. package/dist/model/parser/ViewsParser.d.ts +20 -7
  59. package/dist/model/parser/ViewsParser.mjs +125 -35
  60. package/dist/model-change/ModelChanges.d.ts +1 -1
  61. package/dist/module.mjs +3 -2
  62. package/dist/protocol.d.ts +28 -4
  63. package/dist/references/scope-computation.mjs +2 -3
  64. package/dist/references/scope-provider.d.ts +2 -2
  65. package/dist/references/scope-provider.mjs +8 -15
  66. package/dist/test/testServices.d.ts +2 -0
  67. package/dist/test/testServices.mjs +32 -35
  68. package/dist/utils/disposable.mjs +2 -2
  69. package/dist/utils/index.mjs +1 -1
  70. package/dist/validation/_shared.d.ts +1 -1
  71. package/dist/validation/deployment-checks.d.ts +1 -1
  72. package/dist/validation/deployment-checks.mjs +4 -1
  73. package/dist/validation/dynamic-view.d.ts +3 -2
  74. package/dist/validation/dynamic-view.mjs +21 -2
  75. package/dist/validation/element-ref.d.ts +2 -2
  76. package/dist/validation/element-ref.mjs +1 -1
  77. package/dist/validation/imports.d.ts +0 -1
  78. package/dist/validation/imports.mjs +0 -5
  79. package/dist/validation/index.d.ts +1 -1
  80. package/dist/validation/index.mjs +19 -13
  81. package/dist/validation/view-predicates/relation-with.d.ts +1 -1
  82. package/dist/validation/view.d.ts +1 -1
  83. package/dist/view-utils/index.d.ts +0 -1
  84. package/dist/view-utils/index.mjs +0 -1
  85. package/dist/views/likec4-views.d.ts +6 -0
  86. package/dist/views/likec4-views.mjs +31 -18
  87. package/dist/workspace/ProjectsManager.d.ts +23 -31
  88. package/dist/workspace/ProjectsManager.mjs +78 -89
  89. package/dist/workspace/WorkspaceManager.mjs +1 -1
  90. package/likec4lib/package.json +4 -0
  91. package/package.json +25 -29
  92. package/protocol/package.json +4 -0
  93. package/dist/view-utils/resolve-relative-paths.d.ts +0 -2
  94. package/dist/view-utils/resolve-relative-paths.mjs +0 -78
@@ -20,6 +20,7 @@ export declare function DeploymentViewParser<TBase extends WithExpressionV2 & Wi
20
20
  parseFqnExpressions(astNode: ast.FqnExpressions): c4.FqnExpr[];
21
21
  parseRelationExprOrWith(astNode: ast.RelationExprOrWith): c4.RelationExpr.Any;
22
22
  parseRelationExprWith(astNode: ast.RelationExprWith): c4.RelationExpr.Custom;
23
+ parseCustomRelationProperties(custom: ast.CustomRelationProperties | undefined): import("type-fest").Except<c4.RelationExpr.Custom["customRelation"], "expr">;
23
24
  parseRelationExprOrWhere(astNode: ast.RelationExprOrWhere): c4.RelationExpr.OrWhere;
24
25
  parseRelationExprWhere(astNode: ast.RelationExprWhere): c4.RelationExpr.Where;
25
26
  parseRelationExpr(astNode: ast.RelationExpr): c4.RelationExpr.OrWhere;
@@ -48,16 +49,19 @@ export declare function DeploymentViewParser<TBase extends WithExpressionV2 & Wi
48
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
- parseTitleDescriptionTechnology(inlineProps: {
52
- title?: string | undefined;
53
- description?: string | undefined;
54
- technology?: string | undefined;
55
- }, bodyProps: {
52
+ parseBaseProps(props: {
56
53
  title?: ast.MarkdownOrString | undefined;
54
+ summary?: ast.MarkdownOrString | undefined;
57
55
  description?: ast.MarkdownOrString | undefined;
58
56
  technology?: ast.MarkdownOrString | undefined;
57
+ }, override?: {
58
+ title?: string | undefined;
59
+ summary?: string | undefined;
60
+ description?: string | undefined;
61
+ technology?: string | undefined;
59
62
  }): {
60
63
  title?: string;
64
+ summary?: c4.MarkdownOrString;
61
65
  description?: c4.MarkdownOrString;
62
66
  technology?: string;
63
67
  };
@@ -23,8 +23,7 @@ export function DeploymentViewParser(B) {
23
23
  const {
24
24
  title = null,
25
25
  description = null
26
- } = this.parseTitleDescriptionTechnology(
27
- {},
26
+ } = this.parseBaseProps(
28
27
  pipe(
29
28
  props,
30
29
  filter(ast.isViewStringProperty),
@@ -1,4 +1,6 @@
1
1
  import type * as c4 from '@likec4/core';
2
+ import { type AstNode } from 'langium';
3
+ import type { Except } from 'type-fest';
2
4
  import { ast } from '../../ast';
3
5
  import { type Base } from './Base';
4
6
  export type WithExpressionV2 = ReturnType<typeof ExpressionV2Parser>;
@@ -15,6 +17,7 @@ export declare function ExpressionV2Parser<TBase extends Base>(B: TBase): {
15
17
  parseFqnExpressions(astNode: ast.FqnExpressions): c4.FqnExpr[];
16
18
  parseRelationExprOrWith(astNode: ast.RelationExprOrWith): c4.RelationExpr.Any;
17
19
  parseRelationExprWith(astNode: ast.RelationExprWith): c4.RelationExpr.Custom;
20
+ parseCustomRelationProperties(custom: ast.CustomRelationProperties | undefined): Except<c4.RelationExpr.Custom["customRelation"], "expr">;
18
21
  parseRelationExprOrWhere(astNode: ast.RelationExprOrWhere): c4.RelationExpr.OrWhere;
19
22
  parseRelationExprWhere(astNode: ast.RelationExprWhere): c4.RelationExpr.Where;
20
23
  parseRelationExpr(astNode: ast.RelationExpr): c4.RelationExpr.OrWhere;
@@ -25,7 +28,7 @@ export declare function ExpressionV2Parser<TBase extends Base>(B: TBase): {
25
28
  readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
26
29
  get project(): import("../../workspace").Project;
27
30
  resolveFqn(node: ast.FqnReferenceable): c4.Fqn;
28
- getAstNodePath(node: c4): any;
31
+ getAstNodePath(node: AstNode): any;
29
32
  getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
30
33
  [key: string]: string;
31
34
  } | undefined;
@@ -43,16 +46,19 @@ export declare function ExpressionV2Parser<TBase extends Base>(B: TBase): {
43
46
  parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
44
47
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
45
48
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
46
- parseTitleDescriptionTechnology(inlineProps: {
47
- title?: string | undefined;
48
- description?: string | undefined;
49
- technology?: string | undefined;
50
- }, bodyProps: {
49
+ parseBaseProps(props: {
51
50
  title?: ast.MarkdownOrString | undefined;
51
+ summary?: ast.MarkdownOrString | undefined;
52
52
  description?: ast.MarkdownOrString | undefined;
53
53
  technology?: ast.MarkdownOrString | undefined;
54
+ }, override?: {
55
+ title?: string | undefined;
56
+ summary?: string | undefined;
57
+ description?: string | undefined;
58
+ technology?: string | undefined;
54
59
  }): {
55
60
  title?: string;
61
+ summary?: c4.MarkdownOrString;
56
62
  description?: c4.MarkdownOrString;
57
63
  technology?: string;
58
64
  };
@@ -1,17 +1,25 @@
1
1
  import { invariant, nonexhaustive, nonNullable } from "@likec4/core";
2
+ import { loggable } from "@likec4/log";
3
+ import { AstUtils } from "langium";
2
4
  import { isBoolean, isDefined, isNonNullish, isTruthy } from "remeda";
3
5
  import { ast, parseAstOpacityProperty, parseAstSizeValue, parseMarkdownAsString, toColor } from "../../ast.mjs";
4
- import { logWarnError } from "../../logger.mjs";
6
+ import { serverLogger } from "../../logger.mjs";
5
7
  import { projectIdFrom } from "../../utils/index.mjs";
6
8
  import { importsRef, instanceRef } from "../../utils/fqnRef.mjs";
7
9
  import { createBinaryOperator, parseWhereClause } from "../model-parser-where.mjs";
8
10
  import { removeIndent } from "./Base.mjs";
11
+ const logger = serverLogger.getChild("ExpressionV2Parser");
12
+ const location = (astNode) => {
13
+ const cst = astNode.$cstNode;
14
+ const position = cst ? `:${cst.range.start.line + 1}:${cst.range.start.character + 1}` : "";
15
+ return `${AstUtils.getDocument(astNode).uri.fsPath}${position}`;
16
+ };
9
17
  export function ExpressionV2Parser(B) {
10
18
  return class ExpressionV2Parser extends B {
11
19
  parseFqnRef(astNode) {
12
20
  const refValue = nonNullable(
13
21
  astNode.value?.ref,
14
- `FqnRef is empty ${astNode.$cstNode?.range.start.line}:${astNode.$cstNode?.range.start.character}`
22
+ () => `FqnRef "${astNode.$cstNode?.text}" is empty at ${location(astNode)}`
15
23
  );
16
24
  if (ast.isImported(refValue)) {
17
25
  const fqnRef = {
@@ -87,7 +95,7 @@ export function ExpressionV2Parser(B) {
87
95
  return acc;
88
96
  }
89
97
  if (ast.isElementStringProperty(prop)) {
90
- if (isDefined(prop.value)) {
98
+ if (isDefined(prop.value) && prop.key !== "summary") {
91
99
  if (prop.key === "description") {
92
100
  const parsed = this.parseMarkdownOrString(prop.value);
93
101
  if (parsed) {
@@ -248,7 +256,7 @@ export function ExpressionV2Parser(B) {
248
256
  exprs.push(this.parseFqnExpr(iter.value));
249
257
  }
250
258
  } catch (e) {
251
- logWarnError(e);
259
+ logger.warn(loggable(e));
252
260
  }
253
261
  iter = iter.prev;
254
262
  }
@@ -265,49 +273,54 @@ export function ExpressionV2Parser(B) {
265
273
  }
266
274
  parseRelationExprWith(astNode) {
267
275
  const expr = this.parseRelationExprOrWhere(astNode.subject);
268
- const props = astNode.custom?.props ?? [];
276
+ const customProps = this.parseCustomRelationProperties(astNode.custom);
277
+ return {
278
+ customRelation: {
279
+ ...customProps,
280
+ expr
281
+ }
282
+ };
283
+ }
284
+ parseCustomRelationProperties(custom) {
285
+ const props = custom?.props ?? [];
269
286
  return props.reduce(
270
287
  (acc, prop) => {
271
288
  if (ast.isRelationStringProperty(prop) || ast.isNotationProperty(prop) || ast.isNotesProperty(prop)) {
272
289
  const value = isTruthy(prop.value) ? removeIndent(parseMarkdownAsString(prop.value)) : void 0;
273
290
  if (value) {
274
- acc.customRelation[prop.key] = value;
291
+ acc[prop.key] = value;
275
292
  }
276
293
  return acc;
277
294
  }
278
295
  if (ast.isArrowProperty(prop)) {
279
296
  if (isTruthy(prop.value)) {
280
- acc.customRelation[prop.key] = prop.value;
297
+ acc[prop.key] = prop.value;
281
298
  }
282
299
  return acc;
283
300
  }
284
301
  if (ast.isColorProperty(prop)) {
285
302
  const value = toColor(prop);
286
303
  if (isTruthy(value)) {
287
- acc.customRelation[prop.key] = value;
304
+ acc[prop.key] = value;
288
305
  }
289
306
  return acc;
290
307
  }
291
308
  if (ast.isLineProperty(prop)) {
292
309
  if (isTruthy(prop.value)) {
293
- acc.customRelation[prop.key] = prop.value;
310
+ acc[prop.key] = prop.value;
294
311
  }
295
312
  return acc;
296
313
  }
297
314
  if (ast.isRelationNavigateToProperty(prop)) {
298
315
  const viewId = prop.value.view.ref?.name;
299
316
  if (isTruthy(viewId)) {
300
- acc.customRelation.navigateTo = viewId;
317
+ acc[prop.key] = viewId;
301
318
  }
302
319
  return acc;
303
320
  }
304
321
  nonexhaustive(prop);
305
322
  },
306
- {
307
- customRelation: {
308
- expr
309
- }
310
- }
323
+ {}
311
324
  );
312
325
  }
313
326
  parseRelationExprOrWhere(astNode) {
@@ -20,8 +20,13 @@ export declare function GlobalsParser<TBase extends WithViewsParser>(B: TBase):
20
20
  parseDynamicElementView(astNode: ast.DynamicView, additionalStyles: any[]): import("../../ast").ParsedAstDynamicView;
21
21
  parseDynamicViewRule(astRule: ast.DynamicViewRule): c4.DynamicViewRule;
22
22
  parseDynamicViewIncludePredicate(astRule: ast.DynamicViewIncludePredicate): c4.DynamicViewIncludeRule;
23
- parseDynamicParallelSteps(node: ast.DynamicViewParallelSteps): c4.DynamicViewParallelSteps;
24
- parseDynamicStep(node: ast.DynamicViewStep): c4.DynamicViewStep;
23
+ parseDynamicParallelSteps(node: ast.DynamicViewParallelSteps): c4.DynamicStepsParallel;
24
+ parseDynamicStep(node: ast.DynamicViewStep): c4.DynamicStep | c4.DynamicStepsSeries;
25
+ recursiveParseDynamicStepChain(node: ast.DynamicStepChain, callstack?: Array<[source: c4.Fqn, target: c4.Fqn]>): c4.DynamicStep[];
26
+ parseDynamicStepSingle(node: ast.DynamicStepSingle): c4.DynamicStep;
27
+ parseAbstractDynamicStep(astnode: ast.AbstractDynamicStep): import("type-fest").Writable<import("type-fest").Except<c4.DynamicStep, "source", {
28
+ requireExactProps: true;
29
+ }>>;
25
30
  parsePredicate(astNode: ast.ExpressionV2): c4.ModelExpression;
26
31
  parseElementPredicate(astNode: ast.FqnExprOrWith): c4.ModelFqnExpr.Any;
27
32
  parseElementPredicateOrWhere(astNode: ast.FqnExprOrWhere): c4.ModelFqnExpr.OrWhere;
@@ -44,6 +49,7 @@ export declare function GlobalsParser<TBase extends WithViewsParser>(B: TBase):
44
49
  parseFqnExpressions(astNode: ast.FqnExpressions): c4.FqnExpr[];
45
50
  parseRelationExprOrWith(astNode: ast.RelationExprOrWith): c4.RelationExpr.Any;
46
51
  parseRelationExprWith(astNode: ast.RelationExprWith): c4.RelationExpr.Custom;
52
+ parseCustomRelationProperties(custom: ast.CustomRelationProperties | undefined): import("type-fest").Except<c4.RelationExpr.Custom["customRelation"], "expr">;
47
53
  parseRelationExprOrWhere(astNode: ast.RelationExprOrWhere): c4.RelationExpr.OrWhere;
48
54
  parseRelationExprWhere(astNode: ast.RelationExprWhere): c4.RelationExpr.Where;
49
55
  parseRelationExpr(astNode: ast.RelationExpr): c4.RelationExpr.OrWhere;
@@ -72,16 +78,19 @@ export declare function GlobalsParser<TBase extends WithViewsParser>(B: TBase):
72
78
  parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
73
79
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
74
80
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
75
- parseTitleDescriptionTechnology(inlineProps: {
76
- title?: string | undefined;
77
- description?: string | undefined;
78
- technology?: string | undefined;
79
- }, bodyProps: {
81
+ parseBaseProps(props: {
80
82
  title?: ast.MarkdownOrString | undefined;
83
+ summary?: ast.MarkdownOrString | undefined;
81
84
  description?: ast.MarkdownOrString | undefined;
82
85
  technology?: ast.MarkdownOrString | undefined;
86
+ }, override?: {
87
+ title?: string | undefined;
88
+ summary?: string | undefined;
89
+ description?: string | undefined;
90
+ technology?: string | undefined;
83
91
  }): {
84
92
  title?: string;
93
+ summary?: c4.MarkdownOrString;
85
94
  description?: c4.MarkdownOrString;
86
95
  technology?: string;
87
96
  };
@@ -1,7 +1,9 @@
1
1
  import { nonexhaustive } from "@likec4/core";
2
+ import { loggable } from "@likec4/log";
2
3
  import { hasAtLeast, isTruthy } from "remeda";
3
4
  import { ast } from "../../ast.mjs";
4
- import { logger, logWarnError } from "../../logger.mjs";
5
+ import { serverLogger } from "../../logger.mjs";
6
+ const logger = serverLogger.getChild("GlobalsParser");
5
7
  export function GlobalsParser(B) {
6
8
  return class GlobalsParser extends B {
7
9
  parseGlobals() {
@@ -21,7 +23,7 @@ export function GlobalsParser(B) {
21
23
  }
22
24
  this.parseAndStoreGlobalPredicateGroupOrDynamic(predicate, globalPredicateId, c4Globals);
23
25
  } catch (e) {
24
- logWarnError(e);
26
+ logger.warn(loggable(e));
25
27
  }
26
28
  }
27
29
  const styles = globals.flatMap((r) => r.styles.filter(isValid));
@@ -40,7 +42,7 @@ export function GlobalsParser(B) {
40
42
  c4Globals.styles[globalStyleId] = styles2;
41
43
  }
42
44
  } catch (e) {
43
- logWarnError(e);
45
+ logger.warn(loggable(e));
44
46
  }
45
47
  }
46
48
  }
@@ -27,16 +27,19 @@ export declare function ImportsParser<TBase extends Base>(B: TBase): {
27
27
  parseColorLiteral(astNode: ast.ColorLiteral): ProjectId | undefined;
28
28
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
29
29
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
30
- parseTitleDescriptionTechnology(inlineProps: {
31
- title?: string | undefined;
32
- description?: string | undefined;
33
- technology?: string | undefined;
34
- }, bodyProps: {
30
+ parseBaseProps(props: {
35
31
  title?: ast.MarkdownOrString | undefined;
32
+ summary?: ast.MarkdownOrString | undefined;
36
33
  description?: ast.MarkdownOrString | undefined;
37
34
  technology?: ast.MarkdownOrString | undefined;
35
+ }, override?: {
36
+ title?: string | undefined;
37
+ summary?: string | undefined;
38
+ description?: string | undefined;
39
+ technology?: string | undefined;
38
40
  }): {
39
41
  title?: string;
42
+ summary?: ProjectId;
40
43
  description?: ProjectId;
41
44
  technology?: string;
42
45
  };
@@ -1,5 +1,7 @@
1
1
  import { nonNullable } from "@likec4/core";
2
- import { logWarnError } from "../../logger.mjs";
2
+ import { loggable } from "@likec4/log";
3
+ import { serverLogger } from "../../logger.mjs";
4
+ const logger = serverLogger.getChild("ImportsParser");
3
5
  export function ImportsParser(B) {
4
6
  return class ImportsParser extends B {
5
7
  parseImports() {
@@ -16,7 +18,7 @@ export function ImportsParser(B) {
16
18
  )
17
19
  );
18
20
  } catch (e) {
19
- logWarnError(e);
21
+ logger.warn(loggable(e));
20
22
  }
21
23
  imported = imported.prev;
22
24
  }
@@ -21,6 +21,7 @@ export declare function ModelParser<TBase extends WithExpressionV2>(B: TBase): {
21
21
  parseFqnExpressions(astNode: ast.FqnExpressions): c4.FqnExpr[];
22
22
  parseRelationExprOrWith(astNode: ast.RelationExprOrWith): c4.RelationExpr.Any;
23
23
  parseRelationExprWith(astNode: ast.RelationExprWith): c4.RelationExpr.Custom;
24
+ parseCustomRelationProperties(custom: ast.CustomRelationProperties | undefined): import("type-fest").Except<c4.RelationExpr.Custom["customRelation"], "expr">;
24
25
  parseRelationExprOrWhere(astNode: ast.RelationExprOrWhere): c4.RelationExpr.OrWhere;
25
26
  parseRelationExprWhere(astNode: ast.RelationExprWhere): c4.RelationExpr.Where;
26
27
  parseRelationExpr(astNode: ast.RelationExpr): c4.RelationExpr.OrWhere;
@@ -49,16 +50,19 @@ export declare function ModelParser<TBase extends WithExpressionV2>(B: TBase): {
49
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
- parseTitleDescriptionTechnology(inlineProps: {
53
- title?: string | undefined;
54
- description?: string | undefined;
55
- technology?: string | undefined;
56
- }, bodyProps: {
53
+ parseBaseProps(props: {
57
54
  title?: ast.MarkdownOrString | undefined;
55
+ summary?: ast.MarkdownOrString | undefined;
58
56
  description?: ast.MarkdownOrString | undefined;
59
57
  technology?: ast.MarkdownOrString | undefined;
58
+ }, override?: {
59
+ title?: string | undefined;
60
+ summary?: string | undefined;
61
+ description?: string | undefined;
62
+ technology?: string | undefined;
60
63
  }): {
61
64
  title?: string;
65
+ summary?: c4.MarkdownOrString;
62
66
  description?: c4.MarkdownOrString;
63
67
  technology?: string;
64
68
  };
@@ -1,10 +1,10 @@
1
1
  import { invariant, isNonEmptyArray, LinkedList, nonexhaustive, nonNullable } from "@likec4/core";
2
- import { FqnRef } from "@likec4/core/types";
2
+ import { exact, FqnRef } from "@likec4/core/types";
3
3
  import { loggable } from "@likec4/log";
4
4
  import { filter, first, isDefined, isEmpty, isTruthy, map, mapToObj, pipe } from "remeda";
5
5
  import {
6
6
  ast,
7
- toRelationshipStyleExcludeDefaults
7
+ toRelationshipStyle
8
8
  } from "../../ast.mjs";
9
9
  import { logger as mainLogger } from "../../logger.mjs";
10
10
  import { stringHash } from "../../utils/stringHash.mjs";
@@ -75,33 +75,30 @@ ${error}`, {
75
75
  const style = this.parseElementStyle(astNode.body?.props);
76
76
  const metadata = this.getMetadata(astNode.body?.props.find(ast.isMetadataProperty));
77
77
  const astPath = this.getAstNodePath(astNode);
78
- let [_title, _description, _technology] = astNode.props ?? [];
78
+ let [_title, _summary, _technology] = astNode.props ?? [];
79
79
  const bodyProps = pipe(
80
80
  astNode.body?.props ?? [],
81
81
  filter(isValid),
82
82
  filter(ast.isElementStringProperty),
83
83
  mapToObj((p) => [p.key, p.value])
84
84
  );
85
- const { title, ...descAndTech } = this.parseTitleDescriptionTechnology(
86
- {
87
- title: _title,
88
- description: _description,
89
- technology: _technology
90
- },
91
- bodyProps
92
- );
85
+ const { title, ...descAndTech } = this.parseBaseProps(bodyProps, {
86
+ title: _title,
87
+ summary: _summary,
88
+ technology: _technology
89
+ });
93
90
  const links = this.parseLinks(astNode.body);
94
- return {
91
+ return exact({
95
92
  id,
96
93
  kind,
97
94
  astPath,
98
95
  title: title ?? astNode.name,
99
- ...metadata && { metadata },
100
- ...tags && { tags },
96
+ metadata,
97
+ tags: tags ?? void 0,
101
98
  ...links && isNonEmptyArray(links) && { links },
102
99
  ...descAndTech,
103
100
  style
104
- };
101
+ });
105
102
  }
106
103
  parseExtendElement(astNode) {
107
104
  const id = this.resolveFqn(astNode);
@@ -112,13 +109,13 @@ ${error}`, {
112
109
  if (!tags && isEmpty(metadata ?? {}) && isEmpty(links)) {
113
110
  return null;
114
111
  }
115
- return {
112
+ return exact({
116
113
  id,
117
114
  astPath,
118
- ...metadata && { metadata },
119
- ...tags && { tags },
120
- ...links && isNonEmptyArray(links) && { links }
121
- };
115
+ metadata,
116
+ tags,
117
+ links: isNonEmptyArray(links) ? links : null
118
+ });
122
119
  }
123
120
  _resolveRelationSource(node) {
124
121
  if (isDefined(node.source)) {
@@ -126,12 +123,17 @@ ${error}`, {
126
123
  invariant(FqnRef.isModelRef(source) || FqnRef.isImportRef(source), "Relation source must be a model reference");
127
124
  return source;
128
125
  }
129
- if (!ast.isElementBody(node.$container)) {
130
- throw new Error("RelationRefError: Invalid container for sourceless relation");
126
+ if (ast.isElementBody(node.$container)) {
127
+ return {
128
+ model: this.resolveFqn(node.$container.$container)
129
+ };
130
+ }
131
+ if (ast.isExtendElementBody(node.$container)) {
132
+ return {
133
+ model: this.resolveFqn(node.$container.$container)
134
+ };
131
135
  }
132
- return {
133
- model: this.resolveFqn(node.$container.$container)
134
- };
136
+ throw new Error("RelationRefError: Invalid container for sourceless relation");
135
137
  }
136
138
  parseRelation(astNode) {
137
139
  const isValid = this.isValid;
@@ -156,35 +158,33 @@ ${error}`, {
156
158
  filter(isTruthy),
157
159
  first()
158
160
  );
159
- const { title = "", ...descAndTech } = this.parseTitleDescriptionTechnology(
161
+ const { title = "", description, technology } = this.parseBaseProps(bodyProps, {
160
162
  // inline props
161
- {
162
- title: astNode.title,
163
- description: astNode.description,
164
- technology: astNode.technology
165
- },
166
- bodyProps
167
- );
163
+ title: astNode.title,
164
+ description: astNode.description,
165
+ technology: astNode.technology
166
+ });
168
167
  const styleProp = astNode.body?.props.find(ast.isRelationStyleProperty);
169
168
  const id = stringHash(
170
169
  astPath,
171
170
  source.model,
172
171
  target.model
173
172
  );
174
- return {
173
+ return exact({
175
174
  id,
176
175
  astPath,
177
176
  source,
178
177
  target,
179
178
  title,
180
- ...metadata && { metadata },
181
- ...descAndTech,
182
- ...kind && { kind },
183
- ...tags && { tags },
184
- ...isNonEmptyArray(links) && { links },
185
- ...toRelationshipStyleExcludeDefaults(styleProp?.props, isValid),
186
- ...navigateTo && { navigateTo }
187
- };
179
+ metadata,
180
+ kind,
181
+ tags: tags ?? void 0,
182
+ links: isNonEmptyArray(links) ? links : void 0,
183
+ navigateTo: navigateTo ? navigateTo : void 0,
184
+ description,
185
+ technology,
186
+ ...toRelationshipStyle(styleProp?.props, isValid)
187
+ });
188
188
  }
189
189
  };
190
190
  }
@@ -26,6 +26,7 @@ export declare function PredicatesParser<TBase extends WithExpressionV2>(B: TBas
26
26
  parseFqnExpressions(astNode: ast.FqnExpressions): c4.FqnExpr[];
27
27
  parseRelationExprOrWith(astNode: ast.RelationExprOrWith): c4.RelationExpr.Any;
28
28
  parseRelationExprWith(astNode: ast.RelationExprWith): c4.RelationExpr.Custom;
29
+ parseCustomRelationProperties(custom: ast.CustomRelationProperties | undefined): import("type-fest").Except<c4.RelationExpr.Custom["customRelation"], "expr">;
29
30
  parseRelationExprOrWhere(astNode: ast.RelationExprOrWhere): c4.RelationExpr.OrWhere;
30
31
  parseRelationExprWhere(astNode: ast.RelationExprWhere): c4.RelationExpr.Where;
31
32
  parseRelationExpr(astNode: ast.RelationExpr): c4.RelationExpr.OrWhere;
@@ -54,16 +55,19 @@ export declare function PredicatesParser<TBase extends WithExpressionV2>(B: TBas
54
55
  parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
55
56
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
56
57
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
57
- parseTitleDescriptionTechnology(inlineProps: {
58
- title?: string | undefined;
59
- description?: string | undefined;
60
- technology?: string | undefined;
61
- }, bodyProps: {
58
+ parseBaseProps(props: {
62
59
  title?: ast.MarkdownOrString | undefined;
60
+ summary?: ast.MarkdownOrString | undefined;
63
61
  description?: ast.MarkdownOrString | undefined;
64
62
  technology?: ast.MarkdownOrString | undefined;
63
+ }, override?: {
64
+ title?: string | undefined;
65
+ summary?: string | undefined;
66
+ description?: string | undefined;
67
+ technology?: string | undefined;
65
68
  }): {
66
69
  title?: string;
70
+ summary?: c4.MarkdownOrString;
67
71
  description?: c4.MarkdownOrString;
68
72
  technology?: string;
69
73
  };
@@ -33,16 +33,19 @@ export declare function SpecificationParser<TBase extends Base>(B: TBase): {
33
33
  parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
34
34
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
35
35
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
36
- parseTitleDescriptionTechnology(inlineProps: {
37
- title?: string | undefined;
38
- description?: string | undefined;
39
- technology?: string | undefined;
40
- }, bodyProps: {
36
+ parseBaseProps(props: {
41
37
  title?: ast.MarkdownOrString | undefined;
38
+ summary?: ast.MarkdownOrString | undefined;
42
39
  description?: ast.MarkdownOrString | undefined;
43
40
  technology?: ast.MarkdownOrString | undefined;
41
+ }, override?: {
42
+ title?: string | undefined;
43
+ summary?: string | undefined;
44
+ description?: string | undefined;
45
+ technology?: string | undefined;
44
46
  }): {
45
47
  title?: string;
48
+ summary?: c4.MarkdownOrString;
46
49
  description?: c4.MarkdownOrString;
47
50
  technology?: string;
48
51
  };