Repository: RobinTail/express-zod-api
Pull request #887 (2023-03-16 21:57:09)

Fix example implementation for the client in case of delete method.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3ca9f6a3..03fa3265 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,12 @@
 
 ## Version 9
 
+### v9.4.1
+
+- Fixing the example implementation for the generated client in case of `DELETE` method.
+  - Since v9.0.0-beta1 request `body` is no longer accepted (by default) as an input source.
+  - The example implementation is now aligned accordingly to use query parameters.
+
 ### v9.4.0
 
 - Feature #875, proposed by [@VideoSystemsTech](https://github.com/VideoSystemsTech).
diff --git a/README.md b/README.md
index 7ada8ebb..738680f3 100644
--- a/README.md
+++ b/README.md
@@ -811,13 +811,12 @@ fs.writeFileSync("./frontend/client.ts", new Client(routing).print(), "utf-8");
 import { ExpressZodAPIClient } from "./client.ts";
 
 const client = new ExpressZodAPIClient(async (method, path, params) => {
-  const searchParams =
-    method === "get" ? `?${new URLSearchParams(params)}` : "";
+  const hasBody = !["get", "delete"].includes(method);
+  const searchParams = hasBody ? "" : `?${new URLSearchParams(params)}`;
   const response = await fetch(`https://example.com${path}${searchParams}`, {
     method: method.toUpperCase(),
-    headers:
-      method === "get" ? undefined : { "Content-Type": "application/json" },
-    body: method === "get" ? undefined : JSON.stringify(params),
+    headers: hasBody ? { "Content-Type": "application/json" } : undefined,
+    body: hasBody ? JSON.stringify(params) : undefined,
   });
   return response.json();
 });
diff --git a/example/example.client.ts b/example/example.client.ts
index 53cc7bc8..5c2f3fd6 100644
--- a/example/example.client.ts
+++ b/example/example.client.ts
@@ -130,13 +130,12 @@ export const exampleImplementation: Implementation = async (
   path,
   params
 ) => {
-  const searchParams =
-    method === "get" ? `?${new URLSearchParams(params)}` : "";
+  const hasBody = !["get", "delete"].includes(method);
+  const searchParams = hasBody ? "" : `?${new URLSearchParams(params)}`;
   const response = await fetch(`https://example.com${path}${searchParams}`, {
     method: method.toUpperCase(),
-    headers:
-      method === "get" ? undefined : { "Content-Type": "application/json" },
-    body: method === "get" ? undefined : JSON.stringify(params),
+    headers: hasBody ? { "Content-Type": "application/json" } : undefined,
+    body: hasBody ? JSON.stringify(params) : undefined,
   });
   if (`${method} ${path}` in jsonEndpoints) {
     return response.json();
diff --git a/src/client.ts b/src/client.ts
index e7e41c23..d924605b 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -238,13 +238,12 @@ export class Client {
         "  path,\n" +
         "  params\n" +
         ") => {\n" +
-        "  const searchParams =\n" +
-        '    method === "get" ? `?${new URLSearchParams(params)}` : "";\n' +
+        '  const hasBody = !["get", "delete"].includes(method);\n' +
+        '  const searchParams = hasBody ? "" : `?${new URLSearchParams(params)}`;\n' +
         "  const response = await fetch(`https://example.com${path}${searchParams}`, {\n" +
         "    method: method.toUpperCase(),\n" +
-        "    headers:\n" +
-        '      method === "get" ? undefined : { "Content-Type": "application/json" },\n' +
-        '    body: method === "get" ? undefined : JSON.stringify(params),\n' +
+        '    headers: hasBody ? { "Content-Type": "application/json" } : undefined,\n' +
+        "    body: hasBody ? JSON.stringify(params) : undefined,\n" +
         "  });\n" +
         "  if (`${method} ${path}` in jsonEndpoints) {\n" +
         "    return response.json();\n" +


Test patch:
diff --git a/tests/unit/__snapshots__/client.spec.ts.snap b/tests/unit/__snapshots__/client.spec.ts.snap
index e4427179..e6eff780 100644
--- a/tests/unit/__snapshots__/client.spec.ts.snap
+++ b/tests/unit/__snapshots__/client.spec.ts.snap
@@ -110,13 +110,12 @@ export const exampleImplementation: Implementation = async (
   path,
   params
 ) => {
-  const searchParams =
-    method === "get" ? \`?\${new URLSearchParams(params)}\` : "";
+  const hasBody = !["get", "delete"].includes(method);
+  const searchParams = hasBody ? "" : \`?\${new URLSearchParams(params)}\`;
   const response = await fetch(\`https://example.com\${path}\${searchParams}\`, {
     method: method.toUpperCase(),
-    headers:
-      method === "get" ? undefined : { "Content-Type": "application/json" },
-    body: method === "get" ? undefined : JSON.stringify(params),
+    headers: hasBody ? { "Content-Type": "application/json" } : undefined,
+    body: hasBody ? JSON.stringify(params) : undefined,
   });
   if (\`\${method} \${path}\` in jsonEndpoints) {
     return response.json();
@@ -176,13 +175,12 @@ export const exampleImplementation: Implementation = async (
   path,
   params
 ) => {
-  const searchParams =
-    method === "get" ? \`?\${new URLSearchParams(params)}\` : "";
+  const hasBody = !["get", "delete"].includes(method);
+  const searchParams = hasBody ? "" : \`?\${new URLSearchParams(params)}\`;
   const response = await fetch(\`https://example.com\${path}\${searchParams}\`, {
     method: method.toUpperCase(),
-    headers:
-      method === "get" ? undefined : { "Content-Type": "application/json" },
-    body: method === "get" ? undefined : JSON.stringify(params),
+    headers: hasBody ? { "Content-Type": "application/json" } : undefined,
+    body: hasBody ? JSON.stringify(params) : undefined,
   });
   if (\`\${method} \${path}\` in jsonEndpoints) {
     return response.json();