@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.
- package/CHANGELOG.md +9 -0
- package/bin/create-app.js +0 -0
- package/dist/index.cjs +3631 -0
- package/dist/{cjs/index.d.ts → index.d.ts} +3 -2
- package/dist/index.js +3625 -0
- package/package.json +17 -16
- package/templates/node-lib/bin/test.js +1 -1
- package/templates/node-lib/package.json +2 -2
- package/templates/node-lib/rollup.config.js +1 -2
- package/templates/pack-app/package.json +1 -1
- package/templates/react-app/.env +23 -2
- package/templates/react-app/.env.local +24 -0
- package/templates/react-app/config/common.ts +3 -0
- package/templates/react-app/lib/bootstrap/Bootstrap.ts +36 -0
- package/templates/react-app/lib/bootstrap/BootstrapExecutorPlugin.ts +20 -0
- package/templates/react-app/lib/bootstrap/IOCContainerInterface.ts +33 -0
- package/templates/react-app/lib/bootstrap/IOCManagerInterface.ts +12 -0
- package/templates/react-app/lib/bootstrap/index.ts +7 -0
- package/templates/react-app/lib/bootstrap/plugins/InjectEnv.ts +61 -0
- package/templates/react-app/lib/bootstrap/plugins/InjectGlobal.ts +36 -0
- package/templates/react-app/lib/bootstrap/plugins/InjectIOC.ts +24 -0
- package/templates/react-app/lib/env-config/injectPkgConfig.ts +11 -0
- package/templates/react-app/lib/openAiApi/OpenAIClient.ts +1 -1
- package/templates/react-app/lib/router-loader/Page.ts +8 -4
- package/templates/react-app/lib/router-loader/RouterLoader.ts +1 -1
- package/templates/react-app/package.json +3 -1
- package/templates/react-app/pnpm-lock.yaml +5892 -0
- package/templates/react-app/src/base/consts/IOCIdentifier.ts +16 -0
- package/templates/react-app/src/base/port/IOCFunctionInterface.ts +39 -0
- package/templates/react-app/src/base/port/InversifyIocInterface.ts +9 -0
- package/templates/react-app/src/base/port/StorageTokenInterface.ts +22 -0
- package/templates/react-app/src/base/types/Page.ts +4 -13
- package/templates/react-app/src/base/types/global.d.ts +2 -1
- package/templates/react-app/src/components/ThemeSwitcher.tsx +1 -1
- package/templates/react-app/src/core/AppConfig.ts +27 -0
- package/templates/react-app/src/core/AppIOCContainer.ts +30 -0
- package/templates/react-app/src/core/IOC.ts +48 -0
- package/templates/react-app/src/core/bootstrap.ts +59 -14
- package/templates/react-app/src/core/globals.ts +1 -1
- package/templates/react-app/src/core/registers/RegisterApi.ts +59 -0
- package/templates/react-app/src/core/registers/RegisterCommon.ts +21 -0
- package/templates/react-app/src/core/{feIOC → registers}/RegisterControllers.ts +16 -11
- package/templates/react-app/src/core/registers/RegisterGlobals.ts +20 -0
- package/templates/react-app/src/core/registers/index.ts +17 -0
- package/templates/react-app/src/main.tsx +4 -3
- package/templates/react-app/src/pages/auth/Layout.tsx +1 -1
- package/templates/react-app/src/pages/auth/Login.tsx +4 -4
- package/templates/react-app/src/pages/base/Executor.tsx +1 -1
- package/templates/react-app/src/pages/base/JSONStorage.tsx +1 -1
- package/templates/react-app/src/pages/base/Request.tsx +1 -1
- package/templates/react-app/src/services/I18nService.ts +18 -14
- package/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +7 -1
- package/templates/react-app/src/uikit/providers/ProcessProvider.tsx +1 -1
- package/templates/react-app/src/uikit/utils/RequestLogger.ts +4 -1
- package/templates/react-app/tsconfig.json +2 -1
- package/templates/react-app/tsconfig.node.json +6 -2
- package/templates/react-app/vite.config.ts +14 -0
- package/configs/_common/.release-it.json.template +0 -42
- package/dist/cjs/index.js +0 -1
- package/dist/es/index.d.ts +0 -112
- package/dist/es/index.js +0 -1
- package/templates/react-app/config/app.common.ts +0 -52
- package/templates/react-app/src/base/port/IOCInterface.ts +0 -53
- package/templates/react-app/src/core/feIOC/FeIOC.ts +0 -32
- package/templates/react-app/src/core/feIOC/RegisterApi.ts +0 -41
- package/templates/react-app/src/core/feIOC/RegisterCommon.ts +0 -20
- 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 {
|
|
3
|
-
|
|
4
|
-
import {
|
|
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
|
-
};
|
|
@@ -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
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
|
|
7
|
-
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
28
|
+
if (!window) {
|
|
29
|
+
throw new Error('Not Found Window');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const bootstrap = new Bootstrap(new AppIOCContainer());
|
|
14
33
|
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
19
|
-
|
|
61
|
+
try {
|
|
62
|
+
bootstrap.use(bootstrapList).start(root);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error(`${AppConfig.appName} starup error:`, error);
|
|
20
65
|
}
|
|
21
66
|
}
|
|
@@ -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 {
|
|
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
|
|
19
|
-
register(container:
|
|
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
|
|
46
|
-
container
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
container.bind(
|
|
50
|
-
container.bind(
|
|
51
|
-
container.bind(
|
|
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
|
|
5
|
-
import { FeIOC } from './core/feIOC/FeIOC';
|
|
6
|
+
import startup from './core/bootstrap';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
startup(window);
|
|
8
9
|
|
|
9
10
|
createRoot(document.getElementById('root')!).render(
|
|
10
11
|
<StrictMode>
|
|
@@ -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(
|
|
13
|
-
const [password, setPassword] = useState(
|
|
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 { 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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
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';
|