@leo-h/create-nodejs-app 1.0.21 → 1.0.23

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 (47) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/package.json.js +1 -1
  3. package/dist/src/compose-app/replace-content-in-file.compose.js +1 -1
  4. package/dist/src/core/validation.js +1 -1
  5. package/dist/src/validations/back-end-framework.validation.js +1 -0
  6. package/dist/src/validations/front-end-framework.validation.js +1 -0
  7. package/dist/src/validations/project-name-validation.js +1 -1
  8. package/dist/src/validations/template.validation.js +1 -1
  9. package/package.json +1 -1
  10. package/templates/react-vite/.env.example +8 -0
  11. package/templates/react-vite/.husky/pre-commit +1 -0
  12. package/templates/react-vite/.lintstagedrc.json +4 -0
  13. package/templates/react-vite/.prettierignore +7 -0
  14. package/templates/react-vite/.prettierrc.json +6 -0
  15. package/templates/react-vite/eslint.config.js +36 -0
  16. package/templates/react-vite/gitignore +24 -0
  17. package/templates/react-vite/index.html +12 -0
  18. package/templates/react-vite/npmrc +1 -0
  19. package/templates/react-vite/orval.config.ts +51 -0
  20. package/templates/react-vite/package.json +50 -0
  21. package/templates/react-vite/pnpm-lock.yaml +5412 -0
  22. package/templates/react-vite/public/vite.svg +1 -0
  23. package/templates/react-vite/scripts/orval-generate-api-definition.ts +90 -0
  24. package/templates/react-vite/src/@types/routes.ts +24 -0
  25. package/templates/react-vite/src/api/errors/api-error.ts +7 -0
  26. package/templates/react-vite/src/api/errors/api-unexpected-response-error.ts +8 -0
  27. package/templates/react-vite/src/api/swr-fetcher.ts +41 -0
  28. package/templates/react-vite/src/app.tsx +14 -0
  29. package/templates/react-vite/src/env.ts +19 -0
  30. package/templates/react-vite/src/hooks/use-current-route-handle-params.ts +16 -0
  31. package/templates/react-vite/src/index.css +29 -0
  32. package/templates/react-vite/src/lib/zod-i18n-translation-for-end-users.json +103 -0
  33. package/templates/react-vite/src/lib/zod-i18n.ts +20 -0
  34. package/templates/react-vite/src/main.tsx +13 -0
  35. package/templates/react-vite/src/pages/_layouts/app.tsx +17 -0
  36. package/templates/react-vite/src/pages/_layouts/auth.tsx +17 -0
  37. package/templates/react-vite/src/pages/app/dashboard/dashboard.tsx +12 -0
  38. package/templates/react-vite/src/pages/app/dashboard/styles.css +40 -0
  39. package/templates/react-vite/src/pages/auth/sign-in/index.tsx +83 -0
  40. package/templates/react-vite/src/pages/auth/sign-in/styles.css +92 -0
  41. package/templates/react-vite/src/routes.tsx +65 -0
  42. package/templates/react-vite/src/vite-env.d.ts +1 -0
  43. package/templates/react-vite/tsconfig.app.json +32 -0
  44. package/templates/react-vite/tsconfig.json +13 -0
  45. package/templates/react-vite/tsconfig.node.json +24 -0
  46. package/templates/react-vite/vite.config.ts +9 -0
  47. package/dist/src/validations/framework.validation.js +0 -1
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- const index=require("./src/config/index.js"),commander=require("commander"),promises=require("fs/promises"),path=require("path"),picocolors=require("picocolors"),V=require("prompts"),_package=require("./package.json.js"),copyTemplate_compose=require("./src/compose-app/copy-template.compose.js"),replaceContentInFile_compose=require("./src/compose-app/replace-content-in-file.compose.js"),logs=require("./src/utils/logs.js"),onCancel=require("./src/utils/on-cancel.js"),framework_validation=require("./src/validations/framework.validation.js"),packageManager_validation=require("./src/validations/package-manager.validation.js"),projectNameValidation=require("./src/validations/project-name-validation.js"),template_validation=require("./src/validations/template.validation.js"),w=new commander.Command().name(_package.default.name).description(_package.default.description);w.argument("[project-directory]","Name of the project or relative path of the project considering where the script was called.").option("-pm, --package-manager <package-manager>","Package manager that will be used in the project.").option("-t, --template <template-name>","Template that will be used in the project.").option("-f, --framework <framework-name>","Framework that will be used in the project.").action(async(i,o)=>{const r={projectDirectory:{value:i,validation:projectNameValidation.ProjectNameValidation.create({path:i})},packageManager:{value:o.packageManager,validation:packageManager_validation.PackageManagerValidation.create({packageManager:o.packageManager})},template:{value:o.template,validation:template_validation.TemplateValidation.create({template:o.template})},framework:{value:o.framework,validation:framework_validation.FrameworkValidation.create({framework:o.framework})}},s=Object.keys(r);for(const a of s){const t=r[a];t.value&&await t.validation.fromCli()}const{projectDirectory:e,packageManager:l,template:p,framework:n}=r,v=await V([{type:e.value?null:"text",name:"projectDirectory",message:"What is your project name?",validate:async a=>await e.validation.fromPrompt({path:a})},{type:l.value?null:"select",name:"packageManager",message:"What is your favorite package manager?",choices:packageManager_validation.packageManagers,initial:2},{type:!p.value&&!n.value?"select":null,name:"template",message:"Select your template:",choices:template_validation.templates},{type:(a,t)=>!n.value&&(p.value==="api"||t.template==="api")?"select":null,name:"framework",message:"What is your favorite framework?",choices:framework_validation.frameworks}],{onCancel:onCancel.onCancelPrompt});for(const a of s){const t=v[a];t&&(r[a].value=t)}n.value&&(r.template.value="api");const c=path.basename(e.value);e.value=path.resolve(index.GENERATED_APP_TARGET_ROOT_PATH,e.value),await copyTemplate_compose.copyTemplateCompose(e.value,n.value??"clean");const g=path.resolve(e.value,"package.json"),d=path.resolve(e.value,".env.example"),k=path.resolve(e.value,".husky/pre-commit"),m=path.resolve(e.value,"gitignore"),u=path.resolve(e.value,"npmrc");await Promise.all([replaceContentInFile_compose.replaceContentInFileCompose(g,[["app-name",c]]),replaceContentInFile_compose.replaceContentInFileCompose(d,[["app-name",c]]),replaceContentInFile_compose.replaceContentInFileCompose(k,[["pnpm",l.value]]),promises.rename(m,path.resolve(path.dirname(m),".gitignore")),promises.rename(u,path.resolve(path.dirname(u),".npmrc"))]),logs.successLog(`Success in creating new app ${picocolors.cyan(c)}!`,`> ${e.value}`)});(async()=>await w.parseAsync(process.argv))();
2
+ const index=require("./src/config/index.js"),commander=require("commander"),promises=require("fs/promises"),path=require("path"),picocolors=require("picocolors"),M=require("prompts"),_package=require("./package.json.js"),copyTemplate_compose=require("./src/compose-app/copy-template.compose.js"),replaceContentInFile_compose=require("./src/compose-app/replace-content-in-file.compose.js"),logs=require("./src/utils/logs.js"),onCancel=require("./src/utils/on-cancel.js"),backEndFramework_validation=require("./src/validations/back-end-framework.validation.js"),frontEndFramework_validation=require("./src/validations/front-end-framework.validation.js"),packageManager_validation=require("./src/validations/package-manager.validation.js"),projectNameValidation=require("./src/validations/project-name-validation.js"),template_validation=require("./src/validations/template.validation.js"),C=new commander.Command().name(_package.default.name).description(_package.default.description);C.argument("[project-directory]","Name of the project or relative path of the project considering where the script was called.").option("-pm, --package-manager <package-manager>","Package manager that will be used in the project.").option("-t, --template <template-name>","Template that will be used in the project.").option("-f, --framework <framework-name>","Framework that will be used in the project.").action(async(c,r)=>{const t={projectDirectory:{value:c,validation:projectNameValidation.ProjectNameValidation.create({path:c})},packageManager:{value:r.packageManager,validation:packageManager_validation.PackageManagerValidation.create({packageManager:r.packageManager})},template:{value:r.template,validation:template_validation.TemplateValidation.create({template:r.template})},framework:{value:r.framework,validation:r.template==="api"?backEndFramework_validation.BackEndFrameworkValidation.create({framework:r.framework}):r.template==="front-end"?frontEndFramework_validation.FrontEndFrameworkValidation.create({framework:r.framework}):null}},l=Object.keys(t);for(const o of l){const a=t[o];!a.value||!a.validation||await a.validation.fromCli()}const{projectDirectory:e,packageManager:s,template:p,framework:n}=t,v=await M([{type:e.value?null:"text",name:"projectDirectory",message:"What is your project name?",validate:async o=>await e.validation?.fromPrompt({path:o})??!0},{type:s.value?null:"select",name:"packageManager",message:"What is your favorite package manager?",choices:packageManager_validation.packageManagers,initial:2},{type:!p.value&&!n.value?"select":null,name:"template",message:"Select your template:",choices:template_validation.templates},{type:(o,a)=>{const d=["api","front-end"];return!n.value&&(d.includes(p.value)||d.includes(a.template))?"select":null},name:"framework",message:"What is your favorite framework?",choices:(o,a)=>a.template==="api"?backEndFramework_validation.backEndFrameworks:a.template==="front-end"?frontEndFramework_validation.frontEndFrameworks:[...backEndFramework_validation.backEndFrameworks,...frontEndFramework_validation.frontEndFrameworks]}],{onCancel:onCancel.onCancelPrompt});for(const o of l){const a=v[o];a&&(t[o].value=a)}n.value&&(t.template.value="api");const i=path.basename(e.value);e.value=path.resolve(index.GENERATED_APP_TARGET_ROOT_PATH,e.value),await copyTemplate_compose.copyTemplateCompose(e.value,n.value??"clean");const g=path.resolve(e.value,"package.json"),k=path.resolve(e.value,".env.example"),f=path.resolve(e.value,".husky/pre-commit"),m=path.resolve(e.value,"gitignore"),u=path.resolve(e.value,"npmrc");await Promise.all([replaceContentInFile_compose.replaceContentInFileCompose(g,[["app-name",i]]),replaceContentInFile_compose.replaceContentInFileCompose(k,[["app-name",i]]),replaceContentInFile_compose.replaceContentInFileCompose(f,[["pnpm",s.value]]),promises.rename(m,path.resolve(path.dirname(m),".gitignore")),promises.rename(u,path.resolve(path.dirname(u),".npmrc"))]),logs.successLog(`Success in creating new app ${picocolors.cyan(i)}!`,`> ${e.value}`)});(async()=>await C.parseAsync(process.argv))();
@@ -1 +1 @@
1
- Object.defineProperty(exports,"__esModule",{value:!0});const name="@leo-h/create-nodejs-app",version="1.0.21",packageManager="pnpm@9.15.0",author="Leonardo Henrique <leonardo0507.business@gmail.com>",description="Create a modern Node.js app with TypeScript using one command.",license="MIT",keywords=["node","node.js","typescript"],bin={"create-nodejs-app":"./dist/index.js"},files=["./dist","./templates"],repository={type:"git",url:"https://github.com/Leo-Henrique/create-nodejs-app"},scripts={start:"node ./dist/index.js","start:dev":"tsx --env-file=.env.development ./src/index.ts","start:dev:watch":"tsx --env-file=.env.development watch ./src/index.ts",typecheck:"tsc --noEmit",lint:"eslint . --max-warnings 0 --cache","lint:fix":"pnpm lint --fix",format:"prettier . --write --cache","test:unit":"vitest run","test:unit:watch":"vitest","test:e2e":"vitest run --config ./vitest.config.e2e.mts","test:e2e:watch":"vitest --config ./vitest.config.e2e.mts","test:coverage":"vitest run --coverage.enabled=true",template:"tsx --env-file=.env.development ./scripts/template-cli.ts",prebuild:"rimraf ./dist",build:"unbuild",prepublishOnly:"pnpm build"},dependencies={commander:"12.1.0",picocolors:"1.1.1",prompts:"2.4.2","validate-npm-package-name":"5.0.1",zod:"3.24.1"},devDependencies={"@eslint/js":"9.17.0","@faker-js/faker":"9.3.0","@types/node":"22.10.2","@types/prompts":"2.4.9","@types/validate-npm-package-name":"4.0.2","@vitest/eslint-plugin":"1.1.18","conventional-changelog-conventionalcommits":"8.0.0",eslint:"9.17.0","eslint-config-prettier":"9.1.0",globals:"15.14.0",husky:"9.1.7","lint-staged":"15.2.11",prettier:"3.4.2",rimraf:"6.0.1",tsx:"4.19.2",typescript:"5.7.2","typescript-eslint":"8.18.1",unbuild:"2.0.0","vite-tsconfig-paths":"4.3.2",vitest:"1.6.0"},d={name,version,packageManager,author,description,license,keywords,bin,files,repository,scripts,dependencies,devDependencies};exports.author=author;exports.bin=bin;exports.default=d;exports.dependencies=dependencies;exports.description=description;exports.devDependencies=devDependencies;exports.files=files;exports.keywords=keywords;exports.license=license;exports.name=name;exports.packageManager=packageManager;exports.repository=repository;exports.scripts=scripts;exports.version=version;
1
+ Object.defineProperty(exports,"__esModule",{value:!0});const name="@leo-h/create-nodejs-app",version="1.0.23",packageManager="pnpm@9.15.0",author="Leonardo Henrique <leonardo0507.business@gmail.com>",description="Create a modern Node.js app with TypeScript using one command.",license="MIT",keywords=["node","node.js","typescript"],bin={"create-nodejs-app":"./dist/index.js"},files=["./dist","./templates"],repository={type:"git",url:"https://github.com/Leo-Henrique/create-nodejs-app"},scripts={start:"node ./dist/index.js","start:dev":"tsx --env-file=.env.development ./src/index.ts","start:dev:watch":"tsx --env-file=.env.development watch ./src/index.ts",typecheck:"tsc --noEmit",lint:"eslint . --max-warnings 0 --cache","lint:fix":"pnpm lint --fix",format:"prettier . --write --cache","test:unit":"vitest run","test:unit:watch":"vitest","test:e2e":"vitest run --config ./vitest.config.e2e.mts","test:e2e:watch":"vitest --config ./vitest.config.e2e.mts","test:coverage":"vitest run --coverage.enabled=true",template:"tsx --env-file=.env.development ./scripts/template-cli.ts",prebuild:"rimraf ./dist",build:"unbuild",prepublishOnly:"pnpm build"},dependencies={commander:"12.1.0",picocolors:"1.1.1",prompts:"2.4.2","validate-npm-package-name":"5.0.1",zod:"3.24.1"},devDependencies={"@eslint/js":"9.17.0","@faker-js/faker":"9.3.0","@types/node":"22.10.2","@types/prompts":"2.4.9","@types/validate-npm-package-name":"4.0.2","@vitest/eslint-plugin":"1.1.18","conventional-changelog-conventionalcommits":"8.0.0",eslint:"9.17.0","eslint-config-prettier":"9.1.0",globals:"15.14.0",husky:"9.1.7","lint-staged":"15.2.11",prettier:"3.4.2",rimraf:"6.0.1",tsx:"4.19.2",typescript:"5.7.2","typescript-eslint":"8.18.1",unbuild:"2.0.0","vite-tsconfig-paths":"4.3.2",vitest:"1.6.0"},w={name,version,packageManager,author,description,license,keywords,bin,files,repository,scripts,dependencies,devDependencies};exports.author=author;exports.bin=bin;exports.default=w;exports.dependencies=dependencies;exports.description=description;exports.devDependencies=devDependencies;exports.files=files;exports.keywords=keywords;exports.license=license;exports.name=name;exports.packageManager=packageManager;exports.repository=repository;exports.scripts=scripts;exports.version=version;
@@ -1 +1 @@
1
- const promises=require("fs/promises");async function replaceContentInFileCompose(o,i){let e=await promises.readFile(o,"utf-8");for(const[t,n]of i)e=e.replaceAll(t,n);await promises.writeFile(o,e)}exports.replaceContentInFileCompose=replaceContentInFileCompose;
1
+ const fs=require("fs"),promises=require("fs/promises");async function replaceContentInFileCompose(e,o){if(!fs.existsSync(e))return;let t=await promises.readFile(e,"utf-8");for(const[s,i]of o)t=t.replaceAll(s,i);await promises.writeFile(e,t)}exports.replaceContentInFileCompose=replaceContentInFileCompose;
@@ -1 +1 @@
1
- const left=require("../utils/left.js");var r=Object.defineProperty,e=(a,t,i)=>t in a?r(a,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):a[t]=i,s=(a,t,i)=>(e(a,typeof t!="symbol"?t+"":t,i),i);class Validation{constructor(){s(this,"params")}createValidation(t){return t&&(this.params=t),this}async fromCli(t){t&&(this.params=t);const i=await this.validate();if(!i.isValid)return left.left(i.issue)}async fromPrompt(t){t&&(this.params=t);const i=await this.validate();return i.isValid?!0:i.issue}}exports.Validation=Validation;
1
+ const left=require("../utils/left.js");var e=Object.defineProperty,r=(a,t,i)=>t in a?e(a,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):a[t]=i,s=(a,t,i)=>(r(a,typeof t!="symbol"?t+"":t,i),i);class Validation{constructor(){s(this,"params")}createValidation(t){return t&&(this.params=t),this}async fromCli(t){t&&(this.params=t);const i=await this.validate();if(!i.isValid)return left.left(i.issue)}async fromPrompt(t){t&&(this.params=t);const i=await this.validate();return i.isValid?!0:i.issue}}exports.Validation=Validation;
@@ -0,0 +1 @@
1
+ const validation=require("../core/validation.js"),getValidOptionsFromPrompt=require("../utils/get-valid-options-from-prompt.js"),backEndFrameworks=[{title:"Fastify",value:"fastify"},{title:"Nest + SWC",value:"nest"},{title:"tRPC",value:"trpc",disabled:!0}],backEndValidFrameworks=getValidOptionsFromPrompt.getValidOptionsFromSelect(backEndFrameworks);class BackEndFrameworkValidation extends validation.Validation{static create(a){return new this().createValidation(a)}async validate(){let{framework:a}=this.params;return a=a.toLowerCase(),backEndValidFrameworks.includes(a)?{isValid:!0}:{isValid:!1,issue:`Invalid back-end framework, consider the options: ${backEndValidFrameworks.map(e=>`"${e}"`).join(", ")}.`}}}exports.BackEndFrameworkValidation=BackEndFrameworkValidation;exports.backEndFrameworks=backEndFrameworks;exports.backEndValidFrameworks=backEndValidFrameworks;
@@ -0,0 +1 @@
1
+ const validation=require("../core/validation.js"),getValidOptionsFromPrompt=require("../utils/get-valid-options-from-prompt.js"),frontEndFrameworks=[{title:"React + Vite (includes: React Router v7, SWR + Orval, React Hook Form + Zod)",value:"react-vite"},{title:"Next.js",value:"next",disabled:!0}],frontEndValidFrameworks=getValidOptionsFromPrompt.getValidOptionsFromSelect(frontEndFrameworks);class FrontEndFrameworkValidation extends validation.Validation{static create(t){return new this().createValidation(t)}async validate(){let{framework:t}=this.params;return t=t.toLowerCase(),frontEndValidFrameworks.includes(t)?{isValid:!0}:{isValid:!1,issue:`Invalid front-end framework, consider the options: ${frontEndValidFrameworks.map(e=>`"${e}"`).join(", ")}.`}}}exports.FrontEndFrameworkValidation=FrontEndFrameworkValidation;exports.frontEndFrameworks=frontEndFrameworks;exports.frontEndValidFrameworks=frontEndValidFrameworks;
@@ -1 +1 @@
1
- const index=require("../config/index.js"),validation=require("../core/validation.js"),capitalizeFirstWord=require("../utils/capitalize-first-word.js"),fs=require("fs"),promises=require("fs/promises"),path=require("path"),c=require("validate-npm-package-name");class ProjectNameValidation extends validation.Validation{static create(e){return new this().createValidation(e)}async validate(){const{path:e}=this.params,i=path.basename(e),a=path.resolve(index.GENERATED_APP_TARGET_ROOT_PATH,e);if(fs.existsSync(a)&&(await promises.readdir(a)).includes(i))return{isValid:!1,issue:`Folder with name "${i}" already exists in project directory.`};const s=c(i);return s.validForNewPackages?{isValid:!0}:{isValid:!1,issue:capitalizeFirstWord.capitalizeFirstWord(s.errors[0])}}}exports.ProjectNameValidation=ProjectNameValidation;
1
+ const index=require("../config/index.js"),validation=require("../core/validation.js"),capitalizeFirstWord=require("../utils/capitalize-first-word.js"),fs=require("fs"),promises=require("fs/promises"),path=require("path"),p=require("validate-npm-package-name");class ProjectNameValidation extends validation.Validation{static create(e){return new this().createValidation(e)}async validate(){const{path:e}=this.params,i=path.basename(e),a=path.resolve(index.GENERATED_APP_TARGET_ROOT_PATH,e);if(fs.existsSync(a)&&(await promises.readdir(a)).includes(i))return{isValid:!1,issue:`Folder with name "${i}" already exists in project directory.`};const r=p(i);if(!r.validForNewPackages){const s=r.errors?.[0];return{isValid:!1,issue:s?capitalizeFirstWord.capitalizeFirstWord(s):"Invalid name for unknown reason. Try another name."}}return{isValid:!0}}}exports.ProjectNameValidation=ProjectNameValidation;
@@ -1 +1 @@
1
- const validation=require("../core/validation.js"),getValidOptionsFromPrompt=require("../utils/get-valid-options-from-prompt.js"),templates=[{title:"Clean",value:"clean"},{title:"API",value:"api"}],validTemplates=getValidOptionsFromPrompt.getValidOptionsFromSelect(templates);class TemplateValidation extends validation.Validation{static create(e){return new this().createValidation(e)}async validate(){let{template:e}=this.params;return e=e.toLowerCase(),validTemplates.includes(e)?{isValid:!0}:{isValid:!1,issue:`Invalid template, consider the options: ${validTemplates.map(t=>`"${t}"`).join(", ")}.`}}}exports.TemplateValidation=TemplateValidation;exports.templates=templates;exports.validTemplates=validTemplates;
1
+ const validation=require("../core/validation.js"),getValidOptionsFromPrompt=require("../utils/get-valid-options-from-prompt.js"),templates=[{title:"Clean",value:"clean"},{title:"API",value:"api"},{title:"Front-end",value:"front-end"}],validTemplates=getValidOptionsFromPrompt.getValidOptionsFromSelect(templates);class TemplateValidation extends validation.Validation{static create(e){return new this().createValidation(e)}async validate(){let{template:e}=this.params;return e=e.toLowerCase(),validTemplates.includes(e)?{isValid:!0}:{isValid:!1,issue:`Invalid template, consider the options: ${validTemplates.map(t=>`"${t}"`).join(", ")}.`}}}exports.TemplateValidation=TemplateValidation;exports.templates=templates;exports.validTemplates=validTemplates;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leo-h/create-nodejs-app",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "packageManager": "pnpm@9.15.0",
5
5
  "author": "Leonardo Henrique <leonardo0507.business@gmail.com>",
