@amirhosseinnouri/send 1.0.0-2

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/index.cjs ADDED
@@ -0,0 +1,356 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ PROVIDERS: () => PROVIDERS,
24
+ createSender: () => createSender,
25
+ elementConfigSchema: () => elementConfigSchema,
26
+ mattermostConfigSchema: () => mattermostConfigSchema,
27
+ messageSchema: () => messageSchema,
28
+ providerConfigSchemas: () => providerConfigSchemas,
29
+ send: () => send,
30
+ sendInputSchema: () => sendInputSchema,
31
+ senderConfigSchema: () => senderConfigSchema,
32
+ slackConfigSchema: () => slackConfigSchema,
33
+ teamsConfigSchema: () => teamsConfigSchema,
34
+ telegramConfigSchema: () => telegramConfigSchema
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+
38
+ // src/providers/element.ts
39
+ var import_marked = require("marked");
40
+ var ElementSender = class {
41
+ name = "Element";
42
+ homeserverUrl;
43
+ accessToken;
44
+ roomId;
45
+ constructor(config) {
46
+ this.homeserverUrl = config.homeserverUrl;
47
+ this.accessToken = config.accessToken;
48
+ this.roomId = config.roomId;
49
+ }
50
+ async send(message) {
51
+ const lines = [];
52
+ if (message.title) {
53
+ lines.push(message.markdown ? `**${message.title}**` : message.title, "");
54
+ }
55
+ lines.push(message.body);
56
+ const body = lines.join("\n");
57
+ const formatted = message.markdown ? {
58
+ format: "org.matrix.custom.html",
59
+ formatted_body: await import_marked.marked.parse(body, { async: true })
60
+ } : {};
61
+ const txnId = `send-${Date.now()}`;
62
+ const encodedRoomId = encodeURIComponent(this.roomId);
63
+ const url = `${this.homeserverUrl}/_matrix/client/v3/rooms/${encodedRoomId}/send/m.room.message/${txnId}`;
64
+ let response;
65
+ try {
66
+ response = await fetch(url, {
67
+ method: "PUT",
68
+ headers: {
69
+ "Content-Type": "application/json",
70
+ Authorization: `Bearer ${this.accessToken}`
71
+ },
72
+ body: JSON.stringify({
73
+ msgtype: "m.text",
74
+ body,
75
+ ...formatted
76
+ })
77
+ });
78
+ } catch (error) {
79
+ const cause = error instanceof Error ? error.cause ?? error.message : error;
80
+ throw new Error(`Element fetch failed: ${JSON.stringify(cause)}`);
81
+ }
82
+ if (!response.ok) {
83
+ const responseBody = await response.text();
84
+ throw new Error(
85
+ `Element API returned status ${response.status}: ${responseBody}`
86
+ );
87
+ }
88
+ }
89
+ };
90
+
91
+ // src/providers/mattermost.ts
92
+ var MattermostSender = class {
93
+ name = "Mattermost";
94
+ webhookUrl;
95
+ constructor(config) {
96
+ this.webhookUrl = config.webhookUrl;
97
+ }
98
+ /** Mattermost always renders markdown; escape special chars for plain bodies. */
99
+ escapeMarkdown(text) {
100
+ return text.replace(/([\\`*_{}[\]()#+\-.!|>~])/g, "\\$1");
101
+ }
102
+ async send(message) {
103
+ const summary = message.title ?? message.body;
104
+ const body = message.markdown ? message.body : this.escapeMarkdown(message.body);
105
+ const payload = {
106
+ text: message.title ? `#### ${message.title}` : "",
107
+ attachments: [
108
+ {
109
+ fallback: summary,
110
+ color: "#2eb886",
111
+ text: body
112
+ }
113
+ ]
114
+ };
115
+ const response = await fetch(this.webhookUrl, {
116
+ method: "POST",
117
+ headers: { "Content-Type": "application/json" },
118
+ body: JSON.stringify(payload)
119
+ });
120
+ if (!response.ok) {
121
+ const body2 = await response.text();
122
+ throw new Error(
123
+ `Mattermost webhook returned status ${response.status}: ${body2}`
124
+ );
125
+ }
126
+ }
127
+ };
128
+
129
+ // src/providers/slack.ts
130
+ var SlackSender = class {
131
+ name = "Slack";
132
+ webhookUrl;
133
+ constructor(config) {
134
+ this.webhookUrl = config.webhookUrl;
135
+ }
136
+ async send(message) {
137
+ const summary = message.title ?? message.body;
138
+ const blocks = [];
139
+ if (message.title) {
140
+ blocks.push({
141
+ type: "header",
142
+ text: { type: "plain_text", text: message.title }
143
+ });
144
+ }
145
+ blocks.push({ type: "divider" });
146
+ blocks.push({
147
+ type: "section",
148
+ text: {
149
+ type: message.markdown ? "mrkdwn" : "plain_text",
150
+ text: message.body
151
+ }
152
+ });
153
+ const payload = { text: summary, blocks };
154
+ const response = await fetch(this.webhookUrl, {
155
+ method: "POST",
156
+ headers: { "Content-Type": "application/json" },
157
+ body: JSON.stringify(payload)
158
+ });
159
+ if (!response.ok) {
160
+ const body = await response.text();
161
+ throw new Error(
162
+ `Slack webhook returned status ${response.status}: ${body}`
163
+ );
164
+ }
165
+ }
166
+ };
167
+
168
+ // src/providers/teams.ts
169
+ var TeamsSender = class {
170
+ name = "Microsoft Teams";
171
+ webhookUrl;
172
+ constructor(config) {
173
+ this.webhookUrl = config.webhookUrl;
174
+ }
175
+ async send(message) {
176
+ const summary = message.title ?? message.body;
177
+ const messageCard = {
178
+ "@type": "MessageCard",
179
+ "@context": "https://schema.org/extensions",
180
+ themeColor: "0078D7",
181
+ summary,
182
+ sections: [
183
+ {
184
+ activityTitle: message.title,
185
+ text: message.body,
186
+ markdown: message.markdown ?? false
187
+ }
188
+ ]
189
+ };
190
+ const response = await fetch(this.webhookUrl, {
191
+ method: "POST",
192
+ headers: { "Content-Type": "application/json" },
193
+ body: JSON.stringify(messageCard)
194
+ });
195
+ if (!response.ok) {
196
+ throw new Error(
197
+ `Teams webhook returned status ${response.status}: ${response.statusText}`
198
+ );
199
+ }
200
+ }
201
+ };
202
+
203
+ // src/providers/telegram.ts
204
+ var TelegramSender = class {
205
+ name = "Telegram";
206
+ botToken;
207
+ chatId;
208
+ constructor(config) {
209
+ this.botToken = config.botToken;
210
+ this.chatId = config.chatId;
211
+ }
212
+ escapeMarkdown(text) {
213
+ return text.replace(/([*_`[])/g, "\\$1");
214
+ }
215
+ async send(message) {
216
+ const lines = [];
217
+ if (message.markdown) {
218
+ if (message.title) {
219
+ lines.push(`*${this.escapeMarkdown(message.title)}*`, "");
220
+ }
221
+ lines.push(message.body);
222
+ } else {
223
+ if (message.title) lines.push(message.title, "");
224
+ lines.push(message.body);
225
+ }
226
+ const text = lines.join("\n");
227
+ const url = `https://api.telegram.org/bot${this.botToken}/sendMessage`;
228
+ const response = await fetch(url, {
229
+ method: "POST",
230
+ headers: { "Content-Type": "application/json" },
231
+ body: JSON.stringify({
232
+ chat_id: this.chatId,
233
+ text,
234
+ ...message.markdown ? { parse_mode: "Markdown" } : {}
235
+ })
236
+ });
237
+ if (!response.ok) {
238
+ const body = await response.text();
239
+ throw new Error(
240
+ `Telegram API returned status ${response.status}: ${body}`
241
+ );
242
+ }
243
+ }
244
+ };
245
+
246
+ // src/providers/index.ts
247
+ var PROVIDERS = [
248
+ "slack",
249
+ "teams",
250
+ "mattermost",
251
+ "telegram",
252
+ "element"
253
+ ];
254
+ function createSender(config) {
255
+ switch (config.provider) {
256
+ case "slack":
257
+ return new SlackSender(config);
258
+ case "teams":
259
+ return new TeamsSender(config);
260
+ case "mattermost":
261
+ return new MattermostSender(config);
262
+ case "telegram":
263
+ return new TelegramSender(config);
264
+ case "element":
265
+ return new ElementSender(config);
266
+ }
267
+ }
268
+
269
+ // src/schema/element.ts
270
+ var import_zod = require("zod");
271
+ var elementConfigSchema = import_zod.z.object({
272
+ provider: import_zod.z.literal("element"),
273
+ homeserverUrl: import_zod.z.url(),
274
+ accessToken: import_zod.z.string(),
275
+ roomId: import_zod.z.string()
276
+ });
277
+
278
+ // src/schema/mattermost.ts
279
+ var import_zod2 = require("zod");
280
+ var mattermostConfigSchema = import_zod2.z.object({
281
+ provider: import_zod2.z.literal("mattermost"),
282
+ webhookUrl: import_zod2.z.url()
283
+ });
284
+
285
+ // src/schema/sender.ts
286
+ var import_zod6 = require("zod");
287
+
288
+ // src/schema/slack.ts
289
+ var import_zod3 = require("zod");
290
+ var slackConfigSchema = import_zod3.z.object({
291
+ provider: import_zod3.z.literal("slack"),
292
+ webhookUrl: import_zod3.z.url()
293
+ });
294
+
295
+ // src/schema/teams.ts
296
+ var import_zod4 = require("zod");
297
+ var teamsConfigSchema = import_zod4.z.object({
298
+ provider: import_zod4.z.literal("teams"),
299
+ webhookUrl: import_zod4.z.url()
300
+ });
301
+
302
+ // src/schema/telegram.ts
303
+ var import_zod5 = require("zod");
304
+ var telegramConfigSchema = import_zod5.z.object({
305
+ provider: import_zod5.z.literal("telegram"),
306
+ botToken: import_zod5.z.string(),
307
+ chatId: import_zod5.z.string()
308
+ });
309
+
310
+ // src/schema/sender.ts
311
+ var messageSchema = import_zod6.z.object({
312
+ title: import_zod6.z.string().optional(),
313
+ body: import_zod6.z.string(),
314
+ /** Render the body as markdown in the provider's native format. */
315
+ markdown: import_zod6.z.boolean().optional()
316
+ });
317
+ var senderConfigSchema = import_zod6.z.discriminatedUnion("provider", [
318
+ slackConfigSchema,
319
+ teamsConfigSchema,
320
+ mattermostConfigSchema,
321
+ telegramConfigSchema,
322
+ elementConfigSchema
323
+ ]);
324
+ var sendInputSchema = import_zod6.z.intersection(
325
+ senderConfigSchema,
326
+ messageSchema
327
+ );
328
+ var providerConfigSchemas = {
329
+ slack: slackConfigSchema,
330
+ teams: teamsConfigSchema,
331
+ mattermost: mattermostConfigSchema,
332
+ telegram: telegramConfigSchema,
333
+ element: elementConfigSchema
334
+ };
335
+
336
+ // src/index.ts
337
+ async function send(input) {
338
+ const { title, body, markdown, ...config } = input;
339
+ const message = { title, body, markdown };
340
+ await createSender(config).send(message);
341
+ }
342
+ // Annotate the CommonJS export names for ESM import in node:
343
+ 0 && (module.exports = {
344
+ PROVIDERS,
345
+ createSender,
346
+ elementConfigSchema,
347
+ mattermostConfigSchema,
348
+ messageSchema,
349
+ providerConfigSchemas,
350
+ send,
351
+ sendInputSchema,
352
+ senderConfigSchema,
353
+ slackConfigSchema,
354
+ teamsConfigSchema,
355
+ telegramConfigSchema
356
+ });
@@ -0,0 +1,149 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const messageSchema: z.ZodObject<{
4
+ title: z.ZodOptional<z.ZodString>;
5
+ body: z.ZodString;
6
+ markdown: z.ZodOptional<z.ZodBoolean>;
7
+ }, z.core.$strip>;
8
+ declare const senderConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
9
+ provider: z.ZodLiteral<"slack">;
10
+ webhookUrl: z.ZodURL;
11
+ }, z.core.$strip>, z.ZodObject<{
12
+ provider: z.ZodLiteral<"teams">;
13
+ webhookUrl: z.ZodURL;
14
+ }, z.core.$strip>, z.ZodObject<{
15
+ provider: z.ZodLiteral<"mattermost">;
16
+ webhookUrl: z.ZodURL;
17
+ }, z.core.$strip>, z.ZodObject<{
18
+ provider: z.ZodLiteral<"telegram">;
19
+ botToken: z.ZodString;
20
+ chatId: z.ZodString;
21
+ }, z.core.$strip>, z.ZodObject<{
22
+ provider: z.ZodLiteral<"element">;
23
+ homeserverUrl: z.ZodURL;
24
+ accessToken: z.ZodString;
25
+ roomId: z.ZodString;
26
+ }, z.core.$strip>], "provider">;
27
+ /** Schema for the flat one-shot `send()` input (config merged with message). */
28
+ declare const sendInputSchema: z.ZodIntersection<z.ZodDiscriminatedUnion<[z.ZodObject<{
29
+ provider: z.ZodLiteral<"slack">;
30
+ webhookUrl: z.ZodURL;
31
+ }, z.core.$strip>, z.ZodObject<{
32
+ provider: z.ZodLiteral<"teams">;
33
+ webhookUrl: z.ZodURL;
34
+ }, z.core.$strip>, z.ZodObject<{
35
+ provider: z.ZodLiteral<"mattermost">;
36
+ webhookUrl: z.ZodURL;
37
+ }, z.core.$strip>, z.ZodObject<{
38
+ provider: z.ZodLiteral<"telegram">;
39
+ botToken: z.ZodString;
40
+ chatId: z.ZodString;
41
+ }, z.core.$strip>, z.ZodObject<{
42
+ provider: z.ZodLiteral<"element">;
43
+ homeserverUrl: z.ZodURL;
44
+ accessToken: z.ZodString;
45
+ roomId: z.ZodString;
46
+ }, z.core.$strip>], "provider">, z.ZodObject<{
47
+ title: z.ZodOptional<z.ZodString>;
48
+ body: z.ZodString;
49
+ markdown: z.ZodOptional<z.ZodBoolean>;
50
+ }, z.core.$strip>>;
51
+ /** Per-provider config schemas, keyed by provider, for consumers to reuse. */
52
+ declare const providerConfigSchemas: {
53
+ readonly slack: z.ZodObject<{
54
+ provider: z.ZodLiteral<"slack">;
55
+ webhookUrl: z.ZodURL;
56
+ }, z.core.$strip>;
57
+ readonly teams: z.ZodObject<{
58
+ provider: z.ZodLiteral<"teams">;
59
+ webhookUrl: z.ZodURL;
60
+ }, z.core.$strip>;
61
+ readonly mattermost: z.ZodObject<{
62
+ provider: z.ZodLiteral<"mattermost">;
63
+ webhookUrl: z.ZodURL;
64
+ }, z.core.$strip>;
65
+ readonly telegram: z.ZodObject<{
66
+ provider: z.ZodLiteral<"telegram">;
67
+ botToken: z.ZodString;
68
+ chatId: z.ZodString;
69
+ }, z.core.$strip>;
70
+ readonly element: z.ZodObject<{
71
+ provider: z.ZodLiteral<"element">;
72
+ homeserverUrl: z.ZodURL;
73
+ accessToken: z.ZodString;
74
+ roomId: z.ZodString;
75
+ }, z.core.$strip>;
76
+ };
77
+
78
+ /**
79
+ * A provider-agnostic structured message. Each provider renders the body into
80
+ * its own native format (Slack blocks, Teams card, Telegram markdown, ...),
81
+ * optionally as markdown when {@link Message.markdown} is set.
82
+ */
83
+ type Message = z.infer<typeof messageSchema>;
84
+ /** Discriminated union of every supported provider configuration. */
85
+ type SenderConfig = z.infer<typeof senderConfigSchema>;
86
+ /** Every supported provider key, derived from the config schema discriminant. */
87
+ type ChatProvider = SenderConfig["provider"];
88
+ /** A configured, reusable sender bound to a single provider. */
89
+ interface Sender {
90
+ /** Human-readable provider name, e.g. "Slack". */
91
+ name: string;
92
+ send(message: Message): Promise<void>;
93
+ }
94
+ /** Flat one-shot input: provider config merged with the message. */
95
+ type SendInput = SenderConfig & Message;
96
+
97
+ /** Every supported provider key. */
98
+ declare const PROVIDERS: readonly ["slack", "teams", "mattermost", "telegram", "element"];
99
+ /** Build a reusable {@link Sender} bound to a single provider configuration. */
100
+ declare function createSender(config: SenderConfig): Sender;
101
+
102
+ declare const elementConfigSchema: z.ZodObject<{
103
+ provider: z.ZodLiteral<"element">;
104
+ homeserverUrl: z.ZodURL;
105
+ accessToken: z.ZodString;
106
+ roomId: z.ZodString;
107
+ }, z.core.$strip>;
108
+
109
+ type ElementConfig = z.infer<typeof elementConfigSchema>;
110
+
111
+ declare const mattermostConfigSchema: z.ZodObject<{
112
+ provider: z.ZodLiteral<"mattermost">;
113
+ webhookUrl: z.ZodURL;
114
+ }, z.core.$strip>;
115
+
116
+ type MattermostConfig = z.infer<typeof mattermostConfigSchema>;
117
+
118
+ declare const slackConfigSchema: z.ZodObject<{
119
+ provider: z.ZodLiteral<"slack">;
120
+ webhookUrl: z.ZodURL;
121
+ }, z.core.$strip>;
122
+
123
+ type SlackConfig = z.infer<typeof slackConfigSchema>;
124
+
125
+ declare const teamsConfigSchema: z.ZodObject<{
126
+ provider: z.ZodLiteral<"teams">;
127
+ webhookUrl: z.ZodURL;
128
+ }, z.core.$strip>;
129
+
130
+ type TeamsConfig = z.infer<typeof teamsConfigSchema>;
131
+
132
+ declare const telegramConfigSchema: z.ZodObject<{
133
+ provider: z.ZodLiteral<"telegram">;
134
+ botToken: z.ZodString;
135
+ chatId: z.ZodString;
136
+ }, z.core.$strip>;
137
+
138
+ type TelegramConfig = z.infer<typeof telegramConfigSchema>;
139
+
140
+ /**
141
+ * Send a single message in one call. Convenience wrapper that splits the flat
142
+ * input into a provider config and a message, then dispatches.
143
+ *
144
+ * @example
145
+ * await send({ provider: "slack", webhookUrl, title: "Hi", body: "world" });
146
+ */
147
+ declare function send(input: SendInput): Promise<void>;
148
+
149
+ export { type ChatProvider, type ElementConfig, type MattermostConfig, type Message, PROVIDERS, type SendInput, type Sender, type SenderConfig, type SlackConfig, type TeamsConfig, type TelegramConfig, createSender, elementConfigSchema, mattermostConfigSchema, messageSchema, providerConfigSchemas, send, sendInputSchema, senderConfigSchema, slackConfigSchema, teamsConfigSchema, telegramConfigSchema };
@@ -0,0 +1,149 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const messageSchema: z.ZodObject<{
4
+ title: z.ZodOptional<z.ZodString>;
5
+ body: z.ZodString;
6
+ markdown: z.ZodOptional<z.ZodBoolean>;
7
+ }, z.core.$strip>;
8
+ declare const senderConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
9
+ provider: z.ZodLiteral<"slack">;
10
+ webhookUrl: z.ZodURL;
11
+ }, z.core.$strip>, z.ZodObject<{
12
+ provider: z.ZodLiteral<"teams">;
13
+ webhookUrl: z.ZodURL;
14
+ }, z.core.$strip>, z.ZodObject<{
15
+ provider: z.ZodLiteral<"mattermost">;
16
+ webhookUrl: z.ZodURL;
17
+ }, z.core.$strip>, z.ZodObject<{
18
+ provider: z.ZodLiteral<"telegram">;
19
+ botToken: z.ZodString;
20
+ chatId: z.ZodString;
21
+ }, z.core.$strip>, z.ZodObject<{
22
+ provider: z.ZodLiteral<"element">;
23
+ homeserverUrl: z.ZodURL;
24
+ accessToken: z.ZodString;
25
+ roomId: z.ZodString;
26
+ }, z.core.$strip>], "provider">;
27
+ /** Schema for the flat one-shot `send()` input (config merged with message). */
28
+ declare const sendInputSchema: z.ZodIntersection<z.ZodDiscriminatedUnion<[z.ZodObject<{
29
+ provider: z.ZodLiteral<"slack">;
30
+ webhookUrl: z.ZodURL;
31
+ }, z.core.$strip>, z.ZodObject<{
32
+ provider: z.ZodLiteral<"teams">;
33
+ webhookUrl: z.ZodURL;
34
+ }, z.core.$strip>, z.ZodObject<{
35
+ provider: z.ZodLiteral<"mattermost">;
36
+ webhookUrl: z.ZodURL;
37
+ }, z.core.$strip>, z.ZodObject<{
38
+ provider: z.ZodLiteral<"telegram">;
39
+ botToken: z.ZodString;
40
+ chatId: z.ZodString;
41
+ }, z.core.$strip>, z.ZodObject<{
42
+ provider: z.ZodLiteral<"element">;
43
+ homeserverUrl: z.ZodURL;
44
+ accessToken: z.ZodString;
45
+ roomId: z.ZodString;
46
+ }, z.core.$strip>], "provider">, z.ZodObject<{
47
+ title: z.ZodOptional<z.ZodString>;
48
+ body: z.ZodString;
49
+ markdown: z.ZodOptional<z.ZodBoolean>;
50
+ }, z.core.$strip>>;
51
+ /** Per-provider config schemas, keyed by provider, for consumers to reuse. */
52
+ declare const providerConfigSchemas: {
53
+ readonly slack: z.ZodObject<{
54
+ provider: z.ZodLiteral<"slack">;
55
+ webhookUrl: z.ZodURL;
56
+ }, z.core.$strip>;
57
+ readonly teams: z.ZodObject<{
58
+ provider: z.ZodLiteral<"teams">;
59
+ webhookUrl: z.ZodURL;
60
+ }, z.core.$strip>;
61
+ readonly mattermost: z.ZodObject<{
62
+ provider: z.ZodLiteral<"mattermost">;
63
+ webhookUrl: z.ZodURL;
64
+ }, z.core.$strip>;
65
+ readonly telegram: z.ZodObject<{
66
+ provider: z.ZodLiteral<"telegram">;
67
+ botToken: z.ZodString;
68
+ chatId: z.ZodString;
69
+ }, z.core.$strip>;
70
+ readonly element: z.ZodObject<{
71
+ provider: z.ZodLiteral<"element">;
72
+ homeserverUrl: z.ZodURL;
73
+ accessToken: z.ZodString;
74
+ roomId: z.ZodString;
75
+ }, z.core.$strip>;
76
+ };
77
+
78
+ /**
79
+ * A provider-agnostic structured message. Each provider renders the body into
80
+ * its own native format (Slack blocks, Teams card, Telegram markdown, ...),
81
+ * optionally as markdown when {@link Message.markdown} is set.
82
+ */
83
+ type Message = z.infer<typeof messageSchema>;
84
+ /** Discriminated union of every supported provider configuration. */
85
+ type SenderConfig = z.infer<typeof senderConfigSchema>;
86
+ /** Every supported provider key, derived from the config schema discriminant. */
87
+ type ChatProvider = SenderConfig["provider"];
88
+ /** A configured, reusable sender bound to a single provider. */
89
+ interface Sender {
90
+ /** Human-readable provider name, e.g. "Slack". */
91
+ name: string;
92
+ send(message: Message): Promise<void>;
93
+ }
94
+ /** Flat one-shot input: provider config merged with the message. */
95
+ type SendInput = SenderConfig & Message;
96
+
97
+ /** Every supported provider key. */
98
+ declare const PROVIDERS: readonly ["slack", "teams", "mattermost", "telegram", "element"];
99
+ /** Build a reusable {@link Sender} bound to a single provider configuration. */
100
+ declare function createSender(config: SenderConfig): Sender;
101
+
102
+ declare const elementConfigSchema: z.ZodObject<{
103
+ provider: z.ZodLiteral<"element">;
104
+ homeserverUrl: z.ZodURL;
105
+ accessToken: z.ZodString;
106
+ roomId: z.ZodString;
107
+ }, z.core.$strip>;
108
+
109
+ type ElementConfig = z.infer<typeof elementConfigSchema>;
110
+
111
+ declare const mattermostConfigSchema: z.ZodObject<{
112
+ provider: z.ZodLiteral<"mattermost">;
113
+ webhookUrl: z.ZodURL;
114
+ }, z.core.$strip>;
115
+
116
+ type MattermostConfig = z.infer<typeof mattermostConfigSchema>;
117
+
118
+ declare const slackConfigSchema: z.ZodObject<{
119
+ provider: z.ZodLiteral<"slack">;
120
+ webhookUrl: z.ZodURL;
121
+ }, z.core.$strip>;
122
+
123
+ type SlackConfig = z.infer<typeof slackConfigSchema>;
124
+
125
+ declare const teamsConfigSchema: z.ZodObject<{
126
+ provider: z.ZodLiteral<"teams">;
127
+ webhookUrl: z.ZodURL;
128
+ }, z.core.$strip>;
129
+
130
+ type TeamsConfig = z.infer<typeof teamsConfigSchema>;
131
+
132
+ declare const telegramConfigSchema: z.ZodObject<{
133
+ provider: z.ZodLiteral<"telegram">;
134
+ botToken: z.ZodString;
135
+ chatId: z.ZodString;
136
+ }, z.core.$strip>;
137
+
138
+ type TelegramConfig = z.infer<typeof telegramConfigSchema>;
139
+
140
+ /**
141
+ * Send a single message in one call. Convenience wrapper that splits the flat
142
+ * input into a provider config and a message, then dispatches.
143
+ *
144
+ * @example
145
+ * await send({ provider: "slack", webhookUrl, title: "Hi", body: "world" });
146
+ */
147
+ declare function send(input: SendInput): Promise<void>;
148
+
149
+ export { type ChatProvider, type ElementConfig, type MattermostConfig, type Message, PROVIDERS, type SendInput, type Sender, type SenderConfig, type SlackConfig, type TeamsConfig, type TelegramConfig, createSender, elementConfigSchema, mattermostConfigSchema, messageSchema, providerConfigSchemas, send, sendInputSchema, senderConfigSchema, slackConfigSchema, teamsConfigSchema, telegramConfigSchema };