create-express-esm 1.2.2 → 1.2.4
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/bin/cli.js
CHANGED
|
@@ -14,8 +14,8 @@ const __dirname = path.dirname(__filename);
|
|
|
14
14
|
async function run() {
|
|
15
15
|
console.clear();
|
|
16
16
|
|
|
17
|
-
// 1. 시작 인사
|
|
18
|
-
p.intro(`${chalk.bgBlue.white(' create-express-esm ')} ${chalk.dim('v1.2.
|
|
17
|
+
// 1. 시작 인사 (v1.2.2 버전 반영)
|
|
18
|
+
p.intro(`${chalk.bgBlue.white(' create-express-esm ')} ${chalk.dim('v1.2.2')}`);
|
|
19
19
|
|
|
20
20
|
try {
|
|
21
21
|
// 2. 사용자 질문 그룹
|
|
@@ -45,9 +45,20 @@ async function run() {
|
|
|
45
45
|
}),
|
|
46
46
|
useDb: () =>
|
|
47
47
|
p.confirm({
|
|
48
|
-
message: 'Prisma ORM
|
|
48
|
+
message: 'Prisma ORM 및 전역 에러 핸들링을 추가하시겠습니까?',
|
|
49
49
|
initialValue: false,
|
|
50
50
|
}),
|
|
51
|
+
// [New] DB 타입 선택 (useDb가 true일 때만 실행)
|
|
52
|
+
dbType: ({ results }) => {
|
|
53
|
+
if (!results.useDb) return;
|
|
54
|
+
return p.select({
|
|
55
|
+
message: '사용할 데이터베이스를 선택하세요:',
|
|
56
|
+
options: [
|
|
57
|
+
{ value: 'postgresql', label: 'PostgreSQL' },
|
|
58
|
+
{ value: 'mysql', label: 'MySQL' },
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
},
|
|
51
62
|
},
|
|
52
63
|
{
|
|
53
64
|
onCancel: () => {
|
|
@@ -57,7 +68,7 @@ async function run() {
|
|
|
57
68
|
}
|
|
58
69
|
);
|
|
59
70
|
|
|
60
|
-
const { projectName, language, useTest, useDb } = project;
|
|
71
|
+
const { projectName, language, useTest, useDb, dbType } = project;
|
|
61
72
|
const targetPath = path.join(process.cwd(), projectName);
|
|
62
73
|
const templatePath = path.join(__dirname, '../template', language);
|
|
63
74
|
const commonPath = path.join(__dirname, '../template/common');
|
|
@@ -88,11 +99,23 @@ async function run() {
|
|
|
88
99
|
|
|
89
100
|
// 4. DB 및 에러 핸들링 선택 시 추가 파일 복사 및 코드 주입
|
|
90
101
|
if (useDb) {
|
|
91
|
-
// (1) Prisma 설정 및 Docker Compose 복사
|
|
92
|
-
await fs.
|
|
93
|
-
|
|
102
|
+
// (1) Prisma 설정 및 Docker Compose 복사 (선택한 DB 타입에 맞춤)
|
|
103
|
+
await fs.ensureDir(path.join(targetPath, 'prisma'));
|
|
104
|
+
|
|
105
|
+
const prismaTemplate = `schema.prisma.${dbType}`;
|
|
106
|
+
const dockerTemplate = `docker-compose.yml.${dbType}`;
|
|
94
107
|
|
|
95
|
-
|
|
108
|
+
await fs.copy(
|
|
109
|
+
path.join(commonPath, 'prisma', prismaTemplate),
|
|
110
|
+
path.join(targetPath, 'prisma', 'schema.prisma')
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
await fs.copy(
|
|
114
|
+
path.join(commonPath, dockerTemplate),
|
|
115
|
+
path.join(targetPath, 'docker-compose.yml')
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// (2) 소스 코드 복사 (기존 로직 유지)
|
|
96
119
|
const sourceFolders = ['lib', 'services', 'controllers', 'routes', 'utils', 'middlewares'];
|
|
97
120
|
for (const folder of sourceFolders) {
|
|
98
121
|
const srcFolderPath = path.join(commonPath, 'src', folder);
|
|
@@ -102,7 +125,6 @@ async function run() {
|
|
|
102
125
|
await fs.ensureDir(destFolderPath);
|
|
103
126
|
const files = await fs.readdir(srcFolderPath);
|
|
104
127
|
for (const file of files) {
|
|
105
|
-
// 사용자가 선택한 언어(ts/js)와 일치하는 파일만 복사
|
|
106
128
|
if (file.endsWith(`.${language}`)) {
|
|
107
129
|
await fs.copy(path.join(srcFolderPath, file), path.join(destFolderPath, file));
|
|
108
130
|
}
|
|
@@ -110,39 +132,33 @@ async function run() {
|
|
|
110
132
|
}
|
|
111
133
|
}
|
|
112
134
|
|
|
113
|
-
// (3) app.ts / app.js 에 코드 주입
|
|
135
|
+
// (3) app.ts / app.js 에 코드 주입
|
|
114
136
|
const mainFilePath = path.join(targetPath, `src/app.${language}`);
|
|
115
137
|
if (await fs.pathExists(mainFilePath)) {
|
|
116
138
|
let content = await fs.readFile(mainFilePath, 'utf-8');
|
|
117
|
-
|
|
118
|
-
// 상단 임포트 주입
|
|
119
139
|
const imports = [
|
|
120
140
|
`import userRoutes from './routes/userRoutes.js';`,
|
|
121
141
|
`import { errorHandler } from './middlewares/errorMiddleware.js';`
|
|
122
142
|
].join('\n');
|
|
123
143
|
content = imports + '\n' + content;
|
|
124
|
-
|
|
125
|
-
//
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
// 전역 에러 핸들러 주입 (서버 실행 직전에)
|
|
130
|
-
const errorMiddlewareCode = `\n// 전역 에러 핸들러 (모든 라우터 다음에 위치해야 함)\napp.use(errorHandler);\n`;
|
|
131
|
-
if (content.includes('export default app;')) {
|
|
132
|
-
content = content.replace('export default app;', `${errorMiddlewareCode}\nexport default app;`);
|
|
133
|
-
} else {
|
|
134
|
-
content += `\n${errorMiddlewareCode}`;
|
|
135
|
-
}
|
|
136
|
-
|
|
144
|
+
content = content.replace('app.use(express.json());', `app.use(express.json());\napp.use('/users', userRoutes);`);
|
|
145
|
+
const errorMiddlewareCode = `\n// 전역 에러 핸들러\napp.use(errorHandler);\n`;
|
|
146
|
+
content = content.includes('export default app;')
|
|
147
|
+
? content.replace('export default app;', `${errorMiddlewareCode}\nexport default app;`)
|
|
148
|
+
: content + `\n${errorMiddlewareCode}`;
|
|
137
149
|
await fs.writeFile(mainFilePath, content);
|
|
138
150
|
}
|
|
139
151
|
|
|
140
|
-
// (4) .env 파일에 DATABASE_URL 추가
|
|
152
|
+
// (4) .env 파일에 DB 타입별 DATABASE_URL 추가
|
|
141
153
|
const envPath = path.join(targetPath, '.env');
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
`;
|
|
154
|
+
let dbUrlContent = '';
|
|
155
|
+
|
|
156
|
+
if (dbType === 'postgresql') {
|
|
157
|
+
dbUrlContent = `\n# PostgreSQL Connection\nDATABASE_URL="postgresql://myuser:mypassword@localhost:5433/mydb?schema=public"\n`;
|
|
158
|
+
} else if (dbType === 'mysql') {
|
|
159
|
+
dbUrlContent = `\n# MySQL Connection\nDATABASE_URL="mysql://root:mypassword@localhost:3307/mydb"\n`;
|
|
160
|
+
}
|
|
161
|
+
|
|
146
162
|
await fs.appendFile(envPath, dbUrlContent);
|
|
147
163
|
}
|
|
148
164
|
|
|
@@ -156,27 +172,22 @@ DATABASE_URL="postgresql://myuser:mypassword@localhost:5432/mydb?schema=public"
|
|
|
156
172
|
pkg.devDependencies["tsx"] = "^4.7.0";
|
|
157
173
|
}
|
|
158
174
|
|
|
159
|
-
// 테스트 환경 설정 (비사용 시 관련 파일 및 패키지 제거)
|
|
160
175
|
if (!useTest) {
|
|
161
176
|
const configExt = language === 'ts' ? 'ts' : 'js';
|
|
162
|
-
const testFileExt = language === 'ts' ? 'ts' : 'js';
|
|
163
177
|
await fs.remove(path.join(targetPath, `vitest.config.${configExt}`));
|
|
164
|
-
await fs.remove(path.join(targetPath, `src/app.test.${
|
|
178
|
+
await fs.remove(path.join(targetPath, `src/app.test.${configExt}`));
|
|
165
179
|
delete pkg.scripts.test;
|
|
166
180
|
delete pkg.scripts["test:ui"];
|
|
167
181
|
delete pkg.scripts["test:run"];
|
|
168
182
|
delete pkg.devDependencies.vitest;
|
|
169
183
|
delete pkg.devDependencies.supertest;
|
|
170
|
-
if (pkg.devDependencies["@types/supertest"]) delete pkg.devDependencies["@types/supertest"];
|
|
171
184
|
}
|
|
172
185
|
|
|
173
|
-
// DB 의존성 및 스크립트 추가
|
|
174
186
|
if (useDb) {
|
|
175
187
|
pkg.scripts["db:up"] = "docker-compose up -d";
|
|
176
188
|
pkg.scripts["db:push"] = "prisma db push";
|
|
177
189
|
pkg.scripts["prisma:generate"] = "prisma generate";
|
|
178
190
|
pkg.scripts["prisma:studio"] = "prisma studio";
|
|
179
|
-
|
|
180
191
|
pkg.dependencies["@prisma/client"] = "^5.0.0";
|
|
181
192
|
pkg.devDependencies["prisma"] = "^5.0.0";
|
|
182
193
|
}
|
|
@@ -187,7 +198,6 @@ DATABASE_URL="postgresql://myuser:mypassword@localhost:5432/mydb?schema=public"
|
|
|
187
198
|
// 6. 의존성 설치
|
|
188
199
|
const installSpinner = p.spinner();
|
|
189
200
|
installSpinner.start('의존성 패키지를 설치하는 중... (npm install)');
|
|
190
|
-
|
|
191
201
|
try {
|
|
192
202
|
execSync('npm install', { cwd: targetPath, stdio: 'ignore' });
|
|
193
203
|
installSpinner.stop('설치 완료!');
|
package/package.json
CHANGED