47 lines
1.1 KiB
TypeScript
Executable File
47 lines
1.1 KiB
TypeScript
Executable File
import { z } from 'zod';
|
|
|
|
import { parseSchema } from './parse-schema';
|
|
import type { JsonSchemaObject, JsonSchema, Refs } from '../types';
|
|
import { half } from '../utils/half';
|
|
|
|
const originalIndex = Symbol('Original index');
|
|
|
|
const ensureOriginalIndex = (arr: JsonSchema[]) => {
|
|
const newArr = [];
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
const item = arr[i];
|
|
if (typeof item === 'boolean') {
|
|
newArr.push(item ? { [originalIndex]: i } : { [originalIndex]: i, not: {} });
|
|
} else if (originalIndex in item) {
|
|
return arr;
|
|
} else {
|
|
newArr.push({ ...item, [originalIndex]: i });
|
|
}
|
|
}
|
|
|
|
return newArr;
|
|
};
|
|
|
|
export function parseAllOf(
|
|
jsonSchema: JsonSchemaObject & { allOf: JsonSchema[] },
|
|
refs: Refs,
|
|
): z.ZodTypeAny {
|
|
if (jsonSchema.allOf.length === 0) {
|
|
return z.never();
|
|
}
|
|
|
|
if (jsonSchema.allOf.length === 1) {
|
|
const item = jsonSchema.allOf[0];
|
|
|
|
return parseSchema(item, {
|
|
...refs,
|
|
path: [...refs.path, 'allOf', (item as never)[originalIndex]],
|
|
});
|
|
}
|
|
|
|
const [left, right] = half(ensureOriginalIndex(jsonSchema.allOf));
|
|
|
|
return z.intersection(parseAllOf({ allOf: left }, refs), parseAllOf({ allOf: right }, refs));
|
|
}
|