@adbjs/sdk 0.1.1 → 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.
- package/README.md +336 -223
- package/dist/index.cjs +518 -81
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +885 -1025
- package/dist/index.d.ts +885 -1025
- package/dist/index.js +517 -82
- package/dist/index.js.map +1 -1
- package/package.json +66 -66
package/dist/index.cjs
CHANGED
|
@@ -72,30 +72,35 @@ var BaseResource = class {
|
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
74
74
|
* Make a GET request
|
|
75
|
-
* @
|
|
75
|
+
* @template T - The generated response type (e.g., GetLinkUnlockResponse)
|
|
76
|
+
* @param path - API endpoint path
|
|
77
|
+
* @param params - Optional query parameters
|
|
76
78
|
* @returns The extracted data from the response (without the { status, data } wrapper)
|
|
77
79
|
*/
|
|
78
80
|
async get(path, params) {
|
|
79
|
-
|
|
80
|
-
return clientAny.get(path, params);
|
|
81
|
+
return this.client.get(path, params);
|
|
81
82
|
}
|
|
82
83
|
/**
|
|
83
84
|
* Make a POST request
|
|
84
|
-
* @
|
|
85
|
+
* @template T - The generated response type
|
|
86
|
+
* @param path - API endpoint path
|
|
87
|
+
* @param body - Request body
|
|
88
|
+
* @param params - Optional query parameters
|
|
85
89
|
* @returns The extracted data from the response (without the { status, data } wrapper)
|
|
86
90
|
*/
|
|
87
91
|
async post(path, body, params) {
|
|
88
|
-
|
|
89
|
-
return clientAny.post(path, body, params);
|
|
92
|
+
return this.client.post(path, body, params);
|
|
90
93
|
}
|
|
91
94
|
/**
|
|
92
95
|
* Make a POST request with FormData (multipart/form-data)
|
|
93
|
-
* @
|
|
96
|
+
* @template T - The generated response type
|
|
97
|
+
* @param path - API endpoint path
|
|
98
|
+
* @param formData - Form data to send
|
|
99
|
+
* @param params - Optional query parameters
|
|
94
100
|
* @returns The extracted data from the response (without the { status, data } wrapper)
|
|
95
101
|
*/
|
|
96
102
|
async postFormData(path, formData, params) {
|
|
97
|
-
|
|
98
|
-
return clientAny.postFormData(path, formData, params);
|
|
103
|
+
return this.client.postFormData(path, formData, params);
|
|
99
104
|
}
|
|
100
105
|
};
|
|
101
106
|
|
|
@@ -150,19 +155,24 @@ var LinkResource = class extends BaseResource {
|
|
|
150
155
|
* Get information about one or more links
|
|
151
156
|
*
|
|
152
157
|
* @param links - Single link or array of links to get info for
|
|
158
|
+
* @param password - Optional password for password-protected links
|
|
153
159
|
*
|
|
154
160
|
* @example
|
|
155
161
|
* ```ts
|
|
156
|
-
* const
|
|
157
|
-
* console.log(
|
|
162
|
+
* const data = await client.link.infos('https://example.com/file.zip')
|
|
163
|
+
* console.log(data.infos)
|
|
164
|
+
*
|
|
165
|
+
* // With password
|
|
166
|
+
* const protectedData = await client.link.infos(
|
|
167
|
+
* 'https://example.com/protected.zip',
|
|
168
|
+
* 'mypassword'
|
|
169
|
+
* )
|
|
158
170
|
* ```
|
|
159
171
|
*/
|
|
160
|
-
async infos(links) {
|
|
172
|
+
async infos(links, password) {
|
|
161
173
|
const linksArray = Array.isArray(links) ? links : [links];
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
});
|
|
165
|
-
return data?.infos;
|
|
174
|
+
const params = password ? { password } : void 0;
|
|
175
|
+
return this.post("/link/infos", { "link[]": linksArray }, params);
|
|
166
176
|
}
|
|
167
177
|
/**
|
|
168
178
|
* Extract links from redirectors/link protectors
|
|
@@ -171,19 +181,20 @@ var LinkResource = class extends BaseResource {
|
|
|
171
181
|
*
|
|
172
182
|
* @example
|
|
173
183
|
* ```ts
|
|
174
|
-
* const
|
|
184
|
+
* const data = await client.link.redirector('https://linkprotector.com/abc123')
|
|
185
|
+
* console.log(data.links)
|
|
175
186
|
* ```
|
|
176
187
|
*/
|
|
177
188
|
async redirector(link) {
|
|
178
|
-
|
|
189
|
+
return this.post("/link/redirector", {
|
|
179
190
|
link
|
|
180
191
|
});
|
|
181
|
-
return data?.links;
|
|
182
192
|
}
|
|
183
193
|
/**
|
|
184
194
|
* Unlock a download link
|
|
185
195
|
*
|
|
186
196
|
* @param link - The link to unlock
|
|
197
|
+
* @param password - Optional password for password-protected links
|
|
187
198
|
*
|
|
188
199
|
* @example
|
|
189
200
|
* ```ts
|
|
@@ -194,12 +205,17 @@ var LinkResource = class extends BaseResource {
|
|
|
194
205
|
* // Handle delayed generation
|
|
195
206
|
* const delayedResult = await client.link.delayed(result.delayed)
|
|
196
207
|
* }
|
|
208
|
+
*
|
|
209
|
+
* // With password
|
|
210
|
+
* const protectedResult = await client.link.unlock(
|
|
211
|
+
* 'https://example.com/protected.zip',
|
|
212
|
+
* 'mypassword'
|
|
213
|
+
* )
|
|
197
214
|
* ```
|
|
198
215
|
*/
|
|
199
|
-
async unlock(link) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
});
|
|
216
|
+
async unlock(link, password) {
|
|
217
|
+
const params = password ? { password } : void 0;
|
|
218
|
+
return this.post("/link/unlock", { link }, params);
|
|
203
219
|
}
|
|
204
220
|
/**
|
|
205
221
|
* Unlock a link and automatically poll if delayed
|
|
@@ -228,9 +244,10 @@ var LinkResource = class extends BaseResource {
|
|
|
228
244
|
* const streams = await client.link.streaming('abc123')
|
|
229
245
|
* ```
|
|
230
246
|
*/
|
|
231
|
-
async streaming(id) {
|
|
232
|
-
return this.
|
|
233
|
-
id
|
|
247
|
+
async streaming(id, stream) {
|
|
248
|
+
return this.post("/link/streaming", {
|
|
249
|
+
id,
|
|
250
|
+
stream
|
|
234
251
|
});
|
|
235
252
|
}
|
|
236
253
|
/**
|
|
@@ -244,7 +261,7 @@ var LinkResource = class extends BaseResource {
|
|
|
244
261
|
* ```
|
|
245
262
|
*/
|
|
246
263
|
async delayed(id) {
|
|
247
|
-
return this.
|
|
264
|
+
return this.post("/link/delayed", {
|
|
248
265
|
id
|
|
249
266
|
});
|
|
250
267
|
}
|
|
@@ -265,7 +282,7 @@ var MagnetResource = class extends BaseResource {
|
|
|
265
282
|
*/
|
|
266
283
|
async upload(magnets) {
|
|
267
284
|
const magnetsArray = Array.isArray(magnets) ? magnets : [magnets];
|
|
268
|
-
return this.
|
|
285
|
+
return this.post("/magnet/upload", {
|
|
269
286
|
magnets: magnetsArray
|
|
270
287
|
});
|
|
271
288
|
}
|
|
@@ -292,23 +309,22 @@ var MagnetResource = class extends BaseResource {
|
|
|
292
309
|
return this.postFormData("/magnet/upload/file", formData);
|
|
293
310
|
}
|
|
294
311
|
/**
|
|
295
|
-
* Get the status of
|
|
312
|
+
* Get the status of a specific magnet by ID
|
|
296
313
|
*
|
|
297
|
-
* @param id -
|
|
314
|
+
* @param id - Magnet ID to get status for
|
|
298
315
|
*
|
|
299
316
|
* @example
|
|
300
317
|
* ```ts
|
|
301
|
-
*
|
|
302
|
-
* const allStatus = await client.magnet.status()
|
|
303
|
-
*
|
|
304
|
-
* // Get specific magnet status
|
|
305
|
-
* const status = await client.magnet.status('123')
|
|
318
|
+
* const status = await client.magnet.status(123)
|
|
306
319
|
* console.log(status.magnets[0]?.status) // 'Downloading', 'Ready', etc.
|
|
307
320
|
* ```
|
|
321
|
+
*
|
|
322
|
+
* @remarks
|
|
323
|
+
* This endpoint uses AllDebrid API v4.1 (POST method)
|
|
324
|
+
* Migrated from v4 GET endpoint which was deprecated on 2024-10-16
|
|
308
325
|
*/
|
|
309
326
|
async status(id) {
|
|
310
|
-
const
|
|
311
|
-
const data = await this.get("/magnet/status", params);
|
|
327
|
+
const data = await this.post("/magnet/status", { id });
|
|
312
328
|
if (data?.magnets && !Array.isArray(data.magnets)) {
|
|
313
329
|
return {
|
|
314
330
|
...data,
|
|
@@ -317,71 +333,215 @@ var MagnetResource = class extends BaseResource {
|
|
|
317
333
|
}
|
|
318
334
|
return data;
|
|
319
335
|
}
|
|
336
|
+
/**
|
|
337
|
+
* Get list of magnets with optional status filter
|
|
338
|
+
*
|
|
339
|
+
* @param statusFilter - Optional filter by status: 'active', 'ready', 'expired', or 'error'
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* ```ts
|
|
343
|
+
* // Get all magnets
|
|
344
|
+
* const allMagnets = await client.magnet.statusList()
|
|
345
|
+
*
|
|
346
|
+
* // Get only active magnets
|
|
347
|
+
* const activeMagnets = await client.magnet.statusList('active')
|
|
348
|
+
*
|
|
349
|
+
* // Get only ready magnets
|
|
350
|
+
* const readyMagnets = await client.magnet.statusList('ready')
|
|
351
|
+
* ```
|
|
352
|
+
*
|
|
353
|
+
* @remarks
|
|
354
|
+
* This endpoint uses AllDebrid API v4.1 (POST method)
|
|
355
|
+
*/
|
|
356
|
+
async statusList(statusFilter) {
|
|
357
|
+
const body = statusFilter ? { status: statusFilter } : void 0;
|
|
358
|
+
return this.post("/magnet/status", body);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Get magnet status using live mode for bandwidth-optimized delta synchronization
|
|
362
|
+
*
|
|
363
|
+
* Live mode is designed for monitoring multiple magnets efficiently by only transmitting
|
|
364
|
+
* changes between polling intervals, drastically reducing bandwidth usage for dashboards
|
|
365
|
+
* and real-time monitoring applications.
|
|
366
|
+
*
|
|
367
|
+
* ## How it works
|
|
368
|
+
*
|
|
369
|
+
* 1. **Session initialization**: Generate a random session ID and start with counter = 0
|
|
370
|
+
* 2. **First call (fullsync)**: Returns ALL magnets with `fullsync: true`
|
|
371
|
+
* 3. **Update counter**: Use the `counter` value returned by the API for the next call
|
|
372
|
+
* 4. **Subsequent calls (delta)**: Returns ONLY magnets that changed since last call
|
|
373
|
+
* 5. **Repeat**: Keep calling with updated counter to receive only deltas
|
|
374
|
+
*
|
|
375
|
+
* ## When to use
|
|
376
|
+
*
|
|
377
|
+
* - ✅ Monitoring multiple active magnets simultaneously
|
|
378
|
+
* - ✅ Building real-time dashboards
|
|
379
|
+
* - ✅ High-frequency polling scenarios (every few seconds)
|
|
380
|
+
* - ❌ Watching a single specific magnet (use `watch()` instead)
|
|
381
|
+
*
|
|
382
|
+
* ## Important notes
|
|
383
|
+
*
|
|
384
|
+
* - **Don't use the `id` parameter**: Passing an ID defeats the purpose of live mode
|
|
385
|
+
* as it disables delta sync and behaves like a regular `status()` call
|
|
386
|
+
* - **Session persistence**: Keep the same session ID for the entire monitoring session
|
|
387
|
+
* - **Counter tracking**: Always update the counter with the value returned by the API
|
|
388
|
+
* - **Empty deltas**: When no magnets changed, `magnets` will be an empty array
|
|
389
|
+
*
|
|
390
|
+
* @param options - Live mode session options
|
|
391
|
+
* @param options.session - Unique session ID (generate once: `Math.floor(Math.random() * 1000000)`)
|
|
392
|
+
* @param options.counter - Sync counter (start at 0, then use value from previous API response)
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* ```ts
|
|
396
|
+
* // Initialize session
|
|
397
|
+
* const session = Math.floor(Math.random() * 1000000)
|
|
398
|
+
* let counter = 0
|
|
399
|
+
*
|
|
400
|
+
* // First call - returns all magnets (fullsync: true)
|
|
401
|
+
* const firstCall = await client.magnet.statusLive({ session, counter })
|
|
402
|
+
* console.log('Full sync:', firstCall.fullsync) // true
|
|
403
|
+
* console.log('All magnets:', firstCall.magnets) // Array of all magnets
|
|
404
|
+
* counter = firstCall.counter // Update counter for next call
|
|
405
|
+
*
|
|
406
|
+
* // Second call - returns only magnets that changed
|
|
407
|
+
* await new Promise(resolve => setTimeout(resolve, 3000)) // Wait 3 seconds
|
|
408
|
+
* const secondCall = await client.magnet.statusLive({ session, counter })
|
|
409
|
+
* console.log('Delta sync:', secondCall.magnets) // Only changed magnets
|
|
410
|
+
* counter = secondCall.counter
|
|
411
|
+
*
|
|
412
|
+
* // Example: Monitor all magnets until none are active
|
|
413
|
+
* const activeMagnets = new Map()
|
|
414
|
+
*
|
|
415
|
+
* while (true) {
|
|
416
|
+
* const response = await client.magnet.statusLive({ session, counter })
|
|
417
|
+
* counter = response.counter ?? counter
|
|
418
|
+
*
|
|
419
|
+
* // Update our local state with changes
|
|
420
|
+
* if (response.fullsync) {
|
|
421
|
+
* activeMagnets.clear()
|
|
422
|
+
* response.magnets?.forEach(m => activeMagnets.set(m.id, m))
|
|
423
|
+
* } else {
|
|
424
|
+
* response.magnets?.forEach(m => {
|
|
425
|
+
* if (m.status === 'Ready' || m.status === 'Error' || m.status === 'Expired') {
|
|
426
|
+
* activeMagnets.delete(m.id)
|
|
427
|
+
* } else {
|
|
428
|
+
* activeMagnets.set(m.id, m)
|
|
429
|
+
* }
|
|
430
|
+
* })
|
|
431
|
+
* }
|
|
432
|
+
*
|
|
433
|
+
* // Display current state
|
|
434
|
+
* console.log(`Active downloads: ${activeMagnets.size}`)
|
|
435
|
+
* activeMagnets.forEach(m => {
|
|
436
|
+
* console.log(` ${m.filename}: ${m.status} - ${m.downloaded}/${m.size} bytes`)
|
|
437
|
+
* })
|
|
438
|
+
*
|
|
439
|
+
* // Stop when no more active magnets
|
|
440
|
+
* if (activeMagnets.size === 0) {
|
|
441
|
+
* console.log('All downloads completed!')
|
|
442
|
+
* break
|
|
443
|
+
* }
|
|
444
|
+
*
|
|
445
|
+
* await new Promise(resolve => setTimeout(resolve, 3000))
|
|
446
|
+
* }
|
|
447
|
+
* ```
|
|
448
|
+
*
|
|
449
|
+
* @remarks
|
|
450
|
+
* This method is ideal for scenarios where you're monitoring multiple magnets and want
|
|
451
|
+
* to minimize bandwidth. For simple single-magnet monitoring, use `watch()` instead.
|
|
452
|
+
*/
|
|
453
|
+
async statusLive(options) {
|
|
454
|
+
const body = {
|
|
455
|
+
session: options.session,
|
|
456
|
+
counter: options.counter
|
|
457
|
+
};
|
|
458
|
+
return this.post("/magnet/status", body);
|
|
459
|
+
}
|
|
320
460
|
/**
|
|
321
461
|
* Delete a magnet
|
|
322
462
|
*
|
|
323
|
-
* @param id - The magnet ID to delete
|
|
463
|
+
* @param id - The magnet ID to delete
|
|
324
464
|
*
|
|
325
465
|
* @example
|
|
326
466
|
* ```ts
|
|
327
|
-
* await client.magnet.delete(
|
|
467
|
+
* await client.magnet.delete(123)
|
|
328
468
|
* ```
|
|
329
469
|
*/
|
|
330
470
|
async delete(id) {
|
|
331
|
-
return this.
|
|
471
|
+
return this.post("/magnet/delete", {
|
|
332
472
|
id
|
|
333
473
|
});
|
|
334
474
|
}
|
|
335
475
|
/**
|
|
336
476
|
* Restart one or more failed magnets
|
|
337
477
|
*
|
|
338
|
-
* @param ids - Single magnet ID or array of magnet IDs to restart (
|
|
478
|
+
* @param ids - Single magnet ID or array of magnet IDs to restart (numbers)
|
|
339
479
|
*
|
|
340
480
|
* @example
|
|
341
481
|
* ```ts
|
|
342
482
|
* // Restart single magnet
|
|
343
|
-
* await client.magnet.restart(
|
|
483
|
+
* await client.magnet.restart(123)
|
|
344
484
|
*
|
|
345
485
|
* // Restart multiple magnets
|
|
346
|
-
* await client.magnet.restart([
|
|
486
|
+
* await client.magnet.restart([123, 456])
|
|
347
487
|
* ```
|
|
348
488
|
*/
|
|
349
489
|
async restart(ids) {
|
|
350
490
|
const idsArray = Array.isArray(ids) ? ids : [ids];
|
|
351
|
-
return this.
|
|
491
|
+
return this.post("/magnet/restart", {
|
|
352
492
|
ids: idsArray
|
|
353
493
|
});
|
|
354
494
|
}
|
|
355
495
|
/**
|
|
356
|
-
*
|
|
496
|
+
* Get files for a completed magnet
|
|
357
497
|
*
|
|
358
|
-
* @param
|
|
498
|
+
* @param ids - The magnet ID or IDs to get files for
|
|
359
499
|
*
|
|
360
500
|
* @example
|
|
361
501
|
* ```ts
|
|
362
|
-
* const
|
|
363
|
-
*
|
|
502
|
+
* const data = await client.magnet.files(123)
|
|
503
|
+
* data?.magnets?.forEach(magnet => {
|
|
504
|
+
* console.log(magnet.filename, magnet.files)
|
|
505
|
+
* })
|
|
364
506
|
* ```
|
|
507
|
+
*
|
|
508
|
+
* @remarks
|
|
509
|
+
* Files are now retrieved separately from magnet status (since v4.1)
|
|
510
|
+
* Only available for magnets with status 'Ready'
|
|
365
511
|
*/
|
|
366
|
-
async
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
512
|
+
async files(ids) {
|
|
513
|
+
const formData = new FormData();
|
|
514
|
+
const idsArray = Array.isArray(ids) ? ids : [ids];
|
|
515
|
+
for (const id of idsArray) {
|
|
516
|
+
formData.append("id[]", String(id));
|
|
517
|
+
}
|
|
518
|
+
return this.postFormData("/magnet/files", formData);
|
|
371
519
|
}
|
|
372
520
|
/**
|
|
373
521
|
* Watch a magnet's status with automatic polling
|
|
374
522
|
*
|
|
375
|
-
*
|
|
523
|
+
* This is a simple helper that polls the status of a specific magnet until it reaches
|
|
524
|
+
* a target status (default: 'Ready'). For advanced use cases with multiple magnets
|
|
525
|
+
* or bandwidth optimization, use `statusLive()` directly instead.
|
|
526
|
+
*
|
|
527
|
+
* @param id - The magnet ID to watch
|
|
376
528
|
* @param options - Watch options
|
|
529
|
+
* @param options.interval - Polling interval in milliseconds (default: 3000)
|
|
530
|
+
* @param options.maxAttempts - Maximum polling attempts, 0 for infinite (default: 0)
|
|
531
|
+
* @param options.onUpdate - Callback called on each status update
|
|
532
|
+
* @param options.stopOnStatus - Stop when magnet reaches this status (default: 'Ready')
|
|
377
533
|
*
|
|
378
534
|
* @example
|
|
379
535
|
* ```ts
|
|
380
|
-
* await client.magnet.watch(
|
|
536
|
+
* await client.magnet.watch(123, {
|
|
381
537
|
* onUpdate: (status) => console.log('Status:', status.magnets[0]?.status),
|
|
382
538
|
* stopOnStatus: 'Ready'
|
|
383
539
|
* })
|
|
384
540
|
* ```
|
|
541
|
+
*
|
|
542
|
+
* @remarks
|
|
543
|
+
* For monitoring multiple magnets efficiently, use `statusLive()` directly.
|
|
544
|
+
* See the `statusLive()` documentation for details on delta synchronization.
|
|
385
545
|
*/
|
|
386
546
|
async watch(id, options = {}) {
|
|
387
547
|
const { interval = 3e3, maxAttempts = 0, onUpdate, stopOnStatus = "Ready" } = options;
|
|
@@ -402,6 +562,111 @@ var MagnetResource = class extends BaseResource {
|
|
|
402
562
|
}
|
|
403
563
|
};
|
|
404
564
|
|
|
565
|
+
// src/resources/pin.ts
|
|
566
|
+
var PinResource = class extends BaseResource {
|
|
567
|
+
/**
|
|
568
|
+
* Generate a new PIN code for authentication
|
|
569
|
+
*
|
|
570
|
+
* This initiates the PIN authentication flow. The user should visit the
|
|
571
|
+
* returned URL to authorize the application.
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* ```ts
|
|
575
|
+
* const pinData = await client.pin.generate()
|
|
576
|
+
* console.log('Visit:', pinData.user_url)
|
|
577
|
+
* console.log('PIN:', pinData.pin)
|
|
578
|
+
*
|
|
579
|
+
* // Poll the check endpoint until user authorizes
|
|
580
|
+
* const auth = await client.pin.check(pinData.check, pinData.pin)
|
|
581
|
+
* if (auth.activated) {
|
|
582
|
+
* console.log('API Key:', auth.apikey)
|
|
583
|
+
* }
|
|
584
|
+
* ```
|
|
585
|
+
*
|
|
586
|
+
* @returns PIN code and authorization URL
|
|
587
|
+
*/
|
|
588
|
+
async generate() {
|
|
589
|
+
return super.get("/pin/get");
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Check the status of a PIN authentication
|
|
593
|
+
*
|
|
594
|
+
* Poll this endpoint to check if the user has authorized the application.
|
|
595
|
+
* Once authorized, the response will include the API key.
|
|
596
|
+
*
|
|
597
|
+
* @param check - Check ID from /pin/get
|
|
598
|
+
* @param pin - PIN code from /pin/get
|
|
599
|
+
*
|
|
600
|
+
* @example
|
|
601
|
+
* ```ts
|
|
602
|
+
* const pinData = await client.pin.generate()
|
|
603
|
+
*
|
|
604
|
+
* // Poll every few seconds until activated
|
|
605
|
+
* const checkStatus = async () => {
|
|
606
|
+
* const result = await client.pin.check(pinData.check, pinData.pin)
|
|
607
|
+
* if (result?.activated && result?.apikey) {
|
|
608
|
+
* console.log('Authorized! API Key:', result.apikey)
|
|
609
|
+
* return result.apikey
|
|
610
|
+
* }
|
|
611
|
+
* // Wait and try again
|
|
612
|
+
* await new Promise(resolve => setTimeout(resolve, 3000))
|
|
613
|
+
* return checkStatus()
|
|
614
|
+
* }
|
|
615
|
+
*
|
|
616
|
+
* const apikey = await checkStatus()
|
|
617
|
+
* ```
|
|
618
|
+
*
|
|
619
|
+
* @returns Authorization status and API key (if activated)
|
|
620
|
+
*/
|
|
621
|
+
async check(check, pin) {
|
|
622
|
+
return super.get("/pin/check", { check, pin });
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Helper method to wait for PIN authorization with automatic polling
|
|
626
|
+
*
|
|
627
|
+
* This method handles the polling logic for you, making it easier to
|
|
628
|
+
* implement the PIN authentication flow.
|
|
629
|
+
*
|
|
630
|
+
* @param check - Check ID from /pin/get
|
|
631
|
+
* @param pin - PIN code from /pin/get
|
|
632
|
+
* @param options - Polling options
|
|
633
|
+
* @param options.timeout - Maximum time to wait in milliseconds (default: 600000 = 10 minutes)
|
|
634
|
+
* @param options.interval - Polling interval in milliseconds (default: 3000 = 3 seconds)
|
|
635
|
+
*
|
|
636
|
+
* @example
|
|
637
|
+
* ```ts
|
|
638
|
+
* const pinData = await client.pin.generate()
|
|
639
|
+
* console.log('Visit:', pinData.user_url)
|
|
640
|
+
*
|
|
641
|
+
* try {
|
|
642
|
+
* const apikey = await client.pin.waitForAuth(pinData.check, pinData.pin, {
|
|
643
|
+
* timeout: 600000, // 10 minutes
|
|
644
|
+
* interval: 3000, // Check every 3 seconds
|
|
645
|
+
* })
|
|
646
|
+
* console.log('Authorized! API Key:', apikey)
|
|
647
|
+
* } catch (error) {
|
|
648
|
+
* console.error('Authorization timed out or failed')
|
|
649
|
+
* }
|
|
650
|
+
* ```
|
|
651
|
+
*
|
|
652
|
+
* @returns The API key once authorized
|
|
653
|
+
* @throws Error if timeout is reached or authorization fails
|
|
654
|
+
*/
|
|
655
|
+
async waitForAuth(check, pin, options = {}) {
|
|
656
|
+
const timeout = options.timeout ?? 6e5;
|
|
657
|
+
const interval = options.interval ?? 3e3;
|
|
658
|
+
const startTime = Date.now();
|
|
659
|
+
while (Date.now() - startTime < timeout) {
|
|
660
|
+
const result = await this.check(check, pin);
|
|
661
|
+
if (result?.activated && result?.apikey) {
|
|
662
|
+
return result.apikey;
|
|
663
|
+
}
|
|
664
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
665
|
+
}
|
|
666
|
+
throw new Error("PIN authorization timeout - user did not authorize within the time limit");
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
|
|
405
670
|
// src/resources/user.ts
|
|
406
671
|
var UserResource = class extends BaseResource {
|
|
407
672
|
/**
|
|
@@ -409,13 +674,12 @@ var UserResource = class extends BaseResource {
|
|
|
409
674
|
*
|
|
410
675
|
* @example
|
|
411
676
|
* ```ts
|
|
412
|
-
* const
|
|
413
|
-
* console.log(user.username, user.isPremium)
|
|
677
|
+
* const data = await client.user.getInfo()
|
|
678
|
+
* console.log(data.user.username, data.user.isPremium)
|
|
414
679
|
* ```
|
|
415
680
|
*/
|
|
416
681
|
async getInfo() {
|
|
417
|
-
|
|
418
|
-
return data?.user;
|
|
682
|
+
return this.get("/user");
|
|
419
683
|
}
|
|
420
684
|
/**
|
|
421
685
|
* Get available hosts for the current user based on their subscription
|
|
@@ -443,7 +707,7 @@ var UserResource = class extends BaseResource {
|
|
|
443
707
|
* ```
|
|
444
708
|
*/
|
|
445
709
|
async clearNotification(code) {
|
|
446
|
-
await this.
|
|
710
|
+
await this.post("/user/notification/clear", { code });
|
|
447
711
|
}
|
|
448
712
|
// ============================================
|
|
449
713
|
// Saved Links Management
|
|
@@ -461,30 +725,60 @@ var UserResource = class extends BaseResource {
|
|
|
461
725
|
return this.get("/user/links");
|
|
462
726
|
}
|
|
463
727
|
/**
|
|
464
|
-
* Save
|
|
728
|
+
* Save one or multiple links for later use
|
|
465
729
|
*
|
|
466
|
-
*
|
|
730
|
+
* Supports batch operations - you can save multiple links in a single request.
|
|
731
|
+
*
|
|
732
|
+
* @param links - Single link or array of links to save
|
|
467
733
|
*
|
|
468
734
|
* @example
|
|
469
735
|
* ```ts
|
|
736
|
+
* // Save single link
|
|
470
737
|
* await client.user.saveLink('https://example.com/file.zip')
|
|
738
|
+
*
|
|
739
|
+
* // Save multiple links at once
|
|
740
|
+
* await client.user.saveLink([
|
|
741
|
+
* 'https://example.com/file1.zip',
|
|
742
|
+
* 'https://example.com/file2.zip',
|
|
743
|
+
* 'https://example.com/file3.zip'
|
|
744
|
+
* ])
|
|
471
745
|
* ```
|
|
472
746
|
*/
|
|
473
|
-
async saveLink(
|
|
474
|
-
|
|
747
|
+
async saveLink(links) {
|
|
748
|
+
const linksArray = Array.isArray(links) ? links : [links];
|
|
749
|
+
const formData = new FormData();
|
|
750
|
+
for (const link of linksArray) {
|
|
751
|
+
formData.append("links[]", link);
|
|
752
|
+
}
|
|
753
|
+
return this.postFormData("/user/links/save", formData);
|
|
475
754
|
}
|
|
476
755
|
/**
|
|
477
|
-
* Delete
|
|
756
|
+
* Delete one or multiple saved links
|
|
478
757
|
*
|
|
479
|
-
*
|
|
758
|
+
* Supports batch operations - you can delete multiple links in a single request.
|
|
759
|
+
*
|
|
760
|
+
* @param links - Single link or array of links to delete (can be saved link IDs or URLs)
|
|
480
761
|
*
|
|
481
762
|
* @example
|
|
482
763
|
* ```ts
|
|
764
|
+
* // Delete single link
|
|
483
765
|
* await client.user.deleteLink('saved-link-id')
|
|
766
|
+
*
|
|
767
|
+
* // Delete multiple links at once
|
|
768
|
+
* await client.user.deleteLink([
|
|
769
|
+
* 'saved-link-id-1',
|
|
770
|
+
* 'saved-link-id-2',
|
|
771
|
+
* 'saved-link-id-3'
|
|
772
|
+
* ])
|
|
484
773
|
* ```
|
|
485
774
|
*/
|
|
486
|
-
async deleteLink(
|
|
487
|
-
|
|
775
|
+
async deleteLink(links) {
|
|
776
|
+
const linksArray = Array.isArray(links) ? links : [links];
|
|
777
|
+
const formData = new FormData();
|
|
778
|
+
for (const link of linksArray) {
|
|
779
|
+
formData.append("links[]", link);
|
|
780
|
+
}
|
|
781
|
+
return this.postFormData("/user/links/delete", formData);
|
|
488
782
|
}
|
|
489
783
|
// ============================================
|
|
490
784
|
// History Management
|
|
@@ -510,12 +804,114 @@ var UserResource = class extends BaseResource {
|
|
|
510
804
|
* ```
|
|
511
805
|
*/
|
|
512
806
|
async clearHistory() {
|
|
513
|
-
return this.
|
|
807
|
+
return this.post("/user/history/delete");
|
|
808
|
+
}
|
|
809
|
+
// ============================================
|
|
810
|
+
// Email Verification
|
|
811
|
+
// ============================================
|
|
812
|
+
/**
|
|
813
|
+
* Check email verification status
|
|
814
|
+
*
|
|
815
|
+
* @param token - Verification token
|
|
816
|
+
*
|
|
817
|
+
* @example
|
|
818
|
+
* ```ts
|
|
819
|
+
* const status = await client.user.getVerificationStatus('verification-token')
|
|
820
|
+
* console.log(status.verif) // 'waiting', 'allowed', or 'denied'
|
|
821
|
+
* ```
|
|
822
|
+
*/
|
|
823
|
+
async getVerificationStatus(token) {
|
|
824
|
+
return this.post("/user/verif", void 0, { token });
|
|
825
|
+
}
|
|
826
|
+
/**
|
|
827
|
+
* Resend verification email
|
|
828
|
+
*
|
|
829
|
+
* @param token - Verification token
|
|
830
|
+
*
|
|
831
|
+
* @example
|
|
832
|
+
* ```ts
|
|
833
|
+
* await client.user.resendVerification('verification-token')
|
|
834
|
+
* ```
|
|
835
|
+
*/
|
|
836
|
+
async resendVerification(token) {
|
|
837
|
+
return this.post("/user/verif/resend", void 0, { token });
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
|
|
841
|
+
// src/resources/voucher.ts
|
|
842
|
+
var VoucherResource = class extends BaseResource {
|
|
843
|
+
/**
|
|
844
|
+
* Get voucher balance for reseller accounts
|
|
845
|
+
*
|
|
846
|
+
* This endpoint allows resellers to check their remaining voucher balance.
|
|
847
|
+
* Only available for accounts with reseller privileges.
|
|
848
|
+
*
|
|
849
|
+
* @example
|
|
850
|
+
* ```ts
|
|
851
|
+
* const balance = await client.voucher.getBalance()
|
|
852
|
+
* console.log('Remaining balance:', balance.balance, '€')
|
|
853
|
+
* ```
|
|
854
|
+
*
|
|
855
|
+
* @returns Voucher balance information
|
|
856
|
+
*/
|
|
857
|
+
async getBalance() {
|
|
858
|
+
return this.get("/voucher/balance");
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Retrieve existing vouchers from reseller inventory
|
|
862
|
+
*
|
|
863
|
+
* This endpoint retrieves vouchers that were previously generated
|
|
864
|
+
* and are available in your inventory.
|
|
865
|
+
*
|
|
866
|
+
* @param quantity - Optional number of vouchers to retrieve
|
|
867
|
+
*
|
|
868
|
+
* @example
|
|
869
|
+
* ```ts
|
|
870
|
+
* // Get all available vouchers
|
|
871
|
+
* const allVouchers = await client.voucher.getVouchers()
|
|
872
|
+
* console.log('Vouchers:', allVouchers?.codes)
|
|
873
|
+
*
|
|
874
|
+
* // Get specific quantity
|
|
875
|
+
* const fiveVouchers = await client.voucher.getVouchers(5)
|
|
876
|
+
* ```
|
|
877
|
+
*
|
|
878
|
+
* @returns List of voucher codes
|
|
879
|
+
*/
|
|
880
|
+
async getVouchers(quantity) {
|
|
881
|
+
const params = quantity ? { quantity } : void 0;
|
|
882
|
+
return this.get("/voucher/get", params);
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Generate new vouchers (deducts from reseller balance)
|
|
886
|
+
*
|
|
887
|
+
* This endpoint creates new vouchers and deducts the cost from your
|
|
888
|
+
* reseller account balance.
|
|
889
|
+
*
|
|
890
|
+
* @param quantity - Number of vouchers to generate
|
|
891
|
+
* @param duration - Voucher duration in days
|
|
892
|
+
*
|
|
893
|
+
* @example
|
|
894
|
+
* ```ts
|
|
895
|
+
* // Generate 10 vouchers valid for 30 days
|
|
896
|
+
* const vouchers = await client.voucher.generateVouchers(10, 30)
|
|
897
|
+
* console.log('Generated vouchers:', vouchers?.codes)
|
|
898
|
+
*
|
|
899
|
+
* // Generate 5 vouchers valid for 7 days
|
|
900
|
+
* const weekVouchers = await client.voucher.generateVouchers(5, 7)
|
|
901
|
+
* ```
|
|
902
|
+
*
|
|
903
|
+
* @returns List of newly generated voucher codes
|
|
904
|
+
*/
|
|
905
|
+
async generateVouchers(quantity, duration) {
|
|
906
|
+
return this.post("/voucher/generate", {
|
|
907
|
+
quantity,
|
|
908
|
+
duration
|
|
909
|
+
});
|
|
514
910
|
}
|
|
515
911
|
};
|
|
516
912
|
|
|
517
913
|
// src/client.ts
|
|
518
|
-
var DEFAULT_BASE_URL = "https://api.alldebrid.com/v4";
|
|
914
|
+
var DEFAULT_BASE_URL = "https://api.alldebrid.com/v4.1";
|
|
519
915
|
var DEFAULT_AGENT = "@alldebrid/sdk";
|
|
520
916
|
var DEFAULT_TIMEOUT = 3e4;
|
|
521
917
|
var DEFAULT_MAX_RETRIES = 3;
|
|
@@ -537,6 +933,14 @@ var AllDebridClient = class {
|
|
|
537
933
|
* Host resource for getting information about supported hosts
|
|
538
934
|
*/
|
|
539
935
|
host;
|
|
936
|
+
/**
|
|
937
|
+
* Pin resource for PIN-based authentication
|
|
938
|
+
*/
|
|
939
|
+
pin;
|
|
940
|
+
/**
|
|
941
|
+
* Voucher resource for reseller voucher management
|
|
942
|
+
*/
|
|
943
|
+
voucher;
|
|
540
944
|
constructor(config) {
|
|
541
945
|
this.config = {
|
|
542
946
|
apiKey: config.apiKey,
|
|
@@ -550,6 +954,8 @@ var AllDebridClient = class {
|
|
|
550
954
|
this.link = new LinkResource(this);
|
|
551
955
|
this.magnet = new MagnetResource(this);
|
|
552
956
|
this.host = new HostResource(this);
|
|
957
|
+
this.pin = new PinResource(this);
|
|
958
|
+
this.voucher = new VoucherResource(this);
|
|
553
959
|
}
|
|
554
960
|
/**
|
|
555
961
|
* Build query string from params
|
|
@@ -574,8 +980,11 @@ var AllDebridClient = class {
|
|
|
574
980
|
}
|
|
575
981
|
/**
|
|
576
982
|
* Make a GET request
|
|
577
|
-
* @
|
|
983
|
+
* @template T - The generated response type (e.g., GetLinkUnlockResponse)
|
|
984
|
+
* @param path - API endpoint path
|
|
985
|
+
* @param params - Optional query parameters
|
|
578
986
|
* @returns The extracted data from the response (without the { status, data } wrapper)
|
|
987
|
+
* @internal
|
|
579
988
|
*/
|
|
580
989
|
async get(path, params) {
|
|
581
990
|
try {
|
|
@@ -602,14 +1011,30 @@ var AllDebridClient = class {
|
|
|
602
1011
|
}
|
|
603
1012
|
}
|
|
604
1013
|
/**
|
|
605
|
-
* Make a POST request
|
|
606
|
-
* @
|
|
1014
|
+
* Make a POST request with application/x-www-form-urlencoded
|
|
1015
|
+
* @template T - The generated response type
|
|
1016
|
+
* @param path - API endpoint path
|
|
1017
|
+
* @param body - Request body (will be converted to URLSearchParams)
|
|
1018
|
+
* @param params - Optional query parameters
|
|
607
1019
|
* @returns The extracted data from the response (without the { status, data } wrapper)
|
|
1020
|
+
* @internal
|
|
608
1021
|
*/
|
|
609
1022
|
async post(path, body, params) {
|
|
610
1023
|
try {
|
|
611
1024
|
const url = this.buildUrl(path, params);
|
|
612
|
-
const
|
|
1025
|
+
const formData = new URLSearchParams();
|
|
1026
|
+
if (body && typeof body === "object") {
|
|
1027
|
+
for (const [key, value] of Object.entries(body)) {
|
|
1028
|
+
if (value !== void 0 && value !== null) {
|
|
1029
|
+
if (Array.isArray(value)) {
|
|
1030
|
+
value.forEach((v) => formData.append(key, String(v)));
|
|
1031
|
+
} else {
|
|
1032
|
+
formData.append(key, String(value));
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
const json = await wretch__default.default(this.config.baseUrl).auth(`Bearer ${this.config.apiKey}`).url(url).body(formData).post().json();
|
|
613
1038
|
if (json.status === "error" && json.error) {
|
|
614
1039
|
throw createTypedError(json.error.code, json.error.message);
|
|
615
1040
|
}
|
|
@@ -632,8 +1057,12 @@ var AllDebridClient = class {
|
|
|
632
1057
|
}
|
|
633
1058
|
/**
|
|
634
1059
|
* Make a POST request with FormData (multipart/form-data)
|
|
635
|
-
* @
|
|
1060
|
+
* @template T - The generated response type
|
|
1061
|
+
* @param path - API endpoint path
|
|
1062
|
+
* @param formData - Form data to send
|
|
1063
|
+
* @param params - Optional query parameters
|
|
636
1064
|
* @returns The extracted data from the response (without the { status, data } wrapper)
|
|
1065
|
+
* @internal
|
|
637
1066
|
*/
|
|
638
1067
|
async postFormData(path, formData, params) {
|
|
639
1068
|
try {
|
|
@@ -661,14 +1090,20 @@ var AllDebridClient = class {
|
|
|
661
1090
|
}
|
|
662
1091
|
/**
|
|
663
1092
|
* Test the API connection
|
|
1093
|
+
*
|
|
1094
|
+
* This endpoint doesn't require authentication and can be used to verify
|
|
1095
|
+
* that the AllDebrid API is reachable.
|
|
1096
|
+
*
|
|
1097
|
+
* @example
|
|
1098
|
+
* ```ts
|
|
1099
|
+
* const result = await client.ping()
|
|
1100
|
+
* console.log(result.ping) // 'pong'
|
|
1101
|
+
* ```
|
|
1102
|
+
*
|
|
1103
|
+
* @returns Ping response with 'pong' message
|
|
664
1104
|
*/
|
|
665
1105
|
async ping() {
|
|
666
|
-
|
|
667
|
-
await this.get("/user");
|
|
668
|
-
return true;
|
|
669
|
-
} catch {
|
|
670
|
-
return false;
|
|
671
|
-
}
|
|
1106
|
+
return this.get("/ping");
|
|
672
1107
|
}
|
|
673
1108
|
};
|
|
674
1109
|
|
|
@@ -681,7 +1116,9 @@ exports.LinkResource = LinkResource;
|
|
|
681
1116
|
exports.MagnetError = MagnetError;
|
|
682
1117
|
exports.MagnetResource = MagnetResource;
|
|
683
1118
|
exports.NetworkError = NetworkError;
|
|
1119
|
+
exports.PinResource = PinResource;
|
|
684
1120
|
exports.UserResource = UserResource;
|
|
1121
|
+
exports.VoucherResource = VoucherResource;
|
|
685
1122
|
exports.createTypedError = createTypedError;
|
|
686
1123
|
//# sourceMappingURL=index.cjs.map
|
|
687
1124
|
//# sourceMappingURL=index.cjs.map
|