astahmer / openapi-zod-client

Generate a zodios (typescript http client with zod validation) from an OpenAPI spec (json/yaml)
openapi-zod-client.vercel.app
717 stars 80 forks source link

Getting types for parameters #256

Open ArthurGoupil opened 8 months ago

ArthurGoupil commented 8 months ago

Hello @astahmer !

I'm using the lib along with openapi-generator to get:

For now, I'm using the template to get well formed objects for each spec like this

export const schemas = {
  GET: {
    "/search/form/v1": {
      parameters: searchFormParametersSchema,
      responses: searchFormResponsesSchemas,
    },
  },
  POST: {
    "/search/form/validate-passengers/v1": {
      parameters: searchFormValidationParametersSchema,
      responses: searchFormValidationResponsesSchemas,
    },
  },
};

I would like to have associated types for these. I tried an implementation with z.infer but it's only working with strict TS and we're not here yet.

I've seen in typed-openapi that you can get types for a path like this:

Capture d’écran 2023-12-15 à 11 08 32

Is there a way to do the same with openapi-zod-client template?

FI, I can't use typed-openapi directly as I need both schemas and ts types without z.infer, and I need a template to get clean files.

Thanks a lot!

astahmer commented 8 months ago

I think you may be looking for this option ?

Screenshot 2023-12-15 at 11 47 41

otherwise, no idea I havent used this lib for a while 😅 PRs are ofc welcome if you need anything, here or in typed-api

ArthurGoupil commented 8 months ago

Yes I've tried this but types are not generated for parameters and anyway types are not manipulable as schemas are. So I guess it's not possible to generate types for an endpoint as it's done on typed-openapi. I'll have a look for a PR when I have a moment

mykeels commented 3 weeks ago

I've had some success, enhancing the default.hbs template with:

{{#if @root.options.withAlias}}
    {{#each endpoints}}
        export const {{alias}}Endpoint = {
            method: "{{method}}" as const,
            path: "{{path}}" as const,
            {{#if @root.options.withAlias}}
            {{#if alias}}
            alias: "{{alias}}" as const,
            {{/if}}
            {{/if}}
            {{#if description}}
            description: `{{description}}`,
            {{/if}}
            {{#if requestFormat}}
            requestFormat: "{{requestFormat}}" as const,
            {{/if}}
            {{#if parameters}}
            parameters: makeParameters([
                {{#each parameters}}
                {
                    name: "{{name}}" as const,
                    {{#if description}}
                    description: `{{description}}`,
                    {{/if}}
                    {{#if type}}
                    type: "{{type}}" as const,
                    {{/if}}
                    // @ts-ignore
                    schema: {{{schema}}}
                },
                {{/each}}
            ]),
            {{/if}}
            response: {{{response}}},
            {{#if errors.length}}
            errors: makeErrors([
                {{#each errors}}
                {
                    {{#ifeq status "default" }}
                    status: "default" as const,
                    {{else}}
                    status: {{status}} as const,
                    {{/ifeq}}
                    {{#if description}}
                    description: `{{description}}` as const,
                    {{/if}}
                    // @ts-ignore
                    schema: {{{schema}}}
                },
                {{/each}}
            ])
            {{/if}}
        };
        type T{{alias}}Endpoint = typeof {{alias}}Endpoint;

    {{/each}}
{{/if}}

{{#if @root.options.withAlias}}
export type TEndpoints = [
{{#each endpoints}}
    {{#if @root.options.withAlias}}
        T{{alias}}Endpoint,
    {{else}}

    {{/if}}
{{/each}}
];

export namespace types {
{{#each schemas}}
    export type {{@key}} = z.infer<typeof schemas.{{@key}}>;
{{/each}}
}

export type TNarrowEndpoints = Narrow<TEndpoints>;
{{/if}}

which exports every Endpoint config, a TEndpoints array which groups them all, and a types.* namespace that we can use to get all types.