duron 0.3.0-beta.12 → 0.3.0-beta.14
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/dist/action.d.ts +202 -13
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +13 -128
- package/dist/adapters/postgres/base.d.ts +14 -5
- package/dist/adapters/postgres/base.d.ts.map +1 -1
- package/dist/adapters/postgres/base.js +84 -17
- package/dist/adapters/postgres/schema.d.ts +15 -0
- package/dist/adapters/postgres/schema.d.ts.map +1 -1
- package/dist/adapters/postgres/schema.default.d.ts +15 -0
- package/dist/adapters/postgres/schema.default.d.ts.map +1 -1
- package/dist/adapters/postgres/schema.js +2 -0
- package/dist/adapters/schemas.d.ts +4 -0
- package/dist/adapters/schemas.d.ts.map +1 -1
- package/dist/adapters/schemas.js +3 -0
- package/dist/client.d.ts +109 -14
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -64
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -1
- package/migrations/postgres/20260121134451_thankful_manta/migration.sql +2 -0
- package/migrations/postgres/20260121134451_thankful_manta/snapshot.json +1503 -0
- package/package.json +1 -1
- package/src/action.ts +254 -143
- package/src/adapters/postgres/base.ts +124 -21
- package/src/adapters/postgres/schema.ts +2 -0
- package/src/adapters/schemas.ts +3 -0
- package/src/client.ts +79 -26
package/package.json
CHANGED
package/src/action.ts
CHANGED
|
@@ -183,95 +183,274 @@ export interface ConcurrencyHandlerContext<TInput extends z.ZodObject, TVariable
|
|
|
183
183
|
var: TVariables
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
-
export type ActionDefinition<
|
|
187
|
-
TInput extends z.ZodObject,
|
|
188
|
-
TOutput extends z.ZodObject,
|
|
189
|
-
TVariables = Record<string, unknown>,
|
|
190
|
-
> = z.input<ReturnType<typeof createActionDefinitionSchema<TInput, TOutput, TVariables>>>
|
|
191
|
-
|
|
192
|
-
export type Action<
|
|
193
|
-
TInput extends z.ZodObject,
|
|
194
|
-
TOutput extends z.ZodObject,
|
|
195
|
-
TVariables = Record<string, unknown>,
|
|
196
|
-
> = z.infer<ReturnType<typeof createActionDefinitionSchema<TInput, TOutput, TVariables>>>
|
|
197
|
-
|
|
198
186
|
/**
|
|
199
187
|
* Retry configuration options for actions and steps.
|
|
188
|
+
* Controls how failed operations are retried with exponential backoff.
|
|
200
189
|
*/
|
|
201
|
-
export
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
190
|
+
export interface RetryOptionsInput {
|
|
191
|
+
/**
|
|
192
|
+
* Maximum number of retry attempts.
|
|
193
|
+
* Set to 0 to disable retries.
|
|
194
|
+
*
|
|
195
|
+
* @default 4
|
|
196
|
+
*/
|
|
197
|
+
limit?: number
|
|
209
198
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
199
|
+
/**
|
|
200
|
+
* Exponential backoff factor.
|
|
201
|
+
* The delay between retries is calculated as: `minTimeout * (factor ^ attemptNumber)`
|
|
202
|
+
*
|
|
203
|
+
* @default 2
|
|
204
|
+
*/
|
|
205
|
+
factor?: number
|
|
217
206
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
207
|
+
/**
|
|
208
|
+
* Minimum delay in milliseconds before the first retry.
|
|
209
|
+
* This is the base delay that gets multiplied by the factor.
|
|
210
|
+
*
|
|
211
|
+
* @default 1000
|
|
212
|
+
*/
|
|
213
|
+
minTimeout?: number
|
|
224
214
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
.describe('The retry options')
|
|
215
|
+
/**
|
|
216
|
+
* Maximum delay in milliseconds between retries.
|
|
217
|
+
* The calculated delay will be capped at this value to prevent
|
|
218
|
+
* excessively long wait times.
|
|
219
|
+
*
|
|
220
|
+
* @default 30000
|
|
221
|
+
*/
|
|
222
|
+
maxTimeout?: number
|
|
223
|
+
}
|
|
235
224
|
|
|
236
225
|
/**
|
|
237
|
-
*
|
|
226
|
+
* Configuration options for steps within an action.
|
|
227
|
+
* Controls concurrency, retries, and timeouts for step execution.
|
|
238
228
|
*/
|
|
239
|
-
export
|
|
229
|
+
export interface StepsConfigInput {
|
|
240
230
|
/**
|
|
241
|
-
*
|
|
242
|
-
*
|
|
231
|
+
* Maximum number of steps that can run concurrently within this action.
|
|
232
|
+
* Higher values allow more parallelism but may increase resource usage.
|
|
233
|
+
*
|
|
234
|
+
* @default 100
|
|
243
235
|
*/
|
|
244
|
-
|
|
236
|
+
concurrency?: number
|
|
245
237
|
|
|
246
238
|
/**
|
|
247
|
-
*
|
|
248
|
-
*
|
|
239
|
+
* Retry configuration for steps.
|
|
240
|
+
* These settings apply to all steps unless overridden at the step level.
|
|
241
|
+
*
|
|
242
|
+
* @default { limit: 4, factor: 2, minTimeout: 1000, maxTimeout: 30000 }
|
|
243
|
+
*/
|
|
244
|
+
retry?: RetryOptionsInput
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Timeout in milliseconds for each step.
|
|
248
|
+
* Steps that exceed this timeout will be cancelled and may be retried.
|
|
249
249
|
*
|
|
250
250
|
* @default 300000 (5 minutes)
|
|
251
251
|
*/
|
|
252
|
-
expire
|
|
253
|
-
|
|
254
|
-
.default(5 * 60 * 1000)
|
|
255
|
-
.describe('The expire time for the step (milliseconds)'),
|
|
252
|
+
expire?: number
|
|
253
|
+
}
|
|
256
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Group configuration for concurrency control.
|
|
257
|
+
* Allows grouping jobs by key and controlling concurrency per group.
|
|
258
|
+
*/
|
|
259
|
+
export interface GroupsConfigInput<TInput extends z.ZodObject, TVariables = Record<string, unknown>> {
|
|
257
260
|
/**
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
+
* Function to determine the group key for a job.
|
|
262
|
+
* Jobs with the same group key will respect the group concurrency limit.
|
|
263
|
+
* Use this to limit concurrent processing of related jobs (e.g., per user, per tenant).
|
|
264
|
+
*
|
|
265
|
+
* If not provided, all jobs for this action will use the '@default' group key.
|
|
261
266
|
*
|
|
262
|
-
* @
|
|
267
|
+
* @param ctx - Context containing the validated input and variables
|
|
268
|
+
* @returns Promise resolving to the group key string
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* ```typescript
|
|
272
|
+
* groupKey: async (ctx) => `user:${ctx.input.userId}`
|
|
273
|
+
* ```
|
|
263
274
|
*/
|
|
264
|
-
|
|
265
|
-
|
|
275
|
+
groupKey?: (ctx: ConcurrencyHandlerContext<TInput, TVariables>) => Promise<string>
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Function to dynamically determine the concurrency limit for a job's group.
|
|
279
|
+
* The concurrency limit is stored with each job and used during fetch operations.
|
|
280
|
+
* This allows different groups to have different concurrency limits.
|
|
281
|
+
*
|
|
282
|
+
* If not provided, uses the global `groupConcurrencyLimit` from the client options.
|
|
283
|
+
*
|
|
284
|
+
* @param ctx - Context containing the validated input and variables
|
|
285
|
+
* @returns Promise resolving to the concurrency limit number
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```typescript
|
|
289
|
+
* concurrency: async (ctx) => ctx.input.priority === 'high' ? 10 : 2
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
concurrency?: (ctx: ConcurrencyHandlerContext<TInput, TVariables>) => Promise<number>
|
|
293
|
+
}
|
|
266
294
|
|
|
267
295
|
/**
|
|
268
|
-
*
|
|
296
|
+
* Definition for creating a Duron action.
|
|
297
|
+
* Actions are type-safe, durable job handlers with built-in retry logic,
|
|
298
|
+
* step-based execution, and concurrency control.
|
|
269
299
|
*
|
|
270
|
-
* @template TInput - Zod schema for the action input
|
|
271
|
-
* @template TOutput - Zod schema for the action output
|
|
272
|
-
* @template TVariables - Type of variables available to the action
|
|
273
|
-
* @returns Zod schema for action definitions
|
|
300
|
+
* @template TInput - Zod schema type for validating the action input
|
|
301
|
+
* @template TOutput - Zod schema type for validating the action output
|
|
302
|
+
* @template TVariables - Type of variables available to the action handler
|
|
274
303
|
*/
|
|
304
|
+
export interface ActionDefinitionInput<
|
|
305
|
+
TInput extends z.ZodObject,
|
|
306
|
+
TOutput extends z.ZodObject,
|
|
307
|
+
TVariables = Record<string, unknown>,
|
|
308
|
+
> {
|
|
309
|
+
/**
|
|
310
|
+
* Unique name for this action.
|
|
311
|
+
* Used as the queue name and must be unique across all actions registered with a client.
|
|
312
|
+
* This name is used for job routing, logging, and dashboard display.
|
|
313
|
+
*
|
|
314
|
+
* @example 'send-email', 'process-payment', 'sync-user-data'
|
|
315
|
+
*/
|
|
316
|
+
name: string
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Optional version string for the action.
|
|
320
|
+
* Used to track changes to the action and included in the checksum calculation.
|
|
321
|
+
* Changing the version will cause existing jobs to be treated as having a different checksum.
|
|
322
|
+
*
|
|
323
|
+
* @example '1.0.0', '2024-01-15', 'v2'
|
|
324
|
+
*/
|
|
325
|
+
version?: string
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Zod schema for validating the action input.
|
|
329
|
+
* If provided, input will be validated before the handler is called.
|
|
330
|
+
* Invalid input will throw a validation error and the job will fail.
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* ```typescript
|
|
334
|
+
* input: z.object({
|
|
335
|
+
* email: z.string().email(),
|
|
336
|
+
* subject: z.string().min(1),
|
|
337
|
+
* })
|
|
338
|
+
* ```
|
|
339
|
+
*/
|
|
340
|
+
input?: TInput
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Zod schema for validating the action output.
|
|
344
|
+
* If provided, output will be validated after the handler completes.
|
|
345
|
+
* Invalid output will cause the job to fail.
|
|
346
|
+
*
|
|
347
|
+
* @example
|
|
348
|
+
* ```typescript
|
|
349
|
+
* output: z.object({
|
|
350
|
+
* success: z.boolean(),
|
|
351
|
+
* messageId: z.string().optional(),
|
|
352
|
+
* })
|
|
353
|
+
* ```
|
|
354
|
+
*/
|
|
355
|
+
output?: TOutput
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Group configuration for concurrency control.
|
|
359
|
+
* Allows grouping jobs by a dynamic key and controlling concurrency per group.
|
|
360
|
+
* Useful for rate limiting per user, tenant, or resource.
|
|
361
|
+
*/
|
|
362
|
+
groups?: GroupsConfigInput<TInput, TVariables>
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Configuration for steps within this action.
|
|
366
|
+
* Steps are retryable units of work that can be executed within the action handler.
|
|
367
|
+
* These settings apply to all steps unless overridden at the step level.
|
|
368
|
+
*
|
|
369
|
+
* @default { concurrency: 100, retry: { limit: 4, factor: 2, minTimeout: 1000, maxTimeout: 30000 }, expire: 300000 }
|
|
370
|
+
*/
|
|
371
|
+
steps?: StepsConfigInput
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Maximum number of jobs for this action that can run concurrently across all workers.
|
|
375
|
+
* This limit is enforced per action, regardless of group.
|
|
376
|
+
*
|
|
377
|
+
* @default 100
|
|
378
|
+
*/
|
|
379
|
+
concurrency?: number
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Timeout in milliseconds for the entire action.
|
|
383
|
+
* Jobs that exceed this timeout will be cancelled.
|
|
384
|
+
* Make sure this is greater than the expected total execution time including all steps.
|
|
385
|
+
*
|
|
386
|
+
* @default 900000 (15 minutes)
|
|
387
|
+
*/
|
|
388
|
+
expire?: number
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* The handler function that executes the action logic.
|
|
392
|
+
* Receives a context object with validated input, variables, logger, and step functions.
|
|
393
|
+
* Must return a Promise that resolves to the action output (matching the output schema if provided).
|
|
394
|
+
*
|
|
395
|
+
* @param ctx - Action handler context with input, variables, and step functions
|
|
396
|
+
* @returns Promise resolving to the action output
|
|
397
|
+
*
|
|
398
|
+
* @example
|
|
399
|
+
* ```typescript
|
|
400
|
+
* handler: async (ctx) => {
|
|
401
|
+
* const result = await ctx.step('send', async () => {
|
|
402
|
+
* return await sendEmail(ctx.input.email, ctx.input.subject)
|
|
403
|
+
* })
|
|
404
|
+
* return { success: true, messageId: result.id }
|
|
405
|
+
* }
|
|
406
|
+
* ```
|
|
407
|
+
*/
|
|
408
|
+
handler: (ctx: ActionHandlerContext<TInput, TVariables>) => Promise<z.infer<TOutput>>
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// Type alias for backwards compatibility (inferred from Zod schema)
|
|
412
|
+
export type ActionDefinition<
|
|
413
|
+
TInput extends z.ZodObject,
|
|
414
|
+
TOutput extends z.ZodObject,
|
|
415
|
+
TVariables = Record<string, unknown>,
|
|
416
|
+
> = ActionDefinitionInput<TInput, TOutput, TVariables>
|
|
417
|
+
|
|
418
|
+
// Compile-time check: ensure ActionDefinitionInput is assignable to the Zod schema's input type
|
|
419
|
+
type _EnsureActionDefinitionCompatible<
|
|
420
|
+
TInput extends z.ZodObject,
|
|
421
|
+
TOutput extends z.ZodObject,
|
|
422
|
+
TVariables,
|
|
423
|
+
> = ActionDefinitionInput<TInput, TOutput, TVariables> extends z.input<
|
|
424
|
+
ReturnType<typeof createActionDefinitionSchema<TInput, TOutput, TVariables>>
|
|
425
|
+
>
|
|
426
|
+
? true
|
|
427
|
+
: 'ERROR: ActionDefinitionInput does not match Zod schema input type'
|
|
428
|
+
|
|
429
|
+
// This will cause a compile error if the types diverge
|
|
430
|
+
declare const _actionDefCheck: _EnsureActionDefinitionCompatible<z.ZodObject<any>, z.ZodObject<any>, any>
|
|
431
|
+
const _checkActionDef: _EnsureActionDefinitionCompatible<z.ZodObject<any>, z.ZodObject<any>, any> = true
|
|
432
|
+
|
|
433
|
+
export type Action<
|
|
434
|
+
TInput extends z.ZodObject,
|
|
435
|
+
TOutput extends z.ZodObject,
|
|
436
|
+
TVariables = Record<string, unknown>,
|
|
437
|
+
> = z.infer<ReturnType<typeof createActionDefinitionSchema<TInput, TOutput, TVariables>>>
|
|
438
|
+
|
|
439
|
+
export const RetryOptionsSchema = z
|
|
440
|
+
.object({
|
|
441
|
+
limit: z.number().default(4),
|
|
442
|
+
factor: z.number().default(2),
|
|
443
|
+
minTimeout: z.number().default(1000),
|
|
444
|
+
maxTimeout: z.number().default(30000),
|
|
445
|
+
})
|
|
446
|
+
.default({ limit: 4, factor: 2, minTimeout: 1000, maxTimeout: 30000 })
|
|
447
|
+
|
|
448
|
+
export const StepOptionsSchema = z.object({
|
|
449
|
+
retry: RetryOptionsSchema,
|
|
450
|
+
expire: z.number().default(5 * 60 * 1000),
|
|
451
|
+
parallel: z.boolean().default(false),
|
|
452
|
+
})
|
|
453
|
+
|
|
275
454
|
export function createActionDefinitionSchema<
|
|
276
455
|
TInput extends z.ZodObject,
|
|
277
456
|
TOutput extends z.ZodObject,
|
|
@@ -279,66 +458,25 @@ export function createActionDefinitionSchema<
|
|
|
279
458
|
>() {
|
|
280
459
|
return z
|
|
281
460
|
.object({
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
* Used as the queue name and must be unique across all actions.
|
|
285
|
-
* Required.
|
|
286
|
-
*/
|
|
287
|
-
name: z.string().describe('The name of the action'),
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Version of the action.
|
|
291
|
-
* Used to track changes to the action and generate the checksum.
|
|
292
|
-
*/
|
|
293
|
-
version: z.string().describe('The version of the action').optional(),
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Zod schema for validating the action input.
|
|
297
|
-
* If provided, input will be validated before the handler is called.
|
|
298
|
-
* If not provided, any input will be accepted.
|
|
299
|
-
*/
|
|
461
|
+
name: z.string(),
|
|
462
|
+
version: z.string().optional(),
|
|
300
463
|
input: z
|
|
301
464
|
.custom<TInput>((val: any) => {
|
|
302
465
|
return !val || ('_zod' in val && 'type' in val && val.type === 'object')
|
|
303
466
|
})
|
|
304
467
|
.optional(),
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Zod schema for validating the action output.
|
|
308
|
-
* If provided, output will be validated after the handler completes.
|
|
309
|
-
* If not provided, any output will be accepted.
|
|
310
|
-
*/
|
|
311
468
|
output: z
|
|
312
469
|
.custom<TOutput>((val: any) => {
|
|
313
470
|
return !val || ('_zod' in val && 'type' in val && val.type === 'object')
|
|
314
471
|
})
|
|
315
472
|
.optional(),
|
|
316
|
-
|
|
317
473
|
groups: z
|
|
318
474
|
.object({
|
|
319
|
-
/**
|
|
320
|
-
* Function to determine the group key for a job.
|
|
321
|
-
* Jobs with the same group key will respect the group concurrency limit.
|
|
322
|
-
* If not provided, all jobs for this action will use the '@default' group key.
|
|
323
|
-
*
|
|
324
|
-
* @param ctx - Context containing the input and variables
|
|
325
|
-
* @returns Promise resolving to the group key string
|
|
326
|
-
*/
|
|
327
475
|
groupKey: z
|
|
328
476
|
.custom<(ctx: ConcurrencyHandlerContext<TInput, TVariables>) => Promise<string>>((val) => {
|
|
329
477
|
return !val || val instanceof Function
|
|
330
478
|
})
|
|
331
479
|
.optional(),
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Function to determine the concurrency limit for a job.
|
|
335
|
-
* The concurrency limit is stored with each job and used during fetch operations.
|
|
336
|
-
* When fetching jobs, the latest job's concurrency limit is used for each groupKey.
|
|
337
|
-
* If not provided, defaults to 10.
|
|
338
|
-
*
|
|
339
|
-
* @param ctx - Context containing the input and variables
|
|
340
|
-
* @returns Promise resolving to the concurrency limit number
|
|
341
|
-
*/
|
|
342
480
|
concurrency: z
|
|
343
481
|
.custom<(ctx: ConcurrencyHandlerContext<TInput, TVariables>) => Promise<number>>((val) => {
|
|
344
482
|
return !val || val instanceof Function
|
|
@@ -346,49 +484,22 @@ export function createActionDefinitionSchema<
|
|
|
346
484
|
.optional(),
|
|
347
485
|
})
|
|
348
486
|
.optional(),
|
|
349
|
-
|
|
350
487
|
steps: z
|
|
351
488
|
.object({
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
* When fetching steps, the latest step's concurrency limit is used for each stepKey.
|
|
356
|
-
* If not provided, defaults to 100.
|
|
357
|
-
*/
|
|
358
|
-
concurrency: z.number().default(100).describe('How many steps can run concurrently for this action'),
|
|
359
|
-
retry: RetryOptionsSchema.describe('How to retry on failure for the steps of this action'),
|
|
360
|
-
expire: z
|
|
361
|
-
.number()
|
|
362
|
-
.default(5 * 60 * 1000)
|
|
363
|
-
.describe('How long a step can run for (milliseconds)'),
|
|
489
|
+
concurrency: z.number().default(100),
|
|
490
|
+
retry: RetryOptionsSchema,
|
|
491
|
+
expire: z.number().default(5 * 60 * 1000),
|
|
364
492
|
})
|
|
365
493
|
.default({
|
|
366
494
|
concurrency: 100,
|
|
367
495
|
retry: { limit: 4, factor: 2, minTimeout: 1000, maxTimeout: 30000 },
|
|
368
496
|
expire: 5 * 60 * 1000,
|
|
369
497
|
}),
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
.default(15 * 60 * 1000)
|
|
376
|
-
.describe('How long a job can run for (milliseconds)'),
|
|
377
|
-
|
|
378
|
-
/**
|
|
379
|
-
* The handler function that executes the action logic.
|
|
380
|
-
* Receives a context object with input, variables, and a step function.
|
|
381
|
-
* Must return a Promise that resolves to the action output.
|
|
382
|
-
* Required.
|
|
383
|
-
*
|
|
384
|
-
* @param ctx - Action handler context
|
|
385
|
-
* @returns Promise resolving to the action output
|
|
386
|
-
*/
|
|
387
|
-
handler: z
|
|
388
|
-
.custom<(ctx: ActionHandlerContext<TInput, TVariables>) => Promise<z.infer<TOutput>>>((val) => {
|
|
389
|
-
return val instanceof Function
|
|
390
|
-
})
|
|
391
|
-
.describe('The handler for the action'),
|
|
498
|
+
concurrency: z.number().default(100),
|
|
499
|
+
expire: z.number().default(15 * 60 * 1000),
|
|
500
|
+
handler: z.custom<(ctx: ActionHandlerContext<TInput, TVariables>) => Promise<z.infer<TOutput>>>((val) => {
|
|
501
|
+
return val instanceof Function
|
|
502
|
+
}),
|
|
392
503
|
})
|
|
393
504
|
.transform((def) => {
|
|
394
505
|
const checksum = [def.name, def.version, def.handler.toString()].filter(Boolean).join(':')
|