@qlover/create-app 0.1.11 → 0.1.12

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 (51) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/package.json +1 -1
  3. package/templates/react-app/.env +23 -2
  4. package/templates/react-app/config/common.ts +3 -0
  5. package/templates/react-app/lib/bootstrap/Bootstrap.ts +36 -0
  6. package/templates/react-app/lib/bootstrap/BootstrapExecutorPlugin.ts +20 -0
  7. package/templates/react-app/lib/bootstrap/IOCContainerInterface.ts +33 -0
  8. package/templates/react-app/lib/bootstrap/IOCManagerInterface.ts +12 -0
  9. package/templates/react-app/lib/bootstrap/index.ts +7 -0
  10. package/templates/react-app/lib/bootstrap/plugins/InjectEnv.ts +61 -0
  11. package/templates/react-app/lib/bootstrap/plugins/InjectGlobal.ts +36 -0
  12. package/templates/react-app/lib/bootstrap/plugins/InjectIOC.ts +24 -0
  13. package/templates/react-app/lib/env-config/injectPkgConfig.ts +11 -0
  14. package/templates/react-app/lib/openAiApi/OpenAIClient.ts +1 -1
  15. package/templates/react-app/package.json +3 -1
  16. package/templates/react-app/src/base/consts/IOCIdentifier.ts +16 -0
  17. package/templates/react-app/src/base/port/IOCFunctionInterface.ts +39 -0
  18. package/templates/react-app/src/base/port/InversifyIocInterface.ts +9 -0
  19. package/templates/react-app/src/base/port/StorageTokenInterface.ts +22 -0
  20. package/templates/react-app/src/base/types/Page.ts +4 -13
  21. package/templates/react-app/src/base/types/global.d.ts +2 -1
  22. package/templates/react-app/src/components/ThemeSwitcher.tsx +1 -1
  23. package/templates/react-app/src/core/AppConfig.ts +27 -0
  24. package/templates/react-app/src/core/AppIOCContainer.ts +30 -0
  25. package/templates/react-app/src/core/IOC.ts +48 -0
  26. package/templates/react-app/src/core/bootstrap.ts +59 -14
  27. package/templates/react-app/src/core/globals.ts +1 -1
  28. package/templates/react-app/src/core/registers/RegisterApi.ts +59 -0
  29. package/templates/react-app/src/core/registers/RegisterCommon.ts +21 -0
  30. package/templates/react-app/src/core/{feIOC → registers}/RegisterControllers.ts +16 -11
  31. package/templates/react-app/src/core/registers/RegisterGlobals.ts +20 -0
  32. package/templates/react-app/src/core/registers/index.ts +17 -0
  33. package/templates/react-app/src/main.tsx +4 -3
  34. package/templates/react-app/src/pages/auth/Layout.tsx +1 -1
  35. package/templates/react-app/src/pages/auth/Login.tsx +4 -4
  36. package/templates/react-app/src/pages/base/Executor.tsx +1 -1
  37. package/templates/react-app/src/pages/base/JSONStorage.tsx +1 -1
  38. package/templates/react-app/src/pages/base/Request.tsx +1 -1
  39. package/templates/react-app/src/services/I18nService.ts +18 -14
  40. package/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +7 -1
  41. package/templates/react-app/src/uikit/providers/ProcessProvider.tsx +1 -1
  42. package/templates/react-app/src/uikit/utils/RequestLogger.ts +4 -1
  43. package/templates/react-app/tsconfig.json +2 -1
  44. package/templates/react-app/tsconfig.node.json +6 -2
  45. package/templates/react-app/vite.config.ts +14 -0
  46. package/templates/react-app/config/app.common.ts +0 -52
  47. package/templates/react-app/src/base/port/IOCInterface.ts +0 -53
  48. package/templates/react-app/src/core/feIOC/FeIOC.ts +0 -32
  49. package/templates/react-app/src/core/feIOC/RegisterApi.ts +0 -41
  50. package/templates/react-app/src/core/feIOC/RegisterCommon.ts +0 -20
  51. package/templates/react-app/src/core/index.ts +0 -31
