@parsrun/service-adapters 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 +166 -0
- package/dist/email/index.d.ts +306 -0
- package/dist/email/index.js +300 -0
- package/dist/email/index.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +934 -0
- package/dist/index.js.map +1 -0
- package/dist/payments/index.d.ts +782 -0
- package/dist/payments/index.js +636 -0
- package/dist/payments/index.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# @parsrun/service-adapters
|
|
2
|
+
|
|
3
|
+
Service definitions for Pars microservices - type-safe RPC contracts for email and payments.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Type-Safe**: Full TypeScript support for service contracts
|
|
8
|
+
- **RPC Ready**: Compatible with @parsrun/service
|
|
9
|
+
- **Reusable**: Share definitions between client and server
|
|
10
|
+
- **Versioned**: Service versioning support
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add @parsrun/service-adapters
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { emailService } from '@parsrun/service-adapters/email';
|
|
22
|
+
import { createRpcClient } from '@parsrun/service/rpc';
|
|
23
|
+
|
|
24
|
+
// Create type-safe client
|
|
25
|
+
const email = createRpcClient({
|
|
26
|
+
service: emailService,
|
|
27
|
+
transport: httpTransport,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Call with full type safety
|
|
31
|
+
await email.call('send', {
|
|
32
|
+
to: 'user@example.com',
|
|
33
|
+
subject: 'Hello',
|
|
34
|
+
body: 'World',
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## API Overview
|
|
39
|
+
|
|
40
|
+
### Email Service
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { emailService, type EmailService } from '@parsrun/service-adapters/email';
|
|
44
|
+
|
|
45
|
+
// Service definition
|
|
46
|
+
emailService.name; // 'email'
|
|
47
|
+
emailService.version; // '1.0.0'
|
|
48
|
+
emailService.queries; // { getStatus, ... }
|
|
49
|
+
emailService.mutations; // { send, sendBatch, ... }
|
|
50
|
+
emailService.events; // { sent, failed, ... }
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### Queries
|
|
54
|
+
|
|
55
|
+
| Method | Input | Output |
|
|
56
|
+
|--------|-------|--------|
|
|
57
|
+
| `getStatus` | `void` | `{ status, provider }` |
|
|
58
|
+
| `getQuota` | `void` | `{ used, limit, resetAt }` |
|
|
59
|
+
|
|
60
|
+
#### Mutations
|
|
61
|
+
|
|
62
|
+
| Method | Input | Output |
|
|
63
|
+
|--------|-------|--------|
|
|
64
|
+
| `send` | `{ to, subject, body, ... }` | `{ messageId, status }` |
|
|
65
|
+
| `sendBatch` | `{ messages[] }` | `{ results[] }` |
|
|
66
|
+
| `sendTemplate` | `{ to, template, data }` | `{ messageId }` |
|
|
67
|
+
|
|
68
|
+
#### Events
|
|
69
|
+
|
|
70
|
+
| Event | Payload |
|
|
71
|
+
|-------|---------|
|
|
72
|
+
| `email.sent` | `{ messageId, to, subject }` |
|
|
73
|
+
| `email.failed` | `{ messageId, error }` |
|
|
74
|
+
| `email.bounced` | `{ messageId, reason }` |
|
|
75
|
+
|
|
76
|
+
### Payments Service
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { paymentsService, type PaymentsService } from '@parsrun/service-adapters/payments';
|
|
80
|
+
|
|
81
|
+
// Service definition
|
|
82
|
+
paymentsService.name; // 'payments'
|
|
83
|
+
paymentsService.version; // '1.0.0'
|
|
84
|
+
paymentsService.queries; // { getSubscription, ... }
|
|
85
|
+
paymentsService.mutations; // { createCheckout, ... }
|
|
86
|
+
paymentsService.events; // { subscriptionCreated, ... }
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### Queries
|
|
90
|
+
|
|
91
|
+
| Method | Input | Output |
|
|
92
|
+
|--------|-------|--------|
|
|
93
|
+
| `getSubscription` | `{ subscriptionId }` | `Subscription` |
|
|
94
|
+
| `getCustomer` | `{ customerId }` | `Customer` |
|
|
95
|
+
| `listInvoices` | `{ customerId, limit? }` | `Invoice[]` |
|
|
96
|
+
|
|
97
|
+
#### Mutations
|
|
98
|
+
|
|
99
|
+
| Method | Input | Output |
|
|
100
|
+
|--------|-------|--------|
|
|
101
|
+
| `createCheckout` | `{ priceId, customerId, ... }` | `{ sessionId, url }` |
|
|
102
|
+
| `cancelSubscription` | `{ subscriptionId }` | `{ success }` |
|
|
103
|
+
| `updateSubscription` | `{ subscriptionId, priceId }` | `Subscription` |
|
|
104
|
+
|
|
105
|
+
#### Events
|
|
106
|
+
|
|
107
|
+
| Event | Payload |
|
|
108
|
+
|-------|---------|
|
|
109
|
+
| `subscription.created` | `{ subscriptionId, customerId }` |
|
|
110
|
+
| `subscription.cancelled` | `{ subscriptionId, reason }` |
|
|
111
|
+
| `payment.succeeded` | `{ paymentId, amount }` |
|
|
112
|
+
| `payment.failed` | `{ paymentId, error }` |
|
|
113
|
+
|
|
114
|
+
### Creating RPC Server
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
import { emailService } from '@parsrun/service-adapters/email';
|
|
118
|
+
import { createRpcServer } from '@parsrun/service/rpc';
|
|
119
|
+
|
|
120
|
+
const server = createRpcServer({
|
|
121
|
+
service: emailService,
|
|
122
|
+
handlers: {
|
|
123
|
+
getStatus: async () => {
|
|
124
|
+
return { status: 'healthy', provider: 'resend' };
|
|
125
|
+
},
|
|
126
|
+
send: async ({ to, subject, body }) => {
|
|
127
|
+
const result = await emailProvider.send({ to, subject, body });
|
|
128
|
+
return { messageId: result.id, status: 'sent' };
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Creating RPC Client
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { emailService } from '@parsrun/service-adapters/email';
|
|
138
|
+
import { createRpcClient, HttpTransport } from '@parsrun/service/rpc';
|
|
139
|
+
|
|
140
|
+
const client = createRpcClient({
|
|
141
|
+
service: emailService,
|
|
142
|
+
transport: new HttpTransport({
|
|
143
|
+
baseUrl: 'https://api.example.com/rpc/email',
|
|
144
|
+
}),
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Type-safe calls
|
|
148
|
+
const status = await client.query('getStatus');
|
|
149
|
+
const result = await client.mutation('send', {
|
|
150
|
+
to: 'user@example.com',
|
|
151
|
+
subject: 'Hello',
|
|
152
|
+
body: 'World',
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Exports
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { ... } from '@parsrun/service-adapters'; // Main exports
|
|
160
|
+
import { ... } from '@parsrun/service-adapters/email'; // Email service
|
|
161
|
+
import { ... } from '@parsrun/service-adapters/payments'; // Payments service
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
MIT
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import * as _parsrun_service from '@parsrun/service';
|
|
2
|
+
import { createMemoryEventTransport, RpcServer, EventEmitter, ServiceClientOptions } from '@parsrun/service';
|
|
3
|
+
import { Logger } from '@parsrun/core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @parsrun/service-adapters - Email Service Definition
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Email Service Definition
|
|
10
|
+
*
|
|
11
|
+
* Provides email sending capabilities as a microservice.
|
|
12
|
+
*/
|
|
13
|
+
declare const emailServiceDefinition: _parsrun_service.ServiceDefinition<{
|
|
14
|
+
/**
|
|
15
|
+
* Check if email configuration is valid
|
|
16
|
+
*/
|
|
17
|
+
verify: {
|
|
18
|
+
input: undefined;
|
|
19
|
+
output: {
|
|
20
|
+
valid: boolean;
|
|
21
|
+
provider: string;
|
|
22
|
+
};
|
|
23
|
+
description: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Get available email templates
|
|
27
|
+
*/
|
|
28
|
+
getTemplates: {
|
|
29
|
+
input: undefined;
|
|
30
|
+
output: {
|
|
31
|
+
templates: Array<{
|
|
32
|
+
name: string;
|
|
33
|
+
description: string;
|
|
34
|
+
variables: string[];
|
|
35
|
+
}>;
|
|
36
|
+
};
|
|
37
|
+
description: string;
|
|
38
|
+
};
|
|
39
|
+
}, {
|
|
40
|
+
/**
|
|
41
|
+
* Send a single email
|
|
42
|
+
*/
|
|
43
|
+
send: {
|
|
44
|
+
input: {
|
|
45
|
+
to: string | string[];
|
|
46
|
+
subject: string;
|
|
47
|
+
html?: string;
|
|
48
|
+
text?: string;
|
|
49
|
+
from?: string;
|
|
50
|
+
replyTo?: string;
|
|
51
|
+
cc?: string | string[];
|
|
52
|
+
bcc?: string | string[];
|
|
53
|
+
templateName?: string;
|
|
54
|
+
templateData?: Record<string, unknown>;
|
|
55
|
+
tags?: Record<string, string>;
|
|
56
|
+
scheduledAt?: string;
|
|
57
|
+
};
|
|
58
|
+
output: {
|
|
59
|
+
success: boolean;
|
|
60
|
+
messageId?: string;
|
|
61
|
+
error?: string;
|
|
62
|
+
};
|
|
63
|
+
description: string;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Send batch emails
|
|
67
|
+
*/
|
|
68
|
+
sendBatch: {
|
|
69
|
+
input: {
|
|
70
|
+
emails: Array<{
|
|
71
|
+
to: string | string[];
|
|
72
|
+
subject: string;
|
|
73
|
+
html?: string;
|
|
74
|
+
text?: string;
|
|
75
|
+
templateName?: string;
|
|
76
|
+
templateData?: Record<string, unknown>;
|
|
77
|
+
}>;
|
|
78
|
+
stopOnError?: boolean;
|
|
79
|
+
};
|
|
80
|
+
output: {
|
|
81
|
+
total: number;
|
|
82
|
+
successful: number;
|
|
83
|
+
failed: number;
|
|
84
|
+
results: Array<{
|
|
85
|
+
success: boolean;
|
|
86
|
+
messageId?: string;
|
|
87
|
+
error?: string;
|
|
88
|
+
}>;
|
|
89
|
+
};
|
|
90
|
+
description: string;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Render an email template
|
|
94
|
+
*/
|
|
95
|
+
renderTemplate: {
|
|
96
|
+
input: {
|
|
97
|
+
templateName: string;
|
|
98
|
+
data: Record<string, unknown>;
|
|
99
|
+
};
|
|
100
|
+
output: {
|
|
101
|
+
subject: string;
|
|
102
|
+
html: string;
|
|
103
|
+
text: string;
|
|
104
|
+
};
|
|
105
|
+
description: string;
|
|
106
|
+
};
|
|
107
|
+
}, {
|
|
108
|
+
/**
|
|
109
|
+
* Emitted when an email is sent successfully
|
|
110
|
+
*/
|
|
111
|
+
"email.sent": {
|
|
112
|
+
data: {
|
|
113
|
+
messageId: string;
|
|
114
|
+
to: string[];
|
|
115
|
+
subject: string;
|
|
116
|
+
provider: string;
|
|
117
|
+
timestamp: string;
|
|
118
|
+
};
|
|
119
|
+
delivery: "at-least-once";
|
|
120
|
+
description: string;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Emitted when an email fails to send
|
|
124
|
+
*/
|
|
125
|
+
"email.failed": {
|
|
126
|
+
data: {
|
|
127
|
+
to: string[];
|
|
128
|
+
subject: string;
|
|
129
|
+
error: string;
|
|
130
|
+
provider: string;
|
|
131
|
+
timestamp: string;
|
|
132
|
+
};
|
|
133
|
+
delivery: "at-least-once";
|
|
134
|
+
description: string;
|
|
135
|
+
};
|
|
136
|
+
}, string[]>;
|
|
137
|
+
/**
|
|
138
|
+
* Type export for the email service definition
|
|
139
|
+
*/
|
|
140
|
+
type EmailServiceDefinition = typeof emailServiceDefinition;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @parsrun/service-adapters - Email Service Server
|
|
144
|
+
* Server-side implementation of the Email microservice
|
|
145
|
+
*/
|
|
146
|
+
|
|
147
|
+
interface EmailServiceServerOptions {
|
|
148
|
+
/** Email provider configuration */
|
|
149
|
+
provider: EmailProviderConfig;
|
|
150
|
+
/** Logger */
|
|
151
|
+
logger?: Logger;
|
|
152
|
+
/** Event transport (for emitting events) */
|
|
153
|
+
eventTransport?: ReturnType<typeof createMemoryEventTransport>;
|
|
154
|
+
}
|
|
155
|
+
interface EmailProviderConfig {
|
|
156
|
+
type: "resend" | "sendgrid" | "postmark" | "console";
|
|
157
|
+
apiKey?: string;
|
|
158
|
+
fromEmail: string;
|
|
159
|
+
fromName?: string;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Create Email Service Server
|
|
163
|
+
*/
|
|
164
|
+
declare function createEmailServiceServer(options: EmailServiceServerOptions): {
|
|
165
|
+
rpcServer: RpcServer;
|
|
166
|
+
eventEmitter: EventEmitter;
|
|
167
|
+
register: () => void;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* @parsrun/service-adapters - Email Service Client
|
|
172
|
+
* Type-safe client for the Email microservice
|
|
173
|
+
*/
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Type-safe Email Service Client
|
|
177
|
+
*/
|
|
178
|
+
interface EmailServiceClient {
|
|
179
|
+
/**
|
|
180
|
+
* Verify email provider configuration
|
|
181
|
+
*/
|
|
182
|
+
verify(): Promise<{
|
|
183
|
+
valid: boolean;
|
|
184
|
+
provider: string;
|
|
185
|
+
}>;
|
|
186
|
+
/**
|
|
187
|
+
* Get available email templates
|
|
188
|
+
*/
|
|
189
|
+
getTemplates(): Promise<{
|
|
190
|
+
templates: Array<{
|
|
191
|
+
name: string;
|
|
192
|
+
description: string;
|
|
193
|
+
variables: string[];
|
|
194
|
+
}>;
|
|
195
|
+
}>;
|
|
196
|
+
/**
|
|
197
|
+
* Send a single email
|
|
198
|
+
*/
|
|
199
|
+
send(options: SendEmailOptions): Promise<SendEmailResult>;
|
|
200
|
+
/**
|
|
201
|
+
* Send batch emails
|
|
202
|
+
*/
|
|
203
|
+
sendBatch(options: SendBatchOptions): Promise<SendBatchResult>;
|
|
204
|
+
/**
|
|
205
|
+
* Render an email template
|
|
206
|
+
*/
|
|
207
|
+
renderTemplate(templateName: string, data: Record<string, unknown>): Promise<{
|
|
208
|
+
subject: string;
|
|
209
|
+
html: string;
|
|
210
|
+
text: string;
|
|
211
|
+
}>;
|
|
212
|
+
/**
|
|
213
|
+
* Subscribe to email events
|
|
214
|
+
*/
|
|
215
|
+
onEmailSent(handler: (event: {
|
|
216
|
+
messageId: string;
|
|
217
|
+
to: string[];
|
|
218
|
+
subject: string;
|
|
219
|
+
provider: string;
|
|
220
|
+
timestamp: string;
|
|
221
|
+
}) => Promise<void>): () => void;
|
|
222
|
+
onEmailFailed(handler: (event: {
|
|
223
|
+
to: string[];
|
|
224
|
+
subject: string;
|
|
225
|
+
error: string;
|
|
226
|
+
provider: string;
|
|
227
|
+
timestamp: string;
|
|
228
|
+
}) => Promise<void>): () => void;
|
|
229
|
+
/**
|
|
230
|
+
* Close the client
|
|
231
|
+
*/
|
|
232
|
+
close(): Promise<void>;
|
|
233
|
+
}
|
|
234
|
+
interface SendEmailOptions {
|
|
235
|
+
to: string | string[];
|
|
236
|
+
subject: string;
|
|
237
|
+
html?: string;
|
|
238
|
+
text?: string;
|
|
239
|
+
from?: string;
|
|
240
|
+
replyTo?: string;
|
|
241
|
+
cc?: string | string[];
|
|
242
|
+
bcc?: string | string[];
|
|
243
|
+
templateName?: string;
|
|
244
|
+
templateData?: Record<string, unknown>;
|
|
245
|
+
tags?: Record<string, string>;
|
|
246
|
+
scheduledAt?: string;
|
|
247
|
+
}
|
|
248
|
+
interface SendEmailResult {
|
|
249
|
+
success: boolean;
|
|
250
|
+
messageId?: string;
|
|
251
|
+
error?: string;
|
|
252
|
+
}
|
|
253
|
+
interface SendBatchOptions {
|
|
254
|
+
emails: Array<{
|
|
255
|
+
to: string | string[];
|
|
256
|
+
subject: string;
|
|
257
|
+
html?: string;
|
|
258
|
+
text?: string;
|
|
259
|
+
templateName?: string;
|
|
260
|
+
templateData?: Record<string, unknown>;
|
|
261
|
+
}>;
|
|
262
|
+
stopOnError?: boolean;
|
|
263
|
+
}
|
|
264
|
+
interface SendBatchResult {
|
|
265
|
+
total: number;
|
|
266
|
+
successful: number;
|
|
267
|
+
failed: number;
|
|
268
|
+
results: Array<{
|
|
269
|
+
success: boolean;
|
|
270
|
+
messageId?: string;
|
|
271
|
+
error?: string;
|
|
272
|
+
}>;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Create Email Service Client
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```typescript
|
|
279
|
+
* // Embedded mode (same process)
|
|
280
|
+
* const email = createEmailServiceClient();
|
|
281
|
+
*
|
|
282
|
+
* // HTTP mode (remote service)
|
|
283
|
+
* const email = createEmailServiceClient({
|
|
284
|
+
* mode: 'http',
|
|
285
|
+
* baseUrl: 'https://email.example.com',
|
|
286
|
+
* });
|
|
287
|
+
*
|
|
288
|
+
* // Send email
|
|
289
|
+
* const result = await email.send({
|
|
290
|
+
* to: 'user@example.com',
|
|
291
|
+
* subject: 'Hello',
|
|
292
|
+
* html: '<p>Hello World</p>',
|
|
293
|
+
* });
|
|
294
|
+
*
|
|
295
|
+
* // Use template
|
|
296
|
+
* const result = await email.send({
|
|
297
|
+
* to: 'user@example.com',
|
|
298
|
+
* subject: 'Welcome!',
|
|
299
|
+
* templateName: 'welcome',
|
|
300
|
+
* templateData: { name: 'John', loginUrl: 'https://app.com/login' },
|
|
301
|
+
* });
|
|
302
|
+
* ```
|
|
303
|
+
*/
|
|
304
|
+
declare function createEmailServiceClient(options?: ServiceClientOptions): EmailServiceClient;
|
|
305
|
+
|
|
306
|
+
export { type EmailServiceClient, type EmailServiceDefinition, type EmailServiceServerOptions, createEmailServiceClient, createEmailServiceServer, emailServiceDefinition };
|