import { Err } from "../result-fCtNge01.js";

//#region src/error/types.d.ts

/**
 * Base error structure for all errors in the Result system.
 *
 * Provides a consistent structure for error objects that are JSON-serializable
 * and contain comprehensive debugging information.
 *
 * @example
 * ```ts
 * const error: BaseError = {
 *   name: "DatabaseError",
 *   message: "Connection failed",
 *   context: { host: "localhost", port: 5432 },
 *   cause: originalError
 * };
 * ```
 */
type BaseError = Readonly<{
  name: string;
  message: string;
  context?: Record<string, unknown>;
  cause: unknown;
}>;
/**
 * Creates a tagged error type for type-safe error handling.
 * Uses the `name` property as a discriminator for tagged unions.
 *
 * Error types should follow the convention of ending with "Error" suffix.
 * The Err data structure wraps these error types in the Result system.
 *
 * @example
 * ```ts
 * type ValidationError = TaggedError<"ValidationError">
 * type NetworkError = TaggedError<"NetworkError">
 *
 * function handleError(error: ValidationError | NetworkError) {
 *   switch (error.name) {
 *     case "ValidationError": // TypeScript knows this is ValidationError
 *       break;
 *     case "NetworkError": // TypeScript knows this is NetworkError
 *       break;
 *   }
 * }
 *
 * // Used in Result types:
 * function validate(input: string): Result<string, ValidationError> {
 *   if (!input) {
 *     return Err({
 *       name: "ValidationError",
 *       message: "Input is required",
 *       context: { input },
 *       cause: null,
 *     });
 *   }
 *   return Ok(input);
 * }
 *
 * // Context is optional - omit when not needed:
 * function checkAuth(): Result<User, AuthError> {
 *   if (!isAuthenticated) {
 *     return Err({
 *       name: "AuthError",
 *       message: "User not authenticated",
 *       cause: null,
 *     });
 *   }
 *   return Ok(currentUser);
 * }
 * ```
 */
type TaggedError<T extends string> = BaseError & {
  readonly name: T;
};
//# sourceMappingURL=types.d.ts.map
//#endregion
//#region src/error/utils.d.ts
/**
 * Extracts a readable error message from an unknown error value
 *
 * This utility is commonly used in mapErr functions when converting
 * unknown errors to typed error objects in the Result system.
 *
 * @param error - The unknown error to extract a message from
 * @returns A string representation of the error
 *
 * @example
 * ```ts
 * // With native Error
 * const error = new Error("Something went wrong");
 * const message = extractErrorMessage(error); // "Something went wrong"
 *
 * // With string error
 * const stringError = "String error";
 * const message2 = extractErrorMessage(stringError); // "String error"
 *
 * // With object error
 * const unknownError = { code: 500, details: "Server error" };
 * const message3 = extractErrorMessage(unknownError); // '{"code":500,"details":"Server error"}'
 *
 * // Used in mapErr function
 * const result = await tryAsync({
 *   try: () => riskyOperation(),
 *   mapErr: (error) => Err({
 *     name: "NetworkError",
 *     message: extractErrorMessage(error),
 *     context: { operation: "riskyOperation" },
 *     cause: error,
 *   }),
 * });
 * ```
 */
declare function extractErrorMessage(error: unknown): string;
/**
 * Input type for creating a tagged error (everything except the name)
 */
type TaggedErrorWithoutName<T extends string> = Omit<TaggedError<T>, "name">;
/**
 * Replaces the "Error" suffix with "Err" suffix in error type names.
 *
 * This utility type is used to create companion function names for error constructors
 * that return Err-wrapped results, maintaining consistent naming conventions.
 *
 * @template T - An error type name that must end with "Error"
 * @returns The type name with "Error" replaced by "Err"
 *
 * @example
 * ```ts
 * type NetworkErr = ReplaceErrorWithErr<"NetworkError">; // "NetworkErr"
 * type ValidationErr = ReplaceErrorWithErr<"ValidationError">; // "ValidationErr"
 * type AuthErr = ReplaceErrorWithErr<"AuthError">; // "AuthErr"
 * ```
 */
type ReplaceErrorWithErr<T extends `${string}Error`> = T extends `${infer TBase}Error` ? `${TBase}Err` : never;
/**
 * Return type for createTaggedError - contains both factory functions.
 *
 * Provides two factory functions:
 * - One that creates plain TaggedError objects (named with "Error" suffix)
 * - One that creates Err-wrapped TaggedError objects (named with "Err" suffix)
 */
type TaggedErrorFactories<TErrorName extends `${string}Error`> = { [K in TErrorName]: (input: TaggedErrorWithoutName<K>) => TaggedError<K> } & { [K in ReplaceErrorWithErr<TErrorName>]: (input: TaggedErrorWithoutName<TErrorName>) => Err<TaggedError<TErrorName>> };
/**
 * Returns two different factory functions for tagged errors.
 *
 * Given an error name like "NetworkError", this returns:
 * - `NetworkError`: Creates a plain TaggedError object
 * - `NetworkErr`: Creates a TaggedError object wrapped in an Err result
 *
 * The naming pattern automatically replaces the "Error" suffix with "Err" suffix
 * for the Result-wrapped version.
 *
 * @param name - The name of the error type (must end with "Error")
 * @returns An object with two factory functions:
 *   - [name]: Function that creates plain TaggedError objects
 *   - [name with "Error" replaced by "Err"]: Function that creates Err-wrapped TaggedError objects
 *
 * @example
 * ```ts
 * const { NetworkError, NetworkErr } = createTaggedError('NetworkError');
 *
 * // NetworkError: Creates just the error object
 * const error = NetworkError({
 *   message: 'Connection failed',
 *   context: { url: 'https://api.example.com' },
 *   cause: undefined
 * });
 * // Returns: { name: 'NetworkError', message: 'Connection failed', ... }
 *
 * // NetworkErr: Creates error and wraps in Err result
 * return NetworkErr({
 *   message: 'Connection failed',
 *   context: { url: 'https://api.example.com' },
 *   cause: undefined
 * });
 * // Returns: Err({ name: 'NetworkError', message: 'Connection failed', ... })
 * ```
 */
declare function createTaggedError<TErrorName extends `${string}Error`>(name: TErrorName): TaggedErrorFactories<TErrorName>;
//#endregion
export { BaseError, TaggedError, createTaggedError, extractErrorMessage };
//# sourceMappingURL=index.d.ts.map