@qlover/create-app 0.7.15 → 0.8.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.
Files changed (340) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/configs/_common/.gitignore.template +6 -0
  3. package/dist/configs/_common/.prettierignore +17 -5
  4. package/dist/configs/_common/.vscode/settings.json +6 -1
  5. package/dist/index.cjs +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/templates/next-app/.env.template +1 -1
  8. package/dist/templates/next-app/README.en.md +0 -1
  9. package/dist/templates/next-app/README.md +0 -1
  10. package/dist/templates/next-app/config/Identifier/api.ts +5 -5
  11. package/dist/templates/next-app/config/Identifier/common/admint.table.ts +69 -0
  12. package/dist/templates/next-app/config/Identifier/common/common.ts +76 -0
  13. package/dist/templates/next-app/config/Identifier/common/index.ts +3 -0
  14. package/dist/templates/next-app/config/Identifier/{validator.ts → common/validators.ts} +5 -5
  15. package/dist/templates/next-app/config/Identifier/index.ts +2 -12
  16. package/dist/templates/next-app/config/Identifier/pages/index.ts +6 -0
  17. package/dist/templates/next-app/config/Identifier/pages/page.admin.home.ts +27 -0
  18. package/dist/templates/next-app/config/Identifier/pages/page.admin.locales.ts +266 -0
  19. package/dist/templates/next-app/config/Identifier/pages/page.admin.user.ts +293 -0
  20. package/dist/templates/{react-app/config/Identifier → next-app/config/Identifier/pages}/page.home.ts +15 -22
  21. package/dist/templates/next-app/config/Identifier/{page.login.ts → pages/page.login.ts} +28 -34
  22. package/dist/templates/next-app/config/Identifier/{page.register.ts → pages/page.register.ts} +30 -29
  23. package/dist/templates/next-app/config/adminNavs.ts +19 -0
  24. package/dist/templates/next-app/config/common.ts +22 -13
  25. package/dist/templates/next-app/config/i18n/HomeI18n.ts +5 -5
  26. package/dist/templates/next-app/config/i18n/admin18n.ts +61 -19
  27. package/dist/templates/next-app/config/i18n/i18nConfig.ts +2 -0
  28. package/dist/templates/next-app/config/i18n/i18nKeyScheam.ts +36 -0
  29. package/dist/templates/next-app/config/i18n/loginI18n.ts +22 -22
  30. package/dist/templates/next-app/config/i18n/register18n.ts +23 -24
  31. package/dist/templates/next-app/docs/en/index.md +0 -1
  32. package/dist/templates/next-app/docs/en/project-structure.md +0 -1
  33. package/dist/templates/next-app/docs/zh/index.md +0 -1
  34. package/dist/templates/next-app/docs/zh/project-structure.md +0 -1
  35. package/dist/templates/next-app/make/generateLocales.ts +19 -12
  36. package/dist/templates/next-app/migrations/schema/LocalesSchema.ts +15 -0
  37. package/dist/templates/next-app/migrations/sql/1694244000000.sql +11 -0
  38. package/dist/templates/next-app/package.json +7 -3
  39. package/dist/templates/next-app/public/locales/en.json +172 -207
  40. package/dist/templates/next-app/public/locales/zh.json +172 -207
  41. package/dist/templates/next-app/src/app/[locale]/admin/locales/page.tsx +153 -0
  42. package/dist/templates/next-app/src/app/[locale]/admin/users/page.tsx +48 -50
  43. package/dist/templates/next-app/src/app/[locale]/login/LoginForm.tsx +2 -2
  44. package/dist/templates/next-app/src/app/api/admin/locales/create/route.ts +34 -0
  45. package/dist/templates/next-app/src/app/api/admin/locales/import/route.ts +40 -0
  46. package/dist/templates/next-app/src/app/api/admin/locales/route.ts +42 -0
  47. package/dist/templates/next-app/src/app/api/admin/locales/update/route.ts +32 -0
  48. package/dist/templates/next-app/src/app/api/locales/json/route.ts +44 -0
  49. package/dist/templates/next-app/src/base/cases/AdminPageManager.ts +1 -13
  50. package/dist/templates/next-app/src/base/cases/Datetime.ts +18 -0
  51. package/dist/templates/next-app/src/base/cases/DialogErrorPlugin.ts +12 -6
  52. package/dist/templates/next-app/src/base/cases/ResourceState.ts +17 -0
  53. package/dist/templates/next-app/src/base/cases/TranslateI18nInterface.ts +25 -0
  54. package/dist/templates/next-app/src/base/cases/ZodColumnBuilder.ts +200 -0
  55. package/dist/templates/next-app/src/base/port/ZodBuilderInterface.ts +8 -0
  56. package/dist/templates/next-app/src/base/services/AdminLocalesService.ts +20 -0
  57. package/dist/templates/next-app/src/base/services/AdminPageEvent.ts +26 -0
  58. package/dist/templates/next-app/src/base/services/AdminPageScheduler.ts +42 -0
  59. package/dist/templates/next-app/src/base/services/ResourceService.ts +122 -0
  60. package/dist/templates/next-app/src/base/services/adminApi/AdminLocalesApi.ts +104 -0
  61. package/dist/templates/next-app/src/base/services/adminApi/AdminUserApi.ts +38 -5
  62. package/dist/templates/next-app/src/base/services/appApi/AppApiPlugin.ts +1 -1
  63. package/dist/templates/next-app/src/i18n/request.ts +30 -1
  64. package/dist/templates/next-app/src/server/PageParams.ts +2 -10
  65. package/dist/templates/next-app/src/server/port/DBBridgeInterface.ts +5 -0
  66. package/dist/templates/next-app/src/server/port/DBTableInterface.ts +2 -0
  67. package/dist/templates/next-app/src/server/port/LocalesRepositoryInterface.ts +43 -0
  68. package/dist/templates/next-app/src/server/repositorys/LocalesRepository.ts +197 -0
  69. package/dist/templates/next-app/src/server/services/ApiLocaleService.ts +122 -0
  70. package/dist/templates/next-app/src/server/sqlBridges/SupabaseBridge.ts +60 -11
  71. package/dist/templates/next-app/src/server/validators/ExtendedExecutorError.ts +6 -0
  72. package/dist/templates/next-app/src/server/validators/LocalesValidator.ts +131 -0
  73. package/dist/templates/next-app/src/server/validators/LoginValidator.ts +2 -5
  74. package/dist/templates/next-app/src/server/validators/PaginationValidator.ts +32 -16
  75. package/dist/templates/next-app/src/styles/css/antd-themes/pagination/_default.css +2 -1
  76. package/dist/templates/next-app/src/styles/css/antd-themes/pagination/dark.css +28 -29
  77. package/dist/templates/next-app/src/styles/css/antd-themes/pagination/pink.css +2 -1
  78. package/dist/templates/next-app/src/uikit/components/AdminLayout.tsx +17 -3
  79. package/dist/templates/next-app/src/uikit/components/BaseHeader.tsx +5 -4
  80. package/dist/templates/next-app/src/uikit/components/BaseLayout.tsx +5 -4
  81. package/dist/templates/next-app/src/uikit/components/BootstrapsProvider.tsx +3 -2
  82. package/dist/templates/next-app/src/uikit/components/ComboProvider.tsx +1 -1
  83. package/dist/templates/next-app/src/uikit/components/EditableCell.tsx +118 -0
  84. package/dist/templates/next-app/src/uikit/components/LogoutButton.tsx +5 -6
  85. package/dist/templates/next-app/src/uikit/components/ThemeSwitcher.tsx +1 -1
  86. package/dist/templates/next-app/src/uikit/components/With.tsx +2 -2
  87. package/dist/templates/next-app/src/uikit/components/localesImportButton/LocalesImportButton.tsx +62 -0
  88. package/dist/templates/next-app/src/uikit/components/localesImportButton/LocalesImportEvent.ts +28 -0
  89. package/dist/templates/next-app/src/uikit/components/localesImportButton/import.module.css +6 -0
  90. package/dist/templates/next-app/src/uikit/hook/useI18nInterface.ts +8 -14
  91. package/dist/templates/next-app/src/uikit/hook/useWarnTranslations.ts +25 -0
  92. package/dist/templates/react-app/.prettierignore +17 -0
  93. package/dist/templates/react-app/README.en.md +71 -54
  94. package/dist/templates/react-app/README.md +35 -18
  95. package/dist/templates/react-app/__tests__/__mocks__/BootstrapTest.ts +14 -0
  96. package/dist/templates/react-app/__tests__/__mocks__/MockAppConfit.ts +1 -1
  97. package/dist/templates/react-app/__tests__/__mocks__/MockDialogHandler.ts +2 -2
  98. package/dist/templates/react-app/__tests__/__mocks__/MockLogger.ts +1 -1
  99. package/dist/templates/react-app/__tests__/__mocks__/components/TestApp.tsx +45 -0
  100. package/dist/templates/react-app/__tests__/__mocks__/components/TestBootstrapsProvider.tsx +34 -0
  101. package/dist/templates/react-app/__tests__/__mocks__/components/TestRouter.tsx +46 -0
  102. package/dist/templates/react-app/__tests__/__mocks__/components/index.ts +12 -0
  103. package/dist/templates/react-app/__tests__/__mocks__/createMockGlobals.ts +1 -2
  104. package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOC.ts +51 -0
  105. package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOCRegister.ts +69 -0
  106. package/dist/templates/react-app/__tests__/setup/index.ts +1 -51
  107. package/dist/templates/react-app/__tests__/setup/setupGlobal.ts +51 -0
  108. package/dist/templates/react-app/__tests__/src/App.structure.test.tsx +115 -0
  109. package/dist/templates/react-app/__tests__/src/base/cases/AppConfig.test.ts +2 -2
  110. package/dist/templates/react-app/__tests__/src/base/cases/AppError.test.ts +1 -1
  111. package/dist/templates/react-app/__tests__/src/base/cases/DialogHandler.test.ts +3 -5
  112. package/dist/templates/react-app/__tests__/src/base/cases/I18nKeyErrorPlugin.test.ts +13 -2
  113. package/dist/templates/react-app/__tests__/src/base/cases/InversifyContainer.test.ts +1 -1
  114. package/dist/templates/react-app/__tests__/src/base/cases/PublicAssetsPath.test.ts +1 -1
  115. package/dist/templates/react-app/__tests__/src/base/cases/RequestLogger.test.ts +5 -5
  116. package/dist/templates/react-app/__tests__/src/base/cases/RequestStatusCatcher.test.ts +1 -2
  117. package/dist/templates/react-app/__tests__/src/base/cases/RouterLoader.test.ts +25 -15
  118. package/dist/templates/react-app/__tests__/src/base/services/I18nService.test.ts +29 -15
  119. package/dist/templates/react-app/__tests__/src/core/IOC.test.ts +19 -9
  120. package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapClient.test.ts +153 -0
  121. package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapsApp.test.ts +9 -7
  122. package/dist/templates/react-app/__tests__/src/main.integration.test.tsx +4 -5
  123. package/dist/templates/react-app/__tests__/src/main.test.tsx +4 -4
  124. package/dist/templates/react-app/__tests__/src/uikit/components/BaseHeader.test.tsx +68 -59
  125. package/dist/templates/react-app/config/IOCIdentifier.ts +8 -8
  126. package/dist/templates/react-app/config/Identifier/{common.error.ts → common/common.error.ts} +5 -5
  127. package/dist/templates/react-app/config/Identifier/{common.ts → common/common.ts} +9 -9
  128. package/dist/templates/react-app/config/Identifier/common/index.ts +2 -0
  129. package/dist/templates/react-app/config/Identifier/index.ts +1 -9
  130. package/dist/templates/react-app/config/Identifier/pages/index.ts +8 -0
  131. package/dist/templates/react-app/config/Identifier/{page.about.ts → pages/page.about.ts} +34 -26
  132. package/dist/templates/react-app/config/Identifier/{page.executor.ts → pages/page.executor.ts} +47 -39
  133. package/dist/templates/{next-app/config/Identifier → react-app/config/Identifier/pages}/page.home.ts +24 -23
  134. package/dist/templates/react-app/config/Identifier/pages/page.identifiter.ts +102 -0
  135. package/dist/templates/react-app/config/Identifier/{page.jsonStorage.ts → pages/page.jsonStorage.ts} +18 -11
  136. package/dist/templates/react-app/config/Identifier/{page.login.ts → pages/page.login.ts} +37 -27
  137. package/dist/templates/react-app/config/Identifier/{page.register.ts → pages/page.register.ts} +37 -25
  138. package/dist/templates/react-app/config/Identifier/{page.request.ts → pages/page.request.ts} +34 -44
  139. package/dist/templates/react-app/config/app.router.ts +66 -69
  140. package/dist/templates/react-app/config/i18n/PageI18nInterface.ts +51 -0
  141. package/dist/templates/react-app/config/i18n/aboutI18n.ts +42 -0
  142. package/dist/templates/react-app/config/i18n/executorI18n.ts +51 -0
  143. package/dist/templates/react-app/config/i18n/homeI18n.ts +24 -0
  144. package/dist/templates/react-app/config/i18n/i18nConfig.ts +30 -0
  145. package/dist/templates/react-app/config/i18n/identifiter18n.ts +30 -0
  146. package/dist/templates/react-app/config/i18n/jsonStorage18n.ts +27 -0
  147. package/dist/templates/react-app/config/i18n/login18n.ts +42 -0
  148. package/dist/templates/react-app/config/i18n/notFoundI18n.ts +34 -0
  149. package/dist/templates/react-app/config/i18n/register18n.ts +40 -0
  150. package/dist/templates/react-app/config/i18n/request18n.ts +41 -0
  151. package/dist/templates/react-app/config/theme.ts +14 -4
  152. package/dist/templates/react-app/docs/en/bootstrap.md +1670 -341
  153. package/dist/templates/react-app/docs/en/development-guide.md +1021 -345
  154. package/dist/templates/react-app/docs/en/env.md +1132 -278
  155. package/dist/templates/react-app/docs/en/i18n.md +858 -147
  156. package/dist/templates/react-app/docs/en/index.md +733 -104
  157. package/dist/templates/react-app/docs/en/ioc.md +1228 -287
  158. package/dist/templates/react-app/docs/en/playwright/e2e-tests.md +321 -0
  159. package/dist/templates/react-app/docs/en/playwright/index.md +19 -0
  160. package/dist/templates/react-app/docs/en/playwright/installation-summary.md +332 -0
  161. package/dist/templates/react-app/docs/en/playwright/overview.md +222 -0
  162. package/dist/templates/react-app/docs/en/playwright/quickstart.md +325 -0
  163. package/dist/templates/react-app/docs/en/playwright/reorganization-notes.md +340 -0
  164. package/dist/templates/react-app/docs/en/playwright/setup-complete.md +290 -0
  165. package/dist/templates/react-app/docs/en/playwright/testing-guide.md +565 -0
  166. package/dist/templates/react-app/docs/en/store.md +1194 -184
  167. package/dist/templates/react-app/docs/en/why-no-globals.md +797 -0
  168. package/dist/templates/react-app/docs/zh/bootstrap.md +1670 -341
  169. package/dist/templates/react-app/docs/zh/development-guide.md +1021 -345
  170. package/dist/templates/react-app/docs/zh/env.md +1132 -275
  171. package/dist/templates/react-app/docs/zh/i18n.md +858 -147
  172. package/dist/templates/react-app/docs/zh/index.md +717 -104
  173. package/dist/templates/react-app/docs/zh/ioc.md +1229 -287
  174. package/dist/templates/react-app/docs/zh/playwright/e2e-tests.md +321 -0
  175. package/dist/templates/react-app/docs/zh/playwright/index.md +19 -0
  176. package/dist/templates/react-app/docs/zh/playwright/installation-summary.md +332 -0
  177. package/dist/templates/react-app/docs/zh/playwright/overview.md +222 -0
  178. package/dist/templates/react-app/docs/zh/playwright/quickstart.md +325 -0
  179. package/dist/templates/react-app/docs/zh/playwright/reorganization-notes.md +340 -0
  180. package/dist/templates/react-app/docs/zh/playwright/setup-complete.md +290 -0
  181. package/dist/templates/react-app/docs/zh/playwright/testing-guide.md +565 -0
  182. package/dist/templates/react-app/docs/zh/store.md +1192 -184
  183. package/dist/templates/react-app/docs/zh/why-no-globals.md +797 -0
  184. package/dist/templates/react-app/e2e/App.spec.ts +319 -0
  185. package/dist/templates/react-app/e2e/fixtures/base.fixture.ts +40 -0
  186. package/dist/templates/react-app/e2e/main.spec.ts +20 -0
  187. package/dist/templates/react-app/e2e/utils/test-helpers.ts +19 -0
  188. package/dist/templates/react-app/eslint.config.mjs +247 -0
  189. package/dist/templates/react-app/makes/eslint-utils.mjs +195 -0
  190. package/dist/templates/react-app/makes/generateTs2LocalesOptions.ts +26 -0
  191. package/dist/templates/react-app/package.json +31 -3
  192. package/dist/templates/react-app/playwright.config.ts +79 -0
  193. package/dist/templates/react-app/public/locales/en/common.json +190 -179
  194. package/dist/templates/react-app/public/locales/zh/common.json +190 -179
  195. package/dist/templates/react-app/src/App.tsx +15 -42
  196. package/dist/templates/react-app/src/base/apis/AiApi.ts +5 -5
  197. package/dist/templates/react-app/src/base/apis/feApi/FeApi.ts +1 -1
  198. package/dist/templates/react-app/src/base/apis/feApi/FeApiAdapter.ts +1 -1
  199. package/dist/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +8 -8
  200. package/dist/templates/react-app/src/base/apis/feApi/FeApiType.ts +1 -1
  201. package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +6 -6
  202. package/dist/templates/react-app/src/base/apis/userApi/UserApiAdapter.ts +1 -1
  203. package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +12 -14
  204. package/dist/templates/react-app/src/base/apis/userApi/UserApiType.ts +1 -1
  205. package/dist/templates/react-app/src/base/cases/DialogHandler.ts +5 -2
  206. package/dist/templates/react-app/src/base/cases/I18nKeyErrorPlugin.ts +3 -3
  207. package/dist/templates/react-app/src/base/cases/InversifyContainer.ts +3 -3
  208. package/dist/templates/react-app/src/base/cases/RequestLanguages.ts +2 -2
  209. package/dist/templates/react-app/src/base/cases/RequestLogger.ts +4 -4
  210. package/dist/templates/react-app/src/base/cases/RequestStatusCatcher.ts +1 -1
  211. package/dist/templates/react-app/src/base/cases/ResourceState.ts +23 -0
  212. package/dist/templates/react-app/src/base/cases/RouterLoader.ts +4 -4
  213. package/dist/templates/react-app/src/base/cases/TranslateI18nInterface.ts +26 -0
  214. package/dist/templates/react-app/src/base/port/ExecutorPageBridgeInterface.ts +2 -3
  215. package/dist/templates/react-app/src/base/port/I18nServiceInterface.ts +1 -1
  216. package/dist/templates/react-app/src/base/port/IOCInterface.ts +36 -0
  217. package/dist/templates/react-app/src/base/port/JSONStoragePageBridgeInterface.ts +2 -1
  218. package/dist/templates/react-app/src/base/port/ProcesserExecutorInterface.ts +1 -1
  219. package/dist/templates/react-app/src/base/port/RequestPageBridgeInterface.ts +2 -2
  220. package/dist/templates/react-app/src/base/port/RouteServiceInterface.ts +9 -5
  221. package/dist/templates/react-app/src/base/port/UserServiceInterface.ts +1 -1
  222. package/dist/templates/react-app/src/base/services/I18nService.ts +29 -29
  223. package/dist/templates/react-app/src/base/services/IdentifierService.ts +143 -0
  224. package/dist/templates/react-app/src/base/services/ProcesserExecutor.ts +3 -3
  225. package/dist/templates/react-app/src/base/services/RouteService.ts +27 -8
  226. package/dist/templates/react-app/src/base/services/UserService.ts +8 -8
  227. package/dist/templates/react-app/src/base/types/Page.ts +14 -2
  228. package/dist/templates/react-app/src/base/types/global.d.ts +1 -1
  229. package/dist/templates/react-app/src/core/IOC.ts +5 -46
  230. package/dist/templates/react-app/src/core/bootstraps/{BootstrapApp.ts → BootstrapClient.ts} +44 -17
  231. package/dist/templates/react-app/src/core/bootstraps/BootstrapsRegistry.ts +14 -7
  232. package/dist/templates/react-app/src/core/bootstraps/IocIdentifierTest.ts +1 -1
  233. package/dist/templates/react-app/src/core/bootstraps/PrintBootstrap.ts +1 -1
  234. package/dist/templates/react-app/src/core/clientIoc/ClientIOC.ts +40 -0
  235. package/dist/templates/react-app/src/core/{IocRegisterImpl.ts → clientIoc/ClientIOCRegister.ts} +35 -24
  236. package/dist/templates/react-app/src/core/globals.ts +9 -9
  237. package/dist/templates/react-app/src/main.tsx +4 -4
  238. package/dist/templates/react-app/src/pages/404.tsx +6 -3
  239. package/dist/templates/react-app/src/pages/500.tsx +5 -2
  240. package/dist/templates/react-app/src/pages/NoRouteFound.tsx +5 -0
  241. package/dist/templates/react-app/src/pages/auth/Layout.tsx +9 -6
  242. package/dist/templates/react-app/src/pages/auth/LoginPage.tsx +46 -56
  243. package/dist/templates/react-app/src/pages/auth/RegisterPage.tsx +46 -58
  244. package/dist/templates/react-app/src/pages/base/AboutPage.tsx +35 -40
  245. package/dist/templates/react-app/src/pages/base/ExecutorPage.tsx +51 -51
  246. package/dist/templates/react-app/src/pages/base/HomePage.tsx +14 -15
  247. package/dist/templates/react-app/src/pages/base/IdentifierPage.tsx +70 -11
  248. package/dist/templates/react-app/src/pages/base/JSONStoragePage.tsx +24 -25
  249. package/dist/templates/react-app/src/pages/base/Layout.tsx +2 -2
  250. package/dist/templates/react-app/src/pages/base/RedirectPathname.tsx +3 -2
  251. package/dist/templates/react-app/src/pages/base/RequestPage.tsx +41 -59
  252. package/dist/templates/react-app/src/styles/css/antd-themes/{_default.css → _common/_default.css} +85 -0
  253. package/dist/templates/react-app/src/styles/css/antd-themes/{dark.css → _common/dark.css} +99 -0
  254. package/dist/templates/react-app/src/styles/css/antd-themes/_common/index.css +3 -0
  255. package/dist/templates/react-app/src/styles/css/antd-themes/{pink.css → _common/pink.css} +86 -0
  256. package/dist/templates/react-app/src/styles/css/antd-themes/index.css +4 -3
  257. package/dist/templates/react-app/src/styles/css/antd-themes/menu/_default.css +108 -0
  258. package/dist/templates/react-app/src/styles/css/antd-themes/menu/dark.css +67 -0
  259. package/dist/templates/react-app/src/styles/css/antd-themes/menu/index.css +3 -0
  260. package/dist/templates/react-app/src/styles/css/antd-themes/menu/pink.css +67 -0
  261. package/dist/templates/react-app/src/styles/css/antd-themes/pagination/_default.css +34 -0
  262. package/dist/templates/react-app/src/styles/css/antd-themes/pagination/dark.css +31 -0
  263. package/dist/templates/react-app/src/styles/css/antd-themes/pagination/index.css +3 -0
  264. package/dist/templates/react-app/src/styles/css/antd-themes/pagination/pink.css +36 -0
  265. package/dist/templates/react-app/src/styles/css/antd-themes/table/_default.css +44 -0
  266. package/dist/templates/react-app/src/styles/css/antd-themes/table/dark.css +43 -0
  267. package/dist/templates/react-app/src/styles/css/antd-themes/table/index.css +3 -0
  268. package/dist/templates/react-app/src/styles/css/antd-themes/table/pink.css +43 -0
  269. package/dist/templates/react-app/src/styles/css/page.css +4 -3
  270. package/dist/templates/react-app/src/styles/css/themes/_default.css +1 -0
  271. package/dist/templates/react-app/src/styles/css/themes/dark.css +1 -0
  272. package/dist/templates/react-app/src/styles/css/themes/pink.css +1 -0
  273. package/dist/templates/react-app/src/styles/css/zIndex.css +1 -1
  274. package/dist/templates/react-app/src/uikit/bridges/ExecutorPageBridge.ts +3 -3
  275. package/dist/templates/react-app/src/uikit/bridges/JSONStoragePageBridge.ts +2 -2
  276. package/dist/templates/react-app/src/uikit/bridges/NavigateBridge.ts +1 -1
  277. package/dist/templates/react-app/src/uikit/bridges/RequestPageBridge.ts +3 -3
  278. package/dist/templates/react-app/src/uikit/components/AppRouterProvider.tsx +35 -0
  279. package/dist/templates/react-app/src/uikit/components/BaseHeader.tsx +15 -11
  280. package/dist/templates/react-app/src/uikit/components/BaseRouteProvider.tsx +14 -11
  281. package/dist/templates/react-app/src/uikit/components/BaseRouteSeo.tsx +18 -0
  282. package/dist/templates/react-app/src/uikit/components/BootstrapsProvider.tsx +13 -0
  283. package/dist/templates/react-app/src/uikit/components/ClientSeo.tsx +62 -0
  284. package/dist/templates/react-app/src/uikit/components/ComboProvider.tsx +38 -0
  285. package/dist/templates/react-app/src/uikit/components/LanguageSwitcher.tsx +48 -27
  286. package/dist/templates/react-app/src/uikit/components/Loading.tsx +4 -2
  287. package/dist/templates/react-app/src/uikit/components/LocaleLink.tsx +4 -5
  288. package/dist/templates/react-app/src/uikit/components/LogoutButton.tsx +34 -11
  289. package/dist/templates/react-app/src/uikit/components/ProcessExecutorProvider.tsx +9 -5
  290. package/dist/templates/react-app/src/uikit/components/RouterRenderComponent.tsx +6 -3
  291. package/dist/templates/react-app/src/uikit/components/ThemeSwitcher.tsx +97 -40
  292. package/dist/templates/react-app/src/uikit/components/UserAuthProvider.tsx +5 -5
  293. package/dist/templates/react-app/src/uikit/components/With.tsx +17 -0
  294. package/dist/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +17 -11
  295. package/dist/templates/react-app/src/uikit/contexts/IOCContext.ts +13 -0
  296. package/dist/templates/react-app/src/uikit/hooks/useAppTranslation.ts +26 -0
  297. package/dist/templates/react-app/src/uikit/hooks/useI18nGuard.ts +8 -11
  298. package/dist/templates/react-app/src/uikit/hooks/useI18nInterface.ts +25 -0
  299. package/dist/templates/react-app/src/uikit/hooks/useIOC.ts +35 -0
  300. package/dist/templates/react-app/src/uikit/hooks/useNavigateBridge.ts +3 -3
  301. package/dist/templates/react-app/src/uikit/hooks/useStrictEffect.ts +0 -1
  302. package/dist/templates/react-app/tsconfig.e2e.json +21 -0
  303. package/dist/templates/react-app/tsconfig.json +8 -1
  304. package/dist/templates/react-app/tsconfig.node.json +1 -1
  305. package/dist/templates/react-app/tsconfig.test.json +3 -1
  306. package/dist/templates/react-app/vite.config.ts +50 -34
  307. package/package.json +2 -1
  308. package/dist/configs/react-app/eslint.config.js +0 -94
  309. package/dist/templates/next-app/config/Identifier/common.error.ts +0 -41
  310. package/dist/templates/next-app/config/Identifier/common.ts +0 -69
  311. package/dist/templates/next-app/config/Identifier/page.about.ts +0 -181
  312. package/dist/templates/next-app/config/Identifier/page.admin.ts +0 -48
  313. package/dist/templates/next-app/config/Identifier/page.executor.ts +0 -272
  314. package/dist/templates/next-app/config/Identifier/page.identifiter.ts +0 -39
  315. package/dist/templates/next-app/config/Identifier/page.jsonStorage.ts +0 -72
  316. package/dist/templates/next-app/config/Identifier/page.request.ts +0 -182
  317. package/dist/templates/next-app/src/base/cases/ChatAction.ts +0 -21
  318. package/dist/templates/next-app/src/base/cases/FocusBarAction.ts +0 -36
  319. package/dist/templates/next-app/src/base/cases/RequestState.ts +0 -20
  320. package/dist/templates/next-app/src/base/port/AdminPageInterface.ts +0 -85
  321. package/dist/templates/next-app/src/base/port/AsyncStateInterface.ts +0 -7
  322. package/dist/templates/next-app/src/base/services/AdminUserService.ts +0 -45
  323. package/dist/templates/next-app/src/uikit/components/ChatRoot.tsx +0 -17
  324. package/dist/templates/next-app/src/uikit/components/chat/ChatActionInterface.ts +0 -30
  325. package/dist/templates/next-app/src/uikit/components/chat/ChatFocusBar.tsx +0 -65
  326. package/dist/templates/next-app/src/uikit/components/chat/ChatMessages.tsx +0 -59
  327. package/dist/templates/next-app/src/uikit/components/chat/ChatWrap.tsx +0 -28
  328. package/dist/templates/next-app/src/uikit/components/chat/FocusBarActionInterface.ts +0 -19
  329. package/dist/templates/next-app/src/uikit/hook/useMountedClient.ts +0 -17
  330. package/dist/templates/next-app/src/uikit/hook/useStore.ts +0 -15
  331. package/dist/templates/react-app/__tests__/__mocks__/I18nService.ts +0 -13
  332. package/dist/templates/react-app/__tests__/src/App.test.tsx +0 -139
  333. package/dist/templates/react-app/config/Identifier/page.identifiter.ts +0 -39
  334. package/dist/templates/react-app/config/i18n.ts +0 -15
  335. package/dist/templates/react-app/docs/en/project-structure.md +0 -434
  336. package/dist/templates/react-app/docs/zh/project-structure.md +0 -434
  337. package/dist/templates/react-app/src/base/cases/RequestState.ts +0 -20
  338. package/dist/templates/react-app/src/base/port/AsyncStateInterface.ts +0 -7
  339. package/dist/templates/react-app/src/uikit/hooks/useDocumentTitle.ts +0 -15
  340. package/dist/templates/react-app/src/uikit/hooks/useStore.ts +0 -15
