UNPKG

@alauda/doom

Version:

Doctor Doom making docs.

122 lines (121 loc) 5.4 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { usePage } from '@rspress/core/runtime'; import openapisMap from 'doom-@api-openapisMap'; import { useMemo } from 'react'; import { modelName, omitRoutePathRefs, resolveRef } from '../utils.js'; import { Markdown } from './Markdown.js'; import { HeadingTitle } from './_HeadingTitle.js'; import { RefLink } from './_RefLink.js'; import { X } from './_X.js'; export const get$Ref = (obj) => { if ('$ref' in obj && obj.$ref) { return obj.$ref; } if ('allOf' in obj && Array.isArray(obj.allOf)) { for (const item of obj.allOf) { if ('$ref' in item && item.$ref) { return item.$ref; } } } }; export const OpenAPIProperty = ({ name, property, openapi, }) => { const prop$Ref = get$Ref(property); const propObj = prop$Ref ? resolveRef(openapi, prop$Ref) : property; const type = propObj.type; let typeNode; let extraNode; if (type === 'array') { const { items } = propObj; const items$Ref = get$Ref(items); const itemsObj = items$Ref ? resolveRef(openapi, items$Ref) : items; const itemsType = itemsObj.type; typeNode = (_jsxs("code", { children: ["[]", items$Ref ? _jsx(RefLink, { "$ref": items$Ref }) : itemsType] })); } else if (type === 'object') { if (prop$Ref) { typeNode = _jsx(RefLink, { "$ref": prop$Ref }); } if (typeof propObj.additionalProperties === 'object') { const props = propObj.additionalProperties; const props$Ref = get$Ref(props); const propsObj = props$Ref ? resolveRef(openapi, props$Ref) : props; const propsType = propsObj.type; typeNode = (_jsxs(_Fragment, { children: [typeNode, _jsxs("code", { children: ["map[string]", typeof propsType === 'string' ? propsType : props$Ref && _jsx(RefLink, { "$ref": props$Ref })] })] })); if ('properties' in property && property.properties) { extraNode = (_jsxs("div", { className: "my-4", children: [_jsx("em", { children: "Properties:" }), _jsx(OpenAPIProperties, { properties: property.properties, openapi: openapi })] })); } } else if (!prop$Ref) { typeNode = _jsx("code", { children: type }); } } else if (typeof type === 'string') { typeNode = _jsx("code", { children: type }); } else if (prop$Ref) { typeNode = _jsx(RefLink, { "$ref": prop$Ref }); } return (_jsxs(_Fragment, { children: [name && (_jsxs(_Fragment, { children: [_jsx("code", { children: name }), ":", ' '] })), typeNode, _jsx(Markdown, { children: propObj.description }), extraNode] })); }; export const OpenAPIProperties = ({ properties, openapi, }) => { return (_jsx(X.ul, { children: Object.entries(properties).map(([name, property]) => (_jsx(X.li, { children: _jsx(OpenAPIProperty, { name: name, property: property, openapi: openapi }) }, name))) })); }; const getRefsForSchema = (openapi, schema, knownRefs) => { const refSchema = openapi.components?.schemas[schema]; if (!refSchema) { return []; } const refs = new Set(); const collectRefs = (schema) => { if ('$ref' in schema && typeof schema.$ref === 'string') { const ref = schema.$ref.replace(/^#\/components\/[^/]+\//, ''); if (!knownRefs[ref]) { refs.add(ref); schema = resolveRef(openapi, schema.$ref); } } for (const value of Object.values(schema)) { if (value && typeof value === 'object') { collectRefs(value); } } }; collectRefs(refSchema); return Array.from(refs); }; export const OpenAPIRef = ({ schema, openapiPath: openapiPath_, collectRefs = true, }) => { const { page } = usePage(); // eslint-disable-next-line react-hooks/preserve-manual-memoization const [schemaItem, openapi, openapiPath] = useMemo(() => { for (const [pathname, openapi] of Object.entries(openapisMap)) { if (openapiPath_ && pathname !== openapiPath_) { continue; } const schemaItem = resolveRef(openapi, schema); if (schemaItem) { return [schemaItem, openapi, pathname]; } } return []; }, [openapiPath_, schema]); const refs = useMemo(() => { if (collectRefs && openapi) { return getRefsForSchema(openapi, schema, omitRoutePathRefs(page.routePath)); } }, [collectRefs, openapi, page.routePath, schema]); if (!schemaItem || !openapi) { console.error(`No OpenAPI schema definition found for ${schema}\n`); return null; } return (_jsxs(_Fragment, { children: [_jsx(HeadingTitle, { slug: schema, level: 2, children: modelName(schema) }), _jsx(Markdown, { children: schemaItem.description }), schemaItem.properties && (_jsx(OpenAPIProperties, { properties: schemaItem.properties, openapi: openapi })), refs?.map((schema) => (_jsx(OpenAPIRef, { schema: schema, openapiPath: openapiPath, collectRefs: false }, schema)))] })); }; export default OpenAPIRef;