@qlover/create-app 0.8.0 → 0.10.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 +32 -0
- package/dist/configs/_common/.github/workflows/general-check.yml +1 -1
- package/dist/configs/_common/.github/workflows/release.yml +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/templates/next-app/.env.template +9 -10
- package/dist/templates/next-app/eslint.config.mjs +5 -0
- package/dist/templates/next-app/next.config.ts +1 -1
- package/dist/templates/next-app/src/app/[locale]/login/page.tsx +1 -1
- package/dist/templates/next-app/src/app/[locale]/page.tsx +1 -1
- package/dist/templates/next-app/src/app/[locale]/register/page.tsx +1 -1
- package/dist/templates/next-app/src/app/api/locales/json/route.ts +2 -1
- package/dist/templates/next-app/src/i18n/request.ts +2 -2
- package/dist/templates/react-app/__tests__/__mocks__/{MockAppConfit.ts → MockAppConfig.ts} +1 -1
- package/dist/templates/react-app/__tests__/__mocks__/components/TestApp.tsx +10 -17
- package/dist/templates/react-app/__tests__/__mocks__/components/TestBootstrapsProvider.tsx +27 -8
- package/dist/templates/react-app/__tests__/__mocks__/createMockGlobals.ts +1 -1
- package/dist/templates/react-app/__tests__/__mocks__/i18nextHttpBackend.ts +110 -0
- package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOCRegister.ts +3 -2
- package/dist/templates/react-app/__tests__/setup/setupGlobal.ts +13 -0
- package/dist/templates/react-app/__tests__/src/base/services/I18nService.test.ts +3 -1
- package/dist/templates/react-app/__tests__/src/uikit/components/chatMessage/ChatRoot.test.tsx +274 -0
- package/dist/templates/react-app/config/IOCIdentifier.ts +9 -3
- package/dist/templates/react-app/config/Identifier/components/component.chatMessage.ts +56 -0
- package/dist/templates/react-app/config/Identifier/components/component.messageBaseList.ts +103 -0
- package/dist/templates/react-app/config/Identifier/pages/index.ts +1 -0
- package/dist/templates/react-app/config/Identifier/pages/page.message.ts +20 -0
- package/dist/templates/react-app/config/app.router.ts +23 -0
- package/dist/templates/react-app/config/common.ts +38 -0
- package/dist/templates/react-app/config/feapi.mock.json +5 -12
- package/dist/templates/react-app/config/i18n/chatMessageI18n.ts +17 -0
- package/dist/templates/react-app/config/i18n/messageBaseListI18n.ts +22 -0
- package/dist/templates/react-app/config/i18n/messageI18n.ts +14 -0
- package/dist/templates/react-app/docs/en/components/chat-message-component.md +314 -0
- package/dist/templates/react-app/docs/en/components/chat-message-refactor.md +270 -0
- package/dist/templates/react-app/docs/en/components/message-base-list-component.md +172 -0
- package/dist/templates/react-app/docs/zh/components/chat-message-component.md +314 -0
- package/dist/templates/react-app/docs/zh/components/chat-message-refactor.md +270 -0
- package/dist/templates/react-app/docs/zh/components/message-base-list-component.md +172 -0
- package/dist/templates/react-app/eslint.config.mjs +6 -5
- package/dist/templates/react-app/package.json +1 -1
- package/dist/templates/react-app/playwright.config.ts +6 -6
- package/dist/templates/react-app/public/locales/en/common.json +44 -1
- package/dist/templates/react-app/public/locales/zh/common.json +44 -1
- package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +22 -13
- package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +3 -3
- package/dist/templates/react-app/src/base/apis/userApi/UserApiType.ts +17 -12
- package/dist/templates/react-app/src/base/cases/I18nKeyErrorPlugin.ts +19 -2
- package/dist/templates/react-app/src/base/port/RouteServiceInterface.ts +2 -4
- package/dist/templates/react-app/src/base/port/UserServiceInterface.ts +15 -9
- package/dist/templates/react-app/src/base/services/BaseLayoutService.ts +55 -0
- package/dist/templates/react-app/src/base/services/I18nService.ts +1 -0
- package/dist/templates/react-app/src/base/services/UserBootstrap.ts +43 -0
- package/dist/templates/react-app/src/base/services/UserGatewayPlugin.ts +16 -0
- package/dist/templates/react-app/src/base/services/UserService.ts +51 -80
- package/dist/templates/react-app/src/core/bootstraps/BootstrapClient.ts +8 -3
- package/dist/templates/react-app/src/core/bootstraps/BootstrapsRegistry.ts +6 -6
- package/dist/templates/react-app/src/core/bootstraps/SaveAppInfo.ts +28 -0
- package/dist/templates/react-app/src/core/clientIoc/ClientIOCRegister.ts +24 -18
- package/dist/templates/react-app/src/core/globals.ts +10 -11
- package/dist/templates/react-app/src/main.tsx +1 -1
- package/dist/templates/react-app/src/pages/auth/Layout.tsx +4 -4
- package/dist/templates/react-app/src/pages/auth/RegisterPage.tsx +1 -1
- package/dist/templates/react-app/src/pages/base/Layout.tsx +3 -3
- package/dist/templates/react-app/src/pages/base/MessagePage.tsx +40 -0
- package/dist/templates/react-app/src/uikit/components/BaseLayoutProvider.tsx +44 -0
- package/dist/templates/react-app/src/uikit/components/LogoutButton.tsx +1 -3
- package/dist/templates/react-app/src/uikit/components/MessageBaseList.tsx +240 -0
- package/dist/templates/react-app/src/uikit/components/chatMessage/ChatMessageBridge.ts +176 -0
- package/dist/templates/react-app/src/uikit/components/chatMessage/ChatRoot.tsx +21 -0
- package/dist/templates/react-app/src/uikit/components/chatMessage/FocusBar.tsx +106 -0
- package/dist/templates/react-app/src/uikit/components/chatMessage/MessageApi.ts +271 -0
- package/dist/templates/react-app/src/uikit/components/chatMessage/MessageItem.tsx +102 -0
- package/dist/templates/react-app/src/uikit/components/chatMessage/MessagesList.tsx +86 -0
- package/dist/templates/react-app/src/uikit/hooks/useNavigateBridge.ts +9 -0
- package/dist/templates/react-app/src/uikit/hooks/{useI18nGuard.ts → useRouterI18nGuard.ts} +7 -4
- package/dist/templates/react-app/tsconfig.app.json +4 -2
- package/dist/templates/react-app/tsconfig.node.json +4 -0
- package/dist/templates/react-app/tsconfig.test.json +3 -1
- package/package.json +3 -3
- package/dist/templates/react-app/__tests__/src/base/cases/AppError.test.ts +0 -102
- package/dist/templates/react-app/__tests__/src/main.integration.test.tsx +0 -61
- package/dist/templates/react-app/src/base/services/ProcesserExecutor.ts +0 -57
- package/dist/templates/react-app/src/uikit/components/ProcessExecutorProvider.tsx +0 -28
- package/dist/templates/react-app/src/uikit/components/UserAuthProvider.tsx +0 -16
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { useStore } from '@brain-toolkit/react-kit';
|
|
2
|
+
import { useCallback, type ComponentType } from 'react';
|
|
3
|
+
import type { ChatMessageI18nInterface } from '@config/i18n/chatMessageI18n';
|
|
4
|
+
import { MessageItem, type MessageItemProps } from './MessageItem';
|
|
5
|
+
import type {
|
|
6
|
+
ChatMessage,
|
|
7
|
+
ChatMessageBridgeInterface
|
|
8
|
+
} from '@qlover/corekit-bridge';
|
|
9
|
+
|
|
10
|
+
export type MessageComponentType<
|
|
11
|
+
T,
|
|
12
|
+
MessageType extends ChatMessage<T>
|
|
13
|
+
> = ComponentType<MessageItemProps<T, MessageType>>;
|
|
14
|
+
|
|
15
|
+
export type GetMessageComponent<T, MessageType extends ChatMessage<T>> = (
|
|
16
|
+
props: MessageItemProps<T, MessageType>
|
|
17
|
+
) => MessageComponentType<T, MessageType>;
|
|
18
|
+
|
|
19
|
+
export interface MessagesListProps<T, MessageType extends ChatMessage<T>> {
|
|
20
|
+
bridge: ChatMessageBridgeInterface<T>;
|
|
21
|
+
tt: ChatMessageI18nInterface;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Get message component
|
|
25
|
+
*
|
|
26
|
+
* @default `MessageItem`
|
|
27
|
+
*
|
|
28
|
+
* @type `ComponentType<MessageItemProps<MessageType>>`
|
|
29
|
+
*/
|
|
30
|
+
getMessageComponent?: GetMessageComponent<T, MessageType>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get message unique identifier
|
|
34
|
+
*
|
|
35
|
+
* @default `(message.id ?? '') + (message.startTime ?? 0) + index`
|
|
36
|
+
*
|
|
37
|
+
* @param message Message
|
|
38
|
+
* @param index Message index
|
|
39
|
+
* @returns Message unique identifier
|
|
40
|
+
*/
|
|
41
|
+
getMessageKey?(message: MessageType, index: number): string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function MessagesList<T = string>({
|
|
45
|
+
bridge,
|
|
46
|
+
tt,
|
|
47
|
+
getMessageComponent,
|
|
48
|
+
getMessageKey
|
|
49
|
+
}: MessagesListProps<T, ChatMessage<T>>) {
|
|
50
|
+
const messagesStore = bridge.getMessageStore();
|
|
51
|
+
const messages = useStore(messagesStore, (state) => state.messages);
|
|
52
|
+
|
|
53
|
+
const _getMessageKey = useCallback(
|
|
54
|
+
(message: ChatMessage<T>, index: number): string => {
|
|
55
|
+
return (
|
|
56
|
+
getMessageKey?.(message, index) ||
|
|
57
|
+
String((message.id ?? '') + (message.startTime ?? 0) + index)
|
|
58
|
+
);
|
|
59
|
+
},
|
|
60
|
+
[getMessageKey]
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div
|
|
65
|
+
data-testid="MessagesList"
|
|
66
|
+
className="flex-1 overflow-y-auto p-4 space-y-2"
|
|
67
|
+
>
|
|
68
|
+
{messages.length === 0 ? (
|
|
69
|
+
<div className="flex items-center justify-center h-full">
|
|
70
|
+
<div className="text-center text-text-secondary">
|
|
71
|
+
<p className="text-base mb-1">{tt.empty}</p>
|
|
72
|
+
<p className="text-sm">{tt.start}</p>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
) : (
|
|
76
|
+
messages.map((message, index) => {
|
|
77
|
+
const key = _getMessageKey(message, index);
|
|
78
|
+
const props = { message, index, bridge, tt };
|
|
79
|
+
const Component = getMessageComponent?.(props) || MessageItem;
|
|
80
|
+
|
|
81
|
+
return <Component data-testid="MessageItem" key={key} {...props} />;
|
|
82
|
+
})
|
|
83
|
+
)}
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
@@ -3,6 +3,15 @@ import { useNavigate } from 'react-router-dom';
|
|
|
3
3
|
import { useIOC } from './useIOC';
|
|
4
4
|
import { NavigateBridge } from '../bridges/NavigateBridge';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* 使用 navigate 桥接
|
|
8
|
+
*
|
|
9
|
+
* 将 navigate 桥接到 NavigateBridge 中
|
|
10
|
+
*
|
|
11
|
+
* 这样就可以在服务层使用 navigate 了, 比如在某个service中需要跳转页面,就可以使用 navigateBridge.getUIBridge() 来跳转
|
|
12
|
+
*
|
|
13
|
+
* **但是它需要在 RouterProvider 中使用**
|
|
14
|
+
*/
|
|
6
15
|
export function useNavigateBridge() {
|
|
7
16
|
const navigate = useNavigate();
|
|
8
17
|
const navigateBridge = useIOC(NavigateBridge);
|
|
@@ -5,13 +5,16 @@ import type { LocaleType } from '@config/i18n/i18nConfig';
|
|
|
5
5
|
import { useIOC } from './useIOC';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* 国际化路由国际化守卫
|
|
9
9
|
*
|
|
10
|
-
*
|
|
10
|
+
* 比如: 开启了 `@config/common 中useLocaleRoutes` 为 `true` 时,
|
|
11
|
+
*
|
|
12
|
+
* 访问 `/login` 则会自动重定向到 `/en/login`, 其中 en 为默认语言可配置
|
|
13
|
+
*
|
|
14
|
+
* 或者访问一个不支持的语言,则会自动重定向到 `/en/404`
|
|
11
15
|
*
|
|
12
|
-
* TODO: if language not found, use default language
|
|
13
16
|
*/
|
|
14
|
-
export function
|
|
17
|
+
export function useRouterI18nGuard() {
|
|
15
18
|
const { lng } = useParams<{ lng: LocaleType }>();
|
|
16
19
|
const { pathname } = useLocation();
|
|
17
20
|
const navigate = useNavigate();
|
|
@@ -28,9 +28,11 @@
|
|
|
28
28
|
"paths": {
|
|
29
29
|
"@/*": ["./src/*"],
|
|
30
30
|
"@config/*": ["./config/*"],
|
|
31
|
-
"@lib/*": ["./lib/*"]
|
|
31
|
+
"@lib/*": ["./lib/*"],
|
|
32
|
+
"@qlover/corekit-bridge": ["../../../corekit-bridge"],
|
|
33
|
+
"@qlover/fe-corekit": ["../../../fe-corekit"]
|
|
32
34
|
}
|
|
33
35
|
},
|
|
34
36
|
"include": ["src", "config"],
|
|
35
|
-
"exclude": ["node_modules", "dist"]
|
|
37
|
+
"exclude": ["**/**/node_modules", "**/**dist"]
|
|
36
38
|
}
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
"@/*": ["./src/*"],
|
|
8
8
|
"@config/*": ["./config/*"],
|
|
9
9
|
"@__tests__/*": ["./__tests__/*"],
|
|
10
|
-
"@__mocks__/*": ["./__tests__/__mocks__/*"]
|
|
10
|
+
"@__mocks__/*": ["./__tests__/__mocks__/*"],
|
|
11
|
+
"@qlover/corekit-bridge": ["../../../corekit-bridge"],
|
|
12
|
+
"@qlover/fe-corekit": ["../../../fe-corekit"]
|
|
11
13
|
}
|
|
12
14
|
},
|
|
13
15
|
"include": ["__tests__/**/*"],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qlover/create-app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Create a new app with a single command",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
"ignore": "^7.0.3",
|
|
34
34
|
"lodash": "^4.17.21",
|
|
35
35
|
"ora": "^8.1.1",
|
|
36
|
-
"@qlover/logger": "0.
|
|
36
|
+
"@qlover/logger": "0.3.0"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"commander": "^13.1.0",
|
|
40
40
|
"inquirer": "^12.3.2",
|
|
41
|
-
"@qlover/scripts-context": "1.
|
|
41
|
+
"@qlover/scripts-context": "1.2.0"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"lint": "eslint src --fix",
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AppError test suite
|
|
3
|
-
*
|
|
4
|
-
* Coverage:
|
|
5
|
-
* 1. constructor - Constructor initialization with different source types
|
|
6
|
-
* 2. inheritance - Verify inheritance from ExecutorError
|
|
7
|
-
* 3. error properties - Verify error properties are set correctly
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { ExecutorError } from '@qlover/fe-corekit';
|
|
11
|
-
import { describe, it, expect } from 'vitest';
|
|
12
|
-
import { AppError } from '@/base/cases/AppError';
|
|
13
|
-
|
|
14
|
-
describe('AppError', () => {
|
|
15
|
-
describe('constructor', () => {
|
|
16
|
-
it('should create instance with id only', () => {
|
|
17
|
-
const error = new AppError('TEST_ERROR');
|
|
18
|
-
expect(error).toBeInstanceOf(AppError);
|
|
19
|
-
expect(error).toBeInstanceOf(ExecutorError);
|
|
20
|
-
expect(error).toBeInstanceOf(Error);
|
|
21
|
-
expect(error.id).toBe('TEST_ERROR');
|
|
22
|
-
expect(error.message).toBe('TEST_ERROR');
|
|
23
|
-
expect(error.source).toBeUndefined();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('should create instance with string source', () => {
|
|
27
|
-
const source = 'Test error message';
|
|
28
|
-
const error = new AppError('TEST_ERROR', source);
|
|
29
|
-
expect(error.id).toBe('TEST_ERROR');
|
|
30
|
-
expect(error.message).toBe(source);
|
|
31
|
-
expect(error.source).toBe(source);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('should create instance with Error source', () => {
|
|
35
|
-
const source = new Error('Original error');
|
|
36
|
-
const error = new AppError('TEST_ERROR', source);
|
|
37
|
-
expect(error.id).toBe('TEST_ERROR');
|
|
38
|
-
expect(error.message).toBe('Original error');
|
|
39
|
-
expect(error.source).toBe(source);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
describe('error properties', () => {
|
|
44
|
-
it('should have correct error type', () => {
|
|
45
|
-
const error = new AppError('TEST_ERROR');
|
|
46
|
-
expect(error.id).toBe('TEST_ERROR');
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('should maintain id property', () => {
|
|
50
|
-
const error = new AppError('TEST_ERROR');
|
|
51
|
-
Object.defineProperty(error, 'id', { value: 'NEW_ID' });
|
|
52
|
-
expect(error.id).toBe('NEW_ID');
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('should maintain source property', () => {
|
|
56
|
-
const source = 'source';
|
|
57
|
-
const error = new AppError('TEST_ERROR', source);
|
|
58
|
-
Object.defineProperty(error, 'source', { value: 'new source' });
|
|
59
|
-
expect(error.source).toBe('new source');
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
describe('error handling', () => {
|
|
64
|
-
it('should work in try-catch block', () => {
|
|
65
|
-
expect(() => {
|
|
66
|
-
throw new AppError('TEST_ERROR');
|
|
67
|
-
}).toThrow(AppError);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('should preserve stack trace', () => {
|
|
71
|
-
const error = new AppError('TEST_ERROR');
|
|
72
|
-
expect(error.stack).toBeDefined();
|
|
73
|
-
expect(error.stack).toContain('AppError.test.ts');
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should handle nested errors', () => {
|
|
77
|
-
const originalError = new Error('Original error');
|
|
78
|
-
const wrappedError = new AppError('WRAPPED_ERROR', originalError);
|
|
79
|
-
expect(wrappedError.source).toBe(originalError);
|
|
80
|
-
expect(wrappedError.message).toBe('Original error');
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
describe('error message formatting', () => {
|
|
85
|
-
it('should use id as message when source is undefined', () => {
|
|
86
|
-
const error = new AppError('TEST_ERROR');
|
|
87
|
-
expect(error.message).toBe('TEST_ERROR');
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('should use source message when source is Error', () => {
|
|
91
|
-
const source = new Error('Source error message');
|
|
92
|
-
const error = new AppError('TEST_ERROR', source);
|
|
93
|
-
expect(error.message).toBe('Source error message');
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('should use source string when source is string', () => {
|
|
97
|
-
const source = 'Source error message';
|
|
98
|
-
const error = new AppError('TEST_ERROR', source);
|
|
99
|
-
expect(error.message).toBe('Source error message');
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
});
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { readFileSync, existsSync } from 'fs';
|
|
2
|
-
import { join } from 'path';
|
|
3
|
-
|
|
4
|
-
describe('main.tsx Integration Tests', () => {
|
|
5
|
-
beforeAll(() => {
|
|
6
|
-
// Setup test environment
|
|
7
|
-
if (!document.getElementById('root')) {
|
|
8
|
-
const rootElement = document.createElement('div');
|
|
9
|
-
rootElement.id = 'root';
|
|
10
|
-
document.body.appendChild(rootElement);
|
|
11
|
-
}
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
afterAll(() => {
|
|
15
|
-
// Clean up DOM
|
|
16
|
-
const rootElement = document.getElementById('root');
|
|
17
|
-
if (rootElement) {
|
|
18
|
-
rootElement.remove();
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
// Clean up root element content
|
|
24
|
-
const rootElement = document.getElementById('root');
|
|
25
|
-
if (rootElement) {
|
|
26
|
-
rootElement.innerHTML = '';
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('should have main.tsx file', () => {
|
|
31
|
-
// Test if file exists
|
|
32
|
-
const mainPath = join(process.cwd(), 'src/main.tsx');
|
|
33
|
-
expect(existsSync(mainPath)).toBe(true);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('should have main.tsx with correct structure', () => {
|
|
37
|
-
// Test file content structure
|
|
38
|
-
const mainPath = join(process.cwd(), 'src/main.tsx');
|
|
39
|
-
const content = readFileSync(mainPath, 'utf-8');
|
|
40
|
-
|
|
41
|
-
// Check if it contains necessary imports
|
|
42
|
-
expect(content).toContain('import');
|
|
43
|
-
expect(content).toContain('BootstrapClient');
|
|
44
|
-
expect(content).toContain('createRoot');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('should have App.tsx file', () => {
|
|
48
|
-
// Test if App.tsx file exists
|
|
49
|
-
const appPath = join(process.cwd(), 'src/App.tsx');
|
|
50
|
-
expect(existsSync(appPath)).toBe(true);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('should have BootstrapClient.ts file', () => {
|
|
54
|
-
// Test if BootstrapClient.ts file exists
|
|
55
|
-
const bootstrapPath = join(
|
|
56
|
-
process.cwd(),
|
|
57
|
-
'src/core/bootstraps/BootstrapClient.ts'
|
|
58
|
-
);
|
|
59
|
-
expect(existsSync(bootstrapPath)).toBe(true);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
2
|
-
import {
|
|
3
|
-
AsyncExecutor,
|
|
4
|
-
ExecutorContext,
|
|
5
|
-
ExecutorPlugin
|
|
6
|
-
} from '@qlover/fe-corekit';
|
|
7
|
-
import { injectable, inject } from 'inversify';
|
|
8
|
-
import type { ProcesserExecutorInterface } from '../port/ProcesserExecutorInterface';
|
|
9
|
-
import type { RouteServiceInterface } from '../port/RouteServiceInterface';
|
|
10
|
-
import type { BootstrapContextValue } from '@qlover/corekit-bridge';
|
|
11
|
-
import type { LoggerInterface } from '@qlover/logger';
|
|
12
|
-
|
|
13
|
-
@injectable()
|
|
14
|
-
export class ProcesserExecutor implements ProcesserExecutorInterface {
|
|
15
|
-
pluginName = 'ProcesserExecutor';
|
|
16
|
-
protected executor: AsyncExecutor = new AsyncExecutor();
|
|
17
|
-
|
|
18
|
-
constructor(
|
|
19
|
-
@inject(IOCIdentifier.Logger) protected logger: LoggerInterface,
|
|
20
|
-
@inject(IOCIdentifier.RouteServiceInterface)
|
|
21
|
-
protected routeService: RouteServiceInterface
|
|
22
|
-
) {}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @override
|
|
26
|
-
*/
|
|
27
|
-
onBefore({
|
|
28
|
-
parameters: { ioc }
|
|
29
|
-
}: ExecutorContext<BootstrapContextValue>): void | Promise<void> {
|
|
30
|
-
this.use(ioc.get(IOCIdentifier.I18nKeyErrorPlugin));
|
|
31
|
-
this.use(ioc.get(IOCIdentifier.UserServiceInterface));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
use(plugin: ExecutorPlugin): this {
|
|
35
|
-
this.executor.use(plugin);
|
|
36
|
-
return this;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
handler(): Promise<{ success: boolean }> {
|
|
40
|
-
return Promise.resolve({
|
|
41
|
-
success: true
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async starup(): Promise<unknown> {
|
|
46
|
-
this.logger.info('PageProcesser startup');
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
const result = await this.executor.exec(this.handler);
|
|
50
|
-
return result;
|
|
51
|
-
} catch (err) {
|
|
52
|
-
this.logger.error('PageProcesser init failed', err);
|
|
53
|
-
|
|
54
|
-
this.routeService.gotoLogin();
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
2
|
-
import { UserAuthProvider } from './UserAuthProvider';
|
|
3
|
-
import { useI18nGuard } from '../hooks/useI18nGuard';
|
|
4
|
-
import { useIOC } from '../hooks/useIOC';
|
|
5
|
-
import { useNavigateBridge } from '../hooks/useNavigateBridge';
|
|
6
|
-
import { useStrictEffect } from '../hooks/useStrictEffect';
|
|
7
|
-
|
|
8
|
-
export function ProcessExecutorProvider({
|
|
9
|
-
children
|
|
10
|
-
}: {
|
|
11
|
-
children: React.ReactNode;
|
|
12
|
-
}) {
|
|
13
|
-
const processerExecutor = useIOC(IOCIdentifier.ProcesserExecutorInterface);
|
|
14
|
-
|
|
15
|
-
useI18nGuard();
|
|
16
|
-
|
|
17
|
-
useNavigateBridge();
|
|
18
|
-
|
|
19
|
-
useStrictEffect(() => {
|
|
20
|
-
processerExecutor.starup();
|
|
21
|
-
}, []);
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<UserAuthProvider data-testid="ProcessExecutorProvider">
|
|
25
|
-
{children}
|
|
26
|
-
</UserAuthProvider>
|
|
27
|
-
);
|
|
28
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { useStore } from '@brain-toolkit/react-kit/hooks/useStore';
|
|
2
|
-
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
3
|
-
import { Loading } from './Loading';
|
|
4
|
-
import { useIOC } from '../hooks/useIOC';
|
|
5
|
-
|
|
6
|
-
export function UserAuthProvider({ children }: { children: React.ReactNode }) {
|
|
7
|
-
const userService = useIOC(IOCIdentifier.UserServiceInterface);
|
|
8
|
-
|
|
9
|
-
useStore(userService.store);
|
|
10
|
-
|
|
11
|
-
if (!userService.isAuthenticated()) {
|
|
12
|
-
return <Loading data-testid="UserAuthProvider" fullscreen />;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
return children;
|
|
16
|
-
}
|