UNPKG

express-hale

Version:

๐Ÿš€ Interactive Express.js scaffold CLI with comprehensive error handling, TypeScript/JavaScript, database integrations, Git Flow, and development tools

553 lines (463 loc) โ€ข 15.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConfigTemplates = void 0; const base_renderer_1 = require("./base-renderer"); class ConfigTemplates extends base_renderer_1.BaseRenderer { renderNodemonConfig() { return JSON.stringify({ watch: ['src'], ext: 'ts,js,json', ignore: ['src/**/*.spec.ts', 'src/**/*.test.ts'], exec: 'ts-node src/index.ts', env: { NODE_ENV: 'development', }, delay: 1000, }, null, 2); } renderEnvFile(config) { let content = `# Server Configuration PORT=3000 NODE_ENV=development `; if (config.databases.includes('mysql')) { content += `# MySQL Configuration MYSQL_HOST=localhost MYSQL_PORT=3306 MYSQL_USER=root MYSQL_PASSWORD=your_password MYSQL_DATABASE=your_database `; } if (config.databases.includes('mongodb')) { content += `# MongoDB Configuration MONGODB_URI=mongodb://localhost:27017/your_database `; } if (config.databases.includes('redis')) { content += `# Redis Configuration REDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD=your_redis_password `; } content += `# JWT Secret (generate a strong secret in production) JWT_SECRET=your_jwt_secret_key # API Configuration API_VERSION=v1 API_BASE_URL=http://localhost:3000`; return content; } renderEnvExampleFile(config) { return this.renderEnvFile(config).replace(/=.+$/gm, '='); } renderTsConfig() { return JSON.stringify({ compilerOptions: { target: 'ES2020', module: 'commonjs', lib: ['ES2020'], outDir: './dist', rootDir: './src', strict: true, esModuleInterop: true, skipLibCheck: true, forceConsistentCasingInFileNames: true, declaration: true, sourceMap: true, resolveJsonModule: true, moduleResolution: 'node', }, include: ['src/**/*'], exclude: ['node_modules', 'dist', '**/*.test.ts'], }, null, 2); } renderEslintConfig(config) { if (config.language === 'typescript') { return `const js = require('@eslint/js'); const tseslint = require('@typescript-eslint/eslint-plugin'); const tsparser = require('@typescript-eslint/parser');${config.prettier ? "\nconst prettier = require('eslint-plugin-prettier');\nconst prettierConfig = require('eslint-config-prettier');" : ''} module.exports = [ js.configs.recommended, { files: ['**/*.ts', '**/*.tsx'], languageOptions: { parser: tsparser, parserOptions: { ecmaVersion: 2020, sourceType: 'module', }, globals: { console: 'readonly', process: 'readonly', Buffer: 'readonly', __dirname: 'readonly', __filename: 'readonly', exports: 'writable', module: 'writable', require: 'readonly', global: 'readonly', setTimeout: 'readonly', clearTimeout: 'readonly', setInterval: 'readonly', clearInterval: 'readonly', }, }, plugins: { '@typescript-eslint': tseslint${config.prettier ? ",\n 'prettier': prettier" : ''} }, rules: { ...tseslint.configs.recommended.rules, '@typescript-eslint/no-unused-vars': 'error', '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/no-explicit-any': 'warn'${config.prettier ? ",\n 'prettier/prettier': 'error'" : ''} }, }${config.prettier ? ',\n prettierConfig' : ''} ];`; } else { return `const js = require('@eslint/js');${config.prettier ? "\nconst prettier = require('eslint-plugin-prettier');\nconst prettierConfig = require('eslint-config-prettier');" : ''} module.exports = [ js.configs.recommended, { files: ['**/*.js', '**/*.mjs'], languageOptions: { ecmaVersion: 2020, sourceType: 'module', globals: { console: 'readonly', process: 'readonly', Buffer: 'readonly', __dirname: 'readonly', __filename: 'readonly', exports: 'writable', module: 'writable', require: 'readonly', global: 'readonly', setTimeout: 'readonly', clearTimeout: 'readonly', setInterval: 'readonly', clearInterval: 'readonly', }, }${config.prettier ? ",\n plugins: {\n 'prettier': prettier\n }" : ''}, rules: { 'no-unused-vars': 'error', 'no-console': 'off'${config.prettier ? ",\n 'prettier/prettier': 'error'" : ''} }, }${config.prettier ? ',\n prettierConfig' : ''} ];`; } } renderPrettierConfig() { return JSON.stringify({ semi: true, trailingComma: 'es5', singleQuote: true, printWidth: 80, tabWidth: 2, useTabs: false, }, null, 2); } renderJestConfig(config) { if (config.language === 'typescript') { return `module.exports = { preset: 'ts-jest', testEnvironment: 'node', roots: ['<rootDir>/src', '<rootDir>/tests'], testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'], transform: { '^.+\\.ts$': 'ts-jest' }, collectCoverageFrom: [ 'src/**/*.ts', '!src/**/*.d.ts' ], coverageDirectory: 'coverage', coverageReporters: ['text', 'lcov', 'html'] };`; } else { return `module.exports = { testEnvironment: 'node', roots: ['<rootDir>/src', '<rootDir>/tests'], testMatch: ['**/__tests__/**/*.js', '**/?(*.)+(spec|test).js'], collectCoverageFrom: [ 'src/**/*.js' ], coverageDirectory: 'coverage', coverageReporters: ['text', 'lcov', 'html'] };`; } } renderReadme(projectName, config) { const features = []; // Add language feature features.push(`- ๐Ÿš€ **${config.language === 'typescript' ? 'TypeScript' : 'JavaScript'}** ๆ”ฏๆŒ`); // Add database features if (config.databases.includes('mysql')) features.push('- ๐Ÿ—„๏ธ **MySQL** ๆ•ฐๆฎๅบ“้›†ๆˆ'); if (config.databases.includes('mongodb')) features.push('- ๐Ÿƒ **MongoDB** ๆ•ฐๆฎๅบ“้›†ๆˆ'); if (config.databases.includes('redis')) features.push('- ๐Ÿ”ด **Redis** ็ผ“ๅญ˜้›†ๆˆ'); // Add development tools if (config.eslint) features.push('- ๐Ÿ” **ESLint** ไปฃ็ ๆฃ€ๆŸฅ'); if (config.prettier) features.push('- ๐Ÿ’… **Prettier** ไปฃ็ ๆ ผๅผๅŒ–'); if (config.testing === 'jest') features.push('- ๐Ÿงช **Jest** ๅ•ๅ…ƒๆต‹่ฏ•'); if (config.docker) features.push('- ๐Ÿณ **Docker** ๅฎนๅ™จๅŒ–ๆ”ฏๆŒ'); if (config.gitFlow) features.push('- ๐ŸŒŠ **Git Flow** ๅทฅไฝœๆต'); // Add built-in features features.push('- ๐Ÿ›ก๏ธ **ๅฎ‰ๅ…จไธญ้—ดไปถ** (Helmet, CORS)'); features.push('- ๐Ÿ“ **่ฏทๆฑ‚ๆ—ฅๅฟ—** ๅฝฉ่‰ฒๅฏ่ง†ๅŒ–ๆ˜พ็คบ'); features.push('- โšก **ๅผ‚ๆญฅ้”™่ฏฏๅค„็†** ๅฎŒๆ•ด็š„้”™่ฏฏๅค„็†ๆœบๅˆถ'); features.push('- ๐Ÿ”„ **ไผ˜้›…ๅ…ณ้—ญ** ่ฟ›็จ‹ไฟกๅทๅค„็†'); features.push('- ๐Ÿ“Š **ๅฅๅบทๆฃ€ๆŸฅ** ๅ†…็ฝฎๅฅๅบทๆฃ€ๆŸฅ็ซฏ็‚น'); features.push('- ๐ŸŽฏ **้”™่ฏฏ็›‘ๆŽง** ็”Ÿไบง็Žฏๅขƒ้”™่ฏฏ่ฟฝ่ธช'); return `# ${projectName} > ๐Ÿš€ ๅŸบไบŽ Express.js ็š„็ŽฐไปฃๅŒ– Web ๅบ”็”จ็จ‹ๅบ๏ผŒไฝฟ็”จ express-hale CLI ็”Ÿๆˆ ## โœจ ็‰นๆ€ง ${features.join('\n')} ## ๐Ÿ› ๏ธ ๆŠ€ๆœฏๆ ˆ - **ๆก†ๆžถ**: Express.js - **่ฏญ่จ€**: ${config.language === 'typescript' ? 'TypeScript' : 'JavaScript'} ${config.databases.length > 0 ? `- **ๆ•ฐๆฎๅบ“**: ${config.databases.map(db => db.charAt(0).toUpperCase() + db.slice(1)).join(', ')}` : ''} - **ๅผ€ๅ‘ๅทฅๅ…ท**: ${[ config.eslint && 'ESLint', config.prettier && 'Prettier', config.testing === 'jest' && 'Jest', 'Nodemon' ].filter(Boolean).join(', ')} ${config.docker ? '- **ๅฎนๅ™จๅŒ–**: Docker & Docker Compose' : ''} ## ๐Ÿš€ ๅฟซ้€Ÿๅผ€ๅง‹ ### ๅฎ‰่ฃ…ไพ่ต– \`\`\`bash npm install \`\`\` ### ็Žฏๅขƒ้…็ฝฎ ๅคๅˆถ็Žฏๅขƒๅ˜้‡ๆจกๆฟๆ–‡ไปถ๏ผš \`\`\`bash cp .env.example .env \`\`\` ็ผ–่พ‘ \`.env\` ๆ–‡ไปถ๏ผŒ้…็ฝฎไฝ ็š„็Žฏๅขƒๅ˜้‡ใ€‚ ### ๅผ€ๅ‘ๆจกๅผ \`\`\`bash npm run dev \`\`\` ๅบ”็”จๅฐ†ๅœจ [http://localhost:3000](http://localhost:3000) ๅฏๅŠจ ### ็”Ÿไบงๆจกๅผ ${config.language === 'typescript' ? `\`\`\`bash # ๆž„ๅปบ้กน็›ฎ npm run build # ๅฏๅŠจ็”ŸไบงๆœๅŠก npm start \`\`\`` : `\`\`\`bash npm start \`\`\``} ## ๐Ÿ“ ้กน็›ฎ็ป“ๆž„ \`\`\` ${projectName}/ โ”œโ”€โ”€ src/ โ”‚ โ”œโ”€โ”€ config/ # ๆ•ฐๆฎๅบ“้…็ฝฎ โ”‚ โ”œโ”€โ”€ middleware/ # ไธญ้—ดไปถ โ”‚ โ”œโ”€โ”€ routes/ # ่ทฏ็”ฑๅฎšไน‰ โ”‚ โ”œโ”€โ”€ utils/ # ๅทฅๅ…ทๅ‡ฝๆ•ฐ โ”‚ โ””โ”€โ”€ index.${config.language === 'typescript' ? 'ts' : 'js'} # ๅบ”็”จๅ…ฅๅฃ โ”œโ”€โ”€ tests/ # ๆต‹่ฏ•ๆ–‡ไปถ ${config.docker ? 'โ”œโ”€โ”€ docker-compose.yml # Docker ็ผ–ๆŽ’ๆ–‡ไปถ\nโ”œโ”€โ”€ Dockerfile # Docker ้•œๅƒ้…็ฝฎ' : ''} โ”œโ”€โ”€ .env.example # ็Žฏๅขƒๅ˜้‡ๆจกๆฟ โ”œโ”€โ”€ package.json # ้กน็›ฎ้…็ฝฎ ${config.language === 'typescript' ? 'โ”œโ”€โ”€ tsconfig.json # TypeScript ้…็ฝฎ' : ''} ${config.eslint ? 'โ”œโ”€โ”€ eslint.config.js # ESLint ้…็ฝฎ' : ''} ${config.prettier ? 'โ”œโ”€โ”€ .prettierrc # Prettier ้…็ฝฎ' : ''} ${config.testing === 'jest' ? 'โ”œโ”€โ”€ jest.config.js # Jest ้…็ฝฎ' : ''} ${config.gitFlow ? 'โ””โ”€โ”€ GIT_FLOW.md # Git Flow ๅทฅไฝœๆต่ฏดๆ˜Ž' : ''} \`\`\` ## ๐Ÿ”ง ๅฏ็”จ่„šๆœฌ - \`npm run dev\` - ๅฏๅŠจๅผ€ๅ‘ๆœๅŠกๅ™จ ${config.language === 'typescript' ? '- `npm run build` - ๆž„ๅปบ็”Ÿไบง็‰ˆๆœฌ' : ''} - \`npm start\` - ๅฏๅŠจ็”ŸไบงๆœๅŠกๅ™จ ${config.testing === 'jest' ? '- `npm test` - ่ฟ่กŒๆต‹่ฏ•' : ''} ${config.eslint ? '- `npm run lint` - ไปฃ็ ๆฃ€ๆŸฅ' : ''} ${config.prettier ? '- `npm run format` - ไปฃ็ ๆ ผๅผๅŒ–' : ''} ## ๐ŸŒ API ็ซฏ็‚น ### ๅฅๅบทๆฃ€ๆŸฅ - **GET** \`/health\` - ๅบ”็”จๅฅๅบท็Šถๆ€ๆฃ€ๆŸฅ ### ็คบไพ‹ API - **GET** \`/api/users\` - ่Žทๅ–็”จๆˆทๅˆ—่กจ - **POST** \`/api/users\` - ๅˆ›ๅปบๆ–ฐ็”จๆˆท - **GET** \`/api/error-test\` - ้”™่ฏฏๅค„็†ๆต‹่ฏ• ## ๐Ÿ“Š ่ฏทๆฑ‚ๆ—ฅๅฟ— ๅบ”็”จๅ†…็ฝฎไบ†ๅฝฉ่‰ฒๅฏ่ง†ๅŒ–็š„่ฏทๆฑ‚ๆ—ฅๅฟ—็ณป็ปŸ๏ผš \`\`\` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ ๐ŸŒ HTTP REQUEST LOG โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โฐ Time: 2025/08/10 20:48:08 โ”‚ ๐Ÿ”— Method: GET โ”‚ ๐Ÿ“ Path: /health โ”‚ ๐Ÿ“Š Status: 200 โ”‚ โšก Duration: 1ms โ”‚ ๐Ÿ“ฆ Size: 156 bytes โ”‚ ๐ŸŒ Client: ::1 โ”‚ ๐Ÿ”ง Agent: PostmanRuntime/7.45.0 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ \`\`\` ## ๐Ÿ›ก๏ธ ๅฎ‰ๅ…จ็‰นๆ€ง - **Helmet**: ่ฎพ็ฝฎๅ„็ง HTTP ๅคดๆฅไฟๆŠคๅบ”็”จ - **CORS**: ่ทจๅŸŸ่ต„ๆบๅ…ฑไบซ้…็ฝฎ - **่ฏทๆฑ‚ๅคงๅฐ้™ๅˆถ**: ้˜ฒๆญขๅคงๅž‹่ฏทๆฑ‚ๆ”ปๅ‡ป - **้”™่ฏฏๅค„็†**: ็”Ÿไบง็Žฏๅขƒไธ‹้š่—ๆ•ๆ„Ÿ้”™่ฏฏไฟกๆฏ ## ๐Ÿ”„ ้”™่ฏฏๅค„็† ๅบ”็”จๅŒ…ๅซๅฎŒๆ•ด็š„้”™่ฏฏๅค„็†ๆœบๅˆถ๏ผš - **ๅผ‚ๆญฅ้”™่ฏฏๅŒ…่ฃ…ๅ™จ**: ่‡ชๅŠจๆ•่Žทๅผ‚ๆญฅ่ทฏ็”ฑไธญ็š„้”™่ฏฏ - **ๅ…จๅฑ€้”™่ฏฏๅค„็†ๅ™จ**: ็ปŸไธ€็š„้”™่ฏฏๅ“ๅบ”ๆ ผๅผ - **404 ๅค„็†ๅ™จ**: ไผ˜้›…ๅค„็†ๆœชๆ‰พๅˆฐ็š„่ทฏ็”ฑ - **้”™่ฏฏ็›‘ๆŽง**: ็”Ÿไบง็Žฏๅขƒ้”™่ฏฏ่ฟฝ่ธชๅ’ŒๆŠฅๅ‘Š ${config.databases.length > 0 ? `## ๐Ÿ—„๏ธ ๆ•ฐๆฎๅบ“้…็ฝฎ ${config.databases.includes('mysql') ? `### MySQL \`\`\`bash MYSQL_HOST=localhost MYSQL_PORT=3306 MYSQL_USER=root MYSQL_PASSWORD=your_password MYSQL_DATABASE=your_database \`\`\` ` : ''}${config.databases.includes('mongodb') ? `### MongoDB \`\`\`bash MONGODB_URI=mongodb://localhost:27017/your_database \`\`\` ` : ''}${config.databases.includes('redis') ? `### Redis \`\`\`bash REDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD=your_redis_password \`\`\` ` : ''}` : ''}${config.docker ? `## ๐Ÿณ Docker ๆ”ฏๆŒ ### ไฝฟ็”จ Docker Compose \`\`\`bash # ๅฏๅŠจๆ‰€ๆœ‰ๆœๅŠก docker-compose up -d # ๆŸฅ็œ‹ๆ—ฅๅฟ— docker-compose logs -f # ๅœๆญขๆœๅŠก docker-compose down \`\`\` ### ๅ•็‹ฌไฝฟ็”จ Docker \`\`\`bash # ๆž„ๅปบ้•œๅƒ docker build -t ${projectName.toLowerCase()} . # ่ฟ่กŒๅฎนๅ™จ docker run -p 3000:3000 ${projectName.toLowerCase()} \`\`\` ` : ''}${config.gitFlow ? `## ๐ŸŒŠ Git Flow ๅทฅไฝœๆต ๆœฌ้กน็›ฎไฝฟ็”จ Git Flow ๅทฅไฝœๆต่ฟ›่กŒ็‰ˆๆœฌ็ฎก็†ใ€‚่ฏฆ็ป†่ฏดๆ˜Ž่ฏทๆŸฅ็œ‹ [GIT_FLOW.md](./GIT_FLOW.md)ใ€‚ ### ๅฟซ้€Ÿๅ‘ฝไปค \`\`\`bash # ๅผ€ๅง‹ๆ–ฐๅŠŸ่ƒฝ npm run git:feature <feature-name> # ๅฎŒๆˆๅŠŸ่ƒฝๅผ€ๅ‘ npm run git:feature:finish <feature-name> # ๅผ€ๅง‹ๅ‘ๅธƒ npm run git:release <version> # ๅฎŒๆˆๅ‘ๅธƒ npm run git:release:finish <version> \`\`\` ` : ''}## ๐Ÿค ่ดก็Œฎ 1. Fork ๆœฌไป“ๅบ“ 2. ๅˆ›ๅปบไฝ ็š„็‰นๆ€งๅˆ†ๆ”ฏ (\`git checkout -b feature/AmazingFeature\`) 3. ๆไบคไฝ ็š„ไฟฎๆ”น (\`git commit -m 'Add some AmazingFeature'\`) 4. ๆŽจ้€ๅˆฐๅˆ†ๆ”ฏ (\`git push origin feature/AmazingFeature\`) 5. ๆ‰“ๅผ€ไธ€ไธช Pull Request ## ๐Ÿ“„ ่ฎธๅฏ่ฏ ๆœฌ้กน็›ฎๅŸบไบŽ MIT ่ฎธๅฏ่ฏ - ๆŸฅ็œ‹ [LICENSE](LICENSE) ๆ–‡ไปถไบ†่งฃ่ฏฆๆƒ… ## ๐Ÿ™ ่‡ด่ฐข - [Express.js](https://expressjs.com/) - ๅฟซ้€Ÿใ€ๅผ€ๆ”พใ€ๆž็ฎ€็š„ Web ๆก†ๆžถ - [express-hale](https://www.npmjs.com/package/express-hale) - ็ŽฐไปฃๅŒ–็š„ Express.js ้กน็›ฎ็”Ÿๆˆๅ™จ --- โญ ๅฆ‚ๆžœ่ฟ™ไธช้กน็›ฎๅฏนไฝ ๆœ‰ๅธฎๅŠฉ๏ผŒ่ฏท็ป™ๅฎƒไธ€ไธชๆ˜Ÿๆ ‡๏ผ`; } renderGitignore() { return `# Dependencies node_modules/ npm-debug.log* yarn-debug.log* yarn-error.log* # Runtime data pids *.pid *.seed *.pid.lock # Coverage directory used by tools like istanbul coverage/ *.lcov # nyc test coverage .nyc_output # Grunt intermediate storage .grunt # Bower dependency directory bower_components # node-waf configuration .lock-wscript # Compiled binary addons build/Release # Dependency directories node_modules/ jspm_packages/ # TypeScript output dist/ *.tsbuildinfo # Optional npm cache directory .npm # Optional REPL history .node_repl_history # Output of 'npm pack' *.tgz # Yarn Integrity file .yarn-integrity # dotenv environment variables file .env .env.test .env.local .env.production # parcel-bundler cache .cache .parcel-cache # Next.js build output .next # Nuxt.js build / generate output .nuxt # Gatsby files .cache/ public # Storybook build outputs .out .storybook-out # Temporary folders tmp/ temp/ # Logs logs *.log # Editor directories and files .vscode/ .idea/ *.swp *.swo *~ # OS generated files .DS_Store .DS_Store? ._* .Spotlight-V100 .Trashes ehthumbs.db Thumbs.db`; } } exports.ConfigTemplates = ConfigTemplates; //# sourceMappingURL=config-templates.js.map