@qlover/create-app 0.1.3 → 0.1.5

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.
Files changed (114) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/bin/create-app.js +44 -4
  3. package/{templates/pack-app → configs/_common}/.env.template +8 -1
  4. package/{templates/pack-app → configs/_common}/.github/workflows/general-check.yml +9 -9
  5. package/{templates/pack-app → configs/_common}/.github/workflows/release.yml.template +18 -18
  6. package/configs/_common/.prettierrc.js +7 -0
  7. package/configs/_common/.release-it.json.template +42 -0
  8. package/configs/_common/.vscode/extensions.json +9 -0
  9. package/configs/_common/.vscode/react.code-snippets +19 -0
  10. package/configs/_common/.vscode/settings.json +11 -0
  11. package/configs/_common/package.json +61 -0
  12. package/configs/node-lib/eslint.config.js +50 -0
  13. package/configs/react-app/eslint.config.js +66 -0
  14. package/dist/cjs/index.d.ts +52 -37
  15. package/dist/cjs/index.js +1 -1
  16. package/dist/es/index.d.ts +52 -37
  17. package/dist/es/index.js +1 -1
  18. package/package.json +5 -2
  19. package/templates/node-lib/.release-it.json +42 -0
  20. package/templates/node-lib/__tests__/readJson.test.ts +1 -0
  21. package/templates/node-lib/bin/test.js +30 -0
  22. package/templates/node-lib/package.json +23 -6
  23. package/templates/node-lib/rollup.config.js +15 -24
  24. package/templates/node-lib/src/readJson.ts +9 -3
  25. package/templates/node-lib/tsconfig.json +19 -1
  26. package/templates/pack-app/eslint.config.js +81 -61
  27. package/templates/pack-app/fe-config.json +1 -5
  28. package/templates/pack-app/package.json +19 -11
  29. package/templates/pack-app/tsconfig.json +1 -1
  30. package/templates/pack-app/vite.config.ts +14 -0
  31. package/templates/react-app/README.md +177 -40
  32. package/templates/react-app/config/i18n.ts +1 -1
  33. package/templates/react-app/lib/fe-react-controller/FeController.ts +7 -3
  34. package/templates/react-app/lib/fe-react-theme/ThemeController.ts +1 -1
  35. package/templates/react-app/package.json +53 -8
  36. package/templates/react-app/src/App.tsx +4 -5
  37. package/templates/react-app/src/{services → base/apis}/feApi/FeApiMockPlugin.ts +1 -1
  38. package/templates/react-app/src/base/cases/UserToken.ts +47 -0
  39. package/templates/react-app/src/base/port/IOCInterface.ts +53 -0
  40. package/templates/react-app/src/base/port/StorageTokenInterface.ts +5 -0
  41. package/templates/react-app/src/{types → base/port}/UIDependenciesInterface.ts +6 -0
  42. package/templates/react-app/src/{types → base/types}/global.d.ts +1 -1
  43. package/templates/react-app/src/components/ThemeSwitcher.tsx +3 -2
  44. package/templates/react-app/src/core/bootstrap.ts +21 -0
  45. package/templates/react-app/src/core/feIOC/FeIOC.ts +32 -0
  46. package/templates/react-app/src/core/feIOC/RegisterApi.ts +41 -0
  47. package/templates/react-app/src/core/feIOC/RegisterCommon.ts +20 -0
  48. package/templates/react-app/src/core/feIOC/RegisterControllers.ts +53 -0
  49. package/templates/react-app/src/core/index.ts +31 -0
  50. package/templates/react-app/src/main.tsx +8 -10
  51. package/templates/react-app/src/pages/404.tsx +2 -2
  52. package/templates/react-app/src/pages/500.tsx +1 -1
  53. package/templates/react-app/src/pages/auth/Layout.tsx +3 -2
  54. package/templates/react-app/src/pages/auth/Login.tsx +6 -4
  55. package/templates/react-app/src/pages/base/About.tsx +1 -1
  56. package/templates/react-app/src/pages/base/Executor.tsx +8 -4
  57. package/templates/react-app/src/pages/base/Home.tsx +1 -1
  58. package/templates/react-app/src/pages/base/JSONStorage.tsx +6 -4
  59. package/templates/react-app/src/pages/base/Layout.tsx +1 -1
  60. package/templates/react-app/src/pages/base/RedirectPathname.tsx +1 -1
  61. package/templates/react-app/src/pages/base/Request.tsx +8 -3
  62. package/templates/react-app/src/pages/index.tsx +7 -2
  63. package/templates/react-app/src/services/{pageProcesser/PageProcesser.ts → processer/ProcesserService.ts} +3 -3
  64. package/templates/react-app/src/{containers/context → uikit/contexts}/BaseRouteContext.ts +4 -4
  65. package/templates/react-app/src/{services → uikit}/controllers/ExecutorController.ts +5 -5
  66. package/templates/react-app/src/{services → uikit}/controllers/JSONStorageController.ts +2 -2
  67. package/templates/react-app/src/{services → uikit}/controllers/RequestController.ts +3 -3
  68. package/templates/react-app/src/{services → uikit}/controllers/RouterController.ts +2 -2
  69. package/templates/react-app/src/{services → uikit}/controllers/UserController.ts +25 -51
  70. package/templates/react-app/src/{containers/context → uikit/providers}/BaseRouteProvider.tsx +2 -2
  71. package/templates/react-app/src/{components → uikit/providers}/ProcessProvider.tsx +13 -7
  72. package/templates/react-app/tsconfig.json +27 -5
  73. package/templates/react-app/tsconfig.node.json +3 -15
  74. package/templates/react-app/vite.config.ts +17 -14
  75. package/templates/pack-app/.env +0 -5
  76. package/templates/pack-app/.gitignore.template +0 -50
  77. package/templates/pack-app/.prettierrc.js +0 -3
  78. package/templates/pack-app/CHANGELOG.md +0 -0
  79. package/templates/pack-app/jest.config.js +0 -31
  80. package/templates/react-app/eslint.config.js +0 -31
  81. package/templates/react-app/src/containers/index.ts +0 -71
  82. package/templates/react-app/src/services/pageProcesser/index.ts +0 -1
  83. package/templates/react-app/tsconfig.app.json +0 -29
  84. package/templates/react-vite-lib/.gitignore.template +0 -27
  85. package/templates/react-vite-lib/README.md +0 -50
  86. package/templates/react-vite-lib/__tests__/Sum.test.ts +0 -9
  87. package/templates/react-vite-lib/__tests__/Text.test.tsx +0 -11
  88. package/templates/react-vite-lib/eslint.config.js +0 -28
  89. package/templates/react-vite-lib/index.html +0 -13
  90. package/templates/react-vite-lib/package.json +0 -30
  91. package/templates/react-vite-lib/public/vite.svg +0 -1
  92. package/templates/react-vite-lib/src/calc.ts +0 -3
  93. package/templates/react-vite-lib/src/commponents/Text.tsx +0 -7
  94. package/templates/react-vite-lib/src/index.ts +0 -2
  95. package/templates/react-vite-lib/src/vite-env.d.ts +0 -1
  96. package/templates/react-vite-lib/tsconfig.json +0 -25
  97. package/templates/react-vite-lib/vite.config.ts +0 -24
  98. /package/{templates/pack-app → configs/_common}/.editorconfig +0 -0
  99. /package/{templates/pack-app → configs/_common}/.gitattributes +0 -0
  100. /package/{templates/react-app → configs/_common}/.gitignore.template +0 -0
  101. /package/{templates/pack-app → configs/_common}/.prettierignore +0 -0
  102. /package/templates/react-app/src/{services → base/apis}/feApi/FeApi.ts +0 -0
  103. /package/templates/react-app/src/{services → base/apis}/feApi/FeApiType.ts +0 -0
  104. /package/templates/react-app/src/{services → base/apis}/feApi/index.ts +0 -0
  105. /package/templates/react-app/src/{types → base/types}/Page.ts +0 -0
  106. /package/templates/react-app/src/{containers → core}/globals.ts +0 -0
  107. /package/templates/react-app/src/{hooks → uikit/hooks}/useLanguageGuard.ts +0 -0
  108. /package/templates/react-app/src/{hooks → uikit/hooks}/useStrictEffect.ts +0 -0
  109. /package/templates/react-app/src/{styles → uikit/styles}/css/index.css +0 -0
  110. /package/templates/react-app/src/{styles → uikit/styles}/css/page.css +0 -0
  111. /package/templates/react-app/src/{styles → uikit/styles}/css/tailwind.css +0 -0
  112. /package/templates/react-app/src/{utils → uikit/utils}/RequestLogger.ts +0 -0
  113. /package/templates/react-app/src/{utils → uikit/utils}/datetime.ts +0 -0
  114. /package/templates/react-app/src/{utils → uikit/utils}/thread.ts +0 -0
