@walkeros/server-destination-slack 3.4.0 → 3.4.1-next-1776790594143
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/dist/dev.js +1 -1
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/examples/index.js +14 -0
- package/dist/examples/index.mjs +14 -0
- package/dist/walkerOS.json +22 -8
- package/package.json +4 -4
package/dist/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,o=(e,a)=>{for(var n in a)t(e,n,{get:a[n],enumerable:!0})},s={};o(s,{examples:()=>g,schemas:()=>i}),module.exports=(e=s,((e,o,s,i)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let l of n(o))r.call(e,l)||l===s||t(e,l,{get:()=>o[l],enumerable:!(i=a(o,l))||i.enumerable});return e})(t({},"__esModule",{value:!0}),e));var i={};o(i,{MappingSchema:()=>u,SettingsSchema:()=>d,mapping:()=>h,settings:()=>m});var l=require("@walkeros/core/dev"),c=require("@walkeros/core/dev"),d=c.z.object({token:c.z.string().startsWith("xoxb-").describe("Slack Bot token (xoxb-...). Enables Web API mode. Mutually exclusive with webhookUrl.").optional(),webhookUrl:c.z.string().url().describe("Incoming Webhook URL. Enables webhook mode. Mutually exclusive with token.").optional(),channel:c.z.string().describe('Default Slack channel ID or name (e.g. "#alerts" or "C024BE91L"). Required for Web API mode unless every rule supplies one. Ignored in webhook mode.').optional(),text:c.z.string().describe("Default text template. Supports `${data.field}` interpolation against the walkerOS event.").optional(),blocks:c.z.array(c.z.record(c.z.string(),c.z.unknown())).describe("Default Block Kit blocks applied when no mapping override is set.").optional(),includeHeader:c.z.boolean().describe("Auto-add an event-name header block when generating default blocks. Default: true.").optional(),unfurlLinks:c.z.boolean().describe("Enable link unfurling. Default: false (cleaner for automated alerts).").optional(),unfurlMedia:c.z.boolean().describe("Enable media unfurling. Default: false.").optional(),mrkdwn:c.z.boolean().describe("Use mrkdwn formatting in text. Default: true.").optional(),threadTs:c.z.string().describe("Static thread_ts for replies (rarely set at destination level).").optional(),retryConfig:c.z.enum(["default","fiveRetriesInFiveMinutes","none"]).describe('Retry policy passed to WebClient. Default: "default".').optional()}).refine(e=>Boolean(e.token)!==Boolean(e.webhookUrl),{message:"Provide exactly one of `token` or `webhookUrl`."}),p=require("@walkeros/core/dev"),u=p.z.object({channel:p.z.string().describe("Override the destination channel for this rule. Web API mode only -- ignored in webhook mode.").optional(),text:p.z.string().describe("Override the text template for this rule. Supports `${data.field}` interpolation.").optional(),blocks:p.z.array(p.z.record(p.z.string(),p.z.unknown())).describe("Override Block Kit blocks for this rule.").optional(),threadTs:p.z.string().describe("thread_ts for posting as a reply in a thread.").optional(),replyBroadcast:p.z.boolean().describe("Also broadcast the threaded reply back to the channel.").optional(),ephemeral:p.z.boolean().describe("Send via chat.postEphemeral. Requires `user`.").optional(),user:p.z.string().describe("Slack user ID for ephemeral or DM delivery.").optional(),dm:p.z.boolean().describe("Send as DM via conversations.open + chat.postMessage. Requires `user`.").optional()}),m=(0,l.zodToSchema)(d),h=(0,l.zodToSchema)(u),g={};o(g,{env:()=>k,step:()=>x});var k={};o(k,{push:()=>y,simulation:()=>w});var b={ok:!0,channel:"CMOCK",ts:"1700000000.000100"},
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,o=(e,a)=>{for(var n in a)t(e,n,{get:a[n],enumerable:!0})},s={};o(s,{examples:()=>g,schemas:()=>i}),module.exports=(e=s,((e,o,s,i)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let l of n(o))r.call(e,l)||l===s||t(e,l,{get:()=>o[l],enumerable:!(i=a(o,l))||i.enumerable});return e})(t({},"__esModule",{value:!0}),e));var i={};o(i,{MappingSchema:()=>u,SettingsSchema:()=>d,mapping:()=>h,settings:()=>m});var l=require("@walkeros/core/dev"),c=require("@walkeros/core/dev"),d=c.z.object({token:c.z.string().startsWith("xoxb-").describe("Slack Bot token (xoxb-...). Enables Web API mode. Mutually exclusive with webhookUrl.").optional(),webhookUrl:c.z.string().url().describe("Incoming Webhook URL. Enables webhook mode. Mutually exclusive with token.").optional(),channel:c.z.string().describe('Default Slack channel ID or name (e.g. "#alerts" or "C024BE91L"). Required for Web API mode unless every rule supplies one. Ignored in webhook mode.').optional(),text:c.z.string().describe("Default text template. Supports `${data.field}` interpolation against the walkerOS event.").optional(),blocks:c.z.array(c.z.record(c.z.string(),c.z.unknown())).describe("Default Block Kit blocks applied when no mapping override is set.").optional(),includeHeader:c.z.boolean().describe("Auto-add an event-name header block when generating default blocks. Default: true.").optional(),unfurlLinks:c.z.boolean().describe("Enable link unfurling. Default: false (cleaner for automated alerts).").optional(),unfurlMedia:c.z.boolean().describe("Enable media unfurling. Default: false.").optional(),mrkdwn:c.z.boolean().describe("Use mrkdwn formatting in text. Default: true.").optional(),threadTs:c.z.string().describe("Static thread_ts for replies (rarely set at destination level).").optional(),retryConfig:c.z.enum(["default","fiveRetriesInFiveMinutes","none"]).describe('Retry policy passed to WebClient. Default: "default".').optional()}).refine(e=>Boolean(e.token)!==Boolean(e.webhookUrl),{message:"Provide exactly one of `token` or `webhookUrl`."}),p=require("@walkeros/core/dev"),u=p.z.object({channel:p.z.string().describe("Override the destination channel for this rule. Web API mode only -- ignored in webhook mode.").optional(),text:p.z.string().describe("Override the text template for this rule. Supports `${data.field}` interpolation.").optional(),blocks:p.z.array(p.z.record(p.z.string(),p.z.unknown())).describe("Override Block Kit blocks for this rule.").optional(),threadTs:p.z.string().describe("thread_ts for posting as a reply in a thread.").optional(),replyBroadcast:p.z.boolean().describe("Also broadcast the threaded reply back to the channel.").optional(),ephemeral:p.z.boolean().describe("Send via chat.postEphemeral. Requires `user`.").optional(),user:p.z.string().describe("Slack user ID for ephemeral or DM delivery.").optional(),dm:p.z.boolean().describe("Send as DM via conversations.open + chat.postMessage. Requires `user`.").optional()}),m=(0,l.zodToSchema)(d),h=(0,l.zodToSchema)(u),g={};o(g,{env:()=>k,step:()=>x});var k={};o(k,{push:()=>y,simulation:()=>w});var b={ok:!0,channel:"CMOCK",ts:"1700000000.000100"},v={ok:!0},f={ok:!0,channel:{id:"D-MOCK-DM"}};var y={slackClient:{chat:{postMessage:()=>Promise.resolve(b),postEphemeral:()=>Promise.resolve(v)},conversations:{open:()=>Promise.resolve(f)}},sendServer:()=>Promise.resolve({ok:!0})},w=["call:slackClient.chat.postMessage","call:slackClient.chat.postEphemeral","call:slackClient.conversations.open","call:sendServer"],x={};o(x,{defaultBlocks:()=>C,deployNotification:()=>P,ephemeralMessage:()=>_,errorAlert:()=>M,purchaseAlert:()=>E,threadedCheckoutStep:()=>D,welcomeDM:()=>S});var z=require("@walkeros/core"),E={title:"Purchase alert",description:"A completed order posts a templated message to a sales channel via the Slack Web API.",in:(0,z.getEvent)("order complete",{timestamp:1700000100,data:{id:"ORD-500",total:299.99,currency:"EUR",product:"Pro Plan"},user:{id:"buyer-42"}}),mapping:{settings:{channel:"#sales",text:":moneybag: New order: ${data.id} - ${data.total} ${data.currency}"}},out:[["slackClient.chat.postMessage",{channel:"#sales",text:":moneybag: New order: ORD-500 - 299.99 EUR",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0}]]},M={title:"Error alert",description:"An error event posts a critical alert to an engineering channel using a mapping-level channel override.",in:(0,z.getEvent)("error occur",{timestamp:1700000200,data:{message:"Payment gateway timeout",code:"PGW_TIMEOUT",severity:"critical"}}),mapping:{settings:{channel:"#engineering-alerts",text:":rotating_light: Error: ${data.message}"}},out:[["slackClient.chat.postMessage",{channel:"#engineering-alerts",text:":rotating_light: Error: Payment gateway timeout",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0}]]},S={title:"Welcome DM",description:"A user signup opens a Slack DM channel and posts a welcome message with the selected plan.",in:(0,z.getEvent)("user signup",{timestamp:1700000300,data:{plan:"enterprise"},user:{id:"U-NEW-USER"}}),mapping:{settings:{dm:!0,user:"U-NEW-USER",text:":wave: Welcome aboard! You signed up for the ${data.plan} plan."}},out:[["slackClient.conversations.open",{users:"U-NEW-USER"}],["slackClient.chat.postMessage",{channel:"D-MOCK-DM",text:":wave: Welcome aboard! You signed up for the enterprise plan.",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0}]]},D={title:"Threaded reply",description:"A checkout step posts as a threaded reply in Slack via thread_ts with broadcast to the channel.",in:(0,z.getEvent)("checkout step",{timestamp:1700000400,data:{step:"payment",sessionTs:"1700000000.000050"}}),mapping:{settings:{channel:"#sales",text:"Checkout step: ${data.step}",threadTs:"1700000000.000050",replyBroadcast:!0}},out:[["slackClient.chat.postMessage",{channel:"#sales",text:"Checkout step: payment",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0,thread_ts:"1700000000.000050",reply_broadcast:!0}]]},_={title:"Ephemeral message",description:"A quota warning posts an ephemeral Slack message visible only to a target admin user.",in:(0,z.getEvent)("quota warning",{timestamp:1700000500,data:{remaining:5}}),mapping:{settings:{channel:"#admin",ephemeral:!0,user:"U-ADMIN-1",text:"Heads up: ${data.remaining} requests remaining"}},out:[["slackClient.chat.postEphemeral",{channel:"#admin",text:"Heads up: 5 requests remaining",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0,user:"U-ADMIN-1"}]]},C={title:"Default blocks",description:"With no custom text the destination auto-generates a Block Kit message from event data and source.",in:(0,z.getEvent)("lead submit",{timestamp:1700000600,data:{name:"Acme",email:"sales@acme.test"},source:{type:"server",id:"crm",previous_id:""}}),mapping:{settings:{channel:"#growth"}},out:[["slackClient.chat.postMessage",{channel:"#growth",text:"lead submit",blocks:[{type:"header",text:{type:"plain_text",text:"lead submit"}},{type:"section",fields:[{type:"mrkdwn",text:"*name:*\nAcme"},{type:"mrkdwn",text:"*email:*\nsales@acme.test"}]},{type:"context",elements:[{type:"mrkdwn",text:"Source: crm"}]}],unfurl_links:!1,unfurl_media:!1,mrkdwn:!0}]]},P={title:"Webhook deploy",description:"Without a token the destination posts to an incoming Slack webhook URL with the rendered message body.",in:(0,z.getEvent)("deploy complete",{timestamp:1700000700,data:{version:"1.4.2",environment:"prod"}}),settings:{token:void 0,webhookUrl:"https://hooks.slack.com/services/T00/B00/xxx"},mapping:{settings:{text:":rocket: Deployment complete: ${data.version} to ${data.environment}"}},out:[["sendServer","https://hooks.slack.com/services/T00/B00/xxx",JSON.stringify({text:":rocket: Deployment complete: 1.4.2 to prod",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0})]]};//# sourceMappingURL=dev.js.map
|
package/dist/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z\n .object({\n token: z\n .string()\n .startsWith('xoxb-')\n .describe(\n 'Slack Bot token (xoxb-...). Enables Web API mode. Mutually exclusive with webhookUrl.',\n )\n .optional(),\n webhookUrl: z\n .string()\n .url()\n .describe(\n 'Incoming Webhook URL. Enables webhook mode. Mutually exclusive with token.',\n )\n .optional(),\n channel: z\n .string()\n .describe(\n 'Default Slack channel ID or name (e.g. \"#alerts\" or \"C024BE91L\"). Required for Web API mode unless every rule supplies one. Ignored in webhook mode.',\n )\n .optional(),\n text: z\n .string()\n .describe(\n 'Default text template. Supports `${data.field}` interpolation against the walkerOS event.',\n )\n .optional(),\n blocks: z\n .array(z.record(z.string(), z.unknown()))\n .describe(\n 'Default Block Kit blocks applied when no mapping override is set.',\n )\n .optional(),\n includeHeader: z\n .boolean()\n .describe(\n 'Auto-add an event-name header block when generating default blocks. Default: true.',\n )\n .optional(),\n unfurlLinks: z\n .boolean()\n .describe(\n 'Enable link unfurling. Default: false (cleaner for automated alerts).',\n )\n .optional(),\n unfurlMedia: z\n .boolean()\n .describe('Enable media unfurling. Default: false.')\n .optional(),\n mrkdwn: z\n .boolean()\n .describe('Use mrkdwn formatting in text. Default: true.')\n .optional(),\n threadTs: z\n .string()\n .describe(\n 'Static thread_ts for replies (rarely set at destination level).',\n )\n .optional(),\n retryConfig: z\n .enum(['default', 'fiveRetriesInFiveMinutes', 'none'])\n .describe('Retry policy passed to WebClient. Default: \"default\".')\n .optional(),\n })\n .refine((v) => Boolean(v.token) !== Boolean(v.webhookUrl), {\n message: 'Provide exactly one of `token` or `webhookUrl`.',\n });\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n channel: z\n .string()\n .describe(\n 'Override the destination channel for this rule. Web API mode only -- ignored in webhook mode.',\n )\n .optional(),\n text: z\n .string()\n .describe(\n 'Override the text template for this rule. Supports `${data.field}` interpolation.',\n )\n .optional(),\n blocks: z\n .array(z.record(z.string(), z.unknown()))\n .describe('Override Block Kit blocks for this rule.')\n .optional(),\n threadTs: z\n .string()\n .describe('thread_ts for posting as a reply in a thread.')\n .optional(),\n replyBroadcast: z\n .boolean()\n .describe('Also broadcast the threaded reply back to the channel.')\n .optional(),\n ephemeral: z\n .boolean()\n .describe('Send via chat.postEphemeral. Requires `user`.')\n .optional(),\n user: z\n .string()\n .describe('Slack user ID for ephemeral or DM delivery.')\n .optional(),\n dm: z\n .boolean()\n .describe(\n 'Send as DM via conversations.open + chat.postMessage. Requires `user`.',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env, SlackClientMock } from '../types';\n\nconst okMessageResponse = {\n ok: true as const,\n channel: 'CMOCK',\n ts: '1700000000.000100',\n};\n\nconst okEphemeralResponse = { ok: true as const };\n\nconst okOpenResponse = {\n ok: true as const,\n channel: { id: 'D-MOCK-DM' },\n};\n\nfunction createMockClient(): SlackClientMock {\n return {\n chat: {\n postMessage: () => Promise.resolve(okMessageResponse as never),\n postEphemeral: () => Promise.resolve(okEphemeralResponse as never),\n },\n conversations: {\n open: () => Promise.resolve(okOpenResponse as never),\n },\n };\n}\n\nexport const push: Env = {\n slackClient: createMockClient(),\n sendServer: (() =>\n Promise.resolve({ ok: true } as never)) as Env['sendServer'],\n};\n\nexport const simulation = [\n 'call:slackClient.chat.postMessage',\n 'call:slackClient.chat.postEphemeral',\n 'call:slackClient.conversations.open',\n 'call:sendServer',\n];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type SlackStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Slack server destination operates in two modes:\n *\n * 1. Web API mode — calls the injected `env.slackClient` SDK methods\n * (`chat.postMessage`, `chat.postEphemeral`, `conversations.open`).\n * Captured as `[callable, args]` with dotted callable names such as\n * `'slackClient.chat.postMessage'`.\n *\n * 2. Webhook mode — calls `env.sendServer(url, JSON.stringify(body))`.\n * Captured as `['sendServer', url, bodyAsString]` where `bodyAsString`\n * is the already-stringified JSON body. Key insertion order in the\n * source object matters for string equality.\n *\n * A single push may emit multiple calls (e.g. a DM opens a conversation\n * then posts to the returned channel id), so every `out` is wrapped as\n * `[[callable, ...args], ...]`.\n */\n\n/**\n * Purchase notification -- Web API mode, channel from mapping override,\n * text template interpolated against event.data.\n */\nexport const purchaseAlert: SlackStepExample = {\n in: getEvent('order complete', {\n timestamp: 1700000100,\n data: {\n id: 'ORD-500',\n total: 299.99,\n currency: 'EUR',\n product: 'Pro Plan',\n },\n user: { id: 'buyer-42' },\n }),\n mapping: {\n settings: {\n channel: '#sales',\n text: ':moneybag: New order: ${data.id} - ${data.total} ${data.currency}',\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#sales',\n text: ':moneybag: New order: ORD-500 - 299.99 EUR',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Error alert -- routes to a different channel via mapping override.\n */\nexport const errorAlert: SlackStepExample = {\n in: getEvent('error occur', {\n timestamp: 1700000200,\n data: {\n message: 'Payment gateway timeout',\n code: 'PGW_TIMEOUT',\n severity: 'critical',\n },\n }),\n mapping: {\n settings: {\n channel: '#engineering-alerts',\n text: ':rotating_light: Error: ${data.message}',\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#engineering-alerts',\n text: ':rotating_light: Error: Payment gateway timeout',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Welcome DM -- conversations.open(users) -> chat.postMessage(channel: D-id).\n */\nexport const welcomeDM: SlackStepExample = {\n in: getEvent('user signup', {\n timestamp: 1700000300,\n data: { plan: 'enterprise' },\n user: { id: 'U-NEW-USER' },\n }),\n mapping: {\n settings: {\n dm: true,\n user: 'U-NEW-USER',\n text: ':wave: Welcome aboard! You signed up for the ${data.plan} plan.',\n },\n },\n out: [\n ['slackClient.conversations.open', { users: 'U-NEW-USER' }],\n [\n 'slackClient.chat.postMessage',\n {\n channel: 'D-MOCK-DM',\n text: ':wave: Welcome aboard! You signed up for the enterprise plan.',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Threaded checkout step -- thread_ts override puts the reply into a thread.\n */\nexport const threadedCheckoutStep: SlackStepExample = {\n in: getEvent('checkout step', {\n timestamp: 1700000400,\n data: { step: 'payment', sessionTs: '1700000000.000050' },\n }),\n mapping: {\n settings: {\n channel: '#sales',\n text: 'Checkout step: ${data.step}',\n threadTs: '1700000000.000050',\n replyBroadcast: true,\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#sales',\n text: 'Checkout step: payment',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n thread_ts: '1700000000.000050',\n reply_broadcast: true,\n },\n ],\n ],\n};\n\n/**\n * Ephemeral message -- visible to one user in the target channel.\n */\nexport const ephemeralMessage: SlackStepExample = {\n in: getEvent('quota warning', {\n timestamp: 1700000500,\n data: { remaining: 5 },\n }),\n mapping: {\n settings: {\n channel: '#admin',\n ephemeral: true,\n user: 'U-ADMIN-1',\n text: 'Heads up: ${data.remaining} requests remaining',\n },\n },\n out: [\n [\n 'slackClient.chat.postEphemeral',\n {\n channel: '#admin',\n text: 'Heads up: 5 requests remaining',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n user: 'U-ADMIN-1',\n },\n ],\n ],\n};\n\n/**\n * Default blocks -- no custom text/blocks, destination auto-generates a\n * Block Kit message from the event data.\n */\nexport const defaultBlocks: SlackStepExample = {\n in: getEvent('lead submit', {\n timestamp: 1700000600,\n data: { name: 'Acme', email: 'sales@acme.test' },\n source: { type: 'server', id: 'crm', previous_id: '' },\n }),\n mapping: {\n settings: {\n channel: '#growth',\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#growth',\n text: 'lead submit',\n blocks: [\n {\n type: 'header',\n text: { type: 'plain_text', text: 'lead submit' },\n },\n {\n type: 'section',\n fields: [\n { type: 'mrkdwn', text: '*name:*\\nAcme' },\n { type: 'mrkdwn', text: '*email:*\\nsales@acme.test' },\n ],\n },\n {\n type: 'context',\n elements: [{ type: 'mrkdwn', text: 'Source: crm' }],\n },\n ],\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Webhook mode -- no token, just webhookUrl. The destination calls\n * `env.sendServer(url, JSON.stringify(body))`. Channel is baked into the\n * URL by Slack.\n */\nexport const deployNotification: SlackStepExample = {\n in: getEvent('deploy complete', {\n timestamp: 1700000700,\n data: { version: '1.4.2', environment: 'prod' },\n }),\n settings: {\n token: undefined,\n webhookUrl: 'https://hooks.slack.com/services/T00/B00/xxx',\n },\n mapping: {\n settings: {\n text: ':rocket: Deployment complete: ${data.version} to ${data.environment}',\n },\n },\n out: [\n [\n 'sendServer',\n 'https://hooks.slack.com/services/T00/B00/xxx',\n JSON.stringify({\n text: ':rocket: Deployment complete: 1.4.2 to prod',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n }),\n ],\n ],\n};\n"],"mappings":"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","names":["import_dev","import_dev"]}
|
|
1
|
+
{"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z\n .object({\n token: z\n .string()\n .startsWith('xoxb-')\n .describe(\n 'Slack Bot token (xoxb-...). Enables Web API mode. Mutually exclusive with webhookUrl.',\n )\n .optional(),\n webhookUrl: z\n .string()\n .url()\n .describe(\n 'Incoming Webhook URL. Enables webhook mode. Mutually exclusive with token.',\n )\n .optional(),\n channel: z\n .string()\n .describe(\n 'Default Slack channel ID or name (e.g. \"#alerts\" or \"C024BE91L\"). Required for Web API mode unless every rule supplies one. Ignored in webhook mode.',\n )\n .optional(),\n text: z\n .string()\n .describe(\n 'Default text template. Supports `${data.field}` interpolation against the walkerOS event.',\n )\n .optional(),\n blocks: z\n .array(z.record(z.string(), z.unknown()))\n .describe(\n 'Default Block Kit blocks applied when no mapping override is set.',\n )\n .optional(),\n includeHeader: z\n .boolean()\n .describe(\n 'Auto-add an event-name header block when generating default blocks. Default: true.',\n )\n .optional(),\n unfurlLinks: z\n .boolean()\n .describe(\n 'Enable link unfurling. Default: false (cleaner for automated alerts).',\n )\n .optional(),\n unfurlMedia: z\n .boolean()\n .describe('Enable media unfurling. Default: false.')\n .optional(),\n mrkdwn: z\n .boolean()\n .describe('Use mrkdwn formatting in text. Default: true.')\n .optional(),\n threadTs: z\n .string()\n .describe(\n 'Static thread_ts for replies (rarely set at destination level).',\n )\n .optional(),\n retryConfig: z\n .enum(['default', 'fiveRetriesInFiveMinutes', 'none'])\n .describe('Retry policy passed to WebClient. Default: \"default\".')\n .optional(),\n })\n .refine((v) => Boolean(v.token) !== Boolean(v.webhookUrl), {\n message: 'Provide exactly one of `token` or `webhookUrl`.',\n });\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n channel: z\n .string()\n .describe(\n 'Override the destination channel for this rule. Web API mode only -- ignored in webhook mode.',\n )\n .optional(),\n text: z\n .string()\n .describe(\n 'Override the text template for this rule. Supports `${data.field}` interpolation.',\n )\n .optional(),\n blocks: z\n .array(z.record(z.string(), z.unknown()))\n .describe('Override Block Kit blocks for this rule.')\n .optional(),\n threadTs: z\n .string()\n .describe('thread_ts for posting as a reply in a thread.')\n .optional(),\n replyBroadcast: z\n .boolean()\n .describe('Also broadcast the threaded reply back to the channel.')\n .optional(),\n ephemeral: z\n .boolean()\n .describe('Send via chat.postEphemeral. Requires `user`.')\n .optional(),\n user: z\n .string()\n .describe('Slack user ID for ephemeral or DM delivery.')\n .optional(),\n dm: z\n .boolean()\n .describe(\n 'Send as DM via conversations.open + chat.postMessage. Requires `user`.',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env, SlackClientMock } from '../types';\n\nconst okMessageResponse = {\n ok: true as const,\n channel: 'CMOCK',\n ts: '1700000000.000100',\n};\n\nconst okEphemeralResponse = { ok: true as const };\n\nconst okOpenResponse = {\n ok: true as const,\n channel: { id: 'D-MOCK-DM' },\n};\n\nfunction createMockClient(): SlackClientMock {\n return {\n chat: {\n postMessage: () => Promise.resolve(okMessageResponse as never),\n postEphemeral: () => Promise.resolve(okEphemeralResponse as never),\n },\n conversations: {\n open: () => Promise.resolve(okOpenResponse as never),\n },\n };\n}\n\nexport const push: Env = {\n slackClient: createMockClient(),\n sendServer: (() =>\n Promise.resolve({ ok: true } as never)) as Env['sendServer'],\n};\n\nexport const simulation = [\n 'call:slackClient.chat.postMessage',\n 'call:slackClient.chat.postEphemeral',\n 'call:slackClient.conversations.open',\n 'call:sendServer',\n];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type SlackStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Slack server destination operates in two modes:\n *\n * 1. Web API mode — calls the injected `env.slackClient` SDK methods\n * (`chat.postMessage`, `chat.postEphemeral`, `conversations.open`).\n * Captured as `[callable, args]` with dotted callable names such as\n * `'slackClient.chat.postMessage'`.\n *\n * 2. Webhook mode — calls `env.sendServer(url, JSON.stringify(body))`.\n * Captured as `['sendServer', url, bodyAsString]` where `bodyAsString`\n * is the already-stringified JSON body. Key insertion order in the\n * source object matters for string equality.\n *\n * A single push may emit multiple calls (e.g. a DM opens a conversation\n * then posts to the returned channel id), so every `out` is wrapped as\n * `[[callable, ...args], ...]`.\n */\n\n/**\n * Purchase notification -- Web API mode, channel from mapping override,\n * text template interpolated against event.data.\n */\nexport const purchaseAlert: SlackStepExample = {\n title: 'Purchase alert',\n description:\n 'A completed order posts a templated message to a sales channel via the Slack Web API.',\n in: getEvent('order complete', {\n timestamp: 1700000100,\n data: {\n id: 'ORD-500',\n total: 299.99,\n currency: 'EUR',\n product: 'Pro Plan',\n },\n user: { id: 'buyer-42' },\n }),\n mapping: {\n settings: {\n channel: '#sales',\n text: ':moneybag: New order: ${data.id} - ${data.total} ${data.currency}',\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#sales',\n text: ':moneybag: New order: ORD-500 - 299.99 EUR',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Error alert -- routes to a different channel via mapping override.\n */\nexport const errorAlert: SlackStepExample = {\n title: 'Error alert',\n description:\n 'An error event posts a critical alert to an engineering channel using a mapping-level channel override.',\n in: getEvent('error occur', {\n timestamp: 1700000200,\n data: {\n message: 'Payment gateway timeout',\n code: 'PGW_TIMEOUT',\n severity: 'critical',\n },\n }),\n mapping: {\n settings: {\n channel: '#engineering-alerts',\n text: ':rotating_light: Error: ${data.message}',\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#engineering-alerts',\n text: ':rotating_light: Error: Payment gateway timeout',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Welcome DM -- conversations.open(users) -> chat.postMessage(channel: D-id).\n */\nexport const welcomeDM: SlackStepExample = {\n title: 'Welcome DM',\n description:\n 'A user signup opens a Slack DM channel and posts a welcome message with the selected plan.',\n in: getEvent('user signup', {\n timestamp: 1700000300,\n data: { plan: 'enterprise' },\n user: { id: 'U-NEW-USER' },\n }),\n mapping: {\n settings: {\n dm: true,\n user: 'U-NEW-USER',\n text: ':wave: Welcome aboard! You signed up for the ${data.plan} plan.',\n },\n },\n out: [\n ['slackClient.conversations.open', { users: 'U-NEW-USER' }],\n [\n 'slackClient.chat.postMessage',\n {\n channel: 'D-MOCK-DM',\n text: ':wave: Welcome aboard! You signed up for the enterprise plan.',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Threaded checkout step -- thread_ts override puts the reply into a thread.\n */\nexport const threadedCheckoutStep: SlackStepExample = {\n title: 'Threaded reply',\n description:\n 'A checkout step posts as a threaded reply in Slack via thread_ts with broadcast to the channel.',\n in: getEvent('checkout step', {\n timestamp: 1700000400,\n data: { step: 'payment', sessionTs: '1700000000.000050' },\n }),\n mapping: {\n settings: {\n channel: '#sales',\n text: 'Checkout step: ${data.step}',\n threadTs: '1700000000.000050',\n replyBroadcast: true,\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#sales',\n text: 'Checkout step: payment',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n thread_ts: '1700000000.000050',\n reply_broadcast: true,\n },\n ],\n ],\n};\n\n/**\n * Ephemeral message -- visible to one user in the target channel.\n */\nexport const ephemeralMessage: SlackStepExample = {\n title: 'Ephemeral message',\n description:\n 'A quota warning posts an ephemeral Slack message visible only to a target admin user.',\n in: getEvent('quota warning', {\n timestamp: 1700000500,\n data: { remaining: 5 },\n }),\n mapping: {\n settings: {\n channel: '#admin',\n ephemeral: true,\n user: 'U-ADMIN-1',\n text: 'Heads up: ${data.remaining} requests remaining',\n },\n },\n out: [\n [\n 'slackClient.chat.postEphemeral',\n {\n channel: '#admin',\n text: 'Heads up: 5 requests remaining',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n user: 'U-ADMIN-1',\n },\n ],\n ],\n};\n\n/**\n * Default blocks -- no custom text/blocks, destination auto-generates a\n * Block Kit message from the event data.\n */\nexport const defaultBlocks: SlackStepExample = {\n title: 'Default blocks',\n description:\n 'With no custom text the destination auto-generates a Block Kit message from event data and source.',\n in: getEvent('lead submit', {\n timestamp: 1700000600,\n data: { name: 'Acme', email: 'sales@acme.test' },\n source: { type: 'server', id: 'crm', previous_id: '' },\n }),\n mapping: {\n settings: {\n channel: '#growth',\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#growth',\n text: 'lead submit',\n blocks: [\n {\n type: 'header',\n text: { type: 'plain_text', text: 'lead submit' },\n },\n {\n type: 'section',\n fields: [\n { type: 'mrkdwn', text: '*name:*\\nAcme' },\n { type: 'mrkdwn', text: '*email:*\\nsales@acme.test' },\n ],\n },\n {\n type: 'context',\n elements: [{ type: 'mrkdwn', text: 'Source: crm' }],\n },\n ],\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Webhook mode -- no token, just webhookUrl. The destination calls\n * `env.sendServer(url, JSON.stringify(body))`. Channel is baked into the\n * URL by Slack.\n */\nexport const deployNotification: SlackStepExample = {\n title: 'Webhook deploy',\n description:\n 'Without a token the destination posts to an incoming Slack webhook URL with the rendered message body.',\n in: getEvent('deploy complete', {\n timestamp: 1700000700,\n data: { version: '1.4.2', environment: 'prod' },\n }),\n settings: {\n token: undefined,\n webhookUrl: 'https://hooks.slack.com/services/T00/B00/xxx',\n },\n mapping: {\n settings: {\n text: ':rocket: Deployment complete: ${data.version} to ${data.environment}',\n },\n },\n out: [\n [\n 'sendServer',\n 'https://hooks.slack.com/services/T00/B00/xxx',\n JSON.stringify({\n text: ':rocket: Deployment complete: 1.4.2 to prod',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n }),\n ],\n ],\n};\n"],"mappings":"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","names":["import_dev","import_dev"]}
|
package/dist/dev.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,t=(t,a)=>{for(var n in a)e(t,n,{get:a[n],enumerable:!0})},a={};t(a,{MappingSchema:()=>i,SettingsSchema:()=>
|
|
1
|
+
var e=Object.defineProperty,t=(t,a)=>{for(var n in a)e(t,n,{get:a[n],enumerable:!0})},a={};t(a,{MappingSchema:()=>i,SettingsSchema:()=>r,mapping:()=>c,settings:()=>l});import{zodToSchema as n}from"@walkeros/core/dev";import{z as o}from"@walkeros/core/dev";var r=o.object({token:o.string().startsWith("xoxb-").describe("Slack Bot token (xoxb-...). Enables Web API mode. Mutually exclusive with webhookUrl.").optional(),webhookUrl:o.string().url().describe("Incoming Webhook URL. Enables webhook mode. Mutually exclusive with token.").optional(),channel:o.string().describe('Default Slack channel ID or name (e.g. "#alerts" or "C024BE91L"). Required for Web API mode unless every rule supplies one. Ignored in webhook mode.').optional(),text:o.string().describe("Default text template. Supports `${data.field}` interpolation against the walkerOS event.").optional(),blocks:o.array(o.record(o.string(),o.unknown())).describe("Default Block Kit blocks applied when no mapping override is set.").optional(),includeHeader:o.boolean().describe("Auto-add an event-name header block when generating default blocks. Default: true.").optional(),unfurlLinks:o.boolean().describe("Enable link unfurling. Default: false (cleaner for automated alerts).").optional(),unfurlMedia:o.boolean().describe("Enable media unfurling. Default: false.").optional(),mrkdwn:o.boolean().describe("Use mrkdwn formatting in text. Default: true.").optional(),threadTs:o.string().describe("Static thread_ts for replies (rarely set at destination level).").optional(),retryConfig:o.enum(["default","fiveRetriesInFiveMinutes","none"]).describe('Retry policy passed to WebClient. Default: "default".').optional()}).refine(e=>Boolean(e.token)!==Boolean(e.webhookUrl),{message:"Provide exactly one of `token` or `webhookUrl`."});import{z as s}from"@walkeros/core/dev";var i=s.object({channel:s.string().describe("Override the destination channel for this rule. Web API mode only -- ignored in webhook mode.").optional(),text:s.string().describe("Override the text template for this rule. Supports `${data.field}` interpolation.").optional(),blocks:s.array(s.record(s.string(),s.unknown())).describe("Override Block Kit blocks for this rule.").optional(),threadTs:s.string().describe("thread_ts for posting as a reply in a thread.").optional(),replyBroadcast:s.boolean().describe("Also broadcast the threaded reply back to the channel.").optional(),ephemeral:s.boolean().describe("Send via chat.postEphemeral. Requires `user`.").optional(),user:s.string().describe("Slack user ID for ephemeral or DM delivery.").optional(),dm:s.boolean().describe("Send as DM via conversations.open + chat.postMessage. Requires `user`.").optional()}),l=n(r),c=n(i),d={};t(d,{env:()=>p,step:()=>b});var p={};t(p,{push:()=>g,simulation:()=>k});var m={ok:!0,channel:"CMOCK",ts:"1700000000.000100"},u={ok:!0},h={ok:!0,channel:{id:"D-MOCK-DM"}};var g={slackClient:{chat:{postMessage:()=>Promise.resolve(m),postEphemeral:()=>Promise.resolve(u)},conversations:{open:()=>Promise.resolve(h)}},sendServer:()=>Promise.resolve({ok:!0})},k=["call:slackClient.chat.postMessage","call:slackClient.chat.postEphemeral","call:slackClient.conversations.open","call:sendServer"],b={};t(b,{defaultBlocks:()=>D,deployNotification:()=>S,ephemeralMessage:()=>M,errorAlert:()=>y,purchaseAlert:()=>v,threadedCheckoutStep:()=>x,welcomeDM:()=>w});import{getEvent as f}from"@walkeros/core";var v={title:"Purchase alert",description:"A completed order posts a templated message to a sales channel via the Slack Web API.",in:f("order complete",{timestamp:1700000100,data:{id:"ORD-500",total:299.99,currency:"EUR",product:"Pro Plan"},user:{id:"buyer-42"}}),mapping:{settings:{channel:"#sales",text:":moneybag: New order: ${data.id} - ${data.total} ${data.currency}"}},out:[["slackClient.chat.postMessage",{channel:"#sales",text:":moneybag: New order: ORD-500 - 299.99 EUR",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0}]]},y={title:"Error alert",description:"An error event posts a critical alert to an engineering channel using a mapping-level channel override.",in:f("error occur",{timestamp:1700000200,data:{message:"Payment gateway timeout",code:"PGW_TIMEOUT",severity:"critical"}}),mapping:{settings:{channel:"#engineering-alerts",text:":rotating_light: Error: ${data.message}"}},out:[["slackClient.chat.postMessage",{channel:"#engineering-alerts",text:":rotating_light: Error: Payment gateway timeout",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0}]]},w={title:"Welcome DM",description:"A user signup opens a Slack DM channel and posts a welcome message with the selected plan.",in:f("user signup",{timestamp:1700000300,data:{plan:"enterprise"},user:{id:"U-NEW-USER"}}),mapping:{settings:{dm:!0,user:"U-NEW-USER",text:":wave: Welcome aboard! You signed up for the ${data.plan} plan."}},out:[["slackClient.conversations.open",{users:"U-NEW-USER"}],["slackClient.chat.postMessage",{channel:"D-MOCK-DM",text:":wave: Welcome aboard! You signed up for the enterprise plan.",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0}]]},x={title:"Threaded reply",description:"A checkout step posts as a threaded reply in Slack via thread_ts with broadcast to the channel.",in:f("checkout step",{timestamp:1700000400,data:{step:"payment",sessionTs:"1700000000.000050"}}),mapping:{settings:{channel:"#sales",text:"Checkout step: ${data.step}",threadTs:"1700000000.000050",replyBroadcast:!0}},out:[["slackClient.chat.postMessage",{channel:"#sales",text:"Checkout step: payment",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0,thread_ts:"1700000000.000050",reply_broadcast:!0}]]},M={title:"Ephemeral message",description:"A quota warning posts an ephemeral Slack message visible only to a target admin user.",in:f("quota warning",{timestamp:1700000500,data:{remaining:5}}),mapping:{settings:{channel:"#admin",ephemeral:!0,user:"U-ADMIN-1",text:"Heads up: ${data.remaining} requests remaining"}},out:[["slackClient.chat.postEphemeral",{channel:"#admin",text:"Heads up: 5 requests remaining",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0,user:"U-ADMIN-1"}]]},D={title:"Default blocks",description:"With no custom text the destination auto-generates a Block Kit message from event data and source.",in:f("lead submit",{timestamp:1700000600,data:{name:"Acme",email:"sales@acme.test"},source:{type:"server",id:"crm",previous_id:""}}),mapping:{settings:{channel:"#growth"}},out:[["slackClient.chat.postMessage",{channel:"#growth",text:"lead submit",blocks:[{type:"header",text:{type:"plain_text",text:"lead submit"}},{type:"section",fields:[{type:"mrkdwn",text:"*name:*\nAcme"},{type:"mrkdwn",text:"*email:*\nsales@acme.test"}]},{type:"context",elements:[{type:"mrkdwn",text:"Source: crm"}]}],unfurl_links:!1,unfurl_media:!1,mrkdwn:!0}]]},S={title:"Webhook deploy",description:"Without a token the destination posts to an incoming Slack webhook URL with the rendered message body.",in:f("deploy complete",{timestamp:1700000700,data:{version:"1.4.2",environment:"prod"}}),settings:{token:void 0,webhookUrl:"https://hooks.slack.com/services/T00/B00/xxx"},mapping:{settings:{text:":rocket: Deployment complete: ${data.version} to ${data.environment}"}},out:[["sendServer","https://hooks.slack.com/services/T00/B00/xxx",JSON.stringify({text:":rocket: Deployment complete: 1.4.2 to prod",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0})]]};export{d as examples,a as schemas};//# sourceMappingURL=dev.mjs.map
|
package/dist/dev.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z\n .object({\n token: z\n .string()\n .startsWith('xoxb-')\n .describe(\n 'Slack Bot token (xoxb-...). Enables Web API mode. Mutually exclusive with webhookUrl.',\n )\n .optional(),\n webhookUrl: z\n .string()\n .url()\n .describe(\n 'Incoming Webhook URL. Enables webhook mode. Mutually exclusive with token.',\n )\n .optional(),\n channel: z\n .string()\n .describe(\n 'Default Slack channel ID or name (e.g. \"#alerts\" or \"C024BE91L\"). Required for Web API mode unless every rule supplies one. Ignored in webhook mode.',\n )\n .optional(),\n text: z\n .string()\n .describe(\n 'Default text template. Supports `${data.field}` interpolation against the walkerOS event.',\n )\n .optional(),\n blocks: z\n .array(z.record(z.string(), z.unknown()))\n .describe(\n 'Default Block Kit blocks applied when no mapping override is set.',\n )\n .optional(),\n includeHeader: z\n .boolean()\n .describe(\n 'Auto-add an event-name header block when generating default blocks. Default: true.',\n )\n .optional(),\n unfurlLinks: z\n .boolean()\n .describe(\n 'Enable link unfurling. Default: false (cleaner for automated alerts).',\n )\n .optional(),\n unfurlMedia: z\n .boolean()\n .describe('Enable media unfurling. Default: false.')\n .optional(),\n mrkdwn: z\n .boolean()\n .describe('Use mrkdwn formatting in text. Default: true.')\n .optional(),\n threadTs: z\n .string()\n .describe(\n 'Static thread_ts for replies (rarely set at destination level).',\n )\n .optional(),\n retryConfig: z\n .enum(['default', 'fiveRetriesInFiveMinutes', 'none'])\n .describe('Retry policy passed to WebClient. Default: \"default\".')\n .optional(),\n })\n .refine((v) => Boolean(v.token) !== Boolean(v.webhookUrl), {\n message: 'Provide exactly one of `token` or `webhookUrl`.',\n });\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n channel: z\n .string()\n .describe(\n 'Override the destination channel for this rule. Web API mode only -- ignored in webhook mode.',\n )\n .optional(),\n text: z\n .string()\n .describe(\n 'Override the text template for this rule. Supports `${data.field}` interpolation.',\n )\n .optional(),\n blocks: z\n .array(z.record(z.string(), z.unknown()))\n .describe('Override Block Kit blocks for this rule.')\n .optional(),\n threadTs: z\n .string()\n .describe('thread_ts for posting as a reply in a thread.')\n .optional(),\n replyBroadcast: z\n .boolean()\n .describe('Also broadcast the threaded reply back to the channel.')\n .optional(),\n ephemeral: z\n .boolean()\n .describe('Send via chat.postEphemeral. Requires `user`.')\n .optional(),\n user: z\n .string()\n .describe('Slack user ID for ephemeral or DM delivery.')\n .optional(),\n dm: z\n .boolean()\n .describe(\n 'Send as DM via conversations.open + chat.postMessage. Requires `user`.',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env, SlackClientMock } from '../types';\n\nconst okMessageResponse = {\n ok: true as const,\n channel: 'CMOCK',\n ts: '1700000000.000100',\n};\n\nconst okEphemeralResponse = { ok: true as const };\n\nconst okOpenResponse = {\n ok: true as const,\n channel: { id: 'D-MOCK-DM' },\n};\n\nfunction createMockClient(): SlackClientMock {\n return {\n chat: {\n postMessage: () => Promise.resolve(okMessageResponse as never),\n postEphemeral: () => Promise.resolve(okEphemeralResponse as never),\n },\n conversations: {\n open: () => Promise.resolve(okOpenResponse as never),\n },\n };\n}\n\nexport const push: Env = {\n slackClient: createMockClient(),\n sendServer: (() =>\n Promise.resolve({ ok: true } as never)) as Env['sendServer'],\n};\n\nexport const simulation = [\n 'call:slackClient.chat.postMessage',\n 'call:slackClient.chat.postEphemeral',\n 'call:slackClient.conversations.open',\n 'call:sendServer',\n];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type SlackStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Slack server destination operates in two modes:\n *\n * 1. Web API mode — calls the injected `env.slackClient` SDK methods\n * (`chat.postMessage`, `chat.postEphemeral`, `conversations.open`).\n * Captured as `[callable, args]` with dotted callable names such as\n * `'slackClient.chat.postMessage'`.\n *\n * 2. Webhook mode — calls `env.sendServer(url, JSON.stringify(body))`.\n * Captured as `['sendServer', url, bodyAsString]` where `bodyAsString`\n * is the already-stringified JSON body. Key insertion order in the\n * source object matters for string equality.\n *\n * A single push may emit multiple calls (e.g. a DM opens a conversation\n * then posts to the returned channel id), so every `out` is wrapped as\n * `[[callable, ...args], ...]`.\n */\n\n/**\n * Purchase notification -- Web API mode, channel from mapping override,\n * text template interpolated against event.data.\n */\nexport const purchaseAlert: SlackStepExample = {\n in: getEvent('order complete', {\n timestamp: 1700000100,\n data: {\n id: 'ORD-500',\n total: 299.99,\n currency: 'EUR',\n product: 'Pro Plan',\n },\n user: { id: 'buyer-42' },\n }),\n mapping: {\n settings: {\n channel: '#sales',\n text: ':moneybag: New order: ${data.id} - ${data.total} ${data.currency}',\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#sales',\n text: ':moneybag: New order: ORD-500 - 299.99 EUR',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Error alert -- routes to a different channel via mapping override.\n */\nexport const errorAlert: SlackStepExample = {\n in: getEvent('error occur', {\n timestamp: 1700000200,\n data: {\n message: 'Payment gateway timeout',\n code: 'PGW_TIMEOUT',\n severity: 'critical',\n },\n }),\n mapping: {\n settings: {\n channel: '#engineering-alerts',\n text: ':rotating_light: Error: ${data.message}',\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#engineering-alerts',\n text: ':rotating_light: Error: Payment gateway timeout',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Welcome DM -- conversations.open(users) -> chat.postMessage(channel: D-id).\n */\nexport const welcomeDM: SlackStepExample = {\n in: getEvent('user signup', {\n timestamp: 1700000300,\n data: { plan: 'enterprise' },\n user: { id: 'U-NEW-USER' },\n }),\n mapping: {\n settings: {\n dm: true,\n user: 'U-NEW-USER',\n text: ':wave: Welcome aboard! You signed up for the ${data.plan} plan.',\n },\n },\n out: [\n ['slackClient.conversations.open', { users: 'U-NEW-USER' }],\n [\n 'slackClient.chat.postMessage',\n {\n channel: 'D-MOCK-DM',\n text: ':wave: Welcome aboard! You signed up for the enterprise plan.',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Threaded checkout step -- thread_ts override puts the reply into a thread.\n */\nexport const threadedCheckoutStep: SlackStepExample = {\n in: getEvent('checkout step', {\n timestamp: 1700000400,\n data: { step: 'payment', sessionTs: '1700000000.000050' },\n }),\n mapping: {\n settings: {\n channel: '#sales',\n text: 'Checkout step: ${data.step}',\n threadTs: '1700000000.000050',\n replyBroadcast: true,\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#sales',\n text: 'Checkout step: payment',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n thread_ts: '1700000000.000050',\n reply_broadcast: true,\n },\n ],\n ],\n};\n\n/**\n * Ephemeral message -- visible to one user in the target channel.\n */\nexport const ephemeralMessage: SlackStepExample = {\n in: getEvent('quota warning', {\n timestamp: 1700000500,\n data: { remaining: 5 },\n }),\n mapping: {\n settings: {\n channel: '#admin',\n ephemeral: true,\n user: 'U-ADMIN-1',\n text: 'Heads up: ${data.remaining} requests remaining',\n },\n },\n out: [\n [\n 'slackClient.chat.postEphemeral',\n {\n channel: '#admin',\n text: 'Heads up: 5 requests remaining',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n user: 'U-ADMIN-1',\n },\n ],\n ],\n};\n\n/**\n * Default blocks -- no custom text/blocks, destination auto-generates a\n * Block Kit message from the event data.\n */\nexport const defaultBlocks: SlackStepExample = {\n in: getEvent('lead submit', {\n timestamp: 1700000600,\n data: { name: 'Acme', email: 'sales@acme.test' },\n source: { type: 'server', id: 'crm', previous_id: '' },\n }),\n mapping: {\n settings: {\n channel: '#growth',\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#growth',\n text: 'lead submit',\n blocks: [\n {\n type: 'header',\n text: { type: 'plain_text', text: 'lead submit' },\n },\n {\n type: 'section',\n fields: [\n { type: 'mrkdwn', text: '*name:*\\nAcme' },\n { type: 'mrkdwn', text: '*email:*\\nsales@acme.test' },\n ],\n },\n {\n type: 'context',\n elements: [{ type: 'mrkdwn', text: 'Source: crm' }],\n },\n ],\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Webhook mode -- no token, just webhookUrl. The destination calls\n * `env.sendServer(url, JSON.stringify(body))`. Channel is baked into the\n * URL by Slack.\n */\nexport const deployNotification: SlackStepExample = {\n in: getEvent('deploy complete', {\n timestamp: 1700000700,\n data: { version: '1.4.2', environment: 'prod' },\n }),\n settings: {\n token: undefined,\n webhookUrl: 'https://hooks.slack.com/services/T00/B00/xxx',\n },\n mapping: {\n settings: {\n text: ':rocket: Deployment complete: ${data.version} to ${data.environment}',\n },\n },\n out: [\n [\n 'sendServer',\n 'https://hooks.slack.com/services/T00/B00/xxx',\n JSON.stringify({\n text: ':rocket: Deployment complete: 1.4.2 to prod',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n }),\n ],\n ],\n};\n"],"mappings":"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","names":["z"]}
|
|
1
|
+
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z\n .object({\n token: z\n .string()\n .startsWith('xoxb-')\n .describe(\n 'Slack Bot token (xoxb-...). Enables Web API mode. Mutually exclusive with webhookUrl.',\n )\n .optional(),\n webhookUrl: z\n .string()\n .url()\n .describe(\n 'Incoming Webhook URL. Enables webhook mode. Mutually exclusive with token.',\n )\n .optional(),\n channel: z\n .string()\n .describe(\n 'Default Slack channel ID or name (e.g. \"#alerts\" or \"C024BE91L\"). Required for Web API mode unless every rule supplies one. Ignored in webhook mode.',\n )\n .optional(),\n text: z\n .string()\n .describe(\n 'Default text template. Supports `${data.field}` interpolation against the walkerOS event.',\n )\n .optional(),\n blocks: z\n .array(z.record(z.string(), z.unknown()))\n .describe(\n 'Default Block Kit blocks applied when no mapping override is set.',\n )\n .optional(),\n includeHeader: z\n .boolean()\n .describe(\n 'Auto-add an event-name header block when generating default blocks. Default: true.',\n )\n .optional(),\n unfurlLinks: z\n .boolean()\n .describe(\n 'Enable link unfurling. Default: false (cleaner for automated alerts).',\n )\n .optional(),\n unfurlMedia: z\n .boolean()\n .describe('Enable media unfurling. Default: false.')\n .optional(),\n mrkdwn: z\n .boolean()\n .describe('Use mrkdwn formatting in text. Default: true.')\n .optional(),\n threadTs: z\n .string()\n .describe(\n 'Static thread_ts for replies (rarely set at destination level).',\n )\n .optional(),\n retryConfig: z\n .enum(['default', 'fiveRetriesInFiveMinutes', 'none'])\n .describe('Retry policy passed to WebClient. Default: \"default\".')\n .optional(),\n })\n .refine((v) => Boolean(v.token) !== Boolean(v.webhookUrl), {\n message: 'Provide exactly one of `token` or `webhookUrl`.',\n });\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n channel: z\n .string()\n .describe(\n 'Override the destination channel for this rule. Web API mode only -- ignored in webhook mode.',\n )\n .optional(),\n text: z\n .string()\n .describe(\n 'Override the text template for this rule. Supports `${data.field}` interpolation.',\n )\n .optional(),\n blocks: z\n .array(z.record(z.string(), z.unknown()))\n .describe('Override Block Kit blocks for this rule.')\n .optional(),\n threadTs: z\n .string()\n .describe('thread_ts for posting as a reply in a thread.')\n .optional(),\n replyBroadcast: z\n .boolean()\n .describe('Also broadcast the threaded reply back to the channel.')\n .optional(),\n ephemeral: z\n .boolean()\n .describe('Send via chat.postEphemeral. Requires `user`.')\n .optional(),\n user: z\n .string()\n .describe('Slack user ID for ephemeral or DM delivery.')\n .optional(),\n dm: z\n .boolean()\n .describe(\n 'Send as DM via conversations.open + chat.postMessage. Requires `user`.',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env, SlackClientMock } from '../types';\n\nconst okMessageResponse = {\n ok: true as const,\n channel: 'CMOCK',\n ts: '1700000000.000100',\n};\n\nconst okEphemeralResponse = { ok: true as const };\n\nconst okOpenResponse = {\n ok: true as const,\n channel: { id: 'D-MOCK-DM' },\n};\n\nfunction createMockClient(): SlackClientMock {\n return {\n chat: {\n postMessage: () => Promise.resolve(okMessageResponse as never),\n postEphemeral: () => Promise.resolve(okEphemeralResponse as never),\n },\n conversations: {\n open: () => Promise.resolve(okOpenResponse as never),\n },\n };\n}\n\nexport const push: Env = {\n slackClient: createMockClient(),\n sendServer: (() =>\n Promise.resolve({ ok: true } as never)) as Env['sendServer'],\n};\n\nexport const simulation = [\n 'call:slackClient.chat.postMessage',\n 'call:slackClient.chat.postEphemeral',\n 'call:slackClient.conversations.open',\n 'call:sendServer',\n];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type SlackStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Slack server destination operates in two modes:\n *\n * 1. Web API mode — calls the injected `env.slackClient` SDK methods\n * (`chat.postMessage`, `chat.postEphemeral`, `conversations.open`).\n * Captured as `[callable, args]` with dotted callable names such as\n * `'slackClient.chat.postMessage'`.\n *\n * 2. Webhook mode — calls `env.sendServer(url, JSON.stringify(body))`.\n * Captured as `['sendServer', url, bodyAsString]` where `bodyAsString`\n * is the already-stringified JSON body. Key insertion order in the\n * source object matters for string equality.\n *\n * A single push may emit multiple calls (e.g. a DM opens a conversation\n * then posts to the returned channel id), so every `out` is wrapped as\n * `[[callable, ...args], ...]`.\n */\n\n/**\n * Purchase notification -- Web API mode, channel from mapping override,\n * text template interpolated against event.data.\n */\nexport const purchaseAlert: SlackStepExample = {\n title: 'Purchase alert',\n description:\n 'A completed order posts a templated message to a sales channel via the Slack Web API.',\n in: getEvent('order complete', {\n timestamp: 1700000100,\n data: {\n id: 'ORD-500',\n total: 299.99,\n currency: 'EUR',\n product: 'Pro Plan',\n },\n user: { id: 'buyer-42' },\n }),\n mapping: {\n settings: {\n channel: '#sales',\n text: ':moneybag: New order: ${data.id} - ${data.total} ${data.currency}',\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#sales',\n text: ':moneybag: New order: ORD-500 - 299.99 EUR',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Error alert -- routes to a different channel via mapping override.\n */\nexport const errorAlert: SlackStepExample = {\n title: 'Error alert',\n description:\n 'An error event posts a critical alert to an engineering channel using a mapping-level channel override.',\n in: getEvent('error occur', {\n timestamp: 1700000200,\n data: {\n message: 'Payment gateway timeout',\n code: 'PGW_TIMEOUT',\n severity: 'critical',\n },\n }),\n mapping: {\n settings: {\n channel: '#engineering-alerts',\n text: ':rotating_light: Error: ${data.message}',\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#engineering-alerts',\n text: ':rotating_light: Error: Payment gateway timeout',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Welcome DM -- conversations.open(users) -> chat.postMessage(channel: D-id).\n */\nexport const welcomeDM: SlackStepExample = {\n title: 'Welcome DM',\n description:\n 'A user signup opens a Slack DM channel and posts a welcome message with the selected plan.',\n in: getEvent('user signup', {\n timestamp: 1700000300,\n data: { plan: 'enterprise' },\n user: { id: 'U-NEW-USER' },\n }),\n mapping: {\n settings: {\n dm: true,\n user: 'U-NEW-USER',\n text: ':wave: Welcome aboard! You signed up for the ${data.plan} plan.',\n },\n },\n out: [\n ['slackClient.conversations.open', { users: 'U-NEW-USER' }],\n [\n 'slackClient.chat.postMessage',\n {\n channel: 'D-MOCK-DM',\n text: ':wave: Welcome aboard! You signed up for the enterprise plan.',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Threaded checkout step -- thread_ts override puts the reply into a thread.\n */\nexport const threadedCheckoutStep: SlackStepExample = {\n title: 'Threaded reply',\n description:\n 'A checkout step posts as a threaded reply in Slack via thread_ts with broadcast to the channel.',\n in: getEvent('checkout step', {\n timestamp: 1700000400,\n data: { step: 'payment', sessionTs: '1700000000.000050' },\n }),\n mapping: {\n settings: {\n channel: '#sales',\n text: 'Checkout step: ${data.step}',\n threadTs: '1700000000.000050',\n replyBroadcast: true,\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#sales',\n text: 'Checkout step: payment',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n thread_ts: '1700000000.000050',\n reply_broadcast: true,\n },\n ],\n ],\n};\n\n/**\n * Ephemeral message -- visible to one user in the target channel.\n */\nexport const ephemeralMessage: SlackStepExample = {\n title: 'Ephemeral message',\n description:\n 'A quota warning posts an ephemeral Slack message visible only to a target admin user.',\n in: getEvent('quota warning', {\n timestamp: 1700000500,\n data: { remaining: 5 },\n }),\n mapping: {\n settings: {\n channel: '#admin',\n ephemeral: true,\n user: 'U-ADMIN-1',\n text: 'Heads up: ${data.remaining} requests remaining',\n },\n },\n out: [\n [\n 'slackClient.chat.postEphemeral',\n {\n channel: '#admin',\n text: 'Heads up: 5 requests remaining',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n user: 'U-ADMIN-1',\n },\n ],\n ],\n};\n\n/**\n * Default blocks -- no custom text/blocks, destination auto-generates a\n * Block Kit message from the event data.\n */\nexport const defaultBlocks: SlackStepExample = {\n title: 'Default blocks',\n description:\n 'With no custom text the destination auto-generates a Block Kit message from event data and source.',\n in: getEvent('lead submit', {\n timestamp: 1700000600,\n data: { name: 'Acme', email: 'sales@acme.test' },\n source: { type: 'server', id: 'crm', previous_id: '' },\n }),\n mapping: {\n settings: {\n channel: '#growth',\n },\n },\n out: [\n [\n 'slackClient.chat.postMessage',\n {\n channel: '#growth',\n text: 'lead submit',\n blocks: [\n {\n type: 'header',\n text: { type: 'plain_text', text: 'lead submit' },\n },\n {\n type: 'section',\n fields: [\n { type: 'mrkdwn', text: '*name:*\\nAcme' },\n { type: 'mrkdwn', text: '*email:*\\nsales@acme.test' },\n ],\n },\n {\n type: 'context',\n elements: [{ type: 'mrkdwn', text: 'Source: crm' }],\n },\n ],\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n },\n ],\n ],\n};\n\n/**\n * Webhook mode -- no token, just webhookUrl. The destination calls\n * `env.sendServer(url, JSON.stringify(body))`. Channel is baked into the\n * URL by Slack.\n */\nexport const deployNotification: SlackStepExample = {\n title: 'Webhook deploy',\n description:\n 'Without a token the destination posts to an incoming Slack webhook URL with the rendered message body.',\n in: getEvent('deploy complete', {\n timestamp: 1700000700,\n data: { version: '1.4.2', environment: 'prod' },\n }),\n settings: {\n token: undefined,\n webhookUrl: 'https://hooks.slack.com/services/T00/B00/xxx',\n },\n mapping: {\n settings: {\n text: ':rocket: Deployment complete: ${data.version} to ${data.environment}',\n },\n },\n out: [\n [\n 'sendServer',\n 'https://hooks.slack.com/services/T00/B00/xxx',\n JSON.stringify({\n text: ':rocket: Deployment complete: 1.4.2 to prod',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\n }),\n ],\n ],\n};\n"],"mappings":"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","names":["z"]}
|
package/dist/examples/index.js
CHANGED
|
@@ -76,6 +76,8 @@ __export(step_exports, {
|
|
|
76
76
|
});
|
|
77
77
|
var import_core = require("@walkeros/core");
|
|
78
78
|
var purchaseAlert = {
|
|
79
|
+
title: "Purchase alert",
|
|
80
|
+
description: "A completed order posts a templated message to a sales channel via the Slack Web API.",
|
|
79
81
|
in: (0, import_core.getEvent)("order complete", {
|
|
80
82
|
timestamp: 1700000100,
|
|
81
83
|
data: {
|
|
@@ -106,6 +108,8 @@ var purchaseAlert = {
|
|
|
106
108
|
]
|
|
107
109
|
};
|
|
108
110
|
var errorAlert = {
|
|
111
|
+
title: "Error alert",
|
|
112
|
+
description: "An error event posts a critical alert to an engineering channel using a mapping-level channel override.",
|
|
109
113
|
in: (0, import_core.getEvent)("error occur", {
|
|
110
114
|
timestamp: 1700000200,
|
|
111
115
|
data: {
|
|
@@ -134,6 +138,8 @@ var errorAlert = {
|
|
|
134
138
|
]
|
|
135
139
|
};
|
|
136
140
|
var welcomeDM = {
|
|
141
|
+
title: "Welcome DM",
|
|
142
|
+
description: "A user signup opens a Slack DM channel and posts a welcome message with the selected plan.",
|
|
137
143
|
in: (0, import_core.getEvent)("user signup", {
|
|
138
144
|
timestamp: 1700000300,
|
|
139
145
|
data: { plan: "enterprise" },
|
|
@@ -161,6 +167,8 @@ var welcomeDM = {
|
|
|
161
167
|
]
|
|
162
168
|
};
|
|
163
169
|
var threadedCheckoutStep = {
|
|
170
|
+
title: "Threaded reply",
|
|
171
|
+
description: "A checkout step posts as a threaded reply in Slack via thread_ts with broadcast to the channel.",
|
|
164
172
|
in: (0, import_core.getEvent)("checkout step", {
|
|
165
173
|
timestamp: 1700000400,
|
|
166
174
|
data: { step: "payment", sessionTs: "1700000000.000050" }
|
|
@@ -189,6 +197,8 @@ var threadedCheckoutStep = {
|
|
|
189
197
|
]
|
|
190
198
|
};
|
|
191
199
|
var ephemeralMessage = {
|
|
200
|
+
title: "Ephemeral message",
|
|
201
|
+
description: "A quota warning posts an ephemeral Slack message visible only to a target admin user.",
|
|
192
202
|
in: (0, import_core.getEvent)("quota warning", {
|
|
193
203
|
timestamp: 1700000500,
|
|
194
204
|
data: { remaining: 5 }
|
|
@@ -216,6 +226,8 @@ var ephemeralMessage = {
|
|
|
216
226
|
]
|
|
217
227
|
};
|
|
218
228
|
var defaultBlocks = {
|
|
229
|
+
title: "Default blocks",
|
|
230
|
+
description: "With no custom text the destination auto-generates a Block Kit message from event data and source.",
|
|
219
231
|
in: (0, import_core.getEvent)("lead submit", {
|
|
220
232
|
timestamp: 1700000600,
|
|
221
233
|
data: { name: "Acme", email: "sales@acme.test" },
|
|
@@ -257,6 +269,8 @@ var defaultBlocks = {
|
|
|
257
269
|
]
|
|
258
270
|
};
|
|
259
271
|
var deployNotification = {
|
|
272
|
+
title: "Webhook deploy",
|
|
273
|
+
description: "Without a token the destination posts to an incoming Slack webhook URL with the rendered message body.",
|
|
260
274
|
in: (0, import_core.getEvent)("deploy complete", {
|
|
261
275
|
timestamp: 1700000700,
|
|
262
276
|
data: { version: "1.4.2", environment: "prod" }
|
package/dist/examples/index.mjs
CHANGED
|
@@ -55,6 +55,8 @@ __export(step_exports, {
|
|
|
55
55
|
});
|
|
56
56
|
import { getEvent } from "@walkeros/core";
|
|
57
57
|
var purchaseAlert = {
|
|
58
|
+
title: "Purchase alert",
|
|
59
|
+
description: "A completed order posts a templated message to a sales channel via the Slack Web API.",
|
|
58
60
|
in: getEvent("order complete", {
|
|
59
61
|
timestamp: 1700000100,
|
|
60
62
|
data: {
|
|
@@ -85,6 +87,8 @@ var purchaseAlert = {
|
|
|
85
87
|
]
|
|
86
88
|
};
|
|
87
89
|
var errorAlert = {
|
|
90
|
+
title: "Error alert",
|
|
91
|
+
description: "An error event posts a critical alert to an engineering channel using a mapping-level channel override.",
|
|
88
92
|
in: getEvent("error occur", {
|
|
89
93
|
timestamp: 1700000200,
|
|
90
94
|
data: {
|
|
@@ -113,6 +117,8 @@ var errorAlert = {
|
|
|
113
117
|
]
|
|
114
118
|
};
|
|
115
119
|
var welcomeDM = {
|
|
120
|
+
title: "Welcome DM",
|
|
121
|
+
description: "A user signup opens a Slack DM channel and posts a welcome message with the selected plan.",
|
|
116
122
|
in: getEvent("user signup", {
|
|
117
123
|
timestamp: 1700000300,
|
|
118
124
|
data: { plan: "enterprise" },
|
|
@@ -140,6 +146,8 @@ var welcomeDM = {
|
|
|
140
146
|
]
|
|
141
147
|
};
|
|
142
148
|
var threadedCheckoutStep = {
|
|
149
|
+
title: "Threaded reply",
|
|
150
|
+
description: "A checkout step posts as a threaded reply in Slack via thread_ts with broadcast to the channel.",
|
|
143
151
|
in: getEvent("checkout step", {
|
|
144
152
|
timestamp: 1700000400,
|
|
145
153
|
data: { step: "payment", sessionTs: "1700000000.000050" }
|
|
@@ -168,6 +176,8 @@ var threadedCheckoutStep = {
|
|
|
168
176
|
]
|
|
169
177
|
};
|
|
170
178
|
var ephemeralMessage = {
|
|
179
|
+
title: "Ephemeral message",
|
|
180
|
+
description: "A quota warning posts an ephemeral Slack message visible only to a target admin user.",
|
|
171
181
|
in: getEvent("quota warning", {
|
|
172
182
|
timestamp: 1700000500,
|
|
173
183
|
data: { remaining: 5 }
|
|
@@ -195,6 +205,8 @@ var ephemeralMessage = {
|
|
|
195
205
|
]
|
|
196
206
|
};
|
|
197
207
|
var defaultBlocks = {
|
|
208
|
+
title: "Default blocks",
|
|
209
|
+
description: "With no custom text the destination auto-generates a Block Kit message from event data and source.",
|
|
198
210
|
in: getEvent("lead submit", {
|
|
199
211
|
timestamp: 1700000600,
|
|
200
212
|
data: { name: "Acme", email: "sales@acme.test" },
|
|
@@ -236,6 +248,8 @@ var defaultBlocks = {
|
|
|
236
248
|
]
|
|
237
249
|
};
|
|
238
250
|
var deployNotification = {
|
|
251
|
+
title: "Webhook deploy",
|
|
252
|
+
description: "Without a token the destination posts to an incoming Slack webhook URL with the rendered message body.",
|
|
239
253
|
in: getEvent("deploy complete", {
|
|
240
254
|
timestamp: 1700000700,
|
|
241
255
|
data: { version: "1.4.2", environment: "prod" }
|
package/dist/walkerOS.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$meta": {
|
|
3
3
|
"package": "@walkeros/server-destination-slack",
|
|
4
|
-
"version": "3.4.
|
|
4
|
+
"version": "3.4.1-next-1776790594143",
|
|
5
5
|
"type": "destination",
|
|
6
6
|
"platform": [
|
|
7
7
|
"server"
|
|
@@ -153,6 +153,8 @@
|
|
|
153
153
|
},
|
|
154
154
|
"step": {
|
|
155
155
|
"defaultBlocks": {
|
|
156
|
+
"title": "Default blocks",
|
|
157
|
+
"description": "With no custom text the destination auto-generates a Block Kit message from event data and source.",
|
|
156
158
|
"in": {
|
|
157
159
|
"name": "lead submit",
|
|
158
160
|
"data": {
|
|
@@ -203,7 +205,7 @@
|
|
|
203
205
|
"group": "gr0up",
|
|
204
206
|
"count": 1,
|
|
205
207
|
"version": {
|
|
206
|
-
"source": "3.4.
|
|
208
|
+
"source": "3.4.1-next-1776790594143",
|
|
207
209
|
"tagging": 1
|
|
208
210
|
},
|
|
209
211
|
"source": {
|
|
@@ -262,6 +264,8 @@
|
|
|
262
264
|
]
|
|
263
265
|
},
|
|
264
266
|
"deployNotification": {
|
|
267
|
+
"title": "Webhook deploy",
|
|
268
|
+
"description": "Without a token the destination posts to an incoming Slack webhook URL with the rendered message body.",
|
|
265
269
|
"in": {
|
|
266
270
|
"name": "deploy complete",
|
|
267
271
|
"data": {
|
|
@@ -312,7 +316,7 @@
|
|
|
312
316
|
"group": "gr0up",
|
|
313
317
|
"count": 1,
|
|
314
318
|
"version": {
|
|
315
|
-
"source": "3.4.
|
|
319
|
+
"source": "3.4.1-next-1776790594143",
|
|
316
320
|
"tagging": 1
|
|
317
321
|
},
|
|
318
322
|
"source": {
|
|
@@ -338,6 +342,8 @@
|
|
|
338
342
|
]
|
|
339
343
|
},
|
|
340
344
|
"ephemeralMessage": {
|
|
345
|
+
"title": "Ephemeral message",
|
|
346
|
+
"description": "A quota warning posts an ephemeral Slack message visible only to a target admin user.",
|
|
341
347
|
"in": {
|
|
342
348
|
"name": "quota warning",
|
|
343
349
|
"data": {
|
|
@@ -387,7 +393,7 @@
|
|
|
387
393
|
"group": "gr0up",
|
|
388
394
|
"count": 1,
|
|
389
395
|
"version": {
|
|
390
|
-
"source": "3.4.
|
|
396
|
+
"source": "3.4.1-next-1776790594143",
|
|
391
397
|
"tagging": 1
|
|
392
398
|
},
|
|
393
399
|
"source": {
|
|
@@ -419,6 +425,8 @@
|
|
|
419
425
|
]
|
|
420
426
|
},
|
|
421
427
|
"errorAlert": {
|
|
428
|
+
"title": "Error alert",
|
|
429
|
+
"description": "An error event posts a critical alert to an engineering channel using a mapping-level channel override.",
|
|
422
430
|
"in": {
|
|
423
431
|
"name": "error occur",
|
|
424
432
|
"data": {
|
|
@@ -470,7 +478,7 @@
|
|
|
470
478
|
"group": "gr0up",
|
|
471
479
|
"count": 1,
|
|
472
480
|
"version": {
|
|
473
|
-
"source": "3.4.
|
|
481
|
+
"source": "3.4.1-next-1776790594143",
|
|
474
482
|
"tagging": 1
|
|
475
483
|
},
|
|
476
484
|
"source": {
|
|
@@ -499,6 +507,8 @@
|
|
|
499
507
|
]
|
|
500
508
|
},
|
|
501
509
|
"purchaseAlert": {
|
|
510
|
+
"title": "Purchase alert",
|
|
511
|
+
"description": "A completed order posts a templated message to a sales channel via the Slack Web API.",
|
|
502
512
|
"in": {
|
|
503
513
|
"name": "order complete",
|
|
504
514
|
"data": {
|
|
@@ -582,7 +592,7 @@
|
|
|
582
592
|
"group": "gr0up",
|
|
583
593
|
"count": 1,
|
|
584
594
|
"version": {
|
|
585
|
-
"source": "3.4.
|
|
595
|
+
"source": "3.4.1-next-1776790594143",
|
|
586
596
|
"tagging": 1
|
|
587
597
|
},
|
|
588
598
|
"source": {
|
|
@@ -611,6 +621,8 @@
|
|
|
611
621
|
]
|
|
612
622
|
},
|
|
613
623
|
"threadedCheckoutStep": {
|
|
624
|
+
"title": "Threaded reply",
|
|
625
|
+
"description": "A checkout step posts as a threaded reply in Slack via thread_ts with broadcast to the channel.",
|
|
614
626
|
"in": {
|
|
615
627
|
"name": "checkout step",
|
|
616
628
|
"data": {
|
|
@@ -661,7 +673,7 @@
|
|
|
661
673
|
"group": "gr0up",
|
|
662
674
|
"count": 1,
|
|
663
675
|
"version": {
|
|
664
|
-
"source": "3.4.
|
|
676
|
+
"source": "3.4.1-next-1776790594143",
|
|
665
677
|
"tagging": 1
|
|
666
678
|
},
|
|
667
679
|
"source": {
|
|
@@ -694,6 +706,8 @@
|
|
|
694
706
|
]
|
|
695
707
|
},
|
|
696
708
|
"welcomeDM": {
|
|
709
|
+
"title": "Welcome DM",
|
|
710
|
+
"description": "A user signup opens a Slack DM channel and posts a welcome message with the selected plan.",
|
|
697
711
|
"in": {
|
|
698
712
|
"name": "user signup",
|
|
699
713
|
"data": {
|
|
@@ -741,7 +755,7 @@
|
|
|
741
755
|
"group": "gr0up",
|
|
742
756
|
"count": 1,
|
|
743
757
|
"version": {
|
|
744
|
-
"source": "3.4.
|
|
758
|
+
"source": "3.4.1-next-1776790594143",
|
|
745
759
|
"tagging": 1
|
|
746
760
|
},
|
|
747
761
|
"source": {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walkeros/server-destination-slack",
|
|
3
3
|
"description": "Slack server destination for walkerOS (Incoming Webhook + @slack/web-api, Block Kit, channel routing, threading, DMs)",
|
|
4
|
-
"version": "3.4.
|
|
4
|
+
"version": "3.4.1-next-1776790594143",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@slack/web-api": "^7.0.0",
|
|
38
|
-
"@walkeros/core": "3.4.
|
|
39
|
-
"@walkeros/server-core": "3.4.
|
|
38
|
+
"@walkeros/core": "3.4.1-next-1776790594143",
|
|
39
|
+
"@walkeros/server-core": "3.4.1-next-1776790594143"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@walkeros/collector": "3.4.
|
|
42
|
+
"@walkeros/collector": "3.4.1-next-1776790594143"
|
|
43
43
|
},
|
|
44
44
|
"repository": {
|
|
45
45
|
"url": "git+https://github.com/elbwalker/walkerOS.git",
|