6
6
  "description": "Create a modern Node.js app with TypeScript using one command.",
@@ -0,0 +1,8 @@
1
+ # example: "app-name"
2
+ APP_NAME=
3
+
4
+ # example: "http://localhost:3333"
5
+ APP_API_BASE_URL=
6
+
7
+ # example: "http://localhost:3333/docs/json"
8
+ API_JSON_DOCS_URL=
@@ -0,0 +1 @@
1
+ pnpm lint-staged
@@ -0,0 +1,4 @@
1
+ {
2
+ "*.{js,jsx,ts,tsx,css,scss,html,json,yaml,yml,md}": "prettier --write --cache",
3
+ "*.{js,jsx,ts,tsx}": ["eslint --max-warnings 0 --fix --cache"]
4
+ }
@@ -0,0 +1,7 @@
1
+ node_modules
2
+ package-lock.json
3
+ yarn.lock
4
+ pnpm-lock.yaml
5
+ .husky
6
+ coverage
7
+ dist
@@ -0,0 +1,6 @@
1
+ {
2
+ "arrowParens": "avoid",
3
+ "semi": true,
4
+ "singleQuote": false,
5
+ "tabWidth": 2
6
+ }
@@ -0,0 +1,36 @@
1
+ import js from "@eslint/js";
2
+ import prettierEslint from "eslint-config-prettier";
3
+ import reactHooks from "eslint-plugin-react-hooks";
4
+ import reactRefresh from "eslint-plugin-react-refresh";
5
+ import globals from "globals";
6
+ import typescriptEslint from "typescript-eslint";
7
+
8
+ export default typescriptEslint.config(
9
+ {
10
+ ignores: ["dist", "src/api/orval"],
11
+ },
12
+ {
13
+ extends: [
14
+ js.configs.recommended,
15
+ ...typescriptEslint.configs.recommended,
16
+ prettierEslint,
17
+ ],
18
+ files: ["**/*.{ts,tsx}"],
19
+ languageOptions: {
20
+ ecmaVersion: 2020,
21
+ globals: globals.browser,
22
+ },
23
+ plugins: {
24
+ "react-hooks": reactHooks,
25
+ "react-refresh": reactRefresh,
26
+ },
27
+ rules: {
28
+ ...reactHooks.configs.recommended.rules,
29
+ "react-refresh/only-export-components": [
30
+ "warn",
31
+ { allowConstantExport: true },
32
+ ],
33
+ "@typescript-eslint/no-unused-vars": "warn",
34
+ },
35
+ },
36
+ );
@@ -0,0 +1,24 @@
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ pnpm-debug.log*
8
+ lerna-debug.log*
9
+
10
+ node_modules
11
+ dist
12
+ dist-ssr
13
+ *.local
14
+
15
+ # Editor directories and files
16
+ .vscode/*
17
+ !.vscode/extensions.json
18
+ .idea
19
+ .DS_Store
20
+ *.suo
21
+ *.ntvs*
22
+ *.njsproj
23
+ *.sln
24
+ *.sw?
@@ -0,0 +1,12 @@
1
+ <html lang="pt-BR">
2
+ <head>
3
+ <meta charset="UTF-8" />
4
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ </head>
7
+
8
+ <body>
9
+ <div id="root"></div>
10
+ <script type="module" src="/src/main.tsx"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1 @@
1
+ save-exact=true
@@ -0,0 +1,51 @@
1
+ import { defineConfig } from "orval";
2
+ import { OrvalCustomConfig } from "./scripts/orval-generate-api-definition";
3
+
4
+ export const orvalCustomConfig: OrvalCustomConfig = {
5
+ apiDocs: {
6
+ outputPath: "./src/api/docs.json",
7
+ },
8
+ endpoints: {
9
+ outputPath: "./src/api/orval/endpoints",
10
+ replaceVoidTypeToAnyOnResponse: true,
11
+ },
12
+ zodSchemas: {
13
+ outputPath: "./src/api/orval/schemas",
14
+ },
15
+ };
16
+
17
+ export default defineConfig({
18
+ api: {
19
+ input: orvalCustomConfig.apiDocs.outputPath,
20
+ output: {
21
+ target: orvalCustomConfig.endpoints.outputPath,
22
+ client: "swr",
23
+ httpClient: "fetch",
24
+ baseUrl: new URL(process.env.APP_API_BASE_URL!).toString(),
25
+ mode: "tags",
26
+ clean: true,
27
+ override: {
28
+ mutator: {
29
+ path: "./src/api/swr-fetcher.ts",
30
+ name: "swrFetcher",
31
+ },
32
+ swr: {
33
+ swrOptions: {
34
+ errorRetryCount: 3,
35
+ errorRetryInterval: 3500,
36
+ revalidateOnFocus: false,
37
+ },
38
+ },
39
+ },
40
+ },
41
+ },
42
+ apiZod: {
43
+ input: orvalCustomConfig.apiDocs.outputPath,
44
+ output: {
45
+ target: orvalCustomConfig.zodSchemas.outputPath,
46
+ client: "zod",
47
+ mode: "tags",
48
+ clean: true,
49
+ },
50
+ },
51
+ });
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "app-name",
3
+ "private": true,
4
+ "version": "1.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "prepare": "husky",
8
+ "start:dev": "vite",
9
+ "typecheck": "tsc --noEmit",
10
+ "lint": "eslint . --max-warnings 0 --cache",
11
+ "lint:fix": "pnpm lint --fix",
12
+ "format": "prettier . --write --cache",
13
+ "build": "tsc -b && vite build",
14
+ "preview": "vite preview",
15
+ "orval:generate": "tsx --env-file=.env ./scripts/orval-generate-api-definition.ts"
16
+ },
17
+ "dependencies": {
18
+ "@hookform/resolvers": "3.10.0",
19
+ "i18next": "24.2.1",
20
+ "react": "18.3.1",
21
+ "react-dom": "18.3.1",
22
+ "react-helmet-async": "2.0.5",
23
+ "react-hook-form": "7.54.2",
24
+ "react-router": "7.1.1",
25
+ "swr": "2.3.0",
26
+ "zod": "3.24.1",
27
+ "zod-i18n-map": "2.27.0"
28
+ },
29
+ "devDependencies": {
30
+ "@eslint/js": "9.17.0",
31
+ "@types/react": "18.3.18",
32
+ "@types/react-dom": "18.3.5",
33
+ "@vitejs/plugin-react": "4.3.4",
34
+ "eslint": "9.17.0",
35
+ "eslint-config-prettier": "9.1.0",
36
+ "eslint-plugin-react-hooks": "5.0.0",
37
+ "eslint-plugin-react-refresh": "0.4.16",
38
+ "globals": "15.14.0",
39
+ "husky": "9.1.7",
40
+ "lint-staged": "15.3.0",
41
+ "orval": "7.4.1",
42
+ "prettier": "3.4.2",
43
+ "tsx": "4.19.2",
44
+ "type-fest": "4.32.0",
45
+ "typescript": "~5.6.2",
46
+ "typescript-eslint": "8.18.2",
47
+ "vite": "6.0.7",
48
+ "vite-tsconfig-paths": "5.1.3"
49
+ }
50
+ }