@qlover/create-app 0.10.2 → 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.
- package/CHANGELOG.md +37 -0
- package/dist/configs/_common/.github/workflows/general-check.yml +1 -1
- package/dist/configs/_common/.github/workflows/release.yml +2 -2
- package/dist/index.cjs +4 -4
- package/dist/index.js +4 -4
- package/dist/templates/next-app/eslint.config.mjs +5 -1
- package/dist/templates/next-app/package.json +4 -2
- package/dist/templates/next-app/src/base/cases/AdminPageManager.ts +3 -3
- package/dist/templates/next-app/src/base/cases/AppConfig.ts +14 -13
- package/dist/templates/next-app/src/base/cases/Datetime.ts +3 -3
- package/dist/templates/next-app/src/base/cases/DialogErrorPlugin.ts +8 -2
- package/dist/templates/next-app/src/base/cases/DialogHandler.ts +30 -4
- package/dist/templates/next-app/src/base/cases/InversifyContainer.ts +16 -4
- package/dist/templates/next-app/src/base/cases/NavigateBridge.ts +8 -2
- package/dist/templates/next-app/src/base/cases/RequestEncryptPlugin.ts +8 -2
- package/dist/templates/next-app/src/base/cases/ResourceState.ts +3 -3
- package/dist/templates/next-app/src/base/cases/RouterService.ts +24 -6
- package/dist/templates/next-app/src/base/cases/StringEncryptor.ts +14 -2
- package/dist/templates/next-app/src/base/cases/TranslateI18nInterface.ts +1 -1
- package/dist/templates/next-app/src/base/cases/UserServiceApi.ts +20 -5
- package/dist/templates/next-app/src/base/cases/ZodColumnBuilder.ts +31 -8
- package/dist/templates/next-app/src/base/port/AdminLayoutInterface.ts +4 -1
- package/dist/templates/next-app/src/base/port/I18nServiceInterface.ts +27 -7
- package/dist/templates/next-app/src/base/services/AdminPageEvent.ts +1 -1
- package/dist/templates/next-app/src/base/services/AdminPageScheduler.ts +3 -3
- package/dist/templates/next-app/src/base/services/I18nService.ts +20 -10
- package/dist/templates/next-app/src/base/services/ResourceService.ts +32 -11
- package/dist/templates/next-app/src/base/services/UserService.ts +12 -3
- package/dist/templates/next-app/src/base/services/adminApi/AdminLocalesApi.ts +9 -6
- package/dist/templates/next-app/src/base/services/adminApi/AdminUserApi.ts +20 -5
- package/dist/templates/next-app/src/base/services/appApi/AppApiPlugin.ts +21 -4
- package/dist/templates/next-app/src/base/services/appApi/AppUserApi.ts +12 -3
- package/dist/templates/next-app/src/base/services/appApi/AppUserApiBootstrap.ts +10 -2
- package/dist/templates/next-app/src/core/bootstraps/BootstrapClient.ts +2 -2
- package/dist/templates/next-app/src/core/bootstraps/BootstrapServer.ts +25 -7
- package/dist/templates/next-app/src/core/bootstraps/BootstrapsRegistry.ts +6 -3
- package/dist/templates/next-app/src/core/clientIoc/ClientIOC.ts +11 -2
- package/dist/templates/next-app/src/core/clientIoc/ClientIOCRegister.ts +5 -0
- package/dist/templates/next-app/src/core/serverIoc/ServerIOC.ts +13 -4
- package/dist/templates/next-app/src/core/serverIoc/ServerIOCRegister.ts +8 -1
- package/dist/templates/next-app/src/pages/_app.tsx +1 -1
- package/dist/templates/next-app/src/server/AppErrorApi.ts +1 -1
- package/dist/templates/next-app/src/server/AppPageRouteParams.ts +13 -0
- package/dist/templates/next-app/src/server/AppSuccessApi.ts +1 -1
- package/dist/templates/next-app/src/server/NextApiServer.ts +11 -2
- package/dist/templates/next-app/src/server/PagesRouteParams.ts +11 -1
- package/dist/templates/next-app/src/server/PasswordEncrypt.ts +8 -2
- package/dist/templates/next-app/src/server/ServerAuth.ts +20 -5
- package/dist/templates/next-app/src/server/SupabaseBridge.ts +48 -8
- package/dist/templates/next-app/src/server/UserCredentialToken.ts +8 -2
- package/dist/templates/next-app/src/server/controllers/AdminLocalesController.ts +16 -4
- package/dist/templates/next-app/src/server/controllers/AdminUserController.ts +4 -1
- package/dist/templates/next-app/src/server/controllers/LocalesController.ts +4 -1
- package/dist/templates/next-app/src/server/controllers/UserController.ts +12 -3
- package/dist/templates/next-app/src/server/repositorys/LocalesRepository.ts +23 -7
- package/dist/templates/next-app/src/server/repositorys/UserRepository.ts +15 -6
- package/dist/templates/next-app/src/server/services/AIService.ts +3 -1
- package/dist/templates/next-app/src/server/services/AdminAuthPlugin.ts +5 -2
- package/dist/templates/next-app/src/server/services/ApiLocaleService.ts +5 -5
- package/dist/templates/next-app/src/server/services/ApiUserService.ts +1 -1
- package/dist/templates/next-app/src/server/services/UserService.ts +12 -3
- package/dist/templates/next-app/src/server/validators/LocalesValidator.ts +20 -5
- package/dist/templates/next-app/src/server/validators/LoginValidator.ts +16 -4
- package/dist/templates/next-app/src/server/validators/PaginationValidator.ts +8 -2
- package/dist/templates/next-app/src/uikit/components/IOCProvider.tsx +1 -1
- package/dist/templates/next-app/src/uikit/components/localesImportButton/LocalesImportEvent.ts +7 -1
- package/dist/templates/react-app/__tests__/__mocks__/BootstrapTest.ts +3 -1
- package/dist/templates/react-app/__tests__/__mocks__/MockAppConfig.ts +19 -19
- package/dist/templates/react-app/__tests__/__mocks__/MockDialogHandler.ts +8 -8
- package/dist/templates/react-app/__tests__/__mocks__/MockLogger.ts +9 -9
- package/dist/templates/react-app/__tests__/__mocks__/components/TestBootstrapsProvider.tsx +1 -1
- package/dist/templates/react-app/__tests__/__mocks__/i18nextHttpBackend.ts +5 -5
- package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOC.ts +9 -5
- package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOCRegister.ts +8 -4
- package/dist/templates/react-app/__tests__/src/base/cases/I18nKeyErrorPlugin.test.ts +4 -4
- package/dist/templates/react-app/__tests__/src/base/cases/InversifyContainer.test.ts +5 -5
- package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapClient.test.ts +3 -3
- package/dist/templates/react-app/__tests__/src/uikit/components/chatMessage/ChatRoot.test.tsx +1 -1
- package/dist/templates/react-app/docs/en/components/chat-message-component.md +35 -29
- package/dist/templates/react-app/docs/en/components/chat-message-refactor.md +18 -5
- package/dist/templates/react-app/docs/en/components/message-base-list-component.md +11 -12
- package/dist/templates/react-app/docs/en/request.md +1 -3
- package/dist/templates/react-app/docs/zh/components/chat-message-component.md +35 -29
- package/dist/templates/react-app/docs/zh/components/chat-message-refactor.md +18 -5
- package/dist/templates/react-app/docs/zh/components/message-base-list-component.md +11 -12
- package/dist/templates/react-app/docs/zh/request.md +1 -3
- package/dist/templates/react-app/eslint.config.mjs +10 -5
- package/dist/templates/react-app/src/App.tsx +1 -1
- package/dist/templates/react-app/src/base/apis/feApi/FeApi.ts +2 -2
- package/dist/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +14 -11
- package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +10 -16
- package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +12 -10
- package/dist/templates/react-app/src/base/cases/AppConfig.ts +19 -19
- package/dist/templates/react-app/src/base/cases/DialogHandler.ts +28 -5
- package/dist/templates/react-app/src/base/cases/I18nKeyErrorPlugin.ts +5 -2
- package/dist/templates/react-app/src/base/cases/InversifyContainer.ts +16 -4
- package/dist/templates/react-app/src/base/cases/PublicAssetsPath.ts +1 -1
- package/dist/templates/react-app/src/base/cases/RequestLanguages.ts +6 -3
- package/dist/templates/react-app/src/base/cases/RequestLogger.ts +17 -8
- package/dist/templates/react-app/src/base/cases/RequestStatusCatcher.ts +4 -6
- package/dist/templates/react-app/src/base/cases/ResourceState.ts +3 -3
- package/dist/templates/react-app/src/base/cases/RouterLoader.ts +3 -3
- package/dist/templates/react-app/src/base/cases/TranslateI18nInterface.ts +1 -1
- package/dist/templates/react-app/src/base/port/ExecutorPageBridgeInterface.ts +2 -2
- package/dist/templates/react-app/src/base/port/IOCInterface.ts +4 -2
- package/dist/templates/react-app/src/base/port/JSONStoragePageBridgeInterface.ts +5 -5
- package/dist/templates/react-app/src/base/port/RequestPageBridgeInterface.ts +7 -7
- package/dist/templates/react-app/src/base/port/RouteServiceInterface.ts +8 -8
- package/dist/templates/react-app/src/base/port/UserServiceInterface.ts +4 -2
- package/dist/templates/react-app/src/base/services/BaseLayoutService.ts +3 -3
- package/dist/templates/react-app/src/base/services/I18nService.ts +24 -13
- package/dist/templates/react-app/src/base/services/IdentifierService.ts +21 -26
- package/dist/templates/react-app/src/base/services/RouteService.ts +8 -8
- package/dist/templates/react-app/src/base/services/UserBootstrap.ts +2 -2
- package/dist/templates/react-app/src/base/services/UserGatewayPlugin.ts +9 -5
- package/dist/templates/react-app/src/base/services/UserService.ts +10 -4
- package/dist/templates/react-app/src/core/bootstraps/BootstrapClient.ts +3 -1
- package/dist/templates/react-app/src/core/bootstraps/BootstrapsRegistry.ts +5 -2
- package/dist/templates/react-app/src/core/clientIoc/ClientIOC.ts +11 -4
- package/dist/templates/react-app/src/core/clientIoc/ClientIOCRegister.ts +5 -4
- package/dist/templates/react-app/src/pages/base/Layout.tsx +1 -1
- package/dist/templates/react-app/src/styles/css/antd-themes/_common/_default.css +0 -44
- package/dist/templates/react-app/src/styles/css/antd-themes/_common/dark.css +0 -44
- package/dist/templates/react-app/src/styles/css/antd-themes/_common/pink.css +0 -44
- package/dist/templates/react-app/src/styles/css/index.css +1 -1
- package/dist/templates/react-app/src/styles/css/scrollbar.css +34 -0
- package/dist/templates/react-app/src/uikit/bridges/ExecutorPageBridge.ts +2 -2
- package/dist/templates/react-app/src/uikit/bridges/JSONStoragePageBridge.ts +4 -4
- package/dist/templates/react-app/src/uikit/bridges/NavigateBridge.ts +8 -2
- package/dist/templates/react-app/src/uikit/bridges/RequestPageBridge.ts +6 -6
- package/dist/templates/react-app/src/uikit/components/AppRouterProvider.tsx +1 -1
- package/dist/templates/react-app/src/uikit/components/BootstrapsProvider.tsx +1 -3
- package/dist/templates/react-app/src/uikit/components/MessageBaseList.tsx +4 -1
- package/dist/templates/react-app/src/uikit/components/chatMessage/ChatMessageBridge.ts +39 -16
- package/dist/templates/react-app/src/uikit/components/chatMessage/MessageApi.ts +4 -2
- package/package.json +3 -3
- package/dist/templates/react-app/makes/eslint-utils.mjs +0 -195
|
@@ -28,6 +28,9 @@ export class AppPageRouteParams<
|
|
|
28
28
|
this.locale = this.params.locale || i18nConfig.fallbackLng;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* @override
|
|
33
|
+
*/
|
|
31
34
|
public getLocale(defaultLocale?: string): string {
|
|
32
35
|
if (this.locale) {
|
|
33
36
|
return this.locale;
|
|
@@ -38,6 +41,9 @@ export class AppPageRouteParams<
|
|
|
38
41
|
return this.locale;
|
|
39
42
|
}
|
|
40
43
|
|
|
44
|
+
/**
|
|
45
|
+
* @override
|
|
46
|
+
*/
|
|
41
47
|
public getI18nWithNotFound(): string {
|
|
42
48
|
const locale = this.getLocale();
|
|
43
49
|
|
|
@@ -52,6 +58,7 @@ export class AppPageRouteParams<
|
|
|
52
58
|
* 获取 i18n 消息
|
|
53
59
|
* 使用 next-intl 的 getMessages 加载消息
|
|
54
60
|
*
|
|
61
|
+
* @override
|
|
55
62
|
* @param namespace - 可选的命名空间(单个字符串或字符串数组),会与默认命名空间 ['common', 'api'] 合并
|
|
56
63
|
* @returns Promise<Record<string, string>> 返回翻译消息对象
|
|
57
64
|
*/
|
|
@@ -72,6 +79,9 @@ export class AppPageRouteParams<
|
|
|
72
79
|
return filterMessagesByNamespace(messages, namespaces);
|
|
73
80
|
}
|
|
74
81
|
|
|
82
|
+
/**
|
|
83
|
+
* @override
|
|
84
|
+
*/
|
|
75
85
|
public async getI18nInterface<T extends PageI18nInterface>(
|
|
76
86
|
i18nInterface: T,
|
|
77
87
|
_namespace?: string
|
|
@@ -84,6 +94,9 @@ export class AppPageRouteParams<
|
|
|
84
94
|
return TranslateI18nInterface.translate<T>(i18nInterface, t);
|
|
85
95
|
}
|
|
86
96
|
|
|
97
|
+
/**
|
|
98
|
+
* @override
|
|
99
|
+
*/
|
|
87
100
|
public async getTheme(): Promise<string> {
|
|
88
101
|
const cookieStore = await cookies();
|
|
89
102
|
return (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AppApiSuccessInterface } from '@/base/port/AppApiInterface';
|
|
2
2
|
|
|
3
3
|
export class AppSuccessApi<T = unknown> implements AppApiSuccessInterface<T> {
|
|
4
|
-
readonly success = true;
|
|
4
|
+
public readonly success = true;
|
|
5
5
|
|
|
6
6
|
constructor(public readonly data?: T) {}
|
|
7
7
|
}
|
|
@@ -12,11 +12,17 @@ import { AppSuccessApi } from './AppSuccessApi';
|
|
|
12
12
|
import type { PromiseTask } from '@qlover/fe-corekit';
|
|
13
13
|
|
|
14
14
|
export class NextApiServer extends BootstrapServer {
|
|
15
|
+
/**
|
|
16
|
+
* @override
|
|
17
|
+
*/
|
|
15
18
|
protected isAppApiResult(result: unknown): result is AppApiResult {
|
|
16
19
|
return isAppApiSuccessInterface(result) || isAppApiErrorInterface(result);
|
|
17
20
|
}
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
/**
|
|
23
|
+
* @override
|
|
24
|
+
*/
|
|
25
|
+
public async run<Result>(
|
|
20
26
|
task?: PromiseTask<Result | AppApiResult, BootstrapServerContextValue>
|
|
21
27
|
): Promise<AppApiResult> {
|
|
22
28
|
const result = await this.execNoError(task);
|
|
@@ -39,7 +45,10 @@ export class NextApiServer extends BootstrapServer {
|
|
|
39
45
|
return new AppSuccessApi(result);
|
|
40
46
|
}
|
|
41
47
|
|
|
42
|
-
|
|
48
|
+
/**
|
|
49
|
+
* @override
|
|
50
|
+
*/
|
|
51
|
+
public async runWithJson<Result>(
|
|
43
52
|
task?: PromiseTask<Result | AppApiResult, BootstrapServerContextValue>
|
|
44
53
|
): Promise<NextResponse> {
|
|
45
54
|
const result = await this.run(task);
|
|
@@ -36,6 +36,9 @@ export class PagesRouteParams implements RouteParamsnHandlerInterface {
|
|
|
36
36
|
this.locale = localeParam || i18nConfig.fallbackLng;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* @override
|
|
41
|
+
*/
|
|
39
42
|
public getLocale(defaultLocale?: string): string {
|
|
40
43
|
if (this.locale) {
|
|
41
44
|
return this.locale;
|
|
@@ -53,6 +56,7 @@ export class PagesRouteParams implements RouteParamsnHandlerInterface {
|
|
|
53
56
|
* 获取 locale,如果 locale 不支持则抛出错误
|
|
54
57
|
* 注意:在 pages 目录中,应该在 getStaticProps/getServerSideProps 中返回 { notFound: true } 来处理不支持的 locale
|
|
55
58
|
*
|
|
59
|
+
* @override
|
|
56
60
|
* @returns 支持的 locale 字符串
|
|
57
61
|
* @throws 如果 locale 不支持
|
|
58
62
|
*/
|
|
@@ -73,6 +77,7 @@ export class PagesRouteParams implements RouteParamsnHandlerInterface {
|
|
|
73
77
|
* 使用公共方法加载消息,支持从 API 加载或动态导入 JSON 文件
|
|
74
78
|
* 不依赖 next-intl/server,适用于 getStaticProps/getServerSideProps
|
|
75
79
|
*
|
|
80
|
+
* @override
|
|
76
81
|
* @param namespace - 可选的命名空间(单个字符串或字符串数组),会与默认命名空间 ['common', 'api'] 合并
|
|
77
82
|
* @returns Promise<Record<string, string>> 返回翻译消息对象
|
|
78
83
|
*/
|
|
@@ -95,7 +100,9 @@ export class PagesRouteParams implements RouteParamsnHandlerInterface {
|
|
|
95
100
|
/**
|
|
96
101
|
* 获取翻译后的 i18n 接口
|
|
97
102
|
* 创建一个简单的翻译函数,基于加载的 messages
|
|
98
|
-
|
|
103
|
+
|
|
104
|
+
* @override
|
|
105
|
+
*/
|
|
99
106
|
public async getI18nInterface<T extends PageI18nInterface>(
|
|
100
107
|
i18nInterface: T,
|
|
101
108
|
namespace?: string
|
|
@@ -130,6 +137,9 @@ export class PagesRouteParams implements RouteParamsnHandlerInterface {
|
|
|
130
137
|
);
|
|
131
138
|
}
|
|
132
139
|
|
|
140
|
+
/**
|
|
141
|
+
* @override
|
|
142
|
+
*/
|
|
133
143
|
public getTheme(): string {
|
|
134
144
|
return themeConfig.defaultTheme;
|
|
135
145
|
}
|
|
@@ -2,11 +2,17 @@ import crypto from 'crypto';
|
|
|
2
2
|
import type { Encryptor } from '@qlover/fe-corekit';
|
|
3
3
|
|
|
4
4
|
export class PasswordEncrypt implements Encryptor<string, string> {
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* @override
|
|
7
|
+
*/
|
|
8
|
+
public encrypt(password: string): string {
|
|
6
9
|
return crypto.createHash('md5').update(password).digest('hex');
|
|
7
10
|
}
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
/**
|
|
13
|
+
* @override
|
|
14
|
+
*/
|
|
15
|
+
public decrypt(): string {
|
|
10
16
|
throw new Error('Md5Encrypt is not decryptable');
|
|
11
17
|
}
|
|
12
18
|
}
|
|
@@ -18,13 +18,19 @@ export class ServerAuth implements ServerAuthInterface {
|
|
|
18
18
|
this.userTokenKey = server.userTokenKey;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
/**
|
|
22
|
+
* @override
|
|
23
|
+
*/
|
|
24
|
+
public async setAuth(credential_token: string): Promise<void> {
|
|
22
25
|
const cookieStore = await cookies();
|
|
23
26
|
|
|
24
27
|
cookieStore.set(this.userTokenKey, credential_token);
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
/**
|
|
31
|
+
* @override
|
|
32
|
+
*/
|
|
33
|
+
public async hasAuth(): Promise<boolean> {
|
|
28
34
|
const token = await this.getAuth();
|
|
29
35
|
|
|
30
36
|
if (!token) {
|
|
@@ -40,17 +46,26 @@ export class ServerAuth implements ServerAuthInterface {
|
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
/**
|
|
50
|
+
* @override
|
|
51
|
+
*/
|
|
52
|
+
public async getAuth(): Promise<string> {
|
|
44
53
|
const cookieStore = await cookies();
|
|
45
54
|
return cookieStore.get(this.userTokenKey)?.value || '';
|
|
46
55
|
}
|
|
47
56
|
|
|
48
|
-
|
|
57
|
+
/**
|
|
58
|
+
* @override
|
|
59
|
+
*/
|
|
60
|
+
public async clear(): Promise<void> {
|
|
49
61
|
const cookieStore = await cookies();
|
|
50
62
|
cookieStore.delete(this.userTokenKey);
|
|
51
63
|
}
|
|
52
64
|
|
|
53
|
-
|
|
65
|
+
/**
|
|
66
|
+
* @override
|
|
67
|
+
*/
|
|
68
|
+
public async throwIfNotAuth(): Promise<void> {
|
|
54
69
|
const hasAuth = await this.hasAuth();
|
|
55
70
|
|
|
56
71
|
if (!hasAuth) {
|
|
@@ -46,15 +46,24 @@ export class SupabaseBridge implements DBBridgeInterface {
|
|
|
46
46
|
);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
/**
|
|
50
|
+
* @override
|
|
51
|
+
*/
|
|
52
|
+
public getSupabase(): SupabaseClient {
|
|
50
53
|
return this.supabase;
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
|
|
56
|
+
/**
|
|
57
|
+
* @override
|
|
58
|
+
*/
|
|
59
|
+
public async execSql(sql: string): Promise<SupabaseBridgeResponse<unknown>> {
|
|
54
60
|
const res = await this.supabase.rpc('exec_sql', { sql });
|
|
55
61
|
return this.catch(res);
|
|
56
62
|
}
|
|
57
63
|
|
|
64
|
+
/**
|
|
65
|
+
* @override
|
|
66
|
+
*/
|
|
58
67
|
protected async catch(
|
|
59
68
|
result: PostgrestSingleResponse<unknown>
|
|
60
69
|
): Promise<SupabaseBridgeResponse<unknown>> {
|
|
@@ -73,12 +82,18 @@ export class SupabaseBridge implements DBBridgeInterface {
|
|
|
73
82
|
return result as SupabaseBridgeResponse<unknown>;
|
|
74
83
|
}
|
|
75
84
|
|
|
85
|
+
/**
|
|
86
|
+
* @override
|
|
87
|
+
*/
|
|
76
88
|
protected hasPausedProject(error: PostgrestResponseFailure): boolean {
|
|
77
89
|
return (
|
|
78
90
|
error.status === 0 && error.error.message === 'TypeError: fetch failed'
|
|
79
91
|
);
|
|
80
92
|
}
|
|
81
93
|
|
|
94
|
+
/**
|
|
95
|
+
* @override
|
|
96
|
+
*/
|
|
82
97
|
protected handleWhere(
|
|
83
98
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
84
99
|
handler: PostgrestFilterBuilder<any, any, any, any, string, unknown, any>,
|
|
@@ -101,6 +116,9 @@ export class SupabaseBridge implements DBBridgeInterface {
|
|
|
101
116
|
}
|
|
102
117
|
}
|
|
103
118
|
|
|
119
|
+
/**
|
|
120
|
+
* @override
|
|
121
|
+
*/
|
|
104
122
|
protected handleOrderBy(
|
|
105
123
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
106
124
|
handler: PostgrestFilterBuilder<any, any, any, any, string, unknown, any>,
|
|
@@ -111,7 +129,10 @@ export class SupabaseBridge implements DBBridgeInterface {
|
|
|
111
129
|
}
|
|
112
130
|
}
|
|
113
131
|
|
|
114
|
-
|
|
132
|
+
/**
|
|
133
|
+
* @override
|
|
134
|
+
*/
|
|
135
|
+
public async add(event: BridgeEvent): Promise<DBBridgeResponse<unknown>> {
|
|
115
136
|
const { table, data } = event;
|
|
116
137
|
if (!data) {
|
|
117
138
|
throw new Error('Data is required for add operation');
|
|
@@ -122,7 +143,10 @@ export class SupabaseBridge implements DBBridgeInterface {
|
|
|
122
143
|
return this.catch(res);
|
|
123
144
|
}
|
|
124
145
|
|
|
125
|
-
|
|
146
|
+
/**
|
|
147
|
+
* @override
|
|
148
|
+
*/
|
|
149
|
+
public async upsert(event: BridgeEvent): Promise<DBBridgeResponse<unknown>> {
|
|
126
150
|
const { table, data, fields = '*' } = event;
|
|
127
151
|
if (!data) {
|
|
128
152
|
throw new Error('Data is required for upsert operation');
|
|
@@ -137,7 +161,10 @@ export class SupabaseBridge implements DBBridgeInterface {
|
|
|
137
161
|
return this.catch(res);
|
|
138
162
|
}
|
|
139
163
|
|
|
140
|
-
|
|
164
|
+
/**
|
|
165
|
+
* @override
|
|
166
|
+
*/
|
|
167
|
+
public async update(event: BridgeEvent): Promise<DBBridgeResponse<unknown>> {
|
|
141
168
|
const { table, data, where } = event;
|
|
142
169
|
if (!data) {
|
|
143
170
|
throw new Error('Data is required for update operation');
|
|
@@ -150,7 +177,10 @@ export class SupabaseBridge implements DBBridgeInterface {
|
|
|
150
177
|
return this.catch(await handler);
|
|
151
178
|
}
|
|
152
179
|
|
|
153
|
-
|
|
180
|
+
/**
|
|
181
|
+
* @override
|
|
182
|
+
*/
|
|
183
|
+
public async delete(event: BridgeEvent): Promise<DBBridgeResponse<unknown>> {
|
|
154
184
|
const { table, where } = event;
|
|
155
185
|
const handler = this.supabase.from(table).delete();
|
|
156
186
|
|
|
@@ -159,7 +189,12 @@ export class SupabaseBridge implements DBBridgeInterface {
|
|
|
159
189
|
return this.catch(await handler);
|
|
160
190
|
}
|
|
161
191
|
|
|
162
|
-
|
|
192
|
+
/**
|
|
193
|
+
* @override
|
|
194
|
+
*/
|
|
195
|
+
public async get(
|
|
196
|
+
event: BridgeEvent
|
|
197
|
+
): Promise<SupabaseBridgeResponse<unknown>> {
|
|
163
198
|
const { table, fields = '*', where, orderBy } = event;
|
|
164
199
|
const selectFields = Array.isArray(fields) ? fields.join(',') : fields;
|
|
165
200
|
const handler = this.supabase.from(table).select(selectFields);
|
|
@@ -171,7 +206,12 @@ export class SupabaseBridge implements DBBridgeInterface {
|
|
|
171
206
|
return this.catch(await handler);
|
|
172
207
|
}
|
|
173
208
|
|
|
174
|
-
|
|
209
|
+
/**
|
|
210
|
+
* @override
|
|
211
|
+
*/
|
|
212
|
+
public async pagination(
|
|
213
|
+
event: BridgeEvent
|
|
214
|
+
): Promise<DBBridgeResponse<unknown[]>> {
|
|
175
215
|
const {
|
|
176
216
|
table,
|
|
177
217
|
fields = '*',
|
|
@@ -16,7 +16,10 @@ export class UserCredentialToken implements CrentialTokenInterface<UserCredentia
|
|
|
16
16
|
this.jwtExpiresIn = config.jwtExpiresIn;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* @override
|
|
21
|
+
*/
|
|
22
|
+
public async generateToken(
|
|
20
23
|
data: UserCredentialTokenValue,
|
|
21
24
|
options: { expiresIn?: string } = {}
|
|
22
25
|
): Promise<string> {
|
|
@@ -29,7 +32,10 @@ export class UserCredentialToken implements CrentialTokenInterface<UserCredentia
|
|
|
29
32
|
});
|
|
30
33
|
}
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
/**
|
|
36
|
+
* @override
|
|
37
|
+
*/
|
|
38
|
+
public async parseToken(token: string): Promise<UserCredentialTokenValue> {
|
|
33
39
|
try {
|
|
34
40
|
const decoded = jwt.verify(token, this.jwtSecret) as {
|
|
35
41
|
i: UserSchema['id'];
|
|
@@ -32,7 +32,10 @@ export class AdminLocalesController implements AdminLocalesControllerInterface {
|
|
|
32
32
|
protected localesImportValidator: ValidatorInterface<ImportLocalesData>
|
|
33
33
|
) {}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
/**
|
|
36
|
+
* @override
|
|
37
|
+
*/
|
|
38
|
+
public async getLocales(query: {
|
|
36
39
|
page: number;
|
|
37
40
|
pageSize: number;
|
|
38
41
|
orders?: BridgeOrderBy;
|
|
@@ -48,7 +51,10 @@ export class AdminLocalesController implements AdminLocalesControllerInterface {
|
|
|
48
51
|
return result;
|
|
49
52
|
}
|
|
50
53
|
|
|
51
|
-
|
|
54
|
+
/**
|
|
55
|
+
* @override
|
|
56
|
+
*/
|
|
57
|
+
public async createLocale(
|
|
52
58
|
body: Omit<LocalesSchema, 'id' | 'created_at' | 'updated_at'>
|
|
53
59
|
): Promise<{ success: boolean }> {
|
|
54
60
|
const localesParams = await this.localesValidator.getThrow(body);
|
|
@@ -59,10 +65,16 @@ export class AdminLocalesController implements AdminLocalesControllerInterface {
|
|
|
59
65
|
success: true
|
|
60
66
|
};
|
|
61
67
|
}
|
|
62
|
-
|
|
68
|
+
/**
|
|
69
|
+
* @override
|
|
70
|
+
*/
|
|
71
|
+
public async updateLocale(body: Partial<LocalesSchema>): Promise<void> {
|
|
63
72
|
await this.apiLocaleService.update(body);
|
|
64
73
|
}
|
|
65
|
-
|
|
74
|
+
/**
|
|
75
|
+
* @override
|
|
76
|
+
*/
|
|
77
|
+
public async importLocales(formData: unknown): Promise<UpsertResult> {
|
|
66
78
|
const localesParams = await this.localesImportValidator.getThrow({
|
|
67
79
|
values: formData
|
|
68
80
|
});
|
|
@@ -22,7 +22,10 @@ export class AdminUserController implements AdminUserControllerInterface {
|
|
|
22
22
|
protected apiUserService: ApiUserService
|
|
23
23
|
) {}
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* @override
|
|
27
|
+
*/
|
|
28
|
+
public async getUsers(query: {
|
|
26
29
|
page: number;
|
|
27
30
|
pageSize: number;
|
|
28
31
|
orderBy?: BridgeOrderBy;
|
|
@@ -14,7 +14,10 @@ export class LocalesController implements LocalesControllerInterface {
|
|
|
14
14
|
protected apiLocaleService: ApiLocaleService
|
|
15
15
|
) {}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* @override
|
|
19
|
+
*/
|
|
20
|
+
public async json(
|
|
18
21
|
query: LocalesControllerJsonQuery
|
|
19
22
|
): Promise<Record<string, string>> {
|
|
20
23
|
const locale = query.locale as LocaleType;
|
|
@@ -25,7 +25,10 @@ export class UserController implements UserControllerInerface {
|
|
|
25
25
|
@inject(UserService) protected userService: UserServiceInterface
|
|
26
26
|
) {}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
/**
|
|
29
|
+
* @override
|
|
30
|
+
*/
|
|
31
|
+
public async login(requestBody: LoginValidatorData): Promise<UserSchema> {
|
|
29
32
|
try {
|
|
30
33
|
if (requestBody.password) {
|
|
31
34
|
requestBody.password = this.stringEncryptor.decrypt(
|
|
@@ -47,7 +50,10 @@ export class UserController implements UserControllerInerface {
|
|
|
47
50
|
return user;
|
|
48
51
|
}
|
|
49
52
|
|
|
50
|
-
|
|
53
|
+
/**
|
|
54
|
+
* @override
|
|
55
|
+
*/
|
|
56
|
+
public async register(requestBody: LoginValidatorData): Promise<UserSchema> {
|
|
51
57
|
try {
|
|
52
58
|
if (requestBody.password) {
|
|
53
59
|
requestBody.password = this.stringEncryptor.decrypt(
|
|
@@ -71,7 +77,10 @@ export class UserController implements UserControllerInerface {
|
|
|
71
77
|
return user;
|
|
72
78
|
}
|
|
73
79
|
|
|
74
|
-
|
|
80
|
+
/**
|
|
81
|
+
* @override
|
|
82
|
+
*/
|
|
83
|
+
public async logout(): Promise<void> {
|
|
75
84
|
return await this.userService.logout();
|
|
76
85
|
}
|
|
77
86
|
}
|
|
@@ -18,7 +18,7 @@ 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
|
|
|
@@ -27,7 +27,10 @@ export class LocalesRepository implements LocalesRepositoryInterface {
|
|
|
27
27
|
@inject(Datetime) protected datetime: Datetime
|
|
28
28
|
) {}
|
|
29
29
|
|
|
30
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,7 +75,10 @@ export class LocalesRepository implements LocalesRepositoryInterface {
|
|
|
66
75
|
return (result.data as LocalesSchema[]) || null;
|
|
67
76
|
}
|
|
68
77
|
|
|
69
|
-
|
|
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> {
|
|
@@ -89,7 +101,10 @@ export class LocalesRepository implements LocalesRepositoryInterface {
|
|
|
89
101
|
});
|
|
90
102
|
}
|
|
91
103
|
|
|
92
|
-
|
|
104
|
+
/**
|
|
105
|
+
* @override
|
|
106
|
+
*/
|
|
107
|
+
public async pagination<T = LocalesSchema>(params: {
|
|
93
108
|
page: number;
|
|
94
109
|
pageSize: number;
|
|
95
110
|
orderBy?: BridgeOrderBy;
|
|
@@ -112,13 +127,14 @@ export class LocalesRepository implements LocalesRepositoryInterface {
|
|
|
112
127
|
|
|
113
128
|
/**
|
|
114
129
|
* batch upsert data, support chunk processing and concurrency control
|
|
130
|
+
* @override
|
|
115
131
|
* @param data - data to upsert
|
|
116
132
|
* @param options - options
|
|
117
133
|
* @param options.chunkSize - chunk size, default 100
|
|
118
134
|
* @param options.concurrency - concurrency, default 3
|
|
119
135
|
* @returns UpsertResult - contains success/failure details with returned data
|
|
120
136
|
*/
|
|
121
|
-
async upsert(
|
|
137
|
+
public async upsert(
|
|
122
138
|
data: Partial<LocalesSchema>[],
|
|
123
139
|
options?: {
|
|
124
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
10
|
+
/**
|
|
11
|
+
* @override
|
|
12
|
+
*/
|
|
13
|
+
public async onBefore(
|
|
11
14
|
context: ExecutorContext<BootstrapServerContextValue>
|
|
12
15
|
): Promise<void> {
|
|
13
16
|
const { IOC } = context.parameters;
|
|
@@ -34,7 +34,7 @@ export class ApiLocaleService {
|
|
|
34
34
|
protected localesRepository: LocalesRepositoryInterface
|
|
35
35
|
) {}
|
|
36
36
|
|
|
37
|
-
async getLocalesJson(
|
|
37
|
+
public async getLocalesJson(
|
|
38
38
|
localeName: string,
|
|
39
39
|
orderBy?: BridgeOrderBy
|
|
40
40
|
): Promise<Record<string, string>> {
|
|
@@ -52,7 +52,7 @@ export class ApiLocaleService {
|
|
|
52
52
|
);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
async getLocales(
|
|
55
|
+
public async getLocales(
|
|
56
56
|
params: GetLocalesParams
|
|
57
57
|
): Promise<PaginationInterface<LocalesSchema>> {
|
|
58
58
|
return this.localesRepository.pagination({
|
|
@@ -62,7 +62,7 @@ export class ApiLocaleService {
|
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
async update(data: Partial<LocalesSchema>): Promise<void> {
|
|
65
|
+
public async update(data: Partial<LocalesSchema>): Promise<void> {
|
|
66
66
|
if (!data.id || typeof data.id !== 'number') {
|
|
67
67
|
throw new Error(
|
|
68
68
|
'ID is required and must be a number for update operation'
|
|
@@ -81,7 +81,7 @@ export class ApiLocaleService {
|
|
|
81
81
|
await Promise.all(revalidatePromises);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
async create(data: Partial<LocalesSchema>): Promise<void> {
|
|
84
|
+
public async create(data: Partial<LocalesSchema>): Promise<void> {
|
|
85
85
|
await this.localesRepository.add(data as LocalesSchema);
|
|
86
86
|
|
|
87
87
|
// 清除所有支持的语言的缓存
|
|
@@ -91,7 +91,7 @@ export class ApiLocaleService {
|
|
|
91
91
|
await Promise.all(revalidatePromises);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
async importLocales(data: ImportLocalesData): Promise<UpsertResult> {
|
|
94
|
+
public async importLocales(data: ImportLocalesData): Promise<UpsertResult> {
|
|
95
95
|
const { namespace = 'common', values } = data;
|
|
96
96
|
|
|
97
97
|
const result: Record<string, Record<string, string>> = {};
|