statocysts 0.7.0 → 0.9.0

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/browser.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as http, c as SenderUrl, d as DefineProviderOptions, f as ServiceProvider, h as defineTransport, i as HttpPayload, l as buildSenderRegistry, m as Transport, n as telegram, o as Sender, p as defineProvider, r as slack, s as SenderRegistry, t as json, u as DefineProviderContext } from "./index-DIqKYuP3.js";
1
+ import { _ as defineTransport, a as discord, c as Sender, d as buildSenderRegistry, f as DefineProviderContext, g as Transport, h as defineProvider, i as slack, l as SenderRegistry, m as ServiceProvider, n as bark, o as HttpPayload, p as DefineProviderOptions, r as telegram, s as http, t as json, u as SenderUrl } from "./index-DcoOHy7e.js";
2
2
 
3
3
  //#region src/browser.d.ts
4
4
 
@@ -6,4 +6,4 @@ declare const senderRegistry: SenderRegistry;
6
6
  declare function createSender(urls: SenderUrl[]): Sender;
7
7
  declare function send(url: string | URL, title: string, body?: string): Promise<void>;
8
8
  //#endregion
9
- export { DefineProviderContext, DefineProviderOptions, HttpPayload, Sender, SenderRegistry, SenderUrl, ServiceProvider, Transport, buildSenderRegistry, createSender, defineProvider, defineTransport, http, json, send, senderRegistry, slack, telegram };
9
+ export { DefineProviderContext, DefineProviderOptions, HttpPayload, Sender, SenderRegistry, SenderUrl, ServiceProvider, Transport, bark, buildSenderRegistry, createSender, defineProvider, defineTransport, discord, http, json, send, senderRegistry, slack, telegram };
package/dist/browser.js CHANGED
@@ -1,10 +1,12 @@
1
- import { a as http, c as assert, i as slack, n as json, o as defineTransport, r as telegram, s as defineProvider, t as buildSenderRegistry } from "./shared-DBiCYY_-.js";
1
+ import { a as slack, c as defineTransport, i as telegram, l as defineProvider, n as bark, o as discord, r as buildSenderRegistry, s as http, t as json, u as assert } from "./json-DAUitIVf.js";
2
2
 
3
3
  //#region src/browser.ts
4
4
  const senderRegistry = buildSenderRegistry([
5
+ bark,
5
6
  json,
6
7
  slack,
7
- telegram
8
+ telegram,
9
+ discord
8
10
  ]);
