Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
153 lines
3.7 KiB
Plaintext
153 lines
3.7 KiB
Plaintext
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 const Types = Symbol('Types')
|
|
export const Intersection = Symbol('Intersection')
|
|
|
|
/**
|
|
* Normalized JSON schema.
|
|
*
|
|
* Note: `definitions` and `id` are removed by the normalizer. Use `$defs` and `$id` instead.
|
|
*/
|
|
export interface NormalizedJSONSchema extends Omit<LinkedJSONSchema, 'definitions' | 'id'> {
|
|
[Intersection]?: NormalizedJSONSchema
|
|
[Parent]: NormalizedJSONSchema | null
|
|
[Types]: ReadonlySet<SchemaType>
|
|
|
|
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[]
|
|
}
|
|
|
|
export interface EnumJSONSchema extends NormalizedJSONSchema {
|
|
enum: JSONSchema4Type[]
|
|
}
|
|
|
|
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: NormalizedJSONSchema): NormalizedJSONSchema => {
|
|
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
|
|
}
|