@likec4/language-server 1.25.0 → 1.26.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 (61) hide show
  1. package/bin/likec4-language-server.mjs +1 -1
  2. package/dist/LikeC4FileSystem.js +6 -1
  3. package/dist/LikeC4LanguageServices.d.ts +77 -0
  4. package/dist/LikeC4LanguageServices.js +118 -0
  5. package/dist/Rpc.js +106 -28
  6. package/dist/ast.d.ts +10 -0
  7. package/dist/bundled.mjs +2352 -2278
  8. package/dist/config/index.d.ts +1 -0
  9. package/dist/config/index.js +1 -0
  10. package/dist/config/schema.d.ts +8 -0
  11. package/dist/config/schema.js +19 -0
  12. package/dist/index.d.ts +1 -0
  13. package/dist/lsp/CodeLensProvider.js +3 -1
  14. package/dist/model/builder/buildModel.d.ts +8 -1
  15. package/dist/model/deployments-index.js +1 -1
  16. package/dist/model/fqn-index.d.ts +9 -6
  17. package/dist/model/fqn-index.js +24 -14
  18. package/dist/model/model-builder.d.ts +16 -6
  19. package/dist/model/model-builder.js +64 -50
  20. package/dist/model/model-locator.d.ts +11 -10
  21. package/dist/model/model-locator.js +32 -14
  22. package/dist/model/model-parser.d.ts +148 -148
  23. package/dist/model/model-parser.js +2 -2
  24. package/dist/model/parser/ModelParser.js +14 -2
  25. package/dist/model-change/ModelChanges.d.ts +1 -1
  26. package/dist/model-change/ModelChanges.js +2 -2
  27. package/dist/module.d.ts +9 -3
  28. package/dist/module.js +19 -5
  29. package/dist/protocol.d.ts +98 -16
  30. package/dist/protocol.js +21 -6
  31. package/dist/references/scope-provider.d.ts +24 -11
  32. package/dist/references/scope-provider.js +97 -68
  33. package/dist/shared/index.d.ts +0 -1
  34. package/dist/shared/index.js +0 -1
  35. package/dist/test/testServices.d.ts +15 -1
  36. package/dist/test/testServices.js +65 -17
  37. package/dist/utils/index.d.ts +3 -0
  38. package/dist/utils/index.js +3 -0
  39. package/dist/utils/projectId.d.ts +3 -0
  40. package/dist/utils/projectId.js +6 -0
  41. package/dist/validation/deployment-checks.js +5 -2
  42. package/dist/validation/element.js +2 -1
  43. package/dist/validation/specification.js +14 -7
  44. package/dist/validation/view.js +10 -8
  45. package/dist/views/index.d.ts +1 -1
  46. package/dist/views/index.js +1 -1
  47. package/dist/views/likec4-views.d.ts +17 -8
  48. package/dist/views/likec4-views.js +12 -11
  49. package/dist/workspace/AstNodeDescriptionProvider.d.ts +7 -0
  50. package/dist/workspace/AstNodeDescriptionProvider.js +18 -0
  51. package/dist/workspace/IndexManager.d.ts +10 -0
  52. package/dist/workspace/IndexManager.js +17 -0
  53. package/dist/workspace/LangiumDocuments.d.ts +14 -0
  54. package/dist/workspace/LangiumDocuments.js +31 -0
  55. package/dist/workspace/ProjectsManager.d.ts +48 -0
  56. package/dist/workspace/ProjectsManager.js +150 -0
  57. package/dist/{shared → workspace}/WorkspaceManager.d.ts +8 -2
  58. package/dist/{shared → workspace}/WorkspaceManager.js +22 -0
  59. package/dist/workspace/index.d.ts +5 -0
  60. package/dist/workspace/index.js +5 -0
  61. package/package.json +21 -12
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { startLanguageServer } from '.../dist/bundled.mjs'
3
+ import { startLanguageServer } from '../dist/bundled.mjs'
4
4
 
