@bombillazo/error-x 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -58,8 +58,6 @@ type ErrorXOptions<TMetadata extends ErrorXMetadata = ErrorXMetadata> = {
58
58
  name?: string;
59
59
  /** Error identifier code (auto-generated from name if not provided) */
60
60
  code?: string | number;
61
- /** User-friendly message for UI display */
62
- uiMessage?: string | undefined;
63
61
  /** Original error that caused this error (preserves error chain, will be converted to ErrorXSnapshot format) */
64
62
  cause?: unknown;
65
63
  /** Additional context and debugging information */
@@ -82,51 +80,155 @@ type ErrorXSnapshot = {
82
80
  stack?: string;
83
81
  };
84
82
  /**
85
- * Context passed to the transform function when creating errors via `.create()`.
86
- * Contains information about the preset being used.
83
+ * Type representing valid preset keys for error creation.
84
+ * Allows both string and number keys while preventing accidental misuse.
87
85
  *
88
86
  * @public
89
87
  */
90
- type ErrorXTransformContext = {
91
- /** The preset key used (if any) */
92
- presetKey: string | number | undefined;
93
- };
88
+ type ErrorXBasePresetKey = (number & {}) | (string & {});
89
+
94
90
  /**
95
- * Transform function signature for custom error classes.
96
- * Transforms options after merge but before instantiation.
91
+ * Base configuration properties provided by error-x.
92
+ * Users extend this with their custom properties via ErrorXResolverConfig.
97
93
  *
98
94
  * @public
99
95
  */
100
- type ErrorXTransform<TMetadata extends ErrorXMetadata = ErrorXMetadata> = (opts: ErrorXOptions<ErrorXMetadata>, ctx: ErrorXTransformContext) => ErrorXOptions<TMetadata>;
96
+ type ErrorXBaseConfig = {
97
+ /** i18n namespace for translation key resolution (e.g., 'errors.api') */
98
+ namespace: string;
99
+ /** Path appended to docs base URL (e.g., '/api') */
100
+ docsPath?: string;
101
+ /** Static UI message - overrides i18n at preset level, fallback otherwise */
102
+ uiMessage?: string;
103
+ };
101
104
  /**
102
- * JSON-serializable representation of an ErrorX instance.
103
- * Used for transmitting errors over network or storing in databases.
105
+ * Type helper combining ErrorXBaseConfig with user's custom config properties.
104
106
  *
105
107
  * @example
106
108
  * ```typescript
107
- * const serialized: ErrorXSerialized = {
108
- * name: 'AuthError',
109
- * message: 'Authentication failed.',
110
- * code: 'AUTH_FAILED',
111
- * uiMessage: 'Please check your credentials',
112
- * stack: 'Error: Authentication failed.\n at login (auth.ts:42:15)',
113
- * metadata: { userId: 123, loginAttempt: 3 },
114
- * timestamp: 1705315845123,
115
- * httpStatus: 401,
116
- * original: {
117
- * name: 'NetworkError',
118
- * message: 'Request timeout.',
119
- * stack: '...'
120
- * },
121
- * chain: [
122
- * { name: 'AuthError', message: 'Authentication failed.' },
123
- * { name: 'NetworkError', message: 'Request timeout.' }
124
- * ]
125
- * }
109
+ * type MyConfig = ErrorXResolverConfig<{
110
+ * severity: 'error' | 'warning' | 'info';
111
+ * retryable: boolean;
112
+ * }>;
126
113
  * ```
127
114
  *
128
115
  * @public
129
116
  */
117
+ type ErrorXResolverConfig<TCustom extends Record<string, unknown> = Record<string, unknown>> = ErrorXBaseConfig & TCustom;
118
+ /**
119
+ * Context object passed to the onResolve callback.
120
+ * Contains computed values and merged config for the error.
121
+ *
122
+ * @public
123
+ */
124
+ type ResolveContext<TConfig extends ErrorXBaseConfig = ErrorXBaseConfig> = {
125
+ /** Resolved UI message (from i18n or static config) */
126
+ uiMessage: string | undefined;
127
+ /** Full documentation URL */
128
+ docsUrl: string;
129
+ /** The resolved i18n key (e.g., 'errors.api.AUTH_EXPIRED') */
130
+ i18nKey: string;
131
+ /** The error type returned by onResolveType callback */
132
+ errorType: string;
133
+ /** Merged config for this error (defaults + type + preset) */
134
+ config: TConfig;
135
+ };
136
+ /**
137
+ * i18n configuration for the resolver.
138
+ *
139
+ * @public
140
+ */
141
+ type ErrorXResolverI18nConfig = {
142
+ /**
143
+ * User-provided translation function.
144
+ * Receives the i18n key and optional interpolation params (from error.metadata).
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * resolver: (key, params) => i18next.t(key, params)
149
+ * ```
150
+ */
151
+ resolver: (key: string, params?: Record<string, unknown>) => string;
152
+ /**
153
+ * Template for building translation keys.
154
+ * Available placeholders: {namespace}, {code}, {name}, {errorType}
155
+ * @default '{namespace}.{code}'
156
+ */
157
+ keyTemplate?: string;
158
+ };
159
+ /**
160
+ * Documentation configuration for the resolver.
161
+ *
162
+ * @public
163
+ */
164
+ type ErrorXResolverDocsConfig = {
165
+ /**
166
+ * Base URL for documentation.
167
+ * @default '' (empty string)
168
+ */
169
+ baseUrl?: string;
170
+ };
171
+ /**
172
+ * Per-error-type configuration with optional preset overrides.
173
+ *
174
+ * @public
175
+ */
176
+ type ErrorXResolverTypeConfig<TConfig extends ErrorXBaseConfig = ErrorXBaseConfig> = Omit<TConfig, 'presets'> & {
177
+ /** Per-error-code overrides within this type */
178
+ presets?: {
179
+ [code: string]: Partial<ErrorXBaseConfig> & Partial<Omit<TConfig, keyof ErrorXBaseConfig>>;
180
+ };
181
+ };
182
+ /**
183
+ * Full configuration options for ErrorXResolver.
184
+ *
185
+ * @public
186
+ */
187
+ type ErrorXResolverOptions<TConfig extends ErrorXBaseConfig = ErrorXBaseConfig, TResult = ResolveContext<TConfig>> = {
188
+ /** Optional i18n configuration. If not provided, relies on static uiMessage values. */
189
+ i18n?: ErrorXResolverI18nConfig;
190
+ /** Optional documentation URL configuration. */
191
+ docs?: ErrorXResolverDocsConfig;
192
+ /**
193
+ * Callback to determine the error type key.
194
+ * The returned string is used to look up config in the configs object.
195
+ *
196
+ * @example
197
+ * ```typescript
198
+ * onResolveType: (error) => {
199
+ * if (error instanceof APIErrorX) return 'api';
200
+ * if (error.code.startsWith('DB_')) return 'database';
201
+ * return 'general';
202
+ * }
203
+ * ```
204
+ */
205
+ onResolveType: (error: ErrorX) => string;
206
+ /**
207
+ * Optional callback to customize the resolve output.
208
+ * If not provided, resolve() returns the ResolveContext directly.
209
+ *
210
+ * @example
211
+ * ```typescript
212
+ * onResolve: (error, context) => ({
213
+ * message: context.uiMessage,
214
+ * docs: context.docsUrl,
215
+ * severity: context.config.severity,
216
+ * })
217
+ * ```
218
+ */
219
+ onResolve?: (error: ErrorX, context: ResolveContext<TConfig>) => TResult;
220
+ /** Default config values (fallback for all error types) */
221
+ defaults?: Partial<ErrorXBaseConfig> & Partial<Omit<TConfig, keyof ErrorXBaseConfig>>;
222
+ /** Per-error-type configurations (partial configs get merged with defaults) */
223
+ configs: Record<string, Partial<ErrorXResolverTypeConfig<TConfig>>>;
224
+ };
225
+
226
+ /**
227
+ * JSON-serializable representation of an ErrorX instance.
228
+ * Used for transmitting errors over network or storing in databases.
229
+ *
230
+ * @public
231
+ */
130
232
  type ErrorXSerialized = {
131
233
  /** Error type/name */
132
234
  name: string;
@@ -134,8 +236,6 @@ type ErrorXSerialized = {
134
236
  message: string;
135
237
  /** Error identifier code */
136
238
  code: string;
137
- /** User-friendly message for UI display */
138
- uiMessage: string | undefined;
139
239
  /** Stack trace (optional) */
140
240
  stack?: string;
141
241
  /** Additional context and debugging information */
@@ -149,13 +249,24 @@ type ErrorXSerialized = {
149
249
  /** Serialized error chain timeline (this error and all ancestors) */
150
250
  chain?: ErrorXSerialized[];
151
251
  };
252
+
152
253
  /**
153
- * Type representing valid preset keys for error creation.
154
- * Allows both string and number keys while preventing accidental misuse.
254
+ * Context passed to the transform function when creating errors via `.create()`.
255
+ * Contains information about the preset being used.
155
256
  *
156
257
  * @public
157
258
  */
158
- type ErrorXBasePresetKey = (number & {}) | (string & {});
259
+ type ErrorXTransformContext = {
260
+ /** The preset key used (if any) */
261
+ presetKey: string | number | undefined;
262
+ };
263
+ /**
264
+ * Transform function signature for custom error classes.
265
+ * Transforms options after merge but before instantiation.
266
+ *
267
+ * @public
268
+ */
269
+ type ErrorXTransform<TMetadata extends ErrorXMetadata = ErrorXMetadata> = (opts: ErrorXOptions<ErrorXMetadata>, ctx: ErrorXTransformContext) => ErrorXOptions<TMetadata>;
159
270
 
160
271
  /**
161
272
  * Configuration interface for ErrorX global settings
@@ -194,7 +305,6 @@ interface ErrorXConfig {
194
305
  * message: 'User authentication failed',
195
306
  * name: 'AuthError',
196
307
  * code: 'AUTH_FAILED',
197
- * uiMessage: 'Please check your credentials',
198
308
  * metadata: { userId: 123, loginAttempt: 3 }
199
309
  * })
200
310
  *
@@ -214,8 +324,6 @@ declare class ErrorX<TMetadata extends ErrorXMetadata = ErrorXMetadata> extends
214
324
  private static _config;
215
325
  /** Error identifier code, auto-generated from name if not provided */
216
326
  code: string;
217
- /** User-friendly message suitable for display in UI */
218
- uiMessage: string | undefined;
219
327
  /** Additional context and metadata associated with the error */
220
328
  metadata: TMetadata | undefined;
221
329
  /** Unix epoch timestamp (milliseconds) when the error was created */
@@ -259,7 +367,6 @@ declare class ErrorX<TMetadata extends ErrorXMetadata = ErrorXMetadata> extends
259
367
  * message: 'Database query failed',
260
368
  * name: 'DatabaseError',
261
369
  * code: 'DB_QUERY_FAILED',
262
- * uiMessage: 'Unable to load data. Please try again.',
263
370
  * metadata: { query: 'SELECT * FROM users', timeout: 5000 }
264
371
  * })
265
372
  *
@@ -505,7 +612,6 @@ declare class ErrorX<TMetadata extends ErrorXMetadata = ErrorXMetadata> extends
505
612
  * name: 'DatabaseError',
506
613
  * message: 'Connection failed.',
507
614
  * code: 'DB_CONN_FAILED',
508
- * uiMessage: 'Database is temporarily unavailable',
509
615
  * metadata: { host: 'localhost' },
510
616
  * timestamp: 1705315845123
511
617
  * }
