@accelbyte/sdk 0.0.0-dev-20240906023252 → 0.0.0-dev-20240911051006

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.
@@ -45,16 +45,15 @@ __export(index_node_exports, {
45
45
  IamErrorCode: () => IamErrorCode,
46
46
  Network: () => Network,
47
47
  RefreshSession: () => RefreshSession,
48
+ RefreshToken: () => RefreshToken,
48
49
  SdkDevice: () => SdkDevice,
49
50
  UrlHelper: () => UrlHelper,
50
51
  Validate: () => Validate,
52
+ createAuthInterceptor: () => createAuthInterceptor,
51
53
  createCustomPathInterceptor: () => createCustomPathInterceptor,
52
54
  createGetSessionInterceptor: () => createGetSessionInterceptor,
53
55
  createRefreshSessionInterceptor: () => createRefreshSessionInterceptor,
54
- createSessionExpiredInterceptor: () => createSessionExpiredInterceptor,
55
- doRefreshSession: () => doRefreshSession,
56
- isType: () => isType,
57
- refreshWithLock: () => refreshWithLock
56
+ isType: () => isType
58
57
  });
59
58
  module.exports = __toCommonJS(index_node_exports);
60
59
 
@@ -64,8 +63,29 @@ if (!global.crypto) {
64
63
  global.crypto = import_crypto.webcrypto;
65
64
  }
66
65
 
67
- // src/utils/Network.ts
66
+ // src/utils/ApiUtils.ts
68
67
  var import_axios = __toESM(require("axios"), 1);
68
+ var ApiUtils = class {
69
+ };
70
+ ApiUtils.mergeAxiosConfigs = (config, overrides) => {
71
+ return {
72
+ ...config,
73
+ ...overrides,
74
+ headers: {
75
+ ...config == null ? void 0 : config.headers,
76
+ ...overrides == null ? void 0 : overrides.headers
77
+ }
78
+ };
79
+ };
80
+ ApiUtils.is4xxError = (error) => {
81
+ if (import_axios.default.isAxiosError(error) && error.response) {
82
+ return error.response.status >= 400 && error.response.status <= 499;
83
+ }
84
+ return false;
85
+ };
86
+
87
+ // src/utils/Network.ts
88
+ var import_axios2 = __toESM(require("axios"), 1);
69
89
  var import_query_string = __toESM(require("query-string"), 1);
70
90
 
71
91
  // src/utils/SdkDevice.ts
