diff --git a/packages/cli/src/commands/build/build.schema.ts b/packages/cli/src/commands/build/build.schema.ts index c5063d9..9643052 100644 --- a/packages/cli/src/commands/build/build.schema.ts +++ b/packages/cli/src/commands/build/build.schema.ts @@ -1,22 +1,24 @@ import z from "zod"; export const buildConfigSchema = z.object({ - manifest: z.object({ - prefix: z - .string() - .describe("Default prefix for documentation links") - .default("docs/references"), - enabled: z - .boolean() - .describe("Whether to generate manifest.json file") - .default(true), - path: z - .string() - .describe( - "Path to save manifest file (relative to project root or absolute path). If not specified, uses outputDir/manifest.json", - ) - .optional(), - }), + manifest: z + .object({ + prefix: z + .string() + .describe("Default prefix for documentation links") + .default("docs/references"), + enabled: z + .boolean() + .describe("Whether to generate manifest.json file") + .default(true), + path: z + .string() + .describe( + "Path to save manifest file (relative to project root or absolute path). If not specified, uses outputDir/manifest.json", + ) + .optional(), + }) + .default({}), outputDir: z .string() .describe("Directory where build output will be saved") diff --git a/packages/cli/src/commands/check/check.schema.ts b/packages/cli/src/commands/check/check.schema.ts index 9ae2da7..35fa9c5 100644 --- a/packages/cli/src/commands/check/check.schema.ts +++ b/packages/cli/src/commands/check/check.schema.ts @@ -1,5 +1,7 @@ import { z } from "zod"; -export const checkConfigSchema = z.object({ - entryPoints: z.array(z.string()).optional().describe("Entry points to check"), -}); +export const checkConfigSchema = z + .object({ + entryPoints: z.array(z.string()).optional().describe("Entry points to check"), + }) + .default({}); diff --git a/packages/cli/src/config/config.schema.ts b/packages/cli/src/config/config.schema.ts index a2427ab..d0f169b 100644 --- a/packages/cli/src/config/config.schema.ts +++ b/packages/cli/src/config/config.schema.ts @@ -13,7 +13,8 @@ export const configSchema = z.object({ .describe("Package patterns to include in build"), exclude: z .array(z.string()) - .describe("Package patterns to exclude from build"), + .describe("Package patterns to exclude from build") + .default([]), }), }), commands: z.object({ @@ -58,4 +59,6 @@ export const configSchema = z.object({ * @param {function} plugins.plugin Factory function that returns plugin instance * @param {object} [plugins.options] Plugin options */ -export type Config = z.infer; +export type Config = z.input; + +export type ResolvedConfig = z.output; diff --git a/packages/cli/src/plugins/load-plugins.ts b/packages/cli/src/plugins/load-plugins.ts index b5c3a99..edf27c1 100644 --- a/packages/cli/src/plugins/load-plugins.ts +++ b/packages/cli/src/plugins/load-plugins.ts @@ -1,7 +1,7 @@ import { Plugin } from "./types/plugin.types.js"; -import { Config } from "../config/config.schema.js"; +import { ResolvedConfig } from "../config/config.schema.js"; -export async function loadPlugins(config: Config): Promise { +export async function loadPlugins(config: ResolvedConfig): Promise { const plugins: Plugin[] = []; for (const pluginConfig of config.plugins) { diff --git a/packages/cli/src/plugins/plugin-manager.ts b/packages/cli/src/plugins/plugin-manager.ts index cb669fe..80f95c3 100644 --- a/packages/cli/src/plugins/plugin-manager.ts +++ b/packages/cli/src/plugins/plugin-manager.ts @@ -4,7 +4,7 @@ import { MarkdownGenerator } from "../core/types/generator.types.js"; import { createVitePressPlugin } from "./builtin/vitepress-plugin.js"; import path from "path"; -import { Config } from "../config/config.schema.js"; +import { ResolvedConfig } from "../config/config.schema.js"; export class PluginManager { private plugins: Plugin[] = []; @@ -32,7 +32,7 @@ export class PluginManager { }, manifest); } - getGenerator(config: Config): MarkdownGenerator { + getGenerator(config: ResolvedConfig): MarkdownGenerator { const generatorConfig = config.commands.build.generator; if (generatorConfig.name === "vitepress") { diff --git a/packages/cli/src/plugins/types/plugin.types.ts b/packages/cli/src/plugins/types/plugin.types.ts index c3a633e..0010092 100644 --- a/packages/cli/src/plugins/types/plugin.types.ts +++ b/packages/cli/src/plugins/types/plugin.types.ts @@ -1,5 +1,5 @@ import { SidebarItem } from "../../commands/build/manifest/manifest.js"; -import { Config } from "../../config/config.schema.js"; +import { ResolvedConfig } from "../../config/config.schema.js"; import { MarkdownGenerator } from "../../core/types/generator.types.js"; /** @@ -15,7 +15,7 @@ import { MarkdownGenerator } from "../../core/types/generator.types.js"; */ export interface PluginContext { workspacePath?: string; - config?: Config; + config?: ResolvedConfig; } /** diff --git a/packages/cli/src/tests/plugin/plugin-loader.spec.ts b/packages/cli/src/tests/plugin/plugin-loader.spec.ts index d409b4c..3564dcc 100644 --- a/packages/cli/src/tests/plugin/plugin-loader.spec.ts +++ b/packages/cli/src/tests/plugin/plugin-loader.spec.ts @@ -1,7 +1,7 @@ import { describe, it, expect, beforeEach, afterEach } from "vitest"; import { loadPlugins } from "../../plugins/load-plugins.js"; import { createE2EWorkspace, E2EWorkspace } from "../utils/create-e2e-workspace.js"; -import { Config } from "../../config/config.schema.js"; +import { configSchema } from "../../config/config.schema.js"; import { SidebarItem } from "../../commands/build/manifest/manifest.js"; import { MOCK_CONFIG } from "../__mock__/config.mock.js"; @@ -31,7 +31,7 @@ export default { ` ); - const config: Config = { + const config = configSchema.parse({ ...MOCK_CONFIG, project: { ...MOCK_CONFIG.project, @@ -44,7 +44,7 @@ export default { (await import(`${workspace.root}/my-plugin.js`)).default, }, ], - }; + }); const plugins = await loadPlugins(config); @@ -70,7 +70,7 @@ export const myNamedPlugin = { ` ); - const config: Config = { + const config = configSchema.parse({ ...MOCK_CONFIG, project: { ...MOCK_CONFIG.project, @@ -83,7 +83,7 @@ export const myNamedPlugin = { (await import(`${workspace.root}/named-plugin.js`)).myNamedPlugin, }, ], - }; + }); const plugins = await loadPlugins(config); @@ -94,7 +94,7 @@ export const myNamedPlugin = { it("should load inline plugin", async () => { const workspace = await createE2EWorkspace(); - const config: Config = { + const config = configSchema.parse({ ...MOCK_CONFIG, project: { ...MOCK_CONFIG.project, @@ -113,7 +113,7 @@ export const myNamedPlugin = { }), }, ], - }; + }); const plugins = await loadPlugins(config); @@ -124,14 +124,14 @@ export const myNamedPlugin = { it("should handle empty plugin list", async () => { const workspace = await createE2EWorkspace(); - const config: Config = { + const config = configSchema.parse({ ...MOCK_CONFIG, project: { ...MOCK_CONFIG.project, root: workspace.root, }, plugins: [], - }; + }); const plugins = await loadPlugins(config); @@ -140,7 +140,7 @@ export const myNamedPlugin = { it("should throw error for missing plugin file", async () => { const workspace = await createE2EWorkspace(); - const config: Config = { + const config = configSchema.parse({ ...MOCK_CONFIG, project: { ...MOCK_CONFIG.project, @@ -153,7 +153,7 @@ export const myNamedPlugin = { (await import(`${workspace.root}/nonexistent.js`)).default, }, ], - }; + }); await expect(loadPlugins(config)).rejects.toThrow( "Failed to load plugin 'missing-plugin'" @@ -162,7 +162,7 @@ export const myNamedPlugin = { it("should throw error for plugin without path or hooks", async () => { const workspace = await createE2EWorkspace(); - const config: Config = { + const config = configSchema.parse({ ...MOCK_CONFIG, project: { ...MOCK_CONFIG.project, @@ -174,7 +174,7 @@ export const myNamedPlugin = { plugin: null as unknown as () => Promise, }, ], - }; + }); await expect(loadPlugins(config)).rejects.toThrow( "pluginConfig.plugin is not a function" @@ -190,7 +190,7 @@ export default "not a plugin object"; ` ); - const config: Config = { + const config = configSchema.parse({ ...MOCK_CONFIG, project: { ...MOCK_CONFIG.project, @@ -203,7 +203,7 @@ export default "not a plugin object"; (await import(`${workspace.root}/invalid-plugin.js`)).default, }, ], - }; + }); await expect(loadPlugins(config)).rejects.toThrow( "did not return a valid plugin object"