@likec4/config 1.41.0 → 1.42.1

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/schema.json CHANGED
@@ -30,6 +30,13 @@
30
30
  "pattern": "^(?!\\/|[A-Za-z]:[\\\\\\/])(?!.*:\\/\\/).*$"
31
31
  }
32
32
  },
33
+ "styles": {
34
+ "allOf": [
35
+ {
36
+ "$ref": "#/definitions/StylesConfiguration"
37
+ }
38
+ ]
39
+ },
33
40
  "exclude": {
34
41
  "description": "List of file patterns to exclude from the project, default is [\"**/node_modules/**\"]",
35
42
  "type": "array",
@@ -40,5 +47,529 @@
40
47
  },
41
48
  "required": [
42
49
  "name"
43
- ]
50
+ ],
51
+ "definitions": {
52
+ "StylesConfiguration": {
53
+ "id": "StylesConfiguration",
54
+ "description": "Project styles customization",
55
+ "type": "object",
56
+ "properties": {
57
+ "theme": {
58
+ "allOf": [
59
+ {
60
+ "$ref": "#/definitions/ThemeCustomization"
61
+ }
62
+ ]
63
+ },
64
+ "defaults": {
65
+ "allOf": [
66
+ {
67
+ "$ref": "#/definitions/DefaultStyleValues"
68
+ }
69
+ ]
70
+ }
71
+ }
72
+ },
73
+ "ThemeCustomization": {
74
+ "id": "ThemeCustomization",
75
+ "description": "Theme customization",
76
+ "type": "object",
77
+ "properties": {
78
+ "colors": {
79
+ "allOf": [
80
+ {
81
+ "$ref": "#/definitions/ThemeColors"
82
+ }
83
+ ]
84
+ },
85
+ "sizes": {
86
+ "description": "Map of theme sizes.",
87
+ "type": "object",
88
+ "properties": {
89
+ "xs": {
90
+ "allOf": [
91
+ {
92
+ "$ref": "#/definitions/Dimensions"
93
+ }
94
+ ]
95
+ },
96
+ "sm": {
97
+ "allOf": [
98
+ {
99
+ "$ref": "#/definitions/Dimensions"
100
+ }
101
+ ]
102
+ },
103
+ "md": {
104
+ "allOf": [
105
+ {
106
+ "$ref": "#/definitions/Dimensions"
107
+ }
108
+ ]
109
+ },
110
+ "lg": {
111
+ "allOf": [
112
+ {
113
+ "$ref": "#/definitions/Dimensions"
114
+ }
115
+ ]
116
+ },
117
+ "xl": {
118
+ "allOf": [
119
+ {
120
+ "$ref": "#/definitions/Dimensions"
121
+ }
122
+ ]
123
+ }
124
+ }
125
+ }
126
+ }
127
+ },
128
+ "ThemeColors": {
129
+ "id": "ThemeColors",
130
+ "description": "Override of theme colors",
131
+ "anyOf": [
132
+ {
133
+ "type": "object",
134
+ "propertyNames": {
135
+ "$ref": "#/definitions/ColorName"
136
+ },
137
+ "additionalProperties": {
138
+ "allOf": [
139
+ {
140
+ "$ref": "#/definitions/ThemeColorValues"
141
+ }
142
+ ]
143
+ }
144
+ },
145
+ {
146
+ "type": "object",
147
+ "properties": {
148
+ "amber": {
149
+ "allOf": [
150
+ {
151
+ "$ref": "#/definitions/ThemeColorValues"
152
+ }
153
+ ]
154
+ },
155
+ "blue": {
156
+ "allOf": [
157
+ {
158
+ "$ref": "#/definitions/ThemeColorValues"
159
+ }
160
+ ]
161
+ },
162
+ "gray": {
163
+ "allOf": [
164
+ {
165
+ "$ref": "#/definitions/ThemeColorValues"
166
+ }
167
+ ]
168
+ },
169
+ "slate": {
170
+ "allOf": [
171
+ {
172
+ "$ref": "#/definitions/ThemeColorValues"
173
+ }
174
+ ]
175
+ },
176
+ "green": {
177
+ "allOf": [
178
+ {
179
+ "$ref": "#/definitions/ThemeColorValues"
180
+ }
181
+ ]
182
+ },
183
+ "indigo": {
184
+ "allOf": [
185
+ {
186
+ "$ref": "#/definitions/ThemeColorValues"
187
+ }
188
+ ]
189
+ },
190
+ "muted": {
191
+ "allOf": [
192
+ {
193
+ "$ref": "#/definitions/ThemeColorValues"
194
+ }
195
+ ]
196
+ },
197
+ "primary": {
198
+ "allOf": [
199
+ {
200
+ "$ref": "#/definitions/ThemeColorValues"
201
+ }
202
+ ]
203
+ },
204
+ "red": {
205
+ "allOf": [
206
+ {
207
+ "$ref": "#/definitions/ThemeColorValues"
208
+ }
209
+ ]
210
+ },
211
+ "secondary": {
212
+ "allOf": [
213
+ {
214
+ "$ref": "#/definitions/ThemeColorValues"
215
+ }
216
+ ]
217
+ },
218
+ "sky": {
219
+ "allOf": [
220
+ {
221
+ "$ref": "#/definitions/ThemeColorValues"
222
+ }
223
+ ]
224
+ }
225
+ }
226
+ }
227
+ ]
228
+ },
229
+ "ColorName": {
230
+ "id": "ColorName",
231
+ "description": "Color name (Theme color name or custom color name)",
232
+ "anyOf": [
233
+ {
234
+ "$ref": "#/definitions/ThemeColor"
235
+ },
236
+ {
237
+ "type": "string",
238
+ "minLength": 1
239
+ }
240
+ ]
241
+ },
242
+ "ThemeColor": {
243
+ "id": "ThemeColor",
244
+ "description": "Reserved theme color name",
245
+ "type": "string",
246
+ "enum": [
247
+ "amber",
248
+ "blue",
249
+ "gray",
250
+ "slate",
251
+ "green",
252
+ "indigo",
253
+ "muted",
254
+ "primary",
255
+ "red",
256
+ "secondary",
257
+ "sky"
258
+ ]
259
+ },
260
+ "ThemeColorValues": {
261
+ "id": "ThemeColorValues",
262
+ "description": "Exact value (hex, rgb, rgba, hsl, hsla ...) or break down of specific color values",
263
+ "anyOf": [
264
+ {
265
+ "$ref": "#/definitions/ColorLiteral"
266
+ },
267
+ {
268
+ "type": "object",
269
+ "properties": {
270
+ "elements": {
271
+ "anyOf": [
272
+ {
273
+ "$ref": "#/definitions/ColorLiteral"
274
+ },
275
+ {
276
+ "allOf": [
277
+ {
278
+ "$ref": "#/definitions/ElementColorValues"
279
+ }
280
+ ]
281
+ }
282
+ ]
283
+ },
284
+ "relationships": {
285
+ "anyOf": [
286
+ {
287
+ "$ref": "#/definitions/ColorLiteral"
288
+ },
289
+ {
290
+ "allOf": [
291
+ {
292
+ "$ref": "#/definitions/RelationshipColorValues"
293
+ }
294
+ ]
295
+ }
296
+ ]
297
+ }
298
+ },
299
+ "required": [
300
+ "elements",
301
+ "relationships"
302
+ ]
303
+ }
304
+ ]
305
+ },
306
+ "ColorLiteral": {
307
+ "id": "ColorLiteral",
308
+ "description": "Color value in any valid CSS format: hex, rgb, rgba, hsl, hsla ...",
309
+ "type": "string",
310
+ "minLength": 1
311
+ },
312
+ "ElementColorValues": {
313
+ "id": "ElementColorValues",
314
+ "description": "Specific element colors",
315
+ "type": "object",
316
+ "properties": {
317
+ "fill": {
318
+ "description": "Background color",
319
+ "allOf": [
320
+ {
321
+ "$ref": "#/definitions/ColorLiteral"
322
+ }
323
+ ]
324
+ },
325
+ "stroke": {
326
+ "description": "Stroke color (border, paths above background)",
327
+ "allOf": [
328
+ {
329
+ "$ref": "#/definitions/ColorLiteral"
330
+ }
331
+ ]
332
+ },
333
+ "hiContrast": {
334
+ "description": "High contrast text color (title)",
335
+ "allOf": [
336
+ {
337
+ "$ref": "#/definitions/ColorLiteral"
338
+ }
339
+ ]
340
+ },
341
+ "loContrast": {
342
+ "description": "Low contrast text color (description)",
343
+ "allOf": [
344
+ {
345
+ "$ref": "#/definitions/ColorLiteral"
346
+ }
347
+ ]
348
+ }
349
+ },
350
+ "required": [
351
+ "fill",
352
+ "stroke",
353
+ "hiContrast",
354
+ "loContrast"
355
+ ]
356
+ },
357
+ "RelationshipColorValues": {
358
+ "id": "RelationshipColorValues",
359
+ "description": "Specefic relationship colors",
360
+ "type": "object",
361
+ "properties": {
362
+ "line": {
363
+ "description": "Line color",
364
+ "allOf": [
365
+ {
366
+ "$ref": "#/definitions/ColorLiteral"
367
+ }
368
+ ]
369
+ },
370
+ "label": {
371
+ "description": "Label text color",
372
+ "allOf": [
373
+ {
374
+ "$ref": "#/definitions/ColorLiteral"
375
+ }
376
+ ]
377
+ },
378
+ "labelBg": {
379
+ "description": "Label background color",
380
+ "allOf": [
381
+ {
382
+ "$ref": "#/definitions/ColorLiteral"
383
+ }
384
+ ]
385
+ }
386
+ },
387
+ "required": [
388
+ "line",
389
+ "label"
390
+ ]
391
+ },
392
+ "Dimensions": {
393
+ "id": "Dimensions",
394
+ "description": "Dimensions",
395
+ "type": "object",
396
+ "properties": {
397
+ "width": {
398
+ "type": "number"
399
+ },
400
+ "height": {
401
+ "type": "number"
402
+ }
403
+ },
404
+ "required": [
405
+ "width",
406
+ "height"
407
+ ]
408
+ },
409
+ "DefaultStyleValues": {
410
+ "id": "DefaultStyleValues",
411
+ "description": "Override default values for style properties\nThese values will be used if such property is not defined",
412
+ "type": "object",
413
+ "properties": {
414
+ "color": {
415
+ "allOf": [
416
+ {
417
+ "$ref": "#/definitions/ColorName"
418
+ }
419
+ ]
420
+ },
421
+ "opacity": {
422
+ "allOf": [
423
+ {
424
+ "$ref": "#/definitions/Opacity"
425
+ }
426
+ ]
427
+ },
428
+ "border": {
429
+ "allOf": [
430
+ {
431
+ "$ref": "#/definitions/BorderStyle"
432
+ }
433
+ ]
434
+ },
435
+ "size": {
436
+ "allOf": [
437
+ {
438
+ "$ref": "#/definitions/ElementSize"
439
+ }
440
+ ]
441
+ },
442
+ "shape": {
443
+ "allOf": [
444
+ {
445
+ "$ref": "#/definitions/ElementShape"
446
+ }
447
+ ]
448
+ },
449
+ "group": {
450
+ "type": "object",
451
+ "properties": {
452
+ "color": {
453
+ "allOf": [
454
+ {
455
+ "$ref": "#/definitions/ColorName"
456
+ }
457
+ ]
458
+ },
459
+ "opacity": {
460
+ "allOf": [
461
+ {
462
+ "$ref": "#/definitions/Opacity"
463
+ }
464
+ ]
465
+ },
466
+ "border": {
467
+ "allOf": [
468
+ {
469
+ "$ref": "#/definitions/BorderStyle"
470
+ }
471
+ ]
472
+ }
473
+ }
474
+ },
475
+ "relationship": {
476
+ "type": "object",
477
+ "properties": {
478
+ "color": {
479
+ "allOf": [
480
+ {
481
+ "$ref": "#/definitions/ColorName"
482
+ }
483
+ ]
484
+ },
485
+ "line": {
486
+ "allOf": [
487
+ {
488
+ "$ref": "#/definitions/LineType"
489
+ }
490
+ ]
491
+ },
492
+ "arrow": {
493
+ "allOf": [
494
+ {
495
+ "$ref": "#/definitions/ArrowType"
496
+ }
497
+ ]
498
+ }
499
+ }
500
+ }
501
+ }
502
+ },
503
+ "Opacity": {
504
+ "id": "Opacity",
505
+ "description": "Opacity 0%-100%",
506
+ "type": "number",
507
+ "minimum": 0,
508
+ "maximum": 100
509
+ },
510
+ "BorderStyle": {
511
+ "id": "BorderStyle",
512
+ "description": "Border style",
513
+ "type": "string",
514
+ "enum": [
515
+ "solid",
516
+ "dashed",
517
+ "dotted",
518
+ "none"
519
+ ]
520
+ },
521
+ "ElementSize": {
522
+ "id": "ElementSize",
523
+ "description": "Element size",
524
+ "type": "string",
525
+ "enum": [
526
+ "xs",
527
+ "sm",
528
+ "md",
529
+ "lg",
530
+ "xl"
531
+ ]
532
+ },
533
+ "ElementShape": {
534
+ "id": "ElementShape",
535
+ "description": "Element shape",
536
+ "type": "string",
537
+ "enum": [
538
+ "rectangle",
539
+ "person",
540
+ "browser",
541
+ "mobile",
542
+ "cylinder",
543
+ "storage",
544
+ "queue"
545
+ ]
546
+ },
547
+ "LineType": {
548
+ "id": "LineType",
549
+ "description": "Default line type for relationships",
550
+ "type": "string",
551
+ "enum": [
552
+ "dashed",
553
+ "solid",
554
+ "dotted"
555
+ ]
556
+ },
557
+ "ArrowType": {
558
+ "id": "ArrowType",
559
+ "description": "Relationship arrow type",
560
+ "type": "string",
561
+ "enum": [
562
+ "none",
563
+ "normal",
564
+ "onormal",
565
+ "dot",
566
+ "odot",
567
+ "diamond",
568
+ "odiamond",
569
+ "crow",
570
+ "open",
571
+ "vee"
572
+ ]
573
+ }
574
+ }
44
575
  }
