diff --git a/aspida.config.js b/aspida.config.js index 50812f29..96d848d5 100644 --- a/aspida.config.js +++ b/aspida.config.js @@ -64,6 +64,11 @@ module.exports = [ outputEachDir: true, openapi: { inputFile: 'samples/allOf-required.yml' }, }, + { + input: 'samples/empty-object-response-body', + outputEachDir: true, + openapi: { inputFile: 'samples/empty-object-response-body.yml' }, + }, // { // input: 'samples/path-at-mark', // outputEachDir: true, diff --git a/samples/empty-object-response-body.yml b/samples/empty-object-response-body.yml new file mode 100644 index 00000000..08f929c5 --- /dev/null +++ b/samples/empty-object-response-body.yml @@ -0,0 +1,34 @@ +openapi: 3.0.0 +info: + version: 1.0.0 + title: Sample +paths: + /without-additional-properties: + delete: + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + /with-additional-properties-true: + delete: + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + additionalProperties: true + /with-additional-properties-false: + delete: + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + additionalProperties: false diff --git a/samples/empty-object-response-body/$api.ts b/samples/empty-object-response-body/$api.ts new file mode 100644 index 00000000..c8139fd5 --- /dev/null +++ b/samples/empty-object-response-body/$api.ts @@ -0,0 +1,57 @@ +import type { AspidaClient, BasicHeaders } from 'aspida'; +import type { Methods as Methods0 } from './with-additional-properties-false'; +import type { Methods as Methods1 } from './with-additional-properties-true'; +import type { Methods as Methods2 } from './without-additional-properties'; + +const api = ({ baseURL, fetch }: AspidaClient) => { + const prefix = (baseURL === undefined ? '' : baseURL).replace(/\/$/, ''); + const PATH0 = '/with-additional-properties-false'; + const PATH1 = '/with-additional-properties-true'; + const PATH2 = '/without-additional-properties'; + const DELETE = 'DELETE'; + + return { + with_additional_properties_false: { + /** + * @returns OK + */ + delete: (option?: { config?: T | undefined } | undefined) => + fetch(prefix, PATH0, DELETE, option).json(), + /** + * @returns OK + */ + $delete: (option?: { config?: T | undefined } | undefined) => + fetch(prefix, PATH0, DELETE, option).json().then(r => r.body), + $path: () => `${prefix}${PATH0}`, + }, + with_additional_properties_true: { + /** + * @returns OK + */ + delete: (option?: { config?: T | undefined } | undefined) => + fetch(prefix, PATH1, DELETE, option).json(), + /** + * @returns OK + */ + $delete: (option?: { config?: T | undefined } | undefined) => + fetch(prefix, PATH1, DELETE, option).json().then(r => r.body), + $path: () => `${prefix}${PATH1}`, + }, + without_additional_properties: { + /** + * @returns OK + */ + delete: (option?: { config?: T | undefined } | undefined) => + fetch(prefix, PATH2, DELETE, option).json(), + /** + * @returns OK + */ + $delete: (option?: { config?: T | undefined } | undefined) => + fetch(prefix, PATH2, DELETE, option).json().then(r => r.body), + $path: () => `${prefix}${PATH2}`, + }, + }; +}; + +export type ApiInstance = ReturnType; +export default api; diff --git a/samples/empty-object-response-body/with-additional-properties-false/$api.ts b/samples/empty-object-response-body/with-additional-properties-false/$api.ts new file mode 100644 index 00000000..2c7795b9 --- /dev/null +++ b/samples/empty-object-response-body/with-additional-properties-false/$api.ts @@ -0,0 +1,25 @@ +import type { AspidaClient, BasicHeaders } from 'aspida'; +import type { Methods as Methods0 } from '.'; + +const api = ({ baseURL, fetch }: AspidaClient) => { + const prefix = (baseURL === undefined ? '' : baseURL).replace(/\/$/, ''); + const PATH0 = '/with-additional-properties-false'; + const DELETE = 'DELETE'; + + return { + /** + * @returns OK + */ + delete: (option?: { config?: T | undefined } | undefined) => + fetch(prefix, PATH0, DELETE, option).json(), + /** + * @returns OK + */ + $delete: (option?: { config?: T | undefined } | undefined) => + fetch(prefix, PATH0, DELETE, option).json().then(r => r.body), + $path: () => `${prefix}${PATH0}`, + }; +}; + +export type ApiInstance = ReturnType; +export default api; diff --git a/samples/empty-object-response-body/with-additional-properties-false/index.ts b/samples/empty-object-response-body/with-additional-properties-false/index.ts new file mode 100644 index 00000000..c68852f3 --- /dev/null +++ b/samples/empty-object-response-body/with-additional-properties-false/index.ts @@ -0,0 +1,10 @@ +/* eslint-disable */ +export type Methods = { + delete: { + status: 200 + + /** OK */ + resBody: { + } + } +} diff --git a/samples/empty-object-response-body/with-additional-properties-true/$api.ts b/samples/empty-object-response-body/with-additional-properties-true/$api.ts new file mode 100644 index 00000000..0c868038 --- /dev/null +++ b/samples/empty-object-response-body/with-additional-properties-true/$api.ts @@ -0,0 +1,25 @@ +import type { AspidaClient, BasicHeaders } from 'aspida'; +import type { Methods as Methods0 } from '.'; + +const api = ({ baseURL, fetch }: AspidaClient) => { + const prefix = (baseURL === undefined ? '' : baseURL).replace(/\/$/, ''); + const PATH0 = '/with-additional-properties-true'; + const DELETE = 'DELETE'; + + return { + /** + * @returns OK + */ + delete: (option?: { config?: T | undefined } | undefined) => + fetch(prefix, PATH0, DELETE, option).json(), + /** + * @returns OK + */ + $delete: (option?: { config?: T | undefined } | undefined) => + fetch(prefix, PATH0, DELETE, option).json().then(r => r.body), + $path: () => `${prefix}${PATH0}`, + }; +}; + +export type ApiInstance = ReturnType; +export default api; diff --git a/samples/empty-object-response-body/with-additional-properties-true/index.ts b/samples/empty-object-response-body/with-additional-properties-true/index.ts new file mode 100644 index 00000000..833ecfeb --- /dev/null +++ b/samples/empty-object-response-body/with-additional-properties-true/index.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export type Methods = { + delete: { + status: 200 + + /** OK */ + resBody: { + [key: string]: any + } + } +} diff --git a/samples/empty-object-response-body/without-additional-properties/$api.ts b/samples/empty-object-response-body/without-additional-properties/$api.ts new file mode 100644 index 00000000..c158d097 --- /dev/null +++ b/samples/empty-object-response-body/without-additional-properties/$api.ts @@ -0,0 +1,25 @@ +import type { AspidaClient, BasicHeaders } from 'aspida'; +import type { Methods as Methods0 } from '.'; + +const api = ({ baseURL, fetch }: AspidaClient) => { + const prefix = (baseURL === undefined ? '' : baseURL).replace(/\/$/, ''); + const PATH0 = '/without-additional-properties'; + const DELETE = 'DELETE'; + + return { + /** + * @returns OK + */ + delete: (option?: { config?: T | undefined } | undefined) => + fetch(prefix, PATH0, DELETE, option).json(), + /** + * @returns OK + */ + $delete: (option?: { config?: T | undefined } | undefined) => + fetch(prefix, PATH0, DELETE, option).json().then(r => r.body), + $path: () => `${prefix}${PATH0}`, + }; +}; + +export type ApiInstance = ReturnType; +export default api; diff --git a/samples/empty-object-response-body/without-additional-properties/index.ts b/samples/empty-object-response-body/without-additional-properties/index.ts new file mode 100644 index 00000000..c68852f3 --- /dev/null +++ b/samples/empty-object-response-body/without-additional-properties/index.ts @@ -0,0 +1,10 @@ +/* eslint-disable */ +export type Methods = { + delete: { + status: 200 + + /** OK */ + resBody: { + } + } +} diff --git a/samples/openapi/api/v3/channels/_channelId@string/chats/_chatId@string/items/index.ts b/samples/openapi/api/v3/channels/_channelId@string/chats/_chatId@string/items/index.ts index b2cd7ee0..0d44140f 100644 --- a/samples/openapi/api/v3/channels/_channelId@string/chats/_chatId@string/items/index.ts +++ b/samples/openapi/api/v3/channels/_channelId@string/chats/_chatId@string/items/index.ts @@ -16,6 +16,8 @@ export type Methods = { resBody: { limit: number offset: number + data: { + }[] } } diff --git a/samples/openapi/api/v3/chats/_chatId@string/items/index.ts b/samples/openapi/api/v3/chats/_chatId@string/items/index.ts index b81bab07..46be4b24 100644 --- a/samples/openapi/api/v3/chats/_chatId@string/items/index.ts +++ b/samples/openapi/api/v3/chats/_chatId@string/items/index.ts @@ -18,6 +18,8 @@ export type Methods = { resBody: { limit: number offset: number + data: { + }[] } } diff --git a/src/builderUtils/converters.ts b/src/builderUtils/converters.ts index 7ee661e9..df8b68d6 100644 --- a/src/builderUtils/converters.ts +++ b/src/builderUtils/converters.ts @@ -123,11 +123,11 @@ export const schema2value = ( } else if (isArraySchema(schema)) { isArray = true; value = schema2value(schema.items); - } else if (schema.properties || schema.additionalProperties) { + } else if (schema.type === 'object' || schema.properties || 'additionalProperties' in schema) { value = object2value(schema); } else if (schema.format === 'binary') { value = isResponse ? 'Blob' : BINARY_TYPE; - } else if (schema.type !== 'object') { + } else { value = schema.type ? { integer: 'number',