@temporal-contract/client 0.0.1 → 0.0.2

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.
@@ -1,17 +1,17 @@
1
1
 
2
- > @temporal-contract/client@0.0.1 build /home/runner/work/temporal-contract/temporal-contract/packages/client
2
+ > @temporal-contract/client@0.0.2 build /home/runner/work/temporal-contract/temporal-contract/packages/client
3
3
  > tsdown src/index.ts --format cjs,esm --dts --clean
4
4
 
5
5
  ℹ tsdown v0.17.2 powered by rolldown v1.0.0-beta.53
6
6
  ℹ entry: src/index.ts
7
7
  ℹ tsconfig: tsconfig.json
8
8
  ℹ Build start
9
- ℹ [CJS] dist/index.cjs 8.38 kB │ gzip: 1.77 kB
10
- ℹ [CJS] 1 files, total: 8.38 kB
11
- ℹ [ESM] dist/index.mjs 8.12 kB │ gzip: 1.74 kB
12
- ℹ [ESM] dist/index.d.mts 6.70 kB │ gzip: 1.62 kB
13
- ℹ [ESM] 2 files, total: 14.81 kB
14
- ✔ Build complete in 3603ms
15
- ℹ [CJS] dist/index.d.cts 6.70 kB │ gzip: 1.62 kB
16
- ℹ [CJS] 1 files, total: 6.70 kB
17
- ✔ Build complete in 3605ms
9
+ ℹ [CJS] dist/index.cjs 8.83 kB │ gzip: 1.84 kB
10
+ ℹ [CJS] 1 files, total: 8.83 kB
11
+ ℹ [CJS] dist/index.d.cts 7.02 kB │ gzip: 1.67 kB
12
+ ℹ [CJS] 1 files, total: 7.02 kB
13
+ ✔ Build complete in 4263ms
14
+ ℹ [ESM] dist/index.mjs 8.60 kB │ gzip: 1.81 kB
15
+ ℹ [ESM] dist/index.d.mts 7.02 kB │ gzip: 1.67 kB
16
+ ℹ [ESM] 2 files, total: 15.62 kB
17
+ ✔ Build complete in 4270ms
package/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # @temporal-contract/client
2
+
3
+ ## 0.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Release version 0.0.2
8
+ - Updated dependencies
9
+ - @temporal-contract/contract@0.0.2
package/README.md CHANGED
@@ -2,96 +2,37 @@
2
2
 
3
3
  > Type-safe client for consuming Temporal workflows
4
4
 
