{"version":3,"sources":["../src/chat/chat.schemas.ts"],"names":["CHAT_MESSAGE_BODY_MIN_LENGTH","CHAT_MESSAGE_BODY_MAX_LENGTH","CHAT_MODERATION_REASON_MAX_LENGTH","CHAT_MESSAGE_VIDEO_OFFSET_MAX_SECONDS","ChatMessageUserSchema","z","ChatMessageSchema","ChatHistoryResponseSchema","PaginationResponseSchema","PostChatMessageRequestSchema","ChatModerationDeleteRequestSchema","ChatModerationMuteRequestSchema","value","ChatMuteStateResponseSchema","ChatCredentialsResponseSchema","InProcessChatCredentialsSchema","IvsChatCredentialsSchema","ChatPostAckSchema"],"mappings":"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","file":"chunk-D3TIBT4W.mjs","sourcesContent":["import z from 'zod';\nimport { PaginationResponseSchema } from '../common';\n\nexport const CHAT_MESSAGE_BODY_MIN_LENGTH = 1;\nexport const CHAT_MESSAGE_BODY_MAX_LENGTH = 500;\n\nexport const CHAT_MODERATION_REASON_MAX_LENGTH = 200;\n\n/**\n * Upper bound (seconds) for `videoOffsetSec` — 48 hours. Longer than\n * any realistic stream duration; anything above this is a bad-actor\n * or client-clock-skew signal and gets rejected at the wire.\n */\nexport const CHAT_MESSAGE_VIDEO_OFFSET_MAX_SECONDS = 48 * 60 * 60;\n\nexport const ChatMessageUserSchema = z.object({\n  id: z.string(),\n  displayName: z.string(),\n  colorHex: z.string().regex(/^#[0-9A-Fa-f]{6}$/),\n});\n\nexport const ChatMessageSchema = z.object({\n  id: z.string(),\n  body: z.string(),\n  createdAt: z.iso.datetime(),\n  user: ChatMessageUserSchema,\n  deletedAt: z.iso.datetime().optional(),\n  /**\n   * Seconds elapsed since the event's live stream started at the moment\n   * the client posted the message. Set by the frontend from the local\n   * player clock (`Math.floor(player.currentTime)`); omitted for\n   * pre-LIVE or catch-up posts where the player wasn't playing.\n   *\n   * Consumers render chat during replay by filtering to\n   * `videoOffsetSec <= currentPlayheadSec` and sorting by\n   * `videoOffsetSec ASC` (falling back to `createdAt` for pre-live\n   * messages).\n   */\n  videoOffsetSec: z.number().int().nonnegative().optional(),\n});\n\nexport const ChatHistoryResponseSchema = z.object({\n  items: z.array(ChatMessageSchema),\n  ...PaginationResponseSchema.shape,\n});\n\nexport const PostChatMessageRequestSchema = z.object({\n  body: z.string().trim().min(CHAT_MESSAGE_BODY_MIN_LENGTH).max(CHAT_MESSAGE_BODY_MAX_LENGTH),\n  videoOffsetSec: z.number().int().min(0).max(CHAT_MESSAGE_VIDEO_OFFSET_MAX_SECONDS).optional(),\n});\n\nexport const ChatModerationDeleteRequestSchema = z\n  .object({\n    reason: z.string().trim().max(CHAT_MODERATION_REASON_MAX_LENGTH).optional(),\n  })\n  .strict();\n\nexport const ChatModerationMuteRequestSchema = z\n  .object({\n    /** Optional explicit future timestamp. Omit for the ~1y indefinite default. */\n    until: z.iso\n      .datetime()\n      .refine((value) => new Date(value).getTime() > Date.now(), {\n        message: 'until must be a future timestamp',\n      })\n      .optional(),\n    reason: z.string().trim().max(CHAT_MODERATION_REASON_MAX_LENGTH).optional(),\n  })\n  .strict();\n\n/**\n * Public-shape response for `POST /chat/mute`. `mutedUntil` is the source\n * of truth (`null` = not muted). `mutedBy` is intentionally omitted —\n * moderation metadata stays out of the response surface.\n */\nexport const ChatMuteStateResponseSchema = z.object({\n  eventId: z.string(),\n  mutedUntil: z.iso.datetime().nullable(),\n});\n\nexport const ChatCredentialsResponseSchema = z.discriminatedUnion('kind', [\n  z.object({\n    kind: z.literal('in-process'),\n    wsNamespace: z.string(),\n    token: z.string(),\n    eventRoomId: z.string(),\n  }),\n  z.object({\n    kind: z.literal('ivs'),\n    roomIdentifier: z.string(),\n    endpoint: z.string(),\n    token: z.string(),\n    tokenTtlSeconds: z.number().int().positive(),\n  }),\n]);\n\nexport const InProcessChatCredentialsSchema = z.object({\n  kind: z.literal('in-process'),\n  wsNamespace: z.string(),\n  token: z.string(),\n  eventRoomId: z.string(),\n});\nexport const IvsChatCredentialsSchema = z.object({\n  kind: z.literal('ivs'),\n  roomIdentifier: z.string(),\n  endpoint: z.string(),\n  token: z.string(),\n  tokenTtlSeconds: z.number().int(),\n});\n\n/**\n * ACK envelope for the `chat.post` client → server frame. Success\n * carries the persisted message so the FE can dedupe against the\n * fan-out echo; failure surfaces a stable machine-readable `code`\n * plus a human-readable `message`.\n */\nexport const ChatPostAckSchema = z.discriminatedUnion('ok', [\n  z.object({\n    ok: z.literal(true),\n    message: ChatMessageSchema,\n  }),\n  z.object({\n    ok: z.literal(false),\n    code: z.enum([\n      'unauthorized',\n      'invalid_payload',\n      'muted',\n      'not_live',\n      'forbidden',\n      'not_found',\n      'rate_limited',\n      'internal',\n    ]),\n    message: z.string(),\n    retryAfterSeconds: z.number().int().nonnegative().optional(),\n  }),\n]);\n"]}