@ductape/sdk 0.1.26 → 0.1.27

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.
Files changed (152) hide show
  1. package/README.md +83 -52
  2. package/dist/agents/agent-context.d.ts +1 -1
  3. package/dist/agents/agent-context.js +1 -1
  4. package/dist/agents/agent-context.js.map +1 -1
  5. package/dist/agents/agents.service.js +4 -4
  6. package/dist/agents/agents.service.js.map +1 -1
  7. package/dist/agents/types/agents.types.d.ts +6 -6
  8. package/dist/api/services/featureApi.service.d.ts +199 -0
  9. package/dist/api/services/featureApi.service.js +201 -0
  10. package/dist/api/services/featureApi.service.js.map +1 -0
  11. package/dist/api/services/processorApi.service.d.ts +2 -2
  12. package/dist/api/services/processorApi.service.js +1 -1
  13. package/dist/api/services/productsApi.service.d.ts +6 -6
  14. package/dist/api/services/productsApi.service.js +3 -3
  15. package/dist/api/services/productsApi.service.js.map +1 -1
  16. package/dist/api/urls.d.ts +12 -12
  17. package/dist/api/urls.js +22 -22
  18. package/dist/api/urls.js.map +1 -1
  19. package/dist/apps/validators/index.d.ts +5 -1
  20. package/dist/apps/validators/index.js +9 -1
  21. package/dist/apps/validators/index.js.map +1 -1
  22. package/dist/apps/validators/joi-validators/create.appWebhook.validator.d.ts +1 -0
  23. package/dist/apps/validators/joi-validators/create.appWebhook.validator.js +1 -0
  24. package/dist/apps/validators/joi-validators/create.appWebhook.validator.js.map +1 -1
  25. package/dist/apps/validators/joi-validators/create.appWebhookEvent.validator.d.ts +1 -0
  26. package/dist/apps/validators/joi-validators/create.appWebhookEvent.validator.js +1 -0
  27. package/dist/apps/validators/joi-validators/create.appWebhookEvent.validator.js.map +1 -1
  28. package/dist/apps/validators/joi-validators/update.appWebhook.validator.d.ts +1 -0
  29. package/dist/apps/validators/joi-validators/update.appWebhook.validator.js +1 -0
  30. package/dist/apps/validators/joi-validators/update.appWebhook.validator.js.map +1 -1
  31. package/dist/apps/validators/joi-validators/update.appWebhookEvent.validator.d.ts +1 -0
  32. package/dist/apps/validators/joi-validators/update.appWebhookEvent.validator.js +1 -0
  33. package/dist/apps/validators/joi-validators/update.appWebhookEvent.validator.js.map +1 -1
  34. package/dist/brokers/brokers.service.d.ts +2 -2
  35. package/dist/brokers/brokers.service.js +2 -2
  36. package/dist/brokers/brokers.service.js.map +1 -1
  37. package/dist/brokers/types/index.d.ts +1 -1
  38. package/dist/cloud/cloud-database-link.util.js +22 -3
  39. package/dist/cloud/cloud-database-link.util.js.map +1 -1
  40. package/dist/cloud/cloud-service-map.util.js +6 -5
  41. package/dist/cloud/cloud-service-map.util.js.map +1 -1
  42. package/dist/cloud/index.d.ts +1 -1
  43. package/dist/cloud/index.js +3 -1
  44. package/dist/cloud/index.js.map +1 -1
  45. package/dist/cloud/types/cloud.types.d.ts +1 -1
  46. package/dist/cloud/vpc-connector-connect.util.d.ts +11 -2
  47. package/dist/cloud/vpc-connector-connect.util.js +7 -0
  48. package/dist/cloud/vpc-connector-connect.util.js.map +1 -1
  49. package/dist/cloud/vpc-connector-tunnel.client.d.ts +26 -0
  50. package/dist/cloud/vpc-connector-tunnel.client.js +70 -0
  51. package/dist/cloud/vpc-connector-tunnel.client.js.map +1 -1
  52. package/dist/database/adapters/mysql.adapter.js +15 -0
  53. package/dist/database/adapters/mysql.adapter.js.map +1 -1
  54. package/dist/database/adapters/postgresql.adapter.js +11 -55
  55. package/dist/database/adapters/postgresql.adapter.js.map +1 -1
  56. package/dist/database/databases.service.d.ts +3 -3
  57. package/dist/database/databases.service.js +18 -18
  58. package/dist/database/databases.service.js.map +1 -1
  59. package/dist/database/index.d.ts +1 -1
  60. package/dist/database/triggers/trigger-processor.d.ts +7 -7
  61. package/dist/database/triggers/trigger-processor.js +17 -17
  62. package/dist/database/triggers/trigger-processor.js.map +1 -1
  63. package/dist/database/types/connection.interface.d.ts +0 -2
  64. package/dist/database/types/index.d.ts +1 -1
  65. package/dist/database/types/trigger.interface.d.ts +9 -9
  66. package/dist/database/types/trigger.interface.js +3 -3
  67. package/dist/database/types/trigger.interface.js.map +1 -1
  68. package/dist/features/feature-builder.d.ts +70 -0
  69. package/dist/features/feature-builder.js +348 -0
  70. package/dist/features/feature-builder.js.map +1 -0
  71. package/dist/features/feature-executor.d.ts +289 -0
  72. package/dist/features/feature-executor.js +2444 -0
  73. package/dist/features/feature-executor.js.map +1 -0
  74. package/dist/features/features.service.d.ts +412 -0
  75. package/dist/features/features.service.js +2222 -0
  76. package/dist/features/features.service.js.map +1 -0
  77. package/dist/features/index.d.ts +30 -0
  78. package/dist/features/index.js +64 -0
  79. package/dist/features/index.js.map +1 -0
  80. package/dist/features/types/features.types.d.ts +1081 -0
  81. package/dist/features/types/features.types.js +13 -0
  82. package/dist/features/types/features.types.js.map +1 -0
  83. package/dist/features/types/index.d.ts +6 -0
  84. package/dist/features/types/index.js +23 -0
  85. package/dist/features/types/index.js.map +1 -0
  86. package/dist/index.d.ts +35 -48
  87. package/dist/index.js +48 -63
  88. package/dist/index.js.map +1 -1
  89. package/dist/init.interface.d.ts +1 -11
  90. package/dist/inputs/inputs.service.d.ts +4 -4
  91. package/dist/inputs/inputs.service.js.map +1 -1
  92. package/dist/introspect/index.d.ts +31 -0
  93. package/dist/introspect/index.js +168 -0
  94. package/dist/introspect/index.js.map +1 -0
  95. package/dist/jobs/index.d.ts +1 -1
  96. package/dist/jobs/types.d.ts +3 -3
  97. package/dist/logs/logs.service.d.ts +0 -3
  98. package/dist/logs/logs.service.js +1 -4
  99. package/dist/logs/logs.service.js.map +1 -1
  100. package/dist/logs/logs.types.d.ts +4 -7
  101. package/dist/logs/logs.types.js +2 -3
  102. package/dist/logs/logs.types.js.map +1 -1
  103. package/dist/processor/services/processor.service.d.ts +27 -26
  104. package/dist/processor/services/processor.service.js +71 -72
  105. package/dist/processor/services/processor.service.js.map +1 -1
  106. package/dist/processor/utils/processor.utils.d.ts +2 -2
  107. package/dist/processor/utils/processor.utils.js.map +1 -1
  108. package/dist/products/bootstrap-cache.d.ts +2 -2
  109. package/dist/products/bootstrap-cache.js +3 -3
  110. package/dist/products/bootstrap-cache.js.map +1 -1
  111. package/dist/products/services/products.service.d.ts +32 -57
  112. package/dist/products/services/products.service.js +44 -397
  113. package/dist/products/services/products.service.js.map +1 -1
  114. package/dist/products/validators/index.d.ts +1 -3
  115. package/dist/products/validators/index.js +1 -5
  116. package/dist/products/validators/index.js.map +1 -1
  117. package/dist/products/validators/joi-validators/create.productDatabase.validator.js +1 -1
  118. package/dist/products/validators/joi-validators/create.productDatabase.validator.js.map +1 -1
  119. package/dist/products/validators/joi-validators/create.productFeature.validator.d.ts +1 -7
  120. package/dist/products/validators/joi-validators/create.productFeature.validator.js +6 -61
  121. package/dist/products/validators/joi-validators/create.productFeature.validator.js.map +1 -1
  122. package/dist/products/validators/joi-validators/update.productDatabase.validator.js +23 -27
  123. package/dist/products/validators/joi-validators/update.productDatabase.validator.js.map +1 -1
  124. package/dist/resilience/fallback.service.js +19 -41
  125. package/dist/resilience/fallback.service.js.map +1 -1
  126. package/dist/resilience/healthcheck.service.d.ts +5 -5
  127. package/dist/resilience/healthcheck.service.js +26 -26
  128. package/dist/resilience/healthcheck.service.js.map +1 -1
  129. package/dist/resilience/quota.service.js +17 -27
  130. package/dist/resilience/quota.service.js.map +1 -1
  131. package/dist/resilience/resilience-execution.utils.d.ts +2 -2
  132. package/dist/resilience/resilience-execution.utils.js +7 -7
  133. package/dist/resilience/resilience-execution.utils.js.map +1 -1
  134. package/dist/resilience/resilience.service.js +14 -30
  135. package/dist/resilience/resilience.service.js.map +1 -1
  136. package/dist/resilience/types/index.d.ts +20 -23
  137. package/dist/resilience/types/index.js +2 -3
  138. package/dist/resilience/types/index.js.map +1 -1
  139. package/dist/types/enums.d.ts +1 -2
  140. package/dist/types/enums.js +1 -2
  141. package/dist/types/enums.js.map +1 -1
  142. package/dist/types/index.types.d.ts +3 -4
  143. package/dist/types/index.types.js +2 -2
  144. package/dist/types/index.types.js.map +1 -1
  145. package/dist/types/logs.types.d.ts +0 -1
  146. package/dist/types/logs.types.js.map +1 -1
  147. package/dist/types/processor.types.d.ts +11 -13
  148. package/dist/types/processor.types.js.map +1 -1
  149. package/dist/types/productsBuilder.types.d.ts +52 -58
  150. package/dist/types/productsBuilder.types.js +57 -55
  151. package/dist/types/productsBuilder.types.js.map +1 -1
  152. package/package.json +5 -2
