@qlover/create-app 0.1.11 → 0.1.14

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 (67) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/bin/create-app.js +0 -0
  3. package/dist/index.cjs +3631 -0
  4. package/dist/{cjs/index.d.ts → index.d.ts} +3 -2
  5. package/dist/index.js +3625 -0
  6. package/package.json +17 -16
  7. package/templates/node-lib/bin/test.js +1 -1
  8. package/templates/node-lib/package.json +2 -2
  9. package/templates/node-lib/rollup.config.js +1 -2
  10. package/templates/pack-app/package.json +1 -1
  11. package/templates/react-app/.env +23 -2
  12. package/templates/react-app/.env.local +24 -0
  13. package/templates/react-app/config/common.ts +3 -0
  14. package/templates/react-app/lib/bootstrap/Bootstrap.ts +36 -0
  15. package/templates/react-app/lib/bootstrap/BootstrapExecutorPlugin.ts +20 -0
  16. package/templates/react-app/lib/bootstrap/IOCContainerInterface.ts +33 -0
  17. package/templates/react-app/lib/bootstrap/IOCManagerInterface.ts +12 -0
  18. package/templates/react-app/lib/bootstrap/index.ts +7 -0
  19. package/templates/react-app/lib/bootstrap/plugins/InjectEnv.ts +61 -0
  20. package/templates/react-app/lib/bootstrap/plugins/InjectGlobal.ts +36 -0
  21. package/templates/react-app/lib/bootstrap/plugins/InjectIOC.ts +24 -0
  22. package/templates/react-app/lib/env-config/injectPkgConfig.ts +11 -0
  23. package/templates/react-app/lib/openAiApi/OpenAIClient.ts +1 -1
  24. package/templates/react-app/lib/router-loader/Page.ts +8 -4
  25. package/templates/react-app/lib/router-loader/RouterLoader.ts +1 -1
  26. package/templates/react-app/package.json +3 -1
  27. package/templates/react-app/pnpm-lock.yaml +5892 -0
  28. package/templates/react-app/src/base/consts/IOCIdentifier.ts +16 -0
  29. package/templates/react-app/src/base/port/IOCFunctionInterface.ts +39 -0
  30. package/templates/react-app/src/base/port/InversifyIocInterface.ts +9 -0
  31. package/templates/react-app/src/base/port/StorageTokenInterface.ts +22 -0
  32. package/templates/react-app/src/base/types/Page.ts +4 -13
  33. package/templates/react-app/src/base/types/global.d.ts +2 -1
  34. package/templates/react-app/src/components/ThemeSwitcher.tsx +1 -1
  35. package/templates/react-app/src/core/AppConfig.ts +27 -0
  36. package/templates/react-app/src/core/AppIOCContainer.ts +30 -0
  37. package/templates/react-app/src/core/IOC.ts +48 -0
  38. package/templates/react-app/src/core/bootstrap.ts +59 -14
  39. package/templates/react-app/src/core/globals.ts +1 -1
  40. package/templates/react-app/src/core/registers/RegisterApi.ts +59 -0
  41. package/templates/react-app/src/core/registers/RegisterCommon.ts +21 -0
  42. package/templates/react-app/src/core/{feIOC → registers}/RegisterControllers.ts +16 -11
  43. package/templates/react-app/src/core/registers/RegisterGlobals.ts +20 -0
  44. package/templates/react-app/src/core/registers/index.ts +17 -0
  45. package/templates/react-app/src/main.tsx +4 -3
  46. package/templates/react-app/src/pages/auth/Layout.tsx +1 -1
  47. package/templates/react-app/src/pages/auth/Login.tsx +4 -4
  48. package/templates/react-app/src/pages/base/Executor.tsx +1 -1
  49. package/templates/react-app/src/pages/base/JSONStorage.tsx +1 -1
  50. package/templates/react-app/src/pages/base/Request.tsx +1 -1
  51. package/templates/react-app/src/services/I18nService.ts +18 -14
  52. package/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +7 -1
  53. package/templates/react-app/src/uikit/providers/ProcessProvider.tsx +1 -1
  54. package/templates/react-app/src/uikit/utils/RequestLogger.ts +4 -1
  55. package/templates/react-app/tsconfig.json +2 -1
  56. package/templates/react-app/tsconfig.node.json +6 -2
  57. package/templates/react-app/vite.config.ts +14 -0
  58. package/configs/_common/.release-it.json.template +0 -42
  59. package/dist/cjs/index.js +0 -1
  60. package/dist/es/index.d.ts +0 -112
  61. package/dist/es/index.js +0 -1
  62. package/templates/react-app/config/app.common.ts +0 -52
  63. package/templates/react-app/src/base/port/IOCInterface.ts +0 -53
  64. package/templates/react-app/src/core/feIOC/FeIOC.ts +0 -32
  65. package/templates/react-app/src/core/feIOC/RegisterApi.ts +0 -41
  66. package/templates/react-app/src/core/feIOC/RegisterCommon.ts +0 -20
  67. package/templates/react-app/src/core/index.ts +0 -31
