@zudojs/errors 1.0.1 → 1.2.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.
Files changed (76) hide show
  1. package/README.md +9 -2
  2. package/dist/base/core/baseError.core.d.ts +18 -4
  3. package/dist/base/core/baseError.core.js +31 -46
  4. package/dist/base/core/baseError.serialize.d.ts +53 -0
  5. package/dist/base/core/baseError.serialize.js +109 -0
  6. package/dist/base/core/errorCause.redact.d.ts +25 -0
  7. package/dist/base/core/errorCause.redact.js +75 -0
  8. package/dist/base/types/errorCode.type.d.ts +11 -1
  9. package/dist/base/types/errorCode.type.js +12 -0
  10. package/dist/domain/access/authError.base.d.ts +25 -0
  11. package/dist/domain/access/authError.base.js +26 -0
  12. package/dist/domain/access/index.d.ts +2 -0
  13. package/dist/domain/access/index.js +2 -0
  14. package/dist/domain/access/oauthError.base.d.ts +24 -0
  15. package/dist/domain/access/oauthError.base.js +30 -0
  16. package/dist/domain/cli/cliError.base.d.ts +24 -0
  17. package/dist/domain/cli/cliError.base.js +34 -0
  18. package/dist/domain/cli/index.d.ts +7 -0
  19. package/dist/domain/cli/index.js +7 -0
  20. package/dist/domain/constant/constantError.base.d.ts +21 -0
  21. package/dist/domain/constant/constantError.base.js +31 -0
  22. package/dist/domain/constant/index.d.ts +7 -0
  23. package/dist/domain/constant/index.js +7 -0
  24. package/dist/domain/cqrs/cqrsError.base.d.ts +14 -0
  25. package/dist/domain/cqrs/cqrsError.base.js +26 -0
  26. package/dist/domain/cqrs/index.d.ts +7 -0
  27. package/dist/domain/cqrs/index.js +7 -0
  28. package/dist/domain/event/event.error.d.ts +1 -1
  29. package/dist/domain/event/event.error.js +1 -1
  30. package/dist/domain/event/eventError.lifecycle.d.ts +16 -0
  31. package/dist/domain/event/eventError.lifecycle.js +31 -0
  32. package/dist/domain/index.d.ts +6 -0
  33. package/dist/domain/index.js +6 -0
  34. package/dist/domain/openapi/index.d.ts +7 -0
  35. package/dist/domain/openapi/index.js +7 -0
  36. package/dist/domain/openapi/openApiError.base.d.ts +20 -0
  37. package/dist/domain/openapi/openApiError.base.js +24 -0
  38. package/dist/domain/schema/schemaError.base.js +1 -1
  39. package/dist/domain/shared/domainError.helpers.d.ts +3 -2
  40. package/dist/domain/shared/domainError.helpers.js +32 -8
  41. package/dist/domain/state/validationError.base.d.ts +4 -3
  42. package/dist/domain/state/validationError.base.js +5 -4
  43. package/dist/domain/transaction/index.d.ts +10 -0
  44. package/dist/domain/transaction/index.js +10 -0
  45. package/dist/domain/transaction/transactionError.base.d.ts +18 -0
  46. package/dist/domain/transaction/transactionError.base.js +21 -0
  47. package/dist/domain/transaction/transactionError.misc.d.ts +26 -0
  48. package/dist/domain/transaction/transactionError.misc.js +47 -0
  49. package/dist/domain/transaction/transactionError.types.d.ts +33 -0
  50. package/dist/domain/transaction/transactionError.types.js +62 -0
  51. package/dist/domain/traversal/index.d.ts +7 -0
  52. package/dist/domain/traversal/index.js +7 -0
  53. package/dist/domain/traversal/traversalLimit.error.d.ts +37 -0
  54. package/dist/domain/traversal/traversalLimit.error.js +39 -0
  55. package/dist/infrastructure/httpPipeline/httpMiddleware.error.d.ts +26 -0
  56. package/dist/infrastructure/httpPipeline/httpMiddleware.error.js +43 -0
  57. package/dist/infrastructure/httpPipeline/httpRequestGuard.error.d.ts +21 -0
  58. package/dist/infrastructure/httpPipeline/httpRequestGuard.error.js +28 -0
  59. package/dist/infrastructure/httpPipeline/index.d.ts +8 -0
  60. package/dist/infrastructure/httpPipeline/index.js +8 -0
  61. package/dist/infrastructure/index.d.ts +1 -0
  62. package/dist/infrastructure/index.js +1 -0
  63. package/dist/infrastructure/middleware/index.d.ts +1 -0
  64. package/dist/infrastructure/middleware/index.js +1 -0
  65. package/dist/infrastructure/middleware/middlewareError.types.d.ts +28 -0
  66. package/dist/infrastructure/middleware/middlewareError.types.js +44 -0
  67. package/dist/system/index.d.ts +1 -0
  68. package/dist/system/index.js +1 -0
  69. package/dist/system/observability/index.d.ts +7 -0
  70. package/dist/system/observability/index.js +7 -0
  71. package/dist/system/observability/observabilityError.base.d.ts +16 -0
  72. package/dist/system/observability/observabilityError.base.js +23 -0
  73. package/dist/utils/errorMapper.mappers.d.ts +1 -1
  74. package/dist/utils/errorSerializer.core.d.ts +10 -2
  75. package/dist/utils/errorSerializer.core.js +30 -76
  76. package/package.json +1 -1
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Errors raised by the `zudojs-cli` scaffolding and generation commands.
3
+ *
4
+ * Owned here so the CLI (and tools that drive it) can match them with
5
+ * `instanceof` against a single class hierarchy.
6
+ */
7
+ import { ApplicationError } from "../app/application.error.js";
8
+ /** Invalid user input to a CLI command (bad name, unknown option value). */
9
+ export declare class CLIValidationError extends ApplicationError {
10
+ constructor(message: string);
11
+ }
12
+ /** A generator or scaffolder failed while producing files. */
13
+ export declare class CLIGenerationError extends ApplicationError {
14
+ constructor(message: string, cause?: unknown);
15
+ }
16
+ /** The command needs a Zudojs project but was run outside one. */
17
+ export declare class CLINotInProjectError extends ApplicationError {
18
+ constructor();
19
+ }
20
+ /** A template could not be found or rendered. */
21
+ export declare class CLITemplateError extends ApplicationError {
22
+ constructor(message: string);
23
+ }
24
+ //# sourceMappingURL=cliError.base.d.ts.map
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Errors raised by the `zudojs-cli` scaffolding and generation commands.
3
+ *
4
+ * Owned here so the CLI (and tools that drive it) can match them with
5
+ * `instanceof` against a single class hierarchy.
6
+ */
7
+ import { ApplicationError } from "../app/application.error.js";
8
+ /** Invalid user input to a CLI command (bad name, unknown option value). */
9
+ export class CLIValidationError extends ApplicationError {
10
+ constructor(message) {
11
+ super(message, { isOperational: true });
12
+ }
13
+ }
14
+ /** A generator or scaffolder failed while producing files. */
15
+ export class CLIGenerationError extends ApplicationError {
16
+ constructor(message, cause) {
17
+ super(message, { cause });
18
+ }
19
+ }
20
+ /** The command needs a Zudojs project but was run outside one. */
21
+ export class CLINotInProjectError extends ApplicationError {
22
+ constructor() {
23
+ super("This command must be run inside a Zudojs project directory.", {
24
+ isOperational: true,
25
+ });
26
+ }
27
+ }
28
+ /** A template could not be found or rendered. */
29
+ export class CLITemplateError extends ApplicationError {
30
+ constructor(message) {
31
+ super(message);
32
+ }
33
+ }
34
+ //# sourceMappingURL=cliError.base.js.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @zudojs/errors/domain/cli
3
+ *
4
+ * Errors for the `zudojs-cli` command-line tool.
5
+ */
6
+ export * from "./cliError.base.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @zudojs/errors/domain/cli
3
+ *
4
+ * Errors for the `zudojs-cli` command-line tool.
5
+ */
6
+ export * from "./cliError.base.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Errors raised by `@zudojs/constants` branded-type factories and
3
+ * environment helpers.
4
+ */
5
+ import { BaseError } from "../../base/core/baseError.core.js";
6
+ import { ErrorCode } from "../../base/types/errorCode.type.js";
7
+ import type { ErrorMetadata } from "../../base/core/errorMetadata.type.js";
8
+ /** Error thrown when an invalid constant value is used. */
9
+ export declare class InvalidConstantError extends BaseError {
10
+ constructor(message: string, options?: {
11
+ readonly code?: ErrorCode;
12
+ readonly metadata?: ErrorMetadata;
13
+ });
14
+ }
15
+ /** Error thrown when a constant is used outside its valid context. */
16
+ export declare class ConstantContextError extends BaseError {
17
+ constructor(message: string, options?: {
18
+ readonly metadata?: ErrorMetadata;
19
+ });
20
+ }
21
+ //# sourceMappingURL=constantError.base.d.ts.map
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Errors raised by `@zudojs/constants` branded-type factories and
3
+ * environment helpers.
4
+ */
5
+ import { BaseError } from "../../base/core/baseError.core.js";
6
+ import { ErrorCategory } from "../../base/types/errorCategory.type.js";
7
+ import { ErrorCode } from "../../base/types/errorCode.type.js";
8
+ import { ErrorSeverity } from "../../base/types/errorSeverity.type.js";
9
+ /** Error thrown when an invalid constant value is used. */
10
+ export class InvalidConstantError extends BaseError {
11
+ constructor(message, options) {
12
+ super(message, {
13
+ code: options?.code ?? ErrorCode.CONFIGURATION_INVALID,
14
+ category: ErrorCategory.VALIDATION,
15
+ severity: ErrorSeverity.ERROR,
16
+ metadata: options?.metadata,
17
+ });
18
+ }
19
+ }
20
+ /** Error thrown when a constant is used outside its valid context. */
21
+ export class ConstantContextError extends BaseError {
22
+ constructor(message, options) {
23
+ super(message, {
24
+ code: ErrorCode.INVALID_INPUT,
25
+ category: ErrorCategory.VALIDATION,
26
+ severity: ErrorSeverity.ERROR,
27
+ metadata: options?.metadata,
28
+ });
29
+ }
30
+ }
31
+ //# sourceMappingURL=constantError.base.js.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @zudojs/errors/domain/constant
3
+ *
4
+ * Errors for invalid or misused constants and branded values.
5
+ */
6
+ export * from "./constantError.base.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @zudojs/errors/domain/constant
3
+ *
4
+ * Errors for invalid or misused constants and branded values.
5
+ */
6
+ export * from "./constantError.base.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Base CQRS error, owned here so `@zudojs/cqrs` can extend or re-export it.
3
+ */
4
+ import type { BaseErrorOptions } from "../../base/types/baseError.type.js";
5
+ import { BaseError } from "../../base/core/baseError.core.js";
6
+ /**
7
+ * Base error for failures originating from the CQRS package.
8
+ *
9
+ * Defaults: `ErrorCode.INTERNAL_ERROR`, category `system`, 500, not exposed.
10
+ */
11
+ export declare class CqrsError extends BaseError {
12
+ constructor(message: string, options?: BaseErrorOptions);
13
+ }
14
+ //# sourceMappingURL=cqrsError.base.d.ts.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Base CQRS error, owned here so `@zudojs/cqrs` can extend or re-export it.
3
+ */
4
+ import { BaseError } from "../../base/core/baseError.core.js";
5
+ import { ErrorCategory } from "../../base/types/errorCategory.type.js";
6
+ import { ErrorCode } from "../../base/types/errorCode.type.js";
7
+ import { ErrorSeverity } from "../../base/types/errorSeverity.type.js";
8
+ /**
9
+ * Base error for failures originating from the CQRS package.
10
+ *
11
+ * Defaults: `ErrorCode.INTERNAL_ERROR`, category `system`, 500, not exposed.
12
+ */
13
+ export class CqrsError extends BaseError {
14
+ constructor(message, options = {}) {
15
+ super(message, {
16
+ ...options,
17
+ code: options.code ?? ErrorCode.INTERNAL_ERROR,
18
+ category: options.category ?? ErrorCategory.SYSTEM,
19
+ severity: options.severity ?? ErrorSeverity.ERROR,
20
+ statusCode: options.statusCode ?? 500,
21
+ expose: options.expose ?? false,
22
+ isOperational: options.isOperational ?? true,
23
+ });
24
+ }
25
+ }
26
+ //# sourceMappingURL=cqrsError.base.js.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @zudojs/errors/domain/cqrs
3
+ *
4
+ * Command/query bus errors.
5
+ */
6
+ export * from "./cqrsError.base.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @zudojs/errors/domain/cqrs
3
+ *
4
+ * Command/query bus errors.
5
+ */
6
+ export * from "./cqrsError.base.js";
7
+ //# sourceMappingURL=index.js.map
@@ -4,6 +4,6 @@
4
4
  export { EventError, createEventError, isEventError, toEventError, } from "./eventError.base.js";
