@qlover/create-app 0.10.1 → 0.10.3
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 +178 -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 +4 -4
- package/dist/index.js +4 -4
- package/dist/templates/next-app/config/IOCIdentifier.ts +2 -2
- package/dist/templates/next-app/config/Identifier/common/common.ts +14 -0
- package/dist/templates/next-app/config/Identifier/pages/index.ts +1 -0
- package/dist/templates/next-app/config/Identifier/pages/page.about.ts +20 -0
- package/dist/templates/next-app/config/common.ts +1 -1
- package/dist/templates/next-app/config/cookies.ts +23 -0
- package/dist/templates/next-app/config/i18n/AboutI18n.ts +14 -0
- package/dist/templates/next-app/config/i18n/i18nConfig.ts +3 -1
- package/dist/templates/next-app/config/i18n/index.ts +1 -0
- package/dist/templates/next-app/config/i18n/loginI18n.ts +8 -0
- package/dist/templates/next-app/config/theme.ts +4 -0
- package/dist/templates/next-app/eslint.config.mjs +9 -2
- package/dist/templates/next-app/next.config.ts +1 -0
- package/dist/templates/next-app/package.json +17 -6
- package/dist/templates/next-app/public/locales/en.json +5 -0
- package/dist/templates/next-app/public/locales/zh.json +5 -0
- package/dist/templates/next-app/src/app/[locale]/admin/AdminI18nProvider.tsx +37 -0
- package/dist/templates/next-app/src/app/[locale]/admin/layout.tsx +30 -6
- package/dist/templates/next-app/src/app/[locale]/admin/locales/page.tsx +1 -1
- package/dist/templates/next-app/src/app/[locale]/layout.tsx +47 -10
- package/dist/templates/next-app/src/app/[locale]/login/LoginForm.tsx +1 -1
- package/dist/templates/next-app/src/app/[locale]/login/page.tsx +22 -10
- package/dist/templates/next-app/src/app/[locale]/page.tsx +23 -8
- package/dist/templates/next-app/src/app/[locale]/register/page.tsx +21 -9
- package/dist/templates/next-app/src/app/api/admin/locales/create/route.ts +7 -28
- package/dist/templates/next-app/src/app/api/admin/locales/import/route.ts +7 -34
- package/dist/templates/next-app/src/app/api/admin/locales/route.ts +12 -34
- package/dist/templates/next-app/src/app/api/admin/locales/update/route.ts +7 -26
- package/dist/templates/next-app/src/app/api/admin/users/route.ts +14 -33
- package/dist/templates/next-app/src/app/api/locales/json/route.ts +13 -25
- package/dist/templates/next-app/src/app/api/user/login/route.ts +6 -46
- package/dist/templates/next-app/src/app/api/user/logout/route.ts +5 -24
- package/dist/templates/next-app/src/app/api/user/register/route.ts +6 -45
- package/dist/templates/next-app/src/app/manifest.ts +16 -0
- package/dist/templates/next-app/src/app/robots.txt +2 -0
- package/dist/templates/next-app/src/base/cases/AdminPageManager.ts +3 -3
- package/dist/templates/next-app/src/base/cases/AppConfig.ts +14 -13
- package/dist/templates/next-app/src/base/cases/Datetime.ts +3 -3
- package/dist/templates/next-app/src/base/cases/DialogErrorPlugin.ts +8 -2
- package/dist/templates/next-app/src/base/cases/DialogHandler.ts +30 -4
- package/dist/templates/next-app/src/base/cases/InversifyContainer.ts +16 -4
- package/dist/templates/next-app/src/base/cases/NavigateBridge.ts +20 -4
- package/dist/templates/next-app/src/base/cases/RequestEncryptPlugin.ts +8 -2
- package/dist/templates/next-app/src/base/cases/ResourceState.ts +3 -3
- package/dist/templates/next-app/src/base/cases/RouterService.ts +28 -10
- package/dist/templates/next-app/src/base/cases/StringEncryptor.ts +14 -2
- package/dist/templates/next-app/src/base/cases/TranslateI18nInterface.ts +1 -1
- package/dist/templates/next-app/src/base/cases/UserServiceApi.ts +20 -5
- package/dist/templates/next-app/src/base/cases/ZodColumnBuilder.ts +31 -8
- package/dist/templates/next-app/src/base/port/AdminLayoutInterface.ts +4 -1
- package/dist/templates/next-app/src/base/port/AppApiInterface.ts +22 -0
- package/dist/templates/next-app/src/base/port/I18nServiceInterface.ts +27 -7
- package/dist/templates/next-app/src/base/port/IOCInterface.ts +9 -0
- package/dist/templates/next-app/src/base/services/AdminPageEvent.ts +1 -1
- package/dist/templates/next-app/src/base/services/AdminPageScheduler.ts +3 -3
- package/dist/templates/next-app/src/base/services/I18nService.ts +20 -10
- package/dist/templates/next-app/src/base/services/ResourceService.ts +32 -11
- package/dist/templates/next-app/src/base/services/UserService.ts +12 -3
- package/dist/templates/next-app/src/base/services/adminApi/AdminLocalesApi.ts +9 -6
- package/dist/templates/next-app/src/base/services/adminApi/AdminUserApi.ts +20 -5
- package/dist/templates/next-app/src/base/services/appApi/AppApiPlugin.ts +21 -4
- package/dist/templates/next-app/src/base/services/appApi/AppUserApi.ts +12 -3
- package/dist/templates/next-app/src/base/services/appApi/AppUserApiBootstrap.ts +10 -2
- package/dist/templates/next-app/src/base/types/{PageProps.ts → AppPageRouter.ts} +4 -1
- package/dist/templates/next-app/src/base/types/PagesRouter.ts +9 -0
- package/dist/templates/next-app/src/core/bootstraps/BootstrapClient.ts +20 -6
- package/dist/templates/next-app/src/core/bootstraps/BootstrapServer.ts +27 -9
- package/dist/templates/next-app/src/core/bootstraps/BootstrapsRegistry.ts +6 -4
- package/dist/templates/next-app/src/core/clientIoc/ClientIOC.ts +39 -9
- package/dist/templates/next-app/src/core/clientIoc/ClientIOCRegister.ts +9 -2
- package/dist/templates/next-app/src/core/serverIoc/ServerIOC.ts +37 -10
- package/dist/templates/next-app/src/core/serverIoc/ServerIOCRegister.ts +9 -2
- package/dist/templates/next-app/src/i18n/loadMessages.ts +103 -0
- package/dist/templates/next-app/src/i18n/request.ts +3 -22
- package/dist/templates/next-app/src/pages/[locale]/about.tsx +61 -0
- package/dist/templates/next-app/src/pages/_app.tsx +50 -0
- package/dist/templates/next-app/src/pages/_document.tsx +13 -0
- package/dist/templates/next-app/src/{middleware.ts → proxy.ts} +2 -1
- package/dist/templates/next-app/src/server/AppErrorApi.ts +1 -1
- package/dist/templates/next-app/src/server/AppPageRouteParams.ts +107 -0
- package/dist/templates/next-app/src/server/AppSuccessApi.ts +1 -1
- package/dist/templates/next-app/src/server/NextApiServer.ts +62 -0
- package/dist/templates/next-app/src/server/PagesRouteParams.ts +146 -0
- package/dist/templates/next-app/src/server/PasswordEncrypt.ts +8 -2
- package/dist/templates/next-app/src/server/ServerAuth.ts +20 -5
- package/dist/templates/next-app/src/server/{sqlBridges/SupabaseBridge.ts → SupabaseBridge.ts} +50 -8
- package/dist/templates/next-app/src/server/UserCredentialToken.ts +8 -2
- package/dist/templates/next-app/src/server/controllers/AdminLocalesController.ts +86 -0
- package/dist/templates/next-app/src/server/controllers/AdminUserController.ts +42 -0
- package/dist/templates/next-app/src/server/controllers/LocalesController.ts +36 -0
- package/dist/templates/next-app/src/server/controllers/UserController.ts +86 -0
- package/dist/templates/next-app/src/server/port/AIControllerInterface.ts +8 -0
- package/dist/templates/next-app/src/server/port/AdminLocalesControllerInterface.ts +21 -0
- package/dist/templates/next-app/src/server/port/AdminUserControllerInterface.ts +11 -0
- package/dist/templates/next-app/src/server/port/LocalesControllerInterface.ts +10 -0
- package/dist/templates/next-app/src/server/port/{ParamsHandlerInterface.ts → RouteParamsnHandlerInterface.ts} +9 -2
- package/dist/templates/next-app/src/server/port/ServerInterface.ts +2 -2
- package/dist/templates/next-app/src/server/port/UserControllerInerface.ts +8 -0
- package/dist/templates/next-app/src/server/port/UserServiceInterface.ts +1 -1
- package/dist/templates/next-app/src/server/port/ValidatorInterface.ts +2 -2
- package/dist/templates/next-app/src/server/repositorys/LocalesRepository.ts +31 -9
- package/dist/templates/next-app/src/server/repositorys/UserRepository.ts +15 -6
- package/dist/templates/next-app/src/server/services/AIService.ts +3 -1
- package/dist/templates/next-app/src/server/services/AdminAuthPlugin.ts +5 -2
- package/dist/templates/next-app/src/{base → server}/services/AdminLocalesService.ts +2 -2
- package/dist/templates/next-app/src/server/services/ApiLocaleService.ts +29 -14
- package/dist/templates/next-app/src/server/services/ApiUserService.ts +6 -3
- package/dist/templates/next-app/src/server/services/UserService.ts +12 -3
- package/dist/templates/next-app/src/server/validators/LocalesValidator.ts +24 -7
- package/dist/templates/next-app/src/server/validators/LoginValidator.ts +17 -5
- package/dist/templates/next-app/src/server/validators/PaginationValidator.ts +17 -11
- package/dist/templates/next-app/src/styles/css/antd-themes/_common/_default.css +0 -44
- package/dist/templates/next-app/src/styles/css/antd-themes/_common/dark.css +0 -44
- package/dist/templates/next-app/src/styles/css/antd-themes/_common/pink.css +0 -44
- package/dist/templates/next-app/src/styles/css/index.css +1 -1
- package/dist/templates/next-app/src/styles/css/scrollbar.css +34 -0
- package/dist/templates/next-app/src/uikit/components/AdminLayout.tsx +34 -11
- package/dist/templates/next-app/src/uikit/components/BootstrapsProvider.tsx +69 -39
- package/dist/templates/next-app/src/uikit/components/ClientRootProvider.tsx +64 -0
- package/dist/templates/next-app/src/uikit/components/ClinetRenderProvider.tsx +42 -0
- package/dist/templates/next-app/src/uikit/components/IOCProvider.tsx +34 -0
- package/dist/templates/next-app/src/uikit/components/localesImportButton/LocalesImportEvent.ts +7 -1
- package/dist/templates/next-app/src/uikit/components-app/AppBridge.tsx +17 -0
- package/dist/templates/next-app/src/uikit/components-app/AppRoutePage.tsx +112 -0
- package/dist/templates/next-app/src/uikit/{components → components-app}/LanguageSwitcher.tsx +15 -19
- package/dist/templates/next-app/src/uikit/{components → components-app}/ThemeSwitcher.tsx +53 -52
- package/dist/templates/next-app/src/uikit/components-pages/LanguageSwitcher.tsx +98 -0
- package/dist/templates/next-app/src/uikit/components-pages/PagesRoutePage.tsx +93 -0
- package/dist/templates/next-app/src/uikit/context/IOCContext.ts +16 -4
- package/dist/templates/next-app/src/uikit/hook/useStrictEffect.ts +32 -0
- package/dist/templates/next-app/tsconfig.json +3 -2
- package/dist/templates/react-app/__tests__/__mocks__/BootstrapTest.ts +3 -1
- package/dist/templates/react-app/__tests__/__mocks__/MockAppConfig.ts +19 -19
- package/dist/templates/react-app/__tests__/__mocks__/MockDialogHandler.ts +8 -8
- package/dist/templates/react-app/__tests__/__mocks__/MockLogger.ts +9 -9
- package/dist/templates/react-app/__tests__/__mocks__/components/TestBootstrapsProvider.tsx +1 -1
- package/dist/templates/react-app/__tests__/__mocks__/i18nextHttpBackend.ts +5 -5
- package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOC.ts +9 -5
- package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOCRegister.ts +8 -4
- package/dist/templates/react-app/__tests__/src/base/cases/I18nKeyErrorPlugin.test.ts +4 -4
- package/dist/templates/react-app/__tests__/src/base/cases/InversifyContainer.test.ts +5 -5
- package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapClient.test.ts +3 -3
- package/dist/templates/react-app/__tests__/src/uikit/components/chatMessage/ChatRoot.test.tsx +1 -1
- package/dist/templates/react-app/docs/en/components/chat-message-component.md +35 -29
- package/dist/templates/react-app/docs/en/components/chat-message-refactor.md +18 -5
- package/dist/templates/react-app/docs/en/components/message-base-list-component.md +11 -12
- package/dist/templates/react-app/docs/en/request.md +1 -3
- package/dist/templates/react-app/docs/zh/components/chat-message-component.md +35 -29
- package/dist/templates/react-app/docs/zh/components/chat-message-refactor.md +18 -5
- package/dist/templates/react-app/docs/zh/components/message-base-list-component.md +11 -12
- package/dist/templates/react-app/docs/zh/request.md +1 -3
- package/dist/templates/react-app/eslint.config.mjs +10 -5
- package/dist/templates/react-app/src/App.tsx +1 -1
- package/dist/templates/react-app/src/base/apis/feApi/FeApi.ts +2 -2
- package/dist/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +14 -11
- package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +10 -16
- package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +12 -10
- package/dist/templates/react-app/src/base/cases/AppConfig.ts +19 -19
- package/dist/templates/react-app/src/base/cases/DialogHandler.ts +28 -5
- package/dist/templates/react-app/src/base/cases/I18nKeyErrorPlugin.ts +5 -2
- package/dist/templates/react-app/src/base/cases/InversifyContainer.ts +16 -4
- package/dist/templates/react-app/src/base/cases/PublicAssetsPath.ts +1 -1
- package/dist/templates/react-app/src/base/cases/RequestLanguages.ts +6 -3
- package/dist/templates/react-app/src/base/cases/RequestLogger.ts +17 -8
- package/dist/templates/react-app/src/base/cases/RequestStatusCatcher.ts +4 -6
- package/dist/templates/react-app/src/base/cases/ResourceState.ts +3 -3
- package/dist/templates/react-app/src/base/cases/RouterLoader.ts +3 -3
- package/dist/templates/react-app/src/base/cases/TranslateI18nInterface.ts +1 -1
- package/dist/templates/react-app/src/base/port/ExecutorPageBridgeInterface.ts +2 -2
- package/dist/templates/react-app/src/base/port/IOCInterface.ts +4 -2
- package/dist/templates/react-app/src/base/port/JSONStoragePageBridgeInterface.ts +5 -5
- package/dist/templates/react-app/src/base/port/RequestPageBridgeInterface.ts +7 -7
- package/dist/templates/react-app/src/base/port/RouteServiceInterface.ts +8 -8
- package/dist/templates/react-app/src/base/port/UserServiceInterface.ts +4 -2
- package/dist/templates/react-app/src/base/services/BaseLayoutService.ts +3 -3
- package/dist/templates/react-app/src/base/services/I18nService.ts +24 -13
- package/dist/templates/react-app/src/base/services/IdentifierService.ts +21 -26
- package/dist/templates/react-app/src/base/services/RouteService.ts +8 -8
- package/dist/templates/react-app/src/base/services/UserBootstrap.ts +2 -2
- package/dist/templates/react-app/src/base/services/UserGatewayPlugin.ts +9 -5
- package/dist/templates/react-app/src/base/services/UserService.ts +10 -4
- package/dist/templates/react-app/src/core/bootstraps/BootstrapClient.ts +3 -1
- package/dist/templates/react-app/src/core/bootstraps/BootstrapsRegistry.ts +5 -2
- package/dist/templates/react-app/src/core/clientIoc/ClientIOC.ts +11 -4
- package/dist/templates/react-app/src/core/clientIoc/ClientIOCRegister.ts +5 -4
- package/dist/templates/react-app/src/pages/base/Layout.tsx +1 -1
- package/dist/templates/react-app/src/styles/css/antd-themes/_common/_default.css +0 -44
- package/dist/templates/react-app/src/styles/css/antd-themes/_common/dark.css +0 -44
- package/dist/templates/react-app/src/styles/css/antd-themes/_common/pink.css +0 -44
- package/dist/templates/react-app/src/styles/css/index.css +1 -1
- package/dist/templates/react-app/src/styles/css/scrollbar.css +34 -0
- package/dist/templates/react-app/src/uikit/bridges/ExecutorPageBridge.ts +2 -2
- package/dist/templates/react-app/src/uikit/bridges/JSONStoragePageBridge.ts +4 -4
- package/dist/templates/react-app/src/uikit/bridges/NavigateBridge.ts +8 -2
- package/dist/templates/react-app/src/uikit/bridges/RequestPageBridge.ts +6 -6
- package/dist/templates/react-app/src/uikit/components/AppRouterProvider.tsx +1 -1
- package/dist/templates/react-app/src/uikit/components/BootstrapsProvider.tsx +1 -3
- package/dist/templates/react-app/src/uikit/components/MessageBaseList.tsx +4 -1
- package/dist/templates/react-app/src/uikit/components/chatMessage/ChatMessageBridge.ts +39 -16
- package/dist/templates/react-app/src/uikit/components/chatMessage/MessageApi.ts +4 -2
- package/package.json +3 -3
- package/dist/templates/next-app/src/server/PageParams.ts +0 -66
- package/dist/templates/next-app/src/uikit/components/BaseHeader.tsx +0 -80
- package/dist/templates/next-app/src/uikit/components/BaseLayout.tsx +0 -65
- package/dist/templates/next-app/src/uikit/components/ComboProvider.tsx +0 -58
- package/dist/templates/next-app/src/uikit/components/NextIntlProvider.tsx +0 -21
- package/dist/templates/react-app/makes/eslint-utils.mjs +0 -195
- /package/dist/templates/next-app/{src/app/[locale] → public}/favicon.ico +0 -0
- /package/dist/templates/next-app/src/uikit/{components → components-app}/LogoutButton.tsx +0 -0
|
@@ -14,11 +14,20 @@ import { useMountedClient } from '@brain-toolkit/react-kit';
|
|
|
14
14
|
import { Dropdown } from 'antd';
|
|
15
15
|
import { clsx } from 'clsx';
|
|
16
16
|
import { useTheme } from 'next-themes';
|
|
17
|
-
import { useMemo } from 'react';
|
|
17
|
+
import { useEffect, useMemo } from 'react';
|
|
18
|
+
import {
|
|
19
|
+
COMMON_THEME_DARK,
|
|
20
|
+
COMMON_THEME_DEFAULT,
|
|
21
|
+
COMMON_THEME_LIGHT,
|
|
22
|
+
COMMON_THEME_PINK
|
|
23
|
+
} from '@config/Identifier';
|
|
24
|
+
import { I } from '@config/IOCIdentifier';
|
|
18
25
|
import { type SupportedTheme, themeConfig } from '@config/theme';
|
|
26
|
+
import { useIOC } from '../hook/useIOC';
|
|
27
|
+
import { useWarnTranslations } from '../hook/useWarnTranslations';
|
|
19
28
|
import type { ItemType } from 'antd/es/menu/interface';
|
|
20
29
|
|
|
21
|
-
const { supportedThemes } = themeConfig;
|
|
30
|
+
const { supportedThemes, storageKey } = themeConfig;
|
|
22
31
|
|
|
23
32
|
const defaultTheme = supportedThemes[0] || 'system';
|
|
24
33
|
const themesList = ['system', ...supportedThemes];
|
|
@@ -31,71 +40,76 @@ const colorMap: Record<
|
|
|
31
40
|
normalColor: string;
|
|
32
41
|
Icon: React.ElementType;
|
|
33
42
|
SelectedIcon: React.ElementType;
|
|
34
|
-
TriggerIcon: React.ElementType;
|
|
35
43
|
}
|
|
36
44
|
> = {
|
|
37
45
|
system: {
|
|
38
|
-
i18nkey:
|
|
46
|
+
i18nkey: COMMON_THEME_DEFAULT,
|
|
39
47
|
selectedColor: 'text-text',
|
|
40
48
|
normalColor: 'text-text-secondary',
|
|
41
49
|
Icon: SettingOutlined,
|
|
42
|
-
SelectedIcon: SettingFilled
|
|
43
|
-
TriggerIcon: SettingOutlined
|
|
50
|
+
SelectedIcon: SettingFilled
|
|
44
51
|
},
|
|
45
52
|
light: {
|
|
46
|
-
i18nkey:
|
|
53
|
+
i18nkey: COMMON_THEME_LIGHT,
|
|
47
54
|
selectedColor: 'text-text',
|
|
48
55
|
normalColor: 'text-text-secondary',
|
|
49
56
|
Icon: SunOutlined,
|
|
50
|
-
SelectedIcon: SunFilled
|
|
51
|
-
TriggerIcon: SunOutlined
|
|
57
|
+
SelectedIcon: SunFilled
|
|
52
58
|
},
|
|
53
59
|
dark: {
|
|
54
|
-
i18nkey:
|
|
60
|
+
i18nkey: COMMON_THEME_DARK,
|
|
55
61
|
selectedColor: 'text-[#9333ea]',
|
|
56
62
|
normalColor: 'text-[#a855f7]',
|
|
57
63
|
Icon: MoonOutlined,
|
|
58
|
-
SelectedIcon: MoonFilled
|
|
59
|
-
TriggerIcon: MoonOutlined
|
|
64
|
+
SelectedIcon: MoonFilled
|
|
60
65
|
},
|
|
61
66
|
pink: {
|
|
62
|
-
i18nkey:
|
|
67
|
+
i18nkey: COMMON_THEME_PINK,
|
|
63
68
|
selectedColor: 'text-[#f472b6]',
|
|
64
69
|
normalColor: 'text-[#ec4899]',
|
|
65
70
|
Icon: HeartOutlined,
|
|
66
|
-
SelectedIcon: HeartFilled
|
|
67
|
-
TriggerIcon: HeartOutlined
|
|
71
|
+
SelectedIcon: HeartFilled
|
|
68
72
|
}
|
|
69
73
|
};
|
|
70
74
|
|
|
71
75
|
export function ThemeSwitcher() {
|
|
72
76
|
const { theme: currentTheme, resolvedTheme, setTheme } = useTheme();
|
|
73
77
|
const mounted = useMountedClient();
|
|
78
|
+
const cookieStorage = useIOC(I.CookieStorage);
|
|
79
|
+
const t = useWarnTranslations();
|
|
80
|
+
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (resolvedTheme) {
|
|
83
|
+
cookieStorage.setItem(storageKey, resolvedTheme);
|
|
84
|
+
}
|
|
85
|
+
}, [resolvedTheme, cookieStorage]);
|
|
74
86
|
|
|
75
|
-
const themeOptions =
|
|
76
|
-
|
|
77
|
-
|
|
87
|
+
const themeOptions = useMemo(() => {
|
|
88
|
+
return themesList.map((themeName) => {
|
|
89
|
+
const { i18nkey, selectedColor, normalColor, Icon, SelectedIcon } =
|
|
90
|
+
colorMap[themeName] || colorMap.light;
|
|
78
91
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
92
|
+
const isCurrentTheme =
|
|
93
|
+
currentTheme === themeName ||
|
|
94
|
+
(themeName === resolvedTheme && currentTheme === 'system');
|
|
82
95
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
return {
|
|
97
|
+
key: themeName,
|
|
98
|
+
value: themeName,
|
|
99
|
+
label: (
|
|
100
|
+
<div
|
|
101
|
+
className={clsx(
|
|
102
|
+
'flex items-center gap-2',
|
|
103
|
+
isCurrentTheme ? selectedColor : normalColor
|
|
104
|
+
)}
|
|
105
|
+
>
|
|
106
|
+
{isCurrentTheme ? <SelectedIcon /> : <Icon />}
|
|
107
|
+
<span>{t(i18nkey)}</span>
|
|
108
|
+
</div>
|
|
109
|
+
)
|
|
110
|
+
} as ItemType;
|
|
111
|
+
});
|
|
112
|
+
}, [currentTheme, resolvedTheme, t]);
|
|
99
113
|
|
|
100
114
|
const nextTheme = useMemo(() => {
|
|
101
115
|
if (!currentTheme) {
|
|
@@ -106,26 +120,13 @@ export function ThemeSwitcher() {
|
|
|
106
120
|
return supportedThemes[targetIndex % supportedThemes.length];
|
|
107
121
|
}, [currentTheme]);
|
|
108
122
|
|
|
109
|
-
const TriggerIcon = colorMap[currentTheme || defaultTheme].TriggerIcon;
|
|
110
|
-
|
|
111
|
-
if (!mounted) {
|
|
112
|
-
return (
|
|
113
|
-
<span
|
|
114
|
-
data-testid="ThemeSwitcher"
|
|
115
|
-
className="text-text hover:text-text-hover cursor-pointer text-lg transition-colors"
|
|
116
|
-
>
|
|
117
|
-
<SettingOutlined />
|
|
118
|
-
</span>
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
123
|
return (
|
|
123
124
|
<Dropdown
|
|
124
125
|
data-testid="ThemeSwitcherDropdown"
|
|
125
126
|
trigger={['hover']}
|
|
126
127
|
menu={{
|
|
127
128
|
items: themeOptions,
|
|
128
|
-
selectedKeys: [
|
|
129
|
+
selectedKeys: mounted ? [resolvedTheme!] : undefined,
|
|
129
130
|
onClick: ({ key }) => {
|
|
130
131
|
setTheme(key);
|
|
131
132
|
}
|
|
@@ -136,7 +137,7 @@ export function ThemeSwitcher() {
|
|
|
136
137
|
className="text-text hover:text-text-hover cursor-pointer text-lg transition-colors"
|
|
137
138
|
onClick={() => setTheme(nextTheme)}
|
|
138
139
|
>
|
|
139
|
-
<
|
|
140
|
+
<SunOutlined />
|
|
140
141
|
</span>
|
|
141
142
|
</Dropdown>
|
|
142
143
|
);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { TranslationOutlined } from '@ant-design/icons';
|
|
4
|
+
import { Dropdown } from 'antd';
|
|
5
|
+
import { useRouter } from 'next/router';
|
|
6
|
+
import { useLocale } from 'next-intl';
|
|
7
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
8
|
+
import { useLocaleRoutes } from '@config/common';
|
|
9
|
+
import { i18nConfig } from '@config/i18n';
|
|
10
|
+
import type { LocaleType } from '@config/i18n';
|
|
11
|
+
import type { ItemType } from 'antd/es/menu/interface';
|
|
12
|
+
|
|
13
|
+
export function LanguageSwitcher() {
|
|
14
|
+
const router = useRouter();
|
|
15
|
+
const currentLocale = useLocale() as LocaleType;
|
|
16
|
+
const [isPending, setIsPending] = useState(false);
|
|
17
|
+
|
|
18
|
+
const options: ItemType[] = useMemo(() => {
|
|
19
|
+
return i18nConfig.supportedLngs.map(
|
|
20
|
+
(lang) =>
|
|
21
|
+
({
|
|
22
|
+
type: 'item',
|
|
23
|
+
key: lang,
|
|
24
|
+
value: lang,
|
|
25
|
+
label:
|
|
26
|
+
i18nConfig.localeNames[lang as keyof typeof i18nConfig.localeNames]
|
|
27
|
+
}) as ItemType
|
|
28
|
+
);
|
|
29
|
+
}, []);
|
|
30
|
+
|
|
31
|
+
const handleLanguageChange = useCallback(
|
|
32
|
+
async (value: string) => {
|
|
33
|
+
if (isPending || value === currentLocale) return;
|
|
34
|
+
|
|
35
|
+
setIsPending(true);
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
// Get current path
|
|
39
|
+
let newPath = router.asPath;
|
|
40
|
+
|
|
41
|
+
if (useLocaleRoutes) {
|
|
42
|
+
// Replace locale in path (e.g., /en/about -> /zh/about)
|
|
43
|
+
const pathWithoutLocale = newPath.replace(
|
|
44
|
+
new RegExp(`^/${currentLocale}(/|$)`),
|
|
45
|
+
'/'
|
|
46
|
+
);
|
|
47
|
+
// Remove leading slash if path is root
|
|
48
|
+
const cleanPath = pathWithoutLocale === '/' ? '' : pathWithoutLocale;
|
|
49
|
+
newPath = `/${value}${cleanPath}`;
|
|
50
|
+
} else {
|
|
51
|
+
// If not using locale routes, just update query param
|
|
52
|
+
newPath = router.pathname;
|
|
53
|
+
router.replace({
|
|
54
|
+
pathname: router.pathname,
|
|
55
|
+
query: { ...router.query, locale: value }
|
|
56
|
+
});
|
|
57
|
+
setIsPending(false);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Replace the route
|
|
62
|
+
router.replace(newPath);
|
|
63
|
+
} finally {
|
|
64
|
+
setIsPending(false);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
[router, currentLocale, isPending]
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const nextLocale = useMemo(() => {
|
|
71
|
+
const targetIndex = i18nConfig.supportedLngs.indexOf(currentLocale) + 1;
|
|
72
|
+
return i18nConfig.supportedLngs[
|
|
73
|
+
targetIndex % i18nConfig.supportedLngs.length
|
|
74
|
+
];
|
|
75
|
+
}, [currentLocale]);
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<Dropdown
|
|
79
|
+
data-testid="LanguageSwitcherDropdown"
|
|
80
|
+
trigger={['hover']}
|
|
81
|
+
menu={{
|
|
82
|
+
selectedKeys: [currentLocale],
|
|
83
|
+
items: options,
|
|
84
|
+
onClick: ({ key }) => {
|
|
85
|
+
handleLanguageChange(key);
|
|
86
|
+
}
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
<span
|
|
90
|
+
data-testid="LanguageSwitcher"
|
|
91
|
+
className="text-text hover:text-text-hover cursor-pointer text-lg transition-colors"
|
|
92
|
+
onClick={() => handleLanguageChange(nextLocale)}
|
|
93
|
+
>
|
|
94
|
+
<TranslationOutlined />
|
|
95
|
+
</span>
|
|
96
|
+
</Dropdown>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { TeamOutlined } from '@ant-design/icons';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { useLocale } from 'next-intl';
|
|
4
|
+
import { useMemo } from 'react';
|
|
5
|
+
import { LanguageSwitcher } from './LanguageSwitcher';
|
|
6
|
+
import { LocaleLink } from '../components/LocaleLink';
|
|
7
|
+
import { ThemeSwitcher } from '../components-app/ThemeSwitcher';
|
|
8
|
+
import type { AppRoutePageProps } from '../components-app/AppRoutePage';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* App Route Page
|
|
12
|
+
*
|
|
13
|
+
* 主要用于 /src/app 目录下页面的基础布局,包含头部、主体内容等
|
|
14
|
+
*
|
|
15
|
+
* @description
|
|
16
|
+
* - /src/app/[locale]/page.tsx
|
|
17
|
+
* - /src/app/[locale]/login/page.tsx
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
export function PagesRoutePage({
|
|
21
|
+
children,
|
|
22
|
+
showAdminButton,
|
|
23
|
+
mainProps,
|
|
24
|
+
headerClassName,
|
|
25
|
+
tt,
|
|
26
|
+
headerHref = '/',
|
|
27
|
+
...props
|
|
28
|
+
}: AppRoutePageProps) {
|
|
29
|
+
const locale = useLocale();
|
|
30
|
+
const adminTitle = tt.adminTitle;
|
|
31
|
+
|
|
32
|
+
const actions = useMemo(() => {
|
|
33
|
+
return [
|
|
34
|
+
showAdminButton && (
|
|
35
|
+
<LocaleLink
|
|
36
|
+
key="admin-button"
|
|
37
|
+
href="/admin"
|
|
38
|
+
title={adminTitle}
|
|
39
|
+
locale={locale}
|
|
40
|
+
className="text-text hover:text-text-hover cursor-pointer text-lg transition-colors"
|
|
41
|
+
>
|
|
42
|
+
<TeamOutlined className="text-lg text-text" />
|
|
43
|
+
</LocaleLink>
|
|
44
|
+
),
|
|
45
|
+
|
|
46
|
+
<LanguageSwitcher key="language-switcher" />,
|
|
47
|
+
|
|
48
|
+
<ThemeSwitcher key="theme-switcher" />
|
|
49
|
+
].filter(Boolean);
|
|
50
|
+
}, [adminTitle, showAdminButton, locale]);
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<div
|
|
54
|
+
data-testid="AppRoutePage"
|
|
55
|
+
className="flex flex-col min-h-screen"
|
|
56
|
+
{...props}
|
|
57
|
+
>
|
|
58
|
+
<header
|
|
59
|
+
data-testid="BaseHeader"
|
|
60
|
+
className="h-14 bg-secondary border-b border-c-border sticky top-0 z-50"
|
|
61
|
+
>
|
|
62
|
+
<div
|
|
63
|
+
className={clsx(
|
|
64
|
+
'flex items-center justify-between h-full px-4 mx-auto max-w-7xl',
|
|
65
|
+
headerClassName
|
|
66
|
+
)}
|
|
67
|
+
>
|
|
68
|
+
<div className="flex items-center">
|
|
69
|
+
<LocaleLink
|
|
70
|
+
data-testid="BaseHeaderLogo"
|
|
71
|
+
title={tt.title}
|
|
72
|
+
href={headerHref}
|
|
73
|
+
locale={locale}
|
|
74
|
+
className="flex items-center hover:opacity-80 transition-opacity"
|
|
75
|
+
>
|
|
76
|
+
<span
|
|
77
|
+
data-testid="base-header-app-name"
|
|
78
|
+
className="text-lg font-semibold text-text"
|
|
79
|
+
>
|
|
80
|
+
{tt.title}
|
|
81
|
+
</span>
|
|
82
|
+
</LocaleLink>
|
|
83
|
+
</div>
|
|
84
|
+
<div className="flex items-center gap-2 md:gap-4">{actions}</div>
|
|
85
|
+
</div>
|
|
86
|
+
</header>
|
|
87
|
+
|
|
88
|
+
<main className="flex flex-1 flex-col bg-primary" {...mainProps}>
|
|
89
|
+
{children}
|
|
90
|
+
</main>
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import {
|
|
4
|
+
type IOCContainerInterface,
|
|
5
|
+
type IOCFunctionInterface
|
|
6
|
+
} from '@qlover/corekit-bridge';
|
|
3
7
|
import { createContext } from 'react';
|
|
8
|
+
import { ClientIOC } from '@/core/clientIoc/ClientIOC';
|
|
4
9
|
import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
|
|
11
|
+
// export const IOCInstance = new ClientIOC();
|
|
12
|
+
|
|
13
|
+
// export const IOCContext =
|
|
14
|
+
// createContext<IOCInterface<IOCIdentifierMap, IOCContainerInterface>>(
|
|
15
|
+
// IOCInstance
|
|
16
|
+
// );
|
|
17
|
+
|
|
18
|
+
export const clientIOC = new ClientIOC();
|
|
19
|
+
|
|
20
|
+
export const IOCInstance = clientIOC.create();
|
|
9
21
|
|
|
10
22
|
export const IOCContext = createContext<IOCFunctionInterface<
|
|
11
23
|
IOCIdentifierMap,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* In React Strict Mode, ensure that the effect is executed only once when each dependency changes
|
|
5
|
+
* @param effect The effect function to execute
|
|
6
|
+
* @param deps The dependency array
|
|
7
|
+
*/
|
|
8
|
+
export const useStrictEffect = (
|
|
9
|
+
effect: () => void | (() => void),
|
|
10
|
+
deps?: React.DependencyList
|
|
11
|
+
) => {
|
|
12
|
+
const mountedRef = useRef(false);
|
|
13
|
+
const depsRef = useRef(deps);
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
// Check if the dependencies have changed
|
|
17
|
+
const depsChanged =
|
|
18
|
+
!deps ||
|
|
19
|
+
!depsRef.current ||
|
|
20
|
+
deps.some((dep, i) => dep !== depsRef.current![i]);
|
|
21
|
+
|
|
22
|
+
// Update the dependency reference
|
|
23
|
+
depsRef.current = deps;
|
|
24
|
+
|
|
25
|
+
// If it's the first mount or the dependencies have changed, execute the effect
|
|
26
|
+
if (!mountedRef.current || depsChanged) {
|
|
27
|
+
mountedRef.current = true;
|
|
28
|
+
return effect();
|
|
29
|
+
}
|
|
30
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
31
|
+
}, deps);
|
|
32
|
+
};
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"moduleResolution": "bundler",
|
|
12
12
|
"resolveJsonModule": true,
|
|
13
13
|
"isolatedModules": true,
|
|
14
|
-
"jsx": "
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
15
|
"incremental": true,
|
|
16
16
|
"experimentalDecorators": true,
|
|
17
17
|
"emitDecoratorMetadata": true,
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
"src/**/*.tsx",
|
|
33
33
|
"migrations/**/*.ts",
|
|
34
34
|
".next/types/**/*.ts",
|
|
35
|
-
"config/**/*.ts"
|
|
35
|
+
"config/**/*.ts",
|
|
36
|
+
".next/dev/types/**/*.ts"
|
|
36
37
|
],
|
|
37
38
|
"exclude": ["node_modules"]
|
|
38
39
|
}
|
|
@@ -7,7 +7,9 @@ export interface BootstrapTestArgs extends Omit<BootstrapClientArgs, 'ioc'> {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export class BootstrapTest {
|
|
10
|
-
static async main(
|
|
10
|
+
public static async main(
|
|
11
|
+
args: BootstrapTestArgs
|
|
12
|
+
): Promise<BootstrapClientArgs> {
|
|
11
13
|
const result = await BootstrapClient.main({ ...args, ioc: testIOC });
|
|
12
14
|
return result;
|
|
13
15
|
}
|
|
@@ -2,17 +2,17 @@ import { name, version } from '../../package.json';
|
|
|
2
2
|
import type { EnvConfigInterface } from '@qlover/corekit-bridge';
|
|
3
3
|
|
|
4
4
|
export class MockAppConfig implements EnvConfigInterface {
|
|
5
|
-
appName = name;
|
|
5
|
+
public appName = name;
|
|
6
6
|
|
|
7
|
-
appVersion = version;
|
|
7
|
+
public appVersion = version;
|
|
8
8
|
|
|
9
|
-
env: string = 'test';
|
|
9
|
+
public env: string = 'test';
|
|
10
10
|
|
|
11
|
-
userTokenStorageKey = '__fe_user_token__';
|
|
11
|
+
public userTokenStorageKey = '__fe_user_token__';
|
|
12
12
|
|
|
13
|
-
userInfoStorageKey = '__fe_user_info__';
|
|
13
|
+
public userInfoStorageKey = '__fe_user_info__';
|
|
14
14
|
|
|
15
|
-
openAiModels = [
|
|
15
|
+
public openAiModels = [
|
|
16
16
|
'gpt-4o-mini',
|
|
17
17
|
'gpt-3.5-turbo',
|
|
18
18
|
'gpt-3.5-turbo-2',
|
|
@@ -20,29 +20,29 @@ export class MockAppConfig implements EnvConfigInterface {
|
|
|
20
20
|
'gpt-4-32k'
|
|
21
21
|
];
|
|
22
22
|
|
|
23
|
-
openAiBaseUrl = '';
|
|
23
|
+
public openAiBaseUrl = '';
|
|
24
24
|
|
|
25
|
-
openAiToken = '';
|
|
25
|
+
public openAiToken = '';
|
|
26
26
|
|
|
27
|
-
openAiTokenPrefix = '';
|
|
27
|
+
public openAiTokenPrefix = '';
|
|
28
28
|
|
|
29
|
-
openAiRequireToken = true;
|
|
29
|
+
public openAiRequireToken = true;
|
|
30
30
|
|
|
31
|
-
loginUser = '';
|
|
31
|
+
public loginUser = '';
|
|
32
32
|
|
|
33
|
-
loginPassword = '';
|
|
33
|
+
public loginPassword = '';
|
|
34
34
|
|
|
35
|
-
feApiBaseUrl = '';
|
|
35
|
+
public feApiBaseUrl = '';
|
|
36
36
|
|
|
37
|
-
userApiBaseUrl = '';
|
|
37
|
+
public userApiBaseUrl = '';
|
|
38
38
|
|
|
39
|
-
aiApiBaseUrl = 'https://api.openai.com/v1';
|
|
39
|
+
public aiApiBaseUrl = 'https://api.openai.com/v1';
|
|
40
40
|
|
|
41
|
-
aiApiToken = '';
|
|
41
|
+
public aiApiToken = '';
|
|
42
42
|
|
|
43
|
-
aiApiTokenPrefix = 'Bearer';
|
|
43
|
+
public aiApiTokenPrefix = 'Bearer';
|
|
44
44
|
|
|
45
|
-
aiApiRequireToken = true;
|
|
45
|
+
public aiApiRequireToken = true;
|
|
46
46
|
|
|
47
|
-
bootHref = '';
|
|
47
|
+
public bootHref = '';
|
|
48
48
|
}
|
|
@@ -5,12 +5,12 @@ import type { AntdStaticApiInterface } from '@brain-toolkit/antd-theme-override/
|
|
|
5
5
|
export class MockDialogHandler
|
|
6
6
|
implements InteractionHubInterface, AntdStaticApiInterface
|
|
7
7
|
{
|
|
8
|
-
setMessage = vi.fn();
|
|
9
|
-
setModal = vi.fn();
|
|
10
|
-
setNotification = vi.fn();
|
|
11
|
-
success = vi.fn();
|
|
12
|
-
error = vi.fn();
|
|
13
|
-
info = vi.fn();
|
|
14
|
-
warn = vi.fn();
|
|
15
|
-
confirm = vi.fn();
|
|
8
|
+
public setMessage = vi.fn();
|
|
9
|
+
public setModal = vi.fn();
|
|
10
|
+
public setNotification = vi.fn();
|
|
11
|
+
public success = vi.fn();
|
|
12
|
+
public error = vi.fn();
|
|
13
|
+
public info = vi.fn();
|
|
14
|
+
public warn = vi.fn();
|
|
15
|
+
public confirm = vi.fn();
|
|
16
16
|
}
|
|
@@ -2,13 +2,13 @@ import { vi } from 'vitest';
|
|
|
2
2
|
import type { LoggerInterface } from '@qlover/logger';
|
|
3
3
|
|
|
4
4
|
export class MockLogger implements LoggerInterface {
|
|
5
|
-
info = vi.fn();
|
|
6
|
-
error = vi.fn();
|
|
7
|
-
debug = vi.fn();
|
|
8
|
-
warn = vi.fn();
|
|
9
|
-
trace = vi.fn();
|
|
10
|
-
log = vi.fn();
|
|
11
|
-
fatal = vi.fn();
|
|
12
|
-
addAppender = vi.fn();
|
|
13
|
-
context = vi.fn();
|
|
5
|
+
public info = vi.fn();
|
|
6
|
+
public error = vi.fn();
|
|
7
|
+
public debug = vi.fn();
|
|
8
|
+
public warn = vi.fn();
|
|
9
|
+
public trace = vi.fn();
|
|
10
|
+
public log = vi.fn();
|
|
11
|
+
public fatal = vi.fn();
|
|
12
|
+
public addAppender = vi.fn();
|
|
13
|
+
public context = vi.fn();
|
|
14
14
|
}
|
|
@@ -41,7 +41,7 @@ export function TestBootstrapsProvider({
|
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
return (
|
|
44
|
-
<IOCContext.Provider
|
|
44
|
+
<IOCContext.Provider value={IOC}>
|
|
45
45
|
<TestRouter
|
|
46
46
|
initialEntries={routerInitialEntries}
|
|
47
47
|
initialIndex={routerInitialIndex}
|
|
@@ -24,13 +24,13 @@ const resources: Record<string, Record<string, Record<string, string>>> = {
|
|
|
24
24
|
* Implements the backend interface to avoid network requests
|
|
25
25
|
*/
|
|
26
26
|
export class MockHttpBackend {
|
|
27
|
-
type = 'backend';
|
|
27
|
+
public type = 'backend';
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Initialize the backend
|
|
31
31
|
* This is called by i18next when .use() is called
|
|
32
32
|
*/
|
|
33
|
-
init(
|
|
33
|
+
public init(
|
|
34
34
|
_services: unknown,
|
|
35
35
|
_backendOptions: unknown,
|
|
36
36
|
_i18nextOptions: unknown,
|
|
@@ -60,7 +60,7 @@ export class MockHttpBackend {
|
|
|
60
60
|
* Read translation data for a language and namespace
|
|
61
61
|
* This method is called by i18next to load translations
|
|
62
62
|
*/
|
|
63
|
-
read(
|
|
63
|
+
public read(
|
|
64
64
|
language: string,
|
|
65
65
|
namespace: string,
|
|
66
66
|
callback: (error: Error | null, data?: Record<string, string>) => void
|
|
@@ -82,7 +82,7 @@ export class MockHttpBackend {
|
|
|
82
82
|
* Load URL - called by i18next-http-backend to load from URL
|
|
83
83
|
* We intercept this and return data from memory instead
|
|
84
84
|
*/
|
|
85
|
-
loadUrl(
|
|
85
|
+
public loadUrl(
|
|
86
86
|
_url: string,
|
|
87
87
|
callback: (error: Error | null, data?: Record<string, string>) => void
|
|
88
88
|
): void {
|
|
@@ -104,7 +104,7 @@ export class MockHttpBackend {
|
|
|
104
104
|
/**
|
|
105
105
|
* Create - not used in our mock
|
|
106
106
|
*/
|
|
107
|
-
create(): void {
|
|
107
|
+
public create(): void {
|
|
108
108
|
// No-op
|
|
109
109
|
}
|
|
110
110
|
}
|
|
@@ -11,22 +11,26 @@ import type {
|
|
|
11
11
|
IOCFunctionInterface
|
|
12
12
|
} from '@qlover/corekit-bridge';
|
|
13
13
|
|
|
14
|
-
export class TestIOC
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
export class TestIOC implements IOCInterface<
|
|
15
|
+
IOCIdentifierMap,
|
|
16
|
+
IOCContainerInterface
|
|
17
|
+
> {
|
|
17
18
|
protected ioc: IOCFunctionInterface<
|
|
18
19
|
IOCIdentifierMap,
|
|
19
20
|
IOCContainerInterface
|
|
20
21
|
> | null = null;
|
|
21
22
|
|
|
22
|
-
getIoc(): IOCFunctionInterface<
|
|
23
|
+
public getIoc(): IOCFunctionInterface<
|
|
23
24
|
IOCIdentifierMap,
|
|
24
25
|
IOCContainerInterface
|
|
25
26
|
> | null {
|
|
26
27
|
return this.ioc;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
/**
|
|
31
|
+
* @override
|
|
32
|
+
*/
|
|
33
|
+
public create(
|
|
30
34
|
options: IocRegisterOptions
|
|
31
35
|
): IOCFunctionInterface<IOCIdentifierMap, IOCContainerInterface> {
|
|
32
36
|
if (this.ioc) {
|
|
@@ -18,9 +18,10 @@ import type {
|
|
|
18
18
|
/**
|
|
19
19
|
* TestIOCRegister - Register mock services for testing
|
|
20
20
|
*/
|
|
21
|
-
export class TestIOCRegister
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
export class TestIOCRegister implements IOCRegisterInterface<
|
|
22
|
+
IOCContainerInterface,
|
|
23
|
+
IocRegisterOptions
|
|
24
|
+
> {
|
|
24
25
|
constructor(protected options: IocRegisterOptions) {}
|
|
25
26
|
|
|
26
27
|
protected registerGlobals(ioc: IOCContainerInterface): void {
|
|
@@ -39,7 +40,10 @@ export class TestIOCRegister
|
|
|
39
40
|
ioc.bind(I.CookieStorage, globals.cookieStorage);
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
/**
|
|
44
|
+
* @override
|
|
45
|
+
*/
|
|
46
|
+
public register(
|
|
43
47
|
ioc: IOCContainerInterface,
|
|
44
48
|
_manager: IOCManagerInterface<IOCContainerInterface>
|
|
45
49
|
): void {
|