@fctc/interface-logic 1.7.4 → 1.7.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/provider.mjs CHANGED
@@ -43,25 +43,11 @@ var breadcrums_slice_default = breadcrumbsSlice.reducer;
43
43
  import { createSlice as createSlice2 } from "@reduxjs/toolkit";
44
44
  var initialState2 = {
45
45
  baseUrl: "",
46
+ requests: null,
46
47
  companies: [],
47
48
  user: {},
48
- db: "",
49
- refreshTokenEndpoint: "",
50
- config: {
51
- grantType: "",
52
- clientId: "",
53
- clientSecret: "",
54
- redirectUri: ""
55
- },
49
+ config: null,
56
50
  envFile: null,
57
- requests: {
58
- get: async (url, headers) => ({}),
59
- post: async (url, body, headers) => ({}),
60
- post_excel: async (url, body, headers) => ({}),
61
- put: async (url, body, headers) => ({}),
62
- patch: async (url, body) => ({}),
63
- delete: async (url, body) => ({})
64
- },
65
51
  defaultCompany: {
66
52
  id: null,
67
53
  logo: "",
@@ -2777,11 +2763,333 @@ function matchDomain(record, domain) {
2777
2763
 
2778
2764
  // src/utils/function.ts
2779
2765
  import { useEffect, useState } from "react";
2766
+ var updateTokenParamInOriginalRequest = (originalRequest, newAccessToken) => {
2767
+ if (!originalRequest.data) return originalRequest.data;
2768
+ if (typeof originalRequest.data === "string") {
2769
+ try {
2770
+ const parsedData = JSON.parse(originalRequest.data);
2771
+ if (parsedData.with_context && typeof parsedData.with_context === "object") {
2772
+ parsedData.with_context.token = newAccessToken;
2773
+ }
2774
+ return JSON.stringify(parsedData);
2775
+ } catch (e) {
2776
+ console.warn("Failed to parse originalRequest.data", e);
2777
+ return originalRequest.data;
2778
+ }
2779
+ }
2780
+ if (typeof originalRequest.data === "object" && originalRequest.data.with_context) {
2781
+ originalRequest.data.with_context.token = newAccessToken;
2782
+ }
2783
+ return originalRequest.data;
2784
+ };
2785
+
2786
+ // src/utils/storage/local-storage.ts
2787
+ var localStorageUtils = () => {
2788
+ const setToken = async (access_token) => {
2789
+ localStorage.setItem("accessToken", access_token);
2790
+ };
2791
+ const setRefreshToken = async (refresh_token) => {
2792
+ localStorage.setItem("refreshToken", refresh_token);
2793
+ };
2794
+ const getAccessToken = async () => {
2795
+ return localStorage.getItem("accessToken");
2796
+ };
2797
+ const getRefreshToken = async () => {
2798
+ return localStorage.getItem("refreshToken");
2799
+ };
2800
+ const clearToken = async () => {
2801
+ localStorage.removeItem("accessToken");
2802
+ localStorage.removeItem("refreshToken");
2803
+ };
2804
+ return {
2805
+ setToken,
2806
+ setRefreshToken,
2807
+ getAccessToken,
2808
+ getRefreshToken,
2809
+ clearToken
2810
+ };
2811
+ };
2812
+
2813
+ // src/utils/storage/session-storage.ts
2814
+ var sessionStorageUtils = () => {
2815
+ const getBrowserSession = async () => {
2816
+ return sessionStorage.getItem("browserSession");
2817
+ };
2818
+ return {
2819
+ getBrowserSession
2820
+ };
2821
+ };
2822
+
2823
+ // src/configs/axios-client.ts
2824
+ var axiosClient = {
2825
+ init(config) {
2826
+ const localStorage2 = config.localStorageUtils ?? localStorageUtils();
2827
+ const sessionStorage2 = config.sessionStorageUtils ?? sessionStorageUtils();
2828
+ const db = config.db;
2829
+ let isRefreshing = false;
2830
+ let failedQueue = [];
2831
+ const processQueue = (error, token = null) => {
2832
+ failedQueue?.forEach((prom) => {
2833
+ if (error) {
2834
+ prom.reject(error);
2835
+ } else {
2836
+ prom.resolve(token);
2837
+ }
2838
+ });
2839
+ failedQueue = [];
2840
+ };
2841
+ const instance = axios.create({
2842
+ adapter: axios.defaults.adapter,
2843
+ baseURL: config.baseUrl,
2844
+ timeout: 5e4,
2845
+ paramsSerializer: (params) => new URLSearchParams(params).toString()
2846
+ });
2847
+ instance.interceptors.request.use(
2848
+ async (config2) => {
2849
+ const useRefreshToken = config2.useRefreshToken;
2850
+ const token = useRefreshToken ? await localStorage2.getRefreshToken() : await localStorage2.getAccessToken();
2851
+ if (token) {
2852
+ config2.headers["Authorization"] = "Bearer " + token;
2853
+ }
2854
+ return config2;
2855
+ },
2856
+ (error) => {
2857
+ Promise.reject(error);
2858
+ }
2859
+ );
2860
+ instance.interceptors.response.use(
2861
+ (response) => {
2862
+ return handleResponse(response);
2863
+ },
2864
+ async (error) => {
2865
+ const handleError3 = async (error2) => {
2866
+ if (!error2.response) {
2867
+ return error2;
2868
+ }
2869
+ const { data } = error2.response;
2870
+ if (data && data.code === 400 && ["invalid_grant"].includes(data.data?.error)) {
2871
+ await clearAuthToken();
2872
+ }
2873
+ return data;
2874
+ };
2875
+ const originalRequest = error.config;
2876
+ if ((error.response?.status === 403 || error.response?.status === 401 || error.response?.status === 404) && ["TOKEN_EXPIRED", "AUTHEN_FAIL", 401, "ERR_2FA_006"].includes(
2877
+ error.response.data.code
2878
+ )) {
2879
+ if (isRefreshing) {
2880
+ return new Promise(function(resolve, reject) {
2881
+ failedQueue.push({ resolve, reject });
2882
+ }).then((token) => {
2883
+ originalRequest.headers["Authorization"] = "Bearer " + token;
2884
+ originalRequest.data = updateTokenParamInOriginalRequest(
2885
+ originalRequest,
2886
+ token
2887
+ );
2888
+ return instance.request(originalRequest);
2889
+ }).catch(async (err) => {
2890
+ if ((err.response?.status === 400 || err.response?.status === 401) && ["invalid_grant"].includes(err.response.data.error)) {
2891
+ await clearAuthToken();
2892
+ }
2893
+ });
2894
+ }
2895
+ const browserSession = await sessionStorage2.getBrowserSession();
2896
+ const refreshToken = await localStorage2.getRefreshToken();
2897
+ const accessTokenExp = await localStorage2.getAccessToken();
2898
+ isRefreshing = true;
2899
+ if (!refreshToken && (!browserSession || browserSession == "unActive")) {
2900
+ await clearAuthToken();
2901
+ } else {
2902
+ const payload = Object.fromEntries(
2903
+ Object.entries({
2904
+ refresh_token: refreshToken,
2905
+ grant_type: "refresh_token",
2906
+ client_id: config.config.clientId,
2907
+ client_secret: config.config.clientSecret
2908
+ }).filter(([_, value]) => !!value)
2909
+ );
2910
+ return new Promise(function(resolve) {
2911
+ axios.post(
2912
+ `${config.baseUrl}${config.refreshTokenEndpoint ?? "/authentication/oauth2/token" /* AUTH_TOKEN_PATH */}`,
2913
+ payload,
2914
+ {
2915
+ headers: {
2916
+ "Content-Type": config.refreshTokenEndpoint ? "application/x-www-form-urlencoded" : "multipart/form-data",
2917
+ Authorization: `Bearer ${accessTokenExp}`
2918
+ }
2919
+ }
2920
+ ).then(async (res) => {
2921
+ const data = res.data;
2922
+ await localStorage2.setToken(data.access_token);
2923
+ await localStorage2.setRefreshToken(data.refresh_token);
2924
+ axios.defaults.headers.common["Authorization"] = "Bearer " + data.access_token;
2925
+ originalRequest.headers["Authorization"] = "Bearer " + data.access_token;
2926
+ originalRequest.data = updateTokenParamInOriginalRequest(
2927
+ originalRequest,
2928
+ data.access_token
2929
+ );
2930
+ processQueue(null, data.access_token);
2931
+ resolve(instance.request(originalRequest));
2932
+ }).catch(async (err) => {
2933
+ if (err && (err?.error_code === "AUTHEN_FAIL" || err?.error_code === "TOKEN_EXPIRED" || err?.error_code === "TOKEN_INCORRECT" || err?.code === "ERR_BAD_REQUEST") || err?.error_code === "ERR_2FA_006") {
2934
+ await clearAuthToken();
2935
+ }
2936
+ if (err && err.response) {
2937
+ const { error_code } = err.response?.data || {};
2938
+ if (error_code === "AUTHEN_FAIL") {
2939
+ await clearAuthToken();
2940
+ }
2941
+ }
2942
+ processQueue(err, null);
2943
+ }).finally(() => {
2944
+ isRefreshing = false;
2945
+ });
2946
+ });
2947
+ }
2948
+ }
2949
+ return Promise.reject(await handleError3(error));
2950
+ }
2951
+ );
2952
+ const handleResponse = (res) => {
2953
+ if (res && res.data) {
2954
+ return res.data;
2955
+ }
2956
+ return res;
2957
+ };
2958
+ const handleError2 = (error) => {
2959
+ if (error.isAxiosError && error.code === "ECONNABORTED") {
2960
+ console.error("Request Timeout Error:", error);
2961
+ return "Request Timeout Error";
2962
+ } else if (error.isAxiosError && !error.response) {
2963
+ console.error("Network Error:", error);
2964
+ return "Network Error";
2965
+ } else {
2966
+ console.error("Other Error:", error?.response);
2967
+ const errorMessage = error?.response?.data?.message || "An error occurred";
2968
+ return { message: errorMessage, status: error?.response?.status };
2969
+ }
2970
+ };
2971
+ const clearAuthToken = async () => {
2972
+ await localStorage2.clearToken();
2973
+ if (typeof window !== "undefined") {
2974
+ window.location.href = `/login`;
2975
+ }
2976
+ };
2977
+ function formatUrl(url, db2) {
2978
+ return url + (db2 ? "?db=" + db2 : "");
2979
+ }
2980
+ const responseBody = (response) => response;
2981
+ const requests = {
2982
+ get: (url, headers) => instance.get(formatUrl(url, db), headers).then(responseBody),
2983
+ post: (url, body, headers) => instance.post(formatUrl(url, db), body, headers).then(responseBody),
2984
+ post_excel: (url, body, headers) => instance.post(formatUrl(url, db), body, {
2985
+ responseType: "arraybuffer",
2986
+ headers: {
2987
+ "Content-Type": typeof window !== "undefined" ? "application/json" : "application/javascript",
2988
+ Accept: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
2989
+ }
2990
+ }).then(responseBody),
2991
+ put: (url, body, headers) => instance.put(formatUrl(url, db), body, headers).then(responseBody),
2992
+ patch: (url, body) => instance.patch(formatUrl(url, db), body).then(responseBody),
2993
+ delete: (url, body) => instance.delete(formatUrl(url, db), body).then(responseBody)
2994
+ };
2995
+ return requests;
2996
+ }
2997
+ };
2780
2998
 
2781
2999
  // src/environment/EnvStore.ts
3000
+ var EnvStore = class _EnvStore {
3001
+ static instance = null;
3002
+ envStore;
3003
+ baseUrl;
3004
+ requests;
3005
+ context;
3006
+ defaultCompany;
3007
+ config;
3008
+ companies;
3009
+ user;
3010
+ db;
3011
+ localStorageUtils;
3012
+ sessionStorageUtils;
3013
+ refreshTokenEndpoint;
3014
+ constructor(envStore2, localStorageUtils2, sessionStorageUtils2) {
3015
+ this.envStore = envStore2;
3016
+ this.localStorageUtils = localStorageUtils2;
3017
+ this.sessionStorageUtils = sessionStorageUtils2;
3018
+ this.setup();
3019
+ }
3020
+ static getInstance(envStore2, localStorageUtils2, sessionStorageUtils2) {
3021
+ if (!_EnvStore.instance) {
3022
+ console.log("Creating new EnvStore instance");
3023
+ _EnvStore.instance = new _EnvStore(envStore2, localStorageUtils2, sessionStorageUtils2);
3024
+ } else {
3025
+ console.log("Returning existing EnvStore instance");
3026
+ }
3027
+ return _EnvStore.instance;
3028
+ }
3029
+ setup() {
3030
+ const env = this.envStore.getState().env;
3031
+ console.log("Redux env state in A1:", env);
3032
+ this.baseUrl = env?.baseUrl;
3033
+ this.requests = env?.requests;
3034
+ this.context = env?.context;
3035
+ this.defaultCompany = env?.defaultCompany;
3036
+ this.config = env?.config;
3037
+ this.companies = env?.companies || [];
3038
+ this.user = env?.user;
3039
+ this.db = env?.db;
3040
+ this.refreshTokenEndpoint = env?.refreshTokenEndpoint;
3041
+ console.log("Env setup in A1:", this);
3042
+ }
3043
+ setupEnv(envConfig) {
3044
+ const dispatch = this.envStore.dispatch;
3045
+ const env = {
3046
+ ...envConfig,
3047
+ localStorageUtils: this.localStorageUtils,
3048
+ sessionStorageUtils: this.sessionStorageUtils
3049
+ };
3050
+ console.log("Setting up env with config:", envConfig);
3051
+ const requests = axiosClient.init(env);
3052
+ console.log("axiosClient.init result:", requests);
3053
+ dispatch(setEnv({ ...env, requests }));
3054
+ this.setup();
3055
+ }
3056
+ setUid(uid) {
3057
+ const dispatch = this.envStore.dispatch;
3058
+ dispatch(setUid(uid));
3059
+ this.setup();
3060
+ }
3061
+ setLang(lang) {
3062
+ const dispatch = this.envStore.dispatch;
3063
+ dispatch(setLang(lang));
3064
+ this.setup();
3065
+ }
3066
+ setAllowCompanies(allowCompanies) {
3067
+ const dispatch = this.envStore.dispatch;
3068
+ dispatch(setAllowCompanies(allowCompanies));
3069
+ this.setup();
3070
+ }
3071
+ setCompanies(companies) {
3072
+ const dispatch = this.envStore.dispatch;
3073
+ dispatch(setCompanies(companies));
3074
+ this.setup();
3075
+ }
3076
+ setDefaultCompany(company) {
3077
+ const dispatch = this.envStore.dispatch;
3078
+ dispatch(setDefaultCompany(company));
3079
+ this.setup();
3080
+ }
3081
+ setUserInfo(userInfo) {
3082
+ const dispatch = this.envStore.dispatch;
3083
+ dispatch(setUser(userInfo));
3084
+ this.setup();
3085
+ }
3086
+ };
2782
3087
  function getEnv() {
2783
- console.log("getEnv", envStore.getState().env);
2784
- return envStore.getState().env;
3088
+ const instance = EnvStore.getInstance(envStore);
3089
+ if (!instance) {
3090
+ throw new Error("EnvStore has not been initialized \u2014 call initEnv() first");
3091
+ }
3092
+ return instance;
2785
3093
  }
2786
3094
 
2787
3095
  // src/services/view-service/index.ts
@@ -3045,7 +3353,8 @@ var ViewService = {
3045
3353
  },
3046
3354
  async getVersion() {
3047
3355
  const env = getEnv();
3048
- return env?.requests.get("", {
3356
+ console.log("env?.requests", env, env?.requests);
3357
+ return env?.requests?.get("", {
3049
3358
  headers: {
3050
3359
  "Content-Type": "application/json"
3051
3360
  }
@@ -3242,6 +3551,7 @@ var VersionGate = ({ children }) => {
3242
3551
  };
3243
3552
  const validateVersion = async () => {
3244
3553
  const serverVersion = await view_service_default.getVersion();
3554
+ console.log("serverVersion", serverVersion);
3245
3555
  const cached = localStorage.getItem("__api_version__");
3246
3556
  if (cached !== serverVersion?.api_version) {
3247
3557
  clearVersion();
@@ -1,4 +1,4 @@
1
- import { C as ContextApi, L as LoginCredentialBody, R as ResetPasswordRequest, U as UpdatePasswordRequest, b as GetListParams, c as GetDetailParams, d as SaveParams, D as DeleteParams, O as OnChangeParams, V as ViewData, a as GetViewParams, G as GetSelectionType } from './view-type-D8ukwj_2.mjs';
1
+ import { C as ContextApi, L as LoginCredentialBody, R as ResetPasswordRequest, U as UpdatePasswordRequest, b as GetListParams, a as GetDetailParams, S as SaveParams, D as DeleteParams, O as OnChangeParams, V as ViewData, f as GetViewParams, c as GetSelectionType } from './view-type-BGJfDe73.mjs';
2
2
 
3
3
  declare const ActionService: {
4
4
  loadAction({ idAction, context, }: {
@@ -51,7 +51,6 @@ declare const AuthService: {
51
51
  }): Promise<any>;
52
52
  updatePassword(data: UpdatePasswordRequest, token: string | null): Promise<any>;
53
53
  isValidToken(token: string | null): Promise<any>;
54
- isValidActionToken(actionToken: string | null, path: string): Promise<any>;
55
54
  loginSocial({ db, state, access_token, }: {
56
55
  db: string;
57
56
  state: object;
@@ -1,4 +1,4 @@
1
- import { C as ContextApi, L as LoginCredentialBody, R as ResetPasswordRequest, U as UpdatePasswordRequest, b as GetListParams, c as GetDetailParams, d as SaveParams, D as DeleteParams, O as OnChangeParams, V as ViewData, a as GetViewParams, G as GetSelectionType } from './view-type-D8ukwj_2.js';
1
+ import { C as ContextApi, L as LoginCredentialBody, R as ResetPasswordRequest, U as UpdatePasswordRequest, b as GetListParams, a as GetDetailParams, S as SaveParams, D as DeleteParams, O as OnChangeParams, V as ViewData, f as GetViewParams, c as GetSelectionType } from './view-type-BGJfDe73.js';
2
2
 
3
3
  declare const ActionService: {
4
4
  loadAction({ idAction, context, }: {
@@ -51,7 +51,6 @@ declare const AuthService: {
51
51
  }): Promise<any>;
52
52
  updatePassword(data: UpdatePasswordRequest, token: string | null): Promise<any>;
53
53
  isValidToken(token: string | null): Promise<any>;
54
- isValidActionToken(actionToken: string | null, path: string): Promise<any>;
55
54
  loginSocial({ db, state, access_token, }: {
56
55
  db: string;
57
56
  state: object;