@enfuce/nextgen-sdk 0.0.7 → 0.0.8

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 (54) hide show
  1. package/README.md +19 -6
  2. package/dist/authorisation-control/client.d.ts +2 -2
  3. package/dist/card/client.d.ts +2 -2
  4. package/dist/cardholder/client.d.ts +2 -2
  5. package/dist/cards/client.d.ts +2 -2
  6. package/dist/esm/authorisation-control/client.d.ts +2 -2
  7. package/dist/esm/card/client.d.ts +2 -2
  8. package/dist/esm/cardholder/client.d.ts +2 -2
  9. package/dist/esm/cards/client.d.ts +2 -2
  10. package/dist/esm/exchange-rate/client.d.ts +2 -2
  11. package/dist/esm/issuer-events/client.d.ts +2 -2
  12. package/dist/esm/oauth/axios.d.ts +3 -3
  13. package/dist/esm/oauth/axios.js +1 -1
  14. package/dist/esm/oauth/clientCredentials.d.ts +17 -3
  15. package/dist/esm/oauth/clientCredentials.js +20 -4
  16. package/dist/esm/oauth/index.d.ts +2 -2
  17. package/dist/esm/oauth/index.js +1 -1
  18. package/dist/esm/oauth/tokenManager.d.ts +2 -2
  19. package/dist/esm/oauth/tokenManager.js +2 -2
  20. package/dist/esm/pin/client.d.ts +2 -2
  21. package/dist/esm/threeds/client.d.ts +2 -2
  22. package/dist/esm/threeds-oob/client.d.ts +2 -2
  23. package/dist/esm/wallet/client.d.ts +2 -2
  24. package/dist/exchange-rate/client.d.ts +2 -2
  25. package/dist/issuer-events/client.d.ts +2 -2
  26. package/dist/oauth/axios.d.ts +3 -3
  27. package/dist/oauth/axios.js +1 -1
  28. package/dist/oauth/clientCredentials.d.ts +17 -3
  29. package/dist/oauth/clientCredentials.js +19 -3
  30. package/dist/oauth/index.d.ts +2 -2
  31. package/dist/oauth/index.js +2 -2
  32. package/dist/oauth/tokenManager.d.ts +2 -2
  33. package/dist/oauth/tokenManager.js +4 -4
  34. package/dist/pin/client.d.ts +2 -2
  35. package/dist/threeds/client.d.ts +2 -2
  36. package/dist/threeds-oob/client.d.ts +2 -2
  37. package/dist/wallet/client.d.ts +2 -2
  38. package/package.json +1 -1
  39. package/src/authorisation-control/client.ts +3 -3
  40. package/src/card/client.ts +3 -3
  41. package/src/cardholder/client.ts +3 -3
  42. package/src/cards/client.ts +3 -3
  43. package/src/exchange-rate/client.ts +3 -3
  44. package/src/issuer-events/client.ts +3 -3
  45. package/src/oauth/axios.ts +3 -3
  46. package/src/oauth/clientCredentials.ts +43 -4
  47. package/src/oauth/index.ts +2 -2
  48. package/src/oauth/tokenManager.ts +2 -2
  49. package/src/pin/client.ts +3 -3
  50. package/src/threeds/client.ts +3 -3
  51. package/src/threeds-oob/client.ts +3 -3
  52. package/src/wallet/client.ts +3 -3
  53. package/test/clientCredentials.test.ts +20 -0
  54. package/test/oauth.test.ts +12 -12
@@ -16,20 +16,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
16
16
  });
17
17
  };
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.TokenManager = void 0;
19
+ exports.OAuthClientCredentialsManager = void 0;
20
20
  /**
21
21
  * Caches an access token and refreshes it before expiry. Plug it into a generated
22
22
  * client's `Configuration`:
23
23
  *
24
24
  * ```ts
25
- * const tokens = new TokenManager(fetcher);
25
+ * const tokens = new OAuthClientCredentialsManager(fetcher);
26
26
  * const config = new card.Configuration({ accessToken: () => tokens.getToken() });
27
27
  * ```
28
28
  *
29
29
  * A token is considered expired once the clock passes `expiry - skew`. Concurrent
30
30
  * refreshes share a single in-flight promise, so the token endpoint is hit once.
31
31
  */
