@enfuce/nextgen-sdk 0.0.6 → 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 (70) 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/config/enfuceUrls.d.ts +20 -0
  7. package/dist/config/enfuceUrls.js +47 -0
  8. package/dist/config/index.d.ts +1 -0
  9. package/dist/config/index.js +22 -0
  10. package/dist/esm/authorisation-control/client.d.ts +2 -2
  11. package/dist/esm/card/client.d.ts +2 -2
  12. package/dist/esm/cardholder/client.d.ts +2 -2
  13. package/dist/esm/cards/client.d.ts +2 -2
  14. package/dist/esm/config/enfuceUrls.d.ts +20 -0
  15. package/dist/esm/config/enfuceUrls.js +40 -0
  16. package/dist/esm/config/index.d.ts +1 -0
  17. package/dist/esm/config/index.js +14 -0
  18. package/dist/esm/exchange-rate/client.d.ts +2 -2
  19. package/dist/esm/index.d.ts +1 -0
  20. package/dist/esm/index.js +1 -0
  21. package/dist/esm/issuer-events/client.d.ts +2 -2
  22. package/dist/esm/oauth/axios.d.ts +3 -3
  23. package/dist/esm/oauth/axios.js +1 -1
  24. package/dist/esm/oauth/clientCredentials.d.ts +17 -3
  25. package/dist/esm/oauth/clientCredentials.js +20 -4
  26. package/dist/esm/oauth/index.d.ts +2 -2
  27. package/dist/esm/oauth/index.js +1 -1
  28. package/dist/esm/oauth/tokenManager.d.ts +2 -2
  29. package/dist/esm/oauth/tokenManager.js +2 -2
  30. package/dist/esm/pin/client.d.ts +2 -2
  31. package/dist/esm/threeds/client.d.ts +2 -2
  32. package/dist/esm/threeds-oob/client.d.ts +2 -2
  33. package/dist/esm/wallet/client.d.ts +2 -2
  34. package/dist/exchange-rate/client.d.ts +2 -2
  35. package/dist/index.d.ts +1 -0
  36. package/dist/index.js +2 -1
  37. package/dist/issuer-events/client.d.ts +2 -2
  38. package/dist/oauth/axios.d.ts +3 -3
  39. package/dist/oauth/axios.js +1 -1
  40. package/dist/oauth/clientCredentials.d.ts +17 -3
  41. package/dist/oauth/clientCredentials.js +19 -3
  42. package/dist/oauth/index.d.ts +2 -2
  43. package/dist/oauth/index.js +2 -2
  44. package/dist/oauth/tokenManager.d.ts +2 -2
  45. package/dist/oauth/tokenManager.js +4 -4
  46. package/dist/pin/client.d.ts +2 -2
  47. package/dist/threeds/client.d.ts +2 -2
  48. package/dist/threeds-oob/client.d.ts +2 -2
  49. package/dist/wallet/client.d.ts +2 -2
  50. package/package.json +1 -1
  51. package/src/authorisation-control/client.ts +3 -3
  52. package/src/card/client.ts +3 -3
  53. package/src/cardholder/client.ts +3 -3
  54. package/src/cards/client.ts +3 -3
  55. package/src/config/enfuceUrls.ts +57 -0
  56. package/src/config/index.ts +21 -0
  57. package/src/exchange-rate/client.ts +3 -3
  58. package/src/index.ts +1 -0
  59. package/src/issuer-events/client.ts +3 -3
  60. package/src/oauth/axios.ts +3 -3
  61. package/src/oauth/clientCredentials.ts +43 -4
  62. package/src/oauth/index.ts +2 -2
  63. package/src/oauth/tokenManager.ts +2 -2
  64. package/src/pin/client.ts +3 -3
  65. package/src/threeds/client.ts +3 -3
  66. package/src/threeds-oob/client.ts +3 -3
  67. package/src/wallet/client.ts +3 -3
  68. package/test/clientCredentials.test.ts +20 -0
  69. package/test/config.test.ts +33 -0
  70. package/test/oauth.test.ts +12 -12
@@ -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
+ });
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Tests for the hand-written tenant/environment URL helper (src/config).
3
+ */
4
+ import { describe, expect, it } from 'vitest';
5
+ import { config } from '../src';
6
+
7
+ const sandbox: config.TenantEnvironment = { tenant: 'swile', environment: 'ext-uat1-sandbox' };
8
+
9
+ describe('config URL helpers', () => {
10
+ it('derives per-domain base URLs as api.<tenant>.<environment>.mycore.enfuce.com/<domain>', () => {
11
+ expect(config.apiBaseUrl(sandbox)).toBe('https://api.swile.ext-uat1-sandbox.mycore.enfuce.com');
12
+ expect(config.issuerBaseUrl(sandbox)).toBe('https://api.swile.ext-uat1-sandbox.mycore.enfuce.com/issuer');
13
+ expect(config.processorBaseUrl(sandbox)).toBe('https://api.swile.ext-uat1-sandbox.mycore.enfuce.com/processor');
14
+ expect(config.exchangeRateBaseUrl(sandbox)).toBe(
15
+ 'https://api.swile.ext-uat1-sandbox.mycore.enfuce.com/exchange-rates-api',
16
+ );
17
+ });
18
+
19
+ it('derives the token URL from the auth host', () => {
20
+ expect(config.tokenUrl(sandbox)).toBe('https://auth.swile.ext-uat1-sandbox.mycore.enfuce.com/oauth2/token');
21
+ });
22
+
23
+ it('places a multi-segment environment verbatim', () => {
24
+ expect(config.issuerBaseUrl({ tenant: 'swile', environment: 'eu.live.prod' })).toBe(
25
+ 'https://api.swile.eu.live.prod.mycore.enfuce.com/issuer',
26
+ );
27
+ });
28
+
29
+ it('rejects an empty tenant or environment', () => {
30
+ expect(() => config.issuerBaseUrl({ tenant: ' ', environment: 'env' })).toThrow();
31
+ expect(() => config.tokenUrl({ tenant: 'swile', environment: '' })).toThrow();
32
+ });
33
+ });
@@ -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;