@alauda/doom
Version:
Doctor Doom making docs.
106 lines (105 loc) • 5.02 kB
JavaScript
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;