@lostgradient/weft 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/README.md +1 -1
  2. package/dist/alerting/alert-manager.d.ts +5 -5
  3. package/dist/alerting/alert-manager.js +24 -6
  4. package/dist/alerting/index.d.ts +1 -1
  5. package/dist/alerting/types.d.ts +17 -13
  6. package/dist/alerting/types.js +5 -0
  7. package/dist/core/engine/disposal.js +7 -0
  8. package/dist/core/engine/engine-runtime-helpers.d.ts +3 -1
  9. package/dist/core/engine/engine-runtime-helpers.js +2 -2
  10. package/dist/core/engine/errors.d.ts +20 -0
  11. package/dist/core/engine/errors.js +8 -0
  12. package/dist/core/engine/index.d.ts +39 -17
  13. package/dist/core/engine/index.js +81 -9
  14. package/dist/core/engine/inline-launch-queue.d.ts +6 -2
  15. package/dist/core/engine/inline-launch-queue.js +41 -6
  16. package/dist/core/engine/internals.d.ts +2 -0
  17. package/dist/core/engine/lease-manager.d.ts +3 -2
  18. package/dist/core/engine/lease-manager.js +7 -3
  19. package/dist/core/engine/operations-time.js +6 -0
  20. package/dist/core/execution-strategy.d.ts +8 -0
  21. package/dist/core/inline-execution-strategy.d.ts +1 -0
  22. package/dist/core/inline-execution-strategy.js +33 -20
  23. package/dist/core/weft-error.d.ts +1 -1
  24. package/dist/core/weft-error.js +1 -0
  25. package/dist/core/worker-execution-strategy.d.ts +2 -0
  26. package/dist/core/worker-execution-strategy.js +7 -2
  27. package/dist/core/worker-turn-watchdog.d.ts +4 -1
  28. package/dist/core/worker-turn-watchdog.js +9 -4
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.js +1 -0
  31. package/dist/indexeddb.js +1 -1
  32. package/dist/json-schema.js +1 -1
  33. package/dist/mcp/tools.js +1 -3
  34. package/dist/server/dashboard-assets.d.ts +12 -1
  35. package/dist/server/dashboard-assets.js +145 -31
  36. package/dist/server/operations/aggregate-workflows.js +0 -7
  37. package/dist/server/operations/async-activity.js +5 -24
  38. package/dist/server/operations/bulk-cancel-workflows.js +3 -8
  39. package/dist/server/operations/bulk-delete-workflows.js +3 -8
  40. package/dist/server/operations/bulk-mutate-workflow-tags.js +3 -8
  41. package/dist/server/operations/bulk-operation-helpers.d.ts +2 -10
  42. package/dist/server/operations/bulk-operation-helpers.js +0 -6
  43. package/dist/server/operations/bulk-retry-failed-workflows.js +3 -8
  44. package/dist/server/operations/bulk-signal-workflows.js +3 -8
  45. package/dist/server/operations/cancel-schedule.js +1 -3
  46. package/dist/server/operations/cancel-workflow.js +1 -3
  47. package/dist/server/operations/create-schedule.js +2 -3
  48. package/dist/server/operations/fork-workflow.js +2 -3
  49. package/dist/server/operations/get-checkpoint-at.js +1 -6
  50. package/dist/server/operations/get-registry.js +1 -7
  51. package/dist/server/operations/get-retention-overview.js +2 -15
  52. package/dist/server/operations/get-review.js +2 -15
  53. package/dist/server/operations/get-schedule.js +2 -8
  54. package/dist/server/operations/get-stream-chunks.js +2 -6
  55. package/dist/server/operations/get-system-lease.js +1 -7
  56. package/dist/server/operations/get-system-metrics.js +0 -4
  57. package/dist/server/operations/get-task-diagnostics.js +2 -13
  58. package/dist/server/operations/get-update-result.js +1 -6
  59. package/dist/server/operations/get-workflow-attributes.js +2 -15
  60. package/dist/server/operations/get-workflow-events.js +2 -15
  61. package/dist/server/operations/get-workflow-observability.js +2 -5
  62. package/dist/server/operations/get-workflow-result.js +0 -7
  63. package/dist/server/operations/get-workflow-timeline.js +1 -6
  64. package/dist/server/operations/get-workflow.d.ts +3 -6
  65. package/dist/server/operations/get-workflow.js +2 -12
  66. package/dist/server/operations/list-alerts.d.ts +5 -2
  67. package/dist/server/operations/list-alerts.js +2 -9
  68. package/dist/server/operations/list-checkpoints.js +1 -6
  69. package/dist/server/operations/list-reviews.js +0 -7
  70. package/dist/server/operations/list-schedules.js +3 -8
  71. package/dist/server/operations/list-task-queues.js +0 -4
  72. package/dist/server/operations/list-workers.js +0 -4
  73. package/dist/server/operations/list-workflows.js +0 -7
  74. package/dist/server/operations/pause-schedule.js +1 -3
  75. package/dist/server/operations/purge-workflows.js +2 -5
  76. package/dist/server/operations/query-workflow.js +4 -15
  77. package/dist/server/operations/replay-workflow.js +2 -6
  78. package/dist/server/operations/resume-schedule.js +1 -3
  79. package/dist/server/operations/resume-workflow.js +1 -3
  80. package/dist/server/operations/set-workflow-attributes.js +3 -15
  81. package/dist/server/operations/signal-workflow.js +3 -12
  82. package/dist/server/operations/single-workflow-tag-mutation.js +0 -7
  83. package/dist/server/operations/start-or-signal-workflow.js +2 -3
  84. package/dist/server/operations/start-workflow.js +2 -3
  85. package/dist/server/operations/storage-capabilities.js +1 -3
  86. package/dist/server/operations/storage.js +7 -13
  87. package/dist/server/operations/submit-review-decision.js +3 -12
  88. package/dist/server/operations/suspend-workflow.js +1 -3
  89. package/dist/server/operations/timeout-workflow.js +1 -3
  90. package/dist/server/operations/update-schedule.js +1 -3
  91. package/dist/server/operations/update-workflow.js +2 -3
  92. package/dist/server/operations/worker-drain.js +0 -8
  93. package/dist/server/rest-binding.d.ts +3 -2
  94. package/dist/server/route-model.d.ts +2 -0
  95. package/dist/server/route-model.js +1 -1
  96. package/dist/server/runtime/task-reconciliation.d.ts +10 -1
  97. package/dist/server/runtime/task-reconciliation.js +26 -2
  98. package/dist/server/serve-internals.js +12 -6
  99. package/dist/storage/indexeddb.js +28 -48
  100. package/dist/storage/testing.d.ts +6 -3
  101. package/dist/storage/testing.js +1 -1
  102. package/dist/version.d.ts +1 -1
  103. package/dist/version.js +1 -1
  104. package/dist/worker/protocol-schemas.d.ts +2 -2
  105. package/dist/worker/protocol-schemas.js +2 -2
  106. package/dist/worker/protocol.js +1 -1
  107. package/package.json +1 -1
