@levino/shipyard-docs 0.7.2 → 0.7.3

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/index.ts +140 -116
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@levino/shipyard-docs",
3
- "version": "0.7.2",
3
+ "version": "0.7.3",
4
4
  "description": "Documentation plugin for shipyard with automatic sidebar, pagination, and git metadata",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -27,7 +27,7 @@
27
27
  "effect": "^3.12.5",
28
28
  "ramda": "^0.31",
29
29
  "unist-util-visit": "^5.0.0",
30
- "@levino/shipyard-base": "^0.7.2"
30
+ "@levino/shipyard-base": "^0.7.3"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@tailwindcss/typography": "^0.5.16",
package/src/index.ts CHANGED
@@ -73,111 +73,129 @@ const sidebarSchema = z
73
73
  * Base docs schema object (before transforms/refinements).
74
74
  * Used internally for extending with additional fields.
75
75
  */
76
- const docsSchemaBase = z.object({
77
- // === Page Metadata ===
78
- /** Custom document ID (default: file path) */
79
- id: z.string().optional(),
80
- /** Reference title for SEO, pagination, previews (default: H1) */
81
- title: z.string().optional(),
82
- /** Override title for SEO/browser tab (default: title) - Docusaurus snake_case convention */
83
- title_meta: z.string().optional(),
84
- /** Meta description (default: first paragraph) */
85
- description: z.string().optional(),
86
- /** SEO keywords */
87
- keywords: z.array(z.string()).optional(),
88
- /** Social preview image (og:image) */
89
- image: z.string().optional(),
90
- /** Custom canonical URL */
91
- canonicalUrl: z.string().optional(),
92
- /** Custom canonical URL - snake_case alias for Docusaurus compatibility */
93
- canonical_url: z.string().optional(),
94
-
95
- // === Page Rendering ===
96
- /** Whether to render a page (default: true) */
97
- render: z.boolean().default(true),
98
- /** Exclude from production builds (default: false) */
99
- draft: z.boolean().default(false),
100
- /** Render page but hide from sidebar (default: false) */
101
- unlisted: z.boolean().default(false),
102
- /** Custom URL slug */
103
- slug: z.string().optional(),
104
-
105
- // === Layout Options ===
106
- /** Hide the H1 heading (default: false) */
107
- hideTitle: z.boolean().default(false),
108
- /** Hide the H1 heading (default: false) - snake_case alias for Docusaurus compatibility */
109
- hide_title: z.boolean().optional(),
110
- /** Hide the TOC (default: false) */
111
- hideTableOfContents: z.boolean().default(false),
112
- /** Hide the TOC (default: false) - snake_case alias for Docusaurus compatibility */
113
- hide_table_of_contents: z.boolean().optional(),
114
- /** Full-width page without sidebar (default: false) */
115
- hideSidebar: z.boolean().default(false),
116
- /** Min heading level in TOC (default: 2) */
117
- tocMinHeadingLevel: z.number().min(1).max(6).default(2),
118
- /** Max heading level in TOC (default: 3) */
119
- tocMaxHeadingLevel: z.number().min(1).max(6).default(3),
120
-
121
- // === Sidebar Configuration (grouped) ===
122
- sidebar: sidebarSchema.default({ collapsible: true, collapsed: true }),
123
-
124
- // === Pagination ===
125
- /** Label shown in prev/next buttons */
126
- paginationLabel: z.string().optional(),
127
- /** Label shown in prev/next buttons - snake_case alias for Docusaurus compatibility */
128
- pagination_label: z.string().optional(),
129
- /** Next page ID, or null to disable */
130
- paginationNext: z.string().nullable().optional(),
131
- /** Next page ID - snake_case alias for Docusaurus compatibility */
132
- pagination_next: z.string().nullable().optional(),
133
- /** Previous page ID, or null to disable */
134
- paginationPrev: z.string().nullable().optional(),
135
- /** Previous page ID - snake_case alias for Docusaurus compatibility */
136
- pagination_prev: z.string().nullable().optional(),
137
-
138
- // === Git Metadata Overrides ===
139
- /**
140
- * Override the last update author for this specific page.
141
- * Set to false to hide the author for this page.
142
- */
143
- lastUpdateAuthor: z.union([z.string(), z.literal(false)]).optional(),
144
- /**
145
- * Override the last update timestamp for this specific page.
146
- * Set to false to hide the timestamp for this page.
147
- */
148
- lastUpdateTime: z.union([z.literal(false), z.coerce.date()]).optional(),
149
- /**
150
- * Custom edit URL for this specific page.
151
- * Set to null to disable edit link for this page.
152
- */
153
- customEditUrl: z.string().nullable().optional(),
154
-
155
- // === Custom Meta Tags ===
156
- customMetaTags: z
157
- .array(
158
- z.object({
159
- name: z.string().optional(),
160
- property: z.string().optional(),
161
- content: z.string(),
162
- }),
163
- )
164
- .optional(),
165
- /** Custom meta tags - snake_case alias for Docusaurus compatibility */
166
- custom_meta_tags: z
167
- .array(
168
- z.object({
169
- name: z.string().optional(),
170
- property: z.string().optional(),
171
- content: z.string(),
172
- }),
173
- )
174
- .optional(),
175
- })
76
+ const docsSchemaBase = (image: () => z.ZodType) =>
77
+ z.object({
78
+ // === Page Metadata ===
79
+ /** Custom document ID (default: file path) */
80
+ id: z.string().optional(),
81
+ /** Reference title for SEO, pagination, previews (default: H1) */
82
+ title: z.string().optional(),
83
+ /** Override title for SEO/browser tab (default: title) - Docusaurus snake_case convention */
84
+ title_meta: z.string().optional(),
85
+ /** Meta description (default: first paragraph) */
86
+ description: z.string().optional(),
87
+ /** SEO keywords */
88
+ keywords: z.array(z.string()).optional(),
89
+ /** Image for the page. Use a relative path to a local image file. */
90
+ image: image().optional(),
91
+ /** Custom canonical URL */
92
+ canonicalUrl: z.string().optional(),
93
+ /** Custom canonical URL - snake_case alias for Docusaurus compatibility */
94
+ canonical_url: z.string().optional(),
95
+
96
+ // === Page Rendering ===
97
+ /** Whether to render a page (default: true) */
98
+ render: z.boolean().default(true),
99
+ /** Exclude from production builds (default: false) */
100
+ draft: z.boolean().default(false),
101
+ /** Render page but hide from sidebar (default: false) */
102
+ unlisted: z.boolean().default(false),
103
+ /** Custom URL slug */
104
+ slug: z.string().optional(),
105
+
106
+ // === Layout Options ===
107
+ /** Hide the H1 heading (default: false) */
108
+ hideTitle: z.boolean().default(false),
109
+ /** Hide the H1 heading (default: false) - snake_case alias for Docusaurus compatibility */
110
+ hide_title: z.boolean().optional(),
111
+ /** Hide the TOC (default: false) */
112
+ hideTableOfContents: z.boolean().default(false),
113
+ /** Hide the TOC (default: false) - snake_case alias for Docusaurus compatibility */
114
+ hide_table_of_contents: z.boolean().optional(),
115
+ /** Full-width page without sidebar (default: false) */
116
+ hideSidebar: z.boolean().default(false),
117
+ /** Min heading level in TOC (default: 2) */
118
+ tocMinHeadingLevel: z.number().min(1).max(6).default(2),
119
+ /** Max heading level in TOC (default: 3) */
120
+ tocMaxHeadingLevel: z.number().min(1).max(6).default(3),
121
+
122
+ // === Sidebar Configuration (grouped) ===
123
+ sidebar: sidebarSchema.default({ collapsible: true, collapsed: true }),
124
+
125
+ // === Pagination ===
126
+ /** Label shown in prev/next buttons */
127
+ paginationLabel: z.string().optional(),
128
+ /** Label shown in prev/next buttons - snake_case alias for Docusaurus compatibility */
129
+ pagination_label: z.string().optional(),
130
+ /** Next page ID, or null to disable */
131
+ paginationNext: z.string().nullable().optional(),
132
+ /** Next page ID - snake_case alias for Docusaurus compatibility */
133
+ pagination_next: z.string().nullable().optional(),
134
+ /** Previous page ID, or null to disable */
135
+ paginationPrev: z.string().nullable().optional(),
136
+ /** Previous page ID - snake_case alias for Docusaurus compatibility */
137
+ pagination_prev: z.string().nullable().optional(),
138
+
139
+ // === Git Metadata Overrides ===
140
+ /**
141
+ * Override the last update author for this specific page.
142
+ * Set to false to hide the author for this page.
143
+ */
144
+ lastUpdateAuthor: z.union([z.string(), z.literal(false)]).optional(),
145
+ /**
146
+ * Override the last update timestamp for this specific page.
147
+ * Set to false to hide the timestamp for this page.
148
+ */
149
+ lastUpdateTime: z.union([z.literal(false), z.coerce.date()]).optional(),
150
+ /**
151
+ * Custom edit URL for this specific page.
152
+ * Set to null to disable edit link for this page.
153
+ */
154
+ customEditUrl: z.string().nullable().optional(),
155
+
156
+ // === Custom Meta Tags ===
157
+ customMetaTags: z
158
+ .array(
159
+ z.object({
160
+ name: z.string().optional(),
161
+ property: z.string().optional(),
162
+ content: z.string(),
163
+ }),
164
+ )
165
+ .optional(),
166
+ /** Custom meta tags - snake_case alias for Docusaurus compatibility */
167
+ custom_meta_tags: z
168
+ .array(
169
+ z.object({
170
+ name: z.string().optional(),
171
+ property: z.string().optional(),
172
+ content: z.string(),
173
+ }),
174
+ )
175
+ .optional(),
176
+ })
176
177
 
