@arex95/vue-core 1.1.37 → 1.1.39

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.
@@ -10,12 +10,13 @@ export declare class AxiosService {
10
10
  private cancelTokenSource;
11
11
  private activeRequests;
12
12
  private readonly refreshTokenUrl;
13
- private readonly refreshAuth;
13
+ private readonly auth;
14
14
  private isRefreshing;
15
15
  private failedQueue;
16
- constructor(options: AxiosServiceOptions, refreshAuth: () => Promise<void>);
16
+ constructor(options: AxiosServiceOptions);
17
17
  private processQueue;
18
18
  private setAuthHeader;
19
+ private getLatestAuthToken;
19
20
  private initializeInterceptors;
20
21
  getActiveRequests(): number;
21
22
  getAxiosInstance(): AxiosInstance;
@@ -1,12 +1,41 @@
1
1
  import { AxiosInstance } from "axios";
2
+ /**
3
+ * Configuration object for the Axios instance.
4
+ */
2
5
  interface AxiosConfig {
3
6
  baseURL: string;
4
7
  }
8
+ /**
9
+ * Configuration object for a custom Axios instance.
10
+ */
5
11
  interface CustomAxiosConfig {
6
12
  baseURL: string;
7
13
  headers?: Record<string, string>;
8
14
  }
15
+ /**
16
+ * Configures the global Axios instance with a base URL.
17
+ *
18
+ * @param {AxiosConfig} config - An object containing the base URL for the Axios instance.
19
+ * @param {string} config.baseURL - The base URL for the Axios instance.
20
+ *
21
+ * @returns {void}
22
+ */
9
23
  export declare const configAxios: (config: AxiosConfig) => void;
24
+ /**
25
+ * Retrieves the configured Axios instance.
26
+ *
27
+ * @returns {AxiosService} The configured Axios instance.
28
+ * @throws Will throw an error if the Axios instance is not configured.
29
+ */
10
30
  export declare const getAxiosInstance: () => AxiosInstance;
31
+ /**
32
+ * Creates a new AxiosService instance with custom headers.
33
+ *
34
+ * @param {CustomAxiosConfig} config - An object containing the base URL and optional custom headers.
35
+ * @param {string} config.baseURL - The base URL for the Axios instance.
36
+ * @param {Record<string, string>} [config.headers] - Custom headers to set (optional).
37
+ *
38
+ * @returns {AxiosService} The new AxiosService instance.
39
+ */
11
40
  export declare const createCustomAxiosInstance: (config: CustomAxiosConfig) => AxiosInstance;
12
41
  export {};
package/dist/index.mjs CHANGED
@@ -993,131 +993,47 @@ const verifyAuth = async () => {
993
993
  }
994
994
  };
995
995
 
