.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / table / node_modules / ajv / lib / vocabularies / jtd / discriminator.ts
diff --git a/.config/coc/extensions/node_modules/coc-prettier/node_modules/table/node_modules/ajv/lib/vocabularies/jtd/discriminator.ts b/.config/coc/extensions/node_modules/coc-prettier/node_modules/table/node_modules/ajv/lib/vocabularies/jtd/discriminator.ts
new file mode 100644 (file)
index 0000000..f487c97
--- /dev/null
@@ -0,0 +1,89 @@
+import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, not, getProperty, Name} from "../../compile/codegen"
+import {checkMetadata} from "./metadata"
+import {checkNullableObject} from "./nullable"
+import {typeErrorMessage, typeErrorParams, _JTDTypeError} from "./error"
+import {DiscrError, DiscrErrorObj} from "../discriminator/types"
+
+export type JTDDiscriminatorError =
+  | _JTDTypeError<"discriminator", "object", string>
+  | DiscrErrorObj<DiscrError.Tag>
+  | DiscrErrorObj<DiscrError.Mapping>
+
+const error: KeywordErrorDefinition = {
+  message: (cxt) => {
+    const {schema, params} = cxt
+    return params.discrError
+      ? params.discrError === DiscrError.Tag
+        ? `tag "${schema}" must be string`
+        : `value of tag "${schema}" must be in mapping`
+      : typeErrorMessage(cxt, "object")
+  },
+  params: (cxt) => {
+    const {schema, params} = cxt
+    return params.discrError
+      ? _`{error: ${params.discrError}, tag: ${schema}, tagValue: ${params.tag}}`
+      : typeErrorParams(cxt, "object")
+  },
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "discriminator",
+  schemaType: "string",
+  implements: ["mapping"],
+  error,
+  code(cxt: KeywordCxt) {
+    checkMetadata(cxt)
+    const {gen, data, schema, parentSchema} = cxt
+    const [valid, cond] = checkNullableObject(cxt, data)
+
+    gen.if(cond)
+    validateDiscriminator()
+    gen.elseIf(not(valid))
+    cxt.error()
+    gen.endIf()
+    cxt.ok(valid)
+
+    function validateDiscriminator(): void {
+      const tag = gen.const("tag", _`${data}${getProperty(schema)}`)
+      gen.if(_`${tag} === undefined`)
+      cxt.error(false, {discrError: DiscrError.Tag, tag})
+      gen.elseIf(_`typeof ${tag} == "string"`)
+      validateMapping(tag)
+      gen.else()
+      cxt.error(false, {discrError: DiscrError.Tag, tag}, {instancePath: schema})
+      gen.endIf()
+    }
+
+    function validateMapping(tag: Name): void {
+      gen.if(false)
+      for (const tagValue in parentSchema.mapping) {
+        gen.elseIf(_`${tag} === ${tagValue}`)
+        gen.assign(valid, applyTagSchema(tagValue))
+      }
+      gen.else()
+      cxt.error(
+        false,
+        {discrError: DiscrError.Mapping, tag},
+        {instancePath: schema, schemaPath: "mapping", parentSchema: true}
+      )
+      gen.endIf()
+    }
+
+    function applyTagSchema(schemaProp: string): Name {
+      const _valid = gen.name("valid")
+      cxt.subschema(
+        {
+          keyword: "mapping",
+          schemaProp,
+          jtdDiscriminator: schema,
+        },
+        _valid
+      )
+      return _valid
+    }
+  },
+}
+
+export default def