@@ -0,0 +1,41 @@
1
+ import { IOCInterface, IOCRegisterInterface } from '@/base/port/IOCInterface';
2
+ import { RequestLogger } from '@/uikit/utils/RequestLogger';
3
+ import { localJsonStorage } from '../globals';
4
+ import { FetchAbortPlugin, FetchURLPlugin } from '@qlover/fe-utils';
5
+ import { FeApiMockPlugin } from '@/base/apis/feApi';
6
+ import { defaultFeApiConfig } from '@config/app.common';
7
+ import { OpenAIClient } from '@lib/openAiApi';
8
+ import { openAiConfig } from '@config/app.common';
9
+ import { FeApi } from '@/base/apis/feApi';
10
+ import { RequestCommonPlugin } from '@lib/request-common-plugin';
11
+ import mockDataJson from '@config/feapi.mock.json';
12
+
13
+ export class RegisterApi implements IOCRegisterInterface {
14
+ register(container: IOCInterface): void {
15
+ const openAiApi = new OpenAIClient({
16
+ ...openAiConfig,
17
+ commonPluginConfig: {
18
+ ...openAiConfig.commonPluginConfig,
19
+ requestDataSerializer: (data) => JSON.stringify(data)
20
+ }
21
+ }).usePlugin(container.get(RequestLogger));
22
+
23
+ const feApi = new FeApi({
24
+ abortPlugin: container.get(FetchAbortPlugin),
25
+ config: defaultFeApiConfig.adapter
26
+ })
27
+ .usePlugin(new FetchURLPlugin())
28
+ .usePlugin(
29
+ new RequestCommonPlugin({
30
+ ...defaultFeApiConfig.commonPluginConfig,
31
+ token: () => localJsonStorage.getItem('fe_user_token')
32
+ })
33
+ )
34
+ .usePlugin(new FeApiMockPlugin(mockDataJson))
35
+ .usePlugin(container.get(RequestLogger))
36
+ .usePlugin(container.get(FetchAbortPlugin));
37
+
38
+ container.bind(OpenAIClient, openAiApi);
39
+ container.bind(FeApi, feApi);
40
+ }
41
+ }
@@ -0,0 +1,20 @@
1
+ import { IOCInterface, IOCRegisterInterface } from '@/base/port/IOCInterface';
2
+ import { RequestLogger } from '@/uikit/utils/RequestLogger';
3
+ import { localJsonStorage, logger } from '../globals';
4
+ import { FetchAbortPlugin } from '@qlover/fe-utils';
5
+ import { UserToken } from '@/base/cases/UserToken';
6
+
7
+ export class RegisterCommon implements IOCRegisterInterface {
8
+ register(container: IOCInterface): void {
9
+ const requestLogger = new RequestLogger(logger);
10
+ const feApiAbort = new FetchAbortPlugin();
11
+ const userToken = new UserToken({
12
+ storageKey: 'fe_user_token',
13
+ storage: localJsonStorage
14
+ });
15
+
16
+ container.bind(RequestLogger, requestLogger);
17
+ container.bind(FetchAbortPlugin, feApiAbort);
18
+ container.bind(UserToken, userToken);
19
+ }
20
+ }
@@ -0,0 +1,53 @@
1
+ import { IOCInterface, IOCRegisterInterface } from '@/base/port/IOCInterface';
2
+ import { localJsonStorage, logger } from '../globals';
3
+ import { RouterController } from '@/uikit/controllers/RouterController';
4
+ import { JSONStorageController } from '@/uikit/controllers/JSONStorageController';
5
+ import { RequestController } from '@/uikit/controllers/RequestController';
6
+ import { ProcesserService } from '@/services/processer/ProcesserService';
7
+ import { ExecutorController } from '@/uikit/controllers/ExecutorController';
8
+ import { UserController } from '@/uikit/controllers/UserController';
9
+ import { ThemeController } from '@lib/fe-react-theme/ThemeController';
10
+ import { RouteConfig } from '@/base/types/Page';
11
+ import { OpenAIClient } from '@lib/openAiApi';
12
+ import { FeApi } from '@/base/apis/feApi';
13
+
14
+ import appRouterConfig from '@config/app.router.json';
15
+ import themeConfigJson from '@config/theme.json';
16
+ import { UserToken } from '@/base/cases/UserToken';
17
+
18
+ export class RegisterControllers implements IOCRegisterInterface {
19
+ register(container: IOCInterface): void {
20
+ const routerController = new RouterController({
21
+ config: appRouterConfig.base as RouteConfig,
22
+ logger
23
+ });
24
+
25
+ const jsonStorageController = new JSONStorageController(localJsonStorage);
26
+ const requestController = new RequestController(
27
+ container.get(OpenAIClient),
28
+ container.get(FeApi)
29
+ );
30
+ const executorController = new ExecutorController(container.get(FeApi));
31
+ const userController = new UserController({
32
+ userToken: container.get(UserToken),
33
+ feApi: container.get(FeApi),
34
+ routerController
35
+ });
36
+ const themeController = new ThemeController({
37
+ ...themeConfigJson.override,
38
+ storage: localJsonStorage
39
+ });
40
+
41
+ const pageProcesser = new ProcesserService({
42
+ logger
43
+ }).usePlugin(userController);
44
+
45
+ container.bind(RouterController, routerController);
46
+ container.bind(JSONStorageController, jsonStorageController);
47
+ container.bind(RequestController, requestController);
48
+ container.bind(ExecutorController, executorController);
49
+ container.bind(UserController, userController);
50
+ container.bind(ThemeController, themeController);
51
+ container.bind(ProcesserService, pageProcesser);
52
+ }
53
+ }
@@ -0,0 +1,31 @@
1
+ // ! dont't import tsx, only ts file
2
+ import { ServiceIdentifier, IOCInterface } from '@/base/port/IOCInterface';
3
+
4
+ export type IOCFunction = {
5
+ <T>(serviceIdentifier: ServiceIdentifier<T>): T;
6
+ /**
7
+ * IOC container instance
8
+ */
9
+ implemention: IOCInterface | null;
10
+ /**
11
+ * implement IOC container
12
+ */
13
+ implement(container: IOCInterface): void;
14
+ };
15
+
16
+ export const IOC: IOCFunction = Object.assign(
17
+ function <T>(serviceIdentifier: ServiceIdentifier<T>): T {
18
+ if (!IOC.implemention) {
19
+ throw new Error('IOC is not implemented');
20
+ }
21
+ return IOC.implemention.get(serviceIdentifier);
22
+ },
23
+ {
24
+ implemention: null,
25
+ implement: (container: IOCInterface) => {
26
+ // FIXME: maybe runtimes configure
27
+ container.configure();
28
+ IOC.implemention = container;
29
+ }
30
+ }
31
+ );
@@ -1,15 +1,13 @@
1
- import { StrictMode } from 'react'
2
- import { createRoot } from 'react-dom/client'
3
- import App from './App.tsx'
4
- import * as feGlobals from '@/containers/globals';
1
+ import { StrictMode } from 'react';
2
+ import { createRoot } from 'react-dom/client';
3
+ import App from './App.tsx';
4
+ import { Bootstrap } from './core/bootstrap';
5
+ import { FeIOC } from './core/feIOC/FeIOC';
5
6
 
