@temporal-contract/client 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -70
- package/dist/index.cjs +50 -80
- package/dist/index.d.cts +11 -10
- package/dist/index.d.mts +11 -10
- package/dist/index.mjs +50 -80
- package/package.json +9 -6
- package/.turbo/turbo-build.log +0 -17
- package/src/client.spec.ts +0 -564
- package/src/client.ts +0 -390
- package/src/errors.ts +0 -80
- package/src/index.ts +0 -9
- package/tsconfig.json +0 -9
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
|
-
|
|
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,
|
|
30
|
-
|
|
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.
|
|
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,
|
|
42
|
-
|
|
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.
|
|
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,
|
|
54
|
-
|
|
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.
|
|
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,
|
|
65
|
-
|
|
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.
|
|
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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Client utilities for consuming temporal-contract workflows",
|
|
6
6
|
"homepage": "https://github.com/btravers/temporal-contract#readme",
|
|
@@ -36,22 +36,25 @@
|
|
|
36
36
|
},
|
|
37
37
|
"./package.json": "./package.json"
|
|
38
38
|
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist"
|
|
41
|
+
],
|
|
39
42
|
"dependencies": {
|
|
40
|
-
"@
|
|
43
|
+
"@standard-schema/spec": "1.0.0",
|
|
44
|
+
"@temporal-contract/contract": "0.0.3"
|
|
41
45
|
},
|
|
42
46
|
"devDependencies": {
|
|
43
47
|
"@temporalio/client": "1.13.2",
|
|
44
48
|
"@types/node": "24.10.2",
|
|
49
|
+
"@vitest/coverage-v8": "4.0.15",
|
|
45
50
|
"tsdown": "0.17.2",
|
|
46
|
-
"type-fest": "5.3.1",
|
|
47
51
|
"typescript": "5.9.3",
|
|
48
52
|
"vitest": "4.0.15",
|
|
49
53
|
"zod": "4.1.13",
|
|
50
|
-
"@temporal-contract/tsconfig": "0.0.
|
|
54
|
+
"@temporal-contract/tsconfig": "0.0.3"
|
|
51
55
|
},
|
|
52
56
|
"peerDependencies": {
|
|
53
|
-
"@temporalio/client": ">=1.13.0 <2.0.0"
|
|
54
|
-
"zod": "^4.0.0"
|
|
57
|
+
"@temporalio/client": ">=1.13.0 <2.0.0"
|
|
55
58
|
},
|
|
56
59
|
"scripts": {
|
|
57
60
|
"dev": "tsdown src/index.ts --format cjs,esm --dts --watch",
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @temporal-contract/client@0.0.1 build /home/runner/work/temporal-contract/temporal-contract/packages/client
|
|
3
|
-
> tsdown src/index.ts --format cjs,esm --dts --clean
|
|
4
|
-
|
|
5
|
-
[34mℹ[39m tsdown [2mv0.17.2[22m powered by rolldown [2mv1.0.0-beta.53[22m
|
|
6
|
-
[34mℹ[39m entry: [34msrc/index.ts[39m
|
|
7
|
-
[34mℹ[39m tsconfig: [34mtsconfig.json[39m
|
|
8
|
-
[34mℹ[39m Build start
|
|
9
|
-
[34mℹ[39m [33m[CJS][39m [2mdist/[22m[1mindex.cjs[22m [2m8.38 kB[22m [2m│ gzip: 1.77 kB[22m
|
|
10
|
-
[34mℹ[39m [33m[CJS][39m 1 files, total: 8.38 kB
|
|
11
|
-
[34mℹ[39m [34m[ESM][39m [2mdist/[22m[1mindex.mjs[22m [2m8.12 kB[22m [2m│ gzip: 1.74 kB[22m
|
|
12
|
-
[34mℹ[39m [34m[ESM][39m [2mdist/[22m[32m[1mindex.d.mts[22m[39m [2m6.70 kB[22m [2m│ gzip: 1.62 kB[22m
|
|
13
|
-
[34mℹ[39m [34m[ESM][39m 2 files, total: 14.81 kB
|
|
14
|
-
[32m✔[39m Build complete in [32m3603ms[39m
|
|
15
|
-
[34mℹ[39m [33m[CJS][39m [2mdist/[22m[32m[1mindex.d.cts[22m[39m [2m6.70 kB[22m [2m│ gzip: 1.62 kB[22m
|
|
16
|
-
[34mℹ[39m [33m[CJS][39m 1 files, total: 6.70 kB
|
|
17
|
-
[32m✔[39m Build complete in [32m3605ms[39m
|