diff --git a/README.md b/README.md index b4de6b4a4..945522731 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,16 @@ +This is a fork of the original OpenAPI Typescript Codegen library. It is only meant as a temprorary npm package to use until these feature requests are merged into the original repo: +- https://github.com/ferdikoomen/openapi-typescript-codegen/pull/1465 +- https://github.com/ferdikoomen/openapi-typescript-codegen/pull/1145 + +To install this fork: `npm install @oskarasplin/openapi-typescript-codegen` + +At the time of writing the `feature/omit-read-only` branch is published as the latest npm version + +Original ReadMe below + # Important announcement -> [!IMPORTANT] +> [!IMPORTANT] > Please migrate your projects to use [@hey-api/openapi-ts](https://github.com/hey-api/openapi-ts) Due to time limitations on my end, this project has been unmaintained for a while now. The `@hey-api/openapi-ts` @@ -65,6 +75,7 @@ $ openapi --help --postfixServices Service name postfix (default: "Service") --postfixModels Model name postfix --request Path to custom request file + --transformCase Transforms field names to specified case [camel, snake] (default: none) -h, --help display help for command Examples diff --git a/bin/index.js b/bin/index.js index 32f2fecbc..7105cc6b7 100755 --- a/bin/index.js +++ b/bin/index.js @@ -23,6 +23,7 @@ const params = program .option('--indent ', 'Indentation options [4, 2, tabs]', '4') .option('--postfixServices ', 'Service name postfix', 'Service') .option('--postfixModels ', 'Model name postfix') + .option('--transformCase ', 'Transforms field names to specified case [camel, snake]', 'none') .option('--request ', 'Path to custom request file') .parse(process.argv) .opts(); @@ -44,6 +45,7 @@ if (OpenAPI) { indent: params.indent, postfixServices: params.postfixServices, postfixModels: params.postfixModels, + transformCase: params.transformCase, request: params.request, }) .then(() => { diff --git a/package-lock.json b/package-lock.json index e773d3132..092b66d9a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { - "name": "openapi-typescript-codegen", - "version": "0.29.0", + "name": "@cloudfactory/openapi-typescript-codegen", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "openapi-typescript-codegen", - "version": "0.29.0", + "name": "@cloudfactory/openapi-typescript-codegen", + "version": "1.0.0", "license": "MIT", "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.5.4", @@ -5999,18 +5999,6 @@ "@types/node": "*" } }, - "node_modules/@types/eslint": { - "version": "8.56.7", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.7.tgz", - "integrity": "sha512-SjDvI/x3zsZnOkYZ3lCt9lOZWZLB2jIlNKz+LBgCtDurK0JZcwucxYHn1w2BJkD34dgX9Tjnak0txtq4WTggEA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", diff --git a/package.json b/package.json index 9833a6f91..727e947ec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "openapi-typescript-codegen", - "version": "0.29.0", + "name": "@cloudfactory/openapi-typescript-codegen", + "version": "1.0.0", "description": "Library that generates Typescript clients based on the OpenAPI specification.", "author": "Ferdi Koomen", "homepage": "https://github.com/ferdikoomen/openapi-typescript-codegen", diff --git a/src/Case.ts b/src/Case.ts new file mode 100644 index 000000000..880e6189f --- /dev/null +++ b/src/Case.ts @@ -0,0 +1,55 @@ +import { Enum } from './client/interfaces/Enum'; +import { Model } from './client/interfaces/Model'; +import { OperationResponse } from './client/interfaces/OperationResponse'; +import { Service } from './client/interfaces/Service'; + +export enum Case { + NONE = 'none', + CAMEL = 'camel', + SNAKE = 'snake', +} +// Convert a string from snake case to camel case. +const toCamelCase = (str: string): string => { + return str.replace(/_([a-z0-9])/g, match => match[1].toUpperCase()); +}; + +// Convert a string from camel case or pascal case to snake case. +const toSnakeCase = (str: string): string => { + return str.replace(/([A-Z])/g, match => `_${match.toLowerCase()}`); +}; + +const transforms = { + [Case.CAMEL]: toCamelCase, + [Case.SNAKE]: toSnakeCase, +}; + +// A recursive function that looks at the models and their properties and +// converts each property name using the provided transform function. +export const convertModelCase = (model: T, type: Exclude): T => { + return { + ...model, + name: transforms[type](model.name), + link: model.link ? convertModelCase(model.link, type) : null, + enum: model.enum.map(modelEnum => convertEnumCase(modelEnum, type)), + enums: model.enums.map(property => convertModelCase(property, type)), + properties: model.properties.map(property => convertModelCase(property, type)), + }; +}; + +const convertEnumCase = (modelEnum: Enum, type: Exclude): Enum => { + return { + ...modelEnum, + name: transforms[type](modelEnum.name), + }; +}; + +export const convertServiceCase = (service: Service, type: Exclude): Service => { + return { + ...service, + operations: service.operations.map(op => ({ + ...op, + parameters: op.parameters.map(opParameter => convertModelCase(opParameter, type)), + results: op.results.map(results => convertModelCase(results, type)), + })), + }; +}; diff --git a/src/index.ts b/src/index.ts index e63919085..a02110d43 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ +import { Case } from './Case'; import { HttpClient } from './HttpClient'; import { Indent } from './Indent'; import { parse as parseV2 } from './openApi/v2'; @@ -26,6 +27,7 @@ export type Options = { indent?: Indent; postfixServices?: string; postfixModels?: string; + transformCase?: Case; request?: string; write?: boolean; }; @@ -47,6 +49,7 @@ export type Options = { * @param indent Indentation options (4, 2 or tab) * @param postfixServices Service name postfix * @param postfixModels Model name postfix + * @param transformCase Transform case (camel, snake) * @param request Path to custom request file * @param write Write the files to disk (true or false) */ @@ -64,6 +67,7 @@ export const generate = async ({ indent = Indent.SPACE_4, postfixServices = 'Service', postfixModels = '', + transformCase = Case.NONE, request, write = true, }: Options): Promise => { @@ -94,6 +98,7 @@ export const generate = async ({ indent, postfixServices, postfixModels, + transformCase, clientName, request ); @@ -118,6 +123,7 @@ export const generate = async ({ indent, postfixServices, postfixModels, + transformCase, clientName, request ); diff --git a/src/templates/core/utils/OmitReadonly.hbs b/src/templates/core/utils/OmitReadonly.hbs new file mode 100644 index 000000000..0a10bb4aa --- /dev/null +++ b/src/templates/core/utils/OmitReadonly.hbs @@ -0,0 +1,41 @@ +/** + * The contents of this file are inspired from https://stackoverflow.com/a/62362197/10326226 + * and https://stackoverflow.com/a/75587790/14166396 + * */ + +type IfEquals = (() => T extends X ? 1 : 2) extends < + T, +>() => T extends Y ? 1 : 2 + ? A + : B; + +type WritableKeys = { + [P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]: T[P] }, P>; +}[keyof T]; + +type Primitive = undefined | null | boolean | string | number | Function; + +type OmitReadonlyArray = Array>; +type OmitReadonlyMap = Map>; +type DeepWriableSet = Set>; + +type OmitReadonlyObject = MakeUndefinedFieldsOptional<{ + [K in WritableKeys]: OmitReadonly; +}>; + +type UndefinedProps = { + [K in keyof T as undefined extends T[K] ? K : never]?: T[K]; +}; + +type MakeUndefinedFieldsOptional = UndefinedProps & + Omit>; + +export declare type OmitReadonly = T extends Primitive + ? T + : T extends Array + ? OmitReadonlyArray + : T extends Map + ? OmitReadonlyMap + : T extends Set + ? DeepWriableSet + : OmitReadonlyObject; diff --git a/src/templates/exportService.hbs b/src/templates/exportService.hbs index d6bccbbeb..bf6c25bf0 100644 --- a/src/templates/exportService.hbs +++ b/src/templates/exportService.hbs @@ -30,6 +30,7 @@ import type { BaseHttpRequest } from '../core/BaseHttpRequest'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; {{/if}} +import type { OmitReadonly } from '../core/utils/OmitReadonly'; {{#equals @root.httpClient 'angular'}} @Injectable({ diff --git a/src/templates/partials/parameters.hbs b/src/templates/partials/parameters.hbs index 57ab5a7d1..9e23a9190 100644 --- a/src/templates/partials/parameters.hbs +++ b/src/templates/partials/parameters.hbs @@ -16,13 +16,13 @@ {{/if}} */ {{/ifdef}} -{{{name}}}{{>isRequired}}: {{>type}}, +{{{name}}}{{>isRequired}}: {{>typeWithOmitReadOnly httpMethod=../method}}, {{/each}} } {{~else}} {{#each parameters}} -{{{name}}}{{>isRequired}}: {{>type}}{{#if default}} = {{{default}}}{{/if}}, +{{{name}}}{{>isRequired}}: {{>typeWithOmitReadOnly httpMethod=../method}}{{#if default}} = {{{default}}}{{/if}}, {{/each}} {{/if}} {{/if}} diff --git a/src/templates/partials/typeWithOmitReadOnly.hbs b/src/templates/partials/typeWithOmitReadOnly.hbs new file mode 100644 index 000000000..ec5359c59 --- /dev/null +++ b/src/templates/partials/typeWithOmitReadOnly.hbs @@ -0,0 +1,13 @@ +{{#equals export "reference"}} +{{#equals httpMethod "POST"~}} + OmitReadonly<{{>type}}> +{{~else equals httpMethod "PUT"~}} + OmitReadonly<{{>type}}> +{{~else equals httpMethod "PATCH"~}} + OmitReadonly<{{>type}}> +{{else}} + {{~>type}} +{{~/equals}} +{{~else}} + {{~>type}} +{{~/equals}} diff --git a/src/utils/registerHandlebarTemplates.ts b/src/utils/registerHandlebarTemplates.ts index bf77cbdc1..6ead3a7f7 100644 --- a/src/utils/registerHandlebarTemplates.ts +++ b/src/utils/registerHandlebarTemplates.ts @@ -46,6 +46,7 @@ import nodeRequest from '../templates/core/node/request.hbs'; import nodeSendRequest from '../templates/core/node/sendRequest.hbs'; import templateCoreSettings from '../templates/core/OpenAPI.hbs'; import templateCoreRequest from '../templates/core/request.hbs'; +import omitReadonly from '../templates/core/utils/OmitReadonly.hbs'; import xhrGetHeaders from '../templates/core/xhr/getHeaders.hbs'; import xhrGetRequestBody from '../templates/core/xhr/getRequestBody.hbs'; import xhrGetResponseBody from '../templates/core/xhr/getResponseBody.hbs'; @@ -83,6 +84,7 @@ import partialTypeInterface from '../templates/partials/typeInterface.hbs'; import partialTypeIntersection from '../templates/partials/typeIntersection.hbs'; import partialTypeReference from '../templates/partials/typeReference.hbs'; import partialTypeUnion from '../templates/partials/typeUnion.hbs'; +import typeWithOmitReadOnly from '../templates/partials/typeWithOmitReadOnly.hbs'; import { registerHandlebarHelpers } from './registerHandlebarHelpers'; export interface Templates { @@ -102,6 +104,9 @@ export interface Templates { request: Handlebars.TemplateDelegate; baseHttpRequest: Handlebars.TemplateDelegate; httpRequest: Handlebars.TemplateDelegate; + utils: { + omitReadonly: Handlebars.TemplateDelegate; + }; }; } @@ -134,6 +139,9 @@ export const registerHandlebarTemplates = (root: { request: Handlebars.template(templateCoreRequest), baseHttpRequest: Handlebars.template(templateCoreBaseHttpRequest), httpRequest: Handlebars.template(templateCoreHttpRequest), + utils: { + omitReadonly: Handlebars.template(omitReadonly), + }, }, }; @@ -163,6 +171,7 @@ export const registerHandlebarTemplates = (root: { Handlebars.registerPartial('typeInterface', Handlebars.template(partialTypeInterface)); Handlebars.registerPartial('typeReference', Handlebars.template(partialTypeReference)); Handlebars.registerPartial('typeUnion', Handlebars.template(partialTypeUnion)); + Handlebars.registerPartial('typeWithOmitReadOnly', Handlebars.template(typeWithOmitReadOnly)); Handlebars.registerPartial('typeIntersection', Handlebars.template(partialTypeIntersection)); Handlebars.registerPartial('base', Handlebars.template(partialBase)); diff --git a/src/utils/writeClient.spec.ts b/src/utils/writeClient.spec.ts index 3c06a95a5..fed931607 100644 --- a/src/utils/writeClient.spec.ts +++ b/src/utils/writeClient.spec.ts @@ -1,3 +1,4 @@ +import { Case } from '../Case'; import type { Client } from '../client/interfaces/Client'; import { HttpClient } from '../HttpClient'; import { Indent } from '../Indent'; @@ -33,6 +34,9 @@ describe('writeClient', () => { request: () => 'request', baseHttpRequest: () => 'baseHttpRequest', httpRequest: () => 'httpRequest', + utils: { + omitReadonly: () => 'omitReadonly', + }, }, }; @@ -49,7 +53,8 @@ describe('writeClient', () => { true, Indent.SPACE_4, 'Service', - 'AppClient' + 'AppClient', + Case.NONE, ); expect(rmdir).toBeCalled(); diff --git a/src/utils/writeClient.ts b/src/utils/writeClient.ts index cea2f3d88..cbda510ee 100644 --- a/src/utils/writeClient.ts +++ b/src/utils/writeClient.ts @@ -1,6 +1,7 @@ import { resolve } from 'path'; import type { Client } from '../client/interfaces/Client'; +import { Case } from '../Case'; import type { HttpClient } from '../HttpClient'; import type { Indent } from '../Indent'; import { mkdir, rmdir } from './fileSystem'; @@ -30,6 +31,7 @@ import { writeClientServices } from './writeClientServices'; * @param indent Indentation options (4, 2 or tab) * @param postfixServices Service name postfix * @param postfixModels Model name postfix + * @param transformCase Transform model case (camel, snake) * @param clientName Custom client class name * @param request Path to custom request file */ @@ -47,11 +49,13 @@ export const writeClient = async ( indent: Indent, postfixServices: string, postfixModels: string, + transformCase: Case, clientName?: string, request?: string ): Promise => { const outputPath = resolve(process.cwd(), output); const outputPathCore = resolve(outputPath, 'core'); + const outputPathCoreUtils = resolve(outputPath, 'core', 'utils'); const outputPathModels = resolve(outputPath, 'models'); const outputPathSchemas = resolve(outputPath, 'schemas'); const outputPathServices = resolve(outputPath, 'services'); @@ -62,8 +66,17 @@ export const writeClient = async ( if (exportCore) { await rmdir(outputPathCore); - await mkdir(outputPathCore); - await writeClientCore(client, templates, outputPathCore, httpClient, indent, clientName, request); + await mkdir(outputPathCoreUtils); + await writeClientCore( + client, + templates, + outputPathCore, + outputPathCoreUtils, + httpClient, + indent, + clientName, + request + ); } if (exportServices) { @@ -78,6 +91,7 @@ export const writeClient = async ( useOptions, indent, postfixServices, + transformCase, clientName ); } @@ -91,7 +105,15 @@ export const writeClient = async ( if (exportModels) { await rmdir(outputPathModels); await mkdir(outputPathModels); - await writeClientModels(client.models, templates, outputPathModels, httpClient, useUnionTypes, indent); + await writeClientModels( + client.models, + templates, + outputPathModels, + httpClient, + useUnionTypes, + indent, + transformCase + ); } if (isDefined(clientName)) { diff --git a/src/utils/writeClientClass.spec.ts b/src/utils/writeClientClass.spec.ts index 102f2eb57..9233dc4e5 100644 --- a/src/utils/writeClientClass.spec.ts +++ b/src/utils/writeClientClass.spec.ts @@ -33,6 +33,9 @@ describe('writeClientClass', () => { request: () => 'request', baseHttpRequest: () => 'baseHttpRequest', httpRequest: () => 'httpRequest', + utils: { + omitReadonly: () => 'omitReadonly', + }, }, }; diff --git a/src/utils/writeClientCore.spec.ts b/src/utils/writeClientCore.spec.ts index 7db71f59b..a8fd65274 100644 --- a/src/utils/writeClientCore.spec.ts +++ b/src/utils/writeClientCore.spec.ts @@ -36,10 +36,13 @@ describe('writeClientCore', () => { request: () => 'request', baseHttpRequest: () => 'baseHttpRequest', httpRequest: () => 'httpRequest', + utils: { + omitReadonly: () => 'omitReadonly', + }, }, }; - await writeClientCore(client, templates, '/', HttpClient.FETCH, Indent.SPACE_4); + await writeClientCore(client, templates, '/', '/utils', HttpClient.FETCH, Indent.SPACE_4); expect(writeFile).toBeCalledWith(resolve('/', '/OpenAPI.ts'), `settings${EOL}`); expect(writeFile).toBeCalledWith(resolve('/', '/ApiError.ts'), `apiError${EOL}`); @@ -47,5 +50,6 @@ describe('writeClientCore', () => { expect(writeFile).toBeCalledWith(resolve('/', '/ApiResult.ts'), `apiResult${EOL}`); expect(writeFile).toBeCalledWith(resolve('/', '/CancelablePromise.ts'), `cancelablePromise${EOL}`); expect(writeFile).toBeCalledWith(resolve('/', '/request.ts'), `request${EOL}`); + expect(writeFile).toBeCalledWith(resolve('/', '/utils/OmitReadonly.ts'), `omitReadonly${EOL}`); }); }); diff --git a/src/utils/writeClientCore.ts b/src/utils/writeClientCore.ts index 6d35849d2..74547335f 100644 --- a/src/utils/writeClientCore.ts +++ b/src/utils/writeClientCore.ts @@ -14,6 +14,7 @@ import type { Templates } from './registerHandlebarTemplates'; * @param client Client object, containing, models, schemas and services * @param templates The loaded handlebar templates * @param outputPath Directory to write the generated files to + * @param outputUtilsPath Directory to write the generated util files to * @param httpClient The selected httpClient (fetch, xhr, node or axios) * @param indent Indentation options (4, 2 or tab) * @param clientName Custom client class name @@ -23,6 +24,7 @@ export const writeClientCore = async ( client: Client, templates: Templates, outputPath: string, + outputUtilsPath: string, httpClient: HttpClient, indent: Indent, clientName?: string, @@ -43,6 +45,7 @@ export const writeClientCore = async ( await writeFile(resolve(outputPath, 'ApiResult.ts'), i(templates.core.apiResult(context), indent)); await writeFile(resolve(outputPath, 'CancelablePromise.ts'), i(templates.core.cancelablePromise(context), indent)); await writeFile(resolve(outputPath, 'request.ts'), i(templates.core.request(context), indent)); + await writeFile(resolve(outputUtilsPath, 'OmitReadonly.ts'), i(templates.core.utils.omitReadonly(context), indent)); if (isDefined(clientName)) { await writeFile(resolve(outputPath, 'BaseHttpRequest.ts'), i(templates.core.baseHttpRequest(context), indent)); diff --git a/src/utils/writeClientIndex.spec.ts b/src/utils/writeClientIndex.spec.ts index a7d5b610a..0c15468ef 100644 --- a/src/utils/writeClientIndex.spec.ts +++ b/src/utils/writeClientIndex.spec.ts @@ -33,6 +33,9 @@ describe('writeClientIndex', () => { request: () => 'request', baseHttpRequest: () => 'baseHttpRequest', httpRequest: () => 'httpRequest', + utils: { + omitReadonly: () => 'omitReadonly', + }, }, }; diff --git a/src/utils/writeClientModels.spec.ts b/src/utils/writeClientModels.spec.ts index ee0f2b4f6..921446de5 100644 --- a/src/utils/writeClientModels.spec.ts +++ b/src/utils/writeClientModels.spec.ts @@ -1,6 +1,7 @@ import { EOL } from 'os'; import { resolve } from 'path'; +import { Case } from '../Case'; import type { Model } from '../client/interfaces/Model'; import { HttpClient } from '../HttpClient'; import { Indent } from '../Indent'; @@ -49,10 +50,13 @@ describe('writeClientModels', () => { request: () => 'request', baseHttpRequest: () => 'baseHttpRequest', httpRequest: () => 'httpRequest', + utils: { + omitReadonly: () => 'omitReadonly', + }, }, }; - await writeClientModels(models, templates, '/', HttpClient.FETCH, false, Indent.SPACE_4); + await writeClientModels(models, templates, '/', HttpClient.FETCH, false, Indent.SPACE_4, Case.NONE); expect(writeFile).toBeCalledWith(resolve('/', '/User.ts'), `model${EOL}`); }); diff --git a/src/utils/writeClientModels.ts b/src/utils/writeClientModels.ts index 997569b9f..84244f70b 100644 --- a/src/utils/writeClientModels.ts +++ b/src/utils/writeClientModels.ts @@ -1,5 +1,6 @@ import { resolve } from 'path'; +import { Case, convertModelCase } from '../Case'; import type { Model } from '../client/interfaces/Model'; import type { HttpClient } from '../HttpClient'; import type { Indent } from '../Indent'; @@ -16,6 +17,7 @@ import type { Templates } from './registerHandlebarTemplates'; * @param httpClient The selected httpClient (fetch, xhr, node or axios) * @param useUnionTypes Use union types instead of enums * @param indent Indentation options (4, 2 or tab) + * @param transformCase Transform model case (camel, snake) */ export const writeClientModels = async ( models: Model[], @@ -23,12 +25,14 @@ export const writeClientModels = async ( outputPath: string, httpClient: HttpClient, useUnionTypes: boolean, - indent: Indent + indent: Indent, + transformCase: Case ): Promise => { for (const model of models) { + const newModel = transformCase === Case.NONE ? model : convertModelCase(model, transformCase); const file = resolve(outputPath, `${model.name}.ts`); const templateResult = templates.exports.model({ - ...model, + ...newModel, httpClient, useUnionTypes, }); diff --git a/src/utils/writeClientSchemas.spec.ts b/src/utils/writeClientSchemas.spec.ts index e75928b8c..119561ccb 100644 --- a/src/utils/writeClientSchemas.spec.ts +++ b/src/utils/writeClientSchemas.spec.ts @@ -49,6 +49,9 @@ describe('writeClientSchemas', () => { request: () => 'request', baseHttpRequest: () => 'baseHttpRequest', httpRequest: () => 'httpRequest', + utils: { + omitReadonly: () => 'omitReadonly', + }, }, }; diff --git a/src/utils/writeClientServices.spec.ts b/src/utils/writeClientServices.spec.ts index f936d6609..7add2d108 100644 --- a/src/utils/writeClientServices.spec.ts +++ b/src/utils/writeClientServices.spec.ts @@ -1,6 +1,7 @@ import { EOL } from 'os'; import { resolve } from 'path'; +import { Case } from '../Case'; import type { Service } from '../client/interfaces/Service'; import { HttpClient } from '../HttpClient'; import { Indent } from '../Indent'; @@ -37,10 +38,23 @@ describe('writeClientServices', () => { request: () => 'request', baseHttpRequest: () => 'baseHttpRequest', httpRequest: () => 'httpRequest', + utils: { + omitReadonly: () => 'omitReadonly', + }, }, }; - await writeClientServices(services, templates, '/', HttpClient.FETCH, false, false, Indent.SPACE_4, 'Service'); + await writeClientServices( + services, + templates, + '/', + HttpClient.FETCH, + false, + false, + Indent.SPACE_4, + 'Service', + Case.NONE + ); expect(writeFile).toBeCalledWith(resolve('/', '/UserService.ts'), `service${EOL}`); }); diff --git a/src/utils/writeClientServices.ts b/src/utils/writeClientServices.ts index 2f95341d2..02f589c52 100644 --- a/src/utils/writeClientServices.ts +++ b/src/utils/writeClientServices.ts @@ -1,5 +1,6 @@ import { resolve } from 'path'; +import { Case, convertServiceCase } from '../Case'; import type { Service } from '../client/interfaces/Service'; import type { HttpClient } from '../HttpClient'; import type { Indent } from '../Indent'; @@ -19,6 +20,7 @@ import type { Templates } from './registerHandlebarTemplates'; * @param useOptions Use options or arguments functions * @param indent Indentation options (4, 2 or tab) * @param postfix Service name postfix + * @param transformCase Transform model case (camel, snake) * @param clientName Custom client class name */ export const writeClientServices = async ( @@ -30,12 +32,14 @@ export const writeClientServices = async ( useOptions: boolean, indent: Indent, postfix: string, + transformCase: Case, clientName?: string ): Promise => { for (const service of services) { + const newService = transformCase === Case.NONE ? service : convertServiceCase(service, transformCase); const file = resolve(outputPath, `${service.name}${postfix}.ts`); const templateResult = templates.exports.service({ - ...service, + ...newService, httpClient, useUnionTypes, useOptions,