@qlover/create-app 0.10.0 → 0.10.2

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 (125) hide show
  1. package/CHANGELOG.md +145 -0
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/templates/next-app/config/IOCIdentifier.ts +2 -2
  5. package/dist/templates/next-app/config/Identifier/common/common.ts +14 -0
  6. package/dist/templates/next-app/config/Identifier/pages/index.ts +1 -0
  7. package/dist/templates/next-app/config/Identifier/pages/page.about.ts +20 -0
  8. package/dist/templates/next-app/config/common.ts +1 -1
  9. package/dist/templates/next-app/config/cookies.ts +23 -0
  10. package/dist/templates/next-app/config/i18n/AboutI18n.ts +14 -0
  11. package/dist/templates/next-app/config/i18n/i18nConfig.ts +3 -1
  12. package/dist/templates/next-app/config/i18n/index.ts +1 -0
  13. package/dist/templates/next-app/config/i18n/loginI18n.ts +8 -0
  14. package/dist/templates/next-app/config/theme.ts +4 -0
  15. package/dist/templates/next-app/eslint.config.mjs +4 -1
  16. package/dist/templates/next-app/migrations/schema/UserSchema.ts +17 -3
  17. package/dist/templates/next-app/next.config.ts +1 -0
  18. package/dist/templates/next-app/package.json +15 -7
  19. package/dist/templates/next-app/public/locales/en.json +5 -0
  20. package/dist/templates/next-app/public/locales/zh.json +5 -0
  21. package/dist/templates/next-app/src/app/[locale]/admin/AdminI18nProvider.tsx +37 -0
  22. package/dist/templates/next-app/src/app/[locale]/admin/layout.tsx +30 -6
  23. package/dist/templates/next-app/src/app/[locale]/admin/locales/page.tsx +1 -1
  24. package/dist/templates/next-app/src/app/[locale]/layout.tsx +47 -10
  25. package/dist/templates/next-app/src/app/[locale]/login/LoginForm.tsx +1 -1
  26. package/dist/templates/next-app/src/app/[locale]/login/page.tsx +22 -10
  27. package/dist/templates/next-app/src/app/[locale]/page.tsx +23 -8
  28. package/dist/templates/next-app/src/app/[locale]/register/page.tsx +21 -9
  29. package/dist/templates/next-app/src/app/api/admin/locales/create/route.ts +7 -28
  30. package/dist/templates/next-app/src/app/api/admin/locales/import/route.ts +7 -34
  31. package/dist/templates/next-app/src/app/api/admin/locales/route.ts +12 -34
  32. package/dist/templates/next-app/src/app/api/admin/locales/update/route.ts +7 -26
  33. package/dist/templates/next-app/src/app/api/admin/users/route.ts +14 -33
  34. package/dist/templates/next-app/src/app/api/locales/json/route.ts +13 -25
  35. package/dist/templates/next-app/src/app/api/user/login/route.ts +6 -46
  36. package/dist/templates/next-app/src/app/api/user/logout/route.ts +5 -24
  37. package/dist/templates/next-app/src/app/api/user/register/route.ts +6 -45
  38. package/dist/templates/next-app/src/app/manifest.ts +16 -0
  39. package/dist/templates/next-app/src/app/robots.txt +2 -0
  40. package/dist/templates/next-app/src/base/cases/DialogHandler.ts +1 -2
  41. package/dist/templates/next-app/src/base/cases/NavigateBridge.ts +12 -2
  42. package/dist/templates/next-app/src/base/cases/RequestEncryptPlugin.ts +4 -5
  43. package/dist/templates/next-app/src/base/cases/RouterService.ts +5 -5
  44. package/dist/templates/next-app/src/base/cases/UserServiceApi.ts +44 -29
  45. package/dist/templates/next-app/src/base/cases/ZodColumnBuilder.ts +1 -2
  46. package/dist/templates/next-app/src/base/port/AppApiInterface.ts +22 -0
  47. package/dist/templates/next-app/src/base/port/AppUserApiInterface.ts +22 -10
  48. package/dist/templates/next-app/src/base/port/IOCInterface.ts +9 -0
  49. package/dist/templates/next-app/src/base/port/UserServiceInterface.ts +17 -9
  50. package/dist/templates/next-app/src/base/services/ResourceService.ts +3 -4
  51. package/dist/templates/next-app/src/base/services/UserService.ts +37 -13
  52. package/dist/templates/next-app/src/base/services/appApi/AppApiRequester.ts +8 -7
  53. package/dist/templates/next-app/src/base/services/appApi/AppUserApi.ts +15 -26
  54. package/dist/templates/next-app/src/base/types/{PageProps.ts → AppPageRouter.ts} +4 -1
  55. package/dist/templates/next-app/src/base/types/PagesRouter.ts +9 -0
  56. package/dist/templates/next-app/src/core/bootstraps/BootstrapClient.ts +19 -5
  57. package/dist/templates/next-app/src/core/bootstraps/BootstrapServer.ts +2 -2
  58. package/dist/templates/next-app/src/core/bootstraps/BootstrapsRegistry.ts +0 -1
  59. package/dist/templates/next-app/src/core/clientIoc/ClientIOC.ts +33 -11
  60. package/dist/templates/next-app/src/core/clientIoc/ClientIOCRegister.ts +8 -5
  61. package/dist/templates/next-app/src/core/globals.ts +2 -1
  62. package/dist/templates/next-app/src/core/serverIoc/ServerIOC.ts +29 -10
  63. package/dist/templates/next-app/src/core/serverIoc/ServerIOCRegister.ts +6 -7
  64. package/dist/templates/next-app/src/i18n/loadMessages.ts +103 -0
  65. package/dist/templates/next-app/src/i18n/request.ts +3 -22
  66. package/dist/templates/next-app/src/pages/[locale]/about.tsx +61 -0
  67. package/dist/templates/next-app/src/pages/_app.tsx +50 -0
  68. package/dist/templates/next-app/src/pages/_document.tsx +13 -0
  69. package/dist/templates/next-app/src/{middleware.ts → proxy.ts} +2 -1
  70. package/dist/templates/next-app/src/server/AppPageRouteParams.ts +94 -0
  71. package/dist/templates/next-app/src/server/NextApiServer.ts +53 -0
  72. package/dist/templates/next-app/src/server/PagesRouteParams.ts +136 -0
  73. package/dist/templates/next-app/src/server/{sqlBridges/SupabaseBridge.ts → SupabaseBridge.ts} +2 -0
  74. package/dist/templates/next-app/src/server/UserCredentialToken.ts +1 -3
  75. package/dist/templates/next-app/src/server/controllers/AdminLocalesController.ts +74 -0
  76. package/dist/templates/next-app/src/server/controllers/AdminUserController.ts +39 -0
  77. package/dist/templates/next-app/src/server/controllers/LocalesController.ts +33 -0
  78. package/dist/templates/next-app/src/server/controllers/UserController.ts +77 -0
  79. package/dist/templates/next-app/src/server/port/AIControllerInterface.ts +8 -0
  80. package/dist/templates/next-app/src/server/port/AdminLocalesControllerInterface.ts +21 -0
  81. package/dist/templates/next-app/src/server/port/AdminUserControllerInterface.ts +11 -0
  82. package/dist/templates/next-app/src/server/port/LocalesControllerInterface.ts +10 -0
  83. package/dist/templates/next-app/src/server/port/{ParamsHandlerInterface.ts → RouteParamsnHandlerInterface.ts} +9 -2
  84. package/dist/templates/next-app/src/server/port/ServerInterface.ts +2 -2
  85. package/dist/templates/next-app/src/server/port/UserControllerInerface.ts +8 -0
  86. package/dist/templates/next-app/src/server/port/UserServiceInterface.ts +1 -1
  87. package/dist/templates/next-app/src/server/port/ValidatorInterface.ts +2 -2
  88. package/dist/templates/next-app/src/server/repositorys/LocalesRepository.ts +8 -2
  89. package/dist/templates/next-app/src/{base → server}/services/AdminLocalesService.ts +2 -2
  90. package/dist/templates/next-app/src/server/services/ApiLocaleService.ts +25 -10
  91. package/dist/templates/next-app/src/server/services/ApiUserService.ts +5 -2
  92. package/dist/templates/next-app/src/server/validators/LocalesValidator.ts +4 -2
  93. package/dist/templates/next-app/src/server/validators/LoginValidator.ts +1 -1
  94. package/dist/templates/next-app/src/server/validators/PaginationValidator.ts +10 -10
  95. package/dist/templates/next-app/src/styles/css/antd-themes/_common/_default.css +0 -44
  96. package/dist/templates/next-app/src/styles/css/antd-themes/_common/dark.css +0 -44
  97. package/dist/templates/next-app/src/styles/css/antd-themes/_common/pink.css +0 -44
  98. package/dist/templates/next-app/src/styles/css/index.css +1 -1
  99. package/dist/templates/next-app/src/styles/css/scrollbar.css +34 -0
  100. package/dist/templates/next-app/src/uikit/components/AdminLayout.tsx +34 -11
  101. package/dist/templates/next-app/src/uikit/components/BootstrapsProvider.tsx +69 -39
  102. package/dist/templates/next-app/src/uikit/components/ClientRootProvider.tsx +64 -0
  103. package/dist/templates/next-app/src/uikit/components/ClinetRenderProvider.tsx +42 -0
  104. package/dist/templates/next-app/src/uikit/components/IOCProvider.tsx +34 -0
  105. package/dist/templates/next-app/src/uikit/components/LocaleLink.tsx +1 -2
  106. package/dist/templates/next-app/src/uikit/components-app/AppBridge.tsx +17 -0
  107. package/dist/templates/next-app/src/uikit/components-app/AppRoutePage.tsx +112 -0
  108. package/dist/templates/next-app/src/uikit/{components → components-app}/LanguageSwitcher.tsx +15 -19
  109. package/dist/templates/next-app/src/uikit/{components → components-app}/ThemeSwitcher.tsx +53 -52
  110. package/dist/templates/next-app/src/uikit/components-pages/LanguageSwitcher.tsx +98 -0
  111. package/dist/templates/next-app/src/uikit/components-pages/PagesRoutePage.tsx +93 -0
  112. package/dist/templates/next-app/src/uikit/context/IOCContext.ts +16 -4
  113. package/dist/templates/next-app/src/uikit/hook/useStrictEffect.ts +32 -0
  114. package/dist/templates/next-app/tsconfig.json +3 -2
  115. package/dist/templates/react-app/tsconfig.app.json +1 -3
  116. package/dist/templates/react-app/tsconfig.node.json +0 -4
  117. package/dist/templates/react-app/tsconfig.test.json +1 -3
  118. package/package.json +1 -1
  119. package/dist/templates/next-app/src/server/PageParams.ts +0 -66
  120. package/dist/templates/next-app/src/uikit/components/BaseHeader.tsx +0 -80
  121. package/dist/templates/next-app/src/uikit/components/BaseLayout.tsx +0 -65
  122. package/dist/templates/next-app/src/uikit/components/ComboProvider.tsx +0 -58
  123. package/dist/templates/next-app/src/uikit/components/NextIntlProvider.tsx +0 -21
  124. /package/dist/templates/next-app/{src/app/[locale] → public}/favicon.ico +0 -0
  125. /package/dist/templates/next-app/src/uikit/{components → components-app}/LogoutButton.tsx +0 -0
