@qlover/create-app 0.1.15 → 0.1.16
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 +33 -27
- package/bin/create-app.js +0 -0
- package/configs/_common/package.json.template +10 -0
- package/configs/react-app/eslint.config.js +70 -42
- package/dist/index.cjs +1 -3631
- package/dist/index.js +1 -3625
- package/package.json +7 -7
- package/templates/react-app/.env +1 -0
- package/templates/react-app/config/ErrorIdentifier.ts +27 -0
- package/templates/react-app/config/app.router.json +9 -0
- package/templates/react-app/config/common.ts +12 -0
- package/templates/react-app/config/feapi.mock.json +15 -2
- package/templates/react-app/config/i18n.ts +3 -11
- package/templates/react-app/package.json +7 -4
- package/templates/react-app/pnpm-lock.yaml +176 -25
- package/templates/react-app/public/locales/en/common.json +6 -2
- package/templates/react-app/public/locales/zh/common.json +6 -3
- package/templates/react-app/src/App.tsx +8 -8
- package/templates/react-app/src/base/apis/AiApi.ts +55 -0
- package/templates/react-app/src/base/apis/feApi/FeApi.ts +13 -44
- package/templates/react-app/src/base/apis/feApi/FeApiAdapter.ts +14 -0
- package/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +67 -0
- package/templates/react-app/src/base/apis/feApi/FeApiType.ts +2 -35
- package/templates/react-app/src/base/apis/userApi/UserApi.ts +64 -0
- package/templates/react-app/src/base/apis/userApi/UserApiAdapter.ts +14 -0
- package/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +75 -0
- package/templates/react-app/src/base/apis/userApi/UserApiType.ts +52 -0
- package/templates/react-app/src/base/cases/RequestLogger.ts +71 -0
- package/templates/react-app/src/base/cases/RequestStatusCatcher.ts +41 -0
- package/templates/react-app/src/base/cases/appError/AppError.ts +13 -0
- package/templates/react-app/{lib/router-loader/RouterLoader.ts → src/base/cases/router-loader/index.ts} +1 -1
- package/templates/react-app/src/base/port/ApiTransactionInterface.ts +7 -0
- package/templates/react-app/src/base/port/InversifyIocInterface.ts +1 -1
- package/templates/react-app/src/base/port/LoginInterface.ts +4 -0
- package/templates/react-app/src/base/port/RequestCatcherInterface.ts +12 -0
- package/templates/react-app/src/{services → base/services}/I18nService.ts +7 -2
- package/templates/react-app/src/{services/processer → base/services}/ProcesserService.ts +10 -11
- package/templates/react-app/src/base/types/Page.ts +1 -13
- package/templates/react-app/src/core/AppConfig.ts +14 -5
- package/templates/react-app/src/core/IOC.ts +77 -37
- package/templates/react-app/src/core/bootstrap.ts +38 -25
- package/templates/react-app/src/core/bootstraps/BootstrapApp.ts +7 -0
- package/templates/react-app/src/core/bootstraps/index.ts +12 -0
- package/templates/react-app/src/core/globals.ts +7 -10
- package/templates/react-app/src/core/registers/RegisterApi.ts +1 -52
- package/templates/react-app/src/core/registers/RegisterCommon.ts +44 -6
- package/templates/react-app/src/core/registers/RegisterControllers.ts +5 -34
- package/templates/react-app/src/core/registers/RegisterGlobals.ts +8 -2
- package/templates/react-app/src/core/registers/index.ts +2 -1
- package/templates/react-app/src/main.tsx +4 -1
- package/templates/react-app/src/pages/auth/Layout.tsx +4 -3
- package/templates/react-app/src/pages/auth/Login.tsx +5 -3
- package/templates/react-app/src/pages/base/ErrorIdentifier.tsx +39 -0
- package/templates/react-app/src/pages/base/Executor.tsx +31 -10
- package/templates/react-app/src/pages/base/Home.tsx +58 -30
- package/templates/react-app/src/pages/base/JSONStorage.tsx +2 -4
- package/templates/react-app/src/pages/base/Request.tsx +318 -73
- package/templates/react-app/src/pages/base/components/BaseHeader.tsx +2 -2
- package/templates/react-app/src/{components → uikit/components}/RouterRenderComponent.tsx +1 -1
- package/templates/react-app/src/{components → uikit/components}/ThemeSwitcher.tsx +6 -6
- package/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +6 -3
- package/templates/react-app/src/uikit/controllers/ExecutorController.ts +52 -22
- package/templates/react-app/src/uikit/controllers/JSONStorageController.ts +7 -3
- package/templates/react-app/src/uikit/controllers/RequestController.ts +65 -11
- package/templates/react-app/src/uikit/controllers/RouterController.ts +8 -7
- package/templates/react-app/src/uikit/controllers/UserController.ts +48 -54
- package/templates/react-app/src/uikit/hooks/useLanguageGuard.ts +1 -2
- package/templates/react-app/src/uikit/providers/ProcessProvider.tsx +4 -4
- package/templates/react-app/src/uikit/styles/css/index.css +1 -1
- package/templates/react-app/src/uikit/styles/css/page.css +1 -1
- package/templates/react-app/tailwind.config.js +2 -2
- package/templates/react-app/tsconfig.json +0 -1
- package/templates/react-app/tsconfig.node.json +1 -2
- package/templates/react-app/vite.config.ts +21 -26
- package/templates/react-app/.env.local +0 -24
- package/templates/react-app/lib/bootstrap/Bootstrap.ts +0 -36
- package/templates/react-app/lib/bootstrap/BootstrapExecutorPlugin.ts +0 -20
- package/templates/react-app/lib/bootstrap/IOCContainerInterface.ts +0 -33
- package/templates/react-app/lib/bootstrap/IOCManagerInterface.ts +0 -12
- package/templates/react-app/lib/bootstrap/index.ts +0 -7
- package/templates/react-app/lib/bootstrap/plugins/InjectEnv.ts +0 -61
- package/templates/react-app/lib/bootstrap/plugins/InjectGlobal.ts +0 -36
- package/templates/react-app/lib/bootstrap/plugins/InjectIOC.ts +0 -24
- package/templates/react-app/lib/env-config/injectPkgConfig.ts +0 -11
- package/templates/react-app/lib/fe-react-controller/FeController.ts +0 -19
- package/templates/react-app/lib/fe-react-controller/index.ts +0 -2
- package/templates/react-app/lib/fe-react-controller/useController.ts +0 -71
- package/templates/react-app/lib/fe-react-theme/ThemeController.ts +0 -40
- package/templates/react-app/lib/fe-react-theme/ThemeStateGetter.ts +0 -53
- package/templates/react-app/lib/fe-react-theme/index.ts +0 -3
- package/templates/react-app/lib/fe-react-theme/type.ts +0 -21
- package/templates/react-app/lib/openAiApi/OpenAIAuthPlugin.ts +0 -29
- package/templates/react-app/lib/openAiApi/OpenAIClient.ts +0 -51
- package/templates/react-app/lib/openAiApi/StreamProcessor.ts +0 -81
- package/templates/react-app/lib/openAiApi/index.ts +0 -3
- package/templates/react-app/lib/request-common-plugin/index.ts +0 -169
- package/templates/react-app/lib/router-loader/Page.ts +0 -68
- package/templates/react-app/lib/tw-root10px/index.css +0 -4
- package/templates/react-app/src/base/apis/feApi/FeApiMockPlugin.ts +0 -44
- package/templates/react-app/src/base/apis/feApi/index.ts +0 -2
- package/templates/react-app/src/base/cases/UserToken.ts +0 -47
- package/templates/react-app/src/base/consts/IOCIdentifier.ts +0 -16
- package/templates/react-app/src/base/port/IOCFunctionInterface.ts +0 -39
- package/templates/react-app/src/base/port/StorageTokenInterface.ts +0 -27
- package/templates/react-app/src/core/AppIOCContainer.ts +0 -30
- package/templates/react-app/src/uikit/utils/RequestLogger.ts +0 -37
- package/templates/react-app/src/uikit/utils/datetime.ts +0 -30
- package/templates/react-app/src/uikit/utils/thread.ts +0 -3
- /package/templates/react-app/lib/{tw-root10px/index.js → tailwind/root10px.js} +0 -0
- /package/templates/react-app/lib/{fe-react-theme/tw-generator.js → tailwind/theme-generator.js} +0 -0
- /package/templates/react-app/src/{components → uikit/components}/Loading.tsx +0 -0
- /package/templates/react-app/src/{components → uikit/components}/LocaleLink.tsx +0 -0
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ExecutorContext,
|
|
3
|
-
ExecutorPlugin,
|
|
4
|
-
RequestAdapterFetchConfig,
|
|
5
|
-
RequestAdapterResponse
|
|
6
|
-
} from '@qlover/fe-utils';
|
|
7
|
-
import { sleep } from '@/uikit/utils/thread';
|
|
8
|
-
|
|
9
|
-
export class FeApiMockPlugin implements ExecutorPlugin {
|
|
10
|
-
readonly pluginName = 'FeApiMockPlugin';
|
|
11
|
-
|
|
12
|
-
constructor(
|
|
13
|
-
private readonly mockDataJson: typeof import('@config/feapi.mock.json')
|
|
14
|
-
) {}
|
|
15
|
-
|
|
16
|
-
async onExec({
|
|
17
|
-
parameters
|
|
18
|
-
}: ExecutorContext<RequestAdapterFetchConfig>): Promise<RequestAdapterResponse> {
|
|
19
|
-
const { method = 'GET', url = '', headers } = parameters;
|
|
20
|
-
const key = `${method.toUpperCase()} ${url}`;
|
|
21
|
-
const mockData = url
|
|
22
|
-
? this.mockDataJson[key as keyof typeof this.mockDataJson] ||
|
|
23
|
-
this.mockDataJson._default
|
|
24
|
-
: this.mockDataJson._default;
|
|
25
|
-
|
|
26
|
-
const response = new Response(JSON.stringify(mockData), {
|
|
27
|
-
status: 200,
|
|
28
|
-
statusText: 'OK'
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
console.log('jj [mock]', key, mockData, headers);
|
|
32
|
-
|
|
33
|
-
await sleep(1000);
|
|
34
|
-
|
|
35
|
-
return {
|
|
36
|
-
status: response.status,
|
|
37
|
-
statusText: response.statusText,
|
|
38
|
-
headers: Object.fromEntries(response.headers.entries()),
|
|
39
|
-
data: mockData,
|
|
40
|
-
config: parameters,
|
|
41
|
-
response
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { StorageTokenInterface } from '@/base/port/StorageTokenInterface';
|
|
2
|
-
import { adjustExpirationTime } from '@/uikit/utils/datetime';
|
|
3
|
-
import { JSONStorage } from '@qlover/fe-utils';
|
|
4
|
-
|
|
5
|
-
export interface UserTokenOptions {
|
|
6
|
-
/**
|
|
7
|
-
* @default `month`
|
|
8
|
-
*/
|
|
9
|
-
expiresIn?: number | 'day' | 'week' | 'month' | 'year';
|
|
10
|
-
storageKey: string;
|
|
11
|
-
storage: JSONStorage;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export class UserToken implements StorageTokenInterface {
|
|
15
|
-
private token = '';
|
|
16
|
-
|
|
17
|
-
constructor(private options: UserTokenOptions) {}
|
|
18
|
-
|
|
19
|
-
getToken(): string {
|
|
20
|
-
if (!this.token) {
|
|
21
|
-
const { storageKey, storage } = this.options;
|
|
22
|
-
const token = storage.getItem(storageKey, '');
|
|
23
|
-
|
|
24
|
-
if (token) {
|
|
25
|
-
this.setToken(token);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return this.token;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
setToken(token: string, expireTime?: number): void {
|
|
33
|
-
this.token = token;
|
|
34
|
-
|
|
35
|
-
expireTime =
|
|
36
|
-
expireTime !== undefined
|
|
37
|
-
? expireTime
|
|
38
|
-
: adjustExpirationTime(Date.now(), this.options.expiresIn ?? 'month');
|
|
39
|
-
|
|
40
|
-
this.options.storage.setItem(this.options.storageKey, token, expireTime);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
removeToken(): void {
|
|
44
|
-
this.token = '';
|
|
45
|
-
this.options.storage.removeItem(this.options.storageKey);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* IOC identifier
|
|
3
|
-
*
|
|
4
|
-
* @description
|
|
5
|
-
* IOC identifier is used to identify the service in the IOC container.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```ts
|
|
9
|
-
* const a = IOC(IOCIdentifier.JSON);
|
|
10
|
-
* ```
|
|
11
|
-
*/
|
|
12
|
-
export const IOCIdentifier = Object.freeze({
|
|
13
|
-
JSON: 'JSON',
|
|
14
|
-
JSONStorage: 'JSONStorage',
|
|
15
|
-
Logger: 'Logger'
|
|
16
|
-
});
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { IOCManagerInterface } from '@lib/bootstrap';
|
|
2
|
-
import type { JSONSerializer, JSONStorage, Logger } from '@qlover/fe-utils';
|
|
3
|
-
import type { ServiceIdentifier } from 'inversify';
|
|
4
|
-
import type { IOCIdentifier } from '@/base/consts/IOCIdentifier';
|
|
5
|
-
|
|
6
|
-
export type IOCIdentifierMap = {
|
|
7
|
-
[IOCIdentifier.JSON]: JSONSerializer;
|
|
8
|
-
[IOCIdentifier.JSONStorage]: JSONStorage;
|
|
9
|
-
[IOCIdentifier.Logger]: Logger;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* IOC function
|
|
14
|
-
*
|
|
15
|
-
* eg.
|
|
16
|
-
* ```ts
|
|
17
|
-
* const a = IOC(A);
|
|
18
|
-
* const logger = IOC(ConstanstIdentifier.Logger);
|
|
19
|
-
* ```
|
|
20
|
-
*
|
|
21
|
-
*/
|
|
22
|
-
export interface IOCFunctionInterface extends IOCManagerInterface {
|
|
23
|
-
/**
|
|
24
|
-
* get constant identifier
|
|
25
|
-
*
|
|
26
|
-
* Preferred match for simple types
|
|
27
|
-
*/
|
|
28
|
-
<K extends keyof IOCIdentifierMap>(serviceIdentifier: K): IOCIdentifierMap[K];
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* get service identifier
|
|
32
|
-
*/
|
|
33
|
-
<T>(serviceIdentifier: ServiceIdentifier<T>): T;
|
|
34
|
-
|
|
35
|
-
get<K extends keyof IOCIdentifierMap>(
|
|
36
|
-
serviceIdentifier: K
|
|
37
|
-
): IOCIdentifierMap[K];
|
|
38
|
-
get<T>(serviceIdentifier: ServiceIdentifier<T>): T;
|
|
39
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Storage token interface
|
|
3
|
-
*
|
|
4
|
-
* @description
|
|
5
|
-
* Storage token interface is used to store and retrieve token from the storage.
|
|
6
|
-
*/
|
|
7
|
-
export interface StorageTokenInterface {
|
|
8
|
-
/**
|
|
9
|
-
* Get token
|
|
10
|
-
*
|
|
11
|
-
* @returns {string} token
|
|
12
|
-
*/
|
|
13
|
-
getToken(): string;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Set token
|
|
17
|
-
*
|
|
18
|
-
* @param {string} token
|
|
19
|
-
* @param {number} expireTime
|
|
20
|
-
*/
|
|
21
|
-
setToken(token: string, expireTime?: number): void;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Remove token
|
|
25
|
-
*/
|
|
26
|
-
removeToken(): void;
|
|
27
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { InversifyRegisterInterface } from '@/base/port/InversifyIocInterface';
|
|
2
|
-
import type { IOCContainerInterface } from '@lib/bootstrap';
|
|
3
|
-
import { ServiceIdentifier, Container } from 'inversify';
|
|
4
|
-
|
|
5
|
-
export class AppIOCContainer implements IOCContainerInterface {
|
|
6
|
-
private container: Container;
|
|
7
|
-
|
|
8
|
-
constructor() {
|
|
9
|
-
this.container = new Container({
|
|
10
|
-
// allow `@injectable` decorator, auto bind injectable classes
|
|
11
|
-
autobind: true,
|
|
12
|
-
// use singleton scope
|
|
13
|
-
defaultScope: 'Singleton'
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
configure(registers?: InversifyRegisterInterface[]): void {
|
|
18
|
-
if (registers) {
|
|
19
|
-
registers.forEach((register) => register.register(this.container, this));
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
bind<T>(key: ServiceIdentifier<T>, value: T): void {
|
|
24
|
-
this.container.bind<T>(key).toConstantValue(value);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
get<T>(key: string): T {
|
|
28
|
-
return this.container.get<T>(key);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { IOCIdentifier } from '@/base/consts/IOCIdentifier';
|
|
2
|
-
import {
|
|
3
|
-
ExecutorPlugin,
|
|
4
|
-
ExecutorContext,
|
|
5
|
-
RequestAdapterFetchConfig,
|
|
6
|
-
Logger
|
|
7
|
-
} from '@qlover/fe-utils';
|
|
8
|
-
import { injectable, inject } from 'inversify';
|
|
9
|
-
|
|
10
|
-
@injectable()
|
|
11
|
-
export class RequestLogger
|
|
12
|
-
implements ExecutorPlugin<RequestAdapterFetchConfig>
|
|
13
|
-
{
|
|
14
|
-
readonly pluginName = 'RequestLogger';
|
|
15
|
-
|
|
16
|
-
constructor(@inject(IOCIdentifier.Logger) public logger: Logger) {}
|
|
17
|
-
|
|
18
|
-
async onSuccess({
|
|
19
|
-
parameters,
|
|
20
|
-
returnValue
|
|
21
|
-
}: ExecutorContext<RequestAdapterFetchConfig>): Promise<void> {
|
|
22
|
-
this.logger.info(
|
|
23
|
-
`Request [${new Date().toLocaleString()}] ${parameters.method} ${parameters.url} [success] `,
|
|
24
|
-
returnValue
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
onError({
|
|
29
|
-
parameters,
|
|
30
|
-
error
|
|
31
|
-
}: ExecutorContext<RequestAdapterFetchConfig>): void {
|
|
32
|
-
this.logger.error(
|
|
33
|
-
`Request [${new Date().toLocaleString()}] ${parameters.method} ${parameters.url} [error] `,
|
|
34
|
-
error
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Adjusts the expiration time based on the provided `expiresIn` value.
|
|
3
|
-
*
|
|
4
|
-
* @param {number} baseTime - The base time in milliseconds to adjust.
|
|
5
|
-
* @returns {number} - The adjusted time in milliseconds.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* const adjustedTime = userController.adjustExpirationTime(Date.now());
|
|
9
|
-
*/
|
|
10
|
-
export function adjustExpirationTime(
|
|
11
|
-
baseTime: number,
|
|
12
|
-
expiresIn: number | 'day' | 'week' | 'month' | 'year'
|
|
13
|
-
): number {
|
|
14
|
-
const dayInMs = 24 * 60 * 60 * 1000;
|
|
15
|
-
|
|
16
|
-
switch (expiresIn) {
|
|
17
|
-
case 'day':
|
|
18
|
-
return baseTime + dayInMs;
|
|
19
|
-
case 'week':
|
|
20
|
-
return baseTime + 7 * dayInMs;
|
|
21
|
-
case 'month':
|
|
22
|
-
return baseTime + 30 * dayInMs; // Approximation
|
|
23
|
-
case 'year':
|
|
24
|
-
return baseTime + 365 * dayInMs; // Approximation
|
|
25
|
-
default:
|
|
26
|
-
return (
|
|
27
|
-
baseTime + (typeof expiresIn === 'number' ? expiresIn : 30 * dayInMs)
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
File without changes
|
/package/templates/react-app/lib/{fe-react-theme/tw-generator.js → tailwind/theme-generator.js}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|