@@ -0,0 +1,16 @@
1
+ /**
2
+ * IOC identifier
3
+ *
4
+ * @description
5
+ * IOC identifier is used to identify the service in the IOC container.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * const a = IOC(IOCIdentifier.JSON);
10
+ * ```
11
+ */
12
+ export const IOCIdentifier = Object.freeze({
13
+ JSON: 'JSON',
14
+ JSONStorage: 'JSONStorage',
15
+ Logger: 'Logger'
16
+ });
@@ -0,0 +1,39 @@
1
+ import type { IOCManagerInterface } from '@lib/bootstrap';
2
+ import type { JSONSerializer, JSONStorage, Logger } from '@qlover/fe-utils';
3
+ import type { ServiceIdentifier } from 'inversify';
4
+ import type { IOCIdentifier } from '@/base/consts/IOCIdentifier';
5
+
6
+ export type IOCIdentifierMap = {
7
+ [IOCIdentifier.JSON]: JSONSerializer;
8
+ [IOCIdentifier.JSONStorage]: JSONStorage;
9
+ [IOCIdentifier.Logger]: Logger;
10
+ };
11
+
12
+ /**
13
+ * IOC function
14
+ *
15
+ * eg.
16
+ * ```ts
17
+ * const a = IOC(A);
18
+ * const logger = IOC(ConstanstIdentifier.Logger);
19
+ * ```
20
+ *
21
+ */
22
+ export interface IOCFunctionInterface extends IOCManagerInterface {
23
+ /**
24
+ * get constant identifier
25
+ *
26
+ * Preferred match for simple types
27
+ */
28
+ <K extends keyof IOCIdentifierMap>(serviceIdentifier: K): IOCIdentifierMap[K];
29
+
30
+ /**
31
+ * get service identifier
32
+ */
33
+ <T>(serviceIdentifier: ServiceIdentifier<T>): T;
34
+
35
+ get<K extends keyof IOCIdentifierMap>(
36
+ serviceIdentifier: K
37
+ ): IOCIdentifierMap[K];
38
+ get<T>(serviceIdentifier: ServiceIdentifier<T>): T;
39
+ }
@@ -0,0 +1,9 @@
1
+ import type { IOCRegisterInterface } from '@lib/bootstrap';
2
+ import type { Container } from 'inversify';
3
+
4
+ export type InversifyRegisterContainer = Container;
5
+ /**
6
+ * Inversify register interface.
7
+ */
8
+ export interface InversifyRegisterInterface
9
+ extends IOCRegisterInterface<InversifyRegisterContainer> {}
@@ -1,5 +1,27 @@
1
+ /**
2
+ * Storage token interface
3
+ *
4
+ * @description
5
+ * Storage token interface is used to store and retrieve token from the storage.
6
+ */
1
7
  export interface StorageTokenInterface {
8
+ /**
9
+ * Get token
10
+ *
11
+ * @returns {string} token
12
+ */
2
13
  getToken(): string;
14
+
15
+ /**
16
+ * Set token
17
+ *
18
+ * @param {string} token
19
+ * @param {number} expireTime
20
+ */
3
21
  setToken(token: string, expireTime?: number): void;
22
+
23
+ /**
24
+ * Remove token
25
+ */
4
26
  removeToken(): void;
5
27
  }