@@ -1,50 +1,10 @@
1
- import { ExecutorError } from '@qlover/fe-corekit';
2
- import { NextResponse } from 'next/server';
3
- import { StringEncryptor } from '@/base/cases/StringEncryptor';
4
- import { BootstrapServer } from '@/core/bootstraps/BootstrapServer';
5
- import { AppErrorApi } from '@/server/AppErrorApi';
6
- import { AppSuccessApi } from '@/server/AppSuccessApi';
7
- import type { UserServiceInterface } from '@/server/port/UserServiceInterface';
8
- import { ServerAuth } from '@/server/ServerAuth';
9
- import { UserService } from '@/server/services/UserService';
10
- import { LoginValidator } from '@/server/validators/LoginValidator';
11
- import type { UserSchema } from '@migrations/schema/UserSchema';
1
+ import { UserController } from '@/server/controllers/UserController';
2
+ import { NextApiServer } from '@/server/NextApiServer';
12
3
  import type { NextRequest } from 'next/server';
13
4
 
14
5
  export async function POST(req: NextRequest) {
15
- const server = new BootstrapServer();
16
-
17
- const result = await server.execNoError(async ({ parameters: { IOC } }) => {
18
- const requestBody = await req.json();
19
-
20
- try {
21
- if (requestBody.password) {
22
- requestBody.password = IOC(StringEncryptor).decrypt(
23
- requestBody.password
24
- );
25
- }
26
- } catch {
27
- throw new ExecutorError(
28
- 'encrypt_password_failed',
29
- 'Encrypt password failed'
30
- );
31
- }
32
- const body = IOC(LoginValidator).getThrow(requestBody);
33
-
34
- const userService: UserServiceInterface = IOC(UserService);
35
-
36
- const user = (await userService.login(body)) as UserSchema;
37
-
38
- await IOC(ServerAuth).setAuth(user.credential_token);
39
-
40
- return user;
41
- });
42
-
43
- if (result instanceof ExecutorError) {
44
- return NextResponse.json(new AppErrorApi(result.id, result.message), {
45
- status: 400
46
- });
47
- }
48
-
49
- return NextResponse.json(new AppSuccessApi(result));
6
+ const requestBody = await req.json();
7
+ return await new NextApiServer().runWithJson(
8
+ async ({ parameters: { IOC } }) => IOC(UserController).login(requestBody)
9
+ );
50
10
  }