@@ -571,99 +677,89 @@ declare const dbPresets: {
571
677
  readonly code: "CONNECTION_FAILED";
572
678
  readonly name: "DBConnectionError";
573
679
  readonly message: "Failed to connect to database.";
574
- readonly uiMessage: "Unable to connect to the database. Please try again later.";
575
680
  };
576
681
  readonly CONNECTION_TIMEOUT: {
577
682
  readonly code: "CONNECTION_TIMEOUT";
578
683
  readonly name: "DBConnectionTimeoutError";
579
684
  readonly message: "Database connection timed out.";
580
- readonly uiMessage: "The database connection timed out. Please try again.";
581
685
  };
582
686
  readonly CONNECTION_REFUSED: {
583
687
  readonly code: "CONNECTION_REFUSED";
584
688
  readonly name: "DBConnectionRefusedError";
585
689
  readonly message: "Database connection refused.";
586
- readonly uiMessage: "Unable to connect to the database. Please try again later.";
587
690
  };
588
691
  readonly CONNECTION_LOST: {
589
692
  readonly code: "CONNECTION_LOST";
590
693
  readonly name: "DBConnectionLostError";
591
694
  readonly message: "Database connection lost.";
592
- readonly uiMessage: "The database connection was lost. Please try again.";
593
695
  };
594
696
  readonly QUERY_FAILED: {
595
697
  readonly code: "QUERY_FAILED";
596
698
  readonly name: "DBQueryError";
597
699
  readonly message: "Database query failed.";
598
- readonly uiMessage: "The database operation failed. Please try again.";
599
700
  };
