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