@qlover/create-app 0.7.5 → 0.7.7

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 (166) hide show
  1. package/CHANGELOG.md +257 -0
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/templates/next-app/.env.template +22 -0
  5. package/dist/templates/next-app/.prettierignore +58 -0
  6. package/dist/templates/next-app/README.md +36 -0
  7. package/dist/templates/next-app/build/generateLocales.ts +25 -0
  8. package/dist/templates/next-app/config/IOCIdentifier.ts +45 -0
  9. package/dist/templates/next-app/config/Identifier/common.error.ts +34 -0
  10. package/dist/templates/next-app/config/Identifier/common.ts +62 -0
  11. package/dist/templates/next-app/config/Identifier/index.ts +10 -0
  12. package/dist/templates/next-app/config/Identifier/page.about.ts +181 -0
  13. package/dist/templates/next-app/config/Identifier/page.executor.ts +272 -0
  14. package/dist/templates/next-app/config/Identifier/page.home.ts +63 -0
  15. package/dist/templates/next-app/config/Identifier/page.identifiter.ts +39 -0
  16. package/dist/templates/next-app/config/Identifier/page.jsonStorage.ts +72 -0
  17. package/dist/templates/next-app/config/Identifier/page.login.ts +165 -0
  18. package/dist/templates/next-app/config/Identifier/page.register.ts +147 -0
  19. package/dist/templates/next-app/config/Identifier/page.request.ts +182 -0
  20. package/dist/templates/next-app/config/common.ts +34 -0
  21. package/dist/templates/next-app/config/i18n/PageI18nInterface.ts +51 -0
  22. package/dist/templates/next-app/config/i18n/i18nConfig.ts +12 -0
  23. package/dist/templates/next-app/config/i18n/index.ts +3 -0
  24. package/dist/templates/next-app/config/i18n/loginI18n.ts +42 -0
  25. package/dist/templates/next-app/config/theme.ts +23 -0
  26. package/dist/templates/next-app/docs/env.md +94 -0
  27. package/dist/templates/next-app/eslint.config.mjs +181 -0
  28. package/dist/templates/next-app/next.config.ts +21 -0
  29. package/dist/templates/next-app/package.json +58 -0
  30. package/dist/templates/next-app/plugins/eslint-plugin-testid.mjs +94 -0
  31. package/dist/templates/next-app/plugins/generateLocalesPlugin.ts +33 -0
  32. package/dist/templates/next-app/postcss.config.mjs +5 -0
  33. package/dist/templates/next-app/public/file.svg +1 -0
  34. package/dist/templates/next-app/public/globe.svg +1 -0
  35. package/dist/templates/next-app/public/locales/en/common.json +183 -0
  36. package/dist/templates/next-app/public/locales/zh/common.json +183 -0
  37. package/dist/templates/next-app/public/next.svg +1 -0
  38. package/dist/templates/next-app/public/vercel.svg +1 -0
  39. package/dist/templates/next-app/public/window.svg +1 -0
  40. package/dist/templates/next-app/src/app/[locale]/favicon.ico +0 -0
  41. package/dist/templates/next-app/src/app/[locale]/layout.tsx +44 -0
  42. package/dist/templates/next-app/src/app/[locale]/login/FeatureItem.tsx +13 -0
  43. package/dist/templates/next-app/src/app/[locale]/login/LoginForm.tsx +115 -0
  44. package/dist/templates/next-app/src/app/[locale]/login/page.tsx +73 -0
  45. package/dist/templates/next-app/src/app/[locale]/not-found.tsx +24 -0
  46. package/dist/templates/next-app/src/app/[locale]/page.tsx +106 -0
  47. package/dist/templates/next-app/src/base/cases/AppConfig.ts +15 -0
  48. package/dist/templates/next-app/src/base/cases/InversifyContainer.ts +33 -0
  49. package/dist/templates/next-app/src/base/port/I18nServiceInterface.ts +25 -0
  50. package/dist/templates/next-app/src/base/port/UserServiceInterface.ts +11 -0
  51. package/dist/templates/next-app/src/base/services/I18nService.ts +115 -0
  52. package/dist/templates/next-app/src/base/services/UserService.ts +23 -0
  53. package/dist/templates/next-app/src/core/IOC.ts +58 -0
  54. package/dist/templates/next-app/src/core/IocRegisterImpl.ts +100 -0
  55. package/dist/templates/next-app/src/core/bootstraps/BootstrapClient.ts +98 -0
  56. package/dist/templates/next-app/src/core/bootstraps/BootstrapsRegistry.ts +47 -0
  57. package/dist/templates/next-app/src/core/bootstraps/IocIdentifierTest.ts +26 -0
  58. package/dist/templates/next-app/src/core/bootstraps/PrintBootstrap.ts +18 -0
  59. package/dist/templates/next-app/src/core/globals.ts +21 -0
  60. package/dist/templates/next-app/src/i18n/request.ts +22 -0
  61. package/dist/templates/next-app/src/i18n/routing.ts +30 -0
  62. package/dist/templates/next-app/src/middleware.ts +22 -0
  63. package/dist/templates/next-app/src/server/getServerI18n.ts +26 -0
  64. package/dist/templates/next-app/src/styles/css/antd-themes/_default.css +239 -0
  65. package/dist/templates/next-app/src/styles/css/antd-themes/dark.css +178 -0
  66. package/dist/templates/next-app/src/styles/css/antd-themes/index.css +3 -0
  67. package/dist/templates/next-app/src/styles/css/antd-themes/no-context.css +34 -0
  68. package/dist/templates/next-app/src/styles/css/antd-themes/pink.css +204 -0
  69. package/dist/templates/next-app/src/styles/css/index.css +6 -0
  70. package/dist/templates/next-app/src/styles/css/page.css +19 -0
  71. package/dist/templates/next-app/src/styles/css/tailwind.css +5 -0
  72. package/dist/templates/next-app/src/styles/css/themes/_default.css +29 -0
  73. package/dist/templates/next-app/src/styles/css/themes/dark.css +29 -0
  74. package/dist/templates/next-app/src/styles/css/themes/index.css +3 -0
  75. package/dist/templates/next-app/src/styles/css/themes/pink.css +29 -0
  76. package/dist/templates/next-app/src/styles/css/zIndex.css +9 -0
  77. package/dist/templates/next-app/src/uikit/components/BaseHeader.tsx +42 -0
  78. package/dist/templates/next-app/src/uikit/components/BootstrapsProvider.tsx +25 -0
  79. package/dist/templates/next-app/src/uikit/components/ComboProvider.tsx +45 -0
  80. package/dist/templates/next-app/src/uikit/components/LanguageSwitcher.tsx +52 -0
  81. package/dist/templates/next-app/src/uikit/components/LocaleLink.tsx +51 -0
  82. package/dist/templates/next-app/src/uikit/components/NextIntlProvider.tsx +21 -0
  83. package/dist/templates/next-app/src/uikit/components/ThemeSwitcher.tsx +86 -0
  84. package/dist/templates/next-app/src/uikit/context/IOCContext.ts +6 -0
  85. package/dist/templates/next-app/src/uikit/hook/useI18nInterface.ts +28 -0
  86. package/dist/templates/next-app/src/uikit/hook/useIOC.ts +37 -0
  87. package/dist/templates/next-app/src/uikit/hook/useMountedClient.ts +11 -0
  88. package/dist/templates/next-app/src/uikit/hook/useStore.ts +15 -0
  89. package/dist/templates/next-app/tailwind.config.ts +8 -0
  90. package/dist/templates/next-app/tsconfig.json +36 -0
  91. package/dist/templates/react-app/.env.template +0 -2
  92. package/dist/templates/react-app/__tests__/src/base/services/I18nService.test.ts +1 -1
  93. package/dist/templates/react-app/__tests__/src/core/IOC.test.ts +6 -31
  94. package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapsApp.test.ts +1 -1
  95. package/dist/templates/react-app/config/IOCIdentifier.ts +77 -5
  96. package/dist/templates/react-app/config/app.router.ts +2 -2
  97. package/dist/templates/react-app/package.json +4 -7
  98. package/dist/templates/react-app/public/locales/en/common.json +1 -1
  99. package/dist/templates/react-app/public/locales/zh/common.json +1 -1
  100. package/dist/templates/react-app/src/App.tsx +9 -4
  101. package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +1 -1
  102. package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +4 -0
  103. package/dist/templates/react-app/src/base/cases/DialogHandler.ts +16 -13
  104. package/dist/templates/react-app/src/base/cases/I18nKeyErrorPlugin.ts +4 -3
  105. package/dist/templates/react-app/src/base/cases/InversifyContainer.ts +2 -2
  106. package/dist/templates/react-app/src/base/cases/RequestLanguages.ts +39 -0
  107. package/dist/templates/react-app/src/base/cases/RequestState.ts +20 -0
  108. package/dist/templates/react-app/src/base/cases/RequestStatusCatcher.ts +2 -2
  109. package/dist/templates/react-app/src/base/cases/RouterLoader.ts +8 -2
  110. package/dist/templates/react-app/src/base/port/AsyncStateInterface.ts +7 -0
  111. package/dist/templates/react-app/src/base/port/ExecutorPageBridgeInterface.ts +24 -0
  112. package/dist/templates/react-app/src/base/port/I18nServiceInterface.ts +10 -0
  113. package/dist/templates/react-app/src/base/port/JSONStoragePageBridgeInterface.ts +20 -0
  114. package/dist/templates/react-app/src/base/port/ProcesserExecutorInterface.ts +20 -0
  115. package/dist/templates/react-app/src/base/port/RequestPageBridgeInterface.ts +23 -0
  116. package/dist/templates/react-app/src/base/port/RequestStatusInterface.ts +5 -0
  117. package/dist/templates/react-app/src/base/port/RouteServiceInterface.ts +27 -0
  118. package/dist/templates/react-app/src/base/port/UserServiceInterface.ts +12 -0
  119. package/dist/templates/react-app/src/base/services/I18nService.ts +10 -6
  120. package/dist/templates/react-app/src/base/services/ProcesserExecutor.ts +23 -5
  121. package/dist/templates/react-app/src/base/services/RouteService.ts +25 -54
  122. package/dist/templates/react-app/src/base/services/UserService.ts +10 -20
  123. package/dist/templates/react-app/src/core/IOC.ts +1 -26
  124. package/dist/templates/react-app/src/core/IocRegisterImpl.ts +125 -0
  125. package/dist/templates/react-app/src/core/bootstraps/BootstrapApp.ts +4 -6
  126. package/dist/templates/react-app/src/core/bootstraps/BootstrapsRegistry.ts +8 -6
  127. package/dist/templates/react-app/src/core/bootstraps/IocIdentifierTest.ts +26 -0
  128. package/dist/templates/react-app/src/pages/auth/Layout.tsx +2 -2
  129. package/dist/templates/react-app/src/pages/auth/LoginPage.tsx +5 -6
  130. package/dist/templates/react-app/src/pages/auth/RegisterPage.tsx +8 -7
  131. package/dist/templates/react-app/src/pages/base/ExecutorPage.tsx +8 -19
  132. package/dist/templates/react-app/src/pages/base/{ErrorIdentifierPage.tsx → IdentifierPage.tsx} +1 -1
  133. package/dist/templates/react-app/src/pages/base/JSONStoragePage.tsx +11 -15
  134. package/dist/templates/react-app/src/pages/base/Layout.tsx +1 -1
  135. package/dist/templates/react-app/src/pages/base/RedirectPathname.tsx +2 -2
  136. package/dist/templates/react-app/src/pages/base/RequestPage.tsx +34 -46
  137. package/dist/templates/react-app/src/styles/css/antd-themes/_default.css +2 -2
  138. package/dist/templates/react-app/src/styles/css/antd-themes/dark.css +2 -2
  139. package/dist/templates/react-app/src/styles/css/antd-themes/pink.css +2 -2
  140. package/dist/templates/react-app/src/styles/css/index.css +1 -0
  141. package/dist/templates/react-app/src/styles/css/page.css +8 -0
  142. package/dist/templates/react-app/src/styles/css/zIndex.css +9 -0
  143. package/dist/templates/react-app/src/uikit/{controllers/ExecutorController.ts → bridges/ExecutorPageBridge.ts} +13 -36
  144. package/dist/templates/react-app/src/uikit/bridges/JSONStoragePageBridge.ts +41 -0
  145. package/dist/templates/react-app/src/uikit/bridges/NavigateBridge.ts +16 -0
  146. package/dist/templates/react-app/src/uikit/bridges/RequestPageBridge.ts +136 -0
  147. package/dist/templates/react-app/src/uikit/components/LanguageSwitcher.tsx +3 -2
  148. package/dist/templates/react-app/src/uikit/components/LogoutButton.tsx +2 -2
  149. package/dist/templates/react-app/src/uikit/{providers → components}/ProcessExecutorProvider.tsx +4 -4
  150. package/dist/templates/react-app/src/uikit/components/RouterRenderComponent.tsx +1 -1
  151. package/dist/templates/react-app/src/uikit/components/ThemeSwitcher.tsx +3 -5
  152. package/dist/templates/react-app/src/uikit/{providers → components}/UserAuthProvider.tsx +3 -3
  153. package/dist/templates/react-app/src/uikit/hooks/useI18nGuard.ts +5 -2
  154. package/dist/templates/react-app/src/uikit/hooks/{userRouterService.ts → useNavigateBridge.ts} +3 -3
  155. package/dist/templates/react-app/src/uikit/hooks/useStore.ts +5 -2
  156. package/dist/templates/react-app/tsconfig.json +1 -4
  157. package/package.json +1 -1
  158. package/dist/templates/react-app/src/base/port/InteractionHubInterface.ts +0 -94
  159. package/dist/templates/react-app/src/base/port/UIDependenciesInterface.ts +0 -37
  160. package/dist/templates/react-app/src/core/registers/IocRegisterImpl.ts +0 -25
  161. package/dist/templates/react-app/src/core/registers/RegisterCommon.ts +0 -74
  162. package/dist/templates/react-app/src/core/registers/RegisterControllers.ts +0 -26
  163. package/dist/templates/react-app/src/core/registers/RegisterGlobals.ts +0 -30
  164. package/dist/templates/react-app/src/uikit/controllers/JSONStorageController.ts +0 -49
  165. package/dist/templates/react-app/src/uikit/controllers/RequestController.ts +0 -158
  166. /package/dist/templates/react-app/src/uikit/{providers → components}/BaseRouteProvider.tsx +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,262 @@
