@qlover/create-app 0.0.1
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 +10 -0
- package/bin/create-app.js +28 -0
- package/dist/cjs/index.d.ts +67 -0
- package/dist/cjs/index.js +1 -0
- package/dist/es/index.d.ts +67 -0
- package/dist/es/index.js +1 -0
- package/package.json +60 -0
- package/templates/fe-react/.env +3 -0
- package/templates/fe-react/README.md +50 -0
- package/templates/fe-react/config/app.common.ts +52 -0
- package/templates/fe-react/config/app.router.json +150 -0
- package/templates/fe-react/config/feapi.mock.json +14 -0
- package/templates/fe-react/config/i18n.ts +21 -0
- package/templates/fe-react/config/theme.json +90 -0
- package/templates/fe-react/eslint.config.js +31 -0
- package/templates/fe-react/index.html +13 -0
- package/templates/fe-react/lib/fe-react-controller/FeController.ts +15 -0
- package/templates/fe-react/lib/fe-react-controller/index.ts +2 -0
- package/templates/fe-react/lib/fe-react-controller/useController.ts +71 -0
- package/templates/fe-react/lib/fe-react-theme/ThemeController.ts +40 -0
- package/templates/fe-react/lib/fe-react-theme/ThemeStateGetter.ts +53 -0
- package/templates/fe-react/lib/fe-react-theme/index.ts +3 -0
- package/templates/fe-react/lib/fe-react-theme/tw-generator.js +239 -0
- package/templates/fe-react/lib/fe-react-theme/type.ts +21 -0
- package/templates/fe-react/lib/openAiApi/OpenAIAuthPlugin.ts +29 -0
- package/templates/fe-react/lib/openAiApi/OpenAIClient.ts +51 -0
- package/templates/fe-react/lib/openAiApi/StreamProcessor.ts +81 -0
- package/templates/fe-react/lib/openAiApi/index.ts +3 -0
- package/templates/fe-react/lib/request-common-plugin/index.ts +169 -0
- package/templates/fe-react/lib/tw-root10px/index.css +4 -0
- package/templates/fe-react/lib/tw-root10px/index.js +178 -0
- package/templates/fe-react/package.json +49 -0
- package/templates/fe-react/postcss.config.js +6 -0
- package/templates/fe-react/public/locales/en/about.json +3 -0
- package/templates/fe-react/public/locales/en/common.json +6 -0
- package/templates/fe-react/public/locales/en/executor.json +6 -0
- package/templates/fe-react/public/locales/en/home.json +10 -0
- package/templates/fe-react/public/locales/en/jsonStorage.json +11 -0
- package/templates/fe-react/public/locales/en/login.json +7 -0
- package/templates/fe-react/public/locales/en/request.json +15 -0
- package/templates/fe-react/public/locales/zh/about.json +3 -0
- package/templates/fe-react/public/locales/zh/common.json +7 -0
- package/templates/fe-react/public/locales/zh/executor.json +7 -0
- package/templates/fe-react/public/locales/zh/home.json +10 -0
- package/templates/fe-react/public/locales/zh/jsonStorage.json +11 -0
- package/templates/fe-react/public/locales/zh/login.json +8 -0
- package/templates/fe-react/public/locales/zh/request.json +15 -0
- package/templates/fe-react/public/logo.svg +1 -0
- package/templates/fe-react/src/App.tsx +20 -0
- package/templates/fe-react/src/assets/react.svg +1 -0
- package/templates/fe-react/src/components/Loading.tsx +41 -0
- package/templates/fe-react/src/components/LocaleLink.tsx +42 -0
- package/templates/fe-react/src/components/ProcessProvider.tsx +41 -0
- package/templates/fe-react/src/components/ThemeSwitcher.tsx +29 -0
- package/templates/fe-react/src/containers/context/BaseRouteContext.ts +27 -0
- package/templates/fe-react/src/containers/context/BaseRouteProvider.tsx +11 -0
- package/templates/fe-react/src/containers/globals.ts +31 -0
- package/templates/fe-react/src/containers/index.ts +71 -0
- package/templates/fe-react/src/hooks/useLanguageGuard.ts +25 -0
- package/templates/fe-react/src/hooks/useStrictEffect.ts +29 -0
- package/templates/fe-react/src/main.tsx +15 -0
- package/templates/fe-react/src/pages/404.tsx +14 -0
- package/templates/fe-react/src/pages/500.tsx +14 -0
- package/templates/fe-react/src/pages/auth/Layout.tsx +14 -0
- package/templates/fe-react/src/pages/auth/Login.tsx +62 -0
- package/templates/fe-react/src/pages/auth/Register.tsx +3 -0
- package/templates/fe-react/src/pages/base/About.tsx +12 -0
- package/templates/fe-react/src/pages/base/Executor.tsx +38 -0
- package/templates/fe-react/src/pages/base/Home.tsx +78 -0
- package/templates/fe-react/src/pages/base/JSONStorage.tsx +124 -0
- package/templates/fe-react/src/pages/base/Layout.tsx +17 -0
- package/templates/fe-react/src/pages/base/RedirectPathname.tsx +15 -0
- package/templates/fe-react/src/pages/base/Request.tsx +91 -0
- package/templates/fe-react/src/pages/base/components/BaseHeader.tsx +19 -0
- package/templates/fe-react/src/pages/index.tsx +108 -0
- package/templates/fe-react/src/services/controllers/ExecutorController.ts +56 -0
- package/templates/fe-react/src/services/controllers/JSONStorageController.ts +42 -0
- package/templates/fe-react/src/services/controllers/RequestController.ts +105 -0
- package/templates/fe-react/src/services/controllers/RouterController.ts +90 -0
- package/templates/fe-react/src/services/controllers/UserController.ts +146 -0
- package/templates/fe-react/src/services/feApi/FeApi.ts +51 -0
- package/templates/fe-react/src/services/feApi/FeApiMockPlugin.ts +42 -0
- package/templates/fe-react/src/services/feApi/FeApiType.ts +55 -0
- package/templates/fe-react/src/services/feApi/index.ts +2 -0
- package/templates/fe-react/src/services/i18n/index.ts +50 -0
- package/templates/fe-react/src/services/pageProcesser/PageProcesser.ts +29 -0
- package/templates/fe-react/src/services/pageProcesser/index.ts +1 -0
- package/templates/fe-react/src/styles/css/index.css +2 -0
- package/templates/fe-react/src/styles/css/page.css +3 -0
- package/templates/fe-react/src/styles/css/tailwind.css +3 -0
- package/templates/fe-react/src/types/Page.ts +49 -0
- package/templates/fe-react/src/types/UIDependenciesInterface.ts +31 -0
- package/templates/fe-react/src/types/global.d.ts +7 -0
- package/templates/fe-react/src/utils/RequestLogger.ts +34 -0
- package/templates/fe-react/src/utils/datetime.ts +25 -0
- package/templates/fe-react/src/utils/thread.ts +3 -0
- package/templates/fe-react/src/vite-env.d.ts +1 -0
- package/templates/fe-react/tailwind.config.js +18 -0
- package/templates/fe-react/tsconfig.app.json +29 -0
- package/templates/fe-react/tsconfig.json +7 -0
- package/templates/fe-react/tsconfig.node.json +22 -0
- package/templates/fe-react/vite.config.ts +32 -0
- package/templates/pack-app/.editorconfig +23 -0
- package/templates/pack-app/.env +5 -0
- package/templates/pack-app/.env.template +6 -0
- package/templates/pack-app/.gitattributes +2 -0
- package/templates/pack-app/.github/workflows/general-check.yml +50 -0
- package/templates/pack-app/.github/workflows/release.yml.template +110 -0
- package/templates/pack-app/.prettierignore +5 -0
- package/templates/pack-app/.prettierrc.js +3 -0
- package/templates/pack-app/CHANGELOG.md +0 -0
- package/templates/pack-app/README.md +1 -0
- package/templates/pack-app/eslint.config.js +77 -0
- package/templates/pack-app/fe-config.json +10 -0
- package/templates/pack-app/jest.config.js +31 -0
- package/templates/pack-app/package.json +66 -0
- package/templates/pack-app/packages/browser/__tests__/calc.test.ts +9 -0
- package/templates/pack-app/packages/browser/package.json +11 -0
- package/templates/pack-app/packages/browser/rollup.config.js +70 -0
- package/templates/pack-app/packages/browser/src/calc.ts +3 -0
- package/templates/pack-app/packages/browser/src/index.ts +1 -0
- package/templates/pack-app/packages/browser/tsconfig.json +15 -0
- package/templates/pack-app/packages/node/__tests__/readJson.test.ts +25 -0
- package/templates/pack-app/packages/node/package.json +11 -0
- package/templates/pack-app/packages/node/rollup.config.js +89 -0
- package/templates/pack-app/packages/node/src/index.ts +7 -0
- package/templates/pack-app/packages/node/src/readJson.ts +6 -0
- package/templates/pack-app/packages/node/tsconfig.json +17 -0
- package/templates/pack-app/packages/react-vite-lib/README.md +50 -0
- package/templates/pack-app/packages/react-vite-lib/__tests__/Sum.test.ts +9 -0
- package/templates/pack-app/packages/react-vite-lib/__tests__/Text.test.tsx +11 -0
- package/templates/pack-app/packages/react-vite-lib/eslint.config.js +28 -0
- package/templates/pack-app/packages/react-vite-lib/index.html +13 -0
- package/templates/pack-app/packages/react-vite-lib/package.json +30 -0
- package/templates/pack-app/packages/react-vite-lib/public/vite.svg +1 -0
- package/templates/pack-app/packages/react-vite-lib/src/calc.ts +3 -0
- package/templates/pack-app/packages/react-vite-lib/src/commponents/Text.tsx +7 -0
- package/templates/pack-app/packages/react-vite-lib/src/index.ts +2 -0
- package/templates/pack-app/packages/react-vite-lib/src/vite-env.d.ts +1 -0
- package/templates/pack-app/packages/react-vite-lib/tsconfig.json +25 -0
- package/templates/pack-app/packages/react-vite-lib/vite.config.ts +24 -0
- package/templates/pack-app/pnpm-workspace.yaml +2 -0
- package/templates/pack-app/tsconfig.json +9 -0
- package/templates/pack-app/tsconfig.test.json +10 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { dirname, join } from 'path';
|
|
5
|
+
import { Generator } from '../dist/es/index.js';
|
|
6
|
+
import { existsSync } from 'fs';
|
|
7
|
+
|
|
8
|
+
async function main() {
|
|
9
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const templatePath = join(__dirname, '../templates');
|
|
11
|
+
|
|
12
|
+
const options = {
|
|
13
|
+
options: {
|
|
14
|
+
templatePath
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
if (!existsSync(templatePath)) {
|
|
19
|
+
console.error('Template is empty!');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const generator = new Generator(options);
|
|
24
|
+
|
|
25
|
+
await generator.generate();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
main();
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { FeScriptContext } from '@qlover/fe-scripts';
|
|
2
|
+
import { Logger } from '@qlover/fe-utils';
|
|
3
|
+
import { DistinctQuestion } from 'inquirer';
|
|
4
|
+
import ignore from 'ignore';
|
|
5
|
+
|
|
6
|
+
type GeneratorOptions = {
|
|
7
|
+
prompts?: DistinctQuestion[];
|
|
8
|
+
templatePath: string;
|
|
9
|
+
};
|
|
10
|
+
interface GeneratorResult {
|
|
11
|
+
name: string;
|
|
12
|
+
templateName: string;
|
|
13
|
+
}
|
|
14
|
+
type TaskOptions = {
|
|
15
|
+
templateFiles: TemplateFile[];
|
|
16
|
+
result: GeneratorResult;
|
|
17
|
+
};
|
|
18
|
+
type TemplateFile = {
|
|
19
|
+
path: string;
|
|
20
|
+
content: string;
|
|
21
|
+
};
|
|
22
|
+
declare class Generator {
|
|
23
|
+
private prompts;
|
|
24
|
+
private ora;
|
|
25
|
+
protected context: FeScriptContext<GeneratorOptions>;
|
|
26
|
+
constructor(context: Partial<FeScriptContext<GeneratorOptions>>);
|
|
27
|
+
get logger(): Logger;
|
|
28
|
+
steps(prompts: DistinctQuestion[]): Promise<GeneratorResult>;
|
|
29
|
+
getTemplateFiles(path: string): Promise<TemplateFile[]>;
|
|
30
|
+
action({ label, task }: {
|
|
31
|
+
label: string;
|
|
32
|
+
task: () => Promise<unknown>;
|
|
33
|
+
}): Promise<unknown>;
|
|
34
|
+
/**
|
|
35
|
+
* Creates files and directories based on the provided template files.
|
|
36
|
+
*
|
|
37
|
+
* This method iterates through the template files and writes their content
|
|
38
|
+
* to the file system. It handles both files and directories, ensuring that
|
|
39
|
+
* the directory structure is preserved.
|
|
40
|
+
*
|
|
41
|
+
* @param templateFiles - An array of template files to be created.
|
|
42
|
+
* @param result - The result object containing the name and template name.
|
|
43
|
+
*
|
|
44
|
+
* @returns A promise that resolves when all files have been created.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* const templateFiles = [{ type: 'file', name: 'example.txt', content: 'Hello World' }];
|
|
48
|
+
* await taskCreate({ templateFiles, result });
|
|
49
|
+
*/
|
|
50
|
+
create(targetPath: string, name: string): Promise<void>;
|
|
51
|
+
generate(): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
declare const validRequiredString: (value: string, key: string) => string | true;
|
|
55
|
+
|
|
56
|
+
declare class Copyer {
|
|
57
|
+
getIg(targetDir: string): ignore.Ignore;
|
|
58
|
+
/**
|
|
59
|
+
* copy templates recursively
|
|
60
|
+
* @param {string} templatesDir - source directory
|
|
61
|
+
* @param {string} targetDir - target directory
|
|
62
|
+
* @param {ignore.Ignore} ig - ignore rules
|
|
63
|
+
*/
|
|
64
|
+
copyTemplates(templatesDir: string, targetDir: string, ig: ignore.Ignore): void;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export { Copyer, Generator, type GeneratorOptions, type GeneratorResult, type TaskOptions, type TemplateFile, validRequiredString };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var t=require("@qlover/fe-scripts"),e=require("inquirer"),r=require("path"),o=require("ora"),i=require("fs"),n=require("ignore");function s(t,e,r,o){return new(r||(r=Promise))((function(i,n){function s(t){try{c(o.next(t))}catch(t){n(t)}}function a(t){try{c(o.throw(t))}catch(t){n(t)}}function c(t){var e;t.done?i(t.value):(e=t.value,e instanceof r?e:new r((function(t){t(e)}))).then(s,a)}c((o=o.apply(t,e||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const a=(t,e)=>"string"==typeof t&&""!==t.trim()||`${e} is required`,c=[{type:"input",name:"name",message:"Project name",validate:t=>a(t,"Project name")},{type:"list",name:"templateName",message:"Template name",choices:["fe-react","pack-app"]}];class p{getIg(t){const e=r.join(t,".gitignore"),o=i.readFileSync(e,"utf8").split("\n").map((t=>t.trim())).filter((t=>t&&!t.startsWith("#")));return n().add(o)}copyTemplates(t,e,o){const n=i.readdirSync(t);for(const s of n){const n=r.join(t,s),a=r.join(e,s);if(o.ignores(s))continue;const c=r.dirname(a);i.existsSync(c)||i.mkdirSync(c,{recursive:!0}),i.statSync(n).isDirectory()?this.copyTemplates(n,a,o):i.copyFileSync(n,a)}}}exports.Copyer=p,exports.Generator=class{constructor(e){var r,n;this.prompts=[];const s=null===(r=e.options)||void 0===r?void 0:r.templatePath;if(!s)throw new Error("template path not exit");if(!i.existsSync(s))throw new Error("template path not exit");this.ora=o.oraPromise,this.context=new t.FeScriptContext(e),this.prompts=(null===(n=e.options)||void 0===n?void 0:n.prompts)||c}get logger(){return this.context.logger}steps(t){return s(this,void 0,void 0,(function*(){try{return yield e.prompt(t)}catch(t){throw this.logger.error(t),t}}))}getTemplateFiles(t){return s(this,void 0,void 0,(function*(){return console.log("jj paths",t),[]}))}action(t){return s(this,arguments,void 0,(function*({label:t,task:e}){let r=e();r instanceof Promise||(r=Promise.resolve(r));const o=t;return this.ora(r,o),r}))}create(t,e){return s(this,void 0,void 0,(function*(){const r=new p;r.copyTemplates(t,e,r.getIg(t))}))}generate(){return s(this,void 0,void 0,(function*(){const{templatePath:t}=this.context.options,e=yield this.steps(this.prompts);this.logger.info(e);const o=r.join(t,e.templateName);yield this.action({label:"Creating project",task:()=>this.create(o,e.name)})}))}},exports.validRequiredString=a;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { FeScriptContext } from '@qlover/fe-scripts';
|
|
2
|
+
import { Logger } from '@qlover/fe-utils';
|
|
3
|
+
import { DistinctQuestion } from 'inquirer';
|
|
4
|
+
import ignore from 'ignore';
|
|
5
|
+
|
|
6
|
+
type GeneratorOptions = {
|
|
7
|
+
prompts?: DistinctQuestion[];
|
|
8
|
+
templatePath: string;
|
|
9
|
+
};
|
|
10
|
+
interface GeneratorResult {
|
|
11
|
+
name: string;
|
|
12
|
+
templateName: string;
|
|
13
|
+
}
|
|
14
|
+
type TaskOptions = {
|
|
15
|
+
templateFiles: TemplateFile[];
|
|
16
|
+
result: GeneratorResult;
|
|
17
|
+
};
|
|
18
|
+
type TemplateFile = {
|
|
19
|
+
path: string;
|
|
20
|
+
content: string;
|
|
21
|
+
};
|
|
22
|
+
declare class Generator {
|
|
23
|
+
private prompts;
|
|
24
|
+
private ora;
|
|
25
|
+
protected context: FeScriptContext<GeneratorOptions>;
|
|
26
|
+
constructor(context: Partial<FeScriptContext<GeneratorOptions>>);
|
|
27
|
+
get logger(): Logger;
|
|
28
|
+
steps(prompts: DistinctQuestion[]): Promise<GeneratorResult>;
|
|
29
|
+
getTemplateFiles(path: string): Promise<TemplateFile[]>;
|
|
30
|
+
action({ label, task }: {
|
|
31
|
+
label: string;
|
|
32
|
+
task: () => Promise<unknown>;
|
|
33
|
+
}): Promise<unknown>;
|
|
34
|
+
/**
|
|
35
|
+
* Creates files and directories based on the provided template files.
|
|
36
|
+
*
|
|
37
|
+
* This method iterates through the template files and writes their content
|
|
38
|
+
* to the file system. It handles both files and directories, ensuring that
|
|
39
|
+
* the directory structure is preserved.
|
|
40
|
+
*
|
|
41
|
+
* @param templateFiles - An array of template files to be created.
|
|
42
|
+
* @param result - The result object containing the name and template name.
|
|
43
|
+
*
|
|
44
|
+
* @returns A promise that resolves when all files have been created.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* const templateFiles = [{ type: 'file', name: 'example.txt', content: 'Hello World' }];
|
|
48
|
+
* await taskCreate({ templateFiles, result });
|
|
49
|
+
*/
|
|
50
|
+
create(targetPath: string, name: string): Promise<void>;
|
|
51
|
+
generate(): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
declare const validRequiredString: (value: string, key: string) => string | true;
|
|
55
|
+
|
|
56
|
+
declare class Copyer {
|
|
57
|
+
getIg(targetDir: string): ignore.Ignore;
|
|
58
|
+
/**
|
|
59
|
+
* copy templates recursively
|
|
60
|
+
* @param {string} templatesDir - source directory
|
|
61
|
+
* @param {string} targetDir - target directory
|
|
62
|
+
* @param {ignore.Ignore} ig - ignore rules
|
|
63
|
+
*/
|
|
64
|
+
copyTemplates(templatesDir: string, targetDir: string, ig: ignore.Ignore): void;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export { Copyer, Generator, type GeneratorOptions, type GeneratorResult, type TaskOptions, type TemplateFile, validRequiredString };
|
package/dist/es/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{FeScriptContext as t}from"@qlover/fe-scripts";import e from"inquirer";import{join as o,dirname as r}from"path";import{oraPromise as i}from"ora";import{readFileSync as n,readdirSync as s,existsSync as a,mkdirSync as p,statSync as c,copyFileSync as m}from"fs";import l from"ignore";function u(t,e,o,r){return new(o||(o=Promise))((function(i,n){function s(t){try{p(r.next(t))}catch(t){n(t)}}function a(t){try{p(r.throw(t))}catch(t){n(t)}}function p(t){var e;t.done?i(t.value):(e=t.value,e instanceof o?e:new o((function(t){t(e)}))).then(s,a)}p((r=r.apply(t,e||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const h=(t,e)=>"string"==typeof t&&""!==t.trim()||`${e} is required`,f=[{type:"input",name:"name",message:"Project name",validate:t=>h(t,"Project name")},{type:"list",name:"templateName",message:"Template name",choices:["fe-react","pack-app"]}];class g{getIg(t){const e=o(t,".gitignore"),r=n(e,"utf8").split("\n").map((t=>t.trim())).filter((t=>t&&!t.startsWith("#")));return l().add(r)}copyTemplates(t,e,i){const n=s(t);for(const s of n){const n=o(t,s),l=o(e,s);if(i.ignores(s))continue;const u=r(l);a(u)||p(u,{recursive:!0}),c(n).isDirectory()?this.copyTemplates(n,l,i):m(n,l)}}}class d{constructor(e){var o,r;this.prompts=[];const n=null===(o=e.options)||void 0===o?void 0:o.templatePath;if(!n)throw new Error("template path not exit");if(!a(n))throw new Error("template path not exit");this.ora=i,this.context=new t(e),this.prompts=(null===(r=e.options)||void 0===r?void 0:r.prompts)||f}get logger(){return this.context.logger}steps(t){return u(this,void 0,void 0,(function*(){try{return yield e.prompt(t)}catch(t){throw this.logger.error(t),t}}))}getTemplateFiles(t){return u(this,void 0,void 0,(function*(){return console.log("jj paths",t),[]}))}action(t){return u(this,arguments,void 0,(function*({label:t,task:e}){let o=e();o instanceof Promise||(o=Promise.resolve(o));const r=t;return this.ora(o,r),o}))}create(t,e){return u(this,void 0,void 0,(function*(){const o=new g;o.copyTemplates(t,e,o.getIg(t))}))}generate(){return u(this,void 0,void 0,(function*(){const{templatePath:t}=this.context.options,e=yield this.steps(this.prompts);this.logger.info(e);const r=o(t,e.templateName);yield this.action({label:"Creating project",task:()=>this.create(r,e.name)})}))}}export{g as Copyer,d as Generator,h as validRequiredString};
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@qlover/create-app",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"private": false,
|
|
6
|
+
"main": "./dist/es/index.js",
|
|
7
|
+
"module": "./dist/es/index.js",
|
|
8
|
+
"types": "./dist/es/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
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"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"bin",
|
|
22
|
+
"templates",
|
|
23
|
+
"package.json",
|
|
24
|
+
"README.md",
|
|
25
|
+
"CHANGELOG.md"
|
|
26
|
+
],
|
|
27
|
+
"bin": {
|
|
28
|
+
"create-app": "./bin/create-app.js"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "node ./scripts/copy-templates.js && rollup -c"
|
|
32
|
+
},
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/qlover/fe-base.git",
|
|
36
|
+
"directory": "packages/create-app"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/qlover/fe-base#readme",
|
|
39
|
+
"keywords": [
|
|
40
|
+
"create-app",
|
|
41
|
+
"fe-scripts",
|
|
42
|
+
"scripts"
|
|
43
|
+
],
|
|
44
|
+
"author": "qlover",
|
|
45
|
+
"license": "ISC",
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@octokit/graphql": "^8.1.2",
|
|
51
|
+
"@octokit/rest": "^21.1.0",
|
|
52
|
+
"@qlover/fe-scripts": "^0.5.2",
|
|
53
|
+
"@qlover/fe-utils": "^1.1.3",
|
|
54
|
+
"ignore": "^7.0.3",
|
|
55
|
+
"inquirer": "^12.3.2"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"ora": "^8.1.1"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# React + TypeScript + Vite
|
|
2
|
+
|
|
3
|
+
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
|
4
|
+
|
|
5
|
+
Currently, two official plugins are available:
|
|
6
|
+
|
|
7
|
+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
|
|
8
|
+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
|
9
|
+
|
|
10
|
+
## Expanding the ESLint configuration
|
|
11
|
+
|
|
12
|
+
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
|
|
13
|
+
|
|
14
|
+
- Configure the top-level `parserOptions` property like this:
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
export default tseslint.config({
|
|
18
|
+
languageOptions: {
|
|
19
|
+
// other options...
|
|
20
|
+
parserOptions: {
|
|
21
|
+
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
|
22
|
+
tsconfigRootDir: import.meta.dirname,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
})
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
|
|
29
|
+
- Optionally add `...tseslint.configs.stylisticTypeChecked`
|
|
30
|
+
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
// eslint.config.js
|
|
34
|
+
import react from 'eslint-plugin-react'
|
|
35
|
+
|
|
36
|
+
export default tseslint.config({
|
|
37
|
+
// Set the react version
|
|
38
|
+
settings: { react: { version: '18.3' } },
|
|
39
|
+
plugins: {
|
|
40
|
+
// Add the react plugin
|
|
41
|
+
react,
|
|
42
|
+
},
|
|
43
|
+
rules: {
|
|
44
|
+
// other rules...
|
|
45
|
+
// Enable its recommended rules
|
|
46
|
+
...react.configs.recommended.rules,
|
|
47
|
+
...react.configs['jsx-runtime'].rules,
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
```
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { i18nConfig } from '@config/i18n';
|
|
2
|
+
import { OpenAIClientConfig } from '@lib/openAiApi';
|
|
3
|
+
import { RequestCommonPluginConfig } from '@lib/request-common-plugin';
|
|
4
|
+
import { RequestAdapterFetchConfig } from '@qlover/fe-utils';
|
|
5
|
+
|
|
6
|
+
export const openAiModels = [
|
|
7
|
+
'gpt-3.5-turbo',
|
|
8
|
+
'gpt-3.5-turbo-2',
|
|
9
|
+
'gpt-4',
|
|
10
|
+
'gpt-4-32k'
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
export const requestCommonPluginConfig: RequestCommonPluginConfig = {
|
|
14
|
+
tokenPrefix: 'Bearer',
|
|
15
|
+
defaultHeaders: {
|
|
16
|
+
'Content-Type': 'application/json'
|
|
17
|
+
},
|
|
18
|
+
defaultRequestData: {
|
|
19
|
+
model: 'gpt-4o-mini',
|
|
20
|
+
stream: true
|
|
21
|
+
},
|
|
22
|
+
requiredToken: true,
|
|
23
|
+
token: import.meta.env.VITE_OPENAI_API_KEY
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const openAiConfig: OpenAIClientConfig = {
|
|
27
|
+
baseURL: import.meta.env.VITE_OPENAI_API_URL,
|
|
28
|
+
models: openAiModels,
|
|
29
|
+
commonPluginConfig: requestCommonPluginConfig
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const defaultBaseRoutemeta = {
|
|
33
|
+
localNamespace: i18nConfig.defaultNS,
|
|
34
|
+
title: '',
|
|
35
|
+
icon: ''
|
|
36
|
+
} as const;
|
|
37
|
+
|
|
38
|
+
export const defaultLoginInfo = {
|
|
39
|
+
name: 'qlover',
|
|
40
|
+
password: 'q1234566'
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const defaultFeApiConfig: {
|
|
44
|
+
adapter: Partial<RequestAdapterFetchConfig>;
|
|
45
|
+
commonPluginConfig: RequestCommonPluginConfig;
|
|
46
|
+
} = {
|
|
47
|
+
adapter: {
|
|
48
|
+
responseType: 'json',
|
|
49
|
+
baseURL: 'https://api.example.com/'
|
|
50
|
+
},
|
|
51
|
+
commonPluginConfig: requestCommonPluginConfig
|
|
52
|
+
};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
{
|
|
2
|
+
"base": {
|
|
3
|
+
"routes": [
|
|
4
|
+
{
|
|
5
|
+
"path": "/",
|
|
6
|
+
"element": "base/RedirectPathname",
|
|
7
|
+
"meta": {
|
|
8
|
+
"category": "main"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"path": "/:lng",
|
|
13
|
+
"element": "base/Layout",
|
|
14
|
+
"meta": {
|
|
15
|
+
"category": "main"
|
|
16
|
+
},
|
|
17
|
+
"children": [
|
|
18
|
+
{
|
|
19
|
+
"index": true,
|
|
20
|
+
"element": "base/Home",
|
|
21
|
+
"meta": {
|
|
22
|
+
"title": "fe-utils/home",
|
|
23
|
+
"icon": "home",
|
|
24
|
+
"localNamespace": "home"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"path": "about",
|
|
29
|
+
"element": "base/About",
|
|
30
|
+
"meta": {
|
|
31
|
+
"title": "关于",
|
|
32
|
+
"icon": "info",
|
|
33
|
+
"localNamespace": "about"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"path": "jsonStorage",
|
|
38
|
+
"element": "base/JSONStorage",
|
|
39
|
+
"meta": {
|
|
40
|
+
"title": "FE-Utils JSONStorage",
|
|
41
|
+
"icon": "info",
|
|
42
|
+
"localNamespace": "jsonStorage"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"path": "request",
|
|
47
|
+
"element": "base/Request",
|
|
48
|
+
"meta": {
|
|
49
|
+
"title": "FE-Utils Request",
|
|
50
|
+
"icon": "info",
|
|
51
|
+
"localNamespace": "request"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"path": "executor",
|
|
56
|
+
"element": "base/Executor",
|
|
57
|
+
"meta": {
|
|
58
|
+
"title": "FE-Utils Executor",
|
|
59
|
+
"icon": "info",
|
|
60
|
+
"localNamespace": "executor"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"path": "404",
|
|
65
|
+
"element": "404",
|
|
66
|
+
"meta": {
|
|
67
|
+
"category": "common",
|
|
68
|
+
"title": "404",
|
|
69
|
+
"layout": "blank",
|
|
70
|
+
"localNamespace": "common"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"path": "500",
|
|
75
|
+
"element": "500",
|
|
76
|
+
"meta": {
|
|
77
|
+
"category": "common",
|
|
78
|
+
"title": "500",
|
|
79
|
+
"layout": "blank",
|
|
80
|
+
"localNamespace": "common"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
{
|
|
87
|
+
"path": "/:lng",
|
|
88
|
+
"element": "auth/Layout",
|
|
89
|
+
"meta": {
|
|
90
|
+
"category": "auth"
|
|
91
|
+
},
|
|
92
|
+
"children": [
|
|
93
|
+
{
|
|
94
|
+
"index": true,
|
|
95
|
+
"element": "auth/Login"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"path": "login",
|
|
99
|
+
"element": "auth/Login",
|
|
100
|
+
"meta": {
|
|
101
|
+
"title": "登录",
|
|
102
|
+
"icon": "info",
|
|
103
|
+
"localNamespace": "login"
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"path": "register",
|
|
108
|
+
"element": "auth/Register",
|
|
109
|
+
"meta": {
|
|
110
|
+
"title": "注册",
|
|
111
|
+
"icon": "info",
|
|
112
|
+
"localNamespace": "register"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
{
|
|
119
|
+
"path": "404",
|
|
120
|
+
"element": "404",
|
|
121
|
+
"meta": {
|
|
122
|
+
"category": "common",
|
|
123
|
+
"title": "404",
|
|
124
|
+
"layout": "blank",
|
|
125
|
+
"localNamespace": "common"
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"path": "500",
|
|
130
|
+
"element": "500",
|
|
131
|
+
"meta": {
|
|
132
|
+
"category": "common",
|
|
133
|
+
"title": "500",
|
|
134
|
+
"layout": "blank",
|
|
135
|
+
"localNamespace": "common"
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"path": "*",
|
|
140
|
+
"element": "404",
|
|
141
|
+
"meta": {
|
|
142
|
+
"category": "common",
|
|
143
|
+
"title": "404",
|
|
144
|
+
"layout": "blank",
|
|
145
|
+
"localNamespace": "common"
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_default": {
|
|
3
|
+
"mock": true,
|
|
4
|
+
"noUrl": true
|
|
5
|
+
},
|
|
6
|
+
"GET https://api.example.com/api/userinfo": {
|
|
7
|
+
"name": "John Doe",
|
|
8
|
+
"email": "john.doe@example.com",
|
|
9
|
+
"picture": "https://randomuser.me/api/portraits/men/1.jpg"
|
|
10
|
+
},
|
|
11
|
+
"POST https://api.example.com/api/login": {
|
|
12
|
+
"token": "asdfasdf123123asdfasdf"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isProduction } from "@/containers/globals";
|
|
2
|
+
|
|
3
|
+
/** @type {import('i18next').InitOptions} */
|
|
4
|
+
export const i18nConfig = {
|
|
5
|
+
/**
|
|
6
|
+
* default language
|
|
7
|
+
*/
|
|
8
|
+
fallbackLng: 'en',
|
|
9
|
+
debug: !isProduction,
|
|
10
|
+
interpolation: {
|
|
11
|
+
escapeValue: false // React already does escaping
|
|
12
|
+
},
|
|
13
|
+
ns: ['common'],
|
|
14
|
+
defaultNS: 'common',
|
|
15
|
+
backend: {
|
|
16
|
+
loadPath: '/locales/{{lng}}/{{ns}}.json'
|
|
17
|
+
},
|
|
18
|
+
supportedLngs: ['en', 'zh']
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
export type I18nServiceLocale = (typeof i18nConfig.supportedLngs)[number];
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"base": {
|
|
3
|
+
"domAttribute": "data-theme",
|
|
4
|
+
"defaultTheme": "system",
|
|
5
|
+
"target": "html",
|
|
6
|
+
"storageKey": "fe_theme",
|
|
7
|
+
"supportedThemes": ["light", "dark", "pink"],
|
|
8
|
+
"styleThemeKeyTemplate": "${target}[${domAttribute}='${theme}']",
|
|
9
|
+
"colors": {
|
|
10
|
+
"light": {
|
|
11
|
+
"primary": "#00f",
|
|
12
|
+
"secondary": "#fff",
|
|
13
|
+
"text": "#000",
|
|
14
|
+
"background": "#fff"
|
|
15
|
+
},
|
|
16
|
+
"dark": {
|
|
17
|
+
"primary": "#f00",
|
|
18
|
+
"secondary": "#000",
|
|
19
|
+
"text": "#fff",
|
|
20
|
+
"background": "#000"
|
|
21
|
+
},
|
|
22
|
+
"pink": {
|
|
23
|
+
"primary": "#f0f",
|
|
24
|
+
"secondary": "#aaa",
|
|
25
|
+
"text": "#ddd",
|
|
26
|
+
"background": "#e0e0e0"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"override": {
|
|
31
|
+
"domAttribute": "data-theme",
|
|
32
|
+
"defaultTheme": "system",
|
|
33
|
+
"target": "html",
|
|
34
|
+
"supportedThemes": ["light", "dark", "pink"],
|
|
35
|
+
"storageKey": "fe_theme",
|
|
36
|
+
"styleThemeKeyTemplate": "${target}[${domAttribute}='${theme}']",
|
|
37
|
+
"styleKeyTemplate": "--fe-color-${colorKey}",
|
|
38
|
+
"colorsValueTemplate": "rgb(var(${styleKey}))",
|
|
39
|
+
"colors": {
|
|
40
|
+
"light": {
|
|
41
|
+
"white": "255 255 255",
|
|
42
|
+
"black": "0 0 0",
|
|
43
|
+
"gray": {
|
|
44
|
+
"50": "249 250 251",
|
|
45
|
+
"100": "243 244 246",
|
|
46
|
+
"200": "229 231 235",
|
|
47
|
+
"300": "209 213 219",
|
|
48
|
+
"400": "156 163 175",
|
|
49
|
+
"500": "107 114 128",
|
|
50
|
+
"600": "75 85 99",
|
|
51
|
+
"700": "55 65 81",
|
|
52
|
+
"800": "31 41 55",
|
|
53
|
+
"900": "17 24 39"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"dark": {
|
|
57
|
+
"white": "226 232 240",
|
|
58
|
+
"black": "0 0 0",
|
|
59
|
+
"gray": {
|
|
60
|
+
"50": "10 10 10",
|
|
61
|
+
"100": "28 28 28",
|
|
62
|
+
"200": "46 46 46",
|
|
63
|
+
"300": "64 64 64",
|
|
64
|
+
"400": "82 82 82",
|
|
65
|
+
"500": "100 100 100",
|
|
66
|
+
"600": "120 120 120",
|
|
67
|
+
"700": "138 138 138",
|
|
68
|
+
"800": "156 156 156",
|
|
69
|
+
"900": "176 176 176"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"pink": {
|
|
73
|
+
"white": "255 228 225",
|
|
74
|
+
"black": "51 51 51",
|
|
75
|
+
"gray": {
|
|
76
|
+
"50": "255 245 245",
|
|
77
|
+
"100": "255 234 234",
|
|
78
|
+
"200": "255 194 194",
|
|
79
|
+
"300": "255 153 153",
|
|
80
|
+
"400": "255 112 112",
|
|
81
|
+
"500": "255 71 71",
|
|
82
|
+
"600": "255 31 31",
|
|
83
|
+
"700": "230 0 0",
|
|
84
|
+
"800": "179 0 0",
|
|
85
|
+
"900": "128 0 0"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import js from '@eslint/js';
|
|
2
|
+
import globals from 'globals';
|
|
3
|
+
import reactHooks from 'eslint-plugin-react-hooks';
|
|
4
|
+
import reactRefresh from 'eslint-plugin-react-refresh';
|
|
5
|
+
import tseslint from 'typescript-eslint';
|
|
6
|
+
import * as feDev from '@qlover/eslint-plugin-fe-dev';
|
|
7
|
+
|
|
8
|
+
export default tseslint.config(
|
|
9
|
+
{ ignores: ['dist', 'node_modules'] },
|
|
10
|
+
{
|
|
11
|
+
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
|
12
|
+
files: ['src/**/*.{ts,tsx}'],
|
|
13
|
+
languageOptions: {
|
|
14
|
+
ecmaVersion: 2020,
|
|
15
|
+
globals: globals.browser
|
|
16
|
+
},
|
|
17
|
+
plugins: {
|
|
18
|
+
'react-hooks': reactHooks,
|
|
19
|
+
'react-refresh': reactRefresh,
|
|
20
|
+
'fe-dev': feDev
|
|
21
|
+
},
|
|
22
|
+
rules: {
|
|
23
|
+
...reactHooks.configs.recommended.rules,
|
|
24
|
+
'react-refresh/only-export-components': [
|
|
25
|
+
'warn',
|
|
26
|
+
{ allowConstantExport: true }
|
|
27
|
+
],
|
|
28
|
+
'fe-dev/ts-class-method-return': 'error'
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Template FE-React</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="root"></div>
|
|
11
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|