{"version":3,"sources":["../src/config.ts","../src/push.ts","../src/message.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Logger } from '@walkeros/core';\nimport type { Config, PartialConfig, Settings } from './types';\n\nexport function getConfig(\n  partialConfig: PartialConfig = {},\n  logger: Logger.Instance,\n): Config {\n  const settings = (partialConfig.settings || {}) as Partial<Settings>;\n  const { token, webhookUrl, channel } = settings;\n\n  if (!token && !webhookUrl)\n    logger.throw('Slack destination requires either token or webhookUrl');\n  if (token && webhookUrl)\n    logger.throw(\n      'Slack destination accepts either token or webhookUrl, not both',\n    );\n  if (token && !channel)\n    logger.warn(\n      'Slack destination has no default channel; every mapping rule must provide one',\n    );\n\n  return {\n    ...partialConfig,\n    settings: { ...settings } as Settings,\n  };\n}\n","import { isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport type { Mapping, PushFn, Settings, SlackClientMock } from './types';\nimport { buildMessage } from './message';\n\nexport const push: PushFn = async function (event, ctx) {\n  const { config, rule, env, logger } = ctx;\n  const settings = config.settings as Settings;\n  const ruleSettings = (rule?.settings || {}) as Partial<Mapping>;\n\n  const message = buildMessage(event, settings, ruleSettings);\n\n  // Webhook mode\n  if (settings.webhookUrl) {\n    return await pushWebhook(message, settings, env, logger);\n  }\n\n  // Web API mode\n  return await pushWebApi(message, settings, ruleSettings, env, logger);\n};\n\nasync function pushWebhook(\n  message: { text?: string; blocks?: unknown[] },\n  settings: Settings,\n  env: { sendServer?: typeof sendServer } | undefined,\n  logger: import('@walkeros/core').Logger.Instance,\n): Promise<void> {\n  if (!message.text && !message.blocks) {\n    logger.warn('Slack message has no text or blocks; skipping');\n    return;\n  }\n\n  const body = {\n    ...(message.text ? { text: message.text } : {}),\n    ...(message.blocks ? { blocks: message.blocks } : {}),\n    unfurl_links: settings.unfurlLinks ?? false,\n    unfurl_media: settings.unfurlMedia ?? false,\n    mrkdwn: settings.mrkdwn ?? true,\n  };\n\n  const send = env?.sendServer || sendServer;\n  const result = await send(\n    settings.webhookUrl as string,\n    JSON.stringify(body),\n  );\n\n  if (isObject(result) && result.ok === false) {\n    logger.warn(`Slack webhook error: ${JSON.stringify(result)}`);\n  }\n}\n\nasync function pushWebApi(\n  message: { text?: string; blocks?: unknown[] },\n  settings: Settings,\n  rule: Partial<Mapping>,\n  env: { slackClient?: SlackClientMock } | undefined,\n  logger: import('@walkeros/core').Logger.Instance,\n): Promise<void> {\n  const client =\n    (env?.slackClient as SlackClientMock | undefined) ||\n    (settings._client as unknown as SlackClientMock | undefined);\n\n  if (!client) {\n    logger.warn('Slack WebClient not initialized');\n    return;\n  }\n\n  if (!message.text && !message.blocks) {\n    logger.warn('Slack message has no text or blocks; skipping');\n    return;\n  }\n\n  // Resolve target channel\n  let channel = rule.channel ?? settings.channel;\n\n  // DM path: open DM channel first\n  if (rule.dm) {\n    if (!rule.user) {\n      logger.throw('Slack DM requires `mapping.settings.user`');\n      return;\n    }\n    const opened = await client.conversations.open({ users: rule.user });\n    const dmChannel = (\n      opened as unknown as {\n        channel?: { id?: string };\n      }\n    ).channel?.id;\n    if (!dmChannel) {\n      logger.warn('Slack conversations.open returned no channel id');\n      return;\n    }\n    channel = dmChannel;\n  }\n\n  if (!channel) {\n    logger.throw(\n      'Slack push requires a channel (set settings.channel or mapping.settings.channel)',\n    );\n    return;\n  }\n\n  const baseArgs: Record<string, unknown> = {\n    channel,\n    ...(message.text ? { text: message.text } : {}),\n    ...(message.blocks ? { blocks: message.blocks } : {}),\n    unfurl_links: settings.unfurlLinks ?? false,\n    unfurl_media: settings.unfurlMedia ?? false,\n    mrkdwn: settings.mrkdwn ?? true,\n  };\n\n  if (rule.threadTs ?? settings.threadTs) {\n    baseArgs.thread_ts = rule.threadTs ?? settings.threadTs;\n  }\n  if (rule.replyBroadcast) baseArgs.reply_broadcast = true;\n\n  // Ephemeral path\n  if (rule.ephemeral) {\n    if (!rule.user) {\n      logger.throw('Slack ephemeral requires `mapping.settings.user`');\n      return;\n    }\n    await client.chat.postEphemeral({\n      ...baseArgs,\n      user: rule.user,\n    } as never);\n    return;\n  }\n\n  await client.chat.postMessage(baseArgs as never);\n}\n","import type { WalkerOS } from '@walkeros/core';\nimport type { Mapping, Settings, SlackBlock } from './types';\n\nexport interface BuiltMessage {\n  text?: string;\n  blocks?: SlackBlock[];\n}\n\nconst TOKEN_RE = /\\$\\{([^}]+)\\}/g;\n\nfunction getPath(obj: unknown, path: string): unknown {\n  return path.split('.').reduce<unknown>((acc, key) => {\n    if (acc && typeof acc === 'object' && key in (acc as object)) {\n      return (acc as Record<string, unknown>)[key];\n    }\n    return undefined;\n  }, obj);\n}\n\nexport function interpolate(template: string, event: WalkerOS.Event): string {\n  return template.replace(TOKEN_RE, (_, path: string) => {\n    const value = getPath(event, path.trim());\n    if (value === undefined || value === null) return '';\n    if (typeof value === 'object') return JSON.stringify(value);\n    return String(value);\n  });\n}\n\nexport function buildMessage(\n  event: WalkerOS.Event,\n  settings: Partial<Settings>,\n  rule: Partial<Mapping>,\n): BuiltMessage {\n  // 1. Custom blocks via rule\n  if (rule.blocks && rule.blocks.length > 0) {\n    const result: BuiltMessage = {\n      blocks: interpolateBlocks(rule.blocks, event),\n    };\n    const text = rule.text ?? settings.text;\n    if (text) result.text = interpolate(text, event);\n    return result;\n  }\n\n  // 2. Custom text via rule (no blocks)\n  const text = rule.text ?? settings.text;\n  if (text) {\n    return { text: interpolate(text, event) };\n  }\n\n  // 3. Destination-level blocks\n  if (settings.blocks && settings.blocks.length > 0) {\n    return { blocks: interpolateBlocks(settings.blocks, event) };\n  }\n\n  // 4. Auto-generated default blocks from event data\n  return {\n    text: event.name,\n    blocks: defaultBlocks(event, settings.includeHeader !== false),\n  };\n}\n\nfunction interpolateBlocks(\n  blocks: SlackBlock[],\n  event: WalkerOS.Event,\n): SlackBlock[] {\n  return JSON.parse(interpolate(JSON.stringify(blocks), event)) as SlackBlock[];\n}\n\nfunction defaultBlocks(\n  event: WalkerOS.Event,\n  includeHeader: boolean,\n): SlackBlock[] {\n  const blocks: SlackBlock[] = [];\n\n  if (includeHeader) {\n    blocks.push({\n      type: 'header',\n      text: { type: 'plain_text', text: event.name },\n    });\n  }\n\n  const data = (event.data || {}) as Record<string, unknown>;\n  const fields = Object.entries(data)\n    .filter(([, v]) => v !== undefined && v !== null)\n    .map(([key, value]) => ({\n      type: 'mrkdwn' as const,\n      text: `*${key}:*\\n${stringify(value)}`,\n    }));\n\n  if (fields.length > 0) {\n    blocks.push({ type: 'section', fields });\n  }\n\n  const sourceType = event.source?.type;\n  if (sourceType) {\n    blocks.push({\n      type: 'context',\n      elements: [{ type: 'mrkdwn', text: `Source: ${sourceType}` }],\n    });\n  }\n\n  return blocks;\n}\n\nfunction stringify(value: unknown): string {\n  if (value === null || value === undefined) return '';\n  if (typeof value === 'object') return JSON.stringify(value);\n  return String(value);\n}\n","import type {\n  Mapping as WalkerOSMapping,\n  Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\nimport type {\n  WebClient,\n  ChatPostMessageArguments,\n  ChatPostMessageResponse,\n  ChatPostEphemeralArguments,\n  ChatPostEphemeralResponse,\n  ConversationsOpenArguments,\n  ConversationsOpenResponse,\n} from '@slack/web-api';\n\n/** A single Block Kit block (kept loose -- Slack does not export a union type). */\nexport type SlackBlock = Record<string, unknown>;\n\nexport interface Settings {\n  // --- Auth (exactly one required) ---\n  /** Slack Bot token (xoxb-...). Enables Web API mode. */\n  token?: string;\n  /** Incoming Webhook URL. Enables webhook mode. */\n  webhookUrl?: string;\n\n  // --- Target ---\n  /** Default channel ID or name. Required for Web API mode unless every rule provides one. */\n  channel?: string;\n\n  // --- Message formatting ---\n  /** Default text template. Supports `${data.field}` interpolation against the walkerOS event. */\n  text?: string;\n  /** Default Block Kit blocks applied when no mapping override is set. */\n  blocks?: SlackBlock[];\n  /** Auto-add an event-name header block when generating default blocks. Default: true. */\n  includeHeader?: boolean;\n\n  // --- Behavior ---\n  /** Enable link unfurling. Default: false. */\n  unfurlLinks?: boolean;\n  /** Enable media unfurling. Default: false. */\n  unfurlMedia?: boolean;\n  /** Use mrkdwn formatting. Default: true. */\n  mrkdwn?: boolean;\n\n  // --- Threading ---\n  /** Static thread_ts to reply to (rarely set at destination level). */\n  threadTs?: string;\n\n  // --- SDK config (Web API only) ---\n  /** Retry policy passed to WebClient. Default: 'default'. */\n  retryConfig?: 'default' | 'fiveRetriesInFiveMinutes' | 'none';\n\n  // --- Runtime (not user-facing) ---\n  _client?: WebClient;\n}\n\nexport type InitSettings = Partial<Settings>;\n\n/**\n * Per-rule mapping settings. Override channel, text, blocks, and route\n * to threads / DMs / ephemeral.\n */\nexport interface Mapping {\n  /** Override the channel for this rule (Web API mode only). */\n  channel?: string;\n  /** Override the text template for this rule. */\n  text?: string;\n  /** Override Block Kit blocks for this rule. */\n  blocks?: SlackBlock[];\n  /** thread_ts for posting as a reply in a thread. */\n  threadTs?: string;\n  /** Also broadcast the threaded reply back to the channel. */\n  replyBroadcast?: boolean;\n  /** Send via chat.postEphemeral instead of chat.postMessage. */\n  ephemeral?: boolean;\n  /** Slack user ID for ephemeral or DM delivery. */\n  user?: string;\n  /** Send as DM (conversations.open + chat.postMessage). Requires `user`. */\n  dm?: boolean;\n}\n\n/**\n * Mock-friendly interface for the WebClient methods the destination calls.\n * Tests inject this via env.slackClient.\n */\nexport interface SlackClientMock {\n  chat: {\n    postMessage: (\n      opts: ChatPostMessageArguments,\n    ) => Promise<ChatPostMessageResponse>;\n    postEphemeral: (\n      opts: ChatPostEphemeralArguments,\n    ) => Promise<ChatPostEphemeralResponse>;\n  };\n  conversations: {\n    open: (\n      opts: ConversationsOpenArguments,\n    ) => Promise<ConversationsOpenResponse>;\n  };\n}\n\n/**\n * Env -- optional SDK / transport overrides. Production leaves these undefined.\n * Tests inject `slackClient` (Web API mode) and/or `sendServer` (webhook mode).\n */\nexport interface Env extends DestinationServer.Env {\n  slackClient?: SlackClientMock;\n  sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n  init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n  settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n","import type { Destination, Settings, SlackClientMock } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationSlack from './types';\n\nconst RETRY_PRESETS: Record<string, unknown> = {\n  default: undefined,\n  fiveRetriesInFiveMinutes: { retries: 5, factor: 1.96 },\n  none: { retries: 0 },\n};\n\nexport const destinationSlack: Destination = {\n  type: 'slack',\n\n  config: {},\n\n  init({ config: partialConfig, logger, env }) {\n    const config = getConfig(partialConfig, logger);\n    const settings = config.settings as Settings;\n\n    // Webhook mode -- nothing to initialize.\n    if (settings.webhookUrl) return config;\n\n    // Web API mode -- prefer mock client from env (testing).\n    const envClient = (env as { slackClient?: SlackClientMock } | undefined)\n      ?.slackClient;\n    if (envClient) return config;\n\n    // Production path: lazily load @slack/web-api so webhook-only users\n    // do not pay for the SDK import cost.\n    try {\n      const { WebClient } = require('@slack/web-api');\n      const retryConfig = RETRY_PRESETS[settings.retryConfig || 'default'];\n      settings._client = new WebClient(settings.token, {\n        ...(retryConfig !== undefined ? { retryConfig } : {}),\n      });\n    } catch (err) {\n      logger.throw(`Failed to initialize Slack WebClient: ${err}`);\n    }\n\n    return config;\n  },\n\n  async push(event, context) {\n    return await push(event, context);\n  },\n};\n\nexport default destinationSlack;\n"],"mappings":"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","names":["text"]}