1
1
  # @qlover/create-app
2
2
 
3
+ ## 0.7.7
4
+
5
+ ### Patch Changes
6
+
7
+ #### ✨ Features
8
+
9
+ - **next-app:** initialize Next.js application template with essential configurations and files ([a6c37ed](https://github.com/qlover/fe-base/commit/a6c37edee416989a72c04a0c3ef77fe296308399)) ([#504](https://github.com/qlover/fe-base/pull/504))
10
+ - Added ESLint configuration for Next.js with TypeScript support.
11
+ - Created Next.js configuration file for application settings.
12
+ - Included package.json with scripts and dependencies for React, Next.js, TypeScript, and Tailwind CSS.
13
+ - Set up PostCSS configuration for Tailwind CSS integration.
14
+ - Added README.md for project setup instructions and resources.
15
+ - Configured TypeScript settings in tsconfig.json.
16
+ - Included global CSS styles and layout structure for the application.
17
+ - Created initial page component with example content and links to documentation.
18
+ - Added SVG assets for branding and icons.
19
+
20
+ This commit establishes a foundational structure for a new Next.js application, enabling developers to quickly start building their projects.
21
+
22
+ - **next-app:** enhance Next.js application template with new features and configurations ([1b65acf](https://github.com/qlover/fe-base/commit/1b65acf89cd88c34ac61480435196fe427d760ba)) ([#504](https://github.com/qlover/fe-base/pull/504))
23
+ - Added .env.template for environment variable management.
24
+ - Updated package.json scripts to support different environments (development, test, production).
25
+ - Introduced common configuration files for better organization and maintainability.
26
+ - Created new components for login functionality and base header structure.
27
+ - Implemented Inversify container for dependency injection and service management.
28
+ - Enhanced TypeScript configuration with additional path mappings.
29
+ - Added documentation for environment configuration and usage.
30
+
31
+ These changes aim to improve the overall structure and functionality of the Next.js application template, facilitating easier development and deployment.
32
+
33
+ - **next-app:** integrate theme management and enhance styling capabilities ([081e736](https://github.com/qlover/fe-base/commit/081e736c7e126b8e4fb6a38f29a68cd4a28929ac)) ([#504](https://github.com/qlover/fe-base/pull/504))
34
+ - Added `next-themes` package for theme management.
35
+ - Introduced `theme.ts` configuration for theme settings.
36
+ - Updated `layout.tsx` to include `ThemeProvider` for theme context.
37
+ - Created multiple CSS files for theme styles, including default, dark, and pink themes.
38
+ - Implemented `ThemeSwitcher` component for user theme selection.
39
+ - Enhanced global styles with new CSS imports for better organization.
40
+
41
+ These changes aim to improve the user experience by allowing dynamic theme switching and providing a more organized styling structure.
42
+
43
+ - **next-app:** add Tailwind CSS configuration and enhance theme management ([22320fd](https://github.com/qlover/fe-base/commit/22320fd81a1565339762fe9d60efe0279caaf7b9)) ([#504](https://github.com/qlover/fe-base/pull/504))
44
+ - Introduced `tailwind.config.ts` for Tailwind CSS setup.
45
+ - Updated `theme.ts` to include JSDoc type annotations for better clarity.
46
+ - Removed obsolete `globals.css` in favor of a more modular CSS structure.
47
+ - Modified `layout.tsx` to integrate new theme configurations and CSS imports.
48
+ - Enhanced `LoginPage` with improved styling and layout adjustments.
49
+ - Added `useMountedClient` hook for better theme management in `ThemeSwitcher`.
50
+
51
+ These changes aim to streamline the styling process and improve the overall user experience with dynamic theming capabilities.
52
+
53
+ - **next-app:** enhance application configuration and bootstrap process ([8fc5264](https://github.com/qlover/fe-base/commit/8fc5264d6b4ebe21fe7b8fca1dee075264c43755)) ([#504](https://github.com/qlover/fe-base/pull/504))
54
+ - Updated package.json scripts to support localhost and staging environments.
55
+ - Introduced AppConfig class for managing application configuration and environment settings.
56
+ - Enhanced IOC registration with new IocRegisterImpl for improved dependency management.
57
+ - Added BootstrapsApp component to initialize the bootstrap process in the application.
58
+ - Implemented BootstrapsRegistry for managing bootstrap plugins and configurations.
59
+ - Updated BaseHeader to dynamically display the application name from AppConfig.
60
+
61
+ These changes aim to improve the application's configuration management and streamline the bootstrap process for better maintainability and flexibility.
62
+
63
+ - **next-app:** enhance configuration and update dependencies ([76024eb](https://github.com/qlover/fe-base/commit/76024eb9d40122864e6727d46a0e94d2ca4c88d6)) ([#504](https://github.com/qlover/fe-base/pull/504))
64
+ - Added environment variable support in next.config.ts for better configuration management.
65
+ - Updated package.json to include new dependencies: @ant-design/nextjs-registry and @ant-design/v5-patch-for-react-19 for improved UI components.
66
+ - Enhanced TypeScript configuration in tsconfig.json with experimental decorators and metadata emission.
67
+ - Modified common.ts to disable localized routes for a more straightforward routing approach.
68
+ - Refactored layout.tsx to integrate AntdRegistry for better theme management and component structure.
69
+ - Updated LoginForm.tsx to utilize IOC for user service instantiation and improved login handling.
70
+
71
+ These changes aim to streamline application configuration, enhance UI capabilities, and improve overall code organization.
72
+
73
+ - **next-app:** implement internationalization support and update routing ([9554899](https://github.com/qlover/fe-base/commit/9554899b1b0da7ae064494f870eb7019be6fc9b8)) ([#504](https://github.com/qlover/fe-base/pull/504))
74
+ - Added i18n configuration in a new i18n.ts file to manage localization settings.
75
+ - Updated next.config.ts to include internationalization settings for default locale and supported languages.
76
+ - Modified common.ts to enable localized routes for improved routing experience.
77
+ - Introduced LanguageSwitcher component for dynamic language selection in the UI.
78
+ - Enhanced I18nService to manage language detection and translation functionalities.
79
+ - Updated BaseHeader to include the LanguageSwitcher for user accessibility.
80
+
81
+ These changes aim to enhance the application's internationalization capabilities, providing a better user experience for multilingual support.
82
+
83
+ - **next-app:** refactor theme management and enhance IOC integration ([3006a26](https://github.com/qlover/fe-base/commit/3006a2625870458285e2193c0b7c43c0730059d2)) ([#504](https://github.com/qlover/fe-base/pull/504))
84
+ - Updated tsconfig.json to include source files from the src directory for better TypeScript support.
85
+ - Enhanced theme configuration in theme.ts by adding antdTheme settings for improved theme management.
86
+ - Refactored layout.tsx to utilize ComboProvider for streamlined theme and bootstrap context integration.
87
+ - Removed obsolete BootstrapsApp component and replaced it with BootstrapsProvider for better structure.
88
+ - Introduced ComboProvider to encapsulate multiple providers, including AntdThemeProvider and ThemeProvider.
89
+ - Added IOCContext for better dependency injection management across components.
90
+ - Created useIOC hook for easier access to the IOC context in functional components.
91
+
92
+ These changes aim to improve the modularity and maintainability of the application by enhancing theme management and dependency injection practices.
93
+
94
+ - **next-app:** enhance TypeScript configuration and improve IOC integration ([f721e1b](https://github.com/qlover/fe-base/commit/f721e1b9cbfcccc84660d0d7c6973513c26805ac)) ([#504](https://github.com/qlover/fe-base/pull/504))
95
+ - Updated tsconfig.json to include .next/types/\*_/_.ts for better type support.
96
+ - Refactored IOC.ts to streamline dependency injection and introduced a new createIOC function for improved IOC management.
97
+ - Modified BootstrapClient to integrate IOC into the bootstrap process.
98
+ - Updated BootstrapsProvider to utilize the createIOC function for better dependency handling.
99
+
100
+ These changes aim to enhance TypeScript support and improve the modularity of the IOC system within the application.
101
+
102
+ - **next-app:** enhance internationalization support and improve IOC integration ([d706df8](https://github.com/qlover/fe-base/commit/d706df89b16a3cc75741ae4baa478f7ed4a3b5f8)) ([#504](https://github.com/qlover/fe-base/pull/504))
103
+ - Added I18nService and I18nServiceInterface for better language management.
104
+ - Updated IOCIdentifier to include I18nServiceInterface for dependency injection.
105
+ - Refactored I18nService methods to return promises for asynchronous operations.
106
+ - Modified BootstrapsRegistry and BootstrapClient to support pathname handling.
107
+ - Enhanced LanguageSwitcher component for dynamic language selection.
108
+
109
+ These changes aim to improve the application's internationalization capabilities and streamline the integration of the IOC system.
110
+
111
+ - **next-app:** enhance localization support and streamline locale generation ([4ba5934](https://github.com/qlover/fe-base/commit/4ba5934f02c46dc64edf485c41a4f6d67d0e3d3c)) ([#504](https://github.com/qlover/fe-base/pull/504))
112
+ - Integrated locale generation into the build process by adding a generateLocales function.
113
+ - Updated next.config.ts to automatically generate localization files at build start.
114
+ - Created a new plugin to handle locale generation during development and production builds.
115
+ - Added English and Chinese localization files for common application messages.
116
+
117
+ These changes aim to improve the application's internationalization capabilities by automating locale management and providing essential translations for better user experience.
118
+
119
+ - **next-app:** refactor internationalization implementation and enhance localization features ([d95a8bf](https://github.com/qlover/fe-base/commit/d95a8bf52cc70d2b5d0d0bcee894c6455bbe54b7)) ([#504](https://github.com/qlover/fe-base/pull/504))
120
+ - Replaced i18next with next-intl for improved localization support.
121
+ - Updated next.config.ts to integrate next-intl plugin for locale management.
122
+ - Refactored i18n configuration to streamline language detection and fallback settings.
123
+ - Enhanced LoginForm and LoginPage components to utilize next-intl for translations.
124
+ - Introduced NextIntlProvider component for better context management of translations.
125
+
126
+ These changes aim to simplify the internationalization process and improve the user experience with more efficient localization handling.
127
+
128
+ - **next-app:** implement middleware and enhance internationalization routing ([08e6d0b](https://github.com/qlover/fe-base/commit/08e6d0be99c508df5242a389211937cc16173026)) ([#504](https://github.com/qlover/fe-base/pull/504))
129
+ - Added middleware for locale detection and internationalized routing using next-intl.
130
+ - Refactored layout.tsx to streamline message retrieval and improve locale handling.
131
+ - Updated LoginForm and LoginPage components to utilize lodash for translation functions.
132
+ - Introduced new i18n request configuration for dynamic message loading based on request locale.
133
+ - Created routing.ts to define supported locales and localized pathnames for improved navigation.
134
+
135
+ These changes aim to enhance the application's internationalization capabilities and provide a more robust routing experience.
136
+
137
+ - **next-app:** enhance layout structure and improve localization in login components ([1bfa104](https://github.com/qlover/fe-base/commit/1bfa1045dbe224a2e45b510d3b41d21f3a38c0be)) ([#504](https://github.com/qlover/fe-base/pull/504))
138
+ - Integrated BaseHeader into the RootLayout for consistent header display across the application.
139
+ - Updated LoginForm and LoginPage components to utilize next-intl for translation handling, replacing lodash.
140
+ - Refactored layout structure to ensure proper rendering of children components within a flex container.
141
+
142
+ These changes aim to improve the user interface and enhance the internationalization support in the login flow.
143
+
144
+ - **next-app:** add login internationalization interface and refactor login components ([e2fe74a](https://github.com/qlover/fe-base/commit/e2fe74a9639809749df985ca3dc9e97334c43a29)) ([#504](https://github.com/qlover/fe-base/pull/504))
145
+ - Introduced `LoginI18nInterface` for managing localization keys specific to the login page.
146
+ - Created `PageI18nInterface` to standardize SEO meta properties across pages.
147
+ - Refactored `LoginForm` and `LoginPage` components to utilize the new i18n structure, enhancing translation handling.
148
+ - Updated `FeatureItem` component to include a data-testid for improved testing capabilities.
149
+ - Implemented `useI18nInterface` hook for streamlined access to localized strings.
150
+
151
+ These changes aim to improve the internationalization support for the login flow and enhance the overall structure of the components.
152
+
153
+ - **next-app:** add initial locale support and layout structure for next-app ([32f60e6](https://github.com/qlover/fe-base/commit/32f60e6d529584bf542a04029a06102393bb3874)) ([#504](https://github.com/qlover/fe-base/pull/504))
154
+ - Introduced new layout structure in `layout.tsx` to support internationalization with `NextIntlClientProvider`.
155
+ - Added `favicon.ico` for branding consistency across locales.
156
+ - Created `not-found.tsx` for handling 404 errors with localized messages.
157
+ - Developed `page.tsx` for the home page, featuring a welcoming layout and links to documentation and deployment.
158
+ - Implemented login components including `LoginForm`, `FeatureItem`, and `LoginPage` to facilitate user authentication with localization support.
159
+ - Added `useServerI18n.ts` for server-side translation handling.
160
+
161
+ These changes lay the groundwork for a multilingual application experience, enhancing user engagement through localized content.
162
+
163
+ - **next-app:** enhance internationalization support with new i18n configuration and components ([3706b88](https://github.com/qlover/fe-base/commit/3706b880d6245dd51c4bfdef8e37ba52779d196d)) ([#504](https://github.com/qlover/fe-base/pull/504))
164
+ - Added `i18nConfig` for managing locale settings and fallback languages.
165
+ - Introduced `PageI18nInterface` and `LoginI18nInterface` to standardize localization keys for SEO and login components.
166
+ - Created new files for login internationalization, including `loginI18n.ts` and `i18nConfig.ts`.
167
+ - Implemented middleware for locale detection and routing in `middleware.ts`.
168
+ - Updated TypeScript configuration to include new source paths for better type support.
169
+
170
+ These changes aim to improve the application's internationalization capabilities and provide a more structured approach to localization.
171
+
172
+ - **next-app:** enhance ESLint configuration with new plugins and rules ([87775e4](https://github.com/qlover/fe-base/commit/87775e4c1d31788fe83457399c876415af27fe54)) ([#504](https://github.com/qlover/fe-base/pull/504))
173
+ - Added eslint-plugin-import and eslint-plugin-unused-imports to improve import management and unused variable detection.
174
+ - Updated ESLint configuration to include recommended settings for import ordering and unused imports.
175
+ - Introduced a new lint:fix script for automatic code formatting and cleanup.
176
+
177
+ These changes aim to improve code quality and maintainability by enforcing stricter linting rules.
178
+
179
+ - **next-app:** add Prettier and ESLint configurations for improved code formatting ([e7f1e72](https://github.com/qlover/fe-base/commit/e7f1e72983759cd18f0cc16c49d5a0f3f95994ea)) ([#504](https://github.com/qlover/fe-base/pull/504))
180
+ - Introduced .prettierignore and .prettierrc.js files to define formatting rules and ignore patterns for Prettier.
181
+ - Updated ESLint configuration to include prettier integration, enhancing code quality and consistency.
182
+ - Added new scripts for formatting and linting in package.json to streamline development processes.
183
+
184
+ These changes aim to enforce consistent code style and improve maintainability across the project.
185
+
186
+ - **next-app:** integrate custom ESLint plugin for data-testid enforcement and enhance component testing ([51ebeea](https://github.com/qlover/fe-base/commit/51ebeea8b875179fde6dbe49d64960e8902534fb)) ([#504](https://github.com/qlover/fe-base/pull/504))
187
+ - Added a new ESLint plugin to enforce the presence of data-testid attributes on root elements of TSX components, improving testability.
188
+ - Updated ESLint configuration to include the new plugin and enforce its rules.
189
+ - Modified several components to include data-testid attributes, enhancing their compatibility with testing frameworks.
190
+ - Adjusted the order of linting and formatting scripts in package.json for better workflow efficiency.
191
+
192
+ These changes aim to improve the testing capabilities of the application by ensuring that components are easily identifiable in tests.
193
+
194
+ - **next-app:** integrate @qlover/eslint-plugin and update ESLint rules for improved testing ([9bda32f](https://github.com/qlover/fe-base/commit/9bda32fc610753b863557f4f90fa90fe001fb928)) ([#504](https://github.com/qlover/fe-base/pull/504))
195
+ - Replaced the custom eslint-plugin-testid with @qlover/eslint-plugin to enhance testability of components.
196
+ - Updated ESLint configuration to include new rules for enforcing data-testid attributes on root elements.
197
+ - Refactored I18nService and BootstrapClient to specify return types for better type safety.
198
+
199
+ These changes aim to improve the testing capabilities and maintainability of the application by ensuring consistent ESLint rules and enhancing type definitions.
200
+
201
+ #### ♻️ Refactors
202
+
203
+ - **next-app:** update error identifiers and localization keys for consistency ([5ce5894](https://github.com/qlover/fe-base/commit/5ce5894abe73e10b4a42ac6c6b89c5a2d7dcb45e)) ([#504](https://github.com/qlover/fe-base/pull/504))
204
+ - Refactored error identifiers and localization keys across various components to use a consistent naming convention with double underscores.
205
+ - Updated keys in common.error.ts, common.ts, and various page identifier files to enhance readability and maintainability.
206
+ - Adjusted localization files to reflect the new key structure, ensuring alignment with the updated identifiers.
207
+
208
+ These changes aim to improve the clarity and consistency of localization keys throughout the application.
209
+
210
+ - **next-app:** streamline IOC integration and enhance I18nService usage ([ee888ce](https://github.com/qlover/fe-base/commit/ee888ceee1f94e4ad6f38cb0c816dc9888011290)) ([#504](https://github.com/qlover/fe-base/pull/504))
211
+ - Removed the @injectable() decorator from I18nService for simplified instantiation.
212
+ - Updated IOC creation logic in BootstrapClient to use a singleton pattern for better resource management.
213
+ - Refactored IocRegisterImpl to directly instantiate I18nService, improving clarity in service registration.
214
+ - Adjusted BootstrapsProvider to utilize the new IOC creation method, ensuring consistent IOC management across components.
215
+
216
+ These changes aim to enhance the modularity and efficiency of the IOC system while improving the integration of the I18nService.
217
+
218
+ - **next-app:** reorganize imports and enhance i18n integration ([7f57af0](https://github.com/qlover/fe-base/commit/7f57af00627b3838ab19d3f1b5683b738fc2f12c)) ([#504](https://github.com/qlover/fe-base/pull/504))
219
+ - Cleaned up import statements across various components for better readability and consistency.
220
+ - Introduced a new `getServerI18n` function to streamline server-side translation handling.
221
+ - Updated layout and component files to utilize the new i18n structure, improving localization support.
222
+ - Adjusted type imports and ensured proper usage of the `next-intl` library for internationalization.
223
+
224
+ These changes aim to enhance the modularity and clarity of the codebase while improving the internationalization capabilities of the application.
225
+
226
+ - **next-app:** update component exports and ESLint rules for improved consistency ([e7836e5](https://github.com/qlover/fe-base/commit/e7836e5f8c4119fdc52f362c9c18e66e24d3a97f)) ([#504](https://github.com/qlover/fe-base/pull/504))
227
+ - Changed default exports to named exports for several components, enhancing import clarity and consistency.
228
+ - Updated ESLint configuration to enforce no default exports, with exceptions for specific files to maintain flexibility.
229
+ - Cleaned up import statements across various files for better readability and adherence to coding standards.
230
+
231
+ These changes aim to improve code maintainability and enforce a more consistent coding style across the project.
232
+
233
+ - **eslint-plugin:** improve rule exports and update ESLint configurations ([c142834](https://github.com/qlover/fe-base/commit/c142834bbabbeec3e5e3f92c6646bc0dc960379a)) ([#504](https://github.com/qlover/fe-base/pull/504))
234
+ - Refactored the export statements for ESLint rules to use named exports for better clarity and consistency.
235
+ - Enhanced the ESLint configuration to improve the handling of unused variables and enforce stricter linting rules.
236
+ - Updated the `require-root-testid` rule to ensure proper formatting and documentation.
237
+
238
+ These changes aim to enhance the maintainability and readability of the ESLint plugin while ensuring consistent rule enforcement across the codebase.
239
+
240
+ ## 0.7.6
241
+
242
+ ### Patch Changes
243
+
244
+ #### ✨ Features
245
+
246
+ - **ui:** introduce UI bridge interfaces and notification system ([6969561](https://github.com/qlover/fe-base/commit/6969561b3f4603bb51ae7ad5fdca9e539d75209b)) ([#499](https://github.com/qlover/fe-base/pull/499))
247
+ - Added UIBridgeInterface for decoupling business logic from UI components.
248
+ - Implemented UINotificationInterface and UIDialogInterface for standardized notification handling.
249
+ - Created NavigateBridge to facilitate navigation integration with React Router.
250
+ - Updated RouteService to utilize the new UIBridgeInterface for improved dependency management.
251
+ - Introduced useNavigateBridge hook for setting up navigation in React components.
252
+ - Removed obsolete UIDependenciesInterface to streamline the codebase.
253
+
254
+ - **dialog:** enhance UIDialogInterface and integrate into DialogHandler ([d9d2cdd](https://github.com/qlover/fe-base/commit/d9d2cdd68ff2a68675a2abdd7339c7be0c706724)) ([#499](https://github.com/qlover/fe-base/pull/499))
255
+ - Updated UIDialogInterface to use generic types for notification options, improving flexibility.
256
+ - Integrated UIDialogInterface into DialogHandler for better type safety and consistency in dialog handling.
257
+ - Adjusted RouteService to streamline navigation handling and improve code clarity.
258
+ - Updated package.json to reference local paths for corekit-bridge and fe-corekit for development.
259
+
3
260
  ## 0.7.5
4
261
 
5
262
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -8,4 +8,4 @@ ${t}`,dn=Object.getOwnPropertyDescriptor(Function.prototype,"toString"),_n=Objec
8
8
  `))this.#e+=Math.max(1,Math.ceil(Ye(D,{countAnsiEscapeCodes:!0})/t))}get isEnabled(){return this.#a&&!this.#F}set isEnabled(t){if(typeof t!="boolean")throw new TypeError("The `isEnabled` option must be a boolean");this.#a=t}get isSilent(){return this.#F}set isSilent(t){if(typeof t!="boolean")throw new TypeError("The `isSilent` option must be a boolean");this.#F=t}frame(){let t=Date.now();(this.#i===-1||t-this.#c>=this.interval)&&(this.#i=++this.#i%this.#D.frames.length,this.#c=t);let{frames:r}=this.#D,u=r[this.#i];this.color&&(u=d[this.color](u));let i=typeof this.#s=="string"&&this.#s!==""?this.#s+" ":"",D=typeof this.text=="string"?" "+this.text:"",o=typeof this.#o=="string"&&this.#o!==""?" "+this.#o:"";return i+u+D+o}clear(){if(!this.#a||!this.#u.isTTY)return this;this.#u.cursorTo(0);for(let t=0;t<this.#n;t++)t>0&&this.#u.moveCursor(0,-1),this.#u.clearLine(1);return(this.#l||this.lastIndent!==this.#l)&&this.#u.cursorTo(this.#l),this.lastIndent=this.#l,this.#n=0,this}render(){return this.#F?this:(this.clear(),this.#u.write(this.frame()),this.#n=this.#e,this)}start(t){return t&&(this.text=t),this.#F?this:this.#a?this.isSpinning?this:(this.#t.hideCursor&&$e.hide(this.#u),this.#t.discardStdin&&V.default.stdin.isTTY&&(this.#r=!0,Je.start()),this.render(),this.#f=setInterval(this.render.bind(this),this.interval),this):(this.text&&this.#u.write(`- ${this.text}
9
9
  `),this)}stop(){return this.#a?(clearInterval(this.#f),this.#f=void 0,this.#i=0,this.clear(),this.#t.hideCursor&&$e.show(this.#u),this.#t.discardStdin&&V.default.stdin.isTTY&&this.#r&&(Je.stop(),this.#r=!1),this):this}succeed(t){return this.stopAndPersist({symbol:H.success,text:t})}fail(t){return this.stopAndPersist({symbol:H.error,text:t})}warn(t){return this.stopAndPersist({symbol:H.warning,text:t})}info(t){return this.stopAndPersist({symbol:H.info,text:t})}stopAndPersist(t={}){if(this.#F)return this;let r=t.prefixText??this.#s,u=this.#E(r," "),i=t.symbol??" ",D=t.text??this.text,s=typeof D=="string"?(i?" ":"")+D:"",a=t.suffixText??this.#o,f=this.#g(a," "),p=u+i+s+f+`
10
10
  `;return this.stop(),this.#u.write(p),this}};function tr(e){return new Ze(e)}async function rr(e,t){let r=typeof e=="function",u=typeof e.then=="function";if(!r&&!u)throw new TypeError("Parameter `action` must be a Function or a Promise");let{successText:i,failText:D}=typeof t=="object"?t:{successText:void 0,failText:void 0},o=tr(t).start();try{let a=await(r?e(o):e);return o.succeed(i===void 0?void 0:typeof i=="string"?i:i(a)),a}catch(s){throw o.fail(D===void 0?void 0:typeof D=="string"?D:D(s)),s}}var HD=require("fs");var P=require("path"),me=require("fs"),cr=h(lr(),1),Dt=require("fs");var de=require("fs"),X=class{static ensureDir(t){(0,de.existsSync)(t)||(0,de.mkdirSync)(t,{recursive:!0})}};var{copyFile:rs,stat:us}=Dt.promises,_e=class e{constructor(t,r=e.IGNORE_FILE){this.ignoreTargetPath=t;this.ignoreFile=r}static IGNORE_FILE=".gitignore.template";getIg(t=this.ignoreTargetPath){let r=(0,P.join)(t,this.ignoreFile);if(!(0,me.existsSync)(r))return;let D=(0,me.readFileSync)(r,"utf8").split(`
11
- `).map(o=>o.trim()).filter(o=>o&&!o.startsWith("#"));return(0,cr.default)().add(D)}async copyFiles(t,r,u,i){let D=await Dt.promises.readdir(t);await Promise.all(D.map(async o=>{let s=(0,P.join)(t,o),a=(0,P.join)(r,o);if(u&&u.ignores(o))return;if(X.ensureDir((0,P.dirname)(a)),(await us(s)).isDirectory())await this.copyFiles(s,a,u,i);else{if(i&&await i(s,a))return;await rs(s,a)}}))}copyPaths({sourcePath:t,targetPath:r,copyCallback:u}){X.ensureDir(r);let i=this.getIg();return this.copyFiles(t,r,i,u)}};var L=require("fs"),kD=h(LD(),1),xe=class{constructor(){}isJSONFilePath(t){return t.endsWith(".json")||t.endsWith(".json.template")}isTemplateFilePath(t){return t.endsWith(".template")}getRealTemplateFilePath(t){return t.replace(".template","")}readFile(t){return(0,L.readFileSync)(t,"utf-8")}readJSONFile(t){return JSON.parse(this.readFile(t))}writeFile(t,r){(0,L.writeFileSync)(this.getRealTemplateFilePath(t),r,{encoding:"utf-8"})}replaceFile(t,r){let u=this.readFile(t);return Object.keys(r).forEach(i=>{let D=r[i];u=u.replace(new RegExp(`\\[TPL:${i}\\]`,"g"),typeof D=="string"?D:JSON.stringify(D))}),u}mergeJSONFile(t,r){let u=this.readJSONFile(t),i=(0,kD.default)(r,u);this.writeFile(t,JSON.stringify(i,null,2))}composeConfigFile(t,r,u){if(this.isTemplateFilePath(r)){let i=this.replaceFile(r,t);if(this.isJSONFilePath(r)&&this.isJSONFilePath(u)){let D=this.getRealTemplateFilePath(u);return(0,L.existsSync)(D)?(this.mergeJSONFile(D,JSON.parse(i)),!0):(this.writeFile(D,i),!0)}return this.writeFile(u,i),!0}return!1}};var $D=["pack-app"],ye=class{ora;context;subPackages;copyer;compose;constructor(t){let r=t.options?.templateRootPath;if(!r)throw new Error("template path not exit");if(!(0,HD.existsSync)(r))throw new Error("template path not exit");this.ora=rr,this.context=new UD.FeScriptContext(t),this.subPackages=["node-lib","react-app"],this.copyer=new _e((0,v.join)(this.context.options.configsRootPath,"_common")),this.compose=new xe}get logger(){return this.context.logger}async steps(t){try{return await WD.default.prompt(t)}catch(r){throw r.isTtyError,this.logger.error(r),r}}async action({label:t,task:r}){let u=r();u instanceof Promise||(u=Promise.resolve(u));let i=t;return this.ora(u,i),u}isPackageTemplate(t){return $D.includes(t)}async getGeneratorContext(){let t=Ot(this.subPackages,$D),r=await this.steps(t);if(this.isPackageTemplate(r.template)){let u=wt(this.subPackages),i=await this.steps(u);Object.assign(r,i)}return r.targetPath=(0,v.join)(process.cwd(),r.projectName),r.releasePath=r.releasePath||"src",r}async generate(){let t=await this.getGeneratorContext();if(this.logger.debug("context is:",t,this.context.options.templateRootPath),t.subPackages){await this.action({label:"Generate Directories(subPackages)",task:async()=>{await this.generateTemplateDir(t),await this.generateSubPackages(t),await this.generateConfigs(t,t.targetPath,"_common")}});return}await this.action({label:"Generate Directory",task:async()=>{await this.generateTemplateDir(t),await this.generateConfigs(t,t.targetPath,"_common"),await this.generateConfigs(t,t.targetPath,t.template)}})}async generateConfigs(t,r,u){let i=(s,a)=>(this.logger.debug("copyCallback",s,a),this.compose.composeConfigFile(t,s,a)),{configsRootPath:D,config:o}=this.context.options;if(!o){this.logger.debug("no copy config files");return}await this.copyer.copyPaths({sourcePath:(0,v.join)(D,u),targetPath:r,copyCallback:i})}generateTemplateDir(t){return this.copyer.copyPaths({sourcePath:(0,v.join)(this.context.options.templateRootPath,t.template),targetPath:t.targetPath})}async generateSubPackages(t){let{packagesNames:r="packages",subPackages:u=[],targetPath:i=""}=t,{templateRootPath:D}=this.context.options;for(let o of u){let s=(0,v.join)(D,o),a=(0,v.join)(i,r,o);this.logger.debug("copy sub package",s,a),await this.copyer.copyPaths({sourcePath:s,targetPath:a})}}};var bt={name:"@qlover/create-app",version:"0.7.5",description:"Create a new app with a single command",private:!1,type:"module",files:["dist","package.json","README.md","CHANGELOG.md"],bin:{"create-app":"dist/index.js"},scripts:{build:"tsup","create:app":"node ./dist/index.js"},repository:{type:"git",url:"git+https://github.com/qlover/fe-base.git",directory:"packages/create-app"},homepage:"https://github.com/qlover/fe-base#readme",keywords:["create-app","fe-scripts","scripts"],author:"qlover",license:"ISC",publishConfig:{access:"public"},devDependencies:{"@qlover/logger":"workspace:*",ignore:"^7.0.3",lodash:"^4.17.21",ora:"^8.1.1"},dependencies:{"@qlover/scripts-context":"workspace:*",commander:"^13.1.0",inquirer:"^12.3.2"}};function Ul(){let e=new YD.Command;return e.version(bt.version,"-v, --version","Show version").description(bt.description).option("-d, --dry-run","Do not touch or write anything, but show the commands").option("-V, --verbose","Show more information").option("--config","Copy config files (default: true)",!0).option("--no-config","Do not copy config files"),e.parse(),e.opts()}async function Wl(){let{dryRun:e,verbose:t,...r}=Ul(),u=(0,vt.resolve)("./templates"),i=(0,vt.resolve)("./configs");(0,xt.existsSync)(u)||(console.error("Template is empty!"),process.exit(1)),(0,xt.existsSync)(i)||(console.error("Configs is empty!"),process.exit(1)),await new ye({dryRun:e,verbose:t,options:{...r,templateRootPath:u,configsRootPath:i}}).generate()}Wl().catch(e=>{console.error(e),process.exit(1)});
11
+ `).map(o=>o.trim()).filter(o=>o&&!o.startsWith("#"));return(0,cr.default)().add(D)}async copyFiles(t,r,u,i){let D=await Dt.promises.readdir(t);await Promise.all(D.map(async o=>{let s=(0,P.join)(t,o),a=(0,P.join)(r,o);if(u&&u.ignores(o))return;if(X.ensureDir((0,P.dirname)(a)),(await us(s)).isDirectory())await this.copyFiles(s,a,u,i);else{if(i&&await i(s,a))return;await rs(s,a)}}))}copyPaths({sourcePath:t,targetPath:r,copyCallback:u}){X.ensureDir(r);let i=this.getIg();return this.copyFiles(t,r,i,u)}};var L=require("fs"),kD=h(LD(),1),xe=class{constructor(){}isJSONFilePath(t){return t.endsWith(".json")||t.endsWith(".json.template")}isTemplateFilePath(t){return t.endsWith(".template")}getRealTemplateFilePath(t){return t.replace(".template","")}readFile(t){return(0,L.readFileSync)(t,"utf-8")}readJSONFile(t){return JSON.parse(this.readFile(t))}writeFile(t,r){(0,L.writeFileSync)(this.getRealTemplateFilePath(t),r,{encoding:"utf-8"})}replaceFile(t,r){let u=this.readFile(t);return Object.keys(r).forEach(i=>{let D=r[i];u=u.replace(new RegExp(`\\[TPL:${i}\\]`,"g"),typeof D=="string"?D:JSON.stringify(D))}),u}mergeJSONFile(t,r){let u=this.readJSONFile(t),i=(0,kD.default)(r,u);this.writeFile(t,JSON.stringify(i,null,2))}composeConfigFile(t,r,u){if(this.isTemplateFilePath(r)){let i=this.replaceFile(r,t);if(this.isJSONFilePath(r)&&this.isJSONFilePath(u)){let D=this.getRealTemplateFilePath(u);return(0,L.existsSync)(D)?(this.mergeJSONFile(D,JSON.parse(i)),!0):(this.writeFile(D,i),!0)}return this.writeFile(u,i),!0}return!1}};var $D=["pack-app"],ye=class{ora;context;subPackages;copyer;compose;constructor(t){let r=t.options?.templateRootPath;if(!r)throw new Error("template path not exit");if(!(0,HD.existsSync)(r))throw new Error("template path not exit");this.ora=rr,this.context=new UD.FeScriptContext(t),this.subPackages=["node-lib","react-app"],this.copyer=new _e((0,v.join)(this.context.options.configsRootPath,"_common")),this.compose=new xe}get logger(){return this.context.logger}async steps(t){try{return await WD.default.prompt(t)}catch(r){throw r.isTtyError,this.logger.error(r),r}}async action({label:t,task:r}){let u=r();u instanceof Promise||(u=Promise.resolve(u));let i=t;return this.ora(u,i),u}isPackageTemplate(t){return $D.includes(t)}async getGeneratorContext(){let t=Ot(this.subPackages,$D),r=await this.steps(t);if(this.isPackageTemplate(r.template)){let u=wt(this.subPackages),i=await this.steps(u);Object.assign(r,i)}return r.targetPath=(0,v.join)(process.cwd(),r.projectName),r.releasePath=r.releasePath||"src",r}async generate(){let t=await this.getGeneratorContext();if(this.logger.debug("context is:",t,this.context.options.templateRootPath),t.subPackages){await this.action({label:"Generate Directories(subPackages)",task:async()=>{await this.generateTemplateDir(t),await this.generateSubPackages(t),await this.generateConfigs(t,t.targetPath,"_common")}});return}await this.action({label:"Generate Directory",task:async()=>{await this.generateTemplateDir(t),await this.generateConfigs(t,t.targetPath,"_common"),await this.generateConfigs(t,t.targetPath,t.template)}})}async generateConfigs(t,r,u){let i=(s,a)=>(this.logger.debug("copyCallback",s,a),this.compose.composeConfigFile(t,s,a)),{configsRootPath:D,config:o}=this.context.options;if(!o){this.logger.debug("no copy config files");return}await this.copyer.copyPaths({sourcePath:(0,v.join)(D,u),targetPath:r,copyCallback:i})}generateTemplateDir(t){return this.copyer.copyPaths({sourcePath:(0,v.join)(this.context.options.templateRootPath,t.template),targetPath:t.targetPath})}async generateSubPackages(t){let{packagesNames:r="packages",subPackages:u=[],targetPath:i=""}=t,{templateRootPath:D}=this.context.options;for(let o of u){let s=(0,v.join)(D,o),a=(0,v.join)(i,r,o);this.logger.debug("copy sub package",s,a),await this.copyer.copyPaths({sourcePath:s,targetPath:a})}}};var bt={name:"@qlover/create-app",version:"0.7.7",description:"Create a new app with a single command",private:!1,type:"module",files:["dist","package.json","README.md","CHANGELOG.md"],bin:{"create-app":"dist/index.js"},scripts:{build:"tsup","create:app":"node ./dist/index.js"},repository:{type:"git",url:"git+https://github.com/qlover/fe-base.git",directory:"packages/create-app"},homepage:"https://github.com/qlover/fe-base#readme",keywords:["create-app","fe-scripts","scripts"],author:"qlover",license:"ISC",publishConfig:{access:"public"},devDependencies:{"@qlover/logger":"workspace:*",ignore:"^7.0.3",lodash:"^4.17.21",ora:"^8.1.1"},dependencies:{"@qlover/scripts-context":"workspace:*",commander:"^13.1.0",inquirer:"^12.3.2"}};function Ul(){let e=new YD.Command;return e.version(bt.version,"-v, --version","Show version").description(bt.description).option("-d, --dry-run","Do not touch or write anything, but show the commands").option("-V, --verbose","Show more information").option("--config","Copy config files (default: true)",!0).option("--no-config","Do not copy config files"),e.parse(),e.opts()}async function Wl(){let{dryRun:e,verbose:t,...r}=Ul(),u=(0,vt.resolve)("./templates"),i=(0,vt.resolve)("./configs");(0,xt.existsSync)(u)||(console.error("Template is empty!"),process.exit(1)),(0,xt.existsSync)(i)||(console.error("Configs is empty!"),process.exit(1)),await new ye({dryRun:e,verbose:t,options:{...r,templateRootPath:u,configsRootPath:i}}).generate()}Wl().catch(e=>{console.error(e),process.exit(1)});
package/dist/index.js CHANGED
@@ -8,4 +8,4 @@ ${t}`,cn=Object.getOwnPropertyDescriptor(Function.prototype,"toString"),fn=Objec
8
8
  `))this.#e+=Math.max(1,Math.ceil(Le(D,{countAnsiEscapeCodes:!0})/t))}get isEnabled(){return this.#a&&!this.#F}set isEnabled(t){if(typeof t!="boolean")throw new TypeError("The `isEnabled` option must be a boolean");this.#a=t}get isSilent(){return this.#F}set isSilent(t){if(typeof t!="boolean")throw new TypeError("The `isSilent` option must be a boolean");this.#F=t}frame(){let t=Date.now();(this.#i===-1||t-this.#c>=this.interval)&&(this.#i=++this.#i%this.#D.frames.length,this.#c=t);let{frames:r}=this.#D,u=r[this.#i];this.color&&(u=E[this.color](u));let i=typeof this.#s=="string"&&this.#s!==""?this.#s+" ":"",D=typeof this.text=="string"?" "+this.text:"",o=typeof this.#o=="string"&&this.#o!==""?" "+this.#o:"";return i+u+D+o}clear(){if(!this.#a||!this.#u.isTTY)return this;this.#u.cursorTo(0);for(let t=0;t<this.#n;t++)t>0&&this.#u.moveCursor(0,-1),this.#u.clearLine(1);return(this.#l||this.lastIndent!==this.#l)&&this.#u.cursorTo(this.#l),this.lastIndent=this.#l,this.#n=0,this}render(){return this.#F?this:(this.clear(),this.#u.write(this.frame()),this.#n=this.#e,this)}start(t){return t&&(this.text=t),this.#F?this:this.#a?this.isSpinning?this:(this.#t.hideCursor&&je.hide(this.#u),this.#t.discardStdin&&ce.stdin.isTTY&&(this.#r=!0,We.start()),this.render(),this.#f=setInterval(this.render.bind(this),this.interval),this):(this.text&&this.#u.write(`- ${this.text}
9
9
  `),this)}stop(){return this.#a?(clearInterval(this.#f),this.#f=void 0,this.#i=0,this.clear(),this.#t.hideCursor&&je.show(this.#u),this.#t.discardStdin&&ce.stdin.isTTY&&this.#r&&(We.stop(),this.#r=!1),this):this}succeed(t){return this.stopAndPersist({symbol:k.success,text:t})}fail(t){return this.stopAndPersist({symbol:k.error,text:t})}warn(t){return this.stopAndPersist({symbol:k.warning,text:t})}info(t){return this.stopAndPersist({symbol:k.info,text:t})}stopAndPersist(t={}){if(this.#F)return this;let r=t.prefixText??this.#s,u=this.#E(r," "),i=t.symbol??" ",D=t.text??this.text,s=typeof D=="string"?(i?" ":"")+D:"",a=t.suffixText??this.#o,f=this.#g(a," "),p=u+i+s+f+`
10
10
  `;return this.stop(),this.#u.write(p),this}};function zt(e){return new He(e)}async function Kt(e,t){let r=typeof e=="function",u=typeof e.then=="function";if(!r&&!u)throw new TypeError("Parameter `action` must be a Function or a Promise");let{successText:i,failText:D}=typeof t=="object"?t:{successText:void 0,failText:void 0},o=zt(t).start();try{let a=await(r?e(o):e);return o.succeed(i===void 0?void 0:typeof i=="string"?i:i(a)),a}catch(s){throw o.fail(D===void 0?void 0:typeof D=="string"?D:D(s)),s}}import{existsSync as Hl}from"fs";var Dr=ue(ir(),1);import{dirname as Jn,join as Ze}from"path";import{existsSync as Zn,readFileSync as Qn}from"fs";import{promises as nr}from"fs";import{existsSync as Kn,mkdirSync as Xn}from"fs";var H=class{static ensureDir(t){Kn(t)||Xn(t,{recursive:!0})}};var{copyFile:es,stat:ts}=nr,Ce=class e{constructor(t,r=e.IGNORE_FILE){this.ignoreTargetPath=t;this.ignoreFile=r}static IGNORE_FILE=".gitignore.template";getIg(t=this.ignoreTargetPath){let r=Ze(t,this.ignoreFile);if(!Zn(r))return;let D=Qn(r,"utf8").split(`
11
- `).map(o=>o.trim()).filter(o=>o&&!o.startsWith("#"));return(0,Dr.default)().add(D)}async copyFiles(t,r,u,i){let D=await nr.readdir(t);await Promise.all(D.map(async o=>{let s=Ze(t,o),a=Ze(r,o);if(u&&u.ignores(o))return;if(H.ensureDir(Jn(a)),(await ts(s)).isDirectory())await this.copyFiles(s,a,u,i);else{if(i&&await i(s,a))return;await es(s,a)}}))}copyPaths({sourcePath:t,targetPath:r,copyCallback:u}){H.ensureDir(r);let i=this.getIg();return this.copyFiles(t,r,i,u)}};var ID=ue(qD(),1);import{readFileSync as Ll,writeFileSync as kl,existsSync as $l}from"fs";var me=class{constructor(){}isJSONFilePath(t){return t.endsWith(".json")||t.endsWith(".json.template")}isTemplateFilePath(t){return t.endsWith(".template")}getRealTemplateFilePath(t){return t.replace(".template","")}readFile(t){return Ll(t,"utf-8")}readJSONFile(t){return JSON.parse(this.readFile(t))}writeFile(t,r){kl(this.getRealTemplateFilePath(t),r,{encoding:"utf-8"})}replaceFile(t,r){let u=this.readFile(t);return Object.keys(r).forEach(i=>{let D=r[i];u=u.replace(new RegExp(`\\[TPL:${i}\\]`,"g"),typeof D=="string"?D:JSON.stringify(D))}),u}mergeJSONFile(t,r){let u=this.readJSONFile(t),i=(0,ID.default)(r,u);this.writeFile(t,JSON.stringify(i,null,2))}composeConfigFile(t,r,u){if(this.isTemplateFilePath(r)){let i=this.replaceFile(r,t);if(this.isJSONFilePath(r)&&this.isJSONFilePath(u)){let D=this.getRealTemplateFilePath(u);return $l(D)?(this.mergeJSONFile(D,JSON.parse(i)),!0):(this.writeFile(D,i),!0)}return this.writeFile(u,i),!0}return!1}};var jD=["pack-app"],Be=class{ora;context;subPackages;copyer;compose;constructor(t){let r=t.options?.templateRootPath;if(!r)throw new Error("template path not exit");if(!Hl(r))throw new Error("template path not exit");this.ora=Kt,this.context=new Ul(t),this.subPackages=["node-lib","react-app"],this.copyer=new Ce(N(this.context.options.configsRootPath,"_common")),this.compose=new me}get logger(){return this.context.logger}async steps(t){try{return await Wl.prompt(t)}catch(r){throw r.isTtyError,this.logger.error(r),r}}async action({label:t,task:r}){let u=r();u instanceof Promise||(u=Promise.resolve(u));let i=t;return this.ora(u,i),u}isPackageTemplate(t){return jD.includes(t)}async getGeneratorContext(){let t=_t(this.subPackages,jD),r=await this.steps(t);if(this.isPackageTemplate(r.template)){let u=mt(this.subPackages),i=await this.steps(u);Object.assign(r,i)}return r.targetPath=N(process.cwd(),r.projectName),r.releasePath=r.releasePath||"src",r}async generate(){let t=await this.getGeneratorContext();if(this.logger.debug("context is:",t,this.context.options.templateRootPath),t.subPackages){await this.action({label:"Generate Directories(subPackages)",task:async()=>{await this.generateTemplateDir(t),await this.generateSubPackages(t),await this.generateConfigs(t,t.targetPath,"_common")}});return}await this.action({label:"Generate Directory",task:async()=>{await this.generateTemplateDir(t),await this.generateConfigs(t,t.targetPath,"_common"),await this.generateConfigs(t,t.targetPath,t.template)}})}async generateConfigs(t,r,u){let i=(s,a)=>(this.logger.debug("copyCallback",s,a),this.compose.composeConfigFile(t,s,a)),{configsRootPath:D,config:o}=this.context.options;if(!o){this.logger.debug("no copy config files");return}await this.copyer.copyPaths({sourcePath:N(D,u),targetPath:r,copyCallback:i})}generateTemplateDir(t){return this.copyer.copyPaths({sourcePath:N(this.context.options.templateRootPath,t.template),targetPath:t.targetPath})}async generateSubPackages(t){let{packagesNames:r="packages",subPackages:u=[],targetPath:i=""}=t,{templateRootPath:D}=this.context.options;for(let o of u){let s=N(D,o),a=N(i,r,o);this.logger.debug("copy sub package",s,a),await this.copyer.copyPaths({sourcePath:s,targetPath:a})}}};var Et={name:"@qlover/create-app",version:"0.7.5",description:"Create a new app with a single command",private:!1,type:"module",files:["dist","package.json","README.md","CHANGELOG.md"],bin:{"create-app":"dist/index.js"},scripts:{build:"tsup","create:app":"node ./dist/index.js"},repository:{type:"git",url:"git+https://github.com/qlover/fe-base.git",directory:"packages/create-app"},homepage:"https://github.com/qlover/fe-base#readme",keywords:["create-app","fe-scripts","scripts"],author:"qlover",license:"ISC",publishConfig:{access:"public"},devDependencies:{"@qlover/logger":"workspace:*",ignore:"^7.0.3",lodash:"^4.17.21",ora:"^8.1.1"},dependencies:{"@qlover/scripts-context":"workspace:*",commander:"^13.1.0",inquirer:"^12.3.2"}};function zl(){let e=new Vl;return e.version(Et.version,"-v, --version","Show version").description(Et.description).option("-d, --dry-run","Do not touch or write anything, but show the commands").option("-V, --verbose","Show more information").option("--config","Copy config files (default: true)",!0).option("--no-config","Do not copy config files"),e.parse(),e.opts()}async function Kl(){let{dryRun:e,verbose:t,...r}=zl(),u=ND("./templates"),i=ND("./configs");GD(u)||(console.error("Template is empty!"),process.exit(1)),GD(i)||(console.error("Configs is empty!"),process.exit(1)),await new Be({dryRun:e,verbose:t,options:{...r,templateRootPath:u,configsRootPath:i}}).generate()}Kl().catch(e=>{console.error(e),process.exit(1)});
11
+ `).map(o=>o.trim()).filter(o=>o&&!o.startsWith("#"));return(0,Dr.default)().add(D)}async copyFiles(t,r,u,i){let D=await nr.readdir(t);await Promise.all(D.map(async o=>{let s=Ze(t,o),a=Ze(r,o);if(u&&u.ignores(o))return;if(H.ensureDir(Jn(a)),(await ts(s)).isDirectory())await this.copyFiles(s,a,u,i);else{if(i&&await i(s,a))return;await es(s,a)}}))}copyPaths({sourcePath:t,targetPath:r,copyCallback:u}){H.ensureDir(r);let i=this.getIg();return this.copyFiles(t,r,i,u)}};var ID=ue(qD(),1);import{readFileSync as Ll,writeFileSync as kl,existsSync as $l}from"fs";var me=class{constructor(){}isJSONFilePath(t){return t.endsWith(".json")||t.endsWith(".json.template")}isTemplateFilePath(t){return t.endsWith(".template")}getRealTemplateFilePath(t){return t.replace(".template","")}readFile(t){return Ll(t,"utf-8")}readJSONFile(t){return JSON.parse(this.readFile(t))}writeFile(t,r){kl(this.getRealTemplateFilePath(t),r,{encoding:"utf-8"})}replaceFile(t,r){let u=this.readFile(t);return Object.keys(r).forEach(i=>{let D=r[i];u=u.replace(new RegExp(`\\[TPL:${i}\\]`,"g"),typeof D=="string"?D:JSON.stringify(D))}),u}mergeJSONFile(t,r){let u=this.readJSONFile(t),i=(0,ID.default)(r,u);this.writeFile(t,JSON.stringify(i,null,2))}composeConfigFile(t,r,u){if(this.isTemplateFilePath(r)){let i=this.replaceFile(r,t);if(this.isJSONFilePath(r)&&this.isJSONFilePath(u)){let D=this.getRealTemplateFilePath(u);return $l(D)?(this.mergeJSONFile(D,JSON.parse(i)),!0):(this.writeFile(D,i),!0)}return this.writeFile(u,i),!0}return!1}};var jD=["pack-app"],Be=class{ora;context;subPackages;copyer;compose;constructor(t){let r=t.options?.templateRootPath;if(!r)throw new Error("template path not exit");if(!Hl(r))throw new Error("template path not exit");this.ora=Kt,this.context=new Ul(t),this.subPackages=["node-lib","react-app"],this.copyer=new Ce(N(this.context.options.configsRootPath,"_common")),this.compose=new me}get logger(){return this.context.logger}async steps(t){try{return await Wl.prompt(t)}catch(r){throw r.isTtyError,this.logger.error(r),r}}async action({label:t,task:r}){let u=r();u instanceof Promise||(u=Promise.resolve(u));let i=t;return this.ora(u,i),u}isPackageTemplate(t){return jD.includes(t)}async getGeneratorContext(){let t=_t(this.subPackages,jD),r=await this.steps(t);if(this.isPackageTemplate(r.template)){let u=mt(this.subPackages),i=await this.steps(u);Object.assign(r,i)}return r.targetPath=N(process.cwd(),r.projectName),r.releasePath=r.releasePath||"src",r}async generate(){let t=await this.getGeneratorContext();if(this.logger.debug("context is:",t,this.context.options.templateRootPath),t.subPackages){await this.action({label:"Generate Directories(subPackages)",task:async()=>{await this.generateTemplateDir(t),await this.generateSubPackages(t),await this.generateConfigs(t,t.targetPath,"_common")}});return}await this.action({label:"Generate Directory",task:async()=>{await this.generateTemplateDir(t),await this.generateConfigs(t,t.targetPath,"_common"),await this.generateConfigs(t,t.targetPath,t.template)}})}async generateConfigs(t,r,u){let i=(s,a)=>(this.logger.debug("copyCallback",s,a),this.compose.composeConfigFile(t,s,a)),{configsRootPath:D,config:o}=this.context.options;if(!o){this.logger.debug("no copy config files");return}await this.copyer.copyPaths({sourcePath:N(D,u),targetPath:r,copyCallback:i})}generateTemplateDir(t){return this.copyer.copyPaths({sourcePath:N(this.context.options.templateRootPath,t.template),targetPath:t.targetPath})}async generateSubPackages(t){let{packagesNames:r="packages",subPackages:u=[],targetPath:i=""}=t,{templateRootPath:D}=this.context.options;for(let o of u){let s=N(D,o),a=N(i,r,o);this.logger.debug("copy sub package",s,a),await this.copyer.copyPaths({sourcePath:s,targetPath:a})}}};var Et={name:"@qlover/create-app",version:"0.7.7",description:"Create a new app with a single command",private:!1,type:"module",files:["dist","package.json","README.md","CHANGELOG.md"],bin:{"create-app":"dist/index.js"},scripts:{build:"tsup","create:app":"node ./dist/index.js"},repository:{type:"git",url:"git+https://github.com/qlover/fe-base.git",directory:"packages/create-app"},homepage:"https://github.com/qlover/fe-base#readme",keywords:["create-app","fe-scripts","scripts"],author:"qlover",license:"ISC",publishConfig:{access:"public"},devDependencies:{"@qlover/logger":"workspace:*",ignore:"^7.0.3",lodash:"^4.17.21",ora:"^8.1.1"},dependencies:{"@qlover/scripts-context":"workspace:*",commander:"^13.1.0",inquirer:"^12.3.2"}};function zl(){let e=new Vl;return e.version(Et.version,"-v, --version","Show version").description(Et.description).option("-d, --dry-run","Do not touch or write anything, but show the commands").option("-V, --verbose","Show more information").option("--config","Copy config files (default: true)",!0).option("--no-config","Do not copy config files"),e.parse(),e.opts()}async function Kl(){let{dryRun:e,verbose:t,...r}=zl(),u=ND("./templates"),i=ND("./configs");GD(u)||(console.error("Template is empty!"),process.exit(1)),GD(i)||(console.error("Configs is empty!"),process.exit(1)),await new Be({dryRun:e,verbose:t,options:{...r,templateRootPath:u,configsRootPath:i}}).generate()}Kl().catch(e=>{console.error(e),process.exit(1)});
@@ -0,0 +1,22 @@
1
+ # ci
2
+ NPM_TOKEN=
3
+ GITHUB_TOKEN=
4
+
5
+ # fe-scripts
6
+ FE_RELEASE_BRANCH=master
7
+ FE_RELEASE=false
8
+ FE_RELEASE_ENV=production
9
+
10
+ # ===== build
11
+ NEXT_PUBLIC_SERVER_PORT=3200
12
+
13
+ # ===== app config
14
+ NEXT_PUBLIC_USER_TOKEN_STORAGE_KEY=fe_user_token
15
+ NEXT_PUBLIC_OPEN_AI_MODELS='["gpt-4o-mini","gpt-3.5-turbo","gpt-3.5-turbo-2","gpt-4","gpt-4-32k"]'
16
+ NEXT_PUBLIC_OPEN_AI_BASE_URL=
17
+ NEXT_PUBLIC_OPEN_AI_TOKEN=sk-proj-1234567890
18
+ NEXT_PUBLIC_OPEN_AI_TOKEN_PREFIX=Bearer
19
+ NEXT_PUBLIC_OPEN_AI_REQUIRE_TOKEN=true
20
+ NEXT_PUBLIC_LOGIN_USER=admin
21
+ NEXT_PUBLIC_LOGIN_PASSWORD=prod-123456
22
+ NEXT_PUBLIC_FE_API_BASE_URL=https://feapi.example.com/
@@ -0,0 +1,58 @@
1
+ # dependencies
2
+ node_modules
3
+ .pnp
4
+ .pnp.js
5
+
6
+ # testing
7
+ /coverage
8
+
9
+ # next.js
10
+ /.next/
11
+ /out/
12
+ /build
13
+ /dist
14
+
15
+ # misc
16
+ .DS_Store
17
+ *.pem
18
+
19
+ # debug
20
+ npm-debug.log*
21
+ yarn-debug.log*
22
+ yarn-error.log*
23
+
24
+ # local env files
25
+ .env*.local
26
+ .env
27
+
28
+ # vercel
29
+ .vercel
30
+
31
+ # typescript
32
+ *.tsbuildinfo
33
+ next-env.d.ts
34
+
35
+ # cache
36
+ .cache
37
+ .eslintcache
38
+ .stylelintcache
39
+
40
+ # IDE
41
+ .idea
42
+ .vscode
43
+
44
+ # generated files
45
+ public/locales
46
+ **/vendor/**
47
+ **/*.min.js
48
+ **/*.bundle.js
49
+
50
+ # package files
51
+ package-lock.json
52
+ yarn.lock
53
+ pnpm-lock.yaml
54
+
55
+ # config files
56
+ *.config.js
57
+ *.config.mjs
58
+ *.config.cjs
@@ -0,0 +1,36 @@
1
+ This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
2
+
3
+ ## Getting Started
4
+
5
+ First, run the development server:
6
+
7
+ ```bash
8
+ npm run dev
9
+ # or
10
+ yarn dev
11
+ # or
12
+ pnpm dev
13
+ # or
14
+ bun dev
15
+ ```
16
+
17
+ Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18
+
19
+ You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20
+
21
+ This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
22
+
23
+ ## Learn More
24
+
25
+ To learn more about Next.js, take a look at the following resources:
26
+
27
+ - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28
+ - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29
+
30
+ You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
31
+
32
+ ## Deploy on Vercel
33
+
34
+ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35
+
36
+ Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
@@ -0,0 +1,25 @@
1
+ import { Ts2Locales } from '@brain-toolkit/ts2locales';
2
+ import { i18nConfig } from '../config/i18n';
3
+ import { join } from 'path';
4
+ import { readdirSync } from 'fs';
5
+
6
+ export async function generateLocales() {
7
+ const locales = i18nConfig.supportedLngs as unknown as string[];
8
+ const options = readdirSync('./config/Identifier')
9
+ .map((file) => ({
10
+ file,
11
+ name: file.replace('.ts', ''),
12
+ path: join('./config/Identifier', file)
13
+ }))
14
+ .map(({ path }) => ({
15
+ source: path,
16
+ // You can use namespace
17
+ // target: `./public/locales/{{lng}}/{{${name}}}.json`
18
+ target: `./public/locales/{{lng}}/common.json`
19
+ }));
20
+
21
+ const ts2Locale = new Ts2Locales(locales);
22
+ for (const value of options) {
23
+ await ts2Locale.generate(value);
24
+ }
25
+ }
@@ -0,0 +1,45 @@
1
+ import type { AppConfig } from '@/base/cases/AppConfig';
2
+ import type { I18nService } from '@/base/services/I18nService';
3
+ import type * as CorekitBridge from '@qlover/corekit-bridge';
4
+ import type * as FeCorekit from '@qlover/fe-corekit';
5
+ import type * as Logger from '@qlover/logger';
6
+
7
+ /**
8
+ * IOC identifier
9
+ */
10
+ export const IOCIdentifier = Object.freeze({
11
+ JSONSerializer: 'JSONSerializer',
12
+ Logger: 'Logger',
13
+ AppConfig: 'AppConfig',
14
+ DialogHandler: 'DialogHandler',
15
+ LocalStorage: 'LocalStorage',
16
+ LocalStorageEncrypt: 'LocalStorageEncrypt',
17
+ CookieStorage: 'CookieStorage',
18
+ I18nServiceInterface: 'I18nServiceInterface'
19
+ });
20
+
21
+ export const I = IOCIdentifier;
22
+
23
+ /**
24
+ * IOC identifier map
25
+ *
26
+ * Define the implementation class corresponding to the string identifier
27
+ *
28
+ * - key: interface alias or name
29
+ * - value: implementation class
30
+ */
31
+ export interface IOCIdentifierMap {
32
+ [IOCIdentifier.JSONSerializer]: FeCorekit.JSONSerializer;
33
+ [IOCIdentifier.Logger]: Logger.Logger;
34
+ [IOCIdentifier.LocalStorage]: FeCorekit.SyncStorage<
35
+ unknown,
36
+ FeCorekit.ObjectStorageOptions
37
+ >;
38
+ [IOCIdentifier.LocalStorageEncrypt]: FeCorekit.SyncStorage<
39
+ unknown,
40
+ FeCorekit.ObjectStorageOptions
41
+ >;
42
+ [IOCIdentifier.CookieStorage]: CorekitBridge.CookieStorage;
43
+ [IOCIdentifier.AppConfig]: AppConfig;
44
+ [IOCIdentifier.I18nServiceInterface]: I18nService;
45
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @description 本地未找到 user token
3
+ * @localZh 本地未找到 user token
4
+ * @localEn Local no user token
5
+ */
6
+ export const LOCAL_NO_USER_TOKEN = 'err__local__no__user__token';
7
+
8
+ /**
9
+ * @description 全局未找到 window
10
+ * @localZh 全局未找到 window
11
+ * @localEn Global no window
12
+ */
13
+ export const GLOBAL_NO_WINDOW = 'err__global__no__window';
14
+
15
+ /**
16
+ * @description 必须在 PageProvider 中使用
17
+ * @localZh 必须在 PageProvider 中使用
18
+ * @localEn Must be used in PageProvider
19
+ */
20
+ export const WITHIN_PAGE_PROVIDER = 'err__within__page__provider';
21
+
22
+ /**
23
+ * @description 响应内容没有 token 值
24
+ * @localZh 响应内容没有 token 值
25
+ * @localEn Response not token value
26
+ */
27
+ export const RES_NO_TOKEN = 'err__response__no__token';
28
+
29
+ /**
30
+ * @description 未找到组件
31
+ * @localZh 未找到组件
32
+ * @localEn Not found component
33
+ */
34
+ export const NOT_FOUND_COMPONENT = 'err__not__found__component';
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @description Theme switcher default theme label
3
+ * @localZh 默认主题
4
+ * @localEn Default Theme
5
+ */
6
+ export const HEADER_THEME_DEFAULT = 'header__theme__default';
7
+
8
+ /**
9
+ * @description Theme switcher dark theme label
10
+ * @localZh 暗色主题
11
+ * @localEn Dark Theme
12
+ */
13
+ export const HEADER_THEME_DARK = 'header__theme__dark';
14
+
15
+ /**
16
+ * @description Theme switcher pink theme label
17
+ * @localZh 粉色主题
18
+ * @localEn Pink Theme
19
+ */
20
+ export const HEADER_THEME_PINK = 'header__theme__pink';
21
+
22
+ /**
23
+ * @description logout dialog title
24
+ * @localZh 登出
25
+ * @localEn Logout
26
+ */
27
+ export const AUTH_LOGOUT_DIALOG_TITLE = 'auth__logout__dialog__title';
28
+
29
+ /**
30
+ * @description logout dialog content
31
+ * @localZh 确定要登出吗?
32
+ * @localEn Are you sure you want to logout?
33
+ */
34
+ export const AUTH_LOGOUT_DIALOG_CONTENT = 'auth__logout__dialog__content';
35
+
36
+ /**
37
+ * @description 404 page title
38
+ * @localZh 404 页面未找到
39
+ * @localEn 404 Page Not Found
40
+ */
41
+ export const PAGE_404_TITLE = 'page__404__title';
42
+
43
+ /**
44
+ * @description 404 page description
45
+ * @localZh 404 页面描述
46
+ * @localEn 404 Page Description
47
+ */
48
+ export const PAGE_404_DESCRIPTION = 'page__404__description';
49
+
50
+ /**
51
+ * @description 500 page title
52
+ * @localZh 500 页面错误
53
+ * @localEn 500 Page Error
54
+ */
55
+ export const PAGE_500_TITLE = 'page__500__title';
56
+
57
+ /**
58
+ * @description 500 page description
59
+ * @localZh 500 页面描述
60
+ * @localEn 500 Page Description
61
+ */
62
+ export const PAGE_500_DESCRIPTION = 'page__500__description';