@crossdelta/platform-sdk 0.3.38 → 0.3.40

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 CHANGED
@@ -156,7 +156,7 @@ my-platform/
156
156
 
157
157
  ## ⚡ Event-Driven Architecture
158
158
 
159
- Every workspace includes **NATS + JetStream** for event-driven microservices communication using **[`@crossdelta/cloudevents`](https://github.com/orderboss/platform/tree/main/packages/cloudevents)**:
159
+ Every workspace includes **NATS + JetStream** for event-driven microservices communication using **[`@crossdelta/cloudevents`](https://www.npmjs.com/package/@crossdelta/cloudevents)**:
160
160
 
161
161
  - 🎯 **Type-safe event handlers** with Zod schemas
162
162
  - 🔄 **Auto-discovery** of event handlers (`*.event.ts` files)
@@ -2,7 +2,13 @@
2
2
 
3
3
  ## Architecture Overview
4
4
 
5
- Bun-based **monorepo** (Turborepo) with event-driven microservices:
5
+ Bun-based **monorepo** (Tu }).optional(),
6
+ })
7
+
8
+ // Export type for use in use-cases
9
+ export type OrderCreatedEvent = z.infer<typeof OrderCreatedSchema>
10
+
11
+ export default handleEvent() with event-driven microservices:
6
12
 
7
13
  | Directory | Stack | Purpose |
8
14
  |-----------|-------|---------|
@@ -86,7 +92,6 @@ import { z } from 'zod'
86
92
  import { sendNotification } from '../use-cases/send-notification.use-case'
87
93
 
88
94
  const OrderCreatedSchema = z.object({
89
- type: z.literal('orders.created'),
90
95
  orderId: z.string(),
91
96
  customerId: z.string(),
92
97
  total: z.number(),
@@ -99,12 +104,30 @@ const OrderCreatedSchema = z.object({
99
104
  ).optional(),
100
105
  })
101
106
 
102
- export default handleEvent(OrderCreatedSchema, async (data) => {
103
- await sendNotification(data)
104
- })
107
+ // Export type for reuse in other services
108
+ export type OrderCreatedEvent = z.infer<typeof OrderCreatedSchema>
109
+
110
+ export default handleEvent(
111
+ {
112
+ schema: OrderCreatedSchema,
113
+ type: 'orders.created',
114
+ },
115
+ async (data) => {
116
+ await sendNotification(data)
117
+ },
118
+ )
105
119
  ```
106
120
 
107
- **Schema naming:** Use PascalCase for schema constants (e.g., `OrderCreatedSchema`, `UserUpdatedSchema`)
121
+ **Important:**
122
+ - **Schema** validates only the event data payload (without `type` field)
123
+ - **Event type** is declared in the options object, not in the schema
124
+ - Event type matches the first parameter of `publish()` (e.g., `'orders.created'`)
125
+ - Do NOT include `type: z.literal('...')` in the schema - it's redundant and causes validation errors
126
+ - **Always export the inferred type** using `export type EventName = z.infer<typeof EventSchema>` for use in use-cases
127
+
128
+ **Naming conventions:**
129
+ - Schema constants: PascalCase with `Schema` suffix (e.g., `OrderCreatedSchema`, `UserUpdatedSchema`)
130
+ - Exported types: PascalCase with `Event` suffix (e.g., `OrderCreatedEvent`, `UserUpdatedEvent`)
108
131
 
109
132
  ### Service Folder Structure
110
133
 
@@ -249,12 +272,46 @@ Format source files with path headers. Paths are relative to the service directo
249
272
 
250
273
  #### `src/handlers/event-name.event.ts`
251
274
  ```typescript
252
- // event handler code
275
+ import { handleEvent } from '@crossdelta/cloudevents'
276
+ import { z } from 'zod'
277
+ import { businessLogic } from '../use-cases/business-logic.use-case'
278
+
279
+ const EventDataSchema = z.object({
280
+ id: z.string(),
281
+ // ... other fields
282
+ })
283
+
284
+ // Export type for use in use-cases
285
+ export type EventDataType = z.infer<typeof EventDataSchema>
286
+
287
+ export default handleEvent(
288
+ {
289
+ schema: EventDataSchema,
290
+ type: 'resource.action', // e.g., 'orders.created', 'users.updated'
291
+ },
292
+ async (data) => {
293
+ await businessLogic(data)
294
+ },
295
+ )
253
296
  ```
254
297
 
255
298
  #### `src/use-cases/business-logic.use-case.ts`
256
299
  ```typescript
257
- // business logic code
300
+ import type { EventDataType } from '../handlers/event-name.event'
301
+
302
+ /**
303
+ * Business logic that processes the event data.
304
+ * Uses the exported type from the handler for type safety.
305
+ */
306
+ export async function businessLogic(data: EventDataType): Promise<void> {
307
+ // Full type inference from the handler schema
308
+ console.log('Processing:', data.id)
309
+
310
+ // All business logic here
311
+ // - Validation
312
+ // - External API calls
313
+ // - Database operations
314
+ }
258
315
  ```
259
316
 
260
317
  ### Tests
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossdelta/platform-sdk",
3
- "version": "0.3.38",
3
+ "version": "0.3.40",
4
4
  "description": "CLI toolkit for scaffolding Turborepo workspaces with Pulumi infrastructure and Hono/NestJS microservices",
5
5
  "keywords": [
6
6
  "cli",