@sentry/junior 0.109.0 → 0.110.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 (92) hide show
  1. package/dist/{agent-hooks-FHHVLNPA.js → agent-hooks-ELT4ODFF.js} +12 -13
  2. package/dist/api/conversations/access.d.ts +9 -0
  3. package/dist/api/conversations/aggregate.d.ts +12 -1
  4. package/dist/api/conversations/archive.d.ts +3 -5
  5. package/dist/api/conversations/detail.d.ts +156 -7
  6. package/dist/api/conversations/events.d.ts +1 -1
  7. package/dist/api/conversations/list.d.ts +57 -6
  8. package/dist/api/conversations/projection.d.ts +6 -7
  9. package/dist/api/conversations/reporting.d.ts +10 -4
  10. package/dist/api/conversations/routes.d.ts +2 -1
  11. package/dist/api/conversations/shared.d.ts +1 -1
  12. package/dist/api/conversations/stats.d.ts +37 -6
  13. package/dist/api/conversations/stats.query.d.ts +1 -1
  14. package/dist/api/conversations/usage.d.ts +9 -0
  15. package/dist/api/http.d.ts +7 -0
  16. package/dist/api/locations/detail.d.ts +102 -6
  17. package/dist/api/locations/list.d.ts +43 -5
  18. package/dist/api/locations/query.d.ts +4 -2
  19. package/dist/api/locations/routes.d.ts +2 -1
  20. package/dist/api/people/list.d.ts +28 -6
  21. package/dist/api/people/list.query.d.ts +1 -1
  22. package/dist/api/people/profile.d.ts +96 -7
  23. package/dist/api/people/profile.query.d.ts +4 -2
  24. package/dist/api/people/routes.d.ts +2 -1
  25. package/dist/api/people/shared.d.ts +1219 -2
  26. package/dist/api/route.d.ts +18 -4
  27. package/dist/api/schema/common.d.ts +6 -0
  28. package/dist/api/{conversations/schema.d.ts → schema/conversation.d.ts} +31 -3
  29. package/dist/api/{locations/schema.d.ts → schema/location.d.ts} +5 -0
  30. package/dist/api/{people/schema.d.ts → schema/person.d.ts} +37 -45
  31. package/dist/api/schema.d.ts +8 -22
  32. package/dist/api/schema.js +10 -2
  33. package/dist/api.d.ts +5 -1
  34. package/dist/api.js +767 -384
  35. package/dist/app.js +87 -70
  36. package/dist/catalog-runtime-4GI22PXK.js +16 -0
  37. package/dist/chat/agent/resume.d.ts +11 -12
  38. package/dist/chat/conversations/history.d.ts +3 -0
  39. package/dist/chat/conversations/sql/privacy.d.ts +3 -15
  40. package/dist/chat/pi/messages.d.ts +2 -2
  41. package/dist/chat/pi/sql-model-usage.d.ts +4 -1
  42. package/dist/chat/services/auth-pause.d.ts +4 -0
  43. package/dist/chat/services/context-compaction.d.ts +1 -0
  44. package/dist/chat/task-execution/queue-signing.d.ts +10 -8
  45. package/dist/chat/task-execution/queue.d.ts +9 -7
  46. package/dist/chat/task-execution/slack-work.d.ts +6 -6
  47. package/dist/{chunk-QY636HZU.js → chunk-2T7TIEXI.js} +90 -7
  48. package/dist/{chunk-CEA3A3UA.js → chunk-2ZTTXTSZ.js} +24 -1
  49. package/dist/{chunk-FWJRXN4F.js → chunk-3S7YYHBI.js} +3 -139
  50. package/dist/{chunk-3SXUV423.js → chunk-3TV7OEHL.js} +1 -1
  51. package/dist/{chunk-MXW4GL53.js → chunk-3UBQI73J.js} +7 -7
  52. package/dist/{chunk-IVVGFRQQ.js → chunk-42WRQLJ6.js} +10 -38
  53. package/dist/{chunk-FENLIFJD.js → chunk-4QU44P7Q.js} +69 -10
  54. package/dist/{chunk-O3JMSZLI.js → chunk-6Y5L4BOM.js} +3 -5
  55. package/dist/{chunk-PLB7MRCQ.js → chunk-C4MZ3GP5.js} +1 -1
  56. package/dist/{chunk-72OMGPDS.js → chunk-C5XAFTHY.js} +7 -9
  57. package/dist/{chunk-HHVY4SMP.js → chunk-FPK7XY3F.js} +98 -92
  58. package/dist/{chunk-OUHNWH46.js → chunk-GK47NBDE.js} +1 -1
  59. package/dist/{chunk-ISMWX44P.js → chunk-IYKPU7H6.js} +2 -2
  60. package/dist/{chunk-TMBRFULF.js → chunk-JQFJO5WH.js} +7 -1
  61. package/dist/{chunk-RGX4V75M.js → chunk-L5XQPJ7T.js} +3 -3
  62. package/dist/{chunk-7Q6WCISF.js → chunk-MIAKQNYX.js} +43 -31
  63. package/dist/{chunk-IXKSQGIO.js → chunk-RHHRKSPI.js} +178 -142
  64. package/dist/{chunk-WHMOBKT7.js → chunk-SBOBTS27.js} +2 -2
  65. package/dist/{chunk-HO5NT6OE.js → chunk-W6RJZG7F.js} +4 -4
  66. package/dist/chunk-W75ZPAGG.js +44 -0
  67. package/dist/{chunk-JNAVF45E.js → chunk-WNOVRQ67.js} +2 -2
  68. package/dist/{chunk-TT6GMXNA.js → chunk-Y3H2DN6F.js} +2 -2
  69. package/dist/{chunk-MGUMR35T.js → chunk-Y5FK3CNG.js} +1 -1
  70. package/dist/{chunk-OCD3OZRK.js → chunk-ZKIOWEFL.js} +1 -1
  71. package/dist/cli/chat.js +23 -24
  72. package/dist/cli/check.js +8 -8
  73. package/dist/cli/plugins.js +15 -16
  74. package/dist/cli/snapshot-warmup.js +11 -11
  75. package/dist/cli/upgrade.js +9 -9
  76. package/dist/db/schema/conversations.d.ts +17 -0
  77. package/dist/db/schema.d.ts +17 -0
  78. package/dist/{db-V3NU72O2.js → db-Y6W6CWWW.js} +8 -9
  79. package/dist/instrumentation.js +4 -4
  80. package/dist/nitro.js +3 -4
  81. package/dist/reporting-schema.d.ts +46 -0
  82. package/dist/{runner-JYBCQBLK.js → runner-BBFV5GLR.js} +14 -15
  83. package/dist/{skills-U6MDAST7.js → skills-AR4AF32L.js} +8 -8
  84. package/dist/{validation-72N3JVRU.js → validation-FBIEPTC2.js} +8 -8
  85. package/dist/version.js +1 -1
  86. package/migrations/0007_thick_sugar_man.sql +23 -0
  87. package/migrations/meta/0007_snapshot.json +1013 -0
  88. package/migrations/meta/_journal.json +7 -0
  89. package/package.json +5 -5
  90. package/dist/catalog-runtime-DMGJSLV2.js +0 -16
  91. package/dist/chunk-OB42YVAE.js +0 -16
  92. package/dist/chunk-SYAQIR5Z.js +0 -53
