nodejs-quickstart-structure 1.7.5 โ 1.8.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 +22 -0
- package/README.md +2 -2
- package/docs/generateCase.md +1 -0
- package/docs/generatorFlow.md +5 -1
- package/docs/ruleDevelop.md +25 -0
- package/lib/modules/config-files.js +6 -2
- package/lib/prompts.js +1 -1
- package/package.json +1 -1
- package/templates/common/.gitlab-ci.yml.ejs +35 -0
- package/templates/common/README.md.ejs +9 -1
- package/templates/common/eslint.config.mjs.ejs +41 -0
- package/templates/common/package.json.ejs +22 -19
- package/templates/common/.eslintrc.json.ejs +0 -26
- /package/templates/clean-architecture/js/src/interfaces/controllers/{UserController.js โ userController.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,28 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.8.1] - 2026-02-22
|
|
9
|
+
### Security
|
|
10
|
+
- Resolved all high-severity npm vulnerabilities (0 vulnerabilities detected on install).
|
|
11
|
+
- Upgraded ESLint to v9 and `typescript-eslint` to v8, migrating generated templates from `.eslintrc.json` to Flat Config (`eslint.config.mjs`) to eliminate deprecated `eslint@8` transitive dependencies.
|
|
12
|
+
- Upgraded `supertest` to v7, `rimraf` to v6, and `ejs` to v3.1.10.
|
|
13
|
+
- Replaced vulnerable `copyfiles` dependency with `cpx2` for view template orchestration.
|
|
14
|
+
- Configured npm `overrides` for `minimatch@^10.2.1` to patch outdated `jest` sub-dependencies without breaking the test runner.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- Fixed `npm install` crashing due to `husky install` expecting an initialized `.git` directory by adding a graceful fallback wrapper.
|
|
18
|
+
|
|
19
|
+
## [1.8.0] - 2026-02-18
|
|
20
|
+
### Added
|
|
21
|
+
- Introduced **GitLab CI/CD pipeline support**:
|
|
22
|
+
- Preconfigured `.gitlab-ci.yml` for automated build, test, and deploy steps.
|
|
23
|
+
- End-to-end (e2e) test job included to ensure project reliability.
|
|
24
|
+
- Aligns with existing GitHub Actions and Jenkins workflows for consistent CI/CD coverage.
|
|
25
|
+
|
|
26
|
+
### Improved
|
|
27
|
+
- Documentation updated to highlight GitLab CI/CD as a supported option.
|
|
28
|
+
- Enhanced CI/CD setup instructions in `README.md` for multi-platform pipelines.
|
|
29
|
+
|
|
8
30
|
## [1.7.5] - 2026-02-17
|
|
9
31
|
> Happy Lunar New Year! This release coincides with Tet Vietnam. ๐
|
|
10
32
|
### Fixed
|
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ We don't just generate boilerplate; we generate **production-ready** foundations
|
|
|
25
25
|
- **๐ Code Quality**: Pre-configured `Eslint` and `Prettier` for consistent coding standards.
|
|
26
26
|
- **๐ก๏ธ Security**: Built-in `Helmet`, `HPP`, `CORS`, and Rate-Limiting middleware.
|
|
27
27
|
- **๐งช Testing Strategy**: Integrated `Jest` and `Supertest` setup for Unit and Integration testing.
|
|
28
|
-
- **๐ CI/CD
|
|
28
|
+
- **๐ CI/CD Integration**: Pre-configured workflows for **GitHub Actions**, **Jenkins**, and **GitLab CI**.
|
|
29
29
|
- **โ Git Hooks**: `Husky` and `Lint-Staged` to ensure no bad code is ever committed.
|
|
30
30
|
- **๐ณ DevOps**: Highly optimized **Multi-Stage Dockerfile** for small, secure production images.
|
|
31
31
|
|
|
@@ -68,7 +68,7 @@ The CLI will guide you through the following steps:
|
|
|
68
68
|
5. **Database Name**: The name of the initial database.
|
|
69
69
|
6. **Communication**: `REST APIs` (default) or `Kafka`.
|
|
70
70
|
7. **Caching**: `Redis` or `None`.
|
|
71
|
-
8. **CI/CD**: `GitHub Actions`, `Jenkins`, or `None`.
|
|
71
|
+
8. **CI/CD**: `GitHub Actions`, `Jenkins`, `GitLab CI` or `None`.
|
|
72
72
|
|
|
73
73
|
## Generated Project Structure
|
|
74
74
|
|
package/docs/generateCase.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
This document lists the **112 possible project combinations** supported by the `nodejs-quickstart` CLI. These combinations cover all supported languages, architectures, databases, communication patterns, and caching options.
|
|
4
4
|
|
|
5
5
|
## Summary
|
|
6
|
+
- **CI Providers**: `None`, `GitHub Actions`, `Jenkins`, `GitLab CI`
|
|
6
7
|
- **MVC Architecture**: 84 Combinations
|
|
7
8
|
- **With Database (36)**: 2 Lang ร 3 View ร 3 DB ร 2 Comm = 36 * 2 (Caching: None/Redis) = 72
|
|
8
9
|
- **No Database (12)**: 2 Lang ร 3 View ร 1 DB ร 2 Comm = 12 * 1 (Caching: None) = 12
|
package/docs/generatorFlow.md
CHANGED
|
@@ -90,7 +90,11 @@ The `generateProject` function in `lib/generator.js` executes the following step
|
|
|
90
90
|
16. **Test Setup**:
|
|
91
91
|
* Generates `jest.config.js` and a sample `health.test.{js|ts}`.
|
|
92
92
|
17. **CI/CD Setup**:
|
|
93
|
-
*
|
|
93
|
+
* Helper: `setupCiCd`
|
|
94
|
+
* Checks `config.ciProvider`:
|
|
95
|
+
* **GitHub Actions**: Copies `.github/workflows/ci.yml`.
|
|
96
|
+
* **Jenkins**: Renders `Jenkinsfile`.
|
|
97
|
+
* **GitLab CI**: Renders `.gitlab-ci.yml` if selected.
|
|
94
98
|
|
|
95
99
|
## 4. TypeScript vs JavaScript Generation Steps
|
|
96
100
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Development Rules & Conventions
|
|
2
|
+
|
|
3
|
+
## General Standards
|
|
4
|
+
|
|
5
|
+
### File Naming
|
|
6
|
+
- **Controllers**: Use camelCase (e.g., `kafkaController.ts`, `userController.ts`).
|
|
7
|
+
- **Services**: Use camelCase (e.g., `kafkaService.ts`, `userService.ts`) or PascalCase depending on export type. Class-based services should generally match class name.
|
|
8
|
+
- **Routes**: Use camelCase (e.g., `userRoutes.ts`, `kafkaRoutes.ts`).
|
|
9
|
+
- **Utilities**: Use camelCase (e.g., `httpCodes.ts`).
|
|
10
|
+
|
|
11
|
+
### Code Style
|
|
12
|
+
- **Status Codes**: ALWAYS use `HTTP_STATUS` constants from `@/utils/httpCodes` (TS) or `../../utils/httpCodes.js` (JS) instead of hardcoded numbers.
|
|
13
|
+
- Good: `res.status(HTTP_STATUS.OK).json(...)`
|
|
14
|
+
- Bad: `res.status(200).json(...)`
|
|
15
|
+
- **Imports**:
|
|
16
|
+
- **TypeScript**: Use path aliases (e.g., `@/services/...`, `@/utils/...`) instead of relative paths (e.g., `../../utils/...`).
|
|
17
|
+
- **JavaScript**: Use relative paths as configured by the project structure.
|
|
18
|
+
|
|
19
|
+
### API Response Structure
|
|
20
|
+
- Success: `{ status: string, data: any }` or direct JSON object.
|
|
21
|
+
- Error: `{ error: string }`
|
|
22
|
+
|
|
23
|
+
## Git Workflow
|
|
24
|
+
- Commit messages should be descriptive.
|
|
25
|
+
- Ensure all tests pass before pushing.
|
|
@@ -60,9 +60,9 @@ export const renderDockerfile = async (templatesDir, targetDir, config) => {
|
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
export const renderProfessionalConfig = async (templatesDir, targetDir, language) => {
|
|
63
|
-
const eslintTemplate = await fs.readFile(path.join(templatesDir, 'common', '.
|
|
63
|
+
const eslintTemplate = await fs.readFile(path.join(templatesDir, 'common', 'eslint.config.mjs.ejs'), 'utf-8');
|
|
64
64
|
const eslintContent = ejs.render(eslintTemplate, { language });
|
|
65
|
-
await fs.writeFile(path.join(targetDir, '.
|
|
65
|
+
await fs.writeFile(path.join(targetDir, 'eslint.config.mjs'), eslintContent);
|
|
66
66
|
|
|
67
67
|
await fs.copy(path.join(templatesDir, 'common', '.prettierrc'), path.join(targetDir, '.prettierrc'));
|
|
68
68
|
await fs.copy(path.join(templatesDir, 'common', '.lintstagedrc'), path.join(targetDir, '.lintstagedrc'));
|
|
@@ -81,6 +81,10 @@ export const setupCiCd = async (templatesDir, targetDir, config) => {
|
|
|
81
81
|
const jenkinsTemplate = await fs.readFile(path.join(templatesDir, 'common', 'Jenkinsfile.ejs'), 'utf-8');
|
|
82
82
|
const jenkinsContent = ejs.render(jenkinsTemplate, { projectName });
|
|
83
83
|
await fs.writeFile(path.join(targetDir, 'Jenkinsfile'), jenkinsContent);
|
|
84
|
+
} else if (ciProvider === 'GitLab CI') {
|
|
85
|
+
const gitlabTemplate = await fs.readFile(path.join(templatesDir, 'common', '.gitlab-ci.yml.ejs'), 'utf-8');
|
|
86
|
+
const gitlabContent = ejs.render(gitlabTemplate, { projectName });
|
|
87
|
+
await fs.writeFile(path.join(targetDir, '.gitlab-ci.yml'), gitlabContent);
|
|
84
88
|
}
|
|
85
89
|
};
|
|
86
90
|
|
package/lib/prompts.js
CHANGED
|
@@ -74,7 +74,7 @@ export const getProjectDetails = async (options = {}) => {
|
|
|
74
74
|
type: 'list',
|
|
75
75
|
name: 'ciProvider',
|
|
76
76
|
message: 'Select CI/CD Provider:',
|
|
77
|
-
choices: ['None', 'GitHub Actions', 'Jenkins'],
|
|
77
|
+
choices: ['None', 'GitHub Actions', 'Jenkins', 'GitLab CI'],
|
|
78
78
|
default: 'None',
|
|
79
79
|
when: !options.ciProvider
|
|
80
80
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
variables:
|
|
2
|
+
NODE_ENV: 'test'
|
|
3
|
+
|
|
4
|
+
stages:
|
|
5
|
+
- lint
|
|
6
|
+
- test
|
|
7
|
+
- build
|
|
8
|
+
|
|
9
|
+
cache:
|
|
10
|
+
paths:
|
|
11
|
+
- node_modules/
|
|
12
|
+
|
|
13
|
+
install_dependencies:
|
|
14
|
+
stage: .pre
|
|
15
|
+
image: node:18-alpine
|
|
16
|
+
script:
|
|
17
|
+
- npm ci
|
|
18
|
+
|
|
19
|
+
lint_code:
|
|
20
|
+
stage: lint
|
|
21
|
+
image: node:18-alpine
|
|
22
|
+
script:
|
|
23
|
+
- npm run lint
|
|
24
|
+
|
|
25
|
+
run_tests:
|
|
26
|
+
stage: test
|
|
27
|
+
image: node:18-alpine
|
|
28
|
+
script:
|
|
29
|
+
- npm test
|
|
30
|
+
|
|
31
|
+
build_app:
|
|
32
|
+
stage: build
|
|
33
|
+
image: node:18-alpine
|
|
34
|
+
script:
|
|
35
|
+
- npm run build --if-present
|
|
@@ -17,12 +17,20 @@ This project comes pre-configured with industry-standard tooling for **Code Qual
|
|
|
17
17
|
- **DevOps**: Multi-stage Docker build, CI/CD ready.
|
|
18
18
|
|
|
19
19
|
## ๐ CI/CD Pipeline
|
|
20
|
-
<% if (ciProvider === 'GitHub Actions') { -%>
|
|
20
|
+
<%_ if (ciProvider === 'GitHub Actions') { -%>
|
|
21
|
+

|
|
21
22
|
This project includes a **GitHub Actions** workflow located in `.github/workflows/ci.yml`.
|
|
22
23
|
It automatically runs:
|
|
23
24
|
- Linting
|
|
24
25
|
- Tests
|
|
25
26
|
- Builds
|
|
27
|
+
<%_ } else if (ciProvider === 'GitLab CI') { -%>
|
|
28
|
+

|
|
29
|
+
This project includes a **GitLab CI** configuration in `.gitlab-ci.yml`.
|
|
30
|
+
It automatically runs:
|
|
31
|
+
- Linting
|
|
32
|
+
- Tests
|
|
33
|
+
- Builds
|
|
26
34
|
<% } else if (ciProvider === 'Jenkins') { -%>
|
|
27
35
|
This project includes a **Jenkinsfile** for comprehensive CI/CD.
|
|
28
36
|
Pipeline stages:
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import eslint from '@eslint/js';
|
|
2
|
+
import eslintConfigPrettier from 'eslint-config-prettier';
|
|
3
|
+
import globals from 'globals';
|
|
4
|
+
<% if (language === 'TypeScript') { %>import tseslint from 'typescript-eslint';
|
|
5
|
+
|
|
6
|
+
export default tseslint.config(
|
|
7
|
+
eslint.configs.recommended,
|
|
8
|
+
...tseslint.configs.recommended,
|
|
9
|
+
eslintConfigPrettier,
|
|
10
|
+
{
|
|
11
|
+
languageOptions: {
|
|
12
|
+
globals: {
|
|
13
|
+
...globals.node,
|
|
14
|
+
...globals.jest,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
rules: {
|
|
18
|
+
"no-console": "warn",
|
|
19
|
+
"no-unused-vars": "off",
|
|
20
|
+
"@typescript-eslint/no-unused-vars": "warn"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
);<% } else { %>
|
|
24
|
+
export default [
|
|
25
|
+
eslint.configs.recommended,
|
|
26
|
+
eslintConfigPrettier,
|
|
27
|
+
{
|
|
28
|
+
languageOptions: {
|
|
29
|
+
ecmaVersion: 'latest',
|
|
30
|
+
sourceType: 'module',
|
|
31
|
+
globals: {
|
|
32
|
+
...globals.node,
|
|
33
|
+
...globals.jest,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
rules: {
|
|
37
|
+
"no-console": "warn",
|
|
38
|
+
"no-unused-vars": "warn"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
];<% } %>
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"start": "<% if (language === 'TypeScript') { %>node dist/index.js<% } else { %>node src/index.js<% } %>",
|
|
8
8
|
"dev": "<% if (language === 'TypeScript') { %>nodemon --exec ts-node -r tsconfig-paths/register src/index.ts<% } else { %>nodemon src/index.js<% } %>"<% if (language === 'TypeScript') { %>,
|
|
9
|
-
"build": "rimraf dist && tsc && tsc-alias<% if (viewEngine && viewEngine !== 'None') { %> &&
|
|
10
|
-
"lint": "eslint .
|
|
11
|
-
"lint:fix": "eslint . --
|
|
9
|
+
"build": "rimraf dist && tsc && tsc-alias<% if (viewEngine && viewEngine !== 'None') { %> && cpx2 \"src/views/**/*\" dist/views<% } %>"<% } %>,
|
|
10
|
+
"lint": "eslint .",
|
|
11
|
+
"lint:fix": "eslint . --fix",
|
|
12
12
|
"format": "prettier --write .",
|
|
13
|
-
"prepare": "husky install",
|
|
13
|
+
"prepare": "node -e \"try { require('child_process').execSync('husky install'); } catch (e) { console.log('Not a git repository, skipping husky install'); }\"",
|
|
14
14
|
"test": "jest",
|
|
15
15
|
"test:watch": "jest --watch",
|
|
16
16
|
"test:coverage": "jest --coverage"
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
<% } -%>
|
|
35
35
|
<% if (caching === 'Redis') { %> "ioredis": "^5.3.2",
|
|
36
36
|
<% } -%>
|
|
37
|
-
<% if (viewEngine === 'EJS') { %> "ejs": "^3.1.
|
|
37
|
+
<% if (viewEngine === 'EJS') { %> "ejs": "^3.1.10",
|
|
38
38
|
<% } -%>
|
|
39
39
|
<% if (viewEngine === 'Pug') { %> "pug": "^3.0.2",
|
|
40
40
|
<% } -%>
|
|
@@ -55,7 +55,6 @@
|
|
|
55
55
|
"@types/node": "^20.10.5",
|
|
56
56
|
"@types/express": "^4.17.21",
|
|
57
57
|
"@types/cors": "^2.8.17",
|
|
58
|
-
"@types/dotenv": "^8.2.0",
|
|
59
58
|
"@types/hpp": "^0.2.3",
|
|
60
59
|
<% if (caching === 'Redis') { %> "@types/ioredis": "^5.0.0",
|
|
61
60
|
<% } -%>
|
|
@@ -65,26 +64,30 @@
|
|
|
65
64
|
"@types/sequelize": "^4.28.19",
|
|
66
65
|
<%_ } -%>
|
|
67
66
|
"@types/morgan": "^1.9.9",
|
|
68
|
-
"rimraf": "^
|
|
69
|
-
"
|
|
70
|
-
"eslint": "^
|
|
71
|
-
"
|
|
72
|
-
"
|
|
67
|
+
"rimraf": "^6.0.1"<% if (viewEngine && viewEngine !== 'None') { %>,
|
|
68
|
+
"cpx2": "^8.0.0"<% } %><% } %>,
|
|
69
|
+
"eslint": "^9.20.1",
|
|
70
|
+
"@eslint/js": "^9.20.0",
|
|
71
|
+
"globals": "^15.14.0",
|
|
72
|
+
"prettier": "^3.5.1",
|
|
73
|
+
"eslint-config-prettier": "^10.0.1",
|
|
73
74
|
"husky": "^8.0.3",
|
|
74
|
-
"lint-staged": "^15.
|
|
75
|
-
"
|
|
76
|
-
"@typescript-eslint/parser": "^6.18.1",
|
|
75
|
+
"lint-staged": "^15.4.3"<% if (language === 'TypeScript') { %>,
|
|
76
|
+
"typescript-eslint": "^8.24.1",
|
|
77
77
|
<% if (communication === 'REST APIs') { %> "@types/swagger-ui-express": "^4.1.6",
|
|
78
78
|
"@types/swagger-jsdoc": "^6.0.4",<% } -%>
|
|
79
79
|
"jest": "^29.7.0",
|
|
80
|
-
"ts-jest": "^29.
|
|
81
|
-
"@types/jest": "^29.5.
|
|
82
|
-
"supertest": "^
|
|
80
|
+
"ts-jest": "^29.2.5",
|
|
81
|
+
"@types/jest": "^29.5.14",
|
|
82
|
+
"supertest": "^7.1.3",
|
|
83
83
|
"tsconfig-paths": "^4.2.0",
|
|
84
|
-
"tsc-alias": "^1.8.
|
|
84
|
+
"tsc-alias": "^1.8.10",
|
|
85
85
|
"@types/supertest": "^6.0.2"<% } else { %>,
|
|
86
86
|
"jest": "^29.7.0",
|
|
87
|
-
"supertest": "^
|
|
87
|
+
"supertest": "^7.1.3"<% } %>
|
|
88
|
+
},
|
|
89
|
+
"overrides": {
|
|
90
|
+
"minimatch": "^10.2.1"
|
|
88
91
|
},
|
|
89
92
|
"lint-staged": {
|
|
90
93
|
"*.{js,ts}": [
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"env": {
|
|
3
|
-
"node": true,
|
|
4
|
-
"es2021": true,
|
|
5
|
-
"jest": true
|
|
6
|
-
},
|
|
7
|
-
"extends": [
|
|
8
|
-
"eslint:recommended",
|
|
9
|
-
"prettier"<% if (language === 'TypeScript') { %>,
|
|
10
|
-
"plugin:@typescript-eslint/recommended"<% } %>
|
|
11
|
-
],
|
|
12
|
-
"parserOptions": {
|
|
13
|
-
"ecmaVersion": "latest",
|
|
14
|
-
"sourceType": "module"
|
|
15
|
-
}<% if (language === 'TypeScript') { %>,
|
|
16
|
-
"parser": "@typescript-eslint/parser",
|
|
17
|
-
"plugins": ["@typescript-eslint"]<% } %>,
|
|
18
|
-
"rules": {
|
|
19
|
-
"no-console": "warn",
|
|
20
|
-
<% if (language === 'TypeScript') { %>
|
|
21
|
-
"no-unused-vars": "off",
|
|
22
|
-
"@typescript-eslint/no-unused-vars": "warn"
|
|
23
|
-
<% } else { %>
|
|
24
|
-
"no-unused-vars": "warn"<% } %>
|
|
25
|
-
}
|
|
26
|
-
}
|
|
File without changes
|