@@ -1,14 +1,6 @@
1
- import { realpathSync, statSync } from "node:fs";
2
- import { isAbsolute, join, relative, resolve, sep } from "node:path";
3
- const ROOT_API_PREFIXES = ["/api", "/v1"], DISCOVERY_DOCUMENTS = [
4
- "/openapi.json",
5
- "/openrpc.json",
6
- "/asyncapi.json",
7
- "/.well-known/mcp.json"
8
- ];
9
- function hasPathPrefix(path, prefix) {
10
- return path === prefix || path.startsWith(`${prefix}/`);
11
- }
1
+ import * as fileSystem from "node:fs";
2
+ import { isAbsolute, join, relative, resolve as resolvePath, sep } from "node:path";
3
+ import { API_PREFIX, DIRECT_HTTP_ROUTES, ROOT_API_PREFIX } from "./route-model.js";
12
4
  function overlapsDashboardPageRoute(prefix, route) {
13
5
  if (route.endsWith("/*")) {
14
6
  const base = route.slice(0, -2);
@@ -16,6 +8,9 @@ function overlapsDashboardPageRoute(prefix, route) {
16
8
  }
17
9
  return prefix === route;
18
10
  }
11
+ function overlapsWildcardRoute(prefix, route) {
12
+ return prefix === route || prefix.startsWith(`${route}/`) || route.startsWith(`${prefix}/`);
13
+ }
19
14
  function hasInvalidPrefixShape(prefix) {
20
15
  return prefix.length === 0 || prefix === "/" || !prefix.startsWith("/") || prefix.endsWith("/") || ["?", "#", "%", "*", ":", "\\"].some((character) => prefix.includes(character));
21
16
  }
@@ -24,14 +19,19 @@ function validateAssetPrefixShape(prefix) {
24
19
  throw Error("dashboardAssets.prefix must be an absolute path prefix without a trailing slash, wildcard, parameter, query, fragment, percent escape, or backslash");
25
20
  if (prefix.split("/").slice(1).some((segment) => segment.length === 0 || segment === "." || segment === ".."))
26
21
  throw Error("dashboardAssets.prefix must contain only concrete, non-empty path segments");
22
+ const serializedPathname = new URL(prefix, "http://weft.invalid").pathname;
23
+ if (serializedPathname !== prefix)
24
+ throw Error(`dashboardAssets.prefix must round-trip through URL serialization unchanged; ${prefix} serializes as ${serializedPathname}`);
27
25
  }
28
26
  function validateAssetPrefixReservations(prefix, pageRoutes) {
29
- if (ROOT_API_PREFIXES.some((reserved) => hasPathPrefix(prefix, reserved)))
30
- throw Error("dashboardAssets.prefix must not overlap the /api or /v1 route spaces");
27
+ if ([
28
+ API_PREFIX,
29
+ ROOT_API_PREFIX,
30
+ ...DIRECT_HTTP_ROUTES.map(({ path }) => path)
31
+ ].some((reserved) => overlapsWildcardRoute(prefix, reserved)))
32
+ throw Error("dashboardAssets.prefix must not overlap the /api, /v1, or direct HTTP route spaces");
31
33
  if (pageRoutes.some((route) => overlapsDashboardPageRoute(prefix, route)))
32
34
  throw Error("dashboardAssets.prefix must not overlap dashboard page routes");
33
- if (DISCOVERY_DOCUMENTS.some((document) => document === prefix))
34
- throw Error("dashboardAssets.prefix must not overlap a discovery document route");
35
35
  }
36
36
  function validateAssetPrefix(prefix, pageRoutes) {
37
37
  validateAssetPrefixShape(prefix);
@@ -46,50 +46,164 @@ export function resolveDashboardAssets(value, pageRoutes) {
46
46
  if (typeof prefix !== "string" || typeof directory !== "string")
47
47
  throw Error("dashboardAssets.prefix and dashboardAssets.directory must be strings");
48
48
  validateAssetPrefix(prefix, pageRoutes);
49
- const resolvedDirectory = resolve(directory);
49
+ const resolvedDirectory = resolvePath(directory);
50
50
  let directoryStats;
51
51
  try {
52
- directoryStats = statSync(resolvedDirectory);
52
+ directoryStats = fileSystem.statSync(resolvedDirectory);
53
53
  } catch {
54
54
  throw Error(`dashboardAssets.directory does not exist: ${directory}`);
55
55
  }
56
56
  if (!directoryStats.isDirectory())
57
57
  throw Error(`dashboardAssets.directory must be a directory: ${directory}`);
58
- return { prefix, directory: realpathSync(resolvedDirectory) };
58
+ return { prefix, directory: fileSystem.realpathSync(resolvedDirectory) };
59
59
  }
60
60
  function isWithinDirectory(directory, path) {
61
61
  const pathRelativeToDirectory = relative(directory, path);
62
62
  return pathRelativeToDirectory.length > 0 && pathRelativeToDirectory !== ".." && !pathRelativeToDirectory.startsWith(`..${sep}`) && !isAbsolute(pathRelativeToDirectory);
63
63
  }
64
- function assetResponse(directory, prefix, request) {
64
+ function hasSameFileIdentity(left, right) {
65
+ return left.dev === right.dev && left.ino === right.ino;
66
+ }
67
+ function resolveAssetPath(directory, prefix, request) {
68
+ if (request.signal.aborted)
69
+ return;
65
70
  const rawWildcardPath = new URL(request.url).pathname.slice(prefix.length + 1);
66
71
  let wildcardPath;
67
72
  try {
68
73
  wildcardPath = decodeURIComponent(rawWildcardPath);
69
74
  } catch {
70
- return new Response("Not Found", { status: 404 });
75
+ return;
71
76
  }
72
77
  if (wildcardPath.length === 0)
73
- return new Response("Not Found", { status: 404 });
78
+ return;
74
79
  const pathSegments = wildcardPath.split(/[\\/]/);
75
80
  if (pathSegments.some((segment) => segment === ".." || segment.length === 0))
76
- return new Response("Not Found", { status: 404 });
77
- const assetPath = resolve(join(directory, ...pathSegments));
81
+ return;
82
+ const assetPath = resolvePath(join(directory, ...pathSegments));
78
83
  if (!isWithinDirectory(directory, assetPath))
84
+ return;
85
+ return assetPath;
86
+ }
87
+ function isVerifiedAssetDescriptor(request, directory, canonicalStats, openedStats, postOpenStats, postOpenAssetPath, openedAssetPath) {
88
+ return !request.signal.aborted && isWithinDirectory(directory, postOpenAssetPath) && (openedAssetPath === void 0 || isWithinDirectory(directory, openedAssetPath)) && canonicalStats.isFile() && openedStats.isFile() && postOpenStats.isFile() && hasSameFileIdentity(openedStats, canonicalStats) && hasSameFileIdentity(openedStats, postOpenStats);
89
+ }
90
+ function resolveOpenedDescriptorPath(descriptor, assetFileSystem) {
91
+ for (const descriptorPath of [`/proc/self/fd/${descriptor}`, `/dev/fd/${descriptor}`])
92
+ try {
93
+ const resolvedPath = assetFileSystem.realpathSync(descriptorPath);
94
+ if (resolvedPath.startsWith("/proc/self/fd/") || resolvedPath.startsWith("/dev/fd/"))
95
+ continue;
96
+ return resolvedPath;
97
+ } catch {}
98
+ return;
99
+ }
100
+ function createAssetStream(descriptor, verifiedSize, assetFileSystem) {
101
+ let closed = !1, cancelled = !1, position = 0, remainingBytes = verifiedSize, inFlightRead;
102
+ const close = () => {
103
+ if (!closed) {
104
+ closed = !0;
105
+ assetFileSystem.closeSync(descriptor);
106
+ }
107
+ };
108
+ return { stream: new ReadableStream({
109
+ async pull(controller) {
110
+ if (cancelled)
111
+ return;
112
+ if (remainingBytes === 0) {
113
+ close();
114
+ controller.close();
115
+ return;
116
+ }
117
+ const buffer = Buffer.allocUnsafe(Math.min(65536, remainingBytes)), read = assetFileSystem.read(descriptor, buffer, 0, buffer.byteLength, position);
118
+ inFlightRead = read;
119
+ try {
120
+ const bytesRead = await read;
121
+ if (cancelled) {
122
+ close();
123
+ return;
124
+ }
125
+ if (bytesRead === 0) {
126
+ close();
127
+ controller.error(Error("Dashboard asset ended before its verified content length was read."));
128
+ return;
129
+ }
130
+ const boundedBytesRead = Math.min(bytesRead, remainingBytes);
131
+ position += boundedBytesRead;
132
+ remainingBytes -= boundedBytesRead;
133
+ controller.enqueue(buffer.subarray(0, boundedBytesRead));
134
+ if (remainingBytes === 0) {
135
+ close();
136
+ controller.close();
137
+ }
138
+ } catch (error) {
139
+ close();
140
+ if (!cancelled)
141
+ controller.error(error);
142
+ } finally {
143
+ if (inFlightRead === read)
144
+ inFlightRead = void 0;
145
+ }
146
+ },
147
+ async cancel() {
148
+ cancelled = !0;
149
+ try {
150
+ await inFlightRead;
151
+ } catch {}
152
+ close();
153
+ }
154
+ }), close };
155
+ }
156
+ function readAssetDescriptor(descriptor, buffer, offset, length, position) {
157
+ return new Promise((_resolve, reject) => {
158
+ fileSystem.read(descriptor, buffer, offset, length, position, (error, bytesRead) => {
159
+ if (error)
160
+ reject(error);
161
+ else
162
+ _resolve(bytesRead);
163
+ });
164
+ });
165
+ }
166
+ function assetResponse(directory, prefix, request, assetFileSystem) {
167
+ const assetPath = resolveAssetPath(directory, prefix, request);
168
+ if (assetPath === void 0)
79
169
  return new Response("Not Found", { status: 404 });
80
- let realAssetPath;
170
+ let descriptor;
81
171
  try {
82
- realAssetPath = realpathSync(assetPath);
83
- if (!statSync(realAssetPath).isFile())
172
+ const realAssetPath = assetFileSystem.realpathSync(assetPath);
173
+ if (!isWithinDirectory(directory, realAssetPath))
84
174
  return new Response("Not Found", { status: 404 });
175
+ const canonicalStats = assetFileSystem.statSync(realAssetPath);
176
+ descriptor = assetFileSystem.openSync(realAssetPath, assetFileSystem.constants.O_RDONLY | assetFileSystem.constants.O_NOFOLLOW | assetFileSystem.constants.O_NONBLOCK);
177
+ const fileStats = assetFileSystem.fstatSync(descriptor), postOpenAssetPath = assetFileSystem.realpathSync(realAssetPath), postOpenStats = assetFileSystem.statSync(postOpenAssetPath), openedAssetPath = resolveOpenedDescriptorPath(descriptor, assetFileSystem);
178
+ if (!isVerifiedAssetDescriptor(request, directory, canonicalStats, fileStats, postOpenStats, postOpenAssetPath, openedAssetPath))
179
+ return new Response("Not Found", { status: 404 });
180
+ const headers = {
181
+ "content-length": String(fileStats.size),
182
+ "content-type": Bun.file(realAssetPath).type
183
+ };
184
+ if (request.method === "HEAD")
185
+ return new Response(null, { headers });
186
+ const assetStream = createAssetStream(descriptor, fileStats.size, assetFileSystem);
187
+ try {
188
+ const response = new Response(assetStream.stream, { headers });
189
+ descriptor = void 0;
190
+ return response;
191
+ } catch {
192
+ assetStream.close();
193
+ descriptor = void 0;
194
+ return new Response("Not Found", { status: 404 });
195
+ }
85
196
  } catch {
86
197
  return new Response("Not Found", { status: 404 });
198
+ } finally {
199
+ if (descriptor !== void 0)
200
+ assetFileSystem.closeSync(descriptor);
87
201
  }
88
- if (!isWithinDirectory(directory, realAssetPath))
89
- return new Response("Not Found", { status: 404 });
90
- return new Response(Bun.file(realAssetPath));
91
202
  }
92
- export function createDashboardAssetRoute(assets) {
93
- const handler = (request) => assetResponse(assets.directory, assets.prefix, request);
203
+ export function createDashboardAssetRoute(assets, assetFileSystem) {
204
+ const fileSystemForAsset = assetFileSystem ?? {
205
+ ...fileSystem,
206
+ read: readAssetDescriptor
207
+ }, handler = (request) => assetResponse(assets.directory, assets.prefix, request, fileSystemForAsset);
94
208
  return { GET: handler, HEAD: handler };
95
209
  }
@@ -79,12 +79,6 @@ function extractAggregateWorkflowsInput(request) {
79
79
  ...limitValue !== void 0 && Number.isFinite(limitValue) && limitValue >= 1 ? { limit: limitValue } : {}
80
80
  };
81
81
  }
82
- function shapeAggregateWorkflowsSuccess(result) {
83
- return new Response(JSON.stringify(result), {
84
- status: 200,
85
- headers: { "Content-Type": "application/json" }
86
- });
87
- }
88
82
  function shapeAggregateWorkflowsFault(fault) {
89
83
  if (fault.code === "Unprocessable")
90
84
  return shapeRestFault(fault, { status: 400 });
@@ -106,6 +100,5 @@ export const aggregateWorkflowsRestBinding = {
106
100
  },
107
101
  extractInput: async (request) => extractAggregateWorkflowsInput(request),
108
102
  success: { kind: "json", status: 200 },
109
- shapeSuccess: (output) => shapeAggregateWorkflowsSuccess(output),
110
103
  shapeFault: shapeAggregateWorkflowsFault
111
104
  };
@@ -11,7 +11,7 @@ import { PayloadSizeExceededError } from "../../core/payload-size.js";
11
11
  import { raiseFault } from "../operation-catalog.js";
12
12
  import { defineOperation } from "../operation-registry.js";
13
13
  import { readRestJsonBody } from "../rest-body.js";
14
- import { invalidParamsFault, isOperationFault, shapeRestFault } from "./operation-helpers.js";
14
+ import { invalidParamsFault, isOperationFault } from "./operation-helpers.js";
15
15
  const asyncActivityReadAccess = {
16
16
  kind: "scoped",
17
17
  scopes: { kind: "anyOf", scopes: ["workflows:read"] }
@@ -137,20 +137,7 @@ export const completeAsyncActivityOperation = defineOperation({
137
137
  }
138
138
  return { ok: !0 };
139
139
  }
140
- });
141
- function shapeAsyncActivitySuccess(output) {
142
- return new Response(JSON.stringify(output), {
143
- status: 200,
144
- headers: { "Content-Type": "application/json" }
145
- });
146
- }
147
- function shapePendingAsyncActivitiesSuccess(output) {
148
- return new Response(JSON.stringify(output), {
149
- status: 200,
150
- headers: { "Content-Type": "application/json" }
151
- });
152
- }
153
- export const listPendingAsyncActivitiesRestBinding = {
140
+ }), listPendingAsyncActivitiesRestBinding = {
154
141
  method: "GET",
155
142
  path: "/v1/workflows/:id/pending-async-activities",
156
143
  pathParamNames: ["id"],
@@ -168,9 +155,7 @@ export const listPendingAsyncActivitiesRestBinding = {
168
155
  ...cursor === null ? {} : { cursor }
169
156
  };
170
157
  },
171
- success: { kind: "json", status: 200 },
172
- shapeSuccess: (output) => shapePendingAsyncActivitiesSuccess(output),
173
- shapeFault: shapeRestFault
158
+ success: { kind: "json", status: 200 }
174
159
  };
