@likec4/language-server 1.32.1 → 1.33.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 (51) hide show
  1. package/dist/ast.d.ts +6 -5
  2. package/dist/ast.js +3 -0
  3. package/dist/bundled.mjs +3347 -2559
  4. package/dist/config/schema.d.ts +2 -2
  5. package/dist/config/schema.js +8 -11
  6. package/dist/formatting/LikeC4Formatter.js +2 -2
  7. package/dist/generated/ast.d.ts +22 -11
  8. package/dist/generated/ast.js +19 -5
  9. package/dist/generated/grammar.js +1 -1
  10. package/dist/lsp/SemanticTokenProvider.js +1 -1
  11. package/dist/mcp/LikeC4MCPServerFactory.d.ts +4 -0
  12. package/dist/mcp/LikeC4MCPServerFactory.js +6 -0
  13. package/dist/mcp/LikeC4MCPTools.js +5 -2
  14. package/dist/mcp/sseserver/MCPServer.d.ts +4 -2
  15. package/dist/mcp/sseserver/MCPServer.js +12 -6
  16. package/dist/mcp/sseserver/with-mcp-server.js +22 -6
  17. package/dist/model/builder/MergedSpecification.js +8 -4
  18. package/dist/model/index.d.ts +1 -0
  19. package/dist/model/index.js +1 -0
  20. package/dist/model/model-builder.js +20 -19
  21. package/dist/model/model-parser.d.ts +126 -0
  22. package/dist/model/parser/Base.d.ts +30 -2
  23. package/dist/model/parser/Base.js +54 -3
  24. package/dist/model/parser/DeploymentModelParser.d.ts +14 -0
  25. package/dist/model/parser/DeploymentModelParser.js +28 -23
  26. package/dist/model/parser/DeploymentViewParser.d.ts +14 -0
  27. package/dist/model/parser/DeploymentViewParser.js +15 -6
  28. package/dist/model/parser/FqnRefParser.d.ts +14 -0
  29. package/dist/model/parser/FqnRefParser.js +8 -6
  30. package/dist/model/parser/GlobalsParser.d.ts +14 -0
  31. package/dist/model/parser/ImportsParser.d.ts +14 -0
  32. package/dist/model/parser/ModelParser.d.ts +14 -0
  33. package/dist/model/parser/ModelParser.js +27 -17
  34. package/dist/model/parser/PredicatesParser.d.ts +14 -0
  35. package/dist/model/parser/SpecificationParser.d.ts +14 -0
  36. package/dist/model/parser/SpecificationParser.js +16 -11
  37. package/dist/model/parser/ValueConverter.d.ts +4 -0
  38. package/dist/model/parser/ValueConverter.js +12 -0
  39. package/dist/model/parser/ViewsParser.d.ts +14 -0
  40. package/dist/model/parser/ViewsParser.js +21 -7
  41. package/dist/module.d.ts +6 -3
  42. package/dist/module.js +9 -5
  43. package/dist/utils/index.d.ts +5 -0
  44. package/dist/utils/index.js +19 -0
  45. package/dist/views/configurable-layouter.d.ts +2 -2
  46. package/dist/views/configurable-layouter.js +23 -27
  47. package/dist/views/likec4-views.d.ts +2 -3
  48. package/dist/views/likec4-views.js +28 -50
  49. package/dist/workspace/ProjectsManager.d.ts +0 -1
  50. package/dist/workspace/ProjectsManager.js +15 -4
  51. package/package.json +24 -23
@@ -272,7 +272,7 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
272
272
  });
273
273
  return "prune";
274
274
  }