5
5
  startLanguageServer().catch((e) => {
6
6
  console.error(e)
@@ -4,10 +4,15 @@ import { NodeFileSystemProvider } from "langium/node";
4
4
  import { LikeC4LanguageMetaData } from "./generated/module.js";
5
5
  import { Content, isLikeC4Builtin } from "./likec4lib.js";
6
6
  import { logError } from "./logger.js";
7
+ import { ProjectsManager } from "./workspace/ProjectsManager.js";
7
8
  export const LikeC4FileSystem = {
8
9
  fileSystemProvider: () => new SymLinkTraversingFileSystemProvider()
9
10
  };
10
- const hasExtension = (path) => LikeC4LanguageMetaData.fileExtensions.some((ext) => path.endsWith(ext));
11
+ const SearchExtension = [
12
+ ...LikeC4LanguageMetaData.fileExtensions,
13
+ ...ProjectsManager.ConfigFileNames
14
+ ];
15
+ const hasExtension = (path) => SearchExtension.some((ext) => path.endsWith(ext));
11
16
  class SymLinkTraversingFileSystemProvider extends NodeFileSystemProvider {
12
17
  async readFile(uri) {
13
18
  if (isLikeC4Builtin(uri)) {
@@ -0,0 +1,77 @@
1
+ import { type DiagramView, type NonEmptyArray, type ProjectId, LikeC4Model } from '@likec4/core';
2
+ import { URI } from 'langium';
3
+ import { type Range } from 'vscode-languageserver-types';
4
+ import type { ProjectConfig } from './config';
5
+ import type { LikeC4ModelBuilder } from './model';
6
+ import type { LikeC4Services } from './module';
7
+ import type { LikeC4Views } from './views/likec4-views';
8
+ export interface LikeC4LanguageServices {
9
+ readonly views: LikeC4Views;
10
+ readonly builder: LikeC4ModelBuilder;
11
+ readonly workspaceUri: URI;
12
+ projects(): NonEmptyArray<{
13
+ id: ProjectId;
14
+ folder: URI;
15
+ config: ProjectConfig;
16
+ documents: NonEmptyArray<URI> | null;
17
+ }>;
18
+ diagrams(): Promise<DiagramView[]>;
19
+ computedModel(project?: ProjectId | undefined): Promise<LikeC4Model.Computed>;
20
+ layoutedModel(project?: ProjectId | undefined): Promise<LikeC4Model.Layouted>;
21
+ getErrors(): Array<{
22
+ message: string;
23
+ line: number;
24
+ range: Range;
25
+ sourceFsPath: string;
26
+ }>;
27
+ notifyUpdate(update: {
28
+ changed?: string;
29
+ removed?: string;
30
+ }): Promise<boolean>;
31
+ }
32
+ /**
33
+ * Public Language Services
34
+ */
35
+ export declare class DefaultLikeC4LanguageServices implements LikeC4LanguageServices {
36
+ private services;
37
+ readonly views: LikeC4Views;
38
+ readonly builder: LikeC4ModelBuilder;
39
+ private projectsManager;
40
+ constructor(services: LikeC4Services);
41
+ get workspaceUri(): URI;
42
+ projects(): NonEmptyArray<{
43
+ id: ProjectId;
44
+ folder: URI;
45
+ config: ProjectConfig;
46
+ documents: NonEmptyArray<URI> | null;
47
+ }>;
48
+ /**
49
+ * Diagram is a computed view, layouted using Graphviz
50
+ * Used in React components
51
+ */
52
+ diagrams(): Promise<DiagramView[]>;
53
+ /**
54
+ * Builds LikeC4Model from all documents
55
+ * Only computes view predicates {@link ComputedView} - i.e. no layout
56
+ * Not ready for rendering, but enough to traverse
57
+ */
58
+ computedModel(project?: ProjectId | undefined): Promise<LikeC4Model.Computed>;
59
+ /**
60
+ * Same as {@link computedModel()}, but also applies layout
61
+ * Ready for rendering
62
+ */
63
+ layoutedModel(project?: ProjectId | undefined): Promise<LikeC4Model.Layouted>;
64
+ getErrors(): Array<{
65
+ message: string;
66
+ line: number;
67
+ range: Range;
68
+ sourceFsPath: string;
69
+ }>;
70
+ /**
71
+ * TODO Replace with watcher
72
+ */
73
+ notifyUpdate({ changed, removed }: {
74
+ changed?: string;
75
+ removed?: string;
76
+ }): Promise<boolean>;
77
+ }
@@ -0,0 +1,118 @@
1
+ import { LikeC4Model } from "@likec4/core";
2
+ import { loggable } from "@likec4/log";
3
+ import { URI } from "langium";
4
+ import { entries, hasAtLeast, indexBy, map, pipe, prop } from "remeda";
5
+ import { DiagnosticSeverity } from "vscode-languageserver-types";
6
+ import { logger as mainLogger } from "./logger.js";
7
+ import { ProjectsManager } from "./workspace/index.js";
8
+ const logger = mainLogger.getChild("LikeC4LanguageServices");
9
+ export class DefaultLikeC4LanguageServices {
10
+ constructor(services) {
11
+ this.services = services;
12
+ this.views = services.likec4.Views;
13
+ this.builder = services.likec4.ModelBuilder;
14
+ this.projectsManager = services.shared.workspace.ProjectsManager;
15
+ }
16
+ views;
17
+ builder;
18
+ projectsManager;
19
+ get workspaceUri() {
20
+ return this.services.shared.workspace.WorkspaceManager.workspaceUri;
21
+ }
22
+ projects() {
23
+ const projectsManager = this.services.shared.workspace.ProjectsManager;
24
+ const projectsWithDocs = pipe(
25
+ this.services.shared.workspace.LangiumDocuments.groupedByProject(),
26
+ entries(),
27
+ map(([projectId, docs]) => {
28
+ const id = projectId;
29
+ const { folder, config } = projectsManager.getProject(id);
30
+ return {
31
+ id,
32
+ folder,
33
+ config,
34
+ documents: map(docs, prop("uri"))
35
+ };
36
+ })
37
+ );
38
+ if (hasAtLeast(projectsWithDocs, 1)) {
39
+ return projectsWithDocs;
40
+ }
41
+ return [{
42
+ id: ProjectsManager.DefaultProjectId,
43
+ folder: this.services.shared.workspace.WorkspaceManager.workspaceUri,
44
+ config: {
45
+ name: "default"
46
+ },
47
+ documents: null
48
+ }];
49
+ }
50
+ /**
51
+ * Diagram is a computed view, layouted using Graphviz
52
+ * Used in React components
53
+ */
54
+ async diagrams() {
55
+ return await this.views.diagrams();
56
+ }
57
+ /**
58
+ * Builds LikeC4Model from all documents
59
+ * Only computes view predicates {@link ComputedView} - i.e. no layout
60
+ * Not ready for rendering, but enough to traverse
61
+ */
62
+ async computedModel(project) {
63
+ const projectId = this.projectsManager.ensureProjectId(project);
64
+ return await this.builder.buildLikeC4Model(projectId);
65
+ }
66
+ /**
67
+ * Same as {@link computedModel()}, but also applies layout
68
+ * Ready for rendering
69
+ */
70
+ async layoutedModel(project) {
71
+ const projectId = this.projectsManager.ensureProjectId(project);
72
+ const parsed = await this.builder.parseModel(projectId);
73
+ if (!parsed) {
74
+ throw new Error("Failed to parse model");
75
+ }
76
+ const diagrams = await this.views.diagrams(projectId);
77
+ return LikeC4Model.create({
78
+ ...parsed,
79
+ __: "layouted",
80
+ views: indexBy(diagrams, prop("id"))
81
+ });
82
+ }
83
+ getErrors() {
84
+ const docs = this.services.shared.workspace.LangiumDocuments.allExcludingBuiltin.toArray();
85
+ return docs.flatMap((doc) => {
86
+ return (doc.diagnostics ?? []).filter((d) => d.severity === DiagnosticSeverity.Error).map(({ message, range }) => ({
87
+ message,
88
+ line: range.start.line,
89
+ range,
90
+ sourceFsPath: doc.uri.fsPath
91
+ }));
92
+ });
93
+ }
94
+ /**
95
+ * TODO Replace with watcher
96
+ */
97
+ async notifyUpdate({ changed, removed }) {
98
+ if (!changed && !removed) {
99
+ return false;
100
+ }
101
+ const mutex = this.services.shared.workspace.WorkspaceLock;
102
+ try {
103
+ let completed = false;
104
+ await mutex.write(async (token) => {
105
+ await this.services.shared.workspace.DocumentBuilder.update(
106
+ changed ? [URI.file(changed)] : [],
107
+ removed ? [URI.file(removed)] : [],
108
+ token
109
+ );
110
+ completed = !token.isCancellationRequested;
111
+ });
112
+ return completed;
113
+ } catch (e) {
114
+ logger.error(loggable(e));
115
+ return false;
116
+ }
117
+ }
118
+ }
package/dist/Rpc.js CHANGED
@@ -1,19 +1,23 @@
1
- import { filter, funnel, indexBy, map, pipe } from "remeda";
1
+ import { filter, flatMap, funnel, indexBy, keys, map, mapValues, pipe, sort } from "remeda";
2
2
  import { logger as rootLogger } from "./logger.js";
3
- import { LikeC4Model, nonexhaustive } from "@likec4/core";
3
+ import {
4
+ LikeC4Model,
5
+ nonexhaustive
6
+ } from "@likec4/core";
4
7
  import { Disposable, interruptAndCheck, URI, UriUtils } from "langium";
5
8
  import { DiagnosticSeverity } from "vscode-languageserver";
6
- import { isLikeC4LangiumDocument } from "./ast.js";
7
- import { isLikeC4Builtin } from "./likec4lib.js";
8
9
  import {
9
10
  BuildDocuments,
10
11
  ChangeView,
11
12
  ComputeView,
13
+ DidChangeModelNotification,
12
14
  FetchComputedModel,
13
15
  FetchLayoutedModel,
16
+ FetchProjects,
17
+ FetchTelemetryMetrics,
18
+ FetchViewsFromAllProjects,
14
19
  LayoutView,
15
20
  Locate,
16
- onDidChangeModel,
17
21
  ValidateLayout
18
22
  } from "./protocol.js";
19
23
  import { ADisposable } from "./utils/index.js";
@@ -29,6 +33,7 @@ export class Rpc extends ADisposable {
29
33
  const modelEditor = this.services.likec4.ModelChanges;
30
34
  const views = this.services.likec4.Views;
31
35
  const connection = this.services.shared.lsp.Connection;
36
+ const projects = this.services.shared.workspace.ProjectsManager;
32
37
  if (!connection) {
33
38
  logger.info(`[ServerRpc] no connection, not initializing`);
34
39
  return;
@@ -39,14 +44,14 @@ export class Rpc extends ADisposable {
39
44
  const notifyModelParsed = funnel(
40
45
  () => {
41
46
  logger.debug`sendNotification ${"onDidChangeModel"}`;
42
- connection.sendNotification(onDidChangeModel, "").catch((e) => {
47
+ connection.sendNotification(DidChangeModelNotification.type, "").catch((e) => {
43
48
  logger.warn(`[ServerRpc] error sending onDidChangeModel: ${e}`);
44
49
  return Promise.resolve();
45
50
  });
46
51
  },
47
52
  {
48
53
  triggerAt: "end",
49
- minQuietPeriodMs: 150,
54
+ minQuietPeriodMs: 100,
50
55
  maxBurstDurationMs: 500,
51
56
  minGapMs: 300
52
57
  }
@@ -54,28 +59,29 @@ export class Rpc extends ADisposable {
54
59
  let isFirstBuild = true;
55
60
  this.onDispose(
56
61
  modelBuilder.onModelParsed(() => notifyModelParsed.call()),
57
- connection.onRequest(FetchComputedModel.Req, async ({ cleanCaches }, cancelToken) => {
58
- logger.debug`received request ${"fetchComputedModel"}`;
62
+ connection.onRequest(FetchComputedModel.req, async ({ projectId, cleanCaches }, cancelToken) => {
63
+ logger.debug`received request ${"fetchComputedModel"} for project ${projectId}`;
59
64
  if (cleanCaches) {
60
- const all = LangiumDocuments.all.map((d) => d.uri).toArray();
61
- await DocumentBuilder.update(all, [], cancelToken);
65
+ const docs = projectId ? LangiumDocuments.projectDocuments(projectId) : LangiumDocuments.all;
66
+ const uris = docs.map((d) => d.uri).toArray();
67
+ await DocumentBuilder.update(uris, [], cancelToken);
62
68
  }
63
- const likec4model = await modelBuilder.buildLikeC4Model(cancelToken);
69
+ const likec4model = await modelBuilder.buildLikeC4Model(projectId, cancelToken);
64
70
  if (likec4model !== LikeC4Model.EMPTY) {
65
71
  return { model: likec4model.$model };
66
72
  }
67
73
  return { model: null };
68
74
  }),
69
- connection.onRequest(ComputeView.Req, async ({ viewId }, cancelToken) => {
70
- const view = await modelBuilder.computeView(viewId, cancelToken);
75
+ connection.onRequest(ComputeView.req, async ({ viewId, projectId }, cancelToken) => {
76
+ const view = await modelBuilder.computeView(viewId, projectId, cancelToken);
71
77
  return { view };
72
78
  }),
73
- connection.onRequest(FetchLayoutedModel.Req, async (cancelToken) => {
74
- const model = await modelBuilder.parseModel(cancelToken);
79
+ connection.onRequest(FetchLayoutedModel.req, async ({ projectId }, cancelToken) => {
80
+ const model = await modelBuilder.parseModel(projectId, cancelToken);
75
81
  if (model === null) {
76
82
  return { model: null };
77
83
  }
78
- const diagrams = await views.diagrams();
84
+ const diagrams = await views.diagrams(projectId, cancelToken);
79
85
  return {
80
86
  model: {
81
87
  ...model,
@@ -84,20 +90,59 @@ export class Rpc extends ADisposable {
84
90
  }
85
91
  };
86
92
  }),
87
- connection.onRequest(LayoutView.Req, async ({ viewId }, cancelToken) => {
88
- logger.debug`received request ${"layoutView"} of ${viewId}`;
89
- const result = await views.layoutView(viewId, cancelToken);
93
+ connection.onRequest(LayoutView.req, async ({ viewId, projectId }, cancelToken) => {
94
+ logger.debug`received request ${"layoutView"} of ${viewId} from project ${projectId}`;
95
+ const result = await views.layoutView(viewId, projectId, cancelToken);
90
96
  return { result };
91
97
  }),
92
- connection.onRequest(ValidateLayout.Req, async (cancelToken) => {
93
- const layouts = await views.layoutAllViews(cancelToken);
98
+ connection.onRequest(ValidateLayout.Req, async ({ projectId }, cancelToken) => {
99
+ const layouts = await views.layoutAllViews(projectId, cancelToken);
94
100
  const result = reportLayoutDrift(layouts.map((l) => l.diagram));
95
101
  return { result };
96
102
  }),
103
+ connection.onRequest(FetchProjects.req, async (_cancelToken) => {
104
+ logger.debug`received request ${"FetchProjects"}`;
105
+ const docsByProject = LangiumDocuments.groupedByProject();
106
+ return {
107
+ projects: mapValues(docsByProject, (docs) => map(docs, (d) => d.uri.toString()))
108
+ };
109
+ }),
110
+ connection.onRequest(FetchViewsFromAllProjects.req, async (cancelToken) => {
111
+ logger.debug`received request ${"FetchViewsFromAllProjects"}`;
112
+ const promises = projects.all.map(async (projectId) => {
113
+ const computedViews = await views.computedViews(projectId, cancelToken);
114
+ return pipe(
115
+ computedViews,
116
+ map((v) => ({
117
+ id: v.id,
118
+ title: v.title ?? v.id,
119
+ projectId
120
+ })),
121
+ sort((a, b) => {
122
+ if (a.id === "index") {
123
+ return -1;
124
+ }
125
+ if (b.id === "index") {
126
+ return 1;
127
+ }
128
+ return a.title.localeCompare(b.title);
129
+ })
130
+ );
131
+ });
132
+ const results = await Promise.allSettled(promises);
133
+ await interruptAndCheck(cancelToken);
134
+ return {
135
+ views: pipe(
136
+ results,
137
+ filter((r) => r.status === "fulfilled"),
138
+ flatMap((r) => r.value)
139
+ )
140
+ };
141
+ }),
97
142
  connection.onRequest(BuildDocuments.Req, async ({ docs }, cancelToken) => {
98
143
  const changed = docs.map((d) => URI.parse(d));
99
144
  const notChanged = (uri) => changed.every((c) => !UriUtils.equals(c, uri));
100
- const deleted = LangiumDocuments.all.toArray().filter((d) => !isLikeC4Builtin(d.uri) && isLikeC4LangiumDocument(d) && notChanged(d.uri)).map((d) => d.uri);
145
+ const deleted = LangiumDocuments.allExcludingBuiltin.toArray().filter((d) => notChanged(d.uri)).map((d) => d.uri);
101
146
  logger.debug(
102
147
  `[ServerRpc] received request to build:
103
148
  changed (total ${changed.length}):${docs.map((d) => "\n - " + d).join("")}
@@ -126,21 +171,54 @@ export class Rpc extends ADisposable {
126
171
  connection.onRequest(Locate.Req, (params) => {
127
172
  switch (true) {
128
173
  case "element" in params:
129
- return modelLocator.locateElement(params.element, params.property ?? "name");
174
+ return modelLocator.locateElement(params.element, params.projectId);
130
175
  case "relation" in params:
131
- return modelLocator.locateRelation(params.relation);
176
+ return modelLocator.locateRelation(params.relation, params.projectId);
132
177
  case "view" in params:
133
- return modelLocator.locateView(params.view);
178
+ return modelLocator.locateView(params.view, params.projectId);
134
179
  case "deployment" in params:
135
- return modelLocator.locateDeploymentElement(params.deployment, params.property ?? "name");
180
+ return modelLocator.locateDeploymentElement(params.deployment, params.projectId);
136
181
  default:
137
182
  nonexhaustive(params);
138
183
  }
139
184
  }),
140
185
  connection.onRequest(ChangeView.Req, async (request, _cancelToken) => {
141
- logger.debug`received request ${"changeView"} of ${request.viewId}`;
186
+ logger.debug`received request ${"changeView"} of ${request.viewId} from project ${request.projectId}`;
142
187
  return await modelEditor.applyChange(request);
143
188
  }),
189
+ connection.onRequest(FetchTelemetryMetrics.req, async (cancelToken) => {
190
+ const projectsIds = [...projects.all];
191
+ const promises = projectsIds.map(async (projectId) => {
192
+ const model = await modelBuilder.buildLikeC4Model(projectId, cancelToken);
193
+ if (model === LikeC4Model.EMPTY) {
194
+ return Promise.reject(new Error(`Model is empty`));
195
+ }
196
+ return {
197
+ elementKinds: keys(model.$model.specification.elements).length,
198
+ relationshipKinds: keys(model.$model.specification.relationships).length,
199
+ tags: model.$model.specification.tags.length,
200
+ elements: keys(model.$model.elements).length,
201
+ relationships: keys(model.$model.relations).length,
202
+ views: keys(model.$model.views).length,
203
+ projects: 1
204
+ };
205
+ });
206
+ const results = await Promise.allSettled(promises);
207
+ await interruptAndCheck(cancelToken);
208
+ const values = results.filter((r) => r.status === "fulfilled").map((r) => r.value);
209
+ const metrics = values.length > 0 ? values.reduce((acc, r) => ({
210
+ elementKinds: acc.elementKinds + r.elementKinds,
211
+ relationshipKinds: acc.relationshipKinds + r.relationshipKinds,
212
+ tags: acc.tags + r.tags,
213
+ elements: acc.elements + r.elements,
214
+ relationships: acc.relationships + r.relationships,
215
+ views: acc.views + r.views,
216
+ projects: acc.projects + 1
217
+ })) : null;
218
+ return {
219
+ metrics
220
+ };
221
+ }),
144
222
  Disposable.create(() => {
145
223
  notifyModelParsed.cancel();
146
224
  })
package/dist/ast.d.ts CHANGED
@@ -7,6 +7,14 @@ import * as ast from './generated/ast';
7
7
  import type { IsValidFn } from './validation';
8
8
  export { ast };
9
9
  declare const idattr: unique symbol;
10
+ declare module 'langium' {
11
+ interface LangiumDocument {
12
+ likec4ProjectId?: c4.ProjectId;
13
+ }
14
+ interface AstNodeDescription {
15
+ likec4ProjectId?: c4.ProjectId;
16
+ }
17
+ }
10
18
  declare module './generated/ast' {
11
19
  interface Element {
12
20
  [idattr]?: c4.Fqn | undefined;
@@ -173,8 +181,10 @@ export interface LikeC4DocumentProps {
173
181
  }
174
182
  type LikeC4GrammarDocument = Omit<LangiumDocument<LikeC4Grammar>, 'diagnostics'>;
175
183
  export interface LikeC4LangiumDocument extends LikeC4GrammarDocument, LikeC4DocumentProps {
184
+ likec4ProjectId: c4.ProjectId;
176
185
  }
177
186
  export interface ParsedLikeC4LangiumDocument extends LikeC4GrammarDocument, Required<LikeC4DocumentProps> {
187
+ likec4ProjectId: c4.ProjectId;
178
188
  }
179
189
  export declare function isLikeC4LangiumDocument(doc: LangiumDocument): doc is LikeC4LangiumDocument;
180
190
  export declare function isParsedLikeC4LangiumDocument(doc: LangiumDocument): doc is ParsedLikeC4LangiumDocument;