values.ts 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import type {CodeKeywordDefinition, SchemaObject} from "../../types"
  2. import type {KeywordCxt} from "../../compile/validate"
  3. import {alwaysValidSchema, Type} from "../../compile/util"
  4. import {not, or, Name} from "../../compile/codegen"
  5. import {checkMetadata} from "./metadata"
  6. import {checkNullableObject} from "./nullable"
  7. import {typeError, _JTDTypeError} from "./error"
  8. export type JTDValuesError = _JTDTypeError<"values", "object", SchemaObject>
  9. const def: CodeKeywordDefinition = {
  10. keyword: "values",
  11. schemaType: "object",
  12. error: typeError("object"),
  13. code(cxt: KeywordCxt) {
  14. checkMetadata(cxt)
  15. const {gen, data, schema, it} = cxt
  16. const [valid, cond] = checkNullableObject(cxt, data)
  17. if (alwaysValidSchema(it, schema)) {
  18. gen.if(not(or(cond, valid)), () => cxt.error())
  19. } else {
  20. gen.if(cond)
  21. gen.assign(valid, validateMap())
  22. gen.elseIf(not(valid))
  23. cxt.error()
  24. gen.endIf()
  25. }
  26. cxt.ok(valid)
  27. function validateMap(): Name | boolean {
  28. const _valid = gen.name("valid")
  29. if (it.allErrors) {
  30. const validMap = gen.let("valid", true)
  31. validateValues(() => gen.assign(validMap, false))
  32. return validMap
  33. }
  34. gen.var(_valid, true)
  35. validateValues(() => gen.break())
  36. return _valid
  37. function validateValues(notValid: () => void): void {
  38. gen.forIn("key", data, (key) => {
  39. cxt.subschema(
  40. {
  41. keyword: "values",
  42. dataProp: key,
  43. dataPropType: Type.Str,
  44. },
  45. _valid
  46. )
  47. gen.if(not(_valid), notValid)
  48. })
  49. }
  50. }
  51. },
  52. }
  53. export default def