From 0153b1ae18ae3bb8aa710999a8c258405e94be8f Mon Sep 17 00:00:00 2001 From: shinevision Date: Sat, 8 Apr 2023 22:42:26 +0200 Subject: [PATCH 1/3] Add support for returning null instead of undefined. --- README.md | 1 + bin/index.js | 2 ++ bin/index.spec.js | 1 + docs/basic-usage.md | 1 + src/index.ts | 6 ++++++ src/templates/core/angular/getResponseBody.hbs | 4 ++++ src/templates/core/axios/getResponseBody.hbs | 4 ++++ src/templates/core/fetch/getResponseBody.hbs | 4 ++++ src/templates/core/node/getResponseBody.hbs | 4 ++++ src/templates/core/xhr/getResponseBody.hbs | 4 ++++ src/utils/registerHandlebarTemplates.ts | 1 + src/utils/writeClient.ts | 3 ++- src/utils/writeClientCore.ts | 4 +++- 13 files changed, 37 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 429f905ee..0c08326f9 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ $ openapi --help --name Custom client class name --useOptions Use options instead of arguments --useUnionTypes Use union types instead of enums + --useNullForNoContent Use null for returning instead of undefined if a response returns 204 no content --exportCore Write core files to disk (default: true) --exportServices Write services to disk (default: true) --exportModels Write models to disk (default: true) diff --git a/bin/index.js b/bin/index.js index ed8b0889b..58672737a 100755 --- a/bin/index.js +++ b/bin/index.js @@ -16,6 +16,7 @@ const params = program .option('--name ', 'Custom client class name') .option('--useOptions', 'Use options instead of arguments') .option('--useUnionTypes', 'Use union types instead of enums') + .option('--useNullForNoContent', 'Use null for returning instead of undefined if a response returns 204 no content') .option('--exportCore ', 'Write core files to disk', true) .option('--exportServices ', 'Write services to disk', true) .option('--exportModels ', 'Write models to disk', true) @@ -38,6 +39,7 @@ if (OpenAPI) { clientName: params.name, useOptions: params.useOptions, useUnionTypes: params.useUnionTypes, + useNullForNoContent: params.useNullForNoContent, exportCore: JSON.parse(params.exportCore) === true, exportServices: JSON.parse(params.exportServices) === true, exportModels: JSON.parse(params.exportModels) === true, diff --git a/bin/index.spec.js b/bin/index.spec.js index 6f49daf03..33c9f79f3 100755 --- a/bin/index.spec.js +++ b/bin/index.spec.js @@ -24,6 +24,7 @@ describe('bin', () => { 'fetch', '--useOptions', '--useUnionTypes', + '--useNullForNoContent', '--exportCore', 'true', '--exportServices', diff --git a/docs/basic-usage.md b/docs/basic-usage.md index d02da0888..fa54fd85f 100644 --- a/docs/basic-usage.md +++ b/docs/basic-usage.md @@ -13,6 +13,7 @@ $ openapi --help --name Custom client class name --useOptions Use options instead of arguments --useUnionTypes Use union types instead of enums + --useNullForNoContent Use null for returning instead of undefined if a response returns 204 no content --exportCore Write core files to disk (default: true) --exportServices Write services to disk (default: true) --exportModels Write models to disk (default: true) diff --git a/src/index.ts b/src/index.ts index e63919085..9d73b246a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,6 +19,7 @@ export type Options = { clientName?: string; useOptions?: boolean; useUnionTypes?: boolean; + useNullForNoContent?: boolean; exportCore?: boolean; exportServices?: boolean; exportModels?: boolean; @@ -40,6 +41,7 @@ export type Options = { * @param clientName Custom client class name * @param useOptions Use options or arguments functions * @param useUnionTypes Use union types instead of enums + * @param useNullForNoContent Use null for no content responses * @param exportCore Generate core client classes * @param exportServices Generate services * @param exportModels Generate models @@ -57,6 +59,7 @@ export const generate = async ({ clientName, useOptions = false, useUnionTypes = false, + useNullForNoContent = false, exportCore = true, exportServices = true, exportModels = true, @@ -72,6 +75,7 @@ export const generate = async ({ const templates = registerHandlebarTemplates({ httpClient, useUnionTypes, + useNullForNoContent, useOptions, }); @@ -87,6 +91,7 @@ export const generate = async ({ httpClient, useOptions, useUnionTypes, + useNullForNoContent, exportCore, exportServices, exportModels, @@ -111,6 +116,7 @@ export const generate = async ({ httpClient, useOptions, useUnionTypes, + useNullForNoContent, exportCore, exportServices, exportModels, diff --git a/src/templates/core/angular/getResponseBody.hbs b/src/templates/core/angular/getResponseBody.hbs index 91761fc57..0a90d01b0 100644 --- a/src/templates/core/angular/getResponseBody.hbs +++ b/src/templates/core/angular/getResponseBody.hbs @@ -2,5 +2,9 @@ const getResponseBody = (response: HttpResponse): T | undefined => { if (response.status !== 204 && response.body !== null) { return response.body; } + {{#if @root.useNullForNoContent}} + return null; + {{else}} return undefined; + {{/if}} }; diff --git a/src/templates/core/axios/getResponseBody.hbs b/src/templates/core/axios/getResponseBody.hbs index 0d0287882..8e230b47d 100644 --- a/src/templates/core/axios/getResponseBody.hbs +++ b/src/templates/core/axios/getResponseBody.hbs @@ -2,5 +2,9 @@ const getResponseBody = (response: AxiosResponse): any => { if (response.status !== 204) { return response.data; } + {{#if @root.useNullForNoContent}} + return null; + {{else}} return undefined; + {{/if}} }; diff --git a/src/templates/core/fetch/getResponseBody.hbs b/src/templates/core/fetch/getResponseBody.hbs index 556c1f03f..37ad01477 100644 --- a/src/templates/core/fetch/getResponseBody.hbs +++ b/src/templates/core/fetch/getResponseBody.hbs @@ -15,5 +15,9 @@ const getResponseBody = async (response: Response): Promise => { console.error(error); } } + {{#if @root.useNullForNoContent}} + return null; + {{else}} return undefined; + {{/if}} }; diff --git a/src/templates/core/node/getResponseBody.hbs b/src/templates/core/node/getResponseBody.hbs index 556c1f03f..37ad01477 100644 --- a/src/templates/core/node/getResponseBody.hbs +++ b/src/templates/core/node/getResponseBody.hbs @@ -15,5 +15,9 @@ const getResponseBody = async (response: Response): Promise => { console.error(error); } } + {{#if @root.useNullForNoContent}} + return null; + {{else}} return undefined; + {{/if}} }; diff --git a/src/templates/core/xhr/getResponseBody.hbs b/src/templates/core/xhr/getResponseBody.hbs index 84a662ef7..5670eb6e3 100644 --- a/src/templates/core/xhr/getResponseBody.hbs +++ b/src/templates/core/xhr/getResponseBody.hbs @@ -15,5 +15,9 @@ const getResponseBody = (xhr: XMLHttpRequest): any => { console.error(error); } } + {{#if @root.useNullForNoContent}} + return null; + {{else}} return undefined; + {{/if}} }; diff --git a/src/utils/registerHandlebarTemplates.ts b/src/utils/registerHandlebarTemplates.ts index bf77cbdc1..745e993bb 100644 --- a/src/utils/registerHandlebarTemplates.ts +++ b/src/utils/registerHandlebarTemplates.ts @@ -113,6 +113,7 @@ export const registerHandlebarTemplates = (root: { httpClient: HttpClient; useOptions: boolean; useUnionTypes: boolean; + useNullForNoContent: boolean; }): Templates => { registerHandlebarHelpers(root); diff --git a/src/utils/writeClient.ts b/src/utils/writeClient.ts index cea2f3d88..02547375a 100644 --- a/src/utils/writeClient.ts +++ b/src/utils/writeClient.ts @@ -40,6 +40,7 @@ export const writeClient = async ( httpClient: HttpClient, useOptions: boolean, useUnionTypes: boolean, + useNullForNoContent: boolean, exportCore: boolean, exportServices: boolean, exportModels: boolean, @@ -63,7 +64,7 @@ export const writeClient = async ( if (exportCore) { await rmdir(outputPathCore); await mkdir(outputPathCore); - await writeClientCore(client, templates, outputPathCore, httpClient, indent, clientName, request); + await writeClientCore(client, templates, outputPathCore, httpClient, indent, clientName, request, useNullForNoContent); } if (exportServices) { diff --git a/src/utils/writeClientCore.ts b/src/utils/writeClientCore.ts index 6d35849d2..f489b4934 100644 --- a/src/utils/writeClientCore.ts +++ b/src/utils/writeClientCore.ts @@ -26,7 +26,8 @@ export const writeClientCore = async ( httpClient: HttpClient, indent: Indent, clientName?: string, - request?: string + request?: string, + useNullForNoContent: boolean, ): Promise => { const httpRequest = getHttpRequestName(httpClient); const context = { @@ -35,6 +36,7 @@ export const writeClientCore = async ( httpRequest, server: client.server, version: client.version, + useNullForNoContent, }; await writeFile(resolve(outputPath, 'OpenAPI.ts'), i(templates.core.settings(context), indent)); From c8faa10ae0d9ab7ae775077f0650cd93970167fe Mon Sep 17 00:00:00 2001 From: shinevision Date: Sat, 8 Apr 2023 23:07:49 +0200 Subject: [PATCH 2/3] Update getResponseBody.hbs Add null return value type. --- src/templates/core/angular/getResponseBody.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/templates/core/angular/getResponseBody.hbs b/src/templates/core/angular/getResponseBody.hbs index 0a90d01b0..8e38d830b 100644 --- a/src/templates/core/angular/getResponseBody.hbs +++ b/src/templates/core/angular/getResponseBody.hbs @@ -1,4 +1,4 @@ -const getResponseBody = (response: HttpResponse): T | undefined => { +const getResponseBody = (response: HttpResponse): T | {{#if @root.useNullForNoContent}}null{{else}}undefined{{/if}} => { if (response.status !== 204 && response.body !== null) { return response.body; } From cf4f78b0c2d9f5ba452976f76347dd7d8f66afb3 Mon Sep 17 00:00:00 2001 From: shinevision Date: Sun, 9 Apr 2023 00:57:24 +0200 Subject: [PATCH 3/3] Tests. Support tests. --- src/utils/registerHandlebarTemplates.spec.ts | 1 + src/utils/writeClient.spec.ts | 1 + src/utils/writeClientCore.ts | 2 +- test/index.js | 1 + test/index.spec.ts | 2 ++ types/index.d.ts | 1 + 6 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/utils/registerHandlebarTemplates.spec.ts b/src/utils/registerHandlebarTemplates.spec.ts index 5e1302384..be420ebe9 100644 --- a/src/utils/registerHandlebarTemplates.spec.ts +++ b/src/utils/registerHandlebarTemplates.spec.ts @@ -7,6 +7,7 @@ describe('registerHandlebarTemplates', () => { httpClient: HttpClient.FETCH, useOptions: false, useUnionTypes: false, + useNullForNoContent: false, }); expect(templates.index).toBeDefined(); expect(templates.exports.model).toBeDefined(); diff --git a/src/utils/writeClient.spec.ts b/src/utils/writeClient.spec.ts index 3c06a95a5..2bfc3e284 100644 --- a/src/utils/writeClient.spec.ts +++ b/src/utils/writeClient.spec.ts @@ -43,6 +43,7 @@ describe('writeClient', () => { HttpClient.FETCH, false, false, + false, true, true, true, diff --git a/src/utils/writeClientCore.ts b/src/utils/writeClientCore.ts index f489b4934..d0a84420c 100644 --- a/src/utils/writeClientCore.ts +++ b/src/utils/writeClientCore.ts @@ -27,7 +27,7 @@ export const writeClientCore = async ( indent: Indent, clientName?: string, request?: string, - useNullForNoContent: boolean, + useNullForNoContent?: boolean, ): Promise => { const httpRequest = getHttpRequestName(httpClient); const context = { diff --git a/test/index.js b/test/index.js index 6d276c412..67140aaab 100644 --- a/test/index.js +++ b/test/index.js @@ -10,6 +10,7 @@ const generate = async (input, output) => { httpClient: OpenAPI.HttpClient.FETCH, useOptions: true, useUnionTypes: false, + useNullForNoContent: false, exportCore: true, exportSchemas: true, exportModels: true, diff --git a/test/index.spec.ts b/test/index.spec.ts index b8e87da75..455157389 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -11,6 +11,7 @@ describe('v2', () => { httpClient: HttpClient.FETCH, useOptions: false, useUnionTypes: false, + useNullForNoContent: false, exportCore: true, exportSchemas: true, exportModels: true, @@ -33,6 +34,7 @@ describe('v3', () => { httpClient: HttpClient.FETCH, useOptions: false, useUnionTypes: false, + useNullForNoContent: false, exportCore: true, exportSchemas: true, exportModels: true, diff --git a/types/index.d.ts b/types/index.d.ts index e2b5247e0..e7fb57674 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -19,6 +19,7 @@ export type Options = { clientName?: string; useOptions?: boolean; useUnionTypes?: boolean; + useNullForNoContent?: boolean; exportCore?: boolean; exportServices?: boolean; exportModels?: boolean;