-
-
Notifications
You must be signed in to change notification settings - Fork 64
/
ajv.ts
106 lines (93 loc) · 3.14 KB
/
ajv.ts
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import type AjvCore from "ajv/dist/core"
import type {ParsedArgs} from "minimist"
import type {SchemaSpec} from "./types"
import Ajv7, {Plugin} from "ajv"
import Ajv2019 from "ajv/dist/2019"
import Ajv2020 from "ajv/dist/2020"
import AjvJTD from "ajv/dist/jtd"
import {Service} from "ts-node"
import {getOptions} from "./options"
import * as util from "./util"
import * as path from "path"
import * as draft6metaSchema from "ajv/lib/refs/json-schema-draft-06.json"
type AjvMethod = "addSchema" | "addMetaSchema"
// copied from https://github.com/babel/babel/blob/d8da63c929f2d28c401571e2a43166678c555bc4/packages/babel-helpers/src/helpers.js#L602-L606
/* istanbul ignore next */
const interopRequireDefault = (obj: any): {default: any} =>
obj && obj.__esModule ? obj : {default: obj}
const importDefault = <T = unknown>(moduleName: string): T =>
interopRequireDefault(require(moduleName)).default
const AjvClass: {[S in SchemaSpec]?: typeof AjvCore} = {
jtd: AjvJTD,
draft7: Ajv7,
draft2019: Ajv2019,
draft2020: Ajv2020,
}
export default function (argv: ParsedArgs): AjvCore {
const opts = getOptions(argv)
if (argv.o) opts.code.source = true
const Ajv: typeof AjvCore = AjvClass[argv.spec as SchemaSpec] || Ajv7
const ajv = new Ajv(opts)
let invalid: boolean | undefined
if (argv.spec !== "jtd") ajv.addMetaSchema(draft6metaSchema)
addSchemas(argv.m, "addMetaSchema", "meta-schema")
addSchemas(argv.r, "addSchema", "schema")
customFormatsKeywords(argv.c)
if (invalid) process.exit(1)
return ajv
function addSchemas(
args: string | string[] | undefined,
method: AjvMethod,
fileType: string
): void {
if (!args) return
const files = util.getFiles(args)
files.forEach((file) => {
const schema = util.openFile(file, fileType)
try {
ajv[method](schema)
} catch (err) {
console.error(`${fileType} ${file} is invalid`)
console.error(`error: ${(err as Error).message}`)
invalid = true
}
})
}
function customFormatsKeywords(args: string | string[] | undefined): void {
if (!args) return
const files = util.getFiles(args)
files.forEach((file) => {
if (file[0] === ".") file = path.resolve(process.cwd(), file)
try {
if (file.endsWith(".ts")) {
requireTypeScriptKeyword(file)
} else {
require(file)(ajv)
}
} catch (err) {
console.error(`module ${file} is invalid; it should export function`)
console.error(`error: ${(err as Error).message}`)
invalid = true
}
})
}
function requireTypeScriptKeyword(file: string): void {
let registerer: Service
try {
registerer = require("ts-node").register()
} catch (err) {
/* istanbul ignore next */
if ((err as {code?: string; message: string}).code === "MODULE_NOT_FOUND") {
throw new Error(
`'ts-node' is required for the TypeScript configuration files. Make sure it is installed\nError: ${
(err as Error).message
}`
)
}
throw err
}
registerer.enabled(true)
importDefault<Plugin<undefined>>(file)(ajv)
registerer.enabled(false)
}
}