@@ -1,51 +1 @@
1
- import { createMockGlobals } from '../__mocks__/createMockGlobals';
2
-
3
- // 设置测试环境
4
- beforeEach(() => {
5
- // 清理DOM
6
- document.body.innerHTML = '';
7
-
8
- // 创建root元素(如果不存在)
9
- if (!document.getElementById('root')) {
10
- const rootElement = document.createElement('div');
11
- rootElement.id = 'root';
12
- document.body.appendChild(rootElement);
13
- }
14
- });
15
-
16
- afterEach(() => {
17
- // 清理所有mock
18
- vi.clearAllMocks();
19
- });
20
-
21
- // 全局测试配置
22
- global.ResizeObserver = vi.fn().mockImplementation(() => ({
23
- observe: vi.fn(),
24
- unobserve: vi.fn(),
25
- disconnect: vi.fn()
26
- }));
27
-
28
- // Mock window.matchMedia
29
- Object.defineProperty(window, 'matchMedia', {
30
- writable: true,
31
- value: vi.fn().mockImplementation((query) => ({
32
- matches: false,
33
- media: query,
34
- onchange: null,
35
- addListener: vi.fn(), // deprecated
36
- removeListener: vi.fn(), // deprecated
37
- addEventListener: vi.fn(),
38
- removeEventListener: vi.fn(),
39
- dispatchEvent: vi.fn()
40
- }))
41
- });
42
-
43
- // Mock IntersectionObserver
44
- global.IntersectionObserver = vi.fn().mockImplementation(() => ({
45
- observe: vi.fn(),
46
- unobserve: vi.fn(),
47
- disconnect: vi.fn()
48
- }));
49
-
50
- // Mock globals
51
- vi.mock('@/core/globals', () => createMockGlobals());
1
+ import './setupGlobal';
@@ -0,0 +1,51 @@
1
+ import { createMockGlobals } from '__tests__/__mocks__/createMockGlobals';
2
+
3
+ // 设置测试环境
4
+ beforeEach(() => {
5
+ // 清理DOM
6
+ document.body.innerHTML = '';
7
+
8
+ // 创建root元素(如果不存在)
9
+ if (!document.getElementById('root')) {
10
+ const rootElement = document.createElement('div');
11
+ rootElement.id = 'root';
12
+ document.body.appendChild(rootElement);
13
+ }
14
+ });
15
+
16
+ afterEach(() => {
17
+ // 清理所有mock
18
+ vi.clearAllMocks();
19
+ });
20
+
21
+ // 全局测试配置
22
+ global.ResizeObserver = vi.fn().mockImplementation(() => ({
23
+ observe: vi.fn(),
24
+ unobserve: vi.fn(),
25
+ disconnect: vi.fn()
26
+ }));
27
+
28
+ // Mock window.matchMedia
29
+ Object.defineProperty(window, 'matchMedia', {
30
+ writable: true,
31
+ value: vi.fn().mockImplementation((query) => ({
32
+ matches: false,
33
+ media: query,
34
+ onchange: null,
35
+ addListener: vi.fn(), // deprecated
36
+ removeListener: vi.fn(), // deprecated
37
+ addEventListener: vi.fn(),
38
+ removeEventListener: vi.fn(),
39
+ dispatchEvent: vi.fn()
40
+ }))
41
+ });
42
+
43
+ // Mock IntersectionObserver
44
+ global.IntersectionObserver = vi.fn().mockImplementation(() => ({
45
+ observe: vi.fn(),
46
+ unobserve: vi.fn(),
47
+ disconnect: vi.fn()
48
+ }));
49
+
50
+ // Mock globals
51
+ vi.mock('@/core/globals', () => createMockGlobals());
@@ -0,0 +1,115 @@
1
+ import { routerPrefix } from '@config/common';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { testIOC } from '__tests__/__mocks__/testIOC/TestIOC';
4
+ import { describe, it, expect, vi, beforeAll } from 'vitest';
5
+ import App from '@/App';
6
+ import { BootstrapClient } from '@/core/bootstraps/BootstrapClient';
7
+
8
+ // Mock CSS imports
9
+ vi.mock('@/styles/css/index.css', () => ({}));
10
+
11
+ // Mock RouterProvider
12
+ vi.mock('react-router-dom', () => ({
13
+ createBrowserRouter: vi.fn((routes, options) => ({
14
+ routes,
15
+ basename: options?.basename
16
+ })),
17
+ RouterProvider: ({ router }: any) => (
18
+ <div data-testid="router-provider">
19
+ <div data-testid="router-basename">{router?.basename}</div>
20
+ <div data-testid="router-routes-count">{router?.routes?.length || 0}</div>
21
+ </div>
22
+ ),
23
+ useNavigate: () => vi.fn()
24
+ }));
25
+
26
+ // Mock AntdThemeProvider
27
+ vi.mock('@brain-toolkit/antd-theme-override/react', () => ({
28
+ AntdThemeProvider: ({ children, theme }: any) => (
29
+ <div data-testid="antd-theme-provider">
30
+ <div data-testid="theme-key">{theme?.cssVar?.key}</div>
31
+ <div data-testid="theme-prefix">{theme?.cssVar?.prefix}</div>
32
+ {children}
33
+ </div>
34
+ )
35
+ }));
36
+
37
+ // Mock react-kit
38
+ vi.mock('@brain-toolkit/react-kit', () => ({
39
+ useMountedClient: () => true,
40
+ useStore: (_service: any, selector?: any) => {
41
+ if (selector) {
42
+ return [
43
+ { path: '/', component: 'HomePage' },
44
+ { path: '/about', component: 'AboutPage' }
45
+ ];
46
+ }
47
+ return [];
48
+ }
49
+ }));
50
+
51
+ // Mock ComboProvider - force children to render
52
+ vi.mock('@/uikit/components/ComboProvider', () => ({
53
+ ComboProvider: ({ children }: any) => children
54
+ }));
55
+
56
+ // Mock AppRouterProvider - return our mocked router structure
57
+ vi.mock('@/uikit/components/AppRouterProvider', () => ({
58
+ AppRouterProvider: () => (
59
+ <div data-testid="router-provider">
60
+ <div data-testid="router-basename">{routerPrefix}</div>
61
+ <div data-testid="router-routes-count">0</div>
62
+ </div>
63
+ )
64
+ }));
65
+
66
+ // Import App after all mocks
67
+ import { ClientIOCRegister } from '@/core/clientIoc/ClientIOCRegister';
68
+ import { appConfig } from '@/core/globals';
69
+
70
+ describe('App Component with IOC Initialization', () => {
71
+ beforeAll(async () => {
72
+ /**
73
+ * Initialize IOC container with BootstrapClient.main()
74
+ * This is essential to register all services including DialogHandler
75
+ *
76
+ * Without this initialization, you'll get:
77
+ * "No bindings found for service: DialogHandler"
78
+ */
79
+ await BootstrapClient.main({
80
+ root: globalThis,
81
+ bootHref: 'http://localhost:3000',
82
+ ioc: testIOC,
83
+ iocRegister: new ClientIOCRegister({
84
+ pathname: '/',
85
+ appConfig: appConfig
86
+ })
87
+ });
88
+ });
89
+
90
+ it('should render without crashing', () => {
91
+ const { container } = render(<App />);
92
+ expect(container).toBeDefined();
93
+ });
94
+
95
+ it('should initialize and render the app structure', () => {
96
+ render(<App />);
97
+
98
+ // App should render successfully after IOC initialization
99
+ const routerProvider = screen.getByTestId('router-provider');
100
+ expect(routerProvider).toBeDefined();
101
+ });
102
+
103
+ it('should configure router with correct basename', () => {
104
+ render(<App />);
105
+
106
+ const routerBasename = screen.getByTestId('router-basename');
107
+ expect(routerBasename.textContent).toBe(routerPrefix);
108
+ });
109
+
110
+ it('should render without DialogHandler binding errors', () => {
111
+ // This test verifies that BootstrapClient.main() correctly initialized the IOC container
112
+ // If DialogHandler was not registered, this would throw an error
113
+ expect(() => render(<App />)).not.toThrow();
114
+ });
115
+ });
@@ -12,10 +12,10 @@
12
12
  * 8. Configuration validation
