@qlover/create-app 0.7.12 → 0.7.14

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 (66) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/dist/index.cjs +7 -7
  3. package/dist/index.js +8 -8
  4. package/dist/templates/next-app/config/IOCIdentifier.ts +14 -1
  5. package/dist/templates/next-app/config/Identifier/index.ts +1 -0
  6. package/dist/templates/next-app/config/Identifier/page.admin.ts +48 -0
  7. package/dist/templates/next-app/config/i18n/admin18n.ts +33 -0
  8. package/dist/templates/next-app/config/i18n/index.ts +3 -1
  9. package/dist/templates/next-app/migrations/schema/UserSchema.ts +2 -2
  10. package/dist/templates/next-app/next.config.ts +1 -1
  11. package/dist/templates/next-app/package.json +3 -1
  12. package/dist/templates/next-app/public/locales/en.json +8 -1
  13. package/dist/templates/next-app/public/locales/zh.json +8 -1
  14. package/dist/templates/next-app/src/app/[locale]/admin/layout.tsx +1 -1
  15. package/dist/templates/next-app/src/app/[locale]/admin/page.tsx +14 -16
  16. package/dist/templates/next-app/src/app/[locale]/admin/users/page.tsx +10 -3
  17. package/dist/templates/next-app/src/app/[locale]/layout.tsx +1 -1
  18. package/dist/templates/next-app/src/app/[locale]/login/page.tsx +1 -1
  19. package/dist/templates/next-app/src/app/[locale]/page.tsx +2 -3
  20. package/dist/templates/next-app/src/app/[locale]/register/page.tsx +1 -1
  21. package/dist/templates/next-app/src/app/api/ai/completions/route.ts +32 -0
  22. package/dist/templates/next-app/src/base/cases/AppConfig.ts +3 -0
  23. package/dist/templates/next-app/src/base/cases/ChatAction.ts +21 -0
  24. package/dist/templates/next-app/src/base/cases/FocusBarAction.ts +36 -0
  25. package/dist/templates/next-app/src/base/port/AdminPageInterface.ts +1 -3
  26. package/dist/templates/next-app/src/base/services/AdminUserService.ts +1 -1
  27. package/dist/templates/next-app/src/base/services/adminApi/AdminUserApi.ts +1 -1
  28. package/dist/templates/next-app/src/base/services/appApi/AppApiPlugin.ts +23 -1
  29. package/dist/templates/next-app/src/base/services/appApi/AppUserApiBootstrap.ts +2 -2
  30. package/dist/templates/next-app/src/base/types/PageProps.ts +1 -1
  31. package/dist/templates/next-app/src/core/bootstraps/BootstrapClient.ts +1 -0
  32. package/dist/templates/next-app/src/core/bootstraps/BootstrapServer.ts +1 -0
  33. package/dist/templates/next-app/src/core/globals.ts +2 -0
  34. package/dist/templates/next-app/src/core/serverIoc/ServerIOCRegister.ts +4 -1
  35. package/dist/templates/next-app/src/{base/cases → server}/PageParams.ts +1 -1
  36. package/dist/templates/next-app/src/server/port/DBBridgeInterface.ts +31 -0
  37. package/dist/templates/next-app/src/server/port/DBTableInterface.ts +1 -1
  38. package/dist/templates/next-app/src/server/repositorys/UserRepository.ts +6 -4
  39. package/dist/templates/next-app/src/server/services/AIService.ts +43 -0
  40. package/dist/templates/next-app/src/server/services/ApiUserService.ts +1 -1
  41. package/dist/templates/next-app/src/server/{SupabaseBridge.ts → sqlBridges/SupabaseBridge.ts} +16 -11
  42. package/dist/templates/next-app/src/server/validators/LoginValidator.ts +4 -4
  43. package/dist/templates/next-app/src/server/validators/PaginationValidator.ts +1 -1
  44. package/dist/templates/next-app/src/uikit/components/AdminLayout.tsx +32 -25
  45. package/dist/templates/next-app/src/uikit/components/BaseHeader.tsx +12 -26
  46. package/dist/templates/next-app/src/uikit/components/BaseLayout.tsx +37 -5
  47. package/dist/templates/next-app/src/uikit/components/ChatRoot.tsx +17 -0
  48. package/dist/templates/next-app/src/uikit/components/ClientSeo.tsx +36 -0
  49. package/dist/templates/next-app/src/uikit/components/LanguageSwitcher.tsx +5 -6
  50. package/dist/templates/next-app/src/uikit/components/LogoutButton.tsx +2 -0
  51. package/dist/templates/next-app/src/uikit/components/With.tsx +17 -0
  52. package/dist/templates/next-app/src/uikit/components/chat/ChatActionInterface.ts +30 -0
  53. package/dist/templates/next-app/src/uikit/components/chat/ChatFocusBar.tsx +65 -0
  54. package/dist/templates/next-app/src/uikit/components/chat/ChatMessages.tsx +59 -0
  55. package/dist/templates/next-app/src/uikit/components/chat/ChatWrap.tsx +28 -0
  56. package/dist/templates/next-app/src/uikit/components/chat/FocusBarActionInterface.ts +19 -0
  57. package/package.json +1 -1
  58. package/dist/templates/next-app/src/base/port/DBBridgeInterface.ts +0 -21
  59. package/dist/templates/next-app/src/base/port/DBMigrationInterface.ts +0 -92
  60. package/dist/templates/next-app/src/base/port/MigrationApiInterface.ts +0 -3
  61. package/dist/templates/next-app/src/base/port/ServerApiResponseInterface.ts +0 -6
  62. package/dist/templates/next-app/src/base/services/migrations/MigrationsApi.ts +0 -43
  63. package/dist/templates/next-app/config/i18n/{HomeI18n .ts → HomeI18n.ts} +0 -0
  64. package/dist/templates/next-app/{build → make}/generateLocales.ts +2 -2
  65. /package/dist/templates/next-app/src/{base → server}/port/PaginationInterface.ts +0 -0
  66. /package/dist/templates/next-app/src/{base → server}/port/ParamsHandlerInterface.ts +0 -0
