@oxyhq/core 3.4.5 → 3.4.6
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/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/OxyServices.base.js +39 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/OxyServices.base.js +39 -0
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/HttpService.d.ts +1 -1
- package/dist/types/OxyServices.base.d.ts +14 -0
- package/dist/types/OxyServices.d.ts +2 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/mixins/OxyServices.analytics.d.ts +1 -0
- package/dist/types/mixins/OxyServices.appData.d.ts +1 -0
- package/dist/types/mixins/OxyServices.applications.d.ts +1 -0
- package/dist/types/mixins/OxyServices.assets.d.ts +1 -0
- package/dist/types/mixins/OxyServices.auth.d.ts +1 -0
- package/dist/types/mixins/OxyServices.contacts.d.ts +1 -0
- package/dist/types/mixins/OxyServices.devices.d.ts +1 -0
- package/dist/types/mixins/OxyServices.features.d.ts +1 -0
- package/dist/types/mixins/OxyServices.fedcm.d.ts +1 -0
- package/dist/types/mixins/OxyServices.language.d.ts +1 -0
- package/dist/types/mixins/OxyServices.location.d.ts +1 -0
- package/dist/types/mixins/OxyServices.managedAccounts.d.ts +1 -0
- package/dist/types/mixins/OxyServices.payment.d.ts +1 -0
- package/dist/types/mixins/OxyServices.privacy.d.ts +1 -0
- package/dist/types/mixins/OxyServices.redirect.d.ts +1 -0
- package/dist/types/mixins/OxyServices.reputation.d.ts +1 -0
- package/dist/types/mixins/OxyServices.security.d.ts +1 -0
- package/dist/types/mixins/OxyServices.silent.d.ts +1 -0
- package/dist/types/mixins/OxyServices.sso.d.ts +1 -0
- package/dist/types/mixins/OxyServices.topics.d.ts +1 -0
- package/dist/types/mixins/OxyServices.user.d.ts +1 -0
- package/dist/types/mixins/OxyServices.utility.d.ts +1 -0
- package/dist/types/mixins/OxyServices.workspaces.d.ts +1 -0
- package/package.json +1 -1
- package/src/HttpService.ts +1 -1
- package/src/OxyServices.base.ts +50 -1
- package/src/OxyServices.ts +3 -1
- package/src/__tests__/linkedClient.test.ts +64 -0
- package/src/index.ts +1 -0
|
@@ -172,7 +172,7 @@ export declare class HttpService {
|
|
|
172
172
|
* Get auth header with automatic token refresh
|
|
173
173
|
*/
|
|
174
174
|
private getAuthHeader;
|
|
175
|
-
|
|
175
|
+
refreshAccessToken(reason: AuthRefreshReason): Promise<string | null>;
|
|
176
176
|
/**
|
|
177
177
|
* Unwrap standardized API response format
|
|
178
178
|
*/
|
|
@@ -3,6 +3,10 @@ import { HttpService, type RequestOptions } from './HttpService';
|
|
|
3
3
|
export interface OxyConfig extends OxyConfigBase {
|
|
4
4
|
cloudURL?: string;
|
|
5
5
|
}
|
|
6
|
+
export interface LinkedHttpClient {
|
|
7
|
+
client: HttpService;
|
|
8
|
+
dispose(): void;
|
|
9
|
+
}
|
|
6
10
|
/**
|
|
7
11
|
* Base class for OxyServices with core infrastructure
|
|
8
12
|
*/
|
|
@@ -40,6 +44,16 @@ export declare class OxyServicesBase {
|
|
|
40
44
|
* Useful for advanced use cases where direct access to the HTTP service is needed
|
|
41
45
|
*/
|
|
42
46
|
getClient(): HttpService;
|
|
47
|
+
/**
|
|
48
|
+
* Create an app/backend HTTP client linked to this Oxy session.
|
|
49
|
+
*
|
|
50
|
+
* Use this when an app has its own API origin (for example
|
|
51
|
+
* `https://api.syra.fm`) but authentication is owned by the canonical
|
|
52
|
+
* OxyServices instance mounted in OxyProvider. The returned client has its own
|
|
53
|
+
* base URL, cache and request queue, but its bearer token is kept in lockstep
|
|
54
|
+
* with this session and its 401 refresh path delegates back to this session.
|
|
55
|
+
*/
|
|
56
|
+
createLinkedClient(config: OxyConfig): LinkedHttpClient;
|
|
43
57
|
/**
|
|
44
58
|
* Get performance metrics
|
|
45
59
|
*/
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
*
|
|
57
57
|
* See method JSDoc for more details and options.
|
|
58
58
|
*/
|
|
59
|
-
import { type OxyConfig } from './OxyServices.base';
|
|
59
|
+
import { type LinkedHttpClient, type OxyConfig } from './OxyServices.base';
|
|
60
60
|
import { OxyAuthenticationError, OxyAuthenticationTimeoutError } from './OxyServices.errors';
|
|
61
61
|
import type { SessionLoginResponse } from './models/session';
|
|
62
62
|
import type { FedCMAuthOptions, FedCMConfig } from './mixins/OxyServices.fedcm';
|
|
@@ -111,6 +111,7 @@ export declare class OxyServices extends OxyServicesComposed {
|
|
|
111
111
|
constructor(config: OxyConfig);
|
|
112
112
|
}
|
|
113
113
|
export interface OxyServices extends InstanceType<ReturnType<typeof composeOxyServices>> {
|
|
114
|
+
createLinkedClient(config: OxyConfig): LinkedHttpClient;
|
|
114
115
|
isFedCMSupported(): boolean;
|
|
115
116
|
signInWithFedCM(options?: FedCMAuthOptions): Promise<SessionLoginResponse>;
|
|
116
117
|
silentSignInWithFedCM(): Promise<SessionLoginResponse | null>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
import './crypto/polyfill';
|
|
20
20
|
export { OxyServices, OxyAuthenticationError, OxyAuthenticationTimeoutError } from './OxyServices';
|
|
21
21
|
export { OXY_CLOUD_URL, oxyClient } from './OxyServices';
|
|
22
|
+
export type { LinkedHttpClient } from './OxyServices.base';
|
|
22
23
|
export { AuthManager, createAuthManager } from './AuthManager';
|
|
23
24
|
export type { StorageAdapter, AuthStateChangeCallback, AuthMethod, AuthManagerConfig, } from './AuthManager';
|
|
24
25
|
export type { AuthManagerAccount, RestoreFromCookiesResult, RestoreFromCookiesOptions, SwitchAuthuserResult, } from './AuthManagerTypes';
|
|
@@ -27,6 +27,7 @@ export declare function OxyServicesAnalyticsMixin<T extends typeof OxyServicesBa
|
|
|
27
27
|
getBaseURL(): string;
|
|
28
28
|
getSessionBaseUrl(): string;
|
|
29
29
|
getClient(): import("../HttpService").HttpService;
|
|
30
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
30
31
|
getMetrics(): {
|
|
31
32
|
totalRequests: number;
|
|
32
33
|
successfulRequests: number;
|
|
@@ -63,6 +63,7 @@ export declare function OxyServicesAppDataMixin<T extends typeof OxyServicesBase
|
|
|
63
63
|
getBaseURL(): string;
|
|
64
64
|
getSessionBaseUrl(): string;
|
|
65
65
|
getClient(): import("../HttpService").HttpService;
|
|
66
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
66
67
|
getMetrics(): {
|
|
67
68
|
totalRequests: number;
|
|
68
69
|
successfulRequests: number;
|
|
@@ -371,6 +371,7 @@ export declare function OxyServicesApplicationsMixin<T extends typeof OxyService
|
|
|
371
371
|
getBaseURL(): string;
|
|
372
372
|
getSessionBaseUrl(): string;
|
|
373
373
|
getClient(): import("../HttpService").HttpService;
|
|
374
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
374
375
|
getMetrics(): {
|
|
375
376
|
totalRequests: number;
|
|
376
377
|
successfulRequests: number;
|
|
@@ -100,6 +100,7 @@ export declare function OxyServicesAssetsMixin<T extends typeof OxyServicesBase>
|
|
|
100
100
|
getBaseURL(): string;
|
|
101
101
|
getSessionBaseUrl(): string;
|
|
102
102
|
getClient(): import("../HttpService").HttpService;
|
|
103
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
103
104
|
getMetrics(): {
|
|
104
105
|
totalRequests: number;
|
|
105
106
|
successfulRequests: number;
|
|
@@ -398,6 +398,7 @@ export declare function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(B
|
|
|
398
398
|
getBaseURL(): string;
|
|
399
399
|
getSessionBaseUrl(): string;
|
|
400
400
|
getClient(): import("../HttpService").HttpService;
|
|
401
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
401
402
|
getMetrics(): {
|
|
402
403
|
totalRequests: number;
|
|
403
404
|
successfulRequests: number;
|
|
@@ -55,6 +55,7 @@ export declare function OxyServicesContactsMixin<T extends typeof OxyServicesBas
|
|
|
55
55
|
getBaseURL(): string;
|
|
56
56
|
getSessionBaseUrl(): string;
|
|
57
57
|
getClient(): import("../HttpService").HttpService;
|
|
58
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
58
59
|
getMetrics(): {
|
|
59
60
|
totalRequests: number;
|
|
60
61
|
successfulRequests: number;
|
|
@@ -57,6 +57,7 @@ export declare function OxyServicesDevicesMixin<T extends typeof OxyServicesBase
|
|
|
57
57
|
getBaseURL(): string;
|
|
58
58
|
getSessionBaseUrl(): string;
|
|
59
59
|
getClient(): import("../HttpService").HttpService;
|
|
60
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
60
61
|
getMetrics(): {
|
|
61
62
|
totalRequests: number;
|
|
62
63
|
successfulRequests: number;
|
|
@@ -184,6 +184,7 @@ export declare function OxyServicesFeaturesMixin<T extends typeof OxyServicesBas
|
|
|
184
184
|
getBaseURL(): string;
|
|
185
185
|
getSessionBaseUrl(): string;
|
|
186
186
|
getClient(): import("../HttpService").HttpService;
|
|
187
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
187
188
|
getMetrics(): {
|
|
188
189
|
totalRequests: number;
|
|
189
190
|
successfulRequests: number;
|
|
@@ -259,6 +259,7 @@ export declare function OxyServicesFedCMMixin<T extends typeof OxyServicesBase>(
|
|
|
259
259
|
getBaseURL(): string;
|
|
260
260
|
getSessionBaseUrl(): string;
|
|
261
261
|
getClient(): import("../HttpService").HttpService;
|
|
262
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
262
263
|
getMetrics(): {
|
|
263
264
|
totalRequests: number;
|
|
264
265
|
successfulRequests: number;
|
|
@@ -42,6 +42,7 @@ export declare function OxyServicesLanguageMixin<T extends typeof OxyServicesBas
|
|
|
42
42
|
getBaseURL(): string;
|
|
43
43
|
getSessionBaseUrl(): string;
|
|
44
44
|
getClient(): import("../HttpService").HttpService;
|
|
45
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
45
46
|
getMetrics(): {
|
|
46
47
|
totalRequests: number;
|
|
47
48
|
successfulRequests: number;
|
|
@@ -25,6 +25,7 @@ export declare function OxyServicesLocationMixin<T extends typeof OxyServicesBas
|
|
|
25
25
|
getBaseURL(): string;
|
|
26
26
|
getSessionBaseUrl(): string;
|
|
27
27
|
getClient(): import("../HttpService").HttpService;
|
|
28
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
28
29
|
getMetrics(): {
|
|
29
30
|
totalRequests: number;
|
|
30
31
|
successfulRequests: number;
|
|
@@ -82,6 +82,7 @@ export declare function OxyServicesManagedAccountsMixin<T extends typeof OxyServ
|
|
|
82
82
|
getBaseURL(): string;
|
|
83
83
|
getSessionBaseUrl(): string;
|
|
84
84
|
getClient(): import("../HttpService").HttpService;
|
|
85
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
85
86
|
getMetrics(): {
|
|
86
87
|
totalRequests: number;
|
|
87
88
|
successfulRequests: number;
|
|
@@ -72,6 +72,7 @@ export declare function OxyServicesPaymentMixin<T extends typeof OxyServicesBase
|
|
|
72
72
|
getBaseURL(): string;
|
|
73
73
|
getSessionBaseUrl(): string;
|
|
74
74
|
getClient(): import("../HttpService").HttpService;
|
|
75
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
75
76
|
getMetrics(): {
|
|
76
77
|
totalRequests: number;
|
|
77
78
|
successfulRequests: number;
|
|
@@ -83,6 +83,7 @@ export declare function OxyServicesPrivacyMixin<T extends typeof OxyServicesBase
|
|
|
83
83
|
getBaseURL(): string;
|
|
84
84
|
getSessionBaseUrl(): string;
|
|
85
85
|
getClient(): import("../HttpService").HttpService;
|
|
86
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
86
87
|
getMetrics(): {
|
|
87
88
|
totalRequests: number;
|
|
88
89
|
successfulRequests: number;
|
|
@@ -44,6 +44,7 @@ export declare function OxyServicesRedirectAuthMixin<T extends typeof OxyService
|
|
|
44
44
|
getBaseURL(): string;
|
|
45
45
|
getSessionBaseUrl(): string;
|
|
46
46
|
getClient(): import("../HttpService").HttpService;
|
|
47
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
47
48
|
getMetrics(): {
|
|
48
49
|
totalRequests: number;
|
|
49
50
|
successfulRequests: number;
|
|
@@ -390,6 +390,7 @@ export declare function OxyServicesReputationMixin<T extends typeof OxyServicesB
|
|
|
390
390
|
getBaseURL(): string;
|
|
391
391
|
getSessionBaseUrl(): string;
|
|
392
392
|
getClient(): import("../HttpService").HttpService;
|
|
393
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
393
394
|
getMetrics(): {
|
|
394
395
|
totalRequests: number;
|
|
395
396
|
successfulRequests: number;
|
|
@@ -39,6 +39,7 @@ export declare function OxyServicesSecurityMixin<T extends typeof OxyServicesBas
|
|
|
39
39
|
getBaseURL(): string;
|
|
40
40
|
getSessionBaseUrl(): string;
|
|
41
41
|
getClient(): import("../HttpService").HttpService;
|
|
42
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
42
43
|
getMetrics(): {
|
|
43
44
|
totalRequests: number;
|
|
44
45
|
successfulRequests: number;
|
|
@@ -82,6 +82,7 @@ export declare function OxyServicesSilentAuthMixin<T extends typeof OxyServicesB
|
|
|
82
82
|
getBaseURL(): string;
|
|
83
83
|
getSessionBaseUrl(): string;
|
|
84
84
|
getClient(): import("../HttpService").HttpService;
|
|
85
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
85
86
|
getMetrics(): {
|
|
86
87
|
totalRequests: number;
|
|
87
88
|
successfulRequests: number;
|
|
@@ -64,6 +64,7 @@ export declare function OxyServicesSsoMixin<T extends typeof OxyServicesBase>(Ba
|
|
|
64
64
|
getBaseURL(): string;
|
|
65
65
|
getSessionBaseUrl(): string;
|
|
66
66
|
getClient(): import("../HttpService").HttpService;
|
|
67
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
67
68
|
getMetrics(): {
|
|
68
69
|
totalRequests: number;
|
|
69
70
|
successfulRequests: number;
|
|
@@ -65,6 +65,7 @@ export declare function OxyServicesTopicsMixin<T extends typeof OxyServicesBase>
|
|
|
65
65
|
getBaseURL(): string;
|
|
66
66
|
getSessionBaseUrl(): string;
|
|
67
67
|
getClient(): import("../HttpService").HttpService;
|
|
68
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
68
69
|
getMetrics(): {
|
|
69
70
|
totalRequests: number;
|
|
70
71
|
successfulRequests: number;
|
|
@@ -231,6 +231,7 @@ export declare function OxyServicesUserMixin<T extends typeof OxyServicesBase>(B
|
|
|
231
231
|
getBaseURL(): string;
|
|
232
232
|
getSessionBaseUrl(): string;
|
|
233
233
|
getClient(): import("../HttpService").HttpService;
|
|
234
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
234
235
|
getMetrics(): {
|
|
235
236
|
totalRequests: number;
|
|
236
237
|
successfulRequests: number;
|
|
@@ -250,6 +250,7 @@ export declare function OxyServicesUtilityMixin<T extends typeof OxyServicesBase
|
|
|
250
250
|
getBaseURL(): string;
|
|
251
251
|
getSessionBaseUrl(): string;
|
|
252
252
|
getClient(): import("../HttpService").HttpService;
|
|
253
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
253
254
|
getMetrics(): {
|
|
254
255
|
totalRequests: number;
|
|
255
256
|
successfulRequests: number;
|
|
@@ -159,6 +159,7 @@ export declare function OxyServicesWorkspacesMixin<T extends typeof OxyServicesB
|
|
|
159
159
|
getBaseURL(): string;
|
|
160
160
|
getSessionBaseUrl(): string;
|
|
161
161
|
getClient(): import("../HttpService").HttpService;
|
|
162
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
162
163
|
getMetrics(): {
|
|
163
164
|
totalRequests: number;
|
|
164
165
|
successfulRequests: number;
|
package/package.json
CHANGED
package/src/HttpService.ts
CHANGED
|
@@ -878,7 +878,7 @@ export class HttpService {
|
|
|
878
878
|
}
|
|
879
879
|
}
|
|
880
880
|
|
|
881
|
-
|
|
881
|
+
async refreshAccessToken(reason: AuthRefreshReason): Promise<string | null> {
|
|
882
882
|
if (!this.authRefreshHandler) {
|
|
883
883
|
return null;
|
|
884
884
|
}
|
package/src/OxyServices.base.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { jwtDecode } from 'jwt-decode';
|
|
7
7
|
import type { OxyConfig as OxyConfigBase, ApiError, User } from './models/interfaces';
|
|
8
8
|
import { handleHttpError } from './utils/errorUtils';
|
|
9
|
-
import { HttpService, type RequestOptions } from './HttpService';
|
|
9
|
+
import { HttpService, type AuthRefreshReason, type RequestOptions } from './HttpService';
|
|
10
10
|
import { OxyAuthenticationError, OxyAuthenticationTimeoutError } from './OxyServices.errors';
|
|
11
11
|
import { resolveCentralAuthUrl } from './utils/authWebUrl';
|
|
12
12
|
|
|
@@ -14,6 +14,11 @@ export interface OxyConfig extends OxyConfigBase {
|
|
|
14
14
|
cloudURL?: string;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
export interface LinkedHttpClient {
|
|
18
|
+
client: HttpService;
|
|
19
|
+
dispose(): void;
|
|
20
|
+
}
|
|
21
|
+
|
|
17
22
|
interface JwtPayload {
|
|
18
23
|
exp?: number;
|
|
19
24
|
userId?: string;
|
|
@@ -116,6 +121,50 @@ export class OxyServicesBase {
|
|
|
116
121
|
return this.httpService;
|
|
117
122
|
}
|
|
118
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Create an app/backend HTTP client linked to this Oxy session.
|
|
126
|
+
*
|
|
127
|
+
* Use this when an app has its own API origin (for example
|
|
128
|
+
* `https://api.syra.fm`) but authentication is owned by the canonical
|
|
129
|
+
* OxyServices instance mounted in OxyProvider. The returned client has its own
|
|
130
|
+
* base URL, cache and request queue, but its bearer token is kept in lockstep
|
|
131
|
+
* with this session and its 401 refresh path delegates back to this session.
|
|
132
|
+
*/
|
|
133
|
+
public createLinkedClient(config: OxyConfig): LinkedHttpClient {
|
|
134
|
+
const client = new HttpService(config);
|
|
135
|
+
|
|
136
|
+
const syncToken = (accessToken: string | null): void => {
|
|
137
|
+
const currentAccessToken = client.getAccessToken();
|
|
138
|
+
if (accessToken) {
|
|
139
|
+
if (currentAccessToken !== accessToken) {
|
|
140
|
+
client.setTokens(accessToken);
|
|
141
|
+
}
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (currentAccessToken) {
|
|
146
|
+
client.clearTokens();
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
syncToken(this.getAccessToken());
|
|
151
|
+
const unsubscribe = this.onTokensChanged(syncToken);
|
|
152
|
+
client.setAuthRefreshHandler(async (reason: AuthRefreshReason) => {
|
|
153
|
+
const refreshed = await this.httpService.refreshAccessToken(reason);
|
|
154
|
+
syncToken(refreshed);
|
|
155
|
+
return refreshed;
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
client,
|
|
160
|
+
dispose: () => {
|
|
161
|
+
unsubscribe();
|
|
162
|
+
client.setAuthRefreshHandler(null);
|
|
163
|
+
client.clearTokens();
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
119
168
|
/**
|
|
120
169
|
* Get performance metrics
|
|
121
170
|
*/
|
package/src/OxyServices.ts
CHANGED
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
*
|
|
57
57
|
* See method JSDoc for more details and options.
|
|
58
58
|
*/
|
|
59
|
-
import { OxyServicesBase, type OxyConfig } from './OxyServices.base';
|
|
59
|
+
import { OxyServicesBase, type LinkedHttpClient, type OxyConfig } from './OxyServices.base';
|
|
60
60
|
import { OxyAuthenticationError, OxyAuthenticationTimeoutError } from './OxyServices.errors';
|
|
61
61
|
import type { SessionLoginResponse } from './models/session';
|
|
62
62
|
import type { FedCMAuthOptions, FedCMConfig } from './mixins/OxyServices.fedcm';
|
|
@@ -130,6 +130,8 @@ export class OxyServices extends OxyServicesComposed {
|
|
|
130
130
|
// Explicit declarations are added for cross-domain auth methods that downstream
|
|
131
131
|
// packages (auth-sdk, services) need without casting to `any`.
|
|
132
132
|
export interface OxyServices extends InstanceType<ReturnType<typeof composeOxyServices>> {
|
|
133
|
+
createLinkedClient(config: OxyConfig): LinkedHttpClient;
|
|
134
|
+
|
|
133
135
|
// FedCM authentication
|
|
134
136
|
isFedCMSupported(): boolean;
|
|
135
137
|
signInWithFedCM(options?: FedCMAuthOptions): Promise<SessionLoginResponse>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { OxyServices } from '../OxyServices';
|
|
2
|
+
|
|
3
|
+
function createServices(): OxyServices {
|
|
4
|
+
return new OxyServices({ baseURL: 'https://api.oxy.so' });
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
describe('OxyServices.createLinkedClient', () => {
|
|
8
|
+
it('mirrors token changes from the session owner', () => {
|
|
9
|
+
const oxy = createServices();
|
|
10
|
+
const linked = oxy.createLinkedClient({ baseURL: 'https://api.syra.fm' });
|
|
11
|
+
|
|
12
|
+
expect(linked.client.getAccessToken()).toBeNull();
|
|
13
|
+
|
|
14
|
+
oxy.setTokens('access_1');
|
|
15
|
+
expect(linked.client.getAccessToken()).toBe('access_1');
|
|
16
|
+
|
|
17
|
+
oxy.setTokens('access_2');
|
|
18
|
+
expect(linked.client.getAccessToken()).toBe('access_2');
|
|
19
|
+
|
|
20
|
+
oxy.clearTokens();
|
|
21
|
+
expect(linked.client.getAccessToken()).toBeNull();
|
|
22
|
+
|
|
23
|
+
linked.dispose();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('copies the current token when created after sign-in', () => {
|
|
27
|
+
const oxy = createServices();
|
|
28
|
+
oxy.setTokens('existing_access');
|
|
29
|
+
|
|
30
|
+
const linked = oxy.createLinkedClient({ baseURL: 'https://api.syra.fm' });
|
|
31
|
+
|
|
32
|
+
expect(linked.client.getAccessToken()).toBe('existing_access');
|
|
33
|
+
|
|
34
|
+
linked.dispose();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('delegates token refresh to the session owner', async () => {
|
|
38
|
+
const oxy = createServices();
|
|
39
|
+
const linked = oxy.createLinkedClient({ baseURL: 'https://api.syra.fm' });
|
|
40
|
+
|
|
41
|
+
oxy.getClient().setAuthRefreshHandler(async () => 'refreshed_access');
|
|
42
|
+
|
|
43
|
+
const refreshed = await linked.client.refreshAccessToken('preflight');
|
|
44
|
+
|
|
45
|
+
expect(refreshed).toBe('refreshed_access');
|
|
46
|
+
expect(oxy.getAccessToken()).toBe('refreshed_access');
|
|
47
|
+
expect(linked.client.getAccessToken()).toBe('refreshed_access');
|
|
48
|
+
|
|
49
|
+
linked.dispose();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('stops mirroring after dispose', () => {
|
|
53
|
+
const oxy = createServices();
|
|
54
|
+
const linked = oxy.createLinkedClient({ baseURL: 'https://api.syra.fm' });
|
|
55
|
+
|
|
56
|
+
oxy.setTokens('before_dispose');
|
|
57
|
+
expect(linked.client.getAccessToken()).toBe('before_dispose');
|
|
58
|
+
|
|
59
|
+
linked.dispose();
|
|
60
|
+
oxy.setTokens('after_dispose');
|
|
61
|
+
|
|
62
|
+
expect(linked.client.getAccessToken()).toBeNull();
|
|
63
|
+
});
|
|
64
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -25,6 +25,7 @@ import './crypto/polyfill';
|
|
|
25
25
|
// ---------------------------------------------------------------------------
|
|
26
26
|
export { OxyServices, OxyAuthenticationError, OxyAuthenticationTimeoutError } from './OxyServices';
|
|
27
27
|
export { OXY_CLOUD_URL, oxyClient } from './OxyServices';
|
|
28
|
+
export type { LinkedHttpClient } from './OxyServices.base';
|
|
28
29
|
|
|
29
30
|
// ---------------------------------------------------------------------------
|
|
30
31
|
// Authentication
|