'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
var zod = require('zod');

/**
 * Helpers for coercing string value
 * Modify the value only if it's a string, otherwise return the value as-is
 */
function coerceString(value, transform) {
  if (typeof value !== 'string') {
    return value;
  }
  if (value === '') {
    return undefined;
  }
  if (typeof transform !== 'function') {
    return value;
  }
  return transform(value);
}

/**
 * Helpers for coercing file
 * Modify the value only if it's a file, otherwise return the value as-is
 */
function coerceFile(file) {
  if (typeof File !== 'undefined' && file instanceof File && file.name === '' && file.size === 0) {
    return undefined;
  }
  return file;
}

/**
 * A file schema is usually defined as `z.instanceof(File)`
 * which is implemented based on ZodAny with `superRefine`
 * Check the `instanceOfType` function on zod for more info
 */
function isFileSchema(schema) {
  if (typeof File === 'undefined') {
    return false;
  }
  return schema._def.effect.type === 'refinement' && schema.innerType() instanceof zod.ZodAny && schema.safeParse(new File([], '')).success && !schema.safeParse('').success;
}

/**
 * Reconstruct the provided schema with additional preprocessing steps
 * This coerce empty values to undefined and transform strings to the correct type
 */
function enableTypeCoercion(type) {
  var cache = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Map();
  var result = cache.get(type);

  // Return the cached schema if it's already processed
  // This is to prevent infinite recursion caused by z.lazy()
  if (result) {
    return result;
  }
  var schema = type;
  if (type instanceof zod.ZodString || type instanceof zod.ZodLiteral || type instanceof zod.ZodEnum || type instanceof zod.ZodNativeEnum) {
    schema = zod.any().transform(value => coerceString(value)).pipe(type);
  } else if (type instanceof zod.ZodNumber) {
    schema = zod.any().transform(value => coerceString(value, text => text.trim() === '' ? Number.NaN : Number(text))).pipe(type);
  } else if (type instanceof zod.ZodBoolean) {
    schema = zod.any().transform(value => coerceString(value, text => text === 'on' ? true : text)).pipe(type);
  } else if (type instanceof zod.ZodDate) {
    schema = zod.any().transform(value => coerceString(value, timestamp => {
      var date = new Date(timestamp);

      // z.date() does not expose a quick way to set invalid_date error
      // This gets around it by returning the original string if it's invalid
      // See https://github.com/colinhacks/zod/issues/1526
      if (isNaN(date.getTime())) {
        return timestamp;
      }
      return date;
    })).pipe(type);
  } else if (type instanceof zod.ZodBigInt) {
    schema = zod.any().transform(value => coerceString(value, BigInt)).pipe(type);
  } else if (type instanceof zod.ZodArray) {
    schema = zod.any().transform(value => {
      // No preprocess needed if the value is already an array
      if (Array.isArray(value)) {
        return value;
      }
      if (typeof value === 'undefined' || typeof coerceFile(coerceString(value)) === 'undefined') {
        return [];
      }

      // Wrap it in an array otherwise
      return [value];
    }).pipe(new zod.ZodArray(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, type._def), {}, {
      type: enableTypeCoercion(type.element, cache)
    })));
  } else if (type instanceof zod.ZodObject) {
    var _shape = Object.fromEntries(Object.entries(type.shape).map(_ref => {
      var [key, def] = _ref;
      return [key,
      // @ts-expect-error see message above
      enableTypeCoercion(def, cache)];
    }));
    schema = new zod.ZodObject(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, type._def), {}, {
      shape: () => _shape
    }));
  } else if (type instanceof zod.ZodEffects) {
    if (isFileSchema(type)) {
      schema = zod.any().transform(value => coerceFile(value)).pipe(type);
    } else {
      schema = new zod.ZodEffects(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, type._def), {}, {
        schema: enableTypeCoercion(type.innerType(), cache)
      }));
    }
  } else if (type instanceof zod.ZodOptional) {
    schema = zod.any().transform(value => coerceFile(coerceString(value))).pipe(new zod.ZodOptional(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, type._def), {}, {
      innerType: enableTypeCoercion(type.unwrap(), cache)
    })));
  } else if (type instanceof zod.ZodDefault) {
    schema = zod.any().transform(value => coerceFile(coerceString(value))).pipe(new zod.ZodDefault(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, type._def), {}, {
      innerType: enableTypeCoercion(type.removeDefault(), cache)
    })));
  } else if (type instanceof zod.ZodCatch) {
    schema = new zod.ZodCatch(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, type._def), {}, {
      innerType: enableTypeCoercion(type.removeCatch(), cache)
    }));
  } else if (type instanceof zod.ZodIntersection) {
    schema = new zod.ZodIntersection(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, type._def), {}, {
      left: enableTypeCoercion(type._def.left, cache),
      right: enableTypeCoercion(type._def.right, cache)
    }));
  } else if (type instanceof zod.ZodUnion) {
    schema = new zod.ZodUnion(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, type._def), {}, {
      options: type.options.map(option => enableTypeCoercion(option, cache))
    }));
  } else if (type instanceof zod.ZodDiscriminatedUnion) {
    schema = new zod.ZodDiscriminatedUnion(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, type._def), {}, {
      options: type.options.map(option => enableTypeCoercion(option, cache)),
      optionsMap: new Map(Array.from(type.optionsMap.entries()).map(_ref2 => {
        var [discriminator, option] = _ref2;
        return [discriminator, enableTypeCoercion(option, cache)];
      }))
    }));
  } else if (type instanceof zod.ZodTuple) {
    schema = new zod.ZodTuple(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, type._def), {}, {
      items: type.items.map(item => enableTypeCoercion(item, cache))
    }));
  } else if (type instanceof zod.ZodNullable) {
    schema = new zod.ZodNullable(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, type._def), {}, {
      innerType: enableTypeCoercion(type.unwrap(), cache)
    }));
  } else if (type instanceof zod.ZodPipeline) {
    schema = new zod.ZodPipeline(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, type._def), {}, {
      in: enableTypeCoercion(type._def.in, cache),
      out: enableTypeCoercion(type._def.out, cache)
    }));
  } else if (type instanceof zod.ZodLazy) {
    schema = zod.lazy(() => enableTypeCoercion(type.schema, cache));
  }
  if (type !== schema) {
    cache.set(type, schema);
  }
  return schema;
}

exports.coerceFile = coerceFile;
exports.coerceString = coerceString;
exports.enableTypeCoercion = enableTypeCoercion;
exports.isFileSchema = isFileSchema;
