@temporal-contract/contract 0.0.5 → 0.0.7
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/index.cjs +213 -102
- package/dist/index.d.cts +151 -40
- package/dist/index.d.mts +151 -40
- package/dist/index.mjs +213 -102
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -2,6 +2,217 @@ let zod = require("zod");
|
|
|
2
2
|
|
|
3
3
|
//#region src/builder.ts
|
|
4
4
|
/**
|
|
5
|
+
* Define a Temporal activity with type-safe input and output schemas.
|
|
6
|
+
*
|
|
7
|
+
* Activities are the building blocks of Temporal workflows that execute business logic
|
|
8
|
+
* and interact with external services. This function preserves TypeScript types while
|
|
9
|
+
* providing a consistent structure for activity definitions.
|
|
10
|
+
*
|
|
11
|
+
* @template TActivity - The activity definition type with input/output schemas
|
|
12
|
+
* @param definition - The activity definition containing input and output schemas
|
|
13
|
+
* @returns The same definition with preserved types for type inference
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { defineActivity } from '@temporal-contract/contract';
|
|
18
|
+
* import { z } from 'zod';
|
|
19
|
+
*
|
|
20
|
+
* export const sendEmail = defineActivity({
|
|
21
|
+
* input: z.object({
|
|
22
|
+
* to: z.string().email(),
|
|
23
|
+
* subject: z.string(),
|
|
24
|
+
* body: z.string(),
|
|
25
|
+
* }),
|
|
26
|
+
* output: z.object({
|
|
27
|
+
* messageId: z.string(),
|
|
28
|
+
* sentAt: z.date(),
|
|
29
|
+
* }),
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
function defineActivity(definition) {
|
|
34
|
+
return definition;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Define a Temporal signal with type-safe input schema.
|
|
38
|
+
*
|
|
39
|
+
* Signals are asynchronous messages sent to running workflows to update their state
|
|
40
|
+
* or trigger certain behaviors. This function ensures type safety for signal payloads.
|
|
41
|
+
*
|
|
42
|
+
* @template TSignal - The signal definition type with input schema
|
|
43
|
+
* @param definition - The signal definition containing input schema
|
|
44
|
+
* @returns The same definition with preserved types for type inference
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import { defineSignal } from '@temporal-contract/contract';
|
|
49
|
+
* import { z } from 'zod';
|
|
50
|
+
*
|
|
51
|
+
* export const approveOrder = defineSignal({
|
|
52
|
+
* input: z.object({
|
|
53
|
+
* orderId: z.string(),
|
|
54
|
+
* approvedBy: z.string(),
|
|
55
|
+
* }),
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
function defineSignal(definition) {
|
|
60
|
+
return definition;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Define a Temporal query with type-safe input and output schemas.
|
|
64
|
+
*
|
|
65
|
+
* Queries allow you to read the current state of a running workflow without
|
|
66
|
+
* modifying it. They are synchronous and should not perform any mutations.
|
|
67
|
+
*
|
|
68
|
+
* @template TQuery - The query definition type with input/output schemas
|
|
69
|
+
* @param definition - The query definition containing input and output schemas
|
|
70
|
+
* @returns The same definition with preserved types for type inference
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* import { defineQuery } from '@temporal-contract/contract';
|
|
75
|
+
* import { z } from 'zod';
|
|
76
|
+
*
|
|
77
|
+
* export const getOrderStatus = defineQuery({
|
|
78
|
+
* input: z.object({ orderId: z.string() }),
|
|
79
|
+
* output: z.object({
|
|
80
|
+
* status: z.enum(['pending', 'processing', 'completed', 'failed']),
|
|
81
|
+
* updatedAt: z.date(),
|
|
82
|
+
* }),
|
|
83
|
+
* });
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
function defineQuery(definition) {
|
|
87
|
+
return definition;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Define a Temporal update with type-safe input and output schemas.
|
|
91
|
+
*
|
|
92
|
+
* Updates are similar to signals but return a value and wait for the workflow
|
|
93
|
+
* to process them before completing. They provide a synchronous way to modify
|
|
94
|
+
* workflow state and get immediate feedback.
|
|
95
|
+
*
|
|
96
|
+
* @template TUpdate - The update definition type with input/output schemas
|
|
97
|
+
* @param definition - The update definition containing input and output schemas
|
|
98
|
+
* @returns The same definition with preserved types for type inference
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* import { defineUpdate } from '@temporal-contract/contract';
|
|
103
|
+
* import { z } from 'zod';
|
|
104
|
+
*
|
|
105
|
+
* export const updateOrderQuantity = defineUpdate({
|
|
106
|
+
* input: z.object({
|
|
107
|
+
* orderId: z.string(),
|
|
108
|
+
* newQuantity: z.number().positive(),
|
|
109
|
+
* }),
|
|
110
|
+
* output: z.object({
|
|
111
|
+
* success: z.boolean(),
|
|
112
|
+
* totalPrice: z.number(),
|
|
113
|
+
* }),
|
|
114
|
+
* });
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
function defineUpdate(definition) {
|
|
118
|
+
return definition;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Define a Temporal workflow with type-safe input, output, and associated operations.
|
|
122
|
+
*
|
|
123
|
+
* Workflows are durable functions that orchestrate activities, handle timeouts,
|
|
124
|
+
* and manage long-running processes. This function provides type safety for the
|
|
125
|
+
* entire workflow definition including activities, signals, queries, and updates.
|
|
126
|
+
*
|
|
127
|
+
* @template TWorkflow - The workflow definition type with all associated schemas
|
|
128
|
+
* @param definition - The workflow definition containing input, output, and operations
|
|
129
|
+
* @returns The same definition with preserved types for type inference
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* import { defineWorkflow, defineActivity, defineSignal } from '@temporal-contract/contract';
|
|
134
|
+
* import { z } from 'zod';
|
|
135
|
+
*
|
|
136
|
+
* export const processOrder = defineWorkflow({
|
|
137
|
+
* input: z.object({ orderId: z.string() }),
|
|
138
|
+
* output: z.object({ success: z.boolean() }),
|
|
139
|
+
* activities: {
|
|
140
|
+
* validatePayment: defineActivity({
|
|
141
|
+
* input: z.object({ orderId: z.string() }),
|
|
142
|
+
* output: z.object({ valid: z.boolean() }),
|
|
143
|
+
* }),
|
|
144
|
+
* },
|
|
145
|
+
* signals: {
|
|
146
|
+
* cancel: defineSignal({
|
|
147
|
+
* input: z.object({ reason: z.string() }),
|
|
148
|
+
* }),
|
|
149
|
+
* },
|
|
150
|
+
* });
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
function defineWorkflow(definition) {
|
|
154
|
+
return definition;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Define a complete Temporal contract with type-safe workflows and activities.
|
|
158
|
+
*
|
|
159
|
+
* A contract is the central definition that ties together your Temporal application's
|
|
160
|
+
* workflows and activities. It provides:
|
|
161
|
+
* - Type safety across client, worker, and workflow code
|
|
162
|
+
* - Automatic validation at runtime
|
|
163
|
+
* - Compile-time verification of implementations
|
|
164
|
+
* - Clear API boundaries and documentation
|
|
165
|
+
*
|
|
166
|
+
* The contract validates the structure and ensures:
|
|
167
|
+
* - Task queue is specified
|
|
168
|
+
* - At least one workflow is defined
|
|
169
|
+
* - Valid JavaScript identifiers are used
|
|
170
|
+
* - No conflicts between global and workflow-specific activities
|
|
171
|
+
* - All schemas implement the Standard Schema specification
|
|
172
|
+
*
|
|
173
|
+
* @template TContract - The contract definition type
|
|
174
|
+
* @param definition - The complete contract definition
|
|
175
|
+
* @returns The same definition with preserved types for type inference
|
|
176
|
+
* @throws {Error} If the contract structure is invalid
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* import { defineContract } from '@temporal-contract/contract';
|
|
181
|
+
* import { z } from 'zod';
|
|
182
|
+
*
|
|
183
|
+
* export const myContract = defineContract({
|
|
184
|
+
* taskQueue: 'orders',
|
|
185
|
+
* workflows: {
|
|
186
|
+
* processOrder: {
|
|
187
|
+
* input: z.object({ orderId: z.string() }),
|
|
188
|
+
* output: z.object({ success: z.boolean() }),
|
|
189
|
+
* activities: {
|
|
190
|
+
* chargePayment: {
|
|
191
|
+
* input: z.object({ amount: z.number() }),
|
|
192
|
+
* output: z.object({ transactionId: z.string() }),
|
|
193
|
+
* },
|
|
194
|
+
* },
|
|
195
|
+
* },
|
|
196
|
+
* },
|
|
197
|
+
* // Optional global activities shared across workflows
|
|
198
|
+
* activities: {
|
|
199
|
+
* logEvent: {
|
|
200
|
+
* input: z.object({ message: z.string() }),
|
|
201
|
+
* output: z.void(),
|
|
202
|
+
* },
|
|
203
|
+
* },
|
|
204
|
+
* });
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
function defineContract(definition) {
|
|
208
|
+
const validationResult = contractValidationSchema.safeParse(definition);
|
|
209
|
+
if (!validationResult.success) {
|
|
210
|
+
const cleanMessage = getCleanErrorMessage(validationResult.error);
|
|
211
|
+
throw new Error(`Contract validation failed: ${cleanMessage}`);
|
|
212
|
+
}
|
|
213
|
+
return definition;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
5
216
|
* Check if a value is a Standard Schema compatible schema
|
|
6
217
|
*/
|
|
7
218
|
function isStandardSchema(value) {
|
|
@@ -18,7 +229,7 @@ const identifierSchema = zod.z.string().min(1).regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$
|
|
|
18
229
|
/**
|
|
19
230
|
* Extract clean error message from Zod validation error
|
|
20
231
|
*/
|
|
21
|
-
|
|
232
|
+
function getCleanErrorMessage(error) {
|
|
22
233
|
try {
|
|
23
234
|
const parsed = JSON.parse(error.message);
|
|
24
235
|
if (Array.isArray(parsed) && parsed.length > 0) {
|
|
@@ -31,7 +242,7 @@ const getCleanErrorMessage = (error) => {
|
|
|
31
242
|
}
|
|
32
243
|
} catch {}
|
|
33
244
|
return error.message;
|
|
34
|
-
}
|
|
245
|
+
}
|
|
35
246
|
/**
|
|
36
247
|
* Schema for validating activity definitions
|
|
37
248
|
* Checks that input and output are Standard Schema compatible schemas
|
|
@@ -88,106 +299,6 @@ const contractValidationSchema = zod.z.object({
|
|
|
88
299
|
}
|
|
89
300
|
}
|
|
90
301
|
});
|
|
91
|
-
/**
|
|
92
|
-
* Builder for creating activity definitions
|
|
93
|
-
*
|
|
94
|
-
* @example
|
|
95
|
-
* ```ts
|
|
96
|
-
* const myActivity = defineActivity({
|
|
97
|
-
* input: z.tuple([z.object({ name: z.string() })]),
|
|
98
|
-
* output: z.object({ greeting: z.string() }),
|
|
99
|
-
* });
|
|
100
|
-
* ```
|
|
101
|
-
*/
|
|
102
|
-
const defineActivity = (definition) => {
|
|
103
|
-
return definition;
|
|
104
|
-
};
|
|
105
|
-
/**
|
|
106
|
-
* Builder for creating signal definitions
|
|
107
|
-
*
|
|
108
|
-
* @example
|
|
109
|
-
* ```ts
|
|
110
|
-
* const mySignal = defineSignal({
|
|
111
|
-
* input: z.object({ message: z.string() }),
|
|
112
|
-
* });
|
|
113
|
-
* ```
|
|
114
|
-
*/
|
|
115
|
-
const defineSignal = (definition) => {
|
|
116
|
-
return definition;
|
|
117
|
-
};
|
|
118
|
-
/**
|
|
119
|
-
* Builder for creating query definitions
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* ```ts
|
|
123
|
-
* const myQuery = defineQuery({
|
|
124
|
-
* input: z.object({ id: z.string() }),
|
|
125
|
-
* output: z.object({ status: z.string() }),
|
|
126
|
-
* });
|
|
127
|
-
* ```
|
|
128
|
-
*/
|
|
129
|
-
const defineQuery = (definition) => {
|
|
130
|
-
return definition;
|
|
131
|
-
};
|
|
132
|
-
/**
|
|
133
|
-
* Builder for creating update definitions
|
|
134
|
-
*
|
|
135
|
-
* @example
|
|
136
|
-
* ```ts
|
|
137
|
-
* const myUpdate = defineUpdate({
|
|
138
|
-
* input: z.object({ value: z.number() }),
|
|
139
|
-
* output: z.object({ newValue: z.number() }),
|
|
140
|
-
* });
|
|
141
|
-
* ```
|
|
142
|
-
*/
|
|
143
|
-
const defineUpdate = (definition) => {
|
|
144
|
-
return definition;
|
|
145
|
-
};
|
|
146
|
-
/**
|
|
147
|
-
* Builder for creating workflow definitions
|
|
148
|
-
*
|
|
149
|
-
* @example
|
|
150
|
-
* ```ts
|
|
151
|
-
* const myWorkflow = defineWorkflow({
|
|
152
|
-
* input: z.tuple([z.object({ orderId: z.string() })]),
|
|
153
|
-
* output: z.object({ status: z.string() }),
|
|
154
|
-
* activities: {
|
|
155
|
-
* processPayment: defineActivity({
|
|
156
|
-
* input: z.tuple([z.object({ amount: z.number() })]),
|
|
157
|
-
* output: z.object({ success: z.boolean() }),
|
|
158
|
-
* }),
|
|
159
|
-
* },
|
|
160
|
-
* });
|
|
161
|
-
* ```
|
|
162
|
-
*/
|
|
163
|
-
const defineWorkflow = (definition) => {
|
|
164
|
-
return definition;
|
|
165
|
-
};
|
|
166
|
-
/**
|
|
167
|
-
* Builder for creating a complete contract
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```ts
|
|
171
|
-
* const myContract = defineContract({
|
|
172
|
-
* taskQueue: 'my-service',
|
|
173
|
-
* workflows: {
|
|
174
|
-
* processOrder: defineWorkflow({ ... }),
|
|
175
|
-
* sendNotification: defineWorkflow({ ... }),
|
|
176
|
-
* },
|
|
177
|
-
* activities: {
|
|
178
|
-
* sendEmail: defineActivity({ ... }),
|
|
179
|
-
* },
|
|
180
|
-
* });
|
|
181
|
-
* ```
|
|
182
|
-
*/
|
|
183
|
-
const defineContract = (definition) => {
|
|
184
|
-
const validationResult = contractValidationSchema.safeParse(definition);
|
|
185
|
-
if (!validationResult.success) {
|
|
186
|
-
const cleanMessage = getCleanErrorMessage(validationResult.error);
|
|
187
|
-
throw new Error(`Contract error: ${cleanMessage}`);
|
|
188
|
-
}
|
|
189
|
-
return definition;
|
|
190
|
-
};
|
|
191
302
|
|
|
192
303
|
//#endregion
|
|
193
304
|
//#region src/nexus-types.ts
|
package/dist/index.d.cts
CHANGED
|
@@ -89,88 +89,199 @@ type InferContractWorkflows<TContract extends ContractDefinition> = TContract["w
|
|
|
89
89
|
//#endregion
|
|
90
90
|
//#region src/builder.d.ts
|
|
91
91
|
/**
|
|
92
|
-
*
|
|
92
|
+
* Define a Temporal activity with type-safe input and output schemas.
|
|
93
|
+
*
|
|
94
|
+
* Activities are the building blocks of Temporal workflows that execute business logic
|
|
95
|
+
* and interact with external services. This function preserves TypeScript types while
|
|
96
|
+
* providing a consistent structure for activity definitions.
|
|
97
|
+
*
|
|
98
|
+
* @template TActivity - The activity definition type with input/output schemas
|
|
99
|
+
* @param definition - The activity definition containing input and output schemas
|
|
100
|
+
* @returns The same definition with preserved types for type inference
|
|
93
101
|
*
|
|
94
102
|
* @example
|
|
95
|
-
* ```
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
103
|
+
* ```typescript
|
|
104
|
+
* import { defineActivity } from '@temporal-contract/contract';
|
|
105
|
+
* import { z } from 'zod';
|
|
106
|
+
*
|
|
107
|
+
* export const sendEmail = defineActivity({
|
|
108
|
+
* input: z.object({
|
|
109
|
+
* to: z.string().email(),
|
|
110
|
+
* subject: z.string(),
|
|
111
|
+
* body: z.string(),
|
|
112
|
+
* }),
|
|
113
|
+
* output: z.object({
|
|
114
|
+
* messageId: z.string(),
|
|
115
|
+
* sentAt: z.date(),
|
|
116
|
+
* }),
|
|
99
117
|
* });
|
|
100
118
|
* ```
|
|
101
119
|
*/
|
|
102
|
-
declare
|
|
120
|
+
declare function defineActivity<TActivity extends ActivityDefinition>(definition: TActivity): TActivity;
|
|
103
121
|
/**
|
|
104
|
-
*
|
|
122
|
+
* Define a Temporal signal with type-safe input schema.
|
|
123
|
+
*
|
|
124
|
+
* Signals are asynchronous messages sent to running workflows to update their state
|
|
125
|
+
* or trigger certain behaviors. This function ensures type safety for signal payloads.
|
|
126
|
+
*
|
|
127
|
+
* @template TSignal - The signal definition type with input schema
|
|
128
|
+
* @param definition - The signal definition containing input schema
|
|
129
|
+
* @returns The same definition with preserved types for type inference
|
|
105
130
|
*
|
|
106
131
|
* @example
|
|
107
|
-
* ```
|
|
108
|
-
*
|
|
109
|
-
*
|
|
132
|
+
* ```typescript
|
|
133
|
+
* import { defineSignal } from '@temporal-contract/contract';
|
|
134
|
+
* import { z } from 'zod';
|
|
135
|
+
*
|
|
136
|
+
* export const approveOrder = defineSignal({
|
|
137
|
+
* input: z.object({
|
|
138
|
+
* orderId: z.string(),
|
|
139
|
+
* approvedBy: z.string(),
|
|
140
|
+
* }),
|
|
110
141
|
* });
|
|
111
142
|
* ```
|
|
112
143
|
*/
|
|
113
|
-
declare
|
|
144
|
+
declare function defineSignal<TSignal extends SignalDefinition>(definition: TSignal): TSignal;
|
|
114
145
|
/**
|
|
115
|
-
*
|
|
146
|
+
* Define a Temporal query with type-safe input and output schemas.
|
|
147
|
+
*
|
|
148
|
+
* Queries allow you to read the current state of a running workflow without
|
|
149
|
+
* modifying it. They are synchronous and should not perform any mutations.
|
|
150
|
+
*
|
|
151
|
+
* @template TQuery - The query definition type with input/output schemas
|
|
152
|
+
* @param definition - The query definition containing input and output schemas
|
|
153
|
+
* @returns The same definition with preserved types for type inference
|
|
116
154
|
*
|
|
117
155
|
* @example
|
|
118
|
-
* ```
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
156
|
+
* ```typescript
|
|
157
|
+
* import { defineQuery } from '@temporal-contract/contract';
|
|
158
|
+
* import { z } from 'zod';
|
|
159
|
+
*
|
|
160
|
+
* export const getOrderStatus = defineQuery({
|
|
161
|
+
* input: z.object({ orderId: z.string() }),
|
|
162
|
+
* output: z.object({
|
|
163
|
+
* status: z.enum(['pending', 'processing', 'completed', 'failed']),
|
|
164
|
+
* updatedAt: z.date(),
|
|
165
|
+
* }),
|
|
122
166
|
* });
|
|
123
167
|
* ```
|
|
124
168
|
*/
|
|
125
|
-
declare
|
|
169
|
+
declare function defineQuery<TQuery extends QueryDefinition>(definition: TQuery): TQuery;
|
|
126
170
|
/**
|
|
127
|
-
*
|
|
171
|
+
* Define a Temporal update with type-safe input and output schemas.
|
|
172
|
+
*
|
|
173
|
+
* Updates are similar to signals but return a value and wait for the workflow
|
|
174
|
+
* to process them before completing. They provide a synchronous way to modify
|
|
175
|
+
* workflow state and get immediate feedback.
|
|
176
|
+
*
|
|
177
|
+
* @template TUpdate - The update definition type with input/output schemas
|
|
178
|
+
* @param definition - The update definition containing input and output schemas
|
|
179
|
+
* @returns The same definition with preserved types for type inference
|
|
128
180
|
*
|
|
129
181
|
* @example
|
|
130
|
-
* ```
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
182
|
+
* ```typescript
|
|
183
|
+
* import { defineUpdate } from '@temporal-contract/contract';
|
|
184
|
+
* import { z } from 'zod';
|
|
185
|
+
*
|
|
186
|
+
* export const updateOrderQuantity = defineUpdate({
|
|
187
|
+
* input: z.object({
|
|
188
|
+
* orderId: z.string(),
|
|
189
|
+
* newQuantity: z.number().positive(),
|
|
190
|
+
* }),
|
|
191
|
+
* output: z.object({
|
|
192
|
+
* success: z.boolean(),
|
|
193
|
+
* totalPrice: z.number(),
|
|
194
|
+
* }),
|
|
134
195
|
* });
|
|
135
196
|
* ```
|
|
136
197
|
*/
|
|
137
|
-
declare
|
|
198
|
+
declare function defineUpdate<TUpdate extends UpdateDefinition>(definition: TUpdate): TUpdate;
|
|
138
199
|
/**
|
|
139
|
-
*
|
|
200
|
+
* Define a Temporal workflow with type-safe input, output, and associated operations.
|
|
201
|
+
*
|
|
202
|
+
* Workflows are durable functions that orchestrate activities, handle timeouts,
|
|
203
|
+
* and manage long-running processes. This function provides type safety for the
|
|
204
|
+
* entire workflow definition including activities, signals, queries, and updates.
|
|
205
|
+
*
|
|
206
|
+
* @template TWorkflow - The workflow definition type with all associated schemas
|
|
207
|
+
* @param definition - The workflow definition containing input, output, and operations
|
|
208
|
+
* @returns The same definition with preserved types for type inference
|
|
140
209
|
*
|
|
141
210
|
* @example
|
|
142
|
-
* ```
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
211
|
+
* ```typescript
|
|
212
|
+
* import { defineWorkflow, defineActivity, defineSignal } from '@temporal-contract/contract';
|
|
213
|
+
* import { z } from 'zod';
|
|
214
|
+
*
|
|
215
|
+
* export const processOrder = defineWorkflow({
|
|
216
|
+
* input: z.object({ orderId: z.string() }),
|
|
217
|
+
* output: z.object({ success: z.boolean() }),
|
|
146
218
|
* activities: {
|
|
147
|
-
*
|
|
148
|
-
* input: z.
|
|
149
|
-
* output: z.object({
|
|
219
|
+
* validatePayment: defineActivity({
|
|
220
|
+
* input: z.object({ orderId: z.string() }),
|
|
221
|
+
* output: z.object({ valid: z.boolean() }),
|
|
222
|
+
* }),
|
|
223
|
+
* },
|
|
224
|
+
* signals: {
|
|
225
|
+
* cancel: defineSignal({
|
|
226
|
+
* input: z.object({ reason: z.string() }),
|
|
150
227
|
* }),
|
|
151
228
|
* },
|
|
152
229
|
* });
|
|
153
230
|
* ```
|
|
154
231
|
*/
|
|
155
|
-
declare
|
|
232
|
+
declare function defineWorkflow<TWorkflow extends WorkflowDefinition>(definition: TWorkflow): TWorkflow;
|
|
156
233
|
/**
|
|
157
|
-
*
|
|
234
|
+
* Define a complete Temporal contract with type-safe workflows and activities.
|
|
235
|
+
*
|
|
236
|
+
* A contract is the central definition that ties together your Temporal application's
|
|
237
|
+
* workflows and activities. It provides:
|
|
238
|
+
* - Type safety across client, worker, and workflow code
|
|
239
|
+
* - Automatic validation at runtime
|
|
240
|
+
* - Compile-time verification of implementations
|
|
241
|
+
* - Clear API boundaries and documentation
|
|
242
|
+
*
|
|
243
|
+
* The contract validates the structure and ensures:
|
|
244
|
+
* - Task queue is specified
|
|
245
|
+
* - At least one workflow is defined
|
|
246
|
+
* - Valid JavaScript identifiers are used
|
|
247
|
+
* - No conflicts between global and workflow-specific activities
|
|
248
|
+
* - All schemas implement the Standard Schema specification
|
|
249
|
+
*
|
|
250
|
+
* @template TContract - The contract definition type
|
|
251
|
+
* @param definition - The complete contract definition
|
|
252
|
+
* @returns The same definition with preserved types for type inference
|
|
253
|
+
* @throws {Error} If the contract structure is invalid
|
|
158
254
|
*
|
|
159
255
|
* @example
|
|
160
|
-
* ```
|
|
161
|
-
*
|
|
162
|
-
*
|
|
256
|
+
* ```typescript
|
|
257
|
+
* import { defineContract } from '@temporal-contract/contract';
|
|
258
|
+
* import { z } from 'zod';
|
|
259
|
+
*
|
|
260
|
+
* export const myContract = defineContract({
|
|
261
|
+
* taskQueue: 'orders',
|
|
163
262
|
* workflows: {
|
|
164
|
-
* processOrder:
|
|
165
|
-
*
|
|
263
|
+
* processOrder: {
|
|
264
|
+
* input: z.object({ orderId: z.string() }),
|
|
265
|
+
* output: z.object({ success: z.boolean() }),
|
|
266
|
+
* activities: {
|
|
267
|
+
* chargePayment: {
|
|
268
|
+
* input: z.object({ amount: z.number() }),
|
|
269
|
+
* output: z.object({ transactionId: z.string() }),
|
|
270
|
+
* },
|
|
271
|
+
* },
|
|
272
|
+
* },
|
|
166
273
|
* },
|
|
274
|
+
* // Optional global activities shared across workflows
|
|
167
275
|
* activities: {
|
|
168
|
-
*
|
|
276
|
+
* logEvent: {
|
|
277
|
+
* input: z.object({ message: z.string() }),
|
|
278
|
+
* output: z.void(),
|
|
279
|
+
* },
|
|
169
280
|
* },
|
|
170
281
|
* });
|
|
171
282
|
* ```
|
|
172
283
|
*/
|
|
173
|
-
declare
|
|
284
|
+
declare function defineContract<TContract extends ContractDefinition>(definition: TContract): TContract;
|
|
174
285
|
//#endregion
|
|
175
286
|
//#region src/nexus-types.d.ts
|
|
176
287
|
/**
|
package/dist/index.d.mts
CHANGED
|
@@ -89,88 +89,199 @@ type InferContractWorkflows<TContract extends ContractDefinition> = TContract["w
|
|
|
89
89
|
//#endregion
|
|
90
90
|
//#region src/builder.d.ts
|
|
91
91
|
/**
|
|
92
|
-
*
|
|
92
|
+
* Define a Temporal activity with type-safe input and output schemas.
|
|
93
|
+
*
|
|
94
|
+
* Activities are the building blocks of Temporal workflows that execute business logic
|
|
95
|
+
* and interact with external services. This function preserves TypeScript types while
|
|
96
|
+
* providing a consistent structure for activity definitions.
|
|
97
|
+
*
|
|
98
|
+
* @template TActivity - The activity definition type with input/output schemas
|
|
99
|
+
* @param definition - The activity definition containing input and output schemas
|
|
100
|
+
* @returns The same definition with preserved types for type inference
|
|
93
101
|
*
|
|
94
102
|
* @example
|
|
95
|
-
* ```
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
103
|
+
* ```typescript
|
|
104
|
+
* import { defineActivity } from '@temporal-contract/contract';
|
|
105
|
+
* import { z } from 'zod';
|
|
106
|
+
*
|
|
107
|
+
* export const sendEmail = defineActivity({
|
|
108
|
+
* input: z.object({
|
|
109
|
+
* to: z.string().email(),
|
|
110
|
+
* subject: z.string(),
|
|
111
|
+
* body: z.string(),
|
|
112
|
+
* }),
|
|
113
|
+
* output: z.object({
|
|
114
|
+
* messageId: z.string(),
|
|
115
|
+
* sentAt: z.date(),
|
|
116
|
+
* }),
|
|
99
117
|
* });
|
|
100
118
|
* ```
|
|
101
119
|
*/
|
|
102
|
-
declare
|
|
120
|
+
declare function defineActivity<TActivity extends ActivityDefinition>(definition: TActivity): TActivity;
|
|
103
121
|
/**
|
|
104
|
-
*
|
|
122
|
+
* Define a Temporal signal with type-safe input schema.
|
|
123
|
+
*
|
|
124
|
+
* Signals are asynchronous messages sent to running workflows to update their state
|
|
125
|
+
* or trigger certain behaviors. This function ensures type safety for signal payloads.
|
|
126
|
+
*
|
|
127
|
+
* @template TSignal - The signal definition type with input schema
|
|
128
|
+
* @param definition - The signal definition containing input schema
|
|
129
|
+
* @returns The same definition with preserved types for type inference
|
|
105
130
|
*
|
|
106
131
|
* @example
|
|
107
|
-
* ```
|
|
108
|
-
*
|
|
109
|
-
*
|
|
132
|
+
* ```typescript
|
|
133
|
+
* import { defineSignal } from '@temporal-contract/contract';
|
|
134
|
+
* import { z } from 'zod';
|
|
135
|
+
*
|
|
136
|
+
* export const approveOrder = defineSignal({
|
|
137
|
+
* input: z.object({
|
|
138
|
+
* orderId: z.string(),
|
|
139
|
+
* approvedBy: z.string(),
|
|
140
|
+
* }),
|
|
110
141
|
* });
|
|
111
142
|
* ```
|
|
112
143
|
*/
|
|
113
|
-
declare
|
|
144
|
+
declare function defineSignal<TSignal extends SignalDefinition>(definition: TSignal): TSignal;
|
|
114
145
|
/**
|
|
115
|
-
*
|
|
146
|
+
* Define a Temporal query with type-safe input and output schemas.
|
|
147
|
+
*
|
|
148
|
+
* Queries allow you to read the current state of a running workflow without
|
|
149
|
+
* modifying it. They are synchronous and should not perform any mutations.
|
|
150
|
+
*
|
|
151
|
+
* @template TQuery - The query definition type with input/output schemas
|
|
152
|
+
* @param definition - The query definition containing input and output schemas
|
|
153
|
+
* @returns The same definition with preserved types for type inference
|
|
116
154
|
*
|
|
117
155
|
* @example
|
|
118
|
-
* ```
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
156
|
+
* ```typescript
|
|
157
|
+
* import { defineQuery } from '@temporal-contract/contract';
|
|
158
|
+
* import { z } from 'zod';
|
|
159
|
+
*
|
|
160
|
+
* export const getOrderStatus = defineQuery({
|
|
161
|
+
* input: z.object({ orderId: z.string() }),
|
|
162
|
+
* output: z.object({
|
|
163
|
+
* status: z.enum(['pending', 'processing', 'completed', 'failed']),
|
|
164
|
+
* updatedAt: z.date(),
|
|
165
|
+
* }),
|
|
122
166
|
* });
|
|
123
167
|
* ```
|
|
124
168
|
*/
|
|
125
|
-
declare
|
|
169
|
+
declare function defineQuery<TQuery extends QueryDefinition>(definition: TQuery): TQuery;
|
|
126
170
|
/**
|
|
127
|
-
*
|
|
171
|
+
* Define a Temporal update with type-safe input and output schemas.
|
|
172
|
+
*
|
|
173
|
+
* Updates are similar to signals but return a value and wait for the workflow
|
|
174
|
+
* to process them before completing. They provide a synchronous way to modify
|
|
175
|
+
* workflow state and get immediate feedback.
|
|
176
|
+
*
|
|
177
|
+
* @template TUpdate - The update definition type with input/output schemas
|
|
178
|
+
* @param definition - The update definition containing input and output schemas
|
|
179
|
+
* @returns The same definition with preserved types for type inference
|
|
128
180
|
*
|
|
129
181
|
* @example
|
|
130
|
-
* ```
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
182
|
+
* ```typescript
|
|
183
|
+
* import { defineUpdate } from '@temporal-contract/contract';
|
|
184
|
+
* import { z } from 'zod';
|
|
185
|
+
*
|
|
186
|
+
* export const updateOrderQuantity = defineUpdate({
|
|
187
|
+
* input: z.object({
|
|
188
|
+
* orderId: z.string(),
|
|
189
|
+
* newQuantity: z.number().positive(),
|
|
190
|
+
* }),
|
|
191
|
+
* output: z.object({
|
|
192
|
+
* success: z.boolean(),
|
|
193
|
+
* totalPrice: z.number(),
|
|
194
|
+
* }),
|
|
134
195
|
* });
|
|
135
196
|
* ```
|
|
136
197
|
*/
|
|
137
|
-
declare
|
|
198
|
+
declare function defineUpdate<TUpdate extends UpdateDefinition>(definition: TUpdate): TUpdate;
|
|
138
199
|
/**
|
|
139
|
-
*
|
|
200
|
+
* Define a Temporal workflow with type-safe input, output, and associated operations.
|
|
201
|
+
*
|
|
202
|
+
* Workflows are durable functions that orchestrate activities, handle timeouts,
|
|
203
|
+
* and manage long-running processes. This function provides type safety for the
|
|
204
|
+
* entire workflow definition including activities, signals, queries, and updates.
|
|
205
|
+
*
|
|
206
|
+
* @template TWorkflow - The workflow definition type with all associated schemas
|
|
207
|
+
* @param definition - The workflow definition containing input, output, and operations
|
|
208
|
+
* @returns The same definition with preserved types for type inference
|
|
140
209
|
*
|
|
141
210
|
* @example
|
|
142
|
-
* ```
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
211
|
+
* ```typescript
|
|
212
|
+
* import { defineWorkflow, defineActivity, defineSignal } from '@temporal-contract/contract';
|
|
213
|
+
* import { z } from 'zod';
|
|
214
|
+
*
|
|
215
|
+
* export const processOrder = defineWorkflow({
|
|
216
|
+
* input: z.object({ orderId: z.string() }),
|
|
217
|
+
* output: z.object({ success: z.boolean() }),
|
|
146
218
|
* activities: {
|
|
147
|
-
*
|
|
148
|
-
* input: z.
|
|
149
|
-
* output: z.object({
|
|
219
|
+
* validatePayment: defineActivity({
|
|
220
|
+
* input: z.object({ orderId: z.string() }),
|
|
221
|
+
* output: z.object({ valid: z.boolean() }),
|
|
222
|
+
* }),
|
|
223
|
+
* },
|
|
224
|
+
* signals: {
|
|
225
|
+
* cancel: defineSignal({
|
|
226
|
+
* input: z.object({ reason: z.string() }),
|
|
150
227
|
* }),
|
|
151
228
|
* },
|
|
152
229
|
* });
|
|
153
230
|
* ```
|
|
154
231
|
*/
|
|
155
|
-
declare
|
|
232
|
+
declare function defineWorkflow<TWorkflow extends WorkflowDefinition>(definition: TWorkflow): TWorkflow;
|
|
156
233
|
/**
|
|
157
|
-
*
|
|
234
|
+
* Define a complete Temporal contract with type-safe workflows and activities.
|
|
235
|
+
*
|
|
236
|
+
* A contract is the central definition that ties together your Temporal application's
|
|
237
|
+
* workflows and activities. It provides:
|
|
238
|
+
* - Type safety across client, worker, and workflow code
|
|
239
|
+
* - Automatic validation at runtime
|
|
240
|
+
* - Compile-time verification of implementations
|
|
241
|
+
* - Clear API boundaries and documentation
|
|
242
|
+
*
|
|
243
|
+
* The contract validates the structure and ensures:
|
|
244
|
+
* - Task queue is specified
|
|
245
|
+
* - At least one workflow is defined
|
|
246
|
+
* - Valid JavaScript identifiers are used
|
|
247
|
+
* - No conflicts between global and workflow-specific activities
|
|
248
|
+
* - All schemas implement the Standard Schema specification
|
|
249
|
+
*
|
|
250
|
+
* @template TContract - The contract definition type
|
|
251
|
+
* @param definition - The complete contract definition
|
|
252
|
+
* @returns The same definition with preserved types for type inference
|
|
253
|
+
* @throws {Error} If the contract structure is invalid
|
|
158
254
|
*
|
|
159
255
|
* @example
|
|
160
|
-
* ```
|
|
161
|
-
*
|
|
162
|
-
*
|
|
256
|
+
* ```typescript
|
|
257
|
+
* import { defineContract } from '@temporal-contract/contract';
|
|
258
|
+
* import { z } from 'zod';
|
|
259
|
+
*
|
|
260
|
+
* export const myContract = defineContract({
|
|
261
|
+
* taskQueue: 'orders',
|
|
163
262
|
* workflows: {
|
|
164
|
-
* processOrder:
|
|
165
|
-
*
|
|
263
|
+
* processOrder: {
|
|
264
|
+
* input: z.object({ orderId: z.string() }),
|
|
265
|
+
* output: z.object({ success: z.boolean() }),
|
|
266
|
+
* activities: {
|
|
267
|
+
* chargePayment: {
|
|
268
|
+
* input: z.object({ amount: z.number() }),
|
|
269
|
+
* output: z.object({ transactionId: z.string() }),
|
|
270
|
+
* },
|
|
271
|
+
* },
|
|
272
|
+
* },
|
|
166
273
|
* },
|
|
274
|
+
* // Optional global activities shared across workflows
|
|
167
275
|
* activities: {
|
|
168
|
-
*
|
|
276
|
+
* logEvent: {
|
|
277
|
+
* input: z.object({ message: z.string() }),
|
|
278
|
+
* output: z.void(),
|
|
279
|
+
* },
|
|
169
280
|
* },
|
|
170
281
|
* });
|
|
171
282
|
* ```
|
|
172
283
|
*/
|
|
173
|
-
declare
|
|
284
|
+
declare function defineContract<TContract extends ContractDefinition>(definition: TContract): TContract;
|
|
174
285
|
//#endregion
|
|
175
286
|
//#region src/nexus-types.d.ts
|
|
176
287
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -2,6 +2,217 @@ import { z } from "zod";
|
|
|
2
2
|
|
|
3
3
|
//#region src/builder.ts
|
|
4
4
|
/**
|
|
5
|
+
* Define a Temporal activity with type-safe input and output schemas.
|
|
6
|
+
*
|
|
7
|
+
* Activities are the building blocks of Temporal workflows that execute business logic
|
|
8
|
+
* and interact with external services. This function preserves TypeScript types while
|
|
9
|
+
* providing a consistent structure for activity definitions.
|
|
10
|
+
*
|
|
11
|
+
* @template TActivity - The activity definition type with input/output schemas
|
|
12
|
+
* @param definition - The activity definition containing input and output schemas
|
|
13
|
+
* @returns The same definition with preserved types for type inference
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { defineActivity } from '@temporal-contract/contract';
|
|
18
|
+
* import { z } from 'zod';
|
|
19
|
+
*
|
|
20
|
+
* export const sendEmail = defineActivity({
|
|
21
|
+
* input: z.object({
|
|
22
|
+
* to: z.string().email(),
|
|
23
|
+
* subject: z.string(),
|
|
24
|
+
* body: z.string(),
|
|
25
|
+
* }),
|
|
26
|
+
* output: z.object({
|
|
27
|
+
* messageId: z.string(),
|
|
28
|
+
* sentAt: z.date(),
|
|
29
|
+
* }),
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
function defineActivity(definition) {
|
|
34
|
+
return definition;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Define a Temporal signal with type-safe input schema.
|
|
38
|
+
*
|
|
39
|
+
* Signals are asynchronous messages sent to running workflows to update their state
|
|
40
|
+
* or trigger certain behaviors. This function ensures type safety for signal payloads.
|
|
41
|
+
*
|
|
42
|
+
* @template TSignal - The signal definition type with input schema
|
|
43
|
+
* @param definition - The signal definition containing input schema
|
|
44
|
+
* @returns The same definition with preserved types for type inference
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import { defineSignal } from '@temporal-contract/contract';
|
|
49
|
+
* import { z } from 'zod';
|
|
50
|
+
*
|
|
51
|
+
* export const approveOrder = defineSignal({
|
|
52
|
+
* input: z.object({
|
|
53
|
+
* orderId: z.string(),
|
|
54
|
+
* approvedBy: z.string(),
|
|
55
|
+
* }),
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
function defineSignal(definition) {
|
|
60
|
+
return definition;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Define a Temporal query with type-safe input and output schemas.
|
|
64
|
+
*
|
|
65
|
+
* Queries allow you to read the current state of a running workflow without
|
|
66
|
+
* modifying it. They are synchronous and should not perform any mutations.
|
|
67
|
+
*
|
|
68
|
+
* @template TQuery - The query definition type with input/output schemas
|
|
69
|
+
* @param definition - The query definition containing input and output schemas
|
|
70
|
+
* @returns The same definition with preserved types for type inference
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* import { defineQuery } from '@temporal-contract/contract';
|
|
75
|
+
* import { z } from 'zod';
|
|
76
|
+
*
|
|
77
|
+
* export const getOrderStatus = defineQuery({
|
|
78
|
+
* input: z.object({ orderId: z.string() }),
|
|
79
|
+
* output: z.object({
|
|
80
|
+
* status: z.enum(['pending', 'processing', 'completed', 'failed']),
|
|
81
|
+
* updatedAt: z.date(),
|
|
82
|
+
* }),
|
|
83
|
+
* });
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
function defineQuery(definition) {
|
|
87
|
+
return definition;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Define a Temporal update with type-safe input and output schemas.
|
|
91
|
+
*
|
|
92
|
+
* Updates are similar to signals but return a value and wait for the workflow
|
|
93
|
+
* to process them before completing. They provide a synchronous way to modify
|
|
94
|
+
* workflow state and get immediate feedback.
|
|
95
|
+
*
|
|
96
|
+
* @template TUpdate - The update definition type with input/output schemas
|
|
97
|
+
* @param definition - The update definition containing input and output schemas
|
|
98
|
+
* @returns The same definition with preserved types for type inference
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* import { defineUpdate } from '@temporal-contract/contract';
|
|
103
|
+
* import { z } from 'zod';
|
|
104
|
+
*
|
|
105
|
+
* export const updateOrderQuantity = defineUpdate({
|
|
106
|
+
* input: z.object({
|
|
107
|
+
* orderId: z.string(),
|
|
108
|
+
* newQuantity: z.number().positive(),
|
|
109
|
+
* }),
|
|
110
|
+
* output: z.object({
|
|
111
|
+
* success: z.boolean(),
|
|
112
|
+
* totalPrice: z.number(),
|
|
113
|
+
* }),
|
|
114
|
+
* });
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
function defineUpdate(definition) {
|
|
118
|
+
return definition;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Define a Temporal workflow with type-safe input, output, and associated operations.
|
|
122
|
+
*
|
|
123
|
+
* Workflows are durable functions that orchestrate activities, handle timeouts,
|
|
124
|
+
* and manage long-running processes. This function provides type safety for the
|
|
125
|
+
* entire workflow definition including activities, signals, queries, and updates.
|
|
126
|
+
*
|
|
127
|
+
* @template TWorkflow - The workflow definition type with all associated schemas
|
|
128
|
+
* @param definition - The workflow definition containing input, output, and operations
|
|
129
|
+
* @returns The same definition with preserved types for type inference
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* import { defineWorkflow, defineActivity, defineSignal } from '@temporal-contract/contract';
|
|
134
|
+
* import { z } from 'zod';
|
|
135
|
+
*
|
|
136
|
+
* export const processOrder = defineWorkflow({
|
|
137
|
+
* input: z.object({ orderId: z.string() }),
|
|
138
|
+
* output: z.object({ success: z.boolean() }),
|
|
139
|
+
* activities: {
|
|
140
|
+
* validatePayment: defineActivity({
|
|
141
|
+
* input: z.object({ orderId: z.string() }),
|
|
142
|
+
* output: z.object({ valid: z.boolean() }),
|
|
143
|
+
* }),
|
|
144
|
+
* },
|
|
145
|
+
* signals: {
|
|
146
|
+
* cancel: defineSignal({
|
|
147
|
+
* input: z.object({ reason: z.string() }),
|
|
148
|
+
* }),
|
|
149
|
+
* },
|
|
150
|
+
* });
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
function defineWorkflow(definition) {
|
|
154
|
+
return definition;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Define a complete Temporal contract with type-safe workflows and activities.
|
|
158
|
+
*
|
|
159
|
+
* A contract is the central definition that ties together your Temporal application's
|
|
160
|
+
* workflows and activities. It provides:
|
|
161
|
+
* - Type safety across client, worker, and workflow code
|
|
162
|
+
* - Automatic validation at runtime
|
|
163
|
+
* - Compile-time verification of implementations
|
|
164
|
+
* - Clear API boundaries and documentation
|
|
165
|
+
*
|
|
166
|
+
* The contract validates the structure and ensures:
|
|
167
|
+
* - Task queue is specified
|
|
168
|
+
* - At least one workflow is defined
|
|
169
|
+
* - Valid JavaScript identifiers are used
|
|
170
|
+
* - No conflicts between global and workflow-specific activities
|
|
171
|
+
* - All schemas implement the Standard Schema specification
|
|
172
|
+
*
|
|
173
|
+
* @template TContract - The contract definition type
|
|
174
|
+
* @param definition - The complete contract definition
|
|
175
|
+
* @returns The same definition with preserved types for type inference
|
|
176
|
+
* @throws {Error} If the contract structure is invalid
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* import { defineContract } from '@temporal-contract/contract';
|
|
181
|
+
* import { z } from 'zod';
|
|
182
|
+
*
|
|
183
|
+
* export const myContract = defineContract({
|
|
184
|
+
* taskQueue: 'orders',
|
|
185
|
+
* workflows: {
|
|
186
|
+
* processOrder: {
|
|
187
|
+
* input: z.object({ orderId: z.string() }),
|
|
188
|
+
* output: z.object({ success: z.boolean() }),
|
|
189
|
+
* activities: {
|
|
190
|
+
* chargePayment: {
|
|
191
|
+
* input: z.object({ amount: z.number() }),
|
|
192
|
+
* output: z.object({ transactionId: z.string() }),
|
|
193
|
+
* },
|
|
194
|
+
* },
|
|
195
|
+
* },
|
|
196
|
+
* },
|
|
197
|
+
* // Optional global activities shared across workflows
|
|
198
|
+
* activities: {
|
|
199
|
+
* logEvent: {
|
|
200
|
+
* input: z.object({ message: z.string() }),
|
|
201
|
+
* output: z.void(),
|
|
202
|
+
* },
|
|
203
|
+
* },
|
|
204
|
+
* });
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
function defineContract(definition) {
|
|
208
|
+
const validationResult = contractValidationSchema.safeParse(definition);
|
|
209
|
+
if (!validationResult.success) {
|
|
210
|
+
const cleanMessage = getCleanErrorMessage(validationResult.error);
|
|
211
|
+
throw new Error(`Contract validation failed: ${cleanMessage}`);
|
|
212
|
+
}
|
|
213
|
+
return definition;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
5
216
|
* Check if a value is a Standard Schema compatible schema
|
|
6
217
|
*/
|
|
7
218
|
function isStandardSchema(value) {
|
|
@@ -18,7 +229,7 @@ const identifierSchema = z.string().min(1).regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, "
|
|
|
18
229
|
/**
|
|
19
230
|
* Extract clean error message from Zod validation error
|
|
20
231
|
*/
|
|
21
|
-
|
|
232
|
+
function getCleanErrorMessage(error) {
|
|
22
233
|
try {
|
|
23
234
|
const parsed = JSON.parse(error.message);
|
|
24
235
|
if (Array.isArray(parsed) && parsed.length > 0) {
|
|
@@ -31,7 +242,7 @@ const getCleanErrorMessage = (error) => {
|
|
|
31
242
|
}
|
|
32
243
|
} catch {}
|
|
33
244
|
return error.message;
|
|
34
|
-
}
|
|
245
|
+
}
|
|
35
246
|
/**
|
|
36
247
|
* Schema for validating activity definitions
|
|
37
248
|
* Checks that input and output are Standard Schema compatible schemas
|
|
@@ -88,106 +299,6 @@ const contractValidationSchema = z.object({
|
|
|
88
299
|
}
|
|
89
300
|
}
|
|
90
301
|
});
|
|
91
|
-
/**
|
|
92
|
-
* Builder for creating activity definitions
|
|
93
|
-
*
|
|
94
|
-
* @example
|
|
95
|
-
* ```ts
|
|
96
|
-
* const myActivity = defineActivity({
|
|
97
|
-
* input: z.tuple([z.object({ name: z.string() })]),
|
|
98
|
-
* output: z.object({ greeting: z.string() }),
|
|
99
|
-
* });
|
|
100
|
-
* ```
|
|
101
|
-
*/
|
|
102
|
-
const defineActivity = (definition) => {
|
|
103
|
-
return definition;
|
|
104
|
-
};
|
|
105
|
-
/**
|
|
106
|
-
* Builder for creating signal definitions
|
|
107
|
-
*
|
|
108
|
-
* @example
|
|
109
|
-
* ```ts
|
|
110
|
-
* const mySignal = defineSignal({
|
|
111
|
-
* input: z.object({ message: z.string() }),
|
|
112
|
-
* });
|
|
113
|
-
* ```
|
|
114
|
-
*/
|
|
115
|
-
const defineSignal = (definition) => {
|
|
116
|
-
return definition;
|
|
117
|
-
};
|
|
118
|
-
/**
|
|
119
|
-
* Builder for creating query definitions
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* ```ts
|
|
123
|
-
* const myQuery = defineQuery({
|
|
124
|
-
* input: z.object({ id: z.string() }),
|
|
125
|
-
* output: z.object({ status: z.string() }),
|
|
126
|
-
* });
|
|
127
|
-
* ```
|
|
128
|
-
*/
|
|
129
|
-
const defineQuery = (definition) => {
|
|
130
|
-
return definition;
|
|
131
|
-
};
|
|
132
|
-
/**
|
|
133
|
-
* Builder for creating update definitions
|
|
134
|
-
*
|
|
135
|
-
* @example
|
|
136
|
-
* ```ts
|
|
137
|
-
* const myUpdate = defineUpdate({
|
|
138
|
-
* input: z.object({ value: z.number() }),
|
|
139
|
-
* output: z.object({ newValue: z.number() }),
|
|
140
|
-
* });
|
|
141
|
-
* ```
|
|
142
|
-
*/
|
|
143
|
-
const defineUpdate = (definition) => {
|
|
144
|
-
return definition;
|
|
145
|
-
};
|
|
146
|
-
/**
|
|
147
|
-
* Builder for creating workflow definitions
|
|
148
|
-
*
|
|
149
|
-
* @example
|
|
150
|
-
* ```ts
|
|
151
|
-
* const myWorkflow = defineWorkflow({
|
|
152
|
-
* input: z.tuple([z.object({ orderId: z.string() })]),
|
|
153
|
-
* output: z.object({ status: z.string() }),
|
|
154
|
-
* activities: {
|
|
155
|
-
* processPayment: defineActivity({
|
|
156
|
-
* input: z.tuple([z.object({ amount: z.number() })]),
|
|
157
|
-
* output: z.object({ success: z.boolean() }),
|
|
158
|
-
* }),
|
|
159
|
-
* },
|
|
160
|
-
* });
|
|
161
|
-
* ```
|
|
162
|
-
*/
|
|
163
|
-
const defineWorkflow = (definition) => {
|
|
164
|
-
return definition;
|
|
165
|
-
};
|
|
166
|
-
/**
|
|
167
|
-
* Builder for creating a complete contract
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```ts
|
|
171
|
-
* const myContract = defineContract({
|
|
172
|
-
* taskQueue: 'my-service',
|
|
173
|
-
* workflows: {
|
|
174
|
-
* processOrder: defineWorkflow({ ... }),
|
|
175
|
-
* sendNotification: defineWorkflow({ ... }),
|
|
176
|
-
* },
|
|
177
|
-
* activities: {
|
|
178
|
-
* sendEmail: defineActivity({ ... }),
|
|
179
|
-
* },
|
|
180
|
-
* });
|
|
181
|
-
* ```
|
|
182
|
-
*/
|
|
183
|
-
const defineContract = (definition) => {
|
|
184
|
-
const validationResult = contractValidationSchema.safeParse(definition);
|
|
185
|
-
if (!validationResult.success) {
|
|
186
|
-
const cleanMessage = getCleanErrorMessage(validationResult.error);
|
|
187
|
-
throw new Error(`Contract error: ${cleanMessage}`);
|
|
188
|
-
}
|
|
189
|
-
return definition;
|
|
190
|
-
};
|
|
191
302
|
|
|
192
303
|
//#endregion
|
|
193
304
|
//#region src/nexus-types.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@temporal-contract/contract",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "Contract builder for temporal-contract",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"contract",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"directory": "packages/contract"
|
|
18
18
|
},
|
|
19
19
|
"license": "MIT",
|
|
20
|
-
"author": "Benoit TRAVERS <benoit.travers.
|
|
20
|
+
"author": "Benoit TRAVERS <benoit.travers.fr@gmail.com>",
|
|
21
21
|
"type": "module",
|
|
22
22
|
"exports": {
|
|
23
23
|
".": {
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@vitest/coverage-v8": "4.0.16",
|
|
47
47
|
"arktype": "2.1.29",
|
|
48
|
-
"tsdown": "0.18.
|
|
48
|
+
"tsdown": "0.18.1",
|
|
49
49
|
"typescript": "5.9.3",
|
|
50
50
|
"valibot": "1.2.0",
|
|
51
51
|
"vitest": "4.0.16",
|
|
52
|
-
"@temporal-contract/tsconfig": "0.0.
|
|
52
|
+
"@temporal-contract/tsconfig": "0.0.7"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"build": "tsdown src/index.ts --format cjs,esm --dts --clean",
|