diff --git a/packages/tests/src/core/S_refine_test.res b/packages/tests/src/core/S_refine_test.res index 1c67199a..af23baa1 100644 --- a/packages/tests/src/core/S_refine_test.res +++ b/packages/tests/src/core/S_refine_test.res @@ -82,7 +82,7 @@ test("Compiled parse code snapshot for simple object with refine", t => { t->U.assertCompiledCode( ~schema, ~op=#Parse, - `i=>{if(!i||i.constructor!==Object){e[3](i)}let v0=i["foo"],v1=i["bar"],v2={"foo":v0,"bar":v1,};if(typeof v0!=="string"){e[0](v0)}if(typeof v1!=="boolean"){e[1](v1)}e[2](v2);return v2}`, + `i=>{if(!i||i.constructor!==Object){e[3](i)}let v0=i["foo"],v1=i["bar"],v2;if(typeof v0!=="string"){e[0](v0)}if(typeof v1!=="boolean"){e[1](v1)}v2={"foo":v0,"bar":v1,};e[2](v2);return v2}`, ) }) @@ -95,7 +95,7 @@ module Issue79 = { t->U.assertCompiledCode( ~schema, ~op=#Parse, - `i=>{if(!i||i.constructor!==Object){e[2](i)}let v0=i["myField"],v2,v3=v2;if(v0!==void 0&&(v0!==null&&(typeof v0!=="string"))){e[0](v0)}if(v0!==void 0){let v1;if(v0!==null){v1=v0}else{v1=void 0}v2=v1}e[1](v3);return v3}`, + `i=>{if(!i||i.constructor!==Object){e[2](i)}let v0=i["myField"],v2,v3;if(v0!==void 0&&(v0!==null&&(typeof v0!=="string"))){e[0](v0)}if(v0!==void 0){let v1;if(v0!==null){v1=v0}else{v1=void 0}v2=v1}v3=v2;e[1](v3);return v3}`, ) t->Assert.deepEqual(jsonString->S.parseJsonStringWith(schema), Ok(Some("test")), ()) diff --git a/src/S_Core.bs.mjs b/src/S_Core.bs.mjs index e7c8e5d3..5ad070f3 100644 --- a/src/S_Core.bs.mjs +++ b/src/S_Core.bs.mjs @@ -1027,13 +1027,21 @@ function containerName() { function internalRefine(schema, refiner) { return make(schema.n, schema.r, schema.m, (function (b, input, selfSchema, path) { return transform(b, schema.p(b, input, schema, path), (function (b, input) { - var rCode = refiner(b, input, selfSchema, path); + var input$1; + if (b.c === "" && input.v !== undefined) { + input$1 = input; + } else { + var scopedInput = allocateVal(b); + b.c = b.c + set(b, scopedInput, input) + ";"; + input$1 = scopedInput; + } + var rCode = refiner(b, $$var(b, input$1), selfSchema, path); b.c = b.c + rCode; - return input; + return input$1; })); }), (function (b, input, selfSchema, path) { var input$1 = transform(b, input, (function (b, input) { - b.c = b.c + refiner(b, input, selfSchema, path); + b.c = b.c + refiner(b, $$var(b, input), selfSchema, path); return input; })); return schema.s(b, input$1, schema, path); @@ -1041,9 +1049,9 @@ function internalRefine(schema, refiner) { } function refine(schema, refiner) { - return internalRefine(schema, (function (b, input, selfSchema, path) { + return internalRefine(schema, (function (b, inputVar, selfSchema, path) { var value = refiner(effectCtx(b, selfSchema, path)); - return "e[" + (b.g.e.push(value) - 1) + "](" + $$var(b, input) + ");"; + return "e[" + (b.g.e.push(value) - 1) + "](" + inputVar + ");"; })); } @@ -2577,8 +2585,8 @@ function intMin(schema, minValue, maybeMessage) { value: minValue }, message: message - }, (function (b, input, param, path) { - return "if(" + $$var(b, input) + "<" + ("e[" + (b.g.e.push(minValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(" + inputVar + "<" + ("e[" + (b.g.e.push(minValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2590,8 +2598,8 @@ function intMax(schema, maxValue, maybeMessage) { value: maxValue }, message: message - }, (function (b, input, param, path) { - return "if(" + $$var(b, input) + ">" + ("e[" + (b.g.e.push(maxValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(" + inputVar + ">" + ("e[" + (b.g.e.push(maxValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2600,8 +2608,8 @@ function port(schema, messageOpt) { return addRefinement(schema, metadataId$1, { kind: "Port", message: message - }, (function (b, input, param, path) { - return "if(" + $$var(b, input) + "<1||" + $$var(b, input) + ">65535){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(" + inputVar + "<1||" + inputVar + ">65535){" + fail(b, message, path) + "}"; })); } @@ -2613,8 +2621,8 @@ function floatMin(schema, minValue, maybeMessage) { value: minValue }, message: message - }, (function (b, input, param, path) { - return "if(" + $$var(b, input) + "<" + ("e[" + (b.g.e.push(minValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(" + inputVar + "<" + ("e[" + (b.g.e.push(minValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2626,8 +2634,8 @@ function floatMax(schema, maxValue, maybeMessage) { value: maxValue }, message: message - }, (function (b, input, param, path) { - return "if(" + $$var(b, input) + ">" + ("e[" + (b.g.e.push(maxValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(" + inputVar + ">" + ("e[" + (b.g.e.push(maxValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2639,8 +2647,8 @@ function arrayMinLength(schema, length, maybeMessage) { length: length }, message: message - }, (function (b, input, param, path) { - return "if(" + $$var(b, input) + ".length<" + ("e[" + (b.g.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(" + inputVar + ".length<" + ("e[" + (b.g.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2652,8 +2660,8 @@ function arrayMaxLength(schema, length, maybeMessage) { length: length }, message: message - }, (function (b, input, param, path) { - return "if(" + $$var(b, input) + ".length>" + ("e[" + (b.g.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(" + inputVar + ".length>" + ("e[" + (b.g.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2665,8 +2673,8 @@ function arrayLength(schema, length, maybeMessage) { length: length }, message: message - }, (function (b, input, param, path) { - return "if(" + $$var(b, input) + ".length!==" + ("e[" + (b.g.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(" + inputVar + ".length!==" + ("e[" + (b.g.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2678,8 +2686,8 @@ function stringMinLength(schema, length, maybeMessage) { length: length }, message: message - }, (function (b, input, param, path) { - return "if(" + $$var(b, input) + ".length<" + ("e[" + (b.g.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(" + inputVar + ".length<" + ("e[" + (b.g.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2691,8 +2699,8 @@ function stringMaxLength(schema, length, maybeMessage) { length: length }, message: message - }, (function (b, input, param, path) { - return "if(" + $$var(b, input) + ".length>" + ("e[" + (b.g.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(" + inputVar + ".length>" + ("e[" + (b.g.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2704,8 +2712,8 @@ function stringLength(schema, length, maybeMessage) { length: length }, message: message - }, (function (b, input, param, path) { - return "if(" + $$var(b, input) + ".length!==" + ("e[" + (b.g.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(" + inputVar + ".length!==" + ("e[" + (b.g.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2714,8 +2722,8 @@ function email(schema, messageOpt) { return addRefinement(schema, metadataId, { kind: "Email", message: message - }, (function (b, input, param, path) { - return "if(!" + ("e[" + (b.g.e.push(emailRegex) - 1) + "]") + ".test(" + $$var(b, input) + ")){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(!" + ("e[" + (b.g.e.push(emailRegex) - 1) + "]") + ".test(" + inputVar + ")){" + fail(b, message, path) + "}"; })); } @@ -2724,8 +2732,8 @@ function uuid(schema, messageOpt) { return addRefinement(schema, metadataId, { kind: "Uuid", message: message - }, (function (b, input, param, path) { - return "if(!" + ("e[" + (b.g.e.push(uuidRegex) - 1) + "]") + ".test(" + $$var(b, input) + ")){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(!" + ("e[" + (b.g.e.push(uuidRegex) - 1) + "]") + ".test(" + inputVar + ")){" + fail(b, message, path) + "}"; })); } @@ -2734,8 +2742,8 @@ function cuid(schema, messageOpt) { return addRefinement(schema, metadataId, { kind: "Cuid", message: message - }, (function (b, input, param, path) { - return "if(!" + ("e[" + (b.g.e.push(cuidRegex) - 1) + "]") + ".test(" + $$var(b, input) + ")){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "if(!" + ("e[" + (b.g.e.push(cuidRegex) - 1) + "]") + ".test(" + inputVar + ")){" + fail(b, message, path) + "}"; })); } @@ -2744,8 +2752,8 @@ function url(schema, messageOpt) { return addRefinement(schema, metadataId, { kind: "Url", message: message - }, (function (b, input, param, path) { - return "try{new URL(" + $$var(b, input) + ")}catch(_){" + fail(b, message, path) + "}"; + }, (function (b, inputVar, param, path) { + return "try{new URL(" + inputVar + ")}catch(_){" + fail(b, message, path) + "}"; })); } @@ -2757,10 +2765,10 @@ function pattern(schema, re, messageOpt) { re: re }, message: message - }, (function (b, input, param, path) { + }, (function (b, inputVar, param, path) { var reVal = val(b, "e[" + (b.g.e.push(re) - 1) + "]"); var reVar = $$var(b, reVal); - return reVar + ".lastIndex=0;if(!" + reVar + ".test(" + $$var(b, input) + ")){" + fail(b, message, path) + "}"; + return reVar + ".lastIndex=0;if(!" + reVar + ".test(" + inputVar + ")){" + fail(b, message, path) + "}"; })); } diff --git a/src/S_Core.res b/src/S_Core.res index 3bcd7f14..51220213 100644 --- a/src/S_Core.res +++ b/src/S_Core.res @@ -1494,7 +1494,14 @@ let internalRefine = (schema, refiner) => { ~rawTagged=schema.rawTagged, ~parseOperationBuilder=Builder.make((b, ~input, ~selfSchema, ~path) => { b->B.transform(~input=b->B.parse(~schema, ~input, ~path), (b, ~input) => { - let rCode = refiner(b, ~input, ~selfSchema, ~path) + let input = if b.code === "" && input._var !== None { + input + } else { + let scopedInput = b->B.allocateVal + b.code = b.code ++ b->B.Val.set(scopedInput, input) ++ ";" + scopedInput + } + let rCode = refiner(b, ~inputVar=b->B.Val.var(input), ~selfSchema, ~path) b.code = b.code ++ rCode input }) @@ -1503,7 +1510,7 @@ let internalRefine = (schema, refiner) => { b->B.serialize( ~schema, ~input=b->B.transform(~input, (b, ~input) => { - b.code = b.code ++ refiner(b, ~input, ~selfSchema, ~path) + b.code = b.code ++ refiner(b, ~inputVar=b->B.Val.var(input), ~selfSchema, ~path) input }), ~path, @@ -1515,8 +1522,8 @@ let internalRefine = (schema, refiner) => { } let refine: (t<'value>, s<'value> => 'value => unit) => t<'value> = (schema, refiner) => { - schema->internalRefine((b, ~input, ~selfSchema, ~path) => { - `${b->B.embed(refiner(b->B.effectCtx(~selfSchema, ~path)))}(${b->B.Val.var(input)});` + schema->internalRefine((b, ~inputVar, ~selfSchema, ~path) => { + `${b->B.embed(refiner(b->B.effectCtx(~selfSchema, ~path)))}(${inputVar});` }) } @@ -3534,8 +3541,8 @@ let intMin = (schema, minValue, ~message as maybeMessage=?) => { } schema->addRefinement( ~metadataId=Int.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(${b->B.Val.var(input)}<${b->B.embed(minValue)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(${inputVar}<${b->B.embed(minValue)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Min({value: minValue}), @@ -3551,8 +3558,8 @@ let intMax = (schema, maxValue, ~message as maybeMessage=?) => { } schema->addRefinement( ~metadataId=Int.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(${b->B.Val.var(input)}>${b->B.embed(maxValue)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(${inputVar}>${b->B.embed(maxValue)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Max({value: maxValue}), @@ -3564,8 +3571,8 @@ let intMax = (schema, maxValue, ~message as maybeMessage=?) => { let port = (schema, ~message="Invalid port") => { schema->addRefinement( ~metadataId=Int.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(${b->B.Val.var(input)}<1||${b->B.Val.var(input)}>65535){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(${inputVar}<1||${inputVar}>65535){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Port, @@ -3581,8 +3588,8 @@ let floatMin = (schema, minValue, ~message as maybeMessage=?) => { } schema->addRefinement( ~metadataId=Float.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(${b->B.Val.var(input)}<${b->B.embed(minValue)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(${inputVar}<${b->B.embed(minValue)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Min({value: minValue}), @@ -3598,8 +3605,8 @@ let floatMax = (schema, maxValue, ~message as maybeMessage=?) => { } schema->addRefinement( ~metadataId=Float.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(${b->B.Val.var(input)}>${b->B.embed(maxValue)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(${inputVar}>${b->B.embed(maxValue)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Max({value: maxValue}), @@ -3615,8 +3622,8 @@ let arrayMinLength = (schema, length, ~message as maybeMessage=?) => { } schema->addRefinement( ~metadataId=Array.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(${b->B.Val.var(input)}.length<${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(${inputVar}.length<${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Min({length: length}), @@ -3632,8 +3639,8 @@ let arrayMaxLength = (schema, length, ~message as maybeMessage=?) => { } schema->addRefinement( ~metadataId=Array.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(${b->B.Val.var(input)}.length>${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(${inputVar}.length>${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Max({length: length}), @@ -3649,8 +3656,8 @@ let arrayLength = (schema, length, ~message as maybeMessage=?) => { } schema->addRefinement( ~metadataId=Array.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(${b->B.Val.var(input)}.length!==${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(${inputVar}.length!==${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Length({length: length}), @@ -3666,8 +3673,8 @@ let stringMinLength = (schema, length, ~message as maybeMessage=?) => { } schema->addRefinement( ~metadataId=String.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(${b->B.Val.var(input)}.length<${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(${inputVar}.length<${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Min({length: length}), @@ -3683,8 +3690,8 @@ let stringMaxLength = (schema, length, ~message as maybeMessage=?) => { } schema->addRefinement( ~metadataId=String.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(${b->B.Val.var(input)}.length>${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(${inputVar}.length>${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Max({length: length}), @@ -3700,8 +3707,8 @@ let stringLength = (schema, length, ~message as maybeMessage=?) => { } schema->addRefinement( ~metadataId=String.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(${b->B.Val.var(input)}.length!==${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(${inputVar}.length!==${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Length({length: length}), @@ -3713,11 +3720,8 @@ let stringLength = (schema, length, ~message as maybeMessage=?) => { let email = (schema, ~message=`Invalid email address`) => { schema->addRefinement( ~metadataId=String.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(!${b->B.embed(String.emailRegex)}.test(${b->B.Val.var(input)})){${b->B.fail( - ~message, - ~path, - )}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(!${b->B.embed(String.emailRegex)}.test(${inputVar})){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Email, @@ -3729,11 +3733,8 @@ let email = (schema, ~message=`Invalid email address`) => { let uuid = (schema, ~message=`Invalid UUID`) => { schema->addRefinement( ~metadataId=String.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(!${b->B.embed(String.uuidRegex)}.test(${b->B.Val.var(input)})){${b->B.fail( - ~message, - ~path, - )}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(!${b->B.embed(String.uuidRegex)}.test(${inputVar})){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Uuid, @@ -3745,11 +3746,8 @@ let uuid = (schema, ~message=`Invalid UUID`) => { let cuid = (schema, ~message=`Invalid CUID`) => { schema->addRefinement( ~metadataId=String.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `if(!${b->B.embed(String.cuidRegex)}.test(${b->B.Val.var(input)})){${b->B.fail( - ~message, - ~path, - )}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `if(!${b->B.embed(String.cuidRegex)}.test(${inputVar})){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Cuid, @@ -3761,8 +3759,8 @@ let cuid = (schema, ~message=`Invalid CUID`) => { let url = (schema, ~message=`Invalid url`) => { schema->addRefinement( ~metadataId=String.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { - `try{new URL(${b->B.Val.var(input)})}catch(_){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + `try{new URL(${inputVar})}catch(_){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Url, @@ -3774,13 +3772,10 @@ let url = (schema, ~message=`Invalid url`) => { let pattern = (schema, re, ~message=`Invalid`) => { schema->addRefinement( ~metadataId=String.Refinement.metadataId, - ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { let reVal = b->B.val(b->B.embed(re)) let reVar = b->B.Val.var(reVal) - `${reVar}.lastIndex=0;if(!${reVar}.test(${b->B.Val.var(input)})){${b->B.fail( - ~message, - ~path, - )}}` + `${reVar}.lastIndex=0;if(!${reVar}.test(${inputVar})){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Pattern({re: re}),