@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,39 +0,0 @@
1
- import { Expr, nonexhaustive, parentFqn } from '@likec4/core'
2
- import { type Element, whereOperatorAsPredicate } from '@likec4/core'
3
- import { isNullish } from 'remeda'
4
-
5
- type Predicate<T> = (x: T) => boolean
6
-
7
- export function elementExprToPredicate<T extends Pick<Element, 'id' | 'kind' | 'tags'>>(
8
- target: Expr.ElementPredicateExpression
9
- ): Predicate<T> {
10
- if (Expr.isElementWhere(target)) {
11
- const predicate = elementExprToPredicate(target.where.expr)
12
- const where = whereOperatorAsPredicate(target.where.condition)
13
- return n => predicate(n) && where(n)
14
- }
15
- if (Expr.isWildcard(target)) {
16
- return () => true
17
- }
18
- if (Expr.isElementKindExpr(target)) {
19
- return target.isEqual ? n => n.kind === target.elementKind : n => n.kind !== target.elementKind
20
- }
21
- if (Expr.isElementTagExpr(target)) {
22
- return target.isEqual
23
- ? ({ tags }) => !!tags && tags.includes(target.elementTag)
24
- : ({ tags }) => isNullish(tags) || !tags.includes(target.elementTag)
25
- }
26
- if (Expr.isExpandedElementExpr(target)) {
27
- return n => n.id === target.expanded || parentFqn(n.id) === target.expanded
28
- }
29
- if (Expr.isElementRef(target)) {
30
- const { element, isDescedants } = target
31
- return isDescedants
32
- ? n => n.id.startsWith(element + '.')
33
- : n => (n.id as string) === element
34
- }
35
- if (Expr.isCustomElement(target)) {
36
- return elementExprToPredicate(target.custom.expr)
37
- }
38
- nonexhaustive(target)
39
- }
@@ -1,43 +0,0 @@
1
- import type { Element, Relation } from '@likec4/core'
2
- import { Expr, nonexhaustive, whereOperatorAsPredicate } from '@likec4/core'
3
- import { elementExprToPredicate } from './elementExpressionToPredicate'
4
-
5
- type Predicate<T> = (x: T) => boolean
6
- export type FilterableEdge = Pick<Relation, 'kind' | 'tags'> & {
7
- source: Element
8
- target: Element
9
- }
10
-
11
- export function relationExpressionToPredicates<T extends FilterableEdge>(
12
- expr: Expr.RelationExpression | Expr.RelationWhereExpr
13
- ): Predicate<T> {
14
- switch (true) {
15
- case Expr.isRelationWhere(expr):
16
- const predicate = relationExpressionToPredicates(expr.where.expr)
17
- const where = whereOperatorAsPredicate(expr.where.condition)
18
-
19
- return e => predicate(e) && where(e)
20
- case Expr.isRelation(expr): {
21
- const isSource = elementExprToPredicate(expr.source)
22
- const isTarget = elementExprToPredicate(expr.target)
23
- return edge => {
24
- return (isSource(edge.source) && isTarget(edge.target))
25
- || (!!expr.isBidirectional && isSource(edge.target) && isTarget(edge.source))
26
- }
27
- }
28
- case Expr.isInOut(expr): {
29
- const isInOut = elementExprToPredicate(expr.inout)
30
- return edge => isInOut(edge.source) || isInOut(edge.target)
31
- }
32
- case Expr.isIncoming(expr): {
33
- const isTarget = elementExprToPredicate(expr.incoming)
34
- return edge => isTarget(edge.target)
35
- }
36
- case Expr.isOutgoing(expr): {
37
- const isSource = elementExprToPredicate(expr.outgoing)
38
- return edge => isSource(edge.source)
39
- }
40
- default:
41
- nonexhaustive(expr)
42
- }
43
- }
@@ -1,105 +0,0 @@
1
- import {
2
- compareByFqnHierarchically,
3
- compareRelations,
4
- type ComputedEdge,
5
- type ComputedNode,
6
- type EdgeId,
7
- type Fqn,
8
- invariant,
9
- nonNullable
10
- } from '@likec4/core'
11
- import { difference, filter, map, pipe, sort, tap } from 'remeda'
12
- import { Graph, postorder } from '../../utils/graphlib'
13
-
14
- // side effect
15
- function sortChildren(nodes: readonly ComputedNode[]) {
16
- nodes.forEach(parent => {
17
- if (parent.children.length > 0) {
18
- parent.children = nodes.flatMap(n => (n.parent === parent.id ? n.id : []))
19
- }
20
- })
21
- }
22
-
23
- export function sortNodes({
24
- nodes,
25
- edges
26
- }: {
27
- nodes: ComputedNode[]
28
- edges: ComputedEdge[]
29
- }): ComputedNode[] {
30
- if (nodes.length < 2) {
31
- return nodes
32
- }
33
- if (edges.length === 0) {
34
- return pipe(
35
- nodes,
36
- sort(compareByFqnHierarchically),
37
- tap(sortChildren)
38
- )
39
- }
40
-
41
- const g = new Graph({
42
- compound: false,
43
- directed: true,
44
- multigraph: false
45
- })
46
-
47
- const getNode = (id: Fqn) =>
48
- nonNullable(
49
- nodes.find(n => n.id === id),
50
- 'Edge not found'
51
- )
52
- const getEdge = (id: EdgeId) =>
53
- nonNullable(
54
- edges.find(edge => edge.id === id),
55
- 'Edge not found'
56
- )
57
-
58
- for (const e of [...edges].sort(compareRelations)) {
59
- g.setEdge(e.source, e.target)
60
- }
61
-
62
- for (const n of nodes) {
63
- g.setNode(n.id, n.id)
64
- if (n.children.length > 0) {
65
- n.inEdges.forEach(e => {
66
- const edge = getEdge(e)
67
- // if this edge from leaf to the child of this node
68
- if (edge.target !== n.id && getNode(edge.source).children.length === 0) {
69
- // const id = `${edge.source}:${n.id}`
70
- g.setEdge(edge.source, n.id)
71
- }
72
- })
73
- // n.outEdges.forEach(e => {
74
- // const edge = getEdge(e)
75
- // if (edge.source !== n.id) {
76
- // const id = `${n.id}:${edge.target}`
77
- // g.setEdge(n.id, edge.target, undefined, id)
78
- // }
79
- // })
80
- }
81
- if (n.parent) {
82
- g.setEdge(n.parent, n.id)
83
- }
84
- }
85
-
86
- let sources = g.sources() as unknown as Fqn[]
87
- if (sources.length === 0) {
88
- sources = pipe(
89
- nodes,
90
- filter(n => n.inEdges.length === 0 || n.parent === null),
91
- sort(compareByFqnHierarchically),
92
- map(n => n.id)
93
- )
94
- }
95
- const orderedIds = postorder(g, sources).reverse() as Fqn[]
96
- const sorted = orderedIds.map(getNode)
97
- if (sorted.length < nodes.length) {
98
- const unsorted = difference(nodes, sorted).sort(compareByFqnHierarchically)
99
- sorted.push(...unsorted)
100
- }
101
-
102
- invariant(sorted.length === nodes.length, 'Not all nodes were processed by graphlib')
103
- sortChildren(sorted)
104
- return sorted
105
- }
@@ -1,42 +0,0 @@
1
- import { compareNatural } from '@likec4/core'
2
- import { describe, expect, it } from 'vitest'
3
- import { uniqueTags } from './uniqueTags'
4
-
5
- describe('uniqueTags function', () => {
6
- it('returns unique tags from an array of elements', () => {
7
- const input = [
8
- { tags: ['tag1', 'tag2', 'tag3'] },
9
- { tags: ['tag2', 'tag3', 'tag4'] },
10
- { tags: ['tag3', 'tag4', 'tag5'] }
11
- ] as const
12
- const result = uniqueTags(input)
13
- expect(result).toEqual(['tag1', 'tag2', 'tag3', 'tag4', 'tag5'])
14
- })
15
-
16
- it('should return unique tags naturally sorted', () => {
17
- const input = [
18
- { tags: ['tag1', 'tag20', 'tag30'] },
19
- { tags: ['tag2', 'tag23', 'tag34'] },
20
- { tags: ['tag3'] }
21
- ] as const
22
- const result = uniqueTags(input)
23
- expect(result).toEqual([
24
- 'tag1',
25
- 'tag2',
26
- 'tag3',
27
- 'tag20',
28
- 'tag23',
29
- 'tag30',
30
- 'tag34'
31
- ].sort(compareNatural))
32
- })
33
-
34
- it('returns null if the tags array is null', () => {
35
- const input = [
36
- { tags: null },
37
- {}
38
- ]
39
- const result = uniqueTags(input)
40
- expect(result).toBeNull()
41
- })
42
- })
@@ -1,19 +0,0 @@
1
- import { compareNatural, hasAtLeast, type NonEmptyReadonlyArray, type Tag } from '@likec4/core'
2
- import { flatMap, pipe, sort, unique } from 'remeda'
3
- import type { LiteralUnion } from 'type-fest'
4
-
5
- /**
6
- * Extracts unique tags from an array of elements.
7
- * and sort in natural order; returns null if no tags are present.
8
- */
9
- export function uniqueTags<T extends { tags?: NonEmptyReadonlyArray<LiteralUnion<Tag, string>> | null }>(
10
- elements: ReadonlyArray<T>
11
- ) {
12
- const tags = pipe(
13
- elements,
14
- flatMap(e => e.tags ?? []),
15
- unique(),
16
- sort(compareNatural)
17
- )
18
- return hasAtLeast(tags, 1) ? tags : null
19
- }
@@ -1,9 +0,0 @@
1
- import dagre from '@dagrejs/dagre'
2
-
3
- const Graph = dagre.graphlib.Graph
4
-
5
- export { Graph }
6
-
7
- export const postorder = dagre.graphlib.alg.postorder
8
- export const findCycles = dagre.graphlib.alg.findCycles
9
- export const isAcyclic = dagre.graphlib.alg.isAcyclic
@@ -1,66 +0,0 @@
1
- import { isExtendsElementView, type LikeC4View } from '@likec4/core'
2
- import { logger } from '@likec4/log'
3
- import { first, last, values } from 'remeda'
4
- import { findCycles, Graph, isAcyclic, postorder } from '../utils/graphlib'
5
-
6
- /**
7
- * Resolve rules of extended views
8
- * (Removes invalid views)
9
- */
10
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
- export function resolveRulesExtendedViews<V extends Record<any, LikeC4View>>(
12
- unresolvedViews: V
13
- ): V {
14
- const g = new Graph({
15
- directed: true,
16
- multigraph: false,
17
- compound: false
18
- })
19
- for (const view of values(unresolvedViews)) {
20
- g.setNode(view.id, view.id)
21
- if (isExtendsElementView(view)) {
22
- // view -> parent
23
- g.setEdge(view.id, view.extends)
24
- }
25
- }
26
- if (g.edgeCount() === 0) {
27
- return unresolvedViews
28
- }
29
-
30
- // Remove circular dependencies
31
- while (!isAcyclic(g)) {
32
- const firstCycle = first(findCycles(g))
33
- if (!firstCycle) {
34
- break
35
- }
36
- const cycledNode = last(firstCycle)
37
- if (!cycledNode) {
38
- break
39
- }
40
- g.removeNode(cycledNode)
41
- }
42
-
43
- const ordered = postorder(g, g.sources() as unknown as string[])
44
-
45
- return ordered.reduce((acc, id) => {
46
- const view = unresolvedViews[id]
47
- if (!view) {
48
- return acc
49
- }
50
- if (isExtendsElementView(view)) {
51
- const extendsFrom = acc[view.extends]
52
- if (!extendsFrom) {
53
- logger.debug(`View "${view.id}" extends from "${view.extends}" which does not exist`)
54
- return acc
55
- }
56
- return Object.assign(acc, {
57
- [view.id]: {
58
- ...extendsFrom,
59
- ...view,
60
- rules: [...extendsFrom.rules, ...view.rules]
61
- }
62
- })
63
- }
64
- return Object.assign(acc, { [view.id]: view })
65
- }, {} as V)
66
- }
@@ -1,88 +0,0 @@
1
- import {
2
- type DynamicView,
3
- type DynamicViewRule,
4
- type ElementView,
5
- isDynamicView,
6
- isElementView,
7
- isViewRuleGlobalPredicateRef,
8
- isViewRuleGlobalStyle,
9
- type ModelGlobals,
10
- nonexhaustive,
11
- type ViewRule,
12
- type ViewRuleGlobalPredicateRef,
13
- type ViewRuleGlobalStyle
14
- } from '@likec4/core'
15
- import { logger } from '@likec4/log'
16
- import { isNullish } from 'remeda'
17
-
18
- export function resolveGlobalRules<V extends DynamicView | ElementView>(
19
- view: V,
20
- globals: ModelGlobals
21
- ): V {
22
- if (isElementView(view)) {
23
- return {
24
- ...view,
25
- rules: resolveGlobalRulesInElementView(view, globals)
26
- }
27
- } else if (isDynamicView(view)) {
28
- return {
29
- ...view,
30
- rules: resolveGlobalRulesInDynamicView(view, globals)
31
- }
32
- }
33
- nonexhaustive(view)
34
- }
35
-
36
- type ViewRuleGlobal = ViewRuleGlobalPredicateRef | ViewRuleGlobalStyle
37
-
38
- export function resolveGlobalRulesInElementView(
39
- view: ElementView,
40
- globals: ModelGlobals
41
- ): Array<Exclude<ViewRule, ViewRuleGlobal>> {
42
- return view.rules.reduce((acc, rule) => {
43
- if (isViewRuleGlobalPredicateRef(rule)) {
44
- const globalPredicates = globals.predicates[rule.predicateId]
45
- if (isNullish(globalPredicates)) {
46
- logger.warn(`Global predicate not found: ${rule.predicateId}`)
47
- return acc
48
- }
49
- return acc.concat(globalPredicates)
50
- }
51
- if (isViewRuleGlobalStyle(rule)) {
52
- const globalStyles = globals.styles[rule.styleId]
53
- if (isNullish(globalStyles)) {
54
- logger.warn(`Global style not found: ${rule.styleId}`)
55
- return acc
56
- }
57
- return acc.concat(globalStyles)
58
- }
59
- acc.push(rule)
60
- return acc
61
- }, [] as Array<Exclude<ViewRule, ViewRuleGlobal>>)
62
- }
63
-
64
- export function resolveGlobalRulesInDynamicView(
65
- view: DynamicView,
66
- globals: ModelGlobals
67
- ): Array<Exclude<DynamicViewRule, ViewRuleGlobal>> {
68
- return view.rules.reduce((acc, rule) => {
69
- if (isViewRuleGlobalPredicateRef(rule)) {
70
- const globalPredicates = globals.dynamicPredicates[rule.predicateId]
71
- if (isNullish(globalPredicates)) {
72
- logger.warn(`Global predicate not found: ${rule.predicateId}`)
73
- return acc
74
- }
75
- return acc.concat(globalPredicates)
76
- }
77
- if (isViewRuleGlobalStyle(rule)) {
78
- const globalStyles = globals.styles[rule.styleId]
79
- if (isNullish(globalStyles)) {
80
- logger.warn(`Global style not found: ${rule.styleId}`)
81
- return acc
82
- }
83
- return acc.concat(globalStyles)
84
- }
85
- acc.push(rule)
86
- return acc
87
- }, [] as Array<Exclude<DynamicViewRule, ViewRuleGlobal>>)
88
- }
@@ -1,27 +0,0 @@
1
- import type { ComputedView } from '@likec4/core'
2
- import objectHash from 'object-hash'
3
- import { isTruthy, map, mapToObj, pick, pipe } from 'remeda'
4
- import type { SetOptional } from 'type-fest'
5
-
6
- export function calcViewLayoutHash<V extends ComputedView>(view: SetOptional<V, 'hash'>): V {
7
- const tohash = {
8
- id: view.id,
9
- __: view.__ ?? 'element',
10
- autoLayout: view.autoLayout,
11
- nodes: pipe(
12
- view.nodes,
13
- map(pick(['id', 'title', 'description', 'technology', 'shape', 'icon', 'children'])),
14
- mapToObj(({ id, icon, ...node }) => [id, { ...node, icon: isTruthy(icon) ? 'Y' : 'N' }])
15
- ),
16
- edges: pipe(
17
- view.edges,
18
- map(pick(['source', 'target', 'label', 'description', 'technology', 'dir', 'head', 'tail', 'line'])),
19
- mapToObj(({ source, target, ...edge }) => [`${source}:${target}`, edge])
20
- )
21
- }
22
- view.hash = objectHash(tohash, {
23
- ignoreUnknown: true,
24
- respectType: false
25
- })
26
- return view as V
27
- }