@qlover/create-app 0.12.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 +4 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/templates/next-app/next.config.ts +4 -3
- package/dist/templates/next-app/package.json +14 -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/package.json +2 -1
- 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 +26 -13
- package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +30 -34
- package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +20 -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/UserBootstrap.ts +6 -7
- package/dist/templates/react-app/src/base/services/UserService.ts +1 -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 +1 -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 +3 -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
|
@@ -6,8 +6,8 @@ import type {
|
|
|
6
6
|
UserApiRegisterTransaction
|
|
7
7
|
} from '@/base/port/AppUserApiInterface';
|
|
8
8
|
import { AppApiRequester } from './AppApiRequester';
|
|
9
|
-
import type { AppApiConfig } from './AppApiRequester';
|
|
10
|
-
import
|
|
9
|
+
import type { AppApiConfig, AppApiRequesterContext } from './AppApiRequester';
|
|
10
|
+
import { RequestExecutor } from '@qlover/fe-corekit';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* UserApi
|
|
@@ -20,7 +20,7 @@ import type { RequestTransaction } from '@qlover/fe-corekit';
|
|
|
20
20
|
export class AppUserApi implements AppUserApiInterface {
|
|
21
21
|
constructor(
|
|
22
22
|
@inject(AppApiRequester)
|
|
23
|
-
protected client:
|
|
23
|
+
protected client: RequestExecutor<AppApiConfig, AppApiRequesterContext>
|
|
24
24
|
) {}
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -29,7 +29,10 @@ export class AppUserApi implements AppUserApiInterface {
|
|
|
29
29
|
public async login(
|
|
30
30
|
params: UserApiLoginTransaction['data']
|
|
31
31
|
): Promise<UserApiLoginTransaction['response']> {
|
|
32
|
-
const response = await this.client.request<
|
|
32
|
+
const response = await this.client.request<
|
|
33
|
+
UserApiLoginTransaction['response'],
|
|
34
|
+
UserApiLoginTransaction['request']
|
|
35
|
+
>({
|
|
33
36
|
url: '/user/login',
|
|
34
37
|
method: 'POST',
|
|
35
38
|
data: params,
|
|
@@ -45,7 +48,10 @@ export class AppUserApi implements AppUserApiInterface {
|
|
|
45
48
|
public async register(
|
|
46
49
|
params: UserApiRegisterTransaction['data']
|
|
47
50
|
): Promise<UserApiRegisterTransaction['response']> {
|
|
48
|
-
const response = await this.client.request<
|
|
51
|
+
const response = await this.client.request<
|
|
52
|
+
UserApiRegisterTransaction['response'],
|
|
53
|
+
UserApiRegisterTransaction['request']
|
|
54
|
+
>({
|
|
49
55
|
url: '/user/register',
|
|
50
56
|
method: 'POST',
|
|
51
57
|
data: params,
|
|
@@ -61,7 +67,10 @@ export class AppUserApi implements AppUserApiInterface {
|
|
|
61
67
|
public async logout(
|
|
62
68
|
_params?: unknown
|
|
63
69
|
): Promise<UserApiLogoutTransaction['response']> {
|
|
64
|
-
return await this.client.request<
|
|
70
|
+
return await this.client.request<
|
|
71
|
+
UserApiLogoutTransaction['response'],
|
|
72
|
+
UserApiLogoutTransaction['request']
|
|
73
|
+
>({
|
|
65
74
|
url: '/user/logout',
|
|
66
75
|
method: 'POST'
|
|
67
76
|
});
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { FetchURLPlugin } from '@qlover/fe-corekit';
|
|
1
|
+
import { RequestPlugin, ResponsePlugin } from '@qlover/fe-corekit';
|
|
3
2
|
import { DialogErrorPlugin } from '@/base/cases/DialogErrorPlugin';
|
|
4
3
|
import { RequestEncryptPlugin } from '@/base/cases/RequestEncryptPlugin';
|
|
5
4
|
import { StringEncryptor } from '@/base/cases/StringEncryptor';
|
|
@@ -11,7 +10,7 @@ import type {
|
|
|
11
10
|
BootstrapContext,
|
|
12
11
|
BootstrapExecutorPlugin
|
|
13
12
|
} from '@qlover/corekit-bridge';
|
|
14
|
-
import type {
|
|
13
|
+
import type { SerializerIneterface } from '@qlover/fe-corekit';
|
|
15
14
|
|
|
16
15
|
export class AppUserApiBootstrap implements BootstrapExecutorPlugin {
|
|
17
16
|
public readonly pluginName = 'AppUserApiBootstrap';
|
|
@@ -21,20 +20,19 @@ export class AppUserApiBootstrap implements BootstrapExecutorPlugin {
|
|
|
21
20
|
/**
|
|
22
21
|
* @override
|
|
23
22
|
*/
|
|
24
|
-
public onBefore({
|
|
25
|
-
parameters: { ioc }
|
|
26
|
-
}: BootstrapContext): void | Promise<void> {
|
|
23
|
+
public onBefore({ parameters: { ioc } }: BootstrapContext): void {
|
|
27
24
|
const appUserApi = ioc.get<AppApiRequester>(AppApiRequester);
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
appUserApi.
|
|
31
|
-
appUserApi.
|
|
32
|
-
new
|
|
26
|
+
// 数据加密优先于 RequestPlugin(会序列化数据)
|
|
27
|
+
appUserApi.use(new RequestEncryptPlugin(ioc.get(StringEncryptor)));
|
|
28
|
+
appUserApi.use(
|
|
29
|
+
new RequestPlugin({
|
|
33
30
|
requestDataSerializer: this.requestDataSerializer.bind(this)
|
|
34
31
|
})
|
|
35
32
|
);
|
|
36
|
-
appUserApi.
|
|
37
|
-
appUserApi.
|
|
33
|
+
appUserApi.use(new ResponsePlugin());
|
|
34
|
+
appUserApi.use(new AppApiPlugin(ioc.get(I.Logger)));
|
|
35
|
+
appUserApi.use(ioc.get(DialogErrorPlugin));
|
|
38
36
|
}
|
|
39
37
|
|
|
40
38
|
/**
|
|
@@ -42,13 +40,13 @@ export class AppUserApiBootstrap implements BootstrapExecutorPlugin {
|
|
|
42
40
|
*/
|
|
43
41
|
protected requestDataSerializer(
|
|
44
42
|
data: unknown,
|
|
45
|
-
|
|
43
|
+
config: AppApiConfig
|
|
46
44
|
): unknown {
|
|
47
45
|
if (data instanceof FormData) {
|
|
48
46
|
return data;
|
|
49
47
|
}
|
|
50
48
|
|
|
51
|
-
if (
|
|
49
|
+
if (config.responseType === 'json') {
|
|
52
50
|
return this.serializer.serialize(data);
|
|
53
51
|
}
|
|
54
52
|
|
|
@@ -1,28 +1,37 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import {
|
|
3
3
|
type ServiceIdentifier,
|
|
4
|
-
type BootstrapContextValue,
|
|
5
|
-
type BootstrapExecutorPlugin,
|
|
6
4
|
type IOCContainerInterface,
|
|
7
|
-
type IOCFunctionInterface
|
|
5
|
+
type IOCFunctionInterface,
|
|
6
|
+
BootstrapPluginOptions
|
|
8
7
|
} from '@qlover/corekit-bridge';
|
|
9
8
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
ExecutorAsyncTask,
|
|
10
|
+
ExecutorContextInterface,
|
|
11
|
+
LifecycleExecutor,
|
|
12
|
+
LifecyclePluginInterface,
|
|
13
|
+
type ExecutorError
|
|
14
14
|
} from '@qlover/fe-corekit';
|
|
15
15
|
import type { ServerInterface } from '@/server/port/ServerInterface';
|
|
16
16
|
import { I, type IOCIdentifierMapServer } from '@config/IOCIdentifier';
|
|
17
17
|
import { ServerIOC } from '../serverIoc/ServerIOC';
|
|
18
18
|
import type { LoggerInterface } from '@qlover/logger';
|
|
19
19
|
|
|
20
|
-
export interface
|
|
20
|
+
export interface BootstrapServerContextOptions extends BootstrapPluginOptions {
|
|
21
21
|
IOC: IOCFunctionInterface<IOCIdentifierMapServer, IOCContainerInterface>;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
export interface BootstrapServerPlugin
|
|
25
|
+
extends LifecyclePluginInterface<BootstrapServerContext> {}
|
|
26
|
+
|
|
27
|
+
export interface BootstrapServerContext
|
|
28
|
+
extends ExecutorContextInterface<BootstrapServerContextOptions> {}
|
|
29
|
+
|
|
24
30
|
export class BootstrapServer implements ServerInterface {
|
|
25
|
-
protected executor:
|
|
31
|
+
protected executor: LifecycleExecutor<
|
|
32
|
+
BootstrapServerContext,
|
|
33
|
+
BootstrapServerPlugin
|
|
34
|
+
>;
|
|
26
35
|
protected root: Record<string, unknown> = {};
|
|
27
36
|
protected IOC: IOCFunctionInterface<
|
|
28
37
|
IOCIdentifierMapServer,
|
|
@@ -35,7 +44,7 @@ export class BootstrapServer implements ServerInterface {
|
|
|
35
44
|
const ioc = serverIOC.create();
|
|
36
45
|
const logger = ioc(I.Logger);
|
|
37
46
|
|
|
38
|
-
this.executor = new
|
|
47
|
+
this.executor = new LifecycleExecutor();
|
|
39
48
|
this.IOC = ioc;
|
|
40
49
|
this.logger = logger;
|
|
41
50
|
}
|
|
@@ -76,20 +85,25 @@ export class BootstrapServer implements ServerInterface {
|
|
|
76
85
|
*/
|
|
77
86
|
public use(
|
|
78
87
|
plugin:
|
|
79
|
-
|
|
|
80
|
-
|
|
|
88
|
+
| BootstrapServerPlugin
|
|
89
|
+
| BootstrapServerPlugin[]
|
|
81
90
|
| ((
|
|
82
91
|
ioc: IOCFunctionInterface<
|
|
83
92
|
IOCIdentifierMapServer,
|
|
84
93
|
IOCContainerInterface
|
|
85
94
|
>
|
|
86
|
-
) =>
|
|
95
|
+
) => BootstrapServerPlugin)
|
|
87
96
|
): this {
|
|
88
97
|
if (typeof plugin === 'function') {
|
|
89
98
|
plugin = plugin(this.IOC);
|
|
90
99
|
}
|
|
91
100
|
|
|
92
|
-
|
|
101
|
+
if (Array.isArray(plugin)) {
|
|
102
|
+
plugin.forEach((p) => this.executor.use(p));
|
|
103
|
+
return this;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
this.executor.use(plugin);
|
|
93
107
|
return this;
|
|
94
108
|
}
|
|
95
109
|
|
|
@@ -97,15 +111,18 @@ export class BootstrapServer implements ServerInterface {
|
|
|
97
111
|
* @override
|
|
98
112
|
*/
|
|
99
113
|
public execNoError<Result>(
|
|
100
|
-
task?:
|
|
114
|
+
task?: ExecutorAsyncTask<Result, BootstrapServerContextOptions>
|
|
101
115
|
): Promise<Result | ExecutorError> {
|
|
102
|
-
const
|
|
116
|
+
const options = {
|
|
103
117
|
logger: this.logger,
|
|
104
118
|
root: this.root,
|
|
105
119
|
ioc: this.IOC.implemention!,
|
|
106
120
|
IOC: this.IOC
|
|
107
121
|
};
|
|
108
122
|
|
|
109
|
-
return this.executor.execNoError(
|
|
123
|
+
return this.executor.execNoError(
|
|
124
|
+
options,
|
|
125
|
+
task ?? (() => Promise.resolve(undefined as Result))
|
|
126
|
+
);
|
|
110
127
|
}
|
|
111
128
|
}
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
isAppApiSuccessInterface,
|
|
6
6
|
type AppApiResult
|
|
7
7
|
} from '@/base/port/AppApiInterface';
|
|
8
|
-
import type {
|
|
8
|
+
import type { BootstrapServerContextOptions } from '@/core/bootstraps/BootstrapServer';
|
|
9
9
|
import { BootstrapServer } from '@/core/bootstraps/BootstrapServer';
|
|
10
10
|
import { AppErrorApi } from './AppErrorApi';
|
|
11
11
|
import { AppSuccessApi } from './AppSuccessApi';
|
|
12
|
-
import type {
|
|
12
|
+
import type { ExecutorAsyncTask } from '@qlover/fe-corekit';
|
|
13
13
|
|
|
14
14
|
export class NextApiServer extends BootstrapServer {
|
|
15
15
|
/**
|
|
@@ -23,7 +23,10 @@ export class NextApiServer extends BootstrapServer {
|
|
|
23
23
|
* @override
|
|
24
24
|
*/
|
|
25
25
|
public async run<Result>(
|
|
26
|
-
task?:
|
|
26
|
+
task?: ExecutorAsyncTask<
|
|
27
|
+
Result | AppApiResult,
|
|
28
|
+
BootstrapServerContextOptions
|
|
29
|
+
>
|
|
27
30
|
): Promise<AppApiResult> {
|
|
28
31
|
const result = await this.execNoError(task);
|
|
29
32
|
|
|
@@ -49,7 +52,10 @@ export class NextApiServer extends BootstrapServer {
|
|
|
49
52
|
* @override
|
|
50
53
|
*/
|
|
51
54
|
public async runWithJson<Result>(
|
|
52
|
-
task?:
|
|
55
|
+
task?: ExecutorAsyncTask<
|
|
56
|
+
Result | AppApiResult,
|
|
57
|
+
BootstrapServerContextOptions
|
|
58
|
+
>
|
|
53
59
|
): Promise<NextResponse> {
|
|
54
60
|
const result = await this.run(task);
|
|
55
61
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
|
-
import type {
|
|
2
|
+
import type { EncryptorInterface } from '@qlover/fe-corekit';
|
|
3
3
|
|
|
4
|
-
export class PasswordEncrypt implements
|
|
4
|
+
export class PasswordEncrypt implements EncryptorInterface<string, string> {
|
|
5
5
|
/**
|
|
6
6
|
* @override
|
|
7
7
|
*/
|
|
@@ -12,14 +12,14 @@ import type { ServerAuthInterface } from '../port/ServerAuthInterface';
|
|
|
12
12
|
import type { UserControllerInerface } from '../port/UserControllerInerface';
|
|
13
13
|
import type { UserServiceInterface } from '../port/UserServiceInterface';
|
|
14
14
|
import type { ValidatorInterface } from '../port/ValidatorInterface';
|
|
15
|
-
import type {
|
|
15
|
+
import type { EncryptorInterface } from '@qlover/fe-corekit';
|
|
16
16
|
|
|
17
17
|
@injectable()
|
|
18
18
|
export class UserController implements UserControllerInerface {
|
|
19
19
|
constructor(
|
|
20
20
|
@inject(ServerAuth) protected serverAuth: ServerAuthInterface,
|
|
21
21
|
@inject(StringEncryptor)
|
|
22
|
-
protected stringEncryptor:
|
|
22
|
+
protected stringEncryptor: EncryptorInterface<string, string>,
|
|
23
23
|
@inject(LoginValidator)
|
|
24
24
|
protected loginValidator: ValidatorInterface<LoginValidatorData>,
|
|
25
25
|
@inject(UserService) protected userService: UserServiceInterface
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ExecutorAsyncTask, type ExecutorError } from '@qlover/fe-corekit';
|
|
2
2
|
import { type IOCIdentifierMapServer } from '@config/IOCIdentifier';
|
|
3
3
|
import type {
|
|
4
4
|
ServiceIdentifier,
|
|
@@ -17,6 +17,6 @@ export interface ServerInterface {
|
|
|
17
17
|
getIOC<T>(serviceIdentifier: ServiceIdentifier<T>): T;
|
|
18
18
|
|
|
19
19
|
execNoError<Result>(
|
|
20
|
-
task?:
|
|
20
|
+
task?: ExecutorAsyncTask<Result, unknown>
|
|
21
21
|
): Promise<Result | ExecutorError>;
|
|
22
22
|
}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
BootstrapServerContext,
|
|
3
|
+
BootstrapServerPlugin
|
|
4
|
+
} from '@/core/bootstraps/BootstrapServer';
|
|
2
5
|
import { ServerAuth } from '../ServerAuth';
|
|
3
6
|
import type { ServerAuthInterface } from '../port/ServerAuthInterface';
|
|
4
|
-
import type { BootstrapExecutorPlugin } from '@qlover/corekit-bridge';
|
|
5
|
-
import type { ExecutorContext } from '@qlover/fe-corekit';
|
|
6
7
|
|
|
7
|
-
export class AdminAuthPlugin implements
|
|
8
|
+
export class AdminAuthPlugin implements BootstrapServerPlugin {
|
|
8
9
|
public pluginName = 'AdminAuthPlugin';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* @override
|
|
12
13
|
*/
|
|
13
|
-
public async onBefore(
|
|
14
|
-
context: ExecutorContext<BootstrapServerContextValue>
|
|
15
|
-
): Promise<void> {
|
|
14
|
+
public async onBefore(context: BootstrapServerContext): Promise<void> {
|
|
16
15
|
const { IOC } = context.parameters;
|
|
17
16
|
|
|
18
17
|
const serverAuth: ServerAuthInterface = IOC(ServerAuth);
|
|
@@ -16,7 +16,7 @@ import type { CrentialTokenInterface } from '../port/CrentialTokenInterface';
|
|
|
16
16
|
import type { ServerAuthInterface } from '../port/ServerAuthInterface';
|
|
17
17
|
import type { UserRepositoryInterface } from '../port/UserRepositoryInterface';
|
|
18
18
|
import type { UserServiceInterface } from '../port/UserServiceInterface';
|
|
19
|
-
import type {
|
|
19
|
+
import type { EncryptorInterface } from '@qlover/fe-corekit';
|
|
20
20
|
|
|
21
21
|
@injectable()
|
|
22
22
|
export class UserService implements UserServiceInterface {
|
|
@@ -26,7 +26,7 @@ export class UserService implements UserServiceInterface {
|
|
|
26
26
|
@inject(ServerAuth)
|
|
27
27
|
protected userAuth: ServerAuthInterface,
|
|
28
28
|
@inject(PasswordEncrypt)
|
|
29
|
-
protected encryptor:
|
|
29
|
+
protected encryptor: EncryptorInterface<string, string>,
|
|
30
30
|
@inject(UserCredentialToken)
|
|
31
31
|
protected credentialToken: CrentialTokenInterface<UserCredentialTokenValue>
|
|
32
32
|
) {}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import '@ant-design/v5-patch-for-react-19';
|
|
3
3
|
|
|
4
|
-
import { useState } from 'react';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
import { useLocale } from 'next-intl';
|
|
5
6
|
import { BootstrapClient } from '@/core/bootstraps/BootstrapClient';
|
|
6
7
|
import { useIOC } from '../hook/useIOC';
|
|
7
8
|
import { useStrictEffect } from '../hook/useStrictEffect';
|
|
9
|
+
import { useWarnTranslations } from '../hook/useWarnTranslations';
|
|
10
|
+
import { I } from '@config/IOCIdentifier';
|
|
11
|
+
import type { I18nServiceLocale } from '@/base/port/I18nServiceInterface';
|
|
8
12
|
|
|
9
13
|
export function BootstrapsProvider(props: { children: React.ReactNode }) {
|
|
10
14
|
const IOC = useIOC();
|
|
15
|
+
const locale = useLocale();
|
|
16
|
+
const t = useWarnTranslations();
|
|
11
17
|
|
|
12
18
|
const [, setIocMounted] = useState(false);
|
|
13
19
|
|
|
@@ -24,52 +30,10 @@ export function BootstrapsProvider(props: { children: React.ReactNode }) {
|
|
|
24
30
|
});
|
|
25
31
|
}, []);
|
|
26
32
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// // 启动前注册所有依赖
|
|
33
|
-
// // clientIOC.register(register);
|
|
34
|
-
|
|
35
|
-
// BootstrapClient.main({
|
|
36
|
-
// root: window,
|
|
37
|
-
// pathname: window.location.pathname,
|
|
38
|
-
// IOC: IOC,
|
|
39
|
-
// register: register
|
|
40
|
-
// }).then(() => {
|
|
41
|
-
// setIocMounted(true);
|
|
42
|
-
// });
|
|
43
|
-
// }, []);
|
|
44
|
-
|
|
45
|
-
// if (!register) {
|
|
46
|
-
// return <div data-testid="BootstrapsProviderLoading">Loading...</div>;
|
|
47
|
-
// }
|
|
48
|
-
|
|
49
|
-
// const IOC = clientIOC.create();
|
|
50
|
-
// const locale = useLocale();
|
|
51
|
-
// const router = useRouter();
|
|
52
|
-
// const t = useWarnTranslations();
|
|
53
|
-
|
|
54
|
-
// useEffect(() => {
|
|
55
|
-
// IOC(I.RouterServiceInterface).setLocale(locale);
|
|
56
|
-
// IOC(NavigateBridge).setUIBridge(router);
|
|
57
|
-
// }, [locale, router, IOC]);
|
|
58
|
-
|
|
59
|
-
// useEffect(() => {
|
|
60
|
-
// IOC(I.I18nServiceInterface).changeLanguage(locale as I18nServiceLocale);
|
|
61
|
-
// IOC(I.I18nServiceInterface).setTranslator(t);
|
|
62
|
-
// }, [t, IOC, locale]);
|
|
63
|
-
|
|
64
|
-
// useEffect(() => {
|
|
65
|
-
// if (typeof window !== 'undefined') {
|
|
66
|
-
// BootstrapClient.main({
|
|
67
|
-
// root: window,
|
|
68
|
-
// pathname: window.location.pathname,
|
|
69
|
-
// IOC: IOC
|
|
70
|
-
// });
|
|
71
|
-
// }
|
|
72
|
-
// }, [IOC]);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
IOC(I.I18nServiceInterface).changeLanguage(locale as I18nServiceLocale);
|
|
35
|
+
IOC(I.I18nServiceInterface).setTranslator(t);
|
|
36
|
+
}, [t, IOC, locale]);
|
|
73
37
|
|
|
74
38
|
return props.children;
|
|
75
39
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { vi } from 'vitest';
|
|
2
|
-
import type {
|
|
2
|
+
import type { DialogHandlerOptions } from '@/base/cases/DialogHandler';
|
|
3
3
|
import type { AntdStaticApiInterface } from '@brain-toolkit/antd-theme-override/react';
|
|
4
|
+
import type { UIDialogInterface } from '@qlover/corekit-bridge';
|
|
4
5
|
|
|
5
6
|
export class MockDialogHandler
|
|
6
|
-
implements
|
|
7
|
+
implements UIDialogInterface<DialogHandlerOptions>, AntdStaticApiInterface
|
|
7
8
|
{
|
|
8
9
|
public setMessage = vi.fn();
|
|
9
10
|
public setModal = vi.fn();
|
|
@@ -79,6 +79,9 @@ export function createMockGlobals() {
|
|
|
79
79
|
size: vi.fn(() => Object.keys(mockCookieStorageData).length)
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
+
// Add length property to prevent lodash.omit from treating this as array-like
|
|
83
|
+
// This is needed because BootstrapClient uses omit(globals, ...) and lodash
|
|
84
|
+
// checks for length property to determine if object is array-like
|
|
82
85
|
return {
|
|
83
86
|
logger: mockLogger,
|
|
84
87
|
appConfig: mockAppConfig,
|
|
@@ -86,6 +89,8 @@ export function createMockGlobals() {
|
|
|
86
89
|
JSON: mockJSON,
|
|
87
90
|
localStorage: mockLocalStorage,
|
|
88
91
|
localStorageEncrypt: mockLocalStorageEncrypt,
|
|
89
|
-
cookieStorage: mockCookieStorage
|
|
92
|
+
cookieStorage: mockCookieStorage,
|
|
93
|
+
// Explicitly define length as undefined to satisfy lodash's isArrayLike check
|
|
94
|
+
length: undefined
|
|
90
95
|
};
|
|
91
96
|
}
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { MockLogger } from '@__mocks__/MockLogger';
|
|
12
|
+
import { ExecutorContextImpl } from '@qlover/fe-corekit';
|
|
12
13
|
import { describe, it, expect, beforeEach } from 'vitest';
|
|
13
14
|
import { I18nKeyErrorPlugin } from '@/base/cases/I18nKeyErrorPlugin';
|
|
14
15
|
import { I18nService } from '@/base/services/I18nService';
|
|
15
|
-
import type { ExecutorContext } from '@qlover/fe-corekit';
|
|
16
16
|
|
|
17
17
|
class MockI18nService extends I18nService {
|
|
18
18
|
constructor() {
|
|
@@ -44,12 +44,8 @@ describe('I18nKeyErrorPlugin', () => {
|
|
|
44
44
|
|
|
45
45
|
describe('onError handling', () => {
|
|
46
46
|
it('should handle non-Error objects', () => {
|
|
47
|
-
const context
|
|
48
|
-
|
|
49
|
-
parameters: {},
|
|
50
|
-
returnValue: undefined,
|
|
51
|
-
hooksRuntimes: {}
|
|
52
|
-
};
|
|
47
|
+
const context = new ExecutorContextImpl({});
|
|
48
|
+
context.setError(new Error('not an error'));
|
|
53
49
|
const result = plugin.onError(context);
|
|
54
50
|
expect(result).toBeUndefined();
|
|
55
51
|
expect(mockLogger.debug).not.toHaveBeenCalled();
|
|
@@ -58,12 +54,8 @@ describe('I18nKeyErrorPlugin', () => {
|
|
|
58
54
|
|
|
59
55
|
it('should handle Error objects without i18n key', () => {
|
|
60
56
|
const error = new Error('regular error');
|
|
61
|
-
const context
|
|
62
|
-
|
|
63
|
-
parameters: {},
|
|
64
|
-
returnValue: undefined,
|
|
65
|
-
hooksRuntimes: {}
|
|
66
|
-
};
|
|
57
|
+
const context = new ExecutorContextImpl({});
|
|
58
|
+
context.setError(error);
|
|
67
59
|
const result = plugin.onError(context);
|
|
68
60
|
expect(result).toBeUndefined();
|
|
69
61
|
expect(mockLogger.debug).not.toHaveBeenCalled();
|
|
@@ -74,12 +66,8 @@ describe('I18nKeyErrorPlugin', () => {
|
|
|
74
66
|
const error = new Error('error.key');
|
|
75
67
|
mockI18nService.t.mockReturnValueOnce('Translated error message');
|
|
76
68
|
|
|
77
|
-
const context
|
|
78
|
-
|
|
79
|
-
parameters: {},
|
|
80
|
-
returnValue: undefined,
|
|
81
|
-
hooksRuntimes: {}
|
|
82
|
-
};
|
|
69
|
+
const context = new ExecutorContextImpl({});
|
|
70
|
+
context.setError(error);
|
|
83
71
|
|
|
84
72
|
const result = plugin.onError(context);
|
|
85
73
|
|
|
@@ -96,12 +84,8 @@ describe('I18nKeyErrorPlugin', () => {
|
|
|
96
84
|
const error = new Error('error.key');
|
|
97
85
|
mockI18nService.t.mockReturnValueOnce('error.key');
|
|
98
86
|
|
|
99
|
-
const context
|
|
100
|
-
|
|
101
|
-
parameters: {},
|
|
102
|
-
returnValue: undefined,
|
|
103
|
-
hooksRuntimes: {}
|
|
104
|
-
};
|
|
87
|
+
const context = new ExecutorContextImpl({});
|
|
88
|
+
context.setError(error);
|
|
105
89
|
|
|
106
90
|
const result = plugin.onError(context);
|
|
107
91
|
|
|
@@ -118,12 +102,8 @@ describe('I18nKeyErrorPlugin', () => {
|
|
|
118
102
|
'Error with param1: {0} and param2: {1}'
|
|
119
103
|
);
|
|
120
104
|
|
|
121
|
-
const context
|
|
122
|
-
|
|
123
|
-
parameters: { param1: 'value1', param2: 'value2' },
|
|
124
|
-
returnValue: undefined,
|
|
125
|
-
hooksRuntimes: {}
|
|
126
|
-
};
|
|
105
|
+
const context = new ExecutorContextImpl({});
|
|
106
|
+
context.setError(error);
|
|
127
107
|
|
|
128
108
|
const result = plugin.onError(context);
|
|
129
109
|
|
|
@@ -142,12 +122,8 @@ describe('I18nKeyErrorPlugin', () => {
|
|
|
142
122
|
.mockReturnValueOnce('Wrapped Error')
|
|
143
123
|
.mockReturnValueOnce('Original Error');
|
|
144
124
|
|
|
145
|
-
const context
|
|
146
|
-
|
|
147
|
-
parameters: {},
|
|
148
|
-
returnValue: undefined,
|
|
149
|
-
hooksRuntimes: {}
|
|
150
|
-
};
|
|
125
|
+
const context = new ExecutorContextImpl({});
|
|
126
|
+
context.setError(wrappedError);
|
|
151
127
|
|
|
152
128
|
const result = plugin.onError(context);
|
|
153
129
|
|
|
@@ -160,12 +136,8 @@ describe('I18nKeyErrorPlugin', () => {
|
|
|
160
136
|
describe('edge cases', () => {
|
|
161
137
|
it('should handle empty error message', () => {
|
|
162
138
|
const error = new Error('');
|
|
163
|
-
const context
|
|
164
|
-
|
|
165
|
-
parameters: {},
|
|
166
|
-
returnValue: undefined,
|
|
167
|
-
hooksRuntimes: {}
|
|
168
|
-
};
|
|
139
|
+
const context = new ExecutorContextImpl({});
|
|
140
|
+
context.setError(error);
|
|
169
141
|
const result = plugin.onError(context);
|
|
170
142
|
expect(result).toBeUndefined();
|
|
171
143
|
expect(mockLogger.debug).not.toHaveBeenCalled();
|
|
@@ -176,12 +148,8 @@ describe('I18nKeyErrorPlugin', () => {
|
|
|
176
148
|
it('should handle null error message', () => {
|
|
177
149
|
const error = new Error();
|
|
178
150
|
error.message = ''; // Force empty message
|
|
179
|
-
const context
|
|
180
|
-
|
|
181
|
-
parameters: {},
|
|
182
|
-
returnValue: undefined,
|
|
183
|
-
hooksRuntimes: {}
|
|
184
|
-
};
|
|
151
|
+
const context = new ExecutorContextImpl({});
|
|
152
|
+
context.setError(error);
|
|
185
153
|
const result = plugin.onError(context);
|
|
186
154
|
expect(result).toBeUndefined();
|
|
187
155
|
expect(mockLogger.debug).not.toHaveBeenCalled();
|
|
@@ -190,12 +158,8 @@ describe('I18nKeyErrorPlugin', () => {
|
|
|
190
158
|
});
|
|
191
159
|
|
|
192
160
|
it('should handle undefined context error', () => {
|
|
193
|
-
const context
|
|
194
|
-
|
|
195
|
-
parameters: {},
|
|
196
|
-
returnValue: undefined,
|
|
197
|
-
hooksRuntimes: {}
|
|
198
|
-
};
|
|
161
|
+
const context = new ExecutorContextImpl({});
|
|
162
|
+
context.setError(undefined);
|
|
199
163
|
const result = plugin.onError(context);
|
|
200
164
|
expect(result).toBeUndefined();
|
|
201
165
|
expect(mockLogger.debug).not.toHaveBeenCalled();
|
|
@@ -203,12 +167,8 @@ describe('I18nKeyErrorPlugin', () => {
|
|
|
203
167
|
});
|
|
204
168
|
|
|
205
169
|
it('should handle null context error', () => {
|
|
206
|
-
const context
|
|
207
|
-
|
|
208
|
-
parameters: {},
|
|
209
|
-
returnValue: undefined,
|
|
210
|
-
hooksRuntimes: {}
|
|
211
|
-
};
|
|
170
|
+
const context = new ExecutorContextImpl({});
|
|
171
|
+
context.setError(null);
|
|
212
172
|
const result = plugin.onError(context);
|
|
213
173
|
expect(result).toBeUndefined();
|
|
214
174
|
expect(mockLogger.debug).not.toHaveBeenCalled();
|