5
5
  export type { EventErrorOptions } from "./eventError.base.js";
6
6
  export { EventHandlerError, createEventHandlerError, EventHandlerNotFoundError, DuplicateEventHandlerError, EventMiddlewareError, } from "./eventError.handler.js";
7
- export { EventPublishError, InvalidEventError, EventTypeNotFoundError, DuplicateEventDefinitionError, EventDefinitionNotFoundError, EventDispatchAbortedError, EventEmitterDisposedError, EventRegistryDisposedError, EventSubscriptionClosedError, EventBusDisposedError, EventTimeoutError, } from "./eventError.lifecycle.js";
7
+ export { EventPublishError, InvalidEventError, EventTypeNotFoundError, DuplicateEventDefinitionError, EventDefinitionNotFoundError, EventDispatchAbortedError, EventEmitterDisposedError, EventRegistryDisposedError, EventSubscriptionClosedError, EventBusDisposedError, EventListenerLimitExceededError, EventTimeoutError, } from "./eventError.lifecycle.js";
8
8
  export { EventSerializationError, EventDeserializationError, } from "./eventError.serialization.js";
9
9
  //# sourceMappingURL=event.error.d.ts.map
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export { EventError, createEventError, isEventError, toEventError, } from "./eventError.base.js";
5
5
  export { EventHandlerError, createEventHandlerError, EventHandlerNotFoundError, DuplicateEventHandlerError, EventMiddlewareError, } from "./eventError.handler.js";
