@@ -537,7 +537,8 @@ export type ZodStringCheck =
537537 precision : number | null ;
538538 message ?: string ;
539539 }
540- | { kind : "ip" ; version ?: IpVersion ; message ?: string } ;
540+ | { kind : "ip" ; version ?: IpVersion ; message ?: string }
541+ | { kind : "base64" ; message ?: string } ;
541542
542543export interface ZodStringDef extends ZodTypeDef {
543544 checks : ZodStringCheck [ ] ;
@@ -579,6 +580,10 @@ const ipv4Regex =
579580const ipv6Regex =
580581 / ^ ( ( [ a - f 0 - 9 ] { 1 , 4 } : ) { 7 } | : : ( [ a - f 0 - 9 ] { 1 , 4 } : ) { 0 , 6 } | ( [ a - f 0 - 9 ] { 1 , 4 } : ) { 1 } : ( [ a - f 0 - 9 ] { 1 , 4 } : ) { 0 , 5 } | ( [ a - f 0 - 9 ] { 1 , 4 } : ) { 2 } : ( [ a - f 0 - 9 ] { 1 , 4 } : ) { 0 , 4 } | ( [ a - f 0 - 9 ] { 1 , 4 } : ) { 3 } : ( [ a - f 0 - 9 ] { 1 , 4 } : ) { 0 , 3 } | ( [ a - f 0 - 9 ] { 1 , 4 } : ) { 4 } : ( [ a - f 0 - 9 ] { 1 , 4 } : ) { 0 , 2 } | ( [ a - f 0 - 9 ] { 1 , 4 } : ) { 5 } : ( [ a - f 0 - 9 ] { 1 , 4 } : ) { 0 , 1 } ) ( [ a - f 0 - 9 ] { 1 , 4 } | ( ( ( 2 5 [ 0 - 5 ] ) | ( 2 [ 0 - 4 ] [ 0 - 9 ] ) | ( 1 [ 0 - 9 ] { 2 } ) | ( [ 0 - 9 ] { 1 , 2 } ) ) \. ) { 3 } ( ( 2 5 [ 0 - 5 ] ) | ( 2 [ 0 - 4 ] [ 0 - 9 ] ) | ( 1 [ 0 - 9 ] { 2 } ) | ( [ 0 - 9 ] { 1 , 2 } ) ) ) $ / ;
581582
583+ // https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript
584+ const base64Regex =
585+ / ^ ( [ 0 - 9 a - z A - Z + / ] { 4 } ) * ( ( [ 0 - 9 a - z A - Z + / ] { 2 } = = ) | ( [ 0 - 9 a - z A - Z + / ] { 3 } = ) ) ? $ / ;
586+
582587// Adapted from https://stackoverflow.com/a/3143231
583588const datetimeRegex = ( args : { precision : number | null ; offset : boolean } ) => {
584589 if ( args . precision ) {
@@ -845,6 +850,16 @@ export class ZodString extends ZodType<string, ZodStringDef> {
845850 } ) ;
846851 status . dirty ( ) ;
847852 }
853+ } else if ( check . kind === "base64" ) {
854+ if ( ! base64Regex . test ( input . data ) ) {
855+ ctx = this . _getOrReturnCtx ( input , ctx ) ;
856+ addIssueToContext ( ctx , {
857+ validation : "base64" ,
858+ code : ZodIssueCode . invalid_string ,
859+ message : check . message ,
860+ } ) ;
861+ status . dirty ( ) ;
862+ }
848863 } else {
849864 util . assertNever ( check ) ;
850865 }
@@ -893,6 +908,9 @@ export class ZodString extends ZodType<string, ZodStringDef> {
893908 ulid ( message ?: errorUtil . ErrMessage ) {
894909 return this . _addCheck ( { kind : "ulid" , ...errorUtil . errToObj ( message ) } ) ;
895910 }
911+ base64 ( message ?: errorUtil . ErrMessage ) {
912+ return this . _addCheck ( { kind : "base64" , ...errorUtil . errToObj ( message ) } ) ;
913+ }
896914
897915 ip ( options ?: string | { version ?: "v4" | "v6" ; message ?: string } ) {
898916 return this . _addCheck ( { kind : "ip" , ...errorUtil . errToObj ( options ) } ) ;
@@ -1038,6 +1056,9 @@ export class ZodString extends ZodType<string, ZodStringDef> {
10381056 get isIP ( ) {
10391057 return ! ! this . _def . checks . find ( ( ch ) => ch . kind === "ip" ) ;
10401058 }
1059+ get isBase64 ( ) {
1060+ return ! ! this . _def . checks . find ( ( ch ) => ch . kind === "base64" ) ;
1061+ }
10411062
10421063 get minLength ( ) {
10431064 let min : number | null = null ;
0 commit comments