@qlover/create-app 0.10.0 → 0.10.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 +4 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/templates/next-app/migrations/schema/UserSchema.ts +17 -3
- package/dist/templates/next-app/package.json +2 -3
- package/dist/templates/next-app/src/base/cases/DialogHandler.ts +1 -2
- package/dist/templates/next-app/src/base/cases/RequestEncryptPlugin.ts +4 -5
- package/dist/templates/next-app/src/base/cases/UserServiceApi.ts +44 -29
- package/dist/templates/next-app/src/base/cases/ZodColumnBuilder.ts +1 -2
- package/dist/templates/next-app/src/base/port/AppUserApiInterface.ts +22 -10
- package/dist/templates/next-app/src/base/port/UserServiceInterface.ts +17 -9
- package/dist/templates/next-app/src/base/services/ResourceService.ts +3 -4
- package/dist/templates/next-app/src/base/services/UserService.ts +37 -13
- package/dist/templates/next-app/src/base/services/appApi/AppApiRequester.ts +8 -7
- package/dist/templates/next-app/src/base/services/appApi/AppUserApi.ts +15 -26
- package/dist/templates/next-app/src/core/clientIoc/ClientIOC.ts +4 -3
- package/dist/templates/next-app/src/core/clientIoc/ClientIOCRegister.ts +4 -3
- package/dist/templates/next-app/src/core/globals.ts +2 -1
- package/dist/templates/next-app/src/core/serverIoc/ServerIOC.ts +4 -3
- package/dist/templates/next-app/src/core/serverIoc/ServerIOCRegister.ts +5 -6
- package/dist/templates/next-app/src/server/UserCredentialToken.ts +1 -3
- package/dist/templates/next-app/src/uikit/components/LocaleLink.tsx +1 -2
- package/dist/templates/react-app/tsconfig.app.json +1 -3
- package/dist/templates/react-app/tsconfig.node.json +0 -4
- package/dist/templates/react-app/tsconfig.test.json +1 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -8,4 +8,4 @@ ${t}`,_n=Object.getOwnPropertyDescriptor(Function.prototype,"toString"),mn=Objec
|
|
|
8
8
|
`))this.#e+=Math.max(1,Math.ceil(Ye(D,{countAnsiEscapeCodes:!0})/t))}get isEnabled(){return this.#a&&!this.#F}set isEnabled(t){if(typeof t!="boolean")throw new TypeError("The `isEnabled` option must be a boolean");this.#a=t}get isSilent(){return this.#F}set isSilent(t){if(typeof t!="boolean")throw new TypeError("The `isSilent` option must be a boolean");this.#F=t}frame(){let t=Date.now();(this.#i===-1||t-this.#c>=this.interval)&&(this.#i=++this.#i%this.#D.frames.length,this.#c=t);let{frames:r}=this.#D,u=r[this.#i];this.color&&(u=d[this.color](u));let i=typeof this.#s=="string"&&this.#s!==""?this.#s+" ":"",D=typeof this.text=="string"?" "+this.text:"",o=typeof this.#o=="string"&&this.#o!==""?" "+this.#o:"";return i+u+D+o}clear(){if(!this.#a||!this.#u.isTTY)return this;this.#u.cursorTo(0);for(let t=0;t<this.#n;t++)t>0&&this.#u.moveCursor(0,-1),this.#u.clearLine(1);return(this.#l||this.lastIndent!==this.#l)&&this.#u.cursorTo(this.#l),this.lastIndent=this.#l,this.#n=0,this}render(){return this.#F?this:(this.clear(),this.#u.write(this.frame()),this.#n=this.#e,this)}start(t){return t&&(this.text=t),this.#F?this:this.#a?this.isSpinning?this:(this.#t.hideCursor&&$e.hide(this.#u),this.#t.discardStdin&&V.default.stdin.isTTY&&(this.#r=!0,Je.start()),this.render(),this.#f=setInterval(this.render.bind(this),this.interval),this):(this.text&&this.#u.write(`- ${this.text}
|
|
9
9
|
`),this)}stop(){return this.#a?(clearInterval(this.#f),this.#f=void 0,this.#i=0,this.clear(),this.#t.hideCursor&&$e.show(this.#u),this.#t.discardStdin&&V.default.stdin.isTTY&&this.#r&&(Je.stop(),this.#r=!1),this):this}succeed(t){return this.stopAndPersist({symbol:H.success,text:t})}fail(t){return this.stopAndPersist({symbol:H.error,text:t})}warn(t){return this.stopAndPersist({symbol:H.warning,text:t})}info(t){return this.stopAndPersist({symbol:H.info,text:t})}stopAndPersist(t={}){if(this.#F)return this;let r=t.prefixText??this.#s,u=this.#E(r," "),i=t.symbol??" ",D=t.text??this.text,s=typeof D=="string"?(i?" ":"")+D:"",a=t.suffixText??this.#o,l=this.#g(a," "),p=u+i+s+l+`
|
|
10
10
|
`;return this.stop(),this.#u.write(p),this}};function rr(e){return new Ze(e)}async function ur(e,t){let r=typeof e=="function",u=typeof e.then=="function";if(!r&&!u)throw new TypeError("Parameter `action` must be a Function or a Promise");let{successText:i,failText:D}=typeof t=="object"?t:{successText:void 0,failText:void 0},o=rr(t).start();try{let a=await(r?e(o):e);return o.succeed(i===void 0?void 0:typeof i=="string"?i:i(a)),a}catch(s){throw o.fail(D===void 0?void 0:typeof D=="string"?D:D(s)),s}}var bt=require("fs");var P=require("path"),me=require("fs"),fr=h(cr(),1),Dt=require("fs");var de=require("fs"),X=class{static ensureDir(t){(0,de.existsSync)(t)||(0,de.mkdirSync)(t,{recursive:!0})}};var{copyFile:us,stat:is}=Dt.promises,_e=class e{constructor(t,r=e.IGNORE_FILE){this.ignoreTargetPath=t;this.ignoreFile=r}static IGNORE_FILE=".gitignore.template";getIg(t=this.ignoreTargetPath){let r=(0,P.join)(t,this.ignoreFile);if(!(0,me.existsSync)(r))return;let D=(0,me.readFileSync)(r,"utf8").split(`
|
|
11
|
-
`).map(o=>o.trim()).filter(o=>o&&!o.startsWith("#"));return(0,fr.default)().add(D)}async copyFiles(t,r,u,i){let D=await Dt.promises.readdir(t);await Promise.all(D.map(async o=>{let s=(0,P.join)(t,o),a=(0,P.join)(r,o);if(u&&u.ignores(o))return;if(X.ensureDir((0,P.dirname)(a)),(await is(s)).isDirectory())await this.copyFiles(s,a,u,i);else{if(i&&await i(s,a))return;await us(s,a)}}))}copyPaths({sourcePath:t,targetPath:r,copyCallback:u}){X.ensureDir(r);let i=this.getIg();return this.copyFiles(t,r,i,u)}};var L=require("fs"),$D=h(kD(),1),xe=class{constructor(){}isJSONFilePath(t){return t.endsWith(".json")||t.endsWith(".json.template")}isTemplateFilePath(t){return t.endsWith(".template")}getRealTemplateFilePath(t){return t.replace(".template","")}readFile(t){return(0,L.readFileSync)(t,"utf-8")}readJSONFile(t){return JSON.parse(this.readFile(t))}writeFile(t,r){(0,L.writeFileSync)(this.getRealTemplateFilePath(t),r,{encoding:"utf-8"})}replaceFile(t,r){let u=this.readFile(t);return Object.keys(r).forEach(i=>{let D=r[i];u=u.replace(new RegExp(`\\[TPL:${i}\\]`,"g"),typeof D=="string"?D:JSON.stringify(D))}),u}mergeJSONFile(t,r){let u=this.readJSONFile(t),i=(0,$D.default)(r,u);this.writeFile(t,JSON.stringify(i,null,2))}composeConfigFile(t,r,u){if(this.isTemplateFilePath(r)){let i=this.replaceFile(r,t);if(this.isJSONFilePath(r)&&this.isJSONFilePath(u)){let D=this.getRealTemplateFilePath(u);return(0,L.existsSync)(D)?(this.mergeJSONFile(D,JSON.parse(i)),!0):(this.writeFile(D,i),!0)}return this.writeFile(u,i),!0}return!1}};var UD=["pack-app"],ye=class{ora;context;subPackages;copyer;compose;constructor(t){let r=t.options?.templateRootPath;if(!r)throw new Error("template path not exit");if(!(0,bt.existsSync)(r))throw new Error("template path not exit");this.ora=ur,this.context=new WD.ScriptContext("create-app",t),this.subPackages=["node-lib","react-app","next-app"],this.copyer=new _e((0,v.join)(this.context.options.configsRootPath,"_common")),this.compose=new xe}get logger(){return this.context.logger}async steps(t){try{return await HD.default.prompt(t)}catch(r){throw r.isTtyError,this.logger.error(r),r}}async action({label:t,task:r}){let u=r();u instanceof Promise||(u=Promise.resolve(u));let i=t;return this.ora(u,i),u}isPackageTemplate(t){return UD.includes(t)}async getGeneratorContext(){let t=wt(this.subPackages,UD),r=await this.steps(t);if(this.isPackageTemplate(r.template)){let u=Pt(this.subPackages),i=await this.steps(u);Object.assign(r,i)}return r.targetPath=(0,v.join)(process.cwd(),r.projectName),r.releasePath=r.releasePath||"src",r}async generate(){let t=await this.getGeneratorContext();if(this.logger.debug("context is:",t,this.context.options.templateRootPath),t.subPackages){await this.action({label:"Generate Directories(subPackages)",task:async()=>{await this.generateTemplateDir(t),await this.generateSubPackages(t),await this.generateConfigs(t,t.targetPath,"_common")}});return}await this.action({label:"Generate Directory",task:async()=>{await this.generateTemplateDir(t),await this.generateConfigs(t,t.targetPath,"_common"),await this.generateConfigs(t,t.targetPath,t.template)}})}async generateConfigs(t,r,u){let i=(a,l)=>(this.logger.debug("copyCallback",a,l),this.compose.composeConfigFile(t,a,l)),{configsRootPath:D,config:o}=this.context.options;if(!o){this.logger.debug("no copy config files");return}let s=(0,v.join)(D,u);if(!(0,bt.existsSync)(s)){this.logger.debug(`Config path not found: ${s}`);return}await this.copyer.copyPaths({sourcePath:s,targetPath:r,copyCallback:i})}generateTemplateDir(t){return this.copyer.copyPaths({sourcePath:(0,v.join)(this.context.options.templateRootPath,t.template),targetPath:t.targetPath})}async generateSubPackages(t){let{packagesNames:r="packages",subPackages:u=[],targetPath:i=""}=t,{templateRootPath:D}=this.context.options;for(let o of u){let s=(0,v.join)(D,o),a=(0,v.join)(i,r,o);this.logger.debug("copy sub package",s,a),await this.copyer.copyPaths({sourcePath:s,targetPath:a})}}};var vt={name:"@qlover/create-app",version:"0.10.
|
|
11
|
+
`).map(o=>o.trim()).filter(o=>o&&!o.startsWith("#"));return(0,fr.default)().add(D)}async copyFiles(t,r,u,i){let D=await Dt.promises.readdir(t);await Promise.all(D.map(async o=>{let s=(0,P.join)(t,o),a=(0,P.join)(r,o);if(u&&u.ignores(o))return;if(X.ensureDir((0,P.dirname)(a)),(await is(s)).isDirectory())await this.copyFiles(s,a,u,i);else{if(i&&await i(s,a))return;await us(s,a)}}))}copyPaths({sourcePath:t,targetPath:r,copyCallback:u}){X.ensureDir(r);let i=this.getIg();return this.copyFiles(t,r,i,u)}};var L=require("fs"),$D=h(kD(),1),xe=class{constructor(){}isJSONFilePath(t){return t.endsWith(".json")||t.endsWith(".json.template")}isTemplateFilePath(t){return t.endsWith(".template")}getRealTemplateFilePath(t){return t.replace(".template","")}readFile(t){return(0,L.readFileSync)(t,"utf-8")}readJSONFile(t){return JSON.parse(this.readFile(t))}writeFile(t,r){(0,L.writeFileSync)(this.getRealTemplateFilePath(t),r,{encoding:"utf-8"})}replaceFile(t,r){let u=this.readFile(t);return Object.keys(r).forEach(i=>{let D=r[i];u=u.replace(new RegExp(`\\[TPL:${i}\\]`,"g"),typeof D=="string"?D:JSON.stringify(D))}),u}mergeJSONFile(t,r){let u=this.readJSONFile(t),i=(0,$D.default)(r,u);this.writeFile(t,JSON.stringify(i,null,2))}composeConfigFile(t,r,u){if(this.isTemplateFilePath(r)){let i=this.replaceFile(r,t);if(this.isJSONFilePath(r)&&this.isJSONFilePath(u)){let D=this.getRealTemplateFilePath(u);return(0,L.existsSync)(D)?(this.mergeJSONFile(D,JSON.parse(i)),!0):(this.writeFile(D,i),!0)}return this.writeFile(u,i),!0}return!1}};var UD=["pack-app"],ye=class{ora;context;subPackages;copyer;compose;constructor(t){let r=t.options?.templateRootPath;if(!r)throw new Error("template path not exit");if(!(0,bt.existsSync)(r))throw new Error("template path not exit");this.ora=ur,this.context=new WD.ScriptContext("create-app",t),this.subPackages=["node-lib","react-app","next-app"],this.copyer=new _e((0,v.join)(this.context.options.configsRootPath,"_common")),this.compose=new xe}get logger(){return this.context.logger}async steps(t){try{return await HD.default.prompt(t)}catch(r){throw r.isTtyError,this.logger.error(r),r}}async action({label:t,task:r}){let u=r();u instanceof Promise||(u=Promise.resolve(u));let i=t;return this.ora(u,i),u}isPackageTemplate(t){return UD.includes(t)}async getGeneratorContext(){let t=wt(this.subPackages,UD),r=await this.steps(t);if(this.isPackageTemplate(r.template)){let u=Pt(this.subPackages),i=await this.steps(u);Object.assign(r,i)}return r.targetPath=(0,v.join)(process.cwd(),r.projectName),r.releasePath=r.releasePath||"src",r}async generate(){let t=await this.getGeneratorContext();if(this.logger.debug("context is:",t,this.context.options.templateRootPath),t.subPackages){await this.action({label:"Generate Directories(subPackages)",task:async()=>{await this.generateTemplateDir(t),await this.generateSubPackages(t),await this.generateConfigs(t,t.targetPath,"_common")}});return}await this.action({label:"Generate Directory",task:async()=>{await this.generateTemplateDir(t),await this.generateConfigs(t,t.targetPath,"_common"),await this.generateConfigs(t,t.targetPath,t.template)}})}async generateConfigs(t,r,u){let i=(a,l)=>(this.logger.debug("copyCallback",a,l),this.compose.composeConfigFile(t,a,l)),{configsRootPath:D,config:o}=this.context.options;if(!o){this.logger.debug("no copy config files");return}let s=(0,v.join)(D,u);if(!(0,bt.existsSync)(s)){this.logger.debug(`Config path not found: ${s}`);return}await this.copyer.copyPaths({sourcePath:s,targetPath:r,copyCallback:i})}generateTemplateDir(t){return this.copyer.copyPaths({sourcePath:(0,v.join)(this.context.options.templateRootPath,t.template),targetPath:t.targetPath})}async generateSubPackages(t){let{packagesNames:r="packages",subPackages:u=[],targetPath:i=""}=t,{templateRootPath:D}=this.context.options;for(let o of u){let s=(0,v.join)(D,o),a=(0,v.join)(i,r,o);this.logger.debug("copy sub package",s,a),await this.copyer.copyPaths({sourcePath:s,targetPath:a})}}};var vt={name:"@qlover/create-app",version:"0.10.1",description:"Create a new app with a single command",private:!1,type:"module",files:["dist","package.json","README.md","CHANGELOG.md"],bin:{"create-app":"dist/index.js"},scripts:{lint:"eslint src --fix",build:"tsup","create:app":"node ./dist/index.js"},repository:{type:"git",url:"git+https://github.com/qlover/fe-base.git",directory:"packages/create-app"},homepage:"https://github.com/qlover/fe-base#readme",keywords:["create-app","fe-scripts","scripts"],author:"qlover",license:"ISC",publishConfig:{access:"public"},devDependencies:{"@qlover/logger":"workspace:*",ignore:"^7.0.3",lodash:"^4.17.21",ora:"^8.1.1"},dependencies:{"@qlover/scripts-context":"workspace:*",commander:"^13.1.0",inquirer:"^12.3.2"}};function Wl(){let e=new YD.Command;return e.version(vt.version,"-v, --version","Show version").description(vt.description).option("-d, --dry-run","Do not touch or write anything, but show the commands").option("-V, --verbose","Show more information").option("--config","Copy config files (default: true)",!0).option("--no-config","Do not copy config files"),e.parse(),e.opts()}async function VD(e=process.cwd()){let{dryRun:t,verbose:r,...u}=Wl(),i=(0,xt.resolve)(e,"./templates"),D=(0,xt.resolve)(e,"./configs");(0,yt.existsSync)(i)||(console.error("Template is empty!"),process.exit(1)),(0,yt.existsSync)(D)||(console.error("Configs is empty!"),process.exit(1)),await new ye({dryRun:t,verbose:r,options:{...u,templateRootPath:i,configsRootPath:D}}).generate()}VD(__dirname).catch(e=>{console.error(e),process.exit(1)});
|
package/dist/index.js
CHANGED
|
@@ -8,4 +8,4 @@ ${t}`,pD=Object.getOwnPropertyDescriptor(Function.prototype,"toString"),hD=Objec
|
|
|
8
8
|
`))this.#e+=Math.max(1,Math.ceil(Le(n,{countAnsiEscapeCodes:!0})/t))}get isEnabled(){return this.#a&&!this.#F}set isEnabled(t){if(typeof t!="boolean")throw new TypeError("The `isEnabled` option must be a boolean");this.#a=t}get isSilent(){return this.#F}set isSilent(t){if(typeof t!="boolean")throw new TypeError("The `isSilent` option must be a boolean");this.#F=t}frame(){let t=Date.now();(this.#i===-1||t-this.#c>=this.interval)&&(this.#i=++this.#i%this.#n.frames.length,this.#c=t);let{frames:r}=this.#n,u=r[this.#i];this.color&&(u=E[this.color](u));let i=typeof this.#s=="string"&&this.#s!==""?this.#s+" ":"",n=typeof this.text=="string"?" "+this.text:"",o=typeof this.#o=="string"&&this.#o!==""?" "+this.#o:"";return i+u+n+o}clear(){if(!this.#a||!this.#u.isTTY)return this;this.#u.cursorTo(0);for(let t=0;t<this.#D;t++)t>0&&this.#u.moveCursor(0,-1),this.#u.clearLine(1);return(this.#l||this.lastIndent!==this.#l)&&this.#u.cursorTo(this.#l),this.lastIndent=this.#l,this.#D=0,this}render(){return this.#F?this:(this.clear(),this.#u.write(this.frame()),this.#D=this.#e,this)}start(t){return t&&(this.text=t),this.#F?this:this.#a?this.isSpinning?this:(this.#t.hideCursor&&je.hide(this.#u),this.#t.discardStdin&&ce.stdin.isTTY&&(this.#r=!0,We.start()),this.render(),this.#f=setInterval(this.render.bind(this),this.interval),this):(this.text&&this.#u.write(`- ${this.text}
|
|
9
9
|
`),this)}stop(){return this.#a?(clearInterval(this.#f),this.#f=void 0,this.#i=0,this.clear(),this.#t.hideCursor&&je.show(this.#u),this.#t.discardStdin&&ce.stdin.isTTY&&this.#r&&(We.stop(),this.#r=!1),this):this}succeed(t){return this.stopAndPersist({symbol:k.success,text:t})}fail(t){return this.stopAndPersist({symbol:k.error,text:t})}warn(t){return this.stopAndPersist({symbol:k.warning,text:t})}info(t){return this.stopAndPersist({symbol:k.info,text:t})}stopAndPersist(t={}){if(this.#F)return this;let r=t.prefixText??this.#s,u=this.#E(r," "),i=t.symbol??" ",n=t.text??this.text,s=typeof n=="string"?(i?" ":"")+n:"",a=t.suffixText??this.#o,l=this.#g(a," "),p=u+i+s+l+`
|
|
10
10
|
`;return this.stop(),this.#u.write(p),this}};function zt(e){return new He(e)}async function Kt(e,t){let r=typeof e=="function",u=typeof e.then=="function";if(!r&&!u)throw new TypeError("Parameter `action` must be a Function or a Promise");let{successText:i,failText:n}=typeof t=="object"?t:{successText:void 0,failText:void 0},o=zt(t).start();try{let a=await(r?e(o):e);return o.succeed(i===void 0?void 0:typeof i=="string"?i:i(a)),a}catch(s){throw o.fail(n===void 0?void 0:typeof n=="string"?n:n(s)),s}}import{existsSync as Nn}from"fs";var nr=ue(ir(),1);import{dirname as QD,join as Ze}from"path";import{existsSync as es,readFileSync as ts}from"fs";import{promises as Dr}from"fs";import{existsSync as JD,mkdirSync as ZD}from"fs";var H=class{static ensureDir(t){JD(t)||ZD(t,{recursive:!0})}};var{copyFile:rs,stat:us}=Dr,Ce=class e{constructor(t,r=e.IGNORE_FILE){this.ignoreTargetPath=t;this.ignoreFile=r}static IGNORE_FILE=".gitignore.template";getIg(t=this.ignoreTargetPath){let r=Ze(t,this.ignoreFile);if(!es(r))return;let n=ts(r,"utf8").split(`
|
|
11
|
-
`).map(o=>o.trim()).filter(o=>o&&!o.startsWith("#"));return(0,nr.default)().add(n)}async copyFiles(t,r,u,i){let n=await Dr.readdir(t);await Promise.all(n.map(async o=>{let s=Ze(t,o),a=Ze(r,o);if(u&&u.ignores(o))return;if(H.ensureDir(QD(a)),(await us(s)).isDirectory())await this.copyFiles(s,a,u,i);else{if(i&&await i(s,a))return;await rs(s,a)}}))}copyPaths({sourcePath:t,targetPath:r,copyCallback:u}){H.ensureDir(r);let i=this.getIg();return this.copyFiles(t,r,i,u)}};var jn=ue(In(),1);import{readFileSync as $l,writeFileSync as Ul,existsSync as Wl}from"fs";var _e=class{constructor(){}isJSONFilePath(t){return t.endsWith(".json")||t.endsWith(".json.template")}isTemplateFilePath(t){return t.endsWith(".template")}getRealTemplateFilePath(t){return t.replace(".template","")}readFile(t){return $l(t,"utf-8")}readJSONFile(t){return JSON.parse(this.readFile(t))}writeFile(t,r){Ul(this.getRealTemplateFilePath(t),r,{encoding:"utf-8"})}replaceFile(t,r){let u=this.readFile(t);return Object.keys(r).forEach(i=>{let n=r[i];u=u.replace(new RegExp(`\\[TPL:${i}\\]`,"g"),typeof n=="string"?n:JSON.stringify(n))}),u}mergeJSONFile(t,r){let u=this.readJSONFile(t),i=(0,jn.default)(r,u);this.writeFile(t,JSON.stringify(i,null,2))}composeConfigFile(t,r,u){if(this.isTemplateFilePath(r)){let i=this.replaceFile(r,t);if(this.isJSONFilePath(r)&&this.isJSONFilePath(u)){let n=this.getRealTemplateFilePath(u);return Wl(n)?(this.mergeJSONFile(n,JSON.parse(i)),!0):(this.writeFile(n,i),!0)}return this.writeFile(u,i),!0}return!1}};var Gn=["pack-app"],Be=class{ora;context;subPackages;copyer;compose;constructor(t){let r=t.options?.templateRootPath;if(!r)throw new Error("template path not exit");if(!Nn(r))throw new Error("template path not exit");this.ora=Kt,this.context=new Hl("create-app",t),this.subPackages=["node-lib","react-app","next-app"],this.copyer=new Ce(N(this.context.options.configsRootPath,"_common")),this.compose=new _e}get logger(){return this.context.logger}async steps(t){try{return await Yl.prompt(t)}catch(r){throw r.isTtyError,this.logger.error(r),r}}async action({label:t,task:r}){let u=r();u instanceof Promise||(u=Promise.resolve(u));let i=t;return this.ora(u,i),u}isPackageTemplate(t){return Gn.includes(t)}async getGeneratorContext(){let t=mt(this.subPackages,Gn),r=await this.steps(t);if(this.isPackageTemplate(r.template)){let u=_t(this.subPackages),i=await this.steps(u);Object.assign(r,i)}return r.targetPath=N(process.cwd(),r.projectName),r.releasePath=r.releasePath||"src",r}async generate(){let t=await this.getGeneratorContext();if(this.logger.debug("context is:",t,this.context.options.templateRootPath),t.subPackages){await this.action({label:"Generate Directories(subPackages)",task:async()=>{await this.generateTemplateDir(t),await this.generateSubPackages(t),await this.generateConfigs(t,t.targetPath,"_common")}});return}await this.action({label:"Generate Directory",task:async()=>{await this.generateTemplateDir(t),await this.generateConfigs(t,t.targetPath,"_common"),await this.generateConfigs(t,t.targetPath,t.template)}})}async generateConfigs(t,r,u){let i=(a,l)=>(this.logger.debug("copyCallback",a,l),this.compose.composeConfigFile(t,a,l)),{configsRootPath:n,config:o}=this.context.options;if(!o){this.logger.debug("no copy config files");return}let s=N(n,u);if(!Nn(s)){this.logger.debug(`Config path not found: ${s}`);return}await this.copyer.copyPaths({sourcePath:s,targetPath:r,copyCallback:i})}generateTemplateDir(t){return this.copyer.copyPaths({sourcePath:N(this.context.options.templateRootPath,t.template),targetPath:t.targetPath})}async generateSubPackages(t){let{packagesNames:r="packages",subPackages:u=[],targetPath:i=""}=t,{templateRootPath:n}=this.context.options;for(let o of u){let s=N(n,o),a=N(i,r,o);this.logger.debug("copy sub package",s,a),await this.copyer.copyPaths({sourcePath:s,targetPath:a})}}};var Et={name:"@qlover/create-app",version:"0.10.
|
|
11
|
+
`).map(o=>o.trim()).filter(o=>o&&!o.startsWith("#"));return(0,nr.default)().add(n)}async copyFiles(t,r,u,i){let n=await Dr.readdir(t);await Promise.all(n.map(async o=>{let s=Ze(t,o),a=Ze(r,o);if(u&&u.ignores(o))return;if(H.ensureDir(QD(a)),(await us(s)).isDirectory())await this.copyFiles(s,a,u,i);else{if(i&&await i(s,a))return;await rs(s,a)}}))}copyPaths({sourcePath:t,targetPath:r,copyCallback:u}){H.ensureDir(r);let i=this.getIg();return this.copyFiles(t,r,i,u)}};var jn=ue(In(),1);import{readFileSync as $l,writeFileSync as Ul,existsSync as Wl}from"fs";var _e=class{constructor(){}isJSONFilePath(t){return t.endsWith(".json")||t.endsWith(".json.template")}isTemplateFilePath(t){return t.endsWith(".template")}getRealTemplateFilePath(t){return t.replace(".template","")}readFile(t){return $l(t,"utf-8")}readJSONFile(t){return JSON.parse(this.readFile(t))}writeFile(t,r){Ul(this.getRealTemplateFilePath(t),r,{encoding:"utf-8"})}replaceFile(t,r){let u=this.readFile(t);return Object.keys(r).forEach(i=>{let n=r[i];u=u.replace(new RegExp(`\\[TPL:${i}\\]`,"g"),typeof n=="string"?n:JSON.stringify(n))}),u}mergeJSONFile(t,r){let u=this.readJSONFile(t),i=(0,jn.default)(r,u);this.writeFile(t,JSON.stringify(i,null,2))}composeConfigFile(t,r,u){if(this.isTemplateFilePath(r)){let i=this.replaceFile(r,t);if(this.isJSONFilePath(r)&&this.isJSONFilePath(u)){let n=this.getRealTemplateFilePath(u);return Wl(n)?(this.mergeJSONFile(n,JSON.parse(i)),!0):(this.writeFile(n,i),!0)}return this.writeFile(u,i),!0}return!1}};var Gn=["pack-app"],Be=class{ora;context;subPackages;copyer;compose;constructor(t){let r=t.options?.templateRootPath;if(!r)throw new Error("template path not exit");if(!Nn(r))throw new Error("template path not exit");this.ora=Kt,this.context=new Hl("create-app",t),this.subPackages=["node-lib","react-app","next-app"],this.copyer=new Ce(N(this.context.options.configsRootPath,"_common")),this.compose=new _e}get logger(){return this.context.logger}async steps(t){try{return await Yl.prompt(t)}catch(r){throw r.isTtyError,this.logger.error(r),r}}async action({label:t,task:r}){let u=r();u instanceof Promise||(u=Promise.resolve(u));let i=t;return this.ora(u,i),u}isPackageTemplate(t){return Gn.includes(t)}async getGeneratorContext(){let t=mt(this.subPackages,Gn),r=await this.steps(t);if(this.isPackageTemplate(r.template)){let u=_t(this.subPackages),i=await this.steps(u);Object.assign(r,i)}return r.targetPath=N(process.cwd(),r.projectName),r.releasePath=r.releasePath||"src",r}async generate(){let t=await this.getGeneratorContext();if(this.logger.debug("context is:",t,this.context.options.templateRootPath),t.subPackages){await this.action({label:"Generate Directories(subPackages)",task:async()=>{await this.generateTemplateDir(t),await this.generateSubPackages(t),await this.generateConfigs(t,t.targetPath,"_common")}});return}await this.action({label:"Generate Directory",task:async()=>{await this.generateTemplateDir(t),await this.generateConfigs(t,t.targetPath,"_common"),await this.generateConfigs(t,t.targetPath,t.template)}})}async generateConfigs(t,r,u){let i=(a,l)=>(this.logger.debug("copyCallback",a,l),this.compose.composeConfigFile(t,a,l)),{configsRootPath:n,config:o}=this.context.options;if(!o){this.logger.debug("no copy config files");return}let s=N(n,u);if(!Nn(s)){this.logger.debug(`Config path not found: ${s}`);return}await this.copyer.copyPaths({sourcePath:s,targetPath:r,copyCallback:i})}generateTemplateDir(t){return this.copyer.copyPaths({sourcePath:N(this.context.options.templateRootPath,t.template),targetPath:t.targetPath})}async generateSubPackages(t){let{packagesNames:r="packages",subPackages:u=[],targetPath:i=""}=t,{templateRootPath:n}=this.context.options;for(let o of u){let s=N(n,o),a=N(i,r,o);this.logger.debug("copy sub package",s,a),await this.copyer.copyPaths({sourcePath:s,targetPath:a})}}};var Et={name:"@qlover/create-app",version:"0.10.1",description:"Create a new app with a single command",private:!1,type:"module",files:["dist","package.json","README.md","CHANGELOG.md"],bin:{"create-app":"dist/index.js"},scripts:{lint:"eslint src --fix",build:"tsup","create:app":"node ./dist/index.js"},repository:{type:"git",url:"git+https://github.com/qlover/fe-base.git",directory:"packages/create-app"},homepage:"https://github.com/qlover/fe-base#readme",keywords:["create-app","fe-scripts","scripts"],author:"qlover",license:"ISC",publishConfig:{access:"public"},devDependencies:{"@qlover/logger":"workspace:*",ignore:"^7.0.3",lodash:"^4.17.21",ora:"^8.1.1"},dependencies:{"@qlover/scripts-context":"workspace:*",commander:"^13.1.0",inquirer:"^12.3.2"}};function Kl(){let e=new zl;return e.version(Et.version,"-v, --version","Show version").description(Et.description).option("-d, --dry-run","Do not touch or write anything, but show the commands").option("-V, --verbose","Show more information").option("--config","Copy config files (default: true)",!0).option("--no-config","Do not copy config files"),e.parse(),e.opts()}async function kn(e=process.cwd()){let{dryRun:t,verbose:r,...u}=Kl(),i=Mn(e,"./templates"),n=Mn(e,"./configs");Ln(i)||(console.error("Template is empty!"),process.exit(1)),Ln(n)||(console.error("Configs is empty!"),process.exit(1)),await new Be({dryRun:t,verbose:r,options:{...u,templateRootPath:i,configsRootPath:n}}).generate()}import{fileURLToPath as Xl}from"url";import{dirname as Jl}from"path";var Zl=Xl(import.meta.url),Ql=Jl(Zl);kn(Ql).catch(e=>{console.error(e),process.exit(1)});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import type { SafeParseReturnType } from 'zod';
|
|
2
3
|
|
|
3
4
|
export const UserRole = {
|
|
4
5
|
ADMIN: 0,
|
|
@@ -16,9 +17,22 @@ export const userSchema = z.object({
|
|
|
16
17
|
* 加密的token, 包含token, 过期时间
|
|
17
18
|
*/
|
|
18
19
|
credential_token: z.string(),
|
|
19
|
-
email_confirmed_at: z.number(),
|
|
20
|
-
created_at: z.
|
|
21
|
-
updated_at: z.
|
|
20
|
+
email_confirmed_at: z.number().nullable().optional(),
|
|
21
|
+
created_at: z.string(),
|
|
22
|
+
updated_at: z.string().nullable().optional()
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
export type UserSchema = z.infer<typeof userSchema>;
|
|
26
|
+
|
|
27
|
+
export type UserCredential = {
|
|
28
|
+
credential_token: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export function isWebUserSchema(
|
|
32
|
+
value: unknown
|
|
33
|
+
): SafeParseReturnType<
|
|
34
|
+
Omit<UserSchema, 'password'>,
|
|
35
|
+
Omit<UserSchema, 'password'>
|
|
36
|
+
> {
|
|
37
|
+
return userSchema.omit({ password: true }).safeParse(value);
|
|
38
|
+
}
|
|
@@ -24,10 +24,9 @@
|
|
|
24
24
|
"@brain-toolkit/antd-theme-override": "^0.0.3",
|
|
25
25
|
"@brain-toolkit/bridge": "^0.0.1",
|
|
26
26
|
"@brain-toolkit/react-kit": "^0.1.0",
|
|
27
|
-
"@qlover/corekit-bridge": "
|
|
28
|
-
"@qlover/fe-corekit": "
|
|
27
|
+
"@qlover/corekit-bridge": "latest",
|
|
28
|
+
"@qlover/fe-corekit": "latest",
|
|
29
29
|
"@qlover/slice-store-react": "^1.4.1",
|
|
30
|
-
"@supabase/auth-helpers-nextjs": "^0.10.0",
|
|
31
30
|
"@supabase/ssr": "^0.7.0",
|
|
32
31
|
"@supabase/supabase-js": "^2.57.2",
|
|
33
32
|
"@types/jsonwebtoken": "^9.0.10",
|
|
@@ -6,8 +6,9 @@ import type {
|
|
|
6
6
|
RequestAdapterConfig
|
|
7
7
|
} from '@qlover/fe-corekit';
|
|
8
8
|
|
|
9
|
-
export interface RequestEncryptPluginProps<
|
|
10
|
-
|
|
9
|
+
export interface RequestEncryptPluginProps<
|
|
10
|
+
Request = unknown
|
|
11
|
+
> extends RequestAdapterConfig<Request> {
|
|
11
12
|
/**
|
|
12
13
|
* 加密密码在 HTTP 请求中
|
|
13
14
|
*
|
|
@@ -18,9 +19,7 @@ export interface RequestEncryptPluginProps<Request = unknown>
|
|
|
18
19
|
encryptProps?: string[] | string;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
export class RequestEncryptPlugin
|
|
22
|
-
implements ExecutorPlugin<RequestEncryptPluginProps>
|
|
23
|
-
{
|
|
22
|
+
export class RequestEncryptPlugin implements ExecutorPlugin<RequestEncryptPluginProps> {
|
|
24
23
|
readonly pluginName = 'RequestEncryptPlugin';
|
|
25
24
|
|
|
26
25
|
constructor(protected encryptor: Encryptor<string, string>) {}
|
|
@@ -1,48 +1,63 @@
|
|
|
1
1
|
import { inject, injectable } from 'inversify';
|
|
2
|
-
import
|
|
2
|
+
import { omit } from 'lodash';
|
|
3
|
+
import type { LoginValidatorData } from '@/server/validators/LoginValidator';
|
|
4
|
+
import {
|
|
5
|
+
isWebUserSchema,
|
|
6
|
+
type UserCredential,
|
|
7
|
+
type UserSchema
|
|
8
|
+
} from '@migrations/schema/UserSchema';
|
|
3
9
|
import { AppUserApi } from '../services/appApi/AppUserApi';
|
|
4
|
-
import type { AppApiSuccessInterface } from '../port/AppApiInterface';
|
|
5
10
|
import type { AppUserApiInterface } from '../port/AppUserApiInterface';
|
|
6
|
-
import type {
|
|
7
|
-
LoginResponseData,
|
|
8
|
-
UserAuthApiInterface,
|
|
9
|
-
UserAuthStoreInterface
|
|
10
|
-
} from '@qlover/corekit-bridge';
|
|
11
|
+
import type { UserServiceGateway } from '@qlover/corekit-bridge';
|
|
11
12
|
|
|
12
13
|
@injectable()
|
|
13
|
-
export class UserServiceApi implements
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
export class UserServiceApi implements UserServiceGateway<
|
|
15
|
+
UserSchema,
|
|
16
|
+
UserCredential
|
|
17
|
+
> {
|
|
16
18
|
constructor(@inject(AppUserApi) protected appUserApi: AppUserApiInterface) {}
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
getUserInfo(_params?: unknown): Promise<UserSchema | null> {
|
|
21
|
+
if (_params && isWebUserSchema(_params).success) {
|
|
22
|
+
return Promise.resolve(omit(_params, 'credential_token') as UserSchema);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return Promise.resolve(null);
|
|
20
26
|
}
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
|
|
28
|
+
refreshUserInfo<Params>(
|
|
29
|
+
_params?: Params | undefined
|
|
30
|
+
): Promise<UserSchema | null> {
|
|
31
|
+
return this.getUserInfo(_params);
|
|
23
32
|
}
|
|
24
33
|
|
|
25
|
-
async login(params: {
|
|
26
|
-
email: string;
|
|
27
|
-
password: string;
|
|
28
|
-
}): Promise<LoginResponseData> {
|
|
34
|
+
async login(params: LoginValidatorData): Promise<UserCredential> {
|
|
29
35
|
const response = await this.appUserApi.login(params);
|
|
30
|
-
|
|
36
|
+
|
|
37
|
+
if (!response.data.success) {
|
|
38
|
+
throw response;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return response.data.data as UserCredential;
|
|
31
42
|
}
|
|
32
43
|
|
|
33
|
-
async register(params: {
|
|
34
|
-
email: string;
|
|
35
|
-
password: string;
|
|
36
|
-
}): Promise<LoginResponseData> {
|
|
44
|
+
async register(params: LoginValidatorData): Promise<UserSchema> {
|
|
37
45
|
const response = await this.appUserApi.register(params);
|
|
38
|
-
return (response as AppApiSuccessInterface).data as LoginResponseData;
|
|
39
|
-
}
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
if (!response.data.success) {
|
|
48
|
+
throw response;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return response.data.data as UserSchema;
|
|
43
52
|
}
|
|
44
53
|
|
|
45
|
-
|
|
46
|
-
|
|
54
|
+
async logout<P = unknown, Result = void>(params?: P): Promise<Result> {
|
|
55
|
+
const response = await this.appUserApi.logout(params);
|
|
56
|
+
|
|
57
|
+
if (!response.data.success) {
|
|
58
|
+
throw response;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return response.data.data as Result;
|
|
47
62
|
}
|
|
48
63
|
}
|
|
@@ -33,8 +33,7 @@ export const ZodType2RenderFormMap = {
|
|
|
33
33
|
export class ZodColumnBuilder<
|
|
34
34
|
Value extends ZodRawShape,
|
|
35
35
|
Input extends ZodObject<Value>
|
|
36
|
-
> implements ZodBuilderInterface<Input, ResourceTableOption<z.infer<Input>>>
|
|
37
|
-
{
|
|
36
|
+
> implements ZodBuilderInterface<Input, ResourceTableOption<z.infer<Input>>> {
|
|
38
37
|
protected optionMap: OptionMap<Value, Input>;
|
|
39
38
|
|
|
40
39
|
constructor(
|
|
@@ -1,15 +1,27 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LoginValidatorData } from '@/server/validators/LoginValidator';
|
|
2
|
+
import type { UserSchema } from '@migrations/schema/UserSchema';
|
|
3
|
+
import type { AppApiTransaction } from '../services/appApi/AppApiRequester';
|
|
4
|
+
|
|
5
|
+
export type UserApiLoginTransaction = AppApiTransaction<
|
|
6
|
+
LoginValidatorData,
|
|
7
|
+
UserSchema
|
|
8
|
+
>;
|
|
9
|
+
|
|
10
|
+
export type UserApiRegisterTransaction = AppApiTransaction<
|
|
11
|
+
LoginValidatorData,
|
|
12
|
+
UserSchema
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
export type UserApiLogoutTransaction = AppApiTransaction<unknown, void>;
|
|
2
16
|
|
|
3
17
|
export interface AppUserApiInterface {
|
|
4
|
-
login(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}): Promise<AppApiResult<unknown>>;
|
|
18
|
+
login(
|
|
19
|
+
params: UserApiLoginTransaction['data']
|
|
20
|
+
): Promise<UserApiLoginTransaction['response']>;
|
|
8
21
|
|
|
9
|
-
register(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}): Promise<AppApiResult<unknown>>;
|
|
22
|
+
register(
|
|
23
|
+
params: UserApiRegisterTransaction['data']
|
|
24
|
+
): Promise<UserApiRegisterTransaction['response']>;
|
|
13
25
|
|
|
14
|
-
logout(): Promise<
|
|
26
|
+
logout(params?: unknown): Promise<UserApiLogoutTransaction['response']>;
|
|
15
27
|
}
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
3
|
-
import type { ExecutorPlugin } from '@qlover/fe-corekit';
|
|
1
|
+
import type { UserCredential, UserSchema } from '@migrations/schema/UserSchema';
|
|
2
|
+
import type { UserService as CorekitBridgeUserServiceInterface } from '@qlover/corekit-bridge';
|
|
4
3
|
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
{
|
|
9
|
-
|
|
4
|
+
export interface UserServiceInterface extends CorekitBridgeUserServiceInterface<
|
|
5
|
+
UserSchema,
|
|
6
|
+
UserCredential
|
|
7
|
+
> {
|
|
8
|
+
// You can add your own methods here
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Get the user token
|
|
12
|
+
*
|
|
13
|
+
* This is a extends method from the corekit-bridge UserServiceInterface.
|
|
14
|
+
*/
|
|
15
|
+
getToken(): string;
|
|
16
|
+
|
|
17
|
+
isUserInfo(value: unknown): value is UserSchema;
|
|
18
|
+
|
|
19
|
+
isUserCredential(value: unknown): value is UserCredential;
|
|
12
20
|
}
|
|
@@ -11,10 +11,9 @@ import type { PaginationInterface } from '@/server/port/PaginationInterface';
|
|
|
11
11
|
|
|
12
12
|
export class ResourceService<
|
|
13
13
|
T,
|
|
14
|
-
Store extends
|
|
15
|
-
ResourceStore<ResourceStateInterface>
|
|
16
|
-
> implements ResourceServiceInterface<T>
|
|
17
|
-
{
|
|
14
|
+
Store extends ResourceStore<ResourceStateInterface> =
|
|
15
|
+
ResourceStore<ResourceStateInterface>
|
|
16
|
+
> implements ResourceServiceInterface<T> {
|
|
18
17
|
readonly unionKey: string = 'id';
|
|
19
18
|
|
|
20
19
|
constructor(
|
|
@@ -1,24 +1,48 @@
|
|
|
1
|
+
import { UserService as CorekitBridgeUserService } from '@qlover/corekit-bridge';
|
|
1
2
|
import { injectable, inject } from 'inversify';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
3
|
+
import { isObject, isString } from 'lodash';
|
|
4
|
+
import {
|
|
5
|
+
userSchema,
|
|
6
|
+
type UserCredential,
|
|
7
|
+
type UserSchema
|
|
8
|
+
} from '@migrations/schema/UserSchema';
|
|
4
9
|
import { UserServiceApi } from '../cases/UserServiceApi';
|
|
5
|
-
import { UserServiceInterface } from '../port/UserServiceInterface';
|
|
6
|
-
import type {
|
|
10
|
+
import type { UserServiceInterface } from '../port/UserServiceInterface';
|
|
11
|
+
import type { UserServiceGateway } from '@qlover/corekit-bridge';
|
|
7
12
|
|
|
8
13
|
@injectable()
|
|
9
|
-
export class UserService
|
|
14
|
+
export class UserService
|
|
15
|
+
extends CorekitBridgeUserService<UserSchema, UserCredential>
|
|
16
|
+
implements UserServiceInterface
|
|
17
|
+
{
|
|
10
18
|
constructor(
|
|
11
|
-
@inject(
|
|
12
|
-
|
|
19
|
+
@inject(UserServiceApi)
|
|
20
|
+
userApi: UserServiceGateway<UserSchema, UserCredential>
|
|
13
21
|
) {
|
|
14
|
-
super(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
super({
|
|
23
|
+
gateway: userApi
|
|
24
|
+
// next-js ssr 将 credential 存储在 cookie 中无需存储用户信息到本地
|
|
25
|
+
// store: {
|
|
26
|
+
// storageKey: appConfig.userInfoKey,
|
|
27
|
+
// credentialStorageKey: appConfig.userTokenKey,
|
|
28
|
+
// persistUserInfo: true,
|
|
29
|
+
// }
|
|
18
30
|
});
|
|
19
31
|
}
|
|
20
32
|
|
|
21
|
-
getToken(): string
|
|
22
|
-
return this.store.getCredential();
|
|
33
|
+
getToken(): string {
|
|
34
|
+
return this.store.getCredential()?.credential_token ?? '';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
isUserInfo(value: unknown): value is UserSchema {
|
|
38
|
+
return userSchema.safeParse(value).success;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
isUserCredential(value: unknown): value is UserCredential {
|
|
42
|
+
return (
|
|
43
|
+
isObject(value) &&
|
|
44
|
+
'credential_token' in value &&
|
|
45
|
+
isString(value.credential_token)
|
|
46
|
+
);
|
|
23
47
|
}
|
|
24
48
|
}
|
|
@@ -13,8 +13,7 @@ import type {
|
|
|
13
13
|
} from '@qlover/fe-corekit';
|
|
14
14
|
|
|
15
15
|
export interface AppApiConfig<Request = unknown>
|
|
16
|
-
extends RequestAdapterConfig<Request>,
|
|
17
|
-
RequestEncryptPluginProps<Request> {}
|
|
16
|
+
extends RequestAdapterConfig<Request>, RequestEncryptPluginProps<Request> {}
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
19
|
* UserApiResponse
|
|
@@ -33,11 +32,13 @@ export type AppApiResponse<
|
|
|
33
32
|
/**
|
|
34
33
|
* UserApi common transaction
|
|
35
34
|
*/
|
|
36
|
-
export interface AppApiTransaction<
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
export interface AppApiTransaction<
|
|
36
|
+
Request = unknown,
|
|
37
|
+
Response = unknown
|
|
38
|
+
> extends RequestTransactionInterface<
|
|
39
|
+
AppApiConfig<Request>,
|
|
40
|
+
AppApiResponse<Request, Response>
|
|
41
|
+
> {
|
|
41
42
|
data: AppApiConfig<Request>['data'];
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -1,25 +1,14 @@
|
|
|
1
1
|
import { inject, injectable } from 'inversify';
|
|
2
|
-
import type {
|
|
3
|
-
|
|
2
|
+
import type {
|
|
3
|
+
AppUserApiInterface,
|
|
4
|
+
UserApiLoginTransaction,
|
|
5
|
+
UserApiLogoutTransaction,
|
|
6
|
+
UserApiRegisterTransaction
|
|
7
|
+
} from '@/base/port/AppUserApiInterface';
|
|
4
8
|
import { AppApiRequester } from './AppApiRequester';
|
|
5
|
-
import type { AppApiConfig
|
|
9
|
+
import type { AppApiConfig } from './AppApiRequester';
|
|
6
10
|
import type { RequestTransaction } from '@qlover/fe-corekit';
|
|
7
11
|
|
|
8
|
-
export type UserApiLoginTransaction = AppApiTransaction<
|
|
9
|
-
{ email: string; password: string },
|
|
10
|
-
{
|
|
11
|
-
token: string;
|
|
12
|
-
}
|
|
13
|
-
>;
|
|
14
|
-
|
|
15
|
-
export type UserApiRegisterTransaction = AppApiTransaction<
|
|
16
|
-
{
|
|
17
|
-
email: string;
|
|
18
|
-
password: string;
|
|
19
|
-
},
|
|
20
|
-
AppApiTransaction['response']['data']
|
|
21
|
-
>;
|
|
22
|
-
|
|
23
12
|
/**
|
|
24
13
|
* UserApi
|
|
25
14
|
*
|
|
@@ -36,7 +25,7 @@ export class AppUserApi implements AppUserApiInterface {
|
|
|
36
25
|
|
|
37
26
|
async login(
|
|
38
27
|
params: UserApiLoginTransaction['data']
|
|
39
|
-
): Promise<
|
|
28
|
+
): Promise<UserApiLoginTransaction['response']> {
|
|
40
29
|
const response = await this.client.request<UserApiLoginTransaction>({
|
|
41
30
|
url: '/user/login',
|
|
42
31
|
method: 'POST',
|
|
@@ -44,12 +33,12 @@ export class AppUserApi implements AppUserApiInterface {
|
|
|
44
33
|
encryptProps: 'password'
|
|
45
34
|
});
|
|
46
35
|
|
|
47
|
-
return response
|
|
36
|
+
return response;
|
|
48
37
|
}
|
|
49
38
|
|
|
50
39
|
async register(
|
|
51
40
|
params: UserApiRegisterTransaction['data']
|
|
52
|
-
): Promise<
|
|
41
|
+
): Promise<UserApiRegisterTransaction['response']> {
|
|
53
42
|
const response = await this.client.request<UserApiRegisterTransaction>({
|
|
54
43
|
url: '/user/register',
|
|
55
44
|
method: 'POST',
|
|
@@ -57,15 +46,15 @@ export class AppUserApi implements AppUserApiInterface {
|
|
|
57
46
|
encryptProps: 'password'
|
|
58
47
|
});
|
|
59
48
|
|
|
60
|
-
return response
|
|
49
|
+
return response;
|
|
61
50
|
}
|
|
62
51
|
|
|
63
|
-
async logout(
|
|
64
|
-
|
|
52
|
+
async logout(
|
|
53
|
+
_params?: unknown
|
|
54
|
+
): Promise<UserApiLogoutTransaction['response']> {
|
|
55
|
+
return await this.client.request<UserApiLogoutTransaction>({
|
|
65
56
|
url: '/user/logout',
|
|
66
57
|
method: 'POST'
|
|
67
58
|
});
|
|
68
|
-
|
|
69
|
-
return response.data as AppApiResult<unknown>;
|
|
70
59
|
}
|
|
71
60
|
}
|
|
@@ -9,9 +9,10 @@ import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
|
9
9
|
import { ClientIOCRegister } from './ClientIOCRegister';
|
|
10
10
|
import { appConfig } from '../globals';
|
|
11
11
|
|
|
12
|
-
export class ClientIOC
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
export class ClientIOC implements IOCInterface<
|
|
13
|
+
IOCIdentifierMap,
|
|
14
|
+
IOCContainerInterface
|
|
15
|
+
> {
|
|
15
16
|
protected ioc: IOCFunctionInterface<
|
|
16
17
|
IOCIdentifierMap,
|
|
17
18
|
IOCContainerInterface
|
|
@@ -10,9 +10,10 @@ import type {
|
|
|
10
10
|
IOCRegisterInterface
|
|
11
11
|
} from '@qlover/corekit-bridge';
|
|
12
12
|
|
|
13
|
-
export class ClientIOCRegister
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
export class ClientIOCRegister implements IOCRegisterInterface<
|
|
14
|
+
IOCContainerInterface,
|
|
15
|
+
IocRegisterOptions
|
|
16
|
+
> {
|
|
16
17
|
constructor(protected options: IocRegisterOptions) {}
|
|
17
18
|
|
|
18
19
|
/**
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
|
|
3
3
|
// ! global variables, don't import any dependencies and don't have side effects
|
|
4
|
-
import { ColorFormatter
|
|
4
|
+
import { ColorFormatter } from '@qlover/corekit-bridge';
|
|
5
5
|
import { JSONSerializer } from '@qlover/fe-corekit';
|
|
6
|
+
import { Logger, ConsoleHandler } from '@qlover/logger';
|
|
6
7
|
import { AppConfig } from '@/base/cases/AppConfig';
|
|
7
8
|
import { DialogHandler } from '@/base/cases/DialogHandler';
|
|
8
9
|
import { loggerStyles } from '@config/common';
|
|
@@ -9,9 +9,10 @@ import type { IOCInterface } from '@/base/port/IOCInterface';
|
|
|
9
9
|
import type { IOCIdentifierMapServer } from '@config/IOCIdentifier';
|
|
10
10
|
import { ServerIOCRegister } from './ServerIOCRegister';
|
|
11
11
|
|
|
12
|
-
export class ServerIOC
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
export class ServerIOC implements IOCInterface<
|
|
13
|
+
IOCIdentifierMapServer,
|
|
14
|
+
IOCContainerInterface
|
|
15
|
+
> {
|
|
15
16
|
static instance: ServerIOC | null = null;
|
|
16
17
|
|
|
17
18
|
protected ioc: IOCFunctionInterface<
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ConsoleHandler,
|
|
3
|
-
Logger,
|
|
4
|
-
TimestampFormatter,
|
|
5
2
|
type IOCContainerInterface,
|
|
6
3
|
type IOCManagerInterface,
|
|
7
4
|
type IOCRegisterInterface
|
|
8
5
|
} from '@qlover/corekit-bridge';
|
|
6
|
+
import { Logger, ConsoleHandler, TimestampFormatter } from '@qlover/logger';
|
|
9
7
|
import type { IocRegisterOptions } from '@/base/port/IOCInterface';
|
|
10
8
|
import { SupabaseBridge } from '@/server/sqlBridges/SupabaseBridge';
|
|
11
9
|
import { IOCIdentifier as I } from '@config/IOCIdentifier';
|
|
12
10
|
|
|
13
|
-
export class ServerIOCRegister
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
export class ServerIOCRegister implements IOCRegisterInterface<
|
|
12
|
+
IOCContainerInterface,
|
|
13
|
+
IocRegisterOptions
|
|
14
|
+
> {
|
|
16
15
|
constructor(protected options: IocRegisterOptions) {}
|
|
17
16
|
|
|
18
17
|
/**
|
|
@@ -7,9 +7,7 @@ import type { CrentialTokenInterface } from './port/CrentialTokenInterface';
|
|
|
7
7
|
export type UserCredentialTokenValue = Pick<UserSchema, 'id' | 'email'>;
|
|
8
8
|
|
|
9
9
|
@injectable()
|
|
10
|
-
export class UserCredentialToken
|
|
11
|
-
implements CrentialTokenInterface<UserCredentialTokenValue>
|
|
12
|
-
{
|
|
10
|
+
export class UserCredentialToken implements CrentialTokenInterface<UserCredentialTokenValue> {
|
|
13
11
|
protected jwtSecret: string;
|
|
14
12
|
protected jwtExpiresIn: string;
|
|
15
13
|
|
|
@@ -5,8 +5,7 @@ import type { LinkProps } from 'next/link';
|
|
|
5
5
|
import type { ReactNode } from 'react';
|
|
6
6
|
|
|
7
7
|
interface LocaleLinkProps
|
|
8
|
-
extends Omit<LinkProps, 'href'>,
|
|
9
|
-
React.HTMLAttributes<HTMLAnchorElement> {
|
|
8
|
+
extends Omit<LinkProps, 'href'>, React.HTMLAttributes<HTMLAnchorElement> {
|
|
10
9
|
href:
|
|
11
10
|
| string
|
|
12
11
|
| {
|
|
@@ -28,9 +28,7 @@
|
|
|
28
28
|
"paths": {
|
|
29
29
|
"@/*": ["./src/*"],
|
|
30
30
|
"@config/*": ["./config/*"],
|
|
31
|
-
"@lib/*": ["./lib/*"]
|
|
32
|
-
"@qlover/corekit-bridge": ["../../../corekit-bridge"],
|
|
33
|
-
"@qlover/fe-corekit": ["../../../fe-corekit"]
|
|
31
|
+
"@lib/*": ["./lib/*"]
|
|
34
32
|
}
|
|
35
33
|
},
|
|
36
34
|
"include": ["src", "config"],
|
|
@@ -7,9 +7,7 @@
|
|
|
7
7
|
"@/*": ["./src/*"],
|
|
8
8
|
"@config/*": ["./config/*"],
|
|
9
9
|
"@__tests__/*": ["./__tests__/*"],
|
|
10
|
-
"@__mocks__/*": ["./__tests__/__mocks__/*"]
|
|
11
|
-
"@qlover/corekit-bridge": ["../../../corekit-bridge"],
|
|
12
|
-
"@qlover/fe-corekit": ["../../../fe-corekit"]
|
|
10
|
+
"@__mocks__/*": ["./__tests__/__mocks__/*"]
|
|
13
11
|
}
|
|
14
12
|
},
|
|
15
13
|
"include": ["__tests__/**/*"],
|