fumadocs-openapi 10.4.1 → 10.6.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/css/generated/shared.css +34 -22
- package/dist/generate-file.d.ts +21 -3
- package/dist/generate-file.d.ts.map +1 -1
- package/dist/generate-file.js +74 -28
- package/dist/generate-file.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/playground/client.d.ts +27 -7
- package/dist/playground/client.d.ts.map +1 -1
- package/dist/playground/client.js +51 -44
- package/dist/playground/client.js.map +1 -1
- package/dist/playground/components/inputs.js +1 -1
- package/dist/playground/components/inputs.js.map +1 -1
- package/dist/playground/components/server-select.js +3 -4
- package/dist/playground/components/server-select.js.map +1 -1
- package/dist/playground/index.d.ts +1 -1
- package/dist/playground/index.d.ts.map +1 -1
- package/dist/playground/index.js +2 -2
- package/dist/playground/index.js.map +1 -1
- package/dist/playground/schema.d.ts +0 -1
- package/dist/playground/schema.d.ts.map +1 -1
- package/dist/playground/schema.js +11 -13
- package/dist/playground/schema.js.map +1 -1
- package/dist/requests/generators/python.d.ts +2 -1
- package/dist/requests/generators/python.d.ts.map +1 -1
- package/dist/requests/generators/python.js +13 -2
- package/dist/requests/generators/python.js.map +1 -1
- package/dist/requests/media/adapter.js +1 -1
- package/dist/requests/string-utils.js +1 -1
- package/dist/scalar/index.d.ts +2 -1
- package/dist/scalar/index.d.ts.map +1 -1
- package/dist/server/create.d.ts +2 -0
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/create.js +11 -8
- package/dist/server/create.js.map +1 -1
- package/dist/server/source-api.d.ts +9 -3
- package/dist/server/source-api.d.ts.map +1 -1
- package/dist/server/source-api.js +65 -6
- package/dist/server/source-api.js.map +1 -1
- package/dist/types.d.ts +2 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/api-page.d.ts +2 -2
- package/dist/ui/api-page.d.ts.map +1 -1
- package/dist/ui/api-page.js +4 -6
- package/dist/ui/api-page.js.map +1 -1
- package/dist/ui/base.d.ts +20 -16
- package/dist/ui/base.d.ts.map +1 -1
- package/dist/ui/base.js +18 -9
- package/dist/ui/base.js.map +1 -1
- package/dist/ui/{full.client.js → client/full.js} +3 -3
- package/dist/ui/client/full.js.map +1 -0
- package/dist/ui/client/index.d.ts +1 -1
- package/dist/ui/client/index.js.map +1 -1
- package/dist/ui/client/storage-key.js.map +1 -1
- package/dist/ui/components/server-tab.js +43 -0
- package/dist/ui/components/server-tab.js.map +1 -0
- package/dist/ui/contexts/api.js +18 -35
- package/dist/ui/contexts/api.js.map +1 -1
- package/dist/ui/create-client.d.ts +26 -0
- package/dist/ui/create-client.d.ts.map +1 -0
- package/dist/ui/create-client.js +132 -0
- package/dist/ui/create-client.js.map +1 -0
- package/dist/ui/index.d.ts +10 -2
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +21 -1
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/operation/client.js +44 -36
- package/dist/ui/operation/client.js.map +1 -1
- package/dist/ui/operation/{request-tabs.d.ts → get-example-requests.d.ts} +2 -3
- package/dist/ui/operation/get-example-requests.d.ts.map +1 -0
- package/dist/ui/operation/get-example-requests.js +83 -0
- package/dist/ui/operation/get-example-requests.js.map +1 -0
- package/dist/ui/operation/index.js +101 -63
- package/dist/ui/operation/index.js.map +1 -1
- package/dist/ui/operation/request-tabs.js +3 -81
- package/dist/ui/operation/request-tabs.js.map +1 -1
- package/dist/ui/operation/response-tabs.d.ts +1 -1
- package/dist/ui/operation/response-tabs.js +57 -54
- package/dist/ui/operation/response-tabs.js.map +1 -1
- package/dist/ui/operation/usage-tabs/client.js +7 -48
- package/dist/ui/operation/usage-tabs/client.js.map +1 -1
- package/dist/ui/operation/usage-tabs/index.js +14 -10
- package/dist/ui/operation/usage-tabs/index.js.map +1 -1
- package/dist/ui/operation/usage-tabs/lazy.js +1 -2
- package/dist/ui/operation/usage-tabs/lazy.js.map +1 -1
- package/dist/ui/schema/client.d.ts +1 -0
- package/dist/ui/schema/client.d.ts.map +1 -1
- package/dist/ui/schema/index.d.ts +2 -1
- package/dist/ui/schema/index.d.ts.map +1 -1
- package/dist/ui/schema/index.js +4 -2
- package/dist/ui/schema/index.js.map +1 -1
- package/dist/utils/pages/builder.d.ts +10 -11
- package/dist/utils/pages/builder.d.ts.map +1 -1
- package/dist/utils/pages/builder.js +30 -31
- package/dist/utils/pages/builder.js.map +1 -1
- package/dist/utils/pages/preset-auto.d.ts +6 -5
- package/dist/utils/pages/preset-auto.d.ts.map +1 -1
- package/dist/utils/pages/preset-auto.js +97 -35
- package/dist/utils/pages/preset-auto.js.map +1 -1
- package/dist/utils/pages/to-text.d.ts.map +1 -1
- package/dist/utils/pages/to-text.js +4 -12
- package/dist/utils/pages/to-text.js.map +1 -1
- package/dist/utils/process-document.d.ts +1 -1
- package/dist/utils/process-document.js +1 -32
- package/dist/utils/process-document.js.map +1 -1
- package/dist/utils/schema/dereference.js +37 -0
- package/dist/utils/schema/dereference.js.map +1 -0
- package/dist/utils/{schema.d.ts → schema/index.d.ts} +3 -3
- package/dist/utils/schema/index.d.ts.map +1 -0
- package/dist/utils/{schema.js → schema/index.js} +3 -3
- package/dist/utils/schema/index.js.map +1 -0
- package/dist/utils/schema/resolve-ref.js +21 -0
- package/dist/utils/schema/resolve-ref.js.map +1 -0
- package/dist/utils/{schema-to-string.js → schema/to-string.js} +2 -2
- package/dist/utils/schema/to-string.js.map +1 -0
- package/package.json +10 -9
- package/dist/requests/to-python-object.js +0 -17
- package/dist/requests/to-python-object.js.map +0 -1
- package/dist/ui/full.client.js.map +0 -1
- package/dist/ui/full.d.ts +0 -11
- package/dist/ui/full.d.ts.map +0 -1
- package/dist/ui/full.js +0 -36
- package/dist/ui/full.js.map +0 -1
- package/dist/ui/operation/request-tabs.d.ts.map +0 -1
- package/dist/utils/pages/to-body.js +0 -22
- package/dist/utils/pages/to-body.js.map +0 -1
- package/dist/utils/schema-to-string.js.map +0 -1
- package/dist/utils/schema.d.ts.map +0 -1
- package/dist/utils/schema.js.map +0 -1
- /package/dist/utils/{schema-to-string.d.ts → schema/to-string.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-select.js","names":[],"sources":["../../../src/playground/components/server-select.tsx"],"sourcesContent":["'use client';\nimport { useServerContext
|
|
1
|
+
{"version":3,"file":"server-select.js","names":[],"sources":["../../../src/playground/components/server-select.tsx"],"sourcesContent":["'use client';\nimport { useServerContext } from '@/ui/contexts/api';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/ui/components/select';\nimport { Input, labelVariants } from '@/ui/components/input';\nimport { useEffect, useState, useRef, type ComponentProps } from 'react';\nimport { cn } from '@/utils/cn';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/ui/components/dialog';\nimport { resolveServerUrl, withBase } from '@/utils/url';\nimport type { ServerVariableObject } from '@/types';\nimport type { NoReference } from '@/utils/schema';\nimport { StfProvider, useFieldValue, useListener, useStf } from '@fumari/stf';\nimport { EditIcon } from 'lucide-react';\nimport { useTranslations } from '@/ui/client/i18n';\n\nexport default function ServerSelect(props: ComponentProps<typeof DialogTrigger>) {\n const { servers, server, setServer, setServerVariables } = useServerContext();\n const [open, setOpen] = useState(false);\n const [isMounted, setIsMounted] = useState(false);\n const t = useTranslations();\n\n useEffect(() => {\n setIsMounted(true);\n }, []);\n\n if (!servers || servers.length <= 0) return;\n const serverSchema = server ? servers.find((obj) => obj.url === server.url) : null;\n\n return (\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogTrigger\n {...props}\n className={cn(\n 'flex items-center gap-2 text-sm text-start px-3 py-2 bg-fd-muted text-fd-muted-foreground transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground',\n props.className,\n )}\n >\n <span className=\"px-2 py-0.5 -ms-2 font-medium rounded-lg border bg-fd-secondary text-fd-secondary-foreground shadow-sm\">\n {server?.name ?? t.serverUrl}\n </span>\n <code className=\"truncate min-w-0 flex-1\">\n {isMounted\n ? withBase(\n server ? resolveServerUrl(server.url, server.variables) : '/',\n window.location.origin,\n )\n : t.loading}\n </code>\n <EditIcon className=\"size-4\" />\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{t.serverUrl}</DialogTitle>\n <DialogDescription>{t.serverUrlDescription}</DialogDescription>\n </DialogHeader>\n <Select value={server?.url} onValueChange={setServer}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {servers.map((item) => (\n <SelectItem key={item.url} value={item.url!}>\n <code className=\"text-[0.8125rem]\">{item.url}</code>\n <p className=\"text-fd-muted-foreground\">{item.description}</p>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {server?.variables && serverSchema?.variables && (\n <ServerSelectContent\n key={server.url}\n defaultValues={server.variables}\n schema={serverSchema.variables}\n onChange={setServerVariables}\n />\n )}\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction ServerSelectContent({\n defaultValues,\n onChange,\n schema,\n}: {\n defaultValues: Record<string, string>;\n onChange: (values: Record<string, string>) => void;\n schema: Record<string, NoReference<ServerVariableObject>>;\n}) {\n const stf = useStf({\n defaultValues: () => structuredClone(defaultValues),\n });\n const timerRef = useRef<number | null>(null);\n useListener({\n stf,\n onUpdate() {\n if (timerRef.current !== null) window.clearTimeout(timerRef.current);\n\n timerRef.current = window.setTimeout(\n () => onChange(stf.dataEngine.getData() as Record<string, string>),\n 500,\n );\n },\n });\n\n return (\n <StfProvider value={stf}>\n <div className=\"flex flex-col gap-4\">\n {Object.entries(schema).map(([key, variable]) => {\n return (\n <fieldset key={key} className=\"flex flex-col gap-1\">\n <label className={cn(labelVariants())} htmlFor={key}>\n {key}\n </label>\n <p className=\"text-xs text-fd-muted-foreground empty:hidden\">\n {variable.description}\n </p>\n <Field fieldName={key} variable={variable} />\n </fieldset>\n );\n })}\n </div>\n </StfProvider>\n );\n}\n\nfunction Field({\n fieldName,\n variable,\n}: {\n variable: NoReference<ServerVariableObject>;\n fieldName: string;\n}) {\n const t = useTranslations();\n const [value, setValue] = useFieldValue([fieldName], {\n compute(currentValue) {\n return typeof currentValue === 'string' ? currentValue : undefined;\n },\n });\n\n if (variable.enum) {\n return (\n <Select value={value} onValueChange={setValue}>\n <SelectTrigger id={fieldName}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {variable.enum.map((value) => (\n <SelectItem key={value} value={String(value)}>\n {value}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n }\n\n return (\n <Input\n id={fieldName}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n placeholder={t.serverUrlFieldPlaceholder}\n />\n );\n}\n"],"mappings":"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"}
|
|
@@ -16,7 +16,7 @@ declare function APIPlayground({
|
|
|
16
16
|
path,
|
|
17
17
|
method,
|
|
18
18
|
ctx
|
|
19
|
-
}: APIPlaygroundProps):
|
|
19
|
+
}: APIPlaygroundProps): string | number | bigint | boolean | react_jsx_runtime0.JSX.Element | Iterable<react.ReactNode> | Promise<react.ReactNode> | null | undefined;
|
|
20
20
|
//#endregion
|
|
21
21
|
export { APIPlayground, APIPlaygroundProps, SecurityEntry };
|
|
22
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/playground/index.tsx"],"mappings":";;;;;UAiBiB,kBAAA;EACf,IAAA;EACA,MAAA,EAAQ,iBAAA;EACR,GAAA,EAAK,aAAA;AAAA;AAAA,KAGK,aAAA,GAAgB,oBAAA;EAC1B,MAAA;EACA,EAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/playground/index.tsx"],"mappings":";;;;;UAiBiB,kBAAA;EACf,IAAA;EACA,MAAA,EAAQ,iBAAA;EACR,GAAA,EAAK,aAAA;AAAA;AAAA,KAGK,aAAA,GAAgB,oBAAA;EAC1B,MAAA;EACA,EAAA;AAAA;AAAA,iBAGc,aAAA,CAAA;EAAgB,IAAA;EAAM,MAAA;EAAQ;AAAA,GAAO,kBAAA,wCAAkB,kBAAA,CAAA,GAAA,CAAA,OAAA,GAAA,QAAA,CAAA,KAAA,CAAA,SAAA,IAAA,OAAA,CAAA,KAAA,CAAA,SAAA"}
|
package/dist/playground/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { getPreferredType } from "../utils/schema.js";
|
|
1
|
+
import { getPreferredType } from "../utils/schema/index.js";
|
|
2
2
|
import { ClientLazy } from "./lazy.js";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
//#region src/playground/index.tsx
|
|
5
|
-
|
|
5
|
+
function APIPlayground({ path, method, ctx }) {
|
|
6
6
|
if (ctx.playground?.render) return ctx.playground.render({
|
|
7
7
|
path,
|
|
8
8
|
method,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/playground/index.tsx"],"sourcesContent":["import type {\n MediaTypeObject,\n MethodInformation,\n ParameterObject,\n RenderContext,\n SecuritySchemeObject,\n} from '@/types';\nimport { getPreferredType, NoReference, type ParsedSchema } from '@/utils/schema';\nimport { type PlaygroundClientProps } from './client';\nimport { ClientLazy } from './lazy';\n\ninterface Context {\n references: Record<string, ParsedSchema>;\n registered: WeakMap<Exclude<ParsedSchema, boolean>, string>;\n id: (schema?: object) => string;\n}\n\nexport interface APIPlaygroundProps {\n path: string;\n method: MethodInformation;\n ctx: RenderContext;\n}\n\nexport type SecurityEntry = SecuritySchemeObject & {\n scopes: string[];\n id: string;\n};\n\nexport
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/playground/index.tsx"],"sourcesContent":["import type {\n MediaTypeObject,\n MethodInformation,\n ParameterObject,\n RenderContext,\n SecuritySchemeObject,\n} from '@/types';\nimport { getPreferredType, NoReference, type ParsedSchema } from '@/utils/schema';\nimport { type PlaygroundClientProps } from './client';\nimport { ClientLazy } from './lazy';\n\ninterface Context {\n references: Record<string, ParsedSchema>;\n registered: WeakMap<Exclude<ParsedSchema, boolean>, string>;\n id: (schema?: object) => string;\n}\n\nexport interface APIPlaygroundProps {\n path: string;\n method: MethodInformation;\n ctx: RenderContext;\n}\n\nexport type SecurityEntry = SecuritySchemeObject & {\n scopes: string[];\n id: string;\n};\n\nexport function APIPlayground({ path, method, ctx }: APIPlaygroundProps) {\n if (ctx.playground?.render) {\n return ctx.playground.render({ path, method, ctx });\n }\n\n const bodyContent = method.requestBody?.content;\n const mediaType = bodyContent ? getPreferredType(bodyContent) : undefined;\n const takenIds = new Map<string, number>();\n\n const context: Context = {\n references: {},\n id(schema) {\n let name = 'r';\n if (schema) {\n const ref = ctx.schema.getRawRef(schema)?.split('/');\n if (ref && ref.length > 0) name = ref[ref.length - 1];\n }\n\n const count = takenIds.get(name) ?? 0;\n takenIds.set(name, count + 1);\n return count === 0 ? name : `${name}${count}`;\n },\n registered: new WeakMap(),\n };\n\n const props: PlaygroundClientProps = {\n securities: parseSecurities(method, ctx),\n method: method.method,\n route: path,\n parameters: method.parameters?.map((param: NoReference<ParameterObject>): ParameterObject => {\n if (param.schema !== undefined) {\n return {\n ...param,\n schema: writeReferences(param.schema, context),\n } as ParameterObject;\n }\n\n if (param.content !== undefined) {\n const content: Record<string, MediaTypeObject> = {};\n\n for (const k in param.content) {\n const original = param.content[k] as NoReference<MediaTypeObject>;\n if (!original || original.schema === undefined) continue;\n\n content[k] = {\n ...original,\n schema: writeReferences(original.schema, context),\n } as MediaTypeObject;\n }\n\n return {\n ...param,\n content,\n } as ParameterObject;\n }\n\n return param;\n }),\n body:\n bodyContent && mediaType\n ? ({\n schema: writeReferences(bodyContent[mediaType].schema as ParsedSchema, context),\n mediaType,\n } as PlaygroundClientProps['body'])\n : undefined,\n references: context.references,\n proxyUrl: ctx.proxyUrl,\n writeOnly: true,\n readOnly: false,\n };\n\n return <ClientLazy {...props} />;\n}\n\nfunction writeReferences(\n schema: ParsedSchema,\n ctx: Context,\n stack: WeakMap<object, object> = new WeakMap(),\n): ParsedSchema {\n if (typeof schema !== 'object' || !schema) return schema;\n if (stack.has(schema)) {\n const out = stack.get(schema)!;\n const id = ctx.id(schema);\n ctx.references[id] = out;\n\n return {\n $ref: `#/${id}`,\n };\n }\n\n const output = { ...schema };\n stack.set(schema, output);\n for (const _n in output) {\n const name = _n as keyof typeof output;\n if (!output[name]) continue;\n\n switch (name) {\n case 'oneOf':\n case 'allOf':\n case 'anyOf':\n output[name] = output[name].map((item) => writeReferences(item, ctx, stack));\n continue;\n case 'items':\n case 'additionalProperties':\n case 'not':\n output[name] = writeReferences(output[name], ctx, stack);\n continue;\n case 'properties':\n case 'patternProperties':\n output[name] = { ...output[name] };\n\n for (const key in output[name]) {\n output[name][key] = writeReferences(output[name][key], ctx, stack);\n }\n }\n }\n\n return output;\n}\n\nfunction parseSecurities(\n method: MethodInformation,\n { schema: { dereferenced } }: RenderContext,\n): PlaygroundClientProps['securities'] {\n const result: PlaygroundClientProps['securities'] = [];\n const security = method.security ?? dereferenced.security ?? [];\n if (security.length === 0) return result;\n\n for (const map of security) {\n const list: PlaygroundClientProps['securities'][number] = [];\n\n for (const [key, scopes] of Object.entries(map)) {\n const scheme = dereferenced.components?.securitySchemes?.[key];\n if (!scheme) continue;\n\n list.push({\n ...scheme,\n scopes,\n id: key,\n });\n }\n\n if (list.length > 0) result.push(list);\n }\n\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","names":[],"sources":["../../src/playground/schema.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.d.ts","names":[],"sources":["../../src/playground/schema.tsx"],"mappings":";;;;UAeiB,WAAA;;;;EAIf,SAAA;;;;EAKA,QAAA;AAAA"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { mergeAllOf } from "../utils/merge-schema.js";
|
|
2
|
-
import { schemaToString } from "../utils/schema
|
|
2
|
+
import { schemaToString } from "../utils/schema/to-string.js";
|
|
3
|
+
import { resolveRefSync } from "../utils/schema/resolve-ref.js";
|
|
3
4
|
import { createContext, use, useMemo } from "react";
|
|
4
5
|
import { jsx } from "react/jsx-runtime";
|
|
5
|
-
import { Ajv2020 } from "ajv/dist/2020";
|
|
6
|
+
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
6
7
|
import { useDataEngine, useFieldValue, useNamespace } from "@fumari/stf";
|
|
7
8
|
import { stringifyFieldKey } from "@fumari/stf/lib/utils";
|
|
8
9
|
import { sample } from "openapi-sampler";
|
|
@@ -129,24 +130,21 @@ function useResolvedSchema(raw) {
|
|
|
129
130
|
return useMemo(() => {
|
|
130
131
|
const schema = dereference(raw, references);
|
|
131
132
|
if (typeof schema === "boolean") return anyFields;
|
|
132
|
-
if (schema.allOf)
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
if (schema.allOf) {
|
|
134
|
+
const merged = mergeAllOf(schema, { dereference(schema) {
|
|
135
|
+
return dereference(schema, references);
|
|
136
|
+
} });
|
|
137
|
+
if (typeof merged === "boolean") return anyFields;
|
|
138
|
+
return merged;
|
|
139
|
+
}
|
|
135
140
|
return schema;
|
|
136
141
|
}, [raw, references]);
|
|
137
142
|
}
|
|
138
143
|
function dereference(schema, references) {
|
|
139
144
|
if (typeof schema === "boolean") return schema;
|
|
140
|
-
|
|
141
|
-
if (ref) {
|
|
142
|
-
if (ref.startsWith("#/")) ref = ref.slice(2);
|
|
143
|
-
if (ref in references) return references[ref];
|
|
144
|
-
}
|
|
145
|
+
if (schema.$ref) return resolveRefSync(schema.$ref, references);
|
|
145
146
|
return schema;
|
|
146
147
|
}
|
|
147
|
-
function fallbackAny(schema) {
|
|
148
|
-
return typeof schema === "boolean" ? anyFields : schema;
|
|
149
|
-
}
|
|
150
148
|
function getUnion(schema) {
|
|
151
149
|
if (schema.anyOf) return [schema.anyOf, "anyOf"];
|
|
152
150
|
if (schema.oneOf) return [schema.oneOf, "oneOf"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","names":[],"sources":["../../src/playground/schema.tsx"],"sourcesContent":["import { Ajv2020 } from 'ajv/dist/2020';\nimport { createContext, ReactNode, use, useMemo } from 'react';\nimport type { ParsedSchema, ResolvedSchema } from '@/utils/schema';\nimport { mergeAllOf } from '@/utils/merge-schema';\nimport { FieldKey, useDataEngine, useFieldValue, useNamespace } from '@fumari/stf';\nimport { stringifyFieldKey } from '@fumari/stf/lib/utils';\nimport { sample } from 'openapi-sampler';\nimport { FormatFlags, schemaToString } from '@/utils/schema
|
|
1
|
+
{"version":3,"file":"schema.js","names":[],"sources":["../../src/playground/schema.tsx"],"sourcesContent":["import { Ajv2020 } from 'ajv/dist/2020';\nimport { createContext, ReactNode, use, useMemo } from 'react';\nimport type { ParsedSchema, ResolvedSchema } from '@/utils/schema';\nimport { mergeAllOf } from '@/utils/merge-schema';\nimport { FieldKey, useDataEngine, useFieldValue, useNamespace } from '@fumari/stf';\nimport { stringifyFieldKey } from '@fumari/stf/lib/utils';\nimport { sample } from 'openapi-sampler';\nimport { FormatFlags, schemaToString } from '@/utils/schema/to-string';\nimport { resolveRefSync } from '@/utils/schema/resolve-ref';\n\ninterface SchemaContextType extends SchemaScope {\n references: Record<string, ParsedSchema>;\n ajv: Ajv2020;\n}\n\nexport interface SchemaScope {\n /**\n * show write only fields\n */\n writeOnly: boolean;\n\n /**\n * show read only fields\n */\n readOnly: boolean;\n}\n\ntype UnionField = 'anyOf' | 'oneOf';\n\nexport interface FieldInfo {\n selectedType?: string;\n oneOf: number;\n\n /**\n * The actual field that represents union members.\n */\n unionField?: UnionField;\n}\n\nconst SchemaContext = createContext<SchemaContextType | undefined>(undefined);\nexport const anyFields = {\n type: ['string', 'number', 'boolean', 'array', 'object'],\n items: true,\n additionalProperties: true,\n} satisfies ParsedSchema;\n\nexport function SchemaProvider({\n references,\n readOnly,\n writeOnly,\n children,\n}: Omit<SchemaContextType, 'ajv'> & { children: ReactNode }) {\n const ajv = useMemo(\n () =>\n new Ajv2020({\n strict: false,\n validateSchema: false,\n validateFormats: false,\n }),\n [],\n );\n\n return (\n <SchemaContext.Provider\n value={useMemo(\n () => ({ references, ajv, readOnly, writeOnly }),\n [references, ajv, readOnly, writeOnly],\n )}\n >\n {children}\n </SchemaContext.Provider>\n );\n}\n\nexport function useSchemaScope(): SchemaScope {\n return use(SchemaContext)!;\n}\n\n/**\n * A hook to store dynamic info of a field, such as selected schema of `oneOf`.\n *\n * @param fieldName - field name of form.\n * @param schema - The **resolved** JSON Schema to generate initial values.\n * @param depth - The depth to avoid duplicated field name with same schema (e.g. nested `oneOf`).\n */\nexport function useFieldInfo(\n fieldName: FieldKey,\n schema: Exclude<ParsedSchema, boolean>,\n depth = 0,\n): {\n info: FieldInfo;\n schema: Exclude<ParsedSchema, boolean>;\n updateInfo: (value: Partial<FieldInfo>) => void;\n} {\n const { ajv, references } = use(SchemaContext)!;\n const engine = useDataEngine();\n const { generateDefault } = useSchemaUtils();\n const fieldData = useNamespace({\n namespace: `field-info:${depth}:${stringifyFieldKey(fieldName)}`,\n initial(): FieldInfo {\n const value = engine.get(fieldName);\n const out: FieldInfo = {\n oneOf: -1,\n };\n const union = getUnion(schema);\n if (union) {\n const [members, field] = union;\n\n out.oneOf = members.findIndex((item) =>\n ajv.validate(typeof item === 'object' ? { ...item, ...references } : item, value),\n );\n if (out.oneOf === -1) out.oneOf = 0;\n out.unionField = field;\n }\n\n if (Array.isArray(schema.type)) {\n const types = schema.type;\n\n out.selectedType =\n types.find((type) => {\n return ajv.validate({ ...schema, ...references, type }, value);\n }) ?? types[0];\n }\n\n return out;\n },\n });\n const [info, setInfo] = useFieldValue<FieldInfo>([], {\n stf: fieldData,\n });\n\n return {\n info,\n schema,\n updateInfo(value) {\n const updated = {\n ...info,\n ...value,\n };\n\n if (updated.oneOf === info.oneOf && updated.selectedType === info.selectedType) return;\n\n setInfo(updated);\n\n let valueSchema: ParsedSchema = schema;\n if (updated.unionField) {\n valueSchema = schema[updated.unionField]![updated.oneOf];\n } else if (updated.selectedType) {\n // must remove to `examples` to avoid invalid default values\n valueSchema = { ...schema, type: updated.selectedType, examples: undefined };\n }\n\n engine.update(fieldName, generateDefault(valueSchema));\n },\n };\n}\n\nexport function useSchemaUtils() {\n const { references } = use(SchemaContext)!;\n\n return {\n generateDefault(schema: ParsedSchema): unknown {\n return sample(\n schema as never,\n { skipNonRequired: true, skipReadOnly: true, quiet: true },\n references,\n );\n },\n schemaToString(value: ResolvedSchema, flags?: FormatFlags) {\n return schemaToString(\n value,\n (s) => ({ dereferenced: dereference(s, references), raw: s }),\n flags,\n );\n },\n };\n}\n\n/**\n * resolve $ref & merge `allOf`.\n */\nexport function useResolvedSchema(raw: ParsedSchema): Exclude<ParsedSchema, boolean> {\n const { references } = use(SchemaContext)!;\n\n return useMemo(() => {\n const schema = dereference(raw, references);\n if (typeof schema === 'boolean') return anyFields;\n\n if (schema.allOf) {\n const merged = mergeAllOf(schema, {\n dereference(schema) {\n return dereference(schema, references);\n },\n });\n if (typeof merged === 'boolean') return anyFields;\n return merged;\n }\n\n return schema;\n }, [raw, references]);\n}\n\nfunction dereference(schema: ParsedSchema, references: Record<string, ParsedSchema>): ParsedSchema {\n if (typeof schema === 'boolean') return schema;\n if (schema.$ref) {\n return resolveRefSync(schema.$ref, references) as ParsedSchema;\n }\n\n return schema;\n}\n\nfunction getUnion(\n schema: Exclude<ParsedSchema, boolean>,\n): [readonly ParsedSchema[], UnionField] | undefined {\n if (schema.anyOf) {\n return [schema.anyOf, 'anyOf'];\n }\n\n if (schema.oneOf) return [schema.oneOf, 'oneOf'];\n}\n"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { CodeUsageGenerator } from "./index.js";
|
|
|
2
2
|
|
|
3
3
|
//#region src/requests/generators/python.d.ts
|
|
4
4
|
declare const python: CodeUsageGenerator;
|
|
5
|
+
declare function generatePythonObject(v: unknown, imports: Set<string>): string;
|
|
5
6
|
//#endregion
|
|
6
|
-
export { python };
|
|
7
|
+
export { generatePythonObject, python };
|
|
7
8
|
//# sourceMappingURL=python.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"python.d.ts","names":[],"sources":["../../../src/requests/generators/python.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"python.d.ts","names":[],"sources":["../../../src/requests/generators/python.ts"],"mappings":";;;cAGa,MAAA,EAAQ,kBAAA;AAAA,iBAuDL,oBAAA,CAAqB,CAAA,WAAY,OAAA,EAAS,GAAA"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { resolveMediaAdapter } from "../media/resolve-adapter.js";
|
|
2
2
|
import "../media/adapter.js";
|
|
3
|
-
import { generatePythonObject } from "../to-python-object.js";
|
|
4
3
|
//#region src/requests/generators/python.ts
|
|
5
4
|
const python = {
|
|
6
5
|
label: "Python",
|
|
@@ -34,7 +33,19 @@ response = requests.request(${params.join(", ")})
|
|
|
34
33
|
print(response.text)`;
|
|
35
34
|
}
|
|
36
35
|
};
|
|
36
|
+
function generatePythonObject(v, imports) {
|
|
37
|
+
if (v === null) return "None";
|
|
38
|
+
else if (typeof v === "boolean") return v ? "True" : "False";
|
|
39
|
+
else if (typeof v === "string") return JSON.stringify(v);
|
|
40
|
+
else if (typeof v === "number") return v.toString();
|
|
41
|
+
else if (Array.isArray(v)) return `[${v.map((item) => generatePythonObject(item, imports)).join(", ")}]`;
|
|
42
|
+
else if (v instanceof Date) {
|
|
43
|
+
imports.add("datetime");
|
|
44
|
+
return `datetime.datetime(${v.getFullYear()}, ${v.getMonth() + 1}, ${v.getDate()}, ${v.getHours()}, ${v.getMinutes()}, ${v.getSeconds()}, ${v.getMilliseconds()})`;
|
|
45
|
+
} else if (typeof v === "object") return `{\n${Object.entries(v).map(([key, value]) => ` ${JSON.stringify(key)}: ${generatePythonObject(value, imports)}`).join(", \n")}\n}`;
|
|
46
|
+
else throw new Error(`Unsupported type: ${typeof v}`);
|
|
47
|
+
}
|
|
37
48
|
//#endregion
|
|
38
|
-
export { python };
|
|
49
|
+
export { generatePythonObject, python };
|
|
39
50
|
|
|
40
51
|
//# sourceMappingURL=python.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"python.js","names":[],"sources":["../../../src/requests/generators/python.ts"],"sourcesContent":["import type { CodeUsageGenerator } from '@/requests/generators';\nimport {
|
|
1
|
+
{"version":3,"file":"python.js","names":[],"sources":["../../../src/requests/generators/python.ts"],"sourcesContent":["import type { CodeUsageGenerator } from '@/requests/generators';\nimport { resolveMediaAdapter } from '@/requests/media/adapter';\n\nexport const python: CodeUsageGenerator = {\n label: 'Python',\n lang: 'python',\n generate(url, data, { mediaAdapters }) {\n const headers: Record<string, string> = {};\n const imports = new Set<string>();\n const params = [`\"${data.method}\"`, 'url'];\n let body: string | undefined;\n\n imports.add('requests');\n\n if (data.body && data.bodyMediaType) {\n const adapter = resolveMediaAdapter(data.bodyMediaType, mediaAdapters);\n headers['Content-Type'] = data.bodyMediaType;\n\n body = adapter?.generateExample(data as { body: unknown }, {\n lang: 'python',\n });\n\n if (body) {\n params.push('data = body');\n }\n }\n\n for (const [k, v] of Object.entries(data.header)) {\n headers[k] = v.value;\n }\n\n if (Object.keys(headers).length > 0) {\n params.push(`headers = ${generatePythonObject(headers, imports)}`);\n }\n\n const inputCookies = Object.entries(data.cookie);\n if (inputCookies.length > 0) {\n const cookies: Record<string, string> = {};\n\n for (const [k, v] of inputCookies) {\n cookies[k] = v.value;\n }\n\n params.push(`cookies = ${generatePythonObject(cookies, imports)}`);\n }\n\n return `${Array.from(imports)\n .map((name) => 'import ' + name)\n .join('\\n')}\n\nurl = ${JSON.stringify(url)}\n${body ?? ''}\nresponse = requests.request(${params.join(', ')})\n\nprint(response.text)`;\n },\n};\n\nexport function generatePythonObject(v: unknown, imports: Set<string>): string {\n if (v === null) {\n return 'None';\n } else if (typeof v === 'boolean') {\n return v ? 'True' : 'False';\n } else if (typeof v === 'string') {\n return JSON.stringify(v);\n } else if (typeof v === 'number') {\n return v.toString();\n } else if (Array.isArray(v)) {\n const items = v.map((item) => generatePythonObject(item, imports));\n return `[${items.join(', ')}]`;\n } else if (v instanceof Date) {\n imports.add('datetime');\n return `datetime.datetime(${v.getFullYear()}, ${v.getMonth() + 1}, ${v.getDate()}, ${v.getHours()}, ${v.getMinutes()}, ${v.getSeconds()}, ${v.getMilliseconds()})`;\n } else if (typeof v === 'object') {\n const entries = Object.entries(v).map(\n ([key, value]) => ` ${JSON.stringify(key)}: ${generatePythonObject(value, imports)}`,\n );\n return `{\\n${entries.join(', \\n')}\\n}`;\n } else {\n throw new Error(`Unsupported type: ${typeof v}`);\n }\n}\n"],"mappings":";;;AAGA,MAAa,SAA6B;CACxC,OAAO;CACP,MAAM;CACN,SAAS,KAAK,MAAM,EAAE,iBAAiB;EACrC,MAAM,UAAkC,EAAE;EAC1C,MAAM,0BAAU,IAAI,KAAa;EACjC,MAAM,SAAS,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM;EAC1C,IAAI;AAEJ,UAAQ,IAAI,WAAW;AAEvB,MAAI,KAAK,QAAQ,KAAK,eAAe;GACnC,MAAM,UAAU,oBAAoB,KAAK,eAAe,cAAc;AACtE,WAAQ,kBAAkB,KAAK;AAE/B,UAAO,SAAS,gBAAgB,MAA2B,EACzD,MAAM,UACP,CAAC;AAEF,OAAI,KACF,QAAO,KAAK,cAAc;;AAI9B,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,KAAK,OAAO,CAC9C,SAAQ,KAAK,EAAE;AAGjB,MAAI,OAAO,KAAK,QAAQ,CAAC,SAAS,EAChC,QAAO,KAAK,aAAa,qBAAqB,SAAS,QAAQ,GAAG;EAGpE,MAAM,eAAe,OAAO,QAAQ,KAAK,OAAO;AAChD,MAAI,aAAa,SAAS,GAAG;GAC3B,MAAM,UAAkC,EAAE;AAE1C,QAAK,MAAM,CAAC,GAAG,MAAM,aACnB,SAAQ,KAAK,EAAE;AAGjB,UAAO,KAAK,aAAa,qBAAqB,SAAS,QAAQ,GAAG;;AAGpE,SAAO,GAAG,MAAM,KAAK,QAAQ,CAC1B,KAAK,SAAS,YAAY,KAAK,CAC/B,KAAK,KAAK,CAAC;;QAEV,KAAK,UAAU,IAAI,CAAC;EAC1B,QAAQ,GAAG;8BACiB,OAAO,KAAK,KAAK,CAAC;;;;CAI/C;AAED,SAAgB,qBAAqB,GAAY,SAA8B;AAC7E,KAAI,MAAM,KACR,QAAO;UACE,OAAO,MAAM,UACtB,QAAO,IAAI,SAAS;UACX,OAAO,MAAM,SACtB,QAAO,KAAK,UAAU,EAAE;UACf,OAAO,MAAM,SACtB,QAAO,EAAE,UAAU;UACV,MAAM,QAAQ,EAAE,CAEzB,QAAO,IADO,EAAE,KAAK,SAAS,qBAAqB,MAAM,QAAQ,CAAC,CACjD,KAAK,KAAK,CAAC;UACnB,aAAa,MAAM;AAC5B,UAAQ,IAAI,WAAW;AACvB,SAAO,qBAAqB,EAAE,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,iBAAiB,CAAC;YACvJ,OAAO,MAAM,SAItB,QAAO,MAHS,OAAO,QAAQ,EAAE,CAAC,KAC/B,CAAC,KAAK,WAAW,KAAK,KAAK,UAAU,IAAI,CAAC,IAAI,qBAAqB,OAAO,QAAQ,GACpF,CACoB,KAAK,OAAO,CAAC;KAElC,OAAM,IAAI,MAAM,qBAAqB,OAAO,IAAI"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { escapeString, inputToString } from "../string-utils.js";
|
|
2
2
|
import "./resolve-adapter.js";
|
|
3
|
-
import js2xml from "xml-js/lib/js2xml";
|
|
3
|
+
import js2xml from "xml-js/lib/js2xml.js";
|
|
4
4
|
//#region src/requests/media/adapter.ts
|
|
5
5
|
const defaultAdapters = {
|
|
6
6
|
"application/json": {
|
package/dist/scalar/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/scalar/index.tsx"],"mappings":";;;;;AAuBA
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/scalar/index.tsx"],"mappings":";;;;;AAuBA;;;iBAAgB,UAAA,CAAW,OAAA,GAAS,oBAAA,GAA4B,oBAAA"}
|
package/dist/server/create.d.ts
CHANGED
|
@@ -27,6 +27,8 @@ interface OpenAPIServer {
|
|
|
27
27
|
createProxy: typeof createProxy;
|
|
28
28
|
getSchemas: () => Promise<ProcessedSchemaMap>;
|
|
29
29
|
getSchema: (document: string) => Promise<ProcessedDocument>;
|
|
30
|
+
/** @private internal API */
|
|
31
|
+
_getWatchPaths: () => string[];
|
|
30
32
|
readonly options: OpenAPIOptions;
|
|
31
33
|
}
|
|
32
34
|
declare function createOpenAPI(options?: OpenAPIOptions): OpenAPIServer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","names":[],"sources":["../../src/server/create.ts"],"mappings":";;;;;;;;AAGsE;
|
|
1
|
+
{"version":3,"file":"create.d.ts","names":[],"sources":["../../src/server/create.ts"],"mappings":";;;;;;;;AAGsE;KAMjE,SAAA,GAAY,MAAA,kBAAwB,QAAA;AAAA,KACpC,kBAAA,GAAqB,MAAA,SAAe,iBAAA;AAAA,UAExB,cAAA;EAHgC;AAAA;;;;;EAU/C,KAAA,qBAA0B,SAAA,GAAY,OAAA,CAAQ,SAAA;EAE9C,YAAA;;;;EAKA,QAAA;AAAA;AAAA,UAGe,aAAA;EACf,WAAA,SAAoB,WAAA;EACpB,UAAA,QAAkB,OAAA,CAAQ,kBAAA;EAC1B,SAAA,GAAY,QAAA,aAAqB,OAAA,CAAQ,iBAAA;EAbK;EAe9C,cAAA;EAAA,SACS,OAAA,EAAS,cAAA;AAAA;AAAA,iBAGJ,aAAA,CAAc,OAAA,GAAS,cAAA,GAAsB,aAAA;AAT7D;;;AAAA,iBAuDgB,gBAAA,GAAA,CACd,OAAA,EAAS,wBAAA,CAAyB,CAAA,IACjC,wBAAA,CAAyB,CAAA"}
|
package/dist/server/create.js
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import { createProxy } from "./proxy.js";
|
|
2
2
|
import { processDocument } from "../utils/process-document.js";
|
|
3
|
+
import fs from "node:fs";
|
|
3
4
|
//#region src/server/create.ts
|
|
4
5
|
function createOpenAPI(options = {}) {
|
|
5
6
|
const { input = [], disableCache = false } = options;
|
|
6
7
|
let schemas;
|
|
7
8
|
async function getSchemas() {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
return out;
|
|
9
|
+
if (Array.isArray(input)) {
|
|
10
|
+
const entries = await Promise.all(input.map(async (item) => [item, await processDocument(item)]));
|
|
11
|
+
return Object.fromEntries(entries);
|
|
12
|
+
} else {
|
|
13
|
+
const entries = await Promise.all(Object.entries(await input()).map(async ([k, v]) => [k, await processDocument(v)]));
|
|
14
|
+
return Object.fromEntries(entries);
|
|
15
|
+
}
|
|
16
16
|
}
|
|
17
17
|
return {
|
|
18
18
|
options,
|
|
19
19
|
createProxy,
|
|
20
|
+
_getWatchPaths() {
|
|
21
|
+
return (Array.isArray(input) ? input : Object.keys(input)).filter((key) => !URL.canParse(key) && fs.existsSync(key));
|
|
22
|
+
},
|
|
20
23
|
async getSchema(document) {
|
|
21
24
|
const schemas = await this.getSchemas();
|
|
22
25
|
if (document in schemas) return schemas[document];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","names":[],"sources":["../../src/server/create.ts"],"sourcesContent":["import { createProxy } from '@/server/proxy';\nimport { processDocument, type ProcessedDocument } from '@/utils/process-document';\nimport type { Document } from '@/types';\nimport type { InlineCodeUsageGenerator } from '@/requests/generators';\n\n/**\n * schema id -> file path, URL, or downloaded schema object\n */\ntype SchemaMap = Record<string, string | Document>;\ntype ProcessedSchemaMap = Record<string, ProcessedDocument>;\n\nexport interface OpenAPIOptions {\n /**\n * Schema files, can be:\n * - URL\n * - file path\n * - a function returning records of downloaded schemas.\n */\n input?: string[] | (() => SchemaMap | Promise<SchemaMap>);\n\n disableCache?: boolean;\n\n /**\n * The url of proxy to avoid CORS issues\n */\n proxyUrl?: string;\n}\n\nexport interface OpenAPIServer {\n createProxy: typeof createProxy;\n getSchemas: () => Promise<ProcessedSchemaMap>;\n getSchema: (document: string) => Promise<ProcessedDocument>;\n readonly options: OpenAPIOptions;\n}\n\nexport function createOpenAPI(options: OpenAPIOptions = {}): OpenAPIServer {\n const { input = [], disableCache = false } = options;\n let schemas: Promise<ProcessedSchemaMap> | undefined;\n\n async function getSchemas()
|
|
1
|
+
{"version":3,"file":"create.js","names":[],"sources":["../../src/server/create.ts"],"sourcesContent":["import { createProxy } from '@/server/proxy';\nimport { processDocument, type ProcessedDocument } from '@/utils/process-document';\nimport type { Document } from '@/types';\nimport type { InlineCodeUsageGenerator } from '@/requests/generators';\nimport fs from 'node:fs';\n\n/**\n * schema id -> file path, URL, or downloaded schema object\n */\ntype SchemaMap = Record<string, string | Document>;\ntype ProcessedSchemaMap = Record<string, ProcessedDocument>;\n\nexport interface OpenAPIOptions {\n /**\n * Schema files, can be:\n * - URL\n * - file path\n * - a function returning records of downloaded schemas.\n */\n input?: string[] | (() => SchemaMap | Promise<SchemaMap>);\n\n disableCache?: boolean;\n\n /**\n * The url of proxy to avoid CORS issues\n */\n proxyUrl?: string;\n}\n\nexport interface OpenAPIServer {\n createProxy: typeof createProxy;\n getSchemas: () => Promise<ProcessedSchemaMap>;\n getSchema: (document: string) => Promise<ProcessedDocument>;\n /** @private internal API */\n _getWatchPaths: () => string[];\n readonly options: OpenAPIOptions;\n}\n\nexport function createOpenAPI(options: OpenAPIOptions = {}): OpenAPIServer {\n const { input = [], disableCache = false } = options;\n let schemas: Promise<ProcessedSchemaMap> | undefined;\n\n async function getSchemas(): Promise<ProcessedSchemaMap> {\n if (Array.isArray(input)) {\n const entries = await Promise.all(\n input.map(async (item) => [item, await processDocument(item)]),\n );\n return Object.fromEntries(entries);\n } else {\n const entries = await Promise.all(\n Object.entries(await input()).map(async ([k, v]) => [k, await processDocument(v)]),\n );\n return Object.fromEntries(entries);\n }\n }\n\n return {\n options,\n createProxy,\n _getWatchPaths() {\n const keys = Array.isArray(input) ? input : Object.keys(input);\n return keys.filter((key) => !URL.canParse(key) && fs.existsSync(key));\n },\n async getSchema(document) {\n const schemas = await this.getSchemas();\n if (document in schemas) return schemas[document];\n\n console.warn(\n `[Fumadocs OpenAPI] the document \"${document}\" is not listed in the input array, this may not be expected.`,\n );\n // do not cache unlisted documents\n return processDocument(document);\n },\n async getSchemas() {\n if (disableCache) return getSchemas();\n\n return (schemas ??= getSchemas());\n },\n };\n}\n\n/**\n * @deprecated\n */\nexport function createCodeSample<T>(\n options: InlineCodeUsageGenerator<T>,\n): InlineCodeUsageGenerator<T> {\n return options;\n}\n"],"mappings":";;;;AAsCA,SAAgB,cAAc,UAA0B,EAAE,EAAiB;CACzE,MAAM,EAAE,QAAQ,EAAE,EAAE,eAAe,UAAU;CAC7C,IAAI;CAEJ,eAAe,aAA0C;AACvD,MAAI,MAAM,QAAQ,MAAM,EAAE;GACxB,MAAM,UAAU,MAAM,QAAQ,IAC5B,MAAM,IAAI,OAAO,SAAS,CAAC,MAAM,MAAM,gBAAgB,KAAK,CAAC,CAAC,CAC/D;AACD,UAAO,OAAO,YAAY,QAAQ;SAC7B;GACL,MAAM,UAAU,MAAM,QAAQ,IAC5B,OAAO,QAAQ,MAAM,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,MAAM,gBAAgB,EAAE,CAAC,CAAC,CACnF;AACD,UAAO,OAAO,YAAY,QAAQ;;;AAItC,QAAO;EACL;EACA;EACA,iBAAiB;AAEf,WADa,MAAM,QAAQ,MAAM,GAAG,QAAQ,OAAO,KAAK,MAAM,EAClD,QAAQ,QAAQ,CAAC,IAAI,SAAS,IAAI,IAAI,GAAG,WAAW,IAAI,CAAC;;EAEvE,MAAM,UAAU,UAAU;GACxB,MAAM,UAAU,MAAM,KAAK,YAAY;AACvC,OAAI,YAAY,QAAS,QAAO,QAAQ;AAExC,WAAQ,KACN,oCAAoC,SAAS,+DAC9C;AAED,UAAO,gBAAgB,SAAS;;EAElC,MAAM,aAAa;AACjB,OAAI,aAAc,QAAO,YAAY;AAErC,UAAQ,YAAY,YAAY;;EAEnC;;;;;AAMH,SAAgB,iBACd,SAC6B;AAC7B,QAAO"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { OpenAPIServer } from "./create.js";
|
|
2
2
|
import { ApiPageProps } from "../ui/api-page.js";
|
|
3
3
|
import { SchemaToPagesOptions } from "../utils/pages/preset-auto.js";
|
|
4
|
+
import { ClientApiPageProps } from "../ui/create-client.js";
|
|
4
5
|
import { ProcessedDocument } from "../utils/process-document.js";
|
|
5
|
-
import { LoaderPlugin, PageData, PageTreeTransformer, Source } from "fumadocs-core/source";
|
|
6
|
+
import { LoaderPlugin, MetaData, PageData, PageTreeTransformer, Source } from "fumadocs-core/source";
|
|
6
7
|
import { StructuredData } from "fumadocs-core/mdx-plugins";
|
|
7
8
|
import { TOCItemType } from "fumadocs-core/toc";
|
|
8
9
|
|
|
@@ -28,16 +29,21 @@ interface OpenAPIPageData extends PageData {
|
|
|
28
29
|
getSchema: () => {
|
|
29
30
|
id: string;
|
|
30
31
|
} & ProcessedDocument;
|
|
32
|
+
getClientAPIPageProps: () => Promise<ClientApiPageProps>;
|
|
31
33
|
structuredData: StructuredData;
|
|
32
34
|
toc: TOCItemType[];
|
|
33
35
|
}
|
|
36
|
+
interface MetaOptions {
|
|
37
|
+
folderStyle?: 'folder' | 'separator';
|
|
38
|
+
}
|
|
34
39
|
/**
|
|
35
40
|
* Generate virtual pages for Fumadocs Source API
|
|
36
41
|
*/
|
|
37
42
|
declare function openapiSource(server: OpenAPIServer, options?: SchemaToPagesOptions & {
|
|
38
|
-
baseDir?: string;
|
|
43
|
+
baseDir?: string; /** Generate `meta.json` files */
|
|
44
|
+
meta?: boolean | MetaOptions;
|
|
39
45
|
}): Promise<Source<{
|
|
40
|
-
metaData:
|
|
46
|
+
metaData: MetaData;
|
|
41
47
|
pageData: OpenAPIPageData;
|
|
42
48
|
}>>;
|
|
43
49
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-api.d.ts","names":[],"sources":["../../src/server/source-api.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"source-api.d.ts","names":[],"sources":["../../src/server/source-api.tsx"],"mappings":";;;;;;;;;;;YA2BmB,QAAA;IAJ0C;;;IAQzD,QAAA,GAAW,mBAAA;EAAA;AAAA;AAAA,UAIE,mBAAA;EACf,MAAA;EACA,OAAA;AAAA;AAFF;;;AAAA,iBAQgB,aAAA,CAAA,GAAiB,YAAA;AAAA,UAuCvB,eAAA,SAAwB,QAAA;EAChC,eAAA,QAAuB,YAAA;EACvB,SAAA;IAAmB,EAAA;EAAA,IAAe,iBAAA;EAClC,qBAAA,QAA6B,OAAA,CAAQ,kBAAA;EACrC,cAAA,EAAgB,cAAA;EAChB,GAAA,EAAK,WAAA;AAAA;AAAA,UAGG,WAAA;EACR,WAAA;AAAA;;;;iBAMoB,aAAA,CACpB,MAAA,EAAQ,aAAA,EACR,OAAA,GAAS,oBAAA;EACP,OAAA,WAlBsC;EAoBtC,IAAA,aAAiB,WAAA;AAAA,IAElB,OAAA,CACD,MAAA;EACE,QAAA,EAAU,QAAA;EACV,QAAA,EAAU,eAAA;AAAA;;;;iBAqIE,kBAAA,CAAA,GAAsB,mBAAA"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { toStaticData } from "../utils/pages/to-static-data.js";
|
|
1
2
|
import { MethodLabel } from "../ui/components/method-label.js";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { PathUtils } from "fumadocs-core/source";
|
|
2
5
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
6
|
//#region src/server/source-api.tsx
|
|
4
7
|
/**
|
|
@@ -38,18 +41,15 @@ function openapiPlugin() {
|
|
|
38
41
|
* Generate virtual pages for Fumadocs Source API
|
|
39
42
|
*/
|
|
40
43
|
async function openapiSource(server, options = {}) {
|
|
41
|
-
const { baseDir = "" } = options;
|
|
44
|
+
const { baseDir = "", meta = false } = options;
|
|
42
45
|
const { createAutoPreset } = await import("../utils/pages/preset-auto.js");
|
|
43
46
|
const { fromServer } = await import("../utils/pages/builder.js");
|
|
44
|
-
const { toBody } = await import("../utils/pages/to-body.js");
|
|
45
|
-
const { toStaticData } = await import("../utils/pages/to-static-data.js");
|
|
46
47
|
const files = [];
|
|
47
48
|
const entries = await fromServer(server, createAutoPreset(options));
|
|
48
49
|
for (const [schemaId, list] of Object.entries(entries)) {
|
|
49
50
|
const processed = await server.getSchema(schemaId);
|
|
50
|
-
|
|
51
|
-
const props =
|
|
52
|
-
props.showDescription ??= true;
|
|
51
|
+
function onEntry(entry) {
|
|
52
|
+
const props = getProps(entry);
|
|
53
53
|
files.push({
|
|
54
54
|
type: "page",
|
|
55
55
|
path: `${baseDir}/${entry.path}`,
|
|
@@ -58,6 +58,15 @@ async function openapiSource(server, options = {}) {
|
|
|
58
58
|
getAPIPageProps() {
|
|
59
59
|
return props;
|
|
60
60
|
},
|
|
61
|
+
async getClientAPIPageProps() {
|
|
62
|
+
return {
|
|
63
|
+
payload: {
|
|
64
|
+
bundled: processed.bundled,
|
|
65
|
+
proxyUrl: server.options.proxyUrl
|
|
66
|
+
},
|
|
67
|
+
...props
|
|
68
|
+
};
|
|
69
|
+
},
|
|
61
70
|
getSchema() {
|
|
62
71
|
return {
|
|
63
72
|
id: schemaId,
|
|
@@ -72,9 +81,59 @@ async function openapiSource(server, options = {}) {
|
|
|
72
81
|
}
|
|
73
82
|
});
|
|
74
83
|
}
|
|
84
|
+
function onEntries(entries, parent) {
|
|
85
|
+
if (!meta) {
|
|
86
|
+
for (const entry of entries) if (entry.type === "group") onEntries(entry.entries, entry);
|
|
87
|
+
else onEntry(entry);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const { folderStyle = "folder" } = meta === true ? {} : meta;
|
|
91
|
+
const pages = [];
|
|
92
|
+
for (const entry of entries) {
|
|
93
|
+
const relativePath = PathUtils.slash(parent ? path.relative(parent.path, entry.path) : entry.path);
|
|
94
|
+
if (entry.type === "group") {
|
|
95
|
+
onEntries(entry.entries, entry);
|
|
96
|
+
if (folderStyle === "folder") pages.push(relativePath);
|
|
97
|
+
else pages.push(`---${entry.info.title}---`, `...${relativePath}`);
|
|
98
|
+
} else {
|
|
99
|
+
onEntry(entry);
|
|
100
|
+
pages.push(relativePath.slice(0, -path.extname(entry.path).length));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (pages.length === 0) return;
|
|
104
|
+
files.push({
|
|
105
|
+
type: "meta",
|
|
106
|
+
path: path.join(baseDir, parent?.path ?? "", "meta.json"),
|
|
107
|
+
data: {
|
|
108
|
+
title: parent?.info.title,
|
|
109
|
+
description: parent?.info.description,
|
|
110
|
+
pages
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
onEntries(list);
|
|
75
115
|
}
|
|
76
116
|
return { files };
|
|
77
117
|
}
|
|
118
|
+
function getProps(entry) {
|
|
119
|
+
if (entry.type === "operation") return {
|
|
120
|
+
document: entry.schemaId,
|
|
121
|
+
operations: [entry.item],
|
|
122
|
+
showDescription: true
|
|
123
|
+
};
|
|
124
|
+
if (entry.type === "webhook") return {
|
|
125
|
+
document: entry.schemaId,
|
|
126
|
+
webhooks: [entry.item],
|
|
127
|
+
showDescription: true
|
|
128
|
+
};
|
|
129
|
+
return {
|
|
130
|
+
showTitle: true,
|
|
131
|
+
showDescription: true,
|
|
132
|
+
document: entry.schemaId,
|
|
133
|
+
operations: entry.operations,
|
|
134
|
+
webhooks: entry.webhooks
|
|
135
|
+
};
|
|
136
|
+
}
|
|
78
137
|
/**
|
|
79
138
|
* @deprecated use `openapiPlugin()`
|
|
80
139
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-api.js","names":[],"sources":["../../src/server/source-api.tsx"],"sourcesContent":["import { MethodLabel } from '@/ui/components/method-label';\nimport
|
|
1
|
+
{"version":3,"file":"source-api.js","names":[],"sources":["../../src/server/source-api.tsx"],"sourcesContent":["import { MethodLabel } from '@/ui/components/method-label';\nimport {\n PathUtils,\n type LoaderPlugin,\n type MetaData,\n type PageData,\n type PageTreeTransformer,\n type Source,\n type VirtualFile,\n} from 'fumadocs-core/source';\nimport type { OpenAPIServer } from '@/server/create';\nimport type { SchemaToPagesOptions } from '@/utils/pages/preset-auto';\nimport type { ApiPageProps } from '@/ui/api-page';\nimport type { StructuredData } from 'fumadocs-core/mdx-plugins';\nimport type { TOCItemType } from 'fumadocs-core/toc';\nimport type { ProcessedDocument } from '@/utils/process-document';\nimport type {\n OperationOutput,\n OutputEntry,\n PageOutput,\n WebhookOutput,\n} from '@/utils/pages/builder';\nimport path from 'node:path';\nimport type { ClientApiPageProps } from '@/ui/create-client';\nimport { toStaticData } from '@/utils/pages/to-static-data';\n\ndeclare module 'fumadocs-core/source' {\n export interface PageData {\n /**\n * Added by Fumadocs OpenAPI\n */\n _openapi?: InternalOpenAPIMeta;\n }\n}\n\nexport interface InternalOpenAPIMeta {\n method?: string;\n webhook?: boolean;\n}\n\n/**\n * Fumadocs Source API integration, pass this to `plugins` array in `loader()`.\n */\nexport function openapiPlugin(): LoaderPlugin {\n return {\n name: 'fumadocs:openapi',\n enforce: 'pre',\n transformPageTree: {\n file(node, filePath) {\n if (!filePath) return node;\n const file = this.storage.read(filePath);\n if (!file || file.format !== 'page') return node;\n\n const openApiData = file.data._openapi;\n if (!openApiData || typeof openApiData !== 'object') return node;\n\n if (openApiData.webhook) {\n node.name = (\n <>\n {node.name}{' '}\n <span className=\"ms-auto border border-current px-1 rounded-lg text-xs text-nowrap font-mono\">\n Webhook\n </span>\n </>\n );\n } else if (openApiData.method) {\n node.name = (\n <>\n {node.name}{' '}\n <MethodLabel className=\"ms-auto text-xs text-nowrap\">\n {openApiData.method}\n </MethodLabel>\n </>\n );\n }\n\n return node;\n },\n },\n };\n}\n\ninterface OpenAPIPageData extends PageData {\n getAPIPageProps: () => ApiPageProps;\n getSchema: () => { id: string } & ProcessedDocument;\n getClientAPIPageProps: () => Promise<ClientApiPageProps>;\n structuredData: StructuredData;\n toc: TOCItemType[];\n}\n\ninterface MetaOptions {\n folderStyle?: 'folder' | 'separator';\n}\n\n/**\n * Generate virtual pages for Fumadocs Source API\n */\nexport async function openapiSource(\n server: OpenAPIServer,\n options: SchemaToPagesOptions & {\n baseDir?: string;\n /** Generate `meta.json` files */\n meta?: boolean | MetaOptions;\n } = {},\n): Promise<\n Source<{\n metaData: MetaData;\n pageData: OpenAPIPageData;\n }>\n> {\n const { baseDir = '', meta = false } = options;\n const { createAutoPreset } = await import('@/utils/pages/preset-auto');\n const { fromServer } = await import('@/utils/pages/builder');\n const files: VirtualFile<{\n pageData: OpenAPIPageData;\n metaData: MetaData;\n }>[] = [];\n\n const entries = await fromServer(server, createAutoPreset(options));\n for (const [schemaId, list] of Object.entries(entries)) {\n const processed = await server.getSchema(schemaId);\n\n function onEntry(entry: PageOutput | OperationOutput | WebhookOutput) {\n const props = getProps(entry);\n\n files.push({\n type: 'page',\n path: `${baseDir}/${entry.path}`,\n data: {\n ...entry.info,\n getAPIPageProps() {\n return props;\n },\n async getClientAPIPageProps() {\n return {\n payload: {\n bundled: processed.bundled,\n proxyUrl: server.options.proxyUrl,\n },\n ...props,\n };\n },\n getSchema() {\n return {\n id: schemaId,\n ...processed,\n };\n },\n ...toStaticData(props, processed.dereferenced),\n _openapi: {\n method:\n entry.type === 'operation' || entry.type === 'webhook'\n ? entry.item.method\n : undefined,\n webhook: entry.type === 'webhook',\n },\n },\n });\n }\n\n function onEntries(entries: OutputEntry[], parent?: OutputEntry) {\n if (!meta) {\n for (const entry of entries) {\n if (entry.type === 'group') {\n onEntries(entry.entries, entry);\n } else {\n onEntry(entry);\n }\n }\n\n return;\n }\n\n const { folderStyle = 'folder' } = meta === true ? {} : meta;\n const pages: string[] = [];\n\n for (const entry of entries) {\n const relativePath = PathUtils.slash(\n parent ? path.relative(parent.path, entry.path) : entry.path,\n );\n\n if (entry.type === 'group') {\n onEntries(entry.entries, entry);\n if (folderStyle === 'folder') {\n pages.push(relativePath);\n } else {\n pages.push(`---${entry.info.title}---`, `...${relativePath}`);\n }\n } else {\n onEntry(entry);\n pages.push(relativePath.slice(0, -path.extname(entry.path).length));\n }\n }\n\n if (pages.length === 0) return;\n files.push({\n type: 'meta',\n path: path.join(baseDir, parent?.path ?? '', 'meta.json'),\n data: {\n title: parent?.info.title,\n description: parent?.info.description,\n pages,\n },\n });\n }\n\n onEntries(list);\n }\n\n return {\n files,\n };\n}\n\nfunction getProps(entry: PageOutput | OperationOutput | WebhookOutput): ApiPageProps {\n if (entry.type === 'operation')\n return {\n document: entry.schemaId,\n operations: [entry.item],\n showDescription: true,\n };\n if (entry.type === 'webhook')\n return {\n document: entry.schemaId,\n webhooks: [entry.item],\n showDescription: true,\n };\n\n return {\n showTitle: true,\n showDescription: true,\n document: entry.schemaId,\n operations: entry.operations,\n webhooks: entry.webhooks,\n };\n}\n\n/**\n * @deprecated use `openapiPlugin()`\n */\nexport function transformerOpenAPI(): PageTreeTransformer {\n return openapiPlugin().transformPageTree!;\n}\n"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { OpenAPIV3, OpenAPIV3_2 } from "./_openapi/types.js";
|
|
2
|
-
import { NoReference } from "./utils/schema.js";
|
|
2
|
+
import { NoReference } from "./utils/schema/index.js";
|
|
3
3
|
import { MediaAdapter } from "./requests/media/adapter.js";
|
|
4
4
|
import { InlineCodeUsageGenerator } from "./requests/generators/index.js";
|
|
5
5
|
import { OpenAPIOptions } from "./server/create.js";
|
|
6
6
|
import { CreateAPIPageOptions } from "./ui/base.js";
|
|
7
7
|
import { ProcessedDocument } from "./utils/process-document.js";
|
|
8
|
-
import Slugger from "github-slugger";
|
|
9
8
|
import { HTMLAttributes, ReactNode } from "react";
|
|
10
9
|
|
|
11
10
|
//#region src/types.d.ts
|
|
@@ -32,8 +31,7 @@ type MethodInformation = NoReference<OperationObject> & {
|
|
|
32
31
|
'x-exclusiveCodeSample'?: string;
|
|
33
32
|
};
|
|
34
33
|
type RequireKeys<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
|
|
35
|
-
interface RenderContext extends Pick<OpenAPIOptions, 'proxyUrl'>, Omit<RequireKeys<CreateAPIPageOptions, '
|
|
36
|
-
slugger: Slugger;
|
|
34
|
+
interface RenderContext extends Pick<OpenAPIOptions, 'proxyUrl'>, Omit<RequireKeys<CreateAPIPageOptions, 'renderMarkdown' | 'generateTypeScriptDefinitions'>, 'renderCodeBlock' | 'renderHeading' | 'generateTypeScriptSchema'> {
|
|
37
35
|
/**
|
|
38
36
|
* dereferenced schema
|
|
39
37
|
*/
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;;;;;KASY,QAAA,GAAW,WAAA,CAAY,QAAA;AAAA,KACvB,eAAA,GAAkB,WAAA,CAAY,eAAA;AAAA,KAC9B,eAAA,GAAkB,WAAA,CAAY,eAAA;AAAA,KAC9B,oBAAA,GAAuB,WAAA,CAAY,oBAAA;AAAA,KACnC,eAAA,GAAkB,WAAA,CAAY,eAAA;AAAA,KAC9B,cAAA,GAAiB,WAAA,CAAY,cAAA;AAAA,KAC7B,SAAA,GAAY,WAAA,CAAY,SAAA;AAAA,KACxB,YAAA,GAAe,WAAA,CAAY,YAAA;AAAA,KAC3B,cAAA,GAAiB,WAAA,CAAY,cAAA;AAAA,KAC7B,oBAAA,GAAuB,SAAA,CAAU,oBAAA;AAAA,KACjC,cAAA,GAAiB,WAAA,CAAY,cAAA;AAAA,KAC7B,oBAAA,GAAuB,WAAA,CAAY,oBAAA;AAAA,KACnC,WAAA,GAAc,WAAA,CAAY,WAAA;AAAA,KAC1B,aAAA,GAAgB,WAAA,CAAY,aAAA;AAAA,KAC5B,eAAA,GAAkB,WAAA,CAAY,eAAA;AAAA,KAC9B,iBAAA,GAAoB,WAAA,CAAY,iBAAA;AAAA,KAEhC,iBAAA,GAAoB,WAAA,CAAY,eAAA;EAC1C,MAAA;EACA,eAAA,GAAkB,wBAAA;EAClB,sBAAA;EACA,uBAAA;AAAA;AAAA,KAGG,WAAA,oBAA+B,CAAA,IAAK,IAAA,CAAK,CAAA,EAAG,CAAA,IAAK,QAAA,CAAS,IAAA,CAAK,CAAA,EAAG,CAAA;AAAA,UAEtD,aAAA,SAEb,IAAA,CAAK,cAAA,eACL,IAAA,CACE,WAAA,CAAY,oBAAA;EA1BS;;;EAgCzB,MAAA,EAAQ,iBAAA;EAER,aAAA,EAAe,MAAA,SAAe,YAAA;EAE9B,aAAA,GACE,KAAA,UACA,IAAA,WAAe,SAAA,EACf,KAAA,GAAQ,cAAA,CAAe,kBAAA;IAAwB,EAAA;EAAA,MAC5C,SAAA;EACL,eAAA,GAAkB,IAAA,UAAc,IAAA,aAAiB,SAAA;AAAA;AAAA,KAGvC,gBAAA,cAA8B,WAAA,IAAe,CAAA,mBAAoB,IAAA,CAAK,CAAA,EAAG,CAAA;AAAA,KACzE,SAAA,MAAe,CAAA,GAAI,OAAA,CAAQ,CAAA"}
|
package/dist/ui/api-page.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { HttpMethods } from "../types.js";
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
//#region src/ui/api-page.d.ts
|
|
4
4
|
interface ApiPageProps {
|
|
5
|
-
document:
|
|
5
|
+
document: string;
|
|
6
6
|
showTitle?: boolean;
|
|
7
7
|
showDescription?: boolean;
|
|
8
8
|
/**
|