@ewyn/client 0.2.0 → 0.4.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 +51 -10
- package/dist/__tests__/cli-fetch-config.test.d.ts +2 -0
- package/dist/__tests__/cli-fetch-config.test.d.ts.map +1 -0
- package/dist/__tests__/cli-fetch-config.test.js +68 -0
- package/dist/__tests__/config-types.test-d.js +0 -6
- package/dist/__tests__/dashboard-config.test.js +1 -11
- package/dist/__tests__/errors.test.js +1 -1
- package/dist/__tests__/ewyn.test.js +1 -9
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +135 -0
- package/dist/index.d.ts +1 -50
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -8
- package/dist/types.d.ts +10 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +17 -12
package/README.md
CHANGED
|
@@ -25,9 +25,7 @@ yarn add @ewyn/client
|
|
|
25
25
|
import { Ewyn } from '@ewyn/client';
|
|
26
26
|
|
|
27
27
|
const client = new Ewyn({
|
|
28
|
-
workspaceId: 'your-workspace-id',
|
|
29
28
|
apiKey: 'your-api-key',
|
|
30
|
-
baseUrl: 'https://www.ewyn.ai/api/v1', // optional; omit to use production default
|
|
31
29
|
});
|
|
32
30
|
|
|
33
31
|
// Send an email using template version ID
|
|
@@ -72,7 +70,6 @@ const config = {
|
|
|
72
70
|
|
|
73
71
|
// 2. Initialize with config
|
|
74
72
|
const client = new Ewyn({
|
|
75
|
-
workspaceId: 'your-workspace-id',
|
|
76
73
|
apiKey: 'your-api-key',
|
|
77
74
|
templates: config,
|
|
78
75
|
});
|
|
@@ -91,7 +88,55 @@ await client.send({
|
|
|
91
88
|
|
|
92
89
|
## Getting Your Template Configuration
|
|
93
90
|
|
|
94
|
-
|
|
91
|
+
You can get your template config in three ways:
|
|
92
|
+
|
|
93
|
+
1. **CLI (recommended)** – Run `npx @ewyn/client fetch-config` to download config and generate `ewynTemplates.ts` (see [Fetching template config (CLI)](#fetching-template-config-cli)).
|
|
94
|
+
2. **Dashboard** – Copy JSON from the API Keys page.
|
|
95
|
+
3. **API** – Call the templates config endpoint with curl or your own code.
|
|
96
|
+
|
|
97
|
+
### Fetching template config (CLI)
|
|
98
|
+
|
|
99
|
+
The easiest way to keep your template config in sync is to use the built-in CLI. From your project root (where you have an `ewyn.config.ts` or `ewyn.config.js`), run:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npx @ewyn/client fetch-config
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
This fetches your workspace’s template config from the API and writes a TypeScript file (e.g. `ewynTemplates.ts`) that you can import for type-safe sending.
|
|
106
|
+
|
|
107
|
+
**Config file** (`ewyn.config.ts` in project root):
|
|
108
|
+
|
|
109
|
+
- `apiKey` (required): Your API key (e.g. `process.env.EWYN_API_KEY`)
|
|
110
|
+
- `configurationPath` (optional): Where to write the generated file (e.g. `./src/ewynTemplates.ts`). If omitted, the file is written as `./ewynTemplates.ts` in the current directory.
|
|
111
|
+
|
|
112
|
+
Example `ewyn.config.ts`:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import type { EwynFetchConfig } from '@ewyn/client';
|
|
116
|
+
|
|
117
|
+
const config: EwynFetchConfig = {
|
|
118
|
+
apiKey: process.env.EWYN_API_KEY!,
|
|
119
|
+
configurationPath: './src/ewynTemplates.ts', // optional
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export default config;
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
After running `fetch-config`, import the generated config and pass it to the client:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { Ewyn } from '@ewyn/client';
|
|
129
|
+
import { ewynTemplates } from './ewynTemplates'; // or from your configurationPath
|
|
130
|
+
|
|
131
|
+
const client = new Ewyn({
|
|
132
|
+
apiKey: process.env.EWYN_API_KEY!,
|
|
133
|
+
templates: ewynTemplates,
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Note:** Regenerate the config after creating or updating templates (re-run `npx @ewyn/client fetch-config`).
|
|
138
|
+
|
|
139
|
+
### From Dashboard
|
|
95
140
|
|
|
96
141
|
1. Go to your dashboard → **API Keys** page
|
|
97
142
|
2. Scroll to **Template Configuration** section
|
|
@@ -104,7 +149,6 @@ const config = {
|
|
|
104
149
|
} as const;
|
|
105
150
|
|
|
106
151
|
const client = new Ewyn({
|
|
107
|
-
workspaceId: 'your-workspace-id',
|
|
108
152
|
apiKey: 'your-api-key',
|
|
109
153
|
templates: config, // Now fully type-safe!
|
|
110
154
|
});
|
|
@@ -115,12 +159,10 @@ const client = new Ewyn({
|
|
|
115
159
|
Alternatively, fetch the config programmatically:
|
|
116
160
|
|
|
117
161
|
```bash
|
|
118
|
-
curl -X GET https://www.ewyn.ai/api/v1/
|
|
162
|
+
curl -X GET https://www.ewyn.ai/api/v1/templates/config \
|
|
119
163
|
-H "Authorization: Bearer YOUR_API_KEY"
|
|
120
164
|
```
|
|
121
165
|
|
|
122
|
-
**Note:** Regenerate the config after creating or updating templates to keep it in sync.
|
|
123
|
-
|
|
124
166
|
## API Reference
|
|
125
167
|
|
|
126
168
|
### `Ewyn` Class
|
|
@@ -133,9 +175,7 @@ new Ewyn(options: EwynOptions)
|
|
|
133
175
|
|
|
134
176
|
**Options:**
|
|
135
177
|
|
|
136
|
-
- `workspaceId` (string, required): Your workspace UUID
|
|
137
178
|
- `apiKey` (string, required): Your API key secret
|
|
138
|
-
- `baseUrl` (string, optional): Base URL for the API (defaults to `https://www.ewyn.ai/api/v1`)
|
|
139
179
|
- `templates` (TemplateConfig, optional): Template configuration for name-based sending
|
|
140
180
|
- `maxRetries` (number, optional): Maximum retries for retryable errors (default: 3)
|
|
141
181
|
- `timeout` (number, optional): Request timeout in milliseconds (default: 30000)
|
|
@@ -235,6 +275,7 @@ Check out the [examples directory](./examples/) for comprehensive examples:
|
|
|
235
275
|
|
|
236
276
|
- [Basic send](./examples/basic-send.ts) - Simple sending with template ID
|
|
237
277
|
- [Type-safe usage](./examples/with-template-config.ts) - Full type safety with template config
|
|
278
|
+
- [ewyn.config example](./examples/ewyn.config.example.ts) - Example config for `fetch-config` CLI
|
|
238
279
|
- [Error handling](./examples/error-handling.ts) - Comprehensive error handling patterns
|
|
239
280
|
- [Idempotency](./examples/idempotency.ts) - Preventing duplicate sends
|
|
240
281
|
- [Advanced patterns](./examples/advanced-usage.ts) - Batch sending, retries, and more
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-fetch-config.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/cli-fetch-config.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
5
|
+
import { runFetchConfig } from '../cli.js';
|
|
6
|
+
const MOCK_TEMPLATES = {
|
|
7
|
+
welcome: {
|
|
8
|
+
id: 'version-uuid-1',
|
|
9
|
+
name: 'Welcome Email',
|
|
10
|
+
version: 1,
|
|
11
|
+
vars: {
|
|
12
|
+
firstName: { required: true },
|
|
13
|
+
lastName: { required: false },
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
describe('fetch-config CLI', () => {
|
|
18
|
+
let tempDir;
|
|
19
|
+
let originalFetch;
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ewyn-cli-test-'));
|
|
22
|
+
originalFetch = globalThis.fetch;
|
|
23
|
+
globalThis.fetch = vi.fn().mockResolvedValue({
|
|
24
|
+
ok: true,
|
|
25
|
+
json: async () => ({ templates: MOCK_TEMPLATES }),
|
|
26
|
+
text: async () => '',
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
globalThis.fetch = originalFetch;
|
|
31
|
+
vi.restoreAllMocks();
|
|
32
|
+
try {
|
|
33
|
+
fs.rmSync(tempDir, { recursive: true });
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// ignore
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
it('writes ewynTemplates.ts with fetched config when using default path', async () => {
|
|
40
|
+
const configPath = path.join(tempDir, 'ewyn.config.js');
|
|
41
|
+
fs.writeFileSync(configPath, `export default {
|
|
42
|
+
apiKey: 'test-api-key',
|
|
43
|
+
};
|
|
44
|
+
`, 'utf-8');
|
|
45
|
+
await runFetchConfig(tempDir);
|
|
46
|
+
const outputPath = path.join(tempDir, 'ewynTemplates.ts');
|
|
47
|
+
expect(fs.existsSync(outputPath)).toBe(true);
|
|
48
|
+
const content = fs.readFileSync(outputPath, 'utf-8');
|
|
49
|
+
expect(content).toContain('// Generated by @ewyn/client fetch-config');
|
|
50
|
+
expect(content).toContain('export const ewynTemplates = ');
|
|
51
|
+
expect(content).toContain('"welcome"');
|
|
52
|
+
expect(content).toContain('"version-uuid-1"');
|
|
53
|
+
expect(content).toContain(' as const;');
|
|
54
|
+
});
|
|
55
|
+
it('writes to configurationPath when set in config', async () => {
|
|
56
|
+
const configPath = path.join(tempDir, 'ewyn.config.js');
|
|
57
|
+
fs.writeFileSync(configPath, `export default {
|
|
58
|
+
apiKey: 'key-1',
|
|
59
|
+
configurationPath: './src/ewynTemplates.ts',
|
|
60
|
+
};
|
|
61
|
+
`, 'utf-8');
|
|
62
|
+
await runFetchConfig(tempDir);
|
|
63
|
+
const outputPath = path.join(tempDir, 'src', 'ewynTemplates.ts');
|
|
64
|
+
expect(fs.existsSync(outputPath)).toBe(true);
|
|
65
|
+
const content = fs.readFileSync(outputPath, 'utf-8');
|
|
66
|
+
expect(content).toContain('"welcome"');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -30,7 +30,6 @@ const dashboardConfig = {
|
|
|
30
30
|
};
|
|
31
31
|
test('client with dashboard config has typed send', () => {
|
|
32
32
|
const client = new Ewyn({
|
|
33
|
-
workspaceId: 'ws',
|
|
34
33
|
apiKey: 'key',
|
|
35
34
|
templates: dashboardConfig,
|
|
36
35
|
});
|
|
@@ -39,7 +38,6 @@ test('client with dashboard config has typed send', () => {
|
|
|
39
38
|
});
|
|
40
39
|
test('valid send: required var present, optional omitted', () => {
|
|
41
40
|
const client = new Ewyn({
|
|
42
|
-
workspaceId: 'ws',
|
|
43
41
|
apiKey: 'key',
|
|
44
42
|
templates: dashboardConfig,
|
|
45
43
|
});
|
|
@@ -51,7 +49,6 @@ test('valid send: required var present, optional omitted', () => {
|
|
|
51
49
|
});
|
|
52
50
|
test('valid send: required and optional vars', () => {
|
|
53
51
|
const client = new Ewyn({
|
|
54
|
-
workspaceId: 'ws',
|
|
55
52
|
apiKey: 'key',
|
|
56
53
|
templates: dashboardConfig,
|
|
57
54
|
});
|
|
@@ -63,7 +60,6 @@ test('valid send: required and optional vars', () => {
|
|
|
63
60
|
});
|
|
64
61
|
test('valid send: hyphenated template name', () => {
|
|
65
62
|
const client = new Ewyn({
|
|
66
|
-
workspaceId: 'ws',
|
|
67
63
|
apiKey: 'key',
|
|
68
64
|
templates: dashboardConfig,
|
|
69
65
|
});
|
|
@@ -75,7 +71,6 @@ test('valid send: hyphenated template name', () => {
|
|
|
75
71
|
});
|
|
76
72
|
test('send return type is Promise<SendEmailResponse>', () => {
|
|
77
73
|
const client = new Ewyn({
|
|
78
|
-
workspaceId: 'ws',
|
|
79
74
|
apiKey: 'key',
|
|
80
75
|
templates: dashboardConfig,
|
|
81
76
|
});
|
|
@@ -87,7 +82,6 @@ test('template name is constrained to config keys at type level', () => {
|
|
|
87
82
|
});
|
|
88
83
|
test('missing required variable is rejected by types', () => {
|
|
89
84
|
const client = new Ewyn({
|
|
90
|
-
workspaceId: 'ws',
|
|
91
85
|
apiKey: 'key',
|
|
92
86
|
templates: dashboardConfig,
|
|
93
87
|
});
|
|
@@ -46,9 +46,7 @@ describe('Dashboard config (runtime)', () => {
|
|
|
46
46
|
};
|
|
47
47
|
it('sends with dashboard-shaped config (only required vars)', async () => {
|
|
48
48
|
const client = new Ewyn({
|
|
49
|
-
workspaceId: 'ws-1',
|
|
50
49
|
apiKey: 'key-1',
|
|
51
|
-
baseUrl: 'https://api.test.com/api/v1',
|
|
52
50
|
templates: configOnlyRequired,
|
|
53
51
|
maxRetries: 1,
|
|
54
52
|
timeout: 5000,
|
|
@@ -72,7 +70,7 @@ describe('Dashboard config (runtime)', () => {
|
|
|
72
70
|
},
|
|
73
71
|
});
|
|
74
72
|
expect(result).toEqual(mockResponse);
|
|
75
|
-
expect(global.fetch).toHaveBeenCalledWith('https://
|
|
73
|
+
expect(global.fetch).toHaveBeenCalledWith('https://www.ewyn.ai/api/v1/send', expect.objectContaining({
|
|
76
74
|
method: 'POST',
|
|
77
75
|
body: expect.stringContaining('"templateId":"version-uuid-1"'),
|
|
78
76
|
}));
|
|
@@ -82,9 +80,7 @@ describe('Dashboard config (runtime)', () => {
|
|
|
82
80
|
});
|
|
83
81
|
it('sends with dashboard-shaped config (mixed required/optional, hyphenated key)', async () => {
|
|
84
82
|
const client = new Ewyn({
|
|
85
|
-
workspaceId: 'ws-2',
|
|
86
83
|
apiKey: 'key-2',
|
|
87
|
-
baseUrl: 'https://api.test.com/api/v1',
|
|
88
84
|
templates: configMixedVars,
|
|
89
85
|
maxRetries: 1,
|
|
90
86
|
timeout: 5000,
|
|
@@ -118,9 +114,7 @@ describe('Dashboard config (runtime)', () => {
|
|
|
118
114
|
});
|
|
119
115
|
it('sends with template that has empty vars (dashboard shape)', async () => {
|
|
120
116
|
const client = new Ewyn({
|
|
121
|
-
workspaceId: 'ws-3',
|
|
122
117
|
apiKey: 'key-3',
|
|
123
|
-
baseUrl: 'https://api.test.com/api/v1',
|
|
124
118
|
templates: configEmptyVars,
|
|
125
119
|
maxRetries: 1,
|
|
126
120
|
timeout: 5000,
|
|
@@ -148,9 +142,7 @@ describe('Dashboard config (runtime)', () => {
|
|
|
148
142
|
});
|
|
149
143
|
it('throws when required variable is missing (dashboard config)', async () => {
|
|
150
144
|
const client = new Ewyn({
|
|
151
|
-
workspaceId: 'ws-1',
|
|
152
145
|
apiKey: 'key-1',
|
|
153
|
-
baseUrl: 'https://api.test.com/api/v1',
|
|
154
146
|
templates: configOnlyRequired,
|
|
155
147
|
maxRetries: 1,
|
|
156
148
|
timeout: 5000,
|
|
@@ -166,9 +158,7 @@ describe('Dashboard config (runtime)', () => {
|
|
|
166
158
|
});
|
|
167
159
|
it('throws when template name is not in config (dashboard config)', async () => {
|
|
168
160
|
const client = new Ewyn({
|
|
169
|
-
workspaceId: 'ws-1',
|
|
170
161
|
apiKey: 'key-1',
|
|
171
|
-
baseUrl: 'https://api.test.com/api/v1',
|
|
172
162
|
templates: configOnlyRequired,
|
|
173
163
|
maxRetries: 1,
|
|
174
164
|
timeout: 5000,
|
|
@@ -8,9 +8,7 @@ describe('Ewyn SDK', () => {
|
|
|
8
8
|
vi.clearAllMocks();
|
|
9
9
|
global.fetch.mockReset();
|
|
10
10
|
client = new Ewyn({
|
|
11
|
-
workspaceId: 'test-workspace-id',
|
|
12
11
|
apiKey: 'test-api-key',
|
|
13
|
-
baseUrl: 'https://api.test.com/api/v1',
|
|
14
12
|
maxRetries: 2, // Allow 1 retry (attempt < maxRetries)
|
|
15
13
|
timeout: 5000,
|
|
16
14
|
});
|
|
@@ -21,7 +19,6 @@ describe('Ewyn SDK', () => {
|
|
|
21
19
|
});
|
|
22
20
|
it('should use default base URL if not provided', () => {
|
|
23
21
|
const defaultClient = new Ewyn({
|
|
24
|
-
workspaceId: 'test-workspace-id',
|
|
25
22
|
apiKey: 'test-api-key',
|
|
26
23
|
});
|
|
27
24
|
expect(defaultClient).toBeInstanceOf(Ewyn);
|
|
@@ -38,7 +35,6 @@ describe('Ewyn SDK', () => {
|
|
|
38
35
|
},
|
|
39
36
|
};
|
|
40
37
|
const configClient = new Ewyn({
|
|
41
|
-
workspaceId: 'test-workspace-id',
|
|
42
38
|
apiKey: 'test-api-key',
|
|
43
39
|
templates: config,
|
|
44
40
|
});
|
|
@@ -65,7 +61,7 @@ describe('Ewyn SDK', () => {
|
|
|
65
61
|
},
|
|
66
62
|
});
|
|
67
63
|
expect(result).toEqual(mockResponse);
|
|
68
|
-
expect(global.fetch).toHaveBeenCalledWith('https://
|
|
64
|
+
expect(global.fetch).toHaveBeenCalledWith('https://www.ewyn.ai/api/v1/send', expect.objectContaining({
|
|
69
65
|
method: 'POST',
|
|
70
66
|
headers: expect.objectContaining({
|
|
71
67
|
'Content-Type': 'application/json',
|
|
@@ -92,7 +88,6 @@ describe('Ewyn SDK', () => {
|
|
|
92
88
|
},
|
|
93
89
|
};
|
|
94
90
|
const configClient = new Ewyn({
|
|
95
|
-
workspaceId: 'test-workspace-id',
|
|
96
91
|
apiKey: 'test-api-key',
|
|
97
92
|
templates: config,
|
|
98
93
|
});
|
|
@@ -203,7 +198,6 @@ describe('Ewyn SDK', () => {
|
|
|
203
198
|
},
|
|
204
199
|
};
|
|
205
200
|
const configClient = new Ewyn({
|
|
206
|
-
workspaceId: 'test-workspace-id',
|
|
207
201
|
apiKey: 'test-api-key',
|
|
208
202
|
templates: config,
|
|
209
203
|
});
|
|
@@ -228,7 +222,6 @@ describe('Ewyn SDK', () => {
|
|
|
228
222
|
},
|
|
229
223
|
};
|
|
230
224
|
const configClient = new Ewyn({
|
|
231
|
-
workspaceId: 'test-workspace-id',
|
|
232
225
|
apiKey: 'test-api-key',
|
|
233
226
|
templates: config,
|
|
234
227
|
});
|
|
@@ -254,7 +247,6 @@ describe('Ewyn SDK', () => {
|
|
|
254
247
|
},
|
|
255
248
|
};
|
|
256
249
|
const configClient = new Ewyn({
|
|
257
|
-
workspaceId: 'test-workspace-id',
|
|
258
250
|
apiKey: 'test-api-key',
|
|
259
251
|
templates: config,
|
|
260
252
|
});
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA0GA,4BAA4B;AAC5B,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB/D"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { pathToFileURL } from 'node:url';
|
|
6
|
+
const EWYN_API_BASE_URL = 'https://www.ewyn.ai/api/v1';
|
|
7
|
+
const CONFIG_NAMES = ['ewyn.config.ts', 'ewyn.config.mjs', 'ewyn.config.js'];
|
|
8
|
+
const DEFAULT_OUTPUT_FILE = 'ewynTemplates.ts';
|
|
9
|
+
function printUsage() {
|
|
10
|
+
console.error(`
|
|
11
|
+
Usage: ewyn <command>
|
|
12
|
+
|
|
13
|
+
Commands:
|
|
14
|
+
fetch-config Fetch template config from the API and write ewynTemplates.ts (or configurationPath from ewyn.config)
|
|
15
|
+
|
|
16
|
+
Config file (in current working directory):
|
|
17
|
+
Look for ewyn.config.ts, ewyn.config.mjs, or ewyn.config.js with default export:
|
|
18
|
+
{ apiKey: string, configurationPath?: string }
|
|
19
|
+
|
|
20
|
+
Example ewyn.config.ts:
|
|
21
|
+
export default {
|
|
22
|
+
apiKey: process.env.EWYN_API_KEY!,
|
|
23
|
+
configurationPath: './src/ewynTemplates.ts', // optional
|
|
24
|
+
};
|
|
25
|
+
`);
|
|
26
|
+
}
|
|
27
|
+
function findConfigPath(cwd) {
|
|
28
|
+
for (const name of CONFIG_NAMES) {
|
|
29
|
+
const p = path.join(cwd, name);
|
|
30
|
+
if (fs.existsSync(p))
|
|
31
|
+
return p;
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
async function loadConfig(configPath) {
|
|
36
|
+
const ext = path.extname(configPath);
|
|
37
|
+
if (ext === '.ts') {
|
|
38
|
+
const require = createRequire(import.meta.url);
|
|
39
|
+
const { register } = require('tsx/cjs');
|
|
40
|
+
register();
|
|
41
|
+
const mod = require(configPath);
|
|
42
|
+
const config = mod?.default;
|
|
43
|
+
if (!config || typeof config !== 'object') {
|
|
44
|
+
throw new Error(`${configPath}: expected default export to be a config object`);
|
|
45
|
+
}
|
|
46
|
+
return config;
|
|
47
|
+
}
|
|
48
|
+
const mod = await import(pathToFileURL(configPath).href);
|
|
49
|
+
const config = mod?.default;
|
|
50
|
+
if (!config || typeof config !== 'object') {
|
|
51
|
+
throw new Error(`${configPath}: expected default export to be a config object`);
|
|
52
|
+
}
|
|
53
|
+
return config;
|
|
54
|
+
}
|
|
55
|
+
function validateConfig(config, configPath) {
|
|
56
|
+
if (!config.apiKey || typeof config.apiKey !== 'string') {
|
|
57
|
+
console.error(`Error: apiKey is missing or invalid in ${configPath}. You can use process.env.EWYN_API_KEY.`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function fetchTemplates(apiKey) {
|
|
62
|
+
const url = `${EWYN_API_BASE_URL}/templates/config`;
|
|
63
|
+
const response = await fetch(url, {
|
|
64
|
+
method: 'GET',
|
|
65
|
+
headers: {
|
|
66
|
+
Authorization: `Bearer ${apiKey}`,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
if (!response.ok) {
|
|
70
|
+
const body = await response.text();
|
|
71
|
+
let details = body;
|
|
72
|
+
try {
|
|
73
|
+
const json = JSON.parse(body);
|
|
74
|
+
details = json.error ?? json.message ?? body;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// use raw body
|
|
78
|
+
}
|
|
79
|
+
console.error(`Error: API request failed (${response.status}): ${details}`);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
const data = (await response.json());
|
|
83
|
+
const templates = data.templates ?? {};
|
|
84
|
+
return templates;
|
|
85
|
+
}
|
|
86
|
+
function serializeTemplates(templates) {
|
|
87
|
+
const lines = ['// Generated by @ewyn/client fetch-config. Do not edit by hand.', '', 'export const ewynTemplates = '];
|
|
88
|
+
const json = JSON.stringify(templates, null, 2);
|
|
89
|
+
// Ensure valid TS: escape any stray characters and add "as const"
|
|
90
|
+
lines.push(json + ' as const;');
|
|
91
|
+
return lines.join('\n');
|
|
92
|
+
}
|
|
93
|
+
/** Exported for testing. */
|
|
94
|
+
export async function runFetchConfig(cwd) {
|
|
95
|
+
const configPath = findConfigPath(cwd);
|
|
96
|
+
if (!configPath) {
|
|
97
|
+
console.error('Error: ewyn.config.ts (or ewyn.config.mjs / ewyn.config.js) not found in current directory.');
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
const config = await loadConfig(configPath);
|
|
101
|
+
validateConfig(config, configPath);
|
|
102
|
+
const outputPath = config.configurationPath
|
|
103
|
+
? path.resolve(cwd, config.configurationPath)
|
|
104
|
+
: path.join(cwd, DEFAULT_OUTPUT_FILE);
|
|
105
|
+
const templates = await fetchTemplates(config.apiKey);
|
|
106
|
+
const dir = path.dirname(outputPath);
|
|
107
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
108
|
+
fs.writeFileSync(outputPath, serializeTemplates(templates), 'utf-8');
|
|
109
|
+
console.log(`Wrote ${outputPath}`);
|
|
110
|
+
}
|
|
111
|
+
async function main() {
|
|
112
|
+
const args = process.argv.slice(2);
|
|
113
|
+
const command = args[0];
|
|
114
|
+
if (!command || command === '--help' || command === '-h') {
|
|
115
|
+
printUsage();
|
|
116
|
+
process.exit(0);
|
|
117
|
+
}
|
|
118
|
+
if (command === 'fetch-config') {
|
|
119
|
+
const cwd = process.cwd();
|
|
120
|
+
await runFetchConfig(cwd);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
console.error(`Error: unknown command "${command}".`);
|
|
124
|
+
printUsage();
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
const isMain = typeof process !== 'undefined' &&
|
|
128
|
+
process.argv[1] &&
|
|
129
|
+
pathToFileURL(process.argv[1]).href === import.meta.url;
|
|
130
|
+
if (isMain) {
|
|
131
|
+
main().catch((err) => {
|
|
132
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
133
|
+
process.exit(1);
|
|
134
|
+
});
|
|
135
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,55 +1,6 @@
|
|
|
1
1
|
import type { EwynOptions, EwynOptionsTyped, SendEmailOptions, SendEmailOptionsTyped, SendEmailResponse, TemplateConfig } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Ewyn SDK Client
|
|
4
|
-
*
|
|
5
|
-
* @example Basic usage without template config
|
|
6
|
-
* ```ts
|
|
7
|
-
* const client = new Ewyn({
|
|
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 Ewyn({
|
|
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
2
|
export declare class Ewyn<TConfig extends TemplateConfig = TemplateConfig> {
|
|
50
|
-
private readonly workspaceId;
|
|
51
3
|
private readonly apiKey;
|
|
52
|
-
private readonly baseUrl;
|
|
53
4
|
private readonly templates?;
|
|
54
5
|
private readonly maxRetries;
|
|
55
6
|
private readonly timeout;
|
|
@@ -95,5 +46,5 @@ export declare class Ewyn<TConfig extends TemplateConfig = TemplateConfig> {
|
|
|
95
46
|
private requestWithRetry;
|
|
96
47
|
}
|
|
97
48
|
export { EwynApiError } from './errors.js';
|
|
98
|
-
export type { EwynOptions, EwynOptionsTyped, SendEmailOptions, SendEmailOptionsBase, SendEmailOptionsTyped, SendEmailResponse, TemplateConfig, TemplateConfigEntry, TemplateVariable
|
|
49
|
+
export type { EwynFetchConfig, EwynOptions, EwynOptionsTyped, SendEmailOptions, SendEmailOptionsBase, SendEmailOptionsTyped, SendEmailResponse, TemplateConfig, TemplateConfigEntry, TemplateVariable } from './types.js';
|
|
99
50
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACf,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACf,MAAM,YAAY,CAAC;AAiDpB,qBAAa,IAAI,CAAC,OAAO,SAAS,cAAc,GAAG,cAAc;IAC/D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAU;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,EAAE,WAAW,GAAG,gBAAgB,CAAC,OAAO,CAAC;IAO5D;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACG,IAAI,CACR,OAAO,EAAE,OAAO,SAAS,cAAc,GACnC,qBAAqB,CAAC,OAAO,CAAC,GAAG,gBAAgB,GACjD,gBAAgB,GACnB,OAAO,CAAC,iBAAiB,CAAC;IA8C7B;;OAEG;YACW,iBAAiB;IAyB/B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA2BzB;;OAEG;YACW,gBAAgB;CAuE/B;AAED,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,6 @@ import { EwynApiError } from './errors.js';
|
|
|
5
5
|
* @example Basic usage without template config
|
|
6
6
|
* ```ts
|
|
7
7
|
* const client = new Ewyn({
|
|
8
|
-
* workspaceId: 'your-workspace-id',
|
|
9
8
|
* apiKey: 'your-api-key',
|
|
10
9
|
* });
|
|
11
10
|
*
|
|
@@ -31,7 +30,6 @@ import { EwynApiError } from './errors.js';
|
|
|
31
30
|
* } as const;
|
|
32
31
|
*
|
|
33
32
|
* const client = new Ewyn({
|
|
34
|
-
* workspaceId: 'your-workspace-id',
|
|
35
33
|
* apiKey: 'your-api-key',
|
|
36
34
|
* templates: config
|
|
37
35
|
* });
|
|
@@ -46,17 +44,14 @@ import { EwynApiError } from './errors.js';
|
|
|
46
44
|
* });
|
|
47
45
|
* ```
|
|
48
46
|
*/
|
|
47
|
+
const EWYN_API_BASE_URL = 'https://www.ewyn.ai/api/v1';
|
|
49
48
|
export class Ewyn {
|
|
50
|
-
workspaceId;
|
|
51
49
|
apiKey;
|
|
52
|
-
baseUrl;
|
|
53
50
|
templates;
|
|
54
51
|
maxRetries;
|
|
55
52
|
timeout;
|
|
56
53
|
constructor(options) {
|
|
57
|
-
this.workspaceId = options.workspaceId;
|
|
58
54
|
this.apiKey = options.apiKey;
|
|
59
|
-
this.baseUrl = options.baseUrl || 'https://www.ewyn.ai/api/v1';
|
|
60
55
|
this.templates = options.templates;
|
|
61
56
|
this.maxRetries = options.maxRetries ?? 3;
|
|
62
57
|
this.timeout = options.timeout ?? 30000;
|
|
@@ -113,7 +108,7 @@ export class Ewyn {
|
|
|
113
108
|
body.version = options.version;
|
|
114
109
|
}
|
|
115
110
|
// Make request with retries
|
|
116
|
-
return this.requestWithRetry(
|
|
111
|
+
return this.requestWithRetry('/send', {
|
|
117
112
|
method: 'POST',
|
|
118
113
|
headers: {
|
|
119
114
|
'Content-Type': 'application/json',
|
|
@@ -166,7 +161,7 @@ export class Ewyn {
|
|
|
166
161
|
* Make HTTP request with retry logic
|
|
167
162
|
*/
|
|
168
163
|
async requestWithRetry(path, init, attempt = 1) {
|
|
169
|
-
const url = `${
|
|
164
|
+
const url = `${EWYN_API_BASE_URL}${path}`;
|
|
170
165
|
const controller = new AbortController();
|
|
171
166
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
172
167
|
try {
|
package/dist/types.d.ts
CHANGED
|
@@ -100,12 +100,8 @@ export interface SendEmailResponse {
|
|
|
100
100
|
* Configuration options for the Ewyn client (base)
|
|
101
101
|
*/
|
|
102
102
|
export interface EwynOptionsBase {
|
|
103
|
-
/** Workspace ID (UUID) */
|
|
104
|
-
workspaceId: string;
|
|
105
103
|
/** API key secret */
|
|
106
104
|
apiKey: string;
|
|
107
|
-
/** Base URL for the API (defaults to production) */
|
|
108
|
-
baseUrl?: string;
|
|
109
105
|
/** Maximum number of retries for retryable errors (default: 3) */
|
|
110
106
|
maxRetries?: number;
|
|
111
107
|
/** Request timeout in milliseconds (default: 30000) */
|
|
@@ -125,5 +121,15 @@ export type EwynOptions = EwynOptionsBase & {
|
|
|
125
121
|
/** Template configuration for name-based sending and validation */
|
|
126
122
|
templates?: TemplateConfig;
|
|
127
123
|
};
|
|
124
|
+
/**
|
|
125
|
+
* Configuration for the fetch-config CLI (ewyn.config.ts).
|
|
126
|
+
* Used only by the CLI to know which API key to use and where to write the generated file.
|
|
127
|
+
*/
|
|
128
|
+
export interface EwynFetchConfig {
|
|
129
|
+
/** API key secret (e.g. process.env.EWYN_API_KEY) */
|
|
130
|
+
apiKey: string;
|
|
131
|
+
/** Output path for the generated ewynTemplates file (e.g. ./src/ewynTemplates.ts). If omitted, defaults to ./ewynTemplates.ts in cwd. */
|
|
132
|
+
configurationPath?: string;
|
|
133
|
+
}
|
|
128
134
|
export {};
|
|
129
135
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAEjE;;GAEG;AACH,KAAK,YAAY,CAAC,CAAC,SAAS,mBAAmB,IAAI;KAChD,CAAC,IAAI,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,GAAG,CAAC,GAAG,KAAK;CAC5E,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAEnB;;GAEG;AACH,KAAK,YAAY,CAAC,CAAC,SAAS,mBAAmB,IAAI;KAChD,CAAC,IAAI,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;QAAE,QAAQ,EAAE,KAAK,CAAA;KAAE,GAAG,CAAC,GAAG,KAAK;CAC7E,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAEnB;;GAEG;AACH,KAAK,mBAAmB,CAAC,CAAC,SAAS,mBAAmB,IACpD,YAAY,CAAC,CAAC,CAAC,SAAS,KAAK,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ewyn/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Official TypeScript SDK for Ewyn email service with full type safety",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -11,16 +11,12 @@
|
|
|
11
11
|
"types": "./dist/index.d.ts"
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"ewyn": "./dist/cli.js"
|
|
16
|
+
},
|
|
14
17
|
"files": [
|
|
15
18
|
"dist"
|
|
16
19
|
],
|
|
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
20
|
"keywords": [
|
|
25
21
|
"ewyn",
|
|
26
22
|
"email",
|
|
@@ -35,12 +31,21 @@
|
|
|
35
31
|
"engines": {
|
|
36
32
|
"node": ">=18.0.0"
|
|
37
33
|
},
|
|
38
|
-
"dependencies": {
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"tsx": "^4.19.0"
|
|
36
|
+
},
|
|
39
37
|
"devDependencies": {
|
|
40
38
|
"@types/node": "^20.11.0",
|
|
41
|
-
"@workspace/eslint-config": "workspace:*",
|
|
42
|
-
"@workspace/typescript-config": "workspace:*",
|
|
43
39
|
"typescript": "^5.7.3",
|
|
44
|
-
"vitest": "^1.2.0"
|
|
40
|
+
"vitest": "^1.2.0",
|
|
41
|
+
"@workspace/eslint-config": "0.0.0",
|
|
42
|
+
"@workspace/typescript-config": "0.0.0"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc",
|
|
46
|
+
"dev": "tsc --watch",
|
|
47
|
+
"lint": "eslint . --max-warnings 0",
|
|
48
|
+
"test": "vitest run --typecheck",
|
|
49
|
+
"test:watch": "vitest"
|
|
45
50
|
}
|
|
46
51
|
}
|