@likec4/generators 1.52.0 → 1.53.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.
@@ -0,0 +1,321 @@
1
+ import * as z from 'zod/v4'
2
+
3
+ import type {
4
+ AnyViewRuleStyle,
5
+ FqnExpr,
6
+ ViewAutoLayout,
7
+ ViewRuleGlobalPredicateRef,
8
+ ViewRuleGlobalStyle,
9
+ ViewRulePredicate,
10
+ ViewRuleRank,
11
+ } from '@likec4/core'
12
+ import { isNonNullish, pickBy } from 'remeda'
13
+ import * as common from './common'
14
+ import * as schemas from './expression'
15
+
16
+ // ============ View Expression & Rule Schemas ============
17
+
18
+ export const autoLayoutDirection = z.literal(['TB', 'BT', 'LR', 'RL'])
19
+
20
+ // ---- Element View Rule Schemas ----
21
+
22
+ export const viewRuleAutoLayout = z
23
+ .object({
24
+ direction: autoLayoutDirection,
25
+ nodeSep: z.number().optional(),
26
+ rankSep: z.number().optional(),
27
+ })
28
+ .transform(v => v as ViewAutoLayout)
29
+
30
+ export const viewRuleInclude = z.strictObject({ include: z.array(schemas.expression) })
31
+ export const viewRuleExclude = z.strictObject({ exclude: z.array(schemas.expression) })
32
+
33
+ export const viewRulePredicate = z
34
+ .union([
35
+ viewRuleInclude,
36
+ viewRuleExclude,
37
+ ])
38
+ .transform(v => v as ViewRulePredicate)
39
+
40
+ export const viewRuleStyle = z
41
+ .object({
42
+ targets: z.array(schemas.fqnExpr),
43
+ notation: z.string().optional(),
44
+ style: common.style,
45
+ })
46
+ .transform(v => v as AnyViewRuleStyle<FqnExpr>)
47
+
48
+ export const viewRuleGlobalStyle = z.object({ styleId: z.string() })
49
+ .transform(v => v as ViewRuleGlobalStyle)
50
+ export const viewRuleGlobalPredicate = z.object({ predicateId: z.string() })
51
+ .transform(v => v as ViewRuleGlobalPredicateRef)
52
+
53
+ const rankValue = z.literal(['max', 'min', 'same', 'sink', 'source'])
54
+ export const viewRuleRank = z
55
+ .object({
56
+ targets: z.array(schemas.fqnExpr),
57
+ rank: rankValue,
58
+ })
59
+ .transform(v => v as ViewRuleRank<FqnExpr>)
60
+
61
+ // Manually typed due to recursive z.lazy schema
62
+ export type ViewRuleGroupInput = {
63
+ groupRules: Array<z.input<typeof viewRulePredicate> | ViewRuleGroupInput>
64
+ title: string | null
65
+ color?: z.input<typeof common.color> | undefined
66
+ border?: z.input<typeof common.border> | undefined
67
+ opacity?: number | undefined
68
+ multiple?: boolean | undefined
69
+ size?: z.input<typeof common.size> | undefined
70
+ padding?: z.input<typeof common.size> | undefined
71
+ textSize?: z.input<typeof common.size> | undefined
72
+ }
73
+
74
+ export type ViewRuleGroupOutput = {
75
+ groupRules: Array<z.infer<typeof viewRulePredicate> | ViewRuleGroupOutput>
76
+ title: string | null
77
+ color?: z.infer<typeof common.color> | undefined
78
+ border?: z.infer<typeof common.border> | undefined
79
+ opacity?: number | undefined
80
+ multiple?: boolean | undefined
81
+ size?: z.infer<typeof common.size> | undefined
82
+ padding?: z.infer<typeof common.size> | undefined
83
+ textSize?: z.infer<typeof common.size> | undefined
84
+ }
85
+
86
+ export const viewRuleGroup: z.ZodType<ViewRuleGroupOutput, ViewRuleGroupInput> = z.lazy(() =>
87
+ z.object({
88
+ groupRules: z.array(z.union([viewRulePredicate, viewRuleGroup])),
89
+ title: z.string().nullable(),
90
+ color: common.color.optional(),
91
+ border: common.border.optional(),
92
+ opacity: common.opacity.optional(),
93
+ multiple: z.boolean().optional(),
94
+ size: common.size.optional(),
95
+ padding: common.size.optional(),
96
+ textSize: common.size.optional(),
97
+ })
98
+ )
99
+
100
+ export const elementViewRule = z
101
+ .union([
102
+ viewRulePredicate,
103
+ viewRuleAutoLayout,
104
+ viewRuleStyle,
105
+ viewRuleGlobalStyle,
106
+ viewRuleGlobalPredicate,
107
+ viewRuleRank,
108
+ viewRuleGroup,
109
+ ])
110
+
111
+ const viewProps = z.object({
112
+ id: common.viewId,
113
+ _stage: z.literal('parsed').default('parsed'),
114
+ title: z.string().nullish(),
115
+ description: common.markdownOrString.nullish(),
116
+ tags: common.tags.nullish(),
117
+ links: common.links.nullish(),
118
+ })
119
+
120
+ // ---- Element View Schema ----
121
+
122
+ /**
123
+ * Replicates ParsedElementView from the core,
124
+ * less strict, as the generator should be able to handle missing fields and provide defaults.
125
+ */
126
+ export const elementView = viewProps
127
+ .extend({
128
+ _type: z.literal('element'),
129
+ viewOf: common.fqn.nullish(),
130
+ extends: common.viewId.nullish(),
131
+ rules: z.array(elementViewRule).optional().default([]),
132
+ })
133
+ // .transform(v => ({
134
+ // ...pickBy(v, isNonNullish),
135
+ // title: v.title ?? null,
136
+ // description: v.description ?? null,
137
+ // rules: v.rules,
138
+ // }))
139
+
140
+ // ---- Deployment View Schema ----
141
+
142
+ export const deploymentViewRule = z
143
+ .union([
144
+ viewRulePredicate,
145
+ viewRuleAutoLayout,
146
+ viewRuleStyle,
147
+ viewRuleGlobalStyle,
148
+ viewRuleGlobalPredicate,
149
+ ])
150
+
151
+ /**
152
+ * Replicates ParsedElementView from the core,
153
+ * less strict, as the generator should be able to handle missing fields and provide defaults.
154
+ */
155
+ export const deploymentView = viewProps
156
+ .extend({
157
+ _type: z.literal('deployment'),
158
+ rules: z.array(deploymentViewRule).optional().default([]),
159
+ })
160
+ // .transform(v => ({
161
+ // ...pickBy(v, isNonNullish),
162
+ // title: v.title ?? null,
163
+ // description: v.description ?? null,
164
+ // rules: v.rules,
165
+ // }))
166
+
167
+ // ---- Dynamic View Schema ----
168
+
169
+ export const dynamicStep = z
170
+ .object({
171
+ source: common.fqn,
172
+ target: common.fqn,
173
+ title: z.string().nullish().default(null),
174
+ kind: z.string().nullish(),
175
+ description: common.markdownOrString.nullish(),
176
+ technology: z.string().nullish(),
177
+ notation: z.string().nullish(),
178
+ notes: common.markdownOrString.nullish(),
179
+ color: common.color.optional(),
180
+ line: common.line.optional(),
181
+ head: common.arrow.optional(),
182
+ tail: common.arrow.optional(),
183
+ isBackward: z.boolean().optional(),
184
+ navigateTo: common.viewId.nullish(),
185
+ // __parallel: z.never().optional(),
186
+ // __series: z.never().optional(),
187
+ })
188
+ .readonly()
189
+ .transform(pickBy(isNonNullish))
190
+
191
+ export const dynamicStepsSeries = z
192
+ .object({
193
+ // source: z.never().optional(),
194
+ // target: z.never().optional(),
195
+ seriesId: z.string().optional(),
196
+ __series: z.array(z.any()).readonly(),
197
+ // __parallel: z.never().optional(),
198
+ // __series: z.array(dynamicStep).nonempty(),
199
+ })
200
+ .readonly()
201
+ .transform(pickBy(isNonNullish))
202
+
203
+ export const dynamicStepsParallel = z.object({
204
+ // source: z.never().optional(),
205
+ // target: z.never().optional(),
206
+ // __series: z.never().optional(),
207
+ parallelId: z.string().optional(),
208
+ __parallel: z.array(z.any()).readonly(),
209
+ // __parallel: z.array(z.union([dynamicStep, dynamicStepsSeries])).nonempty(),
210
+ })
211
+ .readonly()
212
+ .transform(pickBy(isNonNullish))
213
+
214
+ export const dynamicViewStep = z.union([
215
+ dynamicStep,
216
+ dynamicStepsSeries,
217
+ dynamicStepsParallel,
218
+ ])
219
+
220
+ export const dynamicViewIncludeRule = z.strictObject({
221
+ include: z.array(schemas.expression),
222
+ })
223
+
224
+ export const dynamicViewRule = z.union([
225
+ dynamicViewIncludeRule,
226
+ viewRuleGlobalPredicate,
227
+ viewRuleStyle,
228
+ viewRuleGlobalStyle,
229
+ viewRuleAutoLayout,
230
+ ])
231
+
232
+ export const dynamicViewVariant = z.literal(['diagram', 'sequence'])
233
+
234
+ /**
235
+ * Replicates ParsedDynamicView from the core,
236
+ * less strict, as the generator should be able to handle missing fields and provide defaults.
237
+ */
238
+ export const dynamicView = viewProps
239
+ .extend({
240
+ _type: z.literal('dynamic'),
241
+ variant: dynamicViewVariant.optional(),
242
+ steps: z.array(dynamicViewStep).optional(),
243
+ rules: z.array(dynamicViewRule).optional(),
244
+ })
245
+ // .transform(v => ({
246
+ // ...pickBy(v, isNonNullish),
247
+ // title: v.title ?? null,
248
+ // description: v.description ?? null,
249
+ // steps: v.steps,
250
+ // rules: v.rules,
251
+ // }))
252
+
253
+ export const anyView = z.union([
254
+ elementView,
255
+ deploymentView,
256
+ dynamicView,
257
+ ])
258
+
259
+ export const views = z.record(common.viewId, anyView)
260
+
261
+ // export const views = z.union([
262
+ // viewsRecord,
263
+ // z.array(anyView)
264
+ // ]).transform(v => {
265
+ // if (Array.isArray(v)) {
266
+ // return indexBy(v, v => v.id) as z.output<typeof viewsRecord>
267
+ // }
268
+ // return v
269
+ // })
270
+
271
+ // export type ElementViewInput = z.input<typeof elementView>
272
+ // export type ElementViewData = z.infer<typeof elementView>
273
+
274
+ // // ============ Top-Level Schema ============
275
+
276
+ // export const LikeC4DataSchema = z
277
+ // .object({
278
+ // elements: z.union([
279
+ // z.record(fqn, ElementDataSchema),
280
+ // z.array(ElementDataSchema)
281
+ // .transform(indexBy(i => i.id)),
282
+ // ]),
283
+ // relations: z.union([
284
+ // z.record(id, RelationshipSchema),
285
+ // z.array(RelationshipSchema)
286
+ // .transform(
287
+ // indexBy((r, idx) =>
288
+ // r.id as string ?? stringHash(`${r.source.model}, ${r.target.model}, ${r.kind ?? ''}, ${idx}`)
289
+ // ),
290
+ // ),
291
+ // ]),
292
+ // views: z.union([
293
+ // z.record(viewId, elementView),
294
+ // z.array(elementView)
295
+ // .transform(indexBy(v => v.id as string)),
296
+ // ]),
297
+ // project: z.object({
298
+ // id: z.string(),
299
+ // styles: LikeC4StylesConfigSchema.nullish(),
300
+ // }),
301
+ // specification: SpecificationSchema,
302
+ // })
303
+ // .partial()
304
+ // .readonly()
305
+ // export type LikeC4DataInput = z.input<typeof LikeC4DataSchema>
306
+ // export type LikeC4Data = z.infer<typeof LikeC4DataSchema>
307
+
308
+ // interface BaseLikeC4ModelData<A extends Any> {
309
+ // [_stage]: A['Stage']
310
+ // projectId: aux.ProjectId<A>
311
+ // project: LikeC4Project
312
+ // specification: Specification<A>
313
+ // elements: Record<aux.ElementId<A>, Element<A>>
314
+ // deployments: {
315
+ // elements: Record<aux.DeploymentId<A>, DeploymentElement<A>>
316
+ // relations: Record<scalar.RelationId, DeploymentRelationship<A>>
317
+ // }
318
+ // relations: Record<scalar.RelationId, Relationship<A>>
319
+ // globals: ModelGlobals
320
+ // imports: Record<string, NonEmptyArray<Element<A>>>
321
+ // }
@@ -1,5 +0,0 @@
1
- import type { ParsedLikeC4ModelData } from '@likec4/core'
2
-
3
- export function generateLikeC4(_model: ParsedLikeC4ModelData) {
4
- // return `import { printDocs } from '../utils/printDocs'
5
- }