@likec4/language-server 1.15.1 → 1.16.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.
- package/contrib/likec4.tmLanguage.json +1 -1
- package/dist/browser.cjs +1 -1
- package/dist/browser.d.cts +2 -2
- package/dist/browser.d.mts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.mjs +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/model-graph/index.cjs +1 -1
- package/dist/model-graph/index.d.cts +4 -2
- package/dist/model-graph/index.d.mts +4 -2
- package/dist/model-graph/index.d.ts +4 -2
- package/dist/model-graph/index.mjs +1 -1
- package/dist/shared/language-server.7iILaJYc.d.ts +1338 -0
- package/dist/shared/{language-server.B8s2wfT_.cjs → language-server.Bd3NZ8uH.cjs} +123 -72
- package/dist/shared/{language-server.BT4WTbFI.mjs → language-server.C5gxpVUH.mjs} +125 -74
- package/dist/shared/language-server.CmBZHwSl.d.cts +1338 -0
- package/dist/shared/{language-server.U2piOAVt.d.cts → language-server.CnkCWVtf.d.cts} +44 -10
- package/dist/shared/{language-server.DfMwkd2l.d.mts → language-server.DIaiY0-C.d.mts} +44 -10
- package/dist/shared/language-server.DViE1Zxi.d.mts +1338 -0
- package/dist/shared/{language-server.BuChFlda.mjs → language-server.D_13fWJQ.mjs} +177 -84
- package/dist/shared/{language-server.j-ShR6as.d.ts → language-server.DwyQ1FtY.d.ts} +44 -10
- package/dist/shared/{language-server.DfjkvknB.cjs → language-server.Dym6GL4P.cjs} +175 -82
- package/package.json +7 -7
- package/src/ast.ts +11 -3
- package/src/generated/ast.ts +111 -10
- package/src/generated/grammar.ts +1 -1
- package/src/like-c4.langium +19 -0
- package/src/model/model-builder.ts +25 -30
- package/src/model/model-parser.ts +91 -18
- package/src/model-graph/LikeC4ModelGraph.ts +22 -11
- package/src/model-graph/compute-view/__test__/fixture.ts +63 -19
- package/src/model-graph/compute-view/compute.ts +77 -72
- package/src/model-graph/dynamic-view/compute.ts +4 -1
- package/src/model-graph/utils/applyViewRuleStyles.ts +0 -4
- package/src/references/scope-computation.ts +10 -0
- package/src/validation/index.ts +3 -0
- package/src/validation/specification.ts +21 -0
- package/src/view-utils/index.ts +0 -1
- package/src/view-utils/resolve-global-rules.ts +66 -50
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
ElementKind,
|
|
9
9
|
type ElementPredicateExpression,
|
|
10
10
|
type ElementView,
|
|
11
|
+
type Fqn,
|
|
11
12
|
type NodeId,
|
|
12
13
|
type NonEmptyArray,
|
|
13
14
|
type Relation,
|
|
@@ -54,6 +55,7 @@ import {
|
|
|
54
55
|
sort,
|
|
55
56
|
unique
|
|
56
57
|
} from 'remeda'
|
|
58
|
+
import { resolveGlobalRulesInElementView } from '../../view-utils/resolve-global-rules'
|
|
57
59
|
import { calcViewLayoutHash } from '../../view-utils/view-hash'
|
|
58
60
|
import type { LikeC4ModelGraph } from '../LikeC4ModelGraph'
|
|
59
61
|
import { applyCustomElementProperties } from '../utils/applyCustomElementProperties'
|
|
@@ -179,6 +181,29 @@ export class ComputeCtx {
|
|
|
179
181
|
|
|
180
182
|
protected get activeGroup() {
|
|
181
183
|
return this.activeGroupStack[0] ?? this.__rootGroup
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
protected get includedElements() {
|
|
187
|
+
return new Set([
|
|
188
|
+
...this.explicits,
|
|
189
|
+
...this.ctxEdges.flatMap(e => [e.source, e.target])
|
|
190
|
+
]) as ReadonlySet<Element>
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
protected get resolvedElements() {
|
|
194
|
+
return new Set([
|
|
195
|
+
...this.explicits,
|
|
196
|
+
...this.implicits,
|
|
197
|
+
...this.ctxEdges.flatMap(e => [e.source, e.target])
|
|
198
|
+
]) as ReadonlySet<Element>
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
protected get edges() {
|
|
202
|
+
return this.ctxEdges
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
protected get root() {
|
|
206
|
+
return isScopedElementView(this.view) ? this.view.viewOf : null
|
|
182
207
|
}
|
|
183
208
|
|
|
184
209
|
public static elementView(view: ElementView, graph: LikeC4ModelGraph) {
|
|
@@ -194,10 +219,12 @@ export class ComputeCtx {
|
|
|
194
219
|
this.reset()
|
|
195
220
|
const {
|
|
196
221
|
docUri: _docUri, // exclude docUri
|
|
197
|
-
rules,
|
|
222
|
+
rules: _rules, // exclude rules
|
|
198
223
|
...view
|
|
199
224
|
} = this.view
|
|
200
225
|
|
|
226
|
+
const rules = resolveGlobalRulesInElementView(this.view, this.graph.globals)
|
|
227
|
+
|
|
201
228
|
const viewPredicates = rules.filter(anyPass([isViewRulePredicate, isViewRuleGroup])) as Array<
|
|
202
229
|
ViewRulePredicate | ViewRuleGroup
|
|
203
230
|
>
|
|
@@ -213,56 +240,10 @@ export class ComputeCtx {
|
|
|
213
240
|
const elements = [...this.includedElements]
|
|
214
241
|
const nodesMap = buildComputeNodes(elements, this.groups)
|
|
215
242
|
|
|
216
|
-
const ancestorsOf = (node: ComputedNode) => {
|
|
217
|
-
const ancestors = [] as ComputedNode[]
|
|
218
|
-
let parent = node.parent
|
|
219
|
-
while (parent) {
|
|
220
|
-
const parentNode = nodesMap.get(parent)
|
|
221
|
-
if (!parentNode) {
|
|
222
|
-
break
|
|
223
|
-
}
|
|
224
|
-
ancestors.push(parentNode)
|
|
225
|
-
parent = parentNode.parent
|
|
226
|
-
}
|
|
227
|
-
return ancestors
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const edgesMap = new Map<EdgeId, ComputedEdge>()
|
|
231
243
|
const edges = this.computeEdges()
|
|
232
|
-
|
|
233
|
-
edgesMap.set(edge.id, edge)
|
|
234
|
-
const source = nodesMap.get(edge.source)
|
|
235
|
-
const target = nodesMap.get(edge.target)
|
|
236
|
-
invariant(source, `Source node ${edge.source} not found`)
|
|
237
|
-
invariant(target, `Target node ${edge.target} not found`)
|
|
238
|
-
// These ancestors are reversed: from bottom to top
|
|
239
|
-
const sourceAncestors = ancestorsOf(source)
|
|
240
|
-
const targetAncestors = ancestorsOf(target)
|
|
244
|
+
const edgesMap = new Map<EdgeId, ComputedEdge>(edges.map(edge => [edge.id, edge]))
|
|
241
245
|
|
|
242
|
-
|
|
243
|
-
commonHead(
|
|
244
|
-
reverse(sourceAncestors),
|
|
245
|
-
reverse(targetAncestors)
|
|
246
|
-
)
|
|
247
|
-
)
|
|
248
|
-
edge.parent = edgeParent?.id ?? null
|
|
249
|
-
source.outEdges.push(edge.id)
|
|
250
|
-
target.inEdges.push(edge.id)
|
|
251
|
-
// Process edge source ancestors
|
|
252
|
-
for (const sourceAncestor of sourceAncestors) {
|
|
253
|
-
if (sourceAncestor === edgeParent) {
|
|
254
|
-
break
|
|
255
|
-
}
|
|
256
|
-
sourceAncestor.outEdges.push(edge.id)
|
|
257
|
-
}
|
|
258
|
-
// Process target hierarchy
|
|
259
|
-
for (const targetAncestor of targetAncestors) {
|
|
260
|
-
if (targetAncestor === edgeParent) {
|
|
261
|
-
break
|
|
262
|
-
}
|
|
263
|
-
targetAncestor.inEdges.push(edge.id)
|
|
264
|
-
}
|
|
265
|
-
}
|
|
246
|
+
this.linkNodesAndEdges(nodesMap, edges)
|
|
266
247
|
|
|
267
248
|
// nodesMap sorted hierarchically,
|
|
268
249
|
// but we need to keep the initial sort
|
|
@@ -312,10 +293,6 @@ export class ComputeCtx {
|
|
|
312
293
|
})
|
|
313
294
|
}
|
|
314
295
|
|
|
315
|
-
protected get root() {
|
|
316
|
-
return isScopedElementView(this.view) ? this.view.viewOf : null
|
|
317
|
-
}
|
|
318
|
-
|
|
319
296
|
protected computeEdges(): ComputedEdge[] {
|
|
320
297
|
return this.ctxEdges.map((e): ComputedEdge => {
|
|
321
298
|
invariant(hasAtLeast(e.relations, 1), 'Edge must have at least one relation')
|
|
@@ -428,23 +405,40 @@ export class ComputeCtx {
|
|
|
428
405
|
})
|
|
429
406
|
}
|
|
430
407
|
|
|
431
|
-
protected
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
...this.explicits,
|
|
441
|
-
...this.implicits,
|
|
442
|
-
...this.ctxEdges.flatMap(e => [e.source, e.target])
|
|
443
|
-
]) as ReadonlySet<Element>
|
|
444
|
-
}
|
|
408
|
+
protected linkNodesAndEdges(nodesMap: ReadonlyMap<Fqn, ComputedNode>, edges: ComputedEdge[]) {
|
|
409
|
+
for (const edge of edges) {
|
|
410
|
+
const source = nodesMap.get(edge.source)
|
|
411
|
+
const target = nodesMap.get(edge.target)
|
|
412
|
+
invariant(source, `Source node ${edge.source} not found`)
|
|
413
|
+
invariant(target, `Target node ${edge.target} not found`)
|
|
414
|
+
// These ancestors are reversed: from bottom to top
|
|
415
|
+
const sourceAncestors = this.ancestorsOf(source, nodesMap)
|
|
416
|
+
const targetAncestors = this.ancestorsOf(target, nodesMap)
|
|
445
417
|
|
|
446
|
-
|
|
447
|
-
|
|
418
|
+
const edgeParent = last(
|
|
419
|
+
commonHead(
|
|
420
|
+
reverse(sourceAncestors),
|
|
421
|
+
reverse(targetAncestors)
|
|
422
|
+
)
|
|
423
|
+
)
|
|
424
|
+
edge.parent = edgeParent?.id ?? null
|
|
425
|
+
source.outEdges.push(edge.id)
|
|
426
|
+
target.inEdges.push(edge.id)
|
|
427
|
+
// Process edge source ancestors
|
|
428
|
+
for (const sourceAncestor of sourceAncestors) {
|
|
429
|
+
if (sourceAncestor === edgeParent) {
|
|
430
|
+
break
|
|
431
|
+
}
|
|
432
|
+
sourceAncestor.outEdges.push(edge.id)
|
|
433
|
+
}
|
|
434
|
+
// Process target hierarchy
|
|
435
|
+
for (const targetAncestor of targetAncestors) {
|
|
436
|
+
if (targetAncestor === edgeParent) {
|
|
437
|
+
break
|
|
438
|
+
}
|
|
439
|
+
targetAncestor.inEdges.push(edge.id)
|
|
440
|
+
}
|
|
441
|
+
}
|
|
448
442
|
}
|
|
449
443
|
|
|
450
444
|
protected addEdges(edges: ComputeCtx.Edge[]) {
|
|
@@ -539,9 +533,6 @@ export class ComputeCtx {
|
|
|
539
533
|
}),
|
|
540
534
|
filter(isNonNull)
|
|
541
535
|
)
|
|
542
|
-
if (excludedImplicits.size === 0) {
|
|
543
|
-
return
|
|
544
|
-
}
|
|
545
536
|
this.ctxEdges = ctxEdges
|
|
546
537
|
const remaining = this.includedElements
|
|
547
538
|
if (remaining.size === 0) {
|
|
@@ -755,6 +746,20 @@ export class ComputeCtx {
|
|
|
755
746
|
nonexhaustive(expr)
|
|
756
747
|
}
|
|
757
748
|
|
|
749
|
+
private ancestorsOf(node: ComputedNode, nodesMap: ReadonlyMap<Fqn, ComputedNode>): ComputedNode[] {
|
|
750
|
+
const ancestors = [] as ComputedNode[]
|
|
751
|
+
let parent = node.parent
|
|
752
|
+
while (parent) {
|
|
753
|
+
const parentNode = nodesMap.get(parent)
|
|
754
|
+
if (!parentNode) {
|
|
755
|
+
break
|
|
756
|
+
}
|
|
757
|
+
ancestors.push(parentNode)
|
|
758
|
+
parent = parentNode.parent
|
|
759
|
+
}
|
|
760
|
+
return ancestors
|
|
761
|
+
}
|
|
762
|
+
|
|
758
763
|
protected getEdgeLabel(
|
|
759
764
|
relation: {
|
|
760
765
|
title: string
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
StepEdgeId
|
|
27
27
|
} from '@likec4/core'
|
|
28
28
|
import { filter, flatMap, hasAtLeast, isTruthy, map, omit, only, pipe, unique } from 'remeda'
|
|
29
|
+
import { resolveGlobalRulesInDynamicView } from '../../view-utils/resolve-global-rules'
|
|
29
30
|
import { calcViewLayoutHash } from '../../view-utils/view-hash'
|
|
30
31
|
import type { LikeC4ModelGraph } from '../LikeC4ModelGraph'
|
|
31
32
|
import { applyCustomElementProperties } from '../utils/applyCustomElementProperties'
|
|
@@ -111,7 +112,7 @@ export class DynamicViewComputeCtx {
|
|
|
111
112
|
protected compute(): ComputedDynamicView {
|
|
112
113
|
const {
|
|
113
114
|
docUri: _docUri, // exclude docUri
|
|
114
|
-
rules,
|
|
115
|
+
rules: _rules, // exclude rules
|
|
115
116
|
steps: viewSteps,
|
|
116
117
|
...view
|
|
117
118
|
} = this.view
|
|
@@ -133,6 +134,8 @@ export class DynamicViewComputeCtx {
|
|
|
133
134
|
stepNum++
|
|
134
135
|
}
|
|
135
136
|
|
|
137
|
+
const rules = resolveGlobalRulesInDynamicView(this.view, this.graph.globals)
|
|
138
|
+
|
|
136
139
|
for (const rule of rules) {
|
|
137
140
|
if (isDynamicViewIncludeRule(rule)) {
|
|
138
141
|
for (const expr of rule.include) {
|
|
@@ -13,10 +13,6 @@ export function applyViewRuleStyles(_rules: ViewRule[], nodes: ComputedNode[]) {
|
|
|
13
13
|
for (const rule of rules) {
|
|
14
14
|
const predicates = [] as Predicate<ComputedNode>[]
|
|
15
15
|
for (const target of rule.targets) {
|
|
16
|
-
if (Expr.isWildcard(target)) {
|
|
17
|
-
predicates.push(() => true)
|
|
18
|
-
break
|
|
19
|
-
}
|
|
20
16
|
predicates.push(elementExprToPredicate(target) as Predicate<ComputedNode>)
|
|
21
17
|
}
|
|
22
18
|
pipe(
|
|
@@ -69,6 +69,16 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
|
69
69
|
if (isNullish(globals) || globals.length === 0) {
|
|
70
70
|
return
|
|
71
71
|
}
|
|
72
|
+
for (const globalPredicateAst of globals.flatMap(g => g.predicates)) {
|
|
73
|
+
try {
|
|
74
|
+
const id = globalPredicateAst
|
|
75
|
+
if (isTruthy(id.name)) {
|
|
76
|
+
docExports.push(this.descriptions.createDescription(id, id.name, document))
|
|
77
|
+
}
|
|
78
|
+
} catch (e) {
|
|
79
|
+
logError(e)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
72
82
|
for (const globalStyleAst of globals.flatMap(g => g.styles)) {
|
|
73
83
|
try {
|
|
74
84
|
const id = globalStyleAst.id
|
package/src/validation/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { iconPropertyRuleChecks, notesPropertyRuleChecks, opacityPropertyRuleChe
|
|
|
8
8
|
import { relationBodyChecks, relationChecks } from './relation'
|
|
9
9
|
import {
|
|
10
10
|
elementKindChecks,
|
|
11
|
+
globalPredicateChecks,
|
|
11
12
|
globalsChecks,
|
|
12
13
|
globalStyleIdChecks,
|
|
13
14
|
modelRuleChecks,
|
|
@@ -34,6 +35,8 @@ export function registerValidationChecks(services: LikeC4Services) {
|
|
|
34
35
|
SpecificationRule: specificationRuleChecks(services),
|
|
35
36
|
Model: modelRuleChecks(services),
|
|
36
37
|
Globals: globalsChecks(services),
|
|
38
|
+
GlobalPredicateGroup: globalPredicateChecks(services),
|
|
39
|
+
GlobalDynamicPredicateGroup: globalPredicateChecks(services),
|
|
37
40
|
GlobalStyleId: globalStyleIdChecks(services),
|
|
38
41
|
DynamicViewStep: dynamicViewStep(services),
|
|
39
42
|
LikeC4View: viewChecks(services),
|
|
@@ -130,6 +130,27 @@ export const relationshipChecks = (
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
export const globalPredicateChecks = (
|
|
134
|
+
services: LikeC4Services
|
|
135
|
+
): ValidationCheck<ast.GlobalPredicateGroup | ast.GlobalDynamicPredicateGroup> => {
|
|
136
|
+
const index = services.shared.workspace.IndexManager
|
|
137
|
+
return (node, accept) => {
|
|
138
|
+
const predicateGroups = index.allElements(ast.GlobalPredicateGroup)
|
|
139
|
+
const dynamicPredicateGroups = index.allElements(ast.GlobalDynamicPredicateGroup)
|
|
140
|
+
const sameName = predicateGroups
|
|
141
|
+
.concat(dynamicPredicateGroups)
|
|
142
|
+
.filter(s => s.name === node.name)
|
|
143
|
+
.limit(2)
|
|
144
|
+
.count()
|
|
145
|
+
if (sameName > 1) {
|
|
146
|
+
accept('error', `Duplicate GlobalPredicateGroup or GlobalDynamicPredicateGroup name '${node.name}'`, {
|
|
147
|
+
node: node,
|
|
148
|
+
property: 'name'
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
133
154
|
export const globalStyleIdChecks = (
|
|
134
155
|
services: LikeC4Services
|
|
135
156
|
): ValidationCheck<ast.GlobalStyleId> => {
|
package/src/view-utils/index.ts
CHANGED
|
@@ -1,72 +1,88 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type DynamicView,
|
|
3
|
+
type DynamicViewRule,
|
|
3
4
|
type ElementView,
|
|
4
|
-
type GlobalStyle,
|
|
5
|
-
type GlobalStyleID,
|
|
6
5
|
isDynamicView,
|
|
7
6
|
isElementView,
|
|
7
|
+
isViewRuleGlobalPredicateRef,
|
|
8
8
|
isViewRuleGlobalStyle,
|
|
9
|
-
type
|
|
10
|
-
nonexhaustive
|
|
9
|
+
type ModelGlobals,
|
|
10
|
+
nonexhaustive,
|
|
11
|
+
type ViewRule,
|
|
12
|
+
type ViewRuleGlobalPredicateRef,
|
|
13
|
+
type ViewRuleGlobalStyle
|
|
11
14
|
} from '@likec4/core'
|
|
12
15
|
import { logger } from '@likec4/log'
|
|
16
|
+
import { isNullish } from 'remeda'
|
|
13
17
|
|
|
14
|
-
export function resolveGlobalRules(
|
|
15
|
-
view:
|
|
16
|
-
|
|
17
|
-
):
|
|
18
|
+
export function resolveGlobalRules<V extends DynamicView | ElementView>(
|
|
19
|
+
view: V,
|
|
20
|
+
globals: ModelGlobals
|
|
21
|
+
): V {
|
|
18
22
|
if (isElementView(view)) {
|
|
19
|
-
return
|
|
23
|
+
return {
|
|
24
|
+
...view,
|
|
25
|
+
rules: resolveGlobalRulesInElementView(view, globals)
|
|
26
|
+
}
|
|
20
27
|
} else if (isDynamicView(view)) {
|
|
21
|
-
return
|
|
28
|
+
return {
|
|
29
|
+
...view,
|
|
30
|
+
rules: resolveGlobalRulesInDynamicView(view, globals)
|
|
31
|
+
}
|
|
22
32
|
}
|
|
23
33
|
nonexhaustive(view)
|
|
24
34
|
}
|
|
25
35
|
|
|
26
|
-
|
|
36
|
+
type ViewRuleGlobal = ViewRuleGlobalPredicateRef | ViewRuleGlobalStyle
|
|
37
|
+
|
|
38
|
+
export function resolveGlobalRulesInElementView(
|
|
27
39
|
view: ElementView,
|
|
28
|
-
|
|
29
|
-
):
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return []
|
|
37
|
-
}
|
|
38
|
-
return globalStyle.styles
|
|
39
|
-
} else {
|
|
40
|
-
return rule
|
|
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
|
|
41
48
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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>>)
|
|
48
62
|
}
|
|
49
63
|
|
|
50
|
-
function
|
|
64
|
+
export function resolveGlobalRulesInDynamicView(
|
|
51
65
|
view: DynamicView,
|
|
52
|
-
|
|
53
|
-
):
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return []
|
|
61
|
-
}
|
|
62
|
-
return globalStyle.styles
|
|
63
|
-
} else {
|
|
64
|
-
return rule
|
|
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
|
|
65
74
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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>>)
|
|
72
88
|
}
|