@benclmnt/postmock 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +251 -0
- package/dist/seeds/conformance/00-core.d.ts +4 -0
- package/dist/seeds/conformance/00-core.js +12 -0
- package/dist/seeds/conformance/20-bounces.d.ts +3 -0
- package/dist/seeds/conformance/20-bounces.js +108 -0
- package/dist/seeds/conformance/40-messages.d.ts +3 -0
- package/dist/seeds/conformance/40-messages.js +144 -0
- package/dist/seeds/conformance/50-server-color.d.ts +8 -0
- package/dist/seeds/conformance/50-server-color.js +13 -0
- package/dist/seeds/conformance/70-account.d.ts +9 -0
- package/dist/seeds/conformance/70-account.js +29 -0
- package/dist/seeds/conformance/80-templates.d.ts +4 -0
- package/dist/seeds/conformance/80-templates.js +23 -0
- package/dist/seeds/conformance.d.ts +2 -0
- package/dist/seeds/conformance.js +3 -0
- package/dist/seeds/empty.d.ts +4 -0
- package/dist/seeds/empty.js +3 -0
- package/dist/seeds/lib/conformance.d.ts +16 -0
- package/dist/seeds/lib/conformance.js +18 -0
- package/dist/seeds/lib/history.d.ts +27 -0
- package/dist/seeds/lib/history.js +129 -0
- package/dist/seeds/lib/read-server.d.ts +10 -0
- package/dist/seeds/lib/read-server.js +10 -0
- package/dist/seeds/lib/template-server.d.ts +13 -0
- package/dist/seeds/lib/template-server.js +13 -0
- package/dist/src/api/account/authentication.d.ts +39 -0
- package/dist/src/api/account/authentication.js +97 -0
- package/dist/src/api/account/domains.d.ts +59 -0
- package/dist/src/api/account/domains.js +78 -0
- package/dist/src/api/account/paging.d.ts +12 -0
- package/dist/src/api/account/paging.js +35 -0
- package/dist/src/api/account/push.d.ts +14 -0
- package/dist/src/api/account/push.js +84 -0
- package/dist/src/api/account/routes.d.ts +1 -0
- package/dist/src/api/account/routes.js +288 -0
- package/dist/src/api/account/senders.d.ts +54 -0
- package/dist/src/api/account/senders.js +87 -0
- package/dist/src/api/account/servers.d.ts +40 -0
- package/dist/src/api/account/servers.js +148 -0
- package/dist/src/api/bounces/json.d.ts +25 -0
- package/dist/src/api/bounces/json.js +27 -0
- package/dist/src/api/bounces/routes.d.ts +1 -0
- package/dist/src/api/bounces/routes.js +127 -0
- package/dist/src/api/bulk/bulk.d.ts +43 -0
- package/dist/src/api/bulk/bulk.js +81 -0
- package/dist/src/api/bulk/routes.d.ts +1 -0
- package/dist/src/api/bulk/routes.js +252 -0
- package/dist/src/api/data-removals/routes.d.ts +1 -0
- package/dist/src/api/data-removals/routes.js +59 -0
- package/dist/src/api/email/json.d.ts +11 -0
- package/dist/src/api/email/json.js +33 -0
- package/dist/src/api/email/routes.d.ts +1 -0
- package/dist/src/api/email/routes.js +64 -0
- package/dist/src/api/inbound/routes.d.ts +1 -0
- package/dist/src/api/inbound/routes.js +40 -0
- package/dist/src/api/index.d.ts +1 -0
- package/dist/src/api/index.js +3 -0
- package/dist/src/api/message-streams/routes.d.ts +1 -0
- package/dist/src/api/message-streams/routes.js +211 -0
- package/dist/src/api/message-streams/streams.d.ts +28 -0
- package/dist/src/api/message-streams/streams.js +50 -0
- package/dist/src/api/messages/json.d.ts +149 -0
- package/dist/src/api/messages/json.js +114 -0
- package/dist/src/api/messages/query.d.ts +19 -0
- package/dist/src/api/messages/query.js +64 -0
- package/dist/src/api/messages/routes.d.ts +1 -0
- package/dist/src/api/messages/routes.js +203 -0
- package/dist/src/api/server/json.d.ts +26 -0
- package/dist/src/api/server/json.js +25 -0
- package/dist/src/api/server/routes.d.ts +1 -0
- package/dist/src/api/server/routes.js +17 -0
- package/dist/src/api/stats/aggregate.d.ts +58 -0
- package/dist/src/api/stats/aggregate.js +66 -0
- package/dist/src/api/stats/routes.d.ts +1 -0
- package/dist/src/api/stats/routes.js +72 -0
- package/dist/src/api/suppressions/routes.d.ts +1 -0
- package/dist/src/api/suppressions/routes.js +98 -0
- package/dist/src/api/templates/content.d.ts +21 -0
- package/dist/src/api/templates/content.js +39 -0
- package/dist/src/api/templates/routes.d.ts +1 -0
- package/dist/src/api/templates/routes.js +164 -0
- package/dist/src/api/templates/send.d.ts +13 -0
- package/dist/src/api/templates/send.js +105 -0
- package/dist/src/api/templates/templates.d.ts +100 -0
- package/dist/src/api/templates/templates.js +218 -0
- package/dist/src/api/templates/validate.d.ts +15 -0
- package/dist/src/api/templates/validate.js +77 -0
- package/dist/src/api/triggers/routes.d.ts +1 -0
- package/dist/src/api/triggers/routes.js +62 -0
- package/dist/src/api/webhooks/routes.d.ts +14 -0
- package/dist/src/api/webhooks/routes.js +192 -0
- package/dist/src/config.d.ts +17 -0
- package/dist/src/config.js +95 -0
- package/dist/src/control/app.d.ts +5 -0
- package/dist/src/control/app.js +42 -0
- package/dist/src/control/endpoints/account.d.ts +1 -0
- package/dist/src/control/endpoints/account.js +68 -0
- package/dist/src/control/endpoints/bulk.d.ts +1 -0
- package/dist/src/control/endpoints/bulk.js +29 -0
- package/dist/src/control/endpoints/core.d.ts +1 -0
- package/dist/src/control/endpoints/core.js +104 -0
- package/dist/src/control/endpoints/inbound.d.ts +1 -0
- package/dist/src/control/endpoints/inbound.js +61 -0
- package/dist/src/control/endpoints/recipients.d.ts +1 -0
- package/dist/src/control/endpoints/recipients.js +136 -0
- package/dist/src/control/endpoints/smtp.d.ts +1 -0
- package/dist/src/control/endpoints/smtp.js +74 -0
- package/dist/src/control/endpoints/tracking.d.ts +1 -0
- package/dist/src/control/endpoints/tracking.js +95 -0
- package/dist/src/control/endpoints/webhooks.d.ts +1 -0
- package/dist/src/control/endpoints/webhooks.js +36 -0
- package/dist/src/control/index.d.ts +1 -0
- package/dist/src/control/index.js +3 -0
- package/dist/src/control/registry.d.ts +25 -0
- package/dist/src/control/registry.js +19 -0
- package/dist/src/control/seed.d.ts +11 -0
- package/dist/src/control/seed.js +32 -0
- package/dist/src/control/seeding.d.ts +10 -0
- package/dist/src/control/seeding.js +27 -0
- package/dist/src/discover.d.ts +16 -0
- package/dist/src/discover.js +49 -0
- package/dist/src/errors.d.ts +49 -0
- package/dist/src/errors.js +701 -0
- package/dist/src/events.d.ts +49 -0
- package/dist/src/events.js +19 -0
- package/dist/src/http/app.d.ts +8 -0
- package/dist/src/http/app.js +51 -0
- package/dist/src/http/auth.d.ts +7 -0
- package/dist/src/http/auth.js +32 -0
- package/dist/src/http/faults.d.ts +8 -0
- package/dist/src/http/faults.js +33 -0
- package/dist/src/http/normalize.d.ts +57 -0
- package/dist/src/http/normalize.js +225 -0
- package/dist/src/http/respond.d.ts +23 -0
- package/dist/src/http/respond.js +37 -0
- package/dist/src/http/routes.d.ts +60 -0
- package/dist/src/http/routes.js +64 -0
- package/dist/src/inbound/deliver.d.ts +9 -0
- package/dist/src/inbound/deliver.js +34 -0
- package/dist/src/inbound/parse.d.ts +21 -0
- package/dist/src/inbound/parse.js +71 -0
- package/dist/src/inbound/receive.d.ts +17 -0
- package/dist/src/inbound/receive.js +89 -0
- package/dist/src/main.d.ts +2 -0
- package/dist/src/main.js +14 -0
- package/dist/src/mime/compose.d.ts +33 -0
- package/dist/src/mime/compose.js +58 -0
- package/dist/src/pipeline/addresses.d.ts +6 -0
- package/dist/src/pipeline/addresses.js +38 -0
- package/dist/src/pipeline/inactive.d.ts +8 -0
- package/dist/src/pipeline/inactive.js +20 -0
- package/dist/src/pipeline/submit.d.ts +138 -0
- package/dist/src/pipeline/submit.js +415 -0
- package/dist/src/plugins/message-events.d.ts +7 -0
- package/dist/src/plugins/message-events.js +76 -0
- package/dist/src/plugins/smtp.d.ts +15 -0
- package/dist/src/plugins/smtp.js +42 -0
- package/dist/src/plugins/stats.d.ts +7 -0
- package/dist/src/plugins/stats.js +78 -0
- package/dist/src/plugins/webhooks.d.ts +4 -0
- package/dist/src/plugins/webhooks.js +80 -0
- package/dist/src/plugins.d.ts +20 -0
- package/dist/src/plugins.js +9 -0
- package/dist/src/recipients/test-bounces.d.ts +15 -0
- package/dist/src/recipients/test-bounces.js +31 -0
- package/dist/src/recipients/transitions.d.ts +57 -0
- package/dist/src/recipients/transitions.js +279 -0
- package/dist/src/render/mustachio.d.ts +60 -0
- package/dist/src/render/mustachio.js +265 -0
- package/dist/src/runtime.d.ts +12 -0
- package/dist/src/runtime.js +11 -0
- package/dist/src/server.d.ts +25 -0
- package/dist/src/server.js +49 -0
- package/dist/src/smtp/auth.d.ts +35 -0
- package/dist/src/smtp/auth.js +66 -0
- package/dist/src/smtp/listener.d.ts +16 -0
- package/dist/src/smtp/listener.js +121 -0
- package/dist/src/smtp/mime.d.ts +36 -0
- package/dist/src/smtp/mime.js +181 -0
- package/dist/src/smtp/receive.d.ts +21 -0
- package/dist/src/smtp/receive.js +89 -0
- package/dist/src/smtp/reply.d.ts +14 -0
- package/dist/src/smtp/reply.js +24 -0
- package/dist/src/state/clock.d.ts +35 -0
- package/dist/src/state/clock.js +107 -0
- package/dist/src/state/ids.d.ts +6 -0
- package/dist/src/state/ids.js +7 -0
- package/dist/src/state/servers.d.ts +27 -0
- package/dist/src/state/servers.js +101 -0
- package/dist/src/state/store.d.ts +57 -0
- package/dist/src/state/store.js +98 -0
- package/dist/src/state/suppressions.d.ts +9 -0
- package/dist/src/state/suppressions.js +8 -0
- package/dist/src/state/types.d.ts +530 -0
- package/dist/src/state/types.js +41 -0
- package/dist/src/time.d.ts +11 -0
- package/dist/src/time.js +48 -0
- package/dist/src/tracking.d.ts +53 -0
- package/dist/src/tracking.js +150 -0
- package/dist/src/webhooks/deliver.d.ts +60 -0
- package/dist/src/webhooks/deliver.js +172 -0
- package/dist/src/webhooks/egress.d.ts +19 -0
- package/dist/src/webhooks/egress.js +40 -0
- package/dist/src/webhooks/outbound.d.ts +26 -0
- package/dist/src/webhooks/outbound.js +47 -0
- package/dist/src/webhooks/payloads.d.ts +111 -0
- package/dist/src/webhooks/payloads.js +128 -0
- package/package.json +55 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Account, Bounce, BulkRequest, ClickEvent, DataRemoval, Domain, Fault, InboundMessage, InboundRule, MessageStream, OpenEvent, OutboundMessage, SenderSignature, Server, SmtpFault, SmtpToken, StatsFact, Suppression, Template, Webhook, WebhookAttempt } from "./types.ts";
|
|
2
|
+
export type IdKind = "server" | "bounce" | "template" | "webhook" | "webhookAttempt" | "inboundRule" | "domain" | "sender" | "dataRemoval";
|
|
3
|
+
export interface State {
|
|
4
|
+
account: Account;
|
|
5
|
+
servers: Map<number, Server>;
|
|
6
|
+
/** Key: `streamKey(serverId, streamId)`. */
|
|
7
|
+
streams: Map<string, MessageStream>;
|
|
8
|
+
/**
|
|
9
|
+
* `streamKey`s of archived streams deleted at their purge date. Unarchive answers 1232 for them;
|
|
10
|
+
* a new stream with the same ID removes the key (docs/04 §4.3).
|
|
11
|
+
*/
|
|
12
|
+
purgedStreams: Set<string>;
|
|
13
|
+
/** Key: MessageID. */
|
|
14
|
+
outbound: Map<string, OutboundMessage>;
|
|
15
|
+
/** Key: MessageID. */
|
|
16
|
+
inbound: Map<string, InboundMessage>;
|
|
17
|
+
bounces: Map<number, Bounce>;
|
|
18
|
+
/** Key: `suppressionKey(serverId, streamId, email)`. */
|
|
19
|
+
suppressions: Map<string, Suppression>;
|
|
20
|
+
opens: OpenEvent[];
|
|
21
|
+
clicks: ClickEvent[];
|
|
22
|
+
/** Stats API facts, in event order. */
|
|
23
|
+
stats: StatsFact[];
|
|
24
|
+
templates: Map<number, Template>;
|
|
25
|
+
bulkRequests: Map<string, BulkRequest>;
|
|
26
|
+
webhooks: Map<number, Webhook>;
|
|
27
|
+
webhookAttempts: WebhookAttempt[];
|
|
28
|
+
inboundRules: Map<number, InboundRule>;
|
|
29
|
+
domains: Map<number, Domain>;
|
|
30
|
+
senders: Map<number, SenderSignature>;
|
|
31
|
+
dataRemovals: Map<number, DataRemoval>;
|
|
32
|
+
/** Key: access key. */
|
|
33
|
+
smtpTokens: Map<string, SmtpToken>;
|
|
34
|
+
faults: Fault[];
|
|
35
|
+
smtpFaults: SmtpFault[];
|
|
36
|
+
usedIds: Record<IdKind, Set<number>>;
|
|
37
|
+
/** Highest used ID per kind. */
|
|
38
|
+
maxIds: Record<IdKind, number>;
|
|
39
|
+
}
|
|
40
|
+
/** The whole in-memory account. `reset()` swaps in an empty state; hold the Store, not the state. */
|
|
41
|
+
export declare class Store {
|
|
42
|
+
state: State;
|
|
43
|
+
private seedDepth;
|
|
44
|
+
reset(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Runs a seed. Inside it `nextId` throws: a seed part claims fixed IDs from its track's range
|
|
47
|
+
* (docs/11 §5), so its IDs do not depend on the parts other tracks add.
|
|
48
|
+
*/
|
|
49
|
+
seeding<T>(apply: () => Promise<T>): Promise<T>;
|
|
50
|
+
/** The next ID of a kind, above every ID used so far (docs/04 Mock must: bounce IDs increase). */
|
|
51
|
+
nextId(kind: IdKind): number;
|
|
52
|
+
/** Claims a fixed ID. */
|
|
53
|
+
useId(kind: IdKind, id: number): number;
|
|
54
|
+
private claim;
|
|
55
|
+
}
|
|
56
|
+
export declare const streamKey: (serverId: number, streamId: string) => string;
|
|
57
|
+
export declare const suppressionKey: (serverId: number, streamId: string, email: string) => string;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
function emptyState() {
|
|
2
|
+
return {
|
|
3
|
+
account: {
|
|
4
|
+
tokens: [],
|
|
5
|
+
approval: "approved",
|
|
6
|
+
bulkApiEnabled: true,
|
|
7
|
+
dataRemovalsEnabled: true,
|
|
8
|
+
messageStreamsApiEnabled: true,
|
|
9
|
+
customUnsubscribeEnabled: false,
|
|
10
|
+
serverDeletionEnabled: false,
|
|
11
|
+
},
|
|
12
|
+
servers: new Map(),
|
|
13
|
+
streams: new Map(),
|
|
14
|
+
purgedStreams: new Set(),
|
|
15
|
+
outbound: new Map(),
|
|
16
|
+
inbound: new Map(),
|
|
17
|
+
bounces: new Map(),
|
|
18
|
+
suppressions: new Map(),
|
|
19
|
+
opens: [],
|
|
20
|
+
clicks: [],
|
|
21
|
+
stats: [],
|
|
22
|
+
templates: new Map(),
|
|
23
|
+
bulkRequests: new Map(),
|
|
24
|
+
webhooks: new Map(),
|
|
25
|
+
webhookAttempts: [],
|
|
26
|
+
inboundRules: new Map(),
|
|
27
|
+
domains: new Map(),
|
|
28
|
+
senders: new Map(),
|
|
29
|
+
dataRemovals: new Map(),
|
|
30
|
+
smtpTokens: new Map(),
|
|
31
|
+
faults: [],
|
|
32
|
+
smtpFaults: [],
|
|
33
|
+
usedIds: {
|
|
34
|
+
server: new Set(),
|
|
35
|
+
bounce: new Set(),
|
|
36
|
+
template: new Set(),
|
|
37
|
+
webhook: new Set(),
|
|
38
|
+
webhookAttempt: new Set(),
|
|
39
|
+
inboundRule: new Set(),
|
|
40
|
+
domain: new Set(),
|
|
41
|
+
sender: new Set(),
|
|
42
|
+
dataRemoval: new Set(),
|
|
43
|
+
},
|
|
44
|
+
maxIds: {
|
|
45
|
+
server: 0,
|
|
46
|
+
bounce: 0,
|
|
47
|
+
template: 0,
|
|
48
|
+
webhook: 0,
|
|
49
|
+
webhookAttempt: 0,
|
|
50
|
+
inboundRule: 0,
|
|
51
|
+
domain: 0,
|
|
52
|
+
sender: 0,
|
|
53
|
+
dataRemoval: 0,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** The whole in-memory account. `reset()` swaps in an empty state; hold the Store, not the state. */
|
|
58
|
+
export class Store {
|
|
59
|
+
state = emptyState();
|
|
60
|
+
seedDepth = 0;
|
|
61
|
+
reset() {
|
|
62
|
+
this.state = emptyState();
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Runs a seed. Inside it `nextId` throws: a seed part claims fixed IDs from its track's range
|
|
66
|
+
* (docs/11 §5), so its IDs do not depend on the parts other tracks add.
|
|
67
|
+
*/
|
|
68
|
+
async seeding(apply) {
|
|
69
|
+
this.seedDepth += 1;
|
|
70
|
+
try {
|
|
71
|
+
return await apply();
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
this.seedDepth -= 1;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** The next ID of a kind, above every ID used so far (docs/04 Mock must: bounce IDs increase). */
|
|
78
|
+
nextId(kind) {
|
|
79
|
+
if (this.seedDepth > 0)
|
|
80
|
+
throw new Error(`${kind} needs a fixed ID while seeding (store.useId)`);
|
|
81
|
+
return this.claim(kind, this.state.maxIds[kind] + 1);
|
|
82
|
+
}
|
|
83
|
+
/** Claims a fixed ID. */
|
|
84
|
+
useId(kind, id) {
|
|
85
|
+
if (!Number.isInteger(id) || id < 1 || this.state.usedIds[kind].has(id)) {
|
|
86
|
+
throw new Error(`${kind} ID ${id} is taken or invalid`);
|
|
87
|
+
}
|
|
88
|
+
return this.claim(kind, id);
|
|
89
|
+
}
|
|
90
|
+
claim(kind, id) {
|
|
91
|
+
this.state.usedIds[kind].add(id);
|
|
92
|
+
this.state.maxIds[kind] = Math.max(this.state.maxIds[kind], id);
|
|
93
|
+
return id;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export const streamKey = (serverId, streamId) => `${serverId}/${streamId}`;
|
|
97
|
+
// Addresses compare without case (docs/04 Mock must, INFERRED).
|
|
98
|
+
export const suppressionKey = (serverId, streamId, email) => `${serverId}/${streamId}/${email.toLowerCase()}`;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type State } from "./store.ts";
|
|
2
|
+
import type { Suppression } from "./types.ts";
|
|
3
|
+
/** The suppression row of an address on one stream; addresses compare without case. */
|
|
4
|
+
export declare const findSuppression: (state: State, serverId: number, streamId: string, email: string) => Suppression | undefined;
|
|
5
|
+
/**
|
|
6
|
+
* The addresses of `emails` that a send on the stream must refuse with ErrorCode 406, in input
|
|
7
|
+
* order. Only the send stream's list counts (docs/04 §3.3; Q3).
|
|
8
|
+
*/
|
|
9
|
+
export declare const suppressedAddresses: (state: State, serverId: number, streamId: string, emails: readonly string[]) => string[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { suppressionKey } from "./store.js";
|
|
2
|
+
/** The suppression row of an address on one stream; addresses compare without case. */
|
|
3
|
+
export const findSuppression = (state, serverId, streamId, email) => state.suppressions.get(suppressionKey(serverId, streamId, email));
|
|
4
|
+
/**
|
|
5
|
+
* The addresses of `emails` that a send on the stream must refuse with ErrorCode 406, in input
|
|
6
|
+
* order. Only the send stream's list counts (docs/04 §3.3; Q3).
|
|
7
|
+
*/
|
|
8
|
+
export const suppressedAddresses = (state, serverId, streamId, emails) => emails.filter((email) => findSuppression(state, serverId, streamId, email) !== undefined);
|
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
export type TrackLinks = "None" | "HtmlAndText" | "HtmlOnly" | "TextOnly";
|
|
2
|
+
export declare const SERVER_COLORS: readonly ["purple", "blue", "turquoise", "green", "red", "yellow", "grey", "orange"];
|
|
3
|
+
export type ServerColor = (typeof SERVER_COLORS)[number];
|
|
4
|
+
export interface Header {
|
|
5
|
+
Name: string;
|
|
6
|
+
Value: string;
|
|
7
|
+
}
|
|
8
|
+
/** A parsed address. `Name` is null for a bare address (docs/06 §1.5). */
|
|
9
|
+
export interface Address {
|
|
10
|
+
Email: string;
|
|
11
|
+
Name: string | null;
|
|
12
|
+
}
|
|
13
|
+
export interface Attachment {
|
|
14
|
+
Name: string;
|
|
15
|
+
/** Base64. */
|
|
16
|
+
Content: string;
|
|
17
|
+
ContentType: string;
|
|
18
|
+
ContentID: string | null;
|
|
19
|
+
/** Decoded byte count. */
|
|
20
|
+
ContentLength: number;
|
|
21
|
+
}
|
|
22
|
+
export interface Account {
|
|
23
|
+
tokens: string[];
|
|
24
|
+
/** 412 pending, 413 unapproved (docs/02 §4.4). */
|
|
25
|
+
approval: "approved" | "pending" | "unapproved";
|
|
26
|
+
/** Bulk API access; ErrorCode 14 when false (docs/03 §1.6). */
|
|
27
|
+
bulkApiEnabled: boolean;
|
|
28
|
+
/** Data removals access; ErrorCode 1302 when false (docs/04 §5). */
|
|
29
|
+
dataRemovalsEnabled: boolean;
|
|
30
|
+
/** Message streams API access; ErrorCode 1220 when false (docs/04 §4.4). */
|
|
31
|
+
messageStreamsApiEnabled: boolean;
|
|
32
|
+
/** Custom unsubscribe handling; ErrorCode 1238 when false (docs/04 §4.4). */
|
|
33
|
+
customUnsubscribeEnabled: boolean;
|
|
34
|
+
/** Server deletion through the API; ErrorCode 604 when false (refs/api_servers-api.md:483). */
|
|
35
|
+
serverDeletionEnabled: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface Server {
|
|
38
|
+
ID: number;
|
|
39
|
+
Name: string;
|
|
40
|
+
ApiTokens: string[];
|
|
41
|
+
Color: ServerColor;
|
|
42
|
+
SmtpApiActivated: boolean;
|
|
43
|
+
RawEmailEnabled: boolean;
|
|
44
|
+
DeliveryType: "Live" | "Sandbox";
|
|
45
|
+
ServerLink: string;
|
|
46
|
+
InboundAddress: string;
|
|
47
|
+
InboundHookUrl: string;
|
|
48
|
+
BounceHookUrl: string;
|
|
49
|
+
OpenHookUrl: string;
|
|
50
|
+
DeliveryHookUrl: string;
|
|
51
|
+
ClickHookUrl: string;
|
|
52
|
+
PostFirstOpenOnly: boolean;
|
|
53
|
+
InboundDomain: string;
|
|
54
|
+
InboundHash: string;
|
|
55
|
+
InboundSpamThreshold: number;
|
|
56
|
+
TrackOpens: boolean;
|
|
57
|
+
TrackLinks: TrackLinks;
|
|
58
|
+
IncludeBounceContentInHook: boolean;
|
|
59
|
+
EnableSmtpApiErrorHooks: boolean;
|
|
60
|
+
}
|
|
61
|
+
export type MessageStreamType = "Transactional" | "Broadcasts" | "Inbound";
|
|
62
|
+
export type UnsubscribeHandlingType = "None" | "Postmark" | "Custom";
|
|
63
|
+
export interface MessageStream {
|
|
64
|
+
ID: string;
|
|
65
|
+
ServerID: number;
|
|
66
|
+
Name: string;
|
|
67
|
+
Description: string | null;
|
|
68
|
+
MessageStreamType: MessageStreamType;
|
|
69
|
+
CreatedAt: Date;
|
|
70
|
+
UpdatedAt: Date | null;
|
|
71
|
+
ArchivedAt: Date | null;
|
|
72
|
+
ExpectedPurgeDate: Date | null;
|
|
73
|
+
SubscriptionManagementConfiguration: {
|
|
74
|
+
UnsubscribeHandlingType: UnsubscribeHandlingType;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export type OutboundStatus = "Queued" | "Sent" | "Processed";
|
|
78
|
+
export type MessageEventType = "Delivered" | "Transient" | "Opened" | "LinkClicked" | "Bounced" | "SubscriptionChanged";
|
|
79
|
+
export interface MessageEvent {
|
|
80
|
+
Recipient: string;
|
|
81
|
+
Type: MessageEventType;
|
|
82
|
+
ReceivedAt: Date;
|
|
83
|
+
Details: Record<string, string>;
|
|
84
|
+
}
|
|
85
|
+
export interface OutboundMessage {
|
|
86
|
+
MessageID: string;
|
|
87
|
+
ServerID: number;
|
|
88
|
+
MessageStream: string;
|
|
89
|
+
From: string;
|
|
90
|
+
To: Address[];
|
|
91
|
+
Cc: Address[];
|
|
92
|
+
Bcc: Address[];
|
|
93
|
+
ReplyTo: string | null;
|
|
94
|
+
Subject: string | null;
|
|
95
|
+
HtmlBody: string | null;
|
|
96
|
+
TextBody: string | null;
|
|
97
|
+
Tag: string | null;
|
|
98
|
+
Headers: Header[];
|
|
99
|
+
Attachments: Attachment[];
|
|
100
|
+
Metadata: Record<string, string>;
|
|
101
|
+
TrackOpens: boolean;
|
|
102
|
+
TrackLinks: TrackLinks;
|
|
103
|
+
Status: OutboundStatus;
|
|
104
|
+
Sandboxed: boolean;
|
|
105
|
+
/** `SubmittedAt` on the send response; `ReceivedAt` on the Messages API. */
|
|
106
|
+
ReceivedAt: Date;
|
|
107
|
+
MessageEvents: MessageEvent[];
|
|
108
|
+
channel: "rest" | "smtp";
|
|
109
|
+
/** The request JSON (REST) or raw MIME (SMTP), for `GET /control/messages` (docs/09 §5). */
|
|
110
|
+
request: unknown;
|
|
111
|
+
/** The generated MIME source served by the dump endpoint (docs/06 §1.2). */
|
|
112
|
+
rawSource: string;
|
|
113
|
+
bulkRequestId: string | null;
|
|
114
|
+
templateId: number | null;
|
|
115
|
+
/** Recipients on the stream's suppression list at send time; Postmark skips them (docs/04 §3.3). */
|
|
116
|
+
suppressedRecipients: string[];
|
|
117
|
+
}
|
|
118
|
+
export type InboundStatus = "Blocked" | "Processed" | "Queued" | "Failed" | "Scheduled" | "Sent";
|
|
119
|
+
export interface InboundAddress {
|
|
120
|
+
Email: string;
|
|
121
|
+
Name: string;
|
|
122
|
+
MailboxHash: string;
|
|
123
|
+
}
|
|
124
|
+
export interface InboundAttachment {
|
|
125
|
+
Name: string;
|
|
126
|
+
Content: string;
|
|
127
|
+
ContentType: string;
|
|
128
|
+
ContentLength: number;
|
|
129
|
+
ContentID: string;
|
|
130
|
+
}
|
|
131
|
+
export interface InboundMessage {
|
|
132
|
+
MessageID: string;
|
|
133
|
+
ServerID: number;
|
|
134
|
+
MessageStream: string;
|
|
135
|
+
From: string;
|
|
136
|
+
FromName: string;
|
|
137
|
+
FromFull: InboundAddress;
|
|
138
|
+
To: string;
|
|
139
|
+
ToFull: InboundAddress[];
|
|
140
|
+
Cc: string;
|
|
141
|
+
CcFull: InboundAddress[];
|
|
142
|
+
Bcc: string;
|
|
143
|
+
BccFull: InboundAddress[];
|
|
144
|
+
OriginalRecipient: string;
|
|
145
|
+
ReplyTo: string;
|
|
146
|
+
Subject: string;
|
|
147
|
+
MailboxHash: string;
|
|
148
|
+
/** Sender RFC 2822 `Date` header, as received. */
|
|
149
|
+
Date: string;
|
|
150
|
+
TextBody: string;
|
|
151
|
+
HtmlBody: string;
|
|
152
|
+
StrippedTextReply: string;
|
|
153
|
+
Tag: string;
|
|
154
|
+
Headers: Header[];
|
|
155
|
+
Attachments: InboundAttachment[];
|
|
156
|
+
Status: InboundStatus;
|
|
157
|
+
BlockedReason: string | null;
|
|
158
|
+
ReceivedAt: Date;
|
|
159
|
+
rawEmail: string;
|
|
160
|
+
}
|
|
161
|
+
export declare const BOUNCE_TYPES: {
|
|
162
|
+
readonly HardBounce: {
|
|
163
|
+
readonly TypeCode: 1;
|
|
164
|
+
readonly Name: "Hard bounce";
|
|
165
|
+
};
|
|
166
|
+
readonly Transient: {
|
|
167
|
+
readonly TypeCode: 2;
|
|
168
|
+
readonly Name: "Message delayed/Undeliverable";
|
|
169
|
+
};
|
|
170
|
+
readonly Unsubscribe: {
|
|
171
|
+
readonly TypeCode: 16;
|
|
172
|
+
readonly Name: "Unsubscribe request";
|
|
173
|
+
};
|
|
174
|
+
readonly Subscribe: {
|
|
175
|
+
readonly TypeCode: 32;
|
|
176
|
+
readonly Name: "Subscribe request";
|
|
177
|
+
};
|
|
178
|
+
readonly AutoResponder: {
|
|
179
|
+
readonly TypeCode: 64;
|
|
180
|
+
readonly Name: "Auto responder";
|
|
181
|
+
};
|
|
182
|
+
readonly AddressChange: {
|
|
183
|
+
readonly TypeCode: 128;
|
|
184
|
+
readonly Name: "Address change";
|
|
185
|
+
};
|
|
186
|
+
readonly DnsError: {
|
|
187
|
+
readonly TypeCode: 256;
|
|
188
|
+
readonly Name: "DNS error";
|
|
189
|
+
};
|
|
190
|
+
readonly SpamNotification: {
|
|
191
|
+
readonly TypeCode: 512;
|
|
192
|
+
readonly Name: "Spam notification";
|
|
193
|
+
};
|
|
194
|
+
readonly OpenRelayTest: {
|
|
195
|
+
readonly TypeCode: 1024;
|
|
196
|
+
readonly Name: "Open relay test";
|
|
197
|
+
};
|
|
198
|
+
readonly Unknown: {
|
|
199
|
+
readonly TypeCode: 2048;
|
|
200
|
+
readonly Name: "Unknown";
|
|
201
|
+
};
|
|
202
|
+
readonly SoftBounce: {
|
|
203
|
+
readonly TypeCode: 4096;
|
|
204
|
+
readonly Name: "Soft bounce";
|
|
205
|
+
};
|
|
206
|
+
readonly VirusNotification: {
|
|
207
|
+
readonly TypeCode: 8192;
|
|
208
|
+
readonly Name: "Virus notification";
|
|
209
|
+
};
|
|
210
|
+
readonly ChallengeVerification: {
|
|
211
|
+
readonly TypeCode: 16384;
|
|
212
|
+
readonly Name: "Spam challenge verification";
|
|
213
|
+
};
|
|
214
|
+
readonly BadEmailAddress: {
|
|
215
|
+
readonly TypeCode: 100000;
|
|
216
|
+
readonly Name: "Invalid email address";
|
|
217
|
+
};
|
|
218
|
+
readonly SpamComplaint: {
|
|
219
|
+
readonly TypeCode: 100001;
|
|
220
|
+
readonly Name: "Spam complaint";
|
|
221
|
+
};
|
|
222
|
+
readonly ManuallyDeactivated: {
|
|
223
|
+
readonly TypeCode: 100002;
|
|
224
|
+
readonly Name: "Manually deactivated";
|
|
225
|
+
};
|
|
226
|
+
readonly Unconfirmed: {
|
|
227
|
+
readonly TypeCode: 100003;
|
|
228
|
+
readonly Name: "Registration not confirmed";
|
|
229
|
+
};
|
|
230
|
+
readonly Blocked: {
|
|
231
|
+
readonly TypeCode: 100006;
|
|
232
|
+
readonly Name: "ISP block";
|
|
233
|
+
};
|
|
234
|
+
readonly SMTPApiError: {
|
|
235
|
+
readonly TypeCode: 100007;
|
|
236
|
+
readonly Name: "SMTP API error";
|
|
237
|
+
};
|
|
238
|
+
readonly InboundError: {
|
|
239
|
+
readonly TypeCode: 100008;
|
|
240
|
+
readonly Name: "Processing failed";
|
|
241
|
+
};
|
|
242
|
+
readonly DMARCPolicy: {
|
|
243
|
+
readonly TypeCode: 100009;
|
|
244
|
+
readonly Name: "DMARC Policy";
|
|
245
|
+
};
|
|
246
|
+
readonly TemplateRenderingFailed: {
|
|
247
|
+
readonly TypeCode: 100010;
|
|
248
|
+
readonly Name: "Template rendering failed";
|
|
249
|
+
};
|
|
250
|
+
};
|
|
251
|
+
export type BounceType = keyof typeof BOUNCE_TYPES;
|
|
252
|
+
export interface Bounce {
|
|
253
|
+
ID: number;
|
|
254
|
+
ServerID: number;
|
|
255
|
+
MessageStream: string;
|
|
256
|
+
MessageID: string;
|
|
257
|
+
Type: BounceType;
|
|
258
|
+
Tag: string | null;
|
|
259
|
+
Description: string;
|
|
260
|
+
Details: string;
|
|
261
|
+
Email: string;
|
|
262
|
+
From: string | null;
|
|
263
|
+
Subject: string;
|
|
264
|
+
BouncedAt: Date;
|
|
265
|
+
Inactive: boolean;
|
|
266
|
+
CanActivate: boolean;
|
|
267
|
+
/** Raw dump; `DumpAvailable` is false once it is empty or older than 30 days. */
|
|
268
|
+
Content: string;
|
|
269
|
+
Metadata: Record<string, string>;
|
|
270
|
+
}
|
|
271
|
+
export type SuppressionReason = "HardBounce" | "SpamComplaint" | "ManualSuppression";
|
|
272
|
+
export type SuppressionOrigin = "Recipient" | "Customer" | "Admin";
|
|
273
|
+
export interface Suppression {
|
|
274
|
+
ServerID: number;
|
|
275
|
+
MessageStream: string;
|
|
276
|
+
EmailAddress: string;
|
|
277
|
+
SuppressionReason: SuppressionReason;
|
|
278
|
+
Origin: SuppressionOrigin;
|
|
279
|
+
CreatedAt: Date;
|
|
280
|
+
}
|
|
281
|
+
export interface SubscriptionChange {
|
|
282
|
+
MessageID: string | null;
|
|
283
|
+
ServerID: number;
|
|
284
|
+
MessageStream: string;
|
|
285
|
+
ChangedAt: Date;
|
|
286
|
+
Recipient: string;
|
|
287
|
+
Origin: SuppressionOrigin;
|
|
288
|
+
SuppressSending: boolean;
|
|
289
|
+
SuppressionReason: SuppressionReason | null;
|
|
290
|
+
Tag: string | null;
|
|
291
|
+
Metadata: Record<string, string>;
|
|
292
|
+
}
|
|
293
|
+
export interface ClientInfo {
|
|
294
|
+
Name: string;
|
|
295
|
+
Company: string;
|
|
296
|
+
Family: string;
|
|
297
|
+
}
|
|
298
|
+
export interface Geo {
|
|
299
|
+
CountryISOCode?: string;
|
|
300
|
+
Country?: string;
|
|
301
|
+
RegionISOCode?: string;
|
|
302
|
+
Region?: string;
|
|
303
|
+
City?: string;
|
|
304
|
+
Zip?: string;
|
|
305
|
+
Coords?: string;
|
|
306
|
+
IP?: string;
|
|
307
|
+
}
|
|
308
|
+
export interface OpenEvent {
|
|
309
|
+
ServerID: number;
|
|
310
|
+
MessageID: string;
|
|
311
|
+
MessageStream: string;
|
|
312
|
+
Recipient: string;
|
|
313
|
+
Tag: string | null;
|
|
314
|
+
Metadata: Record<string, string>;
|
|
315
|
+
ReceivedAt: Date;
|
|
316
|
+
FirstOpen: boolean;
|
|
317
|
+
UserAgent: string;
|
|
318
|
+
ReadSeconds: number;
|
|
319
|
+
Client: ClientInfo | null;
|
|
320
|
+
OS: ClientInfo | null;
|
|
321
|
+
Platform: "WebMail" | "Desktop" | "Mobile" | "Unknown" | null;
|
|
322
|
+
Geo: Geo | null;
|
|
323
|
+
}
|
|
324
|
+
export interface ClickEvent {
|
|
325
|
+
ServerID: number;
|
|
326
|
+
MessageID: string;
|
|
327
|
+
MessageStream: string;
|
|
328
|
+
Recipient: string;
|
|
329
|
+
Tag: string | null;
|
|
330
|
+
Metadata: Record<string, string>;
|
|
331
|
+
ReceivedAt: Date;
|
|
332
|
+
UserAgent: string;
|
|
333
|
+
ClickLocation: "HTML" | "Text";
|
|
334
|
+
OriginalLink: string;
|
|
335
|
+
Client: ClientInfo | null;
|
|
336
|
+
OS: ClientInfo | null;
|
|
337
|
+
Platform: "WebMail" | "Desktop" | "Mobile" | "Unknown" | null;
|
|
338
|
+
Geo: Geo | null;
|
|
339
|
+
}
|
|
340
|
+
export type StatsFact = {
|
|
341
|
+
ServerID: number;
|
|
342
|
+
MessageStream: string;
|
|
343
|
+
Tag: string | null;
|
|
344
|
+
at: Date;
|
|
345
|
+
} & ({
|
|
346
|
+
kind: "sent";
|
|
347
|
+
openTracking: boolean;
|
|
348
|
+
linkTracking: boolean;
|
|
349
|
+
trackedLinks: number;
|
|
350
|
+
} | {
|
|
351
|
+
kind: "bounce";
|
|
352
|
+
type: "HardBounce" | "SoftBounce" | "Transient" | "SMTPApiError";
|
|
353
|
+
} | {
|
|
354
|
+
kind: "spamComplaint";
|
|
355
|
+
} | {
|
|
356
|
+
kind: "open";
|
|
357
|
+
MessageID: string;
|
|
358
|
+
Recipient: string;
|
|
359
|
+
/** The recipient's first open of the message ever. */
|
|
360
|
+
first: boolean;
|
|
361
|
+
platform: OpenEvent["Platform"];
|
|
362
|
+
client: string | null;
|
|
363
|
+
readSeconds: number;
|
|
364
|
+
} | {
|
|
365
|
+
kind: "click";
|
|
366
|
+
MessageID: string;
|
|
367
|
+
Recipient: string;
|
|
368
|
+
/** The recipient's first click on this link of the message ever. */
|
|
369
|
+
first: boolean;
|
|
370
|
+
link: string;
|
|
371
|
+
location: ClickEvent["ClickLocation"];
|
|
372
|
+
platform: ClickEvent["Platform"];
|
|
373
|
+
browser: string | null;
|
|
374
|
+
});
|
|
375
|
+
export interface Template {
|
|
376
|
+
TemplateId: number;
|
|
377
|
+
ServerID: number;
|
|
378
|
+
Name: string;
|
|
379
|
+
Alias: string;
|
|
380
|
+
Subject: string | null;
|
|
381
|
+
HtmlBody: string | null;
|
|
382
|
+
TextBody: string | null;
|
|
383
|
+
TemplateType: "Standard" | "Layout";
|
|
384
|
+
LayoutTemplate: string | null;
|
|
385
|
+
Active: boolean;
|
|
386
|
+
}
|
|
387
|
+
export interface BulkRequest {
|
|
388
|
+
Id: string;
|
|
389
|
+
ServerID: number;
|
|
390
|
+
SubmittedAt: Date;
|
|
391
|
+
Status: "Accepted" | "Processing" | "Completed" | "Cancelled";
|
|
392
|
+
TotalMessages: number;
|
|
393
|
+
PercentageCompleted: number;
|
|
394
|
+
ReleasedCount: number;
|
|
395
|
+
FailedCount: number;
|
|
396
|
+
Subject: string | null;
|
|
397
|
+
messageIds: string[];
|
|
398
|
+
/** Why processing stopped on behavior postmock does not know (`Unsupported`), or null. */
|
|
399
|
+
unsupported: string | null;
|
|
400
|
+
}
|
|
401
|
+
export interface WebhookTriggers {
|
|
402
|
+
Open: {
|
|
403
|
+
Enabled: boolean;
|
|
404
|
+
PostFirstOpenOnly: boolean;
|
|
405
|
+
};
|
|
406
|
+
Click: {
|
|
407
|
+
Enabled: boolean;
|
|
408
|
+
};
|
|
409
|
+
Delivery: {
|
|
410
|
+
Enabled: boolean;
|
|
411
|
+
};
|
|
412
|
+
Bounce: {
|
|
413
|
+
Enabled: boolean;
|
|
414
|
+
IncludeContent: boolean;
|
|
415
|
+
};
|
|
416
|
+
SpamComplaint: {
|
|
417
|
+
Enabled: boolean;
|
|
418
|
+
IncludeContent: boolean;
|
|
419
|
+
};
|
|
420
|
+
SubscriptionChange: {
|
|
421
|
+
Enabled: boolean;
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
export interface Webhook {
|
|
425
|
+
ID: number;
|
|
426
|
+
ServerID: number;
|
|
427
|
+
Url: string;
|
|
428
|
+
MessageStream: string;
|
|
429
|
+
Status: "verified" | "unverified";
|
|
430
|
+
HttpAuth: {
|
|
431
|
+
Username: string;
|
|
432
|
+
Password: string;
|
|
433
|
+
} | null;
|
|
434
|
+
HttpHeaders: Header[];
|
|
435
|
+
Triggers: WebhookTriggers;
|
|
436
|
+
}
|
|
437
|
+
export type WebhookRecordType = "Bounce" | "SpamComplaint" | "Delivery" | "Open" | "Click" | "SubscriptionChange" | "Inbound";
|
|
438
|
+
export interface WebhookAttempt {
|
|
439
|
+
id: number;
|
|
440
|
+
serverId: number;
|
|
441
|
+
/** The `/webhooks` row; null for a server hook URL (`BounceHookUrl`, `InboundHookUrl`, …). */
|
|
442
|
+
webhookId: number | null;
|
|
443
|
+
recordType: WebhookRecordType;
|
|
444
|
+
/** The URL as configured, userinfo included. */
|
|
445
|
+
url: string;
|
|
446
|
+
traceId: string;
|
|
447
|
+
/** Request headers as sent, the `Authorization` header included. */
|
|
448
|
+
headers: Header[];
|
|
449
|
+
/** The JSON body, the same bytes on every attempt of one event. */
|
|
450
|
+
body: string;
|
|
451
|
+
/** 1 for the first attempt. */
|
|
452
|
+
attempt: number;
|
|
453
|
+
at: Date;
|
|
454
|
+
outcome: {
|
|
455
|
+
status: number;
|
|
456
|
+
} | {
|
|
457
|
+
error: string;
|
|
458
|
+
};
|
|
459
|
+
/** What the outcome causes (docs/05 §3.4, §3.6). */
|
|
460
|
+
result: "success" | "retry" | "stop" | "exhausted";
|
|
461
|
+
nextAttemptAt: Date | null;
|
|
462
|
+
}
|
|
463
|
+
export interface InboundRule {
|
|
464
|
+
ID: number;
|
|
465
|
+
ServerID: number;
|
|
466
|
+
Rule: string;
|
|
467
|
+
}
|
|
468
|
+
export interface Domain {
|
|
469
|
+
ID: number;
|
|
470
|
+
Name: string;
|
|
471
|
+
SPFVerified: boolean;
|
|
472
|
+
SPFHost: string;
|
|
473
|
+
SPFTextValue: string;
|
|
474
|
+
DKIMVerified: boolean;
|
|
475
|
+
WeakDKIM: boolean;
|
|
476
|
+
DKIMHost: string;
|
|
477
|
+
DKIMTextValue: string;
|
|
478
|
+
DKIMPendingHost: string;
|
|
479
|
+
DKIMPendingTextValue: string;
|
|
480
|
+
DKIMRevokedHost: string;
|
|
481
|
+
DKIMRevokedTextValue: string;
|
|
482
|
+
SafeToRemoveRevokedKeyFromDNS: boolean;
|
|
483
|
+
DKIMUpdateStatus: "Pending" | "Verified";
|
|
484
|
+
ReturnPathDomain: string;
|
|
485
|
+
ReturnPathDomainVerified: boolean;
|
|
486
|
+
ReturnPathDomainCNAMEValue: string;
|
|
487
|
+
}
|
|
488
|
+
export interface SenderSignature extends Omit<Domain, "Name"> {
|
|
489
|
+
Domain: string;
|
|
490
|
+
EmailAddress: string;
|
|
491
|
+
ReplyToEmailAddress: string;
|
|
492
|
+
Name: string;
|
|
493
|
+
Confirmed: boolean;
|
|
494
|
+
ConfirmationPersonalNote: string;
|
|
495
|
+
}
|
|
496
|
+
export interface DataRemoval {
|
|
497
|
+
ID: number;
|
|
498
|
+
RequestedBy: string;
|
|
499
|
+
RequestedFor: string;
|
|
500
|
+
NotifyWhenCompleted: boolean;
|
|
501
|
+
Status: "Pending" | "Done";
|
|
502
|
+
createdAt: Date;
|
|
503
|
+
}
|
|
504
|
+
export interface SmtpToken {
|
|
505
|
+
accessKey: string;
|
|
506
|
+
secretKey: string;
|
|
507
|
+
serverId: number;
|
|
508
|
+
messageStream: string;
|
|
509
|
+
}
|
|
510
|
+
export interface SmtpFault {
|
|
511
|
+
stage: "connect" | "mail" | "rcpt" | "data";
|
|
512
|
+
remaining: number;
|
|
513
|
+
code: number;
|
|
514
|
+
message: string;
|
|
515
|
+
}
|
|
516
|
+
/** An error reply is built with `apiError`, so its status and code pair exists in docs/02 §4.4. */
|
|
517
|
+
export type FaultReply = {
|
|
518
|
+
status: number;
|
|
519
|
+
body: {
|
|
520
|
+
ErrorCode: number;
|
|
521
|
+
Message: string;
|
|
522
|
+
};
|
|
523
|
+
} | "timeout" | "reset";
|
|
524
|
+
export interface Fault {
|
|
525
|
+
method: string;
|
|
526
|
+
/** A route pattern, matched like an API route (`/email`, `/templates/:id`). */
|
|
527
|
+
path: string;
|
|
528
|
+
remaining: number;
|
|
529
|
+
reply: FaultReply;
|
|
530
|
+
}
|