@@ -1939,6 +1939,7 @@ let setHas = (has, tag: tag) => {
19391939let jsonName = ` JSON`
19401940
19411941let jsonString = shaken ("jsonString" )
1942+ let json = shaken ("json" )
19421943
19431944module Literal = {
19441945 let literalDecoder = Builder .make ((b , ~input , ~selfSchema , ~path ) => {
@@ -2064,10 +2065,6 @@ let rec parse = (prevB: b, ~schema, ~input as inputArg: val, ~path, ~reuseScope=
20642065 | Some (to ) =>
20652066 switch schema {
20662067 | {parser } => input := parser (b , ~input = input .contents , ~selfSchema = schema , ~path )
2067- // FIXME: Run encoder on the input.schema instead of the schema
2068- // eg for the case when jsonString returns an input with JSON schema
2069- // | {encoder} if input.contents.schema === schema =>
2070- // input := encoder(b, ~input=input.contents, ~selfSchema=schema, ~path)
20712068 | _ => ()
20722069 }
20732070
@@ -2091,7 +2088,7 @@ and isAsyncInternal = (schema, ~defs) => {
20912088 var : B ._var ,
20922089 flag : ValFlag .none ,
20932090 inline : Builder .intitialInputVar ,
2094- schema : unknown , // FIXME:
2091+ schema : unknown ,
20952092 }
20962093 let output = parse (b , ~schema , ~input , ~path = Path .empty )
20972094 let isAsync = output .flag -> Flag .has (ValFlag .async )
@@ -2107,30 +2104,10 @@ and isAsyncInternal = (schema, ~defs) => {
21072104and internalCompile = (~schema , ~flag , ~defs ) => {
21082105 let b = B .rootScope (~flag , ~defs )
21092106
2110- if flag -> Flag .unsafeHas (Flag .jsonableOutput ) {
2111- let output = schema -> reverse
2112- jsonableValidation (~output , ~parent = output , ~path = Path .empty , ~flag )
2113- }
2114-
2115- let input = {
2116- b ,
2117- var : B ._var ,
2118- inline : Builder .intitialInputVar ,
2119- flag : ValFlag .none ,
2120- schema : if (
2121- flag -> Flag .unsafeHas (Flag .typeValidation ) || schema .tag === unionTag || schema -> isLiteral
2122- ) {
2123- unknown
2124- } else {
2125- schema
2126- },
2127- }
2128-
21292107 let schema = if flag -> Flag .unsafeHas (Flag .assertOutput ) {
21302108 schema
21312109 -> updateOutput (mut => {
2132- let t = base (unit .tag )
2133- t .const = unit .const
2110+ let t = unit -> copySchema
21342111 t .noValidation = Some (true )
21352112 mut .to = Some (t )
21362113 })
@@ -2141,10 +2118,30 @@ and internalCompile = (~schema, ~flag, ~defs) => {
21412118 mut .to = Some (jsonString )
21422119 })
21432120 -> castToInternal
2121+ } else if flag -> Flag .unsafeHas (Flag .jsonableOutput ) {
2122+ schema
2123+ -> updateOutput (mut => {
2124+ mut .to = Some (json )
2125+ })
2126+ -> castToInternal
21442127 } else {
21452128 schema
21462129 }
21472130
2131+ let input = {
2132+ b ,
2133+ var : B ._var ,
2134+ inline : Builder .intitialInputVar ,
2135+ flag : ValFlag .none ,
2136+ schema : if (
2137+ flag -> Flag .unsafeHas (Flag .typeValidation ) || schema .tag === unionTag || schema -> isLiteral
2138+ ) {
2139+ unknown
2140+ } else {
2141+ schema
2142+ },
2143+ }
2144+
21482145 let output = parse (b , ~schema , ~input , ~path = Path .empty )
21492146
21502147 let code = b -> B .allocateScope (~input )
@@ -2473,8 +2470,13 @@ let objectDecoder = Builder.make((b, ~input, ~selfSchema, ~path) => {
24732470 }
24742471 }
24752472
2476- // FIXME: Run only for unknown input
2477- if selfSchema .additionalItems === Some (Strict ) {
2473+ if (
2474+ selfSchema .additionalItems === Some (Strict ) &&
2475+ switch input .schema .additionalItems -> X .Option .getUnsafe {
2476+ | Schema (_ ) => true
2477+ | _ => false
2478+ }
2479+ ) {
24782480 let key = b -> B .allocateVal (~schema = unknown )
24792481 let keyVar = key .inline
24802482 b .code = b .code ++ ` for(${keyVar} in ${b-> B.Val.var(input)}){if(`
@@ -4034,8 +4036,6 @@ module String = {
40344036 let datetimeRe = /^ \d {4 }- \d {2 }- \d {2 }T \d {2 }:\d {2 }:\d {2 }(\.\d + )?Z $/
40354037}
40364038
4037- let json = shaken ("json" )
4038-
40394039let jsonEncoder = Builder .make ((b , ~input , ~selfSchema as to , ~path ) => {
40404040 let toTagFlag = to .tag -> TagFlag .get
40414041
@@ -4105,6 +4105,25 @@ let jsonDecoder = Builder.make((b, ~input, ~selfSchema, ~path) => {
41054105 },
41064106 )
41074107 Array .arrayDecoder (b , ~input , ~selfSchema = mut , ~path )
4108+ } else if inputTagFlag -> Flag .unsafeHas (TagFlag .object ) {
4109+ let mut = base (objectTag )
4110+ let properties = Js .Dict .empty ()
4111+ mut .items = Some (
4112+ input .schema .items
4113+ -> X .Option .getUnsafe
4114+ -> Js .Array2 .map (item => {
4115+ properties -> Js .Dict .set (item .location , json )
4116+ {... item , schema : json -> castToPublic }
4117+ }),
4118+ )
4119+ mut .properties = Some (properties )
4120+ mut .additionalItems = Some (
4121+ switch input .schema .additionalItems -> X .Option .getUnsafe {
4122+ | Schema (_ ) => Schema (json -> castToPublic )
4123+ | v => v
4124+ },
4125+ )
4126+ objectDecoder (b , ~input , ~selfSchema = mut , ~path )
41084127 } else if inputTagFlag -> Flag .unsafeHas (TagFlag .unknown ) {
41094128 let to = selfSchema .to -> X .Option .getUnsafe
41104129 // Whether we can optimize encoding during decoding
@@ -4183,31 +4202,35 @@ let enableJsonString = {
41834202 }
41844203
41854204 let makeJsonStringEncoder = (~validateOnly ) =>
4186- Builder .make ((b , ~input , ~selfSchema , ~path ) => {
4187- let inputVar = b -> B .Val .var (input )
4188- let output = ref (input )
4189- b .code =
4190- b .code ++
4191- ` try{` ++
4192- if validateOnly {
4193- ""
4194- } else {
4195- let targetVal = b -> B .allocateVal (~schema = json )
4196- output := targetVal
4197- targetVal .inline ++ "="
4198- } ++
4199- ` JSON.parse(${inputVar})}catch(t){${b-> B.failWithArg(
4200- ~path,
4201- input = > InvalidType({
4202- expected: selfSchema-> castToPublic,
4203- received: input,
4204- }),
4205- inputVar,
4206- )}}`
4207- if ! validateOnly {
4208- output := jsonEncoder (b , ~input = output .contents , ~selfSchema , ~path )
4205+ Builder .make ((b , ~input , ~selfSchema as to , ~path ) => {
4206+ if to .format === Some (JSON ) {
4207+ input
4208+ } else {
4209+ let inputVar = b -> B .Val .var (input )
4210+ let output = ref (input )
4211+ b .code =
4212+ b .code ++
4213+ ` try{` ++
4214+ if validateOnly {
4215+ ""
4216+ } else {
4217+ let targetVal = b -> B .allocateVal (~schema = json )
4218+ output := targetVal
4219+ targetVal .inline ++ "="
4220+ } ++
4221+ ` JSON.parse(${inputVar})}catch(t){${b-> B.failWithArg(
4222+ ~path,
4223+ input = > InvalidType({
4224+ expected: to-> castToPublic,
4225+ received: input,
4226+ }),
4227+ inputVar,
4228+ )}}`
4229+ if ! validateOnly {
4230+ output := jsonEncoder (b , ~input = output .contents , ~selfSchema = to , ~path )
4231+ }
4232+ output .contents
42094233 }
4210- output .contents
42114234 })
42124235
42134236 () => {
@@ -4654,45 +4677,45 @@ module Schema = {
46544677 (b , ~input : val , ~selfSchema , ~path ) => {
46554678 let isFlatten = b .global .flag -> Flag .unsafeHas (Flag .flatten )
46564679 // let outputs = isFlatten ? input.properties->Obj.magic : Js.Dict.empty()
4657- let outputs = Js .Dict .empty () // FIXME:
4680+ // let outputs = Js.Dict.empty() // FIXME:
46584681
4659- if ! isFlatten {
4660- let items = selfSchema .items -> X .Option .getUnsafe
4682+ // if !isFlatten {
4683+ // let items = selfSchema.items->X.Option.getUnsafe
46614684
4662- for idx in 0 to items -> Js .Array2 .length - 1 {
4663- let {schema , location } = items -> Js .Array2 .unsafe_get (idx )
4664- let schema = schema -> castToInternal
4685+ // for idx in 0 to items->Js.Array2.length - 1 {
4686+ // let {schema, location} = items->Js.Array2.unsafe_get(idx)
4687+ // let schema = schema->castToInternal
46654688
4666- let itemInput = b -> B .Val .get (input , location )
4667- let path = path -> Path .concat (b -> B .inlineLocation (location )-> Path .fromInlinedLocation )
4668- outputs -> Js .Dict .set (location , b -> parse (~schema , ~input = itemInput , ~path ))
4669- }
4689+ // let itemInput = b->B.Val.get(input, location)
4690+ // let path = path->Path.concat(b->B.inlineLocation(location)->Path.fromInlinedLocation)
4691+ // outputs->Js.Dict.set(location, b->parse(~schema, ~input=itemInput, ~path))
4692+ // }
46704693
4671- b -> objectStrictModeCheck (~input , ~items , ~selfSchema , ~path )
4672- }
4694+ // b->objectStrictModeCheck(~input, ~items, ~selfSchema, ~path)
4695+ // }
46734696
4674- switch flattened {
4675- | None => ()
4676- | Some (rootItems ) =>
4677- let prevFlag = b .global .flag
4678- b .global .flag = prevFlag -> Flag .with (Flag .flatten )
4679- for idx in 0 to rootItems -> Js .Array2 .length - 1 {
4680- let item = rootItems -> Js .Array2 .unsafe_get (idx )
4681- outputs
4682- -> Js .Dict .set (
4683- item -> getUnsafeDitemIndex ,
4684- b -> parse (~schema = item -> getDitemSchema , ~input , ~path ),
4685- )
4686- -> ignore
4687- }
4688- b .global .flag = prevFlag
4689- }
4697+ // switch flattened {
4698+ // | None => ()
4699+ // | Some(rootItems) =>
4700+ // let prevFlag = b.global.flag
4701+ // b.global.flag = prevFlag->Flag.with(Flag.flatten)
4702+ // for idx in 0 to rootItems->Js.Array2.length - 1 {
4703+ // let item = rootItems->Js.Array2.unsafe_get(idx)
4704+ // outputs
4705+ // ->Js.Dict.set(
4706+ // item->getUnsafeDitemIndex,
4707+ // b->parse(~schema=item->getDitemSchema, ~input, ~path),
4708+ // )
4709+ // ->ignore
4710+ // }
4711+ // b.global.flag = prevFlag
4712+ // }
46904713
46914714 let rec getItemOutput = item => {
46924715 switch item {
46934716 | ItemField ({target : item , location }) => b -> B .Val .get (item -> getItemOutput , location )
4694- | Item ({location }) => outputs -> Js . Dict . unsafeGet ( location )
4695- | Root ({idx }) => outputs -> Js . Dict . unsafeGet ( idx -> X .Int .unsafeToString )
4717+ | Item ({location }) => b -> B . Val . get ( input , location )
4718+ | Root ({idx }) => b -> B . Val . get ( input , idx -> X .Int .unsafeToString )
46964719 }
46974720 }
46984721
@@ -5080,6 +5103,7 @@ module Schema = {
50805103 mut .items = Some (items )
50815104 mut .properties = Some (properties )
50825105 mut .additionalItems = Some (globalConfig .defaultAdditionalItems )
5106+ mut .decoder = Some (objectDecoder )
50835107 mut .parser = Some (advancedBuilder (~definition , ~flattened ))
50845108 mut .to = Some (definitionToTarget (~definition , ~flattened ))
50855109 mut -> castToPublic
@@ -5130,6 +5154,7 @@ module Schema = {
51305154 let mut = base (arrayTag )
51315155 mut .items = Some (items )
51325156 mut .additionalItems = Some (Strict )
5157+ mut .decoder = Some (Array .arrayDecoder )
51335158 mut .parser = Some (advancedBuilder (~definition ))
51345159 mut .to = Some (definitionToTarget (~definition ))
51355160 mut -> castToPublic
0 commit comments