@likec4/language-server 1.38.0 → 1.39.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 (63) hide show
  1. package/dist/LikeC4LanguageServices.d.ts +8 -0
  2. package/dist/LikeC4LanguageServices.js +25 -4
  3. package/dist/Rpc.js +11 -4
  4. package/dist/ast.d.ts +1 -1
  5. package/dist/ast.js +2 -1
  6. package/dist/bundled.d.ts +8 -0
  7. package/dist/bundled.js +40 -0
  8. package/dist/bundled.mjs +3612 -3512
  9. package/dist/filesystem/ChokidarWatcher.js +12 -9
  10. package/dist/filesystem/LikeC4FileSystem.d.ts +0 -2
  11. package/dist/filesystem/LikeC4FileSystem.js +7 -5
  12. package/dist/filesystem/index.d.ts +7 -0
  13. package/dist/filesystem/index.js +3 -0
  14. package/dist/generated/ast.d.ts +1 -0
  15. package/dist/generated/ast.js +2 -1
  16. package/dist/generated/grammar.js +1 -1
  17. package/dist/generated-lib/icons.js +1 -1
  18. package/dist/index.d.ts +1 -0
  19. package/dist/logger.js +1 -1
  20. package/dist/mcp/MCPServerFactory.js +6 -5
  21. package/dist/mcp/server/StreamableLikeC4MCPServer.d.ts +2 -2
  22. package/dist/mcp/server/StreamableLikeC4MCPServer.js +97 -100
  23. package/dist/mcp/server/WithMCPServer.d.ts +3 -1
  24. package/dist/mcp/server/WithMCPServer.js +6 -5
  25. package/dist/mcp/tools/search-element.js +26 -11
  26. package/dist/mcp/utils.js +2 -2
  27. package/dist/model/builder/MergedSpecification.d.ts +3 -3
  28. package/dist/model/builder/MergedSpecification.js +4 -7
  29. package/dist/model/builder/assignTagColors.js +1 -1
  30. package/dist/model/builder/buildModel.d.ts +3 -8
  31. package/dist/model/builder/buildModel.js +14 -11
  32. package/dist/model/model-builder.d.ts +1 -1
  33. package/dist/model/model-locator.js +2 -1
  34. package/dist/model/model-parser.d.ts +19 -46
  35. package/dist/model/model-parser.js +13 -3
  36. package/dist/model/parser/Base.d.ts +4 -7
  37. package/dist/model/parser/Base.js +19 -0
  38. package/dist/model/parser/DeploymentModelParser.d.ts +2 -5
  39. package/dist/model/parser/DeploymentViewParser.d.ts +2 -5
  40. package/dist/model/parser/FqnRefParser.d.ts +2 -5
  41. package/dist/model/parser/GlobalsParser.d.ts +2 -5
  42. package/dist/model/parser/ImportsParser.d.ts +2 -5
  43. package/dist/model/parser/ModelParser.d.ts +2 -5
  44. package/dist/model/parser/PredicatesParser.d.ts +2 -5
  45. package/dist/model/parser/SpecificationParser.d.ts +2 -5
  46. package/dist/model/parser/ViewsParser.d.ts +2 -5
  47. package/dist/protocol.d.ts +16 -2
  48. package/dist/protocol.js +4 -0
  49. package/dist/test/testServices.d.ts +5 -1
  50. package/dist/test/testServices.js +18 -3
  51. package/dist/utils/disposable.d.ts +1 -1
  52. package/dist/utils/stringHash.js +1 -1
  53. package/dist/view-utils/resolve-relative-paths.js +1 -1
  54. package/dist/workspace/LangiumDocuments.d.ts +4 -1
  55. package/dist/workspace/LangiumDocuments.js +15 -0
  56. package/dist/workspace/ProjectsManager.d.ts +25 -11
  57. package/dist/workspace/ProjectsManager.js +85 -44
  58. package/dist/workspace/WorkspaceManager.js +5 -4
  59. package/package.json +22 -28
  60. package/dist/config/index.d.ts +0 -1
  61. package/dist/config/index.js +0 -1
  62. package/dist/config/schema.d.ts +0 -10
  63. package/dist/config/schema.js +0 -39
@@ -28,11 +28,7 @@ export declare function DeploymentViewParser<TBase extends WithExpressionV2 & Wi
28
28
  isValid: import("../../validation").IsValidFn;
29
29
  readonly services: import("../..").LikeC4Services;
