rynkai 0.1.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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +156 -0
  3. package/dist/core/Client.d.ts +46 -0
  4. package/dist/core/Client.d.ts.map +1 -0
  5. package/dist/core/Client.js +183 -0
  6. package/dist/core/Client.js.map +1 -0
  7. package/dist/core/Middleware.d.ts +27 -0
  8. package/dist/core/Middleware.d.ts.map +1 -0
  9. package/dist/core/Middleware.js +26 -0
  10. package/dist/core/Middleware.js.map +1 -0
  11. package/dist/core/RateLimiter.d.ts +24 -0
  12. package/dist/core/RateLimiter.d.ts.map +1 -0
  13. package/dist/core/RateLimiter.js +40 -0
  14. package/dist/core/RateLimiter.js.map +1 -0
  15. package/dist/index.d.ts +11 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +18 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/message/MessageBuilder.d.ts +25 -0
  20. package/dist/message/MessageBuilder.d.ts.map +1 -0
  21. package/dist/message/MessageBuilder.js +29 -0
  22. package/dist/message/MessageBuilder.js.map +1 -0
  23. package/dist/message/MessageParser.d.ts +8 -0
  24. package/dist/message/MessageParser.d.ts.map +1 -0
  25. package/dist/message/MessageParser.js +80 -0
  26. package/dist/message/MessageParser.js.map +1 -0
  27. package/dist/plugin/PluginLoader.d.ts +21 -0
  28. package/dist/plugin/PluginLoader.d.ts.map +1 -0
  29. package/dist/plugin/PluginLoader.js +113 -0
  30. package/dist/plugin/PluginLoader.js.map +1 -0
  31. package/dist/session/FileSessionStore.d.ts +17 -0
  32. package/dist/session/FileSessionStore.d.ts.map +1 -0
  33. package/dist/session/FileSessionStore.js +74 -0
  34. package/dist/session/FileSessionStore.js.map +1 -0
  35. package/dist/session/MongoSessionStore.d.ts +25 -0
  36. package/dist/session/MongoSessionStore.d.ts.map +1 -0
  37. package/dist/session/MongoSessionStore.js +103 -0
  38. package/dist/session/MongoSessionStore.js.map +1 -0
  39. package/dist/types/index.d.ts +76 -0
  40. package/dist/types/index.d.ts.map +1 -0
  41. package/dist/types/index.js +3 -0
  42. package/dist/types/index.js.map +1 -0
  43. package/package.json +48 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 rynk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,156 @@
