fumadocs-openapi 10.6.2 → 10.6.4
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 +8 -17
- package/dist/generate-file.d.ts +2 -2
- package/dist/generate-file.d.ts.map +1 -1
- package/dist/generate-file.js.map +1 -1
- package/dist/playground/client.d.ts +15 -19
- package/dist/playground/client.d.ts.map +1 -1
- package/dist/playground/client.js +30 -18
- package/dist/playground/client.js.map +1 -1
- package/dist/playground/schema.js +14 -35
- package/dist/playground/schema.js.map +1 -1
- package/dist/server/create.d.ts +1 -1
- package/dist/server/create.js +1 -1
- package/dist/server/create.js.map +1 -1
- package/dist/server/source-api.d.ts +2 -2
- package/dist/server/source-api.d.ts.map +1 -1
- package/dist/server/source-api.js.map +1 -1
- package/dist/types.d.ts +4 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/base.d.ts +10 -9
- package/dist/ui/base.d.ts.map +1 -1
- package/dist/ui/base.js +22 -0
- package/dist/ui/base.js.map +1 -1
- package/dist/ui/components/{server-tab.js → select-tab.js} +11 -11
- package/dist/ui/components/select-tab.js.map +1 -0
- package/dist/ui/create-client.d.ts.map +1 -1
- package/dist/ui/create-client.js +18 -13
- package/dist/ui/create-client.js.map +1 -1
- package/dist/ui/operation/get-example-requests.js +2 -2
- package/dist/ui/operation/get-example-requests.js.map +1 -1
- package/dist/ui/operation/index.js +6 -7
- package/dist/ui/operation/index.js.map +1 -1
- package/dist/ui/operation/response-tabs.d.ts +1 -1
- package/dist/ui/schema/index.d.ts +1 -1
- package/dist/utils/deep-equal.js +8 -4
- package/dist/utils/deep-equal.js.map +1 -1
- package/dist/utils/document/dereference.d.ts +18 -0
- package/dist/utils/document/dereference.d.ts.map +1 -0
- package/dist/utils/document/dereference.js +21 -0
- package/dist/utils/document/dereference.js.map +1 -0
- package/dist/utils/document/process.d.ts +7 -0
- package/dist/utils/document/process.d.ts.map +1 -0
- package/dist/utils/{process-document.js → document/process.js} +5 -18
- package/dist/utils/document/process.js.map +1 -0
- package/dist/utils/is-plain-object.js +10 -0
- package/dist/utils/is-plain-object.js.map +1 -0
- package/dist/utils/pages/builder.d.ts +4 -4
- package/dist/utils/pages/builder.d.ts.map +1 -1
- package/dist/utils/pages/builder.js.map +1 -1
- package/dist/utils/pages/preset-auto.d.ts +2 -2
- package/dist/utils/pages/preset-auto.d.ts.map +1 -1
- package/dist/utils/pages/preset-auto.js.map +1 -1
- package/dist/utils/pages/to-text.js.map +1 -1
- package/dist/utils/remove-undefined.js +10 -8
- package/dist/utils/remove-undefined.js.map +1 -1
- package/dist/utils/schema/index.d.ts +7 -2
- package/dist/utils/schema/index.d.ts.map +1 -1
- package/dist/utils/schema/index.js +21 -2
- package/dist/utils/schema/index.js.map +1 -1
- package/dist/utils/schema/pick.js +46 -0
- package/dist/utils/schema/pick.js.map +1 -0
- package/dist/utils/schema/ref.js +37 -0
- package/dist/utils/schema/ref.js.map +1 -0
- package/dist/utils/schema/resolve-ref.js +4 -12
- package/dist/utils/schema/resolve-ref.js.map +1 -1
- package/dist/utils/schema/to-string.js.map +1 -1
- package/package.json +3 -4
- package/dist/playground/index.d.ts +0 -22
- package/dist/playground/index.d.ts.map +0 -1
- package/dist/playground/index.js +0 -118
- package/dist/playground/index.js.map +0 -1
- package/dist/ui/components/server-tab.js.map +0 -1
- package/dist/utils/process-document.d.ts +0 -18
- package/dist/utils/process-document.d.ts.map +0 -1
- package/dist/utils/process-document.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preset-auto.js","names":["path"],"sources":["../../../src/utils/pages/preset-auto.ts"],"sourcesContent":["import * as path from 'node:path';\nimport type { ProcessedDocument } from '@/utils/process-document';\nimport type {\n OperationOutput,\n OutputEntry,\n OutputGroup,\n PageOutput,\n PagesBuilder,\n PagesBuilderConfig,\n WebhookOutput,\n} from '@/utils/pages/builder';\nimport { isUrl } from '@/utils/url';\nimport type { DistributiveOmit } from '@/types';\n\ninterface OperationConfig extends BaseConfig {\n /**\n * Generate a page for each API endpoint/operation (default).\n */\n per?: 'operation';\n\n /**\n * Group output using folders (Only works on `operation` mode)\n * - tag: `{tag}/{file}`\n * - route: `{endpoint}/{method}` (it will ignore the `name` option)\n * - none: `{file}` (default)\n * - a function that aligns group name (folder path) to each entry\n *\n * @defaultValue 'none'\n */\n groupBy?:\n | 'tag'\n | 'route'\n | 'none'\n | ((entry: DistributiveOmit<OperationOutput | WebhookOutput, 'path'>) => string);\n\n /**\n * Specify name for output file\n */\n name?: NameFn<OperationOutput | WebhookOutput> | NameFnOptions;\n}\n\ninterface TagConfig extends BaseConfig {\n /**\n * Generate a page for each tag.\n */\n per: 'tag';\n\n /**\n * Specify name for output file\n */\n name?: NameFn<PageOutput> | NameFnOptions;\n}\n\ninterface SchemaConfig extends BaseConfig {\n /**\n * Generate a page for each schema file.\n */\n per: 'file';\n\n /**\n * Specify name for output file\n */\n name?: NameFn<PageOutput> | NameFnOptions;\n}\n\nexport type SchemaToPagesOptions =\n | SchemaConfig\n | TagConfig\n | OperationConfig\n | ({\n per: 'custom';\n } & PagesBuilderConfig);\n\ntype NameFn<\n Entry extends OperationOutput | WebhookOutput | PageOutput =\n | OperationOutput\n | WebhookOutput\n | PageOutput,\n> = (\n this: PagesBuilder,\n output: DistributiveOmit<Entry, 'path'>,\n document: ProcessedDocument['dereferenced'],\n) => string;\n\ninterface NameFnOptions {\n /**\n * The version of algorithm used to generate file paths.\n *\n * v1: Fumadocs OpenAPI v8\n * v2: Fumadocs OpenAPI v9\n *\n * @defaultValue v2\n */\n algorithm?: 'v2' | 'v1';\n}\n\ninterface BaseConfig {\n /**\n * Custom function to convert names into file names.\n *\n * By default, it only escapes whitespaces and upper case (English) characters\n */\n slugify?: (name: string) => string;\n}\n\nexport function createAutoPreset(options: SchemaToPagesOptions): PagesBuilderConfig {\n if (options.per === 'custom') return options;\n const {\n slugify = (s) => {\n return s.replace(/\\s+/g, '-').toLowerCase();\n },\n } = options;\n let nameFn: NameFn;\n\n if (typeof options.name === 'function') {\n nameFn = options.name as NameFn;\n } else {\n const { algorithm = 'v2' } = options.name ?? {};\n\n nameFn = function (result, document) {\n if (result.type === 'page') {\n if (result.tag) return slugify(result.tag.name!);\n const schemaId = result.schemaId;\n\n return isUrl(schemaId) ? 'index' : path.basename(schemaId, path.extname(schemaId));\n }\n\n if (result.type === 'operation') {\n const operation = document.paths![result.item.path]![result.item.method]!;\n\n if (algorithm === 'v2' && operation.operationId) {\n return operation.operationId;\n }\n\n return path.join(\n this.routePathToFilePath(result.item.path),\n result.item.method.toLowerCase(),\n );\n }\n\n const hook = document.webhooks![result.item.name][result.item.method]!;\n\n if (algorithm === 'v2' && hook.operationId) {\n return hook.operationId;\n }\n\n return slugify(result.item.name);\n };\n }\n\n function group(\n builder: PagesBuilder,\n entries: DistributiveOmit<OperationOutput | WebhookOutput, 'path'>[],\n ): OutputEntry[] {\n const groups = new Map<string, OutputGroup>();\n const rest: OutputEntry[] = [];\n const { dereferenced } = builder.document;\n const { groupBy = 'none' } = options as OperationConfig;\n\n for (const entry of entries) {\n switch (groupBy) {\n case 'route': {\n const groupName = builder.routePathToFilePath(\n entry.type === 'operation' ? entry.item.path : entry.item.name,\n );\n\n let group = groups.get(groupName);\n if (!group) {\n group = {\n type: 'group',\n info: { title: groupName },\n entries: [],\n schemaId: builder.id,\n path: groupName,\n };\n groups.set(groupName, group);\n }\n\n group.entries.push({\n ...entry,\n path: path.join(groupName, `${entry.item.method.toLowerCase()}.mdx`),\n });\n break;\n }\n case 'tag': {\n let tags =\n entry.type === 'operation'\n ? dereferenced.paths![entry.item.path]![entry.item.method]!.tags\n : dereferenced.webhooks![entry.item.name][entry.item.method]!.tags;\n\n if (!tags || tags.length === 0) {\n console.warn(\n 'When `groupBy` is set to `tag`, make sure a `tags` is defined for every operation schema.',\n );\n\n tags = ['unknown'];\n }\n\n for (const tag of tags) {\n const groupName = slugify(tag);\n const { displayName, info } = builder.fromTagName(tag)!;\n let group = groups.get(groupName);\n if (!group) {\n group = {\n type: 'group',\n info: { title: displayName, description: info.description },\n tag: info,\n entries: [],\n schemaId: builder.id,\n path: groupName,\n };\n groups.set(groupName, group);\n }\n\n group.entries.push({\n ...entry,\n path: path.join(groupName, `${nameFn.call(builder, entry, dereferenced)}.mdx`),\n });\n }\n\n break;\n }\n default: {\n const fileName = `${nameFn.call(builder, entry, dereferenced)}.mdx`;\n\n if (typeof groupBy === 'function') {\n const groupDisplayName = groupBy(entry);\n const groupName = slugify(groupDisplayName);\n\n let group = groups.get(groupName);\n if (!group) {\n group = {\n type: 'group',\n info: { title: groupDisplayName },\n entries: [],\n schemaId: builder.id,\n path: groupName,\n };\n groups.set(groupName, group);\n }\n\n group.entries.push({\n ...entry,\n path: path.join(groupName, fileName),\n });\n break;\n }\n\n rest.push({\n ...entry,\n path: fileName,\n });\n }\n }\n }\n\n rest.push(...groups.values());\n return rest;\n }\n\n return {\n toPages(builder) {\n const { dereferenced } = builder.document;\n const items = builder.extract();\n\n if (options.per === 'file') {\n const entry: PageOutput = {\n type: 'page',\n schemaId: builder.id,\n path: '',\n info: {\n title: dereferenced.info?.title ?? 'Unknown',\n description: dereferenced.info?.description,\n },\n ...items,\n };\n entry.path = `${nameFn.call(builder, entry, dereferenced)}.mdx`;\n builder.create(entry);\n return;\n }\n\n if (options.per === 'tag') {\n const tags = dereferenced.tags ?? [];\n\n for (const tag of tags) {\n const { displayName } = builder.fromTag(tag);\n const entry: PageOutput = {\n type: 'page',\n path: '',\n schemaId: builder.id,\n info: {\n title: displayName,\n description: tag.description,\n },\n webhooks: items.webhooks.filter((webhook) => webhook.tags?.includes(tag.name!)),\n operations: items.operations.filter((op) => op.tags?.includes(tag.name!)),\n tag,\n };\n\n entry.path = `${nameFn.call(builder, entry, dereferenced)}.mdx`;\n builder.create(entry);\n }\n\n return;\n }\n\n const entries: DistributiveOmit<OperationOutput | WebhookOutput, 'path'>[] = [];\n for (const op of items.operations) {\n const { pathItem, operation, displayName } = builder.fromExtractedOperation(op)!;\n\n entries.push({\n type: 'operation',\n schemaId: builder.id,\n item: op,\n info: {\n title: displayName,\n description: operation.description ?? pathItem.description,\n },\n });\n }\n\n for (const webhook of items.webhooks) {\n const { pathItem, operation, displayName } = builder.fromExtractedWebhook(webhook)!;\n\n entries.push({\n type: 'webhook',\n schemaId: builder.id,\n info: {\n title: displayName,\n description: operation.description ?? pathItem.description,\n },\n item: webhook,\n });\n }\n\n for (const entry of group(builder, entries)) {\n builder.create(entry);\n }\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"preset-auto.js","names":["path"],"sources":["../../../src/utils/pages/preset-auto.ts"],"sourcesContent":["import * as path from 'node:path';\nimport type { DereferencedDocument } from '@/utils/document/dereference';\nimport type {\n OperationOutput,\n OutputEntry,\n OutputGroup,\n PageOutput,\n PagesBuilder,\n PagesBuilderConfig,\n WebhookOutput,\n} from '@/utils/pages/builder';\nimport { isUrl } from '@/utils/url';\nimport type { DistributiveOmit } from '@/types';\n\ninterface OperationConfig extends BaseConfig {\n /**\n * Generate a page for each API endpoint/operation (default).\n */\n per?: 'operation';\n\n /**\n * Group output using folders (Only works on `operation` mode)\n * - tag: `{tag}/{file}`\n * - route: `{endpoint}/{method}` (it will ignore the `name` option)\n * - none: `{file}` (default)\n * - a function that aligns group name (folder path) to each entry\n *\n * @defaultValue 'none'\n */\n groupBy?:\n | 'tag'\n | 'route'\n | 'none'\n | ((entry: DistributiveOmit<OperationOutput | WebhookOutput, 'path'>) => string);\n\n /**\n * Specify name for output file\n */\n name?: NameFn<OperationOutput | WebhookOutput> | NameFnOptions;\n}\n\ninterface TagConfig extends BaseConfig {\n /**\n * Generate a page for each tag.\n */\n per: 'tag';\n\n /**\n * Specify name for output file\n */\n name?: NameFn<PageOutput> | NameFnOptions;\n}\n\ninterface SchemaConfig extends BaseConfig {\n /**\n * Generate a page for each schema file.\n */\n per: 'file';\n\n /**\n * Specify name for output file\n */\n name?: NameFn<PageOutput> | NameFnOptions;\n}\n\nexport type SchemaToPagesOptions =\n | SchemaConfig\n | TagConfig\n | OperationConfig\n | ({\n per: 'custom';\n } & PagesBuilderConfig);\n\ntype NameFn<\n Entry extends OperationOutput | WebhookOutput | PageOutput =\n | OperationOutput\n | WebhookOutput\n | PageOutput,\n> = (\n this: PagesBuilder,\n output: DistributiveOmit<Entry, 'path'>,\n document: DereferencedDocument['dereferenced'],\n) => string;\n\ninterface NameFnOptions {\n /**\n * The version of algorithm used to generate file paths.\n *\n * v1: Fumadocs OpenAPI v8\n * v2: Fumadocs OpenAPI v9\n *\n * @defaultValue v2\n */\n algorithm?: 'v2' | 'v1';\n}\n\ninterface BaseConfig {\n /**\n * Custom function to convert names into file names.\n *\n * By default, it only escapes whitespaces and upper case (English) characters\n */\n slugify?: (name: string) => string;\n}\n\nexport function createAutoPreset(options: SchemaToPagesOptions): PagesBuilderConfig {\n if (options.per === 'custom') return options;\n const {\n slugify = (s) => {\n return s.replace(/\\s+/g, '-').toLowerCase();\n },\n } = options;\n let nameFn: NameFn;\n\n if (typeof options.name === 'function') {\n nameFn = options.name as NameFn;\n } else {\n const { algorithm = 'v2' } = options.name ?? {};\n\n nameFn = function (result, document) {\n if (result.type === 'page') {\n if (result.tag) return slugify(result.tag.name!);\n const schemaId = result.schemaId;\n\n return isUrl(schemaId) ? 'index' : path.basename(schemaId, path.extname(schemaId));\n }\n\n if (result.type === 'operation') {\n const operation = document.paths![result.item.path]![result.item.method]!;\n\n if (algorithm === 'v2' && operation.operationId) {\n return operation.operationId;\n }\n\n return path.join(\n this.routePathToFilePath(result.item.path),\n result.item.method.toLowerCase(),\n );\n }\n\n const hook = document.webhooks![result.item.name][result.item.method]!;\n\n if (algorithm === 'v2' && hook.operationId) {\n return hook.operationId;\n }\n\n return slugify(result.item.name);\n };\n }\n\n function group(\n builder: PagesBuilder,\n entries: DistributiveOmit<OperationOutput | WebhookOutput, 'path'>[],\n ): OutputEntry[] {\n const groups = new Map<string, OutputGroup>();\n const rest: OutputEntry[] = [];\n const { dereferenced } = builder.document;\n const { groupBy = 'none' } = options as OperationConfig;\n\n for (const entry of entries) {\n switch (groupBy) {\n case 'route': {\n const groupName = builder.routePathToFilePath(\n entry.type === 'operation' ? entry.item.path : entry.item.name,\n );\n\n let group = groups.get(groupName);\n if (!group) {\n group = {\n type: 'group',\n info: { title: groupName },\n entries: [],\n schemaId: builder.id,\n path: groupName,\n };\n groups.set(groupName, group);\n }\n\n group.entries.push({\n ...entry,\n path: path.join(groupName, `${entry.item.method.toLowerCase()}.mdx`),\n });\n break;\n }\n case 'tag': {\n let tags =\n entry.type === 'operation'\n ? dereferenced.paths![entry.item.path]![entry.item.method]!.tags\n : dereferenced.webhooks![entry.item.name][entry.item.method]!.tags;\n\n if (!tags || tags.length === 0) {\n console.warn(\n 'When `groupBy` is set to `tag`, make sure a `tags` is defined for every operation schema.',\n );\n\n tags = ['unknown'];\n }\n\n for (const tag of tags) {\n const groupName = slugify(tag);\n const { displayName, info } = builder.fromTagName(tag)!;\n let group = groups.get(groupName);\n if (!group) {\n group = {\n type: 'group',\n info: { title: displayName, description: info.description },\n tag: info,\n entries: [],\n schemaId: builder.id,\n path: groupName,\n };\n groups.set(groupName, group);\n }\n\n group.entries.push({\n ...entry,\n path: path.join(groupName, `${nameFn.call(builder, entry, dereferenced)}.mdx`),\n });\n }\n\n break;\n }\n default: {\n const fileName = `${nameFn.call(builder, entry, dereferenced)}.mdx`;\n\n if (typeof groupBy === 'function') {\n const groupDisplayName = groupBy(entry);\n const groupName = slugify(groupDisplayName);\n\n let group = groups.get(groupName);\n if (!group) {\n group = {\n type: 'group',\n info: { title: groupDisplayName },\n entries: [],\n schemaId: builder.id,\n path: groupName,\n };\n groups.set(groupName, group);\n }\n\n group.entries.push({\n ...entry,\n path: path.join(groupName, fileName),\n });\n break;\n }\n\n rest.push({\n ...entry,\n path: fileName,\n });\n }\n }\n }\n\n rest.push(...groups.values());\n return rest;\n }\n\n return {\n toPages(builder) {\n const { dereferenced } = builder.document;\n const items = builder.extract();\n\n if (options.per === 'file') {\n const entry: PageOutput = {\n type: 'page',\n schemaId: builder.id,\n path: '',\n info: {\n title: dereferenced.info?.title ?? 'Unknown',\n description: dereferenced.info?.description,\n },\n ...items,\n };\n entry.path = `${nameFn.call(builder, entry, dereferenced)}.mdx`;\n builder.create(entry);\n return;\n }\n\n if (options.per === 'tag') {\n const tags = dereferenced.tags ?? [];\n\n for (const tag of tags) {\n const { displayName } = builder.fromTag(tag);\n const entry: PageOutput = {\n type: 'page',\n path: '',\n schemaId: builder.id,\n info: {\n title: displayName,\n description: tag.description,\n },\n webhooks: items.webhooks.filter((webhook) => webhook.tags?.includes(tag.name!)),\n operations: items.operations.filter((op) => op.tags?.includes(tag.name!)),\n tag,\n };\n\n entry.path = `${nameFn.call(builder, entry, dereferenced)}.mdx`;\n builder.create(entry);\n }\n\n return;\n }\n\n const entries: DistributiveOmit<OperationOutput | WebhookOutput, 'path'>[] = [];\n for (const op of items.operations) {\n const { pathItem, operation, displayName } = builder.fromExtractedOperation(op)!;\n\n entries.push({\n type: 'operation',\n schemaId: builder.id,\n item: op,\n info: {\n title: displayName,\n description: operation.description ?? pathItem.description,\n },\n });\n }\n\n for (const webhook of items.webhooks) {\n const { pathItem, operation, displayName } = builder.fromExtractedWebhook(webhook)!;\n\n entries.push({\n type: 'webhook',\n schemaId: builder.id,\n info: {\n title: displayName,\n description: operation.description ?? pathItem.description,\n },\n item: webhook,\n });\n }\n\n for (const entry of group(builder, entries)) {\n builder.create(entry);\n }\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"to-text.js","names":[],"sources":["../../../src/utils/pages/to-text.ts"],"sourcesContent":["import type { ApiPageProps, OperationItem, WebhookItem } from '@/ui/api-page';\nimport type {
|
|
1
|
+
{"version":3,"file":"to-text.js","names":[],"sources":["../../../src/utils/pages/to-text.ts"],"sourcesContent":["import type { ApiPageProps, OperationItem, WebhookItem } from '@/ui/api-page';\nimport type { DereferencedDocument } from '@/utils/document/dereference';\nimport type { TagObject } from '@/types';\nimport { dump } from 'js-yaml';\nimport { removeUndefined } from '@/utils/remove-undefined';\nimport type { OperationOutput, PageOutput, WebhookOutput } from '@/utils/pages/builder';\nimport type { InternalOpenAPIMeta } from '@/server/source-api';\nimport { toStaticData } from '@/utils/pages/to-static-data';\n\nexport interface PagesToTextOptions {\n /**\n * Additional imports of your MDX components.\n */\n imports?: {\n names: string[];\n from: string;\n }[];\n\n /**\n * Customise frontmatter.\n *\n * A `full: true` property will be added by default.\n */\n frontmatter?: (\n title: string,\n description: string | undefined,\n context: DocumentContext,\n ) => Record<string, unknown>;\n\n /**\n * Add description to document body.\n *\n * We recommend but don't enable it by default because some OpenAPI schemas have invalid description that breaks MDX syntax.\n *\n * @defaultValue false\n */\n includeDescription?: boolean;\n\n /**\n * Add a comment to the top of generated files indicating they are auto-generated.\n * - `true`: Adds a standardized comment\n * - `false`: No comment is added\n * - `string`: Adds the provided custom comment\n *\n * @defaultValue true\n */\n addGeneratedComment?: boolean | string;\n}\n\nexport function toText(\n entry: PageOutput | OperationOutput | WebhookOutput,\n processed: DereferencedDocument,\n options: PagesToTextOptions = {},\n) {\n switch (entry.type) {\n case 'operation':\n return generatePage(\n entry.schemaId,\n processed,\n {\n operations: [entry.item],\n },\n {\n ...options,\n ...entry.info,\n },\n {\n type: 'operation',\n },\n );\n case 'page':\n return generatePage(\n entry.schemaId,\n processed,\n {\n operations: entry.operations,\n webhooks: entry.webhooks,\n showTitle: true,\n },\n {\n ...options,\n ...entry.info,\n },\n entry.tag\n ? {\n type: 'tag',\n tag: entry.tag,\n }\n : {\n type: 'file',\n },\n );\n case 'webhook':\n return generatePage(\n entry.schemaId,\n processed,\n {\n webhooks: [entry.item],\n },\n {\n ...options,\n ...entry.info,\n },\n {\n type: 'operation',\n },\n );\n }\n}\n\nexport function generateDocument(\n frontmatter: unknown,\n content: string,\n options: PagesToTextOptions,\n): string {\n const { addGeneratedComment = true, imports } = options;\n const out: string[] = [];\n const banner = dump(removeUndefined(frontmatter as object)).trimEnd();\n if (banner.length > 0) out.push(`---\\n${banner}\\n---`);\n\n if (addGeneratedComment) {\n let commentContent =\n 'This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again.';\n\n if (typeof addGeneratedComment === 'string') {\n commentContent = addGeneratedComment;\n }\n\n commentContent = commentContent.replaceAll('/', '\\\\/');\n out.push(`{/* ${commentContent} */}`);\n }\n\n if (imports) {\n out.push(\n ...imports\n .map((item) => `import { ${item.names.join(', ')} } from ${JSON.stringify(item.from)};`)\n .join('\\n'),\n );\n }\n\n out.push(content);\n return out.join('\\n\\n');\n}\n\nexport type DocumentContext =\n | {\n type: 'tag';\n tag: TagObject | undefined;\n }\n | {\n type: 'operation';\n }\n | {\n type: 'file';\n };\n\nfunction generatePage(\n schemaId: string,\n processed: DereferencedDocument,\n pageProps: Omit<ApiPageProps, 'document'>,\n options: PagesToTextOptions & {\n title: string;\n description?: string;\n },\n context: DocumentContext,\n): string {\n const { frontmatter, includeDescription = false } = options;\n const extend = frontmatter?.(options.title, options.description, context);\n const page: ApiPageProps = {\n ...pageProps,\n document: schemaId,\n };\n\n let meta: InternalOpenAPIMeta | undefined;\n if (page.operations?.length === 1) {\n const operation = page.operations[0];\n\n meta = {\n method: operation.method.toUpperCase(),\n };\n } else if (page.webhooks?.length === 1) {\n const webhook = page.webhooks[0];\n\n meta = {\n method: webhook.method.toUpperCase(),\n webhook: true,\n };\n }\n\n const data = toStaticData(page, processed.dereferenced);\n const content: string[] = [];\n\n if (options.description && includeDescription) content.push(options.description);\n content.push(pageContent(page));\n\n return generateDocument(\n {\n title: options.title,\n description: !includeDescription ? options.description : undefined,\n full: true,\n ...extend,\n _openapi: {\n ...meta,\n ...data,\n ...(extend?._openapi as object | undefined),\n },\n },\n content.join('\\n\\n'),\n options,\n );\n}\n\nfunction pageContent({\n showTitle,\n showDescription,\n document,\n webhooks,\n operations,\n}: ApiPageProps): string {\n const propStrs: string[] = [`document={${JSON.stringify(document)}}`];\n\n // filter extra properties in props\n if (webhooks) {\n propStrs.push(\n `webhooks={${JSON.stringify(\n webhooks.map(\n (item) =>\n ({\n name: item.name,\n method: item.method,\n }) satisfies WebhookItem,\n ),\n )}}`,\n );\n }\n if (operations) {\n propStrs.push(\n `operations={${JSON.stringify(\n operations.map(\n (item) =>\n ({\n path: item.path,\n method: item.method,\n }) satisfies OperationItem,\n ),\n )}}`,\n );\n }\n if (showTitle) {\n propStrs.push(`showTitle={${JSON.stringify(showTitle)}}`);\n }\n if (showDescription) {\n propStrs.push(`showDescription={${JSON.stringify(showDescription)}}`);\n }\n\n return `<APIPage ${propStrs.join(' ')} />`;\n}\n"],"mappings":";;;;AAiDA,SAAgB,OACd,OACA,WACA,UAA8B,EAAE,EAChC;AACA,SAAQ,MAAM,MAAd;EACE,KAAK,YACH,QAAO,aACL,MAAM,UACN,WACA,EACE,YAAY,CAAC,MAAM,KAAK,EACzB,EACD;GACE,GAAG;GACH,GAAG,MAAM;GACV,EACD,EACE,MAAM,aACP,CACF;EACH,KAAK,OACH,QAAO,aACL,MAAM,UACN,WACA;GACE,YAAY,MAAM;GAClB,UAAU,MAAM;GAChB,WAAW;GACZ,EACD;GACE,GAAG;GACH,GAAG,MAAM;GACV,EACD,MAAM,MACF;GACE,MAAM;GACN,KAAK,MAAM;GACZ,GACD,EACE,MAAM,QACP,CACN;EACH,KAAK,UACH,QAAO,aACL,MAAM,UACN,WACA,EACE,UAAU,CAAC,MAAM,KAAK,EACvB,EACD;GACE,GAAG;GACH,GAAG,MAAM;GACV,EACD,EACE,MAAM,aACP,CACF;;;AAIP,SAAgB,iBACd,aACA,SACA,SACQ;CACR,MAAM,EAAE,sBAAsB,MAAM,YAAY;CAChD,MAAM,MAAgB,EAAE;CACxB,MAAM,SAAS,KAAK,gBAAgB,YAAsB,CAAC,CAAC,SAAS;AACrE,KAAI,OAAO,SAAS,EAAG,KAAI,KAAK,QAAQ,OAAO,OAAO;AAEtD,KAAI,qBAAqB;EACvB,IAAI,iBACF;AAEF,MAAI,OAAO,wBAAwB,SACjC,kBAAiB;AAGnB,mBAAiB,eAAe,WAAW,KAAK,MAAM;AACtD,MAAI,KAAK,OAAO,eAAe,MAAM;;AAGvC,KAAI,QACF,KAAI,KACF,GAAG,QACA,KAAK,SAAS,YAAY,KAAK,MAAM,KAAK,KAAK,CAAC,UAAU,KAAK,UAAU,KAAK,KAAK,CAAC,GAAG,CACvF,KAAK,KAAK,CACd;AAGH,KAAI,KAAK,QAAQ;AACjB,QAAO,IAAI,KAAK,OAAO;;AAezB,SAAS,aACP,UACA,WACA,WACA,SAIA,SACQ;CACR,MAAM,EAAE,aAAa,qBAAqB,UAAU;CACpD,MAAM,SAAS,cAAc,QAAQ,OAAO,QAAQ,aAAa,QAAQ;CACzE,MAAM,OAAqB;EACzB,GAAG;EACH,UAAU;EACX;CAED,IAAI;AACJ,KAAI,KAAK,YAAY,WAAW,EAG9B,QAAO,EACL,QAHgB,KAAK,WAAW,GAGd,OAAO,aAAa,EACvC;UACQ,KAAK,UAAU,WAAW,EAGnC,QAAO;EACL,QAHc,KAAK,SAAS,GAGZ,OAAO,aAAa;EACpC,SAAS;EACV;CAGH,MAAM,OAAO,aAAa,MAAM,UAAU,aAAa;CACvD,MAAM,UAAoB,EAAE;AAE5B,KAAI,QAAQ,eAAe,mBAAoB,SAAQ,KAAK,QAAQ,YAAY;AAChF,SAAQ,KAAK,YAAY,KAAK,CAAC;AAE/B,QAAO,iBACL;EACE,OAAO,QAAQ;EACf,aAAa,CAAC,qBAAqB,QAAQ,cAAc,KAAA;EACzD,MAAM;EACN,GAAG;EACH,UAAU;GACR,GAAG;GACH,GAAG;GACH,GAAI,QAAQ;GACb;EACF,EACD,QAAQ,KAAK,OAAO,EACpB,QACD;;AAGH,SAAS,YAAY,EACnB,WACA,iBACA,UACA,UACA,cACuB;CACvB,MAAM,WAAqB,CAAC,aAAa,KAAK,UAAU,SAAS,CAAC,GAAG;AAGrE,KAAI,SACF,UAAS,KACP,aAAa,KAAK,UAChB,SAAS,KACN,UACE;EACC,MAAM,KAAK;EACX,QAAQ,KAAK;EACd,EACJ,CACF,CAAC,GACH;AAEH,KAAI,WACF,UAAS,KACP,eAAe,KAAK,UAClB,WAAW,KACR,UACE;EACC,MAAM,KAAK;EACX,QAAQ,KAAK;EACd,EACJ,CACF,CAAC,GACH;AAEH,KAAI,UACF,UAAS,KAAK,cAAc,KAAK,UAAU,UAAU,CAAC,GAAG;AAE3D,KAAI,gBACF,UAAS,KAAK,oBAAoB,KAAK,UAAU,gBAAgB,CAAC,GAAG;AAGvE,QAAO,YAAY,SAAS,KAAK,IAAI,CAAC"}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import { isPlainObject } from "./is-plain-object.js";
|
|
1
2
|
//#region src/utils/remove-undefined.ts
|
|
2
3
|
function removeUndefined(value, deep = false) {
|
|
3
|
-
|
|
4
|
-
for (const key in
|
|
5
|
-
|
|
6
|
-
if (
|
|
7
|
-
|
|
8
|
-
if (typeof entry === "object" && entry !== null) {
|
|
9
|
-
removeUndefined(entry, deep);
|
|
4
|
+
if (!isPlainObject(value)) return value;
|
|
5
|
+
for (const key in value) {
|
|
6
|
+
const prop = value[key];
|
|
7
|
+
if (prop === void 0) {
|
|
8
|
+
delete value[key];
|
|
10
9
|
continue;
|
|
11
10
|
}
|
|
12
|
-
if (
|
|
11
|
+
if (deep) {
|
|
12
|
+
if (Array.isArray(prop)) for (const item of prop) removeUndefined(item, deep);
|
|
13
|
+
if (isPlainObject(prop)) removeUndefined(prop, deep);
|
|
14
|
+
}
|
|
13
15
|
}
|
|
14
16
|
return value;
|
|
15
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove-undefined.js","names":[],"sources":["../../src/utils/remove-undefined.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"remove-undefined.js","names":[],"sources":["../../src/utils/remove-undefined.ts"],"sourcesContent":["import { isPlainObject } from './is-plain-object';\n\nexport function removeUndefined<T extends object>(value: T, deep = false): T {\n if (!isPlainObject(value)) return value;\n\n for (const key in value) {\n const prop = value[key];\n if (prop === undefined) {\n delete value[key];\n continue;\n }\n\n if (deep) {\n if (Array.isArray(prop)) {\n for (const item of prop) removeUndefined(item, deep);\n }\n\n if (isPlainObject(prop)) {\n removeUndefined(prop, deep);\n }\n }\n }\n\n return value;\n}\n"],"mappings":";;AAEA,SAAgB,gBAAkC,OAAU,OAAO,OAAU;AAC3E,KAAI,CAAC,cAAc,MAAM,CAAE,QAAO;AAElC,MAAK,MAAM,OAAO,OAAO;EACvB,MAAM,OAAO,MAAM;AACnB,MAAI,SAAS,KAAA,GAAW;AACtB,UAAO,MAAM;AACb;;AAGF,MAAI,MAAM;AACR,OAAI,MAAM,QAAQ,KAAK,CACrB,MAAK,MAAM,QAAQ,KAAM,iBAAgB,MAAM,KAAK;AAGtD,OAAI,cAAc,KAAK,CACrB,iBAAgB,MAAM,KAAK;;;AAKjC,QAAO"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReferenceObject } from "../../types.js";
|
|
1
|
+
import { ReferenceObject, SecuritySchemeObject } from "../../types.js";
|
|
2
2
|
import { JSONSchema } from "json-schema-typed/draft-2020-12";
|
|
3
3
|
|
|
4
4
|
//#region src/utils/schema/index.d.ts
|
|
@@ -10,6 +10,11 @@ type ParsedSchema = (JSONSchema & {
|
|
|
10
10
|
'x-playground-lazy'?: boolean;
|
|
11
11
|
}) | boolean;
|
|
12
12
|
type ResolvedSchema = NoReferenceJSONSchema<ParsedSchema>;
|
|
13
|
+
/** parsed security scheme objects */
|
|
14
|
+
type SecurityEntry = SecuritySchemeObject & {
|
|
15
|
+
scopes: string[];
|
|
16
|
+
id: string;
|
|
17
|
+
};
|
|
13
18
|
//#endregion
|
|
14
|
-
export { NoReference, ParsedSchema, ResolvedSchema };
|
|
19
|
+
export { NoReference, ParsedSchema, ResolvedSchema, SecurityEntry };
|
|
15
20
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/utils/schema/index.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/utils/schema/index.ts"],"mappings":";;;;KAiBY,WAAA,MAAiB,CAAA,uBACzB,WAAA,CAAY,CAAA,MACZ,CAAA,SAAU,eAAA,GACR,OAAA,CAAQ,CAAA,EAAG,eAAA,IACX,CAAA,gCAEgB,CAAA,GAAI,WAAA,CAAY,CAAA,CAAE,CAAA,OAEhC,CAAA;AAAA,KAEH,qBAAA,MAA2B,CAAA,uBAC5B,WAAA,CAAY,CAAA,MACZ,CAAA;EAAY,IAAA;AAAA,IACV,IAAA,CAAK,CAAA,YACL,CAAA;AAAA,KAEM,YAAA,IACP,UAAA;EACC,mBAAA;AAAA;AAAA,KAGM,cAAA,GAAiB,qBAAA,CAAsB,YAAA;;KAkEvC,aAAA,GAAgB,oBAAA;EAC1B,MAAA;EACA,EAAA;AAAA"}
|
|
@@ -27,7 +27,7 @@ function createMethod(method, path, operation) {
|
|
|
27
27
|
...operation,
|
|
28
28
|
servers: operation.servers ?? path.servers,
|
|
29
29
|
parameters: [...operation.parameters ?? [], ...path.parameters ?? []],
|
|
30
|
-
method
|
|
30
|
+
method
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
function pickExample(value) {
|
|
@@ -45,7 +45,26 @@ function pickExample(value) {
|
|
|
45
45
|
if (examples.length > 0) return examples[0].value;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
+
function parseSecurities(method, dereferenced) {
|
|
49
|
+
const result = [];
|
|
50
|
+
const security = method.security ?? dereferenced.security ?? [];
|
|
51
|
+
if (security.length === 0) return result;
|
|
52
|
+
for (const map of security) {
|
|
53
|
+
const list = [];
|
|
54
|
+
for (const [key, scopes] of Object.entries(map)) {
|
|
55
|
+
const scheme = dereferenced.components?.securitySchemes?.[key];
|
|
56
|
+
if (!scheme) continue;
|
|
57
|
+
list.push({
|
|
58
|
+
...scheme,
|
|
59
|
+
scopes,
|
|
60
|
+
id: key
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
if (list.length > 0) result.push(list);
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
48
67
|
//#endregion
|
|
49
|
-
export { createMethod, getPreferredType, getTagDisplayName, methodKeys, pickExample };
|
|
68
|
+
export { createMethod, getPreferredType, getTagDisplayName, methodKeys, parseSecurities, pickExample };
|
|
50
69
|
|
|
51
70
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/utils/schema/index.ts"],"sourcesContent":["import type { JSONSchema } from 'json-schema-typed/draft-2020-12';\nimport type {\n ExampleObject,\n MediaTypeObject,\n MethodInformation,\n OperationObject,\n PathItemObject,\n ReferenceObject,\n TagObject,\n} from '@/types';\nimport { idToTitle } from '@/utils/id-to-title';\n\nexport const methodKeys = ['get', 'post', 'patch', 'delete', 'head', 'put'] as const;\n\nexport type NoReference<T> = T extends (infer I)[]\n ? NoReference<I>[]\n : T extends ReferenceObject\n ? Exclude<T, ReferenceObject>\n : T extends object\n ? {\n [K in keyof T]: NoReference<T[K]>;\n }\n : T;\n\ntype NoReferenceJSONSchema<T> = T extends (infer I)[]\n ? NoReference<I>[]\n : T extends { $ref?: string }\n ? Omit<T, '$ref'>\n : T;\n\nexport type ParsedSchema =\n | (JSONSchema & {\n 'x-playground-lazy'?: boolean;\n })\n | boolean;\nexport type ResolvedSchema = NoReferenceJSONSchema<ParsedSchema>;\n\nexport function getPreferredType(body: Record<string, unknown>): string | undefined {\n if ('application/json' in body) return 'application/json';\n\n return Object.keys(body)[0];\n}\n\nexport function getTagDisplayName(tag: TagObject): string {\n if ('x-displayName' in tag && typeof tag['x-displayName'] === 'string')\n return tag['x-displayName'];\n\n if (tag.summary) return tag.summary;\n return idToTitle(tag.name!);\n}\n\n/**\n * Summarize method endpoint information\n */\nexport function createMethod(\n method:
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/utils/schema/index.ts"],"sourcesContent":["import type { JSONSchema } from 'json-schema-typed/draft-2020-12';\nimport type {\n Document,\n ExampleObject,\n HttpMethods,\n MediaTypeObject,\n MethodInformation,\n OperationObject,\n PathItemObject,\n ReferenceObject,\n SecuritySchemeObject,\n TagObject,\n} from '@/types';\nimport { idToTitle } from '@/utils/id-to-title';\n\nexport const methodKeys = ['get', 'post', 'patch', 'delete', 'head', 'put'] as const;\n\nexport type NoReference<T> = T extends (infer I)[]\n ? NoReference<I>[]\n : T extends ReferenceObject\n ? Exclude<T, ReferenceObject>\n : T extends object\n ? {\n [K in keyof T]: NoReference<T[K]>;\n }\n : T;\n\ntype NoReferenceJSONSchema<T> = T extends (infer I)[]\n ? NoReference<I>[]\n : T extends { $ref?: string }\n ? Omit<T, '$ref'>\n : T;\n\nexport type ParsedSchema =\n | (JSONSchema & {\n 'x-playground-lazy'?: boolean;\n })\n | boolean;\nexport type ResolvedSchema = NoReferenceJSONSchema<ParsedSchema>;\n\nexport function getPreferredType(body: Record<string, unknown>): string | undefined {\n if ('application/json' in body) return 'application/json';\n\n return Object.keys(body)[0];\n}\n\nexport function getTagDisplayName(tag: TagObject): string {\n if ('x-displayName' in tag && typeof tag['x-displayName'] === 'string')\n return tag['x-displayName'];\n\n if (tag.summary) return tag.summary;\n return idToTitle(tag.name!);\n}\n\n/**\n * Summarize method endpoint information\n */\nexport function createMethod(\n method: HttpMethods,\n path: NoReference<PathItemObject>,\n operation: NoReference<OperationObject>,\n): MethodInformation {\n return {\n description: path.description,\n summary: path.summary,\n ...operation,\n servers: operation.servers ?? path.servers,\n parameters: [...(operation.parameters ?? []), ...(path.parameters ?? [])],\n method,\n };\n}\n\ninterface ExampleLike {\n example?: unknown;\n examples?: {\n [media: string]: ExampleObject;\n };\n content?: {\n [media: string]: MediaTypeObject;\n };\n}\n\nexport function pickExample(value: ExampleLike): unknown | undefined {\n if (value.example !== undefined) {\n return value.example;\n }\n\n if (value.content) {\n const type = getPreferredType(value.content);\n const content = type ? value.content[type] : undefined;\n\n if (type && content) {\n const out = value.examples?.[type].value ?? pickExample(content);\n if (out !== undefined) return out;\n }\n }\n\n if (value.examples) {\n const examples = Object.values(value.examples);\n if (examples.length > 0) return examples[0].value;\n }\n}\n\n/** parsed security scheme objects */\nexport type SecurityEntry = SecuritySchemeObject & {\n scopes: string[];\n id: string;\n};\n\nexport function parseSecurities(\n method: MethodInformation,\n dereferenced: NoReference<Document>,\n): SecurityEntry[][] {\n const result: SecurityEntry[][] = [];\n const security = method.security ?? dereferenced.security ?? [];\n if (security.length === 0) return result;\n\n for (const map of security) {\n const list: SecurityEntry[] = [];\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":";;AAeA,MAAa,aAAa;CAAC;CAAO;CAAQ;CAAS;CAAU;CAAQ;CAAM;AAyB3E,SAAgB,iBAAiB,MAAmD;AAClF,KAAI,sBAAsB,KAAM,QAAO;AAEvC,QAAO,OAAO,KAAK,KAAK,CAAC;;AAG3B,SAAgB,kBAAkB,KAAwB;AACxD,KAAI,mBAAmB,OAAO,OAAO,IAAI,qBAAqB,SAC5D,QAAO,IAAI;AAEb,KAAI,IAAI,QAAS,QAAO,IAAI;AAC5B,QAAO,UAAU,IAAI,KAAM;;;;;AAM7B,SAAgB,aACd,QACA,MACA,WACmB;AACnB,QAAO;EACL,aAAa,KAAK;EAClB,SAAS,KAAK;EACd,GAAG;EACH,SAAS,UAAU,WAAW,KAAK;EACnC,YAAY,CAAC,GAAI,UAAU,cAAc,EAAE,EAAG,GAAI,KAAK,cAAc,EAAE,CAAE;EACzE;EACD;;AAaH,SAAgB,YAAY,OAAyC;AACnE,KAAI,MAAM,YAAY,KAAA,EACpB,QAAO,MAAM;AAGf,KAAI,MAAM,SAAS;EACjB,MAAM,OAAO,iBAAiB,MAAM,QAAQ;EAC5C,MAAM,UAAU,OAAO,MAAM,QAAQ,QAAQ,KAAA;AAE7C,MAAI,QAAQ,SAAS;GACnB,MAAM,MAAM,MAAM,WAAW,MAAM,SAAS,YAAY,QAAQ;AAChE,OAAI,QAAQ,KAAA,EAAW,QAAO;;;AAIlC,KAAI,MAAM,UAAU;EAClB,MAAM,WAAW,OAAO,OAAO,MAAM,SAAS;AAC9C,MAAI,SAAS,SAAS,EAAG,QAAO,SAAS,GAAG;;;AAUhD,SAAgB,gBACd,QACA,cACmB;CACnB,MAAM,SAA4B,EAAE;CACpC,MAAM,WAAW,OAAO,YAAY,aAAa,YAAY,EAAE;AAC/D,KAAI,SAAS,WAAW,EAAG,QAAO;AAElC,MAAK,MAAM,OAAO,UAAU;EAC1B,MAAM,OAAwB,EAAE;AAEhC,OAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QAAQ,IAAI,EAAE;GAC/C,MAAM,SAAS,aAAa,YAAY,kBAAkB;AAC1D,OAAI,CAAC,OAAQ;AAEb,QAAK,KAAK;IACR,GAAG;IACH;IACA,IAAI;IACL,CAAC;;AAGJ,MAAI,KAAK,SAAS,EAAG,QAAO,KAAK,KAAK;;AAGxC,QAAO"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { isPlainObject } from "../is-plain-object.js";
|
|
2
|
+
import { decodeInternalRef } from "./ref.js";
|
|
3
|
+
import { resolveRefSync } from "./resolve-ref.js";
|
|
4
|
+
//#region src/utils/schema/pick.ts
|
|
5
|
+
/**
|
|
6
|
+
* return a filtered object that only contains the given `$ref` & its referenced fields.
|
|
7
|
+
*/
|
|
8
|
+
function pickSchema(root, $ref) {
|
|
9
|
+
const out = {};
|
|
10
|
+
const scanned = /* @__PURE__ */ new Set();
|
|
11
|
+
function scan(next) {
|
|
12
|
+
if (isPlainObject(next)) {
|
|
13
|
+
if (typeof next.$ref === "string") {
|
|
14
|
+
if (scanned.has(next.$ref)) return;
|
|
15
|
+
const resolved = resolveRefSync(next.$ref, root);
|
|
16
|
+
scanned.add(next.$ref);
|
|
17
|
+
scan(resolved);
|
|
18
|
+
setField(out, decodeInternalRef(next.$ref), resolved);
|
|
19
|
+
}
|
|
20
|
+
for (const k in next) scan(next[k]);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (Array.isArray(next)) for (const item of next) scan(item);
|
|
24
|
+
}
|
|
25
|
+
scan({ $ref });
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
function setField(obj, field, value) {
|
|
29
|
+
if (field.length === 0) return value;
|
|
30
|
+
const out = isPlainObject(obj) ? obj : {};
|
|
31
|
+
let current = out;
|
|
32
|
+
for (let i = 0; i < field.length; i++) {
|
|
33
|
+
const k = field[i];
|
|
34
|
+
if (i === field.length - 1) current[k] = value;
|
|
35
|
+
else {
|
|
36
|
+
const v = current[k];
|
|
37
|
+
if (isPlainObject(v)) current = v;
|
|
38
|
+
else current = current[k] = {};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { pickSchema };
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=pick.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pick.js","names":[],"sources":["../../../src/utils/schema/pick.ts"],"sourcesContent":["import { isPlainObject } from '../is-plain-object';\nimport { decodeInternalRef } from './ref';\nimport { resolveRefSync } from './resolve-ref';\n\n/**\n * return a filtered object that only contains the given `$ref` & its referenced fields.\n */\nexport function pickSchema(root: object, $ref: string): object {\n const out: object = {};\n const scanned = new Set<string>();\n\n function scan(next: unknown) {\n if (isPlainObject(next)) {\n if (typeof next.$ref === 'string') {\n if (scanned.has(next.$ref)) return;\n\n const resolved = resolveRefSync(next.$ref, root);\n scanned.add(next.$ref);\n scan(resolved);\n setField(out, decodeInternalRef(next.$ref), resolved);\n }\n\n for (const k in next) scan(next[k]);\n return;\n }\n\n if (Array.isArray(next)) {\n for (const item of next) scan(item);\n }\n }\n\n scan({ $ref });\n return out;\n}\n\nfunction setField(obj: unknown, field: string[], value: unknown): unknown {\n if (field.length === 0) return value;\n\n const out: Record<string, unknown> = isPlainObject(obj) ? obj : {};\n let current = out;\n\n for (let i = 0; i < field.length; i++) {\n const k = field[i];\n\n if (i === field.length - 1) {\n current[k] = value;\n } else {\n const v = current[k];\n\n if (isPlainObject(v)) {\n current = v;\n } else {\n current = current[k] = {};\n }\n }\n }\n\n return out;\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,WAAW,MAAc,MAAsB;CAC7D,MAAM,MAAc,EAAE;CACtB,MAAM,0BAAU,IAAI,KAAa;CAEjC,SAAS,KAAK,MAAe;AAC3B,MAAI,cAAc,KAAK,EAAE;AACvB,OAAI,OAAO,KAAK,SAAS,UAAU;AACjC,QAAI,QAAQ,IAAI,KAAK,KAAK,CAAE;IAE5B,MAAM,WAAW,eAAe,KAAK,MAAM,KAAK;AAChD,YAAQ,IAAI,KAAK,KAAK;AACtB,SAAK,SAAS;AACd,aAAS,KAAK,kBAAkB,KAAK,KAAK,EAAE,SAAS;;AAGvD,QAAK,MAAM,KAAK,KAAM,MAAK,KAAK,GAAG;AACnC;;AAGF,MAAI,MAAM,QAAQ,KAAK,CACrB,MAAK,MAAM,QAAQ,KAAM,MAAK,KAAK;;AAIvC,MAAK,EAAE,MAAM,CAAC;AACd,QAAO;;AAGT,SAAS,SAAS,KAAc,OAAiB,OAAyB;AACxE,KAAI,MAAM,WAAW,EAAG,QAAO;CAE/B,MAAM,MAA+B,cAAc,IAAI,GAAG,MAAM,EAAE;CAClE,IAAI,UAAU;AAEd,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,IAAI,MAAM;AAEhB,MAAI,MAAM,MAAM,SAAS,EACvB,SAAQ,KAAK;OACR;GACL,MAAM,IAAI,QAAQ;AAElB,OAAI,cAAc,EAAE,CAClB,WAAU;OAEV,WAAU,QAAQ,KAAK,EAAE;;;AAK/B,QAAO"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/utils/schema/ref.ts
|
|
2
|
+
/**
|
|
3
|
+
* RFC 6901 reference-token encoding for JSON Pointer fragments used in in-document `$ref` (`#/…`).
|
|
4
|
+
*
|
|
5
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6901
|
|
6
|
+
*/
|
|
7
|
+
function encodeSegment(segment) {
|
|
8
|
+
return segment.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
9
|
+
}
|
|
10
|
+
function decodeSegment(segment) {
|
|
11
|
+
return segment.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Build an in-document `$ref` string from logical path segments (e.g. `['components','schemas','Pet']` → `#/components/schemas/Pet`).
|
|
15
|
+
*/
|
|
16
|
+
function encodeInternalRef(segments) {
|
|
17
|
+
if (segments.length === 0) return "#/";
|
|
18
|
+
return `#/${segments.map(encodeSegment).join("/")}`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Parse an in-document `$ref` (`#/…`) into decoded path segments for walking the root document.
|
|
22
|
+
*/
|
|
23
|
+
function decodeInternalRef(ref) {
|
|
24
|
+
if (!ref.startsWith("#")) throw new Error("expected in-document $ref starting with `#`");
|
|
25
|
+
const raw = ref.slice(1);
|
|
26
|
+
const out = [];
|
|
27
|
+
if (raw.length === 0) return out;
|
|
28
|
+
for (const token of raw.split("/")) {
|
|
29
|
+
if (token.length === 0) continue;
|
|
30
|
+
out.push(decodeSegment(token));
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { decodeInternalRef, encodeInternalRef };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=ref.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ref.js","names":[],"sources":["../../../src/utils/schema/ref.ts"],"sourcesContent":["/**\n * RFC 6901 reference-token encoding for JSON Pointer fragments used in in-document `$ref` (`#/…`).\n *\n * @see https://datatracker.ietf.org/doc/html/rfc6901\n */\n\nfunction encodeSegment(segment: string): string {\n return segment.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n\nfunction decodeSegment(segment: string): string {\n return segment.replace(/~1/g, '/').replace(/~0/g, '~');\n}\n\n/**\n * Build an in-document `$ref` string from logical path segments (e.g. `['components','schemas','Pet']` → `#/components/schemas/Pet`).\n */\nexport function encodeInternalRef(segments: readonly string[]): string {\n if (segments.length === 0) return '#/';\n return `#/${segments.map(encodeSegment).join('/')}`;\n}\n\n/**\n * Parse an in-document `$ref` (`#/…`) into decoded path segments for walking the root document.\n */\nexport function decodeInternalRef(ref: string): string[] {\n if (!ref.startsWith('#')) {\n throw new Error('expected in-document $ref starting with `#`');\n }\n\n const raw = ref.slice(1);\n const out: string[] = [];\n if (raw.length === 0) return out;\n\n for (const token of raw.split('/')) {\n if (token.length === 0) continue;\n out.push(decodeSegment(token));\n }\n\n return out;\n}\n"],"mappings":";;;;;;AAMA,SAAS,cAAc,SAAyB;AAC9C,QAAO,QAAQ,QAAQ,MAAM,KAAK,CAAC,QAAQ,OAAO,KAAK;;AAGzD,SAAS,cAAc,SAAyB;AAC9C,QAAO,QAAQ,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,IAAI;;;;;AAMxD,SAAgB,kBAAkB,UAAqC;AACrE,KAAI,SAAS,WAAW,EAAG,QAAO;AAClC,QAAO,KAAK,SAAS,IAAI,cAAc,CAAC,KAAK,IAAI;;;;;AAMnD,SAAgB,kBAAkB,KAAuB;AACvD,KAAI,CAAC,IAAI,WAAW,IAAI,CACtB,OAAM,IAAI,MAAM,8CAA8C;CAGhE,MAAM,MAAM,IAAI,MAAM,EAAE;CACxB,MAAM,MAAgB,EAAE;AACxB,KAAI,IAAI,WAAW,EAAG,QAAO;AAE7B,MAAK,MAAM,SAAS,IAAI,MAAM,IAAI,EAAE;AAClC,MAAI,MAAM,WAAW,EAAG;AACxB,MAAI,KAAK,cAAc,MAAM,CAAC;;AAGhC,QAAO"}
|
|
@@ -1,20 +1,12 @@
|
|
|
1
|
+
import { isPlainObject } from "../is-plain-object.js";
|
|
2
|
+
import { decodeInternalRef } from "./ref.js";
|
|
1
3
|
//#region src/utils/schema/resolve-ref.ts
|
|
2
4
|
function resolveRefSync(ref, schema) {
|
|
3
|
-
if (!ref.startsWith("#")) return;
|
|
4
|
-
const segments = ref.slice(1).split("/");
|
|
5
5
|
let current = schema;
|
|
6
|
-
for (const seg of
|
|
7
|
-
|
|
8
|
-
if (isPlainObject(current)) current = current[seg];
|
|
9
|
-
else return;
|
|
10
|
-
}
|
|
6
|
+
for (const seg of decodeInternalRef(ref)) if (isPlainObject(current)) current = current[seg];
|
|
7
|
+
else return;
|
|
11
8
|
return current;
|
|
12
9
|
}
|
|
13
|
-
function isPlainObject(value) {
|
|
14
|
-
if (typeof value !== "object" || value === null) return false;
|
|
15
|
-
const prototype = Object.getPrototypeOf(value);
|
|
16
|
-
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
17
|
-
}
|
|
18
10
|
//#endregion
|
|
19
11
|
export { resolveRefSync };
|
|
20
12
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-ref.js","names":[],"sources":["../../../src/utils/schema/resolve-ref.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"resolve-ref.js","names":[],"sources":["../../../src/utils/schema/resolve-ref.ts"],"sourcesContent":["import { isPlainObject } from '../is-plain-object';\nimport { decodeInternalRef } from './ref';\n\nexport function resolveRefSync(ref: string, schema: unknown): unknown | undefined {\n let current = schema;\n\n for (const seg of decodeInternalRef(ref)) {\n if (isPlainObject(current)) current = current[seg];\n else return;\n }\n\n return current;\n}\n"],"mappings":";;;AAGA,SAAgB,eAAe,KAAa,QAAsC;CAChF,IAAI,UAAU;AAEd,MAAK,MAAM,OAAO,kBAAkB,IAAI,CACtC,KAAI,cAAc,QAAQ,CAAE,WAAU,QAAQ;KACzC;AAGP,QAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"to-string.js","names":[],"sources":["../../../src/utils/schema/to-string.ts"],"sourcesContent":["import type { ParsedSchema, ResolvedSchema } from '@/utils/schema';\nimport type {
|
|
1
|
+
{"version":3,"file":"to-string.js","names":[],"sources":["../../../src/utils/schema/to-string.ts"],"sourcesContent":["import type { ParsedSchema, ResolvedSchema } from '@/utils/schema';\nimport type { DereferencedDocument } from '@/utils/document/dereference';\n\nexport enum FormatFlags {\n None = 0,\n UseAlias = 1 << 0,\n}\n\ntype Resolver = (schema: ResolvedSchema) => {\n dereferenced: ResolvedSchema;\n raw?: ParsedSchema;\n};\n\nexport function schemaToString(\n value: ResolvedSchema,\n _resolver?: DereferencedDocument | Resolver,\n flags: FormatFlags = FormatFlags.None,\n): string {\n const resolver: Resolver =\n typeof _resolver === 'function'\n ? _resolver\n : (schema) => {\n const ref =\n _resolver && typeof schema === 'object' ? _resolver.getRawRef(schema) : undefined;\n\n return {\n dereferenced: schema,\n raw: ref ? { $ref: ref } : undefined,\n };\n };\n function union(union: readonly ResolvedSchema[], sep: string, flags: FormatFlags) {\n const members = new Set();\n let nullable = false;\n\n for (const item of union) {\n const result = run(item, flags | FormatFlags.UseAlias);\n\n if (result === 'null') {\n nullable = true;\n } else if (result !== 'unknown') {\n members.add(result);\n }\n }\n\n const result = Array.from(members).join(sep);\n return nullable ? `${result} | null` : result;\n }\n\n function run(schema: ResolvedSchema, flags: FormatFlags): string {\n const resolved = resolver(schema);\n schema = resolved.dereferenced;\n\n if (schema === true) return 'any';\n else if (schema === false) return 'never';\n\n if ((flags & FormatFlags.UseAlias) === FormatFlags.UseAlias) {\n if (schema.title) return schema.title;\n\n if (typeof resolved.raw === 'object' && resolved.raw.$ref) {\n const ref = resolved.raw.$ref.split('/');\n if (ref.length > 0) return ref[ref.length - 1];\n }\n }\n\n if (Array.isArray(schema.type)) {\n return union(\n schema.type.map((type) => ({\n ...schema,\n type,\n })),\n ' | ',\n flags,\n );\n }\n\n if (schema.type === 'array')\n return `array<${schema.items ? run(schema.items, flags | FormatFlags.UseAlias) : 'unknown'}>`;\n\n const or = schema.oneOf ?? schema.anyOf;\n if (schema.oneOf && schema.anyOf) {\n return `(${union(schema.oneOf, ' | ', flags)}) & (${union(schema.anyOf, ' | ', flags)})`;\n } else if (or) {\n return union(or, ' | ', flags);\n }\n\n if (schema.allOf) {\n return union(schema.allOf, ' & ', flags);\n }\n\n if (schema.not) return `not ${run(schema.not, flags)}`;\n if (schema.type === 'string' && schema.format === 'binary') return 'file';\n\n if (schema.type && Array.isArray(schema.type)) {\n return schema.type.filter((v) => v !== 'null').join(' | ');\n }\n\n if (schema.type) {\n return schema.type as string;\n }\n\n return 'unknown';\n }\n\n return run(value, flags);\n}\n"],"mappings":";AAGA,IAAY,cAAL,yBAAA,aAAA;AACL,aAAA,YAAA,UAAA,KAAA;AACA,aAAA,YAAA,cAAA,KAAA;;KACD;AAOD,SAAgB,eACd,OACA,WACA,QAAqB,YAAY,MACzB;CACR,MAAM,WACJ,OAAO,cAAc,aACjB,aACC,WAAW;EACV,MAAM,MACJ,aAAa,OAAO,WAAW,WAAW,UAAU,UAAU,OAAO,GAAG,KAAA;AAE1E,SAAO;GACL,cAAc;GACd,KAAK,MAAM,EAAE,MAAM,KAAK,GAAG,KAAA;GAC5B;;CAET,SAAS,MAAM,OAAkC,KAAa,OAAoB;EAChF,MAAM,0BAAU,IAAI,KAAK;EACzB,IAAI,WAAW;AAEf,OAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,SAAS,IAAI,MAAM,QAAQ,YAAY,SAAS;AAEtD,OAAI,WAAW,OACb,YAAW;YACF,WAAW,UACpB,SAAQ,IAAI,OAAO;;EAIvB,MAAM,SAAS,MAAM,KAAK,QAAQ,CAAC,KAAK,IAAI;AAC5C,SAAO,WAAW,GAAG,OAAO,WAAW;;CAGzC,SAAS,IAAI,QAAwB,OAA4B;EAC/D,MAAM,WAAW,SAAS,OAAO;AACjC,WAAS,SAAS;AAElB,MAAI,WAAW,KAAM,QAAO;WACnB,WAAW,MAAO,QAAO;AAElC,OAAK,QAAQ,YAAY,cAAc,YAAY,UAAU;AAC3D,OAAI,OAAO,MAAO,QAAO,OAAO;AAEhC,OAAI,OAAO,SAAS,QAAQ,YAAY,SAAS,IAAI,MAAM;IACzD,MAAM,MAAM,SAAS,IAAI,KAAK,MAAM,IAAI;AACxC,QAAI,IAAI,SAAS,EAAG,QAAO,IAAI,IAAI,SAAS;;;AAIhD,MAAI,MAAM,QAAQ,OAAO,KAAK,CAC5B,QAAO,MACL,OAAO,KAAK,KAAK,UAAU;GACzB,GAAG;GACH;GACD,EAAE,EACH,OACA,MACD;AAGH,MAAI,OAAO,SAAS,QAClB,QAAO,SAAS,OAAO,QAAQ,IAAI,OAAO,OAAO,QAAQ,YAAY,SAAS,GAAG,UAAU;EAE7F,MAAM,KAAK,OAAO,SAAS,OAAO;AAClC,MAAI,OAAO,SAAS,OAAO,MACzB,QAAO,IAAI,MAAM,OAAO,OAAO,OAAO,MAAM,CAAC,OAAO,MAAM,OAAO,OAAO,OAAO,MAAM,CAAC;WAC7E,GACT,QAAO,MAAM,IAAI,OAAO,MAAM;AAGhC,MAAI,OAAO,MACT,QAAO,MAAM,OAAO,OAAO,OAAO,MAAM;AAG1C,MAAI,OAAO,IAAK,QAAO,OAAO,IAAI,OAAO,KAAK,MAAM;AACpD,MAAI,OAAO,SAAS,YAAY,OAAO,WAAW,SAAU,QAAO;AAEnE,MAAI,OAAO,QAAQ,MAAM,QAAQ,OAAO,KAAK,CAC3C,QAAO,OAAO,KAAK,QAAQ,MAAM,MAAM,OAAO,CAAC,KAAK,MAAM;AAG5D,MAAI,OAAO,KACT,QAAO,OAAO;AAGhB,SAAO;;AAGT,QAAO,IAAI,OAAO,MAAM"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-openapi",
|
|
3
|
-
"version": "10.6.
|
|
3
|
+
"version": "10.6.4",
|
|
4
4
|
"description": "Generate MDX docs for your OpenAPI spec",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Docs",
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
"exports": {
|
|
22
22
|
".": "./dist/index.js",
|
|
23
23
|
"./i18n": "./dist/i18n.js",
|
|
24
|
-
"./playground": "./dist/playground/index.js",
|
|
25
24
|
"./playground/client": "./dist/playground/client.js",
|
|
26
25
|
"./requests/generators": "./dist/requests/generators/index.js",
|
|
27
26
|
"./requests/generators/all": "./dist/requests/generators/all.js",
|
|
@@ -79,8 +78,8 @@
|
|
|
79
78
|
"tailwindcss": "^4.2.2",
|
|
80
79
|
"tsdown": "0.21.6",
|
|
81
80
|
"@fumadocs/tailwind": "0.0.3",
|
|
82
|
-
"fumadocs-core": "16.7.
|
|
83
|
-
"fumadocs-ui": "16.7.
|
|
81
|
+
"fumadocs-core": "16.7.10",
|
|
82
|
+
"fumadocs-ui": "16.7.10",
|
|
84
83
|
"tsconfig": "0.0.0"
|
|
85
84
|
},
|
|
86
85
|
"peerDependencies": {
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { MethodInformation, RenderContext, SecuritySchemeObject } from "../types.js";
|
|
2
|
-
import * as _$react from "react";
|
|
3
|
-
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
|
-
|
|
5
|
-
//#region src/playground/index.d.ts
|
|
6
|
-
interface APIPlaygroundProps {
|
|
7
|
-
path: string;
|
|
8
|
-
method: MethodInformation;
|
|
9
|
-
ctx: RenderContext;
|
|
10
|
-
}
|
|
11
|
-
type SecurityEntry = SecuritySchemeObject & {
|
|
12
|
-
scopes: string[];
|
|
13
|
-
id: string;
|
|
14
|
-
};
|
|
15
|
-
declare function APIPlayground({
|
|
16
|
-
path,
|
|
17
|
-
method,
|
|
18
|
-
ctx
|
|
19
|
-
}: APIPlaygroundProps): string | number | bigint | boolean | Iterable<_$react.ReactNode> | Promise<_$react.ReactNode> | _$react_jsx_runtime0.JSX.Element | null | undefined;
|
|
20
|
-
//#endregion
|
|
21
|
-
export { APIPlayground, APIPlaygroundProps, SecurityEntry };
|
|
22
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/playground/index.tsx"],"mappings":";;;;;UAgBiB,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,QAAA,CAAA,OAAA,CAAA,SAAA,IAAA,OAAA,CAAA,OAAA,CAAA,SAAA,IAAA,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
package/dist/playground/index.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { getPreferredType } from "../utils/schema/index.js";
|
|
2
|
-
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
//#region src/playground/index.tsx
|
|
4
|
-
function APIPlayground({ path, method, ctx }) {
|
|
5
|
-
if (ctx.playground?.render) return ctx.playground.render({
|
|
6
|
-
path,
|
|
7
|
-
method,
|
|
8
|
-
ctx
|
|
9
|
-
});
|
|
10
|
-
const bodyContent = method.requestBody?.content;
|
|
11
|
-
const mediaType = bodyContent ? getPreferredType(bodyContent) : void 0;
|
|
12
|
-
const takenIds = /* @__PURE__ */ new Map();
|
|
13
|
-
const context = {
|
|
14
|
-
references: {},
|
|
15
|
-
id(schema) {
|
|
16
|
-
let name = "r";
|
|
17
|
-
if (schema) {
|
|
18
|
-
const ref = ctx.schema.getRawRef(schema)?.split("/");
|
|
19
|
-
if (ref && ref.length > 0) name = ref[ref.length - 1];
|
|
20
|
-
}
|
|
21
|
-
const count = takenIds.get(name) ?? 0;
|
|
22
|
-
takenIds.set(name, count + 1);
|
|
23
|
-
return count === 0 ? name : `${name}${count}`;
|
|
24
|
-
},
|
|
25
|
-
registered: /* @__PURE__ */ new WeakMap()
|
|
26
|
-
};
|
|
27
|
-
const props = {
|
|
28
|
-
securities: parseSecurities(method, ctx),
|
|
29
|
-
method: method.method,
|
|
30
|
-
route: path,
|
|
31
|
-
parameters: method.parameters?.map((param) => {
|
|
32
|
-
if (param.schema !== void 0) return {
|
|
33
|
-
...param,
|
|
34
|
-
schema: writeReferences(param.schema, context)
|
|
35
|
-
};
|
|
36
|
-
if (param.content !== void 0) {
|
|
37
|
-
const content = {};
|
|
38
|
-
for (const k in param.content) {
|
|
39
|
-
const original = param.content[k];
|
|
40
|
-
if (!original || original.schema === void 0) continue;
|
|
41
|
-
content[k] = {
|
|
42
|
-
...original,
|
|
43
|
-
schema: writeReferences(original.schema, context)
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
return {
|
|
47
|
-
...param,
|
|
48
|
-
content
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
return param;
|
|
52
|
-
}),
|
|
53
|
-
body: bodyContent && mediaType ? {
|
|
54
|
-
schema: writeReferences(bodyContent[mediaType].schema, context),
|
|
55
|
-
mediaType
|
|
56
|
-
} : void 0,
|
|
57
|
-
references: context.references,
|
|
58
|
-
proxyUrl: ctx.proxyUrl,
|
|
59
|
-
writeOnly: true,
|
|
60
|
-
readOnly: false
|
|
61
|
-
};
|
|
62
|
-
return /* @__PURE__ */ jsx(ctx.clientBoundary.PlaygroundClient, { ...props });
|
|
63
|
-
}
|
|
64
|
-
function writeReferences(schema, ctx, stack = /* @__PURE__ */ new WeakMap()) {
|
|
65
|
-
if (typeof schema !== "object" || !schema) return schema;
|
|
66
|
-
if (stack.has(schema)) {
|
|
67
|
-
const out = stack.get(schema);
|
|
68
|
-
const id = ctx.id(schema);
|
|
69
|
-
ctx.references[id] = out;
|
|
70
|
-
return { $ref: `#/${id}` };
|
|
71
|
-
}
|
|
72
|
-
const output = { ...schema };
|
|
73
|
-
stack.set(schema, output);
|
|
74
|
-
for (const _n in output) {
|
|
75
|
-
const name = _n;
|
|
76
|
-
if (!output[name]) continue;
|
|
77
|
-
switch (name) {
|
|
78
|
-
case "oneOf":
|
|
79
|
-
case "allOf":
|
|
80
|
-
case "anyOf":
|
|
81
|
-
output[name] = output[name].map((item) => writeReferences(item, ctx, stack));
|
|
82
|
-
continue;
|
|
83
|
-
case "items":
|
|
84
|
-
case "additionalProperties":
|
|
85
|
-
case "not":
|
|
86
|
-
output[name] = writeReferences(output[name], ctx, stack);
|
|
87
|
-
continue;
|
|
88
|
-
case "properties":
|
|
89
|
-
case "patternProperties":
|
|
90
|
-
output[name] = { ...output[name] };
|
|
91
|
-
for (const key in output[name]) output[name][key] = writeReferences(output[name][key], ctx, stack);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return output;
|
|
95
|
-
}
|
|
96
|
-
function parseSecurities(method, { schema: { dereferenced } }) {
|
|
97
|
-
const result = [];
|
|
98
|
-
const security = method.security ?? dereferenced.security ?? [];
|
|
99
|
-
if (security.length === 0) return result;
|
|
100
|
-
for (const map of security) {
|
|
101
|
-
const list = [];
|
|
102
|
-
for (const [key, scopes] of Object.entries(map)) {
|
|
103
|
-
const scheme = dereferenced.components?.securitySchemes?.[key];
|
|
104
|
-
if (!scheme) continue;
|
|
105
|
-
list.push({
|
|
106
|
-
...scheme,
|
|
107
|
-
scopes,
|
|
108
|
-
id: key
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
if (list.length > 0) result.push(list);
|
|
112
|
-
}
|
|
113
|
-
return result;
|
|
114
|
-
}
|
|
115
|
-
//#endregion
|
|
116
|
-
export { APIPlayground };
|
|
117
|
-
|
|
118
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
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';\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 <ctx.clientBoundary.PlaygroundClient {...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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server-tab.js","names":[],"sources":["../../../src/ui/components/server-tab.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@/utils/cn';\nimport { SelectTrigger, Select, SelectValue, SelectContent, SelectItem } from './select';\nimport { type ReactNode, useState, useMemo, type ComponentProps, createContext, use } from 'react';\n\nconst Context = createContext<{\n type: string | null;\n setType: (type: string) => void;\n} | null>(null);\n\nexport function SelectTabs({\n defaultValue,\n children,\n}: {\n defaultValue?: string;\n children: ReactNode;\n}) {\n const [type, setType] = useState<string | null>(defaultValue ?? null);\n\n return <Context value={useMemo(() => ({ type, setType }), [type])}>{children}</Context>;\n}\n\nexport function SelectTab({\n value,\n ...props\n}: ComponentProps<'div'> & {\n value: string;\n}) {\n const ctx = use(Context);\n if (value !== ctx?.type) return;\n\n return <div {...props}>{props.children}</div>;\n}\n\nexport function SelectTabTrigger({\n items,\n className,\n ...props\n}: ComponentProps<typeof SelectTrigger> & {\n items: {\n label: ReactNode;\n value: string;\n }[];\n}) {\n const { type, setType } = use(Context)!;\n\n return (\n <Select value={type ?? ''} onValueChange={setType}>\n <SelectTrigger className={cn('not-prose w-fit min-w-0 *:min-w-0', className)} {...props}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {items.map(({ label, value }) => (\n <SelectItem key={value} value={value}>\n {label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n"],"mappings":";;;;;;AAMA,MAAM,UAAU,cAGN,KAAK;AAEf,SAAgB,WAAW,EACzB,cACA,YAIC;CACD,MAAM,CAAC,MAAM,WAAW,SAAwB,gBAAgB,KAAK;AAErE,QAAO,oBAAC,SAAD;EAAS,OAAO,eAAe;GAAE;GAAM;GAAS,GAAG,CAAC,KAAK,CAAC;EAAG;EAAmB,CAAA;;AAGzF,SAAgB,UAAU,EACxB,OACA,GAAG,SAGF;AAED,KAAI,UADQ,IAAI,QAAQ,EACL,KAAM;AAEzB,QAAO,oBAAC,OAAD;EAAK,GAAI;YAAQ,MAAM;EAAe,CAAA;;AAG/C,SAAgB,iBAAiB,EAC/B,OACA,WACA,GAAG,SAMF;CACD,MAAM,EAAE,MAAM,YAAY,IAAI,QAAQ;AAEtC,QACE,qBAAC,QAAD;EAAQ,OAAO,QAAQ;EAAI,eAAe;YAA1C,CACE,oBAAC,eAAD;GAAe,WAAW,GAAG,qCAAqC,UAAU;GAAE,GAAI;aAChF,oBAAC,aAAD,EAAe,CAAA;GACD,CAAA,EAChB,oBAAC,eAAD,EAAA,UACG,MAAM,KAAK,EAAE,OAAO,YACnB,oBAAC,YAAD;GAA+B;aAC5B;GACU,EAFI,MAEJ,CACb,EACY,CAAA,CACT"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { NoReference } from "./schema/index.js";
|
|
2
|
-
import { Document } from "../types.js";
|
|
3
|
-
|
|
4
|
-
//#region src/utils/process-document.d.ts
|
|
5
|
-
interface ProcessedDocument {
|
|
6
|
-
/**
|
|
7
|
-
* dereferenced document
|
|
8
|
-
*/
|
|
9
|
-
dereferenced: NoReference<Document>;
|
|
10
|
-
/**
|
|
11
|
-
* Get raw $ref from dereferenced object
|
|
12
|
-
*/
|
|
13
|
-
getRawRef: (obj: object) => string | undefined;
|
|
14
|
-
bundled: Document;
|
|
15
|
-
}
|
|
16
|
-
//#endregion
|
|
17
|
-
export { ProcessedDocument };
|
|
18
|
-
//# sourceMappingURL=process-document.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"process-document.d.ts","names":[],"sources":["../../src/utils/process-document.ts"],"mappings":";;;;UAQiB,iBAAA;;AAAjB;;EAIE,YAAA,EAAc,WAAA,CAAY,QAAA;EAAA;;;EAK1B,SAAA,GAAY,GAAA;EAEZ,OAAA,EAAS,QAAA;AAAA"}
|