@temporal-contract/contract 0.0.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/dist/index.cjs +14 -129
- package/dist/index.d.cts +14 -238
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +14 -238
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +15 -128
- package/dist/index.mjs.map +1 -0
- package/package.json +10 -6
package/README.md
CHANGED
|
@@ -13,18 +13,20 @@ pnpm add @temporal-contract/contract zod
|
|
|
13
13
|
## Quick Example
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
|
-
import { defineContract } from
|
|
17
|
-
import { z } from
|
|
16
|
+
import { defineContract } from "@temporal-contract/contract";
|
|
17
|
+
import { z } from "zod";
|
|
18
18
|
|
|
19
19
|
export const myContract = defineContract({
|
|
20
|
-
taskQueue:
|
|
20
|
+
taskQueue: "orders",
|
|
21
21
|
workflows: {
|
|
22
22
|
processOrder: {
|
|
23
23
|
input: z.object({ orderId: z.string() }),
|
|
24
24
|
output: z.object({ success: z.boolean() }),
|
|
25
|
-
activities: {
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
activities: {
|
|
26
|
+
/* ... */
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
28
30
|
});
|
|
29
31
|
```
|
|
30
32
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
1
2
|
let zod = require("zod");
|
|
2
3
|
|
|
3
4
|
//#region src/builder.ts
|
|
@@ -227,21 +228,21 @@ function isStandardSchema(value) {
|
|
|
227
228
|
*/
|
|
228
229
|
const identifierSchema = zod.z.string().min(1).regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, "must be a valid JavaScript identifier");
|
|
229
230
|
/**
|
|
230
|
-
* Extract clean error message from Zod validation error
|
|
231
|
+
* Extract a clean, single-line error message from a Zod validation error.
|
|
232
|
+
*
|
|
233
|
+
* Uses `error.issues` directly (compatible with Zod v4+) rather than parsing
|
|
234
|
+
* `error.message` as JSON, which was a Zod v3 implementation detail.
|
|
231
235
|
*/
|
|
232
236
|
function getCleanErrorMessage(error) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
} catch {}
|
|
244
|
-
return error.message;
|
|
237
|
+
const issues = error.issues;
|
|
238
|
+
if (!issues || issues.length === 0) return error.message;
|
|
239
|
+
const firstIssue = issues[0];
|
|
240
|
+
if (!firstIssue) return error.message;
|
|
241
|
+
if (firstIssue.code === "invalid_key" && "issues" in firstIssue && Array.isArray(firstIssue.issues) && firstIssue.issues.length > 0) {
|
|
242
|
+
const nestedMessage = firstIssue.issues[0]?.message;
|
|
243
|
+
if (nestedMessage) return nestedMessage;
|
|
244
|
+
}
|
|
245
|
+
return firstIssue.message ?? error.message;
|
|
245
246
|
}
|
|
246
247
|
/**
|
|
247
248
|
* Schema for validating activity definitions
|
|
@@ -300,125 +301,9 @@ const contractValidationSchema = zod.z.object({
|
|
|
300
301
|
}
|
|
301
302
|
});
|
|
302
303
|
|
|
303
|
-
//#endregion
|
|
304
|
-
//#region src/nexus-types.ts
|
|
305
|
-
/**
|
|
306
|
-
* BUILDER FUNCTIONS (Proposed API)
|
|
307
|
-
* These would be added to builder.ts when Nexus support is implemented
|
|
308
|
-
*/
|
|
309
|
-
/**
|
|
310
|
-
* Builder for creating Nexus operation definitions
|
|
311
|
-
*
|
|
312
|
-
* @template TOperation - A NexusOperationDefinition containing input and output schemas
|
|
313
|
-
* @param definition - The Nexus operation definition with typed input/output schemas
|
|
314
|
-
* @returns The same definition with preserved types
|
|
315
|
-
*
|
|
316
|
-
* @example
|
|
317
|
-
* ```typescript
|
|
318
|
-
* const processPayment = defineNexusOperation({
|
|
319
|
-
* input: z.object({ amount: z.number(), customerId: z.string() }),
|
|
320
|
-
* output: z.object({ transactionId: z.string(), status: z.enum(['success', 'failed']) }),
|
|
321
|
-
* });
|
|
322
|
-
* ```
|
|
323
|
-
*/
|
|
324
|
-
function defineNexusOperation(definition) {
|
|
325
|
-
return definition;
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Builder for creating Nexus service definitions
|
|
329
|
-
*
|
|
330
|
-
* @template TService - A NexusServiceDefinition containing a record of operations
|
|
331
|
-
* @param definition - The Nexus service definition with typed operations
|
|
332
|
-
* @returns The same definition with preserved types
|
|
333
|
-
*
|
|
334
|
-
* @example
|
|
335
|
-
* ```typescript
|
|
336
|
-
* const PaymentService = defineNexusService({
|
|
337
|
-
* operations: {
|
|
338
|
-
* processPayment: defineNexusOperation({ ... }),
|
|
339
|
-
* refundPayment: defineNexusOperation({ ... }),
|
|
340
|
-
* },
|
|
341
|
-
* });
|
|
342
|
-
* ```
|
|
343
|
-
*/
|
|
344
|
-
function defineNexusService(definition) {
|
|
345
|
-
return definition;
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* USAGE EXAMPLE
|
|
349
|
-
*
|
|
350
|
-
* This example demonstrates the complete type-safe Nexus workflow:
|
|
351
|
-
*
|
|
352
|
-
* ```typescript
|
|
353
|
-
* import { defineContract, defineNexusService, defineNexusOperation } from '@temporal-contract/contract';
|
|
354
|
-
* import { z } from 'zod';
|
|
355
|
-
*
|
|
356
|
-
* // 1. Define contract with Nexus service
|
|
357
|
-
* const paymentContract = defineContract({
|
|
358
|
-
* taskQueue: 'payments',
|
|
359
|
-
* workflows: { ... },
|
|
360
|
-
* nexusServices: {
|
|
361
|
-
* PaymentService: defineNexusService({
|
|
362
|
-
* operations: {
|
|
363
|
-
* processPayment: defineNexusOperation({
|
|
364
|
-
* input: z.object({
|
|
365
|
-
* amount: z.number().positive(),
|
|
366
|
-
* customerId: z.string().uuid(),
|
|
367
|
-
* }),
|
|
368
|
-
* output: z.object({
|
|
369
|
-
* transactionId: z.string(),
|
|
370
|
-
* status: z.enum(['success', 'failed']),
|
|
371
|
-
* }),
|
|
372
|
-
* }),
|
|
373
|
-
* },
|
|
374
|
-
* }),
|
|
375
|
-
* },
|
|
376
|
-
* });
|
|
377
|
-
*
|
|
378
|
-
* // 2. Worker implementation (type-safe handlers)
|
|
379
|
-
* import { createNexusHandlers } from '@temporal-contract/worker';
|
|
380
|
-
*
|
|
381
|
-
* const nexusHandlers = createNexusHandlers(paymentContract, {
|
|
382
|
-
* PaymentService: {
|
|
383
|
-
* processPayment: async ({ amount, customerId }) => {
|
|
384
|
-
* // ✅ Fully typed parameters
|
|
385
|
-
* // ✅ Input automatically validated
|
|
386
|
-
* const payment = await processPaymentInDatabase(customerId, amount);
|
|
387
|
-
* // ✅ Return value validated against schema
|
|
388
|
-
* return {
|
|
389
|
-
* transactionId: payment.id,
|
|
390
|
-
* status: 'success',
|
|
391
|
-
* };
|
|
392
|
-
* },
|
|
393
|
-
* },
|
|
394
|
-
* });
|
|
395
|
-
*
|
|
396
|
-
* // 3. Client usage (type-safe invocation)
|
|
397
|
-
* import { createNexusClient } from '@temporal-contract/client';
|
|
398
|
-
*
|
|
399
|
-
* const nexusClient = createNexusClient<typeof paymentContract>(connection, {
|
|
400
|
-
* namespace: 'payments-ns',
|
|
401
|
-
* });
|
|
402
|
-
*
|
|
403
|
-
* // ✅ Fully typed invocation
|
|
404
|
-
* const result = await nexusClient.invoke('PaymentService', 'processPayment', {
|
|
405
|
-
* amount: 100,
|
|
406
|
-
* customerId: 'cust-123',
|
|
407
|
-
* });
|
|
408
|
-
*
|
|
409
|
-
* // ❌ TypeScript errors caught at compile time
|
|
410
|
-
* await nexusClient.invoke('PaymentService', 'processPayment', {
|
|
411
|
-
* amount: -50, // Error: amount must be positive
|
|
412
|
-
* customerId: 'invalid', // Error: customerId must be UUID
|
|
413
|
-
* });
|
|
414
|
-
* ```
|
|
415
|
-
*/
|
|
416
|
-
|
|
417
304
|
//#endregion
|
|
418
305
|
exports.defineActivity = defineActivity;
|
|
419
306
|
exports.defineContract = defineContract;
|
|
420
|
-
exports.defineNexusOperation = defineNexusOperation;
|
|
421
|
-
exports.defineNexusService = defineNexusService;
|
|
422
307
|
exports.defineQuery = defineQuery;
|
|
423
308
|
exports.defineSignal = defineSignal;
|
|
424
309
|
exports.defineUpdate = defineUpdate;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
2
|
|
|
3
3
|
//#region src/types.d.ts
|
|
4
|
-
|
|
5
4
|
/**
|
|
6
5
|
* Base types for validation schemas
|
|
7
6
|
* Any schema that implements the Standard Schema specification
|
|
@@ -11,49 +10,49 @@ type AnySchema = StandardSchemaV1;
|
|
|
11
10
|
/**
|
|
12
11
|
* Definition of an activity
|
|
13
12
|
*/
|
|
14
|
-
|
|
13
|
+
type ActivityDefinition<TInput extends AnySchema = AnySchema, TOutput extends AnySchema = AnySchema> = {
|
|
15
14
|
readonly input: TInput;
|
|
16
15
|
readonly output: TOutput;
|
|
17
|
-
}
|
|
16
|
+
};
|
|
18
17
|
/**
|
|
19
18
|
* Definition of a signal
|
|
20
19
|
*/
|
|
21
|
-
|
|
20
|
+
type SignalDefinition<TInput extends AnySchema = AnySchema> = {
|
|
22
21
|
readonly input: TInput;
|
|
23
|
-
}
|
|
22
|
+
};
|
|
24
23
|
/**
|
|
25
24
|
* Definition of a query
|
|
26
25
|
*/
|
|
27
|
-
|
|
26
|
+
type QueryDefinition<TInput extends AnySchema = AnySchema, TOutput extends AnySchema = AnySchema> = {
|
|
28
27
|
readonly input: TInput;
|
|
29
28
|
readonly output: TOutput;
|
|
30
|
-
}
|
|
29
|
+
};
|
|
31
30
|
/**
|
|
32
31
|
* Definition of an update
|
|
33
32
|
*/
|
|
34
|
-
|
|
33
|
+
type UpdateDefinition<TInput extends AnySchema = AnySchema, TOutput extends AnySchema = AnySchema> = {
|
|
35
34
|
readonly input: TInput;
|
|
36
35
|
readonly output: TOutput;
|
|
37
|
-
}
|
|
36
|
+
};
|
|
38
37
|
/**
|
|
39
38
|
* Definition of a workflow
|
|
40
39
|
*/
|
|
41
|
-
|
|
40
|
+
type WorkflowDefinition<TActivities extends Record<string, ActivityDefinition> = Record<string, ActivityDefinition>, TSignals extends Record<string, SignalDefinition> = Record<string, SignalDefinition>, TQueries extends Record<string, QueryDefinition> = Record<string, QueryDefinition>, TUpdates extends Record<string, UpdateDefinition> = Record<string, UpdateDefinition>> = {
|
|
42
41
|
readonly input: AnySchema;
|
|
43
42
|
readonly output: AnySchema;
|
|
44
43
|
readonly activities?: TActivities;
|
|
45
44
|
readonly signals?: TSignals;
|
|
46
45
|
readonly queries?: TQueries;
|
|
47
46
|
readonly updates?: TUpdates;
|
|
48
|
-
}
|
|
47
|
+
};
|
|
49
48
|
/**
|
|
50
49
|
* Contract definition containing workflows and optional global activities
|
|
51
50
|
*/
|
|
52
|
-
|
|
51
|
+
type ContractDefinition<TWorkflows extends Record<string, WorkflowDefinition> = Record<string, WorkflowDefinition>, TActivities extends Record<string, ActivityDefinition> = Record<string, ActivityDefinition>> = {
|
|
53
52
|
readonly taskQueue: string;
|
|
54
53
|
readonly workflows: TWorkflows;
|
|
55
54
|
readonly activities?: TActivities;
|
|
56
|
-
}
|
|
55
|
+
};
|
|
57
56
|
/**
|
|
58
57
|
* UTILITY TYPES
|
|
59
58
|
*/
|
|
@@ -283,228 +282,5 @@ declare function defineWorkflow<TWorkflow extends WorkflowDefinition>(definition
|
|
|
283
282
|
*/
|
|
284
283
|
declare function defineContract<TContract extends ContractDefinition>(definition: TContract): TContract;
|
|
285
284
|
//#endregion
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
* Definition of a Nexus operation
|
|
289
|
-
* Similar to ActivityDefinition but for cross-namespace operations
|
|
290
|
-
*
|
|
291
|
-
* @example
|
|
292
|
-
* ```typescript
|
|
293
|
-
* const processPayment = {
|
|
294
|
-
* input: z.object({ amount: z.number(), customerId: z.string() }),
|
|
295
|
-
* output: z.object({ transactionId: z.string(), status: z.enum(['success', 'failed']) }),
|
|
296
|
-
* };
|
|
297
|
-
* ```
|
|
298
|
-
*/
|
|
299
|
-
interface NexusOperationDefinition<TInput extends AnySchema = AnySchema, TOutput extends AnySchema = AnySchema> {
|
|
300
|
-
readonly input: TInput;
|
|
301
|
-
readonly output: TOutput;
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Definition of a Nexus service containing multiple operations
|
|
305
|
-
*
|
|
306
|
-
* @example
|
|
307
|
-
* ```typescript
|
|
308
|
-
* const PaymentService = {
|
|
309
|
-
* operations: {
|
|
310
|
-
* processPayment: { input: ..., output: ... },
|
|
311
|
-
* refundPayment: { input: ..., output: ... },
|
|
312
|
-
* },
|
|
313
|
-
* };
|
|
314
|
-
* ```
|
|
315
|
-
*/
|
|
316
|
-
interface NexusServiceDefinition<TOperations extends Record<string, NexusOperationDefinition> = Record<string, NexusOperationDefinition>> {
|
|
317
|
-
readonly operations: TOperations;
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Extended ContractDefinition that includes Nexus services
|
|
321
|
-
* This would replace the current ContractDefinition when Nexus support is added
|
|
322
|
-
*
|
|
323
|
-
* @example
|
|
324
|
-
* ```typescript
|
|
325
|
-
* const contract = defineContract({
|
|
326
|
-
* taskQueue: 'payments',
|
|
327
|
-
* workflows: { ... },
|
|
328
|
-
* activities: { ... },
|
|
329
|
-
* nexusServices: {
|
|
330
|
-
* PaymentService: {
|
|
331
|
-
* operations: {
|
|
332
|
-
* processPayment: { input: ..., output: ... },
|
|
333
|
-
* },
|
|
334
|
-
* },
|
|
335
|
-
* },
|
|
336
|
-
* });
|
|
337
|
-
* ```
|
|
338
|
-
*/
|
|
339
|
-
interface ContractDefinitionWithNexus<TWorkflows extends Record<string, WorkflowDefinition> = Record<string, WorkflowDefinition>, TActivities extends Record<string, ActivityDefinition> = Record<string, ActivityDefinition>, TNexusServices extends Record<string, NexusServiceDefinition> = Record<string, NexusServiceDefinition>> {
|
|
340
|
-
readonly taskQueue: string;
|
|
341
|
-
readonly workflows: TWorkflows;
|
|
342
|
-
readonly activities?: TActivities;
|
|
343
|
-
readonly nexusServices?: TNexusServices;
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* WORKER PERSPECTIVE - Nexus operation handler type inference
|
|
347
|
-
* Worker receives the parsed input and returns the raw output
|
|
348
|
-
*/
|
|
349
|
-
/**
|
|
350
|
-
* Infer input type from a Nexus operation definition (worker perspective)
|
|
351
|
-
*/
|
|
352
|
-
type WorkerInferNexusOperationInput<T extends NexusOperationDefinition> = StandardSchemaV1.InferOutput<T["input"]>;
|
|
353
|
-
/**
|
|
354
|
-
* Infer output type from a Nexus operation definition (worker perspective)
|
|
355
|
-
*/
|
|
356
|
-
type WorkerInferNexusOperationOutput<T extends NexusOperationDefinition> = StandardSchemaV1.InferInput<T["output"]>;
|
|
357
|
-
/**
|
|
358
|
-
* Infer the handler function signature for a Nexus operation (worker perspective)
|
|
359
|
-
*
|
|
360
|
-
* @example
|
|
361
|
-
* ```typescript
|
|
362
|
-
* type ProcessPaymentHandler = WorkerInferNexusOperationHandler<typeof processPaymentOperation>;
|
|
363
|
-
* // (args: { amount: number; customerId: string }) => Promise<{ transactionId: string; status: 'success' | 'failed' }>
|
|
364
|
-
* ```
|
|
365
|
-
*/
|
|
366
|
-
type WorkerInferNexusOperationHandler<TOperation extends NexusOperationDefinition> = (args: WorkerInferNexusOperationInput<TOperation>) => Promise<WorkerInferNexusOperationOutput<TOperation>>;
|
|
367
|
-
/**
|
|
368
|
-
* Infer all operation handlers for a Nexus service (worker perspective)
|
|
369
|
-
*
|
|
370
|
-
* @example
|
|
371
|
-
* ```typescript
|
|
372
|
-
* type PaymentServiceHandlers = WorkerInferNexusServiceHandlers<typeof PaymentService>;
|
|
373
|
-
* // {
|
|
374
|
-
* // processPayment: (args: { ... }) => Promise<{ ... }>;
|
|
375
|
-
* // refundPayment: (args: { ... }) => Promise<{ ... }>;
|
|
376
|
-
* // }
|
|
377
|
-
* ```
|
|
378
|
-
*/
|
|
379
|
-
type WorkerInferNexusServiceHandlers<T extends NexusServiceDefinition> = { [K in keyof T["operations"]]: WorkerInferNexusOperationHandler<T["operations"][K]> };
|
|
380
|
-
/**
|
|
381
|
-
* Infer all Nexus service handlers from a contract (worker perspective)
|
|
382
|
-
*
|
|
383
|
-
* @example
|
|
384
|
-
* ```typescript
|
|
385
|
-
* type AllNexusHandlers = WorkerInferNexusServices<typeof myContract>;
|
|
386
|
-
* // {
|
|
387
|
-
* // PaymentService: { processPayment: ..., refundPayment: ... };
|
|
388
|
-
* // InventoryService: { reserveItems: ..., releaseItems: ... };
|
|
389
|
-
* // }
|
|
390
|
-
* ```
|
|
391
|
-
*/
|
|
392
|
-
type WorkerInferNexusServices<TContract extends ContractDefinitionWithNexus> = TContract["nexusServices"] extends Record<string, NexusServiceDefinition> ? { [K in keyof TContract["nexusServices"]]: WorkerInferNexusServiceHandlers<TContract["nexusServices"][K]> } : {};
|
|
393
|
-
/**
|
|
394
|
-
* CLIENT PERSPECTIVE - Nexus operation client type inference
|
|
395
|
-
* Client sends the raw input and receives the parsed output
|
|
396
|
-
*/
|
|
397
|
-
/**
|
|
398
|
-
* Infer input type from a Nexus operation definition (client perspective)
|
|
399
|
-
*/
|
|
400
|
-
type ClientInferNexusOperationInput<T extends NexusOperationDefinition> = StandardSchemaV1.InferInput<T["input"]>;
|
|
401
|
-
/**
|
|
402
|
-
* Infer output type from a Nexus operation definition (client perspective)
|
|
403
|
-
*/
|
|
404
|
-
type ClientInferNexusOperationOutput<T extends NexusOperationDefinition> = StandardSchemaV1.InferOutput<T["output"]>;
|
|
405
|
-
/**
|
|
406
|
-
* Infer the client function signature for a Nexus operation (client perspective)
|
|
407
|
-
*
|
|
408
|
-
* @example
|
|
409
|
-
* ```typescript
|
|
410
|
-
* type ProcessPaymentClient = ClientInferNexusOperationInvoker<typeof processPaymentOperation>;
|
|
411
|
-
* // (args: { amount: number; customerId: string }) => Promise<{ transactionId: string; status: 'success' | 'failed' }>
|
|
412
|
-
* ```
|
|
413
|
-
*/
|
|
414
|
-
type ClientInferNexusOperationInvoker<TOperation extends NexusOperationDefinition> = (args: ClientInferNexusOperationInput<TOperation>) => Promise<ClientInferNexusOperationOutput<TOperation>>;
|
|
415
|
-
/**
|
|
416
|
-
* Infer all operation invokers for a Nexus service (client perspective)
|
|
417
|
-
*/
|
|
418
|
-
type ClientInferNexusServiceOperations<T extends NexusServiceDefinition> = { [K in keyof T["operations"]]: ClientInferNexusOperationInvoker<T["operations"][K]> };
|
|
419
|
-
/**
|
|
420
|
-
* Infer all Nexus service operations from a contract (client perspective)
|
|
421
|
-
*
|
|
422
|
-
* @example
|
|
423
|
-
* ```typescript
|
|
424
|
-
* type AllNexusOperations = ClientInferNexusServices<typeof myContract>;
|
|
425
|
-
* // {
|
|
426
|
-
* // PaymentService: { processPayment: ..., refundPayment: ... };
|
|
427
|
-
* // InventoryService: { reserveItems: ..., releaseItems: ... };
|
|
428
|
-
* // }
|
|
429
|
-
* ```
|
|
430
|
-
*/
|
|
431
|
-
type ClientInferNexusServices<TContract extends ContractDefinitionWithNexus> = TContract["nexusServices"] extends Record<string, NexusServiceDefinition> ? { [K in keyof TContract["nexusServices"]]: ClientInferNexusServiceOperations<TContract["nexusServices"][K]> } : {};
|
|
432
|
-
/**
|
|
433
|
-
* UTILITY TYPES
|
|
434
|
-
*/
|
|
435
|
-
/**
|
|
436
|
-
* Extract service names from a contract as a union type
|
|
437
|
-
*
|
|
438
|
-
* @example
|
|
439
|
-
* ```typescript
|
|
440
|
-
* type MyServiceNames = InferNexusServiceNames<typeof myContract>;
|
|
441
|
-
* // "PaymentService" | "InventoryService"
|
|
442
|
-
* ```
|
|
443
|
-
*/
|
|
444
|
-
type InferNexusServiceNames<TContract extends ContractDefinitionWithNexus> = TContract["nexusServices"] extends Record<string, NexusServiceDefinition> ? keyof TContract["nexusServices"] & string : never;
|
|
445
|
-
/**
|
|
446
|
-
* Extract operation names from a service as a union type
|
|
447
|
-
*
|
|
448
|
-
* @example
|
|
449
|
-
* ```typescript
|
|
450
|
-
* type PaymentOperations = InferNexusOperationNames<typeof myContract, "PaymentService">;
|
|
451
|
-
* // "processPayment" | "refundPayment"
|
|
452
|
-
* ```
|
|
453
|
-
*/
|
|
454
|
-
type InferNexusOperationNames<TContract extends ContractDefinitionWithNexus, TServiceName extends InferNexusServiceNames<TContract>> = TContract["nexusServices"] extends Record<string, NexusServiceDefinition> ? keyof TContract["nexusServices"][TServiceName]["operations"] & string : never;
|
|
455
|
-
/**
|
|
456
|
-
* Infer the handler type for a specific Nexus operation (worker perspective)
|
|
457
|
-
*
|
|
458
|
-
* @example
|
|
459
|
-
* ```typescript
|
|
460
|
-
* const processPayment: NexusOperationHandler<
|
|
461
|
-
* typeof myContract,
|
|
462
|
-
* "PaymentService",
|
|
463
|
-
* "processPayment"
|
|
464
|
-
* > = async ({ amount, customerId }) => {
|
|
465
|
-
* // Implementation
|
|
466
|
-
* return { transactionId: 'tx-123', status: 'success' };
|
|
467
|
-
* };
|
|
468
|
-
* ```
|
|
469
|
-
*/
|
|
470
|
-
type NexusOperationHandler<TContract extends ContractDefinitionWithNexus, TServiceName extends InferNexusServiceNames<TContract>, TOperationName extends InferNexusOperationNames<TContract, TServiceName>> = TContract["nexusServices"] extends Record<string, NexusServiceDefinition> ? (args: WorkerInferNexusOperationInput<TContract["nexusServices"][TServiceName]["operations"][TOperationName]>) => Promise<WorkerInferNexusOperationOutput<TContract["nexusServices"][TServiceName]["operations"][TOperationName]>> : never;
|
|
471
|
-
/**
|
|
472
|
-
* BUILDER FUNCTIONS (Proposed API)
|
|
473
|
-
* These would be added to builder.ts when Nexus support is implemented
|
|
474
|
-
*/
|
|
475
|
-
/**
|
|
476
|
-
* Builder for creating Nexus operation definitions
|
|
477
|
-
*
|
|
478
|
-
* @template TOperation - A NexusOperationDefinition containing input and output schemas
|
|
479
|
-
* @param definition - The Nexus operation definition with typed input/output schemas
|
|
480
|
-
* @returns The same definition with preserved types
|
|
481
|
-
*
|
|
482
|
-
* @example
|
|
483
|
-
* ```typescript
|
|
484
|
-
* const processPayment = defineNexusOperation({
|
|
485
|
-
* input: z.object({ amount: z.number(), customerId: z.string() }),
|
|
486
|
-
* output: z.object({ transactionId: z.string(), status: z.enum(['success', 'failed']) }),
|
|
487
|
-
* });
|
|
488
|
-
* ```
|
|
489
|
-
*/
|
|
490
|
-
declare function defineNexusOperation<TOperation extends NexusOperationDefinition>(definition: TOperation): TOperation;
|
|
491
|
-
/**
|
|
492
|
-
* Builder for creating Nexus service definitions
|
|
493
|
-
*
|
|
494
|
-
* @template TService - A NexusServiceDefinition containing a record of operations
|
|
495
|
-
* @param definition - The Nexus service definition with typed operations
|
|
496
|
-
* @returns The same definition with preserved types
|
|
497
|
-
*
|
|
498
|
-
* @example
|
|
499
|
-
* ```typescript
|
|
500
|
-
* const PaymentService = defineNexusService({
|
|
501
|
-
* operations: {
|
|
502
|
-
* processPayment: defineNexusOperation({ ... }),
|
|
503
|
-
* refundPayment: defineNexusOperation({ ... }),
|
|
504
|
-
* },
|
|
505
|
-
* });
|
|
506
|
-
* ```
|
|
507
|
-
*/
|
|
508
|
-
declare function defineNexusService<TService extends NexusServiceDefinition>(definition: TService): TService;
|
|
509
|
-
//#endregion
|
|
510
|
-
export { type ActivityDefinition, type AnySchema, type ClientInferNexusOperationInput, type ClientInferNexusOperationInvoker, type ClientInferNexusOperationOutput, type ClientInferNexusServiceOperations, type ClientInferNexusServices, type ContractDefinition, type ContractDefinitionWithNexus, type InferActivityNames, type InferContractWorkflows, type InferNexusOperationNames, type InferNexusServiceNames, type InferWorkflowNames, type NexusOperationDefinition, type NexusOperationHandler, type NexusServiceDefinition, type QueryDefinition, type SignalDefinition, type UpdateDefinition, type WorkerInferNexusOperationHandler, type WorkerInferNexusOperationInput, type WorkerInferNexusOperationOutput, type WorkerInferNexusServiceHandlers, type WorkerInferNexusServices, type WorkflowDefinition, defineActivity, defineContract, defineNexusOperation, defineNexusService, defineQuery, defineSignal, defineUpdate, defineWorkflow };
|
|
285
|
+
export { type ActivityDefinition, type AnySchema, type ContractDefinition, type InferActivityNames, type InferContractWorkflows, type InferWorkflowNames, type QueryDefinition, type SignalDefinition, type UpdateDefinition, type WorkflowDefinition, defineActivity, defineContract, defineQuery, defineSignal, defineUpdate, defineWorkflow };
|
|
286
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/builder.ts"],"mappings":";;;;;AAOA;;;KAAY,SAAA,GAAY,gBAAA;;AAKxB;;KAAY,kBAAA,gBACK,SAAA,GAAY,SAAA,kBACX,SAAA,GAAY,SAAA;EAAA,SAEnB,KAAA,EAAO,MAAA;EAAA,SACP,MAAA,EAAQ,OAAA;AAAA;;;;KAMP,gBAAA,gBAAgC,SAAA,GAAY,SAAA;EAAA,SAC7C,KAAA,EAAO,MAAA;AAAA;;;;KAMN,eAAA,gBACK,SAAA,GAAY,SAAA,kBACX,SAAA,GAAY,SAAA;EAAA,SAEnB,KAAA,EAAO,MAAA;EAAA,SACP,MAAA,EAAQ,OAAA;AAAA;;;;KAMP,gBAAA,gBACK,SAAA,GAAY,SAAA,kBACX,SAAA,GAAY,SAAA;EAAA,SAEnB,KAAA,EAAO,MAAA;EAAA,SACP,MAAA,EAAQ,OAAA;AAAA;;;;KAMP,kBAAA,qBACU,MAAA,SAAe,kBAAA,IAAsB,MAAA,SAAe,kBAAA,oBACvD,MAAA,SAAe,gBAAA,IAAoB,MAAA,SAAe,gBAAA,oBAClD,MAAA,SAAe,eAAA,IAAmB,MAAA,SAAe,eAAA,oBACjD,MAAA,SAAe,gBAAA,IAAoB,MAAA,SAAe,gBAAA;EAAA,SAE1D,KAAA,EAAO,SAAA;EAAA,SACP,MAAA,EAAQ,SAAA;EAAA,SACR,UAAA,GAAa,WAAA;EAAA,SACb,OAAA,GAAU,QAAA;EAAA,SACV,OAAA,GAAU,QAAA;EAAA,SACV,OAAA,GAAU,QAAA;AAAA;;AAjCrB;;KAuCY,kBAAA,oBACS,MAAA,SAAe,kBAAA,IAAsB,MAAA,SAAe,kBAAA,uBACnD,MAAA,SAAe,kBAAA,IAAsB,MAAA,SAAe,kBAAA;EAAA,SAE/D,SAAA;EAAA,SACA,SAAA,EAAW,UAAA;EAAA,SACX,UAAA,GAAa,WAAA;AAAA;;;;;;;;;;;;;KAgBZ,kBAAA,mBAAqC,kBAAA,UACzC,SAAA;;;;AAnDR;;;;;;KA8DY,kBAAA,mBAAqC,kBAAA,IAC/C,SAAA,uBAAgC,MAAA,SAAe,kBAAA,UACrC,SAAA;;;;;;;;;KAWA,sBAAA,mBAAyC,kBAAA,IAAsB,SAAA;;;;;AA7G3E;;;;;AAKA;;;;;;;;;;;;;;;;;;;;;;iBC8BgB,cAAA,mBAAiC,kBAAA,CAAA,CAC/C,UAAA,EAAY,SAAA,GACX,SAAA;ADrBH;;;;;;;;;;;;;;;AAOA;;;;;;;;AAPA,iBCgDgB,YAAA,iBAA6B,gBAAA,CAAA,CAAkB,UAAA,EAAY,OAAA,GAAU,OAAA;;;;;;;;;;;;;;;AD9BrF;;;;;;;;;;iBC0DgB,WAAA,gBAA2B,eAAA,CAAA,CAAiB,UAAA,EAAY,MAAA,GAAS,MAAA;;;;;;;;;;;;;AD/CjF;;;;;;;;;;;;;;;;iBC+EgB,YAAA,iBAA6B,gBAAA,CAAA,CAAkB,UAAA,EAAY,OAAA,GAAU,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqCrE,cAAA,mBAAiC,kBAAA,CAAA,CAC/C,UAAA,EAAY,SAAA,GACX,SAAA;;;;;;;;;;;ADrGH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA;;;;;;;;;iBCsIgB,cAAA,mBAAiC,kBAAA,CAAA,CAC/C,UAAA,EAAY,SAAA,GACX,SAAA"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
2
|
|
|
3
3
|
//#region src/types.d.ts
|
|
4
|
-
|
|
5
4
|
/**
|
|
6
5
|
* Base types for validation schemas
|
|
7
6
|
* Any schema that implements the Standard Schema specification
|
|
@@ -11,49 +10,49 @@ type AnySchema = StandardSchemaV1;
|
|
|
11
10
|
/**
|
|
12
11
|
* Definition of an activity
|
|
13
12
|
*/
|
|
14
|
-
|
|
13
|
+
type ActivityDefinition<TInput extends AnySchema = AnySchema, TOutput extends AnySchema = AnySchema> = {
|
|
15
14
|
readonly input: TInput;
|
|
16
15
|
readonly output: TOutput;
|
|
17
|
-
}
|
|
16
|
+
};
|
|
18
17
|
/**
|
|
19
18
|
* Definition of a signal
|
|
20
19
|
*/
|
|
21
|
-
|
|
20
|
+
type SignalDefinition<TInput extends AnySchema = AnySchema> = {
|
|
22
21
|
readonly input: TInput;
|
|
23
|
-
}
|
|
22
|
+
};
|
|
24
23
|
/**
|
|
25
24
|
* Definition of a query
|
|
26
25
|
*/
|
|
27
|
-
|
|
26
|
+
type QueryDefinition<TInput extends AnySchema = AnySchema, TOutput extends AnySchema = AnySchema> = {
|
|
28
27
|
readonly input: TInput;
|
|
29
28
|
readonly output: TOutput;
|
|
30
|
-
}
|
|
29
|
+
};
|
|
31
30
|
/**
|
|
32
31
|
* Definition of an update
|
|
33
32
|
*/
|
|
34
|
-
|
|
33
|
+
type UpdateDefinition<TInput extends AnySchema = AnySchema, TOutput extends AnySchema = AnySchema> = {
|
|
35
34
|
readonly input: TInput;
|
|
36
35
|
readonly output: TOutput;
|
|
37
|
-
}
|
|
36
|
+
};
|
|
38
37
|
/**
|
|
39
38
|
* Definition of a workflow
|
|
40
39
|
*/
|
|
41
|
-
|
|
40
|
+
type WorkflowDefinition<TActivities extends Record<string, ActivityDefinition> = Record<string, ActivityDefinition>, TSignals extends Record<string, SignalDefinition> = Record<string, SignalDefinition>, TQueries extends Record<string, QueryDefinition> = Record<string, QueryDefinition>, TUpdates extends Record<string, UpdateDefinition> = Record<string, UpdateDefinition>> = {
|
|
42
41
|
readonly input: AnySchema;
|
|
43
42
|
readonly output: AnySchema;
|
|
44
43
|
readonly activities?: TActivities;
|
|
45
44
|
readonly signals?: TSignals;
|
|
46
45
|
readonly queries?: TQueries;
|
|
47
46
|
readonly updates?: TUpdates;
|
|
48
|
-
}
|
|
47
|
+
};
|
|
49
48
|
/**
|
|
50
49
|
* Contract definition containing workflows and optional global activities
|
|
51
50
|
*/
|
|
52
|
-
|
|
51
|
+
type ContractDefinition<TWorkflows extends Record<string, WorkflowDefinition> = Record<string, WorkflowDefinition>, TActivities extends Record<string, ActivityDefinition> = Record<string, ActivityDefinition>> = {
|
|
53
52
|
readonly taskQueue: string;
|
|
54
53
|
readonly workflows: TWorkflows;
|
|
55
54
|
readonly activities?: TActivities;
|
|
56
|
-
}
|
|
55
|
+
};
|
|
57
56
|
/**
|
|
58
57
|
* UTILITY TYPES
|
|
59
58
|
*/
|
|
@@ -283,228 +282,5 @@ declare function defineWorkflow<TWorkflow extends WorkflowDefinition>(definition
|
|
|
283
282
|
*/
|
|
284
283
|
declare function defineContract<TContract extends ContractDefinition>(definition: TContract): TContract;
|
|
285
284
|
//#endregion
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
* Definition of a Nexus operation
|
|
289
|
-
* Similar to ActivityDefinition but for cross-namespace operations
|
|
290
|
-
*
|
|
291
|
-
* @example
|
|
292
|
-
* ```typescript
|
|
293
|
-
* const processPayment = {
|
|
294
|
-
* input: z.object({ amount: z.number(), customerId: z.string() }),
|
|
295
|
-
* output: z.object({ transactionId: z.string(), status: z.enum(['success', 'failed']) }),
|
|
296
|
-
* };
|
|
297
|
-
* ```
|
|
298
|
-
*/
|
|
299
|
-
interface NexusOperationDefinition<TInput extends AnySchema = AnySchema, TOutput extends AnySchema = AnySchema> {
|
|
300
|
-
readonly input: TInput;
|
|
301
|
-
readonly output: TOutput;
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Definition of a Nexus service containing multiple operations
|
|
305
|
-
*
|
|
306
|
-
* @example
|
|
307
|
-
* ```typescript
|
|
308
|
-
* const PaymentService = {
|
|
309
|
-
* operations: {
|
|
310
|
-
* processPayment: { input: ..., output: ... },
|
|
311
|
-
* refundPayment: { input: ..., output: ... },
|
|
312
|
-
* },
|
|
313
|
-
* };
|
|
314
|
-
* ```
|
|
315
|
-
*/
|
|
316
|
-
interface NexusServiceDefinition<TOperations extends Record<string, NexusOperationDefinition> = Record<string, NexusOperationDefinition>> {
|
|
317
|
-
readonly operations: TOperations;
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Extended ContractDefinition that includes Nexus services
|
|
321
|
-
* This would replace the current ContractDefinition when Nexus support is added
|
|
322
|
-
*
|
|
323
|
-
* @example
|
|
324
|
-
* ```typescript
|
|
325
|
-
* const contract = defineContract({
|
|
326
|
-
* taskQueue: 'payments',
|
|
327
|
-
* workflows: { ... },
|
|
328
|
-
* activities: { ... },
|
|
329
|
-
* nexusServices: {
|
|
330
|
-
* PaymentService: {
|
|
331
|
-
* operations: {
|
|
332
|
-
* processPayment: { input: ..., output: ... },
|
|
333
|
-
* },
|
|
334
|
-
* },
|
|
335
|
-
* },
|
|
336
|
-
* });
|
|
337
|
-
* ```
|
|
338
|
-
*/
|
|
339
|
-
interface ContractDefinitionWithNexus<TWorkflows extends Record<string, WorkflowDefinition> = Record<string, WorkflowDefinition>, TActivities extends Record<string, ActivityDefinition> = Record<string, ActivityDefinition>, TNexusServices extends Record<string, NexusServiceDefinition> = Record<string, NexusServiceDefinition>> {
|
|
340
|
-
readonly taskQueue: string;
|
|
341
|
-
readonly workflows: TWorkflows;
|
|
342
|
-
readonly activities?: TActivities;
|
|
343
|
-
readonly nexusServices?: TNexusServices;
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* WORKER PERSPECTIVE - Nexus operation handler type inference
|
|
347
|
-
* Worker receives the parsed input and returns the raw output
|
|
348
|
-
*/
|
|
349
|
-
/**
|
|
350
|
-
* Infer input type from a Nexus operation definition (worker perspective)
|
|
351
|
-
*/
|
|
352
|
-
type WorkerInferNexusOperationInput<T extends NexusOperationDefinition> = StandardSchemaV1.InferOutput<T["input"]>;
|
|
353
|
-
/**
|
|
354
|
-
* Infer output type from a Nexus operation definition (worker perspective)
|
|
355
|
-
*/
|
|
356
|
-
type WorkerInferNexusOperationOutput<T extends NexusOperationDefinition> = StandardSchemaV1.InferInput<T["output"]>;
|
|
357
|
-
/**
|
|
358
|
-
* Infer the handler function signature for a Nexus operation (worker perspective)
|
|
359
|
-
*
|
|
360
|
-
* @example
|
|
361
|
-
* ```typescript
|
|
362
|
-
* type ProcessPaymentHandler = WorkerInferNexusOperationHandler<typeof processPaymentOperation>;
|
|
363
|
-
* // (args: { amount: number; customerId: string }) => Promise<{ transactionId: string; status: 'success' | 'failed' }>
|
|
364
|
-
* ```
|
|
365
|
-
*/
|
|
366
|
-
type WorkerInferNexusOperationHandler<TOperation extends NexusOperationDefinition> = (args: WorkerInferNexusOperationInput<TOperation>) => Promise<WorkerInferNexusOperationOutput<TOperation>>;
|
|
367
|
-
/**
|
|
368
|
-
* Infer all operation handlers for a Nexus service (worker perspective)
|
|
369
|
-
*
|
|
370
|
-
* @example
|
|
371
|
-
* ```typescript
|
|
372
|
-
* type PaymentServiceHandlers = WorkerInferNexusServiceHandlers<typeof PaymentService>;
|
|
373
|
-
* // {
|
|
374
|
-
* // processPayment: (args: { ... }) => Promise<{ ... }>;
|
|
375
|
-
* // refundPayment: (args: { ... }) => Promise<{ ... }>;
|
|
376
|
-
* // }
|
|
377
|
-
* ```
|
|
378
|
-
*/
|
|
379
|
-
type WorkerInferNexusServiceHandlers<T extends NexusServiceDefinition> = { [K in keyof T["operations"]]: WorkerInferNexusOperationHandler<T["operations"][K]> };
|
|
380
|
-
/**
|
|
381
|
-
* Infer all Nexus service handlers from a contract (worker perspective)
|
|
382
|
-
*
|
|
383
|
-
* @example
|
|
384
|
-
* ```typescript
|
|
385
|
-
* type AllNexusHandlers = WorkerInferNexusServices<typeof myContract>;
|
|
386
|
-
* // {
|
|
387
|
-
* // PaymentService: { processPayment: ..., refundPayment: ... };
|
|
388
|
-
* // InventoryService: { reserveItems: ..., releaseItems: ... };
|
|
389
|
-
* // }
|
|
390
|
-
* ```
|
|
391
|
-
*/
|
|
392
|
-
type WorkerInferNexusServices<TContract extends ContractDefinitionWithNexus> = TContract["nexusServices"] extends Record<string, NexusServiceDefinition> ? { [K in keyof TContract["nexusServices"]]: WorkerInferNexusServiceHandlers<TContract["nexusServices"][K]> } : {};
|
|
393
|
-
/**
|
|
394
|
-
* CLIENT PERSPECTIVE - Nexus operation client type inference
|
|
395
|
-
* Client sends the raw input and receives the parsed output
|
|
396
|
-
*/
|
|
397
|
-
/**
|
|
398
|
-
* Infer input type from a Nexus operation definition (client perspective)
|
|
399
|
-
*/
|
|
400
|
-
type ClientInferNexusOperationInput<T extends NexusOperationDefinition> = StandardSchemaV1.InferInput<T["input"]>;
|
|
401
|
-
/**
|
|
402
|
-
* Infer output type from a Nexus operation definition (client perspective)
|
|
403
|
-
*/
|
|
404
|
-
type ClientInferNexusOperationOutput<T extends NexusOperationDefinition> = StandardSchemaV1.InferOutput<T["output"]>;
|
|
405
|
-
/**
|
|
406
|
-
* Infer the client function signature for a Nexus operation (client perspective)
|
|
407
|
-
*
|
|
408
|
-
* @example
|
|
409
|
-
* ```typescript
|
|
410
|
-
* type ProcessPaymentClient = ClientInferNexusOperationInvoker<typeof processPaymentOperation>;
|
|
411
|
-
* // (args: { amount: number; customerId: string }) => Promise<{ transactionId: string; status: 'success' | 'failed' }>
|
|
412
|
-
* ```
|
|
413
|
-
*/
|
|
414
|
-
type ClientInferNexusOperationInvoker<TOperation extends NexusOperationDefinition> = (args: ClientInferNexusOperationInput<TOperation>) => Promise<ClientInferNexusOperationOutput<TOperation>>;
|
|
415
|
-
/**
|
|
416
|
-
* Infer all operation invokers for a Nexus service (client perspective)
|
|
417
|
-
*/
|
|
418
|
-
type ClientInferNexusServiceOperations<T extends NexusServiceDefinition> = { [K in keyof T["operations"]]: ClientInferNexusOperationInvoker<T["operations"][K]> };
|
|
419
|
-
/**
|
|
420
|
-
* Infer all Nexus service operations from a contract (client perspective)
|
|
421
|
-
*
|
|
422
|
-
* @example
|
|
423
|
-
* ```typescript
|
|
424
|
-
* type AllNexusOperations = ClientInferNexusServices<typeof myContract>;
|
|
425
|
-
* // {
|
|
426
|
-
* // PaymentService: { processPayment: ..., refundPayment: ... };
|
|
427
|
-
* // InventoryService: { reserveItems: ..., releaseItems: ... };
|
|
428
|
-
* // }
|
|
429
|
-
* ```
|
|
430
|
-
*/
|
|
431
|
-
type ClientInferNexusServices<TContract extends ContractDefinitionWithNexus> = TContract["nexusServices"] extends Record<string, NexusServiceDefinition> ? { [K in keyof TContract["nexusServices"]]: ClientInferNexusServiceOperations<TContract["nexusServices"][K]> } : {};
|
|
432
|
-
/**
|
|
433
|
-
* UTILITY TYPES
|
|
434
|
-
*/
|
|
435
|
-
/**
|
|
436
|
-
* Extract service names from a contract as a union type
|
|
437
|
-
*
|
|
438
|
-
* @example
|
|
439
|
-
* ```typescript
|
|
440
|
-
* type MyServiceNames = InferNexusServiceNames<typeof myContract>;
|
|
441
|
-
* // "PaymentService" | "InventoryService"
|
|
442
|
-
* ```
|
|
443
|
-
*/
|
|
444
|
-
type InferNexusServiceNames<TContract extends ContractDefinitionWithNexus> = TContract["nexusServices"] extends Record<string, NexusServiceDefinition> ? keyof TContract["nexusServices"] & string : never;
|
|
445
|
-
/**
|
|
446
|
-
* Extract operation names from a service as a union type
|
|
447
|
-
*
|
|
448
|
-
* @example
|
|
449
|
-
* ```typescript
|
|
450
|
-
* type PaymentOperations = InferNexusOperationNames<typeof myContract, "PaymentService">;
|
|
451
|
-
* // "processPayment" | "refundPayment"
|
|
452
|
-
* ```
|
|
453
|
-
*/
|
|
454
|
-
type InferNexusOperationNames<TContract extends ContractDefinitionWithNexus, TServiceName extends InferNexusServiceNames<TContract>> = TContract["nexusServices"] extends Record<string, NexusServiceDefinition> ? keyof TContract["nexusServices"][TServiceName]["operations"] & string : never;
|
|
455
|
-
/**
|
|
456
|
-
* Infer the handler type for a specific Nexus operation (worker perspective)
|
|
457
|
-
*
|
|
458
|
-
* @example
|
|
459
|
-
* ```typescript
|
|
460
|
-
* const processPayment: NexusOperationHandler<
|
|
461
|
-
* typeof myContract,
|
|
462
|
-
* "PaymentService",
|
|
463
|
-
* "processPayment"
|
|
464
|
-
* > = async ({ amount, customerId }) => {
|
|
465
|
-
* // Implementation
|
|
466
|
-
* return { transactionId: 'tx-123', status: 'success' };
|
|
467
|
-
* };
|
|
468
|
-
* ```
|
|
469
|
-
*/
|
|
470
|
-
type NexusOperationHandler<TContract extends ContractDefinitionWithNexus, TServiceName extends InferNexusServiceNames<TContract>, TOperationName extends InferNexusOperationNames<TContract, TServiceName>> = TContract["nexusServices"] extends Record<string, NexusServiceDefinition> ? (args: WorkerInferNexusOperationInput<TContract["nexusServices"][TServiceName]["operations"][TOperationName]>) => Promise<WorkerInferNexusOperationOutput<TContract["nexusServices"][TServiceName]["operations"][TOperationName]>> : never;
|
|
471
|
-
/**
|
|
472
|
-
* BUILDER FUNCTIONS (Proposed API)
|
|
473
|
-
* These would be added to builder.ts when Nexus support is implemented
|
|
474
|
-
*/
|
|
475
|
-
/**
|
|
476
|
-
* Builder for creating Nexus operation definitions
|
|
477
|
-
*
|
|
478
|
-
* @template TOperation - A NexusOperationDefinition containing input and output schemas
|
|
479
|
-
* @param definition - The Nexus operation definition with typed input/output schemas
|
|
480
|
-
* @returns The same definition with preserved types
|
|
481
|
-
*
|
|
482
|
-
* @example
|
|
483
|
-
* ```typescript
|
|
484
|
-
* const processPayment = defineNexusOperation({
|
|
485
|
-
* input: z.object({ amount: z.number(), customerId: z.string() }),
|
|
486
|
-
* output: z.object({ transactionId: z.string(), status: z.enum(['success', 'failed']) }),
|
|
487
|
-
* });
|
|
488
|
-
* ```
|
|
489
|
-
*/
|
|
490
|
-
declare function defineNexusOperation<TOperation extends NexusOperationDefinition>(definition: TOperation): TOperation;
|
|
491
|
-
/**
|
|
492
|
-
* Builder for creating Nexus service definitions
|
|
493
|
-
*
|
|
494
|
-
* @template TService - A NexusServiceDefinition containing a record of operations
|
|
495
|
-
* @param definition - The Nexus service definition with typed operations
|
|
496
|
-
* @returns The same definition with preserved types
|
|
497
|
-
*
|
|
498
|
-
* @example
|
|
499
|
-
* ```typescript
|
|
500
|
-
* const PaymentService = defineNexusService({
|
|
501
|
-
* operations: {
|
|
502
|
-
* processPayment: defineNexusOperation({ ... }),
|
|
503
|
-
* refundPayment: defineNexusOperation({ ... }),
|
|
504
|
-
* },
|
|
505
|
-
* });
|
|
506
|
-
* ```
|
|
507
|
-
*/
|
|
508
|
-
declare function defineNexusService<TService extends NexusServiceDefinition>(definition: TService): TService;
|
|
509
|
-
//#endregion
|
|
510
|
-
export { type ActivityDefinition, type AnySchema, type ClientInferNexusOperationInput, type ClientInferNexusOperationInvoker, type ClientInferNexusOperationOutput, type ClientInferNexusServiceOperations, type ClientInferNexusServices, type ContractDefinition, type ContractDefinitionWithNexus, type InferActivityNames, type InferContractWorkflows, type InferNexusOperationNames, type InferNexusServiceNames, type InferWorkflowNames, type NexusOperationDefinition, type NexusOperationHandler, type NexusServiceDefinition, type QueryDefinition, type SignalDefinition, type UpdateDefinition, type WorkerInferNexusOperationHandler, type WorkerInferNexusOperationInput, type WorkerInferNexusOperationOutput, type WorkerInferNexusServiceHandlers, type WorkerInferNexusServices, type WorkflowDefinition, defineActivity, defineContract, defineNexusOperation, defineNexusService, defineQuery, defineSignal, defineUpdate, defineWorkflow };
|
|
285
|
+
export { type ActivityDefinition, type AnySchema, type ContractDefinition, type InferActivityNames, type InferContractWorkflows, type InferWorkflowNames, type QueryDefinition, type SignalDefinition, type UpdateDefinition, type WorkflowDefinition, defineActivity, defineContract, defineQuery, defineSignal, defineUpdate, defineWorkflow };
|
|
286
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/builder.ts"],"mappings":";;;;;AAOA;;;KAAY,SAAA,GAAY,gBAAA;;AAKxB;;KAAY,kBAAA,gBACK,SAAA,GAAY,SAAA,kBACX,SAAA,GAAY,SAAA;EAAA,SAEnB,KAAA,EAAO,MAAA;EAAA,SACP,MAAA,EAAQ,OAAA;AAAA;;;;KAMP,gBAAA,gBAAgC,SAAA,GAAY,SAAA;EAAA,SAC7C,KAAA,EAAO,MAAA;AAAA;;;;KAMN,eAAA,gBACK,SAAA,GAAY,SAAA,kBACX,SAAA,GAAY,SAAA;EAAA,SAEnB,KAAA,EAAO,MAAA;EAAA,SACP,MAAA,EAAQ,OAAA;AAAA;;;;KAMP,gBAAA,gBACK,SAAA,GAAY,SAAA,kBACX,SAAA,GAAY,SAAA;EAAA,SAEnB,KAAA,EAAO,MAAA;EAAA,SACP,MAAA,EAAQ,OAAA;AAAA;;;;KAMP,kBAAA,qBACU,MAAA,SAAe,kBAAA,IAAsB,MAAA,SAAe,kBAAA,oBACvD,MAAA,SAAe,gBAAA,IAAoB,MAAA,SAAe,gBAAA,oBAClD,MAAA,SAAe,eAAA,IAAmB,MAAA,SAAe,eAAA,oBACjD,MAAA,SAAe,gBAAA,IAAoB,MAAA,SAAe,gBAAA;EAAA,SAE1D,KAAA,EAAO,SAAA;EAAA,SACP,MAAA,EAAQ,SAAA;EAAA,SACR,UAAA,GAAa,WAAA;EAAA,SACb,OAAA,GAAU,QAAA;EAAA,SACV,OAAA,GAAU,QAAA;EAAA,SACV,OAAA,GAAU,QAAA;AAAA;;AAjCrB;;KAuCY,kBAAA,oBACS,MAAA,SAAe,kBAAA,IAAsB,MAAA,SAAe,kBAAA,uBACnD,MAAA,SAAe,kBAAA,IAAsB,MAAA,SAAe,kBAAA;EAAA,SAE/D,SAAA;EAAA,SACA,SAAA,EAAW,UAAA;EAAA,SACX,UAAA,GAAa,WAAA;AAAA;;;;;;;;;;;;;KAgBZ,kBAAA,mBAAqC,kBAAA,UACzC,SAAA;;;;AAnDR;;;;;;KA8DY,kBAAA,mBAAqC,kBAAA,IAC/C,SAAA,uBAAgC,MAAA,SAAe,kBAAA,UACrC,SAAA;;;;;;;;;KAWA,sBAAA,mBAAyC,kBAAA,IAAsB,SAAA;;;;;AA7G3E;;;;;AAKA;;;;;;;;;;;;;;;;;;;;;;iBC8BgB,cAAA,mBAAiC,kBAAA,CAAA,CAC/C,UAAA,EAAY,SAAA,GACX,SAAA;ADrBH;;;;;;;;;;;;;;;AAOA;;;;;;;;AAPA,iBCgDgB,YAAA,iBAA6B,gBAAA,CAAA,CAAkB,UAAA,EAAY,OAAA,GAAU,OAAA;;;;;;;;;;;;;;;AD9BrF;;;;;;;;;;iBC0DgB,WAAA,gBAA2B,eAAA,CAAA,CAAiB,UAAA,EAAY,MAAA,GAAS,MAAA;;;;;;;;;;;;;AD/CjF;;;;;;;;;;;;;;;;iBC+EgB,YAAA,iBAA6B,gBAAA,CAAA,CAAkB,UAAA,EAAY,OAAA,GAAU,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqCrE,cAAA,mBAAiC,kBAAA,CAAA,CAC/C,UAAA,EAAY,SAAA,GACX,SAAA;;;;;;;;;;;ADrGH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA;;;;;;;;;iBCsIgB,cAAA,mBAAiC,kBAAA,CAAA,CAC/C,UAAA,EAAY,SAAA,GACX,SAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -227,21 +227,21 @@ function isStandardSchema(value) {
|
|
|
227
227
|
*/
|
|
228
228
|
const identifierSchema = z.string().min(1).regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, "must be a valid JavaScript identifier");
|
|
229
229
|
/**
|
|
230
|
-
* Extract clean error message from Zod validation error
|
|
230
|
+
* Extract a clean, single-line error message from a Zod validation error.
|
|
231
|
+
*
|
|
232
|
+
* Uses `error.issues` directly (compatible with Zod v4+) rather than parsing
|
|
233
|
+
* `error.message` as JSON, which was a Zod v3 implementation detail.
|
|
231
234
|
*/
|
|
232
235
|
function getCleanErrorMessage(error) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
} catch {}
|
|
244
|
-
return error.message;
|
|
236
|
+
const issues = error.issues;
|
|
237
|
+
if (!issues || issues.length === 0) return error.message;
|
|
238
|
+
const firstIssue = issues[0];
|
|
239
|
+
if (!firstIssue) return error.message;
|
|
240
|
+
if (firstIssue.code === "invalid_key" && "issues" in firstIssue && Array.isArray(firstIssue.issues) && firstIssue.issues.length > 0) {
|
|
241
|
+
const nestedMessage = firstIssue.issues[0]?.message;
|
|
242
|
+
if (nestedMessage) return nestedMessage;
|
|
243
|
+
}
|
|
244
|
+
return firstIssue.message ?? error.message;
|
|
245
245
|
}
|
|
246
246
|
/**
|
|
247
247
|
* Schema for validating activity definitions
|
|
@@ -301,118 +301,5 @@ const contractValidationSchema = z.object({
|
|
|
301
301
|
});
|
|
302
302
|
|
|
303
303
|
//#endregion
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
* BUILDER FUNCTIONS (Proposed API)
|
|
307
|
-
* These would be added to builder.ts when Nexus support is implemented
|
|
308
|
-
*/
|
|
309
|
-
/**
|
|
310
|
-
* Builder for creating Nexus operation definitions
|
|
311
|
-
*
|
|
312
|
-
* @template TOperation - A NexusOperationDefinition containing input and output schemas
|
|
313
|
-
* @param definition - The Nexus operation definition with typed input/output schemas
|
|
314
|
-
* @returns The same definition with preserved types
|
|
315
|
-
*
|
|
316
|
-
* @example
|
|
317
|
-
* ```typescript
|
|
318
|
-
* const processPayment = defineNexusOperation({
|
|
319
|
-
* input: z.object({ amount: z.number(), customerId: z.string() }),
|
|
320
|
-
* output: z.object({ transactionId: z.string(), status: z.enum(['success', 'failed']) }),
|
|
321
|
-
* });
|
|
322
|
-
* ```
|
|
323
|
-
*/
|
|
324
|
-
function defineNexusOperation(definition) {
|
|
325
|
-
return definition;
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Builder for creating Nexus service definitions
|
|
329
|
-
*
|
|
330
|
-
* @template TService - A NexusServiceDefinition containing a record of operations
|
|
331
|
-
* @param definition - The Nexus service definition with typed operations
|
|
332
|
-
* @returns The same definition with preserved types
|
|
333
|
-
*
|
|
334
|
-
* @example
|
|
335
|
-
* ```typescript
|
|
336
|
-
* const PaymentService = defineNexusService({
|
|
337
|
-
* operations: {
|
|
338
|
-
* processPayment: defineNexusOperation({ ... }),
|
|
339
|
-
* refundPayment: defineNexusOperation({ ... }),
|
|
340
|
-
* },
|
|
341
|
-
* });
|
|
342
|
-
* ```
|
|
343
|
-
*/
|
|
344
|
-
function defineNexusService(definition) {
|
|
345
|
-
return definition;
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* USAGE EXAMPLE
|
|
349
|
-
*
|
|
350
|
-
* This example demonstrates the complete type-safe Nexus workflow:
|
|
351
|
-
*
|
|
352
|
-
* ```typescript
|
|
353
|
-
* import { defineContract, defineNexusService, defineNexusOperation } from '@temporal-contract/contract';
|
|
354
|
-
* import { z } from 'zod';
|
|
355
|
-
*
|
|
356
|
-
* // 1. Define contract with Nexus service
|
|
357
|
-
* const paymentContract = defineContract({
|
|
358
|
-
* taskQueue: 'payments',
|
|
359
|
-
* workflows: { ... },
|
|
360
|
-
* nexusServices: {
|
|
361
|
-
* PaymentService: defineNexusService({
|
|
362
|
-
* operations: {
|
|
363
|
-
* processPayment: defineNexusOperation({
|
|
364
|
-
* input: z.object({
|
|
365
|
-
* amount: z.number().positive(),
|
|
366
|
-
* customerId: z.string().uuid(),
|
|
367
|
-
* }),
|
|
368
|
-
* output: z.object({
|
|
369
|
-
* transactionId: z.string(),
|
|
370
|
-
* status: z.enum(['success', 'failed']),
|
|
371
|
-
* }),
|
|
372
|
-
* }),
|
|
373
|
-
* },
|
|
374
|
-
* }),
|
|
375
|
-
* },
|
|
376
|
-
* });
|
|
377
|
-
*
|
|
378
|
-
* // 2. Worker implementation (type-safe handlers)
|
|
379
|
-
* import { createNexusHandlers } from '@temporal-contract/worker';
|
|
380
|
-
*
|
|
381
|
-
* const nexusHandlers = createNexusHandlers(paymentContract, {
|
|
382
|
-
* PaymentService: {
|
|
383
|
-
* processPayment: async ({ amount, customerId }) => {
|
|
384
|
-
* // ✅ Fully typed parameters
|
|
385
|
-
* // ✅ Input automatically validated
|
|
386
|
-
* const payment = await processPaymentInDatabase(customerId, amount);
|
|
387
|
-
* // ✅ Return value validated against schema
|
|
388
|
-
* return {
|
|
389
|
-
* transactionId: payment.id,
|
|
390
|
-
* status: 'success',
|
|
391
|
-
* };
|
|
392
|
-
* },
|
|
393
|
-
* },
|
|
394
|
-
* });
|
|
395
|
-
*
|
|
396
|
-
* // 3. Client usage (type-safe invocation)
|
|
397
|
-
* import { createNexusClient } from '@temporal-contract/client';
|
|
398
|
-
*
|
|
399
|
-
* const nexusClient = createNexusClient<typeof paymentContract>(connection, {
|
|
400
|
-
* namespace: 'payments-ns',
|
|
401
|
-
* });
|
|
402
|
-
*
|
|
403
|
-
* // ✅ Fully typed invocation
|
|
404
|
-
* const result = await nexusClient.invoke('PaymentService', 'processPayment', {
|
|
405
|
-
* amount: 100,
|
|
406
|
-
* customerId: 'cust-123',
|
|
407
|
-
* });
|
|
408
|
-
*
|
|
409
|
-
* // ❌ TypeScript errors caught at compile time
|
|
410
|
-
* await nexusClient.invoke('PaymentService', 'processPayment', {
|
|
411
|
-
* amount: -50, // Error: amount must be positive
|
|
412
|
-
* customerId: 'invalid', // Error: customerId must be UUID
|
|
413
|
-
* });
|
|
414
|
-
* ```
|
|
415
|
-
*/
|
|
416
|
-
|
|
417
|
-
//#endregion
|
|
418
|
-
export { defineActivity, defineContract, defineNexusOperation, defineNexusService, defineQuery, defineSignal, defineUpdate, defineWorkflow };
|
|
304
|
+
export { defineActivity, defineContract, defineQuery, defineSignal, defineUpdate, defineWorkflow };
|
|
305
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/builder.ts"],"sourcesContent":["import { z } from \"zod\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type {\n ActivityDefinition,\n ContractDefinition,\n QueryDefinition,\n SignalDefinition,\n UpdateDefinition,\n WorkflowDefinition,\n} from \"./types.js\";\n\n// Exported builders first (classic functions for hoisting)\n\n/**\n * Define a Temporal activity with type-safe input and output schemas.\n *\n * Activities are the building blocks of Temporal workflows that execute business logic\n * and interact with external services. This function preserves TypeScript types while\n * providing a consistent structure for activity definitions.\n *\n * @template TActivity - The activity definition type with input/output schemas\n * @param definition - The activity definition containing input and output schemas\n * @returns The same definition with preserved types for type inference\n *\n * @example\n * ```typescript\n * import { defineActivity } from '@temporal-contract/contract';\n * import { z } from 'zod';\n *\n * export const sendEmail = defineActivity({\n * input: z.object({\n * to: z.string().email(),\n * subject: z.string(),\n * body: z.string(),\n * }),\n * output: z.object({\n * messageId: z.string(),\n * sentAt: z.date(),\n * }),\n * });\n * ```\n */\nexport function defineActivity<TActivity extends ActivityDefinition>(\n definition: TActivity,\n): TActivity {\n return definition;\n}\n\n/**\n * Define a Temporal signal with type-safe input schema.\n *\n * Signals are asynchronous messages sent to running workflows to update their state\n * or trigger certain behaviors. This function ensures type safety for signal payloads.\n *\n * @template TSignal - The signal definition type with input schema\n * @param definition - The signal definition containing input schema\n * @returns The same definition with preserved types for type inference\n *\n * @example\n * ```typescript\n * import { defineSignal } from '@temporal-contract/contract';\n * import { z } from 'zod';\n *\n * export const approveOrder = defineSignal({\n * input: z.object({\n * orderId: z.string(),\n * approvedBy: z.string(),\n * }),\n * });\n * ```\n */\nexport function defineSignal<TSignal extends SignalDefinition>(definition: TSignal): TSignal {\n return definition;\n}\n\n/**\n * Define a Temporal query with type-safe input and output schemas.\n *\n * Queries allow you to read the current state of a running workflow without\n * modifying it. They are synchronous and should not perform any mutations.\n *\n * @template TQuery - The query definition type with input/output schemas\n * @param definition - The query definition containing input and output schemas\n * @returns The same definition with preserved types for type inference\n *\n * @example\n * ```typescript\n * import { defineQuery } from '@temporal-contract/contract';\n * import { z } from 'zod';\n *\n * export const getOrderStatus = defineQuery({\n * input: z.object({ orderId: z.string() }),\n * output: z.object({\n * status: z.enum(['pending', 'processing', 'completed', 'failed']),\n * updatedAt: z.date(),\n * }),\n * });\n * ```\n */\nexport function defineQuery<TQuery extends QueryDefinition>(definition: TQuery): TQuery {\n return definition;\n}\n\n/**\n * Define a Temporal update with type-safe input and output schemas.\n *\n * Updates are similar to signals but return a value and wait for the workflow\n * to process them before completing. They provide a synchronous way to modify\n * workflow state and get immediate feedback.\n *\n * @template TUpdate - The update definition type with input/output schemas\n * @param definition - The update definition containing input and output schemas\n * @returns The same definition with preserved types for type inference\n *\n * @example\n * ```typescript\n * import { defineUpdate } from '@temporal-contract/contract';\n * import { z } from 'zod';\n *\n * export const updateOrderQuantity = defineUpdate({\n * input: z.object({\n * orderId: z.string(),\n * newQuantity: z.number().positive(),\n * }),\n * output: z.object({\n * success: z.boolean(),\n * totalPrice: z.number(),\n * }),\n * });\n * ```\n */\nexport function defineUpdate<TUpdate extends UpdateDefinition>(definition: TUpdate): TUpdate {\n return definition;\n}\n\n/**\n * Define a Temporal workflow with type-safe input, output, and associated operations.\n *\n * Workflows are durable functions that orchestrate activities, handle timeouts,\n * and manage long-running processes. This function provides type safety for the\n * entire workflow definition including activities, signals, queries, and updates.\n *\n * @template TWorkflow - The workflow definition type with all associated schemas\n * @param definition - The workflow definition containing input, output, and operations\n * @returns The same definition with preserved types for type inference\n *\n * @example\n * ```typescript\n * import { defineWorkflow, defineActivity, defineSignal } from '@temporal-contract/contract';\n * import { z } from 'zod';\n *\n * export const processOrder = defineWorkflow({\n * input: z.object({ orderId: z.string() }),\n * output: z.object({ success: z.boolean() }),\n * activities: {\n * validatePayment: defineActivity({\n * input: z.object({ orderId: z.string() }),\n * output: z.object({ valid: z.boolean() }),\n * }),\n * },\n * signals: {\n * cancel: defineSignal({\n * input: z.object({ reason: z.string() }),\n * }),\n * },\n * });\n * ```\n */\nexport function defineWorkflow<TWorkflow extends WorkflowDefinition>(\n definition: TWorkflow,\n): TWorkflow {\n return definition;\n}\n\n/**\n * Define a complete Temporal contract with type-safe workflows and activities.\n *\n * A contract is the central definition that ties together your Temporal application's\n * workflows and activities. It provides:\n * - Type safety across client, worker, and workflow code\n * - Automatic validation at runtime\n * - Compile-time verification of implementations\n * - Clear API boundaries and documentation\n *\n * The contract validates the structure and ensures:\n * - Task queue is specified\n * - At least one workflow is defined\n * - Valid JavaScript identifiers are used\n * - No conflicts between global and workflow-specific activities\n * - All schemas implement the Standard Schema specification\n *\n * @template TContract - The contract definition type\n * @param definition - The complete contract definition\n * @returns The same definition with preserved types for type inference\n * @throws {Error} If the contract structure is invalid\n *\n * @example\n * ```typescript\n * import { defineContract } from '@temporal-contract/contract';\n * import { z } from 'zod';\n *\n * export const myContract = defineContract({\n * taskQueue: 'orders',\n * workflows: {\n * processOrder: {\n * input: z.object({ orderId: z.string() }),\n * output: z.object({ success: z.boolean() }),\n * activities: {\n * chargePayment: {\n * input: z.object({ amount: z.number() }),\n * output: z.object({ transactionId: z.string() }),\n * },\n * },\n * },\n * },\n * // Optional global activities shared across workflows\n * activities: {\n * logEvent: {\n * input: z.object({ message: z.string() }),\n * output: z.void(),\n * },\n * },\n * });\n * ```\n */\nexport function defineContract<TContract extends ContractDefinition>(\n definition: TContract,\n): TContract {\n // Validate entire contract structure with Zod (including activity conflicts)\n const validationResult = contractValidationSchema.safeParse(definition);\n\n if (!validationResult.success) {\n const cleanMessage = getCleanErrorMessage(validationResult.error);\n throw new Error(`Contract validation failed: ${cleanMessage}`);\n }\n\n return definition;\n}\n\n/**\n * Check if a value is a Standard Schema compatible schema\n */\nfunction isStandardSchema(value: unknown): value is StandardSchemaV1 {\n // Standard Schema can be either an object or a function (e.g., ArkType)\n if (\n (typeof value !== \"object\" && typeof value !== \"function\") ||\n value === null ||\n !(\"~standard\" in value)\n ) {\n return false;\n }\n\n const standard = (value as Record<string, unknown>)[\"~standard\"];\n\n return (\n typeof standard === \"object\" &&\n standard !== null &&\n (standard as Record<string, unknown>)[\"version\"] === 1 &&\n typeof (standard as Record<string, unknown>)[\"validate\"] === \"function\"\n );\n}\n\n/**\n * Schema for validating JavaScript identifiers (workflow names, activity names, etc.)\n * Allows: letters, digits, underscore, dollar sign\n * Must start with: letter, underscore, or dollar sign\n */\nconst identifierSchema = z\n .string()\n .min(1)\n .regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, \"must be a valid JavaScript identifier\");\n\n/**\n * Extract a clean, single-line error message from a Zod validation error.\n *\n * Uses `error.issues` directly (compatible with Zod v4+) rather than parsing\n * `error.message` as JSON, which was a Zod v3 implementation detail.\n */\nfunction getCleanErrorMessage(error: z.ZodError): string {\n const issues = error.issues;\n if (!issues || issues.length === 0) {\n return error.message;\n }\n\n const firstIssue = issues[0];\n if (!firstIssue) {\n return error.message;\n }\n\n // For record key validation errors (invalid_key), surface the nested issue message\n if (\n firstIssue.code === \"invalid_key\" &&\n \"issues\" in firstIssue &&\n Array.isArray((firstIssue as { issues?: unknown[] }).issues) &&\n (firstIssue as { issues: { message?: string }[] }).issues.length > 0\n ) {\n const nestedMessage = (firstIssue as { issues: { message?: string }[] }).issues[0]?.message;\n if (nestedMessage) {\n return nestedMessage;\n }\n }\n\n return firstIssue.message ?? error.message;\n}\n\n/**\n * Schema for validating activity definitions\n * Checks that input and output are Standard Schema compatible schemas\n */\nconst activityDefinitionSchema = z.object({\n input: z.custom<StandardSchemaV1>((val) => isStandardSchema(val), {\n message: \"input must be a Standard Schema compatible schema (e.g., Zod, Valibot, ArkType)\",\n }),\n output: z.custom<StandardSchemaV1>((val) => isStandardSchema(val), {\n message: \"output must be a Standard Schema compatible schema (e.g., Zod, Valibot, ArkType)\",\n }),\n});\n\n/**\n * Schema for validating signal definitions\n */\nconst signalDefinitionSchema = z.object({\n input: z.custom<StandardSchemaV1>((val) => isStandardSchema(val), {\n message: \"input must be a Standard Schema compatible schema (e.g., Zod, Valibot, ArkType)\",\n }),\n});\n\n/**\n * Schema for validating query definitions\n */\nconst queryDefinitionSchema = z.object({\n input: z.custom<StandardSchemaV1>((val) => isStandardSchema(val), {\n message: \"input must be a Standard Schema compatible schema (e.g., Zod, Valibot, ArkType)\",\n }),\n output: z.custom<StandardSchemaV1>((val) => isStandardSchema(val), {\n message: \"output must be a Standard Schema compatible schema (e.g., Zod, Valibot, ArkType)\",\n }),\n});\n\n/**\n * Schema for validating update definitions\n */\nconst updateDefinitionSchema = z.object({\n input: z.custom<StandardSchemaV1>((val) => isStandardSchema(val), {\n message: \"input must be a Standard Schema compatible schema (e.g., Zod, Valibot, ArkType)\",\n }),\n output: z.custom<StandardSchemaV1>((val) => isStandardSchema(val), {\n message: \"output must be a Standard Schema compatible schema (e.g., Zod, Valibot, ArkType)\",\n }),\n});\n\n/**\n * Schema for validating workflow definitions\n */\nconst workflowDefinitionSchema = z.object({\n input: z.custom<StandardSchemaV1>((val) => isStandardSchema(val), {\n message: \"input must be a Standard Schema compatible schema (e.g., Zod, Valibot, ArkType)\",\n }),\n output: z.custom<StandardSchemaV1>((val) => isStandardSchema(val), {\n message: \"output must be a Standard Schema compatible schema (e.g., Zod, Valibot, ArkType)\",\n }),\n activities: z.record(identifierSchema, activityDefinitionSchema).optional(),\n signals: z.record(identifierSchema, signalDefinitionSchema).optional(),\n queries: z.record(identifierSchema, queryDefinitionSchema).optional(),\n updates: z.record(identifierSchema, updateDefinitionSchema).optional(),\n});\n\n/**\n * Schema for validating a contract definition structure\n */\nconst contractValidationSchema = z\n .object({\n taskQueue: z.string().trim().min(1, \"taskQueue cannot be empty\"),\n workflows: z\n .record(identifierSchema, workflowDefinitionSchema)\n .refine((workflows) => Object.keys(workflows).length > 0, {\n message: \"at least one workflow is required\",\n }),\n activities: z.record(identifierSchema, activityDefinitionSchema).optional(),\n })\n .superRefine((contract, ctx) => {\n // Check for conflicts between global and workflow-specific activities\n if (!contract.activities) {\n return;\n }\n\n for (const [workflowName, workflow] of Object.entries(contract.workflows)) {\n if (workflow.activities) {\n for (const activityName of Object.keys(workflow.activities)) {\n if (activityName in contract.activities) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `workflow \"${workflowName}\" has activity \"${activityName}\" that conflicts with a global activity. Consider renaming the workflow-specific activity or removing the global activity \"${activityName}\".`,\n });\n return;\n }\n }\n }\n }\n });\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,SAAgB,eACd,YACW;AACX,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;AA0BT,SAAgB,aAA+C,YAA8B;AAC3F,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BT,SAAgB,YAA4C,YAA4B;AACtF,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BT,SAAgB,aAA+C,YAA8B;AAC3F,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCT,SAAgB,eACd,YACW;AACX,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDT,SAAgB,eACd,YACW;CAEX,MAAM,mBAAmB,yBAAyB,UAAU,WAAW;AAEvE,KAAI,CAAC,iBAAiB,SAAS;EAC7B,MAAM,eAAe,qBAAqB,iBAAiB,MAAM;AACjE,QAAM,IAAI,MAAM,+BAA+B,eAAe;;AAGhE,QAAO;;;;;AAMT,SAAS,iBAAiB,OAA2C;AAEnE,KACG,OAAO,UAAU,YAAY,OAAO,UAAU,cAC/C,UAAU,QACV,EAAE,eAAe,OAEjB,QAAO;CAGT,MAAM,WAAY,MAAkC;AAEpD,QACE,OAAO,aAAa,YACpB,aAAa,QACZ,SAAqC,eAAe,KACrD,OAAQ,SAAqC,gBAAgB;;;;;;;AASjE,MAAM,mBAAmB,EACtB,QAAQ,CACR,IAAI,EAAE,CACN,MAAM,8BAA8B,wCAAwC;;;;;;;AAQ/E,SAAS,qBAAqB,OAA2B;CACvD,MAAM,SAAS,MAAM;AACrB,KAAI,CAAC,UAAU,OAAO,WAAW,EAC/B,QAAO,MAAM;CAGf,MAAM,aAAa,OAAO;AAC1B,KAAI,CAAC,WACH,QAAO,MAAM;AAIf,KACE,WAAW,SAAS,iBACpB,YAAY,cACZ,MAAM,QAAS,WAAsC,OAAO,IAC3D,WAAkD,OAAO,SAAS,GACnE;EACA,MAAM,gBAAiB,WAAkD,OAAO,IAAI;AACpF,MAAI,cACF,QAAO;;AAIX,QAAO,WAAW,WAAW,MAAM;;;;;;AAOrC,MAAM,2BAA2B,EAAE,OAAO;CACxC,OAAO,EAAE,QAA0B,QAAQ,iBAAiB,IAAI,EAAE,EAChE,SAAS,mFACV,CAAC;CACF,QAAQ,EAAE,QAA0B,QAAQ,iBAAiB,IAAI,EAAE,EACjE,SAAS,oFACV,CAAC;CACH,CAAC;;;;AAKF,MAAM,yBAAyB,EAAE,OAAO,EACtC,OAAO,EAAE,QAA0B,QAAQ,iBAAiB,IAAI,EAAE,EAChE,SAAS,mFACV,CAAC,EACH,CAAC;;;;AAKF,MAAM,wBAAwB,EAAE,OAAO;CACrC,OAAO,EAAE,QAA0B,QAAQ,iBAAiB,IAAI,EAAE,EAChE,SAAS,mFACV,CAAC;CACF,QAAQ,EAAE,QAA0B,QAAQ,iBAAiB,IAAI,EAAE,EACjE,SAAS,oFACV,CAAC;CACH,CAAC;;;;AAKF,MAAM,yBAAyB,EAAE,OAAO;CACtC,OAAO,EAAE,QAA0B,QAAQ,iBAAiB,IAAI,EAAE,EAChE,SAAS,mFACV,CAAC;CACF,QAAQ,EAAE,QAA0B,QAAQ,iBAAiB,IAAI,EAAE,EACjE,SAAS,oFACV,CAAC;CACH,CAAC;;;;AAKF,MAAM,2BAA2B,EAAE,OAAO;CACxC,OAAO,EAAE,QAA0B,QAAQ,iBAAiB,IAAI,EAAE,EAChE,SAAS,mFACV,CAAC;CACF,QAAQ,EAAE,QAA0B,QAAQ,iBAAiB,IAAI,EAAE,EACjE,SAAS,oFACV,CAAC;CACF,YAAY,EAAE,OAAO,kBAAkB,yBAAyB,CAAC,UAAU;CAC3E,SAAS,EAAE,OAAO,kBAAkB,uBAAuB,CAAC,UAAU;CACtE,SAAS,EAAE,OAAO,kBAAkB,sBAAsB,CAAC,UAAU;CACrE,SAAS,EAAE,OAAO,kBAAkB,uBAAuB,CAAC,UAAU;CACvE,CAAC;;;;AAKF,MAAM,2BAA2B,EAC9B,OAAO;CACN,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,4BAA4B;CAChE,WAAW,EACR,OAAO,kBAAkB,yBAAyB,CAClD,QAAQ,cAAc,OAAO,KAAK,UAAU,CAAC,SAAS,GAAG,EACxD,SAAS,qCACV,CAAC;CACJ,YAAY,EAAE,OAAO,kBAAkB,yBAAyB,CAAC,UAAU;CAC5E,CAAC,CACD,aAAa,UAAU,QAAQ;AAE9B,KAAI,CAAC,SAAS,WACZ;AAGF,MAAK,MAAM,CAAC,cAAc,aAAa,OAAO,QAAQ,SAAS,UAAU,CACvE,KAAI,SAAS,YACX;OAAK,MAAM,gBAAgB,OAAO,KAAK,SAAS,WAAW,CACzD,KAAI,gBAAgB,SAAS,YAAY;AACvC,OAAI,SAAS;IACX,MAAM,EAAE,aAAa;IACrB,SAAS,aAAa,aAAa,kBAAkB,aAAa,6HAA6H,aAAa;IAC7M,CAAC;AACF;;;EAKR"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@temporal-contract/contract",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Contract builder for temporal-contract",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"contract",
|
|
@@ -40,19 +40,23 @@
|
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@standard-schema/spec": "1.1.0",
|
|
43
|
-
"zod": "4.
|
|
43
|
+
"zod": "4.3.6"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@vitest/coverage-v8": "4.0.
|
|
46
|
+
"@vitest/coverage-v8": "4.0.18",
|
|
47
47
|
"arktype": "2.1.29",
|
|
48
|
-
"tsdown": "0.
|
|
48
|
+
"tsdown": "0.20.3",
|
|
49
|
+
"typedoc": "0.28.17",
|
|
50
|
+
"typedoc-plugin-markdown": "4.10.0",
|
|
49
51
|
"typescript": "5.9.3",
|
|
50
52
|
"valibot": "1.2.0",
|
|
51
|
-
"vitest": "4.0.
|
|
52
|
-
"@temporal-contract/tsconfig": "0.0
|
|
53
|
+
"vitest": "4.0.18",
|
|
54
|
+
"@temporal-contract/tsconfig": "0.2.0",
|
|
55
|
+
"@temporal-contract/typedoc": "0.1.0"
|
|
53
56
|
},
|
|
54
57
|
"scripts": {
|
|
55
58
|
"build": "tsdown src/index.ts --format cjs,esm --dts --clean",
|
|
59
|
+
"build:docs": "typedoc",
|
|
56
60
|
"dev": "tsdown src/index.ts --format cjs,esm --dts --watch",
|
|
57
61
|
"test": "vitest run",
|
|
58
62
|
"test:watch": "vitest",
|