import { runSync, gen, flatMap, tryPromise, service, tapError, sync, map, withTrace, TaggedError, filterOrFail, Error as Error$1, try as try_ } from "../../effect/dist-esm-Micro.js";
import { isRecord, isNumber, isString } from "../../effect/dist-esm-Predicate.js";
import { Tag } from "../../effect/dist-esm-Context.js";
(class extends TaggedError("InvalidRouteConfig") {
  constructor(type, field) {
    const reason = field ? `Expected route config to have a ${field} for key ${type} but none was found.` : `Encountered an invalid route config during backfilling. ${type} was not found.`;
    super({ reason });
  }
});
(class extends TaggedError("UnknownFileType") {
  constructor(fileName) {
    const reason = `Could not determine type for ${fileName}`;
    super({ reason });
  }
});
(class extends TaggedError("InvalidFileType") {
  constructor(fileType, fileName) {
    const reason = `File type ${fileType} not allowed for ${fileName}`;
    super({ reason });
  }
});
(class extends TaggedError("InvalidFileSize") {
  constructor(fileSize) {
    const reason = `Invalid file size: ${fileSize}`;
    super({ reason });
  }
});
var InvalidURLError = class extends TaggedError("InvalidURL") {
  constructor(attemptedUrl) {
    super({ reason: `Failed to parse '${attemptedUrl}' as a URL.` });
  }
};
(class extends TaggedError("RetryError") {
});
var FetchError = class extends TaggedError("FetchError") {
};
var InvalidJsonError = class extends TaggedError("InvalidJson") {
};
var BadRequestError = class extends TaggedError("BadRequestError") {
  getMessage() {
    if (isRecord(this.json)) {
      if (typeof this.json.message === "string") return this.json.message;
    }
    return this.message;
  }
};
var UploadPausedError = class extends TaggedError("UploadAborted") {
};
var UploadAbortedError = class extends TaggedError("UploadAborted") {
};
async function safeParseJSON(input) {
  const text$1 = await input.text();
  try {
    return JSON.parse(text$1);
  } catch (err) {
    console.error(`Error parsing JSON, got '${text$1}'`, err);
    return /* @__PURE__ */ new Error(`Error parsing JSON, got '${text$1}'`);
  }
}
function semverLite(required, toCheck) {
  const semverRegex = /(\d+)\.?(\d+)?\.?(\d+)?/;
  const requiredMatch = semverRegex.exec(required);
  if (!requiredMatch?.[0]) throw new Error(`Invalid semver requirement: ${required}`);
  const toCheckMatch = semverRegex.exec(toCheck);
  if (!toCheckMatch?.[0]) throw new Error(`Invalid semver to check: ${toCheck}`);
  const [_1, rMajor, rMinor, rPatch] = requiredMatch;
  const [_2, cMajor, cMinor, cPatch] = toCheckMatch;
  if (required.startsWith("^")) {
    if (rMajor !== cMajor) return false;
    if (rMinor && cMinor && rMinor > cMinor) return false;
    return true;
  }
  if (required.startsWith("~")) {
    if (rMajor !== cMajor) return false;
    if (rMinor !== cMinor) return false;
    return true;
  }
  return rMajor === cMajor && rMinor === cMinor && rPatch === cPatch;
}
function warnIfInvalidPeerDependency(pkg, required, toCheck) {
  if (!semverLite(required, toCheck)) console.warn(`!!!WARNING::: ${pkg} requires "uploadthing@${required}", but version "${toCheck}" is installed`);
}
const getFullApiUrl = (maybeUrl) => gen(function* () {
  const base = (() => {
    if (typeof window !== "undefined") return window.location.origin;
    if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`;
    return "http://localhost:3000";
  })();
  const url = yield* try_({
    try: () => new URL(maybeUrl ?? "/api/uploadthing", base),
    catch: () => new InvalidURLError(maybeUrl ?? "/api/uploadthing")
  });
  if (url.pathname === "/") url.pathname = "/api/uploadthing";
  return url;
});
const resolveMaybeUrlArg = (maybeUrl) => {
  return maybeUrl instanceof URL ? maybeUrl : runSync(getFullApiUrl(maybeUrl));
};
function noop() {
}
function createIdentityProxy() {
  return new Proxy(noop, { get: (_, prop) => prop });
}
function unwrap(x, ...args) {
  return typeof x === "function" ? x(...args) : x;
}
const ERROR_CODES = {
  BAD_REQUEST: 400,
  NOT_FOUND: 404,
  FORBIDDEN: 403,
  INTERNAL_SERVER_ERROR: 500,
  INTERNAL_CLIENT_ERROR: 500,
  TOO_LARGE: 413,
  TOO_SMALL: 400,
  TOO_MANY_FILES: 400,
  KEY_TOO_LONG: 400,
  URL_GENERATION_FAILED: 500,
  UPLOAD_FAILED: 500,
  MISSING_ENV: 500,
  INVALID_SERVER_CONFIG: 500,
  FILE_LIMIT_EXCEEDED: 500
};
function messageFromUnknown(cause, fallback) {
  if (typeof cause === "string") return cause;
  if (cause instanceof Error) return cause.message;
  if (cause && typeof cause === "object" && "message" in cause && typeof cause.message === "string") return cause.message;
  return fallback ?? "An unknown error occurred";
}
var UploadThingError = class UploadThingError2 extends Error$1 {
  _tag = "UploadThingError";
  name = "UploadThingError";
  cause;
  code;
  data;
  constructor(initOpts) {
    const opts = typeof initOpts === "string" ? {
      code: "INTERNAL_SERVER_ERROR",
      message: initOpts
    } : initOpts;
    const message = opts.message ?? messageFromUnknown(opts.cause, opts.code);
    super({ message });
    this.code = opts.code;
    this.data = opts.data;
    if (opts.cause instanceof Error) this.cause = opts.cause;
    else if (isRecord(opts.cause) && isNumber(opts.cause.status) && isString(opts.cause.statusText)) this.cause = /* @__PURE__ */ new Error(`Response ${opts.cause.status} ${opts.cause.statusText}`);
    else if (isString(opts.cause)) this.cause = new Error(opts.cause);
    else this.cause = opts.cause;
  }
  static toObject(error) {
    return {
      code: error.code,
      message: error.message,
      data: error.data
    };
  }
  static serialize(error) {
    return JSON.stringify(UploadThingError2.toObject(error));
  }
};
function getErrorTypeFromStatusCode(statusCode) {
  for (const [code, status] of Object.entries(ERROR_CODES)) if (status === statusCode) return code;
  return "INTERNAL_SERVER_ERROR";
}
const INTERNAL_DO_NOT_USE__fatalClientError = (e) => new UploadThingError({
  code: "INTERNAL_CLIENT_ERROR",
  message: "Something went wrong. Please report this to UploadThing.",
  cause: e
});
var FetchContext = class extends Tag("uploadthing/Fetch")() {
};
const fetchEff = (input, init) => flatMap(service(FetchContext), (fetch) => {
  const headers = new Headers(init?.headers ?? []);
  const reqInfo = {
    url: input.toString(),
    method: init?.method,
    body: init?.body,
    headers: Object.fromEntries(headers)
  };
  return tryPromise({
    try: (signal) => fetch(input, {
      ...init,
      headers,
      signal
    }),
    catch: (error) => new FetchError({
      error: error instanceof Error ? {
        ...error,
        name: error.name,
        message: error.message,
        stack: error.stack
      } : error,
      input: reqInfo
    })
  }).pipe(tapError((e) => sync(() => console.error(e.input))), map((res) => Object.assign(res, { requestUrl: reqInfo.url })), withTrace("fetch"));
});
const parseResponseJson = (res) => tryPromise({
  try: async () => {
    const json = await res.json();
    return {
      json,
      ok: res.ok,
      status: res.status
    };
  },
  catch: (error) => new InvalidJsonError({
    error,
    input: res.requestUrl
  })
}).pipe(filterOrFail(({ ok }) => ok, ({ json, status }) => new BadRequestError({
  status,
  message: `Request to ${res.requestUrl} failed with status ${status}`,
  json
})), map(({ json }) => json), withTrace("parseJson"));
const roundProgress = (progress, granularity) => {
  if (granularity === "all") return progress;
  if (granularity === "fine") return Math.round(progress);
  return Math.floor(progress / 10) * 10;
};
new TextEncoder();
export {
  BadRequestError,
  FetchContext,
  FetchError,
  INTERNAL_DO_NOT_USE__fatalClientError,
  InvalidJsonError,
  InvalidURLError,
  UploadAbortedError,
  UploadPausedError,
  UploadThingError,
  createIdentityProxy,
  fetchEff,
  getErrorTypeFromStatusCode,
  getFullApiUrl,
  noop,
  parseResponseJson,
  resolveMaybeUrlArg,
  roundProgress,
  safeParseJSON,
  semverLite,
  unwrap,
  warnIfInvalidPeerDependency
};
//# sourceMappingURL=dist-index.js.map
