@likec4/config 1.42.1 → 1.44.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.
@@ -18,57 +18,48 @@ import {
18
18
  exact,
19
19
  } from '@likec4/core/types'
20
20
  import { fromKeys } from 'remeda'
21
- import z from 'zod/v4'
21
+ import * as z from 'zod'
22
22
 
23
23
  const opacity = z
24
- .number()
24
+ .int()
25
25
  .min(0, 'Opacity must be between 0 and 100')
26
26
  .max(100, 'Opacity must be between 0 and 100')
27
27
  .meta({
28
28
  id: 'Opacity',
29
- description: 'Opacity 0%-100%',
29
+ description: 'Opacity 0-100%',
30
30
  })
31
31
 
32
- const shape = z.literal(ElementShapes).meta({
33
- id: 'ElementShape',
34
- description: 'Element shape',
35
- })
32
+ const shape = z
33
+ .literal(ElementShapes)
34
+ .meta({ id: 'ElementShape' })
36
35
 
37
- const border = z.literal(BorderStyles).meta({
38
- id: 'BorderStyle',
39
- description: 'Border style',
40
- })
36
+ const border = z
37
+ .literal(BorderStyles)
38
+ .meta({ id: 'BorderStyle' })
41
39
 
42
- const size = z.literal(Sizes).meta({
43
- id: 'ElementSize',
44
- description: 'Element size',
45
- })
40
+ const size = z
41
+ .literal(Sizes)
42
+ .meta({ id: 'ElementSize' })
43
+
44
+ const arrow = z
45
+ .literal(RelationshipArrowTypes)
46
+ .meta({ id: 'ArrowType' })
46
47
 
47
- const arrow = z.literal(RelationshipArrowTypes).meta({
48
- id: 'ArrowType',
49
- description: 'Relationship arrow type',
50
- })
51
48
  const line = z
52
49
  .literal(['dashed', 'solid', 'dotted'])
53
- .meta({
54
- id: 'LineType',
55
- description: 'Default line type for relationships',
56
- })
50
+ .meta({ id: 'LineType' })
57
51
 
58
- const themeColor = z.literal(ThemeColors).meta({
59
- id: 'ThemeColor',
60
- description: 'Reserved theme color name',
61
- })
52
+ const themeColor = z
53
+ .literal(ThemeColors)
54
+ .meta({ id: 'ThemeColor' })
62
55
 
63
- const color = z.union([
64
- themeColor,
65
- z.string().nonempty('Color name cannot be empty'),
66
- ])
56
+ const color = z
57
+ .union([
58
+ themeColor,
59
+ z.string().nonempty('Color name cannot be empty'),
60
+ ])
67
61
  .transform(value => value as ThemeColor)
68
- .meta({
69
- id: 'ColorName',
70
- description: 'Color name (Theme color name or custom color name)',
71
- })
62
+ .meta({ id: 'ColorName' })
72
63
 
73
64
  const colorValue = z
74
65
  .string()
@@ -84,20 +75,17 @@ const colorSchema = colorValue
84
75
  // type ColorValue = z.infer<typeof colorSchema>
85
76
 
86
77
  const ElementColorValuesSchema = z
