format.js 4.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const codegen_1 = require("../../compile/codegen");
  4. const error = {
  5. message: ({ schemaCode }) => (0, codegen_1.str) `must match format "${schemaCode}"`,
  6. params: ({ schemaCode }) => (0, 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", (0, codegen_1._) `${fmts}[${schemaCode}]`);
  29. const fType = gen.let("fType");
  30. const format = gen.let("format");
  31. // TODO simplify
  32. gen.if((0, codegen_1._) `typeof ${fDef} == "object" && !(${fDef} instanceof RegExp)`, () => gen.assign(fType, (0, codegen_1._) `${fDef}.type || "string"`).assign(format, (0, codegen_1._) `${fDef}.validate`), () => gen.assign(fType, (0, codegen_1._) `"string"`).assign(format, fDef));
  33. cxt.fail$data((0, codegen_1.or)(unknownFmt(), invalidFmt()));
  34. function unknownFmt() {
  35. if (opts.strictSchema === false)
  36. return codegen_1.nil;
  37. return (0, codegen_1._) `${schemaCode} && !${format}`;
  38. }
  39. function invalidFmt() {
  40. const callFormat = schemaEnv.$async
  41. ? (0, codegen_1._) `(${fDef}.async ? await ${format}(${data}) : ${format}(${data}))`
  42. : (0, codegen_1._) `${format}(${data})`;
  43. const validData = (0, codegen_1._) `(typeof ${format} == "function" ? ${callFormat} : ${format}.test(${data}))`;
  44. return (0, 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.strictSchema === 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 code = fmtDef instanceof RegExp
  70. ? (0, codegen_1.regexpCode)(fmtDef)
  71. : opts.code.formats
  72. ? (0, codegen_1._) `${opts.code.formats}${(0, codegen_1.getProperty)(schema)}`
  73. : undefined;
  74. const fmt = gen.scopeValue("formats", { key: schema, ref: fmtDef, code });
  75. if (typeof fmtDef == "object" && !(fmtDef instanceof RegExp)) {
  76. return [fmtDef.type || "string", fmtDef.validate, (0, codegen_1._) `${fmt}.validate`];
  77. }
  78. return ["string", fmtDef, fmt];
  79. }
  80. function validCondition() {
  81. if (typeof formatDef == "object" && !(formatDef instanceof RegExp) && formatDef.async) {
  82. if (!schemaEnv.$async)
  83. throw new Error("async format in sync schema");
  84. return (0, codegen_1._) `await ${fmtRef}(${data})`;
  85. }
  86. return typeof format == "function" ? (0, codegen_1._) `${fmtRef}(${data})` : (0, codegen_1._) `${fmtRef}.test(${data})`;
  87. }
  88. }
  89. },
  90. };
  91. exports.default = def;
  92. //# sourceMappingURL=format.js.map