@qlover/create-app 0.1.10 → 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 (59) hide show
  1. package/CHANGELOG.md +9 -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/lib/router-loader/Page.ts +64 -0
  16. package/templates/react-app/lib/router-loader/RouterLoader.ts +90 -0
  17. package/templates/react-app/package.json +3 -1
  18. package/templates/react-app/src/App.tsx +27 -6
  19. package/templates/react-app/src/base/consts/IOCIdentifier.ts +16 -0
  20. package/templates/react-app/src/base/port/IOCFunctionInterface.ts +39 -0
  21. package/templates/react-app/src/base/port/InversifyIocInterface.ts +9 -0
  22. package/templates/react-app/src/base/port/StorageTokenInterface.ts +22 -0
  23. package/templates/react-app/src/base/types/Page.ts +5 -17
  24. package/templates/react-app/src/base/types/global.d.ts +2 -1
  25. package/templates/react-app/src/components/RouterRenderComponent.tsx +16 -0
  26. package/templates/react-app/src/components/ThemeSwitcher.tsx +1 -1
  27. package/templates/react-app/src/core/AppConfig.ts +27 -0
  28. package/templates/react-app/src/core/AppIOCContainer.ts +30 -0
  29. package/templates/react-app/src/core/IOC.ts +48 -0
  30. package/templates/react-app/src/core/bootstrap.ts +60 -15
  31. package/templates/react-app/src/core/globals.ts +1 -1
  32. package/templates/react-app/src/core/registers/RegisterApi.ts +59 -0
  33. package/templates/react-app/src/core/registers/RegisterCommon.ts +21 -0
  34. package/templates/react-app/src/core/{feIOC → registers}/RegisterControllers.ts +16 -11
  35. package/templates/react-app/src/core/registers/RegisterGlobals.ts +20 -0
  36. package/templates/react-app/src/core/registers/index.ts +17 -0
  37. package/templates/react-app/src/main.tsx +4 -3
  38. package/templates/react-app/src/pages/auth/Layout.tsx +1 -1
  39. package/templates/react-app/src/pages/auth/Login.tsx +4 -4
  40. package/templates/react-app/src/pages/base/Executor.tsx +1 -1
  41. package/templates/react-app/src/pages/base/JSONStorage.tsx +1 -1
  42. package/templates/react-app/src/pages/base/Request.tsx +1 -1
  43. package/templates/react-app/src/services/{i18n/index.ts → I18nService.ts} +25 -17
  44. package/templates/react-app/src/services/processer/ProcesserService.ts +2 -2
  45. package/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +7 -1
  46. package/templates/react-app/src/uikit/controllers/RouterController.ts +13 -16
  47. package/templates/react-app/src/uikit/hooks/useLanguageGuard.ts +1 -1
  48. package/templates/react-app/src/uikit/providers/ProcessProvider.tsx +2 -4
  49. package/templates/react-app/src/uikit/utils/RequestLogger.ts +4 -1
  50. package/templates/react-app/tsconfig.json +2 -1
  51. package/templates/react-app/tsconfig.node.json +6 -2
  52. package/templates/react-app/vite.config.ts +14 -0
  53. package/templates/react-app/config/app.common.ts +0 -52
  54. package/templates/react-app/src/base/port/IOCInterface.ts +0 -53
  55. package/templates/react-app/src/core/feIOC/FeIOC.ts +0 -32
  56. package/templates/react-app/src/core/feIOC/RegisterApi.ts +0 -41
  57. package/templates/react-app/src/core/feIOC/RegisterCommon.ts +0 -20
  58. package/templates/react-app/src/core/index.ts +0 -31
  59. package/templates/react-app/src/pages/index.tsx +0 -113
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
 
2
2
 
