@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.
Files changed (112) hide show
  1. package/CHANGELOG.md +33 -27
  2. package/bin/create-app.js +0 -0
  3. package/configs/_common/package.json.template +10 -0
  4. package/configs/react-app/eslint.config.js +70 -42
  5. package/dist/index.cjs +1 -3631
  6. package/dist/index.js +1 -3625
  7. package/package.json +7 -7
  8. package/templates/react-app/.env +1 -0
  9. package/templates/react-app/config/ErrorIdentifier.ts +27 -0
  10. package/templates/react-app/config/app.router.json +9 -0
  11. package/templates/react-app/config/common.ts +12 -0
  12. package/templates/react-app/config/feapi.mock.json +15 -2
  13. package/templates/react-app/config/i18n.ts +3 -11
  14. package/templates/react-app/package.json +7 -4
  15. package/templates/react-app/pnpm-lock.yaml +176 -25
  16. package/templates/react-app/public/locales/en/common.json +6 -2
  17. package/templates/react-app/public/locales/zh/common.json +6 -3
  18. package/templates/react-app/src/App.tsx +8 -8
  19. package/templates/react-app/src/base/apis/AiApi.ts +55 -0
  20. package/templates/react-app/src/base/apis/feApi/FeApi.ts +13 -44
  21. package/templates/react-app/src/base/apis/feApi/FeApiAdapter.ts +14 -0
  22. package/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +67 -0
  23. package/templates/react-app/src/base/apis/feApi/FeApiType.ts +2 -35
  24. package/templates/react-app/src/base/apis/userApi/UserApi.ts +64 -0
  25. package/templates/react-app/src/base/apis/userApi/UserApiAdapter.ts +14 -0
  26. package/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +75 -0
  27. package/templates/react-app/src/base/apis/userApi/UserApiType.ts +52 -0
  28. package/templates/react-app/src/base/cases/RequestLogger.ts +71 -0
  29. package/templates/react-app/src/base/cases/RequestStatusCatcher.ts +41 -0
  30. package/templates/react-app/src/base/cases/appError/AppError.ts +13 -0
  31. package/templates/react-app/{lib/router-loader/RouterLoader.ts → src/base/cases/router-loader/index.ts} +1 -1
  32. package/templates/react-app/src/base/port/ApiTransactionInterface.ts +7 -0
  33. package/templates/react-app/src/base/port/InversifyIocInterface.ts +1 -1
  34. package/templates/react-app/src/base/port/LoginInterface.ts +4 -0
  35. package/templates/react-app/src/base/port/RequestCatcherInterface.ts +12 -0
  36. package/templates/react-app/src/{services → base/services}/I18nService.ts +7 -2
  37. package/templates/react-app/src/{services/processer → base/services}/ProcesserService.ts +10 -11
  38. package/templates/react-app/src/base/types/Page.ts +1 -13
  39. package/templates/react-app/src/core/AppConfig.ts +14 -5
  40. package/templates/react-app/src/core/IOC.ts +77 -37
  41. package/templates/react-app/src/core/bootstrap.ts +38 -25
  42. package/templates/react-app/src/core/bootstraps/BootstrapApp.ts +7 -0
  43. package/templates/react-app/src/core/bootstraps/index.ts +12 -0
  44. package/templates/react-app/src/core/globals.ts +7 -10
  45. package/templates/react-app/src/core/registers/RegisterApi.ts +1 -52
  46. package/templates/react-app/src/core/registers/RegisterCommon.ts +44 -6
  47. package/templates/react-app/src/core/registers/RegisterControllers.ts +5 -34
  48. package/templates/react-app/src/core/registers/RegisterGlobals.ts +8 -2
  49. package/templates/react-app/src/core/registers/index.ts +2 -1
  50. package/templates/react-app/src/main.tsx +4 -1
  51. package/templates/react-app/src/pages/auth/Layout.tsx +4 -3
  52. package/templates/react-app/src/pages/auth/Login.tsx +5 -3
  53. package/templates/react-app/src/pages/base/ErrorIdentifier.tsx +39 -0
  54. package/templates/react-app/src/pages/base/Executor.tsx +31 -10
  55. package/templates/react-app/src/pages/base/Home.tsx +58 -30
  56. package/templates/react-app/src/pages/base/JSONStorage.tsx +2 -4
  57. package/templates/react-app/src/pages/base/Request.tsx +318 -73
  58. package/templates/react-app/src/pages/base/components/BaseHeader.tsx +2 -2
  59. package/templates/react-app/src/{components → uikit/components}/RouterRenderComponent.tsx +1 -1
  60. package/templates/react-app/src/{components → uikit/components}/ThemeSwitcher.tsx +6 -6
  61. package/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +6 -3
  62. package/templates/react-app/src/uikit/controllers/ExecutorController.ts +52 -22
  63. package/templates/react-app/src/uikit/controllers/JSONStorageController.ts +7 -3
  64. package/templates/react-app/src/uikit/controllers/RequestController.ts +65 -11
  65. package/templates/react-app/src/uikit/controllers/RouterController.ts +8 -7
  66. package/templates/react-app/src/uikit/controllers/UserController.ts +48 -54
  67. package/templates/react-app/src/uikit/hooks/useLanguageGuard.ts +1 -2
  68. package/templates/react-app/src/uikit/providers/ProcessProvider.tsx +4 -4
  69. package/templates/react-app/src/uikit/styles/css/index.css +1 -1
  70. package/templates/react-app/src/uikit/styles/css/page.css +1 -1
  71. package/templates/react-app/tailwind.config.js +2 -2
  72. package/templates/react-app/tsconfig.json +0 -1
  73. package/templates/react-app/tsconfig.node.json +1 -2
  74. package/templates/react-app/vite.config.ts +21 -26
  75. package/templates/react-app/.env.local +0 -24
  76. package/templates/react-app/lib/bootstrap/Bootstrap.ts +0 -36
  77. package/templates/react-app/lib/bootstrap/BootstrapExecutorPlugin.ts +0 -20
  78. package/templates/react-app/lib/bootstrap/IOCContainerInterface.ts +0 -33
  79. package/templates/react-app/lib/bootstrap/IOCManagerInterface.ts +0 -12
  80. package/templates/react-app/lib/bootstrap/index.ts +0 -7
  81. package/templates/react-app/lib/bootstrap/plugins/InjectEnv.ts +0 -61
  82. package/templates/react-app/lib/bootstrap/plugins/InjectGlobal.ts +0 -36
  83. package/templates/react-app/lib/bootstrap/plugins/InjectIOC.ts +0 -24
  84. package/templates/react-app/lib/env-config/injectPkgConfig.ts +0 -11
  85. package/templates/react-app/lib/fe-react-controller/FeController.ts +0 -19
  86. package/templates/react-app/lib/fe-react-controller/index.ts +0 -2
  87. package/templates/react-app/lib/fe-react-controller/useController.ts +0 -71
  88. package/templates/react-app/lib/fe-react-theme/ThemeController.ts +0 -40
  89. package/templates/react-app/lib/fe-react-theme/ThemeStateGetter.ts +0 -53
  90. package/templates/react-app/lib/fe-react-theme/index.ts +0 -3
  91. package/templates/react-app/lib/fe-react-theme/type.ts +0 -21
  92. package/templates/react-app/lib/openAiApi/OpenAIAuthPlugin.ts +0 -29
  93. package/templates/react-app/lib/openAiApi/OpenAIClient.ts +0 -51
  94. package/templates/react-app/lib/openAiApi/StreamProcessor.ts +0 -81
  95. package/templates/react-app/lib/openAiApi/index.ts +0 -3
  96. package/templates/react-app/lib/request-common-plugin/index.ts +0 -169
  97. package/templates/react-app/lib/router-loader/Page.ts +0 -68
  98. package/templates/react-app/lib/tw-root10px/index.css +0 -4
  99. package/templates/react-app/src/base/apis/feApi/FeApiMockPlugin.ts +0 -44
  100. package/templates/react-app/src/base/apis/feApi/index.ts +0 -2
  101. package/templates/react-app/src/base/cases/UserToken.ts +0 -47
  102. package/templates/react-app/src/base/consts/IOCIdentifier.ts +0 -16
  103. package/templates/react-app/src/base/port/IOCFunctionInterface.ts +0 -39
  104. package/templates/react-app/src/base/port/StorageTokenInterface.ts +0 -27
  105. package/templates/react-app/src/core/AppIOCContainer.ts +0 -30
  106. package/templates/react-app/src/uikit/utils/RequestLogger.ts +0 -37
  107. package/templates/react-app/src/uikit/utils/datetime.ts +0 -30
  108. package/templates/react-app/src/uikit/utils/thread.ts +0 -3
  109. /package/templates/react-app/lib/{tw-root10px/index.js → tailwind/root10px.js} +0 -0
  110. /package/templates/react-app/lib/{fe-react-theme/tw-generator.js → tailwind/theme-generator.js} +0 -0
  111. /package/templates/react-app/src/{components → uikit/components}/Loading.tsx +0 -0
  112. /package/templates/react-app/src/{components → uikit/components}/LocaleLink.tsx +0 -0
