@zdavison/matador 2.0.3 → 2.0.5
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/core/fanout.test.js +0 -1
- package/dist/core/matador.d.ts +2 -2
- package/dist/core/matador.d.ts.map +1 -1
- package/dist/core/matador.js +1 -0
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/errors/retry-errors.d.ts +40 -5
- package/dist/errors/retry-errors.d.ts.map +1 -1
- package/dist/errors/retry-errors.js +56 -9
- package/dist/errors/retry-errors.test.d.ts +2 -0
- package/dist/errors/retry-errors.test.d.ts.map +1 -0
- package/dist/errors/retry-errors.test.js +136 -0
- package/dist/index.cjs +73 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/pipeline/pipeline.d.ts +4 -1
- package/dist/pipeline/pipeline.d.ts.map +1 -1
- package/dist/pipeline/pipeline.js +16 -4
- package/dist/pipeline/pipeline.test.js +48 -1
- package/dist/retry/standard-policy.test.js +7 -1
- package/dist/schema/registry.d.ts.map +1 -1
- package/dist/schema/registry.js +4 -1
- package/dist/schema/types.test.js +0 -1
- package/dist/topology/builder.d.ts.map +1 -1
- package/dist/topology/builder.js +2 -1
- package/dist/topology/builder.test.js +68 -0
- package/dist/topology/index.d.ts +2 -2
- package/dist/topology/index.d.ts.map +1 -1
- package/dist/topology/index.js +1 -1
- package/dist/topology/types.d.ts +53 -1
- package/dist/topology/types.d.ts.map +1 -1
- package/dist/topology/types.js +10 -0
- package/dist/transport/rabbitmq/rabbitmq-transport.d.ts.map +1 -1
- package/dist/transport/rabbitmq/rabbitmq-transport.js +30 -22
- package/dist/transport/rabbitmq/rabbitmq-transport.test.js +1 -1
- package/dist/types/dispatcher.d.ts +14 -0
- package/dist/types/dispatcher.d.ts.map +1 -0
- package/dist/types/dispatcher.js +1 -0
- package/dist/types/envelope.d.ts +17 -0
- package/dist/types/envelope.d.ts.map +1 -1
- package/dist/types/envelope.js +19 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/subscriber.d.ts +28 -8
- package/dist/types/subscriber.d.ts.map +1 -1
- package/dist/types/subscriber.js +0 -2
- package/package.json +1 -1
- package/src/core/fanout.test.ts +0 -1
- package/src/core/matador.ts +3 -1
- package/src/errors/index.ts +1 -0
- package/src/errors/retry-errors.test.ts +175 -0
- package/src/errors/retry-errors.ts +63 -9
- package/src/index.ts +11 -0
- package/src/pipeline/pipeline.test.ts +62 -2
- package/src/pipeline/pipeline.ts +28 -6
- package/src/retry/standard-policy.test.ts +9 -1
- package/src/schema/registry.ts +4 -1
- package/src/schema/types.test.ts +0 -1
- package/src/topology/builder.test.ts +90 -0
- package/src/topology/builder.ts +2 -1
- package/src/topology/index.ts +4 -0
- package/src/topology/types.ts +75 -1
- package/src/transport/rabbitmq/rabbitmq-transport.test.ts +1 -1
- package/src/transport/rabbitmq/rabbitmq-transport.ts +33 -25
- package/src/types/dispatcher.ts +18 -0
- package/src/types/envelope.ts +23 -0
- package/src/types/index.ts +5 -1
- package/src/types/subscriber.ts +33 -10
- package/test/e2e/rabbitmq-transport.e2e.test.ts +287 -0
- package/tsconfig.tsbuildinfo +1 -1
package/dist/core/fanout.test.js
CHANGED
|
@@ -489,7 +489,6 @@ describe('FanoutEngine', () => {
|
|
|
489
489
|
it('should work with subscriber stubs', async () => {
|
|
490
490
|
const stub = createSubscriberStub({
|
|
491
491
|
name: 'remote-subscriber',
|
|
492
|
-
description: 'Remote subscriber stub',
|
|
493
492
|
enabled: () => false,
|
|
494
493
|
});
|
|
495
494
|
schema.register(UserCreatedEvent, [stub]);
|
package/dist/core/matador.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { RetryPolicy } from '../retry/index.js';
|
|
|
5
5
|
import type { MatadorSchema } from '../schema/index.js';
|
|
6
6
|
import type { Topology } from '../topology/index.js';
|
|
7
7
|
import type { Transport } from '../transport/index.js';
|
|
8
|
-
import type { AnySubscriber, Event, EventClass, EventOptions } from '../types/index.js';
|
|
8
|
+
import type { AnySubscriber, Dispatcher, Event, EventClass, EventOptions } from '../types/index.js';
|
|
9
9
|
import type { SendResult } from './fanout.js';
|
|
10
10
|
import type { HandlersState, ShutdownConfig } from './shutdown.js';
|
|
11
11
|
/**
|
|
@@ -44,7 +44,7 @@ export interface MatadorConfig {
|
|
|
44
44
|
* - Fanout: Event sending
|
|
45
45
|
* - Shutdown: Graceful termination
|
|
46
46
|
*/
|
|
47
|
-
export declare class Matador {
|
|
47
|
+
export declare class Matador implements Dispatcher {
|
|
48
48
|
private readonly transport;
|
|
49
49
|
private readonly topology;
|
|
50
50
|
private readonly schema;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matador.d.ts","sourceRoot":"","sources":["../../src/core/matador.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAO/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EACV,aAAa,EACb,KAAK,EACL,UAAU,EACV,YAAY,EACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGnE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAE9B,6BAA6B;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAE/B,sDAAsD;IACtD,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAErD,sCAAsC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAEnC,0BAA0B;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAE/C,6BAA6B;IAC7B,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAE9D;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;CACxD;AAED;;;;;;;;;GASG;AACH,qBAAa,
|
|
1
|
+
{"version":3,"file":"matador.d.ts","sourceRoot":"","sources":["../../src/core/matador.ts"],"names":[],"mappings":"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"}
|
package/dist/core/matador.js
CHANGED
package/dist/errors/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { HasDescription } from './has-description.js';
|
|
2
2
|
export { hasDescription } from './has-description.js';
|
|
3
|
-
export { DontRetry, DoRetry, EventAssertionError, isAssertionError, isDontRetry, isDoRetry, RetryControlError, } from './retry-errors.js';
|
|
3
|
+
export { assertEvent, DontRetry, DoRetry, EventAssertionError, isAssertionError, isDontRetry, isDoRetry, RetryControlError, } from './retry-errors.js';
|
|
4
4
|
export { MatadorError, isMatadorError, NotStartedError, isNotStartedError, ShutdownInProgressError, TransportNotConnectedError, isTransportNotConnectedError, TransportClosedError, TransportSendError, AllTransportsFailedError, DelayedMessagesNotSupportedError, EventNotRegisteredError, isEventNotRegisteredError, SubscriberNotRegisteredError, isSubscriberNotRegisteredError, NoSubscribersExistError, InvalidSchemaError, SubscriberIsStubError, LocalTransportCannotProcessStubError, QueueNotFoundError, InvalidEventError, MessageMaybePoisonedError, isMessageMaybePoisonedError, IdempotentMessageCannotRetryError, isIdempotentMessageCannotRetryError, TimeoutError, } from './matador-errors.js';
|
|
5
5
|
export { CheckpointStoreError, DuplicateIoKeyError, isCheckpointStoreError, isDuplicateIoKeyError, } from './checkpoint-errors.js';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EACL,SAAS,EACT,OAAO,EACP,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAEL,YAAY,EACZ,cAAc,EAEd,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EAEvB,0BAA0B,EAC1B,4BAA4B,EAC5B,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,gCAAgC,EAEhC,uBAAuB,EACvB,yBAAyB,EACzB,4BAA4B,EAC5B,8BAA8B,EAC9B,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,oCAAoC,EAEpC,kBAAkB,EAElB,iBAAiB,EAEjB,yBAAyB,EACzB,2BAA2B,EAC3B,iCAAiC,EACjC,mCAAmC,EAEnC,YAAY,GACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EACL,WAAW,EACX,SAAS,EACT,OAAO,EACP,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAEL,YAAY,EACZ,cAAc,EAEd,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EAEvB,0BAA0B,EAC1B,4BAA4B,EAC5B,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,gCAAgC,EAEhC,uBAAuB,EACvB,yBAAyB,EACzB,4BAA4B,EAC5B,8BAA8B,EAC9B,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,oCAAoC,EAEpC,kBAAkB,EAElB,iBAAiB,EAEjB,yBAAyB,EACzB,2BAA2B,EAC3B,iCAAiC,EACjC,mCAAmC,EAEnC,YAAY,GACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC"}
|
package/dist/errors/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { hasDescription } from './has-description.js';
|
|
2
|
-
export { DontRetry, DoRetry, EventAssertionError, isAssertionError, isDontRetry, isDoRetry, RetryControlError, } from './retry-errors.js';
|
|
2
|
+
export { assertEvent, DontRetry, DoRetry, EventAssertionError, isAssertionError, isDontRetry, isDoRetry, RetryControlError, } from './retry-errors.js';
|
|
3
3
|
export {
|
|
4
4
|
// Base class
|
|
5
5
|
MatadorError, isMatadorError,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Envelope } from '../types/envelope.js';
|
|
1
2
|
/**
|
|
2
3
|
* Base class for retry control errors.
|
|
3
4
|
* These errors control the retry behavior of message processing.
|
|
@@ -40,16 +41,24 @@ export declare class DontRetry extends RetryControlError {
|
|
|
40
41
|
constructor(message?: string);
|
|
41
42
|
}
|
|
42
43
|
/**
|
|
43
|
-
*
|
|
44
|
-
* Use for programming errors and invariant violations.
|
|
44
|
+
* Thrown by `assertEvent` in the event of a failed assertion.
|
|
45
45
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
46
|
+
* This error indicates that an event was in an unexpected state when it reached the subscriber.
|
|
47
|
+
* Throwing this error will indicate to Matador NOT to retry the event - it will be sent
|
|
48
|
+
* directly to the undeliverable dead-letter queue.
|
|
49
|
+
*
|
|
50
|
+
* Use `assertEvent` in your subscribers to assert properties about an event payload.
|
|
51
|
+
* This is useful in scenarios where you would expect an event payload to contain a field
|
|
52
|
+
* based on the types, but something unexpected caused it to not be present.
|
|
53
|
+
*
|
|
54
|
+
* @see assertEvent
|
|
48
55
|
*/
|
|
49
56
|
export declare class EventAssertionError extends Error {
|
|
50
57
|
readonly name: string;
|
|
51
58
|
readonly description: string;
|
|
52
|
-
|
|
59
|
+
/** The envelope that failed the assertion */
|
|
60
|
+
readonly envelope: Envelope<unknown>;
|
|
61
|
+
constructor(envelope: Envelope<unknown>, message: string);
|
|
53
62
|
toJSON(): Record<string, unknown>;
|
|
54
63
|
}
|
|
55
64
|
/**
|
|
@@ -64,4 +73,30 @@ export declare function isDontRetry(error: unknown): error is DontRetry;
|
|
|
64
73
|
* Checks if an error is an assertion error (never retry).
|
|
65
74
|
*/
|
|
66
75
|
export declare function isAssertionError(error: unknown): error is EventAssertionError;
|
|
76
|
+
/**
|
|
77
|
+
* Same as Node.js `assert`, but throws an `EventAssertionError` if the assertion fails.
|
|
78
|
+
*
|
|
79
|
+
* `EventAssertionError`s thrown within a subscriber do not cause the subscriber to be retried.
|
|
80
|
+
* The event will be delivered to the undeliverable dead-letter queue instead.
|
|
81
|
+
*
|
|
82
|
+
* @see https://nodejs.org/api/assert.html#assertvalue-message
|
|
83
|
+
* @param envelope - The envelope this assertion relates to.
|
|
84
|
+
* @param value - The value to assert. If falsy, the assertion fails.
|
|
85
|
+
* @param message - The message to include in the error if the assertion fails.
|
|
86
|
+
* @throws {EventAssertionError} If the assertion fails.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const subscriber = createSubscriber<MyEvent>({
|
|
91
|
+
* name: 'my-subscriber',
|
|
92
|
+
* description: 'Processes MyEvent',
|
|
93
|
+
* callback: async (envelope) => {
|
|
94
|
+
* // Assert that userId exists - if not, event goes to DLQ without retry
|
|
95
|
+
* assertEvent(envelope, envelope.data.userId, 'userId is required');
|
|
96
|
+
* // ... rest of processing
|
|
97
|
+
* },
|
|
98
|
+
* });
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export declare function assertEvent(envelope: Envelope<unknown>, value: unknown, message: string): asserts value;
|
|
67
102
|
//# sourceMappingURL=retry-errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry-errors.d.ts","sourceRoot":"","sources":["../../src/errors/retry-errors.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"retry-errors.d.ts","sourceRoot":"","sources":["../../src/errors/retry-errors.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD;;;GAGG;AACH,8BAAsB,iBAAkB,SAAQ,KAAK;IACnD;;OAEG;IACH,SAAiB,IAAI,EAAE,MAAM,CAAC;IAE9B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAE1B,OAAO,EAAE,MAAM;IAY3B;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAQlC;AAED;;;;;;GAMG;AACH,qBAAa,OAAQ,SAAQ,iBAAiB;IAC5C,QAAQ,CAAC,WAAW,SAGyD;gBAEjE,OAAO,SAA2B;CAG/C;AAED;;;;;;GAMG;AACH,qBAAa,SAAU,SAAQ,iBAAiB;IAC9C,QAAQ,CAAC,WAAW,SAIqD;gBAE7D,OAAO,SAA8B;CAGlD;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,SAAiB,IAAI,EAAE,MAAM,CAAC;IAE9B,QAAQ,CAAC,WAAW,SAO0E;IAE9F,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;gBAEzB,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM;IAYxD,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CASlC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAE1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAE9D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAE7E;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,EAC3B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,KAAK,CAMf"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
1
2
|
/**
|
|
2
3
|
* Base class for retry control errors.
|
|
3
4
|
* These errors control the retry behavior of message processing.
|
|
@@ -58,20 +59,32 @@ export class DontRetry extends RetryControlError {
|
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
/**
|
|
61
|
-
*
|
|
62
|
-
* Use for programming errors and invariant violations.
|
|
62
|
+
* Thrown by `assertEvent` in the event of a failed assertion.
|
|
63
63
|
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
64
|
+
* This error indicates that an event was in an unexpected state when it reached the subscriber.
|
|
65
|
+
* Throwing this error will indicate to Matador NOT to retry the event - it will be sent
|
|
66
|
+
* directly to the undeliverable dead-letter queue.
|
|
67
|
+
*
|
|
68
|
+
* Use `assertEvent` in your subscribers to assert properties about an event payload.
|
|
69
|
+
* This is useful in scenarios where you would expect an event payload to contain a field
|
|
70
|
+
* based on the types, but something unexpected caused it to not be present.
|
|
71
|
+
*
|
|
72
|
+
* @see assertEvent
|
|
66
73
|
*/
|
|
67
74
|
export class EventAssertionError extends Error {
|
|
68
|
-
description = '
|
|
69
|
-
'
|
|
70
|
-
'
|
|
71
|
-
'
|
|
72
|
-
|
|
75
|
+
description = 'Thrown to indicate that an event was in an unexpected state when it reached the subscriber. ' +
|
|
76
|
+
'Throwing this error will indicate to Matador NOT to retry the event. ' +
|
|
77
|
+
'Matador does not throw this error directly - it is thrown by assertEvent, which you can ' +
|
|
78
|
+
'use in your subscribers to assert properties about an event. ' +
|
|
79
|
+
'This can be useful in scenarios where you would expect an event payload to contain a field ' +
|
|
80
|
+
'based on the types, but something unexpected caused it to not be present. ' +
|
|
81
|
+
'Using this instead of the NodeJS assert allows Matador to not retry the event subscriber.';
|
|
82
|
+
/** The envelope that failed the assertion */
|
|
83
|
+
envelope;
|
|
84
|
+
constructor(envelope, message) {
|
|
73
85
|
super(message);
|
|
74
86
|
this.name = 'EventAssertionError';
|
|
87
|
+
this.envelope = envelope;
|
|
75
88
|
Object.defineProperty(this, 'name', {
|
|
76
89
|
value: 'EventAssertionError',
|
|
77
90
|
enumerable: true,
|
|
@@ -84,6 +97,7 @@ export class EventAssertionError extends Error {
|
|
|
84
97
|
name: this.name,
|
|
85
98
|
message: this.message,
|
|
86
99
|
description: this.description,
|
|
100
|
+
envelope: this.envelope,
|
|
87
101
|
stack: this.stack,
|
|
88
102
|
};
|
|
89
103
|
}
|
|
@@ -106,3 +120,36 @@ export function isDontRetry(error) {
|
|
|
106
120
|
export function isAssertionError(error) {
|
|
107
121
|
return error instanceof EventAssertionError;
|
|
108
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Same as Node.js `assert`, but throws an `EventAssertionError` if the assertion fails.
|
|
125
|
+
*
|
|
126
|
+
* `EventAssertionError`s thrown within a subscriber do not cause the subscriber to be retried.
|
|
127
|
+
* The event will be delivered to the undeliverable dead-letter queue instead.
|
|
128
|
+
*
|
|
129
|
+
* @see https://nodejs.org/api/assert.html#assertvalue-message
|
|
130
|
+
* @param envelope - The envelope this assertion relates to.
|
|
131
|
+
* @param value - The value to assert. If falsy, the assertion fails.
|
|
132
|
+
* @param message - The message to include in the error if the assertion fails.
|
|
133
|
+
* @throws {EventAssertionError} If the assertion fails.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* const subscriber = createSubscriber<MyEvent>({
|
|
138
|
+
* name: 'my-subscriber',
|
|
139
|
+
* description: 'Processes MyEvent',
|
|
140
|
+
* callback: async (envelope) => {
|
|
141
|
+
* // Assert that userId exists - if not, event goes to DLQ without retry
|
|
142
|
+
* assertEvent(envelope, envelope.data.userId, 'userId is required');
|
|
143
|
+
* // ... rest of processing
|
|
144
|
+
* },
|
|
145
|
+
* });
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
export function assertEvent(envelope, value, message) {
|
|
149
|
+
try {
|
|
150
|
+
assert(value, message);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
throw new EventAssertionError(envelope, message);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-errors.test.d.ts","sourceRoot":"","sources":["../../src/errors/retry-errors.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
import { createEnvelope } from '../types/envelope.js';
|
|
3
|
+
import { assertEvent, DontRetry, DoRetry, EventAssertionError, isAssertionError, isDontRetry, isDoRetry, } from './retry-errors.js';
|
|
4
|
+
function createTestEnvelope(data = { foo: 'bar' }) {
|
|
5
|
+
return createEnvelope({
|
|
6
|
+
data,
|
|
7
|
+
eventKey: 'test.event',
|
|
8
|
+
targetSubscriber: 'test-subscriber',
|
|
9
|
+
importance: 'can-ignore',
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
describe('retry-errors', () => {
|
|
13
|
+
describe('DoRetry', () => {
|
|
14
|
+
it('should have correct name', () => {
|
|
15
|
+
const error = new DoRetry('test message');
|
|
16
|
+
expect(error.name).toBe('DoRetry');
|
|
17
|
+
});
|
|
18
|
+
it('should have description', () => {
|
|
19
|
+
const error = new DoRetry('test message');
|
|
20
|
+
expect(error.description).toBeDefined();
|
|
21
|
+
});
|
|
22
|
+
it('should serialize to JSON', () => {
|
|
23
|
+
const error = new DoRetry('test message');
|
|
24
|
+
const json = error.toJSON();
|
|
25
|
+
expect(json.name).toBe('DoRetry');
|
|
26
|
+
expect(json.message).toBe('test message');
|
|
27
|
+
expect(json.description).toBeDefined();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe('DontRetry', () => {
|
|
31
|
+
it('should have correct name', () => {
|
|
32
|
+
const error = new DontRetry('test message');
|
|
33
|
+
expect(error.name).toBe('DontRetry');
|
|
34
|
+
});
|
|
35
|
+
it('should have description', () => {
|
|
36
|
+
const error = new DontRetry('test message');
|
|
37
|
+
expect(error.description).toBeDefined();
|
|
38
|
+
});
|
|
39
|
+
it('should serialize to JSON', () => {
|
|
40
|
+
const error = new DontRetry('test message');
|
|
41
|
+
const json = error.toJSON();
|
|
42
|
+
expect(json.name).toBe('DontRetry');
|
|
43
|
+
expect(json.message).toBe('test message');
|
|
44
|
+
expect(json.description).toBeDefined();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
describe('EventAssertionError', () => {
|
|
48
|
+
it('should have correct name', () => {
|
|
49
|
+
const envelope = createTestEnvelope();
|
|
50
|
+
const error = new EventAssertionError(envelope, 'assertion failed');
|
|
51
|
+
expect(error.name).toBe('EventAssertionError');
|
|
52
|
+
});
|
|
53
|
+
it('should store the envelope', () => {
|
|
54
|
+
const envelope = createTestEnvelope();
|
|
55
|
+
const error = new EventAssertionError(envelope, 'assertion failed');
|
|
56
|
+
expect(error.envelope).toBe(envelope);
|
|
57
|
+
});
|
|
58
|
+
it('should have description', () => {
|
|
59
|
+
const envelope = createTestEnvelope();
|
|
60
|
+
const error = new EventAssertionError(envelope, 'assertion failed');
|
|
61
|
+
expect(error.description).toBeDefined();
|
|
62
|
+
expect(error.description).toContain('NOT to retry');
|
|
63
|
+
});
|
|
64
|
+
it('should serialize to JSON with envelope', () => {
|
|
65
|
+
const envelope = createTestEnvelope();
|
|
66
|
+
const error = new EventAssertionError(envelope, 'assertion failed');
|
|
67
|
+
const json = error.toJSON();
|
|
68
|
+
expect(json.name).toBe('EventAssertionError');
|
|
69
|
+
expect(json.message).toBe('assertion failed');
|
|
70
|
+
expect(json.envelope).toBe(envelope);
|
|
71
|
+
expect(json.description).toBeDefined();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('assertEvent', () => {
|
|
75
|
+
it('should not throw when value is truthy', () => {
|
|
76
|
+
const envelope = createTestEnvelope();
|
|
77
|
+
expect(() => assertEvent(envelope, true, 'should be true')).not.toThrow();
|
|
78
|
+
expect(() => assertEvent(envelope, 'string', 'should be string')).not.toThrow();
|
|
79
|
+
expect(() => assertEvent(envelope, 1, 'should be number')).not.toThrow();
|
|
80
|
+
expect(() => assertEvent(envelope, {}, 'should be object')).not.toThrow();
|
|
81
|
+
expect(() => assertEvent(envelope, [], 'should be array')).not.toThrow();
|
|
82
|
+
});
|
|
83
|
+
it('should throw EventAssertionError when value is falsy', () => {
|
|
84
|
+
const envelope = createTestEnvelope();
|
|
85
|
+
expect(() => assertEvent(envelope, false, 'value was false')).toThrow(EventAssertionError);
|
|
86
|
+
expect(() => assertEvent(envelope, null, 'value was null')).toThrow(EventAssertionError);
|
|
87
|
+
expect(() => assertEvent(envelope, undefined, 'value was undefined')).toThrow(EventAssertionError);
|
|
88
|
+
expect(() => assertEvent(envelope, 0, 'value was zero')).toThrow(EventAssertionError);
|
|
89
|
+
expect(() => assertEvent(envelope, '', 'value was empty string')).toThrow(EventAssertionError);
|
|
90
|
+
});
|
|
91
|
+
it('should include envelope in thrown error', () => {
|
|
92
|
+
const envelope = createTestEnvelope();
|
|
93
|
+
try {
|
|
94
|
+
assertEvent(envelope, false, 'assertion failed');
|
|
95
|
+
expect.unreachable('should have thrown');
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
expect(error).toBeInstanceOf(EventAssertionError);
|
|
99
|
+
expect(error.envelope).toBe(envelope);
|
|
100
|
+
expect(error.message).toBe('assertion failed');
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
it('should include message in thrown error', () => {
|
|
104
|
+
const envelope = createTestEnvelope();
|
|
105
|
+
try {
|
|
106
|
+
assertEvent(envelope, null, 'userId is required');
|
|
107
|
+
expect.unreachable('should have thrown');
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
expect(error).toBeInstanceOf(EventAssertionError);
|
|
111
|
+
expect(error.message).toBe('userId is required');
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
describe('type guards', () => {
|
|
116
|
+
it('isDoRetry should identify DoRetry errors', () => {
|
|
117
|
+
expect(isDoRetry(new DoRetry('test'))).toBe(true);
|
|
118
|
+
expect(isDoRetry(new DontRetry('test'))).toBe(false);
|
|
119
|
+
expect(isDoRetry(new Error('test'))).toBe(false);
|
|
120
|
+
expect(isDoRetry(null)).toBe(false);
|
|
121
|
+
});
|
|
122
|
+
it('isDontRetry should identify DontRetry errors', () => {
|
|
123
|
+
expect(isDontRetry(new DontRetry('test'))).toBe(true);
|
|
124
|
+
expect(isDontRetry(new DoRetry('test'))).toBe(false);
|
|
125
|
+
expect(isDontRetry(new Error('test'))).toBe(false);
|
|
126
|
+
expect(isDontRetry(null)).toBe(false);
|
|
127
|
+
});
|
|
128
|
+
it('isAssertionError should identify EventAssertionError', () => {
|
|
129
|
+
const envelope = createTestEnvelope();
|
|
130
|
+
expect(isAssertionError(new EventAssertionError(envelope, 'test'))).toBe(true);
|
|
131
|
+
expect(isAssertionError(new DoRetry('test'))).toBe(false);
|
|
132
|
+
expect(isAssertionError(new Error('test'))).toBe(false);
|
|
133
|
+
expect(isAssertionError(null)).toBe(false);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
});
|
package/dist/index.cjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var assert = require('assert');
|
|
3
4
|
var amqplib = require('amqplib');
|
|
4
5
|
|
|
5
6
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
6
7
|
|
|
8
|
+
var assert__default = /*#__PURE__*/_interopDefault(assert);
|
|
7
9
|
var amqplib__default = /*#__PURE__*/_interopDefault(amqplib);
|
|
8
10
|
|
|
9
11
|
// src/errors/has-description.ts
|
|
10
12
|
function hasDescription(error) {
|
|
11
13
|
return typeof error === "object" && error !== null && "description" in error && typeof error.description === "string";
|
|
12
14
|
}
|
|
13
|
-
|
|
14
|
-
// src/errors/retry-errors.ts
|
|
15
15
|
var RetryControlError = class extends Error {
|
|
16
16
|
constructor(message) {
|
|
17
17
|
super(message);
|
|
@@ -48,10 +48,13 @@ var DontRetry = class extends RetryControlError {
|
|
|
48
48
|
}
|
|
49
49
|
};
|
|
50
50
|
var EventAssertionError = class extends Error {
|
|
51
|
-
description = "
|
|
52
|
-
|
|
51
|
+
description = "Thrown to indicate that an event was in an unexpected state when it reached the subscriber. Throwing this error will indicate to Matador NOT to retry the event. Matador does not throw this error directly - it is thrown by assertEvent, which you can use in your subscribers to assert properties about an event. This can be useful in scenarios where you would expect an event payload to contain a field based on the types, but something unexpected caused it to not be present. Using this instead of the NodeJS assert allows Matador to not retry the event subscriber.";
|
|
52
|
+
/** The envelope that failed the assertion */
|
|
53
|
+
envelope;
|
|
54
|
+
constructor(envelope, message) {
|
|
53
55
|
super(message);
|
|
54
56
|
this.name = "EventAssertionError";
|
|
57
|
+
this.envelope = envelope;
|
|
55
58
|
Object.defineProperty(this, "name", {
|
|
56
59
|
value: "EventAssertionError",
|
|
57
60
|
enumerable: true,
|
|
@@ -64,6 +67,7 @@ var EventAssertionError = class extends Error {
|
|
|
64
67
|
name: this.name,
|
|
65
68
|
message: this.message,
|
|
66
69
|
description: this.description,
|
|
70
|
+
envelope: this.envelope,
|
|
67
71
|
stack: this.stack
|
|
68
72
|
};
|
|
69
73
|
}
|
|
@@ -77,6 +81,13 @@ function isDontRetry(error) {
|
|
|
77
81
|
function isAssertionError(error) {
|
|
78
82
|
return error instanceof EventAssertionError;
|
|
79
83
|
}
|
|
84
|
+
function assertEvent(envelope, value, message) {
|
|
85
|
+
try {
|
|
86
|
+
assert__default.default(value, message);
|
|
87
|
+
} catch {
|
|
88
|
+
throw new EventAssertionError(envelope, message);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
80
91
|
|
|
81
92
|
// src/errors/matador-errors.ts
|
|
82
93
|
var MatadorError = class extends Error {
|
|
@@ -330,6 +341,12 @@ function getDeadLetterQueueName(namespace, queueName, dlqType) {
|
|
|
330
341
|
function getRetryQueueName(namespace, queueName) {
|
|
331
342
|
return `${namespace}.${queueName}.retry`;
|
|
332
343
|
}
|
|
344
|
+
function resolveQueueName(namespace, queueDef) {
|
|
345
|
+
if (queueDef.exact) {
|
|
346
|
+
return queueDef.name;
|
|
347
|
+
}
|
|
348
|
+
return `${namespace}.${queueDef.name}`;
|
|
349
|
+
}
|
|
333
350
|
|
|
334
351
|
// src/topology/builder.ts
|
|
335
352
|
function isQueueDefinition(arg) {
|
|
@@ -440,7 +457,7 @@ var TopologyBuilder = class _TopologyBuilder {
|
|
|
440
457
|
for (const queue of this.queues) {
|
|
441
458
|
if (!queue.name || queue.name.trim() === "") {
|
|
442
459
|
issues.push("Queue name cannot be empty");
|
|
443
|
-
} else if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(queue.name)) {
|
|
460
|
+
} else if (!queue.exact && !/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(queue.name)) {
|
|
444
461
|
issues.push(
|
|
445
462
|
`Queue name "${queue.name}" must start with a letter and contain only alphanumeric characters, underscores, and hyphens`
|
|
446
463
|
);
|
|
@@ -528,6 +545,14 @@ function createEnvelope(options) {
|
|
|
528
545
|
}
|
|
529
546
|
};
|
|
530
547
|
}
|
|
548
|
+
function createDummyEnvelope(event) {
|
|
549
|
+
return createEnvelope({
|
|
550
|
+
data: event.data,
|
|
551
|
+
eventKey: event.constructor.key,
|
|
552
|
+
targetSubscriber: "dummy-subscriber",
|
|
553
|
+
importance: "can-ignore"
|
|
554
|
+
});
|
|
555
|
+
}
|
|
531
556
|
|
|
532
557
|
// src/types/event.ts
|
|
533
558
|
var MatadorEvent = class {
|
|
@@ -575,7 +600,6 @@ function createSubscriber(input) {
|
|
|
575
600
|
function createSubscriberStub(input) {
|
|
576
601
|
return {
|
|
577
602
|
name: input.name,
|
|
578
|
-
description: input.description,
|
|
579
603
|
isStub: true,
|
|
580
604
|
idempotent: input.idempotent ?? "unknown",
|
|
581
605
|
importance: input.importance ?? "should-investigate",
|
|
@@ -1406,6 +1430,7 @@ var ProcessingPipeline = class {
|
|
|
1406
1430
|
retryPolicy;
|
|
1407
1431
|
hooks;
|
|
1408
1432
|
checkpointStore;
|
|
1433
|
+
dispatcher;
|
|
1409
1434
|
constructor(config) {
|
|
1410
1435
|
this.transport = config.transport;
|
|
1411
1436
|
this.schema = config.schema;
|
|
@@ -1413,6 +1438,7 @@ var ProcessingPipeline = class {
|
|
|
1413
1438
|
this.retryPolicy = config.retryPolicy;
|
|
1414
1439
|
this.hooks = config.hooks;
|
|
1415
1440
|
this.checkpointStore = config.checkpointStore ?? new NoOpCheckpointStore();
|
|
1441
|
+
this.dispatcher = config.dispatcher;
|
|
1416
1442
|
}
|
|
1417
1443
|
/**
|
|
1418
1444
|
* Processes a raw message from the transport.
|
|
@@ -1499,15 +1525,23 @@ var ProcessingPipeline = class {
|
|
|
1499
1525
|
}
|
|
1500
1526
|
});
|
|
1501
1527
|
}
|
|
1528
|
+
const callbackContext = { matador: this.dispatcher };
|
|
1502
1529
|
await this.hooks.onWorkerWrap(envelope, subscriberDef, async () => {
|
|
1503
1530
|
await this.hooks.onWorkerBeforeProcess(envelope, subscriberDef);
|
|
1504
1531
|
try {
|
|
1505
1532
|
if (isResumable && context) {
|
|
1506
1533
|
const resumableCallback = subscriber.callback;
|
|
1507
|
-
|
|
1534
|
+
const fullContext = {
|
|
1535
|
+
io: context.io.bind(context),
|
|
1536
|
+
all: context.all.bind(context),
|
|
1537
|
+
attempt: context.attempt,
|
|
1538
|
+
isRetry: context.isRetry,
|
|
1539
|
+
matador: this.dispatcher
|
|
1540
|
+
};
|
|
1541
|
+
result = await resumableCallback(envelope, fullContext);
|
|
1508
1542
|
} else {
|
|
1509
1543
|
const standardCallback = subscriber.callback;
|
|
1510
|
-
result = await standardCallback(envelope);
|
|
1544
|
+
result = await standardCallback(envelope, callbackContext);
|
|
1511
1545
|
}
|
|
1512
1546
|
} catch (e) {
|
|
1513
1547
|
error = e instanceof Error ? e : new Error(String(e));
|
|
@@ -1818,9 +1852,11 @@ var SchemaRegistry = class {
|
|
|
1818
1852
|
if (!subscriber) return void 0;
|
|
1819
1853
|
const def = {
|
|
1820
1854
|
name: subscriber.name,
|
|
1821
|
-
description: subscriber.description,
|
|
1822
1855
|
idempotent: subscriber.idempotent ?? "unknown",
|
|
1823
|
-
importance: subscriber.importance ?? "should-investigate"
|
|
1856
|
+
importance: subscriber.importance ?? "should-investigate",
|
|
1857
|
+
..."description" in subscriber && subscriber.description !== void 0 && {
|
|
1858
|
+
description: subscriber.description
|
|
1859
|
+
}
|
|
1824
1860
|
};
|
|
1825
1861
|
if (subscriber.targetQueue !== void 0) {
|
|
1826
1862
|
def.targetQueue = subscriber.targetQueue;
|
|
@@ -1940,7 +1976,8 @@ var Matador = class {
|
|
|
1940
1976
|
codec: this.codec,
|
|
1941
1977
|
retryPolicy: this.retryPolicy,
|
|
1942
1978
|
hooks: this.hooks,
|
|
1943
|
-
checkpointStore: config.checkpointStore
|
|
1979
|
+
checkpointStore: config.checkpointStore,
|
|
1980
|
+
dispatcher: this
|
|
1944
1981
|
});
|
|
1945
1982
|
const defaultQueue = this.topology.queues[0]?.name ?? "default";
|
|
1946
1983
|
this.fanout = new FanoutEngine({
|
|
@@ -2986,24 +3023,29 @@ var RabbitMQTransport = class {
|
|
|
2986
3023
|
}
|
|
2987
3024
|
async assertWorkQueue(channel, topology, queueDef) {
|
|
2988
3025
|
const queueName = queueDef.exact ? queueDef.name : `${topology.namespace}.${queueDef.name}`;
|
|
2989
|
-
const
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
}
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3026
|
+
const rabbitmqOptions = queueDef.transport?.rabbitmq?.options;
|
|
3027
|
+
if (rabbitmqOptions) {
|
|
3028
|
+
await channel.assertQueue(queueName, rabbitmqOptions);
|
|
3029
|
+
} else {
|
|
3030
|
+
const queueOptions = {
|
|
3031
|
+
durable: true,
|
|
3032
|
+
arguments: {}
|
|
3033
|
+
};
|
|
3034
|
+
if (this.config.quorumQueues && !queueDef.exact) {
|
|
3035
|
+
queueOptions.arguments["x-queue-type"] = "quorum";
|
|
3036
|
+
}
|
|
3037
|
+
const dlxExchange = this.getDLXExchangeName(topology.namespace);
|
|
3038
|
+
if (topology.deadLetter.unhandled.enabled || topology.deadLetter.undeliverable.enabled) {
|
|
3039
|
+
queueOptions.arguments["x-dead-letter-exchange"] = dlxExchange;
|
|
3040
|
+
}
|
|
3041
|
+
if (queueDef.priorities) {
|
|
3042
|
+
queueOptions.arguments["x-max-priority"] = 10;
|
|
3043
|
+
}
|
|
3044
|
+
if (queueDef.consumerTimeout) {
|
|
3045
|
+
queueOptions.arguments["x-consumer-timeout"] = queueDef.consumerTimeout;
|
|
3046
|
+
}
|
|
3047
|
+
await channel.assertQueue(queueName, queueOptions);
|
|
3005
3048
|
}
|
|
3006
|
-
await channel.assertQueue(queueName, queueOptions);
|
|
3007
3049
|
const mainExchange = this.getMainExchangeName(topology.namespace);
|
|
3008
3050
|
await channel.bindQueue(queueName, mainExchange, queueName);
|
|
3009
3051
|
if (this.delayedExchangeAvailable) {
|
|
@@ -3144,8 +3186,10 @@ exports.TopologyValidationError = TopologyValidationError;
|
|
|
3144
3186
|
exports.TransportClosedError = TransportClosedError;
|
|
3145
3187
|
exports.TransportNotConnectedError = TransportNotConnectedError;
|
|
3146
3188
|
exports.TransportSendError = TransportSendError;
|
|
3189
|
+
exports.assertEvent = assertEvent;
|
|
3147
3190
|
exports.bind = bind;
|
|
3148
3191
|
exports.consoleLogger = consoleLogger;
|
|
3192
|
+
exports.createDummyEnvelope = createDummyEnvelope;
|
|
3149
3193
|
exports.createEnvelope = createEnvelope;
|
|
3150
3194
|
exports.createSubscriber = createSubscriber;
|
|
3151
3195
|
exports.createSubscriberStub = createSubscriberStub;
|
|
@@ -3174,6 +3218,7 @@ exports.isSubscriber = isSubscriber;
|
|
|
3174
3218
|
exports.isSubscriberNotRegisteredError = isSubscriberNotRegisteredError;
|
|
3175
3219
|
exports.isSubscriberStub = isSubscriberStub;
|
|
3176
3220
|
exports.isTransportNotConnectedError = isTransportNotConnectedError;
|
|
3221
|
+
exports.resolveQueueName = resolveQueueName;
|
|
3177
3222
|
exports.supportsDelayedMessages = supportsDelayedMessages;
|
|
3178
3223
|
exports.supportsDeliveryMode = supportsDeliveryMode;
|
|
3179
3224
|
exports.validResult = validResult;
|