statocysts 0.10.2 → 0.11.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 +2 -2
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +5 -5
- package/dist/browser.js.map +1 -1
- package/dist/{index-Tf7eZY-O.d.ts → index-3aBHgxSi.d.ts} +12 -5
- package/dist/index-3aBHgxSi.d.ts.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -7
- package/dist/index.js.map +1 -1
- package/dist/{server-chan-UPO915jk.js → server-chan-DeSNBT3J.js} +86 -23
- package/dist/server-chan-DeSNBT3J.js.map +1 -0
- package/package.json +4 -3
- package/dist/index-Tf7eZY-O.d.ts.map +0 -1
- package/dist/server-chan-UPO915jk.js.map +0 -1
package/dist/browser.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { _ as
|
|
1
|
+
import { _ as defineProvider, a as slack, c as HttpPayload, d as SenderRegistry, f as SenderUrl, g as ServiceProvider, h as DefineProviderOptions, i as telegram, l as http, m as DefineProviderContext, o as lark, p as buildSenderRegistry, r as bark, s as discord, t as json, u as Sender, v as Transport, y as defineTransport } from "./index-3aBHgxSi.js";
|
|
2
2
|
|
|
3
3
|
//#region src/browser.d.ts
|
|
4
4
|
declare const senderRegistry: SenderRegistry;
|
|
5
5
|
declare function createSender(urls: SenderUrl[]): Sender;
|
|
6
6
|
declare function send(url: string | URL, title: string, body?: string): Promise<void>;
|
|
7
7
|
//#endregion
|
|
8
|
-
export { DefineProviderContext, DefineProviderOptions, HttpPayload, Sender, SenderRegistry, SenderUrl, ServiceProvider, Transport, bark, buildSenderRegistry, createSender, defineProvider, defineTransport, discord, http, json, send, senderRegistry, slack, telegram };
|
|
8
|
+
export { DefineProviderContext, DefineProviderOptions, HttpPayload, Sender, SenderRegistry, SenderUrl, ServiceProvider, Transport, bark, buildSenderRegistry, createSender, defineProvider, defineTransport, discord, http, json, lark, send, senderRegistry, slack, telegram };
|
|
9
9
|
//# sourceMappingURL=browser.d.ts.map
|
package/dist/browser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","names":[],"sources":["../src/browser.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"browser.d.ts","names":[],"sources":["../src/browser.ts"],"mappings":";;;cAWa,cAAA,EAAqG,cAAA;AAAA,iBAElG,YAAA,CAAa,IAAA,EAAM,SAAA,KAAc,MAAA;AAAA,iBAI3B,IAAA,CACpB,GAAA,WAAc,GAAA,EACd,KAAA,UACA,IAAA,YACC,OAAA"}
|
package/dist/browser.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { a as buildSenderRegistry, c as
|
|
2
|
-
|
|
1
|
+
import { a as buildSenderRegistry, c as lark, d as defineTransport, f as defineProvider, i as bark, l as discord, n as json, o as telegram, p as assert, r as jsons, s as slack, t as serverChan, u as http } from "./server-chan-DeSNBT3J.js";
|
|
3
2
|
//#region src/browser.ts
|
|
4
3
|
const senderRegistry = buildSenderRegistry([
|
|
5
4
|
bark,
|
|
@@ -8,7 +7,8 @@ const senderRegistry = buildSenderRegistry([
|
|
|
8
7
|
jsons,
|
|
9
8
|
slack,
|
|
10
9
|
telegram,
|
|
11
|
-
discord
|
|
10
|
+
discord,
|
|
11
|
+
lark
|
|
12
12
|
]);
|
|
13
13
|
function createSender(urls) {
|
|
14
14
|
return senderRegistry(urls);
|
|
@@ -23,7 +23,7 @@ async function send(url, title, body) {
|
|
|
23
23
|
};
|
|
24
24
|
await provider.send(_url.toString(), messageObj);
|
|
25
25
|
}
|
|
26
|
-
|
|
27
26
|
//#endregion
|
|
28
|
-
export { bark, buildSenderRegistry, createSender, defineProvider, defineTransport, discord, http, json, send, senderRegistry, slack, telegram };
|
|
27
|
+
export { bark, buildSenderRegistry, createSender, defineProvider, defineTransport, discord, http, json, lark, send, senderRegistry, slack, telegram };
|
|
28
|
+
|
|
29
29
|
//# sourceMappingURL=browser.js.map
|
package/dist/browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","names":[],"sources":["../src/browser.ts"],"sourcesContent":["import type { Sender, SenderUrl } from '#/shared'\nimport { discord } from '#/services/chat/discord'\nimport { slack } from '#/services/chat/slack'\nimport { telegram } from '#/services/chat/telegram'\nimport { bark } from '#/services/push/bark'\nimport { json, jsons } from '#/services/specialized/json'\nimport { buildSenderRegistry } from '#/shared'\nimport { assert } from '#/utils'\nimport { serverChan } from './services/push/server-chan'\n\nexport const senderRegistry = buildSenderRegistry([bark, json, serverChan, jsons, slack, telegram, discord])\n\nexport function createSender(urls: SenderUrl[]): Sender {\n return senderRegistry(urls)\n}\n\nexport async function send(\n url: string | URL,\n title: string,\n body?: string,\n): Promise<void> {\n const _url = typeof url === 'string' ? new URL(url) : url\n const provider = senderRegistry.resolveProvider(_url)\n assert(provider, `Unsupported protocol ${_url.protocol}`)\n const messageObj = { title, body }\n await provider.send(_url.toString(), messageObj)\n}\n\nexport { bark, discord, json, slack, telegram }\nexport * from './shared'\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"browser.js","names":[],"sources":["../src/browser.ts"],"sourcesContent":["import type { Sender, SenderUrl } from '#/shared'\nimport { discord } from '#/services/chat/discord'\nimport { lark } from '#/services/chat/lark'\nimport { slack } from '#/services/chat/slack'\nimport { telegram } from '#/services/chat/telegram'\nimport { bark } from '#/services/push/bark'\nimport { json, jsons } from '#/services/specialized/json'\nimport { buildSenderRegistry } from '#/shared'\nimport { assert } from '#/utils'\nimport { serverChan } from './services/push/server-chan'\n\nexport const senderRegistry = buildSenderRegistry([bark, json, serverChan, jsons, slack, telegram, discord, lark])\n\nexport function createSender(urls: SenderUrl[]): Sender {\n return senderRegistry(urls)\n}\n\nexport async function send(\n url: string | URL,\n title: string,\n body?: string,\n): Promise<void> {\n const _url = typeof url === 'string' ? new URL(url) : url\n const provider = senderRegistry.resolveProvider(_url)\n assert(provider, `Unsupported protocol ${_url.protocol}`)\n const messageObj = { title, body }\n await provider.send(_url.toString(), messageObj)\n}\n\nexport { bark, discord, json, lark, slack, telegram }\nexport * from './shared'\n"],"mappings":";;AAWA,MAAa,iBAAiB,oBAAoB;CAAC;CAAM;CAAM;CAAY;CAAO;CAAO;CAAU;CAAS;CAAK,CAAC;AAElH,SAAgB,aAAa,MAA2B;AACtD,QAAO,eAAe,KAAK;;AAG7B,eAAsB,KACpB,KACA,OACA,MACe;CACf,MAAM,OAAO,OAAO,QAAQ,WAAW,IAAI,IAAI,IAAI,GAAG;CACtD,MAAM,WAAW,eAAe,gBAAgB,KAAK;AACrD,QAAO,UAAU,wBAAwB,KAAK,WAAW;CACzD,MAAM,aAAa;EAAE;EAAO;EAAM;AAClC,OAAM,SAAS,KAAK,KAAK,UAAU,EAAE,WAAW"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as ofetch$1 from "ofetch";
|
|
2
2
|
import { FetchOptions } from "ofetch";
|
|
3
3
|
import z from "zod";
|
|
4
4
|
|
|
@@ -72,6 +72,13 @@ interface DiscordOptions {
|
|
|
72
72
|
}
|
|
73
73
|
declare const discord: ServiceProvider<"discord:", HttpPayload, DiscordOptions>;
|
|
74
74
|
//#endregion
|
|
75
|
+
//#region src/services/chat/lark/index.d.ts
|
|
76
|
+
interface LarkOptions {
|
|
77
|
+
baseUrl?: string;
|
|
78
|
+
fetchOptions?: FetchOptions;
|
|
79
|
+
}
|
|
80
|
+
declare const lark: ServiceProvider<"lark:", HttpPayload, LarkOptions>;
|
|
81
|
+
//#endregion
|
|
75
82
|
//#region src/services/chat/slack/index.d.ts
|
|
76
83
|
interface SlackOptions {
|
|
77
84
|
/**
|
|
@@ -115,8 +122,8 @@ interface BarkOptions {
|
|
|
115
122
|
declare const bark: ServiceProvider<"bark:", HttpPayload, BarkOptions>;
|
|
116
123
|
//#endregion
|
|
117
124
|
//#region src/services/specialized/json/index.d.ts
|
|
118
|
-
declare const json: ServiceProvider<"json:", HttpPayload, FetchOptions<
|
|
119
|
-
declare const jsons: ServiceProvider<"jsons:", HttpPayload, FetchOptions<
|
|
125
|
+
declare const json: ServiceProvider<"json:", HttpPayload, FetchOptions<ofetch$1.ResponseType, any>>;
|
|
126
|
+
declare const jsons: ServiceProvider<"jsons:", HttpPayload, FetchOptions<ofetch$1.ResponseType, any>>;
|
|
120
127
|
//#endregion
|
|
121
|
-
export {
|
|
122
|
-
//# sourceMappingURL=index-
|
|
128
|
+
export { defineProvider as _, slack as a, HttpPayload as c, SenderRegistry as d, SenderUrl as f, ServiceProvider as g, DefineProviderOptions as h, telegram as i, http as l, DefineProviderContext as m, jsons as n, lark as o, buildSenderRegistry as p, bark as r, discord as s, json as t, Sender as u, Transport as v, defineTransport as y };
|
|
129
|
+
//# sourceMappingURL=index-3aBHgxSi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-3aBHgxSi.d.ts","names":[],"sources":["../src/core/transport.ts","../src/core/provider.ts","../src/core/sender.ts","../src/core/transports/http.ts","../src/services/chat/discord/index.ts","../src/services/chat/lark/index.ts","../src/services/chat/slack/index.ts","../src/services/chat/telegram/index.ts","../src/services/push/bark/index.ts","../src/services/specialized/json/index.ts"],"mappings":";;;;;;;;;UAIiB,SAAA;EAAA;;;;EAKf,IAAA,GAAO,OAAA,EAAS,OAAA,KAAY,OAAA;AAAA;AAAA,iBAGd,eAAA,SAAA,CACd,SAAA,EAAW,SAAA,CAAU,OAAA,IACpB,SAAA,CAAU,OAAA;;;KCTR,qBAAA,MAA2B,CAAA,SAAU,SAAA,YAAqB,CAAA;AAAA,UAE9C,eAAA;EAAA,SAKN,UAAA,EAAY,SAAA,CAAU,OAAA;EAAA,SACtB,QAAA,EAAU,QAAA;EACnB,cAAA,EAAgB,OAAA;EAChB,IAAA,GAAO,GAAA,UAAa,OAAA;IAAW,KAAA;IAAe,IAAA;EAAA,GAAiB,OAAA,GAAU,OAAA,KAAY,OAAA;AAAA;AAAA,UAGtE,qBAAA;EACf,GAAA,EAAK,GAAA;EACL,OAAA;IAAW,KAAA;IAAe,IAAA;EAAA;AAAA;AAAA,UAGX,qBAAA,WAAgC,SAAA;EAC/C,cAAA,GAAiB,OAAA;EACjB,SAAA,EAAW,CAAA;EACX,OAAA,GACE,IAAA,EAAM,qBAAA,EACN,GAAA,EAAK,qBAAA,EACL,OAAA,EAAS,OAAA,KACN,OAAA,CAAQ,qBAAA,CAAsB,CAAA;AAAA;AAAA,iBAGrB,cAAA,0CAAwD,SAAA,sBAAA,CACtE,QAAA,EAAU,QAAA,EACV,aAAA,EAAe,qBAAA,CAAsB,CAAA,EAAG,OAAA,IACvC,eAAA,CAAgB,QAAA,EAAU,qBAAA,CAAsB,CAAA,GAAI,OAAA;;;UClCtC,MAAA;EACf,IAAA,GAAO,KAAA,UAAe,IAAA,cAAkB,OAAA;AAAA;AAAA,KAG9B,SAAA,YAAqB,GAAA;AAAA,UAEhB,cAAA;EAAA,CACd,IAAA,EAAM,SAAA,KAAc,MAAA;EACrB,eAAA,GAAkB,GAAA,WAAc,GAAA,KAAQ,eAAA;AAAA;AAAA,iBAG1B,mBAAA,CACd,SAAA,EAAW,eAAA,uBACV,cAAA;;;;;;UCRc,WAAA;EACf,OAAA,EAAS,OAAA;EACT,YAAA,GAAe,YAAA;AAAA;;;;;cAOJ,IAAA,EAAI,SAAA,CAAA,WAAA;;;UCTP,cAAA;EACR,YAAA,GAAe,YAAA;AAAA;AAAA,cAeJ,OAAA,EAAO,eAAA,aA2ClB,WAAA,EA3CkB,cAAA;;;UClBV,WAAA;EACR,OAAA;EACA,YAAA,GAAe,YAAA;AAAA;AAAA,cAoBJ,IAAA,EAAI,eAAA,UA8Df,WAAA,EA9De,WAAA;;;UCrBA,YAAA;;;;ANFjB;;EMQE,WAAA;ENHmC;;;;;EMSnC,aAAA;ENTmC;;AAGrC;;;EMaE,IAAA,GAAO,MAAA;EAEP,YAAA,GAAe,YAAA;AAAA;AAAA,cAGJ,KAAA,EAAK,eAAA,WAsFhB,WAAA,EAtFgB,YAAA;;;UCnBD,eAAA;EPFf;;;;;EOQA,UAAA;EAEA,YAAA,GAAe,YAAA;AAAA;AAAA,cAGJ,QAAA,EAAQ,eAAA,cAwGnB,WAAA,EAxGmB,eAAA;;;UCfJ,WAAA;EACf,YAAA,GAAe,YAAA;AAAA;AAAA,cAoBJ,IAAA,EAAI,eAAA,UAyCf,WAAA,EAzCe,WAAA;;;cC4BJ,IAAA,EAAI,eAAA,UAMf,WAAA,EANe,YAAA,CAAA,QAAA,CAAA,YAAA;AAAA,cASJ,KAAA,EAAK,eAAA,WAMhB,WAAA,EANgB,YAAA,CAAA,QAAA,CAAA,YAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as
|
|
1
|
+
import { _ as defineProvider, a as slack, c as HttpPayload, d as SenderRegistry, f as SenderUrl, g as ServiceProvider, h as DefineProviderOptions, i as telegram, l as http, m as DefineProviderContext, n as jsons, o as lark, p as buildSenderRegistry, r as bark, s as discord, t as json, u as Sender, v as Transport, y as defineTransport } from "./index-3aBHgxSi.js";
|
|
2
2
|
import { Message, MessageHeaders, SMTPConnectionOptions } from "emailjs";
|
|
3
3
|
|
|
4
4
|
//#region src/core/transports/smtp.d.ts
|
|
@@ -28,5 +28,5 @@ declare const senderRegistry: SenderRegistry;
|
|
|
28
28
|
declare function createSender(urls: SenderUrl[]): Sender;
|
|
29
29
|
declare function send(url: string | URL, title: string, body?: string): Promise<void>;
|
|
30
30
|
//#endregion
|
|
31
|
-
export { DefineProviderContext, DefineProviderOptions, HttpPayload, Sender, SenderRegistry, SenderUrl, ServiceProvider, Transport, bark, buildSenderRegistry, createSender, defineProvider, defineTransport, discord, email, http, json, jsons, send, senderRegistry, slack, telegram };
|
|
31
|
+
export { DefineProviderContext, DefineProviderOptions, HttpPayload, Sender, SenderRegistry, SenderUrl, ServiceProvider, Transport, bark, buildSenderRegistry, createSender, defineProvider, defineTransport, discord, email, http, json, jsons, lark, send, senderRegistry, slack, telegram };
|
|
32
32
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/core/transports/smtp.ts","../src/services/specialized/email/index.ts","../src/index.ts"],"mappings":";;;;;;;UAOiB,WAAA;EAAW;;;EAI1B,MAAA,EAAQ,OAAA,CAAQ,qBAAA;EAIP;;;EAAT,OAAA,EAAS,OAAA,GAAU,cAAA;AAAA;;;UCRJ,YAAA;EAEf,WAAA;EAEA,UAAA,GAAa,OAAA,CAAQ,qBAAA;AAAA;AAAA,cAWV,KAAA,EAAK,eAAA,WAAA,WAAA,EAAA,YAAA;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/core/transports/smtp.ts","../src/services/specialized/email/index.ts","../src/index.ts"],"mappings":";;;;;;;UAOiB,WAAA;EAAW;;;EAI1B,MAAA,EAAQ,OAAA,CAAQ,qBAAA;EAIP;;;EAAT,OAAA,EAAS,OAAA,GAAU,cAAA;AAAA;;;UCRJ,YAAA;EAEf,WAAA;EAEA,UAAA,GAAa,OAAA,CAAQ,qBAAA;AAAA;AAAA,cAWV,KAAA,EAAK,eAAA,WAAA,WAAA,EAAA,YAAA;;;cCVL,cAAA,EAA4G,cAAA;AAAA,iBAEzG,YAAA,CAAa,IAAA,EAAM,SAAA,KAAc,MAAA;AAAA,iBAI3B,IAAA,CACpB,GAAA,WAAc,GAAA,EACd,KAAA,UACA,IAAA,YACC,OAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { a as buildSenderRegistry, c as
|
|
1
|
+
import { a as buildSenderRegistry, c as lark, d as defineTransport, f as defineProvider, i as bark, l as discord, n as json, o as telegram, p as assert, r as jsons, s as slack, t as serverChan, u as http } from "./server-chan-DeSNBT3J.js";
|
|
2
2
|
import z from "zod";
|
|
3
3
|
import { SMTPClient } from "emailjs";
|
|
4
|
-
|
|
5
4
|
//#region src/core/transports/smtp.ts
|
|
6
5
|
/**
|
|
7
6
|
* SMTP transport implementation
|
|
@@ -10,7 +9,6 @@ import { SMTPClient } from "emailjs";
|
|
|
10
9
|
const smtp = defineTransport({ async send(payload) {
|
|
11
10
|
await new SMTPClient(payload.client).sendAsync(payload.message);
|
|
12
11
|
} });
|
|
13
|
-
|
|
14
12
|
//#endregion
|
|
15
13
|
//#region src/services/specialized/email/index.ts
|
|
16
14
|
const queryParamSchema = z.object({
|
|
@@ -72,7 +70,6 @@ const email = defineProvider("email:", {
|
|
|
72
70
|
};
|
|
73
71
|
}
|
|
74
72
|
});
|
|
75
|
-
|
|
76
73
|
//#endregion
|
|
77
74
|
//#region src/index.ts
|
|
78
75
|
const senderRegistry = buildSenderRegistry([
|
|
@@ -83,7 +80,8 @@ const senderRegistry = buildSenderRegistry([
|
|
|
83
80
|
serverChan,
|
|
84
81
|
slack,
|
|
85
82
|
telegram,
|
|
86
|
-
discord
|
|
83
|
+
discord,
|
|
84
|
+
lark
|
|
87
85
|
]);
|
|
88
86
|
function createSender(urls) {
|
|
89
87
|
return senderRegistry(urls);
|
|
@@ -98,7 +96,7 @@ async function send(url, title, body) {
|
|
|
98
96
|
};
|
|
99
97
|
await provider.send(_url.toString(), messageObj);
|
|
100
98
|
}
|
|
101
|
-
|
|
102
99
|
//#endregion
|
|
103
|
-
export { bark, buildSenderRegistry, createSender, defineProvider, defineTransport, discord, email, http, json, jsons, send, senderRegistry, slack, telegram };
|
|
100
|
+
export { bark, buildSenderRegistry, createSender, defineProvider, defineTransport, discord, email, http, json, jsons, lark, send, senderRegistry, slack, telegram };
|
|
101
|
+
|
|
104
102
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/core/transports/smtp.ts","../src/services/specialized/email/index.ts","../src/index.ts"],"sourcesContent":["import type { Message, MessageHeaders, SMTPConnectionOptions } from 'emailjs'\nimport { SMTPClient } from 'emailjs'\nimport { defineTransport } from '../transport'\n\n/**\n * SMTP payload for SMTP transport\n */\nexport interface SmtpPayload {\n /**\n * SMTP client configuration\n */\n client: Partial<SMTPConnectionOptions>\n /**\n * Email message to send\n */\n message: Message | MessageHeaders\n}\n\n/**\n * SMTP transport implementation\n * Handles sending emails over SMTP protocol using emailjs\n */\nexport const smtp = defineTransport({\n async send(payload: SmtpPayload) {\n const client = new SMTPClient(payload.client)\n await client.sendAsync(payload.message)\n },\n})\n","import type { SmtpPayload } from '#/core/transports/smtp'\nimport type { SMTPConnectionOptions } from 'emailjs'\nimport { defineProvider } from '#/core/provider'\nimport { smtp } from '#/core/transports/smtp'\nimport { assert } from '#/utils'\nimport z from 'zod'\n\nexport interface EmailOptions {\n // Optional default sender email address\n defaultFrom?: string\n // Optional default SMTP configuration\n smtpConfig?: Partial<SMTPConnectionOptions>\n}\n\n// Zod schema for validating single-value query parameters\nconst queryParamSchema = z.object({\n from: z.string().email().optional(),\n subject: z.string().optional(),\n ssl: z.string().transform(val => val === 'true').optional(),\n tls: z.string().transform(val => val !== 'false').optional(),\n})\n\nexport const email = defineProvider('email:', {\n transport: smtp,\n defaultOptions: {} as EmailOptions,\n async prepare(ctx, options) {\n const { url, message } = ctx\n\n // Parse query parameters (use getAll for multi-value parameters)\n const to = url.searchParams.getAll('to')\n const cc = url.searchParams.getAll('cc')\n const bcc = url.searchParams.getAll('bcc')\n\n // Parse single-value parameters\n const from = url.searchParams.get('from')\n const subject = url.searchParams.get('subject')\n const sslParam = url.searchParams.get('ssl')\n const tlsParam = url.searchParams.get('tls')\n\n // Validate single-value parameters\n const queryResult = queryParamSchema.safeParse({\n from: from || undefined,\n subject: subject || undefined,\n ssl: sslParam || undefined,\n tls: tlsParam || undefined,\n })\n\n if (!queryResult.success) {\n throw new Error(`Invalid email query parameters: ${queryResult.error.message}`)\n }\n\n const query = queryResult.data\n\n // Build SMTP client configuration\n const host = url.hostname\n assert(host, 'SMTP host is required')\n\n const port = url.port ? Number.parseInt(url.port, 10) : 587\n const user = decodeURIComponent(url.username || '')\n const password = decodeURIComponent(url.password || '')\n\n // Determine sender address\n const fromAddress = query.from || options.defaultFrom || user\n assert(fromAddress, 'Sender email address (from) is required')\n\n // Ensure at least one recipient is provided\n assert(to.length > 0, 'At least one recipient email address (to) is required')\n\n // Build email message\n const emailSubject = query.subject || message.title\n const text = message.body\n ? `${message.title}\\n\\n${message.body}`\n : message.title\n\n // Build SMTP payload\n const smtpPayload: SmtpPayload = {\n client: {\n host,\n port,\n // Only include auth if both user and password are provided\n ...(user && password ? { user, password } : {}),\n ssl: query.ssl ?? false,\n tls: query.tls ?? (port === 587),\n ...options.smtpConfig,\n },\n message: {\n from: fromAddress,\n to: to.join(', '), // emailjs accepts comma-separated string\n cc: cc.length > 0 ? cc.join(', ') : undefined,\n bcc: bcc.length > 0 ? bcc.join(', ') : undefined,\n subject: emailSubject,\n text,\n },\n }\n\n return smtpPayload\n },\n})\n","import type { Sender, SenderUrl } from '#/shared'\nimport { discord } from '#/services/chat/discord'\nimport { slack } from '#/services/chat/slack'\nimport { telegram } from '#/services/chat/telegram'\nimport { bark } from '#/services/push/bark'\nimport { email } from '#/services/specialized/email'\nimport { json, jsons } from '#/services/specialized/json'\nimport { buildSenderRegistry } from '#/shared'\nimport { assert } from '#/utils'\nimport { serverChan } from './services/push/server-chan'\n\nexport const senderRegistry = buildSenderRegistry([bark, email, json, jsons, serverChan, slack, telegram, discord])\n\nexport function createSender(urls: SenderUrl[]): Sender {\n return senderRegistry(urls)\n}\n\nexport async function send(\n url: string | URL,\n title: string,\n body?: string,\n): Promise<void> {\n const _url = typeof url === 'string' ? new URL(url) : url\n const provider = senderRegistry.resolveProvider(_url)\n assert(provider, `Unsupported protocol ${_url.protocol}`)\n const messageObj = { title, body }\n await provider.send(_url.toString(), messageObj)\n}\n\nexport { bark, discord, email, json, jsons, slack, telegram }\nexport * from './shared'\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/core/transports/smtp.ts","../src/services/specialized/email/index.ts","../src/index.ts"],"sourcesContent":["import type { Message, MessageHeaders, SMTPConnectionOptions } from 'emailjs'\nimport { SMTPClient } from 'emailjs'\nimport { defineTransport } from '../transport'\n\n/**\n * SMTP payload for SMTP transport\n */\nexport interface SmtpPayload {\n /**\n * SMTP client configuration\n */\n client: Partial<SMTPConnectionOptions>\n /**\n * Email message to send\n */\n message: Message | MessageHeaders\n}\n\n/**\n * SMTP transport implementation\n * Handles sending emails over SMTP protocol using emailjs\n */\nexport const smtp = defineTransport({\n async send(payload: SmtpPayload) {\n const client = new SMTPClient(payload.client)\n await client.sendAsync(payload.message)\n },\n})\n","import type { SmtpPayload } from '#/core/transports/smtp'\nimport type { SMTPConnectionOptions } from 'emailjs'\nimport { defineProvider } from '#/core/provider'\nimport { smtp } from '#/core/transports/smtp'\nimport { assert } from '#/utils'\nimport z from 'zod'\n\nexport interface EmailOptions {\n // Optional default sender email address\n defaultFrom?: string\n // Optional default SMTP configuration\n smtpConfig?: Partial<SMTPConnectionOptions>\n}\n\n// Zod schema for validating single-value query parameters\nconst queryParamSchema = z.object({\n from: z.string().email().optional(),\n subject: z.string().optional(),\n ssl: z.string().transform(val => val === 'true').optional(),\n tls: z.string().transform(val => val !== 'false').optional(),\n})\n\nexport const email = defineProvider('email:', {\n transport: smtp,\n defaultOptions: {} as EmailOptions,\n async prepare(ctx, options) {\n const { url, message } = ctx\n\n // Parse query parameters (use getAll for multi-value parameters)\n const to = url.searchParams.getAll('to')\n const cc = url.searchParams.getAll('cc')\n const bcc = url.searchParams.getAll('bcc')\n\n // Parse single-value parameters\n const from = url.searchParams.get('from')\n const subject = url.searchParams.get('subject')\n const sslParam = url.searchParams.get('ssl')\n const tlsParam = url.searchParams.get('tls')\n\n // Validate single-value parameters\n const queryResult = queryParamSchema.safeParse({\n from: from || undefined,\n subject: subject || undefined,\n ssl: sslParam || undefined,\n tls: tlsParam || undefined,\n })\n\n if (!queryResult.success) {\n throw new Error(`Invalid email query parameters: ${queryResult.error.message}`)\n }\n\n const query = queryResult.data\n\n // Build SMTP client configuration\n const host = url.hostname\n assert(host, 'SMTP host is required')\n\n const port = url.port ? Number.parseInt(url.port, 10) : 587\n const user = decodeURIComponent(url.username || '')\n const password = decodeURIComponent(url.password || '')\n\n // Determine sender address\n const fromAddress = query.from || options.defaultFrom || user\n assert(fromAddress, 'Sender email address (from) is required')\n\n // Ensure at least one recipient is provided\n assert(to.length > 0, 'At least one recipient email address (to) is required')\n\n // Build email message\n const emailSubject = query.subject || message.title\n const text = message.body\n ? `${message.title}\\n\\n${message.body}`\n : message.title\n\n // Build SMTP payload\n const smtpPayload: SmtpPayload = {\n client: {\n host,\n port,\n // Only include auth if both user and password are provided\n ...(user && password ? { user, password } : {}),\n ssl: query.ssl ?? false,\n tls: query.tls ?? (port === 587),\n ...options.smtpConfig,\n },\n message: {\n from: fromAddress,\n to: to.join(', '), // emailjs accepts comma-separated string\n cc: cc.length > 0 ? cc.join(', ') : undefined,\n bcc: bcc.length > 0 ? bcc.join(', ') : undefined,\n subject: emailSubject,\n text,\n },\n }\n\n return smtpPayload\n },\n})\n","import type { Sender, SenderUrl } from '#/shared'\nimport { discord } from '#/services/chat/discord'\nimport { lark } from '#/services/chat/lark'\nimport { slack } from '#/services/chat/slack'\nimport { telegram } from '#/services/chat/telegram'\nimport { bark } from '#/services/push/bark'\nimport { email } from '#/services/specialized/email'\nimport { json, jsons } from '#/services/specialized/json'\nimport { buildSenderRegistry } from '#/shared'\nimport { assert } from '#/utils'\nimport { serverChan } from './services/push/server-chan'\n\nexport const senderRegistry = buildSenderRegistry([bark, email, json, jsons, serverChan, slack, telegram, discord, lark])\n\nexport function createSender(urls: SenderUrl[]): Sender {\n return senderRegistry(urls)\n}\n\nexport async function send(\n url: string | URL,\n title: string,\n body?: string,\n): Promise<void> {\n const _url = typeof url === 'string' ? new URL(url) : url\n const provider = senderRegistry.resolveProvider(_url)\n assert(provider, `Unsupported protocol ${_url.protocol}`)\n const messageObj = { title, body }\n await provider.send(_url.toString(), messageObj)\n}\n\nexport { bark, discord, email, json, jsons, lark, slack, telegram }\nexport * from './shared'\n"],"mappings":";;;;;;;;AAsBA,MAAa,OAAO,gBAAgB,EAClC,MAAM,KAAK,SAAsB;AAE/B,OADe,IAAI,WAAW,QAAQ,OAAO,CAChC,UAAU,QAAQ,QAAQ;GAE1C,CAAC;;;ACZF,MAAM,mBAAmB,EAAE,OAAO;CAChC,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,UAAU;CACnC,SAAS,EAAE,QAAQ,CAAC,UAAU;CAC9B,KAAK,EAAE,QAAQ,CAAC,WAAU,QAAO,QAAQ,OAAO,CAAC,UAAU;CAC3D,KAAK,EAAE,QAAQ,CAAC,WAAU,QAAO,QAAQ,QAAQ,CAAC,UAAU;CAC7D,CAAC;AAEF,MAAa,QAAQ,eAAe,UAAU;CAC5C,WAAW;CACX,gBAAgB,EAAE;CAClB,MAAM,QAAQ,KAAK,SAAS;EAC1B,MAAM,EAAE,KAAK,YAAY;EAGzB,MAAM,KAAK,IAAI,aAAa,OAAO,KAAK;EACxC,MAAM,KAAK,IAAI,aAAa,OAAO,KAAK;EACxC,MAAM,MAAM,IAAI,aAAa,OAAO,MAAM;EAG1C,MAAM,OAAO,IAAI,aAAa,IAAI,OAAO;EACzC,MAAM,UAAU,IAAI,aAAa,IAAI,UAAU;EAC/C,MAAM,WAAW,IAAI,aAAa,IAAI,MAAM;EAC5C,MAAM,WAAW,IAAI,aAAa,IAAI,MAAM;EAG5C,MAAM,cAAc,iBAAiB,UAAU;GAC7C,MAAM,QAAQ,KAAA;GACd,SAAS,WAAW,KAAA;GACpB,KAAK,YAAY,KAAA;GACjB,KAAK,YAAY,KAAA;GAClB,CAAC;AAEF,MAAI,CAAC,YAAY,QACf,OAAM,IAAI,MAAM,mCAAmC,YAAY,MAAM,UAAU;EAGjF,MAAM,QAAQ,YAAY;EAG1B,MAAM,OAAO,IAAI;AACjB,SAAO,MAAM,wBAAwB;EAErC,MAAM,OAAO,IAAI,OAAO,OAAO,SAAS,IAAI,MAAM,GAAG,GAAG;EACxD,MAAM,OAAO,mBAAmB,IAAI,YAAY,GAAG;EACnD,MAAM,WAAW,mBAAmB,IAAI,YAAY,GAAG;EAGvD,MAAM,cAAc,MAAM,QAAQ,QAAQ,eAAe;AACzD,SAAO,aAAa,0CAA0C;AAG9D,SAAO,GAAG,SAAS,GAAG,wDAAwD;EAG9E,MAAM,eAAe,MAAM,WAAW,QAAQ;EAC9C,MAAM,OAAO,QAAQ,OACjB,GAAG,QAAQ,MAAM,MAAM,QAAQ,SAC/B,QAAQ;AAuBZ,SApBiC;GAC/B,QAAQ;IACN;IACA;IAEA,GAAI,QAAQ,WAAW;KAAE;KAAM;KAAU,GAAG,EAAE;IAC9C,KAAK,MAAM,OAAO;IAClB,KAAK,MAAM,OAAQ,SAAS;IAC5B,GAAG,QAAQ;IACZ;GACD,SAAS;IACP,MAAM;IACN,IAAI,GAAG,KAAK,KAAK;IACjB,IAAI,GAAG,SAAS,IAAI,GAAG,KAAK,KAAK,GAAG,KAAA;IACpC,KAAK,IAAI,SAAS,IAAI,IAAI,KAAK,KAAK,GAAG,KAAA;IACvC,SAAS;IACT;IACD;GACF;;CAIJ,CAAC;;;ACrFF,MAAa,iBAAiB,oBAAoB;CAAC;CAAM;CAAO;CAAM;CAAO;CAAY;CAAO;CAAU;CAAS;CAAK,CAAC;AAEzH,SAAgB,aAAa,MAA2B;AACtD,QAAO,eAAe,KAAK;;AAG7B,eAAsB,KACpB,KACA,OACA,MACe;CACf,MAAM,OAAO,OAAO,QAAQ,WAAW,IAAI,IAAI,IAAI,GAAG;CACtD,MAAM,WAAW,eAAe,gBAAgB,KAAK;AACrD,QAAO,UAAU,wBAAwB,KAAK,WAAW;CACzD,MAAM,aAAa;EAAE;EAAO;EAAM;AAClC,OAAM,SAAS,KAAK,KAAK,UAAU,EAAE,WAAW"}
|
|
@@ -2,21 +2,24 @@ import { getQuery, withProtocol, withoutLeadingSlash } from "ufo";
|
|
|
2
2
|
import defu from "defu";
|
|
3
3
|
import { ofetch } from "ofetch";
|
|
4
4
|
import z from "zod";
|
|
5
|
-
|
|
6
5
|
//#region src/utils/assert.ts
|
|
7
6
|
function assert(condition, message) {
|
|
8
7
|
if (!condition) throw typeof message === "string" ? new Error(message) : message;
|
|
9
8
|
}
|
|
10
|
-
|
|
11
9
|
//#endregion
|
|
12
10
|
//#region src/utils/markdown.ts
|
|
13
11
|
/**
|
|
14
|
-
* Escape special characters: _*[]()~`>#+-=|{}.!
|
|
12
|
+
* Escape special characters for Telegram MarkdownV2: _*[]()~`>#+-=|{}.!
|
|
15
13
|
*/
|
|
16
14
|
function escapeMarkdown(text) {
|
|
17
15
|
return text.replace(/([_*[\]()~`>#+\-=|{}.!])/g, "\\$1");
|
|
18
16
|
}
|
|
19
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Escape special characters for HTML: &<>
|
|
19
|
+
*/
|
|
20
|
+
function escapeHtml(text) {
|
|
21
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
22
|
+
}
|
|
20
23
|
//#endregion
|
|
21
24
|
//#region src/utils/url.ts
|
|
22
25
|
function getValidateQuery(url, parser) {
|
|
@@ -27,7 +30,6 @@ function withoutPathname(input) {
|
|
|
27
30
|
_url.pathname = "";
|
|
28
31
|
return _url.toString();
|
|
29
32
|
}
|
|
30
|
-
|
|
31
33
|
//#endregion
|
|
32
34
|
//#region src/core/provider.ts
|
|
33
35
|
function defineProvider(protocol, createOptions) {
|
|
@@ -55,13 +57,11 @@ function defineProvider(protocol, createOptions) {
|
|
|
55
57
|
send
|
|
56
58
|
};
|
|
57
59
|
}
|
|
58
|
-
|
|
59
60
|
//#endregion
|
|
60
61
|
//#region src/core/transport.ts
|
|
61
62
|
function defineTransport(transport) {
|
|
62
63
|
return transport;
|
|
63
64
|
}
|
|
64
|
-
|
|
65
65
|
//#endregion
|
|
66
66
|
//#region src/core/transports/http.ts
|
|
67
67
|
/**
|
|
@@ -71,7 +71,6 @@ function defineTransport(transport) {
|
|
|
71
71
|
const http = defineTransport({ async send(payload) {
|
|
72
72
|
await ofetch(payload.request, payload.fetchOptions);
|
|
73
73
|
} });
|
|
74
|
-
|
|
75
74
|
//#endregion
|
|
76
75
|
//#region src/services/chat/discord/index.ts
|
|
77
76
|
const querySchema$1 = z.object({
|
|
@@ -107,7 +106,67 @@ const discord = defineProvider("discord:", {
|
|
|
107
106
|
};
|
|
108
107
|
}
|
|
109
108
|
});
|
|
110
|
-
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/services/chat/lark/index.ts
|
|
111
|
+
const FEISHU_BASE_URL = "https://open.feishu.cn";
|
|
112
|
+
const LARK_BASE_URL = "https://open.larksuite.com";
|
|
113
|
+
async function computeSign(timestamp, secret) {
|
|
114
|
+
const key = `${timestamp}\n${secret}`;
|
|
115
|
+
const encoder = new TextEncoder();
|
|
116
|
+
const cryptoKey = await globalThis.crypto.subtle.importKey("raw", encoder.encode(key), {
|
|
117
|
+
name: "HMAC",
|
|
118
|
+
hash: "SHA-256"
|
|
119
|
+
}, false, ["sign"]);
|
|
120
|
+
const signature = await globalThis.crypto.subtle.sign("HMAC", cryptoKey, new Uint8Array(0));
|
|
121
|
+
return btoa(String.fromCharCode(...new Uint8Array(signature)));
|
|
122
|
+
}
|
|
123
|
+
const lark = defineProvider("lark:", {
|
|
124
|
+
transport: http,
|
|
125
|
+
defaultOptions: {},
|
|
126
|
+
async prepare(ctx, options) {
|
|
127
|
+
const { url } = ctx;
|
|
128
|
+
assert(url.hostname === "webhook", "Invalid lark URL");
|
|
129
|
+
assert(url.username, "Webhook token is required");
|
|
130
|
+
const token = url.username;
|
|
131
|
+
const secret = url.password || void 0;
|
|
132
|
+
const domain = url.searchParams.get("domain");
|
|
133
|
+
const baseUrl = options.baseUrl ?? (domain === "feishu" ? FEISHU_BASE_URL : LARK_BASE_URL);
|
|
134
|
+
const requestUrl = new URL(`/open-apis/bot/v2/hook/${token}`, baseUrl);
|
|
135
|
+
let body;
|
|
136
|
+
if (ctx.message.body) body = {
|
|
137
|
+
msg_type: "interactive",
|
|
138
|
+
card: {
|
|
139
|
+
header: { title: {
|
|
140
|
+
tag: "plain_text",
|
|
141
|
+
content: ctx.message.title
|
|
142
|
+
} },
|
|
143
|
+
elements: [{
|
|
144
|
+
tag: "markdown",
|
|
145
|
+
content: ctx.message.body
|
|
146
|
+
}]
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
else body = {
|
|
150
|
+
msg_type: "text",
|
|
151
|
+
content: { text: ctx.message.title }
|
|
152
|
+
};
|
|
153
|
+
if (secret) {
|
|
154
|
+
const timestamp = Math.floor(Date.now() / 1e3).toString();
|
|
155
|
+
const sign = await computeSign(timestamp, secret);
|
|
156
|
+
body.timestamp = timestamp;
|
|
157
|
+
body.sign = sign;
|
|
158
|
+
}
|
|
159
|
+
const headers = new Headers([["Content-Type", "application/json"]]);
|
|
160
|
+
return {
|
|
161
|
+
request: new Request(requestUrl, {
|
|
162
|
+
method: "POST",
|
|
163
|
+
headers,
|
|
164
|
+
body: JSON.stringify(body)
|
|
165
|
+
}),
|
|
166
|
+
fetchOptions: options.fetchOptions
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
});
|
|
111
170
|
//#endregion
|
|
112
171
|
//#region src/services/chat/slack/index.ts
|
|
113
172
|
const slack = defineProvider("slack:", {
|
|
@@ -168,7 +227,6 @@ const slack = defineProvider("slack:", {
|
|
|
168
227
|
};
|
|
169
228
|
}
|
|
170
229
|
});
|
|
171
|
-
|
|
172
230
|
//#endregion
|
|
173
231
|
//#region src/services/chat/telegram/index.ts
|
|
174
232
|
const telegramQuerySchema = z.object({ parse_mode: z.enum([
|
|
@@ -197,11 +255,20 @@ const telegram = defineProvider("telegram:", {
|
|
|
197
255
|
if (this.message.body) {
|
|
198
256
|
const parseMode = query.parse_mode;
|
|
199
257
|
let titleFormatted;
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
258
|
+
let bodyFormatted;
|
|
259
|
+
if (parseMode === "HTML") {
|
|
260
|
+
titleFormatted = `<b>${escapeHtml(this.message.title)}</b>`;
|
|
261
|
+
bodyFormatted = escapeHtml(this.message.body);
|
|
262
|
+
} else if (parseMode === "MarkdownV2") {
|
|
263
|
+
titleFormatted = `*${escapeMarkdown(this.message.title)}*`;
|
|
264
|
+
bodyFormatted = escapeMarkdown(this.message.body);
|
|
265
|
+
} else {
|
|
266
|
+
titleFormatted = `*${this.message.title}*`;
|
|
267
|
+
bodyFormatted = this.message.body;
|
|
268
|
+
}
|
|
269
|
+
text = `${titleFormatted}\n\n${bodyFormatted}`;
|
|
204
270
|
} else if (query.parse_mode === "MarkdownV2") text = escapeMarkdown(this.message.title);
|
|
271
|
+
else if (query.parse_mode === "HTML") text = escapeHtml(this.message.title);
|
|
205
272
|
else text = this.message.title;
|
|
206
273
|
const body = {
|
|
207
274
|
chat_id: chatId,
|
|
@@ -219,7 +286,6 @@ const telegram = defineProvider("telegram:", {
|
|
|
219
286
|
};
|
|
220
287
|
}
|
|
221
288
|
});
|
|
222
|
-
|
|
223
289
|
//#endregion
|
|
224
290
|
//#region src/core/sender.ts
|
|
225
291
|
function buildSenderRegistry(providers) {
|
|
@@ -252,7 +318,6 @@ function buildSenderRegistry(providers) {
|
|
|
252
318
|
}
|
|
253
319
|
return Object.assign(createSender, { resolveProvider });
|
|
254
320
|
}
|
|
255
|
-
|
|
256
321
|
//#endregion
|
|
257
322
|
//#region src/services/push/bark/index.ts
|
|
258
323
|
const querySchema = z.object({
|
|
@@ -292,8 +357,8 @@ const bark = defineProvider("bark:", {
|
|
|
292
357
|
const headers = new Headers([["Content-Type", "application/json"]]);
|
|
293
358
|
const contentData = message.body ? {
|
|
294
359
|
title: message.title,
|
|
295
|
-
|
|
296
|
-
} : {
|
|
360
|
+
markdown: message.body
|
|
361
|
+
} : { markdown: message.title };
|
|
297
362
|
const body = defu({ device_keys: deviceKeys }, contentData, query);
|
|
298
363
|
return {
|
|
299
364
|
request: new Request(requestUrl, {
|
|
@@ -305,7 +370,6 @@ const bark = defineProvider("bark:", {
|
|
|
305
370
|
};
|
|
306
371
|
}
|
|
307
372
|
});
|
|
308
|
-
|
|
309
373
|
//#endregion
|
|
310
374
|
//#region src/services/specialized/json/index.ts
|
|
311
375
|
async function prepareJsonRequest(_ctx, defaultProtocol, options) {
|
|
@@ -350,7 +414,6 @@ const jsons = defineProvider("jsons:", {
|
|
|
350
414
|
return prepareJsonRequest.call(this, ctx, "https:", options);
|
|
351
415
|
}
|
|
352
416
|
});
|
|
353
|
-
|
|
354
417
|
//#endregion
|
|
355
418
|
//#region src/services/push/server-chan/index.ts
|
|
356
419
|
const serverChan = defineProvider("server-chan:", {
|
|
@@ -396,7 +459,7 @@ const serverChan = defineProvider("server-chan:", {
|
|
|
396
459
|
};
|
|
397
460
|
}
|
|
398
461
|
});
|
|
399
|
-
|
|
400
462
|
//#endregion
|
|
401
|
-
export { buildSenderRegistry as a,
|
|
402
|
-
|
|
463
|
+
export { buildSenderRegistry as a, lark as c, defineTransport as d, defineProvider as f, bark as i, discord as l, json as n, telegram as o, assert as p, jsons as r, slack as s, serverChan as t, http as u };
|
|
464
|
+
|
|
465
|
+
//# sourceMappingURL=server-chan-DeSNBT3J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-chan-DeSNBT3J.js","names":["querySchema"],"sources":["../src/utils/assert.ts","../src/utils/markdown.ts","../src/utils/url.ts","../src/core/provider.ts","../src/core/transport.ts","../src/core/transports/http.ts","../src/services/chat/discord/index.ts","../src/services/chat/lark/index.ts","../src/services/chat/slack/index.ts","../src/services/chat/telegram/index.ts","../src/core/sender.ts","../src/services/push/bark/index.ts","../src/services/specialized/json/index.ts","../src/services/push/server-chan/index.ts"],"sourcesContent":["export function assert(condition: any, message: string | Error): asserts condition {\n if (!condition) {\n throw typeof message === 'string' ? new Error(message) : message\n }\n}\n","/**\n * Escape special characters for Telegram MarkdownV2: _*[]()~`>#+-=|{}.!\n */\nexport function escapeMarkdown(text: string): string {\n return text.replace(/([_*[\\]()~`>#+\\-=|{}.!])/g, '\\\\$1')\n}\n\n/**\n * Escape special characters for HTML: &<>\n */\nexport function escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n}\n","import { getQuery } from 'ufo'\n\nexport function getValidateQuery<T>(\n url: URL | string,\n parser: (params: unknown) => T,\n): T {\n const query = getQuery(url.toString())\n return parser(query)\n}\n\nexport function withoutPathname(input: string): string {\n const _url = new URL(input)\n _url.pathname = ''\n return _url.toString()\n}\n","import type { Transport } from './transport'\nimport { assert } from '#/utils'\nimport defu from 'defu'\n\n// Utility type to infer Payload from Transport\ntype InferTransportPayload<T> = T extends Transport<infer P> ? P : never\n\nexport interface ServiceProvider<\n Protocol extends string,\n Payload,\n Options = void,\n> {\n readonly $transport: Transport<Payload>\n readonly protocol: Protocol\n defaultOptions: Options | undefined\n send: (url: string, message: { title: string, body?: string }, options?: Options) => Promise<void>\n}\n\nexport interface DefineProviderContext {\n url: URL\n message: { title: string, body?: string }\n}\n\nexport interface DefineProviderOptions<T extends Transport, Options> {\n defaultOptions?: Options\n transport: T\n prepare: (\n this: DefineProviderContext,\n ctx: DefineProviderContext,\n options: Options,\n ) => Promise<InferTransportPayload<T>>\n}\n\nexport function defineProvider<const Protocol extends string, T extends Transport<any>, Options = void>(\n protocol: Protocol,\n createOptions: DefineProviderOptions<T, Options>,\n): ServiceProvider<Protocol, InferTransportPayload<T>, Options> {\n const send: ServiceProvider<Protocol, InferTransportPayload<T>, Options>['send'] = async (\n protocolUrl,\n message,\n options,\n ): Promise<void> => {\n const url = new URL(protocolUrl)\n\n assert(url.protocol === protocol, `Unexpected protocol \"${url.protocol}\"`)\n\n const ctx: DefineProviderContext = {\n url,\n message,\n }\n\n const opts = defu(options ?? {}, createOptions.defaultOptions ?? {}) as Options\n\n const payload = await createOptions.prepare.call(ctx, ctx, opts)\n\n await createOptions.transport.send(payload)\n }\n return {\n get protocol() {\n return protocol\n },\n get defaultOptions() {\n return createOptions.defaultOptions\n },\n get $transport() {\n return createOptions.transport\n },\n send,\n }\n}\n","/**\n * Transport interface for protocol-specific network communication\n * Each transport handles the actual sending of data over a specific protocol\n */\nexport interface Transport<Payload = unknown> {\n /**\n * Send data using the transport's protocol\n * @param payload Protocol-specific payload to send\n */\n send: (payload: Payload) => Promise<void>\n}\n\nexport function defineTransport<Payload>(\n transport: Transport<Payload>,\n): Transport<Payload> {\n return transport\n}\n","import type { FetchOptions } from 'ofetch'\nimport { ofetch } from 'ofetch'\nimport { defineTransport } from '../transport'\n\n/**\n * HTTP payload for HTTP transport\n */\nexport interface HttpPayload {\n request: Request\n fetchOptions?: FetchOptions\n}\n\n/**\n * HTTP transport implementation\n * Handles sending data over HTTP/HTTPS protocols\n */\nexport const http = defineTransport({\n async send(payload: HttpPayload) {\n await ofetch(payload.request, payload.fetchOptions)\n },\n})\n","import type { FetchOptions } from 'ofetch'\nimport { defineProvider } from '#/core/provider'\nimport { http } from '#/core/transports/http'\nimport { assert, getValidateQuery } from '#/utils'\nimport defu from 'defu'\nimport z from 'zod'\n\ninterface DiscordOptions {\n fetchOptions?: FetchOptions\n}\n\nconst querySchema = z.object({\n avatar_url: z.string().optional(),\n username: z.string().optional(),\n\n wait: z.string().transform((val) => {\n if (val === 'false' || val === '0' || val === '') {\n return false\n }\n return true\n }).optional(),\n})\n\nexport const discord = defineProvider('discord:', {\n transport: http,\n defaultOptions: {} as DiscordOptions,\n async prepare(ctx, options) {\n const { url } = ctx\n\n assert(url.hostname === 'webhook', 'Invalid discord URL')\n assert(url.username, 'Webhook ID is required')\n assert(url.password, 'Webhook token is required')\n\n const queryResult = getValidateQuery(url, querySchema.safeParse)\n\n if (!queryResult.success) {\n throw new Error('Invalid discord query')\n }\n\n const { wait, ...query } = queryResult.data\n\n const headers = new Headers([\n ['Content-Type', 'application/json'],\n ])\n\n const content = ctx.message.body ? `## ${ctx.message.title}\\n\\n${ctx.message.body}` : ctx.message.title\n\n const body = defu({ content }, query)\n\n const requestUrl = new URL(`/api/webhooks/${url.username}/${url.password}`, 'https://discord.com')\n\n if (wait) {\n requestUrl.searchParams.set('wait', 'true')\n }\n\n const request = new Request(requestUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n })\n\n return {\n request,\n fetchOptions: options.fetchOptions,\n }\n },\n})\n","import type { FetchOptions } from 'ofetch'\nimport { defineProvider } from '#/core/provider'\nimport { http } from '#/core/transports/http'\nimport { assert } from '#/utils'\n\ninterface LarkOptions {\n baseUrl?: string\n fetchOptions?: FetchOptions\n}\n\nconst FEISHU_BASE_URL = 'https://open.feishu.cn'\nconst LARK_BASE_URL = 'https://open.larksuite.com'\n\nasync function computeSign(timestamp: string, secret: string): Promise<string> {\n const key = `${timestamp}\\n${secret}`\n const encoder = new TextEncoder()\n const cryptoKey = await globalThis.crypto.subtle.importKey(\n 'raw',\n encoder.encode(key),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n const signature = await globalThis.crypto.subtle.sign('HMAC', cryptoKey, new Uint8Array(0))\n return btoa(String.fromCharCode(...new Uint8Array(signature)))\n}\n\nexport const lark = defineProvider('lark:', {\n transport: http,\n defaultOptions: {} as LarkOptions,\n async prepare(ctx, options) {\n const { url } = ctx\n\n assert(url.hostname === 'webhook', 'Invalid lark URL')\n assert(url.username, 'Webhook token is required')\n\n const token = url.username\n const secret = url.password || undefined\n const domain = url.searchParams.get('domain')\n\n const baseUrl = options.baseUrl\n ?? (domain === 'feishu' ? FEISHU_BASE_URL : LARK_BASE_URL)\n\n const requestUrl = new URL(`/open-apis/bot/v2/hook/${token}`, baseUrl)\n\n let body: Record<string, unknown>\n\n if (ctx.message.body) {\n body = {\n msg_type: 'interactive',\n card: {\n header: {\n title: { tag: 'plain_text', content: ctx.message.title },\n },\n elements: [\n { tag: 'markdown', content: ctx.message.body },\n ],\n },\n }\n }\n else {\n body = {\n msg_type: 'text',\n content: { text: ctx.message.title },\n }\n }\n\n if (secret) {\n const timestamp = Math.floor(Date.now() / 1000).toString()\n const sign = await computeSign(timestamp, secret)\n body.timestamp = timestamp\n body.sign = sign\n }\n\n const headers = new Headers([\n ['Content-Type', 'application/json'],\n ])\n\n const request = new Request(requestUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n })\n\n return {\n request,\n fetchOptions: options.fetchOptions,\n }\n },\n})\n","import type { FetchOptions } from 'ofetch'\nimport { defineProvider } from '#/core/provider'\nimport { http } from '#/core/transports/http'\nimport { assert } from '#/utils'\nimport { withoutLeadingSlash } from 'ufo'\n\nexport interface SlackOptions {\n /**\n * The base URL for webhook services\n *\n * @default `https://hooks.slack.com/services`\n */\n hookBaseUrl?: string\n /**\n * The base URL for bot API services\n *\n * @default `https://slack.com/api`\n */\n botApiBaseUrl?: string\n\n /**\n * The body of the request\n *\n * NOTICE*: This will override the body of the request. You should known what you are doing.\n */\n body?: Record<string, any>\n\n fetchOptions?: FetchOptions\n}\n\nexport const slack = defineProvider('slack:', {\n transport: http,\n defaultOptions: {\n hookBaseUrl: 'https://hooks.slack.com/',\n botApiBaseUrl: 'https://slack.com/',\n } as SlackOptions,\n async prepare(_, options) {\n const { url } = this\n\n // Validate URL format\n assert(url.hostname === 'bot' || url.hostname === 'webhook', `Invalid slack URL: ${url.toString()}`)\n\n const type = url.hostname as 'bot' | 'webhook'\n\n if (type === 'bot') {\n assert(url.username, 'Channel ID is required')\n assert(url.password, 'Bot token is required')\n }\n else {\n const pathParts = url.pathname.split('/').filter(Boolean)\n assert(pathParts.length === 3, 'Webhook URL is invalid')\n }\n\n let requestUrl: URL\n const headers = new Headers([\n ['Content-Type', 'application/json'],\n ])\n const body: Record<string, any> = {}\n\n // Build message content based on title and body\n if (this.message.body) {\n // When body is present, use blocks for rich markdown formatting\n body.blocks = [\n {\n type: 'header',\n text: {\n type: 'plain_text',\n text: this.message.title,\n },\n },\n {\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: this.message.body,\n },\n },\n ]\n // Fallback text for notifications\n body.text = this.message.title\n }\n else {\n // When only title is present, use simple text format\n body.text = this.message.title\n }\n\n if (type === 'bot') {\n const { username: channel, password: token, searchParams } = url\n requestUrl = new URL('/api/chat.postMessage', options.botApiBaseUrl)\n searchParams.forEach((value, key) => {\n requestUrl.searchParams.set(key, value)\n })\n\n headers.set('Authorization', `Bearer ${token}`)\n\n body.channel = channel\n }\n else {\n const { searchParams } = url\n requestUrl = new URL(`/services/${withoutLeadingSlash(url.pathname)}`, options.hookBaseUrl)\n searchParams.forEach((value, key) => {\n requestUrl.searchParams.set(key, value)\n })\n }\n\n const request = new Request(requestUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(options.body ?? body),\n })\n\n return {\n request,\n fetchOptions: options.fetchOptions,\n }\n },\n})\n","import type { FetchOptions } from 'ofetch'\nimport { defineProvider } from '#/core/provider'\nimport { http } from '#/core/transports/http'\nimport { escapeHtml, escapeMarkdown, getValidateQuery } from '#/utils'\nimport { assert } from '#/utils/assert'\nimport z from 'zod'\n\nexport const telegramQuerySchema = z.object({\n parse_mode: z.enum(['Markdown', 'MarkdownV2', 'HTML']).optional(),\n})\n\nexport interface TelegramOptions {\n /**\n * The base URL for Telegram Bot API\n *\n * @default `https://api.telegram.org`\n */\n apiBaseUrl?: string\n\n fetchOptions?: FetchOptions\n}\n\nexport const telegram = defineProvider('telegram:', {\n transport: http,\n defaultOptions: {\n apiBaseUrl: 'https://api.telegram.org',\n } as TelegramOptions,\n async prepare(_, options) {\n const { url } = this\n\n // Validate URL format\n assert(url.hostname === 'bot', `Invalid telegram URL: ${url.toString()}`)\n assert(url.username, 'Bot token is required')\n\n // Extract chat IDs from pathname (e.g., /chat-1/chat-2)\n const pathSegments = url.pathname.split('/').filter(Boolean)\n assert(pathSegments.length > 0, 'At least one chat ID is required')\n\n const queryResult = getValidateQuery(url, telegramQuerySchema.safeParse)\n\n if (!queryResult.success) {\n throw new Error('Invalid telegram query')\n }\n\n const query = queryResult.data\n\n // Bot token is in the username and password fields, because token contains `:` character\n const botToken = `${url.username}:${url.password}`\n\n // First chat ID from pathname (decode to handle @ symbols like @mychannel)\n // Support format: chat-id or chat-id:message-thread-id\n const chatPart = decodeURIComponent(pathSegments[0])\n const [chatId, messageThreadId] = chatPart.includes(':')\n ? chatPart.split(':', 2)\n : [chatPart, undefined]\n\n // Build API URL\n const requestUrl = new URL(`/bot${botToken}/sendMessage`, options.apiBaseUrl)\n\n const headers = new Headers([\n ['Content-Type', 'application/json'],\n ])\n\n // Build message text based on parse_mode\n let text: string\n if (this.message.body) {\n // Title as h1, body as content\n const parseMode = query.parse_mode\n let titleFormatted: string\n let bodyFormatted: string\n\n if (parseMode === 'HTML') {\n // Escape title and body to prevent breaking HTML tags\n titleFormatted = `<b>${escapeHtml(this.message.title)}</b>`\n bodyFormatted = escapeHtml(this.message.body)\n }\n else if (parseMode === 'MarkdownV2') {\n // MarkdownV2 requires escaping special characters in title and body\n const escapedTitle = escapeMarkdown(this.message.title)\n titleFormatted = `*${escapedTitle}*`\n bodyFormatted = escapeMarkdown(this.message.body)\n }\n else {\n // Markdown or default\n titleFormatted = `*${this.message.title}*`\n bodyFormatted = this.message.body\n }\n\n text = `${titleFormatted}\\n\\n${bodyFormatted}`\n }\n else {\n // No body, title is the main content\n // Need to escape special characters in MarkdownV2/HTML mode\n if (query.parse_mode === 'MarkdownV2') {\n text = escapeMarkdown(this.message.title)\n }\n else if (query.parse_mode === 'HTML') {\n text = escapeHtml(this.message.title)\n }\n else {\n text = this.message.title\n }\n }\n\n const body: Record<string, any> = {\n chat_id: chatId,\n text,\n parse_mode: query.parse_mode,\n }\n\n // Add message_thread_id if specified (for topic/forum groups)\n if (messageThreadId) {\n body.message_thread_id = Number.parseInt(messageThreadId, 10)\n }\n\n const request = new Request(requestUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n })\n\n return {\n request,\n fetchOptions: options.fetchOptions,\n }\n },\n})\n","import type { ServiceProvider } from '#/core/provider'\n\nexport interface Sender {\n send: (title: string, body?: string) => Promise<void>\n}\n\nexport type SenderUrl = string | URL\n\nexport interface SenderRegistry {\n (urls: SenderUrl[]): Sender\n resolveProvider: (url: string | URL) => ServiceProvider<string, any, any> | undefined\n}\n\nexport function buildSenderRegistry(\n providers: ServiceProvider<string, any, any>[],\n): SenderRegistry {\n const providersRegistry = new Map<string, ServiceProvider<string, any, any>>()\n providers.forEach((provider) => {\n providersRegistry.set(provider.protocol, provider)\n })\n\n function resolveProvider(\n url: string | URL,\n ): ServiceProvider<string, any, any> | undefined {\n const _url = typeof url === 'string' ? new URL(url) : url\n\n return providersRegistry.get(_url.protocol)\n }\n\n function createSender(urls: SenderUrl[]): Sender {\n const registries = urls.map((url) => {\n const provider = resolveProvider(url)\n if (!provider) {\n return undefined\n }\n return { provider, url }\n }).filter((p): p is { provider: ServiceProvider<string, any, any>, url: SenderUrl } => !!p)\n\n return {\n async send(title: string, body?: string) {\n for (const registry of registries) {\n // Convert message string to { title, body? } format\n const messageObj = { title, body }\n await registry.provider.send(\n registry.url.toString(),\n messageObj,\n )\n }\n },\n }\n }\n\n return Object.assign(createSender, { resolveProvider })\n}\n","import type { FetchOptions } from 'ofetch'\nimport { defineProvider, http } from '#/shared'\nimport { assert, getValidateQuery, withoutPathname } from '#/utils'\nimport defu from 'defu'\nimport { withProtocol } from 'ufo'\nimport z from 'zod'\n\nexport interface BarkOptions {\n fetchOptions?: FetchOptions\n}\n\nconst querySchema = z.object({\n subtitle: z.string().optional(),\n group: z.string().optional(),\n url: z.string().optional(),\n icon: z.string().optional(),\n sound: z.string().optional(),\n call: z.enum(['1']).optional(),\n ciphertext: z.string().optional(),\n level: z.enum(['active', 'timeSensitive', 'passive', 'critical']).optional(),\n volume: z.string().optional(),\n badge: z.coerce.number().optional(),\n autoCopy: z.enum(['1']).optional(),\n copy: z.string().optional(),\n action: z.enum(['none']).optional(),\n isArchive: z.enum(['1']).optional(),\n})\n\nexport const bark = defineProvider('bark:', {\n transport: http,\n defaultOptions: {} as BarkOptions,\n async prepare(ctx, options) {\n const { message, url } = ctx\n\n assert(url.hostname, 'Server URL hostname is required')\n assert(url.pathname, 'Device key is required')\n\n const deviceKeys = url.pathname.split('/').filter(Boolean)\n assert(deviceKeys.length > 0, 'At least one device key is required')\n\n const queryResult = getValidateQuery(url, querySchema.safeParse)\n\n if (!queryResult.success) {\n throw new Error('Invalid Bark query parameters')\n }\n\n const query = queryResult.data\n\n const requestUrl = new URL(`/push`, withProtocol(withoutPathname(url.toString()), 'https:'))\n\n const headers = new Headers([\n ['Content-Type', 'application/json'],\n ])\n\n const contentData: { markdown: string, title?: string } = message.body ? { title: message.title, markdown: message.body } : { markdown: message.title }\n\n const body = defu({ device_keys: deviceKeys }, contentData, query)\n\n const request = new Request(requestUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n })\n\n return {\n request,\n fetchOptions: options.fetchOptions,\n }\n },\n})\n","import type { DefineProviderContext } from '#/core/provider'\nimport type { FetchOptions } from 'ofetch'\nimport { defineProvider } from '#/core/provider'\nimport { http } from '#/core/transports/http'\nimport { withProtocol } from 'ufo'\n\nasync function prepareJsonRequest(this: DefineProviderContext, _ctx: DefineProviderContext, defaultProtocol: string, options: FetchOptions) {\n const url = new URL(this.url)\n\n const protocol = defaultProtocol\n\n const headers = new Headers([\n ['Content-Type', 'application/json'],\n ])\n\n const body: Record<string, string> = {\n title: this.message.title,\n }\n\n if (this.message.body) {\n body.body = this.message.body\n }\n\n Array.from(url.searchParams.entries()).forEach(([key, value]) => {\n if (key.startsWith(' ')) {\n url.searchParams.delete(key)\n const headerKey = key.slice(1)\n if (headers.has(headerKey)) {\n headers.set(headerKey, value)\n }\n else {\n headers.append(headerKey, value)\n }\n }\n else if (key.startsWith(':')) {\n url.searchParams.delete(key)\n const propertyKey = key.slice(1)\n body[propertyKey] = value\n }\n })\n\n const requestUrl = withProtocol(url.toString(), protocol)\n\n const request = new Request(requestUrl, {\n method: 'POST',\n body: JSON.stringify(body),\n headers,\n })\n\n return {\n request,\n fetchOptions: options,\n }\n}\n\n// Supports json:// protocol (default to HTTP)\nexport const json = defineProvider('json:', {\n transport: http,\n defaultOptions: {} as FetchOptions,\n prepare(ctx, options) {\n return prepareJsonRequest.call(this, ctx, 'http:', options)\n },\n})\n\n// Supports jsons:// protocol (explicit HTTPS)\nexport const jsons = defineProvider('jsons:', {\n transport: http,\n defaultOptions: {} as FetchOptions,\n prepare(ctx, options) {\n return prepareJsonRequest.call(this, ctx, 'https:', options)\n },\n})\n","import type { FetchOptions } from 'ofetch'\nimport { defineProvider, http } from '#/shared'\nimport { assert } from '#/utils'\n\nexport interface ServerChanOptions {\n fetchOptions?: FetchOptions\n}\n\nexport const serverChan = defineProvider('server-chan:', {\n transport: http,\n defaultOptions: {} as ServerChanOptions,\n async prepare(_, options) {\n const { url } = this\n\n // Validate URL hostname to determine version\n assert(\n url.hostname === 'v3' || url.hostname === 'turbo',\n `Invalid server-chan URL: hostname must be 'v3' or 'turbo', got '${url.hostname}'`,\n )\n\n const version = url.hostname as 'v3' | 'turbo'\n\n let requestUrl: URL\n const headers = new Headers([\n ['Content-Type', 'application/json'],\n ])\n const body: Record<string, any> = {\n title: this.message.title,\n }\n\n if (this.message.body) {\n body.desp = this.message.body\n }\n\n if (version === 'v3') {\n // Server Chan 3: server-chan://uid:sendKey@v3?tags=<tag1>&tags=<tag2>&short=<short>\n const { username: uid, password: sendKey, searchParams } = url\n\n assert(uid, 'UID is required for Server Chan 3')\n assert(sendKey, 'SendKey is required for Server Chan 3')\n\n requestUrl = new URL(`https://${uid}.push.ft07.com/send/${sendKey}.send`)\n\n // Add optional parameters from searchParams\n const tags: string[] = []\n searchParams.forEach((value, key) => {\n if (key === 'tags') {\n tags.push(value)\n }\n else if (key === 'short') {\n body.short = value\n }\n })\n\n if (tags.length > 0) {\n body.tags = tags.join('|')\n }\n }\n else {\n // Server Chan Turbo: server-chan://ftqq:SENDKEY@turbo?short=<short>&noip=<1|0|true|false>&channel=<channel>&openid=<openid>\n // Note: username (ftqq) is optional and not used in the API request\n const { password: sendKey, searchParams } = url\n\n assert(sendKey, 'SendKey is required for Server Chan Turbo')\n\n requestUrl = new URL(`https://sctapi.ftqq.com/${sendKey}.send`)\n\n // Add optional parameters from searchParams\n searchParams.forEach((value, key) => {\n if (key === 'short') {\n body.short = value\n }\n else if (key === 'noip') {\n body.noip = value === '1' || value === 'true' ? 1 : 0\n }\n else if (key === 'channel') {\n body.channel = value\n }\n else if (key === 'openid') {\n body.openid = value\n }\n })\n }\n\n const request = new Request(requestUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n })\n\n return {\n request,\n fetchOptions: options.fetchOptions,\n }\n },\n})\n"],"mappings":";;;;;AAAA,SAAgB,OAAO,WAAgB,SAA4C;AACjF,KAAI,CAAC,UACH,OAAM,OAAO,YAAY,WAAW,IAAI,MAAM,QAAQ,GAAG;;;;;;;ACC7D,SAAgB,eAAe,MAAsB;AACnD,QAAO,KAAK,QAAQ,6BAA6B,OAAO;;;;;AAM1D,SAAgB,WAAW,MAAsB;AAC/C,QAAO,KACJ,QAAQ,MAAM,QAAQ,CACtB,QAAQ,MAAM,OAAO,CACrB,QAAQ,MAAM,OAAO;;;;ACZ1B,SAAgB,iBACd,KACA,QACG;AAEH,QAAO,OADO,SAAS,IAAI,UAAU,CAAC,CAClB;;AAGtB,SAAgB,gBAAgB,OAAuB;CACrD,MAAM,OAAO,IAAI,IAAI,MAAM;AAC3B,MAAK,WAAW;AAChB,QAAO,KAAK,UAAU;;;;ACoBxB,SAAgB,eACd,UACA,eAC8D;CAC9D,MAAM,OAA6E,OACjF,aACA,SACA,YACkB;EAClB,MAAM,MAAM,IAAI,IAAI,YAAY;AAEhC,SAAO,IAAI,aAAa,UAAU,wBAAwB,IAAI,SAAS,GAAG;EAE1E,MAAM,MAA6B;GACjC;GACA;GACD;EAED,MAAM,OAAO,KAAK,WAAW,EAAE,EAAE,cAAc,kBAAkB,EAAE,CAAC;EAEpE,MAAM,UAAU,MAAM,cAAc,QAAQ,KAAK,KAAK,KAAK,KAAK;AAEhE,QAAM,cAAc,UAAU,KAAK,QAAQ;;AAE7C,QAAO;EACL,IAAI,WAAW;AACb,UAAO;;EAET,IAAI,iBAAiB;AACnB,UAAO,cAAc;;EAEvB,IAAI,aAAa;AACf,UAAO,cAAc;;EAEvB;EACD;;;;ACxDH,SAAgB,gBACd,WACoB;AACpB,QAAO;;;;;;;;ACCT,MAAa,OAAO,gBAAgB,EAClC,MAAM,KAAK,SAAsB;AAC/B,OAAM,OAAO,QAAQ,SAAS,QAAQ,aAAa;GAEtD,CAAC;;;ACTF,MAAMA,gBAAc,EAAE,OAAO;CAC3B,YAAY,EAAE,QAAQ,CAAC,UAAU;CACjC,UAAU,EAAE,QAAQ,CAAC,UAAU;CAE/B,MAAM,EAAE,QAAQ,CAAC,WAAW,QAAQ;AAClC,MAAI,QAAQ,WAAW,QAAQ,OAAO,QAAQ,GAC5C,QAAO;AAET,SAAO;GACP,CAAC,UAAU;CACd,CAAC;AAEF,MAAa,UAAU,eAAe,YAAY;CAChD,WAAW;CACX,gBAAgB,EAAE;CAClB,MAAM,QAAQ,KAAK,SAAS;EAC1B,MAAM,EAAE,QAAQ;AAEhB,SAAO,IAAI,aAAa,WAAW,sBAAsB;AACzD,SAAO,IAAI,UAAU,yBAAyB;AAC9C,SAAO,IAAI,UAAU,4BAA4B;EAEjD,MAAM,cAAc,iBAAiB,KAAKA,cAAY,UAAU;AAEhE,MAAI,CAAC,YAAY,QACf,OAAM,IAAI,MAAM,wBAAwB;EAG1C,MAAM,EAAE,MAAM,GAAG,UAAU,YAAY;EAEvC,MAAM,UAAU,IAAI,QAAQ,CAC1B,CAAC,gBAAgB,mBAAmB,CACrC,CAAC;EAIF,MAAM,OAAO,KAAK,EAAE,SAFJ,IAAI,QAAQ,OAAO,MAAM,IAAI,QAAQ,MAAM,MAAM,IAAI,QAAQ,SAAS,IAAI,QAAQ,OAErE,EAAE,MAAM;EAErC,MAAM,aAAa,IAAI,IAAI,iBAAiB,IAAI,SAAS,GAAG,IAAI,YAAY,sBAAsB;AAElG,MAAI,KACF,YAAW,aAAa,IAAI,QAAQ,OAAO;AAS7C,SAAO;GACL,SAPc,IAAI,QAAQ,YAAY;IACtC,QAAQ;IACR;IACA,MAAM,KAAK,UAAU,KAAK;IAC3B,CAAC;GAIA,cAAc,QAAQ;GACvB;;CAEJ,CAAC;;;ACxDF,MAAM,kBAAkB;AACxB,MAAM,gBAAgB;AAEtB,eAAe,YAAY,WAAmB,QAAiC;CAC7E,MAAM,MAAM,GAAG,UAAU,IAAI;CAC7B,MAAM,UAAU,IAAI,aAAa;CACjC,MAAM,YAAY,MAAM,WAAW,OAAO,OAAO,UAC/C,OACA,QAAQ,OAAO,IAAI,EACnB;EAAE,MAAM;EAAQ,MAAM;EAAW,EACjC,OACA,CAAC,OAAO,CACT;CACD,MAAM,YAAY,MAAM,WAAW,OAAO,OAAO,KAAK,QAAQ,WAAW,IAAI,WAAW,EAAE,CAAC;AAC3F,QAAO,KAAK,OAAO,aAAa,GAAG,IAAI,WAAW,UAAU,CAAC,CAAC;;AAGhE,MAAa,OAAO,eAAe,SAAS;CAC1C,WAAW;CACX,gBAAgB,EAAE;CAClB,MAAM,QAAQ,KAAK,SAAS;EAC1B,MAAM,EAAE,QAAQ;AAEhB,SAAO,IAAI,aAAa,WAAW,mBAAmB;AACtD,SAAO,IAAI,UAAU,4BAA4B;EAEjD,MAAM,QAAQ,IAAI;EAClB,MAAM,SAAS,IAAI,YAAY,KAAA;EAC/B,MAAM,SAAS,IAAI,aAAa,IAAI,SAAS;EAE7C,MAAM,UAAU,QAAQ,YAClB,WAAW,WAAW,kBAAkB;EAE9C,MAAM,aAAa,IAAI,IAAI,0BAA0B,SAAS,QAAQ;EAEtE,IAAI;AAEJ,MAAI,IAAI,QAAQ,KACd,QAAO;GACL,UAAU;GACV,MAAM;IACJ,QAAQ,EACN,OAAO;KAAE,KAAK;KAAc,SAAS,IAAI,QAAQ;KAAO,EACzD;IACD,UAAU,CACR;KAAE,KAAK;KAAY,SAAS,IAAI,QAAQ;KAAM,CAC/C;IACF;GACF;MAGD,QAAO;GACL,UAAU;GACV,SAAS,EAAE,MAAM,IAAI,QAAQ,OAAO;GACrC;AAGH,MAAI,QAAQ;GACV,MAAM,YAAY,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK,CAAC,UAAU;GAC1D,MAAM,OAAO,MAAM,YAAY,WAAW,OAAO;AACjD,QAAK,YAAY;AACjB,QAAK,OAAO;;EAGd,MAAM,UAAU,IAAI,QAAQ,CAC1B,CAAC,gBAAgB,mBAAmB,CACrC,CAAC;AAQF,SAAO;GACL,SAPc,IAAI,QAAQ,YAAY;IACtC,QAAQ;IACR;IACA,MAAM,KAAK,UAAU,KAAK;IAC3B,CAAC;GAIA,cAAc,QAAQ;GACvB;;CAEJ,CAAC;;;AC3DF,MAAa,QAAQ,eAAe,UAAU;CAC5C,WAAW;CACX,gBAAgB;EACd,aAAa;EACb,eAAe;EAChB;CACD,MAAM,QAAQ,GAAG,SAAS;EACxB,MAAM,EAAE,QAAQ;AAGhB,SAAO,IAAI,aAAa,SAAS,IAAI,aAAa,WAAW,sBAAsB,IAAI,UAAU,GAAG;EAEpG,MAAM,OAAO,IAAI;AAEjB,MAAI,SAAS,OAAO;AAClB,UAAO,IAAI,UAAU,yBAAyB;AAC9C,UAAO,IAAI,UAAU,wBAAwB;QAI7C,QADkB,IAAI,SAAS,MAAM,IAAI,CAAC,OAAO,QAAQ,CACxC,WAAW,GAAG,yBAAyB;EAG1D,IAAI;EACJ,MAAM,UAAU,IAAI,QAAQ,CAC1B,CAAC,gBAAgB,mBAAmB,CACrC,CAAC;EACF,MAAM,OAA4B,EAAE;AAGpC,MAAI,KAAK,QAAQ,MAAM;AAErB,QAAK,SAAS,CACZ;IACE,MAAM;IACN,MAAM;KACJ,MAAM;KACN,MAAM,KAAK,QAAQ;KACpB;IACF,EACD;IACE,MAAM;IACN,MAAM;KACJ,MAAM;KACN,MAAM,KAAK,QAAQ;KACpB;IACF,CACF;AAED,QAAK,OAAO,KAAK,QAAQ;QAIzB,MAAK,OAAO,KAAK,QAAQ;AAG3B,MAAI,SAAS,OAAO;GAClB,MAAM,EAAE,UAAU,SAAS,UAAU,OAAO,iBAAiB;AAC7D,gBAAa,IAAI,IAAI,yBAAyB,QAAQ,cAAc;AACpE,gBAAa,SAAS,OAAO,QAAQ;AACnC,eAAW,aAAa,IAAI,KAAK,MAAM;KACvC;AAEF,WAAQ,IAAI,iBAAiB,UAAU,QAAQ;AAE/C,QAAK,UAAU;SAEZ;GACH,MAAM,EAAE,iBAAiB;AACzB,gBAAa,IAAI,IAAI,aAAa,oBAAoB,IAAI,SAAS,IAAI,QAAQ,YAAY;AAC3F,gBAAa,SAAS,OAAO,QAAQ;AACnC,eAAW,aAAa,IAAI,KAAK,MAAM;KACvC;;AASJ,SAAO;GACL,SAPc,IAAI,QAAQ,YAAY;IACtC,QAAQ;IACR;IACA,MAAM,KAAK,UAAU,QAAQ,QAAQ,KAAK;IAC3C,CAAC;GAIA,cAAc,QAAQ;GACvB;;CAEJ,CAAC;;;AC7GF,MAAa,sBAAsB,EAAE,OAAO,EAC1C,YAAY,EAAE,KAAK;CAAC;CAAY;CAAc;CAAO,CAAC,CAAC,UAAU,EAClE,CAAC;AAaF,MAAa,WAAW,eAAe,aAAa;CAClD,WAAW;CACX,gBAAgB,EACd,YAAY,4BACb;CACD,MAAM,QAAQ,GAAG,SAAS;EACxB,MAAM,EAAE,QAAQ;AAGhB,SAAO,IAAI,aAAa,OAAO,yBAAyB,IAAI,UAAU,GAAG;AACzE,SAAO,IAAI,UAAU,wBAAwB;EAG7C,MAAM,eAAe,IAAI,SAAS,MAAM,IAAI,CAAC,OAAO,QAAQ;AAC5D,SAAO,aAAa,SAAS,GAAG,mCAAmC;EAEnE,MAAM,cAAc,iBAAiB,KAAK,oBAAoB,UAAU;AAExE,MAAI,CAAC,YAAY,QACf,OAAM,IAAI,MAAM,yBAAyB;EAG3C,MAAM,QAAQ,YAAY;EAG1B,MAAM,WAAW,GAAG,IAAI,SAAS,GAAG,IAAI;EAIxC,MAAM,WAAW,mBAAmB,aAAa,GAAG;EACpD,MAAM,CAAC,QAAQ,mBAAmB,SAAS,SAAS,IAAI,GACpD,SAAS,MAAM,KAAK,EAAE,GACtB,CAAC,UAAU,KAAA,EAAU;EAGzB,MAAM,aAAa,IAAI,IAAI,OAAO,SAAS,eAAe,QAAQ,WAAW;EAE7E,MAAM,UAAU,IAAI,QAAQ,CAC1B,CAAC,gBAAgB,mBAAmB,CACrC,CAAC;EAGF,IAAI;AACJ,MAAI,KAAK,QAAQ,MAAM;GAErB,MAAM,YAAY,MAAM;GACxB,IAAI;GACJ,IAAI;AAEJ,OAAI,cAAc,QAAQ;AAExB,qBAAiB,MAAM,WAAW,KAAK,QAAQ,MAAM,CAAC;AACtD,oBAAgB,WAAW,KAAK,QAAQ,KAAK;cAEtC,cAAc,cAAc;AAGnC,qBAAiB,IADI,eAAe,KAAK,QAAQ,MAAM,CACrB;AAClC,oBAAgB,eAAe,KAAK,QAAQ,KAAK;UAE9C;AAEH,qBAAiB,IAAI,KAAK,QAAQ,MAAM;AACxC,oBAAgB,KAAK,QAAQ;;AAG/B,UAAO,GAAG,eAAe,MAAM;aAK3B,MAAM,eAAe,aACvB,QAAO,eAAe,KAAK,QAAQ,MAAM;WAElC,MAAM,eAAe,OAC5B,QAAO,WAAW,KAAK,QAAQ,MAAM;MAGrC,QAAO,KAAK,QAAQ;EAIxB,MAAM,OAA4B;GAChC,SAAS;GACT;GACA,YAAY,MAAM;GACnB;AAGD,MAAI,gBACF,MAAK,oBAAoB,OAAO,SAAS,iBAAiB,GAAG;AAS/D,SAAO;GACL,SAPc,IAAI,QAAQ,YAAY;IACtC,QAAQ;IACR;IACA,MAAM,KAAK,UAAU,KAAK;IAC3B,CAAC;GAIA,cAAc,QAAQ;GACvB;;CAEJ,CAAC;;;ACjHF,SAAgB,oBACd,WACgB;CAChB,MAAM,oCAAoB,IAAI,KAAgD;AAC9E,WAAU,SAAS,aAAa;AAC9B,oBAAkB,IAAI,SAAS,UAAU,SAAS;GAClD;CAEF,SAAS,gBACP,KAC+C;EAC/C,MAAM,OAAO,OAAO,QAAQ,WAAW,IAAI,IAAI,IAAI,GAAG;AAEtD,SAAO,kBAAkB,IAAI,KAAK,SAAS;;CAG7C,SAAS,aAAa,MAA2B;EAC/C,MAAM,aAAa,KAAK,KAAK,QAAQ;GACnC,MAAM,WAAW,gBAAgB,IAAI;AACrC,OAAI,CAAC,SACH;AAEF,UAAO;IAAE;IAAU;IAAK;IACxB,CAAC,QAAQ,MAA4E,CAAC,CAAC,EAAE;AAE3F,SAAO,EACL,MAAM,KAAK,OAAe,MAAe;AACvC,QAAK,MAAM,YAAY,YAAY;IAEjC,MAAM,aAAa;KAAE;KAAO;KAAM;AAClC,UAAM,SAAS,SAAS,KACtB,SAAS,IAAI,UAAU,EACvB,WACD;;KAGN;;AAGH,QAAO,OAAO,OAAO,cAAc,EAAE,iBAAiB,CAAC;;;;ACzCzD,MAAM,cAAc,EAAE,OAAO;CAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;CAC/B,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,KAAK,EAAE,QAAQ,CAAC,UAAU;CAC1B,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU;CAC9B,YAAY,EAAE,QAAQ,CAAC,UAAU;CACjC,OAAO,EAAE,KAAK;EAAC;EAAU;EAAiB;EAAW;EAAW,CAAC,CAAC,UAAU;CAC5E,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,OAAO,EAAE,OAAO,QAAQ,CAAC,UAAU;CACnC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU;CAClC,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,UAAU;CACnC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU;CACpC,CAAC;AAEF,MAAa,OAAO,eAAe,SAAS;CAC1C,WAAW;CACX,gBAAgB,EAAE;CAClB,MAAM,QAAQ,KAAK,SAAS;EAC1B,MAAM,EAAE,SAAS,QAAQ;AAEzB,SAAO,IAAI,UAAU,kCAAkC;AACvD,SAAO,IAAI,UAAU,yBAAyB;EAE9C,MAAM,aAAa,IAAI,SAAS,MAAM,IAAI,CAAC,OAAO,QAAQ;AAC1D,SAAO,WAAW,SAAS,GAAG,sCAAsC;EAEpE,MAAM,cAAc,iBAAiB,KAAK,YAAY,UAAU;AAEhE,MAAI,CAAC,YAAY,QACf,OAAM,IAAI,MAAM,gCAAgC;EAGlD,MAAM,QAAQ,YAAY;EAE1B,MAAM,aAAa,IAAI,IAAI,SAAS,aAAa,gBAAgB,IAAI,UAAU,CAAC,EAAE,SAAS,CAAC;EAE5F,MAAM,UAAU,IAAI,QAAQ,CAC1B,CAAC,gBAAgB,mBAAmB,CACrC,CAAC;EAEF,MAAM,cAAoD,QAAQ,OAAO;GAAE,OAAO,QAAQ;GAAO,UAAU,QAAQ;GAAM,GAAG,EAAE,UAAU,QAAQ,OAAO;EAEvJ,MAAM,OAAO,KAAK,EAAE,aAAa,YAAY,EAAE,aAAa,MAAM;AAQlE,SAAO;GACL,SAPc,IAAI,QAAQ,YAAY;IACtC,QAAQ;IACR;IACA,MAAM,KAAK,UAAU,KAAK;IAC3B,CAAC;GAIA,cAAc,QAAQ;GACvB;;CAEJ,CAAC;;;AC/DF,eAAe,mBAAgD,MAA6B,iBAAyB,SAAuB;CAC1I,MAAM,MAAM,IAAI,IAAI,KAAK,IAAI;CAE7B,MAAM,WAAW;CAEjB,MAAM,UAAU,IAAI,QAAQ,CAC1B,CAAC,gBAAgB,mBAAmB,CACrC,CAAC;CAEF,MAAM,OAA+B,EACnC,OAAO,KAAK,QAAQ,OACrB;AAED,KAAI,KAAK,QAAQ,KACf,MAAK,OAAO,KAAK,QAAQ;AAG3B,OAAM,KAAK,IAAI,aAAa,SAAS,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW;AAC/D,MAAI,IAAI,WAAW,IAAI,EAAE;AACvB,OAAI,aAAa,OAAO,IAAI;GAC5B,MAAM,YAAY,IAAI,MAAM,EAAE;AAC9B,OAAI,QAAQ,IAAI,UAAU,CACxB,SAAQ,IAAI,WAAW,MAAM;OAG7B,SAAQ,OAAO,WAAW,MAAM;aAG3B,IAAI,WAAW,IAAI,EAAE;AAC5B,OAAI,aAAa,OAAO,IAAI;GAC5B,MAAM,cAAc,IAAI,MAAM,EAAE;AAChC,QAAK,eAAe;;GAEtB;CAEF,MAAM,aAAa,aAAa,IAAI,UAAU,EAAE,SAAS;AAQzD,QAAO;EACL,SAPc,IAAI,QAAQ,YAAY;GACtC,QAAQ;GACR,MAAM,KAAK,UAAU,KAAK;GAC1B;GACD,CAAC;EAIA,cAAc;EACf;;AAIH,MAAa,OAAO,eAAe,SAAS;CAC1C,WAAW;CACX,gBAAgB,EAAE;CAClB,QAAQ,KAAK,SAAS;AACpB,SAAO,mBAAmB,KAAK,MAAM,KAAK,SAAS,QAAQ;;CAE9D,CAAC;AAGF,MAAa,QAAQ,eAAe,UAAU;CAC5C,WAAW;CACX,gBAAgB,EAAE;CAClB,QAAQ,KAAK,SAAS;AACpB,SAAO,mBAAmB,KAAK,MAAM,KAAK,UAAU,QAAQ;;CAE/D,CAAC;;;AC/DF,MAAa,aAAa,eAAe,gBAAgB;CACvD,WAAW;CACX,gBAAgB,EAAE;CAClB,MAAM,QAAQ,GAAG,SAAS;EACxB,MAAM,EAAE,QAAQ;AAGhB,SACE,IAAI,aAAa,QAAQ,IAAI,aAAa,SAC1C,mEAAmE,IAAI,SAAS,GACjF;EAED,MAAM,UAAU,IAAI;EAEpB,IAAI;EACJ,MAAM,UAAU,IAAI,QAAQ,CAC1B,CAAC,gBAAgB,mBAAmB,CACrC,CAAC;EACF,MAAM,OAA4B,EAChC,OAAO,KAAK,QAAQ,OACrB;AAED,MAAI,KAAK,QAAQ,KACf,MAAK,OAAO,KAAK,QAAQ;AAG3B,MAAI,YAAY,MAAM;GAEpB,MAAM,EAAE,UAAU,KAAK,UAAU,SAAS,iBAAiB;AAE3D,UAAO,KAAK,oCAAoC;AAChD,UAAO,SAAS,wCAAwC;AAExD,gBAAa,IAAI,IAAI,WAAW,IAAI,sBAAsB,QAAQ,OAAO;GAGzE,MAAM,OAAiB,EAAE;AACzB,gBAAa,SAAS,OAAO,QAAQ;AACnC,QAAI,QAAQ,OACV,MAAK,KAAK,MAAM;aAET,QAAQ,QACf,MAAK,QAAQ;KAEf;AAEF,OAAI,KAAK,SAAS,EAChB,MAAK,OAAO,KAAK,KAAK,IAAI;SAGzB;GAGH,MAAM,EAAE,UAAU,SAAS,iBAAiB;AAE5C,UAAO,SAAS,4CAA4C;AAE5D,gBAAa,IAAI,IAAI,2BAA2B,QAAQ,OAAO;AAG/D,gBAAa,SAAS,OAAO,QAAQ;AACnC,QAAI,QAAQ,QACV,MAAK,QAAQ;aAEN,QAAQ,OACf,MAAK,OAAO,UAAU,OAAO,UAAU,SAAS,IAAI;aAE7C,QAAQ,UACf,MAAK,UAAU;aAER,QAAQ,SACf,MAAK,SAAS;KAEhB;;AASJ,SAAO;GACL,SAPc,IAAI,QAAQ,YAAY;IACtC,QAAQ;IACR;IACA,MAAM,KAAK,UAAU,KAAK;IAC3B,CAAC;GAIA,cAAc,QAAQ;GACvB;;CAEJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "statocysts",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.11.0",
|
|
5
5
|
"description": "Notification library for JavaScript",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://github.com/octoplorer/statocysts",
|
|
@@ -53,11 +53,12 @@
|
|
|
53
53
|
"zod": "^4.3.6"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@types/node": "^25.
|
|
56
|
+
"@types/node": "^25.3.5",
|
|
57
57
|
"@types/smtp-server": "^3.5.12",
|
|
58
58
|
"@vitest/coverage-v8": "^4.0.18",
|
|
59
|
+
"publint": "^0.3.18",
|
|
59
60
|
"smtp-server": "^3.18.1",
|
|
60
|
-
"tsdown": "^0.
|
|
61
|
+
"tsdown": "^0.21.0",
|
|
61
62
|
"typescript": "^5.9.3",
|
|
62
63
|
"vitest": "^4.0.18"
|
|
63
64
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-Tf7eZY-O.d.ts","names":[],"sources":["../src/core/transport.ts","../src/core/provider.ts","../src/core/sender.ts","../src/core/transports/http.ts","../src/services/chat/discord/index.ts","../src/services/chat/slack/index.ts","../src/services/chat/telegram/index.ts","../src/services/push/bark/index.ts","../src/services/specialized/json/index.ts"],"mappings":";;;;;;;;;UAIiB,SAAA;EAAA;;;;EAKf,IAAA,GAAO,OAAA,EAAS,OAAA,KAAY,OAAA;AAAA;AAAA,iBAGd,eAAA,SAAA,CACd,SAAA,EAAW,SAAA,CAAU,OAAA,IACpB,SAAA,CAAU,OAAA;;;KCTR,qBAAA,MAA2B,CAAA,SAAU,SAAA,YAAqB,CAAA;AAAA,UAE9C,eAAA;EAAA,SAKN,UAAA,EAAY,SAAA,CAAU,OAAA;EAAA,SACtB,QAAA,EAAU,QAAA;EACnB,cAAA,EAAgB,OAAA;EAChB,IAAA,GAAO,GAAA,UAAa,OAAA;IAAW,KAAA;IAAe,IAAA;EAAA,GAAiB,OAAA,GAAU,OAAA,KAAY,OAAA;AAAA;AAAA,UAGtE,qBAAA;EACf,GAAA,EAAK,GAAA;EACL,OAAA;IAAW,KAAA;IAAe,IAAA;EAAA;AAAA;AAAA,UAGX,qBAAA,WAAgC,SAAA;EAC/C,cAAA,GAAiB,OAAA;EACjB,SAAA,EAAW,CAAA;EACX,OAAA,GACE,IAAA,EAAM,qBAAA,EACN,GAAA,EAAK,qBAAA,EACL,OAAA,EAAS,OAAA,KACN,OAAA,CAAQ,qBAAA,CAAsB,CAAA;AAAA;AAAA,iBAGrB,cAAA,0CAAwD,SAAA,sBAAA,CACtE,QAAA,EAAU,QAAA,EACV,aAAA,EAAe,qBAAA,CAAsB,CAAA,EAAG,OAAA,IACvC,eAAA,CAAgB,QAAA,EAAU,qBAAA,CAAsB,CAAA,GAAI,OAAA;;;UClCtC,MAAA;EACf,IAAA,GAAO,KAAA,UAAe,IAAA,cAAkB,OAAA;AAAA;AAAA,KAG9B,SAAA,YAAqB,GAAA;AAAA,UAEhB,cAAA;EAAA,CACd,IAAA,EAAM,SAAA,KAAc,MAAA;EACrB,eAAA,GAAkB,GAAA,WAAc,GAAA,KAAQ,eAAA;AAAA;AAAA,iBAG1B,mBAAA,CACd,SAAA,EAAW,eAAA,uBACV,cAAA;;;;;;UCRc,WAAA;EACf,OAAA,EAAS,OAAA;EACT,YAAA,GAAe,YAAA;AAAA;;;;;cAOJ,IAAA,EAAI,SAAA,CAAA,WAAA;;;UCTP,cAAA;EACR,YAAA,GAAe,YAAA;AAAA;AAAA,cAeJ,OAAA,EAAO,eAAA,aA2ClB,WAAA,EA3CkB,cAAA;;;UCjBH,YAAA;;;;ALFjB;;EKQE,WAAA;ELHmC;;;;;EKSnC,aAAA;ELTmC;;AAGrC;;;EKaE,IAAA,GAAO,MAAA;EAEP,YAAA,GAAe,YAAA;AAAA;AAAA,cAGJ,KAAA,EAAK,eAAA,WAsFhB,WAAA,EAtFgB,YAAA;;;UCnBD,eAAA;ENFf;;;;;EMQA,UAAA;EAEA,YAAA,GAAe,YAAA;AAAA;AAAA,cAGJ,QAAA,EAAQ,eAAA,cAgGnB,WAAA,EAhGmB,eAAA;;;UCfJ,WAAA;EACf,YAAA,GAAe,YAAA;AAAA;AAAA,cAoBJ,IAAA,EAAI,eAAA,UAyCf,WAAA,EAzCe,WAAA;;;cC4BJ,IAAA,EAAI,eAAA,UAMf,WAAA,EANe,YAAA,CAAA,OAAA,CAAA,YAAA;AAAA,cASJ,KAAA,EAAK,eAAA,WAMhB,WAAA,EANgB,YAAA,CAAA,OAAA,CAAA,YAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server-chan-UPO915jk.js","names":["querySchema"],"sources":["../src/utils/assert.ts","../src/utils/markdown.ts","../src/utils/url.ts","../src/core/provider.ts","../src/core/transport.ts","../src/core/transports/http.ts","../src/services/chat/discord/index.ts","../src/services/chat/slack/index.ts","../src/services/chat/telegram/index.ts","../src/core/sender.ts","../src/services/push/bark/index.ts","../src/services/specialized/json/index.ts","../src/services/push/server-chan/index.ts"],"sourcesContent":["export function assert(condition: any, message: string | Error): asserts condition {\n if (!condition) {\n throw typeof message === 'string' ? new Error(message) : message\n }\n}\n","/**\n * Escape special characters: _*[]()~`>#+-=|{}.!\n */\nexport function escapeMarkdown(text: string): string {\n return text.replace(/([_*[\\]()~`>#+\\-=|{}.!])/g, '\\\\$1')\n}\n","import { getQuery } from 'ufo'\n\nexport function getValidateQuery<T>(\n url: URL | string,\n parser: (params: unknown) => T,\n): T {\n const query = getQuery(url.toString())\n return parser(query)\n}\n\nexport function withoutPathname(input: string): string {\n const _url = new URL(input)\n _url.pathname = ''\n return _url.toString()\n}\n","import type { Transport } from './transport'\nimport { assert } from '#/utils'\nimport defu from 'defu'\n\n// Utility type to infer Payload from Transport\ntype InferTransportPayload<T> = T extends Transport<infer P> ? P : never\n\nexport interface ServiceProvider<\n Protocol extends string,\n Payload,\n Options = void,\n> {\n readonly $transport: Transport<Payload>\n readonly protocol: Protocol\n defaultOptions: Options | undefined\n send: (url: string, message: { title: string, body?: string }, options?: Options) => Promise<void>\n}\n\nexport interface DefineProviderContext {\n url: URL\n message: { title: string, body?: string }\n}\n\nexport interface DefineProviderOptions<T extends Transport, Options> {\n defaultOptions?: Options\n transport: T\n prepare: (\n this: DefineProviderContext,\n ctx: DefineProviderContext,\n options: Options,\n ) => Promise<InferTransportPayload<T>>\n}\n\nexport function defineProvider<const Protocol extends string, T extends Transport<any>, Options = void>(\n protocol: Protocol,\n createOptions: DefineProviderOptions<T, Options>,\n): ServiceProvider<Protocol, InferTransportPayload<T>, Options> {\n const send: ServiceProvider<Protocol, InferTransportPayload<T>, Options>['send'] = async (\n protocolUrl,\n message,\n options,\n ): Promise<void> => {\n const url = new URL(protocolUrl)\n\n assert(url.protocol === protocol, `Unexpected protocol \"${url.protocol}\"`)\n\n const ctx: DefineProviderContext = {\n url,\n message,\n }\n\n const opts = defu(options ?? {}, createOptions.defaultOptions ?? {}) as Options\n\n const payload = await createOptions.prepare.call(ctx, ctx, opts)\n\n await createOptions.transport.send(payload)\n }\n return {\n get protocol() {\n return protocol\n },\n get defaultOptions() {\n return createOptions.defaultOptions\n },\n get $transport() {\n return createOptions.transport\n },\n send,\n }\n}\n","/**\n * Transport interface for protocol-specific network communication\n * Each transport handles the actual sending of data over a specific protocol\n */\nexport interface Transport<Payload = unknown> {\n /**\n * Send data using the transport's protocol\n * @param payload Protocol-specific payload to send\n */\n send: (payload: Payload) => Promise<void>\n}\n\nexport function defineTransport<Payload>(\n transport: Transport<Payload>,\n): Transport<Payload> {\n return transport\n}\n","import type { FetchOptions } from 'ofetch'\nimport { ofetch } from 'ofetch'\nimport { defineTransport } from '../transport'\n\n/**\n * HTTP payload for HTTP transport\n */\nexport interface HttpPayload {\n request: Request\n fetchOptions?: FetchOptions\n}\n\n/**\n * HTTP transport implementation\n * Handles sending data over HTTP/HTTPS protocols\n */\nexport const http = defineTransport({\n async send(payload: HttpPayload) {\n await ofetch(payload.request, payload.fetchOptions)\n },\n})\n","import type { FetchOptions } from 'ofetch'\nimport { defineProvider } from '#/core/provider'\nimport { http } from '#/core/transports/http'\nimport { assert, getValidateQuery } from '#/utils'\nimport defu from 'defu'\nimport z from 'zod'\n\ninterface DiscordOptions {\n fetchOptions?: FetchOptions\n}\n\nconst querySchema = z.object({\n avatar_url: z.string().optional(),\n username: z.string().optional(),\n\n wait: z.string().transform((val) => {\n if (val === 'false' || val === '0' || val === '') {\n return false\n }\n return true\n }).optional(),\n})\n\nexport const discord = defineProvider('discord:', {\n transport: http,\n defaultOptions: {} as DiscordOptions,\n async prepare(ctx, options) {\n const { url } = ctx\n\n assert(url.hostname === 'webhook', 'Invalid discord URL')\n assert(url.username, 'Webhook ID is required')\n assert(url.password, 'Webhook token is required')\n\n const queryResult = getValidateQuery(url, querySchema.safeParse)\n\n if (!queryResult.success) {\n throw new Error('Invalid discord query')\n }\n\n const { wait, ...query } = queryResult.data\n\n const headers = new Headers([\n ['Content-Type', 'application/json'],\n ])\n\n const content = ctx.message.body ? `## ${ctx.message.title}\\n\\n${ctx.message.body}` : ctx.message.title\n\n const body = defu({ content }, query)\n\n const requestUrl = new URL(`/api/webhooks/${url.username}/${url.password}`, 'https://discord.com')\n\n if (wait) {\n requestUrl.searchParams.set('wait', 'true')\n }\n\n const request = new Request(requestUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n })\n\n return {\n request,\n fetchOptions: options.fetchOptions,\n }\n },\n})\n","import type { FetchOptions } from 'ofetch'\nimport { defineProvider } from '#/core/provider'\nimport { http } from '#/core/transports/http'\nimport { assert } from '#/utils'\nimport { withoutLeadingSlash } from 'ufo'\n\nexport interface SlackOptions {\n /**\n * The base URL for webhook services\n *\n * @default `https://hooks.slack.com/services`\n */\n hookBaseUrl?: string\n /**\n * The base URL for bot API services\n *\n * @default `https://slack.com/api`\n */\n botApiBaseUrl?: string\n\n /**\n * The body of the request\n *\n * NOTICE*: This will override the body of the request. You should known what you are doing.\n */\n body?: Record<string, any>\n\n fetchOptions?: FetchOptions\n}\n\nexport const slack = defineProvider('slack:', {\n transport: http,\n defaultOptions: {\n hookBaseUrl: 'https://hooks.slack.com/',\n botApiBaseUrl: 'https://slack.com/',\n } as SlackOptions,\n async prepare(_, options) {\n const { url } = this\n\n // Validate URL format\n assert(url.hostname === 'bot' || url.hostname === 'webhook', `Invalid slack URL: ${url.toString()}`)\n\n const type = url.hostname as 'bot' | 'webhook'\n\n if (type === 'bot') {\n assert(url.username, 'Channel ID is required')\n assert(url.password, 'Bot token is required')\n }\n else {\n const pathParts = url.pathname.split('/').filter(Boolean)\n assert(pathParts.length === 3, 'Webhook URL is invalid')\n }\n\n let requestUrl: URL\n const headers = new Headers([\n ['Content-Type', 'application/json'],\n ])\n const body: Record<string, any> = {}\n\n // Build message content based on title and body\n if (this.message.body) {\n // When body is present, use blocks for rich markdown formatting\n body.blocks = [\n {\n type: 'header',\n text: {\n type: 'plain_text',\n text: this.message.title,\n },\n },\n {\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: this.message.body,\n },\n },\n ]\n // Fallback text for notifications\n body.text = this.message.title\n }\n else {\n // When only title is present, use simple text format\n body.text = this.message.title\n }\n\n if (type === 'bot') {\n const { username: channel, password: token, searchParams } = url\n requestUrl = new URL('/api/chat.postMessage', options.botApiBaseUrl)\n searchParams.forEach((value, key) => {\n requestUrl.searchParams.set(key, value)\n })\n\n headers.set('Authorization', `Bearer ${token}`)\n\n body.channel = channel\n }\n else {\n const { searchParams } = url\n requestUrl = new URL(`/services/${withoutLeadingSlash(url.pathname)}`, options.hookBaseUrl)\n searchParams.forEach((value, key) => {\n requestUrl.searchParams.set(key, value)\n })\n }\n\n const request = new Request(requestUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(options.body ?? body),\n })\n\n return {\n request,\n fetchOptions: options.fetchOptions,\n }\n },\n})\n","import type { FetchOptions } from 'ofetch'\nimport { defineProvider } from '#/core/provider'\nimport { http } from '#/core/transports/http'\nimport { escapeMarkdown, getValidateQuery } from '#/utils'\nimport { assert } from '#/utils/assert'\nimport z from 'zod'\n\nexport const telegramQuerySchema = z.object({\n parse_mode: z.enum(['Markdown', 'MarkdownV2', 'HTML']).optional(),\n})\n\nexport interface TelegramOptions {\n /**\n * The base URL for Telegram Bot API\n *\n * @default `https://api.telegram.org`\n */\n apiBaseUrl?: string\n\n fetchOptions?: FetchOptions\n}\n\nexport const telegram = defineProvider('telegram:', {\n transport: http,\n defaultOptions: {\n apiBaseUrl: 'https://api.telegram.org',\n } as TelegramOptions,\n async prepare(_, options) {\n const { url } = this\n\n // Validate URL format\n assert(url.hostname === 'bot', `Invalid telegram URL: ${url.toString()}`)\n assert(url.username, 'Bot token is required')\n\n // Extract chat IDs from pathname (e.g., /chat-1/chat-2)\n const pathSegments = url.pathname.split('/').filter(Boolean)\n assert(pathSegments.length > 0, 'At least one chat ID is required')\n\n const queryResult = getValidateQuery(url, telegramQuerySchema.safeParse)\n\n if (!queryResult.success) {\n throw new Error('Invalid telegram query')\n }\n\n const query = queryResult.data\n\n // Bot token is in the username and password fields, because token contains `:` character\n const botToken = `${url.username}:${url.password}`\n\n // First chat ID from pathname (decode to handle @ symbols like @mychannel)\n // Support format: chat-id or chat-id:message-thread-id\n const chatPart = decodeURIComponent(pathSegments[0])\n const [chatId, messageThreadId] = chatPart.includes(':')\n ? chatPart.split(':', 2)\n : [chatPart, undefined]\n\n // Build API URL\n const requestUrl = new URL(`/bot${botToken}/sendMessage`, options.apiBaseUrl)\n\n const headers = new Headers([\n ['Content-Type', 'application/json'],\n ])\n\n // Build message text based on parse_mode\n let text: string\n if (this.message.body) {\n // Title as h1, body as content\n const parseMode = query.parse_mode\n let titleFormatted: string\n\n if (parseMode === 'HTML') {\n titleFormatted = `<b>${this.message.title}</b>`\n }\n else if (parseMode === 'MarkdownV2') {\n // MarkdownV2 requires escaping special characters\n const escapedTitle = escapeMarkdown(this.message.title)\n titleFormatted = `*${escapedTitle}*`\n }\n else {\n // Markdown or default\n titleFormatted = `*${this.message.title}*`\n }\n\n text = `${titleFormatted}\\n\\n${this.message.body}`\n }\n else {\n // No body, title is the main content\n // Need to escape special characters in MarkdownV2 mode\n if (query.parse_mode === 'MarkdownV2') {\n text = escapeMarkdown(this.message.title)\n }\n else {\n text = this.message.title\n }\n }\n\n const body: Record<string, any> = {\n chat_id: chatId,\n text,\n parse_mode: query.parse_mode,\n }\n\n // Add message_thread_id if specified (for topic/forum groups)\n if (messageThreadId) {\n body.message_thread_id = Number.parseInt(messageThreadId, 10)\n }\n\n const request = new Request(requestUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n })\n\n return {\n request,\n fetchOptions: options.fetchOptions,\n }\n },\n})\n","import type { ServiceProvider } from '#/core/provider'\n\nexport interface Sender {\n send: (title: string, body?: string) => Promise<void>\n}\n\nexport type SenderUrl = string | URL\n\nexport interface SenderRegistry {\n (urls: SenderUrl[]): Sender\n resolveProvider: (url: string | URL) => ServiceProvider<string, any, any> | undefined\n}\n\nexport function buildSenderRegistry(\n providers: ServiceProvider<string, any, any>[],\n): SenderRegistry {\n const providersRegistry = new Map<string, ServiceProvider<string, any, any>>()\n providers.forEach((provider) => {\n providersRegistry.set(provider.protocol, provider)\n })\n\n function resolveProvider(\n url: string | URL,\n ): ServiceProvider<string, any, any> | undefined {\n const _url = typeof url === 'string' ? new URL(url) : url\n\n return providersRegistry.get(_url.protocol)\n }\n\n function createSender(urls: SenderUrl[]): Sender {\n const registries = urls.map((url) => {\n const provider = resolveProvider(url)\n if (!provider) {\n return undefined\n }\n return { provider, url }\n }).filter((p): p is { provider: ServiceProvider<string, any, any>, url: SenderUrl } => !!p)\n\n return {\n async send(title: string, body?: string) {\n for (const registry of registries) {\n // Convert message string to { title, body? } format\n const messageObj = { title, body }\n await registry.provider.send(\n registry.url.toString(),\n messageObj,\n )\n }\n },\n }\n }\n\n return Object.assign(createSender, { resolveProvider })\n}\n","import type { FetchOptions } from 'ofetch'\nimport { defineProvider, http } from '#/shared'\nimport { assert, getValidateQuery, withoutPathname } from '#/utils'\nimport defu from 'defu'\nimport { withProtocol } from 'ufo'\nimport z from 'zod'\n\nexport interface BarkOptions {\n fetchOptions?: FetchOptions\n}\n\nconst querySchema = z.object({\n subtitle: z.string().optional(),\n group: z.string().optional(),\n url: z.string().optional(),\n icon: z.string().optional(),\n sound: z.string().optional(),\n call: z.enum(['1']).optional(),\n ciphertext: z.string().optional(),\n level: z.enum(['active', 'timeSensitive', 'passive', 'critical']).optional(),\n volume: z.string().optional(),\n badge: z.coerce.number().optional(),\n autoCopy: z.enum(['1']).optional(),\n copy: z.string().optional(),\n action: z.enum(['none']).optional(),\n isArchive: z.enum(['1']).optional(),\n})\n\nexport const bark = defineProvider('bark:', {\n transport: http,\n defaultOptions: {} as BarkOptions,\n async prepare(ctx, options) {\n const { message, url } = ctx\n\n assert(url.hostname, 'Server URL hostname is required')\n assert(url.pathname, 'Device key is required')\n\n const deviceKeys = url.pathname.split('/').filter(Boolean)\n assert(deviceKeys.length > 0, 'At least one device key is required')\n\n const queryResult = getValidateQuery(url, querySchema.safeParse)\n\n if (!queryResult.success) {\n throw new Error('Invalid Bark query parameters')\n }\n\n const query = queryResult.data\n\n const requestUrl = new URL(`/push`, withProtocol(withoutPathname(url.toString()), 'https:'))\n\n const headers = new Headers([\n ['Content-Type', 'application/json'],\n ])\n\n const contentData: { body: string, title?: string } = message.body ? { title: message.title, body: message.body } : { body: message.title }\n\n const body = defu({ device_keys: deviceKeys }, contentData, query)\n\n const request = new Request(requestUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n })\n\n return {\n request,\n fetchOptions: options.fetchOptions,\n }\n },\n})\n","import type { DefineProviderContext } from '#/core/provider'\nimport type { FetchOptions } from 'ofetch'\nimport { defineProvider } from '#/core/provider'\nimport { http } from '#/core/transports/http'\nimport { withProtocol } from 'ufo'\n\nasync function prepareJsonRequest(this: DefineProviderContext, _ctx: DefineProviderContext, defaultProtocol: string, options: FetchOptions) {\n const url = new URL(this.url)\n\n const protocol = defaultProtocol\n\n const headers = new Headers([\n ['Content-Type', 'application/json'],\n ])\n\n const body: Record<string, string> = {\n title: this.message.title,\n }\n\n if (this.message.body) {\n body.body = this.message.body\n }\n\n Array.from(url.searchParams.entries()).forEach(([key, value]) => {\n if (key.startsWith(' ')) {\n url.searchParams.delete(key)\n const headerKey = key.slice(1)\n if (headers.has(headerKey)) {\n headers.set(headerKey, value)\n }\n else {\n headers.append(headerKey, value)\n }\n }\n else if (key.startsWith(':')) {\n url.searchParams.delete(key)\n const propertyKey = key.slice(1)\n body[propertyKey] = value\n }\n })\n\n const requestUrl = withProtocol(url.toString(), protocol)\n\n const request = new Request(requestUrl, {\n method: 'POST',\n body: JSON.stringify(body),\n headers,\n })\n\n return {\n request,\n fetchOptions: options,\n }\n}\n\n// Supports json:// protocol (default to HTTP)\nexport const json = defineProvider('json:', {\n transport: http,\n defaultOptions: {} as FetchOptions,\n prepare(ctx, options) {\n return prepareJsonRequest.call(this, ctx, 'http:', options)\n },\n})\n\n// Supports jsons:// protocol (explicit HTTPS)\nexport const jsons = defineProvider('jsons:', {\n transport: http,\n defaultOptions: {} as FetchOptions,\n prepare(ctx, options) {\n return prepareJsonRequest.call(this, ctx, 'https:', options)\n },\n})\n","import type { FetchOptions } from 'ofetch'\nimport { defineProvider, http } from '#/shared'\nimport { assert } from '#/utils'\n\nexport interface ServerChanOptions {\n fetchOptions?: FetchOptions\n}\n\nexport const serverChan = defineProvider('server-chan:', {\n transport: http,\n defaultOptions: {} as ServerChanOptions,\n async prepare(_, options) {\n const { url } = this\n\n // Validate URL hostname to determine version\n assert(\n url.hostname === 'v3' || url.hostname === 'turbo',\n `Invalid server-chan URL: hostname must be 'v3' or 'turbo', got '${url.hostname}'`,\n )\n\n const version = url.hostname as 'v3' | 'turbo'\n\n let requestUrl: URL\n const headers = new Headers([\n ['Content-Type', 'application/json'],\n ])\n const body: Record<string, any> = {\n title: this.message.title,\n }\n\n if (this.message.body) {\n body.desp = this.message.body\n }\n\n if (version === 'v3') {\n // Server Chan 3: server-chan://uid:sendKey@v3?tags=<tag1>&tags=<tag2>&short=<short>\n const { username: uid, password: sendKey, searchParams } = url\n\n assert(uid, 'UID is required for Server Chan 3')\n assert(sendKey, 'SendKey is required for Server Chan 3')\n\n requestUrl = new URL(`https://${uid}.push.ft07.com/send/${sendKey}.send`)\n\n // Add optional parameters from searchParams\n const tags: string[] = []\n searchParams.forEach((value, key) => {\n if (key === 'tags') {\n tags.push(value)\n }\n else if (key === 'short') {\n body.short = value\n }\n })\n\n if (tags.length > 0) {\n body.tags = tags.join('|')\n }\n }\n else {\n // Server Chan Turbo: server-chan://ftqq:SENDKEY@turbo?short=<short>&noip=<1|0|true|false>&channel=<channel>&openid=<openid>\n // Note: username (ftqq) is optional and not used in the API request\n const { password: sendKey, searchParams } = url\n\n assert(sendKey, 'SendKey is required for Server Chan Turbo')\n\n requestUrl = new URL(`https://sctapi.ftqq.com/${sendKey}.send`)\n\n // Add optional parameters from searchParams\n searchParams.forEach((value, key) => {\n if (key === 'short') {\n body.short = value\n }\n else if (key === 'noip') {\n body.noip = value === '1' || value === 'true' ? 1 : 0\n }\n else if (key === 'channel') {\n body.channel = value\n }\n else if (key === 'openid') {\n body.openid = value\n }\n })\n }\n\n const request = new Request(requestUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n })\n\n return {\n request,\n fetchOptions: options.fetchOptions,\n }\n },\n})\n"],"mappings":"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"}
|