175
160
  async function readJsonObjectBody(request, context) {
176
161
  const body = await readRestJsonBody(request, context).catch((error) => {
@@ -198,9 +183,7 @@ export const completeAsyncActivityRestBinding = {
198
183
  ..."result" in body ? { result: body.result } : {}
199
184
  };
200
185
  },
201
- success: { kind: "json", status: 200 },
202
- shapeSuccess: (output) => shapeAsyncActivitySuccess(output),
203
- shapeFault: shapeRestFault
186
+ success: { kind: "json", status: 200 }
204
187
  }, failAsyncActivityRestBinding = {
205
188
  method: "POST",
206
189
  path: "/v1/activities/fail",
@@ -217,7 +200,5 @@ export const completeAsyncActivityRestBinding = {
217
200
  error: body.error
218
201
  };
219
202
  },
220
- success: { kind: "json", status: 200 },
221
- shapeSuccess: (output) => shapeAsyncActivitySuccess(output),
222
- shapeFault: shapeRestFault
203
+ success: { kind: "json", status: 200 }
223
204
  };
@@ -12,11 +12,8 @@ import {
12
12
  parseBulkOperationControlFromBody,
13
13
  readOptionalJsonBody
14
14
  } from "./bulk-filter-helpers.js";
15
- import {
16
- shapeBulkJsonSuccess,
17
- validatedListFilterFromBulkInput
18
- } from "./bulk-operation-helpers.js";
19
- import { invalidParamsFault, shapeRestFault } from "./operation-helpers.js";
15
+ import { validatedListFilterFromBulkInput } from "./bulk-operation-helpers.js";
16
+ import { invalidParamsFault } from "./operation-helpers.js";
20
17
  const bulkCancelWorkflowsInput = bulkListFilterInputSchema.merge(bulkOperationControlInputSchema), bulkCancelWorkflowsOutput = z.unknown();
