discriminator.ts 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import type {CodeKeywordDefinition} from "../../types"
  2. import type KeywordCxt from "../../compile/context"
  3. import {_, getProperty, Name} from "../../compile/codegen"
  4. import {checkMetadata} from "./metadata"
  5. import {checkNullableObject} from "./nullable"
  6. const def: CodeKeywordDefinition = {
  7. keyword: "discriminator",
  8. schemaType: "string",
  9. implements: ["mapping"],
  10. code(cxt: KeywordCxt) {
  11. checkMetadata(cxt)
  12. const {gen, data, schema, parentSchema} = cxt
  13. const [valid, cond] = checkNullableObject(cxt, data)
  14. gen.if(cond, () => {
  15. const tag = gen.const("tag", _`${data}${getProperty(schema)}`)
  16. gen.if(_`typeof ${tag} == "string"`, () => {
  17. gen.if(false)
  18. for (const tagValue in parentSchema.mapping) {
  19. gen.elseIf(_`${tag} === ${tagValue}`)
  20. gen.assign(valid, applyTagSchema(tagValue))
  21. }
  22. gen.endIf()
  23. })
  24. })
  25. cxt.pass(valid)
  26. function applyTagSchema(schemaProp: string): Name {
  27. const _valid = gen.name("valid")
  28. cxt.subschema(
  29. {
  30. keyword: "mapping",
  31. schemaProp,
  32. jtdDiscriminator: schema,
  33. },
  34. _valid
  35. )
  36. return _valid
  37. }
  38. },
  39. }
  40. export default def