@qlover/create-app 0.10.1 → 0.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/CHANGELOG.md +178 -0
  2. package/dist/configs/_common/.github/workflows/general-check.yml +1 -1
  3. package/dist/configs/_common/.github/workflows/release.yml +2 -2
  4. package/dist/index.cjs +4 -4
  5. package/dist/index.js +4 -4
  6. package/dist/templates/next-app/config/IOCIdentifier.ts +2 -2
  7. package/dist/templates/next-app/config/Identifier/common/common.ts +14 -0
  8. package/dist/templates/next-app/config/Identifier/pages/index.ts +1 -0
  9. package/dist/templates/next-app/config/Identifier/pages/page.about.ts +20 -0
  10. package/dist/templates/next-app/config/common.ts +1 -1
  11. package/dist/templates/next-app/config/cookies.ts +23 -0
  12. package/dist/templates/next-app/config/i18n/AboutI18n.ts +14 -0
  13. package/dist/templates/next-app/config/i18n/i18nConfig.ts +3 -1
  14. package/dist/templates/next-app/config/i18n/index.ts +1 -0
  15. package/dist/templates/next-app/config/i18n/loginI18n.ts +8 -0
  16. package/dist/templates/next-app/config/theme.ts +4 -0
  17. package/dist/templates/next-app/eslint.config.mjs +9 -2
  18. package/dist/templates/next-app/next.config.ts +1 -0
  19. package/dist/templates/next-app/package.json +17 -6
  20. package/dist/templates/next-app/public/locales/en.json +5 -0
  21. package/dist/templates/next-app/public/locales/zh.json +5 -0
  22. package/dist/templates/next-app/src/app/[locale]/admin/AdminI18nProvider.tsx +37 -0
  23. package/dist/templates/next-app/src/app/[locale]/admin/layout.tsx +30 -6
  24. package/dist/templates/next-app/src/app/[locale]/admin/locales/page.tsx +1 -1
  25. package/dist/templates/next-app/src/app/[locale]/layout.tsx +47 -10
  26. package/dist/templates/next-app/src/app/[locale]/login/LoginForm.tsx +1 -1
  27. package/dist/templates/next-app/src/app/[locale]/login/page.tsx +22 -10
  28. package/dist/templates/next-app/src/app/[locale]/page.tsx +23 -8
  29. package/dist/templates/next-app/src/app/[locale]/register/page.tsx +21 -9
  30. package/dist/templates/next-app/src/app/api/admin/locales/create/route.ts +7 -28
  31. package/dist/templates/next-app/src/app/api/admin/locales/import/route.ts +7 -34
  32. package/dist/templates/next-app/src/app/api/admin/locales/route.ts +12 -34
  33. package/dist/templates/next-app/src/app/api/admin/locales/update/route.ts +7 -26
  34. package/dist/templates/next-app/src/app/api/admin/users/route.ts +14 -33
  35. package/dist/templates/next-app/src/app/api/locales/json/route.ts +13 -25
  36. package/dist/templates/next-app/src/app/api/user/login/route.ts +6 -46
  37. package/dist/templates/next-app/src/app/api/user/logout/route.ts +5 -24
  38. package/dist/templates/next-app/src/app/api/user/register/route.ts +6 -45
  39. package/dist/templates/next-app/src/app/manifest.ts +16 -0
  40. package/dist/templates/next-app/src/app/robots.txt +2 -0
  41. package/dist/templates/next-app/src/base/cases/AdminPageManager.ts +3 -3
  42. package/dist/templates/next-app/src/base/cases/AppConfig.ts +14 -13
  43. package/dist/templates/next-app/src/base/cases/Datetime.ts +3 -3
  44. package/dist/templates/next-app/src/base/cases/DialogErrorPlugin.ts +8 -2
  45. package/dist/templates/next-app/src/base/cases/DialogHandler.ts +30 -4
  46. package/dist/templates/next-app/src/base/cases/InversifyContainer.ts +16 -4
  47. package/dist/templates/next-app/src/base/cases/NavigateBridge.ts +20 -4
  48. package/dist/templates/next-app/src/base/cases/RequestEncryptPlugin.ts +8 -2
  49. package/dist/templates/next-app/src/base/cases/ResourceState.ts +3 -3
  50. package/dist/templates/next-app/src/base/cases/RouterService.ts +28 -10
  51. package/dist/templates/next-app/src/base/cases/StringEncryptor.ts +14 -2
  52. package/dist/templates/next-app/src/base/cases/TranslateI18nInterface.ts +1 -1
  53. package/dist/templates/next-app/src/base/cases/UserServiceApi.ts +20 -5
  54. package/dist/templates/next-app/src/base/cases/ZodColumnBuilder.ts +31 -8
  55. package/dist/templates/next-app/src/base/port/AdminLayoutInterface.ts +4 -1
  56. package/dist/templates/next-app/src/base/port/AppApiInterface.ts +22 -0
  57. package/dist/templates/next-app/src/base/port/I18nServiceInterface.ts +27 -7
  58. package/dist/templates/next-app/src/base/port/IOCInterface.ts +9 -0
  59. package/dist/templates/next-app/src/base/services/AdminPageEvent.ts +1 -1
  60. package/dist/templates/next-app/src/base/services/AdminPageScheduler.ts +3 -3
  61. package/dist/templates/next-app/src/base/services/I18nService.ts +20 -10
  62. package/dist/templates/next-app/src/base/services/ResourceService.ts +32 -11
  63. package/dist/templates/next-app/src/base/services/UserService.ts +12 -3
  64. package/dist/templates/next-app/src/base/services/adminApi/AdminLocalesApi.ts +9 -6
  65. package/dist/templates/next-app/src/base/services/adminApi/AdminUserApi.ts +20 -5
  66. package/dist/templates/next-app/src/base/services/appApi/AppApiPlugin.ts +21 -4
  67. package/dist/templates/next-app/src/base/services/appApi/AppUserApi.ts +12 -3
  68. package/dist/templates/next-app/src/base/services/appApi/AppUserApiBootstrap.ts +10 -2
  69. package/dist/templates/next-app/src/base/types/{PageProps.ts → AppPageRouter.ts} +4 -1
  70. package/dist/templates/next-app/src/base/types/PagesRouter.ts +9 -0
  71. package/dist/templates/next-app/src/core/bootstraps/BootstrapClient.ts +20 -6
  72. package/dist/templates/next-app/src/core/bootstraps/BootstrapServer.ts +27 -9
  73. package/dist/templates/next-app/src/core/bootstraps/BootstrapsRegistry.ts +6 -4
  74. package/dist/templates/next-app/src/core/clientIoc/ClientIOC.ts +39 -9
  75. package/dist/templates/next-app/src/core/clientIoc/ClientIOCRegister.ts +9 -2
  76. package/dist/templates/next-app/src/core/serverIoc/ServerIOC.ts +37 -10
  77. package/dist/templates/next-app/src/core/serverIoc/ServerIOCRegister.ts +9 -2
  78. package/dist/templates/next-app/src/i18n/loadMessages.ts +103 -0
  79. package/dist/templates/next-app/src/i18n/request.ts +3 -22
  80. package/dist/templates/next-app/src/pages/[locale]/about.tsx +61 -0
  81. package/dist/templates/next-app/src/pages/_app.tsx +50 -0
  82. package/dist/templates/next-app/src/pages/_document.tsx +13 -0
  83. package/dist/templates/next-app/src/{middleware.ts → proxy.ts} +2 -1
  84. package/dist/templates/next-app/src/server/AppErrorApi.ts +1 -1
  85. package/dist/templates/next-app/src/server/AppPageRouteParams.ts +107 -0
  86. package/dist/templates/next-app/src/server/AppSuccessApi.ts +1 -1
  87. package/dist/templates/next-app/src/server/NextApiServer.ts +62 -0
  88. package/dist/templates/next-app/src/server/PagesRouteParams.ts +146 -0
  89. package/dist/templates/next-app/src/server/PasswordEncrypt.ts +8 -2
  90. package/dist/templates/next-app/src/server/ServerAuth.ts +20 -5
  91. package/dist/templates/next-app/src/server/{sqlBridges/SupabaseBridge.ts → SupabaseBridge.ts} +50 -8
  92. package/dist/templates/next-app/src/server/UserCredentialToken.ts +8 -2
  93. package/dist/templates/next-app/src/server/controllers/AdminLocalesController.ts +86 -0
  94. package/dist/templates/next-app/src/server/controllers/AdminUserController.ts +42 -0
  95. package/dist/templates/next-app/src/server/controllers/LocalesController.ts +36 -0
  96. package/dist/templates/next-app/src/server/controllers/UserController.ts +86 -0
  97. package/dist/templates/next-app/src/server/port/AIControllerInterface.ts +8 -0
  98. package/dist/templates/next-app/src/server/port/AdminLocalesControllerInterface.ts +21 -0
  99. package/dist/templates/next-app/src/server/port/AdminUserControllerInterface.ts +11 -0
  100. package/dist/templates/next-app/src/server/port/LocalesControllerInterface.ts +10 -0
  101. package/dist/templates/next-app/src/server/port/{ParamsHandlerInterface.ts → RouteParamsnHandlerInterface.ts} +9 -2
  102. package/dist/templates/next-app/src/server/port/ServerInterface.ts +2 -2
  103. package/dist/templates/next-app/src/server/port/UserControllerInerface.ts +8 -0
  104. package/dist/templates/next-app/src/server/port/UserServiceInterface.ts +1 -1
  105. package/dist/templates/next-app/src/server/port/ValidatorInterface.ts +2 -2
  106. package/dist/templates/next-app/src/server/repositorys/LocalesRepository.ts +31 -9
  107. package/dist/templates/next-app/src/server/repositorys/UserRepository.ts +15 -6
  108. package/dist/templates/next-app/src/server/services/AIService.ts +3 -1
  109. package/dist/templates/next-app/src/server/services/AdminAuthPlugin.ts +5 -2
  110. package/dist/templates/next-app/src/{base → server}/services/AdminLocalesService.ts +2 -2
  111. package/dist/templates/next-app/src/server/services/ApiLocaleService.ts +29 -14
  112. package/dist/templates/next-app/src/server/services/ApiUserService.ts +6 -3
  113. package/dist/templates/next-app/src/server/services/UserService.ts +12 -3
  114. package/dist/templates/next-app/src/server/validators/LocalesValidator.ts +24 -7
  115. package/dist/templates/next-app/src/server/validators/LoginValidator.ts +17 -5
  116. package/dist/templates/next-app/src/server/validators/PaginationValidator.ts +17 -11
  117. package/dist/templates/next-app/src/styles/css/antd-themes/_common/_default.css +0 -44
  118. package/dist/templates/next-app/src/styles/css/antd-themes/_common/dark.css +0 -44
  119. package/dist/templates/next-app/src/styles/css/antd-themes/_common/pink.css +0 -44
  120. package/dist/templates/next-app/src/styles/css/index.css +1 -1
  121. package/dist/templates/next-app/src/styles/css/scrollbar.css +34 -0
  122. package/dist/templates/next-app/src/uikit/components/AdminLayout.tsx +34 -11
  123. package/dist/templates/next-app/src/uikit/components/BootstrapsProvider.tsx +69 -39
  124. package/dist/templates/next-app/src/uikit/components/ClientRootProvider.tsx +64 -0
  125. package/dist/templates/next-app/src/uikit/components/ClinetRenderProvider.tsx +42 -0
  126. package/dist/templates/next-app/src/uikit/components/IOCProvider.tsx +34 -0
  127. package/dist/templates/next-app/src/uikit/components/localesImportButton/LocalesImportEvent.ts +7 -1
  128. package/dist/templates/next-app/src/uikit/components-app/AppBridge.tsx +17 -0
  129. package/dist/templates/next-app/src/uikit/components-app/AppRoutePage.tsx +112 -0
  130. package/dist/templates/next-app/src/uikit/{components → components-app}/LanguageSwitcher.tsx +15 -19
  131. package/dist/templates/next-app/src/uikit/{components → components-app}/ThemeSwitcher.tsx +53 -52
  132. package/dist/templates/next-app/src/uikit/components-pages/LanguageSwitcher.tsx +98 -0
  133. package/dist/templates/next-app/src/uikit/components-pages/PagesRoutePage.tsx +93 -0
  134. package/dist/templates/next-app/src/uikit/context/IOCContext.ts +16 -4
  135. package/dist/templates/next-app/src/uikit/hook/useStrictEffect.ts +32 -0
  136. package/dist/templates/next-app/tsconfig.json +3 -2
  137. package/dist/templates/react-app/__tests__/__mocks__/BootstrapTest.ts +3 -1
  138. package/dist/templates/react-app/__tests__/__mocks__/MockAppConfig.ts +19 -19
  139. package/dist/templates/react-app/__tests__/__mocks__/MockDialogHandler.ts +8 -8
  140. package/dist/templates/react-app/__tests__/__mocks__/MockLogger.ts +9 -9
  141. package/dist/templates/react-app/__tests__/__mocks__/components/TestBootstrapsProvider.tsx +1 -1
  142. package/dist/templates/react-app/__tests__/__mocks__/i18nextHttpBackend.ts +5 -5
  143. package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOC.ts +9 -5
  144. package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOCRegister.ts +8 -4
  145. package/dist/templates/react-app/__tests__/src/base/cases/I18nKeyErrorPlugin.test.ts +4 -4
  146. package/dist/templates/react-app/__tests__/src/base/cases/InversifyContainer.test.ts +5 -5
  147. package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapClient.test.ts +3 -3
  148. package/dist/templates/react-app/__tests__/src/uikit/components/chatMessage/ChatRoot.test.tsx +1 -1
  149. package/dist/templates/react-app/docs/en/components/chat-message-component.md +35 -29
  150. package/dist/templates/react-app/docs/en/components/chat-message-refactor.md +18 -5
  151. package/dist/templates/react-app/docs/en/components/message-base-list-component.md +11 -12
  152. package/dist/templates/react-app/docs/en/request.md +1 -3
  153. package/dist/templates/react-app/docs/zh/components/chat-message-component.md +35 -29
  154. package/dist/templates/react-app/docs/zh/components/chat-message-refactor.md +18 -5
  155. package/dist/templates/react-app/docs/zh/components/message-base-list-component.md +11 -12
  156. package/dist/templates/react-app/docs/zh/request.md +1 -3
  157. package/dist/templates/react-app/eslint.config.mjs +10 -5
  158. package/dist/templates/react-app/src/App.tsx +1 -1
  159. package/dist/templates/react-app/src/base/apis/feApi/FeApi.ts +2 -2
  160. package/dist/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +14 -11
  161. package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +10 -16
  162. package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +12 -10
  163. package/dist/templates/react-app/src/base/cases/AppConfig.ts +19 -19
  164. package/dist/templates/react-app/src/base/cases/DialogHandler.ts +28 -5
  165. package/dist/templates/react-app/src/base/cases/I18nKeyErrorPlugin.ts +5 -2
  166. package/dist/templates/react-app/src/base/cases/InversifyContainer.ts +16 -4
  167. package/dist/templates/react-app/src/base/cases/PublicAssetsPath.ts +1 -1
  168. package/dist/templates/react-app/src/base/cases/RequestLanguages.ts +6 -3
  169. package/dist/templates/react-app/src/base/cases/RequestLogger.ts +17 -8
  170. package/dist/templates/react-app/src/base/cases/RequestStatusCatcher.ts +4 -6
  171. package/dist/templates/react-app/src/base/cases/ResourceState.ts +3 -3
  172. package/dist/templates/react-app/src/base/cases/RouterLoader.ts +3 -3
  173. package/dist/templates/react-app/src/base/cases/TranslateI18nInterface.ts +1 -1
  174. package/dist/templates/react-app/src/base/port/ExecutorPageBridgeInterface.ts +2 -2
  175. package/dist/templates/react-app/src/base/port/IOCInterface.ts +4 -2
  176. package/dist/templates/react-app/src/base/port/JSONStoragePageBridgeInterface.ts +5 -5
  177. package/dist/templates/react-app/src/base/port/RequestPageBridgeInterface.ts +7 -7
  178. package/dist/templates/react-app/src/base/port/RouteServiceInterface.ts +8 -8
  179. package/dist/templates/react-app/src/base/port/UserServiceInterface.ts +4 -2
  180. package/dist/templates/react-app/src/base/services/BaseLayoutService.ts +3 -3
  181. package/dist/templates/react-app/src/base/services/I18nService.ts +24 -13
  182. package/dist/templates/react-app/src/base/services/IdentifierService.ts +21 -26
  183. package/dist/templates/react-app/src/base/services/RouteService.ts +8 -8
  184. package/dist/templates/react-app/src/base/services/UserBootstrap.ts +2 -2
  185. package/dist/templates/react-app/src/base/services/UserGatewayPlugin.ts +9 -5
  186. package/dist/templates/react-app/src/base/services/UserService.ts +10 -4
  187. package/dist/templates/react-app/src/core/bootstraps/BootstrapClient.ts +3 -1
  188. package/dist/templates/react-app/src/core/bootstraps/BootstrapsRegistry.ts +5 -2
  189. package/dist/templates/react-app/src/core/clientIoc/ClientIOC.ts +11 -4
  190. package/dist/templates/react-app/src/core/clientIoc/ClientIOCRegister.ts +5 -4
  191. package/dist/templates/react-app/src/pages/base/Layout.tsx +1 -1
  192. package/dist/templates/react-app/src/styles/css/antd-themes/_common/_default.css +0 -44
  193. package/dist/templates/react-app/src/styles/css/antd-themes/_common/dark.css +0 -44
  194. package/dist/templates/react-app/src/styles/css/antd-themes/_common/pink.css +0 -44
  195. package/dist/templates/react-app/src/styles/css/index.css +1 -1
  196. package/dist/templates/react-app/src/styles/css/scrollbar.css +34 -0
  197. package/dist/templates/react-app/src/uikit/bridges/ExecutorPageBridge.ts +2 -2
  198. package/dist/templates/react-app/src/uikit/bridges/JSONStoragePageBridge.ts +4 -4
  199. package/dist/templates/react-app/src/uikit/bridges/NavigateBridge.ts +8 -2
  200. package/dist/templates/react-app/src/uikit/bridges/RequestPageBridge.ts +6 -6
  201. package/dist/templates/react-app/src/uikit/components/AppRouterProvider.tsx +1 -1
  202. package/dist/templates/react-app/src/uikit/components/BootstrapsProvider.tsx +1 -3
  203. package/dist/templates/react-app/src/uikit/components/MessageBaseList.tsx +4 -1
  204. package/dist/templates/react-app/src/uikit/components/chatMessage/ChatMessageBridge.ts +39 -16
  205. package/dist/templates/react-app/src/uikit/components/chatMessage/MessageApi.ts +4 -2
  206. package/package.json +3 -3
  207. package/dist/templates/next-app/src/server/PageParams.ts +0 -66
  208. package/dist/templates/next-app/src/uikit/components/BaseHeader.tsx +0 -80
  209. package/dist/templates/next-app/src/uikit/components/BaseLayout.tsx +0 -65
  210. package/dist/templates/next-app/src/uikit/components/ComboProvider.tsx +0 -58
  211. package/dist/templates/next-app/src/uikit/components/NextIntlProvider.tsx +0 -21
  212. package/dist/templates/react-app/makes/eslint-utils.mjs +0 -195
  213. /package/dist/templates/next-app/{src/app/[locale] → public}/favicon.ico +0 -0
  214. /package/dist/templates/next-app/src/uikit/{components → components-app}/LogoutButton.tsx +0 -0