21
18
  export const bulkCancelWorkflowsOperation = defineOperation({
22
19
  name: "weft.workflows.bulk.cancel",
@@ -58,7 +55,5 @@ export const bulkCancelWorkflowsOperation = defineOperation({
58
55
  throw invalidParamsFault(faultMessage(error));
59
56
  }
60
57
  },
61
- success: { kind: "json", status: 200 },
62
- shapeSuccess: (output) => shapeBulkJsonSuccess(output),
63
- shapeFault: shapeRestFault
58
+ success: { kind: "json", status: 200 }
64
59
  };
@@ -16,11 +16,8 @@ import {
16
16
  readOptionalJsonBody,
17
17
  unprocessableFault
18
18
  } from "./bulk-filter-helpers.js";
19
- import {
20
- shapeBulkJsonSuccess,
21
- validatedListFilterFromBulkInput
22
- } from "./bulk-operation-helpers.js";
23
- import { invalidParamsFault, shapeRestFault } from "./operation-helpers.js";
19
+ import { validatedListFilterFromBulkInput } from "./bulk-operation-helpers.js";
20
+ import { invalidParamsFault } from "./operation-helpers.js";
24
21
  const bulkDeleteWorkflowsInput = bulkListFilterInputSchema.merge(bulkOperationControlInputSchema), bulkDeleteWorkflowsOutput = z.unknown();
25
22
  export const bulkDeleteWorkflowsOperation = defineOperation({
26
23
  name: "weft.workflows.bulk.delete",
@@ -65,7 +62,5 @@ export const bulkDeleteWorkflowsOperation = defineOperation({
65
62
  throw invalidParamsFault(faultMessage(error));
66
63
  }
67
64
  },
68
- success: { kind: "json", status: 200 },
69
- shapeSuccess: (output) => shapeBulkJsonSuccess(output),
70
- shapeFault: shapeRestFault
65
+ success: { kind: "json", status: 200 }
71
66
  };
@@ -13,11 +13,8 @@ import {
13
13
  parseBulkOperationControlFromBody,
14
14
  readOptionalJsonBody
15
15
  } from "./bulk-filter-helpers.js";
16
- import {
17
- shapeBulkJsonSuccess,
18
- validatedListFilterFromBulkInput
19
- } from "./bulk-operation-helpers.js";
20
- import { invalidParamsFault, shapeRestFault } from "./operation-helpers.js";
16
+ import { validatedListFilterFromBulkInput } from "./bulk-operation-helpers.js";
17
+ import { invalidParamsFault } from "./operation-helpers.js";
21
18
  const bulkMutateWorkflowTagsInput = z.object({
22
19
  filter: bulkListFilterInputSchema.optional(),
23
20
  tags: z.array(z.string()),
@@ -94,7 +91,5 @@ export const bulkMutateWorkflowTagsRestBinding = {
94
91
  ...parseBulkOperationControlFromBody(body)
95
92
  };
96
93
  },
97
- success: { kind: "json", status: 200 },
98
- shapeSuccess: (output) => shapeBulkJsonSuccess(output),
99
- shapeFault: shapeRestFault
94
+ success: { kind: "json", status: 200 }
100
95
  };
@@ -1,4 +1,4 @@
1
- import type { BulkCancelResult, BulkDeleteResult, BulkOperationDryRunResult, BulkRetryFailedResult, BulkSignalResult, BulkTagResult, ListFilter, PurgeResult } from '../../core/types.ts';
1
+ import type { ListFilter } from '../../core/types.ts';
2
2
  import { type BulkListFilterInput } from './bulk-filter-helpers.ts';
3
3
  /**
4
4
  * Coerces filter tags (label `Field "filter.tags"`), builds a `ListFilter`
@@ -13,15 +13,7 @@ import { type BulkListFilterInput } from './bulk-filter-helpers.ts';
13
13
  * runs.
14
14
  *
15
15
  * Not used by `purge-workflows.ts`: purge allows empty/unscoped filters and
16
- * shapes faults through `shapeRestFault` (sanitized) rather than passing
16
+ * uses the canonical REST fault fallback (sanitized) rather than passing
17
17
  * raw engine messages through unmasked.
18
18
  */
19
19
  export declare function validatedListFilterFromBulkInput(input: BulkListFilterInput): ListFilter;
20
- export type BulkOperationSuccessResult = BulkCancelResult | BulkDeleteResult | BulkRetryFailedResult | BulkSignalResult | BulkTagResult | BulkOperationDryRunResult | PurgeResult;
21
- /**
22
- * Standard JSON 200 response shape for bulk-workflow operations. Used by
23
- * every bulk operation's REST `shapeSuccess`; the result types are unioned
24
- * rather than left as `unknown` so the type system catches accidental
25
- * `undefined` / `Response` / `Error` arguments at the call site.
26
- */
27
- export declare function shapeBulkJsonSuccess(result: BulkOperationSuccessResult): Response;
@@ -21,9 +21,3 @@ export function validatedListFilterFromBulkInput(input) {
21
21
  }
22
22
  return filter;
23
23
  }
24
- export function shapeBulkJsonSuccess(result) {
25
- return new Response(JSON.stringify(result), {
26
- status: 200,
27
- headers: { "Content-Type": "application/json" }
28
- });
29
- }
@@ -12,11 +12,8 @@ import {
12
12
  parseBulkOperationControlFromBody,
13
13
  readOptionalJsonBody
14
14
  } from "./bulk-filter-helpers.js";
15
- import {
16
- shapeBulkJsonSuccess,
17
- validatedListFilterFromBulkInput
18
- } from "./bulk-operation-helpers.js";
19
- import { invalidParamsFault, shapeRestFault } from "./operation-helpers.js";
15
+ import { validatedListFilterFromBulkInput } from "./bulk-operation-helpers.js";
16
+ import { invalidParamsFault } from "./operation-helpers.js";
20
17
  const bulkRetryFailedWorkflowsInput = bulkListFilterInputSchema.merge(bulkOperationControlInputSchema), bulkRetryFailedWorkflowsOutput = z.unknown();
21
18
  export const bulkRetryFailedWorkflowsOperation = defineOperation({
22
19
  name: "weft.workflows.bulk.retryfailed",
@@ -58,7 +55,5 @@ export const bulkRetryFailedWorkflowsOperation = defineOperation({
58
55
  throw invalidParamsFault(faultMessage(error));
59
56
  }
60
57
  },
61
- success: { kind: "json", status: 200 },
62
- shapeSuccess: (output) => shapeBulkJsonSuccess(output),
63
- shapeFault: shapeRestFault
58
+ success: { kind: "json", status: 200 }
64
59
  };
@@ -12,11 +12,8 @@ import {
12
12
  parseBulkOperationControlFromBody,
13
13
  readOptionalJsonBody
14
14
  } from "./bulk-filter-helpers.js";
15
- import {
16
- shapeBulkJsonSuccess,
17
- validatedListFilterFromBulkInput
18
- } from "./bulk-operation-helpers.js";
19
- import { invalidParamsFault, shapeRestFault } from "./operation-helpers.js";
15
+ import { validatedListFilterFromBulkInput } from "./bulk-operation-helpers.js";
16
+ import { invalidParamsFault } from "./operation-helpers.js";
20
17
  const bulkSignalWorkflowsInput = bulkListFilterInputSchema.extend({
21
18
  name: z.string().min(1),
22
19
  payload: z.unknown().optional()
@@ -74,7 +71,5 @@ export const bulkSignalWorkflowsOperation = defineOperation({
74
71
  ...parseBulkOperationControlFromBody(body)
75
72
  };
76
73
  },
77
- success: { kind: "json", status: 200 },
78
- shapeSuccess: (output) => shapeBulkJsonSuccess(output),
79
- shapeFault: shapeRestFault
74
+ success: { kind: "json", status: 200 }
80
75
  };
@@ -1,6 +1,5 @@
1
1
  import { z } from "zod";
2
2
  import { defineOperation } from "../operation-registry.js";
3
- import { shapeRestFault } from "./operation-helpers.js";
4
3
  import { mapScheduleErrorToFault } from "./schedule-faults.js";
5
4
  const cancelScheduleInput = z.object({
6
5
  scheduleId: z.string().min(1)
@@ -38,6 +37,5 @@ export const cancelScheduleOperation = defineOperation({
38
37
  extractInput: async (_request, pathParams) => ({
39
38
  scheduleId: pathParams.id ?? ""
40
39
  }),
41
- success: { kind: "empty", status: 204 },
42
- shapeFault: shapeRestFault
40
+ success: { kind: "empty", status: 204 }
43
41
  };
@@ -1,5 +1,4 @@
1
1
  import { z } from "zod";
2
- import { shapeRestFault } from "./operation-helpers.js";
3
2
  import {
4
3
  createSingleWorkflowControlOperation,
5
4
  extractWorkflowIdFromPath
@@ -29,6 +28,5 @@ export const cancelWorkflowOperation = createSingleWorkflowControlOperation({
29
28
  workflowId: { kind: "path", pathParam: "id" }
30
29
  },
31
30
  extractInput: async (_request, pathParams) => extractWorkflowIdFromPath(pathParams),
32
- success: { kind: "empty", status: 204 },
33
- shapeFault: shapeRestFault
31
+ success: { kind: "empty", status: 204 }
34
32
  };
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { defineOperation } from "../operation-registry.js";
3
- import { invalidParamsFault, shapeRestFault } from "./operation-helpers.js";
3
+ import { invalidParamsFault } from "./operation-helpers.js";
4
4
  import {
5
5
  mapScheduleErrorToFault,
6
6
  validateScheduleInputCadence,
@@ -101,6 +101,5 @@ export const createScheduleOperation = defineOperation({
101
101
  ...extractSharedScheduleRestFields(record)
102
102
  };
103
103
  },
104
- success: { kind: "json", status: 201 },
105
- shapeFault: shapeRestFault
104
+ success: { kind: "json", status: 201 }
106
105
  };
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { defineOperation } from "../operation-registry.js";
3
3
  import { readRestTextBody } from "../rest-body.js";
4
- import { invalidParamsFault, shapeRestFault } from "./operation-helpers.js";
4
+ import { invalidParamsFault } from "./operation-helpers.js";
5
5
  const forkWorkflowInput = z.object({
6
6
  workflowId: z.string().min(1),
7
7
  fromStep: z.unknown().optional()
@@ -84,6 +84,5 @@ export const forkWorkflowOperation = defineOperation({
84
84
  fromStep: record.fromStep
85
85
  };
86
86
  },
87
- success: { kind: "json", status: 201 },
88
- shapeFault: shapeRestFault
87
+ success: { kind: "json", status: 201 }
89
88
  };
@@ -1,7 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { negotiatedResponse } from "../handler/response-helpers.js";
3
3
  import { defineOperation } from "../operation-registry.js";
4
- import { shapeRestFault } from "./operation-helpers.js";
5
4
  const getCheckpointAtInput = z.object({
6
5
  workflowId: z.string().min(1),
7
6
  step: z.number().int().nonnegative()
@@ -32,9 +31,6 @@ export const getCheckpointAtOperation = defineOperation({
32
31
  function shapeGetCheckpointAtSuccess(result, request) {
33
32
  return negotiatedResponse(request, result, 200);
34
33
  }
35
- function shapeGetCheckpointAtFault(fault) {
36
- return shapeRestFault(fault);
37
- }
38
34
  export const getCheckpointAtRestBinding = {
39
35
  method: "GET",
40
36
  path: "/v1/workflows/:id/checkpoints/:step",
@@ -69,6 +65,5 @@ export const getCheckpointAtRestBinding = {
69
65
  };
70
66
  },
71
67
  success: { kind: "json", status: 200 },
72
- shapeSuccess: (output, request) => shapeGetCheckpointAtSuccess(output, request),
73
- shapeFault: shapeGetCheckpointAtFault
68
+ shapeSuccess: (output, request) => shapeGetCheckpointAtSuccess(output, request)
74
69
  };
@@ -4,7 +4,6 @@ import {
4
4
  RegistrySchemaConversionError
5
5
  } from "../../core/registry-snapshot.js";
6
6
  import { defineOperation } from "../operation-registry.js";
7
- import { shapeRestFault } from "./operation-helpers.js";
8
7
  const getRegistryInput = z.object({}), objectValue = z.unknown().refine((value) => typeof value === "object" && value !== null && !Array.isArray(value), {
9
8
  message: "expected an object"
10
9
  }), getRegistryOutput = z.object({
@@ -47,10 +46,5 @@ export const getRegistryOperation = defineOperation({
47
46
  operationName: "weft.system.registry",
48
47
  inputSources: {},
49
48
  extractInput: async () => ({}),
50
- success: { kind: "json", status: 200 },
51
- shapeSuccess: (output) => new Response(JSON.stringify(output), {
52
- status: 200,
53
- headers: { "Content-Type": "application/json" }
54
- }),
55
- shapeFault: shapeRestFault
49
+ success: { kind: "json", status: 200 }
56
50
  };
@@ -1,6 +1,5 @@
1
1
  import { z } from "zod";
2
2
  import { defineOperation } from "../operation-registry.js";
3
- import { shapeRestFault } from "./operation-helpers.js";
4
3
  const getRetentionOverviewInput = z.object({}), getRetentionOverviewOutput = z.unknown();
5
4
  export const getRetentionOverviewOperation = defineOperation({
6
5
  name: "weft.retention.get",
@@ -16,24 +15,12 @@ export const getRetentionOverviewOperation = defineOperation({
16
15
  invoke: async ({ engine }) => {
17
16
  return engine.getRetentionOverview();
18
17
  }
19
- });
20
- function shapeGetRetentionOverviewSuccess(result) {
21
- return new Response(JSON.stringify(result), {
22
- status: 200,
23
- headers: { "Content-Type": "application/json" }
24
- });
25
- }
26
- function shapeGetRetentionOverviewFault(fault) {
27
- return shapeRestFault(fault);
28
- }
29
- export const getRetentionOverviewRestBinding = {
18
+ }), getRetentionOverviewRestBinding = {
30
19
  method: "GET",
31
20
  path: "/v1/retention",
32
21
  pathParamNames: [],
33
22
  operationName: "weft.retention.get",
34
23
  inputSources: {},
35
24
  extractInput: async () => ({}),
36
- success: { kind: "json", status: 200 },
37
- shapeSuccess: (output) => shapeGetRetentionOverviewSuccess(output),
38
- shapeFault: shapeGetRetentionOverviewFault
25
+ success: { kind: "json", status: 200 }
39
26
  };
@@ -1,6 +1,5 @@
1
1
  import { z } from "zod";
2
2
  import { defineOperation } from "../operation-registry.js";
3
- import { shapeRestFault } from "./operation-helpers.js";
4
3
  const getReviewInput = z.object({
5
4
  workflowId: z.string().min(1),
6
5
  reviewId: z.string().min(1)
@@ -28,17 +27,7 @@ export const getReviewOperation = defineOperation({
28
27
  };
29
28
  return review;
30
29
  }
31
- });
32
- function shapeGetReviewSuccess(result) {
33
- return new Response(JSON.stringify(result), {
34
- status: 200,
35
- headers: { "Content-Type": "application/json" }
36
- });
37
- }
38
- function shapeGetReviewFault(fault) {
39
- return shapeRestFault(fault);
40
- }
41
- export const getReviewRestBinding = {
30
+ }), getReviewRestBinding = {
42
31
  method: "GET",
43
32
  path: "/v1/workflows/:id/review/:reviewId",
44
33
  pathParamNames: ["id", "reviewId"],
@@ -51,7 +40,5 @@ export const getReviewRestBinding = {
51
40
  workflowId: pathParams.id ?? "",
52
41
  reviewId: pathParams.reviewId ?? ""
53
42
  }),
54
- success: { kind: "json", status: 200 },
55
- shapeSuccess: (output) => shapeGetReviewSuccess(output),
56
- shapeFault: shapeGetReviewFault
43
+ success: { kind: "json", status: 200 }
57
44
  };