@transloadit/convex 0.0.2 → 0.0.4
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 +184 -121
- package/dist/client/index.d.ts +100 -60
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +69 -31
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +2 -2
- package/dist/component/_generated/component.d.ts +35 -15
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/_generated/dataModel.d.ts +1 -1
- package/dist/component/_generated/server.d.ts +1 -1
- package/dist/component/apiUtils.d.ts +36 -7
- package/dist/component/apiUtils.d.ts.map +1 -1
- package/dist/component/apiUtils.js +60 -40
- package/dist/component/apiUtils.js.map +1 -1
- package/dist/component/lib.d.ts +71 -49
- package/dist/component/lib.d.ts.map +1 -1
- package/dist/component/lib.js +206 -73
- package/dist/component/lib.js.map +1 -1
- package/dist/component/schema.d.ts +11 -13
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +3 -10
- package/dist/component/schema.js.map +1 -1
- package/dist/debug/index.d.ts +19 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js +49 -0
- package/dist/debug/index.js.map +1 -0
- package/dist/react/index.d.ts +213 -17
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +726 -105
- package/dist/react/index.js.map +1 -1
- package/dist/shared/assemblyUrls.d.ts +10 -0
- package/dist/shared/assemblyUrls.d.ts.map +1 -0
- package/dist/shared/assemblyUrls.js +26 -0
- package/dist/shared/assemblyUrls.js.map +1 -0
- package/dist/shared/errors.d.ts +7 -0
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/errors.js +10 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/pollAssembly.d.ts +12 -0
- package/dist/shared/pollAssembly.d.ts.map +1 -0
- package/dist/shared/pollAssembly.js +50 -0
- package/dist/shared/pollAssembly.js.map +1 -0
- package/dist/shared/resultTypes.d.ts +37 -0
- package/dist/shared/resultTypes.d.ts.map +1 -0
- package/dist/shared/resultTypes.js +2 -0
- package/dist/shared/resultTypes.js.map +1 -0
- package/dist/shared/resultUtils.d.ts +4 -0
- package/dist/shared/resultUtils.d.ts.map +1 -0
- package/dist/shared/resultUtils.js +69 -0
- package/dist/shared/resultUtils.js.map +1 -0
- package/dist/shared/tusUpload.d.ts +13 -0
- package/dist/shared/tusUpload.d.ts.map +1 -0
- package/dist/shared/tusUpload.js +32 -0
- package/dist/shared/tusUpload.js.map +1 -0
- package/dist/test/index.d.ts +65 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +8 -0
- package/dist/test/index.js.map +1 -0
- package/dist/test/nodeModules.d.ts +2 -0
- package/dist/test/nodeModules.d.ts.map +1 -0
- package/dist/test/nodeModules.js +19 -0
- package/dist/test/nodeModules.js.map +1 -0
- package/package.json +53 -15
- package/src/client/index.ts +141 -38
- package/src/component/_generated/api.ts +2 -2
- package/src/component/_generated/component.ts +44 -13
- package/src/component/_generated/dataModel.ts +1 -1
- package/src/component/_generated/server.ts +1 -1
- package/src/component/apiUtils.test.ts +195 -2
- package/src/component/apiUtils.ts +124 -66
- package/src/component/lib.test.ts +243 -7
- package/src/component/lib.ts +302 -90
- package/src/component/schema.ts +3 -13
- package/src/debug/index.ts +84 -0
- package/src/react/index.test.tsx +340 -0
- package/src/react/index.tsx +1105 -152
- package/src/react/uploadWithTus.test.tsx +192 -0
- package/src/shared/assemblyUrls.test.ts +71 -0
- package/src/shared/assemblyUrls.ts +59 -0
- package/src/shared/errors.ts +23 -0
- package/src/shared/pollAssembly.ts +65 -0
- package/src/shared/resultTypes.ts +44 -0
- package/src/shared/resultUtils.test.ts +29 -0
- package/src/shared/resultUtils.ts +71 -0
- package/src/shared/tusUpload.ts +59 -0
- package/src/test/index.ts +10 -0
- package/src/test/nodeModules.ts +19 -0
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { createHmac } from "node:crypto";
|
|
2
|
-
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { describe, expect, test, vi } from "vitest";
|
|
3
3
|
import {
|
|
4
4
|
buildTransloaditParams,
|
|
5
|
+
buildWebhookQueueArgs,
|
|
6
|
+
handleWebhookRequest,
|
|
7
|
+
parseAndVerifyTransloaditWebhook,
|
|
8
|
+
parseTransloaditWebhook,
|
|
5
9
|
signTransloaditParams,
|
|
6
10
|
verifyWebhookSignature,
|
|
7
|
-
} from "./apiUtils.
|
|
11
|
+
} from "./apiUtils.ts";
|
|
8
12
|
|
|
9
13
|
describe("apiUtils", () => {
|
|
10
14
|
test("buildTransloaditParams requires templateId or steps", () => {
|
|
@@ -45,4 +49,193 @@ describe("apiUtils", () => {
|
|
|
45
49
|
|
|
46
50
|
expect(verified).toBe(true);
|
|
47
51
|
});
|
|
52
|
+
|
|
53
|
+
test("parseTransloaditWebhook returns payload and signature", async () => {
|
|
54
|
+
const payload = { ok: "ASSEMBLY_COMPLETED", assembly_id: "asm_123" };
|
|
55
|
+
const formData = new FormData();
|
|
56
|
+
formData.append("transloadit", JSON.stringify(payload));
|
|
57
|
+
formData.append("signature", "sha384:abc");
|
|
58
|
+
|
|
59
|
+
const request = new Request("http://localhost", {
|
|
60
|
+
method: "POST",
|
|
61
|
+
body: formData,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const result = await parseTransloaditWebhook(request);
|
|
65
|
+
expect(result.payload).toEqual(payload);
|
|
66
|
+
expect(result.rawBody).toBe(JSON.stringify(payload));
|
|
67
|
+
expect(result.signature).toBe("sha384:abc");
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("parseTransloaditWebhook throws on missing payload", async () => {
|
|
71
|
+
const request = new Request("http://localhost", {
|
|
72
|
+
method: "POST",
|
|
73
|
+
body: new FormData(),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await expect(parseTransloaditWebhook(request)).rejects.toThrow(
|
|
77
|
+
"Missing transloadit payload",
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("parseAndVerifyTransloaditWebhook verifies signature", async () => {
|
|
82
|
+
const payload = { ok: "ASSEMBLY_COMPLETED", assembly_id: "asm_123" };
|
|
83
|
+
const rawBody = JSON.stringify(payload);
|
|
84
|
+
const secret = "webhook-secret";
|
|
85
|
+
const digest = createHmac("sha384", secret).update(rawBody).digest("hex");
|
|
86
|
+
const formData = new FormData();
|
|
87
|
+
formData.append("transloadit", rawBody);
|
|
88
|
+
formData.append("signature", `sha384:${digest}`);
|
|
89
|
+
|
|
90
|
+
const request = new Request("http://localhost", {
|
|
91
|
+
method: "POST",
|
|
92
|
+
body: formData,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const parsed = await parseAndVerifyTransloaditWebhook(request, {
|
|
96
|
+
authSecret: secret,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
expect(parsed.payload).toEqual(payload);
|
|
100
|
+
expect(parsed.verified).toBe(true);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test("parseAndVerifyTransloaditWebhook rejects invalid signature", async () => {
|
|
104
|
+
const payload = { ok: "ASSEMBLY_COMPLETED", assembly_id: "asm_123" };
|
|
105
|
+
const formData = new FormData();
|
|
106
|
+
formData.append("transloadit", JSON.stringify(payload));
|
|
107
|
+
formData.append("signature", "sha384:bad");
|
|
108
|
+
|
|
109
|
+
const request = new Request("http://localhost", {
|
|
110
|
+
method: "POST",
|
|
111
|
+
body: formData,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
await expect(
|
|
115
|
+
parseAndVerifyTransloaditWebhook(request, {
|
|
116
|
+
authSecret: "secret",
|
|
117
|
+
}),
|
|
118
|
+
).rejects.toThrow("Invalid Transloadit webhook signature");
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("buildWebhookQueueArgs returns webhook payload args", async () => {
|
|
122
|
+
const payload = { ok: "ASSEMBLY_COMPLETED", assembly_id: "asm_123" };
|
|
123
|
+
const rawBody = JSON.stringify(payload);
|
|
124
|
+
const secret = "webhook-secret";
|
|
125
|
+
const digest = createHmac("sha384", secret).update(rawBody).digest("hex");
|
|
126
|
+
const formData = new FormData();
|
|
127
|
+
formData.append("transloadit", rawBody);
|
|
128
|
+
formData.append("signature", `sha384:${digest}`);
|
|
129
|
+
|
|
130
|
+
const request = new Request("http://localhost", {
|
|
131
|
+
method: "POST",
|
|
132
|
+
body: formData,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const args = await buildWebhookQueueArgs(request, { authSecret: secret });
|
|
136
|
+
expect(args.payload).toEqual(payload);
|
|
137
|
+
expect(args.rawBody).toBe(rawBody);
|
|
138
|
+
expect(args.signature).toBe(`sha384:${digest}`);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test("buildWebhookQueueArgs can skip verification", async () => {
|
|
142
|
+
const payload = { ok: "ASSEMBLY_COMPLETED", assembly_id: "asm_123" };
|
|
143
|
+
const rawBody = JSON.stringify(payload);
|
|
144
|
+
const formData = new FormData();
|
|
145
|
+
formData.append("transloadit", rawBody);
|
|
146
|
+
|
|
147
|
+
const request = new Request("http://localhost", {
|
|
148
|
+
method: "POST",
|
|
149
|
+
body: formData,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const args = await buildWebhookQueueArgs(request, {
|
|
153
|
+
authSecret: "secret",
|
|
154
|
+
requireSignature: false,
|
|
155
|
+
});
|
|
156
|
+
expect(args.payload).toEqual(payload);
|
|
157
|
+
expect(args.rawBody).toBe(rawBody);
|
|
158
|
+
expect(args.signature).toBeUndefined();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test("handleWebhookRequest queues webhook by default", async () => {
|
|
162
|
+
const payload = { ok: "ASSEMBLY_COMPLETED", assembly_id: "asm_123" };
|
|
163
|
+
const rawBody = JSON.stringify(payload);
|
|
164
|
+
const formData = new FormData();
|
|
165
|
+
formData.append("transloadit", rawBody);
|
|
166
|
+
formData.append("signature", "sha384:abc");
|
|
167
|
+
|
|
168
|
+
const request = new Request("http://localhost", {
|
|
169
|
+
method: "POST",
|
|
170
|
+
body: formData,
|
|
171
|
+
});
|
|
172
|
+
const runAction = vi.fn().mockResolvedValue(null);
|
|
173
|
+
|
|
174
|
+
const response = await handleWebhookRequest(request, {
|
|
175
|
+
runAction,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
expect(runAction).toHaveBeenCalledWith({
|
|
179
|
+
payload,
|
|
180
|
+
rawBody,
|
|
181
|
+
signature: "sha384:abc",
|
|
182
|
+
});
|
|
183
|
+
expect(response.status).toBe(202);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
test("handleWebhookRequest supports sync mode with verification", async () => {
|
|
187
|
+
const payload = { ok: "ASSEMBLY_COMPLETED", assembly_id: "asm_123" };
|
|
188
|
+
const rawBody = JSON.stringify(payload);
|
|
189
|
+
const secret = "webhook-secret";
|
|
190
|
+
const digest = createHmac("sha384", secret).update(rawBody).digest("hex");
|
|
191
|
+
const formData = new FormData();
|
|
192
|
+
formData.append("transloadit", rawBody);
|
|
193
|
+
formData.append("signature", `sha384:${digest}`);
|
|
194
|
+
|
|
195
|
+
const request = new Request("http://localhost", {
|
|
196
|
+
method: "POST",
|
|
197
|
+
body: formData,
|
|
198
|
+
});
|
|
199
|
+
const runAction = vi.fn().mockResolvedValue(null);
|
|
200
|
+
|
|
201
|
+
const response = await handleWebhookRequest(request, {
|
|
202
|
+
mode: "sync",
|
|
203
|
+
runAction,
|
|
204
|
+
requireSignature: true,
|
|
205
|
+
authSecret: secret,
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
expect(runAction).toHaveBeenCalledWith({
|
|
209
|
+
payload,
|
|
210
|
+
rawBody,
|
|
211
|
+
signature: `sha384:${digest}`,
|
|
212
|
+
});
|
|
213
|
+
expect(response.status).toBe(204);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
test("handleWebhookRequest honors a custom response status", async () => {
|
|
217
|
+
const payload = { ok: "ASSEMBLY_COMPLETED", assembly_id: "asm_123" };
|
|
218
|
+
const rawBody = JSON.stringify(payload);
|
|
219
|
+
const formData = new FormData();
|
|
220
|
+
formData.append("transloadit", rawBody);
|
|
221
|
+
formData.append("signature", "sha384:abc");
|
|
222
|
+
|
|
223
|
+
const request = new Request("http://localhost", {
|
|
224
|
+
method: "POST",
|
|
225
|
+
body: formData,
|
|
226
|
+
});
|
|
227
|
+
const runAction = vi.fn().mockResolvedValue(null);
|
|
228
|
+
|
|
229
|
+
const response = await handleWebhookRequest(request, {
|
|
230
|
+
runAction,
|
|
231
|
+
responseStatus: 299,
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
expect(runAction).toHaveBeenCalledWith({
|
|
235
|
+
payload,
|
|
236
|
+
rawBody,
|
|
237
|
+
signature: "sha384:abc",
|
|
238
|
+
});
|
|
239
|
+
expect(response.status).toBe(299);
|
|
240
|
+
});
|
|
48
241
|
});
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { signParams, verifyWebhookSignature } from "@transloadit/utils";
|
|
2
|
+
import type { AssemblyStatusResults } from "@transloadit/zod/v3/assemblyStatus";
|
|
3
|
+
import type { AssemblyInstructionsInput } from "@transloadit/zod/v3/template";
|
|
4
|
+
import { transloaditError } from "../shared/errors.ts";
|
|
5
|
+
|
|
1
6
|
export interface TransloaditAuthConfig {
|
|
2
7
|
authKey: string;
|
|
3
8
|
authSecret: string;
|
|
@@ -6,8 +11,8 @@ export interface TransloaditAuthConfig {
|
|
|
6
11
|
export interface BuildParamsOptions {
|
|
7
12
|
authKey: string;
|
|
8
13
|
templateId?: string;
|
|
9
|
-
steps?:
|
|
10
|
-
fields?:
|
|
14
|
+
steps?: AssemblyInstructionsInput["steps"];
|
|
15
|
+
fields?: AssemblyInstructionsInput["fields"];
|
|
11
16
|
notifyUrl?: string;
|
|
12
17
|
numExpectedUploadFiles?: number;
|
|
13
18
|
expires?: string;
|
|
@@ -23,7 +28,10 @@ export function buildTransloaditParams(
|
|
|
23
28
|
options: BuildParamsOptions,
|
|
24
29
|
): BuildParamsResult {
|
|
25
30
|
if (!options.templateId && !options.steps) {
|
|
26
|
-
throw
|
|
31
|
+
throw transloaditError(
|
|
32
|
+
"createAssembly",
|
|
33
|
+
"Provide either templateId or steps to create an Assembly",
|
|
34
|
+
);
|
|
27
35
|
}
|
|
28
36
|
|
|
29
37
|
const auth: Record<string, string> = {
|
|
@@ -59,90 +67,140 @@ export function buildTransloaditParams(
|
|
|
59
67
|
};
|
|
60
68
|
}
|
|
61
69
|
|
|
62
|
-
async function hmacHex(
|
|
63
|
-
algorithm: "SHA-384" | "SHA-1",
|
|
64
|
-
key: string,
|
|
65
|
-
data: string,
|
|
66
|
-
): Promise<string> {
|
|
67
|
-
if (globalThis.crypto?.subtle) {
|
|
68
|
-
const encoder = new TextEncoder();
|
|
69
|
-
const cryptoKey = await globalThis.crypto.subtle.importKey(
|
|
70
|
-
"raw",
|
|
71
|
-
encoder.encode(key),
|
|
72
|
-
{ name: "HMAC", hash: { name: algorithm } },
|
|
73
|
-
false,
|
|
74
|
-
["sign"],
|
|
75
|
-
);
|
|
76
|
-
const signature = await globalThis.crypto.subtle.sign(
|
|
77
|
-
"HMAC",
|
|
78
|
-
cryptoKey,
|
|
79
|
-
encoder.encode(data),
|
|
80
|
-
);
|
|
81
|
-
const bytes = new Uint8Array(signature);
|
|
82
|
-
return Array.from(bytes)
|
|
83
|
-
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
84
|
-
.join("");
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const { createHmac } = await import("node:crypto");
|
|
88
|
-
return createHmac(algorithm.replace("-", "").toLowerCase(), key)
|
|
89
|
-
.update(data)
|
|
90
|
-
.digest("hex");
|
|
91
|
-
}
|
|
92
|
-
|
|
93
70
|
export async function signTransloaditParams(
|
|
94
71
|
paramsString: string,
|
|
95
72
|
authSecret: string,
|
|
96
73
|
): Promise<string> {
|
|
97
|
-
|
|
98
|
-
return `sha384:${signature}`;
|
|
74
|
+
return signParams(paramsString, authSecret, "sha384");
|
|
99
75
|
}
|
|
100
76
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
77
|
+
export type ParsedWebhookRequest = {
|
|
78
|
+
payload: unknown;
|
|
79
|
+
rawBody: string;
|
|
80
|
+
signature?: string;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export type VerifiedWebhookRequest = ParsedWebhookRequest & {
|
|
84
|
+
verified: boolean;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export async function parseTransloaditWebhook(
|
|
88
|
+
request: Request,
|
|
89
|
+
): Promise<ParsedWebhookRequest> {
|
|
90
|
+
const formData = await request.formData();
|
|
91
|
+
const rawPayload = formData.get("transloadit");
|
|
92
|
+
const signature = formData.get("signature");
|
|
93
|
+
|
|
94
|
+
if (typeof rawPayload !== "string") {
|
|
95
|
+
throw transloaditError("webhook", "Missing transloadit payload");
|
|
106
96
|
}
|
|
107
|
-
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
payload: JSON.parse(rawPayload),
|
|
100
|
+
rawBody: rawPayload,
|
|
101
|
+
signature: typeof signature === "string" ? signature : undefined,
|
|
102
|
+
};
|
|
108
103
|
}
|
|
109
104
|
|
|
110
|
-
export async function
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
105
|
+
export async function parseAndVerifyTransloaditWebhook(
|
|
106
|
+
request: Request,
|
|
107
|
+
options: {
|
|
108
|
+
authSecret: string;
|
|
109
|
+
requireSignature?: boolean;
|
|
110
|
+
},
|
|
111
|
+
): Promise<VerifiedWebhookRequest> {
|
|
112
|
+
const parsed = await parseTransloaditWebhook(request);
|
|
113
|
+
const authSecret = options.authSecret;
|
|
114
|
+
if (!authSecret) {
|
|
115
|
+
throw transloaditError(
|
|
116
|
+
"webhook",
|
|
117
|
+
"Missing authSecret for webhook verification",
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
const verified = await verifyWebhookSignature({
|
|
121
|
+
rawBody: parsed.rawBody,
|
|
122
|
+
signatureHeader: parsed.signature,
|
|
123
|
+
authSecret,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
if (options.requireSignature ?? true) {
|
|
127
|
+
if (!verified) {
|
|
128
|
+
throw transloaditError(
|
|
129
|
+
"webhook",
|
|
130
|
+
"Invalid Transloadit webhook signature",
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
116
134
|
|
|
117
|
-
|
|
118
|
-
|
|
135
|
+
return { ...parsed, verified };
|
|
136
|
+
}
|
|
119
137
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
138
|
+
export async function buildWebhookQueueArgs(
|
|
139
|
+
request: Request,
|
|
140
|
+
options: {
|
|
141
|
+
authSecret: string;
|
|
142
|
+
requireSignature?: boolean;
|
|
143
|
+
},
|
|
144
|
+
): Promise<ParsedWebhookRequest> {
|
|
145
|
+
if (options.requireSignature === false) {
|
|
146
|
+
return parseTransloaditWebhook(request);
|
|
147
|
+
}
|
|
123
148
|
|
|
124
|
-
const
|
|
125
|
-
|
|
149
|
+
const parsed = await parseAndVerifyTransloaditWebhook(request, options);
|
|
150
|
+
return {
|
|
151
|
+
payload: parsed.payload,
|
|
152
|
+
rawBody: parsed.rawBody,
|
|
153
|
+
signature: parsed.signature,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
126
156
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
157
|
+
export type WebhookActionArgs = {
|
|
158
|
+
payload: unknown;
|
|
159
|
+
rawBody?: string;
|
|
160
|
+
signature?: string;
|
|
161
|
+
};
|
|
130
162
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
163
|
+
export async function handleWebhookRequest(
|
|
164
|
+
request: Request,
|
|
165
|
+
options: {
|
|
166
|
+
mode?: "queue" | "sync";
|
|
167
|
+
runAction: (args: WebhookActionArgs) => Promise<unknown>;
|
|
168
|
+
requireSignature?: boolean;
|
|
169
|
+
authSecret?: string;
|
|
170
|
+
responseStatus?: number;
|
|
171
|
+
},
|
|
172
|
+
): Promise<Response> {
|
|
173
|
+
const mode = options.mode ?? "queue";
|
|
174
|
+
const requireSignature = options.requireSignature ?? false;
|
|
175
|
+
|
|
176
|
+
const parsed = requireSignature
|
|
177
|
+
? await parseAndVerifyTransloaditWebhook(request, {
|
|
178
|
+
authSecret: options.authSecret ?? "",
|
|
179
|
+
requireSignature: true,
|
|
180
|
+
})
|
|
181
|
+
: await parseTransloaditWebhook(request);
|
|
182
|
+
|
|
183
|
+
await options.runAction({
|
|
184
|
+
payload: parsed.payload,
|
|
185
|
+
rawBody: parsed.rawBody,
|
|
186
|
+
signature: parsed.signature,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const status = options.responseStatus ?? (mode === "sync" ? 204 : 202);
|
|
190
|
+
return new Response(null, { status });
|
|
137
191
|
}
|
|
138
192
|
|
|
193
|
+
export { verifyWebhookSignature };
|
|
194
|
+
|
|
195
|
+
export type AssemblyResult = AssemblyStatusResults[string][number];
|
|
196
|
+
|
|
139
197
|
export type AssemblyResultRecord = {
|
|
140
198
|
stepName: string;
|
|
141
|
-
result:
|
|
199
|
+
result: AssemblyResult;
|
|
142
200
|
};
|
|
143
201
|
|
|
144
202
|
export function flattenResults(
|
|
145
|
-
results:
|
|
203
|
+
results: AssemblyStatusResults | undefined,
|
|
146
204
|
): AssemblyResultRecord[] {
|
|
147
205
|
if (!results) return [];
|
|
148
206
|
const output: AssemblyResultRecord[] = [];
|