From 27d4c551ee2cafe8d75cc47e202ade69c4062e9e Mon Sep 17 00:00:00 2001 From: Nicholas Lim <18374483+niclim@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:54:30 -0500 Subject: [PATCH] fix nullables with type (#2641) --- package.json | 2 +- projects/fastify-capture/package.json | 2 +- projects/json-pointer-helpers/package.json | 2 +- projects/openapi-io/package.json | 2 +- projects/openapi-utilities/package.json | 2 +- projects/optic/package.json | 2 +- .../__snapshots__/patches.test.ts.snap | 102 ++++++++++++++++++ .../capture/patches/__tests__/patches.test.ts | 11 +- .../capture/patches/patchers/shapes/diff.ts | 16 ++- projects/rulesets-base/package.json | 2 +- projects/standard-rulesets/package.json | 2 +- 11 files changed, 131 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 31570d394d..f7f2881814 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "openapi-workspaces", "license": "MIT", "private": true, - "version": "0.53.17", + "version": "0.53.18", "workspaces": [ "projects/json-pointer-helpers", "projects/openapi-io", diff --git a/projects/fastify-capture/package.json b/projects/fastify-capture/package.json index 7a20bf5387..69964a8e6e 100644 --- a/projects/fastify-capture/package.json +++ b/projects/fastify-capture/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/fastify-capture", "license": "MIT", "packageManager": "yarn@4.0.2", - "version": "0.53.17", + "version": "0.53.18", "main": "build/index.js", "types": "build/index.d.ts", "files": [ diff --git a/projects/json-pointer-helpers/package.json b/projects/json-pointer-helpers/package.json index 1fc2b1519b..5fdfca98f1 100644 --- a/projects/json-pointer-helpers/package.json +++ b/projects/json-pointer-helpers/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/json-pointer-helpers", "license": "MIT", "packageManager": "yarn@4.0.2", - "version": "0.53.17", + "version": "0.53.18", "main": "build/index.js", "types": "build/index.d.ts", "files": [ diff --git a/projects/openapi-io/package.json b/projects/openapi-io/package.json index 6ad4e96cdb..bbb1fc1f10 100644 --- a/projects/openapi-io/package.json +++ b/projects/openapi-io/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/openapi-io", "license": "MIT", "packageManager": "yarn@4.0.2", - "version": "0.53.17", + "version": "0.53.18", "main": "build/index.js", "types": "build/index.d.ts", "files": [ diff --git a/projects/openapi-utilities/package.json b/projects/openapi-utilities/package.json index 55afb5694e..2ad7ad616f 100644 --- a/projects/openapi-utilities/package.json +++ b/projects/openapi-utilities/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/openapi-utilities", "license": "MIT", "packageManager": "yarn@4.0.2", - "version": "0.53.17", + "version": "0.53.18", "main": "build/index.js", "types": "build/index.d.ts", "files": [ diff --git a/projects/optic/package.json b/projects/optic/package.json index 3e9a2666b7..dfde4c709c 100644 --- a/projects/optic/package.json +++ b/projects/optic/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/optic", "license": "MIT", "packageManager": "yarn@4.0.2", - "version": "0.53.17", + "version": "0.53.18", "main": "build/index.js", "types": "build/index.d.ts", "files": [ diff --git a/projects/optic/src/commands/capture/patches/__tests__/__snapshots__/patches.test.ts.snap b/projects/optic/src/commands/capture/patches/__tests__/__snapshots__/patches.test.ts.snap index f38038b1b9..097e312010 100644 --- a/projects/optic/src/commands/capture/patches/__tests__/__snapshots__/patches.test.ts.snap +++ b/projects/optic/src/commands/capture/patches/__tests__/__snapshots__/patches.test.ts.snap @@ -802,6 +802,57 @@ exports[`generateEndpointSpecPatches OAS version 3.0.1 allOf with nullable 2`] = } `; +exports[`generateEndpointSpecPatches OAS version 3.0.1 anyOf with nullable 1`] = `[]`; + +exports[`generateEndpointSpecPatches OAS version 3.0.1 anyOf with nullable 2`] = ` +{ + "info": {}, + "openapi": "3.0.1", + "paths": { + "/api/animals": { + "post": { + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "properties": { + "key": { + "anyOf": [ + { + "properties": { + "goodbye": { + "type": "string", + }, + "hello": { + "type": "string", + }, + }, + "required": [ + "hello", + "goodbye", + ], + "type": "object", + }, + ], + "nullable": true, + }, + }, + "required": [ + "key", + ], + "type": "object", + }, + }, + }, + }, + }, + }, + }, + }, +} +`; + exports[`generateEndpointSpecPatches OAS version 3.0.1 array with multiple items 1`] = ` [ { @@ -3889,6 +3940,57 @@ exports[`generateEndpointSpecPatches OAS version 3.0.1 missing required property } `; +exports[`generateEndpointSpecPatches OAS version 3.0.1 oneOf with nullable 1`] = `[]`; + +exports[`generateEndpointSpecPatches OAS version 3.0.1 oneOf with nullable 2`] = ` +{ + "info": {}, + "openapi": "3.0.1", + "paths": { + "/api/animals": { + "post": { + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "properties": { + "key": { + "nullable": true, + "oneOf": [ + { + "properties": { + "goodbye": { + "type": "string", + }, + "hello": { + "type": "string", + }, + }, + "required": [ + "hello", + "goodbye", + ], + "type": "object", + }, + ], + }, + }, + "required": [ + "key", + ], + "type": "object", + }, + }, + }, + }, + }, + }, + }, + }, +} +`; + exports[`generateEndpointSpecPatches OAS version 3.0.1 query parameter not documented 1`] = ` [ { diff --git a/projects/optic/src/commands/capture/patches/__tests__/patches.test.ts b/projects/optic/src/commands/capture/patches/__tests__/patches.test.ts index cfd1801617..37a22cd15b 100644 --- a/projects/optic/src/commands/capture/patches/__tests__/patches.test.ts +++ b/projects/optic/src/commands/capture/patches/__tests__/patches.test.ts @@ -980,8 +980,11 @@ describe('generateEndpointSpecPatches', () => { expect(patches).toMatchSnapshot(); expect(specHolder.spec).toMatchSnapshot(); }); + }); - test('with nullable', async () => { + test.each([['oneOf'], ['anyOf'], ['allOf']])( + '%s with nullable', + async (polymorphic) => { // nullable keyword only valid in 3.0.1 if (version !== '3.0.1') return; specHolder.spec.paths['/api/animals'].post.responses = { @@ -994,7 +997,7 @@ describe('generateEndpointSpecPatches', () => { properties: { key: { nullable: true, - allOf: [ + [polymorphic]: [ { type: 'object', properties: { @@ -1038,8 +1041,8 @@ describe('generateEndpointSpecPatches', () => { expect(patches).toMatchSnapshot(); expect(specHolder.spec).toMatchSnapshot(); - }); - }); + } + ); describe.each([['query'], ['header']])('%s parameter', (location) => { test('not documented', async () => { diff --git a/projects/optic/src/commands/capture/patches/patchers/shapes/diff.ts b/projects/optic/src/commands/capture/patches/patchers/shapes/diff.ts index a491ee3d52..14491f3fc3 100644 --- a/projects/optic/src/commands/capture/patches/patchers/shapes/diff.ts +++ b/projects/optic/src/commands/capture/patches/patchers/shapes/diff.ts @@ -321,8 +321,20 @@ function prepareSchemaForDiff(input: SchemaObject): SchemaObject { // Fix case where nullable is set and there is no type key if (!schema.type && schema.nullable) { - // if polymorphic, this could also be nullable - if (!(schema.oneOf || schema.anyOf || schema.allOf)) { + if (schema.oneOf || schema.anyOf || schema.allOf) { + if (schema.oneOf || schema.anyOf) { + (schema.oneOf || schema.anyOf).push({ + type: 'object', + nullable: true, + }); + } else { + schema.allOf = schema.allOf.map((s: any) => ({ + ...s, + nullable: true, + })); + } + delete schema.nullable; + } else { // We set this to string since we're not sure what the actual type is; this should be fine for us since we'll use this schema for diffing purposes and update schema.type = 'string'; } diff --git a/projects/rulesets-base/package.json b/projects/rulesets-base/package.json index 5b05a884ca..c09bb1a724 100644 --- a/projects/rulesets-base/package.json +++ b/projects/rulesets-base/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/rulesets-base", "license": "MIT", "packageManager": "yarn@4.0.2", - "version": "0.53.17", + "version": "0.53.18", "main": "build/index.js", "types": "build/index.d.ts", "files": [ diff --git a/projects/standard-rulesets/package.json b/projects/standard-rulesets/package.json index 0cb81230cb..4fa252ee9a 100644 --- a/projects/standard-rulesets/package.json +++ b/projects/standard-rulesets/package.json @@ -2,7 +2,7 @@ "name": "@useoptic/standard-rulesets", "license": "MIT", "packageManager": "yarn@4.0.2", - "version": "0.53.17", + "version": "0.53.18", "main": "build/index.js", "types": "build/index.d.ts", "files": [