@agentisend/sdk-node 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +97 -0
  2. package/dist/cli/args.d.ts +24 -0
  3. package/dist/cli/args.js +71 -0
  4. package/dist/cli/args.js.map +1 -0
  5. package/dist/cli/commands.d.ts +29 -0
  6. package/dist/cli/commands.js +147 -0
  7. package/dist/cli/commands.js.map +1 -0
  8. package/dist/cli/config.d.ts +31 -0
  9. package/dist/cli/config.js +73 -0
  10. package/dist/cli/config.js.map +1 -0
  11. package/dist/cli/doctor.d.ts +36 -0
  12. package/dist/cli/doctor.js +161 -0
  13. package/dist/cli/doctor.js.map +1 -0
  14. package/dist/cli/listen.d.ts +28 -0
  15. package/dist/cli/listen.js +140 -0
  16. package/dist/cli/listen.js.map +1 -0
  17. package/dist/cli/main.d.ts +14 -0
  18. package/dist/cli/main.js +369 -0
  19. package/dist/cli/main.js.map +1 -0
  20. package/dist/cli/output.d.ts +40 -0
  21. package/dist/cli/output.js +35 -0
  22. package/dist/cli/output.js.map +1 -0
  23. package/dist/cli/scheduled-at.d.ts +19 -0
  24. package/dist/cli/scheduled-at.js +108 -0
  25. package/dist/cli/scheduled-at.js.map +1 -0
  26. package/dist/cli.d.ts +2 -0
  27. package/dist/cli.js +17 -0
  28. package/dist/cli.js.map +1 -0
  29. package/dist/client.d.ts +426 -0
  30. package/dist/client.js +542 -0
  31. package/dist/client.js.map +1 -0
  32. package/dist/compat-resend.d.ts +194 -0
  33. package/dist/compat-resend.js +233 -0
  34. package/dist/compat-resend.js.map +1 -0
  35. package/dist/errors.d.ts +82 -0
  36. package/dist/errors.js +92 -0
  37. package/dist/errors.js.map +1 -0
  38. package/dist/index.d.ts +10 -0
  39. package/dist/index.js +9 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/types.d.ts +499 -0
  42. package/dist/types.js +9 -0
  43. package/dist/types.js.map +1 -0
  44. package/dist/version.d.ts +8 -0
  45. package/dist/version.js +9 -0
  46. package/dist/version.js.map +1 -0
  47. package/dist/webhook-signing.d.ts +64 -0
  48. package/dist/webhook-signing.js +125 -0
  49. package/dist/webhook-signing.js.map +1 -0
  50. package/package.json +65 -0
