@temporal-contract/contract 0.0.1

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.
@@ -0,0 +1,351 @@
1
+ import { z } from "zod";
2
+
3
+ //#region src/types.d.ts
4
+
5
+ /**
6
+ * Base types for validation schemas
7
+ * Constrained to avoid implicit any types
8
+ */
9
+ type AnyZodSchema = z.ZodType<unknown, unknown>;
10
+ /**
11
+ * Definition of an activity
12
+ */
13
+ interface ActivityDefinition<TInput extends AnyZodSchema = AnyZodSchema, TOutput extends AnyZodSchema = AnyZodSchema> {
14
+ readonly input: TInput;
15
+ readonly output: TOutput;
16
+ }
17
+ /**
18
+ * Definition of a signal
19
+ */
20
+ interface SignalDefinition<TInput extends AnyZodSchema = AnyZodSchema> {
21
+ readonly input: TInput;
22
+ }
23
+ /**
24
+ * Definition of a query
25
+ */
26
+ interface QueryDefinition<TInput extends AnyZodSchema = AnyZodSchema, TOutput extends AnyZodSchema = AnyZodSchema> {
27
+ readonly input: TInput;
28
+ readonly output: TOutput;
29
+ }
30
+ /**
31
+ * Definition of an update
32
+ */
33
+ interface UpdateDefinition<TInput extends AnyZodSchema = AnyZodSchema, TOutput extends AnyZodSchema = AnyZodSchema> {
34
+ readonly input: TInput;
35
+ readonly output: TOutput;
36
+ }
37
+ /**
38
+ * Definition of a workflow
39
+ */
40
+ interface 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>> {
41
+ readonly input: AnyZodSchema;
42
+ readonly output: AnyZodSchema;
43
+ readonly activities?: TActivities;
44
+ readonly signals?: TSignals;
45
+ readonly queries?: TQueries;
46
+ readonly updates?: TUpdates;
47
+ }
48
+ /**
49
+ * Contract definition containing workflows and optional global activities
50
+ */
51
+ interface ContractDefinition<TWorkflows extends Record<string, WorkflowDefinition> = Record<string, WorkflowDefinition>, TActivities extends Record<string, ActivityDefinition> = Record<string, ActivityDefinition>> {
52
+ readonly taskQueue: string;
53
+ readonly workflows: TWorkflows;
54
+ readonly activities?: TActivities;
55
+ }
56
+ /**
57
+ * Infer input type from a definition (worker perspective)
58
+ * Worker receives z.output (after input schema parsing/transformation)
59
+ */
60
+ type WorkerInferInput<T extends {
61
+ input: AnyZodSchema;
62
+ }> = z.output<T["input"]>;
63
+ /**
64
+ * Infer output type from a definition (worker perspective)
65
+ * Worker returns z.input (before output schema parsing/transformation)
66
+ */
67
+ type WorkerInferOutput<T extends {
68
+ output: AnyZodSchema;
69
+ }> = z.input<T["output"]>;
70
+ /**
71
+ * Infer input type from a definition (client perspective)
72
+ * Client sends z.input (before input schema parsing/transformation)
73
+ */
74
+ type ClientInferInput<T extends {
75
+ input: AnyZodSchema;
76
+ }> = z.input<T["input"]>;
77
+ /**
78
+ * Infer output type from a definition (client perspective)
79
+ * Client receives z.output (after output schema parsing/transformation)
80
+ */
81
+ type ClientInferOutput<T extends {
82
+ output: AnyZodSchema;
83
+ }> = z.output<T["output"]>;
84
+ /**
85
+ * WORKER PERSPECTIVE
86
+ * Worker receives z.output of input (parsed data) and returns z.input of output (raw data)
87
+ */
88
+ /**
89
+ * Infer workflow function signature from worker perspective
90
+ * Worker receives z.input and returns z.output
91
+ */
92
+ type WorkerInferWorkflow<TWorkflow extends WorkflowDefinition> = (args: WorkerInferInput<TWorkflow>) => Promise<WorkerInferOutput<TWorkflow>>;
93
+ /**
94
+ * Infer activity function signature from worker perspective
95
+ * Worker receives z.input and returns z.output
96
+ */
97
+ type WorkerInferActivity<TActivity extends ActivityDefinition> = (args: WorkerInferInput<TActivity>) => Promise<WorkerInferOutput<TActivity>>;
98
+ /**
99
+ * Infer signal handler signature from worker perspective
100
+ * Worker receives z.input
101
+ */
102
+ type WorkerInferSignal<TSignal extends SignalDefinition> = (args: WorkerInferInput<TSignal>) => Promise<void>;
103
+ /**
104
+ * Infer query handler signature from worker perspective
105
+ * Worker receives z.input and returns z.output
106
+ */
107
+ type WorkerInferQuery<TQuery extends QueryDefinition> = (args: WorkerInferInput<TQuery>) => Promise<WorkerInferOutput<TQuery>>;
108
+ /**
109
+ * Infer update handler signature from worker perspective
110
+ * Worker receives z.input and returns z.output
111
+ */
112
+ type WorkerInferUpdate<TUpdate extends UpdateDefinition> = (args: WorkerInferInput<TUpdate>) => Promise<WorkerInferOutput<TUpdate>>;
113
+ /**
114
+ * CLIENT PERSPECTIVE
115
+ * Client sends z.output and receives z.input
116
+ */
117
+ /**
118
+ * Infer workflow function signature from client perspective
119
+ * Client sends z.output and receives z.input
120
+ */
121
+ type ClientInferWorkflow<TWorkflow extends WorkflowDefinition> = (args: ClientInferInput<TWorkflow>) => Promise<ClientInferOutput<TWorkflow>>;
122
+ /**
123
+ * Infer activity function signature from client perspective
124
+ * Client sends z.output and receives z.input
125
+ */
126
+ type ClientInferActivity<TActivity extends ActivityDefinition> = (args: ClientInferInput<TActivity>) => Promise<ClientInferOutput<TActivity>>;
127
+ /**
128
+ * Infer signal handler signature from client perspective
129
+ * Client sends z.output
130
+ */
131
+ type ClientInferSignal<TSignal extends SignalDefinition> = (args: ClientInferInput<TSignal>) => Promise<void>;
132
+ /**
133
+ * Infer query handler signature from client perspective
134
+ * Client sends z.output and receives z.input
135
+ */
136
+ type ClientInferQuery<TQuery extends QueryDefinition> = (args: ClientInferInput<TQuery>) => Promise<ClientInferOutput<TQuery>>;
137
+ /**
138
+ * Infer update handler signature from client perspective
139
+ * Client sends z.output and receives z.input
140
+ */
141
+ type ClientInferUpdate<TUpdate extends UpdateDefinition> = (args: ClientInferInput<TUpdate>) => Promise<ClientInferOutput<TUpdate>>;
142
+ /**
143
+ * WORKER PERSPECTIVE - Contract-level types
144
+ */
145
+ /**
146
+ * Infer all workflows from a contract (worker perspective)
147
+ */
148
+ type WorkerInferWorkflows<TContract extends ContractDefinition> = { [K in keyof TContract["workflows"]]: WorkerInferWorkflow<TContract["workflows"][K]> };
149
+ /**
150
+ * Infer all activities from a contract (worker perspective)
151
+ */
152
+ type WorkerInferActivities<TContract extends ContractDefinition> = TContract["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof TContract["activities"]]: WorkerInferActivity<TContract["activities"][K]> } : {};
153
+ /**
154
+ * Infer activities from a workflow definition (worker perspective)
155
+ */
156
+ type WorkerInferWorkflowActivities<T extends WorkflowDefinition> = T["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof T["activities"]]: WorkerInferActivity<T["activities"][K]> } : {};
157
+ /**
158
+ * Infer signals from a workflow definition (worker perspective)
159
+ */
160
+ type WorkerInferWorkflowSignals<T extends WorkflowDefinition> = T["signals"] extends Record<string, SignalDefinition> ? { [K in keyof T["signals"]]: WorkerInferSignal<T["signals"][K]> } : {};
161
+ /**
162
+ * Infer queries from a workflow definition (worker perspective)
163
+ */
164
+ type WorkerInferWorkflowQueries<T extends WorkflowDefinition> = T["queries"] extends Record<string, QueryDefinition> ? { [K in keyof T["queries"]]: WorkerInferQuery<T["queries"][K]> } : {};
165
+ /**
166
+ * Infer updates from a workflow definition (worker perspective)
167
+ */
168
+ type WorkerInferWorkflowUpdates<T extends WorkflowDefinition> = T["updates"] extends Record<string, UpdateDefinition> ? { [K in keyof T["updates"]]: WorkerInferUpdate<T["updates"][K]> } : {};
169
+ /**
170
+ * Infer all activities available in a workflow context (worker perspective)
171
+ * Combines workflow-specific activities with global activities
172
+ */
173
+ type WorkerInferWorkflowContextActivities<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> = WorkerInferWorkflowActivities<TContract["workflows"][TWorkflowName]> & WorkerInferActivities<TContract>;
174
+ /**
175
+ * CLIENT PERSPECTIVE - Contract-level types
176
+ */
177
+ /**
178
+ * Infer all workflows from a contract (client perspective)
179
+ */
180
+ type ClientInferWorkflows<TContract extends ContractDefinition> = { [K in keyof TContract["workflows"]]: ClientInferWorkflow<TContract["workflows"][K]> };
181
+ /**
182
+ * Infer all activities from a contract (client perspective)
183
+ */
184
+ type ClientInferActivities<TContract extends ContractDefinition> = TContract["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof TContract["activities"]]: ClientInferActivity<TContract["activities"][K]> } : {};
185
+ /**
186
+ * Infer activities from a workflow definition (client perspective)
187
+ */
188
+ type ClientInferWorkflowActivities<T extends WorkflowDefinition> = T["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof T["activities"]]: ClientInferActivity<T["activities"][K]> } : {};
189
+ /**
190
+ * Infer signals from a workflow definition (client perspective)
191
+ */
192
+ type ClientInferWorkflowSignals<T extends WorkflowDefinition> = T["signals"] extends Record<string, SignalDefinition> ? { [K in keyof T["signals"]]: ClientInferSignal<T["signals"][K]> } : {};
193
+ /**
194
+ * Infer queries from a workflow definition (client perspective)
195
+ */
196
+ type ClientInferWorkflowQueries<T extends WorkflowDefinition> = T["queries"] extends Record<string, QueryDefinition> ? { [K in keyof T["queries"]]: ClientInferQuery<T["queries"][K]> } : {};
197
+ /**
198
+ * Infer updates from a workflow definition (client perspective)
199
+ */
200
+ type ClientInferWorkflowUpdates<T extends WorkflowDefinition> = T["updates"] extends Record<string, UpdateDefinition> ? { [K in keyof T["updates"]]: ClientInferUpdate<T["updates"][K]> } : {};
201
+ /**
202
+ * Infer all activities available in a workflow context (client perspective)
203
+ * Combines workflow-specific activities with global activities
204
+ */
205
+ type ClientInferWorkflowContextActivities<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> = ClientInferWorkflowActivities<TContract["workflows"][TWorkflowName]> & ClientInferActivities<TContract>;
206
+ /**
207
+ * UTILITY TYPES FOR ACTIVITY HANDLERS
208
+ */
209
+ /**
210
+ * Extract workflow names from a contract as a union type
211
+ *
212
+ * @example
213
+ * ```typescript
214
+ * type MyWorkflowNames = InferWorkflowNames<typeof myContract>;
215
+ * // "processOrder" | "sendNotification"
216
+ * ```
217
+ */
218
+ type InferWorkflowNames<TContract extends ContractDefinition> = keyof TContract["workflows"] & string;
219
+ /**
220
+ * Extract activity names from a contract (global activities) as a union type
221
+ *
222
+ * @example
223
+ * ```typescript
224
+ * type MyActivityNames = InferActivityNames<typeof myContract>;
225
+ * // "log" | "sendEmail"
226
+ * ```
227
+ */
228
+ type InferActivityNames<TContract extends ContractDefinition> = TContract["activities"] extends Record<string, ActivityDefinition> ? keyof TContract["activities"] & string : never;
229
+ /**
230
+ * Extract all workflows from a contract with their definitions
231
+ *
232
+ * @example
233
+ * ```typescript
234
+ * type MyWorkflows = InferContractWorkflows<typeof myContract>;
235
+ * ```
236
+ */
237
+ type InferContractWorkflows<TContract extends ContractDefinition> = TContract["workflows"];
238
+ /**
239
+ * Infer the handler type for a global activity from a contract
240
+ *
241
+ * @example
242
+ * ```typescript
243
+ * const log: ActivityHandler<typeof myContract, "log"> = async ({ level, message }) => {
244
+ * logger[level](message);
245
+ * };
246
+ * ```
247
+ */
248
+ type ActivityHandler<TContract extends ContractDefinition, TActivityName extends keyof TContract["activities"]> = TContract["activities"] extends Record<string, ActivityDefinition> ? (args: WorkerInferInput<TContract["activities"][TActivityName]>) => Promise<WorkerInferOutput<TContract["activities"][TActivityName]>> : never;
249
+ /**
250
+ * Infer the handler type for a workflow-specific activity from a contract
251
+ *
252
+ * @example
253
+ * ```typescript
254
+ * const processPayment: WorkflowActivityHandler<
255
+ * typeof myContract,
256
+ * "processOrder",
257
+ * "processPayment"
258
+ * > = async ({ customerId, amount }) => {
259
+ * // Implementation
260
+ * return { transactionId, status: "success" as const, paidAmount: amount };
261
+ * };
262
+ * ```
263
+ */
264
+ type WorkflowActivityHandler<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"], TActivityName extends keyof TContract["workflows"][TWorkflowName]["activities"]> = TContract["workflows"][TWorkflowName]["activities"] extends Record<string, ActivityDefinition> ? (args: WorkerInferInput<TContract["workflows"][TWorkflowName]["activities"][TActivityName]>) => Promise<WorkerInferOutput<TContract["workflows"][TWorkflowName]["activities"][TActivityName]>> : never;
265
+ //#endregion
266
+ //#region src/builder.d.ts
267
+ /**
268
+ * Builder for creating activity definitions
269
+ *
270
+ * @example
271
+ * ```ts
272
+ * const myActivity = defineActivity({
273
+ * input: z.tuple([z.object({ name: z.string() })]),
274
+ * output: z.object({ greeting: z.string() }),
275
+ * });
276
+ * ```
277
+ */
278
+ declare const defineActivity: <TActivity extends ActivityDefinition>(definition: TActivity) => TActivity;
279
+ /**
280
+ * Builder for creating signal definitions
281
+ *
282
+ * @example
283
+ * ```ts
284
+ * const mySignal = defineSignal({
285
+ * input: z.object({ message: z.string() }),
286
+ * });
287
+ * ```
288
+ */
289
+ declare const defineSignal: <TSignal extends SignalDefinition>(definition: TSignal) => TSignal;
290
+ /**
291
+ * Builder for creating query definitions
292
+ *
293
+ * @example
294
+ * ```ts
295
+ * const myQuery = defineQuery({
296
+ * input: z.object({ id: z.string() }),
297
+ * output: z.object({ status: z.string() }),
298
+ * });
299
+ * ```
300
+ */
301
+ declare const defineQuery: <TQuery extends QueryDefinition>(definition: TQuery) => TQuery;
302
+ /**
303
+ * Builder for creating update definitions
304
+ *
305
+ * @example
306
+ * ```ts
307
+ * const myUpdate = defineUpdate({
308
+ * input: z.object({ value: z.number() }),
309
+ * output: z.object({ newValue: z.number() }),
310
+ * });
311
+ * ```
312
+ */
313
+ declare const defineUpdate: <TUpdate extends UpdateDefinition>(definition: TUpdate) => TUpdate;
314
+ /**
315
+ * Builder for creating workflow definitions
316
+ *
317
+ * @example
318
+ * ```ts
319
+ * const myWorkflow = defineWorkflow({
320
+ * input: z.tuple([z.object({ orderId: z.string() })]),
321
+ * output: z.object({ status: z.string() }),
322
+ * activities: {
323
+ * processPayment: defineActivity({
324
+ * input: z.tuple([z.object({ amount: z.number() })]),
325
+ * output: z.object({ success: z.boolean() }),
326
+ * }),
327
+ * },
328
+ * });
329
+ * ```
330
+ */
331
+ declare const defineWorkflow: <TWorkflow extends WorkflowDefinition>(definition: TWorkflow) => TWorkflow;
332
+ /**
333
+ * Builder for creating a complete contract
334
+ *
335
+ * @example
336
+ * ```ts
337
+ * const myContract = defineContract({
338
+ * taskQueue: 'my-service',
339
+ * workflows: {
340
+ * processOrder: defineWorkflow({ ... }),
341
+ * sendNotification: defineWorkflow({ ... }),
342
+ * },
343
+ * activities: {
344
+ * sendEmail: defineActivity({ ... }),
345
+ * },
346
+ * });
347
+ * ```
348
+ */
349
+ declare const defineContract: <TContract extends ContractDefinition>(definition: TContract) => TContract;
350
+ //#endregion
351
+ export { type ActivityDefinition, type ActivityHandler, type AnyZodSchema, type ClientInferActivities, type ClientInferActivity, type ClientInferInput, type ClientInferOutput, type ClientInferQuery, type ClientInferSignal, type ClientInferUpdate, type ClientInferWorkflow, type ClientInferWorkflowActivities, type ClientInferWorkflowContextActivities, type ClientInferWorkflowQueries, type ClientInferWorkflowSignals, type ClientInferWorkflowUpdates, type ClientInferWorkflows, type ContractDefinition, type InferActivityNames, type InferContractWorkflows, type InferWorkflowNames, type QueryDefinition, type SignalDefinition, type UpdateDefinition, type WorkerInferActivities, type WorkerInferActivity, type WorkerInferInput, type WorkerInferOutput, type WorkerInferQuery, type WorkerInferSignal, type WorkerInferUpdate, type WorkerInferWorkflow, type WorkerInferWorkflowActivities, type WorkerInferWorkflowContextActivities, type WorkerInferWorkflowQueries, type WorkerInferWorkflowSignals, type WorkerInferWorkflowUpdates, type WorkerInferWorkflows, type WorkflowActivityHandler, type WorkflowDefinition, defineActivity, defineContract, defineQuery, defineSignal, defineUpdate, defineWorkflow };
package/dist/index.mjs ADDED
@@ -0,0 +1,185 @@
1
+ import { z } from "zod";
2
+
3
+ //#region src/builder.ts
4
+ /**
5
+ * Schema for validating JavaScript identifiers (workflow names, activity names, etc.)
6
+ * Allows: letters, digits, underscore, dollar sign
7
+ * Must start with: letter, underscore, or dollar sign
8
+ */
9
+ const identifierSchema = z.string().min(1).regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, "must be a valid JavaScript identifier");
10
+ /**
11
+ * Extract clean error message from Zod validation error
12
+ */
13
+ const getCleanErrorMessage = (error) => {
14
+ try {
15
+ const parsed = JSON.parse(error.message);
16
+ if (Array.isArray(parsed) && parsed.length > 0) {
17
+ const firstError = parsed[0];
18
+ if (firstError?.code === "invalid_key" && firstError?.issues && firstError.issues.length > 0) {
19
+ const nestedError = firstError.issues[0];
20
+ if (nestedError?.message) return nestedError.message;
21
+ }
22
+ if (firstError?.message) return firstError.message;
23
+ }
24
+ } catch {}
25
+ return error.message;
26
+ };
27
+ /**
28
+ * Schema for validating activity definitions
29
+ * Checks that input and output are Zod schemas
30
+ */
31
+ const activityDefinitionSchema = z.object({
32
+ input: z.instanceof(z.ZodType, { message: "input must be a Zod schema" }),
33
+ output: z.instanceof(z.ZodType, { message: "output must be a Zod schema" })
34
+ });
35
+ /**
36
+ * Schema for validating signal definitions
37
+ */
38
+ const signalDefinitionSchema = z.object({ input: z.instanceof(z.ZodType, { message: "input must be a Zod schema" }) });
39
+ /**
40
+ * Schema for validating query definitions
41
+ */
42
+ const queryDefinitionSchema = z.object({
43
+ input: z.instanceof(z.ZodType, { message: "input must be a Zod schema" }),
44
+ output: z.instanceof(z.ZodType, { message: "output must be a Zod schema" })
45
+ });
46
+ /**
47
+ * Schema for validating update definitions
48
+ */
49
+ const updateDefinitionSchema = z.object({
50
+ input: z.instanceof(z.ZodType, { message: "input must be a Zod schema" }),
51
+ output: z.instanceof(z.ZodType, { message: "output must be a Zod schema" })
52
+ });
53
+ /**
54
+ * Schema for validating workflow definitions
55
+ */
56
+ const workflowDefinitionSchema = z.object({
57
+ input: z.instanceof(z.ZodType, { message: "input must be a Zod schema" }),
58
+ output: z.instanceof(z.ZodType, { message: "output must be a Zod schema" }),
59
+ activities: z.record(identifierSchema, activityDefinitionSchema).optional(),
60
+ signals: z.record(identifierSchema, signalDefinitionSchema).optional(),
61
+ queries: z.record(identifierSchema, queryDefinitionSchema).optional(),
62
+ updates: z.record(identifierSchema, updateDefinitionSchema).optional()
63
+ });
64
+ /**
65
+ * Schema for validating a contract definition structure
66
+ */
67
+ const contractValidationSchema = z.object({
68
+ taskQueue: z.string().trim().min(1, "taskQueue cannot be empty"),
69
+ workflows: z.record(identifierSchema, workflowDefinitionSchema).refine((workflows) => Object.keys(workflows).length > 0, { message: "at least one workflow is required" }),
70
+ activities: z.record(identifierSchema, activityDefinitionSchema).optional()
71
+ }).superRefine((contract, ctx) => {
72
+ if (!contract.activities) return;
73
+ for (const [workflowName, workflow] of Object.entries(contract.workflows)) if (workflow.activities) {
74
+ for (const activityName of Object.keys(workflow.activities)) if (activityName in contract.activities) {
75
+ ctx.addIssue({
76
+ code: z.ZodIssueCode.custom,
77
+ message: `workflow "${workflowName}" has activity "${activityName}" that conflicts with a global activity. Consider renaming the workflow-specific activity or removing the global activity "${activityName}".`
78
+ });
79
+ return;
80
+ }
81
+ }
82
+ });
83
+ /**
84
+ * Builder for creating activity definitions
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * const myActivity = defineActivity({
89
+ * input: z.tuple([z.object({ name: z.string() })]),
90
+ * output: z.object({ greeting: z.string() }),
91
+ * });
92
+ * ```
93
+ */
94
+ const defineActivity = (definition) => {
95
+ return definition;
96
+ };
97
+ /**
98
+ * Builder for creating signal definitions
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * const mySignal = defineSignal({
103
+ * input: z.object({ message: z.string() }),
104
+ * });
105
+ * ```
106
+ */
107
+ const defineSignal = (definition) => {
108
+ return definition;
109
+ };
110
+ /**
111
+ * Builder for creating query definitions
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * const myQuery = defineQuery({
116
+ * input: z.object({ id: z.string() }),
117
+ * output: z.object({ status: z.string() }),
118
+ * });
119
+ * ```
120
+ */
121
+ const defineQuery = (definition) => {
122
+ return definition;
123
+ };
124
+ /**
125
+ * Builder for creating update definitions
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * const myUpdate = defineUpdate({
130
+ * input: z.object({ value: z.number() }),
131
+ * output: z.object({ newValue: z.number() }),
132
+ * });
133
+ * ```
134
+ */
135
+ const defineUpdate = (definition) => {
136
+ return definition;
137
+ };
138
+ /**
139
+ * Builder for creating workflow definitions
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const myWorkflow = defineWorkflow({
144
+ * input: z.tuple([z.object({ orderId: z.string() })]),
145
+ * output: z.object({ status: z.string() }),
146
+ * activities: {
147
+ * processPayment: defineActivity({
148
+ * input: z.tuple([z.object({ amount: z.number() })]),
149
+ * output: z.object({ success: z.boolean() }),
150
+ * }),
151
+ * },
152
+ * });
153
+ * ```
154
+ */
155
+ const defineWorkflow = (definition) => {
156
+ return definition;
157
+ };
158
+ /**
159
+ * Builder for creating a complete contract
160
+ *
161
+ * @example
162
+ * ```ts
163
+ * const myContract = defineContract({
164
+ * taskQueue: 'my-service',
165
+ * workflows: {
166
+ * processOrder: defineWorkflow({ ... }),
167
+ * sendNotification: defineWorkflow({ ... }),
168
+ * },
169
+ * activities: {
170
+ * sendEmail: defineActivity({ ... }),
171
+ * },
172
+ * });
173
+ * ```
174
+ */
175
+ const defineContract = (definition) => {
176
+ const validationResult = contractValidationSchema.safeParse(definition);
177
+ if (!validationResult.success) {
178
+ const cleanMessage = getCleanErrorMessage(validationResult.error);
179
+ throw new Error(`Contract error: ${cleanMessage}`);
180
+ }
181
+ return definition;
182
+ };
183
+
184
+ //#endregion
185
+ export { defineActivity, defineContract, defineQuery, defineSignal, defineUpdate, defineWorkflow };
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@temporal-contract/contract",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "description": "Contract builder for temporal-contract",
6
+ "homepage": "https://github.com/btravers/temporal-contract#readme",
7
+ "bugs": {
8
+ "url": "https://github.com/btravers/temporal-contract/issues"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/btravers/temporal-contract.git",
13
+ "directory": "packages/contract"
14
+ },
15
+ "author": "Benoit TRAVERS <benoit.travers.frgmail.com>",
16
+ "license": "MIT",
17
+ "keywords": [
18
+ "temporal",
19
+ "typescript",
20
+ "contract"
21
+ ],
22
+ "main": "./dist/index.cjs",
23
+ "module": "./dist/index.mjs",
24
+ "types": "./dist/index.d.mts",
25
+ "exports": {
26
+ ".": {
27
+ "import": {
28
+ "types": "./dist/index.d.mts",
29
+ "default": "./dist/index.mjs"
30
+ },
31
+ "require": {
32
+ "types": "./dist/index.d.cts",
33
+ "default": "./dist/index.cjs"
34
+ }
35
+ },
36
+ "./package.json": "./package.json"
37
+ },
38
+ "devDependencies": {
39
+ "tsdown": "0.17.2",
40
+ "typescript": "5.9.3",
41
+ "vitest": "4.0.15",
42
+ "zod": "4.1.13",
43
+ "@temporal-contract/tsconfig": "0.0.1"
44
+ },
45
+ "peerDependencies": {
46
+ "zod": "^4.0.0"
47
+ },
48
+ "scripts": {
49
+ "dev": "tsdown src/index.ts --format cjs,esm --dts --watch",
50
+ "build": "tsdown src/index.ts --format cjs,esm --dts --clean",
51
+ "typecheck": "tsc --noEmit",
52
+ "test": "vitest run",
53
+ "test:watch": "vitest"
54
+ }
55
+ }