@@ -1,27 +1,8 @@
1
- import { ExecutorError } from '@qlover/fe-corekit';
2
- import { NextResponse } from 'next/server';
3
- import { BootstrapServer } from '@/core/bootstraps/BootstrapServer';
4
- import { AppErrorApi } from '@/server/AppErrorApi';
5
- import { AppSuccessApi } from '@/server/AppSuccessApi';
6
- import type { UserServiceInterface } from '@/server/port/UserServiceInterface';
7
- import { UserService } from '@/server/services/UserService';
1
+ import { UserController } from '@/server/controllers/UserController';
2
+ import { NextApiServer } from '@/server/NextApiServer';
8
3
 
9
4
  export async function POST() {
10
- const server = new BootstrapServer();
11
-
12
- const result = await server.execNoError(async ({ parameters: { IOC } }) => {
13
- const userService: UserServiceInterface = IOC(UserService);
14
-
15
- await userService.logout();
16
-
17
- return true;
18
- });
19
-
20
- if (result instanceof ExecutorError) {
21
- return NextResponse.json(new AppErrorApi(result.id, result.message), {
22
- status: 400
23
- });
24
- }
25
-
26
- return NextResponse.json(new AppSuccessApi(result));
5
+ return await new NextApiServer().runWithJson(
6
+ async ({ parameters: { IOC } }) => IOC(UserController).logout()
7
+ );
27
8
  }