30
30
  readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
31
- get project(): {
32
- id: c4.ProjectId;
33
- folderUri: c4;
34
- config: Readonly<import("../../config").ProjectConfig>;
35
- };
31
+ get project(): import("../../workspace").Project;
36
32
  resolveFqn(node: ast.FqnReferenceable): c4.Fqn;
37
33
  getAstNodePath(node: c4): any;
38
34
  getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
@@ -48,6 +44,7 @@ export declare function DeploymentViewParser<TBase extends WithExpressionV2 & Wi
48
44
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
49
45
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
50
46
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
47
+ parseImageAlias(value: string): string | undefined;
51
48
  parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
52
49
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
53
50
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
@@ -23,11 +23,7 @@ export declare function ExpressionV2Parser<TBase extends Base>(B: TBase): {
23
23
  isValid: import("../../validation").IsValidFn;
24
24
  readonly services: import("../..").LikeC4Services;
25
25
  readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
26
- get project(): {
27
- id: c4.ProjectId;
28
- folderUri: c4;
29
- config: Readonly<import("../../config").ProjectConfig>;
30
- };
26
+ get project(): import("../../workspace").Project;
31
27
  resolveFqn(node: ast.FqnReferenceable): c4.Fqn;
32
28
  getAstNodePath(node: c4): any;
33
29
  getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
@@ -43,6 +39,7 @@ export declare function ExpressionV2Parser<TBase extends Base>(B: TBase): {
43
39
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
44
40
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
45
41
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
42
+ parseImageAlias(value: string): string | undefined;
46
43
  parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
47
44
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
48
45
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
@@ -52,11 +52,7 @@ export declare function GlobalsParser<TBase extends WithViewsParser>(B: TBase):
52
52
  isValid: import("../../validation").IsValidFn;
53
53
  readonly services: import("../..").LikeC4Services;
54
54
  readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
55
- get project(): {
56
- id: c4.ProjectId;
57
- folderUri: c4;
58
- config: Readonly<import("../../config").ProjectConfig>;
59
- };
55
+ get project(): import("../../workspace").Project;
60
56
  resolveFqn(node: ast.FqnReferenceable): c4.Fqn;
61
57
  getAstNodePath(node: c4): any;
62
58
  getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
@@ -72,6 +68,7 @@ export declare function GlobalsParser<TBase extends WithViewsParser>(B: TBase):
72
68
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
73
69
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
74
70
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
71
+ parseImageAlias(value: string): string | undefined;
75
72
  parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
76
73
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
77
74
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
@@ -7,11 +7,7 @@ export declare function ImportsParser<TBase extends Base>(B: TBase): {
7
7
  isValid: import("../../validation").IsValidFn;
8
8
  readonly services: import("../..").LikeC4Services;
9
9
  readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
10
- get project(): {
11
- id: ProjectId;
12
- folderUri: ProjectId;
13
- config: Readonly<import("../../config").ProjectConfig>;
14
- };
10
+ get project(): import("../../workspace").Project;
15
11
  resolveFqn(node: ast.FqnReferenceable): ProjectId;
16
12
  getAstNodePath(node: ProjectId): any;
17
13
  getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
@@ -27,6 +23,7 @@ export declare function ImportsParser<TBase extends Base>(B: TBase): {
27
23
  convertLinks(source?: ast.LinkProperty["$container"]): ProjectId[] | undefined;
28
24
  parseLinks(source?: ast.LinkProperty["$container"]): ProjectId[] | undefined;
29
25
  parseIconProperty(prop: ast.IconProperty | undefined): ProjectId | undefined;
26
+ parseImageAlias(value: string): string | undefined;
30
27
  parseColorLiteral(astNode: ast.ColorLiteral): ProjectId | undefined;
31
28
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
32
29
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
@@ -29,11 +29,7 @@ export declare function ModelParser<TBase extends WithExpressionV2>(B: TBase): {
29
29
  isValid: import("../../validation").IsValidFn;
30
30
  readonly services: import("../..").LikeC4Services;
31
31
  readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
32
- get project(): {
33
- id: c4.ProjectId;
34
- folderUri: c4;
35
- config: Readonly<import("../../config").ProjectConfig>;
36
- };
32
+ get project(): import("../../workspace").Project;
37
33
  resolveFqn(node: ast.FqnReferenceable): c4.Fqn;
38
34
  getAstNodePath(node: c4): any;
39
35
  getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
@@ -49,6 +45,7 @@ export declare function ModelParser<TBase extends WithExpressionV2>(B: TBase): {
49
45
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
50
46
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
51
47
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
48
+ parseImageAlias(value: string): string | undefined;
52
49
  parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
53
50
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
54
51
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
@@ -34,11 +34,7 @@ export declare function PredicatesParser<TBase extends WithExpressionV2>(B: TBas
34
34
  isValid: import("../../validation").IsValidFn;
35
35
  readonly services: import("../..").LikeC4Services;
36
36
  readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
37
- get project(): {
38
- id: c4.ProjectId;
39
- folderUri: c4;
40
- config: Readonly<import("../../config").ProjectConfig>;
41
- };
37
+ get project(): import("../../workspace").Project;
42
38
  resolveFqn(node: ast.FqnReferenceable): c4.Fqn;
43
39
  getAstNodePath(node: c4): any;
44
40
  getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
@@ -54,6 +50,7 @@ export declare function PredicatesParser<TBase extends WithExpressionV2>(B: TBas
54
50
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
55
51
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
56
52
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
53
+ parseImageAlias(value: string): string | undefined;
57
54
  parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
58
55
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
59
56
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
@@ -13,11 +13,7 @@ export declare function SpecificationParser<TBase extends Base>(B: TBase): {
13
13
  isValid: import("../../validation").IsValidFn;
14
14
  readonly services: import("../..").LikeC4Services;
15
15
  readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
16
- get project(): {
17
- id: c4.ProjectId;
18
- folderUri: c4;
19
- config: Readonly<import("../../config").ProjectConfig>;
20
- };
16
+ get project(): import("../../workspace").Project;
21
17
  resolveFqn(node: ast.FqnReferenceable): c4.Fqn;
22
18
  getAstNodePath(node: c4): any;
23
19
  getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
@@ -33,6 +29,7 @@ export declare function SpecificationParser<TBase extends Base>(B: TBase): {
33
29
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
34
30
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
35
31
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
32
+ parseImageAlias(value: string): string | undefined;
36
33
  parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
37
34
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
38
35
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
@@ -50,11 +50,7 @@ export declare function ViewsParser<TBase extends WithPredicates & WithDeploymen
50
50
  isValid: import("../../validation").IsValidFn;
51
51
  readonly services: import("../..").LikeC4Services;
52
52
  readonly doc: import("../../ast").ParsedLikeC4LangiumDocument;
53
- get project(): {
54
- id: c4.ProjectId;
55
- folderUri: c4;
56
- config: Readonly<import("../../config").ProjectConfig>;
57
- };
53
+ get project(): import("../../workspace").Project;
58
54
  resolveFqn(node: ast.FqnReferenceable): c4.Fqn;
59
55
  getAstNodePath(node: c4): any;
60
56
  getMetadata(metadataAstNode: ast.MetadataProperty | undefined): {
@@ -70,6 +66,7 @@ export declare function ViewsParser<TBase extends WithPredicates & WithDeploymen
70
66
  convertLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
71
67
  parseLinks(source?: ast.LinkProperty["$container"]): c4.Link[] | undefined;
72
68
  parseIconProperty(prop: ast.IconProperty | undefined): c4.IconUrl | undefined;
69
+ parseImageAlias(value: string): string | undefined;
73
70
  parseColorLiteral(astNode: ast.ColorLiteral): c4.ColorLiteral | undefined;
74
71
  parseElementStyle(elementProps: Array<ast.ElementProperty> | ast.ElementStyleProperty | undefined): import("../../ast").ParsedElementStyle;
75
72
  parseStyleProps(styleProps: Array<ast.StyleProperty> | undefined): import("../../ast").ParsedElementStyle;
@@ -1,7 +1,7 @@
1
+ import type { LikeC4ProjectJsonConfig } from '@likec4/config';
1
2
  import type { ComputedLikeC4ModelData, ComputedView, DeploymentFqn, DiagramView, Fqn, LayoutedLikeC4ModelData, NonEmptyArray, ProjectId, RelationId, ViewChange, ViewId } from '@likec4/core';
2
3
  import { NotificationType, RequestType, RequestType0 } from 'vscode-jsonrpc';
3
4
  import type { DiagnosticSeverity, DocumentUri, Location, Position, Range, URI } from 'vscode-languageserver-types';
4
- import type { ProjectConfig } from './config';
5
5
  export declare namespace DidChangeModelNotification {
6
6
  const type: NotificationType<string>;
7
7
  type Type = typeof type;
@@ -139,7 +139,7 @@ export declare namespace FetchProjects {
139
139
  projects: {
140
140
  [projectId: ProjectId]: {
141
141
  folder: URI;
142
- config: ProjectConfig;
142
+ config: LikeC4ProjectJsonConfig;
143
143
  docs: NonEmptyArray<DocumentUri>;
144
144
  };
145
145
  };
@@ -147,6 +147,20 @@ export declare namespace FetchProjects {
147
147
  const req: RequestType0<Res, void>;
148
148
  type Req = typeof req;
149
149
  }
150
+ /**
151
+ * Request from the client to register a project.
152
+ */
153
+ export declare namespace RegisterProject {
154
+ type Params = {
155
+ folderUri: URI;
156
+ config: LikeC4ProjectJsonConfig;
157
+ };
158
+ type Res = {
159
+ id: ProjectId;
160
+ };
161
+ const req: RequestType<Params, Res, void>;
162
+ type Req = typeof req;
163
+ }
150
164
  /**
151
165
  * Request to build documents.
152
166
  */
package/dist/protocol.js CHANGED
@@ -39,6 +39,10 @@ export var FetchProjects;
39
39
  ((FetchProjects2) => {
40
40
  FetchProjects2.req = new RequestType0("likec4/fetch-projects");
41
41
  })(FetchProjects || (FetchProjects = {}));
42
+ export var RegisterProject;
43
+ ((RegisterProject2) => {
44
+ RegisterProject2.req = new RequestType("likec4/register-project");
45
+ })(RegisterProject || (RegisterProject = {}));
42
46
  export var BuildDocuments;
43
47
  ((BuildDocuments2) => {
44
48
  BuildDocuments2.Req = new RequestType("likec4/build");
@@ -1,8 +1,12 @@
1
+ import type { LikeC4ProjectJsonConfig } from '@likec4/config';
1
2
  import type { ComputedLikeC4ModelData } from '@likec4/core';
2
3
  import type { LiteralUnion } from 'type-fest';
3
4
  import { URI } from 'vscode-uri';
4
5
  import type { LikeC4LangiumDocument } from '../ast';
5
- export declare function createTestServices(workspace?: string): {
6
+ export declare function createTestServices(options?: {
7
+ workspace?: string;
8
+ projectConfig?: Partial<LikeC4ProjectJsonConfig>;
9
+ }): {
6
10
  services: any;
7
11
  addDocument: (input: string, uri?: string) => Promise<LikeC4LangiumDocument>;
8
12
  parse: (input: string, uri?: string) => Promise<LikeC4LangiumDocument>;
@@ -6,7 +6,9 @@ import { DiagnosticSeverity } from "vscode-languageserver-types";
6
6
  import { URI, Utils } from "vscode-uri";
7
7
  import { NoopFileSystem } from "../filesystem/index.js";
8
8
  import { createLanguageServices } from "../module.js";
9
- export function createTestServices(workspace = "file:///test/workspace") {
9
+ export function createTestServices(options) {
10
+ const workspace = options?.workspace ?? "file:///test/workspace";
11
+ const projectConfig = options?.projectConfig;
10
12
  const services = createLanguageServices(NoopFileSystem).likec4;
11
13
  const metaData = services.LanguageMetaData;
12
14
  const langiumDocuments = services.shared.workspace.LangiumDocuments;
@@ -15,7 +17,7 @@ export function createTestServices(workspace = "file:///test/workspace") {
15
17
  const workspaceUri = URI.parse(workspace);
16
18
  const formatter = services.lsp.Formatter;
17
19
  const workspaceFolder = {
18
- name: "test",
20
+ name: projectConfig?.name || "test-project",
19
21
  uri: workspaceUri.toString()
20
22
  };
21
23
  let isInitialized = false;
@@ -34,6 +36,19 @@ export function createTestServices(workspace = "file:///test/workspace") {
34
36
  workspaceFolders: [workspaceFolder]
35
37
  });
36
38
  await services.shared.workspace.WorkspaceManager.initializeWorkspace([workspaceFolder]);
39
+ if (projectConfig) {
40
+ const projectFolderUri = Utils.resolvePath(workspaceUri, "src");
41
+ services.shared.workspace.ProjectsManager.registerProject({
42
+ config: {
43
+ name: projectConfig?.name || "test-project",
44
+ title: projectConfig?.title || "Test Project",
45
+ contactPerson: projectConfig?.contactPerson || "Unknown",
46
+ imageAliases: projectConfig?.imageAliases || {},
47
+ exclude: projectConfig?.exclude || ["node_modules"]
48
+ },
49
+ folderUri: projectFolderUri
50
+ });
51
+ }
37
52
  });
38
53
  }
39
54
  const addDocument = async (input, uri) => {
@@ -139,7 +154,7 @@ export async function createMultiProjectTestServices(data) {
139
154
  services,
140
155
  addDocument,
141
156
  validateAll
142
- } = createTestServices(workspace);
157
+ } = createTestServices({ workspace });
143
158
  const projects = {};
144
159
  for (const [name, files] of entries(data)) {
145
160
  const folderUri = UriUtils.joinPath(URI.parse(workspace), "src", name);
@@ -1,4 +1,4 @@
1
- import { Disposable } from 'langium';
1
+ import type { Disposable } from 'langium';
2
2
  export declare abstract class ADisposable implements Disposable {
3
3
  protected toDispose: Disposable[];
4
4
  protected isDisposed: boolean;
@@ -1,4 +1,4 @@
1
- import { stringHash as hash } from "@likec4/core";
1
+ import { stringHash as hash } from "@likec4/core/utils";
2
2
  export function stringHash(...str) {
3
3
  var s = str.length > 1 ? str.join(":::") : str[0];
4
4
  return hash(s);
@@ -1,4 +1,4 @@
1
- import { compareNatural, invariant } from "@likec4/core";
1
+ import { compareNatural, invariant } from "@likec4/core/utils";
2
2
  import { filter, hasAtLeast, isTruthy, map, pipe, unique } from "remeda";
3
3
  import { parsePath } from "ufo";
4
4
  function commonAncestorPath(views, sep = "/") {
@@ -1,10 +1,13 @@
1
1
  import type { NonEmptyArray, ProjectId } from '@likec4/core';
2
- import { type Stream, DefaultLangiumDocuments } from 'langium';
2
+ import type { LangiumDocument, Stream } from 'langium';
3
+ import { DefaultLangiumDocuments } from 'langium';
3
4
  import { type LikeC4LangiumDocument } from '../ast';
4
5
  import type { LikeC4SharedServices } from '../module';
5
6
  export declare class LangiumDocuments extends DefaultLangiumDocuments {
6
7
  protected services: LikeC4SharedServices;
8
+ protected compare: any;
7
9
  constructor(services: LikeC4SharedServices);
10
+ addDocument(document: LangiumDocument): void;
8
11
  /**
9
12
  * Returns all user documents, excluding built-in documents.
10
13
  */
@@ -1,12 +1,27 @@
1
+ import { compareNaturalHierarchically } from "@likec4/core/utils";
1
2
  import { DefaultLangiumDocuments } from "langium";
2
3
  import { groupBy, prop } from "remeda";
3
4
  import { isLikeC4LangiumDocument } from "../ast.js";
4
5
  import { isLikeC4Builtin } from "../likec4lib.js";
6
+ const compare = compareNaturalHierarchically("/", true);
7
+ const ensureOrder = (a, b) => compare(a.uri.path, b.uri.path);
5
8
  export class LangiumDocuments extends DefaultLangiumDocuments {
6
9
  constructor(services) {
7
10
  super(services);
8
11
  this.services = services;
9
12
  }
13
+ compare = compareNaturalHierarchically("/", true);
14
+ addDocument(document) {
15
+ const uriString = document.uri.toString();
16
+ if (this.documentMap.has(uriString)) {
17
+ throw new Error(`A document with the URI '${uriString}' is already present.`);
18
+ }
19
+ const docs = [...this.documentMap.values(), document].sort(ensureOrder);
20
+ this.documentMap.clear();
21
+ for (const doc of docs) {
22
+ this.documentMap.set(doc.uri.toString(), doc);
23
+ }
24
+ }
10
25
  /**
11
26
  * Returns all user documents, excluding built-in documents.
12
27
  */
@@ -1,35 +1,35 @@
1
+ import { type LikeC4ProjectConfig } from '@likec4/config';
1
2
  import type { NonEmptyReadonlyArray, ProjectId } from '@likec4/core';
2
3
  import { type Cancellation, type FileSystemNode, type LangiumDocument, URI, WorkspaceCache } from 'langium';
3
- import picomatch from 'picomatch';
4
4
  import type { Tagged } from 'type-fest';
5
- import { ProjectConfig } from '../config';
6
5
  import type { LikeC4SharedServices } from '../module';
7
6
  /**
8
- * A tagged string that represents a project folder.
7
+ * A tagged string that represents a project folder URI
9
8
  * Always has trailing slash.
10
9
  */
11
10
  export type ProjectFolder = Tagged<string, 'ProjectFolder'>;
12
11
  export declare function ProjectFolder(folder: URI | string): ProjectFolder;
13
12
  interface ProjectData {
14
13
  id: ProjectId;
15
- config: ProjectConfig;
14
+ config: LikeC4ProjectConfig;
16
15
  folder: ProjectFolder;
17
16
  folderUri: URI;
18
- exclude?: picomatch.Matcher;
17
+ exclude?: (path: string) => boolean;
19
18
  }
20
19
  export interface Project {
21
20
  id: ProjectId;
22
21
  folderUri: URI;
23
- config: ProjectConfig;
22
+ config: LikeC4ProjectConfig;
24
23
  }
25
24
  export declare class ProjectsManager {
25
+ #private;
26
26
  protected services: LikeC4SharedServices;
27
27
  /**
28
28
  * The global project ID used for all documents
29
29
  * that are not part of a specific project.
30
30
  */
31
31
  static readonly DefaultProjectId: ProjectId;
32
- static readonly ConfigFileNames: string[];
32
+ private static DefaultProject;
33
33
  /**
34
34
  * The mapping between project config files and project IDs.
35
35
  */
@@ -41,20 +41,30 @@ export declare class ProjectsManager {
41
41
  */
42
42
  private _projects;
43
43
  private excludedDocuments;
44
- private defaultGlobalProject;
44
+ private get defaultGlobalProject();
45
45
  private reloadProjectsLimiter;
46
46
  constructor(services: LikeC4SharedServices);
47
47
  /**
48
48
  * Returns:
49
+ * - configured default project ID if set
49
50
  * - the default project ID if there are no projects.
50
51
  * - the ID of the only project
51
52
  * - undefined if there are multiple projects.
52
53
  */
53
54
  get defaultProjectId(): ProjectId | undefined;
55
+ set defaultProjectId(id: ProjectId | undefined);
54
56
  get all(): NonEmptyReadonlyArray<ProjectId>;
55
57
  getProject(arg: ProjectId | LangiumDocument): Project;
58
+ /**
59
+ * Validates and ensures the project ID.
60
+ * If no project ID is specified, returns default project ID
61
+ * If there are multiple projects and default project is not set, throws an error
62
+ */
56
63
  ensureProjectId(projectId?: ProjectId | undefined): ProjectId;
57
64
  hasMultipleProjects(): boolean;
65
+ /**
66
+ * Checks if the specified document should be excluded from processing.
67
+ */
58
68
  checkIfExcluded(document: LangiumDocument | URI | string): boolean;
59
69
  /**
60
70
  * Checks if it is a config file and it is not excluded by default exclude pattern
@@ -68,15 +78,19 @@ export declare class ProjectsManager {
68
78
  * @param entry The file system entry to check
69
79
  */
70
80
  loadConfigFile(entry: FileSystemNode): Promise<ProjectData | undefined>;
71
- registerProject(configFile: URI): Promise<ProjectData>;
72
- registerProject(opts: {
73
- config: ProjectConfig;
81
+ /**
82
+ * Registers (or reloads) likec4 project by config file or config object.
83
+ * If there is some project registered at same folder, it will be reloaded.
84
+ */
85
+ registerProject(opts: URI | {
86
+ config: LikeC4ProjectConfig;
74
87
  folderUri: URI | string;
75
88
  }): Promise<ProjectData>;
76
89
  belongsTo(document: LangiumDocument | URI | string): ProjectId;
77
90
  reloadProjects(token?: Cancellation.CancellationToken): Promise<void>;
78
91
  protected uniqueProjectId(name: string): ProjectId;
79
92
  protected resetProjectIds(): void;
93
+ protected rebuidDocuments(): Promise<void>;
80
94
  protected findProjectForDocument(documentUri: string): any;
81
95
  protected get mappingsToProject(): WorkspaceCache<string, Pick<ProjectData, 'id' | 'config' | 'exclude'>>;
82
96
  }