@kubb/parser-md 5.0.0-beta.25

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 ADDED
@@ -0,0 +1,92 @@
1
+ <div align="center">
2
+ <h1>@kubb/parser-md</h1>
3
+ <a href="https://kubb.dev" target="_blank" rel="noopener noreferrer">
4
+ <img width="180" src="https://raw.githubusercontent.com/kubb-labs/kubb/main/assets/logo.png" alt="Kubb logo">
5
+ </a>
6
+
7
+ [![npm version][npm-version-src]][npm-version-href]
8
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
9
+ [![Coverage][coverage-src]][coverage-href]
10
+ [![License][license-src]][license-href]
11
+ [![Sponsors][sponsors-src]][sponsors-href]
12
+
13
+ <h4>
14
+ <a href="https://kubb.dev/" target="_blank">Documentation</a>
15
+ <span> · </span>
16
+ <a href="https://github.com/kubb-labs/kubb/issues/" target="_blank">Report Bug</a>
17
+ <span> · </span>
18
+ <a href="https://github.com/kubb-labs/kubb/issues/" target="_blank">Request Feature</a>
19
+ </h4>
20
+ </div>
21
+
22
+ Markdown source file parser for Kubb. Joins source blocks as plain markdown and renders YAML frontmatter via `parserMd.print`.
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ bun add @kubb/parser-md
28
+ # or
29
+ pnpm add @kubb/parser-md
30
+ # or
31
+ npm install @kubb/parser-md
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ```typescript
37
+ import { defineConfig } from 'kubb'
38
+ import { parserMd } from '@kubb/parser-md'
39
+ import { parserTs } from '@kubb/parser-ts'
40
+
41
+ export default defineConfig({
42
+ input: { path: './petstore.yaml' },
43
+ output: { path: './src/gen' },
44
+ parsers: [parserTs, parserMd],
45
+ })
46
+ ```
47
+
48
+ To convert a metadata object into a YAML frontmatter envelope from inside a plugin, call `print` on the parser instance:
49
+
50
+ ```typescript
51
+ import { parserMd } from '@kubb/parser-md'
52
+
53
+ const source = parserMd.print({ title: 'Pets', layout: 'doc' })
54
+ // → ---
55
+ // title: Pets
56
+ // layout: doc
57
+ // ---
58
+ ```
59
+
60
+ ## API
61
+
62
+ ### `parserMd`
63
+
64
+ Parser instance for `.md` and `.markdown` files. Pass to `defineConfig({ parsers: [...] })` to emit Markdown source files.
65
+
66
+ - `parserMd.parse(file)` — serialise a `FileNode` to Markdown source. When `file.meta.frontmatter` is set, the parser prepends the corresponding YAML envelope.
67
+ - `parserMd.print(...parts)` — join markdown fragments separated by blank lines. Plain objects are serialised as YAML frontmatter; strings pass through unchanged.
68
+
69
+ ## Supporting Kubb
70
+
71
+ Kubb is an open source project with its ongoing development made possible entirely by the support of Sponsors. If you would like to become a sponsor, please consider:
72
+
73
+ - [Become a Sponsor on GitHub](https://github.com/sponsors/stijnvanhulle)
74
+
75
+ <p align="center">
76
+ <a href="https://github.com/sponsors/stijnvanhulle">
77
+ <img src="https://raw.githubusercontent.com/stijnvanhulle/sponsors/main/sponsors.svg" alt="My sponsors" />
78
+ </a>
79
+ </p>
80
+
81
+ <!-- Badges -->
82
+
83
+ [npm-version-src]: https://img.shields.io/npm/v/@kubb/parser-md?flat&colorA=18181B&colorB=f58517
84
+ [npm-version-href]: https://npmjs.com/package/@kubb/parser-md
85
+ [npm-downloads-src]: https://img.shields.io/npm/dm/@kubb/parser-md?flat&colorA=18181B&colorB=f58517
86
+ [npm-downloads-href]: https://npmjs.com/package/@kubb/parser-md
87
+ [license-src]: https://img.shields.io/github/license/kubb-labs/kubb.svg?flat&colorA=18181B&colorB=f58517
88
+ [license-href]: https://github.com/kubb-labs/kubb/blob/main/LICENSE
89
+ [coverage-src]: https://img.shields.io/codecov/c/github/kubb-labs/kubb?style=flat&colorA=18181B&colorB=f58517
90
+ [coverage-href]: https://www.npmjs.com/package/@kubb/parser-md
91
+ [sponsors-src]: https://img.shields.io/github/sponsors/stijnvanhulle?style=flat&colorA=18181B&colorB=f58517
92
+ [sponsors-href]: https://github.com/sponsors/stijnvanhulle/
@@ -0,0 +1,8 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __name = (target, value) => __defProp(target, "name", {
4
+ value,
5
+ configurable: true
6
+ });
7
+ //#endregion
8
+ export { __name as t };
package/dist/index.cjs ADDED
@@ -0,0 +1,94 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#endregion
3
+ let _kubb_ast = require("@kubb/ast");
4
+ let _kubb_core = require("@kubb/core");
5
+ let yaml = require("yaml");
6
+ //#region src/utils.ts
7
+ /**
8
+ * Wraps a plain object as a YAML frontmatter envelope:
9
+ *
10
+ * ```
11
+ * ---
12
+ * <yaml>
13
+ * ---
14
+ * ```
15
+ *
16
+ * Returns an empty string for `null`, `undefined`, or empty objects so callers
17
+ * can drop the result through the same filter chain as banner/footer fields.
18
+ */
19
+ function printFrontmatter(data) {
20
+ if (!data || Object.keys(data).length === 0) return "";
21
+ return `---\n${(0, yaml.stringify)(data).trimEnd()}\n---`;
22
+ }
23
+ /**
24
+ * Joins a list of markdown fragments with blank lines. Plain objects are
25
+ * rendered as YAML frontmatter via {@link printFrontmatter}; strings pass
26
+ * through unchanged.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * print({ title: 'Hi' }, '# Hello')
31
+ * // '---\ntitle: Hi\n---\n\n# Hello'
32
+ * ```
33
+ */
34
+ function print(...parts) {
35
+ const rendered = [];
36
+ for (const part of parts) {
37
+ if (part === null || part === void 0 || part === "") continue;
38
+ const text = typeof part === "string" ? part : printFrontmatter(part);
39
+ if (text) rendered.push(text.trimEnd());
40
+ }
41
+ return rendered.join("\n\n");
42
+ }
43
+ //#endregion
44
+ //#region src/parserMd.ts
45
+ /**
46
+ * Kubb parser for `.md` and `.markdown` files. Joins source blocks as plain
47
+ * markdown (separated by blank lines) and, when `file.meta.frontmatter` is set,
48
+ * prepends a YAML frontmatter envelope produced by `parserMd.print`.
49
+ *
50
+ * Add to the `parsers` array on `defineConfig` to opt in. `parserTs` keeps
51
+ * handling `.ts`/`.js` files, `parserMd` claims `.md`/`.markdown`.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * import { defineConfig } from 'kubb'
56
+ * import { adapterOas } from '@kubb/adapter-oas'
57
+ * import { parserMd } from '@kubb/parser-md'
58
+ *
59
+ * export default defineConfig({
60
+ * input: { path: './petStore.yaml' },
61
+ * output: { path: './src/gen' },
62
+ * adapter: adapterOas(),
63
+ * parsers: [parserMd],
64
+ * plugins: [],
65
+ * })
66
+ * ```
67
+ */
68
+ const parserMd = (0, _kubb_core.defineParser)({
69
+ name: "markdown",
70
+ extNames: [".md", ".markdown"],
71
+ print(...parts) {
72
+ return print(...parts);
73
+ },
74
+ parse(file) {
75
+ const sourceParts = [];
76
+ for (const source of file.sources) {
77
+ const text = (0, _kubb_ast.extractStringsFromNodes)(source.nodes);
78
+ if (text) sourceParts.push(text.trimEnd());
79
+ }
80
+ const body = sourceParts.join("\n\n");
81
+ const meta = file.meta;
82
+ const frontmatter = print(meta?.frontmatter ?? void 0);
83
+ return [
84
+ file.banner,
85
+ frontmatter,
86
+ body,
87
+ file.footer
88
+ ].filter((segment) => Boolean(segment)).map((segment) => segment.trimEnd()).join("\n\n");
89
+ }
90
+ });
91
+ //#endregion
92
+ exports.parserMd = parserMd;
93
+
94
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/utils.ts","../src/parserMd.ts"],"sourcesContent":["import { stringify } from 'yaml'\n\n/**\n * Markdown `print` input — either a markdown text fragment (passed through\n * verbatim) or a plain object that is serialised as a YAML frontmatter envelope.\n */\nexport type PrintInput = string | Record<string, unknown>\n\n/**\n * Wraps a plain object as a YAML frontmatter envelope:\n *\n * ```\n * ---\n * <yaml>\n * ---\n * ```\n *\n * Returns an empty string for `null`, `undefined`, or empty objects so callers\n * can drop the result through the same filter chain as banner/footer fields.\n */\nexport function printFrontmatter(data: Record<string, unknown> | null | undefined): string {\n if (!data || Object.keys(data).length === 0) return ''\n return `---\\n${stringify(data).trimEnd()}\\n---`\n}\n\n/**\n * Joins a list of markdown fragments with blank lines. Plain objects are\n * rendered as YAML frontmatter via {@link printFrontmatter}; strings pass\n * through unchanged.\n *\n * @example\n * ```ts\n * print({ title: 'Hi' }, '# Hello')\n * // '---\\ntitle: Hi\\n---\\n\\n# Hello'\n * ```\n */\nexport function print(...parts: Array<PrintInput | null | undefined>): string {\n const rendered: string[] = []\n for (const part of parts) {\n if (part === null || part === undefined || part === '') continue\n const text = typeof part === 'string' ? part : printFrontmatter(part)\n if (text) rendered.push(text.trimEnd())\n }\n return rendered.join('\\n\\n')\n}\n","import type { CodeNode } from '@kubb/ast'\nimport { extractStringsFromNodes } from '@kubb/ast'\nimport { defineParser } from '@kubb/core'\nimport { print, type PrintInput } from './utils.ts'\n\n/**\n * Metadata accepted by `parserMd`. Set `frontmatter` on a `<File meta={…}>` to\n * have the parser prepend the corresponding YAML envelope.\n */\nexport type MdMeta = {\n frontmatter?: Record<string, unknown> | null\n}\n\n/**\n * Kubb parser for `.md` and `.markdown` files. Joins source blocks as plain\n * markdown (separated by blank lines) and, when `file.meta.frontmatter` is set,\n * prepends a YAML frontmatter envelope produced by `parserMd.print`.\n *\n * Add to the `parsers` array on `defineConfig` to opt in. `parserTs` keeps\n * handling `.ts`/`.js` files, `parserMd` claims `.md`/`.markdown`.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { adapterOas } from '@kubb/adapter-oas'\n * import { parserMd } from '@kubb/parser-md'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserMd],\n * plugins: [],\n * })\n * ```\n */\nexport const parserMd = defineParser({\n name: 'markdown',\n extNames: ['.md', '.markdown'],\n print(...parts: PrintInput[]) {\n return print(...parts)\n },\n parse(file) {\n const sourceParts: string[] = []\n for (const source of file.sources) {\n const text = extractStringsFromNodes(source.nodes as Array<CodeNode>)\n if (text) sourceParts.push(text.trimEnd())\n }\n const body = sourceParts.join('\\n\\n')\n\n const meta = file.meta as MdMeta | undefined\n const frontmatter = print(meta?.frontmatter ?? undefined)\n\n const parts = [file.banner, frontmatter, body, file.footer].filter((segment): segment is string => Boolean(segment)).map((segment) => segment.trimEnd())\n return parts.join('\\n\\n')\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;AAoBA,SAAgB,iBAAiB,MAA0D;CACzF,IAAI,CAAC,QAAQ,OAAO,KAAK,KAAK,CAAC,WAAW,GAAG,OAAO;CACpD,OAAO,SAAA,GAAA,KAAA,WAAkB,KAAK,CAAC,SAAS,CAAC;;;;;;;;;;;;;AAc3C,SAAgB,MAAM,GAAG,OAAqD;CAC5E,MAAM,WAAqB,EAAE;CAC7B,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,SAAS,QAAQ,SAAS,KAAA,KAAa,SAAS,IAAI;EACxD,MAAM,OAAO,OAAO,SAAS,WAAW,OAAO,iBAAiB,KAAK;EACrE,IAAI,MAAM,SAAS,KAAK,KAAK,SAAS,CAAC;;CAEzC,OAAO,SAAS,KAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;ACP9B,MAAa,YAAA,GAAA,WAAA,cAAwB;CACnC,MAAM;CACN,UAAU,CAAC,OAAO,YAAY;CAC9B,MAAM,GAAG,OAAqB;EAC5B,OAAO,MAAM,GAAG,MAAM;;CAExB,MAAM,MAAM;EACV,MAAM,cAAwB,EAAE;EAChC,KAAK,MAAM,UAAU,KAAK,SAAS;GACjC,MAAM,QAAA,GAAA,UAAA,yBAA+B,OAAO,MAAyB;GACrE,IAAI,MAAM,YAAY,KAAK,KAAK,SAAS,CAAC;;EAE5C,MAAM,OAAO,YAAY,KAAK,OAAO;EAErC,MAAM,OAAO,KAAK;EAClB,MAAM,cAAc,MAAM,MAAM,eAAe,KAAA,EAAU;EAGzD,OADc;GAAC,KAAK;GAAQ;GAAa;GAAM,KAAK;GAAO,CAAC,QAAQ,YAA+B,QAAQ,QAAQ,CAAC,CAAC,KAAK,YAAY,QAAQ,SAAS,CAC3I,CAAC,KAAK,OAAO;;CAE5B,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { t as __name } from "./chunk--u3MIqq1.js";
2
+ import * as _$_kubb_core0 from "@kubb/core";
3
+
4
+ //#region src/parserMd.d.ts
5
+ /**
6
+ * Metadata accepted by `parserMd`. Set `frontmatter` on a `<File meta={…}>` to
7
+ * have the parser prepend the corresponding YAML envelope.
8
+ */
9
+ type MdMeta = {
10
+ frontmatter?: Record<string, unknown> | null;
11
+ };
12
+ /**
13
+ * Kubb parser for `.md` and `.markdown` files. Joins source blocks as plain
14
+ * markdown (separated by blank lines) and, when `file.meta.frontmatter` is set,
15
+ * prepends a YAML frontmatter envelope produced by `parserMd.print`.
16
+ *
17
+ * Add to the `parsers` array on `defineConfig` to opt in. `parserTs` keeps
18
+ * handling `.ts`/`.js` files, `parserMd` claims `.md`/`.markdown`.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { defineConfig } from 'kubb'
23
+ * import { adapterOas } from '@kubb/adapter-oas'
24
+ * import { parserMd } from '@kubb/parser-md'
25
+ *
26
+ * export default defineConfig({
27
+ * input: { path: './petStore.yaml' },
28
+ * output: { path: './src/gen' },
29
+ * adapter: adapterOas(),
30
+ * parsers: [parserMd],
31
+ * plugins: [],
32
+ * })
33
+ * ```
34
+ */
35
+ declare const parserMd: _$_kubb_core0.Parser<any>;
36
+ //#endregion
37
+ export { type MdMeta, parserMd };
38
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,93 @@
1
+ import "./chunk--u3MIqq1.js";
2
+ import { extractStringsFromNodes } from "@kubb/ast";
3
+ import { defineParser } from "@kubb/core";
4
+ import { stringify } from "yaml";
5
+ //#region src/utils.ts
6
+ /**
7
+ * Wraps a plain object as a YAML frontmatter envelope:
8
+ *
9
+ * ```
10
+ * ---
11
+ * <yaml>
12
+ * ---
13
+ * ```
14
+ *
15
+ * Returns an empty string for `null`, `undefined`, or empty objects so callers
16
+ * can drop the result through the same filter chain as banner/footer fields.
17
+ */
18
+ function printFrontmatter(data) {
19
+ if (!data || Object.keys(data).length === 0) return "";
20
+ return `---\n${stringify(data).trimEnd()}\n---`;
21
+ }
22
+ /**
23
+ * Joins a list of markdown fragments with blank lines. Plain objects are
24
+ * rendered as YAML frontmatter via {@link printFrontmatter}; strings pass
25
+ * through unchanged.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * print({ title: 'Hi' }, '# Hello')
30
+ * // '---\ntitle: Hi\n---\n\n# Hello'
31
+ * ```
32
+ */
33
+ function print(...parts) {
34
+ const rendered = [];
35
+ for (const part of parts) {
36
+ if (part === null || part === void 0 || part === "") continue;
37
+ const text = typeof part === "string" ? part : printFrontmatter(part);
38
+ if (text) rendered.push(text.trimEnd());
39
+ }
40
+ return rendered.join("\n\n");
41
+ }
42
+ //#endregion
43
+ //#region src/parserMd.ts
44
+ /**
45
+ * Kubb parser for `.md` and `.markdown` files. Joins source blocks as plain
46
+ * markdown (separated by blank lines) and, when `file.meta.frontmatter` is set,
47
+ * prepends a YAML frontmatter envelope produced by `parserMd.print`.
48
+ *
49
+ * Add to the `parsers` array on `defineConfig` to opt in. `parserTs` keeps
50
+ * handling `.ts`/`.js` files, `parserMd` claims `.md`/`.markdown`.
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * import { defineConfig } from 'kubb'
55
+ * import { adapterOas } from '@kubb/adapter-oas'
56
+ * import { parserMd } from '@kubb/parser-md'
57
+ *
58
+ * export default defineConfig({
59
+ * input: { path: './petStore.yaml' },
60
+ * output: { path: './src/gen' },
61
+ * adapter: adapterOas(),
62
+ * parsers: [parserMd],
63
+ * plugins: [],
64
+ * })
65
+ * ```
66
+ */
67
+ const parserMd = defineParser({
68
+ name: "markdown",
69
+ extNames: [".md", ".markdown"],
70
+ print(...parts) {
71
+ return print(...parts);
72
+ },
73
+ parse(file) {
74
+ const sourceParts = [];
75
+ for (const source of file.sources) {
76
+ const text = extractStringsFromNodes(source.nodes);
77
+ if (text) sourceParts.push(text.trimEnd());
78
+ }
79
+ const body = sourceParts.join("\n\n");
80
+ const meta = file.meta;
81
+ const frontmatter = print(meta?.frontmatter ?? void 0);
82
+ return [
83
+ file.banner,
84
+ frontmatter,
85
+ body,
86
+ file.footer
87
+ ].filter((segment) => Boolean(segment)).map((segment) => segment.trimEnd()).join("\n\n");
88
+ }
89
+ });
90
+ //#endregion
91
+ export { parserMd };
92
+
93
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/utils.ts","../src/parserMd.ts"],"sourcesContent":["import { stringify } from 'yaml'\n\n/**\n * Markdown `print` input — either a markdown text fragment (passed through\n * verbatim) or a plain object that is serialised as a YAML frontmatter envelope.\n */\nexport type PrintInput = string | Record<string, unknown>\n\n/**\n * Wraps a plain object as a YAML frontmatter envelope:\n *\n * ```\n * ---\n * <yaml>\n * ---\n * ```\n *\n * Returns an empty string for `null`, `undefined`, or empty objects so callers\n * can drop the result through the same filter chain as banner/footer fields.\n */\nexport function printFrontmatter(data: Record<string, unknown> | null | undefined): string {\n if (!data || Object.keys(data).length === 0) return ''\n return `---\\n${stringify(data).trimEnd()}\\n---`\n}\n\n/**\n * Joins a list of markdown fragments with blank lines. Plain objects are\n * rendered as YAML frontmatter via {@link printFrontmatter}; strings pass\n * through unchanged.\n *\n * @example\n * ```ts\n * print({ title: 'Hi' }, '# Hello')\n * // '---\\ntitle: Hi\\n---\\n\\n# Hello'\n * ```\n */\nexport function print(...parts: Array<PrintInput | null | undefined>): string {\n const rendered: string[] = []\n for (const part of parts) {\n if (part === null || part === undefined || part === '') continue\n const text = typeof part === 'string' ? part : printFrontmatter(part)\n if (text) rendered.push(text.trimEnd())\n }\n return rendered.join('\\n\\n')\n}\n","import type { CodeNode } from '@kubb/ast'\nimport { extractStringsFromNodes } from '@kubb/ast'\nimport { defineParser } from '@kubb/core'\nimport { print, type PrintInput } from './utils.ts'\n\n/**\n * Metadata accepted by `parserMd`. Set `frontmatter` on a `<File meta={…}>` to\n * have the parser prepend the corresponding YAML envelope.\n */\nexport type MdMeta = {\n frontmatter?: Record<string, unknown> | null\n}\n\n/**\n * Kubb parser for `.md` and `.markdown` files. Joins source blocks as plain\n * markdown (separated by blank lines) and, when `file.meta.frontmatter` is set,\n * prepends a YAML frontmatter envelope produced by `parserMd.print`.\n *\n * Add to the `parsers` array on `defineConfig` to opt in. `parserTs` keeps\n * handling `.ts`/`.js` files, `parserMd` claims `.md`/`.markdown`.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { adapterOas } from '@kubb/adapter-oas'\n * import { parserMd } from '@kubb/parser-md'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserMd],\n * plugins: [],\n * })\n * ```\n */\nexport const parserMd = defineParser({\n name: 'markdown',\n extNames: ['.md', '.markdown'],\n print(...parts: PrintInput[]) {\n return print(...parts)\n },\n parse(file) {\n const sourceParts: string[] = []\n for (const source of file.sources) {\n const text = extractStringsFromNodes(source.nodes as Array<CodeNode>)\n if (text) sourceParts.push(text.trimEnd())\n }\n const body = sourceParts.join('\\n\\n')\n\n const meta = file.meta as MdMeta | undefined\n const frontmatter = print(meta?.frontmatter ?? undefined)\n\n const parts = [file.banner, frontmatter, body, file.footer].filter((segment): segment is string => Boolean(segment)).map((segment) => segment.trimEnd())\n return parts.join('\\n\\n')\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;AAoBA,SAAgB,iBAAiB,MAA0D;CACzF,IAAI,CAAC,QAAQ,OAAO,KAAK,KAAK,CAAC,WAAW,GAAG,OAAO;CACpD,OAAO,QAAQ,UAAU,KAAK,CAAC,SAAS,CAAC;;;;;;;;;;;;;AAc3C,SAAgB,MAAM,GAAG,OAAqD;CAC5E,MAAM,WAAqB,EAAE;CAC7B,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,SAAS,QAAQ,SAAS,KAAA,KAAa,SAAS,IAAI;EACxD,MAAM,OAAO,OAAO,SAAS,WAAW,OAAO,iBAAiB,KAAK;EACrE,IAAI,MAAM,SAAS,KAAK,KAAK,SAAS,CAAC;;CAEzC,OAAO,SAAS,KAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;ACP9B,MAAa,WAAW,aAAa;CACnC,MAAM;CACN,UAAU,CAAC,OAAO,YAAY;CAC9B,MAAM,GAAG,OAAqB;EAC5B,OAAO,MAAM,GAAG,MAAM;;CAExB,MAAM,MAAM;EACV,MAAM,cAAwB,EAAE;EAChC,KAAK,MAAM,UAAU,KAAK,SAAS;GACjC,MAAM,OAAO,wBAAwB,OAAO,MAAyB;GACrE,IAAI,MAAM,YAAY,KAAK,KAAK,SAAS,CAAC;;EAE5C,MAAM,OAAO,YAAY,KAAK,OAAO;EAErC,MAAM,OAAO,KAAK;EAClB,MAAM,cAAc,MAAM,MAAM,eAAe,KAAA,EAAU;EAGzD,OADc;GAAC,KAAK;GAAQ;GAAa;GAAM,KAAK;GAAO,CAAC,QAAQ,YAA+B,QAAQ,QAAQ,CAAC,CAAC,KAAK,YAAY,QAAQ,SAAS,CAC3I,CAAC,KAAK,OAAO;;CAE5B,CAAC"}
package/extension.yaml ADDED
@@ -0,0 +1,74 @@
1
+ $schema: https://kubb.dev/schemas/extension.json
2
+ kind: parser
3
+ id: parser-md
4
+ name: Markdown
5
+ description: Markdown file parser for Kubb. Joins source blocks as plain markdown and renders YAML frontmatter via `parserMd.print`.
6
+ category: docs
7
+ type: official
8
+ npmPackage: '@kubb/parser-md'
9
+ docsPath: /parsers/parser-md
10
+ repo: https://github.com/kubb-labs/kubb
11
+ maintainers:
12
+ - name: Stijn Van Hulle
13
+ github: stijnvanhulle
14
+ compatibility:
15
+ kubb: '>=5.0.0'
16
+ node: '>=22'
17
+ tags:
18
+ - markdown
19
+ - frontmatter
20
+ - parser
21
+ - docs
22
+ - yaml
23
+ resources:
24
+ documentation: https://kubb.dev/parsers/parser-md
25
+ repository: https://github.com/kubb-labs/kubb
26
+ issues: https://github.com/kubb-labs/kubb/issues
27
+ changelog: https://github.com/kubb-labs/kubb/blob/main/packages/parser-md/CHANGELOG.md
28
+ featured: false
29
+ intro: |-
30
+ `@kubb/parser-md` emits `.md` and `.markdown` files. Source blocks pass through as plain markdown, joined by blank lines. Call `parserMd.print` on the parser instance to convert a metadata object into a YAML frontmatter envelope (`---\n…\n---`).
31
+
32
+ Use it when a plugin needs to generate documentation alongside the TypeScript output — README sections, changelog excerpts, MDX-flavoured pages — without hand-rolling a frontmatter string builder.
33
+
34
+ Configure on `defineConfig({ parsers: [parserMd] })`. The parser claims `.md` and `.markdown`; pair it with `parserTs` so the same generator can emit both `.ts` and `.md` files in a single run.
35
+ examples:
36
+ - name: Standalone markdown
37
+ files:
38
+ - name: kubb.config.ts
39
+ lang: typescript
40
+ twoslash: false
41
+ code: |-
42
+ import { defineConfig } from 'kubb'
43
+ import { adapterOas } from '@kubb/adapter-oas'
44
+ import { parserMd } from '@kubb/parser-md'
45
+
46
+ export default defineConfig({
47
+ input: { path: './petStore.yaml' },
48
+ output: { path: './src/gen' },
49
+ adapter: adapterOas(),
50
+ parsers: [parserMd],
51
+ plugins: [],
52
+ })
53
+ - name: Markdown alongside TypeScript
54
+ files:
55
+ - name: kubb.config.ts
56
+ lang: typescript
57
+ twoslash: false
58
+ code: |-
59
+ import { defineConfig } from 'kubb'
60
+ import { adapterOas } from '@kubb/adapter-oas'
61
+ import { parserMd } from '@kubb/parser-md'
62
+ import { parserTs } from '@kubb/parser-ts'
63
+
64
+ export default defineConfig({
65
+ input: { path: './petStore.yaml' },
66
+ output: { path: './src/gen' },
67
+ adapter: adapterOas(),
68
+ parsers: [parserTs, parserMd],
69
+ plugins: [],
70
+ })
71
+ notes:
72
+ - type: tip
73
+ body: |-
74
+ `parserMd.print({ title: 'Pets', layout: 'doc' })` returns `---\ntitle: Pets\nlayout: doc\n---`. Render it from a plugin to inject frontmatter into a generated page without depending on `yaml` directly.
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@kubb/parser-md",
3
+ "version": "5.0.0-beta.25",
4
+ "description": "Markdown source file parser for Kubb. Converts the universal AST to `.md` source and renders YAML frontmatter via the `print` helper.",
5
+ "keywords": [
6
+ "codegen",
7
+ "frontmatter",
8
+ "kubb",
9
+ "markdown",
10
+ "parser",
11
+ "yaml"
12
+ ],
13
+ "license": "MIT",
14
+ "author": "stijnvanhulle",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/kubb-labs/kubb.git",
18
+ "directory": "packages/parser-md"
19
+ },
20
+ "files": [
21
+ "src",
22
+ "dist",
23
+ "extension.yaml",
24
+ "!/**/**.test.**",
25
+ "!/**/__tests__/**",
26
+ "!/**/__snapshots__/**"
27
+ ],
28
+ "type": "module",
29
+ "sideEffects": false,
30
+ "main": "./dist/index.cjs",
31
+ "module": "./dist/index.js",
32
+ "types": "./dist/index.d.ts",
33
+ "exports": {
34
+ ".": {
35
+ "import": "./dist/index.js",
36
+ "require": "./dist/index.cjs"
37
+ },
38
+ "./package.json": "./package.json"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public",
42
+ "registry": "https://registry.npmjs.org/"
43
+ },
44
+ "scripts": {
45
+ "build": "tsdown",
46
+ "clean": "npx rimraf ./dist",
47
+ "lint": "oxlint .",
48
+ "lint:fix": "oxlint --fix .",
49
+ "release": "pnpm publish --no-git-check",
50
+ "release:canary": "bash ../../.github/canary.sh && node ../../scripts/build.js canary && pnpm publish --no-git-check",
51
+ "start": "tsdown --watch",
52
+ "test": "vitest --passWithNoTests",
53
+ "typecheck": "tsc -p ./tsconfig.json --noEmit --emitDeclarationOnly false"
54
+ },
55
+ "dependencies": {
56
+ "@kubb/ast": "workspace:*",
57
+ "@kubb/core": "workspace:*",
58
+ "yaml": "catalog:"
59
+ },
60
+ "devDependencies": {
61
+ "@internals/utils": "workspace:*"
62
+ },
63
+ "engines": {
64
+ "node": ">=22"
65
+ }
66
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { parserMd, type MdMeta } from './parserMd.ts'
@@ -0,0 +1,57 @@
1
+ import type { CodeNode } from '@kubb/ast'
2
+ import { extractStringsFromNodes } from '@kubb/ast'
3
+ import { defineParser } from '@kubb/core'
4
+ import { print, type PrintInput } from './utils.ts'
5
+
6
+ /**
7
+ * Metadata accepted by `parserMd`. Set `frontmatter` on a `<File meta={…}>` to
8
+ * have the parser prepend the corresponding YAML envelope.
9
+ */
10
+ export type MdMeta = {
11
+ frontmatter?: Record<string, unknown> | null
12
+ }
13
+
14
+ /**
15
+ * Kubb parser for `.md` and `.markdown` files. Joins source blocks as plain
16
+ * markdown (separated by blank lines) and, when `file.meta.frontmatter` is set,
17
+ * prepends a YAML frontmatter envelope produced by `parserMd.print`.
18
+ *
19
+ * Add to the `parsers` array on `defineConfig` to opt in. `parserTs` keeps
20
+ * handling `.ts`/`.js` files, `parserMd` claims `.md`/`.markdown`.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * import { defineConfig } from 'kubb'
25
+ * import { adapterOas } from '@kubb/adapter-oas'
26
+ * import { parserMd } from '@kubb/parser-md'
27
+ *
28
+ * export default defineConfig({
29
+ * input: { path: './petStore.yaml' },
30
+ * output: { path: './src/gen' },
31
+ * adapter: adapterOas(),
32
+ * parsers: [parserMd],
33
+ * plugins: [],
34
+ * })
35
+ * ```
36
+ */
37
+ export const parserMd = defineParser({
38
+ name: 'markdown',
39
+ extNames: ['.md', '.markdown'],
40
+ print(...parts: PrintInput[]) {
41
+ return print(...parts)
42
+ },
43
+ parse(file) {
44
+ const sourceParts: string[] = []
45
+ for (const source of file.sources) {
46
+ const text = extractStringsFromNodes(source.nodes as Array<CodeNode>)
47
+ if (text) sourceParts.push(text.trimEnd())
48
+ }
49
+ const body = sourceParts.join('\n\n')
50
+
51
+ const meta = file.meta as MdMeta | undefined
52
+ const frontmatter = print(meta?.frontmatter ?? undefined)
53
+
54
+ const parts = [file.banner, frontmatter, body, file.footer].filter((segment): segment is string => Boolean(segment)).map((segment) => segment.trimEnd())
55
+ return parts.join('\n\n')
56
+ },
57
+ })
package/src/utils.ts ADDED
@@ -0,0 +1,45 @@
1
+ import { stringify } from 'yaml'
2
+
3
+ /**
4
+ * Markdown `print` input — either a markdown text fragment (passed through
5
+ * verbatim) or a plain object that is serialised as a YAML frontmatter envelope.
6
+ */
7
+ export type PrintInput = string | Record<string, unknown>
8
+
9
+ /**
10
+ * Wraps a plain object as a YAML frontmatter envelope:
11
+ *
12
+ * ```
13
+ * ---
14
+ * <yaml>
15
+ * ---
16
+ * ```
17
+ *
18
+ * Returns an empty string for `null`, `undefined`, or empty objects so callers
19
+ * can drop the result through the same filter chain as banner/footer fields.
20
+ */
21
+ export function printFrontmatter(data: Record<string, unknown> | null | undefined): string {
22
+ if (!data || Object.keys(data).length === 0) return ''
23
+ return `---\n${stringify(data).trimEnd()}\n---`
24
+ }
25
+
26
+ /**
27
+ * Joins a list of markdown fragments with blank lines. Plain objects are
28
+ * rendered as YAML frontmatter via {@link printFrontmatter}; strings pass
29
+ * through unchanged.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * print({ title: 'Hi' }, '# Hello')
34
+ * // '---\ntitle: Hi\n---\n\n# Hello'
35
+ * ```
36
+ */
37
+ export function print(...parts: Array<PrintInput | null | undefined>): string {
38
+ const rendered: string[] = []
39
+ for (const part of parts) {
40
+ if (part === null || part === undefined || part === '') continue
41
+ const text = typeof part === 'string' ? part : printFrontmatter(part)
42
+ if (text) rendered.push(text.trimEnd())
43
+ }
44
+ return rendered.join('\n\n')
45
+ }