@@ -1,9 +1,7 @@
1
- import { LazyExoticComponent, PropsWithChildren } from 'react';
2
- import { RouteObject } from 'react-router-dom';
3
-
4
- import { TFunction } from 'i18next';
5
- import { UseTranslationResponse } from 'react-i18next';
6
- import { RouteConfigValue } from '@lib/router-loader/RouterLoader';
1
+ import type { LazyExoticComponent, PropsWithChildren } from 'react';
2
+ import type { TFunction } from 'i18next';
3
+ import type { UseTranslationResponse } from 'react-i18next';
4
+ import type { RouteConfigValue } from '@lib/router-loader/RouterLoader';
7
5
 
8
6
  export interface BasePageProvider {
9
7
  meta: RouteMeta;
@@ -37,10 +35,3 @@ export type PagesMaps = Record<
37
35
  | (() => LazyExoticComponent<React.ComponentType<unknown>>)
38
36
  | (() => React.ComponentType<unknown>)
39
37
  >;
40
-
41
- export type LoadProps = {
42
- pagesMaps: PagesMaps;
43
- componentPath: string;
44
- route: RouteType;
45
- Provider?: React.ComponentType<PropsWithChildren<RouteMeta>>;
46
- };
@@ -1,7 +1,8 @@
1
1
  import * as feGlobals from '@/core/globals';
2
+ import type { browserGlobalsName } from '@config/common';
2
3
 
3
4
  declare global {
4
5
  interface Window {
5
- feGlobals: Readonly<typeof feGlobals>;
6
+ [browserGlobalsName]: Readonly<typeof feGlobals>;
6
7
  }
7
8
  }
@@ -1,4 +1,4 @@
1
- import { IOC } from '@/core';
1
+ import { IOC } from '@/core/IOC';
2
2
  import { useController } from '@lib/fe-react-controller';
3
3
  import { ThemeController } from '@lib/fe-react-theme/ThemeController';
4
4
  import { useTranslation } from 'react-i18next';
@@ -0,0 +1,27 @@
1
+ import type { EnvConfigInterface } from '@lib/bootstrap';
2
+
3
+ class AppConfig implements EnvConfigInterface {
4
+ readonly appName = '';
5
+ readonly appVersion = '';
6
+ /**
7
+ * vite mode
8
+ */
9
+ readonly env = import.meta.env.VITE_USER_NODE_ENV;
10
+
11
+ readonly userTokenStorageKey = 'fe_user_token';
12
+ readonly openAiModels = [
13
+ 'gpt-4o-mini',
14
+ 'gpt-3.5-turbo',
15
+ 'gpt-3.5-turbo-2',
16
+ 'gpt-4',
17
+ 'gpt-4-32k'
18
+ ];
19
+ readonly openAiBaseUrl = '';
20
+ readonly openAiToken = '';
21
+ readonly openAiTokenPrefix = '';
22
+ readonly openAiRequireToken = true;
23
+ readonly loginUser = '';
24
+ readonly loginPassword = '';
25
+ }
26
+
27
+ export default new AppConfig();
@@ -0,0 +1,30 @@
1
+ import type { InversifyRegisterInterface } from '@/base/port/InversifyIocInterface';
2
+ import type { IOCContainerInterface } from '@lib/bootstrap';
3
+ import { ServiceIdentifier, Container } from 'inversify';
4
+
5
+ export class AppIOCContainer implements IOCContainerInterface {
6
+ private container: Container;
7
+
8
+ constructor() {
9
+ this.container = new Container({
10
+ // allow `@injectable` decorator, auto bind injectable classes
11
+ autobind: true,
12
+ // use singleton scope
13
+ defaultScope: 'Singleton'
14
+ });
15
+ }
16
+
17
+ configure(registers?: InversifyRegisterInterface[]): void {
18
+ if (registers) {
19
+ registers.forEach((register) => register.register(this.container, this));
20
+ }
21
+ }
22
+
23
+ bind<T>(key: ServiceIdentifier<T>, value: T): void {
24
+ this.container.bind<T>(key).toConstantValue(value);
25
+ }
26
+
27
+ get<T>(key: string): T {
28
+ return this.container.get<T>(key);
29
+ }
30
+ }
@@ -0,0 +1,48 @@
1
+ // ! dont't import tsx, only ts file
2
+ import type { IOCContainerInterface } from '@lib/bootstrap';
3
+ import type {
4
+ IOCIdentifierMap,
5
+ IOCFunctionInterface
6
+ } from '@/base/port/IOCFunctionInterface';
7
+ import type { ServiceIdentifier } from 'inversify';
8
+
9
+ let implemention: IOCContainerInterface | null;
10
+
11
+ function ioc<T>(serviceIdentifier: ServiceIdentifier<T>): T;
12
+ function ioc<K extends keyof IOCIdentifierMap>(
13
+ serviceIdentifier: K
14
+ ): IOCIdentifierMap[K];
15
+ function ioc<T, K extends keyof IOCIdentifierMap>(
16
+ serviceIdentifier: ServiceIdentifier<T> | K
17
+ ): T | IOCIdentifierMap[K] {
18
+ if (!implemention) {
19
+ throw new Error('IOC is not implemented');
20
+ }
21
+ return implemention.get(serviceIdentifier);
22
+ }
23
+
24
+ /**
25
+ * IOC manager function.
26
+ *
27
+ * eg.
28
+ * ```ts
29
+ * class A {}
30
+ * const a = IOC(A);
31
+ * ```
32
+ *
33
+ * or
34
+ * ```ts
35
+ * const a = IOC<A>();
36
+ * ```
37
+ *
38
+ * or use get(),
39
+ */
40
+ export const IOC: IOCFunctionInterface = Object.assign(ioc, {
41
+ get implemention() {
42
+ return implemention;
43
+ },
44
+ implement: (container: IOCContainerInterface) => {
45
+ implemention = container;
46
+ },
47
+ get: ioc
48
+ });
@@ -1,21 +1,66 @@
1
- import * as feGlobals from '@/core/globals';
2
- import { IOC } from '.';
3
- import { IOCInterface } from '@/base/port/IOCInterface';
1
+ import {
2
+ Bootstrap,
3
+ BootstrapExecutorPlugin,
4
+ InjectEnv,
5
+ InjectIOC,
6
+ InjectGlobal
7
+ } from '@lib/bootstrap';
8
+ import { AppIOCContainer } from '@/core/AppIOCContainer';
9
+ import AppConfig from '@/core/AppConfig';
10
+ import { envPrefix, browserGlobalsName } from '@config/common';
11
+ import { IOC } from './IOC';
12
+ import * as globals from '@/core/globals';
4
13
  import { I18nService } from '@/services/I18nService';
14
+ import { registerList } from './registers';
5
15
 
6
- export class Bootstrap {
7
- constructor(private IOCContainer: IOCInterface) {}
16
+ /**
17
+ * Bootstrap
18
+ *
19
+ * 1. inject env config to AppConfig
20
+ * 2. inject IOC to Application
21
+ * 3. inject globals to window
22
+ *
23
+ */
24
+ export default function startup(root: typeof globalThis) {
25
+ const window =
26
+ typeof root !== 'undefined' && root instanceof Window ? root : undefined;
8
27
 
9
- start(): void {
10
- // set global feGlobals
11
- if (typeof window !== 'undefined') {
12
- window.feGlobals = Object.freeze(Object.assign({}, feGlobals));
13
- }
28
+ if (!window) {
29
+ throw new Error('Not Found Window');
30
+ }
31
+
32
+ const bootstrap = new Bootstrap(new AppIOCContainer());
14
33
 
15
- // startup IOC
16
- IOC.implement(this.IOCContainer);
34
+ /**
35
+ * bootstrap start list
36
+ *
37
+ * - inject env config to AppConfig
38
+ * - inject IOC to Application
39
+ * - inject globals to window
40
+ * - inject i18n service to Application
41
+ */
42
+ const bootstrapList: BootstrapExecutorPlugin[] = [
43
+ new InjectEnv(AppConfig, import.meta.env, envPrefix),
44
+ new InjectIOC(IOC, registerList),
45
+ new InjectGlobal(globals, browserGlobalsName),
46
+ new I18nService(window.location.pathname)
47
+ ];
48
+
49
+ if (AppConfig.env !== 'production') {
50
+ bootstrapList.push({
51
+ pluginName: 'InjectDevTools',
52
+ onBefore() {
53
+ console.log(AppConfig);
54
+ },
55
+ onError({ error }) {
56
+ console.error(`${AppConfig.appName} starup error:`, error);
57
+ }
58
+ });
59
+ }
17
60
 
18
- // startup i18n
19
- I18nService.init();
61
+ try {
62
+ bootstrap.use(bootstrapList).start(root);
63
+ } catch (error) {
64
+ console.error(`${AppConfig.appName} starup error:`, error);
20
65
  }
21
66
  }
@@ -6,7 +6,7 @@ import {
6
6
  SyncStorage
7
7
  } from '@qlover/fe-utils';
8
8
 
9
- export const env = import.meta.env.VITE_NODE_ENV;
9
+ export const env = import.meta.env.VITE_USER_NODE_ENV;
10
10
  export const isProduction = env === 'production';
11
11
 
12
12
  /**
@@ -0,0 +1,59 @@
1
+ import type {
2
+ InversifyRegisterInterface,
3
+ InversifyRegisterContainer
4
+ } from '@/base/port/InversifyIocInterface';
5
+
6
+ import { RequestLogger } from '@/uikit/utils/RequestLogger';
7
+ import { localJsonStorage } from '../globals';
8
+ import { FetchAbortPlugin, FetchURLPlugin } from '@qlover/fe-utils';
9
+ import { FeApiMockPlugin } from '@/base/apis/feApi';
10
+ import { OpenAIClient } from '@lib/openAiApi';
11
+ import { FeApi } from '@/base/apis/feApi';
12
+ import { RequestCommonPlugin } from '@lib/request-common-plugin';
13
+ import mockDataJson from '@config/feapi.mock.json';
14
+ import AppConfig from '@/core/AppConfig';
15
+
16
+ export class RegisterApi implements InversifyRegisterInterface {
17
+ register(container: InversifyRegisterContainer): void {
18
+ const openAiApi = new OpenAIClient({
19
+ baseURL: AppConfig.openAiBaseUrl,
20
+ models: AppConfig.openAiModels,
21
+ commonPluginConfig: {
22
+ tokenPrefix: AppConfig.openAiTokenPrefix,
23
+ token: AppConfig.openAiToken,
24
+ defaultHeaders: {
25
+ 'Content-Type': 'application/json'
26
+ },
27
+ defaultRequestData: {
28
+ model: AppConfig.openAiModels[0],
29
+ stream: true
30
+ },
31
+ requiredToken: true,
32
+ requestDataSerializer: (data) => JSON.stringify(data)
33
+ }
34
+ }).usePlugin(container.get(RequestLogger));
35
+
36
+ const abortPlugin = container.get(FetchAbortPlugin);
37
+ const feApi = new FeApi({
38
+ abortPlugin,
39
+ config: {
40
+ responseType: 'json',
41
+ baseURL: 'https://api.example.com/'
42
+ }
43
+ })
44
+ .usePlugin(new FetchURLPlugin())
45
+ .usePlugin(
46
+ new RequestCommonPlugin({
47
+ tokenPrefix: AppConfig.openAiTokenPrefix,
48
+ requiredToken: true,
49
+ token: () => localJsonStorage.getItem('fe_user_token')
50
+ })
51
+ )
52
+ .usePlugin(new FeApiMockPlugin(mockDataJson))
53
+ .usePlugin(container.get(RequestLogger))
54
+ .usePlugin(abortPlugin);
55
+
56
+ container.bind(OpenAIClient).toConstantValue(openAiApi);
57
+ container.bind(FeApi).toConstantValue(feApi);
58
+ }
59
+ }
@@ -0,0 +1,21 @@
1
+ import type {
2
+ InversifyRegisterInterface,
3
+ InversifyRegisterContainer
4
+ } from '@/base/port/InversifyIocInterface';
5
+
6
+ import { FetchAbortPlugin, JSONStorage } from '@qlover/fe-utils';
7
+ import { UserToken } from '@/base/cases/UserToken';
8
+ import AppConfig from '@/core/AppConfig';
9
+
10
+ export class RegisterCommon implements InversifyRegisterInterface {
11
+ register(container: InversifyRegisterContainer): void {
12
+ const feApiAbort = new FetchAbortPlugin();
13
+ const userToken = new UserToken({
14
+ storageKey: AppConfig.userTokenStorageKey,
15
+ storage: container.get(JSONStorage)
16
+ });
17
+
18
+ container.bind(FetchAbortPlugin).toConstantValue(feApiAbort);
19
+ container.bind(UserToken).toConstantValue(userToken);
20
+ }
21
+ }
@@ -1,4 +1,8 @@
1
- import { IOCInterface, IOCRegisterInterface } from '@/base/port/IOCInterface';
1
+ import type {
2
+ InversifyRegisterInterface,
3
+ InversifyRegisterContainer
4
+ } from '@/base/port/InversifyIocInterface';
5
+
2
6
  import { localJsonStorage, logger } from '../globals';
3
7
  import { RouterController } from '@/uikit/controllers/RouterController';
4
8
  import { JSONStorageController } from '@/uikit/controllers/JSONStorageController';
@@ -10,13 +14,12 @@ import { ThemeController } from '@lib/fe-react-theme/ThemeController';
10
14
  import { RouteConfig } from '@/base/types/Page';
11
15
  import { OpenAIClient } from '@lib/openAiApi';
12
16
  import { FeApi } from '@/base/apis/feApi';
13
-
14
17
  import appRouterConfig from '@config/app.router.json';
15
18
  import themeConfigJson from '@config/theme.json';
16
19
  import { UserToken } from '@/base/cases/UserToken';
17
20
 
18
- export class RegisterControllers implements IOCRegisterInterface {
19
- register(container: IOCInterface): void {
21
+ export class RegisterControllers implements InversifyRegisterInterface {
22
+ register(container: InversifyRegisterContainer): void {
20
23
  const routerController = new RouterController({
21
24
  config: appRouterConfig.base as RouteConfig,
22
25
  logger
@@ -42,12 +45,14 @@ export class RegisterControllers implements IOCRegisterInterface {
42
45
  logger
43
46
  }).usePlugin(userController);
44
47
 
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);
48
+ container.bind(RouterController).toConstantValue(routerController);
49
+ container
50
+ .bind(JSONStorageController)
51
+ .toConstantValue(jsonStorageController);
52
+ container.bind(RequestController).toConstantValue(requestController);
53
+ container.bind(ExecutorController).toConstantValue(executorController);
54
+ container.bind(UserController).toConstantValue(userController);
55
+ container.bind(ThemeController).toConstantValue(themeController);
56
+ container.bind(ProcesserService).toConstantValue(pageProcesser);
52
57
  }
53
58
  }
@@ -0,0 +1,20 @@
1
+ import type {
2
+ InversifyRegisterInterface,
3
+ InversifyRegisterContainer
4
+ } from '@/base/port/InversifyIocInterface';
5
+ import { JSON, localJsonStorage, logger } from '../globals';
6
+ import { JSONSerializer, JSONStorage, Logger } from '@qlover/fe-utils';
7
+ import { IOCIdentifier } from '@/base/consts/IOCIdentifier';
8
+
9
+ export class RegisterGlobals implements InversifyRegisterInterface {
10
+ register(container: InversifyRegisterContainer): void {
11
+ container.bind(JSONSerializer).toConstantValue(JSON);
12
+ container.bind(IOCIdentifier.JSON).toConstantValue(JSON);
13
+
14
+ container.bind(Logger).toConstantValue(logger);
15
+ container.bind(IOCIdentifier.Logger).toConstantValue(logger);
16
+
17
+ container.bind(JSONStorage).toConstantValue(localJsonStorage);
18
+ container.bind(IOCIdentifier.JSONStorage).toConstantValue(localJsonStorage);
19
+ }
20
+ }
@@ -0,0 +1,17 @@
1
+ import type { InversifyRegisterInterface } from '@/base/port/InversifyIocInterface';
2
+ import { RegisterGlobals } from './RegisterGlobals';
3
+ import { RegisterCommon } from './RegisterCommon';
4
+ import { RegisterApi } from './RegisterApi';
5
+ import { RegisterControllers } from './RegisterControllers';
6
+
7
+ /**
8
+ * Register List
9
+ *
10
+ * Register List is used to register dependencies in bootstrap
11
+ */
12
+ export const registerList: InversifyRegisterInterface[] = [
13
+ new RegisterGlobals(),
14
+ new RegisterCommon(),
15
+ new RegisterApi(),
16
+ new RegisterControllers()
17
+ ];
@@ -1,10 +1,11 @@
1
+ // !only this file use `window`, `document` ...global variables
2
+ import 'reflect-metadata';
1
3
  import { StrictMode } from 'react';
2
4
  import { createRoot } from 'react-dom/client';
3
5
  import App from './App.tsx';
4
- import { Bootstrap } from './core/bootstrap';
5
- import { FeIOC } from './core/feIOC/FeIOC';
6
+ import startup from './core/bootstrap';
6
7
 
7
- new Bootstrap(new FeIOC()).start();
8
+ startup(window);
8
9
 
9
10
  createRoot(document.getElementById('root')!).render(
10
11
  <StrictMode>
@@ -1,4 +1,4 @@
1
- import { IOC } from '@/core';
1
+ import { IOC } from '@/core/IOC';
2
2
  import { UserController } from '@/uikit/controllers/UserController';
3
3
  import { useController } from '@lib/fe-react-controller';
4
4
  import { Navigate, Outlet } from 'react-router-dom';
@@ -1,16 +1,16 @@
1
1
  import { useState } from 'react';
2
2
  import { useController } from '@lib/fe-react-controller';
3
- import { IOC } from '@/core';
3
+ import { IOC } from '@/core/IOC';
4
4
  import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
5
- import { defaultLoginInfo } from '@config/app.common';
6
5
  import { RouterController } from '@/uikit/controllers/RouterController';
7
6
  import { UserController } from '@/uikit/controllers/UserController';
7
+ import AppConfig from '@/core/AppConfig';
8
8
 
9
9
  export default function Login() {
10
10
  const { t } = useBaseRoutePage();
11
11
  const controller = useController(IOC(UserController));
12
- const [email, setEmail] = useState(defaultLoginInfo.name);
13
- const [password, setPassword] = useState(defaultLoginInfo.password);
12
+ const [email, setEmail] = useState(AppConfig.loginUser);
13
+ const [password, setPassword] = useState(AppConfig.loginPassword);
14
14
  const [loading, setLoading] = useState(false);
15
15
 
16
16
  const handleLogin = async () => {
@@ -1,4 +1,4 @@
1
- import { IOC } from '@/core';
1
+ import { IOC } from '@/core/IOC';
2
2
  import { useControllerState } from '@lib/fe-react-controller';
3
3
  import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
4
4
  import { JSONStorageController } from '@/uikit/controllers/JSONStorageController';
@@ -1,4 +1,4 @@
1
- import { IOC } from '@/core';
1
+ import { IOC } from '@/core/IOC';
2
2
  import { useController, useControllerState } from '@lib/fe-react-controller';
3
3
  import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
4
4
  import template from 'lodash/template';
@@ -1,4 +1,4 @@
1
- import { IOC } from '@/core';
1
+ import { IOC } from '@/core/IOC';
2
2
  import { useControllerState } from '@lib/fe-react-controller';
3
3
  import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
4
4
  import { JSONStorageController } from '@/uikit/controllers/JSONStorageController';
@@ -4,24 +4,16 @@ import LanguageDetector from 'i18next-browser-languagedetector';
4
4
  import HttpApi from 'i18next-http-backend';
5
5
  import merge from 'lodash/merge';
6
6
  import { i18nConfig, I18nServiceLocale } from '@config/i18n';
7
+ import type { BootstrapExecutorPlugin } from '@lib/bootstrap';
7
8
 
8
9
  const { supportedLngs, fallbackLng } = i18nConfig;
9
10
 
10
- // custom language detector
11
- const pathLanguageDetector = {
12
- name: 'pathLanguageDetector',
13
- lookup() {
14
- const path = window.location.pathname.split('/');
15
- const language = path[1];
16
- return I18nService.isValidLanguage(language) ? language : fallbackLng;
17
- },
18
- cacheUserLanguage() {
19
- // no cache, because we get language from URL
20
- }
21
- };
11
+ export class I18nService implements BootstrapExecutorPlugin {
12
+ readonly pluginName = 'I18nService';
13
+
14
+ constructor(private pathname: string) {}
22
15
 
23
- export class I18nService {
24
- static init(): void {
16
+ onBefore(): void {
25
17
  i18n
26
18
  .use(HttpApi)
27
19
  .use(LanguageDetector)
@@ -36,6 +28,18 @@ export class I18nService {
36
28
  );
37
29
 
38
30
  // add custom detector
31
+ // custom language detector
32
+ const pathLanguageDetector = {
33
+ name: 'pathLanguageDetector',
34
+ lookup: () => {
35
+ const path = this.pathname.split('/');
36
+ const language = path[1];
37
+ return I18nService.isValidLanguage(language) ? language : fallbackLng;
38
+ },
39
+ cacheUserLanguage() {
40
+ // no cache, because we get language from URL
41
+ }
42
+ };
39
43
  i18n.services.languageDetector.addDetector(pathLanguageDetector);
40
44
  }
41
45
 
@@ -3,8 +3,14 @@ import { useContext, useMemo } from 'react';
3
3
  import { BasePageProvider } from '@/base/types/Page';
4
4
  import { RouteMeta } from '@/base/types/Page';
5
5
  import { createContext } from 'react';
6
- import { defaultBaseRoutemeta } from '@config/app.common';
7
6
  import merge from 'lodash/merge';
7
+ import { i18nConfig } from '@config/i18n';
8
+
9
+ const defaultBaseRoutemeta = {
10
+ localNamespace: i18nConfig.defaultNS,
11
+ title: '',
12
+ icon: ''
13
+ };
8
14
 
9
15
  export const BaseRoutePageContext = createContext<RouteMeta>({});
10
16
 
@@ -1,5 +1,5 @@
1
1
  import { createContext, useEffect } from 'react';
2
- import { IOC } from '@/core';
2
+ import { IOC } from '@/core/IOC';
3
3
  import { useLanguageGuard } from '@/uikit/hooks/useLanguageGuard';
4
4
  import { useStrictEffect } from '@/uikit/hooks/useStrictEffect';
5
5
  import { ProcesserService } from '@/services/processer/ProcesserService';