@likec4/language-server 1.17.0 → 1.18.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/protocol.d.cts +8 -5
- package/dist/protocol.d.mts +8 -5
- package/dist/protocol.d.ts +8 -5
- package/dist/shared/{language-server.DZRuJVSg.cjs → language-server.CO_nmHiL.cjs} +5605 -4215
- package/dist/shared/{language-server.DJo88TnT.d.cts → language-server.Da6ey08o.d.cts} +391 -110
- package/dist/shared/{language-server.PEjk7U9s.d.ts → language-server.De7S3e5Z.d.ts} +391 -110
- package/dist/shared/{language-server.BgDKnNok.d.mts → language-server.Dj4iDjtB.d.mts} +391 -110
- package/dist/shared/{language-server.B8qSDsWW.mjs → language-server.oO_9JoAG.mjs} +5594 -4215
- package/package.json +17 -31
- package/src/Rpc.ts +6 -3
- package/src/ast.ts +124 -71
- package/src/formatting/LikeC4Formatter.ts +9 -4
- package/src/generated/ast.ts +656 -40
- package/src/generated/grammar.ts +2 -2
- package/src/generated/module.ts +3 -2
- package/src/index.ts +1 -0
- package/src/like-c4.langium +170 -22
- package/src/logger.ts +7 -2
- package/src/lsp/CodeLensProvider.ts +0 -1
- package/src/lsp/CompletionProvider.ts +17 -2
- package/src/lsp/DocumentSymbolProvider.ts +5 -2
- package/src/lsp/HoverProvider.ts +34 -2
- package/src/lsp/SemanticTokenProvider.ts +58 -32
- package/src/model/deployments-index.ts +218 -0
- package/src/model/fqn-computation.ts +1 -1
- package/src/model/fqn-index.ts +0 -1
- package/src/model/index.ts +1 -0
- package/src/model/model-builder.ts +172 -37
- package/src/model/model-locator.ts +36 -7
- package/src/model/model-parser.ts +554 -92
- package/src/model-change/changeViewLayout.ts +2 -2
- package/src/module.ts +10 -4
- package/src/protocol.ts +10 -6
- package/src/references/index.ts +1 -0
- package/src/references/name-provider.ts +37 -0
- package/src/references/scope-computation.ts +130 -21
- package/src/references/scope-provider.ts +63 -36
- package/src/shared/NodeKindProvider.ts +15 -3
- package/src/utils/deploymentRef.ts +31 -0
- package/src/{elementRef.ts → utils/elementRef.ts} +1 -1
- package/src/utils/stringHash.ts +2 -2
- package/src/validation/_shared.ts +7 -5
- package/src/validation/deployment-checks.ts +144 -0
- package/src/validation/dynamic-view-step.ts +1 -1
- package/src/validation/index.ts +7 -0
- package/src/validation/relation.ts +1 -1
- package/src/validation/view-predicates/deployments.ts +56 -0
- package/src/validation/view-predicates/index.ts +1 -0
- package/src/view-utils/assignNavigateTo.ts +6 -5
- package/src/view-utils/index.ts +0 -1
- package/dist/model-graph/index.cjs +0 -10
- package/dist/model-graph/index.d.cts +0 -81
- package/dist/model-graph/index.d.mts +0 -81
- package/dist/model-graph/index.d.ts +0 -81
- package/dist/model-graph/index.mjs +0 -1
- package/dist/shared/language-server.BGGRJRnr.d.mts +0 -1338
- package/dist/shared/language-server.BXFhlTPo.mjs +0 -1953
- package/dist/shared/language-server.Bmpq16Gw.d.ts +0 -1338
- package/dist/shared/language-server.C1ZfM22X.d.cts +0 -1338
- package/dist/shared/language-server.N8HLDQqz.cjs +0 -1967
- package/src/model-graph/LikeC4ModelGraph.ts +0 -338
- package/src/model-graph/compute-view/__test__/fixture.ts +0 -630
- package/src/model-graph/compute-view/compute.ts +0 -788
- package/src/model-graph/compute-view/index.ts +0 -33
- package/src/model-graph/compute-view/predicates.ts +0 -509
- package/src/model-graph/dynamic-view/__test__/fixture.ts +0 -61
- package/src/model-graph/dynamic-view/compute.ts +0 -281
- package/src/model-graph/dynamic-view/index.ts +0 -29
- package/src/model-graph/index.ts +0 -3
- package/src/model-graph/utils/applyCustomElementProperties.ts +0 -65
- package/src/model-graph/utils/applyCustomRelationProperties.ts +0 -41
- package/src/model-graph/utils/applyViewRuleStyles.ts +0 -49
- package/src/model-graph/utils/buildComputeNodes.ts +0 -113
- package/src/model-graph/utils/buildElementNotations.ts +0 -63
- package/src/model-graph/utils/elementExpressionToPredicate.ts +0 -39
- package/src/model-graph/utils/relationExpressionToPredicates.ts +0 -43
- package/src/model-graph/utils/sortNodes.ts +0 -105
- package/src/model-graph/utils/uniqueTags.test.ts +0 -42
- package/src/model-graph/utils/uniqueTags.ts +0 -19
- package/src/utils/graphlib.ts +0 -9
- package/src/view-utils/resolve-extended-views.ts +0 -66
- package/src/view-utils/resolve-global-rules.ts +0 -88
- package/src/view-utils/view-hash.ts +0 -27
|
@@ -1,630 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type BorderStyle,
|
|
3
|
-
type Color,
|
|
4
|
-
type ComputedView,
|
|
5
|
-
type CustomElementExpr as C4CustomElementExpr,
|
|
6
|
-
type CustomRelationExpr as C4CustomRelationExpr,
|
|
7
|
-
type Element,
|
|
8
|
-
type ElementExpression as C4ElementExpression,
|
|
9
|
-
type ElementKind,
|
|
10
|
-
type ElementShape,
|
|
11
|
-
type ElementWhereExpr,
|
|
12
|
-
type Expression as C4Expression,
|
|
13
|
-
type Fqn,
|
|
14
|
-
type GlobalStyleID,
|
|
15
|
-
type IconUrl,
|
|
16
|
-
type IncomingExpr as C4IncomingExpr,
|
|
17
|
-
type InOutExpr as C4InOutExpr,
|
|
18
|
-
isElementRef,
|
|
19
|
-
isElementWhere,
|
|
20
|
-
isRelationExpression,
|
|
21
|
-
isRelationWhere,
|
|
22
|
-
type NonEmptyArray,
|
|
23
|
-
type OutgoingExpr as C4OutgoingExpr,
|
|
24
|
-
type Relation,
|
|
25
|
-
type RelationExpr as C4RelationExpr,
|
|
26
|
-
type RelationID,
|
|
27
|
-
type RelationshipArrowType,
|
|
28
|
-
type RelationshipLineType,
|
|
29
|
-
type RelationWhereExpr,
|
|
30
|
-
type Tag,
|
|
31
|
-
type ViewID,
|
|
32
|
-
type ViewRule,
|
|
33
|
-
type ViewRuleGlobalStyle,
|
|
34
|
-
type ViewRuleGroup,
|
|
35
|
-
type ViewRulePredicate,
|
|
36
|
-
type ViewRuleStyle,
|
|
37
|
-
type WhereOperator
|
|
38
|
-
} from '@likec4/core'
|
|
39
|
-
import { indexBy, isString, map, prop } from 'remeda'
|
|
40
|
-
import { LikeC4ModelGraph } from '../../LikeC4ModelGraph'
|
|
41
|
-
import { computeElementView } from '../index'
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
┌──────────────────────────────────────────────────┐
|
|
45
|
-
│ cloud │
|
|
46
|
-
│ ┌───────────────────────────────────────────┐ │
|
|
47
|
-
│ │ frontend │ │
|
|
48
|
-
┏━━━━━━━━━━┓ │ │ ┏━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━┓ │ │ ┏━━━━━━━━━━━┓
|
|
49
|
-
┃ ┃ │ │ ┃ ┃ ┃ ┃ │ │ ┃ ┃
|
|
50
|
-
┃ customer ┃──┼──┼──▶┃ dashboard ┃ ┃ adminpanel ┃◀───┼───┼───┃ support ┃
|
|
51
|
-
┃ ┃ │ │ ┃ ┃ ┃ ┃ │ │ ┃ ┃
|
|
52
|
-
┗━━━━━━━━━━┛ │ │ ┗━━━━━━┳━━━━━━┛ ┗━━━━━━━━┳━━━━━━━┛ │ │ ┗━━━━━━━━━━━┛
|
|
53
|
-
│ └──────────┼───────────────────┼────────────┘ │
|
|
54
|
-
│ ├───────────────────┘ │
|
|
55
|
-
│ │ │
|
|
56
|
-
│ ┌──────────┼────────────────────────────────┐ │
|
|
57
|
-
│ │ ▼ backend │ │
|
|
58
|
-
│ │ ┏━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━┓ │ │
|
|
59
|
-
│ │ ┃ ┃ ┃ ┃ │ │
|
|
60
|
-
│ │ ┃ graphlql ┃──────▶┃ storage ┃ │ │
|
|
61
|
-
│ │ ┃ ┃ ┃ ┃ │ │
|
|
62
|
-
│ │ ┗━━━━━━━━━━━━━┛ ┗━━━━━━┳━━━━━━┛ │ │
|
|
63
|
-
│ └────────────────────────────────┼──────────┘ │
|
|
64
|
-
└───────────────────────────────────┼──────────────┘
|
|
65
|
-
│
|
|
66
|
-
┌─────────┼─────────┐
|
|
67
|
-
│ amazon │ │
|
|
68
|
-
│ ▼ │
|
|
69
|
-
│ ┏━━━━━━━━━━━━━━┓ │
|
|
70
|
-
│ ┃ ┃ │
|
|
71
|
-
│ ┃ s3 ┃ │
|
|
72
|
-
│ ┃ ┃ │
|
|
73
|
-
│ ┗━━━━━━━━━━━━━━┛ │
|
|
74
|
-
└───────────────────┘
|
|
75
|
-
|
|
76
|
-
specification {
|
|
77
|
-
element actor
|
|
78
|
-
element system
|
|
79
|
-
element container
|
|
80
|
-
element component
|
|
81
|
-
|
|
82
|
-
tag old
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
model {
|
|
86
|
-
|
|
87
|
-
actor customer
|
|
88
|
-
actor support
|
|
89
|
-
|
|
90
|
-
system cloud {
|
|
91
|
-
container backend {
|
|
92
|
-
component graphql
|
|
93
|
-
component storage {
|
|
94
|
-
#old
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
graphql -> storage
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
container frontend {
|
|
101
|
-
component dashboard {
|
|
102
|
-
-> graphql
|
|
103
|
-
}
|
|
104
|
-
component adminPanel {
|
|
105
|
-
#old
|
|
106
|
-
-> graphql
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
customer -> dashboard
|
|
112
|
-
support -> adminPanel
|
|
113
|
-
|
|
114
|
-
system amazon {
|
|
115
|
-
component s3
|
|
116
|
-
|
|
117
|
-
cloud.backend.storage -> s3
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
*/
|
|
123
|
-
type TestTag = 'old' | 'next' | 'aws' | 'storage' | 'communication' | 'legacy'
|
|
124
|
-
|
|
125
|
-
const el = ({
|
|
126
|
-
id,
|
|
127
|
-
kind,
|
|
128
|
-
title,
|
|
129
|
-
style,
|
|
130
|
-
tags,
|
|
131
|
-
...props
|
|
132
|
-
}: Partial<Omit<Element, 'id' | 'kind' | 'tags'>> & {
|
|
133
|
-
id: string
|
|
134
|
-
kind: string
|
|
135
|
-
tags?: NonEmptyArray<TestTag>
|
|
136
|
-
}): Element => ({
|
|
137
|
-
id: id as Fqn,
|
|
138
|
-
kind: kind as ElementKind,
|
|
139
|
-
title: title ?? id,
|
|
140
|
-
description: null,
|
|
141
|
-
technology: null,
|
|
142
|
-
tags: tags as NonEmptyArray<Tag> ?? null,
|
|
143
|
-
links: null,
|
|
144
|
-
style: {
|
|
145
|
-
...style
|
|
146
|
-
},
|
|
147
|
-
...props
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
export const fakeElements = {
|
|
151
|
-
'customer': el({
|
|
152
|
-
id: 'customer',
|
|
153
|
-
kind: 'actor',
|
|
154
|
-
title: 'customer',
|
|
155
|
-
shape: 'person'
|
|
156
|
-
}),
|
|
157
|
-
'support': el({
|
|
158
|
-
id: 'support',
|
|
159
|
-
kind: 'actor',
|
|
160
|
-
title: 'support',
|
|
161
|
-
shape: 'person'
|
|
162
|
-
}),
|
|
163
|
-
'cloud': el({
|
|
164
|
-
id: 'cloud',
|
|
165
|
-
kind: 'system',
|
|
166
|
-
title: 'cloud',
|
|
167
|
-
icon: 'none',
|
|
168
|
-
tags: ['next', 'old']
|
|
169
|
-
}),
|
|
170
|
-
'cloud.backend': el({
|
|
171
|
-
id: 'cloud.backend',
|
|
172
|
-
kind: 'container',
|
|
173
|
-
title: 'backend'
|
|
174
|
-
}),
|
|
175
|
-
'cloud.frontend': el({
|
|
176
|
-
id: 'cloud.frontend',
|
|
177
|
-
kind: 'container',
|
|
178
|
-
title: 'frontend',
|
|
179
|
-
shape: 'browser'
|
|
180
|
-
}),
|
|
181
|
-
'cloud.backend.graphql': el({
|
|
182
|
-
id: 'cloud.backend.graphql',
|
|
183
|
-
kind: 'component',
|
|
184
|
-
icon: 'tech:graphql' as IconUrl,
|
|
185
|
-
title: 'graphql'
|
|
186
|
-
}),
|
|
187
|
-
'email': el({
|
|
188
|
-
id: 'email',
|
|
189
|
-
kind: 'system',
|
|
190
|
-
title: 'email'
|
|
191
|
-
}),
|
|
192
|
-
'cloud.backend.storage': el({
|
|
193
|
-
id: 'cloud.backend.storage',
|
|
194
|
-
kind: 'component',
|
|
195
|
-
title: 'storage',
|
|
196
|
-
tags: ['storage', 'old']
|
|
197
|
-
}),
|
|
198
|
-
'cloud.frontend.adminPanel': el({
|
|
199
|
-
id: 'cloud.frontend.adminPanel',
|
|
200
|
-
kind: 'component',
|
|
201
|
-
title: 'adminPanel',
|
|
202
|
-
tags: ['old']
|
|
203
|
-
}),
|
|
204
|
-
'cloud.frontend.dashboard': el({
|
|
205
|
-
id: 'cloud.frontend.dashboard',
|
|
206
|
-
kind: 'component',
|
|
207
|
-
title: 'dashboard',
|
|
208
|
-
icon: 'tech:react' as IconUrl,
|
|
209
|
-
tags: ['next']
|
|
210
|
-
}),
|
|
211
|
-
'amazon': el({
|
|
212
|
-
id: 'amazon',
|
|
213
|
-
kind: 'system',
|
|
214
|
-
title: 'amazon',
|
|
215
|
-
icon: 'tech:aws' as IconUrl,
|
|
216
|
-
tags: ['aws']
|
|
217
|
-
}),
|
|
218
|
-
'amazon.s3': el({
|
|
219
|
-
id: 'amazon.s3',
|
|
220
|
-
kind: 'component',
|
|
221
|
-
title: 's3',
|
|
222
|
-
shape: 'storage',
|
|
223
|
-
icon: 'aws:s3' as IconUrl,
|
|
224
|
-
tags: ['aws', 'storage']
|
|
225
|
-
})
|
|
226
|
-
} satisfies Record<string, Element>
|
|
227
|
-
|
|
228
|
-
export type FakeElementIds = keyof typeof fakeElements
|
|
229
|
-
|
|
230
|
-
const rel = <Source extends FakeElementIds, Target extends FakeElementIds>({
|
|
231
|
-
source,
|
|
232
|
-
target,
|
|
233
|
-
title,
|
|
234
|
-
...props
|
|
235
|
-
}: {
|
|
236
|
-
source: Source
|
|
237
|
-
target: Target
|
|
238
|
-
title?: string
|
|
239
|
-
kind?: string
|
|
240
|
-
color?: Color
|
|
241
|
-
line?: RelationshipLineType
|
|
242
|
-
head?: RelationshipArrowType
|
|
243
|
-
tail?: RelationshipArrowType
|
|
244
|
-
tags?: NonEmptyArray<TestTag>
|
|
245
|
-
}) =>
|
|
246
|
-
({
|
|
247
|
-
id: `${source}:${target}` as RelationID,
|
|
248
|
-
title: title ?? '',
|
|
249
|
-
source: source as Fqn,
|
|
250
|
-
target: target as Fqn,
|
|
251
|
-
...(props as any)
|
|
252
|
-
}) as Omit<Relation, 'id'> & { id: `${Source}:${Target}` }
|
|
253
|
-
|
|
254
|
-
export const fakeRelations = [
|
|
255
|
-
rel({
|
|
256
|
-
source: 'customer',
|
|
257
|
-
target: 'cloud.frontend.dashboard',
|
|
258
|
-
title: 'opens in browser'
|
|
259
|
-
}),
|
|
260
|
-
rel({
|
|
261
|
-
source: 'support',
|
|
262
|
-
target: 'cloud.frontend.adminPanel',
|
|
263
|
-
title: 'manages'
|
|
264
|
-
}),
|
|
265
|
-
rel({
|
|
266
|
-
source: 'cloud.backend.storage',
|
|
267
|
-
target: 'amazon.s3',
|
|
268
|
-
title: 'uploads',
|
|
269
|
-
tags: ['aws', 'storage', 'legacy']
|
|
270
|
-
}),
|
|
271
|
-
rel({
|
|
272
|
-
source: 'customer',
|
|
273
|
-
target: 'cloud',
|
|
274
|
-
title: 'uses'
|
|
275
|
-
}),
|
|
276
|
-
rel({
|
|
277
|
-
source: 'cloud.backend.graphql',
|
|
278
|
-
target: 'cloud.backend.storage',
|
|
279
|
-
title: 'stores',
|
|
280
|
-
tags: ['old', 'storage']
|
|
281
|
-
}),
|
|
282
|
-
// rel({
|
|
283
|
-
// source: 'cloud.backend',
|
|
284
|
-
// target: 'cloud.email',
|
|
285
|
-
// title: 'schedule emails'
|
|
286
|
-
// }),
|
|
287
|
-
// rel({
|
|
288
|
-
// source: 'cloud.email',
|
|
289
|
-
// target: 'customer',
|
|
290
|
-
// title: 'send emails'
|
|
291
|
-
// }),
|
|
292
|
-
rel({
|
|
293
|
-
source: 'cloud.frontend',
|
|
294
|
-
target: 'cloud.backend',
|
|
295
|
-
title: 'requests'
|
|
296
|
-
}),
|
|
297
|
-
rel({
|
|
298
|
-
source: 'cloud.frontend.dashboard',
|
|
299
|
-
target: 'cloud.backend.graphql',
|
|
300
|
-
kind: 'graphlql',
|
|
301
|
-
title: 'requests',
|
|
302
|
-
line: 'solid',
|
|
303
|
-
tags: ['next']
|
|
304
|
-
}),
|
|
305
|
-
rel({
|
|
306
|
-
source: 'cloud.frontend.adminPanel',
|
|
307
|
-
target: 'cloud.backend.graphql',
|
|
308
|
-
kind: 'graphlql',
|
|
309
|
-
title: 'fetches',
|
|
310
|
-
line: 'dashed',
|
|
311
|
-
tail: 'odiamond',
|
|
312
|
-
tags: ['old']
|
|
313
|
-
}),
|
|
314
|
-
rel({
|
|
315
|
-
source: 'cloud',
|
|
316
|
-
target: 'amazon',
|
|
317
|
-
title: 'uses',
|
|
318
|
-
head: 'diamond',
|
|
319
|
-
tail: 'odiamond',
|
|
320
|
-
tags: ['aws']
|
|
321
|
-
}),
|
|
322
|
-
rel({
|
|
323
|
-
source: 'cloud.backend',
|
|
324
|
-
target: 'email',
|
|
325
|
-
title: 'schedule',
|
|
326
|
-
tags: ['communication']
|
|
327
|
-
}),
|
|
328
|
-
rel({
|
|
329
|
-
source: 'cloud',
|
|
330
|
-
target: 'email',
|
|
331
|
-
title: 'uses',
|
|
332
|
-
tags: ['communication']
|
|
333
|
-
}),
|
|
334
|
-
rel({
|
|
335
|
-
source: 'email',
|
|
336
|
-
target: 'cloud',
|
|
337
|
-
title: 'notifies',
|
|
338
|
-
tags: ['communication']
|
|
339
|
-
})
|
|
340
|
-
]
|
|
341
|
-
|
|
342
|
-
export const globalStyles = {
|
|
343
|
-
'mute_old': [{
|
|
344
|
-
targets: [$expr({
|
|
345
|
-
elementTag: 'old' as Tag,
|
|
346
|
-
isEqual: true
|
|
347
|
-
})],
|
|
348
|
-
style: {
|
|
349
|
-
color: 'muted'
|
|
350
|
-
}
|
|
351
|
-
}],
|
|
352
|
-
'red_next': [{
|
|
353
|
-
targets: [$expr({
|
|
354
|
-
elementTag: 'next' as Tag,
|
|
355
|
-
isEqual: true
|
|
356
|
-
})],
|
|
357
|
-
style: {
|
|
358
|
-
color: 'red'
|
|
359
|
-
}
|
|
360
|
-
}]
|
|
361
|
-
} as const
|
|
362
|
-
|
|
363
|
-
export type FakeRelationIds = (typeof fakeRelations)[number]['id']
|
|
364
|
-
|
|
365
|
-
export const fakeModel = new LikeC4ModelGraph({
|
|
366
|
-
elements: fakeElements,
|
|
367
|
-
relations: indexBy(fakeRelations, r => r.id),
|
|
368
|
-
globals: {
|
|
369
|
-
predicates: {},
|
|
370
|
-
dynamicPredicates: {},
|
|
371
|
-
styles: globalStyles
|
|
372
|
-
}
|
|
373
|
-
})
|
|
374
|
-
|
|
375
|
-
const emptyView = {
|
|
376
|
-
__: 'element' as const,
|
|
377
|
-
id: 'index' as ViewID,
|
|
378
|
-
title: null,
|
|
379
|
-
description: null,
|
|
380
|
-
tags: null,
|
|
381
|
-
links: null,
|
|
382
|
-
customColorDefinitions: {},
|
|
383
|
-
rules: []
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
export const includeWildcard = {
|
|
387
|
-
include: [
|
|
388
|
-
{
|
|
389
|
-
wildcard: true
|
|
390
|
-
}
|
|
391
|
-
]
|
|
392
|
-
} satisfies ViewRule
|
|
393
|
-
|
|
394
|
-
export type ElementRefExpr = '*' | FakeElementIds | `${FakeElementIds}.*` | `${FakeElementIds}._`
|
|
395
|
-
|
|
396
|
-
type InOutExpr = `-> ${ElementRefExpr} ->`
|
|
397
|
-
type IncomingExpr = `-> ${ElementRefExpr}`
|
|
398
|
-
type OutgoingExpr = `${ElementRefExpr} ->`
|
|
399
|
-
type RelationKeyword = '->' | '<->'
|
|
400
|
-
type RelationExpr = `${ElementRefExpr} ${RelationKeyword} ${ElementRefExpr}`
|
|
401
|
-
|
|
402
|
-
export type Expression =
|
|
403
|
-
| ElementRefExpr
|
|
404
|
-
| InOutExpr
|
|
405
|
-
| IncomingExpr
|
|
406
|
-
| OutgoingExpr
|
|
407
|
-
| RelationExpr
|
|
408
|
-
|
|
409
|
-
export function $custom(
|
|
410
|
-
expr: ElementRefExpr,
|
|
411
|
-
props: {
|
|
412
|
-
title?: string
|
|
413
|
-
description?: string
|
|
414
|
-
technology?: string
|
|
415
|
-
shape?: ElementShape
|
|
416
|
-
color?: Color
|
|
417
|
-
border?: BorderStyle
|
|
418
|
-
icon?: string
|
|
419
|
-
opacity?: number
|
|
420
|
-
navigateTo?: string
|
|
421
|
-
}
|
|
422
|
-
): C4CustomElementExpr {
|
|
423
|
-
return {
|
|
424
|
-
custom: {
|
|
425
|
-
expr: $expr(expr) as any,
|
|
426
|
-
...props as any
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
export function $customRelation(
|
|
432
|
-
relation: RelationExpr,
|
|
433
|
-
props: Omit<C4CustomRelationExpr['customRelation'], 'relation'>
|
|
434
|
-
): C4CustomRelationExpr {
|
|
435
|
-
return {
|
|
436
|
-
customRelation: {
|
|
437
|
-
relation: $expr(relation) as any,
|
|
438
|
-
...props
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
export function $where(
|
|
444
|
-
expr: Expression | C4Expression,
|
|
445
|
-
operator: WhereOperator<TestTag, string>
|
|
446
|
-
): ElementWhereExpr | RelationWhereExpr {
|
|
447
|
-
return {
|
|
448
|
-
where: {
|
|
449
|
-
expr: $expr(expr) as any,
|
|
450
|
-
condition: operator
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
export function $inout(
|
|
456
|
-
expr: InOutExpr | C4ElementExpression
|
|
457
|
-
): C4InOutExpr {
|
|
458
|
-
const innerExpression = !isString(expr)
|
|
459
|
-
? expr as C4Expression
|
|
460
|
-
: $expr(expr.replace(/->/g, '').trim() as ElementRefExpr) as any
|
|
461
|
-
|
|
462
|
-
return { inout: innerExpression }
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
export function $incoming(
|
|
466
|
-
expr: IncomingExpr | C4ElementExpression
|
|
467
|
-
): C4IncomingExpr {
|
|
468
|
-
const innerExpression = !isString(expr)
|
|
469
|
-
? expr as C4Expression
|
|
470
|
-
: $expr(expr.replace('-> ', '') as ElementRefExpr) as any
|
|
471
|
-
|
|
472
|
-
return { incoming: innerExpression }
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
export function $outgoing(
|
|
476
|
-
expr: OutgoingExpr | C4ElementExpression
|
|
477
|
-
): C4OutgoingExpr {
|
|
478
|
-
const innerExpression = !isString(expr)
|
|
479
|
-
? expr as C4Expression
|
|
480
|
-
: $expr(expr.replace(' ->', '') as ElementRefExpr) as any
|
|
481
|
-
|
|
482
|
-
return { outgoing: innerExpression }
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
export function $relation(
|
|
486
|
-
expr: RelationExpr
|
|
487
|
-
): C4RelationExpr {
|
|
488
|
-
const [source, target] = expr.split(/ -> | <-> /)
|
|
489
|
-
const isBidirectional = expr.includes(' <-> ')
|
|
490
|
-
|
|
491
|
-
return {
|
|
492
|
-
source: $expr(source as ElementRefExpr) as any,
|
|
493
|
-
target: $expr(target as ElementRefExpr) as any,
|
|
494
|
-
...(isBidirectional && { isBidirectional })
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
export function $expr(expr: Expression | C4Expression): C4Expression {
|
|
499
|
-
if (!isString(expr)) {
|
|
500
|
-
return expr as C4Expression
|
|
501
|
-
}
|
|
502
|
-
if (expr === '*') {
|
|
503
|
-
return { wildcard: true }
|
|
504
|
-
}
|
|
505
|
-
if (expr.startsWith('->')) {
|
|
506
|
-
return expr.endsWith('->') ? $inout(expr as InOutExpr) : $incoming(expr as IncomingExpr)
|
|
507
|
-
}
|
|
508
|
-
if (expr.endsWith(' ->')) {
|
|
509
|
-
return $outgoing(expr as OutgoingExpr)
|
|
510
|
-
}
|
|
511
|
-
if (expr.includes(' -> ') || expr.includes(' <-> ')) {
|
|
512
|
-
return $relation(expr as RelationExpr)
|
|
513
|
-
}
|
|
514
|
-
if (expr.endsWith('._')) {
|
|
515
|
-
return {
|
|
516
|
-
expanded: expr.replace('._', '') as Fqn
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
if (expr.endsWith('.*')) {
|
|
520
|
-
return {
|
|
521
|
-
element: expr.replace('.*', '') as Fqn,
|
|
522
|
-
isDescedants: true
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
return {
|
|
526
|
-
element: expr as Fqn,
|
|
527
|
-
isDescedants: false
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
type CustomProps = {
|
|
532
|
-
where?: WhereOperator<TestTag, string>
|
|
533
|
-
with?: {
|
|
534
|
-
title?: string
|
|
535
|
-
description?: string
|
|
536
|
-
technology?: string
|
|
537
|
-
shape?: ElementShape
|
|
538
|
-
color?: Color
|
|
539
|
-
border?: BorderStyle
|
|
540
|
-
icon?: string
|
|
541
|
-
opacity?: number
|
|
542
|
-
navigateTo?: string
|
|
543
|
-
} & Omit<C4CustomRelationExpr['customRelation'], 'relation' | 'navigateTo'>
|
|
544
|
-
}
|
|
545
|
-
export function $include(expr: Expression | C4Expression, props?: CustomProps): ViewRulePredicate {
|
|
546
|
-
let _expr = props?.where ? $where(expr, props.where) : $expr(expr)
|
|
547
|
-
_expr = props?.with ? $with(_expr, props.with) : _expr
|
|
548
|
-
return {
|
|
549
|
-
include: [_expr]
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
export function $with(expr: C4Expression, props?: CustomProps['with']): C4CustomRelationExpr | C4CustomElementExpr {
|
|
553
|
-
if (isRelationExpression(expr) || isRelationWhere(expr)) {
|
|
554
|
-
return {
|
|
555
|
-
customRelation: {
|
|
556
|
-
relation: expr,
|
|
557
|
-
...props as any
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
} else if (isElementRef(expr) || isElementWhere(expr)) {
|
|
561
|
-
return {
|
|
562
|
-
custom: {
|
|
563
|
-
expr: expr,
|
|
564
|
-
...props as any
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
throw 'Unsupported type of internal expression'
|
|
570
|
-
}
|
|
571
|
-
export function $exclude(expr: Expression | C4Expression, where?: WhereOperator<TestTag, string>): ViewRulePredicate {
|
|
572
|
-
let _expr = where ? $where(expr, where) : $expr(expr)
|
|
573
|
-
return {
|
|
574
|
-
exclude: [_expr]
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
export function $group(groupRules: ViewRuleGroup['groupRules']): ViewRuleGroup {
|
|
578
|
-
return {
|
|
579
|
-
title: null,
|
|
580
|
-
groupRules
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
export function $style(element: ElementRefExpr, style: ViewRuleStyle['style']): ViewRuleStyle {
|
|
585
|
-
return {
|
|
586
|
-
targets: [$expr(element) as C4ElementExpression],
|
|
587
|
-
style: Object.assign({}, style)
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
type GlobalStyles = keyof typeof globalStyles
|
|
592
|
-
type GlobalExpr = `style ${GlobalStyles}`
|
|
593
|
-
export function $global(expr: GlobalExpr): ViewRuleGlobalStyle {
|
|
594
|
-
const [_t, id] = expr.split(' ') as [string, string]
|
|
595
|
-
if (_t === 'style') {
|
|
596
|
-
return {
|
|
597
|
-
styleId: id as GlobalStyleID
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
throw new Error('Invalid global expression')
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
export function computeView(
|
|
604
|
-
...args: [FakeElementIds, ViewRule | ViewRule[]] | [ViewRule | ViewRule[]]
|
|
605
|
-
) {
|
|
606
|
-
let result: ComputedView
|
|
607
|
-
if (args.length === 1) {
|
|
608
|
-
result = computeElementView(
|
|
609
|
-
{
|
|
610
|
-
...emptyView,
|
|
611
|
-
rules: [args[0]].flat()
|
|
612
|
-
},
|
|
613
|
-
fakeModel
|
|
614
|
-
)
|
|
615
|
-
} else {
|
|
616
|
-
result = computeElementView(
|
|
617
|
-
{
|
|
618
|
-
...emptyView,
|
|
619
|
-
id: 'index' as ViewID,
|
|
620
|
-
viewOf: args[0] as Fqn,
|
|
621
|
-
rules: [args[1]].flat()
|
|
622
|
-
},
|
|
623
|
-
fakeModel
|
|
624
|
-
)
|
|
625
|
-
}
|
|
626
|
-
return Object.assign(result, {
|
|
627
|
-
nodeIds: map(result.nodes, prop('id')) as string[],
|
|
628
|
-
edgeIds: map(result.edges, prop('id')) as string[]
|
|
629
|
-
})
|
|
630
|
-
}
|