ref.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.callRef = exports.getValidate = void 0;
  4. const error_classes_1 = require("../../compile/error_classes");
  5. const code_1 = require("../code");
  6. const codegen_1 = require("../../compile/codegen");
  7. const names_1 = require("../../compile/names");
  8. const compile_1 = require("../../compile");
  9. const util_1 = require("../../compile/util");
  10. const def = {
  11. keyword: "$ref",
  12. schemaType: "string",
  13. code(cxt) {
  14. const { gen, schema, it } = cxt;
  15. const { baseId, schemaEnv: env, validateName, opts, self } = it;
  16. // TODO See comment in dynamicRef.ts
  17. // This has to be improved to resolve #815.
  18. if (schema === "#" || schema === "#/")
  19. return callRootRef();
  20. const schOrEnv = compile_1.resolveRef.call(self, env.root, baseId, schema);
  21. if (schOrEnv === undefined)
  22. throw new error_classes_1.MissingRefError(baseId, schema);
  23. if (schOrEnv instanceof compile_1.SchemaEnv)
  24. return callValidate(schOrEnv);
  25. return inlineRefSchema(schOrEnv);
  26. function callRootRef() {
  27. if (env === env.root)
  28. return callRef(cxt, validateName, env, env.$async);
  29. const rootName = gen.scopeValue("root", { ref: env.root });
  30. return callRef(cxt, codegen_1._ `${rootName}.validate`, env.root, env.root.$async);
  31. }
  32. function callValidate(sch) {
  33. const v = getValidate(cxt, sch);
  34. callRef(cxt, v, sch, sch.$async);
  35. }
  36. function inlineRefSchema(sch) {
  37. const schName = gen.scopeValue("schema", opts.code.source === true ? { ref: sch, code: codegen_1.stringify(sch) } : { ref: sch });
  38. const valid = gen.name("valid");
  39. const schCxt = cxt.subschema({
  40. schema: sch,
  41. strictSchema: true,
  42. dataTypes: [],
  43. schemaPath: codegen_1.nil,
  44. topSchemaRef: schName,
  45. errSchemaPath: schema,
  46. }, valid);
  47. cxt.mergeEvaluated(schCxt);
  48. cxt.ok(valid);
  49. }
  50. },
  51. };
  52. function getValidate(cxt, sch) {
  53. const { gen } = cxt;
  54. return sch.validate
  55. ? gen.scopeValue("validate", { ref: sch.validate })
  56. : codegen_1._ `${gen.scopeValue("wrapper", { ref: sch })}.validate`;
  57. }
  58. exports.getValidate = getValidate;
  59. function callRef(cxt, v, sch, $async) {
  60. const { gen, it } = cxt;
  61. const { allErrors, schemaEnv: env, opts } = it;
  62. const passCxt = opts.passContext ? names_1.default.this : codegen_1.nil;
  63. if ($async)
  64. callAsyncRef();
  65. else
  66. callSyncRef();
  67. function callAsyncRef() {
  68. if (!env.$async)
  69. throw new Error("async schema referenced by sync schema");
  70. const valid = gen.let("valid");
  71. gen.try(() => {
  72. gen.code(codegen_1._ `await ${code_1.callValidateCode(cxt, v, passCxt)}`);
  73. addEvaluatedFrom(v); // TODO will not work with async, it has to be returned with the result
  74. if (!allErrors)
  75. gen.assign(valid, true);
  76. }, (e) => {
  77. gen.if(codegen_1._ `!(${e} instanceof ${it.ValidationError})`, () => gen.throw(e));
  78. addErrorsFrom(e);
  79. if (!allErrors)
  80. gen.assign(valid, false);
  81. });
  82. cxt.ok(valid);
  83. }
  84. function callSyncRef() {
  85. cxt.result(code_1.callValidateCode(cxt, v, passCxt), () => addEvaluatedFrom(v), () => addErrorsFrom(v));
  86. }
  87. function addErrorsFrom(source) {
  88. const errs = codegen_1._ `${source}.errors`;
  89. gen.assign(names_1.default.vErrors, codegen_1._ `${names_1.default.vErrors} === null ? ${errs} : ${names_1.default.vErrors}.concat(${errs})`); // TODO tagged
  90. gen.assign(names_1.default.errors, codegen_1._ `${names_1.default.vErrors}.length`);
  91. }
  92. function addEvaluatedFrom(source) {
  93. var _a;
  94. if (!it.opts.unevaluated)
  95. return;
  96. const schEvaluated = (_a = sch === null || sch === void 0 ? void 0 : sch.validate) === null || _a === void 0 ? void 0 : _a.evaluated;
  97. // TODO refactor
  98. if (it.props !== true) {
  99. if (schEvaluated && !schEvaluated.dynamicProps) {
  100. if (schEvaluated.props !== undefined) {
  101. it.props = util_1.mergeEvaluated.props(gen, schEvaluated.props, it.props);
  102. }
  103. }
  104. else {
  105. const props = gen.var("props", codegen_1._ `${source}.evaluated.props`);
  106. it.props = util_1.mergeEvaluated.props(gen, props, it.props, codegen_1.Name);
  107. }
  108. }
  109. if (it.items !== true) {
  110. if (schEvaluated && !schEvaluated.dynamicItems) {
  111. if (schEvaluated.items !== undefined) {
  112. it.items = util_1.mergeEvaluated.items(gen, schEvaluated.items, it.items);
  113. }
  114. }
  115. else {
  116. const items = gen.var("items", codegen_1._ `${source}.evaluated.items`);
  117. it.items = util_1.mergeEvaluated.items(gen, items, it.items, codegen_1.Name);
  118. }
  119. }
  120. }
  121. }
  122. exports.callRef = callRef;
  123. exports.default = def;
  124. //# sourceMappingURL=ref.js.map