12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 |
- 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
|