import { a as NextlyErrorCode } from './error-codes.d-CbwkO1ux.d.ts'; /** * Structured public payloads attached to NextlyError instances. * * `publicData` lives in HTTP response bodies and Server Action results. * It is safe by construction — never contains rejected values, identifiers * the caller didn't already provide, or operator-only context. */ type ValidationPublicData = { errors: Array<{ /** Dotted/bracketed path: "user.email", "items[2].quantity" */ path: string; /** Stable machine code: "INVALID_FORMAT" | "REQUIRED" | "TOO_LOW" | ... */ code: string; /** Complete sentence, ends with a period: "Must be a valid email address." */ message: string; }>; }; type RateLimitPublicData = { retryAfterSeconds?: number; }; type PublicData = ValidationPublicData | RateLimitPublicData | undefined; /** * Code accepted by NextlyError: canonical codes get autocomplete, but plugin * authors may use any UPPER_SNAKE string. The `(string & {})` trick preserves * the literal union for IntelliSense without collapsing to plain `string`. */ type NextlyErrorCodeLike = NextlyErrorCode | (string & {}); type NextlyErrorOpts = { code: NextlyErrorCodeLike; publicMessage: string; publicData?: PublicData; messageKey?: string; logMessage?: string; logContext?: Record; statusCode?: number; cause?: Error; }; type NextlyErrorResponseJSON = { code: string; message: string; messageKey?: string; data?: PublicData; requestId: string; }; /** * Unified error class for Nextly. Used at every throw site across services, * direct API, auth, and plugins. Carries two distinct payloads: * * - Public (`code`, `publicMessage`, `publicData`, `statusCode`, `messageKey`) * sent in HTTP responses and Server Action results. * - Log (`logMessage`, `logContext`, `cause`, stack trace) * written to the server logger; never serialised to the wire. * * Use the static factories (notFound, forbidden, validation, ...) for the * common cases. Use the free-form constructor for plugin codes or one-off * shapes. */ declare class NextlyError extends Error { readonly code: NextlyErrorCodeLike; readonly statusCode: number; readonly publicMessage: string; readonly publicData?: PublicData; readonly messageKey?: string; readonly logMessage?: string; readonly logContext?: Record; readonly cause?: Error; readonly timestamp: Date; constructor(opts: NextlyErrorOpts); private static resolveStatusCode; /** HTTP-safe JSON. Strips logMessage / logContext / cause / stack. */ toResponseJSON(requestId: string): NextlyErrorResponseJSON; /** Operator-facing JSON for log lines. Includes everything. */ toLogJSON(requestId: string): Record; static invalidCredentials(opts?: { logContext?: Record; }): NextlyError; static authRequired(opts?: { logContext?: Record; }): NextlyError; /** * Distinct from `authRequired`: the caller was authenticated but the * session token expired. Clients key on the TOKEN_EXPIRED *code* to * silently refresh and retry rather than redirecting to login; the public * message stays the generic spec §13.6 string ("Authentication required.") * so the wire never reveals the session state — same as `authRequired`. */ static tokenExpired(opts?: { logContext?: Record; }): NextlyError; static notFound(opts?: { cause?: Error; logContext?: Record; }): NextlyError; static forbidden(opts?: { cause?: Error; logContext?: Record; }): NextlyError; /** * A call the caller got wrong, where naming the mistake IS the value of the * error. * * The only factory that takes its public message from the caller. The * generic messages elsewhere exist so an HTTP response cannot leak internal * detail; this one is for arguments and configuration a developer controls * and must be told about — a missing option, an unusable combination — where * `internal()` would reduce the one useful sentence to "An unexpected error * occurred." Do not pass user-supplied data through it. */ static invalidInput(opts: { message: string; logContext?: Record; }): NextlyError; static validation(opts: { errors: ValidationPublicData["errors"]; cause?: Error; logContext?: Record; }): NextlyError; static conflict(opts?: { reason?: "version" | "state"; message?: string; cause?: Error; logContext?: Record; }): NextlyError; static duplicate(opts?: { logContext?: Record; }): NextlyError; static rateLimited(opts?: { retryAfterSeconds?: number; logContext?: Record; }): NextlyError; static internal(opts?: { cause?: Error; logContext?: Record; }): NextlyError; static serviceUnavailable(opts?: { /** * What the caller is told, when "try again later" is the wrong advice. * * The default assumes waiting resolves it. Some causes are not transient — * a lock with no expiry is held until an operator clears it — and there the * default sends someone to retry a request that cannot start succeeding. * Supply a message naming what to DO; it reaches an API response, so it * carries a remedy rather than internal state. */ publicMessage?: string; logMessage?: string; cause?: Error; logContext?: Record; }): NextlyError; /** * Convert a DbError (or arbitrary unknown thrown by the DB layer) to a * NextlyError with a generic public message and rich logContext. Used by * `withDbErrors` for auto-conversion (Pattern A) and by services that * catch DB errors at boundaries (Pattern B). Spec §8.2 mapping table. * * Never leaks DB driver text, constraint names, or table names into * `publicMessage`. All DB context goes into `logContext`. The original * DbError is preserved as `cause`. */ static fromDatabaseError(error: unknown): NextlyError; static is(err: unknown): err is NextlyError; static isCode(err: unknown, code: NextlyErrorCodeLike): err is NextlyError; static isNotFound(err: unknown): err is NextlyError; static isValidation(err: unknown): err is NextlyError; static isAuthRequired(err: unknown): err is NextlyError; static isForbidden(err: unknown): err is NextlyError; static isConflict(err: unknown): err is NextlyError; static isRateLimited(err: unknown): err is NextlyError; } export { NextlyError as N }; export type { PublicData as P, RateLimitPublicData as R, ValidationPublicData as V, NextlyErrorResponseJSON as a };