275
- if ("value" in node && node.value) {
275
+ if ("value" in node && node.value && !ast.isStringProperty(node)) {
276
276
  acceptor({
277
277
  node,
278
278
  property: "value",
@@ -2,6 +2,8 @@ import type { ServerOptions } from '@modelcontextprotocol/sdk/server/index.js';
2
2
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import type { LikeC4Services } from '../module';
4
4
  export interface LikeC4MCPServer {
5
+ readonly isStarted: boolean;
6
+ readonly port: number;
5
7
  start(port: number): Promise<void>;
6
8
  stop(): Promise<void>;
7
9
  }
@@ -9,6 +11,8 @@ export interface LikeC4MCPServerFactory {
9
11
  create(options?: ServerOptions): McpServer;
10
12
  }
11
13
  export declare class NoopLikeC4MCPServer implements LikeC4MCPServer {
14
+ get isStarted(): boolean;
15
+ get port(): number;
12
16
  start(port: number): Promise<never>;
13
17
  stop(): Promise<never>;
14
18
  }
@@ -1,4 +1,10 @@
1
1
  export class NoopLikeC4MCPServer {
2
+ get isStarted() {
3
+ return false;
4
+ }
5
+ get port() {
6
+ return NaN;
7
+ }
2
8
  start(port) {
3
9
  return Promise.reject(new Error("Not implemented"));
4
10
  }
@@ -1,4 +1,4 @@
1
- import { _type } from "@likec4/core";
1
+ import { _type, RichText } from "@likec4/core";
2
2
  import { loggable } from "@likec4/log";
3
3
  import { flatMap } from "remeda";
4
4
  import stripIndent from "strip-indent";
@@ -9,7 +9,10 @@ import { ProjectsManager } from "../workspace/ProjectsManager.js";
9
9
  import { elementResource, modelViewResource } from "./utils.js";
10
10
  const logger = mainLogger.getChild("LikeC4MCPServices");
11
11
  function singleLine(str) {
12
- const res = toSingleLine(str)?.replaceAll('"', "'");
12
+ if (str === null || str === void 0) {
13
+ return "null";
14
+ }
15
+ const res = toSingleLine(RichText.from(str).text)?.replaceAll('"', "'");
13
16
  return res ? `"${res}"` : "null";
14
17
  }
15
18
  function outputEach(iterator, ifEmpty, output) {
@@ -3,10 +3,12 @@ import type { LikeC4Services } from '../../module';
3
3
  import type { LikeC4MCPServer } from '../LikeC4MCPServerFactory';
4
4
  export declare class SSELikeC4MCPServer implements LikeC4MCPServer, AsyncDisposable {
5
5
  private services;
6
- private readonly transports;
6
+ private transports;
7
7
  private server;
8
- private port;
8
+ private _port;
9
9
  constructor(services: LikeC4Services);
10
+ get isStarted(): boolean;
11
+ get port(): number;
10
12
  dispose(): Promise<void>;
11
13
  start(port?: number): Promise<void>;
12
14
  stop(): Promise<void>;
@@ -9,7 +9,13 @@ export class SSELikeC4MCPServer {
9
9
  // Store transports by session ID to send notifications
10
10
  transports = {};
11
11
  server = void 0;
12
- port = 33335;
12
+ _port = 33335;
13
+ get isStarted() {
14
+ return this.server?.listening === true;
15
+ }
16
+ get port() {
17
+ return this._port;
18
+ }
13
19
  async dispose() {
14
20
  await this.stop();
15
21
  }
@@ -20,8 +26,8 @@ export class SSELikeC4MCPServer {
20
26
  }
21
27
  await this.stop();
22
28
  }
23
- logger.info("Starting server on port {port}", { port });
24
- this.port = port;
29
+ logger.info("Starting MCP server on port {port}", { port });
30
+ this._port = port;
25
31
  const mcp = this.services.mcp.ServerFactory.create();
26
32
  const app = express();
27
33
  app.get("/sse", async (_, res) => {
@@ -44,13 +50,12 @@ export class SSELikeC4MCPServer {
44
50
  }
45
51
  });
46
52
  return new Promise((resolve, reject) => {
47
- this.server = app.listen(port, (err) => {
53
+ this.server = app.listen(this._port, (err) => {
48
54
  if (err) {
49
- logger.error("Failed to start server", { err });
50
55
  reject(err);
51
56
  return;
52
57
  }
53
- logger.info("server listening on port {port}", { port });
58
+ logger.info("MCP server listening on port {port}", { port: this._port });
54
59
  resolve();
55
60
  });
56
61
  });
@@ -62,6 +67,7 @@ export class SSELikeC4MCPServer {
62
67
  }
63
68
  logger.info("Stopping server");
64
69
  this.server = void 0;
70
+ this.transports = {};
65
71
  return new Promise((resolve) => {
66
72
  server.close((err) => {
67
73
  if (err) {
@@ -1,3 +1,5 @@
1
+ import { loggable } from "@likec4/log";
2
+ import { isError } from "remeda";
1
3
  import { logger } from "../../logger.js";
2
4
  import { SSELikeC4MCPServer } from "./MCPServer.js";
3
5
  import { LikeC4MCPServerFactory } from "./MCPServerFactory.js";
@@ -14,19 +16,33 @@ export const WithMCPServer = {
14
16
  return;
15
17
  }
16
18
  logger.debug("Configuration update: {update}", { update });
17
- const { enabled, port } = update.configuration.mcp ?? {
18
- enabled: false,
19
- port: 33335
20
- };
19
+ const {
20
+ enabled = false,
21
+ port = 33335
22
+ } = update.configuration.mcp;
21
23
  if (!enabled) {
22
24
  server.stop();
23
25
  return;
24
26
  }
25
27
  Promise.resolve().then(() => server.start(port)).then(() => {
26
28
  connection?.telemetry?.logEvent({
27
- eventName: "mcp-server-started"
29
+ eventName: "mcp-server-started",
30
+ mcpPort: port
28
31
  });
29
- }).catch((err) => logger.error("Failed to start LikeC4 MCP Server", { err }));
32
+ }).catch((err) => {
33
+ const message = isError(err) ? err.message : void 0;
34
+ connection?.telemetry?.logEvent({
35
+ eventName: "mcp-server-start-failed",
36
+ mcpPort: port,
37
+ ...message && { message }
38
+ });
39
+ logger.error("Failed to start LikeC4 MCP Server", { err });
40
+ if (connection) {
41
+ connection.window.showErrorMessage(`LikeC4: Failed to start MCP Server
42
+
43
+ ${loggable(err)}`);
44
+ }
45
+ });
30
46
  });
31
47
  return server;
32
48
  },
@@ -102,8 +102,8 @@ export class MergedSpecification {
102
102
  },
103
103
  links: links ?? null,
104
104
  tags: tags ?? [],
105
- technology: technology ?? null,
106
- description: description ?? null,
105
+ ...technology && { technology },
106
+ ...description && { description },
107
107
  title,
108
108
  kind,
109
109
  id
@@ -155,6 +155,7 @@ export class MergedSpecification {
155
155
  };
156
156
  }
157
157
  if ("element" in parsed) {
158
+ logger.warn`Invalid ParsedAstDeployment ${parsed.id}, has both element and kind properties`;
158
159
  return null;
159
160
  }
160
161
  try {
@@ -166,10 +167,13 @@ export class MergedSpecification {
166
167
  let {
167
168
  technology = __kind.technology,
168
169
  notation = __kind.notation,
169
- style
170
+ style,
171
+ description,
172
+ ...rest
170
173
  } = parsed;
171
174
  return {
172
- ...parsed,
175
+ ...rest,
176
+ ...description && { description },
173
177
  ...notation && { notation },
174
178
  ...technology && { technology },
175
179
  style: {
@@ -3,3 +3,4 @@ export * from './fqn-index';
3
3
  export * from './model-builder';
4
4
  export * from './model-locator';
5
5
  export * from './model-parser';
6
+ export * from './parser/ValueConverter';
@@ -3,3 +3,4 @@ export * from "./fqn-index.js";
3
3
  export * from "./model-builder.js";
4
4
  export * from "./model-locator.js";
5
5
  export * from "./model-parser.js";
6
+ export * from "./parser/ValueConverter.js";
@@ -11,7 +11,6 @@ import {
11
11
  DocumentState,
12
12
  interruptAndCheck
13
13
  } from "langium";
14
- import prettyMs from "pretty-ms";
15
14
  import {
16
15
  filter,
17
16
  flatMap,
@@ -26,13 +25,13 @@ import {
26
25
  import { CancellationToken } from "vscode-jsonrpc";
27
26
  import { isLikeC4Builtin } from "../likec4lib.js";
28
27
  import { logger as mainLogger, logWarnError } from "../logger.js";
29
- import { ADisposable } from "../utils/index.js";
28
+ import { ADisposable, performanceMark } from "../utils/index.js";
30
29
  import { assignNavigateTo } from "../view-utils/index.js";
31
30
  import { buildModelData } from "./builder/buildModel.js";
32
31
  const parsedWithoutImportsCacheKey = (projectId) => `parsed-without-imports-${projectId}`;
33
32
  const parsedModelCacheKey = (projectId) => `parsed-model-${projectId}`;
34
33
  const computedModelCacheKey = (projectId) => `computed-model-${projectId}`;
35
- const logger = mainLogger.getChild("ModelBuilder");
34
+ const builderLogger = mainLogger.getChild("model-builder");
36
35
  export class DefaultLikeC4ModelBuilder extends ADisposable {
37
36
  projects;
38
37
  parser;
@@ -65,7 +64,7 @@ export class DefaultLikeC4ModelBuilder extends ADisposable {
65
64
  }
66
65
  )
67
66
  );
68
- logger.debug`created`;
67
+ builderLogger.debug`created`;
69
68
  }
70
69
  /**
71
70
  * WARNING:
@@ -76,19 +75,19 @@ export class DefaultLikeC4ModelBuilder extends ADisposable {
76
75
  */
77
76
  unsafeSyncParseModelData(projectId) {
78
77
  const cache = this.cache;
79
- const log = logger.getChild(["project", projectId]);
78
+ const logger = builderLogger.getChild(projectId);
80
79
  const key = parsedWithoutImportsCacheKey(projectId);
81
80
  if (cache.has(key)) {
82
- log.debug`unsafeSyncBuildModelData from cache, project ${projectId}`;
81
+ logger.debug`unsafeSyncBuildModelData from cache`;
83
82
  }
84
83
  return cache.get(key, () => {
85
84
  try {
86
85
  const docs = this.documents(projectId);
87
86
  if (docs.length === 0) {
88
- logger.debug`no documents to build model, project ${projectId}`;
87
+ logger.debug`no documents to build model`;
89
88
  return null;
90
89
  }
91
- log.debug`unsafeSyncBuildModelData, project ${projectId}`;
90
+ logger.debug`unsafeSyncBuildModelData`;
92
91
  return buildModelData(projectId, docs);
93
92
  } catch (e) {
94
93
  logWarnError(e);
@@ -100,6 +99,7 @@ export class DefaultLikeC4ModelBuilder extends ADisposable {
100
99
  * To avoid circular dependencies, first we parse all documents and then we join them.
101
100
  */
102
101
  unsafeSyncJoinedModelData(projectId) {
102
+ const logger = builderLogger.getChild(projectId);
103
103
  const cache = this.cache;
104
104
  const key = parsedModelCacheKey(projectId);
105
105
  return cache.get(key, () => {
@@ -133,18 +133,18 @@ export class DefaultLikeC4ModelBuilder extends ADisposable {
133
133
  }
134
134
  async parseModel(projectId, cancelToken = CancellationToken.None) {
135
135
  const project = this.projects.ensureProjectId(projectId);
136
- const log = logger.getChild(["project", project]);
136
+ const logger = builderLogger.getChild(project);
137
137
  const cache = this.cache;
138
138
  const cached = cache.get(parsedModelCacheKey(project));
139
139
  if (cached) {
140
- log.debug`parseModel from cache, project ${project}`;
140
+ logger.debug`parseModel from cache`;
141
141
  return cached;
142
142
  }
143
- const t0 = performance.now();
143
+ const t0 = performanceMark();
144
144
  return await this.mutex.read(async () => {
145
145
  await interruptAndCheck(cancelToken);
146
146
  const result = this.unsafeSyncJoinedModelData(project);
147
- log.debug(`parseModel, project ${project} in ${prettyMs(performance.now() - t0)}`);
147
+ logger.debug`parseModel in ${t0.pretty}`;
148
148
  return result;
149
149
  });
150
150
  }
@@ -155,6 +155,7 @@ export class DefaultLikeC4ModelBuilder extends ADisposable {
155
155
  * Otherwise, the model may be incomplete.
156
156
  */
157
157
  unsafeSyncBuildModel(projectId) {
158
+ const logger = builderLogger.getChild(projectId);
158
159
  const cache = this.cache;
159
160
  const viewsCache = this.cache;
160
161
  return cache.get(computedModelCacheKey(projectId), () => {
@@ -189,24 +190,24 @@ export class DefaultLikeC4ModelBuilder extends ADisposable {
189
190
  }
190
191
  async buildLikeC4Model(projectId, cancelToken = CancellationToken.None) {
191
192
  const project = this.projects.ensureProjectId(projectId);
192
- const log = logger.getChild(["project", project]);
193
+ const logger = builderLogger.getChild(project);
193
194
  const cache = this.cache;
194
195
  const cached = cache.get(computedModelCacheKey(project));
195
196
  if (cached) {
196
- log.debug("buildLikeC4Model from cache");
197
+ logger.debug("buildLikeC4Model from cache");
197
198
  return cached;
198
199
  }
199
- const t0 = performance.now();
200
+ const t0 = performanceMark();
200
201
  return await this.mutex.read(async () => {
201
202
  await interruptAndCheck(cancelToken);
202
203
  const result = this.unsafeSyncBuildModel(project);
203
- log.debug(`buildLikeC4Model in ${prettyMs(performance.now() - t0)}`);
204
+ logger.debug(`buildLikeC4Model in ${t0.pretty}`);
204
205
  return result;
205
206
  });
206
207
  }
207
208
  async computeView(viewId, projectId, cancelToken = CancellationToken.None) {
208
209
  const project = this.projects.ensureProjectId(projectId);
209
- const log = logger.getChild(["project", project]);
210
+ const logger = builderLogger.getChild(project);
210
211
  const cache = this.cache;
211
212
  const cacheKey = computedViewKey(project, viewId);
212
213
  if (cache.has(cacheKey)) {
@@ -219,10 +220,10 @@ export class DefaultLikeC4ModelBuilder extends ADisposable {
219
220
  return cache.get(cacheKey, () => {
220
221
  const view = parsed.$data.views[viewId];
221
222
  if (!view) {
222
- log.warn`computeView: cant find view ${viewId}`;
223
+ logger.warn`computeView: cant find view ${viewId}`;
223
224
  return null;
224
225
  }
225
- log.debug`computeView: ${viewId}`;
226
+ logger.debug`computeView: ${viewId}`;
226
227
  const result = computeView(view, parsed);
227
228
  if (!result.isSuccess) {
228
229
  logWarnError(result.error);
@@ -63,6 +63,7 @@ declare const DocumentParserFromMixins: {
63
63
  getMetadata(metadataAstNode: import("../generated/ast").MetadataProperty | undefined): {
64
64
  [key: string]: string;
65
65
  } | undefined;
66
+ parseMarkdownOrString(markdownOrString: import("../generated/ast").MarkdownOrString | undefined): ProjectId | undefined;
66
67
  convertTags<E extends {
67
68
  tags?: import("../generated/ast").Tags;
68
69
  }>(withTags?: E | undefined): any;
@@ -75,6 +76,19 @@ declare const DocumentParserFromMixins: {
75
76
  parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
76
77
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
77
78
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
79
+ parseTitleDescriptionTechnology(inlineProps: {
80
+ title?: string | undefined;
81
+ description?: string | undefined;
82
+ technology?: string | undefined;
83
+ }, bodyProps: {
84
+ title?: import("../generated/ast").MarkdownOrString | undefined;
85
+ description?: import("../generated/ast").MarkdownOrString | undefined;
86
+ technology?: import("../generated/ast").MarkdownOrString | undefined;
87
+ }): {
88
+ title?: string;
89
+ description?: ProjectId;
90
+ technology?: string;
91
+ };
78
92
  parseDeploymentView(astNode: import("../generated/ast").DeploymentView): import("../ast").ParsedAstDeploymentView;
79
93
  parseDeploymentViewRule(astRule: import("../generated/ast").DeploymentViewRule): ProjectId;
80
94
  parseDeploymentViewRulePredicate(astRule: import("../generated/ast").DeploymentViewRulePredicate): ProjectId;
@@ -140,6 +154,7 @@ declare const DocumentParserFromMixins: {
140
154
  getMetadata(metadataAstNode: import("../generated/ast").MetadataProperty | undefined): {
141
155
  [key: string]: string;
142
156
  } | undefined;
157
+ parseMarkdownOrString(markdownOrString: import("../generated/ast").MarkdownOrString | undefined): ProjectId | undefined;
143
158
  convertTags<E extends {
144
159
  tags?: import("../generated/ast").Tags;
145
160
  }>(withTags?: E | undefined): any;
@@ -152,6 +167,19 @@ declare const DocumentParserFromMixins: {
152
167
  parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
153
168
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
154
169
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
170
+ parseTitleDescriptionTechnology(inlineProps: {
171
+ title?: string | undefined;
172
+ description?: string | undefined;
173
+ technology?: string | undefined;
174
+ }, bodyProps: {
175
+ title?: import("../generated/ast").MarkdownOrString | undefined;
176
+ description?: import("../generated/ast").MarkdownOrString | undefined;
177
+ technology?: import("../generated/ast").MarkdownOrString | undefined;
178
+ }): {
179
+ title?: string;
180
+ description?: ProjectId;
181
+ technology?: string;
182
+ };
155
183
  parseDeploymentView(astNode: import("../generated/ast").DeploymentView): import("../ast").ParsedAstDeploymentView;
156
184
  parseDeploymentViewRule(astRule: import("../generated/ast").DeploymentViewRule): ProjectId;
157
185
  parseDeploymentViewRulePredicate(astRule: import("../generated/ast").DeploymentViewRulePredicate): ProjectId;
@@ -181,6 +209,7 @@ declare const DocumentParserFromMixins: {
181
209
  getMetadata(metadataAstNode: import("../generated/ast").MetadataProperty | undefined): {
182
210
  [key: string]: string;
183
211
  } | undefined;
212
+ parseMarkdownOrString(markdownOrString: import("../generated/ast").MarkdownOrString | undefined): ProjectId | undefined;
184
213
  convertTags<E extends {
185
214
  tags?: import("../generated/ast").Tags;
186
215
  }>(withTags?: E | undefined): any;
@@ -193,6 +222,19 @@ declare const DocumentParserFromMixins: {
193
222
  parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
194
223
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
195
224
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
225
+ parseTitleDescriptionTechnology(inlineProps: {
226
+ title?: string | undefined;
227
+ description?: string | undefined;
228
+ technology?: string | undefined;
229
+ }, bodyProps: {
230
+ title?: import("../generated/ast").MarkdownOrString | undefined;
231
+ description?: import("../generated/ast").MarkdownOrString | undefined;
232
+ technology?: import("../generated/ast").MarkdownOrString | undefined;
233
+ }): {
234
+ title?: string;
235
+ description?: ProjectId;
236
+ technology?: string;
237
+ };
196
238
  };
197
239
  } & {
198
240
  new (...args: any[]): {
@@ -234,6 +276,7 @@ declare const DocumentParserFromMixins: {
234
276
  getMetadata(metadataAstNode: import("../generated/ast").MetadataProperty | undefined): {
235
277
  [key: string]: string;
236
278
  } | undefined;
279
+ parseMarkdownOrString(markdownOrString: import("../generated/ast").MarkdownOrString | undefined): ProjectId | undefined;
237
280
  convertTags<E extends {
238
281
  tags?: import("../generated/ast").Tags;
239
282
  }>(withTags?: E | undefined): any;
@@ -246,6 +289,19 @@ declare const DocumentParserFromMixins: {
246
289
  parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
247
290
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
248
291
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
292
+ parseTitleDescriptionTechnology(inlineProps: {
293
+ title?: string | undefined;
294
+ description?: string | undefined;
295
+ technology?: string | undefined;
296
+ }, bodyProps: {
297
+ title?: import("../generated/ast").MarkdownOrString | undefined;
298
+ description?: import("../generated/ast").MarkdownOrString | undefined;
299
+ technology?: import("../generated/ast").MarkdownOrString | undefined;
300
+ }): {
301
+ title?: string;
302
+ description?: ProjectId;
303
+ technology?: string;
304
+ };
249
305
  };
250
306
  } & {
251
307
  new (...args: any[]): {
@@ -280,6 +336,7 @@ declare const DocumentParserFromMixins: {
280
336
  getMetadata(metadataAstNode: import("../generated/ast").MetadataProperty | undefined): {
281
337
  [key: string]: string;
282
338
  } | undefined;
339
+ parseMarkdownOrString(markdownOrString: import("../generated/ast").MarkdownOrString | undefined): ProjectId | undefined;
283
340
  convertTags<E extends {
284
341
  tags?: import("../generated/ast").Tags;
285
342
  }>(withTags?: E | undefined): any;
@@ -292,6 +349,19 @@ declare const DocumentParserFromMixins: {
292
349
  parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
293
350
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
294
351
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
352
+ parseTitleDescriptionTechnology(inlineProps: {
353
+ title?: string | undefined;
354
+ description?: string | undefined;
355
+ technology?: string | undefined;
356
+ }, bodyProps: {
357
+ title?: import("../generated/ast").MarkdownOrString | undefined;
358
+ description?: import("../generated/ast").MarkdownOrString | undefined;
359
+ technology?: import("../generated/ast").MarkdownOrString | undefined;
360
+ }): {
361
+ title?: string;
362
+ description?: ProjectId;
363
+ technology?: string;
364
+ };
295
365
  parseDeployment(): void;
296
366
  parseDeploymentNode(astNode: import("../generated/ast").DeploymentNode): import("../ast").ParsedAstDeployment.Node;
297
367
  parseDeployedInstance(astNode: import("../generated/ast").DeployedInstance): import("../ast").ParsedAstDeployment.Instance;
@@ -334,6 +404,7 @@ declare const DocumentParserFromMixins: {
334
404
  getMetadata(metadataAstNode: import("../generated/ast").MetadataProperty | undefined): {
335
405
  [key: string]: string;
336
406
  } | undefined;
407
+ parseMarkdownOrString(markdownOrString: import("../generated/ast").MarkdownOrString | undefined): ProjectId | undefined;
337
408
  convertTags<E extends {
338
409
  tags?: import("../generated/ast").Tags;
339
410
  }>(withTags?: E | undefined): any;
@@ -346,6 +417,19 @@ declare const DocumentParserFromMixins: {
346
417
  parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
347
418
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
348
419
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
420
+ parseTitleDescriptionTechnology(inlineProps: {
421
+ title?: string | undefined;
422
+ description?: string | undefined;
423
+ technology?: string | undefined;
424
+ }, bodyProps: {
425
+ title?: import("../generated/ast").MarkdownOrString | undefined;
426
+ description?: import("../generated/ast").MarkdownOrString | undefined;
427
+ technology?: import("../generated/ast").MarkdownOrString | undefined;
428
+ }): {
429
+ title?: string;
430
+ description?: ProjectId;
431
+ technology?: string;
432
+ };
349
433
  };
350
434
  } & {
351
435
  new (...args: any[]): {
@@ -381,6 +465,7 @@ declare const DocumentParserFromMixins: {
381
465
  getMetadata(metadataAstNode: import("../generated/ast").MetadataProperty | undefined): {
382
466
  [key: string]: string;
383
467
  } | undefined;
468
+ parseMarkdownOrString(markdownOrString: import("../generated/ast").MarkdownOrString | undefined): ProjectId | undefined;
384
469
  convertTags<E extends {
385
470
  tags?: import("../generated/ast").Tags;
386
471
  }>(withTags?: E | undefined): any;
@@ -393,6 +478,19 @@ declare const DocumentParserFromMixins: {
393
478
  parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
394
479
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
395
480
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
481
+ parseTitleDescriptionTechnology(inlineProps: {
482
+ title?: string | undefined;
483
+ description?: string | undefined;
484
+ technology?: string | undefined;
485
+ }, bodyProps: {
486
+ title?: import("../generated/ast").MarkdownOrString | undefined;
487
+ description?: import("../generated/ast").MarkdownOrString | undefined;
488
+ technology?: import("../generated/ast").MarkdownOrString | undefined;
489
+ }): {
490
+ title?: string;
491
+ description?: ProjectId;
492
+ technology?: string;
493
+ };
396
494
  };
397
495
  } & {
398
496
  new (...args: any[]): {
@@ -410,6 +508,7 @@ declare const DocumentParserFromMixins: {
410
508
  getMetadata(metadataAstNode: import("../generated/ast").MetadataProperty | undefined): {
411
509
  [key: string]: string;
412
510
  } | undefined;
511
+ parseMarkdownOrString(markdownOrString: import("../generated/ast").MarkdownOrString | undefined): ProjectId | undefined;
413
512
  convertTags<E extends {
414
513
  tags?: import("../generated/ast").Tags;
415
514
  }>(withTags?: E | undefined): any;
@@ -422,6 +521,19 @@ declare const DocumentParserFromMixins: {
422
521
  parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
423
522
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
424
523
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
524
+ parseTitleDescriptionTechnology(inlineProps: {
525
+ title?: string | undefined;
526
+ description?: string | undefined;
527
+ technology?: string | undefined;
528
+ }, bodyProps: {
529
+ title?: import("../generated/ast").MarkdownOrString | undefined;
530
+ description?: import("../generated/ast").MarkdownOrString | undefined;
531
+ technology?: import("../generated/ast").MarkdownOrString | undefined;
532
+ }): {
533
+ title?: string;
534
+ description?: ProjectId;
535
+ technology?: string;
536
+ };
425
537
  };
426
538
  } & {
427
539
  new (...args: any[]): {
@@ -452,6 +564,7 @@ declare const DocumentParserFromMixins: {
452
564
  getMetadata(metadataAstNode: import("../generated/ast").MetadataProperty | undefined): {
453
565
  [key: string]: string;
454
566
  } | undefined;
567
+ parseMarkdownOrString(markdownOrString: import("../generated/ast").MarkdownOrString | undefined): ProjectId | undefined;
455
568
  convertTags<E extends {
456
569
  tags?: import("../generated/ast").Tags;
457
570
  }>(withTags?: E | undefined): any;
@@ -464,6 +577,19 @@ declare const DocumentParserFromMixins: {
464
577
  parseColorLiteral(astNode: import("../generated/ast").ColorLiteral): ProjectId | undefined;
465
578
  parseElementStyle(elementProps: Array<import("../generated/ast").ElementProperty> | import("../generated/ast").ElementStyleProperty | undefined): import("../ast").ParsedElementStyle;
466
579
  parseStyleProps(styleProps: Array<import("../generated/ast").StyleProperty> | undefined): import("../ast").ParsedElementStyle;
580
+ parseTitleDescriptionTechnology(inlineProps: {
581
+ title?: string | undefined;
582
+ description?: string | undefined;
583
+ technology?: string | undefined;
584
+ }, bodyProps: {
585
+ title?: import("../generated/ast").MarkdownOrString | undefined;
586
+ description?: import("../generated/ast").MarkdownOrString | undefined;
587
+ technology?: import("../generated/ast").MarkdownOrString | undefined;
588
+ }): {
589
+ title?: string;
590
+ description?: ProjectId;
591
+ technology?: string;
592
+ };
467
593
  };
468
594
  } & typeof BaseParser;
469
595
  export declare class DocumentParser extends DocumentParserFromMixins {
@@ -1,12 +1,22 @@
1
1
  import type * as c4 from '@likec4/core';
2
+ import { type MarkdownOrString } from '@likec4/core';
2
3
  import type { AstNode, URI } from 'langium';
3
4
  import { type ParsedElementStyle, type ParsedLikeC4LangiumDocument, ast } from '../../ast';
4
5
  import type { ProjectConfig } from '../../config';
5
6
  import type { LikeC4Services } from '../../module';
6
7
  import { type IsValidFn } from '../../validation';
7
8
  export type GConstructor<T = {}> = new (...args: any[]) => T;
8
- export declare function toSingleLine<T extends string | undefined | null>(str: T): T;
9
- export declare function removeIndent<T extends string | undefined | null>(str: T): T;
9
+ export declare function toSingleLine(str: string): string;
10
+ export declare function toSingleLine(str: string | undefined | null): string | undefined;
11
+ export declare function toSingleLine(str: ast.MarkdownOrString): MarkdownOrString;
12
+ export declare function toSingleLine(str: ast.MarkdownOrString | undefined | null): MarkdownOrString | undefined;
13
+ export declare function toSingleLine(str: ast.MarkdownOrString | string): MarkdownOrString | string;
14
+ export declare function toSingleLine(str: ast.MarkdownOrString | string | undefined | null): MarkdownOrString | string | undefined;
15
+ export declare function removeIndent(str: string): string;
16
+ export declare function removeIndent(str: string | undefined): string | undefined;
17
+ export declare function removeIndent(str: ast.MarkdownOrString): MarkdownOrString;
18
+ export declare function removeIndent(str: ast.MarkdownOrString | undefined): MarkdownOrString | undefined;
19
+ export declare function removeIndent(str: ast.MarkdownOrString | string): MarkdownOrString | string;
10
20
  export type Base = GConstructor<BaseParser>;
11
21
  export declare class BaseParser {
12
22
  readonly services: LikeC4Services;
@@ -23,6 +33,7 @@ export declare class BaseParser {
23
33
  getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
24
34
  [key: string]: string;
25
35
  } | undefined;
36
+ parseMarkdownOrString(markdownOrString: ast.MarkdownOrString | undefined): c4.MarkdownOrString | undefined;
26
37
  convertTags<E extends {
27
38
  tags?: ast.Tags;
28
39
  }>(withTags?: E): any;
@@ -35,4 +46,21 @@ export declare class BaseParser {
35
46
  parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
36
47
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): ParsedElementStyle;
37
48
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): ParsedElementStyle;
49
+ /**
50
+ * Parses title, description and technology
51
+ * Inline properties (right on node) have higher priority than body properties (inside '{...}')
52
+ */
53
+ parseTitleDescriptionTechnology(inlineProps: {
54
+ title?: string | undefined;
55
+ description?: string | undefined;
56
+ technology?: string | undefined;
57
+ }, bodyProps: {
58
+ title?: ast.MarkdownOrString | undefined;
59
+ description?: ast.MarkdownOrString | undefined;
60
+ technology?: ast.MarkdownOrString | undefined;
61
+ }): {
62
+ title?: string;
63
+ description?: c4.MarkdownOrString;
64
+ technology?: string;
65
+ };
38
66
  }