@@ -0,0 +1,1081 @@
1
+ /**
2
+ * Feature Service Types
3
+ *
4
+ * Type definitions for the Ductape Features code-first API.
5
+ */
6
+ import { IProductFeature, IProductFeatureStep, IFeatureOptions, IFeatureSignal, IFeatureQuery, IFeatureEnv, IFeatureStepOptions, IFeatureStepRollback, FeatureStepType, FeatureRollbackStrategy, FeatureStatus, IActionRequest, INotificationRequest, IDbActionRequest, IStorageRequest } from '../../types';
7
+ /**
8
+ * Configuration options for FeatureService initialization
9
+ */
10
+ export interface IFeatureServiceConfig {
11
+ /** Workspace ID */
12
+ workspace_id: string;
13
+ /** Public key for authentication */
14
+ public_key: string;
15
+ /** User ID */
16
+ user_id: string;
17
+ /** Authentication token */
18
+ token: string;
19
+ /** Environment type (staging, production, local) */
20
+ env_type: string;
21
+ /** Optional Redis client for caching */
22
+ redis_client?: any;
23
+ }
24
+ /**
25
+ * Feature configuration for local registration
26
+ */
27
+ export interface IFeatureConfig {
28
+ /** Human-readable name */
29
+ name: string;
30
+ /** Unique feature tag */
31
+ tag: string;
32
+ /** Description */
33
+ description?: string;
34
+ /** Input schema */
35
+ input?: Record<string, unknown>;
36
+ /** Output schema */
37
+ output?: Record<string, unknown>;
38
+ /** Feature steps */
39
+ steps: IProductFeatureStep[];
40
+ /** Signal definitions */
41
+ signals?: Record<string, IFeatureSignal>;
42
+ /** Query definitions */
43
+ queries?: Record<string, IFeatureQuery>;
44
+ /** Feature options */
45
+ options?: IFeatureOptions;
46
+ /** Environment configurations */
47
+ envs?: IFeatureEnv[];
48
+ }
49
+ /**
50
+ * Additional context metadata for feature execution
51
+ */
52
+ export interface IFeatureContextMeta {
53
+ /** Request ID */
54
+ request_id?: string;
55
+ /** Correlation ID */
56
+ correlation_id?: string;
57
+ /** Parent feature ID (for child features) */
58
+ parent_feature_id?: string;
59
+ /** Parent step tag (for child features) */
60
+ parent_step_tag?: string;
61
+ /** Custom metadata */
62
+ [key: string]: unknown;
63
+ }
64
+ /**
65
+ * Logger interface for feature execution
66
+ */
67
+ export interface IFeatureLogger {
68
+ debug(message: string, data?: Record<string, unknown>): void;
69
+ info(message: string, data?: Record<string, unknown>): void;
70
+ warn(message: string, data?: Record<string, unknown>): void;
71
+ error(message: string, data?: Record<string, unknown>): void;
72
+ }
73
+ /**
74
+ * Wait options for signals
75
+ */
76
+ export interface IWaitOptions {
77
+ /** Timeout duration (ms or duration string like '1h', '30m') */
78
+ timeout?: number | string;
79
+ }
80
+ /**
81
+ * Child feature options
82
+ */
83
+ export interface IChildFeatureOptions {
84
+ /** Timeout for child feature */
85
+ timeout?: number | string;
86
+ /** Number of retries */
87
+ retries?: number;
88
+ /** How to handle parent cancellation */
89
+ parent_close_policy?: 'terminate' | 'abandon' | 'request_cancel';
90
+ /** Idempotency key */
91
+ idempotency_key?: string;
92
+ }
93
+ /**
94
+ * Rollback result
95
+ */
96
+ export interface IRollbackResult {
97
+ /** Whether rollback was successful */
98
+ success: boolean;
99
+ /** Steps that were rolled back */
100
+ rolled_back_steps: string[];
101
+ /** Steps that failed to rollback */
102
+ failed_steps?: Array<{
103
+ tag: string;
104
+ error: string;
105
+ }>;
106
+ /** Reason for triggering rollback */
107
+ reason: string;
108
+ }
109
+ /**
110
+ * Action context for feature steps
111
+ */
112
+ export interface IFeatureActionContext {
113
+ run<T>(options: {
114
+ app: string;
115
+ event: string;
116
+ input: IActionRequest;
117
+ retries?: number;
118
+ timeout?: number;
119
+ }): Promise<T>;
120
+ }
121
+ /**
122
+ * Database context for feature steps
123
+ */
124
+ export interface IFeatureDatabaseContext {
125
+ execute<T>(options: {
126
+ database: string;
127
+ event: string;
128
+ input: IDbActionRequest;
129
+ retries?: number;
130
+ timeout?: number;
131
+ }): Promise<T>;
132
+ query<T>(options: {
133
+ database: string;
134
+ event: string;
135
+ params?: Record<string, unknown>;
136
+ }): Promise<T[]>;
137
+ insert<T>(options: {
138
+ database: string;
139
+ event: string;
140
+ data: Record<string, unknown>;
141
+ }): Promise<T>;
142
+ update<T>(options: {
143
+ database: string;
144
+ event: string;
145
+ data: Record<string, unknown>;
146
+ where: Record<string, unknown>;
147
+ }): Promise<T>;
148
+ delete(options: {
149
+ database: string;
150
+ event: string;
151
+ where: Record<string, unknown>;
152
+ }): Promise<boolean>;
153
+ }
154
+ /**
155
+ * Graph context for feature steps
156
+ */
157
+ export interface IFeatureGraphContext {
158
+ execute<T>(options: {
159
+ graph: string;
160
+ action: string;
161
+ input: Record<string, unknown>;
162
+ }): Promise<T>;
163
+ createNode<T>(options: {
164
+ graph: string;
165
+ labels: string[];
166
+ properties: Record<string, unknown>;
167
+ }): Promise<T>;
168
+ updateNode<T>(options: {
169
+ graph: string;
170
+ id: string | number;
171
+ properties: Record<string, unknown>;
172
+ }): Promise<T>;
173
+ deleteNode(options: {
174
+ graph: string;
175
+ id: string | number;
176
+ }): Promise<void>;
177
+ createRelationship<T>(options: {
178
+ graph: string;
179
+ from: string;
180
+ to: string;
181
+ type: string;
182
+ properties?: Record<string, unknown>;
183
+ }): Promise<T>;
184
+ deleteRelationship(options: {
185
+ graph: string;
186
+ id: string | number;
187
+ }): Promise<void>;
188
+ query<T>(options: {
189
+ graph: string;
190
+ action: string;
191
+ params?: Record<string, unknown>;
192
+ }): Promise<T[]>;
193
+ }
194
+ /**
195
+ * Notification context for feature steps
196
+ */
197
+ export interface IFeatureNotificationContext {
198
+ send(options: {
199
+ notification: string;
200
+ event: string;
201
+ input: INotificationRequest;
202
+ retries?: number;
203
+ }): Promise<void>;
204
+ email(options: {
205
+ notification: string;
206
+ event: string;
207
+ recipients: string[];
208
+ subject: Record<string, unknown>;
209
+ template: Record<string, unknown>;
210
+ }): Promise<void>;
211
+ push(options: {
212
+ notification: string;
213
+ event: string;
214
+ tokens: string[];
215
+ title: Record<string, unknown>;
216
+ body: Record<string, unknown>;
217
+ data?: Record<string, unknown>;
218
+ }): Promise<void>;
219
+ sms(options: {
220
+ notification: string;
221
+ event: string;
222
+ phones: string[];
223
+ message: Record<string, unknown>;
224
+ }): Promise<void>;
225
+ }
226
+ /**
227
+ * Storage context for feature steps
228
+ */
229
+ export interface IFeatureStorageContext {
230
+ upload(options: {
231
+ storage: string;
232
+ event: string;
233
+ input: IStorageRequest;
234
+ retries?: number;
235
+ }): Promise<IFileUploadResult>;
236
+ download(options: {
237
+ storage: string;
238
+ event: string;
239
+ input: IStorageRequest;
240
+ }): Promise<IFileDownloadResult>;
241
+ delete(options: {
242
+ storage: string;
243
+ event: string;
244
+ input: {
245
+ file_key: string;
246
+ };
247
+ }): Promise<void>;
248
+ }
249
+ /**
250
+ * Messaging context for feature steps (Ductape primitive).
251
+ * Use ctx.messaging.produce() to publish to a message broker.
252
+ */
253
+ export interface IFeatureMessagingContext {
254
+ /**
255
+ * Publish a message to a broker topic.
256
+ * @param options.event - Full event string "broker-tag:topic-tag" (e.g. "order-events:payment-processed")
257
+ * @param options.message - Message payload
258
+ */
259
+ produce(options: {
260
+ event: string;
261
+ message: Record<string, unknown>;
262
+ }): Promise<void>;
263
+ }
264
+ /**
265
+ * Publish context for feature steps.
266
+ * @deprecated Prefer ctx.messaging.produce() (Ductape primitive).
267
+ */
268
+ export interface IFeaturePublishContext {
269
+ send(options: {
270
+ broker: string;
271
+ event: string;
272
+ input: {
273
+ message: Record<string, unknown>;
274
+ };
275
+ retries?: number;
276
+ }): Promise<void>;
277
+ }
278
+ /**
279
+ * Quota context for feature steps
280
+ */
281
+ export interface IFeatureQuotaContext {
282
+ execute<T>(options: {
283
+ quota: string;
284
+ input: Record<string, unknown>;
285
+ timeout?: number;
286
+ }): Promise<T>;
287
+ }
288
+ /**
289
+ * Fallback context for feature steps
290
+ */
291
+ export interface IFeatureFallbackContext {
292
+ execute<T>(options: {
293
+ fallback: string;
294
+ input: Record<string, unknown>;
295
+ timeout?: number;
296
+ }): Promise<T>;
297
+ }
298
+ /**
299
+ * Healthcheck context for feature steps
300
+ */
301
+ export interface IFeatureHealthcheckContext {
302
+ getStatus(tag: string): Promise<{
303
+ status: 'available' | 'unavailable';
304
+ lastChecked?: string;
305
+ lastLatency?: number;
306
+ }>;
307
+ }
308
+ /**
309
+ * Transform context for data transformations
310
+ */
311
+ export interface ITransformContext {
312
+ /** Get the number of keys in an object */
313
+ size(obj: Record<string, unknown>): number;
314
+ /** Get the length of an array or string */
315
+ length(arr: unknown[] | string): number;
316
+ /** Parse JSON string */
317
+ parseJson<T>(str: string): T;
318
+ /** Stringify to JSON */
319
+ stringify(obj: unknown): string;
320
+ /** Convert to uppercase */
321
+ upper(str: string): string;
322
+ /** Convert to lowercase */
323
+ lower(str: string): string;
324
+ /** Trim whitespace */
325
+ trim(str: string): string;
326
+ /** Split string */
327
+ split(str: string, separator: string): string[];
328
+ /** Join array */
329
+ join(arr: string[], separator: string): string;
330
+ /** Get current timestamp */
331
+ now(): number;
332
+ /** Format date */
333
+ formatDate(date: Date | number | string, format: string): string;
334
+ }
335
+ /**
336
+ * File upload result
337
+ */
338
+ export interface IFileUploadResult {
339
+ file_key: string;
340
+ url?: string;
341
+ size?: number;
342
+ content_type?: string;
343
+ }
344
+ /**
345
+ * File download result
346
+ */
347
+ export interface IFileDownloadResult {
348
+ content: Buffer | string;
349
+ content_type?: string;
350
+ size?: number;
351
+ }
352
+ /**
353
+ * Full feature context interface
354
+ */
355
+ export interface IFeatureContext<TInput = Record<string, unknown>> {
356
+ /** Feature input (read-only) */
357
+ readonly input: TInput;
358
+ /** Feature metadata */
359
+ readonly feature_id: string;
360
+ readonly feature_tag: string;
361
+ readonly env: string;
362
+ readonly product: string;
363
+ readonly context: IFeatureContextMeta;
364
+ /** Execution state */
365
+ readonly state: Record<string, unknown>;
366
+ readonly steps: Record<string, unknown>;
367
+ readonly completed_steps: string[];
368
+ readonly current_step: string | null;
369
+ /** Session token in format: session_tag:jwt_token */
370
+ readonly session?: string;
371
+ /** Step execution */
372
+ step<T>(tag: string, handler: () => Promise<T>, rollback?: ((result: T) => Promise<void>) | null, options?: IFeatureStepOptions): Promise<T>;
373
+ /** Ductape components */
374
+ action: IFeatureActionContext;
375
+ database: IFeatureDatabaseContext;
376
+ graph: IFeatureGraphContext;
377
+ notification: IFeatureNotificationContext;
378
+ storage: IFeatureStorageContext;
379
+ /** Message broker (Ductape primitive). Prefer over publish. */
380
+ events: IFeatureMessagingContext;
381
+ /** @deprecated Prefer ctx.events.produce() */
382
+ publish: IFeaturePublishContext;
383
+ /** Resilience components */
384
+ quota: IFeatureQuotaContext;
385
+ fallback: IFeatureFallbackContext;
386
+ healthcheck: IFeatureHealthcheckContext;
387
+ /** Data transformations */
388
+ transform: ITransformContext;
389
+ /** Data references */
390
+ variable(app: string, key: string): unknown;
391
+ constant(app: string, key: string): unknown;
392
+ token(key: string): string;
393
+ auth: Record<string, unknown>;
394
+ default<T>(value: T | undefined, fallback: T): T;
395
+ /** Control flow */
396
+ sleep(duration: number | string): Promise<void>;
397
+ waitForSignal<T>(signal: string | string[], options?: IWaitOptions): Promise<T>;
398
+ checkpoint(name: string, metadata?: Record<string, unknown>): Promise<void>;
399
+ /** State management */
400
+ setState(key: string, value: unknown): void;
401
+ getState<T>(key: string): T | undefined;
402
+ /** Logging */
403
+ log: IFeatureLogger;
404
+ /** Child features */
405
+ feature<TChildInput, TChildOutput>(childId: string, tag: string, input: TChildInput, options?: IChildFeatureOptions): Promise<TChildOutput>;
406
+ /** Rollback control */
407
+ triggerRollback(reason: string): Promise<IRollbackResult>;
408
+ }
409
+ /**
410
+ * Feature handler function type
411
+ */
412
+ export type FeatureHandler<TInput = Record<string, unknown>, TOutput = unknown> = (ctx: IFeatureContext<TInput>) => Promise<TOutput>;
413
+ /**
414
+ * Options for defining a feature with code-first API
415
+ */
416
+ export interface IDefineFeatureOptions<TInput = Record<string, unknown>, TOutput = unknown> {
417
+ /** Target product (optional if using builder pattern) */
418
+ product?: string;
419
+ /** Unique feature tag */
420
+ tag: string;
421
+ /** Human-readable name */
422
+ name: string;
423
+ /** Description */
424
+ description?: string;
425
+ /** Input schema (field names and types for documentation/validation), e.g. { orderId: { type: 'string', required: true } } */
426
+ input?: Record<string, {
427
+ type: string;
428
+ required?: boolean;
429
+ }>;
430
+ /** Output schema (optional, for documentation) */
431
+ output?: Record<string, unknown>;
432
+ /** Signal definitions */
433
+ signals?: Record<string, {
434
+ input?: Record<string, string>;
435
+ }>;
436
+ /** Query definitions */
437
+ queries?: Record<string, {
438
+ handler?: (ctx: IFeatureContext<TInput>) => unknown;
439
+ }>;
440
+ /** Feature options */
441
+ options?: IFeatureOptions;
442
+ /** Environment configurations */
443
+ envs?: IFeatureEnv[];
444
+ /**
445
+ * Optional step result overrides when recording the handler.
446
+ * Use when the handler branches on a step result (e.g. if (!validation.valid) return ...).
447
+ * Key = step tag, value = result to return to the handler so it continues and records later steps.
448
+ * Example: { validate: { valid: true } } so the handler does not early-return and process-payment is recorded.
449
+ * Steps recorded after an overridden step get a condition so they only run when that step's real output matches (e.g. $Step{validate}{valid} == true).
450
+ */
451
+ branchOverrides?: Record<string, unknown>;
452
+ /**
453
+ * Sample input used during recording so loops and control flow see real values.
454
+ * Example: { items: [{ id: '1' }, { id: '2' }] } so that for (const item of ctx.input.items) runs twice and records steps process-1, process-2.
455
+ * Use unique step tags per iteration (e.g. ctx.step(`process-${item.id}`, ...)).
456
+ */
457
+ recordInput?: TInput;
458
+ /**
459
+ * For switch/alternate branches: run the handler once per scenario with that as recordInput.
460
+ * Each step recorded in that run gets a condition so it only runs when feature input matches (e.g. $Input{type} == 'a').
461
+ * Example: recordScenarios: [ { type: 'a' }, { type: 'b' } ] records both branches; handle-a gets condition $Input{type} == 'a', handle-b gets $Input{type} == 'b'.
462
+ */
463
+ recordScenarios?: Record<string, unknown>[];
464
+ /** Feature handler function */
465
+ handler: FeatureHandler<TInput, TOutput>;
466
+ }
467
+ /**
468
+ * Options for executing a feature
469
+ */
470
+ export interface IExecuteFeatureOptions {
471
+ /** Product tag */
472
+ product: string;
473
+ /** Environment slug */
474
+ env: string;
475
+ /** Feature tag */
476
+ tag: string;
477
+ /** Feature input */
478
+ input: Record<string, unknown>;
479
+ /** Pre-resolved product ID (avoids duplicate initProduct when provided) */
480
+ product_id?: string;
481
+ /** Session token in format: session_tag:jwt_token */
482
+ session?: string;
483
+ /** Idempotency key */
484
+ idempotency_key?: string;
485
+ /** Cache tag */
486
+ cache?: string;
487
+ /** Number of retries */
488
+ retries?: number;
489
+ /** Timeout in ms */
490
+ timeout?: number;
491
+ }
492
+ /**
493
+ * Feature execution result
494
+ */
495
+ export interface IFeatureExecutionResult<T = unknown> {
496
+ /** Execution status */
497
+ status: FeatureStatus;
498
+ /** Feature ID */
499
+ feature_id: string;
500
+ /** Output data */
501
+ output?: T;
502
+ /** Error message if failed */
503
+ error?: string;
504
+ /** Execution time in ms */
505
+ execution_time: number;
506
+ /** Completed steps */
507
+ completed_steps: string[];
508
+ /** Per-step timing (tag, duration_ms, success) for reporting */
509
+ step_timings?: Array<{
510
+ tag: string;
511
+ duration_ms: number;
512
+ success: boolean;
513
+ }>;
514
+ /** Failed step (if any) */
515
+ failed_step?: string;
516
+ /** Rollback info (if rolled back) */
517
+ rollback_info?: {
518
+ triggered_by: string;
519
+ reason: string;
520
+ rolled_back_steps: string[];
521
+ failed_rollbacks?: Array<{
522
+ tag: string;
523
+ error: string;
524
+ }>;
525
+ };
526
+ }
527
+ /**
528
+ * Schedule configuration for dispatched features
529
+ */
530
+ export interface IFeatureSchedule {
531
+ /** Start time (timestamp or ISO string) */
532
+ start_at?: number | string;
533
+ /** Cron expression for recurring */
534
+ cron?: string;
535
+ /** Interval in ms for recurring */
536
+ every?: number;
537
+ /** Maximum number of executions */
538
+ limit?: number;
539
+ /** End date for recurring */
540
+ endDate?: number | string;
541
+ /** Timezone */
542
+ tz?: string;
543
+ }
544
+ /**
545
+ * Options for dispatching a feature
546
+ */
547
+ export interface IFeatureDispatchInput {
548
+ /** Product tag */
549
+ product: string;
550
+ /** Environment slug */
551
+ env: string;
552
+ /** Feature tag */
553
+ feature: string;
554
+ /** Feature input */
555
+ input: Record<string, unknown>;
556
+ /** Schedule configuration */
557
+ schedule?: IFeatureSchedule;
558
+ /** Session token in format: session_tag:jwt_token */
559
+ session?: string;
560
+ /** Cache tag */
561
+ cache?: string;
562
+ /** Number of retries */
563
+ retries?: number;
564
+ }
565
+ /**
566
+ * Dispatch result
567
+ */
568
+ export interface IFeatureDispatchResult {
569
+ /** Job ID */
570
+ job_id: string;
571
+ /** Job status */
572
+ status: 'scheduled' | 'queued' | 'running';
573
+ /** Scheduled timestamp */
574
+ scheduled_at?: number;
575
+ /** Whether this is a recurring job */
576
+ recurring?: boolean;
577
+ /** Next run timestamp (for recurring) */
578
+ next_run_at?: number;
579
+ }
580
+ /**
581
+ * Options for sending a signal to a feature
582
+ */
583
+ export interface ISendSignalOptions {
584
+ /** Product tag */
585
+ product: string;
586
+ /** Environment slug */
587
+ env: string;
588
+ /** Feature ID */
589
+ feature_id: string;
590
+ /** Signal name */
591
+ signal: string;
592
+ /** Signal payload */
593
+ payload?: Record<string, unknown>;
594
+ }
595
+ /**
596
+ * Options for querying a feature
597
+ */
598
+ export interface IQueryFeatureOptions {
599
+ /** Product tag */
600
+ product: string;
601
+ /** Environment slug */
602
+ env: string;
603
+ /** Feature ID */
604
+ feature_id: string;
605
+ /** Query name */
606
+ query: string;
607
+ /** Query parameters */
608
+ params?: Record<string, unknown>;
609
+ }
610
+ /**
611
+ * Step builder interface for fluent API
612
+ */
613
+ export interface IStepBuilder {
614
+ /** Set as action step */
615
+ action(app: string, event: string): IStepBuilder;
616
+ /** Set as database step */
617
+ database(database: string, event: string): IStepBuilder;
618
+ /** Set as graph step */
619
+ graph(graph: string, action: string): IStepBuilder;
620
+ /** Set as notification step */
621
+ notification(notification: string, event: string): IStepBuilder;
622
+ /** Set as storage step */
623
+ storage(storage: string, event: string): IStepBuilder;
624
+ /** Set as message broker produce step */
625
+ produce(broker: string, event: string): IStepBuilder;
626
+ /** @deprecated Use produce() */
627
+ publish(broker: string, event: string): IStepBuilder;
628
+ /** Set as quota step */
629
+ quota(quota: string): IStepBuilder;
630
+ /** Set as fallback step */
631
+ fallback(fallback: string): IStepBuilder;
632
+ /** Set as child feature step */
633
+ feature(feature: string): IStepBuilder;
634
+ /** Set as sleep step */
635
+ sleep(duration: number | string): IStepBuilder;
636
+ /** Set as wait for signal step */
637
+ waitForSignal(signal: string, timeout?: number | string): IStepBuilder;
638
+ /** Set as checkpoint step */
639
+ checkpoint(): IStepBuilder;
640
+ /** Set step input */
641
+ input(input: Record<string, unknown>): IStepBuilder;
642
+ /** Set step dependencies */
643
+ dependsOn(steps: string[]): IStepBuilder;
644
+ /** Set step condition */
645
+ condition(condition: string): IStepBuilder;
646
+ /** Set step options */
647
+ options(options: IFeatureStepOptions): IStepBuilder;
648
+ /** Mark as optional */
649
+ optional(): IStepBuilder;
650
+ /** Mark as critical */
651
+ critical(): IStepBuilder;
652
+ /** Mark as allow_fail */
653
+ allowFail(): IStepBuilder;
654
+ /** Set step name */
655
+ name(name: string): IStepBuilder;
656
+ /** Configure rollback */
657
+ rollback(): IRollbackBuilder;
658
+ /** Complete step definition and return to feature builder */
659
+ done(): IFeatureBuilder;
660
+ }
661
+ /**
662
+ * Rollback builder interface for fluent API
663
+ */
664
+ export interface IRollbackBuilder {
665
+ /** Set as action rollback */
666
+ action(app: string, event: string): IRollbackBuilder;
667
+ /** Set as database rollback */
668
+ database(database: string, event: string): IRollbackBuilder;
669
+ /** Set as graph rollback */
670
+ graph(graph: string, action: string): IRollbackBuilder;
671
+ /** Set as notification rollback */
672
+ notification(notification: string, event: string): IRollbackBuilder;
673
+ /** Set as storage rollback */
674
+ storage(storage: string, event: string): IRollbackBuilder;
675
+ /** Set as message broker produce rollback */
676
+ produce(broker: string, event: string): IRollbackBuilder;
677
+ /** @deprecated Use produce() */
678
+ publish(broker: string, event: string): IRollbackBuilder;
679
+ /** Set rollback input */
680
+ input(input: Record<string, unknown>): IRollbackBuilder;
681
+ /** Complete rollback definition and return to step builder */
682
+ done(): IStepBuilder;
683
+ }
684
+ /**
685
+ * Feature builder interface for fluent API
686
+ */
687
+ export interface IFeatureBuilder {
688
+ /** Set feature name */
689
+ name(name: string): IFeatureBuilder;
690
+ /** Set feature description */
691
+ description(description: string): IFeatureBuilder;
692
+ /** Set input schema */
693
+ input(input: Record<string, unknown>): IFeatureBuilder;
694
+ /** Set output schema */
695
+ output(output: Record<string, unknown>): IFeatureBuilder;
696
+ /** Set feature options */
697
+ options(options: IFeatureOptions): IFeatureBuilder;
698
+ /** Add environment */
699
+ env(slug: string, active?: boolean): IFeatureBuilder;
700
+ /** Add signal */
701
+ signal(name: string, input?: Record<string, string>): IFeatureBuilder;
702
+ /** Add query */
703
+ query(name: string, handler?: string): IFeatureBuilder;
704
+ /** Start defining a step */
705
+ step(tag: string): IStepBuilder;
706
+ /** Build the feature schema */
707
+ build(): IProductFeature;
708
+ /** Get compiled JSON schema */
709
+ toSchema(): IProductFeature;
710
+ }
711
+ /**
712
+ * Options for replaying a feature
713
+ */
714
+ export interface IFeatureReplayInput {
715
+ /** Product tag */
716
+ product: string;
717
+ /** Environment slug */
718
+ env: string;
719
+ /** Original feature ID to replay */
720
+ feature_id: string;
721
+ /** Override options for the replay */
722
+ options?: Partial<IFeatureOptions>;
723
+ /** Reason for replay (for audit) */
724
+ reason?: string;
725
+ /** Idempotency key */
726
+ idempotency_key?: string;
727
+ }
728
+ /**
729
+ * Result of replaying a feature
730
+ */
731
+ export interface IFeatureReplayResult extends IFeatureExecutionResult {
732
+ /** Original feature ID that was replayed */
733
+ replayed_from: string;
734
+ }
735
+ /**
736
+ * Options for restarting a feature
737
+ */
738
+ export interface IFeatureRestartInput {
739
+ /** Product tag */
740
+ product: string;
741
+ /** Environment slug */
742
+ env: string;
743
+ /** Original feature ID to restart */
744
+ feature_id: string;
745
+ /** New input (replaces original) */
746
+ input?: Record<string, unknown>;
747
+ /** Partial input override (merged with original) */
748
+ input_override?: Record<string, unknown>;
749
+ /** Whether to merge input_override with original input */
750
+ merge_input?: boolean;
751
+ /** Reason for restart (for audit) */
752
+ reason?: string;
753
+ /** Override options */
754
+ options?: Partial<IFeatureOptions>;
755
+ }
756
+ /**
757
+ * Result of restarting a feature
758
+ */
759
+ export interface IFeatureRestartResult extends IFeatureExecutionResult {
760
+ /** Original feature ID that was restarted */
761
+ restarted_from: string;
762
+ }
763
+ /**
764
+ * Options for resuming a feature
765
+ */
766
+ export interface IFeatureResumeInput {
767
+ /** Product tag */
768
+ product: string;
769
+ /** Environment slug */
770
+ env: string;
771
+ /** Feature ID to resume */
772
+ feature_id: string;
773
+ /** Resume from specific checkpoint */
774
+ from_checkpoint?: string;
775
+ /** Resume from specific step */
776
+ from_step?: string;
777
+ /** Steps to skip */
778
+ skip_steps?: string[];
779
+ /** Additional input for remaining steps */
780
+ input?: Record<string, unknown>;
781
+ }
782
+ /**
783
+ * Result of resuming a feature
784
+ */
785
+ export interface IFeatureResumeResult extends IFeatureExecutionResult {
786
+ /** Original feature ID that was resumed */
787
+ resumed_from: string;
788
+ /** Checkpoint resumed from (if applicable) */
789
+ resumed_checkpoint?: string;
790
+ }
791
+ /**
792
+ * Options for replaying from a specific step
793
+ */
794
+ export interface IFeatureReplayFromStepInput {
795
+ /** Product tag */
796
+ product: string;
797
+ /** Environment slug */
798
+ env: string;
799
+ /** Original feature ID */
800
+ feature_id: string;
801
+ /** Step to start from */
802
+ from_step: string;
803
+ /** Override outputs from previous steps */
804
+ step_outputs?: Record<string, unknown>;
805
+ /** Debug options */
806
+ debug?: {
807
+ enabled: boolean;
808
+ pause_after_step?: boolean;
809
+ log_level?: 'info' | 'verbose' | 'debug';
810
+ };
811
+ }
812
+ /**
813
+ * Options for getting feature status
814
+ */
815
+ export interface IFeatureStatusInput {
816
+ /** Product tag */
817
+ product: string;
818
+ /** Environment slug */
819
+ env: string;
820
+ /** Feature ID */
821
+ feature_id: string;
822
+ }
823
+ /**
824
+ * Feature status response
825
+ */
826
+ export interface IFeatureStatus {
827
+ /** Feature ID */
828
+ feature_id: string;
829
+ /** Feature tag */
830
+ feature_tag: string;
831
+ /** Current status */
832
+ status: FeatureStatus;
833
+ /** Currently executing step */
834
+ current_step?: string;
835
+ /** Completed step tags */
836
+ completed_steps: string[];
837
+ /** Feature state */
838
+ state: Record<string, unknown>;
839
+ /** Start timestamp */
840
+ started_at: number;
841
+ /** Last update timestamp */
842
+ updated_at: number;
843
+ /** Input data */
844
+ input?: Record<string, unknown>;
845
+ /** Output data (if completed) */
846
+ output?: unknown;
847
+ /** Error (if failed) */
848
+ error?: {
849
+ message: string;
850
+ step?: string;
851
+ code?: string;
852
+ };
853
+ }
854
+ /**
855
+ * Options for cancelling a feature
856
+ */
857
+ export interface IFeatureCancelInput {
858
+ /** Product tag */
859
+ product: string;
860
+ /** Environment slug */
861
+ env: string;
862
+ /** Feature ID */
863
+ feature_id: string;
864
+ /** Reason for cancellation */
865
+ reason?: string;
866
+ }
867
+ /**
868
+ * Cancel result
869
+ */
870
+ export interface IFeatureCancelResult {
871
+ /** Whether cancellation was successful */
872
+ cancelled: boolean;
873
+ /** Steps that were rolled back */
874
+ rolled_back_steps: string[];
875
+ /** Steps that failed to rollback */
876
+ failed_rollbacks?: Array<{
877
+ tag: string;
878
+ error: string;
879
+ }>;
880
+ }
881
+ /**
882
+ * Options for getting feature history
883
+ */
884
+ export interface IFeatureHistoryInput {
885
+ /** Product tag */
886
+ product: string;
887
+ /** Environment slug */
888
+ env: string;
889
+ /** Feature ID */
890
+ feature_id: string;
891
+ /** Include detailed step information */
892
+ include_step_details?: boolean;
893
+ /** Include rollback details */
894
+ include_rollback_details?: boolean;
895
+ }
896
+ /**
897
+ * Feature event types
898
+ */
899
+ export type FeatureEventType = 'feature_started' | 'feature_completed' | 'feature_failed' | 'feature_cancelled' | 'feature_rolled_back' | 'step_started' | 'step_completed' | 'step_failed' | 'step_skipped' | 'step_rolled_back' | 'checkpoint_created' | 'signal_received' | 'signal_timeout' | 'rollback_started' | 'rollback_completed' | 'rollback_failed';
900
+ /**
901
+ * Feature event
902
+ */
903
+ export interface IFeatureEvent {
904
+ /** Event type */
905
+ type: FeatureEventType;
906
+ /** Timestamp */
907
+ timestamp: number;
908
+ /** Event data */
909
+ data: Record<string, unknown>;
910
+ }
911
+ /**
912
+ * Checkpoint info
913
+ */
914
+ export interface ICheckpoint {
915
+ /** Checkpoint name */
916
+ name: string;
917
+ /** Checkpoint metadata */
918
+ metadata?: Record<string, unknown>;
919
+ /** Timestamp */
920
+ timestamp: number;
921
+ }
922
+ /**
923
+ * Feature history
924
+ */
925
+ export interface IFeatureHistory {
926
+ /** Feature ID */
927
+ feature_id: string;
928
+ /** Feature tag */
929
+ feature_tag: string;
930
+ /** Final status */
931
+ status: FeatureStatus;
932
+ /** All events */
933
+ events: IFeatureEvent[];
934
+ /** Checkpoints */
935
+ checkpoints: ICheckpoint[];
936
+ /** Replay IDs (if this feature was replayed) */
937
+ replays?: string[];
938
+ /** Restart IDs (if this feature was restarted) */
939
+ restarts?: string[];
940
+ }
941
+ /**
942
+ * Options for getting step details
943
+ */
944
+ export interface IStepDetailInput {
945
+ /** Product tag */
946
+ product: string;
947
+ /** Environment slug */
948
+ env: string;
949
+ /** Feature ID */
950
+ feature_id: string;
951
+ /** Step tag */
952
+ step_tag: string;
953
+ }
954
+ /**
955
+ * Step status
956
+ */
957
+ export type StepStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped' | 'rolled_back';
958
+ /**
959
+ * Rollback status
960
+ */
961
+ export type RollbackStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped';
962
+ /**
963
+ * Step error
964
+ */
965
+ export interface IStepError {
966
+ /** Error message */
967
+ message: string;
968
+ /** Error code */
969
+ code?: string;
970
+ /** Stack trace */
971
+ stack?: string;
972
+ }
973
+ /**
974
+ * Step detail
975
+ */
976
+ export interface IStepDetail {
977
+ /** Step tag */
978
+ tag: string;
979
+ /** Step name */
980
+ name?: string;
981
+ /** Step status */
982
+ status: StepStatus;
983
+ /** Step input */
984
+ input?: Record<string, unknown>;
985
+ /** Step output */
986
+ output?: Record<string, unknown>;
987
+ /** Step error (if failed) */
988
+ error?: IStepError;
989
+ /** Number of attempts */
990
+ attempts: number;
991
+ /** Start timestamp */
992
+ start_time?: number;
993
+ /** End timestamp */
994
+ end_time?: number;
995
+ /** Duration in ms */
996
+ duration?: number;
997
+ /** Rollback status */
998
+ rollback_status?: RollbackStatus;
999
+ /** Rollback error (if rollback failed) */
1000
+ rollback_error?: string;
1001
+ }
1002
+ /**
1003
+ * Options for listing related executions
1004
+ */
1005
+ export interface IRelatedExecutionsInput {
1006
+ /** Product tag */
1007
+ product: string;
1008
+ /** Environment slug */
1009
+ env: string;
1010
+ /** Feature ID */
1011
+ feature_id: string;
1012
+ }
1013
+ /**
1014
+ * Related execution entry
1015
+ */
1016
+ export interface IRelatedExecution {
1017
+ /** Feature ID */
1018
+ feature_id: string;
1019
+ /** Execution type */
1020
+ type: 'original' | 'replay' | 'restart' | 'resume';
1021
+ /** Status */
1022
+ status: FeatureStatus;
1023
+ /** Created timestamp */
1024
+ created_at: number;
1025
+ /** Original feature ID (for replays) */
1026
+ replayed_from?: string;
1027
+ /** Original feature ID (for restarts) */
1028
+ restarted_from?: string;
1029
+ /** Original feature ID (for resumes) */
1030
+ resumed_from?: string;
1031
+ }
1032
+ /**
1033
+ * Related executions response
1034
+ */
1035
+ export interface IRelatedExecutions {
1036
+ /** Original feature ID */
1037
+ original: string;
1038
+ /** All related executions */
1039
+ executions: IRelatedExecution[];
1040
+ }
1041
+ /**
1042
+ * Options for comparing executions
1043
+ */
1044
+ export interface ICompareExecutionsInput {
1045
+ /** Product tag */
1046
+ product: string;
1047
+ /** Environment slug */
1048
+ env: string;
1049
+ /** Feature IDs to compare */
1050
+ feature_ids: string[];
1051
+ }
1052
+ /**
1053
+ * Step diff entry
1054
+ */
1055
+ export interface IStepDiff {
1056
+ /** Step tag */
1057
+ step: string;
1058
+ /** Status and output per feature */
1059
+ [feature_id: string]: {
1060
+ status: StepStatus;
1061
+ output?: Record<string, unknown>;
1062
+ error?: string;
1063
+ } | string;
1064
+ }
1065
+ /**
1066
+ * Execution comparison
1067
+ */
1068
+ export interface IExecutionComparison {
1069
+ /** Feature IDs compared */
1070
+ features: string[];
1071
+ /** Input differences */
1072
+ input_diff: Record<string, unknown[]>;
1073
+ /** Step differences */
1074
+ step_diffs: IStepDiff[];
1075
+ /** Outcome differences */
1076
+ outcome_diff: Record<string, {
1077
+ status: FeatureStatus;
1078
+ output?: unknown;
1079
+ }>;
1080
+ }
1081
+ export { IProductFeature, IProductFeatureStep, IFeatureOptions, IFeatureSignal, IFeatureQuery, IFeatureEnv, IFeatureStepOptions, IFeatureStepRollback, FeatureStepType, FeatureRollbackStrategy, FeatureStatus, };