keyword.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.keywordCode = void 0;
  4. const context_1 = require("../context");
  5. const errors_1 = require("../errors");
  6. const code_1 = require("../../vocabularies/code");
  7. const codegen_1 = require("../codegen");
  8. const names_1 = require("../names");
  9. function keywordCode(it, keyword, def, ruleType) {
  10. const cxt = new context_1.default(it, def, keyword);
  11. if ("code" in def) {
  12. def.code(cxt, ruleType);
  13. }
  14. else if (cxt.$data && def.validate) {
  15. funcKeywordCode(cxt, def);
  16. }
  17. else if ("macro" in def) {
  18. macroKeywordCode(cxt, def);
  19. }
  20. else if (def.compile || def.validate) {
  21. funcKeywordCode(cxt, def);
  22. }
  23. }
  24. exports.keywordCode = keywordCode;
  25. function macroKeywordCode(cxt, def) {
  26. const { gen, keyword, schema, parentSchema, it } = cxt;
  27. const macroSchema = def.macro.call(it.self, schema, parentSchema, it);
  28. const schemaRef = useKeyword(gen, keyword, macroSchema);
  29. if (it.opts.validateSchema !== false)
  30. it.self.validateSchema(macroSchema, true);
  31. const valid = gen.name("valid");
  32. cxt.subschema({
  33. schema: macroSchema,
  34. schemaPath: codegen_1.nil,
  35. errSchemaPath: `${it.errSchemaPath}/${keyword}`,
  36. topSchemaRef: schemaRef,
  37. compositeRule: true,
  38. }, valid);
  39. cxt.pass(valid, () => cxt.error(true));
  40. }
  41. function funcKeywordCode(cxt, def) {
  42. var _a;
  43. const { gen, keyword, schema, parentSchema, $data, it } = cxt;
  44. checkAsync(it, def);
  45. const validate = !$data && def.compile ? def.compile.call(it.self, schema, parentSchema, it) : def.validate;
  46. const validateRef = useKeyword(gen, keyword, validate);
  47. const valid = gen.let("valid");
  48. cxt.block$data(valid, validateKeyword);
  49. cxt.ok((_a = def.valid) !== null && _a !== void 0 ? _a : valid);
  50. function validateKeyword() {
  51. if (def.errors === false) {
  52. assignValid();
  53. if (def.modifying)
  54. modifyData(cxt);
  55. reportErrs(() => cxt.error());
  56. }
  57. else {
  58. const ruleErrs = def.async ? validateAsync() : validateSync();
  59. if (def.modifying)
  60. modifyData(cxt);
  61. reportErrs(() => addErrs(cxt, ruleErrs));
  62. }
  63. }
  64. function validateAsync() {
  65. const ruleErrs = gen.let("ruleErrs", null);
  66. gen.try(() => assignValid(codegen_1._ `await `), (e) => gen.assign(valid, false).if(codegen_1._ `${e} instanceof ${it.ValidationError}`, () => gen.assign(ruleErrs, codegen_1._ `${e}.errors`), () => gen.throw(e)));
  67. return ruleErrs;
  68. }
  69. function validateSync() {
  70. const validateErrs = codegen_1._ `${validateRef}.errors`;
  71. gen.assign(validateErrs, null);
  72. assignValid(codegen_1.nil);
  73. return validateErrs;
  74. }
  75. function assignValid(_await = def.async ? codegen_1._ `await ` : codegen_1.nil) {
  76. const passCxt = it.opts.passContext ? names_1.default.this : names_1.default.self;
  77. const passSchema = !(("compile" in def && !$data) || def.schema === false);
  78. gen.assign(valid, codegen_1._ `${_await}${code_1.callValidateCode(cxt, validateRef, passCxt, passSchema)}`, def.modifying);
  79. }
  80. function reportErrs(errors) {
  81. var _a;
  82. gen.if(codegen_1.not((_a = def.valid) !== null && _a !== void 0 ? _a : valid), errors);
  83. }
  84. }
  85. function modifyData(cxt) {
  86. const { gen, data, it } = cxt;
  87. gen.if(it.parentData, () => gen.assign(data, codegen_1._ `${it.parentData}[${it.parentDataProperty}]`));
  88. }
  89. function addErrs(cxt, errs) {
  90. const { gen } = cxt;
  91. gen.if(codegen_1._ `Array.isArray(${errs})`, () => {
  92. gen
  93. .assign(names_1.default.vErrors, codegen_1._ `${names_1.default.vErrors} === null ? ${errs} : ${names_1.default.vErrors}.concat(${errs})`)
  94. .assign(names_1.default.errors, codegen_1._ `${names_1.default.vErrors}.length`);
  95. errors_1.extendErrors(cxt);
  96. }, () => cxt.error());
  97. }
  98. function checkAsync({ schemaEnv }, def) {
  99. if (def.async && !schemaEnv.$async)
  100. throw new Error("async keyword in sync schema");
  101. }
  102. function useKeyword(gen, keyword, result) {
  103. if (result === undefined)
  104. throw new Error(`keyword "${keyword}" failed to compile`);
  105. return gen.scopeValue("keyword", typeof result == "function" ? { ref: result } : { ref: result, code: codegen_1.stringify(result) });
  106. }
  107. //# sourceMappingURL=keyword.js.map