@@ -1,50 +1,11 @@
1
- import { ExecutorError } from '@qlover/fe-corekit';
2
- import { NextResponse } from 'next/server';
3
- import { StringEncryptor } from '@/base/cases/StringEncryptor';
4
- import { BootstrapServer } from '@/core/bootstraps/BootstrapServer';
5
- import { AppErrorApi } from '@/server/AppErrorApi';
6
- import { AppSuccessApi } from '@/server/AppSuccessApi';
7
- import type { UserServiceInterface } from '@/server/port/UserServiceInterface';
8
- import { UserService } from '@/server/services/UserService';
9
- import { LoginValidator } from '@/server/validators/LoginValidator';
1
+ import { UserController } from '@/server/controllers/UserController';
2
+ import { NextApiServer } from '@/server/NextApiServer';
10
3
  import type { NextRequest } from 'next/server';
11
4
 
12
5
  export async function POST(req: NextRequest) {
13
- const server = new BootstrapServer();
6
+ const requestBody = await req.json();
14
7
 
15
- const result = await server.execNoError(async ({ parameters: { IOC } }) => {
16
- const requestBody = await req.json();
17
-
18
- try {
19
- if (requestBody.password) {
20
- requestBody.password = IOC(StringEncryptor).decrypt(
21
- requestBody.password
22
- );
23
- }
24
- } catch {
25
- throw new ExecutorError(
26
- 'encrypt_password_failed',
27
- 'Encrypt password failed'
28
- );
29
- }
30
-
31
- const body = IOC(LoginValidator).getThrow(requestBody);
32
-
33
- const userService: UserServiceInterface = IOC(UserService);
34
-
35
- const user = await userService.register({
36
- email: body.email,
37
- password: body.password
38
- });
39
-
40
- return user;
41
- });
42
-
43
- if (result instanceof ExecutorError) {
44
- return NextResponse.json(new AppErrorApi(result.id, result.message), {
45
- status: 400
46
- });
47
- }
48
-
49
- return NextResponse.json(new AppSuccessApi(result));
8
+ return await new NextApiServer().runWithJson(
9
+ async ({ parameters: { IOC } }) => IOC(UserController).register(requestBody)
10
+ );
50
11
  }
