@adbjs/sdk 0.1.1 → 1.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 +481 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +830 -1019
- package/dist/index.d.ts +830 -1019
- package/dist/index.js +480 -75
- 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,18 +155,28 @@ 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
162
|
* const info = await client.link.infos('https://example.com/file.zip')
|
|
157
163
|
* console.log(info)
|
|
164
|
+
*
|
|
165
|
+
* // With password
|
|
166
|
+
* const protectedInfo = 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
|
-
|
|
174
|
+
const params = password ? { password } : void 0;
|
|
175
|
+
const data = await this.post(
|
|
176
|
+
"/link/infos",
|
|
177
|
+
{ "link[]": linksArray },
|
|
178
|
+
params
|
|
179
|
+
);
|
|
165
180
|
return data?.infos;
|
|
166
181
|
}
|
|
167
182
|
/**
|
|
@@ -175,7 +190,7 @@ var LinkResource = class extends BaseResource {
|
|
|
175
190
|
* ```
|
|
176
191
|
*/
|
|
177
192
|
async redirector(link) {
|
|
178
|
-
const data = await this.
|
|
193
|
+
const data = await this.post("/link/redirector", {
|
|
179
194
|
link
|
|
180
195
|
});
|
|
181
196
|
return data?.links;
|
|
@@ -184,6 +199,7 @@ var LinkResource = class extends BaseResource {
|
|
|
184
199
|
* Unlock a download link
|
|
185
200
|
*
|
|
186
201
|
* @param link - The link to unlock
|
|
202
|
+
* @param password - Optional password for password-protected links
|
|
187
203
|
*
|
|
188
204
|
* @example
|
|
189
205
|
* ```ts
|
|
@@ -194,12 +210,17 @@ var LinkResource = class extends BaseResource {
|
|
|
194
210
|
* // Handle delayed generation
|
|
195
211
|
* const delayedResult = await client.link.delayed(result.delayed)
|
|
196
212
|
* }
|
|
213
|
+
*
|
|
214
|
+
* // With password
|
|
215
|
+
* const protectedResult = await client.link.unlock(
|
|
216
|
+
* 'https://example.com/protected.zip',
|
|
217
|
+
* 'mypassword'
|
|
218
|
+
* )
|
|
197
219
|
* ```
|
|
198
220
|
*/
|
|
199
|
-
async unlock(link) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
});
|
|
221
|
+
async unlock(link, password) {
|
|
222
|
+
const params = password ? { password } : void 0;
|
|
223
|
+
return this.post("/link/unlock", { link }, params);
|
|
203
224
|
}
|
|
204
225
|
/**
|
|
205
226
|
* Unlock a link and automatically poll if delayed
|
|
@@ -228,9 +249,10 @@ var LinkResource = class extends BaseResource {
|
|
|
228
249
|
* const streams = await client.link.streaming('abc123')
|
|
229
250
|
* ```
|
|
230
251
|
*/
|
|
231
|
-
async streaming(id) {
|
|
232
|
-
return this.
|
|
233
|
-
id
|
|
252
|
+
async streaming(id, stream) {
|
|
253
|
+
return this.post("/link/streaming", {
|
|
254
|
+
id,
|
|
255
|
+
stream
|
|
234
256
|
});
|
|
235
257
|
}
|
|
236
258
|
/**
|
|
@@ -244,7 +266,7 @@ var LinkResource = class extends BaseResource {
|
|
|
244
266
|
* ```
|
|
245
267
|
*/
|
|
246
268
|
async delayed(id) {
|
|
247
|
-
return this.
|
|
269
|
+
return this.post("/link/delayed", {
|
|
248
270
|
id
|
|
249
271
|
});
|
|
250
272
|
}
|
|
@@ -265,7 +287,7 @@ var MagnetResource = class extends BaseResource {
|
|
|
265
287
|
*/
|
|
266
288
|
async upload(magnets) {
|
|
267
289
|
const magnetsArray = Array.isArray(magnets) ? magnets : [magnets];
|
|
268
|
-
return this.
|
|
290
|
+
return this.post("/magnet/upload", {
|
|
269
291
|
magnets: magnetsArray
|
|
270
292
|
});
|
|
271
293
|
}
|
|
@@ -292,23 +314,22 @@ var MagnetResource = class extends BaseResource {
|
|
|
292
314
|
return this.postFormData("/magnet/upload/file", formData);
|
|
293
315
|
}
|
|
294
316
|
/**
|
|
295
|
-
* Get the status of
|
|
317
|
+
* Get the status of a specific magnet by ID
|
|
296
318
|
*
|
|
297
|
-
* @param id -
|
|
319
|
+
* @param id - Magnet ID to get status for
|
|
298
320
|
*
|
|
299
321
|
* @example
|
|
300
322
|
* ```ts
|
|
301
|
-
*
|
|
302
|
-
* const allStatus = await client.magnet.status()
|
|
303
|
-
*
|
|
304
|
-
* // Get specific magnet status
|
|
305
|
-
* const status = await client.magnet.status('123')
|
|
323
|
+
* const status = await client.magnet.status(123)
|
|
306
324
|
* console.log(status.magnets[0]?.status) // 'Downloading', 'Ready', etc.
|
|
307
325
|
* ```
|
|
326
|
+
*
|
|
327
|
+
* @remarks
|
|
328
|
+
* This endpoint uses AllDebrid API v4.1 (POST method)
|
|
329
|
+
* Migrated from v4 GET endpoint which was deprecated on 2024-10-16
|
|
308
330
|
*/
|
|
309
331
|
async status(id) {
|
|
310
|
-
const
|
|
311
|
-
const data = await this.get("/magnet/status", params);
|
|
332
|
+
const data = await this.post("/magnet/status", { id });
|
|
312
333
|
if (data?.magnets && !Array.isArray(data.magnets)) {
|
|
313
334
|
return {
|
|
314
335
|
...data,
|
|
@@ -317,78 +338,186 @@ var MagnetResource = class extends BaseResource {
|
|
|
317
338
|
}
|
|
318
339
|
return data;
|
|
319
340
|
}
|
|
341
|
+
/**
|
|
342
|
+
* Get list of magnets with optional status filter
|
|
343
|
+
*
|
|
344
|
+
* @param statusFilter - Optional filter by status: 'active', 'ready', 'expired', or 'error'
|
|
345
|
+
*
|
|
346
|
+
* @example
|
|
347
|
+
* ```ts
|
|
348
|
+
* // Get all magnets
|
|
349
|
+
* const allMagnets = await client.magnet.statusList()
|
|
350
|
+
*
|
|
351
|
+
* // Get only active magnets
|
|
352
|
+
* const activeMagnets = await client.magnet.statusList('active')
|
|
353
|
+
*
|
|
354
|
+
* // Get only ready magnets
|
|
355
|
+
* const readyMagnets = await client.magnet.statusList('ready')
|
|
356
|
+
* ```
|
|
357
|
+
*
|
|
358
|
+
* @remarks
|
|
359
|
+
* This endpoint uses AllDebrid API v4.1 (POST method)
|
|
360
|
+
*/
|
|
361
|
+
async statusList(statusFilter) {
|
|
362
|
+
const body = statusFilter ? { status: statusFilter } : void 0;
|
|
363
|
+
return this.post("/magnet/status", body);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Get magnet status using live mode for reduced bandwidth consumption
|
|
367
|
+
*
|
|
368
|
+
* Live mode uses delta synchronization - only changes since the last call are transmitted.
|
|
369
|
+
* On the first call (counter=0), all data is returned with `fullsync: true`.
|
|
370
|
+
* Subsequent calls return only modifications.
|
|
371
|
+
*
|
|
372
|
+
* @param options - Live mode options
|
|
373
|
+
* @param options.session - Session ID (generate once per session and reuse)
|
|
374
|
+
* @param options.counter - Synchronization counter (start at 0, use returned counter for next call)
|
|
375
|
+
* @param id - Optional magnet ID to filter a specific magnet
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```ts
|
|
379
|
+
* // Initialize session
|
|
380
|
+
* const session = Math.floor(Math.random() * 1000000)
|
|
381
|
+
* let counter = 0
|
|
382
|
+
*
|
|
383
|
+
* // First call - full sync
|
|
384
|
+
* const firstCall = await client.magnet.statusLive({ session, counter })
|
|
385
|
+
* console.log('Full sync:', firstCall.fullsync) // true
|
|
386
|
+
* console.log('All magnets:', firstCall.magnets)
|
|
387
|
+
*
|
|
388
|
+
* // Update counter with value returned by API
|
|
389
|
+
* counter = firstCall.counter
|
|
390
|
+
*
|
|
391
|
+
* // Second call - only changes
|
|
392
|
+
* const secondCall = await client.magnet.statusLive({ session, counter })
|
|
393
|
+
* console.log('Delta sync:', secondCall.magnets) // Only modified magnets
|
|
394
|
+
*
|
|
395
|
+
* // Filter specific magnet in live mode
|
|
396
|
+
* const magnetLive = await client.magnet.statusLive({ session, counter }, 123)
|
|
397
|
+
* ```
|
|
398
|
+
*
|
|
399
|
+
* @remarks
|
|
400
|
+
* This is ideal for real-time dashboards or frequent polling scenarios
|
|
401
|
+
* as it significantly reduces bandwidth usage by transmitting only changes.
|
|
402
|
+
*/
|
|
403
|
+
async statusLive(options, id) {
|
|
404
|
+
const body = {
|
|
405
|
+
session: options.session,
|
|
406
|
+
counter: options.counter
|
|
407
|
+
};
|
|
408
|
+
if (id !== void 0) {
|
|
409
|
+
body.id = id;
|
|
410
|
+
}
|
|
411
|
+
return this.post("/magnet/status", body);
|
|
412
|
+
}
|
|
320
413
|
/**
|
|
321
414
|
* Delete a magnet
|
|
322
415
|
*
|
|
323
|
-
* @param id - The magnet ID to delete
|
|
416
|
+
* @param id - The magnet ID to delete
|
|
324
417
|
*
|
|
325
418
|
* @example
|
|
326
419
|
* ```ts
|
|
327
|
-
* await client.magnet.delete(
|
|
420
|
+
* await client.magnet.delete(123)
|
|
328
421
|
* ```
|
|
329
422
|
*/
|
|
330
423
|
async delete(id) {
|
|
331
|
-
return this.
|
|
424
|
+
return this.post("/magnet/delete", {
|
|
332
425
|
id
|
|
333
426
|
});
|
|
334
427
|
}
|
|
335
428
|
/**
|
|
336
429
|
* Restart one or more failed magnets
|
|
337
430
|
*
|
|
338
|
-
* @param ids - Single magnet ID or array of magnet IDs to restart (
|
|
431
|
+
* @param ids - Single magnet ID or array of magnet IDs to restart (numbers)
|
|
339
432
|
*
|
|
340
433
|
* @example
|
|
341
434
|
* ```ts
|
|
342
435
|
* // Restart single magnet
|
|
343
|
-
* await client.magnet.restart(
|
|
436
|
+
* await client.magnet.restart(123)
|
|
344
437
|
*
|
|
345
438
|
* // Restart multiple magnets
|
|
346
|
-
* await client.magnet.restart([
|
|
439
|
+
* await client.magnet.restart([123, 456])
|
|
347
440
|
* ```
|
|
348
441
|
*/
|
|
349
442
|
async restart(ids) {
|
|
350
443
|
const idsArray = Array.isArray(ids) ? ids : [ids];
|
|
351
|
-
return this.
|
|
444
|
+
return this.post("/magnet/restart", {
|
|
352
445
|
ids: idsArray
|
|
353
446
|
});
|
|
354
447
|
}
|
|
355
448
|
/**
|
|
356
|
-
*
|
|
449
|
+
* Get files for a completed magnet
|
|
357
450
|
*
|
|
358
|
-
* @param
|
|
451
|
+
* @param ids - The magnet ID or IDs to get files for
|
|
359
452
|
*
|
|
360
453
|
* @example
|
|
361
454
|
* ```ts
|
|
362
|
-
* const
|
|
363
|
-
*
|
|
455
|
+
* const files = await client.magnet.files(123)
|
|
456
|
+
* files?.forEach(file => {
|
|
457
|
+
* console.log(file.filename, file.link)
|
|
458
|
+
* })
|
|
364
459
|
* ```
|
|
460
|
+
*
|
|
461
|
+
* @remarks
|
|
462
|
+
* Files are now retrieved separately from magnet status (since v4.1)
|
|
463
|
+
* Only available for magnets with status 'Ready'
|
|
365
464
|
*/
|
|
366
|
-
async
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
465
|
+
async files(ids) {
|
|
466
|
+
const formData = new FormData();
|
|
467
|
+
const idsArray = Array.isArray(ids) ? ids : [ids];
|
|
468
|
+
for (const id of idsArray) {
|
|
469
|
+
formData.append("id[]", String(id));
|
|
470
|
+
}
|
|
471
|
+
const data = await this.postFormData("/magnet/files", formData);
|
|
472
|
+
return data?.magnets;
|
|
371
473
|
}
|
|
372
474
|
/**
|
|
373
475
|
* Watch a magnet's status with automatic polling
|
|
374
476
|
*
|
|
375
|
-
* @param id - The magnet ID to watch
|
|
477
|
+
* @param id - The magnet ID to watch
|
|
376
478
|
* @param options - Watch options
|
|
479
|
+
* @param options.interval - Polling interval in milliseconds (default: 3000)
|
|
480
|
+
* @param options.maxAttempts - Maximum polling attempts, 0 for infinite (default: 0)
|
|
481
|
+
* @param options.onUpdate - Callback called on each status update
|
|
482
|
+
* @param options.stopOnStatus - Stop when magnet reaches this status (default: 'Ready')
|
|
483
|
+
* @param options.useLiveMode - Use live mode for reduced bandwidth (default: false)
|
|
377
484
|
*
|
|
378
485
|
* @example
|
|
379
486
|
* ```ts
|
|
380
|
-
*
|
|
487
|
+
* // Standard mode
|
|
488
|
+
* await client.magnet.watch(123, {
|
|
381
489
|
* onUpdate: (status) => console.log('Status:', status.magnets[0]?.status),
|
|
382
490
|
* stopOnStatus: 'Ready'
|
|
383
491
|
* })
|
|
492
|
+
*
|
|
493
|
+
* // Live mode for reduced bandwidth
|
|
494
|
+
* await client.magnet.watch(123, {
|
|
495
|
+
* useLiveMode: true,
|
|
496
|
+
* interval: 2000,
|
|
497
|
+
* onUpdate: (status) => console.log('Update:', status)
|
|
498
|
+
* })
|
|
384
499
|
* ```
|
|
385
500
|
*/
|
|
386
501
|
async watch(id, options = {}) {
|
|
387
|
-
const {
|
|
502
|
+
const {
|
|
503
|
+
interval = 3e3,
|
|
504
|
+
maxAttempts = 0,
|
|
505
|
+
onUpdate,
|
|
506
|
+
stopOnStatus = "Ready",
|
|
507
|
+
useLiveMode = false
|
|
508
|
+
} = options;
|
|
388
509
|
let attempt = 0;
|
|
510
|
+
let session;
|
|
511
|
+
let counter = 0;
|
|
512
|
+
if (useLiveMode) {
|
|
513
|
+
session = Math.floor(Math.random() * 1e6);
|
|
514
|
+
}
|
|
389
515
|
while (maxAttempts === 0 || attempt < maxAttempts) {
|
|
390
516
|
attempt++;
|
|
391
|
-
const status = await this.status(id);
|
|
517
|
+
const status = useLiveMode && session !== void 0 ? await this.statusLive({ session, counter }, id) : await this.status(id);
|
|
518
|
+
if (useLiveMode && status?.counter !== void 0) {
|
|
519
|
+
counter = status.counter;
|
|
520
|
+
}
|
|
392
521
|
onUpdate?.(status);
|
|
393
522
|
const magnet = status?.magnets?.[0];
|
|
394
523
|
if (magnet?.status === stopOnStatus) {
|
|
@@ -402,6 +531,111 @@ var MagnetResource = class extends BaseResource {
|
|
|
402
531
|
}
|
|
403
532
|
};
|
|
404
533
|
|
|
534
|
+
// src/resources/pin.ts
|
|
535
|
+
var PinResource = class extends BaseResource {
|
|
536
|
+
/**
|
|
537
|
+
* Generate a new PIN code for authentication
|
|
538
|
+
*
|
|
539
|
+
* This initiates the PIN authentication flow. The user should visit the
|
|
540
|
+
* returned URL to authorize the application.
|
|
541
|
+
*
|
|
542
|
+
* @example
|
|
543
|
+
* ```ts
|
|
544
|
+
* const pinData = await client.pin.generate()
|
|
545
|
+
* console.log('Visit:', pinData.user_url)
|
|
546
|
+
* console.log('PIN:', pinData.pin)
|
|
547
|
+
*
|
|
548
|
+
* // Poll the check endpoint until user authorizes
|
|
549
|
+
* const auth = await client.pin.check(pinData.check, pinData.pin)
|
|
550
|
+
* if (auth.activated) {
|
|
551
|
+
* console.log('API Key:', auth.apikey)
|
|
552
|
+
* }
|
|
553
|
+
* ```
|
|
554
|
+
*
|
|
555
|
+
* @returns PIN code and authorization URL
|
|
556
|
+
*/
|
|
557
|
+
async generate() {
|
|
558
|
+
return super.get("/pin/get");
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Check the status of a PIN authentication
|
|
562
|
+
*
|
|
563
|
+
* Poll this endpoint to check if the user has authorized the application.
|
|
564
|
+
* Once authorized, the response will include the API key.
|
|
565
|
+
*
|
|
566
|
+
* @param check - Check ID from /pin/get
|
|
567
|
+
* @param pin - PIN code from /pin/get
|
|
568
|
+
*
|
|
569
|
+
* @example
|
|
570
|
+
* ```ts
|
|
571
|
+
* const pinData = await client.pin.generate()
|
|
572
|
+
*
|
|
573
|
+
* // Poll every few seconds until activated
|
|
574
|
+
* const checkStatus = async () => {
|
|
575
|
+
* const result = await client.pin.check(pinData.check, pinData.pin)
|
|
576
|
+
* if (result?.activated && result?.apikey) {
|
|
577
|
+
* console.log('Authorized! API Key:', result.apikey)
|
|
578
|
+
* return result.apikey
|
|
579
|
+
* }
|
|
580
|
+
* // Wait and try again
|
|
581
|
+
* await new Promise(resolve => setTimeout(resolve, 3000))
|
|
582
|
+
* return checkStatus()
|
|
583
|
+
* }
|
|
584
|
+
*
|
|
585
|
+
* const apikey = await checkStatus()
|
|
586
|
+
* ```
|
|
587
|
+
*
|
|
588
|
+
* @returns Authorization status and API key (if activated)
|
|
589
|
+
*/
|
|
590
|
+
async check(check, pin) {
|
|
591
|
+
return super.get("/pin/check", { check, pin });
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Helper method to wait for PIN authorization with automatic polling
|
|
595
|
+
*
|
|
596
|
+
* This method handles the polling logic for you, making it easier to
|
|
597
|
+
* implement the PIN authentication flow.
|
|
598
|
+
*
|
|
599
|
+
* @param check - Check ID from /pin/get
|
|
600
|
+
* @param pin - PIN code from /pin/get
|
|
601
|
+
* @param options - Polling options
|
|
602
|
+
* @param options.timeout - Maximum time to wait in milliseconds (default: 600000 = 10 minutes)
|
|
603
|
+
* @param options.interval - Polling interval in milliseconds (default: 3000 = 3 seconds)
|
|
604
|
+
*
|
|
605
|
+
* @example
|
|
606
|
+
* ```ts
|
|
607
|
+
* const pinData = await client.pin.generate()
|
|
608
|
+
* console.log('Visit:', pinData.user_url)
|
|
609
|
+
*
|
|
610
|
+
* try {
|
|
611
|
+
* const apikey = await client.pin.waitForAuth(pinData.check, pinData.pin, {
|
|
612
|
+
* timeout: 600000, // 10 minutes
|
|
613
|
+
* interval: 3000, // Check every 3 seconds
|
|
614
|
+
* })
|
|
615
|
+
* console.log('Authorized! API Key:', apikey)
|
|
616
|
+
* } catch (error) {
|
|
617
|
+
* console.error('Authorization timed out or failed')
|
|
618
|
+
* }
|
|
619
|
+
* ```
|
|
620
|
+
*
|
|
621
|
+
* @returns The API key once authorized
|
|
622
|
+
* @throws Error if timeout is reached or authorization fails
|
|
623
|
+
*/
|
|
624
|
+
async waitForAuth(check, pin, options = {}) {
|
|
625
|
+
const timeout = options.timeout ?? 6e5;
|
|
626
|
+
const interval = options.interval ?? 3e3;
|
|
627
|
+
const startTime = Date.now();
|
|
628
|
+
while (Date.now() - startTime < timeout) {
|
|
629
|
+
const result = await this.check(check, pin);
|
|
630
|
+
if (result?.activated && result?.apikey) {
|
|
631
|
+
return result.apikey;
|
|
632
|
+
}
|
|
633
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
634
|
+
}
|
|
635
|
+
throw new Error("PIN authorization timeout - user did not authorize within the time limit");
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
|
|
405
639
|
// src/resources/user.ts
|
|
406
640
|
var UserResource = class extends BaseResource {
|
|
407
641
|
/**
|
|
@@ -443,7 +677,7 @@ var UserResource = class extends BaseResource {
|
|
|
443
677
|
* ```
|
|
444
678
|
*/
|
|
445
679
|
async clearNotification(code) {
|
|
446
|
-
await this.
|
|
680
|
+
await this.post("/user/notification/clear", { code });
|
|
447
681
|
}
|
|
448
682
|
// ============================================
|
|
449
683
|
// Saved Links Management
|
|
@@ -461,30 +695,60 @@ var UserResource = class extends BaseResource {
|
|
|
461
695
|
return this.get("/user/links");
|
|
462
696
|
}
|
|
463
697
|
/**
|
|
464
|
-
* Save
|
|
698
|
+
* Save one or multiple links for later use
|
|
699
|
+
*
|
|
700
|
+
* Supports batch operations - you can save multiple links in a single request.
|
|
465
701
|
*
|
|
466
|
-
* @param
|
|
702
|
+
* @param links - Single link or array of links to save
|
|
467
703
|
*
|
|
468
704
|
* @example
|
|
469
705
|
* ```ts
|
|
706
|
+
* // Save single link
|
|
470
707
|
* await client.user.saveLink('https://example.com/file.zip')
|
|
708
|
+
*
|
|
709
|
+
* // Save multiple links at once
|
|
710
|
+
* await client.user.saveLink([
|
|
711
|
+
* 'https://example.com/file1.zip',
|
|
712
|
+
* 'https://example.com/file2.zip',
|
|
713
|
+
* 'https://example.com/file3.zip'
|
|
714
|
+
* ])
|
|
471
715
|
* ```
|
|
472
716
|
*/
|
|
473
|
-
async saveLink(
|
|
474
|
-
|
|
717
|
+
async saveLink(links) {
|
|
718
|
+
const linksArray = Array.isArray(links) ? links : [links];
|
|
719
|
+
const formData = new FormData();
|
|
720
|
+
for (const link of linksArray) {
|
|
721
|
+
formData.append("links[]", link);
|
|
722
|
+
}
|
|
723
|
+
return this.postFormData("/user/links/save", formData);
|
|
475
724
|
}
|
|
476
725
|
/**
|
|
477
|
-
* Delete
|
|
726
|
+
* Delete one or multiple saved links
|
|
727
|
+
*
|
|
728
|
+
* Supports batch operations - you can delete multiple links in a single request.
|
|
478
729
|
*
|
|
479
|
-
* @param
|
|
730
|
+
* @param links - Single link or array of links to delete (can be saved link IDs or URLs)
|
|
480
731
|
*
|
|
481
732
|
* @example
|
|
482
733
|
* ```ts
|
|
734
|
+
* // Delete single link
|
|
483
735
|
* await client.user.deleteLink('saved-link-id')
|
|
736
|
+
*
|
|
737
|
+
* // Delete multiple links at once
|
|
738
|
+
* await client.user.deleteLink([
|
|
739
|
+
* 'saved-link-id-1',
|
|
740
|
+
* 'saved-link-id-2',
|
|
741
|
+
* 'saved-link-id-3'
|
|
742
|
+
* ])
|
|
484
743
|
* ```
|
|
485
744
|
*/
|
|
486
|
-
async deleteLink(
|
|
487
|
-
|
|
745
|
+
async deleteLink(links) {
|
|
746
|
+
const linksArray = Array.isArray(links) ? links : [links];
|
|
747
|
+
const formData = new FormData();
|
|
748
|
+
for (const link of linksArray) {
|
|
749
|
+
formData.append("links[]", link);
|
|
750
|
+
}
|
|
751
|
+
return this.postFormData("/user/links/delete", formData);
|
|
488
752
|
}
|
|
489
753
|
// ============================================
|
|
490
754
|
// History Management
|
|
@@ -510,12 +774,114 @@ var UserResource = class extends BaseResource {
|
|
|
510
774
|
* ```
|
|
511
775
|
*/
|
|
512
776
|
async clearHistory() {
|
|
513
|
-
return this.
|
|
777
|
+
return this.post("/user/history/delete");
|
|
778
|
+
}
|
|
779
|
+
// ============================================
|
|
780
|
+
// Email Verification
|
|
781
|
+
// ============================================
|
|
782
|
+
/**
|
|
783
|
+
* Check email verification status
|
|
784
|
+
*
|
|
785
|
+
* @param token - Verification token
|
|
786
|
+
*
|
|
787
|
+
* @example
|
|
788
|
+
* ```ts
|
|
789
|
+
* const status = await client.user.getVerificationStatus('verification-token')
|
|
790
|
+
* console.log(status.verif) // 'waiting', 'allowed', or 'denied'
|
|
791
|
+
* ```
|
|
792
|
+
*/
|
|
793
|
+
async getVerificationStatus(token) {
|
|
794
|
+
return this.post("/user/verif", void 0, { token });
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Resend verification email
|
|
798
|
+
*
|
|
799
|
+
* @param token - Verification token
|
|
800
|
+
*
|
|
801
|
+
* @example
|
|
802
|
+
* ```ts
|
|
803
|
+
* await client.user.resendVerification('verification-token')
|
|
804
|
+
* ```
|
|
805
|
+
*/
|
|
806
|
+
async resendVerification(token) {
|
|
807
|
+
return this.post("/user/verif/resend", void 0, { token });
|
|
808
|
+
}
|
|
809
|
+
};
|
|
810
|
+
|
|
811
|
+
// src/resources/voucher.ts
|
|
812
|
+
var VoucherResource = class extends BaseResource {
|
|
813
|
+
/**
|
|
814
|
+
* Get voucher balance for reseller accounts
|
|
815
|
+
*
|
|
816
|
+
* This endpoint allows resellers to check their remaining voucher balance.
|
|
817
|
+
* Only available for accounts with reseller privileges.
|
|
818
|
+
*
|
|
819
|
+
* @example
|
|
820
|
+
* ```ts
|
|
821
|
+
* const balance = await client.voucher.getBalance()
|
|
822
|
+
* console.log('Remaining balance:', balance.balance, '€')
|
|
823
|
+
* ```
|
|
824
|
+
*
|
|
825
|
+
* @returns Voucher balance information
|
|
826
|
+
*/
|
|
827
|
+
async getBalance() {
|
|
828
|
+
return this.get("/voucher/balance");
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Retrieve existing vouchers from reseller inventory
|
|
832
|
+
*
|
|
833
|
+
* This endpoint retrieves vouchers that were previously generated
|
|
834
|
+
* and are available in your inventory.
|
|
835
|
+
*
|
|
836
|
+
* @param quantity - Optional number of vouchers to retrieve
|
|
837
|
+
*
|
|
838
|
+
* @example
|
|
839
|
+
* ```ts
|
|
840
|
+
* // Get all available vouchers
|
|
841
|
+
* const allVouchers = await client.voucher.getVouchers()
|
|
842
|
+
* console.log('Vouchers:', allVouchers?.codes)
|
|
843
|
+
*
|
|
844
|
+
* // Get specific quantity
|
|
845
|
+
* const fiveVouchers = await client.voucher.getVouchers(5)
|
|
846
|
+
* ```
|
|
847
|
+
*
|
|
848
|
+
* @returns List of voucher codes
|
|
849
|
+
*/
|
|
850
|
+
async getVouchers(quantity) {
|
|
851
|
+
const params = quantity ? { quantity } : void 0;
|
|
852
|
+
return this.get("/voucher/get", params);
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Generate new vouchers (deducts from reseller balance)
|
|
856
|
+
*
|
|
857
|
+
* This endpoint creates new vouchers and deducts the cost from your
|
|
858
|
+
* reseller account balance.
|
|
859
|
+
*
|
|
860
|
+
* @param quantity - Number of vouchers to generate
|
|
861
|
+
* @param duration - Voucher duration in days
|
|
862
|
+
*
|
|
863
|
+
* @example
|
|
864
|
+
* ```ts
|
|
865
|
+
* // Generate 10 vouchers valid for 30 days
|
|
866
|
+
* const vouchers = await client.voucher.generateVouchers(10, 30)
|
|
867
|
+
* console.log('Generated vouchers:', vouchers?.codes)
|
|
868
|
+
*
|
|
869
|
+
* // Generate 5 vouchers valid for 7 days
|
|
870
|
+
* const weekVouchers = await client.voucher.generateVouchers(5, 7)
|
|
871
|
+
* ```
|
|
872
|
+
*
|
|
873
|
+
* @returns List of newly generated voucher codes
|
|
874
|
+
*/
|
|
875
|
+
async generateVouchers(quantity, duration) {
|
|
876
|
+
return this.post("/voucher/generate", {
|
|
877
|
+
quantity,
|
|
878
|
+
duration
|
|
879
|
+
});
|
|
514
880
|
}
|
|
515
881
|
};
|
|
516
882
|
|
|
517
883
|
// src/client.ts
|
|
518
|
-
var DEFAULT_BASE_URL = "https://api.alldebrid.com/v4";
|
|
884
|
+
var DEFAULT_BASE_URL = "https://api.alldebrid.com/v4.1";
|
|
519
885
|
var DEFAULT_AGENT = "@alldebrid/sdk";
|
|
520
886
|
var DEFAULT_TIMEOUT = 3e4;
|
|
521
887
|
var DEFAULT_MAX_RETRIES = 3;
|
|
@@ -537,6 +903,14 @@ var AllDebridClient = class {
|
|
|
537
903
|
* Host resource for getting information about supported hosts
|
|
538
904
|
*/
|
|
539
905
|
host;
|
|
906
|
+
/**
|
|
907
|
+
* Pin resource for PIN-based authentication
|
|
908
|
+
*/
|
|
909
|
+
pin;
|
|
910
|
+
/**
|
|
911
|
+
* Voucher resource for reseller voucher management
|
|
912
|
+
*/
|
|
913
|
+
voucher;
|
|
540
914
|
constructor(config) {
|
|
541
915
|
this.config = {
|
|
542
916
|
apiKey: config.apiKey,
|
|
@@ -550,6 +924,8 @@ var AllDebridClient = class {
|
|
|
550
924
|
this.link = new LinkResource(this);
|
|
551
925
|
this.magnet = new MagnetResource(this);
|
|
552
926
|
this.host = new HostResource(this);
|
|
927
|
+
this.pin = new PinResource(this);
|
|
928
|
+
this.voucher = new VoucherResource(this);
|
|
553
929
|
}
|
|
554
930
|
/**
|
|
555
931
|
* Build query string from params
|
|
@@ -574,8 +950,11 @@ var AllDebridClient = class {
|
|
|
574
950
|
}
|
|
575
951
|
/**
|
|
576
952
|
* Make a GET request
|
|
577
|
-
* @
|
|
953
|
+
* @template T - The generated response type (e.g., GetLinkUnlockResponse)
|
|
954
|
+
* @param path - API endpoint path
|
|
955
|
+
* @param params - Optional query parameters
|
|
578
956
|
* @returns The extracted data from the response (without the { status, data } wrapper)
|
|
957
|
+
* @internal
|
|
579
958
|
*/
|
|
580
959
|
async get(path, params) {
|
|
581
960
|
try {
|
|
@@ -602,14 +981,30 @@ var AllDebridClient = class {
|
|
|
602
981
|
}
|
|
603
982
|
}
|
|
604
983
|
/**
|
|
605
|
-
* Make a POST request
|
|
606
|
-
* @
|
|
984
|
+
* Make a POST request with application/x-www-form-urlencoded
|
|
985
|
+
* @template T - The generated response type
|
|
986
|
+
* @param path - API endpoint path
|
|
987
|
+
* @param body - Request body (will be converted to URLSearchParams)
|
|
988
|
+
* @param params - Optional query parameters
|
|
607
989
|
* @returns The extracted data from the response (without the { status, data } wrapper)
|
|
990
|
+
* @internal
|
|
608
991
|
*/
|
|
609
992
|
async post(path, body, params) {
|
|
610
993
|
try {
|
|
611
994
|
const url = this.buildUrl(path, params);
|
|
612
|
-
const
|
|
995
|
+
const formData = new URLSearchParams();
|
|
996
|
+
if (body && typeof body === "object") {
|
|
997
|
+
for (const [key, value] of Object.entries(body)) {
|
|
998
|
+
if (value !== void 0 && value !== null) {
|
|
999
|
+
if (Array.isArray(value)) {
|
|
1000
|
+
value.forEach((v) => formData.append(key, String(v)));
|
|
1001
|
+
} else {
|
|
1002
|
+
formData.append(key, String(value));
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
const json = await wretch__default.default(this.config.baseUrl).auth(`Bearer ${this.config.apiKey}`).url(url).body(formData).post().json();
|
|
613
1008
|
if (json.status === "error" && json.error) {
|
|
614
1009
|
throw createTypedError(json.error.code, json.error.message);
|
|
615
1010
|
}
|
|
@@ -632,8 +1027,12 @@ var AllDebridClient = class {
|
|
|
632
1027
|
}
|
|
633
1028
|
/**
|
|
634
1029
|
* Make a POST request with FormData (multipart/form-data)
|
|
635
|
-
* @
|
|
1030
|
+
* @template T - The generated response type
|
|
1031
|
+
* @param path - API endpoint path
|
|
1032
|
+
* @param formData - Form data to send
|
|
1033
|
+
* @param params - Optional query parameters
|
|
636
1034
|
* @returns The extracted data from the response (without the { status, data } wrapper)
|
|
1035
|
+
* @internal
|
|
637
1036
|
*/
|
|
638
1037
|
async postFormData(path, formData, params) {
|
|
639
1038
|
try {
|
|
@@ -661,14 +1060,20 @@ var AllDebridClient = class {
|
|
|
661
1060
|
}
|
|
662
1061
|
/**
|
|
663
1062
|
* Test the API connection
|
|
1063
|
+
*
|
|
1064
|
+
* This endpoint doesn't require authentication and can be used to verify
|
|
1065
|
+
* that the AllDebrid API is reachable.
|
|
1066
|
+
*
|
|
1067
|
+
* @example
|
|
1068
|
+
* ```ts
|
|
1069
|
+
* const result = await client.ping()
|
|
1070
|
+
* console.log(result.ping) // 'pong'
|
|
1071
|
+
* ```
|
|
1072
|
+
*
|
|
1073
|
+
* @returns Ping response with 'pong' message
|
|
664
1074
|
*/
|
|
665
1075
|
async ping() {
|
|
666
|
-
|
|
667
|
-
await this.get("/user");
|
|
668
|
-
return true;
|
|
669
|
-
} catch {
|
|
670
|
-
return false;
|
|
671
|
-
}
|
|
1076
|
+
return this.get("/ping");
|
|
672
1077
|
}
|
|
673
1078
|
};
|
|
674
1079
|
|
|
@@ -681,7 +1086,9 @@ exports.LinkResource = LinkResource;
|
|
|
681
1086
|
exports.MagnetError = MagnetError;
|
|
682
1087
|
exports.MagnetResource = MagnetResource;
|
|
683
1088
|
exports.NetworkError = NetworkError;
|
|
1089
|
+
exports.PinResource = PinResource;
|
|
684
1090
|
exports.UserResource = UserResource;
|
|
1091
|
+
exports.VoucherResource = VoucherResource;
|
|
685
1092
|
exports.createTypedError = createTypedError;
|
|
686
1093
|
//# sourceMappingURL=index.cjs.map
|
|
687
1094
|
//# sourceMappingURL=index.cjs.map
|