@likec4/config 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.
package/dist/index.d.mts CHANGED
@@ -143,6 +143,13 @@ declare const LikeC4ProjectJsonConfigSchema: z.ZodObject<{
143
143
  }, z.core.$strict>>;
144
144
  inferTechnologyFromIcon: z.ZodOptional<z.ZodBoolean>;
145
145
  implicitViews: z.ZodOptional<z.ZodBoolean>;
146
+ landingPage: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
147
+ redirect: z.ZodLiteral<true>;
148
+ }, z.core.$strict>, z.ZodObject<{
149
+ include: z.ZodArray<z.ZodString>;
150
+ }, z.core.$strict>, z.ZodObject<{
151
+ exclude: z.ZodArray<z.ZodString>;
152
+ }, z.core.$strict>]>>;
146
153
  }, z.core.$strip>;
147
154
  type LikeC4ProjectJsonConfig = z.input<typeof LikeC4ProjectJsonConfigSchema>;
148
155
  /**
@@ -272,6 +279,8 @@ type LikeC4ProjectConfigInput = LikeC4ProjectJsonConfig & {
272
279
  };
273
280
  /**
274
281
  * Validates Object into a LikeC4ProjectConfig object.
282
+ * Zod v4 can strip optional union keys (e.g. landingPage) from parse output;
283
+ * we validate landingPage once with LandingPageSchema and merge onto the result.
275
284
  */
276
285
  declare function validateProjectConfig<C extends Record<string, unknown>>(config: C): LikeC4ProjectConfig;
277
286
  /**
@@ -584,4 +593,4 @@ declare function defineTheme<const S extends LikeC4ConfigThemeInput>(theme: S):
584
593
  */
585
594
  declare function defineStyle<const S extends LikeC4StylesConfigInput>(styles: S): LikeC4ProjectStylesConfig;
586
595
  //#endregion
