@likec4/language-server 0.37.1 → 0.41.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 (60) hide show
  1. package/contrib/likec4.monarch.ts +5 -5
  2. package/contrib/likec4.tmLanguage.json +1 -1
  3. package/dist/Rpc.d.ts +7 -0
  4. package/dist/Rpc.js +130 -0
  5. package/dist/ast.d.ts +20 -0
  6. package/dist/ast.js +169 -141
  7. package/dist/elementRef.js +31 -44
  8. package/dist/generated/ast.d.ts +48 -7
  9. package/dist/generated/ast.js +344 -315
  10. package/dist/generated/grammar.js +2 -3177
  11. package/dist/generated/module.js +13 -18
  12. package/dist/index.js +2 -3
  13. package/dist/logger.js +39 -42
  14. package/dist/lsp/CodeLensProvider.js +28 -32
  15. package/dist/lsp/DocumentLinkProvider.js +26 -33
  16. package/dist/lsp/DocumentSymbolProvider.js +165 -167
  17. package/dist/lsp/HoverProvider.js +35 -48
  18. package/dist/lsp/SemanticTokenProvider.js +160 -201
  19. package/dist/lsp/index.js +5 -6
  20. package/dist/model/fqn-computation.js +39 -40
  21. package/dist/model/fqn-index.js +117 -141
  22. package/dist/model/index.js +5 -6
  23. package/dist/model/model-builder.d.ts +10 -5
  24. package/dist/model/model-builder.js +247 -176
  25. package/dist/model/model-locator.d.ts +1 -1
  26. package/dist/model/model-locator.js +102 -100
  27. package/dist/model/model-parser.d.ts +2 -6
  28. package/dist/model/model-parser.js +284 -286
  29. package/dist/module.d.ts +4 -1
  30. package/dist/module.js +69 -60
  31. package/dist/protocol.d.ts +16 -19
  32. package/dist/protocol.js +14 -22
  33. package/dist/references/index.js +2 -3
  34. package/dist/references/scope-computation.js +72 -69
  35. package/dist/references/scope-provider.js +126 -116
  36. package/dist/shared/WorkspaceManager.d.ts +2 -3
  37. package/dist/shared/WorkspaceManager.js +13 -16
  38. package/dist/shared/index.js +1 -2
  39. package/dist/test/index.js +1 -2
  40. package/dist/test/testServices.js +73 -61
  41. package/dist/utils.d.ts +1 -0
  42. package/dist/utils.js +4 -3
  43. package/dist/validation/element.d.ts +1 -0
  44. package/dist/validation/element.js +31 -38
  45. package/dist/validation/index.js +37 -46
  46. package/dist/validation/relation.js +46 -46
  47. package/dist/validation/specification.d.ts +1 -0
  48. package/dist/validation/specification.js +33 -30
  49. package/dist/validation/view.js +16 -22
  50. package/dist/view-utils/assignNavigateTo.d.ts +3 -0
  51. package/dist/view-utils/assignNavigateTo.js +20 -0
  52. package/dist/view-utils/index.d.ts +4 -0
  53. package/dist/view-utils/index.js +3 -0
  54. package/dist/view-utils/resolve-extended-views.d.ts +7 -0
  55. package/dist/view-utils/resolve-extended-views.js +41 -0
  56. package/dist/view-utils/resolve-relative-paths.d.ts +3 -0
  57. package/dist/view-utils/resolve-relative-paths.js +76 -0
  58. package/package.json +33 -18
  59. package/dist/registerProtocolHandlers.d.ts +0 -3
  60. package/dist/registerProtocolHandlers.js +0 -112
@@ -1,14 +1,13 @@
1
- import type { LangiumDocument, LangiumDocumentFactory, LangiumSharedServices } from 'langium';
1
+ import type { LangiumDocument } from 'langium';
2
2
  import { DefaultWorkspaceManager } from 'langium';
3
3
  import type { WorkspaceFolder } from 'vscode-languageserver';
