import { Static, TModule, TSchema } from "typebox";
import { Compile, Validator } from "typebox/compile";

//#region src/index.d.ts
declare const copySchema: <T>(node: T) => T;
interface BaseSchema {
  '~kind': string;
  id?: string;
  $id?: string;
  type?: string;
  $schema?: string;
  const?: unknown[];
  pattern?: string;
  additionalItems?: boolean | AnySchema;
  items?: AnySchema | AnySchema[];
  required?: string[];
  additionalProperties?: boolean | AnySchema;
  definitions?: {
    [name: string]: AnySchema;
  };
  properties?: {
    [name: string]: AnySchema;
  };
  patternProperties?: {
    [name: string]: AnySchema;
  };
  dependencies?: {
    [name: string]: AnySchema | string[];
  };
  enum?: any[];
  allOf?: AnySchema[];
  anyOf?: AnySchema[];
  oneOf?: AnySchema[];
  not?: AnySchema;
  $ref?: string;
  $defs?: Record<string, AnySchema>;
}
type AnySchema = TSchema & BaseSchema;
declare const mergeObjectIntersection: (schema: AnySchema) => AnySchema;
type MaybeArray<T> = T | T[];
interface Instruction<Emit extends boolean = false> {
  optionals: string[];
  optionalsInArray: string[][];
  parentIsOptional: boolean;
  array: number;
  unions: Validator<any>[][];
  unionKeys: Record<string, 1>;
  sanitize: MaybeArray<(v: string) => string> | undefined;
  fromUnion?: boolean;
  emit?: Emit;
  /**
   * Apply a TypeBox codec's `~codec` transform at codec leaves during the
   * mirror walk, instead of only cleaning the value.
   *
   * @default undefined — pure clean, no transform
   */
  transform?: 'decode' | 'encode';
  /**
   * Codec transform functions collected during codegen, referenced from the
   * generated source by index as `d.codecs[i]`
   */
  codecs: Function[];
  /**
   * TypeCompiler is required when using Union
   *
   * Left as opt-in to reduce bundle size
   * many end-user doesn't use Union
   *
   * @default undefined
   */
  Compile?: typeof Compile;
  typeCompilerWanred?: boolean;
  modules?: TModule<{}>;
  definitions: Record<string, AnySchema>;
  /**
   * Shared cyclic codegen state: generated per-definition mirror
   * functions, grouped by `$defs` object identity
   */
  cyclic: CyclicContext;
  /**
   * `$defs` group the current cyclic definition body is generated
   * against, used to resolve `Ref` nodes to function calls
   */
  cyclicDefs?: CyclicGroup;
  recursion: number;
  /**
   * @default 8
   */
  recursionLimit: number;
  /**
   * If incorrect type is passed to Union value, should it be removed?
   *
   * If you check a value later, it's recommended to set this to `false`
   * otherwise, set this to true
   *
   * @default false
   */
  removeUnknownUnionType: boolean;
}
declare function deepClone<T>(source: T, weak?: WeakMap<object, any>): T;
interface CyclicGroup {
  defs: Record<string, AnySchema>;
  names: Record<string, string>;
}
interface CyclicContext {
  groups: Map<object, CyclicGroup>;
  fns: string[];
  count: number;
}
interface Manifest {
  source: string;
  externals: {
    unions: Validator<any, TSchema, unknown, unknown>[][];
    codecs?: Function[];
    hof?: Record<string, Function>;
  };
}
declare const createMirror: <T extends TSchema, Emit extends boolean = false>(schema: T, {
  Compile,
  modules,
  definitions,
  sanitize,
  recursionLimit,
  removeUnknownUnionType,
  emit,
  decode,
  encode
}?: Partial<Pick<Instruction<Emit>, "Compile" | "definitions" | "sanitize" | "modules" | "recursionLimit" | "removeUnknownUnionType" | "emit">> & {
  /**
   * Apply each codec's `~codec.decode` at codec leaves (parse input,
   * e.g. numeric string → number) on top of the clean walk
   *
   * The value is assumed to have already passed `Check`
   *
   * @default false
   */
  decode?: boolean;
  /**
   * Apply each codec's `~codec.encode` at codec leaves
   *
   * @default false
   */
  encode?: boolean;
}) => Emit extends true ? Manifest : (v: Static<T>) => Static<T>;
//#endregion
export { Instruction, Manifest, copySchema, createMirror, createMirror as default, deepClone, mergeObjectIntersection };