@pedrohb/errors 0.0.0-stage → 1.0.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/LICENSE +21 -0
- package/README.md +52 -3
- package/dist/error-params-CR2parjT.d.cts +387 -0
- package/dist/error-params-CR2parjT.d.mts +387 -0
- package/dist/errors/index.cjs +6 -0
- package/dist/errors/index.d.cts +115 -0
- package/dist/errors/index.d.mts +115 -0
- package/dist/errors/index.mjs +3 -0
- package/dist/errors-DrDL51y9.mjs +149 -0
- package/dist/errors-DrDL51y9.mjs.map +1 -0
- package/dist/errors-TgPe2YUV.cjs +178 -0
- package/dist/errors-TgPe2YUV.cjs.map +1 -0
- package/dist/functions/index.cjs +408 -0
- package/dist/functions/index.cjs.map +1 -0
- package/dist/functions/index.d.cts +3 -0
- package/dist/functions/index.d.mts +3 -0
- package/dist/functions/index.mjs +399 -0
- package/dist/functions/index.mjs.map +1 -0
- package/dist/index-B4tdSdCF.d.mts +544 -0
- package/dist/index-BzFCOXvr.d.cts +544 -0
- package/dist/index.cjs +637 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +510 -0
- package/dist/index.d.mts +510 -0
- package/dist/index.mjs +614 -0
- package/dist/index.mjs.map +1 -0
- package/dist/invalid-param-delimiters-error-BFxlVXp3.mjs +44 -0
- package/dist/invalid-param-delimiters-error-BFxlVXp3.mjs.map +1 -0
- package/dist/invalid-param-delimiters-error-C6UxV7cK.cjs +49 -0
- package/dist/invalid-param-delimiters-error-C6UxV7cK.cjs.map +1 -0
- package/dist/types/index.cjs +0 -0
- package/dist/types/index.d.cts +143 -0
- package/dist/types/index.d.mts +143 -0
- package/dist/types/index.mjs +1 -0
- package/package.json +117 -3
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_invalid_param_delimiters_error = require("../invalid-param-delimiters-error-C6UxV7cK.cjs");
|
|
3
|
+
//#region src/functions/escape-reg-exp.ts
|
|
4
|
+
/**
|
|
5
|
+
* Escapa os caracteres especiais de expressões regulares em uma string, para
|
|
6
|
+
* que ela possa ser usada como texto literal dentro de um `RegExp`.
|
|
7
|
+
*
|
|
8
|
+
* Cada caractere especial (`. * + ? ^ $ { } ( ) | [ ] \`) é precedido por uma
|
|
9
|
+
* barra invertida. Caracteres comuns permanecem inalterados.
|
|
10
|
+
*
|
|
11
|
+
* Útil por exemplo, para montar uma expressão regular a partir de
|
|
12
|
+
* delimitadores informados pelo usuário (como os de placeholders), sem que
|
|
13
|
+
* símbolos como `[` ou `{` sejam interpretados como parte da sintaxe.
|
|
14
|
+
*
|
|
15
|
+
* @param value - String a ser escapada.
|
|
16
|
+
* @returns A string com os caracteres especiais escapados.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* escapeRegExp("{id}"); // "\\{id\\}"
|
|
21
|
+
* escapeRegExp("[nome]"); // "\\[nome\\]"
|
|
22
|
+
* escapeRegExp("a.b*c"); // "a\\.b\\*c"
|
|
23
|
+
* escapeRegExp("texto livre"); // "texto livre"
|
|
24
|
+
*
|
|
25
|
+
* const regex = new RegExp(escapeRegExp("(x)"), "g");
|
|
26
|
+
* "valor (x) aqui".replace(regex, "1"); // "valor 1 aqui"
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
function escapeRegExp(value) {
|
|
30
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/functions/create-param-placeholder.ts
|
|
34
|
+
/**
|
|
35
|
+
* Delimitadores padrão dos placeholders em mensagens de erro: `{` para abrir
|
|
36
|
+
* e `}` para fechar (ex.: `{id}`).
|
|
37
|
+
*
|
|
38
|
+
* Declarado com `as const`, então mantém os tipos literais `"{"` e `"}"`,
|
|
39
|
+
* o que permite derivar {@link DefaultParamDelimiters} a partir dele.
|
|
40
|
+
*/
|
|
41
|
+
const DEFAULT_PARAM_DELIMITERS = {
|
|
42
|
+
open: "{",
|
|
43
|
+
close: "}"
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Cria uma expressão regular global que localiza os placeholders de uma
|
|
47
|
+
* mensagem de erro com base nos delimitadores informados.
|
|
48
|
+
*
|
|
49
|
+
* Os delimitadores são escapados com {@link escapeRegExp}, então símbolos como
|
|
50
|
+
* `[`, `(` ou `$` são tratados como texto literal. Delimitadores com mais de
|
|
51
|
+
* um caractere (ex.: `{{` e `}}`) também são aceitos.
|
|
52
|
+
*
|
|
53
|
+
* Em cada correspondência o grupo de captura `1` contém o texto entre os
|
|
54
|
+
* delimitadores, exatamente como aparece na mensagem (sem aparar espaços).
|
|
55
|
+
* O conteúdo pode ocupar várias linhas, mas não pode conter os delimitadores
|
|
56
|
+
* de abertura ou de fechamento. Em casos como `{{id}}` a correspondência
|
|
57
|
+
* recai sobre o par mais interno (`{id}`). Placeholders vazios (ex.: `{}`)
|
|
58
|
+
* também correspondem com o grupo `1` igual a `""`.
|
|
59
|
+
*
|
|
60
|
+
* Cada chamada devolve uma nova instância de `RegExp`. Como ela usa a flag
|
|
61
|
+
* `g` que mantém estado em `lastIndex`, isso evita que usos diferentes
|
|
62
|
+
* compartilhem o mesmo estado.
|
|
63
|
+
*
|
|
64
|
+
* @param delimiters - Delimitadores `open` e `close` do placeholder. Por
|
|
65
|
+
* padrão, {@link DEFAULT_PARAM_DELIMITERS} (`{` e `}`).
|
|
66
|
+
* @returns Expressão regular global que corresponde a cada placeholder.
|
|
67
|
+
* @throws {InvalidParamDelimitersError} Se `open` ou `close` for uma string
|
|
68
|
+
* vazia.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* const regex = createParamPlaceholder();
|
|
73
|
+
*
|
|
74
|
+
* for (const match of "Usuário {id} não encontrado em {table}".matchAll(regex)) {
|
|
75
|
+
* console.log(match[1]);
|
|
76
|
+
* }
|
|
77
|
+
* // "id"
|
|
78
|
+
* // "table"
|
|
79
|
+
*
|
|
80
|
+
* "Olá, {nome}!".replace(regex, (_, param) => `<${param}>`);
|
|
81
|
+
* // "Olá, <nome>!"
|
|
82
|
+
*
|
|
83
|
+
* // Delimitadores personalizados
|
|
84
|
+
* const brackets = createParamPlaceholder({ open: "[", close: "]" });
|
|
85
|
+
* "Rota [route] não encontrada".match(brackets); // ["[route]"]
|
|
86
|
+
*
|
|
87
|
+
* // Delimitadores vazios não são permitidos
|
|
88
|
+
* createParamPlaceholder({ open: "", close: "}" });
|
|
89
|
+
* // Lança InvalidParamDelimitersError
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
function createParamPlaceholder(delimiters = DEFAULT_PARAM_DELIMITERS) {
|
|
93
|
+
const { open, close } = delimiters;
|
|
94
|
+
if (open === "" || close === "") throw new require_invalid_param_delimiters_error.InvalidParamDelimitersError();
|
|
95
|
+
const o = escapeRegExp(open);
|
|
96
|
+
const c = escapeRegExp(close);
|
|
97
|
+
return new RegExp(`${o}((?:(?!${o}|${c})[\\s\\S])*)${c}`, "g");
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/functions/is-base-error.ts
|
|
101
|
+
/**
|
|
102
|
+
* Símbolo usado como marca ("brand") para identificar instâncias de
|
|
103
|
+
* `BaseError` em tempo de execução.
|
|
104
|
+
*
|
|
105
|
+
* É criado com `Symbol.for` que consulta o registro global de símbolos. Assim
|
|
106
|
+
* mesmo que o pacote seja carregado mais de uma vez (ex.: versões duplicadas
|
|
107
|
+
* em `node_modules` ou diferentes bundles), todas as cópias compartilham o
|
|
108
|
+
* mesmo símbolo e {@link isBaseError} continua reconhecendo os erros, algo que
|
|
109
|
+
* `instanceof` sozinho não garante.
|
|
110
|
+
*/
|
|
111
|
+
const BASE_ERROR_BRAND = Symbol.for("@pedrohb/errors/base-error");
|
|
112
|
+
/**
|
|
113
|
+
* Verifica se um valor é uma instância de `BaseError` funcionando como um
|
|
114
|
+
* type guard.
|
|
115
|
+
*
|
|
116
|
+
* A checagem exige que o valor seja uma instância de `Error` e que possua a
|
|
117
|
+
* propriedade marcada por {@link BASE_ERROR_BRAND} com o valor `true`. Por
|
|
118
|
+
* usar a marca em vez de `instanceof BaseError`, o resultado é confiável
|
|
119
|
+
* mesmo quando há múltiplas cópias do pacote carregadas na mesma aplicação.
|
|
120
|
+
*
|
|
121
|
+
* @param value - Valor a ser verificado.
|
|
122
|
+
* @returns `true` se `value` for um `BaseError` (e nesse caso o TypeScript
|
|
123
|
+
* restringe o tipo para `BaseError`); caso contrário `false`.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* try {
|
|
128
|
+
* await execute();
|
|
129
|
+
* } catch (error) {
|
|
130
|
+
* if (isBaseError(error)) {
|
|
131
|
+
* console.log(error.code); // `error` é tipado como BaseError
|
|
132
|
+
* } else {
|
|
133
|
+
* throw error;
|
|
134
|
+
* }
|
|
135
|
+
* }
|
|
136
|
+
*
|
|
137
|
+
* isBaseError(new Error("comum")); // false
|
|
138
|
+
* isBaseError("texto"); // false
|
|
139
|
+
* isBaseError(null); // false
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
function isBaseError(value) {
|
|
143
|
+
return value instanceof Error && value[BASE_ERROR_BRAND] === true;
|
|
144
|
+
}
|
|
145
|
+
//#endregion
|
|
146
|
+
//#region src/functions/serialize-native-error.ts
|
|
147
|
+
/**
|
|
148
|
+
* Serializa um `Error` nativo para um objeto simples
|
|
149
|
+
* ({@link SerializedNativeError}) apropriado para `JSON.stringify`, logs ou
|
|
150
|
+
* transmissão.
|
|
151
|
+
*
|
|
152
|
+
* O resultado sempre contém `message` e `name`. As demais propriedades são
|
|
153
|
+
* incluídas apenas quando aplicável:
|
|
154
|
+
* - `cause`: se o erro tiver causa (`error.cause !== undefined`) serializada
|
|
155
|
+
* com {@link serializeCauseError};
|
|
156
|
+
* - `errors`: se o erro tiver uma propriedade `errors` que seja um array
|
|
157
|
+
* (como em `AggregateError`) com cada item serializado com
|
|
158
|
+
* {@link serializeCauseError};
|
|
159
|
+
* - `stack`: somente se `includeStack` for `true`.
|
|
160
|
+
*
|
|
161
|
+
* **Referências circulares:** o erro é registrado em `seen` durante a
|
|
162
|
+
* serialização e removido ao final (mesmo se ocorrer uma exceção). Assim se
|
|
163
|
+
* `cause` ou algum item de `errors` apontar de volta para este mesmo erro, o
|
|
164
|
+
* ponto de repetição é substituído por `"[Circular]"` em vez de causar
|
|
165
|
+
* recursão infinita. Por ser removido ao terminar, o mesmo erro pode aparecer
|
|
166
|
+
* em lugares distintos (sem ciclo) e ser serializado por completo em cada um.
|
|
167
|
+
*
|
|
168
|
+
* **Limitações:** apenas `message`, `name`, `cause`, `errors` e `stack` são
|
|
169
|
+
* copiados. Propriedades adicionais definidas em subclasses (ex.: `code` ou
|
|
170
|
+
* `status`) não são incluídas.
|
|
171
|
+
*
|
|
172
|
+
* @param error - `Error` a ser serializado.
|
|
173
|
+
* @param includeStack - Se `true` inclui o stack trace no resultado e o
|
|
174
|
+
* repassa à serialização da causa e dos erros agregados. Por padrão, `false`.
|
|
175
|
+
* @param seen - Conjunto de referências em processo de serialização usado
|
|
176
|
+
* internamente na recursão para detectar ciclos. Em geral não deve ser
|
|
177
|
+
* informado; por padrão, um novo `WeakSet` vazio.
|
|
178
|
+
* @returns Objeto serializável que representa o erro.
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```ts
|
|
182
|
+
* serializeNativeError(new TypeError("valor inválido"));
|
|
183
|
+
* // { message: "valor inválido", name: "TypeError" }
|
|
184
|
+
*
|
|
185
|
+
* // Com stack trace
|
|
186
|
+
* serializeNativeError(new Error("falhou"), true);
|
|
187
|
+
* // { message: "falhou", name: "Error", stack: "Error: falhou\n at ..." }
|
|
188
|
+
*
|
|
189
|
+
* // Com causa
|
|
190
|
+
* serializeNativeError(new Error("falhou", { cause: "timeout" }));
|
|
191
|
+
* // { cause: "timeout", message: "falhou", name: "Error" }
|
|
192
|
+
*
|
|
193
|
+
* // Com erros agregados
|
|
194
|
+
* serializeNativeError(
|
|
195
|
+
* new AggregateError([new Error("a"), new Error("b")], "vários erros"),
|
|
196
|
+
* );
|
|
197
|
+
* // {
|
|
198
|
+
* // errors: [
|
|
199
|
+
* // { message: "a", name: "Error" },
|
|
200
|
+
* // { message: "b", name: "Error" },
|
|
201
|
+
* // ],
|
|
202
|
+
* // message: "vários erros",
|
|
203
|
+
* // name: "AggregateError",
|
|
204
|
+
* // }
|
|
205
|
+
*
|
|
206
|
+
* // Referência circular
|
|
207
|
+
* const error = new Error("ciclo");
|
|
208
|
+
* error.cause = error;
|
|
209
|
+
* serializeNativeError(error);
|
|
210
|
+
* // { cause: "[Circular]", message: "ciclo", name: "Error" }
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
function serializeNativeError(error, includeStack = false, seen = /* @__PURE__ */ new WeakSet()) {
|
|
214
|
+
seen.add(error);
|
|
215
|
+
try {
|
|
216
|
+
const errors = "errors" in error && Array.isArray(error.errors) ? error.errors : void 0;
|
|
217
|
+
return {
|
|
218
|
+
...error.cause !== void 0 && { cause: serializeCauseError(error.cause, includeStack, seen) },
|
|
219
|
+
...errors && { errors: errors.map((item) => serializeCauseError(item, includeStack, seen)) },
|
|
220
|
+
message: error.message,
|
|
221
|
+
name: error.name,
|
|
222
|
+
...includeStack && { stack: error.stack }
|
|
223
|
+
};
|
|
224
|
+
} finally {
|
|
225
|
+
seen.delete(error);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
//#endregion
|
|
229
|
+
//#region src/functions/serialize-cause-error.ts
|
|
230
|
+
/**
|
|
231
|
+
* Texto que substitui uma referência circular durante a serialização.
|
|
232
|
+
*
|
|
233
|
+
* É retornado no lugar de um objeto que já está sendo serializado mais acima
|
|
234
|
+
* na mesma cadeia evitando recursão infinita.
|
|
235
|
+
*/
|
|
236
|
+
const CIRCULAR_MARKER = "[Circular]";
|
|
237
|
+
/**
|
|
238
|
+
* Serializa de forma segura, o valor de uma `cause` (causa) de erro para uma
|
|
239
|
+
* estrutura simples e apropriada para `JSON.stringify`, logs ou transmissão.
|
|
240
|
+
*
|
|
241
|
+
* A conversão depende do tipo do valor:
|
|
242
|
+
* - `string`, `number`, `boolean` e `undefined`: retornados sem alteração;
|
|
243
|
+
* - `null`: retorna `null`;
|
|
244
|
+
* - `bigint` e `symbol`: convertidos para texto com `toString()`
|
|
245
|
+
* (ex.: `10n` vira `"10"`);
|
|
246
|
+
* - função: vira o texto `"[Function: nome]"` ou `"[Function: anonymous]"`
|
|
247
|
+
* se não tiver nome;
|
|
248
|
+
* - `BaseError`: delegado a {@link serializeBaseError};
|
|
249
|
+
* - `Error` nativo: delegado a {@link serializeNativeError};
|
|
250
|
+
* - `Date`: convertida para string ISO 8601 ou `"Invalid Date"` se a data
|
|
251
|
+
* for inválida;
|
|
252
|
+
* - array: cada item é serializado recursivamente;
|
|
253
|
+
* - objeto comum: cada propriedade própria enumerável de chave `string` é
|
|
254
|
+
* serializada recursivamente, resultando em um novo objeto simples.
|
|
255
|
+
*
|
|
256
|
+
* **Referências circulares:** apenas as referências da cadeia atual (os
|
|
257
|
+
* "ancestrais" do valor sendo serializado) são rastreadas. Quando um objeto
|
|
258
|
+
* aparece dentro de si mesmo o ponto de repetição é substituído por
|
|
259
|
+
* {@link CIRCULAR_MARKER}. Como cada objeto é removido do conjunto ao terminar
|
|
260
|
+
* de ser serializado, um mesmo objeto referenciado em dois lugares distintos
|
|
261
|
+
* (sem ciclo) é serializado por completo nas duas ocorrências e não marcado
|
|
262
|
+
* como circular.
|
|
263
|
+
*
|
|
264
|
+
* **Limitações:** protótipos e métodos de objetos comuns são descartados e
|
|
265
|
+
* propriedades com chave `symbol` são ignoradas. Instâncias como `Map` e
|
|
266
|
+
* `Set`, que não possuem propriedades próprias enumeráveis resultam em `{}`.
|
|
267
|
+
*
|
|
268
|
+
* @param cause - Valor a ser serializado normalmente a propriedade `cause`
|
|
269
|
+
* de um erro, mas pode ser qualquer valor.
|
|
270
|
+
* @param includeStack - Se `true`, inclui o stack trace ao serializar erros
|
|
271
|
+
* (`BaseError` e `Error` nativo), repassando a opção aos respectivos
|
|
272
|
+
* serializadores. Por padrão, `false`.
|
|
273
|
+
* @param seen - Conjunto de referências em processo de serialização usado
|
|
274
|
+
* internamente na recursão para detectar ciclos. Em geral não deve ser
|
|
275
|
+
* informado; por padrão, um novo `WeakSet` vazio.
|
|
276
|
+
* @returns Representação serializável do valor cujo formato depende do tipo
|
|
277
|
+
* recebido (ver lista acima).
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* ```ts
|
|
281
|
+
* serializeCauseError("falha"); // "falha"
|
|
282
|
+
* serializeCauseError(10n); // "10"
|
|
283
|
+
* serializeCauseError(Symbol("x")); // "Symbol(x)"
|
|
284
|
+
* serializeCauseError(function foo() {}); // "[Function: foo]"
|
|
285
|
+
* serializeCauseError(new Date("2026-01-01T00:00:00Z"));
|
|
286
|
+
* // "2026-01-01T00:00:00.000Z"
|
|
287
|
+
* serializeCauseError(new Date("inválida")); // "Invalid Date"
|
|
288
|
+
*
|
|
289
|
+
* // Estruturas aninhadas
|
|
290
|
+
* serializeCauseError({ ids: [1, 2n], origin: null });
|
|
291
|
+
* // { ids: [1, "2"], origin: null }
|
|
292
|
+
*
|
|
293
|
+
* // Referência circular
|
|
294
|
+
* const a: Record<string, unknown> = { name: "a" };
|
|
295
|
+
* a.self = a;
|
|
296
|
+
* serializeCauseError(a);
|
|
297
|
+
* // { name: "a", self: "[Circular]" }
|
|
298
|
+
*
|
|
299
|
+
* // Mesmo objeto em dois lugares (sem ciclo): serializado nas duas vezes
|
|
300
|
+
* const shared = { x: 1 };
|
|
301
|
+
* serializeCauseError({ a: shared, b: shared });
|
|
302
|
+
* // { a: { x: 1 }, b: { x: 1 } }
|
|
303
|
+
*
|
|
304
|
+
* // Erros, com stack trace opcional
|
|
305
|
+
* serializeCauseError(new Error("falhou"), true);
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
function serializeCauseError(cause, includeStack = false, seen = /* @__PURE__ */ new WeakSet()) {
|
|
309
|
+
switch (typeof cause) {
|
|
310
|
+
case "bigint":
|
|
311
|
+
case "symbol": return cause.toString();
|
|
312
|
+
case "function": return `[Function: ${cause.name || "anonymous"}]`;
|
|
313
|
+
case "object": break;
|
|
314
|
+
default: return cause;
|
|
315
|
+
}
|
|
316
|
+
if (cause === null) return null;
|
|
317
|
+
if (seen.has(cause)) return CIRCULAR_MARKER;
|
|
318
|
+
if (isBaseError(cause)) return serializeBaseError(cause, includeStack, seen);
|
|
319
|
+
if (cause instanceof Error) return serializeNativeError(cause, includeStack, seen);
|
|
320
|
+
if (cause instanceof Date) return Number.isNaN(cause.getTime()) ? "Invalid Date" : cause.toISOString();
|
|
321
|
+
seen.add(cause);
|
|
322
|
+
try {
|
|
323
|
+
if (Array.isArray(cause)) return cause.map((item) => serializeCauseError(item, includeStack, seen));
|
|
324
|
+
return Object.fromEntries(Object.entries(cause).map(([key, value]) => [key, serializeCauseError(value, includeStack, seen)]));
|
|
325
|
+
} finally {
|
|
326
|
+
seen.delete(cause);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
//#endregion
|
|
330
|
+
//#region src/functions/serialize-base-error.ts
|
|
331
|
+
/**
|
|
332
|
+
* Serializa um `BaseError` para um objeto simples ({@link SerializedBaseError})
|
|
333
|
+
* apropriado para `JSON.stringify`, logs ou transmissão.
|
|
334
|
+
*
|
|
335
|
+
* O resultado sempre contém `code`, `message` e `name`. As demais
|
|
336
|
+
* propriedades são incluídas apenas quando aplicável:
|
|
337
|
+
* - `cause`: se o erro tiver causa (`error.cause !== undefined`) serializada
|
|
338
|
+
* com {@link serializeCauseError};
|
|
339
|
+
* - `params`: se o erro tiver parâmetros (`error.params !== undefined`)
|
|
340
|
+
* também serializados com {@link serializeCauseError};
|
|
341
|
+
* - `stack`: somente se `includeStack` for `true`.
|
|
342
|
+
*
|
|
343
|
+
* **Referências circulares:** o erro é registrado em `seen` durante a
|
|
344
|
+
* serialização e removido ao final (mesmo se ocorrer uma exceção). Assim se
|
|
345
|
+
* alguma `cause` ou `params` apontar de volta para este mesmo erro, o ponto
|
|
346
|
+
* de repetição é substituído por `"[Circular]"` em vez de causar recursão
|
|
347
|
+
* infinita. Por ser removido ao terminar, o mesmo erro pode aparecer em
|
|
348
|
+
* lugares distintos (sem ciclo) e ser serializado por completo em cada um.
|
|
349
|
+
*
|
|
350
|
+
* @param error - `BaseError` a ser serializado.
|
|
351
|
+
* @param includeStack - Se `true` inclui o stack trace no resultado e o
|
|
352
|
+
* repassa à serialização da causa e dos parâmetros. Por padrão, `false`.
|
|
353
|
+
* @param seen - Conjunto de referências em processo de serialização usado
|
|
354
|
+
* internamente na recursão para detectar ciclos. Em geral não deve ser
|
|
355
|
+
* informado; por padrão, um novo `WeakSet` vazio.
|
|
356
|
+
* @returns Objeto serializável que representa o erro.
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* ```ts
|
|
360
|
+
* const error = new BaseError(ERROR_CODES.USER_NOT_FOUND, { id: 42 });
|
|
361
|
+
*
|
|
362
|
+
* serializeBaseError(error);
|
|
363
|
+
* // {
|
|
364
|
+
* // code: "USER_NOT_FOUND",
|
|
365
|
+
* // message: "Usuário 42 não encontrado",
|
|
366
|
+
* // name: "BaseError",
|
|
367
|
+
* // params: { id: 42 },
|
|
368
|
+
* // }
|
|
369
|
+
*
|
|
370
|
+
* // Com stack trace
|
|
371
|
+
* serializeBaseError(erro, true);
|
|
372
|
+
* // { ..., stack: "BaseError: Usuário 42 não encontrado\n at ..." }
|
|
373
|
+
*
|
|
374
|
+
* // Com causa
|
|
375
|
+
* const withCause = new BaseError(ERROR_CODES.INVALID_TOKEN, undefined, {
|
|
376
|
+
* cause: new Error("expirado"),
|
|
377
|
+
* });
|
|
378
|
+
* serializeBaseError(withCause);
|
|
379
|
+
* // { cause: { ... }, code: "INVALID_TOKEN", message: "Token inválido", name: "BaseError" }
|
|
380
|
+
* ```
|
|
381
|
+
*/
|
|
382
|
+
function serializeBaseError(error, includeStack = false, seen = /* @__PURE__ */ new WeakSet()) {
|
|
383
|
+
seen.add(error);
|
|
384
|
+
try {
|
|
385
|
+
return {
|
|
386
|
+
...error.cause !== void 0 && { cause: serializeCauseError(error.cause, includeStack, seen) },
|
|
387
|
+
code: error.code,
|
|
388
|
+
message: error.message,
|
|
389
|
+
name: error.name,
|
|
390
|
+
...error.params !== void 0 && { params: serializeCauseError(error.params, includeStack, seen) },
|
|
391
|
+
...includeStack && { stack: error.stack }
|
|
392
|
+
};
|
|
393
|
+
} finally {
|
|
394
|
+
seen.delete(error);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
//#endregion
|
|
398
|
+
exports.BASE_ERROR_BRAND = BASE_ERROR_BRAND;
|
|
399
|
+
exports.CIRCULAR_MARKER = CIRCULAR_MARKER;
|
|
400
|
+
exports.DEFAULT_PARAM_DELIMITERS = DEFAULT_PARAM_DELIMITERS;
|
|
401
|
+
exports.createParamPlaceholder = createParamPlaceholder;
|
|
402
|
+
exports.escapeRegExp = escapeRegExp;
|
|
403
|
+
exports.isBaseError = isBaseError;
|
|
404
|
+
exports.serializeBaseError = serializeBaseError;
|
|
405
|
+
exports.serializeCauseError = serializeCauseError;
|
|
406
|
+
exports.serializeNativeError = serializeNativeError;
|
|
407
|
+
|
|
408
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["InvalidParamDelimitersError"],"sources":["../../src/functions/escape-reg-exp.ts","../../src/functions/create-param-placeholder.ts","../../src/functions/is-base-error.ts","../../src/functions/serialize-native-error.ts","../../src/functions/serialize-cause-error.ts","../../src/functions/serialize-base-error.ts"],"sourcesContent":["/**\r\n * Escapa os caracteres especiais de expressões regulares em uma string, para\r\n * que ela possa ser usada como texto literal dentro de um `RegExp`.\r\n *\r\n * Cada caractere especial (`. * + ? ^ $ { } ( ) | [ ] \\`) é precedido por uma\r\n * barra invertida. Caracteres comuns permanecem inalterados.\r\n *\r\n * Útil por exemplo, para montar uma expressão regular a partir de\r\n * delimitadores informados pelo usuário (como os de placeholders), sem que\r\n * símbolos como `[` ou `{` sejam interpretados como parte da sintaxe.\r\n *\r\n * @param value - String a ser escapada.\r\n * @returns A string com os caracteres especiais escapados.\r\n *\r\n * @example\r\n * ```ts\r\n * escapeRegExp(\"{id}\"); // \"\\\\{id\\\\}\"\r\n * escapeRegExp(\"[nome]\"); // \"\\\\[nome\\\\]\"\r\n * escapeRegExp(\"a.b*c\"); // \"a\\\\.b\\\\*c\"\r\n * escapeRegExp(\"texto livre\"); // \"texto livre\"\r\n *\r\n * const regex = new RegExp(escapeRegExp(\"(x)\"), \"g\");\r\n * \"valor (x) aqui\".replace(regex, \"1\"); // \"valor 1 aqui\"\r\n * ```\r\n */\r\nexport function escapeRegExp(value: string) {\r\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n}\r\n","import { InvalidParamDelimitersError } from \"#/errors/invalid-param-delimiters-error.js\";\r\nimport type { ErrorParamDelimiters } from \"#/types/error-param-delimiters.js\";\r\nimport { escapeRegExp } from \"./escape-reg-exp.js\";\r\n\r\n/**\r\n * Delimitadores padrão dos placeholders em mensagens de erro: `{` para abrir\r\n * e `}` para fechar (ex.: `{id}`).\r\n *\r\n * Declarado com `as const`, então mantém os tipos literais `\"{\"` e `\"}\"`,\r\n * o que permite derivar {@link DefaultParamDelimiters} a partir dele.\r\n */\r\nexport const DEFAULT_PARAM_DELIMITERS = {\r\n open: \"{\",\r\n close: \"}\",\r\n} as const satisfies ErrorParamDelimiters;\r\n\r\n/**\r\n * Tipo dos delimitadores padrão equivalente a\r\n * `{ readonly open: \"{\"; readonly close: \"}\" }`.\r\n *\r\n * É usado como valor padrão de `Delimiters` em tipos como `ErrorParams`.\r\n */\r\nexport type DefaultParamDelimiters = typeof DEFAULT_PARAM_DELIMITERS;\r\n\r\n/**\r\n * Cria uma expressão regular global que localiza os placeholders de uma\r\n * mensagem de erro com base nos delimitadores informados.\r\n *\r\n * Os delimitadores são escapados com {@link escapeRegExp}, então símbolos como\r\n * `[`, `(` ou `$` são tratados como texto literal. Delimitadores com mais de\r\n * um caractere (ex.: `{{` e `}}`) também são aceitos.\r\n *\r\n * Em cada correspondência o grupo de captura `1` contém o texto entre os\r\n * delimitadores, exatamente como aparece na mensagem (sem aparar espaços).\r\n * O conteúdo pode ocupar várias linhas, mas não pode conter os delimitadores\r\n * de abertura ou de fechamento. Em casos como `{{id}}` a correspondência\r\n * recai sobre o par mais interno (`{id}`). Placeholders vazios (ex.: `{}`)\r\n * também correspondem com o grupo `1` igual a `\"\"`.\r\n *\r\n * Cada chamada devolve uma nova instância de `RegExp`. Como ela usa a flag\r\n * `g` que mantém estado em `lastIndex`, isso evita que usos diferentes\r\n * compartilhem o mesmo estado.\r\n *\r\n * @param delimiters - Delimitadores `open` e `close` do placeholder. Por\r\n * padrão, {@link DEFAULT_PARAM_DELIMITERS} (`{` e `}`).\r\n * @returns Expressão regular global que corresponde a cada placeholder.\r\n * @throws {InvalidParamDelimitersError} Se `open` ou `close` for uma string\r\n * vazia.\r\n *\r\n * @example\r\n * ```ts\r\n * const regex = createParamPlaceholder();\r\n *\r\n * for (const match of \"Usuário {id} não encontrado em {table}\".matchAll(regex)) {\r\n * console.log(match[1]);\r\n * }\r\n * // \"id\"\r\n * // \"table\"\r\n *\r\n * \"Olá, {nome}!\".replace(regex, (_, param) => `<${param}>`);\r\n * // \"Olá, <nome>!\"\r\n *\r\n * // Delimitadores personalizados\r\n * const brackets = createParamPlaceholder({ open: \"[\", close: \"]\" });\r\n * \"Rota [route] não encontrada\".match(brackets); // [\"[route]\"]\r\n *\r\n * // Delimitadores vazios não são permitidos\r\n * createParamPlaceholder({ open: \"\", close: \"}\" });\r\n * // Lança InvalidParamDelimitersError\r\n * ```\r\n */\r\nexport function createParamPlaceholder(\r\n delimiters: ErrorParamDelimiters = DEFAULT_PARAM_DELIMITERS,\r\n) {\r\n const { open, close } = delimiters;\r\n\r\n if (open === \"\" || close === \"\") {\r\n throw new InvalidParamDelimitersError();\r\n }\r\n\r\n const o = escapeRegExp(open);\r\n const c = escapeRegExp(close);\r\n\r\n return new RegExp(`${o}((?:(?!${o}|${c})[\\\\s\\\\S])*)${c}`, \"g\");\r\n}\r\n","import type { BaseError } from \"#/base-error.js\";\r\n\r\n/**\r\n * Símbolo usado como marca (\"brand\") para identificar instâncias de\r\n * `BaseError` em tempo de execução.\r\n *\r\n * É criado com `Symbol.for` que consulta o registro global de símbolos. Assim\r\n * mesmo que o pacote seja carregado mais de uma vez (ex.: versões duplicadas\r\n * em `node_modules` ou diferentes bundles), todas as cópias compartilham o\r\n * mesmo símbolo e {@link isBaseError} continua reconhecendo os erros, algo que\r\n * `instanceof` sozinho não garante.\r\n */\r\nexport const BASE_ERROR_BRAND = Symbol.for(\"@pedrohb/errors/base-error\");\r\n\r\n/**\r\n * Verifica se um valor é uma instância de `BaseError` funcionando como um\r\n * type guard.\r\n *\r\n * A checagem exige que o valor seja uma instância de `Error` e que possua a\r\n * propriedade marcada por {@link BASE_ERROR_BRAND} com o valor `true`. Por\r\n * usar a marca em vez de `instanceof BaseError`, o resultado é confiável\r\n * mesmo quando há múltiplas cópias do pacote carregadas na mesma aplicação.\r\n *\r\n * @param value - Valor a ser verificado.\r\n * @returns `true` se `value` for um `BaseError` (e nesse caso o TypeScript\r\n * restringe o tipo para `BaseError`); caso contrário `false`.\r\n *\r\n * @example\r\n * ```ts\r\n * try {\r\n * await execute();\r\n * } catch (error) {\r\n * if (isBaseError(error)) {\r\n * console.log(error.code); // `error` é tipado como BaseError\r\n * } else {\r\n * throw error;\r\n * }\r\n * }\r\n *\r\n * isBaseError(new Error(\"comum\")); // false\r\n * isBaseError(\"texto\"); // false\r\n * isBaseError(null); // false\r\n * ```\r\n */\r\nexport function isBaseError(value: unknown): value is BaseError {\r\n return (\r\n value instanceof Error &&\r\n (value as { [BASE_ERROR_BRAND]?: unknown })[BASE_ERROR_BRAND] === true\r\n );\r\n}\r\n","import {\r\n type SeenReferences,\r\n serializeCauseError,\r\n} from \"./serialize-cause-error.js\";\r\n\r\n/**\r\n * Representação serializável de um `Error` nativo (ou de uma subclasse que\r\n * não seja `BaseError`), composta apenas por valores simples e apropriada para\r\n * `JSON.stringify`, logs ou transmissão.\r\n *\r\n * As propriedades `cause`, `errors` e `stack` são opcionais e só aparecem\r\n * quando o erro as possui (ou no caso de `stack` quando solicitado).\r\n */\r\nexport type SerializedNativeError = Readonly<{\r\n /** Causa do erro já serializada com {@link serializeCauseError}. */\r\n cause?: unknown;\r\n /**\r\n * Lista de erros agregados já serializados. Presente em erros como\r\n * `AggregateError` que expõem uma propriedade `errors` do tipo array.\r\n */\r\n errors?: readonly unknown[];\r\n /** Mensagem do erro. */\r\n message: string;\r\n /** Nome do erro (ex.: `\"Error\"`, `\"TypeError\"`, `\"AggregateError\"`). */\r\n name: string;\r\n /** Stack trace do erro presente apenas se `includeStack` for `true`. */\r\n stack?: string;\r\n}>;\r\n\r\n/**\r\n * Serializa um `Error` nativo para um objeto simples\r\n * ({@link SerializedNativeError}) apropriado para `JSON.stringify`, logs ou\r\n * transmissão.\r\n *\r\n * O resultado sempre contém `message` e `name`. As demais propriedades são\r\n * incluídas apenas quando aplicável:\r\n * - `cause`: se o erro tiver causa (`error.cause !== undefined`) serializada\r\n * com {@link serializeCauseError};\r\n * - `errors`: se o erro tiver uma propriedade `errors` que seja um array\r\n * (como em `AggregateError`) com cada item serializado com\r\n * {@link serializeCauseError};\r\n * - `stack`: somente se `includeStack` for `true`.\r\n *\r\n * **Referências circulares:** o erro é registrado em `seen` durante a\r\n * serialização e removido ao final (mesmo se ocorrer uma exceção). Assim se\r\n * `cause` ou algum item de `errors` apontar de volta para este mesmo erro, o\r\n * ponto de repetição é substituído por `\"[Circular]\"` em vez de causar\r\n * recursão infinita. Por ser removido ao terminar, o mesmo erro pode aparecer\r\n * em lugares distintos (sem ciclo) e ser serializado por completo em cada um.\r\n *\r\n * **Limitações:** apenas `message`, `name`, `cause`, `errors` e `stack` são\r\n * copiados. Propriedades adicionais definidas em subclasses (ex.: `code` ou\r\n * `status`) não são incluídas.\r\n *\r\n * @param error - `Error` a ser serializado.\r\n * @param includeStack - Se `true` inclui o stack trace no resultado e o\r\n * repassa à serialização da causa e dos erros agregados. Por padrão, `false`.\r\n * @param seen - Conjunto de referências em processo de serialização usado\r\n * internamente na recursão para detectar ciclos. Em geral não deve ser\r\n * informado; por padrão, um novo `WeakSet` vazio.\r\n * @returns Objeto serializável que representa o erro.\r\n *\r\n * @example\r\n * ```ts\r\n * serializeNativeError(new TypeError(\"valor inválido\"));\r\n * // { message: \"valor inválido\", name: \"TypeError\" }\r\n *\r\n * // Com stack trace\r\n * serializeNativeError(new Error(\"falhou\"), true);\r\n * // { message: \"falhou\", name: \"Error\", stack: \"Error: falhou\\n at ...\" }\r\n *\r\n * // Com causa\r\n * serializeNativeError(new Error(\"falhou\", { cause: \"timeout\" }));\r\n * // { cause: \"timeout\", message: \"falhou\", name: \"Error\" }\r\n *\r\n * // Com erros agregados\r\n * serializeNativeError(\r\n * new AggregateError([new Error(\"a\"), new Error(\"b\")], \"vários erros\"),\r\n * );\r\n * // {\r\n * // errors: [\r\n * // { message: \"a\", name: \"Error\" },\r\n * // { message: \"b\", name: \"Error\" },\r\n * // ],\r\n * // message: \"vários erros\",\r\n * // name: \"AggregateError\",\r\n * // }\r\n *\r\n * // Referência circular\r\n * const error = new Error(\"ciclo\");\r\n * error.cause = error;\r\n * serializeNativeError(error);\r\n * // { cause: \"[Circular]\", message: \"ciclo\", name: \"Error\" }\r\n * ```\r\n */\r\nexport function serializeNativeError(\r\n error: Error,\r\n includeStack = false,\r\n seen: SeenReferences = new WeakSet(),\r\n): SerializedNativeError {\r\n seen.add(error);\r\n\r\n try {\r\n const errors =\r\n \"errors\" in error && Array.isArray(error.errors)\r\n ? (error.errors as unknown[])\r\n : undefined;\r\n\r\n return {\r\n ...(error.cause !== undefined && {\r\n cause: serializeCauseError(error.cause, includeStack, seen),\r\n }),\r\n ...(errors && {\r\n errors: errors.map((item) =>\r\n serializeCauseError(item, includeStack, seen),\r\n ),\r\n }),\r\n message: error.message,\r\n name: error.name,\r\n ...(includeStack && { stack: error.stack }),\r\n };\r\n } finally {\r\n seen.delete(error);\r\n }\r\n}\r\n","import { isBaseError } from \"./is-base-error.js\";\r\nimport { serializeBaseError } from \"./serialize-base-error.js\";\r\nimport { serializeNativeError } from \"./serialize-native-error.js\";\r\n\r\n/**\r\n * Texto que substitui uma referência circular durante a serialização.\r\n *\r\n * É retornado no lugar de um objeto que já está sendo serializado mais acima\r\n * na mesma cadeia evitando recursão infinita.\r\n */\r\nexport const CIRCULAR_MARKER = \"[Circular]\";\r\n\r\n/**\r\n * Conjunto de referências em processo de serialização usado para detectar\r\n * ciclos.\r\n *\r\n * Por ser um `WeakSet` não impede que os objetos sejam coletados pelo\r\n * garbage collector.\r\n */\r\nexport type SeenReferences = WeakSet<object>;\r\n\r\n/**\r\n * Serializa de forma segura, o valor de uma `cause` (causa) de erro para uma\r\n * estrutura simples e apropriada para `JSON.stringify`, logs ou transmissão.\r\n *\r\n * A conversão depende do tipo do valor:\r\n * - `string`, `number`, `boolean` e `undefined`: retornados sem alteração;\r\n * - `null`: retorna `null`;\r\n * - `bigint` e `symbol`: convertidos para texto com `toString()`\r\n * (ex.: `10n` vira `\"10\"`);\r\n * - função: vira o texto `\"[Function: nome]\"` ou `\"[Function: anonymous]\"`\r\n * se não tiver nome;\r\n * - `BaseError`: delegado a {@link serializeBaseError};\r\n * - `Error` nativo: delegado a {@link serializeNativeError};\r\n * - `Date`: convertida para string ISO 8601 ou `\"Invalid Date\"` se a data\r\n * for inválida;\r\n * - array: cada item é serializado recursivamente;\r\n * - objeto comum: cada propriedade própria enumerável de chave `string` é\r\n * serializada recursivamente, resultando em um novo objeto simples.\r\n *\r\n * **Referências circulares:** apenas as referências da cadeia atual (os\r\n * \"ancestrais\" do valor sendo serializado) são rastreadas. Quando um objeto\r\n * aparece dentro de si mesmo o ponto de repetição é substituído por\r\n * {@link CIRCULAR_MARKER}. Como cada objeto é removido do conjunto ao terminar\r\n * de ser serializado, um mesmo objeto referenciado em dois lugares distintos\r\n * (sem ciclo) é serializado por completo nas duas ocorrências e não marcado\r\n * como circular.\r\n *\r\n * **Limitações:** protótipos e métodos de objetos comuns são descartados e\r\n * propriedades com chave `symbol` são ignoradas. Instâncias como `Map` e\r\n * `Set`, que não possuem propriedades próprias enumeráveis resultam em `{}`.\r\n *\r\n * @param cause - Valor a ser serializado normalmente a propriedade `cause`\r\n * de um erro, mas pode ser qualquer valor.\r\n * @param includeStack - Se `true`, inclui o stack trace ao serializar erros\r\n * (`BaseError` e `Error` nativo), repassando a opção aos respectivos\r\n * serializadores. Por padrão, `false`.\r\n * @param seen - Conjunto de referências em processo de serialização usado\r\n * internamente na recursão para detectar ciclos. Em geral não deve ser\r\n * informado; por padrão, um novo `WeakSet` vazio.\r\n * @returns Representação serializável do valor cujo formato depende do tipo\r\n * recebido (ver lista acima).\r\n *\r\n * @example\r\n * ```ts\r\n * serializeCauseError(\"falha\"); // \"falha\"\r\n * serializeCauseError(10n); // \"10\"\r\n * serializeCauseError(Symbol(\"x\")); // \"Symbol(x)\"\r\n * serializeCauseError(function foo() {}); // \"[Function: foo]\"\r\n * serializeCauseError(new Date(\"2026-01-01T00:00:00Z\"));\r\n * // \"2026-01-01T00:00:00.000Z\"\r\n * serializeCauseError(new Date(\"inválida\")); // \"Invalid Date\"\r\n *\r\n * // Estruturas aninhadas\r\n * serializeCauseError({ ids: [1, 2n], origin: null });\r\n * // { ids: [1, \"2\"], origin: null }\r\n *\r\n * // Referência circular\r\n * const a: Record<string, unknown> = { name: \"a\" };\r\n * a.self = a;\r\n * serializeCauseError(a);\r\n * // { name: \"a\", self: \"[Circular]\" }\r\n *\r\n * // Mesmo objeto em dois lugares (sem ciclo): serializado nas duas vezes\r\n * const shared = { x: 1 };\r\n * serializeCauseError({ a: shared, b: shared });\r\n * // { a: { x: 1 }, b: { x: 1 } }\r\n *\r\n * // Erros, com stack trace opcional\r\n * serializeCauseError(new Error(\"falhou\"), true);\r\n * ```\r\n */\r\nexport function serializeCauseError(\r\n cause: unknown,\r\n includeStack = false,\r\n seen: SeenReferences = new WeakSet(),\r\n): unknown {\r\n switch (typeof cause) {\r\n case \"bigint\":\r\n case \"symbol\":\r\n return cause.toString();\r\n case \"function\":\r\n return `[Function: ${cause.name || \"anonymous\"}]`;\r\n case \"object\":\r\n break;\r\n default:\r\n return cause;\r\n }\r\n\r\n if (cause === null) {\r\n return null;\r\n }\r\n\r\n if (seen.has(cause)) {\r\n return CIRCULAR_MARKER;\r\n }\r\n\r\n if (isBaseError(cause)) {\r\n return serializeBaseError(cause, includeStack, seen);\r\n }\r\n\r\n if (cause instanceof Error) {\r\n return serializeNativeError(cause, includeStack, seen);\r\n }\r\n\r\n if (cause instanceof Date) {\r\n return Number.isNaN(cause.getTime()) ? \"Invalid Date\" : cause.toISOString();\r\n }\r\n\r\n seen.add(cause);\r\n\r\n try {\r\n if (Array.isArray(cause)) {\r\n return cause.map((item) => serializeCauseError(item, includeStack, seen));\r\n }\r\n\r\n return Object.fromEntries(\r\n Object.entries(cause).map(([key, value]) => [\r\n key,\r\n serializeCauseError(value, includeStack, seen),\r\n ]),\r\n );\r\n } finally {\r\n seen.delete(cause);\r\n }\r\n}\r\n","import type { BaseError } from \"#/base-error.js\";\r\nimport {\r\n type SeenReferences,\r\n serializeCauseError,\r\n} from \"./serialize-cause-error.js\";\r\n\r\n/**\r\n * Representação serializável de um `BaseError` composta apenas por valores\r\n * simples e apropriada para `JSON.stringify`, logs ou transmissão.\r\n *\r\n * As propriedades `cause`, `params` e `stack` são opcionais e só aparecem\r\n * quando o erro as possui (ou no caso de `stack` quando solicitado).\r\n */\r\nexport type SerializedBaseError = Readonly<{\r\n /** Causa do erro já serializada com {@link serializeCauseError}. */\r\n cause?: unknown;\r\n /** Código do erro conforme o catálogo (ex.: `\"USER_NOT_FOUND\"`). */\r\n code: string;\r\n /** Mensagem do erro já com os placeholders interpolados. */\r\n message: string;\r\n /** Nome da classe do erro (ex.: `\"BaseError\"`). */\r\n name: string;\r\n /** Parâmetros usados para interpolar a mensagem já serializados. */\r\n params?: Readonly<Record<string, unknown>>;\r\n /** Stack trace do erro presente apenas se `includeStack` for `true`. */\r\n stack?: string;\r\n}>;\r\n\r\n/**\r\n * Serializa um `BaseError` para um objeto simples ({@link SerializedBaseError})\r\n * apropriado para `JSON.stringify`, logs ou transmissão.\r\n *\r\n * O resultado sempre contém `code`, `message` e `name`. As demais\r\n * propriedades são incluídas apenas quando aplicável:\r\n * - `cause`: se o erro tiver causa (`error.cause !== undefined`) serializada\r\n * com {@link serializeCauseError};\r\n * - `params`: se o erro tiver parâmetros (`error.params !== undefined`)\r\n * também serializados com {@link serializeCauseError};\r\n * - `stack`: somente se `includeStack` for `true`.\r\n *\r\n * **Referências circulares:** o erro é registrado em `seen` durante a\r\n * serialização e removido ao final (mesmo se ocorrer uma exceção). Assim se\r\n * alguma `cause` ou `params` apontar de volta para este mesmo erro, o ponto\r\n * de repetição é substituído por `\"[Circular]\"` em vez de causar recursão\r\n * infinita. Por ser removido ao terminar, o mesmo erro pode aparecer em\r\n * lugares distintos (sem ciclo) e ser serializado por completo em cada um.\r\n *\r\n * @param error - `BaseError` a ser serializado.\r\n * @param includeStack - Se `true` inclui o stack trace no resultado e o\r\n * repassa à serialização da causa e dos parâmetros. Por padrão, `false`.\r\n * @param seen - Conjunto de referências em processo de serialização usado\r\n * internamente na recursão para detectar ciclos. Em geral não deve ser\r\n * informado; por padrão, um novo `WeakSet` vazio.\r\n * @returns Objeto serializável que representa o erro.\r\n *\r\n * @example\r\n * ```ts\r\n * const error = new BaseError(ERROR_CODES.USER_NOT_FOUND, { id: 42 });\r\n *\r\n * serializeBaseError(error);\r\n * // {\r\n * // code: \"USER_NOT_FOUND\",\r\n * // message: \"Usuário 42 não encontrado\",\r\n * // name: \"BaseError\",\r\n * // params: { id: 42 },\r\n * // }\r\n *\r\n * // Com stack trace\r\n * serializeBaseError(erro, true);\r\n * // { ..., stack: \"BaseError: Usuário 42 não encontrado\\n at ...\" }\r\n *\r\n * // Com causa\r\n * const withCause = new BaseError(ERROR_CODES.INVALID_TOKEN, undefined, {\r\n * cause: new Error(\"expirado\"),\r\n * });\r\n * serializeBaseError(withCause);\r\n * // { cause: { ... }, code: \"INVALID_TOKEN\", message: \"Token inválido\", name: \"BaseError\" }\r\n * ```\r\n */\r\nexport function serializeBaseError(\r\n error: BaseError,\r\n includeStack = false,\r\n seen: SeenReferences = new WeakSet(),\r\n): SerializedBaseError {\r\n seen.add(error);\r\n\r\n try {\r\n return {\r\n ...(error.cause !== undefined && {\r\n cause: serializeCauseError(error.cause, includeStack, seen),\r\n }),\r\n code: error.code,\r\n message: error.message,\r\n name: error.name,\r\n ...(error.params !== undefined && {\r\n params: serializeCauseError(\r\n error.params,\r\n includeStack,\r\n seen,\r\n ) as Readonly<Record<string, unknown>>,\r\n }),\r\n ...(includeStack && { stack: error.stack }),\r\n };\r\n } finally {\r\n seen.delete(error);\r\n }\r\n}\r\n"],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { d as DEFAULT_PARAM_DELIMITERS, f as DefaultParamDelimiters, p as createParamPlaceholder } from "../error-params-CR2parjT.cjs";
|
|
2
|
+
import { a as CIRCULAR_MARKER, c as BASE_ERROR_BRAND, i as serializeBaseError, l as isBaseError, n as serializeNativeError, o as SeenReferences, p as escapeRegExp, r as SerializedBaseError, s as serializeCauseError, t as SerializedNativeError } from "../index-BzFCOXvr.cjs";
|
|
3
|
+
export { BASE_ERROR_BRAND, CIRCULAR_MARKER, DEFAULT_PARAM_DELIMITERS, DefaultParamDelimiters, SeenReferences, SerializedBaseError, SerializedNativeError, createParamPlaceholder, escapeRegExp, isBaseError, serializeBaseError, serializeCauseError, serializeNativeError };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { d as DEFAULT_PARAM_DELIMITERS, f as DefaultParamDelimiters, p as createParamPlaceholder } from "../error-params-CR2parjT.mjs";
|
|
2
|
+
import { a as CIRCULAR_MARKER, c as BASE_ERROR_BRAND, i as serializeBaseError, l as isBaseError, n as serializeNativeError, o as SeenReferences, p as escapeRegExp, r as SerializedBaseError, s as serializeCauseError, t as SerializedNativeError } from "../index-B4tdSdCF.mjs";
|
|
3
|
+
export { BASE_ERROR_BRAND, CIRCULAR_MARKER, DEFAULT_PARAM_DELIMITERS, DefaultParamDelimiters, SeenReferences, SerializedBaseError, SerializedNativeError, createParamPlaceholder, escapeRegExp, isBaseError, serializeBaseError, serializeCauseError, serializeNativeError };
|