@@ -2,6 +2,7 @@ export * from './api';
2
2
  export * from './common';
3
3
  export * from './common.error';
4
4
  export * from './page.about';
5
+ export * from './page.admin';
5
6
  export * from './page.executor';
6
7
  export * from './page.home';
7
8
  export * from './page.identifiter';
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @description Admin page title
3
+ * @localZh 管理员页面
4
+ * @localEn Admin page
5
+ */
6
+ export const PAGE_ADMIN_TITLE = 'page__admin__title';
7
+
8
+ /**
9
+ * @description Admin page description
10
+ * @localZh 管理员页面
11
+ * @localEn Admin page
12
+ */
13
+ export const PAGE_ADMIN_DESCRIPTION = 'page__admin__description';
14
+
15
+ /**
16
+ * @description Admin page keywords
17
+ * @localZh 管理员页面关键词
18
+ * @localEn Admin page
19
+ */
20
+ export const PAGE_ADMIN_KEYWORDS = 'page__admin__keywords';
21
+
22
+ /**
23
+ * @description Home page welcome message
24
+ * @localZh 欢迎来到管理员页面
25
+ * @localEn Welcome to the admin page
26
+ */
27
+ export const ADMIN_WELCOME = 'admin__welcome';
28
+
29
+ /**
30
+ * @description Admin users page title
31
+ * @localZh 后台管理 - 管理员用户页面
32
+ * @localEn Admin users page
33
+ */
34
+ export const PAGE_ADMIN_USERS_TITLE = 'page__admin__users__title';
35
+
36
+ /**
37
+ * @description Admin users page description
38
+ * @localZh 后台管理 - 管理员用户页面
39
+ * @localEn Admin users page
40
+ */
41
+ export const PAGE_ADMIN_USERS_DESCRIPTION = 'page__admin__users__description';
42
+
43
+ /**
44
+ * @description Admin users page keywords
45
+ * @localZh 后台管理 - 管理员用户页面关键词
46
+ * @localEn Admin users page keywords
47
+ */
48
+ export const PAGE_ADMIN_USERS_KEYWORDS = 'page__admin__users__keywords';
@@ -0,0 +1,33 @@
1
+ import * as i18nKeys from '../Identifier/page.admin';
2
+
3
+ /**
4
+ * Register page i18n interface
5
+ *
6
+ * @description
7
+ * - welcome: welcome message
8
+ */
9
+ export type AdminI18nInterface = typeof admin18n;
10
+
11
+ export const admin18n = Object.freeze({
12
+ // basic meta properties
13
+ title: i18nKeys.PAGE_ADMIN_TITLE,
14
+ description: i18nKeys.PAGE_ADMIN_DESCRIPTION,
15
+ content: i18nKeys.PAGE_ADMIN_DESCRIPTION,
16
+ keywords: i18nKeys.PAGE_ADMIN_KEYWORDS,
17
+
18
+ // admin page
19
+ welcome: i18nKeys.ADMIN_WELCOME
20
+ });
21
+
22
+ export type AdminUsersI18nInterface = typeof adminUsers18n;
23
+
24
+ export const adminUsers18n = Object.freeze({
25
+ // basic meta properties
26
+ title: i18nKeys.PAGE_ADMIN_USERS_TITLE,
27
+ description: i18nKeys.PAGE_ADMIN_USERS_DESCRIPTION,
28
+ content: i18nKeys.PAGE_ADMIN_USERS_DESCRIPTION,
29
+ keywords: i18nKeys.PAGE_ADMIN_USERS_KEYWORDS,
30
+
31
+ // admin page
32
+ welcome: i18nKeys.ADMIN_WELCOME
33
+ });
@@ -1,4 +1,6 @@
1
+ export * from './HomeI18n';
2
+ export * from './admin18n';
1
3
  export * from './i18nConfig';
