@likec4/language-server 1.17.1 → 1.19.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 (268) hide show
  1. package/contrib/likec4.tmLanguage.json +1 -1
  2. package/dist/LikeC4FileSystem.d.ts +13 -0
  3. package/dist/LikeC4FileSystem.js +27 -0
  4. package/dist/Rpc.d.ts +9 -0
  5. package/dist/Rpc.js +126 -0
  6. package/dist/ast.d.ts +200 -0
  7. package/dist/ast.js +276 -0
  8. package/dist/browser.d.ts +6 -20
  9. package/dist/browser.js +13 -0
  10. package/dist/formatting/LikeC4Formatter.d.ts +27 -0
  11. package/dist/formatting/LikeC4Formatter.js +261 -0
  12. package/dist/formatting/utils.d.ts +6 -0
  13. package/dist/formatting/utils.js +15 -0
  14. package/dist/generated/ast.d.ts +1242 -0
  15. package/dist/generated/ast.js +1945 -0
  16. package/dist/generated/grammar.d.ts +6 -0
  17. package/dist/generated/grammar.js +3 -0
  18. package/dist/generated/module.d.ts +9 -0
  19. package/dist/generated/module.js +23 -0
  20. package/dist/generated-lib/icons.d.ts +1 -0
  21. package/dist/{likec4lib.mjs → generated-lib/icons.js} +1 -6
  22. package/dist/index.d.ts +8 -31
  23. package/dist/index.js +13 -0
  24. package/dist/like-c4.langium +845 -0
  25. package/dist/likec4lib.d.ts +4 -6
  26. package/dist/likec4lib.js +4 -0
  27. package/dist/logger.d.ts +7 -0
  28. package/dist/logger.js +73 -0
  29. package/dist/lsp/CodeLensProvider.d.ts +9 -0
  30. package/dist/lsp/CodeLensProvider.js +40 -0
  31. package/dist/lsp/CompletionProvider.d.ts +6 -0
  32. package/dist/lsp/CompletionProvider.js +135 -0
  33. package/dist/lsp/DocumentHighlightProvider.d.ts +9 -0
  34. package/dist/lsp/DocumentHighlightProvider.js +10 -0
  35. package/dist/lsp/DocumentLinkProvider.d.ts +11 -0
  36. package/dist/lsp/DocumentLinkProvider.js +49 -0
  37. package/dist/lsp/DocumentSymbolProvider.d.ts +23 -0
  38. package/dist/lsp/DocumentSymbolProvider.js +202 -0
  39. package/dist/lsp/HoverProvider.d.ts +10 -0
  40. package/dist/lsp/HoverProvider.js +69 -0
  41. package/dist/lsp/RenameProvider.d.ts +5 -0
  42. package/dist/lsp/RenameProvider.js +6 -0
  43. package/dist/lsp/SemanticTokenProvider.d.ts +7 -0
  44. package/dist/lsp/SemanticTokenProvider.js +297 -0
  45. package/dist/lsp/index.d.ts +7 -0
  46. package/dist/lsp/index.js +7 -0
  47. package/dist/model/deployments-index.d.ts +60 -0
  48. package/dist/model/deployments-index.js +181 -0
  49. package/dist/model/fqn-computation.d.ts +3 -0
  50. package/dist/model/fqn-computation.js +72 -0
  51. package/dist/model/fqn-index.d.ts +25 -0
  52. package/dist/model/fqn-index.js +96 -0
  53. package/dist/model/index.d.ts +6 -0
  54. package/dist/model/index.js +6 -0
  55. package/dist/model/model-builder.d.ts +32 -0
  56. package/dist/model/model-builder.js +598 -0
  57. package/dist/model/model-locator.d.ts +23 -0
  58. package/dist/model/model-locator.js +126 -0
  59. package/dist/model/model-parser-where.d.ts +3 -0
  60. package/dist/model/model-parser-where.js +70 -0
  61. package/dist/model/model-parser.d.ts +292 -0
  62. package/dist/model/model-parser.js +72 -0
  63. package/dist/model/parser/Base.d.ts +28 -0
  64. package/dist/model/parser/Base.js +87 -0
  65. package/dist/model/parser/DeploymentModelParser.d.ts +33 -0
  66. package/dist/model/parser/DeploymentModelParser.js +162 -0
  67. package/dist/model/parser/DeploymentViewParser.d.ts +38 -0
  68. package/dist/model/parser/DeploymentViewParser.js +98 -0
  69. package/dist/model/parser/FqnRefParser.d.ts +29 -0
  70. package/dist/model/parser/FqnRefParser.js +108 -0
  71. package/dist/model/parser/GlobalsParser.d.ts +66 -0
  72. package/dist/model/parser/GlobalsParser.js +80 -0
  73. package/dist/model/parser/ModelParser.d.ts +27 -0
  74. package/dist/model/parser/ModelParser.js +122 -0
  75. package/dist/model/parser/PredicatesParser.d.ts +34 -0
  76. package/dist/model/parser/PredicatesParser.js +272 -0
  77. package/dist/model/parser/SpecificationParser.d.ts +27 -0
  78. package/dist/model/parser/SpecificationParser.js +120 -0
  79. package/dist/model/parser/ViewsParser.d.ts +64 -0
  80. package/dist/model/parser/ViewsParser.js +377 -0
  81. package/dist/model-change/ModelChanges.d.ts +15 -0
  82. package/dist/model-change/ModelChanges.js +89 -0
  83. package/dist/model-change/changeElementStyle.d.ts +16 -0
  84. package/dist/model-change/changeElementStyle.js +136 -0
  85. package/dist/model-change/changeViewLayout.d.ts +12 -0
  86. package/dist/model-change/changeViewLayout.js +32 -0
  87. package/dist/model-change/saveManualLayout.d.ts +11 -0
  88. package/dist/model-change/saveManualLayout.js +27 -0
  89. package/dist/module.d.ts +62 -0
  90. package/dist/module.js +123 -0
  91. package/dist/protocol.d.ts +27 -27
  92. package/dist/protocol.js +14 -0
  93. package/dist/references/index.d.ts +3 -0
  94. package/dist/references/index.js +3 -0
  95. package/dist/references/name-provider.d.ts +9 -0
  96. package/dist/references/name-provider.js +33 -0
  97. package/dist/references/scope-computation.d.ts +20 -0
  98. package/dist/references/scope-computation.js +281 -0
  99. package/dist/references/scope-provider.d.ts +16 -0
  100. package/dist/references/scope-provider.js +165 -0
  101. package/dist/shared/NodeKindProvider.d.ts +15 -0
  102. package/dist/shared/NodeKindProvider.js +108 -0
  103. package/dist/shared/WorkspaceManager.d.ts +18 -0
  104. package/dist/shared/WorkspaceManager.js +36 -0
  105. package/dist/shared/WorkspaceSymbolProvider.d.ts +3 -0
  106. package/dist/shared/WorkspaceSymbolProvider.js +3 -0
  107. package/dist/shared/index.d.ts +3 -0
  108. package/dist/shared/index.js +3 -0
  109. package/dist/test/index.d.ts +1 -0
  110. package/dist/test/index.js +1 -0
  111. package/dist/test/setup.d.ts +1 -0
  112. package/dist/test/setup.js +7 -0
  113. package/dist/test/testServices.d.ts +22 -0
  114. package/dist/test/testServices.js +119 -0
  115. package/dist/utils/elementRef.d.ts +11 -0
  116. package/dist/utils/elementRef.js +15 -0
  117. package/dist/utils/fqnRef.d.ts +8 -0
  118. package/dist/utils/fqnRef.js +46 -0
  119. package/dist/utils/index.d.ts +1 -0
  120. package/dist/utils/index.js +1 -0
  121. package/dist/utils/printDocs.d.ts +2 -0
  122. package/dist/utils/printDocs.js +1 -0
  123. package/dist/utils/stringHash.d.ts +1 -0
  124. package/dist/utils/stringHash.js +5 -0
  125. package/dist/validation/_shared.d.ts +3 -0
  126. package/dist/validation/_shared.js +22 -0
  127. package/dist/validation/deployment-checks.d.ts +6 -0
  128. package/dist/validation/deployment-checks.js +114 -0
  129. package/dist/validation/dynamic-view-rule.d.ts +4 -0
  130. package/dist/validation/dynamic-view-rule.js +16 -0
  131. package/dist/validation/dynamic-view-step.d.ts +4 -0
  132. package/dist/validation/dynamic-view-step.js +33 -0
  133. package/dist/validation/element.d.ts +4 -0
  134. package/dist/validation/element.js +49 -0
  135. package/dist/validation/index.d.ts +15 -0
  136. package/dist/validation/index.js +152 -0
  137. package/dist/validation/property-checks.d.ts +6 -0
  138. package/dist/validation/property-checks.js +38 -0
  139. package/dist/validation/relation.d.ts +5 -0
  140. package/dist/validation/relation.js +56 -0
  141. package/dist/validation/specification.d.ts +11 -0
  142. package/dist/validation/specification.js +136 -0
  143. package/dist/validation/view-predicates/element-with.d.ts +4 -0
  144. package/dist/validation/view-predicates/element-with.js +30 -0
  145. package/dist/validation/view-predicates/expanded-element.d.ts +4 -0
  146. package/dist/validation/view-predicates/expanded-element.js +11 -0
  147. package/dist/validation/view-predicates/expression-v2.d.ts +5 -0
  148. package/dist/validation/view-predicates/expression-v2.js +83 -0
  149. package/dist/validation/view-predicates/incoming.d.ts +4 -0
  150. package/dist/validation/view-predicates/incoming.js +15 -0
  151. package/dist/validation/view-predicates/index.d.ts +6 -0
  152. package/dist/validation/view-predicates/index.js +6 -0
  153. package/dist/validation/view-predicates/outgoing.d.ts +4 -0
  154. package/dist/validation/view-predicates/outgoing.js +15 -0
  155. package/dist/validation/view-predicates/relation-with.d.ts +4 -0
  156. package/dist/validation/view-predicates/relation-with.js +12 -0
  157. package/dist/validation/view.d.ts +4 -0
  158. package/dist/validation/view.js +23 -0
  159. package/dist/view-utils/assignNavigateTo.d.ts +2 -0
  160. package/dist/view-utils/assignNavigateTo.js +25 -0
  161. package/dist/view-utils/index.d.ts +2 -0
  162. package/dist/view-utils/index.js +2 -0
  163. package/dist/view-utils/manual-layout.d.ts +7 -0
  164. package/dist/view-utils/manual-layout.js +99 -0
  165. package/dist/view-utils/resolve-relative-paths.d.ts +2 -0
  166. package/dist/view-utils/resolve-relative-paths.js +78 -0
  167. package/package.json +42 -73
  168. package/src/LikeC4FileSystem.ts +22 -21
  169. package/src/Rpc.ts +6 -3
  170. package/src/ast.ts +136 -172
  171. package/src/browser.ts +10 -11
  172. package/src/generated/ast.ts +656 -40
  173. package/src/generated/grammar.ts +1 -1
  174. package/src/index.ts +11 -8
  175. package/src/like-c4.langium +173 -22
  176. package/src/logger.ts +41 -57
  177. package/src/lsp/CodeLensProvider.ts +0 -1
  178. package/src/lsp/CompletionProvider.ts +20 -5
  179. package/src/lsp/DocumentSymbolProvider.ts +5 -2
  180. package/src/lsp/HoverProvider.ts +37 -3
  181. package/src/lsp/SemanticTokenProvider.ts +58 -32
  182. package/src/model/deployments-index.ts +222 -0
  183. package/src/model/fqn-computation.ts +1 -1
  184. package/src/model/fqn-index.ts +0 -1
  185. package/src/model/index.ts +1 -0
  186. package/src/model/model-builder.ts +176 -39
  187. package/src/model/model-locator.ts +36 -7
  188. package/src/model/model-parser.ts +69 -1119
  189. package/src/model/parser/Base.ts +107 -0
  190. package/src/model/parser/DeploymentModelParser.ts +192 -0
  191. package/src/model/parser/DeploymentViewParser.ts +116 -0
  192. package/src/model/parser/FqnRefParser.ts +118 -0
  193. package/src/model/parser/GlobalsParser.ts +96 -0
  194. package/src/model/parser/ModelParser.ts +141 -0
  195. package/src/model/parser/PredicatesParser.ts +291 -0
  196. package/src/model/parser/SpecificationParser.ts +133 -0
  197. package/src/model/parser/ViewsParser.ts +428 -0
  198. package/src/model-change/changeViewLayout.ts +2 -2
  199. package/src/module.ts +26 -21
  200. package/src/protocol.ts +10 -6
  201. package/src/references/index.ts +1 -0
  202. package/src/references/name-provider.ts +37 -0
  203. package/src/references/scope-computation.ts +130 -21
  204. package/src/references/scope-provider.ts +68 -35
  205. package/src/shared/NodeKindProvider.ts +15 -3
  206. package/src/{elementRef.ts → utils/elementRef.ts} +1 -1
  207. package/src/utils/fqnRef.ts +56 -0
  208. package/src/utils/stringHash.ts +2 -2
  209. package/src/validation/_shared.ts +6 -5
  210. package/src/validation/deployment-checks.ts +131 -0
  211. package/src/validation/dynamic-view-step.ts +1 -1
  212. package/src/validation/index.ts +104 -6
  213. package/src/validation/relation.ts +1 -1
  214. package/src/validation/view-predicates/expression-v2.ts +101 -0
  215. package/src/validation/view-predicates/index.ts +1 -0
  216. package/src/view-utils/assignNavigateTo.ts +6 -5
  217. package/src/view-utils/index.ts +0 -1
  218. package/src/view-utils/manual-layout.ts +25 -0
  219. package/dist/browser.cjs +0 -25
  220. package/dist/browser.d.cts +0 -23
  221. package/dist/browser.d.mts +0 -23
  222. package/dist/browser.mjs +0 -20
  223. package/dist/index.cjs +0 -53
  224. package/dist/index.d.cts +0 -34
  225. package/dist/index.d.mts +0 -34
  226. package/dist/index.mjs +0 -46
  227. package/dist/likec4lib.cjs +0 -1546
  228. package/dist/likec4lib.d.cts +0 -6
  229. package/dist/likec4lib.d.mts +0 -6
  230. package/dist/model-graph/index.cjs +0 -10
  231. package/dist/model-graph/index.d.cts +0 -81
  232. package/dist/model-graph/index.d.mts +0 -81
  233. package/dist/model-graph/index.d.ts +0 -81
  234. package/dist/model-graph/index.mjs +0 -1
  235. package/dist/protocol.cjs +0 -25
  236. package/dist/protocol.d.cts +0 -45
  237. package/dist/protocol.d.mts +0 -45
  238. package/dist/protocol.mjs +0 -17
  239. package/dist/shared/language-server.BIbAD1T-.mjs +0 -6292
  240. package/dist/shared/language-server.BQRvVmE0.d.cts +0 -1303
  241. package/dist/shared/language-server.BysPcTxr.d.ts +0 -1303
  242. package/dist/shared/language-server.D2QdbOJO.cjs +0 -1995
  243. package/dist/shared/language-server.DGrBGmsd.mjs +0 -1981
  244. package/dist/shared/language-server.DKV_FdPN.cjs +0 -6304
  245. package/dist/shared/language-server._wkyPgso.d.mts +0 -1303
  246. package/src/model-graph/LikeC4ModelGraph.ts +0 -338
  247. package/src/model-graph/compute-view/__test__/fixture.ts +0 -630
  248. package/src/model-graph/compute-view/compute.ts +0 -788
  249. package/src/model-graph/compute-view/index.ts +0 -33
  250. package/src/model-graph/compute-view/predicates.ts +0 -509
  251. package/src/model-graph/dynamic-view/__test__/fixture.ts +0 -61
  252. package/src/model-graph/dynamic-view/compute.ts +0 -313
  253. package/src/model-graph/dynamic-view/index.ts +0 -29
  254. package/src/model-graph/index.ts +0 -3
  255. package/src/model-graph/utils/applyCustomElementProperties.ts +0 -65
  256. package/src/model-graph/utils/applyCustomRelationProperties.ts +0 -41
  257. package/src/model-graph/utils/applyViewRuleStyles.ts +0 -49
  258. package/src/model-graph/utils/buildComputeNodes.ts +0 -113
  259. package/src/model-graph/utils/buildElementNotations.ts +0 -63
  260. package/src/model-graph/utils/elementExpressionToPredicate.ts +0 -39
  261. package/src/model-graph/utils/relationExpressionToPredicates.ts +0 -43
  262. package/src/model-graph/utils/sortNodes.ts +0 -105
  263. package/src/model-graph/utils/uniqueTags.test.ts +0 -42
  264. package/src/model-graph/utils/uniqueTags.ts +0 -19
  265. package/src/utils/graphlib.ts +0 -9
  266. package/src/view-utils/resolve-extended-views.ts +0 -66
  267. package/src/view-utils/resolve-global-rules.ts +0 -88
  268. package/src/view-utils/view-hash.ts +0 -27
