File size: 1,501 Bytes
1df763a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import type {FuncKeywordDefinition} from "ajv"

type Constructor = new (...args: any[]) => any

const CONSTRUCTORS: Record<string, Constructor | undefined> = {
  Object,
  Array,
  Function,
  Number,
  String,
  Date,
  RegExp,
}

/* istanbul ignore else */
if (typeof Buffer != "undefined") CONSTRUCTORS.Buffer = Buffer

/* istanbul ignore else */
if (typeof Promise != "undefined") CONSTRUCTORS.Promise = Promise

const getDef: (() => FuncKeywordDefinition) & {
  CONSTRUCTORS: typeof CONSTRUCTORS
} = Object.assign(_getDef, {CONSTRUCTORS})

function _getDef(): FuncKeywordDefinition {
  return {
    keyword: "instanceof",
    schemaType: ["string", "array"],
    compile(schema: string | string[]) {
      if (typeof schema == "string") {
        const C = getConstructor(schema)
        return (data) => data instanceof C
      }

      if (Array.isArray(schema)) {
        const constructors = schema.map(getConstructor)
        return (data) => {
          for (const C of constructors) {
            if (data instanceof C) return true
          }
          return false
        }
      }

      /* istanbul ignore next */
      throw new Error("ajv implementation error")
    },
    metaSchema: {
      anyOf: [{type: "string"}, {type: "array", items: {type: "string"}}],
    },
  }
}

function getConstructor(c: string): Constructor {
  const C = CONSTRUCTORS[c]
  if (C) return C
  throw new Error(`invalid "instanceof" keyword value ${c}`)
}

export default getDef
module.exports = getDef