@qlover/create-app 0.7.10 → 0.7.12
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 +88 -0
- package/dist/index.cjs +6 -6
- package/dist/index.js +6 -6
- package/dist/templates/next-app/config/Identifier/api.ts +14 -0
- package/dist/templates/next-app/config/Identifier/common.ts +7 -0
- package/dist/templates/next-app/eslint.config.mjs +17 -0
- package/dist/templates/next-app/migrations/schema/UserSchema.ts +21 -10
- package/dist/templates/next-app/next.config.ts +1 -0
- package/dist/templates/next-app/package.json +1 -0
- package/dist/templates/next-app/public/locales/en.json +4 -1
- package/dist/templates/next-app/public/locales/zh.json +4 -1
- package/dist/templates/next-app/src/app/[locale]/admin/layout.tsx +4 -7
- package/dist/templates/next-app/src/app/[locale]/admin/page.tsx +16 -4
- package/dist/templates/next-app/src/app/[locale]/admin/users/page.tsx +62 -0
- package/dist/templates/next-app/src/app/[locale]/layout.tsx +1 -1
- package/dist/templates/next-app/src/app/[locale]/login/LoginForm.tsx +1 -1
- package/dist/templates/next-app/src/app/[locale]/login/page.tsx +1 -1
- package/dist/templates/next-app/src/app/[locale]/page.tsx +3 -3
- package/dist/templates/next-app/src/app/[locale]/register/RegisterForm.tsx +1 -1
- package/dist/templates/next-app/src/app/[locale]/register/page.tsx +1 -1
- package/dist/templates/next-app/src/app/api/admin/users/route.ts +39 -0
- package/dist/templates/next-app/src/base/cases/AdminPageManager.ts +40 -0
- package/dist/templates/next-app/src/base/cases/AppConfig.ts +1 -1
- package/dist/templates/next-app/src/base/cases/DialogErrorPlugin.ts +13 -2
- package/dist/templates/next-app/src/base/cases/PageParams.ts +1 -1
- package/dist/templates/next-app/src/base/cases/RequestState.ts +20 -0
- package/dist/templates/next-app/src/base/cases/UserServiceApi.ts +1 -1
- package/dist/templates/next-app/src/base/port/AdminLayoutInterface.ts +26 -0
- package/dist/templates/next-app/src/base/port/AdminPageInterface.ts +87 -0
- package/dist/templates/next-app/src/base/port/AppApiInterface.ts +1 -1
- package/dist/templates/next-app/src/base/port/AppUserApiInterface.ts +4 -4
- package/dist/templates/next-app/src/base/port/AsyncStateInterface.ts +7 -0
- package/dist/templates/next-app/src/base/port/DBBridgeInterface.ts +3 -0
- package/dist/templates/next-app/src/base/port/PaginationInterface.ts +6 -0
- package/dist/templates/next-app/src/base/services/AdminUserService.ts +45 -0
- package/dist/templates/next-app/src/base/services/UserService.ts +1 -1
- package/dist/templates/next-app/src/base/services/adminApi/AdminApiRequester.ts +21 -0
- package/dist/templates/next-app/src/base/services/adminApi/AdminUserApi.ts +34 -0
- package/dist/templates/next-app/src/base/services/appApi/AppApiPlugin.ts +2 -2
- package/dist/templates/next-app/src/base/services/appApi/AppApiRequester.ts +56 -0
- package/dist/templates/next-app/src/base/services/appApi/AppUserApi.ts +30 -31
- package/dist/templates/next-app/src/base/services/appApi/AppUserApiBootstrap.ts +5 -4
- package/dist/templates/next-app/src/core/bootstraps/BootstrapClient.ts +1 -1
- package/dist/templates/next-app/src/core/bootstraps/BootstrapServer.ts +3 -14
- package/dist/templates/next-app/src/core/bootstraps/BootstrapsRegistry.ts +2 -2
- package/dist/templates/next-app/src/core/bootstraps/PrintBootstrap.ts +1 -1
- package/dist/templates/next-app/src/core/clientIoc/ClientIOC.ts +1 -1
- package/dist/templates/next-app/src/core/clientIoc/ClientIOCRegister.ts +1 -1
- package/dist/templates/next-app/src/core/globals.ts +1 -1
- package/dist/templates/next-app/src/core/serverIoc/ServerIOC.ts +1 -1
- package/dist/templates/next-app/src/core/serverIoc/ServerIOCRegister.ts +1 -1
- package/dist/templates/next-app/src/server/ServerAuth.ts +13 -3
- package/dist/templates/next-app/src/server/SupabaseBridge.ts +37 -2
- package/dist/templates/next-app/src/server/UserCredentialToken.ts +1 -1
- package/dist/templates/next-app/src/server/port/DBTableInterface.ts +10 -0
- package/dist/templates/next-app/src/server/port/{UserAuthInterface.ts → ServerAuthInterface.ts} +3 -1
- package/dist/templates/next-app/src/server/port/UserRepositoryInterface.ts +1 -1
- package/dist/templates/next-app/src/server/repositorys/UserRepository.ts +32 -1
- package/dist/templates/next-app/src/server/services/AdminAuthPlugin.ts +19 -0
- package/dist/templates/next-app/src/server/services/ApiUserService.ts +26 -0
- package/dist/templates/next-app/src/server/services/UserService.ts +3 -3
- package/dist/templates/next-app/src/server/validators/PaginationValidator.ts +48 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/{_default.css → _common/_default.css} +74 -1
- package/dist/templates/next-app/src/styles/css/antd-themes/{dark.css → _common/dark.css} +73 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/_common/index.css +3 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/{pink.css → _common/pink.css} +70 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/index.css +4 -3
- package/dist/templates/next-app/src/styles/css/antd-themes/menu/_default.css +108 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/menu/dark.css +67 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/menu/index.css +3 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/menu/pink.css +67 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/pagination/_default.css +33 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/pagination/dark.css +32 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/pagination/index.css +3 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/pagination/pink.css +35 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/table/_default.css +44 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/table/dark.css +43 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/table/index.css +3 -0
- package/dist/templates/next-app/src/styles/css/antd-themes/table/pink.css +43 -0
- package/dist/templates/next-app/src/uikit/components/AdminLayout.tsx +106 -0
- package/dist/templates/next-app/src/uikit/components/BaseHeader.tsx +68 -17
- package/dist/templates/next-app/src/uikit/components/BaseLayout.tsx +6 -1
- package/dist/templates/next-app/src/uikit/components/BootstrapsProvider.tsx +1 -1
- package/dist/templates/next-app/src/uikit/components/ComboProvider.tsx +11 -3
- package/dist/templates/next-app/src/uikit/components/LanguageSwitcher.tsx +1 -1
- package/dist/templates/next-app/src/uikit/components/LogoutButton.tsx +1 -1
- package/dist/templates/next-app/src/uikit/hook/useIOC.ts +1 -1
- package/dist/templates/next-app/src/uikit/hook/useMountedClient.ts +7 -1
- package/package.json +1 -1
- package/dist/templates/next-app/src/base/cases/ServerErrorHandler.ts +0 -27
- package/dist/templates/next-app/src/base/port/DBTableInterface.ts +0 -3
- package/dist/templates/next-app/src/base/services/appApi/AppUserType.ts +0 -51
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { inject, injectable } from 'inversify';
|
|
2
|
+
import {
|
|
3
|
+
AdminPageInterface,
|
|
4
|
+
type AdminPageListParams,
|
|
5
|
+
AdminPageState
|
|
6
|
+
} from '../port/AdminPageInterface';
|
|
7
|
+
import { AdminUserApi } from './adminApi/AdminUserApi';
|
|
8
|
+
import { RequestState } from '../cases/RequestState';
|
|
9
|
+
import type { PaginationInterface } from '../port/PaginationInterface';
|
|
10
|
+
|
|
11
|
+
@injectable()
|
|
12
|
+
export class AdminUserService extends AdminPageInterface<AdminPageState> {
|
|
13
|
+
constructor(@inject(AdminUserApi) protected adminUserApi: AdminUserApi) {
|
|
14
|
+
super(() => new AdminPageState());
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override async fetchList(
|
|
18
|
+
params: Partial<AdminPageListParams>
|
|
19
|
+
): Promise<PaginationInterface<unknown>> {
|
|
20
|
+
this.changeListState(new RequestState(true));
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const response = await this.adminUserApi.getUserList(
|
|
24
|
+
Object.assign({}, this.state.listParams, params)
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
if (response.data.success) {
|
|
28
|
+
const paginationData = response.data
|
|
29
|
+
.data as PaginationInterface<unknown>;
|
|
30
|
+
|
|
31
|
+
this.changeListState(new RequestState(false, paginationData));
|
|
32
|
+
|
|
33
|
+
return paginationData;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
this.changeListState(
|
|
37
|
+
new RequestState(false, null, response.data.message)
|
|
38
|
+
);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
this.changeListState(new RequestState(false, null, error));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return this.state.listState.result!;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { injectable, inject } from 'inversify';
|
|
2
|
+
import type { UserSchema } from '@migrations/schema/UserSchema';
|
|
2
3
|
import { AppConfig } from '../cases/AppConfig';
|
|
3
4
|
import { UserServiceApi } from '../cases/UserServiceApi';
|
|
4
5
|
import { UserServiceInterface } from '../port/UserServiceInterface';
|
|
5
|
-
import type { UserSchema } from '@migrations/schema/UserSchema';
|
|
6
6
|
import type { UserAuthApiInterface } from '@qlover/corekit-bridge';
|
|
7
7
|
|
|
8
8
|
@injectable()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FetchAbortPlugin,
|
|
3
|
+
RequestAdapterFetch,
|
|
4
|
+
RequestTransaction
|
|
5
|
+
} from '@qlover/fe-corekit';
|
|
6
|
+
import { inject, injectable } from 'inversify';
|
|
7
|
+
import type { AppApiConfig } from '../appApi/AppApiRequester';
|
|
8
|
+
|
|
9
|
+
@injectable()
|
|
10
|
+
export class AdminApiRequester extends RequestTransaction<AppApiConfig> {
|
|
11
|
+
constructor(
|
|
12
|
+
@inject(FetchAbortPlugin) protected abortPlugin: FetchAbortPlugin
|
|
13
|
+
) {
|
|
14
|
+
super(
|
|
15
|
+
new RequestAdapterFetch({
|
|
16
|
+
baseURL: '/api/admin',
|
|
17
|
+
responseType: 'json'
|
|
18
|
+
})
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { inject, injectable } from 'inversify';
|
|
2
|
+
import type { AdminPageListParams } from '@/base/port/AdminPageInterface';
|
|
3
|
+
import type { PaginationInterface } from '@/base/port/PaginationInterface';
|
|
4
|
+
import {
|
|
5
|
+
AppApiRequester,
|
|
6
|
+
type AppApiConfig,
|
|
7
|
+
type AppApiTransaction
|
|
8
|
+
} from '../appApi/AppApiRequester';
|
|
9
|
+
import type { RequestTransaction } from '@qlover/fe-corekit';
|
|
10
|
+
|
|
11
|
+
export type AdminUserListTransaction = AppApiTransaction<
|
|
12
|
+
AdminPageListParams,
|
|
13
|
+
PaginationInterface<unknown>
|
|
14
|
+
>;
|
|
15
|
+
|
|
16
|
+
@injectable()
|
|
17
|
+
export class AdminUserApi {
|
|
18
|
+
constructor(
|
|
19
|
+
@inject(AppApiRequester)
|
|
20
|
+
protected client: RequestTransaction<AppApiConfig>
|
|
21
|
+
) {}
|
|
22
|
+
|
|
23
|
+
async getUserList(
|
|
24
|
+
params: AdminPageListParams
|
|
25
|
+
): Promise<AdminUserListTransaction['response']> {
|
|
26
|
+
const response = await this.client.request<AdminUserListTransaction>({
|
|
27
|
+
url: '/admin/users',
|
|
28
|
+
method: 'GET',
|
|
29
|
+
params: params as unknown as Record<string, unknown>
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
return response;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
type ExecutorPlugin
|
|
6
6
|
} from '@qlover/fe-corekit';
|
|
7
7
|
import type { AppApiErrorInterface } from '@/base/port/AppApiInterface';
|
|
8
|
-
import type {
|
|
8
|
+
import type { AppApiConfig } from './AppApiRequester';
|
|
9
9
|
|
|
10
10
|
export class AppApiPlugin implements ExecutorPlugin {
|
|
11
11
|
readonly pluginName = 'AppApiPlugin';
|
|
@@ -30,7 +30,7 @@ export class AppApiPlugin implements ExecutorPlugin {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
async onError(
|
|
33
|
-
context: ExecutorContext<
|
|
33
|
+
context: ExecutorContext<AppApiConfig>
|
|
34
34
|
): Promise<ExecutorError | void> {
|
|
35
35
|
const { error, parameters } = context;
|
|
36
36
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FetchAbortPlugin,
|
|
3
|
+
RequestAdapterFetch,
|
|
4
|
+
RequestTransaction
|
|
5
|
+
} from '@qlover/fe-corekit';
|
|
6
|
+
import { inject, injectable } from 'inversify';
|
|
7
|
+
import type { RequestEncryptPluginProps } from '@/base/cases/RequestEncryptPlugin';
|
|
8
|
+
import type { AppApiResult } from '@/base/port/AppApiInterface';
|
|
9
|
+
import type {
|
|
10
|
+
RequestAdapterConfig,
|
|
11
|
+
RequestAdapterResponse,
|
|
12
|
+
RequestTransactionInterface
|
|
13
|
+
} from '@qlover/fe-corekit';
|
|
14
|
+
|
|
15
|
+
export interface AppApiConfig<Request = unknown>
|
|
16
|
+
extends RequestAdapterConfig<Request>,
|
|
17
|
+
RequestEncryptPluginProps<Request> {}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* UserApiResponse
|
|
21
|
+
*
|
|
22
|
+
* @description
|
|
23
|
+
* UserApiResponse is the response for the UserApi.
|
|
24
|
+
*
|
|
25
|
+
* extends:
|
|
26
|
+
* - RequestAdapterResponse<Request, Response>
|
|
27
|
+
*/
|
|
28
|
+
export type AppApiResponse<
|
|
29
|
+
Request = unknown,
|
|
30
|
+
Response = unknown
|
|
31
|
+
> = RequestAdapterResponse<Request, AppApiResult<Response>>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* UserApi common transaction
|
|
35
|
+
*/
|
|
36
|
+
export interface AppApiTransaction<Request = unknown, Response = unknown>
|
|
37
|
+
extends RequestTransactionInterface<
|
|
38
|
+
AppApiConfig<Request>,
|
|
39
|
+
AppApiResponse<Request, Response>
|
|
40
|
+
> {
|
|
41
|
+
data: AppApiConfig<Request>['data'];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@injectable()
|
|
45
|
+
export class AppApiRequester extends RequestTransaction<AppApiConfig> {
|
|
46
|
+
constructor(
|
|
47
|
+
@inject(FetchAbortPlugin) protected abortPlugin: FetchAbortPlugin
|
|
48
|
+
) {
|
|
49
|
+
super(
|
|
50
|
+
new RequestAdapterFetch({
|
|
51
|
+
baseURL: '/api',
|
|
52
|
+
responseType: 'json'
|
|
53
|
+
})
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -1,16 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
FetchAbortPlugin,
|
|
3
|
-
RequestTransaction,
|
|
4
|
-
RequestAdapterFetch
|
|
5
|
-
} from '@qlover/fe-corekit';
|
|
6
1
|
import { inject, injectable } from 'inversify';
|
|
7
|
-
import type {
|
|
2
|
+
import type { AppApiResult } from '@/base/port/AppApiInterface';
|
|
8
3
|
import type { AppUserApiInterface } from '@/base/port/AppUserApiInterface';
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
import { AppApiRequester } from './AppApiRequester';
|
|
5
|
+
import type { AppApiConfig, AppApiTransaction } from './AppApiRequester';
|
|
6
|
+
import type { RequestTransaction } from '@qlover/fe-corekit';
|
|
7
|
+
|
|
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
|
+
>;
|
|
14
22
|
|
|
15
23
|
/**
|
|
16
24
|
* UserApi
|
|
@@ -20,25 +28,16 @@ import type {
|
|
|
20
28
|
*
|
|
21
29
|
*/
|
|
22
30
|
@injectable()
|
|
23
|
-
export class AppUserApi
|
|
24
|
-
extends RequestTransaction<UserApiConfig>
|
|
25
|
-
implements AppUserApiInterface
|
|
26
|
-
{
|
|
31
|
+
export class AppUserApi implements AppUserApiInterface {
|
|
27
32
|
constructor(
|
|
28
|
-
@inject(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
new RequestAdapterFetch({
|
|
32
|
-
baseURL: '/api',
|
|
33
|
-
responseType: 'json'
|
|
34
|
-
})
|
|
35
|
-
);
|
|
36
|
-
}
|
|
33
|
+
@inject(AppApiRequester)
|
|
34
|
+
protected client: RequestTransaction<AppApiConfig>
|
|
35
|
+
) {}
|
|
37
36
|
|
|
38
37
|
async login(
|
|
39
38
|
params: UserApiLoginTransaction['data']
|
|
40
|
-
): Promise<
|
|
41
|
-
const response = await this.request<UserApiLoginTransaction>({
|
|
39
|
+
): Promise<AppApiResult<unknown>> {
|
|
40
|
+
const response = await this.client.request<UserApiLoginTransaction>({
|
|
42
41
|
url: '/user/login',
|
|
43
42
|
method: 'POST',
|
|
44
43
|
data: params,
|
|
@@ -50,8 +49,8 @@ export class AppUserApi
|
|
|
50
49
|
|
|
51
50
|
async register(
|
|
52
51
|
params: UserApiRegisterTransaction['data']
|
|
53
|
-
): Promise<
|
|
54
|
-
const response = await this.request<UserApiRegisterTransaction>({
|
|
52
|
+
): Promise<AppApiResult<unknown>> {
|
|
53
|
+
const response = await this.client.request<UserApiRegisterTransaction>({
|
|
55
54
|
url: '/user/register',
|
|
56
55
|
method: 'POST',
|
|
57
56
|
data: params,
|
|
@@ -61,12 +60,12 @@ export class AppUserApi
|
|
|
61
60
|
return response.data;
|
|
62
61
|
}
|
|
63
62
|
|
|
64
|
-
async logout(): Promise<
|
|
65
|
-
const response = await this.request({
|
|
63
|
+
async logout(): Promise<AppApiResult<unknown>> {
|
|
64
|
+
const response = await this.client.request({
|
|
66
65
|
url: '/user/logout',
|
|
67
66
|
method: 'POST'
|
|
68
67
|
});
|
|
69
68
|
|
|
70
|
-
return response.data as
|
|
69
|
+
return response.data as AppApiResult<unknown>;
|
|
71
70
|
}
|
|
72
71
|
}
|
|
@@ -4,8 +4,8 @@ import { DialogErrorPlugin } from '@/base/cases/DialogErrorPlugin';
|
|
|
4
4
|
import { RequestEncryptPlugin } from '@/base/cases/RequestEncryptPlugin';
|
|
5
5
|
import { StringEncryptor } from '@/base/cases/StringEncryptor';
|
|
6
6
|
import { AppApiPlugin } from './AppApiPlugin';
|
|
7
|
-
import {
|
|
8
|
-
import type {
|
|
7
|
+
import { AppApiRequester } from './AppApiRequester';
|
|
8
|
+
import type { AppApiConfig } from './AppApiRequester';
|
|
9
9
|
import type {
|
|
10
10
|
BootstrapContext,
|
|
11
11
|
BootstrapExecutorPlugin
|
|
@@ -18,7 +18,7 @@ export class AppUserApiBootstrap implements BootstrapExecutorPlugin {
|
|
|
18
18
|
constructor(protected serializer: SerializerIneterface) {}
|
|
19
19
|
|
|
20
20
|
onBefore({ parameters: { ioc } }: BootstrapContext): void | Promise<void> {
|
|
21
|
-
const appUserApi = ioc.get<
|
|
21
|
+
const appUserApi = ioc.get<AppApiRequester>(AppApiRequester);
|
|
22
22
|
|
|
23
23
|
appUserApi.usePlugin(new FetchURLPlugin());
|
|
24
24
|
appUserApi.usePlugin(new RequestEncryptPlugin(ioc.get(StringEncryptor)));
|
|
@@ -29,11 +29,12 @@ export class AppUserApiBootstrap implements BootstrapExecutorPlugin {
|
|
|
29
29
|
);
|
|
30
30
|
appUserApi.usePlugin(new AppApiPlugin());
|
|
31
31
|
appUserApi.usePlugin(ioc.get(DialogErrorPlugin));
|
|
32
|
+
console.log('jj AppUserApiBootstrap success');
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
protected requestDataSerializer(
|
|
35
36
|
data: unknown,
|
|
36
|
-
context: ExecutorContext<
|
|
37
|
+
context: ExecutorContext<AppApiConfig>
|
|
37
38
|
): unknown {
|
|
38
39
|
if (data instanceof FormData) {
|
|
39
40
|
return data;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Bootstrap } from '@qlover/corekit-bridge';
|
|
2
2
|
import { isObject } from 'lodash';
|
|
3
3
|
import { browserGlobalsName } from '@config/common';
|
|
4
|
+
import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
4
5
|
import { BootstrapsRegistry } from './BootstrapsRegistry';
|
|
5
6
|
import * as globals from '../globals';
|
|
6
|
-
import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
7
7
|
import type {
|
|
8
8
|
IOCContainerInterface,
|
|
9
9
|
IOCFunctionInterface
|
|
@@ -12,23 +12,11 @@ import {
|
|
|
12
12
|
type PromiseTask,
|
|
13
13
|
type ExecutorPlugin
|
|
14
14
|
} from '@qlover/fe-corekit';
|
|
15
|
-
import { I, type IOCIdentifierMapServer } from '@config/IOCIdentifier';
|
|
16
15
|
import type { ServerInterface } from '@/server/port/ServerInterface';
|
|
16
|
+
import { I, type IOCIdentifierMapServer } from '@config/IOCIdentifier';
|
|
17
17
|
import { ServerIOC } from '../serverIoc/ServerIOC';
|
|
18
18
|
|
|
19
|
-
export interface BootstrapServerResult {
|
|
20
|
-
locale: string;
|
|
21
|
-
messages: Record<string, string>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
19
|
export interface BootstrapServerContextValue extends BootstrapContextValue {
|
|
25
|
-
locale: string;
|
|
26
|
-
messages: Record<string, string>;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
interface BootstrapServerContext {
|
|
30
|
-
logger: LoggerInterface;
|
|
31
|
-
root: Record<string, unknown>;
|
|
32
20
|
IOC: IOCFunctionInterface<IOCIdentifierMapServer, IOCContainerInterface>;
|
|
33
21
|
}
|
|
34
22
|
|
|
@@ -90,11 +78,12 @@ export class BootstrapServer implements ServerInterface {
|
|
|
90
78
|
}
|
|
91
79
|
|
|
92
80
|
execNoError<Result>(
|
|
93
|
-
task?: PromiseTask<Result,
|
|
81
|
+
task?: PromiseTask<Result, BootstrapServerContextValue>
|
|
94
82
|
): Promise<Result | ExecutorError> {
|
|
95
83
|
const context = {
|
|
96
84
|
logger: this.logger,
|
|
97
85
|
root: this.root,
|
|
86
|
+
ioc: this.IOC.implemention!,
|
|
98
87
|
IOC: this.IOC
|
|
99
88
|
};
|
|
100
89
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { I, IOCIdentifier } from '@config/IOCIdentifier';
|
|
2
1
|
import { AppUserApiBootstrap } from '@/base/services/appApi/AppUserApiBootstrap';
|
|
2
|
+
import { I, IOCIdentifier } from '@config/IOCIdentifier';
|
|
3
|
+
import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
3
4
|
import { IocIdentifierTest } from './IocIdentifierTest';
|
|
4
5
|
import { printBootstrap } from './PrintBootstrap';
|
|
5
6
|
import type { BootstrapAppArgs } from './BootstrapClient';
|
|
6
|
-
import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
7
7
|
import type {
|
|
8
8
|
BootstrapExecutorPlugin,
|
|
9
9
|
EnvConfigInterface,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { browserGlobalsName } from '@config/common';
|
|
2
1
|
import { AppConfig } from '@/base/cases/AppConfig';
|
|
2
|
+
import { browserGlobalsName } from '@config/common';
|
|
3
3
|
import type { BootstrapExecutorPlugin } from '@qlover/corekit-bridge';
|
|
4
4
|
|
|
5
5
|
export const printBootstrap: BootstrapExecutorPlugin = {
|
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
} from '@qlover/corekit-bridge';
|
|
6
6
|
import { InversifyContainer } from '@/base/cases/InversifyContainer';
|
|
7
7
|
import type { IOCInterface } from '@/base/port/IOCInterface';
|
|
8
|
+
import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
8
9
|
import { ClientIOCRegister } from './ClientIOCRegister';
|
|
9
10
|
import { appConfig } from '../globals';
|
|
10
|
-
import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
11
11
|
|
|
12
12
|
export class ClientIOC
|
|
13
13
|
implements IOCInterface<IOCIdentifierMap, IOCContainerInterface>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { IOCIdentifier as I } from '@config/IOCIdentifier';
|
|
2
1
|
import { RouterService } from '@/base/cases/RouterService';
|
|
3
2
|
import type { IocRegisterOptions } from '@/base/port/IOCInterface';
|
|
4
3
|
import { I18nService } from '@/base/services/I18nService';
|
|
5
4
|
import { UserService } from '@/base/services/UserService';
|
|
5
|
+
import { IOCIdentifier as I } from '@config/IOCIdentifier';
|
|
6
6
|
import { dialogHandler, logger, JSON } from '../globals';
|
|
7
7
|
import type {
|
|
8
8
|
IOCContainerInterface,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// ! global variables, don't import any dependencies and don't have side effects
|
|
2
2
|
import { ColorFormatter, ConsoleHandler, Logger } from '@qlover/corekit-bridge';
|
|
3
3
|
import { JSONSerializer } from '@qlover/fe-corekit';
|
|
4
|
-
import { loggerStyles } from '@config/common';
|
|
5
4
|
import { AppConfig } from '@/base/cases/AppConfig';
|
|
6
5
|
import { DialogHandler } from '@/base/cases/DialogHandler';
|
|
6
|
+
import { loggerStyles } from '@config/common';
|
|
7
7
|
|
|
8
8
|
export const appConfig = new AppConfig();
|
|
9
9
|
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
import { AppConfig } from '@/base/cases/AppConfig';
|
|
7
7
|
import { InversifyContainer } from '@/base/cases/InversifyContainer';
|
|
8
8
|
import type { IOCInterface } from '@/base/port/IOCInterface';
|
|
9
|
-
import { ServerIOCRegister } from './ServerIOCRegister';
|
|
10
9
|
import type { IOCIdentifierMapServer } from '@config/IOCIdentifier';
|
|
10
|
+
import { ServerIOCRegister } from './ServerIOCRegister';
|
|
11
11
|
|
|
12
12
|
export class ServerIOC
|
|
13
13
|
implements IOCInterface<IOCIdentifierMapServer, IOCContainerInterface>
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
type IOCManagerInterface,
|
|
7
7
|
type IOCRegisterInterface
|
|
8
8
|
} from '@qlover/corekit-bridge';
|
|
9
|
-
import { IOCIdentifier as I } from '@config/IOCIdentifier';
|
|
10
9
|
import type { IocRegisterOptions } from '@/base/port/IOCInterface';
|
|
10
|
+
import { IOCIdentifier as I } from '@config/IOCIdentifier';
|
|
11
11
|
|
|
12
12
|
export class ServerIOCRegister
|
|
13
13
|
implements IOCRegisterInterface<IOCContainerInterface, IocRegisterOptions>
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import { ExecutorError } from '@qlover/fe-corekit';
|
|
1
2
|
import { inject, injectable } from 'inversify';
|
|
2
3
|
import { cookies } from 'next/headers';
|
|
3
|
-
import { I } from '@config/IOCIdentifier';
|
|
4
4
|
import type { AppConfig } from '@/base/cases/AppConfig';
|
|
5
|
+
import { API_NOT_AUTHORIZED } from '@config/Identifier';
|
|
6
|
+
import { I } from '@config/IOCIdentifier';
|
|
5
7
|
import { UserCredentialToken } from './UserCredentialToken';
|
|
6
|
-
import type {
|
|
8
|
+
import type { ServerAuthInterface } from './port/ServerAuthInterface';
|
|
7
9
|
|
|
8
10
|
@injectable()
|
|
9
|
-
export class ServerAuth implements
|
|
11
|
+
export class ServerAuth implements ServerAuthInterface {
|
|
10
12
|
protected userTokenKey: string;
|
|
11
13
|
constructor(
|
|
12
14
|
@inject(I.AppConfig) protected server: AppConfig,
|
|
@@ -47,4 +49,12 @@ export class ServerAuth implements UserAuthInterface {
|
|
|
47
49
|
const cookieStore = await cookies();
|
|
48
50
|
cookieStore.delete(this.userTokenKey);
|
|
49
51
|
}
|
|
52
|
+
|
|
53
|
+
async throwIfNotAuth(): Promise<void> {
|
|
54
|
+
const hasAuth = await this.hasAuth();
|
|
55
|
+
|
|
56
|
+
if (!hasAuth) {
|
|
57
|
+
throw new ExecutorError(API_NOT_AUTHORIZED, 'Not authorized');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
50
60
|
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createClient,
|
|
3
3
|
type PostgrestSingleResponse,
|
|
4
|
-
type SupabaseClient
|
|
4
|
+
type SupabaseClient,
|
|
5
|
+
type PostgrestResponse
|
|
5
6
|
} from '@supabase/supabase-js';
|
|
6
7
|
import { injectable, inject } from 'inversify';
|
|
7
|
-
import { I } from '@config/IOCIdentifier';
|
|
8
8
|
import type { AppConfig } from '@/base/cases/AppConfig';
|
|
9
9
|
import type {
|
|
10
10
|
BridgeEvent,
|
|
11
11
|
DBBridgeInterface,
|
|
12
12
|
Where
|
|
13
13
|
} from '@/base/port/DBBridgeInterface';
|
|
14
|
+
import { I } from '@config/IOCIdentifier';
|
|
14
15
|
import type { LoggerInterface } from '@qlover/logger';
|
|
15
16
|
import type { PostgrestFilterBuilder } from '@supabase/postgrest-js';
|
|
16
17
|
|
|
@@ -121,4 +122,38 @@ export class SupabaseBridge implements DBBridgeInterface {
|
|
|
121
122
|
|
|
122
123
|
return this.catch(await handler);
|
|
123
124
|
}
|
|
125
|
+
|
|
126
|
+
async pagination(event: BridgeEvent): Promise<PostgrestResponse<unknown>> {
|
|
127
|
+
const { table, fields = '*', where, page = 1, pageSize = 10 } = event;
|
|
128
|
+
const selectFields = Array.isArray(fields) ? fields.join(',') : fields;
|
|
129
|
+
|
|
130
|
+
// 获取总数
|
|
131
|
+
const countHandler = this.supabase
|
|
132
|
+
.from(table)
|
|
133
|
+
.select('*', { count: 'exact', head: true });
|
|
134
|
+
|
|
135
|
+
this.handleWhere(countHandler, where ?? []);
|
|
136
|
+
const countResult = await this.catch(await countHandler);
|
|
137
|
+
|
|
138
|
+
// 获取分页数据
|
|
139
|
+
const handler = this.supabase
|
|
140
|
+
.from(table)
|
|
141
|
+
.select(selectFields)
|
|
142
|
+
.range((page - 1) * pageSize, page * pageSize - 1);
|
|
143
|
+
|
|
144
|
+
this.handleWhere(handler, where ?? []);
|
|
145
|
+
const result = await this.catch(await handler);
|
|
146
|
+
|
|
147
|
+
if (result.error) {
|
|
148
|
+
return result as PostgrestResponse<unknown>;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
data: Array.isArray(result.data) ? result.data : [],
|
|
153
|
+
error: null,
|
|
154
|
+
count: countResult.count,
|
|
155
|
+
status: result.status,
|
|
156
|
+
statusText: result.statusText
|
|
157
|
+
};
|
|
158
|
+
}
|
|
124
159
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { inject, injectable } from 'inversify';
|
|
2
2
|
import jwt from 'jsonwebtoken';
|
|
3
3
|
import { AppConfig } from '@/base/cases/AppConfig';
|
|
4
|
-
import type { CrentialTokenInterface } from './port/CrentialTokenInterface';
|
|
5
4
|
import type { UserSchema } from '@migrations/schema/UserSchema';
|
|
5
|
+
import type { CrentialTokenInterface } from './port/CrentialTokenInterface';
|
|
6
6
|
|
|
7
7
|
export type UserCredentialTokenValue = Pick<UserSchema, 'id' | 'email'>;
|
|
8
8
|
|
package/dist/templates/next-app/src/server/port/{UserAuthInterface.ts → ServerAuthInterface.ts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export interface
|
|
1
|
+
export interface ServerAuthInterface {
|
|
2
2
|
setAuth(credential_token: string): Promise<void>;
|
|
3
3
|
|
|
4
4
|
getAuth(): Promise<string>;
|
|
@@ -6,4 +6,6 @@ export interface UserAuthInterface {
|
|
|
6
6
|
clear(): Promise<void>;
|
|
7
7
|
|
|
8
8
|
hasAuth(): Promise<boolean>;
|
|
9
|
+
|
|
10
|
+
throwIfNotAuth(): Promise<void>;
|
|
9
11
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DBTableInterface } from '@/
|
|
1
|
+
import type { DBTableInterface } from '@/server/port/DBTableInterface';
|
|
2
2
|
import type { UserSchema } from '@migrations/schema/UserSchema';
|
|
3
3
|
|
|
4
4
|
export interface UserRepositoryInterface extends DBTableInterface {
|
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
import { inject, injectable } from 'inversify';
|
|
2
2
|
import { isEmpty, last } from 'lodash';
|
|
3
3
|
import type { DBBridgeInterface } from '@/base/port/DBBridgeInterface';
|
|
4
|
+
import type { PaginationInterface } from '@/base/port/PaginationInterface';
|
|
5
|
+
import type { UserSchema } from '@migrations/schema/UserSchema';
|
|
4
6
|
import { SupabaseBridge } from '../SupabaseBridge';
|
|
5
7
|
import type { UserRepositoryInterface } from '../port/UserRepositoryInterface';
|
|
6
|
-
import type { UserSchema } from '@migrations/schema/UserSchema';
|
|
7
8
|
|
|
8
9
|
@injectable()
|
|
9
10
|
export class UserRepository implements UserRepositoryInterface {
|
|
10
11
|
readonly name = 'fe_users';
|
|
11
12
|
|
|
13
|
+
protected safeFields = [
|
|
14
|
+
'created_at',
|
|
15
|
+
// 'credential_token',
|
|
16
|
+
'email',
|
|
17
|
+
'email_confirmed_at',
|
|
18
|
+
'id',
|
|
19
|
+
// 'password',
|
|
20
|
+
'role',
|
|
21
|
+
'updated_at'
|
|
22
|
+
];
|
|
23
|
+
|
|
12
24
|
constructor(@inject(SupabaseBridge) protected dbBridge: DBBridgeInterface) {}
|
|
13
25
|
|
|
14
26
|
getAll(): Promise<unknown> {
|
|
@@ -60,4 +72,23 @@ export class UserRepository implements UserRepositoryInterface {
|
|
|
60
72
|
where: [['id', '=', id]]
|
|
61
73
|
});
|
|
62
74
|
}
|
|
75
|
+
|
|
76
|
+
async pagination<UserSchema>(params: {
|
|
77
|
+
page: number;
|
|
78
|
+
pageSize: number;
|
|
79
|
+
}): Promise<PaginationInterface<UserSchema>> {
|
|
80
|
+
const result = await this.dbBridge.pagination({
|
|
81
|
+
table: this.name,
|
|
82
|
+
page: params.page,
|
|
83
|
+
pageSize: params.pageSize,
|
|
84
|
+
fields: this.safeFields
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
list: result.data as UserSchema[],
|
|
89
|
+
total: result.count ?? 0,
|
|
90
|
+
page: params.page,
|
|
91
|
+
pageSize: params.pageSize
|
|
92
|
+
};
|
|
93
|
+
}
|
|
63
94
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { BootstrapServerContextValue } from '@/core/bootstraps/BootstrapServer';
|
|
2
|
+
import { ServerAuth } from '../ServerAuth';
|
|
3
|
+
import type { ServerAuthInterface } from '../port/ServerAuthInterface';
|
|
4
|
+
import type { BootstrapExecutorPlugin } from '@qlover/corekit-bridge';
|
|
5
|
+
import type { ExecutorContext } from '@qlover/fe-corekit';
|
|
6
|
+
|
|
7
|
+
export class AdminAuthPlugin implements BootstrapExecutorPlugin {
|
|
8
|
+
pluginName = 'AdminAuthPlugin';
|
|
9
|
+
|
|
10
|
+
async onBefore(
|
|
11
|
+
context: ExecutorContext<BootstrapServerContextValue>
|
|
12
|
+
): Promise<void> {
|
|
13
|
+
const { IOC } = context.parameters;
|
|
14
|
+
|
|
15
|
+
const serverAuth: ServerAuthInterface = IOC(ServerAuth);
|
|
16
|
+
|
|
17
|
+
await serverAuth.throwIfNotAuth();
|
|
18
|
+
}
|
|
19
|
+
}
|