600
701
  readonly QUERY_TIMEOUT: {
601
702
  readonly code: "QUERY_TIMEOUT";
602
703
  readonly name: "DBQueryTimeoutError";
603
704
  readonly message: "Database query timed out.";
604
- readonly uiMessage: "The database operation took too long. Please try again.";
605
705
  };
606
706
  readonly SYNTAX_ERROR: {
607
707
  readonly code: "SYNTAX_ERROR";
608
708
  readonly name: "DBSyntaxError";
609
709
  readonly message: "Invalid query syntax.";
610
- readonly uiMessage: "An internal error occurred. Please contact support.";
611
710
  };
612
711
  readonly UNIQUE_VIOLATION: {
613
712
  readonly code: "UNIQUE_VIOLATION";
614
713
  readonly name: "DBUniqueViolationError";
615
714
  readonly message: "Unique constraint violation.";
616
- readonly uiMessage: "This record already exists.";
617
715
  readonly httpStatus: 409;
618
716
  };
619
717
  readonly FOREIGN_KEY_VIOLATION: {
620
718
  readonly code: "FOREIGN_KEY_VIOLATION";
621
719
  readonly name: "DBForeignKeyError";
622
720
  readonly message: "Foreign key constraint violation.";
623
- readonly uiMessage: "This operation references a record that does not exist.";
624
721
  readonly httpStatus: 400;
625
722
  };
626
723
  readonly NOT_NULL_VIOLATION: {
627
724
  readonly code: "NOT_NULL_VIOLATION";
628
725
  readonly name: "DBNotNullError";
629
726
  readonly message: "Not null constraint violation.";
630
- readonly uiMessage: "A required field is missing.";
631
727
  readonly httpStatus: 400;
632
728
  };
633
729
  readonly CHECK_VIOLATION: {
634
730
  readonly code: "CHECK_VIOLATION";
635
731
  readonly name: "DBCheckViolationError";
636
732
  readonly message: "Check constraint violation.";
637
- readonly uiMessage: "The provided data is invalid.";
638
733
  readonly httpStatus: 400;
639
734
  };
640
735
  readonly TRANSACTION_FAILED: {
641
736
  readonly code: "TRANSACTION_FAILED";
642
737
  readonly name: "DBTransactionError";
643
738
  readonly message: "Database transaction failed.";
644
- readonly uiMessage: "The operation failed. Please try again.";
645
739
  };
646
740
  readonly DEADLOCK: {
647
741
  readonly code: "DEADLOCK";
648
742
  readonly name: "DBDeadlockError";
649
743
  readonly message: "Database deadlock detected.";
650
- readonly uiMessage: "The operation encountered a conflict. Please try again.";
651
744
  readonly httpStatus: 409;
652
745
  };
653
746
  readonly NOT_FOUND: {
654
747
  readonly code: "NOT_FOUND";
655
748
  readonly name: "DBNotFoundError";
656
749
  readonly message: "Record not found.";
657
- readonly uiMessage: "The requested record was not found.";
658
750
  readonly httpStatus: 404;
659
751
  };
660
752
  readonly UNKNOWN: {
661
753
  readonly code: "UNKNOWN";
662
754
  readonly name: "DBErrorX";
663
755
  readonly message: "An unknown database error occurred.";
664
- readonly uiMessage: "A database error occurred. Please try again later.";
665
756
  };
666
757
  };
758
+ /**
759
+ * User-friendly messages for database error presets.
760
+ * Keyed by preset name.
761
+ */
762
+ declare const dbErrorUiMessages: Record<keyof typeof dbPresets, string>;
667
763
  /**
668
764
  * Valid preset keys for DBErrorX.create()
669
765
  * Derived from the presets object. Provides autocomplete for known presets
@@ -745,97 +841,82 @@ declare class DBErrorX extends ErrorX<DBErrorXMetadata> {
745
841
  readonly code: "CONNECTION_FAILED";
746
842
  readonly name: "DBConnectionError";
747
843
  readonly message: "Failed to connect to database.";
748
- readonly uiMessage: "Unable to connect to the database. Please try again later.";
749
844
  };
750
845
  readonly CONNECTION_TIMEOUT: {
751
846
  readonly code: "CONNECTION_TIMEOUT";
752
847
  readonly name: "DBConnectionTimeoutError";
753
848
  readonly message: "Database connection timed out.";
754
- readonly uiMessage: "The database connection timed out. Please try again.";
755
849
  };
756
850
  readonly CONNECTION_REFUSED: {
757
851
  readonly code: "CONNECTION_REFUSED";
758
852
  readonly name: "DBConnectionRefusedError";
759
853
  readonly message: "Database connection refused.";
760
- readonly uiMessage: "Unable to connect to the database. Please try again later.";
761
854
  };
762
855
  readonly CONNECTION_LOST: {
763
856
  readonly code: "CONNECTION_LOST";
764
857
  readonly name: "DBConnectionLostError";
765
858
  readonly message: "Database connection lost.";
766
- readonly uiMessage: "The database connection was lost. Please try again.";
767
859
  };
768
860
  readonly QUERY_FAILED: {
769
861
  readonly code: "QUERY_FAILED";
770
862
  readonly name: "DBQueryError";
771
863
  readonly message: "Database query failed.";
772
- readonly uiMessage: "The database operation failed. Please try again.";
773
864
  };
774
865
  readonly QUERY_TIMEOUT: {
775
866
  readonly code: "QUERY_TIMEOUT";
776
867
  readonly name: "DBQueryTimeoutError";
777
868
  readonly message: "Database query timed out.";
778
- readonly uiMessage: "The database operation took too long. Please try again.";
779
869
  };
780
870
  readonly SYNTAX_ERROR: {
781
871
  readonly code: "SYNTAX_ERROR";
782
872
  readonly name: "DBSyntaxError";
783
873
  readonly message: "Invalid query syntax.";
784
- readonly uiMessage: "An internal error occurred. Please contact support.";
785
874
  };
786
875
  readonly UNIQUE_VIOLATION: {
787
876
  readonly code: "UNIQUE_VIOLATION";
788
877
  readonly name: "DBUniqueViolationError";
789
878
  readonly message: "Unique constraint violation.";
790
- readonly uiMessage: "This record already exists.";
791
879
  readonly httpStatus: 409;
792
880
  };
793
881
  readonly FOREIGN_KEY_VIOLATION: {
794
882
  readonly code: "FOREIGN_KEY_VIOLATION";
795
883
  readonly name: "DBForeignKeyError";
796
884
  readonly message: "Foreign key constraint violation.";
797
- readonly uiMessage: "This operation references a record that does not exist.";
798
885
  readonly httpStatus: 400;
799
886
  };
800
887
  readonly NOT_NULL_VIOLATION: {
801
888
  readonly code: "NOT_NULL_VIOLATION";
802
889
  readonly name: "DBNotNullError";
803
890
  readonly message: "Not null constraint violation.";
804
- readonly uiMessage: "A required field is missing.";
805
891
  readonly httpStatus: 400;
806
892
  };
807
893
  readonly CHECK_VIOLATION: {
808
894
  readonly code: "CHECK_VIOLATION";
809
895
  readonly name: "DBCheckViolationError";
810
896
  readonly message: "Check constraint violation.";
811
- readonly uiMessage: "The provided data is invalid.";
812
897
  readonly httpStatus: 400;
813
898
  };
814
899
  readonly TRANSACTION_FAILED: {
815
900
  readonly code: "TRANSACTION_FAILED";
816
901
  readonly name: "DBTransactionError";
817
902
  readonly message: "Database transaction failed.";
818
- readonly uiMessage: "The operation failed. Please try again.";
819
903
  };
820
904
  readonly DEADLOCK: {
821
905
  readonly code: "DEADLOCK";
822
906
  readonly name: "DBDeadlockError";
823
907
  readonly message: "Database deadlock detected.";
824
- readonly uiMessage: "The operation encountered a conflict. Please try again.";
825
908
  readonly httpStatus: 409;
826
909
  };
827
910
  readonly NOT_FOUND: {
828
911
  readonly code: "NOT_FOUND";
829
912
  readonly name: "DBNotFoundError";
830
913
  readonly message: "Record not found.";
831
- readonly uiMessage: "The requested record was not found.";
832
914
  readonly httpStatus: 404;
833
915
  };
834
916
  readonly UNKNOWN: {
835
917
  readonly code: "UNKNOWN";
836
918
  readonly name: "DBErrorX";
837
919
  readonly message: "An unknown database error occurred.";
838
- readonly uiMessage: "A database error occurred. Please try again later.";
839
920
  };
840
921
  };
841
922
  /** Default to UNKNOWN when no preset specified */
