@qlover/create-app 0.1.3 → 0.1.5
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 +4 -0
- package/bin/create-app.js +44 -4
- package/{templates/pack-app → configs/_common}/.env.template +8 -1
- package/{templates/pack-app → configs/_common}/.github/workflows/general-check.yml +9 -9
- package/{templates/pack-app → configs/_common}/.github/workflows/release.yml.template +18 -18
- package/configs/_common/.prettierrc.js +7 -0
- package/configs/_common/.release-it.json.template +42 -0
- package/configs/_common/.vscode/extensions.json +9 -0
- package/configs/_common/.vscode/react.code-snippets +19 -0
- package/configs/_common/.vscode/settings.json +11 -0
- package/configs/_common/package.json +61 -0
- package/configs/node-lib/eslint.config.js +50 -0
- package/configs/react-app/eslint.config.js +66 -0
- package/dist/cjs/index.d.ts +52 -37
- package/dist/cjs/index.js +1 -1
- package/dist/es/index.d.ts +52 -37
- package/dist/es/index.js +1 -1
- package/package.json +5 -2
- package/templates/node-lib/.release-it.json +42 -0
- package/templates/node-lib/__tests__/readJson.test.ts +1 -0
- package/templates/node-lib/bin/test.js +30 -0
- package/templates/node-lib/package.json +23 -6
- package/templates/node-lib/rollup.config.js +15 -24
- package/templates/node-lib/src/readJson.ts +9 -3
- package/templates/node-lib/tsconfig.json +19 -1
- package/templates/pack-app/eslint.config.js +81 -61
- package/templates/pack-app/fe-config.json +1 -5
- package/templates/pack-app/package.json +19 -11
- package/templates/pack-app/tsconfig.json +1 -1
- package/templates/pack-app/vite.config.ts +14 -0
- package/templates/react-app/README.md +177 -40
- package/templates/react-app/config/i18n.ts +1 -1
- package/templates/react-app/lib/fe-react-controller/FeController.ts +7 -3
- package/templates/react-app/lib/fe-react-theme/ThemeController.ts +1 -1
- package/templates/react-app/package.json +53 -8
- package/templates/react-app/src/App.tsx +4 -5
- package/templates/react-app/src/{services → base/apis}/feApi/FeApiMockPlugin.ts +1 -1
- package/templates/react-app/src/base/cases/UserToken.ts +47 -0
- package/templates/react-app/src/base/port/IOCInterface.ts +53 -0
- package/templates/react-app/src/base/port/StorageTokenInterface.ts +5 -0
- package/templates/react-app/src/{types → base/port}/UIDependenciesInterface.ts +6 -0
- package/templates/react-app/src/{types → base/types}/global.d.ts +1 -1
- package/templates/react-app/src/components/ThemeSwitcher.tsx +3 -2
- package/templates/react-app/src/core/bootstrap.ts +21 -0
- package/templates/react-app/src/core/feIOC/FeIOC.ts +32 -0
- package/templates/react-app/src/core/feIOC/RegisterApi.ts +41 -0
- package/templates/react-app/src/core/feIOC/RegisterCommon.ts +20 -0
- package/templates/react-app/src/core/feIOC/RegisterControllers.ts +53 -0
- package/templates/react-app/src/core/index.ts +31 -0
- package/templates/react-app/src/main.tsx +8 -10
- package/templates/react-app/src/pages/404.tsx +2 -2
- package/templates/react-app/src/pages/500.tsx +1 -1
- package/templates/react-app/src/pages/auth/Layout.tsx +3 -2
- package/templates/react-app/src/pages/auth/Login.tsx +6 -4
- package/templates/react-app/src/pages/base/About.tsx +1 -1
- package/templates/react-app/src/pages/base/Executor.tsx +8 -4
- package/templates/react-app/src/pages/base/Home.tsx +1 -1
- package/templates/react-app/src/pages/base/JSONStorage.tsx +6 -4
- package/templates/react-app/src/pages/base/Layout.tsx +1 -1
- package/templates/react-app/src/pages/base/RedirectPathname.tsx +1 -1
- package/templates/react-app/src/pages/base/Request.tsx +8 -3
- package/templates/react-app/src/pages/index.tsx +7 -2
- package/templates/react-app/src/services/{pageProcesser/PageProcesser.ts → processer/ProcesserService.ts} +3 -3
- package/templates/react-app/src/{containers/context → uikit/contexts}/BaseRouteContext.ts +4 -4
- package/templates/react-app/src/{services → uikit}/controllers/ExecutorController.ts +5 -5
- package/templates/react-app/src/{services → uikit}/controllers/JSONStorageController.ts +2 -2
- package/templates/react-app/src/{services → uikit}/controllers/RequestController.ts +3 -3
- package/templates/react-app/src/{services → uikit}/controllers/RouterController.ts +2 -2
- package/templates/react-app/src/{services → uikit}/controllers/UserController.ts +25 -51
- package/templates/react-app/src/{containers/context → uikit/providers}/BaseRouteProvider.tsx +2 -2
- package/templates/react-app/src/{components → uikit/providers}/ProcessProvider.tsx +13 -7
- package/templates/react-app/tsconfig.json +27 -5
- package/templates/react-app/tsconfig.node.json +3 -15
- package/templates/react-app/vite.config.ts +17 -14
- package/templates/pack-app/.env +0 -5
- package/templates/pack-app/.gitignore.template +0 -50
- package/templates/pack-app/.prettierrc.js +0 -3
- package/templates/pack-app/CHANGELOG.md +0 -0
- package/templates/pack-app/jest.config.js +0 -31
- package/templates/react-app/eslint.config.js +0 -31
- package/templates/react-app/src/containers/index.ts +0 -71
- package/templates/react-app/src/services/pageProcesser/index.ts +0 -1
- package/templates/react-app/tsconfig.app.json +0 -29
- package/templates/react-vite-lib/.gitignore.template +0 -27
- package/templates/react-vite-lib/README.md +0 -50
- package/templates/react-vite-lib/__tests__/Sum.test.ts +0 -9
- package/templates/react-vite-lib/__tests__/Text.test.tsx +0 -11
- package/templates/react-vite-lib/eslint.config.js +0 -28
- package/templates/react-vite-lib/index.html +0 -13
- package/templates/react-vite-lib/package.json +0 -30
- package/templates/react-vite-lib/public/vite.svg +0 -1
- package/templates/react-vite-lib/src/calc.ts +0 -3
- package/templates/react-vite-lib/src/commponents/Text.tsx +0 -7
- package/templates/react-vite-lib/src/index.ts +0 -2
- package/templates/react-vite-lib/src/vite-env.d.ts +0 -1
- package/templates/react-vite-lib/tsconfig.json +0 -25
- package/templates/react-vite-lib/vite.config.ts +0 -24
- /package/{templates/pack-app → configs/_common}/.editorconfig +0 -0
- /package/{templates/pack-app → configs/_common}/.gitattributes +0 -0
- /package/{templates/react-app → configs/_common}/.gitignore.template +0 -0
- /package/{templates/pack-app → configs/_common}/.prettierignore +0 -0
- /package/templates/react-app/src/{services → base/apis}/feApi/FeApi.ts +0 -0
- /package/templates/react-app/src/{services → base/apis}/feApi/FeApiType.ts +0 -0
- /package/templates/react-app/src/{services → base/apis}/feApi/index.ts +0 -0
- /package/templates/react-app/src/{types → base/types}/Page.ts +0 -0
- /package/templates/react-app/src/{containers → core}/globals.ts +0 -0
- /package/templates/react-app/src/{hooks → uikit/hooks}/useLanguageGuard.ts +0 -0
- /package/templates/react-app/src/{hooks → uikit/hooks}/useStrictEffect.ts +0 -0
- /package/templates/react-app/src/{styles → uikit/styles}/css/index.css +0 -0
- /package/templates/react-app/src/{styles → uikit/styles}/css/page.css +0 -0
- /package/templates/react-app/src/{styles → uikit/styles}/css/tailwind.css +0 -0
- /package/templates/react-app/src/{utils → uikit/utils}/RequestLogger.ts +0 -0
- /package/templates/react-app/src/{utils → uikit/utils}/datetime.ts +0 -0
- /package/templates/react-app/src/{utils → uikit/utils}/thread.ts +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { IOCInterface, IOCRegisterInterface } from '@/base/port/IOCInterface';
|
|
2
|
+
import { RequestLogger } from '@/uikit/utils/RequestLogger';
|
|
3
|
+
import { localJsonStorage } from '../globals';
|
|
4
|
+
import { FetchAbortPlugin, FetchURLPlugin } from '@qlover/fe-utils';
|
|
5
|
+
import { FeApiMockPlugin } from '@/base/apis/feApi';
|
|
6
|
+
import { defaultFeApiConfig } from '@config/app.common';
|
|
7
|
+
import { OpenAIClient } from '@lib/openAiApi';
|
|
8
|
+
import { openAiConfig } from '@config/app.common';
|
|
9
|
+
import { FeApi } from '@/base/apis/feApi';
|
|
10
|
+
import { RequestCommonPlugin } from '@lib/request-common-plugin';
|
|
11
|
+
import mockDataJson from '@config/feapi.mock.json';
|
|
12
|
+
|
|
13
|
+
export class RegisterApi implements IOCRegisterInterface {
|
|
14
|
+
register(container: IOCInterface): void {
|
|
15
|
+
const openAiApi = new OpenAIClient({
|
|
16
|
+
...openAiConfig,
|
|
17
|
+
commonPluginConfig: {
|
|
18
|
+
...openAiConfig.commonPluginConfig,
|
|
19
|
+
requestDataSerializer: (data) => JSON.stringify(data)
|
|
20
|
+
}
|
|
21
|
+
}).usePlugin(container.get(RequestLogger));
|
|
22
|
+
|
|
23
|
+
const feApi = new FeApi({
|
|
24
|
+
abortPlugin: container.get(FetchAbortPlugin),
|
|
25
|
+
config: defaultFeApiConfig.adapter
|
|
26
|
+
})
|
|
27
|
+
.usePlugin(new FetchURLPlugin())
|
|
28
|
+
.usePlugin(
|
|
29
|
+
new RequestCommonPlugin({
|
|
30
|
+
...defaultFeApiConfig.commonPluginConfig,
|
|
31
|
+
token: () => localJsonStorage.getItem('fe_user_token')
|
|
32
|
+
})
|
|
33
|
+
)
|
|
34
|
+
.usePlugin(new FeApiMockPlugin(mockDataJson))
|
|
35
|
+
.usePlugin(container.get(RequestLogger))
|
|
36
|
+
.usePlugin(container.get(FetchAbortPlugin));
|
|
37
|
+
|
|
38
|
+
container.bind(OpenAIClient, openAiApi);
|
|
39
|
+
container.bind(FeApi, feApi);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { IOCInterface, IOCRegisterInterface } from '@/base/port/IOCInterface';
|
|
2
|
+
import { RequestLogger } from '@/uikit/utils/RequestLogger';
|
|
3
|
+
import { localJsonStorage, logger } from '../globals';
|
|
4
|
+
import { FetchAbortPlugin } from '@qlover/fe-utils';
|
|
5
|
+
import { UserToken } from '@/base/cases/UserToken';
|
|
6
|
+
|
|
7
|
+
export class RegisterCommon implements IOCRegisterInterface {
|
|
8
|
+
register(container: IOCInterface): void {
|
|
9
|
+
const requestLogger = new RequestLogger(logger);
|
|
10
|
+
const feApiAbort = new FetchAbortPlugin();
|
|
11
|
+
const userToken = new UserToken({
|
|
12
|
+
storageKey: 'fe_user_token',
|
|
13
|
+
storage: localJsonStorage
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
container.bind(RequestLogger, requestLogger);
|
|
17
|
+
container.bind(FetchAbortPlugin, feApiAbort);
|
|
18
|
+
container.bind(UserToken, userToken);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { IOCInterface, IOCRegisterInterface } from '@/base/port/IOCInterface';
|
|
2
|
+
import { localJsonStorage, logger } from '../globals';
|
|
3
|
+
import { RouterController } from '@/uikit/controllers/RouterController';
|
|
4
|
+
import { JSONStorageController } from '@/uikit/controllers/JSONStorageController';
|
|
5
|
+
import { RequestController } from '@/uikit/controllers/RequestController';
|
|
6
|
+
import { ProcesserService } from '@/services/processer/ProcesserService';
|
|
7
|
+
import { ExecutorController } from '@/uikit/controllers/ExecutorController';
|
|
8
|
+
import { UserController } from '@/uikit/controllers/UserController';
|
|
9
|
+
import { ThemeController } from '@lib/fe-react-theme/ThemeController';
|
|
10
|
+
import { RouteConfig } from '@/base/types/Page';
|
|
11
|
+
import { OpenAIClient } from '@lib/openAiApi';
|
|
12
|
+
import { FeApi } from '@/base/apis/feApi';
|
|
13
|
+
|
|
14
|
+
import appRouterConfig from '@config/app.router.json';
|
|
15
|
+
import themeConfigJson from '@config/theme.json';
|
|
16
|
+
import { UserToken } from '@/base/cases/UserToken';
|
|
17
|
+
|
|
18
|
+
export class RegisterControllers implements IOCRegisterInterface {
|
|
19
|
+
register(container: IOCInterface): void {
|
|
20
|
+
const routerController = new RouterController({
|
|
21
|
+
config: appRouterConfig.base as RouteConfig,
|
|
22
|
+
logger
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const jsonStorageController = new JSONStorageController(localJsonStorage);
|
|
26
|
+
const requestController = new RequestController(
|
|
27
|
+
container.get(OpenAIClient),
|
|
28
|
+
container.get(FeApi)
|
|
29
|
+
);
|
|
30
|
+
const executorController = new ExecutorController(container.get(FeApi));
|
|
31
|
+
const userController = new UserController({
|
|
32
|
+
userToken: container.get(UserToken),
|
|
33
|
+
feApi: container.get(FeApi),
|
|
34
|
+
routerController
|
|
35
|
+
});
|
|
36
|
+
const themeController = new ThemeController({
|
|
37
|
+
...themeConfigJson.override,
|
|
38
|
+
storage: localJsonStorage
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const pageProcesser = new ProcesserService({
|
|
42
|
+
logger
|
|
43
|
+
}).usePlugin(userController);
|
|
44
|
+
|
|
45
|
+
container.bind(RouterController, routerController);
|
|
46
|
+
container.bind(JSONStorageController, jsonStorageController);
|
|
47
|
+
container.bind(RequestController, requestController);
|
|
48
|
+
container.bind(ExecutorController, executorController);
|
|
49
|
+
container.bind(UserController, userController);
|
|
50
|
+
container.bind(ThemeController, themeController);
|
|
51
|
+
container.bind(ProcesserService, pageProcesser);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// ! dont't import tsx, only ts file
|
|
2
|
+
import { ServiceIdentifier, IOCInterface } from '@/base/port/IOCInterface';
|
|
3
|
+
|
|
4
|
+
export type IOCFunction = {
|
|
5
|
+
<T>(serviceIdentifier: ServiceIdentifier<T>): T;
|
|
6
|
+
/**
|
|
7
|
+
* IOC container instance
|
|
8
|
+
*/
|
|
9
|
+
implemention: IOCInterface | null;
|
|
10
|
+
/**
|
|
11
|
+
* implement IOC container
|
|
12
|
+
*/
|
|
13
|
+
implement(container: IOCInterface): void;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const IOC: IOCFunction = Object.assign(
|
|
17
|
+
function <T>(serviceIdentifier: ServiceIdentifier<T>): T {
|
|
18
|
+
if (!IOC.implemention) {
|
|
19
|
+
throw new Error('IOC is not implemented');
|
|
20
|
+
}
|
|
21
|
+
return IOC.implemention.get(serviceIdentifier);
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
implemention: null,
|
|
25
|
+
implement: (container: IOCInterface) => {
|
|
26
|
+
// FIXME: maybe runtimes configure
|
|
27
|
+
container.configure();
|
|
28
|
+
IOC.implemention = container;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
);
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { StrictMode } from 'react'
|
|
2
|
-
import { createRoot } from 'react-dom/client'
|
|
3
|
-
import App from './App.tsx'
|
|
4
|
-
import
|
|
1
|
+
import { StrictMode } from 'react';
|
|
2
|
+
import { createRoot } from 'react-dom/client';
|
|
3
|
+
import App from './App.tsx';
|
|
4
|
+
import { Bootstrap } from './core/bootstrap';
|
|
5
|
+
import { FeIOC } from './core/feIOC/FeIOC';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
if (typeof window !== 'undefined') {
|
|
8
|
-
window.feGlobals = Object.freeze(Object.assign({}, feGlobals));
|
|
9
|
-
}
|
|
7
|
+
new Bootstrap(new FeIOC()).start();
|
|
10
8
|
|
|
11
9
|
createRoot(document.getElementById('root')!).render(
|
|
12
10
|
<StrictMode>
|
|
13
11
|
<App />
|
|
14
|
-
</StrictMode
|
|
15
|
-
)
|
|
12
|
+
</StrictMode>
|
|
13
|
+
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useBaseRoutePage } from '@/
|
|
1
|
+
import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
|
|
2
2
|
|
|
3
3
|
export default function NotFound({ route }: { route?: string }) {
|
|
4
4
|
const { t } = useBaseRoutePage();
|
|
@@ -6,7 +6,7 @@ export default function NotFound({ route }: { route?: string }) {
|
|
|
6
6
|
<div className="flex flex-col justify-center min-h-screen py-6 bg-background sm:py-12">
|
|
7
7
|
<div className="relative py-3 mx-auto sm:max-w-xl">
|
|
8
8
|
<h1 className="text-primary text-2xl font-bold text-center">
|
|
9
|
-
404 -
|
|
9
|
+
404 -{route ? `${t('404.notComponent')}: ${route}` : t('404.notPage')}
|
|
10
10
|
</h1>
|
|
11
11
|
</div>
|
|
12
12
|
</div>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IOC } from '@/core';
|
|
2
|
+
import { UserController } from '@/uikit/controllers/UserController';
|
|
2
3
|
import { useController } from '@lib/fe-react-controller';
|
|
3
4
|
import { Navigate, Outlet } from 'react-router-dom';
|
|
4
5
|
|
|
5
6
|
export default function Layout() {
|
|
6
|
-
const controller = useController(
|
|
7
|
+
const controller = useController(IOC(UserController));
|
|
7
8
|
|
|
8
9
|
// If user is authenticated, redirect to home page
|
|
9
10
|
if (controller.isAuthenticated()) {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
2
|
import { useController } from '@lib/fe-react-controller';
|
|
3
|
-
import {
|
|
4
|
-
import { useBaseRoutePage } from '@/
|
|
3
|
+
import { IOC } from '@/core';
|
|
4
|
+
import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
|
|
5
5
|
import { defaultLoginInfo } from '@config/app.common';
|
|
6
|
+
import { RouterController } from '@/uikit/controllers/RouterController';
|
|
7
|
+
import { UserController } from '@/uikit/controllers/UserController';
|
|
6
8
|
|
|
7
9
|
export default function Login() {
|
|
8
10
|
const { t } = useBaseRoutePage();
|
|
9
|
-
const controller = useController(
|
|
11
|
+
const controller = useController(IOC(UserController));
|
|
10
12
|
const [email, setEmail] = useState(defaultLoginInfo.name);
|
|
11
13
|
const [password, setPassword] = useState(defaultLoginInfo.password);
|
|
12
14
|
const [loading, setLoading] = useState(false);
|
|
@@ -16,7 +18,7 @@ export default function Login() {
|
|
|
16
18
|
setLoading(true);
|
|
17
19
|
await controller.login({ username: email, password });
|
|
18
20
|
// Redirect or show success message
|
|
19
|
-
|
|
21
|
+
IOC(RouterController).replaceToHome();
|
|
20
22
|
} catch (error) {
|
|
21
23
|
// Handle login error
|
|
22
24
|
console.error(error);
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IOC } from '@/core';
|
|
2
2
|
import { useControllerState } from '@lib/fe-react-controller';
|
|
3
|
-
import { useBaseRoutePage } from '@/
|
|
3
|
+
import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
|
|
4
|
+
import { JSONStorageController } from '@/uikit/controllers/JSONStorageController';
|
|
5
|
+
import { ExecutorController } from '@/uikit/controllers/ExecutorController';
|
|
4
6
|
|
|
5
7
|
export default function Executor() {
|
|
6
|
-
const jsonStorageControllerState = useControllerState(
|
|
8
|
+
const jsonStorageControllerState = useControllerState(
|
|
9
|
+
IOC(JSONStorageController)
|
|
10
|
+
);
|
|
7
11
|
const { t } = useBaseRoutePage();
|
|
8
12
|
|
|
9
13
|
return (
|
|
@@ -26,7 +30,7 @@ export default function Executor() {
|
|
|
26
30
|
|
|
27
31
|
<button
|
|
28
32
|
className="bg-blue-500 text-white px-4 py-2 rounded-md"
|
|
29
|
-
onClick={
|
|
33
|
+
onClick={IOC(ExecutorController).onTestPlugins}
|
|
30
34
|
>
|
|
31
35
|
{t('testPlugin')}
|
|
32
36
|
</button>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import LocaleLink from '@/components/LocaleLink';
|
|
2
|
-
import { useBaseRoutePage } from '
|
|
2
|
+
import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
|
|
3
3
|
|
|
4
4
|
export default function Home() {
|
|
5
5
|
const { t } = useBaseRoutePage();
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IOC } from '@/core';
|
|
2
2
|
import { useController, useControllerState } from '@lib/fe-react-controller';
|
|
3
|
-
import { useBaseRoutePage } from '@/
|
|
3
|
+
import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
|
|
4
4
|
import template from 'lodash/template';
|
|
5
|
+
import { JSONStorageController } from '@/uikit/controllers/JSONStorageController';
|
|
5
6
|
|
|
6
7
|
export default function JSONStorage() {
|
|
8
|
+
const jsonStorageController = IOC(JSONStorageController);
|
|
7
9
|
const controllerState = useControllerState(
|
|
8
10
|
useController(jsonStorageController)
|
|
9
11
|
);
|
|
@@ -28,7 +30,7 @@ export default function JSONStorage() {
|
|
|
28
30
|
{template(t('format.title'))({
|
|
29
31
|
key: 'testKey1',
|
|
30
32
|
min: 100,
|
|
31
|
-
max: 9000
|
|
33
|
+
max: 9000
|
|
32
34
|
})}
|
|
33
35
|
</div>
|
|
34
36
|
|
|
@@ -58,7 +60,7 @@ export default function JSONStorage() {
|
|
|
58
60
|
{template(t('format.title'))({
|
|
59
61
|
key: 'testKey2',
|
|
60
62
|
min: 100,
|
|
61
|
-
max: 9000
|
|
63
|
+
max: 9000
|
|
62
64
|
})}
|
|
63
65
|
</div>
|
|
64
66
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import BaseHeader from './components/BaseHeader';
|
|
2
2
|
import { Outlet } from 'react-router-dom';
|
|
3
|
-
import { ProcessProvider } from '@/
|
|
3
|
+
import { ProcessProvider } from '@/uikit/providers/ProcessProvider';
|
|
4
4
|
|
|
5
5
|
export default function Layout() {
|
|
6
6
|
return (
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IOC } from '@/core';
|
|
2
2
|
import { useControllerState } from '@lib/fe-react-controller';
|
|
3
|
-
import { useBaseRoutePage } from '
|
|
3
|
+
import { useBaseRoutePage } from '@/uikit/contexts/BaseRouteContext';
|
|
4
|
+
import { JSONStorageController } from '@/uikit/controllers/JSONStorageController';
|
|
5
|
+
import { RequestController } from '@/uikit/controllers/RequestController';
|
|
4
6
|
|
|
5
7
|
export default function Request() {
|
|
8
|
+
const requestController = IOC(RequestController);
|
|
6
9
|
const requestControllerState = useControllerState(requestController);
|
|
7
|
-
const jsonStorageControllerState = useControllerState(
|
|
10
|
+
const jsonStorageControllerState = useControllerState(
|
|
11
|
+
IOC(JSONStorageController)
|
|
12
|
+
);
|
|
8
13
|
const { t } = useBaseRoutePage();
|
|
9
14
|
|
|
10
15
|
return (
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { lazy, Suspense } from 'react';
|
|
2
2
|
import isString from 'lodash/isString';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
LoadProps,
|
|
5
|
+
PagesMaps,
|
|
6
|
+
RouteCategory,
|
|
7
|
+
RouteType
|
|
8
|
+
} from '@/base/types/Page';
|
|
4
9
|
import { Loading } from '@/components/Loading';
|
|
5
|
-
import BaseRouteProvider from '../
|
|
10
|
+
import BaseRouteProvider from '../uikit/providers/BaseRouteProvider';
|
|
6
11
|
import NotFound from './404';
|
|
7
12
|
import NotFound500 from './500';
|
|
8
13
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { AsyncExecutor, ExecutorPlugin, Logger } from '@qlover/fe-utils';
|
|
2
2
|
|
|
3
|
-
export interface
|
|
3
|
+
export interface ProcesserServiceOptions {
|
|
4
4
|
logger: Logger;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
export class
|
|
7
|
+
export class ProcesserService {
|
|
8
8
|
private executor: AsyncExecutor;
|
|
9
|
-
constructor(private options:
|
|
9
|
+
constructor(private options: ProcesserServiceOptions) {
|
|
10
10
|
this.executor = new AsyncExecutor();
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useTranslation } from 'react-i18next';
|
|
2
|
-
import { useContext } from 'react';
|
|
3
|
-
import { BasePageProvider } from '@/types/Page';
|
|
4
|
-
import { RouteMeta } from '@/types/Page';
|
|
2
|
+
import { useContext, useMemo } from 'react';
|
|
3
|
+
import { BasePageProvider } from '@/base/types/Page';
|
|
4
|
+
import { RouteMeta } from '@/base/types/Page';
|
|
5
5
|
import { createContext } from 'react';
|
|
6
6
|
import { defaultBaseRoutemeta } from '@config/app.common';
|
|
7
7
|
import merge from 'lodash/merge';
|
|
@@ -15,7 +15,7 @@ export function useBaseRoutePage(): BasePageProvider {
|
|
|
15
15
|
throw new Error('useBaseRoutePage must be used within a PageProvider');
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const _meta = merge({}, defaultBaseRoutemeta, meta);
|
|
18
|
+
const _meta = useMemo(() => merge({}, defaultBaseRoutemeta, meta), [meta]);
|
|
19
19
|
|
|
20
20
|
const i18n = useTranslation(_meta.localNamespace);
|
|
21
21
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { FeController } from '@lib/fe-react-controller';
|
|
2
|
-
import { FeApi } from '@/
|
|
2
|
+
import { FeApi } from '@/base/apis/feApi';
|
|
3
3
|
import cloneDeep from 'lodash/cloneDeep';
|
|
4
4
|
import {
|
|
5
5
|
ExecutorPlugin,
|
|
6
|
-
RequestAdapterResponse
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
RequestAdapterResponse,
|
|
7
|
+
RequestAdapterFetchConfig
|
|
8
|
+
} from '@qlover/fe-utils';
|
|
9
9
|
|
|
10
10
|
function createDefaultState() {
|
|
11
11
|
return {
|
|
@@ -37,7 +37,7 @@ export class ExecutorController extends FeController<ExecutorControllerState> {
|
|
|
37
37
|
private feApi: FeApi;
|
|
38
38
|
|
|
39
39
|
constructor(feApi: FeApi) {
|
|
40
|
-
super(createDefaultState
|
|
40
|
+
super(createDefaultState);
|
|
41
41
|
|
|
42
42
|
this.feApi = cloneDeep(feApi);
|
|
43
43
|
|
|
@@ -11,12 +11,12 @@ interface JSONStoragePageState {
|
|
|
11
11
|
|
|
12
12
|
export class JSONStorageController extends FeController<JSONStoragePageState> {
|
|
13
13
|
constructor(private storage: JSONStorage) {
|
|
14
|
-
super({
|
|
14
|
+
super(() => ({
|
|
15
15
|
testKey1: storage.getItem('testKey1') ?? 0,
|
|
16
16
|
testKey2: storage.getItem('testKey2') ?? 0,
|
|
17
17
|
expireTime: 5000,
|
|
18
18
|
requestTimeout: storage.getItem('requestTimeout') ?? 5000
|
|
19
|
-
});
|
|
19
|
+
}));
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
changeRandomTestKey1 = (): void => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { OpenAIClient } from '@lib/openAiApi/OpenAIClient';
|
|
2
2
|
import { FeController } from '@lib/fe-react-controller';
|
|
3
|
-
import { FeApi } from '@/
|
|
4
|
-
import { logger } from '@/
|
|
3
|
+
import { FeApi } from '@/base/apis/feApi';
|
|
4
|
+
import { logger } from '@/core/globals';
|
|
5
5
|
|
|
6
6
|
function createDefaultState() {
|
|
7
7
|
return {
|
|
@@ -35,7 +35,7 @@ export class RequestController extends FeController<RequestControllerState> {
|
|
|
35
35
|
private readonly aiApi: OpenAIClient,
|
|
36
36
|
private readonly feApi: FeApi
|
|
37
37
|
) {
|
|
38
|
-
super(createDefaultState
|
|
38
|
+
super(createDefaultState);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
onHello = async () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { I18nService } from '@/services/i18n';
|
|
2
|
-
import { RouteConfig, RouteType } from '@/types/Page';
|
|
3
|
-
import { UIDependenciesInterface } from '@/
|
|
2
|
+
import { RouteConfig, RouteType } from '@/base/types/Page';
|
|
3
|
+
import { UIDependenciesInterface } from '@/base/port/UIDependenciesInterface';
|
|
4
4
|
import { i18nConfig } from '@config/i18n';
|
|
5
5
|
import { Logger } from '@qlover/fe-utils';
|
|
6
6
|
import { NavigateFunction, NavigateOptions } from 'react-router-dom';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { ExecutorPlugin
|
|
2
|
-
import { sleep } from '@/utils/thread';
|
|
1
|
+
import { ExecutorPlugin } from '@qlover/fe-utils';
|
|
2
|
+
import { sleep } from '@/uikit/utils/thread';
|
|
3
3
|
import { FeController } from '@lib/fe-react-controller';
|
|
4
|
-
import { FeApi } from '@/
|
|
5
|
-
import { FeApiGetUserInfo, FeApiLogin } from '@/
|
|
6
|
-
import { adjustExpirationTime } from '@/utils/datetime';
|
|
4
|
+
import { FeApi } from '@/base/apis/feApi';
|
|
5
|
+
import { FeApiGetUserInfo, FeApiLogin } from '@/base/apis/feApi/FeApiType';
|
|
7
6
|
import { RouterController } from './RouterController';
|
|
7
|
+
import { StorageTokenInterface } from '@/base/port/StorageTokenInterface';
|
|
8
8
|
|
|
9
9
|
export interface UserControllerState {
|
|
10
10
|
success: boolean;
|
|
@@ -12,12 +12,7 @@ export interface UserControllerState {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export interface UserControllerOptions {
|
|
15
|
-
|
|
16
|
-
* @default `month`
|
|
17
|
-
*/
|
|
18
|
-
expiresIn?: number | 'day' | 'week' | 'month' | 'year';
|
|
19
|
-
storageKey: string;
|
|
20
|
-
storage: JSONStorage;
|
|
15
|
+
userToken: StorageTokenInterface;
|
|
21
16
|
feApi: FeApi;
|
|
22
17
|
routerController: RouterController;
|
|
23
18
|
}
|
|
@@ -29,23 +24,19 @@ interface LoginInterface {
|
|
|
29
24
|
logout(): void;
|
|
30
25
|
}
|
|
31
26
|
|
|
32
|
-
function
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
const
|
|
37
|
-
const token = storage.getItem(storageKey, '') as string;
|
|
27
|
+
function createDefaultState(
|
|
28
|
+
options: UserControllerOptions
|
|
29
|
+
): UserControllerState {
|
|
30
|
+
const { userToken } = options;
|
|
31
|
+
const token = userToken.getToken();
|
|
38
32
|
|
|
39
33
|
return {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
token
|
|
34
|
+
success: !!token,
|
|
35
|
+
userInfo: {
|
|
36
|
+
name: '',
|
|
37
|
+
email: '',
|
|
38
|
+
picture: ''
|
|
39
|
+
}
|
|
49
40
|
};
|
|
50
41
|
}
|
|
51
42
|
|
|
@@ -55,24 +46,17 @@ export class UserController
|
|
|
55
46
|
{
|
|
56
47
|
readonly pluginName = 'UserController';
|
|
57
48
|
|
|
58
|
-
private token = '';
|
|
59
|
-
|
|
60
49
|
constructor(private options: UserControllerOptions) {
|
|
61
|
-
|
|
62
|
-
super(restoreSession.state);
|
|
63
|
-
|
|
64
|
-
this.token = restoreSession.token;
|
|
50
|
+
super(() => createDefaultState(options));
|
|
65
51
|
}
|
|
66
52
|
|
|
67
|
-
selectorSuccess = (state: UserControllerState): boolean => state.success;
|
|
68
|
-
|
|
69
53
|
/**
|
|
70
54
|
* @override
|
|
71
55
|
*/
|
|
72
56
|
async onBefore(): Promise<void> {
|
|
73
57
|
await sleep(1000);
|
|
74
58
|
|
|
75
|
-
if (!this.
|
|
59
|
+
if (!this.options.userToken.getToken()) {
|
|
76
60
|
throw new Error('User not logged in');
|
|
77
61
|
}
|
|
78
62
|
|
|
@@ -103,7 +87,7 @@ export class UserController
|
|
|
103
87
|
|
|
104
88
|
const result = await feApi.login(params);
|
|
105
89
|
|
|
106
|
-
this.setToken(result.data.token);
|
|
90
|
+
this.options.userToken.setToken(result.data.token);
|
|
107
91
|
|
|
108
92
|
const userInfo = await feApi.getUserInfo();
|
|
109
93
|
|
|
@@ -122,22 +106,12 @@ export class UserController
|
|
|
122
106
|
this.reset();
|
|
123
107
|
}
|
|
124
108
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const { storageKey, storage } = this.options;
|
|
129
|
-
|
|
130
|
-
storage.setItem(
|
|
131
|
-
storageKey,
|
|
132
|
-
this.token,
|
|
133
|
-
adjustExpirationTime(Date.now(), this.options.expiresIn ?? 'month')
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
|
|
109
|
+
/**
|
|
110
|
+
* @override
|
|
111
|
+
*/
|
|
137
112
|
reset(): void {
|
|
138
|
-
this.
|
|
139
|
-
|
|
140
|
-
this.setState({ success: false });
|
|
113
|
+
this.options.userToken.removeToken();
|
|
114
|
+
super.reset();
|
|
141
115
|
}
|
|
142
116
|
|
|
143
117
|
isAuthenticated(): boolean {
|
package/templates/react-app/src/{containers/context → uikit/providers}/BaseRouteProvider.tsx
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
|
2
|
-
import { RouteMeta } from '@/types/Page';
|
|
3
|
-
import { BaseRoutePageContext } from '
|
|
2
|
+
import { RouteMeta } from '@/base/types/Page';
|
|
3
|
+
import { BaseRoutePageContext } from '../contexts/BaseRouteContext';
|
|
4
4
|
|
|
5
5
|
export default function BaseRouteProvider(props: PropsWithChildren<RouteMeta>) {
|
|
6
6
|
return (
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import { createContext, useEffect } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { useLanguageGuard } from '@/hooks/useLanguageGuard';
|
|
4
|
-
import { useStrictEffect } from '@/hooks/useStrictEffect';
|
|
5
|
-
import {
|
|
2
|
+
import { IOC } from '@/core';
|
|
3
|
+
import { useLanguageGuard } from '@/uikit/hooks/useLanguageGuard';
|
|
4
|
+
import { useStrictEffect } from '@/uikit/hooks/useStrictEffect';
|
|
5
|
+
import { ProcesserService } from '@/services/processer/ProcesserService';
|
|
6
6
|
import { Navigate, useNavigate } from 'react-router-dom';
|
|
7
7
|
import { useControllerState } from '@lib/fe-react-controller';
|
|
8
|
-
import { Loading } from '
|
|
8
|
+
import { Loading } from '@/components/Loading';
|
|
9
|
+
import { RouterController } from '../controllers/RouterController';
|
|
10
|
+
import { UserController } from '../controllers/UserController';
|
|
9
11
|
|
|
10
|
-
const PageProcesserContext = createContext<
|
|
12
|
+
const PageProcesserContext = createContext<ProcesserService>(
|
|
13
|
+
IOC(ProcesserService)
|
|
14
|
+
);
|
|
11
15
|
|
|
12
16
|
export function ProcessProvider({ children }: { children: React.ReactNode }) {
|
|
13
17
|
useLanguageGuard();
|
|
18
|
+
const userController = IOC(UserController);
|
|
19
|
+
const pageProcesser = IOC(ProcesserService);
|
|
14
20
|
const { success } = useControllerState(userController);
|
|
15
21
|
|
|
16
22
|
const navigate = useNavigate();
|
|
@@ -20,7 +26,7 @@ export function ProcessProvider({ children }: { children: React.ReactNode }) {
|
|
|
20
26
|
}, []);
|
|
21
27
|
|
|
22
28
|
useEffect(() => {
|
|
23
|
-
|
|
29
|
+
IOC(RouterController).setDependencies({
|
|
24
30
|
navigate
|
|
25
31
|
});
|
|
26
32
|
}, [navigate]);
|