@adriangalilea/utils 0.30.0 → 1.0.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.
@@ -0,0 +1,65 @@
1
+ import { createLogger } from "../universal/log.js";
2
+ const log = createLogger("bot/storage-d1");
3
+ export function d1Storage(opts) {
4
+ const table = opts.table ?? "session";
5
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(table)) {
6
+ throw new Error(`bot/storage-d1: invalid table name "${table}"`);
7
+ }
8
+ const db = opts.db;
9
+ // In-flight writes, awaited by flush(). Stored already error-swallowed so
10
+ // flush() never rejects; a failed write degrades to "looks like a new
11
+ // user", never a crash mid-update.
12
+ const pending = new Set();
13
+ const track = (promise) => {
14
+ const settled = promise.catch((error) => {
15
+ log.error("write failed:", error instanceof Error ? error.message : error);
16
+ return undefined;
17
+ });
18
+ pending.add(settled);
19
+ settled.finally(() => pending.delete(settled));
20
+ return settled;
21
+ };
22
+ return {
23
+ async get(key) {
24
+ try {
25
+ const row = await db
26
+ .prepare(`SELECT value FROM ${table} WHERE key = ?1`)
27
+ .bind(String(key))
28
+ .first();
29
+ if (!row)
30
+ return undefined;
31
+ return JSON.parse(row.value);
32
+ }
33
+ catch (error) {
34
+ log.error("read failed:", error instanceof Error ? error.message : error);
35
+ return undefined;
36
+ }
37
+ },
38
+ async has(key) {
39
+ try {
40
+ const row = await db
41
+ .prepare(`SELECT 1 AS one FROM ${table} WHERE key = ?1`)
42
+ .bind(String(key))
43
+ .first();
44
+ return row !== null;
45
+ }
46
+ catch {
47
+ return false;
48
+ }
49
+ },
50
+ async set(key, value) {
51
+ await track(db
52
+ .prepare(`INSERT INTO ${table} (key, value) VALUES (?1, ?2) ON CONFLICT (key) DO UPDATE SET value = ?2`)
53
+ .bind(String(key), JSON.stringify(value))
54
+ .run());
55
+ },
56
+ async delete(key) {
57
+ const res = await track(db.prepare(`DELETE FROM ${table} WHERE key = ?1`).bind(String(key)).run());
58
+ return (res?.meta.changes ?? 0) > 0;
59
+ },
60
+ async flush() {
61
+ await Promise.all([...pending]);
62
+ },
63
+ };
64
+ }
65
+ //# sourceMappingURL=storage-d1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-d1.js","sourceRoot":"","sources":["../../src/bot/storage-d1.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { type AlertThrottle } from "./notify.js";
2
+ /** The slice of a gramio `Bot` the worker cap drives — structural, so versions don't pin. */
3
+ export type WorkerBot = {
4
+ info?: {
5
+ username?: string;
6
+ };
7
+ updates: {
8
+ handleUpdate(update: unknown): Promise<unknown>;
9
+ };
10
+ api: {
11
+ setWebhook(params: {
12
+ url: string;
13
+ secret_token: string;
14
+ allowed_updates: string[];
15
+ }): Promise<unknown>;
16
+ deleteWebhook(): Promise<unknown>;
17
+ getWebhookInfo(): Promise<{
18
+ url?: string;
19
+ [k: string]: unknown;
20
+ }>;
21
+ /** For the lifecycle DMs (notifyAdmins rides the same bot). */
22
+ sendMessage(params: {
23
+ chat_id: number;
24
+ text: string;
25
+ }): Promise<unknown>;
26
+ };
27
+ };
28
+ type WaitUntilCtx = {
29
+ waitUntil(promise: Promise<unknown>): void;
30
+ };
31
+ export type BotWorkerRuntime = {
32
+ bot: WorkerBot;
33
+ /** Telegram webhook secret; unset → webhook/setup respond 500 (a misconfigured prod must scream). */
34
+ webhookSecret?: string;
35
+ /** Bearer for /pause, /resume, /webhook-status; unset → those 404 (surface disabled). */
36
+ operatorSecret?: string;
37
+ /** Deployment label echoed in responses/DMs (e.g. the wrangler env name). */
38
+ mode?: string;
39
+ /** Live admin resolver for the lifecycle DMs + error alerts. Default: nobody (DMs off). */
40
+ adminIds?: () => Promise<readonly number[]>;
41
+ /** Awaited inside waitUntil after each update — hand `d1Storage`'s flush here. */
42
+ flush?: () => Promise<void>;
43
+ /** Extra fields merged into /webhook-status (e.g. a live feature flag). */
44
+ statusExtra?: () => Promise<Record<string, unknown>>;
45
+ /** Consumer endpoints, tried BEFORE the built-ins. Return null to fall through. */
46
+ routes?: (request: Request, url: URL, ctx: WaitUntilCtx) => Promise<Response | null> | Response | null;
47
+ /** Error-alert throttle (share one to share its budget). Default: own 60s window. */
48
+ errorThrottle?: AlertThrottle;
49
+ };
50
+ /**
51
+ * Build the Worker `fetch` handler. `resolve` runs per request — memoize your
52
+ * bot construction inside it (the classic `let botPromise` pattern) so the
53
+ * isolate builds once.
54
+ */
55
+ export declare function botWorkerFetch<Env>(resolve: (env: Env) => Promise<BotWorkerRuntime> | BotWorkerRuntime): (request: Request, env: Env, ctx: WaitUntilCtx) => Promise<Response>;
56
+ export {};
57
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/bot/worker.ts"],"names":[],"mappings":"AA2CA,OAAO,EAAE,KAAK,aAAa,EAAgD,MAAM,aAAa,CAAC;AAI/F,6FAA6F;AAC7F,MAAM,MAAM,SAAS,GAAG;IACvB,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7B,OAAO,EAAE;QAAE,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAC;IAC7D,GAAG,EAAE;QACJ,UAAU,CAAC,MAAM,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAC;YAAC,eAAe,EAAE,MAAM,EAAE,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACvG,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;QAClC,cAAc,IAAI,OAAO,CAAC;YAAE,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,CAAC,CAAC;QAClE,+DAA+D;QAC/D,WAAW,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KACzE,CAAC;CACF,CAAC;AAEF,KAAK,YAAY,GAAG;IAAE,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,gBAAgB,GAAG;IAC9B,GAAG,EAAE,SAAS,CAAC;IACf,qGAAqG;IACrG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yFAAyF;IACzF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAC5C,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrD,mFAAmF;IACnF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAC;IACvG,qFAAqF;IACrF,aAAa,CAAC,EAAE,aAAa,CAAC;CAC9B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EACjC,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,GACjE,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,QAAQ,CAAC,CAkItE"}
@@ -0,0 +1,210 @@
1
+ /**
2
+ * The Cloudflare Worker cap for a GramIO bot: everything between "I have a
3
+ * `Bot` with features" and "it serves Telegram traffic in production", so a
4
+ * bot file never hand-rolls a fetch handler. The workerd twin of `bot/kit`'s
5
+ * `gracefulStart` (which owns the Node long-poll lifecycle).
6
+ *
7
+ * Endpoints (all on the worker root):
8
+ *
9
+ * POST / webhook — `X-Telegram-Bot-Api-Secret-Token` checked,
10
+ * acked immediately; the update (+ storage flush) rides
11
+ * `ctx.waitUntil`, errors DM the admins (throttled).
12
+ * POST /setup registers the webhook with `allowed_updates` DERIVED
13
+ * from the bot's handlers (a new handler type never
14
+ * fires until /setup reruns — deploys should end here).
15
+ * Body may carry `{sha, author, message}`: the deploy
16
+ * DM then names the commit that went live.
17
+ * POST /deploy-started the "what is shipping" DM — curl it from your deploy
18
+ * script on the STILL-LIVE version the moment a deploy
19
+ * starts. Body `{sha, author, message, etaSeconds?}`.
20
+ * POST /pause deleteWebhook (traffic truly stops; Telegram queues
21
+ * ~24h) — operator-authed.
22
+ * POST /resume re-register the webhook — operator-authed.
23
+ * GET /webhook-status `{mode, paused, webhook, ...statusExtra}` — operator-authed.
24
+ * GET / liveness: `ok (<mode>)`.
25
+ *
26
+ * Auth: `/setup` + `/deploy-started` take `Bearer <webhookSecret>`; the
27
+ * operator verbs take `Bearer <operatorSecret>` and 404 when it's unset.
28
+ * Consumer endpoints go in `routes` (tried first, return null to fall through).
29
+ *
30
+ * Usage — the resolver receives the Worker env and returns the runtime (build
31
+ * & memoize your bot inside it):
32
+ *
33
+ * export default { fetch: botWorkerFetch(async (env) => ({
34
+ * bot: await getBot(env),
35
+ * webhookSecret: env.WEBHOOK_SECRET,
36
+ * operatorSecret: env.SEND_SECRET,
37
+ * mode: env.MODE,
38
+ * adminIds: () => readAdminIds(env),
39
+ * flush,
40
+ * })) }
41
+ */
42
+ import { buildAllowedUpdates } from "gramio";
43
+ import { createLogger } from "../universal/log.js";
44
+ import { alertAdminError, alertThrottle, notifyAdmins } from "./notify.js";
45
+ const log = createLogger("bot/worker");
46
+ /**
47
+ * Build the Worker `fetch` handler. `resolve` runs per request — memoize your
48
+ * bot construction inside it (the classic `let botPromise` pattern) so the
49
+ * isolate builds once.
50
+ */
51
+ export function botWorkerFetch(resolve) {
52
+ const fallbackThrottle = alertThrottle();
53
+ return async (request, env, ctx) => {
54
+ const url = new URL(request.url);
55
+ try {
56
+ const rt = await resolve(env);
57
+ const { bot } = rt;
58
+ const mode = rt.mode ?? "?";
59
+ const adminIds = rt.adminIds ?? (async () => []);
60
+ const throttle = rt.errorThrottle ?? fallbackThrottle;
61
+ const webhookSecret = rt.webhookSecret?.trim();
62
+ // Consumer routes first — the escape hatch for bot-specific endpoints.
63
+ if (rt.routes) {
64
+ const handled = await rt.routes(request, url, ctx);
65
+ if (handled)
66
+ return handled;
67
+ }
68
+ if (request.method === "GET" && url.pathname === "/") {
69
+ return new Response(`ok (${mode})`);
70
+ }
71
+ if (request.method === "POST" && url.pathname === "/") {
72
+ if (!webhookSecret)
73
+ return new Response("webhookSecret is required", { status: 500 });
74
+ if (request.headers.get("X-Telegram-Bot-Api-Secret-Token") !== webhookSecret) {
75
+ return new Response("Unauthorized", { status: 401 });
76
+ }
77
+ let update;
78
+ try {
79
+ update = await request.json();
80
+ }
81
+ catch {
82
+ return new Response("Bad Request", { status: 400 });
83
+ }
84
+ // Ack Telegram immediately, then keep the Worker alive for the slow
85
+ // work (avoids GramIO's 30s webhook timeout).
86
+ ctx.waitUntil((async () => {
87
+ await bot.updates.handleUpdate(update);
88
+ if (rt.flush)
89
+ await rt.flush();
90
+ })().catch(async (error) => {
91
+ log.error("update failed:", error instanceof Error ? error.message : error);
92
+ // awaited so the DM rides the same waitUntil, not a frozen isolate
93
+ await alertAdminError(bot, await adminIds(), "webhook update failed", error, throttle);
94
+ }));
95
+ return new Response("OK");
96
+ }
97
+ // Deploy narration, step 1 of 2: what is SHIPPING (curled on the still-live version).
98
+ if (request.method === "POST" && url.pathname === "/deploy-started") {
99
+ if (!webhookSecret)
100
+ return new Response("webhookSecret is required", { status: 500 });
101
+ if (bearerToken(request.headers.get("Authorization")) !== webhookSecret) {
102
+ return new Response("forbidden", { status: 403 });
103
+ }
104
+ const meta = await request.json().catch(() => ({}));
105
+ const commit = parseCommitMeta(meta);
106
+ const eta = etaSeconds(meta);
107
+ log.info(`deploy started${commit ? ` · ${describeCommit(commit)}` : ""}`);
108
+ ctx.waitUntil(adminIds().then((ids) => notifyAdmins(bot, ids, `🛳 <b>@${bot.info?.username}</b> deploying${eta ? ` <i>(~${eta}s)</i>` : ""}…${commitHtml(commit)}`, DEPLOY_DM_PARAMS)));
109
+ return new Response("ok");
110
+ }
111
+ // Deploy narration, step 2 of 2: what went LIVE — and the load-bearing
112
+ // webhook re-registration (allowed_updates derives from the handlers).
113
+ if (request.method === "POST" && url.pathname === "/setup") {
114
+ if (!webhookSecret)
115
+ return new Response("webhookSecret is required", { status: 500 });
116
+ const token = bearerToken(request.headers.get("Authorization")) ?? request.headers.get("X-Setup-Token");
117
+ if (token !== webhookSecret)
118
+ return new Response("forbidden", { status: 403 });
119
+ const commit = parseCommitMeta(await request.json().catch(() => ({})));
120
+ const allowedUpdates = await registerWebhook(bot, url.origin, webhookSecret);
121
+ log.success(`deployed${commit ? ` · ${describeCommit(commit)}` : ""} — webhook registered`);
122
+ ctx.waitUntil(adminIds().then((ids) => notifyAdmins(bot, ids, `🚀 <b>@${bot.info?.username}</b> deployed · webhook registered${commitHtml(commit)}`, DEPLOY_DM_PARAMS)));
123
+ return new Response(`[${mode}] webhook set to ${url.origin}/ (updates: ${allowedUpdates.join(", ")})`);
124
+ }
125
+ // The operator tap: pause = deleteWebhook (Telegram queues ~24h),
126
+ // resume = re-register, status = getWebhookInfo (+statusExtra).
127
+ if (url.pathname === "/pause" || url.pathname === "/resume" || url.pathname === "/webhook-status") {
128
+ const secret = rt.operatorSecret?.trim();
129
+ if (!secret)
130
+ return json({ error: "operator API disabled" }, 404);
131
+ if (request.headers.get("Authorization") !== `Bearer ${secret}`) {
132
+ return json({ error: "unauthorized" }, 401);
133
+ }
134
+ if (request.method === "POST" && url.pathname === "/pause") {
135
+ await bot.api.deleteWebhook();
136
+ ctx.waitUntil(adminIds().then((ids) => notifyAdmins(bot, ids, `⏸️ @${bot.info?.username} [${mode}] paused — webhook deleted, Telegram queues ~24h.`)));
137
+ }
138
+ else if (request.method === "POST" && url.pathname === "/resume") {
139
+ if (!webhookSecret)
140
+ return new Response("webhookSecret is required", { status: 500 });
141
+ await registerWebhook(bot, url.origin, webhookSecret);
142
+ ctx.waitUntil(adminIds().then((ids) => notifyAdmins(bot, ids, `▶️ @${bot.info?.username} [${mode}] resumed — webhook re-registered.`)));
143
+ }
144
+ else if (!(request.method === "GET" && url.pathname === "/webhook-status")) {
145
+ return new Response("Not Found", { status: 404 });
146
+ }
147
+ const info = await bot.api.getWebhookInfo();
148
+ const extra = rt.statusExtra ? await rt.statusExtra() : {};
149
+ return json({ mode, paused: !info.url, ...extra, webhook: info });
150
+ }
151
+ return new Response("Not Found", { status: 404 });
152
+ }
153
+ catch (error) {
154
+ log.error("worker request failed:", error instanceof Error ? error.message : error);
155
+ return new Response("internal error", { status: 500 });
156
+ }
157
+ };
158
+ }
159
+ // allowed_updates must list the opt-in types (message_reaction, chat-member
160
+ // events) or Telegram never delivers them. Derived from the bot's registered
161
+ // handlers — which is why deploys re-register (/setup) and /resume re-derives
162
+ // instead of remembering a stale list.
163
+ async function registerWebhook(bot, origin, webhookSecret) {
164
+ const allowedUpdates = [...buildAllowedUpdates(bot)];
165
+ await bot.api.setWebhook({ url: `${origin}/`, secret_token: webhookSecret, allowed_updates: allowedUpdates });
166
+ return allowedUpdates;
167
+ }
168
+ function bearerToken(header) {
169
+ const match = /^Bearer\s+(.+)$/i.exec(header ?? "");
170
+ return match?.[1]?.trim() || null;
171
+ }
172
+ function json(value, status = 200) {
173
+ return new Response(JSON.stringify(value), { status, headers: { "content-type": "application/json" } });
174
+ }
175
+ function parseCommitMeta(meta) {
176
+ const m = meta;
177
+ const commit = {
178
+ sha: typeof m?.sha === "string" ? m.sha.trim().slice(0, 7) : "",
179
+ author: typeof m?.author === "string" ? m.author.trim() : "",
180
+ message: typeof m?.message === "string" ? (m.message.split("\n")[0]?.trim().slice(0, 120) ?? "") : "",
181
+ };
182
+ return commit.sha || commit.author || commit.message ? commit : null;
183
+ }
184
+ /** One line for the operator log: `abc1234 · Author · "message"`. */
185
+ function describeCommit(c) {
186
+ return [c.sha, c.author, c.message ? `“${c.message}”` : ""].filter(Boolean).join(" · ");
187
+ }
188
+ /**
189
+ * The deploy DMs' commit block (Telegram HTML), appended to the headline:
190
+ * a mono sha + author line, then the message as a quote. Empty when no metadata came.
191
+ */
192
+ function commitHtml(c) {
193
+ if (!c)
194
+ return "";
195
+ const head = [c.sha ? `<code>${escapeHtml(c.sha)}</code>` : "", escapeHtml(c.author)].filter(Boolean).join(" · ");
196
+ const quote = c.message ? `\n<blockquote>${escapeHtml(c.message)}</blockquote>` : "";
197
+ return `${head ? `\n${head}` : ""}${quote}`;
198
+ }
199
+ // HTML mode + no link preview, shared by both deploy DMs.
200
+ const DEPLOY_DM_PARAMS = { parse_mode: "HTML", link_preview_options: { is_disabled: true } };
201
+ /** The recent average deploy duration (seconds) a CI measured, when present and sane. */
202
+ function etaSeconds(meta) {
203
+ const n = Number(meta?.etaSeconds);
204
+ return Number.isFinite(n) && n > 0 && n < 3600 ? Math.round(n) : null;
205
+ }
206
+ // Local minimal escaper; graduates to bot/format when that module lands.
207
+ function escapeHtml(s) {
208
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
209
+ }
210
+ //# sourceMappingURL=worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/bot/worker.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adriangalilea/utils",
3
- "version": "0.30.0",
3
+ "version": "1.0.0",
4
4
  "description": "TypeScript utilities - logger, currency, formatter, GramIO bot plugins, and more",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -84,6 +84,10 @@
84
84
  "types": "./dist/bot/storage.d.ts",
85
85
  "default": "./dist/bot/storage.js"
86
86
  },
87
+ "./bot/storage-d1": {
88
+ "types": "./dist/bot/storage-d1.d.ts",
89
+ "default": "./dist/bot/storage-d1.js"
90
+ },
87
91
  "./bot/ctx": {
88
92
  "types": "./dist/bot/ctx.d.ts",
89
93
  "default": "./dist/bot/ctx.js"
@@ -103,6 +107,14 @@
103
107
  "./bot/notify": {
104
108
  "types": "./dist/bot/notify.d.ts",
105
109
  "default": "./dist/bot/notify.js"
110
+ },
111
+ "./bot/worker": {
112
+ "types": "./dist/bot/worker.d.ts",
113
+ "default": "./dist/bot/worker.js"
114
+ },
115
+ "./bot/create": {
116
+ "types": "./dist/bot/create.d.ts",
117
+ "default": "./dist/bot/create.js"
106
118
  }
107
119
  },
108
120
  "files": [