Repository: fabien0102/ts-to-zod
Pull request #260 (2024-08-07 06:07:33)

feat: add support for date, time and duration `@format` types
As discussed in #144  the recent [Zod release v3.23](https://github.com/colinhacks/zod/releases/tag/v3.23.0) added support for `date`, `time` and `duration` string `@format` types and they are mentioned in [OpenAPI Formats Registry](https://spec.openapis.org/registry/format/) so we can now add support for them.


Patch:
diff --git a/README.md b/README.md
index 85f88dd..5f0c69c 100644
--- a/README.md
+++ b/README.md
@@ -44,17 +44,20 @@ List of supported keywords:
 | `@format {FormatType} [err_msg]`                                                                                           | `@format email`            | `z.string().email()`                 |
 | `@pattern {regex}` <br><br> **Note**: Due to parsing ambiguities, `@pattern` does _not_ support generating error messages. | `@pattern ^hello`          | `z.string().regex(/^hello/)`         |
 
-By default, `FormatType` is defined as:
+By default, `FormatType` is defined as the following type (corresponding Zod validator in comment):
 
 ```ts
 type FormatType =
-  | "date-time"
-  | "email"
-  | "ip"
-  | "ipv4"
-  | "ipv6"
-  | "url"
-  | "uuid";
+  | "date-time" // z.string().datetime()
+  | "date"      // z.string().date()
+  | "time"      // z.string().time()
+  | "duration"  // z.string().duration()
+  | "email"     // z.string().email()
+  | "ip"        // z.string().ip()
+  | "ipv4"      // z.string().ip()
+  | "ipv6"      // z.string().ip()
+  | "url"       // z.string().url()
+  | "uuid";     // z.string().uuid()
 ```
 
 However, see the section on [Custom JSDoc Format Types](#custom-jsdoc-format-types) to learn more about defining other types of formats for string validation.
diff --git a/package.json b/package.json
index 583891d..449357d 100644
--- a/package.json
+++ b/package.json
@@ -53,7 +53,7 @@
     "tslib": "^2.3.1",
     "tsutils": "^3.21.0",
     "typescript": "^5.2.2",
-    "zod": "^3.22.4"
+    "zod": "^3.23.8"
   },
   "devDependencies": {
     "@babel/core": "^7.23.2",
diff --git a/src/core/jsDocTags.ts b/src/core/jsDocTags.ts
index a69cda4..d42f014 100644
--- a/src/core/jsDocTags.ts
+++ b/src/core/jsDocTags.ts
@@ -8,6 +8,9 @@ import { CustomJSDocFormatType, CustomJSDocFormatTypes } from "../config";
  */
 const builtInJSDocFormatsTypes = [
   "date-time",
+  "date",
+  "time",
+  "duration",
   "email",
   "ip",
   "ipv4",
@@ -15,7 +18,6 @@ const builtInJSDocFormatsTypes = [
   "url",
   "uuid",
   // "uri",
-  // "date",
 ] as const;
 
 type BuiltInJSDocFormatsType = (typeof builtInJSDocFormatsTypes)[number];
diff --git a/yarn.lock b/yarn.lock
index 150e90b..8865d3c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5337,7 +5337,7 @@ yocto-queue@^0.1.0:
   resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
   integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
 
-zod@^3.22.4:
-  version "3.22.4"
-  resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff"
-  integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==
+zod@^3.23.8:
+  version "3.23.8"
+  resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d"
+  integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==


Test patch:
diff --git a/src/core/generateZodSchema.test.ts b/src/core/generateZodSchema.test.ts
index 4a952f0..1c779d4 100644
--- a/src/core/generateZodSchema.test.ts
+++ b/src/core/generateZodSchema.test.ts
@@ -772,12 +772,33 @@ describe("generateZodSchema", () => {
       age: number;
 
       /**
-       * The hero's birthday.
+       * Hero last seen.
        *
        * @format date-time
        */
+      lastSeen: string;
+
+      /**
+       * The hero's birthday.
+       *
+       * @format date
+       */
       birthday: string;
 
+      /**
+       * The hero's wakeup-time.
+       *
+       * @format time
+       */
+      wakeupTime: string;
+
+      /**
+       * The hero's super power boost duration.
+       *
+       * @format duration
+       */
+      boost: string;
+
       /**
        * The hero's ipv4 address.
        *
@@ -868,11 +889,29 @@ describe("generateZodSchema", () => {
            */
           age: z.number().min(0).max(500),
           /**
-           * The hero's birthday.
+           * Hero last seen.
            *
            * @format date-time
            */
-          birthday: z.string().datetime(),
+          lastSeen: z.string().datetime(),
+          /**
+           * The hero's birthday.
+           *
+           * @format date
+           */
+          birthday: z.string().date(),
+          /**
+           * The hero's wakeup-time.
+           *
+           * @format time
+           */
+          wakeupTime: z.string().time(),
+          /**
+           * The hero's super power boost duration.
+           *
+           * @format duration
+           */
+          boost: z.string().duration(),
           /**
            * The hero's ipv4 address.
            *