32
- class TokenManager {
32
+ class OAuthClientCredentialsManager {
33
33
  constructor(fetcher, skewSeconds = 60, now = Date.now) {
34
34
  this.fetcher = fetcher;
35
35
  this.skewSeconds = skewSeconds;
@@ -78,4 +78,4 @@ class TokenManager {
78
78
  return this.inflight;
79
79
  }
80
80
  }
81
- exports.TokenManager = TokenManager;
81
+ exports.OAuthClientCredentialsManager = OAuthClientCredentialsManager;
@@ -1,5 +1,5 @@
1
1
  import { type AxiosInstance } from 'axios';
2
- import { type TokenManager } from '../oauth';
2
+ import { type OAuthClientCredentialsManager } from '../oauth';
3
3
  import { Configuration } from './configuration';
4
4
  import { PINOperationsUsingPKIApi, PINOperationsWithPreSharedKeyApi } from './api';
5
5
  /**
@@ -38,7 +38,7 @@ export declare class PinClientBuilder {
38
38
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
39
39
  baseUrl(baseUrl: string): this;
40
40
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
41
- oauth(tokens: TokenManager): this;
41
+ oauth(tokens: OAuthClientCredentialsManager): this;
42
42
  /**
43
43
  * Customize the underlying axios instance — set a timeout (`http.defaults.timeout = ...`), a proxy,
44
44
  * default headers, extra interceptors, etc. Runs after OAuth is installed. Composable: multiple
@@ -1,5 +1,5 @@
1
1
  import { type AxiosInstance } from 'axios';
2
- import { type TokenManager } from '../oauth';
2
+ import { type OAuthClientCredentialsManager } from '../oauth';
3
3
  import { Configuration } from './configuration';
4
4
  import { ThreeDSApi } from './api';
5
5
  /**
@@ -36,7 +36,7 @@ export declare class ThreedsClientBuilder {
36
36
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
37
37
  baseUrl(baseUrl: string): this;
38
38
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
39
- oauth(tokens: TokenManager): this;
39
+ oauth(tokens: OAuthClientCredentialsManager): this;
40
40
  /**
41
41
  * Customize the underlying axios instance — set a timeout (`http.defaults.timeout = ...`), a proxy,
42
42
  * default headers, extra interceptors, etc. Runs after OAuth is installed. Composable: multiple
@@ -1,5 +1,5 @@
1
1
  import { type AxiosInstance } from 'axios';
2
- import { type TokenManager } from '../oauth';
2
+ import { type OAuthClientCredentialsManager } from '../oauth';
3
3
  import { Configuration } from './configuration';
4
4
  import { OOBAuthenticationChallengeWebhookNotificationApi } from './api';
5
5
  /**
@@ -36,7 +36,7 @@ export declare class ThreedsOobClientBuilder {
36
36
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
37
37
  baseUrl(baseUrl: string): this;
38
38
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
39
- oauth(tokens: TokenManager): this;
39
+ oauth(tokens: OAuthClientCredentialsManager): this;
40
40
  /**
41
41
  * Customize the underlying axios instance — set a timeout (`http.defaults.timeout = ...`), a proxy,
42
42
  * default headers, extra interceptors, etc. Runs after OAuth is installed. Composable: multiple
@@ -1,5 +1,5 @@
1
1
  import { type AxiosInstance } from 'axios';
2
- import { type TokenManager } from '../oauth';
2
+ import { type OAuthClientCredentialsManager } from '../oauth';
3
3
  import { Configuration } from './configuration';
4
4
  import { ActivateTokenApi, DeactivateTokenApi, EligibleTokenRequestorsApi, GetTokensApi, PushCardsApi, PushProvisionApi, SuspendTokenApi, UnsuspendTokenApi } from './api';
5
5
  /**
@@ -50,7 +50,7 @@ export declare class WalletClientBuilder {
50
50
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
51
51
  baseUrl(baseUrl: string): this;
52
52
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
53
- oauth(tokens: TokenManager): this;
53
+ oauth(tokens: OAuthClientCredentialsManager): this;
54
54
  /**
55
55
  * Customize the underlying axios instance — set a timeout (`http.defaults.timeout = ...`), a proxy,
56
56
  * default headers, extra interceptors, etc. Runs after OAuth is installed. Composable: multiple
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enfuce/nextgen-sdk",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Enfuce nextgen client SDK (TypeScript). One namespaced export per API.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -6,7 +6,7 @@
6
6
  * retry) to the module's Configuration and exposes each API. Nothing is shared across modules.
7
7
  */
8
8
  import globalAxios, { type AxiosInstance } from 'axios';
9
- import { createOAuthAxios, type TokenManager } from '../oauth';
9
+ import { createOAuthAxios, type OAuthClientCredentialsManager } from '../oauth';
10
10
  import { Configuration } from './configuration';
11
11
  import {
12
12
  AuthorisationRequestAPIApi,
@@ -50,7 +50,7 @@ export class AuthorisationControlClient {
50
50
  export class AuthorisationControlClientBuilder {
51
51
 
52
52
  private _baseUrl?: string;
53
- private _tokens?: TokenManager;
53
+ private _tokens?: OAuthClientCredentialsManager;
54
54
  private _customizers: Array<(http: AxiosInstance) => void> = [];
55
55
 
56
56
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
@@ -60,7 +60,7 @@ export class AuthorisationControlClientBuilder {
60
60
  }
61
61
 
62
62
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
63
- oauth(tokens: TokenManager): this {
63
+ oauth(tokens: OAuthClientCredentialsManager): this {
64
64
  this._tokens = tokens;
65
65
  return this;
66
66
  }
@@ -6,7 +6,7 @@
6
6
  * retry) to the module's Configuration and exposes each API. Nothing is shared across modules.
7
7
  */
8
8
  import globalAxios, { type AxiosInstance } from 'axios';
9
- import { createOAuthAxios, type TokenManager } from '../oauth';
9
+ import { createOAuthAxios, type OAuthClientCredentialsManager } from '../oauth';
10
10
  import { Configuration } from './configuration';
11
11
  import {
12
12
  CreateCardApi,
@@ -80,7 +80,7 @@ export class CardClient {
80
80
  export class CardClientBuilder {
81
81
 
82
82
  private _baseUrl?: string;
83
- private _tokens?: TokenManager;
83
+ private _tokens?: OAuthClientCredentialsManager;
84
84
  private _customizers: Array<(http: AxiosInstance) => void> = [];
85
85
 
86
86
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
@@ -90,7 +90,7 @@ export class CardClientBuilder {
90
90
  }
91
91
 
92
92
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
93
- oauth(tokens: TokenManager): this {
93
+ oauth(tokens: OAuthClientCredentialsManager): this {
94
94
  this._tokens = tokens;
95
95
  return this;
96
96
  }
@@ -6,7 +6,7 @@
6
6
  * retry) to the module's Configuration and exposes each API. Nothing is shared across modules.
7
7
  */
8
8
  import globalAxios, { type AxiosInstance } from 'axios';
9
- import { createOAuthAxios, type TokenManager } from '../oauth';
9
+ import { createOAuthAxios, type OAuthClientCredentialsManager } from '../oauth';
10
10
  import { Configuration } from './configuration';
11
11
  import {
12
12
  CreateCardholderApi,
@@ -68,7 +68,7 @@ export class CardholderClient {
68
68
  export class CardholderClientBuilder {
69
69
 
70
70
  private _baseUrl?: string;
71
- private _tokens?: TokenManager;
71
+ private _tokens?: OAuthClientCredentialsManager;
72
72
  private _customizers: Array<(http: AxiosInstance) => void> = [];
73
73
 
74
74
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
@@ -78,7 +78,7 @@ export class CardholderClientBuilder {
78
78
  }
79
79
 
80
80
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
81
- oauth(tokens: TokenManager): this {
81
+ oauth(tokens: OAuthClientCredentialsManager): this {
82
82
  this._tokens = tokens;
83
83
  return this;
84
84
  }
@@ -6,7 +6,7 @@
6
6
  * retry) to the module's Configuration and exposes each API. Nothing is shared across modules.
7
7
  */
8
8
  import globalAxios, { type AxiosInstance } from 'axios';
9
- import { createOAuthAxios, type TokenManager } from '../oauth';
9
+ import { createOAuthAxios, type OAuthClientCredentialsManager } from '../oauth';
10
10
  import { Configuration } from './configuration';
11
11
  import {
12
12
  CardsApi,
@@ -50,7 +50,7 @@ export class CardsClient {
50
50
  export class CardsClientBuilder {
51
51
 
52
52
  private _baseUrl?: string;
53
- private _tokens?: TokenManager;
53
+ private _tokens?: OAuthClientCredentialsManager;
54
54
  private _customizers: Array<(http: AxiosInstance) => void> = [];
55
55
 
56
56
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
@@ -60,7 +60,7 @@ export class CardsClientBuilder {
60
60
  }
61
61
 
62
62
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
63
- oauth(tokens: TokenManager): this {
63
+ oauth(tokens: OAuthClientCredentialsManager): this {
64
64
  this._tokens = tokens;
65
65
  return this;
66
66
  }
@@ -6,7 +6,7 @@
6
6
  * retry) to the module's Configuration and exposes each API. Nothing is shared across modules.
7
7
  */
8
8
  import globalAxios, { type AxiosInstance } from 'axios';
9
- import { createOAuthAxios, type TokenManager } from '../oauth';
9
+ import { createOAuthAxios, type OAuthClientCredentialsManager } from '../oauth';
10
10
  import { Configuration } from './configuration';
11
11
  import {
12
12
  GetECBExchangeRateApi,
@@ -62,7 +62,7 @@ export class ExchangeRateClient {
62
62
  export class ExchangeRateClientBuilder {
63
63
 
64
64
  private _baseUrl?: string;
65
- private _tokens?: TokenManager;
65
+ private _tokens?: OAuthClientCredentialsManager;
66
66
  private _customizers: Array<(http: AxiosInstance) => void> = [];
67
67
 
68
68
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
@@ -72,7 +72,7 @@ export class ExchangeRateClientBuilder {
72
72
  }
73
73
 
74
74
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
75
- oauth(tokens: TokenManager): this {
75
+ oauth(tokens: OAuthClientCredentialsManager): this {
76
76
  this._tokens = tokens;
77
77
  return this;
78
78
  }
@@ -6,7 +6,7 @@
6
6
  * retry) to the module's Configuration and exposes each API. Nothing is shared across modules.
7
7
  */
8
8
  import globalAxios, { type AxiosInstance } from 'axios';
9
- import { createOAuthAxios, type TokenManager } from '../oauth';
9
+ import { createOAuthAxios, type OAuthClientCredentialsManager } from '../oauth';
10
10
  import { Configuration } from './configuration';
11
11
  import {
12
12
  IssuerEventWebhooksApi,
@@ -50,7 +50,7 @@ export class IssuerEventsClient {
50
50
  export class IssuerEventsClientBuilder {
51
51
 
52
52
  private _baseUrl?: string;
53
- private _tokens?: TokenManager;
53
+ private _tokens?: OAuthClientCredentialsManager;
54
54
  private _customizers: Array<(http: AxiosInstance) => void> = [];
55
55
 
56
56
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
@@ -60,7 +60,7 @@ export class IssuerEventsClientBuilder {
60
60
  }
61
61
 
62
62
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
63
- oauth(tokens: TokenManager): this {
63
+ oauth(tokens: OAuthClientCredentialsManager): this {
64
64
  this._tokens = tokens;
65
65
  return this;
66
66
  }
@@ -6,7 +6,7 @@
6
6
  * OpenAPI Generator to (re)produce it.
7
7
  */
8
8
  import axios, { AxiosError, AxiosInstance, InternalAxiosRequestConfig } from 'axios';
9
- import { TokenManager } from './tokenManager';
9
+ import { OAuthClientCredentialsManager } from './tokenManager';
10
10
 
11
11
  const BEARER_PREFIX = 'Bearer ';
12
12
 
@@ -22,7 +22,7 @@ function stripBearer(header: string): string {
22
22
  * Returns an {@link AxiosInstance} with OAuth bearer-token handling built in:
23
23
  *
24
24
  * - **Proactive:** a request interceptor attaches a fresh bearer token (from the
25
- * {@link TokenManager}) to *every* request. This authenticates API modules whose spec declares no
25
+ * {@link OAuthClientCredentialsManager}) to *every* request. This authenticates API modules whose spec declares no
26
26
  * security scheme (e.g. exchange-rate), so no `accessToken` on the `Configuration` is required.
27
27
  * - **Reactive:** a response interceptor, on a `401`, forces a token refresh and retries the request
28
28
  * exactly once with the new bearer token.
@@ -35,7 +35,7 @@ function stripBearer(header: string): string {
35
35
  * const api = new card.CardApi(config, undefined, http);
36
36
  * ```
37
37
  */
38
- export function createOAuthAxios(manager: TokenManager, instance?: AxiosInstance): AxiosInstance {
38
+ export function createOAuthAxios(manager: OAuthClientCredentialsManager, instance?: AxiosInstance): AxiosInstance {
39
39
  const http = instance ?? axios.create();
40
40
 
41
41
  // Proactive: attach a fresh bearer token to every outgoing request.
@@ -6,7 +6,7 @@
6
6
  * OpenAPI Generator to (re)produce it.
7
7
  */
8
8
  import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
9
- import { AccessToken, TokenFetcher, TokenManager } from './tokenManager';
9
+ import { AccessToken, TokenFetcher, OAuthClientCredentialsManager } from './tokenManager';
10
10
 
11
11
  /** Configuration for the OAuth2 `client_credentials` grant. */
12
12
  export interface OAuthConfig {
@@ -23,6 +23,19 @@ export interface OAuthConfig {
23
23
  axiosInstance?: AxiosInstance;
24
24
  }
25
25
 
26
+ /**
27
+ * The OAuth2 client-credentials identity — the client id/secret and requested scopes. It carries
28
+ * no URL: pair it with a token URL (e.g. derived from a `TenantEnvironment`) via the
29
+ * `clientCredentials(tokenUrl, credentials)` overload below.
30
+ */
31
+ export interface ClientCredentials {
32
+ clientId: string;
33
+ /** May be omitted for a public client. */
34
+ clientSecret?: string;
35
+ /** Requested scopes; space-joined into a `scope` parameter. */
36
+ scopes?: string[];
37
+ }
38
+
26
39
  interface TokenResponse {
27
40
  access_token?: string;
28
41
  expires_in?: number;
@@ -66,7 +79,33 @@ export function clientCredentialsFetcher(config: OAuthConfig): TokenFetcher {
66
79
  };
67
80
  }
68
81
 
69
- /** Convenience: a caching {@link TokenManager} backed by the client-credentials grant. */
70
- export function clientCredentials(config: OAuthConfig, skewSeconds: number = 60): TokenManager {
71
- return new TokenManager(clientCredentialsFetcher(config), skewSeconds);
82
+ /** Convenience: a caching {@link OAuthClientCredentialsManager} backed by the client-credentials grant. */
83
+ export function clientCredentials(config: OAuthConfig, skewSeconds?: number): OAuthClientCredentialsManager;
84
+ /** Convenience overload pairing a token URL with a {@link ClientCredentials} identity. */
85
+ export function clientCredentials(
86
+ tokenUrl: string,
87
+ credentials: ClientCredentials,
88
+ skewSeconds?: number,
89
+ ): OAuthClientCredentialsManager;
90
+ export function clientCredentials(
91
+ configOrUrl: OAuthConfig | string,
92
+ credsOrSkew?: ClientCredentials | number,
93
+ skewSeconds = 60,
94
+ ): OAuthClientCredentialsManager {
95
+ let config: OAuthConfig;
96
+ let skew: number;
97
+ if (typeof configOrUrl === 'string') {
98
+ const creds = credsOrSkew as ClientCredentials;
99
+ config = {
100
+ tokenUrl: configOrUrl,
101
+ clientId: creds.clientId,
102
+ clientSecret: creds.clientSecret ?? '',
103
+ scopes: creds.scopes,
104
+ };
105
+ skew = skewSeconds;
106
+ } else {
107
+ config = configOrUrl;
108
+ skew = typeof credsOrSkew === 'number' ? credsOrSkew : 60;
109
+ }
110
+ return new OAuthClientCredentialsManager(clientCredentialsFetcher(config), skew);
72
111
  }
@@ -22,6 +22,6 @@
22
22
  *
23
23
  * Server-side only — a client secret must never ship to a browser.
24
24
  */
25
- export { AccessToken, TokenFetcher, TokenManager } from './tokenManager';
26
- export { OAuthConfig, clientCredentials, clientCredentialsFetcher } from './clientCredentials';
25
+ export { AccessToken, TokenFetcher, OAuthClientCredentialsManager } from './tokenManager';
26
+ export { ClientCredentials, OAuthConfig, clientCredentials, clientCredentialsFetcher } from './clientCredentials';
27
27
  export { createOAuthAxios } from './axios';
@@ -21,14 +21,14 @@ export type TokenFetcher = () => Promise<AccessToken>;
21
21
  * client's `Configuration`:
22
22
  *
23
23
  * ```ts
24
- * const tokens = new TokenManager(fetcher);
24
+ * const tokens = new OAuthClientCredentialsManager(fetcher);
25
25
  * const config = new card.Configuration({ accessToken: () => tokens.getToken() });
26
26
  * ```
27
27
  *
28
28
  * A token is considered expired once the clock passes `expiry - skew`. Concurrent
29
29
  * refreshes share a single in-flight promise, so the token endpoint is hit once.
30
30
  */
31
- export class TokenManager {
31
+ export class OAuthClientCredentialsManager {
32
32
  private token?: string;
33
33
  private expiresAtMs?: number;
34
34
  private inflight?: Promise<string>;
package/src/pin/client.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  * retry) to the module's Configuration and exposes each API. Nothing is shared across modules.
7
7
  */
8
8
  import globalAxios, { type AxiosInstance } from 'axios';
9
- import { createOAuthAxios, type TokenManager } from '../oauth';
9
+ import { createOAuthAxios, type OAuthClientCredentialsManager } from '../oauth';
10
10
  import { Configuration } from './configuration';
11
11
  import {
12
12
  PINOperationsUsingPKIApi,
@@ -56,7 +56,7 @@ export class PinClient {
56
56
  export class PinClientBuilder {
57
57
 
58
58
  private _baseUrl?: string;
59
- private _tokens?: TokenManager;
59
+ private _tokens?: OAuthClientCredentialsManager;
60
60
  private _customizers: Array<(http: AxiosInstance) => void> = [];
61
61
 
62
62
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
@@ -66,7 +66,7 @@ export class PinClientBuilder {
66
66
  }
67
67
 
68
68
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
69
- oauth(tokens: TokenManager): this {
69
+ oauth(tokens: OAuthClientCredentialsManager): this {
70
70
  this._tokens = tokens;
71
71
  return this;
72
72
  }
@@ -6,7 +6,7 @@
6
6
  * retry) to the module's Configuration and exposes each API. Nothing is shared across modules.
7
7
  */
8
8
  import globalAxios, { type AxiosInstance } from 'axios';
9
- import { createOAuthAxios, type TokenManager } from '../oauth';
9
+ import { createOAuthAxios, type OAuthClientCredentialsManager } from '../oauth';
10
10
  import { Configuration } from './configuration';
11
11
  import {
12
12
  ThreeDSApi,
@@ -50,7 +50,7 @@ export class ThreedsClient {
50
50
  export class ThreedsClientBuilder {
51
51
 
52
52
  private _baseUrl?: string;
53
- private _tokens?: TokenManager;
53
+ private _tokens?: OAuthClientCredentialsManager;
54
54
  private _customizers: Array<(http: AxiosInstance) => void> = [];
55
55
 
56
56
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
@@ -60,7 +60,7 @@ export class ThreedsClientBuilder {
60
60
  }
61
61
 
62
62
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
63
- oauth(tokens: TokenManager): this {
63
+ oauth(tokens: OAuthClientCredentialsManager): this {
64
64
  this._tokens = tokens;
65
65
  return this;
66
66
  }
@@ -6,7 +6,7 @@
6
6
  * retry) to the module's Configuration and exposes each API. Nothing is shared across modules.
7
7
  */
8
8
  import globalAxios, { type AxiosInstance } from 'axios';
9
- import { createOAuthAxios, type TokenManager } from '../oauth';
9
+ import { createOAuthAxios, type OAuthClientCredentialsManager } from '../oauth';
10
10
  import { Configuration } from './configuration';
11
11
  import {
12
12
  OOBAuthenticationChallengeWebhookNotificationApi,
@@ -50,7 +50,7 @@ export class ThreedsOobClient {
50
50
  export class ThreedsOobClientBuilder {
51
51
 
52
52
  private _baseUrl?: string;
53
- private _tokens?: TokenManager;
53
+ private _tokens?: OAuthClientCredentialsManager;
54
54
  private _customizers: Array<(http: AxiosInstance) => void> = [];
55
55
 
56
56
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
@@ -60,7 +60,7 @@ export class ThreedsOobClientBuilder {
60
60
  }
61
61
 
62
62
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
63
- oauth(tokens: TokenManager): this {
63
+ oauth(tokens: OAuthClientCredentialsManager): this {
64
64
  this._tokens = tokens;
65
65
  return this;
66
66
  }
@@ -6,7 +6,7 @@
6
6
  * retry) to the module's Configuration and exposes each API. Nothing is shared across modules.
7
7
  */
8
8
  import globalAxios, { type AxiosInstance } from 'axios';
9
- import { createOAuthAxios, type TokenManager } from '../oauth';
9
+ import { createOAuthAxios, type OAuthClientCredentialsManager } from '../oauth';
10
10
  import { Configuration } from './configuration';
11
11
  import {
12
12
  ActivateTokenApi,
@@ -92,7 +92,7 @@ export class WalletClient {
92
92
  export class WalletClientBuilder {
93
93
 
94
94
  private _baseUrl?: string;
95
- private _tokens?: TokenManager;
95
+ private _tokens?: OAuthClientCredentialsManager;
96
96
  private _customizers: Array<(http: AxiosInstance) => void> = [];
97
97
 
98
98
  /** The module's host, e.g. `https://api.<tenant>.../issuer`. */
@@ -102,7 +102,7 @@ export class WalletClientBuilder {
102
102
  }
103
103
 
104
104
  /** Install OAuth: a fresh bearer token on every request + reactive 401 retry. */
105
- oauth(tokens: TokenManager): this {
105
+ oauth(tokens: OAuthClientCredentialsManager): this {
106
106
  this._tokens = tokens;
107
107
  return this;
108
108
  }
@@ -0,0 +1,20 @@
1
+ /** Tests for the ClientCredentials identity object and the clientCredentials overloads. */
2
+ import { describe, expect, it } from 'vitest';
3
+ import { oauth } from '../src';
4
+
5
+ describe('ClientCredentials pairing', () => {
6
+ it('clientCredentials(tokenUrl, credentials) builds an OAuthClientCredentialsManager', () => {
7
+ const creds: oauth.ClientCredentials = { clientId: 'id', clientSecret: 'secret', scopes: ['s.read'] };
8
+ const mgr = oauth.clientCredentials('https://auth.example.com/oauth2/token', creds);
9
+ expect(mgr).toBeInstanceOf(oauth.OAuthClientCredentialsManager);
10
+ });
11
+
12
+ it('still accepts a full OAuthConfig', () => {
13
+ const mgr = oauth.clientCredentials({
14
+ tokenUrl: 'https://auth.example.com/oauth2/token',
15
+ clientId: 'id',
16
+ clientSecret: 'secret',
17
+ });
18
+ expect(mgr).toBeInstanceOf(oauth.OAuthClientCredentialsManager);
19
+ });
20
+ });
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Tests for the hand-written OAuth token-management helper (src/oauth).
3
3
  *
4
- * Covers the TokenManager cache/refresh/single-flight logic, the client-credentials
4
+ * Covers the OAuthClientCredentialsManager cache/refresh/single-flight logic, the client-credentials
5
5
  * fetcher and the reactive 401-retry axios instance, using capturing axios adapters
6
6
  * so nothing hits the network.
7
7
  */
@@ -9,7 +9,7 @@ import axios, { type AxiosAdapter, type InternalAxiosRequestConfig } from 'axios
9
9
  import { describe, expect, it } from 'vitest';
10
10
  import { oauth } from '../src';
11
11
 
12
- const { TokenManager, clientCredentialsFetcher, clientCredentials, createOAuthAxios } = oauth;
12
+ const { OAuthClientCredentialsManager, clientCredentialsFetcher, clientCredentials, createOAuthAxios } = oauth;
13
13
 
14
14
  function makeClock(start = 1000) {
15
15
  const state = { t: start };
@@ -25,11 +25,11 @@ function countingFetcher(expiresInSeconds = 300) {
25
25
  return { fetch, calls };
26
26
  }
27
27
 
28
- describe('TokenManager', () => {
28
+ describe('OAuthClientCredentialsManager', () => {
29
29
  it('caches the token within its validity window', async () => {
30
30
  const { fetch, calls } = countingFetcher();
31
31
  const clock = makeClock();
32
- const mgr = new TokenManager(fetch, 60, clock.now);
32
+ const mgr = new OAuthClientCredentialsManager(fetch, 60, clock.now);
33
33
 
34
34
  expect(await mgr.getToken()).toBe('token-1');
35
35
  expect(await mgr.getToken()).toBe('token-1');
@@ -39,7 +39,7 @@ describe('TokenManager', () => {
39
39
  it('refreshes once past expiry minus skew', async () => {
40
40
  const { fetch, calls } = countingFetcher(300);
41
41
  const clock = makeClock();
42
- const mgr = new TokenManager(fetch, 60, clock.now);
42
+ const mgr = new OAuthClientCredentialsManager(fetch, 60, clock.now);
43
43
 
44
44
  expect(await mgr.getToken()).toBe('token-1');
45
45
  clock.advance(239_000);
@@ -53,7 +53,7 @@ describe('TokenManager', () => {
53
53
 
54
54
  it('refetches every call when lifetime is unknown', async () => {
55
55
  const { fetch, calls } = countingFetcher(0);
56
- const mgr = new TokenManager(fetch, 60, makeClock().now);
56
+ const mgr = new OAuthClientCredentialsManager(fetch, 60, makeClock().now);
57
57
  await mgr.getToken();
58
58
  await mgr.getToken();
59
59
  expect(calls.n).toBe(2);
@@ -61,7 +61,7 @@ describe('TokenManager', () => {
61
61
 
62
62
  it('shares a single in-flight fetch across concurrent callers', async () => {
63
63
  const { fetch, calls } = countingFetcher();
64
- const mgr = new TokenManager(fetch, 60, makeClock().now);
64
+ const mgr = new OAuthClientCredentialsManager(fetch, 60, makeClock().now);
65
65
 
66
66
  const results = await Promise.all([mgr.getToken(), mgr.getToken(), mgr.getToken()]);
67
67
 
@@ -71,7 +71,7 @@ describe('TokenManager', () => {
71
71
 
72
72
  it('forceRefresh is a no-op when the cached token already moved on', async () => {
73
73
  const { fetch, calls } = countingFetcher();
74
- const mgr = new TokenManager(fetch, 60, makeClock().now);
74
+ const mgr = new OAuthClientCredentialsManager(fetch, 60, makeClock().now);
75
75
 
76
76
  expect(await mgr.getToken()).toBe('token-1');
77
77
  expect(await mgr.forceRefresh('an-older-token')).toBe('token-1');
@@ -129,7 +129,7 @@ describe('clientCredentialsFetcher', () => {
129
129
  expect(captured.config?.auth).toBeUndefined();
130
130
  });
131
131
 
132
- it('clientCredentials returns a caching TokenManager', async () => {
132
+ it('clientCredentials returns a caching OAuthClientCredentialsManager', async () => {
133
133
  const { instance } = capturingAxios({ access_token: 'abc', expires_in: 120 });
134
134
  const mgr = clientCredentials(
135
135
  { tokenUrl: 'https://auth.example.com/oauth/token', clientId: 'id', clientSecret: 's', axiosInstance: instance },
@@ -141,7 +141,7 @@ describe('clientCredentialsFetcher', () => {
141
141
  describe('createOAuthAxios', () => {
142
142
  it('proactively attaches a bearer token to a request that has no Authorization header', async () => {
143
143
  const { fetch, calls } = countingFetcher();
144
- const mgr = new TokenManager(fetch, 60, makeClock().now);
144
+ const mgr = new OAuthClientCredentialsManager(fetch, 60, makeClock().now);
145
145
 
146
146
  const seenAuth: (string | undefined)[] = [];
147
147
  const adapter: AxiosAdapter = async (config) => {
@@ -160,7 +160,7 @@ describe('createOAuthAxios', () => {
160
160
 
161
161
  it('retries the request with a refreshed token when the first call rejects with 401', async () => {
162
162
  const { fetch } = countingFetcher();
163
- const mgr = new TokenManager(fetch, 60, makeClock().now);
163
+ const mgr = new OAuthClientCredentialsManager(fetch, 60, makeClock().now);
164
164
  await mgr.getToken(); // seed token-1
165
165
 
166
166
  const seenAuth: (string | undefined)[] = [];
@@ -196,7 +196,7 @@ describe('createOAuthAxios', () => {
196
196
 
197
197
  it('surfaces the error after a single retry (no infinite loop)', async () => {
198
198
  const { fetch } = countingFetcher();
199
- const mgr = new TokenManager(fetch, 60, makeClock().now);
199
+ const mgr = new OAuthClientCredentialsManager(fetch, 60, makeClock().now);
200
200
  await mgr.getToken();
201
201
 
202
202
  let calls = 0;