@@ -0,0 +1,16 @@
1
+ import { getTranslations } from 'next-intl/server';
2
+ import { routing } from '@/i18n/routing';
3
+ import { COMMON_MANIFEST_NAME } from '@config/Identifier';
4
+ import type { MetadataRoute } from 'next';
5
+
6
+ export default async function manifest(): Promise<MetadataRoute.Manifest> {
7
+ const t = await getTranslations({
8
+ locale: routing.defaultLocale
9
+ });
10
+
11
+ return {
12
+ name: t(COMMON_MANIFEST_NAME),
13
+ start_url: '/',
14
+ theme_color: '#101E33'
15
+ };
16
+ }
@@ -0,0 +1,2 @@
1
+ User-Agent: *
2
+ Allow: *
@@ -11,8 +11,7 @@ import type {
11
11
  import type { ModalFuncProps } from 'antd';
12
12
 
13
13
  export interface DialogHandlerOptions
14
- extends NotificationOptions,
15
- ModalFuncProps {
14
+ extends NotificationOptions, ModalFuncProps {
16
15
  content: string;
17
16
  }
18
17
 
@@ -1,16 +1,26 @@
1
- import { injectable } from 'inversify';
1
+ import { inject, injectable } from 'inversify';
2
+ import type { useRouter } from '@/i18n/routing';
3
+ import { I } from '@config/IOCIdentifier';
2
4
  import type { UIBridgeInterface } from '@qlover/corekit-bridge';
3
- import type { AppRouterInstance } from 'next/dist/shared/lib/app-router-context.shared-runtime';
5
+ import type { LoggerInterface } from '@qlover/logger';
6
+
7
+ type AppRouterInstance = ReturnType<typeof useRouter>;
4
8
 
5
9
  @injectable()
6
10
  export class NavigateBridge implements UIBridgeInterface<AppRouterInstance> {
7
11
  protected navigate: AppRouterInstance | null = null;
8
12
 
13
+ constructor(@inject(I.Logger) protected logger: LoggerInterface) {}
14
+
9
15
  setUIBridge(ui: AppRouterInstance): void {
10
16
  this.navigate = ui;
11
17
  }
12
18
 
13
19
  getUIBridge(): AppRouterInstance | null {
20
+ if (!this.navigate) {
21
+ this.logger.debug('NavigateBridge this.navigate is not set');
22
+ }
23
+
14
24
  return this.navigate;
15
25
  }
16
26
  }
@@ -6,8 +6,9 @@ import type {
6
6
  RequestAdapterConfig
7
7
  } from '@qlover/fe-corekit';
8
8
 
9
- export interface RequestEncryptPluginProps<Request = unknown>
10
- extends RequestAdapterConfig<Request> {
9
+ export interface RequestEncryptPluginProps<
10
+ Request = unknown
11
+ > extends RequestAdapterConfig<Request> {
11
12
  /**
12
13
  * 加密密码在 HTTP 请求中
13
14
  *
@@ -18,9 +19,7 @@ export interface RequestEncryptPluginProps<Request = unknown>
18
19
  encryptProps?: string[] | string;
19
20
  }
20
21
 
21
- export class RequestEncryptPlugin
22
- implements ExecutorPlugin<RequestEncryptPluginProps>
23
- {
22
+ export class RequestEncryptPlugin implements ExecutorPlugin<RequestEncryptPluginProps> {
24
23
  readonly pluginName = 'RequestEncryptPlugin';
25
24
 
26
25
  constructor(protected encryptor: Encryptor<string, string>) {}
@@ -13,12 +13,8 @@ export class RouterService implements RouterInterface {
13
13
  protected uiBridge: UIBridgeInterface<AppRouterInstance>
14
14
  ) {}
15
15
 
16
- protected padLocaleHref(href: RouterPathname): string {
17
- return `/${this.locale}${href === '/' ? '' : href}`;
18
- }
19
-
20
16
  goto(href: RouterPathname): void {
21
- this.uiBridge.getUIBridge()?.push(this.padLocaleHref(href));
17
+ this.uiBridge.getUIBridge()?.push(href as string);
22
18
  }
23
19
 
24
20
  gotoHome(): void {
@@ -29,6 +25,10 @@ export class RouterService implements RouterInterface {
29
25
  this.goto('/login');
30
26
  }
31
27
 
28
+ replaceHome(): void {
29
+ this.uiBridge.getUIBridge()?.replace('/');
30
+ }
31
+
32
32
  setLocale(locale: string): void {
33
33
  this.locale = locale;
34
34
  }
@@ -1,48 +1,63 @@
1
1
  import { inject, injectable } from 'inversify';
2
- import type { UserSchema } from '@migrations/schema/UserSchema';
2
+ import { omit } from 'lodash';
3
+ import type { LoginValidatorData } from '@/server/validators/LoginValidator';
4
+ import {
5
+ isWebUserSchema,
6
+ type UserCredential,
7
+ type UserSchema
8
+ } from '@migrations/schema/UserSchema';
3
9
  import { AppUserApi } from '../services/appApi/AppUserApi';
4
- import type { AppApiSuccessInterface } from '../port/AppApiInterface';
5
10
  import type { AppUserApiInterface } from '../port/AppUserApiInterface';
6
- import type {
7
- LoginResponseData,
8
- UserAuthApiInterface,
9
- UserAuthStoreInterface
10
- } from '@qlover/corekit-bridge';
11
+ import type { UserServiceGateway } from '@qlover/corekit-bridge';
11
12
 
12
13
  @injectable()
13
- export class UserServiceApi implements UserAuthApiInterface<UserSchema> {
14
- protected store: UserAuthStoreInterface<UserSchema> | null = null;
15
-
14
+ export class UserServiceApi implements UserServiceGateway<
15
+ UserSchema,
16
+ UserCredential
17
+ > {
16
18
  constructor(@inject(AppUserApi) protected appUserApi: AppUserApiInterface) {}
17
19
 
18
- getStore(): UserAuthStoreInterface<UserSchema> | null {
19
- return this.store;
20
+ getUserInfo(_params?: unknown): Promise<UserSchema | null> {
21
+ if (_params && isWebUserSchema(_params).success) {
22
+ return Promise.resolve(omit(_params, 'credential_token') as UserSchema);
23
+ }
24
+
25
+ return Promise.resolve(null);
20
26
  }
21
- setStore(store: UserAuthStoreInterface<UserSchema>): void {
22
- this.store = store;
27
+
28
+ refreshUserInfo<Params>(
29
+ _params?: Params | undefined
30
+ ): Promise<UserSchema | null> {
31
+ return this.getUserInfo(_params);
23
32
  }
24
33
 
25
- async login(params: {
26
- email: string;
27
- password: string;
28
- }): Promise<LoginResponseData> {
34
+ async login(params: LoginValidatorData): Promise<UserCredential> {
29
35
  const response = await this.appUserApi.login(params);
30
- return (response as AppApiSuccessInterface).data as LoginResponseData;
36
+
37
+ if (!response.data.success) {
38
+ throw response;
39
+ }
40
+
41
+ return response.data.data as UserCredential;
31
42
  }
32
43
 
33
- async register(params: {
34
- email: string;
35
- password: string;
36
- }): Promise<LoginResponseData> {
44
+ async register(params: LoginValidatorData): Promise<UserSchema> {
37
45
  const response = await this.appUserApi.register(params);
38
- return (response as AppApiSuccessInterface).data as LoginResponseData;
39
- }
40
46
 
41
- async logout(): Promise<void> {
42
- await this.appUserApi.logout();
47
+ if (!response.data.success) {
48
+ throw response;
49
+ }
50
+
51
+ return response.data.data as UserSchema;
43
52
  }
44
53
 
45
- getUserInfo(loginData: LoginResponseData): Promise<UserSchema> {
46
- return Promise.resolve(loginData as unknown as UserSchema);
54
+ async logout<P = unknown, Result = void>(params?: P): Promise<Result> {
55
+ const response = await this.appUserApi.logout(params);
56
+
57
+ if (!response.data.success) {
58
+ throw response;
59
+ }
60
+
61
+ return response.data.data as Result;
47
62
  }
48
63
  }
@@ -33,8 +33,7 @@ export const ZodType2RenderFormMap = {
33
33
  export class ZodColumnBuilder<
34
34
  Value extends ZodRawShape,
35
35
  Input extends ZodObject<Value>
36
- > implements ZodBuilderInterface<Input, ResourceTableOption<z.infer<Input>>>
37
- {
36
+ > implements ZodBuilderInterface<Input, ResourceTableOption<z.infer<Input>>> {
38
37
  protected optionMap: OptionMap<Value, Input>;
39
38
 
40
39
  constructor(
@@ -12,3 +12,25 @@ export interface AppApiSuccessInterface<T = unknown> {
12
12
  export type AppApiResult<T = unknown> =
13
13
  | AppApiErrorInterface
14
14
  | AppApiSuccessInterface<T>;
15
+
16
+ export function isAppApiSuccessInterface(
17
+ result: unknown
18
+ ): result is AppApiSuccessInterface {
19
+ return (
20
+ typeof result === 'object' &&
21
+ result !== null &&
22
+ 'success' in result &&
23
+ result.success === true
24
+ );
25
+ }
26
+
27
+ export function isAppApiErrorInterface(
28
+ result: unknown
29
+ ): result is AppApiErrorInterface {
30
+ return (
31
+ typeof result === 'object' &&
32
+ result !== null &&
33
+ 'success' in result &&
34
+ result.success === false
35
+ );
36
+ }
@@ -1,15 +1,27 @@
1
- import type { AppApiResult } from './AppApiInterface';
1
+ import type { LoginValidatorData } from '@/server/validators/LoginValidator';
2
+ import type { UserSchema } from '@migrations/schema/UserSchema';
3
+ import type { AppApiTransaction } from '../services/appApi/AppApiRequester';
4
+
5
+ export type UserApiLoginTransaction = AppApiTransaction<
6
+ LoginValidatorData,
7
+ UserSchema
8
+ >;
9
+
10
+ export type UserApiRegisterTransaction = AppApiTransaction<
11
+ LoginValidatorData,
12
+ UserSchema
13
+ >;
14
+
15
+ export type UserApiLogoutTransaction = AppApiTransaction<unknown, void>;
2
16
 
3
17
  export interface AppUserApiInterface {
4
- login(params: {
5
- email: string;
6
- password: string;
7
- }): Promise<AppApiResult<unknown>>;
18
+ login(
19
+ params: UserApiLoginTransaction['data']
20
+ ): Promise<UserApiLoginTransaction['response']>;
8
21
 
9
- register(params: {
10
- email: string;
11
- password: string;
12
- }): Promise<AppApiResult<unknown>>;
22
+ register(
23
+ params: UserApiRegisterTransaction['data']
24
+ ): Promise<UserApiRegisterTransaction['response']>;
13
25
 
14
- logout(): Promise<AppApiResult<unknown>>;
26
+ logout(params?: unknown): Promise<UserApiLogoutTransaction['response']>;
15
27
  }
@@ -21,4 +21,13 @@ export interface IOCInterface<
21
21
  create(
22
22
  options: IocRegisterOptions
23
23
  ): IOCFunctionInterface<IdentifierMap, IOCContainer>;
24
+
25
+ /**
26
+ * 该方法主要用于在应用启动前注册所有依赖
27
+ *
28
+ * 因为ssr渲染的原因可能需要在一些特定的环境下注册一些依赖
29
+ *
30
+ * @param options - 注册选项
31
+ */
32
+ register(options?: IocRegisterOptions): void;
24
33
  }
@@ -1,12 +1,20 @@
1
- import { UserAuthService } from '@qlover/corekit-bridge';
2
- import type { UserSchema } from '@migrations/schema/UserSchema';
3
- import type { ExecutorPlugin } from '@qlover/fe-corekit';
1
+ import type { UserCredential, UserSchema } from '@migrations/schema/UserSchema';
2
+ import type { UserService as CorekitBridgeUserServiceInterface } from '@qlover/corekit-bridge';
4
3
 
5
- export abstract class UserServiceInterface
6
- extends UserAuthService<UserSchema>
7
- implements ExecutorPlugin
8
- {
9
- readonly pluginName = 'UserService';
4
+ export interface UserServiceInterface extends CorekitBridgeUserServiceInterface<
5
+ UserSchema,
6
+ UserCredential
7
+ > {
8
+ // You can add your own methods here
10
9
 
11
- abstract getToken(): string | null;
10
+ /**
11
+ * Get the user token
12
+ *
13
+ * This is a extends method from the corekit-bridge UserServiceInterface.
14
+ */
15
+ getToken(): string;
16
+
17
+ isUserInfo(value: unknown): value is UserSchema;
18
+
19
+ isUserCredential(value: unknown): value is UserCredential;
12
20
  }
@@ -11,10 +11,9 @@ import type { PaginationInterface } from '@/server/port/PaginationInterface';
11
11
 
12
12
  export class ResourceService<
13
13
  T,
14
- Store extends
15
- ResourceStore<ResourceStateInterface> = ResourceStore<ResourceStateInterface>
16
- > implements ResourceServiceInterface<T>
17
- {
14
+ Store extends ResourceStore<ResourceStateInterface> =
15
+ ResourceStore<ResourceStateInterface>
16
+ > implements ResourceServiceInterface<T> {
18
17
  readonly unionKey: string = 'id';
19
18
 
20
19
  constructor(
@@ -1,24 +1,48 @@
1
+ import { UserService as CorekitBridgeUserService } from '@qlover/corekit-bridge';
1
2
  import { injectable, inject } from 'inversify';
2
- import type { UserSchema } from '@migrations/schema/UserSchema';
3
- import { AppConfig } from '../cases/AppConfig';
3
+ import { isObject, isString } from 'lodash';
4
+ import {
5
+ userSchema,
6
+ type UserCredential,
7
+ type UserSchema
8
+ } from '@migrations/schema/UserSchema';
4
9
  import { UserServiceApi } from '../cases/UserServiceApi';
5
- import { UserServiceInterface } from '../port/UserServiceInterface';
6
- import type { UserAuthApiInterface } from '@qlover/corekit-bridge';
10
+ import type { UserServiceInterface } from '../port/UserServiceInterface';
11
+ import type { UserServiceGateway } from '@qlover/corekit-bridge';
7
12
 
8
13
  @injectable()
9
- export class UserService extends UserServiceInterface {
14
+ export class UserService
15
+ extends CorekitBridgeUserService<UserSchema, UserCredential>
16
+ implements UserServiceInterface
17
+ {
10
18
  constructor(
11
- @inject(AppConfig) protected appConfig: AppConfig,
12
- @inject(UserServiceApi) protected userApi: UserAuthApiInterface<UserSchema>
19
+ @inject(UserServiceApi)
20
+ userApi: UserServiceGateway<UserSchema, UserCredential>
13
21
  ) {
14
- super(userApi, {
15
- credentialStorage: {
16
- key: appConfig.userTokenKey
17
- }
22
+ super({
23
+ gateway: userApi
24
+ // next-js ssr 将 credential 存储在 cookie 中无需存储用户信息到本地
25
+ // store: {
26
+ // storageKey: appConfig.userInfoKey,
27
+ // credentialStorageKey: appConfig.userTokenKey,
28
+ // persistUserInfo: true,
29
+ // }
18
30
  });
19
31
  }
20
32
 
21
- getToken(): string | null {
22
- return this.store.getCredential();
33
+ getToken(): string {
34
+ return this.store.getCredential()?.credential_token ?? '';
35
+ }
36
+
37
+ isUserInfo(value: unknown): value is UserSchema {
38
+ return userSchema.safeParse(value).success;
39
+ }
40
+
41
+ isUserCredential(value: unknown): value is UserCredential {
42
+ return (
43
+ isObject(value) &&
44
+ 'credential_token' in value &&
45
+ isString(value.credential_token)
46
+ );
23
47
  }
24
48
  }
@@ -13,8 +13,7 @@ import type {
13
13
  } from '@qlover/fe-corekit';
14
14
 
15
15
  export interface AppApiConfig<Request = unknown>
16
- extends RequestAdapterConfig<Request>,
17
- RequestEncryptPluginProps<Request> {}
16
+ extends RequestAdapterConfig<Request>, RequestEncryptPluginProps<Request> {}
18
17
 
19
18
  /**
20
19
  * UserApiResponse
@@ -33,11 +32,13 @@ export type AppApiResponse<
33
32
  /**
34
33
  * UserApi common transaction
35
34
  */
36
- export interface AppApiTransaction<Request = unknown, Response = unknown>
37
- extends RequestTransactionInterface<
38
- AppApiConfig<Request>,
39
- AppApiResponse<Request, Response>
40
- > {
35
+ export interface AppApiTransaction<
36
+ Request = unknown,
37
+ Response = unknown
38
+ > extends RequestTransactionInterface<
39
+ AppApiConfig<Request>,
40
+ AppApiResponse<Request, Response>
41
+ > {
41
42
  data: AppApiConfig<Request>['data'];
42
43
  }
43
44
 
@@ -1,25 +1,14 @@
1
1
  import { inject, injectable } from 'inversify';
2
- import type { AppApiResult } from '@/base/port/AppApiInterface';
3
- import type { AppUserApiInterface } from '@/base/port/AppUserApiInterface';
2
+ import type {
3
+ AppUserApiInterface,
4
+ UserApiLoginTransaction,
5
+ UserApiLogoutTransaction,
6
+ UserApiRegisterTransaction
7
+ } from '@/base/port/AppUserApiInterface';
4
8
  import { AppApiRequester } from './AppApiRequester';
5
- import type { AppApiConfig, AppApiTransaction } from './AppApiRequester';
9
+ import type { AppApiConfig } from './AppApiRequester';
6
10
  import type { RequestTransaction } from '@qlover/fe-corekit';
7
11
 
8
- export type UserApiLoginTransaction = AppApiTransaction<
9
- { email: string; password: string },
10
- {
11
- token: string;
12
- }
13
- >;
14
-
15
- export type UserApiRegisterTransaction = AppApiTransaction<
16
- {
17
- email: string;
18
- password: string;
19
- },
20
- AppApiTransaction['response']['data']
21
- >;
22
-
23
12
  /**
24
13
  * UserApi
25
14
  *
@@ -36,7 +25,7 @@ export class AppUserApi implements AppUserApiInterface {
36
25
 
37
26
  async login(
38
27
  params: UserApiLoginTransaction['data']
39
- ): Promise<AppApiResult<unknown>> {
28
+ ): Promise<UserApiLoginTransaction['response']> {
40
29
  const response = await this.client.request<UserApiLoginTransaction>({
41
30
  url: '/user/login',
42
31
  method: 'POST',
@@ -44,12 +33,12 @@ export class AppUserApi implements AppUserApiInterface {
44
33
  encryptProps: 'password'
45
34
  });
46
35
 
47
- return response.data;
36
+ return response;
48
37
  }
49
38
 
50
39
  async register(
51
40
  params: UserApiRegisterTransaction['data']
52
- ): Promise<AppApiResult<unknown>> {
41
+ ): Promise<UserApiRegisterTransaction['response']> {
53
42
  const response = await this.client.request<UserApiRegisterTransaction>({
54
43
  url: '/user/register',
55
44
  method: 'POST',
@@ -57,15 +46,15 @@ export class AppUserApi implements AppUserApiInterface {
57
46
  encryptProps: 'password'
58
47
  });
59
48
 
60
- return response.data;
49
+ return response;
61
50
  }
62
51
 
63
- async logout(): Promise<AppApiResult<unknown>> {
64
- const response = await this.client.request({
52
+ async logout(
53
+ _params?: unknown
54
+ ): Promise<UserApiLogoutTransaction['response']> {
55
+ return await this.client.request<UserApiLogoutTransaction>({
65
56
  url: '/user/logout',
66
57
  method: 'POST'
67
58
  });
68
-
69
- return response.data as AppApiResult<unknown>;
70
59
  }
71
60
  }