@crossdelta/cloudevents 0.6.2 → 0.6.4
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/bin/cli.js +1226 -0
- package/dist/index.cjs +1508 -338
- package/dist/{index.d.mts → index.d.cts} +705 -52
- package/dist/index.d.ts +705 -52
- package/dist/index.js +1485 -331
- package/package.json +24 -10
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Context } from 'hono';
|
|
2
2
|
import { CloudEventV1 } from 'cloudevents';
|
|
3
3
|
import { ZodTypeAny, z } from 'zod';
|
|
4
|
+
import { ChangeResult, FlowContext, FsContextMixin, GenerationContextMixin, FlowStep } from '@crossdelta/flowcore';
|
|
5
|
+
import { PfPlugin } from '@crossdelta/platform-sdk';
|
|
4
6
|
import { ConsumerMessages, Subscription } from 'nats';
|
|
5
7
|
|
|
6
8
|
/**
|
|
@@ -46,6 +48,355 @@ interface CloudEventParseResult {
|
|
|
46
48
|
*/
|
|
47
49
|
declare const parseEventFromContext: (context: Context) => Promise<CloudEventParseResult>;
|
|
48
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Domain Effects
|
|
53
|
+
*
|
|
54
|
+
* Effects are pure DATA describing side effects that need to happen.
|
|
55
|
+
* They are produced by domain flows and consumed by runtime handlers.
|
|
56
|
+
*
|
|
57
|
+
* This enables:
|
|
58
|
+
* - Clean separation between domain logic (cloudevents) and runtime integration (pf)
|
|
59
|
+
* - Testability: flows return data, no side effects
|
|
60
|
+
* - MCP compatibility: effects can be returned to AI agents
|
|
61
|
+
*
|
|
62
|
+
* Naming Convention:
|
|
63
|
+
* - Kind: `<noun>.<past-participle>` (e.g., `stream.wired`, `contract.created`)
|
|
64
|
+
* - Type: `<Noun><PastParticiple>Effect` (e.g., `StreamWiredEffect`)
|
|
65
|
+
* - Factory: `<noun><PastParticiple>` (e.g., `streamWired()`)
|
|
66
|
+
*/
|
|
67
|
+
/**
|
|
68
|
+
* Effect: Stream was wired to a service
|
|
69
|
+
*
|
|
70
|
+
* Signals that a service should be configured to consume from a stream.
|
|
71
|
+
* Runtime handler will modify the service's entry point (index.ts/main.ts).
|
|
72
|
+
*/
|
|
73
|
+
interface StreamWiredEffect {
|
|
74
|
+
readonly kind: 'stream.wired';
|
|
75
|
+
readonly stream: string;
|
|
76
|
+
readonly servicePath: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Effect: Contract was created
|
|
80
|
+
*
|
|
81
|
+
* Signals that a new contract file was created.
|
|
82
|
+
* Runtime may need to invalidate caches or trigger rebuilds.
|
|
83
|
+
*/
|
|
84
|
+
interface ContractCreatedEffect {
|
|
85
|
+
readonly kind: 'contract.created';
|
|
86
|
+
readonly path: string;
|
|
87
|
+
readonly eventType: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Effect: Handler was created
|
|
91
|
+
*
|
|
92
|
+
* Signals that a new handler file was created.
|
|
93
|
+
* Runtime may need to update service configuration.
|
|
94
|
+
*/
|
|
95
|
+
interface HandlerCreatedEffect {
|
|
96
|
+
readonly kind: 'handler.created';
|
|
97
|
+
readonly path: string;
|
|
98
|
+
readonly eventType: string;
|
|
99
|
+
readonly servicePath: string;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Union of all domain effects
|
|
103
|
+
*
|
|
104
|
+
* Add new effect types here as the system grows.
|
|
105
|
+
* Effects are a discriminated union on `kind`.
|
|
106
|
+
*/
|
|
107
|
+
type DomainEffect = StreamWiredEffect | ContractCreatedEffect | HandlerCreatedEffect;
|
|
108
|
+
/**
|
|
109
|
+
* Create a stream.wired effect
|
|
110
|
+
*/
|
|
111
|
+
declare const streamWired: (stream: string, servicePath: string) => StreamWiredEffect;
|
|
112
|
+
/**
|
|
113
|
+
* Create a contract.created effect
|
|
114
|
+
*/
|
|
115
|
+
declare const contractCreated: (path: string, eventType: string) => ContractCreatedEffect;
|
|
116
|
+
/**
|
|
117
|
+
* Create a handler.created effect
|
|
118
|
+
*/
|
|
119
|
+
declare const handlerCreated: (path: string, eventType: string, servicePath: string) => HandlerCreatedEffect;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Generator Types
|
|
123
|
+
*
|
|
124
|
+
* Interfaces for file system abstraction and generator options
|
|
125
|
+
*/
|
|
126
|
+
/**
|
|
127
|
+
* File system abstraction for testing
|
|
128
|
+
*/
|
|
129
|
+
interface FileSystem {
|
|
130
|
+
readFile(path: string): string | null;
|
|
131
|
+
writeFile(path: string, content: string): void;
|
|
132
|
+
exists(path: string): boolean;
|
|
133
|
+
mkdir(path: string): void;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* In-memory file system for testing
|
|
137
|
+
*/
|
|
138
|
+
declare const createMemoryFileSystem: (initialFiles?: Record<string, string>) => FileSystem & {
|
|
139
|
+
files: Record<string, string>;
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Schema field definition for contract generation
|
|
143
|
+
*/
|
|
144
|
+
interface SchemaField {
|
|
145
|
+
name: string;
|
|
146
|
+
type: 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'array' | 'object';
|
|
147
|
+
optional?: boolean;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Options for contract generation
|
|
151
|
+
*/
|
|
152
|
+
interface GenerateContractOptions {
|
|
153
|
+
/** Event type (e.g., 'order.created') */
|
|
154
|
+
eventType: string;
|
|
155
|
+
/** Schema fields */
|
|
156
|
+
fields?: SchemaField[];
|
|
157
|
+
/** Base path for contracts (e.g., 'packages/contracts/src') */
|
|
158
|
+
basePath: string;
|
|
159
|
+
/** Package scope for imports (e.g., '@crossdelta') */
|
|
160
|
+
scope?: string;
|
|
161
|
+
/** Force overwrite existing files */
|
|
162
|
+
force?: boolean;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Options for event handler generation
|
|
166
|
+
*/
|
|
167
|
+
interface GenerateEventHandlerOptions {
|
|
168
|
+
/** Event type (e.g., 'order.created') */
|
|
169
|
+
eventType: string;
|
|
170
|
+
/** Base path for service (e.g., 'services/orders/src') */
|
|
171
|
+
basePath: string;
|
|
172
|
+
/** Contract package name (e.g., '@crossdelta/contracts') */
|
|
173
|
+
contractsPackage?: string;
|
|
174
|
+
/** Force overwrite existing files */
|
|
175
|
+
force?: boolean;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Options for mock generation
|
|
179
|
+
*/
|
|
180
|
+
interface GenerateMockOptions {
|
|
181
|
+
/** Event type (e.g., 'order.created') */
|
|
182
|
+
eventType: string;
|
|
183
|
+
/** Base path for mocks (e.g., 'packages/contracts/src/__mocks__') */
|
|
184
|
+
basePath: string;
|
|
185
|
+
/** Schema fields to generate mock data for */
|
|
186
|
+
fields?: SchemaField[];
|
|
187
|
+
/** Force overwrite existing files */
|
|
188
|
+
force?: boolean;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Contract Generator
|
|
193
|
+
*
|
|
194
|
+
* Pure function for generating event contract files
|
|
195
|
+
*/
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Generate contract file content
|
|
199
|
+
*/
|
|
200
|
+
declare const generateContractContent: (options: GenerateContractOptions) => string;
|
|
201
|
+
/**
|
|
202
|
+
* Get the full path for a contract file
|
|
203
|
+
*/
|
|
204
|
+
declare const getContractFilePath: (eventType: string, basePath: string) => string;
|
|
205
|
+
/**
|
|
206
|
+
* Generate a contract file
|
|
207
|
+
*
|
|
208
|
+
* Returns ChangeResult indicating if file was created, updated, or skipped.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* generateContract({
|
|
212
|
+
* eventType: 'order.created',
|
|
213
|
+
* basePath: 'packages/contracts/src',
|
|
214
|
+
* fields: [
|
|
215
|
+
* { name: 'orderId', type: 'string' },
|
|
216
|
+
* { name: 'total', type: 'number' },
|
|
217
|
+
* ],
|
|
218
|
+
* })
|
|
219
|
+
*/
|
|
220
|
+
declare const generateContract: (options: GenerateContractOptions, fs?: FileSystem) => ChangeResult<string>;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Handler Generator
|
|
224
|
+
*
|
|
225
|
+
* Pure function for generating event handler files
|
|
226
|
+
*/
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Generate handler file content
|
|
230
|
+
*/
|
|
231
|
+
declare const generateEventHandlerContent: (options: GenerateEventHandlerOptions) => string;
|
|
232
|
+
/**
|
|
233
|
+
* Get the full path for a handler file
|
|
234
|
+
*/
|
|
235
|
+
declare const getHandlerFilePath: (eventType: string, basePath: string) => string;
|
|
236
|
+
/**
|
|
237
|
+
* Generate an event handler file
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* generateEventHandler({
|
|
241
|
+
* eventType: 'order.created',
|
|
242
|
+
* basePath: 'services/orders/src',
|
|
243
|
+
* contractsPackage: '@my-org/contracts',
|
|
244
|
+
* })
|
|
245
|
+
*/
|
|
246
|
+
declare const generateEventHandler: (options: GenerateEventHandlerOptions, fs?: FileSystem) => ChangeResult<string>;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Mock Generator
|
|
250
|
+
*
|
|
251
|
+
* Pure functions for generating event mock files (TypeScript and JSON formats).
|
|
252
|
+
* Supports optional @faker-js/faker for realistic mock data.
|
|
253
|
+
*/
|
|
254
|
+
|
|
255
|
+
interface JsonMockData {
|
|
256
|
+
eventName: string;
|
|
257
|
+
description: string;
|
|
258
|
+
data: Record<string, unknown>;
|
|
259
|
+
faker?: Record<string, string>;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Initialize faker (call once at startup if you want faker support)
|
|
263
|
+
*/
|
|
264
|
+
declare const initFaker: () => Promise<boolean>;
|
|
265
|
+
/**
|
|
266
|
+
* Generate mock file content
|
|
267
|
+
*/
|
|
268
|
+
declare const generateMockContent: (options: GenerateMockOptions) => string;
|
|
269
|
+
/**
|
|
270
|
+
* Get the full path for a mock file
|
|
271
|
+
*/
|
|
272
|
+
declare const getMockFilePath: (eventType: string, basePath: string) => string;
|
|
273
|
+
/**
|
|
274
|
+
* Generate a mock file
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* generateMock({
|
|
278
|
+
* eventType: 'order.created',
|
|
279
|
+
* basePath: 'packages/contracts/src/__mocks__',
|
|
280
|
+
* fields: [
|
|
281
|
+
* { name: 'orderId', type: 'string' },
|
|
282
|
+
* { name: 'total', type: 'number' },
|
|
283
|
+
* ],
|
|
284
|
+
* })
|
|
285
|
+
*/
|
|
286
|
+
declare const generateMock: (options: GenerateMockOptions, fs?: FileSystem) => ChangeResult<string>;
|
|
287
|
+
/**
|
|
288
|
+
* Get the JSON mock file path for an event type
|
|
289
|
+
*/
|
|
290
|
+
declare const getJsonMockPath: (eventType: string, contractsPath: string) => string;
|
|
291
|
+
/**
|
|
292
|
+
* Check if a JSON mock file exists
|
|
293
|
+
*/
|
|
294
|
+
declare const jsonMockExists: (eventType: string, contractsPath: string, fs?: FileSystem) => boolean;
|
|
295
|
+
/**
|
|
296
|
+
* Load JSON mock data for an event type
|
|
297
|
+
*/
|
|
298
|
+
declare const loadJsonMock: (eventType: string, contractsPath: string, fs?: FileSystem) => JsonMockData | null;
|
|
299
|
+
/**
|
|
300
|
+
* Generate and save a JSON mock file for an event type
|
|
301
|
+
*/
|
|
302
|
+
declare const generateJsonMock: (options: {
|
|
303
|
+
eventType: string;
|
|
304
|
+
contractsPath: string;
|
|
305
|
+
fields?: SchemaField[];
|
|
306
|
+
force?: boolean;
|
|
307
|
+
/** Use @faker-js/faker for realistic data */
|
|
308
|
+
useFaker?: boolean;
|
|
309
|
+
}, fs?: FileSystem) => ChangeResult<string>;
|
|
310
|
+
/**
|
|
311
|
+
* Generate JSON mock from existing contract file
|
|
312
|
+
*/
|
|
313
|
+
declare const generateJsonMockFromContract: (eventType: string, contractsPath: string, options?: {
|
|
314
|
+
useFaker?: boolean;
|
|
315
|
+
}, fs?: FileSystem) => ChangeResult<string> | null;
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Simple options for creating an event
|
|
319
|
+
*/
|
|
320
|
+
interface CreateEventOptions {
|
|
321
|
+
/** Schema fields as string (e.g., 'orderId:string,total:number') or array */
|
|
322
|
+
fields?: string | SchemaField[];
|
|
323
|
+
/** Service path for handler (e.g., 'services/orders') */
|
|
324
|
+
service?: string;
|
|
325
|
+
/** Base path for contracts (default: 'packages/contracts/src') */
|
|
326
|
+
contractsPath?: string;
|
|
327
|
+
/** Base path for mocks (optional) */
|
|
328
|
+
mocksPath?: string;
|
|
329
|
+
/** Overwrite existing files */
|
|
330
|
+
force?: boolean;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Create an event contract (and optionally handler + mock)
|
|
334
|
+
*
|
|
335
|
+
* @example
|
|
336
|
+
* ```typescript
|
|
337
|
+
* import { createEvent } from '@crossdelta/cloudevents'
|
|
338
|
+
*
|
|
339
|
+
* // Simple: just the event type (interactive)
|
|
340
|
+
* await createEvent('order.created')
|
|
341
|
+
*
|
|
342
|
+
* // With fields
|
|
343
|
+
* await createEvent('order.created', {
|
|
344
|
+
* fields: 'orderId:string,total:number,customerId:string'
|
|
345
|
+
* })
|
|
346
|
+
*
|
|
347
|
+
* // With handler
|
|
348
|
+
* await createEvent('order.created', {
|
|
349
|
+
* fields: 'orderId:string,total:number',
|
|
350
|
+
* service: 'services/orders'
|
|
351
|
+
* })
|
|
352
|
+
* ```
|
|
353
|
+
*/
|
|
354
|
+
declare const createEvent: (eventType: string, options?: CreateEventOptions) => Promise<{
|
|
355
|
+
created: string[];
|
|
356
|
+
skipped: string[];
|
|
357
|
+
effects: DomainEffect[];
|
|
358
|
+
}>;
|
|
359
|
+
/**
|
|
360
|
+
* List all event types in the workspace
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* ```typescript
|
|
364
|
+
* import { listEvents } from '@crossdelta/cloudevents'
|
|
365
|
+
*
|
|
366
|
+
* // List all
|
|
367
|
+
* const events = await listEvents()
|
|
368
|
+
* // ['order.created', 'order.updated', 'customer.created']
|
|
369
|
+
*
|
|
370
|
+
* // Filter by pattern
|
|
371
|
+
* const orderEvents = await listEvents({ pattern: 'order' })
|
|
372
|
+
* // ['order.created', 'order.updated']
|
|
373
|
+
* ```
|
|
374
|
+
*/
|
|
375
|
+
declare const listEvents: (options?: {
|
|
376
|
+
pattern?: string;
|
|
377
|
+
contractsPath?: string;
|
|
378
|
+
}) => Promise<string[]>;
|
|
379
|
+
/**
|
|
380
|
+
* Publish an event to NATS
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* ```typescript
|
|
384
|
+
* import { publishEvent } from '@crossdelta/cloudevents'
|
|
385
|
+
*
|
|
386
|
+
* await publishEvent('order.created', {
|
|
387
|
+
* orderId: 'ord_123',
|
|
388
|
+
* total: 99.99,
|
|
389
|
+
* customerId: 'cus_456'
|
|
390
|
+
* })
|
|
391
|
+
* ```
|
|
392
|
+
*/
|
|
393
|
+
declare const publishEvent: (eventType: string, data: Record<string, unknown>, options?: {
|
|
394
|
+
natsUrl?: string;
|
|
395
|
+
contractsPath?: string;
|
|
396
|
+
}) => Promise<{
|
|
397
|
+
success: boolean;
|
|
398
|
+
}>;
|
|
399
|
+
|
|
49
400
|
/**
|
|
50
401
|
* Domain Types
|
|
51
402
|
*
|
|
@@ -254,6 +605,185 @@ declare function eventSchema<T extends Record<string, ZodTypeAny>>(schema: T & {
|
|
|
254
605
|
type: ZodTypeAny;
|
|
255
606
|
} extends infer T_1 ? { -readonly [P in keyof T_1]: T_1[P]; } : never, z.core.$strip>;
|
|
256
607
|
|
|
608
|
+
/**
|
|
609
|
+
* Pluralization Utilities
|
|
610
|
+
*
|
|
611
|
+
* Re-exports from the 'pluralize' library for consistent pluralization.
|
|
612
|
+
* Used by both cloudevents (subject derivation) and platform-sdk (contract generation).
|
|
613
|
+
*/
|
|
614
|
+
/**
|
|
615
|
+
* Convert singular word to plural
|
|
616
|
+
*
|
|
617
|
+
* @example pluralize('order') => 'orders'
|
|
618
|
+
* @example pluralize('policy') => 'policies'
|
|
619
|
+
* @example pluralize('max') => 'maxes'
|
|
620
|
+
* @example pluralize('batch') => 'batches'
|
|
621
|
+
* @example pluralize('bus') => 'buses'
|
|
622
|
+
* @example pluralize('products') => 'products' (already plural)
|
|
623
|
+
*/
|
|
624
|
+
declare const pluralize: (word: string) => string;
|
|
625
|
+
/**
|
|
626
|
+
* Convert plural word to singular
|
|
627
|
+
*
|
|
628
|
+
* @example singularize('orders') => 'order'
|
|
629
|
+
* @example singularize('policies') => 'policy'
|
|
630
|
+
* @example singularize('maxes') => 'max'
|
|
631
|
+
* @example singularize('batches') => 'batch'
|
|
632
|
+
*/
|
|
633
|
+
declare const singularize: (word: string) => string;
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Event Naming Domain
|
|
637
|
+
*
|
|
638
|
+
* Central authority for all event naming conventions:
|
|
639
|
+
* - Event type format and validation
|
|
640
|
+
* - Pluralization rules for streams/domains
|
|
641
|
+
* - Name derivation (schema, contract, handler, etc.)
|
|
642
|
+
* - Path structure for contracts and handlers
|
|
643
|
+
*/
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Derived names from an event type
|
|
647
|
+
*/
|
|
648
|
+
interface EventNames {
|
|
649
|
+
/** Original event type (e.g., 'order.created') */
|
|
650
|
+
eventType: string;
|
|
651
|
+
/** Event type in kebab-case (e.g., 'order-created') */
|
|
652
|
+
kebab: string;
|
|
653
|
+
/** Event type in PascalCase (e.g., 'OrderCreated') */
|
|
654
|
+
pascal: string;
|
|
655
|
+
/** Schema name - singular PascalCase (e.g., 'OrderCreatedSchema') */
|
|
656
|
+
schemaName: string;
|
|
657
|
+
/** Type name - singular PascalCase (e.g., 'OrderCreatedData') */
|
|
658
|
+
typeName: string;
|
|
659
|
+
/** Contract name - plural PascalCase (e.g., 'OrdersCreatedContract') */
|
|
660
|
+
contractName: string;
|
|
661
|
+
/** Handler filename (e.g., 'order-created.handler.ts') */
|
|
662
|
+
handlerFile: string;
|
|
663
|
+
/** Stream name - uppercase plural (e.g., 'ORDERS') */
|
|
664
|
+
streamName: string;
|
|
665
|
+
/** Domain folder - lowercase plural (e.g., 'customers') */
|
|
666
|
+
domain: string;
|
|
667
|
+
/** Event action part (e.g., 'created' from 'order.created') */
|
|
668
|
+
action: string;
|
|
669
|
+
/** Namespace part - singular (e.g., 'order' from 'order.created') */
|
|
670
|
+
namespace: string;
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Event type validation result
|
|
674
|
+
*/
|
|
675
|
+
interface EventTypeValidation {
|
|
676
|
+
valid: boolean;
|
|
677
|
+
errors: string[];
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Contract file path structure
|
|
681
|
+
*/
|
|
682
|
+
interface ContractPaths {
|
|
683
|
+
/** Relative path from contracts root (e.g., 'events/orders/created.ts') */
|
|
684
|
+
relativePath: string;
|
|
685
|
+
/** Domain folder (e.g., 'orders') */
|
|
686
|
+
folder: string;
|
|
687
|
+
/** Filename without extension (e.g., 'created') */
|
|
688
|
+
filename: string;
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Convert string to kebab-case
|
|
692
|
+
* Handles dots as separators
|
|
693
|
+
*/
|
|
694
|
+
declare const toKebabCase: (str: string) => string;
|
|
695
|
+
/**
|
|
696
|
+
* Convert string to PascalCase
|
|
697
|
+
* Handles dots and dashes as word separators
|
|
698
|
+
*/
|
|
699
|
+
declare const toPascalCase: (str: string) => string;
|
|
700
|
+
/**
|
|
701
|
+
* Validate an event type string
|
|
702
|
+
*
|
|
703
|
+
* Rules:
|
|
704
|
+
* - Must contain at least one dot (namespace.action)
|
|
705
|
+
* - Must be lowercase
|
|
706
|
+
* - Must not start/end with dots
|
|
707
|
+
* - Namespace must be singular (will be pluralized for domain)
|
|
708
|
+
*/
|
|
709
|
+
declare const validateEventType: (eventType: string) => EventTypeValidation;
|
|
710
|
+
/**
|
|
711
|
+
* Check if an event type is valid
|
|
712
|
+
*/
|
|
713
|
+
declare const isValidEventType: (eventType: string) => boolean;
|
|
714
|
+
/**
|
|
715
|
+
* Derive all names from an event type
|
|
716
|
+
*
|
|
717
|
+
* @example
|
|
718
|
+
* deriveEventNames('order.created')
|
|
719
|
+
* // {
|
|
720
|
+
* // eventType: 'order.created',
|
|
721
|
+
* // kebab: 'order-created',
|
|
722
|
+
* // pascal: 'OrderCreated',
|
|
723
|
+
* // schemaName: 'OrderCreatedSchema',
|
|
724
|
+
* // typeName: 'OrderCreatedData',
|
|
725
|
+
* // contractName: 'OrdersCreatedContract',
|
|
726
|
+
* // handlerFile: 'order-created.handler.ts',
|
|
727
|
+
* // streamName: 'ORDERS',
|
|
728
|
+
* // domain: 'orders',
|
|
729
|
+
* // action: 'created',
|
|
730
|
+
* // namespace: 'order',
|
|
731
|
+
* // }
|
|
732
|
+
*/
|
|
733
|
+
declare const deriveEventNames: (eventType: string) => EventNames;
|
|
734
|
+
/**
|
|
735
|
+
* Get contract file paths from an event type
|
|
736
|
+
*
|
|
737
|
+
* @example
|
|
738
|
+
* getContractPaths('order.created')
|
|
739
|
+
* // {
|
|
740
|
+
* // relativePath: 'events/orders/created.ts',
|
|
741
|
+
* // folder: 'orders',
|
|
742
|
+
* // filename: 'created',
|
|
743
|
+
* // }
|
|
744
|
+
*/
|
|
745
|
+
declare const getContractPaths: (eventType: string) => ContractPaths;
|
|
746
|
+
/**
|
|
747
|
+
* Get handler file path from an event type
|
|
748
|
+
*
|
|
749
|
+
* @example
|
|
750
|
+
* getHandlerPath('order.created')
|
|
751
|
+
* // 'events/order-created.handler.ts'
|
|
752
|
+
*/
|
|
753
|
+
declare const getHandlerPath: (eventType: string) => string;
|
|
754
|
+
/**
|
|
755
|
+
* Get stream name from an event type
|
|
756
|
+
*
|
|
757
|
+
* @example
|
|
758
|
+
* getStreamName('order.created') // 'ORDERS'
|
|
759
|
+
* getStreamName('customer.updated') // 'CUSTOMERS'
|
|
760
|
+
*/
|
|
761
|
+
declare const getStreamName: (eventType: string) => string;
|
|
762
|
+
/**
|
|
763
|
+
* Parse an event type from a handler filename
|
|
764
|
+
*
|
|
765
|
+
* @example
|
|
766
|
+
* parseEventTypeFromHandler('order-created.handler.ts') // 'order.created'
|
|
767
|
+
* parseEventTypeFromHandler('customer-profile-updated.handler.ts') // 'customer-profile.updated'
|
|
768
|
+
*/
|
|
769
|
+
declare const parseEventTypeFromHandler: (filename: string) => string | null;
|
|
770
|
+
/**
|
|
771
|
+
* Parse an event type from a contract filename
|
|
772
|
+
*
|
|
773
|
+
* @example
|
|
774
|
+
* parseEventTypeFromContract('orders/created.ts') // 'order.created'
|
|
775
|
+
* parseEventTypeFromContract('customers/profile-updated.ts') // 'customer.profile-updated'
|
|
776
|
+
*/
|
|
777
|
+
declare const parseEventTypeFromContract: (path: string) => string | null;
|
|
778
|
+
/**
|
|
779
|
+
* Normalize subject from event type
|
|
780
|
+
* Used for NATS subject derivation
|
|
781
|
+
*
|
|
782
|
+
* @example
|
|
783
|
+
* normalizeSubject('order.created') // 'orders.created'
|
|
784
|
+
*/
|
|
785
|
+
declare const normalizeSubject: (eventType: string) => string;
|
|
786
|
+
|
|
257
787
|
/**
|
|
258
788
|
* Domain Validation
|
|
259
789
|
*
|
|
@@ -269,6 +799,150 @@ declare function eventSchema<T extends Record<string, ZodTypeAny>>(schema: T & {
|
|
|
269
799
|
*/
|
|
270
800
|
declare const extractTypeFromSchema: (schema: ZodTypeAny) => string | undefined;
|
|
271
801
|
|
|
802
|
+
/**
|
|
803
|
+
* Create Event Flow
|
|
804
|
+
*
|
|
805
|
+
* Interactive flow for creating event contracts, handlers, and mocks
|
|
806
|
+
*/
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Configuration for event flows
|
|
810
|
+
*/
|
|
811
|
+
interface FlowConfig$2 {
|
|
812
|
+
/** Base path for contracts (e.g., 'packages/contracts/src') */
|
|
813
|
+
contractsPath: string;
|
|
814
|
+
/** Base path for mocks (e.g., 'packages/contracts/src/__mocks__') */
|
|
815
|
+
mocksPath?: string;
|
|
816
|
+
/** Contracts package name (e.g., '@my-platform/contracts') */
|
|
817
|
+
contractsPackage?: string;
|
|
818
|
+
/** File system abstraction (defaults to node fs) */
|
|
819
|
+
fs?: FileSystem;
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Context for create event flow
|
|
823
|
+
*
|
|
824
|
+
* Flow-specific fields (user-provided):
|
|
825
|
+
* - eventType: Event name like "order.created"
|
|
826
|
+
* - servicePath: Optional service for handler creation
|
|
827
|
+
* - fieldsInput: Raw input string from user (internal)
|
|
828
|
+
* - fields: Parsed schema fields
|
|
829
|
+
* - availableServices: Services available for handler creation
|
|
830
|
+
* - force: Overwrite existing files
|
|
831
|
+
* - config: Flow configuration (paths, fs)
|
|
832
|
+
*
|
|
833
|
+
* Infrastructure fields (auto-initialized by ensure() steps):
|
|
834
|
+
* - _fs: Filesystem abstraction (lazy-init via flow.ensure())
|
|
835
|
+
* - _generation: Generation tracker (lazy-init via flow.ensure())
|
|
836
|
+
*
|
|
837
|
+
* @see FsContextMixin for _fs details
|
|
838
|
+
* @see GenerationContextMixin for _generation details
|
|
839
|
+
*/
|
|
840
|
+
interface CreateEventContext extends FlowContext, FsContextMixin, GenerationContextMixin<DomainEffect> {
|
|
841
|
+
/** Event type (e.g., 'order.created') */
|
|
842
|
+
eventType: string;
|
|
843
|
+
/** Service path for handler generation */
|
|
844
|
+
servicePath?: string;
|
|
845
|
+
/** Schema fields as comma-separated string */
|
|
846
|
+
fieldsInput?: string;
|
|
847
|
+
/** Parsed schema fields */
|
|
848
|
+
fields?: Array<{
|
|
849
|
+
name: string;
|
|
850
|
+
type: string;
|
|
851
|
+
optional?: boolean;
|
|
852
|
+
}>;
|
|
853
|
+
/** Available services for selection */
|
|
854
|
+
availableServices?: string[];
|
|
855
|
+
/** Force overwrite existing files */
|
|
856
|
+
force?: boolean;
|
|
857
|
+
/** Flow configuration */
|
|
858
|
+
config: FlowConfig$2;
|
|
859
|
+
/** Internal filesystem (lazy-initialized) */
|
|
860
|
+
_fs?: FileSystem;
|
|
861
|
+
}
|
|
862
|
+
declare const parseFieldsInput: (input: string) => SchemaField[];
|
|
863
|
+
/**
|
|
864
|
+
* Complete flow for creating event contracts
|
|
865
|
+
*
|
|
866
|
+
* Steps:
|
|
867
|
+
* 1. Initialize infrastructure (_fs, _generation)
|
|
868
|
+
* 2. Get event type (e.g., "order.created")
|
|
869
|
+
* 3. Get schema fields (optional)
|
|
870
|
+
* 4. Select service for handler (optional)
|
|
871
|
+
* 5. Generate files (contract, mock, handler, exports)
|
|
872
|
+
* 6. Print summary
|
|
873
|
+
*/
|
|
874
|
+
declare const createEventFlowSteps: FlowStep<CreateEventContext>[];
|
|
875
|
+
|
|
876
|
+
/**
|
|
877
|
+
* List Events Flow
|
|
878
|
+
*
|
|
879
|
+
* Flow for discovering and listing event types in the workspace
|
|
880
|
+
*/
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* Configuration for event flows
|
|
884
|
+
*/
|
|
885
|
+
interface FlowConfig$1 {
|
|
886
|
+
/** Base path for contracts (e.g., 'packages/contracts/src') */
|
|
887
|
+
contractsPath: string;
|
|
888
|
+
/** Base path for mocks (e.g., 'packages/contracts/src/__mocks__') */
|
|
889
|
+
mocksPath?: string;
|
|
890
|
+
/** Contracts package name (e.g., '@my-platform/contracts') */
|
|
891
|
+
contractsPackage?: string;
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Context for list events flow
|
|
895
|
+
*/
|
|
896
|
+
interface ListEventsContext extends FlowContext {
|
|
897
|
+
/** Filter pattern for event types */
|
|
898
|
+
pattern?: string;
|
|
899
|
+
/** Discovered event types */
|
|
900
|
+
eventTypes?: string[];
|
|
901
|
+
/** Flow configuration */
|
|
902
|
+
config: FlowConfig$1;
|
|
903
|
+
}
|
|
904
|
+
declare const discoverEventTypes: (contractsPath: string, pattern?: string) => string[];
|
|
905
|
+
declare const listEventsFlowSteps: FlowStep<ListEventsContext>[];
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* Publish Event Flow
|
|
909
|
+
*
|
|
910
|
+
* Flow for publishing events to NATS
|
|
911
|
+
*/
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* Configuration for event flows
|
|
915
|
+
*/
|
|
916
|
+
interface FlowConfig {
|
|
917
|
+
/** Base path for contracts (e.g., 'packages/contracts/src') */
|
|
918
|
+
contractsPath: string;
|
|
919
|
+
/** NATS connection URL */
|
|
920
|
+
natsUrl?: string;
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Context for publish event flow
|
|
924
|
+
*/
|
|
925
|
+
interface PublishEventContext extends FlowContext {
|
|
926
|
+
/** Event type to publish */
|
|
927
|
+
eventType: string;
|
|
928
|
+
/** Event data as JSON string */
|
|
929
|
+
dataInput?: string;
|
|
930
|
+
/** Parsed event data */
|
|
931
|
+
data?: Record<string, unknown>;
|
|
932
|
+
/** NATS connection URL */
|
|
933
|
+
natsUrl?: string;
|
|
934
|
+
/** Whether publish was successful */
|
|
935
|
+
published?: boolean;
|
|
936
|
+
/** Whether mock data was used */
|
|
937
|
+
usedMock?: boolean;
|
|
938
|
+
/** Flow configuration */
|
|
939
|
+
config: FlowConfig & {
|
|
940
|
+
natsUrl?: string;
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
declare const parseDataInput: (input: string) => Record<string, unknown> | null;
|
|
944
|
+
declare const publishEventFlowSteps: FlowStep<PublishEventContext>[];
|
|
945
|
+
|
|
272
946
|
/**
|
|
273
947
|
* Handler Cache Management
|
|
274
948
|
* Immutable cache operations for CloudEvents handlers
|
|
@@ -502,12 +1176,42 @@ interface CloudEventsOptions {
|
|
|
502
1176
|
*/
|
|
503
1177
|
declare function cloudEvents(options?: CloudEventsOptions): (ctx: Context, next: () => Promise<void>) => Promise<void | Response>;
|
|
504
1178
|
|
|
1179
|
+
/**
|
|
1180
|
+
* PfPlugin Adapter
|
|
1181
|
+
*
|
|
1182
|
+
* Exposes cloudevents functionality as a pf plugin.
|
|
1183
|
+
* Architectural rules:
|
|
1184
|
+
* - cloudevents IMPORTS Pf* interfaces from platform-sdk
|
|
1185
|
+
* - Uses flows for all commands (CLI + MCP)
|
|
1186
|
+
* - Returns effects for workspace mutations
|
|
1187
|
+
*/
|
|
1188
|
+
|
|
1189
|
+
interface CloudEventsPfPluginOptions {
|
|
1190
|
+
contractsPath?: string;
|
|
1191
|
+
contractsPackage?: string;
|
|
1192
|
+
mocksPath?: string;
|
|
1193
|
+
availableServices?: string[];
|
|
1194
|
+
natsUrl?: string;
|
|
1195
|
+
}
|
|
1196
|
+
declare const createPfPlugin: (options?: CloudEventsPfPluginOptions) => PfPlugin;
|
|
1197
|
+
|
|
505
1198
|
interface PublishNatsEventOptions {
|
|
506
1199
|
servers?: string;
|
|
507
1200
|
source?: string;
|
|
508
1201
|
subject?: string;
|
|
509
1202
|
tenantId?: string;
|
|
1203
|
+
/** Close connection after publishing (for CLI tools) */
|
|
1204
|
+
closeAfterPublish?: boolean;
|
|
510
1205
|
}
|
|
1206
|
+
/**
|
|
1207
|
+
* Close the NATS connection and reset state
|
|
1208
|
+
*/
|
|
1209
|
+
declare const closeConnection: () => Promise<void>;
|
|
1210
|
+
/**
|
|
1211
|
+
* Reset publisher state (for testing only)
|
|
1212
|
+
* @internal
|
|
1213
|
+
*/
|
|
1214
|
+
declare const __resetNatsPublisher: () => Promise<void>;
|
|
511
1215
|
declare const deriveSubjectFromType: (eventType: string, config?: RoutingConfig) => string;
|
|
512
1216
|
declare const deriveStreamFromType: (eventType: string, config?: RoutingConfig) => string | undefined;
|
|
513
1217
|
declare const publishNatsRawEvent: (subjectName: string, eventType: string, eventData: unknown, options?: PublishNatsEventOptions) => Promise<string>;
|
|
@@ -518,7 +1222,6 @@ declare const publish: (eventTypeOrContract: string | {
|
|
|
518
1222
|
subject?: string;
|
|
519
1223
|
};
|
|
520
1224
|
}, eventData: unknown, options?: PublishNatsEventOptions) => Promise<string>;
|
|
521
|
-
declare const __resetNatsPublisher: () => void;
|
|
522
1225
|
|
|
523
1226
|
interface PublishEventOptions {
|
|
524
1227
|
projectId?: string;
|
|
@@ -527,26 +1230,6 @@ interface PublishEventOptions {
|
|
|
527
1230
|
subject?: string;
|
|
528
1231
|
attributes?: Record<string, string>;
|
|
529
1232
|
}
|
|
530
|
-
/**
|
|
531
|
-
* Publishes an event using a Zod schema for validation and type extraction.
|
|
532
|
-
* Automatically extracts the event type from the schema and creates a CloudEvent.
|
|
533
|
-
*
|
|
534
|
-
* @param topicName - PubSub topic name
|
|
535
|
-
* @param schema - Zod schema that defines the event structure and type
|
|
536
|
-
* @param eventData - Event data that must match the schema
|
|
537
|
-
* @param options - Optional PubSub configuration
|
|
538
|
-
* @returns Promise resolving to the published message ID
|
|
539
|
-
*
|
|
540
|
-
* @example
|
|
541
|
-
* ```typescript
|
|
542
|
-
* await publishEvent(
|
|
543
|
-
* 'customer-events',
|
|
544
|
-
* CustomerCreatedSchema,
|
|
545
|
-
* { customer: { id: '123', email: 'test@example.com' } }
|
|
546
|
-
* )
|
|
547
|
-
* ```
|
|
548
|
-
*/
|
|
549
|
-
declare function publishEvent<T extends ZodTypeAny>(topicName: string, schema: T, eventData: unknown, options?: PublishEventOptions): Promise<string>;
|
|
550
1233
|
/**
|
|
551
1234
|
* Raw event publisher - bypasses schema validation.
|
|
552
1235
|
* Use this when you need direct control over the event type and data.
|
|
@@ -809,34 +1492,4 @@ interface NatsConsumerOptions extends Pick<CloudEventsOptions, 'quarantineTopic'
|
|
|
809
1492
|
*/
|
|
810
1493
|
declare function consumeNatsEvents(options: NatsConsumerOptions): Promise<Subscription>;
|
|
811
1494
|
|
|
812
|
-
|
|
813
|
-
* Pluralization Utilities
|
|
814
|
-
*
|
|
815
|
-
* Central place for English pluralization rules.
|
|
816
|
-
* Used by both cloudevents (subject derivation) and platform-sdk (contract generation).
|
|
817
|
-
*
|
|
818
|
-
* Rules follow standard English grammar:
|
|
819
|
-
* - consonant + y → ies (policy → policies)
|
|
820
|
-
* - s, sh, ch, x → +es (max → maxes, batch → batches)
|
|
821
|
-
* - all other → +s (order → orders)
|
|
822
|
-
*/
|
|
823
|
-
/**
|
|
824
|
-
* Convert singular word to plural
|
|
825
|
-
*
|
|
826
|
-
* @example pluralize('order') => 'orders'
|
|
827
|
-
* @example pluralize('policy') => 'policies'
|
|
828
|
-
* @example pluralize('max') => 'maxes'
|
|
829
|
-
* @example pluralize('batch') => 'batches'
|
|
830
|
-
*/
|
|
831
|
-
declare const pluralize: (word: string) => string;
|
|
832
|
-
/**
|
|
833
|
-
* Convert plural word to singular (inverse of pluralize)
|
|
834
|
-
*
|
|
835
|
-
* @example singularize('orders') => 'order'
|
|
836
|
-
* @example singularize('policies') => 'policy'
|
|
837
|
-
* @example singularize('maxes') => 'max'
|
|
838
|
-
* @example singularize('batches') => 'batch'
|
|
839
|
-
*/
|
|
840
|
-
declare const singularize: (word: string) => string;
|
|
841
|
-
|
|
842
|
-
export { type ChannelConfig, type ChannelMetadata, type EnrichedEvent, type EventContext, type HandleEventOptions, type IdempotencyStore, type InferEventData, type JetStreamConsumerOptions, type JetStreamStreamOptions, type JetStreamStreamsConsumerOptions, type JetStreamStreamsOptions, type PublishEventOptions, type PublishNatsEventOptions, type RoutingConfig, type StreamConfig, type StreamDefinition, __resetNatsPublisher, checkAndMarkProcessed, clearHandlerCache, cloudEvents, consumeJetStreamEvents, consumeJetStreamStreams, consumeJetStreams, consumeNatsEvents, createContract, createInMemoryIdempotencyStore, deriveStreamFromType, deriveSubjectFromType, ensureJetStreamStream, ensureJetStreamStreams, ensureJetStreams, eventSchema, extractTypeFromSchema, getDefaultIdempotencyStore, handleEvent, parseEventFromContext, pluralize, publish, publishEvent, publishNatsEvent, publishNatsRawEvent, publishRawEvent, resetDefaultIdempotencyStore, singularize };
|
|
1495
|
+
export { type ChannelConfig, type ChannelMetadata, type CloudEventsPfPluginOptions, type ContractCreatedEffect, type ContractPaths, type CreateEventContext, type CreateEventOptions, type DomainEffect, type EnrichedEvent, type EventContext, type EventNames, type EventTypeValidation, type FileSystem, type HandleEventOptions, type HandlerCreatedEffect, type IdempotencyStore, type InferEventData, type JetStreamConsumerOptions, type JetStreamStreamOptions, type JetStreamStreamsConsumerOptions, type JetStreamStreamsOptions, type ListEventsContext, type PublishEventContext, type PublishEventOptions, type PublishNatsEventOptions, type RoutingConfig, type SchemaField, type StreamConfig, type StreamDefinition, type StreamWiredEffect, __resetNatsPublisher, checkAndMarkProcessed, clearHandlerCache, closeConnection, cloudEvents, consumeJetStreamEvents, consumeJetStreamStreams, consumeJetStreams, consumeNatsEvents, contractCreated, createContract, createEvent, createEventFlowSteps, createInMemoryIdempotencyStore, createMemoryFileSystem, createPfPlugin, deriveEventNames, deriveStreamFromType, deriveSubjectFromType, discoverEventTypes, ensureJetStreamStream, ensureJetStreamStreams, ensureJetStreams, eventSchema, extractTypeFromSchema, generateContract, generateContractContent, generateEventHandler, generateEventHandlerContent, generateJsonMock, generateJsonMockFromContract, generateMock, generateMockContent, getContractFilePath, getContractPaths, getDefaultIdempotencyStore, getHandlerFilePath, getHandlerPath, getJsonMockPath, getMockFilePath, getStreamName, handleEvent, handlerCreated, initFaker, isValidEventType, jsonMockExists, listEvents, listEventsFlowSteps, loadJsonMock, normalizeSubject, parseDataInput, parseEventFromContext, parseEventTypeFromContract, parseEventTypeFromHandler, parseFieldsInput, pluralize, publish, publishEvent, publishEventFlowSteps, publishNatsEvent, publishNatsRawEvent, publishRawEvent, resetDefaultIdempotencyStore, singularize, streamWired, toKebabCase, toPascalCase, validateEventType };
|