@@ -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';
@@ -1,16 +1,19 @@
1
+ import { IOCIdentifier } from '@/base/consts/IOCIdentifier';
1
2
  import {
2
3
  ExecutorPlugin,
3
4
  ExecutorContext,
4
5
  RequestAdapterFetchConfig,
5
6
  Logger
6
7
  } from '@qlover/fe-utils';
8
+ import { injectable, inject } from 'inversify';
7
9
 
10
+ @injectable()
8
11
  export class RequestLogger
9
12
  implements ExecutorPlugin<RequestAdapterFetchConfig>
10
13
  {
11
14
  readonly pluginName = 'RequestLogger';
12
15
 
13
- constructor(public logger: Logger) {}
16
+ constructor(@inject(IOCIdentifier.Logger) public logger: Logger) {}
14
17
 
15
18
  async onSuccess({
16
19
  parameters,
@@ -22,7 +22,8 @@
22
22
  "@/*": ["./src/*"],
23
23
  "@lib/*": ["./lib/*"],
24
24
  "@config/*": ["./config/*"]
25
- }
25
+ },
26
+ "experimentalDecorators": true
26
27
  },
27
28
  "include": ["src"],
28
29
  "references": [{ "path": "./tsconfig.node.json" }]
@@ -4,7 +4,11 @@
4
4
  "skipLibCheck": true,
5
5
  "module": "ESNext",
6
6
  "moduleResolution": "bundler",
7
- "allowSyntheticDefaultImports": true
7
+ "allowSyntheticDefaultImports": true,
8
+ "paths": {
9
+ "@lib/*": ["./lib/*"],
10
+ "@config/*": ["./config/*"]
11
+ }
8
12
  },
9
- "include": ["vite.config.ts"]
13
+ "include": ["vite.config.ts", "lib", "config"]
10
14
  }
@@ -4,11 +4,23 @@ import alias from '@rollup/plugin-alias';
4
4
  import tsappconfig from './tsconfig.json';
5
5
  import { resolve } from 'path';
6
6
  import { Env } from '@qlover/env-loader';
7
+ import { envPrefix } from './config/common';
8
+ import { name, version } from './package.json';
9
+ import { injectPkgConfig } from './lib/env-config/injectPkgConfig';
7
10
 
8
11
  Env.searchEnv();
9
12
 
10
13
  const tsAppPaths = tsappconfig.compilerOptions.paths || {};
11
14
 
15
+ // add version and name to env
16
+ injectPkgConfig(
17
+ [
18
+ ['APP_NAME', name],
19
+ ['APP_VERSION', version]
20
+ ],
21
+ envPrefix
22
+ );
23
+
12
24
  // convert tsconfig paths to vite alias
