import * as v from "@badrap/valita";
export * from "@badrap/valita";
function toDisplay(value) {
  switch (typeof value) {
    case "string":
    case "number":
    case "boolean":
      return JSON.stringify(value);
    case "undefined":
      return "undefined";
    case "bigint":
      return value.toString() + "n";
    default:
      if (value === null) {
        return "null";
      }
      if (Array.isArray(value)) {
        return "array";
      }
      return typeof value;
  }
}
function toDisplayAtPath(v2, path) {
  if (!path?.length) {
    return toDisplay(v2);
  }
  let cur = v2;
  for (const p of path) {
    cur = cur[p];
  }
  return toDisplay(cur);
}
function displayList(word, expected, toDisplay2 = (x) => String(x)) {
  if (expected.length === 1) {
    return toDisplay2(expected[0]);
  }
  const suffix = `${toDisplay2(
    expected[expected.length - 2]
  )} ${word} ${toDisplay2(expected[expected.length - 1])}`;
  if (expected.length === 2) {
    return suffix;
  }
  return `${expected.slice(0, -2).map(toDisplay2).join(", ")}, ${suffix}`;
}
function getMessage(err, v2, schema, mode) {
  const firstIssue = err.issues[0];
  const { path } = firstIssue;
  const atPath = path?.length ? ` at ${path.join(".")}` : "";
  switch (firstIssue.code) {
    case "invalid_type":
      return `Expected ${displayList(
        "or",
        firstIssue.expected
      )}${atPath}. Got ${toDisplayAtPath(v2, path)}`;
    case "missing_value": {
      const atPath2 = path && path.length > 1 ? ` at ${path.slice(0, -1).join(".")}` : "";
      if (firstIssue.path?.length) {
        return `Missing property ${firstIssue.path.at(-1)}${atPath2}`;
      }
      return `TODO Unknown missing property${atPath2}`;
    }
    case "invalid_literal":
      return `Expected literal value ${displayList(
        "or",
        firstIssue.expected,
        toDisplay
      )}${atPath} Got ${toDisplayAtPath(v2, path)}`;
    case "invalid_length": {
      return `Expected array with length ${firstIssue.minLength === firstIssue.maxLength ? firstIssue.minLength : `between ${firstIssue.minLength} and ${firstIssue.maxLength}`}${atPath}. Got array with length ${v2.length}`;
    }
    case "unrecognized_keys":
      if (firstIssue.keys.length === 1) {
        return `Unexpected property ${firstIssue.keys[0]}${atPath}`;
      }
      return `Unexpected properties ${displayList(
        "and",
        firstIssue.keys
      )}${atPath}`;
    case "invalid_union":
      return schema.name === "union" ? getDeepestUnionParseError(v2, schema, mode ?? "strict") : `Invalid union value${atPath}`;
    case "custom_error": {
      const { error } = firstIssue;
      const message = !error ? "unknown" : typeof error === "string" ? error : error.message ?? "unknown";
      return `${message}${atPath}. Got ${toDisplayAtPath(v2, path)}`;
    }
  }
}
function getDeepestUnionParseError(value, schema, mode) {
  const failures = [];
  for (const type of schema.options) {
    const r = type.try(value, { mode });
    if (!r.ok) {
      failures.push({ type, err: r });
    }
  }
  if (failures.length) {
    failures.sort(pathCmp);
    if (failures.length === 1 || pathCmp(failures[0], failures[1]) < 0) {
      return getMessage(failures[0].err, value, failures[0].type, mode);
    }
  }
  try {
    const str = JSON.stringify(value);
    return `Invalid union value: ${str}`;
  } catch {
    return `Invalid union value`;
  }
}
function pathCmp(a, b) {
  const aPath = a.err.issues[0].path;
  const bPath = b.err.issues[0].path;
  if (aPath.length !== bPath.length) {
    return bPath.length - aPath.length;
  }
  for (let i = 0; i < aPath.length; i++) {
    if (bPath[i] > aPath[i]) {
      return -1;
    }
    if (bPath[i] < aPath[i]) {
      return 1;
    }
  }
  return 0;
}
function parse(value, schema, mode) {
  const res = test(value, schema, mode);
  if (!res.ok) {
    throw new TypeError(res.error);
  }
  return res.value;
}
function assert(value, schema, mode) {
  parse(value, schema, mode);
}
function test(value, schema, mode) {
  const res = schema.try(value, mode ? { mode } : void 0);
  if (!res.ok) {
    return {
      ok: false,
      error: getMessage(res, value, schema, mode)
    };
  }
  return res;
}
function testOptional(value, schema, mode) {
  let flags = 1;
  const res = schema.func(value, flags);
  if (res === void 0) {
    return { ok: true, value };
  } else if (res.ok) {
    return res;
  }
  const err = new v.ValitaError(res);
  return { ok: false, error: getMessage(err, value, schema, mode) };
}
function readonly(t) {
  return t;
}
function readonlyObject(t) {
  return v.object(t);
}
function readonlyArray(t) {
  return v.array(t);
}
function readonlyRecord(t) {
  return v.record(t);
}
const AbstractType = Object.getPrototypeOf(
  Object.getPrototypeOf(v.string().optional())
).constructor;
function instanceOfAbstractType(obj) {
  return obj instanceof AbstractType;
}
function deepPartial(s) {
  const shape = {};
  for (const [key, type] of Object.entries(s.shape)) {
    if (type.name === "object") {
      shape[key] = deepPartial(type).optional();
    } else {
      shape[key] = type.optional();
    }
  }
  return v.object(shape);
}
function literalUnion(...literals) {
  return v.union(...literals.map(v.literal));
}
export {
  assert,
  deepPartial,
  instanceOfAbstractType,
  literalUnion,
  parse,
  readonly,
  readonlyArray,
  readonlyObject,
  readonlyRecord,
  test,
  testOptional
};
//# sourceMappingURL=valita.js.map
