properties.ts 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import type {CodeKeywordDefinition} from "../../types"
  2. import KeywordCxt from "../../compile/context"
  3. import {propertyInData, allSchemaProperties} from "../code"
  4. import {alwaysValidSchema, toHash, mergeEvaluated} from "../../compile/util"
  5. import apDef from "./additionalProperties"
  6. const def: CodeKeywordDefinition = {
  7. keyword: "properties",
  8. type: "object",
  9. schemaType: "object",
  10. code(cxt: KeywordCxt) {
  11. const {gen, schema, parentSchema, data, it} = cxt
  12. if (it.opts.removeAdditional === "all" && parentSchema.additionalProperties === undefined) {
  13. apDef.code(new KeywordCxt(it, apDef, "additionalProperties"))
  14. }
  15. const allProps = allSchemaProperties(schema)
  16. if (it.opts.unevaluated && allProps.length && it.props !== true) {
  17. it.props = mergeEvaluated.props(gen, toHash(allProps), it.props)
  18. }
  19. const properties = allProps.filter((p) => !alwaysValidSchema(it, schema[p]))
  20. if (properties.length === 0) return
  21. const valid = gen.name("valid")
  22. for (const prop of properties) {
  23. if (hasDefault(prop)) {
  24. applyPropertySchema(prop)
  25. } else {
  26. gen.if(propertyInData(data, prop, it.opts.ownProperties))
  27. applyPropertySchema(prop)
  28. if (!it.allErrors) gen.else().var(valid, true)
  29. gen.endIf()
  30. }
  31. cxt.ok(valid)
  32. }
  33. function hasDefault(prop: string): boolean | undefined {
  34. return it.opts.useDefaults && !it.compositeRule && schema[prop].default !== undefined
  35. }
  36. function applyPropertySchema(prop: string): void {
  37. cxt.subschema(
  38. {
  39. keyword: "properties",
  40. schemaProp: prop,
  41. dataProp: prop,
  42. strictSchema: it.strictSchema,
  43. },
  44. valid
  45. )
  46. }
  47. },
  48. }
  49. export default def