@qlover/create-app 0.1.11 → 0.1.14

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 (67) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/bin/create-app.js +0 -0
  3. package/dist/index.cjs +3631 -0
  4. package/dist/{cjs/index.d.ts → index.d.ts} +3 -2
  5. package/dist/index.js +3625 -0
  6. package/package.json +17 -16
  7. package/templates/node-lib/bin/test.js +1 -1
  8. package/templates/node-lib/package.json +2 -2
  9. package/templates/node-lib/rollup.config.js +1 -2
  10. package/templates/pack-app/package.json +1 -1
  11. package/templates/react-app/.env +23 -2
  12. package/templates/react-app/.env.local +24 -0
  13. package/templates/react-app/config/common.ts +3 -0
  14. package/templates/react-app/lib/bootstrap/Bootstrap.ts +36 -0
  15. package/templates/react-app/lib/bootstrap/BootstrapExecutorPlugin.ts +20 -0
  16. package/templates/react-app/lib/bootstrap/IOCContainerInterface.ts +33 -0
  17. package/templates/react-app/lib/bootstrap/IOCManagerInterface.ts +12 -0
  18. package/templates/react-app/lib/bootstrap/index.ts +7 -0
  19. package/templates/react-app/lib/bootstrap/plugins/InjectEnv.ts +61 -0
  20. package/templates/react-app/lib/bootstrap/plugins/InjectGlobal.ts +36 -0
  21. package/templates/react-app/lib/bootstrap/plugins/InjectIOC.ts +24 -0
  22. package/templates/react-app/lib/env-config/injectPkgConfig.ts +11 -0
  23. package/templates/react-app/lib/openAiApi/OpenAIClient.ts +1 -1
  24. package/templates/react-app/lib/router-loader/Page.ts +8 -4
  25. package/templates/react-app/lib/router-loader/RouterLoader.ts +1 -1
  26. package/templates/react-app/package.json +3 -1
  27. package/templates/react-app/pnpm-lock.yaml +5892 -0
  28. package/templates/react-app/src/base/consts/IOCIdentifier.ts +16 -0
  29. package/templates/react-app/src/base/port/IOCFunctionInterface.ts +39 -0
  30. package/templates/react-app/src/base/port/InversifyIocInterface.ts +9 -0
  31. package/templates/react-app/src/base/port/StorageTokenInterface.ts +22 -0
  32. package/templates/react-app/src/base/types/Page.ts +4 -13
  33. package/templates/react-app/src/base/types/global.d.ts +2 -1
  34. package/templates/react-app/src/components/ThemeSwitcher.tsx +1 -1
  35. package/templates/react-app/src/core/AppConfig.ts +27 -0
  36. package/templates/react-app/src/core/AppIOCContainer.ts +30 -0
  37. package/templates/react-app/src/core/IOC.ts +48 -0
  38. package/templates/react-app/src/core/bootstrap.ts +59 -14
  39. package/templates/react-app/src/core/globals.ts +1 -1
  40. package/templates/react-app/src/core/registers/RegisterApi.ts +59 -0
  41. package/templates/react-app/src/core/registers/RegisterCommon.ts +21 -0
  42. package/templates/react-app/src/core/{feIOC → registers}/RegisterControllers.ts +16 -11
  43. package/templates/react-app/src/core/registers/RegisterGlobals.ts +20 -0
  44. package/templates/react-app/src/core/registers/index.ts +17 -0
  45. package/templates/react-app/src/main.tsx +4 -3
  46. package/templates/react-app/src/pages/auth/Layout.tsx +1 -1
  47. package/templates/react-app/src/pages/auth/Login.tsx +4 -4
  48. package/templates/react-app/src/pages/base/Executor.tsx +1 -1
  49. package/templates/react-app/src/pages/base/JSONStorage.tsx +1 -1
  50. package/templates/react-app/src/pages/base/Request.tsx +1 -1
  51. package/templates/react-app/src/services/I18nService.ts +18 -14
  52. package/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +7 -1
  53. package/templates/react-app/src/uikit/providers/ProcessProvider.tsx +1 -1
  54. package/templates/react-app/src/uikit/utils/RequestLogger.ts +4 -1
  55. package/templates/react-app/tsconfig.json +2 -1
  56. package/templates/react-app/tsconfig.node.json +6 -2
  57. package/templates/react-app/vite.config.ts +14 -0
  58. package/configs/_common/.release-it.json.template +0 -42
  59. package/dist/cjs/index.js +0 -1
  60. package/dist/es/index.d.ts +0 -112
  61. package/dist/es/index.js +0 -1
  62. package/templates/react-app/config/app.common.ts +0 -52
  63. package/templates/react-app/src/base/port/IOCInterface.ts +0 -53
  64. package/templates/react-app/src/core/feIOC/FeIOC.ts +0 -32
  65. package/templates/react-app/src/core/feIOC/RegisterApi.ts +0 -41
  66. package/templates/react-app/src/core/feIOC/RegisterCommon.ts +0 -20
  67. package/templates/react-app/src/core/index.ts +0 -31