@@ -5,39 +5,11 @@ import {
5
5
  juniorDestinationKindSchema
6
6
  } from "./chunk-VFUK3X5B.js";
7
7
 
8
- // src/api/activity.ts
8
+ // src/api/schema/common.ts
9
9
  import { z } from "zod";
10
- var dailyConversationActivitySchema = z.object({
11
- active: z.number(),
12
- conversations: z.number(),
13
- date: z.string(),
14
- durationMs: z.number(),
15
- failed: z.number(),
16
- tokens: z.number().optional()
17
- }).strict();
18
- function emptyActivityDay(date) {
19
- return {
20
- active: 0,
21
- conversations: 0,
22
- date,
23
- durationMs: 0,
24
- failed: 0
25
- };
26
- }
27
- function activityDays(days, nowMs, count) {
28
- const items = [];
29
- const end = new Date(nowMs);
30
- end.setUTCHours(0, 0, 0, 0);
31
- const start = new Date(end);
32
- start.setUTCDate(start.getUTCDate() - (count - 1));
33
- for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setUTCDate(cursor.getUTCDate() + 1)) {
34
- const date = cursor.toISOString().slice(0, 10);
35
- items.push(days.get(date) ?? emptyActivityDay(date));
36
- }
37
- return items;
38
- }
10
+ var apiErrorSchema = z.object({ error: z.string().min(1) }).strict();
39
11
 