@@ -10,7 +10,7 @@ import {
10
10
  localesSchema,
11
11
  type LocalesSchema
12
12
  } from '@migrations/schema/LocalesSchema';
13
- import { I } from '@config/IOCIdentifier';
13
+ import { SupabaseBridge } from '../SupabaseBridge';
14
14
  import type {
15
15
  LocalesRepositoryInterface,
16
16
  UpsertResult
@@ -18,16 +18,19 @@ import type {
18
18
 
19
19
  @injectable()
20
20
  export class LocalesRepository implements LocalesRepositoryInterface {
21
- readonly name = 'next_app_locales';
21
+ public readonly name = 'next_app_locales';
22
22
 
23
23
  protected safeFields = Object.keys(localesSchema.shape);
24
24
 
25
25
  constructor(
26
- @inject(I.DBBridgeInterface) protected dbBridge: DBBridgeInterface,
26
+ @inject(SupabaseBridge) protected dbBridge: DBBridgeInterface,
27
27
  @inject(Datetime) protected datetime: Datetime
28
28
  ) {}
29
29
 
30
- async getAll(): Promise<LocalesSchema[]> {
30
+ /**
31
+ * @override
32
+ */
33
+ public async getAll(): Promise<LocalesSchema[]> {
31
34
  const result = await this.dbBridge.get({
32
35
  table: this.name,
33
36
  fields: this.safeFields
@@ -35,7 +38,10 @@ export class LocalesRepository implements LocalesRepositoryInterface {
35
38
  return (result.data as LocalesSchema[]) || [];
36
39
  }
37
40
 
38
- async getLocales(
41
+ /**
42
+ * @override
43
+ */
44
+ public async getLocales(
39
45
  localeName: string,
40
46
  orderBy?: BridgeOrderBy
41
47
  ): Promise<LocalesSchema[]> {
@@ -49,7 +55,10 @@ export class LocalesRepository implements LocalesRepositoryInterface {
49
55
  return data && data.length > 0 ? data : [];
50
56
  }
51
57
 
52
- async add(params: LocalesSchema): Promise<LocalesSchema[] | null> {
58
+ /**
59
+ * @override
60
+ */
61
+ public async add(params: LocalesSchema): Promise<LocalesSchema[] | null> {
53
62
  const now = this.datetime.timestampz();
54
63
  const data = {
55
64
  ...params,
@@ -66,10 +75,19 @@ export class LocalesRepository implements LocalesRepositoryInterface {
66
75
  return (result.data as LocalesSchema[]) || null;
67
76
  }
68
77
 
69
- async updateById(
78
+ /**
79
+ * @override
80
+ */
81
+ public async updateById(
70
82
  id: number,
71
83
  params: Partial<Omit<LocalesSchema, 'id' | 'created_at'>>
72
84
  ): Promise<void> {
85
+ if (!id || typeof id !== 'number') {
86
+ throw new Error(
87
+ 'ID is required and must be a number for updateById operation'
88
+ );
89
+ }
90
+
73
91
  const data = {
74
92
  ...params,
75
93
  updated_at: this.datetime.timestampz()
@@ -83,7 +101,10 @@ export class LocalesRepository implements LocalesRepositoryInterface {
83
101
  });
84
102
  }
85
103
 
86
- async pagination<T = LocalesSchema>(params: {
104
+ /**
105
+ * @override
106
+ */
107
+ public async pagination<T = LocalesSchema>(params: {
87
108
  page: number;
88
109
  pageSize: number;
89
110
  orderBy?: BridgeOrderBy;
@@ -106,13 +127,14 @@ export class LocalesRepository implements LocalesRepositoryInterface {
106
127
 
107
128
  /**
108
129
  * batch upsert data, support chunk processing and concurrency control
130
+ * @override
109
131
  * @param data - data to upsert
110
132
  * @param options - options
111
133
  * @param options.chunkSize - chunk size, default 100
112
134
  * @param options.concurrency - concurrency, default 3
113
135
  * @returns UpsertResult - contains success/failure details with returned data
114
136
  */
115
- async upsert(
137
+ public async upsert(
116
138
  data: Partial<LocalesSchema>[],
117
139
  options?: {
118
140
  chunkSize?: number;
@@ -8,7 +8,7 @@ import type { UserRepositoryInterface } from '../port/UserRepositoryInterface';
8
8
 
9
9
  @injectable()
10
10
  export class UserRepository implements UserRepositoryInterface {
11
- readonly name = 'fe_users';
11
+ public readonly name = 'fe_users';
12
12
 
13
13
  protected safeFields = [
14
14
  'created_at',
@@ -25,14 +25,17 @@ export class UserRepository implements UserRepositoryInterface {
25
25
  @inject(I.DBBridgeInterface) protected dbBridge: DBBridgeInterface
26
26
  ) {}
27
27
 
28
- getAll(): Promise<unknown> {
28
+ /**
29
+ * @override
30
+ */
31
+ public getAll(): Promise<unknown> {
29
32
  return this.dbBridge.get({ table: this.name });
30
33
  }
31
34
 
32
35
  /**
33
36
  * @override
34
37
  */
35
- async getUserByEmail(email: string): Promise<UserSchema | null> {
38
+ public async getUserByEmail(email: string): Promise<UserSchema | null> {
36
39
  const result = await this.dbBridge.get({
37
40
  table: this.name,
38
41
  where: [['email', '=', email]]
@@ -48,7 +51,7 @@ export class UserRepository implements UserRepositoryInterface {
48
51
  /**
49
52
  * @override
50
53
  */
51
- async add(params: {
54
+ public async add(params: {
52
55
  email: string;
53
56
  password: string;
54
57
  }): Promise<UserSchema[] | null> {
@@ -64,7 +67,10 @@ export class UserRepository implements UserRepositoryInterface {
64
67
  return result.data as UserSchema[];
65
68
  }
66
69
 
67
- async updateById(
70
+ /**
71
+ * @override
72
+ */
73
+ public async updateById(
68
74
  id: number,
69
75
  params: Partial<Omit<UserSchema, 'id' | 'created_at'>>
70
76
  ): Promise<void> {
@@ -75,7 +81,10 @@ export class UserRepository implements UserRepositoryInterface {
75
81
  });
76
82
  }
77
83
 
78
- async pagination<UserSchema>(params: {
84
+ /**
85
+ * @override
86
+ */
87
+ public async pagination<UserSchema>(params: {
79
88
  page: number;
80
89
  pageSize: number;
81
90
  }): Promise<PaginationInterface<UserSchema>> {
@@ -21,7 +21,9 @@ export class AIService {
21
21
  });
22
22
  }
23
23
 
24
- async completions(messages: ChatCompletionMessageParam[]): Promise<unknown> {
24
+ public async completions(
25
+ messages: ChatCompletionMessageParam[]
26
+ ): Promise<unknown> {
25
27
  const url = `${this.baseUrl}/chat/completions`;
26
28
 
27
29
  const response = await fetch(url, {
@@ -5,9 +5,12 @@ import type { BootstrapExecutorPlugin } from '@qlover/corekit-bridge';
5
5
  import type { ExecutorContext } from '@qlover/fe-corekit';
6
6
 
7
7
  export class AdminAuthPlugin implements BootstrapExecutorPlugin {
8
- pluginName = 'AdminAuthPlugin';
8
+ public pluginName = 'AdminAuthPlugin';
9
9
 
10
- async onBefore(
10
+ /**
11
+ * @override
12
+ */
13
+ public async onBefore(
11
14
  context: ExecutorContext<BootstrapServerContextValue>
12
15
  ): Promise<void> {
13
16
  const { IOC } = context.parameters;
@@ -1,9 +1,9 @@
1
1
  import { ResourceStore } from '@qlover/corekit-bridge';
2
2
  import { inject, injectable } from 'inversify';
3
+ import { ResourceState } from '@/base/cases/ResourceState';
4
+ import { AdminLocalesApi } from '@/base/services/adminApi/AdminLocalesApi';
3
5
  import { ResourceService } from '@/base/services/ResourceService';
4
6
  import type { LocalesSchema } from '@migrations/schema/LocalesSchema';
5
- import { AdminLocalesApi } from './adminApi/AdminLocalesApi';
6
- import { ResourceState } from '../cases/ResourceState';
7
7
 
8
8
  @injectable()
9
9
  export class AdminLocalesService extends ResourceService<
@@ -1,4 +1,5 @@
1
1
  import { inject, injectable } from 'inversify';
2
+ import { omit } from 'lodash';
2
3
  import { revalidateTag } from 'next/cache';
3
4
  import type { LocalesSchema } from '@migrations/schema/LocalesSchema';
4
5
  import type { LocaleType } from '@config/i18n';
@@ -20,6 +21,12 @@ export type ImportLocalesData = {
20
21
  };
21
22
  };
22
23
 
24
+ export type GetLocalesParams = {
25
+ page: number;
26
+ pageSize: number;
27
+ orderBy?: BridgeOrderBy;
28
+ };
29
+
23
30
  @injectable()
24
31
  export class ApiLocaleService {
25
32
  constructor(
@@ -27,7 +34,7 @@ export class ApiLocaleService {
27
34
  protected localesRepository: LocalesRepositoryInterface
28
35
  ) {}
29
36
 
30
- async getLocalesJson(
37
+ public async getLocalesJson(
31
38
  localeName: string,
32
39
  orderBy?: BridgeOrderBy
33
40
  ): Promise<Record<string, string>> {
@@ -45,11 +52,9 @@ export class ApiLocaleService {
45
52
  );
46
53
  }
47
54
 
48
- async getLocales(params: {
49
- page: number;
50
- pageSize: number;
51
- orderBy?: BridgeOrderBy;
52
- }): Promise<PaginationInterface<LocalesSchema>> {
55
+ public async getLocales(
56
+ params: GetLocalesParams
57
+ ): Promise<PaginationInterface<LocalesSchema>> {
53
58
  return this.localesRepository.pagination({
54
59
  page: params.page,
55
60
  pageSize: params.pageSize,
@@ -57,30 +62,36 @@ export class ApiLocaleService {
57
62
  });
58
63
  }
59
64
 
60
- async update(data: Partial<LocalesSchema>): Promise<void> {
65
+ public async update(data: Partial<LocalesSchema>): Promise<void> {
66
+ if (!data.id || typeof data.id !== 'number') {
67
+ throw new Error(
68
+ 'ID is required and must be a number for update operation'
69
+ );
70
+ }
71
+
61
72
  await this.localesRepository.updateById(
62
- data.id!,
63
- data as Omit<LocalesSchema, 'id' | 'created_at'>
73
+ data.id,
74
+ omit(data, ['id', 'created_at'])
64
75
  );
65
76
 
66
77
  // 清除所有支持的语言的缓存
67
78
  const revalidatePromises = i18nConfig.supportedLngs.map(async (locale) => {
68
- await revalidateTag(`i18n-${locale}`);
79
+ await revalidateTag(`i18n-${locale}`, 'default');
69
80
  });
70
81
  await Promise.all(revalidatePromises);
71
82
  }
72
83
 
73
- async create(data: Partial<LocalesSchema>): Promise<void> {
84
+ public async create(data: Partial<LocalesSchema>): Promise<void> {
74
85
  await this.localesRepository.add(data as LocalesSchema);
75
86
 
76
87
  // 清除所有支持的语言的缓存
77
88
  const revalidatePromises = i18nConfig.supportedLngs.map(async (locale) => {
78
- await revalidateTag(`i18n-${locale}`);
89
+ await revalidateTag(`i18n-${locale}`, 'default');
79
90
  });
80
91
  await Promise.all(revalidatePromises);
81
92
  }
82
93
 
83
- async importLocales(data: ImportLocalesData): Promise<UpsertResult> {
94
+ public async importLocales(data: ImportLocalesData): Promise<UpsertResult> {
84
95
  const { namespace = 'common', values } = data;
85
96
 
86
97
  const result: Record<string, Record<string, string>> = {};
@@ -94,6 +105,10 @@ export class ApiLocaleService {
94
105
  result[key]!['value'] = key;
95
106
  result[key]![locale] = value;
96
107
 
108
+ if (locale === i18nConfig.fallbackLng) {
109
+ result[key]!['description'] = value;
110
+ }
111
+
97
112
  const { namespace: namespace2 } = splitI18nKey(key);
98
113
  result[key]!['namespace'] = namespace2 || namespace;
99
114
  });
@@ -111,7 +126,7 @@ export class ApiLocaleService {
111
126
  if (upsertResult.successCount > 0) {
112
127
  const revalidatePromises = i18nConfig.supportedLngs.map(
113
128
  async (locale) => {
114
- await revalidateTag(`i18n-${locale}`);
129
+ await revalidateTag(`i18n-${locale}`, 'default');
115
130
  }
116
131
  );
117
132
  await Promise.all(revalidatePromises);
@@ -2,7 +2,10 @@ import { inject, injectable } from 'inversify';
2
2
  import type { PaginationInterface } from '@/server/port/PaginationInterface';
3
3
  import type { UserSchema } from '@migrations/schema/UserSchema';
4
4
  import { UserRepository } from '../repositorys/UserRepository';
5
- import { PaginationValidator } from '../validators/PaginationValidator';
5
+ import {
6
+ type PaginationParams,
7
+ PaginationValidator
8
+ } from '../validators/PaginationValidator';
6
9
  import type { UserRepositoryInterface } from '../port/UserRepositoryInterface';
7
10
  import type { ValidatorInterface } from '../port/ValidatorInterface';
8
11
 
@@ -12,10 +15,10 @@ export class ApiUserService {
12
15
  @inject(UserRepository)
13
16
  protected userRepository: UserRepositoryInterface,
14
17
  @inject(PaginationValidator)
15
- protected paginationValidator: ValidatorInterface
18
+ protected paginationValidator: ValidatorInterface<PaginationParams>
16
19
  ) {}
17
20
 
18
- async getUsers(params: {
21
+ public async getUsers(params: {
19
22
  page: number;
20
23
  pageSize: number;
21
24
  }): Promise<PaginationInterface<UserSchema>> {
@@ -31,7 +31,10 @@ export class UserService implements UserServiceInterface {
31
31
  protected credentialToken: CrentialTokenInterface<UserCredentialTokenValue>
32
32
  ) {}
33
33
 
34
- async register(params: {
34
+ /**
35
+ * @override
36
+ */
37
+ public async register(params: {
35
38
  email: string;
36
39
  password: string;
37
40
  }): Promise<UserSchema> {
@@ -54,7 +57,10 @@ export class UserService implements UserServiceInterface {
54
57
  return omit(target, 'password') as UserSchema;
55
58
  }
56
59
 
57
- async login(params: {
60
+ /**
61
+ * @override
62
+ */
63
+ public async login(params: {
58
64
  email: string;
59
65
  password: string;
60
66
  }): Promise<UserSchema> {
@@ -81,7 +87,10 @@ export class UserService implements UserServiceInterface {
81
87
  });
82
88
  }
83
89
 
84
- async logout(): Promise<void> {
90
+ /**
91
+ * @override
92
+ */
93
+ public async logout(): Promise<void> {
85
94
  const auth = await this.userAuth.getAuth();
86
95
 
87
96
  if (!auth) {
@@ -11,8 +11,13 @@ import {
11
11
  import type { ExtendedExecutorError } from './ExtendedExecutorError';
12
12
  import type { ImportLocalesData } from '../services/ApiLocaleService';
13
13
 
14
- export class LocalesValidator implements ValidatorInterface {
15
- validate(data: unknown): void | ValidationFaildResult {
14
+ export class LocalesValidator implements ValidatorInterface<
15
+ Omit<LocalesSchema, 'id' | 'created_at' | 'updated_at'>
16
+ > {
17
+ /**
18
+ * @override
19
+ */
20
+ public validate(data: unknown): void | ValidationFaildResult {
16
21
  if (typeof data !== 'object' || data === null) {
17
22
  return {
18
23
  path: ['form'],
@@ -29,7 +34,10 @@ export class LocalesValidator implements ValidatorInterface {
29
34
  }
30
35
  }
31
36
 
32
- getThrow(
37
+ /**
38
+ * @override
39
+ */
40
+ public getThrow(
33
41
  data: unknown
34
42
  ): Omit<LocalesSchema, 'id' | 'created_at' | 'updated_at'> {
35
43
  const result = this.validate(data);
@@ -44,8 +52,11 @@ export class LocalesValidator implements ValidatorInterface {
44
52
  }
45
53
  }
46
54
 
47
- export class LocalesImportValidator implements ValidatorInterface {
48
- getHasAnyFilesLocale(
55
+ export class LocalesImportValidator implements ValidatorInterface<ImportLocalesData> {
56
+ /**
57
+ * @override
58
+ */
59
+ public getHasAnyFilesLocale(
49
60
  values: FormData
50
61
  ): { language: LocaleType; value: FormDataEntryValue }[] {
51
62
  const hasAnyFilesLocale = [];
@@ -58,7 +69,10 @@ export class LocalesImportValidator implements ValidatorInterface {
58
69
  return hasAnyFilesLocale;
59
70
  }
60
71
 
61
- async validate(data: {
72
+ /**
73
+ * @override
74
+ */
75
+ public async validate(data: {
62
76
  namespace?: string;
63
77
  values: unknown;
64
78
  }): Promise<void | ValidationFaildResult> {
@@ -99,7 +113,10 @@ export class LocalesImportValidator implements ValidatorInterface {
99
113
  }
100
114
  }
101
115
 
102
- async getThrow(data: {
116
+ /**
117
+ * @override
118
+ */
119
+ public async getThrow(data: {
103
120
  namespace?: string;
104
121
  values: unknown;
105
122
  }): Promise<ImportLocalesData> {
@@ -26,22 +26,31 @@ const passwordSchema = z
26
26
  .max(50, { message: V_PASSWORD_MAX_LENGTH })
27
27
  .regex(/^\S+$/, { message: V_PASSWORD_SPECIAL_CHARS });
28
28
 
29
- export class LoginValidator implements ValidatorInterface {
30
- validateEmail(data: unknown): void | ValidationFaildResult {
29
+ export class LoginValidator implements ValidatorInterface<LoginValidatorData> {
30
+ /**
31
+ * @override
32
+ */
33
+ public validateEmail(data: unknown): void | ValidationFaildResult {
31
34
  const emailResult = emailSchema.safeParse(data);
32
35
  if (!emailResult.success) {
33
36
  return emailResult.error.issues[0];
34
37
  }
35
38
  }
36
39
 
37
- validatePassword(data: unknown): void | ValidationFaildResult {
40
+ /**
41
+ * @override
42
+ */
43
+ public validatePassword(data: unknown): void | ValidationFaildResult {
38
44
  const passwordResult = passwordSchema.safeParse(data);
39
45
  if (!passwordResult.success) {
40
46
  return passwordResult.error.issues[0];
41
47
  }
42
48
  }
43
49
 
44
- validate(data: unknown): void | ValidationFaildResult {
50
+ /**
51
+ * @override
52
+ */
53
+ public validate(data: unknown): void | ValidationFaildResult {
45
54
  if (typeof data !== 'object' || data === null) {
46
55
  return {
47
56
  path: ['form'],
@@ -62,7 +71,10 @@ export class LoginValidator implements ValidatorInterface {
62
71
  }
63
72
  }
64
73
 
65
- getThrow(data: unknown): LoginValidatorData {
74
+ /**
75
+ * @override
76
+ */
77
+ public getThrow(data: unknown): LoginValidatorData {
66
78
  const result = this.validate(data);
67
79
 
68
80
  if (result == null) {
@@ -1,5 +1,4 @@
1
1
  import { z } from 'zod';
2
- import type { PaginationInterface } from '@/server/port/PaginationInterface';
3
2
  import { API_PAGE_INVALID } from '@config/Identifier';
4
3
  import {
5
4
  type ValidationFaildResult,
@@ -22,10 +21,19 @@ const paginationSchema = z.object({
22
21
  order: z.string().optional().default('0')
23
22
  });
24
23
 
25
- export class PaginationValidator implements ValidatorInterface {
24
+ export type PaginationParams = {
25
+ page: number;
26
+ pageSize: number;
27
+ orders?: BridgeOrderBy;
28
+ };
29
+
30
+ export class PaginationValidator implements ValidatorInterface<PaginationParams> {
26
31
  protected defaultPageSize = 10;
27
32
 
28
- validate(data: unknown): void | ValidationFaildResult {
33
+ /**
34
+ * @override
35
+ */
36
+ public validate(data: unknown): void | ValidationFaildResult {
29
37
  if (typeof data !== 'object' || data === null) {
30
38
  return {
31
39
  path: ['form'],
@@ -39,12 +47,10 @@ export class PaginationValidator implements ValidatorInterface {
39
47
  }
40
48
  }
41
49
 
42
- getThrow(data: unknown): Pick<
43
- PaginationInterface<unknown>,
44
- 'page' | 'pageSize'
45
- > & {
46
- orders: BridgeOrderBy;
47
- } {
50
+ /**
51
+ * @override
52
+ */
53
+ public getThrow<T>(data: unknown): T {
48
54
  const result = paginationSchema.safeParse(data);
49
55
  if (!result.success) {
50
56
  throw new Error(result.error.issues[0].message);
@@ -58,7 +64,7 @@ export class PaginationValidator implements ValidatorInterface {
58
64
  orders: [
59
65
  result.data.orderBy || 'updated_at',
60
66
  order == '0' || order == '1' ? (+order as 0 | 1) : 0
61
- ]
62
- };
67
+ ] as BridgeOrderBy
68
+ } as T;
63
69
  }
64
70
  }
@@ -277,48 +277,4 @@ html,
277
277
  --fe-layout-light-trigger-bg: rgb(var(--color-bg-base));
278
278
  --fe-layout-light-trigger-color: rgb(var(--text-primary));
279
279
  }
280
-
281
- /* 滚动条样式变量 */
282
- --fe-scrollbar-size: 6px;
283
- --fe-scrollbar-thumb-bg: rgba(15 23 42 / 0.2);
284
- --fe-scrollbar-thumb-hover-bg: rgba(15 23 42 / 0.3);
285
- --fe-scrollbar-track-bg: transparent;
286
-
287
- /* 滚动条样式 */
288
- ::-webkit-scrollbar {
289
- width: var(--fe-scrollbar-size);
290
- height: var(--fe-scrollbar-size);
291
- }
292
-
293
- ::-webkit-scrollbar-track {
294
- background: var(--fe-scrollbar-track-bg);
295
- border-radius: var(--fe-scrollbar-size);
296
- }
297
-
298
- ::-webkit-scrollbar-thumb {
299
- background: var(--fe-scrollbar-thumb-bg);
300
- border-radius: var(--fe-scrollbar-size);
301
- }
302
-
303
- ::-webkit-scrollbar-thumb:hover {
304
- background: var(--fe-scrollbar-thumb-hover-bg);
305
- }
306
-
307
- ::-webkit-scrollbar-corner {
308
- background: transparent;
309
- }
310
-
311
- /* 可选的细滚动条样式 */
312
- .scrollbar-thin {
313
- --fe-scrollbar-size: 4px;
314
- }
315
-
316
- /* 隐藏滚动条但保持可滚动 */
317
- .scrollbar-hidden {
318
- -ms-overflow-style: none;
319
- scrollbar-width: none;
320
- &::-webkit-scrollbar {
321
- display: none;
322
- }
323
- }
324
280
  }
@@ -230,48 +230,4 @@
230
230
  --fe-layout-light-trigger-bg: rgb(30 41 59);
231
231
  --fe-layout-light-trigger-color: rgb(var(--text-primary));
232
232
  }
233
-
234
- /* 滚动条样式变量 */
235
- --fe-scrollbar-size: 6px;
236
- --fe-scrollbar-thumb-bg: rgba(255 255 255 / 0.2);
237
- --fe-scrollbar-thumb-hover-bg: rgba(255 255 255 / 0.3);
238
- --fe-scrollbar-track-bg: transparent;
239
-
240
- /* 滚动条样式 */
241
- ::-webkit-scrollbar {
242
- width: var(--fe-scrollbar-size);
243
- height: var(--fe-scrollbar-size);
244
- }
245
-
246
- ::-webkit-scrollbar-track {
247
- background: var(--fe-scrollbar-track-bg);
248
- border-radius: var(--fe-scrollbar-size);
249
- }
250
-
251
- ::-webkit-scrollbar-thumb {
252
- background: var(--fe-scrollbar-thumb-bg);
253
- border-radius: var(--fe-scrollbar-size);
254
- }
255
-
256
- ::-webkit-scrollbar-thumb:hover {
257
- background: var(--fe-scrollbar-thumb-hover-bg);
258
- }
259
-
260
- ::-webkit-scrollbar-corner {
261
- background: transparent;
262
- }
263
-
264
- /* 可选的细滚动条样式 */
265
- .scrollbar-thin {
266
- --fe-scrollbar-size: 4px;
267
- }
268
-
269
- /* 隐藏滚动条但保持可滚动 */
270
- .scrollbar-hidden {
271
- -ms-overflow-style: none;
272
- scrollbar-width: none;
273
- &::-webkit-scrollbar {
274
- display: none;
275
- }
276
- }
277
233
  }
@@ -243,48 +243,4 @@
243
243
  --fe-layout-light-trigger-bg: var(--ant-color-bg-container);
244
244
  --fe-layout-light-trigger-color: var(--ant-color-text);
245
245
  }
246
-
247
- /* 滚动条样式变量 */
248
- --fe-scrollbar-size: 6px;
249
- --fe-scrollbar-thumb-bg: rgba(244 114 182 / 0.3);
250
- --fe-scrollbar-thumb-hover-bg: rgba(244 114 182 / 0.4);
251
- --fe-scrollbar-track-bg: transparent;
252
-
253
- /* 滚动条样式 */
254
- ::-webkit-scrollbar {
255
- width: var(--fe-scrollbar-size);
256
- height: var(--fe-scrollbar-size);
257
- }
258
-
259
- ::-webkit-scrollbar-track {
260
- background: var(--fe-scrollbar-track-bg);
261
- border-radius: var(--fe-scrollbar-size);
262
- }
263
-
264
- ::-webkit-scrollbar-thumb {
265
- background: var(--fe-scrollbar-thumb-bg);
266
- border-radius: var(--fe-scrollbar-size);
267
- }
268
-
269
- ::-webkit-scrollbar-thumb:hover {
270
- background: var(--fe-scrollbar-thumb-hover-bg);
271
- }
272
-
273
- ::-webkit-scrollbar-corner {
274
- background: transparent;
275
- }
276
-
277
- /* 可选的细滚动条样式 */
278
- .scrollbar-thin {
279
- --fe-scrollbar-size: 4px;
280
- }
281
-
282
- /* 隐藏滚动条但保持可滚动 */
283
- .scrollbar-hidden {
284
- -ms-overflow-style: none;
285
- scrollbar-width: none;
286
- &::-webkit-scrollbar {
287
- display: none;
288
- }
289
- }
290
246
  }