@@ -1,4 +1,14 @@
1
- import { type GeneratorFn, type LikeC4ProjectConfig, GeneratorsSchema, LikeC4ProjectConfigSchema } from './schema'
1
+ import type { LikeC4ProjectStylesConfig, LikeC4ProjectTheme, ThemeColorValues } from '@likec4/core/types'
2
+ import type { GeneratorFn, LikeC4ProjectConfig, LikeC4ProjectConfigInput } from './schema'
3
+ import { GeneratorsSchema, LikeC4ProjectConfigSchema } from './schema'
4
+ import {
5
+ type LikeC4ConfigThemeInput,
6
+ type LikeC4StylesConfigInput,
7
+ type ThemeColorValuesInput,
8
+ LikeC4Config_Styles_Theme,
9
+ LikeC4StylesConfigSchema,
10
+ ThemeColorValuesSchema,
11
+ } from './schema.theme'
2
12
 
3
13
  /**
4
14
  * Defines LikeC4 Project, allows custom generators that can be executed using CLI:
@@ -21,8 +31,8 @@ import { type GeneratorFn, type LikeC4ProjectConfig, GeneratorsSchema, LikeC4Pro
21
31
  * })
22
32
  * ```
23
33
  */
24
- export function defineConfig<const C extends LikeC4ProjectConfig>(config: C): C {
25
- return LikeC4ProjectConfigSchema.parse(config) as unknown as C
34
+ export function defineConfig<C extends LikeC4ProjectConfigInput>(config: C): LikeC4ProjectConfig {
35
+ return LikeC4ProjectConfigSchema.parse(config) as unknown as LikeC4ProjectConfig
26
36
  }
27
37
 
28
38
  /**
@@ -49,3 +59,73 @@ export function defineConfig<const C extends LikeC4ProjectConfig>(config: C): C
49
59
  export function defineGenerators<const G extends Record<string, GeneratorFn>>(generators: G): G {
50
60
  return GeneratorsSchema.parse(generators) as unknown as G
51
61
  }
62
+
63
+ /**
64
+ * Define reusable custom theme color
65
+ * @example
66
+ * ```ts
67
+ * export default defineThemeColor({
68
+ * element: {
69
+ * fill: 'red'
70
+ * }
71
+ * })
72
+ * ```
73
+ */
74
+ export function defineThemeColor<const S extends ThemeColorValuesInput>(colors: S): ThemeColorValues {
75
+ return ThemeColorValuesSchema.parse(colors)
76
+ }
77
+
78
+ /**
79
+ * Define reusable custom theme
80
+ * @example
81
+ * ```ts
82
+ * import { defineThemeColor, defineTheme } from 'likec4/config'
83
+ *
84
+ * export default defineTheme({
85
+ * colors: {
86
+ * primary: '#FF0000',
87
+ * // Or use defineThemeColor
88
+ * red: defineThemeColor({
89
+ * elements: {
90
+ * fill: 'red'
91
+ * }
92
+ * })
93
+ * }
94
+ * })
95
+ * ```
96
+ */
97
+ export function defineTheme<const S extends LikeC4ConfigThemeInput>(theme: S): LikeC4ProjectTheme {
98
+ return LikeC4Config_Styles_Theme.parse(theme)
99
+ }
100
+
101
+ /**
102
+ * Define reusable custom style
103
+ * @example
104
+ * ```ts
105
+ * import { defineStyle, defineThemeColor } from 'likec4/config'
106
+ *
107
+ * export default defineStyle({
108
+ * theme: {
109
+ * colors: {
110
+ * red: defineThemeColor({
111
+ * elements: {
112
+ * fill: 'red'
113
+ * }
114
+ * })
115
+ * }
116
+ * },
117
+ * defaults: {
118
+ * color: 'red',
119
+ * opacity: 50,
120
+ * border: 'solid',
121
+ * size: 'sm',
122
+ * relationship: {
123
+ * color: 'grey',
124
+ * line: 'solid',
125
+ * }
126
+ * }
127
+ * })
128
+ */
129
+ export function defineStyle<const S extends LikeC4StylesConfigInput>(styles: S): LikeC4ProjectStylesConfig {
130
+ return LikeC4StylesConfigSchema.parse(styles)
131
+ }
package/src/index.ts CHANGED
@@ -3,9 +3,15 @@ export type {
3
3
  GeneratorFnContext,
4
4
  GeneratorFnParams,
5
5
  LikeC4ProjectConfig,
6
+ LikeC4ProjectConfigInput,
6
7
  LikeC4ProjectJsonConfig,
7
8
  } from './schema'
8
9
 
10
+ export type {
11
+ LikeC4StylesConfig,
12
+ LikeC4StylesConfigInput,
13
+ } from './schema.theme'
14
+
9
15
  export { serializableLikeC4ProjectConfig, validateProjectConfig } from './schema'
10
16
 
11
17
  export {
@@ -18,4 +24,7 @@ export {
18
24
  export {
19
25
  defineConfig,
20
26
  defineGenerators,
27
+ defineStyle,
28
+ defineTheme,
29
+ defineThemeColor,
21
30
  } from './define-config'
@@ -45,13 +45,17 @@ export async function loadConfig(filepath: URI): Promise<LikeC4ProjectConfig> {
45
45
  /**
46
46
  * Mock implementation, this allows to skip redundant bundling @likec4/config
47
47
  */
48
- build.onLoad({ filter: /.*/, namespace: 'likec4-config' }, (args) => {
48
+ build.onLoad({ filter: /.*/, namespace: 'likec4-config' }, (_args) => {
49
49
  return {
50
50
  contents: `
51
- function mockDefineConfig(x) { return x }
51
+ // Mock implementation to allow loading config files without bundling @likec4/config
52
+ function mock(x) { return x }
52
53
  export {
53
- mockDefineConfig as defineConfig,
54
- mockDefineConfig as defineGenerators,
54
+ mock as defineConfig,
55
+ mock as defineGenerators,
56
+ mock as defineStyle,
57
+ mock as defineTheme,
58
+ mock as defineThemeColor,
55
59
  }`,
56
60
  loader: 'js',
57
61
  }
@@ -1,4 +1,4 @@
1
- import * as z from 'zod4'
1
+ import * as z from 'zod/v4'
2
2
 
3
3
  // Key must be prefixed with "@" and contain only allowed characters
4
4
  const IMAGE_ALIAS_KEY_REGEX = /^@[A-Za-z0-9_-]*$/