@alauda/doom
Version:
Doctor Doom making docs.
122 lines (121 loc) • 5.4 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 { 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;