@qlover/create-app 0.7.7 → 0.7.8
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 +91 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/templates/next-app/build/generateLocales.ts +1 -1
- package/dist/templates/next-app/config/IOCIdentifier.ts +15 -2
- package/dist/templates/next-app/config/Identifier/common.error.ts +7 -0
- package/dist/templates/next-app/package.json +1 -1
- package/dist/templates/next-app/public/locales/{en/common.json → en.json} +2 -1
- package/dist/templates/next-app/public/locales/{zh/common.json → zh.json} +2 -1
- package/dist/templates/next-app/src/app/[locale]/layout.tsx +8 -20
- package/dist/templates/next-app/src/app/[locale]/login/LoginForm.tsx +6 -7
- package/dist/templates/next-app/src/app/[locale]/login/page.tsx +24 -11
- package/dist/templates/next-app/src/app/[locale]/page.tsx +14 -1
- package/dist/templates/next-app/src/base/cases/DialogHandler.ts +92 -0
- package/dist/templates/next-app/src/base/cases/NavigateBridge.ts +16 -0
- package/dist/templates/next-app/src/base/cases/PageParams.ts +74 -0
- package/dist/templates/next-app/src/base/cases/RouterService.ts +35 -0
- package/dist/templates/next-app/src/base/cases/ServerAuth.ts +17 -0
- package/dist/templates/next-app/src/base/cases/ServerErrorHandler.ts +27 -0
- package/dist/templates/next-app/src/base/port/IOCInterface.ts +24 -0
- package/dist/templates/next-app/src/base/port/ParamsHandlerInterface.ts +11 -0
- package/dist/templates/next-app/src/base/port/RouterInterface.ts +11 -0
- package/dist/templates/next-app/src/base/port/ServerAuthInterface.ts +3 -0
- package/dist/templates/next-app/src/base/port/ServerInterface.ts +12 -0
- package/dist/templates/next-app/src/base/types/PageProps.ts +9 -0
- package/dist/templates/next-app/src/core/bootstraps/BootstrapClient.ts +2 -39
- package/dist/templates/next-app/src/core/bootstraps/BootstrapServer.ts +78 -0
- package/dist/templates/next-app/src/core/clientIoc/ClientIOC.ts +37 -0
- package/dist/templates/next-app/src/core/{IocRegisterImpl.ts → clientIoc/ClientIOCRegister.ts} +20 -23
- package/dist/templates/next-app/src/core/globals.ts +3 -0
- package/dist/templates/next-app/src/core/serverIoc/ServerIOC.ts +52 -0
- package/dist/templates/next-app/src/core/serverIoc/ServerIOCRegister.ts +63 -0
- package/dist/templates/next-app/src/i18n/request.ts +1 -2
- package/dist/templates/next-app/src/i18n/routing.ts +3 -3
- package/dist/templates/next-app/src/middleware.ts +6 -3
- package/dist/templates/next-app/src/uikit/components/BaseHeader.tsx +9 -4
- package/dist/templates/next-app/src/uikit/components/BootstrapsProvider.tsx +13 -1
- package/dist/templates/next-app/src/uikit/components/ComboProvider.tsx +5 -0
- package/dist/templates/next-app/src/uikit/components/LogoutButton.tsx +34 -0
- package/dist/templates/next-app/src/uikit/components/ThemeSwitcher.tsx +16 -3
- package/dist/templates/next-app/src/uikit/context/IOCContext.ts +9 -2
- package/package.json +1 -1
- package/dist/templates/next-app/plugins/eslint-plugin-testid.mjs +0 -94
- package/dist/templates/next-app/plugins/generateLocalesPlugin.ts +0 -33
- package/dist/templates/next-app/src/core/IOC.ts +0 -58
- package/dist/templates/next-app/src/server/getServerI18n.ts +0 -26
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { inject, injectable } from 'inversify';
|
|
2
|
+
import { NavigateBridge } from './NavigateBridge';
|
|
3
|
+
import type { RouterInterface, RouterPathname } from '../port/RouterInterface';
|
|
4
|
+
import type { UIBridgeInterface } from '@qlover/corekit-bridge';
|
|
5
|
+
import type { AppRouterInstance } from 'next/dist/shared/lib/app-router-context.shared-runtime';
|
|
6
|
+
|
|
7
|
+
@injectable()
|
|
8
|
+
export class RouterService implements RouterInterface {
|
|
9
|
+
protected locale: string = '';
|
|
10
|
+
|
|
11
|
+
constructor(
|
|
12
|
+
@inject(NavigateBridge)
|
|
13
|
+
protected uiBridge: UIBridgeInterface<AppRouterInstance>
|
|
14
|
+
) {}
|
|
15
|
+
|
|
16
|
+
protected padLocaleHref(href: RouterPathname): string {
|
|
17
|
+
return `/${this.locale}${href === '/' ? '' : href}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
goto(href: RouterPathname): void {
|
|
21
|
+
this.uiBridge.getUIBridge()?.push(this.padLocaleHref(href));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
gotoHome(): void {
|
|
25
|
+
this.goto('/');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
setLocale(locale: string): void {
|
|
29
|
+
this.locale = locale;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getLocale(): string {
|
|
33
|
+
return this.locale;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { cookies } from 'next/headers';
|
|
2
|
+
import { I } from '@config/IOCIdentifier';
|
|
3
|
+
import type { ServerAuthInterface } from '../port/ServerAuthInterface';
|
|
4
|
+
import type { ServerInterface } from '../port/ServerInterface';
|
|
5
|
+
|
|
6
|
+
export class ServerAuth implements ServerAuthInterface {
|
|
7
|
+
constructor(protected server: ServerInterface) {}
|
|
8
|
+
|
|
9
|
+
async hasAuth(): Promise<boolean> {
|
|
10
|
+
const cookieStore = await cookies();
|
|
11
|
+
const appConfig = this.server.getIOC(I.AppConfig);
|
|
12
|
+
|
|
13
|
+
const token = cookieStore.get(appConfig.userTokenKey);
|
|
14
|
+
|
|
15
|
+
return !!token;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ExecutorError, type ExecutorContext } from '@qlover/fe-corekit';
|
|
2
|
+
import { SERVER_AUTH_ERROR } from '@config/Identifier';
|
|
3
|
+
import type { BootstrapServerContextValue } from '@/core/bootstraps/BootstrapServer';
|
|
4
|
+
import type { BootstrapExecutorPlugin } from '@qlover/corekit-bridge';
|
|
5
|
+
|
|
6
|
+
export class ServerErrorHandler implements BootstrapExecutorPlugin {
|
|
7
|
+
pluginName = 'ServerErrorHandler';
|
|
8
|
+
|
|
9
|
+
onError(
|
|
10
|
+
context: ExecutorContext<BootstrapServerContextValue>
|
|
11
|
+
): ExecutorError | void {
|
|
12
|
+
const { parameters, error } = context;
|
|
13
|
+
const { messages } = parameters;
|
|
14
|
+
|
|
15
|
+
if (error instanceof Error) {
|
|
16
|
+
const messageId = error.message;
|
|
17
|
+
|
|
18
|
+
if (messageId === SERVER_AUTH_ERROR) {
|
|
19
|
+
const message = messages[messageId];
|
|
20
|
+
|
|
21
|
+
if (message) {
|
|
22
|
+
return new ExecutorError(messageId, message);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
EnvConfigInterface,
|
|
3
|
+
IOCContainerInterface,
|
|
4
|
+
IOCFunctionInterface
|
|
5
|
+
} from '@qlover/corekit-bridge';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* IOC register options
|
|
9
|
+
*/
|
|
10
|
+
export type IocRegisterOptions = {
|
|
11
|
+
/**
|
|
12
|
+
* The app config
|
|
13
|
+
*/
|
|
14
|
+
appConfig: EnvConfigInterface;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export interface IOCInterface<
|
|
18
|
+
IdentifierMap,
|
|
19
|
+
IOCContainer extends IOCContainerInterface
|
|
20
|
+
> {
|
|
21
|
+
create(
|
|
22
|
+
options: IocRegisterOptions
|
|
23
|
+
): IOCFunctionInterface<IdentifierMap, IOCContainer>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PageI18nInterface } from '@config/i18n';
|
|
2
|
+
|
|
3
|
+
export interface ParamsHandlerInterface {
|
|
4
|
+
getLocale(defaultLocale?: string): string;
|
|
5
|
+
getI18nWithNotFound(): string;
|
|
6
|
+
getI18nMessages(): Promise<Record<string, string>>;
|
|
7
|
+
getI18nInterface<T extends PageI18nInterface>(
|
|
8
|
+
i18nInterface: T,
|
|
9
|
+
namespace?: string
|
|
10
|
+
): Promise<T>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { redirect } from '@/i18n/routing';
|
|
2
|
+
export type RouterPathname = Parameters<typeof redirect>[0]['href'];
|
|
3
|
+
|
|
4
|
+
export interface RouterInterface {
|
|
5
|
+
gotoHome(): void;
|
|
6
|
+
goto(href: RouterPathname): void;
|
|
7
|
+
|
|
8
|
+
getLocale(): string;
|
|
9
|
+
|
|
10
|
+
setLocale(locale: string): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type IOCContainerInterface,
|
|
3
|
+
type IOCFunctionInterface
|
|
4
|
+
} from '@qlover/corekit-bridge';
|
|
5
|
+
import { type IOCIdentifierMapServer } from '@config/IOCIdentifier';
|
|
6
|
+
|
|
7
|
+
export interface ServerInterface {
|
|
8
|
+
getIOC(): IOCFunctionInterface<IOCIdentifierMapServer, IOCContainerInterface>;
|
|
9
|
+
getIOC<T extends keyof IOCIdentifierMapServer>(
|
|
10
|
+
identifier: T
|
|
11
|
+
): IOCIdentifierMapServer[T];
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PageWithParams } from '@/base/cases/PageParams';
|
|
2
|
+
|
|
3
|
+
export interface PageParamsProps extends PageWithParams {
|
|
4
|
+
searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface PageLayoutProps extends PageWithParams {
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
}
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import { Bootstrap
|
|
1
|
+
import { Bootstrap } from '@qlover/corekit-bridge';
|
|
2
2
|
import { isObject } from 'lodash';
|
|
3
3
|
import { browserGlobalsName } from '@config/common';
|
|
4
|
-
import { InversifyContainer } from '@/base/cases/InversifyContainer';
|
|
5
4
|
import { BootstrapsRegistry } from './BootstrapsRegistry';
|
|
6
5
|
import * as globals from '../globals';
|
|
7
|
-
import { appConfig } from '../globals';
|
|
8
|
-
import { IocRegisterImpl } from '../IocRegisterImpl';
|
|
9
|
-
import type { IOCContainer } from '../IOC';
|
|
10
6
|
import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
11
7
|
import type {
|
|
12
|
-
EnvConfigInterface,
|
|
13
8
|
IOCContainerInterface,
|
|
14
|
-
IOCFunctionInterface
|
|
15
|
-
IOCManagerInterface
|
|
9
|
+
IOCFunctionInterface
|
|
16
10
|
} from '@qlover/corekit-bridge';
|
|
17
11
|
|
|
18
12
|
export type BootstrapAppArgs = {
|
|
@@ -31,37 +25,6 @@ export type BootstrapAppArgs = {
|
|
|
31
25
|
};
|
|
32
26
|
|
|
33
27
|
export class BootstrapClient {
|
|
34
|
-
private static _ioc: IOCFunctionInterface<
|
|
35
|
-
IOCIdentifierMap,
|
|
36
|
-
IOCContainerInterface
|
|
37
|
-
> | null = null;
|
|
38
|
-
|
|
39
|
-
static createSingletonIOC(): IOCFunctionInterface<
|
|
40
|
-
IOCIdentifierMap,
|
|
41
|
-
IOCContainerInterface
|
|
42
|
-
> {
|
|
43
|
-
if (BootstrapClient._ioc) {
|
|
44
|
-
return BootstrapClient._ioc;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
BootstrapClient._ioc = createIOCFunction<IOCIdentifierMap>(
|
|
48
|
-
/**
|
|
49
|
-
* If not inversify, you can use any IOC container,
|
|
50
|
-
* then replace the InversifyContainer with your own IOC container
|
|
51
|
-
*/
|
|
52
|
-
new InversifyContainer()
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
new IocRegisterImpl({
|
|
56
|
-
appConfig: appConfig as EnvConfigInterface
|
|
57
|
-
}).register(
|
|
58
|
-
BootstrapClient._ioc.implemention as IOCContainer,
|
|
59
|
-
BootstrapClient._ioc as IOCManagerInterface<IOCContainer>
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
return BootstrapClient._ioc;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
28
|
static async main(args: BootstrapAppArgs): Promise<BootstrapAppArgs> {
|
|
66
29
|
const { root, IOC } = args;
|
|
67
30
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type BootstrapContextValue,
|
|
3
|
+
type BootstrapExecutorPlugin,
|
|
4
|
+
type IOCContainerInterface,
|
|
5
|
+
type IOCFunctionInterface,
|
|
6
|
+
type LoggerInterface
|
|
7
|
+
} from '@qlover/corekit-bridge';
|
|
8
|
+
import { AsyncExecutor, type ExecutorPlugin } from '@qlover/fe-corekit';
|
|
9
|
+
import { I, type IOCIdentifierMapServer } from '@config/IOCIdentifier';
|
|
10
|
+
import type { ServerInterface } from '@/base/port/ServerInterface';
|
|
11
|
+
import { ServerIOC } from '../serverIoc/ServerIOC';
|
|
12
|
+
|
|
13
|
+
export interface BootstrapServerResult {
|
|
14
|
+
locale: string;
|
|
15
|
+
messages: Record<string, string>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface BootstrapServerContextValue extends BootstrapContextValue {
|
|
19
|
+
locale: string;
|
|
20
|
+
messages: Record<string, string>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class BootstrapServer implements ServerInterface {
|
|
24
|
+
protected executor: AsyncExecutor;
|
|
25
|
+
protected root: Record<string, unknown> = {};
|
|
26
|
+
protected IOC: IOCFunctionInterface<
|
|
27
|
+
IOCIdentifierMapServer,
|
|
28
|
+
IOCContainerInterface
|
|
29
|
+
>;
|
|
30
|
+
readonly logger: LoggerInterface;
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
const serverIOC = ServerIOC.create();
|
|
34
|
+
const ioc = serverIOC.create();
|
|
35
|
+
const logger = ioc(I.Logger);
|
|
36
|
+
|
|
37
|
+
this.executor = new AsyncExecutor();
|
|
38
|
+
this.IOC = ioc;
|
|
39
|
+
this.logger = logger;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getIOC(): IOCFunctionInterface<IOCIdentifierMapServer, IOCContainerInterface>;
|
|
43
|
+
getIOC<T extends keyof IOCIdentifierMapServer>(
|
|
44
|
+
identifier: T
|
|
45
|
+
): IOCIdentifierMapServer[T];
|
|
46
|
+
getIOC(
|
|
47
|
+
identifier?: keyof IOCIdentifierMapServer
|
|
48
|
+
):
|
|
49
|
+
| IOCFunctionInterface<IOCIdentifierMapServer, IOCContainerInterface>
|
|
50
|
+
| IOCIdentifierMapServer[keyof IOCIdentifierMapServer] {
|
|
51
|
+
if (identifier === undefined) {
|
|
52
|
+
return this.IOC;
|
|
53
|
+
}
|
|
54
|
+
return this.IOC(identifier);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @override
|
|
59
|
+
*/
|
|
60
|
+
use(
|
|
61
|
+
plugin:
|
|
62
|
+
| BootstrapExecutorPlugin
|
|
63
|
+
| BootstrapExecutorPlugin[]
|
|
64
|
+
| ((
|
|
65
|
+
ioc: IOCFunctionInterface<
|
|
66
|
+
IOCIdentifierMapServer,
|
|
67
|
+
IOCContainerInterface
|
|
68
|
+
>
|
|
69
|
+
) => BootstrapExecutorPlugin)
|
|
70
|
+
): this {
|
|
71
|
+
if (typeof plugin === 'function') {
|
|
72
|
+
plugin = plugin(this.IOC);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
this.executor.use(plugin as ExecutorPlugin<unknown>);
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createIOCFunction,
|
|
3
|
+
type IOCContainerInterface,
|
|
4
|
+
type IOCFunctionInterface
|
|
5
|
+
} from '@qlover/corekit-bridge';
|
|
6
|
+
import { InversifyContainer } from '@/base/cases/InversifyContainer';
|
|
7
|
+
import type { IOCInterface } from '@/base/port/IOCInterface';
|
|
8
|
+
import { ClientIOCRegister } from './ClientIOCRegister';
|
|
9
|
+
import { appConfig } from '../globals';
|
|
10
|
+
import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
11
|
+
|
|
12
|
+
export class ClientIOC
|
|
13
|
+
implements IOCInterface<IOCIdentifierMap, IOCContainerInterface>
|
|
14
|
+
{
|
|
15
|
+
protected ioc: IOCFunctionInterface<
|
|
16
|
+
IOCIdentifierMap,
|
|
17
|
+
IOCContainerInterface
|
|
18
|
+
> | null = null;
|
|
19
|
+
|
|
20
|
+
create(): IOCFunctionInterface<IOCIdentifierMap, IOCContainerInterface> {
|
|
21
|
+
if (this.ioc) {
|
|
22
|
+
return this.ioc;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
this.ioc = createIOCFunction<IOCIdentifierMap>(new InversifyContainer());
|
|
26
|
+
|
|
27
|
+
const register = new ClientIOCRegister({
|
|
28
|
+
appConfig: appConfig
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
register.register(this.ioc.implemention!, this.ioc);
|
|
32
|
+
|
|
33
|
+
return this.ioc;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const clientIOC = new ClientIOC();
|
package/dist/templates/next-app/src/core/{IocRegisterImpl.ts → clientIoc/ClientIOCRegister.ts}
RENAMED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { IOCIdentifier as I } from '@config/IOCIdentifier';
|
|
2
|
+
import { RouterService } from '@/base/cases/RouterService';
|
|
3
|
+
import type { IocRegisterOptions } from '@/base/port/IOCInterface';
|
|
2
4
|
import { I18nService } from '@/base/services/I18nService';
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import type {
|
|
5
|
+
import { UserService } from '@/base/services/UserService';
|
|
6
|
+
import { dialogHandler, logger, JSON } from '../globals';
|
|
7
|
+
import type {
|
|
8
|
+
IOCContainerInterface,
|
|
9
|
+
IOCManagerInterface,
|
|
10
|
+
IOCRegisterInterface
|
|
11
|
+
} from '@qlover/corekit-bridge';
|
|
6
12
|
|
|
7
|
-
export class
|
|
13
|
+
export class ClientIOCRegister
|
|
14
|
+
implements IOCRegisterInterface<IOCContainerInterface, IocRegisterOptions>
|
|
15
|
+
{
|
|
8
16
|
constructor(protected options: IocRegisterOptions) {}
|
|
9
17
|
|
|
10
18
|
/**
|
|
@@ -14,13 +22,13 @@ export class IocRegisterImpl implements IOCRegister {
|
|
|
14
22
|
*
|
|
15
23
|
* @param ioc - IOC container
|
|
16
24
|
*/
|
|
17
|
-
protected registerGlobals(ioc:
|
|
25
|
+
protected registerGlobals(ioc: IOCContainerInterface): void {
|
|
18
26
|
const { appConfig } = this.options;
|
|
19
27
|
ioc.bind(I.JSONSerializer, JSON);
|
|
20
28
|
ioc.bind(I.Logger, logger);
|
|
21
29
|
ioc.bind(I.AppConfig, appConfig);
|
|
22
30
|
// ioc.bind(I.EnvConfigInterface, appConfig);
|
|
23
|
-
|
|
31
|
+
ioc.bind(I.DialogHandler, dialogHandler);
|
|
24
32
|
// ioc.bind(I.UIDialogInterface, dialogHandler);
|
|
25
33
|
// ioc.bind(I.AntdStaticApiInterface, dialogHandler);
|
|
26
34
|
// ioc.bind(I.LocalStorage, globals.localStorage);
|
|
@@ -38,20 +46,9 @@ export class IocRegisterImpl implements IOCRegister {
|
|
|
38
46
|
*
|
|
39
47
|
* @param ioc
|
|
40
48
|
*/
|
|
41
|
-
protected registerImplement(ioc:
|
|
49
|
+
protected registerImplement(ioc: IOCContainerInterface): void {
|
|
42
50
|
ioc.bind(I.I18nServiceInterface, new I18nService());
|
|
43
|
-
|
|
44
|
-
// I.RouteServiceInterface,
|
|
45
|
-
// new RouteService(
|
|
46
|
-
// ioc.get(NavigateBridge),
|
|
47
|
-
// ioc.get(I.I18nServiceInterface),
|
|
48
|
-
// {
|
|
49
|
-
// routes: useLocaleRoutes ? baseRoutes : baseNoLocaleRoutes,
|
|
50
|
-
// logger: ioc.get(I.Logger),
|
|
51
|
-
// hasLocalRoutes: useLocaleRoutes
|
|
52
|
-
// }
|
|
53
|
-
// )
|
|
54
|
-
// );
|
|
51
|
+
ioc.bind(I.RouterServiceInterface, ioc.get(RouterService));
|
|
55
52
|
// ioc.bind(
|
|
56
53
|
// I.ThemeService,
|
|
57
54
|
// new ThemeService({
|
|
@@ -61,14 +58,14 @@ export class IocRegisterImpl implements IOCRegister {
|
|
|
61
58
|
// );
|
|
62
59
|
// ioc.bind(I.I18nKeyErrorPlugin, ioc.get(I18nKeyErrorPlugin));
|
|
63
60
|
// ioc.bind(I.ProcesserExecutorInterface, ioc.get(ProcesserExecutor));
|
|
64
|
-
|
|
61
|
+
ioc.bind(I.UserServiceInterface, ioc.get(UserService));
|
|
65
62
|
// ioc.bind(I.RequestCatcherInterface, ioc.get(RequestStatusCatcher));
|
|
66
63
|
// ioc.bind(I.ExecutorPageBridgeInterface, ioc.get(ExecutorPageBridge));
|
|
67
64
|
// ioc.bind(I.JSONStoragePageInterface, ioc.get(JSONStoragePageBridge));
|
|
68
65
|
// ioc.bind(I.RequestPageBridgeInterface, ioc.get(RequestPageBridge));
|
|
69
66
|
}
|
|
70
67
|
|
|
71
|
-
protected registerCommon(_ioc:
|
|
68
|
+
protected registerCommon(_ioc: IOCContainerInterface): void {
|
|
72
69
|
// const { appConfig } = this.options;
|
|
73
70
|
// const logger = ioc.get(I.Logger);
|
|
74
71
|
// const feApiRequestCommonPlugin = new RequestCommonPlugin({
|
|
@@ -90,8 +87,8 @@ export class IocRegisterImpl implements IOCRegister {
|
|
|
90
87
|
* @override
|
|
91
88
|
*/
|
|
92
89
|
register(
|
|
93
|
-
ioc:
|
|
94
|
-
_manager: IOCManagerInterface<
|
|
90
|
+
ioc: IOCContainerInterface,
|
|
91
|
+
_manager: IOCManagerInterface<IOCContainerInterface>
|
|
95
92
|
): void {
|
|
96
93
|
this.registerGlobals(ioc);
|
|
97
94
|
this.registerCommon(ioc);
|
|
@@ -3,9 +3,12 @@ import { ColorFormatter, ConsoleHandler, Logger } from '@qlover/corekit-bridge';
|
|
|
3
3
|
import { JSONSerializer } from '@qlover/fe-corekit';
|
|
4
4
|
import { loggerStyles } from '@config/common';
|
|
5
5
|
import { AppConfig } from '@/base/cases/AppConfig';
|
|
6
|
+
import { DialogHandler } from '@/base/cases/DialogHandler';
|
|
6
7
|
|
|
7
8
|
export const appConfig = new AppConfig();
|
|
8
9
|
|
|
10
|
+
export const dialogHandler = new DialogHandler();
|
|
11
|
+
|
|
9
12
|
/**
|
|
10
13
|
* Global logger
|
|
11
14
|
*/
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createIOCFunction,
|
|
3
|
+
type IOCContainerInterface,
|
|
4
|
+
type IOCFunctionInterface
|
|
5
|
+
} from '@qlover/corekit-bridge';
|
|
6
|
+
import { AppConfig } from '@/base/cases/AppConfig';
|
|
7
|
+
import { InversifyContainer } from '@/base/cases/InversifyContainer';
|
|
8
|
+
import type { IOCInterface } from '@/base/port/IOCInterface';
|
|
9
|
+
import { ServerIOCRegister } from './ServerIOCRegister';
|
|
10
|
+
import type { IOCIdentifierMapServer } from '@config/IOCIdentifier';
|
|
11
|
+
|
|
12
|
+
export class ServerIOC
|
|
13
|
+
implements IOCInterface<IOCIdentifierMapServer, IOCContainerInterface>
|
|
14
|
+
{
|
|
15
|
+
static instance: ServerIOC | null = null;
|
|
16
|
+
|
|
17
|
+
protected ioc: IOCFunctionInterface<
|
|
18
|
+
IOCIdentifierMapServer,
|
|
19
|
+
IOCContainerInterface
|
|
20
|
+
> | null = null;
|
|
21
|
+
|
|
22
|
+
static create(): ServerIOC {
|
|
23
|
+
if (this.instance) {
|
|
24
|
+
return this.instance;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
this.instance = new ServerIOC();
|
|
28
|
+
|
|
29
|
+
return this.instance;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
create(): IOCFunctionInterface<
|
|
33
|
+
IOCIdentifierMapServer,
|
|
34
|
+
IOCContainerInterface
|
|
35
|
+
> {
|
|
36
|
+
if (this.ioc) {
|
|
37
|
+
return this.ioc;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.ioc = createIOCFunction<IOCIdentifierMapServer>(
|
|
41
|
+
new InversifyContainer()
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const register = new ServerIOCRegister({
|
|
45
|
+
appConfig: new AppConfig()
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
register.register(this.ioc.implemention!, this.ioc);
|
|
49
|
+
|
|
50
|
+
return this.ioc;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ConsoleHandler,
|
|
3
|
+
Logger,
|
|
4
|
+
TimestampFormatter,
|
|
5
|
+
type IOCContainerInterface,
|
|
6
|
+
type IOCManagerInterface,
|
|
7
|
+
type IOCRegisterInterface
|
|
8
|
+
} from '@qlover/corekit-bridge';
|
|
9
|
+
import { IOCIdentifier as I } from '@config/IOCIdentifier';
|
|
10
|
+
import type { IocRegisterOptions } from '@/base/port/IOCInterface';
|
|
11
|
+
|
|
12
|
+
export class ServerIOCRegister
|
|
13
|
+
implements IOCRegisterInterface<IOCContainerInterface, IocRegisterOptions>
|
|
14
|
+
{
|
|
15
|
+
constructor(protected options: IocRegisterOptions) {}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Register globals
|
|
19
|
+
*
|
|
20
|
+
* 一般用于注册全局
|
|
21
|
+
*
|
|
22
|
+
* @param ioc - IOC container
|
|
23
|
+
*/
|
|
24
|
+
protected registerGlobals(ioc: IOCContainerInterface): void {
|
|
25
|
+
const { appConfig } = this.options;
|
|
26
|
+
ioc.bind(I.AppConfig, appConfig);
|
|
27
|
+
ioc.bind(
|
|
28
|
+
I.Logger,
|
|
29
|
+
new Logger({
|
|
30
|
+
handlers: new ConsoleHandler(
|
|
31
|
+
new TimestampFormatter({
|
|
32
|
+
localeOptions: {
|
|
33
|
+
year: '2-digit',
|
|
34
|
+
month: '2-digit',
|
|
35
|
+
day: '2-digit',
|
|
36
|
+
hour: '2-digit',
|
|
37
|
+
minute: '2-digit',
|
|
38
|
+
second: '2-digit'
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
),
|
|
42
|
+
silent: false,
|
|
43
|
+
level: appConfig.env === 'development' ? 'debug' : 'info'
|
|
44
|
+
})
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
protected registerImplement(_ioc: IOCContainerInterface): void {}
|
|
49
|
+
|
|
50
|
+
protected registerCommon(_ioc: IOCContainerInterface): void {}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @override
|
|
54
|
+
*/
|
|
55
|
+
register(
|
|
56
|
+
ioc: IOCContainerInterface,
|
|
57
|
+
_manager: IOCManagerInterface<IOCContainerInterface>
|
|
58
|
+
): void {
|
|
59
|
+
this.registerGlobals(ioc);
|
|
60
|
+
this.registerCommon(ioc);
|
|
61
|
+
this.registerImplement(ioc);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -16,7 +16,6 @@ export default getRequestConfig(async ({ requestLocale }) => {
|
|
|
16
16
|
// Dynamically import the translation messages for the selected locale
|
|
17
17
|
return {
|
|
18
18
|
locale,
|
|
19
|
-
messages: (await import(`../../public/locales/${locale}
|
|
20
|
-
.default
|
|
19
|
+
messages: (await import(`../../public/locales/${locale}.json`)).default
|
|
21
20
|
};
|
|
22
21
|
});
|
|
@@ -15,8 +15,11 @@ export const config = {
|
|
|
15
15
|
matcher: [
|
|
16
16
|
'/', // Match the root path explicitly
|
|
17
17
|
|
|
18
|
-
// Match all paths except for
|
|
19
|
-
//
|
|
20
|
-
|
|
18
|
+
// Match all paths except for:
|
|
19
|
+
// - API routes
|
|
20
|
+
// - Next.js internals (_next/*)
|
|
21
|
+
// - Static files (*.svg, *.png, *.jpg, *.jpeg, *.gif, *.ico)
|
|
22
|
+
// - Other static assets and special files
|
|
23
|
+
'/((?!api|_next|.*\\.(?:svg|png|jpg|jpeg|gif|ico)|favicon.ico|sitemap.xml|sitemap-0.xml).*)'
|
|
21
24
|
]
|
|
22
25
|
};
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import Link from 'next/link';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
5
|
+
import { useIOC } from '@/uikit/hook/useIOC';
|
|
6
6
|
import { LanguageSwitcher } from './LanguageSwitcher';
|
|
7
|
+
import { LogoutButton } from './LogoutButton';
|
|
7
8
|
import { ThemeSwitcher } from './ThemeSwitcher';
|
|
8
9
|
|
|
9
|
-
export function BaseHeader() {
|
|
10
|
+
export function BaseHeader(props: { showLogoutButton?: boolean }) {
|
|
11
|
+
const { showLogoutButton } = props;
|
|
12
|
+
const appConfig = useIOC(IOCIdentifier.AppConfig);
|
|
10
13
|
return (
|
|
11
14
|
<header
|
|
12
15
|
data-testid="base-header"
|
|
@@ -28,13 +31,15 @@ export function BaseHeader() {
|
|
|
28
31
|
data-testid="base-header-app-name"
|
|
29
32
|
className="ml-2 text-lg font-semibold text-text"
|
|
30
33
|
>
|
|
31
|
-
{
|
|
34
|
+
{appConfig.appName}
|
|
32
35
|
</span>
|
|
33
36
|
</Link>
|
|
34
37
|
</div>
|
|
35
38
|
<div className="flex items-center gap-4">
|
|
36
39
|
<LanguageSwitcher />
|
|
37
40
|
<ThemeSwitcher />
|
|
41
|
+
|
|
42
|
+
{showLogoutButton && <LogoutButton />}
|
|
38
43
|
</div>
|
|
39
44
|
</div>
|
|
40
45
|
</header>
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import '@ant-design/v5-patch-for-react-19';
|
|
3
|
+
import { useRouter } from 'next/navigation';
|
|
4
|
+
import { useLocale } from 'next-intl';
|
|
3
5
|
import { useEffect } from 'react';
|
|
6
|
+
import { I } from '@config/IOCIdentifier';
|
|
7
|
+
import { NavigateBridge } from '@/base/cases/NavigateBridge';
|
|
4
8
|
import { BootstrapClient } from '@/core/bootstraps/BootstrapClient';
|
|
9
|
+
import { clientIOC } from '@/core/clientIoc/ClientIOC';
|
|
5
10
|
import { IOCContext } from '../context/IOCContext';
|
|
6
11
|
|
|
7
12
|
export function BootstrapsProvider(props: { children: React.ReactNode }) {
|
|
8
|
-
const IOC =
|
|
13
|
+
const IOC = clientIOC.create();
|
|
14
|
+
const locale = useLocale();
|
|
15
|
+
const router = useRouter();
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
IOC(I.RouterServiceInterface).setLocale(locale);
|
|
19
|
+
IOC(NavigateBridge).setUIBridge(router);
|
|
20
|
+
}, [locale, router, IOC]);
|
|
9
21
|
|
|
10
22
|
useEffect(() => {
|
|
11
23
|
if (typeof window !== 'undefined') {
|