mirror of
https://github.com/tiennm99/miti99bot.git
synced 2026-04-17 15:20:58 +00:00
feat: scaffold plug-n-play telegram bot on cloudflare workers
grammY-based bot with a module plugin system loaded from the MODULES env var. Three command visibility levels (public/protected/private) share a unified command namespace with conflict detection at registry build. - 4 initial modules (util, wordle, loldle, misc); util fully implemented, others are stubs proving the plugin system end-to-end - util: /info (chat/thread/sender ids) + /help (pure renderer over the registry, HTML parse mode, escapes user-influenced strings) - KVStore interface with CFKVStore and a per-module prefixing factory; getJSON/putJSON convenience helpers; other backends drop in via one file - Webhook at POST /webhook with secret-token validation via grammY's webhookCallback; no admin HTTP surface - Post-deploy register script (npm run deploy = wrangler deploy && node --env-file=.env.deploy scripts/register.js) for setWebhook and setMyCommands; --dry-run flag for preview - 56 vitest unit tests across 7 suites covering registry, db wrapper, dispatcher, help renderer, validators, and HTML escaper - biome for lint + format; phased implementation plan under plans/
This commit is contained in:
44
src/db/kv-store-interface.js
Normal file
44
src/db/kv-store-interface.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @file KVStore interface — JSDoc typedefs only, no runtime code.
|
||||
*
|
||||
* This is the contract every storage backend must satisfy. modules receive
|
||||
* a prefixed `KVStore` (via {@link module:db/create-store}) and must NEVER
|
||||
* touch the underlying binding. to swap Cloudflare KV for a different
|
||||
* backend (D1, Upstash Redis, ...) in the future, implement this interface
|
||||
* in a new file and change the one import in create-store.js — no module
|
||||
* code changes required.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} KVStorePutOptions
|
||||
* @property {number} [expirationTtl] seconds — value auto-deletes after this many seconds.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} KVStoreListOptions
|
||||
* @property {string} [prefix] additional prefix (appended AFTER the module namespace).
|
||||
* @property {number} [limit]
|
||||
* @property {string} [cursor] pagination cursor from a previous list() call.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} KVStoreListResult
|
||||
* @property {string[]} keys — module namespace already stripped.
|
||||
* @property {string} [cursor] — present if more pages available.
|
||||
* @property {boolean} done — true when list_complete.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} KVStore
|
||||
* @property {(key: string) => Promise<string|null>} get
|
||||
* @property {(key: string, value: string, opts?: KVStorePutOptions) => Promise<void>} put
|
||||
* @property {(key: string) => Promise<void>} delete
|
||||
* @property {(opts?: KVStoreListOptions) => Promise<KVStoreListResult>} list
|
||||
* @property {(key: string) => Promise<any|null>} getJSON
|
||||
* returns null on missing key OR malformed JSON (logs a warning — does not throw).
|
||||
* @property {(key: string, value: any, opts?: KVStorePutOptions) => Promise<void>} putJSON
|
||||
* throws if value is undefined or contains a cycle.
|
||||
*/
|
||||
|
||||
// JSDoc-only module. No runtime exports.
|
||||
export {};
|
||||
Reference in New Issue
Block a user