4
4
  export declare class LikeC4WorkspaceManager extends DefaultWorkspaceManager {
5
- protected readonly documentFactory: LangiumDocumentFactory;
6
- constructor(services: LangiumSharedServices);
7
5
  /**
8
6
  * Load all additional documents that shall be visible in the context of the given workspace
9
7
  * folders and add them to the collector. This can be used to include built-in libraries of
10
8
  * your language, which can be either loaded from provided files or constructed in memory.
11
9
  */
12
10
  protected loadAdditionalDocuments(_folders: WorkspaceFolder[], _collector: (document: LangiumDocument) => void): Promise<void>;
11
+ workspace(): WorkspaceFolder | null;
13
12
  }
14
13
  //# sourceMappingURL=WorkspaceManager.d.ts.map
@@ -1,18 +1,15 @@
1
- import { DefaultWorkspaceManager } from 'langium';
1
+ import { nonNullable } from "@likec4/core";
2
+ import { DefaultWorkspaceManager } from "langium";
2
3
  export class LikeC4WorkspaceManager extends DefaultWorkspaceManager {
3
- documentFactory;
4
- constructor(services) {
5
- super(services);
6
- this.documentFactory = services.workspace.LangiumDocumentFactory;
7
- }
8
- /**
9
- * Load all additional documents that shall be visible in the context of the given workspace
10
- * folders and add them to the collector. This can be used to include built-in libraries of
11
- * your language, which can be either loaded from provided files or constructed in memory.
12
- */
13
- loadAdditionalDocuments(_folders, _collector) {
14
- // collector(this.documentFactory.fromString(builtin.specification.document, URI.parse(builtin.specification.uri)))
15
- return Promise.resolve();
16
- }
4
+ /**
5
+ * Load all additional documents that shall be visible in the context of the given workspace
6
+ * folders and add them to the collector. This can be used to include built-in libraries of
7
+ * your language, which can be either loaded from provided files or constructed in memory.
8
+ */
9
+ loadAdditionalDocuments(_folders, _collector) {
10
+ return Promise.resolve();
11
+ }
12
+ workspace() {
13
+ return this.folders && this.folders.length > 0 ? nonNullable(this.folders[0]) : null;
14
+ }
17
15
  }
