mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-16 15:45:13 +00:00
Fix read-only in generateSchemaExample (#3069)
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'@gitbook/react-openapi': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix read-only in generateSchemaExample
|
||||||
@@ -268,6 +268,7 @@ function getExamplesFromMediaTypeObject(args: {
|
|||||||
value: {
|
value: {
|
||||||
[root]: generateSchemaExample(mediaTypeObject.schema, {
|
[root]: generateSchemaExample(mediaTypeObject.schema, {
|
||||||
xml: mediaType === 'application/xml',
|
xml: mediaType === 'application/xml',
|
||||||
|
mode: 'read',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -277,7 +278,11 @@ function getExamplesFromMediaTypeObject(args: {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
key: 'default',
|
key: 'default',
|
||||||
example: { value: generateSchemaExample(mediaTypeObject.schema) },
|
example: {
|
||||||
|
value: generateSchemaExample(mediaTypeObject.schema, {
|
||||||
|
mode: 'read',
|
||||||
|
}),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,14 +16,10 @@ export function generateSchemaExample(
|
|||||||
schema: OpenAPIV3.SchemaObject,
|
schema: OpenAPIV3.SchemaObject,
|
||||||
options?: GenerateSchemaExampleOptions
|
options?: GenerateSchemaExampleOptions
|
||||||
): JSONValue | undefined {
|
): JSONValue | undefined {
|
||||||
return getExampleFromSchema(
|
return getExampleFromSchema(schema, {
|
||||||
schema,
|
emptyString: 'text',
|
||||||
{
|
...options,
|
||||||
emptyString: 'text',
|
});
|
||||||
...options,
|
|
||||||
},
|
|
||||||
3 // Max depth for circular references
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,21 +99,6 @@ function guessFromFormat(schema: Record<string, any>, fallback = '') {
|
|||||||
return genericExampleValues[schema.format] ?? fallback;
|
return genericExampleValues[schema.format] ?? fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Map of all the results */
|
|
||||||
const resultCache = new WeakMap<Record<string, any>, any>();
|
|
||||||
|
|
||||||
/** Store result in the cache, and return the result */
|
|
||||||
function cache(schema: Record<string, any>, result: unknown) {
|
|
||||||
// Avoid unnecessary WeakMap operations for primitive values
|
|
||||||
if (typeof result !== 'object' || result === null) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
resultCache.set(schema, result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function takes an OpenAPI schema and generates an example from it
|
* This function takes an OpenAPI schema and generates an example from it
|
||||||
* Forked from : https://github.com/scalar/scalar/blob/main/packages/oas-utils/src/spec-getters/getExampleFromSchema.ts
|
* Forked from : https://github.com/scalar/scalar/blob/main/packages/oas-utils/src/spec-getters/getExampleFromSchema.ts
|
||||||
@@ -152,8 +133,20 @@ const getExampleFromSchema = (
|
|||||||
},
|
},
|
||||||
level = 0,
|
level = 0,
|
||||||
parentSchema?: Record<string, any>,
|
parentSchema?: Record<string, any>,
|
||||||
name?: string
|
name?: string,
|
||||||
|
resultCache = new WeakMap<Record<string, any>, any>()
|
||||||
): any => {
|
): any => {
|
||||||
|
// Store result in the cache, and return the result
|
||||||
|
function cache(schema: Record<string, any>, result: unknown) {
|
||||||
|
// Avoid unnecessary WeakMap operations for primitive values
|
||||||
|
if (typeof result !== 'object' || result === null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
resultCache.set(schema, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the result is already cached
|
// Check if the result is already cached
|
||||||
if (resultCache.has(schema)) {
|
if (resultCache.has(schema)) {
|
||||||
return resultCache.get(schema);
|
return resultCache.get(schema);
|
||||||
@@ -245,7 +238,8 @@ const getExampleFromSchema = (
|
|||||||
options,
|
options,
|
||||||
level + 1,
|
level + 1,
|
||||||
schema,
|
schema,
|
||||||
propertyName
|
propertyName,
|
||||||
|
resultCache
|
||||||
);
|
);
|
||||||
|
|
||||||
if (typeof response[propertyXmlTagName ?? propertyName] === 'undefined') {
|
if (typeof response[propertyXmlTagName ?? propertyName] === 'undefined') {
|
||||||
@@ -269,7 +263,8 @@ const getExampleFromSchema = (
|
|||||||
options,
|
options,
|
||||||
level + 1,
|
level + 1,
|
||||||
schema,
|
schema,
|
||||||
exampleKey
|
exampleKey,
|
||||||
|
resultCache
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,21 +285,51 @@ const getExampleFromSchema = (
|
|||||||
response.ANY_ADDITIONAL_PROPERTY = getExampleFromSchema(
|
response.ANY_ADDITIONAL_PROPERTY = getExampleFromSchema(
|
||||||
schema.additionalProperties,
|
schema.additionalProperties,
|
||||||
options,
|
options,
|
||||||
level + 1
|
level + 1,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
resultCache
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schema.anyOf !== undefined) {
|
if (schema.anyOf !== undefined) {
|
||||||
Object.assign(response, getExampleFromSchema(schema.anyOf[0], options, level + 1));
|
Object.assign(
|
||||||
|
response,
|
||||||
|
getExampleFromSchema(
|
||||||
|
schema.anyOf[0],
|
||||||
|
options,
|
||||||
|
level + 1,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
resultCache
|
||||||
|
)
|
||||||
|
);
|
||||||
} else if (schema.oneOf !== undefined) {
|
} else if (schema.oneOf !== undefined) {
|
||||||
Object.assign(response, getExampleFromSchema(schema.oneOf[0], options, level + 1));
|
Object.assign(
|
||||||
|
response,
|
||||||
|
getExampleFromSchema(
|
||||||
|
schema.oneOf[0],
|
||||||
|
options,
|
||||||
|
level + 1,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
resultCache
|
||||||
|
)
|
||||||
|
);
|
||||||
} else if (schema.allOf !== undefined) {
|
} else if (schema.allOf !== undefined) {
|
||||||
Object.assign(
|
Object.assign(
|
||||||
response,
|
response,
|
||||||
...schema.allOf
|
...schema.allOf
|
||||||
.map((item: Record<string, any>) =>
|
.map((item: Record<string, any>) =>
|
||||||
getExampleFromSchema(item, options, level + 1, schema)
|
getExampleFromSchema(
|
||||||
|
item,
|
||||||
|
options,
|
||||||
|
level + 1,
|
||||||
|
schema,
|
||||||
|
undefined,
|
||||||
|
resultCache
|
||||||
|
)
|
||||||
)
|
)
|
||||||
.filter((item: any) => item !== undefined)
|
.filter((item: any) => item !== undefined)
|
||||||
);
|
);
|
||||||
@@ -335,7 +360,9 @@ const getExampleFromSchema = (
|
|||||||
{ type: 'object', allOf: schema.items.allOf },
|
{ type: 'object', allOf: schema.items.allOf },
|
||||||
options,
|
options,
|
||||||
level + 1,
|
level + 1,
|
||||||
schema
|
schema,
|
||||||
|
undefined,
|
||||||
|
resultCache
|
||||||
);
|
);
|
||||||
|
|
||||||
return cache(
|
return cache(
|
||||||
@@ -346,7 +373,14 @@ const getExampleFromSchema = (
|
|||||||
// For non-objects (like strings), collect all examples
|
// For non-objects (like strings), collect all examples
|
||||||
const examples = schema.items.allOf
|
const examples = schema.items.allOf
|
||||||
.map((item: Record<string, any>) =>
|
.map((item: Record<string, any>) =>
|
||||||
getExampleFromSchema(item, options, level + 1, schema)
|
getExampleFromSchema(
|
||||||
|
item,
|
||||||
|
options,
|
||||||
|
level + 1,
|
||||||
|
schema,
|
||||||
|
undefined,
|
||||||
|
resultCache
|
||||||
|
)
|
||||||
)
|
)
|
||||||
.filter((item: any) => item !== undefined);
|
.filter((item: any) => item !== undefined);
|
||||||
|
|
||||||
@@ -368,7 +402,14 @@ const getExampleFromSchema = (
|
|||||||
const schemas = schema.items[rule].slice(0, 1);
|
const schemas = schema.items[rule].slice(0, 1);
|
||||||
const exampleFromRule = schemas
|
const exampleFromRule = schemas
|
||||||
.map((item: Record<string, any>) =>
|
.map((item: Record<string, any>) =>
|
||||||
getExampleFromSchema(item, options, level + 1, schema)
|
getExampleFromSchema(
|
||||||
|
item,
|
||||||
|
options,
|
||||||
|
level + 1,
|
||||||
|
schema,
|
||||||
|
undefined,
|
||||||
|
resultCache
|
||||||
|
)
|
||||||
)
|
)
|
||||||
.filter((item: any) => item !== undefined);
|
.filter((item: any) => item !== undefined);
|
||||||
|
|
||||||
@@ -380,7 +421,14 @@ const getExampleFromSchema = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (schema.items?.type) {
|
if (schema.items?.type) {
|
||||||
const exampleFromSchema = getExampleFromSchema(schema.items, options, level + 1);
|
const exampleFromSchema = getExampleFromSchema(
|
||||||
|
schema.items,
|
||||||
|
options,
|
||||||
|
level + 1,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
resultCache
|
||||||
|
);
|
||||||
|
|
||||||
return wrapItems ? [{ [itemsXmlTagName]: exampleFromSchema }] : [exampleFromSchema];
|
return wrapItems ? [{ [itemsXmlTagName]: exampleFromSchema }] : [exampleFromSchema];
|
||||||
}
|
}
|
||||||
@@ -407,7 +455,14 @@ const getExampleFromSchema = (
|
|||||||
const firstOneOfItem = discriminateSchema[0];
|
const firstOneOfItem = discriminateSchema[0];
|
||||||
|
|
||||||
// Return an example for the first item
|
// Return an example for the first item
|
||||||
return getExampleFromSchema(firstOneOfItem, options, level + 1);
|
return getExampleFromSchema(
|
||||||
|
firstOneOfItem,
|
||||||
|
options,
|
||||||
|
level + 1,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
resultCache
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if schema has the `allOf` key
|
// Check if schema has the `allOf` key
|
||||||
@@ -417,7 +472,14 @@ const getExampleFromSchema = (
|
|||||||
// Loop through all `allOf` schemas
|
// Loop through all `allOf` schemas
|
||||||
schema.allOf.forEach((allOfItem: Record<string, any>) => {
|
schema.allOf.forEach((allOfItem: Record<string, any>) => {
|
||||||
// Return an example from the schema
|
// Return an example from the schema
|
||||||
const newExample = getExampleFromSchema(allOfItem, options, level + 1);
|
const newExample = getExampleFromSchema(
|
||||||
|
allOfItem,
|
||||||
|
options,
|
||||||
|
level + 1,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
resultCache
|
||||||
|
);
|
||||||
|
|
||||||
// Merge or overwrite the example
|
// Merge or overwrite the example
|
||||||
example =
|
example =
|
||||||
|
|||||||
Reference in New Issue
Block a user