5
+ [![npm version](https://img.shields.io/npm/v/@temporal-contract/client.svg?logo=npm)](https://www.npmjs.com/package/@temporal-contract/client)
6
+
5
7
  ## Installation
6
8
 
7
9
  ```bash
8
10
  pnpm add @temporal-contract/client @temporal-contract/contract @temporalio/client zod
9
11
  ```
10
12
 
11
- ## Quick Start
13
+ ## Quick Example
12
14
 
13
15
  ```typescript
14
- import { Connection } from '@temporalio/client';
15
16
  import { TypedClient } from '@temporal-contract/client';
16
- import { myContract } from './contract';
17
+ import { Connection } from '@temporalio/client';
17
18
 
18
- // Connect to Temporal
19
19
  const connection = await Connection.connect({ address: 'localhost:7233' });
20
-
21
- // Create typed client
22
- const client = TypedClient.create(myContract, {
23
- connection,
24
- namespace: 'default',
25
- });
20
+ const client = TypedClient.create(myContract, { connection });
26
21
 
27
22
  // Execute workflow (fully typed!)
28
23
  const result = await client.executeWorkflow('processOrder', {
29
24
  workflowId: 'order-123',
30
- args: { orderId: 'ORD-123', customerId: 'CUST-456' },
25
+ args: { orderId: 'ORD-123' }
31
26
  });
32
-
33
- console.log(result.status); // 'success' | 'failed' — typed!
34
- ```
35
-
36
- ## API
37
-
38
- ### `TypedClient.create(contract, options)`
39
-
40
- Creates a type-safe Temporal client.
41
-
42
- **Returns:** Type-safe client with these methods:
43
-
44
- #### `executeWorkflow(name, options)`
45
-
46
- Execute and wait for result:
47
-
48
- ```typescript
49
- const result = await client.executeWorkflow('processOrder', {
50
- workflowId: 'order-123',
51
- args: { orderId: 'ORD-123', customerId: 'CUST-456' },
52
- });
53
- ```
54
-
55
- #### `startWorkflow(name, options)` / `getHandle(name, workflowId)`
56
-
57
- Get a typed workflow handle for signals/queries/updates:
58
-
59
- ```typescript
60
- const handle = await client.startWorkflow('processOrder', {
61
- workflowId: 'order-456',
62
- args: { orderId: 'ORD-456' },
63
- });
64
-
65
- // Type-safe queries, signals, updates
66
- await handle.queries.getStatus();
67
- await handle.signals.cancel({ reason: 'Customer request' });
68
- await handle.updates.changeAmount({ newAmount: 150 });
69
- ```
70
-
71
- ## Error Handling
72
-
73
- Custom error classes with contextual information:
74
-
75
- ```typescript
76
- import { WorkflowValidationError, WorkflowNotFoundError } from '@temporal-contract/client';
77
-
78
- try {
79
- await client.executeWorkflow('processOrder', { args: invalidData });
80
- } catch (error) {
81
- if (error instanceof WorkflowValidationError) {
82
- console.error('Validation:', error.zodError.errors);
83
- } else if (error instanceof WorkflowNotFoundError) {
84
- console.error('Available:', error.availableWorkflows);
85
- }
86
- }
87
27
  ```
88
28
 
89
- ---
29
+ ## Documentation
90
30
 
91
- ## Learn More
31
+ 📖 **[Read the full documentation →](https://btravers.github.io/temporal-contract)**
92
32
 
93
- - [Main README](../../README.md) — Quick start guide
94
- - [Worker Implementation](../../docs/CONTRACT_HANDLER.md) — Implementing workers
33
+ - [API Reference](https://btravers.github.io/temporal-contract/api/client)
34
+ - [Getting Started](https://btravers.github.io/temporal-contract/guide/getting-started)
35
+ - [Examples](https://btravers.github.io/temporal-contract/examples/)
95
36
 
96
37
  ## License
97
38
 
package/dist/index.cjs CHANGED
@@ -1,5 +1,4 @@
1
1
  let __temporalio_client = require("@temporalio/client");
2
- let zod = require("zod");
3
2
 
4
3
  //#region src/errors.ts
5
4
  /**
@@ -16,9 +15,11 @@ var TypedClientError = class extends Error {
16
15
  * Error thrown when a workflow is not found in the contract
17
16
  */
18
17
  var WorkflowNotFoundError = class extends TypedClientError {
19
- constructor(workflowName) {
20
- super(`Workflow "${workflowName}" not found in contract`);
18
+ constructor(workflowName, availableWorkflows = []) {
19
+ const message = availableWorkflows.length > 0 ? `Workflow "${workflowName}" not found in contract. Available workflows: ${availableWorkflows.join(", ")}` : `Workflow "${workflowName}" not found in contract`;
20
+ super(message);
21
21
  this.workflowName = workflowName;
22
+ this.availableWorkflows = availableWorkflows;
22
23
  this.name = "WorkflowNotFoundError";
23
24
  }
24
25
  };
@@ -26,11 +27,12 @@ var WorkflowNotFoundError = class extends TypedClientError {
26
27
  * Error thrown when workflow input or output validation fails
27
28
  */
28
29
  var WorkflowValidationError = class extends TypedClientError {
29
- constructor(workflowName, phase, zodError) {
30
- super(`Validation failed for workflow "${workflowName}" ${phase}: ${zodError.message}`);
30
+ constructor(workflowName, phase, issues) {
31
+ const message = issues.map((issue) => issue.message).join("; ");
32
+ super(`Validation failed for workflow "${workflowName}" ${phase}: ${message}`);
31
33
  this.workflowName = workflowName;
32
34
  this.phase = phase;
33
- this.zodError = zodError;
35
+ this.issues = issues;
34
36
  this.name = "WorkflowValidationError";
35
37
  }
36
38
  };
@@ -38,11 +40,12 @@ var WorkflowValidationError = class extends TypedClientError {
38
40
  * Error thrown when query input or output validation fails
39
41
  */
40
42
  var QueryValidationError = class extends TypedClientError {
41
- constructor(queryName, phase, zodError) {
42
- super(`Validation failed for query "${queryName}" ${phase}: ${zodError.message}`);
43
+ constructor(queryName, phase, issues) {
44
+ const message = issues.map((issue) => issue.message).join("; ");
45
+ super(`Validation failed for query "${queryName}" ${phase}: ${message}`);
43
46
  this.queryName = queryName;
44
47
  this.phase = phase;
45
- this.zodError = zodError;
48
+ this.issues = issues;
46
49
  this.name = "QueryValidationError";
47
50
  }
48
51
  };
@@ -50,10 +53,11 @@ var QueryValidationError = class extends TypedClientError {
50
53
  * Error thrown when signal input validation fails
51
54
  */
52
55
  var SignalValidationError = class extends TypedClientError {
53
- constructor(signalName, zodError) {
54
- super(`Validation failed for signal "${signalName}" input: ${zodError.message}`);
56
+ constructor(signalName, issues) {
57
+ const message = issues.map((issue) => issue.message).join("; ");
58
+ super(`Validation failed for signal "${signalName}" input: ${message}`);
55
59
  this.signalName = signalName;
56
- this.zodError = zodError;
60
+ this.issues = issues;
57
61
  this.name = "SignalValidationError";
58
62
  }
59
63
  };
@@ -61,11 +65,12 @@ var SignalValidationError = class extends TypedClientError {
61
65
  * Error thrown when update input or output validation fails
62
66
  */
63
67
  var UpdateValidationError = class extends TypedClientError {
64
- constructor(updateName, phase, zodError) {
65
- super(`Validation failed for update "${updateName}" ${phase}: ${zodError.message}`);
68
+ constructor(updateName, phase, issues) {
69
+ const message = issues.map((issue) => issue.message).join("; ");
70
+ super(`Validation failed for update "${updateName}" ${phase}: ${message}`);
66
71
  this.updateName = updateName;
67
72
  this.phase = phase;
68
- this.zodError = zodError;
73
+ this.issues = issues;
69
74
  this.name = "UpdateValidationError";
70
75
  }
71
76
  };
@@ -120,14 +125,10 @@ var TypedClient = class TypedClient {
120
125
  */
121
126
  async startWorkflow(workflowName, { args, ...temporalOptions }) {
122
127
  const definition = this.contract.workflows[workflowName];
123
- if (!definition) throw new WorkflowNotFoundError(String(workflowName));
124
- let validatedInput;
125
- try {
126
- validatedInput = definition.input.parse(args);
127
- } catch (error) {
128
- if (error instanceof zod.ZodError) throw new WorkflowValidationError(String(workflowName), "input", error);
129
- throw error;
130
- }
128
+ if (!definition) throw new WorkflowNotFoundError(String(workflowName), Object.keys(this.contract.workflows));
129
+ const inputResult = await definition.input["~standard"].validate(args);
130
+ if (inputResult.issues) throw new WorkflowValidationError(String(workflowName), "input", inputResult.issues);
131
+ const validatedInput = inputResult.value;
131
132
  const handle = await this.client.workflow.start(workflowName, {
132
133
  ...temporalOptions,
133
134
  taskQueue: this.contract.taskQueue,
@@ -152,25 +153,18 @@ var TypedClient = class TypedClient {
152
153
  */
153
154
  async executeWorkflow(workflowName, { args, ...temporalOptions }) {
154
155
  const definition = this.contract.workflows[workflowName];
155
- if (!definition) throw new WorkflowNotFoundError(String(workflowName));
156
- let validatedInput;
157
- try {
158
- validatedInput = definition.input.parse(args);
159
- } catch (error) {
160
- if (error instanceof zod.ZodError) throw new WorkflowValidationError(String(workflowName), "input", error);
161
- throw error;
162
- }
156
+ if (!definition) throw new WorkflowNotFoundError(String(workflowName), Object.keys(this.contract.workflows));
157
+ const inputResult = await definition.input["~standard"].validate(args);
158
+ if (inputResult.issues) throw new WorkflowValidationError(String(workflowName), "input", inputResult.issues);
159
+ const validatedInput = inputResult.value;
163
160
  const result = await this.client.workflow.execute(workflowName, {
164
161
  ...temporalOptions,
165
162
  taskQueue: this.contract.taskQueue,
166
163
  args: [validatedInput]
167
164
  });
168
- try {
169
- return definition.output.parse(result);
170
- } catch (error) {
171
- if (error instanceof zod.ZodError) throw new WorkflowValidationError(String(workflowName), "output", error);
172
- throw error;
173
- }
165
+ const outputResult = await definition.output["~standard"].validate(result);
166
+ if (outputResult.issues) throw new WorkflowValidationError(String(workflowName), "output", outputResult.issues);
167
+ return outputResult.value;
174
168
  }
175
169
  /**
176
170
  * Get a handle to an existing workflow
@@ -183,55 +177,34 @@ var TypedClient = class TypedClient {
183
177
  */
184
178
  async getHandle(workflowName, workflowId) {
185
179
  const definition = this.contract.workflows[workflowName];
186
- if (!definition) throw new WorkflowNotFoundError(String(workflowName));
180
+ if (!definition) throw new WorkflowNotFoundError(String(workflowName), Object.keys(this.contract.workflows));
187
181
  const handle = this.client.workflow.getHandle(workflowId);
188
182
  return this.createTypedHandle(handle, definition);
189
183
  }
190
184
  createTypedHandle(handle, definition) {
191
185
  const queries = {};
192
186
  for (const [queryName, queryDef] of Object.entries(definition.queries ?? {})) queries[queryName] = async (args) => {
193
- let validatedInput;
194
- try {
195
- validatedInput = queryDef.input.parse(args);
196
- } catch (error) {
197
- if (error instanceof zod.ZodError) throw new QueryValidationError(queryName, "input", error);
198
- throw error;
199
- }
200
- const result = await handle.query(queryName, validatedInput);
201
- try {
202
- return queryDef.output.parse(result);
203
- } catch (error) {
204
- if (error instanceof zod.ZodError) throw new QueryValidationError(queryName, "output", error);
205
- throw error;
206
- }
187
+ const inputResult = await queryDef.input["~standard"].validate(args);
188
+ if (inputResult.issues) throw new QueryValidationError(queryName, "input", inputResult.issues);
189
+ const result = await handle.query(queryName, inputResult.value);
190
+ const outputResult = await queryDef.output["~standard"].validate(result);
191
+ if (outputResult.issues) throw new QueryValidationError(queryName, "output", outputResult.issues);
192
+ return outputResult.value;
207
193
  };
208
194
  const signals = {};
209
195
  for (const [signalName, signalDef] of Object.entries(definition.signals ?? {})) signals[signalName] = async (args) => {
210
- let validatedInput;
211
- try {
212
- validatedInput = signalDef.input.parse(args);
213
- } catch (error) {
214
- if (error instanceof zod.ZodError) throw new SignalValidationError(signalName, error);
215
- throw error;
216
- }
217
- await handle.signal(signalName, validatedInput);
196
+ const inputResult = await signalDef.input["~standard"].validate(args);
197
+ if (inputResult.issues) throw new SignalValidationError(signalName, inputResult.issues);
198
+ await handle.signal(signalName, inputResult.value);
218
199
  };
219
200
  const updates = {};
220
201
  for (const [updateName, updateDef] of Object.entries(definition.updates ?? {})) updates[updateName] = async (args) => {
221
- let validatedInput;
222
- try {
223
- validatedInput = updateDef.input.parse(args);
224
- } catch (error) {
225
- if (error instanceof zod.ZodError) throw new UpdateValidationError(updateName, "input", error);
226
- throw error;
227
- }
228
- const result = await handle.executeUpdate(updateName, { args: [validatedInput] });
229
- try {
230
- return updateDef.output.parse(result);
231
- } catch (error) {
232
- if (error instanceof zod.ZodError) throw new UpdateValidationError(updateName, "output", error);
233
- throw error;
234
- }
202
+ const inputResult = await updateDef.input["~standard"].validate(args);
203
+ if (inputResult.issues) throw new UpdateValidationError(updateName, "input", inputResult.issues);
204
+ const result = await handle.executeUpdate(updateName, { args: [inputResult.value] });
205
+ const outputResult = await updateDef.output["~standard"].validate(result);
206
+ if (outputResult.issues) throw new UpdateValidationError(updateName, "output", outputResult.issues);
207
+ return outputResult.value;
235
208
  };
236
209
  return {
237
210
  workflowId: handle.workflowId,
@@ -240,12 +213,9 @@ var TypedClient = class TypedClient {
240
213
  updates,
241
214
  result: async () => {
242
215
  const result = await handle.result();
243
- try {
244
- return definition.output.parse(result);
245
- } catch (error) {
246
- if (error instanceof zod.ZodError) throw new WorkflowValidationError(handle.workflowId, "output", error);
247
- throw error;
248
- }
216
+ const outputResult = await definition.output["~standard"].validate(result);
217
+ if (outputResult.issues) throw new WorkflowValidationError(handle.workflowId, "output", outputResult.issues);
218
+ return outputResult.value;
249
219
  },
250
220
  terminate: async (reason) => {
251
221
  await handle.terminate(reason);
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ClientOptions, WorkflowHandle, WorkflowOptions, WorkflowStartOptions } from "@temporalio/client";
2
2
  import { ClientInferInput, ClientInferOutput, ClientInferWorkflowQueries, ClientInferWorkflowSignals, ClientInferWorkflowUpdates, ContractDefinition, WorkflowDefinition } from "@temporal-contract/contract";
3
- import { z } from "zod";
3
+ import { StandardSchemaV1 } from "@standard-schema/spec";
4
4
 
5
5
  //#region src/client.d.ts
6
6
 
@@ -149,7 +149,8 @@ declare class TypedClientError extends Error {
149
149
  */
150
150
  declare class WorkflowNotFoundError extends TypedClientError {
151
151
  readonly workflowName: string;
152
- constructor(workflowName: string);
152
+ readonly availableWorkflows: readonly string[];
153
+ constructor(workflowName: string, availableWorkflows?: readonly string[]);
153
154
  }
154
155
  /**
155
156
  * Error thrown when workflow input or output validation fails
@@ -157,8 +158,8 @@ declare class WorkflowNotFoundError extends TypedClientError {
157
158
  declare class WorkflowValidationError extends TypedClientError {
158
159
  readonly workflowName: string;
159
160
  readonly phase: "input" | "output";
160
- readonly zodError: z.ZodError;
161
- constructor(workflowName: string, phase: "input" | "output", zodError: z.ZodError);
161
+ readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
162
+ constructor(workflowName: string, phase: "input" | "output", issues: ReadonlyArray<StandardSchemaV1.Issue>);
162
163
  }
163
164
  /**
164
165
  * Error thrown when query input or output validation fails
@@ -166,16 +167,16 @@ declare class WorkflowValidationError extends TypedClientError {
166
167
  declare class QueryValidationError extends TypedClientError {
167
168
  readonly queryName: string;
168
169
  readonly phase: "input" | "output";
169
- readonly zodError: z.ZodError;
170
- constructor(queryName: string, phase: "input" | "output", zodError: z.ZodError);
170
+ readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
171
+ constructor(queryName: string, phase: "input" | "output", issues: ReadonlyArray<StandardSchemaV1.Issue>);
171
172
  }
172
173
  /**
173
174
  * Error thrown when signal input validation fails
174
175
  */
175
176
  declare class SignalValidationError extends TypedClientError {
176
177
  readonly signalName: string;
177
- readonly zodError: z.ZodError;
178
- constructor(signalName: string, zodError: z.ZodError);
178
+ readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
179
+ constructor(signalName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
179
180
  }
180
181
  /**
181
182
  * Error thrown when update input or output validation fails
@@ -183,8 +184,8 @@ declare class SignalValidationError extends TypedClientError {
183
184
  declare class UpdateValidationError extends TypedClientError {
184
185
  readonly updateName: string;
185
186
  readonly phase: "input" | "output";
186
- readonly zodError: z.ZodError;
187
- constructor(updateName: string, phase: "input" | "output", zodError: z.ZodError);
187
+ readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
188
+ constructor(updateName: string, phase: "input" | "output", issues: ReadonlyArray<StandardSchemaV1.Issue>);
188
189
  }
189
190
  //#endregion
190
191
  export { QueryValidationError, SignalValidationError, TypedClient, TypedClientError, type TypedWorkflowHandle, type TypedWorkflowStartOptions, UpdateValidationError, WorkflowNotFoundError, WorkflowValidationError };
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ClientOptions, WorkflowHandle, WorkflowOptions, WorkflowStartOptions } from "@temporalio/client";
2
- import { z } from "zod";
3
2
  import { ClientInferInput, ClientInferOutput, ClientInferWorkflowQueries, ClientInferWorkflowSignals, ClientInferWorkflowUpdates, ContractDefinition, WorkflowDefinition } from "@temporal-contract/contract";
3
+ import { StandardSchemaV1 } from "@standard-schema/spec";
4
4
 
5
5
  //#region src/client.d.ts
6
6
 
@@ -149,7 +149,8 @@ declare class TypedClientError extends Error {
149
149
  */
150
150
  declare class WorkflowNotFoundError extends TypedClientError {
151
151
  readonly workflowName: string;
152
- constructor(workflowName: string);
152
+ readonly availableWorkflows: readonly string[];
153
+ constructor(workflowName: string, availableWorkflows?: readonly string[]);
153
154
  }
154
155
  /**
155
156
  * Error thrown when workflow input or output validation fails
@@ -157,8 +158,8 @@ declare class WorkflowNotFoundError extends TypedClientError {
157
158
  declare class WorkflowValidationError extends TypedClientError {
158
159
  readonly workflowName: string;
159
160
  readonly phase: "input" | "output";
160
- readonly zodError: z.ZodError;
161
- constructor(workflowName: string, phase: "input" | "output", zodError: z.ZodError);
161
+ readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
162
+ constructor(workflowName: string, phase: "input" | "output", issues: ReadonlyArray<StandardSchemaV1.Issue>);
162
163
  }
163
164
  /**
164
165
  * Error thrown when query input or output validation fails
@@ -166,16 +167,16 @@ declare class WorkflowValidationError extends TypedClientError {
166
167
  declare class QueryValidationError extends TypedClientError {
167
168
  readonly queryName: string;
168
169
  readonly phase: "input" | "output";
169
- readonly zodError: z.ZodError;
170
- constructor(queryName: string, phase: "input" | "output", zodError: z.ZodError);
170
+ readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
171
+ constructor(queryName: string, phase: "input" | "output", issues: ReadonlyArray<StandardSchemaV1.Issue>);
171
172
  }
172
173
  /**
173
174
  * Error thrown when signal input validation fails
174
175
  */
175
176
  declare class SignalValidationError extends TypedClientError {
176
177
  readonly signalName: string;
177
- readonly zodError: z.ZodError;
178
- constructor(signalName: string, zodError: z.ZodError);
178
+ readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
179
+ constructor(signalName: string, issues: ReadonlyArray<StandardSchemaV1.Issue>);
179
180
  }
180
181
  /**
181
182
  * Error thrown when update input or output validation fails
@@ -183,8 +184,8 @@ declare class SignalValidationError extends TypedClientError {
183
184
  declare class UpdateValidationError extends TypedClientError {
184
185
  readonly updateName: string;
185
186
  readonly phase: "input" | "output";
186
- readonly zodError: z.ZodError;
187
- constructor(updateName: string, phase: "input" | "output", zodError: z.ZodError);
187
+ readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
188
+ constructor(updateName: string, phase: "input" | "output", issues: ReadonlyArray<StandardSchemaV1.Issue>);
188
189
  }
189
190
  //#endregion
190
191
  export { QueryValidationError, SignalValidationError, TypedClient, TypedClientError, type TypedWorkflowHandle, type TypedWorkflowStartOptions, UpdateValidationError, WorkflowNotFoundError, WorkflowValidationError };
package/dist/index.mjs CHANGED
@@ -1,5 +1,4 @@
1
1
  import { Client } from "@temporalio/client";
2
- import { ZodError } from "zod";
3
2
 
4
3
  //#region src/errors.ts
5
4
  /**
@@ -16,9 +15,11 @@ var TypedClientError = class extends Error {
16
15
  * Error thrown when a workflow is not found in the contract
17
16
  */
18
17
  var WorkflowNotFoundError = class extends TypedClientError {
19
- constructor(workflowName) {
20
- super(`Workflow "${workflowName}" not found in contract`);
18
+ constructor(workflowName, availableWorkflows = []) {
19
+ const message = availableWorkflows.length > 0 ? `Workflow "${workflowName}" not found in contract. Available workflows: ${availableWorkflows.join(", ")}` : `Workflow "${workflowName}" not found in contract`;
20
+ super(message);
21
21
  this.workflowName = workflowName;
22
+ this.availableWorkflows = availableWorkflows;
22
23
  this.name = "WorkflowNotFoundError";
23
24
  }
24
25
  };
@@ -26,11 +27,12 @@ var WorkflowNotFoundError = class extends TypedClientError {
26
27
  * Error thrown when workflow input or output validation fails
27
28
  */
28
29
  var WorkflowValidationError = class extends TypedClientError {
29
- constructor(workflowName, phase, zodError) {
30
- super(`Validation failed for workflow "${workflowName}" ${phase}: ${zodError.message}`);
30
+ constructor(workflowName, phase, issues) {
31
+ const message = issues.map((issue) => issue.message).join("; ");
32
+ super(`Validation failed for workflow "${workflowName}" ${phase}: ${message}`);
31
33
  this.workflowName = workflowName;
32
34
  this.phase = phase;
33
- this.zodError = zodError;
35
+ this.issues = issues;
34
36
  this.name = "WorkflowValidationError";
35
37
  }
36
38
  };
@@ -38,11 +40,12 @@ var WorkflowValidationError = class extends TypedClientError {
38
40
  * Error thrown when query input or output validation fails
39
41
  */
40
42
  var QueryValidationError = class extends TypedClientError {
41
- constructor(queryName, phase, zodError) {
42
- super(`Validation failed for query "${queryName}" ${phase}: ${zodError.message}`);
43
+ constructor(queryName, phase, issues) {
44
+ const message = issues.map((issue) => issue.message).join("; ");
45
+ super(`Validation failed for query "${queryName}" ${phase}: ${message}`);
43
46
  this.queryName = queryName;
44
47
  this.phase = phase;
45
- this.zodError = zodError;
48
+ this.issues = issues;
46
49
  this.name = "QueryValidationError";
47
50
  }
48
51
  };
@@ -50,10 +53,11 @@ var QueryValidationError = class extends TypedClientError {
50
53
  * Error thrown when signal input validation fails
51
54
  */
52
55
  var SignalValidationError = class extends TypedClientError {
53
- constructor(signalName, zodError) {
54
- super(`Validation failed for signal "${signalName}" input: ${zodError.message}`);
56
+ constructor(signalName, issues) {
57
+ const message = issues.map((issue) => issue.message).join("; ");
58
+ super(`Validation failed for signal "${signalName}" input: ${message}`);
55
59
  this.signalName = signalName;
56
- this.zodError = zodError;
60
+ this.issues = issues;
57
61
  this.name = "SignalValidationError";
58
62
  }
59
63
  };
@@ -61,11 +65,12 @@ var SignalValidationError = class extends TypedClientError {
61
65
  * Error thrown when update input or output validation fails
62
66
  */
63
67
  var UpdateValidationError = class extends TypedClientError {
64
- constructor(updateName, phase, zodError) {
65
- super(`Validation failed for update "${updateName}" ${phase}: ${zodError.message}`);
68
+ constructor(updateName, phase, issues) {
69
+ const message = issues.map((issue) => issue.message).join("; ");
70
+ super(`Validation failed for update "${updateName}" ${phase}: ${message}`);
66
71
  this.updateName = updateName;
67
72
  this.phase = phase;
68
- this.zodError = zodError;
73
+ this.issues = issues;
69
74
  this.name = "UpdateValidationError";
70
75
  }
71
76
  };
@@ -120,14 +125,10 @@ var TypedClient = class TypedClient {
120
125
  */
121
126
  async startWorkflow(workflowName, { args, ...temporalOptions }) {
122
127
  const definition = this.contract.workflows[workflowName];
123
- if (!definition) throw new WorkflowNotFoundError(String(workflowName));
124
- let validatedInput;
125
- try {
126
- validatedInput = definition.input.parse(args);
127
- } catch (error) {
128
- if (error instanceof ZodError) throw new WorkflowValidationError(String(workflowName), "input", error);
129
- throw error;
130
- }
128
+ if (!definition) throw new WorkflowNotFoundError(String(workflowName), Object.keys(this.contract.workflows));
129
+ const inputResult = await definition.input["~standard"].validate(args);
130
+ if (inputResult.issues) throw new WorkflowValidationError(String(workflowName), "input", inputResult.issues);
131
+ const validatedInput = inputResult.value;
131
132
  const handle = await this.client.workflow.start(workflowName, {
132
133
  ...temporalOptions,
133
134
  taskQueue: this.contract.taskQueue,
@@ -152,25 +153,18 @@ var TypedClient = class TypedClient {
152
153
  */
153
154
  async executeWorkflow(workflowName, { args, ...temporalOptions }) {
154
155
  const definition = this.contract.workflows[workflowName];
155
- if (!definition) throw new WorkflowNotFoundError(String(workflowName));
156
- let validatedInput;
157
- try {
158
- validatedInput = definition.input.parse(args);
159
- } catch (error) {
160
- if (error instanceof ZodError) throw new WorkflowValidationError(String(workflowName), "input", error);
161
- throw error;
162
- }
156
+ if (!definition) throw new WorkflowNotFoundError(String(workflowName), Object.keys(this.contract.workflows));
157
+ const inputResult = await definition.input["~standard"].validate(args);
158
+ if (inputResult.issues) throw new WorkflowValidationError(String(workflowName), "input", inputResult.issues);
159
+ const validatedInput = inputResult.value;
163
160
  const result = await this.client.workflow.execute(workflowName, {
164
161
  ...temporalOptions,
165
162
  taskQueue: this.contract.taskQueue,
166
163
  args: [validatedInput]
167
164
  });
168
- try {
169
- return definition.output.parse(result);
170
- } catch (error) {
171
- if (error instanceof ZodError) throw new WorkflowValidationError(String(workflowName), "output", error);
172
- throw error;
173
- }
165
+ const outputResult = await definition.output["~standard"].validate(result);
166
+ if (outputResult.issues) throw new WorkflowValidationError(String(workflowName), "output", outputResult.issues);
167
+ return outputResult.value;
174
168
  }
175
169
  /**
176
170
  * Get a handle to an existing workflow
@@ -183,55 +177,34 @@ var TypedClient = class TypedClient {
183
177
  */
184
178
  async getHandle(workflowName, workflowId) {
185
179
  const definition = this.contract.workflows[workflowName];
186
- if (!definition) throw new WorkflowNotFoundError(String(workflowName));
180
+ if (!definition) throw new WorkflowNotFoundError(String(workflowName), Object.keys(this.contract.workflows));
187
181
  const handle = this.client.workflow.getHandle(workflowId);
188
182
  return this.createTypedHandle(handle, definition);
189
183
  }
190
184
  createTypedHandle(handle, definition) {
191
185
  const queries = {};
192
186
  for (const [queryName, queryDef] of Object.entries(definition.queries ?? {})) queries[queryName] = async (args) => {
193
- let validatedInput;
194
- try {
195
- validatedInput = queryDef.input.parse(args);
196
- } catch (error) {
197
- if (error instanceof ZodError) throw new QueryValidationError(queryName, "input", error);
198
- throw error;
199
- }
200
- const result = await handle.query(queryName, validatedInput);
201
- try {
202
- return queryDef.output.parse(result);
203
- } catch (error) {
204
- if (error instanceof ZodError) throw new QueryValidationError(queryName, "output", error);
205
- throw error;
206
- }
187
+ const inputResult = await queryDef.input["~standard"].validate(args);
188
+ if (inputResult.issues) throw new QueryValidationError(queryName, "input", inputResult.issues);
189
+ const result = await handle.query(queryName, inputResult.value);
190
+ const outputResult = await queryDef.output["~standard"].validate(result);
191
+ if (outputResult.issues) throw new QueryValidationError(queryName, "output", outputResult.issues);
192
+ return outputResult.value;
207
193
  };
208
194
  const signals = {};
209
195
  for (const [signalName, signalDef] of Object.entries(definition.signals ?? {})) signals[signalName] = async (args) => {
210
- let validatedInput;
211
- try {
212
- validatedInput = signalDef.input.parse(args);
213
- } catch (error) {
214
- if (error instanceof ZodError) throw new SignalValidationError(signalName, error);
215
- throw error;
216
- }
217
- await handle.signal(signalName, validatedInput);
196
+ const inputResult = await signalDef.input["~standard"].validate(args);
197
+ if (inputResult.issues) throw new SignalValidationError(signalName, inputResult.issues);
198
+ await handle.signal(signalName, inputResult.value);
218
199
  };
219
200
  const updates = {};
220
201
  for (const [updateName, updateDef] of Object.entries(definition.updates ?? {})) updates[updateName] = async (args) => {
221
- let validatedInput;
222
- try {
223
- validatedInput = updateDef.input.parse(args);
224
- } catch (error) {
225
- if (error instanceof ZodError) throw new UpdateValidationError(updateName, "input", error);
226
- throw error;
227
- }
228
- const result = await handle.executeUpdate(updateName, { args: [validatedInput] });
229
- try {
230
- return updateDef.output.parse(result);
231
- } catch (error) {
232
- if (error instanceof ZodError) throw new UpdateValidationError(updateName, "output", error);
233
- throw error;
234
- }
202
+ const inputResult = await updateDef.input["~standard"].validate(args);
203
+ if (inputResult.issues) throw new UpdateValidationError(updateName, "input", inputResult.issues);
204
+ const result = await handle.executeUpdate(updateName, { args: [inputResult.value] });
205
+ const outputResult = await updateDef.output["~standard"].validate(result);
206
+ if (outputResult.issues) throw new UpdateValidationError(updateName, "output", outputResult.issues);
207
+ return outputResult.value;
235
208
  };
236
209
  return {
237
210
  workflowId: handle.workflowId,
@@ -240,12 +213,9 @@ var TypedClient = class TypedClient {
240
213
  updates,
241
214
  result: async () => {
242
215
  const result = await handle.result();
243
- try {
244
- return definition.output.parse(result);
245
- } catch (error) {
246
- if (error instanceof ZodError) throw new WorkflowValidationError(handle.workflowId, "output", error);
247
- throw error;
248
- }
216
+ const outputResult = await definition.output["~standard"].validate(result);
217
+ if (outputResult.issues) throw new WorkflowValidationError(handle.workflowId, "output", outputResult.issues);
218
+ return outputResult.value;
249
219
  },
250
220
  terminate: async (reason) => {
251
221
  await handle.terminate(reason);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@temporal-contract/client",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "type": "module",
5
5
  "description": "Client utilities for consuming temporal-contract workflows",
6
6
  "homepage": "https://github.com/btravers/temporal-contract#readme",
@@ -37,21 +37,21 @@
37
37
  "./package.json": "./package.json"
38
38
  },
39
39
  "dependencies": {
40
- "@temporal-contract/contract": "0.0.1"
40
+ "@standard-schema/spec": "1.0.0",
41
+ "@temporal-contract/contract": "0.0.2"
41
42
  },
42
43
  "devDependencies": {
43
44
  "@temporalio/client": "1.13.2",
44
45
  "@types/node": "24.10.2",
46
+ "@vitest/coverage-v8": "4.0.15",
45
47
  "tsdown": "0.17.2",
46
- "type-fest": "5.3.1",
47
48
  "typescript": "5.9.3",
48
49
  "vitest": "4.0.15",
49
50
  "zod": "4.1.13",
50
- "@temporal-contract/tsconfig": "0.0.1"
51
+ "@temporal-contract/tsconfig": "0.0.2"
51
52
  },
52
53
  "peerDependencies": {
53
- "@temporalio/client": ">=1.13.0 <2.0.0",
54
- "zod": "^4.0.0"
54
+ "@temporalio/client": ">=1.13.0 <2.0.0"
55
55
  },
56
56
  "scripts": {
57
57
  "dev": "tsdown src/index.ts --format cjs,esm --dts --watch",
package/src/client.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Client, WorkflowHandle } from "@temporalio/client";
2
2
  import type { ClientOptions, WorkflowStartOptions, WorkflowOptions } from "@temporalio/client";
3
- import { ZodError } from "zod";
4
3
  import type {
5
4
  ClientInferInput,
6
5
  ClientInferOutput,
@@ -155,21 +154,20 @@ export class TypedClient<TContract extends ContractDefinition> {
155
154
  const definition = this.contract.workflows[workflowName as string];
156
155
 
157
156
  if (!definition) {
158
- throw new WorkflowNotFoundError(String(workflowName));
157
+ throw new WorkflowNotFoundError(
158
+ String(workflowName),
159
+ Object.keys(this.contract.workflows) as string[],
160
+ );
159
161
  }
160
162
 
161
- // Validate input with Zod schema (tuple)
162
- let validatedInput: ClientInferInput<TContract["workflows"][TWorkflowName]>;
163
- try {
164
- validatedInput = definition.input.parse(args) as ClientInferInput<
165
- TContract["workflows"][TWorkflowName]
166
- >;
167
- } catch (error) {
168
- if (error instanceof ZodError) {
169
- throw new WorkflowValidationError(String(workflowName), "input", error);
170
- }
171
- throw error;
163
+ // Validate input with Standard Schema
164
+ const inputResult = await definition.input["~standard"].validate(args);
165
+ if (inputResult.issues) {
166
+ throw new WorkflowValidationError(String(workflowName), "input", inputResult.issues);
172
167
  }
168
+ const validatedInput = inputResult.value as ClientInferInput<
169
+ TContract["workflows"][TWorkflowName]
170
+ >;
173
171
 
174
172
  // Start workflow (Temporal expects args as array, so wrap single parameter)
175
173
  const handle = await this.client.workflow.start(workflowName as string, {
@@ -210,21 +208,20 @@ export class TypedClient<TContract extends ContractDefinition> {
210
208
  const definition = this.contract.workflows[workflowName as string];
211
209
 
212
210
  if (!definition) {
213
- throw new WorkflowNotFoundError(String(workflowName));
211
+ throw new WorkflowNotFoundError(
212
+ String(workflowName),
213
+ Object.keys(this.contract.workflows) as string[],
214
+ );
214
215
  }
215
216
 
216
- // Validate input with Zod schema
217
- let validatedInput: ClientInferInput<TContract["workflows"][TWorkflowName]>;
218
- try {
219
- validatedInput = definition.input.parse(args) as ClientInferInput<
220
- TContract["workflows"][TWorkflowName]
221
- >;
222
- } catch (error) {
223
- if (error instanceof ZodError) {
224
- throw new WorkflowValidationError(String(workflowName), "input", error);
225
- }
226
- throw error;
217
+ // Validate input with Standard Schema
218
+ const inputResult = await definition.input["~standard"].validate(args);
219
+ if (inputResult.issues) {
220
+ throw new WorkflowValidationError(String(workflowName), "input", inputResult.issues);
227
221
  }
222
+ const validatedInput = inputResult.value as ClientInferInput<
223
+ TContract["workflows"][TWorkflowName]
224
+ >;
228
225
 
229
226
  // Execute workflow (Temporal expects args as array, so wrap single parameter)
230
227
  const result = await this.client.workflow.execute(workflowName as string, {
@@ -233,17 +230,13 @@ export class TypedClient<TContract extends ContractDefinition> {
233
230
  args: [validatedInput],
234
231
  });
235
232
 
236
- // Validate output with Zod schema
237
- try {
238
- return definition.output.parse(result) as ClientInferOutput<
239
- TContract["workflows"][TWorkflowName]
240
- >;
241
- } catch (error) {
242
- if (error instanceof ZodError) {
243
- throw new WorkflowValidationError(String(workflowName), "output", error);
244
- }
245
- throw error;
233
+ // Validate output with Standard Schema
234
+ const outputResult = await definition.output["~standard"].validate(result);
235
+ if (outputResult.issues) {
236
+ throw new WorkflowValidationError(String(workflowName), "output", outputResult.issues);
246
237
  }
238
+
239
+ return outputResult.value as ClientInferOutput<TContract["workflows"][TWorkflowName]>;
247
240
  }
248
241
 
249
242
  /**
@@ -262,7 +255,10 @@ export class TypedClient<TContract extends ContractDefinition> {
262
255
  const definition = this.contract.workflows[workflowName as string];
263
256
 
264
257
  if (!definition) {
265
- throw new WorkflowNotFoundError(String(workflowName));
258
+ throw new WorkflowNotFoundError(
259
+ String(workflowName),
260
+ Object.keys(this.contract.workflows) as string[],
261
+ );
266
262
  }
267
263
 
268
264
  const handle = this.client.workflow.getHandle(workflowId);
@@ -283,26 +279,19 @@ export class TypedClient<TContract extends ContractDefinition> {
283
279
  (queries as Record<string, unknown>)[queryName] = async (
284
280
  args: ClientInferInput<typeof queryDef>,
285
281
  ) => {
286
- let validatedInput: ClientInferInput<typeof queryDef>;
287
- try {
288
- validatedInput = queryDef.input.parse(args) as ClientInferInput<typeof queryDef>;
289
- } catch (error) {
290
- if (error instanceof ZodError) {
291
- throw new QueryValidationError(queryName, "input", error);
292
- }
293
- throw error;
282
+ const inputResult = await queryDef.input["~standard"].validate(args);
283
+ if (inputResult.issues) {
284
+ throw new QueryValidationError(queryName, "input", inputResult.issues);
294
285
  }
295
286
 
296
- const result = await handle.query(queryName as string, validatedInput);
287
+ const result = await handle.query(queryName as string, inputResult.value);
297
288
 
298
- try {
299
- return queryDef.output.parse(result);
300
- } catch (error) {
301
- if (error instanceof ZodError) {
302
- throw new QueryValidationError(queryName, "output", error);
303
- }
304
- throw error;
289
+ const outputResult = await queryDef.output["~standard"].validate(result);
290
+ if (outputResult.issues) {
291
+ throw new QueryValidationError(queryName, "output", outputResult.issues);
305
292
  }
293
+
294
+ return outputResult.value;
306
295
  };
307
296
  }
308
297
 
@@ -314,16 +303,11 @@ export class TypedClient<TContract extends ContractDefinition> {
314
303
  (signals as Record<string, unknown>)[signalName] = async (
315
304
  args: ClientInferInput<typeof signalDef>,
316
305
  ) => {
317
- let validatedInput: ClientInferInput<typeof signalDef>;
318
- try {
319
- validatedInput = signalDef.input.parse(args) as ClientInferInput<typeof signalDef>;
320
- } catch (error) {
321
- if (error instanceof ZodError) {
322
- throw new SignalValidationError(signalName, error);
323
- }
324
- throw error;
306
+ const inputResult = await signalDef.input["~standard"].validate(args);
307
+ if (inputResult.issues) {
308
+ throw new SignalValidationError(signalName, inputResult.issues);
325
309
  }
326
- await handle.signal(signalName as string, validatedInput);
310
+ await handle.signal(signalName as string, inputResult.value);
327
311
  };
328
312
  }
329
313
 
@@ -335,26 +319,21 @@ export class TypedClient<TContract extends ContractDefinition> {
335
319
  (updates as Record<string, unknown>)[updateName] = async (
336
320
  args: ClientInferInput<typeof updateDef>,
337
321
  ) => {
338
- let validatedInput: ClientInferInput<typeof updateDef>;
339
- try {
340
- validatedInput = updateDef.input.parse(args) as ClientInferInput<typeof updateDef>;
341
- } catch (error) {
342
- if (error instanceof ZodError) {
343
- throw new UpdateValidationError(updateName, "input", error);
344
- }
345
- throw error;
322
+ const inputResult = await updateDef.input["~standard"].validate(args);
323
+ if (inputResult.issues) {
324
+ throw new UpdateValidationError(updateName, "input", inputResult.issues);
346
325
  }
347
326
 
348
- const result = await handle.executeUpdate(updateName as string, { args: [validatedInput] });
327
+ const result = await handle.executeUpdate(updateName as string, {
328
+ args: [inputResult.value],
329
+ });
349
330
 
350
- try {
351
- return updateDef.output.parse(result);
352
- } catch (error) {
353
- if (error instanceof ZodError) {
354
- throw new UpdateValidationError(updateName, "output", error);
355
- }
356
- throw error;
331
+ const outputResult = await updateDef.output["~standard"].validate(result);
332
+ if (outputResult.issues) {
333
+ throw new UpdateValidationError(updateName, "output", outputResult.issues);
357
334
  }
335
+
336
+ return outputResult.value;
358
337
  };
359
338
  }
360
339
 
@@ -365,15 +344,12 @@ export class TypedClient<TContract extends ContractDefinition> {
365
344
  updates,
366
345
  result: async () => {
367
346
  const result = await handle.result();
368
- // Validate output with Zod schema
369
- try {
370
- return definition.output.parse(result) as ClientInferOutput<TWorkflow>;
371
- } catch (error) {
372
- if (error instanceof ZodError) {
373
- throw new WorkflowValidationError(handle.workflowId, "output", error);
374
- }
375
- throw error;
347
+ // Validate output with Standard Schema
348
+ const outputResult = await definition.output["~standard"].validate(result);
349
+ if (outputResult.issues) {
350
+ throw new WorkflowValidationError(handle.workflowId, "output", outputResult.issues);
376
351
  }
352
+ return outputResult.value as ClientInferOutput<TWorkflow>;
377
353
  },
378
354
  terminate: async (reason?: string) => {
379
355
  await handle.terminate(reason);
package/src/errors.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { z } from "zod";
1
+ import type { StandardSchemaV1 } from "@standard-schema/spec";
2
2
 
3
3
  /**
4
4
  * Base error class for typed client errors
@@ -18,8 +18,15 @@ export class TypedClientError extends Error {
18
18
  * Error thrown when a workflow is not found in the contract
19
19
  */
20
20
  export class WorkflowNotFoundError extends TypedClientError {
21
- constructor(public readonly workflowName: string) {
22
- super(`Workflow "${workflowName}" not found in contract`);
21
+ constructor(
22
+ public readonly workflowName: string,
23
+ public readonly availableWorkflows: readonly string[] = [],
24
+ ) {
25
+ const message =
26
+ availableWorkflows.length > 0
27
+ ? `Workflow "${workflowName}" not found in contract. Available workflows: ${availableWorkflows.join(", ")}`
28
+ : `Workflow "${workflowName}" not found in contract`;
29
+ super(message);
23
30
  this.name = "WorkflowNotFoundError";
24
31
  }
25
32
  }
@@ -31,9 +38,10 @@ export class WorkflowValidationError extends TypedClientError {
31
38
  constructor(
32
39
  public readonly workflowName: string,
33
40
  public readonly phase: "input" | "output",
34
- public readonly zodError: z.ZodError,
41
+ public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,
35
42
  ) {
36
- super(`Validation failed for workflow "${workflowName}" ${phase}: ${zodError.message}`);
43
+ const message = issues.map((issue) => issue.message).join("; ");
44
+ super(`Validation failed for workflow "${workflowName}" ${phase}: ${message}`);
37
45
  this.name = "WorkflowValidationError";
38
46
  }
39
47
  }
@@ -45,9 +53,10 @@ export class QueryValidationError extends TypedClientError {
45
53
  constructor(
46
54
  public readonly queryName: string,
47
55
  public readonly phase: "input" | "output",
48
- public readonly zodError: z.ZodError,
56
+ public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,
49
57
  ) {
50
- super(`Validation failed for query "${queryName}" ${phase}: ${zodError.message}`);
58
+ const message = issues.map((issue) => issue.message).join("; ");
59
+ super(`Validation failed for query "${queryName}" ${phase}: ${message}`);
51
60
  this.name = "QueryValidationError";
52
61
  }
53
62
  }
@@ -58,9 +67,10 @@ export class QueryValidationError extends TypedClientError {
58
67
  export class SignalValidationError extends TypedClientError {
59
68
  constructor(
60
69
  public readonly signalName: string,
61
- public readonly zodError: z.ZodError,
70
+ public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,
62
71
  ) {
63
- super(`Validation failed for signal "${signalName}" input: ${zodError.message}`);
72
+ const message = issues.map((issue) => issue.message).join("; ");
73
+ super(`Validation failed for signal "${signalName}" input: ${message}`);
64
74
  this.name = "SignalValidationError";
65
75
  }
66
76
  }
@@ -72,9 +82,10 @@ export class UpdateValidationError extends TypedClientError {
72
82
  constructor(
73
83
  public readonly updateName: string,
74
84
  public readonly phase: "input" | "output",
75
- public readonly zodError: z.ZodError,
85
+ public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,
76
86
  ) {
77
- super(`Validation failed for update "${updateName}" ${phase}: ${zodError.message}`);
87
+ const message = issues.map((issue) => issue.message).join("; ");
88
+ super(`Validation failed for update "${updateName}" ${phase}: ${message}`);
78
89
  this.name = "UpdateValidationError";
79
90
  }
80
91
  }
@@ -0,0 +1,12 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ reporters: ["default"],
6
+ coverage: {
7
+ provider: "v8",
8
+ reporter: ["text", "json", "json-summary", "html"],
9
+ include: ["src/**"],
10
+ },
11
+ },
12
+ });