@okta/auth-foundation 0.6.0 → 0.9.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.
Files changed (81) hide show
  1. package/README.MD +136 -0
  2. package/claude.md +256 -0
  3. package/dist/esm/Credential/Credential.js +17 -14
  4. package/dist/esm/Credential/Credential.js.map +1 -1
  5. package/dist/esm/Credential/CredentialCoordinator.js +6 -2
  6. package/dist/esm/Credential/CredentialCoordinator.js.map +1 -1
  7. package/dist/esm/Credential/CredentialDataSource.js +6 -4
  8. package/dist/esm/Credential/CredentialDataSource.js.map +1 -1
  9. package/dist/esm/Credential/TokenStorage.js +3 -0
  10. package/dist/esm/Credential/TokenStorage.js.map +1 -1
  11. package/dist/esm/FetchClient.js +5 -1
  12. package/dist/esm/FetchClient.js.map +1 -1
  13. package/dist/esm/Token.js +1 -0
  14. package/dist/esm/Token.js.map +1 -1
  15. package/dist/esm/TokenOrchestrator.js +4 -1
  16. package/dist/esm/TokenOrchestrator.js.map +1 -1
  17. package/dist/esm/http/APIClient.js +4 -0
  18. package/dist/esm/http/APIClient.js.map +1 -1
  19. package/dist/esm/http/oktaUserAgent.js +1 -1
  20. package/dist/esm/http/requests/APIRequest.js.map +1 -1
  21. package/dist/esm/http/requests/OAuth2Request.js.map +1 -1
  22. package/dist/esm/http/wwwAuthenticate.js.map +1 -1
  23. package/dist/esm/jwt/IDTokenValidator.js +3 -0
  24. package/dist/esm/jwt/IDTokenValidator.js.map +1 -1
  25. package/dist/esm/jwt/JWK.js.map +1 -1
  26. package/dist/esm/jwt/JWT.js.map +1 -1
  27. package/dist/esm/jwt/TokenHashValidator.js.map +1 -1
  28. package/dist/esm/oauth2/client.js +14 -9
  29. package/dist/esm/oauth2/client.js.map +1 -1
  30. package/dist/esm/oauth2/configuration.js +7 -3
  31. package/dist/esm/oauth2/configuration.js.map +1 -1
  32. package/dist/esm/oauth2/dpop/index.js.map +1 -1
  33. package/dist/esm/oauth2/dpop/nonceCache.js.map +1 -1
  34. package/dist/esm/oauth2/dpop/storage.js.map +1 -1
  35. package/dist/esm/oauth2/pkce.js.map +1 -1
  36. package/dist/esm/oauth2/requests/UserInfo.js.map +1 -1
  37. package/dist/esm/platform/Platform.js.map +1 -1
  38. package/dist/esm/platform/defaults.js.map +1 -1
  39. package/dist/esm/types/oauth.js.map +1 -1
  40. package/dist/esm/utils/EventEmitter.js +29 -1
  41. package/dist/esm/utils/EventEmitter.js.map +1 -1
  42. package/dist/esm/utils/TaskBridge.js +13 -0
  43. package/dist/esm/utils/TaskBridge.js.map +1 -1
  44. package/dist/esm/utils/TimeCoordinator.js.map +1 -1
  45. package/dist/esm/utils/merge.js.map +1 -1
  46. package/dist/esm/utils/pause.js.map +1 -1
  47. package/dist/types/Credential/Credential.d.ts +38 -21
  48. package/dist/types/Credential/CredentialCoordinator.d.ts +10 -3
  49. package/dist/types/Credential/CredentialDataSource.d.ts +2 -1
  50. package/dist/types/Credential/TokenStorage.d.ts +13 -2
  51. package/dist/types/FetchClient.d.ts +26 -5
  52. package/dist/types/Token.d.ts +23 -11
  53. package/dist/types/TokenOrchestrator.d.ts +61 -11
  54. package/dist/types/http/APIClient.d.ts +220 -8
  55. package/dist/types/http/index.d.ts +5 -0
  56. package/dist/types/http/requests/APIRequest.d.ts +28 -2
  57. package/dist/types/http/requests/OAuth2Request.d.ts +12 -2
  58. package/dist/types/http/wwwAuthenticate.d.ts +10 -2
  59. package/dist/types/jwt/IDTokenValidator.d.ts +46 -3
  60. package/dist/types/jwt/JWK.d.ts +35 -0
  61. package/dist/types/jwt/JWT.d.ts +126 -4
  62. package/dist/types/jwt/TokenHashValidator.d.ts +6 -0
  63. package/dist/types/oauth2/client.d.ts +95 -11
  64. package/dist/types/oauth2/configuration.d.ts +81 -7
  65. package/dist/types/oauth2/dpop/index.d.ts +10 -5
  66. package/dist/types/oauth2/dpop/nonceCache.d.ts +18 -0
  67. package/dist/types/oauth2/dpop/storage.d.ts +1 -0
  68. package/dist/types/oauth2/dpop/types.d.ts +7 -0
  69. package/dist/types/oauth2/pkce.d.ts +19 -0
  70. package/dist/types/oauth2/requests/UserInfo.d.ts +2 -1
  71. package/dist/types/platform/Platform.d.ts +51 -3
  72. package/dist/types/platform/defaults.d.ts +1 -0
  73. package/dist/types/types/lib.d.ts +16 -2
  74. package/dist/types/types/oauth.d.ts +5 -5
  75. package/dist/types/types/openid.d.ts +50 -234
  76. package/dist/types/utils/EventEmitter.d.ts +84 -2
  77. package/dist/types/utils/TaskBridge.d.ts +9 -1
  78. package/dist/types/utils/TimeCoordinator.d.ts +2 -0
  79. package/dist/types/utils/merge.d.ts +2 -0
  80. package/dist/types/utils/pause.d.ts +1 -0
  81. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
