@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 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 };