UNPKG

@alauda/doom

Version:

Doctor Doom making docs.

106 lines (105 loc) 5.02 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 { useId, 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'; import { UidProvider, useUid } from './_context.js'; export const OpenAPIProperty = ({ name, property, openapi, }) => { const propObj = '$ref' in property ? resolveRef(openapi, property.$ref) : property; const type = propObj.type; let typeNode; let extraNode; if (type === 'array') { const { items } = propObj; const itemsObj = '$ref' in items ? resolveRef(openapi, items.$ref) : items; const itemsType = itemsObj.type; typeNode = (_jsxs("code", { children: ["[]", '$ref' in items ? _jsx(RefLink, { "$ref": items.$ref }) : itemsType] })); } else if (type === 'object') { if ('properties' in property && property.properties) { extraNode = (_jsxs("div", { className: "my-4", children: [_jsx("em", { children: "Properties:" }), _jsx(OpenAPIProperties, { properties: property.properties, openapi: openapi })] })); } if (typeof propObj.additionalProperties === 'object') { const props = propObj.additionalProperties; const propsObj = '$ref' in props ? resolveRef(openapi, props.$ref) : props; const propsType = propsObj.type; typeNode = (_jsxs("code", { children: ["map[string]", typeof propsType === 'string' ? propsType : '$ref' in props && _jsx(RefLink, { "$ref": props.$ref })] })); } else { typeNode = _jsx("code", { children: type }); } } else if (typeof type === 'string') { typeNode = _jsx("code", { children: type }); } else if ('$ref' in property) { typeNode = _jsx(RefLink, { "$ref": property.$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/schemas/', ''); 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_, isCommonRef = true, collectRefs = true, }) => { const { page } = usePage(); let uid = useUid(); const innerUid = useId(); if (isCommonRef) { uid = ''; // common references do not need a unique ID } else if (!uid) { uid = innerUid; } const [schemaItem, openapi, openapiPath] = useMemo(() => { for (const [pathname, openapi] of Object.entries(openapisMap)) { if (openapiPath_ && pathname !== openapiPath_) { continue; } const schemaItem = openapi.components?.schemas?.[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(UidProvider, { value: uid, 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, isCommonRef: isCommonRef, collectRefs: false }, schema)))] })); }; export default OpenAPIRef;