@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 +92 -0
- package/dist/chunk--u3MIqq1.js +8 -0
- package/dist/index.cjs +94 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/extension.yaml +74 -0
- package/package.json +66 -0
- package/src/index.ts +1 -0
- package/src/parserMd.ts +57 -0
- package/src/utils.ts +45 -0
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/
|
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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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'
|
package/src/parserMd.ts
ADDED
|
@@ -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
|
+
}
|