@@ -109,7 +129,7 @@ var isMobile = (opts) => {
109
129
  // src/utils/Network.ts
110
130
  var _Network = class _Network {
111
131
  static create(...configs) {
112
- const axiosInstance = import_axios.default.create(
132
+ const axiosInstance = import_axios2.default.create(
113
133
  Object.assign(
114
134
  {
115
135
  paramsSerializer: import_query_string.default.stringify
@@ -173,9 +193,27 @@ var AccelByteSDK = class _AccelByteSDK {
173
193
  }
174
194
  }
175
195
  };
176
- this.axiosInstance = Network.create({ baseURL: coreConfig.baseURL, ...this.axiosConfig.request });
196
+ this.axiosInstance = this.createAxiosInstance();
177
197
  this.token = {};
178
198
  }
199
+ createAxiosInstance() {
200
+ const axiosInstance = Network.create({ baseURL: this.coreConfig.baseURL, ...this.axiosConfig.request });
201
+ const interceptors = this.axiosConfig.interceptors;
202
+ if (interceptors) {
203
+ for (const interceptor of interceptors) {
204
+ if (interceptor.type === "request") {
205
+ axiosInstance.interceptors.request.use(interceptor == null ? void 0 : interceptor.onRequest, interceptor.onError);
206
+ }
207
+ if (interceptor.type === "response") {
208
+ axiosInstance.interceptors.response.use(interceptor == null ? void 0 : interceptor.onSuccess, interceptor.onError);
209
+ }
210
+ }
211
+ }
212
+ return axiosInstance;
213
+ }
214
+ /**
215
+ * Assembles and returns the current Axios instance along with core and Axios configurations.
216
+ */
179
217
  assembly() {
180
218
  return {
181
219
  axiosInstance: this.axiosInstance,
@@ -183,6 +221,12 @@ var AccelByteSDK = class _AccelByteSDK {
183
221
  axiosConfig: this.axiosConfig
184
222
  };
185
223
  }
224
+ /**
225
+ * Creates a new instance of AccelByteSDK with a shallow copy of the current configurations.
226
+ * Optionally allows excluding interceptors.
227
+ * @param {boolean} [opts.interceptors] - Whether to include interceptors in the clone. Default is true.
228
+ * @returns {AccelByteSDK} A new instance of AccelByteSDK with the cloned configuration.
229
+ */
186
230
  clone(opts) {
187
231
  const newConfigs = {
188
232
  coreConfig: { ...this.coreConfig },
@@ -193,6 +237,9 @@ var AccelByteSDK = class _AccelByteSDK {
193
237
  }
194
238
  return new _AccelByteSDK(newConfigs);
195
239
  }
240
+ /**
241
+ * Adds interceptors to the current Axios configuration.
242
+ */
196
243
  addInterceptors(interceptors) {
197
244
  if (!this.axiosConfig.interceptors) {
198
245
  this.axiosConfig.interceptors = [];
@@ -205,11 +252,18 @@ var AccelByteSDK = class _AccelByteSDK {
205
252
  if (!((_a = this.axiosConfig) == null ? void 0 : _a.interceptors)) return this;
206
253
  if (!filterCallback) {
207
254
  this.axiosConfig.interceptors = void 0;
255
+ this.axiosInstance.interceptors.request.clear();
256
+ this.axiosInstance.interceptors.response.clear();
208
257
  return this;
209
258
  }
210
259
  this.axiosConfig.interceptors = this.axiosConfig.interceptors.filter(filterCallback);
260
+ this.axiosInstance = this.createAxiosInstance();
211
261
  return this;
212
262
  }
263
+ /**
264
+ * Updates the SDK's core and Axios configurations.
265
+ * Merges the provided configurations with the current ones.
266
+ */
213
267
  setConfig({ coreConfig, axiosConfig }) {
214
268
  this.coreConfig = {
215
269
  ...this.coreConfig,
@@ -217,19 +271,36 @@ var AccelByteSDK = class _AccelByteSDK {
217
271
  };
218
272
  this.axiosConfig = {
219
273
  ...this.axiosConfig,
220
- ...axiosConfig
274
+ ...axiosConfig == null ? void 0 : axiosConfig.interceptors,
275
+ request: ApiUtils.mergeAxiosConfigs(this.axiosConfig.request, axiosConfig == null ? void 0 : axiosConfig.request)
221
276
  };
277
+ this.axiosInstance = this.createAxiosInstance();
222
278
  return this;
223
279
  }
280
+ /**
281
+ * Set accessToken and refreshToken and updates the Axios request headers to use Bearer authentication.
282
+ */
224
283
  setToken(token) {
225
284
  this.token = {
226
285
  ...this.token,
227
286
  ...token
228
287
  };
288
+ const configOverride = { headers: { Authorization: this.token.accessToken ? `Bearer ${this.token.accessToken}` : "" } };
289
+ this.axiosConfig = {
290
+ ...this.axiosConfig,
291
+ request: ApiUtils.mergeAxiosConfigs(this.axiosInstance.defaults, configOverride)
292
+ };
293
+ this.axiosInstance = this.createAxiosInstance();
229
294
  }
295
+ /**
296
+ * Removes the currently set token.
297
+ */
230
298
  removeToken() {
231
299
  this.token = {};
232
300
  }
301
+ /**
302
+ * Retrieves the current token configuration.
303
+ */
233
304
  getToken() {
234
305
  return this.token;
235
306
  }
@@ -262,7 +333,7 @@ var ERROR_CODE_TOKEN_EXPIRED = 10196;
262
333
  var ERROR_USER_BANNED = 10134;
263
334
 
264
335
  // src/interceptors/AuthInterceptors.ts
265
- var import_axios2 = __toESM(require("axios"), 1);
336
+ var import_axios3 = __toESM(require("axios"), 1);
266
337
 
267
338
  // src/utils/DesktopChecker.ts
268
339
  var _DesktopChecker = class _DesktopChecker {
@@ -506,69 +577,83 @@ var LoginUrls = /* @__PURE__ */ ((LoginUrls2) => {
506
577
  LoginUrls2["REVOKE"] = "/iam/v3/oauth/revoke";
507
578
  return LoginUrls2;
508
579
  })(LoginUrls || {});
509
- var refreshSession = ({ axiosConfig, refreshToken, clientId, tokenUrl }) => {
510
- const config = {
511
- ...axiosConfig,
512
- withCredentials: false,
513
- headers: {
514
- "Content-Type": "application/x-www-form-urlencoded",
515
- Authorization: `Basic ${Buffer.from(`${clientId}:`).toString("base64")}`
516
- }
517
- };
518
- const axios4 = Network.create(config);
519
- const payload = {
520
- refresh_token: refreshToken || void 0,
521
- client_id: clientId,
522
- grant_type: "refresh_token"
523
- };
524
- if (tokenUrl === "/iam/v4/oauth/token" /* GRANT_TOKEN_V4 */) {
525
- return new OAuth20V4$(axios4).postOauthToken_v4(payload);
526
- }
527
- const oauth20 = new OAuth20$(axios4);
528
- return oauth20.postOauthToken(payload);
529
- };
530
- var refreshWithLock = ({
531
- axiosConfig,
532
- refreshToken,
533
- clientId,
534
- tokenUrl
535
- }) => {
536
- if (RefreshSession.isLocked()) {
537
- return Promise.resolve().then(async () => {
538
- while (RefreshSession.isLocked()) {
539
- await RefreshSession.sleepAsync(REFRESH_EXPIRY_CHECK_RATE);
580
+ var noOp = () => {
581
+ };
582
+ var RefreshToken = class {
583
+ constructor({ config, interceptors }) {
584
+ // Return Promise<true> if refresh in any tab is successful;
585
+ this.runWithLock = () => {
586
+ if (RefreshSession.isLocked()) {
587
+ return Promise.resolve().then(async () => {
588
+ while (RefreshSession.isLocked()) {
589
+ await RefreshSession.sleepAsync(REFRESH_EXPIRY_CHECK_RATE);
590
+ }
591
+ return {};
592
+ });
540
593
  }
541
- return {};
542
- });
543
- }
544
- RefreshSession.lock(REFRESH_EXPIRY);
545
- let isLocallyRefreshingToken = true;
546
- (async () => {
547
- while (isLocallyRefreshingToken) {
548
594
  RefreshSession.lock(REFRESH_EXPIRY);
549
- await RefreshSession.sleepAsync(REFRESH_EXPIRY_UPDATE_RATE);
550
- }
551
- })();
552
- return Promise.resolve().then(doRefreshSession({ axiosConfig, clientId, refreshToken, tokenUrl })).finally(() => {
553
- isLocallyRefreshingToken = false;
554
- RefreshSession.unlock();
555
- });
556
- };
557
- var doRefreshSession = ({ axiosConfig, clientId, refreshToken, tokenUrl }) => async () => {
558
- if (DesktopChecker.isDesktopApp() && !axiosConfig.withCredentials && !refreshToken) {
559
- return false;
560
- }
561
- const result = await refreshSession({ axiosConfig, clientId, refreshToken, tokenUrl });
562
- if (result.error) {
563
- return false;
595
+ let isLocallyRefreshingToken = true;
596
+ (async () => {
597
+ while (isLocallyRefreshingToken) {
598
+ RefreshSession.lock(REFRESH_EXPIRY);
599
+ await RefreshSession.sleepAsync(REFRESH_EXPIRY_UPDATE_RATE);
600
+ }
601
+ })();
602
+ return Promise.resolve().then(() => this.run()).finally(() => {
603
+ isLocallyRefreshingToken = false;
604
+ RefreshSession.unlock();
605
+ });
606
+ };
607
+ this.run = async () => {
608
+ const { axiosConfig, refreshToken } = this.config;
609
+ if (DesktopChecker.isDesktopApp() && !axiosConfig.withCredentials && !refreshToken) {
610
+ return false;
611
+ }
612
+ const result = await this.refreshToken();
613
+ if (result.error) {
614
+ return false;
615
+ }
616
+ return result.response.data;
617
+ };
618
+ this.refreshToken = () => {
619
+ const { axiosConfig, refreshToken, clientId, tokenUrl } = this.config;
620
+ const config = {
621
+ ...axiosConfig,
622
+ withCredentials: false,
623
+ headers: {
624
+ "Content-Type": "application/x-www-form-urlencoded",
625
+ Authorization: `Basic ${Buffer.from(`${clientId}:`).toString("base64")}`
626
+ }
627
+ };
628
+ const axios4 = Network.create(config);
629
+ for (const interceptor of this.interceptors) {
630
+ if (interceptor.type === "request") {
631
+ axios4.interceptors.request.use(interceptor == null ? void 0 : interceptor.onRequest, interceptor.onError);
632
+ }
633
+ if (interceptor.type === "response") {
634
+ axios4.interceptors.response.use(interceptor == null ? void 0 : interceptor.onSuccess, interceptor.onError);
635
+ }
636
+ }
637
+ const payload = {
638
+ refresh_token: refreshToken || void 0,
639
+ client_id: clientId,
640
+ grant_type: "refresh_token"
641
+ };
642
+ if (tokenUrl === "/iam/v4/oauth/token" /* GRANT_TOKEN_V4 */) {
643
+ return new OAuth20V4$(axios4).postOauthToken_v4(payload);
644
+ }
645
+ const oauth20 = new OAuth20$(axios4);
646
+ return oauth20.postOauthToken(payload);
647
+ };
648
+ this.config = config;
649
+ this.interceptors = interceptors || [];
564
650
  }
565
- return result.response.data;
566
651
  };
567
- var uponRefreshComplete = (error, tokenResponse, onSessionExpired, axiosConfig, errorConfig) => {
652
+ var refreshComplete = (error, tokenResponse, onSessionExpired, axiosConfig, errorConfig) => {
568
653
  if (tokenResponse) {
569
654
  const { access_token } = tokenResponse;
570
655
  if (!axiosConfig.withCredentials && access_token) {
571
- return (0, import_axios2.default)({
656
+ return (0, import_axios3.default)({
572
657
  ...errorConfig,
573
658
  headers: {
574
659
  ...errorConfig.headers,
@@ -576,7 +661,7 @@ var uponRefreshComplete = (error, tokenResponse, onSessionExpired, axiosConfig,
576
661
  }
577
662
  });
578
663
  } else {
579
- return (0, import_axios2.default)(errorConfig);
664
+ return (0, import_axios3.default)(errorConfig);
580
665
  }
581
666
  }
582
667
  if (onSessionExpired) {
@@ -584,6 +669,49 @@ var uponRefreshComplete = (error, tokenResponse, onSessionExpired, axiosConfig,
584
669
  }
585
670
  throw error;
586
671
  };
672
+ var createAuthInterceptor = ({
673
+ clientId,
674
+ onSessionExpired,
675
+ onGetUserSession,
676
+ expectedErrorUrls = Object.values({ ...LoginUrls, ...GrantTokenUrls }),
677
+ getRefreshToken,
678
+ tokenUrl = "/iam/v3/oauth/token" /* GRANT_TOKEN */
679
+ }) => {
680
+ return {
681
+ type: "response",
682
+ name: "session-expired",
683
+ onError: (e) => {
684
+ const error = e;
685
+ const { config, response } = error;
686
+ if (import_axios3.default.isCancel(error)) {
687
+ return Promise.reject(error);
688
+ }
689
+ if (!response) {
690
+ console.warn(`sdk:ERR_INTERNET_DISCONNECTED ${config == null ? void 0 : config.baseURL}${config == null ? void 0 : config.url}. ${error.message}
691
+ `);
692
+ }
693
+ if ((response == null ? void 0 : response.status) === 401) {
694
+ const { url } = config || {};
695
+ const axiosConfig = config;
696
+ const refreshToken = getRefreshToken();
697
+ if (!url || url && expectedErrorUrls.includes(url)) {
698
+ return Promise.reject(error);
699
+ }
700
+ const refresh = new RefreshToken({
701
+ config: { axiosConfig, clientId, refreshToken, tokenUrl },
702
+ interceptors: [
703
+ createRefreshSessionInterceptor({ tokenUrl }),
704
+ createGetSessionInterceptor({ onGetUserSession: onGetUserSession || noOp, tokenUrl })
705
+ ]
706
+ });
707
+ return refresh.runWithLock().then((tokenResponse) => {
708
+ return refreshComplete(error, tokenResponse, onSessionExpired, axiosConfig, config || {});
709
+ });
710
+ }
711
+ return Promise.reject(error);
712
+ }
713
+ };
714
+ };
587
715
  var createRefreshSessionInterceptor = (options) => {
588
716
  const { tokenUrl = "/iam/v3/oauth/token" /* GRANT_TOKEN */ } = options || {};
589
717
  return {
@@ -617,41 +745,6 @@ var createGetSessionInterceptor = ({
617
745
  return response;
618
746
  }
619
747
  });
620
- var createSessionExpiredInterceptor = ({
621
- clientId,
622
- onSessionExpired,
623
- expectedErrorUrls = Object.values({ ...LoginUrls, ...GrantTokenUrls }),
624
- getRefreshToken,
625
- tokenUrl = "/iam/v3/oauth/token" /* GRANT_TOKEN */
626
- }) => {
627
- return {
628
- type: "response",
629
- name: "session-expired",
630
- onError: (e) => {
631
- const error = e;
632
- const { config, response } = error;
633
- if (import_axios2.default.isCancel(error)) {
634
- return Promise.reject(error);
635
- }
636
- if (!response) {
637
- console.warn(`sdk:ERR_INTERNET_DISCONNECTED ${config == null ? void 0 : config.baseURL}${config == null ? void 0 : config.url}. ${error.message}
638
- `);
639
- }
640
- if ((response == null ? void 0 : response.status) === 401) {
641
- const { url } = config || {};
642
- const axiosConfig = config;
643
- const refreshToken = getRefreshToken();
644
- if (!url || url && expectedErrorUrls.includes(url)) {
645
- return Promise.reject(error);
646
- }
647
- return refreshWithLock({ axiosConfig, clientId, refreshToken, tokenUrl }).then((tokenResponse) => {
648
- return uponRefreshComplete(error, tokenResponse, onSessionExpired, axiosConfig, config || {});
649
- });
650
- }
651
- return Promise.reject(error);
652
- }
653
- };
654
- };
655
748
 
656
749
  // src/constants/paths.ts
657
750
  var INTERNAL_SERVICES = {
@@ -747,27 +840,6 @@ var ErrorInterceptors = [
747
840
  }
748
841
  ];
749
842
 
750
- // src/utils/ApiUtils.ts
751
- var import_axios3 = __toESM(require("axios"), 1);
752
- var ApiUtils = class {
753
- };
754
- ApiUtils.mergeAxiosConfigs = (config, overrides) => {
755
- return {
756
- ...config,
757
- ...overrides,
758
- headers: {
759
- ...config == null ? void 0 : config.headers,
760
- ...overrides == null ? void 0 : overrides.headers
761
- }
762
- };
763
- };
764
- ApiUtils.is4xxError = (error) => {
765
- if (import_axios3.default.isAxiosError(error) && error.response) {
766
- return error.response.status >= 400 && error.response.status <= 499;
767
- }
768
- return false;
769
- };
770
-
771
843
  // src/utils/Type.ts
772
844
  function isType(schema, data) {
773
845
  return schema.safeParse(data).success;
@@ -839,15 +911,14 @@ var UrlHelper = _UrlHelper;
839
911
  IamErrorCode,
840
912
  Network,
841
913
  RefreshSession,
914
+ RefreshToken,
842
915
  SdkDevice,
843
916
  UrlHelper,
844
917
  Validate,
918
+ createAuthInterceptor,
845
919
  createCustomPathInterceptor,
846
920
  createGetSessionInterceptor,
847
921
  createRefreshSessionInterceptor,
848
- createSessionExpiredInterceptor,
849
- doRefreshSession,
850
- isType,
851
- refreshWithLock
922
+ isType
852
923
  });
853
924
  //# sourceMappingURL=index.cjs.map