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

Correct escaping of forward slash in pattern regex, deprioritizing escaping of unnecessarily escaped forward slash in pattern regex #288

Closed mjperrone closed 4 months ago

mjperrone commented 4 months ago

Fixing the test definition

First I fix the issue with the test I initially added here.

The core issue was not acknowledging that the test strings are written in javascript which has its own escaping rules, so the string that was being provided and tested for was wrong. I'll put details in-line in the PR

Fixing the implementation

For the case that my PR broke (/ needs to end up as /\//), it's easy to understand what to do I add back the .replace(/\//g, "\\/") to transform / to \/ (to prepare the pattern for being defined in code with a regex string (/<regex in here>/). That's easy to understand when you look at the test case description I put in the PR.

What was happening in my initial bug report?

In this bug report I indicated that the pattern .+\/.+ produced /.+\\/.+/ output code, which is invalid because the / in the middle of the regex is not escaped.

To simplify further the pattern \/ yields the code /\\//.

What does \/ in an initial pattern mean? It means the character /, written with an unnecessary escape character.

Should openapi-zod-client support transforming regexes that have unnecessary escape characters?

OpenAPI Spec points to JSON Schema spec, which points to ECMA-262, which is a little too dense for me to quickly get to a definitive answer.

In Javascript, it's totally fine to have an unnecessary escape character when defining regular expressions:

const re = new RegExp("\\/");
re.test("/")
true

const re = new RegExp("/");
re.test("/")
true

So I'm inclined to think that openapi-zod-client should support this.

how to support it?

To address the case where the user gives a pattern with an unnecessary escape character like /\, what is the right output code?

probably /\//

However that means the existing replace .replace(/\//g, "\\/"); ( / -> \/) would get in the way of this solution.

Another option could be to replace \/ with / first. That way \/ -> / -> \/ in the final output. That works, but would break the situation where the user specifies an escaped backslash followed by an unescaped forward slash like \\/. That would go \\/ -> \/ -> \\/ when we'd want to end up with \\\/.

I'm not sure a better way to address this situation. I'm publishing this PR as is because I think it's more important to address the case where \ is specified without an unnecessary escape character.

vercel[bot] commented 4 months ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
openapi-zod-client-rim4 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 17, 2024 4:37pm
astahmer commented 4 months ago

nice ! can you add a changeset so I can merge it ?

mjperrone commented 4 months ago

nice ! can you add a changeset so I can merge it ?

I added a changeset and a test showing the remaining issue.

I marked the changeset patch but arguable this change (and the one in the previous PR) are breaking changes in that they change the output code without users changing their OpenAPI specs. I will leave you the decision of which semver bump to use.

mjperrone commented 4 months ago

Thanks! Looks like this still needs to be merged to get the release out: https://github.com/astahmer/openapi-zod-client/pull/289