@@ -868,237 +949,203 @@ declare const httpPresets: {
868
949
  readonly code: "BAD_REQUEST";
869
950
  readonly name: "BadRequestError";
870
951
  readonly message: "Bad request.";
871
- readonly uiMessage: "The request could not be processed. Please check your input and try again.";
872
952
  };
873
953
  readonly 401: {
874
954
  readonly code: "UNAUTHORIZED";
875
955
  readonly name: "UnauthorizedError";
876
956
  readonly message: "Unauthorized.";
877
- readonly uiMessage: "Authentication required. Please log in to continue.";
878
957
  };
879
958
  readonly 402: {
880
959
  readonly code: "PAYMENT_REQUIRED";
881
960
  readonly name: "PaymentRequiredError";
882
961
  readonly message: "Payment required.";
883
- readonly uiMessage: "Payment is required to access this resource.";
884
962
  };
885
963
  readonly 403: {
886
964
  readonly code: "FORBIDDEN";
887
965
  readonly name: "ForbiddenError";
888
966
  readonly message: "Forbidden.";
889
- readonly uiMessage: "You do not have permission to access this resource.";
890
967
  };
891
968
  readonly 404: {
892
969
  readonly code: "NOT_FOUND";
893
970
  readonly name: "NotFoundError";
894
971
  readonly message: "Not found.";
895
- readonly uiMessage: "The requested resource could not be found.";
896
972
  };
897
973
  readonly 405: {
898
974
  readonly code: "METHOD_NOT_ALLOWED";
899
975
  readonly name: "MethodNotAllowedError";
900
976
  readonly message: "Method not allowed.";
901
- readonly uiMessage: "This action is not allowed for the requested resource.";
902
977
  };
903
978
  readonly 406: {
904
979
  readonly code: "NOT_ACCEPTABLE";
905
980
  readonly name: "NotAcceptableError";
906
981
  readonly message: "Not acceptable.";
907
- readonly uiMessage: "The requested format is not supported.";
908
982
  };
909
983
  readonly 407: {
910
984
  readonly code: "PROXY_AUTHENTICATION_REQUIRED";
911
985
  readonly name: "ProxyAuthenticationRequiredError";
912
986
  readonly message: "Proxy authentication required.";
913
- readonly uiMessage: "Proxy authentication is required to access this resource.";
914
987
  };
915
988
  readonly 408: {
916
989
  readonly code: "REQUEST_TIMEOUT";
917
990
  readonly name: "RequestTimeoutError";
918
991
  readonly message: "Request timeout.";
919
- readonly uiMessage: "The request took too long to complete. Please try again.";
920
992
  };
921
993
  readonly 409: {
922
994
  readonly code: "CONFLICT";
923
995
  readonly name: "ConflictError";
924
996
  readonly message: "Conflict.";
925
- readonly uiMessage: "The request conflicts with the current state. Please refresh and try again.";
926
997
  };
927
998
  readonly 410: {
928
999
  readonly code: "GONE";
929
1000
  readonly name: "GoneError";
930
1001
  readonly message: "Gone.";
931
- readonly uiMessage: "This resource is no longer available.";
932
1002
  };
933
1003
  readonly 411: {
934
1004
  readonly code: "LENGTH_REQUIRED";
935
1005
  readonly name: "LengthRequiredError";
936
1006
  readonly message: "Length required.";
937
- readonly uiMessage: "The request is missing required length information.";
938
1007
  };
939
1008
  readonly 412: {
940
1009
  readonly code: "PRECONDITION_FAILED";
941
1010
  readonly name: "PreconditionFailedError";
942
1011
  readonly message: "Precondition failed.";
943
- readonly uiMessage: "A required condition was not met. Please try again.";
944
1012
  };
945
1013
  readonly 413: {
946
1014
  readonly code: "PAYLOAD_TOO_LARGE";
947
1015
  readonly name: "PayloadTooLargeError";
948
1016
  readonly message: "Payload too large.";
949
- readonly uiMessage: "The request is too large. Please reduce the size and try again.";
950
1017
  };
951
1018
  readonly 414: {
952
1019
  readonly code: "URI_TOO_LONG";
953
1020
  readonly name: "UriTooLongError";
954
1021
  readonly message: "URI too long.";
955
- readonly uiMessage: "The request URL is too long.";
956
1022
  };
957
1023
  readonly 415: {
958
1024
  readonly code: "UNSUPPORTED_MEDIA_TYPE";
959
1025
  readonly name: "UnsupportedMediaTypeError";
960
1026
  readonly message: "Unsupported media type.";
961
- readonly uiMessage: "The file type is not supported.";
962
1027
  };
