mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-21 01:53:26 +00:00
Handle non-array required field in OpenAPI schema (#4030)
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@gitbook/react-openapi": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Handle non-array required field in OpenAPI schema to fix TypeError with specs using boolean required values
|
||||||
@@ -185,6 +185,60 @@ describe('getSchemaAlternatives', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle non-standard boolean required values without throwing', () => {
|
||||||
|
// Some specs (e.g. Trustly) use `"required": true` on properties
|
||||||
|
// instead of the standard `string[]` format. This should not throw.
|
||||||
|
const schema = {
|
||||||
|
allOf: [
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
name: { type: 'string' },
|
||||||
|
},
|
||||||
|
required: true as any,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
email: { type: 'string' },
|
||||||
|
},
|
||||||
|
required: ['email'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
const result = getSchemaAlternatives(schema);
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
// The boolean `required: true` should be ignored, only the valid array is kept
|
||||||
|
expect(result?.schemas[0]?.required).toEqual(['email']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle boolean required on both schemas without throwing', () => {
|
||||||
|
const schema = {
|
||||||
|
allOf: [
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
name: { type: 'string' },
|
||||||
|
},
|
||||||
|
required: true as any,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
email: { type: 'string' },
|
||||||
|
},
|
||||||
|
required: false as any,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
const result = getSchemaAlternatives(schema);
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
// Boolean required values should not cause a crash, result is an empty array
|
||||||
|
expect(result?.schemas[0]?.required).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
describe('safe merging with allOf', () => {
|
describe('safe merging with allOf', () => {
|
||||||
it('should merge objects with safe extensions', () => {
|
it('should merge objects with safe extensions', () => {
|
||||||
expect(
|
expect(
|
||||||
|
|||||||
@@ -1105,15 +1105,19 @@ function mergeRequiredFields(
|
|||||||
schemaOrRef: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject,
|
schemaOrRef: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject,
|
||||||
latestAncestor: OpenAPIV3.SchemaObject | undefined
|
latestAncestor: OpenAPIV3.SchemaObject | undefined
|
||||||
) {
|
) {
|
||||||
if (!schemaOrRef.required && !latestAncestor?.required) {
|
const ancestorRequired = Array.isArray(latestAncestor?.required)
|
||||||
|
? latestAncestor.required
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
if (checkIsReference(schemaOrRef)) {
|
||||||
|
return ancestorRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
const schemaRequired = Array.isArray(schemaOrRef.required) ? schemaOrRef.required : undefined;
|
||||||
|
|
||||||
|
if (!ancestorRequired && !schemaRequired) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkIsReference(schemaOrRef)) {
|
return Array.from(new Set([...(ancestorRequired || []), ...(schemaRequired || [])]));
|
||||||
return latestAncestor?.required;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Array.from(
|
|
||||||
new Set([...(latestAncestor?.required || []), ...(schemaOrRef.required || [])])
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user