ref.js 5.1 KB

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