6
- export { EventPublishError, InvalidEventError, EventTypeNotFoundError, DuplicateEventDefinitionError, EventDefinitionNotFoundError, EventDispatchAbortedError, EventEmitterDisposedError, EventRegistryDisposedError, EventSubscriptionClosedError, EventBusDisposedError, EventTimeoutError, } from "./eventError.lifecycle.js";
6
+ export { EventPublishError, InvalidEventError, EventTypeNotFoundError, DuplicateEventDefinitionError, EventDefinitionNotFoundError, EventDispatchAbortedError, EventEmitterDisposedError, EventRegistryDisposedError, EventSubscriptionClosedError, EventBusDisposedError, EventListenerLimitExceededError, EventTimeoutError, } from "./eventError.lifecycle.js";
7
7
  export { EventSerializationError, EventDeserializationError, } from "./eventError.serialization.js";
8
8
  //# sourceMappingURL=event.error.js.map
@@ -62,6 +62,22 @@ export declare class EventSubscriptionClosedError extends EventError {
62
62
  export declare class EventBusDisposedError extends EventError {
63
63
  constructor();
64
64
  }
65
+ /**
66
+ * Error thrown when a pattern exceeds its configured handler limit.
67
+ *
68
+ * The limit exists to catch a subscribe-without-unsubscribe leak. Registering
69
+ * past it is a programming fault rather than bad input, so this is reported as
70
+ * internal and is never exposed to a caller.
71
+ *
72
+ * A registry only raises this when it is configured to enforce the limit;
73
+ * the default is a one-shot warning, which does not interrupt registration.
74
+ */
75
+ export declare class EventListenerLimitExceededError extends EventError {
76
+ readonly pattern: string;
77
+ readonly count: number;
78
+ readonly limit: number;
79
+ constructor(pattern: string, count: number, limit: number);
80
+ }
65
81
  /** Error thrown when an event operation times out. */
66
82
  export declare class EventTimeoutError extends EventError {
67
83
  readonly timeoutMs: number;
@@ -130,6 +130,37 @@ export class EventBusDisposedError extends EventError {
130
130
  });
131
131
  }
