astahmer / openapi-zod-client

Generate a zodios (typescript http client with zod validation) from an OpenAPI spec (json/yaml)

Home Page:openapi-zod-client.vercel.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Transform alias to camelCase

JarnoRFB opened this issue · comments

Some API specs provide operationIds in something else than camel case, which can lead to eslint warnings for the generated aliases. Would it make sense to provide an option to directly camelCase the operationId either here or via a handlebars template? I would find this change less intrusive than #46 as the operationId is not directly part of the API.

I think you could do it with handlebars custom template + custom helper as of today (like it was done here)

otherwise I'd say any transformation should be applied before being parsed by openapi-zod-client, since it seems out of scope, i've wrote on how to do that here

Thanks for the pointers! Was able to achieve this with

static/clientTemplate.hbs

import { makeApi, Zodios } from "@zodios/core";
import { z } from "zod";

{{#if imports}}
{{#each imports}}
import { {{{@key}}} } from "./{{{this}}}"
{{/each}}
{{/if}}


{{#if types}}
{{#each types}}
{{{this}}};
{{/each}}
{{/if}}

{{#each schemas}}
const {{@key}}{{#if (lookup ../circularTypeByName @key)}}: z.ZodType<{{@key}}>{{/if}} = {{{this}}};
{{/each}}

const endpoints = makeApi([
{{#each endpoints}}
	{
		method: "{{method}}",
		path: "{{path}}",
		{{#if @root.options.withAlias}}
		{{#if alias}}
		alias: "{{camelCase alias}}", // Usage of helper function.
		{{/if}}
		{{/if}}
		{{#if description}}
		description: `{{description}}`,
		{{/if}}
		{{#if requestFormat}}
		requestFormat: "{{requestFormat}}",
		{{/if}}
		{{#if parameters}}
		parameters: [
			{{#each parameters}}
			{
				name: "{{name}}",
				{{#if description}}
				description: `{{description}}`,
				{{/if}}
				{{#if type}}
				type: "{{type}}",
				{{/if}}
				schema: {{{schema}}}
			},
			{{/each}}
		],
		{{/if}}
		response: {{{response}}},
		{{#if errors.length}}
		errors: [
			{{#each errors}}
			{
				{{#ifeq status "default" }}
				status: "default",
				{{else}}
				status: {{status}},
				{{/ifeq}}
				{{#if description}}
				description: `{{description}}`,
				{{/if}}
				schema: {{{schema}}}
			},
			{{/each}}
		]
		{{/if}}
	},
{{/each}}
]);

export const {{options.apiClientName}} = new Zodios({{#if options.baseUrl}}"{{options.baseUrl}}", {{/if}}endpoints);

and

  import {generateZodClientFromOpenAPI, getHandlebars} from "openapi-zod-client";
  import _ from "lodash";

  const handlebars = getHandlebars();
  handlebars.registerHelper("camelCase", _.camelCase);

  await generateZodClientFromOpenAPI({
    openApiDoc,
    distPath: outputPath,
    templatePath: "static/clientTemplate.hbs",
    handlebars,
    options: {withAlias: true},
  });

Might be nice a to add some templates to the library diretly for some standard usecases, but great that the system is so flexible!

🙏 glad it worked well for you !

for some standard usecases

do you have some examples in mind ? i'm very open to have multiple templates built-in, but i'm not sure what kind of usecases could be worth including

maybe after some time and enough demand this will become obvious 😅

maybe after some time and enough demand this will become obvious sweat_smile

Yeah I guess so. This use case (camelcasing aliases) and the more advanced #46 could be a start. These would require shipping the helper functions together with the templates, but that could make sense as well. Maybe I can look into opening a PR that adds support for those.

is it possible to do it with command only using --api-client-name=\"src/api/client-template.hbs\" for example ?