@sachin-thakur/create-nodejs-app 1.0.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/DEVELOPMENT.md +183 -0
- package/README.md +238 -0
- package/bin/cli.js +177 -0
- package/package.json +36 -0
- package/src/generator.js +121 -0
- package/src/templates/clean.js +11 -0
- package/src/templates/featureBased.js +11 -0
- package/src/templates/index.js +76 -0
- package/src/templates/mvc.js +890 -0
- package/src/utils/cicd.js +99 -0
- package/src/utils/docker.js +157 -0
- package/src/utils/envFile.js +102 -0
- package/src/utils/packageJson.js +142 -0
- package/src/utils/readme.js +277 -0
- package/test.sh +40 -0
package/src/generator.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { generatePackageJson } = require('./utils/packageJson');
|
|
4
|
+
const { generateEnvFile } = require('./utils/envFile');
|
|
5
|
+
const { generateReadme } = require('./utils/readme');
|
|
6
|
+
const { generateDockerFiles } = require('./utils/docker');
|
|
7
|
+
const { generateGitHubActions } = require('./utils/cicd');
|
|
8
|
+
const { generateSourceFiles } = require('./templates');
|
|
9
|
+
|
|
10
|
+
async function generateProject(projectName, projectPath, config) {
|
|
11
|
+
// Create project directory
|
|
12
|
+
await fs.ensureDir(projectPath);
|
|
13
|
+
|
|
14
|
+
// Generate package.json
|
|
15
|
+
const packageJson = generatePackageJson(projectName, config);
|
|
16
|
+
await fs.writeJson(path.join(projectPath, 'package.json'), packageJson, { spaces: 2 });
|
|
17
|
+
|
|
18
|
+
// Generate .env.example
|
|
19
|
+
const envContent = generateEnvFile(config);
|
|
20
|
+
await fs.writeFile(path.join(projectPath, '.env.example'), envContent);
|
|
21
|
+
|
|
22
|
+
// Generate .gitignore
|
|
23
|
+
const gitignore = `
|
|
24
|
+
node_modules/
|
|
25
|
+
dist/
|
|
26
|
+
build/
|
|
27
|
+
.env
|
|
28
|
+
.env.local
|
|
29
|
+
*.log
|
|
30
|
+
coverage/
|
|
31
|
+
.DS_Store
|
|
32
|
+
.vscode/
|
|
33
|
+
.idea/
|
|
34
|
+
*.swp
|
|
35
|
+
*.swo
|
|
36
|
+
`.trim();
|
|
37
|
+
await fs.writeFile(path.join(projectPath, '.gitignore'), gitignore);
|
|
38
|
+
|
|
39
|
+
// Generate README.md
|
|
40
|
+
const readme = generateReadme(projectName, config);
|
|
41
|
+
await fs.writeFile(path.join(projectPath, 'README.md'), readme);
|
|
42
|
+
|
|
43
|
+
// Generate source files based on architecture
|
|
44
|
+
await generateSourceFiles(projectPath, config);
|
|
45
|
+
|
|
46
|
+
// Generate Docker files if requested
|
|
47
|
+
if (config.docker) {
|
|
48
|
+
await generateDockerFiles(projectPath, config);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Generate CI/CD files if requested
|
|
52
|
+
if (config.cicd) {
|
|
53
|
+
await generateGitHubActions(projectPath, config);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Generate TypeScript config if needed
|
|
57
|
+
if (config.language === 'typescript') {
|
|
58
|
+
const tsConfig = {
|
|
59
|
+
compilerOptions: {
|
|
60
|
+
target: 'ES2022',
|
|
61
|
+
module: 'commonjs',
|
|
62
|
+
lib: ['ES2022'],
|
|
63
|
+
outDir: './dist',
|
|
64
|
+
rootDir: './src',
|
|
65
|
+
strict: true,
|
|
66
|
+
esModuleInterop: true,
|
|
67
|
+
skipLibCheck: true,
|
|
68
|
+
forceConsistentCasingInFileNames: true,
|
|
69
|
+
resolveJsonModule: true,
|
|
70
|
+
moduleResolution: 'node',
|
|
71
|
+
baseUrl: './src',
|
|
72
|
+
paths: {
|
|
73
|
+
'@/*': ['./*'],
|
|
74
|
+
'@config/*': ['./config/*'],
|
|
75
|
+
'@controllers/*': ['./controllers/*'],
|
|
76
|
+
'@models/*': ['./models/*'],
|
|
77
|
+
'@services/*': ['./services/*'],
|
|
78
|
+
'@middlewares/*': ['./middlewares/*'],
|
|
79
|
+
'@utils/*': ['./utils/*'],
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
include: ['src/**/*'],
|
|
83
|
+
exclude: ['node_modules', 'dist'],
|
|
84
|
+
};
|
|
85
|
+
await fs.writeJson(path.join(projectPath, 'tsconfig.json'), tsConfig, { spaces: 2 });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Generate ESLint config
|
|
89
|
+
const eslintConfig = {
|
|
90
|
+
env: {
|
|
91
|
+
node: true,
|
|
92
|
+
es2022: true,
|
|
93
|
+
},
|
|
94
|
+
extends: [
|
|
95
|
+
'eslint:recommended',
|
|
96
|
+
config.language === 'typescript' ? '@typescript-eslint/recommended' : null,
|
|
97
|
+
].filter(Boolean),
|
|
98
|
+
parser: config.language === 'typescript' ? '@typescript-eslint/parser' : undefined,
|
|
99
|
+
parserOptions: {
|
|
100
|
+
ecmaVersion: 2022,
|
|
101
|
+
sourceType: 'module',
|
|
102
|
+
},
|
|
103
|
+
rules: {
|
|
104
|
+
'no-console': 'warn',
|
|
105
|
+
'no-unused-vars': 'warn',
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
await fs.writeJson(path.join(projectPath, '.eslintrc.json'), eslintConfig, { spaces: 2 });
|
|
109
|
+
|
|
110
|
+
// Generate Prettier config
|
|
111
|
+
const prettierConfig = {
|
|
112
|
+
semi: true,
|
|
113
|
+
trailingComma: 'es5',
|
|
114
|
+
singleQuote: true,
|
|
115
|
+
printWidth: 100,
|
|
116
|
+
tabWidth: 2,
|
|
117
|
+
};
|
|
118
|
+
await fs.writeJson(path.join(projectPath, '.prettierrc'), prettierConfig, { spaces: 2 });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = { generateProject };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
async function generateCleanArchitecture(srcPath, config) {
|
|
5
|
+
// TODO: Implement Clean Architecture structure
|
|
6
|
+
// For now, we'll use MVC as a fallback
|
|
7
|
+
const { generateMVCStructure } = require('./mvc');
|
|
8
|
+
await generateMVCStructure(srcPath, config);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = { generateCleanArchitecture };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
async function generateFeatureBasedStructure(srcPath, config) {
|
|
5
|
+
// TODO: Implement Feature-based Architecture structure
|
|
6
|
+
// For now, we'll use MVC as a fallback
|
|
7
|
+
const { generateMVCStructure } = require('./mvc');
|
|
8
|
+
await generateMVCStructure(srcPath, config);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = { generateFeatureBasedStructure };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { generateMVCStructure } = require('./mvc');
|
|
4
|
+
const { generateCleanArchitecture } = require('./clean');
|
|
5
|
+
const { generateFeatureBasedStructure } = require('./featureBased');
|
|
6
|
+
|
|
7
|
+
async function generateSourceFiles(projectPath, config) {
|
|
8
|
+
const srcPath = path.join(projectPath, 'src');
|
|
9
|
+
await fs.ensureDir(srcPath);
|
|
10
|
+
|
|
11
|
+
// Generate based on architecture
|
|
12
|
+
if (config.architecture === 'mvc') {
|
|
13
|
+
await generateMVCStructure(srcPath, config);
|
|
14
|
+
} else if (config.architecture === 'clean') {
|
|
15
|
+
await generateCleanArchitecture(srcPath, config);
|
|
16
|
+
} else if (config.architecture === 'feature-based') {
|
|
17
|
+
await generateFeatureBasedStructure(srcPath, config);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Generate tests directory
|
|
21
|
+
const testsPath = path.join(projectPath, 'tests');
|
|
22
|
+
await fs.ensureDir(testsPath);
|
|
23
|
+
|
|
24
|
+
if (config.testing !== 'none') {
|
|
25
|
+
await generateTestFiles(testsPath, config);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function generateTestFiles(testsPath, config) {
|
|
30
|
+
const ext = config.language === 'typescript' ? 'ts' : 'js';
|
|
31
|
+
|
|
32
|
+
const exampleTest = config.language === 'typescript'
|
|
33
|
+
? `import { describe, it, expect } from '${config.testing === 'vitest' ? 'vitest' : '@jest/globals'}';
|
|
34
|
+
|
|
35
|
+
describe('Example Test Suite', () => {
|
|
36
|
+
it('should pass this basic test', () => {
|
|
37
|
+
expect(true).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should perform basic arithmetic', () => {
|
|
41
|
+
expect(2 + 2).toBe(4);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
`
|
|
45
|
+
: `const { describe, it, expect } = require('${config.testing === 'vitest' ? 'vitest' : '@jest/globals'}');
|
|
46
|
+
|
|
47
|
+
describe('Example Test Suite', () => {
|
|
48
|
+
it('should pass this basic test', () => {
|
|
49
|
+
expect(true).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should perform basic arithmetic', () => {
|
|
53
|
+
expect(2 + 2).toBe(4);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
`;
|
|
57
|
+
|
|
58
|
+
await fs.writeFile(path.join(testsPath, `example.test.${ext}`), exampleTest);
|
|
59
|
+
|
|
60
|
+
// Jest/Vitest config
|
|
61
|
+
if (config.testing === 'jest' && config.language === 'typescript') {
|
|
62
|
+
const jestConfig = {
|
|
63
|
+
preset: 'ts-jest',
|
|
64
|
+
testEnvironment: 'node',
|
|
65
|
+
roots: ['<rootDir>/tests', '<rootDir>/src'],
|
|
66
|
+
testMatch: ['**/*.test.ts'],
|
|
67
|
+
collectCoverageFrom: [
|
|
68
|
+
'src/**/*.ts',
|
|
69
|
+
'!src/**/*.d.ts',
|
|
70
|
+
],
|
|
71
|
+
};
|
|
72
|
+
await fs.writeJson(path.join(testsPath, '../jest.config.json'), jestConfig, { spaces: 2 });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = { generateSourceFiles };
|