Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,27 @@ import { createFullWidthTable } from "./createFullWidthTable";
import { getSchemaName } from "./schema";
import { create, guard } from "./utils";

function resolveAllOf(allOf: SchemaObject[]) {
// TODO: naive implementation (only supports objects, no directly nested allOf)
const properties = allOf.reduce((acc, cur) => {
if (cur.properties !== undefined) {
const next = { ...acc, ...cur.properties };
return next;
}
return acc;
}, {});

const required = allOf.reduce((acc, cur) => {
if (Array.isArray(cur.required)) {
const next = [...acc, ...cur.required];
return next;
}
return acc;
}, [] as string[]);

return { properties, required };
}

interface RowProps {
name: string;
schema: SchemaObject;
Expand Down Expand Up @@ -85,6 +106,26 @@ function createRows({ schema }: RowsProps): string | undefined {
});
}

// TODO: This can be a bit complicated types can be missmatched and there can be nested allOfs which need to be resolved before merging properties
if (schema.allOf !== undefined) {
const { properties, required } = resolveAllOf(schema.allOf);
return createFullWidthTable({
style: {
marginTop: "var(--ifm-table-cell-padding)",
marginBottom: "0px",
},
children: create("tbody", {
children: Object.entries(properties).map(([key, val]) =>
createRow({
name: key,
schema: val,
required: Array.isArray(required) ? required.includes(key) : false,
})
),
}),
});
}

// array
if (schema.items !== undefined) {
return createRows({ schema: schema.items });
Expand Down Expand Up @@ -112,9 +153,31 @@ function createRowsRoot({ schema }: RowsRootProps) {
);
}

// TODO: This can be a bit complicated types can be missmatched and there can be nested allOfs which need to be resolved before merging properties
if (schema.allOf !== undefined) {
const { properties, required } = resolveAllOf(schema.allOf);
return Object.entries(properties).map(([key, val]) =>
createRow({
name: key,
schema: val,
required: Array.isArray(required) ? required.includes(key) : false,
})
);
}

// array
if (schema.items !== undefined) {
return createRows({ schema: schema.items });
return create("tr", {
children: create("td", {
children: [
create("span", {
style: { opacity: "0.6" },
children: ` ${getSchemaName(schema, true)}`,
}),
createRows({ schema: schema.items }),
],
}),
});
}

// primitive
Expand Down Expand Up @@ -148,7 +211,7 @@ interface Props {
style?: any;
title: string;
body: {
content: {
content?: {
[key: string]: MediaTypeObject;
};
description?: string;
Expand All @@ -161,9 +224,9 @@ export function createSchemaTable({ title, body, ...rest }: Props) {
return undefined;
}

// TODO:
// NOTE: We just pick a random content-type.
// How common is it to have multiple?

const randomFirstKey = Object.keys(body.content)[0];

const firstBody = body.content[randomFirstKey].schema;
Expand All @@ -173,8 +236,10 @@ export function createSchemaTable({ title, body, ...rest }: Props) {
}

// we don't show the table if there is no properties to show
if (Object.keys(firstBody.properties ?? {}).length === 0) {
return undefined;
if (firstBody.properties !== undefined) {
if (Object.keys(firstBody.properties).length === 0) {
return undefined;
}
}

return createFullWidthTable({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ export function createStatusCodesTable({ responses }: Props) {
}),
}),
create("div", {
children: createDescription(
(responses[code] as any)?.description
),
children: createDescription(responses[code].description),
}),
],
}),
Expand All @@ -64,9 +62,8 @@ export function createStatusCodesTable({ responses }: Props) {
},
title: "Schema",
body: {
...responses[code],
description: "", // remove description since it acts as a subtitle, but is already rendered above.
} as any,
content: responses[code].content,
},
}),
}),
],
Expand Down
24 changes: 21 additions & 3 deletions packages/docusaurus-plugin-openapi/src/openapi/createExample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,30 @@ const primitives: Primitives = {
};

export const sampleFromSchema = (schema: SchemaObject = {}): any => {
let { type, example, properties, items } = schema;
let { type, example, allOf, properties, items } = schema;

if (example !== undefined) {
return example;
}

if (allOf) {
// TODO: We are just assuming it will always be an object for now
let obj: SchemaObject = {
type: "object",
properties: {},
required: [], // NOTE: We shouldn't need to worry about required
};
for (let item of allOf) {
if (item.properties) {
obj.properties = {
...obj.properties,
...item.properties,
};
}
}
return sampleFromSchema(obj);
}

if (!type) {
if (properties) {
type = "object";
Expand All @@ -66,8 +84,8 @@ export const sampleFromSchema = (schema: SchemaObject = {}): any => {

if (type === "object") {
let obj: any = {};
for (let [name, prop] of Object.entries(properties || {})) {
if (prop && prop.deprecated) {
for (let [name, prop] of Object.entries(properties ?? {})) {
if (prop.deprecated) {
continue;
}
obj[name] = sampleFromSchema(prop);
Expand Down