package/package.json CHANGED
@@ -1,20 +1,18 @@
1
1
  {
2
2
  "name": "@qlover/create-app",
3
- "version": "0.1.11",
3
+ "version": "0.1.14",
4
4
  "type": "module",
5
5
  "private": false,
6
- "main": "./dist/es/index.js",
7
- "module": "./dist/es/index.js",
8
- "types": "./dist/es/index.d.ts",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
9
  "exports": {
10
+ "./package.json": "./package.json",
10
11
  ".": {
11
- "import": "./dist/es/index.js",
12
- "require": "./dist/cjs/index.js",
13
- "types": "./dist/es/index.d.ts"
14
- },
15
- "./cjs/*": "./dist/cjs/*",
16
- "./es/*": "./dist/es/*",
17
- "./package.json": "./package.json"
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs"
15
+ }
18
16
  },
19
17
  "files": [
20
18
  "dist",
@@ -26,11 +24,10 @@
26
24
  "CHANGELOG.md"
27
25
  ],
28
26
  "bin": {
29
- "create-app": "./bin/create-app.js"
27
+ "create-app": "bin/create-app.js"
30
28
  },
31
29
  "scripts": {
32
30
  "build": "rollup -c",
33
- "test": "jest",
34
31
  "create:app:build": "npm run build && npm run create:app",
35
32
  "create:app": "node ./bin/create-app.js"
36
33
  },
@@ -50,12 +47,16 @@
50
47
  "publishConfig": {
51
48
  "access": "public"
52
49
  },
50
+ "devDependencies": {
51
+ "@qlover/env-loader": "^0.0.1"
52
+ },
53
53
  "dependencies": {
54
- "@qlover/fe-utils": "latest",
55
- "@qlover/scripts-context": "latest",
54
+ "@qlover/fe-corekit": "^1.2.2",
55
+ "@qlover/scripts-context": "^0.0.8",
56
56
  "commander": "^13.1.0",
57
57
  "ignore": "^7.0.3",
58
58
  "inquirer": "^12.3.2",
59
- "ora": "^8.1.1"
59
+ "ora": "^8.1.1",
60
+ "lodash": "^4.17.21"
60
61
  }
61
62
  }
@@ -10,7 +10,7 @@ function programArgs() {
10
10
  'Do not touch or write anything, but show the commands'
11
11
  )
12
12
  .option('-V, --verbose', 'Show more information')
13
- .option('-n, --name <name>', 'The name of the test')
13
+ .option('-n, --name <name>', 'The name of the test');
14
14
  // parse arguments
15
15
  program.parse();
16
16
 
@@ -46,8 +46,8 @@
46
46
  "run:command": "node bin/test.js"
47
47
  },