132
132
  }
133
+ /**
134
+ * Error thrown when a pattern exceeds its configured handler limit.
135
+ *
136
+ * The limit exists to catch a subscribe-without-unsubscribe leak. Registering
137
+ * past it is a programming fault rather than bad input, so this is reported as
138
+ * internal and is never exposed to a caller.
139
+ *
140
+ * A registry only raises this when it is configured to enforce the limit;
141
+ * the default is a one-shot warning, which does not interrupt registration.
142
+ */
143
+ export class EventListenerLimitExceededError extends EventError {
144
+ pattern;
145
+ count;
146
+ limit;
147
+ constructor(pattern, count, limit) {
148
+ assertFiniteNonNegative("count", count);
149
+ assertFiniteNonNegative("limit", limit);
150
+ super(`Possible event handler leak: ${count} handlers registered for ` +
151
+ `"${pattern}" (limit ${limit}). Unsubscribe handlers you no longer ` +
152
+ "need or raise maxHandlersPerPattern / maxListeners.", {
153
+ code: ErrorCode.EVENT_LISTENER_LIMIT_EXCEEDED,
154
+ metadata: { pattern, count, limit },
155
+ statusCode: 500,
156
+ expose: false,
157
+ isOperational: false,
158
+ });
159
+ this.pattern = pattern;
160
+ this.count = count;
161
+ this.limit = limit;
162
+ }
163
+ }
133
164
  /** Error thrown when an event operation times out. */
