/* eslint-disable @typescript-eslint/no-explicit-any */ import type { NonEmptyReadonlyArray } from "effect/Array" import * as Option from "effect/Option" import type { Misc, Union } from "ts-toolbelt" import type * as SET from "./Set.js" // type SomeObject = { // 0: Option.Option // a: { // b: Option.Option // g: Option.Option> // h: Option.Option<{ i: Option.Option }> // } // c: { d: Array }>> } // } // type test0 = Transform // type test1 = Transform type OptOf = Union.Exclude< A extends Option.Some ? X | null : A, Option.None > // eslint-disable-next-line @typescript-eslint/no-explicit-any export type TransformRoot = O extends Option.Option ? Transform> : Transform export type Transform = O extends Misc.BuiltIn | Misc.Primitive ? O : { [K in keyof O]: OptOf extends infer X ? X extends (infer Y)[] ? OptOf>[] : X extends NonEmptyReadonlyArray ? NonEmptyReadonlyArray>> : X extends SET.Set ? SET.Set>> : X extends readonly (infer Y)[] ? readonly OptOf>[] : Transform : never } export const encodeOptsAsNullable = (root: T): TransformRoot => encodeOptsAsNullable_(root, new Map()) const encodeOptsAsNullable_ = (value: any, cacheMap: Map): any => { const cacheEntry = cacheMap.get(value) if (cacheEntry) { return cacheEntry } if (Array.isArray(value)) { const newAr: typeof value = [] cacheMap.set(value, newAr) value.forEach((x) => newAr.push(encodeOptsAsNullable_(x, cacheMap))) return newAr } if ( value instanceof Date || typeof value === "function" || (typeof value === "object" && value !== null && "then" in value && typeof value.then === "function") ) { return value } if (value instanceof Set) { const newValue = [...value] cacheMap.set(value, newValue) return newValue } if (value instanceof Object) { if (value._tag === "Some" || value._tag === "None") { const v = value as Option.Option return encodeOptsAsNullable_(Option.getOrNull(v), cacheMap) } const newObj = {} as Record cacheMap.set(value, newObj) Object.keys(value).forEach((key) => { newObj[key] = encodeOptsAsNullable_(value[key], cacheMap) }) return newObj } return value }