nodejs-quickstart-structure 2.0.0 โ 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +5 -5
- package/bin/index.js +1 -1
- package/lib/modules/config-files.js +10 -0
- package/lib/prompts.js +1 -1
- package/package.json +1 -1
- package/templates/common/.gitlab-ci.yml.ejs +3 -1
- package/templates/common/Jenkinsfile.ejs +10 -1
- package/templates/common/README.md.ejs +1 -1
- package/templates/common/_circleci/config.yml.ejs +96 -0
- package/templates/common/_github/workflows/ci.yml.ejs +1 -1
- package/templates/common/bitbucket-pipelines.yml.ejs +60 -0
- package/templates/common/caching/clean/ts/updateUser.ts.ejs +0 -1
- package/templates/common/docker-compose.yml.ejs +2 -0
- package/templates/common/package.json.ejs +2 -1
- package/templates/common/scripts/run-e2e.js.ejs +26 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
2
2
|
|
|
3
|
+
## [2.0.1] - 2026-04-07
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **Universal CI/CD Support (Phase 8)**: Expanded the generator's CI/CD capabilities to include out-of-the-box support for **Bitbucket Pipelines** and **CircleCI**.
|
|
7
|
+
- **Modernized Pipe & Orb Integration**:
|
|
8
|
+
- Bitbucket templates now utilize official Atlassian Pipes for automated Snyk security scans and SonarCloud analysis.
|
|
9
|
+
- CircleCI configurations (v2.1) are optimized with official Orbs (`circleci/node`, `snyk/snyk`) for advanced dependency caching and security execution.
|
|
10
|
+
- **Project Blueprints (CI/CD Guide)**: Launched a comprehensive "CI/CD Setup Guide" in the VitePress documentation, providing step-by-step configuration workflows for all 5 supported platforms (GitHub, GitLab, Jenkins, Bitbucket, CircleCI).
|
|
11
|
+
- **CLI Ecosystem Sync**: Updated the interactive prompts and command-line flags to seamlessly integrate the new CI/CD choices while maintaining 100% backward compatibility.
|
|
12
|
+
- **Enterprise Readness Documentation**: Updated the generated `README.md` templates to officially include Bitbucket and CircleCI in the supported feature set.
|
|
13
|
+
|
|
14
|
+
|
|
3
15
|
## [2.0.0] - 2026-04-02
|
|
4
16
|
|
|
5
17
|
### Added
|
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ The v2.0.0 release is a major leap forward, turning the generator into a **Commu
|
|
|
40
40
|
- [๐ Quick Start](#-quick-start)
|
|
41
41
|
- [โจ Key Features](#-key-features)
|
|
42
42
|
- [๐ก๏ธ Professional Standards](#-professional-standards)
|
|
43
|
-
- [๐งฉ
|
|
43
|
+
- [๐งฉ 2,640+ Project Combinations](#-2640-project-combinations)
|
|
44
44
|
- [โ๏ธ Configuration Options](#-configuration-options)
|
|
45
45
|
- [๐๏ธ Generated Project Structure](#-generated-project-structure)
|
|
46
46
|
- [๐ Documentation](#-documentation)
|
|
@@ -88,19 +88,19 @@ We don't just generate boilerplate; we generate **production-ready** foundations
|
|
|
88
88
|
- **๐ก๏ธ Enterprise Security**: Integrated **Snyk (SCA)**, **SonarCloud (SAST)**, `Helmet`, `HPP`, and Rate-Limiting.
|
|
89
89
|
- **๐จ Robust Error Handling**: Centralized global error middleware with custom error classes (`ApiError`, `NotFoundError`, etc.) โ consistent across REST & GraphQL.
|
|
90
90
|
- **๐งช Testing Excellence**: Integrated `Jest` and `Supertest` with **>80% Unit Test coverage** out of the box.
|
|
91
|
-
- **๐ DevOps & CI/CD**: Optimized **Multi-Stage Dockerfiles**, health checks, infrastructure retry logic, and workflows for **GitHub Actions**, **Jenkins**, and **
|
|
91
|
+
- **๐ DevOps & CI/CD**: Optimized **Multi-Stage Dockerfiles**, health checks, infrastructure retry logic, and workflows for **GitHub Actions**, **Jenkins**, **GitLab CI**, **CircleCI**, and **Bitbucket Pipelines**.
|
|
92
92
|
- **๐ Scalable Deployment**: Integrated **PM2 Ecosystem** config for zero-downtime reloads.
|
|
93
93
|
|
|
94
94
|
---
|
|
95
95
|
|
|
96
|
-
## ๐งฉ
|
|
96
|
+
## ๐งฉ 2,640+ Project Combinations
|
|
97
97
|
|
|
98
98
|
The CLI supports a massive number of configurations to fit your exact needs:
|
|
99
99
|
|
|
100
100
|
- **240 Core Combinations**:
|
|
101
101
|
- **MVC Architecture**: 180 variants (Languages ร View Engines ร Databases ร Communication Patterns ร Caching)
|
|
102
102
|
- **Clean Architecture**: 60 variants (Languages ร Databases ร Communication Patterns ร Caching)
|
|
103
|
-
- **
|
|
103
|
+
- **2,640+ Total Scenarios**:
|
|
104
104
|
- Every combination can be generated across 3 CI/CD providers.
|
|
105
105
|
- Optional **Enterprise-Grade Security Hardening** doubles the scenarios.
|
|
106
106
|
- Every single scenario is verified to be compatible with our **80% Coverage Threshold** policy.
|
|
@@ -117,7 +117,7 @@ The CLI will guide you through:
|
|
|
117
117
|
5. **Database**: `MySQL` | `PostgreSQL` | `MongoDB`
|
|
118
118
|
6. **Communication**: `REST` | `GraphQL` | `Kafka`
|
|
119
119
|
7. **Caching**: `None` | `Redis` | `Memory Cache`
|
|
120
|
-
8. **CI/CD**: `GitHub Actions` | `Jenkins` | `GitLab CI`
|
|
120
|
+
8. **CI/CD**: `GitHub Actions` | `Jenkins` | `GitLab CI` | `CircleCI` | `Bitbucket Pipelines`
|
|
121
121
|
9. **Security**: (Optional) Snyk & SonarCloud Hardening
|
|
122
122
|
|
|
123
123
|
---
|
package/bin/index.js
CHANGED
|
@@ -29,7 +29,7 @@ program
|
|
|
29
29
|
.option('-d, --database <database>', 'Database (MySQL, PostgreSQL)')
|
|
30
30
|
.option('--db-name <name>', 'Database name')
|
|
31
31
|
.option('-c, --communication <communication>', 'Communication (REST APIs, GraphQL, Kafka)')
|
|
32
|
-
.option('--ci-provider <provider>', 'CI/CD Provider (None, GitHub Actions, Jenkins, GitLab CI)')
|
|
32
|
+
.option('--ci-provider <provider>', 'CI/CD Provider (None, GitHub Actions, Jenkins, GitLab CI, Bitbucket Pipelines, CircleCI)')
|
|
33
33
|
.option('--include-security', 'Include Enterprise Security Hardening')
|
|
34
34
|
.option('--no-include-security', 'Exclude Enterprise Security Hardening')
|
|
35
35
|
.option('--caching <type>', 'Caching Layer (None/Redis)')
|
|
@@ -120,6 +120,16 @@ export const setupCiCd = async (templatesDir, targetDir, config) => {
|
|
|
120
120
|
const gitlabTemplate = await fs.readFile(path.join(templatesDir, 'common', '.gitlab-ci.yml.ejs'), 'utf-8');
|
|
121
121
|
const gitlabContent = ejs.render(gitlabTemplate, { ...config });
|
|
122
122
|
await fs.writeFile(path.join(targetDir, '.gitlab-ci.yml'), gitlabContent);
|
|
123
|
+
} else if (ciProvider === 'Bitbucket Pipelines') {
|
|
124
|
+
const bitbucketTemplate = await fs.readFile(path.join(templatesDir, 'common', 'bitbucket-pipelines.yml.ejs'), 'utf-8');
|
|
125
|
+
const bitbucketContent = ejs.render(bitbucketTemplate, { ...config });
|
|
126
|
+
await fs.writeFile(path.join(targetDir, 'bitbucket-pipelines.yml'), bitbucketContent);
|
|
127
|
+
} else if (ciProvider === 'CircleCI') {
|
|
128
|
+
const circleCiDir = path.join(targetDir, '.circleci');
|
|
129
|
+
await fs.ensureDir(circleCiDir);
|
|
130
|
+
const circleCiTemplate = await fs.readFile(path.join(templatesDir, 'common', '_circleci/config.yml.ejs'), 'utf-8');
|
|
131
|
+
const circleCiContent = ejs.render(circleCiTemplate, { ...config });
|
|
132
|
+
await fs.writeFile(path.join(circleCiDir, 'config.yml'), circleCiContent);
|
|
123
133
|
}
|
|
124
134
|
};
|
|
125
135
|
|
package/lib/prompts.js
CHANGED
|
@@ -74,7 +74,7 @@ export const getProjectDetails = async (options = {}) => {
|
|
|
74
74
|
type: 'select',
|
|
75
75
|
name: 'ciProvider',
|
|
76
76
|
message: 'Select CI/CD Provider:',
|
|
77
|
-
choices: ['None', 'GitHub Actions', 'Jenkins', 'GitLab CI'],
|
|
77
|
+
choices: ['None', 'GitHub Actions', 'Jenkins', 'GitLab CI', 'CircleCI', 'Bitbucket Pipelines'],
|
|
78
78
|
default: 'None',
|
|
79
79
|
when: !options.ciProvider
|
|
80
80
|
},
|
package/package.json
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
variables:
|
|
2
2
|
NODE_ENV: 'test'
|
|
3
|
+
WAIT_ON_HOST: docker
|
|
4
|
+
TEST_URL: http://docker:3001
|
|
3
5
|
|
|
4
6
|
stages:
|
|
5
7
|
- lint
|
|
@@ -30,7 +32,7 @@ run_unit_tests:
|
|
|
30
32
|
stage: test
|
|
31
33
|
image: node:22-slim
|
|
32
34
|
script:
|
|
33
|
-
- npm run test:coverage
|
|
35
|
+
- npm run test:coverage -- --maxWorkers=2
|
|
34
36
|
|
|
35
37
|
run_e2e_tests:
|
|
36
38
|
stage: test
|
|
@@ -3,6 +3,15 @@ pipeline {
|
|
|
3
3
|
|
|
4
4
|
environment {
|
|
5
5
|
CI = 'true'
|
|
6
|
+
DOCKER_BUILDKIT = '0'
|
|
7
|
+
PORT = '3001'
|
|
8
|
+
DB_PORT = '3307'
|
|
9
|
+
WAIT_ON_HOST = 'host.docker.internal'
|
|
10
|
+
TEST_URL = 'http://host.docker.internal:3001'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
tools {
|
|
14
|
+
nodejs 'nodejs'
|
|
6
15
|
}
|
|
7
16
|
|
|
8
17
|
stages {
|
|
@@ -21,7 +30,7 @@ pipeline {
|
|
|
21
30
|
|
|
22
31
|
stage('Unit Test') {
|
|
23
32
|
steps {
|
|
24
|
-
sh 'npm run test:coverage'
|
|
33
|
+
sh 'npm run test:coverage -- --maxWorkers=2'
|
|
25
34
|
}
|
|
26
35
|
}
|
|
27
36
|
|
|
@@ -31,7 +31,7 @@ This project follows a strict **7-Step Production-Ready Process** to ensure qual
|
|
|
31
31
|
- **Database**: <%= database %> <% if (database !== 'None') { %>(via <%= database === 'MongoDB' ? 'Mongoose' : 'Sequelize' %>)<% } %>.
|
|
32
32
|
- **Security**: Helmet, CORS, Rate Limiting, HPP, Snyk SCA.
|
|
33
33
|
- **Quality**: 80%+ Test Coverage, Eslint, Prettier, Husky.
|
|
34
|
-
- **DevOps**: Multi-stage Docker, CI/CD ready (GitHub/GitLab/Jenkins).
|
|
34
|
+
- **DevOps**: Multi-stage Docker, CI/CD ready (GitHub/GitLab/Jenkins/Bitbucket/CircleCI).
|
|
35
35
|
<% if (includeSecurity) { %>- **Enterprise Hardening**: SonarCloud SAST, Security Policies.<% } %>
|
|
36
36
|
|
|
37
37
|
## ๐ Project Structure
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
version: 2.1
|
|
2
|
+
|
|
3
|
+
orbs:
|
|
4
|
+
node: circleci/node@5.2.0
|
|
5
|
+
<% if (includeSecurity) { %>
|
|
6
|
+
snyk: snyk/snyk@2.1.0
|
|
7
|
+
<% } %>
|
|
8
|
+
|
|
9
|
+
executors:
|
|
10
|
+
node-executor:
|
|
11
|
+
docker:
|
|
12
|
+
- image: cimg/node:22.0
|
|
13
|
+
machine-executor:
|
|
14
|
+
machine:
|
|
15
|
+
image: ubuntu-2204:current
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
lint:
|
|
19
|
+
executor: node-executor
|
|
20
|
+
steps:
|
|
21
|
+
- checkout
|
|
22
|
+
- node/install-packages
|
|
23
|
+
- run: npm run lint
|
|
24
|
+
|
|
25
|
+
unit_test:
|
|
26
|
+
executor: node-executor
|
|
27
|
+
steps:
|
|
28
|
+
- checkout
|
|
29
|
+
- node/install-packages
|
|
30
|
+
- run:
|
|
31
|
+
name: Run Unit Tests with Coverage
|
|
32
|
+
command: npm run test:coverage -- --maxWorkers=2
|
|
33
|
+
|
|
34
|
+
e2e_test:
|
|
35
|
+
executor: machine-executor
|
|
36
|
+
steps:
|
|
37
|
+
- checkout
|
|
38
|
+
- node/install:
|
|
39
|
+
node-version: '22.0'
|
|
40
|
+
- run: npm ci
|
|
41
|
+
- run: npm run test:e2e
|
|
42
|
+
|
|
43
|
+
<% if (includeSecurity) { %>
|
|
44
|
+
security_scan:
|
|
45
|
+
executor: node-executor
|
|
46
|
+
steps:
|
|
47
|
+
- checkout
|
|
48
|
+
- node/install-packages
|
|
49
|
+
- snyk/scan:
|
|
50
|
+
fail-on-issues: true
|
|
51
|
+
severity-threshold: high
|
|
52
|
+
|
|
53
|
+
sonarqube_analysis:
|
|
54
|
+
executor: node-executor
|
|
55
|
+
steps:
|
|
56
|
+
- checkout
|
|
57
|
+
- node/install-packages
|
|
58
|
+
- run:
|
|
59
|
+
name: SonarQube Analysis
|
|
60
|
+
command: |
|
|
61
|
+
# Assuming sonar-scanner is available or run via npx
|
|
62
|
+
npx sonar-scanner
|
|
63
|
+
<% } %>
|
|
64
|
+
|
|
65
|
+
build:
|
|
66
|
+
executor: node-executor
|
|
67
|
+
steps:
|
|
68
|
+
- checkout
|
|
69
|
+
- node/install-packages
|
|
70
|
+
- run: npm run build --if-present
|
|
71
|
+
|
|
72
|
+
workflows:
|
|
73
|
+
build_and_test:
|
|
74
|
+
jobs:
|
|
75
|
+
- lint
|
|
76
|
+
- unit_test:
|
|
77
|
+
requires:
|
|
78
|
+
- lint
|
|
79
|
+
- e2e_test:
|
|
80
|
+
requires:
|
|
81
|
+
- unit_test
|
|
82
|
+
<% if (includeSecurity) { %>
|
|
83
|
+
- security_scan:
|
|
84
|
+
requires:
|
|
85
|
+
- unit_test
|
|
86
|
+
- sonarqube_analysis:
|
|
87
|
+
requires:
|
|
88
|
+
- unit_test
|
|
89
|
+
<% } %>
|
|
90
|
+
- build:
|
|
91
|
+
requires:
|
|
92
|
+
- e2e_test
|
|
93
|
+
<% if (includeSecurity) { %>
|
|
94
|
+
- security_scan
|
|
95
|
+
- sonarqube_analysis
|
|
96
|
+
<% } %>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
image: node:22-slim
|
|
2
|
+
|
|
3
|
+
pipelines:
|
|
4
|
+
default:
|
|
5
|
+
- step:
|
|
6
|
+
name: Install Dependencies
|
|
7
|
+
caches:
|
|
8
|
+
- node
|
|
9
|
+
script:
|
|
10
|
+
- npm ci
|
|
11
|
+
- parallel:
|
|
12
|
+
- step:
|
|
13
|
+
name: Lint Code
|
|
14
|
+
script:
|
|
15
|
+
- npm ci
|
|
16
|
+
- npm run lint
|
|
17
|
+
- step:
|
|
18
|
+
name: Run Unit Tests
|
|
19
|
+
script:
|
|
20
|
+
- npm ci
|
|
21
|
+
- npm run test:coverage -- --maxWorkers=2
|
|
22
|
+
- step:
|
|
23
|
+
name: Run E2E Tests
|
|
24
|
+
image: docker:20.10.16
|
|
25
|
+
services:
|
|
26
|
+
- docker
|
|
27
|
+
script:
|
|
28
|
+
- apk add --no-cache nodejs npm docker-compose
|
|
29
|
+
- npm ci
|
|
30
|
+
- export DOCKER_BUILDKIT=0
|
|
31
|
+
- npm run test:e2e
|
|
32
|
+
<% if (includeSecurity) { %>
|
|
33
|
+
- parallel:
|
|
34
|
+
- step:
|
|
35
|
+
name: Snyk Security Scan
|
|
36
|
+
script:
|
|
37
|
+
- pipe: snyk/snyk-scan:1.0.0
|
|
38
|
+
variables:
|
|
39
|
+
SNYK_TOKEN: $SNYK_TOKEN
|
|
40
|
+
LANGUAGE: "npm"
|
|
41
|
+
SEVERITY_THRESHOLD: "high"
|
|
42
|
+
- step:
|
|
43
|
+
name: SonarQube Analysis
|
|
44
|
+
script:
|
|
45
|
+
- pipe: sonarsource/sonarcloud-scan:2.0.0
|
|
46
|
+
variables:
|
|
47
|
+
SONAR_TOKEN: $SONAR_TOKEN
|
|
48
|
+
<% } %>
|
|
49
|
+
- step:
|
|
50
|
+
name: Build Application
|
|
51
|
+
script:
|
|
52
|
+
- npm ci
|
|
53
|
+
- npm run build --if-present
|
|
54
|
+
|
|
55
|
+
definitions:
|
|
56
|
+
services:
|
|
57
|
+
docker:
|
|
58
|
+
memory: 2048
|
|
59
|
+
caches:
|
|
60
|
+
node: ~/.npm
|
|
@@ -122,10 +122,12 @@ services:
|
|
|
122
122
|
FLYWAY_URL: jdbc:mysql://db:3306/<%= dbName %>
|
|
123
123
|
FLYWAY_USER: root
|
|
124
124
|
FLYWAY_PASSWORD: root
|
|
125
|
+
FLYWAY_BASELINE_ON_MIGRATE: "true"
|
|
125
126
|
<%_ } -%><%_ if (database === 'PostgreSQL') { -%>
|
|
126
127
|
FLYWAY_URL: jdbc:postgresql://db:5432/<%= dbName %>
|
|
127
128
|
FLYWAY_USER: postgres
|
|
128
129
|
FLYWAY_PASSWORD: root
|
|
130
|
+
FLYWAY_BASELINE_ON_MIGRATE: "true"
|
|
129
131
|
<%_ } -%>
|
|
130
132
|
depends_on:
|
|
131
133
|
- db
|
|
@@ -3,13 +3,21 @@ const { execSync } = require('child_process');
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
|
|
5
5
|
// Set a specific port for E2E tests to avoid collisions with local development
|
|
6
|
-
process.env.PORT
|
|
7
|
-
const
|
|
6
|
+
const TEST_PORT = <% if (database === 'MySQL') { %>process.env.PORT || '3001'<% } else { %>process.env.PORT || '3001'<% } %>;
|
|
7
|
+
const WAIT_ON_HOST = process.env.WAIT_ON_HOST || '127.0.0.1';
|
|
8
8
|
|
|
9
9
|
const execute = (command) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
console.log(`\n> ${command}`);
|
|
11
|
+
// Run commands from the project root instead of the scripts folder
|
|
12
|
+
execSync(command, {
|
|
13
|
+
stdio: 'inherit',
|
|
14
|
+
cwd: path.resolve(__dirname, '../'),
|
|
15
|
+
env: {
|
|
16
|
+
...process.env,
|
|
17
|
+
PORT: TEST_PORT,
|
|
18
|
+
DB_PORT: process.env.DB_PORT || '3306'
|
|
19
|
+
}
|
|
20
|
+
});
|
|
13
21
|
};
|
|
14
22
|
|
|
15
23
|
let composeCmd = 'docker-compose';
|
|
@@ -26,7 +34,7 @@ try {
|
|
|
26
34
|
let isAlreadyUp = false;
|
|
27
35
|
try {
|
|
28
36
|
// Silently check if the endpoint is already live (1.5-second timeout)
|
|
29
|
-
execSync(`npx wait-on http-get
|
|
37
|
+
execSync(`npx wait-on http-get://${WAIT_ON_HOST}:${TEST_PORT}/health -t 1500`, {
|
|
30
38
|
stdio: 'ignore',
|
|
31
39
|
cwd: path.resolve(__dirname, '../')
|
|
32
40
|
});
|
|
@@ -42,10 +50,18 @@ try {
|
|
|
42
50
|
execute(`${composeCmd} up -d --build`);
|
|
43
51
|
currentProcessStartedDocker = true;
|
|
44
52
|
|
|
45
|
-
console.log(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
53
|
+
console.log(`Waiting for application healthcheck to turn green (420s timeout)...`);
|
|
54
|
+
try {
|
|
55
|
+
// Using WAIT_ON_HOST to allow containerized CI to hit host ports (e.g. host.docker.internal)
|
|
56
|
+
execute(`npx wait-on http-get://${WAIT_ON_HOST}:${TEST_PORT}/health -t 420000`);
|
|
57
|
+
console.log('Infrastructure is healthy!');
|
|
58
|
+
} catch (e) {
|
|
59
|
+
console.error('\nโ Healthcheck timed out! Printing infrastructure logs for debugging:');
|
|
60
|
+
console.error('------------------------------------------------------------');
|
|
61
|
+
execute(`${composeCmd} logs --tail=100`);
|
|
62
|
+
console.error('------------------------------------------------------------');
|
|
63
|
+
throw e;
|
|
64
|
+
}
|
|
49
65
|
}
|
|
50
66
|
|
|
51
67
|
console.log('Running E2E tests...');
|