3
+ ## [0.1.12](https://github.com/qlover/fe-base/compare/create-app-v0.1.11...create-app-v0.1.12) (2025-03-18)
4
+
5
+
6
+ ### Features
7
+
8
+ * add inversify ioc ([#270](https://github.com/qlover/fe-base/issues/270)) ([8c7ba06](https://github.com/qlover/fe-base/commit/8c7ba06bc5bef63d85c59a94737afac9be59138f))
9
+
10
+ ## [0.1.11](https://github.com/qlover/fe-base/compare/create-app-v0.1.10...create-app-v0.1.11) (2025-03-12)
11
+
3
12
  ## [0.1.10](https://github.com/qlover/fe-base/compare/create-app-v0.1.9...create-app-v0.1.10) (2025-02-20)
4
13
 
5
14
  ## [0.1.9](https://github.com/qlover/fe-base/compare/create-app-v0.1.8...create-app-v0.1.9) (2025-02-20)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qlover/create-app",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "main": "./dist/es/index.js",
@@ -1,3 +1,24 @@
1
+ NODE_ENV=production
2
+
3
+ # ci
4
+ NPM_TOKEN=
5
+ GITHUB_TOKEN=
6
+
7
+ # fe-scripts
8
+ FE_RELEASE_BRANCH=master
9
+ FE_RELEASE=false
10
+ FE_RELEASE_ENV=production
11
+
12
+ # ===== build
13
+ VITE_PUBLIC_PATH=
1
14
  VITE_SERVER_PORT=3200
2
- VITE_OPENAI_API_URL=
3
- VITE_OPENAI_API_KEY=
15
+
16
+ # ===== app config
17
+ VITE_USER_TOKEN_STORAGE_KEY=fe_user_token
18
+ VITE_OPEN_AI_MODELS='["gpt-4o-mini","gpt-3.5-turbo","gpt-3.5-turbo-2","gpt-4","gpt-4-32k"]'
19
+ VITE_OPEN_AI_BASE_URL=https://api.openai.com/v1
20
+ VITE_OPEN_AI_TOKEN=sk-proj-1234567890
21
+ VITE_OPEN_AI_TOKEN_PREFIX=Bearer
22
+ VITE_OPEN_AI_REQUIRE_TOKEN=true
23
+ VITE_LOGIN_USER=admin
24
+ VITE_LOGIN_PASSWORD=123456
@@ -0,0 +1,3 @@
1
+ export const envPrefix = 'VITE_';
2
+
3
+ export const browserGlobalsName = 'feGlobals';
@@ -0,0 +1,36 @@
1
+ import type { IOCContainerInterface } from './IOCContainerInterface';
2
+ import { SyncExecutor } from '@qlover/fe-utils';
3
+ import { BootstrapExecutorPlugin } from './BootstrapExecutorPlugin';
4
+
5
+ export class Bootstrap extends SyncExecutor {
6
+ constructor(private IOCContainer: IOCContainerInterface) {
7
+ super();
8
+ }
9
+
10
+ getIOCContainer(): IOCContainerInterface {
11
+ return this.IOCContainer;
12
+ }
13
+
14
+ use(plugin: BootstrapExecutorPlugin | BootstrapExecutorPlugin[]): this {
15
+ if (Array.isArray(plugin)) {
16
+ plugin.forEach((p) => super.use(p));
17
+ return this;
18
+ }
19
+
20
+ super.use(plugin);
21
+
22
+ return this;
23
+ }
24
+
25
+ start(root: unknown): void {
26
+ this.exec({ root, ioc: this.IOCContainer }, () => {
27
+ // nothing to do
28
+ });
29
+ }
30
+
31
+ startNoError(root: unknown): void {
32
+ this.execNoError({ root, ioc: this.IOCContainer }, () => {
33
+ // nothing to do
34
+ });
35
+ }
36
+ }
@@ -0,0 +1,20 @@
1
+ import { IOCContainerInterface } from './IOCContainerInterface';
2
+ import { ExecutorContext, ExecutorPlugin } from '@qlover/fe-utils';
3
+
4
+ export type BootstrapArgs = {
5
+ /**
6
+ * starup global object
7
+ *
8
+ * maybe window or globalThis
9
+ */
10
+ root: unknown;
11
+ /**
12
+ * IOC container
13
+ */
14
+ ioc: IOCContainerInterface;
15
+ };
16
+
17
+ export interface BootstrapExecutorPlugin
18
+ extends ExecutorPlugin<BootstrapArgs> {}
19
+
20
+ export type BootstrapContext = ExecutorContext<BootstrapArgs>;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * IOC container
3
+ *
4
+ */
5
+ export interface IOCContainerInterface {
6
+ /**
7
+ * configure IOC container
8
+ *
9
+ * eg. may need to manually bind implementation classes
10
+ */
11
+ configure(): void;
12
+ configure<Container>(registers?: IOCRegisterInterface<Container>[]): void;
13
+
14
+ /**
15
+ * bind instance
16
+ *
17
+ * @param serviceIdentifier
18
+ * @param value
19
+ */
20
+ bind<T>(serviceIdentifier: unknown, value: T): void;
21
+
22
+ /**
23
+ * get instance
24
+ *
25
+ * @param serviceIdentifier
26
+ * @returns
27
+ */
28
+ get<T>(serviceIdentifier: unknown): T;
29
+ }
30
+
31
+ export interface IOCRegisterInterface<T> {
32
+ register(container: T, thisArg: IOCContainerInterface): void;
33
+ }
@@ -0,0 +1,12 @@
1
+ import type { IOCContainerInterface } from './IOCContainerInterface';
2
+
3
+ export interface IOCManagerInterface {
4
+ get<T>(identifier: unknown): T;
5
+
6
+ /**
7
+ * implement IOC container
8
+ */
9
+ implement(container: IOCContainerInterface): void;
10
+
11
+ get implemention(): IOCContainerInterface | null;
12
+ }
@@ -0,0 +1,7 @@
1
+ export * from './Bootstrap';
2
+ export * from './BootstrapExecutorPlugin';
3
+ export * from './plugins/InjectIOC';
4
+ export * from './plugins/InjectEnv';
5
+ export * from './plugins/InjectGlobal';
6
+ export * from './IOCContainerInterface';
7
+ export * from './IOCManagerInterface';
@@ -0,0 +1,61 @@
1
+ import type { BootstrapExecutorPlugin } from '../BootstrapExecutorPlugin';
2
+
3
+ export interface EnvConfigInterface {
4
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
+ [key: string]: any;
6
+ }
7
+
8
+ export class InjectEnv implements BootstrapExecutorPlugin {
9
+ readonly pluginName = 'InjectEnv';
10
+
11
+ constructor(
12
+ private target: EnvConfigInterface,
13
+ private source: Record<string, unknown>,
14
+ private envPrefix: string = '',
15
+ private envWhiteList: string[] = ['env', 'userNodeEnv']
16
+ ) {}
17
+
18
+ static isJSONString(value: string): boolean {
19
+ return (
20
+ typeof value === 'string' &&
21
+ value !== '' &&
22
+ (value === 'true' ||
23
+ value === 'false' ||
24
+ value.startsWith('{') ||
25
+ value.startsWith('['))
26
+ );
27
+ }
28
+
29
+ env<D>(key: string, defaultValue?: D): D {
30
+ // transform key to env key
31
+ const formattedKey = key.replace(/([a-z])([A-Z])/g, '$1_$2').toUpperCase();
32
+
33
+ const envKey = `${this.envPrefix}${formattedKey}`;
34
+ const value = this.source[envKey];
35
+ // if it is a json string, parse it
36
+ if (typeof value === 'string' && InjectEnv.isJSONString(value)) {
37
+ return JSON.parse(value);
38
+ }
39
+
40
+ return (value ?? defaultValue) as D;
41
+ }
42
+
43
+ inject(config: EnvConfigInterface): void {
44
+ for (const key in config) {
45
+ if (this.envWhiteList.includes(key)) {
46
+ continue;
47
+ }
48
+
49
+ const value = config[key as keyof typeof config];
50
+
51
+ config[key as keyof typeof config] = this.env(key, value);
52
+ }
53
+ }
54
+
55
+ onBefore(): void {
56
+ this.inject(this.target);
57
+
58
+ // transform readonly to writable
59
+ Object.freeze(this.target);
60
+ }
61
+ }
@@ -0,0 +1,36 @@
1
+ import type { ExecutorContext } from '@qlover/fe-utils';
2
+ import type {
3
+ BootstrapArgs,
4
+ BootstrapExecutorPlugin
5
+ } from '../BootstrapExecutorPlugin';
6
+
7
+ export class InjectGlobal implements BootstrapExecutorPlugin {
8
+ readonly pluginName = 'InjectGlobal';
9
+
10
+ constructor(
11
+ private sources: Record<string, unknown>,
12
+ private target?: string | Record<string, unknown>
13
+ ) {}
14
+
15
+ onBefore(context: ExecutorContext<BootstrapArgs>): void {
16
+ // if target is provided, inject globals to target
17
+ if (typeof this.target === 'string') {
18
+ Object.assign(context.parameters.root!, {
19
+ [this.target]: Object.freeze(Object.assign({}, this.sources))
20
+ });
21
+ return;
22
+ }
23
+
24
+ const target = this.target || context.parameters.root;
25
+
26
+ if (typeof target !== 'object' || target === null) {
27
+ throw new Error('target must be an object');
28
+ }
29
+
30
+ // inject globals to root
31
+ for (const key in this.sources) {
32
+ const element = this.sources[key];
33
+ Object.assign(target, { [key]: element });
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,24 @@
1
+ import type { IOCRegisterInterface } from '../IOCContainerInterface';
2
+ import type { IOCManagerInterface } from '../IOCManagerInterface';
3
+ import type {
4
+ BootstrapContext,
5
+ BootstrapExecutorPlugin
6
+ } from '../BootstrapExecutorPlugin';
7
+ import { Container } from 'inversify';
8
+
9
+ export class InjectIOC implements BootstrapExecutorPlugin {
10
+ readonly pluginName = 'InjectIOC';
11
+
12
+ constructor(
13
+ private IOC: IOCManagerInterface,
14
+ private registeres: IOCRegisterInterface<Container>[]
15
+ ) {}
16
+
17
+ onBefore(context: BootstrapContext): void {
18
+ const { ioc } = context.parameters;
19
+ this.IOC.implement(ioc);
20
+
21
+ // maybe runtimes configure
22
+ ioc.configure(this.registeres);
23
+ }
24
+ }
@@ -0,0 +1,11 @@
1
+ export function injectPkgConfig(
2
+ options: [string, string][],
3
+ envPrefix: string = ''
4
+ ) {
5
+ options.forEach(([key, value]) => {
6
+ const envKey = `${envPrefix}${key}`;
7
+ if (!process.env[envKey]) {
8
+ process.env[envKey] = value;
9
+ }
10
+ });
11
+ }
@@ -25,7 +25,7 @@ export interface OpenAIChatParmas {
25
25
 
26
26
  export type OpenAIAargs = {
27
27
  commonPluginConfig: RequestCommonPluginConfig;
28
- models: readonly string[];
28
+ models: string[];
29
29
  };
30
30
 
31
31
  export type OpenAIClientConfig = Partial<RequestAdapterFetchConfig> &
@@ -0,0 +1,64 @@
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
+
7
+ export interface BasePageProvider {
8
+ meta: RouteMeta;
9
+ i18n: UseTranslationResponse<string, string>;
10
+ t: TFunction<string, string>;
11
+ }
12
+
13
+ export type RouteCategory = 'main' | 'auth' | 'common';
14
+
15
+ export interface RouteMeta {
16
+ category?: RouteCategory;
17
+ /**
18
+ * from app.router.json
19
+ */
20
+ title?: string;
21
+ icon?: string;
22
+ /**
23
+ * from app.router.json
24
+ *
25
+ * @default 'common'
26
+ */
27
+ localNamespace?: string;
28
+ }
29
+
30
+ export type RouteType = RouteObject & {
31
+ meta?: RouteMeta;
32
+ };
33
+
34
+ export type RouteConfig = {
35
+ routes: RouteType[];
36
+ };
37
+
38
+ export type PagesMaps = Record<
39
+ string,
40
+ | (() => LazyExoticComponent<React.ComponentType<unknown>>)
41
+ | (() => React.ComponentType<unknown>)
42
+ >;
43
+
44
+ export type LoadProps = {
45
+ pagesMaps: PagesMaps;
46
+ componentPath: string;
47
+ route: RouteType;
48
+ Provider?: React.ComponentType<PropsWithChildren<RouteMeta>>;
49
+ };
50
+
51
+
52
+ type ComponentValue = React.ComponentType<unknown> | LazyExoticComponent<React.ComponentType<unknown>>;
53
+
54
+ export type ComponentMaps = {
55
+ /**
56
+ * key: ./xxx/bbb.(jsx,js,tsx,ts)
57
+ */
58
+ [key: string]: ComponentValue | (() => Promise<ComponentValue>) | (() => ComponentValue);
59
+ }
60
+
61
+ // new RouterManager({
62
+ // routes: [],
63
+ // componentMaps:
64
+ // });
@@ -0,0 +1,90 @@
1
+ import { RouteObject } from 'react-router-dom';
2
+ import isString from 'lodash/isString';
3
+ import type { ComponentType, LazyExoticComponent, ReactNode } from 'react';
4
+
5
+ type ComponentValue = Record<string, () => unknown>;
6
+
7
+ type RouteComponentType<T = unknown> =
8
+ | ComponentType<T>
9
+ | LazyExoticComponent<ComponentType<T>>;
10
+
11
+ export type RouteConfigValue = Omit<RouteObject, 'element' | 'children'> & {
12
+ /**
13
+ * 路径
14
+ *
15
+ * FIXME: support `ReactNode`
16
+ */
17
+ element?: string;
18
+ children?: RouteConfigValue[];
19
+ meta?: Record<string, unknown>;
20
+ };
21
+
22
+ export type RouterLoaderRender = (
23
+ route: Omit<RouteConfigValue, 'element'> & {
24
+ element: () => RouteComponentType;
25
+ }
26
+ ) => ReactNode;
27
+
28
+ export type RouterLoaderOptions = {
29
+ /**
30
+ * 路由配置
31
+ */
32
+ routes?: RouteConfigValue[];
33
+
34
+ /**
35
+ * 组件映射表
36
+ */
37
+ componentMaps?: ComponentValue;
38
+
39
+ /**
40
+ * 渲染路由
41
+ */
42
+ render: RouterLoaderRender;
43
+ };
44
+
45
+ export class RouterLoader {
46
+ constructor(private readonly options: RouterLoaderOptions) {
47
+ if (!options.render) {
48
+ throw new Error('RouterLoader render is required');
49
+ }
50
+ }
51
+
52
+ getComponentMaps(): ComponentValue {
53
+ const { componentMaps = {} } = this.options;
54
+
55
+ return componentMaps;
56
+ }
57
+
58
+ getComponent(element: string): () => RouteComponentType {
59
+ const maps = this.getComponentMaps();
60
+
61
+ const component = maps[element];
62
+
63
+ if (!component) {
64
+ throw new Error(`Component not found: ${element}`);
65
+ }
66
+
67
+ return component as () => RouteComponentType;
68
+ }
69
+
70
+ toRoute(route: RouteConfigValue): RouteObject {
71
+ const { render } = this.options;
72
+ const { element, children, ...rest } = route;
73
+
74
+ if (!element || !isString(element)) {
75
+ console.warn(
76
+ `Invalid route, path is: ${route.path}, element is: ${element}`
77
+ );
78
+ }
79
+
80
+ const componet = this.getComponent(element || '404');
81
+ const Element = render({ ...rest, element: componet });
82
+
83
+ // @ts-expect-error
84
+ return {
85
+ ...rest,
86
+ element: Element,
87
+ children: children?.map((child) => this.toRoute(child))
88
+ };
89
+ }
90
+ }
@@ -56,11 +56,13 @@
56
56
  "i18next": "^24.2.0",
57
57
  "i18next-browser-languagedetector": "^8.0.2",
58
58
  "i18next-http-backend": "^3.0.1",
59
+ "inversify": "^7.1.0",
59
60
  "lodash": "^4.17.21",
60
61
  "react": "^18.3.1",
61
62
  "react-dom": "^18.3.1",
62
63
  "react-i18next": "^15.2.0",
63
- "react-router-dom": "^7.1.5"
64
+ "react-router-dom": "^7.1.5",
65
+ "reflect-metadata": "^0.2.2"
64
66
  },
65
67
  "devDependencies": {
66
68
  "@eslint/js": "^9.11.1",
@@ -1,14 +1,35 @@
1
1
  import '@/uikit/styles/css/index.css';
2
2
  import { createBrowserRouter, RouterProvider } from 'react-router-dom';
3
- import { createFeReactRoutes } from './pages';
4
- import { useMemo } from 'react';
5
- import { IOC } from './core';
6
- import { RouterController } from './uikit/controllers/RouterController';
3
+ import { lazy, useMemo } from 'react';
4
+ import { RouterLoader } from '@lib/router-loader/RouterLoader';
5
+ import appConfig from '@config/app.router.json';
6
+ import { RouterRenderComponent } from './components/RouterRenderComponent';
7
+ import { PagesMaps } from './base/types/Page';
8
+
9
+ function getAllPages() {
10
+ const modules = import.meta.glob('./pages/**/*.tsx');
11
+ return Object.keys(modules).reduce((acc, path) => {
12
+ const componentName = path.replace(/^\.\/pages\/(.*)\.tsx$/, '$1');
13
+ acc[componentName] = () =>
14
+ lazy(
15
+ modules[path] as () => Promise<{
16
+ default: React.ComponentType<unknown>;
17
+ }>
18
+ );
19
+ return acc;
20
+ }, {} as PagesMaps);
21
+ }
22
+
23
+ const routerLoader = new RouterLoader({
24
+ componentMaps: getAllPages(),
25
+ render: RouterRenderComponent
26
+ });
7
27
 
8
28
  function App() {
9
29
  const routerBase = useMemo(() => {
10
- const routerController = IOC(RouterController);
11
- const routes = createFeReactRoutes(routerController.getRoutes());
30
+ const routes = appConfig.base.routes.map((route) =>
31
+ routerLoader.toRoute(route)
32
+ );
12
33
  const router = createBrowserRouter(routes);
13
34
  return router;
14
35
  }, []);
@@ -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,8 +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';
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';
6
5
 
7
6
  export interface BasePageProvider {
8
7
  meta: RouteMeta;
@@ -27,12 +26,8 @@ export interface RouteMeta {
27
26
  localNamespace?: string;
28
27
  }
29
28
 
30
- export type RouteType = RouteObject & {
31
- meta?: RouteMeta;
32
- };
33
-
34
29
  export type RouteConfig = {
35
- routes: RouteType[];
30
+ routes: RouteConfigValue[];
36
31
  };
37
32
 
38
33
  export type PagesMaps = Record<
@@ -40,10 +35,3 @@ export type PagesMaps = Record<
40
35
  | (() => LazyExoticComponent<React.ComponentType<unknown>>)
41
36
  | (() => React.ComponentType<unknown>)
42
37
  >;
43
-
44
- export type LoadProps = {
45
- pagesMaps: PagesMaps;
46
- componentPath: string;
47
- route: RouteType;
48
- Provider?: React.ComponentType<PropsWithChildren<RouteMeta>>;
49
- };
@@ -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
  }