@walkeros/server-destination-slack 3.3.0-next-1776098542393

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,132 @@
1
+ # @walkeros/server-destination-slack
2
+
3
+ Server-side Slack destination for
4
+ [walkerOS](https://github.com/elbwalker/walkerOS). Posts events to Slack as
5
+ formatted notifications via either an Incoming Webhook or the official
6
+ `@slack/web-api` SDK.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ npm install @walkeros/server-destination-slack
12
+ ```
13
+
14
+ ## Modes
15
+
16
+ The destination has two modes, selected by which auth setting you provide:
17
+
18
+ | Setting | Mode | Capabilities |
19
+ | ------------ | ------- | ----------------------------------------------------------- |
20
+ | `webhookUrl` | Webhook | Single channel, simple text + Block Kit |
21
+ | `token` | Web API | Multi-channel, threading, DMs, ephemeral, structured errors |
22
+
23
+ ## Quick Start (Web API mode)
24
+
25
+ ```json
26
+ {
27
+ "destinations": {
28
+ "slack": {
29
+ "package": "@walkeros/server-destination-slack",
30
+ "config": {
31
+ "settings": {
32
+ "token": "$SLACK_BOT_TOKEN",
33
+ "channel": "#alerts"
34
+ },
35
+ "mapping": {
36
+ "order": {
37
+ "complete": {
38
+ "settings": {
39
+ "channel": "#sales",
40
+ "text": ":moneybag: New order: ${data.id} - ${data.total} ${data.currency}"
41
+ }
42
+ }
43
+ },
44
+ "error": {
45
+ "*": {
46
+ "settings": {
47
+ "channel": "#engineering-alerts",
48
+ "text": ":rotating_light: ${data.severity}: ${data.message}"
49
+ }
50
+ }
51
+ }
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
57
+ ```
58
+
59
+ ## Quick Start (Webhook mode)
60
+
61
+ ```json
62
+ {
63
+ "destinations": {
64
+ "slack-deploys": {
65
+ "package": "@walkeros/server-destination-slack",
66
+ "config": {
67
+ "settings": {
68
+ "webhookUrl": "$SLACK_WEBHOOK_URL"
69
+ },
70
+ "mapping": {
71
+ "deploy": {
72
+ "complete": {
73
+ "settings": {
74
+ "text": ":rocket: Deployed ${data.version} to ${data.environment}"
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ ## Settings
86
+
87
+ | Setting | Type | Required | Default | Description |
88
+ | --------------- | ------- | -------- | ----------- | ----------------------------------------------------- |
89
+ | `token` | string | One of | -- | Bot token (`xoxb-...`). Enables Web API mode |
90
+ | `webhookUrl` | string | One of | -- | Incoming Webhook URL. Enables webhook mode |
91
+ | `channel` | string | Web API | -- | Default channel ID or name |
92
+ | `text` | string | No | -- | Default text template (`${data.field}` interpolation) |
93
+ | `blocks` | array | No | -- | Default Block Kit blocks |
94
+ | `includeHeader` | boolean | No | `true` | Auto-add event-name header in default blocks |
95
+ | `unfurlLinks` | boolean | No | `false` | Enable link unfurling |
96
+ | `unfurlMedia` | boolean | No | `false` | Enable media unfurling |
97
+ | `mrkdwn` | boolean | No | `true` | Use mrkdwn formatting |
98
+ | `retryConfig` | enum | No | `'default'` | Retry policy passed to WebClient |
99
+
100
+ ## Mapping Settings
101
+
102
+ Per-event mapping settings override destination defaults and unlock advanced
103
+ features.
104
+
105
+ | Setting | Effect | Mode |
106
+ | -------------------- | ------------------------------------------------------- | ------- |
107
+ | `channel` | Override channel for this rule | Web API |
108
+ | `text` | Override text template | Both |
109
+ | `blocks` | Override Block Kit blocks | Both |
110
+ | `threadTs` | Post as a thread reply | Web API |
111
+ | `replyBroadcast` | Broadcast threaded reply to channel | Web API |
112
+ | `ephemeral` + `user` | Post via `chat.postEphemeral` | Web API |
113
+ | `dm` + `user` | DM the user (`conversations.open` + `chat.postMessage`) | Web API |
114
+
115
+ ## Required Slack App Scopes (Web API mode)
116
+
117
+ - `chat:write` -- post messages to channels the bot is in
118
+ - `chat:write.public` -- post to any public channel without joining
119
+ - `im:write` -- open DM conversations (only needed for `dm: true`)
120
+
121
+ ## Rate Limiting
122
+
123
+ - **Web API mode**: the SDK handles 429 with `Retry-After` automatically
124
+ (default: 10 retries over ~30 min). Configure via `retryConfig`.
125
+ - **Webhook mode**: no automatic retry. Use Web API mode if you need retry on
126
+ rate limit.
127
+
128
+ ## Volume Notes
129
+
130
+ Slack is a notification channel, not an analytics warehouse. Use mapping
131
+ `condition` to filter important events; route different events to different
132
+ channels to spread the load.
package/dist/dev.d.mts ADDED
@@ -0,0 +1,164 @@
1
+ import * as _walkeros_core_dev from '@walkeros/core/dev';
2
+ import { z } from '@walkeros/core/dev';
3
+ import { DestinationServer, sendServer } from '@walkeros/server-core';
4
+ import { ChatPostMessageArguments, ChatPostMessageResponse, ChatPostEphemeralArguments, ChatPostEphemeralResponse, ConversationsOpenArguments, ConversationsOpenResponse, WebClient } from '@slack/web-api';
5
+ import { Flow } from '@walkeros/core';
6
+
7
+ declare const SettingsSchema: z.ZodObject<{
8
+ token: z.ZodOptional<z.ZodString>;
9
+ webhookUrl: z.ZodOptional<z.ZodString>;
10
+ channel: z.ZodOptional<z.ZodString>;
11
+ text: z.ZodOptional<z.ZodString>;
12
+ blocks: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
13
+ includeHeader: z.ZodOptional<z.ZodBoolean>;
14
+ unfurlLinks: z.ZodOptional<z.ZodBoolean>;
15
+ unfurlMedia: z.ZodOptional<z.ZodBoolean>;
16
+ mrkdwn: z.ZodOptional<z.ZodBoolean>;
17
+ threadTs: z.ZodOptional<z.ZodString>;
18
+ retryConfig: z.ZodOptional<z.ZodEnum<{
19
+ default: "default";
20
+ fiveRetriesInFiveMinutes: "fiveRetriesInFiveMinutes";
21
+ none: "none";
22
+ }>>;
23
+ }, z.core.$strip>;
24
+ type Settings$1 = z.infer<typeof SettingsSchema>;
25
+
26
+ declare const MappingSchema: z.ZodObject<{
27
+ channel: z.ZodOptional<z.ZodString>;
28
+ text: z.ZodOptional<z.ZodString>;
29
+ blocks: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
30
+ threadTs: z.ZodOptional<z.ZodString>;
31
+ replyBroadcast: z.ZodOptional<z.ZodBoolean>;
32
+ ephemeral: z.ZodOptional<z.ZodBoolean>;
33
+ user: z.ZodOptional<z.ZodString>;
34
+ dm: z.ZodOptional<z.ZodBoolean>;
35
+ }, z.core.$strip>;
36
+ type Mapping = z.infer<typeof MappingSchema>;
37
+
38
+ declare const settings: _walkeros_core_dev.JSONSchema;
39
+ declare const mapping: _walkeros_core_dev.JSONSchema;
40
+
41
+ type index$1_Mapping = Mapping;
42
+ declare const index$1_MappingSchema: typeof MappingSchema;
43
+ declare const index$1_SettingsSchema: typeof SettingsSchema;
44
+ declare const index$1_mapping: typeof mapping;
45
+ declare const index$1_settings: typeof settings;
46
+ declare namespace index$1 {
47
+ export { type index$1_Mapping as Mapping, index$1_MappingSchema as MappingSchema, type Settings$1 as Settings, index$1_SettingsSchema as SettingsSchema, index$1_mapping as mapping, index$1_settings as settings };
48
+ }
49
+
50
+ /** A single Block Kit block (kept loose -- Slack does not export a union type). */
51
+ type SlackBlock = Record<string, unknown>;
52
+ interface Settings {
53
+ /** Slack Bot token (xoxb-...). Enables Web API mode. */
54
+ token?: string;
55
+ /** Incoming Webhook URL. Enables webhook mode. */
56
+ webhookUrl?: string;
57
+ /** Default channel ID or name. Required for Web API mode unless every rule provides one. */
58
+ channel?: string;
59
+ /** Default text template. Supports `${data.field}` interpolation against the walkerOS event. */
60
+ text?: string;
61
+ /** Default Block Kit blocks applied when no mapping override is set. */
62
+ blocks?: SlackBlock[];
63
+ /** Auto-add an event-name header block when generating default blocks. Default: true. */
64
+ includeHeader?: boolean;
65
+ /** Enable link unfurling. Default: false. */
66
+ unfurlLinks?: boolean;
67
+ /** Enable media unfurling. Default: false. */
68
+ unfurlMedia?: boolean;
69
+ /** Use mrkdwn formatting. Default: true. */
70
+ mrkdwn?: boolean;
71
+ /** Static thread_ts to reply to (rarely set at destination level). */
72
+ threadTs?: string;
73
+ /** Retry policy passed to WebClient. Default: 'default'. */
74
+ retryConfig?: 'default' | 'fiveRetriesInFiveMinutes' | 'none';
75
+ _client?: WebClient;
76
+ }
77
+ /**
78
+ * Mock-friendly interface for the WebClient methods the destination calls.
79
+ * Tests inject this via env.slackClient.
80
+ */
81
+ interface SlackClientMock {
82
+ chat: {
83
+ postMessage: (opts: ChatPostMessageArguments) => Promise<ChatPostMessageResponse>;
84
+ postEphemeral: (opts: ChatPostEphemeralArguments) => Promise<ChatPostEphemeralResponse>;
85
+ };
86
+ conversations: {
87
+ open: (opts: ConversationsOpenArguments) => Promise<ConversationsOpenResponse>;
88
+ };
89
+ }
90
+ /**
91
+ * Env -- optional SDK / transport overrides. Production leaves these undefined.
92
+ * Tests inject `slackClient` (Web API mode) and/or `sendServer` (webhook mode).
93
+ */
94
+ interface Env extends DestinationServer.Env {
95
+ slackClient?: SlackClientMock;
96
+ sendServer?: typeof sendServer;
97
+ }
98
+
99
+ declare const push: Env;
100
+ declare const simulation: string[];
101
+
102
+ declare const env_push: typeof push;
103
+ declare const env_simulation: typeof simulation;
104
+ declare namespace env {
105
+ export { env_push as push, env_simulation as simulation };
106
+ }
107
+
108
+ /**
109
+ * Extended step example that may carry destination-level settings overrides.
110
+ */
111
+ type SlackStepExample = Flow.StepExample & {
112
+ settings?: Partial<Settings>;
113
+ };
114
+ /**
115
+ * Purchase notification -- Web API mode, channel from mapping override,
116
+ * text template interpolated against event.data.
117
+ */
118
+ declare const purchaseAlert: SlackStepExample;
119
+ /**
120
+ * Error alert -- routes to a different channel via mapping override.
121
+ */
122
+ declare const errorAlert: SlackStepExample;
123
+ /**
124
+ * Welcome DM -- conversations.open(users) -> chat.postMessage(channel: D-id).
125
+ */
126
+ declare const welcomeDM: SlackStepExample;
127
+ /**
128
+ * Threaded checkout step -- thread_ts override puts the reply into a thread.
129
+ */
130
+ declare const threadedCheckoutStep: SlackStepExample;
131
+ /**
132
+ * Ephemeral message -- visible to one user in the target channel.
133
+ */
134
+ declare const ephemeralMessage: SlackStepExample;
135
+ /**
136
+ * Default blocks -- no custom text/blocks, destination auto-generates a
137
+ * Block Kit message from the event data.
138
+ */
139
+ declare const defaultBlocks: SlackStepExample;
140
+ /**
141
+ * Webhook mode -- no token, just webhookUrl. The destination calls sendServer
142
+ * with the JSON body. Channel is baked into the URL by Slack.
143
+ */
144
+ declare const deployNotification: SlackStepExample;
145
+
146
+ type step_SlackStepExample = SlackStepExample;
147
+ declare const step_defaultBlocks: typeof defaultBlocks;
148
+ declare const step_deployNotification: typeof deployNotification;
149
+ declare const step_ephemeralMessage: typeof ephemeralMessage;
150
+ declare const step_errorAlert: typeof errorAlert;
151
+ declare const step_purchaseAlert: typeof purchaseAlert;
152
+ declare const step_threadedCheckoutStep: typeof threadedCheckoutStep;
153
+ declare const step_welcomeDM: typeof welcomeDM;
154
+ declare namespace step {
155
+ export { type step_SlackStepExample as SlackStepExample, step_defaultBlocks as defaultBlocks, step_deployNotification as deployNotification, step_ephemeralMessage as ephemeralMessage, step_errorAlert as errorAlert, step_purchaseAlert as purchaseAlert, step_threadedCheckoutStep as threadedCheckoutStep, step_welcomeDM as welcomeDM };
156
+ }
157
+
158
+ declare const index_env: typeof env;
159
+ declare const index_step: typeof step;
160
+ declare namespace index {
161
+ export { index_env as env, index_step as step };
162
+ }
163
+
164
+ export { index as examples, index$1 as schemas };
package/dist/dev.d.ts ADDED
@@ -0,0 +1,164 @@
1
+ import * as _walkeros_core_dev from '@walkeros/core/dev';
2
+ import { z } from '@walkeros/core/dev';
3
+ import { DestinationServer, sendServer } from '@walkeros/server-core';
4
+ import { ChatPostMessageArguments, ChatPostMessageResponse, ChatPostEphemeralArguments, ChatPostEphemeralResponse, ConversationsOpenArguments, ConversationsOpenResponse, WebClient } from '@slack/web-api';
5
+ import { Flow } from '@walkeros/core';
6
+
7
+ declare const SettingsSchema: z.ZodObject<{
8
+ token: z.ZodOptional<z.ZodString>;
9
+ webhookUrl: z.ZodOptional<z.ZodString>;
10
+ channel: z.ZodOptional<z.ZodString>;
11
+ text: z.ZodOptional<z.ZodString>;
12
+ blocks: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
13
+ includeHeader: z.ZodOptional<z.ZodBoolean>;
14
+ unfurlLinks: z.ZodOptional<z.ZodBoolean>;
15
+ unfurlMedia: z.ZodOptional<z.ZodBoolean>;
16
+ mrkdwn: z.ZodOptional<z.ZodBoolean>;
17
+ threadTs: z.ZodOptional<z.ZodString>;
18
+ retryConfig: z.ZodOptional<z.ZodEnum<{
19
+ default: "default";
20
+ fiveRetriesInFiveMinutes: "fiveRetriesInFiveMinutes";
21
+ none: "none";
22
+ }>>;
23
+ }, z.core.$strip>;
24
+ type Settings$1 = z.infer<typeof SettingsSchema>;
25
+
26
+ declare const MappingSchema: z.ZodObject<{
27
+ channel: z.ZodOptional<z.ZodString>;
28
+ text: z.ZodOptional<z.ZodString>;
29
+ blocks: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
30
+ threadTs: z.ZodOptional<z.ZodString>;
31
+ replyBroadcast: z.ZodOptional<z.ZodBoolean>;
32
+ ephemeral: z.ZodOptional<z.ZodBoolean>;
33
+ user: z.ZodOptional<z.ZodString>;
34
+ dm: z.ZodOptional<z.ZodBoolean>;
35
+ }, z.core.$strip>;
36
+ type Mapping = z.infer<typeof MappingSchema>;
37
+
38
+ declare const settings: _walkeros_core_dev.JSONSchema;
39
+ declare const mapping: _walkeros_core_dev.JSONSchema;
40
+
41
+ type index$1_Mapping = Mapping;
42
+ declare const index$1_MappingSchema: typeof MappingSchema;
43
+ declare const index$1_SettingsSchema: typeof SettingsSchema;
44
+ declare const index$1_mapping: typeof mapping;
45
+ declare const index$1_settings: typeof settings;
46
+ declare namespace index$1 {
47
+ export { type index$1_Mapping as Mapping, index$1_MappingSchema as MappingSchema, type Settings$1 as Settings, index$1_SettingsSchema as SettingsSchema, index$1_mapping as mapping, index$1_settings as settings };
48
+ }
49
+
50
+ /** A single Block Kit block (kept loose -- Slack does not export a union type). */
51
+ type SlackBlock = Record<string, unknown>;
52
+ interface Settings {
53
+ /** Slack Bot token (xoxb-...). Enables Web API mode. */
54
+ token?: string;
55
+ /** Incoming Webhook URL. Enables webhook mode. */
56
+ webhookUrl?: string;
57
+ /** Default channel ID or name. Required for Web API mode unless every rule provides one. */
58
+ channel?: string;
59
+ /** Default text template. Supports `${data.field}` interpolation against the walkerOS event. */
60
+ text?: string;
61
+ /** Default Block Kit blocks applied when no mapping override is set. */
62
+ blocks?: SlackBlock[];
63
+ /** Auto-add an event-name header block when generating default blocks. Default: true. */
64
+ includeHeader?: boolean;
65
+ /** Enable link unfurling. Default: false. */
66
+ unfurlLinks?: boolean;
67
+ /** Enable media unfurling. Default: false. */
68
+ unfurlMedia?: boolean;
69
+ /** Use mrkdwn formatting. Default: true. */
70
+ mrkdwn?: boolean;
71
+ /** Static thread_ts to reply to (rarely set at destination level). */
72
+ threadTs?: string;
73
+ /** Retry policy passed to WebClient. Default: 'default'. */
74
+ retryConfig?: 'default' | 'fiveRetriesInFiveMinutes' | 'none';
75
+ _client?: WebClient;
76
+ }
77
+ /**
78
+ * Mock-friendly interface for the WebClient methods the destination calls.
79
+ * Tests inject this via env.slackClient.
80
+ */
81
+ interface SlackClientMock {
82
+ chat: {
83
+ postMessage: (opts: ChatPostMessageArguments) => Promise<ChatPostMessageResponse>;
84
+ postEphemeral: (opts: ChatPostEphemeralArguments) => Promise<ChatPostEphemeralResponse>;
85
+ };
86
+ conversations: {
87
+ open: (opts: ConversationsOpenArguments) => Promise<ConversationsOpenResponse>;
88
+ };
89
+ }
90
+ /**
91
+ * Env -- optional SDK / transport overrides. Production leaves these undefined.
92
+ * Tests inject `slackClient` (Web API mode) and/or `sendServer` (webhook mode).
93
+ */
94
+ interface Env extends DestinationServer.Env {
95
+ slackClient?: SlackClientMock;
96
+ sendServer?: typeof sendServer;
97
+ }
98
+
99
+ declare const push: Env;
100
+ declare const simulation: string[];
101
+
102
+ declare const env_push: typeof push;
103
+ declare const env_simulation: typeof simulation;
104
+ declare namespace env {
105
+ export { env_push as push, env_simulation as simulation };
106
+ }
107
+
108
+ /**
109
+ * Extended step example that may carry destination-level settings overrides.
110
+ */
111
+ type SlackStepExample = Flow.StepExample & {
112
+ settings?: Partial<Settings>;
113
+ };
114
+ /**
115
+ * Purchase notification -- Web API mode, channel from mapping override,
116
+ * text template interpolated against event.data.
117
+ */
118
+ declare const purchaseAlert: SlackStepExample;
119
+ /**
120
+ * Error alert -- routes to a different channel via mapping override.
121
+ */
122
+ declare const errorAlert: SlackStepExample;
123
+ /**
124
+ * Welcome DM -- conversations.open(users) -> chat.postMessage(channel: D-id).
125
+ */
126
+ declare const welcomeDM: SlackStepExample;
127
+ /**
128
+ * Threaded checkout step -- thread_ts override puts the reply into a thread.
129
+ */
130
+ declare const threadedCheckoutStep: SlackStepExample;
131
+ /**
132
+ * Ephemeral message -- visible to one user in the target channel.
133
+ */
134
+ declare const ephemeralMessage: SlackStepExample;
135
+ /**
136
+ * Default blocks -- no custom text/blocks, destination auto-generates a
137
+ * Block Kit message from the event data.
138
+ */
139
+ declare const defaultBlocks: SlackStepExample;
140
+ /**
141
+ * Webhook mode -- no token, just webhookUrl. The destination calls sendServer
142
+ * with the JSON body. Channel is baked into the URL by Slack.
143
+ */
144
+ declare const deployNotification: SlackStepExample;
145
+
146
+ type step_SlackStepExample = SlackStepExample;
147
+ declare const step_defaultBlocks: typeof defaultBlocks;
148
+ declare const step_deployNotification: typeof deployNotification;
149
+ declare const step_ephemeralMessage: typeof ephemeralMessage;
150
+ declare const step_errorAlert: typeof errorAlert;
151
+ declare const step_purchaseAlert: typeof purchaseAlert;
152
+ declare const step_threadedCheckoutStep: typeof threadedCheckoutStep;
153
+ declare const step_welcomeDM: typeof welcomeDM;
154
+ declare namespace step {
155
+ export { type step_SlackStepExample as SlackStepExample, step_defaultBlocks as defaultBlocks, step_deployNotification as deployNotification, step_ephemeralMessage as ephemeralMessage, step_errorAlert as errorAlert, step_purchaseAlert as purchaseAlert, step_threadedCheckoutStep as threadedCheckoutStep, step_welcomeDM as welcomeDM };
156
+ }
157
+
158
+ declare const index_env: typeof env;
159
+ declare const index_step: typeof step;
160
+ declare namespace index {
161
+ export { index_env as env, index_step as step };
162
+ }
163
+
164
+ export { index as examples, index$1 as schemas };
package/dist/dev.js ADDED
@@ -0,0 +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:()=>l}),module.exports=(e=s,((e,o,s,l)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let i of n(o))r.call(e,i)||i===s||t(e,i,{get:()=>o[i],enumerable:!(l=a(o,i))||l.enumerable});return e})(t({},"__esModule",{value:!0}),e));var l={};o(l,{MappingSchema:()=>u,SettingsSchema:()=>d,mapping:()=>h,settings:()=>m});var i=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,i.zodToSchema)(d),h=(0,i.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"},f={ok:!0},v={ok:!0,channel:{id:"D-MOCK-DM"}};var y={slackClient:{chat:{postMessage:()=>Promise.resolve(b),postEphemeral:()=>Promise.resolve(f)},conversations:{open:()=>Promise.resolve(v)}},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:()=>U,ephemeralMessage:()=>S,errorAlert:()=>M,purchaseAlert:()=>E,threadedCheckoutStep:()=>D,welcomeDM:()=>_});var z=require("@walkeros/core"),E={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={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}]},_={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={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",thread_ts:"1700000000.000050",reply_broadcast:!0,unfurl_links:!1,unfurl_media:!1,mrkdwn:!0}]},S={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",user:"U-ADMIN-1",text:"Heads up: 5 requests remaining",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0}]},C={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}]},U={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",{text:":rocket: Deployment complete: 1.4.2 to prod",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0}]};//# sourceMappingURL=dev.js.map
@@ -0,0 +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 * 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 '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 * 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 '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 * 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 'slackClient.chat.postMessage',\n {\n channel: '#sales',\n text: 'Checkout step: payment',\n thread_ts: '1700000000.000050',\n reply_broadcast: true,\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\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 'slackClient.chat.postEphemeral',\n {\n channel: '#admin',\n user: 'U-ADMIN-1',\n text: 'Heads up: 5 requests remaining',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\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 '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 * Webhook mode -- no token, just webhookUrl. The destination calls sendServer\n * with the JSON body. Channel is baked into the 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 'sendServer',\n 'https://hooks.slack.com/services/T00/B00/xxx',\n {\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"],"mappings":"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","names":["import_dev","import_dev"]}
package/dist/dev.mjs ADDED
@@ -0,0 +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:()=>o,mapping:()=>c,settings:()=>l});import{zodToSchema as n}from"@walkeros/core/dev";import{z as r}from"@walkeros/core/dev";var o=r.object({token:r.string().startsWith("xoxb-").describe("Slack Bot token (xoxb-...). Enables Web API mode. Mutually exclusive with webhookUrl.").optional(),webhookUrl:r.string().url().describe("Incoming Webhook URL. Enables webhook mode. Mutually exclusive with token.").optional(),channel:r.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:r.string().describe("Default text template. Supports `${data.field}` interpolation against the walkerOS event.").optional(),blocks:r.array(r.record(r.string(),r.unknown())).describe("Default Block Kit blocks applied when no mapping override is set.").optional(),includeHeader:r.boolean().describe("Auto-add an event-name header block when generating default blocks. Default: true.").optional(),unfurlLinks:r.boolean().describe("Enable link unfurling. Default: false (cleaner for automated alerts).").optional(),unfurlMedia:r.boolean().describe("Enable media unfurling. Default: false.").optional(),mrkdwn:r.boolean().describe("Use mrkdwn formatting in text. Default: true.").optional(),threadTs:r.string().describe("Static thread_ts for replies (rarely set at destination level).").optional(),retryConfig:r.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(o),c=n(i),d={};t(d,{env:()=>p,step:()=>b});var p={};t(p,{push:()=>k,simulation:()=>g});var m={ok:!0,channel:"CMOCK",ts:"1700000000.000100"},u={ok:!0},h={ok:!0,channel:{id:"D-MOCK-DM"}};var k={slackClient:{chat:{postMessage:()=>Promise.resolve(m),postEphemeral:()=>Promise.resolve(u)},conversations:{open:()=>Promise.resolve(h)}},sendServer:()=>Promise.resolve({ok:!0})},g=["call:slackClient.chat.postMessage","call:slackClient.chat.postEphemeral","call:slackClient.conversations.open","call:sendServer"],b={};t(b,{defaultBlocks:()=>D,deployNotification:()=>_,ephemeralMessage:()=>M,errorAlert:()=>y,purchaseAlert:()=>v,threadedCheckoutStep:()=>x,welcomeDM:()=>w});import{getEvent as f}from"@walkeros/core";var v={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={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={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={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",thread_ts:"1700000000.000050",reply_broadcast:!0,unfurl_links:!1,unfurl_media:!1,mrkdwn:!0}]},M={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",user:"U-ADMIN-1",text:"Heads up: 5 requests remaining",unfurl_links:!1,unfurl_media:!1,mrkdwn:!0}]},D={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}]},_={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",{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
@@ -0,0 +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 * 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 '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 * 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 '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 * 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 'slackClient.chat.postMessage',\n {\n channel: '#sales',\n text: 'Checkout step: payment',\n thread_ts: '1700000000.000050',\n reply_broadcast: true,\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\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 'slackClient.chat.postEphemeral',\n {\n channel: '#admin',\n user: 'U-ADMIN-1',\n text: 'Heads up: 5 requests remaining',\n unfurl_links: false,\n unfurl_media: false,\n mrkdwn: true,\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 '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 * Webhook mode -- no token, just webhookUrl. The destination calls sendServer\n * with the JSON body. Channel is baked into the 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 'sendServer',\n 'https://hooks.slack.com/services/T00/B00/xxx',\n {\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"],"mappings":";;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,mBAAmB;;;ACA5B,SAAS,SAAS;AAEX,IAAM,iBAAiB,EAC3B,OAAO;AAAA,EACN,OAAO,EACJ,OAAO,EACP,WAAW,OAAO,EAClB;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,YAAY,EACT,OAAO,EACP,IAAI,EACJ;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,SAAS,EACN,OAAO,EACP;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,MAAM,EACH,OAAO,EACP;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,QAAQ,EACL,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,EACvC;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,eAAe,EACZ,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,aAAa,EACV,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,aAAa,EACV,QAAQ,EACR,SAAS,yCAAyC,EAClD,SAAS;AAAA,EACZ,QAAQ,EACL,QAAQ,EACR,SAAS,+CAA+C,EACxD,SAAS;AAAA,EACZ,UAAU,EACP,OAAO,EACP;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,aAAa,EACV,KAAK,CAAC,WAAW,4BAA4B,MAAM,CAAC,EACpD,SAAS,uDAAuD,EAChE,SAAS;AACd,CAAC,EACA,OAAO,CAAC,MAAM,QAAQ,EAAE,KAAK,MAAM,QAAQ,EAAE,UAAU,GAAG;AAAA,EACzD,SAAS;AACX,CAAC;;;ACrEH,SAAS,KAAAA,UAAS;AAEX,IAAM,gBAAgBA,GAAE,OAAO;AAAA,EACpC,SAASA,GACN,OAAO,EACP;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,MAAMA,GACH,OAAO,EACP;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,QAAQA,GACL,MAAMA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,CAAC,EACvC,SAAS,0CAA0C,EACnD,SAAS;AAAA,EACZ,UAAUA,GACP,OAAO,EACP,SAAS,+CAA+C,EACxD,SAAS;AAAA,EACZ,gBAAgBA,GACb,QAAQ,EACR,SAAS,wDAAwD,EACjE,SAAS;AAAA,EACZ,WAAWA,GACR,QAAQ,EACR,SAAS,+CAA+C,EACxD,SAAS;AAAA,EACZ,MAAMA,GACH,OAAO,EACP,SAAS,6CAA6C,EACtD,SAAS;AAAA,EACZ,IAAIA,GACD,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AACd,CAAC;;;AFjCM,IAAM,WAAW,YAAY,cAAc;AAC3C,IAAM,UAAU,YAAY,aAAa;;;AGThD;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAEA,IAAM,oBAAoB;AAAA,EACxB,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,IAAI;AACN;AAEA,IAAM,sBAAsB,EAAE,IAAI,KAAc;AAEhD,IAAM,iBAAiB;AAAA,EACrB,IAAI;AAAA,EACJ,SAAS,EAAE,IAAI,YAAY;AAC7B;AAEA,SAAS,mBAAoC;AAC3C,SAAO;AAAA,IACL,MAAM;AAAA,MACJ,aAAa,MAAM,QAAQ,QAAQ,iBAA0B;AAAA,MAC7D,eAAe,MAAM,QAAQ,QAAQ,mBAA4B;AAAA,IACnE;AAAA,IACA,eAAe;AAAA,MACb,MAAM,MAAM,QAAQ,QAAQ,cAAuB;AAAA,IACrD;AAAA,EACF;AACF;AAEO,IAAM,OAAY;AAAA,EACvB,aAAa,iBAAiB;AAAA,EAC9B,aAAa,MACX,QAAQ,QAAQ,EAAE,IAAI,KAAK,CAAU;AACzC;AAEO,IAAM,aAAa;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACtCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,SAAS,gBAAgB;AAclB,IAAM,gBAAkC;AAAA,EAC7C,IAAI,SAAS,kBAAkB;AAAA,IAC7B,WAAW;AAAA,IACX,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,UAAU;AAAA,MACV,SAAS;AAAA,IACX;AAAA,IACA,MAAM,EAAE,IAAI,WAAW;AAAA,EACzB,CAAC;AAAA,EACD,SAAS;AAAA,IACP,UAAU;AAAA,MACR,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA,MACN,cAAc;AAAA,MACd,cAAc;AAAA,MACd,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAKO,IAAM,aAA+B;AAAA,EAC1C,IAAI,SAAS,eAAe;AAAA,IAC1B,WAAW;AAAA,IACX,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,UAAU;AAAA,MACR,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA,MACN,cAAc;AAAA,MACd,cAAc;AAAA,MACd,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAKO,IAAM,YAA8B;AAAA,EACzC,IAAI,SAAS,eAAe;AAAA,IAC1B,WAAW;AAAA,IACX,MAAM,EAAE,MAAM,aAAa;AAAA,IAC3B,MAAM,EAAE,IAAI,aAAa;AAAA,EAC3B,CAAC;AAAA,EACD,SAAS;AAAA,IACP,UAAU;AAAA,MACR,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH,CAAC,kCAAkC,EAAE,OAAO,aAAa,CAAC;AAAA,IAC1D;AAAA,MACE;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,cAAc;AAAA,QACd,cAAc;AAAA,QACd,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;AAKO,IAAM,uBAAyC;AAAA,EACpD,IAAI,SAAS,iBAAiB;AAAA,IAC5B,WAAW;AAAA,IACX,MAAM,EAAE,MAAM,WAAW,WAAW,oBAAoB;AAAA,EAC1D,CAAC;AAAA,EACD,SAAS;AAAA,IACP,UAAU;AAAA,MACR,SAAS;AAAA,MACT,MAAM;AAAA,MACN,UAAU;AAAA,MACV,gBAAgB;AAAA,IAClB;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA,MACN,WAAW;AAAA,MACX,iBAAiB;AAAA,MACjB,cAAc;AAAA,MACd,cAAc;AAAA,MACd,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAKO,IAAM,mBAAqC;AAAA,EAChD,IAAI,SAAS,iBAAiB;AAAA,IAC5B,WAAW;AAAA,IACX,MAAM,EAAE,WAAW,EAAE;AAAA,EACvB,CAAC;AAAA,EACD,SAAS;AAAA,IACP,UAAU;AAAA,MACR,SAAS;AAAA,MACT,WAAW;AAAA,MACX,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,cAAc;AAAA,MACd,cAAc;AAAA,MACd,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAMO,IAAM,gBAAkC;AAAA,EAC7C,IAAI,SAAS,eAAe;AAAA,IAC1B,WAAW;AAAA,IACX,MAAM,EAAE,MAAM,QAAQ,OAAO,kBAAkB;AAAA,IAC/C,QAAQ,EAAE,MAAM,UAAU,IAAI,OAAO,aAAa,GAAG;AAAA,EACvD,CAAC;AAAA,EACD,SAAS;AAAA,IACP,UAAU;AAAA,MACR,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,QACN;AAAA,UACE,MAAM;AAAA,UACN,MAAM,EAAE,MAAM,cAAc,MAAM,cAAc;AAAA,QAClD;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,EAAE,MAAM,UAAU,MAAM,gBAAgB;AAAA,YACxC,EAAE,MAAM,UAAU,MAAM,4BAA4B;AAAA,UACtD;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,UAAU,CAAC,EAAE,MAAM,UAAU,MAAM,cAAc,CAAC;AAAA,QACpD;AAAA,MACF;AAAA,MACA,cAAc;AAAA,MACd,cAAc;AAAA,MACd,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAMO,IAAM,qBAAuC;AAAA,EAClD,IAAI,SAAS,mBAAmB;AAAA,IAC9B,WAAW;AAAA,IACX,MAAM,EAAE,SAAS,SAAS,aAAa,OAAO;AAAA,EAChD,CAAC;AAAA,EACD,UAAU;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,EACd;AAAA,EACA,SAAS;AAAA,IACP,UAAU;AAAA,MACR,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,cAAc;AAAA,MACd,cAAc;AAAA,MACd,QAAQ;AAAA,IACV;AAAA,EACF;AACF;","names":["z"]}