@docubook/core 1.1.1 → 1.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Wildan Nursahidan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -71,31 +71,33 @@ const tocs = await docsService.getTocsForSlug("getting-started/introduction");
71
71
 
72
72
  #### Runtime APIs
73
73
 
74
- - `parseMdx`: Compile raw MDX string with optional custom parse options. Returns `MdxCompileResult<Frontmatter>`.
75
- - `createMdxContentService`: Create slug-based docs service (`getParsedForSlug`, `getCompiledForSlug`, `getFrontmatterForSlug`, `getTocsForSlug`). Returns a service object.
76
- - `readMdxFileBySlug`: Read `slug.mdx` or `slug/index.mdx` from docs directory. Returns `ReadMdxFileResult`.
77
- - `parseMdxFile`: Convert raw file result into `frontmatter`, `tocs`, `content`, `filePath`. Returns `ParsedMdxFile<Frontmatter, TocItem>`.
78
- - `compileParsedMdxFile`: Compile parsed MDX while preserving metadata and TOCs. Returns `CompiledMdxFile<Frontmatter, TocItem>`.
79
- - `extractFrontmatter`: Parse frontmatter only from raw markdown/MDX. Returns `Frontmatter`.
80
- - `extractTocsFromRawMdx`: Extract headings for table of contents generation. Returns `TocItem[]`.
81
- - `sluggify`: Convert heading text into URL-safe slug. Returns `string`.
82
- - `createDefaultRehypePlugins`: Get default DocuBook rehype plugin stack. Returns `unknown[]`.
83
- - `createDefaultRemarkPlugins`: Get default DocuBook remark plugin stack. Returns `unknown[]`.
84
- - `preProcess`: Add pre-processing behavior for code blocks (advanced customization). Returns a transformer function.
85
- - `postProcess`: Add post-processing behavior for code blocks (advanced customization). Returns a transformer function.
86
- - `handleCodeTitles`: Move code title metadata to `<pre>` attributes (advanced customization). Returns a transformer function.
74
+ | Function | Description | Returns |
75
+ | -------- | ----------- | ------- |
76
+ | `parseMdx` | Compile raw MDX string with optional custom parse options | `MdxCompileResult<Frontmatter>` |
77
+ | `createMdxContentService` | Create slug-based docs service (`getParsedForSlug`, `getCompiledForSlug`, `getFrontmatterForSlug`, `getTocsForSlug`). Accepts optional `frontmatterEnricher` to inject computed or fallback values after parsing | service object |
78
+ | `readMdxFileBySlug` | Read `slug.mdx` or `slug/index.mdx` from docs directory | `ReadMdxFileResult` |
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` |
82
+ | `extractTocsFromRawMdx` | Extract headings for table of contents generation | `TocItem[]` |
83
+ | `sluggify` | Convert heading text into URL-safe slug | `string` |
84
+ | `createDefaultRehypePlugins` | Get default DocuBook rehype plugin stack | `unknown[]` |
85
+ | `createDefaultRemarkPlugins` | Get default DocuBook remark plugin stack | `unknown[]` |
86
+ | `preProcess` | Add pre-processing behavior for code blocks (advanced) | transformer function |
87
+ | `postProcess` | Add post-processing behavior for code blocks (advanced) | transformer function |
88
+ | `handleCodeTitles` | Move code title metadata to `<pre>` attributes (advanced) | transformer function |
87
89
 
88
90
  #### Type Exports
89
91
 
90
- | Type | Purpose |
91
- | -------------------------------- | --------------------------------------------- |
92
- | `MdxCompileResult` | Result shape for compiled MDX content |
93
- | `TocItem` | Heading item structure used by TOC extraction |
94
- | `ParseMdxOptions` | Options for `parseMdx` compile behavior |
95
- | `ReadMdxFileResult` | Return type for `readMdxFileBySlug` |
96
- | `ParsedMdxFile` | Parsed file structure before compile |
97
- | `CompiledMdxFile` | Compiled file structure with metadata and TOC |
98
- | `CreateMdxContentServiceOptions` | Options for creating the content service |
92
+ | Type | Purpose |
93
+ | -------------------------------- | ------------------------------------------------------------------------- |
94
+ | `MdxCompileResult` | Result shape for compiled MDX content |
95
+ | `TocItem` | Heading item structure used by TOC extraction |
96
+ | `ParseMdxOptions` | Options for `parseMdx` compile behavior |
97
+ | `ReadMdxFileResult` | Return type for `readMdxFileBySlug` |
98
+ | `ParsedMdxFile` | Parsed file structure before compile |
99
+ | `CompiledMdxFile` | Compiled file structure with metadata and TOC |
100
+ | `CreateMdxContentServiceOptions` | Options for creating the content service, including `frontmatterEnricher` |
99
101
 
100
102
  ### Quick Import Recipes
101
103
 
@@ -131,7 +133,28 @@ import { createMdxContentService } from "@docubook/core";
131
133
 
132
134
  Use this as the default app-level integration for frontmatter, TOC, and compiled docs in one service.
133
135
 
134
- #### 5. Low-level file pipeline (advanced)
136
+ #### 5. Frontmatter enrichment (date fallback, computed fields)
137
+
138
+ ```ts
139
+ import { createMdxContentService } from "@docubook/core";
140
+
141
+ const docsService = createMdxContentService<Frontmatter, TocItem>({
142
+ parseOptions: { components },
143
+ cacheFn: cache,
144
+ frontmatterEnricher: async (frontmatter, absoluteFilePath) => {
145
+ if (!frontmatter.date) {
146
+ const { promises: fs } = await import("fs");
147
+ const stat = await fs.stat(absoluteFilePath);
148
+ return { ...frontmatter, date: stat.mtime };
149
+ }
150
+ return frontmatter;
151
+ },
152
+ });
153
+ ```
154
+
155
+ 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.
156
+
157
+ #### 6. Low-level file pipeline (advanced)
135
158
 
136
159
  ```ts
