import { array , boolean , Decoder , DecoderError , fields , fieldsAuto , number , optional , repr , ReprOptions , string , } from ".." ; function run < T > ( decoder , value , options ? ) { try { return decoder ( value ) ; } catch ( error ) { return error instanceof DecoderError ? error . format ( options ) : error instanceof Error ? error . message : `Unknown error: ${ repr ( error ) }` ; } } expect . addSnapshotSerializer ( { test : ( value ) : boolean => typeof value === "string" , print : String , } ) ; test ( "the main readme example" , ( ) => { type User = { name : string ; active : boolean ; age ? : number ; interests : Array < string > ; } ; const userDecoder = fields ( ( field ) : User => ( { name : field ( "full_name" , string ) , active : field ( "is_active" , boolean ) , age : field ( "age" , optional ( number ) ) , interests : field ( "interests" , array ( string ) ) , } ) ) ; const payload = getSomeJSON ( ) ; const user = userDecoder ( payload ) ; expect ( user ) . toStrictEqual ( { name : "John Doe" , active : true , age : 30 , interests : [ "Programming" , "Cooking" ] , } ) ; const payload2 = getSomeInvalidJSON ( ) ; expect ( run ( userDecoder , payload2 ) ) . toMatchInlineSnapshot ( `
    At root["age"] (optional):
    Expected a number
    Got: "30"
  ` ) ; } ) ; test ( "the main readme example – variant" , ( ) => { const userDecoder = fieldsAuto ( { full_name : string , is_active : boolean , age : optional ( number ) , interests : array ( string ) , } ) ; type User = ReturnType < typeof userDecoder > ; const payload = getSomeJSON ( ) ; const user = userDecoder ( payload ) ; expect ( user ) . toStrictEqual ( { full_name : "John Doe" , is_active : true , age : 30 , interests : [ "Programming" , "Cooking" ] , } ) ; const payload2 = getSomeInvalidJSON ( ) ; expect ( run ( userDecoder , payload2 ) ) . toMatchInlineSnapshot ( `
    At root["age"] (optional):
    Expected a number
    Got: "30"
  ` ) ; } ) ; function getSomeJSON ( ) { return { full_name : "John Doe" , is_active : true , age : 30 , interests : [ "Programming" , "Cooking" ] , } ; } function getSomeInvalidJSON ( ) { return { full_name : "John Doe" , is_active : true , age : "30" , interests : [ ] , } ; } test ( "default vs sensitive error messages" , ( ) => { const userDecoder = fieldsAuto ( { name : string , details : fieldsAuto ( { email : string , ssn : string , } ) , } ) ; const data = { name : "John Doe" , details : { email : "john.doe@example.com" , ssn : 123456789 , } , } ; expect ( run ( userDecoder , data ) ) . toMatchInlineSnapshot ( `
    At root["details"]["ssn"]:
    Expected a string
    Got: 123456789
  ` ) ; expect ( run ( userDecoder , data , { sensitive : true } ) ) . toMatchInlineSnapshot ( `
    At root["details"]["ssn"]:
    Expected a string
    Got: number
  ` ) ; } ) ; test ( "fields" , ( ) => { type User = { age : number ; active : boolean ; name : string ; description ? : string ; legacyId ? : number ; version : 1 ; } ; const userDecoder = fields ( ( field ) : User => ( { age : field ( "age" , number ) , active : field ( "is_active" , boolean ) , name : `${ field ( "first_name" , string ) } ${ field ( "last_name" , string ) }` , description : field ( "description" , optional ( string ) ) , legacyId : field ( "extra_data" , number , { mode : { default : undefined } } ) , version : 1 , } ) ) ; expect ( userDecoder ( { age : 30 , is_active : true , first_name : "John" , last_name : "Doe" , legacyId : "bad" , } ) ) . toStrictEqual ( { active : true , age : 30 , description : undefined , legacyId : undefined , name : "John Doe" , version : 1 , } ) ; const ageDecoder = fields ( ( field ) => field ( "age" , number ) ) ; expect ( ageDecoder ( { age : 30 } ) ) . toBe ( 30 ) ; } ) ; test ( "type annotations" , ( ) => { type Person = { name : string ; age ? : number ; } ; const personDecoder = fields ( ( field ) : Person => ( { name : field ( "name" , string ) , age : field ( "age" , optional ( number ) ) , } ) ) ; const personDecoderAuto = fieldsAuto < Person > ( { name : string , age : optional ( number ) , } ) ; const data = { name : "John" } ; expect ( personDecoder ( data ) ) . toStrictEqual ( personDecoderAuto ( data ) ) ; } ) ;