yungle-client 0.3.0 → 0.3.2
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 +2 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.mjs +27 -15
- package/dist/types.d.ts +17 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -85,12 +85,12 @@ refused. No public URL? Create the endpoint with `url: null` and poll `listWebho
|
|
|
85
85
|
|
|
86
86
|
Your vault and end-to-end encrypted transfers, because their keys are derived in
|
|
87
87
|
the client and never sent to Yungle. See
|
|
88
|
-
<https://yungle.co/
|
|
88
|
+
<https://docs.yungle.co/unsupported>.
|
|
89
89
|
|
|
90
90
|
## Related
|
|
91
91
|
|
|
92
92
|
- [`yungle-cli`](https://www.npmjs.com/package/yungle-cli) — resumable uploads from your terminal
|
|
93
93
|
- [`yungle-mcp`](https://www.npmjs.com/package/yungle-mcp) — connect Claude or Cursor to Yungle
|
|
94
|
-
- [API reference](https://yungle.co/
|
|
94
|
+
- [API reference](https://docs.yungle.co/api-reference?ref=npm) · [OpenAPI spec](https://yungle.co/api/v1/openapi.json)
|
|
95
95
|
|
|
96
96
|
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Collection, CollectionFile, CollectionSummary, Contact, ContactInput, DownloadEvent, DownloadLinks, ImportInput, ImportStatus, Submission, UploadRequest, UploadRequestInput, FileInput, Folder, Guest, Me, PulledWebhookEvent, RecipientStatus, Transfer, TransferFile, TransferSummary, UploadTargets, WebhookDelivery, WebhookEndpoint, WebhookEventType } from './types.js';
|
|
1
|
+
import type { Collection, CollectionFile, CollectionSummary, Contact, ContactInput, DownloadEvent, DownloadLinks, ImportInput, ImportStatus, Submission, UploadRequest, UploadRequestInput, FileInput, Folder, Guest, Me, Referral, PulledWebhookEvent, RecipientStatus, Transfer, TransferFile, TransferSummary, UploadTargets, WebhookDelivery, WebhookEndpoint, WebhookEventType } from './types.js';
|
|
2
2
|
import { type RenewOutcome as Renewal } from './upload-token.js';
|
|
3
3
|
import { type UploadFileOptions } from './upload.js';
|
|
4
4
|
export { chunkSize, uploadFile, UploadError, type UploadFileOptions } from './upload.js';
|
|
@@ -106,6 +106,8 @@ export declare class YungleClient {
|
|
|
106
106
|
uploadUrl: string;
|
|
107
107
|
}>;
|
|
108
108
|
me(): Promise<Me>;
|
|
109
|
+
/** Your invite code and link, and the free months it has earned. */
|
|
110
|
+
getReferral(): Promise<Referral>;
|
|
109
111
|
/**
|
|
110
112
|
* One page of transfers, newest first — 100 by default, up to 500. Pass the
|
|
111
113
|
* returned `nextCursor` back as `cursor` for the next page; it is null on the
|
package/dist/index.mjs
CHANGED
|
@@ -220,7 +220,7 @@ function pageQuery(page, extra = {}) {
|
|
|
220
220
|
const q = params.toString();
|
|
221
221
|
return q ? `?${q}` : "";
|
|
222
222
|
}
|
|
223
|
-
var CLIENT_VERSION = true ? "0.3.
|
|
223
|
+
var CLIENT_VERSION = true ? "0.3.2" : "dev";
|
|
224
224
|
var YungleClient = class {
|
|
225
225
|
baseUrl;
|
|
226
226
|
apiKey;
|
|
@@ -260,6 +260,10 @@ var YungleClient = class {
|
|
|
260
260
|
me() {
|
|
261
261
|
return this.request("GET", "/me");
|
|
262
262
|
}
|
|
263
|
+
/** Your invite code and link, and the free months it has earned. */
|
|
264
|
+
getReferral() {
|
|
265
|
+
return this.request("GET", "/me/referral");
|
|
266
|
+
}
|
|
263
267
|
// ── Transfers ─────────────────────────────────────────────────────────────
|
|
264
268
|
/**
|
|
265
269
|
* One page of transfers, newest first — 100 by default, up to 500. Pass the
|
|
@@ -504,22 +508,31 @@ var YungleClient = class {
|
|
|
504
508
|
const safe = method === "GET" || method === "DELETE" || idempotencyKey !== void 0 || opts?.idempotent === true;
|
|
505
509
|
let attempt = 0;
|
|
506
510
|
for (; ; ) {
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
511
|
+
let res;
|
|
512
|
+
try {
|
|
513
|
+
res = await this.doFetch(`${this.baseUrl}${path}`, {
|
|
514
|
+
method,
|
|
515
|
+
headers: {
|
|
516
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
517
|
+
Accept: "application/json",
|
|
518
|
+
"User-Agent": this.userAgent,
|
|
519
|
+
...idempotencyKey ? { "Idempotency-Key": idempotencyKey } : {},
|
|
520
|
+
...body === void 0 ? {} : { "Content-Type": "application/json" }
|
|
521
|
+
},
|
|
522
|
+
...body === void 0 ? {} : { body: JSON.stringify(body) }
|
|
523
|
+
});
|
|
524
|
+
} catch (err) {
|
|
525
|
+
const aborted = err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError");
|
|
526
|
+
if (aborted || !safe || attempt >= this.maxRetries) throw err;
|
|
527
|
+
await sleep(backoffMs(attempt, null));
|
|
528
|
+
attempt++;
|
|
529
|
+
continue;
|
|
530
|
+
}
|
|
518
531
|
if (res.ok) return await res.json();
|
|
519
532
|
const error = await toError(res);
|
|
520
533
|
const mayRetry = error.status === 429 || safe && error.retryable;
|
|
521
534
|
if (!mayRetry || attempt >= this.maxRetries) throw error;
|
|
522
|
-
await sleep(backoffMs(attempt, error));
|
|
535
|
+
await sleep(backoffMs(attempt, error.retryAfterSeconds));
|
|
523
536
|
attempt++;
|
|
524
537
|
}
|
|
525
538
|
}
|
|
@@ -555,8 +568,7 @@ function parseRetryAfter(value, now = Date.now()) {
|
|
|
555
568
|
const seconds = Math.ceil((at - now) / 1e3);
|
|
556
569
|
return seconds >= 0 ? seconds : null;
|
|
557
570
|
}
|
|
558
|
-
function backoffMs(attempt,
|
|
559
|
-
const stated = error.retryAfterSeconds;
|
|
571
|
+
function backoffMs(attempt, stated) {
|
|
560
572
|
if (stated !== null) return stated * 1e3;
|
|
561
573
|
return Math.min(2 ** attempt * 500, 8e3) + Math.floor(Math.random() * 250);
|
|
562
574
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -40,6 +40,23 @@ export interface KeyInfo {
|
|
|
40
40
|
/** Whether this credential may make Yungle email anyone. Absent on older servers. */
|
|
41
41
|
canEmail?: boolean;
|
|
42
42
|
}
|
|
43
|
+
/** Your invite code and what it has earned (`GET /me/referral`). */
|
|
44
|
+
export interface Referral {
|
|
45
|
+
/** Your invite code. A friend can type it in Settings › Plan. */
|
|
46
|
+
code: string;
|
|
47
|
+
/** Your invite link: the same code, as a page that signs them up. */
|
|
48
|
+
url: string;
|
|
49
|
+
/** Free months earned so far. */
|
|
50
|
+
earnedMonths: number;
|
|
51
|
+
/** Free months still available to earn. */
|
|
52
|
+
remainingMonths: number;
|
|
53
|
+
/** The most free months one person can earn, ever. */
|
|
54
|
+
cap: number;
|
|
55
|
+
/** True once `earnedMonths` reached `cap`. The link still gives friends their month. */
|
|
56
|
+
capped: boolean;
|
|
57
|
+
/** Friends in their free month, or inside the 14 days after their first payment. */
|
|
58
|
+
pending: number;
|
|
59
|
+
}
|
|
43
60
|
export interface Me {
|
|
44
61
|
workspace: Workspace;
|
|
45
62
|
plan: PlanInfo;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yungle-client",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"type": "git",
|
|
23
23
|
"url": "git+https://github.com/heindewilde/yungle-clients.git"
|
|
24
24
|
},
|
|
25
|
-
"homepage": "https://yungle.co/
|
|
25
|
+
"homepage": "https://docs.yungle.co/api-reference?ref=npm",
|
|
26
26
|
"bugs": {
|
|
27
27
|
"url": "https://github.com/heindewilde/yungle-clients/issues"
|
|
28
28
|
},
|