137
160
  import {
package/dist/compile.d.ts CHANGED
@@ -8,6 +8,13 @@ export type ParseMdxOptions = {
8
8
  components?: CompileMdxInput["components"];
9
9
  rehypePlugins?: CompilerMdxOptions["rehypePlugins"];
10
10
  remarkPlugins?: CompilerMdxOptions["remarkPlugins"];
11
+ /**
12
+ * Whether to parse frontmatter during MDX compilation.
13
+ * Set to `false` when frontmatter is already extracted separately
14
+ * (e.g. via gray-matter) to avoid redundant parsing.
15
+ * Defaults to `true`.
16
+ */
17
+ parseFrontmatter?: boolean;
11
18
  };
12
19
  export declare const handleCodeTitles: () => (tree: Node) => void;
13
20
  export declare const preProcess: () => (tree: Node) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../src/compile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAU,MAAM,OAAO,CAAC;AAO1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAkBhD,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjF,KAAK,iBAAiB,GAAG,WAAW,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;AACjE,KAAK,kBAAkB,GAAG,WAAW,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC;AAEvE,MAAM,MAAM,eAAe,GAAG;IAC1B,UAAU,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC3C,aAAa,CAAC,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACpD,aAAa,CAAC,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;CACvD,CAAC;AAEF,eAAO,MAAM,gBAAgB,SAAU,MAAM,IAAI,SAgChD,CAAC;AAEF,eAAO,MAAM,UAAU,SAAU,MAAM,IAAI,SAa1C,CAAC;AAEF,eAAO,MAAM,WAAW,SAAU,MAAM,IAAI,SAS3C,CAAC;AAEF,wBAAgB,0BAA0B,IAAI,OAAO,EAAE,CAUtD;AAED,wBAAgB,0BAA0B,IAAI,OAAO,EAAE,CAEtD;AAED,wBAAsB,QAAQ,CAAC,WAAW,EACtC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,eAAoB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAexC"}
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../src/compile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAU,MAAM,OAAO,CAAC;AAO1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAkBhD,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjF,KAAK,iBAAiB,GAAG,WAAW,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;AACjE,KAAK,kBAAkB,GAAG,WAAW,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC;AAEvE,MAAM,MAAM,eAAe,GAAG;IAC1B,UAAU,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC3C,aAAa,CAAC,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACpD,aAAa,CAAC,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACpD;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,SAAU,MAAM,IAAI,SAgChD,CAAC;AAEF,eAAO,MAAM,UAAU,SAAU,MAAM,IAAI,SAa1C,CAAC;AAEF,eAAO,MAAM,WAAW,SAAU,MAAM,IAAI,SAS3C,CAAC;AAEF,wBAAgB,0BAA0B,IAAI,OAAO,EAAE,CAUtD;AAED,wBAAgB,0BAA0B,IAAI,OAAO,EAAE,CAEtD;AAED,wBAAsB,QAAQ,CAAC,WAAW,EACtC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,eAAoB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAexC"}
package/dist/compile.js CHANGED
@@ -79,7 +79,7 @@ export async function parseMdx(rawMdx, options = {}) {
79
79
  return await compileMDX({
80
80
  source: rawMdx,
81
81
  options: {
82
- parseFrontmatter: true,
82
+ parseFrontmatter: options.parseFrontmatter ?? true,
83
83
  mdxOptions: {
84
84
  rehypePlugins,
85
85
  remarkPlugins,
@@ -1 +1 @@
1
- {"version":3,"file":"compile.js","sourceRoot":"","sources":["../src/compile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compile.js","sourceRoot":"","sources":["../src/compile.ts"],"names":[],"mappings":"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"}
package/dist/content.d.ts CHANGED
@@ -3,9 +3,13 @@ import type { MdxCompileResult, TocItem } from "./types";
3
3
  type CacheFn = <T extends (...args: any[]) => any>(fn: T) => T;
4
4
  export type ReadMdxFileResult = {
5
5
  content: string;
6
+ /** Relative path used for UI links (e.g. "docs/getting-started/index.mdx"). */
6
7
  filePath: string;
8
+ /** Absolute path on disk — available when file was read by readMdxFileBySlug. */
9
+ absoluteFilePath?: string;
7
10
  };
8
11
  export type ParsedMdxFile<Frontmatter, T extends TocItem = TocItem> = {
12
+ /** Raw content with frontmatter block stripped — ready to pass to compileMDX. */
9
13
  content: string;
10
14
  filePath: string;
11
15
  frontmatter: Frontmatter;
@@ -30,6 +34,13 @@ export type CreateMdxContentServiceOptions<Frontmatter, T extends TocItem = TocI
30
34
  readOptions?: ReadMdxBySlugOptions;
31
35
  tocsExtractor?: (rawMdx: string) => T[];
32
36
  cacheFn?: CacheFn;
37
+ /**
38
+ * Optional hook to enrich or transform frontmatter after parsing.
39
+ * Called with the parsed frontmatter and the absolute file path.
40
+ * Runs at build time during static generation — ideal for injecting
41
+ * fallback values (e.g. git last-modified date when `date` is absent).
42
+ */
43
+ frontmatterEnricher?: (frontmatter: Frontmatter, absoluteFilePath: string) => Frontmatter | Promise<Frontmatter>;
33
44
  };
34
45
  export declare function createMdxContentService<Frontmatter, T extends TocItem = TocItem>(options?: CreateMdxContentServiceOptions<Frontmatter, T>): {
35
46
  getParsedForSlug: (slug: string) => Promise<ParsedMdxFile<Frontmatter, T>>;
@@ -1 +1 @@
1
- {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzD,KAAK,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAE/D,MAAM,MAAM,iBAAiB,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,WAAW,EAAE,CAAC,SAAS,OAAO,GAAG,OAAO,IAAI;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,IAAI,EAAE,CAAC,EAAE,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,WAAW,EAAE,CAAC,SAAS,OAAO,GAAG,OAAO,IAAI,gBAAgB,CAAC,WAAW,CAAC,GAAG;IACpG,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,CAAC,EAAE,CAAC;CACb,CAAC;AAEF,KAAK,oBAAoB,GAAG;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAyBpH;AAED,KAAK,mBAAmB,CAAC,CAAC,SAAS,OAAO,IAAI;IAC1C,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC,EAAE,CAAC;CAC3C,CAAC;AAEF,wBAAgB,YAAY,CAAC,WAAW,EAAE,CAAC,SAAS,OAAO,GAAG,OAAO,EACjE,GAAG,EAAE,iBAAiB,EACtB,OAAO,GAAE,mBAAmB,CAAC,CAAC,CAAM,GACrC,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC,CAS/B;AAED,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,CAAC,SAAS,OAAO,GAAG,OAAO,EAC/E,MAAM,EAAE,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC,EACrC,OAAO,GAAE,eAAoB,GAC9B,OAAO,CAAC,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAS1C;AAED,MAAM,MAAM,8BAA8B,CAAC,WAAW,EAAE,CAAC,SAAS,OAAO,GAAG,OAAO,IAAI;IACnF,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC,EAAE,CAAC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,CAAC,SAAS,OAAO,GAAG,OAAO,EAC5E,OAAO,GAAE,8BAA8B,CAAC,WAAW,EAAE,CAAC,CAAM;6BAKd,MAAM,KAAG,OAAO,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;+BAK7C,MAAM,KAAG,OAAO,CAAC,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;kCAKtD,MAAM,KAAG,OAAO,CAAC,WAAW,CAAC;2BAKpC,MAAM,KAAG,OAAO,CAAC,CAAC,EAAE,CAAC;EAW5D"}
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"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"}
package/dist/content.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import path from "path";
2
2
  import { promises as fs } from "fs";
3
- import { extractFrontmatter, extractTocsFromRawMdx } from "./extract";
3
+ import { extractFrontmatterWithContent, extractTocsFromRawMdx } from "./extract";
4
4
  import { parseMdx } from "./compile";
5
5
  export async function readMdxFileBySlug(slug, options = {}) {
6
6
  const docsDir = options.docsDir ?? "docs";
@@ -9,35 +9,50 @@ export async function readMdxFileBySlug(slug, options = {}) {
9
9
  const docsRoot = options.rootDir
10
10
  ? path.join(/*turbopackIgnore: true*/ options.rootDir, docsDir)
11
11
  : path.join(/*turbopackIgnore: true*/ process.cwd(), docsDir);
12
+ // Resolve once for path-traversal guard — all candidate paths must stay
13
+ // inside docsRoot. This prevents "../../etc/passwd" style slugs from
14
+ // escaping the docs directory, especially important with dynamicParams=true.
15
+ const resolvedRoot = path.resolve(/*turbopackIgnore: true*/ docsRoot);
12
16
  const paths = [
13
17
  path.join(/*turbopackIgnore: true*/ docsRoot, `${slug}.mdx`),
14
18
  path.join(/*turbopackIgnore: true*/ docsRoot, slug, "index.mdx"),
15
19
  ];
16
20
  for (const p of paths) {
21
+ // Guard: reject any path that escapes the docs root.
22
+ const resolvedP = path.resolve(/*turbopackIgnore: true*/ p);
23
+ if (!resolvedP.startsWith(resolvedRoot + path.sep) && resolvedP !== resolvedRoot) {
24
+ continue;
25
+ }
17
26
  try {
18
27
  const content = await fs.readFile(/*turbopackIgnore: true*/ p, "utf-8");
19
28
  return {
20
29
  content,
21
30
  filePath: `${docsDir}/${path.relative(/*turbopackIgnore: true*/ docsRoot, p)}`,
31
+ absoluteFilePath: p,
22
32
  };
23
33
  }
24
34
  catch {
25
35
  // ignore and try next candidate
26
36
  }
27
37
  }
28
- throw new Error(`Could not find mdx file for slug: ${slug}`);
38
+ throw new Error("Could not find mdx file for the requested slug.");
29
39
  }
30
40
  export function parseMdxFile(raw, options = {}) {
31
41
  const tocsExtractor = options.tocsExtractor ?? ((mdx) => extractTocsFromRawMdx(mdx));
42
+ // Extract frontmatter and stripped content in one gray-matter call.
43
+ // strippedContent is passed to compileMDX so it doesn't need to re-parse frontmatter.
44
+ const { frontmatter, strippedContent } = extractFrontmatterWithContent(raw.content);
32
45
  return {
33
- content: raw.content,
46
+ content: strippedContent,
34
47
  filePath: raw.filePath,
35
- frontmatter: extractFrontmatter(raw.content),
48
+ frontmatter,
36
49
  tocs: tocsExtractor(raw.content),
37
50
  };
38
51
  }
39
52
  export async function compileParsedMdxFile(parsed, options = {}) {
40
- const compiled = await parseMdx(parsed.content, options);
53
+ // Content in parsed is already stripped of frontmatter by parseMdxFile.
54
+ // Set parseFrontmatter:false — no re-parse needed, avoids double work.
55
+ const compiled = await parseMdx(parsed.content, { ...options, parseFrontmatter: false });
41
56
  return {
42
57
  ...compiled,
43
58
  frontmatter: parsed.frontmatter,
@@ -50,7 +65,11 @@ export function createMdxContentService(options = {}) {
50
65
  const cacheFn = options.cacheFn ?? identityCache;
51
66
  const getParsedForSlug = cacheFn(async (slug) => {
52
67
  const raw = await readMdxFileBySlug(slug, options.readOptions);
53
- return parseMdxFile(raw, { tocsExtractor: options.tocsExtractor });
68
+ const parsed = parseMdxFile(raw, { tocsExtractor: options.tocsExtractor });
69
+ if (options.frontmatterEnricher && raw.absoluteFilePath) {
70
+ parsed.frontmatter = await options.frontmatterEnricher(parsed.frontmatter, raw.absoluteFilePath);
71
+ }
72
+ return parsed;
54
73
  });
55
74
  const getCompiledForSlug = cacheFn(async (slug) => {
56
75
  const parsed = await getParsedForSlug(slug);
@@ -1 +1 @@
1
- {"version":3,"file":"content.js","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"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"}
package/dist/extract.d.ts CHANGED
@@ -2,4 +2,12 @@ import type { TocItem } from "./types";
2
2
  export declare function sluggify(text: string): string;
3
3
  export declare function extractTocsFromRawMdx(rawMdx: string): TocItem[];
4
4
  export declare function extractFrontmatter<Frontmatter>(content: string): Frontmatter;
5
+ /**
6
+ * Extract frontmatter and return both the parsed data and the content
7
+ * with the frontmatter block stripped. Avoids a second parse by compileMDX.
8
+ */
9
+ export declare function extractFrontmatterWithContent<Frontmatter>(content: string): {
10
+ frontmatter: Frontmatter;
11
+ strippedContent: string;
12
+ };
5
13
  //# sourceMappingURL=extract.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CA+B/D;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,CAE5E"}
1
+ {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CA+B/D;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,CAE5E;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG;IACzE,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CAC3B,CAGA"}
package/dist/extract.js CHANGED
@@ -5,7 +5,7 @@ export function sluggify(text) {
5
5
  }
6
6
  export function extractTocsFromRawMdx(rawMdx) {
7
7
  // Match code blocks, markdown headings, and <Release version="x.y.z" />.
8
- const combinedRegex = /(```[\s\S]*?```)|^(#{2,4})\s(.+)$|<Release[^>]*version="([^"]+)"/gm;
8
+ const combinedRegex = /(```[\s\S]*?```)|^(#{2,4})\s(.+)$|<Release\s+version="([^"]+)"/gm;
9
9
  const extractedHeadings = [];
10
10
  let match;
11
11
  while ((match = combinedRegex.exec(rawMdx)) !== null) {
@@ -35,4 +35,12 @@ export function extractTocsFromRawMdx(rawMdx) {
35
35
  export function extractFrontmatter(content) {
36
36
  return matter(content).data;
37
37
  }
38
+ /**
39
+ * Extract frontmatter and return both the parsed data and the content
40
+ * with the frontmatter block stripped. Avoids a second parse by compileMDX.
41
+ */
42
+ export function extractFrontmatterWithContent(content) {
43
+ const { data, content: strippedContent } = matter(content);
44
+ return { frontmatter: data, strippedContent };
45
+ }
38
46
  //# sourceMappingURL=extract.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,MAAM,UAAU,QAAQ,CAAC,IAAY;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrD,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAChD,yEAAyE;IACzE,MAAM,aAAa,GAAG,oEAAoE,CAAC;IAC3F,MAAM,iBAAiB,GAAc,EAAE,CAAC;IAExC,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACnD,IAAI,KAAK,CAAC,CAAC,CAAC;YAAE,SAAS;QAEvB,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACX,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACrC,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACpC,iBAAiB,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,IAAI,QAAQ,CAAC,WAAW,CAAC,EAAE;aACpC,CAAC,CAAC;YACH,SAAS;QACb,CAAC;QAED,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACX,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,iBAAiB,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,CAAC;gBACR,IAAI,EAAE,IAAI,OAAO,EAAE;gBACnB,IAAI,EAAE,IAAI,OAAO,EAAE;aACtB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,OAAO,iBAAiB,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAc,OAAe;IAC3D,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,IAAmB,CAAC;AAC/C,CAAC"}
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,MAAM,UAAU,QAAQ,CAAC,IAAY;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrD,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAChD,yEAAyE;IACzE,MAAM,aAAa,GAAG,kEAAkE,CAAC;IACzF,MAAM,iBAAiB,GAAc,EAAE,CAAC;IAExC,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACnD,IAAI,KAAK,CAAC,CAAC,CAAC;YAAE,SAAS;QAEvB,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACX,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACrC,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACpC,iBAAiB,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,IAAI,QAAQ,CAAC,WAAW,CAAC,EAAE;aACpC,CAAC,CAAC;YACH,SAAS;QACb,CAAC;QAED,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACX,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,iBAAiB,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,CAAC;gBACR,IAAI,EAAE,IAAI,OAAO,EAAE;gBACnB,IAAI,EAAE,IAAI,OAAO,EAAE;aACtB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,OAAO,iBAAiB,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAc,OAAe;IAC3D,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,IAAmB,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,6BAA6B,CAAc,OAAe;IAItE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3D,OAAO,EAAE,WAAW,EAAE,IAAmB,EAAE,eAAe,EAAE,CAAC;AACjE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export type { TocItem, MdxCompileResult } from "./types";
2
2
  export { parseMdx, preProcess, postProcess, handleCodeTitles, createDefaultRehypePlugins, createDefaultRemarkPlugins, } from "./compile";
3
- export { extractFrontmatter, extractTocsFromRawMdx, sluggify } from "./extract";
3
+ export { extractFrontmatter, extractFrontmatterWithContent, extractTocsFromRawMdx, sluggify } from "./extract";
4
4
  export type { ParseMdxOptions } from "./compile";
5
5
  export { readMdxFileBySlug, parseMdxFile, compileParsedMdxFile, createMdxContentService, } from "./content";
6
6
  export type { ReadMdxFileResult, ParsedMdxFile, CompiledMdxFile, CreateMdxContentServiceOptions, } from "./content";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,EACH,QAAQ,EACR,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,0BAA0B,EAC1B,0BAA0B,GAC7B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAChF,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EACH,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,uBAAuB,GAC1B,MAAM,WAAW,CAAC;AACnB,YAAY,EACR,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,8BAA8B,GACjC,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,EACH,QAAQ,EACR,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,0BAA0B,EAC1B,0BAA0B,GAC7B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC/G,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EACH,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,uBAAuB,GAC1B,MAAM,WAAW,CAAC;AACnB,YAAY,EACR,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,8BAA8B,GACjC,MAAM,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { parseMdx, preProcess, postProcess, handleCodeTitles, createDefaultRehypePlugins, createDefaultRemarkPlugins, } from "./compile";
2
- export { extractFrontmatter, extractTocsFromRawMdx, sluggify } from "./extract";
2
+ export { extractFrontmatter, extractFrontmatterWithContent, extractTocsFromRawMdx, sluggify } from "./extract";
3
3
  export { readMdxFileBySlug, parseMdxFile, compileParsedMdxFile, createMdxContentService, } from "./content";
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACH,QAAQ,EACR,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,0BAA0B,EAC1B,0BAA0B,GAC7B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEhF,OAAO,EACH,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,uBAAuB,GAC1B,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACH,QAAQ,EACR,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,0BAA0B,EAC1B,0BAA0B,GAC7B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE/G,OAAO,EACH,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,uBAAuB,GAC1B,MAAM,WAAW,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docubook/core",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Shared MDX compile pipeline and markdown utilities for DocuBook",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -30,7 +30,10 @@
30
30
  "homepage": "https://docubook.pro/",
31
31
  "repository": {
32
32
  "type": "git",
33
- "url": "git+https://github.com/DocuBook/docubook"
33
+ "url": "git+https://github.com/DocuBook/docubook.git"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
34
37
  },
35
38
  "author": "wildan.nrs",
36
39
  "author-url": "https://wildan.dev",