@likec4/config 1.45.0 → 1.46.2

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/dist/index.d.mts CHANGED
@@ -14,6 +14,11 @@ declare const LikeC4ProjectJsonConfigSchema: z.ZodObject<{
14
14
  title: z.ZodOptional<z.ZodString>;
15
15
  contactPerson: z.ZodOptional<z.ZodString>;
16
16
  imageAliases: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
17
+ include: z.ZodOptional<z.ZodObject<{
18
+ paths: z.ZodArray<z.ZodString>;
19
+ maxDepth: z.ZodDefault<z.ZodNumber>;
20
+ fileThreshold: z.ZodDefault<z.ZodNumber>;
21
+ }, z.core.$strip>>;
17
22
  styles: z.ZodOptional<z.ZodPipe<z.ZodObject<{
18
23
  theme: z.ZodOptional<z.ZodPipe<z.ZodObject<{
19
24
  colors: z.ZodOptional<z.ZodUnion<readonly [z.ZodRecord<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"amber" | "blue" | "gray" | "slate" | "green" | "indigo" | "muted" | "primary" | "red" | "secondary" | "sky">, z.ZodString]>, z.ZodTransform<"amber" | "blue" | "gray" | "slate" | "green" | "indigo" | "muted" | "primary" | "red" | "secondary" | "sky", string>>, z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodString, z.ZodTransform<`#${string}` | `rgb(${number},${number},${number})` | `rgba(${number},${number},${number},${number})`, string>>, z.ZodObject<{
@@ -913,6 +918,21 @@ type LikeC4ProjectConfigInput = SimplifyDeep<z.input<typeof LikeC4ProjectJsonCon
913
918
  */
914
919
  declare function validateProjectConfig<C extends string | Record<string, unknown>>(config: C): LikeC4ProjectConfig;
915
920
 
921
+ declare const IncludeConfigSchema: z.ZodObject<{
922
+ paths: z.ZodArray<z.ZodString>;
923
+ maxDepth: z.ZodDefault<z.ZodNumber>;
924
+ fileThreshold: z.ZodDefault<z.ZodNumber>;
925
+ }, z.core.$strip>;
926
+ type IncludeConfig = z.infer<typeof IncludeConfigSchema>;
927
+ declare const IncludeSchema: z.ZodOptional<z.ZodObject<{
928
+ paths: z.ZodArray<z.ZodString>;
929
+ maxDepth: z.ZodDefault<z.ZodNumber>;
930
+ fileThreshold: z.ZodDefault<z.ZodNumber>;
931
+ }, z.core.$strip>>;
932
+ type LikeC4IncludeConfig = z.infer<typeof IncludeSchema>;
933
+ declare function normalizeIncludeConfig(include?: LikeC4IncludeConfig): IncludeConfig;
934
+ declare function validateIncludePaths(include?: LikeC4IncludeConfig): void;
935
+
916
936
  declare const ThemeColorValuesSchema: z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodString, z.ZodTransform<`#${string}` | `rgb(${number},${number},${number})` | `rgba(${number},${number},${number},${number})`, string>>, z.ZodObject<{
917
937
  elements: z.ZodPipe<z.ZodUnion<readonly [z.ZodPipe<z.ZodString, z.ZodTransform<`#${string}` | `rgb(${number},${number},${number})` | `rgba(${number},${number},${number},${number})`, string>>, z.ZodPipe<z.ZodObject<{
918
938
  fill: z.ZodPipe<z.ZodString, z.ZodTransform<`#${string}` | `rgb(${number},${number},${number})` | `rgba(${number},${number},${number},${number})`, string>>;
@@ -2372,4 +2392,4 @@ declare function defineTheme<const S extends LikeC4ConfigThemeInput>(theme: S):
2372
2392
  */
2373
2393
  declare function defineStyle<const S extends LikeC4StylesConfigInput>(styles: S): LikeC4ProjectStylesConfig;
2374
2394
 
2375
- export { ConfigFilenames, type GeneratorFn, type GeneratorFnContext, type GeneratorFnParams, type LikeC4ProjectConfig, type LikeC4ProjectConfigInput, type LikeC4ProjectJsonConfig, type LikeC4StylesConfig, type LikeC4StylesConfigInput, type LocateResult, ManualLayoutsConfigSchema, defineConfig, defineGenerators, defineStyle, defineTheme, defineThemeColor, isLikeC4Config, isLikeC4JsonConfig, isLikeC4NonJsonConfig, validateProjectConfig };
2395
+ export { ConfigFilenames, type GeneratorFn, type GeneratorFnContext, type GeneratorFnParams, type IncludeConfig, type LikeC4ProjectConfig, type LikeC4ProjectConfigInput, type LikeC4ProjectJsonConfig, type LikeC4StylesConfig, type LikeC4StylesConfigInput, type LocateResult, ManualLayoutsConfigSchema, defineConfig, defineGenerators, defineStyle, defineTheme, defineThemeColor, isLikeC4Config, isLikeC4JsonConfig, isLikeC4NonJsonConfig, normalizeIncludeConfig, validateIncludePaths, validateProjectConfig };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- export { C as ConfigFilenames, d as defineConfig, c as defineGenerators, e as defineStyle, f as defineTheme, g as defineThemeColor, i as isLikeC4Config, a as isLikeC4JsonConfig, b as isLikeC4NonJsonConfig, v as validateProjectConfig } from './shared/config.BF5VHDtl.mjs';
1
+ export { C as ConfigFilenames, d as defineConfig, e as defineGenerators, f as defineStyle, g as defineTheme, h as defineThemeColor, i as isLikeC4Config, b as isLikeC4JsonConfig, c as isLikeC4NonJsonConfig, n as normalizeIncludeConfig, a as validateIncludePaths, v as validateProjectConfig } from './shared/config.CUC_rqhf.mjs';
@@ -1,6 +1,6 @@
1
1
  import { URI } from 'vscode-uri';
2
2
  import { LikeC4ProjectConfig } from '../index.mjs';
3
- export { ConfigFilenames, GeneratorFn, GeneratorFnContext, GeneratorFnParams, LikeC4ProjectConfigInput, LikeC4ProjectJsonConfig, LikeC4StylesConfig, LikeC4StylesConfigInput, LocateResult, ManualLayoutsConfigSchema, defineConfig, defineGenerators, defineStyle, defineTheme, defineThemeColor, isLikeC4Config, isLikeC4JsonConfig, isLikeC4NonJsonConfig, validateProjectConfig } from '../index.mjs';
3
+ export { ConfigFilenames, GeneratorFn, GeneratorFnContext, GeneratorFnParams, IncludeConfig, LikeC4ProjectConfigInput, LikeC4ProjectJsonConfig, LikeC4StylesConfig, LikeC4StylesConfigInput, LocateResult, ManualLayoutsConfigSchema, defineConfig, defineGenerators, defineStyle, defineTheme, defineThemeColor, isLikeC4Config, isLikeC4JsonConfig, isLikeC4NonJsonConfig, normalizeIncludeConfig, validateIncludePaths, validateProjectConfig } from '../index.mjs';
4
4
  import '@likec4/core';
5
5
  import '@likec4/core/model';
6
6
  import '@likec4/core/types';
@@ -2,8 +2,8 @@ import { invariant } from '@likec4/core';
2
2
  import { bundleRequire } from 'bundle-require';
3
3
  import * as fs from 'node:fs/promises';
4
4
  import { dirname } from 'node:path';
5
- import { a as isLikeC4JsonConfig, v as validateProjectConfig, b as isLikeC4NonJsonConfig, d as defineConfig } from '../shared/config.BF5VHDtl.mjs';
6
- export { C as ConfigFilenames, c as defineGenerators, e as defineStyle, f as defineTheme, g as defineThemeColor, i as isLikeC4Config } from '../shared/config.BF5VHDtl.mjs';
5
+ import { b as isLikeC4JsonConfig, v as validateProjectConfig, c as isLikeC4NonJsonConfig, d as defineConfig } from '../shared/config.CUC_rqhf.mjs';
6
+ export { C as ConfigFilenames, e as defineGenerators, f as defineStyle, g as defineTheme, h as defineThemeColor, i as isLikeC4Config, n as normalizeIncludeConfig, a as validateIncludePaths } from '../shared/config.CUC_rqhf.mjs';
7
7
  import { rootLogger } from '@likec4/log';
8
8
 
9
9
  const logger = rootLogger.getChild("config");
@@ -5,13 +5,13 @@ import { exact } from '@likec4/core/types';
5
5
 
6
6
  const IMAGE_ALIAS_KEY_REGEX = /^@[A-Za-z0-9_-]*$/;
7
7
  const IMAGE_ALIAS_VALUE_REGEX = /^(?!\/|[A-Za-z]:[\\\/])(?!.*:\/\/).*$/;
8
- const ImageAliasValue = z.string().nonempty("Image alias value cannot be empty").regex(
8
+ const ImageAliasValue = z.string().min(1, "Image alias value cannot be empty").regex(
9
9
  IMAGE_ALIAS_VALUE_REGEX,
10
10
  "Image alias value must be a relative path (no leading slash or protocol)"
11
11
  );
12
12
  const ImageAliasesSchema = z.record(
13
13
  z.string(),
14
- // PLAIN key schema - valibot JSON schema export-safe.
14
+ // PLAIN key schema - zod JSON schema export-safe.
15
15
  ImageAliasValue
16
16
  ).meta({
17
17
  description: "Map of image alias prefixes to relative paths (keys must match /^@\\w+$/; values must be relative paths without protocol or leading slash)."
@@ -45,6 +45,66 @@ function validateImageAliases(imageAliases) {
45
45
  }
46
46
  }
47
47
 
48
+ const RELATIVE_PATH_REGEX = /^(?!\/|[A-Za-z]:[\\\/])(?!.*:\/\/).*$/;
49
+ const IncludePathValue = z.string().min(1, "Include path cannot be empty").regex(
50
+ RELATIVE_PATH_REGEX,
51
+ "Include path must be a relative path (no leading slash, drive letter, or protocol)"
52
+ );
53
+ const IncludeConfigSchema = z.object({
54
+ paths: z.array(IncludePathValue).min(1, "Include paths cannot be empty").meta({
55
+ description: [
56
+ "Additional relative directory paths to include LikeC4 source files from, searched recursively.",
57
+ "Paths are relative to the project folder (the folder containing this config file).",
58
+ 'Example: ["../shared", "../common/specs"]'
59
+ ].join("\n")
60
+ }),
61
+ maxDepth: z.number().int().min(1).max(20).default(3).meta({
62
+ description: [
63
+ "Maximum directory depth to scan when searching for .c4 files in include paths.",
64
+ "Prevents excessive scanning of deeply nested directories.",
65
+ "Default: 3"
66
+ ].join("\n")
67
+ }),
68
+ fileThreshold: z.number().int().min(1).default(30).meta({
69
+ description: [
70
+ "Maximum number of files to load from include paths before warning.",
71
+ "Helps identify performance issues from accidentally including large directories.",
72
+ "Default: 30"
73
+ ].join("\n")
74
+ })
75
+ }).meta({
76
+ id: "include-config",
77
+ description: "Configuration for including additional LikeC4 source files"
78
+ });
79
+ const IncludeSchema = IncludeConfigSchema.optional().meta({
80
+ description: [
81
+ "Configuration for including additional LikeC4 source files from other directories.",
82
+ 'Example: { "paths": ["../shared", "../common/specs"], "maxDepth": 5, "fileThreshold": 50 }'
83
+ ].join("\n")
84
+ });
85
+ function normalizeIncludeConfig(include) {
86
+ if (!include) {
87
+ return { paths: [], maxDepth: 3, fileThreshold: 30 };
88
+ }
89
+ return include;
90
+ }
91
+ function validateIncludePaths(include) {
92
+ if (!include?.paths) {
93
+ return;
94
+ }
95
+ const invalidPaths = [];
96
+ for (const path of include.paths) {
97
+ if (!RELATIVE_PATH_REGEX.test(path)) {
98
+ invalidPaths.push(path);
99
+ }
100
+ }
101
+ if (invalidPaths.length) {
102
+ throw new Error(
103
+ `Invalid include path(s): ${invalidPaths.map((p) => JSON.stringify(p)).join(", ")} (must be relative paths without leading slash, drive letter, or protocol)`
104
+ );
105
+ }
106
+ }
107
+
48
108
  function e(e,t,n){let r=n=>e(n,...t);return n===void 0?r:Object.assign(r,{lazy:n,lazyArgs:t})}
49
109
 
50
110
  function t$1(t,n,r){let i=t.length-n.length;if(i===0)return t(...n);if(i===1)return e(t,n,r);throw Error(`Wrong number of arguments`)}
@@ -63,9 +123,9 @@ const line = z.literal(["dashed", "solid", "dotted"]).meta({ id: "LineType" });
63
123
  const themeColor = z.literal(ThemeColors).meta({ id: "ThemeColor" });
64
124
  const color = z.union([
65
125
  themeColor,
66
- z.string().nonempty("Color name cannot be empty")
126
+ z.string().min(1, "Color name cannot be empty")
67
127
  ]).transform((value) => value).meta({ id: "ColorName" });
68
- const colorValue = z.string().nonempty("Color value cannot be empty").transform((value) => value).meta({
128
+ const colorValue = z.string().min(1, "Color value cannot be empty").transform((value) => value).meta({
69
129
  id: "ColorLiteral",
70
130
  description: "Color value in any valid CSS format: hex, rgb, rgba, hsl, hsla ..."
71
131
  });
@@ -234,6 +294,7 @@ const LikeC4ProjectJsonConfigSchema = z.object({
234
294
  title: z.string().nonempty("Project title cannot be empty if specified").optional().meta({ description: "A human readable title for the project" }),
235
295
  contactPerson: z.string().nonempty("Contact person cannot be empty if specified").optional().meta({ description: "A person who has been involved in creating or maintaining this project" }),
236
296
  imageAliases: ImageAliasesSchema.optional(),
297
+ include: IncludeSchema,
237
298
  styles: LikeC4StylesConfigSchema.optional(),
238
299
  exclude: z.array(z.string()).optional().meta({ description: 'List of file patterns to exclude from the project, default is ["**/node_modules/**"]' }),
239
300
  manualLayouts: ManualLayoutsConfigSchema.optional()
@@ -255,6 +316,9 @@ function validateProjectConfig(config) {
255
316
  if (parsed.data.imageAliases) {
256
317
  validateImageAliases(parsed.data.imageAliases);
257
318
  }
319
+ if (parsed.data.include) {
320
+ validateIncludePaths(parsed.data.include);
321
+ }
258
322
  return parsed.data;
259
323
  }
260
324
 
@@ -309,4 +373,4 @@ function defineStyle(styles) {
309
373
  return LikeC4StylesConfigSchema.parse(styles);
310
374
  }
311
375
 
312
- export { ConfigFilenames as C, isLikeC4JsonConfig as a, isLikeC4NonJsonConfig as b, defineGenerators as c, defineConfig as d, defineStyle as e, defineTheme as f, defineThemeColor as g, isLikeC4Config as i, validateProjectConfig as v };
376
+ export { ConfigFilenames as C, validateIncludePaths as a, isLikeC4JsonConfig as b, isLikeC4NonJsonConfig as c, defineConfig as d, defineGenerators as e, defineStyle as f, defineTheme as g, defineThemeColor as h, isLikeC4Config as i, normalizeIncludeConfig as n, validateProjectConfig as v };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@likec4/config",
3
- "version": "1.45.0",
3
+ "version": "1.46.2",
4
4
  "license": "MIT",
5
5
  "homepage": "https://likec4.dev",
6
6
  "author": "Denis Davydkov <denis@davydkov.com>",
@@ -58,14 +58,14 @@
58
58
  "bundle-require": "^5.1.0",
59
59
  "defu": "^6.1.4",
60
60
  "json5": "^2.2.3",
61
- "zod": "^4.1.12",
61
+ "zod": "^4.1.13",
62
62
  "type-fest": "^4.41.0"
63
63
  },
64
64
  "peerDependencies": {
65
- "esbuild": "^0.25.11",
65
+ "esbuild": "^0.27.1",
66
66
  "vscode-uri": "3.1.0",
67
- "@likec4/core": "1.45.0",
68
- "@likec4/log": "1.45.0"
67
+ "@likec4/core": "1.46.2",
68
+ "@likec4/log": "1.46.1"
69
69
  },
70
70
  "peerDependenciesMeta": {
71
71
  "vscode-uri": {
@@ -73,17 +73,17 @@
73
73
  }
74
74
  },
75
75
  "devDependencies": {
76
- "@types/node": "~20.19.22",
76
+ "@types/node": "~22.19.1",
77
77
  "remeda": "^2.32.0",
78
- "tsx": "4.20.6",
79
- "turbo": "2.6.1",
78
+ "tsx": "4.21.0",
79
+ "turbo": "2.6.3",
80
80
  "typescript": "5.9.3",
81
81
  "unbuild": "3.5.0",
82
82
  "nano-spawn": "^1.0.3",
83
- "vitest": "4.0.13",
84
- "@likec4/log": "1.45.0",
85
- "@likec4/core": "1.45.0",
86
- "@likec4/tsconfig": "1.45.0",
83
+ "vitest": "4.0.16",
84
+ "@likec4/core": "1.46.2",
85
+ "@likec4/log": "1.46.1",
86
+ "@likec4/tsconfig": "1.46.1",
87
87
  "@likec4/devops": "1.42.0"
88
88
  },
89
89
  "scripts": {
package/schema.json CHANGED
@@ -30,6 +30,10 @@
30
30
  "pattern": "^(?!\\/|[A-Za-z]:[\\\\\\/])(?!.*:\\/\\/).*$"
31
31
  }
32
32
  },
33
+ "include": {
34
+ "description": "Configuration for including additional LikeC4 source files from other directories.\nExample: { \"paths\": [\"../shared\", \"../common/specs\"], \"maxDepth\": 5, \"fileThreshold\": 50 }",
35
+ "$ref": "#/$defs/include-config"
36
+ },
33
37
  "styles": {
34
38
  "$ref": "#/$defs/StylesConfiguration"
35
39
  },
@@ -48,6 +52,40 @@
48
52
  "name"
49
53
  ],
50
54
  "$defs": {
55
+ "include-config": {
56
+ "id": "include-config",
57
+ "description": "Configuration for including additional LikeC4 source files",
58
+ "type": "object",
59
+ "properties": {
60
+ "paths": {
61
+ "description": "Additional relative directory paths to include LikeC4 source files from, searched recursively.\nPaths are relative to the project folder (the folder containing this config file).\nExample: [\"../shared\", \"../common/specs\"]",
62
+ "minItems": 1,
63
+ "type": "array",
64
+ "items": {
65
+ "type": "string",
66
+ "minLength": 1,
67
+ "pattern": "^(?!\\/|[A-Za-z]:[\\\\\\/])(?!.*:\\/\\/).*$"
68
+ }
69
+ },
70
+ "maxDepth": {
71
+ "description": "Maximum directory depth to scan when searching for .c4 files in include paths.\nPrevents excessive scanning of deeply nested directories.\nDefault: 3",
72
+ "default": 3,
73
+ "type": "integer",
74
+ "minimum": 1,
75
+ "maximum": 20
76
+ },
77
+ "fileThreshold": {
78
+ "description": "Maximum number of files to load from include paths before warning.\nHelps identify performance issues from accidentally including large directories.\nDefault: 30",
79
+ "default": 30,
80
+ "type": "integer",
81
+ "minimum": 1,
82
+ "maximum": 9007199254740991
83
+ }
84
+ },
85
+ "required": [
86
+ "paths"
87
+ ]
88
+ },
51
89
  "StylesConfiguration": {
52
90
  "id": "StylesConfiguration",
53
91
  "description": "Project styles customization",
package/src/index.ts CHANGED
@@ -9,6 +9,10 @@ export type {
9
9
  ManualLayoutsConfigSchema,
10
10
  } from './schema'
11
11
 
12
+ export type {
13
+ IncludeConfig,
14
+ } from './schema.include'
15
+
12
16
  export type {
13
17
  LikeC4StylesConfig,
14
18
  LikeC4StylesConfigInput,
@@ -16,6 +20,8 @@ export type {
16
20
 
17
21
  export { validateProjectConfig } from './schema'
18
22
 
23
+ export { normalizeIncludeConfig, validateIncludePaths } from './schema.include'
24
+
19
25
  export {
20
26
  ConfigFilenames,
21
27
  isLikeC4Config,
@@ -8,14 +8,14 @@ const IMAGE_ALIAS_VALUE_REGEX = /^(?!\/|[A-Za-z]:[\\\/])(?!.*:\/\/).*$/
8
8
  // Schema for an image alias value: must be a non-empty string representing a relative path (no leading slash, drive letter, or protocol).
9
9
  const ImageAliasValue = z
10
10
  .string()
11
- .nonempty('Image alias value cannot be empty')
11
+ .min(1, 'Image alias value cannot be empty')
12
12
  .regex(
13
13
  IMAGE_ALIAS_VALUE_REGEX,
14
14
  'Image alias value must be a relative path (no leading slash or protocol)',
15
15
  )
16
16
 
17
17
  export const ImageAliasesSchema = z.record(
18
- z.string(), // PLAIN key schema - valibot JSON schema export-safe.
18
+ z.string(), // PLAIN key schema - zod JSON schema export-safe.
19
19
  ImageAliasValue,
20
20
  ).meta({
21
21
  description:
@@ -34,7 +34,7 @@ export function validateImageAliases(imageAliases?: LikeC4ImageAliasConfig) {
34
34
  if (!IMAGE_ALIAS_KEY_REGEX.test(key)) {
35
35
  invalidKeys.push(key)
36
36
  }
37
- // Value regex is technically already enforced by Valibot,
37
+ // Value regex is technically already enforced by zod,
38
38
  // so this check is purely defensive.
39
39
  if (!IMAGE_ALIAS_VALUE_REGEX.test(value)) {
40
40
  invalidValues.push(`${key} -> ${value}`)
@@ -0,0 +1,97 @@
1
+ import * as z from 'zod'
2
+
3
+ // Relative path (no leading slash, drive letter, or protocol)
4
+ // eslint-disable-next-line no-useless-escape
5
+ const RELATIVE_PATH_REGEX = /^(?!\/|[A-Za-z]:[\\\/])(?!.*:\/\/).*$/
6
+
7
+ // Schema for an include path value: must be a non-empty string representing a relative path
8
+ const IncludePathValue = z
9
+ .string()
10
+ .min(1, 'Include path cannot be empty')
11
+ .regex(
12
+ RELATIVE_PATH_REGEX,
13
+ 'Include path must be a relative path (no leading slash, drive letter, or protocol)',
14
+ )
15
+
16
+ export const IncludeConfigSchema = z.object({
17
+ paths: z.array(IncludePathValue)
18
+ .min(1, 'Include paths cannot be empty')
19
+ .meta({
20
+ description: [
21
+ 'Additional relative directory paths to include LikeC4 source files from, searched recursively.',
22
+ 'Paths are relative to the project folder (the folder containing this config file).',
23
+ 'Example: ["../shared", "../common/specs"]',
24
+ ].join('\n'),
25
+ }),
26
+ maxDepth: z.number()
27
+ .int()
28
+ .min(1)
29
+ .max(20)
30
+ .default(3)
31
+ .meta({
32
+ description: [
33
+ 'Maximum directory depth to scan when searching for .c4 files in include paths.',
34
+ 'Prevents excessive scanning of deeply nested directories.',
35
+ 'Default: 3',
36
+ ].join('\n'),
37
+ }),
38
+ fileThreshold: z.number()
39
+ .int()
40
+ .min(1)
41
+ .default(30)
42
+ .meta({
43
+ description: [
44
+ 'Maximum number of files to load from include paths before warning.',
45
+ 'Helps identify performance issues from accidentally including large directories.',
46
+ 'Default: 30',
47
+ ].join('\n'),
48
+ }),
49
+ })
50
+ .meta({
51
+ id: 'include-config',
52
+ description: 'Configuration for including additional LikeC4 source files',
53
+ })
54
+
55
+ export type IncludeConfig = z.infer<typeof IncludeConfigSchema>
56
+
57
+ export const IncludeSchema = IncludeConfigSchema
58
+ .optional()
59
+ .meta({
60
+ description: [
61
+ 'Configuration for including additional LikeC4 source files from other directories.',
62
+ 'Example: { "paths": ["../shared", "../common/specs"], "maxDepth": 5, "fileThreshold": 50 }',
63
+ ].join('\n'),
64
+ })
65
+
66
+ type LikeC4IncludeConfig = z.infer<typeof IncludeSchema>
67
+
68
+ export function normalizeIncludeConfig(include?: LikeC4IncludeConfig): IncludeConfig {
69
+ if (!include) {
70
+ return { paths: [], maxDepth: 3, fileThreshold: 30 }
71
+ }
72
+ return include
73
+ }
74
+
75
+ export function validateIncludePaths(include?: LikeC4IncludeConfig) {
76
+ if (!include?.paths) {
77
+ return
78
+ }
79
+
80
+ const invalidPaths: string[] = []
81
+
82
+ for (const path of include.paths) {
83
+ if (!RELATIVE_PATH_REGEX.test(path)) {
84
+ invalidPaths.push(path)
85
+ }
86
+ }
87
+
88
+ if (invalidPaths.length) {
89
+ throw new Error(
90
+ `Invalid include path(s): ${
91
+ invalidPaths
92
+ .map((p) => JSON.stringify(p))
93
+ .join(', ')
94
+ } (must be relative paths without leading slash, drive letter, or protocol)`,
95
+ )
96
+ }
97
+ }
@@ -56,14 +56,14 @@ const themeColor = z
56
56
  const color = z
57
57
  .union([
58
58
  themeColor,
59
- z.string().nonempty('Color name cannot be empty'),
59
+ z.string().min(1, 'Color name cannot be empty'),
60
60
  ])
61
61
  .transform(value => value as ThemeColor)
62
62
  .meta({ id: 'ColorName' })
63
63
 
64
64
  const colorValue = z
65
65
  .string()
66
- .nonempty('Color value cannot be empty')
66
+ .min(1, 'Color value cannot be empty')
67
67
  .transform(value => value as ColorLiteral)
68
68
  .meta({
69
69
  id: 'ColorLiteral',
package/src/schema.ts CHANGED
@@ -15,6 +15,7 @@ import type { SimplifyDeep } from 'type-fest'
15
15
  import type { URI } from 'vscode-uri'
16
16
  import * as z from 'zod'
17
17
  import { ImageAliasesSchema, validateImageAliases } from './schema.image-alias'
18
+ import { IncludeSchema, validateIncludePaths } from './schema.include'
18
19
  import { LikeC4StylesConfigSchema } from './schema.theme'
19
20
 
20
21
  export const ManualLayoutsConfigSchema = z
@@ -59,6 +60,7 @@ export const LikeC4ProjectJsonConfigSchema = z.object({
59
60
  .meta({ description: 'A person who has been involved in creating or maintaining this project' }),
60
61
  imageAliases: ImageAliasesSchema
61
62
  .optional(),
63
+ include: IncludeSchema,
62
64
  styles: LikeC4StylesConfigSchema
63
65
  .optional(),
64
66
  exclude: z.array(z.string())
@@ -247,5 +249,8 @@ export function validateProjectConfig<C extends string | Record<string, unknown>
247
249
  if (parsed.data.imageAliases) {
248
250
  validateImageAliases(parsed.data.imageAliases)
249
251
  }
252
+ if (parsed.data.include) {
253
+ validateIncludePaths(parsed.data.include)
254
+ }
250
255
  return parsed.data as unknown as LikeC4ProjectConfig
251
256
  }