@likec4/config 1.48.0 → 1.49.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/src/schema.ts CHANGED
@@ -11,10 +11,9 @@ import type {
11
11
  ProjectId,
12
12
  } from '@likec4/core/types'
13
13
  import JSON5 from 'json5'
14
- import type { SimplifyDeep } from 'type-fest'
15
14
  import z from 'zod/v4'
16
- import { ImageAliasesSchema, validateImageAliases } from './schema.image-alias'
17
- import { IncludeSchema, validateIncludePaths } from './schema.include'
15
+ import { ImageAliasesSchema } from './schema.image-alias'
16
+ import { type IncludeConfig, IncludeSchema } from './schema.include'
18
17
  import { LikeC4StylesConfigSchema } from './schema.theme'
19
18
 
20
19
  export interface VscodeURI {
@@ -41,7 +40,7 @@ export const ManualLayoutsConfigSchema = z
41
40
  }),
42
41
  })
43
42
  .meta({
44
- id: 'manual-layouts-config',
43
+ id: 'ManualLayoutsConfig',
45
44
  description: 'Configuration for manual layouts',
46
45
  })
47
46
 
@@ -59,6 +58,12 @@ export const LikeC4ProjectJsonConfigSchema = z.object({
59
58
  error: 'Project name cannot contain ".", "@" or "#", try to use A-z, 0-9, _ and -',
60
59
  })
61
60
  .meta({ description: 'Project name, must be unique in the workspace' }),
61
+ extends: z.union([
62
+ z.string().min(1, 'Extend path cannot be empty'),
63
+ z.array(z.string().min(1, 'Extend path cannot be empty')).min(1, 'Extend list cannot be empty'),
64
+ ])
65
+ .optional()
66
+ .meta({ description: 'Extend styles from other config files' }),
62
67
  title: z.string()
63
68
  .nonempty('Project title cannot be empty if specified')
64
69
  .optional()
@@ -67,22 +72,22 @@ export const LikeC4ProjectJsonConfigSchema = z.object({
67
72
  .nonempty('Contact person cannot be empty if specified')
68
73
  .optional()
69
74
  .meta({ description: 'A person who has been involved in creating or maintaining this project' }),
70
- imageAliases: ImageAliasesSchema
71
- .optional(),
72
- include: IncludeSchema,
73
- styles: LikeC4StylesConfigSchema
74
- .optional(),
75
+ styles: LikeC4StylesConfigSchema.optional().meta({
76
+ description: 'Project styles customization',
77
+ }),
78
+ imageAliases: ImageAliasesSchema.optional(),
79
+ include: IncludeSchema.optional(),
75
80
  exclude: z.array(z.string())
76
81
  .optional()
77
82
  .meta({ description: 'List of file patterns to exclude from the project, default is ["**/node_modules/**"]' }),
78
- manualLayouts: ManualLayoutsConfigSchema
79
- .optional(),
83
+ manualLayouts: ManualLayoutsConfigSchema.optional(),
80
84
  })
81
85
  .meta({
82
- description: 'LikeC4 project configuration',
86
+ id: 'LikeC4ProjectConfig',
87
+ description: 'LikeC4 Project Configuration',
83
88
  })
84
89
 
85
- export type LikeC4ProjectJsonConfig = SimplifyDeep<z.input<typeof LikeC4ProjectJsonConfigSchema>>
90
+ export type LikeC4ProjectJsonConfig = z.input<typeof LikeC4ProjectJsonConfigSchema>
86
91
 
87
92
  const FunctionType = z.instanceof(Function)
88
93
  export const GeneratorsSchema = z.record(z.string(), FunctionType)
@@ -236,30 +241,42 @@ export type LikeC4ProjectConfig = z.infer<typeof LikeC4ProjectJsonConfigSchema>
236
241
  generators?: Record<string, GeneratorFn> | undefined
237
242
  }
238
243
 
239
- export type LikeC4ProjectConfigInput = SimplifyDeep<
240
- z.input<typeof LikeC4ProjectJsonConfigSchema> & {
241
- generators?: Record<string, GeneratorFn> | undefined
242
- }
243
- >
244
+ export type LikeC4ProjectConfigInput = LikeC4ProjectJsonConfig & {
245
+ generators?: Record<string, GeneratorFn> | undefined
246
+ }
244
247
 
245
248
  /**
246
- * Validates JSON string or JSON object into a LikeC4ProjectConfig object.
249
+ * Validates Object into a LikeC4ProjectConfig object.
247
250
  */
248
- export function validateProjectConfig<C extends string | Record<string, unknown>>(
249
- config: C,
250
- ): LikeC4ProjectConfig {
251
- const parsed = LikeC4ProjectConfigSchema.safeParse(
252
- typeof config === 'string' ? JSON5.parse(config) : config,
253
- )
254
- if (!parsed.success) {
255
- throw new Error('Config validation failed:\n' + z.prettifyError(parsed.error))
251
+ export function validateProjectConfig<C extends Record<string, unknown>>(config: C): LikeC4ProjectConfig {
252
+ const parsed = LikeC4ProjectConfigSchema.safeParse(config)
253
+ if (parsed.success) {
254
+ return parsed.data as unknown as LikeC4ProjectConfig
256
255
  }
257
- // TODO: rewrite with zod refine
258
- if (parsed.data.imageAliases) {
259
- validateImageAliases(parsed.data.imageAliases)
260
- }
261
- if (parsed.data.include) {
262
- validateIncludePaths(parsed.data.include)
263
- }
264
- return parsed.data as unknown as LikeC4ProjectConfig
256
+ throw new Error('Config validation failed:\n' + z.prettifyError(parsed.error))
257
+ }
258
+
259
+ /**
260
+ * Parses JSON string into a LikeC4ProjectConfig object.
261
+ * Does not process "extends" - use `loadConfig` function instead
262
+ */
263
+ export function parseProjectConfigJSON(config: string): LikeC4ProjectConfig {
264
+ const parsed = JSON5.parse(config.trim() || '{}')
265
+ return validateProjectConfig(parsed)
266
+ }
267
+
268
+ export const LikeC4ProjectConfigOps = {
269
+ parse: parseProjectConfigJSON,
270
+ validate: validateProjectConfig,
271
+ normalizeInclude: (include: z.input<typeof IncludeSchema> | undefined): IncludeConfig => {
272
+ const parsed = IncludeSchema.safeParse(include)
273
+ if (parsed.success) {
274
+ return parsed.data
275
+ }
276
+ return {
277
+ paths: [],
278
+ maxDepth: 3,
279
+ fileThreshold: 30,
280
+ }
281
+ },
265
282
  }