Skip to content

Commit

Permalink
[OAS] Fix handling of schema.nullable to path and query params (#19…
Browse files Browse the repository at this point in the history
…7046)

## Summary

Fixes handling of `schema.nullable(schema.object({..}))` to params and
query inputs. [Example in the
wild](https://github.com/jloleysens/kibana/blob/83e76cb4d854a3c3f9ffdaad8c6ee29d66d56710/x-pack/plugins/reporting/server/routes/common/generate/request_handler.ts#L33).


### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
  • Loading branch information
jloleysens authored Oct 25, 2024
1 parent 6ef0369 commit d3569f6
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,30 @@ describe('convertPathParameters', () => {
convertPathParameters(schema.object({ b: schema.string() }), { a: { optional: false } })
).toThrow(/Unknown parameter: b/);
});

test('converting paths with nullables', () => {
expect(
convertPathParameters(schema.nullable(schema.object({ a: schema.string() })), {
a: { optional: true },
})
).toEqual({
params: [
{
in: 'path',
name: 'a',
required: false,
schema: {
type: 'string',
},
},
],
shared: {},
});
});

test('throws if properties cannot be exracted', () => {
expect(() => convertPathParameters(schema.string(), {})).toThrow(/expected to be an object/);
});
});

describe('convertQuery', () => {
Expand All @@ -166,10 +190,30 @@ describe('convertQuery', () => {
});
});

test('converting queries with nullables', () => {
expect(convertQuery(schema.nullable(schema.object({ a: schema.string() })))).toEqual({
query: [
{
in: 'query',
name: 'a',
required: false,
schema: {
type: 'string',
},
},
],
shared: {},
});
});

test('conversion with refs is disallowed', () => {
const sharedSchema = schema.object({ a: schema.string() }, { meta: { id: 'myparams' } });
expect(() => convertQuery(sharedSchema)).toThrow(/myparams.*not supported/);
});

test('throws if properties cannot be exracted', () => {
expect(() => convertPathParameters(schema.string(), {})).toThrow(/expected to be an object/);
});
});

describe('is', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,17 @@ const convertObjectMembersToParameterObjects = (
knownParameters: KnownParameters = {},
isPathParameter = false
) => {
let properties: Exclude<OpenAPIV3.SchemaObject['properties'], undefined>;
let properties: OpenAPIV3.SchemaObject['properties'];
const required = new Map<string, boolean>();
if (isNullableObjectType(schema)) {
const { result } = parse({ schema, ctx });
const anyOf = (result as OpenAPIV3.SchemaObject).anyOf as OpenAPIV3.SchemaObject[];
properties = anyOf.find((s) => s.type === 'object')!.properties!;
if (result.anyOf) {
properties = result.anyOf.find(
(s): s is OpenAPIV3.SchemaObject => !isReferenceObject(s) && s.type === 'object'
)?.properties;
} else if (result.type === 'object') {
properties = result.properties;
}
} else if (isObjectType(schema)) {
const { result } = parse({ schema, ctx });
if ('$ref' in result)
Expand All @@ -108,6 +113,10 @@ const convertObjectMembersToParameterObjects = (
throw createError(`Expected record, object or nullable object type, but got '${schema.type}'`);
}

if (!properties) {
throw createError(`Could not extract properties from ${schema.describe()}`);
}

return Object.entries(properties).map(([schemaKey, schemaObject]) => {
const paramSchema = getParamSchema(knownParameters, schemaKey);
if (!paramSchema && isPathParameter) {
Expand Down

0 comments on commit d3569f6

Please sign in to comment.