@scalar/openapi-to-markdown 0.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # @scalar/openapi-to-markdown
2
+
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 382b510: init :)
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [be8a6ec]
12
+ - Updated dependencies [1843cfe]
13
+ - @scalar/types@0.1.16
14
+ - @scalar/components@0.13.59
15
+ - @scalar/oas-utils@0.2.144
16
+ - @scalar/openapi-parser@0.10.17
17
+ - @scalar/snippetz@0.2.20
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023-present Scalar
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 ADDED
@@ -0,0 +1,106 @@
1
+ # Scalar OpenAPI to Markdown
2
+
3
+ [![Version](https://img.shields.io/npm/v/%40scalar/openapi-to-markdown)](https://www.npmjs.com/package/@scalar/openapi-to-markdown)
4
+ [![Downloads](https://img.shields.io/npm/dm/%40scalar/openapi-to-markdown)](https://www.npmjs.com/package/@scalar/openapi-to-markdown)
5
+ [![License](https://img.shields.io/npm/l/%40scalar%2Fopenapi-to-markdown)](https://www.npmjs.com/package/@scalar/openapi-to-markdown)
6
+ [![Discord](https://img.shields.io/discord/1135330207960678410?style=flat&color=5865F2)](https://discord.gg/scalar)
7
+
8
+ A Node.js package to generate LLM-friendly Markdown from OpenAPI documents.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @scalar/openapi-to-markdown
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ ```ts
19
+ import { createMarkdownFromOpenApi } from '@scalar/openapi-to-markdown'
20
+
21
+ const content = {
22
+ openapi: '3.1.1',
23
+ info: {
24
+ title: 'My API',
25
+ version: '1.0',
26
+ },
27
+ paths: {
28
+ // …
29
+ },
30
+ }
31
+
32
+ // Generate Markdown from an OpenAPI document
33
+ const markdown = await createMarkdownFromOpenApi(content)
34
+ ```
35
+
36
+ ### With Hono
37
+
38
+ You use the package with any Node.js framework. Here is an example for [Hono](https://hono.dev/):
39
+
40
+ ```ts
41
+ import { Hono } from 'hono'
42
+ import { createMarkdownFromOpenApi } from '@scalar/openapi-to-markdown'
43
+
44
+ // Generate Markdown from an OpenAPI document
45
+ const markdown = await createMarkdownFromOpenApi(content)
46
+
47
+ const app = new Hono()
48
+
49
+ /**
50
+ * Register a route to serve the Markdown for LLMs
51
+ *
52
+ * Q: Why /llms.txt?
53
+ * A: It's a proposal to standardise on using an /llms.txt file.
54
+ *
55
+ * @see https://llmstxt.org/
56
+ */
57
+ app.get('/llms.txt', (c) => c.text(markdown))
58
+
59
+ serve(app)
60
+ ```
61
+
62
+ ### Generate HTML
63
+
64
+ This is not really the purpose of the package, but maybe good to know: This package actually renders HTML at first, and
65
+ transforms the HTML to Markdown then.
66
+
67
+ So if you’d like to have a really light-weight HTML API Reference, here you are:
68
+
69
+ ```ts
70
+ import { Hono } from 'hono'
71
+ import { createHtmlFromOpenApi } from '@scalar/openapi-to-markdown'
72
+
73
+ // Generate HTML from an OpenAPI document
74
+ const html = await createHtmlFromOpenApi(content)
75
+
76
+ const app = new Hono()
77
+
78
+ app.get('/', (c) =>
79
+ c.html(
80
+ `<!doctype html>
81
+ <html lang="en" data-theme="light">
82
+ <head>
83
+ <meta charset="UTF-8" />
84
+ <title>Scalar Galaxy</title>
85
+ <!-- Basic styling for semantic HTML tags (optional) -->
86
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
87
+ </head>
88
+ <body>
89
+ <main class="container">
90
+ ${html}
91
+ </main>
92
+ </body>
93
+ </html>`,
94
+ ),
95
+ )
96
+
97
+ serve(app)
98
+ ```
99
+
100
+ ## Community
101
+
102
+ We are API nerds. You too? Let’s chat on Discord: <https://discord.gg/scalar>
103
+
104
+ ## License
105
+
106
+ The source code in this repository is licensed under [MIT](https://github.com/scalar/scalar/blob/main/LICENSE).
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=MarkdownReference.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownReference.test.d.ts","sourceRoot":"","sources":["../../src/components/MarkdownReference.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import type { OpenAPIV3_1 } from '@scalar/openapi-types';
2
+ type __VLS_Props = {
3
+ content: OpenAPIV3_1.Document;
4
+ };
5
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, HTMLElement>;
6
+ export default _default;
7
+ //# sourceMappingURL=MarkdownReference.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownReference.vue.d.ts","sourceRoot":"","sources":["../../src/components/MarkdownReference.vue"],"names":[],"mappings":"AA6TA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AASxD,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,WAAW,CAAC,QAAQ,CAAA;CAC9B,CAAC;;AAuVF,wBAOG"}
@@ -0,0 +1,238 @@
1
+ import { defineComponent as K, createElementBlock as e, openBlock as t, createElementVNode as l, createBlock as j, createCommentVNode as r, toDisplayString as u, createTextVNode as i, unref as S, Fragment as o, renderList as b, createVNode as v } from "vue";
2
+ import { ScalarMarkdown as x } from "@scalar/components";
3
+ import { getExampleFromSchema as V } from "@scalar/oas-utils/spec-getters";
4
+ import B from "./Schema.vue.js";
5
+ import C from "./XmlOrJson.vue.js";
6
+ const Q = { key: 1 }, X = { key: 0 }, Y = { key: 1 }, Z = { key: 2 }, h = { key: 0 }, a = { key: 1 }, T = { key: 0 }, c = { key: 1 }, _ = { key: 3 }, ll = { key: 2 }, nl = { key: 3 }, tl = { key: 0 }, el = { key: 1 }, ul = { key: 4 }, yl = /* @__PURE__ */ K({
7
+ __name: "MarkdownReference",
8
+ props: {
9
+ content: {}
10
+ },
11
+ setup(sl) {
12
+ return (y, n) => {
13
+ var E, w, D, M, N, P, R, U, q, A, F, I, L, $, W, z, G;
14
+ return t(), e("section", null, [
15
+ l("header", null, [
16
+ l("h1", null, u((w = (E = y.content) == null ? void 0 : E.info) == null ? void 0 : w.title), 1),
17
+ l("ul", null, [
18
+ l("li", null, [
19
+ n[0] || (n[0] = l("strong", null, "OpenAPI Version:", -1)),
20
+ n[1] || (n[1] = i(" ")),
21
+ l("code", null, u((D = y.content) == null ? void 0 : D.openapi), 1)
22
+ ]),
23
+ l("li", null, [
24
+ n[2] || (n[2] = l("strong", null, "API Version:", -1)),
25
+ n[3] || (n[3] = i(" ")),
26
+ l("code", null, u((N = (M = y.content) == null ? void 0 : M.info) == null ? void 0 : N.version), 1)
27
+ ])
28
+ ])
29
+ ]),
30
+ (R = (P = y.content) == null ? void 0 : P.info) != null && R.description ? (t(), j(S(x), {
31
+ key: 0,
32
+ value: (q = (U = y.content) == null ? void 0 : U.info) == null ? void 0 : q.description
33
+ }, null, 8, ["value"])) : r("", !0),
34
+ (F = (A = y.content) == null ? void 0 : A.servers) != null && F.length ? (t(), e("section", Q, [
35
+ n[10] || (n[10] = l("h2", null, "Servers", -1)),
36
+ l("ul", null, [
37
+ (t(!0), e(o, null, b(y.content.servers, (s) => (t(), e("li", {
38
+ key: s.url
39
+ }, [
40
+ n[8] || (n[8] = l("strong", null, "URL:", -1)),
41
+ n[9] || (n[9] = i(" ")),
42
+ l("code", null, u(s.url), 1),
43
+ l("ul", null, [
44
+ s.description ? (t(), e("li", X, [
45
+ n[4] || (n[4] = l("strong", null, "Description:", -1)),
46
+ i(" " + u(s.description), 1)
47
+ ])) : r("", !0),
48
+ s.variables && Object.keys(s.variables).length ? (t(), e("li", Y, [
49
+ n[7] || (n[7] = l("strong", null, "Variables:", -1)),
50
+ l("ul", null, [
51
+ (t(!0), e(o, null, b(s.variables, (g, k) => (t(), e("li", { key: k }, [
52
+ l("code", null, u(k), 1),
53
+ n[5] || (n[5] = i(" (default: ")),
54
+ l("code", null, u(g.default), 1),
55
+ n[6] || (n[6] = i(")")),
56
+ g.description ? (t(), e(o, { key: 0 }, [
57
+ i(": " + u(g.description), 1)
58
+ ], 64)) : r("", !0)
59
+ ]))), 128))
60
+ ])
61
+ ])) : r("", !0)
62
+ ])
63
+ ]))), 128))
64
+ ])
65
+ ])) : r("", !0),
66
+ Object.keys(((I = y.content) == null ? void 0 : I.paths) ?? {}).length ? (t(), e("section", Z, [
67
+ n[21] || (n[21] = l("h2", null, "Operations", -1)),
68
+ (t(!0), e(o, null, b(Object.keys(((L = y.content) == null ? void 0 : L.paths) ?? {}), (s) => {
69
+ var g, k;
70
+ return t(), e(o, { key: s }, [
71
+ (t(!0), e(o, null, b((k = (g = y.content) == null ? void 0 : g.paths) == null ? void 0 : k[s], (d, H) => {
72
+ var J;
73
+ return t(), e("section", { key: d }, [
74
+ l("header", null, [
75
+ l("h3", null, [
76
+ d.summary ? (t(), e(o, { key: 0 }, [
77
+ i(u(d.summary), 1)
78
+ ], 64)) : (t(), e(o, { key: 1 }, [
79
+ i(u(H.toString().toUpperCase()) + " " + u(s), 1)
80
+ ], 64)),
81
+ d["x-scalar-stability"] ? (t(), e(o, { key: 2 }, [
82
+ i(" (" + u(d["x-scalar-stability"]) + ") ", 1)
83
+ ], 64)) : d.deprecated ? (t(), e(o, { key: 3 }, [
84
+ i(" ⚠️ Deprecated ")
85
+ ], 64)) : r("", !0)
86
+ ])
87
+ ]),
88
+ l("ul", null, [
89
+ l("li", null, [
90
+ n[11] || (n[11] = l("strong", null, "Method:", -1)),
91
+ n[12] || (n[12] = i(" ")),
92
+ l("code", null, u(H.toString().toUpperCase()), 1)
93
+ ]),
94
+ l("li", null, [
95
+ n[13] || (n[13] = l("strong", null, "Path:", -1)),
96
+ n[14] || (n[14] = i(" ")),
97
+ l("code", null, u(s), 1)
98
+ ]),
99
+ d.tags ? (t(), e("li", h, [
100
+ n[15] || (n[15] = l("strong", null, "Tags:", -1)),
101
+ i(" " + u(d.tags.join(", ")), 1)
102
+ ])) : r("", !0),
103
+ d["x-scalar-stability"] ? (t(), e("li", a, [
104
+ n[16] || (n[16] = l("strong", null, "Stability:", -1)),
105
+ i(" " + u(d["x-scalar-stability"]), 1)
106
+ ])) : r("", !0)
107
+ ]),
108
+ v(S(x), {
109
+ value: d.description
110
+ }, null, 8, ["value"]),
111
+ (J = d.requestBody) != null && J.content ? (t(), e("section", T, [
112
+ n[18] || (n[18] = l("h4", null, "Request Body", -1)),
113
+ (t(!0), e(o, null, b(d.requestBody.content, (p, m) => (t(), e(o, { key: m }, [
114
+ l("h5", null, "Content-Type: " + u(m), 1),
115
+ p.schema ? (t(), e(o, { key: 0 }, [
116
+ v(B, {
117
+ schema: p.schema
118
+ }, null, 8, ["schema"]),
119
+ n[17] || (n[17] = l("p", null, [
120
+ l("strong", null, "Example:")
121
+ ], -1)),
122
+ v(C, {
123
+ xml: m == null ? void 0 : m.toString().includes("xml"),
124
+ "model-value": S(V)(p.schema, {
125
+ xml: m == null ? void 0 : m.toString().includes("xml")
126
+ })
127
+ }, null, 8, ["xml", "model-value"])
128
+ ], 64)) : r("", !0)
129
+ ], 64))), 128))
130
+ ])) : r("", !0),
131
+ d.responses ? (t(), e("section", c, [
132
+ n[20] || (n[20] = l("h4", null, "Responses", -1)),
133
+ (t(!0), e(o, null, b(d.responses, (p, m) => (t(), e("section", { key: m }, [
134
+ l("header", null, [
135
+ l("h5", null, [
136
+ i(" Status: " + u(m) + " ", 1),
137
+ p.description ? (t(), e(o, { key: 0 }, [
138
+ i(u(p.description), 1)
139
+ ], 64)) : r("", !0)
140
+ ])
141
+ ]),
142
+ (t(!0), e(o, null, b(p.content, (O, f) => (t(), e("section", { key: f }, [
143
+ l("h6", null, "Content-Type: " + u(f), 1),
144
+ O.schema ? (t(), e(o, { key: 0 }, [
145
+ v(B, {
146
+ schema: O.schema
147
+ }, null, 8, ["schema"]),
148
+ n[19] || (n[19] = l("p", null, [
149
+ l("strong", null, "Example:")
150
+ ], -1)),
151
+ v(C, {
152
+ xml: f == null ? void 0 : f.toString().includes("xml"),
153
+ "model-value": S(V)(O.schema, {
154
+ xml: f == null ? void 0 : f.toString().includes("xml")
155
+ })
156
+ }, null, 8, ["xml", "model-value"])
157
+ ], 64)) : r("", !0)
158
+ ]))), 128))
159
+ ]))), 128))
160
+ ])) : r("", !0)
161
+ ]);
162
+ }), 128))
163
+ ], 64);
164
+ }), 128))
165
+ ])) : r("", !0),
166
+ Object.keys((($ = y.content) == null ? void 0 : $.webhooks) ?? {}).length ? (t(), e("section", _, [
167
+ n[26] || (n[26] = l("h2", null, "Webhooks", -1)),
168
+ (t(!0), e(o, null, b((W = y.content) == null ? void 0 : W.webhooks, (s, g) => (t(), e(o, { key: g }, [
169
+ (t(!0), e(o, null, b(s, (k, d) => (t(), e("section", { key: k }, [
170
+ l("header", null, [
171
+ l("h3", null, [
172
+ k.summary ? (t(), e(o, { key: 0 }, [
173
+ i(u(k.summary), 1)
174
+ ], 64)) : (t(), e(o, { key: 1 }, [
175
+ i(u(g), 1)
176
+ ], 64)),
177
+ k["x-scalar-stability"] ? (t(), e("span", ll, "(" + u(k["x-scalar-stability"]) + ")", 1)) : k.deprecated ? (t(), e("span", nl, "⚠️ Deprecated")) : r("", !0)
178
+ ])
179
+ ]),
180
+ l("ul", null, [
181
+ l("li", null, [
182
+ n[22] || (n[22] = l("strong", null, "Method:", -1)),
183
+ l("code", null, u(d.toString().toUpperCase()), 1)
184
+ ]),
185
+ l("li", null, [
186
+ n[23] || (n[23] = l("strong", null, "Path:", -1)),
187
+ l("code", null, "/webhooks/" + u(g), 1)
188
+ ]),
189
+ k.tags ? (t(), e("li", tl, [
190
+ n[24] || (n[24] = l("strong", null, "Tags:", -1)),
191
+ i(" " + u(k.tags.join(", ")), 1)
192
+ ])) : r("", !0),
193
+ k.deprecated ? (t(), e("li", el, n[25] || (n[25] = [
194
+ l("strong", null, "Deprecated", -1)
195
+ ]))) : r("", !0)
196
+ ]),
197
+ v(S(x), {
198
+ value: k.description
199
+ }, null, 8, ["value"])
200
+ ]))), 128))
201
+ ], 64))), 128))
202
+ ])) : r("", !0),
203
+ (G = (z = y.content) == null ? void 0 : z.components) != null && G.schemas && Object.keys(y.content.components.schemas).length ? (t(), e("section", ul, [
204
+ n[29] || (n[29] = l("h2", null, "Schemas", -1)),
205
+ (t(!0), e(o, null, b(y.content.components.schemas, (s, g) => (t(), e("section", { key: g }, [
206
+ l("header", null, [
207
+ l("h3", null, u(s.title ?? g), 1)
208
+ ]),
209
+ l("ul", null, [
210
+ l("li", null, [
211
+ n[27] || (n[27] = l("strong", null, "Type:", -1)),
212
+ l("code", null, u(s.type), 1)
213
+ ])
214
+ ]),
215
+ s.description ? (t(), j(S(x), {
216
+ key: 0,
217
+ value: s.description
218
+ }, null, 8, ["value"])) : r("", !0),
219
+ s.type === "object" ? (t(), j(B, {
220
+ key: 1,
221
+ schema: s
222
+ }, null, 8, ["schema"])) : r("", !0),
223
+ n[28] || (n[28] = l("p", null, [
224
+ l("strong", null, "Example:")
225
+ ], -1)),
226
+ s.type === "object" ? (t(), j(C, {
227
+ key: 2,
228
+ "model-value": S(V)(s)
229
+ }, null, 8, ["model-value"])) : r("", !0)
230
+ ]))), 128))
231
+ ])) : r("", !0)
232
+ ]);
233
+ };
234
+ }
235
+ });
236
+ export {
237
+ yl as default
238
+ };
@@ -0,0 +1,4 @@
1
+ import f from "./MarkdownReference.vue.js";
2
+ export {
3
+ f as default
4
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Schema.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Schema.test.d.ts","sourceRoot":"","sources":["../../src/components/Schema.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import type { OpenAPIV3_1 } from '@scalar/openapi-types';
2
+ type __VLS_Props = {
3
+ schema: OpenAPIV3_1.SchemaObject;
4
+ };
5
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
+ export default _default;
7
+ //# sourceMappingURL=Schema.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Schema.vue.d.ts","sourceRoot":"","sources":["../../src/components/Schema.vue"],"names":[],"mappings":"AA6MA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAIxD,KAAK,WAAW,GAAG;IACjB,MAAM,EAAE,WAAW,CAAC,YAAY,CAAA;CACjC,CAAC;;AAsPF,wBAMG"}
@@ -0,0 +1,138 @@
1
+ import { defineComponent as O, resolveComponent as g, createElementBlock as t, createCommentVNode as i, openBlock as n, createElementVNode as o, Fragment as f, renderList as k, createVNode as d, createBlock as p, toDisplayString as u, createTextVNode as a } from "vue";
2
+ const j = { key: 0 }, v = { key: 0 }, I = { key: 1 }, b = { key: 2 }, N = { key: 3 }, A = { key: 4 }, B = { key: 0 }, C = { key: 0 }, J = { key: 1 }, V = { key: 2 }, E = { key: 3 }, M = { key: 1 }, R = { key: 5 }, D = { key: 0 }, F = { key: 0 }, L = { key: 1 }, P = { key: 2 }, T = { key: 6 }, U = { key: 0 }, w = { key: 1 }, z = { key: 2 }, G = { key: 3 }, Q = /* @__PURE__ */ O({
3
+ __name: "Schema",
4
+ props: {
5
+ schema: { type: [Object, Boolean] }
6
+ },
7
+ setup(H) {
8
+ const c = (s, e) => {
9
+ const r = Object.entries(s).sort(([l], [m]) => {
10
+ const y = e == null ? void 0 : e.includes(l), h = e == null ? void 0 : e.includes(m);
11
+ return y && !h ? -1 : !y && h ? 1 : l.localeCompare(m);
12
+ });
13
+ return Object.fromEntries(r);
14
+ };
15
+ return (s, e) => {
16
+ const r = g("Schema", !0);
17
+ return s.schema ? (n(), t("section", j, [
18
+ s.schema.allOf ? (n(), t("section", v, [
19
+ e[0] || (e[0] = o("header", null, [
20
+ o("strong", null, "All of:")
21
+ ], -1)),
22
+ (n(!0), t(f, null, k(s.schema.allOf, (l, m) => (n(), t("section", { key: m }, [
23
+ d(r, { schema: l }, null, 8, ["schema"])
24
+ ]))), 128))
25
+ ])) : s.schema.anyOf ? (n(), t("section", I, [
26
+ e[1] || (e[1] = o("header", null, [
27
+ o("strong", null, "Any of:")
28
+ ], -1)),
29
+ (n(!0), t(f, null, k(s.schema.anyOf, (l, m) => (n(), t("section", { key: m }, [
30
+ d(r, { schema: l }, null, 8, ["schema"])
31
+ ]))), 128))
32
+ ])) : s.schema.oneOf ? (n(), t("section", b, [
33
+ e[2] || (e[2] = o("header", null, [
34
+ o("strong", null, "One of:")
35
+ ], -1)),
36
+ (n(!0), t(f, null, k(s.schema.oneOf, (l, m) => (n(), t("section", { key: m }, [
37
+ d(r, { schema: l }, null, 8, ["schema"])
38
+ ]))), 128))
39
+ ])) : s.schema.not ? (n(), t("section", N, [
40
+ e[3] || (e[3] = o("header", null, [
41
+ o("strong", null, "Not:")
42
+ ], -1)),
43
+ o("section", null, [
44
+ d(r, {
45
+ schema: s.schema.not
46
+ }, null, 8, ["schema"])
47
+ ])
48
+ ])) : s.schema.type === "object" || s.schema.properties ? (n(), t("section", A, [
49
+ o("ul", null, [
50
+ (n(!0), t(f, null, k(c(
51
+ s.schema.properties || {},
52
+ s.schema.required
53
+ ), (l, m) => {
54
+ var y;
55
+ return n(), t("li", { key: m }, [
56
+ o("strong", null, [
57
+ o("code", null, u(m), 1),
58
+ (y = s.schema.required) != null && y.includes(m) ? (n(), t("span", B, " (required) ")) : i("", !0)
59
+ ]),
60
+ o("p", null, [
61
+ o("code", null, u(Array.isArray(l.type) ? l.type.join(" | ") : l.type || "object"), 1),
62
+ l.format ? (n(), t("span", C, [
63
+ e[4] || (e[4] = a(", format: ")),
64
+ o("code", null, u(l.format), 1)
65
+ ])) : i("", !0),
66
+ l.enum ? (n(), t("span", J, [
67
+ e[5] || (e[5] = a(", possible values: ")),
68
+ o("code", null, u(l.enum.map((h) => JSON.stringify(h)).join(", ")), 1)
69
+ ])) : i("", !0),
70
+ l.default !== void 0 ? (n(), t("span", V, [
71
+ e[6] || (e[6] = a(", default: ")),
72
+ o("code", null, u(JSON.stringify(l.default)), 1)
73
+ ])) : i("", !0),
74
+ l.description ? (n(), t("span", E, " — " + u(l.description), 1)) : i("", !0)
75
+ ]),
76
+ l.type === "object" || l.properties ? (n(), p(r, {
77
+ key: 0,
78
+ schema: l
79
+ }, null, 8, ["schema"])) : i("", !0),
80
+ l.type === "array" && l.items ? (n(), t("section", M, [
81
+ e[7] || (e[7] = o("header", null, [
82
+ o("strong", null, "Items:")
83
+ ], -1)),
84
+ d(r, {
85
+ schema: l.items
86
+ }, null, 8, ["schema"])
87
+ ])) : i("", !0)
88
+ ]);
89
+ }), 128))
90
+ ])
91
+ ])) : s.schema.type === "array" && s.schema.items ? (n(), t("section", R, [
92
+ e[11] || (e[11] = o("header", null, [
93
+ o("strong", null, "Array of:")
94
+ ], -1)),
95
+ o("section", null, [
96
+ d(r, {
97
+ schema: s.schema.items
98
+ }, null, 8, ["schema"])
99
+ ]),
100
+ s.schema.minItems !== void 0 || s.schema.maxItems !== void 0 || s.schema.uniqueItems ? (n(), t("ul", D, [
101
+ s.schema.minItems !== void 0 ? (n(), t("li", F, [
102
+ e[8] || (e[8] = a(" Min items: ")),
103
+ o("code", null, u(s.schema.minItems), 1)
104
+ ])) : i("", !0),
105
+ s.schema.maxItems !== void 0 ? (n(), t("li", L, [
106
+ e[9] || (e[9] = a(" Max items: ")),
107
+ o("code", null, u(s.schema.maxItems), 1)
108
+ ])) : i("", !0),
109
+ s.schema.uniqueItems ? (n(), t("li", P, e[10] || (e[10] = [
110
+ a("Unique items: "),
111
+ o("code", null, "true", -1)
112
+ ]))) : i("", !0)
113
+ ])) : i("", !0)
114
+ ])) : (n(), t("section", T, [
115
+ o("p", null, [
116
+ o("code", null, u(s.schema.type), 1),
117
+ s.schema.format ? (n(), t("span", U, [
118
+ e[12] || (e[12] = a(", format: ")),
119
+ o("code", null, u(s.schema.format), 1)
120
+ ])) : i("", !0),
121
+ s.schema.enum ? (n(), t("span", w, [
122
+ e[13] || (e[13] = a(", possible values: ")),
123
+ o("code", null, u(s.schema.enum.map((l) => JSON.stringify(l)).join(", ")), 1)
124
+ ])) : i("", !0),
125
+ s.schema.default !== void 0 ? (n(), t("span", z, [
126
+ e[14] || (e[14] = a(", default: ")),
127
+ o("code", null, u(JSON.stringify(s.schema.default)), 1)
128
+ ])) : i("", !0),
129
+ s.schema.description ? (n(), t("span", G, " — " + u(s.schema.description), 1)) : i("", !0)
130
+ ])
131
+ ]))
132
+ ])) : i("", !0);
133
+ };
134
+ }
135
+ });
136
+ export {
137
+ Q as default
138
+ };
@@ -0,0 +1,4 @@
1
+ import f from "./Schema.vue.js";
2
+ export {
3
+ f as default
4
+ };
@@ -0,0 +1,10 @@
1
+ import type { OpenAPIV3_1 } from '@scalar/openapi-types';
2
+ type __VLS_Props = {
3
+ xml?: boolean;
4
+ modelValue: OpenAPIV3_1.SchemaObject;
5
+ };
6
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
7
+ xml: boolean;
8
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ export default _default;
10
+ //# sourceMappingURL=XmlOrJson.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"XmlOrJson.vue.d.ts","sourceRoot":"","sources":["../../src/components/XmlOrJson.vue"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAMxD,KAAK,WAAW,GAAG;IACf,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,UAAU,EAAE,WAAW,CAAC,YAAY,CAAA;CACrC,CAAC;;SAFM,OAAO;;AA0EjB,wBAOG"}
@@ -0,0 +1,19 @@
1
+ import { defineComponent as r, createElementBlock as o, openBlock as l, createElementVNode as n, toDisplayString as t, unref as m } from "vue";
2
+ import a from "object-to-xml";
3
+ const p = { key: 0 }, s = { key: 1 }, f = /* @__PURE__ */ r({
4
+ __name: "XmlOrJson",
5
+ props: {
6
+ xml: { type: Boolean, default: !1 },
7
+ modelValue: { type: [Object, Boolean] }
8
+ },
9
+ setup(c) {
10
+ return (e, d) => e.xml ? (l(), o("pre", p, [
11
+ n("code", null, t(`<?xml version="1.0" encoding="UTF-8"?>${m(a)(e.modelValue)}`), 1)
12
+ ])) : (l(), o("pre", s, [
13
+ n("code", null, t(JSON.stringify(e.modelValue, null, 2)), 1)
14
+ ]));
15
+ }
16
+ });
17
+ export {
18
+ f as default
19
+ };
@@ -0,0 +1,4 @@
1
+ import f from "./XmlOrJson.vue.js";
2
+ export {
3
+ f as default
4
+ };
@@ -0,0 +1,7 @@
1
+ import type { OpenAPI } from '@scalar/openapi-types';
2
+ type AnyDocument = OpenAPI.Document | Record<string, unknown> | string;
3
+ export declare function createHtmlFromOpenApi(input: AnyDocument): Promise<string>;
4
+ export declare function createMarkdownFromOpenApi(content: AnyDocument): Promise<string>;
5
+ export declare function markdownFromHtml(html: string): Promise<string>;
6
+ export {};
7
+ //# sourceMappingURL=create-markdown-from-openapi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-markdown-from-openapi.d.ts","sourceRoot":"","sources":["../src/create-markdown-from-openapi.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAYpD,KAAK,WAAW,GAAG,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAA;AAEtE,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,WAAW,mBAyB7D;AAED,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,WAAW,mBAEnE;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAYpE"}
@@ -0,0 +1,41 @@
1
+ import { upgrade as n, dereference as i } from "@scalar/openapi-parser";
2
+ import { minify as a } from "html-minifier-terser";
3
+ import p from "rehype-parse";
4
+ import s from "rehype-remark";
5
+ import u from "rehype-sanitize";
6
+ import c from "remark-gfm";
7
+ import f from "remark-stringify";
8
+ import { unified as l } from "unified";
9
+ import { createSSRApp as y } from "vue";
10
+ import { renderToString as d } from "vue/server-renderer";
11
+ import g from "./components/MarkdownReference.vue.js";
12
+ async function h(e) {
13
+ const { specification: r } = n(e), { schema: t } = await i(r), o = y(g, {
14
+ content: t
15
+ }), m = await d(o);
16
+ return a(m, {
17
+ removeComments: !0,
18
+ removeEmptyElements: !0,
19
+ collapseWhitespace: !0,
20
+ continueOnParseError: !0,
21
+ noNewlinesBeforeTagClose: !0,
22
+ preserveLineBreaks: !0,
23
+ removeEmptyAttributes: !0,
24
+ decodeEntities: !0,
25
+ useShortDoctype: !0
26
+ });
27
+ }
28
+ async function P(e) {
29
+ return w(await h(e));
30
+ }
31
+ async function w(e) {
32
+ const r = await l().use(p, { fragment: !0 }).use(c).use(u).use(s).use(f, {
33
+ bullet: "-"
34
+ }).process(e);
35
+ return String(r);
36
+ }
37
+ export {
38
+ h as createHtmlFromOpenApi,
39
+ P as createMarkdownFromOpenApi,
40
+ w as markdownFromHtml
41
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=create-markdown-from-openapi.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-markdown-from-openapi.test.d.ts","sourceRoot":"","sources":["../src/create-markdown-from-openapi.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export { createMarkdownFromOpenApi } from './create-markdown-from-openapi';
2
+ export { createHtmlFromOpenApi } from './create-markdown-from-openapi';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAA;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ import { createHtmlFromOpenApi as o, createMarkdownFromOpenApi as p } from "./create-markdown-from-openapi.js";
2
+ export {
3
+ o as createHtmlFromOpenApi,
4
+ p as createMarkdownFromOpenApi
5
+ };
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@scalar/openapi-to-markdown",
3
+ "description": "Create plain Markdown from OpenAPI documents (for LLMs)",
4
+ "license": "MIT",
5
+ "author": "Scalar (https://github.com/scalar)",
6
+ "homepage": "https://github.com/scalar/scalar",
7
+ "bugs": "https://github.com/scalar/scalar/issues/new/choose",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/scalar/scalar.git",
11
+ "directory": "packages/openapi-to-markdown"
12
+ },
13
+ "keywords": [
14
+ "openapi",
15
+ "markdown",
16
+ "llm",
17
+ "swagger"
18
+ ],
19
+ "version": "0.1.0",
20
+ "engines": {
21
+ "node": ">=18"
22
+ },
23
+ "type": "module",
24
+ "main": "dist/index.js",
25
+ "exports": {
26
+ ".": {
27
+ "import": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "default": "./dist/index.js"
30
+ },
31
+ "./*.css": {
32
+ "import": "./dist/*.css",
33
+ "require": "./dist/*.css",
34
+ "default": "./dist/*.css"
35
+ },
36
+ "./css/*.css": {
37
+ "import": "./dist/css/*.css",
38
+ "require": "./dist/css/*.css",
39
+ "default": "./dist/css/*.css"
40
+ }
41
+ },
42
+ "files": [
43
+ "dist",
44
+ "CHANGELOG.md"
45
+ ],
46
+ "module": "dist/index.js",
47
+ "dependencies": {
48
+ "html-minifier-terser": "^7.2.0",
49
+ "object-to-xml": "^2.0.0",
50
+ "rehype-parse": "^9.0.0",
51
+ "rehype-remark": "^10.0.1",
52
+ "rehype-sanitize": "^6.0.0",
53
+ "rehype-stringify": "^10.0.0",
54
+ "remark-gfm": "^4.0.0",
55
+ "remark-stringify": "^11.0.0",
56
+ "unified": "^11.0.4",
57
+ "vue": "^3.5.12",
58
+ "@scalar/components": "0.13.59",
59
+ "@scalar/openapi-parser": "0.10.17",
60
+ "@scalar/openapi-types": "0.2.3",
61
+ "@scalar/types": "0.1.16",
62
+ "@scalar/oas-utils": "0.2.144",
63
+ "@scalar/snippetz": "0.2.20"
64
+ },
65
+ "devDependencies": {
66
+ "@hono/node-server": "^1.11.0",
67
+ "@scalar/galaxy": "^0.3.2",
68
+ "@types/html-minifier-terser": "^7.0.2",
69
+ "@vitejs/plugin-vue": "^5.0.4",
70
+ "@vue/test-utils": "^2.4.1",
71
+ "hono": "^4.6.5",
72
+ "vite": "5.4.19",
73
+ "vue": "^3.5.12",
74
+ "@scalar/build-tooling": "0.1.19"
75
+ },
76
+ "scripts": {
77
+ "build": "scalar-build-vite",
78
+ "dev": "nodemon --exec \"vite-node playground/index.ts\" --ext ts,vue --quiet --watch ./",
79
+ "format": "scalar-format",
80
+ "format:check": "scalar-format-check",
81
+ "test": "vitest",
82
+ "types:build": "scalar-types-build-vue",
83
+ "types:check": "scalar-types-check-vue"
84
+ }
85
+ }