fumadocs-openapi 1.0.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) 2023 Fuma
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/dist/bin.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/bin.js ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ generateFiles
4
+ } from "./chunk-6NCGY6WV.js";
5
+
6
+ // src/bin.ts
7
+ import { resolve } from "node:path";
8
+ import { pathToFileURL } from "node:url";
9
+ async function main() {
10
+ const configName = process.argv[2];
11
+ const config = await readConfig(configName);
12
+ await generateFiles(config);
13
+ }
14
+ async function readConfig(name = "openapi.config.js") {
15
+ const path = resolve(process.cwd(), name);
16
+ const result = await import(pathToFileURL(path).toString());
17
+ if (typeof result.default !== "object")
18
+ throw new Error("Invalid configuration");
19
+ return result.default;
20
+ }
21
+ void main();
@@ -0,0 +1,539 @@
1
+ // src/generate.ts
2
+ import Parser from "@apidevtools/swagger-parser";
3
+
4
+ // src/render/element.ts
5
+ function createElement(name, props, ...child) {
6
+ const s = [];
7
+ const params = Object.entries(props).map(([key, value]) => `${key}={${JSON.stringify(value)}}`).join(" ");
8
+ s.push(params.length > 0 ? `<${name} ${params}>` : `<${name}>`);
9
+ s.push(...child);
10
+ s.push(`</${name}>`);
11
+ return s.join("\n\n");
12
+ }
13
+ function p(child) {
14
+ if (!child)
15
+ return "";
16
+ return child.replace("<", "\\<").replace(">", "\\>");
17
+ }
18
+ function span(child) {
19
+ return `<span>${p(child)}</span>`;
20
+ }
21
+ function codeblock({ language, title }, child) {
22
+ return [
23
+ title ? `\`\`\`${language} title=${JSON.stringify(title)}` : `\`\`\`${language}`,
24
+ child,
25
+ "```"
26
+ ].join("\n");
27
+ }
28
+
29
+ // src/render/custom.ts
30
+ function api(...child) {
31
+ return createElement("API", {}, ...child);
32
+ }
33
+ function apiExample(...child) {
34
+ return createElement("APIExample", {}, ...child);
35
+ }
36
+ function root(...child) {
37
+ return createElement("Root", {}, ...child);
38
+ }
39
+ function apiInfo(props, ...child) {
40
+ return createElement("APIInfo", props, ...child);
41
+ }
42
+ function accordions(...child) {
43
+ return createElement("Accordions", {}, ...child);
44
+ }
45
+ function accordion(props, ...child) {
46
+ return createElement("Accordion", props, ...child);
47
+ }
48
+ function tabs(props, ...child) {
49
+ return createElement("Tabs", props, ...child);
50
+ }
51
+ function tab(props, ...child) {
52
+ return createElement("Tab", props, ...child);
53
+ }
54
+ function property({ required = false, deprecated = false, ...props }, ...child) {
55
+ return createElement(
56
+ "Property",
57
+ { required, deprecated, ...props },
58
+ ...child
59
+ );
60
+ }
61
+
62
+ // src/samples/index.ts
63
+ import { sample } from "openapi-sampler";
64
+
65
+ // src/utils.ts
66
+ function noRef(v) {
67
+ return v;
68
+ }
69
+ function getPreferredMedia(body) {
70
+ if (Object.keys(body).length === 0)
71
+ return void 0;
72
+ if ("application/json" in body)
73
+ return body["application/json"];
74
+ return Object.values(body)[0];
75
+ }
76
+ function getValue(value) {
77
+ return typeof value === "string" ? value : JSON.stringify(value, null, 2);
78
+ }
79
+
80
+ // src/samples/index.ts
81
+ function createEndpoint(path, method, baseUrl = "https://example.com") {
82
+ const params = [];
83
+ const responses = {};
84
+ for (const param of method.parameters) {
85
+ const schema = noRef(
86
+ param.schema ?? getPreferredMedia(param.content ?? {})?.schema
87
+ );
88
+ if (!schema)
89
+ continue;
90
+ params.push({
91
+ name: param.name,
92
+ in: param.in,
93
+ schema
94
+ });
95
+ }
96
+ const body = noRef(method.requestBody)?.content ?? {};
97
+ const bodySchema = noRef(getPreferredMedia(body)?.schema);
98
+ for (const [code, value] of Object.entries(method.responses)) {
99
+ const mediaTypes = noRef(value).content ?? {};
100
+ const responseSchema = noRef(getPreferredMedia(mediaTypes)?.schema);
101
+ if (!responseSchema)
102
+ continue;
103
+ responses[code] = {
104
+ schema: responseSchema
105
+ };
106
+ }
107
+ let pathWithParameters = path;
108
+ const queryParams = new URLSearchParams();
109
+ for (const param of params) {
110
+ const value = generateSample(method.method, param.schema);
111
+ if (param.in === "query")
112
+ queryParams.append(param.name, getValue(value));
113
+ if (param.in === "path")
114
+ pathWithParameters = pathWithParameters.replace(
115
+ `{${param.name}}`,
116
+ getValue(value)
117
+ );
118
+ }
119
+ return {
120
+ url: new URL(pathWithParameters, baseUrl).toString(),
121
+ body: bodySchema ? generateSample(method.method, bodySchema) : void 0,
122
+ responses,
123
+ method: method.method,
124
+ parameters: params
125
+ };
126
+ }
127
+ function generateSample(method, schema) {
128
+ return sample(schema, {
129
+ skipReadOnly: method !== "GET",
130
+ skipWriteOnly: method === "GET"
131
+ });
132
+ }
133
+
134
+ // src/samples/response.ts
135
+ function getExampleResponse(endpoint, code) {
136
+ if (code in endpoint.responses) {
137
+ const value = generateSample(
138
+ endpoint.method,
139
+ endpoint.responses[code].schema
140
+ );
141
+ return JSON.stringify(value, null, 2);
142
+ }
143
+ }
144
+
145
+ // src/samples/typescript.ts
146
+ import { compile } from "json-schema-to-typescript";
147
+ async function getTypescript(endpoint, code) {
148
+ if (code in endpoint.responses) {
149
+ return compile(endpoint.responses[code].schema, "Response", {
150
+ bannerComment: "",
151
+ additionalProperties: false,
152
+ format: true,
153
+ enableConstEnums: false
154
+ });
155
+ }
156
+ }
157
+
158
+ // src/samples/curl.ts
159
+ function getSampleRequest(endpoint) {
160
+ const s = [];
161
+ s.push(`curl -X ${endpoint.method} "${endpoint.url}"`);
162
+ for (const param of endpoint.parameters) {
163
+ if (param.in === "header") {
164
+ const value = generateSample(endpoint.method, param.schema);
165
+ const header = `${param.name}: ${getValue2(value)}`;
166
+ s.push(`-H "${header}"`);
167
+ }
168
+ if (param.in === "formData") {
169
+ console.log("Request example for form data is not supported");
170
+ }
171
+ }
172
+ if (endpoint.body)
173
+ s.push(`-d '${getValue2(endpoint.body)}'`);
174
+ return s.join(" \\\n ");
175
+ }
176
+ function getValue2(value) {
177
+ return typeof value === "string" ? value : JSON.stringify(value, null, 2);
178
+ }
179
+
180
+ // src/render/schema.ts
181
+ var keys = {
182
+ example: "Example",
183
+ default: "Default",
184
+ minimum: "Minimum",
185
+ maximum: "Maximum",
186
+ minLength: "Minimum length",
187
+ maxLength: "Maximum length",
188
+ pattern: "Pattern",
189
+ format: "Format"
190
+ };
191
+ function isObject(schema) {
192
+ return schema.type === "object" || schema.properties !== void 0;
193
+ }
194
+ function schemaElement(name, schema, { parseObject, ...ctx }) {
195
+ if (schema.readOnly && !ctx.readOnly)
196
+ return "";
197
+ if (schema.writeOnly && !ctx.writeOnly)
198
+ return "";
199
+ const child = [];
200
+ function field(key, value) {
201
+ child.push(span(`${key}: \`${value}\``));
202
+ }
203
+ if (isObject(schema) && parseObject) {
204
+ const { additionalProperties, properties } = schema;
205
+ if (additionalProperties) {
206
+ if (additionalProperties === true) {
207
+ child.push(
208
+ property({
209
+ name: "[key: string]",
210
+ type: "any"
211
+ })
212
+ );
213
+ } else {
214
+ child.push(
215
+ schemaElement("[key: string]", noRef(additionalProperties), {
216
+ ...ctx,
217
+ required: false,
218
+ parseObject: false
219
+ })
220
+ );
221
+ }
222
+ }
223
+ Object.entries(properties ?? {}).forEach(([key, value]) => {
224
+ child.push(
225
+ schemaElement(key, noRef(value), {
226
+ ...ctx,
227
+ required: schema.required?.includes(key) ?? false,
228
+ parseObject: false
229
+ })
230
+ );
231
+ });
232
+ return child.join("\n\n");
233
+ }
234
+ child.push(p(schema.description));
235
+ for (const [key, value] of Object.entries(keys)) {
236
+ if (key in schema) {
237
+ field(value, JSON.stringify(schema[key]));
238
+ }
239
+ }
240
+ if (schema.enum) {
241
+ field(
242
+ "Value in",
243
+ schema.enum.map((value) => JSON.stringify(value)).join(" | ")
244
+ );
245
+ }
246
+ const resolved = resolveObjectType(schema);
247
+ if (resolved && !parseObject) {
248
+ child.push(
249
+ accordions(
250
+ accordion(
251
+ { title: "Object Type" },
252
+ schemaElement(name, resolved, {
253
+ ...ctx,
254
+ parseObject: true,
255
+ required: false
256
+ })
257
+ )
258
+ )
259
+ );
260
+ }
261
+ return property(
262
+ {
263
+ name,
264
+ type: getSchemaType(schema),
265
+ required: ctx.required,
266
+ deprecated: schema.deprecated
267
+ },
268
+ ...child
269
+ );
270
+ }
271
+ function resolveObjectType(schema) {
272
+ if (isObject(schema))
273
+ return schema;
274
+ if (schema.type === "array") {
275
+ return resolveObjectType(noRef(schema.items));
276
+ }
277
+ }
278
+ function getSchemaType(schema) {
279
+ if (schema.nullable) {
280
+ return `${getSchemaType({ ...schema, nullable: false })} | null`;
281
+ }
282
+ if (schema.type === "array")
283
+ return `array of ${getSchemaType(noRef(schema.items))}`;
284
+ if (schema.oneOf)
285
+ return schema.oneOf.map((one) => getSchemaType(noRef(one))).join(" | ");
286
+ if (schema.allOf)
287
+ return schema.allOf.map((one) => getSchemaType(noRef(one))).join(" & ");
288
+ if (schema.anyOf)
289
+ return `Any properties in ${schema.anyOf.map((one) => getSchemaType(noRef(one))).join(", ")}`;
290
+ if (schema.type)
291
+ return schema.type;
292
+ if (isObject(schema))
293
+ return "object";
294
+ throw new Error(`Cannot detect object type: ${JSON.stringify(schema)}`);
295
+ }
296
+
297
+ // src/render/operation.ts
298
+ async function renderOperation(path, method, baseUrl) {
299
+ const info = [];
300
+ const example = [];
301
+ info.push(`## ${method.summary ?? method.operationId}`);
302
+ if (method.description)
303
+ info.push(p(method.description));
304
+ const body = noRef(method.requestBody);
305
+ if (body) {
306
+ const bodySchema = getPreferredMedia(body.content)?.schema;
307
+ if (!bodySchema)
308
+ throw new Error();
309
+ info.push(
310
+ `### Request Body${!body.required ? " (Optional)" : ""}`,
311
+ p(body.description),
312
+ schemaElement("body", noRef(bodySchema), {
313
+ parseObject: true,
314
+ readOnly: method.method === "GET",
315
+ writeOnly: method.method !== "GET",
316
+ required: body.required ?? false
317
+ })
318
+ );
319
+ }
320
+ const parameterGroups = /* @__PURE__ */ new Map();
321
+ const endpoint = createEndpoint(path, method, baseUrl);
322
+ for (const param of method.parameters) {
323
+ const schema = noRef(
324
+ param.schema ?? getPreferredMedia(param.content ?? {})?.schema
325
+ );
326
+ if (!schema)
327
+ continue;
328
+ const content = schemaElement(
329
+ param.name,
330
+ {
331
+ ...schema,
332
+ description: param.description ?? schema.description,
333
+ deprecated: param.deprecated || schema.deprecated
334
+ },
335
+ {
336
+ parseObject: false,
337
+ readOnly: method.method === "GET",
338
+ writeOnly: method.method !== "GET",
339
+ required: param.required ?? false
340
+ }
341
+ );
342
+ const groupName = {
343
+ path: "Path Parameters",
344
+ query: "Query Parameters",
345
+ header: "Header Parameters",
346
+ cookie: "Cookie Parameters"
347
+ }[param.in] ?? "Other Parameters";
348
+ const group = parameterGroups.get(groupName) ?? [];
349
+ group.push(content);
350
+ parameterGroups.set(groupName, group);
351
+ }
352
+ for (const [group, parameters] of Array.from(parameterGroups.entries())) {
353
+ info.push(`### ${group}`, ...parameters);
354
+ }
355
+ info.push(getResponseTable(method));
356
+ example.push(
357
+ codeblock({ language: "bash", title: "curl" }, getSampleRequest(endpoint))
358
+ );
359
+ example.push(await getResponseTabs(endpoint, method));
360
+ return api(
361
+ apiInfo({ method: method.method, route: path }, ...info),
362
+ apiExample(...example)
363
+ );
364
+ }
365
+ function getResponseTable(operation) {
366
+ const table = [];
367
+ table.push(`| Status code | Description |`);
368
+ table.push(`| ----------- | ----------- |`);
369
+ Object.entries(operation.responses).forEach(([code, value]) => {
370
+ table.push(`| \`${code}\` | ${noRef(value).description} |`);
371
+ });
372
+ return table.join("\n");
373
+ }
374
+ async function getResponseTabs(endpoint, operation) {
375
+ const items = [];
376
+ const child = [];
377
+ for (const [code, _] of Object.entries(operation.responses)) {
378
+ const example = getExampleResponse(endpoint, code);
379
+ const ts = await getTypescript(endpoint, code);
380
+ const description = code in endpoint.responses ? endpoint.responses[code].schema.description : void 0;
381
+ if (example && ts) {
382
+ items.push(code);
383
+ child.push(
384
+ tab(
385
+ { value: code },
386
+ p(description),
387
+ codeblock({ language: "json", title: "Example Response" }, example),
388
+ accordions(
389
+ accordion(
390
+ { title: "Typescript Definition" },
391
+ codeblock({ language: "ts" }, ts)
392
+ )
393
+ )
394
+ )
395
+ );
396
+ }
397
+ }
398
+ if (items.length === 0)
399
+ return "";
400
+ return tabs(
401
+ {
402
+ items
403
+ },
404
+ ...child
405
+ );
406
+ }
407
+
408
+ // src/generate.ts
409
+ async function dereference(pathOrDocument) {
410
+ return await Parser.dereference(pathOrDocument);
411
+ }
412
+ async function generate(pathOrDocument, options = {}) {
413
+ const document = await dereference(pathOrDocument);
414
+ const tag = options.tag ? document.tags?.find((item) => item.name === options.tag) : void 0;
415
+ const routes = Object.entries(document.paths).map(
416
+ ([key, value]) => {
417
+ if (!value)
418
+ throw new Error("Invalid schema");
419
+ const methodKeys = ["get", "post", "patch", "delete", "head"];
420
+ const methods = [];
421
+ for (const methodKey of methodKeys) {
422
+ const operation = value[methodKey];
423
+ if (!operation)
424
+ continue;
425
+ if (tag && !operation.tags?.includes(tag.name))
426
+ continue;
427
+ methods.push(buildOperation(methodKey, operation));
428
+ }
429
+ return {
430
+ ...value,
431
+ path: key,
432
+ methods
433
+ };
434
+ }
435
+ );
436
+ const serverUrl = document.servers?.[0].url;
437
+ const s = [];
438
+ for (const route of routes) {
439
+ for (const method of route.methods) {
440
+ s.push(await renderOperation(route.path, method, serverUrl));
441
+ }
442
+ }
443
+ return render(
444
+ tag?.name ?? document.info.title,
445
+ tag?.description ?? document.info.description,
446
+ root(...s),
447
+ options
448
+ );
449
+ }
450
+ async function generateTags(pathOrDocument, options = {}) {
451
+ const document = await dereference(pathOrDocument);
452
+ const results = document.tags?.map(async (tag) => {
453
+ return {
454
+ tag: tag.name,
455
+ content: await generate(document, {
456
+ tag: tag.name,
457
+ ...options
458
+ })
459
+ };
460
+ });
461
+ return Promise.all(results ?? []);
462
+ }
463
+ function render(title, description, content, {
464
+ render: fn,
465
+ componentsImportPath = "fumadocs-ui/components/api"
466
+ }) {
467
+ const result = fn?.(title, description, content) ?? {};
468
+ const rendered = {
469
+ frontmatter: result.frontmatter ?? [
470
+ "---",
471
+ title && `title: ${title}`,
472
+ description && `description: ${description}`,
473
+ "---"
474
+ ].filter(Boolean).join("\n"),
475
+ imports: result.imports ?? [
476
+ `import { Root, API, APIInfo, APIExample, Property } from '${componentsImportPath}'`,
477
+ `import { Tabs, Tab } from 'fumadocs-ui/components/tabs'`,
478
+ `import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';`
479
+ ],
480
+ content: result.content ?? content
481
+ };
482
+ return [rendered.frontmatter, rendered.imports.join("\n"), rendered.content].filter(Boolean).join("\n\n");
483
+ }
484
+ function buildOperation(method, operation) {
485
+ return {
486
+ ...operation,
487
+ parameters: operation.parameters ?? [],
488
+ method: method.toUpperCase()
489
+ };
490
+ }
491
+
492
+ // src/generate-file.ts
493
+ import { mkdirSync, writeFileSync } from "node:fs";
494
+ import { resolve, dirname, join, parse } from "node:path";
495
+ async function generateFiles({
496
+ input,
497
+ output,
498
+ name: nameFn,
499
+ per = "file",
500
+ render: render2
501
+ }) {
502
+ const outputDir = resolve(output);
503
+ const options = {
504
+ render: render2
505
+ };
506
+ await Promise.all(
507
+ input.map(async (file) => {
508
+ const path = resolve(file);
509
+ let filename = parse(path).name;
510
+ filename = nameFn?.("file", filename) ?? filename;
511
+ if (per === "file") {
512
+ const outPath = join(outputDir, `${filename}.mdx`);
513
+ const result = await generate(path, options);
514
+ write(outPath, result);
515
+ console.log(`Generated: ${outPath}`);
516
+ } else {
517
+ const results = await generateTags(path, options);
518
+ results.forEach((result) => {
519
+ let tagName = result.tag;
520
+ tagName = nameFn?.("tag", tagName) ?? tagName.toLowerCase().replace(/\s+/g, "-");
521
+ const outPath = join(outputDir, `${filename}/${tagName}.mdx`);
522
+ write(outPath, result.content);
523
+ console.log(`Generated: ${outPath}`);
524
+ });
525
+ }
526
+ })
527
+ );
528
+ }
529
+ function write(path, content) {
530
+ mkdirSync(dirname(path), { recursive: true });
531
+ writeFileSync(path, content);
532
+ }
533
+
534
+ export {
535
+ dereference,
536
+ generate,
537
+ generateTags,
538
+ generateFiles
539
+ };
@@ -0,0 +1,64 @@
1
+ import { OpenAPIV3 } from 'openapi-types';
2
+
3
+ declare function dereference(pathOrDocument: string | OpenAPIV3.Document): Promise<OpenAPIV3.Document>;
4
+ interface GenerateOptions {
5
+ tag?: string;
6
+ /**
7
+ * The import path of your API components, it must exports all components in `fumadocs-ui/components/api`
8
+ *
9
+ * @defaultValue `fumadocs-ui/components/api`
10
+ */
11
+ componentsImportPath?: string;
12
+ render?: (title: string | undefined, description: string | undefined, content: string) => Partial<RenderResult>;
13
+ }
14
+ interface RenderResult {
15
+ frontmatter: string;
16
+ imports: string[];
17
+ content: string;
18
+ }
19
+ declare function generate(pathOrDocument: string | OpenAPIV3.Document, options?: GenerateOptions): Promise<string>;
20
+ declare function generateTags(pathOrDocument: string | OpenAPIV3.Document, options?: Omit<GenerateOptions, 'tag'>): Promise<{
21
+ tag: string;
22
+ content: string;
23
+ }[]>;
24
+
25
+ interface Config {
26
+ /**
27
+ * Schema files
28
+ */
29
+ input: string[];
30
+ /**
31
+ * Output directory
32
+ */
33
+ output: string;
34
+ /**
35
+ * tag: Generate a page for each tag
36
+ *
37
+ * file: Generate a page for each schema
38
+ *
39
+ * @defaultValue tag
40
+ */
41
+ per?: 'tag' | 'file';
42
+ /**
43
+ * Specify name for output file
44
+ */
45
+ name?: (type: 'file' | 'tag', name: string) => string;
46
+ /**
47
+ * Modify output file
48
+ */
49
+ render?: NonNullable<GenerateOptions['render']>;
50
+ }
51
+ declare function generateFiles({ input, output, name: nameFn, per, render, }: Config): Promise<void>;
52
+
53
+ interface RouteInformation {
54
+ path: string;
55
+ summary?: string;
56
+ description?: string;
57
+ methods: MethodInformation[];
58
+ }
59
+ interface MethodInformation extends OpenAPIV3.OperationObject {
60
+ parameters: OpenAPIV3.ParameterObject[];
61
+ method: string;
62
+ }
63
+
64
+ export { type Config, type GenerateOptions, type MethodInformation, type RouteInformation, dereference, generate, generateFiles, generateTags };
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import {
2
+ dereference,
3
+ generate,
4
+ generateFiles,
5
+ generateTags
6
+ } from "./chunk-6NCGY6WV.js";
7
+ export {
8
+ dereference,
9
+ generate,
10
+ generateFiles,
11
+ generateTags
12
+ };
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "fumadocs-openapi",
3
+ "version": "1.0.0",
4
+ "description": "Generate MDX docs for your OpenAPI spec",
5
+ "keywords": [
6
+ "NextJs",
7
+ "Docs"
8
+ ],
9
+ "homepage": "https://fumadocs.vercel.app",
10
+ "repository": "github:fuma-nama/next-docs",
11
+ "license": "MIT",
12
+ "author": "Fuma Nama",
13
+ "type": "module",
14
+ "main": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
16
+ "bin": {
17
+ "fumadocs-openapi": "./dist/bin.js"
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "dependencies": {
23
+ "@apidevtools/swagger-parser": "^10.1.0",
24
+ "json-schema-to-typescript": "^13.1.1",
25
+ "openapi-sampler": "^1.4.0"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "18.17.5",
29
+ "@types/openapi-sampler": "^1.0.3",
30
+ "openapi-types": "^12.1.3",
31
+ "eslint-config-custom": "0.0.0",
32
+ "tsconfig": "0.0.0"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "scripts": {
38
+ "build": "tsup",
39
+ "clean": "rimraf dist",
40
+ "dev": "tsup --watch",
41
+ "lint": "eslint .",
42
+ "test": "vitest",
43
+ "types:check": "tsc --noEmit"
44
+ }
45
+ }