13
25
  const entries = Object.entries(tsAppPaths).reduce((acc, [key, value]) => {
14
26
  acc[key.replace('/*', '')] = resolve(__dirname, value[0].replace('/*', ''));
@@ -23,10 +35,12 @@ export default defineConfig({
23
35
  entries
24
36
  })
25
37
  ],
38
+ envPrefix: envPrefix,
26
39
  publicDir: 'public',
27
40
  server: {
28
41
  port: Number(process.env.VITE_SERVER_PORT || 3200)
29
42
  },
43
+ mode: process.env.NODE_ENV,
30
44
  test: {
31
45
  environment: 'jsdom',
32
46
  globals: true,
@@ -1,52 +0,0 @@
1
- import { i18nConfig } from '@config/i18n';
2
- import { OpenAIClientConfig } from '@lib/openAiApi';
3
- import { RequestCommonPluginConfig } from '@lib/request-common-plugin';
4
- import { RequestAdapterFetchConfig } from '@qlover/fe-utils';
5
-
6
- export const openAiModels = [
7
- 'gpt-3.5-turbo',
8
- 'gpt-3.5-turbo-2',
9
- 'gpt-4',
10
- 'gpt-4-32k'
11
- ];
12
-
13
- export const requestCommonPluginConfig: RequestCommonPluginConfig = {
14
- tokenPrefix: 'Bearer',
15
- defaultHeaders: {
16
- 'Content-Type': 'application/json'
17
- },
18
- defaultRequestData: {
19
- model: 'gpt-4o-mini',
20
- stream: true
21
- },
22
- requiredToken: true,
23
- token: import.meta.env.VITE_OPENAI_API_KEY
24
- };
25
-
26
- export const openAiConfig: OpenAIClientConfig = {
27
- baseURL: import.meta.env.VITE_OPENAI_API_URL,
28
- models: openAiModels,
29
- commonPluginConfig: requestCommonPluginConfig
30
- };
31
-
32
- export const defaultBaseRoutemeta = {
33
- localNamespace: i18nConfig.defaultNS,
34
- title: '',
35
- icon: ''
36
- } as const;
37
-
38
- export const defaultLoginInfo = {
39
- name: 'qlover',
40
- password: 'q1234566'
41
- };
42
-
43
- export const defaultFeApiConfig: {
44
- adapter: Partial<RequestAdapterFetchConfig>;
45
- commonPluginConfig: RequestCommonPluginConfig;
46
- } = {
47
- adapter: {
48
- responseType: 'json',
49
- baseURL: 'https://api.example.com/'
50
- },
51
- commonPluginConfig: requestCommonPluginConfig
52
- };
@@ -1,53 +0,0 @@
1
- export interface Abstract<T> {
2
- prototype: T;
3
- }
4
- export type Newable<T, Args extends unknown[] = unknown[]> = new (
5
- ...args: Args
6
- ) => T;
7
-
8
- export type ServiceIdentifier<T = unknown> =
9
- | string
10
- | symbol
11
- | Newable<T>
12
- | Abstract<T>;
13
-
14
- /**
15
- * IOC container
16
- *
17
- */
18
- export interface IOCInterface {
19
- /**
20
- * configure IOC container
21
- */
22
- configure(): void;
23
-
24
- /**
25
- * bind instance
26
- *
27
- * @param serviceIdentifier
28
- * @param value
29
- */
30
- bind<T>(serviceIdentifier: ServiceIdentifier<T>, value: T): void;
31
-
32
- /**
33
- * get instance
34
- *
35
- * @param serviceIdentifier
36
- * @returns
37
- */
38
- get<T>(serviceIdentifier: ServiceIdentifier<T>): T;
39
-
40
- /**
41
- * You can also use the override method to specify a replacement at runtime
42
- *
43
- * However, it may have performance issues because it creates an additional instance
44
- *
45
- * @param serviceIdentifier
46
- * @param value
47
- */
48
- override<T>(serviceIdentifier: ServiceIdentifier<T>, value: T): void;
49
- }
50
-
51
- export interface IOCRegisterInterface {
52
- register(container: IOCInterface): void;
53
- }
@@ -1,32 +0,0 @@
1
- import { IOCInterface } from '@/base/port/IOCInterface';
2
- import { RegisterApi } from './RegisterApi';
3
- import { RegisterControllers } from './RegisterControllers';
4
- import { RegisterCommon } from './RegisterCommon';
5
-
6
- export class FeIOC implements IOCInterface {
7
- private container: Map<string, unknown> = new Map();
8
-
9
- /**
10
- * order:
11
- * 1. RegisterCommon
12
- * 2. RegisterApi
13
- * 3. RegisterControllers
14
- */
15
- configure(): void {
16
- new RegisterCommon().register(this);
17
- new RegisterApi().register(this);
18
- new RegisterControllers().register(this);
19
- }
20
-
21
- bind<T>(key: string, value: T): void {
22
- this.container.set(key, value);
23
- }
24
-
25
- get<T>(key: string): T {
26
- return this.container.get(key) as T;
27
- }
28
-
29
- override<T>(key: string, value: T): void {
30
- this.bind(key, value);
31
- }
32
- }
@@ -1,41 +0,0 @@
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
- }
@@ -1,20 +0,0 @@
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
- }
@@ -1,31 +0,0 @@
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
- );