9
11
  function createSender(urls) {
10
12
  return senderRegistry(urls);
@@ -21,4 +23,4 @@ async function send(url, title, body) {
21
23
  }
22
24
 
23
25
  //#endregion
24
- export { buildSenderRegistry, createSender, defineProvider, defineTransport, http, json, send, senderRegistry, slack, telegram };
26
+ export { bark, buildSenderRegistry, createSender, defineProvider, defineTransport, discord, http, json, send, senderRegistry, slack, telegram };
@@ -66,6 +66,12 @@ interface HttpPayload {
66
66
  */
67
67
  declare const http: Transport<HttpPayload>;
68
68
  //#endregion
69
+ //#region src/services/chat/discord/index.d.ts
70
+ interface DiscordOptions {
71
+ fetchOptions?: FetchOptions;
72
+ }
73
+ declare const discord: ServiceProvider<"discord:", HttpPayload, DiscordOptions>;
74
+ //#endregion
69
75
  //#region src/services/chat/slack/index.d.ts
70
76
  interface SlackOptions {
71
77
  /**
@@ -102,7 +108,13 @@ interface TelegramOptions {
102
108
  }
103
109
  declare const telegram: ServiceProvider<"telegram:", HttpPayload, TelegramOptions>;
104
110
  //#endregion
111
+ //#region src/services/push/bark/index.d.ts
112
+ interface BarkOptions {
113
+ fetchOptions?: FetchOptions;
114
+ }
115
+ declare const bark: ServiceProvider<"bark:", HttpPayload, BarkOptions>;
116
+ //#endregion
105
117
  //#region src/services/specialized/json/index.d.ts
106
118
  declare const json: ServiceProvider<"json:", HttpPayload, FetchOptions<ofetch0.ResponseType, any>>;
107
119
  //#endregion
108
- export { http as a, SenderUrl as c, DefineProviderOptions as d, ServiceProvider as f, defineTransport as h, HttpPayload as i, buildSenderRegistry as l, Transport as m, telegram as n, Sender as o, defineProvider as p, slack as r, SenderRegistry as s, json as t, DefineProviderContext as u };
120
+ export { defineTransport as _, discord as a, Sender as c, buildSenderRegistry as d, DefineProviderContext as f, Transport as g, defineProvider as h, slack as i, SenderRegistry as l, ServiceProvider as m, bark as n, HttpPayload as o, DefineProviderOptions as p, telegram as r, http as s, json as t, SenderUrl as u };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,31 @@
1
- import { a as http, c as SenderUrl, d as DefineProviderOptions, f as ServiceProvider, h as defineTransport, i as HttpPayload, l as buildSenderRegistry, m as Transport, n as telegram, o as Sender, p as defineProvider, r as slack, s as SenderRegistry, t as json, u as DefineProviderContext } from "./index-DIqKYuP3.js";
1
+ import { _ as defineTransport, a as discord, c as Sender, d as buildSenderRegistry, f as DefineProviderContext, g as Transport, h as defineProvider, i as slack, l as SenderRegistry, m as ServiceProvider, n as bark, o as HttpPayload, p as DefineProviderOptions, r as telegram, s as http, t as json, u as SenderUrl } from "./index-DcoOHy7e.js";
2
+ import { Message, MessageHeaders, SMTPConnectionOptions } from "emailjs";
2
3
 
4
+ //#region src/core/transports/smtp.d.ts
5
+ /**
6
+ * SMTP payload for SMTP transport
7
+ */
8
+ interface SmtpPayload {
9
+ /**
10
+ * SMTP client configuration
11
+ */
12
+ client: Partial<SMTPConnectionOptions>;
13
+ /**
14
+ * Email message to send
15
+ */
16
+ message: Message | MessageHeaders;
17
+ }
18
+ //#endregion
19
+ //#region src/services/specialized/email/index.d.ts
20
+ interface EmailOptions {
21
+ defaultFrom?: string;
22
+ smtpConfig?: Partial<SMTPConnectionOptions>;
23
+ }
24
+ declare const email: ServiceProvider<"email:", SmtpPayload, EmailOptions>;
25
+ //#endregion
3
26
  //#region src/index.d.ts
4
-
5
27
  declare const senderRegistry: SenderRegistry;
6
28
  declare function createSender(urls: SenderUrl[]): Sender;
7
29
  declare function send(url: string | URL, title: string, body?: string): Promise<void>;
8
30
  //#endregion
9
- export { DefineProviderContext, DefineProviderOptions, HttpPayload, Sender, SenderRegistry, SenderUrl, ServiceProvider, Transport, buildSenderRegistry, createSender, defineProvider, defineTransport, http, json, send, senderRegistry, slack, telegram };
31
+ export { DefineProviderContext, DefineProviderOptions, HttpPayload, Sender, SenderRegistry, SenderUrl, ServiceProvider, Transport, bark, buildSenderRegistry, createSender, defineProvider, defineTransport, discord, email, http, json, send, senderRegistry, slack, telegram };
package/dist/index.js CHANGED
@@ -1,10 +1,87 @@
1
- import { a as http, c as assert, i as slack, n as json, o as defineTransport, r as telegram, s as defineProvider, t as buildSenderRegistry } from "./shared-DBiCYY_-.js";
1
+ import { a as slack, c as defineTransport, i as telegram, l as defineProvider, n as bark, o as discord, r as buildSenderRegistry, s as http, t as json, u as assert } from "./json-DAUitIVf.js";
2
+ import z from "zod";
3
+ import { SMTPClient } from "emailjs";
2
4
 
5
+ //#region src/core/transports/smtp.ts
6
+ /**
7
+ * SMTP transport implementation
8
+ * Handles sending emails over SMTP protocol using emailjs
9
+ */
10
+ const smtp = defineTransport({ async send(payload) {
11
+ await new SMTPClient(payload.client).sendAsync(payload.message);
12
+ } });
13
+
14
+ //#endregion
15
+ //#region src/services/specialized/email/index.ts
16
+ const queryParamSchema = z.object({
17
+ from: z.string().email().optional(),
18
+ subject: z.string().optional(),
19
+ ssl: z.string().transform((val) => val === "true").optional(),
20
+ tls: z.string().transform((val) => val !== "false").optional()
21
+ });
22
+ const email = defineProvider("email:", {
23
+ transport: smtp,
24
+ defaultOptions: {},
25
+ async prepare(ctx, options) {
26
+ const { url, message } = ctx;
27
+ const to = url.searchParams.getAll("to");
28
+ const cc = url.searchParams.getAll("cc");
29
+ const bcc = url.searchParams.getAll("bcc");
30
+ const from = url.searchParams.get("from");
31
+ const subject = url.searchParams.get("subject");
32
+ const sslParam = url.searchParams.get("ssl");
33
+ const tlsParam = url.searchParams.get("tls");
34
+ const queryResult = queryParamSchema.safeParse({
35
+ from: from || void 0,
36
+ subject: subject || void 0,
37
+ ssl: sslParam || void 0,
38
+ tls: tlsParam || void 0
39
+ });
40
+ if (!queryResult.success) throw new Error(`Invalid email query parameters: ${queryResult.error.message}`);
41
+ const query = queryResult.data;
42
+ const host = url.hostname;
43
+ assert(host, "SMTP host is required");
44
+ const port = url.port ? Number.parseInt(url.port, 10) : 587;
45
+ const user = decodeURIComponent(url.username || "");
46
+ const password = decodeURIComponent(url.password || "");
47
+ const fromAddress = query.from || options.defaultFrom || user;
48
+ assert(fromAddress, "Sender email address (from) is required");
49
+ assert(to.length > 0, "At least one recipient email address (to) is required");
50
+ const emailSubject = query.subject || message.title;
51
+ const text = message.body ? `${message.title}\n\n${message.body}` : message.title;
52
+ return {
53
+ client: {
54
+ host,
55
+ port,
56
+ ...user && password ? {
57
+ user,
58
+ password
59
+ } : {},
60
+ ssl: query.ssl ?? false,
61
+ tls: query.tls ?? port === 587,
62
+ ...options.smtpConfig
63
+ },
64
+ message: {
65
+ from: fromAddress,
66
+ to: to.join(", "),
67
+ cc: cc.length > 0 ? cc.join(", ") : void 0,
68
+ bcc: bcc.length > 0 ? bcc.join(", ") : void 0,
69
+ subject: emailSubject,
70
+ text
71
+ }
72
+ };
73
+ }
74
+ });
75
+
76
+ //#endregion
3
77
  //#region src/index.ts
4
78
  const senderRegistry = buildSenderRegistry([
79
+ bark,
80
+ email,
5
81
  json,
6
82
  slack,
7
- telegram
83
+ telegram,
84
+ discord
8
85
  ]);
9
86
  function createSender(urls) {
10
87
  return senderRegistry(urls);
@@ -21,4 +98,4 @@ async function send(url, title, body) {
21
98
  }
22
99
 
23
100
  //#endregion
24
- export { buildSenderRegistry, createSender, defineProvider, defineTransport, http, json, send, senderRegistry, slack, telegram };
101
+ export { bark, buildSenderRegistry, createSender, defineProvider, defineTransport, discord, email, http, json, send, senderRegistry, slack, telegram };
@@ -22,6 +22,11 @@ function escapeMarkdown(text) {
22
22
  function getValidateQuery(url, parser) {
23
23
  return parser(getQuery(url.toString()));
24
24
  }
25
+ function withoutPathname(input) {
26
+ const _url = new URL(input);
27
+ _url.pathname = "";
28
+ return _url.toString();
29
+ }
25
30
 
26
31
  //#endregion
27
32
  //#region src/core/provider.ts
@@ -67,6 +72,42 @@ const http = defineTransport({ async send(payload) {
67
72
  await ofetch(payload.request, payload.fetchOptions);
68
73
  } });
69
74
 
75
+ //#endregion
76
+ //#region src/services/chat/discord/index.ts
77
+ const querySchema$1 = z.object({
78
+ avatar_url: z.string().optional(),
79
+ username: z.string().optional(),
80
+ wait: z.string().transform((val) => {
81
+ if (val === "false" || val === "0" || val === "") return false;
82
+ return true;
83
+ }).optional()
84
+ });
85
+ const discord = defineProvider("discord:", {
86
+ transport: http,
87
+ defaultOptions: {},
88
+ async prepare(ctx, options) {
89
+ const { url } = ctx;
90
+ assert(url.hostname === "webhook", "Invalid discord URL");
91
+ assert(url.username, "Webhook ID is required");
92
+ assert(url.password, "Webhook token is required");
93
+ const queryResult = getValidateQuery(url, querySchema$1.safeParse);
94
+ if (!queryResult.success) throw new Error("Invalid discord query");
95
+ const { wait, ...query } = queryResult.data;
96
+ const headers = new Headers([["Content-Type", "application/json"]]);
97
+ const body = defu({ content: ctx.message.body ? `## ${ctx.message.title}\n\n${ctx.message.body}` : ctx.message.title }, query);
98
+ const requestUrl = new URL(`/api/webhooks/${url.username}/${url.password}`, "https://discord.com");
99
+ if (wait) requestUrl.searchParams.set("wait", "true");
100
+ return {
101
+ request: new Request(requestUrl, {
102
+ method: "POST",
103
+ headers,
104
+ body: JSON.stringify(body)
105
+ }),
106
+ fetchOptions: options.fetchOptions
107
+ };
108
+ }
109
+ });
110
+
70
111
  //#endregion
71
112
  //#region src/services/chat/slack/index.ts
72
113
  const slack = defineProvider("slack:", {
@@ -179,6 +220,89 @@ const telegram = defineProvider("telegram:", {
179
220
  }
180
221
  });
181
222
 
223
+ //#endregion
224
+ //#region src/core/sender.ts
225
+ function buildSenderRegistry(providers) {
226
+ const providersRegistry = /* @__PURE__ */ new Map();
227
+ providers.forEach((provider) => {
228
+ providersRegistry.set(provider.protocol, provider);
229
+ });
230
+ function resolveProvider(url) {
231
+ const _url = typeof url === "string" ? new URL(url) : url;
232
+ return providersRegistry.get(_url.protocol);
233
+ }
234
+ function createSender(urls) {
235
+ const registries = urls.map((url) => {
236
+ const provider = resolveProvider(url);
237
+ if (!provider) return;
238
+ return {
239
+ provider,
240
+ url
241
+ };
242
+ }).filter((p) => !!p);
243
+ return { async send(message, options) {
244
+ for (const registry of registries) {
245
+ const messageObj = { title: message };
246
+ await registry.provider.send(registry.url.toString(), messageObj, options);
247
+ }
248
+ } };
249
+ }
250
+ return Object.assign(createSender, { resolveProvider });
251
+ }
252
+
253
+ //#endregion
254
+ //#region src/services/push/bark/index.ts
255
+ const querySchema = z.object({
256
+ subtitle: z.string().optional(),
257
+ group: z.string().optional(),
258
+ url: z.string().optional(),
259
+ icon: z.string().optional(),
260
+ sound: z.string().optional(),
261
+ call: z.enum(["1"]).optional(),
262
+ ciphertext: z.string().optional(),
263
+ level: z.enum([
264
+ "active",
265
+ "timeSensitive",
266
+ "passive",
267
+ "critical"
268
+ ]).optional(),
269
+ volume: z.string().optional(),
270
+ badge: z.coerce.number().optional(),
271
+ autoCopy: z.enum(["1"]).optional(),
272
+ copy: z.string().optional(),
273
+ action: z.enum(["none"]).optional(),
274
+ isArchive: z.enum(["1"]).optional()
275
+ });
276
+ const bark = defineProvider("bark:", {
277
+ transport: http,
278
+ defaultOptions: {},
279
+ async prepare(ctx, options) {
280
+ const { message, url } = ctx;
281
+ assert(url.hostname, "Server URL hostname is required");
282
+ assert(url.pathname, "Device key is required");
283
+ const deviceKeys = url.pathname.split("/").filter(Boolean);
284
+ assert(deviceKeys.length > 0, "At least one device key is required");
285
+ const queryResult = getValidateQuery(url, querySchema.safeParse);
286
+ if (!queryResult.success) throw new Error("Invalid Bark query parameters");
287
+ const query = queryResult.data;
288
+ const requestUrl = new URL(`/push`, withProtocol(withoutPathname(url.toString()), "https:"));
289
+ const headers = new Headers([["Content-Type", "application/json"]]);
290
+ const contentData = message.body ? {
291
+ title: message.title,
292
+ body: message.body
293
+ } : { body: message.title };
294
+ const body = defu({ device_keys: deviceKeys }, contentData, query);
295
+ return {
296
+ request: new Request(requestUrl, {
297
+ method: "POST",
298
+ headers,
299
+ body: JSON.stringify(body)
300
+ }),
301
+ fetchOptions: options.fetchOptions
302
+ };
303
+ }
304
+ });
305
+
182
306
  //#endregion
183
307
  //#region src/services/specialized/json/index.ts
184
308
  const json = defineProvider("json:", {
@@ -214,34 +338,4 @@ const json = defineProvider("json:", {
214
338
  });
215
339
 
216
340
  //#endregion
217
- //#region src/core/sender.ts
218
- function buildSenderRegistry(providers) {
219
- const providersRegistry = /* @__PURE__ */ new Map();
220
- providers.forEach((provider) => {
221
- providersRegistry.set(provider.protocol, provider);
222
- });
223
- function resolveProvider(url) {
224
- const _url = typeof url === "string" ? new URL(url) : url;
225
- return providersRegistry.get(_url.protocol);
226
- }
227
- function createSender(urls) {
228
- const registries = urls.map((url) => {
229
- const provider = resolveProvider(url);
230
- if (!provider) return;
231
- return {
232
- provider,
233
- url
234
- };
235
- }).filter((p) => !!p);
236
- return { async send(message, options) {
237
- for (const registry of registries) {
238
- const messageObj = { title: message };
239
- await registry.provider.send(registry.url.toString(), messageObj, options);
240
- }
241
- } };
242
- }
243
- return Object.assign(createSender, { resolveProvider });
244
- }
245
-
246
- //#endregion
247
- export { http as a, assert as c, slack as i, json as n, defineTransport as o, telegram as r, defineProvider as s, buildSenderRegistry as t };
341
+ export { slack as a, defineTransport as c, telegram as i, defineProvider as l, bark as n, discord as o, buildSenderRegistry as r, http as s, json as t, assert as u };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "statocysts",
3
3
  "type": "module",
4
- "version": "0.7.0",
4
+ "version": "0.9.0",
5
5
  "description": "Notification library for JavaScript",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/octoplorer/statocysts",
@@ -47,14 +47,17 @@
47
47
  "dependencies": {
48
48
  "add": "^2.0.6",
49
49
  "defu": "^6.1.4",
50
+ "emailjs": "^5.0.0",
50
51
  "ofetch": "^1.5.1",
51
52
  "ufo": "^1.6.1",
52
53
  "zod": "^4.2.1"
53
54
  },
54
55
  "devDependencies": {
55
56
  "@types/node": "^25.0.3",
57
+ "@types/smtp-server": "^3.5.12",
56
58
  "@vitest/coverage-v8": "4.0.16",
57
- "tsdown": "^0.18.1",
59
+ "smtp-server": "^3.18.0",
60
+ "tsdown": "^0.18.2",
58
61
  "typescript": "^5.9.3",
59
62
  "vitest": "^4.0.16"
60
63
  },