@37signals/basecamp 0.12.0 → 0.14.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 +114 -17
- package/dist/.build-complete +0 -0
- package/dist/client.d.ts +53 -11
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +132 -150
- package/dist/client.js.map +1 -1
- package/dist/download.d.ts +7 -0
- package/dist/download.d.ts.map +1 -1
- package/dist/download.js +82 -22
- package/dist/download.js.map +1 -1
- package/dist/errors.d.ts +19 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +138 -14
- package/dist/errors.js.map +1 -1
- package/dist/generated/metadata.d.ts.map +1 -1
- package/dist/generated/metadata.js +291 -141
- package/dist/generated/metadata.js.map +1 -1
- package/dist/generated/metadata.ts +291 -141
- package/dist/generated/openapi-stripped.json +5954 -3523
- package/dist/generated/path-mapping.d.ts.map +1 -1
- package/dist/generated/path-mapping.js +28 -16
- package/dist/generated/path-mapping.js.map +1 -1
- package/dist/generated/path-mapping.ts +28 -16
- package/dist/generated/schema.d.ts +4390 -2357
- package/dist/generated/services/bookmarks.d.ts +1 -1
- package/dist/generated/services/bookmarks.d.ts.map +1 -1
- package/dist/generated/services/bookmarks.ts +1 -1
- package/dist/generated/services/boosts.d.ts +10 -0
- package/dist/generated/services/boosts.d.ts.map +1 -1
- package/dist/generated/services/boosts.js +8 -0
- package/dist/generated/services/boosts.js.map +1 -1
- package/dist/generated/services/boosts.ts +12 -0
- package/dist/generated/services/campfires.d.ts +54 -40
- package/dist/generated/services/campfires.d.ts.map +1 -1
- package/dist/generated/services/campfires.js +82 -65
- package/dist/generated/services/campfires.js.map +1 -1
- package/dist/generated/services/campfires.ts +107 -85
- package/dist/generated/services/cards.d.ts +5 -0
- package/dist/generated/services/cards.d.ts.map +1 -1
- package/dist/generated/services/cards.js +4 -0
- package/dist/generated/services/cards.js.map +1 -1
- package/dist/generated/services/cards.ts +6 -0
- package/dist/generated/services/checkins.d.ts +14 -0
- package/dist/generated/services/checkins.d.ts.map +1 -1
- package/dist/generated/services/checkins.js +14 -1
- package/dist/generated/services/checkins.js.map +1 -1
- package/dist/generated/services/checkins.ts +20 -0
- package/dist/generated/services/client-approvals.d.ts +6 -3
- package/dist/generated/services/client-approvals.d.ts.map +1 -1
- package/dist/generated/services/client-approvals.js +8 -5
- package/dist/generated/services/client-approvals.js.map +1 -1
- package/dist/generated/services/client-approvals.ts +10 -5
- package/dist/generated/services/client-correspondences.d.ts +6 -3
- package/dist/generated/services/client-correspondences.d.ts.map +1 -1
- package/dist/generated/services/client-correspondences.js +8 -5
- package/dist/generated/services/client-correspondences.js.map +1 -1
- package/dist/generated/services/client-correspondences.ts +10 -5
- package/dist/generated/services/client-replies.d.ts +11 -4
- package/dist/generated/services/client-replies.d.ts.map +1 -1
- package/dist/generated/services/client-replies.js +16 -8
- package/dist/generated/services/client-replies.js.map +1 -1
- package/dist/generated/services/client-replies.ts +18 -8
- package/dist/generated/services/cloud-files.d.ts +92 -0
- package/dist/generated/services/cloud-files.d.ts.map +1 -0
- package/dist/generated/services/cloud-files.js +121 -0
- package/dist/generated/services/cloud-files.js.map +1 -0
- package/dist/generated/services/cloud-files.ts +188 -0
- package/dist/generated/services/comments.d.ts +5 -0
- package/dist/generated/services/comments.d.ts.map +1 -1
- package/dist/generated/services/comments.js +4 -0
- package/dist/generated/services/comments.js.map +1 -1
- package/dist/generated/services/comments.ts +6 -0
- package/dist/generated/services/documents.d.ts +12 -7
- package/dist/generated/services/documents.d.ts.map +1 -1
- package/dist/generated/services/documents.js +10 -6
- package/dist/generated/services/documents.js.map +1 -1
- package/dist/generated/services/documents.ts +14 -8
- package/dist/generated/services/drafts.d.ts +1 -1
- package/dist/generated/services/drafts.d.ts.map +1 -1
- package/dist/generated/services/drafts.ts +1 -1
- package/dist/generated/services/events.d.ts +5 -0
- package/dist/generated/services/events.d.ts.map +1 -1
- package/dist/generated/services/events.js +4 -0
- package/dist/generated/services/events.js.map +1 -1
- package/dist/generated/services/events.ts +6 -0
- package/dist/generated/services/everything.d.ts +14 -14
- package/dist/generated/services/everything.d.ts.map +1 -1
- package/dist/generated/services/everything.ts +14 -14
- package/dist/generated/services/folders.d.ts +96 -0
- package/dist/generated/services/folders.d.ts.map +1 -0
- package/dist/generated/services/folders.js +140 -0
- package/dist/generated/services/folders.js.map +1 -0
- package/dist/generated/services/folders.ts +201 -0
- package/dist/generated/services/forwards.d.ts +7 -20
- package/dist/generated/services/forwards.d.ts.map +1 -1
- package/dist/generated/services/forwards.js +6 -35
- package/dist/generated/services/forwards.js.map +1 -1
- package/dist/generated/services/forwards.ts +10 -48
- package/dist/generated/services/gauges.d.ts +7 -0
- package/dist/generated/services/gauges.d.ts.map +1 -1
- package/dist/generated/services/gauges.js +5 -1
- package/dist/generated/services/gauges.js.map +1 -1
- package/dist/generated/services/gauges.ts +9 -1
- package/dist/generated/services/google-documents.d.ts +98 -0
- package/dist/generated/services/google-documents.d.ts.map +1 -0
- package/dist/generated/services/google-documents.js +123 -0
- package/dist/generated/services/google-documents.js.map +1 -0
- package/dist/generated/services/google-documents.ts +196 -0
- package/dist/generated/services/index.d.ts +7 -4
- package/dist/generated/services/index.d.ts.map +1 -1
- package/dist/generated/services/index.js +7 -4
- package/dist/generated/services/index.js.map +1 -1
- package/dist/generated/services/index.ts +7 -4
- package/dist/generated/services/messages.d.ts +2 -0
- package/dist/generated/services/messages.d.ts.map +1 -1
- package/dist/generated/services/messages.js +1 -1
- package/dist/generated/services/messages.js.map +1 -1
- package/dist/generated/services/messages.ts +3 -1
- package/dist/generated/services/my-notes.d.ts +1 -1
- package/dist/generated/services/my-notes.js +1 -1
- package/dist/generated/services/my-notes.ts +1 -1
- package/dist/generated/services/my-notifications.d.ts +4 -2
- package/dist/generated/services/my-notifications.d.ts.map +1 -1
- package/dist/generated/services/my-notifications.js.map +1 -1
- package/dist/generated/services/my-notifications.ts +4 -2
- package/dist/generated/services/people.d.ts +11 -1
- package/dist/generated/services/people.d.ts.map +1 -1
- package/dist/generated/services/people.js +13 -2
- package/dist/generated/services/people.js.map +1 -1
- package/dist/generated/services/people.ts +15 -1
- package/dist/generated/services/projects.d.ts +26 -0
- package/dist/generated/services/projects.d.ts.map +1 -1
- package/dist/generated/services/projects.js +49 -1
- package/dist/generated/services/projects.js.map +1 -1
- package/dist/generated/services/projects.ts +61 -1
- package/dist/generated/services/recordings.d.ts +2 -12
- package/dist/generated/services/recordings.d.ts.map +1 -1
- package/dist/generated/services/recordings.js +1 -26
- package/dist/generated/services/recordings.js.map +1 -1
- package/dist/generated/services/recordings.ts +3 -31
- package/dist/generated/services/reports.d.ts +8 -12
- package/dist/generated/services/reports.d.ts.map +1 -1
- package/dist/generated/services/reports.js +11 -5
- package/dist/generated/services/reports.js.map +1 -1
- package/dist/generated/services/reports.ts +13 -14
- package/dist/generated/services/schedules.d.ts +94 -15
- package/dist/generated/services/schedules.d.ts.map +1 -1
- package/dist/generated/services/schedules.js +19 -8
- package/dist/generated/services/schedules.js.map +1 -1
- package/dist/generated/services/schedules.ts +107 -17
- package/dist/generated/services/search.d.ts +2 -0
- package/dist/generated/services/search.d.ts.map +1 -1
- package/dist/generated/services/search.js +1 -1
- package/dist/generated/services/search.js.map +1 -1
- package/dist/generated/services/search.ts +3 -1
- package/dist/generated/services/templates.d.ts +2 -0
- package/dist/generated/services/templates.d.ts.map +1 -1
- package/dist/generated/services/templates.js +1 -1
- package/dist/generated/services/templates.js.map +1 -1
- package/dist/generated/services/templates.ts +3 -1
- package/dist/generated/services/timeline.d.ts +2 -0
- package/dist/generated/services/timeline.d.ts.map +1 -1
- package/dist/generated/services/timeline.js +1 -0
- package/dist/generated/services/timeline.js.map +1 -1
- package/dist/generated/services/timeline.ts +3 -0
- package/dist/generated/services/timesheets.d.ts +16 -0
- package/dist/generated/services/timesheets.d.ts.map +1 -1
- package/dist/generated/services/timesheets.js +26 -2
- package/dist/generated/services/timesheets.js.map +1 -1
- package/dist/generated/services/timesheets.ts +35 -2
- package/dist/generated/services/todolist-groups.d.ts +11 -6
- package/dist/generated/services/todolist-groups.d.ts.map +1 -1
- package/dist/generated/services/todolist-groups.js +7 -3
- package/dist/generated/services/todolist-groups.js.map +1 -1
- package/dist/generated/services/todolist-groups.ts +13 -7
- package/dist/generated/services/todolists.d.ts +15 -13
- package/dist/generated/services/todolists.d.ts.map +1 -1
- package/dist/generated/services/todolists.js +11 -8
- package/dist/generated/services/todolists.js.map +1 -1
- package/dist/generated/services/todolists.ts +19 -14
- package/dist/generated/services/todos.d.ts +2 -12
- package/dist/generated/services/todos.d.ts.map +1 -1
- package/dist/generated/services/todos.js +1 -25
- package/dist/generated/services/todos.js.map +1 -1
- package/dist/generated/services/todos.ts +3 -30
- package/dist/generated/services/uploads.d.ts +41 -2
- package/dist/generated/services/uploads.d.ts.map +1 -1
- package/dist/generated/services/uploads.js +41 -1
- package/dist/generated/services/uploads.js.map +1 -1
- package/dist/generated/services/uploads.ts +71 -2
- package/dist/generated/services/vaults.d.ts +5 -0
- package/dist/generated/services/vaults.d.ts.map +1 -1
- package/dist/generated/services/vaults.js +4 -0
- package/dist/generated/services/vaults.js.map +1 -1
- package/dist/generated/services/vaults.ts +6 -0
- package/dist/index.d.ts +16 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -8
- package/dist/index.js.map +1 -1
- package/dist/oauth/authorization-document.d.ts +201 -0
- package/dist/oauth/authorization-document.d.ts.map +1 -0
- package/dist/oauth/authorization-document.js +130 -0
- package/dist/oauth/authorization-document.js.map +1 -0
- package/dist/oauth/identity.d.ts +7 -1
- package/dist/oauth/identity.d.ts.map +1 -1
- package/dist/oauth/identity.js +8 -19
- package/dist/oauth/identity.js.map +1 -1
- package/dist/oauth/index.d.ts +1 -0
- package/dist/oauth/index.d.ts.map +1 -1
- package/dist/oauth/index.js +2 -0
- package/dist/oauth/index.js.map +1 -1
- package/dist/pagination-utils.d.ts +46 -0
- package/dist/pagination-utils.d.ts.map +1 -1
- package/dist/pagination-utils.js +85 -2
- package/dist/pagination-utils.js.map +1 -1
- package/dist/pagination.d.ts +11 -0
- package/dist/pagination.d.ts.map +1 -1
- package/dist/pagination.js.map +1 -1
- package/dist/retry.d.ts +110 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +253 -0
- package/dist/retry.js.map +1 -0
- package/dist/services/authorization.d.ts +22 -52
- package/dist/services/authorization.d.ts.map +1 -1
- package/dist/services/authorization.js +14 -32
- package/dist/services/authorization.js.map +1 -1
- package/dist/services/base.d.ts.map +1 -1
- package/dist/services/base.js +59 -5
- package/dist/services/base.js.map +1 -1
- package/dist/services/cards-extensions.d.ts +26 -21
- package/dist/services/cards-extensions.d.ts.map +1 -1
- package/dist/services/cards-extensions.js +28 -31
- package/dist/services/cards-extensions.js.map +1 -1
- package/dist/services/documents-extensions.d.ts +122 -0
- package/dist/services/documents-extensions.d.ts.map +1 -0
- package/dist/services/documents-extensions.js +125 -0
- package/dist/services/documents-extensions.js.map +1 -0
- package/dist/services/merge-safe.d.ts +167 -0
- package/dist/services/merge-safe.d.ts.map +1 -0
- package/dist/services/merge-safe.js +217 -0
- package/dist/services/merge-safe.js.map +1 -0
- package/dist/services/schedules-extensions.d.ts +266 -0
- package/dist/services/schedules-extensions.d.ts.map +1 -0
- package/dist/services/schedules-extensions.js +268 -0
- package/dist/services/schedules-extensions.js.map +1 -0
- package/dist/services/todolists-extensions.d.ts +110 -0
- package/dist/services/todolists-extensions.d.ts.map +1 -0
- package/dist/services/todolists-extensions.js +262 -0
- package/dist/services/todolists-extensions.js.map +1 -0
- package/dist/services/todos-extensions.d.ts +12 -1
- package/dist/services/todos-extensions.d.ts.map +1 -1
- package/dist/services/todos-extensions.js +27 -8
- package/dist/services/todos-extensions.js.map +1 -1
- package/package.json +6 -5
- package/src/generated/metadata.ts +291 -141
- package/src/generated/openapi-stripped.json +5954 -3523
- package/src/generated/path-mapping.ts +28 -16
- package/src/generated/schema.d.ts +4390 -2357
- package/src/generated/services/bookmarks.ts +1 -1
- package/src/generated/services/boosts.ts +12 -0
- package/src/generated/services/campfires.ts +107 -85
- package/src/generated/services/cards.ts +6 -0
- package/src/generated/services/checkins.ts +20 -0
- package/src/generated/services/client-approvals.ts +10 -5
- package/src/generated/services/client-correspondences.ts +10 -5
- package/src/generated/services/client-replies.ts +18 -8
- package/src/generated/services/cloud-files.ts +188 -0
- package/src/generated/services/comments.ts +6 -0
- package/src/generated/services/documents.ts +14 -8
- package/src/generated/services/drafts.ts +1 -1
- package/src/generated/services/events.ts +6 -0
- package/src/generated/services/everything.ts +14 -14
- package/src/generated/services/folders.ts +201 -0
- package/src/generated/services/forwards.ts +10 -48
- package/src/generated/services/gauges.ts +9 -1
- package/src/generated/services/google-documents.ts +196 -0
- package/src/generated/services/index.ts +7 -4
- package/src/generated/services/messages.ts +3 -1
- package/src/generated/services/my-notes.ts +1 -1
- package/src/generated/services/my-notifications.ts +4 -2
- package/src/generated/services/people.ts +15 -1
- package/src/generated/services/projects.ts +61 -1
- package/src/generated/services/recordings.ts +3 -31
- package/src/generated/services/reports.ts +13 -14
- package/src/generated/services/schedules.ts +107 -17
- package/src/generated/services/search.ts +3 -1
- package/src/generated/services/templates.ts +3 -1
- package/src/generated/services/timeline.ts +3 -0
- package/src/generated/services/timesheets.ts +35 -2
- package/src/generated/services/todolist-groups.ts +13 -7
- package/src/generated/services/todolists.ts +19 -14
- package/src/generated/services/todos.ts +3 -30
- package/src/generated/services/uploads.ts +71 -2
- package/src/generated/services/vaults.ts +6 -0
package/dist/pagination.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuCH;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,UAAc,SAAQ,KAAQ;IAChC,IAAI,CAAW;IAExB;;;;;OAKG;IACH,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,YAAY,KAAU,EAAE,IAAc;QACpC,uDAAuD;QACvD,sEAAsE;QACtE,4EAA4E;QAC5E,KAAK,CAAC,CAAC,CAAC,CAAC;QACT,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;YACtB,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAkB;IAChD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACrD,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IACtB,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACpC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACpC,CAAC"}
|
package/dist/retry.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SDK's retry primitive: the attempt loop extracted from the client's
|
|
3
|
+
* retrying fetch so that both the middleware-chained JSON path (client.ts)
|
|
4
|
+
* and the raw-fetch download hop 1 (download.ts) share one budget/backoff/
|
|
5
|
+
* abort policy. The loop is transport-agnostic — callers own attempt
|
|
6
|
+
* preparation (auth, request construction) via `makeAttempt` and hook
|
|
7
|
+
* emission via `RetryEmit`.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Retry configuration matching x-basecamp-retry extension schema.
|
|
11
|
+
*/
|
|
12
|
+
export interface RetryConfig {
|
|
13
|
+
maxAttempts: number;
|
|
14
|
+
baseDelayMs: number;
|
|
15
|
+
backoff: "exponential" | "linear" | "constant";
|
|
16
|
+
retryOn: number[];
|
|
17
|
+
}
|
|
18
|
+
/** Default retry config used when no operation-specific config is available */
|
|
19
|
+
export declare const DEFAULT_RETRY_CONFIG: RetryConfig;
|
|
20
|
+
/** No-retry config for non-idempotent POST operations */
|
|
21
|
+
export declare const NO_RETRY_CONFIG: RetryConfig;
|
|
22
|
+
/**
|
|
23
|
+
* Ceiling on the backoff term (SPEC §7, "Backoff Ceiling"). Jitter is added
|
|
24
|
+
* after the clamp, so the longest single backoff sleep is this plus
|
|
25
|
+
* `MAX_JITTER_MS`.
|
|
26
|
+
*/
|
|
27
|
+
export declare const MAX_BACKOFF_DELAY_MS = 30000;
|
|
28
|
+
/**
|
|
29
|
+
* Lifecycle seams the retry loop emits through. The loop begins EVERY attempt
|
|
30
|
+
* and finalizes the attempts it abandons (before the backoff sleep); the
|
|
31
|
+
* terminal outcome — the response it returns, or the error it throws — is
|
|
32
|
+
* deliberately NOT finalized here. The caller owns the terminal attempt's end
|
|
33
|
+
* so it can record post-transform results (the client's cache middleware may
|
|
34
|
+
* rewrite a 304 into a cached 200 before its lifecycle middleware finalizes).
|
|
35
|
+
*/
|
|
36
|
+
export interface RetryEmit {
|
|
37
|
+
/** An attempt is beginning (fired for attempt 1 and every retry). */
|
|
38
|
+
begin(attempt: number): void;
|
|
39
|
+
/** An attempt was abandoned in favor of a retry (never the terminal one). */
|
|
40
|
+
finalize(outcome: {
|
|
41
|
+
statusCode: number;
|
|
42
|
+
error?: Error;
|
|
43
|
+
}): void;
|
|
44
|
+
/** A retry is coming: `failedAttempt` just ended, `failedAttempt + 1` is next. */
|
|
45
|
+
retrying(failedAttempt: number, error: Error, delayMs: number): void;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Marks an error thrown during attempt PREPARATION (e.g. a retry's auth
|
|
49
|
+
* refresh) rather than by the transport. The retry loop rethrows it as-is —
|
|
50
|
+
* no retry classification, no budget spent — and the caller unwraps `reason`
|
|
51
|
+
* so the original error's identity survives to its error path.
|
|
52
|
+
*/
|
|
53
|
+
export declare class TerminalRetryError extends Error {
|
|
54
|
+
readonly reason: unknown;
|
|
55
|
+
constructor(reason: unknown);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Runs `makeAttempt` under the retry policy in `config`.
|
|
59
|
+
*
|
|
60
|
+
* `config.maxAttempts` is a total attempt count — the caller passes the
|
|
61
|
+
* effective budget (e.g. 1 when retry is disabled). Status retry is gated on
|
|
62
|
+
* the declared `retryOn` set; 429 honors Retry-After. Transport errors retry
|
|
63
|
+
* on the same budget, except aborts, which are terminal no matter what the
|
|
64
|
+
* budget says: a caller cancellation must not re-send, and a request-timeout
|
|
65
|
+
* budget is shared by every attempt and backoff — once it fires, a retry
|
|
66
|
+
* would instantly re-reject. Terminal errors are rethrown as-is so their
|
|
67
|
+
* identity survives to the caller.
|
|
68
|
+
*
|
|
69
|
+
* `signal`, when given, is the authoritative abort test: a caller can abort
|
|
70
|
+
* with a CUSTOM reason — AbortController.abort(reason) — and fetch then
|
|
71
|
+
* rejects with that reason, not a DOMException named AbortError. The
|
|
72
|
+
* DOMException check remains for abort-shaped rejections that arrive without
|
|
73
|
+
* an aborted signal (e.g. a per-attempt timeout controller).
|
|
74
|
+
*/
|
|
75
|
+
export declare function executeWithRetry(makeAttempt: (attempt: number) => Promise<Response>, config: RetryConfig, emit: RetryEmit, signal?: AbortSignal | null): Promise<Response>;
|
|
76
|
+
/**
|
|
77
|
+
* The backoff term, saturating at {@link MAX_BACKOFF_DELAY_MS} (SPEC §7).
|
|
78
|
+
*
|
|
79
|
+
* Shared by both of the SDK's retry loops — this one and the raw multipart
|
|
80
|
+
* loop in `services/base.ts` — so the ceiling cannot be honored on one path
|
|
81
|
+
* and not the other.
|
|
82
|
+
*
|
|
83
|
+
* The clamp is load-bearing rather than defensive. `Math.pow(2, attempt)`
|
|
84
|
+
* reaches `Infinity` at attempt 1024, and `setTimeout` clamps an out-of-range
|
|
85
|
+
* delay to **1ms**: the failure mode of an unbounded backoff in JS is not a
|
|
86
|
+
* long sleep, it is a tight retry loop against a server that is already
|
|
87
|
+
* answering 429/503. Well before that, the computed delays run to millennia.
|
|
88
|
+
*
|
|
89
|
+
* The exponent is compared against the point where the term reaches the ceiling
|
|
90
|
+
* *before* `Math.pow` is evaluated, and that point is derived from the
|
|
91
|
+
* CONFIGURED base — the same contract Go, Kotlin and Swift get from comparing
|
|
92
|
+
* their multiplier against `MAX_BACKOFF_DELAY_MS / base` before multiplying. A
|
|
93
|
+
* fixed exponent cap plus a trailing `Math.min` looks equivalent and is not:
|
|
94
|
+
* for a small enough base the capped product never reaches the ceiling, so the
|
|
95
|
+
* delay plateaus below it forever instead of saturating at it.
|
|
96
|
+
*
|
|
97
|
+
* `attempt` is the 0-indexed retry count (first retry = 0), matching the SPEC
|
|
98
|
+
* §7 `retry_index`.
|
|
99
|
+
*/
|
|
100
|
+
export declare function saturatingBackoff(baseDelayMs: number, backoff: RetryConfig["backoff"], attempt: number): number;
|
|
101
|
+
export declare function calculateBackoffDelay(config: RetryConfig, attempt: number): number;
|
|
102
|
+
/**
|
|
103
|
+
* Signal-aware sleep for backoff waits: resolves after `ms`, or rejects with
|
|
104
|
+
* the signal's abort reason the moment it fires. Without this, a caller abort
|
|
105
|
+
* or the request-timeout budget expiring during a backoff would leave the
|
|
106
|
+
* request pending for the full delay and then start another attempt — begin,
|
|
107
|
+
* auth refresh, fetch — against an already-aborted signal.
|
|
108
|
+
*/
|
|
109
|
+
export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
|
|
110
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC/C,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,+EAA+E;AAC/E,eAAO,MAAM,oBAAoB,EAAE,WAKlC,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,eAAe,EAAE,WAK7B,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,qEAAqE;IACrE,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/D,kFAAkF;IAClF,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACtE;AAED;;;;;GAKG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC/B,QAAQ,CAAC,MAAM,EAAE,OAAO;gBAAf,MAAM,EAAE,OAAO;CAIrC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,EACnD,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,SAAS,EACf,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,GAC1B,OAAO,CAAC,QAAQ,CAAC,CAqFnB;AAwCD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,EAC/B,OAAO,EAAE,MAAM,GACd,MAAM,CAyBR;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAMlF;AAED;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBrE"}
|
package/dist/retry.js
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SDK's retry primitive: the attempt loop extracted from the client's
|
|
3
|
+
* retrying fetch so that both the middleware-chained JSON path (client.ts)
|
|
4
|
+
* and the raw-fetch download hop 1 (download.ts) share one budget/backoff/
|
|
5
|
+
* abort policy. The loop is transport-agnostic — callers own attempt
|
|
6
|
+
* preparation (auth, request construction) via `makeAttempt` and hook
|
|
7
|
+
* emission via `RetryEmit`.
|
|
8
|
+
*/
|
|
9
|
+
/** Default retry config used when no operation-specific config is available */
|
|
10
|
+
export const DEFAULT_RETRY_CONFIG = {
|
|
11
|
+
maxAttempts: 3,
|
|
12
|
+
baseDelayMs: 1000,
|
|
13
|
+
backoff: "exponential",
|
|
14
|
+
retryOn: [429, 503],
|
|
15
|
+
};
|
|
16
|
+
/** No-retry config for non-idempotent POST operations */
|
|
17
|
+
export const NO_RETRY_CONFIG = {
|
|
18
|
+
maxAttempts: 1,
|
|
19
|
+
baseDelayMs: 0,
|
|
20
|
+
backoff: "constant",
|
|
21
|
+
retryOn: [],
|
|
22
|
+
};
|
|
23
|
+
const MAX_JITTER_MS = 100;
|
|
24
|
+
/**
|
|
25
|
+
* Ceiling on the backoff term (SPEC §7, "Backoff Ceiling"). Jitter is added
|
|
26
|
+
* after the clamp, so the longest single backoff sleep is this plus
|
|
27
|
+
* `MAX_JITTER_MS`.
|
|
28
|
+
*/
|
|
29
|
+
export const MAX_BACKOFF_DELAY_MS = 30_000;
|
|
30
|
+
/**
|
|
31
|
+
* Marks an error thrown during attempt PREPARATION (e.g. a retry's auth
|
|
32
|
+
* refresh) rather than by the transport. The retry loop rethrows it as-is —
|
|
33
|
+
* no retry classification, no budget spent — and the caller unwraps `reason`
|
|
34
|
+
* so the original error's identity survives to its error path.
|
|
35
|
+
*/
|
|
36
|
+
export class TerminalRetryError extends Error {
|
|
37
|
+
reason;
|
|
38
|
+
constructor(reason) {
|
|
39
|
+
super("attempt preparation failed terminally");
|
|
40
|
+
this.reason = reason;
|
|
41
|
+
this.name = "TerminalRetryError";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Runs `makeAttempt` under the retry policy in `config`.
|
|
46
|
+
*
|
|
47
|
+
* `config.maxAttempts` is a total attempt count — the caller passes the
|
|
48
|
+
* effective budget (e.g. 1 when retry is disabled). Status retry is gated on
|
|
49
|
+
* the declared `retryOn` set; 429 honors Retry-After. Transport errors retry
|
|
50
|
+
* on the same budget, except aborts, which are terminal no matter what the
|
|
51
|
+
* budget says: a caller cancellation must not re-send, and a request-timeout
|
|
52
|
+
* budget is shared by every attempt and backoff — once it fires, a retry
|
|
53
|
+
* would instantly re-reject. Terminal errors are rethrown as-is so their
|
|
54
|
+
* identity survives to the caller.
|
|
55
|
+
*
|
|
56
|
+
* `signal`, when given, is the authoritative abort test: a caller can abort
|
|
57
|
+
* with a CUSTOM reason — AbortController.abort(reason) — and fetch then
|
|
58
|
+
* rejects with that reason, not a DOMException named AbortError. The
|
|
59
|
+
* DOMException check remains for abort-shaped rejections that arrive without
|
|
60
|
+
* an aborted signal (e.g. a per-attempt timeout controller).
|
|
61
|
+
*/
|
|
62
|
+
export async function executeWithRetry(makeAttempt, config, emit, signal) {
|
|
63
|
+
let attempt = 1;
|
|
64
|
+
emit.begin(attempt);
|
|
65
|
+
for (;;) {
|
|
66
|
+
let response;
|
|
67
|
+
try {
|
|
68
|
+
response = await makeAttempt(attempt);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
// Attempt preparation failed — the caller marked it terminal. Rethrow
|
|
72
|
+
// the marker itself; the caller unwraps it at its own boundary.
|
|
73
|
+
if (error instanceof TerminalRetryError) {
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
const isAbort = signal?.aborted === true ||
|
|
77
|
+
(error instanceof DOMException &&
|
|
78
|
+
(error.name === "AbortError" || error.name === "TimeoutError"));
|
|
79
|
+
if (isAbort || attempt >= config.maxAttempts) {
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
// Network-error retry rides the same budget as status retry: a caller
|
|
83
|
+
// that resolves a no-retry policy (maxAttempts 1) is rethrown above
|
|
84
|
+
// after its single attempt.
|
|
85
|
+
const cause = error instanceof Error ? error : new Error(String(error));
|
|
86
|
+
const delay = calculateBackoffDelay(config, attempt - 1);
|
|
87
|
+
emit.finalize({ statusCode: 0, error: cause });
|
|
88
|
+
emit.retrying(attempt, cause, delay);
|
|
89
|
+
await sleep(delay, signal ?? undefined);
|
|
90
|
+
// Same placement rationale as the status path below.
|
|
91
|
+
attempt += 1;
|
|
92
|
+
emit.begin(attempt);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
// Terminal: a status outside the declared retryOn set, or a spent
|
|
96
|
+
// budget — maxAttempts is a total attempt count, so attempt N is
|
|
97
|
+
// terminal when it equals the cap.
|
|
98
|
+
if (!config.retryOn.includes(response.status) || attempt >= config.maxAttempts) {
|
|
99
|
+
return response;
|
|
100
|
+
}
|
|
101
|
+
// For 429, respect Retry-After; otherwise back off.
|
|
102
|
+
let delay;
|
|
103
|
+
const retryAfter = response.status === 429 ? response.headers.get("Retry-After") : null;
|
|
104
|
+
const retryAfterSeconds = retryAfter ? parseInt(retryAfter, 10) : NaN;
|
|
105
|
+
if (!isNaN(retryAfterSeconds)) {
|
|
106
|
+
delay = retryAfterSeconds * 1000;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
delay = calculateBackoffDelay(config, attempt - 1);
|
|
110
|
+
}
|
|
111
|
+
const statusError = new Error(`HTTP ${response.status}: ${response.statusText || "Request failed"}`);
|
|
112
|
+
// End the failed attempt before sleeping, so a slow backoff cannot leave
|
|
113
|
+
// an attempt open, then announce the upcoming one.
|
|
114
|
+
emit.finalize({ statusCode: response.status });
|
|
115
|
+
emit.retrying(attempt, statusError, delay);
|
|
116
|
+
// This response is being discarded, so release its stream before we sleep
|
|
117
|
+
// rather than leaving it open across the backoff — otherwise a throttled
|
|
118
|
+
// client holds a connection per in-flight retry and cannot reuse any of
|
|
119
|
+
// them. The multipart transport in services/base.ts already does this.
|
|
120
|
+
// Errors are ignored: the body may already be consumed or closed.
|
|
121
|
+
void response.body?.cancel().catch(() => { });
|
|
122
|
+
await sleep(delay, signal ?? undefined);
|
|
123
|
+
// Begun after the backoff but before any work that can throw. After, so
|
|
124
|
+
// the attempt's duration measures the request rather than the sleep;
|
|
125
|
+
// before, so that if the caller's attempt preparation or the fetch
|
|
126
|
+
// throws, its error path still finds a live attempt to finalize.
|
|
127
|
+
// Starting it later would let onRetry announce an attempt and then never
|
|
128
|
+
// account for it.
|
|
129
|
+
attempt += 1;
|
|
130
|
+
emit.begin(attempt);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* `base * 2**exponent`, computed without ever forming `2**exponent`.
|
|
135
|
+
*
|
|
136
|
+
* JS has no `ldexp`, and `Math.pow(2, e)` is `Infinity` for `e > 1023` — so for
|
|
137
|
+
* a denormal-small base the *product* is still an ordinary number long after the
|
|
138
|
+
* multiplier has overflowed. Scaling in bounded steps keeps every intermediate
|
|
139
|
+
* finite, which is what lets the exponent bound come from the base alone.
|
|
140
|
+
*/
|
|
141
|
+
function scaleByPowerOfTwo(base, exponent) {
|
|
142
|
+
let result = base;
|
|
143
|
+
for (let remaining = exponent; remaining > 0;) {
|
|
144
|
+
const step = Math.min(remaining, 1000);
|
|
145
|
+
result *= Math.pow(2, step);
|
|
146
|
+
if (!Number.isFinite(result))
|
|
147
|
+
return Infinity;
|
|
148
|
+
remaining -= step;
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Smallest exponent `e` with `base * 2**e >= MAX_BACKOFF_DELAY_MS`.
|
|
154
|
+
*
|
|
155
|
+
* Computed in the LOG domain rather than as `MAX_BACKOFF_DELAY_MS / base`. That
|
|
156
|
+
* ratio is `Infinity` for any base below ~1.67e-304 ms, and falling back to a
|
|
157
|
+
* fixed 1023 then saturates *early*: such a base reaches only a fraction of the
|
|
158
|
+
* ceiling at exponent 1023, so returning the ceiling there overstates the
|
|
159
|
+
* specified term instead of tracking it. The log form has no such cliff, so the
|
|
160
|
+
* numeric backstop is gone entirely rather than merely made rarer.
|
|
161
|
+
*/
|
|
162
|
+
function saturatingExponent(base) {
|
|
163
|
+
// log2 is not correctly rounded here, so the estimate can land one either side
|
|
164
|
+
// of the true boundary. Both corrections are bounded.
|
|
165
|
+
let exponent = Math.max(Math.ceil(Math.log2(MAX_BACKOFF_DELAY_MS) - Math.log2(base)), 0);
|
|
166
|
+
while (exponent > 0 && scaleByPowerOfTwo(base, exponent - 1) >= MAX_BACKOFF_DELAY_MS)
|
|
167
|
+
exponent--;
|
|
168
|
+
while (scaleByPowerOfTwo(base, exponent) < MAX_BACKOFF_DELAY_MS)
|
|
169
|
+
exponent++;
|
|
170
|
+
return exponent;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* The backoff term, saturating at {@link MAX_BACKOFF_DELAY_MS} (SPEC §7).
|
|
174
|
+
*
|
|
175
|
+
* Shared by both of the SDK's retry loops — this one and the raw multipart
|
|
176
|
+
* loop in `services/base.ts` — so the ceiling cannot be honored on one path
|
|
177
|
+
* and not the other.
|
|
178
|
+
*
|
|
179
|
+
* The clamp is load-bearing rather than defensive. `Math.pow(2, attempt)`
|
|
180
|
+
* reaches `Infinity` at attempt 1024, and `setTimeout` clamps an out-of-range
|
|
181
|
+
* delay to **1ms**: the failure mode of an unbounded backoff in JS is not a
|
|
182
|
+
* long sleep, it is a tight retry loop against a server that is already
|
|
183
|
+
* answering 429/503. Well before that, the computed delays run to millennia.
|
|
184
|
+
*
|
|
185
|
+
* The exponent is compared against the point where the term reaches the ceiling
|
|
186
|
+
* *before* `Math.pow` is evaluated, and that point is derived from the
|
|
187
|
+
* CONFIGURED base — the same contract Go, Kotlin and Swift get from comparing
|
|
188
|
+
* their multiplier against `MAX_BACKOFF_DELAY_MS / base` before multiplying. A
|
|
189
|
+
* fixed exponent cap plus a trailing `Math.min` looks equivalent and is not:
|
|
190
|
+
* for a small enough base the capped product never reaches the ceiling, so the
|
|
191
|
+
* delay plateaus below it forever instead of saturating at it.
|
|
192
|
+
*
|
|
193
|
+
* `attempt` is the 0-indexed retry count (first retry = 0), matching the SPEC
|
|
194
|
+
* §7 `retry_index`.
|
|
195
|
+
*/
|
|
196
|
+
export function saturatingBackoff(baseDelayMs, backoff, attempt) {
|
|
197
|
+
const base = baseDelayMs > 0 ? baseDelayMs : 0;
|
|
198
|
+
const index = attempt > 0 ? attempt : 0;
|
|
199
|
+
if (base === 0)
|
|
200
|
+
return 0;
|
|
201
|
+
let delay;
|
|
202
|
+
switch (backoff) {
|
|
203
|
+
case "exponential":
|
|
204
|
+
if (index >= saturatingExponent(base))
|
|
205
|
+
return MAX_BACKOFF_DELAY_MS;
|
|
206
|
+
delay = scaleByPowerOfTwo(base, index);
|
|
207
|
+
break;
|
|
208
|
+
case "linear": {
|
|
209
|
+
// Compared before multiplying, so `Infinity * 0`-shaped intermediates
|
|
210
|
+
// never arise. `index + 1` is finite for any finite index.
|
|
211
|
+
const multiplier = index + 1;
|
|
212
|
+
if (multiplier >= MAX_BACKOFF_DELAY_MS / base)
|
|
213
|
+
return MAX_BACKOFF_DELAY_MS;
|
|
214
|
+
delay = base * multiplier;
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
case "constant":
|
|
218
|
+
default:
|
|
219
|
+
delay = base;
|
|
220
|
+
}
|
|
221
|
+
return Math.min(delay, MAX_BACKOFF_DELAY_MS);
|
|
222
|
+
}
|
|
223
|
+
export function calculateBackoffDelay(config, attempt) {
|
|
224
|
+
const delay = saturatingBackoff(config.baseDelayMs, config.backoff, attempt);
|
|
225
|
+
// Add jitter (0-100ms)
|
|
226
|
+
const jitter = Math.random() * MAX_JITTER_MS;
|
|
227
|
+
return delay + jitter;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Signal-aware sleep for backoff waits: resolves after `ms`, or rejects with
|
|
231
|
+
* the signal's abort reason the moment it fires. Without this, a caller abort
|
|
232
|
+
* or the request-timeout budget expiring during a backoff would leave the
|
|
233
|
+
* request pending for the full delay and then start another attempt — begin,
|
|
234
|
+
* auth refresh, fetch — against an already-aborted signal.
|
|
235
|
+
*/
|
|
236
|
+
export function sleep(ms, signal) {
|
|
237
|
+
return new Promise((resolve, reject) => {
|
|
238
|
+
if (signal?.aborted) {
|
|
239
|
+
reject(signal.reason);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
const onAbort = () => {
|
|
243
|
+
clearTimeout(timer);
|
|
244
|
+
reject(signal.reason);
|
|
245
|
+
};
|
|
246
|
+
const timer = setTimeout(() => {
|
|
247
|
+
signal?.removeEventListener("abort", onAbort);
|
|
248
|
+
resolve();
|
|
249
|
+
}, ms);
|
|
250
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,51 +7,8 @@
|
|
|
7
7
|
import { BaseService, type RawClient } from "./base.js";
|
|
8
8
|
import type { BasecampHooks } from "../hooks.js";
|
|
9
9
|
import type { AuthStrategy } from "../auth-strategy.js";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*/
|
|
13
|
-
export interface Identity {
|
|
14
|
-
/** User's unique identifier */
|
|
15
|
-
id: number;
|
|
16
|
-
/** User's first name */
|
|
17
|
-
firstName: string;
|
|
18
|
-
/** User's last name */
|
|
19
|
-
lastName: string;
|
|
20
|
-
/** User's email address */
|
|
21
|
-
emailAddress: string;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* A Basecamp account the user has access to.
|
|
25
|
-
*/
|
|
26
|
-
export interface AuthorizedAccount {
|
|
27
|
-
/** Account's unique identifier */
|
|
28
|
-
id: number;
|
|
29
|
-
/** Account name */
|
|
30
|
-
name: string;
|
|
31
|
-
/** Product type (e.g., "bc3" for Basecamp, "hey" for HEY) */
|
|
32
|
-
product: string;
|
|
33
|
-
/** API URL for this account */
|
|
34
|
-
href: string;
|
|
35
|
-
/** Web app URL for this account */
|
|
36
|
-
appHref: string;
|
|
37
|
-
/** Whether the account is hidden from the user's view */
|
|
38
|
-
hidden?: boolean;
|
|
39
|
-
/** Whether the account subscription has expired */
|
|
40
|
-
expired?: boolean;
|
|
41
|
-
/** Whether this is the user's featured/primary account */
|
|
42
|
-
featured?: boolean;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Authorization information response.
|
|
46
|
-
*/
|
|
47
|
-
export interface AuthorizationInfo {
|
|
48
|
-
/** Token expiration timestamp */
|
|
49
|
-
expiresAt: Date;
|
|
50
|
-
/** The authenticated user's identity */
|
|
51
|
-
identity: Identity;
|
|
52
|
-
/** List of accounts the user can access */
|
|
53
|
-
accounts: AuthorizedAccount[];
|
|
54
|
-
}
|
|
10
|
+
import { type AuthorizationInfo } from "../oauth/authorization-document.js";
|
|
11
|
+
export type { Identity, AuthorizedAccount, AuthorizationInfo, } from "../oauth/authorization-document.js";
|
|
55
12
|
/**
|
|
56
13
|
* Options for fetching authorization information.
|
|
57
14
|
*/
|
|
@@ -59,19 +16,29 @@ export interface GetAuthorizationInfoOptions {
|
|
|
59
16
|
/**
|
|
60
17
|
* Override the default authorization endpoint URL.
|
|
61
18
|
* Defaults to "https://launchpad.37signals.com/authorization.json"
|
|
19
|
+
*
|
|
20
|
+
* This is also how you point at a BC5 issuer, whose document is a different
|
|
21
|
+
* shape — see `../oauth/authorization-document.js`.
|
|
62
22
|
*/
|
|
63
23
|
endpoint?: string;
|
|
64
24
|
/**
|
|
65
25
|
* Filter accounts by product type.
|
|
66
26
|
* Common values: "bc3" (Basecamp), "bcx" (Basecamp 2), "hey" (HEY)
|
|
27
|
+
*
|
|
28
|
+
* A BC5 document carries no `product` on any account, so the filter cannot
|
|
29
|
+
* apply there. In that case all accounts are returned and
|
|
30
|
+
* `AuthorizationInfo.productFilterApplied` is `false`, rather than the empty
|
|
31
|
+
* list a literal filter would produce.
|
|
67
32
|
*/
|
|
68
33
|
filterProduct?: string;
|
|
69
34
|
}
|
|
70
35
|
/**
|
|
71
36
|
* Service for authorization-related operations.
|
|
72
37
|
*
|
|
73
|
-
* This service communicates with
|
|
74
|
-
* rather than the standard Basecamp
|
|
38
|
+
* This service communicates with an authorization endpoint — Launchpad by
|
|
39
|
+
* default, or a BC5 issuer via `endpoint:` — rather than the standard Basecamp
|
|
40
|
+
* API. The two serve different-shaped documents; see
|
|
41
|
+
* `../oauth/authorization-document.js`.
|
|
75
42
|
*
|
|
76
43
|
* @example
|
|
77
44
|
* ```ts
|
|
@@ -84,9 +51,11 @@ export interface GetAuthorizationInfoOptions {
|
|
|
84
51
|
*
|
|
85
52
|
* // Get all accounts
|
|
86
53
|
* const info = await client.authorization.getInfo();
|
|
87
|
-
* console.log(`Logged in as ${info.identity.
|
|
54
|
+
* console.log(`Logged in as identity ${info.identity.id}`);
|
|
88
55
|
*
|
|
89
|
-
* // Filter to only Basecamp accounts
|
|
56
|
+
* // Filter to only Basecamp accounts. Against a BC5 issuer, whose accounts
|
|
57
|
+
* // carry no `product`, this returns every account with
|
|
58
|
+
* // `productFilterApplied === false` instead of an empty list.
|
|
90
59
|
* const bc3Info = await client.authorization.getInfo({ filterProduct: "bc3" });
|
|
91
60
|
* for (const account of bc3Info.accounts) {
|
|
92
61
|
* console.log(account.name);
|
|
@@ -110,12 +79,13 @@ export declare class AuthorizationService extends BaseService {
|
|
|
110
79
|
* ```ts
|
|
111
80
|
* const info = await authService.getInfo();
|
|
112
81
|
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
82
|
+
* // A BC5 issuer emits only `identity.id`; the name and email fields are
|
|
83
|
+
* // Launchpad's and are `undefined` there.
|
|
84
|
+
* console.log(`User: ${info.identity.id}`);
|
|
115
85
|
* console.log(`Token expires: ${info.expiresAt}`);
|
|
116
86
|
*
|
|
117
87
|
* for (const account of info.accounts) {
|
|
118
|
-
* console.log(`${account.name}
|
|
88
|
+
* console.log(`${account.name}: ${account.href}`);
|
|
119
89
|
* }
|
|
120
90
|
* ```
|
|
121
91
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorization.d.ts","sourceRoot":"","sources":["../../src/services/authorization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"authorization.d.ts","sourceRoot":"","sources":["../../src/services/authorization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,oCAAoC,CAAC;AAI5C,YAAY,EACV,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,oCAAoC,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,oBAAqB,SAAQ,WAAW;IACnD,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,SAAS,CAAS;gBAGxB,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,aAAa,GAAG,SAAS,EAChC,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,MAAM;IAOnB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,OAAO,CAAC,OAAO,GAAE,2BAAgC,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAsCrF"}
|
|
@@ -6,12 +6,15 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { BaseService } from "./base.js";
|
|
8
8
|
import { requireSecureEndpoint } from "../security.js";
|
|
9
|
+
import { parseAuthorizationDocument, } from "../oauth/authorization-document.js";
|
|
9
10
|
const DEFAULT_AUTHORIZATION_ENDPOINT = "https://launchpad.37signals.com/authorization.json";
|
|
10
11
|
/**
|
|
11
12
|
* Service for authorization-related operations.
|
|
12
13
|
*
|
|
13
|
-
* This service communicates with
|
|
14
|
-
* rather than the standard Basecamp
|
|
14
|
+
* This service communicates with an authorization endpoint — Launchpad by
|
|
15
|
+
* default, or a BC5 issuer via `endpoint:` — rather than the standard Basecamp
|
|
16
|
+
* API. The two serve different-shaped documents; see
|
|
17
|
+
* `../oauth/authorization-document.js`.
|
|
15
18
|
*
|
|
16
19
|
* @example
|
|
17
20
|
* ```ts
|
|
@@ -24,9 +27,11 @@ const DEFAULT_AUTHORIZATION_ENDPOINT = "https://launchpad.37signals.com/authoriz
|
|
|
24
27
|
*
|
|
25
28
|
* // Get all accounts
|
|
26
29
|
* const info = await client.authorization.getInfo();
|
|
27
|
-
* console.log(`Logged in as ${info.identity.
|
|
30
|
+
* console.log(`Logged in as identity ${info.identity.id}`);
|
|
28
31
|
*
|
|
29
|
-
* // Filter to only Basecamp accounts
|
|
32
|
+
* // Filter to only Basecamp accounts. Against a BC5 issuer, whose accounts
|
|
33
|
+
* // carry no `product`, this returns every account with
|
|
34
|
+
* // `productFilterApplied === false` instead of an empty list.
|
|
30
35
|
* const bc3Info = await client.authorization.getInfo({ filterProduct: "bc3" });
|
|
31
36
|
* for (const account of bc3Info.accounts) {
|
|
32
37
|
* console.log(account.name);
|
|
@@ -54,12 +59,13 @@ export class AuthorizationService extends BaseService {
|
|
|
54
59
|
* ```ts
|
|
55
60
|
* const info = await authService.getInfo();
|
|
56
61
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
62
|
+
* // A BC5 issuer emits only `identity.id`; the name and email fields are
|
|
63
|
+
* // Launchpad's and are `undefined` there.
|
|
64
|
+
* console.log(`User: ${info.identity.id}`);
|
|
59
65
|
* console.log(`Token expires: ${info.expiresAt}`);
|
|
60
66
|
*
|
|
61
67
|
* for (const account of info.accounts) {
|
|
62
|
-
* console.log(`${account.name}
|
|
68
|
+
* console.log(`${account.name}: ${account.href}`);
|
|
63
69
|
* }
|
|
64
70
|
* ```
|
|
65
71
|
*/
|
|
@@ -88,31 +94,7 @@ export class AuthorizationService extends BaseService {
|
|
|
88
94
|
return { data: undefined, error: undefined, response };
|
|
89
95
|
}
|
|
90
96
|
const raw = (await response.json());
|
|
91
|
-
|
|
92
|
-
let accounts = raw.accounts.map((a) => ({
|
|
93
|
-
id: a.id,
|
|
94
|
-
name: a.name,
|
|
95
|
-
product: a.product,
|
|
96
|
-
href: a.href,
|
|
97
|
-
appHref: a.app_href,
|
|
98
|
-
hidden: a.hidden,
|
|
99
|
-
expired: a.expired,
|
|
100
|
-
featured: a.featured,
|
|
101
|
-
}));
|
|
102
|
-
// Filter by product if requested
|
|
103
|
-
if (options.filterProduct) {
|
|
104
|
-
accounts = accounts.filter((a) => a.product === options.filterProduct);
|
|
105
|
-
}
|
|
106
|
-
const data = {
|
|
107
|
-
expiresAt: new Date(raw.expires_at),
|
|
108
|
-
identity: {
|
|
109
|
-
id: raw.identity.id,
|
|
110
|
-
firstName: raw.identity.first_name,
|
|
111
|
-
lastName: raw.identity.last_name,
|
|
112
|
-
emailAddress: raw.identity.email_address,
|
|
113
|
-
},
|
|
114
|
-
accounts,
|
|
115
|
-
};
|
|
97
|
+
const data = parseAuthorizationDocument(raw, { filterProduct: options.filterProduct });
|
|
116
98
|
return { data, error: undefined, response };
|
|
117
99
|
});
|
|
118
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../src/services/authorization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAkB,MAAM,WAAW,CAAC;AAGxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../src/services/authorization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAkB,MAAM,WAAW,CAAC;AAGxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EACL,0BAA0B,GAG3B,MAAM,oCAAoC,CAAC;AAkC5C,MAAM,8BAA8B,GAAG,oDAAoD,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,OAAO,oBAAqB,SAAQ,WAAW;IAC3C,YAAY,CAAe;IAC3B,SAAS,CAAS;IAE1B,YACE,MAAiB,EACjB,KAAgC,EAChC,YAA0B,EAC1B,SAAiB;QAEjB,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,OAAO,CAAC,UAAuC,EAAE;QACrD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,8BAA8B,CAAC;QACpE,0EAA0E;QAC1E,qBAAqB,CAAC,QAAQ,EAAE,wBAAwB,CAAC,CAAC;QAE1D,OAAO,IAAI,CAAC,OAAO,CACjB;YACE,OAAO,EAAE,eAAe;YACxB,SAAS,EAAE,SAAS;YACpB,YAAY,EAAE,eAAe;YAC7B,UAAU,EAAE,KAAK;SAClB,EACD,KAAK,IAAI,EAAE;YACT,mCAAmC;YACnC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;gBAC1B,YAAY,EAAE,IAAI,CAAC,SAAS;gBAC5B,MAAM,EAAE,kBAAkB;aAC3B,CAAC,CAAC;YACH,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAE9C,kDAAkD;YAClD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;gBACrC,MAAM,EAAE,KAAK;gBACb,OAAO;aACR,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;YACzD,CAAC;YAED,MAAM,GAAG,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA6B,CAAC;YAEhE,MAAM,IAAI,GAAG,0BAA0B,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;YAEvF,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;QAC9C,CAAC,CACF,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/services/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAmB,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/services/base.ts"],"names":[],"mappings":"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"}
|