|
1 | 1 | #!/usr/bin/env node |
2 | 2 |
|
3 | 3 | import { Option, program } from "commander"; |
4 | | -import fs from "fs-extra"; |
5 | | -import path from "path"; |
6 | | -import { fileURLToPath } from "url"; |
7 | | -import { execSync } from "child_process"; |
8 | 4 | import figlet from "figlet"; |
9 | 5 | import chalk from "chalk"; |
10 | | -import { createSpinner } from "nanospinner"; |
11 | 6 | import { |
12 | 7 | metadata, |
13 | 8 | commands, |
14 | 9 | templates, |
15 | 10 | supportedDockerComposeCacheImages, |
16 | 11 | } from "./configs.js"; |
17 | | -import validate from "validate-npm-package-name"; |
18 | | -import { |
19 | | - getServicesData, |
20 | | - generateDockerComposeFile, |
21 | | - userPrompts, |
22 | | -} from "./util/docker.js"; |
23 | | -import { initMenu } from "./util/menu.js"; |
24 | 12 | import { clearCWD } from "./util/clear.js"; |
25 | | - |
26 | | -const __filename = fileURLToPath(import.meta.url); |
27 | | -const __dirname = path.dirname(__filename); |
28 | | -const parentDir = path.dirname(__dirname); |
| 13 | +import { initCommand } from "./init.js"; |
29 | 14 |
|
30 | 15 | program |
31 | 16 | .name(metadata.command) |
@@ -113,252 +98,6 @@ program |
113 | 98 | clearCWD(); |
114 | 99 | }); |
115 | 100 |
|
116 | | -async function initCommand(options) { |
117 | | - const selectedTemplate = options.template || "basic"; // Default to 'basic' if no template is specified |
118 | | - const packageName = options.name || "qse-server"; // Default to 'qse-server' if no name is specified |
119 | | - const removeNodemon = options.removeNodemon; |
120 | | - const removeDependencies = options.removeDeps; |
121 | | - |
122 | | - if (!options.template) { |
123 | | - initMenu(initCommand, options); |
124 | | - return; |
125 | | - } |
126 | | - |
127 | | - // Docker Compose options. |
128 | | - const dockerCompose = options.dockerCompose; |
129 | | - const cacheService = options.cacheService; |
130 | | - const skipDb = options.skipDb || false; |
131 | | - |
132 | | - if (packageName) { |
133 | | - const validateResult = validate(packageName); |
134 | | - if (validateResult.validForNewPackages === false) { |
135 | | - const errors = validateResult.errors || validateResult.warnings; |
136 | | - console.error( |
137 | | - chalk.red.bold( |
138 | | - `Invalid package name: ${errors.join( |
139 | | - ", ", |
140 | | - )}. Please provide a valid package name.`, |
141 | | - ), |
142 | | - ); |
143 | | - return; |
144 | | - } |
145 | | - } |
146 | | - |
147 | | - if (!templates[selectedTemplate]) { |
148 | | - console.error( |
149 | | - chalk.red( |
150 | | - `Template ${chalk.bgRed.bold( |
151 | | - selectedTemplate, |
152 | | - )} does not exist. To see available templates use ${chalk.yellow( |
153 | | - '"qse list"', |
154 | | - )}.`, |
155 | | - ), |
156 | | - ); |
157 | | - return; |
158 | | - } |
159 | | - |
160 | | - const targetDir = process.cwd(); |
161 | | - const templatePath = path.join( |
162 | | - parentDir, |
163 | | - "templates", |
164 | | - templates[selectedTemplate].name, |
165 | | - ); |
166 | | - |
167 | | - const isUrl = templates[selectedTemplate].isUrl; |
168 | | - const needDB = templates[selectedTemplate].needDB && !skipDb; |
169 | | - |
170 | | - let dockerTemplate = |
171 | | - selectedTemplate.split("_")[0] === "express" || |
172 | | - selectedTemplate.split("_")[0] === "basic" |
173 | | - ? "express" |
174 | | - : selectedTemplate.split("_")[0]; |
175 | | - |
176 | | - const dockerTemplatePath = path.join( |
177 | | - parentDir, |
178 | | - "templates", |
179 | | - "Docker", |
180 | | - dockerTemplate, |
181 | | - "Dockerfile", |
182 | | - ); |
183 | | - |
184 | | - const destinationPath = path.join(targetDir); |
185 | | - const dockerFileDestination = path.join(destinationPath, "Dockerfile"); |
186 | | - |
187 | | - let runtimeNeedDB = false; |
188 | | - if (dockerCompose) { |
189 | | - try { |
190 | | - console.log(); |
191 | | - const userPrompt = await userPrompts(needDB, cacheService); |
192 | | - runtimeNeedDB = userPrompt.runtimeNeedDB; |
193 | | - |
194 | | - const serviceData = await getServicesData( |
195 | | - packageName, |
196 | | - selectedTemplate, |
197 | | - runtimeNeedDB, |
198 | | - userPrompt.addCacheService, |
199 | | - cacheService, |
200 | | - ); |
201 | | - |
202 | | - console.log("Starting server initialization..."); |
203 | | - |
204 | | - const dockerSpinner = createSpinner( |
205 | | - `Creating Docker Compose File with Entered Services...`, |
206 | | - ).start(); |
207 | | - |
208 | | - const composeFileContent = generateDockerComposeFile( |
209 | | - runtimeNeedDB, |
210 | | - serviceData, |
211 | | - packageName, |
212 | | - selectedTemplate, |
213 | | - ); |
214 | | - const composeFilePath = path.join(targetDir, "docker-compose.yml"); |
215 | | - |
216 | | - fs.writeFileSync(composeFilePath, composeFileContent); |
217 | | - dockerSpinner.success({ |
218 | | - text: `Docker Compose file generated successfully.`, |
219 | | - }); |
220 | | - } catch (error) { |
221 | | - console.log(chalk.red("Error generating Docker Compose file")); |
222 | | - console.error(error.message); |
223 | | - return; |
224 | | - } |
225 | | - } else { |
226 | | - console.log(); |
227 | | - console.log("Starting server initialization..."); |
228 | | - } |
229 | | - |
230 | | - const copySpinner = createSpinner("Creating server files...").start(); |
231 | | - try { |
232 | | - await fs.copy(templatePath, destinationPath); |
233 | | - if (dockerCompose) { |
234 | | - try { |
235 | | - await fs.copyFile(dockerTemplatePath, dockerFileDestination); |
236 | | - } catch (error) { |
237 | | - copySpinner.error({ text: "Error creating Dockerfile.\n" }); |
238 | | - console.error(error.message); |
239 | | - } |
240 | | - } |
241 | | - |
242 | | - copySpinner.success({ text: "Created server files successfully." }); |
243 | | - |
244 | | - if (removeNodemon) { |
245 | | - const nodemonSpinner = createSpinner("Removing nodemon...").start(); |
246 | | - try { |
247 | | - const packageJsonPath = path.join( |
248 | | - destinationPath, |
249 | | - "package.json", |
250 | | - ); |
251 | | - const packageJsonContent = fs.readFileSync( |
252 | | - packageJsonPath, |
253 | | - "utf8", |
254 | | - ); |
255 | | - const packageJson = JSON.parse(packageJsonContent); |
256 | | - |
257 | | - if ( |
258 | | - packageJson.devDependencies && |
259 | | - packageJson.devDependencies.nodemon |
260 | | - ) { |
261 | | - delete packageJson.devDependencies.nodemon; |
262 | | - if (!Object.keys(packageJson.devDependencies).length) { |
263 | | - delete packageJson.devDependencies; |
264 | | - } |
265 | | - } |
266 | | - if (packageJson.scripts && packageJson.scripts.dev) { |
267 | | - delete packageJson.scripts.dev; |
268 | | - } |
269 | | - |
270 | | - fs.writeFileSync( |
271 | | - packageJsonPath, |
272 | | - JSON.stringify(packageJson, null, 2), |
273 | | - ); |
274 | | - |
275 | | - nodemonSpinner.success({ |
276 | | - text: "Removed nodemon successfully.", |
277 | | - }); |
278 | | - } catch (err) { |
279 | | - nodemonSpinner.error({ text: "Error removing nodemon.\n" }); |
280 | | - console.error(err.message); |
281 | | - } |
282 | | - } |
283 | | - } catch (err) { |
284 | | - copySpinner.error({ text: "Error creating server files.\n" }); |
285 | | - console.error(err.message); |
286 | | - } |
287 | | - |
288 | | - const addNameAndTypeSpinner = createSpinner( |
289 | | - "Adding name and type declaration...", |
290 | | - ).start(); |
291 | | - try { |
292 | | - const packageJsonPath = path.join(targetDir, "package.json"); |
293 | | - const packageJsonContent = fs.readFileSync(packageJsonPath, "utf8"); |
294 | | - const packageJson = JSON.parse(packageJsonContent); |
295 | | - packageJson.name = packageName; // Set custom package name |
296 | | - packageJson.type = "module"; // Define type as module |
297 | | - fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); |
298 | | - |
299 | | - addNameAndTypeSpinner.success({ |
300 | | - text: "Added name and type declaration successfully.", |
301 | | - }); |
302 | | - } catch (err) { |
303 | | - addNameAndTypeSpinner.error({ |
304 | | - text: "Error adding type declaration.\n", |
305 | | - }); |
306 | | - console.error(err.message); |
307 | | - } |
308 | | - |
309 | | - if (!removeDependencies) { |
310 | | - const installDependencies = createSpinner( |
311 | | - "Installing dependency packages...", |
312 | | - ).start(); |
313 | | - try { |
314 | | - execSync("npm i", { stdio: "ignore", cwd: targetDir }); |
315 | | - |
316 | | - installDependencies.success({ |
317 | | - text: "Installed dependencies successfully.", |
318 | | - }); |
319 | | - } catch (err) { |
320 | | - installDependencies.error({ |
321 | | - text: "Error installing dependencies.\n", |
322 | | - }); |
323 | | - console.error(err); |
324 | | - } |
325 | | - } |
326 | | - |
327 | | - console.log(chalk.green.bold("\nSetup complete! To run your server:")); |
328 | | - if (removeDependencies) { |
329 | | - console.log( |
330 | | - chalk.yellow("Install dependencies: "), |
331 | | - chalk.white.bold("npm i"), |
332 | | - ); |
333 | | - } |
334 | | - console.log(chalk.yellow("Run:"), chalk.white.bold("npm start")); |
335 | | - if (!removeNodemon) { |
336 | | - console.log( |
337 | | - chalk.yellow("Run with hot reloading:"), |
338 | | - chalk.white.bold("npm run dev"), |
339 | | - ); |
340 | | - } |
341 | | - if (dockerCompose) { |
342 | | - console.log( |
343 | | - chalk.yellow("To start your services with Docker Compose:"), |
344 | | - chalk.white.bold("docker compose up -d"), |
345 | | - ); |
346 | | - } |
347 | | - |
348 | | - if (dockerCompose && isUrl === true && runtimeNeedDB === true) { |
349 | | - console.log( |
350 | | - chalk.yellow("Important Note:"), |
351 | | - chalk.white("Use"), |
352 | | - chalk.blueBright.bold("host.docker.internal"), |
353 | | - chalk.white("instead of"), |
354 | | - chalk.blueBright.bold("localhost/127.0.0.1"), |
355 | | - chalk.white("in your Database Connection URL in the"), |
356 | | - chalk.blueBright.bold(".env"), |
357 | | - chalk.white("file for Docker to work correctly."), |
358 | | - ); |
359 | | - } |
360 | | -} |
361 | | - |
362 | 101 | const toolIntro = () => { |
363 | 102 | console.log( |
364 | 103 | figlet.textSync(metadata.name, { |
|
0 commit comments