134
165
  export class EventTimeoutError extends EventError {
135
166
  timeoutMs;
@@ -17,4 +17,10 @@ export * from "./rpc/index.js";
17
17
  export * from "./scheduler/index.js";
18
18
  export * from "./documentation/index.js";
19
19
  export * from "./plugin/index.js";
20
+ export * from "./transaction/index.js";
21
+ export * from "./traversal/index.js";
22
+ export * from "./openapi/index.js";
23
+ export * from "./cqrs/index.js";
24
+ export * from "./constant/index.js";
25
+ export * from "./cli/index.js";
20
26
  //# sourceMappingURL=index.d.ts.map
@@ -17,4 +17,10 @@ export * from "./rpc/index.js";
17
17
  export * from "./scheduler/index.js";
18
18
  export * from "./documentation/index.js";
19
19
  export * from "./plugin/index.js";
20
+ export * from "./transaction/index.js";
21
+ export * from "./traversal/index.js";
22
+ export * from "./openapi/index.js";
23
+ export * from "./cqrs/index.js";
24
+ export * from "./constant/index.js";
25
+ export * from "./cli/index.js";
20
26
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @zudojs/errors/domain/openapi
3
+ *
4
+ * OpenAPI document build and validation errors.
5
+ */
6
+ export * from "./openApiError.base.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @zudojs/errors/domain/openapi
3
+ *
4
+ * OpenAPI document build and validation errors.
5
+ */
6
+ export * from "./openApiError.base.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Base OpenAPI error. Server-side defaults (500, not exposed): a document
3
+ * that fails to build is an operator's problem, not a client's.
4
+ */
5
+ import { BaseError } from "../../base/core/baseError.core.js";
6
+ /** Options for creating an OpenAPI error. */
7
+ export interface OpenAPIErrorOptions {
8
+ readonly code?: string;
9
+ /** Overrides the default status (500). */
10
+ readonly statusCode?: number;
11
+ /** Overrides the default exposure (false). */
12
+ readonly expose?: boolean;
13
+ readonly cause?: unknown;
14
+ readonly metadata?: Readonly<Record<string, unknown>>;
15
+ }
16
+ /** Base error for all OpenAPI subsystem failures. */
17
+ export declare class OpenAPIError extends BaseError {
18
+ constructor(message: string, options?: OpenAPIErrorOptions);
19
+ }
20
+ //# sourceMappingURL=openApiError.base.d.ts.map
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Base OpenAPI error. Server-side defaults (500, not exposed): a document
3
+ * that fails to build is an operator's problem, not a client's.
4
+ */
5
+ import { BaseError } from "../../base/core/baseError.core.js";
6
+ import { ErrorCategory } from "../../base/types/errorCategory.type.js";
7
+ import { ErrorCode } from "../../base/types/errorCode.type.js";
8
+ import { ErrorSeverity } from "../../base/types/errorSeverity.type.js";
9
+ /** Base error for all OpenAPI subsystem failures. */
10
+ export class OpenAPIError extends BaseError {
11
+ constructor(message, options = {}) {
12
+ super(message, {
13
+ code: options.code ?? ErrorCode.OPENAPI_DOCUMENT,
14
+ category: ErrorCategory.OPENAPI,
15
+ severity: ErrorSeverity.ERROR,
16
+ statusCode: options.statusCode ?? 500,
17
+ expose: options.expose ?? false,
18
+ cause: options.cause,
19
+ metadata: options.metadata,
20
+ });
21
+ this.name = "OpenAPIError";
22
+ }
23
+ }
24
+ //# sourceMappingURL=openApiError.base.js.map
@@ -38,7 +38,7 @@ export class SchemaError extends BaseError {
38
38
  const safeIssues = toJsonSafeIssues(this.issues);
39
39
  return {
40
40
  ...super.toJSON(),
41
- issues: this.expose ? redactIssueValues(safeIssues) : safeIssues,
41
+ issues: redactIssueValues(safeIssues),
42
42
  };
43
43
  }
44
44
  }
