-
Notifications
You must be signed in to change notification settings - Fork 408
/
Copy pathJSONSchema.ts
144 lines (127 loc) · 3.42 KB
/
JSONSchema.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import {JSONSchema4, JSONSchema4Type, JSONSchema4TypeName} from 'json-schema'
import {isPlainObject, memoize} from 'lodash'
export type SchemaType =
| 'ALL_OF'
| 'UNNAMED_SCHEMA'
| 'ANY'
| 'ANY_OF'
| 'BOOLEAN'
| 'NAMED_ENUM'
| 'NAMED_SCHEMA'
| 'NEVER'
| 'NULL'
| 'NUMBER'
| 'STRING'
| 'OBJECT'
| 'ONE_OF'
| 'TYPED_ARRAY'
| 'REFERENCE'
| 'UNION'
| 'UNNAMED_ENUM'
| 'UNTYPED_ARRAY'
| 'CUSTOM_TYPE'
export type JSONSchemaTypeName = JSONSchema4TypeName
export type JSONSchemaType = JSONSchema4Type
export interface JSONSchema extends JSONSchema4 {
/**
* schema extension to support numeric enums
*/
tsEnumNames?: string[]
/**
* schema extension to support custom types
*/
tsType?: string
/**
* property exists at least in https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.3
*/
deprecated?: boolean
}
export const Parent = Symbol('Parent')
export interface LinkedJSONSchema extends JSONSchema {
/**
* A reference to this schema's parent node, for convenience.
* `null` when this is the root schema.
*/
[Parent]: LinkedJSONSchema | null
additionalItems?: boolean | LinkedJSONSchema
additionalProperties?: boolean | LinkedJSONSchema
items?: LinkedJSONSchema | LinkedJSONSchema[]
definitions?: {
[k: string]: LinkedJSONSchema
}
properties?: {
[k: string]: LinkedJSONSchema
}
patternProperties?: {
[k: string]: LinkedJSONSchema
}
dependencies?: {
[k: string]: LinkedJSONSchema | string[]
}
allOf?: LinkedJSONSchema[]
anyOf?: LinkedJSONSchema[]
oneOf?: LinkedJSONSchema[]
not?: LinkedJSONSchema
}
export interface NormalizedJSONSchema extends LinkedJSONSchema {
additionalItems?: boolean | NormalizedJSONSchema
additionalProperties: boolean | NormalizedJSONSchema
extends?: string[]
items?: NormalizedJSONSchema | NormalizedJSONSchema[]
$defs?: {
[k: string]: NormalizedJSONSchema
}
properties?: {
[k: string]: NormalizedJSONSchema
}
patternProperties?: {
[k: string]: NormalizedJSONSchema
}
dependencies?: {
[k: string]: NormalizedJSONSchema | string[]
}
allOf?: NormalizedJSONSchema[]
anyOf?: NormalizedJSONSchema[]
oneOf?: NormalizedJSONSchema[]
not?: NormalizedJSONSchema
required: string[]
// Removed by normalizer
definitions: never
id: never
}
export interface EnumJSONSchema extends NormalizedJSONSchema {
enum: any[]
}
export interface NamedEnumJSONSchema extends NormalizedJSONSchema {
tsEnumNames: string[]
}
export interface SchemaSchema extends NormalizedJSONSchema {
properties: {
[k: string]: NormalizedJSONSchema
}
required: string[]
}
export interface JSONSchemaWithDefinitions extends NormalizedJSONSchema {
$defs: {
[k: string]: NormalizedJSONSchema
}
}
export interface CustomTypeJSONSchema extends NormalizedJSONSchema {
tsType: string
}
export const getRootSchema = memoize((schema: LinkedJSONSchema): LinkedJSONSchema => {
const parent = schema[Parent]
if (!parent) {
return schema
}
return getRootSchema(parent)
})
export function isBoolean(schema: LinkedJSONSchema | JSONSchemaType): schema is boolean {
return schema === true || schema === false
}
export function isPrimitive(schema: LinkedJSONSchema | JSONSchemaType): schema is JSONSchemaType {
return !isPlainObject(schema)
}
export function isCompound(schema: JSONSchema): boolean {
return Array.isArray(schema.type) || 'anyOf' in schema || 'oneOf' in schema
}