Spaces:
Running
Running
File size: 1,708 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 |
import type {MacroKeywordDefinition, SchemaObject, Schema} from "ajv"
import type {DefinitionOptions} from "./_types"
import {metaSchemaRef} from "./_util"
export default function getDef(opts?: DefinitionOptions): MacroKeywordDefinition {
return {
keyword: "deepProperties",
type: "object",
schemaType: "object",
macro: function (schema: Record<string, SchemaObject>) {
const allOf = []
for (const pointer in schema) allOf.push(getSchema(pointer, schema[pointer]))
return {allOf}
},
metaSchema: {
type: "object",
propertyNames: {type: "string", format: "json-pointer"},
additionalProperties: metaSchemaRef(opts),
},
}
}
function getSchema(jsonPointer: string, schema: SchemaObject): SchemaObject {
const segments = jsonPointer.split("/")
const rootSchema: SchemaObject = {}
let pointerSchema: SchemaObject = rootSchema
for (let i = 1; i < segments.length; i++) {
let segment: string = segments[i]
const isLast = i === segments.length - 1
segment = unescapeJsonPointer(segment)
const properties: Record<string, Schema> = (pointerSchema.properties = {})
let items: SchemaObject[] | undefined
if (/[0-9]+/.test(segment)) {
let count = +segment
items = pointerSchema.items = []
pointerSchema.type = ["object", "array"]
while (count--) items.push({})
} else {
pointerSchema.type = "object"
}
pointerSchema = isLast ? schema : {}
properties[segment] = pointerSchema
if (items) items.push(pointerSchema)
}
return rootSchema
}
function unescapeJsonPointer(str: string): string {
return str.replace(/~1/g, "/").replace(/~0/g, "~")
}
module.exports = getDef
|