@ewyn/client 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.
- package/README.md +267 -0
- package/dist/__tests__/config-types.test-d.d.ts +10 -0
- package/dist/__tests__/config-types.test-d.d.ts.map +1 -0
- package/dist/__tests__/config-types.test-d.js +96 -0
- package/dist/__tests__/dashboard-config.test.d.ts +10 -0
- package/dist/__tests__/dashboard-config.test.d.ts.map +1 -0
- package/dist/__tests__/dashboard-config.test.js +182 -0
- package/dist/__tests__/errors.test.d.ts +2 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.js +90 -0
- package/dist/__tests__/mailer.test.d.ts +2 -0
- package/dist/__tests__/mailer.test.d.ts.map +1 -0
- package/dist/__tests__/mailer.test.js +429 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +34 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +211 -0
- package/dist/types.d.ts +129 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +46 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { MailerApiError } from './errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Mailer SDK Client
|
|
4
|
+
*
|
|
5
|
+
* @example Basic usage without template config
|
|
6
|
+
* ```ts
|
|
7
|
+
* const client = new Mailer({
|
|
8
|
+
* workspaceId: 'your-workspace-id',
|
|
9
|
+
* apiKey: 'your-api-key',
|
|
10
|
+
* });
|
|
11
|
+
*
|
|
12
|
+
* await client.send({
|
|
13
|
+
* to: 'user@example.com',
|
|
14
|
+
* templateId: 'version-uuid',
|
|
15
|
+
* variables: { firstName: 'John' }
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example Type-safe usage with template config
|
|
20
|
+
* ```ts
|
|
21
|
+
* const config = {
|
|
22
|
+
* welcome: {
|
|
23
|
+
* id: 'version-uuid',
|
|
24
|
+
* name: 'Welcome Email',
|
|
25
|
+
* version: 1,
|
|
26
|
+
* vars: {
|
|
27
|
+
* firstName: { required: true },
|
|
28
|
+
* plan: { required: false }
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* } as const;
|
|
32
|
+
*
|
|
33
|
+
* const client = new Mailer({
|
|
34
|
+
* workspaceId: 'your-workspace-id',
|
|
35
|
+
* apiKey: 'your-api-key',
|
|
36
|
+
* templates: config
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* // Type-safe sending
|
|
40
|
+
* await client.send({
|
|
41
|
+
* to: 'user@example.com',
|
|
42
|
+
* template: 'welcome', // Autocomplete available
|
|
43
|
+
* variables: {
|
|
44
|
+
* firstName: 'John' // TypeScript enforces required vars
|
|
45
|
+
* }
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export class Mailer {
|
|
50
|
+
workspaceId;
|
|
51
|
+
apiKey;
|
|
52
|
+
baseUrl;
|
|
53
|
+
templates;
|
|
54
|
+
maxRetries;
|
|
55
|
+
timeout;
|
|
56
|
+
constructor(options) {
|
|
57
|
+
this.workspaceId = options.workspaceId;
|
|
58
|
+
this.apiKey = options.apiKey;
|
|
59
|
+
this.baseUrl = options.baseUrl || 'https://www.ewyn.ai/api/v1';
|
|
60
|
+
this.templates = options.templates;
|
|
61
|
+
this.maxRetries = options.maxRetries ?? 3;
|
|
62
|
+
this.timeout = options.timeout ?? 30000;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Send an email using a template
|
|
66
|
+
*
|
|
67
|
+
* @param options - Email sending options
|
|
68
|
+
* @returns Promise resolving to the send response
|
|
69
|
+
* @throws {MailerApiError} If the API request fails
|
|
70
|
+
*
|
|
71
|
+
* @example With template ID
|
|
72
|
+
* ```ts
|
|
73
|
+
* await client.send({
|
|
74
|
+
* to: 'user@example.com',
|
|
75
|
+
* templateId: 'version-uuid',
|
|
76
|
+
* variables: { firstName: 'John' }
|
|
77
|
+
* });
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @example With template name (requires config)
|
|
81
|
+
* ```ts
|
|
82
|
+
* await client.send({
|
|
83
|
+
* to: 'user@example.com',
|
|
84
|
+
* template: 'welcome',
|
|
85
|
+
* version: 2, // Optional: defaults to latest
|
|
86
|
+
* variables: { firstName: 'John' }
|
|
87
|
+
* });
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
async send(options) {
|
|
91
|
+
// Validate and resolve template
|
|
92
|
+
const templateId = await this.resolveTemplateId(options);
|
|
93
|
+
// Validate variables if template config is provided
|
|
94
|
+
if (this.templates && options.template) {
|
|
95
|
+
this.validateVariables(options.template, options.variables || {});
|
|
96
|
+
}
|
|
97
|
+
// Build request body
|
|
98
|
+
const body = {
|
|
99
|
+
to: options.to,
|
|
100
|
+
templateId,
|
|
101
|
+
};
|
|
102
|
+
if (options.variables) {
|
|
103
|
+
body.variables = options.variables;
|
|
104
|
+
}
|
|
105
|
+
if (options.metadata) {
|
|
106
|
+
body.metadata = options.metadata;
|
|
107
|
+
}
|
|
108
|
+
if (options.idempotencyKey) {
|
|
109
|
+
body.idempotencyKey = options.idempotencyKey;
|
|
110
|
+
}
|
|
111
|
+
// Add version if specified
|
|
112
|
+
if ('version' in options && options.version !== undefined) {
|
|
113
|
+
body.version = options.version;
|
|
114
|
+
}
|
|
115
|
+
// Make request with retries
|
|
116
|
+
return this.requestWithRetry(`/workspaces/${this.workspaceId}/send`, {
|
|
117
|
+
method: 'POST',
|
|
118
|
+
headers: {
|
|
119
|
+
'Content-Type': 'application/json',
|
|
120
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
121
|
+
},
|
|
122
|
+
body: JSON.stringify(body),
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Resolve template ID from either templateId or template name
|
|
127
|
+
*/
|
|
128
|
+
async resolveTemplateId(options) {
|
|
129
|
+
if (options.templateId) {
|
|
130
|
+
return options.templateId;
|
|
131
|
+
}
|
|
132
|
+
if (options.template) {
|
|
133
|
+
if (!this.templates) {
|
|
134
|
+
throw new Error('Template name provided but no template config was provided to the client');
|
|
135
|
+
}
|
|
136
|
+
const template = this.templates[options.template];
|
|
137
|
+
if (!template) {
|
|
138
|
+
throw new Error(`Template "${options.template}" not found in template config`);
|
|
139
|
+
}
|
|
140
|
+
return template.id;
|
|
141
|
+
}
|
|
142
|
+
throw new Error('Either templateId or template must be provided');
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Validate that all required variables are provided
|
|
146
|
+
*/
|
|
147
|
+
validateVariables(templateName, variables) {
|
|
148
|
+
if (!this.templates) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const template = this.templates[templateName];
|
|
152
|
+
if (!template) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const missing = [];
|
|
156
|
+
for (const [varName, varDef] of Object.entries(template.vars)) {
|
|
157
|
+
if (varDef?.required && !(varName in variables)) {
|
|
158
|
+
missing.push(varName);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (missing.length > 0) {
|
|
162
|
+
throw new Error(`Missing required variables for template "${templateName}": ${missing.join(', ')}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Make HTTP request with retry logic
|
|
167
|
+
*/
|
|
168
|
+
async requestWithRetry(path, init, attempt = 1) {
|
|
169
|
+
const url = `${this.baseUrl}${path}`;
|
|
170
|
+
const controller = new AbortController();
|
|
171
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
172
|
+
try {
|
|
173
|
+
const response = await fetch(url, {
|
|
174
|
+
...init,
|
|
175
|
+
signal: controller.signal,
|
|
176
|
+
});
|
|
177
|
+
clearTimeout(timeoutId);
|
|
178
|
+
const data = await response.json().catch(() => ({}));
|
|
179
|
+
if (!response.ok) {
|
|
180
|
+
const error = new MailerApiError(response.status, data.code, data.details || data, data.error || data.message);
|
|
181
|
+
// Retry on retryable errors
|
|
182
|
+
if (error.isRetryable() && attempt < this.maxRetries) {
|
|
183
|
+
// Exponential backoff: 1s, 2s, 4s
|
|
184
|
+
const delay = Math.pow(2, attempt - 1) * 1000;
|
|
185
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
186
|
+
return this.requestWithRetry(path, init, attempt + 1);
|
|
187
|
+
}
|
|
188
|
+
throw error;
|
|
189
|
+
}
|
|
190
|
+
return data;
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
clearTimeout(timeoutId);
|
|
194
|
+
if (error instanceof MailerApiError) {
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
// Handle network errors or timeouts
|
|
198
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
199
|
+
throw new MailerApiError(408, 'TIMEOUT', undefined, `Request timed out after ${this.timeout}ms`);
|
|
200
|
+
}
|
|
201
|
+
// Retry on network errors if we have attempts left
|
|
202
|
+
if (attempt < this.maxRetries) {
|
|
203
|
+
const delay = Math.pow(2, attempt - 1) * 1000;
|
|
204
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
205
|
+
return this.requestWithRetry(path, init, attempt + 1);
|
|
206
|
+
}
|
|
207
|
+
throw new MailerApiError(500, 'NETWORK_ERROR', undefined, error instanceof Error ? error.message : 'Unknown network error');
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
export { MailerApiError } from './errors.js';
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template variable definition
|
|
3
|
+
*/
|
|
4
|
+
export interface TemplateVariable {
|
|
5
|
+
required: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Template configuration entry
|
|
9
|
+
*/
|
|
10
|
+
export interface TemplateConfigEntry {
|
|
11
|
+
/** Template version ID (UUID) - used for sending */
|
|
12
|
+
id: string;
|
|
13
|
+
/** Human-readable template name */
|
|
14
|
+
name: string;
|
|
15
|
+
/** Major version number */
|
|
16
|
+
version: number;
|
|
17
|
+
/** Variable definitions */
|
|
18
|
+
vars: Record<string, TemplateVariable>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Template configuration object
|
|
22
|
+
* Maps template names to their configuration
|
|
23
|
+
*/
|
|
24
|
+
export type TemplateConfig = Record<string, TemplateConfigEntry>;
|
|
25
|
+
/**
|
|
26
|
+
* Extract required variable names from a template config entry
|
|
27
|
+
*/
|
|
28
|
+
type RequiredVars<T extends TemplateConfigEntry> = {
|
|
29
|
+
[K in keyof T['vars']]: T['vars'][K] extends {
|
|
30
|
+
required: true;
|
|
31
|
+
} ? K : never;
|
|
32
|
+
}[keyof T['vars']];
|
|
33
|
+
/**
|
|
34
|
+
* Extract optional variable names from a template config entry
|
|
35
|
+
*/
|
|
36
|
+
type OptionalVars<T extends TemplateConfigEntry> = {
|
|
37
|
+
[K in keyof T['vars']]: T['vars'][K] extends {
|
|
38
|
+
required: false;
|
|
39
|
+
} ? K : never;
|
|
40
|
+
}[keyof T['vars']];
|
|
41
|
+
/**
|
|
42
|
+
* Build a variables object type from template config
|
|
43
|
+
*/
|
|
44
|
+
type VariablesFromConfig<T extends TemplateConfigEntry> = RequiredVars<T> extends never ? {
|
|
45
|
+
[K in OptionalVars<T>]?: string;
|
|
46
|
+
} : {
|
|
47
|
+
[K in RequiredVars<T>]: string;
|
|
48
|
+
} & {
|
|
49
|
+
[K in OptionalVars<T>]?: string;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Options for sending an email without template config
|
|
53
|
+
*/
|
|
54
|
+
export interface SendEmailOptionsBase {
|
|
55
|
+
/** Recipient email address */
|
|
56
|
+
to: string;
|
|
57
|
+
/** Template version ID (UUID) - required if template not provided */
|
|
58
|
+
templateId?: string;
|
|
59
|
+
/** Template name (requires template config to be provided) */
|
|
60
|
+
template?: string;
|
|
61
|
+
/** Major version number (use with template name) */
|
|
62
|
+
version?: number;
|
|
63
|
+
/** Variables to substitute in the template */
|
|
64
|
+
variables?: Record<string, string>;
|
|
65
|
+
/** Additional metadata to attach to the message */
|
|
66
|
+
metadata?: Record<string, unknown>;
|
|
67
|
+
/** Idempotency key to prevent duplicate sends */
|
|
68
|
+
idempotencyKey?: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Type-safe options when using template config
|
|
72
|
+
*/
|
|
73
|
+
export type SendEmailOptionsTyped<TConfig extends TemplateConfig, TName extends keyof TConfig = keyof TConfig> = {
|
|
74
|
+
/** Recipient email address */
|
|
75
|
+
to: string;
|
|
76
|
+
/** Template name from config */
|
|
77
|
+
template: TName;
|
|
78
|
+
/** Major version number (optional, defaults to latest) */
|
|
79
|
+
version?: TConfig[TName]['version'];
|
|
80
|
+
/** Type-safe variables based on template config */
|
|
81
|
+
variables: VariablesFromConfig<TConfig[TName]>;
|
|
82
|
+
/** Additional metadata to attach to the message */
|
|
83
|
+
metadata?: Record<string, unknown>;
|
|
84
|
+
/** Idempotency key to prevent duplicate sends */
|
|
85
|
+
idempotencyKey?: string;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Options for sending an email (generic version)
|
|
89
|
+
*/
|
|
90
|
+
export type SendEmailOptions = SendEmailOptionsBase;
|
|
91
|
+
/**
|
|
92
|
+
* Response from sending an email
|
|
93
|
+
*/
|
|
94
|
+
export interface SendEmailResponse {
|
|
95
|
+
messageId: string;
|
|
96
|
+
status: 'queued';
|
|
97
|
+
queuedAt: string;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Configuration options for the Mailer client (base)
|
|
101
|
+
*/
|
|
102
|
+
export interface MailerOptionsBase {
|
|
103
|
+
/** Workspace ID (UUID) */
|
|
104
|
+
workspaceId: string;
|
|
105
|
+
/** API key secret */
|
|
106
|
+
apiKey: string;
|
|
107
|
+
/** Base URL for the API (defaults to production) */
|
|
108
|
+
baseUrl?: string;
|
|
109
|
+
/** Maximum number of retries for retryable errors (default: 3) */
|
|
110
|
+
maxRetries?: number;
|
|
111
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
112
|
+
timeout?: number;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Configuration options with typed template config
|
|
116
|
+
*/
|
|
117
|
+
export type MailerOptionsTyped<TConfig extends TemplateConfig> = MailerOptionsBase & {
|
|
118
|
+
/** Template configuration for type-safe sending */
|
|
119
|
+
templates: TConfig;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Configuration options for the Mailer client (generic version)
|
|
123
|
+
*/
|
|
124
|
+
export type MailerOptions = MailerOptionsBase & {
|
|
125
|
+
/** Template configuration for name-based sending and validation */
|
|
126
|
+
templates?: TemplateConfig;
|
|
127
|
+
};
|
|
128
|
+
export {};
|
|
129
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ewyn/client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official TypeScript SDK for Ewyn email service with full type safety",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"dev": "tsc --watch",
|
|
20
|
+
"lint": "eslint . --max-warnings 0",
|
|
21
|
+
"test": "vitest run --typecheck",
|
|
22
|
+
"test:watch": "vitest"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"ewyn",
|
|
26
|
+
"email",
|
|
27
|
+
"sdk"
|
|
28
|
+
],
|
|
29
|
+
"author": "",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"prepublishOnly": "pnpm build",
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18.0.0"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^20.11.0",
|
|
41
|
+
"@workspace/eslint-config": "workspace:*",
|
|
42
|
+
"@workspace/typescript-config": "workspace:*",
|
|
43
|
+
"typescript": "^5.7.3",
|
|
44
|
+
"vitest": "^1.2.0"
|
|
45
|
+
}
|
|
46
|
+
}
|