963
1028
  readonly 416: {
964
1029
  readonly code: "RANGE_NOT_SATISFIABLE";
965
1030
  readonly name: "RangeNotSatisfiableError";
966
1031
  readonly message: "Range not satisfiable.";
967
- readonly uiMessage: "The requested range cannot be satisfied.";
968
1032
  };
969
1033
  readonly 417: {
970
1034
  readonly code: "EXPECTATION_FAILED";
971
1035
  readonly name: "ExpectationFailedError";
972
1036
  readonly message: "Expectation failed.";
973
- readonly uiMessage: "The server cannot meet the requirements of the request.";
974
1037
  };
975
1038
  readonly 418: {
976
1039
  readonly code: "IM_A_TEAPOT";
977
1040
  readonly name: "ImATeapotError";
978
1041
  readonly message: "I'm a teapot.";
979
- readonly uiMessage: "I'm a teapot and cannot brew coffee.";
980
1042
  };
981
1043
  readonly 422: {
982
1044
  readonly code: "UNPROCESSABLE_ENTITY";
983
1045
  readonly name: "UnprocessableEntityError";
984
1046
  readonly message: "Unprocessable entity.";
985
- readonly uiMessage: "The request contains invalid data. Please check your input.";
986
1047
  };
987
1048
  readonly 423: {
988
1049
  readonly code: "LOCKED";
989
1050
  readonly name: "LockedError";
990
1051
  readonly message: "Locked.";
991
- readonly uiMessage: "This resource is locked and cannot be modified.";
992
1052
  };
993
1053
  readonly 424: {
994
1054
  readonly code: "FAILED_DEPENDENCY";
995
1055
  readonly name: "FailedDependencyError";
996
1056
  readonly message: "Failed dependency.";
997
- readonly uiMessage: "The request failed due to a dependency error.";
998
1057
  };
999
1058
  readonly 425: {
1000
1059
  readonly code: "TOO_EARLY";
1001
1060
  readonly name: "TooEarlyError";
1002
1061
  readonly message: "Too early.";
1003
- readonly uiMessage: "The request was sent too early. Please try again later.";
1004
1062
  };
1005
1063
  readonly 426: {
1006
1064
  readonly code: "UPGRADE_REQUIRED";
1007
1065
  readonly name: "UpgradeRequiredError";
1008
1066
  readonly message: "Upgrade required.";
1009
- readonly uiMessage: "Please upgrade to continue using this service.";
1010
1067
  };
1011
1068
  readonly 428: {
1012
1069
  readonly code: "PRECONDITION_REQUIRED";
1013
1070
  readonly name: "PreconditionRequiredError";
1014
1071
  readonly message: "Precondition required.";
1015
- readonly uiMessage: "Required conditions are missing from the request.";
1016
1072
  };
1017
1073
  readonly 429: {
1018
1074
  readonly code: "TOO_MANY_REQUESTS";
1019
1075
  readonly name: "TooManyRequestsError";
1020
1076
  readonly message: "Too many requests.";
1021
- readonly uiMessage: "You have made too many requests. Please wait and try again.";
1022
1077
  };
1023
1078
  readonly 431: {
1024
1079
  readonly code: "REQUEST_HEADER_FIELDS_TOO_LARGE";
1025
1080
  readonly name: "RequestHeaderFieldsTooLargeError";
1026
1081
  readonly message: "Request header fields too large.";
1027
- readonly uiMessage: "The request headers are too large.";
1028
1082
  };
1029
1083
  readonly 451: {
1030
1084
  readonly code: "UNAVAILABLE_FOR_LEGAL_REASONS";
1031
1085
  readonly name: "UnavailableForLegalReasonsError";
1032
1086
  readonly message: "Unavailable for legal reasons.";
1033
- readonly uiMessage: "This content is unavailable for legal reasons.";
1034
1087
  };
1035
1088
  readonly 500: {
1036
1089
  readonly code: "INTERNAL_SERVER_ERROR";
1037
1090
  readonly name: "InternalServerError";
1038
1091
  readonly message: "Internal server error.";
1039
- readonly uiMessage: "An unexpected error occurred. Please try again later.";
1040
1092
  };
1041
1093
  readonly 501: {
1042
1094
  readonly code: "NOT_IMPLEMENTED";
1043
1095
  readonly name: "NotImplementedError";
1044
1096
  readonly message: "Not implemented.";
1045
- readonly uiMessage: "This feature is not yet available.";
1046
1097
  };
1047
1098
  readonly 502: {
1048
1099
  readonly code: "BAD_GATEWAY";
1049
1100
  readonly name: "BadGatewayError";
1050
1101
  readonly message: "Bad gateway.";
1051
- readonly uiMessage: "Unable to connect to the server. Please try again later.";
1052
1102
  };
1053
1103
  readonly 503: {
1054
1104
  readonly code: "SERVICE_UNAVAILABLE";
1055
1105
  readonly name: "ServiceUnavailableError";
1056
1106
  readonly message: "Service unavailable.";
1057
- readonly uiMessage: "The service is temporarily unavailable. Please try again later.";
1058
1107
  };
1059
1108
  readonly 504: {
1060
1109
  readonly code: "GATEWAY_TIMEOUT";
1061
1110
  readonly name: "GatewayTimeoutError";
1062
1111
  readonly message: "Gateway timeout.";
1063
- readonly uiMessage: "The server took too long to respond. Please try again.";
1064
1112
  };
1065
1113
  readonly 505: {
1066
1114
  readonly code: "HTTP_VERSION_NOT_SUPPORTED";
1067
1115
  readonly name: "HttpVersionNotSupportedError";
1068
1116
  readonly message: "HTTP version not supported.";
1069
- readonly uiMessage: "Your browser version is not supported.";
1070
1117
  };
1071
1118
  readonly 506: {
1072
1119
  readonly code: "VARIANT_ALSO_NEGOTIATES";
1073
1120
  readonly name: "VariantAlsoNegotiatesError";
1074
1121
  readonly message: "Variant also negotiates.";
1075
- readonly uiMessage: "The server has an internal configuration error.";
1076
1122
  };
1077
1123
  readonly 507: {
1078
1124
  readonly code: "INSUFFICIENT_STORAGE";
1079
1125
  readonly name: "InsufficientStorageError";
1080
1126
  readonly message: "Insufficient storage.";
1081
- readonly uiMessage: "The server has insufficient storage to complete the request.";
1082
1127
  };
1083
1128
  readonly 508: {
1084
1129
  readonly code: "LOOP_DETECTED";
1085
1130
  readonly name: "LoopDetectedError";
1086
1131
  readonly message: "Loop detected.";
1087
- readonly uiMessage: "The server detected an infinite loop.";
1088
1132
  };