87
- .object({
78
+ .strictObject({
88
79
  fill: colorSchema.meta({ description: 'Background color' }),
89
80
  stroke: colorSchema.meta({ description: 'Stroke color (border, paths above background)' }),
90
81
  hiContrast: colorSchema.meta({ description: 'High contrast text color (title)' }),
91
82
  loContrast: colorSchema.meta({ description: 'Low contrast text color (description)' }),
92
83
  })
93
- .meta({
94
- id: 'ElementColorValues',
95
- description: 'Specific element colors',
96
- })
84
+ .meta({ id: 'ElementColorValues' })
97
85
  .transform(value => value as ElementColorValues)
98
86
 
99
87
  const RelationshipColorValuesSchema = z
100
- .object({
88
+ .strictObject({
101
89
  line: colorSchema.meta({ description: 'Line color' }),
102
90
  label: colorSchema.meta({ description: 'Label text color' }),
103
91
  labelBg: colorSchema
@@ -105,18 +93,16 @@ const RelationshipColorValuesSchema = z
105
93
  .default('rgba(0, 0, 0, 0)')
106
94
  .meta({ description: 'Label background color' }),
107
95
  })
108
- .meta({
109
- id: 'RelationshipColorValues',
110
- description: 'Specefic relationship colors',
111
- })
96
+ .meta({ id: 'RelationshipColorValues' })
112
97
  .transform(value => value as RelationshipColorValues)
113
98
 
114
99
  export const ThemeColorValuesSchema = z
115
100
  .union([
116
101
  colorSchema,
117
- z.object({
102
+ z.strictObject({
118
103
  elements: z
119
104
  .union([colorSchema, ElementColorValuesSchema])
105
+ .meta({ description: 'Element color value (or a breakdown of specific color values)' })
120
106
  .transform((value): ElementColorValues => {
121
107
  if (typeof value === 'string') {
122
108
  return computeColorValues(value).elements
@@ -125,6 +111,7 @@ export const ThemeColorValuesSchema = z
125
111
  }),
126
112
  relationships: z
127
113
  .union([colorSchema, RelationshipColorValuesSchema])
114
+ .meta({ description: 'Relationship color value (or a breakdown of specific color values)' })
128
115
  .transform((value): RelationshipColorValues => {
129
116
  if (typeof value === 'string') {
130
117
  return computeColorValues(value).relationships
@@ -155,25 +142,31 @@ const ThemeColorsSchema = z.union([
155
142
  ),
156
143
  ]).meta({
157
144
  id: 'ThemeColors',
158
- description: 'Override of theme colors',
145
+ description: 'Override theme colors',
159
146
  })
160
147
 
161
- const DimensionsSchema = z.object({
162
- width: z.number(),
163
- height: z.number(),
148
+ const DimensionsSchema = z.strictObject({
149
+ width: z.number().min(50),
150
+ height: z.number().min(50),
164
151
  }).meta({
165
152
  id: 'Dimensions',
166
153
  description: 'Dimensions',
167
154
  })
168
155
 
156
+ const LikeC4Config_Styles_Theme_Sizes = z
157
+ .strictObject(
158
+ fromKeys(Sizes, () => DimensionsSchema.optional()),
159
+ )
160
+ .meta({
161
+ id: 'ThemeSizes',
162
+ description: 'Override theme sizes',
163
+ })
164
+
169
165
  export const LikeC4Config_Styles_Theme = z
170
- .object({
171
- colors: ThemeColorsSchema,
172
- sizes: z
173
- .object(fromKeys(Sizes, () => DimensionsSchema.optional()))
174
- .meta({ description: 'Map of theme sizes.' }),
166
+ .strictObject({
167
+ colors: ThemeColorsSchema.optional(),
168
+ sizes: LikeC4Config_Styles_Theme_Sizes.optional(),
175
169
  })
176
- .partial()
177
170
  .meta({
178
171
  id: 'ThemeCustomization',
179
172
  description: 'Theme customization',
@@ -186,25 +179,52 @@ export const LikeC4Config_Styles_Theme = z
186
179
  })
187
180
  export type LikeC4ConfigThemeInput = z.input<typeof LikeC4Config_Styles_Theme>
188
181
 
182
+ const LikeC4Config_Styles_Defaults_Group = z
183
+ .strictObject({
184
+ color: color.optional().meta({
185
+ description: 'Default color for groups\n(must be a valid color name from the theme)',
186
+ }),
187
+ opacity: opacity.optional().meta({ description: 'Default opacity for groups' }),
188
+ border: border.optional().meta({ description: 'Default border for groups' }),
189
+ })
190
+ .meta({
191
+ id: 'GroupDefaultStyleValues',
192
+ description:
193
+ 'Override default values for group style properties\nThese values will be used if such property is not defined',
194
+ })
195
+
196
+ const LikeC4Config_Styles_Defaults_Relationship = z
197
+ .strictObject({
198
+ color: color.optional().meta({
199
+ description: 'Default color for relationships\n(must be a valid color name from the theme)',
200
+ }),
201
+ line: line.optional().meta({ description: 'Default line style for relationships' }),
202
+ arrow: arrow.optional().meta({ description: 'Default arrow style for relationships' }),
203
+ })
204
+ .meta({
205
+ id: 'RelationshipDefaultStyleValues',
206
+ description:
207
+ 'Override default values for relationship style properties\nThese values will be used if such property is not defined',
208
+ })
209
+
189
210
  const LikeC4Config_Styles_Defaults = z
190
- .object({
191
- color,
192
- opacity,
193
- border,
194
- size,
195
- shape,
196
- group: z.object({
197
- color,
198
- opacity,
199
- border,
200
- }).partial(),
201
- relationship: z.object({
202
- color,
203
- line,
204
- arrow,
205
- }).partial(),
206
- })
207
- .partial()
211
+ .strictObject({
212
+ color: color.optional().meta({
213
+ description: 'Default color for elements\n(must be a valid color name from the theme)',
214
+ }),
215
+ opacity: opacity.optional().meta({
216
+ description: 'Default opacity (0-100%) for elements when displayed as a group (like a container)',
217
+ }),
218
+ border: border.optional().meta({
219
+ description: 'Default border style for elements when displayed as a group (like a container)',
220
+ }),
221
+ size: size.optional().meta({ description: 'Default size for elements' }),
222
+ shape: shape.optional().meta({ description: 'Default shape for elements' }),
223
+ group: LikeC4Config_Styles_Defaults_Group.optional().meta({ description: 'Default style values for groups' }),
224
+ relationship: LikeC4Config_Styles_Defaults_Relationship.optional().meta({
225
+ description: 'Default style values for relationships',
226
+ }),
227
+ })
208
228
  .meta({
209
229
  id: 'DefaultStyleValues',
210
230
  description:
@@ -212,14 +232,13 @@ const LikeC4Config_Styles_Defaults = z
212
232
  })
213
233
 
214
234
  export const LikeC4StylesConfigSchema = z
215
- .object({
216
- theme: LikeC4Config_Styles_Theme,
217
- defaults: LikeC4Config_Styles_Defaults,
235
+ .strictObject({
236
+ theme: LikeC4Config_Styles_Theme.optional(),
237
+ defaults: LikeC4Config_Styles_Defaults.optional(),
218
238
  // customCss: z
219
239
  // .array(z.string())
220
240
  // .meta({ description: 'List of custom CSS files' }),
221
241
  })
222
- .partial()
223
242
  .meta({
224
243
  id: 'StylesConfiguration',
225
244
  description: 'Project styles customization',
package/src/schema.ts CHANGED
@@ -13,10 +13,25 @@ import type {
13
13
  import JSON5 from 'json5'
14
14
  import type { SimplifyDeep } from 'type-fest'
15
15
  import type { URI } from 'vscode-uri'
16
- import * as z from 'zod/v4'
16
+ import * as z from 'zod'
17
17
  import { ImageAliasesSchema, validateImageAliases } from './schema.image-alias'
18
18
  import { LikeC4StylesConfigSchema } from './schema.theme'
19
19
 
20
+ export const ManualLayoutsConfigSchema = z
21
+ .object({
22
+ outDir: z.string()
23
+ .meta({
24
+ description:
25
+ 'Path to the directory where manual layouts will be stored, relative to the folder containing the project config',
26
+ }),
27
+ })
28
+ .meta({
29
+ id: 'manual-layouts-config',
30
+ description: 'Configuration for manual layouts',
31
+ })
32
+
33
+ export type ManualLayoutsConfig = z.infer<typeof ManualLayoutsConfigSchema>
34
+
20
35
  export const LikeC4ProjectJsonConfigSchema = z.object({
21
36
  name: z.string()
22
37
  .nonempty('Project name cannot be empty')
@@ -44,6 +59,8 @@ export const LikeC4ProjectJsonConfigSchema = z.object({
44
59
  exclude: z.array(z.string())
45
60
  .optional()
46
61
  .meta({ description: 'List of file patterns to exclude from the project, default is ["**/node_modules/**"]' }),
62
+ manualLayouts: ManualLayoutsConfigSchema
63
+ .optional(),
47
64
  })
48
65
  .meta({
49
66
  description: 'LikeC4 project configuration',
@@ -57,6 +74,41 @@ export const LikeC4ProjectConfigSchema = LikeC4ProjectJsonConfigSchema.extend({
57
74
  generators: GeneratorsSchema.optional(),
58
75
  })
59
76
 
77
+ /**
78
+ * Result of the {@link GeneratorFnContext.locate} function
79
+ */
80
+ export type LocateResult = {
81
+ /**
82
+ * Range inside the source file
83
+ */
84
+ range: {
85
+ start: {
86
+ line: number
87
+ character: number
88
+ }
89
+ end: {
90
+ line: number
91
+ character: number
92
+ }
93
+ }
94
+ /**
95
+ * Full path to the source file
96
+ */
97
+ document: URI
98
+ /**
99
+ * Document path relative to the project folder
100
+ */
101
+ relativePath: string
102
+ /**
103
+ * Folder, containing the source file ("dirname" of document)
104
+ */
105
+ folder: string
106
+ /**
107
+ * Source file name ("basename" of document)
108
+ */
109
+ filename: string
110
+ }
111
+
60
112
  export interface GeneratorFnContext {
61
113
  /**
62
114
  * Workspace root directory
@@ -90,37 +142,7 @@ export interface GeneratorFnContext {
90
142
  | DeploymentRelationModel
91
143
  | LikeC4ViewModel
92
144
  | DeploymentElementModel,
93
- ): {
94
- /**
95
- * Range inside the source file
96
- */
97
- range: {
98
- start: {
99
- line: number
100
- character: number
101
- }
102
- end: {
103
- line: number
104
- character: number
105
- }
106
- }
107
- /**
108
- * Full path to the source file
109
- */
110
- document: URI
111
- /**
112
- * Document path relative to the project folder
113
- */
114
- relativePath: string
115
- /**
116
- * Folder, containing the source file ("dirname" of document)
117
- */
118
- folder: string
119
- /**
120
- * Source file name ("basename" of document)
121
- */
122
- filename: string
123
- }
145
+ ): LocateResult
124
146
 
125
147
  /**
126
148
  * Write a file