Skip to content

Commit 7876d0b

Browse files
committed
fix(typescript-zod): validate date and time formats
1 parent b46e83d commit 7876d0b

7 files changed

Lines changed: 42 additions & 1 deletion

File tree

‎packages/quicktype-core/src/language/TypeScriptZod/TypeScriptZodRenderer.ts‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,17 @@ export class TypeScriptZodRenderer extends ConvenienceRenderer {
200200
return ["z.union([", ...arrayIntercalate(", ", children), "])"];
201201
},
202202
(_transformedStringType) => {
203+
if (_transformedStringType.kind === "date") {
204+
return `z.string().regex(/^\\d{4}-(?:0[1-9]|1[0-2])-(?:[0-2]\\d|3[01])$/).refine(value => {
205+
const parsed = Date.parse(`${value}T00:00:00Z`);
206+
return Number.isFinite(parsed) && new Date(parsed).toISOString().slice(0, 10) === value;
207+
})`;
208+
}
209+
if (_transformedStringType.kind === "time") {
210+
return "z.string().regex(/^(?:[01]\\d|2[0-3]):[0-5]\\d:(?:[0-5]\\d|60)(?:\\.\\d+)?(?:Z|[+-](?:[01]\\d|2[0-3]):[0-5]\\d)$/i)";
211+
}
203212
if (_transformedStringType.kind === "date-time") {
204-
return "z.string().pipe(z.coerce.date())";
213+
return "z.string().refine(value => z.string().datetime({ offset: true }).safeParse(value.toUpperCase()).success).pipe(z.coerce.date())";
205214
}
206215
if (_transformedStringType.kind === "uuid") {
207216
return "z.string().uuid()";

‎packages/quicktype-core/src/language/TypeScriptZod/language.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ export class TypeScriptZodTargetLanguage extends TargetLanguage<
4343
const mapping: Map<TransformedStringTypeKind, PrimitiveStringTypeKind> =
4444
new Map();
4545
const dateTimeType = "date-time";
46+
mapping.set("date", "date");
47+
mapping.set("time", "time");
4648
mapping.set("date-time", dateTimeType);
4749
mapping.set("uuid", "uuid");
4850
mapping.set("bool-string", "bool-string");
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"date": "2023-02-29",
3+
"time": "23:20:50.52Z",
4+
"date-time": "2018-08-13T21:31:01+01:00",
5+
"union-array": ["1985-04-12", "23:20:50.52Z"],
6+
"complex-union-array": ["2018-08-13T21:31:01+00:10", "foo", 123]
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"date": "1985-04-12",
3+
"time": "29:99:99Z",
4+
"date-time": "2018-08-13T21:31:01+01:00",
5+
"union-array": ["1985-04-12", "23:20:50.52Z"],
6+
"complex-union-array": ["2018-08-13T21:31:01+00:10", "foo", 123]
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"date": "2024-02-29",
3+
"time": "23:59:59.999z",
4+
"date-time": "2024-02-29t00:00:00z",
5+
"union-array": ["2024-02-29", "00:00:00Z"],
6+
"complex-union-array": ["2024-02-29T23:59:59.999Z", "bar", -1]
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"date": "1985-04-12",
3+
"time": "23:20:50.52Z",
4+
"date-time": "1",
5+
"union-array": ["1985-04-12", "23:20:50.52Z"],
6+
"complex-union-array": ["2018-08-13T21:31:01+00:10", "foo", 123]
7+
}

‎test/languages.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,6 +1736,8 @@ export const TypeScriptZodLanguage: Language = {
17361736
"union",
17371737
"no-defaults",
17381738
"date-time",
1739+
"date",
1740+
"time",
17391741
"uuid",
17401742
"bool-string",
17411743
"integer-string",

0 commit comments

Comments
 (0)