177
178
  /**
178
179
  * Transform function for docs schema to merge snake_case aliases into camelCase fields.
179
180
  */
180
- const docsSchemaTransform = <T extends z.infer<typeof docsSchemaBase>>(
181
+ const docsSchemaTransform = <
182
+ T extends {
183
+ hide_title?: boolean
184
+ hideTitle: boolean
185
+ hide_table_of_contents?: boolean
186
+ hideTableOfContents: boolean
187
+ canonical_url?: string
188
+ canonicalUrl?: string
189
+ custom_meta_tags?: { name?: string; property?: string; content: string }[]
190
+ customMetaTags?: { name?: string; property?: string; content: string }[]
191
+ pagination_label?: string
192
+ paginationLabel?: string
193
+ pagination_next?: string | null
194
+ paginationNext?: string | null
195
+ pagination_prev?: string | null
196
+ paginationPrev?: string | null
197
+ },
198
+ >(
181
199
  data: T,
182
200
  ) => ({
183
201
  ...data,
@@ -204,9 +222,12 @@ const docsSchemaRefinement = {
204
222
  message: 'tocMinHeadingLevel must be <= tocMaxHeadingLevel',
205
223
  }
206
224
 
207
- export const docsSchema = docsSchemaBase
208
- .transform(docsSchemaTransform)
209
- .refine(docsSchemaRefinement.check, { message: docsSchemaRefinement.message })
225
+ export const docsSchema = ({ image }: { image: () => z.ZodType }) =>
226
+ docsSchemaBase(image)
227
+ .transform(docsSchemaTransform)
228
+ .refine(docsSchemaRefinement.check, {
229
+ message: docsSchemaRefinement.message,
230
+ })
210
231
 
211
232
  /**
212
233
  * Schema for a single version entry in the versions configuration.
@@ -438,17 +459,20 @@ export const createDocsCollection = (
438
459
  * Schema for versioned docs that includes version metadata.
439
460
  * Extends docsSchema with a version field extracted from the file path.
440
461
  */
441
- export const versionedDocsSchema = docsSchemaBase
442
- .extend({
443
- /**
444
- * The version this document belongs to.
445
- * Automatically extracted from the directory structure when using createVersionedDocsCollection.
446
- * @example "v1.0", "v2.0", "latest"
447
- */
448
- version: z.string().optional(),
449
- })
450
- .transform(docsSchemaTransform)
451
- .refine(docsSchemaRefinement.check, { message: docsSchemaRefinement.message })
462
+ export const versionedDocsSchema = ({ image }: { image: () => z.ZodType }) =>
463
+ docsSchemaBase(image)
464
+ .extend({
465
+ /**
466
+ * The version this document belongs to.
467
+ * Automatically extracted from the directory structure when using createVersionedDocsCollection.
468
+ * @example "v1.0", "v2.0", "latest"
469
+ */
470
+ version: z.string().optional(),
471
+ })
472
+ .transform(docsSchemaTransform)
473
+ .refine(docsSchemaRefinement.check, {
474
+ message: docsSchemaRefinement.message,
475
+ })
452
476
 
453
477
  /**
454
478
  * Options for configuring a versioned docs collection.
@@ -1041,7 +1065,7 @@ if (
1041
1065
  }
1042
1066
  ---
1043
1067
 
1044
- <Layout headings={headings} routeBasePath={routeBasePath} editUrl={editUrl} lastUpdated={lastUpdated} lastAuthor={lastAuthor} hideTableOfContents={hideTableOfContents} hideTitle={hideTitle} keywords={keywords} image={image} canonicalUrl={canonicalUrl} customMetaTags={customMetaTags} titleMeta={titleMeta}>
1068
+ <Layout headings={headings} routeBasePath={routeBasePath} editUrl={editUrl} lastUpdated={lastUpdated} lastAuthor={lastAuthor} hideTableOfContents={hideTableOfContents} hideTitle={hideTitle} keywords={keywords} image={image?.src} canonicalUrl={canonicalUrl} customMetaTags={customMetaTags} titleMeta={titleMeta}>
1045
1069
  <Content />
1046
1070
  </Layout>
1047
1071
  `