fumadocs-openapi 8.1.3 → 8.1.5
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/dist/generate-file.d.ts.map +1 -1
- package/dist/generate-file.js +40 -23
- package/dist/playground/client.d.ts +5 -16
- package/dist/playground/client.d.ts.map +1 -1
- package/dist/playground/client.js +39 -44
- package/dist/playground/get-default-values.d.ts +2 -2
- package/dist/playground/get-default-values.d.ts.map +1 -1
- package/dist/playground/get-default-values.js +21 -22
- package/dist/playground/index.d.ts +4 -38
- package/dist/playground/index.d.ts.map +1 -1
- package/dist/playground/index.js +43 -139
- package/dist/playground/inputs.d.ts +11 -13
- package/dist/playground/inputs.d.ts.map +1 -1
- package/dist/playground/inputs.js +72 -129
- package/dist/playground/schema.d.ts +38 -0
- package/dist/playground/schema.d.ts.map +1 -0
- package/dist/playground/schema.js +93 -0
- package/dist/render/operation/get-request-data.d.ts +1 -2
- package/dist/render/operation/get-request-data.d.ts.map +1 -1
- package/dist/render/operation/get-request-data.js +2 -2
- package/dist/render/operation/index.d.ts.map +1 -1
- package/dist/render/operation/index.js +5 -5
- package/dist/render/schema.d.ts +3 -3
- package/dist/render/schema.d.ts.map +1 -1
- package/dist/render/schema.js +70 -100
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/client.d.ts +3 -0
- package/dist/ui/client.d.ts.map +1 -1
- package/dist/ui/client.js +15 -0
- package/dist/ui/components/dialog.d.ts.map +1 -1
- package/dist/ui/components/dialog.js +4 -3
- package/dist/ui/components/select.js +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/server-select.d.ts +2 -7
- package/dist/ui/server-select.d.ts.map +1 -1
- package/dist/ui/server-select.js +52 -19
- package/dist/utils/combine-schema.d.ts.map +1 -1
- package/dist/utils/combine-schema.js +12 -2
- package/dist/utils/process-document.js +1 -1
- package/dist/utils/schema-to-string.d.ts +3 -0
- package/dist/utils/schema-to-string.d.ts.map +1 -0
- package/dist/utils/schema-to-string.js +62 -0
- package/dist/utils/schema.d.ts +9 -4
- package/dist/utils/schema.d.ts.map +1 -1
- package/dist/utils/schema.js +2 -0
- package/package.json +8 -7
- package/dist/playground/resolve.d.ts +0 -6
- package/dist/playground/resolve.d.ts.map +0 -1
- package/dist/playground/resolve.js +0 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-file.d.ts","sourceRoot":"","sources":["../src/generate-file.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,eAAe,EAIrB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,MAAO,SAAQ,eAAe;IAC7C;;OAEG;IACH,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAEzB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,WAAW,CAAC;IAEnC;;OAEG;IACH,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAEtD;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;OAIG;IACH,OAAO,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;CACpC;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"generate-file.d.ts","sourceRoot":"","sources":["../src/generate-file.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,eAAe,EAIrB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,MAAO,SAAQ,eAAe;IAC7C;;OAEG;IACH,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAEzB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,WAAW,CAAC;IAEnC;;OAEG;IACH,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAEtD;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;OAIG;IACH,OAAO,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;CACpC;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmJlE"}
|
package/dist/generate-file.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
-
import
|
|
2
|
+
import * as path from 'node:path';
|
|
3
3
|
import fg from 'fast-glob';
|
|
4
4
|
import { generateAll, generatePages, generateTags, } from './generate.js';
|
|
5
5
|
export async function generateFiles(options) {
|
|
6
6
|
const { input, output, name: nameFn, per = 'operation', groupBy = 'none', cwd = process.cwd(), } = options;
|
|
7
|
-
const outputDir = join(cwd, output);
|
|
8
7
|
const urlInputs = [];
|
|
9
8
|
const fileInputs = [];
|
|
10
9
|
for (const v of typeof input === 'string' ? [input] : input) {
|
|
@@ -28,7 +27,7 @@ export async function generateFiles(options) {
|
|
|
28
27
|
file = getFilename(result.pathItem.summary);
|
|
29
28
|
}
|
|
30
29
|
else if (result.type === 'operation') {
|
|
31
|
-
file = join(getOutputPathFromRoute(result.item.path), result.item.method.toLowerCase());
|
|
30
|
+
file = path.join(getOutputPathFromRoute(result.item.path), result.item.method.toLowerCase());
|
|
32
31
|
}
|
|
33
32
|
else {
|
|
34
33
|
file = getFilename(result.item.name);
|
|
@@ -41,11 +40,11 @@ export async function generateFiles(options) {
|
|
|
41
40
|
tags = ['unknown'];
|
|
42
41
|
}
|
|
43
42
|
for (const tag of tags) {
|
|
44
|
-
outPaths.push(join(
|
|
43
|
+
outPaths.push(path.join(getFilename(tag), `${file}.mdx`));
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
else {
|
|
48
|
-
outPaths.push(
|
|
47
|
+
outPaths.push(`${file}.mdx`);
|
|
49
48
|
}
|
|
50
49
|
return outPaths;
|
|
51
50
|
}
|
|
@@ -58,28 +57,41 @@ export async function generateFiles(options) {
|
|
|
58
57
|
console.log(`Generated Meta: ${file}`);
|
|
59
58
|
}
|
|
60
59
|
async function generateFromDocument(pathOrUrl) {
|
|
60
|
+
const outputDir = path.join(cwd, output);
|
|
61
61
|
if (per === 'file') {
|
|
62
|
-
let filename = isUrl(pathOrUrl)
|
|
62
|
+
let filename = isUrl(pathOrUrl)
|
|
63
|
+
? 'index'
|
|
64
|
+
: path.basename(pathOrUrl, path.extname(pathOrUrl));
|
|
63
65
|
if (nameFn)
|
|
64
66
|
filename = nameFn('file', filename);
|
|
65
|
-
const outPath = join(outputDir, `${filename}.mdx`);
|
|
67
|
+
const outPath = path.join(outputDir, `${filename}.mdx`);
|
|
66
68
|
const result = await generateAll(pathOrUrl, options);
|
|
67
69
|
await write(outPath, result);
|
|
68
70
|
console.log(`Generated: ${outPath}`);
|
|
69
71
|
}
|
|
70
72
|
if (per === 'operation') {
|
|
71
73
|
const results = await generatePages(pathOrUrl, options);
|
|
74
|
+
const mapping = new Map();
|
|
72
75
|
for (const result of results) {
|
|
73
76
|
const outputPaths = getOutputPaths(result);
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
for (const outputPath of outputPaths) {
|
|
78
|
+
mapping.set(outputPath, result);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
for (const [key, output] of mapping.entries()) {
|
|
82
|
+
let outputPath = key;
|
|
83
|
+
const isSharedDir = Array.from(mapping.keys()).some((item) => item !== outputPath &&
|
|
84
|
+
path.dirname(item) === path.dirname(outputPath));
|
|
85
|
+
if (!isSharedDir && path.dirname(outputPath) !== '.') {
|
|
86
|
+
outputPath = path.join(path.dirname(outputPath) + '.mdx');
|
|
87
|
+
}
|
|
88
|
+
await write(path.join(outputDir, outputPath), output.content);
|
|
89
|
+
if (groupBy === 'route' && output.pathItem.summary) {
|
|
90
|
+
await writeMetafile(path.join(outputDir, path.dirname(outputPath), 'meta.json'), {
|
|
91
|
+
title: output.pathItem.summary,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
console.log(`Generated: ${outputPath}`);
|
|
83
95
|
}
|
|
84
96
|
}
|
|
85
97
|
if (per === 'tag') {
|
|
@@ -87,7 +99,7 @@ export async function generateFiles(options) {
|
|
|
87
99
|
for (const result of results) {
|
|
88
100
|
let tagName = result.tag;
|
|
89
101
|
tagName = nameFn?.('tag', tagName) ?? getFilename(tagName);
|
|
90
|
-
const outPath = join(outputDir, `${tagName}.mdx`);
|
|
102
|
+
const outPath = path.join(outputDir, `${tagName}.mdx`);
|
|
91
103
|
await write(outPath, result.content);
|
|
92
104
|
console.log(`Generated: ${outPath}`);
|
|
93
105
|
}
|
|
@@ -100,15 +112,20 @@ function isUrl(input) {
|
|
|
100
112
|
}
|
|
101
113
|
function getOutputPathFromRoute(path) {
|
|
102
114
|
return (path
|
|
103
|
-
.
|
|
115
|
+
.toLowerCase()
|
|
116
|
+
.replaceAll('.', '-')
|
|
104
117
|
.split('/')
|
|
105
|
-
.
|
|
106
|
-
.
|
|
118
|
+
.map((v) => {
|
|
119
|
+
if (v.startsWith('{') && v.endsWith('}'))
|
|
120
|
+
return v.slice(1, -1);
|
|
121
|
+
return v;
|
|
122
|
+
})
|
|
123
|
+
.join('/') ?? '');
|
|
107
124
|
}
|
|
108
125
|
function getFilename(s) {
|
|
109
126
|
return s.replace(/\s+/g, '-').toLowerCase();
|
|
110
127
|
}
|
|
111
|
-
async function write(
|
|
112
|
-
await mkdir(dirname(
|
|
113
|
-
await writeFile(
|
|
128
|
+
async function write(file, content) {
|
|
129
|
+
await mkdir(path.dirname(file), { recursive: true });
|
|
130
|
+
await writeFile(file, content);
|
|
114
131
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type FC, type HTMLAttributes, type ReactElement
|
|
1
|
+
import { type FC, type HTMLAttributes, type ReactElement } from 'react';
|
|
2
2
|
import type { ControllerFieldState, ControllerRenderProps, FieldPath, UseFormStateReturn } from 'react-hook-form';
|
|
3
3
|
import type { FetchResult } from '../playground/fetcher.js';
|
|
4
|
-
import type { ParameterField,
|
|
4
|
+
import type { ParameterField, RequestSchema } from '../playground/index.js';
|
|
5
5
|
import type { Security } from '../utils/get-security.js';
|
|
6
6
|
interface FormValues {
|
|
7
7
|
authorization: string | {
|
|
@@ -32,11 +32,12 @@ export type ClientProps = HTMLAttributes<HTMLFormElement> & {
|
|
|
32
32
|
persistentId: string;
|
|
33
33
|
};
|
|
34
34
|
parameters?: ParameterField[];
|
|
35
|
-
body?:
|
|
35
|
+
body?: {
|
|
36
|
+
schema: RequestSchema;
|
|
36
37
|
mediaType: string;
|
|
37
38
|
};
|
|
38
39
|
/**
|
|
39
|
-
* Resolver for
|
|
40
|
+
* Resolver for $ref schemas you've passed
|
|
40
41
|
*/
|
|
41
42
|
references: Record<string, RequestSchema>;
|
|
42
43
|
proxyUrl?: string;
|
|
@@ -51,18 +52,6 @@ export type ClientProps = HTMLAttributes<HTMLFormElement> & {
|
|
|
51
52
|
}>;
|
|
52
53
|
}>;
|
|
53
54
|
};
|
|
54
|
-
interface SchemaContextType {
|
|
55
|
-
references: Record<string, RequestSchema>;
|
|
56
|
-
dynamic: RefObject<Map<string, DynamicField>>;
|
|
57
|
-
}
|
|
58
|
-
export type DynamicField = {
|
|
59
|
-
type: 'object';
|
|
60
|
-
properties: string[];
|
|
61
|
-
} | {
|
|
62
|
-
type: 'field';
|
|
63
|
-
schema: RequestSchema | ReferenceSchema;
|
|
64
|
-
};
|
|
65
|
-
export declare function useSchemaContext(): SchemaContextType;
|
|
66
55
|
export default function Client({ route, method, authorization, parameters, body, fields, references, proxyUrl, components: { ResultDisplay }, ...rest }: ClientProps): import("react/jsx-runtime").JSX.Element;
|
|
67
56
|
export {};
|
|
68
57
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/playground/client.tsx"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/playground/client.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,EAAE,EAEP,KAAK,cAAc,EAEnB,KAAK,YAAY,EAKlB,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EACrB,SAAS,EACT,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AAQzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAYxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAYrD,UAAU,UAAU;IAClB,aAAa,EACT,MAAM,GACN;QACE,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACN,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,WAAW,CAAC,KAAK,SAAS,SAAS,CAAC,UAAU,CAAC,EAAE,IAAI;IACpE,MAAM,EAAE,CAAC,KAAK,EAAE;QACd;;WAEG;QACH,IAAI,EAAE,IAAI,CAAC;QACX,KAAK,EAAE,qBAAqB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAChD,UAAU,EAAE,oBAAoB,CAAC;QACjC,SAAS,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC;KAC3C,KAAK,YAAY,CAAC;CACpB;AAED,MAAM,MAAM,WAAW,GAAG,cAAc,CAAC,eAAe,CAAC,GAAG;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,QAAQ,GAAG;QACzB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE;QACL,MAAM,EAAE,aAAa,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,MAAM,CAAC,EAAE;QACP,SAAS,CAAC,EAAE,WAAW,CACrB,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,MAAM,EAAE,EACnC,cAAc,CACf,CAAC;QACF,IAAI,CAAC,EAAE,WAAW,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;QACnD,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;KAC3C,CAAC;IAEF,UAAU,CAAC,EAAE,OAAO,CAAC;QACnB,aAAa,EAAE,EAAE,CAAC;YAAE,IAAI,EAAE,WAAW,CAAA;SAAE,CAAC,CAAC;KAC1C,CAAC,CAAC;CACJ,CAAC;AAoBF,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAC7B,KAAK,EACL,MAAc,EACd,aAAa,EACb,UAAU,EACV,IAAI,EACJ,MAAM,EACN,UAAU,EACV,QAAQ,EACR,UAAU,EAAE,EAAE,aAAoC,EAAO,EACzD,GAAG,IAAI,EACR,EAAE,WAAW,2CAiHb"}
|
|
@@ -1,30 +1,21 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { Fragment, lazy, useEffect, useMemo, useState, } from 'react';
|
|
4
4
|
import { Controller, FormProvider, useForm, useFormContext, } from 'react-hook-form';
|
|
5
5
|
import { useApiContext, useServerSelectContext } from '../ui/contexts/api.js';
|
|
6
|
-
import { FieldSet, JsonInput
|
|
6
|
+
import { FieldSet, JsonInput } from './inputs.js';
|
|
7
7
|
import { getStatusInfo } from './status-info.js';
|
|
8
8
|
import { getUrl } from '../utils/server-url.js';
|
|
9
9
|
import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock';
|
|
10
10
|
import { MethodLabel } from '../ui/components/method-label.js';
|
|
11
11
|
import { useQuery } from '../utils/use-query.js';
|
|
12
|
-
import ServerSelect from '../ui/server-select.js';
|
|
13
12
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from 'fumadocs-ui/components/ui/collapsible';
|
|
14
13
|
import { ChevronDown, LoaderCircle } from '../icons.js';
|
|
15
|
-
import { OauthDialog, OauthDialogTrigger, } from '../playground/auth/oauth-dialog.js';
|
|
16
14
|
import { useRequestData } from '../ui/contexts/code-example.js';
|
|
17
15
|
import { useEffectEvent } from 'fumadocs-core/utils/use-effect-event';
|
|
18
16
|
import { buttonVariants } from 'fumadocs-ui/components/ui/button';
|
|
19
17
|
import { cn } from 'fumadocs-ui/utils/cn';
|
|
20
|
-
import {
|
|
21
|
-
const SchemaContext = createContext(undefined);
|
|
22
|
-
export function useSchemaContext() {
|
|
23
|
-
const ctx = useContext(SchemaContext);
|
|
24
|
-
if (!ctx)
|
|
25
|
-
throw new Error('Missing provider');
|
|
26
|
-
return ctx;
|
|
27
|
-
}
|
|
18
|
+
import { SchemaProvider, useResolvedSchema, } from '../playground/schema.js';
|
|
28
19
|
function toRequestData(method, mediaType, value) {
|
|
29
20
|
return {
|
|
30
21
|
path: value.path,
|
|
@@ -36,10 +27,11 @@ function toRequestData(method, mediaType, value) {
|
|
|
36
27
|
query: value.query,
|
|
37
28
|
};
|
|
38
29
|
}
|
|
30
|
+
const ServerSelect = lazy(() => import('../ui/server-select.js'));
|
|
39
31
|
export default function Client({ route, method = 'GET', authorization, parameters, body, fields, references, proxyUrl, components: { ResultDisplay = DefaultResultDisplay } = {}, ...rest }) {
|
|
40
32
|
const { server } = useServerSelectContext();
|
|
41
|
-
const dynamicRef = useRef(new Map());
|
|
42
33
|
const requestData = useRequestData();
|
|
34
|
+
const fieldInfoMap = useMemo(() => new Map(), []);
|
|
43
35
|
const authInfo = usePersistentAuthInfo(authorization);
|
|
44
36
|
const defaultValues = useMemo(() => ({
|
|
45
37
|
authorization: authInfo.info,
|
|
@@ -63,6 +55,7 @@ export default function Client({ route, method = 'GET', authorization, parameter
|
|
|
63
55
|
});
|
|
64
56
|
});
|
|
65
57
|
useEffect(() => {
|
|
58
|
+
fieldInfoMap.clear();
|
|
66
59
|
form.reset(defaultValues);
|
|
67
60
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- update default value
|
|
68
61
|
}, [defaultValues]);
|
|
@@ -83,13 +76,11 @@ export default function Client({ route, method = 'GET', authorization, parameter
|
|
|
83
76
|
const onSubmit = form.handleSubmit((value) => {
|
|
84
77
|
testQuery.start(value);
|
|
85
78
|
});
|
|
86
|
-
return (_jsx(FormProvider, { ...form, children: _jsx(
|
|
79
|
+
return (_jsx(FormProvider, { ...form, children: _jsx(SchemaProvider, { fieldInfoMap: fieldInfoMap, references: references, children: _jsxs("form", { ...rest, className: cn('not-prose flex flex-col rounded-xl border shadow-md overflow-hidden bg-fd-card text-fd-card-foreground', rest.className), onSubmit: onSubmit, children: [_jsx(ServerSelect, {}), _jsxs("div", { className: "flex flex-row items-center gap-2 text-sm p-3 pb-0", children: [_jsx(MethodLabel, { children: method }), _jsx(Route, { route: route, className: "flex-1" }), _jsx("button", { type: "submit", className: cn(buttonVariants({ color: 'primary', size: 'sm' }), 'px-3 py-1.5'), disabled: testQuery.isLoading, children: testQuery.isLoading ? (_jsx(LoaderCircle, { className: "size-4 animate-spin" })) : ('Send') })] }), _jsx(FormBody, { body: body, fields: fields, parameters: parameters, authorization: authorization }), testQuery.data ? _jsx(ResultDisplay, { data: testQuery.data }) : null, authorization && _jsx(AuthFooter, { authorization: authorization })] }) }) }));
|
|
87
80
|
}
|
|
88
81
|
const paramNames = ['Headers', 'Cookies', 'Query', 'Path'];
|
|
89
82
|
const paramTypes = ['header', 'cookie', 'query', 'path'];
|
|
90
|
-
function FormBody({ authorization, parameters = [],
|
|
91
|
-
const { servers } = useApiContext();
|
|
92
|
-
const { server, setServer, setServerVariables } = useServerSelectContext();
|
|
83
|
+
function FormBody({ authorization, parameters = [], fields = {}, body, }) {
|
|
93
84
|
const params = useMemo(() => {
|
|
94
85
|
return paramTypes.map((param) => parameters.filter((v) => v.in === param));
|
|
95
86
|
}, [parameters]);
|
|
@@ -99,30 +90,25 @@ function FormBody({ authorization, parameters = [], body, fields = {}, }) {
|
|
|
99
90
|
const schema = authorization.type === 'http' && authorization.scheme === 'basic'
|
|
100
91
|
? {
|
|
101
92
|
type: 'object',
|
|
102
|
-
|
|
93
|
+
required: ['username', 'password'],
|
|
103
94
|
properties: {
|
|
104
95
|
username: {
|
|
105
96
|
type: 'string',
|
|
106
|
-
isRequired: true,
|
|
107
97
|
},
|
|
108
98
|
password: {
|
|
109
99
|
type: 'string',
|
|
110
|
-
isRequired: true,
|
|
111
100
|
},
|
|
112
101
|
},
|
|
113
102
|
}
|
|
114
103
|
: {
|
|
115
104
|
type: 'string',
|
|
116
|
-
isRequired: true,
|
|
117
105
|
description: 'The Authorization access token',
|
|
118
106
|
};
|
|
119
107
|
if (fields?.auth)
|
|
120
108
|
return renderCustomField('authorization', schema, fields.auth);
|
|
121
|
-
return (
|
|
122
|
-
color: 'secondary',
|
|
123
|
-
})), children: "Open" }))] }));
|
|
109
|
+
return (_jsx(FieldSet, { fieldName: "authorization", name: "Authorization", field: schema, isRequired: true }));
|
|
124
110
|
}
|
|
125
|
-
return (_jsxs(_Fragment, { children: [
|
|
111
|
+
return (_jsxs(_Fragment, { children: [params.map((param, i) => {
|
|
126
112
|
const name = paramNames[i];
|
|
127
113
|
const type = paramTypes[i];
|
|
128
114
|
if (type !== 'header' && param.length === 0)
|
|
@@ -131,37 +117,46 @@ function FormBody({ authorization, parameters = [], body, fields = {}, }) {
|
|
|
131
117
|
return;
|
|
132
118
|
return (_jsxs(CollapsiblePanel, { title: name, children: [type === 'header' ? renderAuth() : null, param.map((field) => {
|
|
133
119
|
const fieldName = `${type}.${field.name}`;
|
|
134
|
-
if (
|
|
135
|
-
return (
|
|
120
|
+
if (fields?.parameter) {
|
|
121
|
+
return renderCustomField(fieldName, field.schema, fields.parameter, field.name);
|
|
136
122
|
}
|
|
137
|
-
return
|
|
123
|
+
return (_jsx(FieldSet, { name: field.name, fieldName: fieldName, field: field.schema }, fieldName));
|
|
138
124
|
})] }, name));
|
|
139
|
-
}), body ? (fields.body ? (_jsx(CollapsiblePanel, { title: "Body", children: renderCustomField('body', body, fields.body) })) : (_jsx(BodyInput, { field: body }))) : null] }));
|
|
125
|
+
}), body ? (fields.body ? (_jsx(CollapsiblePanel, { title: "Body", children: renderCustomField('body', body.schema, fields.body) })) : (_jsx(BodyInput, { field: body.schema }))) : null] }));
|
|
140
126
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
active: {
|
|
144
|
-
true: 'bg-fd-primary/10 text-fd-primary',
|
|
145
|
-
false: 'text-fd-muted-foreground',
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
function BodyInput({ field }) {
|
|
127
|
+
function BodyInput({ field: _field }) {
|
|
128
|
+
const field = useResolvedSchema(_field);
|
|
150
129
|
const [isJson, setIsJson] = useState(false);
|
|
151
|
-
return (
|
|
130
|
+
return (_jsx(CollapsiblePanel, { title: "Body", children: isJson ? (_jsx(JsonInput, { fieldName: "body", children: _jsx("button", { className: cn(buttonVariants({
|
|
131
|
+
color: 'ghost',
|
|
132
|
+
size: 'sm',
|
|
133
|
+
className: 'p-2',
|
|
134
|
+
})), onClick: () => setIsJson(false), type: "button", children: "Close JSON Editor" }) })) : (_jsx(FieldSet, { field: field, fieldName: "body", name: _jsx("button", { className: cn(buttonVariants({
|
|
135
|
+
color: 'secondary',
|
|
136
|
+
size: 'sm',
|
|
137
|
+
className: 'p-2',
|
|
138
|
+
})), onClick: () => setIsJson(true), type: "button", children: "Open JSON Editor" }) })) }));
|
|
152
139
|
}
|
|
153
140
|
function renderCustomField(fieldName, info, field, key) {
|
|
154
141
|
return (_jsx(Controller, {
|
|
155
142
|
// @ts-expect-error we use string here
|
|
156
143
|
render: (props) => field.render({ ...props, info }), name: fieldName }, key));
|
|
157
144
|
}
|
|
158
|
-
|
|
145
|
+
const OauthDialog = lazy(() => import('./auth/oauth-dialog.js').then((mod) => ({
|
|
146
|
+
default: mod.OauthDialog,
|
|
147
|
+
})));
|
|
148
|
+
const OauthDialogTrigger = lazy(() => import('./auth/oauth-dialog.js').then((mod) => ({
|
|
149
|
+
default: mod.OauthDialogTrigger,
|
|
150
|
+
})));
|
|
151
|
+
function AuthFooter({ authorization }) {
|
|
159
152
|
const form = useFormContext();
|
|
160
|
-
if (
|
|
161
|
-
return
|
|
153
|
+
if (authorization.type !== 'oauth2')
|
|
154
|
+
return;
|
|
162
155
|
// only the first one, so it looks simpler :)
|
|
163
156
|
const flow = Object.keys(authorization.flows)[0];
|
|
164
|
-
return (_jsx(OauthDialog, { flow: flow, scheme: authorization, setToken: (token) => form.setValue('authorization', `Bearer ${token}`), children:
|
|
157
|
+
return (_jsx(OauthDialog, { flow: flow, scheme: authorization, setToken: (token) => form.setValue('authorization', `Bearer ${token}`), children: _jsx(OauthDialogTrigger, { type: "button", className: cn(buttonVariants({
|
|
158
|
+
color: 'secondary',
|
|
159
|
+
})), children: "Auth Settings" }) }));
|
|
165
160
|
}
|
|
166
161
|
function Route({ route, ...props }) {
|
|
167
162
|
const segments = route.split('/').filter((part) => part.length > 0);
|
|
@@ -170,7 +165,7 @@ function Route({ route, ...props }) {
|
|
|
170
165
|
function DefaultResultDisplay({ data }) {
|
|
171
166
|
const statusInfo = useMemo(() => getStatusInfo(data.status), [data.status]);
|
|
172
167
|
const { shikiOptions } = useApiContext();
|
|
173
|
-
return (_jsxs("div", { className: "flex flex-col gap-3
|
|
168
|
+
return (_jsxs("div", { className: "flex flex-col gap-3 border-t p-3", children: [_jsxs("div", { className: "inline-flex items-center gap-1.5 text-sm font-medium text-fd-foreground", children: [_jsx(statusInfo.icon, { className: cn('size-4', statusInfo.color) }), statusInfo.description] }), _jsx("p", { className: "text-sm text-fd-muted-foreground", children: data.status }), data.data ? (_jsx(DynamicCodeBlock, { lang: typeof data.data === 'string' && data.data.length > 50000
|
|
174
169
|
? 'text'
|
|
175
170
|
: data.type, code: typeof data.data === 'string'
|
|
176
171
|
? data.data
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function getDefaultValue(
|
|
1
|
+
import type { RequestSchema } from '../playground/index.js';
|
|
2
|
+
export declare function getDefaultValue(schema: RequestSchema): unknown;
|
|
3
3
|
//# sourceMappingURL=get-default-values.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-default-values.d.ts","sourceRoot":"","sources":["../../src/playground/get-default-values.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"get-default-values.d.ts","sourceRoot":"","sources":["../../src/playground/get-default-values.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CA2B9D"}
|
|
@@ -1,28 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (
|
|
6
|
-
return
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (
|
|
1
|
+
export function getDefaultValue(schema) {
|
|
2
|
+
if (typeof schema === 'boolean')
|
|
3
|
+
return null;
|
|
4
|
+
const type = schema.type;
|
|
5
|
+
if (Array.isArray(type))
|
|
6
|
+
return getDefaultValue({
|
|
7
|
+
...schema,
|
|
8
|
+
type: type[0],
|
|
9
|
+
});
|
|
10
|
+
if (type === 'object' && typeof schema === 'object')
|
|
11
|
+
return Object.fromEntries(Object.entries(schema.properties ?? {}).map(([key, prop]) => {
|
|
12
|
+
return [key, getDefaultValue(prop)];
|
|
13
|
+
}));
|
|
14
|
+
if (type === 'array')
|
|
11
15
|
return [];
|
|
12
|
-
if (
|
|
16
|
+
if (type === 'null')
|
|
13
17
|
return null;
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return '';
|
|
18
|
-
return getDefaultValue(resolve(first, references), references);
|
|
19
|
-
}
|
|
20
|
-
if (item.type === 'file')
|
|
21
|
-
return undefined;
|
|
22
|
-
if (item.type === 'string')
|
|
18
|
+
if (type === 'string') {
|
|
19
|
+
if (typeof schema === 'object' && schema.format === 'binary')
|
|
20
|
+
return undefined;
|
|
23
21
|
return '';
|
|
24
|
-
|
|
22
|
+
}
|
|
23
|
+
if (type === 'number' || type === 'integer')
|
|
25
24
|
return 0;
|
|
26
|
-
if (
|
|
25
|
+
if (type === 'boolean')
|
|
27
26
|
return false;
|
|
28
27
|
}
|
|
@@ -1,47 +1,13 @@
|
|
|
1
1
|
import type { MethodInformation, RenderContext } from '../types.js';
|
|
2
|
+
import { type ParsedSchema } from '../utils/schema.js';
|
|
2
3
|
import { type ClientProps } from './client.js';
|
|
3
|
-
|
|
4
|
-
description?: string;
|
|
5
|
-
isRequired: boolean;
|
|
6
|
-
}
|
|
7
|
-
export type ParameterField = (PrimitiveSchema | ArraySchema) & {
|
|
4
|
+
export type ParameterField = {
|
|
8
5
|
name: string;
|
|
9
6
|
description?: string;
|
|
7
|
+
schema: ParsedSchema;
|
|
10
8
|
in: 'cookie' | 'header' | 'query' | 'path';
|
|
11
9
|
};
|
|
12
|
-
|
|
13
|
-
type: 'boolean' | 'string' | 'number';
|
|
14
|
-
}
|
|
15
|
-
export interface ReferenceSchema extends BaseSchema {
|
|
16
|
-
type: 'ref';
|
|
17
|
-
schema: string;
|
|
18
|
-
}
|
|
19
|
-
interface ArraySchema extends BaseSchema {
|
|
20
|
-
type: 'array';
|
|
21
|
-
/**
|
|
22
|
-
* Reference to item schema or the schema
|
|
23
|
-
*/
|
|
24
|
-
items: string | RequestSchema;
|
|
25
|
-
}
|
|
26
|
-
interface FileSchema extends BaseSchema {
|
|
27
|
-
type: 'file';
|
|
28
|
-
}
|
|
29
|
-
interface ObjectSchema extends BaseSchema {
|
|
30
|
-
type: 'object';
|
|
31
|
-
properties: Record<string, RequestSchema | ReferenceSchema>;
|
|
32
|
-
/**
|
|
33
|
-
* Reference to schema, or true if it's `any`
|
|
34
|
-
*/
|
|
35
|
-
additionalProperties?: boolean | string;
|
|
36
|
-
}
|
|
37
|
-
interface SwitcherSchema extends BaseSchema {
|
|
38
|
-
type: 'switcher';
|
|
39
|
-
items: Record<string, ReferenceSchema | RequestSchema>;
|
|
40
|
-
}
|
|
41
|
-
interface NullSchema extends BaseSchema {
|
|
42
|
-
type: 'null';
|
|
43
|
-
}
|
|
44
|
-
export type RequestSchema = PrimitiveSchema | ArraySchema | ObjectSchema | SwitcherSchema | NullSchema | FileSchema;
|
|
10
|
+
export type RequestSchema = ParsedSchema;
|
|
45
11
|
export interface APIPlaygroundProps {
|
|
46
12
|
path: string;
|
|
47
13
|
method: MethodInformation;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/playground/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/playground/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,EAAE,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;AAUzC,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;IAC1B,GAAG,EAAE,aAAa,CAAC;IAEnB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;CAC/B;AAED,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEzD,wBAAsB,aAAa,CAAC,EAClC,IAAI,EACJ,MAAM,EACN,GAAG,EACH,MAAM,GACP,EAAE,kBAAkB,oDAyCpB"}
|