1
+ # rynkai
2
+
3
+ Wrapper TypeScript yang clean di atas [Baileys](https://github.com/WhiskeySockets/Baileys), lengkap dengan plugin system & session store yang bisa diganti-ganti (file, MongoDB, dll).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install rynkai
9
+ ```
10
+
11
+ ## Quickstart
12
+
13
+ ```ts
14
+ import { Client, MessageBuilder } from 'rynkai';
15
+
16
+ const bot = new Client({
17
+ sessionName: 'my-bot',
18
+ prefix: '.',
19
+ });
20
+
21
+ bot.on('qr', (qr) => {
22
+ // render qr pakai qrcode-terminal atau library lain
23
+ console.log('Scan QR ini:', qr);
24
+ });
25
+
26
+ bot.on('ready', () => {
27
+ console.log('Bot connected!');
28
+ });
29
+
30
+ bot.on('message', async (msg) => {
31
+ if (msg.text === 'ping') {
32
+ await bot.reply(msg, 'pong');
33
+ }
34
+ });
35
+
36
+ await bot.connect();
37
+ ```
38
+
39
+ ## Plugin system
40
+
41
+ Plugin format-nya sengaja mirip gaya rynk4: `{ name, command, category, execute() }`.
42
+
43
+ ```ts
44
+ // plugins/hello.ts
45
+ import type { Plugin } from 'rynkai';
46
+
47
+ const plugin: Plugin = {
48
+ name: 'hello',
49
+ command: ['hello', 'hi'],
50
+ category: 'general',
51
+ cooldown: 5, // detik, opsional
52
+ execute: async (ctx) => {
53
+ await ctx.reply(`Halo, ${ctx.message.sender}!`);
54
+ },
55
+ };
56
+
57
+ export default plugin;
58
+ ```
59
+
60
+ ```ts
61
+ await bot.plugins.loadFromDirectory('./plugins');
62
+ await bot.connect();
63
+ ```
64
+
65
+ ## Middleware / hooks
66
+
67
+ Middleware jalan sebelum plugin, bergaya "onion" (kayak Koa/Express) — bisa ngerjain sesuatu sebelum & sesudah `next()`, atau berhenti total tanpa memanggil `next()` (misal buat blokir user).
68
+
69
+ ```ts
70
+ bot.use(async (ctx, next) => {
71
+ console.log(`[${ctx.message.sender}] -> ${ctx.message.text}`);
72
+ await next();
73
+ console.log(`[${ctx.message.sender}] <- selesai`);
74
+ });
75
+
76
+ bot.use(async (ctx, next) => {
77
+ if (isBanned(ctx.message.sender)) {
78
+ await ctx.reply('Kamu diblokir dari bot ini.');
79
+ return; // next() tidak dipanggil, plugin tidak jalan
80
+ }
81
+ await next();
82
+ });
83
+ ```
84
+
85
+ Middleware dijalankan berurutan sesuai urutan `use()` dipanggil, dan berlaku untuk semua command (beda dari `cooldown` di plugin yang per-command).
86
+
87
+ ## Rate limiter global
88
+
89
+ Beda dari `cooldown` (per-plugin, per-user), `rateLimit` di config berlaku global — total command apapun yang boleh dijalankan satu user dalam satu window waktu.
90
+
91
+ ```ts
92
+ const bot = new Client({
93
+ sessionName: 'my-bot',
94
+ rateLimit: { max: 10, windowMs: 60_000 }, // maksimal 10 command per menit per user
95
+ });
96
+ ```
97
+
98
+ Kalau user kelebihan limit, bot otomatis reply pemberitahuan dan command tidak diteruskan ke middleware/plugin.
99
+
100
+ ## Session store custom (misal MongoDB)
101
+
102
+ Sudah disediakan `MongoSessionStore` built-in — cocok kalau stack-mu (kayak rynk4) sudah pakai MongoDB/Mongoose:
103
+
104
+ ```bash
105
+ npm install mongoose
106
+ ```
107
+
108
+ ```ts
109
+ import mongoose from 'mongoose';
110
+ import { Client, MongoSessionStore } from 'rynkai';
111
+
112
+ await mongoose.connect(process.env.MONGO_URI!); // buka koneksi dulu sebelum connect()
113
+
114
+ const bot = new Client({
115
+ sessionName: 'my-bot',
116
+ sessionStore: new MongoSessionStore('my-bot'),
117
+ });
118
+ ```
119
+
120
+ Kalau butuh store lain (Redis, dll), tinggal implement interface `SessionStore` yang sama:
121
+
122
+ ```ts
123
+ import type { SessionStore } from 'rynkai';
124
+
125
+ class RedisSessionStore implements SessionStore {
126
+ async load() { /* ... */ }
127
+ async save(state) { /* ... */ }
128
+ async clear() { /* ... */ }
129
+ }
130
+ ```
131
+
132
+ ## Pairing code (tanpa QR)
133
+
134
+ ```ts
135
+ const bot = new Client({
136
+ sessionName: 'my-bot',
137
+ pairingCode: { phoneNumber: '628123456789' },
138
+ });
139
+
140
+ bot.on('pairingCode', (code) => console.log('Kode pairing:', code));
141
+ ```
142
+
143
+ ## Status
144
+
145
+ Masih tahap awal (0.1.0). Yang sudah ada:
146
+ - [x] Core client (connect, reconnect, QR/pairing code)
147
+ - [x] Normalized message parsing (text, media, quoted)
148
+ - [x] Plugin loader + cooldown
149
+ - [x] FileSessionStore default
150
+ - [x] MessageBuilder helper
151
+ - [x] Middleware/hooks sebelum plugin dieksekusi
152
+ - [x] Rate limiter global (terpisah dari cooldown per-plugin)
153
+ - [x] Built-in MongoSessionStore
154
+
155
+ Belum ada (rencana selanjutnya):
156
+ - [ ] Test suite
@@ -0,0 +1,46 @@
1
+ import { type WASocket, type AnyMessageContent } from '@whiskeysockets/baileys';
2
+ import { EventEmitter } from 'events';
3
+ import type { NormalizedMessage, RynkaiConfig } from '../types';
4
+ import { PluginLoader } from '../plugin/PluginLoader';
5
+ import { type Middleware } from './Middleware';
6
+ export interface RynkaiEvents {
7
+ ready: () => void;
8
+ message: (msg: NormalizedMessage) => void;
9
+ disconnected: (reason: string) => void;
10
+ qr: (qr: string) => void;
11
+ pairingCode: (code: string) => void;
12
+ }
13
+ /**
14
+ * Client utama rynkai. Bungkus WASocket Baileys dan expose API yang lebih
15
+ * sederhana: client.on('message', ...), client.send(...), plugin otomatis
16
+ * ke-dispatch kalau prefix cocok.
17
+ */
18
+ export declare class Client extends EventEmitter {
19
+ sock: WASocket | null;
20
+ readonly plugins: PluginLoader;
21
+ private config;
22
+ private sessionStore;
23
+ private logger;
24
+ private middlewares;
25
+ private rateLimiter;
26
+ constructor(config: RynkaiConfig);
27
+ /**
28
+ * Daftarkan middleware yang jalan sebelum (dan bisa membungkus) eksekusi plugin.
29
+ * Dipanggil untuk semua pesan yang cocok prefix, terlepas plugin-nya ada atau tidak
30
+ * dalam urutan pendaftaran (onion model). Chainable.
31
+ */
32
+ use(middleware: Middleware): this;
33
+ /** Konek ke WhatsApp. Resolve setelah koneksi berhasil "open". */
34
+ connect(): Promise<void>;
35
+ /** Cocokkan pesan terhadap prefix & jalankan plugin yang sesuai, kalau ada. */
36
+ private dispatchPlugin;
37
+ /** Kirim pesan ke sebuah chat. Wrapper tipis di atas sock.sendMessage. */
38
+ send(chatId: string, content: AnyMessageContent): Promise<void>;
39
+ /** Balas sebuah NormalizedMessage, otomatis quote pesan aslinya. */
40
+ reply(message: NormalizedMessage, text: string): Promise<void>;
41
+ /** Logout & bersihkan sesi tersimpan. */
42
+ logout(): Promise<void>;
43
+ on<K extends keyof RynkaiEvents>(event: K, listener: RynkaiEvents[K]): this;
44
+ emit<K extends keyof RynkaiEvents>(event: K, ...args: Parameters<RynkaiEvents[K]>): boolean;
45
+ }
46
+ //# sourceMappingURL=Client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Client.d.ts","sourceRoot":"","sources":["../../src/core/Client.ts"],"names":[],"mappings":"AAAA,OAAqB,EAGnB,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAiB,MAAM,UAAU,CAAC;AAG/E,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAGxD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,OAAO,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC1C,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACzB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED;;;;GAIG;AACH,qBAAa,MAAO,SAAQ,YAAY;IAC/B,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAQ;IACpC,SAAgB,OAAO,eAAsB;IAE7C,OAAO,CAAC,MAAM,CACqD;IACnE,OAAO,CAAC,YAAY,CAA+D;IACnF,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,WAAW,CAAqB;gBAE5B,MAAM,EAAE,YAAY;IAgBhC;;;;OAIG;IACH,GAAG,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAKjC,kEAAkE;IAC5D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA0D9B,+EAA+E;YACjE,cAAc;IA6B5B,0EAA0E;IACpE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrE,oEAAoE;IAC9D,KAAK,CAAC,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpE,yCAAyC;IACnC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAM7B,EAAE,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI;IAG3E,IAAI,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO;CAG5F"}
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.Client = void 0;
40
+ const baileys_1 = __importStar(require("@whiskeysockets/baileys"));
41
+ const events_1 = require("events");
42
+ const pino_1 = __importDefault(require("pino"));
43
+ const FileSessionStore_1 = require("../session/FileSessionStore");
44
+ const MessageParser_1 = require("../message/MessageParser");
45
+ const PluginLoader_1 = require("../plugin/PluginLoader");
46
+ const Middleware_1 = require("./Middleware");
47
+ const RateLimiter_1 = require("./RateLimiter");
48
+ /**
49
+ * Client utama rynkai. Bungkus WASocket Baileys dan expose API yang lebih
50
+ * sederhana: client.on('message', ...), client.send(...), plugin otomatis
51
+ * ke-dispatch kalau prefix cocok.
52
+ */
53
+ class Client extends events_1.EventEmitter {
54
+ constructor(config) {
55
+ super();
56
+ this.sock = null;
57
+ this.plugins = new PluginLoader_1.PluginLoader();
58
+ this.middlewares = [];
59
+ this.config = {
60
+ prefix: '.',
61
+ printQR: !config.pairingCode,
62
+ logLevel: 'silent',
63
+ pairingCode: config.pairingCode,
64
+ sessionStore: config.sessionStore,
65
+ sessionName: config.sessionName,
66
+ rateLimit: config.rateLimit,
67
+ };
68
+ this.sessionStore = config.sessionStore ?? new FileSessionStore_1.FileSessionStore(config.sessionName);
69
+ this.logger = (0, pino_1.default)({ level: this.config.logLevel });
70
+ this.rateLimiter = config.rateLimit ? new RateLimiter_1.RateLimiter(config.rateLimit) : null;
71
+ }
72
+ /**
73
+ * Daftarkan middleware yang jalan sebelum (dan bisa membungkus) eksekusi plugin.
74
+ * Dipanggil untuk semua pesan yang cocok prefix, terlepas plugin-nya ada atau tidak
75
+ * dalam urutan pendaftaran (onion model). Chainable.
76
+ */
77
+ use(middleware) {
78
+ this.middlewares.push(middleware);
79
+ return this;
80
+ }
81
+ /** Konek ke WhatsApp. Resolve setelah koneksi berhasil "open". */
82
+ async connect() {
83
+ const state = await this.sessionStore.load();
84
+ if (!state) {
85
+ throw new Error('SessionStore.load() mengembalikan null — pastikan implementasinya benar.');
86
+ }
87
+ const { version } = await (0, baileys_1.fetchLatestBaileysVersion)();
88
+ this.sock = (0, baileys_1.default)({
89
+ version,
90
+ auth: state,
91
+ logger: this.logger,
92
+ printQRInTerminal: false, // kita handle sendiri lewat event 'qr'
93
+ });
94
+ this.sock.ev.on('creds.update', async () => {
95
+ await this.sessionStore.save(state);
96
+ });
97
+ if (this.config.pairingCode && !this.sock.authState.creds.registered) {
98
+ const code = await this.sock.requestPairingCode(this.config.pairingCode.phoneNumber);
99
+ this.emit('pairingCode', code);
100
+ }
101
+ this.sock.ev.on('connection.update', (update) => {
102
+ const { connection, lastDisconnect, qr } = update;
103
+ if (qr && this.config.printQR) {
104
+ this.emit('qr', qr);
105
+ }
106
+ if (connection === 'open') {
107
+ this.emit('ready');
108
+ }
109
+ if (connection === 'close') {
110
+ const statusCode = lastDisconnect?.error?.output?.statusCode;
111
+ const shouldReconnect = statusCode !== baileys_1.DisconnectReason.loggedOut;
112
+ this.emit('disconnected', String(statusCode ?? 'unknown'));
113
+ if (shouldReconnect) {
114
+ this.connect().catch((err) => this.logger.error(err, 'gagal reconnect'));
115
+ }
116
+ }
117
+ });
118
+ this.sock.ev.on('messages.upsert', async ({ messages, type }) => {
119
+ if (type !== 'notify')
120
+ return;
121
+ for (const raw of messages) {
122
+ if (!raw.message)
123
+ continue;
124
+ const message = (0, MessageParser_1.parseMessage)(raw);
125
+ this.emit('message', message);
126
+ await this.dispatchPlugin(message);
127
+ }
128
+ });
129
+ }
130
+ /** Cocokkan pesan terhadap prefix & jalankan plugin yang sesuai, kalau ada. */
131
+ async dispatchPlugin(message) {
132
+ if (message.fromMe)
133
+ return;
134
+ if (!message.text.startsWith(this.config.prefix))
135
+ return;
136
+ const withoutPrefix = message.text.slice(this.config.prefix.length).trim();
137
+ const [command, ...args] = withoutPrefix.split(/\s+/);
138
+ if (!command)
139
+ return;
140
+ const ctx = {
141
+ client: this.sock,
142
+ message,
143
+ args,
144
+ reply: (text) => this.reply(message, text),
145
+ };
146
+ // Rate limit global dicek duluan, sebelum middleware/plugin apapun jalan.
147
+ if (this.rateLimiter && !this.rateLimiter.consume(message.sender)) {
148
+ const retryAfter = this.rateLimiter.retryAfter(message.sender);
149
+ await ctx.reply(`Terlalu banyak perintah. Coba lagi dalam ${retryAfter} detik.`);
150
+ return;
151
+ }
152
+ const pipeline = (0, Middleware_1.compose)(this.middlewares, async () => {
153
+ await this.plugins.execute(command, ctx);
154
+ });
155
+ await pipeline(ctx);
156
+ }
157
+ /** Kirim pesan ke sebuah chat. Wrapper tipis di atas sock.sendMessage. */
158
+ async send(chatId, content) {
159
+ if (!this.sock)
160
+ throw new Error('Client belum connect. Panggil connect() dulu.');
161
+ await this.sock.sendMessage(chatId, content);
162
+ }
163
+ /** Balas sebuah NormalizedMessage, otomatis quote pesan aslinya. */
164
+ async reply(message, text) {
165
+ if (!this.sock)
166
+ throw new Error('Client belum connect. Panggil connect() dulu.');
167
+ await this.sock.sendMessage(message.chatId, { text }, { quoted: message.raw });
168
+ }
169
+ /** Logout & bersihkan sesi tersimpan. */
170
+ async logout() {
171
+ await this.sock?.logout();
172
+ await this.sessionStore.clear();
173
+ }
174
+ // Type-safe event emitter overrides
175
+ on(event, listener) {
176
+ return super.on(event, listener);
177
+ }
178
+ emit(event, ...args) {
179
+ return super.emit(event, ...args);
180
+ }
181
+ }
182
+ exports.Client = Client;
183
+ //# sourceMappingURL=Client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Client.js","sourceRoot":"","sources":["../../src/core/Client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { PluginContext } from '../types';
2
+ export type NextFunction = () => Promise<void>;
3
+ /**
4
+ * Middleware bergaya "onion" (kayak Koa/Express): tiap middleware bisa
5
+ * ngerjain sesuatu sebelum & sesudah next() dipanggil, atau berhenti
6
+ * total dengan tidak memanggil next() sama sekali (misal buat blokir user).
7
+ *
8
+ * Contoh logging:
9
+ * client.use(async (ctx, next) => {
10
+ * console.log(`-> ${ctx.message.sender} pakai command`);
11
+ * await next();
12
+ * console.log(`<- selesai`);
13
+ * });
14
+ *
15
+ * Contoh blokir user tanpa lanjut ke plugin:
16
+ * client.use(async (ctx, next) => {
17
+ * if (isBanned(ctx.message.sender)) return; // next() tidak dipanggil
18
+ * await next();
19
+ * });
20
+ */
21
+ export type Middleware = (ctx: PluginContext, next: NextFunction) => Promise<void> | void;
22
+ /**
23
+ * Susun array middleware + handler akhir jadi satu fungsi dispatch.
24
+ * Implementasi standar "onion model" seperti koa-compose.
25
+ */
26
+ export declare function compose(middlewares: Middleware[], final: NextFunction): (ctx: PluginContext) => Promise<void>;
27
+ //# sourceMappingURL=Middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Middleware.d.ts","sourceRoot":"","sources":["../../src/core/Middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;AAE/C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAE1F;;;GAGG;AACH,wBAAgB,OAAO,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,YAAY,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAqB7G"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compose = compose;
4
+ /**
5
+ * Susun array middleware + handler akhir jadi satu fungsi dispatch.
6
+ * Implementasi standar "onion model" seperti koa-compose.
7
+ */
8
+ function compose(middlewares, final) {
9
+ return async function dispatch(ctx) {
10
+ let lastIndex = -1;
11
+ async function invoke(i) {
12
+ if (i <= lastIndex) {
13
+ throw new Error('next() dipanggil lebih dari sekali oleh middleware yang sama');
14
+ }
15
+ lastIndex = i;
16
+ if (i === middlewares.length) {
17
+ await final();
18
+ return;
19
+ }
20
+ const mw = middlewares[i];
21
+ await mw(ctx, () => invoke(i + 1));
22
+ }
23
+ await invoke(0);
24
+ };
25
+ }
26
+ //# sourceMappingURL=Middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Middleware.js","sourceRoot":"","sources":["../../src/core/Middleware.ts"],"names":[],"mappings":";;AA4BA,0BAqBC;AAzBD;;;GAGG;AACH,SAAgB,OAAO,CAAC,WAAyB,EAAE,KAAmB;IACpE,OAAO,KAAK,UAAU,QAAQ,CAAC,GAAkB;QAC/C,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;QAEnB,KAAK,UAAU,MAAM,CAAC,CAAS;YAC7B,IAAI,CAAC,IAAI,SAAS,EAAE,CAAC;gBACnB,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;YAClF,CAAC;YACD,SAAS,GAAG,CAAC,CAAC;YAEd,IAAI,CAAC,KAAK,WAAW,CAAC,MAAM,EAAE,CAAC;gBAC7B,MAAM,KAAK,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YAED,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;QAED,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,24 @@
1
+ export interface RateLimitConfig {
2
+ /** Maksimal jumlah command yang boleh dijalankan dalam satu window */
3
+ max: number;
4
+ /** Panjang window dalam milidetik */
5
+ windowMs: number;
6
+ }
7
+ /**
8
+ * Rate limiter global berbasis fixed window, per user (bukan per-plugin
9
+ * seperti cooldown di PluginLoader). Cocok buat cegah spam command
10
+ * bertubi-tubi dari satu user, terlepas dari command apa yang dipanggil.
11
+ */
12
+ export declare class RateLimiter {
13
+ private config;
14
+ private hits;
15
+ constructor(config: RateLimitConfig);
16
+ /**
17
+ * Catat satu request dari user. Return true kalau masih dalam limit
18
+ * (request dihitung), false kalau user sudah kena limit.
19
+ */
20
+ consume(userId: string): boolean;
21
+ /** Sisa waktu dalam detik sebelum limit user ini reset. 0 kalau tidak sedang kena limit. */
22
+ retryAfter(userId: string): number;
23
+ }
24
+ //# sourceMappingURL=RateLimiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RateLimiter.d.ts","sourceRoot":"","sources":["../../src/core/RateLimiter.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC;IACZ,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,qBAAa,WAAW;IAGV,OAAO,CAAC,MAAM;IAF1B,OAAO,CAAC,IAAI,CAAyD;gBAEjD,MAAM,EAAE,eAAe;IAE3C;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAiBhC,4FAA4F;IAC5F,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;CAKnC"}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RateLimiter = void 0;
4
+ /**
5
+ * Rate limiter global berbasis fixed window, per user (bukan per-plugin
6
+ * seperti cooldown di PluginLoader). Cocok buat cegah spam command
7
+ * bertubi-tubi dari satu user, terlepas dari command apa yang dipanggil.
8
+ */
9
+ class RateLimiter {
10
+ constructor(config) {
11
+ this.config = config;
12
+ this.hits = new Map();
13
+ }
14
+ /**
15
+ * Catat satu request dari user. Return true kalau masih dalam limit
16
+ * (request dihitung), false kalau user sudah kena limit.
17
+ */
18
+ consume(userId) {
19
+ const now = Date.now();
20
+ const entry = this.hits.get(userId);
21
+ if (!entry || now >= entry.resetAt) {
22
+ this.hits.set(userId, { count: 1, resetAt: now + this.config.windowMs });
23
+ return true;
24
+ }
25
+ if (entry.count >= this.config.max) {
26
+ return false;
27
+ }
28
+ entry.count++;
29
+ return true;
30
+ }
31
+ /** Sisa waktu dalam detik sebelum limit user ini reset. 0 kalau tidak sedang kena limit. */
32
+ retryAfter(userId) {
33
+ const entry = this.hits.get(userId);
34
+ if (!entry)
35
+ return 0;
36
+ return Math.max(0, Math.ceil((entry.resetAt - Date.now()) / 1000));
37
+ }
38
+ }
39
+ exports.RateLimiter = RateLimiter;
40
+ //# sourceMappingURL=RateLimiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../src/core/RateLimiter.ts"],"names":[],"mappings":";;;AAOA;;;;GAIG;AACH,MAAa,WAAW;IAGtB,YAAoB,MAAuB;QAAvB,WAAM,GAAN,MAAM,CAAiB;QAFnC,SAAI,GAAG,IAAI,GAAG,EAA8C,CAAC;IAEvB,CAAC;IAE/C;;;OAGG;IACH,OAAO,CAAC,MAAc;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEpC,IAAI,CAAC,KAAK,IAAI,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YACzE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4FAA4F;IAC5F,UAAU,CAAC,MAAc;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK;YAAE,OAAO,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACrE,CAAC;CACF;AAhCD,kCAgCC"}
@@ -0,0 +1,11 @@
1
+ export { Client } from './core/Client';
2
+ export { FileSessionStore } from './session/FileSessionStore';
3
+ export { MongoSessionStore } from './session/MongoSessionStore';
4
+ export { MessageBuilder } from './message/MessageBuilder';
5
+ export { PluginLoader } from './plugin/PluginLoader';
6
+ export { RateLimiter } from './core/RateLimiter';
7
+ export { compose } from './core/Middleware';
8
+ export type { NormalizedMessage, NormalizedMessageType, SessionStore, Plugin, PluginContext, RynkaiConfig, } from './types';
9
+ export type { Middleware, NextFunction } from './core/Middleware';
10
+ export type { RateLimitConfig } from './core/RateLimiter';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,YAAY,EACV,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,MAAM,EACN,aAAa,EACb,YAAY,GACb,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAClE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compose = exports.RateLimiter = exports.PluginLoader = exports.MessageBuilder = exports.MongoSessionStore = exports.FileSessionStore = exports.Client = void 0;
4
+ var Client_1 = require("./core/Client");
5
+ Object.defineProperty(exports, "Client", { enumerable: true, get: function () { return Client_1.Client; } });
6
+ var FileSessionStore_1 = require("./session/FileSessionStore");
7
+ Object.defineProperty(exports, "FileSessionStore", { enumerable: true, get: function () { return FileSessionStore_1.FileSessionStore; } });
8
+ var MongoSessionStore_1 = require("./session/MongoSessionStore");
9
+ Object.defineProperty(exports, "MongoSessionStore", { enumerable: true, get: function () { return MongoSessionStore_1.MongoSessionStore; } });
10
+ var MessageBuilder_1 = require("./message/MessageBuilder");
11
+ Object.defineProperty(exports, "MessageBuilder", { enumerable: true, get: function () { return MessageBuilder_1.MessageBuilder; } });
12
+ var PluginLoader_1 = require("./plugin/PluginLoader");
13
+ Object.defineProperty(exports, "PluginLoader", { enumerable: true, get: function () { return PluginLoader_1.PluginLoader; } });
14
+ var RateLimiter_1 = require("./core/RateLimiter");
15
+ Object.defineProperty(exports, "RateLimiter", { enumerable: true, get: function () { return RateLimiter_1.RateLimiter; } });
16
+ var Middleware_1 = require("./core/Middleware");
17
+ Object.defineProperty(exports, "compose", { enumerable: true, get: function () { return Middleware_1.compose; } });
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,wCAAuC;AAA9B,gGAAA,MAAM,OAAA;AACf,+DAA8D;AAArD,oHAAA,gBAAgB,OAAA;AACzB,iEAAgE;AAAvD,sHAAA,iBAAiB,OAAA;AAC1B,2DAA0D;AAAjD,gHAAA,cAAc,OAAA;AACvB,sDAAqD;AAA5C,4GAAA,YAAY,OAAA;AACrB,kDAAiD;AAAxC,0GAAA,WAAW,OAAA;AACpB,gDAA4C;AAAnC,qGAAA,OAAO,OAAA"}
@@ -0,0 +1,25 @@
1
+ import type { AnyMessageContent } from '@whiskeysockets/baileys';
2
+ /**
3
+ * Kumpulan helper buat bikin payload pesan dengan cara yang lebih deklaratif
4
+ * dibanding manual bikin object AnyMessageContent-nya Baileys.
5
+ * Semua return AnyMessageContent, siap dilempar ke client.send(chatId, payload).
6
+ */
7
+ export declare const MessageBuilder: {
8
+ text(body: string): AnyMessageContent;
9
+ image(source: Buffer | {
10
+ url: string;
11
+ }, caption?: string): AnyMessageContent;
12
+ video(source: Buffer | {
13
+ url: string;
14
+ }, caption?: string): AnyMessageContent;
15
+ audio(source: Buffer | {
16
+ url: string;
17
+ }, ptt?: boolean): AnyMessageContent;
18
+ sticker(source: Buffer | {
19
+ url: string;
20
+ }): AnyMessageContent;
21
+ document(source: Buffer | {
22
+ url: string;
23
+ }, fileName: string, mimetype?: string): AnyMessageContent;
24
+ };
25
+ //# sourceMappingURL=MessageBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageBuilder.d.ts","sourceRoot":"","sources":["../../src/message/MessageBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE;;;;GAIG;AACH,eAAO,MAAM,cAAc;eACd,MAAM,GAAG,iBAAiB;kBAIvB,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,YAAY,MAAM,GAAG,iBAAiB;kBAI9D,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,YAAY,MAAM,GAAG,iBAAiB;kBAI9D,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,kBAAgB,iBAAiB;oBAIvD,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,iBAAiB;qBAI3C,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,YAAY,MAAM,sBAA0C,iBAAiB;CAGvH,CAAC"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MessageBuilder = void 0;
4
+ /**
5
+ * Kumpulan helper buat bikin payload pesan dengan cara yang lebih deklaratif
6
+ * dibanding manual bikin object AnyMessageContent-nya Baileys.
7
+ * Semua return AnyMessageContent, siap dilempar ke client.send(chatId, payload).
8
+ */
9
+ exports.MessageBuilder = {
10
+ text(body) {
11
+ return { text: body };
12
+ },
13
+ image(source, caption) {
14
+ return { image: source, caption };
15
+ },
16
+ video(source, caption) {
17
+ return { video: source, caption };
18
+ },
19
+ audio(source, ptt = false) {
20
+ return { audio: source, ptt, mimetype: 'audio/mp4' };
21
+ },
22
+ sticker(source) {
23
+ return { sticker: source };
24
+ },
25
+ document(source, fileName, mimetype = 'application/octet-stream') {
26
+ return { document: source, fileName, mimetype };
27
+ },
28
+ };
29
+ //# sourceMappingURL=MessageBuilder.js.map