@blckrose/baileys 1.2.6 → 2.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.
@@ -1,275 +0,0 @@
1
- /**
2
- * apocalypse.js
3
- * HTTP client wrapper untuk https://api.apocalypse.web.id
4
- *
5
- * Usage:
6
- * import { createApocalypse } from '@blckrose/baileys';
7
- * const apocalypse = createApocalypse();
8
- *
9
- * // GET sederhana
10
- * const res = await apocalypse.get('/search/spotify?q=swim');
11
- *
12
- * // GET dengan params object (auto-encode)
13
- * const res = await apocalypse.get('/search/spotify', { q: 'swim' });
14
- *
15
- * // Path dengan sub-kategori + params
16
- * const res = await apocalypse.get('/manga/jagoanmanga/search', { q: 'killer+peter' });
17
- *
18
- * // POST
19
- * const res = await apocalypse.post('/ai/chatgpt', { text: 'halo' });
20
- *
21
- * // Akses data
22
- * console.log(res.result); // data utama
23
- * console.log(res.status); // true/false
24
- * console.log(res.raw); // full response JSON
25
- */
26
-
27
- const APOCALYPSE_BASE = 'https://api.apocalypse.web.id';
28
-
29
- /**
30
- * Buat instance Apocalypse API client.
31
- * @param {object} [config]
32
- * @param {string} [config.baseUrl] — override base URL
33
- * @param {string} [config.apiKey] — API key jika diperlukan (ditaruh di header)
34
- * @param {number} [config.timeout] — timeout ms (default 30000)
35
- * @param {object} [config.headers] — header tambahan
36
- */
37
- export function createApocalypse(config = {}) {
38
- const {
39
- baseUrl = APOCALYPSE_BASE,
40
- apiKey,
41
- timeout = 30_000,
42
- headers: extraHeaders = {}
43
- } = config;
44
-
45
- const _base = baseUrl.replace(/\/$/, '');
46
-
47
- // ── build URL ──────────────────────────────────────────────────────────
48
- function _buildUrl(path, params) {
49
- // path bisa sudah include query string atau tidak
50
- const hasQuery = path.includes('?');
51
-
52
- let url = _base + (path.startsWith('/') ? path : '/' + path);
53
-
54
- if (params && typeof params === 'object' && Object.keys(params).length > 0) {
55
- const qs = Object.entries(params)
56
- .filter(([, v]) => v !== undefined && v !== null)
57
- .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
58
- .join('&');
59
- if (qs) url += (hasQuery ? '&' : '?') + qs;
60
- }
61
-
62
- return url;
63
- }
64
-
65
- // ── base fetch ─────────────────────────────────────────────────────────
66
- async function _fetch(method, path, params, body) {
67
- const url = _buildUrl(path, method === 'GET' ? params : undefined);
68
-
69
- const headers = {
70
- 'Content-Type': 'application/json',
71
- 'Accept': 'application/json',
72
- 'User-Agent': 'blckrose-baileys/1.1.5',
73
- ...extraHeaders
74
- };
75
- if (apiKey) headers['x-api-key'] = apiKey;
76
-
77
- const controller = new AbortController();
78
- const timer = setTimeout(() => controller.abort(), timeout);
79
-
80
- let res;
81
- try {
82
- res = await fetch(url, {
83
- method,
84
- headers,
85
- signal: controller.signal,
86
- ...(method !== 'GET' && body !== undefined
87
- ? { body: JSON.stringify(body ?? params) }
88
- : {})
89
- });
90
- } finally {
91
- clearTimeout(timer);
92
- }
93
-
94
- // Try parse JSON, fallback ke text
95
- let data;
96
- const ct = res.headers.get('content-type') || '';
97
- if (ct.includes('application/json')) {
98
- data = await res.json();
99
- } else {
100
- const text = await res.text();
101
- try { data = JSON.parse(text); } catch { data = { result: text }; }
102
- }
103
-
104
- if (!res.ok) {
105
- const err = new Error(
106
- `[Apocalypse] ${method} ${url} → ${res.status} ${res.statusText}: ` +
107
- (data?.message || data?.error || JSON.stringify(data))
108
- );
109
- err.status = res.status;
110
- err.data = data;
111
- throw err;
112
- }
113
-
114
- // Normalise response
115
- return _wrap(data, url);
116
- }
117
-
118
- // ── response wrapper ───────────────────────────────────────────────────
119
- function _wrap(data, url) {
120
- return {
121
- /** Data utama (data.result / data.data / root jika tidak ada keduanya) */
122
- get result() {
123
- return data?.result ?? data?.data ?? data;
124
- },
125
- /** true jika API mengembalikan status sukses */
126
- get status() {
127
- return data?.status === true || data?.success === true || data?.status === 200;
128
- },
129
- /** Pesan dari API */
130
- get message() {
131
- return data?.message ?? data?.msg ?? '';
132
- },
133
- /** Full response JSON mentah */
134
- raw: data,
135
- /** URL yang dipanggil */
136
- url,
137
- /** Shortcut: ambil field tertentu dari result */
138
- get(key) {
139
- const r = this.result;
140
- if (r && typeof r === 'object') return r[key];
141
- return undefined;
142
- }
143
- };
144
- }
145
-
146
- // ── public API ─────────────────────────────────────────────────────────
147
-
148
- return {
149
- /**
150
- * GET request ke Apocalypse API.
151
- *
152
- * @param {string} path — misal '/search/spotify' atau '/search/spotify?q=swim'
153
- * @param {object} [params] — query params object { q: 'swim' }
154
- * @returns {Promise<ApocalypseResponse>}
155
- *
156
- * @example
157
- * // Keduanya ekuivalen:
158
- * await apocalypse.get('/search/spotify?q=swim');
159
- * await apocalypse.get('/search/spotify', { q: 'swim' });
160
- *
161
- * // Sub-path
162
- * await apocalypse.get('/manga/jagoanmanga/search', { q: 'killer+peter' });
163
- *
164
- * // Akses result
165
- * const { result } = await apocalypse.get('/search/youtube', { q: 'lagu baru' });
166
- * console.log(result);
167
- */
168
- async get(path, params) {
169
- return _fetch('GET', path, params);
170
- },
171
-
172
- /**
173
- * POST request ke Apocalypse API.
174
- *
175
- * @param {string} path
176
- * @param {object} [body] — body JSON
177
- * @param {object} [params] — query params opsional
178
- * @returns {Promise<ApocalypseResponse>}
179
- */
180
- async post(path, body, params) {
181
- return _fetch('POST', path, params, body);
182
- },
183
-
184
- /**
185
- * Shortcut builder — buat caller untuk kategori tertentu.
186
- *
187
- * @param {string} category — misal 'search', 'manga', 'ai'
188
- * @returns {{ get(endpoint, params): Promise, post(endpoint, body, params): Promise }}
189
- *
190
- * @example
191
- * const search = apocalypse.category('search');
192
- * await search.get('spotify', { q: 'swim' });
193
- * await search.get('youtube', { q: 'lagu baru' });
194
- *
195
- * const manga = apocalypse.category('manga/jagoanmanga');
196
- * await manga.get('search', { q: 'killer+peter' });
197
- */
198
- category(cat) {
199
- const prefix = '/' + cat.replace(/^\/|\/$/g, '');
200
- return {
201
- async get(endpoint, params) {
202
- return _fetch('GET', `${prefix}/${endpoint}`, params);
203
- },
204
- async post(endpoint, body, params) {
205
- return _fetch('POST', `${prefix}/${endpoint}`, params, body);
206
- }
207
- };
208
- },
209
-
210
- /** Base URL yang dipakai */
211
- baseUrl: _base,
212
- };
213
- }
214
-
215
- // ── Global mutable instance ────────────────────────────────────────────────
216
- // Config yang bisa diubah kapanpun via apocalypse.setKey() / apocalypse.setConfig()
217
- let _globalConfig = {};
218
-
219
- function _makeGlobal() {
220
- // Proxy yang selalu pakai _globalConfig terbaru saat dipanggil
221
- const handler = {
222
- get(_, prop) {
223
- if (prop === 'setKey') {
224
- /**
225
- * Set API key untuk global apocalypse instance.
226
- * Cukup tulis SEKALI di bot.js setelah require baileys.
227
- *
228
- * @param {string} key
229
- * @example
230
- * apocalypse.setKey('API_KEY_KAMU')
231
- */
232
- return function setKey(key) {
233
- _globalConfig = { ..._globalConfig, apiKey: key };
234
- };
235
- }
236
- if (prop === 'setConfig') {
237
- /**
238
- * Set konfigurasi lengkap untuk global apocalypse instance.
239
- *
240
- * @param {object} config { apiKey, baseUrl, timeout, headers }
241
- * @example
242
- * apocalypse.setConfig({ apiKey: 'xxx', timeout: 15000 })
243
- */
244
- return function setConfig(config) {
245
- _globalConfig = { ..._globalConfig, ...config };
246
- };
247
- }
248
- // Delegate ke instance baru yang dibuat dengan config terkini
249
- const instance = createApocalypse(_globalConfig);
250
- const val = instance[prop];
251
- return typeof val === 'function' ? val.bind(instance) : val;
252
- }
253
- };
254
- return new Proxy({}, handler);
255
- }
256
-
257
- /**
258
- * Instance default global siap pakai.
259
- * Tersedia tanpa import apapun setelah require('@blckrose/baileys').
260
- *
261
- * Tanpa API key:
262
- * @example
263
- * await apocalypse.get('/search/spotify', { q: 'swim' })
264
- *
265
- * Set API key sekali di bot.js:
266
- * @example
267
- * apocalypse.setKey('API_KEY_KAMU')
268
- * // setelah ini semua request otomatis pakai key tersebut
269
- * await apocalypse.get('/premium/endpoint', { q: 'test' })
270
- *
271
- * Set config lengkap:
272
- * @example
273
- * apocalypse.setConfig({ apiKey: 'xxx', timeout: 15000 })
274
- */
275
- export const apocalypse = _makeGlobal();