@intra-mart/smartlime 2.1.1 → 2.2.0-dev.20250408
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/lib/packages/Me/type.d.ts +1 -0
- package/lib/packages/Session/index.js +24 -23
- package/lib/packages/Tenant/Context.d.ts +13 -5
- package/lib/packages/Tenant/constants.d.ts +2 -0
- package/lib/packages/Tenant/constants.js +4 -0
- package/lib/packages/Tenant/hooks/index.d.ts +2 -2
- package/lib/packages/Tenant/hooks/index.js +2 -2
- package/lib/packages/Tenant/hooks/useIMModules.d.ts +6 -0
- package/lib/packages/Tenant/hooks/useIMModules.js +73 -0
- package/lib/packages/Tenant/hooks/useIMModulesState.d.ts +2 -0
- package/lib/packages/Tenant/hooks/{useIMFetchModuleState.js → useIMModulesState.js} +3 -4
- package/lib/packages/Tenant/index.d.ts +3 -15
- package/lib/packages/Tenant/index.js +13 -80
- package/lib/packages/Tenant/modulesType.d.ts +1522 -2
- package/lib/packages/Tenant/modulesType.js +1522 -2
- package/lib/packages/WebView/InternalIMWebView.js +6 -6
- package/lib/packages/WebView/index.js +8 -8
- package/package.json +1 -2
- package/lib/packages/Tenant/hooks/useIMFetchModuleState.d.ts +0 -2
- package/lib/packages/Tenant/hooks/useIMModuleInfo.d.ts +0 -6
- package/lib/packages/Tenant/hooks/useIMModuleInfo.js +0 -13
|
@@ -37,25 +37,30 @@ const useSessionStateRef = (renderTarget) => {
|
|
|
37
37
|
};
|
|
38
38
|
const useLogout = () => {
|
|
39
39
|
const imFetch = useIMFetch({ noValidate: true });
|
|
40
|
-
return useCallback((cookie) => {
|
|
41
|
-
|
|
40
|
+
return useCallback(async (cookie) => {
|
|
41
|
+
const headers = cookie
|
|
42
|
+
? { Cookie: cookie }
|
|
43
|
+
: {};
|
|
44
|
+
await imFetch('/logout', {
|
|
42
45
|
credentials: 'include',
|
|
43
|
-
headers:
|
|
44
|
-
Cookie: cookie,
|
|
45
|
-
},
|
|
46
|
+
headers: headers,
|
|
46
47
|
method: 'GET',
|
|
47
48
|
});
|
|
48
|
-
}, []);
|
|
49
|
+
}, [imFetch]);
|
|
49
50
|
};
|
|
50
51
|
const makeEncodeParams = (clientTypeId = 'pc') => {
|
|
51
52
|
return `${`clientTypeId=${encodeURIComponent(clientTypeId)}`}`;
|
|
52
53
|
};
|
|
53
|
-
const useRequest = (setter, getter) => {
|
|
54
|
+
const useRequest = (setter, getter, logout) => {
|
|
54
55
|
const imFetch = useIMFetch();
|
|
55
|
-
const logout = useLogout();
|
|
56
56
|
const request = useCallback(async (clientTypeId) => {
|
|
57
57
|
try {
|
|
58
58
|
const currentCookies = getter()?.cookies;
|
|
59
|
+
const cookie = currentCookies ? makeCookie(currentCookies) : null;
|
|
60
|
+
// previous session may still be active, so execute the logout process
|
|
61
|
+
await logout();
|
|
62
|
+
if (cookie)
|
|
63
|
+
await logout(cookie);
|
|
59
64
|
const params = makeEncodeParams(clientTypeId);
|
|
60
65
|
const response = await imFetch(`api/bearer/smacolow/session?${params}`, {
|
|
61
66
|
credentials: 'include',
|
|
@@ -71,8 +76,6 @@ const useRequest = (setter, getter) => {
|
|
|
71
76
|
const cookie = response.headers.get('Set-Cookie');
|
|
72
77
|
if (cookie) {
|
|
73
78
|
setter(cookie);
|
|
74
|
-
if (currentCookies)
|
|
75
|
-
logout(makeCookie(currentCookies));
|
|
76
79
|
return { status: 'success' };
|
|
77
80
|
}
|
|
78
81
|
throw new IMSessionError('could not find sessionid from Set-Cookie in response header.');
|
|
@@ -86,20 +89,18 @@ const useRequest = (setter, getter) => {
|
|
|
86
89
|
}, [imFetch]);
|
|
87
90
|
return request;
|
|
88
91
|
};
|
|
89
|
-
const useDestroy = (renderTarget, setter, getter) => {
|
|
90
|
-
|
|
91
|
-
return useCallback(() => {
|
|
92
|
+
const useDestroy = (renderTarget, setter, getter, logout) => {
|
|
93
|
+
return useCallback(async () => {
|
|
92
94
|
const { cookies } = getter();
|
|
93
95
|
if (cookies) {
|
|
94
|
-
logout(makeCookie(cookies));
|
|
96
|
+
await logout(makeCookie(cookies));
|
|
95
97
|
}
|
|
96
98
|
setter(null);
|
|
97
99
|
renderTarget.dispatch();
|
|
98
100
|
}, []);
|
|
99
101
|
};
|
|
100
|
-
const useGetSessionAsync = (request, destroy, getter) => {
|
|
102
|
+
const useGetSessionAsync = (request, destroy, getter, logout) => {
|
|
101
103
|
const imFetch = useIMFetch({ noValidate: true });
|
|
102
|
-
const logout = useLogout();
|
|
103
104
|
const reRequest = async (count) => {
|
|
104
105
|
const { status } = await request();
|
|
105
106
|
if (status === 'success') {
|
|
@@ -127,7 +128,7 @@ const useGetSessionAsync = (request, destroy, getter) => {
|
|
|
127
128
|
return getter();
|
|
128
129
|
}
|
|
129
130
|
else {
|
|
130
|
-
logout(makeCookie(cookies));
|
|
131
|
+
await logout(makeCookie(cookies));
|
|
131
132
|
}
|
|
132
133
|
}
|
|
133
134
|
const status = await reRequest(0);
|
|
@@ -137,8 +138,7 @@ const useGetSessionAsync = (request, destroy, getter) => {
|
|
|
137
138
|
throw new IMSessionError('failed to get session.');
|
|
138
139
|
}, [request]);
|
|
139
140
|
};
|
|
140
|
-
const unmountEffect = (getter) => {
|
|
141
|
-
const logout = useLogout();
|
|
141
|
+
const unmountEffect = (getter, logout) => {
|
|
142
142
|
const { cookies } = getter();
|
|
143
143
|
useEffect(() => {
|
|
144
144
|
return () => {
|
|
@@ -153,10 +153,11 @@ export const IMSession = ({ children, sessionContext }) => {
|
|
|
153
153
|
const contextRef = useRef();
|
|
154
154
|
const sessionStateRenderTarget = useRenderTarget();
|
|
155
155
|
const [, setSession, getSession] = useSessionStateRef(sessionStateRenderTarget);
|
|
156
|
-
const
|
|
157
|
-
const
|
|
158
|
-
const
|
|
159
|
-
|
|
156
|
+
const logout = useLogout();
|
|
157
|
+
const request = useRequest(setSession, getSession, logout);
|
|
158
|
+
const destroy = useDestroy(sessionStateRenderTarget, setSession, getSession, logout);
|
|
159
|
+
const getSessionAsync = useGetSessionAsync(request, destroy, getSession, logout);
|
|
160
|
+
unmountEffect(getSession, logout);
|
|
160
161
|
contextRef.current = {
|
|
161
162
|
getSession,
|
|
162
163
|
getSessionAsync,
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
-
import { FetchModuleState, Moudles } from '.';
|
|
2
1
|
import { RenderTarget } from '../../_shared/renderTarget';
|
|
2
|
+
import { ModuleIds } from './modulesType';
|
|
3
|
+
export interface IMModule {
|
|
4
|
+
moduleId: ModuleIds[number];
|
|
5
|
+
version: string;
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
others: unknown;
|
|
8
|
+
}
|
|
9
|
+
export type IMModules = {
|
|
10
|
+
[key in ModuleIds[number]]: IMModule;
|
|
11
|
+
};
|
|
3
12
|
export interface TenantContext {
|
|
4
13
|
getBaseUrl: () => string;
|
|
5
14
|
getTenantId: () => string | undefined;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
fetchModuleInfo: () => Promise<void>;
|
|
15
|
+
getModules: () => IMModules | undefined;
|
|
16
|
+
setModules: (state: IMModules, silent?: boolean) => void;
|
|
17
|
+
destroyModule: () => Promise<void>;
|
|
10
18
|
modulesStateRenderTarget: RenderTarget;
|
|
11
19
|
}
|
|
12
20
|
export declare const Context: import("react").Context<TenantContext | null>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './useIMBaseUrl';
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
2
|
+
export * from './useIMModules';
|
|
3
|
+
export * from './useIMModulesState';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './useIMBaseUrl';
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
2
|
+
export * from './useIMModules';
|
|
3
|
+
export * from './useIMModulesState';
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
2
|
+
import { useContext, useMemo } from 'react';
|
|
3
|
+
import { useIMFetch } from '../../Fetch';
|
|
4
|
+
import { createStorageKey } from '../constants';
|
|
5
|
+
import { Context as DefaultContext } from '../Context';
|
|
6
|
+
import { IMTenantError } from '../IMTenantError';
|
|
7
|
+
import { MODULE_IDS } from '../modulesType';
|
|
8
|
+
const saveModuleStorage = async (storageKey, Modules) => {
|
|
9
|
+
return await AsyncStorage.setItem(storageKey, JSON.stringify(Modules));
|
|
10
|
+
};
|
|
11
|
+
const getModuleStorage = async (storageKey) => {
|
|
12
|
+
const state = await AsyncStorage.getItem(storageKey);
|
|
13
|
+
if (state == null)
|
|
14
|
+
return;
|
|
15
|
+
const result = JSON.parse(state);
|
|
16
|
+
return result;
|
|
17
|
+
};
|
|
18
|
+
const createInitialModule = () => {
|
|
19
|
+
const initState = MODULE_IDS.reduce((acc, moduleId) => {
|
|
20
|
+
acc[moduleId] = {
|
|
21
|
+
moduleId: moduleId,
|
|
22
|
+
version: '',
|
|
23
|
+
enabled: false,
|
|
24
|
+
others: {},
|
|
25
|
+
};
|
|
26
|
+
return acc;
|
|
27
|
+
}, {});
|
|
28
|
+
return initState;
|
|
29
|
+
};
|
|
30
|
+
const useRequestModule = (baseUrl, setModules) => {
|
|
31
|
+
const IMFetch = useIMFetch();
|
|
32
|
+
return async () => {
|
|
33
|
+
const storageKey = createStorageKey(baseUrl);
|
|
34
|
+
const storageState = await getModuleStorage(storageKey);
|
|
35
|
+
if (storageState) {
|
|
36
|
+
setModules(storageState);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const response = await IMFetch('api/smacolow/modules');
|
|
40
|
+
if (response.status !== 200) {
|
|
41
|
+
throw new IMTenantError('failed to fetch module status.');
|
|
42
|
+
}
|
|
43
|
+
const result = await response.json();
|
|
44
|
+
const state = result.data.modules.reduce((acc, module) => {
|
|
45
|
+
const { moduleId, moduleVersion } = module;
|
|
46
|
+
acc[moduleId] = {
|
|
47
|
+
moduleId: moduleId,
|
|
48
|
+
version: moduleVersion,
|
|
49
|
+
enabled: true,
|
|
50
|
+
others: {},
|
|
51
|
+
};
|
|
52
|
+
return acc;
|
|
53
|
+
}, createInitialModule());
|
|
54
|
+
saveModuleStorage(storageKey, state);
|
|
55
|
+
setModules(state);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
export const useIMModules = (Context) => {
|
|
60
|
+
const tenantContext = useContext(Context || DefaultContext);
|
|
61
|
+
if (tenantContext == null) {
|
|
62
|
+
throw new IMTenantError('useIMModules requires either a Context provide or an ancestor element with a IMTenantProvider.');
|
|
63
|
+
}
|
|
64
|
+
const requestModule = useRequestModule(tenantContext.getBaseUrl(), tenantContext.setModules);
|
|
65
|
+
return useMemo(() => {
|
|
66
|
+
const { getModules, destroyModule } = tenantContext;
|
|
67
|
+
return {
|
|
68
|
+
request: requestModule,
|
|
69
|
+
getModules,
|
|
70
|
+
destroy: destroyModule,
|
|
71
|
+
};
|
|
72
|
+
}, [tenantContext]);
|
|
73
|
+
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { useContext, useEffect, useReducer, useRef } from 'react';
|
|
2
2
|
import { Context as DefaultContext } from '../Context';
|
|
3
3
|
import { IMTenantError } from '../IMTenantError';
|
|
4
|
-
export const
|
|
4
|
+
export const useIMModulesState = (Context) => {
|
|
5
5
|
const initRef = useRef(true);
|
|
6
6
|
const [, forceRender] = useReducer((s) => s + 1, 0);
|
|
7
7
|
const tenantContext = useContext(Context || DefaultContext);
|
|
8
8
|
if (tenantContext == null) {
|
|
9
|
-
throw new IMTenantError('
|
|
9
|
+
throw new IMTenantError('useIMModulesState requires either a Context provide or an ancestor element with a IMTenantProvider.');
|
|
10
10
|
}
|
|
11
11
|
if (initRef.current) {
|
|
12
12
|
initRef.current = false;
|
|
@@ -17,6 +17,5 @@ export const useIMFetchModuleState = (Context) => {
|
|
|
17
17
|
tenantContext.modulesStateRenderTarget.removeEventListener(forceRender);
|
|
18
18
|
};
|
|
19
19
|
}, []);
|
|
20
|
-
|
|
21
|
-
return state;
|
|
20
|
+
return tenantContext.getModules();
|
|
22
21
|
};
|
|
@@ -1,24 +1,12 @@
|
|
|
1
|
-
import { Context as DefaultContext } from './Context';
|
|
2
|
-
import { ModuleIds } from './modulesType';
|
|
1
|
+
import { Context as DefaultContext, IMModules } from './Context';
|
|
3
2
|
interface IMTenantProps {
|
|
4
3
|
children: JSX.Element;
|
|
5
4
|
baseUrl: string;
|
|
6
5
|
tenantId?: string;
|
|
7
6
|
tenantContext?: typeof DefaultContext;
|
|
8
|
-
useModuleInfo?: boolean;
|
|
9
7
|
}
|
|
10
|
-
export interface ModuleInfo<T extends ModuleIds[number]> {
|
|
11
|
-
moduleKey: T;
|
|
12
|
-
enabled: boolean;
|
|
13
|
-
othes: unknown;
|
|
14
|
-
}
|
|
15
|
-
export type Moudles = {
|
|
16
|
-
[key in ModuleIds[number]]: ModuleInfo<key>;
|
|
17
|
-
};
|
|
18
|
-
export type FetchModuleState = 'notRequired' | 'notFetched' | 'fetched';
|
|
19
8
|
export interface ModuleState {
|
|
20
|
-
|
|
21
|
-
modules?: Moudles;
|
|
9
|
+
modules?: IMModules;
|
|
22
10
|
}
|
|
23
|
-
export declare const IMTenant: ({ children, baseUrl, tenantId, tenantContext,
|
|
11
|
+
export declare const IMTenant: ({ children, baseUrl, tenantId, tenantContext, }: IMTenantProps) => import("react").JSX.Element;
|
|
24
12
|
export {};
|
|
@@ -1,40 +1,20 @@
|
|
|
1
1
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
2
2
|
import { useCallback, useRef } from 'react';
|
|
3
3
|
import { useRenderTarget } from '../../_shared/renderTarget';
|
|
4
|
-
import { join } from '../../utils/path';
|
|
5
4
|
import { Context as DefaultContext } from './Context';
|
|
6
|
-
import {
|
|
7
|
-
import { HYBRID_SSO_KEY, MODULE_IDS } from './modulesType';
|
|
5
|
+
import { createStorageKey } from './constants';
|
|
8
6
|
const useGetBaseUrl = (baseUrl) => {
|
|
9
7
|
return useCallback(() => baseUrl, [baseUrl]);
|
|
10
8
|
};
|
|
11
9
|
const useGetTenantId = (tenantId) => {
|
|
12
10
|
return useCallback(() => tenantId, [tenantId]);
|
|
13
11
|
};
|
|
14
|
-
const
|
|
15
|
-
return useModuleInfo ? 'notFetched' : 'notRequired';
|
|
16
|
-
};
|
|
17
|
-
const createStorageKey = (baseUrl, moduleKey) => {
|
|
18
|
-
return `${baseUrl}_${moduleKey}`;
|
|
19
|
-
};
|
|
20
|
-
const saveModuleInfoStorage = async (storageKey, ModuleInfo) => {
|
|
21
|
-
return await AsyncStorage.setItem(storageKey, JSON.stringify(ModuleInfo));
|
|
22
|
-
};
|
|
23
|
-
const deleteModuleInfoStorage = async (storageKey) => {
|
|
12
|
+
const deleteModuleStorage = async (storageKey) => {
|
|
24
13
|
return await AsyncStorage.removeItem(storageKey);
|
|
25
14
|
};
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
if (state == null)
|
|
29
|
-
return;
|
|
30
|
-
const result = JSON.parse(state);
|
|
31
|
-
return result;
|
|
32
|
-
};
|
|
33
|
-
const useFetchModuleStateRef = (renderTarget, useModuleInfo) => {
|
|
34
|
-
const ref = useRef(createInitFetchModuleState(useModuleInfo));
|
|
15
|
+
const useModuleRef = (baseUrl, renderTarget) => {
|
|
16
|
+
const ref = useRef();
|
|
35
17
|
const setter = useCallback((state, silent) => {
|
|
36
|
-
if (!useModuleInfo)
|
|
37
|
-
throw new IMTenantError('useModuleInfo is not enabled');
|
|
38
18
|
if (ref.current === state)
|
|
39
19
|
return;
|
|
40
20
|
ref.current = state;
|
|
@@ -42,74 +22,27 @@ const useFetchModuleStateRef = (renderTarget, useModuleInfo) => {
|
|
|
42
22
|
renderTarget.dispatch();
|
|
43
23
|
}, []);
|
|
44
24
|
const getter = useCallback(() => ref.current, []);
|
|
45
|
-
return [ref, setter, getter];
|
|
46
|
-
};
|
|
47
|
-
const useModuleInfoRef = (baseUrl, fetchModuleStateSetter, useModuleInfo) => {
|
|
48
|
-
const ref = useRef();
|
|
49
|
-
const setter = useCallback((state, silent) => {
|
|
50
|
-
if (!useModuleInfo)
|
|
51
|
-
throw new IMTenantError('useModuleInfo is not enabled');
|
|
52
|
-
if (ref.current === state)
|
|
53
|
-
return;
|
|
54
|
-
ref.current = state;
|
|
55
|
-
fetchModuleStateSetter('fetched', silent);
|
|
56
|
-
}, [fetchModuleStateSetter, useModuleInfo]);
|
|
57
|
-
const getter = useCallback(() => ref.current, []);
|
|
58
25
|
const destroy = useCallback(async () => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (key) {
|
|
62
|
-
const storageKey = createStorageKey(baseUrl, key);
|
|
63
|
-
await deleteModuleInfoStorage(storageKey);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
26
|
+
const storageKey = createStorageKey(baseUrl);
|
|
27
|
+
await deleteModuleStorage(storageKey);
|
|
66
28
|
ref.current = undefined;
|
|
67
|
-
|
|
68
|
-
}, [
|
|
29
|
+
renderTarget.dispatch();
|
|
30
|
+
}, [baseUrl]);
|
|
69
31
|
return [ref, setter, getter, destroy];
|
|
70
32
|
};
|
|
71
|
-
const
|
|
72
|
-
return join(baseUrl, '/im_hybrid_sso/logout');
|
|
73
|
-
};
|
|
74
|
-
const useFetchModuleInfo = (baseUrl, setModuleInfo) => {
|
|
75
|
-
return useCallback(async () => {
|
|
76
|
-
const hybridSSOUrl = createCheckHybridSSOUrl(baseUrl);
|
|
77
|
-
const storageKey = createStorageKey(baseUrl, HYBRID_SSO_KEY);
|
|
78
|
-
const storageState = await getModuleInfoStorage(storageKey);
|
|
79
|
-
if (storageState) {
|
|
80
|
-
setModuleInfo({
|
|
81
|
-
[HYBRID_SSO_KEY]: storageState,
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
const response = await fetch(hybridSSOUrl);
|
|
86
|
-
const hasHyBridSSO = response.status !== 404;
|
|
87
|
-
const state = {
|
|
88
|
-
moduleKey: HYBRID_SSO_KEY,
|
|
89
|
-
enabled: hasHyBridSSO,
|
|
90
|
-
othes: {},
|
|
91
|
-
};
|
|
92
|
-
saveModuleInfoStorage(storageKey, state);
|
|
93
|
-
setModuleInfo({ [HYBRID_SSO_KEY]: state });
|
|
94
|
-
}
|
|
95
|
-
}, [setModuleInfo, baseUrl]);
|
|
96
|
-
};
|
|
97
|
-
export const IMTenant = ({ children, baseUrl, tenantId, tenantContext, useModuleInfo, }) => {
|
|
33
|
+
export const IMTenant = ({ children, baseUrl, tenantId, tenantContext, }) => {
|
|
98
34
|
const Context = tenantContext || DefaultContext;
|
|
99
35
|
const contextRef = useRef();
|
|
100
36
|
const modulesStateRenderTarget = useRenderTarget();
|
|
101
37
|
const getBaseUrl = useGetBaseUrl(baseUrl);
|
|
102
38
|
const getTenantId = useGetTenantId(tenantId);
|
|
103
|
-
const [,
|
|
104
|
-
const [, setModuleInfo, getModuleInfo, destroyModuleInfo] = useModuleInfoRef(baseUrl, setFetchModuleState, useModuleInfo);
|
|
105
|
-
const fetchModuleInfo = useFetchModuleInfo(baseUrl, setModuleInfo);
|
|
39
|
+
const [, setModules, getModules, destroyModule] = useModuleRef(baseUrl, modulesStateRenderTarget);
|
|
106
40
|
contextRef.current = {
|
|
107
41
|
getBaseUrl,
|
|
108
42
|
getTenantId,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
fetchModuleInfo,
|
|
43
|
+
getModules,
|
|
44
|
+
setModules,
|
|
45
|
+
destroyModule,
|
|
113
46
|
modulesStateRenderTarget,
|
|
114
47
|
};
|
|
115
48
|
return (<Context.Provider value={contextRef.current}>{children}</Context.Provider>);
|