nodejs-quickstart-structure 1.18.0 → 1.19.0
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 +17 -4
- package/README.md +2 -1
- package/bin/index.js +93 -92
- package/lib/generator.js +1 -1
- package/lib/modules/caching-setup.js +76 -73
- package/lib/modules/config-files.js +4 -0
- package/lib/modules/kafka-setup.js +249 -191
- package/lib/modules/project-setup.js +1 -0
- package/package.json +13 -2
- package/templates/clean-architecture/js/src/errors/BadRequestError.js +11 -10
- package/templates/clean-architecture/js/src/errors/BadRequestError.spec.js.ejs +22 -21
- package/templates/clean-architecture/js/src/errors/NotFoundError.js +11 -10
- package/templates/clean-architecture/js/src/errors/NotFoundError.spec.js.ejs +22 -21
- package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.js.ejs +69 -39
- package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.spec.js.ejs +142 -81
- package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +1 -1
- package/templates/clean-architecture/js/src/interfaces/controllers/userController.js.ejs +156 -75
- package/templates/clean-architecture/js/src/interfaces/controllers/userController.spec.js.ejs +234 -138
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.js.ejs +27 -21
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.spec.js.ejs +66 -49
- package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/user.types.js.ejs +19 -17
- package/templates/clean-architecture/js/src/interfaces/routes/api.js +12 -10
- package/templates/clean-architecture/js/src/usecases/DeleteUser.js +11 -0
- package/templates/clean-architecture/js/src/usecases/DeleteUser.spec.js.ejs +47 -0
- package/templates/clean-architecture/js/src/usecases/UpdateUser.js +11 -0
- package/templates/clean-architecture/js/src/usecases/UpdateUser.spec.js.ejs +48 -0
- package/templates/clean-architecture/js/src/utils/errorMessages.js +14 -0
- package/templates/clean-architecture/ts/src/errors/BadRequestError.spec.ts.ejs +22 -21
- package/templates/clean-architecture/ts/src/errors/BadRequestError.ts +9 -8
- package/templates/clean-architecture/ts/src/errors/NotFoundError.spec.ts.ejs +22 -21
- package/templates/clean-architecture/ts/src/errors/NotFoundError.ts +9 -8
- package/templates/clean-architecture/ts/src/index.ts.ejs +1 -1
- package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.spec.ts.ejs +175 -85
- package/templates/clean-architecture/ts/src/infrastructure/repositories/userRepository.ts.ejs +74 -0
- package/templates/clean-architecture/ts/src/interfaces/controllers/userController.spec.ts.ejs +331 -185
- package/templates/clean-architecture/ts/src/interfaces/controllers/userController.ts.ejs +173 -84
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -51
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.ts.ejs +29 -21
- package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/user.types.ts.ejs +17 -15
- package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts +13 -11
- package/templates/clean-architecture/ts/src/usecases/deleteUser.spec.ts.ejs +47 -0
- package/templates/clean-architecture/ts/src/usecases/deleteUser.ts +9 -0
- package/templates/clean-architecture/ts/src/usecases/updateUser.spec.ts.ejs +48 -0
- package/templates/clean-architecture/ts/src/usecases/updateUser.ts +9 -0
- package/templates/clean-architecture/ts/src/utils/errorMessages.ts +12 -0
- package/templates/common/.gitattributes +46 -0
- package/templates/common/.snyk.ejs +45 -0
- package/templates/common/Dockerfile +17 -9
- package/templates/common/README.md.ejs +295 -263
- package/templates/common/caching/clean/js/DeleteUser.js.ejs +27 -0
- package/templates/common/caching/clean/js/UpdateUser.js.ejs +27 -0
- package/templates/common/caching/clean/ts/deleteUser.ts.ejs +24 -0
- package/templates/common/caching/clean/ts/updateUser.ts.ejs +25 -0
- package/templates/common/caching/ts/memoryCache.ts.ejs +73 -64
- package/templates/common/caching/ts/redisClient.ts.ejs +89 -80
- package/templates/common/database/js/models/User.js.ejs +79 -53
- package/templates/common/database/js/models/User.js.mongoose.ejs +23 -19
- package/templates/common/database/js/models/User.spec.js.ejs +94 -84
- package/templates/common/database/ts/models/User.spec.ts.ejs +100 -84
- package/templates/common/database/ts/models/User.ts.ejs +87 -61
- package/templates/common/database/ts/models/User.ts.mongoose.ejs +30 -25
- package/templates/common/health/js/healthRoute.js.ejs +50 -47
- package/templates/common/health/ts/healthRoute.ts.ejs +49 -46
- package/templates/common/jest.e2e.config.js.ejs +8 -8
- package/templates/common/kafka/js/messaging/baseConsumer.js.ejs +30 -30
- package/templates/common/kafka/js/messaging/userEventSchema.js.ejs +12 -11
- package/templates/common/kafka/js/messaging/welcomeEmailConsumer.js.ejs +44 -31
- package/templates/common/kafka/js/messaging/welcomeEmailConsumer.spec.js.ejs +86 -49
- package/templates/common/kafka/js/services/kafkaService.js.ejs +93 -93
- package/templates/common/kafka/js/utils/kafkaEvents.js.ejs +7 -0
- package/templates/common/kafka/ts/messaging/userEventSchema.spec.ts.ejs +51 -51
- package/templates/common/kafka/ts/messaging/userEventSchema.ts.ejs +12 -11
- package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.spec.ts.ejs +86 -49
- package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.ts.ejs +38 -25
- package/templates/common/kafka/ts/services/kafkaService.ts.ejs +95 -95
- package/templates/common/kafka/ts/utils/kafkaEvents.ts.ejs +5 -0
- package/templates/common/package.json.ejs +10 -2
- package/templates/common/shutdown/js/gracefulShutdown.js.ejs +65 -61
- package/templates/common/shutdown/js/gracefulShutdown.spec.js.ejs +149 -160
- package/templates/common/shutdown/ts/gracefulShutdown.spec.ts.ejs +179 -158
- package/templates/common/shutdown/ts/gracefulShutdown.ts.ejs +59 -55
- package/templates/common/src/tests/e2e/e2e.users.test.js.ejs +120 -49
- package/templates/common/src/tests/e2e/e2e.users.test.ts.ejs +120 -49
- package/templates/common/swagger.yml.ejs +118 -66
- package/templates/db/mysql/V1__Initial_Setup.sql.ejs +10 -9
- package/templates/db/postgres/V1__Initial_Setup.sql.ejs +10 -9
- package/templates/mvc/js/src/controllers/userController.js.ejs +246 -105
- package/templates/mvc/js/src/controllers/userController.spec.js.ejs +481 -209
- package/templates/mvc/js/src/errors/BadRequestError.js +11 -10
- package/templates/mvc/js/src/errors/BadRequestError.spec.js.ejs +22 -21
- package/templates/mvc/js/src/errors/NotFoundError.js +11 -10
- package/templates/mvc/js/src/errors/NotFoundError.spec.js.ejs +22 -21
- package/templates/mvc/js/src/graphql/resolvers/user.resolvers.js.ejs +25 -19
- package/templates/mvc/js/src/graphql/resolvers/user.resolvers.spec.js.ejs +64 -47
- package/templates/mvc/js/src/graphql/typeDefs/user.types.js.ejs +19 -17
- package/templates/mvc/js/src/index.js.ejs +1 -1
- package/templates/mvc/js/src/routes/api.js +10 -8
- package/templates/mvc/js/src/routes/api.spec.js.ejs +41 -36
- package/templates/mvc/js/src/utils/errorMessages.js +14 -0
- package/templates/mvc/ts/src/controllers/userController.spec.ts.ejs +481 -203
- package/templates/mvc/ts/src/controllers/userController.ts.ejs +248 -107
- package/templates/mvc/ts/src/errors/BadRequestError.spec.ts.ejs +22 -21
- package/templates/mvc/ts/src/errors/BadRequestError.ts +9 -8
- package/templates/mvc/ts/src/errors/NotFoundError.spec.ts.ejs +27 -21
- package/templates/mvc/ts/src/errors/NotFoundError.ts +9 -8
- package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -51
- package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.ts.ejs +29 -21
- package/templates/mvc/ts/src/graphql/typeDefs/user.types.ts.ejs +17 -15
- package/templates/mvc/ts/src/index.ts.ejs +156 -153
- package/templates/mvc/ts/src/routes/api.spec.ts.ejs +59 -40
- package/templates/mvc/ts/src/routes/api.ts +12 -10
- package/templates/mvc/ts/src/utils/errorMessages.ts +12 -0
- package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.ts.ejs +0 -37
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## [1.19.0] - 2026-03-28
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
### Added
|
|
6
|
+
- **Security Hardening**: Added `SECURITY.md` file to the project.
|
|
7
|
+
- **Git Attributes**: Added `.gitattributes` file to the project.
|
|
8
|
+
- **Contributing Guide**: Added `CONTRIBUTING.md` file to the project.
|
|
9
|
+
|
|
10
|
+
## [1.18.1] - 2026-03-27
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Template Security Hardening**: Resolved 29 vulnerabilities in `package.json.ejs` by upgrading `Apollo Server`, `Jest`, and `ESLint`.
|
|
14
|
+
- **Apollo Server 5 Compatibility**: Migrated GraphQL integration to use `@as-integrations/express4`, resolving breaking changes in the latest Apollo release.
|
|
15
|
+
- **Surgical Security Overrides**: Implemented targeted `overrides` for `brace-expansion`, `jake`, and `micromatch`. Removed global `glob/minimatch` overrides to maintain compatibility with Jest's internal APIs while preserving a "Zero-Vulnerability" status.
|
|
16
|
+
- **E2E Validated**: Verified the entire "Secure-by-Default" ecosystem via Windows E2E tests, achieving 100% pass rate.
|
|
17
|
+
- **Enterprise Standards**: Synchronized all generator templates with the latest secure dependency standards across MVC and Clean Architecture.
|
|
18
|
+
### Changed
|
|
19
|
+
- **Readme**: Standardize Generated Project README.
|
|
7
20
|
|
|
8
21
|
## [1.18.0] - 2026-03-25
|
|
9
22
|
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ A powerful CLI tool to scaffold production-ready Node.js microservices with buil
|
|
|
20
20
|
- [⚙️ Configuration Options](#-configuration-options)
|
|
21
21
|
- [🏗️ Generated Project Structure](#-generated-project-structure)
|
|
22
22
|
- [📖 Documentation](#-documentation)
|
|
23
|
-
- [🗺️
|
|
23
|
+
- [🗺️ Support & Roadmap](#️-roadmap--support)
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
@@ -53,6 +53,7 @@ nodejs-quickstart init
|
|
|
53
53
|
- **Communication Patterns**: Supports **REST**, **GraphQL** (Apollo), and **Kafka** (Event-driven).
|
|
54
54
|
- **Multi-layer Caching**: Integrated **Redis** or built-in **Memory Cache**.
|
|
55
55
|
- **AI-Native Optimized**: specifically designed for **Cursor** and AI agents, including built-in `.cursorrules` and Agent Skill prompts. 🚀
|
|
56
|
+
- **Next Gen Web UI**: (Coming Soon) A modern, browser-based project selector featuring real-time virtualization — set for release in v2.0.0!
|
|
56
57
|
|
|
57
58
|
---
|
|
58
59
|
|
package/bin/index.js
CHANGED
|
@@ -1,92 +1,93 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import chalk from 'chalk';
|
|
5
|
-
import { getProjectDetails } from '../lib/prompts.js';
|
|
6
|
-
import { generateProject } from '../lib/generator.js';
|
|
7
|
-
import { readFileSync } from 'fs';
|
|
8
|
-
import { join, dirname } from 'path';
|
|
9
|
-
import { fileURLToPath } from 'url';
|
|
10
|
-
|
|
11
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
-
const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
|
|
13
|
-
|
|
14
|
-
const program = new Command();
|
|
15
|
-
|
|
16
|
-
program
|
|
17
|
-
.name('nodejs-quickstart')
|
|
18
|
-
.description('🚀 CLI to scaffold production-ready Node.js microservices.\n\nGenerates projects with:\n- MVC or Clean Architecture\n- REST or Kafka\n- MySQL, PostgreSQL, or MongoDB\n- Docker, Flyway & Mongoose support')
|
|
19
|
-
.version(pkg.version, '-v, --version', 'Output the current version')
|
|
20
|
-
.addHelpText('after', `\n${chalk.yellow('Example:')}\n $ nodejs-quickstart init ${chalk.gray('# Start the interactive setup')}\n`);
|
|
21
|
-
|
|
22
|
-
program
|
|
23
|
-
.command('init')
|
|
24
|
-
.description('Initialize a new Node.js project')
|
|
25
|
-
.option('-n, --project-name <name>', 'Project name')
|
|
26
|
-
.option('-l, --language <language>', 'Language (JavaScript, TypeScript)')
|
|
27
|
-
.option('-a, --architecture <architecture>', 'Architecture (MVC, Clean Architecture)')
|
|
28
|
-
.option('--view-engine <view>', 'View Engine (None, EJS, Pug) - MVC only')
|
|
29
|
-
.option('-d, --database <database>', 'Database (MySQL, PostgreSQL)')
|
|
30
|
-
.option('--db-name <name>', 'Database name')
|
|
31
|
-
.option('-c, --communication <communication>', 'Communication (REST APIs, GraphQL, Kafka)')
|
|
32
|
-
.option('--ci-provider <provider>', 'CI/CD Provider (None, GitHub Actions, Jenkins, GitLab CI)')
|
|
33
|
-
.option('--include-security', 'Include Enterprise Security Hardening')
|
|
34
|
-
.option('--caching <type>', 'Caching Layer (None/Redis)')
|
|
35
|
-
.action(async (options) => {
|
|
36
|
-
// Fix for Commander camelCase conversion
|
|
37
|
-
if (options.ciProvider) {
|
|
38
|
-
options.ciProvider = options.ciProvider;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
console.log(chalk.blue('Welcome to the Node.js Quickstart Generator!'));
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
const answers = await getProjectDetails(options);
|
|
45
|
-
console.log(chalk.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
console.log(chalk.magenta('
|
|
54
|
-
console.log(chalk.magenta('
|
|
55
|
-
console.log(chalk.magenta(
|
|
56
|
-
console.log(chalk.magenta(`📍 Use
|
|
57
|
-
console.log(chalk.magenta(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (answers.database
|
|
67
|
-
|
|
68
|
-
if (answers.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { getProjectDetails } from '../lib/prompts.js';
|
|
6
|
+
import { generateProject } from '../lib/generator.js';
|
|
7
|
+
import { readFileSync } from 'fs';
|
|
8
|
+
import { join, dirname } from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
|
|
11
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
|
|
13
|
+
|
|
14
|
+
const program = new Command();
|
|
15
|
+
|
|
16
|
+
program
|
|
17
|
+
.name('nodejs-quickstart')
|
|
18
|
+
.description('🚀 CLI to scaffold production-ready Node.js microservices.\n\nGenerates projects with:\n- MVC or Clean Architecture\n- REST or Kafka\n- MySQL, PostgreSQL, or MongoDB\n- Docker, Flyway & Mongoose support')
|
|
19
|
+
.version(pkg.version, '-v, --version', 'Output the current version')
|
|
20
|
+
.addHelpText('after', `\n${chalk.yellow('Example:')}\n $ nodejs-quickstart init ${chalk.gray('# Start the interactive setup')}\n`);
|
|
21
|
+
|
|
22
|
+
program
|
|
23
|
+
.command('init')
|
|
24
|
+
.description('Initialize a new Node.js project')
|
|
25
|
+
.option('-n, --project-name <name>', 'Project name')
|
|
26
|
+
.option('-l, --language <language>', 'Language (JavaScript, TypeScript)')
|
|
27
|
+
.option('-a, --architecture <architecture>', 'Architecture (MVC, Clean Architecture)')
|
|
28
|
+
.option('--view-engine <view>', 'View Engine (None, EJS, Pug) - MVC only')
|
|
29
|
+
.option('-d, --database <database>', 'Database (MySQL, PostgreSQL)')
|
|
30
|
+
.option('--db-name <name>', 'Database name')
|
|
31
|
+
.option('-c, --communication <communication>', 'Communication (REST APIs, GraphQL, Kafka)')
|
|
32
|
+
.option('--ci-provider <provider>', 'CI/CD Provider (None, GitHub Actions, Jenkins, GitLab CI)')
|
|
33
|
+
.option('--include-security', 'Include Enterprise Security Hardening')
|
|
34
|
+
.option('--caching <type>', 'Caching Layer (None/Redis)')
|
|
35
|
+
.action(async (options) => {
|
|
36
|
+
// Fix for Commander camelCase conversion
|
|
37
|
+
if (options.ciProvider) {
|
|
38
|
+
options.ciProvider = options.ciProvider;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
console.log(chalk.blue('Welcome to the Node.js Quickstart Generator!'));
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const answers = await getProjectDetails(options);
|
|
45
|
+
console.log(chalk.blue(`\n🚀 Preparing to generate ${chalk.bold(answers.projectName)} (${answers.architecture})...`));
|
|
46
|
+
|
|
47
|
+
console.log(chalk.yellow('\nGenerating project files...'));
|
|
48
|
+
await generateProject(answers);
|
|
49
|
+
|
|
50
|
+
console.log(chalk.green('\n✔ Project generated successfully!'));
|
|
51
|
+
|
|
52
|
+
console.log(chalk.magenta('\n🚀 Project is AI-Ready!'));
|
|
53
|
+
console.log(chalk.magenta('-----------------------------------------'));
|
|
54
|
+
console.log(chalk.magenta('🤖 We detected you are using AI tools.'));
|
|
55
|
+
console.log(chalk.magenta(`📍 Use Cursor? We've configured '.cursorrules' for you.`));
|
|
56
|
+
console.log(chalk.magenta(`📍 Use ChatGPT/Gemini? Check the 'prompts/' folder for Agent Skills.`));
|
|
57
|
+
console.log(chalk.magenta('-----------------------------------------'));
|
|
58
|
+
|
|
59
|
+
let manualStartInstructions = `\n${chalk.yellow('Development:')}\n cd ${answers.projectName}\n npm install`;
|
|
60
|
+
|
|
61
|
+
const needsInfrastructure = answers.database !== 'None' || answers.caching === 'Redis' || answers.communication === 'Kafka';
|
|
62
|
+
|
|
63
|
+
if (needsInfrastructure) {
|
|
64
|
+
let servicesToStart = '';
|
|
65
|
+
if (answers.database === 'MongoDB') servicesToStart += ' db';
|
|
66
|
+
else if (answers.database !== 'None') servicesToStart += ' db flyway';
|
|
67
|
+
if (answers.caching === 'Redis') servicesToStart += ' redis';
|
|
68
|
+
if (answers.communication === 'Kafka') servicesToStart += ' kafka';
|
|
69
|
+
|
|
70
|
+
manualStartInstructions += `\n docker-compose up -d${servicesToStart} # Start infrastructure first\n npm run dev`;
|
|
71
|
+
} else {
|
|
72
|
+
manualStartInstructions += `\n npm run dev`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.log(chalk.cyan(`\nNext steps:\n cd ${answers.projectName}\n npm install\n docker-compose up\n-----------------------${manualStartInstructions}\n\n${chalk.yellow('Production (PM2):')}\n npm run build\n npm run deploy\n npx pm2 logs`));
|
|
76
|
+
|
|
77
|
+
console.log(chalk.yellow(`\n⭐ If this tool saved you 5 minutes, please give us a star on GitHub: ${chalk.underline('https://github.com/paudang/nodejs-quickstart-structure')}`));
|
|
78
|
+
|
|
79
|
+
} catch (error) {
|
|
80
|
+
if (error.name === 'ExitPromptError') {
|
|
81
|
+
console.log(chalk.yellow('\n\n👋 Goodbye! Setup cancelled.'));
|
|
82
|
+
process.exit(0);
|
|
83
|
+
}
|
|
84
|
+
console.error(chalk.red('Error generating project:'), error);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
program.parse(process.argv);
|
|
90
|
+
|
|
91
|
+
if (!process.argv.slice(2).length) {
|
|
92
|
+
program.outputHelp();
|
|
93
|
+
}
|
package/lib/generator.js
CHANGED
|
@@ -132,7 +132,7 @@ export const generateProject = async (config) => {
|
|
|
132
132
|
2. git init
|
|
133
133
|
3. npm install
|
|
134
134
|
4. npm run prepare (To setup Husky hooks)
|
|
135
|
-
5. docker-compose up -d (To start DB/Infrastructure)
|
|
135
|
+
5. docker-compose up -d${config.database !== 'None' ? ' db' : ''}${config.caching === 'Redis' ? ' redis' : ''}${config.communication === 'Kafka' ? ' kafka' : ''} (To start DB/Infrastructure)
|
|
136
136
|
6. npm run dev (To start development server)
|
|
137
137
|
7. npm test (To run tests)
|
|
138
138
|
`);
|
|
@@ -1,73 +1,76 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import ejs from 'ejs';
|
|
4
|
-
|
|
5
|
-
export const setupCaching = async (templatesDir, targetDir, config) => {
|
|
6
|
-
const { caching, language, architecture } = config;
|
|
7
|
-
if (!caching || caching === 'None') return;
|
|
8
|
-
|
|
9
|
-
if (caching === 'Redis' || caching === 'Memory Cache') {
|
|
10
|
-
const langExt = language === 'TypeScript' ? 'ts' : 'js';
|
|
11
|
-
const clientObj = caching === 'Redis'
|
|
12
|
-
? (language === 'TypeScript' ? 'redisClient.ts' : 'redisClient.js')
|
|
13
|
-
: (language === 'TypeScript' ? 'memoryCache.ts' : 'memoryCache.js');
|
|
14
|
-
const cacheSource = path.join(templatesDir, 'common', 'caching', langExt, `${clientObj}.ejs`);
|
|
15
|
-
|
|
16
|
-
let cacheTarget;
|
|
17
|
-
let loggerPath;
|
|
18
|
-
|
|
19
|
-
if (architecture === 'MVC') {
|
|
20
|
-
await fs.ensureDir(path.join(targetDir, 'src/config'));
|
|
21
|
-
cacheTarget = path.join(targetDir, 'src/config', clientObj);
|
|
22
|
-
loggerPath = language === 'TypeScript' ? '@/utils/logger' : '../utils/logger';
|
|
23
|
-
} else {
|
|
24
|
-
// Clean Architecture
|
|
25
|
-
await fs.ensureDir(path.join(targetDir, 'src/infrastructure/caching'));
|
|
26
|
-
cacheTarget = path.join(targetDir, 'src/infrastructure/caching', clientObj);
|
|
27
|
-
loggerPath = language === 'TypeScript' ? '@/infrastructure/log/logger' : '../log/logger';
|
|
28
|
-
|
|
29
|
-
// Overwrite
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import ejs from 'ejs';
|
|
4
|
+
|
|
5
|
+
export const setupCaching = async (templatesDir, targetDir, config) => {
|
|
6
|
+
const { caching, language, architecture } = config;
|
|
7
|
+
if (!caching || caching === 'None') return;
|
|
8
|
+
|
|
9
|
+
if (caching === 'Redis' || caching === 'Memory Cache') {
|
|
10
|
+
const langExt = language === 'TypeScript' ? 'ts' : 'js';
|
|
11
|
+
const clientObj = caching === 'Redis'
|
|
12
|
+
? (language === 'TypeScript' ? 'redisClient.ts' : 'redisClient.js')
|
|
13
|
+
: (language === 'TypeScript' ? 'memoryCache.ts' : 'memoryCache.js');
|
|
14
|
+
const cacheSource = path.join(templatesDir, 'common', 'caching', langExt, `${clientObj}.ejs`);
|
|
15
|
+
|
|
16
|
+
let cacheTarget;
|
|
17
|
+
let loggerPath;
|
|
18
|
+
|
|
19
|
+
if (architecture === 'MVC') {
|
|
20
|
+
await fs.ensureDir(path.join(targetDir, 'src/config'));
|
|
21
|
+
cacheTarget = path.join(targetDir, 'src/config', clientObj);
|
|
22
|
+
loggerPath = language === 'TypeScript' ? '@/utils/logger' : '../utils/logger';
|
|
23
|
+
} else {
|
|
24
|
+
// Clean Architecture
|
|
25
|
+
await fs.ensureDir(path.join(targetDir, 'src/infrastructure/caching'));
|
|
26
|
+
cacheTarget = path.join(targetDir, 'src/infrastructure/caching', clientObj);
|
|
27
|
+
loggerPath = language === 'TypeScript' ? '@/infrastructure/log/logger' : '../log/logger';
|
|
28
|
+
|
|
29
|
+
// Overwrite UseCases with Caching Enabled
|
|
30
|
+
const useCases = language === 'TypeScript'
|
|
31
|
+
? [
|
|
32
|
+
{ name: 'getAllUsers.ts', src: 'getAllUsers.ts.ejs' },
|
|
33
|
+
{ name: 'createUser.ts', src: 'createUser.ts.ejs' },
|
|
34
|
+
{ name: 'updateUser.ts', src: 'updateUser.ts.ejs' },
|
|
35
|
+
{ name: 'deleteUser.ts', src: 'deleteUser.ts.ejs' }
|
|
36
|
+
]
|
|
37
|
+
: [
|
|
38
|
+
{ name: 'GetAllUsers.js', src: 'GetAllUsers.js.ejs' },
|
|
39
|
+
{ name: 'CreateUser.js', src: 'CreateUser.js.ejs' },
|
|
40
|
+
{ name: 'UpdateUser.js', src: 'UpdateUser.js.ejs' },
|
|
41
|
+
{ name: 'DeleteUser.js', src: 'DeleteUser.js.ejs' }
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
const useCaseTargetDir = path.join(targetDir, 'src/usecases');
|
|
45
|
+
await fs.ensureDir(useCaseTargetDir);
|
|
46
|
+
|
|
47
|
+
for (const uc of useCases) {
|
|
48
|
+
const useCaseSource = path.join(templatesDir, 'common', 'caching', 'clean', langExt, uc.src);
|
|
49
|
+
if (await fs.pathExists(useCaseSource)) {
|
|
50
|
+
const ucContent = await fs.readFile(useCaseSource, 'utf-8');
|
|
51
|
+
const renderedUc = ejs.render(ucContent, { caching });
|
|
52
|
+
await fs.writeFile(path.join(useCaseTargetDir, uc.name), renderedUc);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (await fs.pathExists(cacheSource)) {
|
|
58
|
+
const cacheTemplate = await fs.readFile(cacheSource, 'utf-8');
|
|
59
|
+
const content = ejs.render(cacheTemplate, { loggerPath });
|
|
60
|
+
await fs.writeFile(cacheTarget, content);
|
|
61
|
+
|
|
62
|
+
// Render Spec if exists
|
|
63
|
+
const specTemplateName = clientObj.replace(`.${langExt}`, `.spec.${langExt}.ejs`);
|
|
64
|
+
const specTemplateSource = path.join(templatesDir, 'common', 'caching', langExt, specTemplateName);
|
|
65
|
+
if (await fs.pathExists(specTemplateSource)) {
|
|
66
|
+
const specTemplate = await fs.readFile(specTemplateSource, 'utf-8');
|
|
67
|
+
const specLoggerPath = architecture === 'Clean Architecture' ? '@/infrastructure/log/logger' : '@/utils/logger';
|
|
68
|
+
const specRedisPath = architecture === 'Clean Architecture' ? '@/infrastructure/caching/redisClient' : '@/config/redisClient';
|
|
69
|
+
const specContent = ejs.render(specTemplate, { ...config, loggerPath: specLoggerPath, redisClientPath: specRedisPath });
|
|
70
|
+
const specTarget = cacheTarget.replace(`${path.sep}src${path.sep}`, `${path.sep}tests${path.sep}unit${path.sep}`).replace(`.${langExt}`, `.spec.${langExt}`);
|
|
71
|
+
await fs.ensureDir(path.dirname(specTarget));
|
|
72
|
+
await fs.writeFile(specTarget, specContent);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
@@ -65,6 +65,10 @@ export const renderProfessionalConfig = async (templatesDir, targetDir, config)
|
|
|
65
65
|
const sonarTemplate = await fs.readFile(path.join(templatesDir, 'common', 'sonar-project.properties.ejs'), 'utf-8');
|
|
66
66
|
const sonarContent = ejs.render(sonarTemplate, { ...config });
|
|
67
67
|
await fs.writeFile(path.join(targetDir, 'sonar-project.properties'), sonarContent);
|
|
68
|
+
|
|
69
|
+
const snykTemplate = await fs.readFile(path.join(templatesDir, 'common', '.snyk.ejs'), 'utf-8');
|
|
70
|
+
const snykContent = ejs.render(snykTemplate, { ...config });
|
|
71
|
+
await fs.writeFile(path.join(targetDir, '.snyk'), snykContent);
|
|
68
72
|
}
|
|
69
73
|
};
|
|
70
74
|
|