@intra-mart/smartlime 2.1.0 → 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,24 +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', {
42
- headers: {
43
- Cookie: cookie,
44
- },
40
+ return useCallback(async (cookie) => {
41
+ const headers = cookie
42
+ ? { Cookie: cookie }
43
+ : {};
44
+ await imFetch('/logout', {
45
+ credentials: 'include',
46
+ headers: headers,
45
47
  method: 'GET',
46
48
  });
47
- }, []);
49
+ }, [imFetch]);
48
50
  };
49
51
  const makeEncodeParams = (clientTypeId = 'pc') => {
50
52
  return `${`clientTypeId=${encodeURIComponent(clientTypeId)}`}`;
51
53
  };
52
- const useRequest = (setter, getter) => {
54
+ const useRequest = (setter, getter, logout) => {
53
55
  const imFetch = useIMFetch();
54
- const logout = useLogout();
55
56
  const request = useCallback(async (clientTypeId) => {
56
57
  try {
57
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);
58
64
  const params = makeEncodeParams(clientTypeId);
59
65
  const response = await imFetch(`api/bearer/smacolow/session?${params}`, {
60
66
  credentials: 'include',
@@ -70,8 +76,6 @@ const useRequest = (setter, getter) => {
70
76
  const cookie = response.headers.get('Set-Cookie');
71
77
  if (cookie) {
72
78
  setter(cookie);
73
- if (currentCookies)
74
- logout(makeCookie(currentCookies));
75
79
  return { status: 'success' };
76
80
  }
77
81
  throw new IMSessionError('could not find sessionid from Set-Cookie in response header.');
@@ -85,20 +89,18 @@ const useRequest = (setter, getter) => {
85
89
  }, [imFetch]);
86
90
  return request;
87
91
  };
88
- const useDestroy = (renderTarget, setter, getter) => {
89
- const logout = useLogout();
90
- return useCallback(() => {
92
+ const useDestroy = (renderTarget, setter, getter, logout) => {
93
+ return useCallback(async () => {
91
94
  const { cookies } = getter();
92
95
  if (cookies) {
93
- logout(makeCookie(cookies));
96
+ await logout(makeCookie(cookies));
94
97
  }
95
98
  setter(null);
96
99
  renderTarget.dispatch();
97
100
  }, []);
98
101
  };
99
- const useGetSessionAsync = (request, destroy, getter) => {
102
+ const useGetSessionAsync = (request, destroy, getter, logout) => {
100
103
  const imFetch = useIMFetch({ noValidate: true });
101
- const logout = useLogout();
102
104
  const reRequest = async (count) => {
103
105
  const { status } = await request();
104
106
  if (status === 'success') {
@@ -126,7 +128,7 @@ const useGetSessionAsync = (request, destroy, getter) => {
126
128
  return getter();
127
129
  }
128
130
  else {
129
- logout(makeCookie(cookies));
131
+ await logout(makeCookie(cookies));
130
132
  }
131
133
  }
132
134
  const status = await reRequest(0);
@@ -136,8 +138,7 @@ const useGetSessionAsync = (request, destroy, getter) => {
136
138
  throw new IMSessionError('failed to get session.');
137
139
  }, [request]);
138
140
  };
139
- const unmountEffect = (getter) => {
140
- const logout = useLogout();
141
+ const unmountEffect = (getter, logout) => {
141
142
  const { cookies } = getter();
142
143
  useEffect(() => {
143
144
  return () => {
@@ -152,10 +153,11 @@ export const IMSession = ({ children, sessionContext }) => {
152
153
  const contextRef = useRef();
153
154
  const sessionStateRenderTarget = useRenderTarget();
154
155
  const [, setSession, getSession] = useSessionStateRef(sessionStateRenderTarget);
155
- const request = useRequest(setSession, getSession);
156
- const destroy = useDestroy(sessionStateRenderTarget, setSession, getSession);
157
- const getSessionAsync = useGetSessionAsync(request, destroy, getSession);
158
- 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);
159
161
  contextRef.current = {
160
162
  getSession,
161
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>);