@@ -48,8 +48,9 @@ export declare function normalizeRetryAfterSeconds(value: number, name?: string)
48
48
  export declare function mergeMetadata(callerMetadata: ErrorMetadata | undefined, own: ErrorMetadata): ErrorMetadata;
49
49
  /**
50
50
  * Removes submitted values from a list of issue objects so they can be
51
- * exposed to clients. Values are replaced by a type/size description under
52
- * `<key>Type`.
51
+ * exposed to clients or logged. Values are replaced by a type/size
52
+ * description under `<key>Type`; `__proto__`, `constructor` and `prototype`
53
+ * keys are dropped.
53
54
  */
54
55
  export declare function redactIssueValues<T>(issues: readonly T[]): readonly T[];
55
56
  /**
@@ -7,9 +7,15 @@
7
7
  */
8
8
  /** Default maximum length for untrusted strings embedded in messages. */
9
9
  export const MAX_MESSAGE_FRAGMENT_LENGTH = 200;
10
- /** Control characters (C0 range, DEL, and C1 range) that must not reach logs. */
10
+ /**
11
+ * Characters that must not reach logs: C0, DEL and C1 controls, the Unicode
12
+ * line and paragraph separators (U+2028/U+2029, which break log lines in
13
+ * viewers that honour them), and the bidirectional marks, embeddings,
14
+ * overrides and isolates (U+061C, U+200E/F, U+202A-E, U+2066-9), which can
15
+ * visually reorder a log line.
16
+ */
11
17
  // eslint-disable-next-line no-control-regex
12
- const CONTROL_CHARS = /[\u0000-\u001f\u007f-\u009f]/g;
18
+ const CONTROL_CHARS = /[\u0000-\u001f\u007f-\u009f\u061c\u200e\u200f\u2028\u2029\u202a-\u202e\u2066-\u2069]/g;
13
19
  /** Default maximum length for untrusted strings stored in metadata. */
14
20
  export const MAX_METADATA_FRAGMENT_LENGTH = 1024;
