@gravito/signal 3.1.2 → 4.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/dist/OrbitSignal.d.ts +6 -0
- package/dist/errors/codes.d.ts +19 -0
- package/dist/errors.d.ts +18 -11
- package/dist/index.cjs +96 -35
- package/dist/index.d.ts +1 -0
- package/dist/index.js +96 -35
- package/dist/index.mjs +95 -35
- package/dist/transports/BaseTransport.d.ts +15 -23
- package/package.json +5 -4
package/dist/OrbitSignal.d.ts
CHANGED
|
@@ -200,6 +200,12 @@ export declare class OrbitSignal implements GravitoOrbit {
|
|
|
200
200
|
* ```
|
|
201
201
|
*/
|
|
202
202
|
install(core: PlanetCore): void;
|
|
203
|
+
/**
|
|
204
|
+
* Gracefully release transport and dev resources.
|
|
205
|
+
*
|
|
206
|
+
* Called during shutdown. Detects closeable transports via type narrowing (no `as any`).
|
|
207
|
+
*/
|
|
208
|
+
private cleanup;
|
|
203
209
|
/**
|
|
204
210
|
* Internal: Handle processed webhook.
|
|
205
211
|
*/
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured error codes for @gravito/signal mail operations.
|
|
3
|
+
* Follows fortify's dot-separated namespace convention.
|
|
4
|
+
*
|
|
5
|
+
* NOTE: This replaces MailErrorCode enum for new code.
|
|
6
|
+
* The existing enum in ../errors.ts remains until Phase 18-19 migration.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export declare const MailErrorCodes: {
|
|
11
|
+
readonly CONNECTION_FAILED: "mail.connection_failed";
|
|
12
|
+
readonly AUTH_FAILED: "mail.auth_failed";
|
|
13
|
+
readonly RECIPIENT_REJECTED: "mail.recipient_rejected";
|
|
14
|
+
readonly MESSAGE_REJECTED: "mail.message_rejected";
|
|
15
|
+
readonly RATE_LIMIT: "mail.rate_limit";
|
|
16
|
+
readonly SEND_FAILED: "mail.send_failed";
|
|
17
|
+
readonly UNKNOWN: "mail.unknown";
|
|
18
|
+
};
|
|
19
|
+
export type MailErrorCode = (typeof MailErrorCodes)[keyof typeof MailErrorCodes];
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { InfrastructureException } from '@gravito/core';
|
|
2
|
+
import { type MailErrorCode as MailErrorCodeType } from './errors/codes';
|
|
1
3
|
/**
|
|
2
|
-
* Mail transport error codes.
|
|
3
|
-
*
|
|
4
|
-
* Categorizes common failure modes in the mail delivery process to allow
|
|
5
|
-
* for programmatic handling (e.g., retries on rate limits).
|
|
4
|
+
* Mail transport error codes (legacy enum — kept for backward compat).
|
|
5
|
+
* New code should use MailErrorCodes from './errors/codes' instead.
|
|
6
6
|
*
|
|
7
|
+
* @deprecated Use MailErrorCodes from './errors/codes'
|
|
7
8
|
* @public
|
|
8
9
|
* @since 3.1.0
|
|
9
10
|
*/
|
|
@@ -24,8 +25,9 @@ export declare enum MailErrorCode {
|
|
|
24
25
|
/**
|
|
25
26
|
* Error class for mail transport failures.
|
|
26
27
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
28
|
+
* Extends InfrastructureException for unified error handling across Gravito.
|
|
29
|
+
* Carries a `retryable` flag indicating whether the operation can be retried,
|
|
30
|
+
* and preserves backward compat with the legacy MailErrorCode enum via `.legacyCode`.
|
|
29
31
|
*
|
|
30
32
|
* @example
|
|
31
33
|
* ```typescript
|
|
@@ -39,14 +41,19 @@ export declare enum MailErrorCode {
|
|
|
39
41
|
* @public
|
|
40
42
|
* @since 3.1.0
|
|
41
43
|
*/
|
|
42
|
-
export declare class MailTransportError extends
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
export declare class MailTransportError extends InfrastructureException {
|
|
45
|
+
/**
|
|
46
|
+
* Legacy enum code — preserved for backward compat with callers that switch on MailErrorCode.
|
|
47
|
+
* @deprecated Prefer checking `.code` (mail.* namespaced string) instead.
|
|
48
|
+
*/
|
|
49
|
+
readonly legacyCode: MailErrorCode;
|
|
45
50
|
/**
|
|
46
51
|
* Create a new mail transport error.
|
|
47
52
|
*
|
|
53
|
+
* Accepts both the legacy MailErrorCode enum and new mail.* namespaced string codes.
|
|
54
|
+
*
|
|
48
55
|
* @param message - Human-readable error message
|
|
49
|
-
* @param code - Categorized error code
|
|
56
|
+
* @param code - Categorized error code (legacy enum or new mail.* string)
|
|
50
57
|
* @param cause - Original error that caused this failure
|
|
51
58
|
*
|
|
52
59
|
* @example
|
|
@@ -54,5 +61,5 @@ export declare class MailTransportError extends Error {
|
|
|
54
61
|
* const error = new MailTransportError('Auth failed', MailErrorCode.AUTH_FAILED);
|
|
55
62
|
* ```
|
|
56
63
|
*/
|
|
57
|
-
constructor(message: string, code
|
|
64
|
+
constructor(message: string, code?: MailErrorCode | MailErrorCodeType, cause?: Error);
|
|
58
65
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -59693,6 +59693,7 @@ __export(index_exports, {
|
|
|
59693
59693
|
HtmlRenderer: () => HtmlRenderer,
|
|
59694
59694
|
LogTransport: () => LogTransport,
|
|
59695
59695
|
MailErrorCode: () => MailErrorCode,
|
|
59696
|
+
MailErrorCodes: () => MailErrorCodes,
|
|
59696
59697
|
MailTransportError: () => MailTransportError,
|
|
59697
59698
|
Mailable: () => Mailable,
|
|
59698
59699
|
MemoryTransport: () => MemoryTransport,
|
|
@@ -59838,6 +59839,20 @@ var DevMailbox = class {
|
|
|
59838
59839
|
}
|
|
59839
59840
|
};
|
|
59840
59841
|
|
|
59842
|
+
// src/errors.ts
|
|
59843
|
+
var import_core = require("@gravito/core");
|
|
59844
|
+
|
|
59845
|
+
// src/errors/codes.ts
|
|
59846
|
+
var MailErrorCodes = {
|
|
59847
|
+
CONNECTION_FAILED: "mail.connection_failed",
|
|
59848
|
+
AUTH_FAILED: "mail.auth_failed",
|
|
59849
|
+
RECIPIENT_REJECTED: "mail.recipient_rejected",
|
|
59850
|
+
MESSAGE_REJECTED: "mail.message_rejected",
|
|
59851
|
+
RATE_LIMIT: "mail.rate_limit",
|
|
59852
|
+
SEND_FAILED: "mail.send_failed",
|
|
59853
|
+
UNKNOWN: "mail.unknown"
|
|
59854
|
+
};
|
|
59855
|
+
|
|
59841
59856
|
// src/errors.ts
|
|
59842
59857
|
var MailErrorCode = /* @__PURE__ */ ((MailErrorCode2) => {
|
|
59843
59858
|
MailErrorCode2["CONNECTION_FAILED"] = "CONNECTION_FAILED";
|
|
@@ -59848,12 +59863,31 @@ var MailErrorCode = /* @__PURE__ */ ((MailErrorCode2) => {
|
|
|
59848
59863
|
MailErrorCode2["UNKNOWN"] = "UNKNOWN";
|
|
59849
59864
|
return MailErrorCode2;
|
|
59850
59865
|
})(MailErrorCode || {});
|
|
59851
|
-
var
|
|
59866
|
+
var legacyToNewCode = {
|
|
59867
|
+
["CONNECTION_FAILED" /* CONNECTION_FAILED */]: MailErrorCodes.CONNECTION_FAILED,
|
|
59868
|
+
["AUTH_FAILED" /* AUTH_FAILED */]: MailErrorCodes.AUTH_FAILED,
|
|
59869
|
+
["RECIPIENT_REJECTED" /* RECIPIENT_REJECTED */]: MailErrorCodes.RECIPIENT_REJECTED,
|
|
59870
|
+
["MESSAGE_REJECTED" /* MESSAGE_REJECTED */]: MailErrorCodes.MESSAGE_REJECTED,
|
|
59871
|
+
["RATE_LIMIT" /* RATE_LIMIT */]: MailErrorCodes.RATE_LIMIT,
|
|
59872
|
+
["UNKNOWN" /* UNKNOWN */]: MailErrorCodes.UNKNOWN
|
|
59873
|
+
};
|
|
59874
|
+
var RETRYABLE_CODES = /* @__PURE__ */ new Set([
|
|
59875
|
+
MailErrorCodes.CONNECTION_FAILED,
|
|
59876
|
+
MailErrorCodes.RATE_LIMIT
|
|
59877
|
+
]);
|
|
59878
|
+
var MailTransportError = class _MailTransportError extends import_core.InfrastructureException {
|
|
59879
|
+
/**
|
|
59880
|
+
* Legacy enum code — preserved for backward compat with callers that switch on MailErrorCode.
|
|
59881
|
+
* @deprecated Prefer checking `.code` (mail.* namespaced string) instead.
|
|
59882
|
+
*/
|
|
59883
|
+
legacyCode;
|
|
59852
59884
|
/**
|
|
59853
59885
|
* Create a new mail transport error.
|
|
59854
59886
|
*
|
|
59887
|
+
* Accepts both the legacy MailErrorCode enum and new mail.* namespaced string codes.
|
|
59888
|
+
*
|
|
59855
59889
|
* @param message - Human-readable error message
|
|
59856
|
-
* @param code - Categorized error code
|
|
59890
|
+
* @param code - Categorized error code (legacy enum or new mail.* string)
|
|
59857
59891
|
* @param cause - Original error that caused this failure
|
|
59858
59892
|
*
|
|
59859
59893
|
* @example
|
|
@@ -59861,11 +59895,16 @@ var MailTransportError = class _MailTransportError extends Error {
|
|
|
59861
59895
|
* const error = new MailTransportError('Auth failed', MailErrorCode.AUTH_FAILED);
|
|
59862
59896
|
* ```
|
|
59863
59897
|
*/
|
|
59864
|
-
constructor(message, code
|
|
59865
|
-
|
|
59866
|
-
|
|
59867
|
-
|
|
59898
|
+
constructor(message, code = "UNKNOWN" /* UNKNOWN */, cause) {
|
|
59899
|
+
const newCode = typeof code === "string" && code.startsWith("mail.") ? code : legacyToNewCode[code] ?? MailErrorCodes.UNKNOWN;
|
|
59900
|
+
super(502, newCode, {
|
|
59901
|
+
message,
|
|
59902
|
+
cause,
|
|
59903
|
+
retryable: RETRYABLE_CODES.has(newCode)
|
|
59904
|
+
});
|
|
59868
59905
|
this.name = "MailTransportError";
|
|
59906
|
+
this.legacyCode = typeof code === "string" && code.startsWith("mail.") ? Object.entries(legacyToNewCode).find(([, v]) => v === code)?.[0] ?? "UNKNOWN" /* UNKNOWN */ : code;
|
|
59907
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
59869
59908
|
if (Error.captureStackTrace) {
|
|
59870
59909
|
Error.captureStackTrace(this, _MailTransportError);
|
|
59871
59910
|
}
|
|
@@ -60851,6 +60890,9 @@ var MemoryTransport = class {
|
|
|
60851
60890
|
};
|
|
60852
60891
|
|
|
60853
60892
|
// src/OrbitSignal.ts
|
|
60893
|
+
function isCloseable(obj) {
|
|
60894
|
+
return typeof obj === "object" && obj !== null && "close" in obj && typeof obj.close === "function";
|
|
60895
|
+
}
|
|
60854
60896
|
var OrbitSignal = class {
|
|
60855
60897
|
config;
|
|
60856
60898
|
devMailbox;
|
|
@@ -60916,6 +60958,34 @@ var OrbitSignal = class {
|
|
|
60916
60958
|
}
|
|
60917
60959
|
});
|
|
60918
60960
|
}
|
|
60961
|
+
core.hooks.doAction("core:shutdown", async () => {
|
|
60962
|
+
const DEADLINE_MS = 5e3;
|
|
60963
|
+
const deadline = new Promise(
|
|
60964
|
+
(_, reject) => setTimeout(
|
|
60965
|
+
() => reject(new Error("[OrbitSignal] Shutdown deadline exceeded (5s)")),
|
|
60966
|
+
DEADLINE_MS
|
|
60967
|
+
)
|
|
60968
|
+
);
|
|
60969
|
+
try {
|
|
60970
|
+
await Promise.race([this.cleanup(), deadline]);
|
|
60971
|
+
} catch (err) {
|
|
60972
|
+
core.logger.warn("[OrbitSignal] Forced shutdown:", err);
|
|
60973
|
+
}
|
|
60974
|
+
});
|
|
60975
|
+
}
|
|
60976
|
+
/**
|
|
60977
|
+
* Gracefully release transport and dev resources.
|
|
60978
|
+
*
|
|
60979
|
+
* Called during shutdown. Detects closeable transports via type narrowing (no `as any`).
|
|
60980
|
+
*/
|
|
60981
|
+
async cleanup() {
|
|
60982
|
+
if (this.devMailbox) {
|
|
60983
|
+
this.devMailbox = void 0;
|
|
60984
|
+
}
|
|
60985
|
+
const transport = this.config.transport;
|
|
60986
|
+
if (isCloseable(transport)) {
|
|
60987
|
+
await transport.close();
|
|
60988
|
+
}
|
|
60919
60989
|
}
|
|
60920
60990
|
/**
|
|
60921
60991
|
* Internal: Handle processed webhook.
|
|
@@ -61111,6 +61181,7 @@ init_ReactMjmlRenderer();
|
|
|
61111
61181
|
init_VueMjmlRenderer();
|
|
61112
61182
|
|
|
61113
61183
|
// src/transports/BaseTransport.ts
|
|
61184
|
+
var import_resilience = require("@gravito/resilience");
|
|
61114
61185
|
var BaseTransport = class {
|
|
61115
61186
|
options;
|
|
61116
61187
|
/**
|
|
@@ -61126,14 +61197,14 @@ var BaseTransport = class {
|
|
|
61126
61197
|
};
|
|
61127
61198
|
}
|
|
61128
61199
|
/**
|
|
61129
|
-
* Orchestrates the message delivery with retry
|
|
61200
|
+
* Orchestrates the message delivery with automatic retry via @gravito/resilience.
|
|
61130
61201
|
*
|
|
61131
|
-
*
|
|
61132
|
-
*
|
|
61202
|
+
* Delegates to `doSend()` and retries on retryable InfrastructureException errors
|
|
61203
|
+
* (CONNECTION_FAILED, RATE_LIMIT). Non-retryable errors surface immediately.
|
|
61133
61204
|
*
|
|
61134
61205
|
* @param message - The message to be delivered.
|
|
61135
61206
|
* @returns A promise that resolves when the message is successfully sent.
|
|
61136
|
-
* @throws {MailTransportError} If the message cannot be sent after the maximum number of
|
|
61207
|
+
* @throws {MailTransportError} If the message cannot be sent after the maximum number of attempts.
|
|
61137
61208
|
*
|
|
61138
61209
|
* @example
|
|
61139
61210
|
* ```typescript
|
|
@@ -61146,33 +61217,22 @@ var BaseTransport = class {
|
|
|
61146
61217
|
* ```
|
|
61147
61218
|
*/
|
|
61148
61219
|
async send(message) {
|
|
61149
|
-
|
|
61150
|
-
|
|
61151
|
-
|
|
61152
|
-
|
|
61153
|
-
|
|
61154
|
-
}
|
|
61155
|
-
|
|
61156
|
-
|
|
61157
|
-
|
|
61158
|
-
delay *= this.options.backoffMultiplier;
|
|
61159
|
-
}
|
|
61220
|
+
try {
|
|
61221
|
+
await (0, import_resilience.withRetry)(() => this.doSend(message), {
|
|
61222
|
+
idempotent: true,
|
|
61223
|
+
maxAttempts: this.options.maxRetries,
|
|
61224
|
+
baseDelayMs: this.options.retryDelay
|
|
61225
|
+
});
|
|
61226
|
+
} catch (error) {
|
|
61227
|
+
if (error instanceof MailTransportError) {
|
|
61228
|
+
throw error;
|
|
61160
61229
|
}
|
|
61230
|
+
throw new MailTransportError(
|
|
61231
|
+
`Mail sending failed after ${this.options.maxRetries} retries`,
|
|
61232
|
+
"UNKNOWN" /* UNKNOWN */,
|
|
61233
|
+
error
|
|
61234
|
+
);
|
|
61161
61235
|
}
|
|
61162
|
-
throw new MailTransportError(
|
|
61163
|
-
`Mail sending failed after ${this.options.maxRetries} retries`,
|
|
61164
|
-
"UNKNOWN" /* UNKNOWN */,
|
|
61165
|
-
lastError
|
|
61166
|
-
);
|
|
61167
|
-
}
|
|
61168
|
-
/**
|
|
61169
|
-
* Utility method to pause execution for a given duration.
|
|
61170
|
-
*
|
|
61171
|
-
* @param ms - Milliseconds to sleep.
|
|
61172
|
-
* @returns A promise that resolves after the delay.
|
|
61173
|
-
*/
|
|
61174
|
-
sleep(ms) {
|
|
61175
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
61176
61236
|
}
|
|
61177
61237
|
};
|
|
61178
61238
|
|
|
@@ -61452,6 +61512,7 @@ var SesWebhookDriver = class {
|
|
|
61452
61512
|
HtmlRenderer,
|
|
61453
61513
|
LogTransport,
|
|
61454
61514
|
MailErrorCode,
|
|
61515
|
+
MailErrorCodes,
|
|
61455
61516
|
MailTransportError,
|
|
61456
61517
|
Mailable,
|
|
61457
61518
|
MemoryTransport,
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -59693,6 +59693,7 @@ __export(index_exports, {
|
|
|
59693
59693
|
HtmlRenderer: () => HtmlRenderer,
|
|
59694
59694
|
LogTransport: () => LogTransport,
|
|
59695
59695
|
MailErrorCode: () => MailErrorCode,
|
|
59696
|
+
MailErrorCodes: () => MailErrorCodes,
|
|
59696
59697
|
MailTransportError: () => MailTransportError,
|
|
59697
59698
|
Mailable: () => Mailable,
|
|
59698
59699
|
MemoryTransport: () => MemoryTransport,
|
|
@@ -59838,6 +59839,20 @@ var DevMailbox = class {
|
|
|
59838
59839
|
}
|
|
59839
59840
|
};
|
|
59840
59841
|
|
|
59842
|
+
// src/errors.ts
|
|
59843
|
+
var import_core = require("@gravito/core");
|
|
59844
|
+
|
|
59845
|
+
// src/errors/codes.ts
|
|
59846
|
+
var MailErrorCodes = {
|
|
59847
|
+
CONNECTION_FAILED: "mail.connection_failed",
|
|
59848
|
+
AUTH_FAILED: "mail.auth_failed",
|
|
59849
|
+
RECIPIENT_REJECTED: "mail.recipient_rejected",
|
|
59850
|
+
MESSAGE_REJECTED: "mail.message_rejected",
|
|
59851
|
+
RATE_LIMIT: "mail.rate_limit",
|
|
59852
|
+
SEND_FAILED: "mail.send_failed",
|
|
59853
|
+
UNKNOWN: "mail.unknown"
|
|
59854
|
+
};
|
|
59855
|
+
|
|
59841
59856
|
// src/errors.ts
|
|
59842
59857
|
var MailErrorCode = /* @__PURE__ */ ((MailErrorCode2) => {
|
|
59843
59858
|
MailErrorCode2["CONNECTION_FAILED"] = "CONNECTION_FAILED";
|
|
@@ -59848,12 +59863,31 @@ var MailErrorCode = /* @__PURE__ */ ((MailErrorCode2) => {
|
|
|
59848
59863
|
MailErrorCode2["UNKNOWN"] = "UNKNOWN";
|
|
59849
59864
|
return MailErrorCode2;
|
|
59850
59865
|
})(MailErrorCode || {});
|
|
59851
|
-
var
|
|
59866
|
+
var legacyToNewCode = {
|
|
59867
|
+
["CONNECTION_FAILED" /* CONNECTION_FAILED */]: MailErrorCodes.CONNECTION_FAILED,
|
|
59868
|
+
["AUTH_FAILED" /* AUTH_FAILED */]: MailErrorCodes.AUTH_FAILED,
|
|
59869
|
+
["RECIPIENT_REJECTED" /* RECIPIENT_REJECTED */]: MailErrorCodes.RECIPIENT_REJECTED,
|
|
59870
|
+
["MESSAGE_REJECTED" /* MESSAGE_REJECTED */]: MailErrorCodes.MESSAGE_REJECTED,
|
|
59871
|
+
["RATE_LIMIT" /* RATE_LIMIT */]: MailErrorCodes.RATE_LIMIT,
|
|
59872
|
+
["UNKNOWN" /* UNKNOWN */]: MailErrorCodes.UNKNOWN
|
|
59873
|
+
};
|
|
59874
|
+
var RETRYABLE_CODES = /* @__PURE__ */ new Set([
|
|
59875
|
+
MailErrorCodes.CONNECTION_FAILED,
|
|
59876
|
+
MailErrorCodes.RATE_LIMIT
|
|
59877
|
+
]);
|
|
59878
|
+
var MailTransportError = class _MailTransportError extends import_core.InfrastructureException {
|
|
59879
|
+
/**
|
|
59880
|
+
* Legacy enum code — preserved for backward compat with callers that switch on MailErrorCode.
|
|
59881
|
+
* @deprecated Prefer checking `.code` (mail.* namespaced string) instead.
|
|
59882
|
+
*/
|
|
59883
|
+
legacyCode;
|
|
59852
59884
|
/**
|
|
59853
59885
|
* Create a new mail transport error.
|
|
59854
59886
|
*
|
|
59887
|
+
* Accepts both the legacy MailErrorCode enum and new mail.* namespaced string codes.
|
|
59888
|
+
*
|
|
59855
59889
|
* @param message - Human-readable error message
|
|
59856
|
-
* @param code - Categorized error code
|
|
59890
|
+
* @param code - Categorized error code (legacy enum or new mail.* string)
|
|
59857
59891
|
* @param cause - Original error that caused this failure
|
|
59858
59892
|
*
|
|
59859
59893
|
* @example
|
|
@@ -59861,11 +59895,16 @@ var MailTransportError = class _MailTransportError extends Error {
|
|
|
59861
59895
|
* const error = new MailTransportError('Auth failed', MailErrorCode.AUTH_FAILED);
|
|
59862
59896
|
* ```
|
|
59863
59897
|
*/
|
|
59864
|
-
constructor(message, code
|
|
59865
|
-
|
|
59866
|
-
|
|
59867
|
-
|
|
59898
|
+
constructor(message, code = "UNKNOWN" /* UNKNOWN */, cause) {
|
|
59899
|
+
const newCode = typeof code === "string" && code.startsWith("mail.") ? code : legacyToNewCode[code] ?? MailErrorCodes.UNKNOWN;
|
|
59900
|
+
super(502, newCode, {
|
|
59901
|
+
message,
|
|
59902
|
+
cause,
|
|
59903
|
+
retryable: RETRYABLE_CODES.has(newCode)
|
|
59904
|
+
});
|
|
59868
59905
|
this.name = "MailTransportError";
|
|
59906
|
+
this.legacyCode = typeof code === "string" && code.startsWith("mail.") ? Object.entries(legacyToNewCode).find(([, v]) => v === code)?.[0] ?? "UNKNOWN" /* UNKNOWN */ : code;
|
|
59907
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
59869
59908
|
if (Error.captureStackTrace) {
|
|
59870
59909
|
Error.captureStackTrace(this, _MailTransportError);
|
|
59871
59910
|
}
|
|
@@ -60851,6 +60890,9 @@ var MemoryTransport = class {
|
|
|
60851
60890
|
};
|
|
60852
60891
|
|
|
60853
60892
|
// src/OrbitSignal.ts
|
|
60893
|
+
function isCloseable(obj) {
|
|
60894
|
+
return typeof obj === "object" && obj !== null && "close" in obj && typeof obj.close === "function";
|
|
60895
|
+
}
|
|
60854
60896
|
var OrbitSignal = class {
|
|
60855
60897
|
config;
|
|
60856
60898
|
devMailbox;
|
|
@@ -60916,6 +60958,34 @@ var OrbitSignal = class {
|
|
|
60916
60958
|
}
|
|
60917
60959
|
});
|
|
60918
60960
|
}
|
|
60961
|
+
core.hooks.doAction("core:shutdown", async () => {
|
|
60962
|
+
const DEADLINE_MS = 5e3;
|
|
60963
|
+
const deadline = new Promise(
|
|
60964
|
+
(_, reject) => setTimeout(
|
|
60965
|
+
() => reject(new Error("[OrbitSignal] Shutdown deadline exceeded (5s)")),
|
|
60966
|
+
DEADLINE_MS
|
|
60967
|
+
)
|
|
60968
|
+
);
|
|
60969
|
+
try {
|
|
60970
|
+
await Promise.race([this.cleanup(), deadline]);
|
|
60971
|
+
} catch (err) {
|
|
60972
|
+
core.logger.warn("[OrbitSignal] Forced shutdown:", err);
|
|
60973
|
+
}
|
|
60974
|
+
});
|
|
60975
|
+
}
|
|
60976
|
+
/**
|
|
60977
|
+
* Gracefully release transport and dev resources.
|
|
60978
|
+
*
|
|
60979
|
+
* Called during shutdown. Detects closeable transports via type narrowing (no `as any`).
|
|
60980
|
+
*/
|
|
60981
|
+
async cleanup() {
|
|
60982
|
+
if (this.devMailbox) {
|
|
60983
|
+
this.devMailbox = void 0;
|
|
60984
|
+
}
|
|
60985
|
+
const transport = this.config.transport;
|
|
60986
|
+
if (isCloseable(transport)) {
|
|
60987
|
+
await transport.close();
|
|
60988
|
+
}
|
|
60919
60989
|
}
|
|
60920
60990
|
/**
|
|
60921
60991
|
* Internal: Handle processed webhook.
|
|
@@ -61111,6 +61181,7 @@ init_ReactMjmlRenderer();
|
|
|
61111
61181
|
init_VueMjmlRenderer();
|
|
61112
61182
|
|
|
61113
61183
|
// src/transports/BaseTransport.ts
|
|
61184
|
+
var import_resilience = require("@gravito/resilience");
|
|
61114
61185
|
var BaseTransport = class {
|
|
61115
61186
|
options;
|
|
61116
61187
|
/**
|
|
@@ -61126,14 +61197,14 @@ var BaseTransport = class {
|
|
|
61126
61197
|
};
|
|
61127
61198
|
}
|
|
61128
61199
|
/**
|
|
61129
|
-
* Orchestrates the message delivery with retry
|
|
61200
|
+
* Orchestrates the message delivery with automatic retry via @gravito/resilience.
|
|
61130
61201
|
*
|
|
61131
|
-
*
|
|
61132
|
-
*
|
|
61202
|
+
* Delegates to `doSend()` and retries on retryable InfrastructureException errors
|
|
61203
|
+
* (CONNECTION_FAILED, RATE_LIMIT). Non-retryable errors surface immediately.
|
|
61133
61204
|
*
|
|
61134
61205
|
* @param message - The message to be delivered.
|
|
61135
61206
|
* @returns A promise that resolves when the message is successfully sent.
|
|
61136
|
-
* @throws {MailTransportError} If the message cannot be sent after the maximum number of
|
|
61207
|
+
* @throws {MailTransportError} If the message cannot be sent after the maximum number of attempts.
|
|
61137
61208
|
*
|
|
61138
61209
|
* @example
|
|
61139
61210
|
* ```typescript
|
|
@@ -61146,33 +61217,22 @@ var BaseTransport = class {
|
|
|
61146
61217
|
* ```
|
|
61147
61218
|
*/
|
|
61148
61219
|
async send(message) {
|
|
61149
|
-
|
|
61150
|
-
|
|
61151
|
-
|
|
61152
|
-
|
|
61153
|
-
|
|
61154
|
-
}
|
|
61155
|
-
|
|
61156
|
-
|
|
61157
|
-
|
|
61158
|
-
delay *= this.options.backoffMultiplier;
|
|
61159
|
-
}
|
|
61220
|
+
try {
|
|
61221
|
+
await (0, import_resilience.withRetry)(() => this.doSend(message), {
|
|
61222
|
+
idempotent: true,
|
|
61223
|
+
maxAttempts: this.options.maxRetries,
|
|
61224
|
+
baseDelayMs: this.options.retryDelay
|
|
61225
|
+
});
|
|
61226
|
+
} catch (error) {
|
|
61227
|
+
if (error instanceof MailTransportError) {
|
|
61228
|
+
throw error;
|
|
61160
61229
|
}
|
|
61230
|
+
throw new MailTransportError(
|
|
61231
|
+
`Mail sending failed after ${this.options.maxRetries} retries`,
|
|
61232
|
+
"UNKNOWN" /* UNKNOWN */,
|
|
61233
|
+
error
|
|
61234
|
+
);
|
|
61161
61235
|
}
|
|
61162
|
-
throw new MailTransportError(
|
|
61163
|
-
`Mail sending failed after ${this.options.maxRetries} retries`,
|
|
61164
|
-
"UNKNOWN" /* UNKNOWN */,
|
|
61165
|
-
lastError
|
|
61166
|
-
);
|
|
61167
|
-
}
|
|
61168
|
-
/**
|
|
61169
|
-
* Utility method to pause execution for a given duration.
|
|
61170
|
-
*
|
|
61171
|
-
* @param ms - Milliseconds to sleep.
|
|
61172
|
-
* @returns A promise that resolves after the delay.
|
|
61173
|
-
*/
|
|
61174
|
-
sleep(ms) {
|
|
61175
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
61176
61236
|
}
|
|
61177
61237
|
};
|
|
61178
61238
|
|
|
@@ -61452,6 +61512,7 @@ var SesWebhookDriver = class {
|
|
|
61452
61512
|
HtmlRenderer,
|
|
61453
61513
|
LogTransport,
|
|
61454
61514
|
MailErrorCode,
|
|
61515
|
+
MailErrorCodes,
|
|
61455
61516
|
MailTransportError,
|
|
61456
61517
|
Mailable,
|
|
61457
61518
|
MemoryTransport,
|
package/dist/index.mjs
CHANGED
|
@@ -59817,6 +59817,20 @@ var DevMailbox = class {
|
|
|
59817
59817
|
}
|
|
59818
59818
|
};
|
|
59819
59819
|
|
|
59820
|
+
// src/errors.ts
|
|
59821
|
+
import { InfrastructureException } from "@gravito/core";
|
|
59822
|
+
|
|
59823
|
+
// src/errors/codes.ts
|
|
59824
|
+
var MailErrorCodes = {
|
|
59825
|
+
CONNECTION_FAILED: "mail.connection_failed",
|
|
59826
|
+
AUTH_FAILED: "mail.auth_failed",
|
|
59827
|
+
RECIPIENT_REJECTED: "mail.recipient_rejected",
|
|
59828
|
+
MESSAGE_REJECTED: "mail.message_rejected",
|
|
59829
|
+
RATE_LIMIT: "mail.rate_limit",
|
|
59830
|
+
SEND_FAILED: "mail.send_failed",
|
|
59831
|
+
UNKNOWN: "mail.unknown"
|
|
59832
|
+
};
|
|
59833
|
+
|
|
59820
59834
|
// src/errors.ts
|
|
59821
59835
|
var MailErrorCode = /* @__PURE__ */ ((MailErrorCode2) => {
|
|
59822
59836
|
MailErrorCode2["CONNECTION_FAILED"] = "CONNECTION_FAILED";
|
|
@@ -59827,12 +59841,31 @@ var MailErrorCode = /* @__PURE__ */ ((MailErrorCode2) => {
|
|
|
59827
59841
|
MailErrorCode2["UNKNOWN"] = "UNKNOWN";
|
|
59828
59842
|
return MailErrorCode2;
|
|
59829
59843
|
})(MailErrorCode || {});
|
|
59830
|
-
var
|
|
59844
|
+
var legacyToNewCode = {
|
|
59845
|
+
["CONNECTION_FAILED" /* CONNECTION_FAILED */]: MailErrorCodes.CONNECTION_FAILED,
|
|
59846
|
+
["AUTH_FAILED" /* AUTH_FAILED */]: MailErrorCodes.AUTH_FAILED,
|
|
59847
|
+
["RECIPIENT_REJECTED" /* RECIPIENT_REJECTED */]: MailErrorCodes.RECIPIENT_REJECTED,
|
|
59848
|
+
["MESSAGE_REJECTED" /* MESSAGE_REJECTED */]: MailErrorCodes.MESSAGE_REJECTED,
|
|
59849
|
+
["RATE_LIMIT" /* RATE_LIMIT */]: MailErrorCodes.RATE_LIMIT,
|
|
59850
|
+
["UNKNOWN" /* UNKNOWN */]: MailErrorCodes.UNKNOWN
|
|
59851
|
+
};
|
|
59852
|
+
var RETRYABLE_CODES = /* @__PURE__ */ new Set([
|
|
59853
|
+
MailErrorCodes.CONNECTION_FAILED,
|
|
59854
|
+
MailErrorCodes.RATE_LIMIT
|
|
59855
|
+
]);
|
|
59856
|
+
var MailTransportError = class _MailTransportError extends InfrastructureException {
|
|
59857
|
+
/**
|
|
59858
|
+
* Legacy enum code — preserved for backward compat with callers that switch on MailErrorCode.
|
|
59859
|
+
* @deprecated Prefer checking `.code` (mail.* namespaced string) instead.
|
|
59860
|
+
*/
|
|
59861
|
+
legacyCode;
|
|
59831
59862
|
/**
|
|
59832
59863
|
* Create a new mail transport error.
|
|
59833
59864
|
*
|
|
59865
|
+
* Accepts both the legacy MailErrorCode enum and new mail.* namespaced string codes.
|
|
59866
|
+
*
|
|
59834
59867
|
* @param message - Human-readable error message
|
|
59835
|
-
* @param code - Categorized error code
|
|
59868
|
+
* @param code - Categorized error code (legacy enum or new mail.* string)
|
|
59836
59869
|
* @param cause - Original error that caused this failure
|
|
59837
59870
|
*
|
|
59838
59871
|
* @example
|
|
@@ -59840,11 +59873,16 @@ var MailTransportError = class _MailTransportError extends Error {
|
|
|
59840
59873
|
* const error = new MailTransportError('Auth failed', MailErrorCode.AUTH_FAILED);
|
|
59841
59874
|
* ```
|
|
59842
59875
|
*/
|
|
59843
|
-
constructor(message, code
|
|
59844
|
-
|
|
59845
|
-
|
|
59846
|
-
|
|
59876
|
+
constructor(message, code = "UNKNOWN" /* UNKNOWN */, cause) {
|
|
59877
|
+
const newCode = typeof code === "string" && code.startsWith("mail.") ? code : legacyToNewCode[code] ?? MailErrorCodes.UNKNOWN;
|
|
59878
|
+
super(502, newCode, {
|
|
59879
|
+
message,
|
|
59880
|
+
cause,
|
|
59881
|
+
retryable: RETRYABLE_CODES.has(newCode)
|
|
59882
|
+
});
|
|
59847
59883
|
this.name = "MailTransportError";
|
|
59884
|
+
this.legacyCode = typeof code === "string" && code.startsWith("mail.") ? Object.entries(legacyToNewCode).find(([, v]) => v === code)?.[0] ?? "UNKNOWN" /* UNKNOWN */ : code;
|
|
59885
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
59848
59886
|
if (Error.captureStackTrace) {
|
|
59849
59887
|
Error.captureStackTrace(this, _MailTransportError);
|
|
59850
59888
|
}
|
|
@@ -60830,6 +60868,9 @@ var MemoryTransport = class {
|
|
|
60830
60868
|
};
|
|
60831
60869
|
|
|
60832
60870
|
// src/OrbitSignal.ts
|
|
60871
|
+
function isCloseable(obj) {
|
|
60872
|
+
return typeof obj === "object" && obj !== null && "close" in obj && typeof obj.close === "function";
|
|
60873
|
+
}
|
|
60833
60874
|
var OrbitSignal = class {
|
|
60834
60875
|
config;
|
|
60835
60876
|
devMailbox;
|
|
@@ -60895,6 +60936,34 @@ var OrbitSignal = class {
|
|
|
60895
60936
|
}
|
|
60896
60937
|
});
|
|
60897
60938
|
}
|
|
60939
|
+
core.hooks.doAction("core:shutdown", async () => {
|
|
60940
|
+
const DEADLINE_MS = 5e3;
|
|
60941
|
+
const deadline = new Promise(
|
|
60942
|
+
(_, reject) => setTimeout(
|
|
60943
|
+
() => reject(new Error("[OrbitSignal] Shutdown deadline exceeded (5s)")),
|
|
60944
|
+
DEADLINE_MS
|
|
60945
|
+
)
|
|
60946
|
+
);
|
|
60947
|
+
try {
|
|
60948
|
+
await Promise.race([this.cleanup(), deadline]);
|
|
60949
|
+
} catch (err) {
|
|
60950
|
+
core.logger.warn("[OrbitSignal] Forced shutdown:", err);
|
|
60951
|
+
}
|
|
60952
|
+
});
|
|
60953
|
+
}
|
|
60954
|
+
/**
|
|
60955
|
+
* Gracefully release transport and dev resources.
|
|
60956
|
+
*
|
|
60957
|
+
* Called during shutdown. Detects closeable transports via type narrowing (no `as any`).
|
|
60958
|
+
*/
|
|
60959
|
+
async cleanup() {
|
|
60960
|
+
if (this.devMailbox) {
|
|
60961
|
+
this.devMailbox = void 0;
|
|
60962
|
+
}
|
|
60963
|
+
const transport = this.config.transport;
|
|
60964
|
+
if (isCloseable(transport)) {
|
|
60965
|
+
await transport.close();
|
|
60966
|
+
}
|
|
60898
60967
|
}
|
|
60899
60968
|
/**
|
|
60900
60969
|
* Internal: Handle processed webhook.
|
|
@@ -61090,6 +61159,7 @@ init_ReactMjmlRenderer();
|
|
|
61090
61159
|
init_VueMjmlRenderer();
|
|
61091
61160
|
|
|
61092
61161
|
// src/transports/BaseTransport.ts
|
|
61162
|
+
import { withRetry } from "@gravito/resilience";
|
|
61093
61163
|
var BaseTransport = class {
|
|
61094
61164
|
options;
|
|
61095
61165
|
/**
|
|
@@ -61105,14 +61175,14 @@ var BaseTransport = class {
|
|
|
61105
61175
|
};
|
|
61106
61176
|
}
|
|
61107
61177
|
/**
|
|
61108
|
-
* Orchestrates the message delivery with retry
|
|
61178
|
+
* Orchestrates the message delivery with automatic retry via @gravito/resilience.
|
|
61109
61179
|
*
|
|
61110
|
-
*
|
|
61111
|
-
*
|
|
61180
|
+
* Delegates to `doSend()` and retries on retryable InfrastructureException errors
|
|
61181
|
+
* (CONNECTION_FAILED, RATE_LIMIT). Non-retryable errors surface immediately.
|
|
61112
61182
|
*
|
|
61113
61183
|
* @param message - The message to be delivered.
|
|
61114
61184
|
* @returns A promise that resolves when the message is successfully sent.
|
|
61115
|
-
* @throws {MailTransportError} If the message cannot be sent after the maximum number of
|
|
61185
|
+
* @throws {MailTransportError} If the message cannot be sent after the maximum number of attempts.
|
|
61116
61186
|
*
|
|
61117
61187
|
* @example
|
|
61118
61188
|
* ```typescript
|
|
@@ -61125,33 +61195,22 @@ var BaseTransport = class {
|
|
|
61125
61195
|
* ```
|
|
61126
61196
|
*/
|
|
61127
61197
|
async send(message) {
|
|
61128
|
-
|
|
61129
|
-
|
|
61130
|
-
|
|
61131
|
-
|
|
61132
|
-
|
|
61133
|
-
}
|
|
61134
|
-
|
|
61135
|
-
|
|
61136
|
-
|
|
61137
|
-
delay *= this.options.backoffMultiplier;
|
|
61138
|
-
}
|
|
61198
|
+
try {
|
|
61199
|
+
await withRetry(() => this.doSend(message), {
|
|
61200
|
+
idempotent: true,
|
|
61201
|
+
maxAttempts: this.options.maxRetries,
|
|
61202
|
+
baseDelayMs: this.options.retryDelay
|
|
61203
|
+
});
|
|
61204
|
+
} catch (error) {
|
|
61205
|
+
if (error instanceof MailTransportError) {
|
|
61206
|
+
throw error;
|
|
61139
61207
|
}
|
|
61208
|
+
throw new MailTransportError(
|
|
61209
|
+
`Mail sending failed after ${this.options.maxRetries} retries`,
|
|
61210
|
+
"UNKNOWN" /* UNKNOWN */,
|
|
61211
|
+
error
|
|
61212
|
+
);
|
|
61140
61213
|
}
|
|
61141
|
-
throw new MailTransportError(
|
|
61142
|
-
`Mail sending failed after ${this.options.maxRetries} retries`,
|
|
61143
|
-
"UNKNOWN" /* UNKNOWN */,
|
|
61144
|
-
lastError
|
|
61145
|
-
);
|
|
61146
|
-
}
|
|
61147
|
-
/**
|
|
61148
|
-
* Utility method to pause execution for a given duration.
|
|
61149
|
-
*
|
|
61150
|
-
* @param ms - Milliseconds to sleep.
|
|
61151
|
-
* @returns A promise that resolves after the delay.
|
|
61152
|
-
*/
|
|
61153
|
-
sleep(ms) {
|
|
61154
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
61155
61214
|
}
|
|
61156
61215
|
};
|
|
61157
61216
|
|
|
@@ -61430,6 +61489,7 @@ export {
|
|
|
61430
61489
|
HtmlRenderer,
|
|
61431
61490
|
LogTransport,
|
|
61432
61491
|
MailErrorCode,
|
|
61492
|
+
MailErrorCodes,
|
|
61433
61493
|
MailTransportError,
|
|
61434
61494
|
Mailable,
|
|
61435
61495
|
MemoryTransport,
|
|
@@ -5,6 +5,9 @@ import type { Message, Transport } from '../types';
|
|
|
5
5
|
* Defines the behavior of the automatic retry mechanism, including the number of attempts
|
|
6
6
|
* and the timing between them using exponential backoff.
|
|
7
7
|
*
|
|
8
|
+
* @deprecated Configuration now handled internally by @gravito/resilience RetryOptions.
|
|
9
|
+
* Kept for backward compat of existing subclass constructors.
|
|
10
|
+
*
|
|
8
11
|
* @example
|
|
9
12
|
* ```typescript
|
|
10
13
|
* const options: TransportOptions = {
|
|
@@ -29,21 +32,17 @@ export interface TransportOptions {
|
|
|
29
32
|
/**
|
|
30
33
|
* Multiplier applied to the delay after each failed attempt.
|
|
31
34
|
* Used to implement exponential backoff to avoid overwhelming the service.
|
|
35
|
+
* @deprecated Backoff is now managed by @gravito/resilience (ExponentialBackoff).
|
|
32
36
|
*/
|
|
33
37
|
backoffMultiplier?: number;
|
|
34
38
|
}
|
|
35
39
|
/**
|
|
36
|
-
* Base transport class with automatic retry
|
|
40
|
+
* Base transport class with automatic retry via @gravito/resilience.
|
|
37
41
|
*
|
|
38
42
|
* This abstract class provides a robust foundation for all transport implementations by
|
|
39
|
-
* handling transient failures through
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* The retry mechanism works as follows:
|
|
43
|
-
* 1. Attempt to send the message via `doSend()`.
|
|
44
|
-
* 2. If it fails, wait for `retryDelay` milliseconds.
|
|
45
|
-
* 3. Increment the delay by `backoffMultiplier` for the next attempt.
|
|
46
|
-
* 4. Repeat until success or `maxRetries` is reached.
|
|
43
|
+
* handling transient failures through the unified @gravito/resilience withRetry primitive.
|
|
44
|
+
* Only errors whose `retryable` flag is true (e.g., CONNECTION_FAILED, RATE_LIMIT) are
|
|
45
|
+
* retried automatically.
|
|
47
46
|
*
|
|
48
47
|
* @example
|
|
49
48
|
* ```typescript
|
|
@@ -54,7 +53,7 @@ export interface TransportOptions {
|
|
|
54
53
|
*
|
|
55
54
|
* protected async doSend(message: Message): Promise<void> {
|
|
56
55
|
* // Actual implementation of the sending logic
|
|
57
|
-
* // If this throws, BaseTransport will
|
|
56
|
+
* // If this throws, BaseTransport will retry via withRetry
|
|
58
57
|
* }
|
|
59
58
|
* }
|
|
60
59
|
* ```
|
|
@@ -70,14 +69,14 @@ export declare abstract class BaseTransport implements Transport {
|
|
|
70
69
|
*/
|
|
71
70
|
constructor(options?: TransportOptions);
|
|
72
71
|
/**
|
|
73
|
-
* Orchestrates the message delivery with retry
|
|
72
|
+
* Orchestrates the message delivery with automatic retry via @gravito/resilience.
|
|
74
73
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
74
|
+
* Delegates to `doSend()` and retries on retryable InfrastructureException errors
|
|
75
|
+
* (CONNECTION_FAILED, RATE_LIMIT). Non-retryable errors surface immediately.
|
|
77
76
|
*
|
|
78
77
|
* @param message - The message to be delivered.
|
|
79
78
|
* @returns A promise that resolves when the message is successfully sent.
|
|
80
|
-
* @throws {MailTransportError} If the message cannot be sent after the maximum number of
|
|
79
|
+
* @throws {MailTransportError} If the message cannot be sent after the maximum number of attempts.
|
|
81
80
|
*
|
|
82
81
|
* @example
|
|
83
82
|
* ```typescript
|
|
@@ -94,18 +93,11 @@ export declare abstract class BaseTransport implements Transport {
|
|
|
94
93
|
* Actual transport implementation to be provided by subclasses.
|
|
95
94
|
*
|
|
96
95
|
* This method should contain the protocol-specific logic for delivering the message.
|
|
97
|
-
* It will be automatically retried by
|
|
96
|
+
* It will be automatically retried by `send()` if it throws a retryable error.
|
|
98
97
|
*
|
|
99
98
|
* @param message - The message to send.
|
|
100
99
|
* @returns A promise that resolves when the delivery is successful.
|
|
101
|
-
* @throws {Error} Any error encountered during delivery, which
|
|
100
|
+
* @throws {Error} Any error encountered during delivery, which may trigger a retry.
|
|
102
101
|
*/
|
|
103
102
|
protected abstract doSend(message: Message): Promise<void>;
|
|
104
|
-
/**
|
|
105
|
-
* Utility method to pause execution for a given duration.
|
|
106
|
-
*
|
|
107
|
-
* @param ms - Milliseconds to sleep.
|
|
108
|
-
* @returns A promise that resolves after the delay.
|
|
109
|
-
*/
|
|
110
|
-
private sleep;
|
|
111
103
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gravito/signal",
|
|
3
3
|
"sideEffects": false,
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0",
|
|
5
5
|
"description": "Powerful email framework for Gravito applications with Dev UI and multi-renderer support.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
@@ -39,12 +39,13 @@
|
|
|
39
39
|
"license": "MIT",
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@aws-sdk/client-ses": "^3.953.0",
|
|
42
|
+
"@gravito/resilience": "workspace:*",
|
|
42
43
|
"nodemailer": "^7.0.11"
|
|
43
44
|
},
|
|
44
45
|
"peerDependencies": {
|
|
45
|
-
"@gravito/core": "^
|
|
46
|
-
"@gravito/stream": "^
|
|
47
|
-
"@gravito/prism": "^
|
|
46
|
+
"@gravito/core": "^3.0.0",
|
|
47
|
+
"@gravito/stream": "^3.0.0",
|
|
48
|
+
"@gravito/prism": "^4.0.0",
|
|
48
49
|
"react": "^19.0.0",
|
|
49
50
|
"react-dom": "^19.0.0",
|
|
50
51
|
"vue": "^3.0.0"
|