openmanual 0.15.2 → 0.16.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.ts CHANGED
@@ -13,6 +13,14 @@ declare const OpenManualConfigSchema: z.ZodObject<{
13
13
  all: "all";
14
14
  }>>;
15
15
  favicon: z.ZodOptional<z.ZodString>;
16
+ logo: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
17
+ light: z.ZodString;
18
+ dark: z.ZodString;
19
+ position: z.ZodOptional<z.ZodEnum<{
20
+ sidebar: "sidebar";
21
+ header: "header";
22
+ }>>;
23
+ }, z.core.$strip>]>>;
16
24
  navbar: z.ZodOptional<z.ZodObject<{
17
25
  logo: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
18
26
  light: z.ZodString;
package/dist/index.js CHANGED
@@ -7,6 +7,18 @@ const LogoSchema = z.union([z.string(), z.object({
7
7
  light: z.string(),
8
8
  dark: z.string()
9
9
  })]);
10
+ /** Logo 显示位置 */
11
+ const LogoPositionSchema = z.enum(["sidebar", "header"]);
12
+ /**
13
+ * 顶级 Logo 配置(支持字符串简写和对象形式)
14
+ * - 字符串简写: "/logo.svg" → { light, dark: 同值, position: 'sidebar' }
15
+ * - 对象形式: { light, dark, position? }
16
+ */
17
+ const TopLevelLogoSchema = z.union([z.string(), z.object({
18
+ light: z.string(),
19
+ dark: z.string(),
20
+ position: LogoPositionSchema.optional()
21
+ })]);
10
22
  const FaviconSchema = z.string();
11
23
  const NavbarSchema = z.object({
12
24
  logo: LogoSchema.optional(),
@@ -88,6 +100,7 @@ const OpenManualConfigSchema = z.object({
88
100
  locale: z.string().optional(),
89
101
  contentPolicy: z.enum(["strict", "all"]).optional(),
90
102
  favicon: FaviconSchema.optional(),
103
+ logo: TopLevelLogoSchema.optional(),
91
104
  navbar: NavbarSchema.optional(),
92
105
  header: TopBarSchema.optional(),
93
106
  footer: FooterSchema.optional(),
@@ -99,6 +112,21 @@ const OpenManualConfigSchema = z.object({
99
112
  i18n: I18nConfigSchema.optional(),
100
113
  openapi: OpenApiSchema.optional()
101
114
  });
115
+ /**
116
+ * 将顶级 logo 配置标准化为 { light, dark } 形式
117
+ */
118
+ function normalizeTopLevelLogo(logo) {
119
+ if (typeof logo === "string") return {
120
+ light: logo,
121
+ dark: logo,
122
+ position: "sidebar"
123
+ };
124
+ return {
125
+ light: logo.light,
126
+ dark: logo.dark,
127
+ position: logo.position ?? "sidebar"
128
+ };
129
+ }
102
130
 
103
131
  //#endregion
104
132
  //#region src/core/config/loader.ts
@@ -137,17 +165,31 @@ async function loadConfig(cwd = process.cwd()) {
137
165
  return mergeDefaults(result.data);
138
166
  }
139
167
  function mergeDefaults(config) {
168
+ const topLevelLogo = config.logo ? normalizeTopLevelLogo(config.logo) : null;
169
+ const topLevelLogoSource = topLevelLogo ? topLevelLogo.light === topLevelLogo.dark ? topLevelLogo.light : {
170
+ light: topLevelLogo.light,
171
+ dark: topLevelLogo.dark
172
+ } : null;
140
173
  return {
141
174
  ...config,
142
175
  contentPolicy: config.contentPolicy ?? "strict",
143
176
  contentDir: config.contentDir ?? DEFAULT_CONFIG.contentDir ?? "content",
144
177
  outputDir: config.outputDir ?? DEFAULT_CONFIG.outputDir ?? "dist",
145
178
  locale: config.locale ?? DEFAULT_CONFIG.locale ?? "zh",
179
+ logo: topLevelLogo ? typeof config.logo === "string" ? config.logo : {
180
+ light: topLevelLogo.light,
181
+ dark: topLevelLogo.dark,
182
+ position: topLevelLogo.position
183
+ } : void 0,
146
184
  navbar: {
147
185
  ...DEFAULT_CONFIG.navbar,
148
186
  ...config.navbar,
149
- logo: config.navbar?.logo ?? config.name
187
+ logo: config.navbar?.logo ?? (topLevelLogo && topLevelLogo.position === "sidebar" ? topLevelLogoSource ?? config.name : config.name)
150
188
  },
189
+ header: config.header ? {
190
+ ...config.header,
191
+ logo: config.header.logo ?? (topLevelLogo && topLevelLogo.position === "header" ? topLevelLogoSource ?? void 0 : void 0)
192
+ } : void 0,
151
193
  footer: {
152
194
  ...DEFAULT_CONFIG.footer,
153
195
  ...config.footer,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/core/config/schema.ts","../src/core/config/loader.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const LogoSchema = z.union([z.string(), z.object({ light: z.string(), dark: z.string() })]);\n\nexport const FaviconSchema = z.string();\n\nexport const NavbarSchema = z.object({\n logo: LogoSchema.optional(),\n github: z.url().optional(),\n links: z\n .array(\n z.object({\n label: z.string(),\n href: z.string(),\n })\n )\n .optional(),\n});\n\nexport const FooterSchema = z.object({\n text: z.string().optional(),\n});\n\n// @deprecated Use meta.json files in content directories instead\nexport const SidebarPageSchema = z.object({\n slug: z.string(),\n title: z.string(),\n icon: z.string().optional(),\n});\n\n// @deprecated Use meta.json files in content directories instead\nexport const SidebarGroupSchema = z.object({\n group: z.string(),\n icon: z.string().optional(),\n collapsed: z.boolean().optional(),\n pages: z.array(SidebarPageSchema),\n});\n\nexport const ThemeSchema = z.object({\n primaryHue: z.number().min(0).max(360).optional(),\n darkMode: z.boolean().optional(),\n});\n\nexport const SearchSchema = z.object({\n /**\n * 搜索入口位置\n * - 'sidebar': 放在侧边栏顶部(Fumadocs 风格)\n * - 'header': 放在 header 中间(Mintlify 风格)\n *\n * 默认值: 'sidebar'\n * 不配置 search 字段则不启用搜索(与 header 的「配置即启用」语义一致)\n */\n position: z.enum(['sidebar', 'header']).optional(),\n});\n\nexport const MdxSchema = z.object({\n latex: z.boolean().optional(),\n});\n\nexport const PageActionsSchema = z.object({\n enabled: z.boolean().optional(),\n});\n\nexport const I18nLocaleSchema = z.object({\n code: z.string().min(1),\n name: z.string().min(1),\n});\n\nexport const I18nConfigSchema = z.object({\n enabled: z.boolean().optional(),\n defaultLanguage: z.string().optional(),\n languages: z.array(I18nLocaleSchema).optional(),\n parser: z.enum(['dot', 'dir']).optional(),\n});\n\nexport const OpenApiSpecSchema = z.object({\n /** OpenAPI 规范文件路径,相对于项目根目录 */\n path: z.string(),\n /** 分组标签(用于在侧边栏中显示的分组名) */\n group: z.string().optional(),\n});\n\nexport const OpenApiSchema = z.object({\n /**\n * OpenAPI 规范文件路径(单个文件),相对于项目根目录。支持 .json / .yaml / .yml\n * @deprecated 推荐使用 specs 字段\n */\n specPath: z.string().optional(),\n /**\n * OpenAPI 规范文件配置,支持字符串(单文件)或对象数组(多文件)\n * - string: 单个 spec 文件路径\n * - array: 多个 spec 文件配置,每个可指定 path 和 group\n */\n specs: z.union([z.string(), z.array(OpenApiSpecSchema)]).optional(),\n /** 侧边栏 Tab 显示名称,默认 \"接口文档\"(仅在 separateTab: true 时生效) */\n label: z.string().optional(),\n /**\n * API 端点在侧边栏中的分组策略\n * - 'tag': 按 OpenAPI 规范中的 tags 分组(默认)\n * - 'route': 按路由路径分组\n * - 'none': 不分组,平铺展示\n */\n groupBy: z.enum(['tag', 'route', 'none']).optional().default('tag'),\n /**\n * 是否将 API 文档作为独立的侧边栏 Tab 展示\n * - true: 保持旧行为,API 文档在独立 Tab 中(向后兼容)\n * - false: 将 API 端点混合到文档导航树中(类似 Mintlify 风格) // cspell:ignore Mintlify\n */\n separateTab: z.boolean().optional().default(false),\n});\n\n/** 顶部横条链接项 */\nexport const TopBarLinkSchema = z\n .object({\n /** 链接显示文本(与 icon 至少填一个) */\n label: z.string().optional(),\n /** lucide-react 图标名称(如 \"Github\", \"Twitter\",与 label 至少填一个) */\n icon: z.string().optional(),\n href: z.string(),\n external: z.boolean().optional().default(true),\n })\n .refine((data) => data.label || data.icon, {\n message: '至少需要提供 label 或 icon 中的一个',\n path: ['label'],\n });\n\n/** 顶部横条配置 */\nexport const TopBarSchema = z.object({\n /** 高度,默认 '64px' */\n height: z.string().optional(),\n /** Logo 配置(独立于 navbar.logo) */\n logo: LogoSchema.optional(),\n /** 右侧导航链接 */\n links: z.array(TopBarLinkSchema).optional(),\n /** 是否显示粘性(sticky),默认 true */\n sticky: z.boolean().optional().default(true),\n /** 背景色(CSS 值) */\n background: z.string().optional(),\n /** 底部边框 */\n bordered: z.boolean().optional().default(true),\n});\n\nexport const OpenManualConfigSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n contentDir: z.string().optional(),\n outputDir: z.string().optional(),\n siteUrl: z.url().optional(),\n locale: z.string().optional(),\n contentPolicy: z.enum(['strict', 'all']).optional(),\n favicon: FaviconSchema.optional(),\n navbar: NavbarSchema.optional(),\n header: TopBarSchema.optional(),\n footer: FooterSchema.optional(),\n // @deprecated Use meta.json files in content directories instead\n sidebar: z.array(SidebarGroupSchema).optional(),\n theme: ThemeSchema.optional(),\n search: SearchSchema.optional(),\n mdx: MdxSchema.optional(),\n pageActions: PageActionsSchema.optional(),\n i18n: I18nConfigSchema.optional(),\n openapi: OpenApiSchema.optional(),\n});\n\nexport type OpenManualConfig = z.infer<typeof OpenManualConfigSchema>;\nexport type NavbarConfig = z.infer<typeof NavbarSchema>;\nexport type FooterConfig = z.infer<typeof FooterSchema>;\nexport type SidebarGroup = z.infer<typeof SidebarGroupSchema>;\nexport type SidebarPage = z.infer<typeof SidebarPageSchema>;\nexport type ThemeConfig = z.infer<typeof ThemeSchema>;\nexport type LogoConfig = z.infer<typeof LogoSchema>;\nexport type FaviconConfig = z.infer<typeof FaviconSchema>;\nexport type I18nLocale = z.infer<typeof I18nLocaleSchema>;\nexport type I18nConfig = z.infer<typeof I18nConfigSchema>;\nexport type OpenApiConfig = z.infer<typeof OpenApiSchema>;\nexport type TopBarConfig = z.infer<typeof TopBarSchema>;\nexport type TopBarLink = z.infer<typeof TopBarLinkSchema>;\n\n// @deprecated Use collectSlugsFromMeta from meta-scanner instead\nexport function collectConfiguredSlugs(config: OpenManualConfig): Set<string> {\n const slugs = new Set<string>();\n if (config.sidebar) {\n console.warn(\n '[openmanual] The \"sidebar\" field in openmanual.json is deprecated. ' +\n 'Please use meta.json files in your content directories instead.'\n );\n for (const group of config.sidebar) {\n for (const page of group.pages) {\n slugs.add(page.slug);\n }\n }\n }\n return slugs;\n}\n\nexport function isI18nEnabled(config: OpenManualConfig): boolean {\n return config.i18n?.enabled === true && (config.i18n.languages?.length ?? 0) > 1;\n}\n\nexport function isDirParser(config: OpenManualConfig): boolean {\n return config.i18n?.parser === 'dir';\n}\n\nexport function isOpenApiEnabled(config: OpenManualConfig): boolean {\n if (config.openapi === undefined) return false;\n // 检查 specs(新格式)或 specPath(旧格式,向后兼容)\n const hasSpecs = config.openapi.specs !== undefined;\n const hasSpecPath = typeof config.openapi?.specPath === 'string';\n return hasSpecs || hasSpecPath;\n}\n\n/**\n * 从 OpenAPI 配置中解析出所有 spec 文件路径\n * 兼容 specs(新)和 specPath(旧)两种格式\n */\nexport function resolveOpenApiSpecPaths(config: OpenManualConfig): string[] {\n const openApiCfg = config.openapi;\n if (!openApiCfg) return [];\n\n // 新格式:specs 数组或字符串\n if (openApiCfg.specs !== undefined) {\n if (typeof openApiCfg.specs === 'string') {\n return [openApiCfg.specs];\n }\n return openApiCfg.specs.map((s) => s.path);\n }\n\n // 旧格式:specPath 字符串\n if (typeof openApiCfg.specPath === 'string') {\n return [openApiCfg.specPath];\n }\n\n return [];\n}\n\n/**\n * 判断是否使用独立 Tab 模式(旧行为)\n */\nexport function isSeparateTabMode(config: OpenManualConfig): boolean {\n return config.openapi?.separateTab === true;\n}\n\n/**\n * 判断是否启用了顶部横条(配置了 header 即启用)\n */\nexport function isHeaderEnabled(config: OpenManualConfig): boolean {\n return config.header !== undefined;\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { type OpenManualConfig, OpenManualConfigSchema } from './schema.js';\n\nconst DEFAULT_CONFIG: Partial<OpenManualConfig> = {\n contentDir: 'content',\n outputDir: 'dist',\n locale: 'zh',\n navbar: {},\n footer: {},\n theme: {\n primaryHue: 213,\n darkMode: true,\n },\n mdx: {},\n pageActions: { enabled: true },\n};\n\nexport async function loadConfig(cwd: string = process.cwd()): Promise<OpenManualConfig> {\n const configPath = join(cwd, 'openmanual.json');\n\n let rawJson: string;\n try {\n rawJson = await readFile(configPath, 'utf-8');\n } catch {\n throw new Error(`openmanual.json not found in ${cwd}. Please create one.`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(rawJson);\n } catch {\n throw new Error('openmanual.json is not valid JSON.');\n }\n\n const result = OpenManualConfigSchema.safeParse(parsed);\n if (!result.success) {\n const errors = result.error.issues\n .map((i) => ` - ${i.path.join('.')}: ${i.message}`)\n .join('\\n');\n throw new Error(`openmanual.json validation failed:\\n${errors}`);\n }\n\n return mergeDefaults(result.data);\n}\n\nfunction mergeDefaults(config: OpenManualConfig): OpenManualConfig {\n return {\n ...config,\n contentPolicy: config.contentPolicy ?? 'strict',\n contentDir: config.contentDir ?? DEFAULT_CONFIG.contentDir ?? 'content',\n outputDir: config.outputDir ?? DEFAULT_CONFIG.outputDir ?? 'dist',\n locale: config.locale ?? DEFAULT_CONFIG.locale ?? 'zh',\n navbar: {\n ...DEFAULT_CONFIG.navbar,\n ...config.navbar,\n logo: config.navbar?.logo ?? config.name,\n },\n footer: {\n ...DEFAULT_CONFIG.footer,\n ...config.footer,\n text: config.footer?.text ?? `MIT ${new Date().getFullYear()} © ${config.name}.`,\n },\n theme: {\n ...DEFAULT_CONFIG.theme,\n ...config.theme,\n },\n // 「配置即启用」:用户不配 search 字段则保持 undefined(不启用搜索)\n search: config.search ? { position: config.search.position ?? 'sidebar' } : undefined,\n mdx: {\n ...DEFAULT_CONFIG.mdx,\n ...config.mdx,\n },\n pageActions: {\n ...DEFAULT_CONFIG.pageActions,\n ...config.pageActions,\n },\n i18n: config.i18n\n ? {\n enabled: config.i18n.enabled ?? false,\n defaultLanguage: config.i18n.defaultLanguage ?? config.locale ?? 'zh',\n languages: config.i18n.languages ?? [],\n parser: config.i18n.parser ?? 'dot',\n }\n : undefined,\n openapi: config.openapi\n ? {\n specPath: config.openapi.specPath,\n specs: config.openapi.specs,\n label: config.openapi.label ?? '接口文档',\n groupBy: config.openapi.groupBy ?? 'tag',\n separateTab: config.openapi.separateTab ?? false,\n }\n : undefined,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/core/config/schema.ts","../src/core/config/loader.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const LogoSchema = z.union([z.string(), z.object({ light: z.string(), dark: z.string() })]);\n\n/** Logo 显示位置 */\nexport const LogoPositionSchema = z.enum(['sidebar', 'header']);\n\n/**\n * 顶级 Logo 配置(支持字符串简写和对象形式)\n * - 字符串简写: \"/logo.svg\" → { light, dark: 同值, position: 'sidebar' }\n * - 对象形式: { light, dark, position? }\n */\nexport const TopLevelLogoSchema = z.union([\n z.string(),\n z.object({\n light: z.string(),\n dark: z.string(),\n position: LogoPositionSchema.optional(),\n }),\n]);\n\nexport const FaviconSchema = z.string();\n\nexport const NavbarSchema = z.object({\n /** @deprecated 使用顶级 `logo` 字段代替 */\n logo: LogoSchema.optional(),\n github: z.url().optional(),\n links: z\n .array(\n z.object({\n label: z.string(),\n href: z.string(),\n })\n )\n .optional(),\n});\n\nexport const FooterSchema = z.object({\n text: z.string().optional(),\n});\n\n// @deprecated Use meta.json files in content directories instead\nexport const SidebarPageSchema = z.object({\n slug: z.string(),\n title: z.string(),\n icon: z.string().optional(),\n});\n\n// @deprecated Use meta.json files in content directories instead\nexport const SidebarGroupSchema = z.object({\n group: z.string(),\n icon: z.string().optional(),\n collapsed: z.boolean().optional(),\n pages: z.array(SidebarPageSchema),\n});\n\nexport const ThemeSchema = z.object({\n primaryHue: z.number().min(0).max(360).optional(),\n darkMode: z.boolean().optional(),\n});\n\nexport const SearchSchema = z.object({\n /**\n * 搜索入口位置\n * - 'sidebar': 放在侧边栏顶部(Fumadocs 风格)\n * - 'header': 放在 header 中间(Mintlify 风格)\n *\n * 默认值: 'sidebar'\n * 不配置 search 字段则不启用搜索(与 header 的「配置即启用」语义一致)\n */\n position: z.enum(['sidebar', 'header']).optional(),\n});\n\nexport const MdxSchema = z.object({\n latex: z.boolean().optional(),\n});\n\nexport const PageActionsSchema = z.object({\n enabled: z.boolean().optional(),\n});\n\nexport const I18nLocaleSchema = z.object({\n code: z.string().min(1),\n name: z.string().min(1),\n});\n\nexport const I18nConfigSchema = z.object({\n enabled: z.boolean().optional(),\n defaultLanguage: z.string().optional(),\n languages: z.array(I18nLocaleSchema).optional(),\n parser: z.enum(['dot', 'dir']).optional(),\n});\n\nexport const OpenApiSpecSchema = z.object({\n /** OpenAPI 规范文件路径,相对于项目根目录 */\n path: z.string(),\n /** 分组标签(用于在侧边栏中显示的分组名) */\n group: z.string().optional(),\n});\n\nexport const OpenApiSchema = z.object({\n /**\n * OpenAPI 规范文件路径(单个文件),相对于项目根目录。支持 .json / .yaml / .yml\n * @deprecated 推荐使用 specs 字段\n */\n specPath: z.string().optional(),\n /**\n * OpenAPI 规范文件配置,支持字符串(单文件)或对象数组(多文件)\n * - string: 单个 spec 文件路径\n * - array: 多个 spec 文件配置,每个可指定 path 和 group\n */\n specs: z.union([z.string(), z.array(OpenApiSpecSchema)]).optional(),\n /** 侧边栏 Tab 显示名称,默认 \"接口文档\"(仅在 separateTab: true 时生效) */\n label: z.string().optional(),\n /**\n * API 端点在侧边栏中的分组策略\n * - 'tag': 按 OpenAPI 规范中的 tags 分组(默认)\n * - 'route': 按路由路径分组\n * - 'none': 不分组,平铺展示\n */\n groupBy: z.enum(['tag', 'route', 'none']).optional().default('tag'),\n /**\n * 是否将 API 文档作为独立的侧边栏 Tab 展示\n * - true: 保持旧行为,API 文档在独立 Tab 中(向后兼容)\n * - false: 将 API 端点混合到文档导航树中(类似 Mintlify 风格) // cspell:ignore Mintlify\n */\n separateTab: z.boolean().optional().default(false),\n});\n\n/** 顶部横条链接项 */\nexport const TopBarLinkSchema = z\n .object({\n /** 链接显示文本(与 icon 至少填一个) */\n label: z.string().optional(),\n /** lucide-react 图标名称(如 \"Github\", \"Twitter\",与 label 至少填一个) */\n icon: z.string().optional(),\n href: z.string(),\n external: z.boolean().optional().default(true),\n })\n .refine((data) => data.label || data.icon, {\n message: '至少需要提供 label 或 icon 中的一个',\n path: ['label'],\n });\n\n/** 顶部横条配置 */\nexport const TopBarSchema = z.object({\n /** 高度,默认 '64px' */\n height: z.string().optional(),\n /** @deprecated 使用顶级 `logo` 字段并设置 `position: \"header\"` 代替 */\n logo: LogoSchema.optional(),\n /** 右侧导航链接 */\n links: z.array(TopBarLinkSchema).optional(),\n /** 是否显示粘性(sticky),默认 true */\n sticky: z.boolean().optional().default(true),\n /** 背景色(CSS 值) */\n background: z.string().optional(),\n /** 底部边框 */\n bordered: z.boolean().optional().default(true),\n});\n\nexport const OpenManualConfigSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n contentDir: z.string().optional(),\n outputDir: z.string().optional(),\n siteUrl: z.url().optional(),\n locale: z.string().optional(),\n contentPolicy: z.enum(['strict', 'all']).optional(),\n favicon: FaviconSchema.optional(),\n /** 顶级 Logo 配置(替代 navbar.logo / header.logo) */\n logo: TopLevelLogoSchema.optional(),\n navbar: NavbarSchema.optional(),\n header: TopBarSchema.optional(),\n footer: FooterSchema.optional(),\n // @deprecated Use meta.json files in content directories instead\n sidebar: z.array(SidebarGroupSchema).optional(),\n theme: ThemeSchema.optional(),\n search: SearchSchema.optional(),\n mdx: MdxSchema.optional(),\n pageActions: PageActionsSchema.optional(),\n i18n: I18nConfigSchema.optional(),\n openapi: OpenApiSchema.optional(),\n});\n\nexport type OpenManualConfig = z.infer<typeof OpenManualConfigSchema>;\nexport type NavbarConfig = z.infer<typeof NavbarSchema>;\nexport type FooterConfig = z.infer<typeof FooterSchema>;\nexport type SidebarGroup = z.infer<typeof SidebarGroupSchema>;\nexport type SidebarPage = z.infer<typeof SidebarPageSchema>;\nexport type ThemeConfig = z.infer<typeof ThemeSchema>;\nexport type LogoConfig = z.infer<typeof LogoSchema>;\nexport type FaviconConfig = z.infer<typeof FaviconSchema>;\nexport type I18nLocale = z.infer<typeof I18nLocaleSchema>;\nexport type I18nConfig = z.infer<typeof I18nConfigSchema>;\nexport type OpenApiConfig = z.infer<typeof OpenApiSchema>;\nexport type TopBarConfig = z.infer<typeof TopBarSchema>;\nexport type TopBarLink = z.infer<typeof TopBarLinkSchema>;\nexport type TopLevelLogoConfig = z.infer<typeof TopLevelLogoSchema>;\nexport type LogoPosition = z.infer<typeof LogoPositionSchema>;\n\n// @deprecated Use collectSlugsFromMeta from meta-scanner instead\nexport function collectConfiguredSlugs(config: OpenManualConfig): Set<string> {\n const slugs = new Set<string>();\n if (config.sidebar) {\n console.warn(\n '[openmanual] The \"sidebar\" field in openmanual.json is deprecated. ' +\n 'Please use meta.json files in your content directories instead.'\n );\n for (const group of config.sidebar) {\n for (const page of group.pages) {\n slugs.add(page.slug);\n }\n }\n }\n return slugs;\n}\n\nexport function isI18nEnabled(config: OpenManualConfig): boolean {\n return config.i18n?.enabled === true && (config.i18n.languages?.length ?? 0) > 1;\n}\n\nexport function isDirParser(config: OpenManualConfig): boolean {\n return config.i18n?.parser === 'dir';\n}\n\nexport function isOpenApiEnabled(config: OpenManualConfig): boolean {\n if (config.openapi === undefined) return false;\n // 检查 specs(新格式)或 specPath(旧格式,向后兼容)\n const hasSpecs = config.openapi.specs !== undefined;\n const hasSpecPath = typeof config.openapi?.specPath === 'string';\n return hasSpecs || hasSpecPath;\n}\n\n/**\n * 从 OpenAPI 配置中解析出所有 spec 文件路径\n * 兼容 specs(新)和 specPath(旧)两种格式\n */\nexport function resolveOpenApiSpecPaths(config: OpenManualConfig): string[] {\n const openApiCfg = config.openapi;\n if (!openApiCfg) return [];\n\n // 新格式:specs 数组或字符串\n if (openApiCfg.specs !== undefined) {\n if (typeof openApiCfg.specs === 'string') {\n return [openApiCfg.specs];\n }\n return openApiCfg.specs.map((s) => s.path);\n }\n\n // 旧格式:specPath 字符串\n if (typeof openApiCfg.specPath === 'string') {\n return [openApiCfg.specPath];\n }\n\n return [];\n}\n\n/**\n * 判断是否使用独立 Tab 模式(旧行为)\n */\nexport function isSeparateTabMode(config: OpenManualConfig): boolean {\n return config.openapi?.separateTab === true;\n}\n\n/**\n * 判断是否启用了顶部横条(配置了 header 即启用)\n */\nexport function isHeaderEnabled(config: OpenManualConfig): boolean {\n return config.header !== undefined;\n}\n\n/**\n * 将顶级 logo 配置标准化为 { light, dark } 形式\n */\nexport function normalizeTopLevelLogo(logo: TopLevelLogoConfig): {\n light: string;\n dark: string;\n position: 'sidebar' | 'header';\n} {\n if (typeof logo === 'string') {\n return { light: logo, dark: logo, position: 'sidebar' };\n }\n return {\n light: logo.light,\n dark: logo.dark,\n position: logo.position ?? 'sidebar',\n };\n}\n\n/**\n * 解析有效的 Logo 配置(统一优先级链)\n *\n * 优先级:\n * 1. config.logo(新顶级配置)\n * 2. config.navbar.logo(旧 sidebar logo)\n * 3. config.header.logo(旧 header logo)\n * 4. undefined(调用方回退到 config.name)\n */\nexport function resolveEffectiveLogo(config: OpenManualConfig): {\n source: LogoConfig | undefined;\n position: 'sidebar' | 'header';\n} {\n // 新顶级 logo 最高优先级\n if (config.logo) {\n const normalized = normalizeTopLevelLogo(config.logo);\n const { position, ...source } = normalized;\n return { source: source as LogoConfig, position };\n }\n\n // 旧 navbar.logo → sidebar\n if (config.navbar?.logo) {\n return { source: config.navbar.logo, position: 'sidebar' };\n }\n\n // 旧 header.logo → header\n if (config.header?.logo) {\n return { source: config.header.logo, position: 'header' };\n }\n\n return { source: undefined, position: 'sidebar' };\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { normalizeTopLevelLogo, type OpenManualConfig, OpenManualConfigSchema } from './schema.js';\n\nconst DEFAULT_CONFIG: Partial<OpenManualConfig> = {\n contentDir: 'content',\n outputDir: 'dist',\n locale: 'zh',\n navbar: {},\n footer: {},\n theme: {\n primaryHue: 213,\n darkMode: true,\n },\n mdx: {},\n pageActions: { enabled: true },\n};\n\nexport async function loadConfig(cwd: string = process.cwd()): Promise<OpenManualConfig> {\n const configPath = join(cwd, 'openmanual.json');\n\n let rawJson: string;\n try {\n rawJson = await readFile(configPath, 'utf-8');\n } catch {\n throw new Error(`openmanual.json not found in ${cwd}. Please create one.`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(rawJson);\n } catch {\n throw new Error('openmanual.json is not valid JSON.');\n }\n\n const result = OpenManualConfigSchema.safeParse(parsed);\n if (!result.success) {\n const errors = result.error.issues\n .map((i) => ` - ${i.path.join('.')}: ${i.message}`)\n .join('\\n');\n throw new Error(`openmanual.json validation failed:\\n${errors}`);\n }\n\n return mergeDefaults(result.data);\n}\n\nfunction mergeDefaults(config: OpenManualConfig): OpenManualConfig {\n // 解析顶级 logo(如有),用于后续传播\n const topLevelLogo = config.logo ? normalizeTopLevelLogo(config.logo) : null;\n\n // 将顶级 logo 的 light/dark 部分提取为 LogoConfig 格式(去掉 position)\n const topLevelLogoSource = topLevelLogo\n ? topLevelLogo.light === topLevelLogo.dark\n ? topLevelLogo.light\n : { light: topLevelLogo.light, dark: topLevelLogo.dark }\n : null;\n\n return {\n ...config,\n contentPolicy: config.contentPolicy ?? 'strict',\n contentDir: config.contentDir ?? DEFAULT_CONFIG.contentDir ?? 'content',\n outputDir: config.outputDir ?? DEFAULT_CONFIG.outputDir ?? 'dist',\n locale: config.locale ?? DEFAULT_CONFIG.locale ?? 'zh',\n // 标准化顶级 logo 的 position 默认值\n logo: topLevelLogo\n ? typeof config.logo === 'string'\n ? config.logo\n : { light: topLevelLogo.light, dark: topLevelLogo.dark, position: topLevelLogo.position }\n : undefined,\n navbar: {\n ...DEFAULT_CONFIG.navbar,\n ...config.navbar,\n // 传播逻辑:有顶级 logo 且 position=sidebar → 传播到 navbar.logo\n // 否则保持原有 navbar.logo ?? config.name 逻辑\n logo:\n config.navbar?.logo ??\n (topLevelLogo && topLevelLogo.position === 'sidebar'\n ? (topLevelLogoSource ?? config.name)\n : config.name),\n },\n header: config.header\n ? {\n ...config.header,\n // 传播逻辑:有顶级 logo 且 position=header → 传播到 header.logo\n // 否则保持原有 header.logo 不变\n logo:\n config.header.logo ??\n (topLevelLogo && topLevelLogo.position === 'header'\n ? (topLevelLogoSource ?? undefined)\n : undefined),\n }\n : undefined,\n footer: {\n ...DEFAULT_CONFIG.footer,\n ...config.footer,\n text: config.footer?.text ?? `MIT ${new Date().getFullYear()} © ${config.name}.`,\n },\n theme: {\n ...DEFAULT_CONFIG.theme,\n ...config.theme,\n },\n // 「配置即启用」:用户不配 search 字段则保持 undefined(不启用搜索)\n search: config.search ? { position: config.search.position ?? 'sidebar' } : undefined,\n mdx: {\n ...DEFAULT_CONFIG.mdx,\n ...config.mdx,\n },\n pageActions: {\n ...DEFAULT_CONFIG.pageActions,\n ...config.pageActions,\n },\n i18n: config.i18n\n ? {\n enabled: config.i18n.enabled ?? false,\n defaultLanguage: config.i18n.defaultLanguage ?? config.locale ?? 'zh',\n languages: config.i18n.languages ?? [],\n parser: config.i18n.parser ?? 'dot',\n }\n : undefined,\n openapi: config.openapi\n ? {\n specPath: config.openapi.specPath,\n specs: config.openapi.specs,\n label: config.openapi.label ?? '接口文档',\n groupBy: config.openapi.groupBy ?? 'tag',\n separateTab: config.openapi.separateTab ?? false,\n }\n : undefined,\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openmanual",
3
- "version": "0.15.2",
3
+ "version": "0.16.0",
4
4
  "author": "shenjingnan <sjn.code@gmail.com>",
5
5
  "description": "AI 友好的开源文档系统框架",
6
6
  "type": "module",