@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.
@@ -54,6 +54,7 @@ export interface Me {
54
54
  calendarId: string;
55
55
  firstDayOfWeek: 1 | 2 | 3 | 4 | 5 | 6 | 7;
56
56
  locale: string;
57
+ roleIds: string[];
57
58
  tenantId: string;
58
59
  timeZone: string;
59
60
  userCd: string;
@@ -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
- imFetch('/logout', {
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
- const logout = useLogout();
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 request = useRequest(setSession, getSession);
157
- const destroy = useDestroy(sessionStateRenderTarget, setSession, getSession);
158
- const getSessionAsync = useGetSessionAsync(request, destroy, getSession);
159
- unmountEffect(getSession);
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
- getFetchModuleState: () => FetchModuleState;
7
- getModuleInfo: () => Moudles | undefined;
8
- destroyModuleInfo: () => Promise<void>;
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>;
@@ -0,0 +1,2 @@
1
+ export declare const IM_MODULE_STORAGE_KEY = "IM_MODULE_STORAGE_KEY";
2
+ export declare const createStorageKey: (baseUrl: string) => string;
@@ -0,0 +1,4 @@
1
+ export const IM_MODULE_STORAGE_KEY = 'IM_MODULE_STORAGE_KEY';
2
+ export const createStorageKey = (baseUrl) => {
3
+ return `${baseUrl}_${IM_MODULE_STORAGE_KEY}`;
4
+ };
@@ -1,3 +1,3 @@
1
1
  export * from './useIMBaseUrl';
2
- export * from './useIMFetchModuleState';
3
- export * from './useIMModuleInfo';
2
+ export * from './useIMModules';
3
+ export * from './useIMModulesState';
@@ -1,3 +1,3 @@
1
1
  export * from './useIMBaseUrl';
2
- export * from './useIMFetchModuleState';
3
- export * from './useIMModuleInfo';
2
+ export * from './useIMModules';
3
+ export * from './useIMModulesState';
@@ -0,0 +1,6 @@
1
+ import { Context as DefaultContext, IMModules } from '../Context';
2
+ export declare const useIMModules: (Context?: typeof DefaultContext) => {
3
+ request: () => Promise<void>;
4
+ getModules: () => IMModules | undefined;
5
+ destroy: () => Promise<void>;
6
+ };
@@ -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
+ };
@@ -0,0 +1,2 @@
1
+ import { Context as DefaultContext } from '../Context';
2
+ export declare const useIMModulesState: (Context?: typeof DefaultContext) => import("../Context").IMModules | undefined;
@@ -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 useIMFetchModuleState = (Context) => {
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('useIMFetchModuleState requires either a Context provide or an ancestor element with a IMTenantProvider.');
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
- const state = tenantContext.getFetchModuleState();
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
- fetchModuleState: FetchModuleState;
21
- modules?: Moudles;
9
+ modules?: IMModules;
22
10
  }
23
- export declare const IMTenant: ({ children, baseUrl, tenantId, tenantContext, useModuleInfo, }: IMTenantProps) => import("react").JSX.Element;
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 { IMTenantError } from './IMTenantError';
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 createInitFetchModuleState = (useModuleInfo) => {
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 getModuleInfoStorage = async (storageKey) => {
27
- const state = await AsyncStorage.getItem(storageKey);
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
- for (let i = 0; i < MODULE_IDS.length; i++) {
60
- const key = MODULE_IDS[i];
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
- fetchModuleStateSetter('notFetched');
68
- }, [fetchModuleStateSetter, baseUrl]);
29
+ renderTarget.dispatch();
30
+ }, [baseUrl]);
69
31
  return [ref, setter, getter, destroy];
70
32
  };
71
- const createCheckHybridSSOUrl = (baseUrl) => {
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 [, setFetchModuleState, getFetchModuleState] = useFetchModuleStateRef(modulesStateRenderTarget, useModuleInfo);
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
- getFetchModuleState,
110
- getModuleInfo,
111
- destroyModuleInfo,
112
- fetchModuleInfo,
43
+ getModules,
44
+ setModules,
45
+ destroyModule,
113
46
  modulesStateRenderTarget,
114
47
  };
115
48
  return (<Context.Provider value={contextRef.current}>{children}</Context.Provider>);