var _a, _b;
const CRUD_HTTP_ERROR_MARKER = /* @__PURE__ */ Symbol.for("@open-mercato/CrudHttpError");
class CrudHttpError extends (_b = Error, _a = CRUD_HTTP_ERROR_MARKER, _b) {
  constructor(status, body, options) {
    const normalizedBody = typeof body === "string" ? { error: body } : body ?? {};
    super(typeof body === "string" ? body : normalizedBody.error ?? "Request failed", options);
    this[_a] = true;
    this.status = status;
    this.body = normalizedBody;
  }
}
function isCrudHttpError(err) {
  return !!err && typeof err === "object" && err[CRUD_HTTP_ERROR_MARKER] === true;
}
function badRequest(message) {
  return new CrudHttpError(400, { error: message });
}
function forbidden(message = "Forbidden") {
  return new CrudHttpError(403, { error: message });
}
function notFound(message = "Not found") {
  return new CrudHttpError(404, { error: message });
}
function conflict(message) {
  return new CrudHttpError(409, { error: message });
}
const POSTGRES_UNIQUE_VIOLATION = "23505";
function isUniqueViolation(err, constraintName) {
  if (!err || typeof err !== "object") return false;
  const candidates = [err, err.cause, err.previous];
  for (const candidate of candidates) {
    if (!candidate || typeof candidate !== "object") continue;
    const record = candidate;
    if (record.code === POSTGRES_UNIQUE_VIOLATION) {
      if (!constraintName) return true;
      const constraint = typeof record.constraint === "string" ? record.constraint : "";
      const detail = typeof record.detail === "string" ? record.detail : "";
      const message = typeof record.message === "string" ? record.message : "";
      return constraint === constraintName || detail.includes(constraintName) || message.includes(constraintName);
    }
  }
  return false;
}
function assertFound(value, message) {
  if (!value) throw notFound(message);
  return value;
}
export {
  CrudHttpError,
  assertFound,
  badRequest,
  conflict,
  forbidden,
  isCrudHttpError,
  isUniqueViolation,
  notFound
};
//# sourceMappingURL=errors.js.map