587
- export { ConfigFilenames, type GeneratorFn, type GeneratorFnContext, type GeneratorFnParams, type IncludeConfig, type LikeC4ConfigThemeInput, type LikeC4ProjectConfig, type LikeC4ProjectConfigInput, LikeC4ProjectConfigOps, type LikeC4ProjectJsonConfig, type LikeC4StylesConfig, type LikeC4StylesConfigInput, type LocateResult, type ThemeColorValuesInput, defineConfig, defineGenerators, defineStyle, defineTheme, defineThemeColor, isLikeC4Config, isLikeC4JsonConfig, isLikeC4NonJsonConfig };
596
+ export { ConfigFilenames, type GeneratorFn, type GeneratorFnContext, type GeneratorFnParams, type IncludeConfig, type LikeC4ConfigThemeInput, type LikeC4ProjectConfig, type LikeC4ProjectConfigInput, LikeC4ProjectConfigOps, type LikeC4ProjectJsonConfig, type LikeC4StylesConfig, type LikeC4StylesConfigInput, LikeC4StylesConfigSchema, type LocateResult, type ThemeColorValuesInput, defineConfig, defineGenerators, defineStyle, defineTheme, defineThemeColor, isLikeC4Config, isLikeC4JsonConfig, isLikeC4NonJsonConfig };
package/dist/index.mjs CHANGED
@@ -151,6 +151,14 @@ const ManualLayoutsConfigSchema = z.strictObject({ outDir: z.string().default(".
151
151
  id: "ManualLayoutsConfig",
152
152
  description: "Configuration for manual layouts"
153
153
  });
154
+ const LandingPageSchema = z.union([
155
+ z.strictObject({ redirect: z.literal(true) }),
156
+ z.strictObject({ include: z.array(z.string().nonempty().refine((s) => s !== "#", { message: "selector cannot be \"#\"" })).nonempty("include list cannot be empty") }),
157
+ z.strictObject({ exclude: z.array(z.string().nonempty().refine((s) => s !== "#", { message: "selector cannot be \"#\"" })).nonempty("exclude list cannot be empty") })
158
+ ]).meta({
159
+ id: "LandingPageConfig",
160
+ description: "Configure the landing page. Use redirect to go to the index view, or include/exclude to filter the view grid."
161
+ });
154
162
  const LikeC4ProjectJsonConfigSchema = z.object({
155
163
  name: z.string().nonempty("Project name cannot be empty").refine((value) => value !== "default", {
156
164
  abort: true,
@@ -173,7 +181,8 @@ const LikeC4ProjectJsonConfigSchema = z.object({
173
181
  "Applies to aws:, azure:, gcp:, and tech: icons. Bootstrap icons are excluded.",
174
182
  "Defaults to true."
175
183
  ].join("\n") }),
176
- implicitViews: z.boolean().optional().meta({ description: "Auto-generate scoped views for elements without explicit views. Defaults to false." })
184
+ implicitViews: z.boolean().optional().meta({ description: "Auto-generate scoped views for elements without explicit views. Defaults to false." }),
185
+ landingPage: LandingPageSchema.optional()
177
186
  }).meta({
178
187
  id: "LikeC4ProjectConfig",
179
188
  description: "LikeC4 Project Configuration"
@@ -183,11 +192,34 @@ const GeneratorsSchema = z.record(z.string(), FunctionType);
183
192
  const LikeC4ProjectConfigSchema = LikeC4ProjectJsonConfigSchema.extend({ generators: GeneratorsSchema.optional() });
184
193
  /**
185
194
  * Validates Object into a LikeC4ProjectConfig object.
195
+ * Zod v4 can strip optional union keys (e.g. landingPage) from parse output;
196
+ * we validate landingPage once with LandingPageSchema and merge onto the result.
186
197
  */
187
198
  function validateProjectConfig(config) {
188
- const parsed = LikeC4ProjectConfigSchema.safeParse(config);
189
- if (parsed.success) return parsed.data;
190
- throw new Error("Config validation failed:\n" + z.prettifyError(parsed.error));
199
+ const inputLandingPage = config["landingPage"];
200
+ let validatedLandingPage = null;
201
+ if (inputLandingPage != null) {
202
+ const lpResult = LandingPageSchema.safeParse(inputLandingPage);
203
+ if (!lpResult.success) throw new Error("Config validation failed:\n" + z.prettifyError(lpResult.error));
204
+ validatedLandingPage = lpResult.data;
205
+ }
206
+ const parsed = LikeC4ProjectJsonConfigSchema.safeParse(config);
207
+ if (!parsed.success) throw new Error("Config validation failed:\n" + z.prettifyError(parsed.error));
208
+ let data = parsed.data;
209
+ if (validatedLandingPage !== null) data = {
210
+ ...data,
211
+ landingPage: validatedLandingPage
212
+ };
213
+ const generatorsInput = config["generators"];
214
+ if (generatorsInput != null && typeof generatorsInput === "object" && !Array.isArray(generatorsInput)) {
215
+ const genParsed = GeneratorsSchema.safeParse(generatorsInput);
216
+ if (!genParsed.success) throw new Error("Config validation failed (generators):\n" + z.prettifyError(genParsed.error));
217
+ return {
218
+ ...data,
219
+ generators: genParsed.data
220
+ };
221
+ }
222
+ return data;
191
223
  }
192
224
  /**
193
225
  * Parses JSON string into a LikeC4ProjectConfig object.
@@ -374,4 +406,4 @@ function defineTheme(theme) {
374
406
  function defineStyle(styles) {
375
407
  return LikeC4StylesConfigSchema.parse(styles);
376
408
  }
377
- export { ConfigFilenames, LikeC4ProjectConfigOps, defineConfig, defineGenerators, defineStyle, defineTheme, defineThemeColor, isLikeC4Config, isLikeC4JsonConfig, isLikeC4NonJsonConfig };
409
+ export { ConfigFilenames, LikeC4ProjectConfigOps, LikeC4StylesConfigSchema, defineConfig, defineGenerators, defineStyle, defineTheme, defineThemeColor, isLikeC4Config, isLikeC4JsonConfig, isLikeC4NonJsonConfig };
@@ -143,6 +143,13 @@ declare const LikeC4ProjectJsonConfigSchema: z.ZodObject<{
143
143
  }, z.core.$strict>>;
144
144
  inferTechnologyFromIcon: z.ZodOptional<z.ZodBoolean>;
145
145
  implicitViews: z.ZodOptional<z.ZodBoolean>;
146
+ landingPage: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
147
+ redirect: z.ZodLiteral<true>;
148
+ }, z.core.$strict>, z.ZodObject<{
149
+ include: z.ZodArray<z.ZodString>;
150
+ }, z.core.$strict>, z.ZodObject<{
151
+ exclude: z.ZodArray<z.ZodString>;
152
+ }, z.core.$strict>]>>;
146
153
  }, z.core.$strip>;
147
154
  type LikeC4ProjectJsonConfig = z.input<typeof LikeC4ProjectJsonConfigSchema>;
148
155
  /**
@@ -272,6 +279,8 @@ type LikeC4ProjectConfigInput = LikeC4ProjectJsonConfig & {
272
279
  };
273
280
  /**
274
281
  * Validates Object into a LikeC4ProjectConfig object.
282
+ * Zod v4 can strip optional union keys (e.g. landingPage) from parse output;
283
+ * we validate landingPage once with LandingPageSchema and merge onto the result.
275
284
  */
276
285
  declare function validateProjectConfig<C extends Record<string, unknown>>(config: C): LikeC4ProjectConfig;
277
286
  /**
@@ -591,4 +600,4 @@ declare function defineStyle<const S extends LikeC4StylesConfigInput>(styles: S)
591
600
  */
592
601
  declare function loadConfig(filepath: VscodeURI | string): Promise<LikeC4ProjectConfig>;
593
602
  //#endregion
594
- export { ConfigFilenames, type GeneratorFn, type GeneratorFnContext, type GeneratorFnParams, type IncludeConfig, type LikeC4ConfigThemeInput, type LikeC4ProjectConfig, type LikeC4ProjectConfigInput, LikeC4ProjectConfigOps, type LikeC4ProjectJsonConfig, type LikeC4StylesConfig, type LikeC4StylesConfigInput, type LocateResult, type ThemeColorValuesInput, defineConfig, defineGenerators, defineStyle, defineTheme, defineThemeColor, isLikeC4Config, isLikeC4JsonConfig, isLikeC4NonJsonConfig, loadConfig };
603
+ export { ConfigFilenames, type GeneratorFn, type GeneratorFnContext, type GeneratorFnParams, type IncludeConfig, type LikeC4ConfigThemeInput, type LikeC4ProjectConfig, type LikeC4ProjectConfigInput, LikeC4ProjectConfigOps, type LikeC4ProjectJsonConfig, type LikeC4StylesConfig, type LikeC4StylesConfigInput, LikeC4StylesConfigSchema, type LocateResult, type ThemeColorValuesInput, defineConfig, defineGenerators, defineStyle, defineTheme, defineThemeColor, isLikeC4Config, isLikeC4JsonConfig, isLikeC4NonJsonConfig, loadConfig };
@@ -159,6 +159,14 @@ const ManualLayoutsConfigSchema = z.strictObject({ outDir: z.string().default(".
159
159
  id: "ManualLayoutsConfig",
160
160
  description: "Configuration for manual layouts"
161
161
  });
162
+ const LandingPageSchema = z.union([
163
+ z.strictObject({ redirect: z.literal(true) }),
164
+ z.strictObject({ include: z.array(z.string().nonempty().refine((s) => s !== "#", { message: "selector cannot be \"#\"" })).nonempty("include list cannot be empty") }),
165
+ z.strictObject({ exclude: z.array(z.string().nonempty().refine((s) => s !== "#", { message: "selector cannot be \"#\"" })).nonempty("exclude list cannot be empty") })
166
+ ]).meta({
167
+ id: "LandingPageConfig",
168
+ description: "Configure the landing page. Use redirect to go to the index view, or include/exclude to filter the view grid."
169
+ });
162
170
  const LikeC4ProjectJsonConfigSchema = z.object({
163
171
  name: z.string().nonempty("Project name cannot be empty").refine((value) => value !== "default", {
164
172
  abort: true,
@@ -181,7 +189,8 @@ const LikeC4ProjectJsonConfigSchema = z.object({
181
189
  "Applies to aws:, azure:, gcp:, and tech: icons. Bootstrap icons are excluded.",
182
190
  "Defaults to true."
183
191
  ].join("\n") }),
184
- implicitViews: z.boolean().optional().meta({ description: "Auto-generate scoped views for elements without explicit views. Defaults to false." })
192
+ implicitViews: z.boolean().optional().meta({ description: "Auto-generate scoped views for elements without explicit views. Defaults to false." }),
193
+ landingPage: LandingPageSchema.optional()
185
194
  }).meta({
186
195
  id: "LikeC4ProjectConfig",
187
196
  description: "LikeC4 Project Configuration"
@@ -191,11 +200,34 @@ const GeneratorsSchema = z.record(z.string(), FunctionType);
191
200
  const LikeC4ProjectConfigSchema = LikeC4ProjectJsonConfigSchema.extend({ generators: GeneratorsSchema.optional() });
192
201
  /**
193
202
  * Validates Object into a LikeC4ProjectConfig object.
203
+ * Zod v4 can strip optional union keys (e.g. landingPage) from parse output;
204
+ * we validate landingPage once with LandingPageSchema and merge onto the result.
194
205
  */
195
206
  function validateProjectConfig(config) {
196
- const parsed = LikeC4ProjectConfigSchema.safeParse(config);
197
- if (parsed.success) return parsed.data;
198
- throw new Error("Config validation failed:\n" + z.prettifyError(parsed.error));
207
+ const inputLandingPage = config["landingPage"];
208
+ let validatedLandingPage = null;
209
+ if (inputLandingPage != null) {
210
+ const lpResult = LandingPageSchema.safeParse(inputLandingPage);
211
+ if (!lpResult.success) throw new Error("Config validation failed:\n" + z.prettifyError(lpResult.error));
212
+ validatedLandingPage = lpResult.data;
213
+ }
214
+ const parsed = LikeC4ProjectJsonConfigSchema.safeParse(config);
215
+ if (!parsed.success) throw new Error("Config validation failed:\n" + z.prettifyError(parsed.error));
216
+ let data = parsed.data;
217
+ if (validatedLandingPage !== null) data = {
218
+ ...data,
219
+ landingPage: validatedLandingPage
220
+ };
221
+ const generatorsInput = config["generators"];
222
+ if (generatorsInput != null && typeof generatorsInput === "object" && !Array.isArray(generatorsInput)) {
223
+ const genParsed = GeneratorsSchema.safeParse(generatorsInput);
224
+ if (!genParsed.success) throw new Error("Config validation failed (generators):\n" + z.prettifyError(genParsed.error));
225
+ return {
226
+ ...data,
227
+ generators: genParsed.data
228
+ };
229
+ }
230
+ return data;
199
231
  }
200
232
  /**
201
233
  * Parses JSON string into a LikeC4ProjectConfig object.
@@ -495,4 +527,4 @@ export {
495
527
  });
496
528
  return validateProjectConfig(Object.assign(implicitcfg, mod?.default ?? mod));
497
529
  }
498
- export { ConfigFilenames, LikeC4ProjectConfigOps, defineConfig, defineGenerators, defineStyle, defineTheme, defineThemeColor, isLikeC4Config, isLikeC4JsonConfig, isLikeC4NonJsonConfig, loadConfig };
530
+ export { ConfigFilenames, LikeC4ProjectConfigOps, LikeC4StylesConfigSchema, defineConfig, defineGenerators, defineStyle, defineTheme, defineThemeColor, isLikeC4Config, isLikeC4JsonConfig, isLikeC4NonJsonConfig, loadConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@likec4/config",
3
- "version": "1.52.0",
3
+ "version": "1.53.0",
4
4
  "license": "MIT",
5
5
  "homepage": "https://likec4.dev",
6
6
  "author": "Denis Davydkov <denis@davydkov.com>",
@@ -56,12 +56,12 @@
56
56
  "json5": "^2.2.3",
57
57
  "zod": "^3.25.76",
58
58
  "type-fest": "^4.41.0",
59
- "@likec4/core": "1.52.0",
60
- "@likec4/log": "1.52.0"
59
+ "@likec4/core": "1.53.0",
60
+ "@likec4/log": "1.53.0"
61
61
  },
62
62
  "peerDependencies": {
63
63
  "bundle-require": "^5.1.0",
64
- "esbuild": "0.27.3"
64
+ "esbuild": "0.27.4"
65
65
  },
66
66
  "peerDependenciesMeta": {
67
67
  "esbuild": {
@@ -72,17 +72,17 @@
72
72
  }
73
73
  },
74
74
  "devDependencies": {
75
- "@types/node": "~22.19.11",
75
+ "@types/node": "~22.19.15",
76
76
  "remeda": "^2.33.6",
77
77
  "defu": "^6.1.4",
78
78
  "ufo": "1.6.3",
79
79
  "tsx": "4.21.0",
80
- "turbo": "2.8.13",
80
+ "turbo": "2.8.17",
81
81
  "typescript": "5.9.3",
82
- "obuild": "^0.4.31",
82
+ "obuild": "0.4.31",
83
83
  "nano-spawn": "^2.0.0",
84
- "vitest": "4.0.18",
85
- "@likec4/tsconfig": "1.52.0",
84
+ "vitest": "4.1.0",
85
+ "@likec4/tsconfig": "1.53.0",
86
86
  "@likec4/devops": "1.42.0"
87
87
  },
88
88
  "scripts": {
package/schema.json CHANGED
@@ -86,6 +86,9 @@
86
86
  "implicitViews": {
87
87
  "description": "Auto-generate scoped views for elements without explicit views. Defaults to false.",
88
88
  "type": "boolean"
89
+ },
90
+ "landingPage": {
91
+ "$ref": "#/$defs/LandingPageConfig"
89
92
  }
90
93
  },
91
94
  "required": [
@@ -523,6 +526,59 @@
523
526
  }
524
527
  },
525
528
  "additionalProperties": false
529
+ },
530
+ "LandingPageConfig": {
531
+ "id": "LandingPageConfig",
532
+ "description": "Configure the landing page. Use redirect to go to the index view, or include/exclude to filter the view grid.",
533
+ "anyOf": [
534
+ {
535
+ "type": "object",
536
+ "properties": {
537
+ "redirect": {
538
+ "type": "boolean",
539
+ "const": true
540
+ }
541
+ },
542
+ "required": [
543
+ "redirect"
544
+ ],
545
+ "additionalProperties": false
546
+ },
547
+ {
548
+ "type": "object",
549
+ "properties": {
550
+ "include": {
551
+ "minItems": 1,
552
+ "type": "array",
553
+ "items": {
554
+ "type": "string",
555
+ "minLength": 1
556
+ }
557
+ }
558
+ },
559
+ "required": [
560
+ "include"
561
+ ],
562
+ "additionalProperties": false
563
+ },
564
+ {
565
+ "type": "object",
566
+ "properties": {
567
+ "exclude": {
568
+ "minItems": 1,
569
+ "type": "array",
570
+ "items": {
571
+ "type": "string",
572
+ "minLength": 1
573
+ }
574
+ }
575
+ },
576
+ "required": [
577
+ "exclude"
578
+ ],
579
+ "additionalProperties": false
580
+ }
581
+ ]
526
582
  }
527
583
  }
528
584
  }
package/src/index.ts CHANGED
@@ -23,6 +23,10 @@ export type {
23
23
  ThemeColorValuesInput,
24
24
  } from './schema.theme'
25
25
 
26
+ export {
27
+ LikeC4StylesConfigSchema,
28
+ } from './schema.theme'
29
+
26
30
  export {
27
31
  ConfigFilenames,
28
32
  isLikeC4Config,
package/src/schema.ts CHANGED
@@ -53,6 +53,28 @@ export const ManualLayoutsConfigSchema = z
53
53
 
54
54
  export type ManualLayoutsConfig = z.infer<typeof ManualLayoutsConfigSchema>
55
55
 
56
+ export const LandingPageSchema = z
57
+ .union([
58
+ z.strictObject({
59
+ redirect: z.literal(true),
60
+ }),
61
+ z.strictObject({
62
+ include: z.array(z.string().nonempty().refine(s => s !== '#', { message: 'selector cannot be "#"' })).nonempty(
63
+ 'include list cannot be empty',
64
+ ),
65
+ }),
66
+ z.strictObject({
67
+ exclude: z.array(z.string().nonempty().refine(s => s !== '#', { message: 'selector cannot be "#"' })).nonempty(
68
+ 'exclude list cannot be empty',
69
+ ),
70
+ }),
71
+ ])
72
+ .meta({
73
+ id: 'LandingPageConfig',
74
+ description:
75
+ 'Configure the landing page. Use redirect to go to the index view, or include/exclude to filter the view grid.',
76
+ })
77
+
56
78
  export const LikeC4ProjectJsonConfigSchema = z.object({
57
79
  name: z.string()
58
80
  .nonempty('Project name cannot be empty')
@@ -105,6 +127,7 @@ export const LikeC4ProjectJsonConfigSchema = z.object({
105
127
  .meta({
106
128
  description: 'Auto-generate scoped views for elements without explicit views. Defaults to false.',
107
129
  }),
130
+ landingPage: LandingPageSchema.optional(),
108
131
  })
109
132
  .meta({
110
133
  id: 'LikeC4ProjectConfig',
@@ -271,13 +294,40 @@ export type LikeC4ProjectConfigInput = LikeC4ProjectJsonConfig & {
271
294
 
272
295
  /**
273
296
  * Validates Object into a LikeC4ProjectConfig object.
297
+ * Zod v4 can strip optional union keys (e.g. landingPage) from parse output;
298
+ * we validate landingPage once with LandingPageSchema and merge onto the result.
274
299
  */
275
300
  export function validateProjectConfig<C extends Record<string, unknown>>(config: C): LikeC4ProjectConfig {
276
- const parsed = LikeC4ProjectConfigSchema.safeParse(config)
277
- if (parsed.success) {
278
- return parsed.data as unknown as LikeC4ProjectConfig
301
+ const inputLandingPage = config['landingPage']
302
+ let validatedLandingPage: z.infer<typeof LandingPageSchema> | null = null
303
+ if (inputLandingPage != null) {
304
+ const lpResult = LandingPageSchema.safeParse(inputLandingPage)
305
+ if (!lpResult.success) {
306
+ throw new Error('Config validation failed:\n' + z.prettifyError(lpResult.error))
307
+ }
308
+ validatedLandingPage = lpResult.data
309
+ }
310
+ const parsed = LikeC4ProjectJsonConfigSchema.safeParse(config)
311
+ if (!parsed.success) {
312
+ throw new Error('Config validation failed:\n' + z.prettifyError(parsed.error))
313
+ }
314
+ let data = parsed.data as unknown as LikeC4ProjectConfig
315
+ if (validatedLandingPage !== null) {
316
+ data = { ...data, landingPage: validatedLandingPage }
317
+ }
318
+ const generatorsInput = config['generators']
319
+ if (
320
+ generatorsInput != null &&
321
+ typeof generatorsInput === 'object' &&
322
+ !Array.isArray(generatorsInput)
323
+ ) {
324
+ const genParsed = GeneratorsSchema.safeParse(generatorsInput)
325
+ if (!genParsed.success) {
326
+ throw new Error('Config validation failed (generators):\n' + z.prettifyError(genParsed.error))
327
+ }
328
+ return { ...data, generators: genParsed.data as Record<string, GeneratorFn> }
279
329
  }
280
- throw new Error('Config validation failed:\n' + z.prettifyError(parsed.error))
330
+ return data
281
331
  }
282
332
 
283
333
  /**