1
  import { type GrantType, type Expires, type TokenType, type RequestAuthorizer, type RequestAuthorizerInit, type Seconds, type JSONSerializable, type AcrValues, type TimeInterval, type JsonPrimitive, type JsonRecord } from './types/index.ts';
2
2
  import type { OAuth2Client } from './oauth2/client.ts';
3
+ import type { OAuth2ClientOptions } from './oauth2/configuration.ts';
3
4
  import { JWT } from './jwt/index.ts';
4
5
  import { OAuth2Request } from './http/index.ts';
5
6
  /**
@@ -23,6 +24,7 @@ export type TokenResponse = {
23
24
  /**
24
25
  * Required and optional values to construct a {@link Token} instance
25
26
  * @group Types
27
+ * @useDeclaredType
26
28
  */
27
29
  export type TokenInit = Omit<TokenResponse, 'idToken'> & {
28
30
  idToken?: string | JWT;
@@ -36,11 +38,9 @@ export type TokenPrimitiveInit = TokenResponse;
36
38
  * Internal representation of a OAuth2/OIDC Token.
37
39
  * Contains `accessToken`, conditionally contains `idToken` and `refreshToken`
38
40
  *
39
- * @group Token
40
- *
41
41
  * @remarks
42
42
  * Most operations can be done by {@link Credential} methods. It's recommended
43
- * to use those instead before reaching for a {@link Token.Token | Token} method
43
+ * to use those instead before reaching for a {@link Token} method
44
44
  *
45
45
  * @see
46
46
  * - Okta Documentation: {@link https://developer.okta.com/docs/reference/api/oidc/#response-properties-4 | OIDC }
@@ -95,6 +95,9 @@ export declare class Token implements JSONSerializable, Expires, RequestAuthoriz
95
95
  protected static create<T extends Token>(this: new (init: TokenInit) => T, init: TokenInit): T;
96
96
  static serializer(t: object): string;
97
97
  static isEqual(lhs: Token, rhs: Token): boolean;
98
+ /**
99
+ * Performs a token refresh using the provided `refreshToken`
100
+ */
98
101
  static from(refreshToken: string, client: OAuth2Client): Promise<Token>;
99
102
  /**
100
103
  * When the Token will expire, represented as a `Date`
@@ -107,19 +110,19 @@ export declare class Token implements JSONSerializable, Expires, RequestAuthoriz
107
110
  */
108
111
  get isExpired(): boolean;
109
112
  /**
110
- * Returns `true` if the {@link Token.Token | Token} is _not_ expired
113
+ * Returns `true` if the {@link Token:class | Token} is _not_ expired
111
114
  *
112
115
  * @see {@link Token.isExpired}
113
116
  */
114
117
  get isValid(): boolean;
115
118
  /**
116
- * Returns `true` if the {@link Token.Token | Token} will expire after a duration (seconds)
119
+ * Returns `true` if the {@link Token:class | Token} will expire after a duration (seconds)
117
120
  *
118
121
  * @see {@link Token.willBeValidIn}
119
122
  */
120
123
  willBeExpiredIn(duration: Seconds): boolean;
121
124
  /**
122
- * Returns `true` if the {@link Token.Token | Token} will _not_ expire after a duration (seconds)
125
+ * Returns `true` if the {@link Token:class | Token} will _not_ expire after a duration (seconds)
123
126
  *
124
127
  * @see {@link Token.willBeExpiredIn}
125
128
  */
@@ -129,15 +132,15 @@ export declare class Token implements JSONSerializable, Expires, RequestAuthoriz
129
132
  */
130
133
  get scopes(): string[];
131
134
  /**
132
- * Converts a {@link Token.Token | Token} instance to an serializable object literal representation
135
+ * Converts a {@link Token:class | Token} instance to an serializable object literal representation
133
136
  */
134
137
  toJSON(): JsonRecord;
135
138
  /**
136
- * Used to merge separate {@link Token.Token | Token} instances together. Useful when handling token refresh as
139
+ * Used to merge separate {@link Token:class | Token} instances together. Useful when handling token refresh as
137
140
  * not every value is returned in a refresh request compared to the initial token request
138
141
  *
139
142
  * @param token the "old" token instance to be merged into the "new" token
140
- * @returns new {@link Token.Token | Token} instance
143
+ * @returns new {@link Token:class | Token} instance
141
144
  */
142
145
  merge(token: Token): Token;
143
146
  serialize(): string;
@@ -163,6 +166,7 @@ export declare namespace Token {
163
166
  dpopPairId?: string;
164
167
  acrValues?: AcrValues;
165
168
  maxAge?: TimeInterval;
169
+ clientSettings?: OAuth2ClientOptions;
166
170
  };
167
171
  /**
168
172
  * Utility function for extracting {@link Token.Context} from an union-type object like {@link Token.Metadata:TYPE | Token.Metadata}
@@ -171,8 +175,8 @@ export declare namespace Token {
171
175
  [key: string]: unknown;
172
176
  }): Token.Context;
173
177
  /**
174
- * Non-sensitive metadata values associated with a {@link Token.Token | Token}. Used to store {@link Token.Context} and additional
175
- * metadata for a given {@link Token.Token | Token}
178
+ * Non-sensitive metadata associated with a {@link Token:class | Token}. Used to store {@link Token.Context} and additional
179
+ * metadata for a given {@link Token:class | Token}
176
180
  * {@label TYPE}
177
181
  */
178
182
  type Metadata = Context & {
@@ -180,6 +184,9 @@ export declare namespace Token {
180
184
  tags: string[];
181
185
  claims?: JsonRecord;
182
186
  };
187
+ /**
188
+ * Returns {@link Metadata:type | Token.Metadata} for a given {@link Token:class | Token}
189
+ */
183
190
  function Metadata(token: Token, tags?: string[]): Metadata;
184
191
  /** @internal */
185
192
  interface TokenRequestParams extends OAuth2Request.RequestParams {
@@ -210,6 +217,10 @@ export declare namespace Token {
210
217
  }
211
218
  /**
212
219
  * Possible values provided to {@link OAuth2.OAuth2Client.revoke | OAuth2Client.revoke} to determine which tokens to revoke
220
+ * * `'ALL'` - revokes both the `access_token` and `refresh_token`.
221
+ * * `'ACCESS'` - revokes **only** the `access_token`.
222
+ * * `'REFRESH'` - revokes **only** the `refresh_token`.
223
+ * @inline
213
224
  */
214
225
  type RevokeType = 'ALL' | 'ACCESS' | 'REFRESH';
215
226
  /** @internal */
@@ -224,6 +235,7 @@ export declare namespace Token {
224
235
  }
225
236
  /**
226
237
  * Possible values provided to {@link OAuth2.OAuth2Client.introspect | OAuth2Client.introspect} to determine which token to introspect
238
+ * @inline
227
239
  */
228
240
  type Kind = 'access_token' | 'refresh_token' | 'id_token';
229
241
  /** @internal */
@@ -1,19 +1,50 @@
1
- import type { RequestAuthorizer, RequestAuthorizerInit, JsonRecord, AcrValues } from './types/index.ts';
2
- import { Token } from './Token.ts';
3
- import { EventEmitter } from './utils/EventEmitter.ts';
4
1
  /**
5
2
  * @module TokenOrchestrator
6
3
  */
4
+ import type { RequestAuthorizerInit, JsonRecord, AcrValues } from './types/index.ts';
5
+ import { Token } from './Token.ts';
6
+ import { EventEmitter } from './utils/EventEmitter.ts';
7
7
  /**
8
- * @abstract
8
+ * An abstraction layer between {@link Token} consumers and an application's internal management of {@link Token}s.
9
+ * Implementations of {@link TokenOrchestrator} handle fetching, refreshing, and storing tokens. There is an expectation
10
+ * (but not enforced by code) that tokens provided by {@link TokenOrchestrator} methods are valid (not expired).
11
+ *
12
+ * Consumers simply call {@link TokenOrchestrator.getToken} (or {@link TokenOrchestrator.authorize}) to use tokens as needed.
9
13
  *
10
- * Defines how {@link Token | Tokens} are retrieved to be consumed within an application
14
+ * @typeParam E - Map of all events fired from {@link TokenOrchestrator.emitter}
11
15
  *
12
- * @see {@link FetchClient}
16
+ * @remarks
17
+ * // TODO
18
+ * Each [Platform Library](/docs/structure#tier-3) offers {@link TokenOrchestrator} implementations relevant to the corresponding platform.
19
+ *
20
+ * @see
21
+ * * Orchestrator Consumer Example: {@link FetchClient}
13
22
  */
14
- export declare abstract class TokenOrchestrator<E extends TokenOrchestrator.Events = TokenOrchestrator.Events> implements RequestAuthorizer {
23
+ export declare abstract class TokenOrchestrator<E extends TokenOrchestrator.Events = TokenOrchestrator.Events> {
24
+ /**
25
+ * Possible events: {@link TokenOrchestrator.Events}
26
+ *
27
+ * @example
28
+ * To add a new event within a derived class, first extend {@link TokenOrchestrator.Events}, like so:
29
+ * ```ts
30
+ * type MyOrchestratorEvents = { 'no_token': { params: any } } & TokenOrchestrator.Events;
31
+ *
32
+ * class MyTokenOrchestrator<E extends MyOrchestratorEvents = MyOrchestratorEvents> extends TokenOrchestrator<E> {
33
+ * protected async getToken (params: TokenOrchestrator.AuthorizeParams): Promise<Token | null> {
34
+ * const token = this.findTokenInStorage(params); // example method
35
+ * if (token === null) {
36
+ * // this `.emit` call will be properly typed
37
+ * this.emitter.emit('no_token', params);
38
+ * }
39
+ * return token;
40
+ * }
41
+ * }
42
+ * ```
43
+ */
15
44
  protected readonly emitter: EventEmitter<E>;
45
+ /** alias for `this.emitter.on` */
16
46
  on(...args: Parameters<EventEmitter<E>['on']>): EventEmitter<E>;
47
+ /** alias for `this.emitter.off` */
17
48
  off(...args: Parameters<EventEmitter<E>['off']>): EventEmitter<E>;
18
49
  /**
19
50
  * @abstract
@@ -22,15 +53,34 @@ export declare abstract class TokenOrchestrator<E extends TokenOrchestrator.Even
22
53
  */
23
54
  abstract getToken(params: TokenOrchestrator.AuthorizeParams): Promise<Token | null>;
24
55
  /**
25
- * Signs an outgoing {@link !Request} with an `Authorization` header via {@link Token.Token | Token} retrieved from {@link getToken}
56
+ * @abstract
57
+ * Invalidates a {@link Token.Token | Token}, so subsequent {@link TokenOrchestrator.getToken | getToken} calls will result in the invalidated token
58
+ */
59
+ abstract invalidateToken(id: string): Promise<void>;
60
+ /**
61
+ * Signs an outgoing {@link !Request} with an `Authorization` header via {@link Token | Token} retrieved from {@link getToken}
26
62
  *
27
63
  * Optionally {@link TokenOrchestrator.AuthorizeParams | AuthorizeParams} can be provided to be passed along to {@link getToken}
28
- *
29
- * @see {@link FetchClient}
30
64
  */
31
- authorize(input: string | URL | Request, init?: RequestAuthorizerInit & TokenOrchestrator.AuthorizeParams): Promise<Request>;
65
+ authorize(input: string | URL | Request, init?: RequestAuthorizerInit & TokenOrchestrator.AuthorizeParams): Promise<{
66
+ request: Request;
67
+ tokenId: string;
68
+ }>;
32
69
  }
33
70
  export declare namespace TokenOrchestrator {
71
+ /**
72
+ * @interface
73
+ * Map of events fired from {@link TokenOrchestrator.emitter}
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * // key = Event name
78
+ * // value = Event Type
79
+ * client.emitter.on('error', ({ error }) => {
80
+ * console.log(error);
81
+ * });
82
+ * ```
83
+ */
34
84
  type Events = {
35
85
  error: {
36
86
  error: Error | JsonRecord;
@@ -10,85 +10,292 @@ import { APIClientError } from '../errors/index.ts';
10
10
  export * from './requests/APIRequest.ts';
11
11
  export * from './requests/OAuth2Request.ts';
12
12
  /**
13
- * @group APIClient
13
+ * Generic HTTP client with built in request retry
14
+ * @typeParam E - Map of all events fired from {@link APIClient.emitter}
15
+ *
16
+ * @example
17
+ * To add an event within a derived class, first extend {@link APIClient.Events}, like so:
18
+ * ```ts
19
+ * type MyAPIEvents = { 'foo': { bar: number } } & APIClient.Events;
20
+ *
21
+ * class MyAPIClient<E extends MyAPIEvents = MyAPIEvents> extends APIClient<E> {
22
+ * protected async send (request: APIRequest): Promise<Response> {
23
+ * // this will be properly type checked
24
+ * this.emitter('foo', { bar: 1 });
25
+ * return super.send(request);
26
+ * }
27
+ * }
28
+ * ```
29
+ *
30
+ * @remarks Most application developers won't need to extend this class directly — reach for
31
+ * {@link OAuth2.OAuth2Client | OAuth2Client} or {@link FetchClient} instead
14
32
  */
15
33
  export declare abstract class APIClient<E extends APIClient.Events = APIClient.Events> {
16
34
  #private;
17
35
  readonly configuration: APIClient.Configuration;
36
+ /**
37
+ * Possible events: {@link APIClient.Events}
38
+ */
18
39
  readonly emitter: EventEmitter<E>;
40
+ /**
41
+ * A cache of `dpop-nonce` values returned by authorization or resource servers.
42
+ * The cached nonce values will be used when generating DPoP JWTs for outgoing requests.
43
+ * @remarks Only relevant if client is configured with `dpop: true`
44
+ */
19
45
  protected readonly dpopNonceCache: DPoPNonceCache;
46
+ /** @internal */
20
47
  protected readonly interceptors: APIClient.RequestInterceptor[];
48
+ /** Map of HTTP headers to apply to every request */
21
49
  defaultHeaders: Record<string, string>;
50
+ /** Default {@link APIClient.RequestOptions} to apply to every request */
22
51
  defaultRequestOptions: APIClient.RequestOptions;
23
52
  constructor(params?: APIClient.ConfigurationParams | APIClient.Configuration);
53
+ /**
54
+ * Returns a key for a giving request to store or retrieve nonce values from the {@link APIClient.dpopNonceCache}
55
+ * @group DPoP
56
+ */
24
57
  protected getDPoPNonceCacheKey(request: Request): string;
58
+ /**
59
+ * Retrieves a nonce value from the {@link APIClient.dpopNonceCache}
60
+ * @group DPoP
61
+ */
25
62
  protected getDPoPNonceFromCache(request: Request): Promise<string | undefined>;
63
+ /**
64
+ * Caches an incoming nonce value from the {@link APIClient.dpopNonceCache}
65
+ * @group DPoP
66
+ */
26
67
  protected cacheDPoPNonce(request: Request, nonce: string): Promise<void>;
68
+ /**
69
+ * Cleans up resources associated with the client instance, so that it may be garbage collected.
70
+ *
71
+ * > [!Warning]
72
+ * > **DO NOT** use this method on active clients.
73
+ *
74
+ * @internal
75
+ */
76
+ dispose(): void;
27
77
  /**
28
78
  * Registers an {@link APIClient.RequestInterceptor} on the {@link APIClient}
29
79
  *
30
80
  * @example
81
+ * ```ts
31
82
  * const interceptor = (request: Request) => {
32
83
  * req.headers.append('foo', '1');
33
84
  * return req;
34
85
  * };
35
86
  * client.addInterceptor(interceptor);
87
+ * ```
88
+ * @group Interceptors
36
89
  */
37
90
  addInterceptor(interceptor: APIClient.RequestInterceptor): void;
38
91
  /**
39
92
  * Unregisters an {@link APIClient.RequestInterceptor} on the {@link APIClient}
40
93
  *
41
94
  * @example
95
+ * ```ts
42
96
  * const interceptor = (request: Request) => { ... };
43
97
  * client.addInterceptor(interceptor);
44
98
  * ...
45
99
  * client.removeInterceptor(interceptor);
100
+ * ```
101
+ * @group Interceptors
46
102
  */
47
103
  removeInterceptor(interceptor: APIClient.RequestInterceptor): void;
104
+ /**
105
+ * @group Interceptors
106
+ * @internal
107
+ */
48
108
  protected applyInterceptors(request: APIRequest): Promise<Request>;
109
+ /**
110
+ * Determines if a {@link !Response} indicates a DPoP nonce error. If error is present, returns
111
+ * the value of the `dpop-nonce` response header.
112
+ *
113
+ * @group DPoP
114
+ * @remarks
115
+ * * {@link OAuth2.OAuth2Client} provides an authorization server-provided nonce implementation
116
+ * * {@link FetchClient} provides an resource server-provided nonce implementation
117
+ *
118
+ * @see
119
+ * * {@link https://datatracker.ietf.org/doc/html/rfc9449#section-11.3 | RFC 9449 - DPoP Nonce Downgrade}
120
+ * * {@link https://datatracker.ietf.org/doc/html/rfc9449#section-8 | RFC 9449 - Authorization Server-Provided Nonce}
121
+ * * {@link https://datatracker.ietf.org/doc/html/rfc9449#section-9 | RFC 9449 - Resource Server-Provided Nonce}
122
+ */
49
123
  protected abstract checkForDPoPNonceErrorResponse(response: Response): Promise<string | undefined>;
124
+ /**
125
+ * Prepares an {@link APIRequest} for a retry with a new `dpop-nonce` value
126
+ *
127
+ * @group DPoP
128
+ *
129
+ * @see
130
+ * * {@link APIClient.checkForDPoPNonceErrorResponse}
131
+ * * {@link https://datatracker.ietf.org/doc/html/rfc9449#section-8 | RFC 9449 - Authorization Server-Provided Nonce}
132
+ * * {@link https://datatracker.ietf.org/doc/html/rfc9449#section-9 | RFC 9449 - Resource Server-Provided Nonce}
133
+ */
50
134
  protected abstract prepareDPoPNonceRetry(request: APIRequest, nonce: string): Promise<void>;
135
+ /**
136
+ * Called on every {@link !Response} received.
137
+ */
51
138
  protected processResponse(response: Response, request: APIRequest): Promise<void>;
139
+ /**
140
+ * Called on every {@link !Response} where `response.ok` is `false`
141
+ *
142
+ * @example
143
+ * When processing a {@link !Response}, `processErrorResponse` may invoke {@link APIClient.retry}. Therefore, when extending
144
+ * `APIClient` and calling `super.processErrorResponse` the same error condition could be handled twice erroneously.<br/>
145
+ * To prevent this, check if the parameter `response` and the return value of `super.processErrorResponse` are equal (the
146
+ * same {@link !Response} instance). If they are not equal, the `response` was already retried.
147
+ * ```ts
148
+ * class MyAPIClient extends APIClient {
149
+ * protected async processErrorResponse (response: Response, request: APIRequest): Promise<Response> {
150
+ * const res = await super.processErrorResponse(response, request);
151
+ * if (response !== res) {
152
+ * // response was already retried, return new `Response` instance.
153
+ * return res;
154
+ * }
155
+ * response = res;
156
+ *
157
+ * // handle other scenarios here
158
+ *
159
+ * return response;
160
+ * }
161
+ * }
162
+ * ```
163
+ */
52
164
  protected processErrorResponse(response: Response, request: APIRequest): Promise<Response>;
165
+ /**
166
+ * @abstract
167
+ * Signs an outgoing {@link APIRequest} with required authentication information.
168
+ *
169
+ * This method is marked as `abstract` since not every API requires authentication.
170
+ *
171
+ * @remarks
172
+ * Most implementations of this method usually invoke {@link Token.Token.authorize | Token.authorize}
173
+ */
53
174
  protected authorize(request: APIRequest): Promise<void>;
175
+ /**
176
+ * **Do not call directly** use {@link APIClient.send}.
177
+ *
178
+ * This method provides an alternative means to provide a custom {@link fetch} implementation. By default,
179
+ * this method invokes {@link APIClient.Configuration.fetchImpl | .fetchImpl} and falls back to `globalThis.fetch`
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * class MyAPIClient extends APIClient {
184
+ * protected sendRequest (request: Request): Promise<Response> {
185
+ * return customFetch(request);
186
+ * }
187
+ * }
188
+ * ```
189
+ */
54
190
  protected sendRequest(request: Request): Promise<Response>;
191
+ /**
192
+ * Sends an outgoing {@link APIRequest} and processes the {@link !Response}.
193
+ *
194
+ * @remarks
195
+ * It's **NOT** recommended to override this method, as it contains the majority of the business logic
196
+ */
55
197
  protected send(request: APIRequest): Promise<Response>;
198
+ /**
199
+ * Prepares a {@link APIRequest} for a retry attempt and sends the retry request. Usually invoked within
200
+ * {@link APIClient.processErrorResponse}
201
+ */
56
202
  protected retry(request: APIRequest): Promise<Response>;
203
+ /**
204
+ * Calculates a delay to wait before retrying a {@link APIRequest} which previously responded with `429`.
205
+ * Useful for rate limited APIs.
206
+ */
57
207
  protected getRetryDelay(response: Response, request: APIRequest): number;
208
+ /**
209
+ * A `public` method to expose {@link APIClient.send}
210
+ * @param args - matches call signature of {@link !fetch}
211
+ *
212
+ * @example
213
+ * ```ts
214
+ * class MyAPIClient extends APIClient {...}
215
+ * const client = new MyAPIClient();
216
+ *
217
+ * async function fetchData () {
218
+ * return client.fetch('/foo');
219
+ * }
220
+ * ```
221
+ */
58
222
  fetch(...args: ConstructorParameters<typeof APIRequest>): Promise<Response>;
59
223
  }
60
- /**
61
- * @group APIClient
62
- */
63
224
  export declare namespace APIClient {
225
+ /**
226
+ * Options to provide to {@link Configuration} at instantiation
227
+ */
64
228
  type ConfigurationParams = {
65
229
  dpop?: boolean;
66
230
  fetchImpl?: typeof fetch;
67
231
  };
68
232
  class Configuration implements JSONSerializable {
233
+ /**
234
+ * When `true`, client will utilize DPoP-bound tokens.
235
+ *
236
+ * @remarks
237
+ * Highly recommended feature; greatly improves security posture.
238
+ *
239
+ * @see
240
+ * {@link https://datatracker.ietf.org/doc/html/rfc9449 | DPoP RFC}
241
+ */
69
242
  dpop: boolean;
243
+ /**
244
+ * Implementation of {@link !fetch} used by the client. Defaults to `globalThis.fetch`.
245
+ *
246
+ * @remarks
247
+ * Providing a custom {@link !fetch} implementation can enable greater HTTP request customizations.
248
+ */
70
249
  fetchImpl?: typeof fetch;
250
+ /**
251
+ * @defaultValue
252
+ * ```ts
253
+ * { dpop: false }
254
+ * ```
255
+ */
71
256
  static DefaultOptions: {
72
257
  dpop: boolean;
73
258
  fetchImpl?: typeof fetch;
74
259
  };
75
260
  constructor(params: APIClient.ConfigurationParams);
261
+ /**
262
+ * Returns JSON representiation of {@link Configuration:class | Configuration}
263
+ */
76
264
  toJSON(): JsonRecord;
77
265
  }
266
+ /**
267
+ * Options which control how an {@link APIClient} sends a request.
268
+ */
78
269
  type RequestOptions = {
79
270
  /**
80
- * When `true`, utilizes the provided {@link TokenOrchestrator} to acquire an access token to sign the outgoing request with the proper
81
- * `Authorization` and `Dpop` headers, depending on the {@link TokenType} of the acquired {@link Token}. Defaults to `true`
271
+ * Determines whether a {@link APIRequest} should invoke {@link APIClient.authorize} before sending. Defaults to `true`
82
272
  */
83
273
  authorizeRequest: boolean | ((request: APIRequest) => boolean);
84
274
  };
275
+ /**
276
+ * Function signature for {@link APIClient} request interceptors.
277
+ */
85
278
  type RequestInterceptor = (request: APIRequest) => (Promise<APIRequest> | APIRequest);
279
+ /**
280
+ * @interface
281
+ * Map of events fired from {@link APIClient.emitter}
282
+ *
283
+ * @example
284
+ * ```ts
285
+ * // key = Event name
286
+ * // value = Event Type
287
+ * client.emitter.on('will_send', ({ request }) => {
288
+ * console.log(request.url.href);
289
+ * });
290
+ * ```
291
+ */
86
292
  type Events = {
87
293
  /**
88
294
  * Fired before a request is sent
89
295
  *
90
296
  * @remarks
91
- * The `request` instance is `readonly`. For outgoing request customization see {@link APIClient.addInterceptor}
297
+ * The `request` instance is `readonly`. For outgoing request customization see
298
+ * {@link Networking.APIClient.addInterceptor | APIClient.addInterceptor}
92
299
  */
93
300
  'will_send': {
94
301
  request: Request;
@@ -101,7 +308,8 @@ export declare namespace APIClient {
101
308
  response: Response;
102
309
  };
103
310
  /**
104
- * Fired after a {@link fetch} call fails to complete (`TypeError: Failed to fetch`)
311
+ * Fired after a {@link fetch} call fails to complete (no response is received).
312
+ * Usually indicated via `TypeError: Failed to fetch`
105
313
  */
106
314
  'network_failure': {
107
315
  request: Request;
@@ -109,5 +317,9 @@ export declare namespace APIClient {
109
317
  cause: Error;
110
318
  };
111
319
  };
320
+ /**
321
+ * Determines whether a value is an {@link !Error} indicating network connectivity problems when awaiting
322
+ * a {@link !fetch} request.
323
+ */
112
324
  function isNetworkError(err: unknown): boolean;
113
325
  }
@@ -1,5 +1,10 @@
1
1
  /**
2
2
  * @module Networking
3
+ *
4
+ * @groupDescription WWWAuthenticate
5
+ * A collection of utilities for parsing `www-autheticate` headers
6
+ * * {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/WWW-Authenticate | MDN - WWW-Authenticate}
7
+ * * {@link https://datatracker.ietf.org/doc/html/rfc7235#section-4.1 | RFC 7235 - WWW-Authenticate}
3
8
  */
4
9
  export * from './requests/OAuth2Request.ts';
5
10
  export * from './APIClient.ts';
@@ -1,19 +1,45 @@
1
1
  /**
2
- * @group APIClient
2
+ * @module
3
+ * @mergeModuleWith Networking
4
+ */
5
+ /**
6
+ * Properties requried to construct an instance of {@link APIRequest}
3
7
  */
4
8
  export type APIRequestInit = RequestInit & {
5
9
  context?: object;
6
10
  };
7
11
  /**
8
- * @group APIClient
12
+ * An extension of {@link !Request} to be used within {@link APIClient}.
13
+ *
14
+ * Holds a request {@link APIRequest.context | context } and {@link APIRequest.retryAttempt | retry count}
15
+ *
16
+ * @noInheritDoc
9
17
  */
10
18
  export declare class APIRequest extends Request {
11
19
  #private;
20
+ /**
21
+ * Maximum number of retries which are allowed to be attempted for a given {@link APIRequest}.
22
+ * @defaultValue 2
23
+ *
24
+ * @remarks
25
+ * Changing this value will only effect `APIRequest`s created _afterwards_. It will have no effect
26
+ * on any prexisting instances.
27
+ */
12
28
  static MaxRetryAttempts: number;
29
+ /**
30
+ * A map to store contextual information about the `APIRequest`, meaningful to the specific {@link APIClient}
31
+ */
13
32
  readonly context: Record<string, any>;
14
33
  constructor(input: string | URL | Request, init?: APIRequestInit);
15
34
  get retryAttempt(): number;
35
+ /**
36
+ * Compares the retry counter to {@link APIRequest.MaxRetryAttempts}
37
+ */
16
38
  canRetry(): boolean;
39
+ /**
40
+ * Increments retry counter
41
+ */
17
42
  markRetry(): void;
43
+ /** @internal */
18
44
  clone(): APIRequest;
19
45
  }
@@ -6,25 +6,35 @@ import type { OpenIdConfiguration } from '../../types/index.ts';
6
6
  import type { OAuth2Client } from '../../oauth2/client.ts';
7
7
  import { APIRequest } from './APIRequest.ts';
8
8
  /**
9
- * @group OAuth2Request
9
+ * A builder class for {@link !Request} instances representing a OAuth2 endpoint request
10
+ * @group OAuth2Client
10
11
  */
11
12
  export declare abstract class OAuth2Request {
13
+ /** HTTP headers for the outgoing request */
12
14
  headers: Headers;
15
+ /** HTTP body for the outgoing request */
13
16
  body: URLSearchParams;
17
+ /** Reference to the OAuth2 Metadata document from the authorization server */
14
18
  openIdConfiguration: OpenIdConfiguration;
19
+ /** Configuration of the {@link OAuth2Client} being used to send the request */
15
20
  clientConfiguration: OAuth2Client.Configuration;
21
+ /** Authentication setting for the authorization server. Only relevant to Confidental Clients */
16
22
  clientAuthentication: any;
17
23
  constructor(params: OAuth2Request.RequestParams);
24
+ /** Returns the URL of the request */
18
25
  abstract get url(): string;
19
26
  prepare(context?: object): APIRequest;
20
27
  }
21
28
  /**
22
- * @group OAuth2Request
29
+ * @group OAuth2Client
23
30
  */
24
31
  export declare namespace OAuth2Request {
25
32
  interface RequestParams {
33
+ /** Reference to the OAuth2 Metadata document from the authorization server */
26
34
  openIdConfiguration: OpenIdConfiguration;
35
+ /** Configuration of the {@link OAuth2Client} being used to send the request */
27
36
  clientConfiguration: OAuth2Client.Configuration;
37
+ /** Authentication setting for the authorization server. Only relevant to Confidental Clients */
28
38
  clientAuthentication?: any;
29
39
  }
30
40
  }
@@ -3,7 +3,11 @@
3
3
  * @mergeModuleWith Networking
4
4
  */
5
5
  /**
6
+ * Object representiation of a parsed `www-authenticate` header
6
7
  * @group WWWAuthenticate
8
+ * @see
9
+ * * {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/WWW-Authenticate | MDN}
10
+ * * {@link https://datatracker.ietf.org/doc/html/rfc7235#section-4.1 | RFC 7235 - WWW-Authenticate}
7
11
  */
8
12
  export interface WWWAuthenticateError {
9
13
  readonly error: string;
@@ -12,17 +16,21 @@ export interface WWWAuthenticateError {
12
16
  [key: string]: string;
13
17
  }
14
18
  /**
19
+ * Type predicate for {@link WWWAuthenticateError}
15
20
  * @group WWWAuthenticate
16
21
  */
17
22
  export declare function isWWWAuthenticateError(input: unknown): input is WWWAuthenticateError;
18
23
  /**
19
- * parses a www-authenticate header and builds an object representation of the error condition
24
+ * Parses a `www-authenticate` header and returns an object representation of the error condition.
20
25
  *
21
26
  * @group WWWAuthenticate
27
+ * @see
28
+ * * {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/WWW-Authenticate | MDN}
29
+ * * {@link https://datatracker.ietf.org/doc/html/rfc7235#section-4.1 | RFC 7235 - WWW-Authenticate}
22
30
  */
23
31
  export declare function parse(header: string | Headers | Response): WWWAuthenticateError | null;
24
32
  /**
25
- * Returns string value of a `www-authenticate` header
33
+ * Returns string value of a `www-authenticate` header.
26
34
  *
27
35
  * @remarks
28
36
  * `HeadersInit` allows for a few different representations of headers with different access patterns (.get vs [key])