@@ -1,7 +1,10 @@
1
- import { OpenAIClient } from '@lib/openAiApi/OpenAIClient';
2
- import { FeController } from '@lib/fe-react-controller';
3
- import { FeApi } from '@/base/apis/feApi';
1
+ import { FeApi } from '@/base/apis/feApi/FeApi';
4
2
  import { logger } from '@/core/globals';
3
+ import { UserApi } from '@/base/apis/userApi/UserApi';
4
+ import { aiHello } from '@/base/apis/AiApi';
5
+ import { inject } from 'inversify';
6
+ import { injectable } from 'inversify';
7
+ import { SliceStore } from '@qlover/slice-store-react';
5
8
 
6
9
  function createDefaultState() {
7
10
  return {
@@ -24,25 +27,39 @@ function createDefaultState() {
24
27
  loading: false,
25
28
  result: null as unknown,
26
29
  error: null as unknown
30
+ },
31
+ apiCatchResultState: {
32
+ loading: false,
33
+ result: null as unknown,
34
+ error: null as unknown
27
35
  }
28
36
  };
29
37
  }
30
38
 
31
39
  export type RequestControllerState = ReturnType<typeof createDefaultState>;
32
40
 
33
- export class RequestController extends FeController<RequestControllerState> {
41
+ @injectable()
42
+ export class RequestController extends SliceStore<RequestControllerState> {
34
43
  constructor(
35
- private readonly aiApi: OpenAIClient,
36
- private readonly feApi: FeApi
44
+ @inject(FeApi) private readonly feApi: FeApi,
45
+ @inject(UserApi) private readonly userApi: UserApi
37
46
  ) {
38
47
  super(createDefaultState);
39
48
  }
40
49
 
50
+ setState(state: Partial<RequestControllerState>): void {
51
+ this.emit({ ...this.state, ...state });
52
+ }
53
+
41
54
  onHello = async () => {
55
+ if (this.state.helloState.loading) {
56
+ return;
57
+ }
58
+
42
59
  this.setState({ helloState: { loading: true, result: '', error: null } });
43
60
 
44
61
  try {
45
- const result = await this.aiApi.completion({
62
+ const result = await aiHello({
46
63
  messages: [{ role: 'user', content: 'Hello, world!' }]
47
64
  });
48
65
  this.setState({ helloState: { loading: false, result, error: null } });
@@ -53,9 +70,14 @@ export class RequestController extends FeController<RequestControllerState> {
53
70
  };
54
71
 
55
72
  onIpInfo = async () => {
73
+ if (this.state.ipInfoState.loading) {
74
+ return;
75
+ }
76
+
56
77
  this.setState({
57
78
  ipInfoState: { loading: true, result: null, error: null }
58
79
  });
80
+
59
81
  try {
60
82
  const result = await this.feApi.getIpInfo();
61
83
  this.setState({ ipInfoState: { loading: false, result, error: null } });
@@ -66,11 +88,15 @@ export class RequestController extends FeController<RequestControllerState> {
66
88
  };
67
89
 
68
90
  onRandomUser = async () => {
91
+ if (this.state.randomUserState.loading) {
92
+ return;
93
+ }
94
+
69
95
  this.setState({
70
96
  randomUserState: { loading: true, result: null, error: null }
71
97
  });
72
98
  try {
73
- const result = await this.feApi.getRandomUser();
99
+ const result = await this.userApi.getRandomUser();
74
100
  this.setState({
75
101
  randomUserState: { loading: false, result, error: null }
76
102
  });
@@ -82,6 +108,30 @@ export class RequestController extends FeController<RequestControllerState> {
82
108
  }
83
109
  };
84
110
 
111
+ onTriggerApiCatchResult = async () => {
112
+ if (this.state.apiCatchResultState.loading) {
113
+ return;
114
+ }
115
+
116
+ this.setState({
117
+ apiCatchResultState: { loading: true, result: null, error: null }
118
+ });
119
+ try {
120
+ const result = await this.userApi.testApiCatchResult();
121
+ this.setState({
122
+ apiCatchResultState: {
123
+ loading: false,
124
+ result,
125
+ error: result.apiCatchResult
126
+ }
127
+ });
128
+ } catch (error) {
129
+ this.setState({
130
+ apiCatchResultState: { loading: false, result: null, error }
131
+ });
132
+ }
133
+ };
134
+
85
135
  onTriggerAbortRequest = async () => {
86
136
  if (this.state.abortState.loading) {
87
137
  this.stopAbortRequest();
@@ -90,9 +140,11 @@ export class RequestController extends FeController<RequestControllerState> {
90
140
 
91
141
  this.setState({ abortState: { loading: true, result: null, error: null } });
92
142
  try {
93
- await this.feApi.request({
143
+ await this.userApi.request({
94
144
  method: 'GET',
95
- url: 'https://api.example.com/users'
145
+ url: 'https://api.example.com/users',
146
+ disabledMock: true,
147
+ requestId: 'onTriggerAbortRequest'
96
148
  });
97
149
  } catch (error) {
98
150
  this.setState({ abortState: { loading: false, result: null, error } });
@@ -100,6 +152,8 @@ export class RequestController extends FeController<RequestControllerState> {
100
152
  };
101
153
 
102
154
  stopAbortRequest = async () => {
103
- this.feApi.stop({ method: 'GET', url: 'https://api.example.com/users' });
155
+ this.userApi.stop({
156
+ requestId: 'onTriggerAbortRequest'
157
+ });
104
158
  };
105
159
  }
@@ -1,16 +1,17 @@
1
- import { I18nService } from '@/services/I18nService';
2
- import { UIDependenciesInterface } from '@/base/port/UIDependenciesInterface';
3
- import { Logger } from '@qlover/fe-utils';
4
- import { NavigateFunction, NavigateOptions } from 'react-router-dom';
5
- import { RouteConfigValue } from '@lib/router-loader/RouterLoader';
6
- import { RouteConfig } from '@/base/types/Page';
1
+ import type { RouteConfigValue } from '@/base/cases/router-loader';
2
+ import type { NavigateFunction, NavigateOptions } from 'react-router-dom';
3
+ import type { UIDependenciesInterface } from '@/base/port/UIDependenciesInterface';
4
+ import { I18nService } from '@/base/services/I18nService';
5
+ import { Logger } from '@qlover/fe-corekit';
7
6
 
8
7
  export type RouterControllerDependencies = {
9
8
  navigate: NavigateFunction;
10
9
  };
11
10
 
12
11
  export type RouterControllerOptions = {
13
- config: RouteConfig;
12
+ config: {
13
+ routes: RouteConfigValue[];
14
+ };
14
15
  logger: Logger;
15
16
  };
16
17
 
@@ -1,66 +1,58 @@
1
- import { ExecutorPlugin } from '@qlover/fe-utils';
2
- import { sleep } from '@/uikit/utils/thread';
3
- import { FeController } from '@lib/fe-react-controller';
4
- import { FeApi } from '@/base/apis/feApi';
5
- import { FeApiGetUserInfo, FeApiLogin } from '@/base/apis/feApi/FeApiType';
1
+ import { ExecutorPlugin } from '@qlover/fe-corekit';
2
+ import type {
3
+ UserApiGetUserInfoTransaction,
4
+ UserApiLoginTransaction
5
+ } from '@/base/apis/userApi/UserApiType';
6
6
  import { RouterController } from './RouterController';
7
- import { StorageTokenInterface } from '@/base/port/StorageTokenInterface';
8
-
9
- export interface UserControllerState {
10
- success: boolean;
11
- userInfo: FeApiGetUserInfo['response']['data'];
12
- }
13
-
14
- export interface UserControllerOptions {
15
- userToken: StorageTokenInterface;
16
- feApi: FeApi;
17
- routerController: RouterController;
18
- }
19
-
20
- interface LoginInterface {
21
- login(
22
- params: FeApiLogin['request']
23
- ): Promise<FeApiGetUserInfo['response']['data']>;
24
- logout(): void;
25
- }
26
-
27
- function createDefaultState(
28
- options: UserControllerOptions
29
- ): UserControllerState {
30
- const { userToken } = options;
31
- const token = userToken.getToken();
32
-
33
- return {
34
- success: !!token,
35
- userInfo: {
36
- name: '',
37
- email: '',
38
- picture: ''
39
- }
7
+ import { ThreadUtil, type StorageTokenInterface } from '@qlover/corekit-bridge';
8
+ import { inject, injectable } from 'inversify';
9
+ import { IOCIdentifier } from '@/core/IOC';
10
+ import { LoginInterface } from '@/base/port/LoginInterface';
11
+ import { UserApi } from '@/base/apis/userApi/UserApi';
12
+ import { AppError } from '@/base/cases/appError/AppError';
13
+ import { LOCAL_NO_USER_TOKEN } from '@config/ErrorIdentifier';
14
+ import { SliceStore } from '@qlover/slice-store-react';
15
+
16
+ class UserControllerState {
17
+ success: boolean = false;
18
+ userInfo: UserApiGetUserInfoTransaction['response']['data'] = {
19
+ name: '',
20
+ email: '',
21
+ picture: ''
40
22
  };
41
23
  }
42
24
 
25
+ @injectable()
43
26
  export class UserController
44
- extends FeController<UserControllerState>
27
+ extends SliceStore<UserControllerState>
45
28
  implements ExecutorPlugin, LoginInterface
46
29
  {
47
30
  readonly pluginName = 'UserController';
48
31
 
49
- constructor(private options: UserControllerOptions) {
50
- super(() => createDefaultState(options));
32
+ constructor(
33
+ @inject(UserApi) private userApi: UserApi,
34
+ @inject(RouterController) private routerController: RouterController,
35
+ @inject(IOCIdentifier.FeApiToken)
36
+ private userToken: StorageTokenInterface<string>
37
+ ) {
38
+ super(() => new UserControllerState());
39
+ }
40
+
41
+ setState(state: Partial<UserControllerState>): void {
42
+ this.emit({ ...this.state, ...state });
51
43
  }
52
44
 
53
45
  /**
54
46
  * @override
55
47
  */
56
48
  async onBefore(): Promise<void> {
57
- await sleep(1000);
49
+ await ThreadUtil.sleep(1000);
58
50
 
59
- if (!this.options.userToken.getToken()) {
60
- throw new Error('User not logged in');
51
+ if (!this.userToken.getToken()) {
52
+ throw new AppError(LOCAL_NO_USER_TOKEN);
61
53
  }
62
54
 
63
- const userInfo = await this.options.feApi.getUserInfo();
55
+ const userInfo = await this.userApi.getUserInfo();
64
56
 
65
57
  this.setState({
66
58
  success: true,
@@ -74,29 +66,31 @@ export class UserController
74
66
  async onError(): Promise<void> {
75
67
  this.logout();
76
68
 
77
- this.options.routerController.gotoLogin();
69
+ this.routerController.gotoLogin();
78
70
  }
79
71
 
80
72
  /**
81
73
  * @override
82
74
  */
83
75
  async login(
84
- params: FeApiLogin['request']
85
- ): Promise<FeApiGetUserInfo['response']['data']> {
86
- const { feApi } = this.options;
76
+ params: UserApiLoginTransaction['data']
77
+ ): Promise<UserApiGetUserInfoTransaction['response']> {
78
+ const response = await this.userApi.login(params);
87
79
 
88
- const result = await feApi.login(params);
80
+ if (response.apiCatchResult) {
81
+ throw response.apiCatchResult;
82
+ }
89
83
 
90
- this.options.userToken.setToken(result.data.token);
84
+ this.userToken.setToken(response.data.token);
91
85
 
92
- const userInfo = await feApi.getUserInfo();
86
+ const userInfo = await this.userApi.getUserInfo();
93
87
 
94
88
  this.setState({
95
89
  success: true,
96
90
  userInfo: userInfo.data
97
91
  });
98
92
 
99
- return userInfo.data;
93
+ return userInfo;
100
94
  }
101
95
 
102
96
  /**
@@ -110,7 +104,7 @@ export class UserController
110
104
  * @override
111
105
  */
112
106
  reset(): void {
113
- this.options.userToken.removeToken();
107
+ this.userToken.removeToken();
114
108
  super.reset();
115
109
  }
116
110
 
@@ -1,5 +1,4 @@
1
- import { I18nService } from '@/services/I18nService';
2
- import { I18nServiceLocale } from '@config/i18n';
1
+ import { I18nService, I18nServiceLocale } from '@/base/services/I18nService';
3
2
  import { useEffect } from 'react';
4
3
  import { useNavigate } from 'react-router-dom';
5
4
  import { useParams } from 'react-router-dom';
@@ -2,12 +2,12 @@ import { createContext, useEffect } from 'react';
2
2
  import { IOC } from '@/core/IOC';
3
3
  import { useLanguageGuard } from '@/uikit/hooks/useLanguageGuard';
4
4
  import { useStrictEffect } from '@/uikit/hooks/useStrictEffect';
5
- import { ProcesserService } from '@/services/processer/ProcesserService';
5
+ import { ProcesserService } from '@/base/services/ProcesserService';
6
6
  import { Navigate, useNavigate } from 'react-router-dom';
7
- import { useControllerState } from '@lib/fe-react-controller';
8
- import { Loading } from '@/components/Loading';
7
+ import { Loading } from '@/uikit/components/Loading';
9
8
  import { RouterController } from '../controllers/RouterController';
10
9
  import { UserController } from '../controllers/UserController';
10
+ import { useSliceStore } from '@qlover/slice-store-react';
11
11
 
12
12
  const PageProcesserContext = createContext<ProcesserService>(
13
13
  IOC(ProcesserService)
@@ -17,7 +17,7 @@ export function ProcessProvider({ children }: { children: React.ReactNode }) {
17
17
  useLanguageGuard();
18
18
  const userController = IOC(UserController);
19
19
  const pageProcesser = IOC(ProcesserService);
20
- const { success } = useControllerState(userController);
20
+ const success = useSliceStore(userController, (state) => state.success);
21
21
 
22
22
  const navigate = useNavigate();
23
23
 
@@ -1,2 +1,2 @@
1
1
  @import './tailwind.css';
2
- @import './page.css';
2
+ @import './page.css';
@@ -1,3 +1,3 @@
1
1
  html {
2
2
  @apply bg-white;
3
- }
3
+ }
@@ -1,5 +1,5 @@
1
- import root10px from './lib/tw-root10px';
2
- import themeCreate from './lib/fe-react-theme/tw-generator';
1
+ import root10px from './lib/tailwind/root10px';
2
+ import themeCreate from './lib/tailwind/theme-generator';
3
3
  import themeConfig from './config/theme.json';
4
4
 
5
5
  const theme = themeCreate(themeConfig.override);
@@ -20,7 +20,6 @@
20
20
  "types": ["vite/client"],
21
21
  "paths": {
22
22
  "@/*": ["./src/*"],
23
- "@lib/*": ["./lib/*"],
24
23
  "@config/*": ["./config/*"]
25
24
  },
26
25
  "experimentalDecorators": true
@@ -6,9 +6,8 @@
6
6
  "moduleResolution": "bundler",
7
7
  "allowSyntheticDefaultImports": true,
8
8
  "paths": {
9
- "@lib/*": ["./lib/*"],
10
9
  "@config/*": ["./config/*"]
11
10
  }
12
11
  },
13
- "include": ["vite.config.ts", "lib", "config"]
12
+ "include": ["vite.config.ts", "fe-prod", "config"]
14
13
  }
@@ -1,38 +1,33 @@
1
1
  import { defineConfig } from 'vitest/config';
2
2
  import react from '@vitejs/plugin-react';
3
- import alias from '@rollup/plugin-alias';
4
- import tsappconfig from './tsconfig.json';
5
- import { resolve } from 'path';
6
- import { Env } from '@qlover/env-loader';
7
3
  import { envPrefix } from './config/common';
8
4
  import { name, version } from './package.json';
9
- import { injectPkgConfig } from './lib/env-config/injectPkgConfig';
10
-
11
- Env.searchEnv();
12
-
13
- const tsAppPaths = tsappconfig.compilerOptions.paths || {};
14
-
15
- // add version and name to env
16
- injectPkgConfig(
17
- [
18
- ['APP_NAME', name],
19
- ['APP_VERSION', version]
20
- ],
21
- envPrefix
22
- );
23
-
24
- // convert tsconfig paths to vite alias
25
- const entries = Object.entries(tsAppPaths).reduce((acc, [key, value]) => {
26
- acc[key.replace('/*', '')] = resolve(__dirname, value[0].replace('/*', ''));
27
- return acc;
28
- }, {});
5
+ import tsconfigPaths from 'vite-tsconfig-paths';
6
+ import envConfig from '@qlover/corekit-bridge/build/vite-env-config';
7
+ import ts2Locales from '@qlover/corekit-bridge/build/vite-ts-to-locales';
8
+ import i18nConfig from './config/i18n';
29
9
 
30
10
  // https://vite.dev/config/
31
11
  export default defineConfig({
32
12
  plugins: [
13
+ envConfig({
14
+ envPops: true,
15
+ envPrefix,
16
+ records: [
17
+ ['APP_NAME', name],
18
+ ['APP_VERSION', version]
19
+ ]
20
+ }),
33
21
  react(),
34
- alias({
35
- entries
22
+ tsconfigPaths(),
23
+ ts2Locales({
24
+ locales: i18nConfig.supportedLngs as unknown as string[],
25
+ options: [
26
+ {
27
+ source: './config/ErrorIdentifier.ts',
28
+ target: './public/locales/{{lng}}/common.json'
29
+ }
30
+ ]
36
31
  })
37
32
  ],
38
33
  envPrefix: envPrefix,
@@ -1,24 +0,0 @@
1
- NODE_ENV=local
2
-
3
- # ci
4
- NPM_TOKEN=
5
- GITHUB_TOKEN=
6
-
7
- # fe-scripts
8
- FE_RELEASE_BRANCH=master
9
- FE_RELEASE=false
10
- FE_RELEASE_ENV=production
11
-
12
- # ===== build
13
- VITE_PUBLIC_PATH=
14
- VITE_SERVER_PORT=3200
15
-
16
- # ===== app config
17
- VITE_USER_TOKEN_STORAGE_KEY=fe_user_token
18
- VITE_OPEN_AI_MODELS='["gpt-4o-mini","gpt-3.5-turbo","gpt-3.5-turbo-2","gpt-4","gpt-4-32k"]'
19
- VITE_OPEN_AI_BASE_URL=https://openai-proxy.brain.loocaa.com:1443/v1/
20
- VITE_OPEN_AI_TOKEN=DlJYSkMVj1x4zoe8jZnjvxfHG6z5yGxK
21
- VITE_OPEN_AI_TOKEN_PREFIX=Bearer
22
- VITE_OPEN_AI_REQUIRE_TOKEN=true
23
- VITE_LOGIN_USER=admin
24
- VITE_LOGIN_PASSWORD=123456
@@ -1,36 +0,0 @@
1
- import type { IOCContainerInterface } from './IOCContainerInterface';
2
- import { SyncExecutor } from '@qlover/fe-utils';
3
- import { BootstrapExecutorPlugin } from './BootstrapExecutorPlugin';
4
-
5
- export class Bootstrap extends SyncExecutor {
6
- constructor(private IOCContainer: IOCContainerInterface) {
7
- super();
8
- }
9
-
10
- getIOCContainer(): IOCContainerInterface {
11
- return this.IOCContainer;
12
- }
13
-
14
- use(plugin: BootstrapExecutorPlugin | BootstrapExecutorPlugin[]): this {
15
- if (Array.isArray(plugin)) {
16
- plugin.forEach((p) => super.use(p));
17
- return this;
18
- }
19
-
20
- super.use(plugin);
21
-
22
- return this;
23
- }
24
-
25
- start(root: unknown): void {
26
- this.exec({ root, ioc: this.IOCContainer }, () => {
27
- // nothing to do
28
- });
29
- }
30
-
31
- startNoError(root: unknown): void {
32
- this.execNoError({ root, ioc: this.IOCContainer }, () => {
33
- // nothing to do
34
- });
35
- }
36
- }
@@ -1,20 +0,0 @@
1
- import { IOCContainerInterface } from './IOCContainerInterface';
2
- import { ExecutorContext, ExecutorPlugin } from '@qlover/fe-utils';
3
-
4
- export type BootstrapArgs = {
5
- /**
6
- * starup global object
7
- *
8
- * maybe window or globalThis
9
- */
10
- root: unknown;
11
- /**
12
- * IOC container
13
- */
14
- ioc: IOCContainerInterface;
15
- };
16
-
17
- export interface BootstrapExecutorPlugin
18
- extends ExecutorPlugin<BootstrapArgs> {}
19
-
20
- export type BootstrapContext = ExecutorContext<BootstrapArgs>;
@@ -1,33 +0,0 @@
1
- /**
2
- * IOC container
3
- *
4
- */
5
- export interface IOCContainerInterface {
6
- /**
7
- * configure IOC container
8
- *
9
- * eg. may need to manually bind implementation classes
10
- */
11
- configure(): void;
12
- configure<Container>(registers?: IOCRegisterInterface<Container>[]): void;
13
-
14
- /**
15
- * bind instance
16
- *
17
- * @param serviceIdentifier
18
- * @param value
19
- */
20
- bind<T>(serviceIdentifier: unknown, value: T): void;
21
-
22
- /**
23
- * get instance
24
- *
25
- * @param serviceIdentifier
26
- * @returns
27
- */
28
- get<T>(serviceIdentifier: unknown): T;
29
- }
30
-
31
- export interface IOCRegisterInterface<T> {
32
- register(container: T, thisArg: IOCContainerInterface): void;
33
- }
@@ -1,12 +0,0 @@
1
- import type { IOCContainerInterface } from './IOCContainerInterface';
2
-
3
- export interface IOCManagerInterface {
4
- get<T>(identifier: unknown): T;
5
-
6
- /**
7
- * implement IOC container
8
- */
9
- implement(container: IOCContainerInterface): void;
10
-
11
- get implemention(): IOCContainerInterface | null;
12
- }
@@ -1,7 +0,0 @@
1
- export * from './Bootstrap';
2
- export * from './BootstrapExecutorPlugin';
3
- export * from './plugins/InjectIOC';
4
- export * from './plugins/InjectEnv';
5
- export * from './plugins/InjectGlobal';
6
- export * from './IOCContainerInterface';
7
- export * from './IOCManagerInterface';
@@ -1,61 +0,0 @@
1
- import type { BootstrapExecutorPlugin } from '../BootstrapExecutorPlugin';
2
-
3
- export interface EnvConfigInterface {
4
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
- [key: string]: any;
6
- }
7
-
8
- export class InjectEnv implements BootstrapExecutorPlugin {
9
- readonly pluginName = 'InjectEnv';
10
-
11
- constructor(
12
- private target: EnvConfigInterface,
13
- private source: Record<string, unknown>,
14
- private envPrefix: string = '',
15
- private envWhiteList: string[] = ['env', 'userNodeEnv']
16
- ) {}
17
-
18
- static isJSONString(value: string): boolean {
19
- return (
20
- typeof value === 'string' &&
21
- value !== '' &&
22
- (value === 'true' ||
23
- value === 'false' ||
24
- value.startsWith('{') ||
25
- value.startsWith('['))
26
- );
27
- }
28
-
29
- env<D>(key: string, defaultValue?: D): D {
30
- // transform key to env key
31
- const formattedKey = key.replace(/([a-z])([A-Z])/g, '$1_$2').toUpperCase();
32
-
33
- const envKey = `${this.envPrefix}${formattedKey}`;
34
- const value = this.source[envKey];
35
- // if it is a json string, parse it
36
- if (typeof value === 'string' && InjectEnv.isJSONString(value)) {
37
- return JSON.parse(value);
38
- }
39
-
40
- return (value ?? defaultValue) as D;
41
- }
42
-
43
- inject(config: EnvConfigInterface): void {
44
- for (const key in config) {
45
- if (this.envWhiteList.includes(key)) {
46
- continue;
47
- }
48
-
49
- const value = config[key as keyof typeof config];
50
-
51
- config[key as keyof typeof config] = this.env(key, value);
52
- }
53
- }
54
-
55
- onBefore(): void {
56
- this.inject(this.target);
57
-
58
- // transform readonly to writable
59
- Object.freeze(this.target);
60
- }
61
- }