@@ -0,0 +1,194 @@
1
+ /** Resend's send payload. Their `scheduledAt` maps to our native scheduling. */
2
+ export interface ResendSendPayload {
3
+ from: string;
4
+ to: string | string[];
5
+ subject: string;
6
+ html?: string;
7
+ text?: string;
8
+ cc?: string | string[];
9
+ bcc?: string | string[];
10
+ reply_to?: string | string[];
11
+ headers?: Record<string, string>;
12
+ tags?: {
13
+ name: string;
14
+ value: string;
15
+ }[];
16
+ attachments?: {
17
+ filename: string;
18
+ content: string;
19
+ }[];
20
+ scheduledAt?: string;
21
+ }
22
+ /** Resend returns `{data, error}` rather than throwing. So do we, here. */
23
+ export interface ResendErrorShape {
24
+ message: string;
25
+ name: string;
26
+ statusCode: number;
27
+ }
28
+ export type ResendResult<T> = {
29
+ data: T;
30
+ error: null;
31
+ } | {
32
+ data: null;
33
+ error: ResendErrorShape;
34
+ };
35
+ export type ResendEnvelope<T = Record<string, unknown>> = Promise<ResendResult<T>>;
36
+ export type ResendBatchItem = {
37
+ id: string;
38
+ } | {
39
+ id: null;
40
+ error: ResendErrorShape;
41
+ };
42
+ type Row = Record<string, unknown>;
43
+ /**
44
+ * Every method the Resend Node SDK exposes that AgentiSend answers, as data.
45
+ *
46
+ * `audiences` is absent on purpose: Resend marks it Deprecated in their own
47
+ * spec, and building a shim for a surface its author is removing would tie a
48
+ * migration to something with no future.
49
+ */
50
+ export declare const RESEND_SDK_SURFACE: Record<string, string[]>;
51
+ export declare class Resend {
52
+ private readonly client;
53
+ private readonly warn;
54
+ readonly emails: {
55
+ send: (payload: ResendSendPayload, options?: {
56
+ idempotencyKey?: string;
57
+ }) => ResendEnvelope<{
58
+ id: string;
59
+ }>;
60
+ get: (id: string) => ResendEnvelope;
61
+ list: (query?: Record<string, string | number>) => ResendEnvelope<Row[]>;
62
+ /** Resend's update IS a reschedule. Ours says so out loud. */
63
+ update: (id: string, payload: {
64
+ scheduledAt: string;
65
+ }) => ResendEnvelope;
66
+ cancel: (id: string) => ResendEnvelope;
67
+ batch: {
68
+ send: (payloads: ResendSendPayload[], options?: {
69
+ idempotencyKey?: string;
70
+ }) => ResendEnvelope<ResendBatchItem[]>;
71
+ };
72
+ };
73
+ readonly domains: {
74
+ create: (input: {
75
+ name: string;
76
+ region: string;
77
+ }) => ResendEnvelope;
78
+ list: () => ResendEnvelope<Row[]>;
79
+ get: (id: string) => ResendEnvelope;
80
+ update: (id: string, payload: Row) => ResendEnvelope;
81
+ verify: (id: string) => ResendEnvelope;
82
+ remove: (id: string) => ResendEnvelope;
83
+ };
84
+ readonly apiKeys: {
85
+ create: (input: {
86
+ name: string;
87
+ permission: 'full_access' | 'sending_access';
88
+ }) => ResendEnvelope;
89
+ list: () => ResendEnvelope<Row[]>;
90
+ update: (id: string, payload: Row) => ResendEnvelope;
91
+ remove: (id: string) => ResendEnvelope;
92
+ };
93
+ readonly contacts: {
94
+ create: (input: {
95
+ email: string;
96
+ properties?: Row;
97
+ }) => ResendEnvelope;
98
+ list: (query?: {
99
+ email?: string;
100
+ }) => ResendEnvelope<Row[]>;
101
+ get: (id: string) => ResendEnvelope;
102
+ update: (id: string, input: Row) => ResendEnvelope;
103
+ remove: (id: string) => ResendEnvelope;
104
+ };
105
+ readonly topics: {
106
+ create: (input: {
107
+ name: string;
108
+ description?: string;
109
+ }) => ResendEnvelope;
110
+ list: () => ResendEnvelope<Row[]>;
111
+ get: (id: string) => ResendEnvelope;
112
+ update: (id: string, input: Row) => ResendEnvelope;
113
+ remove: (id: string) => ResendEnvelope;
114
+ };
115
+ readonly segments: {
116
+ create: (input: {
117
+ name: string;
118
+ rules?: Row[];
119
+ }) => ResendEnvelope;
120
+ list: () => ResendEnvelope<Row[]>;
121
+ get: (id: string) => ResendEnvelope;
122
+ update: (id: string, input: Row) => ResendEnvelope;
123
+ remove: (id: string) => ResendEnvelope;
124
+ };
125
+ readonly broadcasts: {
126
+ create: (payload: Row) => ResendEnvelope;
127
+ list: () => ResendEnvelope<Row[]>;
128
+ get: (id: string) => ResendEnvelope;
129
+ update: (id: string, payload: Row) => ResendEnvelope;
130
+ send: (id: string) => ResendEnvelope;
131
+ /** Archive, not delete — and the shim says why. */
132
+ remove: (id: string) => ResendEnvelope;
133
+ };
134
+ readonly templates: {
135
+ create: (payload: {
136
+ name: string;
137
+ subject: string;
138
+ content: unknown;
139
+ variables?: unknown[];
140
+ }) => ResendEnvelope;
141
+ list: () => ResendEnvelope<Row[]>;
142
+ get: (id: string) => ResendEnvelope;
143
+ update: (id: string, payload: Row) => ResendEnvelope;
144
+ publish: (id: string) => ResendEnvelope;
145
+ render: (id: string, values?: Row) => ResendEnvelope<{
146
+ rendered: string;
147
+ }>;
148
+ duplicate: (id: string, name?: string) => ResendEnvelope;
149
+ };
150
+ readonly suppressions: {
151
+ create: (input: {
152
+ email: string;
153
+ level?: 'address' | 'domain';
154
+ }) => ResendEnvelope;
155
+ list: () => ResendEnvelope<Row[]>;
156
+ remove: (id: string) => ResendEnvelope;
157
+ batch: {
158
+ add: (emails: string[]) => ResendEnvelope<Row[]>;
159
+ remove: (emails: string[]) => ResendEnvelope<Row[]>;
160
+ };
161
+ };
162
+ readonly automations: {
163
+ create: (payload: {
164
+ name: string;
165
+ trigger: Row;
166
+ steps: Row[];
167
+ }) => ResendEnvelope;
168
+ list: () => ResendEnvelope<Row[]>;
169
+ get: (id: string) => ResendEnvelope;
170
+ update: (id: string, payload: Row) => ResendEnvelope;
171
+ enable: (id: string) => ResendEnvelope;
172
+ disable: (id: string) => ResendEnvelope;
173
+ };
174
+ readonly webhooks: {
175
+ create: (input: {
176
+ endpoint: string;
177
+ events: string[];
178
+ }) => ResendEnvelope;
179
+ list: () => ResendEnvelope<Row[]>;
180
+ get: (id: string) => ResendEnvelope;
181
+ update: (id: string, payload: Row) => ResendEnvelope;
182
+ remove: (id: string) => ResendEnvelope;
183
+ };
184
+ readonly events: {
185
+ send: (payload: {
186
+ name: string;
187
+ contact_id?: string;
188
+ data?: Row;
189
+ }) => ResendEnvelope;
190
+ };
191
+ constructor(apiKey?: string, baseUrl?: string);
192
+ private toSendBody;
193
+ }
194
+ export {};
@@ -0,0 +1,233 @@
1
+ /**
2
+ * agentisend/compat-resend — the from-Resend migration shim (ENGINEERING §6).
3
+ *
4
+ * A migration should be a find-replace on the import line. That is only true
5
+ * if EVERY method the old SDK had answers here: a shim covering nine of a
6
+ * caller's eleven calls does not save them a rewrite, it moves the rewrite to
7
+ * the two calls they discover in production.
8
+ *
9
+ * So the surface is a declared table (`RESEND_SDK_SURFACE`), the shim is built
10
+ * from it, and `sdk_compat_covers_every_resend_sdk_method` fails if the two
11
+ * ever disagree. Where AgentiSend is deliberately stricter, the shim WARNS
12
+ * rather than silently changing behaviour — a migration warning is a feature.
13
+ *
14
+ * Mapped against research/10 §A.1 (Resend OpenAPI, 113 operations, fetched
15
+ * 2026-09-04) and research/01.
16
+ */
17
+ /* eslint-disable no-console -- the shim's migration warnings are the feature */
18
+ import { AgentiSend } from './client.js';
19
+ import { AgentiSendError } from './errors.js';
20
+ /**
21
+ * Every method the Resend Node SDK exposes that AgentiSend answers, as data.
22
+ *
23
+ * `audiences` is absent on purpose: Resend marks it Deprecated in their own
24
+ * spec, and building a shim for a surface its author is removing would tie a
25
+ * migration to something with no future.
26
+ */
27
+ export const RESEND_SDK_SURFACE = {
28
+ emails: ['send', 'get', 'list', 'update', 'cancel'],
29
+ 'emails.batch': ['send'],
30
+ domains: ['create', 'list', 'get', 'update', 'verify', 'remove'],
31
+ apiKeys: ['create', 'list', 'update', 'remove'],
32
+ contacts: ['create', 'list', 'get', 'update', 'remove'],
33
+ topics: ['create', 'list', 'get', 'update', 'remove'],
34
+ segments: ['create', 'list', 'get', 'update', 'remove'],
35
+ broadcasts: ['create', 'list', 'get', 'update', 'send', 'remove'],
36
+ templates: ['create', 'list', 'get', 'update', 'publish', 'render', 'duplicate'],
37
+ suppressions: ['create', 'list', 'remove'],
38
+ 'suppressions.batch': ['add', 'remove'],
39
+ automations: ['create', 'list', 'get', 'update', 'enable', 'disable'],
40
+ webhooks: ['create', 'list', 'get', 'update', 'remove'],
41
+ events: ['send'],
42
+ };
43
+ export class Resend {
44
+ client;
45
+ warn;
46
+ emails;
47
+ domains;
48
+ apiKeys;
49
+ contacts;
50
+ topics;
51
+ segments;
52
+ broadcasts;
53
+ templates;
54
+ suppressions;
55
+ automations;
56
+ webhooks;
57
+ events;
58
+ constructor(apiKey, baseUrl) {
59
+ this.client = new AgentiSend(apiKey, baseUrl !== undefined ? { baseUrl } : {});
60
+ // A migration warning is a feature: it names exactly where AgentiSend is
61
+ // stricter than Resend instead of silently changing behaviour.
62
+ this.warn = (message) => console.warn(`[agentisend/compat-resend] ${message}`);
63
+ this.emails = {
64
+ send: async (payload, options) => asResend(async () => {
65
+ if (!payload.html && !payload.text) {
66
+ throw new Error('Provide html or text.');
67
+ }
68
+ const result = await this.client.emails.send(this.toSendBody(payload), options);
69
+ return { id: result.id };
70
+ }),
71
+ get: async (id) => asResend(async () => row(await this.client.emails.get(id))),
72
+ list: async (query = {}) => asResend(async () => rowsOf(await this.client.emails.list(query))),
73
+ update: async (id, payload) => {
74
+ // Their `update` only ever moved the schedule; ours is the same act
75
+ // under a name that says so.
76
+ return asResend(async () => row(await this.client.emails.reschedule(id, payload.scheduledAt)));
77
+ },
78
+ cancel: async (id) => asResend(async () => row(await this.client.emails.cancel(id))),
79
+ batch: {
80
+ send: async (payloads, options) => asResend(async () => {
81
+ const results = await this.client.emails.batch(payloads.map((p) => this.toSendBody(p)), options);
82
+ return results.data.map((item) => {
83
+ if (item.status === 'accepted' && item.id !== undefined)
84
+ return { id: item.id };
85
+ return {
86
+ id: null,
87
+ error: {
88
+ message: item.error?.message ?? 'This item was not accepted.',
89
+ name: item.error?.code ?? 'validation_error',
90
+ statusCode: 422,
91
+ },
92
+ };
93
+ });
94
+ }),
95
+ },
96
+ };
97
+ this.domains = {
98
+ create: async (input) => {
99
+ if (typeof input.region !== 'string' || input.region.length === 0) {
100
+ this.warn('Resend defaulted a domain region silently; AgentiSend requires an explicit region (F13). Pass region explicitly.');
101
+ }
102
+ return asResend(async () => row(await this.client.domains.create(input)));
103
+ },
104
+ list: async () => asResend(async () => rowsOf(await this.client.domains.list())),
105
+ get: async (id) => asResend(async () => row(await this.client.domains.get(id))),
106
+ update: async (id, payload) => asResend(async () => row(await this.client.domains.update(id, payload))),
107
+ verify: async (id) => asResend(async () => row(await this.client.domains.verify(id))),
108
+ remove: async (id) => asResend(async () => row(await this.client.domains.delete(id))),
109
+ };
110
+ this.apiKeys = {
111
+ create: async (input) => asResend(async () => row(await this.client.apiKeys.create({ name: input.name, permission: input.permission }))),
112
+ list: async () => asResend(async () => rowsOf(await this.client.apiKeys.list())),
113
+ update: async (id, payload) => asResend(async () => row(await this.client.apiKeys.update(id, payload))),
114
+ remove: async (id) => asResend(async () => row(await this.client.apiKeys.delete(id))),
115
+ };
116
+ this.contacts = {
117
+ create: async (input) => asResend(async () => row(await this.client.contacts.create(input))),
118
+ list: async (query = {}) => asResend(async () => rowsOf(await this.client.contacts.list(query))),
119
+ get: async (id) => asResend(async () => row(await this.client.contacts.get(id))),
120
+ update: async (id, input) => asResend(async () => row(await this.client.contacts.update(id, input))),
121
+ remove: async (id) => asResend(async () => row(await this.client.contacts.delete(id))),
122
+ };
123
+ this.topics = {
124
+ create: async (input) => asResend(async () => row(await this.client.topics.create(input))),
125
+ list: async () => asResend(async () => rowsOf(await this.client.topics.list())),
126
+ get: async (id) => asResend(async () => row(await this.client.topics.get(id))),
127
+ update: async (id, input) => asResend(async () => row(await this.client.topics.update(id, input))),
128
+ remove: async (id) => asResend(async () => row(await this.client.topics.delete(id))),
129
+ };
130
+ this.segments = {
131
+ create: async (input) => asResend(async () => row(await this.client.segments.create(input))),
132
+ list: async () => asResend(async () => rowsOf(await this.client.segments.list())),
133
+ get: async (id) => asResend(async () => row(await this.client.segments.get(id))),
134
+ update: async (id, input) => asResend(async () => row(await this.client.segments.update(id, input))),
135
+ remove: async (id) => asResend(async () => row(await this.client.segments.delete(id))),
136
+ };
137
+ this.broadcasts = {
138
+ create: async (payload) => asResend(async () => row(await this.client.broadcasts.create(payload))),
139
+ list: async () => asResend(async () => rowsOf(await this.client.broadcasts.list())),
140
+ get: async (id) => asResend(async () => row(await this.client.broadcasts.get(id))),
141
+ update: async (id, payload) => asResend(async () => row(await this.client.broadcasts.update(id, payload))),
142
+ send: async (id) => asResend(async () => row(await this.client.broadcasts.send(id))),
143
+ remove: async (id) => {
144
+ this.warn('Resend deletes a broadcast; AgentiSend archives it, so what was sent stays auditable (F14). This archived it.');
145
+ return asResend(async () => row(await this.client.broadcasts.archive(id)));
146
+ },
147
+ };
148
+ this.templates = {
149
+ create: async (payload) => asResend(async () => row(await this.client.templates.create(payload))),
150
+ list: async () => asResend(async () => rowsOf(await this.client.templates.list())),
151
+ get: async (id) => asResend(async () => row(await this.client.templates.get(id))),
152
+ update: async (id, payload) => asResend(async () => row(await this.client.templates.update(id, payload))),
153
+ publish: async (id) => asResend(async () => row(await this.client.templates.publish(id))),
154
+ render: async (id, values = {}) => asResend(async () => await this.client.templates.render(id, values)),
155
+ duplicate: async (id, name) => asResend(async () => row(await this.client.templates.duplicate(id, name !== undefined ? { name } : {}))),
156
+ };
157
+ this.suppressions = {
158
+ create: async (input) => asResend(async () => row(await this.client.suppressions.add(input))),
159
+ list: async () => asResend(async () => rowsOf(await this.client.suppressions.list())),
160
+ remove: async (id) => asResend(async () => row(await this.client.suppressions.remove(id))),
161
+ batch: {
162
+ add: async (emails) => asResend(async () => rowsOf(await this.client.suppressions.batchAdd(emails))),
163
+ remove: async (emails) => asResend(async () => rowsOf(await this.client.suppressions.batchRemove(emails))),
164
+ },
165
+ };
166
+ this.automations = {
167
+ create: async (payload) => asResend(async () => row(await this.client.automations.create(payload))),
168
+ list: async () => asResend(async () => rowsOf(await this.client.automations.list())),
169
+ get: async (id) => asResend(async () => row(await this.client.automations.get(id))),
170
+ update: async (id, payload) => asResend(async () => row(await this.client.automations.update(id, payload))),
171
+ enable: async (id) => asResend(async () => row(await this.client.automations.enable(id))),
172
+ disable: async (id) => asResend(async () => row(await this.client.automations.disable(id))),
173
+ };
174
+ this.webhooks = {
175
+ create: async (input) => asResend(async () => row(await this.client.webhooks.create({
176
+ url: input.endpoint,
177
+ events: input.events.includes('*') ? ['*'] : input.events,
178
+ }))),
179
+ list: async () => asResend(async () => rowsOf(await this.client.webhooks.list())),
180
+ get: async (id) => asResend(async () => row(await this.client.webhooks.get(id))),
181
+ update: async (id, payload) => asResend(async () => row(await this.client.webhooks.update(id, payload))),
182
+ remove: async (id) => asResend(async () => row(await this.client.webhooks.delete(id))),
183
+ };
184
+ this.events = {
185
+ send: async (payload) => asResend(async () => row(await this.client.events.ingest(payload))),
186
+ };
187
+ }
188
+ toSendBody(payload) {
189
+ return {
190
+ from: payload.from,
191
+ to: toArray(payload.to),
192
+ subject: payload.subject,
193
+ ...(payload.html !== undefined ? { html: payload.html } : {}),
194
+ ...(payload.text !== undefined ? { text: payload.text } : {}),
195
+ ...(payload.cc !== undefined ? { cc: toArray(payload.cc) } : {}),
196
+ ...(payload.bcc !== undefined ? { bcc: toArray(payload.bcc) } : {}),
197
+ ...(payload.reply_to !== undefined ? { reply_to: toArray(payload.reply_to) } : {}),
198
+ ...(payload.headers !== undefined ? { headers: payload.headers } : {}),
199
+ ...(payload.tags !== undefined
200
+ ? { tags: Object.fromEntries(payload.tags.map((t) => [t.name, t.value])) }
201
+ : {}),
202
+ ...(payload.attachments !== undefined ? { attachments: payload.attachments } : {}),
203
+ ...(payload.scheduledAt !== undefined ? { scheduled_at: payload.scheduledAt } : {}),
204
+ };
205
+ }
206
+ }
207
+ function toArray(value) {
208
+ return Array.isArray(value) ? value : [value];
209
+ }
210
+ function row(value) {
211
+ return value;
212
+ }
213
+ function rowsOf(result) {
214
+ return result.data;
215
+ }
216
+ function toResendError(caught) {
217
+ if (caught instanceof AgentiSendError) {
218
+ return { message: caught.message, name: caught.code, statusCode: caught.status };
219
+ }
220
+ if (caught instanceof Error) {
221
+ return { message: caught.message, name: 'application_error', statusCode: 500 };
222
+ }
223
+ return { message: String(caught), name: 'application_error', statusCode: 500 };
224
+ }
225
+ async function asResend(work) {
226
+ try {
227
+ return { data: await work(), error: null };
228
+ }
229
+ catch (caught) {
230
+ return { data: null, error: toResendError(caught) };
231
+ }
232
+ }
233
+ //# sourceMappingURL=compat-resend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compat-resend.js","sourceRoot":"","sources":["../src/compat-resend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Resend's error names, resolved onto our codes (M5.3).
3
+ *
4
+ * Kept here rather than imported from @agentisend/core because the published
5
+ * SDK has no runtime dependencies; the API's
6
+ * `migration_resend_error_names_resolve` test asserts this table equals the
7
+ * catalogue's, so the two cannot drift.
8
+ */
9
+ export declare const RESEND_ERROR_ALIASES: Record<string, string>;
10
+ export interface ValidationDetail {
11
+ path: string;
12
+ message: string;
13
+ }
14
+ export interface ErrorPayload {
15
+ code: string;
16
+ message: string;
17
+ fix: string;
18
+ docs_url: string;
19
+ details?: ValidationDetail[];
20
+ /** From the catalog. A 429 that waiting cannot cure is false. */
21
+ retryable?: boolean;
22
+ /** Present exactly when the catalog marks this code retryable. */
23
+ retry_after_seconds?: number;
24
+ }
25
+ /**
26
+ * What the `ratelimit-*` headers said at the moment of the failure. Every
27
+ * response carries them, so an error object can tell a caller not just to wait
28
+ * but how much room it has when it comes back (PRD F9, M5.1).
29
+ */
30
+ export interface RateLimitState {
31
+ /** Requests allowed in one 60-second window for this key. */
32
+ limit: number;
33
+ /** Requests left in the current window. */
34
+ remaining: number;
35
+ /** Seconds until the window resets. */
36
+ resetSeconds: number;
37
+ }
38
+ /**
39
+ * Every 4xx and 5xx the API returns arrives here with a `fix` — what to do and
40
+ * which endpoint does it. That is the point of the field: an integration can
41
+ * repair itself without a human reading prose.
42
+ *
43
+ * `retryAfterSeconds` is populated from the Retry-After header whenever the API
44
+ * sends one, and `rateLimit` from the `ratelimit-*` headers, so a caller never
45
+ * has to guess a backoff (PRD F9).
46
+ */
47
+ export declare class AgentiSendError extends Error {
48
+ readonly code: string;
49
+ readonly fix: string;
50
+ readonly docsUrl: string;
51
+ readonly status: number;
52
+ readonly details: ValidationDetail[] | undefined;
53
+ readonly retryAfterSeconds: number | undefined;
54
+ readonly requestId: string | undefined;
55
+ /** The `ratelimit-*` headers on the failing response, when the API sent them. */
56
+ readonly rateLimit: RateLimitState | undefined;
57
+ private readonly payloadRetryable;
58
+ constructor(payload: ErrorPayload, status: number, extras?: {
59
+ retryAfterSeconds?: number;
60
+ requestId?: string;
61
+ rateLimit?: RateLimitState;
62
+ });
63
+ /**
64
+ * True when retrying the identical request could plausibly succeed later.
65
+ * Reads the body (`retryable`) when the API sent it, so a 429 that waiting
66
+ * cannot cure (daily quota, trust throttle) is not retried.
67
+ */
68
+ get retryable(): boolean;
69
+ /**
70
+ * Does this error answer to `name`? Accepts our code or Resend's name for
71
+ * the same thing, so a migrating `if (err.name === 'invalid_idempotent_request')`
72
+ * keeps working while the code it lands on stays ours.
73
+ */
74
+ matches(name: string): boolean;
75
+ toString(): string;
76
+ }
77
+ /** A response that was not JSON, or not the envelope. Kept distinct from an API error. */
78
+ export declare class AgentiSendTransportError extends Error {
79
+ readonly status: number;
80
+ readonly body: string;
81
+ constructor(message: string, status: number, body: string);
82
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Resend's error names, resolved onto our codes (M5.3).
3
+ *
4
+ * Kept here rather than imported from @agentisend/core because the published
5
+ * SDK has no runtime dependencies; the API's
6
+ * `migration_resend_error_names_resolve` test asserts this table equals the
7
+ * catalogue's, so the two cannot drift.
8
+ */
9
+ export const RESEND_ERROR_ALIASES = {
10
+ missing_api_key: 'missing_api_key',
11
+ restricted_api_key: 'restricted_api_key',
12
+ invalid_api_key: 'invalid_api_key',
13
+ invalid_attachment: 'invalid_attachment',
14
+ invalid_from_address: 'invalid_from_address',
15
+ daily_quota_exceeded: 'daily_quota_exceeded',
16
+ method_not_allowed: 'method_not_allowed',
17
+ concurrent_idempotent_requests: 'idempotency_in_flight',
18
+ invalid_idempotent_request: 'idempotency_payload_mismatch',
19
+ validation_error: 'validation_error',
20
+ not_found: 'not_found',
21
+ rate_limit_exceeded: 'rate_limit_exceeded',
22
+ internal_server_error: 'internal_server_error',
23
+ };
24
+ /**
25
+ * Every 4xx and 5xx the API returns arrives here with a `fix` — what to do and
26
+ * which endpoint does it. That is the point of the field: an integration can
27
+ * repair itself without a human reading prose.
28
+ *
29
+ * `retryAfterSeconds` is populated from the Retry-After header whenever the API
30
+ * sends one, and `rateLimit` from the `ratelimit-*` headers, so a caller never
31
+ * has to guess a backoff (PRD F9).
32
+ */
33
+ export class AgentiSendError extends Error {
34
+ code;
35
+ fix;
36
+ docsUrl;
37
+ status;
38
+ details;
39
+ retryAfterSeconds;
40
+ requestId;
41
+ /** The `ratelimit-*` headers on the failing response, when the API sent them. */
42
+ rateLimit;
43
+ payloadRetryable;
44
+ constructor(payload, status, extras = {}) {
45
+ super(payload.message);
46
+ this.name = 'AgentiSendError';
47
+ this.code = payload.code;
48
+ this.fix = payload.fix;
49
+ this.docsUrl = payload.docs_url;
50
+ this.status = status;
51
+ this.details = payload.details;
52
+ this.payloadRetryable = typeof payload.retryable === 'boolean' ? payload.retryable : undefined;
53
+ this.retryAfterSeconds =
54
+ extras.retryAfterSeconds ??
55
+ (typeof payload.retry_after_seconds === 'number' ? payload.retry_after_seconds : undefined);
56
+ this.requestId = extras.requestId;
57
+ this.rateLimit = extras.rateLimit;
58
+ }
59
+ /**
60
+ * True when retrying the identical request could plausibly succeed later.
61
+ * Reads the body (`retryable`) when the API sent it, so a 429 that waiting
62
+ * cannot cure (daily quota, trust throttle) is not retried.
63
+ */
64
+ get retryable() {
65
+ if (this.payloadRetryable !== undefined)
66
+ return this.payloadRetryable;
67
+ return this.status === 429 || this.status >= 500;
68
+ }
69
+ /**
70
+ * Does this error answer to `name`? Accepts our code or Resend's name for
71
+ * the same thing, so a migrating `if (err.name === 'invalid_idempotent_request')`
72
+ * keeps working while the code it lands on stays ours.
73
+ */
74
+ matches(name) {
75
+ return name === this.code || RESEND_ERROR_ALIASES[name] === this.code;
76
+ }
77
+ toString() {
78
+ return `${this.name} [${this.code}]: ${this.message} — ${this.fix}`;
79
+ }
80
+ }
81
+ /** A response that was not JSON, or not the envelope. Kept distinct from an API error. */
82
+ export class AgentiSendTransportError extends Error {
83
+ status;
84
+ body;
85
+ constructor(message, status, body) {
86
+ super(message);
87
+ this.name = 'AgentiSendTransportError';
88
+ this.status = status;
89
+ this.body = body;
90
+ }
91
+ }
92
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export { AgentiSend, idempotencyKey, DEFAULT_BASE_URL, type ClientOptions, type RequestOptions, type FetchLike, type FetchResponse, } from './client.js';
2
+ export { AgentiSendError, AgentiSendTransportError, RESEND_ERROR_ALIASES, type ErrorPayload, type RateLimitState, type ValidationDetail, } from './errors.js';
3
+ export type * from './types.js';
4
+ export { SDK_VERSION } from './version.js';
5
+ export declare const PACKAGE_NAME = "@agentisend/sdk-node";
6
+ export declare function describeSdk(): {
7
+ name: string;
8
+ role: string;
9
+ };
10
+ export { Resend } from './compat-resend.js';
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ export { AgentiSend, idempotencyKey, DEFAULT_BASE_URL, } from './client.js';
2
+ export { AgentiSendError, AgentiSendTransportError, RESEND_ERROR_ALIASES, } from './errors.js';
3
+ export { SDK_VERSION } from './version.js';
4
+ export const PACKAGE_NAME = '@agentisend/sdk-node';
5
+ export function describeSdk() {
6
+ return { name: PACKAGE_NAME, role: 'typed Node client for the AgentiSend API' };
7
+ }
8
+ export { Resend } from './compat-resend.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,cAAc,EACd,gBAAgB,GAKjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,oBAAoB,GAIrB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,CAAC,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAEnD,MAAM,UAAU,WAAW;IACzB,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,0CAA0C,EAAE,CAAC;AAClF,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC"}