@fctc/interface-logic 1.7.5 → 1.7.7
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/configs.d.mts +5 -7
- package/dist/configs.d.ts +5 -7
- package/dist/configs.js +9 -12
- package/dist/configs.mjs +9 -12
- package/dist/environment.d.mts +37 -1
- package/dist/environment.d.ts +37 -1
- package/dist/environment.js +646 -112
- package/dist/environment.mjs +645 -110
- package/dist/hooks.d.mts +7 -2
- package/dist/hooks.d.ts +7 -2
- package/dist/hooks.js +772 -435
- package/dist/hooks.mjs +731 -395
- package/dist/provider.js +18 -326
- package/dist/provider.mjs +18 -326
- package/dist/services.d.mts +2 -1
- package/dist/services.d.ts +2 -1
- package/dist/services.js +646 -325
- package/dist/services.mjs +646 -325
- package/dist/store.d.mts +112 -28
- package/dist/store.d.ts +112 -28
- package/dist/store.js +12 -6
- package/dist/store.mjs +12 -6
- package/dist/types.d.mts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/{view-type-BGJfDe73.d.mts → view-type-D8ukwj_2.d.mts} +1 -1
- package/dist/{view-type-BGJfDe73.d.ts → view-type-D8ukwj_2.d.ts} +1 -1
- package/package.json +81 -81
- package/dist/environment-BtoPepkC.d.mts +0 -72
- package/dist/environment-BtoPepkC.d.ts +0 -72
package/dist/provider.mjs
CHANGED
|
@@ -43,10 +43,16 @@ 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,
|
|
47
46
|
companies: [],
|
|
48
47
|
user: {},
|
|
49
|
-
|
|
48
|
+
db: "",
|
|
49
|
+
refreshTokenEndpoint: "",
|
|
50
|
+
config: {
|
|
51
|
+
grantType: "",
|
|
52
|
+
clientId: "",
|
|
53
|
+
clientSecret: "",
|
|
54
|
+
redirectUri: ""
|
|
55
|
+
},
|
|
50
56
|
envFile: null,
|
|
51
57
|
defaultCompany: {
|
|
52
58
|
id: null,
|
|
@@ -2763,331 +2769,19 @@ function matchDomain(record, domain) {
|
|
|
2763
2769
|
|
|
2764
2770
|
// src/utils/function.ts
|
|
2765
2771
|
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
|
-
};
|
|
2998
2772
|
|
|
2999
2773
|
// src/environment/EnvStore.ts
|
|
3000
|
-
var
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
this.sessionStorageUtils = sessionStorageUtils2;
|
|
3008
|
-
}
|
|
3009
|
-
static getInstance(localStorageUtils2, sessionStorageUtils2) {
|
|
3010
|
-
if (!_EnvStore.instance) {
|
|
3011
|
-
console.log("Creating new EnvStore instance");
|
|
3012
|
-
_EnvStore.instance = new _EnvStore(localStorageUtils2, sessionStorageUtils2);
|
|
3013
|
-
} else {
|
|
3014
|
-
console.log("Returning existing EnvStore instance");
|
|
3015
|
-
}
|
|
3016
|
-
return _EnvStore.instance;
|
|
3017
|
-
}
|
|
3018
|
-
setupEnv(envConfig) {
|
|
3019
|
-
this.state = {
|
|
3020
|
-
...this.state,
|
|
3021
|
-
...envConfig,
|
|
3022
|
-
localStorageUtils: this.localStorageUtils,
|
|
3023
|
-
sessionStorageUtils: this.sessionStorageUtils
|
|
3024
|
-
};
|
|
3025
|
-
console.log("Setting up env with config:", envConfig);
|
|
3026
|
-
this.state.requests = axiosClient.init(this.state);
|
|
3027
|
-
console.log("axiosClient.init result:", this.state.requests);
|
|
3028
|
-
}
|
|
3029
|
-
setUid(uid) {
|
|
3030
|
-
this.state.uid = uid;
|
|
3031
|
-
}
|
|
3032
|
-
setLang(lang) {
|
|
3033
|
-
this.state.lang = lang;
|
|
3034
|
-
}
|
|
3035
|
-
setAllowCompanies(allowCompanies) {
|
|
3036
|
-
this.state.allowCompanies = allowCompanies;
|
|
3037
|
-
}
|
|
3038
|
-
setCompanies(companies) {
|
|
3039
|
-
this.state.companies = companies;
|
|
3040
|
-
}
|
|
3041
|
-
setDefaultCompany(company) {
|
|
3042
|
-
this.state.defaultCompany = company;
|
|
3043
|
-
}
|
|
3044
|
-
setUserInfo(userInfo) {
|
|
3045
|
-
this.state.user = userInfo;
|
|
3046
|
-
}
|
|
3047
|
-
// Getters để truy cập trạng thái
|
|
3048
|
-
get baseUrl() {
|
|
3049
|
-
return this.state.baseUrl;
|
|
3050
|
-
}
|
|
3051
|
-
get requests() {
|
|
3052
|
-
return this.state.requests;
|
|
3053
|
-
}
|
|
3054
|
-
get context() {
|
|
3055
|
-
return this.state.context;
|
|
3056
|
-
}
|
|
3057
|
-
get defaultCompany() {
|
|
3058
|
-
return this.state.defaultCompany;
|
|
3059
|
-
}
|
|
3060
|
-
get config() {
|
|
3061
|
-
return this.state.config;
|
|
3062
|
-
}
|
|
3063
|
-
get companies() {
|
|
3064
|
-
return this.state.companies;
|
|
3065
|
-
}
|
|
3066
|
-
get user() {
|
|
3067
|
-
return this.state.user;
|
|
3068
|
-
}
|
|
3069
|
-
get db() {
|
|
3070
|
-
return this.state.db;
|
|
3071
|
-
}
|
|
3072
|
-
get refreshTokenEndpoint() {
|
|
3073
|
-
return this.state.refreshTokenEndpoint;
|
|
3074
|
-
}
|
|
3075
|
-
get uid() {
|
|
3076
|
-
return this.state.uid;
|
|
3077
|
-
}
|
|
3078
|
-
get lang() {
|
|
3079
|
-
return this.state.lang;
|
|
3080
|
-
}
|
|
3081
|
-
get allowCompanies() {
|
|
3082
|
-
return this.state.allowCompanies;
|
|
3083
|
-
}
|
|
2774
|
+
var requests = {
|
|
2775
|
+
get: async (url, headers) => ({}),
|
|
2776
|
+
post: async (url, body, headers) => ({}),
|
|
2777
|
+
post_excel: async (url, body, headers) => ({}),
|
|
2778
|
+
put: async (url, body, headers) => ({}),
|
|
2779
|
+
patch: async (url, body) => ({}),
|
|
2780
|
+
delete: async (url, body) => ({})
|
|
3084
2781
|
};
|
|
3085
2782
|
function getEnv() {
|
|
3086
|
-
const
|
|
3087
|
-
|
|
3088
|
-
throw new Error("EnvStore has not been initialized \u2014 call initEnv() first");
|
|
3089
|
-
}
|
|
3090
|
-
return instance;
|
|
2783
|
+
const env = envStore.getState().env;
|
|
2784
|
+
return { ...env, requests };
|
|
3091
2785
|
}
|
|
3092
2786
|
|
|
3093
2787
|
// src/services/view-service/index.ts
|
|
@@ -3351,8 +3045,7 @@ var ViewService = {
|
|
|
3351
3045
|
},
|
|
3352
3046
|
async getVersion() {
|
|
3353
3047
|
const env = getEnv();
|
|
3354
|
-
|
|
3355
|
-
return env?.requests?.get("", {
|
|
3048
|
+
return env?.requests.get("", {
|
|
3356
3049
|
headers: {
|
|
3357
3050
|
"Content-Type": "application/json"
|
|
3358
3051
|
}
|
|
@@ -3549,7 +3242,6 @@ var VersionGate = ({ children }) => {
|
|
|
3549
3242
|
};
|
|
3550
3243
|
const validateVersion = async () => {
|
|
3551
3244
|
const serverVersion = await view_service_default.getVersion();
|
|
3552
|
-
console.log("serverVersion", serverVersion);
|
|
3553
3245
|
const cached = localStorage.getItem("__api_version__");
|
|
3554
3246
|
if (cached !== serverVersion?.api_version) {
|
|
3555
3247
|
clearVersion();
|
package/dist/services.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as ContextApi, L as LoginCredentialBody, R as ResetPasswordRequest, U as UpdatePasswordRequest, b as GetListParams,
|
|
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';
|
|
2
2
|
|
|
3
3
|
declare const ActionService: {
|
|
4
4
|
loadAction({ idAction, context, }: {
|
|
@@ -51,6 +51,7 @@ 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>;
|
|
54
55
|
loginSocial({ db, state, access_token, }: {
|
|
55
56
|
db: string;
|
|
56
57
|
state: object;
|
package/dist/services.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as ContextApi, L as LoginCredentialBody, R as ResetPasswordRequest, U as UpdatePasswordRequest, b as GetListParams,
|
|
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';
|
|
2
2
|
|
|
3
3
|
declare const ActionService: {
|
|
4
4
|
loadAction({ idAction, context, }: {
|
|
@@ -51,6 +51,7 @@ 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>;
|
|
54
55
|
loginSocial({ db, state, access_token, }: {
|
|
55
56
|
db: string;
|
|
56
57
|
state: object;
|