@qlover/create-app 0.11.0 → 1.0.0
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 +18 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +3 -3
- package/dist/templates/next-app/eslint.config.mjs +76 -1
- package/dist/templates/next-app/next.config.ts +4 -3
- package/dist/templates/next-app/package.json +15 -11
- package/dist/templates/next-app/src/app/[locale]/login/LoginForm.tsx +2 -3
- package/dist/templates/next-app/src/base/cases/DialogErrorPlugin.ts +6 -4
- package/dist/templates/next-app/src/base/cases/RequestEncryptPlugin.ts +14 -10
- package/dist/templates/next-app/src/base/cases/StringEncryptor.ts +2 -2
- package/dist/templates/next-app/src/base/port/I18nServiceInterface.ts +1 -4
- package/dist/templates/next-app/src/base/services/I18nService.ts +6 -2
- package/dist/templates/next-app/src/base/services/adminApi/AdminApiRequester.ts +11 -7
- package/dist/templates/next-app/src/base/services/adminApi/AdminLocalesApi.ts +11 -10
- package/dist/templates/next-app/src/base/services/adminApi/AdminUserApi.ts +16 -12
- package/dist/templates/next-app/src/base/services/appApi/AppApiPlugin.ts +19 -19
- package/dist/templates/next-app/src/base/services/appApi/AppApiRequester.ts +26 -21
- package/dist/templates/next-app/src/base/services/appApi/AppUserApi.ts +15 -6
- package/dist/templates/next-app/src/base/services/appApi/AppUserApiBootstrap.ts +12 -14
- package/dist/templates/next-app/src/core/bootstraps/BootstrapServer.ts +34 -17
- package/dist/templates/next-app/src/server/NextApiServer.ts +10 -4
- package/dist/templates/next-app/src/server/PasswordEncrypt.ts +2 -2
- package/dist/templates/next-app/src/server/controllers/UserController.ts +2 -2
- package/dist/templates/next-app/src/server/port/ServerInterface.ts +2 -2
- package/dist/templates/next-app/src/server/services/AdminAuthPlugin.ts +6 -7
- package/dist/templates/next-app/src/server/services/UserService.ts +2 -2
- package/dist/templates/next-app/src/uikit/components/BootstrapsProvider.tsx +11 -47
- package/dist/templates/react-app/__tests__/__mocks__/MockDialogHandler.ts +3 -2
- package/dist/templates/react-app/__tests__/__mocks__/createMockGlobals.ts +6 -1
- package/dist/templates/react-app/__tests__/src/base/cases/I18nKeyErrorPlugin.test.ts +21 -61
- package/dist/templates/react-app/__tests__/src/base/cases/RequestLogger.test.ts +29 -51
- package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapClient.test.ts +8 -26
- package/dist/templates/react-app/__tests__/src/main.test.tsx +2 -2
- package/dist/templates/react-app/config/IOCIdentifier.ts +1 -1
- package/dist/templates/react-app/docs/en/test-guide.md +5 -5
- package/dist/templates/react-app/docs/zh/test-guide.md +5 -5
- package/dist/templates/react-app/eslint.config.mjs +79 -7
- package/dist/templates/react-app/package.json +4 -3
- package/dist/templates/react-app/src/base/apis/AiApi.ts +20 -12
- package/dist/templates/react-app/src/base/apis/feApi/FeApi.ts +14 -5
- package/dist/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +29 -13
- package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +35 -34
- package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +23 -17
- package/dist/templates/react-app/src/base/cases/I18nKeyErrorPlugin.ts +11 -5
- package/dist/templates/react-app/src/base/cases/RequestLanguages.ts +19 -6
- package/dist/templates/react-app/src/base/cases/RequestLogger.ts +11 -11
- package/dist/templates/react-app/src/base/services/BaseLayoutService.ts +11 -5
- package/dist/templates/react-app/src/base/services/I18nService.ts +3 -0
- package/dist/templates/react-app/src/base/services/IdentifierService.ts +24 -0
- package/dist/templates/react-app/src/base/services/UserBootstrap.ts +9 -7
- package/dist/templates/react-app/src/base/services/UserService.ts +4 -5
- package/dist/templates/react-app/src/core/clientIoc/ClientIOCRegister.ts +6 -7
- package/dist/templates/react-app/src/main.tsx +1 -1
- package/dist/templates/react-app/src/pages/auth/LoginPage.tsx +5 -5
- package/dist/templates/react-app/src/pages/base/ExecutorPage.tsx +3 -1
- package/dist/templates/react-app/src/pages/base/JSONStoragePage.tsx +6 -2
- package/dist/templates/react-app/src/pages/base/MessagePage.tsx +34 -3
- package/dist/templates/react-app/src/uikit/bridges/ExecutorPageBridge.ts +13 -7
- package/dist/templates/react-app/src/uikit/components/LogoutButton.tsx +6 -1
- package/dist/templates/react-app/src/uikit/components/MessageBaseList.tsx +26 -11
- package/dist/templates/react-app/src/uikit/components/chatMessage/ChatMessageBridge.ts +7 -1
- package/dist/templates/react-app/src/uikit/components/chatMessage/FocusBar.tsx +3 -1
- package/dist/templates/react-app/src/uikit/components/chatMessage/MessageApi.ts +16 -7
- package/dist/templates/react-app/src/vite-env.d.ts +1 -1
- package/dist/templates/react-app/tsconfig.e2e.json +5 -2
- package/dist/templates/react-app/tsconfig.json +7 -0
- package/dist/templates/react-app/tsconfig.node.json +4 -2
- package/dist/templates/react-app/tsconfig.test.json +4 -1
- package/package.json +4 -3
- package/dist/templates/react-app/src/base/cases/AppError.ts +0 -10
- package/dist/templates/react-app/src/base/port/ProcesserExecutorInterface.ts +0 -20
- package/dist/templates/react-app/src/base/services/UserGatewayPlugin.ts +0 -20
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { RES_NO_TOKEN } from '@config/Identifier';
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Aborter,
|
|
4
|
+
AborterConfig,
|
|
5
|
+
type AborterInterface,
|
|
6
|
+
ExecutorContextInterface,
|
|
7
|
+
ExecutorError,
|
|
8
|
+
LifecycleExecutor,
|
|
9
|
+
type RequestAdapterInterface,
|
|
10
|
+
RequestExecutor
|
|
6
11
|
} from '@qlover/fe-corekit';
|
|
7
12
|
import { inject, injectable } from 'inversify';
|
|
8
|
-
import { AppError } from '@/base/cases/AppError';
|
|
9
13
|
import { UserApiAdapter } from './UserApiAdapter';
|
|
10
14
|
import { UserApiConfig } from './UserApiBootstarp';
|
|
11
15
|
import {
|
|
@@ -17,10 +21,7 @@ import {
|
|
|
17
21
|
UserInfo,
|
|
18
22
|
UserCredential
|
|
19
23
|
} from './UserApiType';
|
|
20
|
-
import type {
|
|
21
|
-
UserAuthStoreInterface,
|
|
22
|
-
UserServiceGateway
|
|
23
|
-
} from '@qlover/corekit-bridge';
|
|
24
|
+
import type { UserServiceGateway } from '@qlover/corekit-bridge';
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* UserApi
|
|
@@ -31,27 +32,20 @@ import type {
|
|
|
31
32
|
*/
|
|
32
33
|
@injectable()
|
|
33
34
|
export class UserApi
|
|
34
|
-
extends
|
|
35
|
+
extends RequestExecutor<
|
|
36
|
+
UserApiConfig,
|
|
37
|
+
ExecutorContextInterface<UserApiConfig>
|
|
38
|
+
>
|
|
35
39
|
implements UserServiceGateway<UserInfo, UserCredential>
|
|
36
40
|
{
|
|
37
|
-
protected store: UserAuthStoreInterface<UserInfo> | null = null;
|
|
38
|
-
|
|
39
41
|
constructor(
|
|
40
|
-
@inject(
|
|
41
|
-
@inject(UserApiAdapter) adapter:
|
|
42
|
+
@inject(Aborter) protected abortPlugin: AborterInterface<AborterConfig>,
|
|
43
|
+
@inject(UserApiAdapter) adapter: RequestAdapterInterface<UserApiConfig>
|
|
42
44
|
) {
|
|
43
|
-
super(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return this.store;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* @param store
|
|
52
|
-
*/
|
|
53
|
-
public setStore(store: UserAuthStoreInterface<UserInfo>): void {
|
|
54
|
-
this.store = store;
|
|
45
|
+
super(
|
|
46
|
+
adapter,
|
|
47
|
+
new LifecycleExecutor<ExecutorContextInterface<UserApiConfig, unknown>>()
|
|
48
|
+
);
|
|
55
49
|
}
|
|
56
50
|
|
|
57
51
|
public stop(request: UserApiConfig): Promise<void> | void {
|
|
@@ -59,7 +53,7 @@ export class UserApi
|
|
|
59
53
|
}
|
|
60
54
|
|
|
61
55
|
public async getRandomUser(): Promise<GetIpInfoTransaction['response']> {
|
|
62
|
-
return this.request
|
|
56
|
+
return this.request({
|
|
63
57
|
url: 'https://randomuser.me/api/',
|
|
64
58
|
method: 'GET',
|
|
65
59
|
disabledMock: true
|
|
@@ -69,7 +63,7 @@ export class UserApi
|
|
|
69
63
|
public async testApiCatchResult(): Promise<
|
|
70
64
|
UserApiTestApiCatchResultTransaction['response']
|
|
71
65
|
> {
|
|
72
|
-
return this.request
|
|
66
|
+
return this.request({
|
|
73
67
|
url: 'https://randomuser.me/api/?_name=ApiCatchResult',
|
|
74
68
|
method: 'GET',
|
|
75
69
|
disabledMock: true,
|
|
@@ -78,29 +72,31 @@ export class UserApi
|
|
|
78
72
|
}
|
|
79
73
|
|
|
80
74
|
/**
|
|
75
|
+
* @override
|
|
81
76
|
* @param params
|
|
82
77
|
* @returns
|
|
83
78
|
*/
|
|
84
79
|
public async login(
|
|
85
80
|
params: UserApiLoginTransaction['data']
|
|
86
81
|
): Promise<UserCredential> {
|
|
87
|
-
const response = await this.post<
|
|
88
|
-
'
|
|
89
|
-
|
|
90
|
-
);
|
|
82
|
+
const response = await this.post<
|
|
83
|
+
UserApiLoginTransaction['response'],
|
|
84
|
+
UserApiLoginTransaction['data']
|
|
85
|
+
>('/api/login', params);
|
|
91
86
|
|
|
92
87
|
if (response.apiCatchResult) {
|
|
93
88
|
throw response.apiCatchResult;
|
|
94
89
|
}
|
|
95
90
|
|
|
96
91
|
if (!response.data.token) {
|
|
97
|
-
throw new
|
|
92
|
+
throw new ExecutorError(RES_NO_TOKEN);
|
|
98
93
|
}
|
|
99
94
|
|
|
100
95
|
return response.data;
|
|
101
96
|
}
|
|
102
97
|
|
|
103
98
|
/**
|
|
99
|
+
* @override
|
|
104
100
|
* @param params
|
|
105
101
|
* @returns
|
|
106
102
|
*/
|
|
@@ -112,6 +108,7 @@ export class UserApi
|
|
|
112
108
|
}
|
|
113
109
|
|
|
114
110
|
/**
|
|
111
|
+
* @override
|
|
115
112
|
* @returns
|
|
116
113
|
*/
|
|
117
114
|
public async refreshUserInfo(): Promise<UserInfo> {
|
|
@@ -119,6 +116,7 @@ export class UserApi
|
|
|
119
116
|
}
|
|
120
117
|
|
|
121
118
|
/**
|
|
119
|
+
* @override
|
|
122
120
|
* @returns
|
|
123
121
|
*/
|
|
124
122
|
public logout(): Promise<any> {
|
|
@@ -126,11 +124,14 @@ export class UserApi
|
|
|
126
124
|
}
|
|
127
125
|
|
|
128
126
|
/**
|
|
127
|
+
* @override
|
|
129
128
|
* @returns
|
|
130
129
|
*/
|
|
131
130
|
public async getUserInfo(_credential?: UserCredential): Promise<UserInfo> {
|
|
132
|
-
const response =
|
|
133
|
-
|
|
131
|
+
const response = await this.get<
|
|
132
|
+
UserApiGetUserInfoTransaction['response'],
|
|
133
|
+
UserApiGetUserInfoTransaction['data']
|
|
134
|
+
>('/api/userinfo');
|
|
134
135
|
|
|
135
136
|
if (response.apiCatchResult) {
|
|
136
137
|
throw response.apiCatchResult;
|
|
@@ -6,15 +6,19 @@ import {
|
|
|
6
6
|
type ApiCatchPluginConfig,
|
|
7
7
|
type ApiCatchPluginResponse
|
|
8
8
|
} from '@qlover/corekit-bridge';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
Aborter,
|
|
11
|
+
AborterPlugin,
|
|
12
|
+
RequestPlugin,
|
|
13
|
+
ResponsePlugin,
|
|
14
|
+
type AborterConfig,
|
|
15
|
+
type RequestAdapterConfig,
|
|
16
|
+
type RequestAdapterResponse
|
|
17
|
+
} from '@qlover/fe-corekit';
|
|
18
|
+
import { RequestLanguages } from '@/base/cases/RequestLanguages';
|
|
10
19
|
import { RequestLogger } from '@/base/cases/RequestLogger';
|
|
11
20
|
import { UserApi } from './UserApi';
|
|
12
|
-
import {
|
|
13
|
-
import type {
|
|
14
|
-
RequestAdapterConfig,
|
|
15
|
-
RequestAdapterResponse,
|
|
16
|
-
RequestTransactionInterface
|
|
17
|
-
} from '@qlover/fe-corekit';
|
|
21
|
+
import type { RequestTransactionInterface } from '../feApi/FeApiBootstarp';
|
|
18
22
|
|
|
19
23
|
/**
|
|
20
24
|
* UserApiConfig
|
|
@@ -30,7 +34,8 @@ export interface UserApiConfig<Request = unknown>
|
|
|
30
34
|
extends
|
|
31
35
|
RequestAdapterConfig<Request>,
|
|
32
36
|
ApiMockPluginOptions,
|
|
33
|
-
ApiCatchPluginConfig
|
|
37
|
+
ApiCatchPluginConfig,
|
|
38
|
+
AborterConfig {}
|
|
34
39
|
|
|
35
40
|
/**
|
|
36
41
|
* UserApiResponse
|
|
@@ -64,17 +69,18 @@ export interface UserApiTransaction<
|
|
|
64
69
|
export class UserApiBootstarp implements BootstrapExecutorPlugin {
|
|
65
70
|
public readonly pluginName = 'UserApiBootstarp';
|
|
66
71
|
|
|
72
|
+
/**
|
|
73
|
+
* @override
|
|
74
|
+
*/
|
|
67
75
|
public onBefore({ parameters: { ioc } }: BootstrapContext): void {
|
|
68
76
|
ioc
|
|
69
77
|
.get<UserApi>(UserApi)
|
|
70
|
-
.
|
|
71
|
-
.
|
|
72
|
-
.
|
|
73
|
-
|
|
74
|
-
)
|
|
75
|
-
.
|
|
76
|
-
.
|
|
77
|
-
.usePlugin(ioc.get(FetchAbortPlugin))
|
|
78
|
-
.usePlugin(ioc.get(IOCIdentifier.ApiCatchPlugin));
|
|
78
|
+
.use(new RequestPlugin())
|
|
79
|
+
.use(ioc.get(ResponsePlugin))
|
|
80
|
+
.use(new AborterPlugin(ioc.get(Aborter)))
|
|
81
|
+
.use(new RequestLanguages(ioc.get(IOCIdentifier.I18nServiceInterface)))
|
|
82
|
+
.use(ioc.get(IOCIdentifier.ApiMockPlugin))
|
|
83
|
+
.use(ioc.get(IOCIdentifier.ApiCatchPlugin))
|
|
84
|
+
.use(ioc.get(RequestLogger));
|
|
79
85
|
}
|
|
80
86
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
2
2
|
import {
|
|
3
|
+
ExecutorContextInterface,
|
|
3
4
|
ExecutorError,
|
|
4
|
-
|
|
5
|
-
type ExecutorPlugin
|
|
5
|
+
LifecyclePluginInterface
|
|
6
6
|
} from '@qlover/fe-corekit';
|
|
7
7
|
import { inject, injectable } from 'inversify';
|
|
8
8
|
import type { I18nServiceInterface } from '../port/I18nServiceInterface';
|
|
@@ -14,7 +14,9 @@ import type { LoggerInterface } from '@qlover/logger';
|
|
|
14
14
|
* If the error thrown is an i18n key, it will be converted to the corresponding text
|
|
15
15
|
*/
|
|
16
16
|
@injectable()
|
|
17
|
-
export class I18nKeyErrorPlugin implements
|
|
17
|
+
export class I18nKeyErrorPlugin implements LifecyclePluginInterface<
|
|
18
|
+
ExecutorContextInterface<unknown, unknown>
|
|
19
|
+
> {
|
|
18
20
|
public readonly pluginName = 'I18nKeyErrorPlugin';
|
|
19
21
|
|
|
20
22
|
constructor(
|
|
@@ -30,7 +32,9 @@ export class I18nKeyErrorPlugin implements ExecutorPlugin {
|
|
|
30
32
|
/**
|
|
31
33
|
* @override
|
|
32
34
|
*/
|
|
33
|
-
public onError(
|
|
35
|
+
public onError(
|
|
36
|
+
context: ExecutorContextInterface<unknown, unknown>
|
|
37
|
+
): ExecutorError | void {
|
|
34
38
|
const { error } = context;
|
|
35
39
|
|
|
36
40
|
if (!error) {
|
|
@@ -39,6 +43,7 @@ export class I18nKeyErrorPlugin implements ExecutorPlugin {
|
|
|
39
43
|
|
|
40
44
|
if (error instanceof ExecutorError) {
|
|
41
45
|
const i18nText = this.translateById(error.id);
|
|
46
|
+
this.logger.error('i18nText', i18nText);
|
|
42
47
|
return new ExecutorError(error.id, i18nText);
|
|
43
48
|
}
|
|
44
49
|
|
|
@@ -50,7 +55,8 @@ export class I18nKeyErrorPlugin implements ExecutorPlugin {
|
|
|
50
55
|
|
|
51
56
|
if (i18nText && i18nText !== i18nKey) {
|
|
52
57
|
this.logger.debug('I18nKeyErrorPlugin Error:', i18nText);
|
|
53
|
-
|
|
58
|
+
// Use i18nText as cause (string) so ExecutorError.message will be the translated text
|
|
59
|
+
return new ExecutorError(i18nKey, i18nText);
|
|
54
60
|
}
|
|
55
61
|
}
|
|
56
62
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { I18nServiceInterface } from '@/base/port/I18nServiceInterface';
|
|
2
2
|
import type {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
ExecutorContextInterface,
|
|
4
|
+
LifecyclePluginInterface,
|
|
5
5
|
RequestAdapterConfig
|
|
6
6
|
} from '@qlover/fe-corekit';
|
|
7
7
|
|
|
8
|
-
export class RequestLanguages implements
|
|
8
|
+
export class RequestLanguages implements LifecyclePluginInterface<
|
|
9
|
+
ExecutorContextInterface<RequestAdapterConfig, unknown>
|
|
10
|
+
> {
|
|
9
11
|
public readonly pluginName = 'RequestLanguages';
|
|
10
12
|
|
|
11
13
|
constructor(
|
|
@@ -25,18 +27,29 @@ export class RequestLanguages implements ExecutorPlugin {
|
|
|
25
27
|
/**
|
|
26
28
|
* @override
|
|
27
29
|
*/
|
|
28
|
-
public onBefore(
|
|
30
|
+
public onBefore(
|
|
31
|
+
context: ExecutorContextInterface<RequestAdapterConfig, unknown>
|
|
32
|
+
): void {
|
|
29
33
|
const currentLanguage = this.i18nService.getCurrentLanguage();
|
|
30
34
|
const languages = this.i18nService.getSupportedLanguages();
|
|
31
35
|
|
|
32
36
|
if (!context.parameters.headers) {
|
|
33
|
-
context.
|
|
37
|
+
context.setParameters({
|
|
38
|
+
...context.parameters,
|
|
39
|
+
headers: {}
|
|
40
|
+
});
|
|
34
41
|
}
|
|
35
42
|
|
|
36
43
|
const languageValue = this.buildAcceptLanguage(
|
|
37
44
|
Array.from(new Set([currentLanguage, ...languages]))
|
|
38
45
|
);
|
|
39
46
|
|
|
40
|
-
context.
|
|
47
|
+
context.setParameters({
|
|
48
|
+
...context.parameters,
|
|
49
|
+
headers: {
|
|
50
|
+
...context.parameters.headers,
|
|
51
|
+
[this.headerName]: languageValue
|
|
52
|
+
}
|
|
53
|
+
});
|
|
41
54
|
}
|
|
42
55
|
}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
2
|
+
import { type ApiCatchPluginResponse } from '@qlover/corekit-bridge';
|
|
2
3
|
import {
|
|
3
|
-
type
|
|
4
|
-
type
|
|
5
|
-
} from '@qlover/corekit-bridge';
|
|
6
|
-
import {
|
|
7
|
-
type ExecutorPlugin,
|
|
8
|
-
type ExecutorContext,
|
|
4
|
+
type LifecyclePluginInterface,
|
|
5
|
+
type ExecutorContextInterface,
|
|
9
6
|
type RequestAdapterFetchConfig,
|
|
10
7
|
type RequestAdapterResponse
|
|
11
8
|
} from '@qlover/fe-corekit';
|
|
@@ -13,7 +10,9 @@ import { injectable, inject } from 'inversify';
|
|
|
13
10
|
import type { LoggerInterface } from '@qlover/logger';
|
|
14
11
|
|
|
15
12
|
@injectable()
|
|
16
|
-
export class RequestLogger implements
|
|
13
|
+
export class RequestLogger implements LifecyclePluginInterface<
|
|
14
|
+
ExecutorContextInterface<RequestAdapterFetchConfig, unknown>
|
|
15
|
+
> {
|
|
17
16
|
public readonly pluginName = 'RequestLogger';
|
|
18
17
|
|
|
19
18
|
constructor(@inject(IOCIdentifier.Logger) public logger: LoggerInterface) {}
|
|
@@ -22,7 +21,7 @@ export class RequestLogger implements ExecutorPlugin<RequestAdapterFetchConfig>
|
|
|
22
21
|
* @override
|
|
23
22
|
*/
|
|
24
23
|
public onBefore(
|
|
25
|
-
context:
|
|
24
|
+
context: ExecutorContextInterface<RequestAdapterFetchConfig, unknown>
|
|
26
25
|
): void {
|
|
27
26
|
this.logger.log(
|
|
28
27
|
`%c[Request before]%c [${new Date().toLocaleString()}] ${context.parameters.method} ${context.parameters.url}`,
|
|
@@ -38,8 +37,9 @@ export class RequestLogger implements ExecutorPlugin<RequestAdapterFetchConfig>
|
|
|
38
37
|
public async onSuccess({
|
|
39
38
|
parameters,
|
|
40
39
|
returnValue
|
|
41
|
-
}:
|
|
42
|
-
RequestAdapterFetchConfig
|
|
40
|
+
}: ExecutorContextInterface<
|
|
41
|
+
RequestAdapterFetchConfig,
|
|
42
|
+
unknown
|
|
43
43
|
>): Promise<void> {
|
|
44
44
|
const _returnValue = returnValue as RequestAdapterResponse &
|
|
45
45
|
ApiCatchPluginResponse;
|
|
@@ -65,7 +65,7 @@ export class RequestLogger implements ExecutorPlugin<RequestAdapterFetchConfig>
|
|
|
65
65
|
public onError({
|
|
66
66
|
parameters,
|
|
67
67
|
error
|
|
68
|
-
}:
|
|
68
|
+
}: ExecutorContextInterface<RequestAdapterFetchConfig, unknown>): void {
|
|
69
69
|
this.loggerError(parameters, error);
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import { I } from '@config/IOCIdentifier';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ExecutorContextInterface,
|
|
4
|
+
LifecycleExecutor,
|
|
5
|
+
LifecyclePluginInterface
|
|
6
|
+
} from '@qlover/fe-corekit';
|
|
3
7
|
import { injectable, inject } from 'inversify';
|
|
4
8
|
import { UserBootstrap } from './UserBootstrap';
|
|
5
9
|
import type { RouteServiceInterface } from '../port/RouteServiceInterface';
|
|
6
10
|
import type { UserServiceInterface } from '../port/UserServiceInterface';
|
|
7
11
|
import type {
|
|
8
|
-
|
|
12
|
+
BootstrapPluginOptions,
|
|
9
13
|
IOCContainerInterface
|
|
10
14
|
} from '@qlover/corekit-bridge';
|
|
11
15
|
import type { LoggerInterface } from '@qlover/logger';
|
|
12
16
|
|
|
13
17
|
@injectable()
|
|
14
18
|
export class BaseLayoutService {
|
|
15
|
-
protected executor:
|
|
19
|
+
protected executor: LifecycleExecutor = new LifecycleExecutor();
|
|
16
20
|
|
|
17
21
|
constructor(
|
|
18
22
|
@inject(I.Logger) protected logger: LoggerInterface,
|
|
@@ -24,7 +28,9 @@ export class BaseLayoutService {
|
|
|
24
28
|
this.use(new UserBootstrap(userService));
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
public use(
|
|
31
|
+
public use(
|
|
32
|
+
plugin: LifecyclePluginInterface<ExecutorContextInterface<unknown, unknown>>
|
|
33
|
+
): this {
|
|
28
34
|
this.executor.use(plugin);
|
|
29
35
|
return this;
|
|
30
36
|
}
|
|
@@ -36,7 +42,7 @@ export class BaseLayoutService {
|
|
|
36
42
|
}
|
|
37
43
|
|
|
38
44
|
public async starup(ioc: IOCContainerInterface): Promise<unknown> {
|
|
39
|
-
const context:
|
|
45
|
+
const context: BootstrapPluginOptions = {
|
|
40
46
|
root: {},
|
|
41
47
|
logger: this.logger,
|
|
42
48
|
ioc: ioc
|
|
@@ -62,6 +62,9 @@ export class IdentifierService<T> implements ResourceServiceInterface<
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* @override
|
|
67
|
+
*/
|
|
65
68
|
public async created(): Promise<unknown> {
|
|
66
69
|
this.unsubscribe = this.i18nService.observe(
|
|
67
70
|
(state) => state.language,
|
|
@@ -73,6 +76,9 @@ export class IdentifierService<T> implements ResourceServiceInterface<
|
|
|
73
76
|
return this.init();
|
|
74
77
|
}
|
|
75
78
|
|
|
79
|
+
/**
|
|
80
|
+
* @override
|
|
81
|
+
*/
|
|
76
82
|
public destroyed(): void {
|
|
77
83
|
this.unsubscribe?.();
|
|
78
84
|
this.unsubscribe = null;
|
|
@@ -80,8 +86,14 @@ export class IdentifierService<T> implements ResourceServiceInterface<
|
|
|
80
86
|
this.store.reset();
|
|
81
87
|
}
|
|
82
88
|
|
|
89
|
+
/**
|
|
90
|
+
* @override
|
|
91
|
+
*/
|
|
83
92
|
public updated(): void {}
|
|
84
93
|
|
|
94
|
+
/**
|
|
95
|
+
* @override
|
|
96
|
+
*/
|
|
85
97
|
public async search(
|
|
86
98
|
params: Partial<ResourceQuery & { locale: LocaleType }>
|
|
87
99
|
): Promise<PaginationInterface<IdentifierRecord>> {
|
|
@@ -122,16 +134,28 @@ export class IdentifierService<T> implements ResourceServiceInterface<
|
|
|
122
134
|
return this.search(this.store.state.searchParams);
|
|
123
135
|
}
|
|
124
136
|
|
|
137
|
+
/**
|
|
138
|
+
* @override
|
|
139
|
+
*/
|
|
125
140
|
public async update(_data: Partial<T>): Promise<unknown> {
|
|
126
141
|
return Promise.resolve(null);
|
|
127
142
|
}
|
|
128
143
|
|
|
144
|
+
/**
|
|
145
|
+
* @override
|
|
146
|
+
*/
|
|
129
147
|
public create(_data: T): Promise<unknown> {
|
|
130
148
|
return Promise.resolve(null);
|
|
131
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* @override
|
|
152
|
+
*/
|
|
132
153
|
public remove(_data: T): Promise<unknown> {
|
|
133
154
|
return Promise.resolve(null);
|
|
134
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* @override
|
|
158
|
+
*/
|
|
135
159
|
public export(_data: T): Promise<unknown> {
|
|
136
160
|
return Promise.resolve(null);
|
|
137
161
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LOCAL_NO_USER_TOKEN } from '@config/Identifier';
|
|
2
2
|
import { I } from '@config/IOCIdentifier';
|
|
3
|
+
import { ExecutorError } from '@qlover/fe-corekit';
|
|
3
4
|
import { inject, injectable } from 'inversify';
|
|
4
|
-
import { AppError } from '../cases/AppError';
|
|
5
5
|
import type { UserServiceInterface } from '../port/UserServiceInterface';
|
|
6
6
|
import type { BootstrapExecutorPlugin } from '@qlover/corekit-bridge';
|
|
7
7
|
|
|
@@ -14,7 +14,10 @@ export class UserBootstrap implements BootstrapExecutorPlugin {
|
|
|
14
14
|
protected userService: UserServiceInterface
|
|
15
15
|
) {}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* @override
|
|
19
|
+
*/
|
|
20
|
+
public onBefore(): void {
|
|
18
21
|
const userService = this.userService;
|
|
19
22
|
|
|
20
23
|
if (userService.isAuthenticated()) {
|
|
@@ -26,18 +29,17 @@ export class UserBootstrap implements BootstrapExecutorPlugin {
|
|
|
26
29
|
if (userService.isUserCredential(credential)) {
|
|
27
30
|
userService.getStore().start();
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
userService.refreshUserInfo().then((user) => {
|
|
33
|
+
userService.getStore().success(user);
|
|
34
|
+
});
|
|
32
35
|
|
|
33
36
|
return;
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
const newError = new
|
|
39
|
+
const newError = new ExecutorError(LOCAL_NO_USER_TOKEN);
|
|
37
40
|
|
|
38
41
|
userService.getStore().failed(newError);
|
|
39
42
|
|
|
40
|
-
// 否则还是抛出错误
|
|
41
43
|
throw newError;
|
|
42
44
|
}
|
|
43
45
|
}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { I } from '@config/IOCIdentifier';
|
|
2
|
-
import {
|
|
3
|
-
UserService as CorekitBridgeUserService,
|
|
4
|
-
GatewayExecutor
|
|
5
|
-
} from '@qlover/corekit-bridge';
|
|
2
|
+
import { UserService as CorekitBridgeUserService } from '@qlover/corekit-bridge';
|
|
6
3
|
import { inject, injectable } from 'inversify';
|
|
7
4
|
import { isObject, isString } from 'lodash';
|
|
8
5
|
import { UserApi } from '@/base/apis/userApi/UserApi';
|
|
@@ -28,7 +25,6 @@ export class UserService
|
|
|
28
25
|
logger: LoggerInterface
|
|
29
26
|
) {
|
|
30
27
|
super({
|
|
31
|
-
executor: new GatewayExecutor(),
|
|
32
28
|
gateway: userApi,
|
|
33
29
|
logger: logger,
|
|
34
30
|
store: {
|
|
@@ -71,6 +67,9 @@ export class UserService
|
|
|
71
67
|
return isObject(value) && 'token' in value && isString(value.token);
|
|
72
68
|
}
|
|
73
69
|
|
|
70
|
+
/**
|
|
71
|
+
* @override
|
|
72
|
+
*/
|
|
74
73
|
public override isAuthenticated(): boolean {
|
|
75
74
|
if (!super.isAuthenticated()) {
|
|
76
75
|
return false;
|
|
@@ -6,16 +6,15 @@ import { themeConfig } from '@config/theme';
|
|
|
6
6
|
import {
|
|
7
7
|
ApiCatchPlugin,
|
|
8
8
|
ApiMockPlugin,
|
|
9
|
-
RequestCommonPlugin,
|
|
10
9
|
ThemeService
|
|
11
10
|
} from '@qlover/corekit-bridge';
|
|
11
|
+
import { RequestPlugin } from '@qlover/fe-corekit';
|
|
12
12
|
import { I18nKeyErrorPlugin } from '@/base/cases/I18nKeyErrorPlugin';
|
|
13
13
|
import { RequestStatusCatcher } from '@/base/cases/RequestStatusCatcher';
|
|
14
14
|
import type { IocRegisterOptions } from '@/base/port/IOCInterface';
|
|
15
15
|
import type { UserServiceInterface } from '@/base/port/UserServiceInterface';
|
|
16
16
|
import { I18nService } from '@/base/services/I18nService';
|
|
17
17
|
import { RouteService } from '@/base/services/RouteService';
|
|
18
|
-
import { UserGatewayPlugin } from '@/base/services/UserGatewayPlugin';
|
|
19
18
|
import { UserService } from '@/base/services/UserService';
|
|
20
19
|
import { ExecutorPageBridge } from '@/uikit/bridges/ExecutorPageBridge';
|
|
21
20
|
import { JSONStoragePageBridge } from '@/uikit/bridges/JSONStoragePageBridge';
|
|
@@ -95,9 +94,10 @@ export class ClientIOCRegister implements IOCRegisterInterface<
|
|
|
95
94
|
|
|
96
95
|
ioc.bind(
|
|
97
96
|
I.UserServiceInterface,
|
|
98
|
-
ioc
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
ioc.get<UserService>(UserService)
|
|
98
|
+
// TODO: use executor replace
|
|
99
|
+
// .use(new UserGatewayPlugin(routeService))
|
|
100
|
+
// .use(ioc.get(I.I18nKeyErrorPlugin))
|
|
101
101
|
);
|
|
102
102
|
ioc.bind(I.RequestCatcherInterface, ioc.get(RequestStatusCatcher));
|
|
103
103
|
ioc.bind(I.ExecutorPageBridgeInterface, ioc.get(ExecutorPageBridge));
|
|
@@ -109,9 +109,8 @@ export class ClientIOCRegister implements IOCRegisterInterface<
|
|
|
109
109
|
const { appConfig } = this.options;
|
|
110
110
|
const logger = ioc.get<LoggerInterface>(I.Logger);
|
|
111
111
|
|
|
112
|
-
const feApiRequestCommonPlugin = new
|
|
112
|
+
const feApiRequestCommonPlugin = new RequestPlugin({
|
|
113
113
|
tokenPrefix: appConfig.openAiTokenPrefix,
|
|
114
|
-
requiredToken: true,
|
|
115
114
|
token: () =>
|
|
116
115
|
ioc.get<UserServiceInterface>(I.UserServiceInterface).getToken()
|
|
117
116
|
});
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import 'reflect-metadata';
|
|
3
3
|
import { StrictMode } from 'react';
|
|
4
4
|
import { createRoot } from 'react-dom/client';
|
|
5
|
-
import App from './App
|
|
5
|
+
import App from './App';
|
|
6
6
|
import { BootstrapClient } from './core/bootstraps/BootstrapClient';
|
|
7
7
|
import { clientIOC } from './core/clientIoc/ClientIOC';
|
|
8
8
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UserOutlined, LockOutlined, GoogleOutlined } from '@ant-design/icons';
|
|
2
2
|
import { login18n } from '@config/i18n/login18n';
|
|
3
|
-
import {
|
|
3
|
+
import { I } from '@config/IOCIdentifier';
|
|
4
4
|
import { Form, Input, Button } from 'antd';
|
|
5
5
|
import { useState } from 'react';
|
|
6
6
|
import { LocaleLink } from '@/uikit/components/LocaleLink';
|
|
@@ -14,10 +14,10 @@ interface LoginFormData {
|
|
|
14
14
|
|
|
15
15
|
export default function LoginPage() {
|
|
16
16
|
const tt = useI18nInterface(login18n);
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
17
|
+
const logger = useIOC(I.Logger);
|
|
18
|
+
const userService = useIOC(I.UserServiceInterface);
|
|
19
|
+
const AppConfig = useIOC(I.AppConfig);
|
|
20
|
+
const routeService = useIOC(I.RouteServiceInterface);
|
|
21
21
|
|
|
22
22
|
const [loading, setLoading] = useState(false);
|
|
23
23
|
|
|
@@ -277,7 +277,9 @@ export default function ExecutorPage() {
|
|
|
277
277
|
<Input
|
|
278
278
|
placeholder={tt.enterUrl}
|
|
279
279
|
value={customUrl}
|
|
280
|
-
onChange={(e) =>
|
|
280
|
+
onChange={(e) =>
|
|
281
|
+
setCustomUrl((e.target as HTMLInputElement).value)
|
|
282
|
+
}
|
|
281
283
|
className="flex-1"
|
|
282
284
|
/>
|
|
283
285
|
<Select
|
|
@@ -74,7 +74,9 @@ export default function JSONStoragePage() {
|
|
|
74
74
|
type="number"
|
|
75
75
|
value={pageState.expireTime}
|
|
76
76
|
onChange={(e) =>
|
|
77
|
-
pageBridge.changeExpireTime(
|
|
77
|
+
pageBridge.changeExpireTime(
|
|
78
|
+
Number((e.target as HTMLInputElement).value)
|
|
79
|
+
)
|
|
78
80
|
}
|
|
79
81
|
className="w-32"
|
|
80
82
|
min="1000"
|
|
@@ -111,7 +113,9 @@ export default function JSONStoragePage() {
|
|
|
111
113
|
type="number"
|
|
112
114
|
value={pageState.requestTimeout}
|
|
113
115
|
onChange={(e) =>
|
|
114
|
-
pageBridge.changeRequestTimeout(
|
|
116
|
+
pageBridge.changeRequestTimeout(
|
|
117
|
+
Number((e.target as HTMLInputElement).value)
|
|
118
|
+
)
|
|
115
119
|
}
|
|
116
120
|
className="w-32"
|
|
117
121
|
min="1000"
|