6
- // set global feGlobals
7
- if (typeof window !== 'undefined') {
8
- window.feGlobals = Object.freeze(Object.assign({}, feGlobals));
9
- }
7
+ new Bootstrap(new FeIOC()).start();
10
8
 
11
9
  createRoot(document.getElementById('root')!).render(
12
10
  <StrictMode>
13
11
  <App />
14
- </StrictMode>,
15
- )
12
+ </StrictMode>
13
+ );
@@ -1,4 +1,4 @@
1
- import { useBaseRoutePage } from '@/containers/context/BaseRouteContext';
1
+ import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
2
2
 
3
3
  export default function NotFound({ route }: { route?: string }) {
4
4
  const { t } = useBaseRoutePage();
@@ -6,7 +6,7 @@ export default function NotFound({ route }: { route?: string }) {
6
6
  <div className="flex flex-col justify-center min-h-screen py-6 bg-background sm:py-12">
7
7
  <div className="relative py-3 mx-auto sm:max-w-xl">
8
8
  <h1 className="text-primary text-2xl font-bold text-center">
9
- 404 - {route ? `${t('404.notComponent')}: ${route}` : t('404.notPage')}
9
+ 404 -{route ? `${t('404.notComponent')}: ${route}` : t('404.notPage')}
10
10
  </h1>
11
11
  </div>
12
12
  </div>
@@ -1,4 +1,4 @@
1
- import { useBaseRoutePage } from '@/containers/context/BaseRouteContext';
1
+ import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
2
2
 
3
3
  export default function NotFound500() {
4
4
  const { t } = useBaseRoutePage();
@@ -1,9 +1,10 @@
1
- import { userController } from '@/containers';
1
+ import { IOC } from '@/core';
2
+ import { UserController } from '@/uikit/controllers/UserController';
2
3
  import { useController } from '@lib/fe-react-controller';
3
4
  import { Navigate, Outlet } from 'react-router-dom';
4
5
 
5
6
  export default function Layout() {
6
- const controller = useController(userController);
7
+ const controller = useController(IOC(UserController));
7
8
 
8
9
  // If user is authenticated, redirect to home page
9
10
  if (controller.isAuthenticated()) {
@@ -1,12 +1,14 @@
1
1
  import { useState } from 'react';
2
2
  import { useController } from '@lib/fe-react-controller';
3
- import { routerController, userController } from '@/containers';
4
- import { useBaseRoutePage } from '@/containers/context/BaseRouteContext';
3
+ import { IOC } from '@/core';
4
+ import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
5
5
  import { defaultLoginInfo } from '@config/app.common';
6
+ import { RouterController } from '@/uikit/controllers/RouterController';
7
+ import { UserController } from '@/uikit/controllers/UserController';
6
8
 
7
9
  export default function Login() {
8
10
  const { t } = useBaseRoutePage();
9
- const controller = useController(userController);
11
+ const controller = useController(IOC(UserController));
10
12
  const [email, setEmail] = useState(defaultLoginInfo.name);
11
13
  const [password, setPassword] = useState(defaultLoginInfo.password);
12
14
  const [loading, setLoading] = useState(false);
@@ -16,7 +18,7 @@ export default function Login() {
16
18
  setLoading(true);
17
19
  await controller.login({ username: email, password });
18
20
  // Redirect or show success message
19
- routerController.replaceToHome();
21
+ IOC(RouterController).replaceToHome();
20
22
  } catch (error) {
21
23
  // Handle login error
22
24
  console.error(error);
@@ -1,4 +1,4 @@
1
- import { useBaseRoutePage } from '@/containers/context/BaseRouteContext';
1
+ import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
2
2
 
3
3
  export default function About() {
4
4
  const { t } = useBaseRoutePage();
@@ -1,9 +1,13 @@
1
- import { executorController, jsonStorageController } from '@/containers';
1
+ import { IOC } from '@/core';
2
2
  import { useControllerState } from '@lib/fe-react-controller';
3
- import { useBaseRoutePage } from '@/containers/context/BaseRouteContext';
3
+ import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
4
+ import { JSONStorageController } from '@/uikit/controllers/JSONStorageController';
5
+ import { ExecutorController } from '@/uikit/controllers/ExecutorController';
4
6
 
5
7
  export default function Executor() {
6
- const jsonStorageControllerState = useControllerState(jsonStorageController);
8
+ const jsonStorageControllerState = useControllerState(
9
+ IOC(JSONStorageController)
10
+ );
7
11
  const { t } = useBaseRoutePage();
8
12
 
9
13
  return (
@@ -26,7 +30,7 @@ export default function Executor() {
26
30
 
27
31
  <button
28
32
  className="bg-blue-500 text-white px-4 py-2 rounded-md"
29
- onClick={executorController.onTestPlugins}
33
+ onClick={IOC(ExecutorController).onTestPlugins}
30
34
  >
31
35
  {t('testPlugin')}
32
36
  </button>
@@ -1,5 +1,5 @@
1
1
  import LocaleLink from '@/components/LocaleLink';
2
- import { useBaseRoutePage } from '../../containers/context/BaseRouteContext';
2
+ import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
3
3
 
4
4
  export default function Home() {
5
5
  const { t } = useBaseRoutePage();
@@ -1,9 +1,11 @@
1
- import { jsonStorageController } from '@/containers';
1
+ import { IOC } from '@/core';
2
2
  import { useController, useControllerState } from '@lib/fe-react-controller';
3
- import { useBaseRoutePage } from '@/containers/context/BaseRouteContext';
3
+ import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
4
4
  import template from 'lodash/template';
5
+ import { JSONStorageController } from '@/uikit/controllers/JSONStorageController';
5
6
 
6
7
  export default function JSONStorage() {
8
+ const jsonStorageController = IOC(JSONStorageController);
7
9
  const controllerState = useControllerState(
8
10
  useController(jsonStorageController)
9
11
  );
@@ -28,7 +30,7 @@ export default function JSONStorage() {
28
30
  {template(t('format.title'))({
29
31
  key: 'testKey1',
30
32
  min: 100,
31
- max: 9000,
33
+ max: 9000
32
34
  })}
33
35
  </div>
34
36
 
@@ -58,7 +60,7 @@ export default function JSONStorage() {
58
60
  {template(t('format.title'))({
59
61
  key: 'testKey2',
60
62
  min: 100,
61
- max: 9000,
63
+ max: 9000
62
64
  })}
63
65
  </div>
64
66
 
@@ -1,6 +1,6 @@
1
1
  import BaseHeader from './components/BaseHeader';
2
2
  import { Outlet } from 'react-router-dom';
3
- import { ProcessProvider } from '@/components/ProcessProvider';
3
+ import { ProcessProvider } from '@/uikit/providers/ProcessProvider';
4
4
 
5
5
  export default function Layout() {
6
6
  return (
@@ -12,4 +12,4 @@ const RedirectToDefault = () => {
12
12
  return null;
13
13
  };
14
14
 
15
- export default RedirectToDefault;
15
+ export default RedirectToDefault;
@@ -1,10 +1,15 @@
1
- import { jsonStorageController, requestController } from '@/containers';
1
+ import { IOC } from '@/core';
2
2
  import { useControllerState } from '@lib/fe-react-controller';
3
- import { useBaseRoutePage } from '../../containers/context/BaseRouteContext';
3
+ import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
4
+ import { JSONStorageController } from '@/uikit/controllers/JSONStorageController';
5
+ import { RequestController } from '@/uikit/controllers/RequestController';
4
6
 
5
7
  export default function Request() {
8
+ const requestController = IOC(RequestController);
6
9
  const requestControllerState = useControllerState(requestController);
7
- const jsonStorageControllerState = useControllerState(jsonStorageController);
10
+ const jsonStorageControllerState = useControllerState(
11
+ IOC(JSONStorageController)
12
+ );
8
13
  const { t } = useBaseRoutePage();
9
14
 
10
15
  return (
@@ -1,8 +1,13 @@
1
1
  import { lazy, Suspense } from 'react';
2
2
  import isString from 'lodash/isString';
3
- import { LoadProps, PagesMaps, RouteCategory, RouteType } from '@/types/Page';
3
+ import {
4
+ LoadProps,
5
+ PagesMaps,
6
+ RouteCategory,
7
+ RouteType
8
+ } from '@/base/types/Page';
4
9
  import { Loading } from '@/components/Loading';
5
- import BaseRouteProvider from '../containers/context/BaseRouteProvider';
10
+ import BaseRouteProvider from '../uikit/providers/BaseRouteProvider';
6
11
  import NotFound from './404';
7
12
  import NotFound500 from './500';
8
13
 
@@ -1,12 +1,12 @@
1
1
  import { AsyncExecutor, ExecutorPlugin, Logger } from '@qlover/fe-utils';
2
2
 
3
- export interface PageProcesserOptions {
3
+ export interface ProcesserServiceOptions {
4
4
  logger: Logger;
5
5
  }
6
6
 
7
- export class PageProcesser {
7
+ export class ProcesserService {
8
8
  private executor: AsyncExecutor;
9
- constructor(private options: PageProcesserOptions) {
9
+ constructor(private options: ProcesserServiceOptions) {
10
10
  this.executor = new AsyncExecutor();
11
11
  }
12
12
 
@@ -1,7 +1,7 @@
1
1
  import { useTranslation } from 'react-i18next';
2
- import { useContext } from 'react';
3
- import { BasePageProvider } from '@/types/Page';
4
- import { RouteMeta } from '@/types/Page';
2
+ import { useContext, useMemo } from 'react';
3
+ import { BasePageProvider } from '@/base/types/Page';
4
+ import { RouteMeta } from '@/base/types/Page';
5
5
  import { createContext } from 'react';
6
6
  import { defaultBaseRoutemeta } from '@config/app.common';
7
7
  import merge from 'lodash/merge';
@@ -15,7 +15,7 @@ export function useBaseRoutePage(): BasePageProvider {
15
15
  throw new Error('useBaseRoutePage must be used within a PageProvider');
16
16
  }
17
17
 
18
- const _meta = merge({}, defaultBaseRoutemeta, meta);
18
+ const _meta = useMemo(() => merge({}, defaultBaseRoutemeta, meta), [meta]);
19
19
 
20
20
  const i18n = useTranslation(_meta.localNamespace);
21
21
 
@@ -1,11 +1,11 @@
1
1
  import { FeController } from '@lib/fe-react-controller';
2
- import { FeApi } from '@/services/feApi';
2
+ import { FeApi } from '@/base/apis/feApi';
3
3
  import cloneDeep from 'lodash/cloneDeep';
4
4
  import {
5
5
  ExecutorPlugin,
6
- RequestAdapterResponse
7
- } from 'packages/fe-utils/interface';
8
- import { RequestAdapterFetchConfig } from '@qlover/fe-utils';
6
+ RequestAdapterResponse,
7
+ RequestAdapterFetchConfig
8
+ } from '@qlover/fe-utils';
9
9
 
10
10
  function createDefaultState() {
11
11
  return {
@@ -37,7 +37,7 @@ export class ExecutorController extends FeController<ExecutorControllerState> {
37
37
  private feApi: FeApi;
38
38
 
39
39
  constructor(feApi: FeApi) {
40
- super(createDefaultState());
40
+ super(createDefaultState);
41
41
 
42
42
  this.feApi = cloneDeep(feApi);
43
43
 
@@ -11,12 +11,12 @@ interface JSONStoragePageState {
11
11
 
12
12
  export class JSONStorageController extends FeController<JSONStoragePageState> {
13
13
  constructor(private storage: JSONStorage) {
14
- super({
14
+ super(() => ({
15
15
  testKey1: storage.getItem('testKey1') ?? 0,
16
16
  testKey2: storage.getItem('testKey2') ?? 0,
17
17
  expireTime: 5000,
18
18
  requestTimeout: storage.getItem('requestTimeout') ?? 5000
19
- });
19
+ }));
20
20
  }
21
21
 
22
22
  changeRandomTestKey1 = (): void => {
@@ -1,7 +1,7 @@
1
1
  import { OpenAIClient } from '@lib/openAiApi/OpenAIClient';
2
2
  import { FeController } from '@lib/fe-react-controller';
3
- import { FeApi } from '@/services/feApi';
4
- import { logger } from '@/containers/globals';
3
+ import { FeApi } from '@/base/apis/feApi';
4
+ import { logger } from '@/core/globals';
5
5
 
6
6
  function createDefaultState() {
7
7
  return {
@@ -35,7 +35,7 @@ export class RequestController extends FeController<RequestControllerState> {
35
35
  private readonly aiApi: OpenAIClient,
36
36
  private readonly feApi: FeApi
37
37
  ) {
38
- super(createDefaultState());
38
+ super(createDefaultState);
39
39
  }
40
40
 
41
41
  onHello = async () => {
@@ -1,6 +1,6 @@
1
1
  import { I18nService } from '@/services/i18n';
2
- import { RouteConfig, RouteType } from '@/types/Page';
3
- import { UIDependenciesInterface } from '@/types/UIDependenciesInterface';
2
+ import { RouteConfig, RouteType } from '@/base/types/Page';
3
+ import { UIDependenciesInterface } from '@/base/port/UIDependenciesInterface';
4
4
  import { i18nConfig } from '@config/i18n';
5
5
  import { Logger } from '@qlover/fe-utils';
6
6
  import { NavigateFunction, NavigateOptions } from 'react-router-dom';
@@ -1,10 +1,10 @@
1
- import { ExecutorPlugin, JSONStorage } from '@qlover/fe-utils';
2
- import { sleep } from '@/utils/thread';
1
+ import { ExecutorPlugin } from '@qlover/fe-utils';
2
+ import { sleep } from '@/uikit/utils/thread';
3
3
  import { FeController } from '@lib/fe-react-controller';
4
- import { FeApi } from '@/services/feApi';
5
- import { FeApiGetUserInfo, FeApiLogin } from '@/services/feApi/FeApiType';
6
- import { adjustExpirationTime } from '@/utils/datetime';
4
+ import { FeApi } from '@/base/apis/feApi';
5
+ import { FeApiGetUserInfo, FeApiLogin } from '@/base/apis/feApi/FeApiType';
7
6
  import { RouterController } from './RouterController';
7
+ import { StorageTokenInterface } from '@/base/port/StorageTokenInterface';
8
8
 
9
9
  export interface UserControllerState {
10
10
  success: boolean;
@@ -12,12 +12,7 @@ export interface UserControllerState {
12
12
  }
13
13
 
14
14
  export interface UserControllerOptions {
15
- /**
16
- * @default `month`
17
- */
18
- expiresIn?: number | 'day' | 'week' | 'month' | 'year';
19
- storageKey: string;
20
- storage: JSONStorage;
15
+ userToken: StorageTokenInterface;
21
16
  feApi: FeApi;
22
17
  routerController: RouterController;
23
18
  }
@@ -29,23 +24,19 @@ interface LoginInterface {
29
24
  logout(): void;
30
25
  }
31
26
 
32
- function restoreUserSession(options: UserControllerOptions): {
33
- state: UserControllerState;
34
- token: string;
35
- } {
36
- const { storageKey, storage } = options;
37
- const token = storage.getItem(storageKey, '') as string;
27
+ function createDefaultState(
28
+ options: UserControllerOptions
29
+ ): UserControllerState {
30
+ const { userToken } = options;
31
+ const token = userToken.getToken();
38
32
 
39
33
  return {
40
- state: {
41
- success: !!token,
42
- userInfo: {
43
- name: '',
44
- email: '',
45
- picture: ''
46
- }
47
- },
48
- token
34
+ success: !!token,
35
+ userInfo: {
36
+ name: '',
37
+ email: '',
38
+ picture: ''
39
+ }
49
40
  };
50
41
  }
51
42
 
@@ -55,24 +46,17 @@ export class UserController
55
46
  {
56
47
  readonly pluginName = 'UserController';
57
48
 
58
- private token = '';
59
-
60
49
  constructor(private options: UserControllerOptions) {
61
- const restoreSession = restoreUserSession(options);
62
- super(restoreSession.state);
63
-
64
- this.token = restoreSession.token;
50
+ super(() => createDefaultState(options));
65
51
  }
66
52
 
67
- selectorSuccess = (state: UserControllerState): boolean => state.success;
68
-
69
53
  /**
70
54
  * @override
71
55
  */
72
56
  async onBefore(): Promise<void> {
73
57
  await sleep(1000);
74
58
 
75
- if (!this.token) {
59
+ if (!this.options.userToken.getToken()) {
76
60
  throw new Error('User not logged in');
77
61
  }
78
62
 
@@ -103,7 +87,7 @@ export class UserController
103
87
 
104
88
  const result = await feApi.login(params);
105
89
 
106
- this.setToken(result.data.token);
90
+ this.options.userToken.setToken(result.data.token);
107
91
 
108
92
  const userInfo = await feApi.getUserInfo();
109
93
 
@@ -122,22 +106,12 @@ export class UserController
122
106
  this.reset();
123
107
  }
124
108
 
125
- setToken(token: string): void {
126
- this.token = token;
127
-
128
- const { storageKey, storage } = this.options;
129
-
130
- storage.setItem(
131
- storageKey,
132
- this.token,
133
- adjustExpirationTime(Date.now(), this.options.expiresIn ?? 'month')
134
- );
135
- }
136
-
109
+ /**
110
+ * @override
111
+ */
137
112
  reset(): void {
138
- this.token = '';
139
- this.options.storage.removeItem(this.options.storageKey);
140
- this.setState({ success: false });
113
+ this.options.userToken.removeToken();
114
+ super.reset();
141
115
  }
142
116
 
143
117
  isAuthenticated(): boolean {
@@ -1,6 +1,6 @@
1
1
  import { PropsWithChildren } from 'react';
2
- import { RouteMeta } from '@/types/Page';
3
- import { BaseRoutePageContext } from './BaseRouteContext';
2
+ import { RouteMeta } from '@/base/types/Page';
3
+ import { BaseRoutePageContext } from '../contexts/BaseRouteContext';
4
4
 
5
5
  export default function BaseRouteProvider(props: PropsWithChildren<RouteMeta>) {
6
6
  return (
@@ -1,16 +1,22 @@
1
1
  import { createContext, useEffect } from 'react';
2
- import { pageProcesser, routerController, userController } from '@/containers';
3
- import { useLanguageGuard } from '@/hooks/useLanguageGuard';
4
- import { useStrictEffect } from '@/hooks/useStrictEffect';
5
- import { PageProcesser } from '@/services/pageProcesser';
2
+ import { IOC } from '@/core';
3
+ import { useLanguageGuard } from '@/uikit/hooks/useLanguageGuard';
4
+ import { useStrictEffect } from '@/uikit/hooks/useStrictEffect';
5
+ import { ProcesserService } from '@/services/processer/ProcesserService';
6
6
  import { Navigate, useNavigate } from 'react-router-dom';
7
7
  import { useControllerState } from '@lib/fe-react-controller';
8
- import { Loading } from './Loading';
8
+ import { Loading } from '@/components/Loading';
9
+ import { RouterController } from '../controllers/RouterController';
10
+ import { UserController } from '../controllers/UserController';
9
11
 
10
- const PageProcesserContext = createContext<PageProcesser>(pageProcesser);
12
+ const PageProcesserContext = createContext<ProcesserService>(
13
+ IOC(ProcesserService)
14
+ );
11
15
 
12
16
  export function ProcessProvider({ children }: { children: React.ReactNode }) {
13
17
  useLanguageGuard();
18
+ const userController = IOC(UserController);
19
+ const pageProcesser = IOC(ProcesserService);
14
20
  const { success } = useControllerState(userController);
15
21
 
16
22
  const navigate = useNavigate();
@@ -20,7 +26,7 @@ export function ProcessProvider({ children }: { children: React.ReactNode }) {
20
26
  }, []);
21
27
 
22
28
  useEffect(() => {
23
- routerController.setDependencies({
29
+ IOC(RouterController).setDependencies({
24
30
  navigate
25
31
  });
26
32
  }, [navigate]);