40
- // src/api/conversations/schema.ts
12
+ // src/api/schema/conversation.ts
41
13
  import { z as z2 } from "zod";
42
14
  var conversationReportStatusSchema = z2.enum([
43
15
  "active",
@@ -51,6 +23,12 @@ var conversationSurfaceSchema = z2.enum([
51
23
  "slack"
52
24
  ]);
53
25
  var conversationUsageSchema = usageSchema;
26
+ var conversationParamsSchema = z2.object({ conversationId: z2.string().min(1) }).strict();
27
+ var conversationFeedQuerySchema = z2.object({
28
+ actorEmail: z2.string().trim().email().transform((value) => value.toLowerCase()).optional()
29
+ }).strict();
30
+ var archiveConversationBodySchema = z2.object({ archived: z2.boolean(), lastSeenAt: z2.string().datetime() }).strict();
31
+ var archiveConversationResponseSchema = z2.object({ archived: z2.boolean() }).strict();
54
32
  var actorIdentitySchema = z2.object({
55
33
  email: z2.string().optional(),
56
34
  fullName: z2.string().optional(),
@@ -62,6 +40,7 @@ var conversationSummaryReportSchema = z2.object({
62
40
  cumulativeDurationMs: z2.number(),
63
41
  cumulativeUsage: conversationUsageSchema.optional(),
64
42
  conversationId: z2.string(),
43
+ isParticipant: z2.boolean(),
65
44
  status: conversationReportStatusSchema,
66
45
  startedAt: z2.string(),
67
46
  lastSeenAt: z2.string(),
@@ -134,6 +113,9 @@ var conversationReportTurnLifecycleEventDataSchema = z2.discriminatedUnion(
134
113
  var conversationReportCompactionEventDataSchema = z2.object({ type: z2.literal("compaction") }).strict();
135
114
  var conversationReportHandoffEventDataSchema = z2.object({
136
115
  type: z2.literal("handoff"),
116
+ modelProfile: z2.string().min(1),
117
+ modelId: z2.string().min(1),
118
+ reasoningLevel: z2.string().min(1).optional(),
137
119
  triggeringToolCallId: z2.string().min(1).optional()
138
120
  }).strict();
139
121
  var conversationReportSubagentStartedEventDataSchema = z2.object({
@@ -271,15 +253,9 @@ var conversationStatsReportSchema = z2.object({
271
253
  windowStart: z2.string()
272
254
  }).strict();
273
255
 
274
- // src/api/people/schema.ts
256
+ // src/api/activity.ts
275
257
  import { z as z3 } from "zod";
276
- var peopleConversationSummaryReportSchema = conversationSummaryReportSchema.omit({
277
- cumulativeUsage: true,
278
- sentryTraceUrl: true,
279
- traceId: true
280
- });
281
- var peopleConversationStatsItemSchema = conversationStatsItemSchema.omit({ costUsd: true });
282
- var actorActivityDayReportSchema = z3.object({
258
+ var dailyConversationActivitySchema = z3.object({
283
259
  active: z3.number(),
284
260
  conversations: z3.number(),
285
261
  date: z3.string(),
@@ -287,48 +263,31 @@ var actorActivityDayReportSchema = z3.object({
287
263
  failed: z3.number(),
288
264
  tokens: z3.number().optional()
289
265
  }).strict();
290
- var peopleActivityDayReportSchema = z3.object({
291
- activePeople: z3.number(),
292
- conversations: z3.number(),
293
- date: z3.string()
294
- }).strict();
295
- var actorTotalsReportSchema = z3.object({
296
- active: z3.number(),
297
- activeDays: z3.number(),
298
- conversations: z3.number(),
299
- durationMs: z3.number(),
300
- failed: z3.number(),
301
- tokens: z3.number().optional()
302
- }).strict();
303
- var identifiedActorSchema = actorIdentitySchema.extend({ email: z3.string().min(1) }).strict();
304
- var actorSummaryReportSchema = actorTotalsReportSchema.extend({
305
- firstSeenAt: z3.string(),
306
- lastSeenAt: z3.string(),
307
- actor: identifiedActorSchema
308
- }).strict();
309
- var actorDirectoryReportSchema = z3.object({
310
- activityDays: z3.array(peopleActivityDayReportSchema),
311
- generatedAt: z3.string(),
312
- people: z3.array(actorSummaryReportSchema),
313
- source: z3.literal("conversation_index"),
314
- windowEnd: z3.string(),
315
- windowStart: z3.string()
316
- }).strict();
317
- var actorProfileReportSchema = z3.object({
318
- activityDays: z3.array(actorActivityDayReportSchema),
319
- generatedAt: z3.string(),
320
- locations: z3.array(peopleConversationStatsItemSchema),
321
- recentConversations: z3.array(peopleConversationSummaryReportSchema),
322
- actor: identifiedActorSchema,
323
- source: z3.literal("conversation_index"),
324
- surfaces: z3.array(peopleConversationStatsItemSchema),
325
- totals: actorTotalsReportSchema,
326
- windowEnd: z3.string(),
327
- windowStart: z3.string()
328
- }).strict();
266
+ function emptyActivityDay(date) {
267
+ return {
268
+ active: 0,
269
+ conversations: 0,
270
+ date,
271
+ durationMs: 0,
272
+ failed: 0
273
+ };
274
+ }
275
+ function activityDays(days, nowMs, count) {
276
+ const items = [];
277
+ const end = new Date(nowMs);
278
+ end.setUTCHours(0, 0, 0, 0);
279
+ const start = new Date(end);
280
+ start.setUTCDate(start.getUTCDate() - (count - 1));
281
+ for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setUTCDate(cursor.getUTCDate() + 1)) {
282
+ const date = cursor.toISOString().slice(0, 10);
283
+ items.push(days.get(date) ?? emptyActivityDay(date));
284
+ }
285
+ return items;
286
+ }
329
287
 
330
- // src/api/locations/schema.ts
288
+ // src/api/schema/location.ts
331
289
  import { z as z4 } from "zod";
290
+ var locationParamsSchema = z4.object({ locationId: z4.string().min(1) }).strict();
332
291
  var locationSummaryReportSchema = conversationStatsItemSchema.extend({
333
292
  id: z4.string(),
334
293
  firstSeenAt: z4.string(),
@@ -363,31 +322,78 @@ var locationDetailReportSchema = locationSummaryReportSchema.extend({
363
322
  windowStart: z4.string()
364
323
  }).strict();
365
324
 
366
- // src/api/schema.ts
325
+ // src/api/schema/person.ts
367
326
  import { z as z5 } from "zod";
368
- var conversationParamsSchema = z5.object({ conversationId: z5.string().min(1) }).strict();
369
- var conversationFeedQuerySchema = z5.object({
370
- actorEmail: z5.string().trim().email().transform((value) => value.toLowerCase()).optional()
371
- }).strict();
372
327
  var personParamsSchema = z5.object({ email: z5.string().trim().min(1) }).strict();
373
- var locationParamsSchema = z5.object({ locationId: z5.string().min(1) }).strict();
328
+ var peopleConversationStatsItemSchema = conversationStatsItemSchema.omit({ costUsd: true });
329
+ var actorActivityDayReportSchema = z5.object({
330
+ active: z5.number(),
331
+ conversations: z5.number(),
332
+ date: z5.string(),
333
+ durationMs: z5.number(),
334
+ failed: z5.number(),
335
+ tokens: z5.number().optional()
336
+ }).strict();
337
+ var peopleActivityDayReportSchema = z5.object({
338
+ activePeople: z5.number(),
339
+ conversations: z5.number(),
340
+ date: z5.string()
341
+ }).strict();
342
+ var actorTotalsReportSchema = z5.object({
343
+ active: z5.number(),
344
+ activeDays: z5.number(),
345
+ conversations: z5.number(),
346
+ durationMs: z5.number(),
347
+ failed: z5.number(),
348
+ tokens: z5.number().optional()
349
+ }).strict();
350
+ var identifiedActorSchema = actorIdentitySchema.extend({ email: z5.string().min(1) }).strict();
351
+ var actorSummaryReportSchema = actorTotalsReportSchema.extend({
352
+ firstSeenAt: z5.string(),
353
+ lastSeenAt: z5.string(),
354
+ actor: identifiedActorSchema
355
+ }).strict();
356
+ var actorDirectoryReportSchema = z5.object({
357
+ activityDays: z5.array(peopleActivityDayReportSchema),
358
+ generatedAt: z5.string(),
359
+ people: z5.array(actorSummaryReportSchema),
360
+ source: z5.literal("conversation_index"),
361
+ windowEnd: z5.string(),
362
+ windowStart: z5.string()
363
+ }).strict();
364
+ var actorProfileReportSchema = z5.object({
365
+ activityDays: z5.array(actorActivityDayReportSchema),
366
+ generatedAt: z5.string(),
367
+ locations: z5.array(peopleConversationStatsItemSchema),
368
+ recentConversations: z5.array(conversationSummaryReportSchema),
369
+ actor: identifiedActorSchema,
370
+ source: z5.literal("conversation_index"),
371
+ surfaces: z5.array(peopleConversationStatsItemSchema),
372
+ totals: actorTotalsReportSchema,
373
+ windowEnd: z5.string(),
374
+ windowStart: z5.string()
375
+ }).strict();
374
376
 
375
377
  export {
376
- dailyConversationActivitySchema,
377
- activityDays,
378
+ apiErrorSchema,
379
+ conversationParamsSchema,
380
+ conversationFeedQuerySchema,
381
+ archiveConversationBodySchema,
382
+ archiveConversationResponseSchema,
383
+ conversationSummaryReportSchema,
378
384
  conversationReportEventDataSchema,
379
385
  conversationReportEventSchema,
380
386
  conversationEventHistorySchema,
381
387
  conversationDetailReportSchema,
382
388
  conversationFeedSchema,
383
389
  conversationStatsReportSchema,
384
- actorDirectoryReportSchema,
385
- actorProfileReportSchema,
390
+ dailyConversationActivitySchema,
391
+ activityDays,
392
+ locationParamsSchema,
386
393
  locationActivityDayReportSchema,
387
394
  locationDirectoryReportSchema,
388
395
  locationDetailReportSchema,
389
- conversationParamsSchema,
390
- conversationFeedQuerySchema,
391
396
  personParamsSchema,
392
- locationParamsSchema
397
+ actorDirectoryReportSchema,
398
+ actorProfileReportSchema
393
399
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getChatConfig
3
- } from "./chunk-JNAVF45E.js";
3
+ } from "./chunk-WNOVRQ67.js";
4
4
 
5
5
  // src/chat/state/adapter.ts
6
6
  import { createMemoryState } from "@chat-adapter/state-memory";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  toOptionalNumber,
3
3
  toOptionalString
4
- } from "./chunk-OB42YVAE.js";
4
+ } from "./chunk-42WRQLJ6.js";
5
5
  import {
6
6
  captureException,
7
7
  getActiveSpan,
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-6GWA276C.js";
14
14
  import {
15
15
  getDeploymentTelemetryAttributes
16
- } from "./chunk-IVVGFRQQ.js";
16
+ } from "./chunk-W75ZPAGG.js";
17
17
 
18
18
  // src/chat/logging.ts
19
19
  import path from "path";
@@ -137,6 +137,11 @@ var juniorConversations = pgTable3(
137
137
  parentConversationId: text3("parent_conversation_id").references(
138
138
  () => juniorConversations.conversationId
139
139
  ),
140
+ // Roots reference themselves; descendants reference the root whose actor
141
+ // and destination own their privacy boundary.
142
+ rootConversationId: text3("root_conversation_id").references(
143
+ () => juniorConversations.conversationId
144
+ ),
140
145
  transcriptPurgedAt: timestamptz("transcript_purged_at"),
141
146
  durationMs: integer("duration_ms").notNull().default(0),
142
147
  usage: jsonb2("usage_json").$type(),
@@ -168,7 +173,8 @@ var juniorConversations = pgTable3(
168
173
  table.originId,
169
174
  table.lastActivityAt.desc()
170
175
  ),
171
- index2("junior_conversations_parent_idx").on(table.parentConversationId)
176
+ index2("junior_conversations_parent_idx").on(table.parentConversationId),
177
+ index2("junior_conversations_root_idx").on(table.rootConversationId)
172
178
  ]
173
179
  );
174
180
 
@@ -3,16 +3,16 @@ import {
3
3
  } from "./chunk-4ZNGQH7C.js";
4
4
  import {
5
5
  getSlackBotToken
6
- } from "./chunk-JNAVF45E.js";
6
+ } from "./chunk-WNOVRQ67.js";
7
7
  import {
8
8
  logWarn,
9
9
  setSpanAttributes,
10
10
  setSpanStatus,
11
11
  withSpan
12
- } from "./chunk-ISMWX44P.js";
12
+ } from "./chunk-IYKPU7H6.js";
13
13
  import {
14
14
  parseSlackChannelReferenceId
15
- } from "./chunk-IVVGFRQQ.js";
15
+ } from "./chunk-42WRQLJ6.js";
16
16
 
17
17
  // src/chat/slack/client.ts
18
18
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
@@ -1,16 +1,39 @@
1
1
  import {
2
2
  createVercelQueueClient
3
3
  } from "./chunk-KNFROR7R.js";
4
- import {
5
- destinationKey,
6
- parseDestination
7
- } from "./chunk-SYAQIR5Z.js";
8
4
 
9
5
  // src/chat/task-execution/queue-signing.ts
10
6
  import { createHmac, timingSafeEqual } from "crypto";
11
- var CONVERSATION_WORK_QUEUE_SIGNATURE_CONTEXT = "junior.conversation_work_queue.v1";
12
- var CONVERSATION_WORK_QUEUE_SIGNATURE_VERSION = "v1";
7
+ import { z as z2 } from "zod";
8
+
9
+ // src/chat/task-execution/queue.ts
10
+ import { z } from "zod";
11
+ var conversationQueueMessageSchema = z.object({
12
+ conversationId: z.string().trim().min(1)
13
+ }).strict();
14
+ var ConversationQueueMessageRejectedError = class extends Error {
15
+ conversationId;
16
+ reason;
17
+ constructor(reason, message, options = {}) {
18
+ super(message);
19
+ this.name = "ConversationQueueMessageRejectedError";
20
+ this.reason = reason;
21
+ this.conversationId = options.conversationId;
22
+ }
23
+ };
24
+ function isConversationQueueMessageRejectedError(error) {
25
+ return error instanceof ConversationQueueMessageRejectedError;
26
+ }
27
+
28
+ // src/chat/task-execution/queue-signing.ts
29
+ var CONVERSATION_WORK_QUEUE_SIGNATURE_CONTEXT = "junior.conversation_work_queue.v2";
30
+ var CONVERSATION_WORK_QUEUE_SIGNATURE_VERSION = "v2";
13
31
  var CONVERSATION_WORK_QUEUE_SIGNATURE_MAX_SKEW_MS = 60 * 60 * 1e3;
32
+ var signedConversationQueueMessageSchema = conversationQueueMessageSchema.extend({
33
+ signature: z2.string().trim().min(1),
34
+ signatureVersion: z2.literal(CONVERSATION_WORK_QUEUE_SIGNATURE_VERSION),
35
+ signedAtMs: z2.number().finite()
36
+ }).strict();
14
37
  function getConversationWorkQueueSecret() {
15
38
  return process.env.JUNIOR_SECRET?.trim() || void 0;
16
39
  }
@@ -18,12 +41,11 @@ function buildSignedPayload(message, signedAtMs) {
18
41
  return [
19
42
  CONVERSATION_WORK_QUEUE_SIGNATURE_CONTEXT,
20
43
  signedAtMs,
21
- message.conversationId,
22
- destinationKey(message.destination)
44
+ message.conversationId
23
45
  ].join(":");
24
46
  }
25
- function signPayload(message, signedAtMs, secret) {
26
- return createHmac("sha256", secret).update(buildSignedPayload(message, signedAtMs)).digest("hex");
47
+ function signPayload(payload, secret) {
48
+ return createHmac("sha256", secret).update(payload).digest("hex");
27
49
  }
28
50
  function timingSafeMatch(expected, actual) {
29
51
  const expectedBuffer = Buffer.from(expected);
@@ -34,21 +56,8 @@ function timingSafeMatch(expected, actual) {
34
56
  return timingSafeEqual(expectedBuffer, actualBuffer);
35
57
  }
36
58
  function parseSignedConversationQueueMessage(value) {
37
- if (!value || typeof value !== "object") {
38
- return void 0;
39
- }
40
- const record = value;
41
- const destination = parseDestination(record.destination);
42
- if (typeof record.conversationId !== "string" || !record.conversationId.trim() || !destination || record.signatureVersion !== CONVERSATION_WORK_QUEUE_SIGNATURE_VERSION || typeof record.signedAtMs !== "number" || !Number.isFinite(record.signedAtMs) || typeof record.signature !== "string" || !record.signature.trim()) {
43
- return void 0;
44
- }
45
- return {
46
- conversationId: record.conversationId,
47
- destination,
48
- signature: record.signature,
49
- signatureVersion: CONVERSATION_WORK_QUEUE_SIGNATURE_VERSION,
50
- signedAtMs: record.signedAtMs
51
- };
59
+ const parsed = signedConversationQueueMessageSchema.safeParse(value);
60
+ return parsed.success ? parsed.data : void 0;
52
61
  }
53
62
  function signConversationQueueMessage(message, nowMs = Date.now()) {
54
63
  const secret = getConversationWorkQueueSecret();
@@ -61,7 +70,7 @@ function signConversationQueueMessage(message, nowMs = Date.now()) {
61
70
  ...message,
62
71
  signedAtMs: nowMs,
63
72
  signatureVersion: CONVERSATION_WORK_QUEUE_SIGNATURE_VERSION,
64
- signature: signPayload(message, nowMs, secret)
73
+ signature: signPayload(buildSignedPayload(message, nowMs), secret)
65
74
  };
66
75
  }
67
76
  function verifyConversationQueueMessage(value, nowMs = Date.now()) {
@@ -79,16 +88,16 @@ function verifyConversationQueueMessage(value, nowMs = Date.now()) {
79
88
  if (Math.abs(nowMs - message.signedAtMs) > CONVERSATION_WORK_QUEUE_SIGNATURE_MAX_SKEW_MS) {
80
89
  return { status: "rejected", reason: "expired" };
81
90
  }
82
- const expected = signPayload(message, message.signedAtMs, secret);
91
+ const expected = signPayload(
92
+ buildSignedPayload(message, message.signedAtMs),
93
+ secret
94
+ );
83
95
  if (!timingSafeMatch(expected, message.signature)) {
84
96
  return { status: "rejected", reason: "signature_mismatch" };
85
97
  }
86
98
  return {
87
99
  status: "verified",
88
- message: {
89
- conversationId: message.conversationId,
90
- destination: message.destination
91
- }
100
+ message: { conversationId: message.conversationId }
92
101
  };
93
102
  }
94
103
 
@@ -130,6 +139,9 @@ function getVercelConversationWorkQueue() {
130
139
  }
131
140
 
132
141
  export {
142
+ conversationQueueMessageSchema,
143
+ ConversationQueueMessageRejectedError,
144
+ isConversationQueueMessageRejectedError,
133
145
  verifyConversationQueueMessage,
134
146
  resolveConversationWorkQueueTopic,
135
147
  getVercelConversationWorkQueue