13
13
  */
14
14
 
15
+ import { envBlackList, envPrefix } from '@config/common';
16
+ import { InjectEnv } from '@qlover/corekit-bridge';
15
17
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
16
18
  import { AppConfig } from '@/base/cases/AppConfig';
17
- import { InjectEnv } from '@qlover/corekit-bridge';
18
- import { envBlackList, envPrefix } from '@config/common';
19
19
 
20
20
  // Mock import.meta.env
21
21
  const mockImportMetaEnv = {
@@ -7,9 +7,9 @@
7
7
  * 3. error properties - Verify error properties are set correctly
8
8
  */
9
9
 
10
+ import { ExecutorError } from '@qlover/fe-corekit';
10
11
  import { describe, it, expect } from 'vitest';
11
12
  import { AppError } from '@/base/cases/AppError';
12
- import { ExecutorError } from '@qlover/fe-corekit';
13
13
 
14
14
  describe('AppError', () => {
15
15
  describe('constructor', () => {
@@ -1,4 +1,3 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
1
  /**
3
2
  * DialogHandler test suite
4
3
  *
@@ -12,13 +11,12 @@
12
11
  */
13
12
 
14
13
  import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
15
- import { DialogHandler } from '../../../../src/base/cases/DialogHandler';
14
+ import { DialogHandler } from '@/base/cases/DialogHandler';
16
15
  import type {
17
16
  MessageApi,
18
17
  ModalApi,
19
18
  NotificationApi
20
19
  } from '@brain-toolkit/antd-theme-override/react';
21
- import type { ConfirmOptions } from '../../../../src/base/port/InteractionHubInterface';
22
20
 
23
21
  describe('DialogHandler', () => {
24
22
  let dialogHandler: DialogHandler;
@@ -192,7 +190,7 @@ describe('DialogHandler', () => {
192
190
  });
193
191
 
194
192
  it('should call modal.confirm with options', () => {
195
- const options: ConfirmOptions = {
193
+ const options = {
196
194
  title: 'Confirm',
197
195
  content: 'Are you sure?',
198
196
  onOk: vi.fn(),
@@ -212,7 +210,7 @@ describe('DialogHandler', () => {
212
210
  });
213
211
 
214
212
  it('should handle undefined modal api', () => {
215
- const options: ConfirmOptions = {
213
+ const options = {
216
214
  title: 'test',
217
215
  content: 'test content'
218
216
  };
@@ -8,12 +8,23 @@
8
8
  * 4. edge cases - Various error scenarios
9
9
  */
10
10
 
11
+ import { MockLogger } from '@__mocks__/MockLogger';
11
12
  import { describe, it, expect, beforeEach } from 'vitest';
12
13
  import { I18nKeyErrorPlugin } from '@/base/cases/I18nKeyErrorPlugin';
13
- import { MockLogger } from '../../../__mocks__/MockLogger';
14
- import { MockI18nService } from '../../../__mocks__/I18nService';
14
+ import { I18nService } from '@/base/services/I18nService';
15
15
  import type { ExecutorContext } from '@qlover/fe-corekit';
16
16
 
17
+ class MockI18nService extends I18nService {
18
+ constructor() {
19
+ super('/');
20
+ }
21
+
22
+ t = vi.fn((key: string) => key);
23
+ changeLanguage = vi.fn();
24
+ changeLoading = vi.fn();
25
+ onBefore = vi.fn();
26
+ }
27
+
17
28
  describe('I18nKeyErrorPlugin', () => {
18
29
  let plugin: I18nKeyErrorPlugin;
19
30
  let mockLogger: MockLogger;
@@ -10,8 +10,8 @@
10
10
  * 6. error handling - Error cases and boundary tests
11
11
  */
12
12
 
13
- import { InversifyContainer } from '@/base/cases/InversifyContainer';
14
13
  import { injectable } from 'inversify';
14
+ import { InversifyContainer } from '@/base/cases/InversifyContainer';
15
15
 
16
16
  describe('InversifyContainer', () => {
17
17
  let container: InversifyContainer;
@@ -6,9 +6,9 @@
6
6
  * 2. getPath - Simple path concatenation with prefix
7
7
  */
8
8
 
9
+ import { routerPrefix } from '@config/common';
9
10
  import { describe, it, expect } from 'vitest';
10
11
  import { PublicAssetsPath } from '@/base/cases/PublicAssetsPath';
11
- import { routerPrefix } from '@config/common';
12
12
 
13
13
  describe('PublicAssetsPath', () => {
14
14
  describe('constructor', () => {
@@ -9,18 +9,18 @@
9
9
  * 5. loggerError - Error formatting and logging
10
10
  */
11
11
 
12
+ import { MockLogger } from '@__mocks__/MockLogger';
12
13
  import { describe, it, expect, beforeEach, vi } from 'vitest';
13
14
  import { RequestLogger } from '@/base/cases/RequestLogger';
14
- import { MockLogger } from '../../../__mocks__/MockLogger';
15
+ import type {
16
+ ApiCatchPluginConfig,
17
+ ApiCatchPluginResponse
18
+ } from '@qlover/corekit-bridge';
15
19
  import type {
16
20
  ExecutorContext,
17
21
  RequestAdapterFetchConfig,
18
22
  RequestAdapterResponse
19
23
  } from '@qlover/fe-corekit';
20
- import type {
21
- ApiCatchPluginConfig,
22
- ApiCatchPluginResponse
23
- } from '@qlover/corekit-bridge';
24
24
 
25
25
  describe('RequestLogger', () => {
26
26
  let logger: MockLogger;
@@ -1,4 +1,3 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
1
  /**
3
2
  * RequestStatusCatcher test suite
4
3
  *
@@ -9,9 +8,9 @@
9
8
  * 4. case200 - Success case handling
10
9
  */
11
10
 
11
+ import { MockLogger } from '@__mocks__/MockLogger';
12
12
  import { describe, it, expect, beforeEach } from 'vitest';
13
13
  import { RequestStatusCatcher } from '@/base/cases/RequestStatusCatcher';
14
- import { MockLogger } from '../../../__mocks__/MockLogger';
15
14
  import type { RequestAdapterResponse } from '@qlover/fe-corekit';
16
15
 
17
16
  describe('RequestStatusCatcher', () => {
@@ -1,4 +1,3 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
1
  /**
3
2
  * RouterLoader test suite
4
3
  *
@@ -10,13 +9,13 @@
10
9
  * 5. error handling - Invalid configurations
11
10
  */
12
11
 
12
+ import { createElement } from 'react';
13
13
  import { describe, it, expect, beforeEach, vi } from 'vitest';
14
14
  import { RouterLoader } from '@/base/cases/RouterLoader';
15
15
  import type {
16
16
  RouteConfigValue,
17
17
  RouterLoaderOptions
18
18
  } from '@/base/cases/RouterLoader';
19
- import { createElement } from 'react';
20
19
 
21
20
  describe('RouterLoader', () => {
22
21
  // Mock components and render function
@@ -29,9 +28,19 @@ describe('RouterLoader', () => {
29
28
  createElement('div', null, route.element())
30
29
  );
31
30
 
31
+ let mockLogger: any;
32
32
  let defaultOptions: RouterLoaderOptions;
33
33
 
34
34
  beforeEach(() => {
35
+ vi.clearAllMocks();
36
+
37
+ mockLogger = {
38
+ warn: vi.fn(),
39
+ error: vi.fn(),
40
+ info: vi.fn(),
41
+ debug: vi.fn()
42
+ };
43
+
35
44
  defaultOptions = {
36
45
  routes: [
37
46
  {
@@ -50,10 +59,9 @@ describe('RouterLoader', () => {
50
59
  About: mockAboutComponent,
51
60
  '404': mockNotFoundComponent
52
61
  },
53
- render: mockRender
62
+ render: mockRender,
63
+ logger: mockLogger
54
64
  };
55
-
56
- vi.clearAllMocks();
57
65
  });
58
66
 
59
67
  describe('constructor', () => {
@@ -68,6 +76,13 @@ describe('RouterLoader', () => {
68
76
  'RouterLoader render is required'
69
77
  );
70
78
  });
79
+
80
+ it('should accept logger in options', () => {
81
+ const loader = new RouterLoader(defaultOptions);
82
+ expect(loader).toBeInstanceOf(RouterLoader);
83
+ // Logger should be accessible through protected options
84
+ expect((loader as any).options.logger).toBe(mockLogger);
85
+ });
71
86
  });
72
87
 
73
88
  describe('getComponentMaps', () => {
@@ -110,15 +125,14 @@ describe('RouterLoader', () => {
110
125
 
111
126
  describe('toRoute', () => {
112
127
  let loader: RouterLoader;
113
- let consoleWarnSpy: any;
114
128
 
115
129
  beforeEach(() => {
116
130
  loader = new RouterLoader(defaultOptions);
117
- consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
118
131
  });
119
132
 
120
- afterEach(() => {
121
- consoleWarnSpy.mockRestore();
133
+ it('should have logger configured', () => {
134
+ expect(mockLogger).toBeDefined();
135
+ expect(mockLogger.warn).toBeDefined();
122
136
  });
123
137
 
124
138
  it('should transform route configuration correctly', () => {
@@ -161,7 +175,7 @@ describe('RouterLoader', () => {
161
175
 
162
176
  const result = loader.toRoute(route);
163
177
 
164
- expect(consoleWarnSpy).toHaveBeenCalledWith(
178
+ expect(mockLogger.warn).toHaveBeenCalledWith(
165
179
  'Invalid route, path is: /invalid, element is: undefined'
166
180
  );
167
181
  expect(result.element).toBeTruthy();
@@ -221,15 +235,11 @@ describe('RouterLoader', () => {
221
235
  path: '/invalid'
222
236
  } as RouteConfigValue;
223
237
 
224
- const consoleWarnSpy = vi
225
- .spyOn(console, 'warn')
226
- .mockImplementation(() => {});
227
238
  loader.toRoute(invalidRoute);
228
239
 
229
- expect(consoleWarnSpy).toHaveBeenCalledWith(
240
+ expect(mockLogger.warn).toHaveBeenCalledWith(
230
241
  'Invalid route, path is: /invalid, element is: undefined'
231
242
  );
232
- consoleWarnSpy.mockRestore();
233
243
  });
234
244
  });
235
245
  });
@@ -1,19 +1,20 @@
1
+ /* eslint-disable import/no-named-as-default-member */
1
2
  /**
2
3
  * I18nService test suite
3
4
  *
4
5
  * Coverage:
5
- * 1. constructor - State initialization
6
- * 2. onBefore - Plugin initialization
7
- * 3. changeLanguage - Language switching
8
- * 4. changeLoading - Loading state management
9
- * 5. static methods - Language validation and retrieval
10
- * 6. translation - Key translation with parameters
6
+ * 1. constructor - State initialization
7
+ * 2. onBefore - Plugin initialization
8
+ * 3. changeLanguage - Language switching
9
+ * 4. changeLoading - Loading state management
10
+ * 5. language methods - Language validation and retrieval
11
+ * 6. translation - Key translation with parameters
11
12
  */
12
13
 
14
+ import { i18nConfig } from '@config/i18n/i18nConfig';
15
+ import i18n from 'i18next';
13
16
  import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
14
17
  import { I18nService, I18nServiceState } from '@/base/services/I18nService';
15
- import i18n from 'i18next';
16
- import i18nConfig from '@config/i18n';
17
18
 
18
19
  const { supportedLngs, fallbackLng } = i18nConfig;
19
20
 
@@ -29,7 +30,8 @@ vi.mock('i18next', () => ({
29
30
  languageDetector: {
30
31
  addDetector: vi.fn()
31
32
  }
32
- }
33
+ },
34
+ on: vi.fn()
33
35
  }
34
36
  }));
35
37
 
@@ -100,8 +102,7 @@ describe('I18nService', () => {
100
102
  expect(i18n.services.languageDetector.addDetector).toHaveBeenCalledWith(
101
103
  expect.objectContaining({
102
104
  name: 'pathLanguageDetector',
103
- lookup: expect.any(Function),
104
- cacheUserLanguage: expect.any(Function)
105
+ lookup: expect.any(Function)
105
106
  })
106
107
  );
107
108
  });
@@ -160,22 +161,35 @@ describe('I18nService', () => {
160
161
  });
161
162
  });
162
163
 
163
- describe('static methods', () => {
164
+ describe('language methods', () => {
164
165
  describe('getCurrentLanguage', () => {
165
166
  it('should return current i18n language', () => {
166
- expect(I18nService.getCurrentLanguage()).toBe('en');
167
+ expect(service.getCurrentLanguage()).toBe('en');
167
168
  });
168
169
  });
169
170
 
170
171
  describe('isValidLanguage', () => {
171
172
  it('should validate supported languages', () => {
172
173
  for (const lang of supportedLngs) {
173
- expect(I18nService.isValidLanguage(lang)).toBe(true);
174
+ expect(service.isValidLanguage(lang)).toBe(true);
174
175
  }
175
176
  });
176
177
 
177
178
  it('should reject unsupported languages', () => {
178
- expect(I18nService.isValidLanguage('invalid')).toBe(false);
179
+ expect(service.isValidLanguage('invalid')).toBe(false);
180
+ });
181
+ });
182
+
183
+ describe('getSupportedLanguages', () => {
184
+ it('should return all supported languages', () => {
185
+ const languages = service.getSupportedLanguages();
186
+ expect(languages).toEqual(supportedLngs);
187
+ });
188
+
189
+ it('should return a copy of supported languages array', () => {
190
+ const languages1 = service.getSupportedLanguages();
191
+ const languages2 = service.getSupportedLanguages();
192
+ expect(languages1).not.toBe(languages2);
179
193
  });
180
194
  });
181
195
  });
@@ -1,11 +1,11 @@
1
- import { IOC, type IOCContainer } from '@/core/IOC';
2
- import { InversifyContainer } from '@/base/cases/InversifyContainer';
3
- import { IocRegisterImpl } from '@/core/IocRegisterImpl';
4
1
  import { IOCIdentifier } from '@config/IOCIdentifier';
5
2
  import type { AppConfig } from '@/base/cases/AppConfig';
3
+ import { InversifyContainer } from '@/base/cases/InversifyContainer';
4
+ import { ClientIOCRegister } from '@/core/clientIoc/ClientIOCRegister';
5
+ import { IOC } from '@/core/IOC';
6
6
 
7
7
  describe('IOC Container Tests', () => {
8
- let container: IOCContainer;
8
+ let container: InversifyContainer;
9
9
  let mockAppConfig: AppConfig;
10
10
 
11
11
  beforeEach(() => {
@@ -73,10 +73,20 @@ describe('IOC Container Tests', () => {
73
73
  // This test verifies that IOC function can be called with string identifiers
74
74
  // The function should accept the identifier, but will throw if service is not bound
75
75
  expect(() => {
76
- IOC(IOCIdentifier.Logger);
76
+ IOC('NonExistentService' as any);
77
77
  }).toThrow();
78
78
  });
79
79
 
80
+ it('should get registered services successfully', () => {
81
+ // Logger is registered during IOC initialization
82
+ expect(() => {
83
+ IOC(IOCIdentifier.Logger);
84
+ }).not.toThrow();
85
+
86
+ const logger = IOC(IOCIdentifier.Logger);
87
+ expect(logger).toBeDefined();
88
+ });
89
+
80
90
  it('should accept class constructors', () => {
81
91
  // Mock class for testing
82
92
  class TestService {
@@ -90,17 +100,17 @@ describe('IOC Container Tests', () => {
90
100
  });
91
101
 
92
102
  describe('IocRegisterImpl', () => {
93
- let registerImpl: IocRegisterImpl;
103
+ let registerImpl: ClientIOCRegister;
94
104
 
95
105
  beforeEach(() => {
96
- registerImpl = new IocRegisterImpl({
106
+ registerImpl = new ClientIOCRegister({
97
107
  pathname: '/test',
98
108
  appConfig: mockAppConfig
99
109
  });
100
110
  });
101
111
 
102
112
  it('should create register implementation correctly', () => {
103
- expect(registerImpl).toBeInstanceOf(IocRegisterImpl);
113
+ expect(registerImpl).toBeInstanceOf(ClientIOCRegister);
104
114
  });
105
115
 
106
116
  it('should register services without throwing', () => {
@@ -132,7 +142,7 @@ describe('IOC Container Tests', () => {
132
142
 
133
143
  describe('Service Registration Integration', () => {
134
144
  it('should register global services correctly', async () => {
135
- const registerImpl = new IocRegisterImpl({
145
+ const registerImpl = new ClientIOCRegister({
136
146
  pathname: '/test',
137
147
  appConfig: mockAppConfig
138
148
  });