@dropgate/core 2.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,883 @@
1
+ /**
2
+ * Default chunk size for file uploads (5MB)
3
+ */
4
+ declare const DEFAULT_CHUNK_SIZE: number;
5
+ /**
6
+ * AES-GCM initialization vector size in bytes
7
+ */
8
+ declare const AES_GCM_IV_BYTES = 12;
9
+ /**
10
+ * AES-GCM authentication tag size in bytes
11
+ */
12
+ declare const AES_GCM_TAG_BYTES = 16;
13
+ /**
14
+ * Total encryption overhead per chunk (IV + tag)
15
+ */
16
+ declare const ENCRYPTION_OVERHEAD_PER_CHUNK: number;
17
+
18
+ interface DropgateErrorOptions {
19
+ code?: string;
20
+ details?: unknown;
21
+ cause?: unknown;
22
+ }
23
+ /**
24
+ * Base error class for all Dropgate errors
25
+ */
26
+ declare class DropgateError extends Error {
27
+ readonly code: string;
28
+ readonly details?: unknown;
29
+ constructor(message: string, opts?: DropgateErrorOptions);
30
+ }
31
+ /**
32
+ * Validation error for invalid inputs
33
+ */
34
+ declare class DropgateValidationError extends DropgateError {
35
+ constructor(message: string, opts?: DropgateErrorOptions);
36
+ }
37
+ /**
38
+ * Network error for connection issues
39
+ */
40
+ declare class DropgateNetworkError extends DropgateError {
41
+ constructor(message: string, opts?: DropgateErrorOptions);
42
+ }
43
+ /**
44
+ * Protocol error for server communication issues
45
+ */
46
+ declare class DropgateProtocolError extends DropgateError {
47
+ constructor(message: string, opts?: DropgateErrorOptions);
48
+ }
49
+ /**
50
+ * Abort error - replacement for DOMException with AbortError name
51
+ * Used when operations are cancelled
52
+ */
53
+ declare class DropgateAbortError extends DropgateError {
54
+ constructor(message?: string);
55
+ }
56
+ /**
57
+ * Timeout error - replacement for DOMException with TimeoutError name
58
+ * Used when operations exceed their time limit
59
+ */
60
+ declare class DropgateTimeoutError extends DropgateError {
61
+ constructor(message?: string);
62
+ }
63
+
64
+ /**
65
+ * Server upload capabilities returned from the server info endpoint.
66
+ */
67
+ interface UploadCapabilities {
68
+ /** Whether hosted uploads are enabled on the server. */
69
+ enabled: boolean;
70
+ /** Maximum file size in megabytes (0 = unlimited). */
71
+ maxSizeMB?: number;
72
+ /** Maximum file lifetime in hours (0 = unlimited). */
73
+ maxLifetimeHours?: number;
74
+ /** Whether end-to-end encryption is supported. */
75
+ e2ee?: boolean;
76
+ }
77
+ /**
78
+ * Server P2P (direct transfer) capabilities.
79
+ */
80
+ interface P2PCapabilities {
81
+ /** Whether P2P transfers are enabled on the server. */
82
+ enabled: boolean;
83
+ /** Path to the PeerJS signaling server. */
84
+ peerjsPath?: string;
85
+ /** ICE servers for WebRTC connectivity. */
86
+ iceServers?: RTCIceServer[];
87
+ }
88
+ /**
89
+ * Server Web UI capabilities.
90
+ */
91
+ interface WebUICapabilities {
92
+ /** Whether the Web UI is enabled on the server. */
93
+ enabled: boolean;
94
+ }
95
+ /**
96
+ * Combined server capabilities object.
97
+ */
98
+ interface ServerCapabilities {
99
+ /** Hosted upload capabilities. */
100
+ upload?: UploadCapabilities;
101
+ /** P2P transfer capabilities. */
102
+ p2p?: P2PCapabilities;
103
+ /** Web UI capabilities. */
104
+ webUI?: WebUICapabilities;
105
+ }
106
+ /**
107
+ * Server information returned from the /api/info endpoint.
108
+ */
109
+ interface ServerInfo {
110
+ /** Display name of the server. */
111
+ name?: string;
112
+ /** Server version string. */
113
+ version: string;
114
+ /** Server capabilities. */
115
+ capabilities?: ServerCapabilities;
116
+ }
117
+ /**
118
+ * Progress event emitted during upload operations.
119
+ */
120
+ interface ProgressEvent {
121
+ /** Current phase of the operation (e.g., 'init', 'chunk', 'complete'). */
122
+ phase: string;
123
+ /** Human-readable status text. */
124
+ text?: string;
125
+ /** Completion percentage (0-100). */
126
+ percent?: number;
127
+ /** Current chunk index (0-based). */
128
+ chunkIndex?: number;
129
+ /** Total number of chunks. */
130
+ totalChunks?: number;
131
+ }
132
+ /**
133
+ * Result of a successful file upload.
134
+ */
135
+ interface UploadResult {
136
+ /** Full download URL including encryption key fragment if encrypted. */
137
+ downloadUrl: string;
138
+ /** Unique file identifier on the server. */
139
+ fileId: string;
140
+ /** Upload session identifier. */
141
+ uploadId: string;
142
+ /** Server base URL used for the upload. */
143
+ baseUrl: string;
144
+ /** Base64-encoded encryption key (only present if encrypted). */
145
+ keyB64?: string;
146
+ }
147
+ /**
148
+ * Result of a client/server compatibility check.
149
+ */
150
+ interface CompatibilityResult {
151
+ /** Whether the client and server versions are compatible. */
152
+ compatible: boolean;
153
+ /** Human-readable compatibility message. */
154
+ message: string;
155
+ /** Client version string. */
156
+ clientVersion: string;
157
+ /** Server version string. */
158
+ serverVersion: string;
159
+ }
160
+ /**
161
+ * Result of resolving a share target (code or URL).
162
+ */
163
+ interface ShareTargetResult {
164
+ /** Whether the share target is valid. */
165
+ valid: boolean;
166
+ /** Type of share target (e.g., 'p2p', 'file'). */
167
+ type?: string;
168
+ /** Resolved target identifier. */
169
+ target?: string;
170
+ /** Reason for invalidity if not valid. */
171
+ reason?: string;
172
+ }
173
+ /**
174
+ * Crypto adapter interface compatible with the Web Crypto API.
175
+ * Used for encryption operations and secure random generation.
176
+ */
177
+ interface CryptoAdapter {
178
+ /** SubtleCrypto interface for cryptographic operations. */
179
+ readonly subtle: SubtleCrypto;
180
+ /** Fill an array with cryptographically secure random values. */
181
+ getRandomValues<T extends ArrayBufferView | null>(array: T): T;
182
+ }
183
+ /**
184
+ * Fetch function type compatible with the standard fetch API.
185
+ * @param input - The URL or Request object to fetch.
186
+ * @param init - Optional fetch configuration.
187
+ * @returns A Promise that resolves to a Response.
188
+ */
189
+ type FetchFn = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
190
+ /**
191
+ * Base64 adapter for environment-agnostic encoding/decoding.
192
+ * Allows the library to work in both browser and Node.js environments.
193
+ */
194
+ interface Base64Adapter {
195
+ /** Encode bytes to a base64 string. */
196
+ encode(bytes: Uint8Array): string;
197
+ /** Decode a base64 string to bytes. */
198
+ decode(b64: string): Uint8Array;
199
+ }
200
+ /**
201
+ * File source abstraction for cross-environment compatibility.
202
+ * Works with browser File/Blob and can be implemented for Node.js streams.
203
+ */
204
+ interface FileSource {
205
+ /** File name. */
206
+ readonly name: string;
207
+ /** File size in bytes. */
208
+ readonly size: number;
209
+ /** MIME type of the file. */
210
+ readonly type?: string;
211
+ /** Extract a slice of the file. */
212
+ slice(start: number, end: number): FileSource;
213
+ /** Read the entire file as an ArrayBuffer. */
214
+ arrayBuffer(): Promise<ArrayBuffer>;
215
+ }
216
+ /**
217
+ * Logger function type for debug and diagnostic output.
218
+ * @param level - Log level (debug, info, warn, error).
219
+ * @param message - Log message.
220
+ * @param meta - Optional metadata object.
221
+ */
222
+ type LoggerFn = (level: 'debug' | 'info' | 'warn' | 'error', message: string, meta?: unknown) => void;
223
+ /**
224
+ * Options for constructing a DropgateClient instance.
225
+ */
226
+ interface DropgateClientOptions {
227
+ /** Client version string for compatibility checking with the server. */
228
+ clientVersion: string;
229
+ /** Upload chunk size in bytes (default: 5MB). */
230
+ chunkSize?: number;
231
+ /** Custom fetch implementation (uses global fetch by default). */
232
+ fetchFn?: FetchFn;
233
+ /** Custom crypto implementation (uses global crypto by default). */
234
+ cryptoObj?: CryptoAdapter;
235
+ /** Custom base64 encoder/decoder. */
236
+ base64?: Base64Adapter;
237
+ /** Custom logger function for debug output. */
238
+ logger?: LoggerFn;
239
+ }
240
+ /**
241
+ * Common server target options specifying the server to connect to.
242
+ */
243
+ interface ServerTarget {
244
+ /** Server hostname (e.g., 'dropgate.link'). */
245
+ host: string;
246
+ /** Server port number (omit for default 80/443). */
247
+ port?: number;
248
+ /** Whether to use HTTPS (default: true). */
249
+ secure?: boolean;
250
+ }
251
+ /**
252
+ * Options for uploading a file to the server.
253
+ */
254
+ interface UploadOptions extends ServerTarget {
255
+ /** File to upload. */
256
+ file: FileSource;
257
+ /** File lifetime in milliseconds (0 = server default). */
258
+ lifetimeMs: number;
259
+ /** Whether to encrypt the file with E2EE. */
260
+ encrypt: boolean;
261
+ /** Override the filename sent to the server. */
262
+ filenameOverride?: string;
263
+ /** Callback for progress updates. */
264
+ onProgress?: (evt: ProgressEvent) => void;
265
+ /** AbortSignal to cancel the upload. */
266
+ signal?: AbortSignal;
267
+ /** Timeout settings for various upload phases. */
268
+ timeouts?: {
269
+ /** Timeout for fetching server info (default: 5000ms). */
270
+ serverInfoMs?: number;
271
+ /** Timeout for upload initialization (default: 15000ms). */
272
+ initMs?: number;
273
+ /** Timeout for each chunk upload (default: 60000ms). */
274
+ chunkMs?: number;
275
+ /** Timeout for upload completion (default: 30000ms). */
276
+ completeMs?: number;
277
+ };
278
+ /** Retry settings for failed chunk uploads. */
279
+ retry?: {
280
+ /** Maximum number of retries per chunk (default: 5). */
281
+ retries?: number;
282
+ /** Initial backoff delay in milliseconds (default: 1000ms). */
283
+ backoffMs?: number;
284
+ /** Maximum backoff delay in milliseconds (default: 30000ms). */
285
+ maxBackoffMs?: number;
286
+ };
287
+ }
288
+ /**
289
+ * Options for fetching server information.
290
+ */
291
+ interface GetServerInfoOptions extends ServerTarget {
292
+ /** Request timeout in milliseconds (default: 5000ms). */
293
+ timeoutMs?: number;
294
+ /** AbortSignal to cancel the request. */
295
+ signal?: AbortSignal;
296
+ }
297
+ /**
298
+ * Options for validating upload inputs before starting an upload.
299
+ */
300
+ interface ValidateUploadOptions {
301
+ /** File to validate. */
302
+ file: FileSource;
303
+ /** Requested file lifetime in milliseconds. */
304
+ lifetimeMs: number;
305
+ /** Whether encryption will be used. */
306
+ encrypt: boolean;
307
+ /** Server info containing capabilities to validate against. */
308
+ serverInfo: ServerInfo;
309
+ }
310
+ /**
311
+ * File metadata returned from the server.
312
+ */
313
+ interface FileMetadata {
314
+ /** Whether the file is encrypted. */
315
+ isEncrypted: boolean;
316
+ /** File size in bytes (encrypted size if encrypted). */
317
+ sizeBytes: number;
318
+ /** Original filename (only for unencrypted files). */
319
+ filename?: string;
320
+ /** Encrypted filename (only for encrypted files). */
321
+ encryptedFilename?: string;
322
+ }
323
+ /**
324
+ * Download progress event.
325
+ */
326
+ interface DownloadProgressEvent {
327
+ /** Current phase of the download. */
328
+ phase: 'metadata' | 'downloading' | 'decrypting' | 'complete';
329
+ /** Human-readable status text. */
330
+ text?: string;
331
+ /** Bytes received so far. */
332
+ receivedBytes: number;
333
+ /** Total bytes expected (may be 0 if unknown). */
334
+ totalBytes: number;
335
+ /** Completion percentage (0-100). */
336
+ percent: number;
337
+ }
338
+ /**
339
+ * Options for downloading a file.
340
+ */
341
+ interface DownloadOptions extends ServerTarget {
342
+ /** File ID to download. */
343
+ fileId: string;
344
+ /** Base64-encoded decryption key (required for encrypted files). */
345
+ keyB64?: string;
346
+ /** Callback for progress updates. */
347
+ onProgress?: (evt: DownloadProgressEvent) => void;
348
+ /** Callback for received data chunks. Consumer handles file writing. */
349
+ onData?: (chunk: Uint8Array) => Promise<void> | void;
350
+ /** AbortSignal to cancel the download. */
351
+ signal?: AbortSignal;
352
+ /** Request timeout in milliseconds (default: 60000ms). */
353
+ timeoutMs?: number;
354
+ }
355
+ /**
356
+ * Result of a file download.
357
+ */
358
+ interface DownloadResult {
359
+ /** Decrypted filename. */
360
+ filename: string;
361
+ /** Total bytes received. */
362
+ receivedBytes: number;
363
+ /** Whether the file was encrypted. */
364
+ wasEncrypted: boolean;
365
+ /** The file data (only if onData callback was not provided). */
366
+ data?: Uint8Array;
367
+ }
368
+
369
+ /**
370
+ * Convert a Uint8Array to a base64 string
371
+ */
372
+ declare function bytesToBase64(bytes: Uint8Array, adapter?: Base64Adapter): string;
373
+ /**
374
+ * Convert an ArrayBuffer to a base64 string
375
+ */
376
+ declare function arrayBufferToBase64(buf: ArrayBuffer, adapter?: Base64Adapter): string;
377
+ /**
378
+ * Convert a base64 string to a Uint8Array
379
+ */
380
+ declare function base64ToBytes(b64: string, adapter?: Base64Adapter): Uint8Array;
381
+
382
+ type LifetimeUnit = 'minutes' | 'hours' | 'days' | 'unlimited';
383
+ /**
384
+ * Convert a lifetime value and unit to milliseconds.
385
+ * Returns 0 for 'unlimited' or invalid inputs.
386
+ */
387
+ declare function lifetimeToMs(value: number, unit: LifetimeUnit | string): number;
388
+
389
+ interface SemverParts {
390
+ major: number;
391
+ minor: number;
392
+ }
393
+ /**
394
+ * Parse a semver string and extract major.minor parts.
395
+ * Returns { major: 0, minor: 0 } for invalid inputs.
396
+ */
397
+ declare function parseSemverMajorMinor(version: string | undefined | null): SemverParts;
398
+
399
+ /**
400
+ * Validate a plain (non-encrypted) filename.
401
+ * Throws DropgateValidationError if invalid.
402
+ */
403
+ declare function validatePlainFilename(filename: string): void;
404
+
405
+ /**
406
+ * Parse a server URL string into host, port, and secure components.
407
+ * If no protocol is specified, defaults to HTTPS.
408
+ */
409
+ declare function parseServerUrl(urlStr: string): ServerTarget;
410
+ /**
411
+ * Build a base URL from host, port, and secure options.
412
+ */
413
+ declare function buildBaseUrl(opts: ServerTarget): string;
414
+ /**
415
+ * Sleep for a specified duration, with optional abort signal support.
416
+ */
417
+ declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
418
+ interface AbortSignalWithCleanup {
419
+ signal: AbortSignal;
420
+ cleanup: () => void;
421
+ }
422
+ /**
423
+ * Create an AbortSignal that combines a parent signal with a timeout.
424
+ */
425
+ declare function makeAbortSignal(parentSignal?: AbortSignal | null, timeoutMs?: number): AbortSignalWithCleanup;
426
+ interface FetchJsonResult {
427
+ res: Response;
428
+ json: unknown;
429
+ text: string;
430
+ }
431
+ interface FetchJsonOptions extends Omit<RequestInit, 'signal'> {
432
+ timeoutMs?: number;
433
+ signal?: AbortSignal;
434
+ }
435
+ /**
436
+ * Fetch JSON from a URL with timeout and error handling.
437
+ */
438
+ declare function fetchJson(fetchFn: FetchFn, url: string, opts?: FetchJsonOptions): Promise<FetchJsonResult>;
439
+
440
+ /**
441
+ * Import a base64-encoded AES-GCM key.
442
+ * @param cryptoObj - Crypto adapter for key import.
443
+ * @param keyB64 - Base64-encoded key bytes.
444
+ * @param base64 - Optional base64 adapter.
445
+ * @returns The imported CryptoKey.
446
+ */
447
+ declare function importKeyFromBase64(cryptoObj: CryptoAdapter, keyB64: string, base64?: Base64Adapter): Promise<CryptoKey>;
448
+ /**
449
+ * Decrypt an AES-GCM encrypted chunk.
450
+ * Expected layout: [IV (12 bytes)] + [ciphertext + tag]
451
+ * @param cryptoObj - Crypto adapter for decryption.
452
+ * @param encryptedData - The encrypted data with IV prepended.
453
+ * @param key - The AES-GCM decryption key.
454
+ * @returns The decrypted data as ArrayBuffer.
455
+ */
456
+ declare function decryptChunk(cryptoObj: CryptoAdapter, encryptedData: Uint8Array, key: CryptoKey): Promise<ArrayBuffer>;
457
+ /**
458
+ * Decrypt a base64-encoded encrypted filename.
459
+ * @param cryptoObj - Crypto adapter for decryption.
460
+ * @param encryptedFilenameB64 - Base64-encoded encrypted filename.
461
+ * @param key - The AES-GCM decryption key.
462
+ * @param base64 - Optional base64 adapter.
463
+ * @returns The decrypted filename string.
464
+ */
465
+ declare function decryptFilenameFromBase64(cryptoObj: CryptoAdapter, encryptedFilenameB64: string, key: CryptoKey, base64?: Base64Adapter): Promise<string>;
466
+
467
+ /**
468
+ * Compute SHA-256 hash of data and return as hex string.
469
+ */
470
+ declare function sha256Hex(cryptoObj: CryptoAdapter, data: ArrayBuffer): Promise<string>;
471
+ /**
472
+ * Generate a new AES-GCM 256-bit encryption key.
473
+ */
474
+ declare function generateAesGcmKey(cryptoObj: CryptoAdapter): Promise<CryptoKey>;
475
+ /**
476
+ * Export a CryptoKey to a base64-encoded raw key.
477
+ */
478
+ declare function exportKeyBase64(cryptoObj: CryptoAdapter, key: CryptoKey): Promise<string>;
479
+
480
+ /**
481
+ * Encrypt data using AES-GCM and return as a Blob with IV prepended.
482
+ * Layout: [IV (12 bytes)] + [ciphertext + tag]
483
+ */
484
+ declare function encryptToBlob(cryptoObj: CryptoAdapter, dataBuffer: ArrayBuffer, key: CryptoKey): Promise<Blob>;
485
+ /**
486
+ * Encrypt a filename using AES-GCM and return as base64.
487
+ */
488
+ declare function encryptFilenameToBase64(cryptoObj: CryptoAdapter, filename: string, key: CryptoKey): Promise<string>;
489
+
490
+ /**
491
+ * Estimate total upload size including encryption overhead.
492
+ */
493
+ declare function estimateTotalUploadSizeBytes(fileSizeBytes: number, totalChunks: number, isEncrypted: boolean): number;
494
+ /**
495
+ * Headless, environment-agnostic client for Dropgate file uploads.
496
+ * Handles server communication, encryption, and chunked uploads.
497
+ */
498
+ declare class DropgateClient {
499
+ /** Client version string for compatibility checking. */
500
+ readonly clientVersion: string;
501
+ /** Chunk size in bytes for upload splitting. */
502
+ readonly chunkSize: number;
503
+ /** Fetch implementation used for HTTP requests. */
504
+ readonly fetchFn: FetchFn;
505
+ /** Crypto implementation for encryption operations. */
506
+ readonly cryptoObj: CryptoAdapter;
507
+ /** Base64 encoder/decoder for binary data. */
508
+ readonly base64: Base64Adapter;
509
+ /** Optional logger for debug output. */
510
+ readonly logger: LoggerFn | null;
511
+ /**
512
+ * Create a new DropgateClient instance.
513
+ * @param opts - Client configuration options.
514
+ * @throws {DropgateValidationError} If clientVersion is missing or invalid.
515
+ */
516
+ constructor(opts: DropgateClientOptions);
517
+ /**
518
+ * Fetch server information from the /api/info endpoint.
519
+ * @param opts - Server target and request options.
520
+ * @returns The server base URL and server info object.
521
+ * @throws {DropgateNetworkError} If the server cannot be reached.
522
+ * @throws {DropgateProtocolError} If the server returns an invalid response.
523
+ */
524
+ getServerInfo(opts: GetServerInfoOptions): Promise<{
525
+ baseUrl: string;
526
+ serverInfo: ServerInfo;
527
+ }>;
528
+ /**
529
+ * Resolve a user-entered sharing code or URL via the server.
530
+ * @param value - The sharing code or URL to resolve.
531
+ * @param opts - Server target and request options.
532
+ * @returns The resolved share target information.
533
+ * @throws {DropgateProtocolError} If the share lookup fails.
534
+ */
535
+ resolveShareTarget(value: string, opts: GetServerInfoOptions): Promise<ShareTargetResult>;
536
+ /**
537
+ * Check version compatibility between this client and a server.
538
+ * @param serverInfo - Server info containing the version to check against.
539
+ * @returns Compatibility result with status and message.
540
+ */
541
+ checkCompatibility(serverInfo: ServerInfo): CompatibilityResult;
542
+ /**
543
+ * Validate file and upload settings against server capabilities.
544
+ * @param opts - Validation options containing file, settings, and server info.
545
+ * @returns True if validation passes.
546
+ * @throws {DropgateValidationError} If any validation check fails.
547
+ */
548
+ validateUploadInputs(opts: ValidateUploadOptions): boolean;
549
+ /**
550
+ * Upload a file to the server with optional encryption.
551
+ * @param opts - Upload options including file, server target, and settings.
552
+ * @returns Upload result containing the download URL and file identifiers.
553
+ * @throws {DropgateValidationError} If input validation fails.
554
+ * @throws {DropgateNetworkError} If the server cannot be reached.
555
+ * @throws {DropgateProtocolError} If the server returns an error.
556
+ * @throws {DropgateAbortError} If the upload is cancelled.
557
+ */
558
+ uploadFile(opts: UploadOptions): Promise<UploadResult>;
559
+ /**
560
+ * Download a file from the server with optional decryption.
561
+ *
562
+ * **Important:** For large files, you must provide an `onData` callback to stream
563
+ * data incrementally. Without it, the entire file is buffered in memory, which will
564
+ * cause memory exhaustion for large files. Files exceeding 100MB without an `onData`
565
+ * callback will throw a validation error.
566
+ *
567
+ * @param opts - Download options including file ID, server target, and optional key.
568
+ * @param opts.onData - Streaming callback that receives data chunks. Required for files > 100MB.
569
+ * @returns Download result containing filename and received bytes.
570
+ * @throws {DropgateValidationError} If input validation fails or file is too large without onData.
571
+ * @throws {DropgateNetworkError} If the server cannot be reached.
572
+ * @throws {DropgateProtocolError} If the server returns an error.
573
+ * @throws {DropgateAbortError} If the download is cancelled.
574
+ */
575
+ downloadFile(opts: DownloadOptions): Promise<DownloadResult>;
576
+ private attemptChunkUpload;
577
+ }
578
+
579
+ /**
580
+ * Get the default Base64 adapter for the current environment.
581
+ * Automatically detects Node.js Buffer vs browser btoa/atob.
582
+ */
583
+ declare function getDefaultBase64(): Base64Adapter;
584
+ /**
585
+ * Get the default crypto object for the current environment.
586
+ * Returns globalThis.crypto if available.
587
+ */
588
+ declare function getDefaultCrypto(): CryptoAdapter | undefined;
589
+ /**
590
+ * Get the default fetch function for the current environment.
591
+ * Returns globalThis.fetch if available.
592
+ */
593
+ declare function getDefaultFetch(): FetchFn | undefined;
594
+
595
+ /**
596
+ * PeerJS Peer constructor interface.
597
+ * Consumer must provide this constructor to P2P functions.
598
+ */
599
+ interface PeerConstructor {
600
+ new (id?: string, options?: PeerOptions): PeerInstance;
601
+ }
602
+ /**
603
+ * PeerJS connection options.
604
+ */
605
+ interface PeerOptions {
606
+ /** PeerJS server hostname. */
607
+ host?: string;
608
+ /** PeerJS server port. */
609
+ port?: number;
610
+ /** PeerJS server path. */
611
+ path?: string;
612
+ /** Whether to use secure WebSocket connection. */
613
+ secure?: boolean;
614
+ /** WebRTC configuration. */
615
+ config?: {
616
+ /** ICE servers for NAT traversal. */
617
+ iceServers?: RTCIceServer[];
618
+ };
619
+ /** PeerJS debug level (0-3). */
620
+ debug?: number;
621
+ }
622
+ /**
623
+ * PeerJS Peer instance interface.
624
+ * Represents a connection to the PeerJS signaling server.
625
+ */
626
+ interface PeerInstance {
627
+ /** Register an event handler. */
628
+ on(event: 'open', callback: (id: string) => void): void;
629
+ on(event: 'connection', callback: (conn: DataConnection) => void): void;
630
+ on(event: 'error', callback: (err: Error) => void): void;
631
+ on(event: 'close', callback: () => void): void;
632
+ on(event: string, callback: (...args: unknown[]) => void): void;
633
+ /** Connect to another peer by ID. */
634
+ connect(peerId: string, options?: {
635
+ reliable?: boolean;
636
+ }): DataConnection;
637
+ /** Destroy this peer and close all connections. */
638
+ destroy(): void;
639
+ }
640
+ /**
641
+ * PeerJS DataConnection interface.
642
+ * Represents a WebRTC data channel connection between peers.
643
+ */
644
+ interface DataConnection {
645
+ /** Register an event handler. */
646
+ on(event: 'open', callback: () => void): void;
647
+ on(event: 'data', callback: (data: unknown) => void): void;
648
+ on(event: 'close', callback: () => void): void;
649
+ on(event: 'error', callback: (err: Error) => void): void;
650
+ on(event: string, callback: (...args: unknown[]) => void): void;
651
+ /** Send data to the connected peer. */
652
+ send(data: unknown): void;
653
+ /** Close the data connection. */
654
+ close(): void;
655
+ /** Internal WebRTC data channel (for buffer monitoring). */
656
+ _dc?: RTCDataChannel;
657
+ }
658
+ /**
659
+ * Options for starting a P2P send session.
660
+ */
661
+ interface P2PSendOptions {
662
+ /** File to send */
663
+ file: FileSource;
664
+ /** PeerJS Peer constructor - REQUIRED */
665
+ Peer: PeerConstructor;
666
+ /** Server info (optional, for capability checking) */
667
+ serverInfo?: ServerInfo;
668
+ /** PeerJS server host */
669
+ host?: string;
670
+ /** PeerJS server port */
671
+ port?: number;
672
+ /** PeerJS server path (default: /peerjs) */
673
+ peerjsPath?: string;
674
+ /** Whether to use secure connection */
675
+ secure?: boolean;
676
+ /** ICE servers for WebRTC */
677
+ iceServers?: RTCIceServer[];
678
+ /** Custom code generator function */
679
+ codeGenerator?: (cryptoObj?: CryptoAdapter) => string;
680
+ /** Crypto object for secure code generation */
681
+ cryptoObj?: CryptoAdapter;
682
+ /** Max attempts to register a peer ID */
683
+ maxAttempts?: number;
684
+ /** Chunk size for data transfer */
685
+ chunkSize?: number;
686
+ /** Timeout waiting for receiver ready signal */
687
+ readyTimeoutMs?: number;
688
+ /** Timeout waiting for end acknowledgment */
689
+ endAckTimeoutMs?: number;
690
+ /** Buffer high water mark for flow control */
691
+ bufferHighWaterMark?: number;
692
+ /** Buffer low water mark for flow control */
693
+ bufferLowWaterMark?: number;
694
+ /** Callback when code is generated */
695
+ onCode?: (code: string, attempt: number) => void;
696
+ /** Callback for status updates */
697
+ onStatus?: (evt: {
698
+ phase: string;
699
+ message: string;
700
+ }) => void;
701
+ /** Callback for progress updates */
702
+ onProgress?: (evt: {
703
+ sent: number;
704
+ total: number;
705
+ percent: number;
706
+ }) => void;
707
+ /** Callback when transfer completes */
708
+ onComplete?: () => void;
709
+ /** Callback on error */
710
+ onError?: (err: Error) => void;
711
+ }
712
+ /**
713
+ * Return value from startP2PSend containing session control.
714
+ */
715
+ interface P2PSendSession {
716
+ /** The PeerJS peer instance. */
717
+ peer: PeerInstance;
718
+ /** The generated sharing code. */
719
+ code: string;
720
+ /** Stop the session and clean up resources. */
721
+ stop: () => void;
722
+ }
723
+ /**
724
+ * Options for starting a P2P receive session.
725
+ */
726
+ interface P2PReceiveOptions {
727
+ /** Sharing code to connect to */
728
+ code: string;
729
+ /** PeerJS Peer constructor - REQUIRED */
730
+ Peer: PeerConstructor;
731
+ /** Server info (optional, for capability checking) */
732
+ serverInfo?: ServerInfo;
733
+ /** PeerJS server host */
734
+ host?: string;
735
+ /** PeerJS server port */
736
+ port?: number;
737
+ /** PeerJS server path (default: /peerjs) */
738
+ peerjsPath?: string;
739
+ /** Whether to use secure connection */
740
+ secure?: boolean;
741
+ /** ICE servers for WebRTC */
742
+ iceServers?: RTCIceServer[];
743
+ /** Callback for status updates */
744
+ onStatus?: (evt: {
745
+ phase: string;
746
+ message: string;
747
+ }) => void;
748
+ /** Callback when file metadata is received */
749
+ onMeta?: (evt: {
750
+ name: string;
751
+ total: number;
752
+ }) => void;
753
+ /** Callback when data chunk is received - consumer handles file writing */
754
+ onData?: (chunk: Uint8Array) => Promise<void> | void;
755
+ /** Callback for progress updates */
756
+ onProgress?: (evt: {
757
+ received: number;
758
+ total: number;
759
+ percent: number;
760
+ }) => void;
761
+ /** Callback when transfer completes */
762
+ onComplete?: (evt: {
763
+ received: number;
764
+ total: number;
765
+ }) => void;
766
+ /** Callback on error */
767
+ onError?: (err: Error) => void;
768
+ /** Callback when sender disconnects */
769
+ onDisconnect?: () => void;
770
+ }
771
+ /**
772
+ * Return value from startP2PReceive containing session control.
773
+ */
774
+ interface P2PReceiveSession {
775
+ /** The PeerJS peer instance. */
776
+ peer: PeerInstance;
777
+ /** Stop the session and clean up resources. */
778
+ stop: () => void;
779
+ }
780
+
781
+ /**
782
+ * Start a direct transfer (P2P) sender session.
783
+ *
784
+ * IMPORTANT: Consumer must provide the PeerJS Peer constructor.
785
+ * This removes DOM coupling (no script injection).
786
+ *
787
+ * Example:
788
+ * ```js
789
+ * import Peer from 'peerjs';
790
+ * import { startP2PSend } from '@dropgate/core/p2p';
791
+ *
792
+ * const session = await startP2PSend({
793
+ * file: myFile,
794
+ * Peer,
795
+ * host: 'dropgate.link',
796
+ * secure: true,
797
+ * onCode: (code) => console.log('Share this code:', code),
798
+ * onProgress: (evt) => console.log(`${evt.percent}% sent`),
799
+ * onComplete: () => console.log('Done!'),
800
+ * });
801
+ * ```
802
+ */
803
+ declare function startP2PSend(opts: P2PSendOptions): Promise<P2PSendSession>;
804
+
805
+ /**
806
+ * Start a direct transfer (P2P) receiver session.
807
+ *
808
+ * IMPORTANT: Consumer must provide the PeerJS Peer constructor and handle file writing.
809
+ * This removes DOM coupling (no streamSaver).
810
+ *
811
+ * Example:
812
+ * ```js
813
+ * import Peer from 'peerjs';
814
+ * import { startP2PReceive } from '@dropgate/core/p2p';
815
+ *
816
+ * let writer;
817
+ * const session = await startP2PReceive({
818
+ * code: 'ABCD-1234',
819
+ * Peer,
820
+ * host: 'dropgate.link',
821
+ * secure: true,
822
+ * onMeta: ({ name, total }) => {
823
+ * // Consumer creates file writer
824
+ * writer = createWriteStream(name);
825
+ * },
826
+ * onData: async (chunk) => {
827
+ * // Consumer writes data
828
+ * await writer.write(chunk);
829
+ * },
830
+ * onComplete: () => {
831
+ * writer.close();
832
+ * console.log('Done!');
833
+ * },
834
+ * });
835
+ * ```
836
+ */
837
+ declare function startP2PReceive(opts: P2PReceiveOptions): Promise<P2PReceiveSession>;
838
+
839
+ /**
840
+ * Check if a hostname is localhost
841
+ */
842
+ declare function isLocalhostHostname(hostname: string): boolean;
843
+ /**
844
+ * Check if the current context allows P2P (HTTPS or localhost)
845
+ */
846
+ declare function isSecureContextForP2P(hostname?: string, isSecureContext?: boolean): boolean;
847
+ /**
848
+ * Generate a P2P sharing code using cryptographically secure random.
849
+ * Format: XXXX-0000 (4 letters + 4 digits)
850
+ */
851
+ declare function generateP2PCode(cryptoObj?: CryptoAdapter): string;
852
+ /**
853
+ * Check if a string looks like a P2P sharing code
854
+ */
855
+ declare function isP2PCodeLike(code: string): boolean;
856
+
857
+ interface BuildPeerOptionsInput {
858
+ host?: string;
859
+ port?: number;
860
+ peerjsPath?: string;
861
+ secure?: boolean;
862
+ iceServers?: RTCIceServer[];
863
+ }
864
+ /**
865
+ * Build PeerJS connection options
866
+ */
867
+ declare function buildPeerOptions(opts?: BuildPeerOptionsInput): PeerOptions;
868
+ interface CreatePeerWithRetriesOptions {
869
+ code?: string | null;
870
+ codeGenerator: () => string;
871
+ maxAttempts: number;
872
+ buildPeer: (id: string) => PeerInstance;
873
+ onCode?: (code: string, attempt: number) => void;
874
+ }
875
+ /**
876
+ * Create a peer with retries if the code is already taken
877
+ */
878
+ declare function createPeerWithRetries(opts: CreatePeerWithRetriesOptions): Promise<{
879
+ peer: PeerInstance;
880
+ code: string;
881
+ }>;
882
+
883
+ export { AES_GCM_IV_BYTES, AES_GCM_TAG_BYTES, type AbortSignalWithCleanup, type Base64Adapter, type CompatibilityResult, type CryptoAdapter, DEFAULT_CHUNK_SIZE, type DataConnection, type DownloadOptions, type DownloadProgressEvent, type DownloadResult, DropgateAbortError, DropgateClient, type DropgateClientOptions, DropgateError, type DropgateErrorOptions, DropgateNetworkError, DropgateProtocolError, DropgateTimeoutError, DropgateValidationError, ENCRYPTION_OVERHEAD_PER_CHUNK, type FetchFn, type FetchJsonOptions, type FetchJsonResult, type FileMetadata, type FileSource, type GetServerInfoOptions, type LoggerFn, type P2PCapabilities, type P2PReceiveOptions, type P2PReceiveSession, type P2PSendOptions, type P2PSendSession, type PeerConstructor, type PeerInstance, type PeerOptions, type ProgressEvent, type SemverParts, type ServerCapabilities, type ServerInfo, type ServerTarget, type ShareTargetResult, type UploadCapabilities, type UploadOptions, type UploadResult, type ValidateUploadOptions, type WebUICapabilities, arrayBufferToBase64, base64ToBytes, buildBaseUrl, buildPeerOptions, bytesToBase64, createPeerWithRetries, decryptChunk, decryptFilenameFromBase64, encryptFilenameToBase64, encryptToBlob, estimateTotalUploadSizeBytes, exportKeyBase64, fetchJson, generateAesGcmKey, generateP2PCode, getDefaultBase64, getDefaultCrypto, getDefaultFetch, importKeyFromBase64, isLocalhostHostname, isP2PCodeLike, isSecureContextForP2P, lifetimeToMs, makeAbortSignal, parseSemverMajorMinor, parseServerUrl, sha256Hex, sleep, startP2PReceive, startP2PSend, validatePlainFilename };