@@ -1,33 +0,0 @@
1
- import { type ComputedElementView, type ElementView } from '@likec4/core'
2
- import type { LikeC4ModelGraph } from '../LikeC4ModelGraph'
3
- import { ComputeCtx } from './compute'
4
-
5
- export function computeElementView(view: ElementView, graph: LikeC4ModelGraph) {
6
- return ComputeCtx.elementView(view, graph)
7
- }
8
-
9
- type ComputeViewResult =
10
- | {
11
- isSuccess: true
12
- view: ComputedElementView
13
- }
14
- | {
15
- isSuccess: false
16
- error: Error
17
- view: undefined
18
- }
19
-
20
- export function computeView(view: ElementView, graph: LikeC4ModelGraph): ComputeViewResult {
21
- try {
22
- return {
23
- isSuccess: true,
24
- view: computeElementView(view, graph)
25
- }
26
- } catch (e) {
27
- return {
28
- isSuccess: false,
29
- error: e instanceof Error ? e : new Error(`Unknown error: ${e}`),
30
- view: undefined
31
- }
32
- }
33
- }
@@ -1,509 +0,0 @@
1
- import type { Element, Relation } from '@likec4/core'
2
- import { Expr, isAncestor, nonexhaustive, parentFqn } from '@likec4/core'
3
- import { allPass, filter as remedaFilter, flatMap, isNullish as isNil, map, pipe, unique } from 'remeda'
4
- import { elementExprToPredicate } from '../utils/elementExpressionToPredicate'
5
- import type { ComputeCtx } from './compute'
6
-
7
- type Predicate<T> = (x: T) => boolean
8
- export type ElementPredicateFn = Predicate<Element>
9
- export type RelationPredicateFn = Predicate<Relation>
10
- // // type ElementPredicate = Predicate<Element>
11
- // type ElementPredicates<T> = T extends Element[] ? (x: T) => T : (T extends Element ? (x: T) => (Element | null) : never)
12
- // type ElementPredicate = ElementPredicates<Element | Element[]>
13
-
14
- const NoFilter: ElementPredicateFn = () => true
15
- const Identity = <T>(x: T) => x
16
- const filterBy = <T>(pred: Predicate<T>) => pred === NoFilter ? Identity : remedaFilter(pred)
17
- const filterOne = <T>(pred: Predicate<T>) => pred === NoFilter ? Identity : (x: T) => pred(x) ? x : null
18
-
19
- export function includeElementRef(this: ComputeCtx, expr: Expr.ElementRefExpr, where = NoFilter) {
20
- // Get the elements that are already in the Ctx before any mutations
21
- // Because we need to add edges between them and the new elements
22
- const currentElements = [...this.resolvedElements]
23
- const filter = filterBy(where)
24
-
25
- const elements = filter(
26
- expr.isDescedants === true
27
- ? this.graph.childrenOrElement(expr.element)
28
- : [this.graph.element(expr.element)]
29
- )
30
- if (elements.length === 0) {
31
- return
32
- }
33
-
34
- this.addElement(...elements)
35
-
36
- if (elements.length > 1) {
37
- this.addEdges(this.graph.edgesWithin(elements))
38
- }
39
-
40
- if (currentElements.length > 0 && elements.length > 0) {
41
- for (const el of elements) {
42
- this.addEdges(this.graph.anyEdgesBetween(el, currentElements))
43
- }
44
- }
45
- }
46
-
47
- export function excludeElementRef(this: ComputeCtx, expr: Expr.ElementRefExpr, where = NoFilter) {
48
- const elements = [...this.resolvedElements].filter(allPass([
49
- elementExprToPredicate(expr),
50
- where
51
- ]))
52
- this.excludeElement(...elements)
53
- }
54
-
55
- export function includeWildcardRef(this: ComputeCtx, _expr: Expr.WildcardExpr, where = NoFilter) {
56
- const root = this.root
57
- if (!root) {
58
- // Take root elements
59
- const elements = this.graph.rootElements.filter(where)
60
- if (elements.length <= 0) {
61
- return
62
- }
63
- const currentElements = [...this.resolvedElements]
64
- this.addElement(...elements)
65
- this.addEdges(this.graph.edgesWithin(elements))
66
- if (currentElements.length > 0) {
67
- for (const el of elements) {
68
- this.addEdges(this.graph.anyEdgesBetween(el, currentElements))
69
- }
70
- }
71
- return
72
- }
73
-
74
- const currentElements = [...this.resolvedElements]
75
- const _elRoot = filterOne(where)(this.graph.element(root))
76
- if (_elRoot) {
77
- this.addElement(_elRoot)
78
- }
79
- const filter = filterBy(where)
80
-
81
- const children = filter(this.graph.children(root))
82
- const hasChildren = children.length > 0
83
- if (hasChildren) {
84
- this.addElement(...children)
85
- this.addEdges(this.graph.edgesWithin(children))
86
- } else if (_elRoot) {
87
- children.push(_elRoot)
88
- }
89
-
90
- // All neighbours that may have relations with root or its children
91
- const neighbours = [
92
- ...currentElements,
93
- ...filter([
94
- ...this.graph.siblings(root),
95
- ...this.graph.ancestors(root).flatMap(a => this.graph.siblings(a.id))
96
- ])
97
- ]
98
-
99
- for (const el of children) {
100
- this.addEdges(this.graph.anyEdgesBetween(el, neighbours)).forEach(edge => {
101
- this.addImplicit(edge.source, edge.target)
102
- })
103
- }
104
-
105
- // If root has no children
106
- if (!hasChildren && _elRoot) {
107
- // Any edges with siblings?
108
- const edgesWithSiblings = this.graph.anyEdgesBetween(_elRoot, this.graph.siblings(root))
109
- if (edgesWithSiblings.length === 0) {
110
- // If no edges with siblings, i.e. root is orphan
111
- // Lets add parent for better view
112
- const _parentId = parentFqn(root)
113
- const parent = _parentId && this.graph.element(_parentId)
114
- if (parent && where(parent)) {
115
- this.addElement(parent)
116
- }
117
- }
118
- }
119
- }
120
-
121
- export function excludeWildcardRef(this: ComputeCtx, _expr: Expr.WildcardExpr, where = NoFilter) {
122
- if (where !== NoFilter) {
123
- const elements = [...this.resolvedElements].filter(where)
124
- this.excludeElement(...elements)
125
- return
126
- }
127
- const root = this.root
128
- if (root) {
129
- this.excludeElement(
130
- this.graph.element(root),
131
- ...this.graph.children(root)
132
- )
133
- this.excludeRelation(
134
- ...this.graph.connectedRelations(root)
135
- )
136
- } else {
137
- this.reset()
138
- }
139
- }
140
-
141
- export function includeExpandedElementExpr(
142
- this: ComputeCtx,
143
- expr: Expr.ExpandedElementExpr,
144
- where = NoFilter
145
- ) {
146
- const filter = filterBy(where)
147
- const currentElements = [...this.resolvedElements]
148
-
149
- // Always add parent
150
- const parent = this.graph.element(expr.expanded)
151
- if (where(parent)) {
152
- this.addElement(parent)
153
- const anyEdgesBetween = this.graph.anyEdgesBetween(parent, currentElements)
154
- this.addEdges(anyEdgesBetween)
155
- }
156
-
157
- const expanded = [] as Element[]
158
-
159
- for (const el of filter(this.graph.children(expr.expanded))) {
160
- this.addImplicit(el)
161
- const edges = this.graph.anyEdgesBetween(el, currentElements)
162
- if (edges.length > 0) {
163
- this.addEdges(edges)
164
- expanded.push(el)
165
- }
166
- }
167
- if (expanded.length > 1) {
168
- this.addEdges(this.graph.edgesWithin(expanded))
169
- }
170
- }
171
-
172
- export function excludeExpandedElementExpr(
173
- this: ComputeCtx,
174
- expr: Expr.ExpandedElementExpr,
175
- where = NoFilter
176
- ) {
177
- const elements = [...this.resolvedElements].filter(allPass([
178
- elementExprToPredicate(expr),
179
- where
180
- ]))
181
- this.excludeElement(...elements)
182
- }
183
-
184
- const asElementPredicate = (
185
- expr: Expr.ElementKindExpr | Expr.ElementTagExpr
186
- ): Predicate<Element> => {
187
- if (expr.isEqual) {
188
- if (Expr.isElementKindExpr(expr)) {
189
- return e => e.kind === expr.elementKind
190
- } else {
191
- return ({ tags }) => !!tags && tags.includes(expr.elementTag)
192
- }
193
- } else {
194
- if (Expr.isElementKindExpr(expr)) {
195
- return e => e.kind !== expr.elementKind
196
- } else {
197
- return ({ tags }) => isNil(tags) || tags.length === 0 || !tags.includes(expr.elementTag)
198
- }
199
- }
200
- }
201
- export function includeElementKindOrTag(
202
- this: ComputeCtx,
203
- expr: Expr.ElementKindExpr | Expr.ElementTagExpr,
204
- where = NoFilter
205
- ) {
206
- const elements = this.graph.elements.filter(asElementPredicate(expr)).filter(where)
207
- if (elements.length > 0) {
208
- const currentElements = [...this.resolvedElements]
209
- this.addElement(...elements)
210
- this.addEdges(this.graph.edgesWithin(elements))
211
- for (const el of elements) {
212
- this.addEdges(this.graph.anyEdgesBetween(el, currentElements))
213
- }
214
- }
215
- }
216
-
217
- export function excludeElementKindOrTag(
218
- this: ComputeCtx,
219
- expr: Expr.ElementKindExpr | Expr.ElementTagExpr,
220
- where = NoFilter
221
- ) {
222
- const elements = [...this.resolvedElements].filter(asElementPredicate(expr)).filter(where)
223
- if (elements.length > 0) {
224
- this.excludeElement(...elements)
225
- }
226
- }
227
-
228
- function resolveNeighbours(this: ComputeCtx, expr: Expr.ElementExpression): Element[] {
229
- if (Expr.isElementRef(expr)) {
230
- return this.graph.ascendingSiblings(expr.element)
231
- }
232
- return this.root ? this.graph.ascendingSiblings(this.root) : this.graph.rootElements
233
- }
234
-
235
- function resolveElements(this: ComputeCtx, expr: Expr.ElementExpression): Element[] {
236
- if (Expr.isWildcard(expr)) {
237
- if (this.root) {
238
- return [...this.graph.children(this.root), this.graph.element(this.root)]
239
- } else {
240
- return this.graph.rootElements
241
- }
242
- }
243
- if (Expr.isElementKindExpr(expr)) {
244
- return this.graph.elements.filter(el => {
245
- if (expr.isEqual) {
246
- return el.kind === expr.elementKind
247
- }
248
- return el.kind !== expr.elementKind
249
- })
250
- }
251
- if (Expr.isElementTagExpr(expr)) {
252
- return this.graph.elements.filter(el => {
253
- const tags = el.tags
254
- if (expr.isEqual) {
255
- return !!tags && tags.includes(expr.elementTag)
256
- }
257
- return isNil(tags) || tags.length === 0 || !tags.includes(expr.elementTag)
258
- })
259
- }
260
- if (Expr.isExpandedElementExpr(expr)) {
261
- return [this.graph.element(expr.expanded)]
262
- }
263
-
264
- // Type guard
265
- if (!Expr.isElementRef(expr)) {
266
- return nonexhaustive(expr)
267
- }
268
-
269
- if (this.root === expr.element && expr.isDescedants !== true) {
270
- return [...this.graph.children(this.root), this.graph.element(this.root)]
271
- }
272
-
273
- if (expr.isDescedants) {
274
- return this.graph.childrenOrElement(expr.element)
275
- } else {
276
- return [this.graph.element(expr.element)]
277
- }
278
- }
279
-
280
- // --------------------------------
281
- // Incoming Expr
282
-
283
- function edgesIncomingExpr(this: ComputeCtx, expr: Expr.ElementExpression) {
284
- if (Expr.isWildcard(expr)) {
285
- if (!this.root) {
286
- return []
287
- }
288
- const sources = this.graph.ascendingSiblings(this.root)
289
- const targets = [...this.graph.children(this.root), this.graph.element(this.root)]
290
- return this.graph.edgesBetween(sources, targets)
291
- }
292
- const targets = resolveElements.call(this, expr)
293
- if (targets.length === 0) {
294
- return []
295
- }
296
- let sources = [...this.resolvedElements]
297
- if (Expr.isElementRef(expr) || Expr.isExpandedElementExpr(expr)) {
298
- const exprElement = expr.element ?? expr.expanded
299
- const isDescedants = expr.isDescedants ?? false
300
- sources = sources.filter(el =>
301
- // allow elements, that are not nested or are direct children
302
- !isAncestor(exprElement, el.id) || (isDescedants && parentFqn(el.id) === exprElement)
303
- )
304
- }
305
- if (sources.length === 0) {
306
- sources = resolveNeighbours.call(this, expr)
307
- }
308
- return this.graph.edgesBetween(sources, targets)
309
- }
310
-
311
- const filterEdges = (edges: ReadonlyArray<ComputeCtx.Edge>, where?: RelationPredicateFn) => {
312
- if (!where) {
313
- return edges as ComputeCtx.Edge[]
314
- }
315
- return pipe(
316
- edges,
317
- map(e => ({ ...e, relations: e.relations.filter(where) })),
318
- remedaFilter(e => e.relations.length > 0)
319
- ) as ComputeCtx.Edge[]
320
- }
321
-
322
- const filterRelations = (edges: ComputeCtx.Edge[], where?: RelationPredicateFn) => {
323
- return pipe(
324
- edges,
325
- flatMap(e => e.relations),
326
- where ? remedaFilter(where) : Identity,
327
- unique()
328
- )
329
- }
330
-
331
- export function includeIncomingExpr(this: ComputeCtx, expr: Expr.IncomingExpr, where?: RelationPredicateFn) {
332
- const edges = filterEdges(edgesIncomingExpr.call(this, expr.incoming), where)
333
- if (edges.length === 0) {
334
- return
335
- }
336
- this.addEdges(edges).forEach(edge => {
337
- this.addImplicit(edge.target)
338
- })
339
- }
340
- export function excludeIncomingExpr(this: ComputeCtx, expr: Expr.IncomingExpr, where?: RelationPredicateFn) {
341
- let relations = filterRelations(edgesIncomingExpr.call(this, expr.incoming), where)
342
- this.excludeRelation(...relations)
343
- }
344
-
345
- // --------------------------------
346
- // Outgoing Expr
347
-
348
- function edgesOutgoingExpr(this: ComputeCtx, expr: Expr.ElementExpression) {
349
- if (Expr.isWildcard(expr)) {
350
- if (!this.root) {
351
- return []
352
- }
353
- const targets = this.graph.ascendingSiblings(this.root)
354
- const sources = [...this.graph.children(this.root), this.graph.element(this.root)]
355
- return this.graph.edgesBetween(sources, targets)
356
- }
357
- const sources = resolveElements.call(this, expr)
358
- if (sources.length === 0) {
359
- return []
360
- }
361
- let targets = [...this.resolvedElements]
362
- if (Expr.isElementRef(expr) || Expr.isExpandedElementExpr(expr)) {
363
- const sourceElement = expr.element ?? expr.expanded
364
- const isDescedants = expr.isDescedants ?? false
365
- targets = targets.filter(el =>
366
- // allow elements, that are not nested or are direct children
367
- !isAncestor(sourceElement, el.id) || (isDescedants && parentFqn(el.id) === sourceElement)
368
- )
369
- }
370
- if (targets.length === 0) {
371
- targets = resolveNeighbours.call(this, expr)
372
- }
373
- return this.graph.edgesBetween(sources, targets)
374
- }
375
-
376
- export function includeOutgoingExpr(this: ComputeCtx, expr: Expr.OutgoingExpr, where?: RelationPredicateFn) {
377
- const edges = filterEdges(edgesOutgoingExpr.call(this, expr.outgoing), where)
378
- if (edges.length === 0) {
379
- return
380
- }
381
- this.addEdges(edges).forEach(edge => {
382
- this.addImplicit(edge.source)
383
- })
384
- }
385
- export function excludeOutgoingExpr(this: ComputeCtx, expr: Expr.OutgoingExpr, where?: RelationPredicateFn) {
386
- const relations = filterRelations(edgesOutgoingExpr.call(this, expr.outgoing), where)
387
- this.excludeRelation(...relations)
388
- }
389
-
390
- // --------------------------------
391
- // InOut Expr
392
- type EdgePredicateResult = {
393
- implicits: Element[]
394
- edges: ComputeCtx.Edge[]
395
- }
396
-
397
- namespace EdgePredicateResult {
398
- export const Empty: EdgePredicateResult = {
399
- implicits: [],
400
- edges: []
401
- }
402
- }
403
- function edgesInOutExpr(this: ComputeCtx, { inout }: Expr.InOutExpr, where?: RelationPredicateFn): EdgePredicateResult {
404
- if (Expr.isWildcard(inout)) {
405
- if (!this.root) {
406
- return EdgePredicateResult.Empty
407
- }
408
- const neighbours = this.graph.ascendingSiblings(this.root)
409
- return {
410
- edges: filterEdges(this.graph.anyEdgesBetween(this.graph.element(this.root), neighbours), where),
411
- implicits: []
412
- }
413
- }
414
- const elements = resolveElements.call(this, inout)
415
- if (elements.length === 0) {
416
- return EdgePredicateResult.Empty
417
- }
418
- let currentElements = [...this.resolvedElements]
419
-
420
- if (Expr.isElementRef(inout) || Expr.isExpandedElementExpr(inout)) {
421
- const exprElement = inout.element ?? inout.expanded
422
- const isDescedants = inout.isDescedants ?? false
423
- currentElements = currentElements.filter(el =>
424
- // allow elements, that are not nested or are direct children
425
- !isAncestor(exprElement, el.id) || (isDescedants && parentFqn(el.id) === exprElement)
426
- )
427
- }
428
- if (currentElements.length === 0) {
429
- currentElements = resolveNeighbours.call(this, inout)
430
- }
431
- return elements.reduce<EdgePredicateResult>((acc, el) => {
432
- const edges = filterEdges(this.graph.anyEdgesBetween(el, currentElements), where)
433
- if (edges.length > 0) {
434
- acc.implicits.push(el)
435
- acc.edges.push(...edges)
436
- }
437
- return acc
438
- }, { implicits: [], edges: [] })
439
- }
440
-
441
- export function includeInOutExpr(this: ComputeCtx, expr: Expr.InOutExpr, where?: RelationPredicateFn) {
442
- const { implicits, edges } = edgesInOutExpr.call(this, expr, where)
443
- this.addEdges(edges)
444
- this.addImplicit(...implicits)
445
- }
446
- export function excludeInOutExpr(this: ComputeCtx, expr: Expr.InOutExpr, where?: RelationPredicateFn) {
447
- const { edges } = edgesInOutExpr.call(this, expr, where)
448
- this.excludeRelation(...edges.flatMap(e => e.relations))
449
- }
450
-
451
- /**
452
- * Expand element to its children and itself, if it is the root (and not ".*")
453
- * Example:
454
- *
455
- * view of api {
456
- * include some -> api
457
- * }
458
- *
459
- * Transform to:
460
- *
461
- * view of api {
462
- * include some -> api.*, some -> api
463
- * }
464
- */
465
- function resolveRelationExprElements(this: ComputeCtx, expr: Expr.ElementExpression) {
466
- if (Expr.isElementRef(expr) && this.root === expr.element && expr.isDescedants !== true) {
467
- return [...this.graph.children(expr.element), this.graph.element(expr.element)]
468
- }
469
- if (Expr.isExpandedElementExpr(expr) && this.root === expr.expanded) {
470
- return [...this.graph.children(expr.expanded), this.graph.element(expr.expanded)]
471
- }
472
- return resolveElements.call(this, expr)
473
- }
474
-
475
- export function includeRelationExpr(this: ComputeCtx, expr: Expr.RelationExpr, where?: RelationPredicateFn) {
476
- let sources, targets
477
- if (Expr.isWildcard(expr.source) && !Expr.isWildcard(expr.target)) {
478
- sources = resolveNeighbours.call(this, expr.target)
479
- targets = resolveRelationExprElements.call(this, expr.target)
480
- } else if (!Expr.isWildcard(expr.source) && Expr.isWildcard(expr.target)) {
481
- sources = resolveRelationExprElements.call(this, expr.source)
482
- targets = resolveNeighbours.call(this, expr.source)
483
- } else {
484
- sources = resolveRelationExprElements.call(this, expr.source)
485
- targets = resolveRelationExprElements.call(this, expr.target)
486
- }
487
- const edges = this.graph.edgesBetween(sources, targets)
488
- if (expr.isBidirectional === true) {
489
- edges.push(...this.graph.edgesBetween(targets, sources))
490
- }
491
- this.addEdges(filterEdges(edges, where)).forEach(edge => {
492
- this.activeGroup.addImplicit(edge.source, edge.target)
493
- })
494
- }
495
-
496
- export function excludeRelationExpr(this: ComputeCtx, expr: Expr.RelationExpr, where?: RelationPredicateFn) {
497
- const isSource = elementExprToPredicate(expr.source)
498
- const isTarget = elementExprToPredicate(expr.target)
499
- const satisfies = (edge: ComputeCtx.Edge) => {
500
- let result = isSource(edge.source) && isTarget(edge.target)
501
- if (!result && expr.isBidirectional) {
502
- result = isSource(edge.target) && isTarget(edge.source)
503
- }
504
- return result
505
- }
506
- const edges = this.edges.filter(satisfies)
507
- const relations = filterRelations(edges, where)
508
- this.excludeRelation(...relations)
509
- }
@@ -1,61 +0,0 @@
1
- import type { DynamicViewRule, DynamicViewStep, Fqn, ViewID, ViewRulePredicate } from '@likec4/core'
2
- import { partition } from 'remeda'
3
- import { type FakeElementIds, fakeModel } from '../../compute-view/__test__/fixture'
4
- import { computeDynamicView } from '../index'
5
-
6
- const emptyView = {
7
- __: 'dynamic' as const,
8
- id: 'index' as ViewID,
9
- title: null,
10
- description: null,
11
- tags: null,
12
- links: null,
13
- customColorDefinitions: {},
14
- rules: []
15
- }
16
-
17
- type StepExpr = `${FakeElementIds} ${'->' | '<-'} ${FakeElementIds}`
18
- type StepProps = Omit<DynamicViewStep, 'source' | 'target' | 'isBackward'>
19
-
20
- export function $step(expr: StepExpr, props?: string | Partial<StepProps>): DynamicViewStep {
21
- const title = typeof props === 'string' ? props : props?.title
22
- if (expr.includes(' -> ')) {
23
- const [source, target] = expr.split(' -> ')
24
- return {
25
- source: source as Fqn,
26
- target: target as Fqn,
27
- ...(typeof props === 'object' ? props : {}),
28
- title: title ?? null
29
- }
30
- }
31
- if (expr.includes(' <- ')) {
32
- const [target, source] = expr.split(' <- ')
33
- return {
34
- source: source as Fqn,
35
- target: target as Fqn,
36
- ...(typeof props === 'object' ? props : {}),
37
- title: title ?? null,
38
- isBackward: true
39
- }
40
- }
41
- throw new Error(`Invalid step expression: ${expr}`)
42
- }
43
-
44
- export function compute(stepsAndRules: (DynamicViewStep | ViewRulePredicate)[]) {
45
- const [steps, rules] = partition(stepsAndRules, (s): s is DynamicViewStep => 'source' in s)
46
- const result = computeDynamicView(
47
- {
48
- ...emptyView,
49
- steps,
50
- rules: rules as DynamicViewRule[]
51
- },
52
- fakeModel
53
- )
54
- if (!result.isSuccess) {
55
- throw result.error
56
- }
57
- return Object.assign(result.view, {
58
- nodeIds: result.view.nodes.map((node) => node.id) as string[],
59
- edgeIds: result.view.edges.map((edge) => edge.id) as string[]
60
- })
61
- }