15
21
  /**
@@ -48,16 +54,22 @@ export function safeStringify(value, maxLength = MAX_METADATA_FRAGMENT_LENGTH) {
48
54
  text = "undefined";
49
55
  }
50
56
  else {
51
- const seen = new WeakSet();
52
- const json = JSON.stringify(value, (_key, item) => {
57
+ // Track the ancestor path, not every object visited: a sub-object
58
+ // shared by two siblings is repeated data, not a cycle.
59
+ const ancestors = [];
60
+ const json = JSON.stringify(value, function replacer(_key, item) {
53
61
  if (typeof item === "bigint")
54
62
  return `${item.toString()}n`;
55
63
  if (typeof item === "symbol")
56
64
  return item.toString();
57
65
  if (typeof item === "object" && item !== null) {
58
- if (seen.has(item))
66
+ while (ancestors.length > 0 &&
67
+ ancestors[ancestors.length - 1] !== this) {
68
+ ancestors.pop();
69
+ }
70
+ if (ancestors.includes(item))
59
71
  return "[Circular]";
60
- seen.add(item);
72
+ ancestors.push(item);
61
73
  }
62
74
  return item;
63
75
  });
@@ -150,12 +162,22 @@ export function normalizeRetryAfterSeconds(value, name = "retryAfterSeconds") {
150
162
  export function mergeMetadata(callerMetadata, own) {
151
163
  return { ...(callerMetadata ?? {}), ...own };
152
164
  }
165
+ /**
166
+ * Keys never copied into a redacted issue: assigning an own `__proto__` key
167
+ * (which a JSON round-trip creates) to a plain object replaces its prototype.
168
+ */
169
+ const FORBIDDEN_ISSUE_KEYS = new Set([
170
+ "__proto__",
171
+ "constructor",
172
+ "prototype",
173
+ ]);
153
174
  /** Keys that hold submitted values inside validation/schema issues. */
154
175
  const VALUE_KEYS = new Set(["value", "received", "input", "actual"]);
155
176
  /**
156
177
  * Removes submitted values from a list of issue objects so they can be
157
- * exposed to clients. Values are replaced by a type/size description under
158
- * `<key>Type`.
178
+ * exposed to clients or logged. Values are replaced by a type/size
179
+ * description under `<key>Type`; `__proto__`, `constructor` and `prototype`
180
+ * keys are dropped.
159
181
  */