18
- //# sourceMappingURL=WorkspaceManager.js.map
@@ -1,2 +1 @@
1
- export * from './WorkspaceManager';
2
- //# sourceMappingURL=index.js.map
1
+ export * from "./WorkspaceManager.js";
@@ -1,2 +1 @@
1
- export * from './testServices';
2
- //# sourceMappingURL=index.js.map
1
+ export * from "./testServices.js";
@@ -1,65 +1,77 @@
1
- import { createLanguageServices } from '../module';
2
- import { EmptyFileSystem } from 'langium';
3
- import { URI, Utils } from 'vscode-uri';
4
- import stripIndent from 'strip-indent';
5
- export function createTestServices(workspace = 'file:///test/workspace') {
6
- const services = createLanguageServices(EmptyFileSystem).likec4;
7
- const metaData = services.LanguageMetaData;
8
- const langiumDocuments = services.shared.workspace.LangiumDocuments;
9
- const documentBuilder = services.shared.workspace.DocumentBuilder;
10
- const modelBuilder = services.likec4.ModelBuilder;
11
- const workspaceUri = URI.parse(workspace);
12
- const initPromise = services.shared.workspace.WorkspaceManager.initializeWorkspace([
13
- {
14
- name: 'test',
15
- uri: workspaceUri.toString()
16
- }
17
- ]);
18
- let documentIndex = 1;
19
- const parse = async (input, uri) => {
20
- await initPromise;
21
- const docUri = Utils.joinPath(workspaceUri, '/src/', uri ?? `${documentIndex++}${metaData.fileExtensions[0]}`);
22
- const document = services.shared.workspace.LangiumDocumentFactory.fromString(stripIndent(input), docUri);
23
- langiumDocuments.addDocument(document);
24
- await documentBuilder.build([document], { validation: false });
25
- return document;
26
- };
27
- const validate = async (input, uri) => {
28
- await initPromise;
29
- const document = typeof input === 'string' ? await parse(input, uri) : input;
30
- await documentBuilder.build([document], { validation: true });
31
- const diagnostics = document.diagnostics ?? [];
32
- const errors = diagnostics.map(d => d.message);
33
- return {
34
- document,
35
- diagnostics,
36
- errors
37
- };
38
- };
39
- const validateAll = async () => {
40
- await initPromise;
41
- const docs = langiumDocuments.all.toArray();
42
- await documentBuilder.build(docs, { validation: true });
43
- const diagnostics = docs.flatMap(doc => doc.diagnostics ?? []);
44
- const errors = diagnostics.map(d => d.message);
45
- return {
46
- diagnostics,
47
- errors
48
- };
49
- };
50
- const buildModel = async () => {
51
- await validateAll();
52
- const model = modelBuilder.buildModel();
53
- if (!model)
54
- throw new Error('No model found');
55
- return model;
1
+ import { createLanguageServices } from "../module.js";
2
+ import { EmptyFileSystem } from "langium";
3
+ import { URI, Utils } from "vscode-uri";
4
+ import stripIndent from "strip-indent";
5
+ export function createTestServices(workspace = "file:///test/workspace") {
6
+ const services = createLanguageServices(EmptyFileSystem).likec4;
7
+ const metaData = services.LanguageMetaData;
8
+ const langiumDocuments = services.shared.workspace.LangiumDocuments;
9
+ const documentBuilder = services.shared.workspace.DocumentBuilder;
10
+ const modelBuilder = services.likec4.ModelBuilder;
11
+ const workspaceUri = URI.parse(workspace);
12
+ const workspaceFolder = {
13
+ name: "test",
14
+ uri: workspaceUri.toString()
15
+ };
16
+ const initPromise = services.shared.workspace.WorkspaceManager.initializeWorkspace([
17
+ workspaceFolder
18
+ ]);
19
+ void initPromise.finally(() => {
20
+ Object.assign(services.shared.workspace.WorkspaceManager, {
21
+ folders: [workspaceFolder]
22
+ });
23
+ });
24
+ let documentIndex = 1;
25
+ const parse = async (input, uri) => {
26
+ await initPromise;
27
+ const docUri = Utils.resolvePath(
28
+ workspaceUri,
29
+ "./src/",
30
+ uri ?? `${documentIndex++}${metaData.fileExtensions[0]}`
31
+ );
32
+ const document = services.shared.workspace.LangiumDocumentFactory.fromString(
33
+ stripIndent(input),
34
+ docUri
35
+ );
36
+ langiumDocuments.addDocument(document);
37
+ await documentBuilder.build([document], { validation: false });
38
+ return document;
39
+ };
40
+ const validate = async (input, uri) => {
41
+ await initPromise;
42
+ const document = typeof input === "string" ? await parse(input, uri) : input;
43
+ await documentBuilder.build([document], { validation: true });
44
+ const diagnostics = document.diagnostics ?? [];
45
+ const errors = diagnostics.map((d) => d.message);
46
+ return {
47
+ document,
48
+ diagnostics,
49
+ errors
56
50
  };
51
+ };
52
+ const validateAll = async () => {
53
+ await initPromise;
54
+ const docs = langiumDocuments.all.toArray();
55
+ await documentBuilder.build(docs, { validation: true });
56
+ const diagnostics = docs.flatMap((doc) => doc.diagnostics ?? []);
57
+ const errors = diagnostics.map((d) => d.message);
57
58
  return {
58
- services,
59
- parse,
60
- validate,
61
- validateAll,
62
- buildModel
59
+ diagnostics,
60
+ errors
63
61
  };
62
+ };
63
+ const buildModel = async () => {
64
+ await validateAll();
65
+ const model = modelBuilder.buildModel();
66
+ if (!model)
67
+ throw new Error("No model found");
68
+ return model;
69
+ };
70
+ return {
71
+ services,
72
+ parse,
73
+ validate,
74
+ validateAll,
75
+ buildModel
76
+ };
64
77
  }
65
- //# sourceMappingURL=testServices.js.map
package/dist/utils.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import type { LangiumDocument } from 'langium';
2
2
  export declare const printDocs: (docs: LangiumDocument[]) => string;
3
+ export declare function queueMicrotask(cb: () => void): Promise<void>;
3
4
  //# sourceMappingURL=utils.d.ts.map
package/dist/utils.js CHANGED
@@ -1,3 +1,4 @@
1
- import { Utils } from 'vscode-uri';
2
- export const printDocs = (docs) => docs.map(d => ' - ' + Utils.basename(d.uri)).join('\n');
3
- //# sourceMappingURL=utils.js.map
1
+ export const printDocs = (docs) => docs.map((d) => " - " + d.uri.path).join("\n");
2
+ export function queueMicrotask(cb) {
3
+ return Promise.resolve().then(cb);
4
+ }
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import { type ValidationCheck } from 'langium';
2
3
  import type { ast } from '../ast';
3
4
  import type { LikeC4Services } from '../module';
@@ -1,41 +1,34 @@
1
- import { getDocument } from 'langium';
1
+ import { getDocument } from "langium";
2
2
  export const elementChecks = (services) => {
3
- const fqnIndex = services.likec4.FqnIndex;
4
- return (el, accept) => {
5
- const fqn = fqnIndex.getFqn(el);
6
- if (!fqn) {
7
- accept('error', 'Not indexed element', {
8
- node: el,
9
- property: 'name'
10
- });
11
- return;
3
+ const fqnIndex = services.likec4.FqnIndex;
4
+ return (el, accept) => {
5
+ const fqn = fqnIndex.getFqn(el);
6
+ if (!fqn) {
7
+ accept("error", "Not indexed element", {
8
+ node: el,
9
+ property: "name"
10
+ });
11
+ return;
12
+ }
13
+ const withSameFqn = fqnIndex.byFqn(fqn).filter((v) => v.el !== el).head();
14
+ if (withSameFqn) {
15
+ accept(
16
+ "error",
17
+ `Duplicate element name ${el.name !== fqn ? el.name + " (" + fqn + ")" : el.name}`,
18
+ {
19
+ node: el,
20
+ property: "name",
21
+ relatedInformation: [
22
+ {
23
+ location: {
24
+ range: withSameFqn.el.$cstNode.range,
25
+ uri: getDocument(withSameFqn.el).uri.toString()
26
+ },
27
+ message: `Already defined here`
28
+ }
29
+ ]
12
30
  }
13
- const withSameFqn = fqnIndex
14
- .byFqn(fqn)
15
- .filter(v => v.el !== el)
16
- .head();
17
- if (withSameFqn) {
18
- accept('error', `Duplicate element name ${el.name !== fqn ? el.name + ' (' + fqn + ')' : el.name}`, {
19
- node: el,
20
- property: 'name',
21
- relatedInformation: [
22
- {
23
- location: {
24
- range: withSameFqn.el.$cstNode.range,
25
- uri: getDocument(withSameFqn.el).uri.toString()
26
- },
27
- message: `Already defined here`
28
- }
29
- ]
30
- });
31
- }
32
- // for (let i = 3; i < el.props.length; i++) {
33
- // accept('error', `Too many properties, max 3 allowed`, {
34
- // node: el,
35
- // property: 'props',
36
- // index: i
37
- // })
38
- // }
39
- };
31
+ );
32
+ }
33
+ };
40
34
  };
41
- //# sourceMappingURL=element.js.map
@@ -1,49 +1,40 @@
1
- import { Utils } from 'vscode-uri';
2
- import { logger } from '../logger';
3
- import { elementChecks } from './element';
4
- import { relationChecks } from './relation';
5
- import { elementKindChecks, tagChecks } from './specification';
6
- import { viewChecks } from './view';
1
+ import * as vscodeUri from "vscode-uri";
2
+ import { logger } from "../logger.js";
3
+ import { elementChecks } from "./element.js";
4
+ import { relationChecks } from "./relation.js";
5
+ import { elementKindChecks, tagChecks, relationshipChecks } from "./specification.js";
6
+ import { viewChecks } from "./view.js";
7
7
  export function registerValidationChecks(services) {
8
- logger.info('registerValidationChecks');
9
- const registry = services.validation.ValidationRegistry;
10
- // const checks: ValidationChecks = {
11
- // Element: validator.checkElementNameDuplicates,
12
- // Tag: validator.checkTagDuplicates,
13
- // ElementKind: elementKindChecks(services),
14
- // ElementStyleProperty: validator.checkElementStyleProperty,
15
- // View: validator.checkViewNameDuplicates,
16
- // ColorStyleProperty: validator.checkColorStyleProperty,
17
- // }
18
- registry.register({
19
- ElementView: viewChecks(services),
20
- Element: elementChecks(services),
21
- ElementKind: elementKindChecks(services),
22
- Relation: relationChecks(services),
23
- Tag: tagChecks(services)
24
- });
25
- const connection = services.shared.lsp.Connection;
26
- if (connection) {
27
- logger.info('registerValidationChecks');
28
- // wokraround for bug in langium
29
- services.shared.workspace.DocumentBuilder.onUpdate((changed, deleted) => {
30
- const message = [`[DocumentBuilder.onUpdate]`];
31
- if (changed.length > 0) {
32
- message.push(` changed:`);
33
- changed.forEach(u => message.push(` - ${Utils.basename(u)}`));
34
- }
35
- if (deleted.length > 0) {
36
- message.push(` deleted:`);
37
- deleted.forEach(u => message.push(` - ${Utils.basename(u)}`));
38
- }
39
- logger.debug(message.join('\n'));
40
- for (const uri of deleted) {
41
- void connection.sendDiagnostics({
42
- uri: uri.toString(),
43
- diagnostics: []
44
- });
45
- }
8
+ logger.info("registerValidationChecks");
9
+ const registry = services.validation.ValidationRegistry;
10
+ registry.register({
11
+ ElementView: viewChecks(services),
12
+ Element: elementChecks(services),
13
+ ElementKind: elementKindChecks(services),
14
+ Relation: relationChecks(services),
15
+ Tag: tagChecks(services),
16
+ RelationshipKind: relationshipChecks(services)
17
+ });
18
+ const connection = services.shared.lsp.Connection;
19
+ if (connection) {
20
+ logger.info("registerValidationChecks");
21
+ services.shared.workspace.DocumentBuilder.onUpdate((changed, deleted) => {
22
+ const message = [`[DocumentBuilder.onUpdate]`];
23
+ if (changed.length > 0) {
24
+ message.push(` changed:`);
25
+ changed.forEach((u) => message.push(` - ${vscodeUri.Utils.basename(u)}`));
26
+ }
27
+ if (deleted.length > 0) {
28
+ message.push(` deleted:`);
29
+ deleted.forEach((u) => message.push(` - ${vscodeUri.Utils.basename(u)}`));
30
+ }
31
+ logger.debug(message.join("\n"));
32
+ for (const uri of deleted) {
33
+ void connection.sendDiagnostics({
34
+ uri: uri.toString(),
35
+ diagnostics: []
46
36
  });
47
- }
37
+ }
38
+ });
39
+ }
48
40
  }
49
- //# sourceMappingURL=index.js.map
@@ -1,50 +1,50 @@
1
- import { isSameHierarchy } from '@likec4/core';
2
- import { ast } from '../ast';
3
- import { elementRef } from '../elementRef';
4
- import { logError } from '../logger';
1
+ import { isSameHierarchy } from "@likec4/core";
2
+ import { ast } from "../ast.js";
3
+ import { elementRef } from "../elementRef.js";
4
+ import { logError } from "../logger.js";
5
5
  export const relationChecks = (services) => {
6
- const fqnIndex = services.likec4.FqnIndex;
7
- return (el, accept) => {
8
- try {
9
- const targetEl = elementRef(el.target);
10
- const target = targetEl && fqnIndex.getFqn(targetEl);
11
- if (!target) {
12
- accept('error', 'Target not found (not parsed/indexed yet)', {
13
- node: el,
14
- property: 'target'
15
- });
6
+ const fqnIndex = services.likec4.FqnIndex;
7
+ return (el, accept) => {
8
+ try {
9
+ const targetEl = elementRef(el.target);
10
+ const target = targetEl && fqnIndex.getFqn(targetEl);
11
+ if (!target) {
12
+ accept("error", "Target not found (not parsed/indexed yet)", {
13
+ node: el,
14
+ property: "target"
15
+ });
16
+ }
17
+ let sourceEl;
18
+ if ("source" in el) {
19
+ sourceEl = elementRef(el.source);
20
+ } else {
21
+ if (!ast.isElementBody(el.$container)) {
22
+ accept(
23
+ "error",
24
+ "Invalid relation, expected to have source defined or be inside the element",
25
+ {
26
+ node: el,
27
+ keyword: "->"
16
28
  }
17
- let sourceEl;
18
- if ('source' in el) {
19
- sourceEl = elementRef(el.source);
20
- }
21
- else {
22
- if (!ast.isElementBody(el.$container)) {
23
- accept('error', 'Invalid relation, expected to have source defined or be inside the element', {
24
- node: el,
25
- keyword: '->'
26
- });
27
- }
28
- else {
29
- sourceEl = el.$container.$container;
30
- }
31
- }
32
- const source = sourceEl && fqnIndex.getFqn(sourceEl);
33
- if (sourceEl && !source) {
34
- accept('error', 'Source not found (not parsed/indexed yet)', {
35
- node: el,
36
- property: 'source'
37
- });
38
- }
39
- if (source && target && isSameHierarchy(source, target)) {
40
- return accept('error', 'Invalid parent-child relationship', {
41
- node: el
42
- });
43
- }
44
- }
45
- catch (e) {
46
- logError(e);
29
+ );
30
+ } else {
31
+ sourceEl = el.$container.$container;
47
32
  }
48
- };
33
+ }
34
+ const source = sourceEl && fqnIndex.getFqn(sourceEl);
35
+ if (sourceEl && !source) {
36
+ accept("error", "Source not found (not parsed/indexed yet)", {
37
+ node: el,
38
+ property: "source"
39
+ });
40
+ }
41
+ if (source && target && isSameHierarchy(source, target)) {
42
+ return accept("error", "Invalid parent-child relationship", {
43
+ node: el
44
+ });
45
+ }
46
+ } catch (e) {
47
+ logError(e);
48
+ }
49
+ };
49
50
  };
50
- //# sourceMappingURL=relation.js.map
@@ -3,4 +3,5 @@ import { ast } from '../ast';
3
3
  import type { LikeC4Services } from '../module';
4
4
  export declare const elementKindChecks: (services: LikeC4Services) => ValidationCheck<ast.ElementKind>;
5
5
  export declare const tagChecks: (services: LikeC4Services) => ValidationCheck<ast.Tag>;
6
+ export declare const relationshipChecks: (services: LikeC4Services) => ValidationCheck<ast.RelationshipKind>;
6
7
  //# sourceMappingURL=specification.d.ts.map
@@ -1,34 +1,37 @@
1
- import { ast } from '../ast';
1
+ import { ast } from "../ast.js";
2
2
  export const elementKindChecks = (services) => {
3
- const index = services.shared.workspace.IndexManager;
4
- return (node, accept) => {
5
- const sameKinds = index
6
- .allElements(ast.ElementKind)
7
- .filter(n => n.name === node.name)
8
- .limit(2)
9
- .count();
10
- if (sameKinds > 1) {
11
- accept('error', `Duplicate element kind '${node.name}'`, {
12
- node: node,
13
- property: 'name'
14
- });
15
- }
16
- };
3
+ const index = services.shared.workspace.IndexManager;
4
+ return (node, accept) => {
5
+ const sameKinds = index.allElements(ast.ElementKind).filter((n) => n.name === node.name).limit(2).count();
6
+ if (sameKinds > 1) {
7
+ accept("error", `Duplicate element kind '${node.name}'`, {
8
+ node,
9
+ property: "name"
10
+ });
11
+ }
12
+ };
17
13
  };
18
14
  export const tagChecks = (services) => {
19
- const index = services.shared.workspace.IndexManager;
20
- return (node, accept) => {
21
- const sameKinds = index
22
- .allElements(ast.Tag)
23
- .filter(n => n.name === node.name)
24
- .limit(2)
25
- .count();
26
- if (sameKinds > 1) {
27
- accept('error', `Duplicate tag '${node.name}'`, {
28
- node: node,
29
- property: 'name'
30
- });
31
- }
32
- };
15
+ const index = services.shared.workspace.IndexManager;
16
+ return (node, accept) => {
17
+ const sameKinds = index.allElements(ast.Tag).filter((n) => n.name === node.name).limit(2).count();
18
+ if (sameKinds > 1) {
19
+ accept("error", `Duplicate tag '${node.name}'`, {
20
+ node,
21
+ property: "name"
22
+ });
23
+ }
24
+ };
25
+ };
26
+ export const relationshipChecks = (services) => {
27
+ const index = services.shared.workspace.IndexManager;
28
+ return (node, accept) => {
29
+ const sameKinds = index.allElements(ast.RelationshipKind).filter((n) => n.name === node.name).limit(2).count();
30
+ if (sameKinds > 1) {
31
+ accept("error", `Duplicate RelationshipKind '${node.name}'`, {
32
+ node,
33
+ property: "name"
34
+ });
35
+ }
36
+ };
33
37
  };
34
- //# sourceMappingURL=specification.js.map
@@ -1,24 +1,18 @@
1
- import { ast } from '../ast';
1
+ import { ast } from "../ast.js";
2
2
  export const viewChecks = (services) => {
3
- const index = services.shared.workspace.IndexManager;
4
- return (el, accept) => {
5
- if (el.extends) {
6
- // TODO: circular dependency check
7
- }
8
- if (!el.name) {
9
- return;
10
- }
11
- const anotherViews = index
12
- .allElements(ast.View)
13
- .filter(n => n.name === el.name)
14
- .limit(2)
15
- .count();
16
- if (anotherViews > 1) {
17
- accept('error', `Duplicate view '${el.name}'`, {
18
- node: el,
19
- property: 'name'
20
- });
21
- }
22
- };
3
+ const index = services.shared.workspace.IndexManager;
4
+ return (el, accept) => {
5
+ if (el.extends) {
6
+ }
7
+ if (!el.name) {
8
+ return;
9
+ }
10
+ const anotherViews = index.allElements(ast.View).filter((n) => n.name === el.name).limit(2).count();
11
+ if (anotherViews > 1) {
12
+ accept("error", `Duplicate view '${el.name}'`, {
13
+ node: el,
14
+ property: "name"
15
+ });
16
+ }
17
+ };
23
18
  };
24
- //# sourceMappingURL=view.js.map
@@ -0,0 +1,3 @@
1
+ import type { ComputedView } from '@likec4/core';
2
+ export declare function assignNavigateTo<R extends Iterable<ComputedView>>(views: R): R;
3
+ //# sourceMappingURL=assignNavigateTo.d.ts.map
@@ -0,0 +1,20 @@
1
+ import { find } from "remeda";
2
+ export function assignNavigateTo(views) {
3
+ const allElementViews = /* @__PURE__ */ new Map();
4
+ for (const v of views) {
5
+ if (v.viewOf && !v.extends) {
6
+ const viewsOf = allElementViews.get(v.viewOf) ?? [];
7
+ viewsOf.push(v.id);
8
+ allElementViews.set(v.viewOf, viewsOf);
9
+ }
10
+ }
11
+ for (const { id, nodes } of views) {
12
+ for (const node of nodes) {
13
+ const navigateTo = find(allElementViews.get(node.id) ?? [], (v) => v !== id);
14
+ if (navigateTo) {
15
+ node.navigateTo = navigateTo;
16
+ }
17
+ }
18
+ }
19
+ return views;
20
+ }
@@ -0,0 +1,4 @@
1
+ export * from './assignNavigateTo';
2
+ export * from './resolve-extended-views';
3
+ export * from './resolve-relative-paths';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ export * from "./assignNavigateTo.js";
2
+ export * from "./resolve-extended-views.js";
3
+ export * from "./resolve-relative-paths.js";
@@ -0,0 +1,7 @@
1
+ import { type ElementView } from '@likec4/core';
2
+ /**
3
+ * Resolve rules of extended views
4
+ * (Removes invalid views)
5
+ */
6
+ export declare function resolveRulesExtendedViews<V extends Record<any, ElementView>>(unresolvedViews: V): V;
7
+ //# sourceMappingURL=resolve-extended-views.d.ts.map