openapi-zod-client
openapi-zod-client copied to clipboard
Regular expression string pattern in OAS yield uncompilable typescript due to unnecessary escaping
Minimal spec with a regex that has an escape character:
openapi: 3.0.0
info:
version: 1.0.0
title: API for Regex Test
paths:
/test:
get:
responses:
'200':
description: A test endpoint
content:
application/json:
schema:
type: object
properties:
regexmatch:
type: string
pattern: .+\/.+
Output:
import { makeApi, Zodios, type ZodiosOptions } from "@zodios/core";
import { z } from "zod";
const endpoints = makeApi([
{
method: "get",
path: "/test",
alias: "getTest",
requestFormat: "json",
response: z.object({ regexmatch: z.string().regex(/.+\\/.+/) }).partial().passthrough(),
},
]);
export const api = new Zodios(endpoints);
export function createApiClient(baseUrl: string, options?: ZodiosOptions) {
return new Zodios(baseUrl, endpoints, options);
}
This does not compile. Compile errors:
tsc
src/minimalout.ts:15:60 - error TS1003: Identifier expected.
15 response: z.object({ regexmatch: z.string().regex(/.+\\/.+/) }).partial().passthrough(),
~
src/minimalout.ts:15:62 - error TS1161: Unterminated regular expression literal.
15 response: z.object({ regexmatch: z.string().regex(/.+\\/.+/) }).partial().passthrough(),
src/minimalout.ts:16:2 - error TS1005: ',' expected.
16 },
~
src/minimalout.ts:17:1 - error TS1135: Argument expression expected.
17 ]);
~
Found 4 errors in the same file, starting at: src/minimalout.ts:15
error Command failed with exit code 2.
Probably the right output for the regexmatch would be:
z.string().regex(/.+\/.+/)
Here is a pull request containing a failing test showing this behavior: https://github.com/astahmer/openapi-zod-client/pull/197
good catch ! if you do want to fix that, please add a changeset 🙏
I haven't used changeset before, but I attempted to do that.
I see that you merged https://github.com/astahmer/openapi-zod-client/pull/197. I'm interested in trying it out, but it looks like there was not a new patch version published. Was that intentional?
yes, a release only happens when merging the PR that the changeset CLI creates
this one for example https://github.com/astahmer/openapi-zod-client/pull/200
you can still try the PR by going on the branch, i'll wait for your confirmation before merging the release PR
@astahmer it looks like you merged the PRs without my confirmation.
There are some more regular expressions I want to make sure work, for example /\d, the regular expression matching / and then a single digit character. Here is the latest version producing uncompilable typescript on that in the playground.
I think there should be a handful of tests containing regular expressions both escaping and not escaping different slashes and using character groups etc. I also think part of the test condition should be making sure the resultant code compiles.
my bad, shouldnt have merged this PR initially. I had to merge cause it was blocking the main changeset PR in the meantime*
thought you were done after this message but I misnterpreted:
I haven't used changeset before, but I attempted to do that.
I haven't had time to go back to this, but I'm confident that there is still a bug in the current version around this behavior.
With the current version (1.11.1), this particular pattern in the spec is incorrectly generated (the escapes are not added to the generated code):
Pattern in spec: ^(https:\/\/)([^\/]+)\/([^\/]+)\/([^\/]+).pdf$
Pattern in generated code: /^(https://)([^/]+)/([^/]+)/([^/]+).pdf$/
@astahmer would you be able to fix this bug with regular expression translation?
@astahmer I spent a good amount of time trying to understand what's going on and in the end I corrected the test and reverted the change you merged: https://github.com/astahmer/openapi-zod-client/pull/288
I think this PR is a better outcome for most user situations and in the description and in-line comments I describe what's going on and what happened. String escaping is tedious to think about carefully!