Files
gitbook/packages/react-openapi/src/generateSchemaExample.ts
T
Samy Pessé 85ec1884e6 OpenAPI blocks (#74)
* Start methods to resolve refs

* bun

* Start package

* Add code to resolve ref

* Continue

* Deref

* Start monorepo

* Continue

* Fix ref resolver

* Style a bit more

* Start toggling section

* Continue

* Start displaying query/path/headers params

* Hide respo se if empty

* Fix recursive refs

* Simplify interactive and styling

* Display enums

* Format

* Improve type name being displayed

* Improve naming

* Render oneOf/anyOf/allOf

* Handle circular references

* Start variable in server url

* Use client component for the spec part

* Improve CSS sizing

* Display open api blocks in aside

* Make aside an overlay

* Improve stickiness of openapi

* Align document on the left when api page

* Improve general layout

* Better align

* Fix padding in aside

* Use syntax highlighting

* Show sample of response

* Improve code generation

* Improve code generated

* Format

* Format

* Rename to OpenAPI

* Skip deprecated properties and handle additionalProperties

* Use discriminator for naming

* Better name enum

* Make entire header toggeable

* Format and lint

* Add curl example

* Improve curl

* style pass

* Start securities

* Bun

* Fix TS

* Improve label

* Start markdown

* Improve code samples

* Test

* Use custom skeleton for api block

* Format

* Add support for redocly code samples

* Fix api blocks in aside

* Use typography for markdown

* Format

* Fix spacing in markdown

* Render headers

* Format

* Format

---------

Co-authored-by: Sebastian Graz <graz@live.se>
2024-01-30 10:15:58 +01:00

190 lines
4.7 KiB
TypeScript

import { OpenAPIV3 } from 'openapi-types';
import { noReference } from './utils';
type JSONValue = string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue };
/**
* Generate a JSON example from a schema
*/
export function generateSchemaExample(
schema: OpenAPIV3.SchemaObject,
options: {
onlyRequired?: boolean;
} = {},
ancestors: Set<OpenAPIV3.SchemaObject> = new Set(),
): JSONValue | undefined {
const { onlyRequired = false } = options;
if (ancestors.has(schema)) {
return undefined;
}
if (schema.example) {
return schema.example;
}
if (schema.enum && schema.enum.length > 0) {
return schema.enum[0];
}
if (schema.type === 'string') {
if (schema.default) {
return schema.default;
}
if (schema.format === 'date-time') {
return new Date().toISOString();
}
if (schema.format === 'date') {
return new Date().toISOString().split('T')[0];
}
if (schema.format === 'email') {
return 'name@gmail.com';
}
if (schema.format === 'hostname') {
return 'example.com';
}
if (schema.format === 'ipv4') {
return '0.0.0.0';
}
if (schema.format === 'ipv6') {
return '2001:0db8:85a3:0000:0000:8a2e:0370:7334';
}
if (schema.format === 'uri') {
return 'https://example.com';
}
if (schema.format === 'uuid') {
return '123e4567-e89b-12d3-a456-426614174000';
}
if (schema.format === 'binary') {
return 'binary';
}
if (schema.format === 'byte') {
return 'Ynl0ZXM=';
}
if (schema.format === 'password') {
return 'password';
}
return 'text';
}
if (schema.type === 'number') {
return schema.default || 0;
}
if (schema.type === 'boolean') {
return schema.default || false;
}
if (schema.type === 'array') {
if (schema.items) {
const exampleValue = generateSchemaExample(
noReference(schema.items),
options,
new Set(ancestors).add(schema),
);
if (exampleValue !== undefined) {
return [exampleValue];
}
return [];
}
return [];
}
if (schema.properties) {
const example: { [key: string]: JSONValue } = {};
const props = onlyRequired ? schema.required ?? [] : Object.keys(schema.properties);
for (const key of props) {
const property = noReference(schema.properties[key]);
if (property && (onlyRequired || !property.deprecated)) {
const exampleValue = generateSchemaExample(
noReference(property),
options,
new Set(ancestors).add(schema),
);
if (exampleValue !== undefined) {
example[key] = exampleValue;
}
}
}
return example;
}
if (schema.oneOf && schema.oneOf.length > 0) {
return generateSchemaExample(
noReference(schema.oneOf[0]),
options,
new Set(ancestors).add(schema),
);
}
if (schema.anyOf && schema.anyOf.length > 0) {
return generateSchemaExample(
noReference(schema.anyOf[0]),
options,
new Set(ancestors).add(schema),
);
}
if (schema.allOf && schema.allOf.length > 0) {
return schema.allOf.reduce(
(acc, curr) => {
const example = generateSchemaExample(
noReference(curr),
options,
new Set(ancestors).add(schema),
);
if (typeof example === 'object' && !Array.isArray(example) && example !== null) {
return { ...acc, ...example };
}
return acc;
},
{} as { [key: string]: JSONValue },
);
}
return undefined;
}
/**
* Generate an example for a media type.
*/
export function generateMediaTypeExample(
mediaType: OpenAPIV3.MediaTypeObject,
options: {
onlyRequired?: boolean;
} = {},
): JSONValue | undefined {
if (mediaType.example) {
return mediaType.example;
}
if (mediaType.examples) {
const example = mediaType.examples[Object.keys(mediaType.examples)[0]];
if (example) {
return noReference(example).value;
}
}
if (mediaType.schema) {
return generateSchemaExample(noReference(mediaType.schema), options);
}
return undefined;
}