--- /dev/null
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.callRef = exports.getValidate = void 0;
+const ref_error_1 = require("../../compile/ref_error");
+const code_1 = require("../code");
+const codegen_1 = require("../../compile/codegen");
+const names_1 = require("../../compile/names");
+const compile_1 = require("../../compile");
+const util_1 = require("../../compile/util");
+const def = {
+ keyword: "$ref",
+ schemaType: "string",
+ code(cxt) {
+ const { gen, schema: $ref, it } = cxt;
+ const { baseId, schemaEnv: env, validateName, opts, self } = it;
+ const { root } = env;
+ if (($ref === "#" || $ref === "#/") && baseId === root.baseId)
+ return callRootRef();
+ const schOrEnv = compile_1.resolveRef.call(self, root, baseId, $ref);
+ if (schOrEnv === undefined)
+ throw new ref_error_1.default(baseId, $ref);
+ if (schOrEnv instanceof compile_1.SchemaEnv)
+ return callValidate(schOrEnv);
+ return inlineRefSchema(schOrEnv);
+ function callRootRef() {
+ if (env === root)
+ return callRef(cxt, validateName, env, env.$async);
+ const rootName = gen.scopeValue("root", { ref: root });
+ return callRef(cxt, codegen_1._ `${rootName}.validate`, root, root.$async);
+ }
+ function callValidate(sch) {
+ const v = getValidate(cxt, sch);
+ callRef(cxt, v, sch, sch.$async);
+ }
+ function inlineRefSchema(sch) {
+ const schName = gen.scopeValue("schema", opts.code.source === true ? { ref: sch, code: codegen_1.stringify(sch) } : { ref: sch });
+ const valid = gen.name("valid");
+ const schCxt = cxt.subschema({
+ schema: sch,
+ dataTypes: [],
+ schemaPath: codegen_1.nil,
+ topSchemaRef: schName,
+ errSchemaPath: $ref,
+ }, valid);
+ cxt.mergeEvaluated(schCxt);
+ cxt.ok(valid);
+ }
+ },
+};
+function getValidate(cxt, sch) {
+ const { gen } = cxt;
+ return sch.validate
+ ? gen.scopeValue("validate", { ref: sch.validate })
+ : codegen_1._ `${gen.scopeValue("wrapper", { ref: sch })}.validate`;
+}
+exports.getValidate = getValidate;
+function callRef(cxt, v, sch, $async) {
+ const { gen, it } = cxt;
+ const { allErrors, schemaEnv: env, opts } = it;
+ const passCxt = opts.passContext ? names_1.default.this : codegen_1.nil;
+ if ($async)
+ callAsyncRef();
+ else
+ callSyncRef();
+ function callAsyncRef() {
+ if (!env.$async)
+ throw new Error("async schema referenced by sync schema");
+ const valid = gen.let("valid");
+ gen.try(() => {
+ gen.code(codegen_1._ `await ${code_1.callValidateCode(cxt, v, passCxt)}`);
+ addEvaluatedFrom(v); // TODO will not work with async, it has to be returned with the result
+ if (!allErrors)
+ gen.assign(valid, true);
+ }, (e) => {
+ gen.if(codegen_1._ `!(${e} instanceof ${it.ValidationError})`, () => gen.throw(e));
+ addErrorsFrom(e);
+ if (!allErrors)
+ gen.assign(valid, false);
+ });
+ cxt.ok(valid);
+ }
+ function callSyncRef() {
+ cxt.result(code_1.callValidateCode(cxt, v, passCxt), () => addEvaluatedFrom(v), () => addErrorsFrom(v));
+ }
+ function addErrorsFrom(source) {
+ const errs = codegen_1._ `${source}.errors`;
+ gen.assign(names_1.default.vErrors, codegen_1._ `${names_1.default.vErrors} === null ? ${errs} : ${names_1.default.vErrors}.concat(${errs})`); // TODO tagged
+ gen.assign(names_1.default.errors, codegen_1._ `${names_1.default.vErrors}.length`);
+ }
+ function addEvaluatedFrom(source) {
+ var _a;
+ if (!it.opts.unevaluated)
+ return;
+ const schEvaluated = (_a = sch === null || sch === void 0 ? void 0 : sch.validate) === null || _a === void 0 ? void 0 : _a.evaluated;
+ // TODO refactor
+ if (it.props !== true) {
+ if (schEvaluated && !schEvaluated.dynamicProps) {
+ if (schEvaluated.props !== undefined) {
+ it.props = util_1.mergeEvaluated.props(gen, schEvaluated.props, it.props);
+ }
+ }
+ else {
+ const props = gen.var("props", codegen_1._ `${source}.evaluated.props`);
+ it.props = util_1.mergeEvaluated.props(gen, props, it.props, codegen_1.Name);
+ }
+ }
+ if (it.items !== true) {
+ if (schEvaluated && !schEvaluated.dynamicItems) {
+ if (schEvaluated.items !== undefined) {
+ it.items = util_1.mergeEvaluated.items(gen, schEvaluated.items, it.items);
+ }
+ }
+ else {
+ const items = gen.var("items", codegen_1._ `${source}.evaluated.items`);
+ it.items = util_1.mergeEvaluated.items(gen, items, it.items, codegen_1.Name);
+ }
+ }
+ }
+}
+exports.callRef = callRef;
+exports.default = def;
+//# sourceMappingURL=ref.js.map
\ No newline at end of file