2
- export * from './PageI18nInterface';
3
4
  export * from './loginI18n';
5
+ export * from './PageI18nInterface';
4
6
  export * from './register18n';
@@ -9,8 +9,8 @@ export type UserRoleType = (typeof UserRole)[keyof typeof UserRole];
9
9
 
10
10
  export const userSchema = z.object({
11
11
  id: z.number(),
12
- role: z.enum(UserRole),
13
- email: z.email(),
12
+ role: z.nativeEnum(UserRole),
13
+ email: z.string().email(),
14
14
  password: z.string(),
15
15
  /**
16
16
  * 加密的token, 包含token, 过期时间
@@ -1,5 +1,5 @@
1
1
  import createNextIntlPlugin from 'next-intl/plugin';
2
- import { generateLocales } from './build/generateLocales';
2
+ import { generateLocales } from './make/generateLocales';
3
3
  import type { NextConfig } from 'next';
4
4
 
5
5
  const withNextIntl = createNextIntlPlugin();
@@ -37,9 +37,11 @@
37
37
  "next": "15.5.0",
38
38
  "next-intl": "^4.3.5",
39
39
  "next-themes": "^0.4.6",
40
+ "openai": "^5.23.0",
40
41
  "react": "19.1.0",
41
42
  "react-dom": "19.1.0",
42
- "zod": "^4.1.8"
43
+ "reflect-metadata": "^0.2.2",
44
+ "zod": "^3.23.8"
43
45
  },
44
46
  "devDependencies": {
45
47
  "@brain-toolkit/ts2locales": "^0.2.3",
@@ -198,5 +198,12 @@
198
198
  "register__feature__progress_tracking": "Progress Tracking",
199
199
  "page__head__admin__title": "Admin Backend",
200
200
  "api__not_authorized": "Not authorized",
201
- "api__page__invalid": "Page number is incorrect"
201
+ "api__page__invalid": "Page number is incorrect",
202
+ "page__admin__title": "Admin page",
203
+ "page__admin__description": "Admin page",
204
+ "page__admin__keywords": "Admin page",
205
+ "admin__welcome": "Welcome to the admin page",
206
+ "page__admin__users__title": "Admin users page",
207
+ "page__admin__users__description": "Admin users page",
208
+ "page__admin__users__keywords": "Admin users page keywords"
202
209
  }
@@ -198,5 +198,12 @@
198
198
  "register__feature__progress_tracking": "进度跟踪",
199
199
  "page__head__admin__title": "管理后台",
200
200
  "api__not_authorized": "未授权",
201
- "api__page__invalid": "页码不正确"
201
+ "api__page__invalid": "页码不正确",
202
+ "page__admin__title": "管理员页面",
203
+ "page__admin__description": "管理员页面",
204
+ "page__admin__keywords": "管理员页面关键词",
205
+ "admin__welcome": "欢迎来到管理员页面",
206
+ "page__admin__users__title": "后台管理 - 管理员用户页面",
207
+ "page__admin__users__description": "后台管理 - 管理员用户页面",
208
+ "page__admin__users__keywords": "后台管理 - 管理员用户页面关键词"
202
209
  }
@@ -1,5 +1,5 @@
1
- import { PageParams } from '@/base/cases/PageParams';
2
1
  import type { PageLayoutProps } from '@/base/types/PageProps';
2
+ import { PageParams } from '@/server/PageParams';
3
3
  import '@/styles/css/index.css';
4
4
  import { AdminLayout } from '@/uikit/components/AdminLayout';
5
5
 
@@ -1,22 +1,20 @@
1
- import type { Metadata } from 'next';
1
+ 'use client';
2
2
 
3
- function AdminPageClient() {
4
- return <div data-testid="AdminPage">Admin Page</div>;
5
- }
6
-
7
- export const metadata: Metadata = {
8
- title: 'Admin Dashboard',
9
- description: 'Admin dashboard for managing application resources',
10
- robots: {
11
- index: false,
12
- follow: false
13
- }
14
- };
3
+ import { ClientSeo } from '@/uikit/components/ClientSeo';
4
+ import { useI18nInterface } from '@/uikit/hook/useI18nInterface';
5
+ import { admin18n } from '@config/i18n';
15
6
 
16
7
  export default function AdminPage() {
8
+ const tt = useI18nInterface(admin18n);
9
+
17
10
  return (
18
- <div data-testid="AdminPageWrapper">
19
- <AdminPageClient />
20
- </div>
11
+ <>
12
+ <ClientSeo i18nInterface={tt} />
13
+ <div data-testid="AdminPageWrapper">
14
+ <div data-testid="AdminPage">
15
+ <h1>{tt.welcome}</h1>
16
+ </div>
17
+ </div>
18
+ </>
21
19
  );
22
20
  }
@@ -3,9 +3,12 @@
3
3
  import { Table } from 'antd';
4
4
  import { useEffect, useRef } from 'react';
5
5
  import { AdminUserService } from '@/base/services/AdminUserService';
6
+ import { ClientSeo } from '@/uikit/components/ClientSeo';
7
+ import { useI18nInterface } from '@/uikit/hook/useI18nInterface';
6
8
  import { useIOC } from '@/uikit/hook/useIOC';
7
9
  import { useStore } from '@/uikit/hook/useStore';
8
10
  import { userSchema, type UserSchema } from '@migrations/schema/UserSchema';
11
+ import { adminUsers18n } from '@config/i18n';
9
12
  import type { ColumnsType } from 'antd/es/table';
10
13
 
11
14
  const baseColumns: ColumnsType<UserSchema> = Object.keys(
@@ -20,7 +23,7 @@ const baseColumns: ColumnsType<UserSchema> = Object.keys(
20
23
 
21
24
  export default function UsersPage() {
22
25
  const adminUserService = useIOC(AdminUserService);
23
-
26
+ const tt = useI18nInterface(adminUsers18n);
24
27
  const listParams = useStore(adminUserService, (state) => state.listParams);
25
28
  const listState = useStore(adminUserService, (state) => state.listState);
26
29
  const mouted = useRef(false);
@@ -28,9 +31,12 @@ export default function UsersPage() {
28
31
  useEffect(() => {
29
32
  if (!mouted.current) {
30
33
  mouted.current = true;
31
- adminUserService.initialize();
34
+
35
+ requestAnimationFrame(() => {
36
+ adminUserService.initialize();
37
+ });
32
38
  }
33
- }, []);
39
+ }, [adminUserService]);
34
40
 
35
41
  const dataSource = listState.result?.list as UserSchema[];
36
42
 
@@ -38,6 +44,7 @@ export default function UsersPage() {
38
44
 
39
45
  return (
40
46
  <div data-testid="UsersPage">
47
+ <ClientSeo i18nInterface={tt} />
41
48
  <Table
42
49
  rowKey="id"
43
50
  columns={columns}
@@ -1,6 +1,6 @@
1
1
  import { NextIntlClientProvider } from 'next-intl';
2
- import { PageParams } from '@/base/cases/PageParams';
3
2
  import type { PageLayoutProps } from '@/base/types/PageProps';
3
+ import { PageParams } from '@/server/PageParams';
4
4
  import { ComboProvider } from '@/uikit/components/ComboProvider';
5
5
  import { themeConfig } from '@config/theme';
6
6
  import '@/styles/css/index.css';
@@ -1,8 +1,8 @@
1
1
  import { notFound } from 'next/navigation';
2
- import { PageParams, type PageParamsType } from '@/base/cases/PageParams';
3
2
  import type { PageParamsProps } from '@/base/types/PageProps';
4
3
  import { BootstrapServer } from '@/core/bootstraps/BootstrapServer';
5
4
  import { redirect } from '@/i18n/routing';
5
+ import { PageParams, type PageParamsType } from '@/server/PageParams';
6
6
  import { ServerAuth } from '@/server/ServerAuth';
7
7
  import { BaseLayout } from '@/uikit/components/BaseLayout';
8
8
  import { FeatureItem } from '@/uikit/components/FeatureItem';
@@ -1,12 +1,11 @@
1
1
  import { Button } from 'antd';
2
- import { PageParams, type PageParamsType } from '@/base/cases/PageParams';
3
2
  import type { PageParamsProps } from '@/base/types/PageProps';
4
3
  import { BootstrapServer } from '@/core/bootstraps/BootstrapServer';
5
4
  import { redirect } from '@/i18n/routing';
5
+ import { PageParams, type PageParamsType } from '@/server/PageParams';
6
6
  import { ServerAuth } from '@/server/ServerAuth';
7
7
  import { BaseLayout } from '@/uikit/components/BaseLayout';
8
- import { i18nConfig } from '@config/i18n';
9
- import { homeI18n } from '@config/i18n/HomeI18n ';
8
+ import { i18nConfig, homeI18n } from '@config/i18n';
10
9
  import type { Metadata } from 'next';
11
10
 
12
11
  // const navigationItems = [
@@ -1,8 +1,8 @@
1
1
  import { notFound } from 'next/navigation';
2
- import { PageParams, type PageParamsType } from '@/base/cases/PageParams';
3
2
  import type { PageParamsProps } from '@/base/types/PageProps';
4
3
  import { BootstrapServer } from '@/core/bootstraps/BootstrapServer';
5
4
  import { redirect } from '@/i18n/routing';
5
+ import { PageParams, type PageParamsType } from '@/server/PageParams';
6
6
  import { ServerAuth } from '@/server/ServerAuth';
7
7
  import { BaseLayout } from '@/uikit/components/BaseLayout';
8
8
  import { FeatureItem } from '@/uikit/components/FeatureItem';
@@ -0,0 +1,32 @@
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 { AIService } from '@/server/services/AIService';
7
+
8
+ export async function GET() {
9
+ const server = new BootstrapServer();
10
+
11
+ const result = await server.execNoError(async ({ parameters: { IOC } }) => {
12
+ // const requestBody = await req.json();
13
+
14
+ const result = await IOC(AIService).completions([
15
+ {
16
+ role: 'user',
17
+ content: 'hello'
18
+ }
19
+ ]);
20
+
21
+ return result;
22
+ });
23
+
24
+ if (result instanceof ExecutorError) {
25
+ console.log(result);
26
+ return NextResponse.json(new AppErrorApi(result.id, result.message), {
27
+ status: 400
28
+ });
29
+ }
30
+
31
+ return NextResponse.json(new AppSuccessApi(result));
32
+ }
@@ -31,4 +31,7 @@ export class AppConfig implements EnvConfigInterface {
31
31
  * @example '1 year'
32
32
  */
33
33
  readonly jwtExpiresIn: StringValue = '30 days';
34
+
35
+ readonly openaiBaseUrl: string = process.env.CEREBRAS_BASE_URL!;
36
+ readonly openaiApiKey: string = process.env.CEREBRAS_API_KEY!;
34
37
  }
@@ -0,0 +1,21 @@
1
+ import { injectable } from 'inversify';
2
+ import {
3
+ ChatActionInterface,
4
+ type MessageInterface,
5
+ type ChatStateInterface
6
+ } from '@/uikit/components/chat/ChatActionInterface';
7
+
8
+ class ChatState implements ChatStateInterface {
9
+ messages: MessageInterface[] = [];
10
+ }
11
+
12
+ @injectable()
13
+ export class ChatAction extends ChatActionInterface<ChatStateInterface> {
14
+ constructor() {
15
+ super(() => new ChatState());
16
+ }
17
+
18
+ focus(): void {
19
+ console.log('focus');
20
+ }
21
+ }
@@ -0,0 +1,36 @@
1
+ import { injectable } from 'inversify';
2
+
3
+ import type { FocusBarStateInterface } from '@/uikit/components/chat/FocusBarActionInterface';
4
+ import { FocusBarActionInterface } from '@/uikit/components/chat/FocusBarActionInterface';
5
+ import { RequestState } from './RequestState';
6
+
7
+ class FocusBarState implements FocusBarStateInterface {
8
+ showHistoryArea = false;
9
+ inputValue = '';
10
+ sendState = new RequestState();
11
+ }
12
+
13
+ @injectable()
14
+ export class FocusBarAction extends FocusBarActionInterface<FocusBarStateInterface> {
15
+ constructor() {
16
+ super(() => new FocusBarState());
17
+ }
18
+
19
+ sendMessage(_message: string): Promise<void> {
20
+ return new Promise((resolve) => {
21
+ this.emit(this.cloneState({ sendState: new RequestState(true) }));
22
+ setTimeout(() => {
23
+ this.emit(this.cloneState({ sendState: new RequestState().end() }));
24
+ resolve();
25
+ }, 1000);
26
+ });
27
+ }
28
+
29
+ setInputValue(value: string): void {
30
+ this.emit(this.cloneState({ inputValue: value }));
31
+ }
32
+
33
+ clearInput(): void {
34
+ this.emit(this.cloneState({ inputValue: '' }));
35
+ }
36
+ }
@@ -1,6 +1,6 @@
1
1
  import { StoreInterface } from '@qlover/corekit-bridge';
2
2
  import { RequestState } from '../cases/RequestState';
3
- import type { PaginationInterface } from './PaginationInterface';
3
+ import type { PaginationInterface } from '../../server/port/PaginationInterface';
4
4
  import type { StoreStateInterface } from '@qlover/corekit-bridge';
5
5
 
6
6
  export interface AdminPageListParams {
@@ -34,8 +34,6 @@ export abstract class AdminPageInterface<
34
34
  try {
35
35
  const result = await this.fetchList(this.state.listParams);
36
36
 
37
- console.log('jj result', result);
38
-
39
37
  this.emit(
40
38
  this.cloneState({
41
39
  initState: new RequestState(false, result).end()
@@ -1,4 +1,5 @@
1
1
  import { inject, injectable } from 'inversify';
2
+ import type { PaginationInterface } from '@/server/port/PaginationInterface';
2
3
  import {
3
4
  AdminPageInterface,
4
5
  type AdminPageListParams,
@@ -6,7 +7,6 @@ import {
6
7
  } from '../port/AdminPageInterface';
7
8
  import { AdminUserApi } from './adminApi/AdminUserApi';
8
9
  import { RequestState } from '../cases/RequestState';
9
- import type { PaginationInterface } from '../port/PaginationInterface';
10
10
 
11
11
  @injectable()
12
12
  export class AdminUserService extends AdminPageInterface<AdminPageState> {
@@ -1,6 +1,6 @@
1
1
  import { inject, injectable } from 'inversify';
2
2
  import type { AdminPageListParams } from '@/base/port/AdminPageInterface';
3
- import type { PaginationInterface } from '@/base/port/PaginationInterface';
3
+ import type { PaginationInterface } from '@/server/port/PaginationInterface';
4
4
  import {
5
5
  AppApiRequester,
6
6
  type AppApiConfig,
@@ -6,10 +6,13 @@ import {
6
6
  } from '@qlover/fe-corekit';
7
7
  import type { AppApiErrorInterface } from '@/base/port/AppApiInterface';
8
8
  import type { AppApiConfig } from './AppApiRequester';
9
+ import type { LoggerInterface } from '@qlover/logger';
9
10
 
10
11
  export class AppApiPlugin implements ExecutorPlugin {
11
12
  readonly pluginName = 'AppApiPlugin';
12
13
 
14
+ constructor(protected logger: LoggerInterface) {}
15
+
13
16
  isAppApiErrorInterface(value: unknown): value is AppApiErrorInterface {
14
17
  return (
15
18
  typeof value === 'object' &&
@@ -21,8 +24,16 @@ export class AppApiPlugin implements ExecutorPlugin {
21
24
  );
22
25
  }
23
26
 
24
- onSuccess(context: ExecutorContext<unknown>): void | Promise<void> {
27
+ onSuccess(context: ExecutorContext<AppApiConfig>): void | Promise<void> {
25
28
  const response = context.returnValue;
29
+ const { parameters } = context;
30
+
31
+ this.logger.info(
32
+ `%c[AppApi ${parameters.method} ${parameters.url}]%c - ${new Date().toLocaleString()}`,
33
+ 'color: #0f0;',
34
+ 'color: inherit;',
35
+ response
36
+ );
26
37
 
27
38
  if (this.isAppApiErrorInterface(response)) {
28
39
  throw new Error(response.message || response.id);
@@ -34,6 +45,8 @@ export class AppApiPlugin implements ExecutorPlugin {
34
45
  ): Promise<ExecutorError | void> {
35
46
  const { error, parameters } = context;
36
47
 
48
+ this.loggerError(parameters, error);
49
+
37
50
  if (error instanceof RequestError && parameters.responseType === 'json') {
38
51
  // @ts-expect-error response is not defined in Error
39
52
  let response = error?.response;
@@ -60,4 +73,13 @@ export class AppApiPlugin implements ExecutorPlugin {
60
73
  return {};
61
74
  }
62
75
  }
76
+
77
+ protected loggerError(config: AppApiConfig, error: unknown): void {
78
+ this.logger.error(
79
+ `%c[AppApi ${config.method} ${config.url}]%c - ${new Date().toLocaleString()}`,
80
+ 'color: #f00;',
81
+ 'color: inherit;',
82
+ error
83
+ );
84
+ }
63
85
  }
@@ -3,6 +3,7 @@ import { FetchURLPlugin } from '@qlover/fe-corekit';
3
3
  import { DialogErrorPlugin } from '@/base/cases/DialogErrorPlugin';
4
4
  import { RequestEncryptPlugin } from '@/base/cases/RequestEncryptPlugin';
5
5
  import { StringEncryptor } from '@/base/cases/StringEncryptor';
6
+ import { I } from '@config/IOCIdentifier';
6
7
  import { AppApiPlugin } from './AppApiPlugin';
7
8
  import { AppApiRequester } from './AppApiRequester';
8
9
  import type { AppApiConfig } from './AppApiRequester';
@@ -27,9 +28,8 @@ export class AppUserApiBootstrap implements BootstrapExecutorPlugin {
27
28
  requestDataSerializer: this.requestDataSerializer.bind(this)
28
29
  })
29
30
  );
30
- appUserApi.usePlugin(new AppApiPlugin());
31
+ appUserApi.usePlugin(new AppApiPlugin(ioc.get(I.Logger)));
31
32
  appUserApi.usePlugin(ioc.get(DialogErrorPlugin));
32
- console.log('jj AppUserApiBootstrap success');
33
33
  }
34
34
 
35
35
  protected requestDataSerializer(
@@ -1,4 +1,4 @@
1
- import type { PageWithParams } from '@/base/cases/PageParams';
1
+ import type { PageWithParams } from '@/server/PageParams';
2
2
 
3
3
  export interface PageParamsProps extends PageWithParams {
4
4
  searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
@@ -1,3 +1,4 @@
1
+ import 'reflect-metadata';
1
2
  import { Bootstrap } from '@qlover/corekit-bridge';
2
3
  import { isObject } from 'lodash';
3
4
  import { browserGlobalsName } from '@config/common';
@@ -1,3 +1,4 @@
1
+ import 'reflect-metadata';
1
2
  import {
2
3
  type ServiceIdentifier,
3
4
  type BootstrapContextValue,
@@ -1,3 +1,5 @@
1
+ import 'reflect-metadata';
2
+
1
3
  // ! global variables, don't import any dependencies and don't have side effects
2
4
  import { ColorFormatter, ConsoleHandler, Logger } from '@qlover/corekit-bridge';
3
5
  import { JSONSerializer } from '@qlover/fe-corekit';
@@ -7,6 +7,7 @@ import {
7
7
  type IOCRegisterInterface
8
8
  } from '@qlover/corekit-bridge';
9
9
  import type { IocRegisterOptions } from '@/base/port/IOCInterface';
10
+ import { SupabaseBridge } from '@/server/sqlBridges/SupabaseBridge';
10
11
  import { IOCIdentifier as I } from '@config/IOCIdentifier';
11
12
 
12
13
  export class ServerIOCRegister
@@ -45,7 +46,9 @@ export class ServerIOCRegister
45
46
  );
46
47
  }
47
48
 
48
- protected registerImplement(_ioc: IOCContainerInterface): void {}
49
+ protected registerImplement(ioc: IOCContainerInterface): void {
50
+ ioc.bind(I.DBBridgeInterface, ioc.get(SupabaseBridge));
51
+ }
49
52
 
50
53
  protected registerCommon(_ioc: IOCContainerInterface): void {}
51
54
 
@@ -2,7 +2,7 @@ import { notFound } from 'next/navigation';
2
2
  import { getMessages, getTranslations } from 'next-intl/server';
3
3
  import { i18nConfig } from '@config/i18n';
4
4
  import type { LocaleType, PageI18nInterface } from '@config/i18n';
5
- import type { ParamsHandlerInterface as ParamsHandlerInterface } from '../port/ParamsHandlerInterface';
5
+ import type { ParamsHandlerInterface as ParamsHandlerInterface } from './port/ParamsHandlerInterface';
6
6
 
7
7
  export interface PageWithParams {
8
8
  params?: Promise<PageParamsType>;
@@ -0,0 +1,31 @@
1
+ export type WhereOperation = '=' | '!=' | '>' | '<' | '>=' | '<=';
2
+ export type Where = [string, WhereOperation, string | number];
3
+
4
+ export interface BridgeEvent {
5
+ table: string;
6
+ fields?: string | string[];
7
+ where?: Where[];
8
+ data?: unknown;
9
+ page?: number;
10
+ pageSize?: number;
11
+ }
12
+
13
+ export interface PaginationInfo {
14
+ total: number;
15
+ page: number;
16
+ pageSize: number;
17
+ }
18
+
19
+ export interface DBBridgeResponse<T> {
20
+ error?: unknown;
21
+ data: T;
22
+ pagination?: PaginationInfo;
23
+ }
24
+
25
+ export interface DBBridgeInterface {
26
+ add(event: BridgeEvent): Promise<DBBridgeResponse<unknown>>;
27
+ update(event: BridgeEvent): Promise<DBBridgeResponse<unknown>>;
28
+ delete(event: BridgeEvent): Promise<DBBridgeResponse<unknown>>;
29
+ get(event: BridgeEvent): Promise<DBBridgeResponse<unknown>>;
30
+ pagination(event: BridgeEvent): Promise<DBBridgeResponse<unknown[]>>;
31
+ }
@@ -1,4 +1,4 @@
1
- import type { PaginationInterface } from '@/base/port/PaginationInterface';
1
+ import type { PaginationInterface } from '@/server/port/PaginationInterface';
2
2
 
3
3
  export interface DBTableInterface {
4
4
  readonly name: string;
@@ -1,9 +1,9 @@
1
1
  import { inject, injectable } from 'inversify';
2
2
  import { isEmpty, last } from 'lodash';
3
- import type { DBBridgeInterface } from '@/base/port/DBBridgeInterface';
4
- import type { PaginationInterface } from '@/base/port/PaginationInterface';
3
+ import type { DBBridgeInterface } from '@/server/port/DBBridgeInterface';
4
+ import type { PaginationInterface } from '@/server/port/PaginationInterface';
5
5
  import type { UserSchema } from '@migrations/schema/UserSchema';
6
- import { SupabaseBridge } from '../SupabaseBridge';
6
+ import { I } from '@config/IOCIdentifier';
7
7
  import type { UserRepositoryInterface } from '../port/UserRepositoryInterface';
8
8
 
9
9
  @injectable()
@@ -21,7 +21,9 @@ export class UserRepository implements UserRepositoryInterface {
21
21
  'updated_at'
22
22
  ];
23
23
 
24
- constructor(@inject(SupabaseBridge) protected dbBridge: DBBridgeInterface) {}
24
+ constructor(
25
+ @inject(I.DBBridgeInterface) protected dbBridge: DBBridgeInterface
26
+ ) {}
25
27
 
26
28
  getAll(): Promise<unknown> {
27
29
  return this.dbBridge.get({ table: this.name });