{"id":20613993,"url":"https://github.com/evanpatchouli/evp-express-cli","last_synced_at":"2026-04-18T17:36:24.219Z","repository":{"id":176161041,"uuid":"655079055","full_name":"Evanpatchouli/evp-express-cli","owner":"Evanpatchouli","description":"A Express.js CLI to initialize your Express Project interactively with info, log4js, database and so on.","archived":false,"fork":false,"pushed_at":"2025-12-19T17:02:47.000Z","size":235,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-22T06:53:09.082Z","etag":null,"topics":["cli","express","express-cli","nodejs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Evanpatchouli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-06-17T20:23:59.000Z","updated_at":"2025-12-19T17:02:50.000Z","dependencies_parsed_at":"2024-02-11T20:03:30.248Z","dependency_job_id":null,"html_url":"https://github.com/Evanpatchouli/evp-express-cli","commit_stats":null,"previous_names":["evanpatchouli/evp-express-cli"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Evanpatchouli/evp-express-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Evanpatchouli%2Fevp-express-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Evanpatchouli%2Fevp-express-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Evanpatchouli%2Fevp-express-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Evanpatchouli%2Fevp-express-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Evanpatchouli","download_url":"https://codeload.github.com/Evanpatchouli/evp-express-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Evanpatchouli%2Fevp-express-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31978478,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T17:30:12.329Z","status":"ssl_error","status_checked_at":"2026-04-18T17:29:59.069Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","express","express-cli","nodejs"],"created_at":"2024-11-16T11:11:36.368Z","updated_at":"2026-04-18T17:36:24.199Z","avatar_url":"https://github.com/Evanpatchouli.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# evp-express-cli\n\n\u003cp\u003e\n  \u003ca href=\"https://www.npmjs.com/package/evp-express-cli\"\u003e\u003cimg alt=\"npmpackage\" src=\"https://badge.fury.io/js/evp-express-cli.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://nodejs.org/en\"\u003e\u003cimg alt=\"nodejs\" src=\"https://img.shields.io/badge/NodeJS-16.17+-black.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/express\"\u003e\u003cimg alt=\"express\" src=\"https://img.shields.io/badge/Express-4.x-%23007fff.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n[![Security Status](https://www.murphysec.com/platform3/v31/badge/1671461396351311872.svg)](https://www.murphysec.com/console/report/1671461396074487808/1671461396351311872)\n\n\nThe package is a **Express.js CLI** to initialize your Express Project interactively with info, log4js, database and so on.\n\nChange language: [中文文档](./README_CN.md) | [English Doc](./README.md)\n\n## News\n\n**Latest 5 versions reports:**\n\n**v1.2.3**\n1. fix: `knex.js` init\n2. fix: set `express` version to v4.\n\n**v1.2.2**\n1. New feature: `SET PORT=\u003cport number\u003e` before `npm start` is supported\n\n**v1.2.1**\n1. fix config init bug\n2. update `show` command\n\n**v1.2.0**\n1. support TypeScript\n2. provide zod template\n\n**v1.1.1**\n1. provide websocket template\n\n## Documentation\n\n- [Installation](#install)\n- [Usages](#usages)\n  + [command](#command)\n  + [Create new project](#create-new-project)\n  + [Running](#running)\n  + [Templates](#templates)\n    * [Validator](#validator)\n    * [Zod](#zod)\n    * [Database](#database)\n    * [Redis](#redis)\n    * [Auth](#auth)\n    * [RabbitMQ](#rabbitmq)\n    * [Websocket](#websocket)\n    * [SocketIO](#socketio)\n    * [Nacos](#nacos)\n  + [DevTools](#devtools)\n    * [Babel](#babel)\n    * [Esint](#eslint)\n    * [Jest](#jest)\n    * [Pkg](#pkg)\n    * [PM2](#pm2)\n  + [Assets](#assets)\n  + [Config](#config)\n  + [Logger](#logger)\n  + [Response](#response)\n  + [ExHandler](#exhandler)\n  + [TypeScript](#typescript)\n  + [EvpConfig](#evpconfig)\n\n## Install\n\nInstall CLI to local directory\n```shell\nnpm i evp-express-cli\n```\nOr install to global environment\n```shell\nnpm i evp-express-cli -g\n```\n\n## Usages\n\nHere are some examples.\n\n### command\n\n`evp-express`: \n - `-v`, `--version`: show version\n - `-i`, `--info`: show information\n - `-h`, `--help`:  display help for command\n - `new \u003cprojectName\u003e`:  create a new Express.js project with the specified name\n - `start`: start and lauch the project dev server.\n - `clean \u003cpath\u003e`: clean up all files in this path if exists.\n - `add \u003ctemplate\u003e`: add certain template or devtool.\n\n### Create new project\n\nDirectly with npx from npm repository :\n```shell\nnpx evp-express-cli new \u003cprojectName\u003e\n```\nCli locally installed:\n```shell\nnpx evp-express new \u003cprojectName\u003e\n```\nCli globally installed:\n```shell\nevp-express new \u003cprojectName\u003e\n```\n\n### Running\n\nChange directory to your project's root directory, and start running the server with: \nCli locally installed:\n```shell\nnpx evp-express start\n```\nCli globally installed:\n```shell\nevp-express start\n```\nOr just start with npm script:\n```shell\nnpm run start\n```\nOr start with node directly:\n```shell\nnode index\n```\n\n### Tempates\n\n\n#### Validator\n\nvalidator middleware is at /midwares/valider.js\n\nIt exports these midware functions:\n```js\nmodule.exports = {\n  validator,\n  ValidRace,\n  ValidAll,\n  ValidQueue,\n  ValidQueueAll\n}\n```\n- validator is package of \"express-validator\".\n- ValidRace is to valid chains concurrently and throws the fastest one.\n- ValidAll is to valid chains concurrently and throws all result.\n- ValidQueue is to valid chains sequentially and throws the first one.\n- ValidQueueAll is to valid chains sequentially and throws all result.\n\nexample:\n```js\nconst { validator, ValidQueue } = require('../midwares/valider');\n\nrouter.get('/',\n  ValidQueue([\n    validator.query('name').trim().notEmpty().withMessage(\"name cannot be empty\"),\n    validator.query('age').trim()\n      .notEmpty().withMessage(\"age cannot be empty\").bail()\n      .isInt().withMessage(\"age must be Int\").bail().toInt()\n  ]),\n(req, res, next) =\u003e {\n  res.send(`Hello ${req.query.name}, you are ${req.query.age} years old!`);\n});\n```\nAnd you will get response like this:\n```json\n{\n  \"code\":500,\n  \"msg\":\"name cannot be empty\",\n  \"data\":null,\n  \"symbol\":-1,\n  \"type\":\"Bad Request\"\n}\n```\n\n#### Zod\n\nThe Zod template is another validator, you can use both the Zod and Validator. Template provide a midware factory, allow you to check `headers`, `body`, `query`, `params`，and you can use it like this:\n```javascript\nconst { Router } = require('express');\nconst logger = require('../utils/logger');\nconst Resp = require('../model/resp');\nconst { ZodValid } = require('../midwares/zod');\nconst { z } = require('zod');\nconst { Json } = require('../midwares/bodyParser');\n\nconst router = Router();\n\nrouter.get('/', ZodValid({\n  query: z.object({ name: z.string().nonempty(\"name cannot be empty\") })\n}), async (req, res, next) =\u003e {\n  const name = req.query.name;\n  logger.info(`Hello World! ${name}`);\n  res.json(Resp.ok(`Hello World! ${name}`, 1, null));\n});\n\n\nrouter.post('/', Json, ZodValid({\n  body: z.object({ \n    name: z.string().nonempty(\"name cannot be empty\").min(8, \"name at least 8 length\"),\n    pass: z.string().nonempty(\"password cannot be empty\").min(8, \"password at least 8 lenght\"),\n    email: z.string().email(\"email is invalid\") })\n}), async (req, res, next) =\u003e {\n  const name = req.body.name;\n  logger.info(`Hello World! ${name}`);\n  res.json(Resp.ok(`Hello World! ${name}`, 1, null));\n});\n\nmodule.exports = router;\n```\n\n#### Database\n\nThe Database Template use **mysql** as default datasource **mysql2** as default mysql driver and **knex.js** as default sqlClient.\n\nYou can require the knex-sqlClient by `const { sqlClient } = require('utils/knex');`.\n\nYou can change to use any other database, driver and sqlClient. But I strongly **suggest you not** to delete the `utils/knex` because this framework uses it to init the database.\n\nMore about its configuration can be found in config.yaml.\n\n#### Redis\n\nThe Redis Template depends on **redis.js** and does not with auth, if you need it, you can modify the `utils/redisProxy`.\n\nYou can require the redisProxy by `const { instance } = require('utils/redisProxy');`. You can use `instance.client` to get the redis client instance.\n\nMore about its configuration can be found in config.yaml.\n\n#### Auth\n\nThe Auth Template only installs the package **passport.js** and you should customize it by yourself.\n\n#### RabbitMQ\n\nThe RabbitMQ Template depends on **ampqlb.js** and use \"guest:guest\" as default user.\n\nYou can require the future rabbitmqProxy by `const { instance } = require('utils/rabbitmqProxy');`. You can use `instance.conn` to get the RabbitMQ connection.You can use `instance.channel` to get the default channel of RabbitMQ connection.\n\n**Notice that it is a promise**, when imported anywhere else please await in async funtion or then-flow to initialize a var of its instance.\n```javascript\nconst { instance } = require('../utils/rabbitmqProxy');\n\napp.get('/', async(req, res)=\u003e{\nconst rbmqProxy = await instance;\n  const { channel: rbmq } = rbmqProxy;\n  rbmq.sendToQueue(\"queue\", \"hello\");\n})\n```\n**Or like this:**\n```javascript\nconst RabbitmqProxy = require('../utils/rabbitmqProxy');\n\napp.get('/', async(req, res)=\u003e{\n  const rbmqProxy = await RabbitmqProxy.instance;\n  const { channel: rbmq } = rbmqProxy;\n  rbmq.sendToQueue(\"queue\", \"hello\");\n})\n```\n**Or like this:**\n```javascript\nconst amqplib = require('amqplib');\nconst RabbitmqProxy = require('../utils/rabbitmqProxy');\n\n//@type {amqplib.Channel}\nlet rbmq = null;\nRabbitmqProxy.instance.then(rabbitmq=\u003e{\n  rbmq = rabbitmq.channel;\n})\n\napp.get('/', async(req, res)=\u003e{\n  rbmq.sendToQueue(\"queue\", \"hello\");\n})\n```\n\nMore about its configuration can be found in config.yaml.\n\n#### Websocket\n\nThe Websocket Template **ws.js** and mounts Websocket Server on express-http-server.\n\nYour can require wsProxy by `const { instance } = require('utils/wsProxy');`. You can use `instance.server` to get Websocket Server instance。\n\n**Warning:** Do not use WebSocket Template and SocketIO Template together.\n\n#### SocketIO\n\nThe SocketIO Template depends on **socket.io** and mounts SockerIO Server on express-http-server.\n\nYou can require the socketioProxy by `const { instance } = require('utils/socketioProxy');`. You can use `instance.server` to get the SocketIO Server instance.\n\nMore about its configuration can be found in config.yaml.\n\n#### Nacos\n\nThe Nacos Template depends on **nacos.js** and use your project's package.json's name as service name.\n\nYou can require the nacosClient by `const { instance } = require('utils/nacosProxy');`. You can use `instance.client` to get the Nacos Client instance.\n\nMore about its configuration can be found in config.yaml.\n\n### DevTools\n\n#### Babel\n\nThe Babel DevTool only installs basic dependencies and creates a basic babel.config.js file. \n\nYou should customize babel more by yourself.\n\n#### Eslint\n\nThe Eslint DevTool only installs basic dependencies. \n\nYou should customize it more by yourself.\n\n#### Jest\n\nThe Jest DevTool only installs basic dependencies and creates a basic jest.config.js file. Besides, the `package.json's scripts.test` is replaced with \"jest\", you can quickly test by jest with command \"npm test\".\n\nYou can customize jest more by yourself.\n\n#### Pkg\n\nThe Pkg DevTool is for building to a executable exe file. The build output directory is dist.\n\nThe `package.json's scripts.build` is replaced with \"npx pkg . --out-path dist -t node16-win-x64\". You can quickly start build with command \"npm build\". The default target is node16-win-x64, you can modify it in package.json and you should download the target node from github personally commonly.\n\n#### PM2\n\nThe PM2 DevTool is a process manager that driven by node. It creates a basic ecosystem.config.js file.\n\nYou can customize pm2 more by yourself.\n\n### Assets\n\nThe framework use assets as default static resources folder. Please don't change it!\n\n### Config\n\nMost of the configuration are written in assets/config.yaml. And you can get the config by require `global.__config` or `__config`. Or you can get config from config.js by `require('path/to/config.js').get()`.\n\n### logger\n\nlogger tool is at /utils/logger.js\n\n### Response\n\nFramework set a Resp of this：\n```typescript\nclass Resp {\n  ok: boolean;\n  msg: string;\n  data: any;\n  symbol: number;\n  type: string;\n}\n```\nResp provides three builder methods of ok, fail, bad.\n\n### Exhandler\n\nexhandler is at /midwares/exhandler.js\n\nThere are two middlewares: excatcher and exlogger.\n\nExcather catch the exception and try to parse err.message as json string, if successful, it means it's our customized exception, if not, it will treat it as common exception and just return \"System Error\" to request source.\n\nAs said, after catching global errors, the default response is Resp.bad with \"System Error\", if we want more, we can throw a exception by this structure:\n```js\nthrow new Error(\n  JSON.stringify({\n    code: 400,  // exception code\n    msg: \"Invalid arguments.\"  // description\n    symbol: 20000,  // service code or error code if you need it\n    data: {},  // type of data is any\n    back: true,  // whether to return the msg, if not, will return \"System Error\"\n    status: 500, // http status code, default is 200\n  }\n);\n```\nFor some examples:\n```javascript\nthrow new Error(JSON.stringify({code:400,msg:\"Invalid arguments.\"});\n```\nWhen we don't need to retuen the msg, we can give \"false\" to \"back\".\n```javascript\nthrow new Error(JSON.stringify({code:400,msg:\"Invalid arguments.\",back:false});\n```\nThe framework just supports exception code of 200 and 400, but you can customize it more.\n\n### TypeScript\n\nIf you generate evp-express project of TypeScript. There are several things that needed to be noticed:\n\n- **types declaration**\ncli predefined some types for config, exhandler etc in `src/types/index.d.ts`. You can modify and expand it, but before doing this should you know what are you doing and what maybe caused.\n- **npm scripts**\ncli predefined some different scripts from the JavaScript project:\n  * `npm run tsc:build`: execute this to compile your codes to .js to dist directory\n  * `npm run start`: execute this to run the compiled codes in dist directory\n  * `npm run restart`: execute this to compile and then run codes in dist directory\n\n### EvpConfig\n\nsince v1.2.1, in the root directory of project, there will be a `evpconfig.json` file. In it has one option: `lang`, it should be `\"typescript\"` or `\"javascript\"` and same with your project language. It works when you execute command `evp-express add \u003ctemplate\u003e` to judge is your project based on TypeScript or JavaScript.\n\nIn future, there will be more options in it.\n\n---\n\nThanks for using!😊🥰","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevanpatchouli%2Fevp-express-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevanpatchouli%2Fevp-express-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevanpatchouli%2Fevp-express-cli/lists"}