11// Zod schema based on Design Tokens Community Group specification
22// does not support JSON Pointer references
33
4- import { z } from "zod" ;
4+ import * as z from "zod/mini " ;
55
66// token and group names MUST NOT:
77// - start with '$' (reserved prefix per DTCG spec)
88// - contain '{' (used in references syntax)
99// - contain '}' (used in references syntax)
1010// - contain '.' (used in path separators within references)
11- export const nameSchema = z
12- . string ( )
13- . refine (
11+ export const nameSchema = z . string ( ) . check (
12+ z . refine (
1413 ( name ) => ! name . startsWith ( "$" ) ,
1514 "Token and group names must not start with '$'" ,
16- )
17- . refine (
15+ ) ,
16+ z . refine (
1817 ( name ) => ! name . includes ( "{" ) ,
1918 "Token and group names must not contain '{'" ,
20- )
21- . refine (
19+ ) ,
20+ z . refine (
2221 ( name ) => ! name . includes ( "}" ) ,
2322 "Token and group names must not contain '}'" ,
24- )
25- . refine (
23+ ) ,
24+ z . refine (
2625 ( name ) => ! name . includes ( "." ) ,
2726 "Token and group names must not contain '.'" ,
28- ) ;
27+ ) ,
28+ ) ;
2929
3030// references use dot-separated paths with curly braces like {colors.primary}
3131// each segment must be a valid name per nameSchema
3232// special case: $root token is allowed within references as it uses the $ prefix
33- export const referenceSchema = z
34- . string ( )
35- . refine (
33+ export const referenceSchema = z . string ( ) . check (
34+ z . refine (
3635 ( value ) => value . startsWith ( "{" ) && value . endsWith ( "}" ) ,
3736 "Reference must be enclosed in curly braces" ,
38- )
39- . refine ( ( value ) => {
37+ ) ,
38+ z . refine ( ( value ) => {
4039 const content = value . slice ( 1 , - 1 ) ;
4140 const segments = content . split ( "." ) ;
4241 return (
@@ -47,7 +46,8 @@ export const referenceSchema = z
4746 return nameSchema . safeParse ( segment ) . success ;
4847 } )
4948 ) ;
50- } , "Each segment in reference must be a valid name" ) ;
49+ } , "Each segment in reference must be a valid name" ) ,
50+ ) ;
5151
5252// Token types
5353const tokenType = z . enum ( [
@@ -90,8 +90,8 @@ const colorSpace = z.enum([
9090export const colorValue = z . object ( {
9191 colorSpace : colorSpace ,
9292 components : z . array ( colorComponent ) ,
93- alpha : z . number ( ) . optional ( ) ,
94- hex : z . string ( ) . optional ( ) ,
93+ alpha : z . optional ( z . number ( ) ) ,
94+ hex : z . optional ( z . string ( ) ) ,
9595} ) ;
9696
9797export const dimensionValue = z . object ( {
@@ -101,11 +101,11 @@ export const dimensionValue = z.object({
101101
102102export const fontFamilyValue = z . union ( [
103103 z . string ( ) ,
104- z . array ( z . string ( ) ) . min ( 1 ) ,
104+ z . array ( z . string ( ) ) . check ( z . minLength ( 1 ) ) ,
105105] ) ;
106106
107107export const fontWeightValue = z . union ( [
108- z . number ( ) . min ( 1 ) . max ( 1000 ) ,
108+ z . number ( ) . check ( z . minimum ( 1 ) , z . maximum ( 1000 ) ) ,
109109 z . enum ( [
110110 "thin" ,
111111 "hairline" ,
@@ -156,7 +156,7 @@ export const strokeStyleString = z.enum([
156156export const strokeStyleValue = z . union ( [
157157 strokeStyleString ,
158158 z . object ( {
159- dashArray : z . array ( dimensionValue ) . min ( 1 ) ,
159+ dashArray : z . array ( dimensionValue ) . check ( z . minLength ( 1 ) ) ,
160160 lineCap : z . enum ( [ "round" , "butt" , "square" ] ) ,
161161 } ) ,
162162] ) ;
@@ -181,20 +181,20 @@ const shadowObject = z.object({
181181 offsetY : z . union ( [ dimensionValue , referenceSchema ] ) ,
182182 blur : z . union ( [ dimensionValue , referenceSchema ] ) ,
183183 spread : z . union ( [ dimensionValue , referenceSchema ] ) ,
184- inset : z . boolean ( ) . optional ( ) ,
184+ inset : z . optional ( z . boolean ( ) ) ,
185185} ) ;
186186
187187export const shadowValue = z . union ( [
188188 shadowObject ,
189- z . array ( shadowObject ) . min ( 1 ) ,
189+ z . array ( shadowObject ) . check ( z . minLength ( 1 ) ) ,
190190] ) ;
191191
192192const gradientStop = z . object ( {
193193 color : z . union ( [ colorValue , referenceSchema ] ) ,
194194 position : z . number ( ) ,
195195} ) ;
196196
197- export const gradientValue = z . array ( gradientStop ) . min ( 1 ) ;
197+ export const gradientValue = z . array ( gradientStop ) . check ( z . minLength ( 1 ) ) ;
198198
199199export const typographyValue = z . object ( {
200200 fontFamily : z . union ( [ fontFamilyValue , referenceSchema ] ) ,
@@ -221,19 +221,19 @@ export const tokenSchema = z.object({
221221 typographyValue ,
222222 referenceSchema ,
223223 ] ) ,
224- $type : tokenType . optional ( ) ,
225- $description : z . string ( ) . optional ( ) ,
226- $extensions : z . record ( z . string ( ) , z . unknown ( ) ) . optional ( ) ,
227- $deprecated : z . union ( [ z . boolean ( ) , z . string ( ) ] ) . optional ( ) ,
224+ $type : z . optional ( tokenType ) ,
225+ $description : z . optional ( z . string ( ) ) ,
226+ $extensions : z . optional ( z . record ( z . string ( ) , z . unknown ( ) ) ) ,
227+ $deprecated : z . optional ( z . union ( [ z . boolean ( ) , z . string ( ) ] ) ) ,
228228} ) ;
229229
230230export const groupSchema = z . object ( {
231- $type : tokenType . optional ( ) ,
232- $description : z . string ( ) . optional ( ) ,
233- $extensions : z . record ( z . string ( ) , z . unknown ( ) ) . optional ( ) ,
234- $extends : referenceSchema . optional ( ) ,
235- $deprecated : z . union ( [ z . boolean ( ) , z . string ( ) ] ) . optional ( ) ,
236- $root : tokenSchema . optional ( ) ,
231+ $type : z . optional ( tokenType ) ,
232+ $description : z . optional ( z . string ( ) ) ,
233+ $extensions : z . optional ( z . record ( z . string ( ) , z . unknown ( ) ) ) ,
234+ $extends : z . optional ( referenceSchema ) ,
235+ $deprecated : z . optional ( z . union ( [ z . boolean ( ) , z . string ( ) ] ) ) ,
236+ $root : z . optional ( tokenSchema ) ,
237237} ) ;
238238
239239export type Token = z . infer < typeof tokenSchema > ;
@@ -262,7 +262,7 @@ export const resolverSourceSchema = z.record(
262262 z . string ( ) ,
263263 // avoid checking to not cut of nested groups and tokens
264264 // but enforce as a type
265- z . unknown ( ) as z . ZodType < Token | Group > ,
265+ z . unknown ( ) as z . ZodMiniType < Token | Group > ,
266266) ;
267267
268268export type ResolverSource = z . infer < typeof resolverSourceSchema > ;
@@ -272,8 +272,8 @@ export const resolverSetSchema = z.object({
272272 type : z . literal ( "set" ) ,
273273 name : nameSchema , // required, unique identifier within resolutionOrder
274274 sources : z . array ( resolverSourceSchema ) , // non-optional, can be empty
275- description : z . string ( ) . optional ( ) ,
276- $extensions : z . record ( z . string ( ) , z . unknown ( ) ) . optional ( ) ,
275+ description : z . optional ( z . string ( ) ) ,
276+ $extensions : z . optional ( z . record ( z . string ( ) , z . unknown ( ) ) ) ,
277277} ) ;
278278
279279export type ResolverSet = z . infer < typeof resolverSetSchema > ;
@@ -289,9 +289,9 @@ export const resolverModifierSchema = z.object({
289289 type : z . literal ( "modifier" ) ,
290290 name : nameSchema , // required, unique identifier within resolutionOrder
291291 contexts : resolverModifierContextsSchema , // non-optional
292- description : z . string ( ) . optional ( ) ,
293- default : z . string ( ) . optional ( ) ,
294- $extensions : z . record ( z . string ( ) , z . unknown ( ) ) . optional ( ) ,
292+ description : z . optional ( z . string ( ) ) ,
293+ default : z . optional ( z . string ( ) ) ,
294+ $extensions : z . optional ( z . record ( z . string ( ) , z . unknown ( ) ) ) ,
295295} ) ;
296296
297297export type ResolverModifier = z . infer < typeof resolverModifierSchema > ;
@@ -306,16 +306,16 @@ export type ResolutionOrderItem = z.infer<typeof resolutionOrderItemSchema>;
306306
307307// Unsupported root-level sets and modifiers
308308// These reject any object with properties - only allow undefined or empty object
309- const unsupportedSetsSchema = z . object ( { } ) . strict ( ) . optional ( ) ;
310- const unsupportedModifiersSchema = z . object ( { } ) . strict ( ) . optional ( ) ;
309+ const unsupportedSetsSchema = z . optional ( z . strictObject ( { } ) ) ;
310+ const unsupportedModifiersSchema = z . optional ( z . strictObject ( { } ) ) ;
311311
312312// Resolver document following Design Tokens Resolver Module 2025.10
313313export const resolverDocumentSchema = z . object ( {
314314 version : z . literal ( "2025.10" ) ,
315- name : z . string ( ) . optional ( ) ,
316- description : z . string ( ) . optional ( ) ,
317- sets : unsupportedSetsSchema . optional ( ) ,
318- modifiers : unsupportedModifiersSchema . optional ( ) ,
315+ name : z . optional ( z . string ( ) ) ,
316+ description : z . optional ( z . string ( ) ) ,
317+ sets : z . optional ( unsupportedSetsSchema ) ,
318+ modifiers : z . optional ( unsupportedModifiersSchema ) ,
319319 resolutionOrder : z . array ( resolutionOrderItemSchema ) ,
320320} ) ;
321321
0 commit comments