48
48
  "devDependencies": {
49
- "@qlover/env-loader": "latest",
50
- "@qlover/fe-standard": "latest",
49
+ "@qlover/env-loader": "workspace:*",
50
+ "@qlover/fe-standard": "workspace:*",
51
51
  "@qlover/scripts-context": "latest",
52
52
  "@release-it/conventional-changelog": "^8.0.1",
53
53
  "@rollup/plugin-commonjs": "^28.0.1",
@@ -9,7 +9,7 @@ import { readFileSync, rmSync } from 'fs';
9
9
  import { Env } from '@qlover/env-loader';
10
10
 
11
11
  const pkg = JSON.parse(readFileSync('./package.json'), 'utf-8');
12
- const env = Env.searchEnv({ logger: console });
12
+ const env = Env.searchEnv();
13
13
  const isProduction = env.get('NODE_ENV') === 'production';
14
14
  const buildDir = 'dist';
15
15
 
@@ -44,7 +44,6 @@ function createPlugin(minify) {
44
44
 
45
45
  function cleanBuildDir() {
46
46
  rmSync(buildDir, { recursive: true, force: true });
47
- console.log(`${buildDir} cleaned`);
48
47
  }
49
48
 
50
49
  cleanBuildDir();
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "devDependencies": {
33
33
  "@qlover/fe-scripts": "latest",
34
- "@qlover/fe-standard": "latest",
34
+ "@qlover/fe-standard": "workspace:*",
35
35
  "@qlover/fe-utils": "latest",
36
36
  "@qlover/fe-release": "latest",
37
37
  "@rollup/plugin-commonjs": "^28.0.1",
@@ -1,3 +1,24 @@
1
+ NODE_ENV=production
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=
1
14
  VITE_SERVER_PORT=3200
2
- VITE_OPENAI_API_URL=
3
- VITE_OPENAI_API_KEY=
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://api.openai.com/v1
20
+ VITE_OPEN_AI_TOKEN=sk-proj-1234567890
21
+ VITE_OPEN_AI_TOKEN_PREFIX=Bearer
22
+ VITE_OPEN_AI_REQUIRE_TOKEN=true
23
+ VITE_LOGIN_USER=admin
24
+ VITE_LOGIN_PASSWORD=123456
@@ -0,0 +1,24 @@
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
@@ -0,0 +1,3 @@
1
+ export const envPrefix = 'VITE_';
2
+
3
+ export const browserGlobalsName = 'feGlobals';
@@ -0,0 +1,36 @@
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
+ }
@@ -0,0 +1,20 @@
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>;
@@ -0,0 +1,33 @@
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
+ }
@@ -0,0 +1,12 @@
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
+ }
@@ -0,0 +1,7 @@
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';
@@ -0,0 +1,61 @@
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
+ }
@@ -0,0 +1,36 @@
1
+ import type { ExecutorContext } from '@qlover/fe-utils';
2
+ import type {
3
+ BootstrapArgs,
4
+ BootstrapExecutorPlugin
5
+ } from '../BootstrapExecutorPlugin';
6
+
7
+ export class InjectGlobal implements BootstrapExecutorPlugin {
8
+ readonly pluginName = 'InjectGlobal';
9
+
10
+ constructor(
11
+ private sources: Record<string, unknown>,
12
+ private target?: string | Record<string, unknown>
13
+ ) {}
14
+
15
+ onBefore(context: ExecutorContext<BootstrapArgs>): void {
16
+ // if target is provided, inject globals to target
17
+ if (typeof this.target === 'string') {
18
+ Object.assign(context.parameters.root!, {
19
+ [this.target]: Object.freeze(Object.assign({}, this.sources))
20
+ });
21
+ return;
22
+ }
23
+
24
+ const target = this.target || context.parameters.root;
25
+
26
+ if (typeof target !== 'object' || target === null) {
27
+ throw new Error('target must be an object');
28
+ }
29
+
30
+ // inject globals to root
31
+ for (const key in this.sources) {
32
+ const element = this.sources[key];
33
+ Object.assign(target, { [key]: element });
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,24 @@
1
+ import type { IOCRegisterInterface } from '../IOCContainerInterface';
2
+ import type { IOCManagerInterface } from '../IOCManagerInterface';
3
+ import type {
4
+ BootstrapContext,
5
+ BootstrapExecutorPlugin
6
+ } from '../BootstrapExecutorPlugin';
7
+ import { Container } from 'inversify';
8
+
9
+ export class InjectIOC implements BootstrapExecutorPlugin {
10
+ readonly pluginName = 'InjectIOC';
11
+
12
+ constructor(
13
+ private IOC: IOCManagerInterface,
14
+ private registeres: IOCRegisterInterface<Container>[]
15
+ ) {}
16
+
17
+ onBefore(context: BootstrapContext): void {
18
+ const { ioc } = context.parameters;
19
+ this.IOC.implement(ioc);
20
+
21
+ // maybe runtimes configure
22
+ ioc.configure(this.registeres);
23
+ }
24
+ }
@@ -0,0 +1,11 @@
1
+ export function injectPkgConfig(
2
+ options: [string, string][],
3
+ envPrefix: string = ''
4
+ ) {
5
+ options.forEach(([key, value]) => {
6
+ const envKey = `${envPrefix}${key}`;
7
+ if (!process.env[envKey]) {
8
+ process.env[envKey] = value;
9
+ }
10
+ });
11
+ }
@@ -25,7 +25,7 @@ export interface OpenAIChatParmas {
25
25
 
26
26
  export type OpenAIAargs = {
27
27
  commonPluginConfig: RequestCommonPluginConfig;
28
- models: readonly string[];
28
+ models: string[];
29
29
  };
30
30
 
31
31
  export type OpenAIClientConfig = Partial<RequestAdapterFetchConfig> &
@@ -48,15 +48,19 @@ export type LoadProps = {
48
48
  Provider?: React.ComponentType<PropsWithChildren<RouteMeta>>;
49
49
  };
50
50
 
51
-
52
- type ComponentValue = React.ComponentType<unknown> | LazyExoticComponent<React.ComponentType<unknown>>;
51
+ type ComponentValue =
52
+ | React.ComponentType<unknown>
53
+ | LazyExoticComponent<React.ComponentType<unknown>>;
53
54
 
54
55
  export type ComponentMaps = {
55
56
  /**
56
57
  * key: ./xxx/bbb.(jsx,js,tsx,ts)
57
58
  */
58
- [key: string]: ComponentValue | (() => Promise<ComponentValue>) | (() => ComponentValue);
59
- }
59
+ [key: string]:
60
+ | ComponentValue
61
+ | (() => Promise<ComponentValue>)
62
+ | (() => ComponentValue);
63
+ };
60
64
 
61
65
  // new RouterManager({
62
66
  // routes: [],
@@ -11,7 +11,7 @@ type RouteComponentType<T = unknown> =
11
11
  export type RouteConfigValue = Omit<RouteObject, 'element' | 'children'> & {
12
12
  /**
13
13
  * 路径
14
- *
14
+ *
15
15
  * FIXME: support `ReactNode`
16
16
  */
17
17
  element?: string;
@@ -56,11 +56,13 @@
56
56
  "i18next": "^24.2.0",
57
57
  "i18next-browser-languagedetector": "^8.0.2",
58
58
  "i18next-http-backend": "^3.0.1",
59
+ "inversify": "^7.1.0",
59
60
  "lodash": "^4.17.21",
60
61
  "react": "^18.3.1",
61
62
  "react-dom": "^18.3.1",
62
63
  "react-i18next": "^15.2.0",
63
- "react-router-dom": "^7.1.5"
64
+ "react-router-dom": "^7.1.5",
65
+ "reflect-metadata": "^0.2.2"
64
66
  },
65
67
  "devDependencies": {
66
68
  "@eslint/js": "^9.11.1",