996
- class AxiosService {
997
- instance;
998
- cancelTokenSource;
999
- activeRequests = 0;
1000
- refreshTokenUrl;
1001
- refreshAuth;
1002
- isRefreshing = false;
1003
- failedQueue = [];
1004
- constructor(options, refreshAuth) {
1005
- this.cancelTokenSource = axios.CancelToken.source();
1006
- this.refreshAuth = refreshAuth;
1007
- const endpointsConfig = getEndpointsConfig();
1008
- this.refreshTokenUrl = endpointsConfig.REFRESH;
1009
- this.instance = axios.create({
1010
- baseURL: options.baseURL ?? "",
1011
- timeout: options.timeout ?? 30000,
1012
- headers: {
1013
- Accept: "application/json",
1014
- "Content-Type": "application/json",
1015
- ...options.headers,
1016
- },
1017
- withCredentials: options.withCredentials ?? false,
1018
- });
1019
- this.initializeInterceptors();
1020
- }
1021
- processQueue(error, token = null) {
1022
- this.failedQueue.forEach((prom) => {
1023
- if (error) {
1024
- prom.reject(error);
1025
- }
1026
- else if (token) {
1027
- prom.resolve(token);
1028
- }
1029
- });
1030
- this.failedQueue = [];
1031
- }
1032
- setAuthHeader(config, token) {
1033
- if (config.headers) {
1034
- config.headers.Authorization = `Bearer ${token}`;
1035
- }
1036
- }
1037
- initializeInterceptors() {
1038
- this.instance.interceptors.request.use(async (config) => {
1039
- const token = await getAuthToken(getAppKey(), "any");
1040
- if (token) {
1041
- this.setAuthHeader(config, token);
1042
- }
1043
- config.cancelToken = this.cancelTokenSource.token;
1044
- this.activeRequests++;
1045
- return config;
1046
- }, (error) => {
1047
- handleError(error, false);
1048
- return Promise.reject(error);
1049
- });
1050
- this.instance.interceptors.response.use((response) => {
1051
- this.activeRequests--;
1052
- return response;
1053
- }, async (error) => {
1054
- this.activeRequests--;
1055
- const originalRequest = error.config;
1056
- const isAuthError = axios.isAxiosError(error) && error.response?.status === 401;
1057
- const isRefreshCall = originalRequest?.url === this.refreshTokenUrl;
1058
- const isRetry = originalRequest?._retry === true;
1059
- if (!isAuthError || isRefreshCall || isRetry) {
1060
- handleError(error, false);
1061
- return Promise.reject(error);
1062
- }
1063
- if (!originalRequest) {
1064
- handleError(error, false);
1065
- return Promise.reject(error);
1066
- }
1067
- if (this.isRefreshing) {
1068
- return new Promise((resolve, reject) => {
1069
- this.failedQueue.push({ resolve, reject });
1070
- })
1071
- .then((newToken) => {
1072
- this.setAuthHeader(originalRequest, newToken);
1073
- return this.instance(originalRequest);
1074
- })
1075
- .catch((err) => {
1076
- return Promise.reject(err);
1077
- });
1078
- }
1079
- this.isRefreshing = true;
1080
- originalRequest._retry = true;
1081
- try {
1082
- await this.refreshAuth();
1083
- const newToken = await getAuthToken(getAppKey(), "any");
1084
- if (newToken) {
1085
- this.processQueue(null, newToken);
1086
- this.setAuthHeader(originalRequest, newToken);
1087
- }
1088
- else {
1089
- const refreshError = new Error("New token not found after refresh.");
1090
- this.processQueue(refreshError, null);
1091
- throw refreshError;
1092
- }
1093
- this.isRefreshing = false;
1094
- return this.instance(originalRequest);
1095
- }
1096
- catch (refreshError) {
1097
- this.processQueue(refreshError, null);
1098
- this.isRefreshing = false;
1099
- handleError(refreshError, false);
1100
- return Promise.reject(error);
1101
- }
1102
- });
1103
- }
1104
- getActiveRequests() {
1105
- return this.activeRequests;
1106
- }
1107
- getAxiosInstance() {
1108
- return this.instance;
1109
- }
1110
- cancelAllRequests() {
1111
- this.cancelTokenSource.cancel("Operation canceled by the user.");
1112
- this.cancelTokenSource = axios.CancelToken.source();
1113
- }
1114
- setHeader(key, value) {
1115
- this.instance.defaults.headers.common[key] = value;
1116
- }
1117
- removeHeader(key) {
1118
- delete this.instance.defaults.headers.common[key];
996
+ let axiosInstance;
997
+ /**
998
+ * Configures the global Axios instance with a base URL.
999
+ *
1000
+ * @param {AxiosConfig} config - An object containing the base URL for the Axios instance.
1001
+ * @param {string} config.baseURL - The base URL for the Axios instance.
1002
+ *
1003
+ * @returns {void}
1004
+ */
1005
+ const configAxios = (config) => {
1006
+ axiosInstance = new AxiosService({
1007
+ baseURL: config.baseURL,
1008
+ });
1009
+ };
1010
+ /**
1011
+ * Retrieves the configured Axios instance.
1012
+ *
1013
+ * @returns {AxiosService} The configured Axios instance.
1014
+ * @throws Will throw an error if the Axios instance is not configured.
1015
+ */
1016
+ const getAxiosInstance = () => {
1017
+ if (!axiosInstance) {
1018
+ throw new Error("Axios instance not configured. Call configAxios first.");
1119
1019
  }
1120
- }
1020
+ return axiosInstance.getAxiosInstance();
1021
+ };
1022
+ /**
1023
+ * Creates a new AxiosService instance with custom headers.
1024
+ *
1025
+ * @param {CustomAxiosConfig} config - An object containing the base URL and optional custom headers.
1026
+ * @param {string} config.baseURL - The base URL for the Axios instance.
1027
+ * @param {Record<string, string>} [config.headers] - Custom headers to set (optional).
1028
+ *
1029
+ * @returns {AxiosService} The new AxiosService instance.
1030
+ */
1031
+ const createCustomAxiosInstance = (config) => {
1032
+ return new AxiosService({
1033
+ baseURL: config.baseURL,
1034
+ headers: config.headers,
1035
+ }).getAxiosInstance();
1036
+ };
1121
1037
 
1122
1038
  /**
1123
1039
  * Converts a Proxy object to a plain object.
@@ -1531,28 +1447,133 @@ function useAuth(secretKey = getAppKey()) {
1531
1447
  };
1532
1448
  }
1533
1449
 
1534
- let axiosInstance;
1535
- const auth = useAuth();
1536
- const refreshAndForget = async () => {
1537
- await auth.refresh();
1538
- };
1539
- const configAxios = (config) => {
1540
- axiosInstance = new AxiosService({
1541
- baseURL: config.baseURL,
1542
- }, refreshAndForget);
1543
- };
1544
- const getAxiosInstance = () => {
1545
- if (!axiosInstance) {
1546
- throw new Error("Axios instance not configured. Call configAxios first.");
1450
+ class AxiosService {
1451
+ instance;
1452
+ cancelTokenSource;
1453
+ activeRequests = 0;
1454
+ refreshTokenUrl;
1455
+ auth = useAuth();
1456
+ isRefreshing = false;
1457
+ failedQueue = [];
1458
+ constructor(options) {
1459
+ this.cancelTokenSource = axios.CancelToken.source();
1460
+ const endpointsConfig = getEndpointsConfig();
1461
+ this.refreshTokenUrl = endpointsConfig.REFRESH;
1462
+ this.instance = axios.create({
1463
+ baseURL: options.baseURL ?? "",
1464
+ timeout: options.timeout ?? 30000,
1465
+ headers: {
1466
+ Accept: "application/json",
1467
+ "Content-Type": "application/json",
1468
+ ...options.headers,
1469
+ },
1470
+ withCredentials: options.withCredentials ?? false,
1471
+ });
1472
+ this.initializeInterceptors();
1547
1473
  }
1548
- return axiosInstance.getAxiosInstance();
1549
- };
1550
- const createCustomAxiosInstance = (config) => {
1551
- return new AxiosService({
1552
- baseURL: config.baseURL,
1553
- headers: config.headers,
1554
- }, refreshAndForget).getAxiosInstance();
1555
- };
1474
+ processQueue(error, token = null) {
1475
+ this.failedQueue.forEach((prom) => {
1476
+ if (error) {
1477
+ prom.reject(error);
1478
+ }
1479
+ else if (token) {
1480
+ prom.resolve(token);
1481
+ }
1482
+ });
1483
+ this.failedQueue = [];
1484
+ }
1485
+ setAuthHeader(config, token) {
1486
+ if (config.headers) {
1487
+ config.headers.Authorization = `Bearer ${token}`;
1488
+ }
1489
+ }
1490
+ async getLatestAuthToken() {
1491
+ return await getAuthToken(getAppKey(), "any");
1492
+ }
1493
+ initializeInterceptors() {
1494
+ this.instance.interceptors.request.use(async (config) => {
1495
+ const token = await this.getLatestAuthToken();
1496
+ if (token) {
1497
+ this.setAuthHeader(config, token);
1498
+ }
1499
+ config.cancelToken = this.cancelTokenSource.token;
1500
+ this.activeRequests++;
1501
+ return config;
1502
+ }, (error) => {
1503
+ handleError(error, false);
1504
+ return Promise.reject(error);
1505
+ });
1506
+ this.instance.interceptors.response.use((response) => {
1507
+ this.activeRequests--;
1508
+ return response;
1509
+ }, async (error) => {
1510
+ this.activeRequests--;
1511
+ const originalRequest = error.config;
1512
+ const isAuthError = axios.isAxiosError(error) && error.response?.status === 401;
1513
+ const isRefreshCall = originalRequest?.url === this.refreshTokenUrl;
1514
+ const isRetry = originalRequest?._retry === true;
1515
+ if (!isAuthError || isRefreshCall || isRetry) {
1516
+ handleError(error, false);
1517
+ return Promise.reject(error);
1518
+ }
1519
+ if (!originalRequest) {
1520
+ handleError(error, false);
1521
+ return Promise.reject(error);
1522
+ }
1523
+ if (this.isRefreshing) {
1524
+ return new Promise((resolve, reject) => {
1525
+ this.failedQueue.push({ resolve, reject });
1526
+ })
1527
+ .then((newToken) => {
1528
+ this.setAuthHeader(originalRequest, newToken);
1529
+ return this.instance(originalRequest);
1530
+ })
1531
+ .catch((err) => {
1532
+ return Promise.reject(err);
1533
+ });
1534
+ }
1535
+ this.isRefreshing = true;
1536
+ originalRequest._retry = true;
1537
+ try {
1538
+ await this.auth.refresh();
1539
+ const newToken = await this.getLatestAuthToken();
1540
+ if (newToken) {
1541
+ this.processQueue(null, newToken);
1542
+ this.setAuthHeader(originalRequest, newToken);
1543
+ }
1544
+ else {
1545
+ const refreshError = new Error("New token not found after refresh.");
1546
+ this.processQueue(refreshError, null);
1547
+ throw refreshError;
1548
+ }
1549
+ this.isRefreshing = false;
1550
+ return this.instance(originalRequest);
1551
+ }
1552
+ catch (refreshError) {
1553
+ this.processQueue(refreshError, null);
1554
+ this.isRefreshing = false;
1555
+ handleError(refreshError, false);
1556
+ return Promise.reject(error);
1557
+ }
1558
+ });
1559
+ }
1560
+ getActiveRequests() {
1561
+ return this.activeRequests;
1562
+ }
1563
+ getAxiosInstance() {
1564
+ return this.instance;
1565
+ }
1566
+ cancelAllRequests() {
1567
+ this.cancelTokenSource.cancel("Operation canceled by the user.");
1568
+ this.cancelTokenSource = axios.CancelToken.source();
1569
+ }
1570
+ setHeader(key, value) {
1571
+ this.instance.defaults.headers.common[key] = value;
1572
+ }
1573
+ removeHeader(key) {
1574
+ delete this.instance.defaults.headers.common[key];
1575
+ }
1576
+ }
1556
1577
 
1557
1578
  /**
1558
1579
  * Creates and downloads a file from Blob data.
@@ -3510,14 +3531,14 @@ const ArexVueCore = {
3510
3531
  accessTokenKey: options.tokenKeys.accessToken,
3511
3532
  refreshTokenKey: options.tokenKeys.refreshToken
3512
3533
  });
3513
- configAxios({
3514
- baseURL: options.apiUrl,
3515
- });
3516
3534
  configEndpoints({
3517
3535
  loginEndpoint: options.endpoints.login,
3518
3536
  refreshEndpoint: options.endpoints.refresh,
3519
3537
  logoutEndpoint: options.endpoints.logout,
3520
3538
  });
3539
+ configAxios({
3540
+ baseURL: options.apiUrl,
3541
+ });
3521
3542
  },
3522
3543
  };
3523
3544
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arex95/vue-core",
3
- "version": "1.1.37",
3
+ "version": "1.1.39",
4
4
  "description": "Opinionated Vue Core",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",