format.js 4.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const codegen_1 = require("../../compile/codegen");
  4. const error = {
  5. message: ({ schemaCode }) => codegen_1.str `should match format "${schemaCode}"`,
  6. params: ({ schemaCode }) => codegen_1._ `{format: ${schemaCode}}`,
  7. };
  8. const def = {
  9. keyword: "format",
  10. type: ["number", "string"],
  11. schemaType: "string",
  12. $data: true,
  13. error,
  14. code(cxt, ruleType) {
  15. const { gen, data, $data, schema, schemaCode, it } = cxt;
  16. const { opts, errSchemaPath, schemaEnv, self } = it;
  17. if (!opts.validateFormats)
  18. return;
  19. if ($data)
  20. validate$DataFormat();
  21. else
  22. validateFormat();
  23. function validate$DataFormat() {
  24. const fmts = gen.scopeValue("formats", {
  25. ref: self.formats,
  26. code: opts.code.formats,
  27. });
  28. const fDef = gen.const("fDef", codegen_1._ `${fmts}[${schemaCode}]`);
  29. const fType = gen.let("fType");
  30. const format = gen.let("format");
  31. // TODO simplify
  32. gen.if(codegen_1._ `typeof ${fDef} == "object" && !(${fDef} instanceof RegExp)`, () => gen.assign(fType, codegen_1._ `${fDef}.type || "string"`).assign(format, codegen_1._ `${fDef}.validate`), () => gen.assign(fType, codegen_1._ `"string"`).assign(format, fDef));
  33. cxt.fail$data(codegen_1.or(unknownFmt(), invalidFmt()));
  34. function unknownFmt() {
  35. if (opts.strict === false)
  36. return codegen_1.nil;
  37. return codegen_1._ `${schemaCode} && !${format}`;
  38. }
  39. function invalidFmt() {
  40. const callFormat = schemaEnv.$async
  41. ? codegen_1._ `(${fDef}.async ? await ${format}(${data}) : ${format}(${data}))`
  42. : codegen_1._ `${format}(${data})`;
  43. const validData = codegen_1._ `(typeof ${format} == "function" ? ${callFormat} : ${format}.test(${data}))`;
  44. return codegen_1._ `${format} && ${format} !== true && ${fType} === ${ruleType} && !${validData}`;
  45. }
  46. }
  47. function validateFormat() {
  48. const formatDef = self.formats[schema];
  49. if (!formatDef) {
  50. unknownFormat();
  51. return;
  52. }
  53. if (formatDef === true)
  54. return;
  55. const [fmtType, format, fmtRef] = getFormat(formatDef);
  56. if (fmtType === ruleType)
  57. cxt.pass(validCondition());
  58. function unknownFormat() {
  59. if (opts.strict === false) {
  60. self.logger.warn(unknownMsg());
  61. return;
  62. }
  63. throw new Error(unknownMsg());
  64. function unknownMsg() {
  65. return `unknown format "${schema}" ignored in schema at path "${errSchemaPath}"`;
  66. }
  67. }
  68. function getFormat(fmtDef) {
  69. const fmt = gen.scopeValue("formats", {
  70. key: schema,
  71. ref: fmtDef,
  72. code: opts.code.formats ? codegen_1._ `${opts.code.formats}${codegen_1.getProperty(schema)}` : undefined,
  73. });
  74. if (typeof fmtDef == "object" && !(fmtDef instanceof RegExp)) {
  75. return [fmtDef.type || "string", fmtDef.validate, codegen_1._ `${fmt}.validate`];
  76. }
  77. return ["string", fmtDef, fmt];
  78. }
  79. function validCondition() {
  80. if (typeof formatDef == "object" && !(formatDef instanceof RegExp) && formatDef.async) {
  81. if (!schemaEnv.$async)
  82. throw new Error("async format in sync schema");
  83. return codegen_1._ `await ${fmtRef}(${data})`;
  84. }
  85. return typeof format == "function" ? codegen_1._ `${fmtRef}(${data})` : codegen_1._ `${fmtRef}.test(${data})`;
  86. }
  87. }
  88. },
  89. };
  90. exports.default = def;
  91. //# sourceMappingURL=format.js.map