Skip to content

Commit 9df0123

Browse files
authored
Merge pull request #542 from traversable/zod-to-string-discriminated-union-bug
fix(zod,zod-types): fixes `zx.toString` bug with `z.default` objects containing an unmatched bracket
2 parents 8909b55 + 5b36349 commit 9df0123

File tree

4 files changed

+335
-116
lines changed

4 files changed

+335
-116
lines changed

.changeset/large-wolves-lay.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@traversable/zod-types": patch
3+
"@traversable/zod": patch
4+
---
5+
6+
fix(zod,zod-types): fixes `zx.toString` bug where objects with 1+ props passed to `z.default` included an unmatched closing bracket

packages/zod-types/src/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ export function serializeShort(json: unknown): string {
155155
case Array_isArray(x): return x.length === 0 ? '[]' : '[' + x.join(', ') + ']'
156156
case !!x && typeof x === 'object': {
157157
const xs = Object.entries(x)
158-
return xs.length === 0 ? '{}' : '{' + xs.map(([k, v]) => parseKey(k) + ': ' + v).join(',') + '}]'
158+
return xs.length === 0 ? '{}' : '{' + xs.map(([k, v]) => parseKey(k) + ': ' + v).join(',') + '}'
159159
}
160160
}
161161
})(json as Json.Unary<string>)

packages/zod/src/to-string.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { z } from 'zod'
22
import type { Showable } from '@traversable/registry'
3-
import { has, Number_isNatural, Object_entries, parseKey } from '@traversable/registry'
3+
import { has, Number_isNatural, Object_entries, parseKey, escape } from '@traversable/registry'
44
import type { Options as v4_Options } from '@traversable/zod-types'
5-
import { defaults as v4_defaults, tagged, serializeShort, Ctx, F, Z, Warn } from '@traversable/zod-types'
5+
import { defaults as v4_defaults, tagged, serializeShort, Ctx, F, Z } from '@traversable/zod-types'
66

77
export interface Options extends v4_Options {}
88
export interface Config extends Required<Options> {}
@@ -140,7 +140,9 @@ export function toString(schema: z.ZodType | z.core.$ZodType, options?: toString
140140
case tagged('array')(x): return `${z}.array(${x._zod.def.element})${applyArrayConstraints(x)}`
141141
case tagged('record')(x): return `${z}.record(${x._zod.def.keyType}, ${x._zod.def.valueType})`
142142
case tagged('intersection')(x): return `${z}.intersection(${x._zod.def.left}, ${x._zod.def.right})`
143-
case tagged('union')(x): return `${z}.union([${x._zod.def.options.join(',')}])`
143+
case tagged('union')(x): return x._zod.def.discriminator === undefined
144+
? `${z}.union([${x._zod.def.options.join(',')}])`
145+
: `${z}.discriminatedUnion(["${escape(x._zod.def.discriminator)}", ${x._zod.def.options.join(',')}])`
144146
case tagged('lazy')(x): return `${z}.lazy(() => ${x._zod.def.getter()})`
145147
case tagged('pipe')(x): return `${x._zod.def.in}.pipe(${x._zod.def.out})`
146148
case tagged('default')(x): return `${x._zod.def.innerType}.default(${serializeShort(x._zod.def.defaultValue!)})`

0 commit comments

Comments
 (0)