@qlover/create-app 0.7.9 → 0.7.11
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 +184 -0
- package/dist/index.cjs +3 -3
- package/dist/index.js +3 -3
- package/dist/templates/next-app/.env.template +8 -4
- package/dist/templates/next-app/config/IOCIdentifier.ts +4 -1
- package/dist/templates/next-app/config/Identifier/api.ts +34 -0
- package/dist/templates/next-app/config/Identifier/common.ts +7 -0
- package/dist/templates/next-app/config/Identifier/index.ts +2 -0
- package/dist/templates/next-app/config/Identifier/page.login.ts +2 -2
- package/dist/templates/next-app/config/Identifier/page.register.ts +43 -22
- package/dist/templates/next-app/config/Identifier/validator.ts +34 -0
- package/dist/templates/next-app/config/i18n/index.ts +1 -0
- package/dist/templates/next-app/config/i18n/register18n.ts +44 -0
- package/dist/templates/next-app/eslint.config.mjs +17 -0
- package/dist/templates/next-app/migrations/schema/UserSchema.ts +24 -0
- package/dist/templates/next-app/migrations/sql/1694244000000.sql +10 -0
- package/dist/templates/next-app/next.config.ts +1 -0
- package/dist/templates/next-app/package.json +12 -2
- package/dist/templates/next-app/public/locales/en.json +19 -2
- package/dist/templates/next-app/public/locales/zh.json +19 -2
- package/dist/templates/next-app/src/app/[locale]/admin/layout.tsx +18 -0
- package/dist/templates/next-app/src/app/[locale]/admin/page.tsx +22 -0
- 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 +26 -6
- package/dist/templates/next-app/src/app/[locale]/login/page.tsx +7 -5
- package/dist/templates/next-app/src/app/[locale]/page.tsx +5 -5
- package/dist/templates/next-app/src/app/[locale]/register/RegisterForm.tsx +176 -0
- package/dist/templates/next-app/src/app/[locale]/register/page.tsx +79 -0
- package/dist/templates/next-app/src/app/api/admin/users/route.ts +39 -0
- package/dist/templates/next-app/src/app/api/user/login/route.ts +50 -0
- package/dist/templates/next-app/src/app/api/user/logout/route.ts +27 -0
- package/dist/templates/next-app/src/app/api/user/register/route.ts +50 -0
- package/dist/templates/next-app/src/base/cases/AdminPageManager.ts +40 -0
- package/dist/templates/next-app/src/base/cases/AppConfig.ts +19 -0
- package/dist/templates/next-app/src/base/cases/DialogErrorPlugin.ts +46 -0
- package/dist/templates/next-app/src/base/cases/PageParams.ts +1 -1
- package/dist/templates/next-app/src/base/cases/RequestEncryptPlugin.ts +70 -0
- package/dist/templates/next-app/src/base/cases/RequestState.ts +20 -0
- package/dist/templates/next-app/src/base/cases/RouterService.ts +4 -0
- package/dist/templates/next-app/src/base/cases/StringEncryptor.ts +67 -0
- package/dist/templates/next-app/src/base/cases/UserServiceApi.ts +48 -0
- 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 +14 -0
- package/dist/templates/next-app/src/base/port/AppUserApiInterface.ts +15 -0
- package/dist/templates/next-app/src/base/port/AsyncStateInterface.ts +7 -0
- package/dist/templates/next-app/src/base/port/DBBridgeInterface.ts +21 -0
- package/dist/templates/next-app/src/base/port/DBMigrationInterface.ts +92 -0
- package/dist/templates/next-app/src/base/port/I18nServiceInterface.ts +3 -2
- package/dist/templates/next-app/src/base/port/MigrationApiInterface.ts +3 -0
- package/dist/templates/next-app/src/base/port/PaginationInterface.ts +6 -0
- package/dist/templates/next-app/src/base/port/ServerApiResponseInterface.ts +6 -0
- package/dist/templates/next-app/src/base/port/UserServiceInterface.ts +3 -2
- package/dist/templates/next-app/src/base/services/AdminUserService.ts +45 -0
- package/dist/templates/next-app/src/base/services/I18nService.ts +9 -45
- package/dist/templates/next-app/src/base/services/UserService.ts +9 -8
- 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 +63 -0
- package/dist/templates/next-app/src/base/services/appApi/AppApiRequester.ts +56 -0
- package/dist/templates/next-app/src/base/services/appApi/AppUserApi.ts +71 -0
- package/dist/templates/next-app/src/base/services/appApi/AppUserApiBootstrap.ts +49 -0
- package/dist/templates/next-app/src/base/services/migrations/MigrationsApi.ts +43 -0
- package/dist/templates/next-app/src/core/bootstraps/BootstrapClient.ts +1 -1
- package/dist/templates/next-app/src/core/bootstraps/BootstrapServer.ts +26 -12
- package/dist/templates/next-app/src/core/bootstraps/BootstrapsRegistry.ts +5 -4
- 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/AppErrorApi.ts +10 -0
- package/dist/templates/next-app/src/server/AppSuccessApi.ts +7 -0
- package/dist/templates/next-app/src/server/PasswordEncrypt.ts +12 -0
- package/dist/templates/next-app/src/server/ServerAuth.ts +60 -0
- package/dist/templates/next-app/src/server/SupabaseBridge.ts +159 -0
- package/dist/templates/next-app/src/server/UserCredentialToken.ts +49 -0
- package/dist/templates/next-app/src/server/port/CrentialTokenInterface.ts +5 -0
- package/dist/templates/next-app/src/server/port/DBTableInterface.ts +10 -0
- package/dist/templates/next-app/src/server/port/ServerAuthInterface.ts +11 -0
- package/dist/templates/next-app/src/server/port/ServerInterface.ts +22 -0
- package/dist/templates/next-app/src/server/port/UserRepositoryInterface.ts +15 -0
- package/dist/templates/next-app/src/server/port/UserServiceInterface.ts +8 -0
- package/dist/templates/next-app/src/server/port/ValidatorInterface.ts +23 -0
- package/dist/templates/next-app/src/server/repositorys/UserRepository.ts +94 -0
- 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 +105 -0
- package/dist/templates/next-app/src/server/validators/LoginValidator.ts +79 -0
- 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 +9 -2
- 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 +21 -11
- 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/dist/templates/next-app/tsconfig.json +3 -1
- package/package.json +2 -2
- package/dist/templates/next-app/src/base/cases/ServerAuth.ts +0 -17
- package/dist/templates/next-app/src/base/cases/ServerErrorHandler.ts +0 -27
- package/dist/templates/next-app/src/base/port/ServerAuthInterface.ts +0 -3
- package/dist/templates/next-app/src/base/port/ServerInterface.ts +0 -12
- /package/dist/templates/next-app/src/{app/[locale]/login → uikit/components}/FeatureItem.tsx +0 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ExecutorError,
|
|
3
|
+
RequestError,
|
|
4
|
+
type ExecutorContext,
|
|
5
|
+
type ExecutorPlugin
|
|
6
|
+
} from '@qlover/fe-corekit';
|
|
7
|
+
import type { AppApiErrorInterface } from '@/base/port/AppApiInterface';
|
|
8
|
+
import type { AppApiConfig } from './AppApiRequester';
|
|
9
|
+
|
|
10
|
+
export class AppApiPlugin implements ExecutorPlugin {
|
|
11
|
+
readonly pluginName = 'AppApiPlugin';
|
|
12
|
+
|
|
13
|
+
isAppApiErrorInterface(value: unknown): value is AppApiErrorInterface {
|
|
14
|
+
return (
|
|
15
|
+
typeof value === 'object' &&
|
|
16
|
+
value !== null &&
|
|
17
|
+
'success' in value &&
|
|
18
|
+
value.success === false &&
|
|
19
|
+
'id' in value &&
|
|
20
|
+
typeof value.id === 'string'
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
onSuccess(context: ExecutorContext<unknown>): void | Promise<void> {
|
|
25
|
+
const response = context.returnValue;
|
|
26
|
+
|
|
27
|
+
if (this.isAppApiErrorInterface(response)) {
|
|
28
|
+
throw new Error(response.message || response.id);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async onError(
|
|
33
|
+
context: ExecutorContext<AppApiConfig>
|
|
34
|
+
): Promise<ExecutorError | void> {
|
|
35
|
+
const { error, parameters } = context;
|
|
36
|
+
|
|
37
|
+
if (error instanceof RequestError && parameters.responseType === 'json') {
|
|
38
|
+
// @ts-expect-error response is not defined in Error
|
|
39
|
+
let response = error?.response;
|
|
40
|
+
|
|
41
|
+
if (response instanceof Response) {
|
|
42
|
+
// clone the response to avoid mutating the original response
|
|
43
|
+
response = response.clone();
|
|
44
|
+
|
|
45
|
+
const json = await this.getResponseJson(response);
|
|
46
|
+
|
|
47
|
+
if (this.isAppApiErrorInterface(json)) {
|
|
48
|
+
const newError = new ExecutorError(json.message || json.id);
|
|
49
|
+
// context.error = newError;
|
|
50
|
+
return newError;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
protected async getResponseJson(response: Response): Promise<unknown> {
|
|
57
|
+
try {
|
|
58
|
+
return await response.json();
|
|
59
|
+
} catch {
|
|
60
|
+
return {};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { inject, injectable } from 'inversify';
|
|
2
|
+
import type { AppApiResult } from '@/base/port/AppApiInterface';
|
|
3
|
+
import type { AppUserApiInterface } from '@/base/port/AppUserApiInterface';
|
|
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
|
+
>;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* UserApi
|
|
25
|
+
*
|
|
26
|
+
* @description
|
|
27
|
+
* UserApi is a client for the user API.
|
|
28
|
+
*
|
|
29
|
+
*/
|
|
30
|
+
@injectable()
|
|
31
|
+
export class AppUserApi implements AppUserApiInterface {
|
|
32
|
+
constructor(
|
|
33
|
+
@inject(AppApiRequester)
|
|
34
|
+
protected client: RequestTransaction<AppApiConfig>
|
|
35
|
+
) {}
|
|
36
|
+
|
|
37
|
+
async login(
|
|
38
|
+
params: UserApiLoginTransaction['data']
|
|
39
|
+
): Promise<AppApiResult<unknown>> {
|
|
40
|
+
const response = await this.client.request<UserApiLoginTransaction>({
|
|
41
|
+
url: '/user/login',
|
|
42
|
+
method: 'POST',
|
|
43
|
+
data: params,
|
|
44
|
+
encryptProps: 'password'
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return response.data;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async register(
|
|
51
|
+
params: UserApiRegisterTransaction['data']
|
|
52
|
+
): Promise<AppApiResult<unknown>> {
|
|
53
|
+
const response = await this.client.request<UserApiRegisterTransaction>({
|
|
54
|
+
url: '/user/register',
|
|
55
|
+
method: 'POST',
|
|
56
|
+
data: params,
|
|
57
|
+
encryptProps: 'password'
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return response.data;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async logout(): Promise<AppApiResult<unknown>> {
|
|
64
|
+
const response = await this.client.request({
|
|
65
|
+
url: '/user/logout',
|
|
66
|
+
method: 'POST'
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return response.data as AppApiResult<unknown>;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { RequestCommonPlugin } from '@qlover/corekit-bridge';
|
|
2
|
+
import { FetchURLPlugin } from '@qlover/fe-corekit';
|
|
3
|
+
import { DialogErrorPlugin } from '@/base/cases/DialogErrorPlugin';
|
|
4
|
+
import { RequestEncryptPlugin } from '@/base/cases/RequestEncryptPlugin';
|
|
5
|
+
import { StringEncryptor } from '@/base/cases/StringEncryptor';
|
|
6
|
+
import { AppApiPlugin } from './AppApiPlugin';
|
|
7
|
+
import { AppApiRequester } from './AppApiRequester';
|
|
8
|
+
import type { AppApiConfig } from './AppApiRequester';
|
|
9
|
+
import type {
|
|
10
|
+
BootstrapContext,
|
|
11
|
+
BootstrapExecutorPlugin
|
|
12
|
+
} from '@qlover/corekit-bridge';
|
|
13
|
+
import type { ExecutorContext, SerializerIneterface } from '@qlover/fe-corekit';
|
|
14
|
+
|
|
15
|
+
export class AppUserApiBootstrap implements BootstrapExecutorPlugin {
|
|
16
|
+
readonly pluginName = 'AppUserApiBootstrap';
|
|
17
|
+
|
|
18
|
+
constructor(protected serializer: SerializerIneterface) {}
|
|
19
|
+
|
|
20
|
+
onBefore({ parameters: { ioc } }: BootstrapContext): void | Promise<void> {
|
|
21
|
+
const appUserApi = ioc.get<AppApiRequester>(AppApiRequester);
|
|
22
|
+
|
|
23
|
+
appUserApi.usePlugin(new FetchURLPlugin());
|
|
24
|
+
appUserApi.usePlugin(new RequestEncryptPlugin(ioc.get(StringEncryptor)));
|
|
25
|
+
appUserApi.usePlugin(
|
|
26
|
+
new RequestCommonPlugin({
|
|
27
|
+
requestDataSerializer: this.requestDataSerializer.bind(this)
|
|
28
|
+
})
|
|
29
|
+
);
|
|
30
|
+
appUserApi.usePlugin(new AppApiPlugin());
|
|
31
|
+
appUserApi.usePlugin(ioc.get(DialogErrorPlugin));
|
|
32
|
+
console.log('jj AppUserApiBootstrap success');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
protected requestDataSerializer(
|
|
36
|
+
data: unknown,
|
|
37
|
+
context: ExecutorContext<AppApiConfig>
|
|
38
|
+
): unknown {
|
|
39
|
+
if (data instanceof FormData) {
|
|
40
|
+
return data;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (context.parameters?.responseType === 'json') {
|
|
44
|
+
return this.serializer.serialize(data);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return data;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { RequestCommonPlugin } from '@qlover/corekit-bridge';
|
|
2
|
+
import {
|
|
3
|
+
FetchAbortPlugin,
|
|
4
|
+
RequestTransaction,
|
|
5
|
+
RequestAdapterFetch,
|
|
6
|
+
FetchURLPlugin
|
|
7
|
+
} from '@qlover/fe-corekit';
|
|
8
|
+
import { inject, injectable } from 'inversify';
|
|
9
|
+
import type { MigrationApiInterface } from '@/base/port/MigrationApiInterface';
|
|
10
|
+
import type { RequestAdapterConfig } from '@qlover/fe-corekit';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* UserApi
|
|
14
|
+
*
|
|
15
|
+
* @description
|
|
16
|
+
* UserApi is a client for the user API.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
@injectable()
|
|
20
|
+
export class MigrationsApi
|
|
21
|
+
extends RequestTransaction<RequestAdapterConfig>
|
|
22
|
+
implements MigrationApiInterface
|
|
23
|
+
{
|
|
24
|
+
constructor(
|
|
25
|
+
@inject(FetchAbortPlugin) protected abortPlugin: FetchAbortPlugin
|
|
26
|
+
) {
|
|
27
|
+
super(
|
|
28
|
+
new RequestAdapterFetch({
|
|
29
|
+
baseURL: '/api/admin/migrations',
|
|
30
|
+
responseType: 'json'
|
|
31
|
+
})
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
this.usePlugin(new FetchURLPlugin()).usePlugin(new RequestCommonPlugin());
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async init(): Promise<unknown> {
|
|
38
|
+
return this.request({
|
|
39
|
+
url: '/init',
|
|
40
|
+
method: 'POST'
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -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
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type ServiceIdentifier,
|
|
2
3
|
type BootstrapContextValue,
|
|
3
4
|
type BootstrapExecutorPlugin,
|
|
4
5
|
type IOCContainerInterface,
|
|
5
6
|
type IOCFunctionInterface,
|
|
6
7
|
type LoggerInterface
|
|
7
8
|
} from '@qlover/corekit-bridge';
|
|
8
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
AsyncExecutor,
|
|
11
|
+
type ExecutorError,
|
|
12
|
+
type PromiseTask,
|
|
13
|
+
type ExecutorPlugin
|
|
14
|
+
} from '@qlover/fe-corekit';
|
|
15
|
+
import type { ServerInterface } from '@/server/port/ServerInterface';
|
|
9
16
|
import { I, type IOCIdentifierMapServer } from '@config/IOCIdentifier';
|
|
10
|
-
import type { ServerInterface } from '@/base/port/ServerInterface';
|
|
11
17
|
import { ServerIOC } from '../serverIoc/ServerIOC';
|
|
12
18
|
|
|
13
|
-
export interface BootstrapServerResult {
|
|
14
|
-
locale: string;
|
|
15
|
-
messages: Record<string, string>;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
19
|
export interface BootstrapServerContextValue extends BootstrapContextValue {
|
|
19
|
-
|
|
20
|
-
messages: Record<string, string>;
|
|
20
|
+
IOC: IOCFunctionInterface<IOCIdentifierMapServer, IOCContainerInterface>;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export class BootstrapServer implements ServerInterface {
|
|
@@ -43,11 +43,12 @@ export class BootstrapServer implements ServerInterface {
|
|
|
43
43
|
getIOC<T extends keyof IOCIdentifierMapServer>(
|
|
44
44
|
identifier: T
|
|
45
45
|
): IOCIdentifierMapServer[T];
|
|
46
|
-
getIOC(
|
|
47
|
-
|
|
46
|
+
getIOC<T>(serviceIdentifier: ServiceIdentifier<T>): T;
|
|
47
|
+
getIOC<T extends keyof IOCIdentifierMapServer>(
|
|
48
|
+
identifier?: T
|
|
48
49
|
):
|
|
49
50
|
| IOCFunctionInterface<IOCIdentifierMapServer, IOCContainerInterface>
|
|
50
|
-
| IOCIdentifierMapServer[
|
|
51
|
+
| IOCIdentifierMapServer[T] {
|
|
51
52
|
if (identifier === undefined) {
|
|
52
53
|
return this.IOC;
|
|
53
54
|
}
|
|
@@ -75,4 +76,17 @@ export class BootstrapServer implements ServerInterface {
|
|
|
75
76
|
this.executor.use(plugin as ExecutorPlugin<unknown>);
|
|
76
77
|
return this;
|
|
77
78
|
}
|
|
79
|
+
|
|
80
|
+
execNoError<Result>(
|
|
81
|
+
task?: PromiseTask<Result, BootstrapServerContextValue>
|
|
82
|
+
): Promise<Result | ExecutorError> {
|
|
83
|
+
const context = {
|
|
84
|
+
logger: this.logger,
|
|
85
|
+
root: this.root,
|
|
86
|
+
ioc: this.IOC.implemention!,
|
|
87
|
+
IOC: this.IOC
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return this.executor.execNoError(context, task);
|
|
91
|
+
}
|
|
78
92
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AppUserApiBootstrap } from '@/base/services/appApi/AppUserApiBootstrap';
|
|
2
|
+
import { I, IOCIdentifier } from '@config/IOCIdentifier';
|
|
3
|
+
import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
2
4
|
import { IocIdentifierTest } from './IocIdentifierTest';
|
|
3
5
|
import { printBootstrap } from './PrintBootstrap';
|
|
4
6
|
import type { BootstrapAppArgs } from './BootstrapClient';
|
|
5
|
-
import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
6
7
|
import type {
|
|
7
8
|
BootstrapExecutorPlugin,
|
|
8
9
|
EnvConfigInterface,
|
|
@@ -28,8 +29,8 @@ export class BootstrapsRegistry {
|
|
|
28
29
|
i18nService.setPathname(this.args.pathname);
|
|
29
30
|
|
|
30
31
|
const bootstrapList: BootstrapExecutorPlugin[] = [
|
|
31
|
-
i18nService
|
|
32
|
-
|
|
32
|
+
i18nService,
|
|
33
|
+
new AppUserApiBootstrap(IOC(I.JSONSerializer))
|
|
33
34
|
// new FeApiBootstarp(),
|
|
34
35
|
// AiApiBootstarp,
|
|
35
36
|
// IOC(IOCIdentifier.I18nKeyErrorPlugin)
|
|
@@ -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>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
import type { Encryptor } from '@qlover/fe-corekit';
|
|
3
|
+
|
|
4
|
+
export class PasswordEncrypt implements Encryptor<string, string> {
|
|
5
|
+
encrypt(password: string): string {
|
|
6
|
+
return crypto.createHash('md5').update(password).digest('hex');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
decrypt(): string {
|
|
10
|
+
throw new Error('Md5Encrypt is not decryptable');
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ExecutorError } from '@qlover/fe-corekit';
|
|
2
|
+
import { inject, injectable } from 'inversify';
|
|
3
|
+
import { cookies } from 'next/headers';
|
|
4
|
+
import type { AppConfig } from '@/base/cases/AppConfig';
|
|
5
|
+
import { API_NOT_AUTHORIZED } from '@config/Identifier';
|
|
6
|
+
import { I } from '@config/IOCIdentifier';
|
|
7
|
+
import { UserCredentialToken } from './UserCredentialToken';
|
|
8
|
+
import type { ServerAuthInterface } from './port/ServerAuthInterface';
|
|
9
|
+
|
|
10
|
+
@injectable()
|
|
11
|
+
export class ServerAuth implements ServerAuthInterface {
|
|
12
|
+
protected userTokenKey: string;
|
|
13
|
+
constructor(
|
|
14
|
+
@inject(I.AppConfig) protected server: AppConfig,
|
|
15
|
+
@inject(UserCredentialToken)
|
|
16
|
+
protected userCredentialToken: UserCredentialToken
|
|
17
|
+
) {
|
|
18
|
+
this.userTokenKey = server.userTokenKey;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async setAuth(credential_token: string): Promise<void> {
|
|
22
|
+
const cookieStore = await cookies();
|
|
23
|
+
|
|
24
|
+
cookieStore.set(this.userTokenKey, credential_token);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async hasAuth(): Promise<boolean> {
|
|
28
|
+
const token = await this.getAuth();
|
|
29
|
+
|
|
30
|
+
if (!token) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
const user = await this.userCredentialToken.parseToken(token);
|
|
36
|
+
|
|
37
|
+
return !!user;
|
|
38
|
+
} catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async getAuth(): Promise<string> {
|
|
44
|
+
const cookieStore = await cookies();
|
|
45
|
+
return cookieStore.get(this.userTokenKey)?.value || '';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async clear(): Promise<void> {
|
|
49
|
+
const cookieStore = await cookies();
|
|
50
|
+
cookieStore.delete(this.userTokenKey);
|
|
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
|
+
}
|
|
60
|
+
}
|