@docubook/core 1.8.1 → 2.0.0-alpha.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/README.md +100 -385
- package/dist/chunk-J7CN2VUH.js +188 -0
- package/dist/chunk-J7CN2VUH.js.map +1 -0
- package/dist/index.d.ts +76 -72
- package/dist/index.js +125 -177
- package/dist/index.js.map +1 -1
- package/dist/mdx-compiler/serialize.d.ts +53 -0
- package/dist/mdx-compiler/serialize.js +7 -0
- package/dist/mdx-compiler/serialize.js.map +1 -0
- package/package.json +23 -6
package/README.md
CHANGED
|
@@ -1,434 +1,149 @@
|
|
|
1
1
|
# @docubook/core
|
|
2
2
|
|
|
3
|
-
Shared MDX compile pipeline and markdown utilities for DocuBook.
|
|
3
|
+
Shared MDX compile pipeline and markdown utilities for the DocuBook ecosystem.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Pipeline
|
|
6
6
|
|
|
7
|
-
- **Centralized MDX Pipeline** - One shared compile flow for all DocuBook projects
|
|
8
|
-
- **Managed Remark/Rehype Plugins** - Core markdown plugins are maintained by DocuBook author
|
|
9
|
-
- **Content-First Workflow** - Users can focus on docs content instead of plugin maintenance
|
|
10
|
-
- **Utility Helpers** - Frontmatter extraction, TOC extraction, and slug helpers included
|
|
11
|
-
- **Consistent Behavior** - Same markdown rendering behavior across apps and templates
|
|
12
|
-
|
|
13
|
-
## Installation
|
|
14
|
-
|
|
15
|
-
Node.js ecosystem:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm install @docubook/core
|
|
19
7
|
```
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
8
|
+
raw MDX string
|
|
9
|
+
│
|
|
10
|
+
▼
|
|
11
|
+
┌─────────────────────────────┐
|
|
12
|
+
│ EXTRACT (extract.ts) │ gray-matter → frontmatter
|
|
13
|
+
│ │ regex line-scan → TOC (headings)
|
|
14
|
+
└──────────┬──────────────────┘
|
|
15
|
+
│ strippedContent
|
|
16
|
+
▼
|
|
17
|
+
┌─────────────────────────────┐
|
|
18
|
+
│ COMPILE (compile.ts) │ serialize() → MDX compiled output
|
|
19
|
+
│ │ remark: GFM, expandable, directives
|
|
20
|
+
│ │ rehype: preProcess → mermaid → codeTitles
|
|
21
|
+
│ │ → expandable → prism → slug
|
|
22
|
+
│ │ → autolink-headings → postProcess
|
|
23
|
+
└──────────┬──────────────────┘
|
|
24
|
+
│ compiledSource (string) / React element
|
|
25
|
+
▼
|
|
26
|
+
SSR HTML + static hydration modules
|
|
23
27
|
```
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Bun (independent runtime/package manager):
|
|
29
|
+
Content comes from the local filesystem/repository — there is no runtime
|
|
30
|
+
remote compilation (no database/CMS fetching), so compilation is a pure
|
|
31
|
+
build-time/transform step: `serialize()` turns MDX into a string
|
|
32
|
+
(`function-body` for `<MDXRemote>`, `program` for static hydration modules).
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
bun add @docubook/core
|
|
33
|
-
```
|
|
34
|
+
## Markdown directives
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
The default remark chain parses markdown directives (via `remark-directive`)
|
|
37
|
+
and converts them to MDX components (`remarkDirectiveToMdx`) — so interactive
|
|
38
|
+
components can be authored with markdown-native syntax instead of JSX tags:
|
|
36
39
|
|
|
37
|
-
|
|
40
|
+
```md
|
|
41
|
+
:::card{title="Hi" horizontal}
|
|
42
|
+
Content here
|
|
43
|
+
:::
|
|
38
44
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
date: string;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
type TocItem = {
|
|
51
|
-
level: number;
|
|
52
|
-
text: string;
|
|
53
|
-
href: string;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const components = {
|
|
57
|
-
// your MDX components
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const docsService = createMdxContentService<Frontmatter, TocItem>({
|
|
61
|
-
parseOptions: { components },
|
|
62
|
-
cacheFn: cache,
|
|
63
|
-
});
|
|
45
|
+
::::tabs
|
|
46
|
+
:::tab{title="One"}
|
|
47
|
+
A
|
|
48
|
+
:::
|
|
49
|
+
:::tab{title="Two"}
|
|
50
|
+
B
|
|
51
|
+
:::
|
|
52
|
+
::::
|
|
64
53
|
|
|
65
|
-
|
|
66
|
-
const frontmatter = await docsService.getFrontmatterForSlug("getting-started/introduction");
|
|
67
|
-
const tocs = await docsService.getTocsForSlug("getting-started/introduction");
|
|
54
|
+
::youtube{videoId="abc123"}
|
|
68
55
|
```
|
|
69
56
|
|
|
70
|
-
|
|
57
|
+
Directive names are PascalCased to match the components map
|
|
58
|
+
(`:::file-tree` → `FileTree`); bare attributes (`{horizontal}`) become
|
|
59
|
+
boolean props. Nested containers need a longer outer fence (`::::`).
|
|
71
60
|
|
|
72
|
-
|
|
61
|
+
## API
|
|
62
|
+
|
|
63
|
+
### Runtime functions
|
|
73
64
|
|
|
74
65
|
| Function | Description | Returns |
|
|
75
66
|
| -------- | ----------- | ------- |
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `parseMdxFile` | Convert raw file result into `frontmatter`, `tocs`, `content`, `filePath` | `ParsedMdxFile<Frontmatter, TocItem>` |
|
|
80
|
-
| `compileParsedMdxFile` | Compile parsed MDX while preserving metadata and TOCs | `CompiledMdxFile<Frontmatter, TocItem>` |
|
|
81
|
-
| `extractFrontmatter` | Parse frontmatter only from raw markdown/MDX | `Frontmatter` |
|
|
67
|
+
| `serialize` | Compile MDX string to compiled output. `outputFormat: "function-body" \| "program"` | `SerializeResult` |
|
|
68
|
+
| `MDXRemote` | Client-side renderer for pre-compiled `serialize()` output | React component |
|
|
69
|
+
| `extractFrontmatter` | Parse frontmatter only | `Frontmatter` |
|
|
82
70
|
| `extractFrontmatterWithContent` | Extract frontmatter and stripped content in one pass (avoids double parsing) | `{ frontmatter, strippedContent }` |
|
|
83
|
-
| `extractTocsFromRawMdx` | Extract headings for
|
|
71
|
+
| `extractTocsFromRawMdx` | Extract headings for TOC generation | `TocItem[]` |
|
|
84
72
|
| `sluggify` | Convert heading text into URL-safe slug | `string` |
|
|
85
|
-
| `createDefaultRehypePlugins` |
|
|
86
|
-
| `createDefaultRemarkPlugins` |
|
|
87
|
-
| `
|
|
88
|
-
| `postProcess` |
|
|
89
|
-
| `handleCodeTitles` | Move code title metadata to `<pre>` attributes
|
|
90
|
-
| `handleCodeExpandableRemark`
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `cn` | Merge class names using `clsx` + `tailwind-merge` | `string` |
|
|
96
|
-
| `parseDate` | Parse `dd-MM-yyyy` or ISO 8601 date strings into a Date object | `Date` |
|
|
97
|
-
| `stringToDate` | Convert a string or Date value to a Date object | `Date` |
|
|
98
|
-
| `formatDate` | Format date to long format (e.g. "Thursday, April 5, 2026") | `string` |
|
|
99
|
-
| `formatDate2` | Format date to short format (e.g. "Apr 5, 2026") | `string` |
|
|
100
|
-
| `toIsoDateOnly` | Convert date to ISO date-only string (e.g. "2026-04-05") | `string` |
|
|
101
|
-
|
|
102
|
-
#### Type Exports
|
|
103
|
-
|
|
104
|
-
| Type | Purpose |
|
|
105
|
-
| -------------------------------- | ------------------------------------------------------------------------- |
|
|
106
|
-
| `MdxCompileResult` | Result shape for compiled MDX content |
|
|
107
|
-
| `TocItem` | Heading item structure used by TOC extraction |
|
|
108
|
-
| `ParseMdxOptions` | Options for `parseMdx` compile behavior |
|
|
109
|
-
| `ReadMdxFileResult` | Return type for `readMdxFileBySlug` |
|
|
110
|
-
| `ParsedMdxFile` | Parsed file structure before compile |
|
|
111
|
-
| `CompiledMdxFile` | Compiled file structure with metadata and TOC |
|
|
112
|
-
| `CreateMdxContentServiceOptions` | Options for creating the content service, including `frontmatterEnricher`, `tocsExtractor`, and `readOptions` |
|
|
113
|
-
| `ReadMdxBySlugOptions` | Options for `readMdxFileBySlug` — configure `rootDir` and `docsDir` |
|
|
114
|
-
|
|
115
|
-
### Quick Import Recipes
|
|
116
|
-
|
|
117
|
-
#### 1. Compile raw MDX only
|
|
73
|
+
| `createDefaultRehypePlugins` | Default rehype plugin stack | `Pluggable[]` |
|
|
74
|
+
| `createDefaultRemarkPlugins` | Default remark stack (GFM, expandable, directives) | `Pluggable[]` |
|
|
75
|
+
| `remarkDirectiveToMdx` | Convert `:::name{attrs}` directives into MDX component elements | transformer |
|
|
76
|
+
| `preProcess` / `postProcess` | Code-block metadata pre/post processing | transformer |
|
|
77
|
+
| `handleCodeTitles` | Move code title metadata to `<pre>` attributes | transformer |
|
|
78
|
+
| `handleCodeExpandableRemark` / `handleCodeExpandable` | Expandable code block remark/rehype plugins | transformer |
|
|
79
|
+
| `rehypeMermaid` | Transform ` ```mermaid ` fenced blocks into `<Mermaid>` elements | transformer |
|
|
80
|
+
| `cn` | Merge class names (`clsx` + `tailwind-merge`) | `string` |
|
|
81
|
+
| `parseDate` / `stringToDate` | Parse `dd-MM-yyyy` or ISO 8601 into `Date` | `Date` |
|
|
82
|
+
| `formatDate` / `formatDate2` / `toIsoDateOnly` | Date formatting helpers | `string` |
|
|
118
83
|
|
|
119
|
-
|
|
120
|
-
import { parseMdx } from "@docubook/core";
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
Use this when your source is already in memory and you only need compiled content.
|
|
84
|
+
### Frontmatter validation (zod)
|
|
124
85
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
```ts
|
|
128
|
-
import { extractFrontmatter } from "@docubook/core";
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Use this for metadata pages where full MDX compilation is unnecessary.
|
|
132
|
-
|
|
133
|
-
#### 3. Extract frontmatter and content in one pass
|
|
86
|
+
Pass `frontmatterSchema` to `extractFrontmatterWithContent` to validate
|
|
87
|
+
frontmatter right after gray-matter parsing.
|
|
134
88
|
|
|
135
89
|
```ts
|
|
90
|
+
import { z } from "zod";
|
|
136
91
|
import { extractFrontmatterWithContent } from "@docubook/core";
|
|
137
92
|
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
#### 4. Build TOC from raw content
|
|
144
|
-
|
|
145
|
-
```ts
|
|
146
|
-
import { extractTocsFromRawMdx } from "@docubook/core";
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
Use this when you need heading navigation from markdown/MDX text.
|
|
150
|
-
|
|
151
|
-
#### 5. Slug-based docs service (recommended for app integration)
|
|
152
|
-
|
|
153
|
-
```ts
|
|
154
|
-
import { createMdxContentService } from "@docubook/core";
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
Use this as the default app-level integration for frontmatter, TOC, and compiled docs in one service.
|
|
158
|
-
|
|
159
|
-
#### 6. Frontmatter enrichment (date fallback, computed fields)
|
|
160
|
-
|
|
161
|
-
```ts
|
|
162
|
-
import { createMdxContentService } from "@docubook/core";
|
|
163
|
-
|
|
164
|
-
const docsService = createMdxContentService<Frontmatter, TocItem>({
|
|
165
|
-
parseOptions: { components },
|
|
166
|
-
cacheFn: cache,
|
|
167
|
-
frontmatterEnricher: async (frontmatter, absoluteFilePath) => {
|
|
168
|
-
if (!frontmatter.date) {
|
|
169
|
-
const { promises: fs } = await import("fs");
|
|
170
|
-
const stat = await fs.stat(absoluteFilePath);
|
|
171
|
-
return { ...frontmatter, date: stat.mtime };
|
|
172
|
-
}
|
|
173
|
-
return frontmatter;
|
|
174
|
-
},
|
|
175
|
-
});
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
Use this to inject computed or fallback values into frontmatter after parsing — such as a last-modified date from the filesystem or a git commit timestamp. The enricher receives the already-parsed frontmatter and the absolute path of the MDX file on disk, and runs once per slug before caching.
|
|
179
|
-
|
|
180
|
-
#### 7. Custom TOC extraction (`tocsExtractor`)
|
|
181
|
-
|
|
182
|
-
```ts
|
|
183
|
-
import { createMdxContentService } from "@docubook/core";
|
|
184
|
-
|
|
185
|
-
const docsService = createMdxContentService<Frontmatter, TocItem>({
|
|
186
|
-
parseOptions: { components },
|
|
187
|
-
cacheFn: cache,
|
|
188
|
-
tocsExtractor: (rawMdx) => {
|
|
189
|
-
// Custom logic to extract headings — e.g. only h2 and h3
|
|
190
|
-
return rawMdx
|
|
191
|
-
.split("\n")
|
|
192
|
-
.filter((line) => /^#{2,3}\s/.test(line))
|
|
193
|
-
.map((line) => {
|
|
194
|
-
const level = line.startsWith("###") ? 3 : 2;
|
|
195
|
-
const text = line.replace(/^#{2,3}\s+/, "");
|
|
196
|
-
return { level, text, href: `#${text.toLowerCase().replace(/\s+/g, "-")}` };
|
|
197
|
-
});
|
|
198
|
-
},
|
|
93
|
+
const frontmatterSchema = z.object({
|
|
94
|
+
title: z.coerce.string().min(1),
|
|
95
|
+
description: z.coerce.string().default(""),
|
|
96
|
+
image: z.coerce.string().url().optional(),
|
|
97
|
+
date: z.coerce.string().optional(),
|
|
199
98
|
});
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
Use this when the default TOC extraction doesn't match your heading structure or you need to filter/transform headings before rendering.
|
|
203
|
-
|
|
204
|
-
#### 8. Custom docs directory (`readOptions`)
|
|
205
|
-
|
|
206
|
-
```ts
|
|
207
|
-
import { createMdxContentService } from "@docubook/core";
|
|
208
|
-
|
|
209
|
-
const docsService = createMdxContentService<Frontmatter, TocItem>({
|
|
210
|
-
parseOptions: { components },
|
|
211
|
-
cacheFn: cache,
|
|
212
|
-
readOptions: {
|
|
213
|
-
rootDir: "/absolute/path/to/project", // defaults to process.cwd()
|
|
214
|
-
docsDir: "content", // defaults to "docs"
|
|
215
|
-
},
|
|
216
|
-
});
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
Use this when your MDX files live in a non-standard directory (e.g. `content/` instead of `docs/`) or when the working directory differs from the project root.
|
|
220
|
-
|
|
221
|
-
#### 9. Root slug behavior
|
|
222
|
-
|
|
223
|
-
When an empty or blank slug is passed to `readMdxFileBySlug` or the content service, it resolves to `"index"` — meaning it reads `docs/index.mdx`:
|
|
224
|
-
|
|
225
|
-
```ts
|
|
226
|
-
// These are equivalent:
|
|
227
|
-
const doc = await docsService.getCompiledForSlug("");
|
|
228
|
-
const doc = await docsService.getCompiledForSlug("index");
|
|
229
|
-
// Both read from: docs/index.mdx
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
For nested slugs, the resolver tries `docs/{slug}.mdx` first, then falls back to `docs/{slug}/index.mdx`.
|
|
233
|
-
|
|
234
|
-
#### 10. Low-level file pipeline (advanced)
|
|
235
99
|
|
|
236
|
-
|
|
237
|
-
import {
|
|
238
|
-
readMdxFileBySlug,
|
|
239
|
-
parseMdxFile,
|
|
240
|
-
compileParsedMdxFile,
|
|
241
|
-
} from "@docubook/core";
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
Use this when you need full control over each pipeline step.
|
|
245
|
-
|
|
246
|
-
#### 11. Non-RSC MDX compilation (`serialize` + `MDXRemote`)
|
|
247
|
-
|
|
248
|
-
```ts
|
|
249
|
-
import { serialize, MDXRemote } from "@docubook/core";
|
|
250
|
-
|
|
251
|
-
const mdxSource = await serialize(rawMdx, { parseFrontmatter: true });
|
|
252
|
-
// Then in your component:
|
|
253
|
-
<MDXRemote {...mdxSource} components={components} />;
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
Use this for Pages Router or non-RSC environments where `compileMDX` (used internally by `parseMdx`) is not available. `serialize` compiles MDX on the server and `MDXRemote` hydrates it on the client.
|
|
257
|
-
|
|
258
|
-
#### 12. Mermaid diagram support (`rehypeMermaid`)
|
|
259
|
-
|
|
260
|
-
```ts
|
|
261
|
-
import { rehypeMermaid } from "@docubook/core";
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
This plugin transforms ` ```mermaid ` fenced code blocks into `<Mermaid chart="...">` elements during MDX compilation. It runs after `preProcess` and before other code transforms, so mermaid blocks are converted before prism or expandable-code plugins process them.
|
|
265
|
-
|
|
266
|
-
The plugin is included in `createDefaultRehypePlugins()` by default — no manual registration needed.
|
|
267
|
-
|
|
268
|
-
In your MDX files:
|
|
269
|
-
|
|
270
|
-
````md
|
|
271
|
-
```mermaid
|
|
272
|
-
graph TD
|
|
273
|
-
A[Start] --> B{Decision}
|
|
274
|
-
B -->|Yes| C[Process]
|
|
275
|
-
B -->|No| D[End]
|
|
276
|
-
```
|
|
277
|
-
````
|
|
278
|
-
|
|
279
|
-
This requires the `<Mermaid>` component to be registered in your MDX component map (provided by `@docubook/mdx-content`).
|
|
280
|
-
|
|
281
|
-
#### 13. Expandable code blocks (code plugins)
|
|
282
|
-
|
|
283
|
-
```ts
|
|
284
|
-
import {
|
|
285
|
-
handleCodeExpandableRemark,
|
|
286
|
-
handleCodeExpandable,
|
|
287
|
-
} from "@docubook/core";
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
These plugins enable collapsible/expandable code blocks in MDX. Add `Expandable` to the code block meta:
|
|
291
|
-
|
|
292
|
-
````md
|
|
293
|
-
```ts Expandable
|
|
294
|
-
// long code block that will be collapsible
|
|
295
|
-
```
|
|
296
|
-
````
|
|
297
|
-
|
|
298
|
-
`handleCodeExpandableRemark` runs during remark phase to inject `data-expandable` attributes. `handleCodeExpandable` runs during rehype phase to propagate those attributes to the rendered `<pre>` element. Both are included in `createDefaultRehypePlugins()` and `createDefaultRemarkPlugins()` by default.
|
|
299
|
-
|
|
300
|
-
#### 13. Utility functions (`cn`, date helpers)
|
|
301
|
-
|
|
302
|
-
```ts
|
|
303
|
-
import { cn, parseDate, formatDate, formatDate2, toIsoDateOnly } from "@docubook/core";
|
|
304
|
-
|
|
305
|
-
// Merge Tailwind classes
|
|
306
|
-
const className = cn("px-4 py-2", isActive && "bg-blue-500");
|
|
307
|
-
|
|
308
|
-
// Parse dates
|
|
309
|
-
const date = parseDate("05-04-2026"); // dd-MM-yyyy
|
|
310
|
-
const isoDate = parseDate("2026-04-05"); // ISO 8601
|
|
311
|
-
|
|
312
|
-
// Format dates
|
|
313
|
-
formatDate("2026-04-05"); // "Saturday, April 5, 2026"
|
|
314
|
-
formatDate2("2026-04-05"); // "Apr 5, 2026"
|
|
315
|
-
toIsoDateOnly("2026-04-05"); // "2026-04-05"
|
|
100
|
+
const { frontmatter, strippedContent } = extractFrontmatterWithContent(rawMdx, frontmatterSchema);
|
|
316
101
|
```
|
|
317
102
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
### Basic Compile Helpers
|
|
103
|
+
YAML coerces unquoted values (`date: 2026-06-10` → Date, `3.5` → number), so use
|
|
104
|
+
`z.coerce.*` for fields that must remain strings.
|
|
321
105
|
|
|
322
|
-
|
|
323
|
-
import {
|
|
324
|
-
parseMdx,
|
|
325
|
-
extractFrontmatter,
|
|
326
|
-
extractTocsFromRawMdx,
|
|
327
|
-
} from "@docubook/core";
|
|
106
|
+
### Type exports
|
|
328
107
|
|
|
329
|
-
|
|
108
|
+
| Type | Purpose |
|
|
109
|
+
| ---- | ------- |
|
|
110
|
+
| `TocItem` | Heading item structure |
|
|
111
|
+
| `SerializeOptions` / `SerializeResult` | Options/result of `serialize()` |
|
|
112
|
+
| `MDXRemoteSerializeResult` | Shape accepted by `<MDXRemote>` |
|
|
113
|
+
| `MDXRemoteProps` | Props of the `<MDXRemote>` component |
|
|
330
114
|
|
|
331
|
-
|
|
332
|
-
const toc = extractTocsFromRawMdx(raw);
|
|
333
|
-
const compiled = await parseMdx<{ title: string }>(raw);
|
|
334
|
-
```
|
|
115
|
+
## Subpath export: `@docubook/core/serialize`
|
|
335
116
|
|
|
336
|
-
|
|
117
|
+
Standalone MDX compilation (same entry the bundlers use):
|
|
337
118
|
|
|
338
119
|
```ts
|
|
339
|
-
import {
|
|
340
|
-
createMdxContentService,
|
|
341
|
-
readMdxFileBySlug,
|
|
342
|
-
parseMdxFile,
|
|
343
|
-
compileParsedMdxFile,
|
|
344
|
-
} from "@docubook/core";
|
|
345
|
-
|
|
346
|
-
type Frontmatter = {
|
|
347
|
-
title: string;
|
|
348
|
-
description: string;
|
|
349
|
-
image: string;
|
|
350
|
-
date: string;
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
const raw = await readMdxFileBySlug("getting-started/introduction");
|
|
354
|
-
const parsed = parseMdxFile<Frontmatter>(raw);
|
|
355
|
-
const compiled = await compileParsedMdxFile(parsed, {
|
|
356
|
-
components: {
|
|
357
|
-
// your mdx components
|
|
358
|
-
},
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
const docsService = createMdxContentService<Frontmatter>({
|
|
362
|
-
parseOptions: {
|
|
363
|
-
components: {
|
|
364
|
-
// your mdx components
|
|
365
|
-
},
|
|
366
|
-
},
|
|
367
|
-
});
|
|
368
|
-
|
|
369
|
-
const doc = await docsService.getCompiledForSlug("getting-started/introduction");
|
|
120
|
+
import { serialize } from "@docubook/core/serialize";
|
|
370
121
|
```
|
|
371
122
|
|
|
372
|
-
## Subpath
|
|
373
|
-
|
|
374
|
-
### `@docubook/core/utils`
|
|
123
|
+
## Subpath export: `@docubook/core/utils`
|
|
375
124
|
|
|
376
|
-
|
|
125
|
+
Lightweight — utilities only, no MDX compile dependencies:
|
|
377
126
|
|
|
378
127
|
```ts
|
|
379
128
|
import { cn, parseDate, stringToDate, formatDate, formatDate2, toIsoDateOnly } from "@docubook/core/utils";
|
|
380
129
|
```
|
|
381
130
|
|
|
382
|
-
|
|
383
|
-
| --------------- | ----------------------------------------------------------- |
|
|
384
|
-
| `cn` | Merge class names using `clsx` + `tailwind-merge` |
|
|
385
|
-
| `parseDate` | Parse `dd-MM-yyyy` or ISO 8601 date strings into a Date |
|
|
386
|
-
| `stringToDate` | Convert a string or Date value to a Date object |
|
|
387
|
-
| `formatDate` | Format date to long format (e.g. "Thursday, April 5, 2026") |
|
|
388
|
-
| `formatDate2` | Format date to short format (e.g. "Apr 5, 2026") |
|
|
389
|
-
| `toIsoDateOnly` | Convert date to ISO date-only string (e.g. "2026-04-05") |
|
|
390
|
-
|
|
391
|
-
## Dependency Management Policy
|
|
392
|
-
|
|
393
|
-
Dependencies required for markdown processing are managed in this package and updated by the DocuBook author.
|
|
394
|
-
|
|
395
|
-
This means app-level users should focus on content and integration. Plugin upgrades, compatibility checks, and pipeline maintenance are handled centrally by DocuBook.
|
|
396
|
-
|
|
397
|
-
### Managed Markdown Dependencies
|
|
398
|
-
|
|
399
|
-
- @11ty/gray-matter
|
|
400
|
-
- rehype-autolink-headings
|
|
401
|
-
- rehype-code-titles
|
|
402
|
-
- rehype-prism-plus
|
|
403
|
-
- rehype-slug
|
|
404
|
-
- remark-gfm
|
|
405
|
-
- unist-util-visit
|
|
406
|
-
|
|
407
|
-
### Managed Utility Dependencies
|
|
408
|
-
|
|
409
|
-
- clsx — class name composition for the `cn()` utility
|
|
410
|
-
- tailwind-merge — intelligent Tailwind class merging for the `cn()` utility
|
|
411
|
-
- next-mdx-remote — MDX runtime/compile engine (`serialize`, `MDXRemote`)
|
|
412
|
-
|
|
413
|
-
The `remark` and `rehype` plugin stack is intentionally owned by this package to avoid dependency drift across apps.
|
|
414
|
-
|
|
415
|
-
## Why This Matters
|
|
416
|
-
|
|
417
|
-
- Consistent behavior across all DocuBook-based projects
|
|
418
|
-
- Easier maintenance and safer upgrades
|
|
419
|
-
- Less dependency duplication in app-level package.json files
|
|
420
|
-
- Faster onboarding for users who only need to write docs
|
|
421
|
-
|
|
422
|
-
## Notes
|
|
423
|
-
|
|
424
|
-
`@docubook/core` already includes and manages the MDX runtime/compile dependencies (including `next-mdx-remote`) as part of the package contract.
|
|
425
|
-
|
|
426
|
-
In most integrations, users only need to install `@docubook/core` and use the core APIs.
|
|
131
|
+
## Dependencies
|
|
427
132
|
|
|
428
|
-
|
|
133
|
+
Markdown processing dependencies are managed here and updated by the DocuBook
|
|
134
|
+
author — app-level users should not redeclare them.
|
|
429
135
|
|
|
430
|
-
|
|
136
|
+
| Category | Packages |
|
|
137
|
+
| -------- | -------- |
|
|
138
|
+
| Frontmatter | `@11ty/gray-matter` |
|
|
139
|
+
| MDX runtime | `@mdx-js/mdx`, `@mdx-js/react`, `vfile`, `vfile-matter`, `unist-util-remove` |
|
|
140
|
+
| Remark plugins | `remark-gfm`, `remark-directive`, `handleCodeExpandable` (internal) |
|
|
141
|
+
| Rehype plugins | `rehype-autolink-headings`, `rehype-code-titles`, `rehype-prism-plus`, `rehype-slug` (internal code plugins) |
|
|
142
|
+
| AST traversal | `unist-util-visit` |
|
|
143
|
+
| Utilities | `clsx`, `tailwind-merge` |
|
|
144
|
+
| Validation | `zod` |
|
|
431
145
|
|
|
432
146
|
## License
|
|
433
147
|
|
|
434
|
-
MIT
|
|
148
|
+
MIT — the files under `src/mdx-compiler/` are MPL-2.0 (derived from
|
|
149
|
+
next-mdx-remote); see `LICENSE-MPL-2.0`.
|