@qlover/create-app 0.1.14 → 0.1.16
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 +41 -16
- package/bin/create-app.js +0 -0
- package/configs/_common/package.json.template +10 -0
- package/configs/react-app/eslint.config.js +70 -42
- package/dist/index.cjs +1 -3631
- package/dist/index.js +1 -3625
- package/package.json +7 -7
- package/templates/react-app/.env +1 -0
- package/templates/react-app/config/ErrorIdentifier.ts +27 -0
- package/templates/react-app/config/app.router.json +9 -0
- package/templates/react-app/config/common.ts +12 -0
- package/templates/react-app/config/feapi.mock.json +15 -2
- package/templates/react-app/config/i18n.ts +3 -11
- package/templates/react-app/package.json +7 -4
- package/templates/react-app/pnpm-lock.yaml +176 -25
- package/templates/react-app/public/locales/en/common.json +6 -2
- package/templates/react-app/public/locales/zh/common.json +6 -3
- package/templates/react-app/src/App.tsx +8 -8
- package/templates/react-app/src/base/apis/AiApi.ts +55 -0
- package/templates/react-app/src/base/apis/feApi/FeApi.ts +13 -44
- package/templates/react-app/src/base/apis/feApi/FeApiAdapter.ts +14 -0
- package/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +67 -0
- package/templates/react-app/src/base/apis/feApi/FeApiType.ts +2 -35
- package/templates/react-app/src/base/apis/userApi/UserApi.ts +64 -0
- package/templates/react-app/src/base/apis/userApi/UserApiAdapter.ts +14 -0
- package/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +75 -0
- package/templates/react-app/src/base/apis/userApi/UserApiType.ts +52 -0
- package/templates/react-app/src/base/cases/RequestLogger.ts +71 -0
- package/templates/react-app/src/base/cases/RequestStatusCatcher.ts +41 -0
- package/templates/react-app/src/base/cases/appError/AppError.ts +13 -0
- package/templates/react-app/{lib/router-loader/RouterLoader.ts → src/base/cases/router-loader/index.ts} +1 -1
- package/templates/react-app/src/base/port/ApiTransactionInterface.ts +7 -0
- package/templates/react-app/src/base/port/InversifyIocInterface.ts +1 -1
- package/templates/react-app/src/base/port/LoginInterface.ts +4 -0
- package/templates/react-app/src/base/port/RequestCatcherInterface.ts +12 -0
- package/templates/react-app/src/{services → base/services}/I18nService.ts +7 -2
- package/templates/react-app/src/{services/processer → base/services}/ProcesserService.ts +10 -11
- package/templates/react-app/src/base/types/Page.ts +1 -13
- package/templates/react-app/src/core/AppConfig.ts +14 -5
- package/templates/react-app/src/core/IOC.ts +77 -37
- package/templates/react-app/src/core/bootstrap.ts +38 -25
- package/templates/react-app/src/core/bootstraps/BootstrapApp.ts +7 -0
- package/templates/react-app/src/core/bootstraps/index.ts +12 -0
- package/templates/react-app/src/core/globals.ts +7 -10
- package/templates/react-app/src/core/registers/RegisterApi.ts +1 -52
- package/templates/react-app/src/core/registers/RegisterCommon.ts +44 -6
- package/templates/react-app/src/core/registers/RegisterControllers.ts +5 -34
- package/templates/react-app/src/core/registers/RegisterGlobals.ts +8 -2
- package/templates/react-app/src/core/registers/index.ts +2 -1
- package/templates/react-app/src/main.tsx +4 -1
- package/templates/react-app/src/pages/auth/Layout.tsx +4 -3
- package/templates/react-app/src/pages/auth/Login.tsx +5 -3
- package/templates/react-app/src/pages/base/ErrorIdentifier.tsx +39 -0
- package/templates/react-app/src/pages/base/Executor.tsx +31 -10
- package/templates/react-app/src/pages/base/Home.tsx +58 -30
- package/templates/react-app/src/pages/base/JSONStorage.tsx +2 -4
- package/templates/react-app/src/pages/base/Request.tsx +318 -73
- package/templates/react-app/src/pages/base/components/BaseHeader.tsx +2 -2
- package/templates/react-app/src/{components → uikit/components}/RouterRenderComponent.tsx +1 -1
- package/templates/react-app/src/{components → uikit/components}/ThemeSwitcher.tsx +6 -6
- package/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +6 -3
- package/templates/react-app/src/uikit/controllers/ExecutorController.ts +52 -22
- package/templates/react-app/src/uikit/controllers/JSONStorageController.ts +7 -3
- package/templates/react-app/src/uikit/controllers/RequestController.ts +65 -11
- package/templates/react-app/src/uikit/controllers/RouterController.ts +8 -7
- package/templates/react-app/src/uikit/controllers/UserController.ts +48 -54
- package/templates/react-app/src/uikit/hooks/useLanguageGuard.ts +1 -2
- package/templates/react-app/src/uikit/providers/ProcessProvider.tsx +4 -4
- package/templates/react-app/src/uikit/styles/css/index.css +1 -1
- package/templates/react-app/src/uikit/styles/css/page.css +1 -1
- package/templates/react-app/tailwind.config.js +2 -2
- package/templates/react-app/tsconfig.json +0 -1
- package/templates/react-app/tsconfig.node.json +1 -2
- package/templates/react-app/vite.config.ts +21 -26
- package/templates/react-app/.env.local +0 -24
- package/templates/react-app/lib/bootstrap/Bootstrap.ts +0 -36
- package/templates/react-app/lib/bootstrap/BootstrapExecutorPlugin.ts +0 -20
- package/templates/react-app/lib/bootstrap/IOCContainerInterface.ts +0 -33
- package/templates/react-app/lib/bootstrap/IOCManagerInterface.ts +0 -12
- package/templates/react-app/lib/bootstrap/index.ts +0 -7
- package/templates/react-app/lib/bootstrap/plugins/InjectEnv.ts +0 -61
- package/templates/react-app/lib/bootstrap/plugins/InjectGlobal.ts +0 -36
- package/templates/react-app/lib/bootstrap/plugins/InjectIOC.ts +0 -24
- package/templates/react-app/lib/env-config/injectPkgConfig.ts +0 -11
- package/templates/react-app/lib/fe-react-controller/FeController.ts +0 -19
- package/templates/react-app/lib/fe-react-controller/index.ts +0 -2
- package/templates/react-app/lib/fe-react-controller/useController.ts +0 -71
- package/templates/react-app/lib/fe-react-theme/ThemeController.ts +0 -40
- package/templates/react-app/lib/fe-react-theme/ThemeStateGetter.ts +0 -53
- package/templates/react-app/lib/fe-react-theme/index.ts +0 -3
- package/templates/react-app/lib/fe-react-theme/type.ts +0 -21
- package/templates/react-app/lib/openAiApi/OpenAIAuthPlugin.ts +0 -29
- package/templates/react-app/lib/openAiApi/OpenAIClient.ts +0 -51
- package/templates/react-app/lib/openAiApi/StreamProcessor.ts +0 -81
- package/templates/react-app/lib/openAiApi/index.ts +0 -3
- package/templates/react-app/lib/request-common-plugin/index.ts +0 -169
- package/templates/react-app/lib/router-loader/Page.ts +0 -68
- package/templates/react-app/lib/tw-root10px/index.css +0 -4
- package/templates/react-app/src/base/apis/feApi/FeApiMockPlugin.ts +0 -44
- package/templates/react-app/src/base/apis/feApi/index.ts +0 -2
- package/templates/react-app/src/base/cases/UserToken.ts +0 -47
- package/templates/react-app/src/base/consts/IOCIdentifier.ts +0 -16
- package/templates/react-app/src/base/port/IOCFunctionInterface.ts +0 -39
- package/templates/react-app/src/base/port/StorageTokenInterface.ts +0 -27
- package/templates/react-app/src/core/AppIOCContainer.ts +0 -30
- package/templates/react-app/src/uikit/utils/RequestLogger.ts +0 -37
- package/templates/react-app/src/uikit/utils/datetime.ts +0 -30
- package/templates/react-app/src/uikit/utils/thread.ts +0 -3
- /package/templates/react-app/lib/{tw-root10px/index.js → tailwind/root10px.js} +0 -0
- /package/templates/react-app/lib/{fe-react-theme/tw-generator.js → tailwind/theme-generator.js} +0 -0
- /package/templates/react-app/src/{components → uikit/components}/Loading.tsx +0 -0
- /package/templates/react-app/src/{components → uikit/components}/LocaleLink.tsx +0 -0
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { FeController } from '@lib/fe-react-controller';
|
|
3
|
-
import { FeApi } from '@/base/apis/feApi';
|
|
1
|
+
import { FeApi } from '@/base/apis/feApi/FeApi';
|
|
4
2
|
import { logger } from '@/core/globals';
|
|
3
|
+
import { UserApi } from '@/base/apis/userApi/UserApi';
|
|
4
|
+
import { aiHello } from '@/base/apis/AiApi';
|
|
5
|
+
import { inject } from 'inversify';
|
|
6
|
+
import { injectable } from 'inversify';
|
|
7
|
+
import { SliceStore } from '@qlover/slice-store-react';
|
|
5
8
|
|
|
6
9
|
function createDefaultState() {
|
|
7
10
|
return {
|
|
@@ -24,25 +27,39 @@ function createDefaultState() {
|
|
|
24
27
|
loading: false,
|
|
25
28
|
result: null as unknown,
|
|
26
29
|
error: null as unknown
|
|
30
|
+
},
|
|
31
|
+
apiCatchResultState: {
|
|
32
|
+
loading: false,
|
|
33
|
+
result: null as unknown,
|
|
34
|
+
error: null as unknown
|
|
27
35
|
}
|
|
28
36
|
};
|
|
29
37
|
}
|
|
30
38
|
|
|
31
39
|
export type RequestControllerState = ReturnType<typeof createDefaultState>;
|
|
32
40
|
|
|
33
|
-
|
|
41
|
+
@injectable()
|
|
42
|
+
export class RequestController extends SliceStore<RequestControllerState> {
|
|
34
43
|
constructor(
|
|
35
|
-
private readonly
|
|
36
|
-
private readonly
|
|
44
|
+
@inject(FeApi) private readonly feApi: FeApi,
|
|
45
|
+
@inject(UserApi) private readonly userApi: UserApi
|
|
37
46
|
) {
|
|
38
47
|
super(createDefaultState);
|
|
39
48
|
}
|
|
40
49
|
|
|
50
|
+
setState(state: Partial<RequestControllerState>): void {
|
|
51
|
+
this.emit({ ...this.state, ...state });
|
|
52
|
+
}
|
|
53
|
+
|
|
41
54
|
onHello = async () => {
|
|
55
|
+
if (this.state.helloState.loading) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
42
59
|
this.setState({ helloState: { loading: true, result: '', error: null } });
|
|
43
60
|
|
|
44
61
|
try {
|
|
45
|
-
const result = await
|
|
62
|
+
const result = await aiHello({
|
|
46
63
|
messages: [{ role: 'user', content: 'Hello, world!' }]
|
|
47
64
|
});
|
|
48
65
|
this.setState({ helloState: { loading: false, result, error: null } });
|
|
@@ -53,9 +70,14 @@ export class RequestController extends FeController<RequestControllerState> {
|
|
|
53
70
|
};
|
|
54
71
|
|
|
55
72
|
onIpInfo = async () => {
|
|
73
|
+
if (this.state.ipInfoState.loading) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
56
77
|
this.setState({
|
|
57
78
|
ipInfoState: { loading: true, result: null, error: null }
|
|
58
79
|
});
|
|
80
|
+
|
|
59
81
|
try {
|
|
60
82
|
const result = await this.feApi.getIpInfo();
|
|
61
83
|
this.setState({ ipInfoState: { loading: false, result, error: null } });
|
|
@@ -66,11 +88,15 @@ export class RequestController extends FeController<RequestControllerState> {
|
|
|
66
88
|
};
|
|
67
89
|
|
|
68
90
|
onRandomUser = async () => {
|
|
91
|
+
if (this.state.randomUserState.loading) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
69
95
|
this.setState({
|
|
70
96
|
randomUserState: { loading: true, result: null, error: null }
|
|
71
97
|
});
|
|
72
98
|
try {
|
|
73
|
-
const result = await this.
|
|
99
|
+
const result = await this.userApi.getRandomUser();
|
|
74
100
|
this.setState({
|
|
75
101
|
randomUserState: { loading: false, result, error: null }
|
|
76
102
|
});
|
|
@@ -82,6 +108,30 @@ export class RequestController extends FeController<RequestControllerState> {
|
|
|
82
108
|
}
|
|
83
109
|
};
|
|
84
110
|
|
|
111
|
+
onTriggerApiCatchResult = async () => {
|
|
112
|
+
if (this.state.apiCatchResultState.loading) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.setState({
|
|
117
|
+
apiCatchResultState: { loading: true, result: null, error: null }
|
|
118
|
+
});
|
|
119
|
+
try {
|
|
120
|
+
const result = await this.userApi.testApiCatchResult();
|
|
121
|
+
this.setState({
|
|
122
|
+
apiCatchResultState: {
|
|
123
|
+
loading: false,
|
|
124
|
+
result,
|
|
125
|
+
error: result.apiCatchResult
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
} catch (error) {
|
|
129
|
+
this.setState({
|
|
130
|
+
apiCatchResultState: { loading: false, result: null, error }
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
85
135
|
onTriggerAbortRequest = async () => {
|
|
86
136
|
if (this.state.abortState.loading) {
|
|
87
137
|
this.stopAbortRequest();
|
|
@@ -90,9 +140,11 @@ export class RequestController extends FeController<RequestControllerState> {
|
|
|
90
140
|
|
|
91
141
|
this.setState({ abortState: { loading: true, result: null, error: null } });
|
|
92
142
|
try {
|
|
93
|
-
await this.
|
|
143
|
+
await this.userApi.request({
|
|
94
144
|
method: 'GET',
|
|
95
|
-
url: 'https://api.example.com/users'
|
|
145
|
+
url: 'https://api.example.com/users',
|
|
146
|
+
disabledMock: true,
|
|
147
|
+
requestId: 'onTriggerAbortRequest'
|
|
96
148
|
});
|
|
97
149
|
} catch (error) {
|
|
98
150
|
this.setState({ abortState: { loading: false, result: null, error } });
|
|
@@ -100,6 +152,8 @@ export class RequestController extends FeController<RequestControllerState> {
|
|
|
100
152
|
};
|
|
101
153
|
|
|
102
154
|
stopAbortRequest = async () => {
|
|
103
|
-
this.
|
|
155
|
+
this.userApi.stop({
|
|
156
|
+
requestId: 'onTriggerAbortRequest'
|
|
157
|
+
});
|
|
104
158
|
};
|
|
105
159
|
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { RouteConfig } from '@/base/types/Page';
|
|
1
|
+
import type { RouteConfigValue } from '@/base/cases/router-loader';
|
|
2
|
+
import type { NavigateFunction, NavigateOptions } from 'react-router-dom';
|
|
3
|
+
import type { UIDependenciesInterface } from '@/base/port/UIDependenciesInterface';
|
|
4
|
+
import { I18nService } from '@/base/services/I18nService';
|
|
5
|
+
import { Logger } from '@qlover/fe-corekit';
|
|
7
6
|
|
|
8
7
|
export type RouterControllerDependencies = {
|
|
9
8
|
navigate: NavigateFunction;
|
|
10
9
|
};
|
|
11
10
|
|
|
12
11
|
export type RouterControllerOptions = {
|
|
13
|
-
config:
|
|
12
|
+
config: {
|
|
13
|
+
routes: RouteConfigValue[];
|
|
14
|
+
};
|
|
14
15
|
logger: Logger;
|
|
15
16
|
};
|
|
16
17
|
|
|
@@ -1,66 +1,58 @@
|
|
|
1
|
-
import { ExecutorPlugin } from '@qlover/fe-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { ExecutorPlugin } from '@qlover/fe-corekit';
|
|
2
|
+
import type {
|
|
3
|
+
UserApiGetUserInfoTransaction,
|
|
4
|
+
UserApiLoginTransaction
|
|
5
|
+
} from '@/base/apis/userApi/UserApiType';
|
|
6
6
|
import { RouterController } from './RouterController';
|
|
7
|
-
import { StorageTokenInterface } from '
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
params: FeApiLogin['request']
|
|
23
|
-
): Promise<FeApiGetUserInfo['response']['data']>;
|
|
24
|
-
logout(): void;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function createDefaultState(
|
|
28
|
-
options: UserControllerOptions
|
|
29
|
-
): UserControllerState {
|
|
30
|
-
const { userToken } = options;
|
|
31
|
-
const token = userToken.getToken();
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
success: !!token,
|
|
35
|
-
userInfo: {
|
|
36
|
-
name: '',
|
|
37
|
-
email: '',
|
|
38
|
-
picture: ''
|
|
39
|
-
}
|
|
7
|
+
import { ThreadUtil, type StorageTokenInterface } from '@qlover/corekit-bridge';
|
|
8
|
+
import { inject, injectable } from 'inversify';
|
|
9
|
+
import { IOCIdentifier } from '@/core/IOC';
|
|
10
|
+
import { LoginInterface } from '@/base/port/LoginInterface';
|
|
11
|
+
import { UserApi } from '@/base/apis/userApi/UserApi';
|
|
12
|
+
import { AppError } from '@/base/cases/appError/AppError';
|
|
13
|
+
import { LOCAL_NO_USER_TOKEN } from '@config/ErrorIdentifier';
|
|
14
|
+
import { SliceStore } from '@qlover/slice-store-react';
|
|
15
|
+
|
|
16
|
+
class UserControllerState {
|
|
17
|
+
success: boolean = false;
|
|
18
|
+
userInfo: UserApiGetUserInfoTransaction['response']['data'] = {
|
|
19
|
+
name: '',
|
|
20
|
+
email: '',
|
|
21
|
+
picture: ''
|
|
40
22
|
};
|
|
41
23
|
}
|
|
42
24
|
|
|
25
|
+
@injectable()
|
|
43
26
|
export class UserController
|
|
44
|
-
extends
|
|
27
|
+
extends SliceStore<UserControllerState>
|
|
45
28
|
implements ExecutorPlugin, LoginInterface
|
|
46
29
|
{
|
|
47
30
|
readonly pluginName = 'UserController';
|
|
48
31
|
|
|
49
|
-
constructor(
|
|
50
|
-
|
|
32
|
+
constructor(
|
|
33
|
+
@inject(UserApi) private userApi: UserApi,
|
|
34
|
+
@inject(RouterController) private routerController: RouterController,
|
|
35
|
+
@inject(IOCIdentifier.FeApiToken)
|
|
36
|
+
private userToken: StorageTokenInterface<string>
|
|
37
|
+
) {
|
|
38
|
+
super(() => new UserControllerState());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setState(state: Partial<UserControllerState>): void {
|
|
42
|
+
this.emit({ ...this.state, ...state });
|
|
51
43
|
}
|
|
52
44
|
|
|
53
45
|
/**
|
|
54
46
|
* @override
|
|
55
47
|
*/
|
|
56
48
|
async onBefore(): Promise<void> {
|
|
57
|
-
await sleep(1000);
|
|
49
|
+
await ThreadUtil.sleep(1000);
|
|
58
50
|
|
|
59
|
-
if (!this.
|
|
60
|
-
throw new
|
|
51
|
+
if (!this.userToken.getToken()) {
|
|
52
|
+
throw new AppError(LOCAL_NO_USER_TOKEN);
|
|
61
53
|
}
|
|
62
54
|
|
|
63
|
-
const userInfo = await this.
|
|
55
|
+
const userInfo = await this.userApi.getUserInfo();
|
|
64
56
|
|
|
65
57
|
this.setState({
|
|
66
58
|
success: true,
|
|
@@ -74,29 +66,31 @@ export class UserController
|
|
|
74
66
|
async onError(): Promise<void> {
|
|
75
67
|
this.logout();
|
|
76
68
|
|
|
77
|
-
this.
|
|
69
|
+
this.routerController.gotoLogin();
|
|
78
70
|
}
|
|
79
71
|
|
|
80
72
|
/**
|
|
81
73
|
* @override
|
|
82
74
|
*/
|
|
83
75
|
async login(
|
|
84
|
-
params:
|
|
85
|
-
): Promise<
|
|
86
|
-
const
|
|
76
|
+
params: UserApiLoginTransaction['data']
|
|
77
|
+
): Promise<UserApiGetUserInfoTransaction['response']> {
|
|
78
|
+
const response = await this.userApi.login(params);
|
|
87
79
|
|
|
88
|
-
|
|
80
|
+
if (response.apiCatchResult) {
|
|
81
|
+
throw response.apiCatchResult;
|
|
82
|
+
}
|
|
89
83
|
|
|
90
|
-
this.
|
|
84
|
+
this.userToken.setToken(response.data.token);
|
|
91
85
|
|
|
92
|
-
const userInfo = await
|
|
86
|
+
const userInfo = await this.userApi.getUserInfo();
|
|
93
87
|
|
|
94
88
|
this.setState({
|
|
95
89
|
success: true,
|
|
96
90
|
userInfo: userInfo.data
|
|
97
91
|
});
|
|
98
92
|
|
|
99
|
-
return userInfo
|
|
93
|
+
return userInfo;
|
|
100
94
|
}
|
|
101
95
|
|
|
102
96
|
/**
|
|
@@ -110,7 +104,7 @@ export class UserController
|
|
|
110
104
|
* @override
|
|
111
105
|
*/
|
|
112
106
|
reset(): void {
|
|
113
|
-
this.
|
|
107
|
+
this.userToken.removeToken();
|
|
114
108
|
super.reset();
|
|
115
109
|
}
|
|
116
110
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { I18nService } from '@/services/I18nService';
|
|
2
|
-
import { I18nServiceLocale } from '@config/i18n';
|
|
1
|
+
import { I18nService, I18nServiceLocale } from '@/base/services/I18nService';
|
|
3
2
|
import { useEffect } from 'react';
|
|
4
3
|
import { useNavigate } from 'react-router-dom';
|
|
5
4
|
import { useParams } from 'react-router-dom';
|
|
@@ -2,12 +2,12 @@ import { createContext, useEffect } from 'react';
|
|
|
2
2
|
import { IOC } from '@/core/IOC';
|
|
3
3
|
import { useLanguageGuard } from '@/uikit/hooks/useLanguageGuard';
|
|
4
4
|
import { useStrictEffect } from '@/uikit/hooks/useStrictEffect';
|
|
5
|
-
import { ProcesserService } from '@/services/
|
|
5
|
+
import { ProcesserService } from '@/base/services/ProcesserService';
|
|
6
6
|
import { Navigate, useNavigate } from 'react-router-dom';
|
|
7
|
-
import {
|
|
8
|
-
import { Loading } from '@/components/Loading';
|
|
7
|
+
import { Loading } from '@/uikit/components/Loading';
|
|
9
8
|
import { RouterController } from '../controllers/RouterController';
|
|
10
9
|
import { UserController } from '../controllers/UserController';
|
|
10
|
+
import { useSliceStore } from '@qlover/slice-store-react';
|
|
11
11
|
|
|
12
12
|
const PageProcesserContext = createContext<ProcesserService>(
|
|
13
13
|
IOC(ProcesserService)
|
|
@@ -17,7 +17,7 @@ export function ProcessProvider({ children }: { children: React.ReactNode }) {
|
|
|
17
17
|
useLanguageGuard();
|
|
18
18
|
const userController = IOC(UserController);
|
|
19
19
|
const pageProcesser = IOC(ProcesserService);
|
|
20
|
-
const
|
|
20
|
+
const success = useSliceStore(userController, (state) => state.success);
|
|
21
21
|
|
|
22
22
|
const navigate = useNavigate();
|
|
23
23
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
@import './tailwind.css';
|
|
2
|
-
@import './page.css';
|
|
2
|
+
@import './page.css';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import root10px from './lib/
|
|
2
|
-
import themeCreate from './lib/
|
|
1
|
+
import root10px from './lib/tailwind/root10px';
|
|
2
|
+
import themeCreate from './lib/tailwind/theme-generator';
|
|
3
3
|
import themeConfig from './config/theme.json';
|
|
4
4
|
|
|
5
5
|
const theme = themeCreate(themeConfig.override);
|
|
@@ -6,9 +6,8 @@
|
|
|
6
6
|
"moduleResolution": "bundler",
|
|
7
7
|
"allowSyntheticDefaultImports": true,
|
|
8
8
|
"paths": {
|
|
9
|
-
"@lib/*": ["./lib/*"],
|
|
10
9
|
"@config/*": ["./config/*"]
|
|
11
10
|
}
|
|
12
11
|
},
|
|
13
|
-
"include": ["vite.config.ts", "
|
|
12
|
+
"include": ["vite.config.ts", "fe-prod", "config"]
|
|
14
13
|
}
|
|
@@ -1,38 +1,33 @@
|
|
|
1
1
|
import { defineConfig } from 'vitest/config';
|
|
2
2
|
import react from '@vitejs/plugin-react';
|
|
3
|
-
import alias from '@rollup/plugin-alias';
|
|
4
|
-
import tsappconfig from './tsconfig.json';
|
|
5
|
-
import { resolve } from 'path';
|
|
6
|
-
import { Env } from '@qlover/env-loader';
|
|
7
3
|
import { envPrefix } from './config/common';
|
|
8
4
|
import { name, version } from './package.json';
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const tsAppPaths = tsappconfig.compilerOptions.paths || {};
|
|
14
|
-
|
|
15
|
-
// add version and name to env
|
|
16
|
-
injectPkgConfig(
|
|
17
|
-
[
|
|
18
|
-
['APP_NAME', name],
|
|
19
|
-
['APP_VERSION', version]
|
|
20
|
-
],
|
|
21
|
-
envPrefix
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
// convert tsconfig paths to vite alias
|
|
25
|
-
const entries = Object.entries(tsAppPaths).reduce((acc, [key, value]) => {
|
|
26
|
-
acc[key.replace('/*', '')] = resolve(__dirname, value[0].replace('/*', ''));
|
|
27
|
-
return acc;
|
|
28
|
-
}, {});
|
|
5
|
+
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
6
|
+
import envConfig from '@qlover/corekit-bridge/build/vite-env-config';
|
|
7
|
+
import ts2Locales from '@qlover/corekit-bridge/build/vite-ts-to-locales';
|
|
8
|
+
import i18nConfig from './config/i18n';
|
|
29
9
|
|
|
30
10
|
// https://vite.dev/config/
|
|
31
11
|
export default defineConfig({
|
|
32
12
|
plugins: [
|
|
13
|
+
envConfig({
|
|
14
|
+
envPops: true,
|
|
15
|
+
envPrefix,
|
|
16
|
+
records: [
|
|
17
|
+
['APP_NAME', name],
|
|
18
|
+
['APP_VERSION', version]
|
|
19
|
+
]
|
|
20
|
+
}),
|
|
33
21
|
react(),
|
|
34
|
-
|
|
35
|
-
|
|
22
|
+
tsconfigPaths(),
|
|
23
|
+
ts2Locales({
|
|
24
|
+
locales: i18nConfig.supportedLngs as unknown as string[],
|
|
25
|
+
options: [
|
|
26
|
+
{
|
|
27
|
+
source: './config/ErrorIdentifier.ts',
|
|
28
|
+
target: './public/locales/{{lng}}/common.json'
|
|
29
|
+
}
|
|
30
|
+
]
|
|
36
31
|
})
|
|
37
32
|
],
|
|
38
33
|
envPrefix: envPrefix,
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
NODE_ENV=local
|
|
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=
|
|
14
|
-
VITE_SERVER_PORT=3200
|
|
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://openai-proxy.brain.loocaa.com:1443/v1/
|
|
20
|
-
VITE_OPEN_AI_TOKEN=DlJYSkMVj1x4zoe8jZnjvxfHG6z5yGxK
|
|
21
|
-
VITE_OPEN_AI_TOKEN_PREFIX=Bearer
|
|
22
|
-
VITE_OPEN_AI_REQUIRE_TOKEN=true
|
|
23
|
-
VITE_LOGIN_USER=admin
|
|
24
|
-
VITE_LOGIN_PASSWORD=123456
|
|
@@ -1,36 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
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>;
|
|
@@ -1,33 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
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';
|
|
@@ -1,61 +0,0 @@
|
|
|
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
|
-
}
|