1089
1133
  readonly 510: {
1090
1134
  readonly code: "NOT_EXTENDED";
1091
1135
  readonly name: "NotExtendedError";
1092
1136
  readonly message: "Not extended.";
1093
- readonly uiMessage: "Additional extensions are required.";
1094
1137
  };
1095
1138
  readonly 511: {
1096
1139
  readonly code: "NETWORK_AUTHENTICATION_REQUIRED";
1097
1140
  readonly name: "NetworkAuthenticationRequiredError";
1098
1141
  readonly message: "Network authentication required.";
1099
- readonly uiMessage: "Network authentication is required to access this resource.";
1100
1142
  };
1101
1143
  };
1144
+ /**
1145
+ * User-friendly messages for HTTP error presets.
1146
+ * Keyed by HTTP status code.
1147
+ */
1148
+ declare const httpErrorUiMessages: Record<keyof typeof httpPresets, string>;
1102
1149
  /**
1103
1150
  * Valid HTTP status codes for HTTPErrorX.create()
1104
1151
  * Derived from the presets object. Provides autocomplete for known codes
@@ -1172,235 +1219,196 @@ declare class HTTPErrorX extends ErrorX<HTTPErrorXMetadata> {
1172
1219
  readonly code: "BAD_REQUEST";
1173
1220
  readonly name: "BadRequestError";
1174
1221
  readonly message: "Bad request.";
1175
- readonly uiMessage: "The request could not be processed. Please check your input and try again.";
1176
1222
  };
1177
1223
  readonly 401: {
1178
1224
  readonly code: "UNAUTHORIZED";
1179
1225
  readonly name: "UnauthorizedError";
1180
1226
  readonly message: "Unauthorized.";
1181
- readonly uiMessage: "Authentication required. Please log in to continue.";
1182
1227
  };
1183
1228
  readonly 402: {
1184
1229
  readonly code: "PAYMENT_REQUIRED";
1185
1230
  readonly name: "PaymentRequiredError";
1186
1231
  readonly message: "Payment required.";
1187
- readonly uiMessage: "Payment is required to access this resource.";
1188
1232
  };
1189
1233
  readonly 403: {
1190
1234
  readonly code: "FORBIDDEN";
1191
1235
  readonly name: "ForbiddenError";
1192
1236
  readonly message: "Forbidden.";
1193
- readonly uiMessage: "You do not have permission to access this resource.";
1194
1237
  };
1195
1238
  readonly 404: {
1196
1239
  readonly code: "NOT_FOUND";
1197
1240
  readonly name: "NotFoundError";
1198
1241
  readonly message: "Not found.";
1199
- readonly uiMessage: "The requested resource could not be found.";
1200
1242
  };
1201
1243
  readonly 405: {
1202
1244
  readonly code: "METHOD_NOT_ALLOWED";
1203
1245
  readonly name: "MethodNotAllowedError";
1204
1246
  readonly message: "Method not allowed.";
1205
- readonly uiMessage: "This action is not allowed for the requested resource.";
1206
1247
  };
1207
1248
  readonly 406: {
1208
1249
  readonly code: "NOT_ACCEPTABLE";
1209
1250
  readonly name: "NotAcceptableError";
1210
1251
  readonly message: "Not acceptable.";
1211
- readonly uiMessage: "The requested format is not supported.";
1212
1252
  };
1213
1253
  readonly 407: {
1214
1254
  readonly code: "PROXY_AUTHENTICATION_REQUIRED";
1215
1255
  readonly name: "ProxyAuthenticationRequiredError";
1216
1256
  readonly message: "Proxy authentication required.";
1217
- readonly uiMessage: "Proxy authentication is required to access this resource.";
1218
1257
  };
1219
1258
  readonly 408: {
1220
1259
  readonly code: "REQUEST_TIMEOUT";
1221
1260
  readonly name: "RequestTimeoutError";
1222
1261
  readonly message: "Request timeout.";
1223
- readonly uiMessage: "The request took too long to complete. Please try again.";
1224
1262
  };
1225
1263
  readonly 409: {
1226
1264
  readonly code: "CONFLICT";
1227
1265
  readonly name: "ConflictError";
1228
1266
  readonly message: "Conflict.";
1229
- readonly uiMessage: "The request conflicts with the current state. Please refresh and try again.";
1230
1267
  };
1231
1268
  readonly 410: {
1232
1269
  readonly code: "GONE";
1233
1270
  readonly name: "GoneError";
1234
1271
  readonly message: "Gone.";
1235
- readonly uiMessage: "This resource is no longer available.";
1236
1272
  };
1237
1273
  readonly 411: {
1238
1274
  readonly code: "LENGTH_REQUIRED";
1239
1275
  readonly name: "LengthRequiredError";
1240
1276
  readonly message: "Length required.";
1241
- readonly uiMessage: "The request is missing required length information.";
1242
1277
  };
1243
1278
  readonly 412: {
1244
1279
  readonly code: "PRECONDITION_FAILED";
1245
1280
  readonly name: "PreconditionFailedError";
1246
1281
  readonly message: "Precondition failed.";
1247
- readonly uiMessage: "A required condition was not met. Please try again.";
1248
1282
  };
1249
1283
  readonly 413: {
1250
1284
  readonly code: "PAYLOAD_TOO_LARGE";
1251
1285
  readonly name: "PayloadTooLargeError";
1252
1286
  readonly message: "Payload too large.";
1253
- readonly uiMessage: "The request is too large. Please reduce the size and try again.";
1254
1287
  };
1255
1288
  readonly 414: {
1256
1289
  readonly code: "URI_TOO_LONG";
1257
1290
  readonly name: "UriTooLongError";
1258
1291
  readonly message: "URI too long.";
1259
- readonly uiMessage: "The request URL is too long.";
1260
1292
  };
1261
1293
  readonly 415: {
1262
1294
  readonly code: "UNSUPPORTED_MEDIA_TYPE";
1263
1295
  readonly name: "UnsupportedMediaTypeError";
1264
1296
  readonly message: "Unsupported media type.";
1265
- readonly uiMessage: "The file type is not supported.";
1266
1297
  };
1267
1298
  readonly 416: {
1268
1299
  readonly code: "RANGE_NOT_SATISFIABLE";
1269
1300
  readonly name: "RangeNotSatisfiableError";
1270
1301
  readonly message: "Range not satisfiable.";
1271
- readonly uiMessage: "The requested range cannot be satisfied.";
1272
1302
  };
1273
1303
  readonly 417: {
1274
1304
  readonly code: "EXPECTATION_FAILED";
1275
1305
  readonly name: "ExpectationFailedError";
1276
1306
  readonly message: "Expectation failed.";
1277
- readonly uiMessage: "The server cannot meet the requirements of the request.";
1278
1307
  };
1279
1308
  readonly 418: {
1280
1309
  readonly code: "IM_A_TEAPOT";
1281
1310
  readonly name: "ImATeapotError";
1282
1311
  readonly message: "I'm a teapot.";
1283
- readonly uiMessage: "I'm a teapot and cannot brew coffee.";
1284
1312
  };
1285
1313
  readonly 422: {
1286
1314
  readonly code: "UNPROCESSABLE_ENTITY";
1287
1315
  readonly name: "UnprocessableEntityError";
1288
1316
  readonly message: "Unprocessable entity.";
1289
- readonly uiMessage: "The request contains invalid data. Please check your input.";
1290
1317
  };
1291
1318
  readonly 423: {
1292
1319
  readonly code: "LOCKED";
1293
1320
  readonly name: "LockedError";
1294
1321
  readonly message: "Locked.";
1295
- readonly uiMessage: "This resource is locked and cannot be modified.";
1296
1322
  };
1297
1323
  readonly 424: {
1298
1324
  readonly code: "FAILED_DEPENDENCY";
1299
1325
  readonly name: "FailedDependencyError";
1300
1326
  readonly message: "Failed dependency.";
1301
- readonly uiMessage: "The request failed due to a dependency error.";
1302
1327
  };
1303
1328
  readonly 425: {
1304
1329
  readonly code: "TOO_EARLY";
1305
1330
  readonly name: "TooEarlyError";
1306
1331
  readonly message: "Too early.";
1307
- readonly uiMessage: "The request was sent too early. Please try again later.";
1308
1332
  };
1309
1333
  readonly 426: {
1310
1334
  readonly code: "UPGRADE_REQUIRED";
1311
1335
  readonly name: "UpgradeRequiredError";
1312
1336
  readonly message: "Upgrade required.";
1313
- readonly uiMessage: "Please upgrade to continue using this service.";
1314
1337
  };
1315
1338
  readonly 428: {
1316
1339
  readonly code: "PRECONDITION_REQUIRED";
1317
1340
  readonly name: "PreconditionRequiredError";
1318
1341
  readonly message: "Precondition required.";
1319
- readonly uiMessage: "Required conditions are missing from the request.";
1320
1342
  };
1321
1343
  readonly 429: {
1322
1344
  readonly code: "TOO_MANY_REQUESTS";
1323
1345
  readonly name: "TooManyRequestsError";
1324
1346
  readonly message: "Too many requests.";
1325
- readonly uiMessage: "You have made too many requests. Please wait and try again.";
1326
1347
  };
1327
1348
  readonly 431: {
1328
1349
  readonly code: "REQUEST_HEADER_FIELDS_TOO_LARGE";
1329
1350
  readonly name: "RequestHeaderFieldsTooLargeError";
1330
1351
  readonly message: "Request header fields too large.";
1331
- readonly uiMessage: "The request headers are too large.";
1332
1352
  };
1333
1353
  readonly 451: {
1334
1354
  readonly code: "UNAVAILABLE_FOR_LEGAL_REASONS";
1335
1355
  readonly name: "UnavailableForLegalReasonsError";
1336
1356
  readonly message: "Unavailable for legal reasons.";
1337
- readonly uiMessage: "This content is unavailable for legal reasons.";
1338
1357
  };
1339
1358
  readonly 500: {
1340
1359
  readonly code: "INTERNAL_SERVER_ERROR";
1341
1360
  readonly name: "InternalServerError";
1342
1361
  readonly message: "Internal server error.";
1343
- readonly uiMessage: "An unexpected error occurred. Please try again later.";
1344
1362
  };
1345
1363
  readonly 501: {
1346
1364
  readonly code: "NOT_IMPLEMENTED";
1347
1365
  readonly name: "NotImplementedError";
1348
1366
  readonly message: "Not implemented.";
1349
- readonly uiMessage: "This feature is not yet available.";
1350
1367
  };
1351
1368
  readonly 502: {
1352
1369
  readonly code: "BAD_GATEWAY";
1353
1370
  readonly name: "BadGatewayError";
1354
1371
  readonly message: "Bad gateway.";
1355
- readonly uiMessage: "Unable to connect to the server. Please try again later.";
1356
1372
  };
1357
1373
  readonly 503: {
1358
1374
  readonly code: "SERVICE_UNAVAILABLE";
1359
1375
  readonly name: "ServiceUnavailableError";
1360
1376
  readonly message: "Service unavailable.";
1361
- readonly uiMessage: "The service is temporarily unavailable. Please try again later.";
1362
1377
  };
1363
1378
  readonly 504: {
1364
1379
  readonly code: "GATEWAY_TIMEOUT";
1365
1380
  readonly name: "GatewayTimeoutError";
1366
1381
  readonly message: "Gateway timeout.";
1367
- readonly uiMessage: "The server took too long to respond. Please try again.";
1368
1382
  };
1369
1383
  readonly 505: {
1370
1384
  readonly code: "HTTP_VERSION_NOT_SUPPORTED";
1371
1385
  readonly name: "HttpVersionNotSupportedError";
1372
1386
  readonly message: "HTTP version not supported.";
1373
- readonly uiMessage: "Your browser version is not supported.";
1374
1387
  };
1375
1388
  readonly 506: {
1376
1389
  readonly code: "VARIANT_ALSO_NEGOTIATES";
1377
1390
  readonly name: "VariantAlsoNegotiatesError";
1378
1391
  readonly message: "Variant also negotiates.";
1379
- readonly uiMessage: "The server has an internal configuration error.";
1380
1392
  };
1381
1393
  readonly 507: {
1382
1394
  readonly code: "INSUFFICIENT_STORAGE";
1383
1395
  readonly name: "InsufficientStorageError";
1384
1396
  readonly message: "Insufficient storage.";
1385
- readonly uiMessage: "The server has insufficient storage to complete the request.";
1386
1397
  };
1387
1398
  readonly 508: {
1388
1399
  readonly code: "LOOP_DETECTED";
1389
1400
  readonly name: "LoopDetectedError";
1390
1401
  readonly message: "Loop detected.";
1391
- readonly uiMessage: "The server detected an infinite loop.";
1392
1402
  };
1393
1403
  readonly 510: {
1394
1404
  readonly code: "NOT_EXTENDED";
1395
1405
  readonly name: "NotExtendedError";
1396
1406
  readonly message: "Not extended.";
1397
- readonly uiMessage: "Additional extensions are required.";
1398
1407
  };
1399
1408
  readonly 511: {
1400
1409
  readonly code: "NETWORK_AUTHENTICATION_REQUIRED";
1401
1410
  readonly name: "NetworkAuthenticationRequiredError";
1402
1411
  readonly message: "Network authentication required.";
1403
- readonly uiMessage: "Network authentication is required to access this resource.";
1404
1412
  };
1405
1413
  };
1406
1414
  /** Default to 500 Internal Server Error when no preset specified */
