import { Sure } from './core.js' import { object } from './object.js' import { PrettifyRec, objMapEntries } from './utils.js' export type ExtractPrimitives = { [t in keyof TSchema]: InferJustMeta } // prettier-ignore export type InferJustMetaOld > = // for objects T extends Sure ?{ type: 'object' schema: ExtractPrimitives } // for optional :T extends Sure ?{ type: 'optional' schema: InferJustMeta } // for array :T extends Sure ? { type: 'array' schema: InferJustMeta } // for any other type : T extends Sure ? Meta : // Here we'll not be able to differentiate MetaNever from MetaObj // Both will be extracted as `undefined` undefined // prettier-ignore export type InferJustMeta< T, // extends Sure > = T extends Sure ? // for objects Meta extends { type: 'object' schema: infer CSchema } ? { type: 'object' schema: ExtractPrimitives } : // for optional Meta extends { type: 'optional' schema: infer CSchema } ? { type: 'optional' schema: InferJustMeta } : // for array Meta extends { type: 'array' schema: infer CSchema } ? { type: 'array' schema: InferJustMeta } : // for any other type Meta : // Here we'll not be able to differentiate MetaNever from MetaObj // Both will be extracted as `undefined` undefined export function justMeta>( insure: TSchema ): PrettifyRec> { // object.getMeta(insure) -> if not object -> null object // @ts-expect-error more explicit? if (insure.meta?.type === 'object') { const { schema, ...rest } = insure.meta as any // @ts-expect-error more explicit? const ret = objMapEntries(schema, ([key, value]) => { return [key, justMeta(value)] }) return { schema: ret, ...rest } } // @ts-expect-error more explicit? if (insure.meta?.type === 'optional') { const { schema, ...rest } = insure.meta as any return { schema: justMeta(schema), ...rest, } } // @ts-expect-error more explicit? if (insure.meta?.type === 'array') { const { schema, ...rest } = insure.meta as any return { schema: justMeta(schema), ...rest, } } if (insure.meta) { return insure.meta as any } return undefined as any } export function metaToJsonSchema(meta: TMeta): any { if (!meta) { return { type: 'unknown', } } // @ts-expect-error figure out if (meta.type === 'object') { // go through each and check if it's optional const optionalKeys: string[] = [] // @ts-expect-error asdfsd const withoutOptional = objMapEntries(meta.schema as any, ([key, value]) => { if (value.type === 'optional') { // @ts-expect-error asdfsd optionalKeys.push(key) return [key, value.schema] } return [key, value] }) const required = Object.keys(withoutOptional).filter(key => !optionalKeys.includes(key)) return { type: 'object', properties: objMapEntries(withoutOptional, ([key, value]) => { return [key, metaToJsonSchema(value)] }), required, } } // @ts-expect-error figure out if (meta.type === 'array') { return { type: 'array', // @ts-expect-error rename schema to items here items: metaToJsonSchema(meta.schema), } } // return meta }