robotrock 0.1.0 → 0.3.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.
- package/README.md +190 -33
- package/dist/ai/index.d.ts +24 -0
- package/dist/ai/index.js +46 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/trigger.d.ts +5 -0
- package/dist/ai/trigger.js +24 -0
- package/dist/ai/trigger.js.map +1 -0
- package/dist/ai/workflow.d.ts +5 -0
- package/dist/ai/workflow.js +24 -0
- package/dist/ai/workflow.js.map +1 -0
- package/dist/chunk-D2FBSEZK.js +67 -0
- package/dist/chunk-D2FBSEZK.js.map +1 -0
- package/dist/chunk-DSZ3GMT4.js +518 -0
- package/dist/chunk-DSZ3GMT4.js.map +1 -0
- package/dist/chunk-KOXJCIST.js +332 -0
- package/dist/chunk-KOXJCIST.js.map +1 -0
- package/dist/chunk-LXM7VS4Q.js +129 -0
- package/dist/chunk-LXM7VS4Q.js.map +1 -0
- package/dist/client-Dhk9qxhL.d.ts +104 -0
- package/dist/handler-webhook-BqEi6Bk-.d.ts +16 -0
- package/dist/index.d.ts +84 -33
- package/dist/index.js +117 -38
- package/dist/index.js.map +1 -1
- package/dist/schemas/index.d.ts +643 -0
- package/dist/schemas/index.js +11 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/trigger/index.d.ts +34 -37
- package/dist/trigger/index.js +44 -72
- package/dist/trigger/index.js.map +1 -1
- package/dist/workflow/index.d.ts +35 -0
- package/dist/workflow/index.js +99 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow-BYeIZgD0.d.ts +309 -0
- package/package.json +38 -8
- package/dist/chunk-TUQXDKV6.js +0 -209
- package/dist/chunk-TUQXDKV6.js.map +0 -1
- package/dist/client-BQ-j7q68.d.ts +0 -37
package/dist/index.d.ts
CHANGED
|
@@ -1,53 +1,104 @@
|
|
|
1
|
-
import { R as RobotRockConfig,
|
|
2
|
-
export {
|
|
3
|
-
import {
|
|
4
|
-
export { ApprovalResult,
|
|
1
|
+
import { R as RobotRockConfig, b as RobotRock } from './client-Dhk9qxhL.js';
|
|
2
|
+
export { c as RobotRockError, g as RobotRockPollingClientConfig, i as RobotRockPollingOptions, f as RobotRockWebhookClientConfig, h as RobotRockWebhookConfig, S as SendToHumanActionInput, a as SendToHumanInput, k as SendToHumanResult, j as SendToHumanValidUntil, d as attachWebhookToActions, e as createClient } from './client-Dhk9qxhL.js';
|
|
3
|
+
import { Task, DiscriminatedApprovalResult } from './schemas/index.js';
|
|
4
|
+
export { ApprovalResult, AssignToInput, CreateTaskBody, CreateTaskBodyInput, Handler, InferActionData, TaskAction, TaskContext, TaskContextInput, TaskResponse, TaskResult, TaskStatus, TriggerHandler, TupleElementIndices, WebhookHandler, assignToSchema, createTaskBodySchema, taskContextSchema } from './schemas/index.js';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
export { R as RobotRockHandlerWebhookPayload } from './handler-webhook-BqEi6Bk-.js';
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Read RobotRock client config from environment variables.
|
|
8
10
|
*
|
|
9
11
|
* - `ROBOTROCK_API_KEY` (required when not passed explicitly)
|
|
10
12
|
* - `ROBOTROCK_BASE_URL` or `ROBOTROCK_API_URL` (optional)
|
|
13
|
+
* - `ROBOTROCK_APP` (optional inbox app bucket)
|
|
11
14
|
*/
|
|
12
15
|
declare function resolveRobotRockConfig(overrides?: Partial<RobotRockConfig>): RobotRockConfig;
|
|
13
16
|
/** Use an explicit client or create one from env / optional config overrides. */
|
|
14
17
|
declare function resolveRobotRockClient(client?: RobotRock, configOverrides?: Partial<RobotRockConfig>): RobotRock;
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
type AskHumanTask<A extends readonly TaskAction[]> = Omit<TaskContextInput, "actions"> & {
|
|
18
|
-
readonly actions: A;
|
|
19
|
-
};
|
|
20
|
-
type AskHumanParams<A extends readonly TaskAction[]> = {
|
|
21
|
-
task: AskHumanTask<A>;
|
|
22
|
-
/** Pre-configured client; when omitted, one is created from env / `apiKey` / `baseUrl`. */
|
|
23
|
-
client?: RobotRock;
|
|
24
|
-
apiKey?: string;
|
|
25
|
-
baseUrl?: string;
|
|
26
|
-
/** Poll interval while waiting for a human (ms). @default 2000 */
|
|
27
|
-
pollInterval?: number;
|
|
28
|
-
/** Max wait time (ms). @default 86400000 (24h) */
|
|
29
|
-
timeout?: number;
|
|
30
|
-
} & Pick<CreateTaskOptions, "idempotencyKey">;
|
|
31
|
-
/**
|
|
32
|
-
* Create a human-in-the-loop task and block until someone completes it.
|
|
33
|
-
*
|
|
34
|
-
* Uses polling against the RobotRock API. For durable waits inside Trigger.dev,
|
|
35
|
-
* use `robotrock/trigger` instead.
|
|
36
|
-
*
|
|
37
|
-
* The return type is inferred from `task.actions`: `actionId` narrows `data`.
|
|
38
|
-
*/
|
|
39
|
-
declare function askHuman<const A extends readonly TaskAction[]>(params: AskHumanParams<A>): Promise<DiscriminatedApprovalResult<A>>;
|
|
40
|
-
|
|
41
|
-
declare class AskHumanTimeoutError extends Error {
|
|
19
|
+
declare class TaskTimeoutError extends Error {
|
|
42
20
|
constructor(message: string);
|
|
43
21
|
}
|
|
44
|
-
declare class
|
|
22
|
+
declare class TaskExpiredError extends Error {
|
|
45
23
|
constructor(message: string);
|
|
46
24
|
}
|
|
47
25
|
/**
|
|
48
26
|
* Map a handled API task to a discriminated approval result.
|
|
49
27
|
* Runtime validation is minimal; TypeScript narrows via `task.actions` at the call site.
|
|
50
28
|
*/
|
|
51
|
-
declare function toDiscriminatedApprovalResult<A extends readonly
|
|
29
|
+
declare function toDiscriminatedApprovalResult<A extends readonly {
|
|
30
|
+
id: string;
|
|
31
|
+
schema?: unknown;
|
|
32
|
+
}[]>(actions: A, task: Task): DiscriminatedApprovalResult<A>;
|
|
33
|
+
|
|
34
|
+
declare const robotRockWebhookPayloadSchema: z.ZodObject<{
|
|
35
|
+
taskId: z.ZodString;
|
|
36
|
+
action: z.ZodObject<{
|
|
37
|
+
id: z.ZodString;
|
|
38
|
+
title: z.ZodString;
|
|
39
|
+
data: z.ZodUnknown;
|
|
40
|
+
}, "strip", z.ZodTypeAny, {
|
|
41
|
+
id: string;
|
|
42
|
+
title: string;
|
|
43
|
+
data?: unknown;
|
|
44
|
+
}, {
|
|
45
|
+
id: string;
|
|
46
|
+
title: string;
|
|
47
|
+
data?: unknown;
|
|
48
|
+
}>;
|
|
49
|
+
handledBy: z.ZodOptional<z.ZodString>;
|
|
50
|
+
handledAt: z.ZodString;
|
|
51
|
+
handlerType: z.ZodString;
|
|
52
|
+
} & {
|
|
53
|
+
headers: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
54
|
+
}, "strip", z.ZodTypeAny, {
|
|
55
|
+
headers: Record<string, string>;
|
|
56
|
+
taskId: string;
|
|
57
|
+
handledAt: string;
|
|
58
|
+
action: {
|
|
59
|
+
id: string;
|
|
60
|
+
title: string;
|
|
61
|
+
data?: unknown;
|
|
62
|
+
};
|
|
63
|
+
handlerType: string;
|
|
64
|
+
handledBy?: string | undefined;
|
|
65
|
+
}, {
|
|
66
|
+
headers: Record<string, string>;
|
|
67
|
+
taskId: string;
|
|
68
|
+
handledAt: string;
|
|
69
|
+
action: {
|
|
70
|
+
id: string;
|
|
71
|
+
title: string;
|
|
72
|
+
data?: unknown;
|
|
73
|
+
};
|
|
74
|
+
handlerType: string;
|
|
75
|
+
handledBy?: string | undefined;
|
|
76
|
+
}>;
|
|
77
|
+
type RobotRockWebhookErrorCode = "MISSING_WEBHOOK_SECRET" | "MISSING_SIGNATURE" | "INVALID_SIGNATURE" | "INVALID_JSON" | "INVALID_PAYLOAD";
|
|
78
|
+
declare class RobotRockWebhookError extends Error {
|
|
79
|
+
readonly code: RobotRockWebhookErrorCode;
|
|
80
|
+
readonly details?: unknown | undefined;
|
|
81
|
+
constructor(message: string, code: RobotRockWebhookErrorCode, details?: unknown | undefined);
|
|
82
|
+
}
|
|
83
|
+
type RobotRockWebhookPayload = z.infer<typeof robotRockWebhookPayloadSchema>;
|
|
84
|
+
interface VerifyRobotRockWebhookOptions {
|
|
85
|
+
/**
|
|
86
|
+
* Override shared secret (defaults to ROBOTROCK_WEBHOOK_SECRET).
|
|
87
|
+
* Keep undefined in production to enforce the canonical env var.
|
|
88
|
+
*/
|
|
89
|
+
secret?: string;
|
|
90
|
+
/**
|
|
91
|
+
* Resolve the tenant signing secret by public task id (hosted MCP uses Convex).
|
|
92
|
+
* Used when secret is not passed explicitly.
|
|
93
|
+
*/
|
|
94
|
+
resolveSecret?: (taskId: string) => Promise<string | undefined>;
|
|
95
|
+
/** Signature header to read. @default "x-robotrock-signature" */
|
|
96
|
+
signatureHeader?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Verify a RobotRock webhook request and return a validated payload.
|
|
100
|
+
* Throws RobotRockWebhookError with machine-readable `code` for audit logging.
|
|
101
|
+
*/
|
|
102
|
+
declare function verifyRobotRockWebhook(request: Request, options?: VerifyRobotRockWebhookOptions): Promise<RobotRockWebhookPayload>;
|
|
52
103
|
|
|
53
|
-
export {
|
|
104
|
+
export { DiscriminatedApprovalResult, RobotRock, RobotRockConfig, RobotRockWebhookError, type RobotRockWebhookErrorCode, type RobotRockWebhookPayload, Task, TaskExpiredError, TaskTimeoutError, type VerifyRobotRockWebhookOptions, resolveRobotRockClient, resolveRobotRockConfig, toDiscriminatedApprovalResult, verifyRobotRockWebhook };
|
package/dist/index.js
CHANGED
|
@@ -1,60 +1,139 @@
|
|
|
1
1
|
import {
|
|
2
|
-
AskHumanExpiredError,
|
|
3
|
-
AskHumanTimeoutError,
|
|
4
2
|
RobotRock,
|
|
5
3
|
RobotRockError,
|
|
4
|
+
TaskExpiredError,
|
|
5
|
+
TaskTimeoutError,
|
|
6
|
+
attachWebhookToActions,
|
|
6
7
|
createClient,
|
|
7
8
|
resolveRobotRockClient,
|
|
8
9
|
resolveRobotRockConfig,
|
|
9
|
-
taskContextSchema,
|
|
10
10
|
toDiscriminatedApprovalResult
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-KOXJCIST.js";
|
|
12
|
+
import {
|
|
13
|
+
assignToSchema,
|
|
14
|
+
createTaskBodySchema,
|
|
15
|
+
taskContextSchema
|
|
16
|
+
} from "./chunk-LXM7VS4Q.js";
|
|
12
17
|
|
|
13
|
-
// src/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
// src/webhook.ts
|
|
19
|
+
import { createHmac, timingSafeEqual } from "crypto";
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
var ROBOTROCK_SIGNATURE_HEADER = "x-robotrock-signature";
|
|
22
|
+
var robotRockWebhookPayloadBodySchema = z.object({
|
|
23
|
+
taskId: z.string().min(1),
|
|
24
|
+
action: z.object({
|
|
25
|
+
id: z.string().min(1),
|
|
26
|
+
title: z.string().min(1),
|
|
27
|
+
data: z.unknown()
|
|
28
|
+
}),
|
|
29
|
+
handledBy: z.string().min(1).optional(),
|
|
30
|
+
handledAt: z.string().min(1),
|
|
31
|
+
handlerType: z.string().min(1)
|
|
32
|
+
});
|
|
33
|
+
var robotRockWebhookPayloadSchema = robotRockWebhookPayloadBodySchema.extend({
|
|
34
|
+
headers: z.record(z.string())
|
|
35
|
+
});
|
|
36
|
+
var RobotRockWebhookError = class extends Error {
|
|
37
|
+
constructor(message, code, details) {
|
|
38
|
+
super(message);
|
|
39
|
+
this.code = code;
|
|
40
|
+
this.details = details;
|
|
41
|
+
this.name = "RobotRockWebhookError";
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
async function verifyRobotRockWebhook(request, options = {}) {
|
|
45
|
+
const signatureHeaderName = options.signatureHeader ?? ROBOTROCK_SIGNATURE_HEADER;
|
|
46
|
+
const signature = request.headers.get(signatureHeaderName);
|
|
47
|
+
if (!signature) {
|
|
48
|
+
throw new RobotRockWebhookError(
|
|
49
|
+
`Missing webhook signature header: ${signatureHeaderName}`,
|
|
50
|
+
"MISSING_SIGNATURE"
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
const rawBody = await request.text();
|
|
54
|
+
const secret = await resolveWebhookSigningSecret(rawBody, options);
|
|
55
|
+
if (!secret) {
|
|
56
|
+
throw new RobotRockWebhookError(
|
|
57
|
+
"Missing webhook signing secret for verification",
|
|
58
|
+
"MISSING_WEBHOOK_SECRET"
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
assertValidSignature(rawBody, signature, secret);
|
|
62
|
+
let parsedBody;
|
|
63
|
+
try {
|
|
64
|
+
parsedBody = JSON.parse(rawBody);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
throw new RobotRockWebhookError("Webhook body is not valid JSON", "INVALID_JSON", {
|
|
67
|
+
cause: error instanceof Error ? error.message : String(error)
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const payloadResult = robotRockWebhookPayloadBodySchema.safeParse(parsedBody);
|
|
71
|
+
if (!payloadResult.success) {
|
|
72
|
+
throw new RobotRockWebhookError(
|
|
73
|
+
"Webhook payload schema validation failed",
|
|
74
|
+
"INVALID_PAYLOAD",
|
|
75
|
+
payloadResult.error.flatten()
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
...payloadResult.data,
|
|
80
|
+
headers: normalizeHeaders(request.headers)
|
|
81
|
+
};
|
|
18
82
|
}
|
|
19
|
-
async function
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const response = await client.createTask(
|
|
31
|
-
task,
|
|
32
|
-
{ idempotencyKey }
|
|
33
|
-
);
|
|
34
|
-
const streamId = response.task.streamId;
|
|
35
|
-
const deadline = Date.now() + timeout;
|
|
36
|
-
while (Date.now() < deadline) {
|
|
37
|
-
const existing = await client.getTask(streamId);
|
|
38
|
-
if (existing?.status === "handled" && existing.handled) {
|
|
39
|
-
return toDiscriminatedApprovalResult(task.actions, existing, streamId);
|
|
83
|
+
async function resolveWebhookSigningSecret(rawBody, options) {
|
|
84
|
+
if (options.secret) {
|
|
85
|
+
return options.secret;
|
|
86
|
+
}
|
|
87
|
+
if (options.resolveSecret) {
|
|
88
|
+
const taskId = peekWebhookTaskId(rawBody);
|
|
89
|
+
if (taskId) {
|
|
90
|
+
const resolved = await options.resolveSecret(taskId);
|
|
91
|
+
if (resolved) {
|
|
92
|
+
return resolved;
|
|
93
|
+
}
|
|
40
94
|
}
|
|
41
|
-
|
|
42
|
-
|
|
95
|
+
}
|
|
96
|
+
return process.env.ROBOTROCK_WEBHOOK_SECRET;
|
|
97
|
+
}
|
|
98
|
+
function peekWebhookTaskId(rawBody) {
|
|
99
|
+
try {
|
|
100
|
+
const parsed = JSON.parse(rawBody);
|
|
101
|
+
if (typeof parsed === "object" && parsed !== null && "taskId" in parsed && typeof parsed.taskId === "string") {
|
|
102
|
+
return parsed.taskId;
|
|
43
103
|
}
|
|
44
|
-
|
|
104
|
+
} catch {
|
|
45
105
|
}
|
|
46
|
-
|
|
106
|
+
return void 0;
|
|
107
|
+
}
|
|
108
|
+
function assertValidSignature(rawBody, signature, secret) {
|
|
109
|
+
const expected = `sha256=${createHmac("sha256", secret).update(rawBody).digest("hex")}`;
|
|
110
|
+
const expectedBuffer = Buffer.from(expected);
|
|
111
|
+
const receivedBuffer = Buffer.from(signature);
|
|
112
|
+
if (expectedBuffer.length !== receivedBuffer.length || !timingSafeEqual(expectedBuffer, receivedBuffer)) {
|
|
113
|
+
throw new RobotRockWebhookError("Webhook signature verification failed", "INVALID_SIGNATURE");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function normalizeHeaders(headers) {
|
|
117
|
+
const result = {};
|
|
118
|
+
headers.forEach((value, key) => {
|
|
119
|
+
result[key] = value;
|
|
120
|
+
});
|
|
121
|
+
return result;
|
|
47
122
|
}
|
|
48
123
|
export {
|
|
49
|
-
AskHumanExpiredError,
|
|
50
|
-
AskHumanTimeoutError,
|
|
51
124
|
RobotRock,
|
|
52
125
|
RobotRockError,
|
|
53
|
-
|
|
126
|
+
RobotRockWebhookError,
|
|
127
|
+
TaskExpiredError,
|
|
128
|
+
TaskTimeoutError,
|
|
129
|
+
assignToSchema,
|
|
130
|
+
attachWebhookToActions,
|
|
54
131
|
createClient,
|
|
132
|
+
createTaskBodySchema,
|
|
55
133
|
resolveRobotRockClient,
|
|
56
134
|
resolveRobotRockConfig,
|
|
57
135
|
taskContextSchema,
|
|
58
|
-
toDiscriminatedApprovalResult
|
|
136
|
+
toDiscriminatedApprovalResult,
|
|
137
|
+
verifyRobotRockWebhook
|
|
59
138
|
};
|
|
60
139
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/
|
|
1
|
+
{"version":3,"sources":["../src/webhook.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { z } from \"zod\";\n\nconst ROBOTROCK_SIGNATURE_HEADER = \"x-robotrock-signature\";\n\nconst robotRockWebhookPayloadBodySchema = z.object({\n taskId: z.string().min(1),\n action: z.object({\n id: z.string().min(1),\n title: z.string().min(1),\n data: z.unknown(),\n }),\n handledBy: z.string().min(1).optional(),\n handledAt: z.string().min(1),\n handlerType: z.string().min(1),\n});\n\nconst robotRockWebhookPayloadSchema = robotRockWebhookPayloadBodySchema.extend({\n headers: z.record(z.string()),\n});\n\nexport type RobotRockWebhookErrorCode =\n | \"MISSING_WEBHOOK_SECRET\"\n | \"MISSING_SIGNATURE\"\n | \"INVALID_SIGNATURE\"\n | \"INVALID_JSON\"\n | \"INVALID_PAYLOAD\";\n\nexport class RobotRockWebhookError extends Error {\n constructor(\n message: string,\n public readonly code: RobotRockWebhookErrorCode,\n public readonly details?: unknown\n ) {\n super(message);\n this.name = \"RobotRockWebhookError\";\n }\n}\n\nexport type RobotRockWebhookPayload = z.infer<typeof robotRockWebhookPayloadSchema>;\n\nexport interface VerifyRobotRockWebhookOptions {\n /**\n * Override shared secret (defaults to ROBOTROCK_WEBHOOK_SECRET).\n * Keep undefined in production to enforce the canonical env var.\n */\n secret?: string;\n /**\n * Resolve the tenant signing secret by public task id (hosted MCP uses Convex).\n * Used when secret is not passed explicitly.\n */\n resolveSecret?: (taskId: string) => Promise<string | undefined>;\n /** Signature header to read. @default \"x-robotrock-signature\" */\n signatureHeader?: string;\n}\n\n/**\n * Verify a RobotRock webhook request and return a validated payload.\n * Throws RobotRockWebhookError with machine-readable `code` for audit logging.\n */\nexport async function verifyRobotRockWebhook(\n request: Request,\n options: VerifyRobotRockWebhookOptions = {}\n): Promise<RobotRockWebhookPayload> {\n const signatureHeaderName = options.signatureHeader ?? ROBOTROCK_SIGNATURE_HEADER;\n const signature = request.headers.get(signatureHeaderName);\n\n if (!signature) {\n throw new RobotRockWebhookError(\n `Missing webhook signature header: ${signatureHeaderName}`,\n \"MISSING_SIGNATURE\"\n );\n }\n\n const rawBody = await request.text();\n const secret = await resolveWebhookSigningSecret(rawBody, options);\n\n if (!secret) {\n throw new RobotRockWebhookError(\n \"Missing webhook signing secret for verification\",\n \"MISSING_WEBHOOK_SECRET\"\n );\n }\n\n assertValidSignature(rawBody, signature, secret);\n\n let parsedBody: unknown;\n try {\n parsedBody = JSON.parse(rawBody);\n } catch (error) {\n throw new RobotRockWebhookError(\"Webhook body is not valid JSON\", \"INVALID_JSON\", {\n cause: error instanceof Error ? error.message : String(error),\n });\n }\n\n const payloadResult = robotRockWebhookPayloadBodySchema.safeParse(parsedBody);\n if (!payloadResult.success) {\n throw new RobotRockWebhookError(\n \"Webhook payload schema validation failed\",\n \"INVALID_PAYLOAD\",\n payloadResult.error.flatten()\n );\n }\n\n return {\n ...payloadResult.data,\n headers: normalizeHeaders(request.headers),\n };\n}\n\nasync function resolveWebhookSigningSecret(\n rawBody: string,\n options: VerifyRobotRockWebhookOptions\n): Promise<string | undefined> {\n if (options.secret) {\n return options.secret;\n }\n\n if (options.resolveSecret) {\n const taskId = peekWebhookTaskId(rawBody);\n if (taskId) {\n const resolved = await options.resolveSecret(taskId);\n if (resolved) {\n return resolved;\n }\n }\n }\n\n return process.env.ROBOTROCK_WEBHOOK_SECRET;\n}\n\nfunction peekWebhookTaskId(rawBody: string): string | undefined {\n try {\n const parsed: unknown = JSON.parse(rawBody);\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"taskId\" in parsed &&\n typeof (parsed as { taskId: unknown }).taskId === \"string\"\n ) {\n return (parsed as { taskId: string }).taskId;\n }\n } catch {\n // fall through\n }\n return undefined;\n}\n\nfunction assertValidSignature(rawBody: string, signature: string, secret: string): void {\n const expected = `sha256=${createHmac(\"sha256\", secret).update(rawBody).digest(\"hex\")}`;\n const expectedBuffer = Buffer.from(expected);\n const receivedBuffer = Buffer.from(signature);\n\n if (\n expectedBuffer.length !== receivedBuffer.length ||\n !timingSafeEqual(expectedBuffer, receivedBuffer)\n ) {\n throw new RobotRockWebhookError(\"Webhook signature verification failed\", \"INVALID_SIGNATURE\");\n }\n}\n\nfunction normalizeHeaders(headers: Headers): Record<string, string> {\n const result: Record<string, string> = {};\n headers.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n}\n"],"mappings":"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","names":[]}
|