160
182
  export function redactIssueValues(issues) {
161
183
  return issues.map((issue) => {
@@ -164,6 +186,8 @@ export function redactIssueValues(issues) {
164
186
  }
165
187
  const out = {};
166
188
  for (const [key, val] of Object.entries(issue)) {
189
+ if (FORBIDDEN_ISSUE_KEYS.has(key))
190
+ continue;
167
191
  if (VALUE_KEYS.has(key)) {
168
192
  out[`${key}Type`] = describeValue(val);
169
193
  }
@@ -34,9 +34,10 @@ export declare class ValidationError extends BaseError {
34
34
  /**
35
35
  * Returns a serialized representation including validation issues.
36
36
  *
37
- * When the error is exposable (the default), submitted values inside
38
- * issues (`value`) are replaced by a type/size description so that secrets
39
- * such as passwords are never echoed to clients or written to logs. The
37
+ * Submitted values inside issues (`value`, `received`, `input`, `actual`)
38
+ * are always replaced by a type/size description, whether or not the error
39
+ * is exposable, so that secrets such as passwords are never echoed to
40
+ * clients or written to logs. The raw values remain on `error.issues`. The
40
41
  * output is always JSON-safe (BigInt and cyclic values are stringified).
41
42
  */
42
43
  toJSON(): {
@@ -35,16 +35,17 @@ export class ValidationError extends BaseError {
35
35
  /**
36
36
  * Returns a serialized representation including validation issues.
37
37
  *
38
- * When the error is exposable (the default), submitted values inside
39
- * issues (`value`) are replaced by a type/size description so that secrets
40
- * such as passwords are never echoed to clients or written to logs. The
38
+ * Submitted values inside issues (`value`, `received`, `input`, `actual`)
39
+ * are always replaced by a type/size description, whether or not the error
40
+ * is exposable, so that secrets such as passwords are never echoed to
41
+ * clients or written to logs. The raw values remain on `error.issues`. The
41
42
  * output is always JSON-safe (BigInt and cyclic values are stringified).
42
43
  */
43
44
  toJSON() {
44
45
  const safeIssues = toJsonSafeIssues(this.issues);
45
46
  return {
46
47
  ...super.toJSON(),
47
- issues: this.expose ? redactIssueValues(safeIssues) : safeIssues,
48
+ issues: redactIssueValues(safeIssues),
48
49
  };
49
50
  }
50
51
  }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @zudojs/errors/domain/transaction
3
+ *
4
+ * Transaction lifecycle errors (state, timeout, commit, rollback, adapter,
5
+ * propagation, isolation, savepoint, presence, capability).
6
+ */
7
+ export * from "./transactionError.base.js";
8
+ export * from "./transactionError.types.js";
9
+ export * from "./transactionError.misc.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @zudojs/errors/domain/transaction
3
+ *
4
+ * Transaction lifecycle errors (state, timeout, commit, rollback, adapter,
5
+ * propagation, isolation, savepoint, presence, capability).
6
+ */
7
+ export * from "./transactionError.base.js";
8
+ export * from "./transactionError.types.js";
9
+ export * from "./transactionError.misc.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Base transaction error, owned here so `@zudojs/transactions` can re-export
3
+ * it and `instanceof` matches across both import paths.
4
+ */
5
+ import { BaseError } from "../../base/core/baseError.core.js";
6
+ import { ErrorCode } from "../../base/types/errorCode.type.js";
7
+ import type { ErrorMetadata } from "../../base/core/errorMetadata.type.js";
8
+ /** Options accepted by {@link TransactionError}. */
9
+ export interface TransactionErrorOptions {
10
+ readonly code?: ErrorCode;
11
+ readonly metadata?: ErrorMetadata;
12
+ readonly cause?: unknown;
13
+ }
14
+ /** Base error for all transaction-related failures. */
15
+ export declare class TransactionError extends BaseError {
16
+ constructor(message: string, options?: TransactionErrorOptions);
17
+ }
18
+ //# sourceMappingURL=transactionError.base.d.ts.map
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Base transaction error, owned here so `@zudojs/transactions` can re-export
3
+ * it and `instanceof` matches across both import paths.
4
+ */
5
+ import { BaseError } from "../../base/core/baseError.core.js";
6
+ import { ErrorCategory } from "../../base/types/errorCategory.type.js";
7
+ import { ErrorCode } from "../../base/types/errorCode.type.js";
8
+ import { ErrorSeverity } from "../../base/types/errorSeverity.type.js";
9
+ /** Base error for all transaction-related failures. */
10
+ export class TransactionError extends BaseError {
11
+ constructor(message, options) {
12
+ super(message, {
13
+ code: options?.code ?? ErrorCode.OPERATION_FAILED,
14
+ category: ErrorCategory.DATABASE,
15
+ severity: ErrorSeverity.ERROR,
16
+ metadata: options?.metadata,
17
+ cause: options?.cause,
18
+ });
19
+ }
20
+ }
21
+ //# sourceMappingURL=transactionError.base.js.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Remaining transaction error subclasses (isolation, savepoints, presence,
3
+ * capabilities).
4
+ */
5
+ import { TransactionError } from "./transactionError.base.js";
6
+ /** Required isolation level is not supported by the adapter. */
7
+ export declare class TransactionIsolationError extends TransactionError {
8
+ constructor(level: string);
9
+ }
10
+ /** Savepoint operation failed. */
11
+ export declare class SavepointError extends TransactionError {
12
+ constructor(message: string, cause?: unknown);
13
+ }
14
+ /** A transaction is required but none exists. */
15
+ export declare class TransactionRequiredError extends TransactionError {
16
+ constructor();
17
+ }
18
+ /** A transaction exists but none was expected. */
19
+ export declare class TransactionUnexpectedError extends TransactionError {
20
+ constructor();
21
+ }
22
+ /** The adapter does not support the requested capability. */
23
+ export declare class TransactionCapabilityError extends TransactionError {
24
+ constructor(capability: string);
25
+ }
26
+ //# sourceMappingURL=transactionError.misc.d.ts.map