@adbjs/sdk 0.1.1

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/index.js ADDED
@@ -0,0 +1,671 @@
1
+ import wretch from 'wretch';
2
+
3
+ // src/client.ts
4
+
5
+ // src/errors.ts
6
+ var AllDebridError = class _AllDebridError extends Error {
7
+ code;
8
+ isAllDebridError = true;
9
+ constructor(code, message) {
10
+ super(message);
11
+ this.name = "AllDebridError";
12
+ this.code = code;
13
+ if ("captureStackTrace" in Error && typeof Error.captureStackTrace === "function") {
14
+ Error.captureStackTrace(this, _AllDebridError);
15
+ }
16
+ }
17
+ /**
18
+ * Create an AllDebridError from an API error response
19
+ */
20
+ static fromApiError(error) {
21
+ return new _AllDebridError(error.code, error.message);
22
+ }
23
+ };
24
+ var AuthenticationError = class extends AllDebridError {
25
+ constructor(code, message) {
26
+ super(code, message);
27
+ this.name = "AuthenticationError";
28
+ }
29
+ };
30
+ var LinkError = class extends AllDebridError {
31
+ constructor(code, message) {
32
+ super(code, message);
33
+ this.name = "LinkError";
34
+ }
35
+ };
36
+ var MagnetError = class extends AllDebridError {
37
+ constructor(code, message) {
38
+ super(code, message);
39
+ this.name = "MagnetError";
40
+ }
41
+ };
42
+ var NetworkError = class extends AllDebridError {
43
+ constructor(message, statusCode) {
44
+ super("NETWORK_ERROR", message);
45
+ this.statusCode = statusCode;
46
+ this.name = "NetworkError";
47
+ }
48
+ };
49
+ function createTypedError(code, message) {
50
+ if (code.startsWith("AUTH_")) {
51
+ return new AuthenticationError(code, message);
52
+ }
53
+ if (code.startsWith("LINK_") || code.startsWith("REDIRECTOR_") || code.startsWith("STREAM_") || code.startsWith("DELAYED_")) {
54
+ return new LinkError(code, message);
55
+ }
56
+ if (code.startsWith("MAGNET_")) {
57
+ return new MagnetError(code, message);
58
+ }
59
+ return new AllDebridError(code, message);
60
+ }
61
+
62
+ // src/base-resource.ts
63
+ var BaseResource = class {
64
+ constructor(client) {
65
+ this.client = client;
66
+ }
67
+ /**
68
+ * Make a GET request
69
+ * @param T - The generated response type (e.g., GetLinkUnlockResponse)
70
+ * @returns The extracted data from the response (without the { status, data } wrapper)
71
+ */
72
+ async get(path, params) {
73
+ const clientAny = this.client;
74
+ return clientAny.get(path, params);
75
+ }
76
+ /**
77
+ * Make a POST request
78
+ * @param T - The generated response type
79
+ * @returns The extracted data from the response (without the { status, data } wrapper)
80
+ */
81
+ async post(path, body, params) {
82
+ const clientAny = this.client;
83
+ return clientAny.post(path, body, params);
84
+ }
85
+ /**
86
+ * Make a POST request with FormData (multipart/form-data)
87
+ * @param T - The generated response type
88
+ * @returns The extracted data from the response (without the { status, data } wrapper)
89
+ */
90
+ async postFormData(path, formData, params) {
91
+ const clientAny = this.client;
92
+ return clientAny.postFormData(path, formData, params);
93
+ }
94
+ };
95
+
96
+ // src/resources/host.ts
97
+ var HostResource = class extends BaseResource {
98
+ /**
99
+ * Get list of all supported hosts with their information
100
+ *
101
+ * @param hostOnly - If true, only return hosts (exclude streams and redirectors)
102
+ *
103
+ * @example
104
+ * ```ts
105
+ * const hosts = await client.host.list()
106
+ * console.log(hosts.hosts) // All supported file hosts
107
+ * console.log(hosts.streams) // Streaming hosts
108
+ * console.log(hosts.redirectors) // Link redirectors
109
+ * ```
110
+ */
111
+ async list(hostOnly) {
112
+ const params = hostOnly ? { hostOnly: "1" } : void 0;
113
+ return this.get("/hosts", params);
114
+ }
115
+ /**
116
+ * Get array of all supported domain names
117
+ *
118
+ * @example
119
+ * ```ts
120
+ * const domains = await client.host.domains()
121
+ * console.log(domains) // ['rapidgator.net', 'uploaded.net', ...]
122
+ * ```
123
+ */
124
+ async domains() {
125
+ return this.get("/hosts/domains");
126
+ }
127
+ /**
128
+ * Get hosts ordered by restriction level (priority list)
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * const priority = await client.host.priority()
133
+ * console.log(priority.hosts) // Ordered list with restriction levels
134
+ * ```
135
+ */
136
+ async priority() {
137
+ return this.get("/hosts/priority");
138
+ }
139
+ };
140
+
141
+ // src/resources/link.ts
142
+ var LinkResource = class extends BaseResource {
143
+ /**
144
+ * Get information about one or more links
145
+ *
146
+ * @param links - Single link or array of links to get info for
147
+ *
148
+ * @example
149
+ * ```ts
150
+ * const info = await client.link.infos('https://example.com/file.zip')
151
+ * console.log(info)
152
+ * ```
153
+ */
154
+ async infos(links) {
155
+ const linksArray = Array.isArray(links) ? links : [links];
156
+ const data = await this.get("/link/infos", {
157
+ link: linksArray
158
+ });
159
+ return data?.infos;
160
+ }
161
+ /**
162
+ * Extract links from redirectors/link protectors
163
+ *
164
+ * @param link - The redirector link to extract from
165
+ *
166
+ * @example
167
+ * ```ts
168
+ * const links = await client.link.redirector('https://linkprotector.com/abc123')
169
+ * ```
170
+ */
171
+ async redirector(link) {
172
+ const data = await this.get("/link/redirector", {
173
+ link
174
+ });
175
+ return data?.links;
176
+ }
177
+ /**
178
+ * Unlock a download link
179
+ *
180
+ * @param link - The link to unlock
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * const result = await client.link.unlock('https://example.com/file.zip')
185
+ * if (result.link) {
186
+ * console.log('Direct link:', result.link)
187
+ * } else if (result.delayed) {
188
+ * // Handle delayed generation
189
+ * const delayedResult = await client.link.delayed(result.delayed)
190
+ * }
191
+ * ```
192
+ */
193
+ async unlock(link) {
194
+ return this.get("/link/unlock", {
195
+ link
196
+ });
197
+ }
198
+ /**
199
+ * Unlock a link and automatically poll if delayed
200
+ * Note: The API response format doesn't include a delayed field in the current OpenAPI spec.
201
+ * This method will be updated once the delayed mechanism is documented.
202
+ *
203
+ * @param link - The link to unlock
204
+ * @param _options - Polling options (currently unused)
205
+ *
206
+ * @example
207
+ * ```ts
208
+ * const result = await client.link.unlockWithPolling('https://example.com/file.zip')
209
+ * console.log('Direct link:', result.link)
210
+ * ```
211
+ */
212
+ async unlockWithPolling(link, _options = {}) {
213
+ return this.unlock(link);
214
+ }
215
+ /**
216
+ * Get streaming options for a generated link
217
+ *
218
+ * @param id - The generated link ID or streaming ID
219
+ *
220
+ * @example
221
+ * ```ts
222
+ * const streams = await client.link.streaming('abc123')
223
+ * ```
224
+ */
225
+ async streaming(id) {
226
+ return this.get("/link/streaming", {
227
+ id
228
+ });
229
+ }
230
+ /**
231
+ * Get the status/result of a delayed link generation
232
+ *
233
+ * @param id - The delayed generation ID
234
+ *
235
+ * @example
236
+ * ```ts
237
+ * const result = await client.link.delayed('delayed_id_123')
238
+ * ```
239
+ */
240
+ async delayed(id) {
241
+ return this.get("/link/delayed", {
242
+ id
243
+ });
244
+ }
245
+ };
246
+
247
+ // src/resources/magnet.ts
248
+ var MagnetResource = class extends BaseResource {
249
+ /**
250
+ * Upload magnets by URI or hash
251
+ *
252
+ * @param magnets - Single magnet URI/hash or array of magnets
253
+ *
254
+ * @example
255
+ * ```ts
256
+ * const result = await client.magnet.upload('magnet:?xt=urn:btih:...')
257
+ * console.log('Magnet ID:', result.magnets[0].id)
258
+ * ```
259
+ */
260
+ async upload(magnets) {
261
+ const magnetsArray = Array.isArray(magnets) ? magnets : [magnets];
262
+ return this.get("/magnet/upload", {
263
+ magnets: magnetsArray
264
+ });
265
+ }
266
+ /**
267
+ * Upload a torrent file
268
+ *
269
+ * @param file - The torrent file (Blob or File)
270
+ * @param filename - Optional filename (defaults to 'torrent.torrent' for Blob, or file.name for File)
271
+ *
272
+ * @example
273
+ * ```ts
274
+ * const file = new File([buffer], 'torrent.torrent')
275
+ * const result = await client.magnet.uploadFile(file)
276
+ *
277
+ * // Or with a Blob and custom filename
278
+ * const blob = new Blob([buffer])
279
+ * const result = await client.magnet.uploadFile(blob, 'my-torrent.torrent')
280
+ * ```
281
+ */
282
+ async uploadFile(file, filename) {
283
+ const formData = new FormData();
284
+ const actualFilename = filename || (file instanceof File ? file.name : "torrent.torrent");
285
+ formData.append("files[]", file, actualFilename);
286
+ return this.postFormData("/magnet/upload/file", formData);
287
+ }
288
+ /**
289
+ * Get the status of one or more magnets
290
+ *
291
+ * @param id - Optional magnet ID to get status for a specific magnet
292
+ *
293
+ * @example
294
+ * ```ts
295
+ * // Get all magnets status
296
+ * const allStatus = await client.magnet.status()
297
+ *
298
+ * // Get specific magnet status
299
+ * const status = await client.magnet.status('123')
300
+ * console.log(status.magnets[0]?.status) // 'Downloading', 'Ready', etc.
301
+ * ```
302
+ */
303
+ async status(id) {
304
+ const params = id ? { id } : void 0;
305
+ const data = await this.get("/magnet/status", params);
306
+ if (data?.magnets && !Array.isArray(data.magnets)) {
307
+ return {
308
+ ...data,
309
+ magnets: [data.magnets]
310
+ };
311
+ }
312
+ return data;
313
+ }
314
+ /**
315
+ * Delete a magnet
316
+ *
317
+ * @param id - The magnet ID to delete (string)
318
+ *
319
+ * @example
320
+ * ```ts
321
+ * await client.magnet.delete('123')
322
+ * ```
323
+ */
324
+ async delete(id) {
325
+ return this.get("/magnet/delete", {
326
+ id
327
+ });
328
+ }
329
+ /**
330
+ * Restart one or more failed magnets
331
+ *
332
+ * @param ids - Single magnet ID or array of magnet IDs to restart (strings)
333
+ *
334
+ * @example
335
+ * ```ts
336
+ * // Restart single magnet
337
+ * await client.magnet.restart('123')
338
+ *
339
+ * // Restart multiple magnets
340
+ * await client.magnet.restart(['123', '456'])
341
+ * ```
342
+ */
343
+ async restart(ids) {
344
+ const idsArray = Array.isArray(ids) ? ids : [ids];
345
+ return this.get("/magnet/restart", {
346
+ ids: idsArray
347
+ });
348
+ }
349
+ /**
350
+ * Check instant availability of magnets
351
+ *
352
+ * @param magnets - Single magnet hash or array of hashes
353
+ *
354
+ * @example
355
+ * ```ts
356
+ * const available = await client.magnet.instant(['hash1', 'hash2'])
357
+ * console.log(available.magnets)
358
+ * ```
359
+ */
360
+ async instant(magnets) {
361
+ const magnetsArray = Array.isArray(magnets) ? magnets : [magnets];
362
+ return this.get("/magnet/instant", {
363
+ magnets: magnetsArray
364
+ });
365
+ }
366
+ /**
367
+ * Watch a magnet's status with automatic polling
368
+ *
369
+ * @param id - The magnet ID to watch (string)
370
+ * @param options - Watch options
371
+ *
372
+ * @example
373
+ * ```ts
374
+ * await client.magnet.watch('123', {
375
+ * onUpdate: (status) => console.log('Status:', status.magnets[0]?.status),
376
+ * stopOnStatus: 'Ready'
377
+ * })
378
+ * ```
379
+ */
380
+ async watch(id, options = {}) {
381
+ const { interval = 3e3, maxAttempts = 0, onUpdate, stopOnStatus = "Ready" } = options;
382
+ let attempt = 0;
383
+ while (maxAttempts === 0 || attempt < maxAttempts) {
384
+ attempt++;
385
+ const status = await this.status(id);
386
+ onUpdate?.(status);
387
+ const magnet = status?.magnets?.[0];
388
+ if (magnet?.status === stopOnStatus) {
389
+ return status;
390
+ }
391
+ await new Promise((resolve) => setTimeout(resolve, interval));
392
+ }
393
+ throw new Error(
394
+ `Watch timeout: magnet did not reach '${stopOnStatus}' status after ${maxAttempts} attempts`
395
+ );
396
+ }
397
+ };
398
+
399
+ // src/resources/user.ts
400
+ var UserResource = class extends BaseResource {
401
+ /**
402
+ * Get user profile information including premium status and quotas
403
+ *
404
+ * @example
405
+ * ```ts
406
+ * const user = await client.user.getInfo()
407
+ * console.log(user.username, user.isPremium)
408
+ * ```
409
+ */
410
+ async getInfo() {
411
+ const data = await this.get("/user");
412
+ return data?.user;
413
+ }
414
+ /**
415
+ * Get available hosts for the current user based on their subscription
416
+ *
417
+ * @param hostOnly - If true, only return hosts data (exclude streams and redirectors)
418
+ *
419
+ * @example
420
+ * ```ts
421
+ * const hosts = await client.user.getHosts()
422
+ * console.log(Object.keys(hosts.hosts))
423
+ * ```
424
+ */
425
+ async getHosts(hostOnly) {
426
+ const params = hostOnly ? { hostOnly: "1" } : void 0;
427
+ return this.get("/user/hosts", params);
428
+ }
429
+ /**
430
+ * Clear a specific notification by code
431
+ *
432
+ * @param code - The notification code to clear
433
+ *
434
+ * @example
435
+ * ```ts
436
+ * await client.user.clearNotification('SOME_NOTIF_CODE')
437
+ * ```
438
+ */
439
+ async clearNotification(code) {
440
+ await this.get("/user/notification/clear", { code });
441
+ }
442
+ // ============================================
443
+ // Saved Links Management
444
+ // ============================================
445
+ /**
446
+ * Get all saved links
447
+ *
448
+ * @example
449
+ * ```ts
450
+ * const savedLinks = await client.user.getLinks()
451
+ * console.log(savedLinks.links)
452
+ * ```
453
+ */
454
+ async getLinks() {
455
+ return this.get("/user/links");
456
+ }
457
+ /**
458
+ * Save a link for later use
459
+ *
460
+ * @param link - The link to save
461
+ *
462
+ * @example
463
+ * ```ts
464
+ * await client.user.saveLink('https://example.com/file.zip')
465
+ * ```
466
+ */
467
+ async saveLink(link) {
468
+ return this.get("/user/links/save", { link });
469
+ }
470
+ /**
471
+ * Delete a saved link
472
+ *
473
+ * @param link - The link to delete (can be the saved link ID or URL)
474
+ *
475
+ * @example
476
+ * ```ts
477
+ * await client.user.deleteLink('saved-link-id')
478
+ * ```
479
+ */
480
+ async deleteLink(link) {
481
+ return this.get("/user/links/delete", { link });
482
+ }
483
+ // ============================================
484
+ // History Management
485
+ // ============================================
486
+ /**
487
+ * Get user history (if enabled in account settings)
488
+ *
489
+ * @example
490
+ * ```ts
491
+ * const history = await client.user.getHistory()
492
+ * console.log(history.links)
493
+ * ```
494
+ */
495
+ async getHistory() {
496
+ return this.get("/user/history");
497
+ }
498
+ /**
499
+ * Clear user history
500
+ *
501
+ * @example
502
+ * ```ts
503
+ * await client.user.clearHistory()
504
+ * ```
505
+ */
506
+ async clearHistory() {
507
+ return this.get("/user/history/delete");
508
+ }
509
+ };
510
+
511
+ // src/client.ts
512
+ var DEFAULT_BASE_URL = "https://api.alldebrid.com/v4";
513
+ var DEFAULT_AGENT = "@alldebrid/sdk";
514
+ var DEFAULT_TIMEOUT = 3e4;
515
+ var DEFAULT_MAX_RETRIES = 3;
516
+ var AllDebridClient = class {
517
+ config;
518
+ /**
519
+ * User resource for managing user account
520
+ */
521
+ user;
522
+ /**
523
+ * Link resource for unlocking and managing download links
524
+ */
525
+ link;
526
+ /**
527
+ * Magnet resource for managing torrents
528
+ */
529
+ magnet;
530
+ /**
531
+ * Host resource for getting information about supported hosts
532
+ */
533
+ host;
534
+ constructor(config) {
535
+ this.config = {
536
+ apiKey: config.apiKey,
537
+ agent: config.agent ?? DEFAULT_AGENT,
538
+ baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,
539
+ timeout: config.timeout ?? DEFAULT_TIMEOUT,
540
+ retry: config.retry ?? true,
541
+ maxRetries: config.maxRetries ?? DEFAULT_MAX_RETRIES
542
+ };
543
+ this.user = new UserResource(this);
544
+ this.link = new LinkResource(this);
545
+ this.magnet = new MagnetResource(this);
546
+ this.host = new HostResource(this);
547
+ }
548
+ /**
549
+ * Build query string from params
550
+ */
551
+ buildUrl(path, params) {
552
+ const allParams = {
553
+ agent: this.config.agent,
554
+ ...params
555
+ };
556
+ const query = new URLSearchParams();
557
+ for (const [key, value] of Object.entries(allParams)) {
558
+ if (value !== void 0 && value !== null) {
559
+ if (Array.isArray(value)) {
560
+ value.forEach((v) => query.append(`${key}[]`, String(v)));
561
+ } else {
562
+ query.append(key, String(value));
563
+ }
564
+ }
565
+ }
566
+ const queryString = query.toString();
567
+ return queryString ? `${path}?${queryString}` : path;
568
+ }
569
+ /**
570
+ * Make a GET request
571
+ * @param T - The generated response type (e.g., GetLinkUnlockResponse)
572
+ * @returns The extracted data from the response (without the { status, data } wrapper)
573
+ */
574
+ async get(path, params) {
575
+ try {
576
+ const url = this.buildUrl(path, params);
577
+ const json = await wretch(this.config.baseUrl).auth(`Bearer ${this.config.apiKey}`).url(url).get().json();
578
+ if (json.status === "error" && json.error) {
579
+ throw createTypedError(json.error.code, json.error.message);
580
+ }
581
+ return json.data;
582
+ } catch (error) {
583
+ if (error.status === 401) {
584
+ throw createTypedError("AUTH_BAD_APIKEY", "Invalid API key or unauthorized access");
585
+ }
586
+ if (error.status === 403) {
587
+ throw createTypedError("AUTH_BLOCKED", "Access forbidden");
588
+ }
589
+ if (error.status === 429) {
590
+ throw createTypedError("RATE_LIMITED", "Too many requests");
591
+ }
592
+ if (error.isAllDebridError) {
593
+ throw error;
594
+ }
595
+ throw new NetworkError(error.message || "Network error occurred", error.status);
596
+ }
597
+ }
598
+ /**
599
+ * Make a POST request
600
+ * @param T - The generated response type
601
+ * @returns The extracted data from the response (without the { status, data } wrapper)
602
+ */
603
+ async post(path, body, params) {
604
+ try {
605
+ const url = this.buildUrl(path, params);
606
+ const json = await wretch(this.config.baseUrl).auth(`Bearer ${this.config.apiKey}`).url(url).post(body).json();
607
+ if (json.status === "error" && json.error) {
608
+ throw createTypedError(json.error.code, json.error.message);
609
+ }
610
+ return json.data;
611
+ } catch (error) {
612
+ if (error.status === 401) {
613
+ throw createTypedError("AUTH_BAD_APIKEY", "Invalid API key or unauthorized access");
614
+ }
615
+ if (error.status === 403) {
616
+ throw createTypedError("AUTH_BLOCKED", "Access forbidden");
617
+ }
618
+ if (error.status === 429) {
619
+ throw createTypedError("RATE_LIMITED", "Too many requests");
620
+ }
621
+ if (error.isAllDebridError) {
622
+ throw error;
623
+ }
624
+ throw new NetworkError(error.message || "Network error occurred", error.status);
625
+ }
626
+ }
627
+ /**
628
+ * Make a POST request with FormData (multipart/form-data)
629
+ * @param T - The generated response type
630
+ * @returns The extracted data from the response (without the { status, data } wrapper)
631
+ */
632
+ async postFormData(path, formData, params) {
633
+ try {
634
+ const url = this.buildUrl(path, params);
635
+ const json = await wretch(this.config.baseUrl).auth(`Bearer ${this.config.apiKey}`).url(url).body(formData).post().json();
636
+ if (json.status === "error" && json.error) {
637
+ throw createTypedError(json.error.code, json.error.message);
638
+ }
639
+ return json.data;
640
+ } catch (error) {
641
+ if (error.status === 401) {
642
+ throw createTypedError("AUTH_BAD_APIKEY", "Invalid API key or unauthorized access");
643
+ }
644
+ if (error.status === 403) {
645
+ throw createTypedError("AUTH_BLOCKED", "Access forbidden");
646
+ }
647
+ if (error.status === 429) {
648
+ throw createTypedError("RATE_LIMITED", "Too many requests");
649
+ }
650
+ if (error.isAllDebridError) {
651
+ throw error;
652
+ }
653
+ throw new NetworkError(error.message || "Network error occurred", error.status);
654
+ }
655
+ }
656
+ /**
657
+ * Test the API connection
658
+ */
659
+ async ping() {
660
+ try {
661
+ await this.get("/user");
662
+ return true;
663
+ } catch {
664
+ return false;
665
+ }
666
+ }
667
+ };
668
+
669
+ export { AllDebridClient, AllDebridError, AuthenticationError, HostResource, LinkError, LinkResource, MagnetError, MagnetResource, NetworkError, UserResource, createTypedError };
670
+ //# sourceMappingURL=index.js.map
671
+ //# sourceMappingURL=index.js.map