@@ -1465,6 +1473,10 @@ type ValidationErrorXMetadata = {
1465
1473
  /** All Zod issues (for multi-error handling) */
1466
1474
  issues?: ZodIssue[];
1467
1475
  };
1476
+ /**
1477
+ * Default user-friendly message for validation errors.
1478
+ */
1479
+ declare const validationErrorUiMessage = "The provided input is invalid. Please check your data.";
1468
1480
  /**
1469
1481
  * Validation Error class designed for Zod integration.
1470
1482
  *
@@ -1502,7 +1514,6 @@ type ValidationErrorXMetadata = {
1502
1514
  *
1503
1515
  * // With overrides
1504
1516
  * ValidationErrorX.fromZodError(zodError, {
1505
- * uiMessage: 'Please check your input',
1506
1517
  * httpStatus: 422,
1507
1518
  * })
1508
1519
  *
@@ -1520,7 +1531,7 @@ type ValidationErrorXMetadata = {
1520
1531
  * if (err instanceof ValidationErrorX) {
1521
1532
  * return res.status(err.httpStatus).json({
1522
1533
  * error: err.code,
1523
- * message: err.uiMessage,
1534
+ * message: err.message,
1524
1535
  * field: err.metadata?.field,
1525
1536
  * })
1526
1537
  * }
@@ -1536,7 +1547,6 @@ declare class ValidationErrorX extends ErrorX<ValidationErrorXMetadata> {
1536
1547
  name: string;
1537
1548
  code: string;
1538
1549
  message: string;
1539
- uiMessage: string;
1540
1550
  };
1541
1551
  /**
1542
1552
  * Transform that maps Zod issue codes to VALIDATION_ prefixed codes.
@@ -1566,9 +1576,9 @@ declare class ValidationErrorX extends ErrorX<ValidationErrorXMetadata> {
1566
1576
  * }
1567
1577
  * }
1568
1578
  *
1569
- * // With custom uiMessage
1579
+ * // With custom message
1570
1580
  * ValidationErrorX.fromZodError(zodError, {
1571
- * uiMessage: 'Please fix the form errors',
1581
+ * message: 'Please fix the form errors',
1572
1582
  * })
1573
1583
  *
1574
1584
  * // Access all issues
@@ -1604,4 +1614,60 @@ declare class ValidationErrorX extends ErrorX<ValidationErrorXMetadata> {
1604
1614
  static forField(field: string, message: string, options?: Partial<ErrorXOptions<ValidationErrorXMetadata>>): ValidationErrorX;
1605
1615
  }
1606
1616
 
1607
- export { type DBErrorXPresetKey as DBErrorPreset, DBErrorX, type DBErrorXMetadata, ErrorX, type ErrorXConfig, type ErrorXMetadata, type ErrorXOptions, type ErrorXSerialized, type ErrorXSnapshot, type ErrorXTransform, type ErrorXTransformContext, HTTPErrorX, type HTTPErrorXMetadata, type HTTPErrorXPresetKey as HTTPStatusCode, ValidationErrorX, type ValidationErrorXMetadata, type ZodIssue };
1617
+ /**
1618
+ * Resolves ErrorX errors to enhanced presentation objects.
1619
+ * Supports i18n translations, documentation URLs, and custom properties.
1620
+ *
1621
+ * @example
1622
+ * ```typescript
1623
+ * const resolver = new ErrorXResolver({
1624
+ * i18n: { resolver: i18next.t },
1625
+ * docs: { baseUrl: 'https://docs.example.com' },
1626
+ * onResolveType: (error) => error.code.startsWith('API_') ? 'api' : 'general',
1627
+ * configs: {
1628
+ * api: { namespace: 'errors.api', docsPath: '/api' },
1629
+ * general: { namespace: 'errors' },
1630
+ * },
1631
+ * });
1632
+ *
1633
+ * const result = resolver.resolve(error, 'es');
1634
+ * ```
1635
+ *
1636
+ * @public
1637
+ */
1638
+ declare class ErrorXResolver<TConfig extends ErrorXBaseConfig = ErrorXBaseConfig, TResult = ResolveContext<TConfig>> {
1639
+ private readonly options;
1640
+ private readonly defaultKeyTemplate;
1641
+ constructor(options: ErrorXResolverOptions<TConfig, TResult>);
1642
+ /**
1643
+ * Resolves an error to its enhanced representation.
1644
+ *
1645
+ * @param error - The ErrorX instance to resolve
1646
+ * @param _locale - Optional locale for i18n (passed to resolver function)
1647
+ * @returns The resolved result (ResolveContext or custom TResult)
1648
+ */
1649
+ resolve(error: ErrorX, _locale?: string): TResult;
1650
+ /**
1651
+ * Merges config from defaults → type → preset
1652
+ */
1653
+ private mergeConfig;
1654
+ /**
1655
+ * Builds the i18n key from template
1656
+ */
1657
+ private buildI18nKey;
1658
+ /**
1659
+ * Resolves uiMessage following the priority order:
1660
+ * 1. presets[code].uiMessage (already merged into config if from preset)
1661
+ * 2. i18n resolver result (if configured)
1662
+ * 3. configs[errorType].uiMessage (fallback)
1663
+ * 4. defaults.uiMessage (fallback)
1664
+ * 5. undefined
1665
+ */
1666
+ private resolveUiMessage;
1667
+ /**
1668
+ * Builds the full documentation URL
1669
+ */
1670
+ private buildDocsUrl;
1671
+ }
1672
+
1673
+ export { type DBErrorXPresetKey as DBErrorPreset, DBErrorX, type DBErrorXMetadata, ErrorX, type ErrorXBaseConfig, type ErrorXConfig, type ErrorXMetadata, type ErrorXOptions, ErrorXResolver, type ErrorXResolverConfig, type ErrorXResolverDocsConfig, type ErrorXResolverI18nConfig, type ErrorXResolverOptions, type ErrorXResolverTypeConfig, type ErrorXSerialized, type ErrorXSnapshot, type ErrorXTransform, type ErrorXTransformContext, HTTPErrorX, type HTTPErrorXMetadata, type HTTPErrorXPresetKey as HTTPStatusCode, type ResolveContext, ValidationErrorX, type ValidationErrorXMetadata, type ZodIssue, dbErrorUiMessages, httpErrorUiMessages, validationErrorUiMessage };