fumadocs-openapi 10.5.0 → 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 +26 -21
- package/dist/generate-file.d.ts +10 -2
- package/dist/generate-file.d.ts.map +1 -1
- package/dist/generate-file.js +15 -3
- package/dist/generate-file.js.map +1 -1
- 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.map +1 -1
- package/dist/playground/schema.js +10 -12
- 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/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 +2 -0
- package/dist/server/source-api.d.ts.map +1 -1
- package/dist/server/source-api.js +10 -1
- 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 +1 -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 -4
- 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/index.d.ts +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 +1 -1
- package/dist/utils/pages/builder.js +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 +5 -4
- 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/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":"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,5 +1,6 @@
|
|
|
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
6
|
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
@@ -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"}
|
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,6 +1,7 @@
|
|
|
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
6
|
import { LoaderPlugin, MetaData, PageData, PageTreeTransformer, Source } from "fumadocs-core/source";
|
|
6
7
|
import { StructuredData } from "fumadocs-core/mdx-plugins";
|
|
@@ -28,6 +29,7 @@ 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
|
}
|
|
@@ -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,3 +1,4 @@
|
|
|
1
|
+
import { toStaticData } from "../utils/pages/to-static-data.js";
|
|
1
2
|
import { MethodLabel } from "../ui/components/method-label.js";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { PathUtils } from "fumadocs-core/source";
|
|
@@ -43,7 +44,6 @@ async function openapiSource(server, options = {}) {
|
|
|
43
44
|
const { baseDir = "", meta = false } = options;
|
|
44
45
|
const { createAutoPreset } = await import("../utils/pages/preset-auto.js");
|
|
45
46
|
const { fromServer } = await import("../utils/pages/builder.js");
|
|
46
|
-
const { toStaticData } = await import("../utils/pages/to-static-data.js");
|
|
47
47
|
const files = [];
|
|
48
48
|
const entries = await fromServer(server, createAutoPreset(options));
|
|
49
49
|
for (const [schemaId, list] of Object.entries(entries)) {
|
|
@@ -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,
|
|
@@ -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 {\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';\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 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
|
|
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,9 +1,8 @@
|
|
|
1
1
|
import { HttpMethods } from "../types.js";
|
|
2
|
-
import { ProcessedDocument } from "../utils/process-document.js";
|
|
3
2
|
|
|
4
3
|
//#region src/ui/api-page.d.ts
|
|
5
4
|
interface ApiPageProps {
|
|
6
|
-
document:
|
|
5
|
+
document: string;
|
|
7
6
|
showTitle?: boolean;
|
|
8
7
|
showDescription?: boolean;
|
|
9
8
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-page.d.ts","names":[],"sources":["../../src/ui/api-page.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"api-page.d.ts","names":[],"sources":["../../src/ui/api-page.tsx"],"mappings":";;;UAKiB,YAAA;EACf,QAAA;EACA,SAAA;EACA,eAAA;;;;EAKA,UAAA,GAAa,aAAA;EAEb,QAAA,GAAW,WAAA;AAAA;AAAA,UAGI,WAAA;EAHf;;;EAOA,IAAA;EACA,MAAA,EAAQ,WAAA;AAAA;AAAA,UAGO,aAAA;EAHI;;;EAOnB,IAAA;EAPmB;;AAGrB;EAQE,MAAA,EAAQ,WAAA;AAAA"}
|
package/dist/ui/api-page.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { createMethod } from "../utils/schema.js";
|
|
1
|
+
import { createMethod } from "../utils/schema/index.js";
|
|
2
2
|
import { ApiProviderLazy, ServerProviderLazy } from "./contexts/api.lazy.js";
|
|
3
3
|
import { Operation } from "./operation/index.js";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
//#region src/ui/api-page.tsx
|
|
6
|
-
|
|
6
|
+
function APIPage({ showTitle: hasHead = false, showDescription, operations, webhooks, ctx }) {
|
|
7
7
|
const { dereferenced } = ctx.schema;
|
|
8
8
|
let { renderPageLayout } = ctx.content ?? {};
|
|
9
9
|
renderPageLayout ??= (slots) => /* @__PURE__ */ jsxs("div", {
|
|
10
10
|
className: "flex flex-col gap-24 text-sm @container",
|
|
11
11
|
children: [slots.operations?.map((op) => op.children), slots.webhooks?.map((op) => op.children)]
|
|
12
12
|
});
|
|
13
|
-
const content =
|
|
13
|
+
const content = renderPageLayout({
|
|
14
14
|
operations: operations?.map((item) => {
|
|
15
15
|
const pathItem = dereferenced.paths?.[item.path];
|
|
16
16
|
if (!pathItem) throw new Error(`[Fumadocs OpenAPI] Path not found in OpenAPI schema: ${item.path}`);
|
|
@@ -45,13 +45,11 @@ async function APIPage({ showTitle: hasHead = false, showDescription, operations
|
|
|
45
45
|
};
|
|
46
46
|
})
|
|
47
47
|
}, ctx);
|
|
48
|
-
let servers = ctx.schema.dereferenced.servers;
|
|
49
|
-
if (!servers || servers.length === 0) servers = [{ url: "/" }];
|
|
50
48
|
return /* @__PURE__ */ jsx(ApiProviderLazy, {
|
|
51
49
|
shikiOptions: ctx.shikiOptions,
|
|
52
50
|
client: ctx.client ?? {},
|
|
53
51
|
children: /* @__PURE__ */ jsx(ServerProviderLazy, {
|
|
54
|
-
servers,
|
|
52
|
+
servers: dereferenced.servers,
|
|
55
53
|
children: content
|
|
56
54
|
})
|
|
57
55
|
});
|
package/dist/ui/api-page.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-page.js","names":[],"sources":["../../src/ui/api-page.tsx"],"sourcesContent":["import { Operation } from '@/ui/operation';\nimport type { HttpMethods, RenderContext } from '@/types';\nimport { createMethod } from '@/utils/schema';\nimport
|
|
1
|
+
{"version":3,"file":"api-page.js","names":[],"sources":["../../src/ui/api-page.tsx"],"sourcesContent":["import { Operation } from '@/ui/operation';\nimport type { HttpMethods, RenderContext, ServerObject } from '@/types';\nimport { createMethod } from '@/utils/schema';\nimport { ApiProviderLazy, ServerProviderLazy } from './contexts/api.lazy';\n\nexport interface ApiPageProps {\n document: string;\n showTitle?: boolean;\n showDescription?: boolean;\n\n /**\n * An array of operations\n */\n operations?: OperationItem[];\n\n webhooks?: WebhookItem[];\n}\n\nexport interface WebhookItem {\n /**\n * webhook name in `webhooks`\n */\n name: string;\n method: HttpMethods;\n}\n\nexport interface OperationItem {\n /**\n * the path of operation in `paths`\n */\n path: string;\n /**\n * the HTTP method of operation\n */\n method: HttpMethods;\n}\n\nexport function APIPage({\n showTitle: hasHead = false,\n showDescription,\n operations,\n webhooks,\n ctx,\n}: Omit<ApiPageProps, 'document'> & {\n ctx: RenderContext;\n}) {\n const { dereferenced } = ctx.schema;\n let { renderPageLayout } = ctx.content ?? {};\n renderPageLayout ??= (slots) => (\n <div className=\"flex flex-col gap-24 text-sm @container\">\n {slots.operations?.map((op) => op.children)}\n {slots.webhooks?.map((op) => op.children)}\n </div>\n );\n\n const content = renderPageLayout(\n {\n operations: operations?.map((item) => {\n const pathItem = dereferenced.paths?.[item.path];\n if (!pathItem)\n throw new Error(`[Fumadocs OpenAPI] Path not found in OpenAPI schema: ${item.path}`);\n\n const operation = pathItem[item.method];\n if (!operation)\n throw new Error(\n `[Fumadocs OpenAPI] Method ${item.method} not found in operation: ${item.path}`,\n );\n\n const method = createMethod(item.method, pathItem, operation);\n\n return {\n item,\n children: (\n <Operation\n key={`${item.path}:${item.method}`}\n method={method}\n path={item.path}\n ctx={ctx}\n showTitle={hasHead}\n showDescription={showDescription}\n />\n ),\n };\n }),\n webhooks: webhooks?.map((item) => {\n const webhook = dereferenced.webhooks?.[item.name];\n if (!webhook)\n throw new Error(`[Fumadocs OpenAPI] Webhook not found in OpenAPI schema: ${item.name}`);\n\n const hook = webhook[item.method];\n if (!hook)\n throw new Error(\n `[Fumadocs OpenAPI] Method ${item.method} not found in webhook: ${item.name}`,\n );\n\n return {\n item,\n children: (\n <Operation\n type=\"webhook\"\n key={`${item.name}:${item.method}`}\n method={createMethod(item.method, webhook, hook)}\n ctx={ctx}\n path={`/${item.name}`}\n showTitle={hasHead}\n showDescription={showDescription}\n />\n ),\n };\n }),\n },\n ctx,\n );\n\n return (\n <ApiProviderLazy shikiOptions={ctx.shikiOptions} client={ctx.client ?? {}}>\n <ServerProviderLazy servers={dereferenced.servers as ServerObject[]}>\n {content}\n </ServerProviderLazy>\n </ApiProviderLazy>\n );\n}\n"],"mappings":";;;;;AAqCA,SAAgB,QAAQ,EACtB,WAAW,UAAU,OACrB,iBACA,YACA,UACA,OAGC;CACD,MAAM,EAAE,iBAAiB,IAAI;CAC7B,IAAI,EAAE,qBAAqB,IAAI,WAAW,EAAE;AAC5C,uBAAsB,UACpB,qBAAC,OAAD;EAAK,WAAU;YAAf,CACG,MAAM,YAAY,KAAK,OAAO,GAAG,SAAS,EAC1C,MAAM,UAAU,KAAK,OAAO,GAAG,SAAS,CACrC;;CAGR,MAAM,UAAU,iBACd;EACE,YAAY,YAAY,KAAK,SAAS;GACpC,MAAM,WAAW,aAAa,QAAQ,KAAK;AAC3C,OAAI,CAAC,SACH,OAAM,IAAI,MAAM,wDAAwD,KAAK,OAAO;GAEtF,MAAM,YAAY,SAAS,KAAK;AAChC,OAAI,CAAC,UACH,OAAM,IAAI,MACR,6BAA6B,KAAK,OAAO,2BAA2B,KAAK,OAC1E;AAIH,UAAO;IACL;IACA,UACE,oBAAC,WAAD;KAEE,QAPS,aAAa,KAAK,QAAQ,UAAU,UAAU;KAQvD,MAAM,KAAK;KACN;KACL,WAAW;KACM;KACjB,EANK,GAAG,KAAK,KAAK,GAAG,KAAK,SAM1B;IAEL;IACD;EACF,UAAU,UAAU,KAAK,SAAS;GAChC,MAAM,UAAU,aAAa,WAAW,KAAK;AAC7C,OAAI,CAAC,QACH,OAAM,IAAI,MAAM,2DAA2D,KAAK,OAAO;GAEzF,MAAM,OAAO,QAAQ,KAAK;AAC1B,OAAI,CAAC,KACH,OAAM,IAAI,MACR,6BAA6B,KAAK,OAAO,yBAAyB,KAAK,OACxE;AAEH,UAAO;IACL;IACA,UACE,oBAAC,WAAD;KACE,MAAK;KAEL,QAAQ,aAAa,KAAK,QAAQ,SAAS,KAAK;KAC3C;KACL,MAAM,IAAI,KAAK;KACf,WAAW;KACM;KACjB,EANK,GAAG,KAAK,KAAK,GAAG,KAAK,SAM1B;IAEL;IACD;EACH,EACD,IACD;AAED,QACE,oBAAC,iBAAD;EAAiB,cAAc,IAAI;EAAc,QAAQ,IAAI,UAAU,EAAE;YACvE,oBAAC,oBAAD;GAAoB,SAAS,aAAa;aACvC;GACkB,CAAA;EACL,CAAA"}
|
package/dist/ui/base.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { NoReference } from "../utils/schema.js";
|
|
1
|
+
import { NoReference } from "../utils/schema/index.js";
|
|
2
2
|
import { MediaAdapter } from "../requests/media/adapter.js";
|
|
3
3
|
import { CodeUsageGeneratorRegistry, InlineCodeUsageGenerator } from "../requests/generators/index.js";
|
|
4
4
|
import { OpenAPIServer } from "../server/create.js";
|
|
5
5
|
import { ApiPageProps, OperationItem, WebhookItem } from "./api-page.js";
|
|
6
|
-
import { ExampleRequestItem } from "./operation/
|
|
6
|
+
import { ExampleRequestItem } from "./operation/get-example-requests.js";
|
|
7
7
|
import { APIPageClientOptions } from "./client/index.js";
|
|
8
8
|
import { SchemaUIOptions } from "./schema/index.js";
|
|
9
9
|
import { ResponseTab } from "./operation/response-tabs.js";
|
|
10
10
|
import { ClientCodeBlockProvider } from "./components/codeblock.js";
|
|
11
11
|
import { Awaitable, MethodInformation, RenderContext } from "../types.js";
|
|
12
|
+
import { ProcessedDocument } from "../utils/process-document.js";
|
|
12
13
|
import { FC, HTMLAttributes, ReactNode } from "react";
|
|
13
14
|
import { ShikiFactory } from "fumadocs-core/highlight/shiki";
|
|
14
15
|
import { JSONSchema } from "json-schema-typed";
|
|
@@ -41,7 +42,7 @@ interface CreateAPIPageOptions {
|
|
|
41
42
|
*
|
|
42
43
|
* Pass `false` to disable it.
|
|
43
44
|
*/
|
|
44
|
-
generateTypeScriptDefinitions?: (schema: JSONSchema, ctx: GenerateTypeScriptDefinitionsContext) => Awaitable<string | undefined
|
|
45
|
+
generateTypeScriptDefinitions?: ((schema: JSONSchema, ctx: GenerateTypeScriptDefinitionsContext) => Awaitable<string | undefined>) | false;
|
|
45
46
|
/**
|
|
46
47
|
* Generate example code usage for all endpoints.
|
|
47
48
|
*/
|
|
@@ -49,7 +50,7 @@ interface CreateAPIPageOptions {
|
|
|
49
50
|
/**
|
|
50
51
|
* Generate example code usage for each endpoint.
|
|
51
52
|
*/
|
|
52
|
-
generateCodeSamples?: (method: MethodInformation) =>
|
|
53
|
+
generateCodeSamples?: (method: MethodInformation) => InlineCodeUsageGenerator[];
|
|
53
54
|
shiki: ShikiFactory;
|
|
54
55
|
renderMarkdown?: (md: string) => ReactNode;
|
|
55
56
|
shikiOptions: Omit<CodeToHastOptionsCommon, 'lang'> & CodeOptionsThemes<BundledTheme>;
|
|
@@ -67,20 +68,20 @@ interface CreateAPIPageOptions {
|
|
|
67
68
|
* Customise page content
|
|
68
69
|
*/
|
|
69
70
|
content?: {
|
|
70
|
-
renderResponseTabs?: (tabs: ResponseTab[], ctx: RenderContext) =>
|
|
71
|
+
renderResponseTabs?: (tabs: ResponseTab[], ctx: RenderContext) => ReactNode;
|
|
71
72
|
renderRequestTabs?: (items: ExampleRequestItem[], ctx: RenderContext & {
|
|
72
73
|
route: string;
|
|
73
74
|
operation: NoReference<MethodInformation>;
|
|
74
|
-
}) =>
|
|
75
|
+
}) => ReactNode;
|
|
75
76
|
renderAPIExampleLayout?: (slots: {
|
|
76
77
|
selector: ReactNode;
|
|
77
78
|
usageTabs: ReactNode;
|
|
78
79
|
responseTabs: ReactNode;
|
|
79
|
-
}, ctx: RenderContext) =>
|
|
80
|
+
}, ctx: RenderContext) => ReactNode;
|
|
80
81
|
/**
|
|
81
82
|
* @param generators - codegens for API example usages
|
|
82
83
|
*/
|
|
83
|
-
renderAPIExampleUsageTabs?: (generators: CodeUsageGeneratorRegistry, ctx: RenderContext) =>
|
|
84
|
+
renderAPIExampleUsageTabs?: (generators: CodeUsageGeneratorRegistry, ctx: RenderContext) => ReactNode;
|
|
84
85
|
/**
|
|
85
86
|
* renderer of the entire page's layout (containing all operations & webhooks UI)
|
|
86
87
|
*/
|
|
@@ -93,7 +94,7 @@ interface CreateAPIPageOptions {
|
|
|
93
94
|
item: WebhookItem;
|
|
94
95
|
children: ReactNode;
|
|
95
96
|
}[];
|
|
96
|
-
}, ctx: RenderContext) =>
|
|
97
|
+
}, ctx: RenderContext) => ReactNode;
|
|
97
98
|
renderOperationLayout?: (slots: {
|
|
98
99
|
header: ReactNode;
|
|
99
100
|
description: ReactNode;
|
|
@@ -104,7 +105,7 @@ interface CreateAPIPageOptions {
|
|
|
104
105
|
body: ReactNode;
|
|
105
106
|
responses: ReactNode;
|
|
106
107
|
callbacks: ReactNode;
|
|
107
|
-
}, ctx: RenderContext, method: NoReference<MethodInformation>) =>
|
|
108
|
+
}, ctx: RenderContext, method: NoReference<MethodInformation>) => ReactNode;
|
|
108
109
|
renderWebhookLayout?: (slots: {
|
|
109
110
|
header: ReactNode;
|
|
110
111
|
description: ReactNode;
|
|
@@ -114,13 +115,13 @@ interface CreateAPIPageOptions {
|
|
|
114
115
|
requests: ReactNode;
|
|
115
116
|
responses: ReactNode;
|
|
116
117
|
callbacks: ReactNode;
|
|
117
|
-
}) =>
|
|
118
|
+
}) => ReactNode;
|
|
118
119
|
};
|
|
119
120
|
/**
|
|
120
121
|
* Info UI for JSON schemas
|
|
121
122
|
*/
|
|
122
123
|
schemaUI?: {
|
|
123
|
-
render?: (options: SchemaUIOptions, ctx: RenderContext) =>
|
|
124
|
+
render?: (options: SchemaUIOptions, ctx: RenderContext) => ReactNode;
|
|
124
125
|
/**
|
|
125
126
|
* Show examples under the generated content of JSON schemas.
|
|
126
127
|
*
|
|
@@ -145,14 +146,17 @@ interface CreateAPIPageOptions {
|
|
|
145
146
|
ctx: RenderContext;
|
|
146
147
|
}) => Awaitable<ReactNode>;
|
|
147
148
|
};
|
|
148
|
-
renderHeading?: (props: HTMLAttributes<HTMLHeadingElement>, depth: number) =>
|
|
149
|
+
renderHeading?: (props: HTMLAttributes<HTMLHeadingElement>, depth: number) => ReactNode;
|
|
149
150
|
renderCodeBlock?: (props: {
|
|
150
151
|
lang: string;
|
|
151
152
|
code: string;
|
|
152
|
-
}) =>
|
|
153
|
+
}) => ReactNode;
|
|
153
154
|
client?: APIPageClientOptions;
|
|
154
155
|
}
|
|
155
|
-
|
|
156
|
+
interface ServerApiPageProps extends Omit<ApiPageProps, 'document'> {
|
|
157
|
+
document: string | ProcessedDocument;
|
|
158
|
+
}
|
|
159
|
+
declare function createAPIPage(server: OpenAPIServer, options: CreateAPIPageOptions): FC<ServerApiPageProps>;
|
|
156
160
|
//#endregion
|
|
157
|
-
export { ClientCodeBlockProvider, CreateAPIPageOptions, GenerateTypeScriptDefinitionsContext, createAPIPage };
|
|
161
|
+
export { ClientCodeBlockProvider, CreateAPIPageOptions, GenerateTypeScriptDefinitionsContext, ServerApiPageProps, createAPIPage };
|
|
158
162
|
//# sourceMappingURL=base.d.ts.map
|